[Kimchi-devel] [PATCH 1/5] [WOK] Move plugins directory to src/wok structure.
pvital at linux.vnet.ibm.com
pvital at linux.vnet.ibm.com
Mon Sep 28 19:49:14 UTC 2015
From: Paulo Vital <pvital at linux.vnet.ibm.com>
Moving plugins directory to be part of src/wok development structure to make
easy develop, build, execute and test all plugins integrated with wok.
Signed-off-by: Paulo Vital <pvital at linux.vnet.ibm.com>
---
plugins/Makefile.am | 25 -
plugins/__init__.py | 18 -
plugins/kimchi/.gitignore | 37 -
plugins/kimchi/API.json | 836 -------
plugins/kimchi/INSTALL | 369 ---
plugins/kimchi/Makefile.am | 161 --
plugins/kimchi/README.md | 1 -
plugins/kimchi/VERSION | 1 -
plugins/kimchi/__init__.py | 21 -
plugins/kimchi/autogen.sh | 21 -
plugins/kimchi/build-aux/config.rpath | 672 ------
plugins/kimchi/build-aux/genChangelog | 25 -
plugins/kimchi/build-aux/pkg-version | 59 -
plugins/kimchi/config.py.in | 144 --
plugins/kimchi/config.rpath | 672 ------
plugins/kimchi/configure.ac | 119 -
plugins/kimchi/contrib/DEBIAN/Makefile.am | 17 -
plugins/kimchi/contrib/DEBIAN/control.in | 30 -
plugins/kimchi/contrib/Makefile.am | 34 -
plugins/kimchi/contrib/check_i18n.py | 82 -
plugins/kimchi/contrib/kimchi.spec.fedora.in | 119 -
plugins/kimchi/contrib/kimchi.spec.suse.in | 107 -
plugins/kimchi/contrib/make-deb.sh.in | 15 -
plugins/kimchi/control/Makefile.am | 27 -
plugins/kimchi/control/__init__.py | 26 -
plugins/kimchi/control/config.py | 57 -
plugins/kimchi/control/cpuinfo.py | 37 -
plugins/kimchi/control/debugreports.py | 61 -
plugins/kimchi/control/groups.py | 28 -
plugins/kimchi/control/host.py | 157 --
plugins/kimchi/control/interfaces.py | 46 -
plugins/kimchi/control/networks.py | 54 -
plugins/kimchi/control/peers.py | 29 -
plugins/kimchi/control/storagepools.py | 116 -
plugins/kimchi/control/storageservers.py | 60 -
plugins/kimchi/control/storagevolumes.py | 83 -
plugins/kimchi/control/templates.py | 58 -
plugins/kimchi/control/users.py | 35 -
plugins/kimchi/control/vm/Makefile.am | 26 -
plugins/kimchi/control/vm/__init__.py | 26 -
plugins/kimchi/control/vm/hostdevs.py | 43 -
plugins/kimchi/control/vm/ifaces.py | 45 -
plugins/kimchi/control/vm/snapshots.py | 58 -
plugins/kimchi/control/vm/storages.py | 45 -
plugins/kimchi/control/vms.py | 67 -
plugins/kimchi/disks.py | 196 --
plugins/kimchi/distroloader.py | 67 -
plugins/kimchi/distros.d/Makefile.am | 22 -
plugins/kimchi/distros.d/debian.json | 9 -
plugins/kimchi/distros.d/fedora.json | 30 -
plugins/kimchi/distros.d/gentoo.json | 9 -
plugins/kimchi/distros.d/opensuse.json | 23 -
plugins/kimchi/distros.d/ubuntu.json | 37 -
plugins/kimchi/docs/API.md | 1116 ---------
plugins/kimchi/docs/Makefile.am | 28 -
plugins/kimchi/docs/README-federation.md | 60 -
plugins/kimchi/docs/README.md | 247 --
plugins/kimchi/docs/kimchi-guest.png | Bin 192281 -> 0 bytes
plugins/kimchi/docs/kimchi-login.png | Bin 318041 -> 0 bytes
plugins/kimchi/docs/kimchi-templates.png | Bin 329678 -> 0 bytes
plugins/kimchi/i18n.py | 335 ---
plugins/kimchi/imageinfo.py | 72 -
plugins/kimchi/iscsi.py | 88 -
plugins/kimchi/isoinfo.py | 506 -----
plugins/kimchi/kimchi.conf | 37 -
plugins/kimchi/kvmusertests.py | 79 -
plugins/kimchi/m4/ac_python_module.m4 | 30 -
plugins/kimchi/m4/gettext.m4 | 383 ----
plugins/kimchi/m4/iconv.m4 | 214 --
plugins/kimchi/m4/intlmacosx.m4 | 51 -
plugins/kimchi/m4/lib-ld.m4 | 110 -
plugins/kimchi/m4/lib-link.m4 | 774 -------
plugins/kimchi/m4/lib-prefix.m4 | 224 --
plugins/kimchi/m4/nls.m4 | 32 -
plugins/kimchi/m4/po.m4 | 449 ----
plugins/kimchi/m4/progtest.m4 | 92 -
plugins/kimchi/mockmodel.py | 627 ------
plugins/kimchi/model/Makefile.am | 25 -
plugins/kimchi/model/__init__.py | 18 -
plugins/kimchi/model/config.py | 176 --
plugins/kimchi/model/cpuinfo.py | 126 --
plugins/kimchi/model/debugreports.py | 213 --
plugins/kimchi/model/diskutils.py | 75 -
plugins/kimchi/model/featuretests.py | 259 ---
plugins/kimchi/model/groups.py | 67 -
plugins/kimchi/model/host.py | 476 ----
plugins/kimchi/model/hostdev.py | 324 ---
plugins/kimchi/model/interfaces.py | 44 -
plugins/kimchi/model/libvirtconnection.py | 136 --
plugins/kimchi/model/libvirtstoragepool.py | 264 ---
plugins/kimchi/model/model.py | 52 -
plugins/kimchi/model/networks.py | 382 ----
plugins/kimchi/model/peers.py | 72 -
plugins/kimchi/model/storagepools.py | 490 ----
plugins/kimchi/model/storageservers.py | 81 -
plugins/kimchi/model/storagetargets.py | 122 -
plugins/kimchi/model/storagevolumes.py | 542 -----
plugins/kimchi/model/templates.py | 303 ---
plugins/kimchi/model/users.py | 90 -
plugins/kimchi/model/utils.py | 161 --
plugins/kimchi/model/vmhostdevs.py | 336 ---
plugins/kimchi/model/vmifaces.py | 186 --
plugins/kimchi/model/vms.py | 1307 -----------
plugins/kimchi/model/vmsnapshots.py | 204 --
plugins/kimchi/model/vmstorages.py | 252 ---
plugins/kimchi/netinfo.py | 216 --
plugins/kimchi/network.py | 62 -
plugins/kimchi/osinfo.py | 213 --
plugins/kimchi/po/LINGUAS | 11 -
plugins/kimchi/po/Makefile.in.in | 398 ----
plugins/kimchi/po/Makevars | 41 -
plugins/kimchi/po/POTFILES.in | 3 -
plugins/kimchi/po/de_DE.po | 2288 -------------------
plugins/kimchi/po/en_US.po | 2075 -----------------
plugins/kimchi/po/es_ES.po | 2305 -------------------
plugins/kimchi/po/fr_FR.po | 2338 -------------------
plugins/kimchi/po/gen-pot.in | 9 -
plugins/kimchi/po/it_IT.po | 2274 -------------------
plugins/kimchi/po/ja_JP.po | 2269 -------------------
plugins/kimchi/po/kimchi.pot | 2074 -----------------
plugins/kimchi/po/ko_KR.po | 2197 ------------------
plugins/kimchi/po/pt_BR.po | 2369 --------------------
plugins/kimchi/po/ru_RU.po | 2198 ------------------
plugins/kimchi/po/zh_CN.po | 2186 ------------------
plugins/kimchi/po/zh_TW.po | 2138 ------------------
plugins/kimchi/repositories.py | 529 -----
plugins/kimchi/root.py | 69 -
plugins/kimchi/scan.py | 89 -
plugins/kimchi/screenshot.py | 184 --
plugins/kimchi/swupdate.py | 263 ---
plugins/kimchi/template.conf | 47 -
plugins/kimchi/tests/Makefile.am | 50 -
plugins/kimchi/tests/iso_gen.py | 212 --
plugins/kimchi/tests/run_tests.sh.in | 55 -
plugins/kimchi/tests/test_authorization.py | 178 --
plugins/kimchi/tests/test_config.py.in | 267 ---
plugins/kimchi/tests/test_exception.py | 123 -
plugins/kimchi/tests/test_host.py | 206 --
plugins/kimchi/tests/test_mock_network.py | 73 -
plugins/kimchi/tests/test_mock_storagepool.py | 147 --
plugins/kimchi/tests/test_mock_storagevolume.py | 98 -
plugins/kimchi/tests/test_mockmodel.py | 141 --
plugins/kimchi/tests/test_model.py | 1248 -----------
plugins/kimchi/tests/test_model_network.py | 149 --
plugins/kimchi/tests/test_model_storagepool.py | 123 -
plugins/kimchi/tests/test_model_storagevolume.py | 280 ---
plugins/kimchi/tests/test_networkxml.py | 172 --
plugins/kimchi/tests/test_objectstore.py | 97 -
plugins/kimchi/tests/test_osinfo.py | 69 -
plugins/kimchi/tests/test_plugin.py | 126 --
plugins/kimchi/tests/test_rest.py | 1327 -----------
plugins/kimchi/tests/test_rollbackcontext.py | 99 -
plugins/kimchi/tests/test_server.py | 289 ---
plugins/kimchi/tests/test_storagepoolxml.py | 171 --
plugins/kimchi/tests/test_template.py | 387 ----
plugins/kimchi/tests/test_utils.py | 69 -
plugins/kimchi/tests/test_vmtemplate.py | 116 -
plugins/kimchi/tests/test_yumparser.py | 162 --
plugins/kimchi/tests/utils.py | 260 ---
plugins/kimchi/ui/Makefile.am | 20 -
plugins/kimchi/ui/config/Makefile.am | 22 -
plugins/kimchi/ui/config/tab-ext.xml | 38 -
plugins/kimchi/ui/css/Makefile.am | 26 -
plugins/kimchi/ui/css/theme-default/guest-edit.css | 424 ----
.../ui/css/theme-default/guest-storage-add.css | 81 -
plugins/kimchi/ui/css/theme-default/host.css | 287 ---
plugins/kimchi/ui/css/theme-default/icon.css | 106 -
plugins/kimchi/ui/css/theme-default/list.css | 326 ---
plugins/kimchi/ui/css/theme-default/network.css | 267 ---
plugins/kimchi/ui/css/theme-default/report-add.css | 37 -
.../kimchi/ui/css/theme-default/report-rename.css | 39 -
.../kimchi/ui/css/theme-default/repository-add.css | 42 -
.../ui/css/theme-default/repository-edit.css | 88 -
plugins/kimchi/ui/css/theme-default/storage.css | 550 -----
.../css/theme-default/storagepool-add-volume.css | 36 -
.../kimchi/ui/css/theme-default/template-edit.css | 175 --
plugins/kimchi/ui/css/theme-default/template.css | 85 -
.../kimchi/ui/css/theme-default/template_add.css | 317 ---
.../kimchi/ui/css/theme-default/template_list.css | 267 ---
plugins/kimchi/ui/images/Makefile.am | 22 -
plugins/kimchi/ui/images/icon-centos.png | Bin 4734 -> 0 bytes
plugins/kimchi/ui/images/icon-debian.png | Bin 4239 -> 0 bytes
plugins/kimchi/ui/images/icon-fedora.png | Bin 4449 -> 0 bytes
plugins/kimchi/ui/images/icon-gentoo.png | Bin 15307 -> 0 bytes
plugins/kimchi/ui/images/icon-opensuse.png | Bin 3046 -> 0 bytes
plugins/kimchi/ui/images/icon-ubuntu.png | Bin 4818 -> 0 bytes
plugins/kimchi/ui/images/icon-vm.png | Bin 2976 -> 0 bytes
plugins/kimchi/ui/images/theme-default/Makefile.am | 20 -
.../kimchi/ui/images/theme-default/ac22_pause.png | Bin 1219 -> 0 bytes
.../ui/images/theme-default/ac22_pause_grey.png | Bin 1175 -> 0 bytes
.../kimchi/ui/images/theme-default/ac24_resume.png | Bin 1341 -> 0 bytes
.../ui/images/theme-default/ac24_resume_grey.png | Bin 1282 -> 0 bytes
.../ui/images/theme-default/arrow-down-black.png | Bin 2942 -> 0 bytes
.../ui/images/theme-default/arrow-down-disable.png | Bin 472 -> 0 bytes
.../kimchi/ui/images/theme-default/arrow-down.png | Bin 537 -> 0 bytes
.../kimchi/ui/images/theme-default/arrow-up.png | Bin 510 -> 0 bytes
.../kimchi/ui/images/theme-default/arrow_out.png | Bin 3048 -> 0 bytes
plugins/kimchi/ui/images/theme-default/group.png | Bin 1703 -> 0 bytes
.../ui/images/theme-default/host-icon-sprite.png | Bin 1034 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-back.png | Bin 244 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-camera.png | Bin 4860 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-design.png | Bin 4562 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-detail.png | Bin 3079 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-iso.png | Bin 4188 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-list.png | Bin 2983 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-load.png | Bin 3678 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-local.png | Bin 425 -> 0 bytes
.../ui/images/theme-default/icon-power-down.png | Bin 4372 -> 0 bytes
.../ui/images/theme-default/icon-power-up.png | Bin 4367 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-qcow2.png | Bin 4684 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-raw.png | Bin 4679 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-remote.png | Bin 1005 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-reset.png | Bin 4576 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-search.png | Bin 4197 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-sort.png | Bin 3421 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-tree.png | Bin 3526 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-user.png | Bin 5366 -> 0 bytes
.../images/theme-default/icon-volume-default.png | Bin 4265 -> 0 bytes
.../images/theme-default/kimchi-loading15x15.gif | Bin 1653 -> 0 bytes
plugins/kimchi/ui/images/theme-default/loading.gif | Bin 2190 -> 0 bytes
plugins/kimchi/ui/images/theme-default/user.png | Bin 1322 -> 0 bytes
plugins/kimchi/ui/js/Makefile.am | 27 -
plugins/kimchi/ui/js/src/kimchi.api.js | 1355 -----------
plugins/kimchi/ui/js/src/kimchi.guest_add_main.js | 86 -
plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js | 759 -------
plugins/kimchi/ui/js/src/kimchi.guest_main.js | 511 -----
.../kimchi/ui/js/src/kimchi.guest_media_main.js | 56 -
.../ui/js/src/kimchi.guest_storage_add.main.js | 199 --
plugins/kimchi/ui/js/src/kimchi.host.js | 858 -------
plugins/kimchi/ui/js/src/kimchi.main.js | 26 -
plugins/kimchi/ui/js/src/kimchi.network.js | 442 ----
plugins/kimchi/ui/js/src/kimchi.report_add_main.js | 72 -
.../kimchi/ui/js/src/kimchi.report_rename_main.js | 66 -
.../kimchi/ui/js/src/kimchi.repository_add_main.js | 96 -
.../ui/js/src/kimchi.repository_edit_main.js | 74 -
plugins/kimchi/ui/js/src/kimchi.storage_main.js | 428 ----
.../ui/js/src/kimchi.storagepool_add_main.js | 414 ----
.../js/src/kimchi.storagepool_add_volume_main.js | 179 --
.../kimchi/ui/js/src/kimchi.template_add_main.js | 441 ----
.../kimchi/ui/js/src/kimchi.template_edit_main.js | 343 ---
plugins/kimchi/ui/js/src/kimchi.template_main.js | 111 -
plugins/kimchi/ui/pages/Makefile.am | 22 -
plugins/kimchi/ui/pages/guest-add.html.tmpl | 98 -
plugins/kimchi/ui/pages/guest-edit.html.tmpl | 311 ---
.../kimchi/ui/pages/guest-storage-add.html.tmpl | 103 -
plugins/kimchi/ui/pages/guest.html.tmpl | 77 -
plugins/kimchi/ui/pages/guests.html.tmpl | 65 -
plugins/kimchi/ui/pages/help/Makefile.am | 34 -
plugins/kimchi/ui/pages/help/de_DE/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/de_DE/guests.dita | 127 --
plugins/kimchi/ui/pages/help/de_DE/host.dita | 49 -
plugins/kimchi/ui/pages/help/de_DE/network.dita | 62 -
plugins/kimchi/ui/pages/help/de_DE/storage.dita | 86 -
plugins/kimchi/ui/pages/help/de_DE/templates.dita | 112 -
plugins/kimchi/ui/pages/help/dita-help.xsl | 26 -
plugins/kimchi/ui/pages/help/en_US/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/en_US/guests.dita | 136 --
plugins/kimchi/ui/pages/help/en_US/host.dita | 70 -
plugins/kimchi/ui/pages/help/en_US/network.dita | 68 -
plugins/kimchi/ui/pages/help/en_US/storage.dita | 99 -
plugins/kimchi/ui/pages/help/en_US/templates.dita | 123 -
plugins/kimchi/ui/pages/help/es_ES/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/es_ES/guests.dita | 120 -
plugins/kimchi/ui/pages/help/es_ES/host.dita | 49 -
plugins/kimchi/ui/pages/help/es_ES/network.dita | 61 -
plugins/kimchi/ui/pages/help/es_ES/storage.dita | 86 -
plugins/kimchi/ui/pages/help/es_ES/templates.dita | 111 -
plugins/kimchi/ui/pages/help/fr_FR/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/fr_FR/guests.dita | 130 --
plugins/kimchi/ui/pages/help/fr_FR/host.dita | 68 -
plugins/kimchi/ui/pages/help/fr_FR/network.dita | 67 -
plugins/kimchi/ui/pages/help/fr_FR/storage.dita | 93 -
plugins/kimchi/ui/pages/help/fr_FR/templates.dita | 120 -
plugins/kimchi/ui/pages/help/it_IT/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/it_IT/guests.dita | 123 -
plugins/kimchi/ui/pages/help/it_IT/host.dita | 51 -
plugins/kimchi/ui/pages/help/it_IT/network.dita | 63 -
plugins/kimchi/ui/pages/help/it_IT/storage.dita | 91 -
plugins/kimchi/ui/pages/help/it_IT/templates.dita | 115 -
plugins/kimchi/ui/pages/help/ja_JP/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/ja_JP/guests.dita | 172 --
plugins/kimchi/ui/pages/help/ja_JP/host.dita | 70 -
plugins/kimchi/ui/pages/help/ja_JP/network.dita | 83 -
plugins/kimchi/ui/pages/help/ja_JP/storage.dita | 120 -
plugins/kimchi/ui/pages/help/ja_JP/templates.dita | 150 --
plugins/kimchi/ui/pages/help/kimchi.css | 208 --
plugins/kimchi/ui/pages/help/ko_KR/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/ko_KR/guests.dita | 119 -
plugins/kimchi/ui/pages/help/ko_KR/host.dita | 47 -
plugins/kimchi/ui/pages/help/ko_KR/network.dita | 61 -
plugins/kimchi/ui/pages/help/ko_KR/storage.dita | 86 -
plugins/kimchi/ui/pages/help/ko_KR/templates.dita | 111 -
plugins/kimchi/ui/pages/help/pt_BR/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/pt_BR/guests.dita | 137 --
plugins/kimchi/ui/pages/help/pt_BR/host.dita | 74 -
plugins/kimchi/ui/pages/help/pt_BR/network.dita | 72 -
plugins/kimchi/ui/pages/help/pt_BR/storage.dita | 102 -
plugins/kimchi/ui/pages/help/pt_BR/templates.dita | 127 --
plugins/kimchi/ui/pages/help/ru_RU/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/ru_RU/guests.dita | 122 -
plugins/kimchi/ui/pages/help/ru_RU/host.dita | 48 -
plugins/kimchi/ui/pages/help/ru_RU/network.dita | 61 -
plugins/kimchi/ui/pages/help/ru_RU/storage.dita | 88 -
plugins/kimchi/ui/pages/help/ru_RU/templates.dita | 111 -
plugins/kimchi/ui/pages/help/zh_CN/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/zh_CN/guests.dita | 118 -
plugins/kimchi/ui/pages/help/zh_CN/host.dita | 45 -
plugins/kimchi/ui/pages/help/zh_CN/network.dita | 61 -
plugins/kimchi/ui/pages/help/zh_CN/storage.dita | 84 -
plugins/kimchi/ui/pages/help/zh_CN/templates.dita | 111 -
plugins/kimchi/ui/pages/help/zh_TW/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/zh_TW/guests.dita | 120 -
plugins/kimchi/ui/pages/help/zh_TW/host.dita | 50 -
plugins/kimchi/ui/pages/help/zh_TW/network.dita | 61 -
plugins/kimchi/ui/pages/help/zh_TW/storage.dita | 88 -
plugins/kimchi/ui/pages/help/zh_TW/templates.dita | 112 -
plugins/kimchi/ui/pages/host.html.tmpl | 177 --
plugins/kimchi/ui/pages/i18n.json.tmpl | 187 --
plugins/kimchi/ui/pages/network.html.tmpl | 133 --
plugins/kimchi/ui/pages/report-add.html.tmpl | 56 -
plugins/kimchi/ui/pages/report-rename.html.tmpl | 56 -
plugins/kimchi/ui/pages/repository-add.html.tmpl | 113 -
plugins/kimchi/ui/pages/repository-edit.html.tmpl | 117 -
plugins/kimchi/ui/pages/storage.html.tmpl | 143 --
.../ui/pages/storagepool-add-volume.html.tmpl | 79 -
plugins/kimchi/ui/pages/storagepool-add.html.tmpl | 186 --
plugins/kimchi/ui/pages/template-add.html.tmpl | 233 --
plugins/kimchi/ui/pages/template-edit.html.tmpl | 193 --
plugins/kimchi/ui/pages/templates.html.tmpl | 77 -
plugins/kimchi/ui/robots.txt | 2 -
plugins/kimchi/ui/spice-html5/Makefile.am | 25 -
plugins/kimchi/ui/spice-html5/atKeynames.js | 183 --
plugins/kimchi/ui/spice-html5/bitmap.js | 51 -
plugins/kimchi/ui/spice-html5/css/Makefile.am | 20 -
plugins/kimchi/ui/spice-html5/css/spice.css | 118 -
plugins/kimchi/ui/spice-html5/cursor.js | 110 -
plugins/kimchi/ui/spice-html5/display.js | 823 -------
plugins/kimchi/ui/spice-html5/enums.js | 324 ---
plugins/kimchi/ui/spice-html5/inputs.js | 280 ---
plugins/kimchi/ui/spice-html5/lz.js | 166 --
plugins/kimchi/ui/spice-html5/main.js | 231 --
plugins/kimchi/ui/spice-html5/pages/Makefile.am | 20 -
.../kimchi/ui/spice-html5/pages/spice_auto.html | 200 --
plugins/kimchi/ui/spice-html5/playback.js | 278 ---
plugins/kimchi/ui/spice-html5/png.js | 256 ---
plugins/kimchi/ui/spice-html5/quic.js | 1335 -----------
plugins/kimchi/ui/spice-html5/resize.js | 70 -
plugins/kimchi/ui/spice-html5/simulatecursor.js | 202 --
plugins/kimchi/ui/spice-html5/spicearraybuffer.js | 58 -
plugins/kimchi/ui/spice-html5/spiceconn.js | 460 ----
plugins/kimchi/ui/spice-html5/spicedataview.js | 120 -
plugins/kimchi/ui/spice-html5/spicemsg.js | 1047 ---------
plugins/kimchi/ui/spice-html5/spicetype.js | 473 ----
.../kimchi/ui/spice-html5/thirdparty/Makefile.am | 20 -
plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js | 589 -----
plugins/kimchi/ui/spice-html5/thirdparty/prng4.js | 79 -
plugins/kimchi/ui/spice-html5/thirdparty/rng.js | 102 -
plugins/kimchi/ui/spice-html5/thirdparty/rsa.js | 146 --
plugins/kimchi/ui/spice-html5/thirdparty/sha1.js | 346 ---
plugins/kimchi/ui/spice-html5/ticket.js | 250 ---
plugins/kimchi/ui/spice-html5/utils.js | 265 ---
plugins/kimchi/ui/spice-html5/webm.js | 553 -----
plugins/kimchi/ui/spice-html5/wire.js | 123 -
plugins/kimchi/utils.py | 39 -
plugins/kimchi/vmtemplate.py | 431 ----
plugins/kimchi/vnc.py | 77 -
plugins/kimchi/xmlutils/Makefile.am | 25 -
plugins/kimchi/xmlutils/__init__.py | 18 -
plugins/kimchi/xmlutils/cpu.py | 60 -
plugins/kimchi/xmlutils/disk.py | 164 --
plugins/kimchi/xmlutils/graphics.py | 45 -
plugins/kimchi/xmlutils/interface.py | 61 -
plugins/kimchi/xmlutils/network.py | 122 -
plugins/kimchi/xmlutils/qemucmdline.py | 45 -
plugins/kimchi/yumparser.py | 283 ---
plugins/sample/API.json | 56 -
plugins/sample/Makefile.am | 29 -
plugins/sample/__init__.py | 97 -
plugins/sample/config.status | 1 -
plugins/sample/i18n.py | 40 -
plugins/sample/model.py | 131 --
plugins/sample/po/LINGUAS | 3 -
plugins/sample/po/Makefile.in.in | 400 ----
plugins/sample/po/Makevars | 41 -
plugins/sample/po/POTFILES.in | 2 -
plugins/sample/po/en_US.po | 21 -
plugins/sample/po/gen-pot | 9 -
plugins/sample/po/pt_BR.po | 24 -
plugins/sample/po/sample.pot | 21 -
plugins/sample/po/zh_CN.po | 24 -
plugins/sample/sample.conf.in | 27 -
plugins/sample/ui/Makefile.am | 22 -
plugins/sample/ui/config/Makefile.am | 21 -
plugins/sample/ui/config/tab-ext.xml | 17 -
plugins/sample/ui/css/.gitignore | 0
plugins/sample/ui/images/.gitignore | 0
plugins/sample/ui/js/.gitignore | 0
plugins/sample/ui/js/Makefile.am | 20 -
plugins/sample/ui/js/util.js | 33 -
plugins/sample/ui/libs/.gitignore | 0
plugins/sample/ui/pages/Makefile.am | 20 -
.../sample/ui/pages/help/en_US/sample-tab1.html | 1 -
.../sample/ui/pages/help/en_US/sample-tab2.html | 1 -
plugins/sample/ui/pages/i18n.json.tmpl | 26 -
plugins/sample/ui/pages/sample-tab1.html.tmpl | 30 -
plugins/sample/ui/pages/sample-tab2.html.tmpl | 30 -
src/wok/plugins/Makefile.am | 25 +
src/wok/plugins/__init__.py | 18 +
src/wok/plugins/kimchi/.gitignore | 37 +
src/wok/plugins/kimchi/API.json | 836 +++++++
src/wok/plugins/kimchi/INSTALL | 369 +++
src/wok/plugins/kimchi/Makefile.am | 161 ++
src/wok/plugins/kimchi/README.md | 1 +
src/wok/plugins/kimchi/VERSION | 1 +
src/wok/plugins/kimchi/__init__.py | 21 +
src/wok/plugins/kimchi/autogen.sh | 21 +
src/wok/plugins/kimchi/build-aux/config.rpath | 672 ++++++
src/wok/plugins/kimchi/build-aux/genChangelog | 25 +
src/wok/plugins/kimchi/build-aux/pkg-version | 59 +
src/wok/plugins/kimchi/config.py.in | 144 ++
src/wok/plugins/kimchi/config.rpath | 672 ++++++
src/wok/plugins/kimchi/configure.ac | 119 +
src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am | 17 +
src/wok/plugins/kimchi/contrib/DEBIAN/control.in | 30 +
src/wok/plugins/kimchi/contrib/Makefile.am | 34 +
src/wok/plugins/kimchi/contrib/check_i18n.py | 82 +
.../plugins/kimchi/contrib/kimchi.spec.fedora.in | 119 +
src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in | 107 +
src/wok/plugins/kimchi/contrib/make-deb.sh.in | 15 +
src/wok/plugins/kimchi/control/Makefile.am | 27 +
src/wok/plugins/kimchi/control/__init__.py | 26 +
src/wok/plugins/kimchi/control/config.py | 57 +
src/wok/plugins/kimchi/control/cpuinfo.py | 37 +
src/wok/plugins/kimchi/control/debugreports.py | 61 +
src/wok/plugins/kimchi/control/groups.py | 28 +
src/wok/plugins/kimchi/control/host.py | 157 ++
src/wok/plugins/kimchi/control/interfaces.py | 46 +
src/wok/plugins/kimchi/control/networks.py | 54 +
src/wok/plugins/kimchi/control/peers.py | 29 +
src/wok/plugins/kimchi/control/storagepools.py | 116 +
src/wok/plugins/kimchi/control/storageservers.py | 60 +
src/wok/plugins/kimchi/control/storagevolumes.py | 83 +
src/wok/plugins/kimchi/control/templates.py | 58 +
src/wok/plugins/kimchi/control/users.py | 35 +
src/wok/plugins/kimchi/control/vm/Makefile.am | 26 +
src/wok/plugins/kimchi/control/vm/__init__.py | 26 +
src/wok/plugins/kimchi/control/vm/hostdevs.py | 43 +
src/wok/plugins/kimchi/control/vm/ifaces.py | 45 +
src/wok/plugins/kimchi/control/vm/snapshots.py | 58 +
src/wok/plugins/kimchi/control/vm/storages.py | 45 +
src/wok/plugins/kimchi/control/vms.py | 67 +
src/wok/plugins/kimchi/disks.py | 196 ++
src/wok/plugins/kimchi/distroloader.py | 67 +
src/wok/plugins/kimchi/distros.d/Makefile.am | 22 +
src/wok/plugins/kimchi/distros.d/debian.json | 9 +
src/wok/plugins/kimchi/distros.d/fedora.json | 30 +
src/wok/plugins/kimchi/distros.d/gentoo.json | 9 +
src/wok/plugins/kimchi/distros.d/opensuse.json | 23 +
src/wok/plugins/kimchi/distros.d/ubuntu.json | 37 +
src/wok/plugins/kimchi/docs/API.md | 1116 +++++++++
src/wok/plugins/kimchi/docs/Makefile.am | 28 +
src/wok/plugins/kimchi/docs/README-federation.md | 60 +
src/wok/plugins/kimchi/docs/README.md | 247 ++
src/wok/plugins/kimchi/docs/kimchi-guest.png | Bin 0 -> 192281 bytes
src/wok/plugins/kimchi/docs/kimchi-login.png | Bin 0 -> 318041 bytes
src/wok/plugins/kimchi/docs/kimchi-templates.png | Bin 0 -> 329678 bytes
src/wok/plugins/kimchi/i18n.py | 335 +++
src/wok/plugins/kimchi/imageinfo.py | 72 +
src/wok/plugins/kimchi/iscsi.py | 88 +
src/wok/plugins/kimchi/isoinfo.py | 506 +++++
src/wok/plugins/kimchi/kimchi.conf | 37 +
src/wok/plugins/kimchi/kvmusertests.py | 79 +
src/wok/plugins/kimchi/m4/ac_python_module.m4 | 30 +
src/wok/plugins/kimchi/m4/gettext.m4 | 383 ++++
src/wok/plugins/kimchi/m4/iconv.m4 | 214 ++
src/wok/plugins/kimchi/m4/intlmacosx.m4 | 51 +
src/wok/plugins/kimchi/m4/lib-ld.m4 | 110 +
src/wok/plugins/kimchi/m4/lib-link.m4 | 774 +++++++
src/wok/plugins/kimchi/m4/lib-prefix.m4 | 224 ++
src/wok/plugins/kimchi/m4/nls.m4 | 32 +
src/wok/plugins/kimchi/m4/po.m4 | 449 ++++
src/wok/plugins/kimchi/m4/progtest.m4 | 92 +
src/wok/plugins/kimchi/mockmodel.py | 627 ++++++
src/wok/plugins/kimchi/model/Makefile.am | 25 +
src/wok/plugins/kimchi/model/__init__.py | 18 +
src/wok/plugins/kimchi/model/config.py | 176 ++
src/wok/plugins/kimchi/model/cpuinfo.py | 126 ++
src/wok/plugins/kimchi/model/debugreports.py | 213 ++
src/wok/plugins/kimchi/model/diskutils.py | 75 +
src/wok/plugins/kimchi/model/featuretests.py | 259 +++
src/wok/plugins/kimchi/model/groups.py | 67 +
src/wok/plugins/kimchi/model/host.py | 476 ++++
src/wok/plugins/kimchi/model/hostdev.py | 324 +++
src/wok/plugins/kimchi/model/interfaces.py | 44 +
src/wok/plugins/kimchi/model/libvirtconnection.py | 136 ++
src/wok/plugins/kimchi/model/libvirtstoragepool.py | 264 +++
src/wok/plugins/kimchi/model/model.py | 52 +
src/wok/plugins/kimchi/model/networks.py | 382 ++++
src/wok/plugins/kimchi/model/peers.py | 72 +
src/wok/plugins/kimchi/model/storagepools.py | 490 ++++
src/wok/plugins/kimchi/model/storageservers.py | 81 +
src/wok/plugins/kimchi/model/storagetargets.py | 122 +
src/wok/plugins/kimchi/model/storagevolumes.py | 542 +++++
src/wok/plugins/kimchi/model/templates.py | 303 +++
src/wok/plugins/kimchi/model/users.py | 90 +
src/wok/plugins/kimchi/model/utils.py | 161 ++
src/wok/plugins/kimchi/model/vmhostdevs.py | 336 +++
src/wok/plugins/kimchi/model/vmifaces.py | 186 ++
src/wok/plugins/kimchi/model/vms.py | 1307 +++++++++++
src/wok/plugins/kimchi/model/vmsnapshots.py | 204 ++
src/wok/plugins/kimchi/model/vmstorages.py | 252 +++
src/wok/plugins/kimchi/netinfo.py | 216 ++
src/wok/plugins/kimchi/network.py | 62 +
src/wok/plugins/kimchi/osinfo.py | 213 ++
src/wok/plugins/kimchi/po/LINGUAS | 11 +
src/wok/plugins/kimchi/po/Makefile.in.in | 398 ++++
src/wok/plugins/kimchi/po/Makevars | 41 +
src/wok/plugins/kimchi/po/POTFILES.in | 3 +
src/wok/plugins/kimchi/po/de_DE.po | 2288 +++++++++++++++++++
src/wok/plugins/kimchi/po/en_US.po | 2075 +++++++++++++++++
src/wok/plugins/kimchi/po/es_ES.po | 2305 +++++++++++++++++++
src/wok/plugins/kimchi/po/fr_FR.po | 2338 +++++++++++++++++++
src/wok/plugins/kimchi/po/gen-pot.in | 9 +
src/wok/plugins/kimchi/po/it_IT.po | 2274 +++++++++++++++++++
src/wok/plugins/kimchi/po/ja_JP.po | 2269 +++++++++++++++++++
src/wok/plugins/kimchi/po/kimchi.pot | 2074 +++++++++++++++++
src/wok/plugins/kimchi/po/ko_KR.po | 2197 ++++++++++++++++++
src/wok/plugins/kimchi/po/pt_BR.po | 2369 ++++++++++++++++++++
src/wok/plugins/kimchi/po/ru_RU.po | 2198 ++++++++++++++++++
src/wok/plugins/kimchi/po/zh_CN.po | 2186 ++++++++++++++++++
src/wok/plugins/kimchi/po/zh_TW.po | 2138 ++++++++++++++++++
src/wok/plugins/kimchi/repositories.py | 529 +++++
src/wok/plugins/kimchi/root.py | 69 +
src/wok/plugins/kimchi/scan.py | 89 +
src/wok/plugins/kimchi/screenshot.py | 184 ++
src/wok/plugins/kimchi/swupdate.py | 263 +++
src/wok/plugins/kimchi/template.conf | 47 +
src/wok/plugins/kimchi/tests/Makefile.am | 50 +
src/wok/plugins/kimchi/tests/iso_gen.py | 212 ++
src/wok/plugins/kimchi/tests/run_tests.sh.in | 55 +
src/wok/plugins/kimchi/tests/test_authorization.py | 178 ++
src/wok/plugins/kimchi/tests/test_config.py.in | 267 +++
src/wok/plugins/kimchi/tests/test_exception.py | 123 +
src/wok/plugins/kimchi/tests/test_host.py | 206 ++
src/wok/plugins/kimchi/tests/test_mock_network.py | 73 +
.../plugins/kimchi/tests/test_mock_storagepool.py | 147 ++
.../kimchi/tests/test_mock_storagevolume.py | 98 +
src/wok/plugins/kimchi/tests/test_mockmodel.py | 141 ++
src/wok/plugins/kimchi/tests/test_model.py | 1248 +++++++++++
src/wok/plugins/kimchi/tests/test_model_network.py | 149 ++
.../plugins/kimchi/tests/test_model_storagepool.py | 123 +
.../kimchi/tests/test_model_storagevolume.py | 280 +++
src/wok/plugins/kimchi/tests/test_networkxml.py | 172 ++
src/wok/plugins/kimchi/tests/test_objectstore.py | 97 +
src/wok/plugins/kimchi/tests/test_osinfo.py | 69 +
src/wok/plugins/kimchi/tests/test_plugin.py | 126 ++
src/wok/plugins/kimchi/tests/test_rest.py | 1327 +++++++++++
.../plugins/kimchi/tests/test_rollbackcontext.py | 99 +
src/wok/plugins/kimchi/tests/test_server.py | 289 +++
.../plugins/kimchi/tests/test_storagepoolxml.py | 171 ++
src/wok/plugins/kimchi/tests/test_template.py | 387 ++++
src/wok/plugins/kimchi/tests/test_utils.py | 69 +
src/wok/plugins/kimchi/tests/test_vmtemplate.py | 116 +
src/wok/plugins/kimchi/tests/test_yumparser.py | 162 ++
src/wok/plugins/kimchi/tests/utils.py | 260 +++
src/wok/plugins/kimchi/ui/Makefile.am | 20 +
src/wok/plugins/kimchi/ui/config/Makefile.am | 22 +
src/wok/plugins/kimchi/ui/config/tab-ext.xml | 38 +
src/wok/plugins/kimchi/ui/css/Makefile.am | 26 +
.../kimchi/ui/css/theme-default/guest-edit.css | 424 ++++
.../ui/css/theme-default/guest-storage-add.css | 81 +
.../plugins/kimchi/ui/css/theme-default/host.css | 287 +++
.../plugins/kimchi/ui/css/theme-default/icon.css | 106 +
.../plugins/kimchi/ui/css/theme-default/list.css | 326 +++
.../kimchi/ui/css/theme-default/network.css | 267 +++
.../kimchi/ui/css/theme-default/report-add.css | 37 +
.../kimchi/ui/css/theme-default/report-rename.css | 39 +
.../kimchi/ui/css/theme-default/repository-add.css | 42 +
.../ui/css/theme-default/repository-edit.css | 88 +
.../kimchi/ui/css/theme-default/storage.css | 550 +++++
.../css/theme-default/storagepool-add-volume.css | 36 +
.../kimchi/ui/css/theme-default/template-edit.css | 175 ++
.../kimchi/ui/css/theme-default/template.css | 85 +
.../kimchi/ui/css/theme-default/template_add.css | 317 +++
.../kimchi/ui/css/theme-default/template_list.css | 267 +++
src/wok/plugins/kimchi/ui/images/Makefile.am | 22 +
src/wok/plugins/kimchi/ui/images/icon-centos.png | Bin 0 -> 4734 bytes
src/wok/plugins/kimchi/ui/images/icon-debian.png | Bin 0 -> 4239 bytes
src/wok/plugins/kimchi/ui/images/icon-fedora.png | Bin 0 -> 4449 bytes
src/wok/plugins/kimchi/ui/images/icon-gentoo.png | Bin 0 -> 15307 bytes
src/wok/plugins/kimchi/ui/images/icon-opensuse.png | Bin 0 -> 3046 bytes
src/wok/plugins/kimchi/ui/images/icon-ubuntu.png | Bin 0 -> 4818 bytes
src/wok/plugins/kimchi/ui/images/icon-vm.png | Bin 0 -> 2976 bytes
.../kimchi/ui/images/theme-default/Makefile.am | 20 +
.../kimchi/ui/images/theme-default/ac22_pause.png | Bin 0 -> 1219 bytes
.../ui/images/theme-default/ac22_pause_grey.png | Bin 0 -> 1175 bytes
.../kimchi/ui/images/theme-default/ac24_resume.png | Bin 0 -> 1341 bytes
.../ui/images/theme-default/ac24_resume_grey.png | Bin 0 -> 1282 bytes
.../ui/images/theme-default/arrow-down-black.png | Bin 0 -> 2942 bytes
.../ui/images/theme-default/arrow-down-disable.png | Bin 0 -> 472 bytes
.../kimchi/ui/images/theme-default/arrow-down.png | Bin 0 -> 537 bytes
.../kimchi/ui/images/theme-default/arrow-up.png | Bin 0 -> 510 bytes
.../kimchi/ui/images/theme-default/arrow_out.png | Bin 0 -> 3048 bytes
.../kimchi/ui/images/theme-default/group.png | Bin 0 -> 1703 bytes
.../ui/images/theme-default/host-icon-sprite.png | Bin 0 -> 1034 bytes
.../kimchi/ui/images/theme-default/icon-back.png | Bin 0 -> 244 bytes
.../kimchi/ui/images/theme-default/icon-camera.png | Bin 0 -> 4860 bytes
.../kimchi/ui/images/theme-default/icon-design.png | Bin 0 -> 4562 bytes
.../kimchi/ui/images/theme-default/icon-detail.png | Bin 0 -> 3079 bytes
.../kimchi/ui/images/theme-default/icon-iso.png | Bin 0 -> 4188 bytes
.../kimchi/ui/images/theme-default/icon-list.png | Bin 0 -> 2983 bytes
.../kimchi/ui/images/theme-default/icon-load.png | Bin 0 -> 3678 bytes
.../kimchi/ui/images/theme-default/icon-local.png | Bin 0 -> 425 bytes
.../ui/images/theme-default/icon-power-down.png | Bin 0 -> 4372 bytes
.../ui/images/theme-default/icon-power-up.png | Bin 0 -> 4367 bytes
.../kimchi/ui/images/theme-default/icon-qcow2.png | Bin 0 -> 4684 bytes
.../kimchi/ui/images/theme-default/icon-raw.png | Bin 0 -> 4679 bytes
.../kimchi/ui/images/theme-default/icon-remote.png | Bin 0 -> 1005 bytes
.../kimchi/ui/images/theme-default/icon-reset.png | Bin 0 -> 4576 bytes
.../kimchi/ui/images/theme-default/icon-search.png | Bin 0 -> 4197 bytes
.../kimchi/ui/images/theme-default/icon-sort.png | Bin 0 -> 3421 bytes
.../kimchi/ui/images/theme-default/icon-tree.png | Bin 0 -> 3526 bytes
.../kimchi/ui/images/theme-default/icon-user.png | Bin 0 -> 5366 bytes
.../images/theme-default/icon-volume-default.png | Bin 0 -> 4265 bytes
.../images/theme-default/kimchi-loading15x15.gif | Bin 0 -> 1653 bytes
.../kimchi/ui/images/theme-default/loading.gif | Bin 0 -> 2190 bytes
.../kimchi/ui/images/theme-default/user.png | Bin 0 -> 1322 bytes
src/wok/plugins/kimchi/ui/js/Makefile.am | 27 +
src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 1355 +++++++++++
.../kimchi/ui/js/src/kimchi.guest_add_main.js | 86 +
.../kimchi/ui/js/src/kimchi.guest_edit_main.js | 759 +++++++
.../plugins/kimchi/ui/js/src/kimchi.guest_main.js | 511 +++++
.../kimchi/ui/js/src/kimchi.guest_media_main.js | 56 +
.../ui/js/src/kimchi.guest_storage_add.main.js | 199 ++
src/wok/plugins/kimchi/ui/js/src/kimchi.host.js | 858 +++++++
src/wok/plugins/kimchi/ui/js/src/kimchi.main.js | 26 +
src/wok/plugins/kimchi/ui/js/src/kimchi.network.js | 442 ++++
.../kimchi/ui/js/src/kimchi.report_add_main.js | 72 +
.../kimchi/ui/js/src/kimchi.report_rename_main.js | 66 +
.../kimchi/ui/js/src/kimchi.repository_add_main.js | 96 +
.../ui/js/src/kimchi.repository_edit_main.js | 74 +
.../kimchi/ui/js/src/kimchi.storage_main.js | 428 ++++
.../ui/js/src/kimchi.storagepool_add_main.js | 414 ++++
.../js/src/kimchi.storagepool_add_volume_main.js | 179 ++
.../kimchi/ui/js/src/kimchi.template_add_main.js | 441 ++++
.../kimchi/ui/js/src/kimchi.template_edit_main.js | 343 +++
.../kimchi/ui/js/src/kimchi.template_main.js | 111 +
src/wok/plugins/kimchi/ui/pages/Makefile.am | 22 +
.../plugins/kimchi/ui/pages/guest-add.html.tmpl | 98 +
.../plugins/kimchi/ui/pages/guest-edit.html.tmpl | 311 +++
.../kimchi/ui/pages/guest-storage-add.html.tmpl | 103 +
src/wok/plugins/kimchi/ui/pages/guest.html.tmpl | 77 +
src/wok/plugins/kimchi/ui/pages/guests.html.tmpl | 65 +
src/wok/plugins/kimchi/ui/pages/help/Makefile.am | 34 +
.../plugins/kimchi/ui/pages/help/de_DE/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/de_DE/guests.dita | 127 ++
.../plugins/kimchi/ui/pages/help/de_DE/host.dita | 49 +
.../kimchi/ui/pages/help/de_DE/network.dita | 62 +
.../kimchi/ui/pages/help/de_DE/storage.dita | 86 +
.../kimchi/ui/pages/help/de_DE/templates.dita | 112 +
src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl | 26 +
.../plugins/kimchi/ui/pages/help/en_US/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/en_US/guests.dita | 136 ++
.../plugins/kimchi/ui/pages/help/en_US/host.dita | 70 +
.../kimchi/ui/pages/help/en_US/network.dita | 68 +
.../kimchi/ui/pages/help/en_US/storage.dita | 99 +
.../kimchi/ui/pages/help/en_US/templates.dita | 123 +
.../plugins/kimchi/ui/pages/help/es_ES/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/es_ES/guests.dita | 120 +
.../plugins/kimchi/ui/pages/help/es_ES/host.dita | 49 +
.../kimchi/ui/pages/help/es_ES/network.dita | 61 +
.../kimchi/ui/pages/help/es_ES/storage.dita | 86 +
.../kimchi/ui/pages/help/es_ES/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/fr_FR/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/fr_FR/guests.dita | 130 ++
.../plugins/kimchi/ui/pages/help/fr_FR/host.dita | 68 +
.../kimchi/ui/pages/help/fr_FR/network.dita | 67 +
.../kimchi/ui/pages/help/fr_FR/storage.dita | 93 +
.../kimchi/ui/pages/help/fr_FR/templates.dita | 120 +
.../plugins/kimchi/ui/pages/help/it_IT/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/it_IT/guests.dita | 123 +
.../plugins/kimchi/ui/pages/help/it_IT/host.dita | 51 +
.../kimchi/ui/pages/help/it_IT/network.dita | 63 +
.../kimchi/ui/pages/help/it_IT/storage.dita | 91 +
.../kimchi/ui/pages/help/it_IT/templates.dita | 115 +
.../plugins/kimchi/ui/pages/help/ja_JP/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/ja_JP/guests.dita | 172 ++
.../plugins/kimchi/ui/pages/help/ja_JP/host.dita | 70 +
.../kimchi/ui/pages/help/ja_JP/network.dita | 83 +
.../kimchi/ui/pages/help/ja_JP/storage.dita | 120 +
.../kimchi/ui/pages/help/ja_JP/templates.dita | 150 ++
src/wok/plugins/kimchi/ui/pages/help/kimchi.css | 208 ++
.../plugins/kimchi/ui/pages/help/ko_KR/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/ko_KR/guests.dita | 119 +
.../plugins/kimchi/ui/pages/help/ko_KR/host.dita | 47 +
.../kimchi/ui/pages/help/ko_KR/network.dita | 61 +
.../kimchi/ui/pages/help/ko_KR/storage.dita | 86 +
.../kimchi/ui/pages/help/ko_KR/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/pt_BR/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/pt_BR/guests.dita | 137 ++
.../plugins/kimchi/ui/pages/help/pt_BR/host.dita | 74 +
.../kimchi/ui/pages/help/pt_BR/network.dita | 72 +
.../kimchi/ui/pages/help/pt_BR/storage.dita | 102 +
.../kimchi/ui/pages/help/pt_BR/templates.dita | 127 ++
.../plugins/kimchi/ui/pages/help/ru_RU/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/ru_RU/guests.dita | 122 +
.../plugins/kimchi/ui/pages/help/ru_RU/host.dita | 48 +
.../kimchi/ui/pages/help/ru_RU/network.dita | 61 +
.../kimchi/ui/pages/help/ru_RU/storage.dita | 88 +
.../kimchi/ui/pages/help/ru_RU/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/zh_CN/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/zh_CN/guests.dita | 118 +
.../plugins/kimchi/ui/pages/help/zh_CN/host.dita | 45 +
.../kimchi/ui/pages/help/zh_CN/network.dita | 61 +
.../kimchi/ui/pages/help/zh_CN/storage.dita | 84 +
.../kimchi/ui/pages/help/zh_CN/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/zh_TW/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/zh_TW/guests.dita | 120 +
.../plugins/kimchi/ui/pages/help/zh_TW/host.dita | 50 +
.../kimchi/ui/pages/help/zh_TW/network.dita | 61 +
.../kimchi/ui/pages/help/zh_TW/storage.dita | 88 +
.../kimchi/ui/pages/help/zh_TW/templates.dita | 112 +
src/wok/plugins/kimchi/ui/pages/host.html.tmpl | 177 ++
src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl | 187 ++
src/wok/plugins/kimchi/ui/pages/network.html.tmpl | 133 ++
.../plugins/kimchi/ui/pages/report-add.html.tmpl | 56 +
.../kimchi/ui/pages/report-rename.html.tmpl | 56 +
.../kimchi/ui/pages/repository-add.html.tmpl | 113 +
.../kimchi/ui/pages/repository-edit.html.tmpl | 117 +
src/wok/plugins/kimchi/ui/pages/storage.html.tmpl | 143 ++
.../ui/pages/storagepool-add-volume.html.tmpl | 79 +
.../kimchi/ui/pages/storagepool-add.html.tmpl | 186 ++
.../plugins/kimchi/ui/pages/template-add.html.tmpl | 233 ++
.../kimchi/ui/pages/template-edit.html.tmpl | 193 ++
.../plugins/kimchi/ui/pages/templates.html.tmpl | 77 +
src/wok/plugins/kimchi/ui/robots.txt | 2 +
src/wok/plugins/kimchi/ui/spice-html5/Makefile.am | 25 +
.../plugins/kimchi/ui/spice-html5/atKeynames.js | 183 ++
src/wok/plugins/kimchi/ui/spice-html5/bitmap.js | 51 +
.../plugins/kimchi/ui/spice-html5/css/Makefile.am | 20 +
.../plugins/kimchi/ui/spice-html5/css/spice.css | 118 +
src/wok/plugins/kimchi/ui/spice-html5/cursor.js | 110 +
src/wok/plugins/kimchi/ui/spice-html5/display.js | 823 +++++++
src/wok/plugins/kimchi/ui/spice-html5/enums.js | 324 +++
src/wok/plugins/kimchi/ui/spice-html5/inputs.js | 280 +++
src/wok/plugins/kimchi/ui/spice-html5/lz.js | 166 ++
src/wok/plugins/kimchi/ui/spice-html5/main.js | 231 ++
.../kimchi/ui/spice-html5/pages/Makefile.am | 20 +
.../kimchi/ui/spice-html5/pages/spice_auto.html | 200 ++
src/wok/plugins/kimchi/ui/spice-html5/playback.js | 278 +++
src/wok/plugins/kimchi/ui/spice-html5/png.js | 256 +++
src/wok/plugins/kimchi/ui/spice-html5/quic.js | 1335 +++++++++++
src/wok/plugins/kimchi/ui/spice-html5/resize.js | 70 +
.../kimchi/ui/spice-html5/simulatecursor.js | 202 ++
.../kimchi/ui/spice-html5/spicearraybuffer.js | 58 +
src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js | 460 ++++
.../plugins/kimchi/ui/spice-html5/spicedataview.js | 120 +
src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js | 1047 +++++++++
src/wok/plugins/kimchi/ui/spice-html5/spicetype.js | 473 ++++
.../kimchi/ui/spice-html5/thirdparty/Makefile.am | 20 +
.../kimchi/ui/spice-html5/thirdparty/jsbn.js | 589 +++++
.../kimchi/ui/spice-html5/thirdparty/prng4.js | 79 +
.../kimchi/ui/spice-html5/thirdparty/rng.js | 102 +
.../kimchi/ui/spice-html5/thirdparty/rsa.js | 146 ++
.../kimchi/ui/spice-html5/thirdparty/sha1.js | 346 +++
src/wok/plugins/kimchi/ui/spice-html5/ticket.js | 250 +++
src/wok/plugins/kimchi/ui/spice-html5/utils.js | 265 +++
src/wok/plugins/kimchi/ui/spice-html5/webm.js | 553 +++++
src/wok/plugins/kimchi/ui/spice-html5/wire.js | 123 +
src/wok/plugins/kimchi/utils.py | 39 +
src/wok/plugins/kimchi/vmtemplate.py | 431 ++++
src/wok/plugins/kimchi/vnc.py | 77 +
src/wok/plugins/kimchi/xmlutils/Makefile.am | 25 +
src/wok/plugins/kimchi/xmlutils/__init__.py | 18 +
src/wok/plugins/kimchi/xmlutils/cpu.py | 60 +
src/wok/plugins/kimchi/xmlutils/disk.py | 164 ++
src/wok/plugins/kimchi/xmlutils/graphics.py | 45 +
src/wok/plugins/kimchi/xmlutils/interface.py | 61 +
src/wok/plugins/kimchi/xmlutils/network.py | 122 +
src/wok/plugins/kimchi/xmlutils/qemucmdline.py | 45 +
src/wok/plugins/kimchi/yumparser.py | 283 +++
src/wok/plugins/sample/API.json | 56 +
src/wok/plugins/sample/Makefile.am | 29 +
src/wok/plugins/sample/__init__.py | 97 +
src/wok/plugins/sample/config.status | 1 +
src/wok/plugins/sample/i18n.py | 40 +
src/wok/plugins/sample/model.py | 131 ++
src/wok/plugins/sample/po/LINGUAS | 3 +
src/wok/plugins/sample/po/Makefile.in.in | 400 ++++
src/wok/plugins/sample/po/Makevars | 41 +
src/wok/plugins/sample/po/POTFILES.in | 2 +
src/wok/plugins/sample/po/en_US.po | 21 +
src/wok/plugins/sample/po/gen-pot | 9 +
src/wok/plugins/sample/po/pt_BR.po | 24 +
src/wok/plugins/sample/po/sample.pot | 21 +
src/wok/plugins/sample/po/zh_CN.po | 24 +
src/wok/plugins/sample/sample.conf.in | 27 +
src/wok/plugins/sample/ui/Makefile.am | 22 +
src/wok/plugins/sample/ui/config/Makefile.am | 21 +
src/wok/plugins/sample/ui/config/tab-ext.xml | 17 +
src/wok/plugins/sample/ui/css/.gitignore | 0
src/wok/plugins/sample/ui/images/.gitignore | 0
src/wok/plugins/sample/ui/js/.gitignore | 0
src/wok/plugins/sample/ui/js/Makefile.am | 20 +
src/wok/plugins/sample/ui/js/util.js | 33 +
src/wok/plugins/sample/ui/libs/.gitignore | 0
src/wok/plugins/sample/ui/pages/Makefile.am | 20 +
.../sample/ui/pages/help/en_US/sample-tab1.html | 1 +
.../sample/ui/pages/help/en_US/sample-tab2.html | 1 +
src/wok/plugins/sample/ui/pages/i18n.json.tmpl | 26 +
.../plugins/sample/ui/pages/sample-tab1.html.tmpl | 30 +
.../plugins/sample/ui/pages/sample-tab2.html.tmpl | 30 +
812 files changed, 82736 insertions(+), 82736 deletions(-)
delete mode 100644 plugins/Makefile.am
delete mode 100644 plugins/__init__.py
delete mode 100644 plugins/kimchi/.gitignore
delete mode 100644 plugins/kimchi/API.json
delete mode 100644 plugins/kimchi/INSTALL
delete mode 100644 plugins/kimchi/Makefile.am
delete mode 120000 plugins/kimchi/README.md
delete mode 100644 plugins/kimchi/VERSION
delete mode 100644 plugins/kimchi/__init__.py
delete mode 100755 plugins/kimchi/autogen.sh
delete mode 100644 plugins/kimchi/build-aux/config.rpath
delete mode 100755 plugins/kimchi/build-aux/genChangelog
delete mode 100755 plugins/kimchi/build-aux/pkg-version
delete mode 100644 plugins/kimchi/config.py.in
delete mode 100644 plugins/kimchi/config.rpath
delete mode 100644 plugins/kimchi/configure.ac
delete mode 100644 plugins/kimchi/contrib/DEBIAN/Makefile.am
delete mode 100644 plugins/kimchi/contrib/DEBIAN/control.in
delete mode 100644 plugins/kimchi/contrib/Makefile.am
delete mode 100755 plugins/kimchi/contrib/check_i18n.py
delete mode 100644 plugins/kimchi/contrib/kimchi.spec.fedora.in
delete mode 100644 plugins/kimchi/contrib/kimchi.spec.suse.in
delete mode 100644 plugins/kimchi/contrib/make-deb.sh.in
delete mode 100644 plugins/kimchi/control/Makefile.am
delete mode 100644 plugins/kimchi/control/__init__.py
delete mode 100644 plugins/kimchi/control/config.py
delete mode 100644 plugins/kimchi/control/cpuinfo.py
delete mode 100644 plugins/kimchi/control/debugreports.py
delete mode 100644 plugins/kimchi/control/groups.py
delete mode 100644 plugins/kimchi/control/host.py
delete mode 100644 plugins/kimchi/control/interfaces.py
delete mode 100644 plugins/kimchi/control/networks.py
delete mode 100644 plugins/kimchi/control/peers.py
delete mode 100644 plugins/kimchi/control/storagepools.py
delete mode 100644 plugins/kimchi/control/storageservers.py
delete mode 100644 plugins/kimchi/control/storagevolumes.py
delete mode 100644 plugins/kimchi/control/templates.py
delete mode 100644 plugins/kimchi/control/users.py
delete mode 100644 plugins/kimchi/control/vm/Makefile.am
delete mode 100644 plugins/kimchi/control/vm/__init__.py
delete mode 100644 plugins/kimchi/control/vm/hostdevs.py
delete mode 100644 plugins/kimchi/control/vm/ifaces.py
delete mode 100644 plugins/kimchi/control/vm/snapshots.py
delete mode 100644 plugins/kimchi/control/vm/storages.py
delete mode 100644 plugins/kimchi/control/vms.py
delete mode 100644 plugins/kimchi/disks.py
delete mode 100644 plugins/kimchi/distroloader.py
delete mode 100644 plugins/kimchi/distros.d/Makefile.am
delete mode 100644 plugins/kimchi/distros.d/debian.json
delete mode 100644 plugins/kimchi/distros.d/fedora.json
delete mode 100644 plugins/kimchi/distros.d/gentoo.json
delete mode 100644 plugins/kimchi/distros.d/opensuse.json
delete mode 100644 plugins/kimchi/distros.d/ubuntu.json
delete mode 100644 plugins/kimchi/docs/API.md
delete mode 100644 plugins/kimchi/docs/Makefile.am
delete mode 100644 plugins/kimchi/docs/README-federation.md
delete mode 100644 plugins/kimchi/docs/README.md
delete mode 100644 plugins/kimchi/docs/kimchi-guest.png
delete mode 100644 plugins/kimchi/docs/kimchi-login.png
delete mode 100644 plugins/kimchi/docs/kimchi-templates.png
delete mode 100644 plugins/kimchi/i18n.py
delete mode 100644 plugins/kimchi/imageinfo.py
delete mode 100644 plugins/kimchi/iscsi.py
delete mode 100644 plugins/kimchi/isoinfo.py
delete mode 100644 plugins/kimchi/kimchi.conf
delete mode 100644 plugins/kimchi/kvmusertests.py
delete mode 100644 plugins/kimchi/m4/ac_python_module.m4
delete mode 100644 plugins/kimchi/m4/gettext.m4
delete mode 100644 plugins/kimchi/m4/iconv.m4
delete mode 100644 plugins/kimchi/m4/intlmacosx.m4
delete mode 100644 plugins/kimchi/m4/lib-ld.m4
delete mode 100644 plugins/kimchi/m4/lib-link.m4
delete mode 100644 plugins/kimchi/m4/lib-prefix.m4
delete mode 100644 plugins/kimchi/m4/nls.m4
delete mode 100644 plugins/kimchi/m4/po.m4
delete mode 100644 plugins/kimchi/m4/progtest.m4
delete mode 100644 plugins/kimchi/mockmodel.py
delete mode 100644 plugins/kimchi/model/Makefile.am
delete mode 100644 plugins/kimchi/model/__init__.py
delete mode 100644 plugins/kimchi/model/config.py
delete mode 100644 plugins/kimchi/model/cpuinfo.py
delete mode 100644 plugins/kimchi/model/debugreports.py
delete mode 100644 plugins/kimchi/model/diskutils.py
delete mode 100644 plugins/kimchi/model/featuretests.py
delete mode 100644 plugins/kimchi/model/groups.py
delete mode 100644 plugins/kimchi/model/host.py
delete mode 100644 plugins/kimchi/model/hostdev.py
delete mode 100644 plugins/kimchi/model/interfaces.py
delete mode 100644 plugins/kimchi/model/libvirtconnection.py
delete mode 100644 plugins/kimchi/model/libvirtstoragepool.py
delete mode 100644 plugins/kimchi/model/model.py
delete mode 100644 plugins/kimchi/model/networks.py
delete mode 100644 plugins/kimchi/model/peers.py
delete mode 100644 plugins/kimchi/model/storagepools.py
delete mode 100644 plugins/kimchi/model/storageservers.py
delete mode 100644 plugins/kimchi/model/storagetargets.py
delete mode 100644 plugins/kimchi/model/storagevolumes.py
delete mode 100644 plugins/kimchi/model/templates.py
delete mode 100644 plugins/kimchi/model/users.py
delete mode 100644 plugins/kimchi/model/utils.py
delete mode 100644 plugins/kimchi/model/vmhostdevs.py
delete mode 100644 plugins/kimchi/model/vmifaces.py
delete mode 100644 plugins/kimchi/model/vms.py
delete mode 100644 plugins/kimchi/model/vmsnapshots.py
delete mode 100644 plugins/kimchi/model/vmstorages.py
delete mode 100644 plugins/kimchi/netinfo.py
delete mode 100644 plugins/kimchi/network.py
delete mode 100644 plugins/kimchi/osinfo.py
delete mode 100644 plugins/kimchi/po/LINGUAS
delete mode 100644 plugins/kimchi/po/Makefile.in.in
delete mode 100644 plugins/kimchi/po/Makevars
delete mode 100644 plugins/kimchi/po/POTFILES.in
delete mode 100644 plugins/kimchi/po/de_DE.po
delete mode 100644 plugins/kimchi/po/en_US.po
delete mode 100644 plugins/kimchi/po/es_ES.po
delete mode 100644 plugins/kimchi/po/fr_FR.po
delete mode 100644 plugins/kimchi/po/gen-pot.in
delete mode 100644 plugins/kimchi/po/it_IT.po
delete mode 100644 plugins/kimchi/po/ja_JP.po
delete mode 100755 plugins/kimchi/po/kimchi.pot
delete mode 100644 plugins/kimchi/po/ko_KR.po
delete mode 100644 plugins/kimchi/po/pt_BR.po
delete mode 100644 plugins/kimchi/po/ru_RU.po
delete mode 100644 plugins/kimchi/po/zh_CN.po
delete mode 100644 plugins/kimchi/po/zh_TW.po
delete mode 100644 plugins/kimchi/repositories.py
delete mode 100644 plugins/kimchi/root.py
delete mode 100644 plugins/kimchi/scan.py
delete mode 100644 plugins/kimchi/screenshot.py
delete mode 100644 plugins/kimchi/swupdate.py
delete mode 100644 plugins/kimchi/template.conf
delete mode 100644 plugins/kimchi/tests/Makefile.am
delete mode 100644 plugins/kimchi/tests/iso_gen.py
delete mode 100644 plugins/kimchi/tests/run_tests.sh.in
delete mode 100644 plugins/kimchi/tests/test_authorization.py
delete mode 100644 plugins/kimchi/tests/test_config.py.in
delete mode 100644 plugins/kimchi/tests/test_exception.py
delete mode 100644 plugins/kimchi/tests/test_host.py
delete mode 100644 plugins/kimchi/tests/test_mock_network.py
delete mode 100644 plugins/kimchi/tests/test_mock_storagepool.py
delete mode 100644 plugins/kimchi/tests/test_mock_storagevolume.py
delete mode 100644 plugins/kimchi/tests/test_mockmodel.py
delete mode 100644 plugins/kimchi/tests/test_model.py
delete mode 100644 plugins/kimchi/tests/test_model_network.py
delete mode 100644 plugins/kimchi/tests/test_model_storagepool.py
delete mode 100644 plugins/kimchi/tests/test_model_storagevolume.py
delete mode 100644 plugins/kimchi/tests/test_networkxml.py
delete mode 100644 plugins/kimchi/tests/test_objectstore.py
delete mode 100644 plugins/kimchi/tests/test_osinfo.py
delete mode 100644 plugins/kimchi/tests/test_plugin.py
delete mode 100644 plugins/kimchi/tests/test_rest.py
delete mode 100644 plugins/kimchi/tests/test_rollbackcontext.py
delete mode 100644 plugins/kimchi/tests/test_server.py
delete mode 100644 plugins/kimchi/tests/test_storagepoolxml.py
delete mode 100644 plugins/kimchi/tests/test_template.py
delete mode 100644 plugins/kimchi/tests/test_utils.py
delete mode 100644 plugins/kimchi/tests/test_vmtemplate.py
delete mode 100644 plugins/kimchi/tests/test_yumparser.py
delete mode 100644 plugins/kimchi/tests/utils.py
delete mode 100644 plugins/kimchi/ui/Makefile.am
delete mode 100644 plugins/kimchi/ui/config/Makefile.am
delete mode 100644 plugins/kimchi/ui/config/tab-ext.xml
delete mode 100644 plugins/kimchi/ui/css/Makefile.am
delete mode 100644 plugins/kimchi/ui/css/theme-default/guest-edit.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/guest-storage-add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/host.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/icon.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/list.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/network.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/report-add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/report-rename.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/repository-add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/repository-edit.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/storage.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template-edit.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template_add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template_list.css
delete mode 100644 plugins/kimchi/ui/images/Makefile.am
delete mode 100644 plugins/kimchi/ui/images/icon-centos.png
delete mode 100644 plugins/kimchi/ui/images/icon-debian.png
delete mode 100644 plugins/kimchi/ui/images/icon-fedora.png
delete mode 100644 plugins/kimchi/ui/images/icon-gentoo.png
delete mode 100644 plugins/kimchi/ui/images/icon-opensuse.png
delete mode 100644 plugins/kimchi/ui/images/icon-ubuntu.png
delete mode 100644 plugins/kimchi/ui/images/icon-vm.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/Makefile.am
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac22_pause.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac24_resume.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down-black.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-up.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow_out.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/group.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-back.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-camera.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-design.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-detail.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-iso.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-list.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-load.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-local.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-power-down.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-power-up.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-qcow2.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-raw.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-remote.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-reset.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-search.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-sort.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-tree.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-user.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-volume-default.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
delete mode 100644 plugins/kimchi/ui/images/theme-default/loading.gif
delete mode 100644 plugins/kimchi/ui/images/theme-default/user.png
delete mode 100644 plugins/kimchi/ui/js/Makefile.am
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.api.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.host.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.network.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.report_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.storage_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.template_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.template_main.js
delete mode 100644 plugins/kimchi/ui/pages/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/guest-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guest-edit.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guest.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guests.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/help/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/dita-help.xsl
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/kimchi.css
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/host.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/i18n.json.tmpl
delete mode 100644 plugins/kimchi/ui/pages/network.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/report-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/report-rename.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/repository-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/repository-edit.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/storage.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/storagepool-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/template-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/template-edit.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/templates.html.tmpl
delete mode 100644 plugins/kimchi/ui/robots.txt
delete mode 100644 plugins/kimchi/ui/spice-html5/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/atKeynames.js
delete mode 100644 plugins/kimchi/ui/spice-html5/bitmap.js
delete mode 100644 plugins/kimchi/ui/spice-html5/css/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/css/spice.css
delete mode 100644 plugins/kimchi/ui/spice-html5/cursor.js
delete mode 100644 plugins/kimchi/ui/spice-html5/display.js
delete mode 100644 plugins/kimchi/ui/spice-html5/enums.js
delete mode 100644 plugins/kimchi/ui/spice-html5/inputs.js
delete mode 100644 plugins/kimchi/ui/spice-html5/lz.js
delete mode 100644 plugins/kimchi/ui/spice-html5/main.js
delete mode 100644 plugins/kimchi/ui/spice-html5/pages/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/pages/spice_auto.html
delete mode 100644 plugins/kimchi/ui/spice-html5/playback.js
delete mode 100644 plugins/kimchi/ui/spice-html5/png.js
delete mode 100644 plugins/kimchi/ui/spice-html5/quic.js
delete mode 100644 plugins/kimchi/ui/spice-html5/resize.js
delete mode 100644 plugins/kimchi/ui/spice-html5/simulatecursor.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicearraybuffer.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spiceconn.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicedataview.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicemsg.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicetype.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/rng.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
delete mode 100644 plugins/kimchi/ui/spice-html5/ticket.js
delete mode 100644 plugins/kimchi/ui/spice-html5/utils.js
delete mode 100644 plugins/kimchi/ui/spice-html5/webm.js
delete mode 100644 plugins/kimchi/ui/spice-html5/wire.js
delete mode 100644 plugins/kimchi/utils.py
delete mode 100644 plugins/kimchi/vmtemplate.py
delete mode 100644 plugins/kimchi/vnc.py
delete mode 100644 plugins/kimchi/xmlutils/Makefile.am
delete mode 100644 plugins/kimchi/xmlutils/__init__.py
delete mode 100644 plugins/kimchi/xmlutils/cpu.py
delete mode 100644 plugins/kimchi/xmlutils/disk.py
delete mode 100644 plugins/kimchi/xmlutils/graphics.py
delete mode 100644 plugins/kimchi/xmlutils/interface.py
delete mode 100644 plugins/kimchi/xmlutils/network.py
delete mode 100644 plugins/kimchi/xmlutils/qemucmdline.py
delete mode 100644 plugins/kimchi/yumparser.py
delete mode 100644 plugins/sample/API.json
delete mode 100644 plugins/sample/Makefile.am
delete mode 100644 plugins/sample/__init__.py
delete mode 120000 plugins/sample/config.status
delete mode 100644 plugins/sample/i18n.py
delete mode 100644 plugins/sample/model.py
delete mode 100644 plugins/sample/po/LINGUAS
delete mode 100644 plugins/sample/po/Makefile.in.in
delete mode 100644 plugins/sample/po/Makevars
delete mode 100644 plugins/sample/po/POTFILES.in
delete mode 100644 plugins/sample/po/en_US.po
delete mode 100755 plugins/sample/po/gen-pot
delete mode 100644 plugins/sample/po/pt_BR.po
delete mode 100644 plugins/sample/po/sample.pot
delete mode 100644 plugins/sample/po/zh_CN.po
delete mode 100644 plugins/sample/sample.conf.in
delete mode 100644 plugins/sample/ui/Makefile.am
delete mode 100644 plugins/sample/ui/config/Makefile.am
delete mode 100644 plugins/sample/ui/config/tab-ext.xml
delete mode 100644 plugins/sample/ui/css/.gitignore
delete mode 100644 plugins/sample/ui/images/.gitignore
delete mode 100644 plugins/sample/ui/js/.gitignore
delete mode 100644 plugins/sample/ui/js/Makefile.am
delete mode 100644 plugins/sample/ui/js/util.js
delete mode 100644 plugins/sample/ui/libs/.gitignore
delete mode 100644 plugins/sample/ui/pages/Makefile.am
delete mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab1.html
delete mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab2.html
delete mode 100644 plugins/sample/ui/pages/i18n.json.tmpl
delete mode 100644 plugins/sample/ui/pages/sample-tab1.html.tmpl
delete mode 100644 plugins/sample/ui/pages/sample-tab2.html.tmpl
create mode 100644 src/wok/plugins/Makefile.am
create mode 100644 src/wok/plugins/__init__.py
create mode 100644 src/wok/plugins/kimchi/.gitignore
create mode 100644 src/wok/plugins/kimchi/API.json
create mode 100644 src/wok/plugins/kimchi/INSTALL
create mode 100644 src/wok/plugins/kimchi/Makefile.am
create mode 120000 src/wok/plugins/kimchi/README.md
create mode 100644 src/wok/plugins/kimchi/VERSION
create mode 100644 src/wok/plugins/kimchi/__init__.py
create mode 100755 src/wok/plugins/kimchi/autogen.sh
create mode 100644 src/wok/plugins/kimchi/build-aux/config.rpath
create mode 100755 src/wok/plugins/kimchi/build-aux/genChangelog
create mode 100755 src/wok/plugins/kimchi/build-aux/pkg-version
create mode 100644 src/wok/plugins/kimchi/config.py.in
create mode 100644 src/wok/plugins/kimchi/config.rpath
create mode 100644 src/wok/plugins/kimchi/configure.ac
create mode 100644 src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am
create mode 100644 src/wok/plugins/kimchi/contrib/DEBIAN/control.in
create mode 100644 src/wok/plugins/kimchi/contrib/Makefile.am
create mode 100755 src/wok/plugins/kimchi/contrib/check_i18n.py
create mode 100644 src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in
create mode 100644 src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in
create mode 100644 src/wok/plugins/kimchi/contrib/make-deb.sh.in
create mode 100644 src/wok/plugins/kimchi/control/Makefile.am
create mode 100644 src/wok/plugins/kimchi/control/__init__.py
create mode 100644 src/wok/plugins/kimchi/control/config.py
create mode 100644 src/wok/plugins/kimchi/control/cpuinfo.py
create mode 100644 src/wok/plugins/kimchi/control/debugreports.py
create mode 100644 src/wok/plugins/kimchi/control/groups.py
create mode 100644 src/wok/plugins/kimchi/control/host.py
create mode 100644 src/wok/plugins/kimchi/control/interfaces.py
create mode 100644 src/wok/plugins/kimchi/control/networks.py
create mode 100644 src/wok/plugins/kimchi/control/peers.py
create mode 100644 src/wok/plugins/kimchi/control/storagepools.py
create mode 100644 src/wok/plugins/kimchi/control/storageservers.py
create mode 100644 src/wok/plugins/kimchi/control/storagevolumes.py
create mode 100644 src/wok/plugins/kimchi/control/templates.py
create mode 100644 src/wok/plugins/kimchi/control/users.py
create mode 100644 src/wok/plugins/kimchi/control/vm/Makefile.am
create mode 100644 src/wok/plugins/kimchi/control/vm/__init__.py
create mode 100644 src/wok/plugins/kimchi/control/vm/hostdevs.py
create mode 100644 src/wok/plugins/kimchi/control/vm/ifaces.py
create mode 100644 src/wok/plugins/kimchi/control/vm/snapshots.py
create mode 100644 src/wok/plugins/kimchi/control/vm/storages.py
create mode 100644 src/wok/plugins/kimchi/control/vms.py
create mode 100644 src/wok/plugins/kimchi/disks.py
create mode 100644 src/wok/plugins/kimchi/distroloader.py
create mode 100644 src/wok/plugins/kimchi/distros.d/Makefile.am
create mode 100644 src/wok/plugins/kimchi/distros.d/debian.json
create mode 100644 src/wok/plugins/kimchi/distros.d/fedora.json
create mode 100644 src/wok/plugins/kimchi/distros.d/gentoo.json
create mode 100644 src/wok/plugins/kimchi/distros.d/opensuse.json
create mode 100644 src/wok/plugins/kimchi/distros.d/ubuntu.json
create mode 100644 src/wok/plugins/kimchi/docs/API.md
create mode 100644 src/wok/plugins/kimchi/docs/Makefile.am
create mode 100644 src/wok/plugins/kimchi/docs/README-federation.md
create mode 100644 src/wok/plugins/kimchi/docs/README.md
create mode 100644 src/wok/plugins/kimchi/docs/kimchi-guest.png
create mode 100644 src/wok/plugins/kimchi/docs/kimchi-login.png
create mode 100644 src/wok/plugins/kimchi/docs/kimchi-templates.png
create mode 100644 src/wok/plugins/kimchi/i18n.py
create mode 100644 src/wok/plugins/kimchi/imageinfo.py
create mode 100644 src/wok/plugins/kimchi/iscsi.py
create mode 100644 src/wok/plugins/kimchi/isoinfo.py
create mode 100644 src/wok/plugins/kimchi/kimchi.conf
create mode 100644 src/wok/plugins/kimchi/kvmusertests.py
create mode 100644 src/wok/plugins/kimchi/m4/ac_python_module.m4
create mode 100644 src/wok/plugins/kimchi/m4/gettext.m4
create mode 100644 src/wok/plugins/kimchi/m4/iconv.m4
create mode 100644 src/wok/plugins/kimchi/m4/intlmacosx.m4
create mode 100644 src/wok/plugins/kimchi/m4/lib-ld.m4
create mode 100644 src/wok/plugins/kimchi/m4/lib-link.m4
create mode 100644 src/wok/plugins/kimchi/m4/lib-prefix.m4
create mode 100644 src/wok/plugins/kimchi/m4/nls.m4
create mode 100644 src/wok/plugins/kimchi/m4/po.m4
create mode 100644 src/wok/plugins/kimchi/m4/progtest.m4
create mode 100644 src/wok/plugins/kimchi/mockmodel.py
create mode 100644 src/wok/plugins/kimchi/model/Makefile.am
create mode 100644 src/wok/plugins/kimchi/model/__init__.py
create mode 100644 src/wok/plugins/kimchi/model/config.py
create mode 100644 src/wok/plugins/kimchi/model/cpuinfo.py
create mode 100644 src/wok/plugins/kimchi/model/debugreports.py
create mode 100644 src/wok/plugins/kimchi/model/diskutils.py
create mode 100644 src/wok/plugins/kimchi/model/featuretests.py
create mode 100644 src/wok/plugins/kimchi/model/groups.py
create mode 100644 src/wok/plugins/kimchi/model/host.py
create mode 100644 src/wok/plugins/kimchi/model/hostdev.py
create mode 100644 src/wok/plugins/kimchi/model/interfaces.py
create mode 100644 src/wok/plugins/kimchi/model/libvirtconnection.py
create mode 100644 src/wok/plugins/kimchi/model/libvirtstoragepool.py
create mode 100644 src/wok/plugins/kimchi/model/model.py
create mode 100644 src/wok/plugins/kimchi/model/networks.py
create mode 100644 src/wok/plugins/kimchi/model/peers.py
create mode 100644 src/wok/plugins/kimchi/model/storagepools.py
create mode 100644 src/wok/plugins/kimchi/model/storageservers.py
create mode 100644 src/wok/plugins/kimchi/model/storagetargets.py
create mode 100644 src/wok/plugins/kimchi/model/storagevolumes.py
create mode 100644 src/wok/plugins/kimchi/model/templates.py
create mode 100644 src/wok/plugins/kimchi/model/users.py
create mode 100644 src/wok/plugins/kimchi/model/utils.py
create mode 100644 src/wok/plugins/kimchi/model/vmhostdevs.py
create mode 100644 src/wok/plugins/kimchi/model/vmifaces.py
create mode 100644 src/wok/plugins/kimchi/model/vms.py
create mode 100644 src/wok/plugins/kimchi/model/vmsnapshots.py
create mode 100644 src/wok/plugins/kimchi/model/vmstorages.py
create mode 100644 src/wok/plugins/kimchi/netinfo.py
create mode 100644 src/wok/plugins/kimchi/network.py
create mode 100644 src/wok/plugins/kimchi/osinfo.py
create mode 100644 src/wok/plugins/kimchi/po/LINGUAS
create mode 100644 src/wok/plugins/kimchi/po/Makefile.in.in
create mode 100644 src/wok/plugins/kimchi/po/Makevars
create mode 100644 src/wok/plugins/kimchi/po/POTFILES.in
create mode 100644 src/wok/plugins/kimchi/po/de_DE.po
create mode 100644 src/wok/plugins/kimchi/po/en_US.po
create mode 100644 src/wok/plugins/kimchi/po/es_ES.po
create mode 100644 src/wok/plugins/kimchi/po/fr_FR.po
create mode 100644 src/wok/plugins/kimchi/po/gen-pot.in
create mode 100644 src/wok/plugins/kimchi/po/it_IT.po
create mode 100644 src/wok/plugins/kimchi/po/ja_JP.po
create mode 100755 src/wok/plugins/kimchi/po/kimchi.pot
create mode 100644 src/wok/plugins/kimchi/po/ko_KR.po
create mode 100644 src/wok/plugins/kimchi/po/pt_BR.po
create mode 100644 src/wok/plugins/kimchi/po/ru_RU.po
create mode 100644 src/wok/plugins/kimchi/po/zh_CN.po
create mode 100644 src/wok/plugins/kimchi/po/zh_TW.po
create mode 100644 src/wok/plugins/kimchi/repositories.py
create mode 100644 src/wok/plugins/kimchi/root.py
create mode 100644 src/wok/plugins/kimchi/scan.py
create mode 100644 src/wok/plugins/kimchi/screenshot.py
create mode 100644 src/wok/plugins/kimchi/swupdate.py
create mode 100644 src/wok/plugins/kimchi/template.conf
create mode 100644 src/wok/plugins/kimchi/tests/Makefile.am
create mode 100644 src/wok/plugins/kimchi/tests/iso_gen.py
create mode 100644 src/wok/plugins/kimchi/tests/run_tests.sh.in
create mode 100644 src/wok/plugins/kimchi/tests/test_authorization.py
create mode 100644 src/wok/plugins/kimchi/tests/test_config.py.in
create mode 100644 src/wok/plugins/kimchi/tests/test_exception.py
create mode 100644 src/wok/plugins/kimchi/tests/test_host.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mock_network.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mock_storagepool.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mock_storagevolume.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mockmodel.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model_network.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model_storagepool.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model_storagevolume.py
create mode 100644 src/wok/plugins/kimchi/tests/test_networkxml.py
create mode 100644 src/wok/plugins/kimchi/tests/test_objectstore.py
create mode 100644 src/wok/plugins/kimchi/tests/test_osinfo.py
create mode 100644 src/wok/plugins/kimchi/tests/test_plugin.py
create mode 100644 src/wok/plugins/kimchi/tests/test_rest.py
create mode 100644 src/wok/plugins/kimchi/tests/test_rollbackcontext.py
create mode 100644 src/wok/plugins/kimchi/tests/test_server.py
create mode 100644 src/wok/plugins/kimchi/tests/test_storagepoolxml.py
create mode 100644 src/wok/plugins/kimchi/tests/test_template.py
create mode 100644 src/wok/plugins/kimchi/tests/test_utils.py
create mode 100644 src/wok/plugins/kimchi/tests/test_vmtemplate.py
create mode 100644 src/wok/plugins/kimchi/tests/test_yumparser.py
create mode 100644 src/wok/plugins/kimchi/tests/utils.py
create mode 100644 src/wok/plugins/kimchi/ui/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/config/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/config/tab-ext.xml
create mode 100644 src/wok/plugins/kimchi/ui/css/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/host.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/icon.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/list.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/network.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/report-add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/storage.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template_add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template_list.css
create mode 100644 src/wok/plugins/kimchi/ui/images/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-centos.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-debian.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-fedora.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-gentoo.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-opensuse.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-ubuntu.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-vm.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-down.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-up.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow_out.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/group.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-back.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-camera.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-design.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-detail.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-iso.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-list.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-load.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-local.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-power-down.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-power-up.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-raw.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-remote.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-reset.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-search.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-sort.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-tree.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-user.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/loading.gif
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/user.png
create mode 100644 src/wok/plugins/kimchi/ui/js/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.network.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js
create mode 100644 src/wok/plugins/kimchi/ui/pages/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guests.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/kimchi.css
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/host.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/network.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/storage.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/templates.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/robots.txt
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/bitmap.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/css/spice.css
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/cursor.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/display.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/enums.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/inputs.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/lz.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/main.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/playback.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/png.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/quic.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/resize.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicetype.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/ticket.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/utils.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/webm.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/wire.js
create mode 100644 src/wok/plugins/kimchi/utils.py
create mode 100644 src/wok/plugins/kimchi/vmtemplate.py
create mode 100644 src/wok/plugins/kimchi/vnc.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/Makefile.am
create mode 100644 src/wok/plugins/kimchi/xmlutils/__init__.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/cpu.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/disk.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/graphics.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/interface.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/network.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/qemucmdline.py
create mode 100644 src/wok/plugins/kimchi/yumparser.py
create mode 100644 src/wok/plugins/sample/API.json
create mode 100644 src/wok/plugins/sample/Makefile.am
create mode 100644 src/wok/plugins/sample/__init__.py
create mode 120000 src/wok/plugins/sample/config.status
create mode 100644 src/wok/plugins/sample/i18n.py
create mode 100644 src/wok/plugins/sample/model.py
create mode 100644 src/wok/plugins/sample/po/LINGUAS
create mode 100644 src/wok/plugins/sample/po/Makefile.in.in
create mode 100644 src/wok/plugins/sample/po/Makevars
create mode 100644 src/wok/plugins/sample/po/POTFILES.in
create mode 100644 src/wok/plugins/sample/po/en_US.po
create mode 100755 src/wok/plugins/sample/po/gen-pot
create mode 100644 src/wok/plugins/sample/po/pt_BR.po
create mode 100644 src/wok/plugins/sample/po/sample.pot
create mode 100644 src/wok/plugins/sample/po/zh_CN.po
create mode 100644 src/wok/plugins/sample/sample.conf.in
create mode 100644 src/wok/plugins/sample/ui/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/config/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/config/tab-ext.xml
create mode 100644 src/wok/plugins/sample/ui/css/.gitignore
create mode 100644 src/wok/plugins/sample/ui/images/.gitignore
create mode 100644 src/wok/plugins/sample/ui/js/.gitignore
create mode 100644 src/wok/plugins/sample/ui/js/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/js/util.js
create mode 100644 src/wok/plugins/sample/ui/libs/.gitignore
create mode 100644 src/wok/plugins/sample/ui/pages/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html
create mode 100644 src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html
create mode 100644 src/wok/plugins/sample/ui/pages/i18n.json.tmpl
create mode 100644 src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl
create mode 100644 src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
deleted file mode 100644
index 21a6ece..0000000
--- a/plugins/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = sample
-
-plugins_PYTHON = \
- __init__.py
-
-pluginsdir = $(pythondir)/wok/plugins
diff --git a/plugins/__init__.py b/plugins/__init__.py
deleted file mode 100644
index 0539a76..0000000
--- a/plugins/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/plugins/kimchi/.gitignore b/plugins/kimchi/.gitignore
deleted file mode 100644
index 1dae610..0000000
--- a/plugins/kimchi/.gitignore
+++ /dev/null
@@ -1,37 +0,0 @@
-*.pyc
-*~
-i18n/mo/*
-log
-data
-mo
-autom4te.cache
-Makefile
-Makefile.in
-aclocal.m4
-build-aux/compile
-build-aux/config.guess
-build-aux/config.sub
-build-aux/install-sh
-build-aux/missing
-build-aux/py-compile
-configure
-config.log
-config.py
-config.status
-contrib/DEBIAN/control
-contrib/kimchi.spec.fedora
-contrib/kimchi.spec.suse
-contrib/make-deb.sh
-*.min.css
-*.min.js
-*.gmo
-stamp-po
-kimchi-*.tar.gz
-tests/run_tests.sh
-tests/test_config.py
-po/POTFILES
-po/gen-pot
-*.orig
-*.rej
-*.pem
-ui/pages/help/*/*.html
diff --git a/plugins/kimchi/API.json b/plugins/kimchi/API.json
deleted file mode 100644
index f1f58ff..0000000
--- a/plugins/kimchi/API.json
+++ /dev/null
@@ -1,836 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-03/schema#",
- "title": "Kimchi API",
- "description": "Json schema for Kimchi API",
- "type": "object",
- "kimchitype": {
- "graphics": {
- "description": "Configure graphics parameters for the new VM",
- "type": "object",
- "properties": {
- "type": {
- "enum": ["spice", "vnc"],
- "error": "KCHVM0014E"
- },
- "listen": {
- "error": "KCHVM0015E",
- "type": [
- {
- "type": "string",
- "format": "ip-address"
- },
- {
- "type": "string",
- "format": "ipv6"
- }
- ]
- }
- }
- },
- "cpu_info": {
- "description": "Configure CPU specifics for a VM.",
- "type": "object",
- "properties": {
- "topology": {
- "description": "Configure the guest CPU topology.",
- "type": "object",
- "properties": {
- "sockets": {
- "type": "integer",
- "required": true,
- "minimum": 1,
- "error": "KCHTMPL0026E"
- },
- "cores": {
- "type": "integer",
- "required": true,
- "minimum": 1,
- "error": "KCHTMPL0026E"
- },
- "threads": {
- "type": "integer",
- "required": true,
- "minimum": 1,
- "error": "KCHTMPL0026E"
- }
- }
- }
- }
- }
- },
- "properties": {
- "debugreports_create": {
- "type": "object",
- "error": "KCHDR0006E",
- "properties": {
- "name": {
- "description": "The name for the debug report file.",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]*$",
- "error": "KCHDR0007E"
- }
- }
- },
- "debugreport_update": {
- "type": "object",
- "properties": {
- "name": {
- "description": "New name of debug report",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]*$",
- "error": "KCHDR0007E"
- }
- },
- "additionalProperties": false
- },
- "storagepools_create": {
- "type": "object",
- "error": "KCHPOOL0026E",
- "properties": {
- "name": {
- "description": "The name of the Storage Pool",
- "type": "string",
- "minLength": 1,
- "pattern": "^[^/]*$",
- "required": true,
- "error": "KCHPOOL0016E"
- },
- "type": {
- "description": "The type of the defined Storage Pool",
- "type": "string",
- "pattern": "^dir|netfs|logical|kimchi-iso|iscsi|scsi$",
- "required": true,
- "error": "KCHPOOL0017E"
- },
- "path": {
- "description": "The path of the defined Storage Pool",
- "type": "string",
- "error": "KCHPOOL0018E"
- },
- "source": {
- "description": "Dictionary containing source information of the pool",
- "type": "object",
- "properties": {
- "host": {
- "description": "IP or hostname of server for a pool backed from a remote host",
- "type": "string",
- "error": "KCHPOOL0019E"
- },
- "path": {
- "description": "Export path on NFS server for NFS pool",
- "type": "string",
- "error": "KCHPOOL0018E"
- },
- "devices": {
- "description": "Array of devices to be used in the Storage Pool",
- "type": "array",
- "minItems": 1,
- "uniqueItems": true,
- "error": "KCHPOOL0021E",
- "items": {
- "description": "Full path of the block device node",
- "type": "string",
- "error": "KCHPOOL0020E"
- }
- },
- "target": {
- "description": "Target IQN of an iSCSI pool",
- "type": "string",
- "error": "KCHPOOL0022E"
- },
- "port": {
- "description": "Listening port of a remote storage server",
- "type": "integer",
- "minimum": 1,
- "maximum": 65535,
- "error": "KCHPOOL0023E"
- },
- "adapter_name": {
- "description": "SCSI host name",
- "type": "string",
- "error": "KCHPOOL0030E"
- },
- "auth": {
- "description": "Storage back-end authentication information",
- "type": "object",
- "properties": {
- "username": {
- "description": "Login username of the iSCSI target",
- "type": "string",
- "error": "KCHPOOL0024E"
- },
- "password": {
- "description": "Login password of the iSCSI target",
- "type": "string",
- "error": "KCHPOOL0025E"
- }
- }
- }
- }
- }
- }
- },
- "storagepool_update": {
- "type": "object",
- "properties": {
- "autostart": {
- "description": "Set autostart value of the pool",
- "type": "boolean"
- },
- "disks": {
- "description": "List of disks/partitions to be added",
- "type": "array",
- "items": { "type": "string" },
- "minItems": 1,
- "uniqueItems": true
- }
- },
- "additionalProperties": false
- },
- "storagevolumes_create": {
- "type": "object",
- "properties": {
- "name": {
- "description": "The name of the Storage Volume",
- "type": "string",
- "minLength": 1,
- "error": "KCHVOL0013E"
- },
- "capacity": {
- "description": "The total size (MiB) of the storage volume",
- "type": "number",
- "minimum": 1,
- "error": "KCHVOL0020E"
- },
- "upload": {
- "description": "When the storage volume will be uploaded",
- "type": "boolean",
- "error": "KCHVOL0025E"
- },
- "allocation": {
- "description": "The size(MiB) of allocation when create the storage volume",
- "type": "number",
- "minimum": 1,
- "error": "KCHVOL0014E"
- },
- "format": {
- "description": "The format of the volume",
- "type": "string",
- "pattern": "^(|bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
- "error": "KCHVOL0015E"
- },
- "url": {
- "description": "The remote URL of the storage volume",
- "type": "string",
- "pattern": "^(http|ftp)[s]?://",
- "error": "KCHVOL0021E"
- }
- }
- },
- "storagevolume_update": {
- "type": "object",
- "properties": {
- "chunk": {
- "description": "Upload storage volume chunk",
- "error": "KCHVOL0024E",
- "required": true
- },
- "chunk_size": {
- "description": "Chunk size of uploaded storage volume",
- "type": "string",
- "error": "KCHVOL0024E",
- "required": true
- }
- },
- "additionalProperties": false
- },
- "vms_create": {
- "type": "object",
- "error": "KCHVM0016E",
- "properties": {
- "name": {
- "description": "The name of the new VM",
- "type": "string",
- "pattern": "^[^/]*$",
- "error": "KCHVM0011E"
- },
- "template": {
- "description": "The URI of a template to use when building a VM",
- "type": "string",
- "pattern": "^/plugins/kimchi/templates/(.*?)/?$",
- "required": true,
- "error": "KCHVM0012E"
- },
- "storagepool": {
- "description": "Assign a specefic Storage Pool to the new VM",
- "type": "string",
- "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$",
- "error": "KCHVM0013E"
- },
- "graphics": { "$ref": "#/kimchitype/graphics" }
- }
- },
- "vm_update": {
- "type": "object",
- "properties": {
- "name": {
- "description": "New name of VM",
- "type": "string",
- "pattern": "^[^/]*$",
- "minLength": 1,
- "error": "KCHVM0011E"
- },
- "users": {
- "description": "Array of users who have permission to the VM",
- "type": "array",
- "uniqueItems": true,
- "error": "KCHVM0023E",
- "items": {
- "description": "User name",
- "type": "string",
- "error": "KCHVM0024E"
- }
- },
- "groups": {
- "description": "Array of groups who have permission to the VM",
- "type": "array",
- "uniqueItems": true,
- "error": "KCHVM0025E",
- "items": {
- "description": "Group name",
- "type": "string",
- "error": "KCHVM0026E"
- }
- },
- "graphics": {
- "description": "Graphics information from guest",
- "type": "object",
- "properties": {
- "passwd": {
- "description": "New graphics password.",
- "type": "string",
- "error": "KCHVM0031E"
- },
- "passwdValidTo": {
- "description": "Life time for the graphics password.",
- "type": "number",
- "error": "KCHVM0032E"
- }
- }
- },
- "cpus": {
- "description": "The new number of virtual CPUs for the VM",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0012E"
- },
- "memory": {
- "description": "The new amount (MB) of memory for the VM",
- "type": "integer",
- "minimum": 512,
- "error": "KCHTMPL0013E"
- }
- },
- "additionalProperties": false
- },
- "networks_create": {
- "type": "object",
- "error": "KCHNET0016E",
- "properties": {
- "name": {
- "description": "The name of the new network",
- "type": "string",
- "minLength": 1,
- "pattern": "^[^/\"]*$",
- "required": true,
- "error": "KCHNET0011E"
- },
- "connection": {
- "description": "Specifies how this network should be connected to the other networks",
- "type": "string",
- "pattern": "^isolated|nat|bridge$",
- "required": true,
- "error": "KCHNET0012E"
- },
- "subnet": {
- "description": "Network segment in slash-separated format with ip address and prefix or netmask",
- "type": "string",
- "error": "KCHNET0013E"
- },
- "interface": {
- "description": "The name of a network interface on the host",
- "type": "string",
- "error": "KCHNET0014E"
- },
- "vlan_id": {
- "description": "Network's VLAN ID",
- "type": "integer",
- "maximum": 4094,
- "minimum": 1,
- "error": "KCHNET0015E"
- }
- }
- },
- "vmifaces_create": {
- "type": "object",
- "error": "KCHVMIF0007E",
- "properties": {
- "type": {
- "description": "The type of VM network interface that libvirt supports",
- "type": "string",
- "pattern": "^network$",
- "required": true,
- "error": "KCHVMIF0004E"
- },
- "network": {
- "description": "the name of one available network",
- "minLength": 1,
- "type": "string",
- "error": "KCHVMIF0005E"
- },
- "model": {
- "description": "model of emulated network interface card",
- "type": "string",
- "pattern": "^ne2k_pci|i82551|i82557b|i82559er|rtl8139|e1000|pcnet|virtio$",
- "error": "KCHVMIF0006E"
- },
- "mac": {
- "description": "Network Interface Card MAC address",
- "type": "string",
- "pattern": "(^$)|^(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$)",
- "error": "KCHVMIF0010E"
- }
- }
- },
- "vmiface_update": {
- "type": "object",
- "error": "KCHVMIF0008E",
- "properties": {
- "mac": {
- "description": "Network Interface Card MAC address",
- "type": "string",
- "pattern": "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$",
- "error": "KCHVMIF0010E"
- }
- }
- },
- "templates_create": {
- "type": "object",
- "error": "KCHTMPL0016E",
- "properties": {
- "name": {
- "description": "The name of the template",
- "type": "string",
- "pattern": "^[^ ]+( +[^ ]+)*$",
- "minLength": 1,
- "error": "KCHTMPL0008E"
- },
- "icon": {
- "description": "The template icon path",
- "type": "string",
- "pattern": "^/plugins/kimchi/images/",
- "error": "KCHTMPL0009E"
- },
- "os_distro": {
- "description": "Distribution name of the Operating System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0010E"
- },
- "os_version": {
- "description": "Version of the Operating System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0011E"
- },
- "cpus": {
- "description": "Number of CPUs for the template",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0012E"
- },
- "memory": {
- "description": "Memory (MB) for the template",
- "type": "integer",
- "minimum": 512,
- "error": "KCHTMPL0013E"
- },
- "cdrom": {
- "description": "Path for cdrom",
- "type": "string",
- "pattern": "^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "error": "KCHTMPL0014E"
- },
- "disks": {
- "description": "List of disks",
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "index": {
- "description": "Index of the disk",
- "type": "integer",
- "minimum": 0
- },
- "size": {
- "description": "Size (GB) of the disk",
- "type": "number",
- "minimum": 1,
- "error": "KCHTMPL0022E"
- },
- "base": {
- "description": "Base image of the disk",
- "type": "string",
- "pattern": "^/.+$",
- "error": "KCHTMPL0023E"
- }
-
- }
- },
- "minItems": 1,
- "uniqueItems": true
- },
- "storagepool": {
- "description": "Location of the storage pool",
- "type": "string",
- "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$",
- "error": "KCHTMPL0015E"
- },
- "networks": {
- "description": "list of which networks will be assigned to the new VM.",
- "type": "array",
- "items": { "type": "string" },
- "error": "KCHTMPL0017E"
- },
- "folder": {
- "description": "Folder",
- "type": "array",
- "items": { "type": "string" }
- },
- "graphics": { "$ref": "#/kimchitype/graphics" },
- "cpu_info": { "$ref": "#/kimchitype/cpu_info" }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "storageservers_get_list": {
- "type": "object",
- "properties": {
- "_target_type": {
- "description": "List storage servers of given type",
- "type": "string",
- "pattern": "^netfs|iscsi$"
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "storagetargets_get_list": {
- "type": "object",
- "properties": {
- "_target_type": {
- "description": "List storage servers of given type",
- "type": "string",
- "pattern": "^netfs|iscsi$"
- },
- "_server_port": {
- "description": "the port of iscsi storage servers",
- "type": "string",
- "pattern": "^[0-9]{1,5}$"
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "vmstorages_create": {
- "type": "object",
- "error": "KCHVMSTOR0012E",
- "properties": {
- "type": {
- "description": "The storage type",
- "type": "string",
- "pattern": "^cdrom|disk$",
- "required": true,
- "error": "KCHVMSTOR0002E"
- },
- "pool": {
- "description": "Storage pool name disk image locate in",
- "type": "string",
- "minLength": 1,
- "error": "KCHVMSTOR0012E"
- },
- "vol": {
- "description": "Storage volume name of disk image",
- "type": "string",
- "minLength": 1,
- "error": "KCHVMSTOR0012E"
- },
- "path": {
- "description": "Path of iso image file or disk mount point",
- "type": "string",
- "pattern": "^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "error": "KCHVMSTOR0003E"
- }
- }
- },
- "vmstorage_update": {
- "type": "object",
- "error": "KCHVMSTOR0013E",
- "properties": {
- "path": {
- "description": "Path of iso image file or disk mount point",
- "type": "string",
- "pattern": "^(|(/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "required": true,
- "error": "KCHVMSTOR0003E"
- }
- },
- "additionalProperties": false
- },
- "template_update": {
- "type": "object",
- "properties": {
- "name": {
- "description": "The name of the template",
- "type": "string",
- "pattern": "^[^ ]+( +[^ ]+)*$",
- "minLength": 1,
- "error": "KCHTMPL0008E"
- },
- "icon": {
- "description": "The template icon path",
- "type": "string",
- "pattern": "^/plugins/kimchi/images/",
- "error": "KCHTMPL0009E"
- },
- "os_distro": {
- "description": "Distribution name of the Operating System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0010E"
- },
- "os_version": {
- "description": "Version of the Operating System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0011E"
- },
- "cpus": {
- "description": "Number of CPUs for the template",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0012E"
- },
- "memory": {
- "description": "Memory (MB) for the template",
- "type": "integer",
- "minimum": 512,
- "error": "KCHTMPL0013E"
- },
- "cdrom": {
- "description": "Path for cdrom",
- "type": "string",
- "pattern": "^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "error": "KCHTMPL0014E"
- },
- "disks": {
- "description": "List of disks",
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "index": {
- "description": "Index of the disk",
- "type": "integer",
- "minimum": 0
- },
- "size": {
- "description": "Size (GB) of the disk",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0022E"
- },
- "format": {
- "description": "Type of the image of the disk",
- "type": "string",
- "pattern": "^(bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
- "error": "KCHTMPL0027E"
- }
- }
- },
- "minItems": 1,
- "uniqueItems": true
- },
- "storagepool": {
- "description": "Location of the storage pool",
- "type": "string",
- "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$",
- "error": "KCHTMPL0015E"
- },
- "networks": {
- "description": "list of which networks will be assigned to the new VM.",
- "type": "array",
- "items": { "type": "string" },
- "error": "KCHTMPL0017E"
- },
- "folder": {
- "description": "Folder",
- "type": "array",
- "items": { "type": "string" }
- },
- "graphics": { "$ref": "#/kimchitype/graphics" },
- "cpu_info": { "$ref": "#/kimchitype/cpu_info" }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "repositories_create": {
- "type": "object",
- "properties": {
- "repo_id": {
- "description": "Repository ID used for YUM repository.",
- "type": "string",
- "error": "KCHREPOS0001E"
- },
- "baseurl": {
- "description": "URL to the directory where the repodata directory of a repository is located. Can be an http://, ftp:// or file:// URL.",
- "type": "string",
- "error": "KCHREPOS0002E"
- },
- "config": {
- "description": "Dictionary containing repository configuration",
- "type": "object",
- "error": "KCHREPOS0003E",
- "properties": {
- "dist": {
- "description": "Distribution to DEB repository",
- "type": "string",
- "error": "KCHREPOS0004E"
- },
- "comps": {
- "description": "List of components to DEB repository",
- "type": "array",
- "error": "KCHREPOS0005E",
- "uniqueItems": true,
- "items": {
- "description": "Component name",
- "type": "string",
- "error": "KCHREPOS0006E"
- }
- },
- "repo_name": {
- "description": "YUM repository name",
- "type": "string",
- "error": "KCHREPOS0023E"
- },
- "mirrorlist": {
- "description": "URL to a file containing a list of baseurls",
- "type": "string",
- "error": "KCHREPOS0007E"
- },
- "metalink": {
- "description": "URL to a metalink file for the repomd.xml",
- "type": "string",
- "error": "KCHREPOS0029E"
- }
- }
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "repository_update": {
- "type": "object",
- "properties": {
- "baseurl": {
- "description": "URL to the directory where the repodata directory of a repository is located. Can be an http://, ftp:// or file:// URL.",
- "type": "string",
- "error": "KCHREPOS0002E"
- },
- "config": {
- "description": "Dictionary containing repository configuration",
- "type": "object",
- "error": "KCHREPOS0003E",
- "properties": {
- "dist": {
- "description": "Distribution to DEB repository",
- "type": "string",
- "error": "KCHREPOS0004E"
- },
- "comps": {
- "description": "List of components to DEB repository",
- "type": "array",
- "error": "KCHREPOS0005E",
- "uniqueItems": true,
- "items": {
- "description": "Component name",
- "type": "string",
- "error": "KCHREPOS0006E"
- }
- },
- "repo_name": {
- "description": "Human-readable string describing the YUM repository.",
- "type": "string",
- "error": "KCHREPOS0008E"
- },
- "mirrorlist": {
- "description": "URL to a file containing a list of baseurls for YUM repository",
- "type": "string",
- "error": "KCHREPOS0007E"
- },
- "gpgcheck": {
- "description": "Indicates if a GPG signature check on the packages gotten from repository should be performed.",
- "type": "boolean",
- "error": "KCHREPOS0009E"
- },
- "gpgkey": {
- "description": "URL pointing to the ASCII-armored GPG key file for the repository.",
- "type": "string",
- "error": "KCHREPOS0010E"
- }
- }
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "devices_get_list": {
- "type": "object",
- "properties": {
- "_cap": {
- "description": "List specific type of device",
- "type": "string",
- "pattern": "^fc_host|net|pci|scsi|scsi_host|storage|system|usb|usb_device$",
- "error": "KCHDEVS0001E"
- },
- "_passthrough": {
- "description": "List only devices eligible to be assigned to guest",
- "type": "string",
- "pattern": "^true|false$",
- "error": "KCHDEVS0002E"
- },
- "_passthrough_affected_by": {
- "description": "List the affected devices in the same group of a certain device to be assigned to guest",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]+$",
- "error": "KCHDEVS0003E"
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "vmhostdevs_create": {
- "type": "object",
- "properties": {
- "name": {
- "description": "Then name of the device to assign to VM",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]+$",
- "required": true,
- "error": "KCHVMHDEV0004E"
- }
- },
- "error": "KCHAPI0001E"
- }
- }
-}
diff --git a/plugins/kimchi/INSTALL b/plugins/kimchi/INSTALL
deleted file mode 100644
index 63bf076..0000000
--- a/plugins/kimchi/INSTALL
+++ /dev/null
@@ -1,369 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
-Inc.
-
- Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved. This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package. Some packages provide this
-`INSTALL' file but do not implement all of the features documented
-below. The lack of an optional feature in a given package is not
-necessarily a bug. More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
- The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package, generally using the just-built uninstalled binaries.
-
- 4. Type `make install' to install the programs and any data files and
- documentation. When installing into a prefix owned by root, it is
- recommended that the package be configured and built as a regular
- user, and only the `make install' phase executed with root
- privileges.
-
- 5. Optionally, type `make installcheck' to repeat any self-tests, but
- this time using the binaries in their final installed location.
- This target does not install anything. Running this target as a
- regular user, particularly if the prior `make install' required
- root privileges, verifies that the installation completed
- correctly.
-
- 6. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 7. Often, you can also type `make uninstall' to remove the installed
- files again. In practice, not all packages have tested that
- uninstallation works correctly, even though it is required by the
- GNU Coding Standards.
-
- 8. Some packages, particularly those that use Automake, provide `make
- distcheck', which can by used by developers to test that all other
- targets like `make install' and `make uninstall' work correctly.
- This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'. This
-is known as a "VPATH" build.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
- On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
-this:
-
- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CPP="gcc -E" CXXCPP="g++ -E"
-
- This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
- The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
-having to reconfigure or recompile.
-
- The first method involves providing an override variable for each
-affected directory. For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-`${prefix}'. Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated. The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
- The second method involves providing the `DESTDIR' variable. For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names. The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters. On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
-
-Optional Features
-=================
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
- Some packages offer the ability to configure how verbose the
-execution of `make' will be. For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
-
-Particular systems
-==================
-
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
- ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
- HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved. Use GNU `make'
-instead.
-
- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
-
- ./configure CC="cc"
-
-and if that doesn't work, try
-
- ./configure CC="cc -nodtk"
-
- On Solaris, don't put `/usr/ucb' early in your `PATH'. This
-directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
-
- On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'. It is recommended to use the following options:
-
- ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS
- KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
- Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
-
-`--no-create'
-`-n'
- Run the configure checks, but stop before creating any output
- files.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
diff --git a/plugins/kimchi/Makefile.am b/plugins/kimchi/Makefile.am
deleted file mode 100644
index 49c835e..0000000
--- a/plugins/kimchi/Makefile.am
+++ /dev/null
@@ -1,161 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = contrib control distros.d docs model po tests ui xmlutils
-
-kimchi_PYTHON = $(filter-out config.py, $(wildcard *.py))
-
-nodist_kimchi_PYTHON = config.py
-
-if WITH_SPICE
-WITH_SPICE=yes
-else
-WITH_SPICE=no
-endif
-
-wokdir = $(pythondir)/wok
-kimchidir = $(pythondir)/wok/plugins/kimchi
-
-confdir = $(sysconfdir)/wok/plugins.d
-dist_conf_DATA = kimchi.conf template.conf
-
-AUTOMAKE_OPTIONS = foreign
-
-ACLOCAL_AMFLAGS = --install -I m4
-
-EXTRA_DIST = \
- config.rpath \
- API.json \
- autogen.sh \
- COPYING.ASL2 \
- COPYING.LGPL \
- CONTRIBUTE.md \
- VERSION \
- build-aux/pkg-version \
- config.py.in \
- $(NULL)
-
-
-PEP8_BLACKLIST = *config.py,*i18n.py,*tests/test_config.py
-
-I18N_FILES = ./i18n.py \
- $(NULL)
-
-check-local:
- contrib/check_i18n.py $(I18N_FILES)
- find . -path './.git' -prune -type f -o \
- -name '*.py' -o -name '*.py.in' | xargs $(PYFLAKES) | \
- while read LINE; do echo "$$LINE"; false; done
-
- $(PEP8) --version
- $(PEP8) --filename '*.py,*.py.in' --exclude="$(PEP8_BLACKLIST)" .
-
-
-# Link built mo files in the source tree to enable use of translations from
-# within the source tree
-all-local:
- while read L && test -n "$$L"; do \
- dir=mo/$$L/LC_MESSAGES ; \
- $(MKDIR_P) $$dir ; \
- ln -sf ../../../po/$$L.gmo $$dir/kimchi.mo ; \
- done < po/LINGUAS
-
-do_substitution = \
- sed -e 's,[@]prefix[@],$(prefix),g' \
- -e 's,[@]datadir[@],$(datadir),g' \
- -e 's,[@]sysconfdir[@],$(sysconfdir),g' \
- -e 's,[@]localstatedir[@],$(localstatedir),g' \
- -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \
- -e 's,[@]wokdir[@],$(wokdir),g' \
- -e 's,[@]kimchidir[@],$(kimchidir),g' \
- -e 's,[@]kimchiversion[@],$(PACKAGE_VERSION),g' \
- -e 's,[@]kimchirelease[@],$(PACKAGE_RELEASE),g' \
- -e 's,[@]withspice[@],$(WITH_SPICE),g'
-
-config.py: config.py.in Makefile
- $(do_substitution) < $(srcdir)/config.py.in > config.py
-
-
-#
-# Packaging helpers
-#
-
-install-deb: install
- cp -R $(top_srcdir)/contrib/DEBIAN $(DESTDIR)/
- mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
- mkdir -p $(DESTDIR)/var/lib/kimchi/debugreports
- mkdir -p $(DESTDIR)/var/lib/kimchi/screenshots
- mkdir -p $(DESTDIR)/var/lib/kimchi/isos
-
-
-deb: contrib/make-deb.sh
- $(top_srcdir)/contrib/make-deb.sh
-
-kimchi.spec: contrib/kimchi.spec.fedora contrib/kimchi.spec.suse
- @if test -e /etc/redhat-release; then \
- ln -sf contrib/kimchi.spec.fedora $@ ; \
- elif test -e /etc/SuSE-release; then \
- ln -sf contrib/kimchi.spec.suse $@ ; \
- else \
- echo "Unable to select a spec file for RPM build" ; \
- /bin/false ; \
- fi
-
-rpm: dist kimchi.spec
- $(MKDIR_P) rpm/BUILD rpm/RPMS rpm/SOURCES rpm/SPECS rpm/SRPMS
- cp $(top_srcdir)/kimchi.spec rpm/SPECS/kimchi.spec
- cp $(DIST_ARCHIVES) rpm/SOURCES
- rpmbuild -ba --define "_topdir `pwd`/rpm" rpm/SPECS/kimchi.spec
-
-fedora-rpm: contrib/kimchi.spec.fedora
- ln -sf contrib/kimchi.spec.fedora kimchi.spec
- $(MAKE) rpm
-
-suse-rpm: contrib/kimchi.spec.suse
- ln -sf contrib/kimchi.spec.suse kimchi.spec
- $(MAKE) rpm
-
-ChangeLog:
- @if test -d .git; then \
- $(top_srcdir)/build-aux/genChangelog --release > $@; \
- fi
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(kimchidir)
- $(INSTALL_DATA) API.json $(DESTDIR)$(kimchidir)/API.json
- mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
- mkdir -p $(DESTDIR)/var/lib/kimchi/{debugreports,isos,screenshots}
-
-uninstall-local:
- $(RM) $(DESTDIR)$(kimchidir)/API.json
- $(RM) -rf $(DESTDIR)/var/lib/kimchi
-
-VERSION:
- @if test -d .git; then \
- git describe --abbrev=0 > $@; \
- fi
-
-.PHONY: deb install-deb rpm fedora-rpm suse-rpm ChangeLog VERSION
-
-
-clean-local:
- rm -rf mo rpm
-
-BUILT_SOURCES = config.py
-CLEANFILES = config.py kimchi.spec `find "$(top_srcdir)" -type f -name "*.pyc" -print`
diff --git a/plugins/kimchi/README.md b/plugins/kimchi/README.md
deleted file mode 120000
index 0e01b43..0000000
--- a/plugins/kimchi/README.md
+++ /dev/null
@@ -1 +0,0 @@
-docs/README.md
\ No newline at end of file
diff --git a/plugins/kimchi/VERSION b/plugins/kimchi/VERSION
deleted file mode 100644
index bc80560..0000000
--- a/plugins/kimchi/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.5.0
diff --git a/plugins/kimchi/__init__.py b/plugins/kimchi/__init__.py
deleted file mode 100644
index 9330044..0000000
--- a/plugins/kimchi/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from root import KimchiRoot
-__all__ = [KimchiRoot]
diff --git a/plugins/kimchi/autogen.sh b/plugins/kimchi/autogen.sh
deleted file mode 100755
index 0f22dba..0000000
--- a/plugins/kimchi/autogen.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-aclocal
-automake --add-missing
-autoreconf
-
-if [ ! -f "configure" ]; then
- echo "Failed to generate configure script. Check to make sure autoconf, "
- echo "automake, and other build dependencies are properly installed."
- exit 1
-fi
-
-if [ "x$1" == "x--system" ]; then
- ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
-else
- if [ $# -gt 0 ]; then
- ./configure $@
- else
- ./configure --prefix=/usr/local
- fi
-fi
diff --git a/plugins/kimchi/build-aux/config.rpath b/plugins/kimchi/build-aux/config.rpath
deleted file mode 100644
index 17298f2..0000000
--- a/plugins/kimchi/build-aux/config.rpath
+++ /dev/null
@@ -1,672 +0,0 @@
-#! /bin/sh
-# Output a system dependent set of variables, describing how to set the
-# run time search path of shared libraries in an executable.
-#
-# Copyright 1996-2010 Free Software Foundation, Inc.
-# Taken from GNU libtool, 2001
-# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# The first argument passed to this file is the canonical host specification,
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
-# should be set by the caller.
-#
-# The set of defined variables is at the end of this script.
-
-# Known limitations:
-# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
-# than 256 bytes, otherwise the compiler driver will dump core. The only
-# known workaround is to choose shorter directory names for the build
-# directory and/or the installation directory.
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-shrext=.so
-
-host="$1"
-host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-# Code taken from libtool.m4's _LT_CC_BASENAME.
-
-for cc_temp in $CC""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
-
-# Code taken from libtool.m4's _LT_COMPILER_PIC.
-
-wl=
-if test "$GCC" = yes; then
- wl='-Wl,'
-else
- case "$host_os" in
- aix*)
- wl='-Wl,'
- ;;
- darwin*)
- case $cc_basename in
- xlc*)
- wl='-Wl,'
- ;;
- esac
- ;;
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- ;;
- hpux9* | hpux10* | hpux11*)
- wl='-Wl,'
- ;;
- irix5* | irix6* | nonstopux*)
- wl='-Wl,'
- ;;
- newsos6)
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- ecc*)
- wl='-Wl,'
- ;;
- icc* | ifort*)
- wl='-Wl,'
- ;;
- lf95*)
- wl='-Wl,'
- ;;
- pgcc | pgf77 | pgf90)
- wl='-Wl,'
- ;;
- ccc*)
- wl='-Wl,'
- ;;
- como)
- wl='-lopt='
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- wl='-Wl,'
- ;;
- esac
- ;;
- esac
- ;;
- osf3* | osf4* | osf5*)
- wl='-Wl,'
- ;;
- rdos*)
- ;;
- solaris*)
- wl='-Wl,'
- ;;
- sunos4*)
- wl='-Qoption ld '
- ;;
- sysv4 | sysv4.2uw2* | sysv4.3*)
- wl='-Wl,'
- ;;
- sysv4*MP*)
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- wl='-Wl,'
- ;;
- unicos*)
- wl='-Wl,'
- ;;
- uts4*)
- ;;
- esac
-fi
-
-# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
-
-hardcode_libdir_flag_spec=
-hardcode_libdir_separator=
-hardcode_direct=no
-hardcode_minus_L=no
-
-case "$host_os" in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
-esac
-
-ld_shlibs=yes
-if test "$with_gnu_ld" = yes; then
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- # Unlike libtool, we use -rpath here, not --rpath, since the documented
- # option of GNU ld is called -rpath, not --rpath.
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- case "$host_os" in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we cannot use
- # them.
- ld_shlibs=no
- ;;
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- interix[3-9]*)
- hardcode_direct=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- netbsd*)
- ;;
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
- sunos4*)
- hardcode_direct=yes
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- esac
- if test "$ld_shlibs" = no; then
- hardcode_libdir_flag_spec=
- fi
-else
- case "$host_os" in
- aix3*)
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- else
- aix_use_runtimelinking=no
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
- fi
- hardcode_direct=yes
- hardcode_libdir_separator=':'
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- fi
- # Begin _LT_AC_SYS_LIBPATH_AIX.
- echo 'int main () { return 0; }' > conftest.c
- ${CC} ${LDFLAGS} conftest.c -o conftest
- aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- fi
- if test -z "$aix_libpath"; then
- aix_libpath="/usr/lib:/lib"
- fi
- rm -f conftest.c conftest
- # End _LT_AC_SYS_LIBPATH_AIX.
- if test "$aix_use_runtimelinking" = yes; then
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- else
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- fi
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs=no
- ;;
- bsdi[45]*)
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- libext=lib
- ;;
- darwin* | rhapsody*)
- hardcode_direct=no
- if test "$GCC" = yes ; then
- :
- else
- case $cc_basename in
- xlc*)
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
- fi
- ;;
- dgux*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- freebsd1*)
- ld_shlibs=no
- ;;
- freebsd2.2*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- freebsd2*)
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- freebsd* | dragonfly*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- hpux9*)
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- hpux10*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
- hpux11*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct=no
- ;;
- *)
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
- irix5* | irix6* | nonstopux*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- netbsd*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- newsos6)
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- else
- case "$host_os" in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- osf3*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- osf4* | osf5*)
- if test "$GCC" = yes; then
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- # Both cc and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- hardcode_libdir_separator=:
- ;;
- solaris*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- sunos4*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- sysv4)
- case $host_vendor in
- sni)
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- hardcode_direct=no
- ;;
- motorola)
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- ;;
- sysv4.3*)
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- ld_shlibs=yes
- fi
- ;;
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- ;;
- sysv5* | sco3.2v5* | sco5v6*)
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator=':'
- ;;
- uts4*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
-fi
-
-# Check dynamic linker characteristics
-# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
-# Unlike libtool.m4, here we don't care about _all_ names of the library, but
-# only about the one the linker finds when passed -lNAME. This is the last
-# element of library_names_spec in libtool.m4, or possibly two of them if the
-# linker has special search rules.
-library_names_spec= # the last element of library_names_spec in libtool.m4
-libname_spec='lib$name'
-case "$host_os" in
- aix3*)
- library_names_spec='$libname.a'
- ;;
- aix[4-9]*)
- library_names_spec='$libname$shrext'
- ;;
- amigaos*)
- library_names_spec='$libname.a'
- ;;
- beos*)
- library_names_spec='$libname$shrext'
- ;;
- bsdi[45]*)
- library_names_spec='$libname$shrext'
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- shrext=.dll
- library_names_spec='$libname.dll.a $libname.lib'
- ;;
- darwin* | rhapsody*)
- shrext=.dylib
- library_names_spec='$libname$shrext'
- ;;
- dgux*)
- library_names_spec='$libname$shrext'
- ;;
- freebsd1*)
- ;;
- freebsd* | dragonfly*)
- case "$host_os" in
- freebsd[123]*)
- library_names_spec='$libname$shrext$versuffix' ;;
- *)
- library_names_spec='$libname$shrext' ;;
- esac
- ;;
- gnu*)
- library_names_spec='$libname$shrext'
- ;;
- hpux9* | hpux10* | hpux11*)
- case $host_cpu in
- ia64*)
- shrext=.so
- ;;
- hppa*64*)
- shrext=.sl
- ;;
- *)
- shrext=.sl
- ;;
- esac
- library_names_spec='$libname$shrext'
- ;;
- interix[3-9]*)
- library_names_spec='$libname$shrext'
- ;;
- irix5* | irix6* | nonstopux*)
- library_names_spec='$libname$shrext'
- case "$host_os" in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
- *) libsuff= shlibsuff= ;;
- esac
- ;;
- esac
- ;;
- linux*oldld* | linux*aout* | linux*coff*)
- ;;
- linux* | k*bsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- knetbsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- netbsd*)
- library_names_spec='$libname$shrext'
- ;;
- newsos6)
- library_names_spec='$libname$shrext'
- ;;
- nto-qnx*)
- library_names_spec='$libname$shrext'
- ;;
- openbsd*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- os2*)
- libname_spec='$name'
- shrext=.dll
- library_names_spec='$libname.a'
- ;;
- osf3* | osf4* | osf5*)
- library_names_spec='$libname$shrext'
- ;;
- rdos*)
- ;;
- solaris*)
- library_names_spec='$libname$shrext'
- ;;
- sunos4*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- sysv4 | sysv4.3*)
- library_names_spec='$libname$shrext'
- ;;
- sysv4*MP*)
- library_names_spec='$libname$shrext'
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- library_names_spec='$libname$shrext'
- ;;
- uts4*)
- library_names_spec='$libname$shrext'
- ;;
-esac
-
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
-shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
-escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-
-LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
-
-# How to pass a linker flag through the compiler.
-wl="$escaped_wl"
-
-# Static library suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally "so").
-shlibext="$shlibext"
-
-# Format of library name prefix.
-libname_spec="$escaped_libname_spec"
-
-# Library names that the linker finds when passed -lNAME.
-library_names_spec="$escaped_library_names_spec"
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator="$hardcode_libdir_separator"
-
-# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct="$hardcode_direct"
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L="$hardcode_minus_L"
-
-EOF
diff --git a/plugins/kimchi/build-aux/genChangelog b/plugins/kimchi/build-aux/genChangelog
deleted file mode 100755
index 803f24e..0000000
--- a/plugins/kimchi/build-aux/genChangelog
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# This script is based on code from the Kandan project:
-# https://github.com/kandanapp/kandan/blob/master/gen-changelog.sh
-
-echo "CHANGELOG"
-echo "========="
-echo
-git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags | tac |grep -v '^$' | while read TAG ; do
- if [ $NEXT ]; then
- echo "#### [$NEXT] ####"
- elif [ "$1" != "--release" ]; then
- echo "#### [Current] ####"
- else
- NEXT=$TAG
- continue
- fi
- GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)" $TAG..$NEXT
- NEXT=$TAG
- echo; echo
-done
-FIRST=$(git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags | head -1)
-
-echo "#### [$FIRST] ####"
-GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)" $FIRST
diff --git a/plugins/kimchi/build-aux/pkg-version b/plugins/kimchi/build-aux/pkg-version
deleted file mode 100755
index 749cf6c..0000000
--- a/plugins/kimchi/build-aux/pkg-version
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/sh
-#
-# Copyright 2008-2012 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# tags and output versions:
-# - 4.9.0 => 4.9.0 (upstream clean)
-# - 4.9.0-1 => 4.9.0 (downstream clean)
-# - 4.9.0-2-g34e62f => 4.9.0 (upstream dirty)
-# - 4.9.0-1-2-g34e62f => 4.9.0 (downstream dirty)
-AWK_VERSION='
- BEGIN { FS="-" }
- /^[0-9]/ {
- print $1
- }'
-
-# tags and output releases:
-# - 4.9.0 => 0 (upstream clean)
-# - 4.9.0-1 => 1 (downstream clean)
-# - 4.9.0-2-g34e62f1 => 2.git34e62f1 (upstream dirty)
-# - 4.9.0-1-2-g34e62f1 => 1.2.git34e62f1 (downstream dirty)
-AWK_RELEASE='
- BEGIN { FS="-"; OFS="." }
- /^[0-9]/ {
- if (NF == 1) print 0
- else if (NF == 2) print $2
- else if (NF == 3) print $2, "git" substr($3, 2)
- else if (NF == 4) print $2, $3, "git" substr($4, 2)
- }'
-
-if [ ! -d .git ]; then
- PKG_VERSION=`cat VERSION`
-else
- PKG_VERSION=`git describe --tags --match "[0-9]*" || cat VERSION`
-fi
-
-if test "x$1" = "x--full"; then
- echo $PKG_VERSION | tr -d '[:space:]'
-elif test "x$1" = "x--version"; then
- echo $PKG_VERSION | awk "$AWK_VERSION" | tr -cd '[:alnum:].'
-elif test "x$1" = "x--release"; then
- echo $PKG_VERSION | awk "$AWK_RELEASE" | tr -cd '[:alnum:].'
-else
- echo "usage: $0 [--full|--version|--release]"
- exit 1
-fi
diff --git a/plugins/kimchi/config.py.in b/plugins/kimchi/config.py.in
deleted file mode 100644
index 6ae0ccd..0000000
--- a/plugins/kimchi/config.py.in
+++ /dev/null
@@ -1,144 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import libvirt
-import os
-import platform
-import threading
-
-from wok.config import CACHEEXPIRES, PluginConfig, PluginPaths
-from wok.xmlutils.utils import xpath_get_text
-
-kimchiLock = threading.Lock()
-
-__with_spice__ = "@withspice@"
-
-# Storage pool constant for read-only pool types
-READONLY_POOL_TYPE = ['iscsi', 'scsi', 'mpath']
-
-
-def get_distros_store():
- return os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d')
-
-
-def get_debugreports_path():
- return os.path.join(PluginPaths('kimchi').state_dir, 'debugreports')
-
-
-def get_screenshot_path():
- return os.path.join(PluginPaths('kimchi').state_dir, 'screenshots')
-
-
-def find_qemu_binary(find_emulator=False):
- try:
- connect = libvirt.open(None)
- except Exception, e:
- raise Exception("Unable to get qemu binary location: %s" % e)
- try:
- xml = connect.getCapabilities()
-
- # On Little Endian system, the qemu binary is
- # qemu-system-ppc64, not qemu-system-ppc64le as expected
- arch = platform.machine()
- if arch == "ppc64le":
- arch = "ppc64"
-
- if find_emulator:
- expr = "/capabilities/guest/arch[@name='%s']\
- /emulator" % arch
- else:
- expr = "/capabilities/guest/arch[@name='%s']\
- /domain[@type='kvm']/emulator" % arch
- res = xpath_get_text(xml, expr)
- location = res[0]
- except Exception, e:
- raise Exception("Unable to get qemu binary location: %s" % e)
- finally:
- connect.close()
- return location
-
-
-class KimchiPaths(PluginPaths):
-
- def __init__(self):
- super(KimchiPaths, self).__init__('kimchi')
- self.spice_file = os.path.join(self.ui_dir,
- 'spice-html5/pages/spice_auto.html')
-
- if __with_spice__ == 'yes':
- self.spice_dir = self.add_prefix('ui/spice-html5')
- elif os.path.exists('@datadir@/spice-html5'):
- self.spice_dir = '@datadir@/spice-html5'
- else:
- self.spice_dir = '/usr/share/spice-html5'
-
- if os.path.exists('@datadir@/novnc'):
- self.novnc_dir = '@datadir@/novnc'
- else:
- self.novnc_dir = '/usr/share/novnc'
-
- if self.installed:
- self.spice_css_file = os.path.join(self.spice_dir, 'spice.css')
- else:
- self.spice_css_file = os.path.join(self.spice_dir, 'css/spice.css')
-
-
-kimchiPaths = KimchiPaths()
-
-
-class KimchiConfig(PluginConfig):
- def __init__(self):
- super(KimchiConfig, self).__init__('kimchi')
-
- static_config = {
- '/novnc': {'type': 'dir',
- 'path': kimchiPaths.novnc_dir},
- '/spice-html5': {'type': 'dir',
- 'path': kimchiPaths.spice_dir},
- '/spice_auto.html': {'type': 'file',
- 'path': kimchiPaths.spice_file},
- '/spice-html5/spice.css': {'type': 'file',
- 'path': kimchiPaths.spice_css_file}}
-
- custom_config = {}
- for uri, data in static_config.iteritems():
- custom_config[uri] = {'tools.nocache.on': True,
- 'tools.wokauth.on': True}
- path = data['path']
- if data['type'] == 'dir':
- custom_config[uri].update({'tools.staticdir.on': True,
- 'tools.staticdir.dir': path})
- elif data['type'] == 'file':
- custom_config[uri].update({'tools.staticfile.on': True,
- 'tools.staticfile.filename': path})
-
- for dirname in ('css', 'js', 'images'):
- custom_config['/' + dirname] = {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': os.path.join(kimchiPaths.ui_dir,
- dirname),
- 'tools.wokauth.on': False,
- 'tools.nocache.on': False}
- if dirname != 'images':
- custom_config['/' + dirname].update({
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES})
-
- self.update(custom_config)
diff --git a/plugins/kimchi/config.rpath b/plugins/kimchi/config.rpath
deleted file mode 100644
index 17298f2..0000000
--- a/plugins/kimchi/config.rpath
+++ /dev/null
@@ -1,672 +0,0 @@
-#! /bin/sh
-# Output a system dependent set of variables, describing how to set the
-# run time search path of shared libraries in an executable.
-#
-# Copyright 1996-2010 Free Software Foundation, Inc.
-# Taken from GNU libtool, 2001
-# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# The first argument passed to this file is the canonical host specification,
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
-# should be set by the caller.
-#
-# The set of defined variables is at the end of this script.
-
-# Known limitations:
-# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
-# than 256 bytes, otherwise the compiler driver will dump core. The only
-# known workaround is to choose shorter directory names for the build
-# directory and/or the installation directory.
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-shrext=.so
-
-host="$1"
-host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-# Code taken from libtool.m4's _LT_CC_BASENAME.
-
-for cc_temp in $CC""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
-
-# Code taken from libtool.m4's _LT_COMPILER_PIC.
-
-wl=
-if test "$GCC" = yes; then
- wl='-Wl,'
-else
- case "$host_os" in
- aix*)
- wl='-Wl,'
- ;;
- darwin*)
- case $cc_basename in
- xlc*)
- wl='-Wl,'
- ;;
- esac
- ;;
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- ;;
- hpux9* | hpux10* | hpux11*)
- wl='-Wl,'
- ;;
- irix5* | irix6* | nonstopux*)
- wl='-Wl,'
- ;;
- newsos6)
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- ecc*)
- wl='-Wl,'
- ;;
- icc* | ifort*)
- wl='-Wl,'
- ;;
- lf95*)
- wl='-Wl,'
- ;;
- pgcc | pgf77 | pgf90)
- wl='-Wl,'
- ;;
- ccc*)
- wl='-Wl,'
- ;;
- como)
- wl='-lopt='
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- wl='-Wl,'
- ;;
- esac
- ;;
- esac
- ;;
- osf3* | osf4* | osf5*)
- wl='-Wl,'
- ;;
- rdos*)
- ;;
- solaris*)
- wl='-Wl,'
- ;;
- sunos4*)
- wl='-Qoption ld '
- ;;
- sysv4 | sysv4.2uw2* | sysv4.3*)
- wl='-Wl,'
- ;;
- sysv4*MP*)
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- wl='-Wl,'
- ;;
- unicos*)
- wl='-Wl,'
- ;;
- uts4*)
- ;;
- esac
-fi
-
-# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
-
-hardcode_libdir_flag_spec=
-hardcode_libdir_separator=
-hardcode_direct=no
-hardcode_minus_L=no
-
-case "$host_os" in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
-esac
-
-ld_shlibs=yes
-if test "$with_gnu_ld" = yes; then
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- # Unlike libtool, we use -rpath here, not --rpath, since the documented
- # option of GNU ld is called -rpath, not --rpath.
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- case "$host_os" in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we cannot use
- # them.
- ld_shlibs=no
- ;;
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- interix[3-9]*)
- hardcode_direct=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- netbsd*)
- ;;
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
- sunos4*)
- hardcode_direct=yes
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- esac
- if test "$ld_shlibs" = no; then
- hardcode_libdir_flag_spec=
- fi
-else
- case "$host_os" in
- aix3*)
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- else
- aix_use_runtimelinking=no
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
- fi
- hardcode_direct=yes
- hardcode_libdir_separator=':'
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- fi
- # Begin _LT_AC_SYS_LIBPATH_AIX.
- echo 'int main () { return 0; }' > conftest.c
- ${CC} ${LDFLAGS} conftest.c -o conftest
- aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- fi
- if test -z "$aix_libpath"; then
- aix_libpath="/usr/lib:/lib"
- fi
- rm -f conftest.c conftest
- # End _LT_AC_SYS_LIBPATH_AIX.
- if test "$aix_use_runtimelinking" = yes; then
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- else
- hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- fi
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs=no
- ;;
- bsdi[45]*)
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- libext=lib
- ;;
- darwin* | rhapsody*)
- hardcode_direct=no
- if test "$GCC" = yes ; then
- :
- else
- case $cc_basename in
- xlc*)
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
- fi
- ;;
- dgux*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- freebsd1*)
- ld_shlibs=no
- ;;
- freebsd2.2*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- freebsd2*)
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- freebsd* | dragonfly*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- hpux9*)
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- hpux10*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
- hpux11*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct=no
- ;;
- *)
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
- irix5* | irix6* | nonstopux*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- netbsd*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- newsos6)
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- else
- case "$host_os" in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- osf3*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- osf4* | osf5*)
- if test "$GCC" = yes; then
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- # Both cc and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- hardcode_libdir_separator=:
- ;;
- solaris*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- sunos4*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- sysv4)
- case $host_vendor in
- sni)
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- hardcode_direct=no
- ;;
- motorola)
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- ;;
- sysv4.3*)
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- ld_shlibs=yes
- fi
- ;;
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
- ;;
- sysv5* | sco3.2v5* | sco5v6*)
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
- hardcode_libdir_separator=':'
- ;;
- uts4*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
-fi
-
-# Check dynamic linker characteristics
-# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
-# Unlike libtool.m4, here we don't care about _all_ names of the library, but
-# only about the one the linker finds when passed -lNAME. This is the last
-# element of library_names_spec in libtool.m4, or possibly two of them if the
-# linker has special search rules.
-library_names_spec= # the last element of library_names_spec in libtool.m4
-libname_spec='lib$name'
-case "$host_os" in
- aix3*)
- library_names_spec='$libname.a'
- ;;
- aix[4-9]*)
- library_names_spec='$libname$shrext'
- ;;
- amigaos*)
- library_names_spec='$libname.a'
- ;;
- beos*)
- library_names_spec='$libname$shrext'
- ;;
- bsdi[45]*)
- library_names_spec='$libname$shrext'
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- shrext=.dll
- library_names_spec='$libname.dll.a $libname.lib'
- ;;
- darwin* | rhapsody*)
- shrext=.dylib
- library_names_spec='$libname$shrext'
- ;;
- dgux*)
- library_names_spec='$libname$shrext'
- ;;
- freebsd1*)
- ;;
- freebsd* | dragonfly*)
- case "$host_os" in
- freebsd[123]*)
- library_names_spec='$libname$shrext$versuffix' ;;
- *)
- library_names_spec='$libname$shrext' ;;
- esac
- ;;
- gnu*)
- library_names_spec='$libname$shrext'
- ;;
- hpux9* | hpux10* | hpux11*)
- case $host_cpu in
- ia64*)
- shrext=.so
- ;;
- hppa*64*)
- shrext=.sl
- ;;
- *)
- shrext=.sl
- ;;
- esac
- library_names_spec='$libname$shrext'
- ;;
- interix[3-9]*)
- library_names_spec='$libname$shrext'
- ;;
- irix5* | irix6* | nonstopux*)
- library_names_spec='$libname$shrext'
- case "$host_os" in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
- *) libsuff= shlibsuff= ;;
- esac
- ;;
- esac
- ;;
- linux*oldld* | linux*aout* | linux*coff*)
- ;;
- linux* | k*bsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- knetbsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- netbsd*)
- library_names_spec='$libname$shrext'
- ;;
- newsos6)
- library_names_spec='$libname$shrext'
- ;;
- nto-qnx*)
- library_names_spec='$libname$shrext'
- ;;
- openbsd*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- os2*)
- libname_spec='$name'
- shrext=.dll
- library_names_spec='$libname.a'
- ;;
- osf3* | osf4* | osf5*)
- library_names_spec='$libname$shrext'
- ;;
- rdos*)
- ;;
- solaris*)
- library_names_spec='$libname$shrext'
- ;;
- sunos4*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- sysv4 | sysv4.3*)
- library_names_spec='$libname$shrext'
- ;;
- sysv4*MP*)
- library_names_spec='$libname$shrext'
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- library_names_spec='$libname$shrext'
- ;;
- uts4*)
- library_names_spec='$libname$shrext'
- ;;
-esac
-
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
-shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
-escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
-
-LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
-
-# How to pass a linker flag through the compiler.
-wl="$escaped_wl"
-
-# Static library suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally "so").
-shlibext="$shlibext"
-
-# Format of library name prefix.
-libname_spec="$escaped_libname_spec"
-
-# Library names that the linker finds when passed -lNAME.
-library_names_spec="$escaped_library_names_spec"
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator="$hardcode_libdir_separator"
-
-# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct="$hardcode_direct"
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L="$hardcode_minus_L"
-
-EOF
diff --git a/plugins/kimchi/configure.ac b/plugins/kimchi/configure.ac
deleted file mode 100644
index adab45b..0000000
--- a/plugins/kimchi/configure.ac
+++ /dev/null
@@ -1,119 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-AC_INIT([kimchi], [m4_esyscmd([./build-aux/pkg-version --version])])
-
-AC_SUBST([PACKAGE_VERSION],
- [m4_esyscmd([./build-aux/pkg-version --version])])
-
-AC_SUBST([PACKAGE_RELEASE],
- [m4_esyscmd([./build-aux/pkg-version --release])])
-
-# Testing for version and release
-AS_IF([test "x$PACKAGE_VERSION" = x],
- AC_MSG_ERROR([package version not defined]))
-AS_IF([test "x$PACKAGE_RELEASE" = x],
- AC_MSG_ERROR([package release not defined]))
-
-AC_CONFIG_AUX_DIR([build-aux])
-AM_INIT_AUTOMAKE([-Wno-portability])
-AM_PATH_PYTHON([2.6])
-AC_PATH_PROG([PEP8], [pep8], [/usr/bin/pep8])
-AC_PYTHON_MODULE([unittest])
-AC_SUBST([HAVE_PYMOD_UNITTEST])
-AC_SUBST([PYTHON_VERSION])
-AM_GNU_GETTEXT([external])
-AM_GNU_GETTEXT_VERSION([0.10])
-AC_PATH_PROG([CHEETAH], [cheetah], [/usr/bin/cheetah])
-
-# Checking for pyflakes
-AC_PATH_PROG([PYFLAKES], [pyflakes])
-if test "x$PYFLAKES" = "x"; then
- AC_MSG_WARN([pyflakes not found])
-fi
-
-AC_ARG_ENABLE(
- [sample],
- [AS_HELP_STRING(
- [--enable-sample],
- [enable sample plugin @<:@default=no@:>@]
- )],
- ,
- [enable_sample="no"]
-)
-
-if test "${enable_sample}" = "yes"; then
-AC_SUBST([ENABLE_SAMPLE], [True])
-else
-AC_SUBST([ENABLE_SAMPLE], [False])
-fi
-
-AC_ARG_WITH(
- [spice-html5],
- [AS_HELP_STRING([--with-spice-html5],
- [Build Kimchi with spice-html5 @<:@default=no@:>@])],
- ,
- [with_spice_html5="no"]
-)
-AM_CONDITIONAL([WITH_SPICE], [test "x$with_spice_html5" = xyes])
-
-AC_CONFIG_FILES([
- po/Makefile.in
- po/gen-pot
- Makefile
- docs/Makefile
- distros.d/Makefile
- control/Makefile
- control/vm/Makefile
- model/Makefile
- ui/Makefile
- ui/config/Makefile
- ui/css/Makefile
- ui/images/Makefile
- ui/images/theme-default/Makefile
- ui/js/Makefile
- ui/spice-html5/Makefile
- ui/spice-html5/css/Makefile
- ui/spice-html5/pages/Makefile
- ui/spice-html5/thirdparty/Makefile
- ui/pages/Makefile
- ui/pages/help/Makefile
- ui/pages/help/en_US/Makefile
- ui/pages/help/de_DE/Makefile
- ui/pages/help/es_ES/Makefile
- ui/pages/help/fr_FR/Makefile
- ui/pages/help/it_IT/Makefile
- ui/pages/help/ja_JP/Makefile
- ui/pages/help/ko_KR/Makefile
- ui/pages/help/pt_BR/Makefile
- ui/pages/help/ru_RU/Makefile
- ui/pages/help/zh_CN/Makefile
- ui/pages/help/zh_TW/Makefile
- contrib/Makefile
- contrib/DEBIAN/Makefile
- contrib/DEBIAN/control
- contrib/kimchi.spec.fedora
- contrib/kimchi.spec.suse
- tests/Makefile
- xmlutils/Makefile
-],[
- chmod +x po/gen-pot
-])
-
-AC_OUTPUT
diff --git a/plugins/kimchi/contrib/DEBIAN/Makefile.am b/plugins/kimchi/contrib/DEBIAN/Makefile.am
deleted file mode 100644
index ca89552..0000000
--- a/plugins/kimchi/contrib/DEBIAN/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-CLEANFILES = control
diff --git a/plugins/kimchi/contrib/DEBIAN/control.in b/plugins/kimchi/contrib/DEBIAN/control.in
deleted file mode 100644
index dc153d8..0000000
--- a/plugins/kimchi/contrib/DEBIAN/control.in
+++ /dev/null
@@ -1,30 +0,0 @@
-Package: @PACKAGE_NAME@
-Version: @PACKAGE_VERSION@
-Section: base
-Priority: optional
-Architecture: all
-Depends: wok,
- python-imaging,
- python-configobj,
- websockify,
- novnc,
- python-jsonschema (>= 1.3.0),
- python-libvirt,
- gettext,
- libvirt-bin,
- nfs-common,
- qemu-kvm,
- python-parted,
- python-psutil (>= 0.6.0),
- python-ethtool,
- sosreport,
- python-ipaddr,
- python-lxml,
- open-iscsi,
- python-guestfs,
- libguestfs-tools,
- spice-html5
-Build-Depends: libxslt,
- python-lxml
-Maintainer: Aline Manera <alinefm at br.ibm.com>
-Description: Kimchi web application
diff --git a/plugins/kimchi/contrib/Makefile.am b/plugins/kimchi/contrib/Makefile.am
deleted file mode 100644
index 5001191..0000000
--- a/plugins/kimchi/contrib/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = DEBIAN
-
-EXTRA_DIST = \
- check_i18n.py \
- kimchi.spec.fedora.in \
- make-deb.sh.in \
- $(NULL)
-
-make-deb.sh: make-deb.sh.in $(top_builddir)/config.status
- $(AM_V_GEN)sed \
- -e 's|[@]PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
- -e 's|[@]PACKAGE_RELEASE[@]|$(PACKAGE_RELEASE)|g' \
- < $< > $@-t && \
- chmod a+x $@-t && \
- mv $@-t $@
-BUILT_SOURCES = make-deb.sh
-
-CLEANFILES = kimchi.spec.fedora kimchi.spec.suse kimchi.spec make-deb.sh
diff --git a/plugins/kimchi/contrib/check_i18n.py b/plugins/kimchi/contrib/check_i18n.py
deleted file mode 100755
index 6a2603c..0000000
--- a/plugins/kimchi/contrib/check_i18n.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python2
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import imp
-import os
-import re
-import sys
-
-
-# Match all conversion specifier with mapping key
-PATTERN = re.compile(r'''%\([^)]+\) # Mapping key
- [#0\-+]? # Conversion flags (optional)
- (\d+|\*)? # Minimum field width (optional)
- (\.(\d+|\*))? # Precision (optional)
- [lLh]? # Length modifier (optional)
- [cdeEfFgGioursxX%] # Conversion type''',
- re.VERBOSE)
-BAD_PATTERN = re.compile(r"%\([^)]*?\)")
-
-
-def load_i18n_module(i18nfile):
- path = os.path.dirname(i18nfile)
- mname = i18nfile.replace("/", "_").rstrip(".py")
- mobj = imp.find_module("i18n", [path])
- return imp.load_module(mname, *mobj)
-
-
-def check_string_formatting(messages):
- for k, v in messages.iteritems():
- if BAD_PATTERN.findall(PATTERN.sub(" ", v)):
- print "bad i18n string formatting:"
- print " %s: %s" % (k, v)
- exit(1)
-
-
-def check_obsolete_messages(path, messages):
- def find_message_key(path, k):
- for root, dirs, files in os.walk(path):
- for f in files:
- fname = os.path.join(root, f)
- if (not fname.endswith("i18n.py") and fname.endswith(".py") or
- fname.endswith(".json")):
- with open(fname) as f:
- string = "".join(f.readlines())
- if k in string:
- return True
- return False
-
- for k in messages.iterkeys():
- if not find_message_key(path, k):
- print " %s is obsolete, it is no longer in use" % k
- exit(1)
-
-
-def main():
- print "Checking for invalid i18n string..."
- for f in sys.argv[1:]:
- messages = load_i18n_module(f).messages
- check_string_formatting(messages)
- check_obsolete_messages(os.path.dirname(f), messages)
- print "Checking for invalid i18n string successfully"
-
-
-if __name__ == '__main__':
- main()
diff --git a/plugins/kimchi/contrib/kimchi.spec.fedora.in b/plugins/kimchi/contrib/kimchi.spec.fedora.in
deleted file mode 100644
index 0db3d7e..0000000
--- a/plugins/kimchi/contrib/kimchi.spec.fedora.in
+++ /dev/null
@@ -1,119 +0,0 @@
-Name: kimchi
-Version: @PACKAGE_VERSION@
-Release: @PACKAGE_RELEASE@%{?dist}
-Summary: Kimchi server application
-BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
-BuildArch: noarch
-Group: System Environment/Base
-License: LGPL/ASL2
-Source0: %{name}-%{version}.tar.gz
-Requires: wok
-Requires: qemu-kvm
-Requires: gettext
-Requires: libvirt
-Requires: libvirt-python
-Requires: libvirt-daemon-config-network
-Requires: python-websockify
-Requires: python-configobj
-Requires: novnc
-Requires: python-imaging
-Requires: pyparted
-Requires: python-psutil >= 0.6.0
-Requires: python-jsonschema >= 1.3.0
-Requires: python-ethtool
-Requires: sos
-Requires: python-ipaddr
-Requires: python-lxml
-Requires: nfs-utils
-Requires: iscsi-initiator-utils
-Requires: python-libguestfs
-Requires: libguestfs-tools
-BuildRequires: libxslt
-BuildRequires: python-lxml
-
-%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
-Requires: spice-html5
-%endif
-
-%if 0%{?fedora} >= 15 || 0%{?rhel} >= 7
-%global with_systemd 1
-%endif
-
-%if 0%{?rhel} == 6
-Requires: python-ordereddict
-Requires: python-imaging
-BuildRequires: python-unittest2
-%endif
-
-%description
-Web application to manage KVM/Qemu virtual machines
-
-
-%prep
-%setup
-
-
-%build
-%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
-%configure
-%else
-%configure --with-spice-html5
-%endif
-make
-
-
-%install
-rm -rf %{buildroot}
-make DESTDIR=%{buildroot} install
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%attr(-,root,root)
-%{python_sitelib}/wok/plugins/kimchi/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
-%{python_sitelib}/wok/plugins/kimchi/model/*.py*
-%{python_sitelib}/wok/plugins/kimchi/API.json
-%{python_sitelib}/wok/plugins/kimchi/
-%{_datadir}/kimchi/doc/API.md
-%{_datadir}/kimchi/doc/README.md
-%{_datadir}/kimchi/doc/README-federation.md
-%{_datadir}/kimchi/doc/kimchi-guest.png
-%{_datadir}/kimchi/doc/kimchi-templates.png
-%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
-%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
-%{_datadir}/wok/plugins/kimchi/ui/
-%{_datadir}/wok/plugins/kimchi
-%{_sysconfdir}/wok/plugins.d/kimchi.conf
-%{_sysconfdir}/wok/plugins.d/template.conf
-%{_sysconfdir}/kimchi/distros.d/debian.json
-%{_sysconfdir}/kimchi/distros.d/fedora.json
-%{_sysconfdir}/kimchi/distros.d/opensuse.json
-%{_sysconfdir}/kimchi/distros.d/ubuntu.json
-%{_sysconfdir}/kimchi/distros.d/gentoo.json
-%{_sysconfdir}/kimchi/
-%{_sharedstatedir}/kimchi/debugreports/
-%{_sharedstatedir}/kimchi/isos/
-%{_sharedstatedir}/kimchi/screenshots/
-%{_sharedstatedir}/kimchi/vnc-tokens/
-%{_sharedstatedir}/kimchi/
-
-
-%changelog
-* Thu Jun 18 2015 Lucio Correia <luciojhc at linux.vnet.ibm.com> 1.6
-- Run kimchi as a plugin
-
-* Thu Feb 26 2015 Frédéric Bonnard <frediz at linux.vnet.ibm.com> 1.4.0
-- Add man page for kimchid
-
-* Tue Feb 11 2014 CrÃstian Viana <vianac at linux.vnet.ibm.com> 1.1.0
-- Add help pages and XSLT dependency
-
-* Tue Jul 16 2013 Adam Litke <agl at us.ibm.com> 0.1.0-1
-- Adapted for autotools build
-
-* Thu Apr 04 2013 Aline Manera <alinefm at br.ibm.com> 0.0-1
-- First build
diff --git a/plugins/kimchi/contrib/kimchi.spec.suse.in b/plugins/kimchi/contrib/kimchi.spec.suse.in
deleted file mode 100644
index e466961..0000000
--- a/plugins/kimchi/contrib/kimchi.spec.suse.in
+++ /dev/null
@@ -1,107 +0,0 @@
-Name: kimchi
-Version: @PACKAGE_VERSION@
-Release: @PACKAGE_RELEASE@%{?dist}
-Summary: Kimchi server application
-BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
-BuildArch: noarch
-Group: System Environment/Base
-License: LGPL/ASL2
-Source0: %{name}-%{version}.tar.gz
-Requires: wok
-Requires: kvm
-Requires: gettext-tools
-Requires: libvirt
-Requires: libvirt-python
-Requires: libvirt-daemon-config-network
-Requires: python-websockify
-Requires: python-configobj
-Requires: novnc
-Requires: python-imaging
-Requires: python-parted
-Requires: python-psutil >= 0.6.0
-Requires: python-jsonschema >= 1.3.0
-Requires: python-ethtool
-Requires: python-ipaddr
-Requires: python-lxml
-Requires: python-xml
-Requires: nfs-client
-Requires: open-iscsi
-Requires: python-libguestfs
-Requires: guestfs-tools
-BuildRequires: libxslt-tools
-BuildRequires: python-lxml
-
-%if 0%{?suse_version} == 1100
-Requires: python-ordereddict
-%endif
-
-%if 0%{?suse_version} > 1140
-%global with_systemd 1
-%endif
-
-%description
-Web application to manage KVM/Qemu virtual machines
-
-%prep
-%setup
-
-%build
-%configure --with-spice-html5
-make
-
-%install
-rm -rf %{buildroot}
-make DESTDIR=%{buildroot} install
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%attr(-,root,root)
-%{python_sitelib}/wok/plugins/kimchi/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
-%{python_sitelib}/wok/plugins/kimchi/model/*.py*
-%{python_sitelib}/wok/plugins/kimchi/API.json
-%{python_sitelib}/wok/plugins/kimchi/
-%{_datadir}/kimchi/doc/API.md
-%{_datadir}/kimchi/doc/README.md
-%{_datadir}/kimchi/doc/README-federation.md
-%{_datadir}/kimchi/doc/kimchi-guest.png
-%{_datadir}/kimchi/doc/kimchi-templates.png
-%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
-%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
-%{_datadir}/wok/plugins/kimchi/ui/
-%{_datadir}/wok/plugins/kimchi
-%{_sysconfdir}/wok/plugins.d/kimchi.conf
-%{_sysconfdir}/wok/plugins.d/template.conf
-%{_sysconfdir}/kimchi/distros.d/debian.json
-%{_sysconfdir}/kimchi/distros.d/fedora.json
-%{_sysconfdir}/kimchi/distros.d/opensuse.json
-%{_sysconfdir}/kimchi/distros.d/ubuntu.json
-%{_sysconfdir}/kimchi/distros.d/gentoo.json
-%{_sysconfdir}/kimchi/
-%{_var}/lib/kimchi/debugreports/
-%{_var}/lib/kimchi/isos/
-%{_var}/lib/kimchi/screenshots/
-%{_var}/lib/kimchi/vnc-tokens/
-%{_var}/lib/kimchi/
-
-
-%changelog
-* Thu Jun 18 2015 Lucio Correia <luciojhc at linux.vnet.ibm.com> 1.6
-- Run kimchi as a plugin
-
-* Thu Feb 26 2015 Frédéric Bonnard <frediz at linux.vnet.ibm.com> 1.4.0
-- Add man page for kimchid
-
-* Tue Feb 11 2014 CrÃstian Viana <vianac at linux.vnet.ibm.com> 1.1.0
-- Add help pages and XSLT dependency
-
-* Thu Jul 18 2013 Adam Litke <agl at us.ibm.com> 0.1.0-1
-- Adapted for autotools build
-- Split Suse and Fedora spec files
-
-* Thu Apr 04 2013 Aline Manera <alinefm at br.ibm.com> 0.0-1
-- First build
diff --git a/plugins/kimchi/contrib/make-deb.sh.in b/plugins/kimchi/contrib/make-deb.sh.in
deleted file mode 100644
index 5a6e56a..0000000
--- a/plugins/kimchi/contrib/make-deb.sh.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-VERSION="@PACKAGE_VERSION@"
-RELEASE="@PACKAGE_RELEASE@"
-
-if [ ! -f configure ]; then
- echo "Please run this script from the top of the package tree"
- exit 1
-fi
-
-TMPDIR=`mktemp -d`
-
-make DESTDIR=$TMPDIR install-deb
-dpkg-deb -b $TMPDIR kimchi-${VERSION}-${RELEASE}.noarch.deb
-rm -rf $TMPDIR
diff --git a/plugins/kimchi/control/Makefile.am b/plugins/kimchi/control/Makefile.am
deleted file mode 100644
index 33118ca..0000000
--- a/plugins/kimchi/control/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = vm
-
-control_PYTHON = *.py
-
-controldir = $(pythondir)/wok/plugins/kimchi/control
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(controldir)
diff --git a/plugins/kimchi/control/__init__.py b/plugins/kimchi/control/__init__.py
deleted file mode 100644
index 4ad9459..0000000
--- a/plugins/kimchi/control/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-
-
-from wok.control.utils import load_url_sub_node
-
-
-sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/plugins/kimchi/control/config.py b/plugins/kimchi/control/config.py
deleted file mode 100644
index 15df68f..0000000
--- a/plugins/kimchi/control/config.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode("config")
-class Config(Resource):
- def __init__(self, model, id=None):
- super(Config, self).__init__(model, id)
- self.capabilities = Capabilities(self.model)
- self.distros = Distros(model)
-
- @property
- def data(self):
- return self.info
-
-
-class Capabilities(Resource):
- def __init__(self, model, id=None):
- super(Capabilities, self).__init__(model, id)
-
- @property
- def data(self):
- return self.info
-
-
-class Distros(Collection):
- def __init__(self, model):
- super(Distros, self).__init__(model)
- self.resource = Distro
-
-
-class Distro(Resource):
- def __init__(self, model, ident):
- super(Distro, self).__init__(model, ident)
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/cpuinfo.py b/plugins/kimchi/control/cpuinfo.py
deleted file mode 100644
index 31f316c..0000000
--- a/plugins/kimchi/control/cpuinfo.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-from wok.control.base import Resource
-
-
-class CPUInfo(Resource):
- def __init__(self, model):
- super(CPUInfo, self).__init__(model)
- self.admin_methods = ['GET']
- self.role_key = 'host'
- self.uri_fmt = "/host/cpuinfo"
-
- @property
- def data(self):
- return {'threading_enabled': self.info['guest_threads_enabled'],
- 'sockets': self.info['sockets'],
- 'cores': self.info['cores_available'],
- 'threads_per_core': self.info['threads_per_core']
- }
diff --git a/plugins/kimchi/control/debugreports.py b/plugins/kimchi/control/debugreports.py
deleted file mode 100644
index b5a3072..0000000
--- a/plugins/kimchi/control/debugreports.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import AsyncCollection, Resource
-from wok.control.utils import internal_redirect
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode('debugreports', True)
-class DebugReports(AsyncCollection):
- def __init__(self, model):
- super(DebugReports, self).__init__(model)
- self.resource = DebugReport
- self.role_key = 'host'
- self.admin_methods = ['GET', 'POST']
-
- def _get_resources(self, filter_params):
- res_list = super(DebugReports, self)._get_resources(filter_params)
- return sorted(res_list, key=lambda x: x.data['time'], reverse=True)
-
-
-class DebugReport(Resource):
- def __init__(self, model, ident):
- super(DebugReport, self).__init__(model, ident)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'PUT', 'POST']
- self.uri_fmt = '/debugreports/%s'
- self.content = DebugReportContent(model, ident)
-
- @property
- def data(self):
- return {'name': self.ident,
- 'uri': self.info['uri'],
- 'time': self.info['ctime']}
-
-
-class DebugReportContent(Resource):
- def __init__(self, model, ident):
- super(DebugReportContent, self).__init__(model, ident)
- self.role_key = 'host'
- self.admin_methods = ['GET']
-
- def get(self):
- self.lookup()
- raise internal_redirect(self.info['uri'])
diff --git a/plugins/kimchi/control/groups.py b/plugins/kimchi/control/groups.py
deleted file mode 100644
index 649ff09..0000000
--- a/plugins/kimchi/control/groups.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import SimpleCollection
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode('groups', True)
-class Groups(SimpleCollection):
- def __init__(self, model):
- super(Groups, self).__init__(model)
- self.role_key = 'guests'
diff --git a/plugins/kimchi/control/host.py b/plugins/kimchi/control/host.py
deleted file mode 100644
index 0a40f1b..0000000
--- a/plugins/kimchi/control/host.py
+++ /dev/null
@@ -1,157 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource, SimpleCollection
-from wok.control.utils import UrlSubNode
-from wok.exception import NotFoundError
-
-from cpuinfo import CPUInfo
-
-
- at UrlSubNode('host', True)
-class Host(Resource):
- def __init__(self, model, id=None):
- super(Host, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'POST']
- self.uri_fmt = '/host/%s'
- self.reboot = self.generate_action_handler('reboot')
- self.shutdown = self.generate_action_handler('shutdown')
- self.stats = HostStats(self.model)
- self.partitions = Partitions(self.model)
- self.devices = Devices(self.model)
- self.packagesupdate = PackagesUpdate(self.model)
- self.repositories = Repositories(self.model)
- self.swupdate = self.generate_action_handler_task('swupdate')
- self.cpuinfo = CPUInfo(self.model)
-
- @property
- def data(self):
- return self.info
-
-
-class HostStats(Resource):
- def __init__(self, model, id=None):
- super(HostStats, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET']
- self.history = HostStatsHistory(self.model)
-
- @property
- def data(self):
- return self.info
-
-
-class HostStatsHistory(Resource):
- @property
- def data(self):
- return self.info
-
-
-class Partitions(Collection):
- def __init__(self, model):
- super(Partitions, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.resource = Partition
-
- # Defining get_resources in order to return list of partitions in UI
- # sorted by their path
- def _get_resources(self, flag_filter):
- res_list = super(Partitions, self)._get_resources(flag_filter)
- res_list = filter(lambda x: x.info['available'], res_list)
- res_list.sort(key=lambda x: x.info['path'])
- return res_list
-
-
-class Partition(Resource):
- def __init__(self, model, id):
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- super(Partition, self).__init__(model, id)
-
- @property
- def data(self):
- if not self.info['available']:
- raise NotFoundError("KCHPART0001E", {'name': self.info['name']})
-
- return self.info
-
-
-class Devices(Collection):
- def __init__(self, model):
- super(Devices, self).__init__(model)
- self.resource = Device
-
-
-class VMHolders(SimpleCollection):
- def __init__(self, model, device_id):
- super(VMHolders, self).__init__(model)
- self.model_args = (device_id, )
-
-
-class Device(Resource):
- def __init__(self, model, id):
- super(Device, self).__init__(model, id)
- self.vm_holders = VMHolders(self.model, id)
-
- @property
- def data(self):
- return self.info
-
-
-class PackagesUpdate(Collection):
- def __init__(self, model):
- super(PackagesUpdate, self).__init__(model)
- self.role_key = 'host'
- self.admin_methods = ['GET']
- self.resource = PackageUpdate
-
-
-class PackageUpdate(Resource):
- def __init__(self, model, id=None):
- super(PackageUpdate, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET']
-
- @property
- def data(self):
- return self.info
-
-
-class Repositories(Collection):
- def __init__(self, model):
- super(Repositories, self).__init__(model)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'POST']
- self.resource = Repository
-
-
-class Repository(Resource):
- def __init__(self, model, id):
- super(Repository, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'PUT', 'POST', 'DELETE']
- self.uri_fmt = "/host/repositories/%s"
- self.enable = self.generate_action_handler('enable')
- self.disable = self.generate_action_handler('disable')
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/interfaces.py b/plugins/kimchi/control/interfaces.py
deleted file mode 100644
index d698b7a..0000000
--- a/plugins/kimchi/control/interfaces.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode('interfaces', True)
-class Interfaces(Collection):
- def __init__(self, model):
- super(Interfaces, self).__init__(model)
- self.role_key = 'network'
- self.admin_methods = ['GET']
- self.resource = Interface
-
-
-class Interface(Resource):
- def __init__(self, model, ident):
- super(Interface, self).__init__(model, ident)
- self.role_key = 'network'
- self.admin_methods = ['GET']
- self.uri_fmt = "/interfaces/%s"
-
- @property
- def data(self):
- return {'name': self.ident,
- 'type': self.info['type'],
- 'ipaddr': self.info['ipaddr'],
- 'netmask': self.info['netmask'],
- 'status': self.info['status']}
diff --git a/plugins/kimchi/control/networks.py b/plugins/kimchi/control/networks.py
deleted file mode 100644
index fd92111..0000000
--- a/plugins/kimchi/control/networks.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode('networks', True)
-class Networks(Collection):
- def __init__(self, model):
- super(Networks, self).__init__(model)
- self.role_key = 'network'
- self.admin_methods = ['POST']
- self.resource = Network
-
-
-class Network(Resource):
- def __init__(self, model, ident):
- super(Network, self).__init__(model, ident)
- self.role_key = 'network'
- self.admin_methods = ['PUT', 'POST', 'DELETE']
- self.uri_fmt = "/networks/%s"
- self.activate = self.generate_action_handler('activate')
- self.deactivate = self.generate_action_handler('deactivate',
- destructive=True)
-
- @property
- def data(self):
- return {'name': self.ident,
- 'vms': self.info['vms'],
- 'in_use': self.info['in_use'],
- 'autostart': self.info['autostart'],
- 'connection': self.info['connection'],
- 'interface': self.info['interface'],
- 'subnet': self.info['subnet'],
- 'dhcp': self.info['dhcp'],
- 'state': self.info['state'],
- 'persistent': self.info['persistent']}
diff --git a/plugins/kimchi/control/peers.py b/plugins/kimchi/control/peers.py
deleted file mode 100644
index 21e9f13..0000000
--- a/plugins/kimchi/control/peers.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import SimpleCollection
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode("peers", True)
-class Peers(SimpleCollection):
- def __init__(self, model):
- super(Peers, self).__init__(model)
- self.role_key = 'peers'
- self.admin_methods = ['GET']
diff --git a/plugins/kimchi/control/storagepools.py b/plugins/kimchi/control/storagepools.py
deleted file mode 100644
index e5f264e..0000000
--- a/plugins/kimchi/control/storagepools.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import get_class_name, model_fn
-from wok.control.utils import validate_params
-from wok.control.utils import UrlSubNode
-
-from ..model.storagepools import ISO_POOL_NAME
-from storagevolumes import IsoVolumes, StorageVolumes
-
-
- at UrlSubNode('storagepools', True)
-class StoragePools(Collection):
- def __init__(self, model):
- super(StoragePools, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['POST']
- self.resource = StoragePool
- isos = IsoPool(model)
- setattr(self, ISO_POOL_NAME, isos)
-
- def create(self, params, *args):
- try:
- create = getattr(self.model, model_fn(self, 'create'))
- except AttributeError:
- error = 'Create is not allowed for %s' % get_class_name(self)
- raise cherrypy.HTTPError(405, error)
-
- validate_params(params, self, 'create')
- args = self.model_args + [params]
- name = create(*args)
- args = self.resource_args + [name]
- res = self.resource(self.model, *args)
- resp = res.get()
-
- if 'task_id' in res.data:
- cherrypy.response.status = 202
- else:
- cherrypy.response.status = 201
-
- return resp
-
- def _get_resources(self, filter_params):
- try:
- res_list = super(StoragePools, self)._get_resources(filter_params)
- # Append reserved pools
- isos = getattr(self, ISO_POOL_NAME)
- isos.lookup()
- res_list.append(isos)
- except AttributeError:
- pass
-
- return res_list
-
-
-class StoragePool(Resource):
- def __init__(self, model, ident):
- super(StoragePool, self).__init__(model, ident)
- self.role_key = 'storage'
- self.admin_methods = ['PUT', 'POST', 'DELETE']
- self.uri_fmt = "/storagepools/%s"
- self.activate = self.generate_action_handler('activate')
- self.deactivate = self.generate_action_handler('deactivate',
- destructive=True)
- self.storagevolumes = StorageVolumes(self.model, ident)
-
- @property
- def data(self):
- res = {'name': self.ident,
- 'state': self.info['state'],
- 'capacity': self.info['capacity'],
- 'allocated': self.info['allocated'],
- 'available': self.info['available'],
- 'path': self.info['path'],
- 'source': self.info['source'],
- 'type': self.info['type'],
- 'nr_volumes': self.info['nr_volumes'],
- 'autostart': self.info['autostart'],
- 'persistent': self.info['persistent']}
-
- val = self.info.get('task_id')
- if val:
- res['task_id'] = val
-
- return res
-
-
-class IsoPool(Resource):
- def __init__(self, model):
- super(IsoPool, self).__init__(model, ISO_POOL_NAME)
- self.storagevolumes = IsoVolumes(self.model, ISO_POOL_NAME)
-
- @property
- def data(self):
- return {'name': self.ident,
- 'state': self.info['state'],
- 'type': self.info['type']}
diff --git a/plugins/kimchi/control/storageservers.py b/plugins/kimchi/control/storageservers.py
deleted file mode 100644
index 654ab47..0000000
--- a/plugins/kimchi/control/storageservers.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok import template
-from wok.control.base import Collection, Resource
-from wok.control.utils import get_class_name, model_fn, UrlSubNode
-
-
- at UrlSubNode('storageservers', True)
-class StorageServers(Collection):
- def __init__(self, model):
- super(StorageServers, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.resource = StorageServer
-
-
-class StorageServer(Resource):
- def __init__(self, model, ident):
- super(StorageServer, self).__init__(model, ident)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.storagetargets = StorageTargets(self.model,
- self.ident.decode("utf-8"))
-
- @property
- def data(self):
- return self.info
-
-
-class StorageTargets(Collection):
- def __init__(self, model, server):
- super(StorageTargets, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.server = server
- self.resource_args = [self.server, ]
- self.model_args = [self.server, ]
-
- def get(self, filter_params):
- res_list = []
- get_list = getattr(self.model, model_fn(self, 'get_list'))
- res_list = get_list(*self.model_args, **filter_params)
- return template.render(get_class_name(self), res_list)
diff --git a/plugins/kimchi/control/storagevolumes.py b/plugins/kimchi/control/storagevolumes.py
deleted file mode 100644
index bbe6627..0000000
--- a/plugins/kimchi/control/storagevolumes.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok import template
-from wok.control.base import AsyncCollection, Collection, Resource
-from wok.control.utils import get_class_name, model_fn
-
-
-class StorageVolumes(AsyncCollection):
- def __init__(self, model, pool):
- super(StorageVolumes, self).__init__(model)
- self.resource = StorageVolume
- self.pool = pool
- self.resource_args = [self.pool, ]
- self.model_args = [self.pool, ]
-
- def filter_data(self, resources, fields_filter):
- # filter directory from storage volumes
- fields_filter.update({'type': ['file', 'block', 'network']})
- return super(StorageVolumes, self).filter_data(resources,
- fields_filter)
-
-
-class StorageVolume(Resource):
- def __init__(self, model, pool, ident):
- super(StorageVolume, self).__init__(model, ident)
- self.pool = pool
- self.ident = ident
- self.info = {}
- self.model_args = [self.pool, self.ident]
- self.uri_fmt = '/storagepools/%s/storagevolumes/%s'
- self.resize = self.generate_action_handler('resize', ['size'])
- self.wipe = self.generate_action_handler('wipe')
- self.clone = self.generate_action_handler_task('clone')
-
- @property
- def data(self):
- res = {'name': self.ident,
- 'type': self.info['type'],
- 'capacity': self.info['capacity'],
- 'allocation': self.info['allocation'],
- 'path': self.info['path'],
- 'used_by': self.info['used_by'],
- 'format': self.info['format']}
-
- for key in ('os_version', 'os_distro', 'bootable', 'base'):
- val = self.info.get(key)
- if val:
- res[key] = val
-
- return res
-
-
-class IsoVolumes(Collection):
- def __init__(self, model, pool):
- super(IsoVolumes, self).__init__(model)
- self.pool = pool
-
- def get(self, filter_params):
- res_list = []
- try:
- get_list = getattr(self.model, model_fn(self, 'get_list'))
- res_list = get_list(*self.model_args)
- except AttributeError:
- pass
-
- return template.render(get_class_name(self), res_list)
diff --git a/plugins/kimchi/control/templates.py b/plugins/kimchi/control/templates.py
deleted file mode 100644
index fc58815..0000000
--- a/plugins/kimchi/control/templates.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode('templates', True)
-class Templates(Collection):
- def __init__(self, model):
- super(Templates, self).__init__(model)
- self.role_key = 'templates'
- self.admin_methods = ['GET', 'POST']
- self.resource = Template
-
-
-class Template(Resource):
- def __init__(self, model, ident):
- super(Template, self).__init__(model, ident)
- self.role_key = 'templates'
- self.admin_methods = ['PUT', 'POST', 'DELETE']
- self.uri_fmt = "/templates/%s"
- self.clone = self.generate_action_handler('clone')
-
- @property
- def data(self):
- return {
- 'name': self.ident,
- 'icon': self.info['icon'],
- 'invalid': self.info['invalid'],
- 'os_distro': self.info['os_distro'],
- 'os_version': self.info['os_version'],
- 'cpus': self.info['cpus'],
- 'memory': self.info['memory'],
- 'cdrom': self.info.get('cdrom', None),
- 'disks': self.info['disks'],
- 'storagepool': self.info['storagepool'],
- 'networks': self.info['networks'],
- 'folder': self.info.get('folder', []),
- 'graphics': self.info['graphics'],
- 'cpu_info': self.info.get('cpu_info')
- }
diff --git a/plugins/kimchi/control/users.py b/plugins/kimchi/control/users.py
deleted file mode 100644
index 756a2f7..0000000
--- a/plugins/kimchi/control/users.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import SimpleCollection
-from wok.control.utils import get_class_name, model_fn, UrlSubNode
-from wok.template import render
-
-
- at UrlSubNode('users', True)
-class Users(SimpleCollection):
- def __init__(self, model):
- super(Users, self).__init__(model)
- self.role_key = 'guests'
-
- def get(self, filter_params):
- res_list = []
- get_list = getattr(self.model, model_fn(self, 'get_list'))
- res_list = get_list(*self.model_args, **filter_params)
- return render(get_class_name(self), res_list)
diff --git a/plugins/kimchi/control/vm/Makefile.am b/plugins/kimchi/control/vm/Makefile.am
deleted file mode 100644
index b17c68a..0000000
--- a/plugins/kimchi/control/vm/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-vm_PYTHON = *.py
-
-vmdir = $(pythondir)/wok/plugins/kimchi/control/vm
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(vmdir)
diff --git a/plugins/kimchi/control/vm/__init__.py b/plugins/kimchi/control/vm/__init__.py
deleted file mode 100644
index a311045..0000000
--- a/plugins/kimchi/control/vm/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-
-
-from wok.control.utils import load_url_sub_node
-
-
-sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/plugins/kimchi/control/vm/hostdevs.py b/plugins/kimchi/control/vm/hostdevs.py
deleted file mode 100644
index a43b9d8..0000000
--- a/plugins/kimchi/control/vm/hostdevs.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode("hostdevs")
-class VMHostDevs(Collection):
- def __init__(self, model, vmid):
- super(VMHostDevs, self).__init__(model)
- self.resource = VMHostDev
- self.vmid = vmid
- self.resource_args = [self.vmid, ]
- self.model_args = [self.vmid, ]
-
-
-class VMHostDev(Resource):
- def __init__(self, model, vmid, ident):
- super(VMHostDev, self).__init__(model, ident)
- self.vmid = vmid
- self.ident = ident
- self.model_args = [self.vmid, self.ident]
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vm/ifaces.py b/plugins/kimchi/control/vm/ifaces.py
deleted file mode 100644
index ac957fd..0000000
--- a/plugins/kimchi/control/vm/ifaces.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode("ifaces")
-class VMIfaces(Collection):
- def __init__(self, model, vm):
- super(VMIfaces, self).__init__(model)
- self.resource = VMIface
- self.vm = vm
- self.resource_args = [self.vm, ]
- self.model_args = [self.vm, ]
-
-
-class VMIface(Resource):
- def __init__(self, model, vm, ident):
- super(VMIface, self).__init__(model, ident)
- self.vm = vm
- self.ident = ident
- self.info = {}
- self.model_args = [self.vm, self.ident]
- self.uri_fmt = '/vms/%s/ifaces/%s'
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vm/snapshots.py b/plugins/kimchi/control/vm/snapshots.py
deleted file mode 100644
index dd17b85..0000000
--- a/plugins/kimchi/control/vm/snapshots.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import AsyncCollection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode('snapshots')
-class VMSnapshots(AsyncCollection):
- def __init__(self, model, vm):
- super(VMSnapshots, self).__init__(model)
- self.resource = VMSnapshot
- self.vm = vm
- self.resource_args = [self.vm, ]
- self.model_args = [self.vm, ]
- self.current = CurrentVMSnapshot(model, vm)
-
-
-class VMSnapshot(Resource):
- def __init__(self, model, vm, ident):
- super(VMSnapshot, self).__init__(model, ident)
- self.vm = vm
- self.ident = ident
- self.model_args = [self.vm, self.ident]
- self.uri_fmt = '/vms/%s/snapshots/%s'
- self.revert = self.generate_action_handler('revert')
-
- @property
- def data(self):
- return self.info
-
-
-class CurrentVMSnapshot(Resource):
- def __init__(self, model, vm):
- super(CurrentVMSnapshot, self).__init__(model)
- self.vm = vm
- self.model_args = [self.vm]
- self.uri_fmt = '/vms/%s/snapshots/current'
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vm/storages.py b/plugins/kimchi/control/vm/storages.py
deleted file mode 100644
index f502caa..0000000
--- a/plugins/kimchi/control/vm/storages.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
- at UrlSubNode("storages")
-class VMStorages(Collection):
- def __init__(self, model, vm):
- super(VMStorages, self).__init__(model)
- self.resource = VMStorage
- self.vm = vm
- self.resource_args = [self.vm, ]
- self.model_args = [self.vm, ]
-
-
-class VMStorage(Resource):
- def __init__(self, model, vm, ident):
- super(VMStorage, self).__init__(model, ident)
- self.vm = vm
- self.ident = ident
- self.info = {}
- self.model_args = [self.vm, self.ident]
- self.uri_fmt = '/vms/%s/storages/%s'
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vms.py b/plugins/kimchi/control/vms.py
deleted file mode 100644
index 858b23c..0000000
--- a/plugins/kimchi/control/vms.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import AsyncCollection, Resource
-from wok.control.utils import internal_redirect, UrlSubNode
-
-from vm import sub_nodes
-
-
- at UrlSubNode('vms', True)
-class VMs(AsyncCollection):
- def __init__(self, model):
- super(VMs, self).__init__(model)
- self.resource = VM
- self.role_key = 'guests'
- self.admin_methods = ['POST']
-
-
-class VM(Resource):
- def __init__(self, model, ident):
- super(VM, self).__init__(model, ident)
- self.role_key = 'guests'
- self.screenshot = VMScreenShot(model, ident)
- self.uri_fmt = '/vms/%s'
- for ident, node in sub_nodes.items():
- setattr(self, ident, node(model, self.ident))
- self.start = self.generate_action_handler('start')
- self.poweroff = self.generate_action_handler('poweroff',
- destructive=True)
- self.shutdown = self.generate_action_handler('shutdown',
- destructive=True)
- self.reset = self.generate_action_handler('reset',
- destructive=True)
- self.connect = self.generate_action_handler('connect')
- self.clone = self.generate_action_handler_task('clone')
- self.suspend = self.generate_action_handler('suspend')
- self.resume = self.generate_action_handler('resume')
-
- @property
- def data(self):
- return self.info
-
-
-class VMScreenShot(Resource):
- def __init__(self, model, ident):
- super(VMScreenShot, self).__init__(model, ident)
- self.role_key = 'guests'
-
- def get(self):
- self.lookup()
- raise internal_redirect(self.info)
diff --git a/plugins/kimchi/disks.py b/plugins/kimchi/disks.py
deleted file mode 100644
index eb40e3a..0000000
--- a/plugins/kimchi/disks.py
+++ /dev/null
@@ -1,196 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os.path
-import re
-import subprocess
-from parted import Device as PDevice
-from parted import Disk as PDisk
-
-from wok.exception import OperationFailed
-from wok.utils import wok_log
-
-
-def _get_dev_node_path(maj_min):
- """ Returns device node path given the device number 'major:min' """
-
- dm_name = "/sys/dev/block/%s/dm/name" % maj_min
- if os.path.exists(dm_name):
- with open(dm_name) as dm_f:
- content = dm_f.read().rstrip('\n')
- return "/dev/mapper/" + content
-
- uevent = "/sys/dev/block/%s/uevent" % maj_min
- with open(uevent) as ueventf:
- content = ueventf.read()
-
- data = dict(re.findall(r'(\S+)=(".*?"|\S+)', content.replace("\n", " ")))
-
- return "/dev/%s" % data["DEVNAME"]
-
-
-def _get_lsblk_devs(keys, devs=[]):
- lsblk = subprocess.Popen(
- ["lsblk", "-Pbo"] + [','.join(keys)] + devs,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = lsblk.communicate()
- if lsblk.returncode != 0:
- raise OperationFailed("KCHDISKS0001E", {'err': err})
-
- return _parse_lsblk_output(out, keys)
-
-
-def _get_dev_major_min(name):
- maj_min = None
-
- keys = ["NAME", "MAJ:MIN"]
- dev_list = _get_lsblk_devs(keys)
-
- for dev in dev_list:
- if dev['name'].split()[0] == name:
- maj_min = dev['maj:min']
- break
- else:
- raise OperationFailed("KCHDISKS0002E", {'device': name})
-
- return maj_min
-
-
-def _is_dev_leaf(devNodePath):
- try:
- # By default, lsblk prints a device information followed by children
- # device information
- childrenCount = len(
- _get_lsblk_devs(["NAME"], [devNodePath])) - 1
- except OperationFailed as e:
- # lsblk is known to fail on multipath devices
- # Assume these devices contain children
- wok_log.error(
- "Error getting device info for %s: %s", devNodePath, e)
- return False
-
- return childrenCount == 0
-
-
-def _is_dev_extended_partition(devType, devNodePath):
- if devType != 'part':
- return False
- diskPath = devNodePath.rstrip('0123456789')
- device = PDevice(diskPath)
- try:
- extended_part = PDisk(device).getExtendedPartition()
- except NotImplementedError as e:
- wok_log.warning(
- "Error getting extended partition info for dev %s type %s: %s",
- devNodePath, devType, e.message)
- # Treate disk with unsupported partiton table as if it does not
- # contain extended partitions.
- return False
- if extended_part and extended_part.path == devNodePath:
- return True
- return False
-
-
-def _parse_lsblk_output(output, keys):
- # output is on format key="value",
- # where key can be NAME, TYPE, FSTYPE, SIZE, MOUNTPOINT, etc
- lines = output.rstrip("\n").split("\n")
- r = []
- for line in lines:
- d = {}
- for key in keys:
- expression = r"%s=\".*?\"" % key
- match = re.search(expression, line)
- field = match.group()
- k, v = field.split('=', 1)
- d[k.lower()] = v[1:-1]
- r.append(d)
- return r
-
-
-def _get_vgname(devNodePath):
- """ Return volume group name of a physical volume. If the device node path
- is not a physical volume, return empty string. """
- pvs = subprocess.Popen(
- ["pvs", "--unbuffered", "--nameprefixes", "--noheadings",
- "-o", "vg_name", devNodePath],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = pvs.communicate()
- if pvs.returncode != 0:
- return ""
-
- return re.findall(r"LVM2_VG_NAME='([^\']*)'", out)[0]
-
-
-def _is_available(name, devtype, fstype, mountpoint, majmin):
- devNodePath = _get_dev_node_path(majmin)
- # Only list unmounted and unformated and leaf and (partition or disk)
- # leaf means a partition, a disk has no partition, or a disk not held
- # by any multipath device. Physical volume belongs to no volume group
- # is also listed. Extended partitions should not be listed.
- if (devtype in ['part', 'disk', 'mpath'] and
- fstype in ['', 'LVM2_member'] and
- mountpoint == "" and
- _get_vgname(devNodePath) == "" and
- _is_dev_leaf(devNodePath) and
- not _is_dev_extended_partition(devtype, devNodePath)):
- return True
- return False
-
-
-def get_partitions_names(check=False):
- names = set()
- keys = ["NAME", "TYPE", "FSTYPE", "MOUNTPOINT", "MAJ:MIN"]
- # output is on format key="value",
- # where key can be NAME, TYPE, FSTYPE, MOUNTPOINT
- for dev in _get_lsblk_devs(keys):
- # split()[0] to avoid the second part of the name, after the
- # whiteline
- name = dev['name'].split()[0]
- if check and not _is_available(name, dev['type'], dev['fstype'],
- dev['mountpoint'], dev['maj:min']):
- continue
- names.add(name)
-
- return list(names)
-
-
-def get_partition_details(name):
- majmin = _get_dev_major_min(name)
- dev_path = _get_dev_node_path(majmin)
-
- keys = ["TYPE", "FSTYPE", "SIZE", "MOUNTPOINT"]
- try:
- dev = _get_lsblk_devs(keys, [dev_path])[0]
- except OperationFailed as e:
- wok_log.error(
- "Error getting partition info for %s: %s", name, e)
- return {}
-
- dev['available'] = _is_available(name, dev['type'], dev['fstype'],
- dev['mountpoint'], majmin)
- if dev['mountpoint']:
- # Sometimes the mountpoint comes with [SWAP] or other
- # info which is not an actual mount point. Filtering it
- regexp = re.compile(r"\[.*\]")
- if regexp.search(dev['mountpoint']) is not None:
- dev['mountpoint'] = ''
- dev['path'] = dev_path
- dev['name'] = name
- return dev
diff --git a/plugins/kimchi/distroloader.py b/plugins/kimchi/distroloader.py
deleted file mode 100644
index 0032737..0000000
--- a/plugins/kimchi/distroloader.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import glob
-import json
-import os
-
-
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import wok_log
-
-import config
-
-
-ARCHS = {'x86_64': ['x86_64', 'amd64', 'i686', 'x86', 'i386'],
- 'amd64': ['x86_64', 'amd64', 'i686', 'x86', 'i386'],
- 'ppc64': ['ppc', 'ppc64'],
- 'ppc64le': ['ppc64', 'ppc64le']}
-
-
-class DistroLoader(object):
-
- def __init__(self, location=None):
- self.location = location or config.get_distros_store()
-
- def _get_json_info(self, fname):
- msg_args = {'filename': fname}
- if not os.path.isfile(fname):
- msg = "DistroLoader: failed to find distro file: %s" % fname
- wok_log.error(msg)
- raise NotFoundError("KCHDL0001E", msg_args)
- try:
- with open(fname) as f:
- data = json.load(f)
- return data
- except ValueError:
- msg = "DistroLoader: failed to parse distro file: %s" % fname
- wok_log.error(msg)
- raise OperationFailed("KCHDL0002E", msg_args)
-
- def get(self):
- arch_list = ARCHS.get(os.uname()[4])
- all_json_files = glob.glob("%s/%s" % (self.location, "*.json"))
- distros = []
- for f in all_json_files:
- distros.extend(self._get_json_info(f))
-
- # Return all remote ISOs arch not found
- return dict([(distro['name'], distro) for distro in distros if
- (arch_list is None or distro['os_arch'] in arch_list)])
diff --git a/plugins/kimchi/distros.d/Makefile.am b/plugins/kimchi/distros.d/Makefile.am
deleted file mode 100644
index 684fe60..0000000
--- a/plugins/kimchi/distros.d/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-distrosdir = $(sysconfdir)/kimchi/distros.d
-
-dist_distros_DATA = *.json
diff --git a/plugins/kimchi/distros.d/debian.json b/plugins/kimchi/distros.d/debian.json
deleted file mode 100644
index 5d6a313..0000000
--- a/plugins/kimchi/distros.d/debian.json
+++ /dev/null
@@ -1,9 +0,0 @@
-[
- {
- "name": "debian-Wheezy",
- "os_distro": "debian",
- "os_arch": "x86_64",
- "os_version": "7.7.0",
- "path": "http://caesar.acc.umu.se/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/fedora.json b/plugins/kimchi/distros.d/fedora.json
deleted file mode 100644
index bce72d6..0000000
--- a/plugins/kimchi/distros.d/fedora.json
+++ /dev/null
@@ -1,30 +0,0 @@
-[
- {
- "name": "Fedora 20",
- "os_distro": "fedora",
- "os_arch": "x86_64",
- "os_version": "20",
- "path": "http://fedora.mirrors.tds.net/pub/fedora/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso"
- },
- {
- "name": "Fedora 18 (PPC64)",
- "os_distro": "fedora",
- "os_arch": "ppc64",
- "os_version": "18",
- "path": "http://mirrors.kernel.org/fedora-secondary/releases/18/Fedora/ppc64/iso/Fedora-18-ppc64-DVD.iso"
- },
- {
- "name": "Fedora 19 (PPC64)",
- "os_distro": "fedora",
- "os_arch": "ppc64",
- "os_version": "19",
- "path": "http://mirrors.kernel.org/fedora-secondary/releases/19/Fedora/ppc64/iso/Fedora-19-ppc64-DVD.iso"
- },
- {
- "name": "Fedora 20 (PPC64)",
- "os_distro": "fedora",
- "os_arch": "ppc64",
- "os_version": "20",
- "path": "http://mirrors.kernel.org/fedora-secondary/releases/20/Fedora/ppc64/iso/Fedora-20-ppc64-DVD.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/gentoo.json b/plugins/kimchi/distros.d/gentoo.json
deleted file mode 100644
index 2c0f012..0000000
--- a/plugins/kimchi/distros.d/gentoo.json
+++ /dev/null
@@ -1,9 +0,0 @@
-[
- {
- "name": "gentoo-20141204",
- "os_distro": "gentoo",
- "os_arch": "x86_64",
- "os_version": "20141204",
- "path": "http://distfiles.gentoo.org/releases/amd64/autobuilds/current-iso/install-amd64-minimal-20141204.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/opensuse.json b/plugins/kimchi/distros.d/opensuse.json
deleted file mode 100644
index f51de97..0000000
--- a/plugins/kimchi/distros.d/opensuse.json
+++ /dev/null
@@ -1,23 +0,0 @@
-[
- {
- "name": "opensuse-12.3",
- "os_distro": "opensuse",
- "os_arch": "x86_64",
- "os_version": "12.3",
- "path": "http://suse.mirrors.tds.net/pub/opensuse/distribution/12.3/iso/openSUSE-12.3-DVD-x86_64.iso"
- },
- {
- "name": "opensuse-13.1",
- "os_distro": "opensuse",
- "os_arch": "x86_64",
- "os_version": "13.1",
- "path": "http://suse.mirrors.tds.net/pub/opensuse/distribution/13.1/iso/openSUSE-13.1-DVD-x86_64.iso"
- },
- {
- "name": "opensuse-13.2",
- "os_distro": "opensuse",
- "os_arch": "x86_64",
- "os_version": "13.2",
- "path": "http://suse.mirrors.tds.net/pub/opensuse/distribution/13.2/iso/openSUSE-13.2-DVD-x86_64.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/ubuntu.json b/plugins/kimchi/distros.d/ubuntu.json
deleted file mode 100644
index 161fbc8..0000000
--- a/plugins/kimchi/distros.d/ubuntu.json
+++ /dev/null
@@ -1,37 +0,0 @@
-[
- {
- "name": "Ubuntu 13.04 (Raring Ringtail)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "13.04",
- "path": "http://ubuntu-releases.cs.umn.edu/13.04/ubuntu-13.04-desktop-amd64.iso"
- },
- {
- "name": "Ubuntu 13.10 (Saucy Salamander)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "13.10",
- "path": "http://ubuntu-releases.cs.umn.edu/13.10/ubuntu-13.10-desktop-amd64.iso"
- },
- {
- "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
- "os_distro": "ubuntu",
- "os_arch": "ppc64",
- "os_version": "14.04",
- "path": "http://cdimages.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-ppc64el.iso"
- },
- {
- "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "14.04",
- "path": "http://releases.ubuntu.com/14.04/ubuntu-14.04-desktop-amd64.iso"
- },
- {
- "name": "Ubuntu Server 14.10 (Utopic Unicorn)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "14.10",
- "path": "http://releases.ubuntu.com/14.10/ubuntu-14.10-desktop-amd64.iso"
- }
-]
diff --git a/plugins/kimchi/docs/API.md b/plugins/kimchi/docs/API.md
deleted file mode 100644
index fca424c..0000000
--- a/plugins/kimchi/docs/API.md
+++ /dev/null
@@ -1,1116 +0,0 @@
-## Project Kimchi REST API Specification
-
-The Kimchi API provides all functionality to the application and may be used
-directly by external tools. In the following sections you will find the
-specification of all Collections and Resource types that are supported and the
-URIs where they can be accessed. In order to use the API effectively, please
-the following general conventions:
-
-* The **Content Type** of the API is JSON. When making HTTP requests to this
- API you should specify the following headers:
- * Accept: application/json
- * Content-type: application/json
-* A **Collection** is a group of Resources of a given type.
- * A **GET** request retrieves a list of summarized Resource representations
- This summary *may* include all or some of the Resource properties but
- *must* include a link to the full Resource representation.
- * A **POST** request will create a new Resource in the Collection. The set
- of Resource properties *must* be specified as a JSON object in the request
- body.
- * No other HTTP methods are supported for Collections
-* A **Resource** is a representation of a singular object in the API (eg.
- Virtual Machine).
- * A **GET** request retrieves the full Resource representation.
- * A **DELETE** request will delete the Resource. This request *may* contain
- a JSON object which specifies optional parameters.
- * A **PUT** request is used to modify the properties of a Resource (eg.
- Change the name of a Virtual Machine). This kind of request *must not*
- alter the live state of the Resource. Only *actions* may alter live state.
- * A **POST** request commits an *action* upon a Resource (eg. Start a
- Virtual Machine). This request is made to a URI relative to the Resource
- URI. Available *actions* are described within the *actions* property of a
- Resource representation. The request body *must* contain a JSON object
- which specifies parameters.
-* URIs begin with '/plugins/kimchi' to indicate the root of Kimchi plugin.
- * Variable segments in the URI begin with a ':' and should replaced with the
- appropriate resource identifier.
-
-### Collection: Virtual Machines
-
-**URI:** /plugins/kimchi/vms
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Virtual Machines
-* **POST**: Create a new Virtual Machine
- * name *(optional)*: The name of the VM. Used to identify the VM in this
- API. If omitted, a name will be chosen based on the template used.
- * persistent: If 'true', vm will persist after a Power Off or host reboot.
- All virtual machines created by Kimchi are persistent.
- * template: The URI of a Template to use when building the VM
- * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
- * graphics *(optional)*: Specify the graphics paramenter for this vm
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
-
-
-### Resource: Virtual Machine
-
-**URI:** /plugins/kimchi/vms/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Virtual Machine
- * name: The name of the VM. Used to identify the VM in this API
- * state: Indicates the current state in the VM lifecycle
- * running: The VM is powered on
- * paused: The VMs virtual CPUs are paused
- * shutoff: The VM is powered off
- * stats: Virtual machine statistics:
- * cpu_utilization: A number between 0 and 100 which indicates the
- percentage of CPU utilization.
- * net_throughput: Expresses total network throughput for reads and
- writes across all virtual interfaces (kb/s).
- * net_throughput_peak: The highest recent value of 'net_throughput'.
- * io_throughput: Expresses the total IO throughput for reads and
- writes across all virtual disks (kb/s).
- * io_throughput_peak: The highest recent value of 'io_throughput'.
- * uuid: UUID of the VM.
- * memory: The amount of memory assigned to the VM (in MB)
- * cpus: The number of CPUs assigned to the VM
- * screenshot: A link to a recent capture of the screen in PNG format
- * icon: A link to an icon that represents the VM
- * graphics: A dict to show detail of VM graphics.
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
- * port: The real port number of the graphics, vnc or spice. Users
- can use this port to connect to the vm with general vnc/spice
- clients.
- * passwd: console password
- * passwdValidTo: lifetime for the console password.
- * users: A list of system users who have permission to access the VM.
- Default is: empty (i.e. only root-users may access).
- * groups: A list of system groups whose users have permission to access
- the VM. Default is: empty (i.e. no groups given access).
-* **DELETE**: Remove the Virtual Machine
-* **PUT**: update the parameters of existed VM
- * name: New name for this VM (only applied for shutoff VM)
- * users: New list of system users.
- * groups: New list of system groups.
- * cpus: New number of virtual cpus for this VM (if VM is running, new value
- will take effect in next reboot)
- * memory: New amount of memory (MB) for this VM (if VM is running, new
- value will take effect in next reboot)
- * graphics: A dict to show detail of VM graphics.
- * passwd *(optional)*: console password. When omitted a random password
- willbe generated.
- * passwdValidTo *(optional)*: lifetime for the console password. When
- omitted the password will be valid just
- for 30 seconds.
-
-* **POST**: *See Virtual Machine Actions*
-
-**Actions (POST):**
-
-* start: Power on a VM
-* poweroff: Power off a VM forcefully. Note this action may produce undesirable
- results, for example unflushed disk cache in the guest.
-* shutdown: Shut down a VM graceful. This action issue shutdown request to guest.
- And the guest will react this request. Note the guest OS may ignore
- the request.
-* reset: Reset a VM immediately without the guest OS shutdown.
- It emulates the power reset button on a machine. Note that there is a
- risk of data loss caused by reset without the guest OS shutdown.
-* connect: Prepare the connection for spice or vnc
-
-* clone: Create a new VM identical to this VM. The new VM's name, UUID and
- network MAC addresses will be generated automatically. Each existing
- disks will be copied to a new volume in the same storage pool. If
- there is no available space on that storage pool to hold the new
- volume, it will be created on the pool 'default'. This action returns
- a Task.
-
-* suspend: Suspend an active domain. The process is frozen without further
- access to CPU resources and I/O but the memory used by the domain at
- the hypervisor level will stay allocated.
-
-* resume: Resume a suspended domain. The process is restarted from the state
- where it was frozen by calling "suspend".
-
-### Sub-resource: Virtual Machine Screenshot
-
-**URI:** /plugins/kimchi/vms/*:name*/screenshot
-
-Represents a snapshot of the Virtual Machine's primary monitor.
-
-**Methods:**
-
-* **GET**: Redirect to the latest screenshot of a Virtual Machine in PNG format
-
-
-### Sub-collection: Virtual Machine storages
-**URI:** /plugins/kimchi/vms/*:name*/storages
-* **GET**: Retrieve a summarized list of all storages of specified guest
-* **POST**: Attach a new storage or virtual drive to specified virtual machine.
- * type: The type of the storage (currently support 'cdrom' and 'disk').
- * path: Path of cdrom iso.
- * pool: Storage pool which disk image file locate in.
- * vol: Storage volume name of disk image.
-
-### Sub-resource: storage
-**URI:** /plugins/kimchi/vms/*:name*/storages/*:dev*
-* **GET**: Retrieve storage information
- * dev: The name of the storage in the vm.
- * type: The type of the storage (currently support 'cdrom' and 'disk').
- * path: Path of cdrom iso or disk image file.
- * bus: Bus type of disk attached.
-* **PUT**: Update storage information
- * path: Path of cdrom iso. Can not be blank. Now just support cdrom type.
-* **DELETE**: Remove the storage.
-
-**Actions (POST):**
-
-
-### Sub-collection: Virtual Machine Passthrough Devices
-**URI:** /plugins/kimchi/vms/*:name*/hostdevs
-* **GET**: Retrieve a summarized list of all directly assigned host device of
- specified guest.
-* **POST**: Directly assign a host device to guest.
- * name: The name of the host device to be assigned to vm.
-
-### Sub-resource: Device
-**URI:** /plugins/kimchi/vms/*:name*/hostdevs/*:dev*
-* **GET**: Retrieve assigned device information
- * name: The name of the assigned device.
- * type: The type of the assigned device.
-* **DELETE**: Detach the host device from VM.
-
-### Sub-collection: Virtual Machine Snapshots
-**URI:** /plugins/kimchi/vms/*:name*/snapshots
-* **POST**: Create a new snapshot on a VM.
- * name: The snapshot name (optional, defaults to a value based on the
- current time).
-* **GET**: Retrieve a list of snapshots on a VM.
-
-### Sub-resource: Snapshot
-**URI:** /plugins/kimchi/vms/*:name*/snapshots/*:snapshot*
-* **GET**: Retrieve snapshot information.
- * created: The time when the snapshot was created
- (in seconds, since the epoch).
- * name: The snapshot name.
- * parent: The name of the parent snapshot, or an empty string if there is
- no parent.
- * state: The corresponding domain's state when the snapshot was created.
-* **DELETE**: Delete snapshot. If the snapshot has any children, they will be
- merged automatically with the snapshot's parent.
-* **POST**: See "Snapshot actions (POST)"
-
-**Snapshot Actions (POST):**
-
-* revert: Revert the domain to the given snapshot.
-
-### Sub-resource: Current snapshot
-**URI:** /plugins/kimchi/vms/*:name*/snapshots/current
-* **GET**: Retrieve current snapshot information for the virtual machine.
-
-### Collection: Templates
-
-**URI:** /plugins/kimchi/templates
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Templates
-* **POST**: Create a new Template
- * name: The name of the Template. Used to identify the Template in this API
- * os_distro *(optional)*: The operating system distribution
- * os_version *(optional)*: The version of the operating system distribution
- * cpus *(optional)*: The number of CPUs assigned to the VM.
- Default is 1, unlees specifying a cpu topology. In that case, cpus
- will default to a product of the topology values (see cpu_info).
- * memory *(optional)*: The amount of memory assigned to the VM.
- Default is 1024M.
- * cdrom *(optional)*: A volume name or URI to an ISO image.
- * storagepool *(optional)*: URI of the storagepool.
- Default is '/storagepools/default'
- * networks *(optional)*: list of networks will be assigned to the new VM.
- Default is '[default]'
- * disks *(optional)*: An array of requested disks with the following optional fields
- (either *size* or *volume* must be specified):
- * index: The device index
- * size: The device size in GB
- * base: Base image of this disk
-
- * graphics *(optional)*: The graphics paramenters of this template
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
- * cpu_info *(optional)*: CPU-specific information.
- * topology: Specify sockets, threads, and cores to run the virtual CPU
- threads on.
- All three are required in order to specify cpu topology.
- * sockets - The number of sockets to use.
- * cores - The number of cores per socket.
- * threads - The number of threads per core.
- If specifying both cpus and CPU topology, make sure cpus is
- equal to the product of sockets, cores, and threads.
-
-### Sub-Collection: Virtual Machine Network Interfaces
-
-**URI:** /plugins/kimchi/vms/*:name*/ifaces
-
-Represents all network interfaces attached to a Virtual Machine.
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all network interfaces attached to a Virtual Machine.
-
-* **POST**: attach a network interface to VM
- * model *(optional)*: model of emulated network interface card. It can be one of these models:
- ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
- When model is missing, libvirt will set 'rtl8139' as default value.
- * network *(optional)*: the name of resource network, it is required when the
- interface type is network.
- * type: The type of VM network interface that libvirt supports.
- Now kimchi just supports 'network' type.
-
-### Sub-Resource: Virtual Machine Network Interface
-
-**URI:** /plugins/kimchi/vms/*:name*/ifaces/*:mac*
-
-A interface represents available network interface on VM.
-
-**Methods:**
-
-* **GET**: Retrieve the full description of the VM network interface
- * bridge *(optional)*: the name of resource bridge, only be available when the
- interface type is bridge.
- * mac: Media Access Control Address of the VM interface.
- * model *(optional)*: model of emulated network interface card. It will be one of these models:
- ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
- * network *(optional)*: the name of resource network, only be available when the
- interface type is network.
- * type: The type of VM network interface that libvirt supports.
- It will be one of these types: 'network', 'bridge', 'user','ethernet',
- 'direct', 'hostdev', 'mcast', 'server' and 'client'.
-
-* **DELETE**: detach the network interface from VM
-
-* **PUT**: update the parameters of existing VM interface.
- * model *(optional)*: model of emulated network interface card. It will be one of these models:
- ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
- This change is only on the persisted VM configuration.
- * network *(optional)*: the name of resource network, only be available when the
- interface type is network.
- This change is on the active VM instance and persisted VM configuration.
-
-**Actions (POST):**
-
-*No actions defined*
-
-
-### Resource: Template
-
-**URI:** /plugins/kimchi/templates/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Template
- * name: A name for this template
- * folder: A virtual path which can be used to organize Templates in a user
- interface. The format is an array of path components.
- * icon: A URI to a PNG image representing this template
- * os_distro: The operating system distribution
- * os_version: The version of the operating system distribution
- * cpus: The number of CPUs assigned to the VM
- * memory: The amount of memory assigned to the VM in the unit of MB
- * cdrom: A volume name or URI to an ISO image
- * storagepool: URI of the storagepool where template allocates vm storage.
- * networks *(optional)*: list of networks will be assigned to the new VM.
- * disks: An array of requested disks with the following optional fields
- (either *size* or *volume* must be specified):
- * index: The device index
- * size: The device size in GB
- * volume: A volume name that contains the initial disk contents
- * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc.
- * graphics: A dict of graphics paramenters of this template
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
- * invalid: A dict indicates which paramenters of this template are invalid.
- * networks *(optional)*: An array of invalid network names.
- * cdrom *(optional)*: An array of invalid cdrom names.
- * disks *(optional)*: An array of invalid volume names.
- * storagepools *(optional)*: An array of invalid storagepool names.
-
-* **DELETE**: Remove the Template
-* **POST**: *See Template Actions*
-* **PUT**: update the parameters of existed template
- * name: A name for this template
- * folder: A virtual path which can be used to organize Templates in the user
- interface. The format is an array of path components.
- * icon: A URI to a PNG image representing this template
- * os_distro: The operating system distribution
- * os_version: The version of the operating system distribution
- * cpus: The number of CPUs assigned to the VM
- * memory: The amount of memory assigned to the VM
- * cdrom: A volume name or URI to an ISO image
- * storagepool: URI of the storagepool where template allocates vm storage.
- * networks *(optional)*: list of networks will be assigned to the new VM.
- * disks: An array of requested disks with the following optional fields
- (either *size* or *volume* must be specified):
- * index: The device index
- * size: The device size in GB
- * volume: A volume name that contains the initial disk contents
- * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc.
- * graphics *(optional)*: A dict of graphics paramenters of this template
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
-
-**Actions (POST):**
-
-* clone: clone a template from an existing template with different name.
- It will provide a reasonable default name with "-cloneN" as suffix
- for the new clone template. The "N" means the number of clone times.
-
-### Collection: Storage Pools
-
-**URI:** /plugins/kimchi/storagepools
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Storage Pools
-* **POST**: Create a new Storage Pool
- * name: The name of the Storage Pool.
- * type: The type of the defined Storage Pool.
- Supported types: 'dir', 'kimchi-iso', 'netfs', 'logical', 'iscsi', 'scsi'
- * path: The path of the defined Storage Pool.
- For 'kimchi-iso' pool refers to targeted deep scan path.
- Pool types: 'dir', 'kimchi-iso'.
- * source: Dictionary containing source information of the pool.
- * host: IP or hostname of server for a pool backed from a remote host.
- Pool types: 'netfs', 'iscsi'.
- * path: Export path on NFS server for NFS pool.
- Pool types: 'netfs'.
- * devices: Array of devices to be used in the Storage Pool
- Pool types: 'logical'.
- * target: Target IQN of an iSCSI pool.
- Pool types: 'iscsi'.
- * port *(optional)*: Listening port of a remote storage server.
- Pool types: 'iscsi'.
- * auth *(optional)*: Storage back-end authentication information.
- Pool types: 'iscsi'.
- * username: Login username of the iSCSI target.
- * password: Login password of the iSCSI target.
- * adapter_name: SCSI host name.
-
-### Resource: Storage Pool
-
-**URI:** /plugins/kimchi/storagepools/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Storage Pool
- * name: The name of the Storage Pool
- Used to identify the Storage Pool in this API
- 'kimchi_isos' is a reserved storage pool
- which aggregates all ISO images
- across all active storage pools into a single view.
- * state: Indicates the current state of the Storage Pool
- * active: The Storage Pool is ready for use
- * inactive: The Storage Pool is not available
- * path: The path of the defined Storage Pool
- * type: The type of the Storage Pool
- * capacity: The total space which can be used to store volumes
- The unit is Bytes
- * allocated: The amount of space which is being used to store volumes
- The unit is Bytes
- * available: Free space available for creating new volumes in the pool
- * nr_volumes: The number of storage volumes for active pools, 0 for inactive pools
- * autostart: Whether the storage pool will be enabled
- automatically when the system boots
- * persistent: True, when pool persist after a system reboot or be stopped.
- All storage pools created by Kimchi are persistent.
- * source: Source of the storage pool,
- * addr: mount address of this storage pool(for 'netfs' pool)
- * path: export path of this storage pool(for 'netfs' pool)
-
-* **PUT**: Set whether the Storage Pool should be enabled automatically when the
- system boots
- * autostart: Toggle the autostart flag of the VM. This flag sets whether
- the Storage Pool should be enabled automatically when the
- system boots
- * disks: Adds one or more disks to the pool (for 'logical' pool only)
-* **DELETE**: Remove the Storage Pool
-* **POST**: *See Storage Pool Actions*
-
-**Actions (POST):**
-
-* activate: Activate an inactive Storage Pool
-* deactivate: Deactivate an active Storage Pool
-
-### Collection: Storage Volumes
-
-**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Storage Volumes
- in the defined Storage Pool
-* **POST**: Create a new Storage Volume in the Storage Pool
- The return resource is a task resource * See Resource: Task *
- Only one of 'capacity', 'url' can be specified.
- * name: The name of the Storage Volume
- * capacity: The total space which can be used to store volumes
- The unit is bytes
- * format: The format of the defined Storage Volume. Only used when creating
- a storage volume with 'capacity'.
- * upload: True to start an upload process. False, otherwise.
- Only used when creating a storage volume 'capacity' parameter.
- * file: File to be uploaded, passed through form data
-
-### Resource: Storage Volume
-
-**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Storage Volume
- * name: The name of the Storage Volume
- Used to identify the Storage Volume in this API
- * type: The type of the Storage Volume
- * capacity: The total space which can be used to store data
- The unit is Bytes
- * allocation: The amount of space which is being used to store data
- The unit is Bytes
- * format: The format of the file or volume
- * path: Full path of the volume on the host filesystem.
- * os_distro *(optional)*: os distribution of the volume, for iso volume only.
- * os_version *(optional)*: os version of the volume, for iso volume only.
- * bootable *(optional)*: True if iso image is bootable and not corrupted.
- * used_by: Name of vms which use this volume.
-
-* **DELETE**: Remove the Storage Volume
-* **POST**: *See Storage Volume Actions*
-* **PUT**: Upload storage volume chunk
- * chunk_size: Chunk size of the slice in Bytes.
- * chunk: Actual data of uploaded file
-
-**Actions (POST):**
-
-* resize: Resize a Storage Volume
- * size: resize the total space which can be used to store data
- The unit is bytes
-* wipe: Wipe a Storage Volume
-* clone: Clone a Storage Volume.
- * pool: The name of the destination pool (optional).
- * name: The new storage volume name (optional).
-
-
-### Collection: Interfaces
-
-**URI:** /plugins/kimchi/interfaces
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of current Interfaces
-
-### Resource: Interface
-
-**URI:** /plugins/kimchi/interfaces/*:name*
-
-A interface represents available interface on host.
-
-**Methods:**
-
-* **GET**: Retrieve the full description of the Interface
- * name: The name of the interface.
- * status: The current status of the Interface.
- * active: The interface is active.
- * inactive: The interface is inactive.
- * ipaddr: The ip address assigned to this interface in subnet.
- * netmask: Is used to divide an IP address into subnets and specify the
- networks available hosts
- * type: The net device type of the interface.
- * nic: Network interface controller that connects a computer to a
- computer network
- * vlan: A logical interface that represents a VLAN in all Layer 3
- activities the unit may participate in
- * bonding: The combination of network interfaces on one host for redundancy
- and/or increased throughput.
- * bridge: A network device that connects multiple network segments.
-
-* **POST**: *See Interface Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Collection: Networks
-
-**URI:** /plugins/kimchi/networks
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Networks
-* **POST**: Create a new Network
- * name: The name of the Network
- * connection: Specifies how this network should be connected to the other
- networks visible to this host.
- * isolated: Create a private, isolated virtual network.
- * nat: Outgoing traffic will be routed through the host.
- * bridge: All traffic on this network will be bridged through the indicated
- interface.
- * subnet *(optional)*: Network segment in slash-separated format with ip address and
- prefix or netmask used to create nat network.
- * interface *(optional)*: The name of a network interface on the host.
- For bridge network, the interface can be a bridge or nic/bonding
- device.
- * vlan_id *(optional)*: VLAN tagging ID for the bridge network.
-
-### Resource: Network
-
-**URI:** /plugins/kimchi/networks/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Network
- * name: The name of the Network
- Used to identify the Network in this API
- * state: Indicates the current state of the Network
- * active: The Network is ready for use
- * inactive: The Network is not available
- * autostart: Network autostart onboot
- * in_use: Indicates ('true') if some guest is attached to this network and 'false' otherwise.
- * vms: all vms attached to this network
- * subnet: Network segment in slash-separated format with ip address and prefix
- * dhcp: DHCP services on the virtual network is enabled.
- * start: start boundary of a pool of addresses to be provided to DHCP clients.
- * end: end boundary of a pool of addresses to be provided to DHCP clients.
- * connection: Specifies how this network should be connected to the other networks
- visible to this host.
- * isolated: A private, isolated virtual network.
- The VMs attached to it can not be reached by the systems
- outside of this network and vice versa.
- * nat: Outgoing traffic will be routed through the host.
- The VM attached to it will have internet access via the host but
- other computers will not be able to connect to the VM.
- * bridge: Aggregated Public Network.
- The VM that joines this network is seen as a peer on this network
- and it may offer network services such as HTTP or SSH.
- * interface: The name of a bridge network interface on the host. All traffic
- on this network will be bridged through the indicated interface.
- The interface is a bridge or ethernet/bonding device.
- * persistent: If 'true', network will persist after a system reboot or be stopped.
- All networks created by Kimchi are persistent.
-
-* **DELETE**: Remove the Network
-* **POST**: *See Network Actions*
-
-**Actions (POST):**
-
-* activate: Activate an inactive Network
-* deactivate: Deactivate an active Network
-
-
-### Resource: Configuration
-
-**URI:** /plugins/kimchi/config
-
-Contains information about the application environment and configuration.
-
-**Methods:**
-
-* **GET**: Retrieve configuration information
- * display_proxy_port: Port for vnc and spice's websocket proxy to listen on
- * version: The version of the kimchi service
-* **POST**: *See Configuration Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Resource: Capabilities
-
-**URI:** /plugins/kimchi/config/capabilities
-
-Contains information about the host capabilities: iso streaming, screenshot
-creation.
-
-**Methods:**
-
-* **GET**: Retrieve capabilities information
- * libvirt_stream_protocols: list of which network protocols are accepted
- for iso streaming by libvirt
- * qemu_spice: True, if QEMU supports Spice; False, otherwise
- * qemu_stream: True, if QEMU supports ISO streaming; False, otherwise
- * screenshot: True, if libvirt stream functionality can create screenshot
- file without problems; False, otherwise or None if the functionality was
- not tested yet
- * system_report_tool: True if the is some debug report tool installed on
- the system; False, otherwise.
- * update_tool: True if there is a compatible package manager for the
- system; False, otherwise
- * repo_mngt_tool: 'deb', 'yum' or None - when the repository management
- tool is not identified
- * federation: 'on' if federation feature is enabled, 'off' otherwise.
- * auth: authentication type, 'pam' and 'ldap' are supported.
-* **POST**: *See Configuration Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Collection: Storage Servers
-
-**URI:** /plugins/kimchi/storageservers
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of used storage servers.
- * Parameters:
- * _target_type: Filter server list with given type, currently support
- 'netfs' and 'iscsi'.
-
-### Resource: Storage Server
-
-**URI:** /plugins/kimchi/storageservers/*:host*
-
-**Methods:**
-
-* **GET**: Retrieve description of a Storage Server
- * host: IP or host name of storage server
- * port: port of storage server, only for "iscsi"
-
-### Collection: Storage Targets
-
-**URI:** /plugins/kimchi/storageservers/*:name*/storagetargets
-
-**Methods:**
-
-* **GET**: Retrieve a list of available storage targets.
- * Parameters:
- * _target_type: Filter target list with given type, currently support
- 'netfs' and 'iscsi'.
- * _server_port: Filter target list with given server port,
- currently support 'iscsi'.
- * Response: A list with storage targets information.
- * host: IP or host name of storage server of this target.
- * target_type: Type of storage target, supported: 'nfs'.
- * target: Storage target path.
-
-### Collection: Distros
-
-**URI:** /plugins/kimchi/config/distros
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all Distros
-
-### Resource: Distro
-
-**URI:** /plugins/kimchi/config/distros/*:name*
-
-Contains information about the OS distribution.
-
-**Methods:**
-
-* **GET**: Retrieve a OS distribution information.
- * name: The name of the Distro.
- * os_distro: The operating system distribution.
- * os_version: The version of the operating system distribution.
- * path: A URI to an ISO image.
-
-**Actions (POST):**
-
-*No actions defined*
-
-#### Collection: Debug Reports
-
-**URI:** /plugins/kimchi/debugreports
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all available Debug Reports
-* **POST**: Create a new Debug Report. This POST method is different
- from the other ones. The return resource is a task resource which
- is identified by the url below
- * task resource. * See Resource: Task *
-
-### Resource: Debug Report
-
-**URI:** /plugins/kimchi/debugreports/*:name*
-
-A Debug Report is an archive of logs and other information about the host that
-is used to diagnose and debug problems. The exact format and contents are
-specific to the low level collection tool being used.
-
-**Methods:**
-
-* **GET**: Retrieve the full description of Debug Report
- * name: The debug report name used to identify the report
- * uri: The URI path to download a debug report
- * time: The time when the debug report is created
-
-* **PUT**: rename an existed debug report
- * name: The new name for this debug report
-
-* **DELETE**: Remove the Debug Report
- * name: The debug report name used to identify the report
-
-* **POST**: *See Debug Report Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Sub-resource: Debug Report content
-
-**URI:** /plugins/kimchi/debugreports/*:name*/content
-
-It is the sub-resource of Debug Report and the client use it to get the real content
-of the Debug Report file from the server
-
-* **GET**: Retrieve the content of a Debug Report file
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Resource: Host
-
-**URI:** /plugins/kimchi/host
-Contains information of host.
-
-**Methods:**
-
-* **GET**: Retrieve host static information
- * memory: Total size of host physical memory
- The unit is Bytes
- * cpu_model: The model name of host CPU
- * cpus: The number of online CPUs available on host
- * os_distro: The OS distribution that runs on host
- * os_version: The version of OS distribution
- * os_codename: The code name of OS distribution
-
-* **POST**: *See Host Actions*
-
-**Actions (POST):**
-
-* reboot: Restart the host machine.
- Only allowed if there is not vm running.
-* shutdown: Power off the host machine.
- Only allowed if there is not vm running.
-* swupdate: Start the update of packages in background and return a Task resource
- * task resource. * See Resource: Task *
-
-### Resource: Users
-
-**URI:** /plugins/kimchi/users
-List of available users.
-
-**Methods:**
-
-* **GET**: Retrieve list of available users.
- * Parameters:
- * _user_id: Validate whether user exists.
- Essential for 'ldap' authentication.
-
-### Resource: Groups
-
-**URI:** /plugins/kimchi/groups
-List of available groups.
-
-**Methods:**
-
-* **GET**: Retrieve list of available groups, only support 'pam' authentication.
-
-### Resource: HostStats
-
-**URI:** /plugins/kimchi/host/stats
-
-Contains the host sample data.
-
-**Methods:**
-
-* **GET**: Retrieve host sample data
- * cpu_utilization: A number between 0 and 100 which indicates the
- percentage of CPU utilization.
- * memory: memory statistics of host
- * total: Total amount of memory. The unit is Bytes.
- * free: The amount of memory left unused by the system. The unit is Bytes.
- * buffers: The amount of memory used for file buffers. The unit is Bytes.
- * cached: The amount of memory used as cache memory. The unit is Bytes.
- * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
- * disk_read_rate: Expresses the total IO throughput for reads across
- all disks (B/s).
- * disk_write_rate: Expresses the total IO throughput for writes across
- all disks (B/s).
- * net_sent_rate: Expresses the total network throughput for writes across
- all interfaces (B/s).
- * net_recv_rate: Expresses the total network throughput for reads across
- all interfaces (B/s).
-
-* **POST**: *See HostStats Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Resource: HostStats
-
-**URI:** /plugins/kimchi/host/cpuinfo
-
-The cores and sockets of a hosts's CPU. Useful when sizing VMs to take
-advantages of the perforamance benefits of SMT (Power) or Hyper-Threading (Intel).
-
-**Methods:**
-
-* **GET**: Retreives the sockets, cores, and threads values.
- * threading_enabled: Whether CPU topology is supported on this system.
- * sockets: The number of total sockets on a system.
- * cores: The total number of cores per socket.
- * threads_per_core: The threads per core.
-
-**Actions (PUT):**
-
-*No actions defined*
-
-**Actions (POST):**
-
-*No actions defined*
-
-
-### Resource: HostStatsHistory
-
-**URI:** /plugins/kimchi/host/stats/history
-
-It is the sub-resource of Host Stats and the client uses it to get the host
-stats history
-
-**Methods:**
-
-* **GET**: Retrieve host sample data history
- * cpu_utilization: CPU utilization history
- * memory: Memory statistics history
- * total: Total amount of memory. The unit is Bytes.
- * free: The amount of memory left unused by the system. The unit is Bytes.
- * buffers: The amount of memory used for file buffers. The unit is Bytes.
- * cached: The amount of memory used as cache memory. The unit is Bytes.
- * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
- * disk_read_rate: IO throughput for reads history
- * disk_write_rate: IO throughput for writes history
- * net_sent_rate: Network throughput for writes history
- * net_recv_rate: Network throughput for reads history
-
-* **POST**: *See HostStatsHistory Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Collection: Partitions
-
-**URI:** /plugins/kimchi/host/partitions
-
-**Methods:**
-
-* **GET**: Retrieves a detailed list of all partitions of the host.
-
-### Resource: Partition
-
-**URI:** /plugins/kimchi/host/partitions/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the description of a single Partition:
- * name: The name of the partition. Used to identify it in this API
- * path: The device path of this partition.
- * type: The type of the partition:
- * part: a standard partition
- * lvm: a partition that belongs to a lvm
- * fstype: The file system type of the partition
- * size: The total size of the partition, in bytes
- * mountpoint: If the partition is mounted, represents the mountpoint.
- Otherwise blank.
- * available: false, if the partition is in use by system; true, otherwise.
-
-### Collection: Devices
-
-**URI:** /plugins/kimchi/host/devices
-
-**Methods:**
-
-* **GET**: Retrieves list of host devices (Node Devices).
- * Parameters:
- * _cap: Filter node device list with given node device capability.
- To list Fibre Channel SCSI Host devices, use "_cap=fc_host".
- Other available values are "fc_host", "net", "pci", "scsi",
- "storage", "system", "usb" and "usb_device".
- * _passthrough: Filter devices eligible to be assigned to guest
- directly. Possible values are "ture" and "false".
- * _passthrough_affected_by: Filter the affected devices in the same
- group of a certain directly assigned device.
- The value should be the name of a device.
-
-### Resource: Device
-
-**URI:** /plugins/kimchi/host/devices/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve information of a single host device.
- * device_type: Type of the device, supported types are "net", "pci", "scsi",
- "storage", "system", "usb" and "usb_device".
- * name: The name of the device.
- * path: Path of device in sysfs.
- * parent: The name of the parent parent device.
- * adapter: Host adapter information of a "scsi_host" or "fc_host" device.
- * type: The capability type of the scsi_host device (fc_host, vport_ops).
- * wwnn: The HBA Word Wide Node Name. Empty if pci device is not fc_host.
- * wwpn: The HBA Word Wide Port Name. Empty if pci device is not fc_host.
- * domain: Domain number of a "pci" device.
- * bus: Bus number of a "pci" device.
- * slot: Slot number of a "pci" device.
- * function: Function number of a "pci" device.
- * vendor: Vendor information of a "pci" device.
- * id: Vendor id of a "pci" device.
- * description: Vendor description of a "pci" device.
- * product: Product information of a "pci" device.
- * id: Product id of a "pci" device.
- * description: Product description of a "pci" device.
- * iommuGroup: IOMMU group number of a "pci" device. Would be None/null if
- host does not enable IOMMU support.
-
-
-### Sub-collection: VMs with the device assigned.
-**URI:** /plugins/kimchi/host/devices/*:name*/vmholders
-* **GET**: Retrieve a summarized list of all VMs holding the device.
-
-### Sub-resource: VM holder
-**URI:** /plugins/kimchi/host/devices/*:name*/vmholders/*:vm*
-* **GET**: Retrieve information of the VM which is holding the device
- * name: The name of the VM.
- * state: The power state of the VM. Could be "running" and "shutdown".
-
-
-### Collection: Host Packages Update
-
-**URI:** /plugins/kimchi/host/packagesupdate
-
-Contains the information and action of packages update in the host.
-
-**Methods:**
-
-* **GET**: Retrieves a list of all packages to be updated in the host:
-
-### Resource: Host Package Update
-
-**URI:** /plugins/kimchi/host/packagesupdate/*:name*
-
-Contains the information for a specific package to be updated.
-
-**Methods:**
-
-* **GET**: Retrieves a full description of a package:
- * package_name: The name of the package to be updated
- * arch: The architecture of the package
- * version: The new version of the package
- * repository: The repository name from where package will be downloaded
-
-### Collection: Host Repositories
-
-**URI:** /plugins/kimchi/host/repositories
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all repositories available
-* **POST**: Add a new repository
- * baseurl: URL to the repodata directory when "is_mirror" is false.
-Otherwise, it can be URL to the mirror system for YUM. Can be an
-http://, ftp:// or file:// URL.
- * repo_id *(optional)*: Unique YUM repository ID
- * config: A dictionary that contains specific data according to repository
- type.
- * repo_name *(optional)*: YUM Repository name
- * mirrorlist *(optional)*: Specifies a URL to a file containing a
- list of baseurls for YUM repository
- * dist: Distribution to DEB repository
- * comps *(optional)*: List of components to DEB repository
-
-### Resource: Repository
-
-**URI:** /plugins/kimchi/host/repositories/*:repo-id*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Repository
- * repo_id: Unique repository name for each repository, one word.
- * baseurl: URL to the repodata directory when "is_mirror" is false.
-Otherwise, it can be URL to the mirror system for YUM. Can be an
-http://, ftp:// or file:// URL.
- * enabled: True, when repository is enabled; False, otherwise
- * config: A dictionary that contains specific data according to repository
- type.
- * repo_name: Human-readable string describing the YUM repository.
- * mirrorlist: Specifies a URL to a file containing a list of baseurls
- for YUM repository
- * gpgcheck: True, to enable GPG signature verification; False, otherwise.
- * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
- repository.
- * dist: Distribution to DEB repository
- * comps: List of components to DEB repository
-
-* **DELETE**: Remove the Repository
-* **POST**: *See Repository Actions*
-* **PUT**: update the parameters of existing Repository
- * repo_id: Unique repository name for each repository, one word.
- * baseurl: URL to the repodata directory when "is_mirror" is false.
-Otherwise, it can be URL to the mirror system for YUM. Can be an
-http://, ftp:// or file:// URL.
- * config: A dictionary that contains specific data according to repository
- type.
- * repo_name: Human-readable string describing the YUM repository.
- * mirrorlist: Specifies a URL to a file containing a list of baseurls
- for YUM repository
- * gpgcheck: True, to enable GPG signature verification; False, otherwise.
- * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
- repository.
- * dist: Distribution to DEB repository
- * comps: List of components to DEB repository
-
-**Actions (POST):**
-
-* enable: Enable the Repository as package source
-* disable: Disable the Repository as package source
-
-### Collection: Peers
-
-**URI:** /plugins/kimchi/peers
-
-**Methods:**
-
-* **GET**: Return the list of Kimchi peers in the same network
- (It uses openSLP for discovering)
diff --git a/plugins/kimchi/docs/Makefile.am b/plugins/kimchi/docs/Makefile.am
deleted file mode 100644
index 679aa18..0000000
--- a/plugins/kimchi/docs/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-docdir = $(datadir)/kimchi/doc
-
-dist_doc_DATA = \
- API.md \
- README.md \
- README-federation.md \
- kimchi-guest.png \
- kimchi-templates.png \
- $(NULL)
diff --git a/plugins/kimchi/docs/README-federation.md b/plugins/kimchi/docs/README-federation.md
deleted file mode 100644
index c184f4f..0000000
--- a/plugins/kimchi/docs/README-federation.md
+++ /dev/null
@@ -1,60 +0,0 @@
-Kimchi Project - Federation Feature
-===================================
-
-Federation feature is a Kimchi mechanism to discover Wok peers in the same
-network. It uses openSLP tool (http://www.openslp.org/) to register and find Wok
-servers.
-
-By default this feature is disabled on Wok as it is not critical for KVM
-virtualization and requires additional software installation.
-
-To enable it, do the following:
-
-1. Install openslp and openslp-server rpm packages,
- or install slpd and slptool deb packages.
-
-2. openSLP uses port 427 (UDP) and port 427 (TCP) so make sure to open those
- ports in your firewall configuration
-
- For system using firewalld, do:
- sudo firewall-cmd --permanent --add-port=427/udp
- sudo firewall-cmd --permanent --add-port=427/tcp
- sudo firewall-cmd --reload
-
- For openSUSE systems, do:
- sudo /sbin/SuSEfirewall2 open EXT TCP 427
- sudo /sbin/SuSEfirewall2 open EXT UDP 427
-
- For system using iptables, do:
- sudo iptables -A INPUT -p tcp --dport 427 -j ACCEPT
- sudo iptables -A INPUT -p udp --dport 427 -j ACCEPT
-
-3. In addition to the openSLP ports, you also need to allow multicast in the
- firewall configuration
-
- For system using firewalld, do:
- sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s <subnet> -j ACCEPT
-
- For openSUSE systems, do:
- Add the subnet to the trusted networks listed on FW_TRUSTED_NETS in
- /etc/sysconfig/SuSEfirewall2 file.
- Make sure to restart /sbin/SuSEfirewall2 after modifying /etc/sysconfig/SuSEfirewall2
-
- For system using iptables, do:
- sudo iptables -A INPUT -s <subnet> -j ACCEPT
-
-4. Start slpd service and make sure it is up while running Wok
- sudo service slpd start
-
-5. Enable federation on Wok by editing the /etc/wok/wok.conf file:
-
- federation = on
-
-6. Then start Wok service
- sudo service wokd start
-
-The Wok server will be registered on openSLP on server starting up and will
-be found by other Wok peers (with federation feature enabled) in the same
-network.
-
-Enjoy!
diff --git a/plugins/kimchi/docs/README.md b/plugins/kimchi/docs/README.md
deleted file mode 100644
index f400333..0000000
--- a/plugins/kimchi/docs/README.md
+++ /dev/null
@@ -1,247 +0,0 @@
-Kimchi Project
-==============
-
-Kimchi is an HTML5 based management tool for KVM. It is designed to make it as
-easy as possible to get started with KVM and create your first guest.
-
-Kimchi runs as a Wok plugin. Wok runs as a daemon on the hypervisor host.
-
-Kimchi manages KVM guests through libvirt. The management interface is accessed
-over the web using a browser that supports HTML5.
-
-Browser Support
-===============
-Desktop Browser Support:
------------------------
-* **Internet Explorer:** IE9+
-* **Chrome:** Current-1 version
-* **Firefox:** Current-1 version Firefox 24ESR
-* **Safari:** Current-1 version
-* **Opera:** Current-1 version
-
-Mobile Browser Support:
------------------------
-* **Safari iOS:** Current-1 version
-* **Android Browser** Current-1 version
-
-Current-1 version denotes that we support the current stable version of the
-browser and the version that preceded it. For example, if the current version of
-a browser is 24.x, we support the 24.x and 23.x versions.This does not mean that
-kimchi cannot be used in other browsers, however, functionality and appearance
-may be diminished and we may not be able to provide support for any problems you
-find.
-
-Hypervisor Distro Support
-=========================
-
-Kimchi and Wok might run on any GNU/Linux distribution that meets the conditions
-described on the 'Getting Started' section below.
-
-The Kimchi community makes an effort to test it with the latest versions of
-Fedora, RHEL, OpenSuSe, and Ubuntu.
-
-Getting Started
-===============
-
-Install Dependencies
---------------------
-
-**For fedora and RHEL:**
-
- $ sudo yum install gcc make autoconf automake gettext-devel git \
- python-cherrypy python-cheetah libvirt-python \
- libvirt libvirt-daemon-config-network python-imaging \
- PyPAM m2crypto python-jsonschema rpm-build \
- qemu-kvm python-psutil python-ethtool sos \
- python-ipaddr python-ldap python-lxml nfs-utils \
- iscsi-initiator-utils libxslt pyparted nginx \
- python-libguestfs libguestfs-tools python-websockify \
- novnc spice-html5 python-configobj
-
- # If using RHEL, install the following additional packages:
- $ sudo yum install python-unittest2 python-ordereddict
-
- # Restart libvirt to allow configuration changes to take effect
- $ sudo service libvirtd restart
-
- Packages version requirement:
- python-psutil >= 0.6.0
-
- # These dependencies are only required if you want to run the tests:
- $ sudo yum install pyflakes python-pep8 python-requests
-
-*Note for RHEL users*: Some of the above packages are located in the Red Hat
-EPEL repositories. See
-[this FAQ](http://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F)
-for more information on how to configure your system to access this repository.
-
-And for RHEL7 systems, you also need to subscribe to the "RHEL Server Optional"
-channel at RHN Classic or Red Hat Satellite.
-
-**For debian:**
-
- $ sudo apt-get install gcc make autoconf automake gettext git \
- python-cherrypy3 python-cheetah python-libvirt \
- libvirt-bin python-imaging python-configobj \
- python-pam python-m2crypto python-jsonschema \
- qemu-kvm libtool python-psutil python-ethtool \
- sosreport python-ipaddr python-ldap \
- python-lxml nfs-common open-iscsi lvm2 xsltproc \
- python-parted nginx python-guestfs libguestfs-tools \
- websockify novnc spice-html5
-
- Packages version requirement:
- python-jsonschema >= 1.3.0
- python-psutil >= 0.6.0
-
- # These dependencies are only required if you want to run the tests:
- $ sudo apt-get install pep8 pyflakes python-requests
-
-**For openSUSE:**
-
- $ sudo zypper install gcc make autoconf automake gettext-tools git \
- python-CherryPy python-Cheetah libvirt-python \
- libvirt libvirt-daemon-config-network python-pam \
- python-imaging python-M2Crypto python-jsonschema \
- rpm-build kvm python-psutil python-ethtool \
- python-ipaddr python-ldap python-lxml nfs-client \
- open-iscsi libxslt-tools python-xml python-parted \
- nginx python-libguestfs python-configobj \
- guestfs-tools python-websockify novnc
-
- Packages version requirement:
- python-psutil >= 0.6.0
-
- # These dependencies are only required if you want to run the tests:
- $ sudo zypper install python-pyflakes python-pep8 python-requests
-
-*Note for openSUSE users*: Some of the above packages are located in different
-openSUSE repositories. See
-[this FAQ](http://download.opensuse.org/repositories/home:GRNET:synnefo/) for
-python-parted; and
-[this FAQ](http://download.opensuse.org/repositories/systemsmanagement:/spacewalk/)
-for python-ethtool to get the correct repository based on your openSUSE version. And
-[this FAQ](http://en.opensuse.org/SDB:Add_package_repositories) for more
-information on how configure your system to access this repository.
-
-Build and Install
------------------
-
- Wok:
- $ ./autogen.sh --system
-
- $ make
- $ sudo make install # Optional if running from the source tree
-
-
- Kimchi:
- $ cd plugins/kimchi
-
- For openSUSE 13.1:
- $ ./autogen.sh --with-spice-html5
-
- Otherwise:
- $ ./autogen.sh --system
-
- $ make
- $ sudo make install # Optional if running from the source tree
-
-Run
----
-
- $ sudo wokd --host=0.0.0.0
-
-If you cannot access Wok, take a look at these 2 points:
-
-1. Firewall
-Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
-
- For system using firewalld, do:
- sudo firewall-cmd --add-port=8000/tcp --permanent
- sudo firewall-cmd --add-port=8001/tcp --permanent
- sudo firewall-cmd --add-port=64667/tcp --permanent
- sudo firewall-cmd --reload
-
- For openSUSE systems, do:
- sudo /sbin/SuSEfirewall2 open EXT TCP 8000
- sudo /sbin/SuSEfirewall2 open EXT TCP 8001
- sudo /sbin/SuSEfirewall2 open EXT TCP 64667
-
- For system using iptables, do:
- sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
- sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
- sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
-
- Don't forget to correctly save the rules.
-
-
-2. SELinux
-Allow httpd_t context for Wok web server:
-
- semanage permissive -a httpd_t
-
-
-Test
-----
-
- $ cd plugins/kimchi
- $ make check-local # check for i18n and formatting errors
- $ sudo make check
-
-After all tests are executed, a summary will be displayed containing any
-errors/failures which might have occurred.
-
-Usage
------
-
-Connect your browser to https://localhost:8001. You should see a screen like:
-
-
-
-Wok uses PAM to authenticate users so you can log in with the same username
-and password that you would use to log in to the machine itself. Once logged in
-you will see a screen like:
-
-
-
-This shows you the list of running guests including a live screenshot of
-the guest session. You can use the action buttons to shutdown the guests
-or connect to the display in a new window.
-
-To create a new guest, click on the "+" button in the upper right corner.
-In Kimchi, all guest creation is done through templates.
-
-You can view or modify templates by clicking on the Templates link in the
-top navigation bar.
-
-The template screen looks like:
-
-
-
-From this view, you can change the parameters of a template or create a
-new template using the "+" button in the upper right corner.
-
-To create a template, you need an ISO on your host or using remote one.
-If you are willing to use your own ISO, please copy it to out of box storage
-pool (default path is: /var/lib/kimchi/isos).
-
-Known Issues
-------------
-
-1. When you are using NFS as storage pool, check the nfs export path permission
-is configured as:
- (1) export path need to be squashed as kvm gid and libvirt uid:
- /my_export_path *(all_squash,anongid=<kvm-gid>, anonuid=<libvirt-uid>,rw,sync)
- So that root user can create volume with right user/group.
- (2) Chown of export path as libvirt user, group as kvm group,
- In order to make sure all mapped user can get into the mount point.
-
-Participating
--------------
-
-All patches are sent through our mailing list hosted by oVirt. More
-information can be found at:
-
-https://github.com/kimchi-project/kimchi/wiki/Communications
-
-Patches should be sent using git-send-email to kimchi-devel at ovirt.org.
diff --git a/plugins/kimchi/docs/kimchi-guest.png b/plugins/kimchi/docs/kimchi-guest.png
deleted file mode 100644
index 2ec8fea930b71c0e03a40700d79c4bbb63bf54e6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 192281
zcmX_H1ymftwj_bz?yd>$?gV#t3&Gvpli=>|PJ+7ym&M%|cXwapFM03%;c$Rucc!QN
zcHLWbYr>QiB$43p;UOR(kff!=R3IQA*&rZ3mcc at UU+F)bp$GqfHj<STgLr%Y%55)6
z0KWp~Af at dL0fB(={`~<WJrfuFB8-c)yg1A%93~nE6l}>L_!S5|7jZ2YQF~ikQ#%(3
zQ72PF7gG~bcS{!wQb}ofCC#76I1mt|5Yl48Y97lctL~X<bE|;Mi5Ao0aqOe%I7)c(
zd{WM8x&i#K)IRhAX`k}27-_kyLW^`tt9Ys~mj2IAVn*x(iwJI*g=M8bq|WI_?pD)U
zPBZsomhjwCJ|zcHZ=Jt*ePQLhUvu6cKN){qo0+}Z9f{iaWar>eR#yIb4uTT?F^^9c
zh$;e07Why~Q&er6k)KZ<KlFLXBwmX?I6<LAx?~3Y?l_quZqP~Ht`*#W-h3xL!GDb?
zLz7P}GM38H>yZsutTCoxVEBS48p-06^q&)=f->bOd&{-!AgXC;X<>i;FkzKOg+e#^
z-+#-+$bYJYr>Em*GD|r>9VQH!OfNPvXiCCf4&`Ddt9)noVp{7}P7Y#)ULB9h%Mxg^
z*F%q3`7)LI{5XAA({0ha=JUyR<Zwq>DOu#hN$-LdELq<gi{<p^*UK3Hjlj51xb!3O
z8hB)VuL<h(1PiV;a#HgsAA+`97n46Nn;*Ag(Z7C2I*YxGBuEuGcg$B#txguNThH$R
zDh&{^|43cU&zGl&Fvw9<|HBj#g)8AGcj^b%C_3s05fJ9{JjwpXFR?QA!hph`W6|`M
zOh-RrKKJWW`87RsG=DsqK4kJ(+5~jg_rbwlJf)-S?s89?S{ZJO9Sbk))3ryw8mMS1
zqF<5Gq514|`|U%#>t>UKHHg%82cw#Cnr(6SDV6!%DAI{UU53Wc+rwg<BCs{<(>lhH
z-5;0-q+-!TPBhaw88(ATifdS02 at Rf}wNzT;coYRkfMr}51TN%~uDWA0Z$7{BuO*rN
zl)|Z(dpm#1<OS&L30~t`BMZie2H*BJsBQAdF0g at WU_49CFA;J16BFCoLbz=7`4cSJ
z)+lXlo}xQrospR+SUHhoi8s$uIDaWPK8xcp|FQPD*U7+KY at FD_$^NbrHBvGRVEr31
z0jd%N9Q$dGAG&h~w3=w&OtX!;K`Ze)U<yQ>Ap6-<+W?H$*5CRv at eu%4$gC1m)`K47
zg3h=R+5VaP#~7KbAP4AVZD7M6>i%&^g~_hxl((UJPhF|o!;#!PQ$k+KrUailIPhwY
zS*F<pq8j<5dCJ>pcLsClOJG>$h|iGhE-kF}3vH;bxZG_fN`yEa*X$dUqpZi={rzgp
z3~dAGZdAXP&wqACBWr)0W;zo_Lkm=<dfmhSRjk8VVIbMwXvxmD<aEGuQ-7R#zd|^#
zu7g{Z=z at Fd$Hi=X@%OX2 at 4nl(axgU_oJfEv-(q8wh%us;!kOb)!%=ioF0Q<4KkvMT
zR&x-uao#X8<#7o&sLkD>l2y#`D{h0W{1lWR_ahO|yXu8~?wBj?%!{9E)qz-FJ(L7W
zsx1;#<fQXzWRTm5CJ+_GP*fcWI9ht!+bmh9;Jjk*@Oz|5gtpWe_e%y5dqwZ?2yJ*L
zcwL-1zipjQjOJTBr`_oDWd*5=6S|ILA`gvkZCWB+4hK7*nWi||ypfYvMc<osbX`|<
z4i!s8>CWcRXzGt|>dRHi*&|fFY;%q3HUIQj7kwBNSLH5uC%X5$HvbE}=dNr!`3Rk;
zmF2Hp^Z8btq}s+enAMEApod)fBo-VkT at U5@+*#(?-cfU|g2SiXn^f7|cmNUwpBK^R
z3od77IGiGidgU8jH$=^EuDo^rer!zht(k89?%d`cKx$JReNEsv>vmP=?$T})E(WU7
z=*4A;!&za$A)2+2T#$m|IH<?pu_rWML at Df-3~}cv@;57~i{Eq|V`(s)R~IPu+pe8~
zXuZ(2m#d!^F*=9t#}9|M7IO9vQ}$I4 at r?RkQa$ENcn&AgzdfxI{rzSjS0j*+<KxWh
zJK!5;Ewq~TX+mHqqHe8#x0>dRB{E^0Cj_o{#ACmu^P;Ohitsjx;PIx5_w_QQ&6A4%
zm-QRS8Bu{2PFMtX>Vq=oC2;*USvrA|#c5}7wL^LzB*<nyZZerGjEKh?2u8f)s?PC?
z&0aiq3#E`4s?|~Ol72CU*xi^P+c!`&r53nRV{E-Jk!etb)ryv_Ee*|24Vs4rMyaZ)
z$eBIjKN0z}uKh}*_u2E)K;}(XRS<~wWHY}!xjuK^NkK6l`-S7VRn(%@tFV>t2nkzu
ze1JX?b*nU-Z}<q0ACuFy)ZTWv6(Q?!+MX17qOCx#E~ZQ#U9@;+Us+4I;zL58 at 1_%x
z9uSTkij+3^^SJo38^(UK%0MjkU;?c`V9kRkKsc__BSMnIGduXFB-?KJ<}6dzc)ewe
zk^6afNeBr5rxN$4I0IWw#&~)#y>Bp)NZ6+ulla1YbZa|pD`lr+zi$J%6yoQiihFec
zS1RFTr0eY67Eh)Nor#~B?s5id5tp=&`V6aGZT9@~b0EjAe4oL%NTJUX^l63Ea;SB}
z1mgT at pOeEZ;KO-Ndm^Oos7<%G79Q_suBnCmSXCulO&?FpQ|~T150~%Zqq(hF33B|x
zQGTJxy^d}s-k%J_A1Ypt638BK-sz1K{Ym9|QP1|=AnCJzz{gPF$>Fd*H-4RoF(iuJ
zdl`io at 7yAUraJ8Npa3U74+lb+A~nAClwf8=J|Du7TBnLTnW=VfcW^Rnv^~Fb>|y?l
zC~7vAE>4+{S6ds;pxZcEWzgB<dHU?VCY6dN;)8BSRCGxn5<du8Fe$;MIia5S$4<^!
z0~WHC$eYtVJ9gvp_Pn++Kf7i>a|rGXRIYVHsm`HZ_(D&>S(!g|-u<|rHLfh6M_v)e
zE{4ZU*+b;QZJx>fQ>~HjT+TnF^@)D7QP8}iE%(E)lXR6wqL4r%Jb(jgsP}O?MWJw3
zj6nzPit4v=jUb`t^Vc(9JACVWcKw))9^o*5wq6Js<<31 at PLmPt&C<(AffI=7U9^bx
z^x^oT3?BEJ%}CyIs&hsE%;8|(aO9Ry1O+?=xrOtM=g~&%*(=XoBbbcT#}m2qU!jB6
zJvEqVM=~F0aGKO{S;q`1$HLv$H(rziu#BN#*j{6aE1Im=<gr{0M=#ACMt{<{r0!<z
zua^k(R6n>9>zZwv9#ylt(rYD{u8_efXZ!r>cjJMH!WU077 at Eo8+z@Z)z8u}g)7|PF
zm at 8jzO$~}@bXuW#;W<7DqwhTbvgWmJx>J+07y8;C$ZGfl)kp}L6<paAwYGY-?YFuf
z55!3lFXfTuCmP)z&6Vr7VHaTvc-?%T`=efN&`At%<i1-p<|DKKuP9ZP3%dQ^OX!hg
zhTcY71^!F1r at K>G%+pp-Qy{ot at RKL#5);#p*(uGxPrdH8d406uVtkp^3fHfz049=g
zy%x0eWK&0AK;z45e?=>T6Wy?MVvEPC=fq`~;8~<3hb855|3RxZu>G6+AXI99AQV@$
zO!(BcH<AUK$a8jKVZSGGsN%6m7wJ3Kfvv0Wa0np)0wkzm0&;%s`zB_8Ac7Fif?t5y
z$Py?lRoY#PDM3(=ywvOgt=P#NQv7OunH7OTm5da+GS9$NAv53NOtUhfifq=)e&%b$
zShE(ub2+L?tq;QV_pfO6q?bQFPkhGBo}}4-X8JZH9g?`aRzMm+GT-De)2L51QWHi+
z^s5VC0ck;g%Dk~5imOG~`+ZVa%<>%9Z!(aQYs?KdFi?5c=ath96CFyKtiviH<0CI{
zHZ-J1WZRVBk|L^L$6E=uCdZG;D#{kfJ$^?aM?bP$ae2+qL`Orjbk?#eprEXbmL>;1
zGJLBLnqRt#U6>V&M;5sFwnN*Mr#_CSsjqld<-awj9mA%s?Q^Co`ThLhym0)~TBkwE
z2Gm=g3Dxe6QoNW37 at 09s^}2!RS=I at MCK6kJX#CN4hS(kBqXJ_vFk!duhAw{_b&&PU
zqUd_uYY2$!o|9xH&-1KO(p at M-#+4_zcU=3{94g%Zp+R=PW?Yu#X=5$*kGtoU!9?v8
zQO_e4vdKv8u2vZ9(_K_kix(e{|0m(r59?YtN1UOMpp at FHF~mQfca4ppbZi_hpqip@
zfYocBIQ_g6ooE{$ZG_!Ru<9@(Yt6Sv+&PqAl=DpbvJ0#!^QujFYJXD&1wiOc>*i0#
z=kfT(p60h+>2f%f(FYQ0b-zkV+QV>;CpKX?S^T@@unE}%w?kZ$mL|Yyqlg)i=josT
z;b)%hq@|6`iPDcr9X6XqW{GG*xGuV?zdeI-6o+$VI1snDw?w=OubJ3P-{eF^A$x<7
z3V#0%`y!hRF<GLRvr52L(7-qfOA0<EBvG)*jC|oL;!<v80^{GrgFKMuVMEAc=Q0DK
zD}=`(yT<jXk at 7);G*=uFhlI5clPvEkh6H|vXzddFAvI}_;X!Ibs at nPW@JY$TO9njE
zS_Z<aHLR}@+PBuQ`h5(`0L~Twp3ql}&5{|DTH?5Qi`A!?_VIb;l-0Awna1buKaqWF
z57|3#^0Lqevb<O%%VOmyMNv(pxIRHCOVt9j#`#LZOALInIvM at 2PFN+fJg^fa?ur~=
zg*?kt5@>aL6YgK(MD0HQ7^&h;Bh4Voa=a*5A!;Q}pgaY@)eq!evRSgaC6mHBKod{=
zrkKC#;hVVL|HFZJj2&lb)pMPpn{>5KBV&jsA1j}rU=G)_r#&ghXoK%knHkw_Z+Cme
zW;v})saZKLKc^>n!aXin5w~9=)W!5IVl!Xr7Ps46B1XInR%k|S8DVl6RU1x%$QM2;
zO0Y`djiA$W>C2oeDaM3QjBzU`%YGPDS`+U^-&^aCI+)qG)eF9CzXzJ(DiA*mj;>g|
z1$Zg)f`fyz1lOl7VuwryO;~Y_rHWJ at Iu!NwSM5k7t>ww%zV8gi-JGowOk6vpn~$AH
z$tu5kOT4_C`*ZE*_zQNNkF?PTF8Wg^>5^guL_4ikmOsl}<0jU2TQH|f5hR)#(j*<H
z7iTo7=N6RqcK}JOfh2RVqRwdpsFv-ggpri2^@2GH?Vk}wRDzuCZZl1dcPDVF=`-fJ
z08YEpfAxV(%oQBTw)>Sa(UZYM{G4M3tnecmE#vNE6(Zq!DeZUIq^oZ9?W?@3e6*U!
z7P{H0 at FT-X3r8GS<3;_Tg!OOQ6;(fnqHI-?dsO~B>UB5XpZKDQgev}tk4LXvT9L0D
zcOWd8EX_~saU{&AK2oBPrN`c$k|gOLy0=YWVG{{`31@*CgM?MT{u80>EG|SvuNIH>
zy(hNxVi7gC;vNY|TxKfH_vU<M`bY1}a=qWmkq_@}yoghXQoTSR9ArK=AUePLcKvp5
zK^n6jc$J$-KI)IhVV~ijDP(pG2&P_~&!fLjxSL?mv{8b^v&~ua<N>ZtNHw)@r!bA6
zLfckWu!z;)6aPe(FSEvi^1kZ;(@QFK at aho1oZ8_1iezb<YmT2_V*T&~bqgcbdQ?F)
zW@%`<5p;H-RpD>9Oi$hN^5adwN1RWudivxcEUS?h*ZA%LKNUF>SUFx$u;69BU}z3H
zIeNGfpbkX!e&o9orPk~LQvom+N8K{U%cpO_{P(*^XiS0P=<Mj at hsq@z?Dc!TdfXUP
z5XMNYgMNw_xw6(L?r?ISb-?xC6_0oUi at Y(Em56?$zU at o5690cEh-ID$BgGI$!@|N+
zQ&(43QJFr=7Zy30=wapxvS&>zH0bo>juy4GWjLO%po7X3fFo7LL=#8L-e+;x_}c1n
zNDlcY=zUa%X7;6(m1e80u7s|$%8ALzoQiF<SPYj#c at 2~aL(Jymgf_rp at B1@)gO1F#
zcJCQ*@ni#Bqx<<ATrQc8B(s=};u--p#QrxXya8NJyOlw3r3 at AhlEg*&sWiYLKU=Ci
zn#G5+;5wy~AX7AGR_9$22 at V*rfB at bi=w|QQK}}UKUeM`cDsy2$%~x$VJI7k;&$A?J
zCzb=a(}(Qf;aPKNP{MxXv|kg`*2Y6ZLV^<hnj`32`ulet7!=7wgKMqkXop8eXc!rj
z6(b%NBl1Hl_1mUrXT^B480!a4tjZ&8cjvDsgWYh%Y;L{3X|++rA~1rl9O_FpO1)wd
zA82bhSRqouX6?CUKf(6>N}MngamkgF#YSH+0Fa#>!1hXB$=!&fe6tCKZ;U96im8G3
zDHO2%d~ERc89RavJP-3#29n0c6sD&7TAh9Z8C>>eleyi0L1%o0Gx9!rY^uD>;}V;c
z=!<!hoF_gbF|~x~jxbCaw$Azt=;ClLoKZ|jviS*Hm)wT9=)r~|zYx1listC`v_}>p
z+noAh8Qb)}v=@}!!@r9)&mp~$<k%xuD;4XTRrVEt2zJAPt@;dmv-<7HDP=0&()}XI
zY*L;xgiHsA6#cbT+p3S)P{L*K@!Q;s$x-{>Z7V{szch{y7aPaG#AaaC{Vk3Z7MJ at 1
zB2mSn0*~u#ut!c2M~^uOX#a+1h}(#(nj2aYuCzp1i$={Sq1+=5!yyN{C8FoOV(s8<
zq!KpQ$w?HSDdu^8B8h0(SROgp77NM&WQ{%Vh38D~C%2`ouyrlea>gF`G%x7j_))oG
zTVP(qEO4>x?!>Ktdb}fvbQ)&}(2`B1!8JE{M|Pl_eWj6KZRNP>I3hk1BokNtu7sN}
zirnQS@=>Tu3!X at vdSt-WriYYt8rqbnxl;asLrLEpm&b>?UDg<vXcLBP04z-O*I+5*
zey4{4sNfQzTLo<|LUjPn{oV)^gly4!gOMd^f>?r6zIn!dk;T4jIJWP*b|bd9ni=1t
zvyF<1dOp(ZT-w$8X~Q|P&~djO6i%Ymw>|g#bfWtE`RsaycieE~S?Ds&zH>C_4Fp3;
z?2c|K5Dwc=tXj8%FN#_GyS$uolHn|!KpwT2`)FogSq~G{<?cbGCz2)5P%E|aF9mDI
z00PAy{Ac9VuEjeL`THKYL<>pd=fkEVj=|9WdLg*p`G6hWc0XbBG8FZ9))W`=g<g~@
zyEjZ=;i3)n&B&Tl3;=STLNXwKebDFcH2LCe-x=^!Wiaxi#ee6%$_AoH8ab`6sgpO%
z)c=j=?TYfM?k&CRSLa(|$u!_{l_^JN+6~vGi}ah%;ipJtL?YHi9%u6!k4x`J!JBI2
z3cMLNq$oAo{@oP+pWf%~IWDc1A)x+kN4vJu5<TDBhR^6>K7V`N^z`VA=E~jxO>ciw
znVw$-1^si4PHS0*(UJ2sM~1O7U<(kjI0SuzV~VR9(%jb!Vpd<iM&r)Kq(aMb)LgZT
zm#?LF)13Aih7iO4C}Jzu{`({8R{jQ;JzNy|;1>(0zE=`P({2FWog8kkMMV?BW6(N|
ztycRNd0S(~ztrp*O`ND+#LjE$GPstlNdtH*ZMbD)<v$*OPyPe9*O`-{1gdqXi*A_n
z!mB)o%-DV={@xJ;oH~o~GJY;=ieBW?eh?GG_pUVatqHH>q+X`ol=Wx+ZP2{a{um0&
z)c~;NG(Ccck~1eq(6sqzU?Nt(Hqp7`o^HH4dkfg9H$LaS+V5}RfT>FYE>K&|omS0}
zO>aBj22 at 8<uGV1seRiKB4icEDO{Y57AsX#gd-D6wmDTn8VMzW?9EbuOPFOJ9JYm34
zpUj{;APhsKc0gO)Q0)KqdULYmTmm96K3J-wT5Y?xAYLqY$fUm}e#JQt6hy$W+3l(F
zPpAv&gL6qv at xPbNW+3i$9P0Pkw{};VYY<YH(>rTB|H5frms{q!S#__<v!zP7O0u^K
zVmtFNr4tyoq2=P5zVGVB^gMpJUoVMcJPiXr2)_9_ at UF)21VPHuJ&bAE<sZ#P;OU~H
z4Mo{crSaiL_pY=!zZa%UHpzCYt+w}kN^={Ror;x4&H+Z^;>jNb!nIYWzD_X0VOJ^E
zdFZF(>{sjtPPK=&R4f!L%hY&Yo4w;R4NcsCaJQYr$R?vmHpQ*pbl^L={A10&)8!`I
zba7(#kj-XGC}x4gy{KueN!daTXI*rVP-{5VhrcrOl;OXxk;%i^{ZM1qF0eTSV)i!d
zf+G+61C3j+XM5xy5&(|<rWB8}nk1W%x+J@?jL=n{B8A{M#!DFAssWG~-X5tFx=cz%
z<NM2nEQAlmq*?whK!Bp18+W7Ks-Vi=-XicD=p*ZYh#RQEa-)|RRrw*G(oMm0{7gfr
zqap8ghs93xY%A#R#IrqJ<$OFs(Cp>#snfssC)4YzcjoL^4+?oTVfqp2oIS3&e0C3+
zKEKTTw=vxaEAHP-K^amTw6TN~cVd2{awCpx43B<dyaX!hIeBDRpf89N^5kb*yqt}v
z)qd6#hPZ~2b*o4ahh~)TNeV?Yq%94vg62>tGmau$3I-dQPFJlIOT)QZ`4T-m!MOR!
z- at mIypOBmgEg0=v at 4yP?xQ=nk9hGutx|M-4_DHRtDWpDh(x#cl6;OzNquM#f^fBPR
z#^`1a(LqGc`4bIs%yrsO&Ta!<mBUsaMqYq$@$TXepHFny5tsgN?o95hx8Bo-Hwvoj
z&JzN?U`z<};Lk>IlL&C+-aTTfJBnMs8r?W|+zTbfMZ|<w6Qxy`p at r7zKU7KYI!o^n
z3pbIDtnQ((Dlg>ai4`v5RL0%?rs%i6#j4^MG|xF?l)_AqpAl1~n at A>RzSH(A$go)-
zNA5>_VgCoyVDU1p{6w-e+O6t17*^*yk at 7(bcn+$_1L+lYV8c-(VFJZFcGf5crcI7)
zg^am7vizXD;AcmD68uT2Id$fQo04+{@BiGt>f>NxkZA+?Z9Pnnd7kn{Ab$`*>?N2(
z?8N5Z4DuUDwl!J~7HxS>C;scTPDGE-8)V>XOJ4Q5=l{^@-_aeFL!daltRY=%8!@9O
zVBEA&ZK1mf-y0i-5km#rlXX_oV0LrRyR1*t4iHXw81AyNdsv!~UVk8B6lkrtO>zW<
zSOFo+fT+P<idRR|UL8Ij?$aC%fi*jKZL(QPC#H`qY<%#9;&377-&pa1wMy{gFKZ(=
zN7 at qd`srL}ydk8sfpKKVL8pHF?i`}&@1<K`2&Ngh5HarISl^B9aQr*@V at m91tH<6a
zs?srI)8HBYTPOEVmV+*%n@<ZDQT^vNPO=y-$KpAL`Zf9)b&PMUMW*RW?&enuZy|=~
z^aYgMKM4FCaA8s`lA{D-&Jl5=F|_2GAE1Z19<@$qLwM_O4ZPiRGSbtX>WWTx9Atj)
zrA_NJisIEqA+bL(Z!||V_clJ9Dca>el?mk<Y{VfU4Fnd>XkVcX+gtTnXLHMd<k`(W
z{+c!PIW5Czd2wIgLl_u1^}~I8iDH_R-M^b_>4B}4H_0%M9pU8MBH-o!(um3j@?D&o
z9Ub_}OMvYMgE`qC3kNUmo1j>o;F{=Wp3MGU3xx{g6)R*}jq{!J`>e0q8x)>{_-`gf
z^_+&j^ck^0fQ2EUhgbKOtKqW4)e^3O)ShM5WYfGvaa?F9;jWzXM+!}!L%JZ}Zg3(Q
zkdGw*mBaCq7z3*1LmTz=iY_6e2%MF_?s(%;MH~MN<M%m5cdzK_FuZ1;uSty%pY>Yr
z64hnVBltKW*}ugdZze|d1s%?={Z=EI_lVlc$_kgqX@^l)`OL?GjEQNntFQptVLPZG
z>}Gr+EltQ at P?FFQ3K9l6 at xO@32;OZE+cD>Bv!f)Mr>it~{4pa{59t1{BP2YxvoqSw
z7q*Rd6+6?iOxq0$#dRh_MjdZ2x(}Bz_M4e?6aB8M$#|$#*%sQqy$t-(amTS{7!kI|
z>1Kc};9cW3L$T)g>2V`(8z-pM at hWD;Lr<{XXyWWUd&pguJjCSuo1PQ5(8HEikJ9$1
zDMtVGWotOBcdD`o6l5_hK261|;COku-479Zh7(3*HtZ2gtQ|CC({o$eU2GIpRi$uW
zd!+MOKUZ7eB)e08WS*Jo+613RR1Ub#^S(^5aBSYcx8}d$hUJ$sCuooC*Dcv>uFK2I
zU(uj}cF)B|CLaB_pnpOA>s&sUXoElqYBI{Is-pbF=NGN4U}{r8kBH0sBZ`1aMMvj}
zgr=arzTT78`CkaU5mFg!uK)GCR#?z|<Sr{OHyKT3nI0yGYWeVlL8V}Fce2!6IZ`a2
zad$@qB_ktKT2b*OVQBCZ4)_MeLR{(*d}x!524l&9J(1hoe{c6P%Ju8asx+;Z6<SSy
z5LMna7l<?8SGUP at h?~t5*bkP7!5UZ7BLEyrfB$(x!KTn3d%r=51=mYok|Gn{<*ZL>
z0g{oq)=hS8D~-EPF$x{EZ?Dru^m@$>6ScC=T0@#fE|^#vWfP`YLAKgssw8Env;vQ(
zI(9KCL9UES at MWGtzsdh~WkY=h2f2}}I-Y3Fvs|$o8XEXIJm28J-3bbb=tBGTj<yv}
z><FwYk-UthXy_q#O7-2h1*a#?py5>{HzFJ0_$SOF_%UgQk}z8u5}$HTGO75AcjyRw
z;4ZBw6D0^Bfl>)sl}-&?Hu>peEGfuU53sb~7C>VCM-~k+jYLG%FgDdK60Mba>tWkw
z?c6~kbPAY1p-t%$x4$oOx?MXzD%F+j)4tz7I8?YyYqjUgwPoeyk-(JAc%$pXXN)lY
zkTikA?Q9gvcVa_E$sB0SahXo;71Ul$BSPi-yk$jBXVXwI at SVf7<`}=4RWOYDBY;xw
zGi-PQ)T)eQx*`{eRiRMFe=d;Hpx3N#&A_$oo@?4J7*4KHsVD9#kCbd$Q&bxdrZA2d
z!W9D}_3&)oIvyQmS{+IKV$jL7tsIGLiJLcOsMykf7C5ROyWC4n^bK{D`jV at P3R|PI
z<HTFSrXVAlr`flZP1S4i*oAj5ek#RV&CSVujQV$BRFGmS+^<|z6H=~|!s143Ay}z1
z>d_PFGC99>5qB2E at pRl>q;|YrLWy$+(s1smz{KC&Ln(A=|MLPEYV+vg&+jRWqeyq$
z3ciSpS;%lFa=)l$8qpJC5(o1V)z%b;HDOnp%(E0+7;$PukW&1Vc-IU>PL7jYe%GDx
zDt@)gXR2^5;~;OCKOJ{ip&fN;JS<a>Wx+37%hwbq8K8>Z`(Z)-A=s<d0#RSlNy|Vl
z#HzYlBxlE477xoxLE&yIR*PjdNq!iGH0zU5t{x&|uX?;_EmmO<Hxo7xsK`tz at Akfk
zs753+jTve5TOG%fO?;W{j=9hDCIh&L!PDWa68(~FJv>k%85Ofiyo_PI&B1d;vcFer
zu>iGU6~IBMZHJq{ZOfz8gp_a$t>k?30>Gd=5 at Gd*fZ8%-5^1y%1X)PZ{jO_Ubl0`>
z>QbTWe{XR=$*qO44VKNjAS12&dkFRm>kDoge;}hF&YvD$86gtmsjen%gNA4q{dDF?
zhk{VM2JJ2L%$@`q9IE1}!l}4{KJpb|76k&9FvYi1o~<PrQt~5#&?e|xv5GRL`aU0Y
z>^<u?%9#H|{)5`|{eYM*x*0F38SjjK*=fdhAfxYrYzq*fjRt!E;qMek{itz%(~~$&
zE|@tyw-F6=(5szYU+p5c(U4ZGZC%VcUw4vTms)K_r;wW_R4Zg({t6*<y!l8hjOy|f
z0RG^i3;u$uG-X0i8d^Se&ozJT5`FYGSQAy20sm9S8a)gudfUfhb=haVq_Hu%!xyv#
z5*$c9HFLCh{Pxfha}EMaH~hpY#d80^Ehg554cIO>b;vxkq&7=CitA8;D^Q;OxqzJ2
zm-Vmf2EUb+^@Tu=3vZS#Dpj~cYqF9qA;6?AsGm(2I_;S>M{~_HVJQp>KInej%%Vo#
zd?8&~Mp;{Xs3_%I_&MnB<p9B0-5+7Fa-m~AE(o%bk(GT<O(Q8xC8edIstP<oJkEPy
zHB&GV#mJ9k<^v at 3#Yx at 7Rf*6`7z~MzL&&)@ZZJDLyTh!qB>3*iG^>(p#Qwz*$u&HP
zYIoU1qNFXYfv{}a$pA~WFq2%ZJ%2Beq1;+Wo- at Jv5G)2kjnU=c14Yd1f{el37?wR~
z+X^x{pA4}kiF{Znhe`IgNa<phOq)u0aWN%0-<{W)j$kL#Ym2C>V}VyFI2gL)X|Bp?
z)pdczevN<4V;iZ5d8atTZfnJPV)qqvzCYprdM$Y+Jgc+Kt&k`F=hXV+!CE`t{faXR
zc(8j%WmS|JW5Z1U_IaP6igb$Ck|3&?4$^}?o=GCP+=GYPS6oX at WF5(ubZBy+1y{Ot
zbvhD}9%dWYzdmewoBTc~WxtbC*F&vEcbZL%#UB(b?c(G|80*JR6lA44!W6CLaf25d
z<x!z#=jK at ao;@nt&UnGf*TYndpBSciVq)S2IG?|(a at dS|p~tOI!WVg+HGBkAiJizb
zT9GN=yxt{$%*wFm>3?|O!+s~hRd;t305VQp+O{(z;`u7*vZJef1=30mGS&82HkZvA
z6H5}*O{cxAC8lJB5>{FiT(2m%ZL!_o)Ub=xn&`MuA`VzZT<xL7 at 1gw@U^Sm!sg|xn
zj^yUdyp+Y&bV^&m!NGxvgL6G%@EQ+x@^n0o*`tdq=gBUCZ9g8T4GYvXG~JE1KI>Eo
zL%9u<*bxo*W$`ja at C?-8cF_8L%|E*ldYD)liera5ZNd;{PqwM{XLPvm at Nk{>8Xaq}
zo(E23fre82#8hc=Tdj7R>GQL*7q?aZS<}-hdJ7Ct;_q<}dpV^x&8KR(prfjxG0=}=
zFe;9tulDd*<^N)x?S00BkB@&>cFE;kVQOanGuJkDN at oU>$Ac_!fXtLY&O(dV1r5L`
zKn!pW%}2$sT~D7`8)~xgRFc_+UXx6}rG;JvG5bwANWestMt|?0*V$7yO-&*Cfg{G<
z*slA#VYd;i0f9>fgV!q at ubYGJ7{8kWk)}H8aH*1+LKT|IjwdVdat&tkID-Qikwh>v
z41>yPLEoLlYL=Q(F7?NJI)K<aax8<ZAknBN5H6B{3wh!?mBknu9CDO#Qs04YWSMGe
zYRpbMQsB3LoyZno833ykB-JKE=vLO&2>XYg#D=&|<2?J!CWEN&>cGw6%q4$}7`ZTR
z at I%K0SH~ri*=TBazIeplF%;ALbk%f1=ZcYcH+9 at HL<_w>XiWH?S{oSO985iLzz7}O
zJY2r;j-DKSePk{u2wkQg`Xh%En)1DbA{cOdXjt-FMw8|KhU=iE66Z5!90~RvaOn~l
zoSwW2nAfz~ML9(G^VsPoG{a^q)l@`YZcXYS;JUEbRU&6<f1%Ceo4k@=(7}NE(D~5M
zge&01?!NBJ1 at 7U3ODxRR_#i{6s&DPh&sQU!J8_b!eC~`o)&r4vy<qr(?@H4ACM_=h
z30wp3gws`S<VP at WJsnq>uQWTFu;L+eZ$L11K0DcUJeuu|XCWxTvI>E1U|_R=kSthL
z2KRY`lGDK9a18Fg;#A5yI<hDVKAPkm>ypQ9th%r7mKnTQ8IFQYacC)ePH-LPbuNd~
zJrn<wp}vqRTduljd=4v2aD8ZV-?AOe7yXWPmNUht4#~i`L2EeQdMAgI_I2|51v9o|
z>L5deb}2++*}p!xmP{t{r%q3;_FGmto at UtFPlV#iw&6PZbpR%r4-Ip3&vyac&o&Of
zvcrCCzO*Wx*cA`UUk~fx$fhaCn>ZX6r8r#;QL%a7*${hdd@!ofGUQhTDt!XSM4ql@
z3Zs7W-LiGdUb?kbqYYjHmEzu?vdS%ce-Ht<R$g(Lk+)f{4}(PEk2QFETF~=8ZJ^hx
z{=tk0794k|gdX8E^&CGTVAF4a=}=*1CGwB_{QMphI8SgKr?l*6dwU$@g~0a4X4rS6
zVJPy)(Wn+PyB?`UvIJe%(<1;Ib=#5uZM~XvwgJp!7)wQZY~zcKZi@<`zs$z;64|#{
z&<k?=k340ecX8NxtKZBiJF{4z%L++qx-po)wAa){^@Yni;A<M=bAp=<b#!LAq5;v3
zQB{Wr&6&x<`LQNZhL^Qia_3VC*GAS3L at 6BtBixd<M$$9Xf2 at uWfNq6BaJh;(f|=fD
zEnxfM!Bhbrw*x7O&&7utEqbnForo|v9q968Kqu&|O}oJgOBs^|JbK2~1M=bF;pXdc
zKJ6wuA{}dNdaW*s82+9hoNrPKmHOIXHJ(Bu^80WiO}SRhFI~HqB4!}LS5;MvuVu_v
zJqSz};0#e$eKvO5v_39PmDR at rAnXl55e(h;JRN7HGXB?}AQNo;KHW&X6zA(U7hYF)
ziyajW`wJFW6WRk?V57Itt&&^tgLxMBt2SqJ0?6|^`+)g#sFSI^_gd~ttT2`Ss5D*5
z<!D*NMLBLwbMIO>d)BFRJ#cljQNX?$gGS0ta*1((T4m_-7v;z&UU0iLt>?-bP>(2_
z<@<90H<Z1O6H1PLI*|%#*bz@<ez3X{ZO#?>pnB4(wxCw0v6ef!x2&pTIR1<5!<l>M
z2ol#ymps?%tQA9A<3iDC&AJ~5jMji_evJwpb=<aEu;HaA_jO=E0$i#?c7>u*Xo2UF
zD%0WPmoHzyNmF2Ue%>gOMovBp#ff1=r`5&MP<etnT&w!~2Z-Nl;b85r2E0q$dLv!f
zF#d4~3zx=>C9nzgeWG7L_v>dZF1%x-X>3gyYIG9}BttkQk;Z$@BRqT0Y`D9XTND1C
zKkm6Wr*9|gT6SgtQ%$qguN9gP3!Px!qs)dDJcjrU$s3-a`v97YEOdG5Eny5lM?i&k
z23byfS_FzC4W0u{6Eb&3wI8MX^NztRZ%sS81#bo#@9L&Jjri!iSSdCWsaQyhI7<L2
zDPnI=YSg$|sjdRIQfa1fX{mL7EsY2PB(;j8Xbw3F(2;j`cAhoUX6<j<J781g_{5jw
z_@!TN1DuyFOHMT|hC><~8FX!RC3O_UD-!en{w4e|SElKHfZu?`Wn1#i4)}+%g7sgy
z0}5WPNT|?liUtR7$?E=D`~9~y-}_afaWk`&o4rA{%FX-E)=-DF0y$qNXslaHbmNZU
z*>(R2$bh21oYovL25tnMPfO}Is)Cd^)HxTnXKgRCi5eYakz8~<d)99wimxD_)|TK3
z=bZ0*UO7>+Ya4MP#2Yy=6D32--VAJ6yE}B<Z36R9;y7htx5}Xb!ZcDK<YWS>jIn&6
zW!Taxmm{#14c}NtZu10G=o`iP9WvTfm2e`;G|Xi&Zzn at Y15=!xlha5WyJ_8z4-ASs
z??4O&YBdcFqo%Yk746vNL=C at A%F8rIPz<D{r466<?s`_vk{jxB{zFw`DEnMoXwZxi
z-~BmzqiJ&4{Ana_4}f>pK0GY*j^doQ%VM6MJmB;XT=2{|9(DWp?Q#76VVhtMa|wFl
zxMyy?GxGZxO3P)k<lq42#CZA66ri(*MpCfHz#ztX>Me7kmdb8p at 69)9Qh8J_ac^@y
z3veK5uz8DhUh`+!d}9ymZ^L)NjwAw6g@}a|sn1fB38(V{*S(*?+9mSw3&}Dsn+#24
z?SU2T?@7TpPA!=!Tx}b;HdJvkVO-n$k8bx-O!cE$Xv5UZ at Jie=1(DF05;Td(HMTIo
z+E5Gs)%2_(_ka--*5{iNq1}C<Hy)wqO%$-QL<dCj;zK|_Z4bU{bR`VwkHEnQCIgW8
z^T!Cia#tQV!n51X+>Q54jgKq;rx)BOiDSm=<!nGB?&~X%qVI;c{xshN at s40T+mUS5
z^bw at 6%{%e3sl2YV5dI+GdNVjZfsF(eBVRXz={#*+gPRM$UZ&rMa)huWuk2Y~R0`9|
zO1Jn-HmzZ=FJ8t;H(RM^f_3Kfq}G7YrSO|#ywMS#=$`_uUE%P|e8^TZG?WUNgE9Wk
z+e955 at 2P?R`J&g`6*jQ0ZuntbEBO-=0UjZPp|S%a90KdIAyL2q0aFjkk*=%%@~UUG
zu0|ij2)SI5BY`aQz~m0*Hf3$!FIqL+t^RGB8kmm+d}?76If}sAL>0Ll!7MOTyxX_m
z^Y~c@=uG2-u_gm4A3V41+i5G~_5Or8SSZN!dpgu}Uv*vaI<6?3v5aI%OiG$6kc`P9
zHkOQtIy;H}@gM5u&?_f-3_Ns62V-~;0 at L5>>ecr`D4Kf<mJrZ=@2eniJ1f$Di(v5Z
z5fU141029$3R5c1^A!`7Lx_3cd;O4U+};4DF$AQ{&%AbC8)r957F~xCUKek!`5ezZ
zJg{Kbd|cV4V_TKDrMv!w&D8O*g&Y!i(%@>wD?=lW`H-l|Kau<)Kr4rV60c56c_C=p
zE(A?>f;6(ReX;R_k$X>MSguWMz#9CwpnO3GkMT&VC2>_kgjD7AoTdev?t at TfM0cKp
z_EUDZWYY%xoa>a%=O8!?N{4<dO=jOG7ci?)SrjB0q#v>3Kyq4(js`k;?LW_sgJ}-9
z006#Yv!3gm`g?k$*RF*EIO6iUP;;$$P=LuA6CvB%`m?pQw*rIze60-}+kZgGFZI$l
z$2dm7t?g-bh$`o=z5xGuAcjKMy>I-`&Yh`M04H=%kConVS=q)fX)5KX^N>O6AmBN_
z!nuAwq%|k{obBc<1B-+_e|+B!4xCcqlbnf<50av~8duC4r`E89B--+F$9|Hj_Gmgs
zL<D1NC=9VjZtRE3zgIHgG^|vbb5?$~e#l(M7goBPpNy1|?5y+HE2o$}5v=oR2z_mt
zH`TBxDUqYR59%A^WrIc9QWni&{X8|M9s2M<*Pf<6;>AEMEw-%!T1?Aqi6+Jq*dc>M
zNwhe(l?hHoNCccp>gsbxA9a%Z!97aA%l-Pq&QL<j!&XGgX(JH);KTCra?eA$7QF;2
zlu6x^Mjly`47eT?CXcgF&wl4xUqwYlH=pT8jKF at vO!qa<chxx4V=F9 at SRnoA$O^0&
zf<M_ at Da)Tt5Ry1#qNCplrYPV>o{k4tbBdFr95SmboH<m83PS%k-EV2kb!9AU3=4=S
zr9NLRfMcVzHn}b05;S^E at tyu}F><dn{?|a at u&1AAq%^p(nyz`a71WZ%&AIZ{3*&il
z_qI9jfO_3{x3NN3d@)YZbaD5GH?l?>v<Hv;c*CPtEvR663ttRQBju(|=}=#3`rlLj
z7Eb5jJ5PD%X{`RQ&skvB-*AY?0WOWMTPA#?!5#i=Fokz%rqk*$CFi=YH=5jlEIo9?
zJkDQJ12J+Wl{r{rPkm{NR!Jhm_N3+&Or{_~1wRC$9bVfj8k~u$e7*8>R+Ak)qTk6r
z{$qiwA at 2?;EWGh|H#Zw#<3CQKY|&`VBddiePF>`nk5i;(=+^k0Tl{=ts$;G4Ta8R=
zH-;bvfbfCxt$U1wElm!493!2I(ZX-Mwp^ov`_a|>7b$6y44SyIp$7X%EqoPO=htGE
zU{Y9WT3Qh<1DyYoLGWs}IPYIQPWX4I+vnVw)M>x7FtC-SR at d;b5oiaTXEp9R<jF)3
zV$0_7_m4G2GBhN at Bl2(&FhR%3c4cpuMI>1F%>t+Sv at zw63m=KZZwTCx6BO}87Xl~#
zcrsn~)i2Gab2qYb{}#;T-K`^J$)%f}*lThZ6wbo1u2GObzNTelWGv5WrUQ3C&wcj!
z2p#*-Olr0F#xr8JZLHnldSfrQ2jb-@!vNbiM{^P2E7{yHqzzG3Cjabq)t|4_m$Xs+
z1Q{`Mpny)8;!;b-<?HkvK8!A>)h(&x3TRcKoZQ1 at S?(d$xvBqqRcl?(5d}Ukf7hSy
ziWjURIcAD*FHSWlJpU4VL at C(!46?n-qY$DK72M&D4w!G9w3 at kU-EB)bE&c1$Ww}J6
zOcS)t9VE`8E4XmSK at ENes10?zQ2n3YwpB1wTV$#!N(T0t_&@ZLxV1%!kxv~p`}G^0
zfyTTS?d*<BvZ|1m8RsGlHY(jq3=yeEdK`@wE$X2Yjb2s&54$Il&fAt?zTl|5V}^Ej
z%yrR6V!!Wb{1q&+BS_fu`4PNZ7wxDYmD<vF>BejWL at 5)B{<M0PY_l&T<6AXIgsTM2
zXZUclEN@`)hz&^?g`v0JMHzB5iM;DS1hyqKXM@%Uqt0#1m28012azIgjsM8M4-O6b
z?9Q62qdJWeF2#|AV8c*L_nR%326nV at 1AYB1XR`cA2~g0!iCf6nZIz?Ez;$NajSX07
zYUVzzDmYn>$f0w*f)M>>GCE at 08}+GzQ3SYClt}KPpUA>(D3xfR6vnPGT3ploD|=UZ
z>kFfXZRM`;ajE+8e>LE(1k<+UwDGkira*Y(QpH3i0;VrA*k}u6?f7NY8AmK*!T|P?
zzdrZBd4Xi7&4`GiwG28Y4p_J1y3}U`N`m!#HGu<R;mV~N`*eo?RX!u!N-~zHmO=zM
zoV}^OM^ZXr*qqK2m at iTry+9{~iD;BR{_wM22UM(t!t>J`ce%k5hA=??u?@N0ZMW2G
zp<lq?UM|d{#NSfKybbZ&ZjC!S-k{XOZ_?T!h`CywDzr}empB)3c6((<c6r4>3zjhh
zqbHWJAC!j4BdMx`V<<T;5nUFtOKpN}I)%#*RifLU1ytrT9G(${3oYxhic3Q`VTh!_
z53(sG2gzucYtXTn60bsIPr19`>7ytZeGx at J+_d?o8d971S at +*YB@^7tYz!-9v#dc4
zjLZ`g-u}=V`h?i`aT2;sSJ9{-rt5qy;VIm8QVGcrJ6x4;v5ilX-e7pz2AXQGmbN2v
z;|G1aWYVOuLwIdAixIfQ5U$QA;n1DODkdDC*!aTmpR{IVFzc3;wyH0=m*A1bi)FSv
z&Nz=ZTuVALIH+!4W4a<X&+SNF;Ji9v1V??2px^p6^-JEzXh-&!6nc}F0VM8dS>8d^
zn=6_$B{3_DUt-h3G(nP(kk(YSjtbbFo{po>PYlz%|N6>gf{aNnEpTrnh-}`NCg}@G
z-L*p<0vUqpScGnSm}}=8iBXN at 6<uz*pOe4CG8<WcnRDJ#(KpD^C6SQiUM^~Or$O4)
zJ^Y3Vm?5()!p#!M2;P_dz0wRnaed+2*?T<nPt${~VN#neI%~Z?t_K{Co*d?WE^;!~
z?x7~Hb7UYmf58&<N_O^mgOs9D`5Z~PTl8D2Egi{F3N_dxTM}&2lfNXCAZ&efpuLqK
zY>N{#G#IcE47#1LDg5K~Da|GsY{liw06)WLne^_h3PdHzV5V3d<#l_Xw|6P=nI6gz
zch3(s;=P6P=ZKaNIOHnI2AxQbDC)D$R9}y4T&)*z(&~lmcZ&M!r=^#tuU3l*hbxD=
zi9n1TuRLeQYGZEke;5Cf<xipP%dHTaS>i9!_byNo91PQJ;Ib0ByTyeFp)8s^J$^0O
z at 8$rOV3%APd2W+mu(pW(jv>J|QY#H%e8`8BlSS0X$>J9D!{K_Y!i+yY6N<YUW5Xax
zsHWV}NOM~h44O at Iv(*K%5n37PhPH(N2}W#$yR6kdVk4$mAm0uVYi-eE>T6&yYRnfT
zP$6`m9Ei0P1k{s!hz(zwH5c8g3^Jwxj{rO at A=U>&JD>zpUoECISCeg=bzWlr5CV-f
zuZQrl_4aajYWwMOJw4a9qy=I>3zcT2@#bQSlPo&2p~;1ayyf(VM?Hl1ct7z^asfhj
zMb{qKKqj9Kid&xZnzE%*pO~b=)v^=26CIyDvgNdT3*y8ak2s39Id$i(ZxzuEFuThW
z-H$DGIWI(Rw}#-TraL at rruA~4R(kpz*OT2a$X+DDtnC(+0WL3eGdy<#Xo+8j(R^Mz
zf(YlU0_kE1x(e6F_PKB(NeL`EKszv_?PpSck5{xB>ZZ-- at uEB+6a;R27asG-gCS3U
zuY}(zL<8~R5`Oo~I(y&vqV4&g1mT-sW?&qb^{<;>10lIf`TL9fy+hL8IFikAG_Q8r
zbUm*A)abdr at gbfn_aRXsZQZo(UA8%gY%gPTy?Vp3RSLuljcWng2nZfPI4IlT$7OaB
z16r at sSlW4x@2}ImF7wK(hMYhVbe`9(m(LrArtDs1oms5$(w!LqEWnNVN*AjjXramT
zb|mEbDIEWm#h+qAk1hJ`2|zw9YvkiTt)$RqP29<EOueeYxWHeZs#%2xcyZ=pwpM3&
zdz#*qdpy=9<S0c*i8=>7 at U7*_#zjE6zOP5<%LJLub at s6m`w?#oE+1Hb;;07MotL~@
z1Q^p<)2?5cL#S{xVncxsdBWDBtY!(96!fxa&Y0RvJ+8K0s8H!*D+34|17D{bh91Zo
zv#f6~o<p at pDW`*}r#~CFXb at Vg%_BJKA;{AB2$2)l!PN^(0*BSH`-sZKTTr2t+jeyt
zgMj&Z6-b7q(gVQ6;}Gt~AX8g9E*s})nFjiWk7{`<S^61TqY?z7i$ASZshg(Ed(SCn
z&VvC`*!?>R^zTY8nV=)<&%OJ7lCH1-St;|n(JU?!z|wp;RxsH%AnHq+9C{4k-G~(<
zaHll_2Z8y!Fr)0IsZ_ND9mpyDr3pzZoTtS>8M98u<{10+l->S#`SC44?eA_)qwO)L
z{qf?Dwlb#*<fI6s%e!IulhT#DaYv97pOftt(O=GJq;Jxh2K;Xy+*Z14O~keSVfy8e
zv3B_QY at jJ`P)w>ZjagNBPtERs8p)_4J);1rd4#u|_VehJI_mqkaoxLBr)g32cv7-J
zbQuUy81b*+p=#p0Yt}8{-`bB9TawGZRh2Fv=NsV^1q7{mqqI{de*Gv-TDYLv_}6sr
z9*}K*y*iYg;H*G9<nx$`LgnpdzMti}mv*kYhsXbLOQBr$*^Zg;|Bt7id){Uc&0;0;
z5!58#-$>S?N>N*XnIZr00DfkN)>vtxVckYdlaFC%d+16$MKeG9s08!hBg7U1vO!cY
zeaTEB+3exI*Zr4tCd>B5{~wWQO=#hdsNOlwRN?)TNWlUBJ9 at uH;kjFG7fZGzZ_P8c
zBbaJJbanstFeK>zIu_f-X_6^i_dD<6saD}D4cFcO#)Leceh9<AHH)0_;c*h+Z@>om
zsJ8*#`@au&8-5*#>@^c^NdG>MvL0f^;})>_|HIh;j|b&fW=tKUFTCFlIotoA6B&}z
zOzz(Qs_muqg==O at 2voNsq1bs}bgGflU|@Z_rjet+-l%)qQe_LQqM>%_x1<=eC$+uj
z9Pq_Ej#_e4WSvf7Swjb|>D8{P0ts{)7fMdo1ncq^#*#^ay4S6a-aUIjj3-uNJ4J`u
z_LjTAF$SQW;v(m~yg%BF>krUXQ-_}$sV$1j&#H5CE(zeX4m#BXz#Lh4v)sQc(FxMd
z+jz`42gnIs!wKtyvK9>f`wlpCCy{U}KXsQ(OQ9<Yd`U8Bvg6FM>14Qrq5>*3a>d)U
z2^b#hb3s->RGaQ_;&q`wMp_}n-D6=Qw*G<BNL2kyP}-Bi(iNNMxig|puh5w31*0t3
zSGnGT)Pm$O5&5%ckPIyt>b5I`6IzCb8p1LC`{ohU60~2mFoonsOi6SvQ)T+kl2)(m
zfNs$%YK<~2T>Ao^=<JwN=v`)NHRk1971`=SHu1{DUgj(#Vf8j0!v9UTJ%RCnMX7M_
zWyAe>;O|F7x<7b{B|n;jt%);2`1Ti+!Z`kB#$^8K?8GMsj6>-s=`j4C7l7nzyvbnw
zhun=IK_}wxk-`j9tFFaZY8%~s#DY(UqK-RA?%Ron(8Apz!>pgRn;LdJLq+TpFotx}
zH#=k2iQYW>X9&vkwT(U!)~tIFa?pz4?p|c;LvIFY(^Z$6Re!%!dA^BmQc{P%;1A3T
zf%wWWo-6Rlq*XAPhomDi<|=l?^8&);w}eVl?0lqdE`+gCv}>=F%nai1$cl3ccuXsf
zpcx at YW`(wEK|)YuaLzrN*KG^yGK5Swif<r1cuJDpCh}A+AW1fXD^Jp_C;-9+m=2zy
z-jz8TME=wx8J}Yk`|nNniUW#3^X=TW<)4`$e^L6vg6+Nlf1iEhgBLE1En3}PU^tGe
zYE4P5tb(L2{n~AEkS#e=Yx}<~X+C;05iiU!ws~!S5`|Lkg;k>828Cdaf8iU6hc4Vt
zV^#da{u#uW>b!m3Y{s$C6g5Ed<_hcQ+fV1g0(aR_K)GE8LKarD1AOA at 2)9lyrcRW3
zc&=&NxFNb?cEoyXcBiz19oRDd5)em4{DTkqv`^9A2MGb7*ryn?h-~Z=@TqE|x5Qp2
z61gF)fOB~xH%kIyDY(sqvIJev_niKD6{3Gr)NwP7Z>x!`Bh-?P6*B~}_w5<f&27{M
zac$NfX21SK`Ayd8;X<-_BX=nRjhOiZOzGT1XXjX-Zrkb4Yh;pW^}79yIxdDj8IM%2
zgU^}2t+X0?9ZvLBJT_Z+9xks>=j**ZCgKt<8)yPpMn{-WhqNE=AnBOhh7}%~y5Y|~
z)?b at na#{WS_ia`lurKVX<Oj6du;b_rg3k at u5Kvrb5D7Rw3i0|;5%SW1Z7}8-Z+qcb
zX+N;_sVSWr%tw3JQx<g`VIt|9SYw5~{?KTB9T!C$&gMq^i|GHTdh58T+BIAlq>&Ek
z?(UNA2I-KLl1_n<p}V_b07<1&8mXa66d1Ze>2CPe{?6I&e$V_fxn`~3^W67!-MwD>
zt<Ra_i=92PgHP&7H6#NJ!0xru)0GBW%Vc(2HH0h?iR1}WN0NAq7<GHzAhnJYLfxBH
zB&z(RNQ27t20ydG(pr5uD&~0daP$1PxDVT`w at V0P^;_Ghfvw(xX6hcoJFP2#|AO3m
zU>IIte#7cw`W3f5De3>9YX8z)7EkU*pPE%rFWuSKd<@RFJ~X>};&PCXNnUmnt%z5J
z at sasM*b1;(6wI{D{xk{|RJ`z;yiTeBQ3sZUmld@%A25o`%YuvV(<9N0pbZnb;rlq9
zzz$S<-5*%a$gY!t2$_^!2v}VQB;ea{4C1#~Q+a~ql5bylOy;xuySHRY7A~!Dc3zQR
z&-&r+^kd$ysIVZSqlzIRA!)LNwc&N&oOLCMKZ>nBfRTpsxe0qj1^Pz}*as_S`cF6N
z_3|#uncV&aKdjHa_;9;`_6hUubMJ1CiLU!ku1zAa#WRceD=_US=OVD5tlxI;VM5I%
z+Q=k2Zb6UD=!KMp!4Wd0{z#MEZj8H#vhKY^*MoOQv!}4~y{(2~?*TMyiO5u2>v!3a
ze3JgelgByXTY+t;bY;ikOOoH&uq1u3Bs_j4C_w^|6esrkPHB*~o4=0jFL{4uDf}6&
zs2_2={ooB9yW!}gdp&B{Vl10WFh6M=F5bSoUV`!#uKKh)^`?JHfuo;?s55TUEY<C5
zh;gH7ZG7OII?@V at BD|6-0Qp6*Jf@`=>G0vF3HUU_n_wuhKb%Pu`koCk=*)(GJHm7=
zbyUN21|dN<fBYpa+~&;kjKkLXLWi=x+z0Nw2_Y)-&JF93>|)z}K4j=b#I7lW{NIhY
z?S%tD=704uKJ!4~+TcR<LgZ~Q_X&vk;IY9+ at 5b*}{Z2c45~XT-Pe0uxe#PIFA(Qy-
z7&KO1E!AX-Cc6aW93wWWC<rpVf4w8+As9O0CBRoDy~xzFEIdH4Zs*7-iJ5;ZM&7db
zvD424Yb-NEOAy%sKT*1xbPIMu9%|gy;@;g)EJY$!&KyUQX!V-H_oI8n$kJZ@>CX3{
znPTp?ijBJ;_%{=MvqxwUZ~%$^&WFddRR+VAW>TUFmAacrB<k5yg!Sggz0Kza<VAyx
z+6!K=hYBU*Y&@OmD7|mMt_ouRQk}tj!g+CnewPmHS6=$HHkKGkHr%o;{qszvt^4)A
zi3M5^pP({gA|L%8$0{&ft5kqOOC at qicbteyMAf&O$Ne8%=c%aA$8P69v#0&vJ#Lqk
z{kCRYDHF&vNMeulBF4SOnrDX3<@4%OBMa7U0TALH_jQq=oR&SST>>dt)Hz*iFJJ4E
zKtDFsa#}%Ch(%r2B6!*nfQGp&ZZRpBOJQ<+_952-d&Laz^$@bX;uRD%d*<#=Hn*96
zHtvsJWaz4yTgl7JU<dLf8`r(FPm;$&PpwopTLH^cOV4(2b86EB3^P}c_X5!Pza1<{
zHvZ76Go{+!`aS`Y7<KIwTnEa&^M=?4Q@^HNyCUcU?nx6QJOcA at nWY?wy$W`w(X;hY
zb)U%PEx?DT2^+$UTEi@%Mw*lTY;1g;r}s{II%M%%-lWlV*HmGD$vn at RMGbz@i5oq2
zO4m4|Nd#EN at Lf{|<71JBB1EK}HLIHU^3~`2l^cuMX-=)p^Avff_hC+TA>BGmh@`=P
zU)dC}B1O(4LS&Z5y)NK?W!jBR9DhIwN&KF2zxU0?R0xcb#K<$cQlOU|jLza at qbANV
z`Kz1(wf(^bqmZwnj~jeL*HP#^qSC3Sp+)*f)__3F>aX}OQf|^yvF*4>Q^o|T^*dC{
z({<CvGcU!E$m5*oQos1VjSlBTY*(U<vmv_;O|DP0M|zC!hqJZg8+8sKikG!VX4V~g
z7Rbolzcow(#=J}dQiDm~lFozuSi7IjX-yzG?a~Vz2s9Y&+sm1g?`EY|D--?54~}_s
zv+8CI!CTWCh7DD5H5dz@>LNkV9~WZ2Z>tMH=kTc|QR=#qOr_##S={79AE`uaP7h^k
zw+6j`$oj`u_c*zRe40JE`}@aLd}2##QBa at CFQsSV_jQ?x5W*6E%VEoRYuNDtq^`Lp
zccP1_bH%1Z(it$##*&Y!-88335$bJoKpivmRNwB_*oDz2?hMb(N|{M5KD9))g#P6P
zAMB>L9+=+ at U1X{a?KHkk-icjsR-?SzLGG^E98AFROL!d&5+HYbG>kJK%$oe&YHJzu
z!m8(Xy|(+o=FNw4<$jAr0cav|Sb~V_=8z_I;VLTB9TwcreVM>un0-$yq6SYPKyRh6
zE<VU<0$!rE=s5E|%<ZsDJhc%s(z%k>dLmBMuN at m;b0|Jr%yCEeU$4cUP}pbtVeRkQ
zVQ=y~=VU_!r@#22Yv=pw57{06>1XJBVIKt|?usyR#htphBkeZLOT+u!FACXjEo;8#
z|DN)vM;4{%=F<RgyDyuN#Y`PThB)Rwy)t{hB0Rx+8>+b8IwO#G_V6bw8xtzj!-Ez8
zld at saFQaTBJBH6kD<s<b$<VQ><SNkZaY0KT5H`|*G59wpvP&_-_d0vt{e}*m>Uo+*
z*xm^@(ElsN*CKZ(Qo3wD)#oMw6oeFKK5AIYyn6~+$ctEKl>HPt)RPSlgG#G!QY19<
zEuL4|kJAkaH4)@Zjph1<euG4ka7QkGgm7`j^{#MEu&sTJTg9J*fZuzzn+qGv9HwC}
zZO at olMOJP{&sOX3QAAzg<(?-4*&PwL8?mHRfor05`DW-%Ttj-X1QJI3eVH#JRHnn0
znWhn6=CXTT+g>geTZE?D?OB#=onZ>EjSTIUeo5Z>RDPOOdGpz6>FviMXGe8^{t2sa
ziKZ0?lX-{twSHpLv+aMRTZD$&XAXK?jN=Kvb8Nj`Z<#1dKaw~^L&!XmI7WL)Ig+T#
z4IaG?0vrr$zt?N{a|}xdD=qfo&t%pst>Tum$7r at oFnqvISsPZvzjHV{rL9^tl(8 at l
zT+M1mf;uc=6PWqmDwB6P5It`8M{bt)zp7}B at q^@qQfa&o8J}_+Tr=-0E$}6>B{zWj
zPt^=mHjB}6LDMrOqnE!vtpD*Wx2RC&KDZJ(%T_h$C6mM=D)>wdRYYfd!vXzXn-f21
z7Li+15dR{4z^t2K9?bXBf>Tb;hh`8LyUw7u>^5|9tB8WbB8y*sFUS}q!1MTcnS+{R
zMh8}AfW}G+BeW%&M^q3ryY!T|7~z!k{A%eGn)r)m+}@7<;tylHy;H;*`Z*O=;qA5l
z&ChN#a4(~X&s2z at ozBZWqZ-u2E?ad_`_SEck;p#uAbDkG(k<?`Cq8?&HSai#$wo7R
z5vQ$`F+Rv;mLKEzd}CN;*o^mm>R7JrW6}lR^5-qb+hrrgLa-B4x7W<9 at QqNSRG^pS
z_|xy;;Xwhhi_L at EOG!~~(21$r3Xy_Emh0(#<;7{Z<D23y2MlF?8O at Z?VT;D$mX(%h
zN2SP<xY(W+B1Qr+uV$b1Z#|m*H+v=AN3NSNO^x1B^Sjoo?()<6O30x1O9PkL!_}&i
zLCwI6sQ`jznt%e9DPI9MvSueYQ90PlRqQN2+He^bT<Y1L#2ij-6zyupPnH?5$qZ)L
zACUK%8akjmkJ62keBR-yz&;MmoD5`IY(V6i$cb&_d=GC$G<KZmlp9c!i%GL2{)Zzu
zS>O5Q^2xE;*?3HStVMmwW41rXiGvOy>FBv><!@J4{76Qf%jfi-c-Zyl;p at -GXyV^j
zo?usILQl!gm+V3a$w%=mE?x%$4Gbq}x#}%PH{N6Y$mT*To}1T*-<dGvS{~3o-R)%N
z@=1D;N}T3Ky5Eecegx~r)+JFa9;kkt2?#uxvbB$B5|x2trar|9lK|UTG%1)Iw9LIi
zDv^4Jiu0q8w7jCx4Gt1XjUL1<Pa5m<BQyrQEvCn`(~J=m5(CZ>eoseGlvrUSQm+4`
z!1Z#>QZo11<mdRhX-7O%ww7IC-LDHw^cgMm+T(p?O*zAz2vso3N9Uwp4FY{6zY03^
zm4i)!z&>FW#yqGoS3DY91T0|0?!;n^&rIF*=Y-_`^D*}ZDDWO4wJvajqyYrf?~t2~
zjU_ir2-Zn{+(yx2E7(O<UIFQI>T?VS_c_xEb@=W`?(-xliP~Z{hB%VsIWDsk|J_nn
z!$d*lAW70+fm}t-eNN|Ut;({i`Tjx)re+t|b^F>L+sEo;dSuJV&~jaW=K)yGbsBsK
zTrxIdaAM7G8)~gAx66&z>!2Os=MW=9Lf at z@FLfmGHAS4e(|MMqGHk2)*;|Xyv1_O+
zSy!j#6%E4&(<7(27NG(sS4c~J0?%RPDzNje%i at +7!`_;nGnp;<PObs4W6dQp?Uoft
zox8Q4qq&gym^a7dX$SUk2%QgQh(~h_69kMdUB`HwQpSR{9LS0u{t8I50X1jtPgnDv
z)(W*E<}+KF2XC+)=6HtBJM6l?-|=;$+-glfe)cIKAowzDKHKElKJ^n$YuyraOkl;1
zhu{%Bz3f_DsQZ*Ms<1{kb)J&_2LH=vU&`MH7ncH&Mh6(FEo>XlnGMH7AAfsSjtK3K
zWs at LLkAg5YgXf7=KNkqb&u at 39FegHZAA(V+q;l-TiV~%ZP~;?N6J>I_uTK6z8ksNW
zGjysCJhN}+FZEW*JOcSW;z4>GRiAA}3Z7n`oyNuEciOExYMn3Ic~;K<3VdJl*I;xQ
z4!p?=qx_qBkQIU9$Nj0e!%vI=<4a!894TLR at 8rW#{K+BymlP1O_`v$j{6sG=Qka6z
z_X#ul6-AifzIi}^`MmmzO~;<P{nNbqNyCiF^W0TumotQ{()l<LK>8)08-o_1ONd3!
z<jIlhlE3MR|8Im`AUJf}5Kno(nEROhJ=@7OLA>Y$9C;H4>G8AzloTKggt3+-e8Gu!
zqf95)GV$K3lWY>JDwF0_<XRgH3yNBsr;kgQjn1=)f(@9{-hn-hdp9}8F$Lg{tel-&
z4230gXX5)-<`ZxbyA@{?%F}5M%?;gD+Hy5)dmOTFYh{TSjWkPuU|=^nH{#B#&uwFa
z{GqD1i%wMCuN;~Y$Hwee0(f#2T2NN6%QBBX1qN7+UhkR++2YscUS%F(_Aog`J=uCz
zkva7q*s3NucdA=2Ic*$3kI>%lL8c3MR>KaURhj~Pr516)B<sCok->E14-0pdFH(l6
zt8cc<t97-Gw(vX`I- at G}*elxI-Tu$RmrTme at MSn|?!bIzqR3pyf#vzW&C2bb>sXGH
zsvZ8nKXY5S=Kis?Rn5n@*tR4TN|-Z+^vO~8!A0z!xMz#B6(d=av=s?oHrcRxoXKQA
zNlzz5+py2p$$w*ob<Q82X2-pJ==345_HP%}2mS}&yyxFP_*Y!pVkF7NU{E&sYeGM_
zbWM&195{58-&jsKx-&pKd-B4MB=4BEw;|c9-&U at Qj{@|j4^)?IgHDcI&F`1IU7cM<
zTjs-`hi4Sbgbp~C4!%is)U*hNJGl<GJg_a1IjlHEH*|%cpuN9r|5N+uobYMuKalAZ
zC2pyj<_x^J^XrSKwY62Z)qF9Vf4J9)>V3X>i_T!Z*pJglx+dz*dmI4baRF5$PhAKq
zEgi5kTCU9eZXh+)Jn|H1hr6A*(wrOHR<SOt4d)pD9A^_4lXKbZeA#%^P0%-O=wpAr
zx at fW%a8vGlsWT at u+YX~{Sb4wn4cplj9VVEo)lyG5cKxQ4>9XVKdGxw$0bfmW*Iso6
z|DN_g at yzy{Fb=K%pvKM#+Gp94?B<wpr=sD)X?@eM%I5=wg}@t%vu at e;y8Fk<v-O{1
zubQK=o-aSW^1G|T4rMYoh0{DUrNTm>G>GI-XjuWjg{|)HT3FSPF)g{QI92<FgpyS<
zT9v&}z3+hgv1DBnxzA|=x{hA(EU&Nlg|}TyUh{O!<hDE?7+T&D;ruq#)<3?%0~7lN
z0K>dX{6dbCHx2(pp9MdTSNr4``B*DBk0g^ISP?`Zp-n#Q!)LWWApY7cIh(I>h+7K0
zE)agoi#<K1MVeYWuM9;3Q9b1O<37rqw(u}g{3A?)>=Wj-ui(BdWx*OoywJmGV62b#
zRwun at k;jpfDi`rVD)8yXA+M*Nak@{J$lT_aiMtmYW_N$m589(>^kF}@payWdg&h7P
zct<qvr}+4w#917z{BFqM(q}4<7r9h at tD=eKV at Z|-7of)t)$$GV=aUa=?;(m6Ef#bf
z%BRuA<?AS!tFQ6f$yEQjv=(U$ZrQJv<6)E*4H#OSQe^^7f~fvf${D>n=-qoX8rq0O
z*u>Q8eA^!IKlwx9agZfa_`}P^d?7L^)~K>ni^SH(bbBaDpH>Xf!9A-PC(<mRYXzqj
z=q?fHjgU(TUiCb8(S;xe-kqaxgZd2V?N1ak1(Bt3)-wwH;fJ1kE>6|#$iT#i!B<`O
zH#fG|H?M;C=rnW?yRj>d_b?HxjcyjgBvR- at _dX@6=g?mI6T{i-2fF6iaF<C4x~KHr
zi1~KQ;MJ0lrQh(}UG&HrqRx?n9rW<9=T7#w{HDhqgyfdG(oYXGm;6EIm4fr%o$o08
zKX!0AUo{^=c2T;-`0j;k5S%+|FJMc)P7Zf|qD?DQu+=0WY%fXXxl*P2+>-XGk;S@$
z%hAd4z0lGkq>ceVu|@nAZ`f+ab(s2y&#gc{)^H&jTwyWkR>VnObg|@v__Eh(ru%Qx
z#LbyMjcyx0l8IA~>o*I5=W^h~u>P~)#;N{0yMpKh4?@Y-)3?j_m5uJlJKsO_{!G6e
zG?0u=47dR21#H6$Z|0|-ZMd2SsZQPTmrVuW2exeln0T%loE^QckxP4h)>9x(!4!D6
zcl%Q at VJPfKakGlbEb1WOS$_F)ny>ZXjHGoN#k`Lw;L+|-!jk=YtEt%ikSH*Yt>>!t
zG&U5M$-aQ9rnoYOEa1GL)p1eB7o^1$a5>25z8LsKZkO*tf4vAo0YBzRu2V at qiyiy@
zWiau1No_qJGVe8*>_XjA#O#OJL4xqRA3ec0v*m at lQEu0FnOkKSJz=UY0XS2gyhMSI
z1us9!C+|40*6f7x+{dMb?|K4)*T7F}bzU~20iXY<x87x%4{CC@!?V3 at KW*d+#IOTD
ziRFPFi-dh^m2dZ79^V)|uQ&Q`4$iv`0-?IZf+wO?(C$1>N%ek}$A9D5k<M7n!h@%I
ze{Q~#{Qov%s-^@<rNQ^&H0&9puQWu+Kt{wgomAxx_3K<zDuHu2YPvCo6b)7Q{x at CR
za2heqB9nM6Ryn1g81 at -OX^HP at pr>NkTEvBo+VV7`@Nlfn#Lk0a4(_k2F=Ot?+gSy|
zf)lAvXY{@nWhE9iD^x%Db$mk`hpQ4OCFuJRS+4u!_Zsvog~0gW{zl&s6-;Hh<>xsK
z1olgq32Aj5(cnU5(%$n4LLzG%FiT~^_<`3u#u%C`a&0)KJFH)r!^;0!&FT-+Y0N?w
zy!5OPyCY5BQRViQzKV0ddi_7e6$i?WKKypjb>w0F%?j~7XF=@Ex!AVP+5GWT{^cDr
zbqp;~Wk))19{7~Q&o`yBU-b(P&OL=z<8OS1qkA##ov6jM-dFf{6`vGUbcO7{uT?g-
zyBDX)G<Te5X at 7gTm^g`_#c($cbS>Svxu$|<DewamU26U=uH}}Hq(E=9KQ-z5t7#8(
ziF0B6RKa|Q-rRb!wxm__mc{%3GO^o&ZG1LAnMF=^QUDRje?N3{Tlh=^4)i<^C?!bK
zbN4NLLKBpu`)}3<cz!RqDGVJ=XRCLD at ea6SbVb+NXsH0jrv$O`apWR+p(xl9nl~~z
zS6mZ^aU}m00F=mTG!>R#4g%x3LfDOVQ&3<&M*=XlNXoHGKg`;yk65QxpBzzXmf+~<
zh*->*TWpHVP4eGa$T~t<$9SNy*y{fBkMP+5K5hgJcr9`d1UG&AQpRoDG&kIU;Z9y`
zT>Yi1i$XRMi^45!*i_^nOJKc at kWLwIyg-sFlJYb27iI@JMev$yo;i#_8ncw3f!&dq
z-`EkjJYPs8`xvsz_%MRg-*>71rJB&teyDtg%|}<)A)to|4zBw|h?dVkew5hiUG?0%
zYI<%cHHK_cGvPXDe}08K#i6WOq1jkIg&wsZ$N1n%l&|0Xzr+AM*L{)-d1LGtX1T!q
z;of0bNzUf?Xn0oRzF?Kg+vF)C?$4L-3pV4HQAt;@!sKEOW5*Kv7>~B)C>%`0<MFtE
zE~#JNWqbjuTsiOe0M4+f_?__~V7{RK2Rn)bC35a8kL|CHWSu`jaU^&4df#9q|H_hL
zIl4avFAFq6^|`sZ-&MR|!L?H<Bop(Vi{99TmSl?v|MPI_QkamM9KEr2BGwUdxt~RT
zQ6g-->gG=+^Zb{zy!{b*;7s?0Yrk#LNL*sJp#MR8P)(v=E9Z*W_8)#FCvVYMfT{)R
zj5p0qLj{8{;sm*kZz{iJI}cZ3FK7QtPMm)v84;bFaC}HDWAQ3G!j`gQ`RR1 at 3eKaV
zKnFILZrfsJXKRv^{l9gXL(;%?w2?b~U`<EYuh|dLAUs^MiWA)bt7bW#<1uMp9U<?^
zE?Zv1-?gMeiHzyczg~nJXP>aR5c%@(-l$s93i?mlx!3YQMiVznze2a2+Xse}MX?s4
z7QTKC2Sg)DN%UolTn=?NJI;nTho(&we!#tZH at 3)a|3I~obc7A()jsF5WM?C&1P_;K
zyZg^}*IkkDx6DlcJtnc at Z~7w>XEUtUdhD$w at AR$uCF3^^9YUHz%q#oq+!#1(qq$$@
z&#OXP|BuovXW3tMJVB^Y-$jY-8;6WbAQi(QA^j$(pBZNU`|}qh#xiaG{NX(z%>uQ(
z?PS(J)-#~Q7MXg-)dUSENW|ig?+!_jxTSwx3RMe??(7&YUcrq<!NXY!<EBRRkb%;h
zqb>=!%beL8_ at z_m<L4XMWmD*tW}D6$CESw#wKdfQ-t=;x%Ke+SpGNzqe`*nnTpA)u
zPp6%ym$7892f$CI7szCOmF|_5kR;S$0#k*~PG*#5H|r~HE*jh0cIokvx&3S7Li^{O
z7n<%@8a^g5lG@|FkBC-C`ADq7tMhJ}<Xtsmm%e;UPbSyIav>62)7(=_#J^?9iLR_C
z)B5~@Atw}aTsFeH|0b~UC`SKgr7DqT)_S~ZN#$P>>MKgh=SV{R)M~E1>I(O8PeQB{
z__day at Q9z!AP4rp%`Y;Cjw3ty7hlc(TU{oz>>pR(3p9Rev252F8ea at NQ1t`vuO$p$
zGHL(%nUxIvf26m1zK|q}2SDk19NI&6x*A<LxcZu2sjEtH!4IFSz6s)3mHplk_&1sY
z7rf+nAd^Ow_~hM6fI{Gb8UhCqLX_55Xr at w#rpW*E2X6wN?BDwPzJRB(I|2cRT6YV#
z1RlKAPaG<I at YgdYiwD_0hgKO6kR<Mpb4+~WD}4W};;2iP#fZ2P`WOVj+oedgz)ybD
zu|msG#~*-Fsy6*w>F*Tcc#tiL`-nr?$8d&te)6xB7#W?fG#g|7b|7>or&CU8{yBl{
zH2x1v2n#!zazlZN`v1T`@Ed4W1W!E+0*UcK1P$R3k3%zQ1G_AN{6V07nV}N^VXs#`
z+5TG#@NYFPB>+Z%Mgv3jEP+WB6}qg<nPW<`Ua6#dDYlF(w#q3M=i4K|$4V)P-6z=N
zS;<^((0{?<TqIZ`Q8-}+27 at WxeA8vkrGGp7jocIHJqGRN^SCSvSDCco0Sxhu8DlwX
zgUjPz2==)!O@=t)6qsG1jaIA>zv$%81EtO!D>7vNPg(qdjc(iUzfPo&wQ;BYn;k<|
zP74um&)P77qjSpk_xC>%^B$N^jQ>xdEDscO$_%?cU)i1v-7j-BX7J3yV9|P&`qehQ
z&QV;jU;1{M{sE#AQxW8`&VTOaud0 at E*qt0N4y+d^R$7>6UCZl_zSh1cJ6V|9SvbRD
zVtNXmBfSFyjj`8jSu at 5~Kw~Yi7;Pq4Mj1c>CpBu44T;zk0vx^atEr2eztVmXlv0AG
zIlxkq#^G1#0zo3VF>r@?;C at _mLict&wK+MJQzF8lnfGo~o5Dbu|GWRNc!~WY^97?w
z(0|Cf8Tyc>9Utr8$1MloK?+bNDJVfDuT`8A3RbuWS{{lyTbj6v>Zwslty0VEi#4^Q
zr5BT at 9IA66nyXCCXB-vh<3A(f>gU?eL;^Tn6wMO9pt_Uy-#kGtfd9T9K!N}E+hGfK
z*I}I?N7*zNf0hQ?bil`hr1gw-D*M^z2u_4=D?3z^U06(Y?12D&2c$c5OaNj4k++t%
zR^C;)PZ`@GonrN*f65TFdA5<byR+%ENpNg7-l`)VGt96V-n&prDN)uhReug}NoD)2
zluNq>469~#V0VG|kkFCX9p_%ELNy`L4~!m+&ZB(g_A$&c#@(9t<LHs;4dVsFZNs6a
zLXbTfv&`!q5r%RD>+l}MOSD=eE4A6247)vvv5V+KJEOTI_yFv&pvNBLYC&tYMO!2M
zwlurfA%!#8f2eMx=e|6?-&HruwA-z>7TIn~J4xD$-fC4o8D4fn2YQ*OjfE~7s^tH~
zb{!klDoOB-HC at hMbe3IBJw%LG4ttRg#XrZI;gD#n2tZ9BZSR=*M<V0W<G9M17XIKh
zl-K7iT}+_p$ggf^Z}Xjt{fu1oYC0_VViiLDai21oCYdF>(u8w9$p%y_RxVcX$mtK9
zx=7O6#pvWL0P4qefCdvaR8;<|J0~h8_}Fn7+(U=@N|!ZV;o&FIowzdI_Qjn7L$Q9R
z?EPwt&+sz$Nz$m&xTxG4Bh8V$&zlrK744UHDH@(1Mn&bY3>8PZ>v=$tmw|<yp^{u%
zgAX}kl}&Vh6{lGCLpT1qmA|12^A63;zL6ZWRe{!6#%EZ`@-ymWAwE$q1f~q0aD_ZW
zf+tCzVE89VXB&4!T|bFdd$*|l$x%;|+FC#;YZt(7&u!LJ`$nFEXG8!K3|idNDeF~m
z*$k}voNZ4Wi4_I_ATVO)KZy7ee+u_NQD0Dj?|6!2I4|zNv(_qhVIR*FQl|EDCAeg0
zkKV)%mSGy-)6<u0f8`J3M-72m^TBMj at etwPii-01o~|=COl(8ao0w7FqYV!Ls{-8~
z85o5!jT&_KUx=lR?UcP;Y!D7_idk>iw6l_jsv}B6R0UtzH|nwqK-tuFFet at ZXEGg{
zV{qvd_><8Xy=gyoDo4X*sFXr)+|9#$8#Ys>Vp6uW{dfa;^_^~8Xd~3n<?eVkw(2cI
zRRpsElg}3dY at Riu=Znq74km{(UYbfNa*<64GxW=N^LR148i<p|7FdUGQQH?FK%>e+
zeYIWvfsy@~*>6Iozv&j?T&a|X07f=H!Pg}12M>1G@=-k at D19&U6a5ywr+&3Q8859T
zGrE=_I_C-V!TU7w at BL(02K<&=5liXKBXUMise8`1N*I2tt%k}fWGXBKv4atKd-L-8
zC7AZLCY(a|EEnu0YSyOrmZ^9%44pKuX*PS%aPj?VE=C$A5tY1R_CJD<LHVEB_uXcy
z&kvmn<+OfHJInl#r<70FNeE(&$q{6m$>v45w$zxJJzwTElR36I0ov5|r;FmxGS95r
zzEjAl<=8mcK;+6`7M5G4+v?i|BT1KQH%|)YzBM*eA9y)mh>EqK^23dXl?~T&Lp%!~
z--u+~)T=d$ZF{sK*C&B&?oytkoUDx^fb~o=H;PmfwC*k~XweDE$M|VZq6y)f8I(zr
z!yazsOC}N@?UZHtJ)J9f0u1z)F0@&d%Zv&jG^0k;o6EhVORxg|MW$%_Hg7@{K&vM?
zsNQw=s;{Dffq|8n+{^WVXjU3ln9s1-&48%f)D=|Jkg1mI1PA3WFbwwnIo90#t6U%M
z0*h4|4~BE5Cp;^q>kj?SP|UUNQ>?r1<M^U$)`!+FxJH>R;pPjS{TYF~6oVh?EfE_U
zdx>YcKLF|y!0C>PcEU`6j#>N at P`kBA%LTd<oPc?QRT^Yn*G}2%w=*-m8nHxN$KQFj
z3cMHX_YQ%!Ak1DII)$ii)cVfJ*kH8MBi!}LGdX#!UkhP!7B-frvW<fyh*EDL%tDlE
zj9XR0VL?Rb;ZUhjD0 at k`5W7)W6=Jqnv{b!;CNw&|keU9Cmk}|qAT9ZqLf8_uik6 at n
zV{4}f-&xwVwWkd)jm+5EP at vT&O9sCptwXc1RZTIo!z1SfM=m9sBuL>}WlSs<BTAc4
z1UHdFl5C1?&(8xfNJ#sxYB;*dwDLFU8iOZCL}^_5<3z&ZDPtcbk~xNyELkkIX^>3R
zuiMCIGz%z at Sx_^&&JN?rR!u<+mnouo{lRSk3c;~v{M-o|LGITg0lk?);#D}5P7{DC
zlvVj%(~m7&lu?gnNm}{MfiCJt#9k(G5wAn)rAJhBpH08&=ETvtL%BuLZt8*uAQs8k
z+2$mEFm^et_wtTek1a9aQ@@f#UWj(PHpXisE1AhsSGDVGu!_0ie01loM_YthQ}G&Y
z<+&I+N0LBaX5EMar(*;rXM)tojgn-x(&>gSNP%(WXIUpy%ZAb?Ss5l|9hVh1OdNe!
zPn1`nwXM9%1W;O>sbGr at xo_w8CldVQ+I=P(yf3O at 1gO%MiF}GRV>=$QZw9#6c>r(H
z)YLTo%vyU)ivm_F%sOJ7 at riOOSd44zb*;1+(;>U{D$Ri2DxC(MUt*@a%b;kM7!1H}
zhg37ziTn%ja$BHas&<DR at UPaLPyrhukN!Nab7&#KB4M|#x0i%lY>pfWm-7dG7ZV_*
zoX+}{zma=w=o$!5lDbSTv*I#O(HYO3S}!93$ZlvP_r<nz8JziWN4dJ>wA%adM)4>+
zapa(?7$hERqWaJ$WMgKXxGOPc7_C-6TS$0<lfBVpY at JK@+;xUEnZ^1hR$Z*7wo{h;
z)t8%vg+_{d_R#akO<${3njtgmC!meF*Z5q-<!}M&)6(2*3A9r?#*x6@$&*AEHVVBb
z5W=?xS(uGiKTmDXY8a(PZY6bNVEFm^ZV_R3GTUF%^7L+=GW*f^&f3{<ji%}FZM&*D
zfOwYdu^VteVn at GF7}u+!VEBVyLA2xze^egMC5+(C#Xih5;-E_>ufb-aT3op$3uYvg
z2wE1KxE4n16B_rlCB_7TTyTPQzMb+kOQVWnc!%MsC+Y9%FS9WTmvW&IahJhpDHOc6
z;p`A`Eirb*^SnorY*kTADJ6ctgK(S$i0gG>gILs%LRumYt^PKxk08vZlrC3vjCzc!
z9MWK*wJROP;yNJ4^%F}JFHDJ7%i6Rg&B2#JL{EO#gqEKC$@0UGgQQ}HJdF?dVl?GW
z{7bmXTF`UXGl`{vpjms7QI7lc_`qy35=lWR!y6CuoVeG1hfc0sii9vxXIB$)2BHvW
zd`*ozYa>fjj)I*g6z_A?Kk0ThPXl2w6gZs{BF#{5TDO=iXQeU9J_T~cm|KzsBL;t)
zt at x|Z@$$H~B-8*G`^b1sv#pkXDOSvAAM@?t;y|&4PUw!0#=)CA0+KB|98*rup$CNW
zS=gWOlsB}<p~UA-AKl6FTA=oP<Dw-TGm!wtpMC!%$F at pyZe5PTcT#slm+P~@qA7lc
z#TY`1f5^QR^)(;L_1R=w)j9)&Qr=!K8{cT2<ugor6z{WeVhOSZvN^%Cq#|T8sH`{2
z*MiUa6vn{8qQ*bTPAm|9X^^D4<7RKCbpqf at L9j`lHZ|%e?7_U%d;c|EEtX~uA2{Q*
zKFed3=K{CY5EYqZ=Zo8Cci?g)|6_g7 at V3$TqD-Yvhz>~4{Qmvh)e5 at Rh$zNgwJegx
zL1PNTIK+|U!Vqm57*z^0PRpqFI==&_GG&Xm0fq)k7~>jCDD!C6QtFg at NocW{Q~hWk
zerQlve^nGH6 at Q0l$bA-sr9UmB54y0CAA~3>tKub!`W1m>x9az%YuTmr9X?dl*E3Nf
z924!C#Yl~HHsV$2SE}O*<{s8>u*M`1qV26WFsVFq6l6w`j)mlV&|NV9dDY2nleh3=
zr>Pl0OEZ&I{)O8*A}W09>&=GDcuZfd#k at XRYsEO)vxw1%p@{G#L=8>chGBd0&XM!Q
z)RR<qfazDMHKvj!E;zdKj;ZC;yu!x`{T4ucxLn#r?>;t-B;)^yt at 4~Bk#P|55Ah7L
zVYjy0Y92X?^+*R1oTTJKp~+Ha2i^|k<#G#_zFGs|gb<;7{jXH#7}sqW&s9>FRHCVd
zl2Mj+ie83^^+dB8={WheeiI`3 at 4RZoiuYe9&#ILE6!z;~wOsNWg2*Od*;kV#^N<*L
zi;aZ4R$r6ByhJ>pldOyvY8fK(s=Mj)b#cLRWehpy0AaL`XcW{><wPwvB<wZ`%ymGC
zy*_;s_ at nb+5{eT6*iKQehVQqUnCH-1z_AItX}sPaqA||1-001=)#nr|n;a!-={%<V
z8w=ihWyF0y#qzG=23d)GBoyDefZLQ?_tM;;czjzv4*=(G90(;*nr*N66ibjEM#9K)
zIbQBWr?;CZlC!TPI9y8AQmi${st5^-jdt053cFHaqu{vDoXvFVayjV*s{!bj#FGxP
z)8_h9`6Uu&Il{}aMbn-oqOaK*8c&cQ5yign)s7dr;W^u<j%O5^wSWU})zXd!upz8X
z&)33+>JZE>%ktA_ at J|4jM*ShE%HLaw_asT;YCzQ28P*v(<<MZI;k6+(9W{=s)r@`W
z!HVSiD{qbIB-O;p4^Lz;wo3<G7UJo5bcsW=4<=6ULP)t8n`2YdUD)a+3l1ZMT}(s@
z?D$NcY at 2v$>3c`Td%B27)&b520jZxS{gw3MZWG~1xb?X$8TXfx*Woh#etoMhxXdH*
zyHR+4=Dy=LoYqyP=3qhPU3rg*_d9hB<4WJc#3U7s2Ba+M6j9N}Nc<qI=_*z_^<B^}
zX?LPoYVHHkHu?k!?BigGHDRv)0XfGNCA8G|oGu*R8}Re6VA4X+E`f|jCf-lm$gV-h
zNriM~B|&Cu9Sg-!Ik-dF&MG;Pd6TFLr+qa7n>gn_X0l}8U7LI~5j()#i*<_mvi(ax
z!J*DdW{$qRre2G6ZO|Sr&x~0vTKpLgw#~1vQEG8c1Dfb0X}pQ2W2<5cI~`e$GQ$zK
zEC+^(q;xkHht2aJAmxsGmYC)dJFSoTHtuPN-O0opswdA=D9VOqjU50~te(rE_$|wD
z*re`wC+)RF?SMR!^`VG*$Q75Loz2BAYT~{l&5jJg!r1U18s45S#dnX`e&ZtP#>21u
z^1~NARB+1QkCKmG at MhQ3$vDX=-KQO*o#$^-Z}D>_3nW;NZTM%{bCUkBmv8A018(k?
z0Ol%a!|bnPsm>kwI!u}<Ni}Cq1h6WujDsklQ?a{gr|jxbiMB6Ftztq#jE0T&s8#Qi
zlg;uuNFO92+BbzuuMxhd3;9sLz;=?<Jkcq8DKW-Fw2$*d3kcyW?_J&#i^R at ++bNAJ
z06803<P?<<y9rO$H|YSrRu<Uy0`7AsjFbn8tg at NBwpg`PEP&PbYP{=+!t{K-L2(G@
zFetj<{zI&PmnKhrI>yJXo%{kzv|(gsZ`Bt?@g~d1jemNVf;SV0?_=)y^vsS6hYkEe
z6C0^!B|O_q3ykG$ywEq&a@*l!-0((1z3%f&;EsHqeL0HgZYDy-xr at W(R|wM?oguwm
ztrrR!3hUx)c-Q(DsT{}s7Iyu3vGMK!1G{{r>6_Xn$c&E2SSiF8`>qpSvHMo!jvOgc
zDBR+#$m!ZE8YPr%9PmWTkj6oKc?T?7OiMWRl}KkkOLtf2Ro9Fk{kUPO{T}v_<)w*V
zf=V4w$%v|DhQV1n1oVo+u(6R<vJCs@{DSo2>@UpO%+V=H^#ma<_&SW)-rwN;AR=9%
zo*f_w;in2cbnH~JWcy^<WMz#j3)ohm>bJ})=Y+CT8he_}Jc+ at naTdPA>^**9l$|PN
z?RdEFA*cp+)|-sN(<JOXcm3^xajHGzD%xKm4%0ypQ5esnTn~o)t%}S2d4bp2Kw`7e
ziv7Y{u2&=3f~%Pa88Cy3 at I{=ZhYOR^^^>hRS$kI{A?6Qo?MEcGc0t3@`{>@hZpjFY
zEDb}aB4iSoP)hd%(mKd@@#6EUD)X$<sL&aSa;O!xAEsXcEGQkc)x<#)O at 7pfMnYx0
z``6$5im#)OMv?LGLWW##cORwP?##^b0xLsSLUhotx7{~#xRbaBAmEzmLA#)ZI>5+V
z<$9nI<vslCeHd)JYFR$i{5EpLs?P|U{k69Wj%dyyUzGm_g*Sb{&D(@$_tJN{KEr(1
z;XYAVN6|h}%K+Mv+f~zgjf)PP4NsczbQ&r)Lad&8BR&9Nc||0;Xh>Bz&IeeeK~u;c
zlJC#3?l_gZ8ri7M-CyOZUYvl<qVnAYPwJ-ht}=a^Hh+%W1K#|D^SJM!-d9~#b$tj&
zQ;SS;Pkm%?wW^=ao8ZQayX~a%B!LdvWYdhSF7CV#XslvbxRC7iePbzWE&*^SOz{ov
zY?GY{tZ-GTBUTKPi7?q9r?!iT$vxIXk1lUi$kIB3<zY4uFaMf_P$0BE5i){Zpt{lD
z(OF+_m!p%29xgN6x_Eb;cfnB-(=(+ZYt`2m6Ro3j%MIx)*RK??&LLt=CDLckyBL9x
zB>Zw~#$g<~-es42hm}6YcLsx7Wo~V!DDYc9Pc*@rfpF>n-L$cFB?+XGOa(*Oh(`H5
zMp<0n${Zj4(q%M0H}RIn<iv!18>q}TV;D%KV{fRDj}ZQ1!=@k at 0V>`_sB at C?gehw@
zZ_B(^gD%{r&hKR39imRrC{~EbFp(jrYA2AZI+Qyt=4p?vDy?4H9NyJ^%_klDYW$(3
zfphypv#QwHY9vE-?sZC_3%;3#^u|SqSOBf)`SMRjgCpGh(LGDwwe?Zwyn?9*ys6lH
z=m#REx>$r$_)n|8ZNwM{Aa9N6xU)OjngpoiGF1X`^tii9qw~VWns9s@;n$Ra=#9aF
zq$x5Uqs=yal-E?K-)Bd5F1{3lR$;>5FCMdfhCe4yjkS72d%%i6Z&950M;>PnDVf_)
zxNl%;INGgR5~*0?P1*k$|0)+5%?|h}-0;nyNdMi*jG^vxtOQ1-+^RL<t{f1GDCJQb
z at Xav4XxHsH>B&izpF9^&pySTR?N at KSOLe?U7WUrAf3J=88E{_)I9A;~hd&TfneWcZ
zULNm0^Cp=m;c|>z*#S~g$CC-fraTdIE0;P$Z<M{afn(fC^5P|SDaNZ0J!PLX__jig
zoYEIJSZWpr|LB5=;P<2(4CJ3DQ0fowFRS15Q1EO_m-s$pDS3=WsiVVu*ZDcF_uY=X
z64>jQOsizfDjvny3Ba5Y)%qI!7V_f^*zZ at 2tTeqVe>PMJ?-&jK-HT6|TB+Oku~Q at x
z4o&cip05SMS%|Y(6dpBIroADvoC^<ADg!k=Qz-57Z;aZ8A4hB_Hk|YgJKN48Ccesg
zROAZjF+Q7kWQe=9DCY0XNmPuMHXad3aVCx<#wkONNYeUS51Z?i8y?pZu-w0;R}m&q
z*Io2$xF@%*4`Uo)Yj8AIk~N>Zz<i|YHn*9vGgqB<dYeyL>#=hhboy&Jp(68Q^BBtS
zQzYs_Y&CP3!4DExTAL<@K{`o>-PyhiTDlsEHsZ7w{YT1^Z~ee+!?9xJPFdi&J_&lK
z13R+^kK<`U69(}pW#)1T*bSNTqIu<&O+jv5F{byRyr_9DU80Gp<{Vn0NICE5?Wy4@
z2$@FkP~NV;Hv!qRls$n{sbosRv;QDup7g{>EhlU}T5Fte{jgE#kbH|BO%Pd_A$$*_
z({cz(3Q!@<>vTEzm;hJDGr}+nm|}MMI`uHOl)Y^NR#Ex!Zpo2d3bjW$>;;x at -tIyA
z@)p+B^_Ig(o`%S`Z9p{CJM33Y#2~|Wzb%StVfcd5rr7`3XIVd9pIA_gX*hdV00hf~
zMb>&qK(N}I;Mg&oXett$Z=IJ9u;nS}93b6%WN=_gb>h)z1^}lb*aNtU`knopkA2D5
zWY-eC54Z-SI~~EkRO=rNfM}1l;!%?o;5nJ(6bGGmUteDb8}MzNic)>F?G4w^s{Up1
z2-mGWt&Egz$XZyq at u%+M$f#%!2v`hFV#V{-CnJqT_Aca37RhOGg3$<N1vzUxtg$KI
zr+OQXOH at Fc??v*)Vv}S&QglZD7=aUl#2vuhLs&hk-y;0yQ8KeKkl4}-4#A&0 at X*U&
zpOp=*Vvz79=#PXDrdanFOe&3h*l1#qxcH$ZKogOoK}$wO#8Jm3X at yNfMM@-3_w)yt
zEW}E0;mS#_WpVP=sjx~3h!YW0;+dv|j^-H{2lgm5FNd?w4mU}s*zY$1$?u<CBqc%T
zaH+KMRs$qSV at T8Pghv#n!`P&V)-3$a#D~twuZItRF-`K=k?ioJY0PiE<`c0|`}P^;
zV>#Tu8yeuP5?W;=dK5Eu at dh2_<=sT5%<F3j9Q*Azr!}kG*H&Bnw8sbPQ>{w<^+?=J
z<L0l^$Tv&fLP4*iPN7*gq;2mkcSgPC!fE3sb2{hYaD1gw9DsM=sn8S9{^6lq8D`wb
zdT*h2by1~>bk-Q1YHG7~?m*)x$~b7&BHK1ae_oyC6%{Z?Wu}6EtgsWVSy+LmK(<<2
z9-XQ?k}-5jN2*y{K|qgrJNJ_Z4q}uC{Ahl at Qgb9TdU7d=m$v)|8M&g!R()wZMW&xX
zX4YZ*3%P}<*Ql8x<IZ7LT`@w7j`AD<Q7X=pgE at 5cPvxQ0?BWj{<YosX({w~F0vUKz
zvCxDBjS6ZRVqf)1BF=!`ucRt0`|R?ia}@ciA4=RY>#r?-qK~E{E)pY3H^L8o%~AW+
zM$dYJCguVrA}F^R&3F7j&|rc_vfG$@EgdL9G=K{vq)GQMZJb0tjO`H~eq=LGVL4Er
zYjsxhxMFyK5K{VyQpD<P8<XIh=*6;;obQAkl5c$T1*H1<m=Y8@`L0qg*&g9m!YiXj
zZ~4``pqbM&Yz_ll=6HHO)DUuuOXEL5fYJGIO!U6|;&USi#qSc}`6XuiK~Z{%ei
zIK{?oFpFr)T}6oh*XF~bYR={6G2PdR7OR85Yqz`dBG_jTyO(vz-;!S?U9nE$CD30E
zh~AFViQZZtov)~X1?0>@k^793YJcN>>U84s!@x$hM_DagN7mxh4gC?Uq9lMmgL|ym
zR(o-oB at hOESRJZoW@dQYtRj$tqBZEmdwrEMm*Z;#cKupi^~hE~{jg>a-1ocPEHEE{
zJRBv?gnA6`(GeG0dLd8USgz9$-E%9 at pn`o>;DMOt;Whj1N?Thu_Sy~3yu)xi$Geu>
zoi*}%Jb7C($rR+?@8dDAGWuQ4Nz3tJlnQ5)o|Jr%WH8d*3mzw+b;bR-95oR&Hc4Kh
z#5vQp$(7qy6N!ypLwZYnv<7PsUDstkBYarM^#X)Q>Bxvr`%YXwS*}$c?aWWac^Zpv
zi3W7d-`Ka;gl$%#=5hCu2N|N#m5>@T6GV$uEfAp{w6uXO-^qv-W9W~AaSR at JG+WOj
zI!=Ee+-$ZHp8Tk}Q#{SDeL=<+yAr1Cd{Ph-6B;z@*mEBd*;^mATRL5}^6o!>9}w$W
z at S^D(*-53NAcqMeAhGS&+>XVbQY|>dYsf2hDL`9~!Y*)4x|9 at DvdOyzzj1|X`$4++
z!7X3ikyT24pC at BapH5z|_#%%Jt$eWE`>A?@CA)avD4qzQ-&Mf<pgt7`svEOrvjV0t
zTaW)>ppe(m$pH5vmS*CKLoZZAcMkeckBWqefW7!j$XgTMK82bOUF(<W?$YZbB9p{g
z at D|=a1 at _=7J~G|tPN79o8A%AY%n;f4^)d7N*I!K6qJ83`lByuFY at BUaR@b7$6jLiv
zu`iEACjLt+t$Q_*XU2X}(H%!|A<FABpX<asX?yY%n9O8F8tb6VZ>SH!1TX$`BCVjs
z;?@_4sM}3yEgg9q9V3Qmg6iZ8;jvK*{;IeQ;wvsGoZI0B0?QV-z^4(Pvpu4gA(qG^
zxE+ at 5VpIx>{HQOl9xp#VUccX4KQBiY{=09Ad&g4tvLSlw=fRCd*$(&J^cv-H=dbA5
zY3R*|#f#TGANE#wXxG3xf{IMAHoCpsRyCH)wajHucX1S5iZ>1Z2-04fp+w;ch%&^9
zhV$<1=4=mzVAXG#lGzu&^P0)+Iq^9LRQkm8=>wSse+s=U=P2FiCq>y%at}+mYQC^w
z>{8xw at U89gt#62b`EitBBi?uOGd~j^D`G5S5326-rw(rSzcj?6?AXNuuhweEm<Y2r
zP=yNQH$q<yH<~_C8F&($G at 3e?%n7aWPtm6poAL%!*Pu1u{BrqkEx<b2h<w39DHyii
zPz)hgZ{nKW1_z2d2G7RJtqrfz6Hc|BVirhRTWNC6HeEcya6X*0<_A;DnffB9DrZcw
zj|CBOZ9P&wV?W=2e^^%+hd&`Fq#oh_0)}rhK`jk3$&%FuVH!OBQ5c}}ftJ+E*8gqJ
zJuNn0i=62=3B at fH(EB2WWNj=9g7+v&Ec819N(j}+e1j9g1T+{3zUbV at 95-6IKBpoK
z64*NIZ^$}BW5obaIgDyGW%- at ZvN(eZag``%2g2>n7g*l>p89YXSlyu2ZdWCxHXN6P
z6oCB8QAITYKUk$YA7-g&ChRaegHjVWv>Y<!yqG>(G6l}CHth`E38s6=^I(TcDDJjS
zCx8oduPgN{<J<83*|9#~VP&Hv!{_?A?Y^;-S?HAY?U$nEQ at _JAc@3%T;8$`=l3iNI
zdn5TkO_}pzc6cEFk?l=VKkxFx&HJ;To1DJkmRX+<qqExmabwN9P<+&;xF^kHghu7n
zV1elRJ(tY83|nWxiR6*VrmmKY{yrOjMA*2U_Cnp3XHcxXaMg?SS-v}DiV?`F4pZ!j
ztG33TI9v2?U+^^4pE9_&WM+nESIW7e=XVuFeUBRBZD_Fh$*z#eF6O7 at uF+yzZ2t4>
z?K{RuY@@bVyM=276=UsEZF?1aOU=A|GFGxCaAe$fREhHYVFlLQ1ZL)E&NG)0M{@D4
zJd12q!FR%9Q#Yt?DsRdg>xCjcBkuUBIR&h_UPZ3O4$>|zE#=1T3y-{0Gap>zd|)z*
z$Lh7~4!}^@*E3w?!LWae-&+`cJ8dTsPvJQ0wpvTsKdYli$DZ~shJe=h)B}_jBY$fY
z!mfd9S5{=w`ZnKGI9SL+f4YUnVJ&zdlF<2tf{Yd{LQVFZCpn42$S_!_cL@|*2rJ|4
zo)e4lCyIQ3#@D3uedA#XKgcYF<C}Fe5Z`(b4U1ax9_UyNq=i<0M!#9+!)$cqJ9|j5
ztD8#uYIuFlm*smt#A6AgXbn)nrF#59Am+9)xS!=qu95ZSY~A!`Go3*oZt;qm{NnhD
zr{aL+ at v3&Jh~JhVg9EtpMLqnY3Ihf!Jl7gX<hWpGOPorCq62$Gnv8mcU{OUL5hA at F
zX;^=#w@=ey(Q!#)a(W|Le@?-)9{U2q`BjyBcEDEK`-u+7fNU{JW$!i`kq4*WeMn^X
zgA+MYvm at ab+eV51!Kny|zM&9CoHDyWSw5X|<ldFkkSj8j;W at AW{OsBKG-q#UtVP_?
zFCo11)In{|`~}Eq_)J2th}I%n`Zarjx-w}pOk(Ud8Ti2ul-%fTi(+c;xsit+{m5)3
ze0f~JJbgX>&o7qRE)2)r_jo40ce1w|upx_zlU~D}YnzGlY<UgMb*1tuD^AM(8H-%R
zXq1!_V0=Y5zdCLhO((UKF7ucDPkW0 at Bwo8k?^ye)vZ5<r9?`wuZg?H?_4VTeu|Xjy
zWwZ|VD&d&za&RuyXOiE2!sOsb6mFxgkcVS14&NfmmS(=DRc*h9RJWlVj}G^6kuE#+
zaCpU}KjQrIJ#j`hjqe^0(^labh*{F`K;NxnxniG$#wu at aJh#*Tp~X}qb7 at 2M!_m+A
z&551AzSrVPV79kw^qdbpNgp(Bb}-<*&)sxqy2Fwhsc#?2 at ofO?xKn%ZFn)NZ>JE^;
z*Q(a%`8ZAO<?Ssff)OU{&fm97p}yyo)=TDTKIkEUo2tm!cllsGfZ~&jzK=mstKMII
zBN_Sqtt>fs^x<9G)rqh5y-a7j0}n*>wD|Tm4Nqn8)g!l*^D2Jp at pE}SJ&R?cPkzwN
zp#<J*yVd9=2&dJMHj3H%WXqdSjUO`)n0*&Mt1*%0W?}5aAy0`SSUONF8L6=J;;U+3
z6obDiDJ47-VpDxo!d)f-3;P)&8I9NtFAI6m(Hv_+3|3PHs>1<&Hh%!COrv*av<Nsx
zF=hd`uQdFjU-bWD>aC;NXrt|69E!V3aV_rdw76SwcP&=j-8HzoTY&;ia1Sk3+^xka
z1PYYjy!Tu8u8%*mkW9!-&YWkT^X#+tnN!1kFFSC$y$ZfaKvm53(gn at B_CyIl8Dwr`
z-hwQR86My0QM)`$+ at hfpHq+zLaQ>hR-iu&7yXuB+U9TPeF%VnIq1v6PdcsJ}X55an
z47?xa4*QN`WXXR|MzE6-Dw)DhgE011lQjY_(__an)&g~A+%~j_OhqShuFCuBfXZ(t
zyB_kR=5p9J_l3$k_ucRxrIyic8h;F^l!r)j(dq6LJ&xje8 at uNnl?E-=(Acio;0x&X
z`7s1 at l0EAeQ@`Ux)D^t&9L4eH*Lwx4v!b0sW8nIsmKbj$%>{Is4D}jv2oCKvp{1A#
zM0zV%O~sPR+|1lZd*1Y$M9T^aND|J#5`osbBaU`#Ay>Lp#8fQjxyc{nrWm04`aoTG
zKlC_9>AI^hyM;c--d&;H4u5URATDIWT*4j}f5%lvT9`TO#e|BwN-$exb`D_RXz{+I
z*^!MoOoEgLxO;LT1bRgcaF#^39PO25DejSM-W*Zw11%xIo95PxE8F!E6L at CXuEb=h
z$#KU%o*wV1N1H}=zc_O}6uqIWI-vApQm4}idN24t6gNSlM2mo<<lN)2TX7r57>4+C
zH@~;oth11JU*=G5XtU5YgI`3S|4u1!`=>^>4o at k0e&^zZ{OJDvGvol*zxTX#C5!c^
zV-_SrL}TyY>bc>+p_d-NwP{1)OA+zs5pP57rk$<dT%%nYpRC5?hp+a!NcPtpxoDd?
z#*&z+$M+ZPEk_<a<FX>O$-QZMsYy&<2xF)|Gx$<rj(kX9P}|KkKr0^lVNfi$9yNeB
z_{e+2EXhRuz<G9^a-H|-3NMe8oFmYONmN@$<3okqn#lo#b95?Jd$rW<1ipp(loN|8
z`daKfd0#^m&1saE!{3 at Ghtnu3dRpx2heYT&yImmVC-4 at jo9MjObZJ+Fd(M6}Mo2u_
zXVkO1l-*<p|NN=yvfV)Ru7HI$i$5|y=~v<dTIOU!pmH8N&0<zhZ at yZ#NZf~k?kI_?
zs1cMmGm|GI?dcBm#36+(P`%?Q(l%8UfcbBJUa%s9zTT6iK>>zChs%nUE>ATgA%15V
z#fH#mcF*tj+3t-KmAA)haEBHPrh at CmoiL2cZ@AzSw{N}LIODNtlF&^Bx7!T2|1Qf}
z at 8w`#Pf_a9G_m#Wjn{BubB@|@@3%e#ckE3Zo$*DF{g%*FdohWqt$h28WbqQHkRGd*
z)f{8nDrgK at QP?Mv3SWy*Ks#0BU6mn6v(Gmqf>?c`^bwso>#4CEQ&!y{pu@{Tlu?oE
z?uyza3G05GwG|{Z+RQ9kTHm14#*=gXB{D|jb<Q^DB$+y0C%Pg!=!{st8;??q2p_dl
z=WC$no>;8)QX}e>abw!$XUuQUciH|y#gI8M?D3m>q<!CYy!0u{Cn^}Ym;j~XM;j$Z
zPNy7KD8jeL;q9xDa(qP;cHj&+!2=l66QWz-1;6dsRnim)M#)H%-$sf-wNw<ldl2C$
zYwUjM=J?y>hW870Taa{25RLk`y;>unUPF%e#{oDtfjwuLz<I9iihX%dEhoJBuXIcp
zn^Q1D4Ju9uKqa|%0N4>o(`H6&+2o-Fk4Go)HMX#5KMxxDt+R3z!CZhmF(P9DAUP|5
zv!ttU`oLU*YPAI++WN@@R={xq5m%&A!IyXZ9TpQd&7-0O65upf&EPfYM>rwe)!DSG
zaO3olF{eRka*QIL&UPSLOur|eTToYw$xfMZo#o>+Y^Q#@863<tr{sES(s+M6 at hC0o
zWgc{u6bj)HbI2M~9YdA!Wb>T?ge3kJ7;@WFvtblN^m0v;jU3+;buF<l`^XU9uutXU
z7%P|joSs{<=|M-#bwBuJU%nyy$u6)*1X-TAlLgC+v`}M$k!1BFgow4$i;_S=Oe0(6
z`Z at r!_bfFTcd`aB+)JKSE8cF#n1jy5q>y@<xTSeFf9>lde at VMMi2P*oPfrjTTWs1}
zWgFP`v(8M1#%1gyW(3J~`=1Hh%%Vq0fK1{Ovw7Kdu{+jLPby{cX at 2D(&!NZQnB44M
z8aJV6EKO#g7AFGKT>cNg9pC&_Gr69A9e!LHj48U8fYX5i^Gk?eo2y+JXJkZVTg<GR
z{EIic6Ip*E8<OL~M^U~cQ7JVYc>m}o1?`o!<79RW*`;R8e3_uCdE*sL$Qi%>i8&gT
z;WI<Z%ax2n=uJu9;3D`IpCkC5wXwc)zwKi)Boad+%PX;Mh9>enHn()$7jW98Nh)GW
z8jmWYzZxUpyZTGPqlklQR`QR5xB=hy=avQJOsI7~zGi0;R+3_Uk6H~iN}6HGYmJh?
z5ksUAJ+(-hW6ita75}?4{PW)*=<dvmB82n<7u?W%Y`9E*CHJXz|Gg~oK8zH#$d{)2
z&)14Uk#Fj?!8poG^rKcM?e>~UmiKGkMDq7Zf(HbONED#uD?nx+7iqItmrK_3>v`+V
zlKmB!fQy#;8XFUXzn@$7yqDbrns6<AILvJEq+JAOXG|aGb+>2^sQM%rlo-W%qMjw;
z!!;4AX23Zm!+yY_d5hG#k>Se@%V*MS2AM_qz)A6K>y3ye+v=b-3O5UHCb0{XTbIIv
z8$E>&hA#M<yS0AW?=j4T9w5(vB(U7E*53r42 at +421fxth*ouc9FZKATCuzIEZ#80%
zKJW~e-R^tL1FLTCIf4VCv`<aP1GpZ<W%;4d^1F`EZj6$7EJ^bSy9xoRjyb?<UoE4D
zY5 at gPuBBIggBtc@Qkm%;RPyZI+}Gyj<}t(fhhoi(BP4&<h~UrBO&^0onlc*8Nk#*w
z at k|F}69yW6ZIvbcz%UKZUsXw_y(VUfnH~__!G;fPot~`b>tP3c`Cids;uVD&?Ey+f
zE{}0vw?;6az7{Tdw1wQ%M#n)j{%ut3=Kk;)_2jW3zc7UFvUEIum=W+irUh%w(=w at w
zAjMuv;u~ei1dvag=Z8m|zNs#L{P6s{?h=w$hH>?9#+Edfmb`&@DRsd>8TvrlcwrcB
z>?W*;iNU>pv3 at mEV4H=mK$sZag$?UK%y0PAw!d^lWpWh(<>tKv2<&PKbT*eqDx=ZT
zD$1+|*85I2suPUm!?zHCoI(s_ja))IW}e*5V=Ekdg$xOGUQ7R$qZ3Q_{z#l106H!F
z2D;E%4E>QSaAGb%ORCUp>bO>(*k<;9A2rG0?g^X0+WxJTNojbpF#xp`bPSKZefT9y
zm{&Q at I_)+&3+E+QrdXYV6)bX_Ga(rs8|0Ursme|kpHPw{knAZR2tz_HgD^LJ#QUnZ
z<JYUX#&%z?zvbO5-#y%7siZUT$X4tg6DBQd7R&A&<3?{Txeei?k5YPx(S&mqdUDT9
zDV%`c`gb)~%UKmFgNGP!ILdei at wOyqMsjVvK$c(SYgq)1Na;THPyV!LGla`y at p{lA
zjsOM<trR(%9Jb%iP%DFI#5jzFgr~7^M80tb0~7(QNY%OXD?iUJoK+T^bbxSLJ*(u!
z#Hh=aVBQ~bKR{r at T4%ypasJu?JF?7KT3S8%I?lILSJ%*R93K<o)+f`4hf72WhefI@
zuNmi{nv_2>a`}|O{OIO&sdh0C0#Ysio;F#_Gopbn5LZq`35SeCe&QB`(iiUb`J%b^
zmulc(sBY8d<>OLay-rO`vt`S1U2OH!qGaIfy}SR4@#SX&9i8k?v`VjwEZ8uy^k_yc
zBuNJl`j{?TfaGqmcdTa at 4XXQ%Q&u(co#tWL*do$w*q|MT;6Z3qFir?YYEuAe4jH2G
z@^*L^8CLNiy3orMm*x7eDu<72DFCJPPy{P5&<u<bE4Y7<zEJBh-AYFSxqYs$B at rVi
zBtEv1td8^ilp*rPiP^!7;6?(UY7f)8*CYjpYiq}lR#i|lyL-H7qk<(OB|YmCDP70o
zrvLhy>BHEqEyqW9`pqr$ci9jz$s6aN%O=t*llaR%q(6zA=GjbzHy2Wu&WnEb4^qKi
zU6_4+8ixzGPQjTt;#l<FBAmtr!>66e|0<ZT*2?Ixscz@{L{JxM;qp^dy{Wb0c4b4@
zWAB`Eb`DVo6H%d$EX`Ya<C<kio2^P0nvs^(Wp|fjX2%H6zqG-ELe@=pe3TETur~Wg
zqIvUwv}X5VE2bWJH;PEZt^31S&f7LA-kP#tcy^r8%kSKZ7qno_OV9qk7M!n_!IWC-
z0ft}ukhv7_N*#q^cS3vjNBhFPmr6ay+yAhAk1xT}aMp*6h9qa>h&bnCB0?rfOtW&N
zirnRR<c3J{*_`4FnPb0OoWkvDS}*$5JT3z<QwLk|j`KHvKAlM#7Pw0*X)0Py#8%hJ
zd*KPt#O$GUn6#Y9aOgtFoVF^+I;RaiBkd<KNn@~Q=i${NkN)h<H?+Jxq%h3CE_0L)
zqwF?o$7{lQA>95q7^`>OPcfYzrmRHqX&^}`bVtbZ5S>N|$9KQbme?!-Zu4}!Zb4$=
zK)@lc^ppuxPL2 at ablJ|qEDTHNAGuqoDX|g`CFF;9e(5PKW<7xoIc*DLwT$;Bnvlkk
z&t!1$0ZcgYt+T;0{epgv5in_Hftm7Pa&RIkR0wq3^#-y|O}wblznB$jR0n&4RU?86
z9rvik>krzD*{9UopQ#fsJuEUS_D$>=E^7=q^x++|@!!D7R9fzUBmG&YtRBP1J-2Bw
zrWc4PSHIyva(qw1Q!Ak7qdXO4>Q1csM$~|}a45|2Pqvsvz9_C^>rDWuWth&B`4A+9
zfRvQKm9u3S9h0;>o&{6Wm)=1Osk1P(U at Mdzn?@`_LTZ4-obB+6*{`2WWW8}nj55mh
zj#C6x<Tu#9N%^`F)z9OlJwdFeIk8QaGdEGD1<7<tx^kldNx)Wp+J1b9YOgajTCB$>
zb_aW|@~U{|3ADkrkKKH(<%udLZoP{Q=?nsTW$%rWvkSntlHe%|wu`ho78vWLsnf2%
zyWYo~i9&ovfnu(+)`{R+Lz$}T4iCah`y??^4IV{@5zu#$O=zZaPq(T$f_PRUW7f22
zcmHoilQ3FL!l{WuKUU6*`PSd-=8)8TO1U!KaJzN14fKRV+!)&mZH{t7j<P*nP1bD9
zYoD{8BMC$AU-l2{&`|7GkCg%ce-F3_H)%%Sqhv%>Y=OB0Ed>peotfwwr+gJA0iieh
zkzt9Gy3$aBWGW&~FKvtl5%lo{MiY)PE!Wjb5vRJT+d2Urr<i2=&-F>Ai;@$2_Eq$g
zQFWgm`&*IDrUoVk+WeY-tiX*FP~3WeLZ{TDDP8JsaM&p)5e{N(@v*YE?W=fFI6WW*
z^<`Wb=5U!wH7<pF8&hKjY}s at CW4Dz4r`|y0Z!0B{@9BC8`a<^a2E!bpVa^Jd9xFSk
zH0a8j(|Kg^z=^;C>H4xAciZ^#@D=*Zda-)Ell)~P>Q;vuAs^?=zwMc&p`ZIuTTjIj
z%=)|NRHObAJ(QhzNV7tX<4dEcZvBXTc76(qLwc-LUDVqN%O|lGxxgx#Xe(ru?JJds
zQ8n^^ze}VNp_`9H8?XnND1B-Y7h~jxC;NwjZ-2!@e09hF&Q9-QQI1MG at o}2kT9$sJ
z+3j;R-1-s!Wnf>lvgEI*<kMp)xY&ZdIrN3;q%2XpEh>RxWZT@!$7SG1u-|@EE9mgH
zWccMNvDKBJ+ZE!;&O)qwg<Jj<KaOkSAtEY3qBYI<aA+PVwTvy1 at a^@iWETV0pX7S^
z*LLGiH4%6DFKQk-`l-<yj>$$rJzKKnUFcIS=A9KR@|D8;VK4VO>kHYJ-~->n74mXj
zj&faJkB8Hu2WX(*-uGY$hi!jkPQ&^#T~g`ZJFlRJd%yBm=FnKKmn%kpEwq)pQi?Dg
z&a#6C=`xxDeX%*$*;3s%o{;Rz(LgiQ4ew*~-463-HnT2HNUZxHX78 at NdUiWKBJD-M
z+gN;9&z_X`azS0}27iX$VV>el*4nOwveHT56&q&)b7+E?)RR%rJ at j%U5>?~BP~Ag$
z at 7_oFu^{GZNDI}OYc<7Whdy+2*8g&J*8iayy4&)4uhMhb7U^+ExZGrvQvHK-<1sfh
znug{LZh&nT8>j5HOq*s@@3rg0jzEFugP1wE<aLR}6NUq`0$*E at e%50u4xIF0Fa at L7
ze|y}><jH_e_R_&4&E at m@sGgfc{@}ygAS at f%YepJ+c`aVRvfWqQpjzI*icm6X at h
zzSo#UnA{Q|_bat);oJJwyQQ>@z2Yz>02Cn4m`<rAdaQS<oAOAe6ySyJK*Hr;DpzIZ
zudYF729gN{Ei-$Q%zkCglX^Wb`L~`YTi-_Q|DCBnKV+MMjl)-5J+5~)&B0QVUI=mG
zgo%uK$AeT~27~#4J*?Y at +m?T5YGPZdFgHh;Ds7oIT at -%Aa0A7*y`kU1Z??a|#C|@4
zq1VQ3Sh>aD&~tc<(M?^kz($<e0T6%rcg-!RepfvWJ(1hJ#=l2bc}_!zyS^of^%!xY
z7Lcs~g8xeox>S?~(j!e+4zVjDJ!l^7BZ<(*Hn!n(R3a3jRv&*Ggc3;pfp*5N9#r
z!wXVflGMcTyUMqtM7M?7_4QlqTXt!7)ZeGDRyfI7ballbxfrI^5ntdQE1$#H)$6J+
zcYeL-WA6jpZ1)|$$j8{gxBjU(?w#kq?o&b!{Dc^Oi5OSvh@$HKlR(9u_sRrykOsTq
z_k$$nG<mw<C(FF$I4?}x7(9N{SX<+?ii`rqI!cY=4ed@&jO>DvI at 3iEdNqRm2ObqC
zJ+lnTT5*ukXB})feaU at YQIcnj&_XK26`%C!Lro6i1}8q?-JdPBkCedqrF460arnWA
zHA*TT0jHtsqfF at Wz8}Y_eebw&QK0P);zR|0At3{W82|6wn(2Wgqx|ud at ALC|4=Ley
z%-*mOMMlFJ`l$W22ZnhbOg(MVoFn~Z&|7k;egL*QO9DlK?^@+%UOpRs`&K^@5=9Qo
zXj$gbPbu}mFLdG}h4`3b4NJG_%8C||d6q)wQKBp6vgGyCt+Mft3a2|fxmbO*1Bxb0
z at cYVVJVlTgt(b0Oa6-D=<4p{Bu_;fp*Wye#W5KZ99%_zt@^t<sJbApKw_(kWak$Az
zN at x}jmxx+A2s<J~q}9>fNomuzI{}iI3$nesy7JO44&*z+M0wT7V%ZU8zge;qJWO#O
zkL-G~c_X+ZY;km2V^&JA!C|gAdj+q at CA5FLq#$ZV*s`1QxDUfHb|)LHsIbMdMKiVf
z+ZpFrNM-*qU)V_4@!u=N_(IePn;(E;1s>ccw<Y;7?_7Shj1Xo|3Zm%>+-#UFIZLhz
zw<-mw(*_L_DFjXm&EwZ<iN$d`rQ}U<172_Tu8ShB^n&7YO0^7yCkrX}d+8|Xn-niz
zpQIuJc$&fwI~E_Bu)jC<4I6!cXCLIUP^2OHkW>oc{{-m0Y?9{8bSWOWv)QKd_cfIE
z_98bQr_`=K&if$BkPh);=~Ci!+rC8`N>7Tznr`2R_7-C#2|wl7S~@t?Di7-3`%ZGU
zvb{y^O&GP(Q_Swr!AG`-dka=t&XuI2;)K(>m)1Mah-USd;JeDYgA%^)+LDQ2Mi^Wy
z*0>3=kxG}yUs|(qn}F%<V{>h3JZ!BR9bDWxVdXqil|(K%PdBcOiv*7K&|gVN^H~@(
z6)GdgG`?GpVD@>N77>J4e2i@`t;U|?hf}fpw{tg;LQzbumm^`+vJR#yn#_V}u~vr%
zdf)@8sIBZ0y!(j$TW<pb)veP_n?6*$L#vM#i;7`<sw&*vAW(;Mf44!a-m$?2vjKj8
z;BqC-CE2lRne&u>+oZ_?T$SEm&j23TmxNFi24`{b*v~APN!|p_z*%lUqMstf7=F{=
zz8{MxqdpUE6&^M0ky}pfclVX;?PdBxp>=wreMtwMR43oZ#<NQE$(yv<1LVs$%I;0H
zJ!5Bx9{E<TYI`C(;#XaWQvhl4uN1(*@}V-a#@Xlgdg3iuu!-+!N*-?yAk6WfRhoSz
z$mp*=%11huJ^1`;y-_{v;o5q`e0n(9+4(!Zes at i+VxAlAVQ#wBiCVUER?1LL**&$q
zihsbm9eAbsW-pG~n^+`bCVG<>Z}t2BBoxnuGeoZ<%cOHEI)QTb=nQ9tp?0%cAwc$g
zg5wW$ueqBI3ju4vtiHkzn;+A{b&KrPac^3*wuE%>4XZO*gM&&vv*K{9%}Sj*MD+yZ
zlMy-=Sn7PLRch7fM~yP=@wrE}3;TIetD4K~6c!z7H=tMW%mpAk5(ezlZ!|TfBHq5$
zN-0`P?BQK6qrE#EWGh)bUFm$yg-h1pSuN2nQtd)(l<LN_@@4C`k!tw>vLNp434XPn
zVpO%^Rt8?zGy7Vmx`(Uya!V!p=G}O at O6}A1?Xs~hdekyyD%~f=H_{nCLjCrq!zsF|
zRlI;BB7f7H_2ype0zS at -_mPsk_QG$=7y9ZLN#-^z=UBX2qgKL_m}y*wpC&<=rlLhL
zDn;E!W%dt#k^UhCM<9fa-Oj};SXZMYje$uIHCm))srxEiCmS+#bNJ4S0bFdDQ+6{8
zbOf8cgb(3NZ<MPGMZFv*USkvhy$v$VF+GGUS}jp3PoRgUmq{88XS>Qek`o7!=76c-
zFX<wz^RL9EsvX<-5ae4w^qCXp8_ty^Mv7Q4Un<^<5gY9W4AG(KIr&xgjQmczY|)o_
zH%*^N560g$xvkW$=uI<B2H^3m(WigvAt*WVho5ypDnZp#8%GjRFk_!oeflX(GZFvV
zJ#2k$B1VZwo3hxFKn8z$5Uw^|cK%0G8sZAH$!kh#48Q?yDCzgRKYT_VhC at P0h$>DL
zh+SlKe5k^5Tu)dlW84>MZMdQ&sAr^pXwtd8Qq&h|!Ql!~q<*yzNp%L+Oa03CF-4We
zJ#tm}?d`es<p*Egh5wfeP$Ou4L{51T$!oL$37#1nqAH}- at kGTqNs1O*{A{bwdN`Ai
zq$OC;l>d|@miL_jIt_gnN}ObfbCG7>5-n!9s%FbL2{H%TPM3Vc;^OyS0qGtL=^}}$
zj at n;)yb=tTn(PO;g%-7iG*}mN2#HC;>Vr{#E at Y83B%of&+qmcO;WctY3O{n19Pt;e
z37DSiHVFpU2oRgSZxoq}PBK|2{k&YLt{ade9xlu)p#RHIJa~}iVzFLvcL}Xn^i-Ir
zp}N_5QU-k|)6<F at tczaEUP!x_)wOn#AVVi+Y;sFqK<3;t4hO<U&_B<BjT8vb6xNrg
z30LOW>fPB}UNtz)VQ^<Vq^$i({+(n~aePLOsI>K9xck1 at fc@)8y2sYcVIPO!TZ%k5
zoMHo$Kddm?ShCx~)oXiHP|<q<zFKX#1GC<3I3Z;lTrlK~p7t#!98Fn_LRj6zNc%$B
zMF}wRR+&gKGu2VQqms;-_z=}+e$%&$Slj_>_tgt<z;-wxk3nW8bYl7DJ*c!*!zjzX
zJ<Km(-OKBNo5r-Fe`<dQH-WR@;D5OzGWkd20t<4Cyb{;CFg(DoD?L6yqHCYUcQ?aq
ze~m#@TQ>mlr?HNeeph(toe<8{@HrVd$XQ_NK%@~tqL|C+dhkriX<x2+TZclu9xu=+
zlVg5}kf3W!bujh!pFHelHn2c~*g-L4JIC7;y;j|t!n*Xvq-qp_2US~57HGvDwt)Ba
zZNv)Oir;enLdF}tZJHLoob6+dpN2h=Q17{)Z3t(;cYJ=0;4$lwCiX?2Vc at 4v`@7h7
zBS0iY at qmG+RkeA<qPeOf`+0=+eD**UqO;wA1QypnGl9h4#B{LPyxV}B<$=Idl$}-^
zT5Q=&=QAf~cONWE{IxO!?M{tAxO<b+HapcyXNI*}I63DW*~&b~iC_DsE|rnA`aiR>
zWX)>+7#H6u-+HTy#F=B)>sZ}4L1$;iWp88yRw!0aR=)QB at JG7&-8OweQRTtIAzw>g
zL7JyK8MS>g{hpeNPfyRSAdORoXm)gkGWD&1u=nU?8iaMhiZqRTKm!<lQ}5D`q at S<1
zVWz3xh|(I<;H4hgC#J6BAPpdPn;Mf=s|`NGY}cuCtK4&G+c&7wwdx`Y$h{E>SW)f8
zPk-afB+SNe8N(WICSDg?^!(lx#eUUry%<N*XrDK9={g5X?g+`Rm1KTmju`5wFRJym
zj1TS5&dO;PdxgeBKD|Wc$Lm>G+w#CXLk|Y;Lcv2vkfBFw6h<<rehM7<xO9fbQ<Xrk
zP076@@(#w_WwiHvvtiXN at M<K%Z&(xud51`ia;&<I1TeNpOE5UxhMeW;GG&!;4><*7
zCl$)d??;W0s;fL~^q1q;R1%-$d4!4}1T<+ks)b8APsg5VfyV(O$yv5IX%75ih)%;A
zUBnrzY#W6cE0yyf^IXA%j=rjfi;)%3v!sd3DajG_+O_15$Q6zF^@>_X5eCTa{eIID
zw!EO8oKYWBV7lHv^q`A15TE^(=R7W)WP0*O)NTV}gkJUmXgeI_%ZlatHSb~jwjR7p
z6q^C5CZDlc#rC);aT*xW)#HwZ;Z_ at aJ)sC7wiK_N)wYXLFZ>aH&j4 at RrLK<keD!RR
zH1y+J{eHRNk=>}Ana1<iBr##q+IwrOjk0EUU$+NU3JkxA?T$z$veZwa5}X%lU3v}f
zI4fzMID*Z+T14+xWxObBez{l(raw3DcpFJYhzUOorKH;|+n8G%s}MN?03*wf$nWYO
zEdnBsPGW>8<$Qk9D2S{qav~~+zgJaoc`64nEZ`a;L*!<RAOb#`(u{Ic=W8u5*mizm
zvx5<zWs8XhsgUy^dO9PRqhjVXB)}}4`k=POg>r9TI at miWa=@}nr&;(TX53FP+YqJ|
z5j4$Rhw}Oxx`GVXb)LJ(!;~e&bb8kIusj at d_K4}x5{`24W#ZQ{?@pynxTQTEPMh3`
zB2A3LKw;j>h$`hOd>y2NznEi;YMihs>8xmYC!%Ivp)4xx>dwiYhRvDYeSVz;L!V>_
zvJ$P$FiA8?_26}Q4Ke1_5!*iJidD9#ewQURm(m_7W-S74qy8u|Xk#JVv0y0q*nzL6
zX$g&;M!eUAbIZf%yXNeSmsYLIQG4i>A~d*4_cQUdu2(YU0#i?esL*rf4*JUKwc%|D
z<9?Z-zuqHc$okl!;LNDdN2}vx<85k{rmfTgTK9}nHu~EirIfVC0Zr818(iTqX3wJ@
zPjdSi!<X2S$d0NTY|sTe<PG)=+R34 at c(pY5jsbn2XGtwy0$)R*m*$7%>@$&H`N!8<
z;W-<DIyyQ;hC5x2g1v`UCe at cq8IHC!X0^JMWykL&zI_zIFw#54JX~t5SF*LwfC at FU
z>vdpIGUi at qd&@4zEQ0HcrkE4OMr?wwpLOfh3R(4j8wJdI;(oY-hx(D(kMUC)S{w?A
zZ0l~&?$2DBG^y-$WWvIYdm^3henF^ig1nYJe5GgcYmHQ=+xPn3g)p<F*^ZmJrb8g+
z0?v$qjcdcHp0S!+55>CaOn2hCp0P;shrx9b+CipcRQQb<0Zg|#PFi{K;2ybmtp=w>
z?O!Ipa>rk=z}RJwn~4r)IKL=sdZL!R1RZ(G1?agr(rrMn%Pjmw5c8O3WPC*Y)D}j-
zVCj8+zDKXE)`QC)2%Yy`p5o}}RpZETV(fs$YM!m!&P-Un6F4)MijKAaSb?b^HJ{fW
zntDpEO0XYCK=Y}w8S-sf0Io1y8#3TQ3mO_Lz-&mZb<~_|Z~fFEOmMb2C7=18WLqlm
zJFjPtBLj>t?G2|wKBepaQ_hEput-}6kYLT{>q7W+sP}Gded~}>I$syuE(>^AS-{I;
zQgL$j?W$4s37S1*aSQDX?719SM7YXPIha5{8{}F&)7C8^7KS;e2SKQ|yB-@>>ouIx
zr!%~PZLCC<<l<x-JNggWS2Nct3kLafXDh%lwNO+KaGx9xL>92tchW6a8x(wgqq%=%
z+b?zf*ILA;x_wG~*CJuc(QZ7NiUNhz%h01TW2Lsw!0V67Y`@1r$+i$Ieoq>$#nQLD
zca?F4oBKt2Irr?T{fO*@o7-}JE|v|-ldTOtMn_}>X7oyjo>)R-7$Zc)AQta^1pQmI
zU<!IRa;Cq3U>footD5geg7`{IG{&Le6}!*x#9U0Ebg&s+iB-ABq#bFR1zFtyW6m)9
z@$9eO>$(eL0y_QXt&xqA1S^QVn at JVl`+a-1Nmop7MD(~WG at bRyJSHD&h{L?k;lv=S
za{5##V^pd-dvI_isdqcr*!QZ$erWI7bDlkbMU>6L3%f1h#Ksd9mTU!P`<>`Kth)h$
zSlc<ba%0(V_?z$kJ-_ydT_k9rV>nA|z_I{}FnGi<s-P5ayl45INEn5YpZFK2??+Jr
zv~yqk+^_r6FLgX)ZITUJ!y<9d=GzxcF#Kve1qW&7IO+r%z1#t9spN&3N||&H(fBiO
zODZnWEwpI!`kO|O%49nG#pzHMN`Q<k>(1EwLbY8qw!m304O!%!VTGk1$FmuC&w9PK
z>hOGE8{iGd@@_^2tn_Q<l}z%(U!+zbBp93crTm at nZ{r)8%k{rFi)-JgGgf6OKvBZU
zvl?@v!=JQ#J8B_K943!$v>Qu8y4}LBnmK_AeFr+2As}i6ucDXvcrI}Dwix68Y?Lf#
z>+%px5;E_q5YUMiuHstBu+K&O7=en(5>Py8l6!)xWN)kX#x<N`!fUO#2t8-Bk;o{!
zw at wuGCa}Ju3I+M6(XPnEZEg`p3QK*-vA`^a5X^qhZ%kKX3D4H!?Gusn+BE!dNv;e2
z0 at LHmL{MhA+LDZRqH6D((prr+wq*2wdP)jaB5lUmY}JrYLKmDZKdKi+#_tsO9<D5>
z22}FMCoK}_T~((K8WZPzNv~?L(ONv`;P}A0&V&BX0q$0)N=?017g9>ehrNbx5 at 9xT
z-0fGWh(b&8I{|fet_(kiq6dP;Y9;c8Nk=0P5atYdixA(+`W$l9h$qgl!b9*S4k!B7
zJTzE7-fTK0C!yEsPP(ohj}KGzw=6}9`ELZg<G#>DlmUSL4 at T&O5%n0K*Sj&QvxBQ3
zeJb6qu~ZnMo^Zq}``sS)R;=zu8L?Tztjm%p`kcN7vfqS>%?4zZYm7=<N`!CRx!^a3
z-UjVAG2)9IY37FCZ&D6A28e+dABdQ(+)_S?1(2c9x)T}PH+Ma-VpaE)e|?v;b`BUi
zw<tl4Dp_IM%-0c%n3_3C)m3ZHvB}|`d2Bw+&!@gWsn#x}pUBBTk at 8v7146%mZu5QG
zu3CGv$D5nR$!VWoJ<v<5(3pdTK$^H<3h!7hAu-c-7vo*LvtfN!V%#Nbrk-gj=CX)S
zlcKAx47?<qaQVbeM!-V-CnlOTCmzy<DDE1AFk;xQrCX<}3#YD5g;OK{xR$X%1e6d?
z{gF31uA;U6GpW+K(^6;a9;J}mUZ)6+qSwRXk9~u?Rof6il_b%8Oogc0f_pBOTnwpy
z(i<slJh39J-U(MltHW%dZ?YCkYRTnoXbinTS33_|XkLf9D$!ooD4Pu1Xe=c5Osakl
z^Af)Qdq+7f6m=_Ul{P(qYc5&2#?}ejUPmOOZcrmzgX^`re)0OV{_oAjmn0Z=4wY@%
z`P0AJzgR?_wE`i4Eva)v5rNtC^S{OSoc49XeGP)q`?VZ8(NV->uUy{7P44?^h(0uX
z&h=PApoFO%m3M-~N-9mxdvU%^wfv!G$tP3KA`5C}EmMSbWcC4HOkfZ~k!I5ayB}=a
zIc;g4yP{$siXbW!R+Gw^RSb|uyP#2;^ifs*sr?(b>R(qzY?pe=1H$@FFHu2?MBqHm
z4T!hdD5k2Ze%0yfcPnzErhLriyMq7*Z|Reo8DC9DYsyvtkzGA<!GU02KIR6jhSsx=
zzER9WR8F5tA}P+&yq3*Jsgn4BmAJ<ssgZe={qYH?ZRrqIF$_FWFKfCyP)lq%9Ln~v
zt6Az1sGhfa%ld7$fM>|UB_-<C6gxU3i7mDx<RBdLrF+Kq)7z18-$sU-zZ=-;kY7HS
zpVxfe`ZYU~=Oj}rUa85?Ff^QCPPuwmV5t-tj;7R^*UY$rt6s*oJ~l@*4X#5z7q at 7{
zYjN{$pPWMA#iU<Gu?M{eiEqdl5T_Fce&|qN4SEnWyy?}S(qPJw$27uIMDHa%@wSU}
zX7V at b@hGX_&Q`9f|Cxp(RQF*Qt at ybJ-6`srV at I}-0>y)}%wXxGuA?gJFTF%S=jT{f
z3Z4`J<?vtSmEpP8aGfcq1<|9adRardY1eKp`Ac2)1yK5_f1ieVAE;zo*~H50d1lDP
z2??dpwVlyNQu~UFG)(-CPn2eKq908JsiFXl;fh}hc{g>-h?7A!WOk2cDcU^Twu9nI
zPa;DNf;<GVYDWT*(vKZ~V7OPacVs^rK1jc5F#m8QcaOvAaWq^+Z!TV}ty!l$?p@<l
z*J8mbAf%g#RRpOr?w_0e#}F}Rx_bC^(GM!%{6jO1Z^tB#(>bxCigIZmHW%ADwV==E
zO(~(*VTXBU`-(A)tEQ%=r;f6~Z=0&krwmeM3Zc0vW_TLo9mCXLl=Z4k_joIBh`C3|
z^VY6QoU_y(WZ3*QjZaTkNQ7ee*fBIzs(sakqk=scVpDPq8@?0Tpoq+td|VBHYKgq`
zf0^vheE-Fypla{XB`yD>-l9zQm&5nX{eB?S=U^vAP-IY{2o10a&@FpmFTMfk0`?|#
zqs4puh&42qFh%~Fv1MDqV|L*Q?_-<A@^-Ub>~NlMphq~H3xDRiRH9Tfi;ch|JppPJ
z-CsoCq(BQ90k(FD8 at XAiXiFMfV*A*0pC_o91A(J^4T#OGHXxuT029KCFR&r|wHk*1
z3ERy#n!C9Adn_tEM#W3bcA=T=?!1dF&;aa9Oc*txYy)i=Cq&Oj%Oix>ul;_j*0!kx
z at T9BW0azaM2BTDT!!tdRE0%H~vXron<LN0%%nKs~?QC(o<{o305ejB5ag<AOQZG&J
z8ol%NA+Rpfpa-oHV-iLaSs@>)9{R)*`J0sbo3he-a!Uoalu9odI`6sw?bf7*=WoK<
zUM#KFbkb(Y)!gO=#H^t?kChx$tf!h?nz<N}0pdR~44xW2kcuDco$OsgBy&m*FP2T5
zhr~aYk$D~|U4ZKRZvs*@J-OiYL{zHuxCNr9sCVBq6zcaf+2=kOd+pr9L+iXzOuSql
z{ZdM~H`7;GlzfbgvrhRieIJaBMB*58KtI5BzRM*B3yb14wl5QTd{sL4WW5GNEVp^w
zSnA7M_5wZMn}YOh!j_5|F at t*C5?@nflE~w2ub at tHCi1gbF3w9nR~y7t%zAH<rJ%~j
z?fN}qvW1LY at 3Ubj)vfWvW1nO|C1?Cse>E}gm(*{A?BcF(F$UBnTNG24yrT-H<8{CT
zvrgafK;*+da;nK%9o6kP?ZQ|qS{{T2RCstVxTWQGIR2?x<4JleBOfe2*PZ3Ax^%P2
z(eH!Xcb at IHzSyYMfi!)8h`>!6 at r3BZ52>cxA`4)<O@(MW4@?`jF??;LKv`{Hxp@&v
z5EGW0!NxCfox#V&Z2+=YI3G6=a~L4 at 9^hN4ON)MbSha^uY*7pB#B;?Pe;m3kCB8t5
zC`I?X+8T$P0SJ!mX}U))#HM5~iCC-@;eLsnlbFHsN`h<yvdBc_H&HweG+ktX_IOwB
z9h3E>J at d+2Pq>022JCh(- at N0_1Tj*sj)^6pGj5Bs2n1X(i+zjUp&Dn+&YDD5a4bL%
zFwflJ+sD=qv~6T?_HuA=_#wcj2O<;bs`72M$NAFGfH7+2NjRXSR+4Hk(WG8#+^;ei
zQ(q3*kv|9G>+NH)ZoEYo3BoG{B1M-JdSLx?zmp}+0^wqy)}@9-8tCK1PTs;q*I2*4
z9E&=EcVGTvn^Qu at cyR}Y(-*gFK`^qJNnEqrXVul+OKnz7wxY08nqPd}<2p^lS|tVF
zYKZR~#dRuHO*$LRI`m;?A(G9*yPXYxVfA!)FlCFhN!Ylzw(HH5F6lq95TUM%k5xOh
z&TY$ub_s+e)b;4{*0Ue7l|KIdx70PNp58}u{cVL@$!GKSvVNt$t7Y-8pO1R|tx1!m
zHVo_HxZ;8U(_*pQPmj&qRrjN_L at lhcS?%tn{+H>qh>v;$R-|+IbN$6{LRy-{;t4X@
zF5<8i^(Ie)QOjSe6(G)vdhxpN8h0)_jw3-YzqS;YykozaH`O%ypm^oTG=*y(M=OW#
zi!>EyIwhwmt7(^Lod*oVr?=gEOSU)<u!qbUKP}pL#EJ?57(S(cjjMKf_2chgpo at 0Z
zv63jJi|X6n6UiDzu#4Sg*MhfE_OE#@@dMVFs?dezw=V$V3Z%IHYMa030<=?(Ko??E
zJ#wRE$w0*rGzlu1KAc}$Gw$My!U9Y5GFda>pzFx>_{Pw8XDcHsrBKR9mW%`P<NFiR
zP1wWnY9+IONTEx9!ZgP@)s83U=L&=hhV3?!Jus=Q+jpHlRg$Teq(3|CaX5PqGGc^U
zABAI?yrp6+cScFfN5+yVl#o5~<%krn|C}xe9~XKvAtCbJaoT$q&sK>H%tJ#L_}lEE
z)Fz+4D|Co{!QV)qIgS2vwx>yys8A>#fFCUj|9hn+wc`R<Cjh57uVv7$@@$};{FQI?
z_-C87;TJd4nMYNQwh_gG{6l4zXEdFP<aXj=QqN5zD{HY}$}-?@pq~qwz1fCVIv?el
znwlJ3T}R^ym|H_%LmEGR!G^PPVzv)p@^O7cWUoo8N({N$k!dvUV)L}YR{>u3{~r3(
zf|7~Y^+(i`=aChJE7QTIdL?A64*1abPF5V#vKksVydX?Ks%me7A;-`vp7DPlutWq@
zayhB0evO~AFj at 1=s_JS~&i?=g0XkM6R00D7+w5lZwG>o<1AaQ_B%%;d1SVy8*1J<P
zTJvA;<|XM^dE1ucp9csNp>M1j^1ZR;;(?nu^a4bBCv152%HLv%@om7x-3>>NGqt--
z%B26_zt&%8bs$VrTN2SE>R}>)%bR_2JuoBqn8!3guHe-BeXa8+D1DR}0q({ebj2Z+
z`+vvfkk)(Pzs_{?RS4EnLl3B<_bQZ$po^q!jZ&`+-NI@|5&R at YUUp1q2>b#9WtuD_
zTj{Feb8G*<llDca#DJNT at 6XvS%Tx(81ecC^^#^UIIukBduXpg+iTi$tvAfRC`r;9o
z7gIzw-Oep69H+_@`4(+2Wd;yM_AHD_Ei|;kqV|Yi3T<V~nW?Ia=<StM4@&LI|IIl9
zD;M-AbO&b_V5QutkEUP$C%wA^SSkqzJ#d?>6m`Lz@|gfVk~Z6EVnAD!M~XQmX~P)+
z4cL^zVX|f1&SZ>g3-gPMQECN(mgj3-lT6)lP{CD_5s;(9#WamLG}3h)NVWCr?T-0a
zfy)2;IsPPL6Iuv-xFoL6ob057;NNUVYx6-a1rq4aw!hJwe)`X2Ab7(gNRR^!q5o!z
z{pVLdu5S136hOlBVj#vcPNznF7l{9!v-auv<z>N!{pF>l=-{XOGVQvZ=Ub?TV7!7$
zwld=ubIrj_+&&%ht2Pba>fFY!u|)^@Jr^H~CZ%2mt$OAE2}qZA=@r0qu^4q5*6<4%
zX at d)Jk1kfC6oTMupEw)o>vb$VK8J`nd!PN}snlk5*&Ym at 5_V`$NjeTN>~bP9SsDHJ
z^3-NMo}#s*c_Dx)mo;ts2L{_uU~iUY%g(=kIuzM`lJx4O>~>v`IW7sMMnpseZW%R?
zB|83Vp<hj~{CN=GMWrRFUbJz!i(vXB(`=C10>5ScQKcJa0$oot#xS>C7hexYD>vqT
z;PK_Lt{0)gbqw%{{ukn_$XVWZg9kGnl&HW*-Od5TkRH_<M)qUrk5iKsg*x4YB`w$W
z6h4yM0W^~nUZqs(QGpc`9dAs#o3FMh+0(WFmtjBKzzkBAYi7LgA?LLPxDk$T+vxcg
zU~DT`5pd1F%S||kJt->}90}2pJG;9%g=-|+{;EcZ79R^_71jOXBS3=Zm`;%Joo=tE
z1jXy3{QdixM|eJ!TQpO0&bGtB?NVA$kLF~B9}CEZFTn%cP5f)QoiZg=$%6nb_FD_d
zsMVYN=CXlcR^#=LWvLuPfB<Y6L?%mF;Xwv%UA?SnfJ&{`MRr)F at o22bWol9wxRGzi
z1hBkq3mNEl``l*y9o*cC_13<d_;WpP19AUJG})^+Nwy3QdYh(R(_mwCyiVSD*!m&O
zyZeY<jBnJ6=ija2oTR<|;?OH-(EQO1daKEq3v82U0vio*1!q2qmoAx&O$<8ZZEWyx
zlgcN3DY|S#Vhp^KW4Cz%YLN!Q$uuD^7(d14V{9M)c<4 at Dd(1VJjE#5u4Pgw`C#5Q%
zW+c7GMLH3CARK(ALA{~~{ln_w(1wfOVyGt9Ml!x~tiXdOC6qwt5I29f_wuleV?MNF
zfup=8`h0Kx%EPIS%o0eAg8Jm?^h)rsi>Oh)A_NDOTOXVDd}>;;RFEv1nfm{-Xgwv_
zxM$j|-9FP|{C*v6!R%1C>z}*3GF>*>%t=hd43Ud@{=Mg!n9R4gv$x{HDFiDtwR8V$
zD7!&3b8&pbtDq6$7EpD(E?cyA-6HpTopSyvzuM1ktQDWK-=9_Q>V*y~9LZJbBNN^F
z5&g~#F^tgjiy)c+Lv0_z&7T(&{%I=4ku;8<N(Q%7lY<V8zLEn&W(P9wW5dgOl8>?t
z(_+cNRSYXb%(11*RF+x5>M4%ZuEX4%59f}sBcG_!0W5(=69CDGGI(w^L{Ju%nh@@i
zhXcQwoM<K_AEOz}#eW(0IyLYBW7g*Ofm`E7ZutoiV9%aez1;h;XhQaxveXBoUZ4MN
zKKvanxcVyOqDad0J?ek1&8Q2)GQN_X72LwsR?5YN8xXp{osq09@$tQPIrVWV at p)_U
z_MvK`ut27dBGbCGPQ)<&2NIdY&nu`abAUfU+HLmFA?_8Q-2gK=TUNcfq-sYGQxYI8
zRcW(wPIb77aq2cY^T5T)O0UH9x__UDIn-4?p*T^3{)_e8PAwj(i%4ZWHcR;^<xe2^
zu1%ALkbB;n5-Q=(6>>A9RcedKIp9zANluRRfs~T1Vm^>Cka{gXwpb(qJYl{5(H;EM
zGJwhYPWE*Y@!{gz<w$`0MvMVXFcOqx&2w5Q6!D`DbpI>tAJP+ck^JPBHm7Nd>oT0}
zIDnunqwDPX%i&`$8A-RkN4r>bE!z!VnYM6>+#ykq^|=10Zrk}5S8%s??tXz(F!_Lx
zNt__k`y6wtUyv*ypS+_c2s;wSR$Y*1%KQ+vN?QF}6!`MEIrsobNB6+_m;Ir#+%aq6
z1M(T*ya#xh*ycL`@=5FWJu7LzthgO7tai(N;5Nv^0gX!nCN91*icI1vr=)~h{wBnH
zK;!Yl-1Mk(j3pquU%7Bv_kE_ECBe}y#};zi4`8Loto?UWEaad{a&G@;fwOgkD7TYV
zzNU#oKGL5siJ-%+{hpg6oc&;SI`Nmtuh&bV at mKNY17vodxGj=5SZCs$gftIb+cIuD
zWI?Y|Az}1mz7K<`WmZDPe_Pyl%C@{c)|t0(8k}(ky<w&gUv&8{{BOs0lc51vu#N2`
zoY0%ly^3j<sLv>K4Z+;Y07Jds2l>yGqqxuOm+M}x>MNyhu*3;}>;tX55PfzwT5(BJ
zR9V1AuuS{ACZ_?eBTDDRS4Bs)|K$SYdJe(o7>1Ql8po^glIJGr at TwEQC)*?)jhkdl
z^y~`*h6#YG++<(_{mH`GTEfM}MV_6V(Q at JRT#^AF-;y7Px at w)Sth>2X3bj-`z&-uM
z7TwigV71z=Zu5inq>tw?u%!9%M2S{C^!#b!b=RQmt0em6H}c2OXNjMzUw4C3R<x`V
z?V-#3SarJSK;G>&adQHZ0SR%^ru4TcQ16 at M9rw8vQQ*TlaL=OEnE9jQP;1bl%Ly-w
zngnhto(+a_37R~8^oQvk53`Fn^qxkZyd1k*zV1?+%m-0wNC-rI34U1U`Bh%ULTCV{
z5sj}93r3PbYw<^d(#&7~+y3{qS^Nvx=pJv+!1#3wj(BpJP%(xaA_7-(!(|VZ``XWN
zz#fEyc=uhf#MVxKl!2L8SOh_t>&xezQ|2oZ*xgU3oZY|FVd>=~x=tI73AP{y^FC_!
zrjniGuduS0_GFKzl-+Fl@!ijYY?7s`(i!<5{#(gE_M>)OK6#i5NoEn)+gYhpX}5A<
zr0nZ{5QH8(3 at ERXb3Fl>zU{a-_~CH at y0@BZrU12g6M`$dBG7r%-gDLO<3CNbe*JgF
zHQKhOzIoIrWzr at B=)(zTqi;xX(YJhbn5)Da_=K)_i92-YI$xUn`$|LJQDu2{55pl2
zO}a{(OhK%19TZ>AQk?}qTxXu1x#&Z6`l+v3O#u=2FS($pA4bSyyU*}k5)NjOKj}8>
z35(RV+VdzM`4EdN;olQU$*?&u<n#dYfzQ~vT<*x_xZ#&{3!Rj%r}S{2qN+GCZP&kV
zWyp}CT=m1vzN4DR#x5I2%*UhUH*OVme|r`DAQPrtm86sUA~txv^QQ6JnOCEWI^<f1
zn+_FODN<`Ind at aiLsLF#etO at u<blYfyB_&FX`<$ePv<)+9HET|l%Tthe*1H#v-5H^
zYQE^cOo=ASa_#s31KEjN=;@<pwFqg8)S1H?)d{|rm6g#x4C1VJlWc6%9x?zoTeS(c
zTr|Sq>pa23<3;fNCn`%)2o54?ANC4{$LAGq|Gm{0|0jy>eFL`vyj2sotShYn^$CAi
zji^990Y14Xg8YQBpeBOquympwEg}_nlO--Gd at JTjO!&MHUi9~<6f>*DbpW4o{qwGX
zPXd-^Pp24Gz0duVJ<VcuA8HDSwY!tK6G|y)H&n45H^FOP`f-F@=7w*F at zi`VW>rMB
zBz<u0NWnfP4}-|#p1YqpBXGGfsXntI&iZJwW$o~<vKUNVnWC0~6qIS|mg?B at 5dXB2
zNQFKiSGN2$4SF7M_ULoQMMV92bz4FcUgkLQZZih9(T-$><Y0`>o^yl;j}~F6AY>F8
zPD9Ht3rEhsIrMks8_6r|ck^(Yb&Zyw3#P=Q=?0Mt*ogw|#m0*1zk=qSuf5{uN=A#O
z5Fl7dNlC+w1JEMg&dtpnKXU7%&|%66r$hqCau=fHw;L(69cLc&o8oHb--;$ncH3kB
zonc2mfy7IszuT)!PjO<x at qQqVL^#Ci&FjAP7f82Gg+pz!=$rb^fOl&Ko*uYdFQ*20
z5;x*&A(w)Uy}R|6S8v|R@@xM_B2-qOe8>&lEx8!3PTh>kA)02Q%(W?EfF#x3Z}0|0
zc*4|7SAe7+w5`OJosf7l)(naVe at N!jo|dkD2|5!NiXJ!fC##yxr7xjw77KTyv;D=L
zQ<!?Yb~&t~Ar<TDdJK7YzrUEC`(4j5-1XyxPjPD3Sfu~2x&epvK at _cCoR<F2xN9N?
z)<()oH2e-Tmp}L`&nyGJ%u~p_Z@*<5b?fi at O@>K6c4dDq=(6 at hv2G1FJ0UXspCl#`
zJBxmhyk*?K<^@uh544%nr6z3UUurPS9Kfv{qyw>6BP!!<`!OHWa1b9R%T*i4s)GgT
z!>y at Iye(bk?uBRXc=CUHJ2nFrER at Wa{6GmA1(P!3w#skwkGOooY9ODzCvWuI@~oKJ
zXV%zjV=jT<P>0};_o1`~Kl%1QPEB7q3XKF%=v(ji>7hm7_EndKwuXg1-s4=opwdKM
zKKa|gBwa#wwECac8ltz&SN^RzyqFRy)Cyyp{hi7E{s)-H>T>y6(nEk4_yzJ_1w}2A
zCZ_d=pxI-A``f2+KS)IQg%XVZ?oLY9?t}B at wuljY<OrZ at fuB$I^k1Qhj|^06ea!~0
z40r1Ps$Iy9cffDzpV2F|UHuo%{YsB7p04h=F6B7wWfI|<0uZ+X7rwSu`yg-q-E#JX
z`GtnL|2b3GO3=K(ws3@}Q<Iy{!15n|Y98C%UXKqA<VpRcDZ6TzvM%Yx${T|%lqq}A
zd!_V)wGZWIuU^m5-|6eFr+-xDzeP}I`w|nj;y*p2iJ!p5{PwIz6_DRf-+b7btI^`1
zlnY=PnhSkV67M|F4!X(Rj>)3l=^Bt4iTwK2!VpiK#_+xmwwI%#53q1Y(m%N9%WN4Y
z&oli(9W4?2NHt;q^t2dR2<wi&&=^>WuI=N~kG=XlcH#o9>gA6?7$cYq-4Bdtl_#Eh
zXw!u?pyF7r at Nw;YuPGTX+c!mnujD|~kc81S_Z-Ofza)#{qR;}u2NQh=KUgWg{Xe3<
zIxMO$>Y5TzT9EDr5s)E<PC*)^TO@{*?(UF~5S*bwQo0*ykrpYD?gr_8kH7bOpYKoS
zk-2m4-RGRO*IIk;tDLk-Z#|6r``wE!Jd{5dORJ50D_B)_+llJ9gPMKiQ+)Iq{evEU
zBu!j*`1`ZWwapSpgyq&b_ at R;EO)tmXsB+MGsh~m3&m#(4(XYEJvUl<B2^1gh18ARV
z37F6v`X`;$G=k)Hs~LB${vV7SDIG|X(>nX<CYmDu74~lZx6W!C%>!z-m!1|?YdC&W
zzJb$j|5Q$c17;kJ6okV(O at HindN6UAZq>TJuiZM+7MD<D46i=I#nWV5(qJJp2$Q1T
zBwjVc<q^69Znoa{x)+iL8suQWpx0H?<ygQCFAvo)rrg2Am{MuWU(4I`t9eq6o3T>L
z6jyU@*E?EgD$~8oO1+fWx=oXC1EG4Pg2zUvx!i#jo8#tWW5dLT*Yy{xe-sBX>2WNZ
zA1kKRc24De=~sFOdzL<Zt&WFw6=1xZ=wu<-6NVytH5)=3Nr5yiEc*?9D)7KTG^^_t
z(}*fSLZG at fbYz(L(%^gCqKw2xEeXP}i>^i$i91G^BYK~ZB=DCo at D95gJnpgKcH}A6
zU1Q;!0|$N>YVPUkVJF?}Rdj}2U0m&V%ASAWB*$9|Bu6{Tt5EOimLKq9lETT|A*8_f
zq|n>HlDYvtH2Q87WkI;g(;pvxALfatBKt-g-q2z9_eYCglX}z4#Qq6H=SuBNeE1Xg
z(}!AaCtQHexed{oD3c=i*!*<>qnIMOyCuh9iO|ujmwCoGj>-*VznggOsU~AIsWYA<
zKJ^m*;9{7biYjow&Mcq|ObE*-v$8pq(YS#J;D!)%qCmpVEe46+K1D`^ZNxpZ%JCU3
z9YVqE(;R!f{<{*<u{M-J9~|zgA*{XT#qnRHPjwa+`F-y+QEk}P?|d=~MGHKZ<uSn{
z)y8}G)>v`7P+LaL&1NPip^9MBfzI)|pS-ZDuPC$W3-#*{!^QG;J8$)eb4LVLmn4W@
zRcf&LUgtHel2rITzh4`vSnk<A_{=mVp!RM1K#XJ8iYDoYB`NxX_x2;tzhSBBe?>*E
z_OKe)x=w7ST6lkRYuvd6Vy;KHcZ=}_T0$O`ZFOBgh{YWJ-p9PYk;_#7K=6hXtx~(T
z`~L4CUE>)SNZ+2x9vygLFSjh9#Sr=`+8rbG&1Sy)MrM#ryP0LOt8xxjgUnk_`LC?N
ziMLnpcy$KG0{f?YH2#<tknY>+xd+~ZA684()`L$Xq5qGZV}C1E~@I;5L|PR^6;
zON|D-S<mPIGJ#vnq|;Zvb_kye<YlVOFaw`Uzu6bdLeJ7G^1W|Glv{B00$7WsYz9k|
zvj45kBiP1Ye=#!oRc>s at gWt~@ttNyh#hjk#4a)E*^?h5y&-B^`Y|Xe>NsBaTI4L<f
zDA?=n!`U5Am(O`qzBE&OAiqp>M!icm_pS-e>_T!)3a6MGg`YFRe{k|h6t6jlK??H)
zcF^kx;?OZ{sz~};ljdil4zn@!G-6n!LVKHW5_k-ugiEXoK7<B_oiyFtZxNPSm6dd`
zzWV)=$BY>Gipu}a{IfY%q=u?yra?gRI+>uO$E{9EV7^{g&LhUxfDoP_V@{H at co|=j
z*~a{GdQ-z~!z}ID&W>YWE<Ek~AYxo#tsR at 7hTl)Ykg15>{_F7FliyOKKN(>bJpOgx
zno2{0f{-aid at 0pQO|5+>#Lkw}j%E)094SfsWADk^4_EIas9%jrAnO>mlIatnkgGZU
zQI||Dh6e5EfmA;|I^;-~<R^D_7(wodHl39M1Ge-`eQf at r-}BrE<M1gyw7UWUDO-nd
zV)P at oZ0GwYXyV?)%t)vbMBxnfg0ir{b^j!Nc&~NbYEN9u;f=;ucml5_K3Y|uFltcf
z#An at iHMXte7?SuNB&nqm%t^&f{1k%Nq{$`f?z0#h^tw7}KaWYHe)*QYUx|$)fR)ae
zzNrw`(faJ^J3}{OS(8T at D=YaZ{?X{X{+WCfQ~gIOgnr^sfoT`{Y{Q3qo)M##CkFiQ
zi?+YN=FYFHd**TIONuAfPV#J2nn+f+zE-sSQK^=+;G`3n=tV$J>W at j-t@rsm4}lHC
zuQy0d4R#U7CIKiDIQV78Pq at gPG?AbwxF$5n at Mf`er;>zc3Rad;v-LRrPDt4~;c%@H
zC498k`EQ));&xuLfOlHsK|6>(suE+!m7&sIT}syCFk)VL!aFTtRrc~JOJ8-Vr+6CM
z>R#A)1%*?$a>u)Vms3D<@Tb|c=8MCddI$tSgWLR<3P_&sYN}KRZYwqTQ(oAIoc}dV
zht7xONRd(P^J5!P)QH*dM_X9^C>Wm*N3-f4W>>v9UG7EYGMnGgs<ij{ZKHO1p*#^<
zS4!3Fjz7j5%HmCcLlmfKdwca(@41w+G%5NwOk5m8l9A3;%v&UGH(G3hF!?s6cXh)T
zckIox$vhAcUE{cGho9rKlv;b9rg;T+(;E5bvIbitv_!KkyFVxPj&~FXj}^;qd at i6h
zV^q-*%AnS|5tv~1VG^Hnjnl|8V~oR&C*U^3Vk5hpC1()(0 at Z*};l}Et`PEDAN~y0Q
zlvlmsO_2iR`w)l%ozk?^efZ?%IN at k#eNaWfMa1Q=i1*~F*T2UXqT|lBPjQLm&M9zI
z#XD$P&JVg at bU5<)Uu}5A>S00PVvrr!#5Oj&!4!S-1>3hV({@iZzj*P8jSIstE13bi
zUl+(*URT_;Ssh5-yhzg#_1<hUL)P>#=1%wrJO+7*;re~Vul452CnjSTcb`Klc7;GC
z|EHuRfXRn%O$U}V-joBjXWR9<)G at m0y(Q-!YF&C8H at 2yswo;og#YM4 at Kg^|7_be{p
zA6=CZM+L8WDZ68+Zv|6y)@J6{=9W6Yn6{sfnN*y6i$M3k?lJa#V2MXkhemIZy&}Li
zl2de{-qmrJq8M1fCjOxNdm-AS?M&9tW0E5KxzB=Y5&V at p8X@_guMPB{25}~OZjr8O
z0;u}47BC>GWa}|qykip+v6&ASU%yk)gcff{8e;Ul(4qTT=S0;7IK3#^c-|rVEpi*p
z9w$nWq5)!-_k_^j<=?I4u<WX_3L*g>;9becY^{EY6>K8Gv=GGYD737Up#RVg%Dead
zyJ6yQQm6BcpN0z2{)7gRH&>ps at p0$;tye$oCD1^c+0uSNc)Qzh&|RFwvfSKFTB^yu
zvYu+vmluB+Y at s((>(3`L9YKTExNkJQ;u3Ia;Q7GS`p8z>wGYX$d0KtzM%QT|%=13n
zCBYdbG(2u^0C`RPT2RDi+C$Ctxnnod`=z|S7SHtr7N=|J2dr&5V;KW>)I7By_gUgC
z0pp;t<388Srv`tRrObX(7bLi}Mq8rOzSn2?;{X_rVM{_7b5)P!GSb?LT~zL9KDuvR
z54xqTL(%#Xa-_9|%YdhnrORQd76XG%lll3^4k^>{$y0z(V%hzV?{^o&Q{&Tn{(%s7
z9Y^4{I6e{Odb?VJYyO7#i3JH4rAT;A^#|W}GM&9f%tH}Z%ER`9VJPfO0a`9xk~-}9
zt4#Kgk6jpgsQMt>oO#WQFxd;TCjXvJ-W9!g32SxVyui0##MEWJMU_kNwiB;54#kCp
z#o%Q#VeF19hJM8nz$tU9h>}jyC3^MUvIcOD_4WdcDEJIW$I+j2O%cqlM)6$fj%0+2
zc7G#u+p<<s?48Uvyni*1-`IY!l<j-Xg9B3ZPYS(fFR`qB3xrZX>oeDBpCI${dIz}V
zlxyTaW#T_`N_XIc)M*m-dlPqaA4POHVTe6&Jp at H$`Qolee~@NrKK?!MUdEL7&)YW?
zBY%8P?jw$GvTm7fry>?3xMS4VQ~U2Sk9X8|yyDa!%B^1q?Bgx_t$g6733!}hpVO;E
zcXn${bU__P5<aFx#WpBqEbunfckB7wTi;`WWd}X13eERhKsck^HS)z-ya4Rsuj?Ts
z*yRvPNl&9AFQ9SK{EzyQ*_0<X&@61~k$pttuqOt465zXssX^y<fn`;caC2%Pef)9y
z6_U`lED*5m*LYp6c=XMzrD_*WGB!Dfw}|)FfLZ9bfzuTe$;$8N9^bgJp>ZFqf_LNd
zBl+QVd^<JjXntB4wE_1Ik?pmFmp at fV?_RC(u$k}u`7S55WkDl^vUS*seNE$wbYFkw
zsJM<e6N#Eg{5+&Q?FJgd6f*uXb553!c%~RT(nklBm=Civ3CP@=MHXjvvXC~_q7fya
z{HS~FY`1&VUHniQWh!<PF$lYlMX;W|2!#|996^ncW4u{?cJ7qdTMAe8u?S#F$rgzn
zbM at A!^_dOSs9_#&E7d>>3W#z0VJ}_*i-_rS=&v;WSV*CFN6909Bzt-4>xb57efAEo
zPMdtP=O1`agG|HtzSvti%%Gf12p~JOVa9ECR%qH-8r$$qDcd;-^QKtz$|tc+4mnQi
z42--^R?Y4CL{10+51gWndsi=J$C6W-dNYY3FSrsuL(|xq_Z>PyA{U-z%FI-!hpW5s
z)Az?gu?s8*X5EL{^e5Y$=O%KfCh9z|%I4Xn%UR at o(YL0lx(%C}dAPF*h1O2uXzhlJ
zmF at fBaMP&O0X5?OJi)22uKeR|eQp`MLZ<%5(>cOorvwU=t~lQdmSyQ$otsL^<l1a$
zJ5xVU2moCI%-H#u3m>3J`ZdU1`Q+b(*;1+T>FHFZdJrPtT#e*xZEcM(Fi389o2kEI
zjx<Oc^Ry(f at oM4KMp25rj})Zoe=RX at PG49W$v<xRu5grhxQ1C>l**-e+-l#j7*6K!
zf_uh10exU8YQmOOc26_r(UZwc{#KPQCLtxI{jpVoq;x?_NXH)2PfCk+)%WojrV~Xa
z%QaL#T5|Ghrhg|Wl6&vT!{-o-&U48 at _F;-|%5Qoug8ANPF=F*5FdQO|q{e}=s%Goe
zUgYA~>Z5G8jQBP5x-I4uVLby!Mgq0RDuv5XTp)5&_6J$$RT=({e)c?39-s*~8B%cX
zUpnJmoigK at M`o19LZK)eVZkR(Dv?Pq=k+-FT3Al2uUd5mMf4-<5KntNxARjS!309}
zlg at g3L$CEu+}I2wzovx#koADEz3)adMS;AnrNWH_S~tF%tG7oAEHCHWo2`KjahNhE
zbxxHTjQ{-kbX1G)D+4_xkSBrI>TsK}<13&{Xi#q_34_6gZIv-TX5k&`p>z>iuowIl
z&D`vCGiofS!1|)Z-$?HgHHR`3dex5C at 3hp+DKh$X$Lw<v8K(;2E#O-d2F%HuW%q_&
z=P4b36ajGT)yq0N&XNy|DKm!X6=x`8K&U<w$ih2-H!{a3m|JYrJd)(zcZKlz at R>Zh
z?-!ogFw?f?anaALDlCK%9i95o00TpRwZ&jbbzPnLcsF<GZZp*DFJm0FsL+nSDe1fJ
za2#;IW4t)M?+92_GbuHo-Q3u<4Gj!nU*vr?aKJ5bA%gc$3C)p?=+mU;Q6{vVDwPD$
zr1g*=);tZ#kLxdfQ~ZsIY#shtwf!&;$dqr2d*UW^cOw)ZuPx+{Myx^|DPgkY`6psv
zLI=1-AVdC47OjFhLZ0c{eB!OKp97P5!%b;1QOs-fpm9mimr+dou}CKC{17IycJT_z
z#EJDKM^|H>o)f>AU(G$+NSN%(*6qR&9$7ba;|*Fqi`=@y8!-d|0S;=Q9+hm=0Y^wj
zfH)#8ZS`UxQ14L{AoW>P(j!0NU$s=va{Rp#0Z~-G3x1Xq?4~D*5X|<CY;mr^|A=%7
z#86ZW+!*0$Ah$3aN%^E>tHJSzAd`~d3Dw)1IXdDOSa&&55`B0DiqXji+`s!K4#liO
zohrUX^@y+Cd1sPfR1U85DCEDP9LkKUN<K_%%0WMQTG|Ay`l;!MQ!^z=za+_w at KlP@
z0PslzgRjm?5-Vp(uNwDk%CiW=xvVWR=-Tjr1)^6eHtU2a5(wR!LwUP#168(+v5D=U
z)!$8GtL0ZFeDUH1NXp314)5;nfGH*n6zJ5w(dr at We`jTdIX^$2*Up74&0$cFow?bI
z{KH$Q_u~9Kx1xe8MGSUbWVpK28S?MXJr<*Li=q`64{MG4eK|)~k2AIGz(nN#=O3U}
z94W!=axIxEcI9`nnJ(3X*cfVUK2I808q1MpCH~;#4g(j9TUC<RvuX9Q5K0^B2Nm at N
z1qIF1s_(F{7 at WQps247pb7e5e09C!ki8Hjw3BW2XIav9H0=!fjLZyQ774ibjdsbJ%
zk3KC1F)8)^M-lFWZ;DMOYa&;2c at m3ioX|JXQEA|B`ThI%+qrXAK9P~3f3mF_YmE0r
zy*)$PaNnYi15V;9bnD<i*1*7EZ|wE34n7*|Ck4;_y6GK68i!-$M at e?r5Wn3_AV~N`
z?k`t$o186_9+_j93hl1{5|yA_vY)Gu#lq%OmIg^KupU*}PIHzTw~-?Xdih?IvhvMe
z494a>|MUc`{fMb4?aTHov|*BBcmWygS>Z2OxF~&8k&;%8$iKtk;i!0$&$}Jft)NHA
z;&7=-|Fzi{c12}5RZPw;qt`C-DAri=C3=)(>Y_v?@ay+CH#h2F(S!Vda at f(eCB=-6
zs78sIP@|QZ!NVI^D1aB}$v^Lrhk{Y>_C(?CQ|R*BP$5;4>h0z at Dq;5}U_ydAE=ec{
zg~EBdxhtK432C;P>0s_9L53Ufmsr`_cDMW8SZY;iPrCs-#@<X7D)0l96~9lJS>b-{
z3B+5+EYTzZ-Kf0*SvCr*L^zO!wjb3fW#~szOlZ>Y*bsT-Ji{F<FdB7HmK|}+8D?@n
z at BhF(`szqS)i2CK?{(n>xCX`g5RycWngmecG&Bf<X#-73tGI*H$HDHnwY^Qo7Z1)K
zv8?#C!RSA3Z6n(GZ#s)L3O|l+n!T!{#ax2oHa9n0YVO-`woMOMCeLge*I454zyIT@
zea at Map-l9V7=GX at 7BA4Ytqgm#E005_ILK0enNF6Hn)SvKbXNlMXo<=i&$#Yav10_l
zdd_d{IOJple at hu?&`XL?V}35O49BY<IIo0rr8QV1oS45-vrR?`S#$NsCME5Uy42fR
zGNXFG>Vyp>GC`eIdWweR!7l_AOiCRD%_P(1m9;LDo$nD^BSSKAH9{V)M*ZMTR5`Ez
zXvBSvEe*u-)AMtclFn^&@6w at O1bpDsL_I5iA-h*;zx%9Y?8)afW9b^vzQ=@C#|X8T
zy%^R#O0zLCIMVakzKbRw1D{v*jMOK&)Z at m@&U`k<gX7Y+;P+cKvkKVcb%jAyu#TH#
z<P~I)fF<Vo=H_cAu*`rFc&1l>*PYf7SjW9pMHV3S8Xg|5v==UjiWP_}Y0fOL{>Rst
zn3x!P0J{nJvzJh)uG<Ui&C0QtUFIQ={_1I2ysy9bJa8ZfTNPzi8Cv1*=Kg1m$X4!#
zld)BP3I?_~5SC^m>r(9P${bZqu27YRXLn+urjNr580>kw$I|eTSuaH~yXozQW&8Fd
zzK~(&B3X1$C~rKKfWX$S$VDk9zaPfX6kw|Vy}=KEMv4fE8AmZ1rSBS|sw_!9)2x83
zo;)L0=%l at M#PlYjvsimeVUG#(jM>P`<0lwa!gb6+ywIyg^Yio58ZEXa_xAQKDYD!f
z0#>2vWPKpi0w*1y6siJ8Wo*@UNE(Sj7^DliJyA^Ih_beiz@;j2=3c*G)`+k9Y}f8q
ztC}9&Gt!qn;YL-y3v54^?c#M}5G5aO<r)P^3wrx&;DWGwN1I1&H}O~khxGF5n~I3{
z<-}M9!%-KegT6CEx&8@>=S%0~{ky|X%ddn+#v}*2Hyzn^hVg|M0l_-)_XO|fPG4M3
zIa^I!-X=vA#rG>_;oyIj>>l-gAdIKEqB6flhUP at rrubvd>D-AQmBo>zF=((k>PYr0
z2}97a_qaL&G2(7LT=7Igc>`T)NLGw?@5#OI+0ha(?9uy*sM+S4rc4Tqk)CTpfML<~
zUkl3Lwt2YDPOSO{249o?Df=ZI91dAo=%eWY2L)!uG-?-QA{dk>z*{wAvv8ulxxOBo
zo{sPpqnX}xGy<muSh!#ZH;d~vUn|-C?W6o97_6L)*hfg at qJt%9NI$n-OT*slX{S at K
zTgnaut8lzj!hF*wj9r*UST5PErr8(JdQD(x at 4jT8)*eBVn$^n?5kRvK+Dx^!A+v2h
z`%}G6;CnvC@{-$8-1*A(_<Pmp((3a7yr3q^$N~Y3ob%+*m_@%za^N_$Ig-*rtyh8n
z=LK*Wi$A2i)%x?f4RcQ5p2;2e9#dTGnyeO9|4w<61^=BTCHrIA*oKC<-suXy083{F
zcfO at ehK>)XORC4kZdv_U=L#aeM><FQAvFC|1{ZJfg}714$O&?bNw7!55OD9si1e}o
zYx<;t?3x-v0Bg$h1rP-}pwk9GHBnmrUEDJNtOO1Y!?JL&sK8Uw61CBN+BjwSRDN+|
z!_w8mBg^Zs`~xA2io`^1qgVvhkRAUAFc5s>M8$nnLmZ+*HTf@^$U`g`ke?1#F99uM
zdQ7nE4QJ|V0Ki#J+RXBFEGaXmLc$YzSZ}S+jad)7odfWjPMKZT79$7e#3Km_xYfL=
zryE)cd-rya3R_b1>W(nA-Tj|Fc%I at Nqx(D(`u#q<06xa+C!1L_4qI!-fxt6f@)F)C
zjAlcQ#t|(<`%U|erFW=MYGjowL8~0$yd^6kR!xYgEIDubsS5ojbx?tU?vy`-)9&gK
zQ7r%I^}NK at D~So1Ya2%og4W$q22(=o%LFgZx-%I-7r-HKp!0^6NOrOulhw-FI*N*n
zc=U7RwdEW?08$`OCSe%p=#D$T*odBll^oV^JSQgmtR(&=4F3xv<|OG>1|~Z8apsS}
z2(7C8Fh?}KIS&~?PasS+*@3bQARF;3Clde*&O4z-OG+Ve!Qx0*NW6pu*k4Y0MUYH&
zWsD)m0rvB;&bm at l-&a`tE~F3Junb18gv2gZ4BmRmIa%M^H@@39$t%)B$`u6Ux3`}a
z>E9bu<Vao$f?ChL+-xMA&Qj4$&GQ*J6$_4vS~zhmT3rk;$8czcb+-!>WhlD6am<9_
z9}Jnv(&FOBpgx3 at lCty~u$KSa#&Z4K>o39XBIZY4zN at X?zJ^UAXpsY-teK94n31A8
zHyJ*wGelT9+v at -lV)F#>5Fc_qhRjj19vch!bf)%fY^HzYXdN at 80MGRmZPGwbiRH@o
z$XYXCNaSzJwiDt%!$;OGm|70P<nH3Zw%R(rNx;A-e-U}gk^UAl+;T~6otD~j-|SL+
z>VdHRPXJfBf`iOSctBUis9kUG at U(<O2bt-b@*HHuLeA22PpVYK;aeWv+egx`t@*ug
z#n$L)tAz-xAuRqpMqq1ylGSt^J!VsvS4vii{EbGUQ;Ciw>?jYZQky}Fm*GH3ln;W{
z2~VhLXlf$+SG9x2?d{_O%zi7l`w at 6F<zCERiE6wzNnnuxjd6os<j<JgK*_pLb9r7~
z9%`{>37y_?Q!R$lO=jY2Y}HE at 5}SIys^Vd+?Ls~#nCzRM<-2{o#ene6MUqEwSM at OC
z^=Q6t{>^13G^K(62s$l>VS2I-<vvC7zy0m78uj-*$8?YjVj)Iilr9>jF(IBN<5I)7
zXrEbT_%M+Fh=EiciN*1)ZD3B}(&!j at MWL)^X;s>QC`+WTor1ko@?x-2+oFWLL!WAd
zf6Q4*(7LjN45sbIj+>3EeT4`1tQUOSDH=aV+CjScO31VDphvXAAI)#$P3VEC;esy?
zy$>pWGo<8Jn~Ph_07g`?JFpM}eF_Xh0C|H1YK_&VVYeAz&Tv!Gt(_h6PoI#(*(`J4
z_4PiS4dE$Iyn_|w=Rblg6_g|tvMY?u&PFLQqt4YA#)g+qO%L(4zFfHb?oCw6$QL4y
z?`a1MUvyge#qmBJEuGDc;J6AnldU6}C^V~dOaCVSbChg at Djuo?a`Xf-f7q(P at nOXs
zI`wW7)(ctk>9Tw5DUKVW9}K72Itr at Y9AZ&!o3{?0NDEU}PQE9T!r6y&K?cI&ahiiI
zOG-)Xle+Yn8jo%v$iI|_dkXpeu@?RJr;n|s#oxkbqdm&+P=3$74<>vB5u#zPS^iqx
zRs*j)V!)s=xg)v66ODkWK2TLV9*@M~El2YOgmiun;}3}&^3C1{lo^WqtAeJoG92LH
z`H}GPq^Y5S1oSZ~RLLNJl$d`c4jh+Yq8+q&1RizpYReipy1)U%m-XRLgWP817iGGl
zga<uLEuHjA5O}HMC<POXI;Xhj>H*MFNcTBt!nt at RZ@2t;50<F>zGt(@1^_Md6>+R3
zkZDzQ>HS+xezfk*css4*!K#@TS!29Z>S&$`AKvIjWh4zZ4OY4hYB+|V1mfFHY_483
zh+$X-l3bHwD^AEhL&TBe$1M!=W^dQ(tTu37zRb3cr2mFP1x<k1p1dttEiLIEj#=GY
zt)I*aYCj*1nBV07rly<jBxhM-#!Hh<n}b+)76e{jka=1CO6MZ}0OBEf+mfC1W6Tqc
zp&cq=Wc(GRGQ*~)AiXZN`SK!Va2 at oWS~-Nv2W4M9t<r(WW8hLs2xau0O`C`-{GzK`
z7Ahq%_Cy{Py`bc5zg&Tad|n#rwSEIZ#h%8DV__06hjfp>i=xLQaj$251CDJvu3uI6
z0YcLnp_tDCiuxAu(rCPnx`QqcL%z$w at 3X{(jgZVaq7_AXYmV;&nqNo+R*OS-RrYm%
z4xWvCnmzclkH%Dlz=T|tv44ki at zxA1e1H-*mz(uQKZAOoZWS$_iQoYs=A?>V58SUH
zy at Ni_tJnCLRW;%YmzMG(WS?E`j*y%D0nE`1Ndqyt)v<M!yIQp+OoJjO-oxM9cADe5
zBk&k9RDd^!O6#G0rdX3lRuZ2UTiWh-?c-6g8xCA*kw`4gMp|413#rTTFc#Zw1IO28
z<}ock2+shc5Cgkqy}gc;10h%l*8+#f_kMIF{Hi2}espmfM6aA+=iYr*tuOJ*@1 at o@
zzt)kT1uiw=SAO2R0~@p+F#ygf9D2bMg{tv8lf1+hY^j4<>O;Q*rP?m&$>@=En_ahy
z_LN>k&ze&PMNK)sh_Ec57`ileGwMHH?LR(m=<xg1A at ByHa*P988rZfTvf3`<>Q9Rf
z9tCKb2yJhS$lJJm&DXZ6%T|}AWkg1if8F)=aVSooNcV}SWu`s#s3|oxaGD~%AL2=d
zUfIb}D)&@3 at KrJs9RXtwrBxX2PPzm1SW)Ywzv*T|Y;v=}#ld4y&8N)RZ{n(}+{ov_
zz0|ucPBt$nUomwB4$JKH+RT8(Bk5(!tZstx4FlZ7Oy{K!0ZD*z$R`h{3#P49woBm{
zu9Qqa%!d#y at 1NcgD-gM`j|@qDV#+lAJbEa9sDL~CcYTnh4TII-DVij|v7W;0c#n)2
zW_Cvh4ag0LWo11;g7Nk(t&64Ak7E0U_v<D^ui$ww3>K=2nncEd5rvZJ-N;pFlAa<~
zs^Ro-br%&LQZ~+OlGQYB`KQ7H^NIOnyzU#CHCO29&~Mu^4z;$fS at 9x?Z&aRxL3`#=
zs5wz<7UdmZH@)=S3%-8+YJUi(P;LSUCcJC9{i`#Z7R>@yJ2lhjWajS3FKWV>I*5|N
za{Fycu(f{w2QG<_x+QZoJuf+qjCyj}%fqDF+Db}8Hl|$GAMDsd)Wb^o=1!D(pivv(
zq}+^n$zxMC_$W*(&5LV>g^2Mp;%}nlbo!!|RDMCay?AMYkS5VJXu8c8oOnb&tNPMM
z#P95}Fksc>!@|uwl6FC(S}<h%d<gD-s2HL1SDI(;EF)&}!#jV~NixuSWRNJ|`gdX-
zouS0YrTO`#`SknxvmqtR0A<TV{k_nXyMzL^6=>##_t4L^GrvSes#JI#C4wzqhO+;~
zIMt64-Q{X?>y4N!FT}ZTbdgVH>UPY)c}NWGa>L9$Je|y+v)8kgZ1+z2NFd8oCL4h?
zY97uwRNyB at 1q;Wm5b-=(3Y~4~{XhaEqY{hrDn;tly;y&+swT5A+tN>NN_b;Q7}1v`
z=sz4qiKt4?YT`zCwT`;(%#6tKpc-!cVjnCFi%oic;U<EBb0&hujuq2 at U;WAZN-Rr`
zvVRr{38YfPhD5<cH@>Lbl%69!WRR0sIT1D9BoRaf?xNI=FfA+yw_<4B*(?Rz)7au-
zJfKO at BtP=q$1|adOjw{ic79v*E5<zeL6i$4cl0>(xBFk14;_bIH7}VksN_;?((50=
zws?D~NlE^RBs}Nr^9wy8WQxxZ;xv)*u34p0h^;%=^~Z4yWi+8;SDWh1K-V7~P0a$n
zi=)hToJ2R>g$Oqgr|UmHLEZOeoP4uI|D6;7f)2sSzAmJve|c9G2`Z+{r}Gxi&d=+i
zGKS^91sOy%R&T^oUKoVS<|Pd9mYG!P+W7=-YPzi%GEO|!QFyUs`gk=KqoKAk3Pa{Q
z-u4VUhuoti%wC{(=t(w{qK3}G>Rl$qep7n`_!$yHLHSWX3YiC4qESZOs2|hmD-1E)
z&cJfBEIIenq;kf(^4wuxYf;-kI9WE&@{gY2qaja~8-1`COtDbDM2j4V0`^5=Ru_?o
zpmg~Cy+7Cv+0y7A(c12et~>V&%B+6MALk39{noUZ`9Z%d<(1a<rbdQ0KgDQW+R(3W
z#hE!ZAMICkZ$A&Wy-86iRr+Y0HiAT$`n-h}^CRQqL`Li4i2Yi+{zN84Le%UlsrEw}
zjGu+?mY7#2eV52y6+iwwqB+&M_Z%@OLZ2;`AT2V7bf~nACe)b79Ntt8CORyxj2%1k
zE^tk7evs0mWJg}dF#G8x=Nela__zz5H~jM&Vr}fCb?>SG0bd^JEFQ8{>aRlVndV^O
zG{y-qcK@|9eOjTtbt+Oo3<E0`jM>QjmHfs`CB4#o;O7wQWs|YLL|_=|7 at Swha{k^h
zA6zh at yWyibTh=J-kVj{5sNkk`4O<Ph9p1Ux_M)}lg1$c_9e44<;76vX*@Na<1SLbJ
z6C>G|O++a}%~&AE=A_K+@@{#ZY}*1-s07_6YS%fV9%4>rwb}aUdo2${e;51XX9Xrq
z6d&#sCPkLO%l6!*PD9 at aL(bGssLGm8d8w#}Cx=3&$N>>970GepM}NhuV-YnXw3;7{
zrOx8W5~6yVHnc#h%6}>7oMBiv55o)`>f!76>Ch<4Dy+Gf6I`3LdB*Tb=-OLh>&H!G
z9jXLPYS@%Mpu;5;G46UP- at W+w#jW)=&%vyJwqa#{^MYQ*t^d%2M{&un{>M*U?=0?~
zTHImA(MYrpxIex`Vu at pPKFI<>r|~E0&LBE^gbAszPPSO{M_)6cT9!h`m?k#ctE5c?
zb*^(7uX4?sh2qm6N}!F8t5vz6-x?9>_e<Vq-R|tjZ(3aPEdT2Lw)j&pVe<1pKf at 5#
zx~p=A*q1mk6ogrFU^sD*y`CVFUVq~LaGG^ob!gw~Msvd<<|v75`tueTFu`8$LKGnv
zw{rZ?ndpBXakM#I8ob%`(K^_hoi<<MPb7Xg9g_LFpQe^HnF{;j7pG0jfC<gH$IJ*#
zSSB8y-o0LW6Svb-Dy)g^Q}a|TW at Lh=Hcxx5#yo8Ye%dXL-JZ at hRW8;}>4k8;`dP at 6
z^Of*OMg*Y<#}Eqq2rE}H-zLJ~av8`O*gSdRZdDD3&rU&Hasw};Sm#9GZ#y(TLUepA
zhiJJUd`ZJ2Z7`0vP)FagQuo9kw2~Yy_+rWE_K%I>qhnwsFh9Pf1uUgZoqp%|T}xHl
z1OAV7<6q=2iH(3(Z!3 at 7y-toxBNl3t{{)9Nb<p&9r57pi?&bnjUpg)Y$>ZWQyX7ku
zNQy|w$b#@uBtLe4`-T+V+m*a<7{!wLZK2I4Uif)9Wz(w<#LGjFQ5h4HMJHPu7K9$p
z#gn^TqKDdKxVj6wm;A<%7uZ at eNLOw?c&l2r<X-sET=|NjZYK@%51|pLW$oj};-i31
zo^!3jza}|3*p#I26QM~CB9Z&3)#P6(=-X<RX#MgK4L70Ii^99Bm|k7HKR38s&!ngn
zH0fXNzNx$;S?m<WYYRm@#k`(gj&*1!RXr36^}A^gjTaXWjCE*4?mc|qyT98RU2>UT
zdwKbz;wYoVKaeC|7PA|TqWoUjcPr&NcjLuN-{prk!n-u%h|3vjN=l-}duf{9-4x0m
zRFhi~>OUl%1mvCYhUJI*LxJp%jGy<)zfRg*)`;Ige%aKm(r+uUp-Bb`AGX%?!mG@!
zOGPD_`k1K^)e!0MP?Jb<r at hDZ;4!o+D;GaRsoaZwT7%+(LFykECalYLHIaoZs98fq
z(x?!iGHu#TRX1zMGw!8D6 at VMT8a0z_oJ3FHlx~UhX=Oo=6<yL&C)&it&BCjdz|k+_
zOVr`N#};`~-lg|^wA*X2JuYkh0d2&0V!MdOmvr&!*!a(VfFFT_k%`pZjF=roDP4o<
zBb$l`Mlp|F^1b;RdVg03+*hjfHrOkvi+9v<=@-biCvxSzo&5)WCb#PyD}@G}-+-t*
zY7i<ge=OJN3h&EXyu|wBx7h7DFD&)P?E!z`A#8MMe)F8RT*mQJFrury<@WEO(`JUp
zN}TY4)p#e7#1(M6$DNFd(|l4`hu-u-cvCozml-m4?uXzxTN!WI({j6T=pX00*>LC~
zJ`24#Ubc9axoN>STBCdn+Sn;M92vul$*)w-p4^FYMP=C20!xX7Uj4SYg^+R!p^5eB
zf!&b%m>^raoQ5dxzRX#%>kkK8mQ5BK;Yp1G->F?UY?|2!maMt>7Y*g%N=E5!$B!CM
z#v>f}{zCAne2HUUZJM5J1BJ_iQH8+kWhkqbS}gg`qBz;l61GTE5{!I%<Zl}PRzv7)
zEf{+(X1KGDZgbE%cam5+4WidSC=^ZOc5Uln!?o3QFH~*^B8)pz?{_?oKNV3-w?E(=
zceLJ#D6OC6vUY*;?Bk at YTQrdE(4nKFBOw9iw(Fn3Ix!JqQzx`xoME;9;spo&4RoKU
z1{$Z%N`(JP-O_w((<NuEH!=Upe5lwxSz^mB>Mc01Kv at vSphVnIv8ULNF*O_SdMNK3
z1u$Tw9(+Xm<DGiARsGiA{|ad!)OrSH)~!n;#mx^&LNIH at JI^mMzpGL!&2FegZnwp|
z at j?UNybPZdYUR=GE(y|ljqYK(TR#sKRl`J~krH|xCSxcTp5QE=tbmM+NvF<wmMy??
zw4&HjS at B%fZw>QD&bR7J!;N&-{OnJ`=-EkVlg`mN4mYB=@f3mGqxTf|r-T6^H5Hfa
z<%h}y1xeHE>O?@!db>MS*0`1XA-k^ce1C4)i<&&P&&fRqW^UIT&(z-kC3*I!Dz5Ue
zz&F=rXk1RRR3amsptjgWF-1j8jRhk(JwihsK++GnY2bFb6<k$OcE4b&T9_}KhyaD+
zHQSt}xypGB0qK{Yy|YV{8Z-o-_>(w>Cm|LpjQGZp*_LAM(_bF~X+J`5ztZGhPCbOT
zJe+2*exdsj;^Q>E=#TAjcl+#izhyCO`eBW*@#Ms$FKqWF!9}FB?b_0A#*@7LzQ)JV
z<HAeVWn=c}RrG5tSDex=w`rr8j+=8Gr|C|Y1RCGRHzY>U7a47&BMT^+l#;RNc+Jt&
zE1I-|x2)~AhaIwuE7Yz`5n~PahNbLYV_O_9dr;i=t6>KzwnvK>HS*SG$6W__ip<As
zmJ>U0b%mU9D|3?ATvo`p%uPL5Ut+$-TeJb%F-P1dyy>NPuVcNgeA_K*9Sf5NRT$%~
zPFV%<Su|iyfw<YdQG%1cD=IYNp~vPl;iYvW;j(I~p9P!jI8iD6#Uhyo727YY9u(Qe
zrsrZ^%I~@P%UhnjqN0=6SZhgHDge%P72)3zZ$`=g9Gi#-!7 at E@<#yRx57wb=9g+72
z;xXca`__9E!mLCXj>irU1lpY2(z%A|F8e;mQGBXqyXBHwb+F~(3cnZH7nfGh&DFL;
zlhBDL<X&r)=eN5 at _xaQ+CI;UoQ!yzy<pO<#?zh6HmxB$1Ws8J3W5sq$YiL8iJFe+Y
z!;4=orEH8Evrr7o=?l4Ag4%JAQN=O at kuHdv*^<4`Lm(2f4*cmp_K%`wC#EM!hDj|$
z167b*g_b6G|4u9uav5dsh3qzCb{~cAK7Vo!wiOQ4pXIf7%$L0Ln_o6H6f7c=)yH<s
zNlU>TCt^99f@*CDn<AuYv0sRB{O8)0fPpv5kW!b-<`<<6hcL{_gG2!-%pg`@z7Tc8
zCIX%ElrbmlhDPiPue-mNs at YSowPJpm#9&pl5|hY3mXI!MMpHzVaYD%#Ert4EX=m-m
zoKv!Xkw;<K>h?+_L5 at r)AP>8*o2e~|+T=Gm at 3Z@!r2Qn8dk1Q!_)Iiu{%ew6fFc%b
zaWpi3+}WyN6$+Tw7jZ)ah;L>CiTPCm!Wg}^0$%5?1wkyzpI307dAzeU=x%$=$eJb-
zw-~iVpzI34>rO9&ql at W9o%-RUjp at TI=pa|EyyQZugLJ8blC~Mg5rc^tR^|iAWD}3G
zxKzmT-qhU)x057yIT5}{l8L3bwDFivv9*c~onJNIb()xM at L7C1M!6=<ABn4SFaux4
z(Cl@>{+E|lZw~2J^D0KlRTh7Vrg*uaDL8wl5TMASoRlXsyn9O{K4Vk=l;%d>EXqqQ
zoU*F;FQ!#Wl at qmkN>IAO$#o4Ml6i2{G45G9N7j~669+;3Rt(ih*3}eEcV}b%HU{Iy
zobarj^bKFVNL8{RL#cqLz9{6>l&42?V$Un{8B{UFl1z6qABOf at P>pHKDzjDzWBCc)
zQuF&M=}v}R1-4Mr8Ryt0*LM($YN+n!;Q$L(or_o`NxIyx8X1w5S?nY^7rNh8!5sd~
zv726S%Fhqbtk-dkNpd19=b^&fhGLrx1mbo*O)m3&s6{6Og0;{c&v~<q07aQrjuyhZ
zZ3IPZZmjvO7eiSrCwK~O`F^=E^g%K__h{^F>?3JbSJSuf*VeVD<t#s=1j%3_YM~M6
z%=iJAtiaX6M(wn!IPtTw+mjwIP<T8E4Ciu0pv#HaY;OJCP#R%r5APwo7f;P=VpY`e
zBBn$8PrIo;cYY#6HZmJ3V7Vf~kp>rBFr`w2=^MXLN|&kc#SV8{8yb7n%{>%D6hEc+
zF9CNKQbZ%QrsQTrMakUnqjHY;&dbw^w<#06l{CPxkUpB%e!J^_cFmmSb#5UROP22@
zkkR4pYr~?LPGXs2Ll^rlpQptgW~WP at W%ah-6=~QG-8N+`muBxHwqn8Ea!_qt2B<q<
zx)Iws^VVKff^@?SYATo%Q{n_th>%&-_=qnl at k&Q^R_8cF-u{KrQ^T{eDtuQ)OoYkE
zKd54b$(a$5nF1SK#q_upZ*`DR3Uf*eNChoYHl?!;?0%4r at UvKQetKab<VDo~5;UMN
zhU*~;NU5o1RaI3LR|E3KzsuI>gS$Kkbk9AO=q%;|q^{=S>`2}$vs{X5l8aT*sExTf
z+LiADd%nCHD7Mo6I_oO2kj0;RfiM2{(mWH7-yj1HjU#xaJ{UBZ!cm8n>$W#E)`aSc
zE=d~BO7ui;6x$)a4rFw{B$lND!rjA%HO*7xY96jE8L}(~1tDvD;AjS?F6bG+nL0i>
zX|cb7CL-*4^j7=v3Us72p`kb(GBJ`6wMrT*i|Rzlwe^IAT`)Em6a34R)bcLEGCsK%
zj-|?P<!zIrwl%Zt0JoH-CZO^M&HItQWkSGm2M?1&8RfGg8vz<Jz!V7#a at 7(!`R5WF
zN6X#+o<u-Ez{ZfP_mfLIT2N&V>_<>s5GiHa(rv~KBiMsOA43GDr+ at z(8o*EvVl??;
z1`Ag;%{h7gJz+U10k9S3|E{o~L55)dJh+bE{}Pu<C=`%!^jV{G)#M={VTh5A!2Ks6
zhDp)6SZ>fS(Bjv>>wO|}_Df@?)eDl#Dg|bZlxYtJ_h8M!Uk)B1E!9q_)ZBDE1;k_`
zV^DH+-kSUeh&1d+k5f7hDzL3+kNxje^W~BBovn)OS`0bOHb*ja>+Q&{udj)3iC9*~
zf%ikLO#5FK2KG;YR1g_Ws~LVko6#vZj9Okc75V#}LATx4OWXJr%wv3!lNT0#KdleL
zV03qLTTXWwv37cI_iU_-!5NS*!*LmKUS$wmNJt>*ph(gN7A^Kq`e at _eu9GyD+&f|%
z{;2R~X(DLl-+Vh>YI!=wmJ1C-UuvcfRrtt?V}&F7r1r~dmm6b%ZjTd6{|Rkx@$y8}
zCx%#PboSD>3nNUcFY+;rlON+SrjZk&;Xld9!|-uMMv-B1<Z`dWFczPkyh$lQnX<;0
z07PF2HGn=5;0~~{vCUzWFOs7%^phCnL92;Mhea_Y2^}3B1363n^GIdcdaJTg at dsZ@
zs3VfF``&lQPi60|=NbNa-NJDwvXg({D%GwcNSKN7rD&Bk8q4RL>n-F)urro8LO}`8
zm_7rb0TjN1(Ai*=mouG<?}+BQUove>d%zOA3euXn{?@Uq=yCV-09Y(28Wv+N7Xtcp
z{OhnBPgp(KN}?hrHw}Z+-g`ZtB1X<<%3Urzz8by9Fn+klTMd3D2z_HoYy1^WUMMxT
zLPCEr46NrQ&)OSr- at kbRUE;Tt?Pqlr%f;PZhSzb6eQB!V;avCo4-xw%SVpgC<TWD%
zDv_t#Pcj-;PN}V4EVW2qPA&RAo#VP<y+3NsA5#b%3ZHsn{nM3}BxW!699eCEUr?Y<
zAE(9RaOB4r$d7)MY&?(5vx(=%1}_!xK*6*URk|{O)x$?~X>Ki at zhRaSULQ;~1MVOf
zp*dH2Hf0S)`Cvx*YUIaL33{L7UK|$goEi?M at IY+7(Md8`C`IV~TLeGTQ9fnH`{p3^
zD;|MV=Uc|2-xJY_Hspr+BlPs~ilgUT5}<8Uu5!a_!$NYupNBtH{Chu4JTVu+DWe6f
zGOA<~Z?xmYSg4;D0Rz_qinx!BF#0arA47uYBkfOhGN&>43aQAWXid;=)c5|+3m{RP
zEVtf!;{=3|<xf_R-d|<RInG}DYvN(kefK)LUI=_R&BRh)xW{b2E2CMx!E3`!&2U2g
z;{I{Zk9>4WXLUc7L)zC4kJ at jIU=L~-MoitTW7qS^U__QpS2wo(PYxX{e9xLR9PD{|
zc%8n(D}Sqn>CiygE(o)YZ<p<hJkeh5Nd71=g<`LZ_mE+ho%||2c$i{xY>xcL2_fDj
zz|tsTzalJ|ED`+&KiS9~6>EOvN&4+hJ8sszB(`rNJ8WBa+rk;+;G)RixrZGOM!ac-
zYKE+q^$1dUXFsF0AR85}#zH0e6B_h;_41}-J|xeZjdP}z{5UA}Xpn_}>4!4vH^WR#
zMx at sy3*#nBChc(g1jVDcivT18?e**^xvrqngRa$hCf37+Xj9R^4<iOoig`l`%{C{v
z7!3U$^Ap>6{>AWE6~4eTTg~4D7UJ;K%z($6Ssoj~E|!hb4EaMPG=RyB6Q#w6#j$6p
z#$kI{8BW_ at _2Yd{ckoWa2rq+7WbQ#N6&W!Am|m5)d@&O9=1JyeolI1b`UiSN?In<(
zwi49bSop46kk^uRMEtZe)|M!IDb+!<X=nH$mnAznT+OETR6hIVB~NCN{Ff+{XeOvS
zT9`;r73}D%^dm$6&L@#pEKf5~jFC|lr{500N?qx@=lo*o+;!zjzyA8GWe2`%G`E7<
z at 5V<II%wZm19*998PhM3GW~W~v)?uLinKCHmLPM9gco{Xzniz%B>>bXuPnW&>)EN<
z{Ew64>raa6PyP^|<JN4a!;gb0h;j-yHjh=LvUa^g7T~C!&W4xbxPM{0WU?9Q5NVlb
zoKp$#8C+fcMjqPyp=yW|rE0}c3~ovEDk(_7qxmsW((Y at _i&3TDZ)<X)Sq~B&tSIYN
zWcG`iv=N?p{E6PJPe)e$NSIr>QoYz8&|=SIe7Ui>d>C*_?|<DL;dCBRE_rn<$NeXO
zV1!C7^32xpW|+?Z{LlM6&s+aLH?c;JQ--new+m;aV~>9sZX{`|g-uj?SwB)0yR*Md
z(&%?saD9}rE{Dgh#2_=c82zxC=OEF1A at 6$y=AMNt-qO_ at o(k)Fo71>!H9HL>P~L1W
z-zvVB>h{8JF}dP9 at H>r|(KzUD5kEC(bo8>8+(pCvL)9;c%Q|}D!J;2|$3QF&=y`s5
zHb{RK4Pq_<97{uMCtg-%1mSeiz4Tq&Lqz|u3&*f1V*<Ty{iDNnZ-%2 at hm}H)2UTp`
zg_yYofBrRA1kLQR%k5Dnz5AUvzW(z_!^c5l!9H2g;PupY3_mG4DsQs*R>S^iH<+2d
zD`vMGp4n(zD)(mv4(Gt8`Q>tajOR|n!X_aQ>PzB-<_C<+RPV^e=GC&TXMriWYe!g(
zhy5>C%qreKL<axxpbPBE at oT~7G>&-YMIsbi>9aZb`pKZvNWp~TRv5va?-nMm4mm!n
zX^ugHJK2Y;_XhTk{|NC_A^LJG(8;J`y2iN%oPey+z>Nq%R*hvZG|oVT8Qh~DLc>4i
zJ%4JnW=`Wf!h=hyAg;UB>7yY(ldzuxE2WwY%Foa}L?Q#`igRReZAUtY1=?2mKKf91
zLDu~ZJBsnx)$z+etR1;rE;B at oy+&@RCDLiz<S#v05uE2iEz9{yWQ~yU@|(HcxR8jh
zSee7SN6Wgu;aNB-ccJ5@{V}?Fv*<%jj?&vpveb6y3n4DXkKg+f{tVXoNKgk!U!o_(
zbLIZVkwY`^)aiWEp)-Z=u5y_h>l~Qo%m==(Mpt)-7aCd0`n{CG1f#V|t(Dor0M8v8
zS4&2&n8Mr at -n>7Z(zh`lwWNW-EN$6nyZqX4Py8|5>KA?X1?BAli`XL!2}IB9USh-J
zOr6dz-?nCX+4~k!&n3%egK-|kGHQ+8Z#Q0fJm4QDKb7Lm5{zPCj1nroMJzv;-k4gt
z%ev+eD<b6WA|>~-Yd;oWc58s*3rP~?LmxD<!cp%^q;uuutf%lyALwXyISp}(`G^cl
zTP`y$x1Jr2l-z2PGsI00E<jx9Ed~-NHMHwF^n_meDA~q>dDGcmBkQ#V at M9q1GD!PD
z+<9yM9pd!Gj8Y7ynbF#jvUpV#lfJK4SH)Sf)kIEs{<yny-P)-IN>PSIZqlUU^X-(y
zy``)>V&d~xHB5X at P|<eJe9HNv-Mfxg_H&>1<$u`gXAkk~;=Oc5a%(ZI#M^gZ;pf5G
z7?R*+)-g&o01)Ok$&f!a`jBF3VS+ at _PnM?G#rC$h#DcXkg#rW)fZIDVFlDEJJTn+`
z>L6&cW<LDzpEF(>6Pe9|zkc=~W+g_`oc=AuleC^>5%O<M=^^OHJF7uGlJdm1Dnvse
z2lTl-^QLM)WQa2Zekn$Ilzbwv2H8J70hS#50XR@~0$X%CE9alD9)JI9{TICVABjxQ
z4Z!MTQAk9KTcwqM3XIBH5z3#chm`(do^Bx4*d8#QU0i^#3^lbXtoYYQ@!xOx-`_kE
zkz6!s1FEP%*TeF;p)yzRa*K_jvF#pxTOfo2qi!=N0IXBwajS0ucmOoGB+;v>oT~r-
z6$3w$Dd7nT1VEfE)vH05#5a$NNp|+mgNNbImTvMY8?-VgRBW7hahSAIV&GASZhC=U
zf^forUr;MUY^T>XBQx<-u!Ey6m1!k4|JWjGFquga!esF4x!qY4lj1}JOg=GNzpTs6
zsMM&1UwD)!b<pAtGC at A9L^A#l(J{&=QW-OZ2JSYG>6?w`z5?E3$tJ at Qk>|#%eH{fn
zeAk&2mI`c6k8<kXdp*7uG>Q;Y9UVB7U!0h}y}ot$zPlQrdZ9GId()QuRH4`o3587Y
z8u5^+8pzQ95%iqZu at S>N&RY0H#M(hKAL7}0*xga+k#l%e<GkQZJ=O+oTx)%u_{G8=
zdbsU#LY*#fJ6|lDxVX4RGM{=9R6#QTm5N4bG}H5A!M4-k?*sT2d4b3Y-|DF1s00&S
zfh{H`MglX)xhdUfdM{vUy5QlehD9D_+6~ggyZE8PRQRb>?I-K|%njJw at pSUG`vtEB
zLQKwgb63fv<ERVkpZ6VfEm}st%goI1SK;}7Atiie-Ec0SSZkQ&*?obX`ba}HhGn8)
zFU==!9`TVH;^ojj`u#g5FplQGvAz=i`PHyMx$S#a)L`uu-*IGss`I;@ckSVZVvQ<m
zf8QQ3=xa2$4}3i~Pn^R~QU!1myxZHAYSZ$^)5vDqRwrbaHED6oM*YbQoE^7!mwd0$
zt at nQ)r=5HnB;B+S&JakUwkq@(@>rkdJu7FcD4=wjGyRSEes{>WsXUDeqw}J?iR*F`
zbRYi0Vu|7b9tACCu${zD&&Cj)M%Q5BOP{A5f*rq?asB6umvH?Z;=~I=goo-t^X|{h
zT|HE;;_p+Hz1IJ7Pc(*z4=OF=CdLzn2 at fIdxH?5dHGrwI`+KIse<Xc=UikfMt at -?g
zEiZY|^zM-eo+&9v<2-onN-eSrcALRxdR}C0jLH!3AK*EMAbRl8j{F{=ZzZ@$`d<Q^
z#P3NdFiIV{N_yo>?L-L+1{voHG<>&tc9T`QN8qWz${$js at 1H^ciothBuLbA(HFe)8
zfW-hrX=421WKf|-M*39BJcecAqZ)!DGZZwoQqrB^eZ`q7oya&V49xf_mq at hO-6>6T
z8;c2n<84<yV?JJ)sq;xwsh7&5vbP1Jb*Nsy<X#156tIDQg}|1PWJ at l@ITN>9+bRum
z%&DwPyZ468%%6DCC6VaR$YW*u3Z-%ap>Z`AYoliD|HIT<g|*d1?V@;~IJ9VRFYXrH
zT?>UGEl$w@#U;4AyGx-!DHPY@?oiyVxI3Kn{r^7u**D2m@~q5E8FRem0^EOrGj6Zw
z5I6Te1Gm}=dm_V$c=K at BJSp(Y;s||XK{UAxF2HE4H<s at U>-a)cpw3t~z%xkOfo+(}
z3}<g(g-2DHzUQ&vV`XPGj$6$b at Mk{jauyOBfk5fvvxzK%pIm{bw!h~h&OS&S8z8HZ
zB!Yh)*w>$U<ftzFm~!=Ip0#LxpE!)r;C5my5#lHpC5-EWxyVn;d?j|kxQTq;G-(Cc
zok?pTF`3tc1RMe=tvI)rt){r+|1gM190Jjj@&Do4gEvUW*jW0F{snt<>6D at qy!)5H
zpJAhHBYz=3zu~nM^|jPGqfNLHXl^cWL-lAy<SzQW_zy(0*n6-SL(M3^gS2h34;-iA
zH`b#At*hkr)A#p!0%Z#)f9+YX;hrkktB6jV-v1t8OEAoDOQuBw21MtRs at GzY^~;f2
zZCEu@`G`27VdN3Q0m1m?FAIYc7JQU-E|rILGj3qF=k$!h7Xb~D9;4yMwNwGPeTe4w
zq+<pBPiwchAz#o5 at -5e4_JD8uxYZ`suU^v)EPdw1C2*S4PbH_rX8XwHIE=GLWfZr#
zlbuI##q>&kAA9O$iB^YD;kvnnTZ7R0ZnBxA(QA}`vO2fM!Xb|yDCn8yhwNj9 at Ax;C
zell9_qJ{(KWr<9dlRObip-^zggl|drHfgl%O~bJx$j1)F%{teKMW!CMM4T|_+8B6B
zcLISD(`ApI!!00J9qyl^CT27S-dveEf}XRMY^S&l{3cep&NUKffv|gku23sc^hxOZ
zjgx)TPD*U<w>iCqO<=T%rP~FY-0ZnBgQ5sR`H;{gGfG%}_yAUqPQ`EO0r{VTRz=af
z0;(kwBdBr2*XwVnF}kCgz**DzkY%M(H)=<TThwkG;OvW_23%7KV7<A?NRgz}Ifi+b
z+W{(1-{%jBjjhiG%NTIP1Bv$^Xg}Av7Bwo=WW-?cPbGN_BYn{hQ`o=T%^RO2iPNB=
z+C_<Dey1r^6xV1%A8c4XAA5OW%__fvFpx#0Z#>P26KhSA=JYn?%T1P9-M%Qe(b-&r
zR4}5z))`NrK;%y$A9!S1v|tcsAZvxGOv$0clbZxg4lDSHtFfyiu==G0ITFr3`L*Y>
zK%Vl at Uuc#x`GJwas=UPc0G?oYQJj^bz{GA}Fo^#SUJq=0VGH!h7KA5rw&6ln(@DQJ
z%MpbTkB?62H8ZS4-kHf(g^geR085_ at ycIzt;~MFr0g3fUVTE{TC&}H6%5!4NPUHaU
zxM*1#=b^=8FHiCWYlO%4Q_I$k(|!rcL7wx_TTQ%<gIfrqg{(kRI|D~Iwi!L~Hn125
z%`=bCp4n8iW)81yjh$(fz2eN0R)ceLF@&*o;>l?pB~Evn*~(|X(toNmZY-4BlCgG3
ze~darJF&$b*!!h)(PKv{){}Af$DjBVN|$GTf?riDAivd|`Vx|p?5iqWA9zKJ9TA7M
zPIqX4<*^=v==jk3eXTKvySkV24ZJkIo1=(+#jO5nuFKno3b5ORC?_|?art|Bx0q02
zf%Pq-fF=9{tr+1y9JXi$=Pamh@{K>vluZK3-YR>w>r{|6RI8jRdwro^1{O`pk^-B`
zlej<p;wP{hjt&Qz5x!fTXz8=%Ce|DGgcWjhw~6Kpxc6(MGu>TK5H??CW1#4;T~xU6
zKnT>UGZBUU1fVc<XTBYvH0b(9bDngWcG=rQR`h9<g>&r|_(qi77`$WlO@=|N%E|xE
z9NTy;^9MM9)R~yy_IN{<ifi0tBGXr@`8}xeQ$zc|5gcwb4s|gMG%hBeF$40^y@(l>
z(M=7CoPt7|vnyg^lq$&nDbu2~1{b%v0%_b^);1Q<{MA#B`hyQq2*3>;B8bOeUP)aG
zl!KvV#hFyjAF>WbGfN at __SkT}MUr(#N(`i{f}yTE??{mb at NqDSkaw+r4xS6gfY)U)
zlP8Hr0eqe#3kRmBuj~QDuZ7*18&7cv;%F{D>7D at Z>8j~;RfS}7Ah?uV<4CEXfq>N+
zrUn3^Z-SNY;{u8-0e)&a*r{n3SIb_$k$O`DZIi*+3qjl4wA4C+67`o?{V*d`N+Be`
z5=oG8(<||Wte+FW<>@1fvfO79a$*DD=p$A!T4N3pZ^yHEVm}C<&^j;hM5_Wss_<pp
zHTm%KE5T#VW_}S;5n(3xF^Va8gZ7a&Wv{RofYX#dMGt3VVY9E-c(U0S;X78Vko4`l
zP6aCnZ`$k3N_0LLV%l}8a5y-hEjP*(FmTI<jWXH(b&nPrDEq4$llWNB{;yT#<-Iq$
z{GM#0aMx8-k&PhxKpE6BNQ}D@{ye}IfjyMcV|{%Un#CeHtkfxA;;{f)3AKEKN;~O!
z9tCKrKC)OG+E^sXi|)U=jv-eHJ{P*}6xTzhRBXCy+s)SY+vFS0m9x|RseC#;{$#(y
z+DAp7$e2C6W*Js|{5$gV{4?3Hl+*43IsM7{e14m}-#psMy3=sQdsNDd#_kbG=jAS%
zHSis<0nY=WSctN;gkZO`h=dwP&>rR>C35JfFX9-YFC!Ib at U6j)Q};E_x%dChaACm{
zN)g%S;GB4~h(n?nVRy&G)K(`E6|Z;@`as{Lehgs7Z<r?{{|K9l942+k at qmTgFjtNO
z*@u>x3ad<rf1n_C9~zM_7SSVkEHT1&i<ePcz-gdM>kK5`ILRyc%Ih#%{l^m3E7$`(
zU5Yio_o_mPd7z;2Ih+(gm!gMbJ~S4Uj>V%yD-gCFpcpVr!}f%{-wg5TiGF+gZzKns
z`&(~eSJrvm`ZDAB4^%r^t~zjBq9as&MC%lyXgXJMnX3^L`O1wc7z>y16S#A-{F9Va
zuzWtVVl at nvOKqg0v5fvjZ-9np{QW6#F62(aPcCyBnq_NeW!U|n=4QxuTuJY)(Y{%X
z_%nI%I)s;u0$AL%Q~()FHnx<(T18ndYCBoZ+2c(%hCpSoUc20>l-L$rny^+KXVagJ
zi@{qwwaW|7&#GW)Cvl1S!Z2=jhJ4;_A4(Ti@@MMwUGvaZ+W>LaV^e)>&HcK)Q6V5R
zX}O6?E{XK*3l?Nr;zDtfx*hOj9QnOP#{dq4c6QO2El*5c3s7=+$y>3<7b<xrMNzRc
z^E`UE8}h`a;Steq^&aMgmugG?>7q_WBd^@X^}_nN|6F#GCfDZC7k3q%&bf&aTQyiK
zWub=xim>?po__ at C1eM4M&Pw*6=|{Y30dFDic72d=V{4E9S}GzMmPM0Y;Vob7$uj50
zj=R~mN1O0 at 3fKIyYg#dQS)<skSme)ezk5$=JAHqApiKgM)i7hDTyFlU;9a4J443@)
zU^Zu!TVoF0`X4gumsZ;8R-OdQ*G5~d-*D`a+qkByr+<_RJ*+wU$;|qJQrp`hLp*+|
z6quUl5myQ6qja6Jt|`J%Z-cm?pwtc5#_prvg(F?S1WT=et|$pbUomW88R_)g15no2
z-};f2cA>(H*HaVCmrfszocfepn+!{ioPo}1B#qpK1f<AExv~4l2oaEVvalCZy(IuZ
zMXaoZ7JB>#6841*K<bk at qFWA{RKoKn{0#663l^(vok|*lY(SyoewJ_<+<`x?nEA2U
z5ZkyENCqR6(Fg)yFJxw6CkuhN^>_txx?&Km`G^FLNLEw$2r7ZDMP1G4TRuN1m%G7z
zgU#p7Tdv_P_w6ZVk&A~9SdhW3ZN*Tz_je^baKS*dfm$tmf-oOA&q-YAmKL5NG(>KV
ziOa$B27+gH)98pe@(zD|=FExrA(vSnt3Hfjd1;Rhz6i3!>xvte$GdxAjb-cJ6E at F%
zX(eW7;AE at de?j5|l-89xwetAvr5l+eQ8$jgf1*WF?Q#s)I}=}U2a495P5b6!OS1(z
z*1w&YA-P9$^G_ at jT}<KR at KVG2lG#C=7DEdL__Zgw!fW1Q7h&YO4-ly#L?$HZ5n0C^
zL#|A*QD2-KD$Y=o3GTGf)K;D#VTPyEM$SERO^cM67pPBPARf5KY4t)BS)YG#&0v?&
zL<J=*N|5*+!cTC~rM$Z^nO#bz<HVqnqdSWKki#fTtRP$`3-2Z$EcGjN_40yiwL at W^
zD(|!G>L8`FVLvzjaYl>>6B~#Y!flr_pRNiT&x^0z&?B}7mhzsDh{Y at 7X&aS~*^T++
z+F63kwCu%u<Y@)E&aWv!&YvZT{fxMJy$DA<{c^r>(R9q9o1t)`xuuQnLMlvec%y*=
z;G>=HNxz3U*QnRO65xWzJvol%=Ex8aigKSz1Yx1=12w4J7!bTPLZxOPH!b3EmQQxF
zE|h5bsjr(XE7p5l6~%2LXSXr%h;*%^HNb*pd9q6R7ug9%=G-V8{i)^7JU26myLk2)
z%}OLna$GizWgH0aZt)yLus_TKB|(>2IY at Y9J@S4G?B=-AeNB7Xw)5!Cvi#+S$_aRp
zeM1F6PC{-L14}!<1HrB5S3<Fr36|r-L?Z+Ex<bpH(C$vH0~ZzYoe~wvzC=<#O_wVX
z2b>)&jOxOoeL9&SmD2D6B!e>#L9FX{IG2KOC03$t+V0wk=mfC at xN7d!1U_ at O&qp4N
zDnEY90te>?-D&!Io`0Ytw~cuW?+#|F#Z{UdgL1FkT<isjtMd>TL<i|zvoFBOO_MWs
z0Sv?q*eo%#E&R~fS-I{zAA?ZeI(3UrV%vXqpC%ti$#^Df#STf$IzLhsE=|f}H|kd+
z{vYnKL<&4$h=O}MxPH!paE$3GYmYPf at F`*j8YgpG%v%^DyZTejD`j=%$MfD8?JEW*
zPX1nAo8n`46bUr0Pf54YX*YV#!1cT3pDZ at h8&HOZe$|yiu6li(7~%N{7=dF>n`KJs
z3S8HB?J4q at D+f2q#OG}#-g00Fx%@NC(}Y{pCPU}ot#$!q?N-t+6pM7iGY`gE?^~@f
z4l5Ev-kWYiwsWZrRXrz1rp_!WpZl({$8j$3-mOB^xW+&|aWA`_i&35#@8AIRp_Q=G
zSu}S%OU{UI$ivJcZUoKYN(_|OIu08a24U0tHHvJ~d9)e~V-%f#p*t=aJzwR~Cp97%
z1 at WGV<Bt!VC1_)nyZ0=NggBSRSVrvMLI#G`BIh6Q|88?xSA~ZQk4&jO<d`MjB<pQ{
z-NagKDKZAa>gxRDW6y2y#~JU20!u9D`hc86_L{B6z*V5As5cY7%R|CX%Xo;;wK?0{
zPA71NAq=ATlX<f?jq!WQj{YE`pzel-3L;0}UgDkPi8Es2t-~7_x%Mw{3!DI#N1+T*
z8n7u}aqF|kjE|DnpF4sa=+*<h+}Cq$@!3sxC2Z~GJPv+`3paM#32hqmpDU7Y_74om
z?~P%s0Br=@a=2WsZV~C}={=NOIbT$79Qn<W^}gWS+_MlmZqFgoqOb+X8>Ll22Sr{n
z2LuWHw1h8vOvde9qvtgcr$026yPpxTl7M~PmBMJKdw6Xmhf=ZYlHSN!D8<9!#1{Hf
zN;XqYV-!#D{qTlj;E4)XCynNn^J;DP;q9otk+UsD?8C(c#bT!!i$LDS;ZWfztsA7+
zey;4&ZENx^_u_c+o7{Do2!A<-(eFY}`Vg<K$5D4ae?Fg<uy?s678dtb&y7(RT%=X<
z?$&Q(5ukDjmZk2r at z@{pY~p?uDoA*TA?wz+9>w4OJcof&Kh)ZWiy;~_7)59^zSW1L
zU<c6&uIqi$CoR9`&-T>(Y3ANo`)58%?$N_#Jj&=2#Rq|`6{+_KN|Qav9amIsMTE at H
z<t=h=IiiV%g{p8f%Jufdz>%!yn%UuISHrIs5`H&I=4R9<3F5gd6JgKZ_?##g=t0>9
z#$2 at D=H63i(ZtWG1nx}>B1~bO at bL>u@?1myaBF){*?s>MzVer($z6HG`R7E>#Rf9{
z+5)eia|v=g+o*oF)m<F8Wm%iwPCM&+1k?cublWyvO8obom{XIGz%dEtR0n4>kp&si
zi2z-lw8lW;(yJrLzfms%_n9;`oo!--_O-jygUjQ-q01LD(fvLaV_vze%q>R`*qpc6
z6xEf-(3`j|(@iX+0)8O<u-@{=7KOkGM?Z!0{T94zjPQuRDE;`T@?YR$pK6V at tg_r?
zhd7vU`k3CD@%+=<FB2Y+x}+MKQZIkWiSIoYs>UkNbjEi}qv=y=;;uC=i3V!LN~-ht
zqulhSjV=gKVscQ%j4P+_HYVxHVPIpcdBDMj3uhp|hoW(b&2th8QOL+E_d*g%HJWO>
zh8ss1vjj`VA)ictOm<j=gV*AoZg;8cGf&6*N7FUbxR1v~)M}UeY`ON(H=5Z1vi8!L
zi~~Pm7PE>on8N>SyXvks9y$CjE-}`CVA&3xfw#!0CU})cNz!(#Xm3m2V|z5qa4a)%
zbm~nld9ttrI4#{$Fm3IUcROAJYpMyl?ae(7-n<ye7O4_n%%1-|=0b6ZL4ePbUM#n}
zyUSa;OvP6izx;(G8<{+cBN}&27;KiVCpW#o&kYZG(>JWwl)u&KKi`-6IbAMeQ=ku6
zcf-Ptp_8_od%s2>ZQYSFQ<c&%<97w+EeLuc!vVKC>G<>R#CV|h$2X{{q&b+obb1CI
zli%*l1Yedd>Z8_DZ<Xq|zO<~ex9b8U=oKQI4N0^{!5N`KSZ3lHKeT43ZbeE${9ILd
zFS>5Cd;&qU&mH02aQga>#d%wBezKJ(BQ^Shm-AbiHTu#u5Y=IBfv!>-n>vzCS#0PS
zdO5dT>aE<Whoy8eO6KTX at U|b_Tf2 at 4WFZ^A#MF*WA1J)2Vr%EdHv!1 at N`Z6Gc2#*D
zE2n06r+m3-bBup)$Gx$;=MB)AYR}Q?CG%$N1+rOFXEJsifGGx7KaC4qX}%^MY+}_W
zWew9C&xbpP3dR*1su9f7SagdS6FT?&I^b~x1)Fkd5vI-W&7vJ6$Q(O{>b-Z^#B$nH
zDxQKC{<$|g3DVCZcGkoxrt|Ow(mjqAf1@`UU;)N8{j<M6{i>S?r$*P$&s+Pyz5q6W
z$;P5qVLv4kUA_HEL^LVCtBd at c<i>wgn4g~4|6){Sj2Pd_-~zrzfHRcN-)9SJ*+D4S
zcBT29c9#hN*^Gt7Ff24UPym|s6gERo17qiwiz6mMZf($@l31C2rrf^k at nZ0QilHqe
z07Y|w at RCH^LaK^uvPF%)ntvCG1-KP`hx#PlaZPNpva-LRYXH(xms5b-0>CH#vVgQ}
z;5}fa#m#iS%J5^G=eJ=b-r6IdUrBoXK>rn*(CQbW8Lr55wAw}rsO)6i+!_pV{}*}r
zKNO~nx;fxuyZ|i-AQde;5pkRj9uA~$ghrgBxa8>#8?mKQ6$7e*+-TMR7q<CM6KVly
zpa2$Uqcc?KoYUY1(_wR?@Culw|1qIF%?|%#ABv`9)&h86{Lb|D_P~Xe$(F$MuNj5o
z`eLn?ms%OM?4xHPLp_o7ahuy at x&olj0o2-LjHCEWWP;p0cCayxJi!&0642;y1Iq0G
z;6<aB;=^*+`Wd9sS_MLOlsVR+5849UyH~Y?kkjvPlFrb~QwZ4NtG|%<t<-Q!asRl_
zcjB3giPfx|hWszU=1o`p7U*RBH;{>Cb~p~MiT}gl{13<YuKf=cW3&i=*&h5n=!kLm
zcP%^%=~7QEMawkD$sq^d+<F6<%AGO*>-iY428$a#+P!SP$FTlCD3+)ez<&dSdjKL4
zbbo>hz!Lsat};>kRt<cFrG~uwPlij%XFE{xnym~Q8K)_9E)=pe%L%vK0Hk&fceQwB
zko0jY at -r*4jNnS=18*u{Mkjzb#AGA%H-f at dDzt5(*-j~?#D1McWfbnyuU{_j?*Zan
zNJz*}AVtjkERez$-V<CjCUe${J>g<V_=Tt*3>G9Exb*>Yj<%fyd!SMC9WU4J8^MH*
zSNoGG-2#G)bNXG-3 at u%2p(*8n%kVR7UbcQ{mifhhOsH&OH;Yiq+#lD50QqZ7a1Z=n
zrqpW;m^dN;fWBJqHY3xwe7Vd%q51>byDXoZ1;E&-c-BG3(h~Hn%FHblI_I7f3V^0e
zbdd4kr0jP*|1(HDq}KFZgvkaJ!mbzq%`Vlzi8IH~mw8j*&*SQ?C|J;m2<URb2<zKn
z8u*Yot;u)&cY at C+W`ZbpO-j3aLr~Jdm|2%rKJm}x_B8Xn5kDDy(rsqGZ{S1T6
zHD3K1KFe8h=m&|O!NYX|tMP0~iM>FlVq+07_qSndMs-_z&Yt{S(aGH6y3y*)*6EK3
z`ssdd0th;h&DH2B3lmu3{?^-({^98PJ#Pd6kE)B#z`y~$x6Si at ihe-7x44=qR-yUk
zKUXp!C+erir3Emnwu>(8USFQwchfC#WN-nUoegvsVQ#JJP_+W at hdCT<OCYR(5#N;x
z2{K;Gbc5drbN+UzdUfP{zXE)??xzA%Fi*JuCLW~883+24h<f5~H`X_tF`TLxvF1uy
zJW-fB<FjE@${1y^qasWPkQ52QXBbN;g7i^v^d%07;@IjEaN6PO5Z=P|!%rbeHcw2!
zYa=j<3n1w8vNpv1^6;a}h!H1|=(a5*7|o4-P+!8sthq5cQh9enE`L6ZIQ}P*t>-~0
zV?I)gau5D{K!gb at 6}+6Jl{h+bJc7OzrD}|ux-88PYG-BbOTXezuR8pK61lj2-%fl?
z7<`+qPhrKDh;Sz_2U=ytA~?fi-OuAkeNy9OQbeVWhS-ARa=#sg$i0d~3^-u<Qn=vz
zuWEgRKP4<W2D<`5xH7m^jhhjPC(6av5!Z+FTfu}zol5L&L4YKCUErxNmmfn43~|TN
zHT?F at scBikOQ(`Iffg{FVXwDc2q?|*d=p8)DygfR+KY)EHxRCnP_*USkn$hq476P@
zcc*zq|IO3m-$!gU7Q;uQvwM8vUP+UiFR}Qg>Z=C29_g{_9yDTBNErFDtp%o6N at 69g
zPPvoDDZXcFb6Cy2Q-LrzEd96XsM3mOc$gC+RyScn^RZze0X<<luq|;Lcy~51Q|3p*
z0eat5ya~=Cez*-*<OB&TDoQet{)fCE*a&Ngsy8ZoKuqX{KxCeiXx)#lc#nOKkOZtC
zWvVs^-hp@!Q;;@}e~`Shd^S$Oy2MwI<PNTGtfaVv4LlW@)ucB)Q^q(0xcWfA9m^#{
zvJvZN5mFSbdJG~vj=BcMymMTU!t^s!X`BouKQ2yq=l~j3aR>>E6fK%dmbgISScHy>
zrQKTr^kjth{wdW$+y&O+c^}>+_u&*`WzIAopoZ_B!uxyTNj2k9M{Brx!Am=85ef;0
zd}I&ZVxo=4O~REFq7x^WIP;1l_aK&(!6|T2G*ed$*ERA$2L6&+=r0dyiRL*HC>U^{
zo&lsi7#Qn=47oieDw&Hy--15;yB2D0Y2lXJHN#|;Pe201CPvjX5!3*u04UoED=LOj
zBnhp~2EMIWCkxbHjR0y9RH|R-=u`kX<`a?+go>1$JY?^2pDj59mly>mCo4-yMkr!f
z*^$WxG-aHcFxGA-KM1`nLcykHMNyJev67;G1_i<~rZb0_+fMKZYq>fp*;UEoptH7`
z>UT1 at z?P5G%X!fR_VjFqXQlUXsN@~m;o9Ws6?fpLR2$n);Zf13(pImSiz|QID+%w@
z*49~8TaYCATVLk4P9S-u9^2asMuLbqJFo)!FBTP9fW!dF2y<8KcDbKH*nfhXK%)es
ze$P*WInvUazfD3wqBQ3=rPh8U at Qicf1m_js$2*Wm_=YV{5hr*uN~R85ku8Mg5$6$B
z8k+xs+?q)8hLDmPbLO21dq5N-DzVf(j0SFJW+M+t`@Om^zqXxN-t|7WqBs+(;6I4f
z%1Biik>Z<yqJy)6b_mB?Nny6D8mc^P=|u|hBZ>f`0mM*JN1a_tohzCJ9}JT+4BXT>
zZEUHMK`U2z$%D7lb{4s`Z-b^LBqa(DmQmq6uRQWxxbf+bg5JhSN}!8JTQ~$M<_E(C
zS@>1M at nRfgqmbE!IzCW+3*t$R^Ch=_Pw9dbPOWVKAN2SYx`u&xSz|T~?q9azp^r|t
z5Go at Lp(>w!53JO}Nup`2N#|ng3}g?r6dEZ#S|^MD?s|>|v)|CC>n9hr)HdrpEe4o3
zHC)Ptv!fi*sMG~p$=2 at v%-7uCiiYr4Qdnh|=abw`?!6G4n|Fk|8GBf8lbCw1F3XpM
zmh|5#?@SEe{Ubd2)BAdF+W6JZ_|P&KCi(z=*=6?&BNcmDJ8u at nW@=H+q9t0qCn9$@
zL2~dNkN)`Yt6BIdl#4Zs;i`o(270t(yzXy_*ZLgOU>dJnYXdE<F{<ABo3nRLvG(ZJ
z>dq3h=7aWfXxv8ltnl<z);H@`S5b=UPonW1QhU`}B>U6BJN3fQteD$Y{PUI-kxy0d
z at C?h5kEbu9IZHL9AS`Xi4KF_miuN1HMuakc62 at 3?cMgMJ!0GFiAh?p*-LT>;Wy!vu
zcdr^Yf$os_A8Q^<s{nr7Uy}q6FXr+qy=<%yI?Psx3yx9|)`CP$7Bb<{IV=%rfupjG
z2L~Tlf)fKu*NNXH?3%{aUIrb{Qbk}%uW7FDQ!(-f%R{W*@os%6#&hvw?-_21OOceH
zMKlydU_}BS<mnyJ=LN$8;3y|qd~E)?e1}8rG}I1I)f8x>lYWem+;$#~nsmfyDkCi*
zrygwS<V0qbg)z$fBUlf at 6i|4BiB_p44=4YPd${o0%42zdoH8%i*1|l<_Qfdn#b0Nl
zT<>d1vXy9#ICo)@T&=LABpl8ke^orj--LgR(Z8G0Uau6Ur&0&0#|g=hkonIb#2L*6
zxRld8l{ouQ=LRbRxnq(<AyzyjWGkm;5cb?6f)J|z8o*mX9fm77qsRo*BnK+oiJBJX
zCfYi(bTT}nwwwEDLAk?S$#{yzWjcpvfpCIql0u?me$&G1mHGjmzforEaKkp=R?*-h
ziB8c<(5O=7;ogZlwa;sZSy_mXd~qJ~r^#%C+;@_GaL1Ei6E~<X)V$u1_xEOlC9&o4
zX61ZvUvgLu<5nc^jez6f#*F5WG<ByS_cCMP>(~-vIliGnR(A-plI9Gu;u1O&agRZy
zqupebY{QMYQ0csdxK{;oMB$KoA!Ca{f|OQ0SP2Np<f*v!!VCCjWrJvh$-9_?(a$^l
zwvRt9B!<3`N;<?WT6k<ig<!{F@$hUi%2wh^zJVYA2JGVf<5aOFI6+^+WQlllb@}cO
zn%H<UK=~oih%5%2UJ~DRsy#&>lVFY*s=5#y@%6_u2!F++J%giRF*QN;LRh4l7 at -&W
zGknli3`w*_k@@}t#kz4vExxYz*)4P at 1Foa})#h&3vI91i`^r>ha6+v?u>J{{m{sc2
zM)FK~dB&K3G&+VVIJvDf0?u?0JW&-tP-Y{n-ym9vH#52X<CBt%K~RU?v`{7B3?-}E
z6SFB!MB_Yk+5<wX at 95&1p>b&16POy|c{ZVN9dPrLVW3+HcXIH`h_86F$~3)Pi&+r)
z at ty{b$~>Zz9>27nL<@rTM;jsb*|$PJ;PojL5CqzTT=0va2zrxoLxK3k;;VAh5uNJD
zQ&7q&q_|%TuLW|2|Gw7A$)lofChJUSnzivDEc?R;sf!COdKJMlN#8`zA!s&Fl*9Kt
z#y2ZbW%*heBD-Kxzr#_*in+*pLW!fVW*Y)y*`^mSB|^pTB&v58<P)JsLW8z^43C01
zaGJdL5*kk)iL`=M2TLg#fK)X7+DFW$Yab9`<p7)ofa8<1N5+rtP2I+h6xV|r5+aN9
z0c%st*OA{y&zsf0$py{G<Ah1zge0jIlJmOS@!1WEpHfEVez)Mm_~UOFf5)}{6@}N^
zwU-xmN9k`H-yE8V9Xv*b_IbMGn<5%pL255Y5|D?(wy+fh)s{1oWv3N-E4ViZ&CO)D
zPs38~yW&CSq}82d4XxxJ-!;e}L8X4z7!Q1gLGa^t3mgXnqL8a;Ib5j?=GQ&ruH==*
zBfAEZ=|!U=P;Ot_?F)i1*1WnwJFY|9HGx6nNdKhMyN!uR_p{L3t$8oGyjE(RTpy;@
zMsv8^=O;l_c<%!(KX at un=rh at A_YNt6<vsC%!qL--*gEMrFr=YpO&wk+h^anE6s_f;
z*}|5y?Q!x>nvT^_p83$x`Bp at JdqFa20f*-Ig8D~=r|s3ypFXG`J-T`YL}p=#(n5Xm
z#Swk04A4`*Cj at p1`#hV4^v099%o=kUTxf>Le4yKA%O@|#<6d&#hpkWzLBOP{|5Oy;
zE4PIL`{~H~h@!lUiKUBf-Y~X;T_4nNeDO7GQ{TY(nFK7 at NO~*wN(0_C$!B)oNY9p^
z?|66G?1HGBC2rusJLa+Ne0LwnzB#o9=~x(OR{tEAo#`+*1zzhZobF3P0P`d6BaF(r
zQz22l<?*D<dMDnDsgEH(U}PmHS at yoJloAg_O(<@SoK5R^DcEx at v@YMNK=nIlj#pkI
zAVwB0308;Tj~WKAM;^j*Bh`Yn*$6M99T=w)Dsh=ZmW|-aqecD80JBcrk>DGR$Q+y#
zg6coYXgIkL^>)NCNESyxfUG{YKc$su%YFdXI~RQ!&qkC6OSp1faqJi#pO8uA2rx2j
z4AJjCO-U*7QXx`{yt<I2Lh`(~g$t=JGr#tC<KUxi#^Hb)g#4s;>|0osM5$N)&cDgk
zjPAGsY{gjd0cz<fI5TnvciN?-Y$9LSuGx#I0v<r=_<{7}Ba5nlP^K{T_Jqr()p<hh
zpm&vy&F9CPV}PJ$S+xYqX`c$p-Ggjs&HiXJ_`5BjN)O5&kPOi)Wc+GDDVzCvZ|l;0
z7L at rb-A%62K$f-oY}>6PO75!oF7R+HlzcI;3(*V4O``r at T%Zvo=I4%+x$4MU<#m|u
zeiZ7qwPd{TCR-R&xAlNtddWA$tNn at fhsg77O?{pQ#j<~{_jASF2OqLkkKyBwQQhtj
z_qa1I+!0&Drgs~<r at b=s9heTnZeqR{Z4T?Tk*fU^Mr|nX%RjH3w3X4m(YI#QAx}9q
z4v%DC4YE94ja<76jQw0$sG$bC>O{PIvOJMFn96j#%p~}-gy^=B`;t4p{_OVz`dA#Z
z-tPCpm7{khyZq9w;&=#5;lnRI&xBh;^EttLr^H=$uRGlzX?UE9*~IxznSx+@?jPM&
zfDFX5YImN+sM|GnL2v%fvyJ1%Q&P9hjR()x!?`7 at Td|myjwkH0cduan>fwCox`Ow$
z-)eCF at A<722cvLfu`@)-&o&H?6!Ajxg7!zkyFY}d{-U?Xjo19C>+ at nS1fs9=xgigS
zu^YB(RF#-t#_LM~R-uafc<3vtOnfLa(!ZTAEP{JZt*#1aa&C|iuhXYDZwxzPhv#n_
zSnsEs7nXC2tcO2pR`P<sYsB)JF=6{#2pXmd40v@;J};?v-7{K82je-^{O(9m<9;{!
z8zSWKYsLw4_6Skq4NUl<V+-zmFbsVMPSZ_77$$!!6-ix35`Z(D_YD!xP#h0Y74eq?
zCJx<1Hz at Bb+OjvfwGhU!n*@s}=HE*$p7IG#I4;pQ`y_A;3vvaTJ<(qTgs?5$i571&
ziLt5VYNZdX!c%O8FeKr>@;t-CCtt41pt;~lR2ssIOu+;o82twU<^Aey<Ss~ILzH#+
z;vu{PIpC`^4wo9#s34dwECydd0$#xl0cuOMXx*$NpZU#|dLD%PAumCw8<UB4)Jv;C
z5bpDg5geX+q2;0iT9H}qx9JUygEBED$|RWTKiDeTL1oBS+KB>;FndN3R8&wHv!33H
za_(0#qwx{t<-m;1irM!!$6~Orl_3Uk-Tyu?13sv!A4Zk8<CL$CxO=gSVRFU~y2}m6
zh4L<8DwD^J_XXpfmn$*XS-;WHbse;1Eq*0`HWlLj&(0!FrJz6-{P}{R`=3Vd2eD={
zY_U5E_o0 at zuS=&ZQ8HYA{PQ)`Awoh^xCoK_h9ScCUg)j*WQGqMqPN9_XG?w_!u2fU
z8w39!MjrRMXFV@(=CXD-CT{l5j^cOjw$yxx4&RLKE!H7h%^dz^K+-OPj(Ld&tTnqM
zzn}dw at Vs<ZY}^Wa$W$%tN|N6q+EEO1znb{zEsEWLuFkkkRTS$l6Uj+w0v4(##rC-s
zof&IIqwrb#?O4wHL;pph==JW_{c6%sU at HN~D^&AGlLfa9JF)opLkwF_JD6fqRNFmV
z96Soab)j)DqwXP5l{5 at 4AWzV&^YEXX+gR|a%a`*6y0FmL&7I@%jr2goyR+QokZWZB
zhvpqr6t^vOw`Z`!!`8g%t at HSoST|(R`&<X<YLu~$o9pX2<6lar)SE+6$$c^UAJza%
zfB{TKtIsPD5EQX%Ywy!F<IaUseRN$b)FvW+?|ptp9SNFn{HUbij~=U}>OxMa-Lp8w
z#iWiWLo4nskG{5omFUr)h>E<0QvWg4x1xLs0&q~@JPVk9U?=z9By{(lC;qrmQg-A8
z&yEe>RE$aM`lkVCAnd+XD4K|?vZ5C*f)RMu!5ej>dFB_|%kPM{NWm^BS9)R7EcjZ@
z2>r()1PFuix|BhPj35#$?Jdf6S1D~8tD~<%_%dk3<l^Nfs2hCnZRBJxStS#{QIZa$
z2s+RNGEgYsBpWBV>{Rs;DP at P_;o*sGdU(ZC5I*<g!XZ>?iIbGzNJ?m%G_Dkvthmt?
zvHPpjpcyn;W2~%U&m78E(BN3(QqN<GQ2Lt&PMGj4XzmBZNC_1C=6SzW&<xyabi{*G
zpNI)k#YdI<qcJ+gUy0WV4{n^W=KAL~sKHQjFvD0(MFwB2X|?eOYEpCn-#IEZfEV`w
zo5p6<>|`3x=o!)Wv>=JbSu*xO?(qDl2YK4Q6mYDIVpQ3X5APMBvu#>uY2BEbH(6Pn
z?#~_)A_Li%W2qHRc8<|t!}}r{B7asFiShJAtuhj|ZvR-?n=mJo>8XSdU%E3gLA1hw
zk=e<E8k1?u$BEXc`YzV{_OJ}26_?`muJYr_d!9dA$U5C!1v$L~Xq3t(@};oV9VN~<
zXWU-2Bu5-1tf6Zp%|;?}Aq;4r;KyC2qQQ!EtcXp<QVL7<K`Irzo^V;ty{_mX)bFB%
zDyA;BOFnleh}GgKSO^Z7t52&9X3+<V){ObEKHOFaBiu7}`?;EMe9`D0MHSsy%u(Qy
z8(Nj$(&5=L#Vfw(^Q94sVLJ+;fzvxSgSFHHjbfO#by<96<D)QkVa8YaB*%kj{?Fg?
z)3Yb^sZ=tVHsUvcWY9O{cYV5NaaO8)T7msIC!XYTQ_P$KJV8@}srjFnd!P}2KLyo3
zh}eQC6NGNC=O!8sAaCKMp+V|wT^<$Q-hQX9+E<=%Z%}o%>Jaj#-bQou3`~51_^owp
z=sqG7up1)D^$WQC2+-%1F6Y5&2a>O!E=3#>Kuyc~%UAxS6V)bB$(=XL)O>9_C<d<U
zN_SIY-teS4JB~+I??fU+dQ{<b5#*0||I=YFQ^Lc`@m~M#u>y&}Q5m8(pqJS^y&koB
z{4`(quzUN-CfE7oZa1s;SI7?!b(Qj|C|Vp=T7R4YSQ=7U`Vowe{%7VH#qrN>*M=om
zVaFw`kP<t6mqHZ&&%8YH1$652FbfS$h4%_{AHKh at ec#W&wvknPYxJ_U?0mRek#%YQ
z!D7x37tlR=pXNB9w0nJ=zV)FMi6YQv!(B$piw;WKhg7BGdQ<GRgk6VkmW4IPM8VEU
z2ad38n_^u_<oy!&eR^Mr5Xwj!3 at 5+l&&dp_NKPWEgawr&&>*Z9PKGJW>g#-nr9_F<
zr_Er{C$y6}i;0slp~-8KqYEB|pBhv at tugX<#m~|$z!vC;sasO7`$-+ at 4aY{M_t)Q8
z)ZfO183QZgv{KS0r^rECtg|56G5v#5hWt0a_wckjv&_6KSCqRS-u0REI?B!-Sekbh
z$j#yg=GUv%!4_CZ0LEWOIjlFCP&M$18ZlS_ood4V_us#Nw{Ks&L+}4uwg;8t$+3Pc
zS9DN6>#6nYHum|4-nu1h+%LTLKvtx;<#GHa6-YNa)MLhr3bK++VX{CpD5$ffvXQJ!
zkE&r))zT&t-M0MEtc;lceYQr94)#eQ2_v*yseh!0Xz(&CJv|*d$gQF^^b5RpbtD=7
znX6yQp)qv)b$0J=y2Blo`%op!?Ag0_%<<vA#r}g(rOriJ8=s1nK>{9%)I|ZUirI``
zMHFWUFYg|cZcR8ki9$+^^P1iAYbQbiV*z>{(ojVAuSFMps$mjZi;-1#{_0i-|3A9N
z-!6u9Ya1Wo!gWvX#wd2h{CZIsV#sz+MPJ}w*4^4i7RR68yICi5*W$+2a5toSowUVD
z at C2bKajT#PYKac;C at CZcx%gt=irwK<YFA)uk#Bx;$TV#rQENu>RtSrCx?1SLO<Sd7
z`Um!%py^4VW at n59qvI-MSczc$>+8lVh<AVtGIVgQ3;XU8dYm;A3^U|x)Ka)-sDWsP
zxo!;Hgm1-u77oqODe?G!v_T<GL({o!(b*tA*gSsf1Rkwg%rmHaSZeW-*!Z<=ZIiUc
zz8IZ7oS at eF^mL}gHQEd_T-rqD{t(aPY*sLJ3{Ocy2v{*DzJWxc0_hC;5+iSDJvWaG
zIUoq#yk~YZ7^WWDLvWGE^-zQZmOqYd<=SNxn~6Oige`c?tZ~Vb;%+93BI%jT+jV}Y
z2cuf+XA8flIqmq07K1x;5JpHT*)E~H8$RaP9(%F`U*6NrfHsyNOjF+9jMZY!?s<pw
zvMrQ9DKiwtOO_yK>-;X`GRPO(FpK5}ed<JXD4Aj62O>fEf_Jb7vAt+N$1a{S#=9=b
z at J3>mY^f)-p5JmKc32S+@|5L>%s8_VJ)IcgvW^jj*d(0uy?h=1C3XR>RcTrlHj(>t
zu&z`(xmdCt{M=^*2d~S9%ZJdDz3EudF<FOBR{kT)wJNe7KkUwC8FKnqezi{SwY|P{
zXMNP$6MH^?Et+Bz8WmxqmrpC=TO(PX5yM77eA(oFWf- at 8!mMsN)@{5Dna?-<K~Sb`
zhSTl8hj0Ak^Uw=5@;Z&>6z2Au`)olnql}q1f5^$rEmb=G#oT;nGccWq##}F<gvleP
zu)Or at XEt`+=*UmF7K$ec-~0O40kKEISM1lS`)Tj-ZvLouVQS&p^k)R7K4}_*%d&8?
zFj_mum2V*H=UIlk?X6qr>lk0i<kxSG;iR1Pwu3AjP$@6AzyFTf6X#Fbou3#zG$xd|
zXF{?J^el||>9X5m9vy7YUl>#;e3pD%<V4!6Q>Luy7YsgGa4<TC7q<P(oo_!rh3@<L
zva3-HHZ`PEK|2R`-nsrxs;h}i?eIKhYAj4n?gGx(65_|ImhfFUF{!MTL4UI2_sldC
zCnK8%+Yg5~TzC7a9v3~wBML<yJu>=ZQun`29I-eJ`;$Fgmx_%Mt~Q1i at 7KJ{-)$%M
z#hkWh5=VoxiBJpimXr-C`}6VkZ}|?Yv$yxBfsnO;a<1AvHlv2qCT!M_1f%Nl-9D7e
zHuBY|f{wwy2cc|Nba+1gIbsawsS|3 at Vu;@+qPO?AlvBTH5!y+uRwTYkX81kFo1#Di
z=+?L5=xLXzs#VTKoe>P&cXUxfWK;!0vB7W81GszZ&}!7q5T%9FD)abarGG}3Qt~UN
ze)$y;0-nUE{n!hpZd^yR8K)kj$`B8mRV5S2C>eM{$UmL5N9PK)v!~<=ME6&}VV0Zm
z5@#M{H~vQT at t-;pD`E=mJ3$!glyLYGZ)BxE_!9#k7%Gx5$`B+GTZT49d|nZX+D5f_
zMBOdgg``p&@i*^x;>Rk*3j)vo-xr`u8U0X>C;HAC(c%WrYq+Ni&A=2(!6F<Q_EB}F
zoYWu3Up`^%vk-Q7DQZ5tCiMc#F8_OlU|gf`CEo~YHEao~Pzk8_QK(S{*?#aas&U+(
zcf_To*IG{~zZj&@F*8?qKb*FAK8js5K+Z?F8rGm72cPMNns~31)_atb)*Td+A0H1?
ztE$cqUw32g_ZeQXaJK^eF7 at mM-9;Q;>U9lgng!<5vQE<5Zl4wyUid}bE+`UtH>B1c
zSiJVgsZ_Xadk*kh8RF?FUXH3SYb;->#=5w3?>WTI?K<Q#c-XD7*y*{&epk#JzaLJp
zs2%L<Ls_xEEtorEni)|@h^pWySIj8cGn-8F&U3Bsm&PU%K7E$(-C#)aJAZA*PNvw1
zb{kFH98|G#6XNO7iqVfrpe>$NMibQz_Qus8#rO?t_;(9B at j!O)J?6ikUh`o$7IY`O
zv>v-S6Y at P{Sd(m+6_+f#9+sbuaz!YPZKTa#QLN#Z@?Q9*o+aeE?1;{P{D9<l^Y}`!
zw%8FUOzz2A{c`Sh+2imc+VOlC+5~+ClPF#+I}h9V2F;VZC-_}2QAoR<TI45c<ah^c
zJ)Z2yQT**48x?N+a(?+V`1q36e|x<CGT)k#={B0hr5Y_On?htR7K0F(ba>*4?BE4F
zW#ZcNy!Xq4$OuoTLynoxx!n`tX?y6B(Y;;kzna^N)!S#{>SkvK($J2<&ReFyO)IC@
z%(XwdSg+)-|M>k<g&oq&uLt{y$)B)%Pgv(So?tpANyW2Z%%X79FXJnapO0JKM^Y4K
zmvdx4$b6$1_(||X{c$BBI}5#Y_eY^(JzAuhV8JQV+SmD~$#C}Ct(%66n|TUKkq7hD
zM+ebhmkin+5;Zb*kNr@;@Y7{<^ZTiR_SOm2)rDWymY(&M8JhE+yw*-E|89Ltq<n0U
zo5?d%C3}y(_okFAqOt<s;9+(JE`9hw2$?v-eGGZPRL0L5`7($iiM~mnF#7o!&zf-z
z`zJ>yEpdZdeng)D!X(2x;dGrKz6h!@i3%B1_!=Z3OcsSW35fxaRYhP>tJAJrR!&IF
zN15V~W&Gsw9p(3!B<S#hHU4a)c)I8qH0dg540B=T{x+kZeUPuM7HQwoS at ZXzNd4fT
zRlq$itVD4~CJb*1u-%j-wPwR}N#1|7l6PDo>+vRL1trVI224<u)N(AtS#YYZPqj%?
zzz|&Ul{q8JghmkPBZMRhwSPELhq<NQ;9y(W$=5PFsiYIjXgFT|<!rx8uD(poy#vRJ
z`j#b_;A~tPzmTwZ?78}`vpP@)$?J*sKM0B~?R4CO#ClJU9-UWj8D8Tdx2>=2qGQi)
z%R at 26!PE2;Y<xrlcAqVV)<l5><Blh_{Sm<oL#ZEfQ$L|@sM?jO7DMM3T6Mw`Cnexo
z?6bYxR|k*Bz*qD#vD2ZEq>TGw^WOuuDdvPeF<E#cVW?wGH6(|@<m#8g)q5?g*K8JU
z<9S5<txv~Kn@<us`~2zYpEf@@ylOnfw7Gn;JMkTESx8<9LWftucU^O*IDN<uJo+lE
zoiA7$$?ts{t9hbFNn&Lh&fj_|vh4l31r};ohzkO_uJu$|1RS-;H at uu-b9Pi1BBNUa
zdisv^T+s<LS>y#bhSR5W!K%YX&cp at hNE8y`)6M?XOK$Jy at 1_`%iVf*;tjoh{FH`p9
zuZxLU%PgJdBPV}{qvyw`6;F0Ued`9}cQ8ZDdseO~9a^s0s&X-tvL8Lh$6ef?CKOO=
zB$$=d^wOv$YZo?wR7#1K9~@E$@_hX^Yv+l}E~oq+4}aemGewUfJUT$aLgcx;;waq5
z{rXIepHYUT{$4Hu#epuQr=gKJtSHj$d`s*#();*O?bkB88Fst>r<3-;Y!XI;KdYe~
zslbmh=_{vEleQW^+NeCe_h^6l?NF0L+G6zl-1 at Kt$}+Q*N%6?QELq9fS+{fhxlV%(
zxqH(?O@;ESm`yc!?8M9C(alYuJ>FCyk)NV5Ss06Dz2R(C&F-;6EHQcd^83gPLdEq%
z#~eatCH#ol9D5MA4fPCVk0(q0OUqo=&EUOriSo(9?$lgOQ^~F->PL*QrU?6mJtXvX
ziwTa<K{#~4KRn5vc#;h-$%;wGUg!OFFA82{JfQ<>&6Fh?F8+JZ9S$Z&YpV>CQLK+4
zn-z1_g~N at qibO<<UvVQb(+=_G`8q+g3LMm7-I8=)tqb8w3LIl*L?mj?25NXeW=Ir%
z879S%oP9}l$kQXOi{6o{L;uo`fI&JCZ{CBR at ZosM2%*`J at aDQSZUlEYjI*aG at E?8B
zVWG4Mei#maTpvUde;D+cl+n5IirxfFxl3i2zes-*BUQH-r%0otF6myyYKVaj&w#uS
z2})uv9<}}TZFmHA^-_-Ffzj`&D|TxtiA6=;@C~*1Ze;BF$*I>cafPsq_0zy at YdE|2
z4wU@<AOHPgVyJ-2wt!OPWoq$zJ!82K9=i+O-v1W-lxq=>7b12aD;r+8GY%k7$*)~u
zM1pJ3TlUMA+*ceuuRvO%c8wQ;SPBoIf$v8~l~QWglv!`lQO6o2UO1Vzc52)_rpy|b
zZoZI4!m6SriCVfpn#CJFyYDpYb4x>mf=Byhyb}ATZaG at ZX$+|Eb8hh`<1s8;lQJ&Z
z=o7Y+Hiz4?DBCa_=$0Y2&OBE|``5_lhSlM34cYG*&Gk}0o#r;OPb_;eW1m+1QlHb`
zHfLWuU$(eweaA9#)Dj$evnI6h<X%)0xOB4Qq3D*Cj$7H){^`Wxl?i=<(Wgf_P1sQw
z+xQjyhOuuCgnapUYVn1ZPmfsvL~<nPPUz(zdfoi(o3v0%<755`e#cTj8)ZteDgCkG
z at _py_sYozIbbmXLvg_OBEm+kWhB~_7vwR!zTnbrxsTJU$w>xpaOD<jU9s$W)2)d64
zE<?^Attp*7z~h5+<CS)KrKG2_T-<Zcj9WPI9C#wr(2GrdM`?!sb>%IW`iSoByE#)$
z;lu0O#ICVf(bTUh5!2DL2mJ&2n;eSoP2Q1mvt-+|86L+d%3#fPs%s;5=}e}59uY79
zNOgCFw8 at p$g!M39;DK;}S0jM(B}_r{gL(k2Veqpf>Z*88pHQzw2rX8+UT1Z6qFI2;
zuENl_5vCo=0ye6@^i%TCrq3&U&^BE(U40c)oex$nLCBa~n^$!j{4mAY=5My?WkLlK
z<iGjS at Io^Oe#U-E3!eJf6&IIkMNCD82TF$fZG#T+YAr{(Mp6>dM2SPm7~Swe<COay
zzCb_qSL63_Fu2rwwm=SqUV$V2gBI)YvvAxlHT0Qyq$!@Ul<LcjVIHj7W$vv+f{40p
zK(YZ72HdAaL_M0V(~iSOk83G*VEZ1UaC9>FSvK-B at yNy>u3%vu$>z)h%qC8~dsiS2
zqos_Gbh(dH^X>~|{9^1@&1reNQFc}(5Z^1Bt78Qr?ikqKhezM^7Pr>W+1b(Z9fv5K
zGI{zNw&h{Bl`GPx>xbA6kqk_Ci~k-Q?bZ&*KPIOu->4oJTaGnx%D$TLhW2$SV_vaG
zm?$Ufs2%-c$#v_ at hHBX2+Hj%ojbw-tsxRnOf2(KNxO|yAdb|0<IYQp<{!u7SpnEG<
z%AtQuVewo2k25`^-i5V3Jzu{*OQCsQ_ABCa6t+ at 9%6jgwh4%t{9;makvw(>Dx28Ml
z_LCaLc$&?~2G5oq|EmqwNPGMgcE643)R$bBb#}MeZKtc>x%OH0D6G6>X2)Ukr*1YA
zS`425&ew!gQ!jDa!FLsx=}OmL<$LkY_D}8Dm3~pCZR}?kZLct#=gXOX24<eb%l%+S
z?RsWmk(c*q5#5_8oGxK3R0#$2ca1TNkd%+_P?P9>cq0~k)(g0f-6EOC-4P%NO|zzZ
zYaJhk)3YI4*B2%w7cOeejuR?nFon?Je=WY78rJrq2W$i?s)C<CrW5rjLpWw1r5Yw3
zD4TMaM8v}H^_EU7r=}^Qp&y;}0wZ&pT26J2Y#B(N(fw*xv~`=1I>b?uM9lIx7yJhl
zh7#We at wB{2pb9_02FB}`1z!ib!+OySrr^J&QAk3w)?K$;up%p at ZSoW-YLOZq&4UVK
zsmvoX7oyj|8{sC`-cadi)~_FUm9WJB_PD(B)@gfX^}lodk$pLtF8JsZq(ifne7o9J
zancre>$mM-)rj%Iymo$TI96=%&=^YbiCqJqJDs>;%?aQ6n7)@|@6$Ng2g}BreDAC`
zN})q+-RhOQXcRU~ee8mLdwj1a`BOukgsMgZ-S3*570A>)qi??$AQiOt3y;`xe<7yK
znN~|%wk*AwI!|o9Ep?GLz_TbpC at 9@REHe_PmP|394)ge`)gr!B#mk*8Uq*KL at VL03
zoL~m-v0cHCPLl9NU{LSDjNqaskz?`Cn!L{)sW(12d{r)=O6&@Cwuh)DR=So7e?IJ}
zu9Z!^O#{CQ!It%Bn-c;Lr=vA|;*?`1)3FF at VG)7hw+68XI>;A7jUM at d8Fsb%-?{YB
z?kwYIDVs?n59Pt)lL)EQizpr8*5U@}7rg%;05d_%zK}K{KMvUvq9=$&AD3iA1UDkM
zu^N*oV5*1;as33+-Gex-s5XNquCF3#3T7mIflv~@@hz|vYY4j9LmM5!a1D`>4owVH
zgasAjnMH%dQx%9JDix)(g;-&Of?*0`La?%;kS<ElUPVQn36!4TBO)1=<#?|!beIU*
zH0UniR#w3Rp|GlL%&%bxp&a5&Q3PX_>Smi2{-&HmwFL|by%k)@uvCfpDvn(v5zrN)
zM$C`M03<<e4`u~1mJl42;fi9++*(OjRaRD4c>Kwyh|$=&G|#)g at 4NWO-+q>(Cznsb
zsMhAa=ffZSTZ%Gp&+P|sRMn9FU^wnJ*;-M(6rGvL*AIt7)`w4$Gz`O7Y~D>K^Mnw{
zvXtAe`%YGl|2e_dI57VjTImuo06t+(U&b;2msRy_6y%=iIVbnsX)^Ss>nqhk&BfR_
zm??^aX0tgK&8!#T`L>u%ZE91ye9mVb#MF+Ws?umQ#?^(hWxE7nP at WuRZ51KXPIgu;
zjuXAnlg?{>zcT^7uQX?2YjvRhIZe~?9ya;x7qekbR=u_cHk0jDSIZbp2CZ3^of5#D
zZH#=(EAhuO+-GtwZ4D}~x;Dlz5)P1vNCS&2sB=WO2gL&=#8oU=z$C?43$qe&yRq_d
zG~10>iDYw_Cd6X1YDcpQV}R-?yB-nIYPD*D4NhR~1zfX39Ij*KCc+%jXd_ZqS~Q7a
zc*45J)R0(`&MZ)Du2K~(97MwywQcAqfXAwDM^&8qt7-My8go*~9|#nlKuOYU5|fND
z%n{ZQn<pj$so_!~t`*QSoCsb)vVis1M(u8u$e6_e;@U{oK at zQkvO-9bRV2<pY+#!w
zh-m`}>xi30Bq8_>G at S)oL!=rvaeJ^l66FLc3dt^@;7Sqz*cw=j^)yC(g+)>F>ih5J
zH4ogwAkR;`=A2Vd$M5}z53~5OPqW^uw0m|e&YjZAw)M=o)V-p5UL(p7O{%$(Y6r|!
z?aB)GU;j?_?Yw~~J@#~72~jJu1_SXeEVwF|*^)fkuIHWFwPPWKaYxw2oDKTif^n2(
zc}nK4uE<<Uv^2G;P3__imD=en%M$NB-up37uH9~vW!ZTq8kD|2@!Yk6X1Y{4Q)h76
zlO!2q=O(K`+qDmDha)=~=xrS%Ri)eQ(rh+Qsl;q&CdoNhRkubOUFSnz|6&C)F~;%u
zlw~;%_}c9@?RNWul2#%PC+YbeFr%treMn8V>|GUSN;0DTAL)jfLGa6n9R=HsaRQSR
z37e=(F&z?p#So_H^$>+vE)#~4%+2GHE;3>;GmIGgSdJiCB!<!aQGwnG%t~T1ho)^}
z7-Icnm`hLxaRB0)XwpJ`50#8q3T|;18i7~=`iT|ZgcvKpw#Dk6F^t;4jcBnFsx-g?
z5=Ye0qu;sN4zZOHRgq>&bREP3QUnx7%m;+oCUR^AUj!f^8!MxrC{~&`RVj*Cu47?<
z_c>Msq`O4u?g#B-!J}>t!YUSLAST4}8>2v|z?iRs#pEWeI7xH?VuG*)5<u3u(o{3I
zRy?w-!LFq_RF%U=PS76=aZc&9ny1B*h$sgS?5Ewzc=p69Wr#SZZ1nmZdgkzWEpL}@
z%j7kZB%#~fiE5Rk=@rkAmm3p*1G`!evA6X`2u*zOqdmD~rS~*Gjw-Y<j*@3gHD;!E
zTC4q?x)b6ew(80z53 at R`2_fLUr_pGfHp?)zsZH(tvvL>uy4nG)Gux_4tJNA;1}@~<
zgYv|4?bQa&WNGA7+Bu!kt&Zn*u+Lm7W at f9CK8e?8Hk)H at tQTUxsso$JO4fEU^jr#N
zX7aUl#l3cXk|d$gXk1)d$4JM^Vg)8YU#rJx>$7dgIBf+%Z`-;J6=)x=FefUmdjH`V
znkp6!B66Ha3-Lpc60;QZE6|$9g%)NxAr8rV;M!eqh7~!uifUM*Rm@|AQFR9J6%HY;
zAHv%EiAe`34x?@s?H{LT&mb`pdOebvMND at QeXnY@vL<nU9@$tUgmP4U(dRN5u_B#u
zTHzZ^1&y();z&ghA|e&;#z5vegdUi9tXbmH84?^}aJ;Gz#aT$ZxZxT}w}l_%gte3C
zNTgX}Eh1gDDp~1qojF7uHrzzi16 at KHDyFxhhtNVqv9JN|08*X=-HF;dmK-DwpRHQw
z^l4Q05o3nMV^F5swhy20b<Q>KPR9^-^Y#1q$Y;KUOB{dr!N20~|G;;jo}6g(`W=gN
zEG^8lx>0G=B at RCI$YXr&i;wY+H@${;zw at nUrBy#)otdqF+iW)3(Y=#rHvfbK<>c^D
z4zE1Q%{#w+B!>R{`^9J+Up~a)jlab$DUm=YT^wPx;yHtvsh|1M^ONdxyFN=VsWMXo
z%)IyG1y_H6IWn75o7&V)zp!h^d at _*9vW#}SJ=RCLFh@`6m&d7_Oq at WbUCy^1V-m={
zoq*a)bt>vHs-1M_9IaOCytT0|M?kZkPW5&KL6a4kx_!9WY>p3(i?Kjazv&A<a3<!_
zl`xmi9f2um)ox{@>IS03;E3TQ;*LPtsTj4ifz028OH#xs;`<;a(e13p%AFwkK9Y8E
zqDTy*V4^0U&@pu~P9Pe%3>h537(#OgCXq62phbzOM^q^`S0Qy+)<y7GERZt7+#*hE
zh4!ifBa8wTt*S1#s>RJPqSQjwhNvN8ShtCglFT)cW{Mjo;5P}9W1S^5YZ5~rDK<d5
z<h?!&)+*q?L_|mXhpW`#O$0Zy4+|Mq4v;Lv*4L1YCsAn=Ee976nT5EH#Wf&>WDhER
z%r&9h#5LOBGMw&3T^G?KRr?v?irv>I*W`mQyNkU`3uI}+pMUgIeC(5-L*@Au>$-(?
zVQ!A=_v{?6o&GRqw%g|0UiknozwaKhG<#lx=whF5^0i4K>}|b)X4(J~0z*Ff&40wR
z$DbhEB7|8vrH<Zaj}JfkPZ`J)q=`}lxP8YDA!yZJISo{%c9w)-d6De5T3;xHz+f<-
zEXz}vkZP*5sZDKaFH9h_71PjawZ>vn7i)v^#3+<8n(6ErTg=Y3*=)swycmblWYuc2
z+R$h;Xf~TKI==5p7^g|6sUDxn%3j^_b at A5^C>O8iF-Zte|9r(dI3Z%eh#^)LjTng0
zqZTXHvT}pyH_#-5a#)E#T8YJy7?couK#8M+vo5Ma%m;YQkk%3sL!|)|?K!=f7?BVw
zj9ZL|3ATQuVgXCrXz=J#7hBwgrI6sUjiRFZYIIRw5_`+A(L?5DiP1)s{56?@VbNFr
zf+za2Y8k8B%ZNmuBWa7o+9)Nl+eEreEaZft5c>h~IWCz+e7~wjtsMs%1eal<#DZZy
zRJaSPs-~{7lb8#>{}kkXtSq6?z=kvUyudWU{D6?JU{Sz!U?wOlm?`FskR%lYvlC(f
zE7yr$K~kW3#q8y0t2*r2y^~kncLx at YyeRnXKl}jy{)2zT>dG=P1Tdq>ha5WeG+%i1
zOEel8x81m(qAVHa1#f=c!~FNZ{4 at OWdwz)f at 4SU#BzC^ttdKsG+<M)sXs*2laUQXR
ze)=dM_~uXWsV{y2p9>b07zAIy<4-)wAAb7hd1CXA>C7Z}JiFRAbH~!V at Szx2a?iI?
zG_{w8)r4bp0p(&WsV7sj*&Js9>cgcz^ri#=Q=8fg at 1z6cYRn}$*uWrE1OS-PN)|53
zS$}>uPF}Dv+Ulg&dsmvKSIlR*bv$0ks`lwx%j)*GOR2_eol)a<sBIdj`pmiFIsnoH
z74R6YDl=4-6Rj!@B8u61g)2!HEB3P3B1T0Up{iOCiOG(tx<ZMQ1Wk6r at F=dmK*-lH
zQ3N*@x{MZ4({VeWCJu%xSZau*(9025B0@#+oOsj^N!@O|4iV{Kso{H at XzFmy4t}G;
zlPFp-o2eiby}_6iAdXtl48_U~R9XZ};p7SoOR$P54c){BZLHD9wQs-=o`Gfu3Xe3q
zhy^Hz<MuM5p)-4l{eamDn(aYiAJZ1nQ#1)!*o3kGW<U>vT~C at iigJ}0=8*Ixq;t6D
zZN!yNA;F>A#M^O_q=__dB={A;uE at Q8(qUH-e&l=q9$)_EA)Yw&EUW9A{L4T35Fh>Y
z7r5>EU9_7S8~vOwe*Gy{`#JyPFLim%%kSf}U->3K at YXkS=fN8ZF^ns(+l50p{p(A9
z at D;ztzx=yTBF(38ny~4<%wHb=5kC3U!|dt4ibNY6+xRli4n9I~8+4b1v=s@!TW<a>
zlomx8KJOk^MRj&+m)+{PV^R|4qJkNya59ZXW87+1Uw9JyKaHTLHnj^s7|!=^>$a)-
zHLX at _Te8+g=<{7S{U&d^@&6$AE0nQMh{d)!?iY&-y3lcYl6Nz?R2X)C+j<8vu<
zX=_DBL};~I+vYUfvhaPCcF{J^p-UO7NviE_#mxAU*h<hE8y^E`-A)*)(7-C}N7+ar
z&Y<L^jV5Jd7U$bl#YT^hgee8d=J123aoHTvm(b|KU=yp^%*?73gcynuMMfk9f~~J2
z^E<G90UC(0fhJ{zUkE8>IEu|I;s)!4=s_HAW)boYBx at jLiG_gZNLaJR>x{tM^=IG!
z%ux=HkTiEgKN3eeBCcUbXb^o5Kgf_|1<9IdVOS at Deu*?@2xds$!^A;*i8v^cumQd#
z(F{x5;QQc)L`o#-VCKL!LG~jK%3^>@mq;He9U6PY!RL^eVqOXI1ZldPP!!N#27i)T
z$o0(5`Sz~C$$M-~Je at 7TXf_-C(|`E${MY~MZ}IrI4&!~~D^DKgD^DJ-f=#okMG*M6
zfBsQ^<)`1pKl;U=#0-kEIO~0$k7J4F^yAL-dc#PQChxlE5BSq>{xF;2Ns>g7uBWFT
z<4e7d5kfV+vstCv7F@%VxHfOO at z>bXehq_R at 4TON>Sw+*eWkji;bJ?%bn9VI6venN
zzh=FuGoVwO+SD#jz%%K5*42jX%Tfzv9AFk{xOuwS{;P7FCTV_a8pkWCB6F at y`h^^$
zdOp<^neDV_CBceqeeNsPf`N|^0*n~HBm{!@m<gtW#R!tYaD+>93lIYhoy90By%<yQ
z5s?`}KSwOX@@0a}5Te61XA!CvuX;2r#?iGaZIx=T5d7Nl3R~hE2tyJTWPT^4DItR9
zYgjSB(IiRc at h6`p<Pk|TEX^twvrxUKIJ$?#s>RJlElx(oLWT)(Z~}={?o(XEl8msl
z100ZsN&?0gh~}`cR0T9X$7~MCc0qeL6g?={iI$?tE<#ceiar*HNai4ILOEhGGDWN;
z`b|VUQF}-V;y_H1C?jahiHf1EI0_i}XSrYn=ofe|IAv;uD$($df8}TS*>`;p_uh3g
zt!9I~C>iECK15pW77yNgC$GH!ZbX!#cuv at S>vhkzjxKfoi56LG-Ok%@`M2CU|AUwb
zQ9P{~VScA$akpcBm(ZM#NF%VP`w(xt<^SgP#UEvu_b&<0Gqr2q>ek~t&o8<Y<&@@W
z at BNr5$vH<+6k}GPDFMLLrgr(A&^nO0JguD-o6vT5VbsZw%Y8^qVu{i;y<{BG3;Fq;
zkABN`-D?sfQ!|!bO^4bQ<?yIf*>M>OvtW=qbR<@YL{Jb4G at V7WtisCJ3^F)`n#W{_
zg$|PLhGGR|6HRuZ&0SD#U}}WeAZa_Szk;Ad3~@4UGpqGz)F7IoWe>78vDv_jM_k27
zCP|Y}Y at n`%x;ACGfsj<pWHOJkhIG2bL7(WY(t4?p3{sJWFrsL#xBx0LfS8{oG at H0)
z7ws2_U%|=*%d`>-Et>?}L{A<8i&$(x7!bR&NNx~PEFMR7FVYg?a1*BsnA^mX1~jij
zdSAsz5Z8pbin>K&Ttyq#S0oFYj}wY!MPk4qB(+M%#0<hR>UI*ivZ$HQRfVV%4sU+l
z!@Tb0_j2UKGArwwc<)Kmgr&JzcJExI)yPI?#OZ^At%AXq+GcjT?6?mlbJ?wY`+;BM
zo*h5M=a2n!p4#{@-bO at G3VYfw<H5bZz`=#L<3g9gVE8=NvoneIPVJ>@ldPl{i<>zm
zn8~t?as(txl4N`+)_rW#NjJ5rou5N?J`UvR1TnAlwyD#-hs*7RP9Au*lYX at XGL!G2
z4*D(!;C-uuQ0ZA at R~6oIGHG_jkOEYNimFPYhL}Q8qRt_SVm?&W0nN~4A7O9;iz%W@
z__TpYfk*?@c|vgntN`s)0Ytuu(L+KPDTnxwp-C4jdWci3tSUcJaoSdGWuizhBx?|f
z*sz7mfWuEgYoTHQ^MW-x`2Gr7ZbG&b(ufut#H4}6fNM6;!4Seo;7}_HYBP_dZmdmX
zWgxl=BjpBt%p2t}W?TROAOJ~3K~$1<h^s?<6Wm}ONf$AV#IjB3Zy>%wv>{0=!HRW|
zS=2Iu+lw|j#C#cC6T%Q1&Jn{JtUrcWiin57F(Q!|hqydLv?PXS at k2l(=AS?`K?2xB
z%V~&5APipAVCGEiTjz5QG#e>5UAKpWwUQ}S>t7x8Tu9(_v8_7ide#^NA{o0|ui|Y7
zUqz6L;G$ZyN~UuV6N<dR$NYi<y{S!ordr$Xk}xwhR;FeK3L%hX8F`+MZ}#MqPfkaD
zYEwIhIp^53XU{nghpi5%h>&I3RmUDUneey}jL_Bt?Ofwjx4ULpcGVqzlaBg at VyU)L
z8J}y6YL)S;DJY(NACn at a7xVh<!pxW%;wp+_oPsnFiV;A5B&2DErCro5Vm`-2F<nEF
z7A|#^h2dl;W`}_RqWh3EC5jP!4^1GtCNe)yvT~Rp4qOwnyu!)gs)~sUCZHJ7XcMzV
z;$WF93xs?I>p1WmB))|-x`cccY>1?bL at klviGY@1Q3*-2Y7xr^Ag&77MzqE<)}InY
zYkGi6Xp>?SPlTCSTz`#dO{7>w+zd$yq3j^ykpyCM9?<|B%Y<wZ)f^vAqGU*(V_5=L
zpfU%Xgv?-Y0#ijyz*e9=kIzpaF-6lB=AU6CNB^8Cs962Mfx0t(mX{i!oC|BRb^p6q
zT;Qc9GPbUrGlA{T#3*(?dkw^@qtBX5GRXBQf#R&myvgL<)@Qw{1a+sjtqFh{w|}v1
z*~z2>R%Z_DQcwMV^@O|m=9{OJY-&?Gk1Rv4*E{b+s9sYw0ms$&eru<@-Y>RuquZ)T
zeX$C`FZLMKLEm;C*w0rCm#Z at 1o3zPu=S4keV<d)%y4 at I?5ZVZRNT^!K=z`5xn3ix9
z8VkUV${7zm9CIMcm?aQekU7i(He5xM9f%oX17y$y=a9TvfkV<3p*V>~!<kY>t3)T8
zbBNAhgFYHPVX%U>I)tK+h(j!)>>a{lB*_+tsi850P$E{KyA~*-;+BsS(*{;VBn-d_
zVv&eccp4Q10ShC>HUp_Bq#15N5pa#&P#gtGkl4r5KwQAAK!c*C5JCmqH%?&YQP&}q
z8`$h#5)&*xjFt&TmpJ at ZMSdWH#fm1{!ZMQXK%B?&Bh-la3QHuFXlLaHj~E*4MPKKq
z3o_~!n#*NnSz&2vob&mto7!pITG6SAXfBt95Gaa*qA14WvbDlLwU?G9NkW!oV=U}N
z2Qwl<p658{Xf~T;HnTj>Pw7pcwwX<BYUg*Loog{p9w7AszM3h}>uSJcaI;-b`eX+0
zN(cO(&p2&&3)R-l?A3;oIn!La5?akfBhKvvh6pL*a>P}Fj*@h-xQpP2n6Ba6EJBwk
zMvx({Y=bPL%oD|9+6Kumzk#L+I1jOblt4H^@C~pbt~E!@kD+b>v2~(KrE8ORK{}8d
zs%w~bk;WokhiD84ZSru8L}x34fXtyq)f(ioHo*+v+aPVU2#KLZifbuB64=}X71X2x
z^pEsyYMh;6$cSMJQ8e@@@@Hwz>>=iB#NkOaT_jotQlO25xVeH;p^SaRgtW0lSuUg2
zMg}>aWgJ2 at 2mWcqM#&HiQ9;C2c#HCA#q?%XOB@!ficzQn8c~QNHmw(fmU*%@a&p~;
z5Gc!%;c!S<mY2nUs`tqHKJ~rM7SL>^M6a(?mL++fljr$mBYmpRyZTw{fM)7fzO-%f
zjGxpXyWn7^1|1Iu0~(FSDQyb%p)$3pP3^)r?sGYybte64tTvqPJ#BYJy}njmmATsY
zqPjY>UE{R1DpQLcU+wd#elIU>KfPgoiI_M{N>uw;T*5SB%#nm9k!38dA+n2L9h`xM
zHE>Fl9x{6ue&b0*71I>_8m>_iWCpSZR`dzM;Ytu~Vww|&Cy*o~mcCNF4?Q%Q0XL77
zB_S at 8q;r^biEQG6CwK>CAJ<wUlq-nqV5LCmag8BnEhIE?c}^VUNSPpMK>$MO&_;_e
z=z&Dk1O-AY!33qEhORyb8*AYtzK7pD0_hUw4E23fBPK1Z7-CWqM5-Xj?ZOX_Vi81#
z#Qp%6DZ~Wx&mtqzflB`dh!Ba at w<e>Ci-3X!fe?^rXspN!o(p_moc&=^2sTaAab<ou
z9MbRi84ib+B|w;L(J6{z9L&_uaVD$Rma5{t$9qp%mJ9}iv3UCBsw8>uDT-noI8E+}
z=Q=m1c5PZ+t!ua23<iUXntRFQA=_%T#?Dn)mUKFuaoKV5keS-lrgrfG&DOGheGp#l
zYb%5>K9J7E7k{pP@~zA_bue=+>_7Eqe!fBP+4kP8)vMZpxfbS99lTx$-e9{hGj%Wn
zDZ&~R;A9C=hec4G!K{ZwkCO(NhiF8<g6IqyV^#4ea-24S6nu%f0?Q+`+i2Q^{u+`9
zF)E at 38XY0@&=_%AQ9K82gD${ul}JJA=7})_m!m~V6cBaD&N<?-Wn5<#D<YIR;&OCm
zC&A~iIe?-Gp}<@LD83)j)FIj+X+=VR1GHi^t#B)GM1veFQi3oFz*VsT7S=1~vvdwA
zBGE5{HL;{w;cQAnbqOh#3FSKKy4CZ#E;h`8XVD2=9kW=CHHM6EJc3}MY9}*4!t{*v
zR}jO+5wjel=bhMpUI?9;t?O;io;^JJ=%d_y_uUjl!RF>B{eJ(lR3Nre`<G=oh6wE4
zyZ4OGUi*2iR*R>edWv4JHx6btHa5mV#^pE<>$bZ(fCA`rI<(vEDTVV(*hdl(LI at XK
zKuNY9vT2%*zt%y_wU9NQ+SIPJ1za!U8a#ikWLRn@#7nWQ&d9Y;m6_aU>rCXi#_2*>
z at l^Gi*{dg+>t4Jhnt-fSfe7uYEv)n-fc`obS{0bz7ZoM5UqNVtY!YLFQzZ_Mg0zU`
z5Yr=QoWasII#?$5K+-1WSHLYIUWpt*-2!Hgm{dS~bql~M(F}=!&}f47ut9*Vi at K6P
ziH3k?5siWm9-0mUge1Ydhgc92L46N(En*pPb6uo8i=8-xW^E*CLOcesB0zSo($R5^
z4$%UXJrKpBjR*=9@#_@}T5BKLD~OUqEFgN+?ZJv=jCC~GN7Mq<2C?rUEfFt7i)dAr
zfoRxRBy?1{R%$+iDnJ at hFrXk&Mq-|k7jt`<Y}dNwmRtDjXFtm$k37PT9Xp6IlIJ-^
zQCt?h+}8C{?=3HT*~`vY4XRt>I-L$nOG`ZR$Rq6CyO$W_xWZH8X12Q}w%!AQG0D{4
zy?a?$SQtO=G>~~|S*?dw2Q(LB$>hb#vV7hlQe$YQlWS^I+up;c{&y`U3nr@$mx6iN
z+CFtHjnO1S*>;Z63nk9^LXXp>&ZSEVW{OBmXHY4z!obZSY at +%yf<A@$oJgD4-z00!
z6WkDV2hMF0f<a+eI>78Gc!wo at q!6sJ2rd#rg*Cy0*)aqKO(D$@Um(&U_D_;@7O`|4
z at pDAK38ml~is_J;XNV3ftrhE1mP4dCj!PDZq{L^BA_7rC%RWIGNZ+BYh!iE|;3x?V
z;-+9WfH()T1_rS#(dG=e8K8t at 07XQ!iZDcCMJ85kQ07mgop~rr2stj at M<`EX<#CXm
zh$|}+gM5fI1~>zsEFi@(#3><<I91HzxZTV`MZn+^M=U%d&$Z^74~zjbb%1jPxG71J
z at bJSA^YqhC^Z4VB)9?3Ru(_M2Df{>D=bn4+q19 at gQ^!R_xcTOrSy))$vBw@`Wo6}(
z6Hyo9z|POlbKiaUv48*mQ$(Y$7;5&Zy<l^puF7nSXlAF=!Fx}m(O_d^<CM0uDQ;$J
zQ`<f#ZL;EUt=ZN#s*4Ty>hCWW5O^h9-I8}cL=opZUe{U$eX`<oHV5l+IX#9!;t(~=
z1d|MW9~vEk41tWq8H7HP%@X}8BD=BX3}N#amUY1jB(7Fqc2}_oN7m5-q}e11vy}Nd
zjvU+)Mib{eR&GK%gGm9q4&Yax!MP^UhD7g3G9jAb(hg`r7_>2k=sgmiMYKs6tdevV
z at FbW-q%2TPkf2y%NZG0w*9=r<pgka#iWT5w7R#5Btb@~8LVpv%A<f;ycoYkvLZ?Kq
zk<O;-fH*8sm*AQQC^x=>rn8XjK{N#|h`B>u4{>dxrr1Ug*SZb{hY%-(7*G|=A~K?e
z*7^pusHa2-BLN^PK~b~O{D}Ut&58462&?Dp!Gj06{r1~m6bxG(7 at VupQCGm1mX>(q
z8{hb%>>;%*$ac2{PVMU3?=Pjh;FQYDWDnz{3i*ZhE>CT0Q#&`#VG`tgtvTv71 at YO&
z;B4cxmEGiWI;}7E7 at Z4Wbfz(y#1mbMb7`{TbiNMdcI(Vw3L&qQ*IlTnfy*3`$3dGI
zS%sak0;7q9HEiu9NCznk%#IV)Rn?0CQ4LWghD~%>V3woWs#>#rfuu&v6Oaxz>=Bz8
zlpak4?}t at ICi7VENOwOTaQOz}Am&Ad?~zIv6BWw!lektFvjmAX)$}G3Gt31f%;986
z&~=<OkoE!+mx)2Z&7p~-EY at LhCpH+On<vq1k?7Z}R<|fsWyHXIghVjc!uP+9(IJ+7
zB<TP>Vvz$079w6tT)G>TwW_e9O(@sF8<855Q-S==D!fij4IS%13ai at E>XtOovF6N$
z=vbX^5Obl|sRN1{6ZvASowM!1r+d~q!SX^TkG2YZUTr#SQ at ixfza|~4<Bv-UX3UJ?
za7db_V at 8}>M6=m!PJ@`KO>LVN?&R02oq6hXRv$)}dLUlQV{|%4{Zi~&t)5SI2D}(&
zP<8K!(+1Hkp|TF<F(MWNp5urFEEH&xW4a5~Ht2xhmr)ss$&RWD)#n}&O)8wph+3G?
zfUJoGK@&fUp&Tw6Vf{Fw5uu581uc7cOOf^Cs3b_*g}92u3eTb%iA2C5D#UyfNm`gL
zVg4jgVA8GVmTeQWK4^k3N~GH$79O$|sz%HMnmOq8h~|;z3=}Dv&JhX$RuFAqWe*yQ
zsGA|!5a-%x7+}@~-N1Z;Iwg98&_&ZtWb-RX(j}HFnD3+Fzyc^liKsEE&{)M at W+RGd
zWkd=9;uHxH8xaUpgL(Pp!i9+4ZWYRXG4_`Wecl(N6X#5#qf>k7SWR40%fMU`0l;Kb
zKFNuGEjkiYo7$BS&|K?lYrCA#YqiC7I~<3}s?2nZF2 at 6uU=46BG(A8p9wAY|hX(3a
zsY()xB(7qS(vzsn;BBSCzJ#i(APB*ih^yodEJSdM#T<zONs9OclL4j*u8qrjm{%O@
zNL;{WKpr4<B(WgU#$`>4{!t|4mDr|vOe$6{K`=2SDi#Katf0vbLg=IM2r<l~Nej~k
zsu79;d-hw1G at w|)+%BB- at OeOVP_=)RZ7l6U3^<)7D&UV{=>pnVK>Eu#&9J1>uW at OB
zplHa^R<{ZQZ4J$52}uhnjzJt$^EU)Y1Q9BV>rq9<{D>ex1Y*QY5F#ccCs at I}RV-*%
zm@{1OeJ>OaWjh0lsZH&LvPn_dN%Dz{3TEow{Sd;KS)l&8D2nL>pW4*6>0rAYYR3`B
z|Nhmt;Ci2=2stwXuig1GyyC$Bz_((~?|$taESArZNsAvl_}f_b)qHXDZ}`j;zrfGl
z{(j2rz_uwgY|TnuXh1W0puR9ptnlc@$N7tI{Q@%h2ARNH_WqaLzW2YP)b?d{8YZc%
zFLsPBM_{ay^6w7)cN{+c8+gBhM7U at 6mAvi7-ypW`=7T5S$CnQMDzP|1jBtJHdfs{C
z|Am`*6GqtfHFLIkaJkMV0W6NFw8APj_#6^EA(^Q}8>NATJ`qFx=<g{B;W!#HqIeJ^
zloidexawNbhl&Sm)KaBM4u!`W8Day>9Y8vZ=<%--vji(=A*;apF-fp~f@`EGIia_P
zh9QguCM8B9enhJrhzQQgswy;G9kHD)A+ktftN5aUq=tFHG$O9~|Fie*QMP4QdEal&
zwfA{e)vf#N_d{w4q?Tk5LK0wM2_z)q2t&jp=3xX5*nmwuFtM>ShVU3bVh^xJ;*kUq
z#|{JqgFp!m7DfV**q|7J9w<mHtVg%{ecx5L>ePAdz1E!hW1W3;ZuPz0_fd6UedZW7
zx^ACS=j^l2+H1{k&G~&_zJ{uV`f04Z6O|pjszFw8*+S(29t`3pfi<E!p=@D0XOM$;
zqN4#`RkUbjubL{53W3(0sGY&$0Ix at AYLU_wLJ28i;sjC5fHWIWvs{e<EZL0kAMqfN
zz^z7$0<$dPOtd|nA4{p=Wh~>`<VKxNhwbfcTCLXARc7kCp0}4Z9GU5KItMyS&df5F
zv3Hx{UUD1+ArZN^bw95@^4FN^8t;AT9sJ?xf5DyIm-C0(rW}5Pzx@@*`MEFrFy}Vj
z!%F`({NYpogzviJ$4KSf;J&9qK)YKkF6JY1p~o-OBC&r7tFV)H_~nPclQ)EQzWjmz
zjo;h;Aiw?eKV_wLFSi}}KK84FyAfNt*cj~wz!w^i{Tic$aX@>#?2dm(r~N|y=-hAd
z(KEly%A-HTn_l`y+}(Zw_uu`G=@z%~shtn=;irF^qmTX_{?otk8MZC%88F`6KYuA>
zv{#%N5C{<^U=lEogm4fF!{R2+Dykh+HnS5wj+<q&KZb??$c)hLSvq*;Qt!#3EN7l6
zlKoWDStt)6!_)X=J6qfM6g+^pv7qR|`(g88+!VJ}+{QV-_ZgU)dCt&Y!Nyyt3nqpb
zpam9pkiu|1h7<6(0n;h8j({o2rUXi`LDmPeb4alUHpX-ZF|d%J?8EddR!#_$1ElFT
z+HQjhCK1&RsRGdwFA_l<A3T~XQr5*~it{)@+nMvCo?qJ&DhUs*te{q%&FyYYrKSL)
z%+$`ZG_-pb({LQZ{sEC?{<Dl_?9*|g2vt=PLbzfZhB=sNwOZ$C`Zt7}y>|3o#xj=i
z#T$4}fCEkdzU99EjzYWiLziDX{m(fveFXE0H>`gf at 9O+4|HCI=Mjz$&7r&QZIQ~vv
zf^qlJA7m;8(QA at T_Ov>4H7aC_KxjX!GeH6mjX%lybd!5-|5jdb at NIl;_sjU7PrjSM
z at Z;Qm_`5(_`v!FPqJ?T-#>gXYxa~(Mw1Y~)XVW&1oc&eQv(Lv%`>*D++T-~42iX{X
zg2PhqRd at UZBd_<=gMD#~F7_GsZ+<w`0V`vsa!4E3DP9eba1?BWQ-iF5ZbNE-OG2c;
z>WBtIy}*1%PIm#7YyfF99!NEl6;6&YK=cq6CxlY)l(49od!u9GnTIJPf%gy};j)gW
zO;kp>6%Z6 at A4Y2>m4=MZ;@W~>cwJ|J61P#Uk=C84J5CQt6WnSfZDZx(>~)hORA(T9
z=qi$?m^iY%gZMT{yAX$H2x#hH(-CSXp)RmALW(JFf=t?Ys|7xRiY%DGSs>(!isrVl
z+$L7xv=BXvS0hA^;PGjgJuWfxXPU1E8slLQ%VW5o>-FVUPnU5m at 7HDA%yS~8M61=h
zViAC1 at szOfa}bfadFFIFos)Bxv5aNxZIZTUivb`~Vs8A#iT{y1cRs|u{a11SvA at B9
zz&l>?=Zw=f{jkc%Mh|i7#Lx2GFZxa1`I&DZj6ccOAO1dGcGpia;>POj-tUc1P&VsR
zbOlU17*0R*nF5~9As+V)%v?>PbS=h7rNlh(<m7WabmE_KhZKDMi++V|8`IGiA07Mw
zn@|2ENrV;cP=uANM0Ep?)8!r#(76i at 1Coz%0Tk5wcz6NgUqI3Zi8ku1xNPGTv%fS{
z0~Gh*@dP4HQc$xQ$EE-`qC*iBkD1(VaflWL8hUt2xGNe~2pX}vg|?@Vjsn|wQ6piB
zS3Rf`S~ybPMI4TB8KdpP#Ezr&2I>Wl;z1!s+=pm7i4^ydsxKgA7n`0#rNrwqNc$+E
zRIEOL_!iVP);WU44JZ;$iNr0``njF06m;CjeVi5A%7}&oq$qgUK&$n9<RYW2U{(o~
zxsoE5fLxslVFhFrt2fbNjZ_cN@?NZZ48btByxIwwALD7(4k(D^f8Pk}`Vz=o<HMI_
z-1K0k+wC%$Os<#%dY+nDQ4|zKL0#8WRW;|)EPZB{v5Y-V6lYb?JyWwn7}}8EJMm7A
zpZWz}fA~B3>iho%+g>AHlf0r6dYnz${2z~e7yt0ypW{8-zsu{2L-bz!Z+Q1ZU&BwY
zd=;|(R^02oxu!kvn%VDl$1#qz?&2d3!A2Ak*iHkw0L5Wk_Rj}suPQTpJ(n7AoDe>_
z^#Ok8vA at M@TletRmw$qt*8N~(YODDE+kXtd^T+t`x!>mlpZ`w&mxsTb|LRpkwwXD&
z at 6i}ti+OOddy48L$qh$A5+s3gOt8<97-O^$o#F_|`V{2^bED7>9u8q~2QQDJ at g!0w
zJQTSa6C<b)Wai7HGoWTlN;`y*ThLs9xQWRDOloA>hp<U#8?n3%t2YTc#EKOp1f)6(
zodQ|?QqtMa5!!u-cVT`8 at hP5kR>go+4+*WOKmuu;4Le=3%yOEXK-#w>+Jji)oPqHc
z6nBG-^8nc at Fu>{rwgy^&7l_ngj<pXWAwfKcmFMv3AcHRpxH#GvU#cQzhzXVo&;cR`
zu;K-1{48!Ya17CNK$R<6A>dTtD`+UO`V2N>EnV+eltW$un`a(GG*Z>eoN^gWG~E1#
z=5i(XOtE{SH6}}qan0_Vad~4dV;Ps1h&>lyWG|8~6XAb-<og+&`yC$aJ&3j+;NKnp
zCp^%5HHTNfhUiAb_`r#G^0t*%(>eThMvwk&db&n893}#_O|m%CH87leE}xl8d2BBt
z5_w7IL4Lh^7yt3xzoFfE3BSMnLGDpF)PMENM`WM)I=eRWOYu<I4TPR;o?R6{k{18=
z<U4uj>7U}5lpI`n4S%@tUe<Jlmmc|k{-4wDVkK?TZQaAu<4+-Ji#y7r<P&z^H&v<U
znh$%$naMy`fC<n?Yy=_T(!tG0b`F<-hGJHY2?VK-xP~euQ-mQB)}h)#!fgaSM at l=m
zmU&-AP!mvqoXm at R1{HOU`3lG;!V0jBcpsN at s3=yI1fS%VtJFhEhdKi!F~!e4frb_`
zDj-z2^l&0UBB?fL_XxU<TL9gHXk=lqtQzJfFgk&^)^X`W9g%PVNdiTI+ZK}6AoOt=
zL46j{!$|04|CuDP{ZzglQM?}DHiD#C%35apA|Ry-u>#c&ZWSH_x##Q)vrMN#NO<bc
zTJ<V0%b&X_ at H9d60G`feEF<U7g}qusF6DK01DWMP at P)z5^^&Y!#*LXLHQ;tU9<#c-
zdPT2OG?T2ZYeERLTCF+hay%YW6vbR!U^(%Yv5dV-;`cIYoQF1khnEUGJo+>bkKTa*
z<!wL0vDMcRF+Ml^Q^x0hi&wnx*Qnfi{m~!bUqAYN$fw at T+YWy_E9>9H_C8c)ZnXBP
z-QPz?+x*Q3-pg-2`a?YN_}^zWwD?c%`5BHK{0=Jiw+H`nu5<DEi|g at zjFE}(nXM1d
ziWS>Z at dqb<9s>>)tGx2)-())t_{fQWMqxt)c-89bc=NsgjDg2JtIAye`_{obBpsvT
zh*pS|gwP^Z5pM}-1iPP57R2}{=9<;HJmS&=eIZ&rilr&$y;=Lj5Ii8}n0uBVcEK$o
zp}++!Z4*KZ3Abam1Gb4tK&3;nvxH(DADu(H?X2iEsnG5n)b&}4D7e&!9l*j4Fr7`B
z!z4S7wtB!pEDaG#L=NCBLE^a?`_9pjy)dQTBy<wiK8#o&(;cV>sH|eeCL%4=4`jtL
zJA>P8P#%V~iCaR;gpIclpCUyo^NAb^bf&aiA=*Prg$U?DupO`|;t7ut)7&xQ^$0kC
zv{E)Pl@>@uIDq*k8jg^vC%%Yg_IWM87}#k5&GF;MdF-*r=0Zx#_+qqLE$+ViZeIAp
z7v7S_(aX5J2qEC^lx2CvGUi2d6E>hFr8GCpTv=Jc-RFFoWh`SES0Ac6cU*2NpjWlY
z;*{?E%h#r7C~qaNnR?z#U(){y9(>s+i8cnD7x!Mt-+TFIaFpaVTRz>hM077WAd3o$
z`weRD at 4k$``?8O~ESZa5QSA}1doD0 at wd2$zP<tuQ>^9{mzV!DwPabME+qP`TTkrS>
z{FOU at a-KLEk=my0b(>E!53Y|ZxPWaD{7$elxOY*HSXH1QVcx|jTSz!Tf~-sy+IZSQ
zq=hhn`XSr|rzWV*+Ne5+PY}^OddZMzSjf7Bs1Zc*coLO>(!)&&z5~)m^%!w-iqP&s
zU8A*-WI~!eNg->PMbuaDVu*XBSa}g?`UK(?$?nSFC~XrC-iwDd{Pdrq?L!cIm^_iw
zf(3O$n~cHMp*sLK=-x%#IZja?!QyEo6i962*1_!wsJdup9b=4*M!79b18NCNS!y{O
zhXT?eNFYt>?8j4|M#^=JEr=}?153Ex1Dr+J#NrA{jmI$(?t}6mOa~~5WQT!kKUa3U
z*gx{fBUDwzo8I)Mxy{8gz8Is?h(G(YKjYJ%{xq+6#VfAkJ-&<^C1Q+}WqHMw)cNjL
z6va#xByS!~g{JYCS%R5mEMxCBzQtsAuVQLD)VqGnzj!KWZbTc+6HdpdY&3tKT<7uF
zofurxYrv^(JR7&+p7DmB?K3X|zGrK*yB>21SQwARpInJaUQ^p}{{NFr*blzKZcBh?
zlV;wZlZS}d2C9bu#e4`dB6*3VDH_&rAAnEu$G6kCv~e-4cHAnUMinH26ri#S-o;3m
z=eBMSS>a5~@s#pdiel*mmIj#iaSgbig=#=3SMe%lev2w16-o<B4xz+-3#Ue6q_z<r
z4fC2%D5QQqP#K)Yho42tRj5m(5VW{Ii-{CU&>7D at tYLB%>IuYg<~&G=rOn(LR-eUn
z)_&%aD@!s!(l#Ok9L4ZCkO8uanH at x>o7+svgLoQ|Mc*PKE4WuA?Lis=Bi!<M<pz)B
z+;#u}AOJ~3K~z1#wZQ!>Ry~4vfmwuNrWm(J^W#$1qQ$u>BAhyPimIx3-RoYr1Tq&G
z%NQf7%9nrnmlI>;i6@@8VmaPr+!|5W^&HGzX=~=3Gt->x6-7Z+Rg`5p*L_~xc$c7N
z8Ozw4jqp~zpBAesi#_De1z;`}?A$7IV^IqKYUj#cS7vU+Xg0fx&7HmWnQ?arg3A<>
zEu6!sr<sD*Hh2at>g}xPl_C-nlD4pLFjraJaZ1!S at zz)3@)Vv1h?EG$tQ{<o$THyw
zs5>zw)Dlv*@N^2K23f^rrU({Wm~COHO;H{OKZ3;pq60{W5M2QuVA4f4A4kg;BqOB>
zqU|i>oOXZ?#C|rzRK-(4;BH7y=6g3BMq-TyAx$9!#daP+Wd)zL(g{7xwh&o^a1hlA
zR_|cd5Di7HSb64AWi!tyYDYm2;IfSnuzG;#F-SW&8;Grdcaby!R`BX^#Cx;qOHJ|)
zQX3w25Y5VPB9b{Z7nvLTwVp4&hpO_}V~_Fr*S~&WuHja=hwHj#GMO-)PPylvdwA%f
zhxn2&`4Un}bI$fMo?m%V2!UR&M~v}`tzhQ6UrLE~yUlPooNtPaAiz?Zc^S*tyBqgb
zCqFi7HCOuio-fj!jcUtYjMJ?;mzp-r>y{8&Ktv&p5IGIu04`3p6-|(eEDa`r_GVR;
zfcOqVIrEYkgO{ZGQKZ^NX=Q~jpCBeP0AnDAiOmc!4R^sT;RM9aAvVa;&Y^=<8<0SJ
zLW)m=MN|*sW>_3zwvEvR-$u$+Qmk+a)K4REh)ape3Q`5&3{tLP?K=R&8IsaHP#!|e
z2%U8#tRo>}smMYEzC(~hFx>(d#KCNvB2;)BK|RUlp`K6-6(#qT)rj8(6cDzvnpst$
zp at Zr+&_cYA`3R8-NP+1X(Jsg~76L+r*cMW>zywK(YQUugeE_bbynJIe-tBhx6ky*<
z`(KQa$z;OL&dwavG?pOCcz#BVaee at L)ux$cS+c#oO}E=UPbSUX=dEVTSjIB0ezV(M
z>Ackz at kQCqD_J*oliP2_F=_x`jPa_+=~kahi;2*+&%R;?6DaOeT+SeJ7-1U?UGRYU
z6tk4gELq2N3^vSC#oERhBE<?}I>194k#SDkJxdffVgo+&TR}AQY1DCZR1GsQHt?{9
zR9l3io!hx+4jxZ~-iB}+$Oc|*Abt;09Kqt_sN9LAQy>X(BP7LwK`{XD;$9&tc$#8`
z6G8<hcn#j~gHF(@h07E*B^3uqqitLVxh>6mNGniJPl9Q#z-X?-I6z&`%&^vQZQ+a&
z)}eC at -}x+F?4Z^H8RFhSwZLo(w;rKzhy%=eVB28hELz|Rl|F=x%wKAZNpGOU{kd8s
zpKoDi#2Bfnit%_%RaNsftJyb}<MjNC=Flp}c*Q*8Ihd*Ins&QAFZDI8A|Zq&YF@@N
z_6gM7YSEmm>~1mJooHW*JoRo)$*r;mHL5Mm?-wJ!UXE1rt$L3%2Wr=i9Go2)bHznV
z at G)*@kZ=f+VlqTckR*8FphJ}QOqqI|Wrejvsz<1-fK5sD21r0Gx70`onGhd}nXt8?
z4sKZ-8Vg7OT+q0U6G(N;eHB5;-E0Pa8quROx0Q9=+b9v$72HlEdKj$2ZHr_hRF6VD
z2r|grp792*0rlH5 at Ua@S4Lc|BFvYD!pq;OInlR21=!5lft?}t`#0$VsOSovhu4I|#
zqG8tlW_YR~jvzix@`{ikMWdia(or4{>)}>m(GeR%8lrj#HwB&MF%rXBBj|+W6-+)u
z9;|1AiYr+^_Uay6Cg{(U%1$X=vD^DHZoRoN9*?goFDiDUqv>=?S(cP#IY-dDC*v}f
zv5c$R#CG at j-%5uCjlANeo=iSlFZ!)$JlB93Gn)gx=K?g(HAc5$!lbH%5UA_=JaGJM
z_t>8AQKCpF$WD{s5hRo-6HFb|+aPpMdjw16>}eCwK5pBfvkIg4F*Xp!h-;Q84h7ik
z-WMfHLC+AB&-fn#o+3hlsNx3ViEK}!*_ at J;Tj6{PegX-{py*;+<7tOfRcN~l>1ia~
zhfw1(#(k8v>U5ptr;xIXatP{Ei0pu^AUeYR020A05CzmC&L*Mg;l6@|2-VZsWYlKK
zsWwv60Z$cD^ni6dZf3t4DTr~C5EN}Go?0M*7&j0(2)2QXpz2^lTuam=&S^xB0d?jM
z6$MuBKyd&KQ><8-dmQba3s*8PF2 at h+V*me2IRLjZplQ~=rZRn@^==u at pE=Q}m^GF7
zt7<cYT%Bo7!y3e_s&k*2Wh`SEdz2&HqOCzq#o=Pa|H~btX0f}K#wdjF4D$b8jM1$&
zPK%tP>z3TOAj$9q9wMSWTsm1bOeQ3InjisBiil?!VFJPcbPduNQJb|-4S at iXjWKb@
zEi$vJ%;u8rh&sdu+)93)Cx~@^t{GYuGr at t7Te&QO2dGDo1h;Ke6Rdm*8a813G!hQu
z at eAND#4R9xmgGY;-7^CPtC*igtTC}Wi>DXjoX*nBGC^zrGA4vWND_<^OJ6{fW>7WL
zD-)NQp=U(HL9ioOJV|K31h-A3+C+mQmS$~fC1y_|x=OO+lzx=t8 at P?}XdqQK-~?iP
ziXz+&bn$u{p~g}xx2eU=3_SO6onFTNAMPz<IWL;St40LiiouMkVrFxR=E-D2S(X$<
zu^j1TEMuPl&8 at Uyx;yQ5`#Gx(mzyx$YA)Ih!ErB7Y;VP+tFZ^Tu7JjCOp9D)uyxP^
zl_6*kv`=9Z+y#O`0`(5Y0H=jBL8K&;-UnccW4XdYn%SYui1FqiKJ%b5P(elKQpTig
zZSS5CAsbS<;O6-`4&pUhtdV4hh=Ce1-N31`qM8pe=_B?SqDR04!XYf3MfJr<dJ1(g
zw()e3#GQzqB+!Cl1YY6EaR-$V&QaVxlfjfH#63$Z=RUXmS*44m4x$yRZQQpoi->`1
zMY0|$UCcH?Rxlf(dW7gB#K)Ne6LQtcEFmEfLW#?1L~g at O5c*&x76d|PUYWTO*25)d
z=9%NM7YAL-xV7 at 2#unykR5^>q4YuLRG-aO)sS+(G;4+qRX^G{tZDPBhb1Sq`m1Q|6
zwKr{Mm%<0RR9WI%!6{lq<`sv=IQ3FN&9iZfZZ*TXcDp_QT$eINyDL<Ck#qr>#4n!P
zm}G^NHgUZlm7OdjECIt1X``(YODDmyWHS=*G{}B01XO2ac(L4)h0W%)A?{=!8<3#6
z%ghW@%|?~Zto2MVcT at z!5os!Nj)cQlazbH56!j9blZY9v0kaM&H7+G?TcGQx51_mc
ztB!*QM0N-q2JIs03}RqqM7>6=kC%eP0;7edhcj?!aCDF?!)#y at GkD=3$`JEy&{ZUD
zA}NuyCU_4dV15c at jCdcFqqq$aKa09z;#mpJ!9uQJ5o89S&Y*gG21mics|*U+d%5ms
zy9XDm?3de0`+Nj67uy at 3tEF}sw`Q)?bQF|j$#^`zVsEB7m}%TM%d(`dYeEQ2CKEyk
z7uEM)#xj=i+==?-B&IiWES{t{3Fwt32p3CMZ+6fZLZB#$c`5yJfXv0JFN?gQTS2N>
zMCKJfGkZ?&iGBU7DWSH4p)-l#f>a+zLP3y3tPG^Y)kzExZ-FH!){wM?#}QrxaL1+z
zS|#cQo`g`$5`VG>i>e|S8bLB_Mw at ZZwvzy6Gv%`ckXyNwh|5u|ifDO&R2)GkCxC?2
zhROsjkKpxL2nkOG1c7=3ZQn<#9>+c5aR&*<&;VX<1B!$i^avjAz_vezgd<ssx_)wY
ze+wd()z=)%9k&{n9zl;`wvGE%7Db3-kPe=92-*Q6l6G*WI4#uL7-tYhxQCgjf#Z at e
z&qkRlj!OoGR!=EfliarF32ncalpf#nwfwnwdzZ?K+{<}-v)<>sMF1|xZ)_R2Zmtw#
zoMVv1`F%N|%^x-noWtR8zJat_t at DVy%UH%T_80uztkJZjE>;}&@^jrPYf!J(I}hw#
z>Swyt#r<X<BX_6M>0DM-W?!S|;JOY(ydHuDilWLA#srFP2PsNKN13l8U8FdG>Lz$a
zQM6DOf(Tj!6hqP)!a6a5WhjHFViqxrneZQUUS&XLqH3P26hhO-WgrQ&BcK8jAv!_2
zXaKP(MNxwEAk~=m!G{DXfrE&TvG_Sex~OSxoeOO+gW!0WAgp55S$y&kLAr<xz at A1h
z8r=d>$rU0o#1kStRPQ3zTWE+NeJr%|YuOf|TtQOAWei~lmsVCy(<#ajG0$8Yk(p_!
zpeh8-zxzxyArwbYDbQd at 5fDEKzQY$wMYrbK-Y7qfMx&d$BD>5fm$7)rmr|M^_Fb_6
zKqIHx7-Ys6=ZVR!?kc^EWnAxA)Y-ooH>c(#eZPRr;=*<_pGbDQT|{KwhPT(>^<wqv
zW^Fwyiej#Y*Zf?^Zw<A6CY3YEid=P_!GTXP0jmvUg1SSoh8ZZ^xJ_{nAYZ)xTxB_s
zN&hm=#Q3;L2!@$wb+aZFPYH8FX2Jq##*4`;8p(je42lC3g#(+o9KhoS47V_Eq0+*#
zaslQW*;taJ;45f4iFu7zRp#o17J;Kk8e`_TM1+7dLZu6S7S}br+61W(QPjXB<thmd
zmN_!$VJw|NWkRYAVGU^EoJB-PaSK6n`<n%VcOZ>$-OOSDDw*_;<H=w)pVO>DA~+%|
z7!}cKR6AH*5&d))L12H at o~u2G*<G<8kH-v0V^;b-`kgi=deOfhjYc at aTCa_vOr}Fl
ze(K|F-}lwL_MR1z`Ax9~K38RC8PDGws4Pn+lga$R?~1 at oQ<>@YdV~<>fTk?Vxq0T|
zWL(BFmT~DD;HCJ5xcf8Q&Tp0^y;(Qvx;~FDb2+U+m-?A+Rx)i_mUADkMKE)zUNV>S
zc^65PH`6$Y$h=>=8K=u_SKLd^jJso at Mit!qS)r?FG<|hcTVJp>R-{;PcXxL$UaZg}
zp%izgxNC8T0zr#Y+}&M*Qz#bPU4s=~e((F<%34|Xk8l&toik_8o|!#X3HX at HDnqOW
zY?s<$xF$%da5ABxR_d`dk(CJHhomJOurisk_hUk^!CHSSNelT5G0laZgTSo9W4OOy
z1B+0C2`(Ez7v*O3w>&sXIM^IYK$*#6<decJYD=SD2PA#)N~uC5Q#RVZ0Bv}>r{&SX
z0}}njg_#xLcfDe~m|)>e<a_lG);slBM;OPzDSbbS5>bD_P&%i=xjqp at L)y6sR;O+r
zA)KMnKruvyDSN%_7s-0b9cUvBIlNdrK75n(#~qQ>Wo)eBy-J&oHvX7|ERus}6!FKT
zjor7WLZ*imDnFEsTj>bay at NmQ5(nHBtY5!cJ>Ecj(iOXJS07Glx^g^9&2RFh_6N4K
zJI at 15^#8cNTPa}P|DYbTHpFNGrp2>?#Le&erTaRsm+?xjdYwArbfsQ>-3LwA=-Kbs
zr>55EO;)m;ExAjea9JwA at Ow&qvD_ByL3xuw_SnZK`vdtH^5cAfDMdnA2YWh}oCj at _
z#Otcs?ApciN7*Cr%hQX$_nVv;`@$@-Z6D-fwo!dW0y*&vWk@%NaFB-NsTEKKGByqO
zb(k+?nfnyVn)__C-^XSrehsP(SJ8Rk#ToQ{yqilc&>JxK9S+o_-l_&M(QZ;UNT-XH
z!#5&hZ7m{9ZB>)NJ(4nh=ErXfUMm$ou%x!+KrFqbqG`5-h?oape~8ADo8I)mM?-uM
zi?p_NjJLf+LqAP-I@${ovOJG%BH3-Z1)YIix7bZbr2Dq9IMwqJ>cfFVY8vni`?71{
zNG$ck!6IeTUsgyJz33v1<>atGaDZCO&~$rgx8dho4{R-U=>i%@1t48Ss->SxcKH0Z
zLj!vidz`a(damED)AC*wDoGn8h at H>Z1Pea2tmZG- at a3Lf-j+&^NA#0Dbk~T3t-1HR
zd#({X_eV*;4xm|0Wt;F;F^A5bdFUB^EsT!(T&n&#^_}Pr35DL*{B_%gy0#%_ at e*x9
zH!%vV>Y9-BbnW at 4+fu2?;o)KVic-aR@~tVc3v+k(yAYIjDl_%5L(f~bEF1 at DaQtIq
z1t=krpS1scpW`qiSz^w7ohAF1%N891tLoI4$r9MrH}FJ!a&(iP|3XIk?`5J&(BRBh
z$n{7eL8n3<7UI@)ojwJ&V7U{W2=__&wtcd)^1-0lM>3?_j-uyCB~919R0HFElpYrl
z*A{-~7=9=+IAuZ$tec?Q&v|Jv+|dsr%@tQ+VCr?StOxD{04iht0?go6m}=EcliPT3
zHQ&oI^~xmY(K*8%Pg7TgdL5d&D51(4Ah{^YDc_-DGS#^O<_=trOl&e&5BU+<#amKD
zKqK3A;RV<}sK2MTv^HH3w)BwMPJiidrzyFAh`}6e#yP?Lo!A(c<{-|n*1##FBWouu
zQf5skJ41)ck?gp63kX;G=Uwz?phUo;?SlXXL at 5;%gHW{PJh*$LahYF=ePi^J9vBt)
zeACmXsL=&N83_B#l;FCZkA0nM^d>>MoITfbz~;3YcrW00=&EsbSQ;39 at z^U`^SIyQ
z`b^cGvhmpd7G>mRmT-oLebs05CIET6V){Mq4tcrn8G?2nO$h({OLa5x_9Aq+4uvbF
zd=p<?8-Tub<!$!;`RsSAyD?PbcX$(<^8Hd<3e5F-+A<e&l?*?bq9Hk!@Oqel`=QlX
z=tFFhXV3F`=dpH8dpHVUqLrj at YmDD_Q9Bs4{*qC0AX?0yKK7r3tqY8 at a-|Y1ep^2u
z71AnW{TC2usHtzywR+)V3uyq}I+{z*AGuk#tR6INo<Z*fU4PpMb<D!60n;igE5Qev
zh!2ioVT$8~AK|}HM~4yO>fj*!WsyVpRIpGaDx)Xsj*=c~eBgXx)n at KsrcW&@|1AlZ
z{0F`=S_mV3qa_ at p)eURg(8mxuE%W%;O4 at n^A1oJCc`CiW0;{>6W*3JYm&lWk$XEeP
zQ@}>y%zxjBaiR&<5Uf8d<H)J}`rt-Z7 at _}xI6r^bHZk!hsvIBOHGYyQLrcW+Z_wN_
z97lU3p<+3DAK93}=#E(Eff8zYbnMjf7k|O+Z at Uc}!_EEYNd}ZdA0~AFQ4)FY}QA
zR}_FBqhJl~E&0WxqPHR4TiiyJHLyiY7kY+C`TCbBqx;ak^Lof=xbWm+M;2D=xdv at t
zCCPdG9Pm$qYL6^%U+AI2C?In7H`gV|!Rm|vN)ve0bCAB_AvBT at 7?1rDk*p3VNl}x$
z4(yIdpnBDTJYV$0 at de)2Jk-2p8Es2--j;g(vd2;6c- at 9}hdO!5j8SzxQ(b<&cm{Ai
zmQcLzJqtc2z5Nq<yyrTq^|n>&xC(3=oW4(M>HOi at b@J`yA>r+TkCKls;PoId_rFP&
zutNApz0-S8+aLP9beFxl)>0!FifPD~uAX7{p<&OZ<(vqCfxcpf6y1+soCG`fDecQC
zgtWo{dO+Y<(b~jrkin_>`N!ekZE0jKpYd^gx+r0-ypob?1p#e&cOUo4vhLcMqsf|A
zmTa32?|g1-!9T&p=>Gd%O49Jzs5)CZ1)^D2&G3}2^0Xok8D+V_ag>8|I)c8bKi6yt
zS(70NdYD%%xbF(WTSI~g at z_I35Ynah*O0OeFu&`5NLpP16KIsq@><|cc at g`e7f|QR
zM$0zd(XQnMwf;DKe<}R8&u@~3`so9E0KE8CUBWXkr1^5$ux5|=3e6HhCkYkkMNJBl
zP8AVR3VwJ`*kVPVJ&z<3`zTW8Ia3?WhwROw at 09#v6NalH3r1<%#^qD`K7GA_*&-`$
zQlgjr;Y4r&@%PGTxmD~Z2{=cuN|(>Zv5y(2E8edLtvcBt6;J}^Rp1HOMe_bP)5Ca6
z01AVI;i~}lHALzaQPA+8E=cm9rbm2NxKQUdU|=h8L8L!8hY2(&mx)p5({HV1MVS<|
zAm(@eWzy(1S9hN5qIV1Bq27#uD$ob4g2ikHg^VD2R`IQfD0`n8MwcSro(G~!Jv2)l
zw7gv<Tz{>i>%0<sL*BS+Vq4C-!!0alg}m$w-Kg~3s&w8}Iqe<J7Q$tVdnZGC-eBU6
ze`+kbi48m|AiUFlukr&Vj+G|W8GH?1(Mw;fGR at 1`C-!#rVI(D7qQT^bP$~Z8q<`UB
zAPv&u;^O|&-!J6V`}F^8Upb5Ubxk`p%du%c^laoA>BhRKA9hjBmVG9a=V3zIK-ElR
zfcXyyymPUu&Bi%q#Ecg6Vp4kuEe(t15c`>VL3;uY8ohh;r%(wjtxcd01{%B&lQRNB
zYg5uEy5mo5Njx9X(U4dA<{1+Sz!_Bb=GAelSor?$HMQOuR&I&X76l<WR{-qHuBHKq
zjnu_E!V##98M<Zny^4`VYpg`*^yGuf{oi;&8-AACN3K!Uv-XQDShQ#?SUdWOrt&kA
zX{^5n{Skk<t4?hTGAKno544qAR5UD!rL;*cBjP8Kw5Z4wPGZOq(9;f47{9}9&R1=H
zx29`pP<-mNV-bv3w-9VvpKfaDYf2oD`zws(>*^|o5Y_%o;Hx*~+l$nuXK3<vMpf;=
z=fJbC!ks>mKF|0GlHMU5MFoG(f3Ys0+PKB{ZO-^{;Gntrvfb)m?&6JzbnEbuW}D%f
zbm>}3i`y;p at vV`^2<)^DlR;k1IxYG4k2Jax@}5C&X{#GIF at 6K^W|^GdoXz-2uQo%m
zubBd`nL6*AYTj+`P`wGaYy^mf_HB|VAI(`=k`To(P6G#NbdfAcFXyrm1XFsprrB4)
zFh<Z0Ju)-ymnKms<WGc7g}dRkca;b=5lj(cbE(nUVA^`+f)mNSdL;i-g9lg04q5)n
z(vjOf0mzbaUFpoi`?K4e+mAUWy%RzDoN&Eu+eox(yb!{o6;yn=yxrY3%vl7j-oJA0
z?@ZNV!&4b#@S_w=qswJ%r+3qYaCpEu_IV)hbG;lkT4pVYxCsiq46O$w<wR4=xexTZ
zb|IdT&F at svzN0RY#=zGFO$a{N)KW73S{XBzfn{ZQei~@com%XS at s9QMZT+4aPRG3x
z9)E91D5C?Q*m4OQivBg?yxv>%qm;!uAvVT?nmpu*AJ=~PPab>*>pm2Bh=V4;xWw86
z3yK?sWkIF3X%lISrc-E1&!Sn9QBzlHZJBW1C(n%+QvdI0qttI_V^3(~N}_TlwW=ZE
zszM5i1%bZhY%*;;oW1<m at I!e!)(yyVdWjZeuAo^*=}Ggw5E<Vek?hawS_4YdeqfXS
zpeOMi+vy=Q{d&sCm&-G7<m4#t0Z+0N`x at GF%bbJP#U8v)PI;@J!8Tti1@@KnOG7dA
zB1363-|MB(5#=!czKnuK+Yg%o?mg`bk^LC8>eQ2S<mS^SVFJ~I(UEG}ma|6t(Z!&w
z`40I)F!E*@tGp(=q94gb>u_D`UoIafg9-B*pf&0F$d8ra>VuNTR+ezUzQebrolH_(
zUpn`mEETt|<lFUMHNc%3flF7<@%p0qBQRTh%*|0a0<Skp7`OZf6q>#0n0?kCK8!0J
zlrmpA!uZPEEs at h3j>8=b3N}9{-_O?PQV<TG($Fo>Xe}tY&`G7?xKy7K^YM*?`f0GV
zLUL%8gxJcw<tzxIJDh#-m*6cc!uW at p^3>?<=&WHvcAa4h<FxQvfL&rvCKr?|?GXD=
z6=ddIDRj<X$#LvWF<- at WtNI;UbCA_g;qxVKLX^F{-oK!7kC`GNtqHmOMlHx753UUz
z!iff#OJ(-OzW;!dFYOnd1YiN2(MXP0dHgWNb?(C6!!P16=m4CMedlo6Z?fII%$G!Q
z^rdimo7e!)Hh<C$4jnl^SnWA at _TDJ$A5TiZq?5W!cvy%2+wi+h$Sd$%O}|d7F+AAY
z_$TYP(enyN_0lD^`O^qGDgLnEVgjw%p4%7LxR-s|t%KfNNM4l|y-K|Nm3kti6koAo
z>Wr-MHJhAmo}Z_Lc0RCqr{J&oLgCL at rAA7n?u8+eqtMq|v4 at z7sIkEs>pWZ>!{?Qy
zf^t>HlpCZXkAyzMFCA$vCwro5Vz&iqLj=Jf7#S!<@%8l4=nJ!ca~2G=rzawCWOEvv
z{i{C=fvlZQ`ulJc%pc9bwk-rHru0y^f$=o0raRL`U;OB+eO!)u=@Pv%tZU9Nj;F!9
zW5F~epozoFw-3=q?px;PS^$E!_L<nF9i(I9V&1lC|9O0S+VL_#;KrEC-!f6|I_xi@
zI-Ex2g7C)~EX&o_;0ohpX4x2g3iB{;PlatRz*I1P2D;2g<HWCj29=uQKJJf#IpHw*
z(9EZ6I9U1Vqc9vxBHzX0qKSF=;QEDpMDdH%3<)g`q5kTn6^4M#P%c}G5c9dnZH+*K
z<&EQ{HAkUQn%yFhoWXZ8V?R~Kwowm70yTTgkdLoAI+a5ls~#m5BZ&l#f4H@>Ky=Wa
zmrdkumO2vKio>yCDUp(pTtlD$zErL;fp2m{CaIU;iZp4&B`e6|dj%yy%y&!Qrf!3A
zpYDf;p;%tNUq?6E8+QXpxG7iWk{8%L+i@?OY(GR5+7%7QTmJR3F-He=XzCKw-N9|Z
z^f$1a(4&i$t}phBb2C)!z_6O%lQ&nx$FvZ8KK$RunfJ#Memg=va4ng{IiXNL1}Fbu
zQ{;{7d!o<yCa*7JMeW-<e`Bgz(&rVLZ$aL#ut at sg%BaSiGFKO5qf`(_+)JBaxop`C
zW0)ZOE$KBDmN&kQ>?*MOXM-$%se&y&e(I9)a;q<9jzyTI%W!6~H at 4qvmgt6+w6&kF
zbJbLUz_gnSE1bbK>#*mc_n6!@tpZV_0YRAxneD4*Qyac at xD7<dj?bdQmd0k{q?`_N
zC0 at s7^=QArW1=`hvQ at JE!8C+sI)o{NgRZTNm+ucvVx^br#|m at CegZJehc#?otm{?i
zi$E)SpMT3-nzvb~F4YzpuS&xqTkD}v$&iM6N_Q9wq?MFGdANA8K7|EoNJV)ETSWrR
z{;w7woN(VN(T5^EwAI0UGZnXwA3f}6d<hPr7%C!IeWw7`K}lB2-s<Kf)}~Du(g?1X
zTcc8|uJN}Sv?)PSnSN2r&)M&<;1>J*V{4;#=wqx8x9^ZpzOb>ATBEzdmoPI}%N3f>
zFbFN`zp5JVEX<>I*eS6r#_l}6K`2t(u4F6QGqrT5k?`kj^!+pm- at GxWd~@B|)3QMp
z(wrr*o#$Qcs%>kjhAusCwBBh9OY3IBo&@{O6GH)JkhS_!)_?UkBx)))h^eGgBc^OK
z1>*~G?MLi}MySC61Q-N*6{$uJ<2c at IS^ckMom~2ivXHFC;`pVl(JQB16za7cW2 at x~
zw`ki0)3<Sz?tDH_pe*DHIKqkMq?dII8Idelo|$3Cr3Zs4I?B|8Sr|F^-85O0B&9!m
zz%W3ZLQ0}6=c&l$vD->USmU*l|IU`hf2NCNh{R5kY=56&S{-=~&>MhtNI$Ti at 0`NZ
zNsND&OBP&sS0JVo>Gd7PKaslHWv4}|!cw>a(Z8UUARCfjG}5T}s6bxh5d5J^)A?}%
z5)S8!!hA-dfjtl5n>E3bd?boJ9lqYClt(UjQ&HKO!pQ8&W1D2>BdywZ_3DYzjmq7I
zRH2j~V(8k6r|@hk3~W;oQs6<KT+P<)CaTlW6GrYFHDPsccxvv3a{D<1x)_#U+^ZQc
zhrXBPTK#JKZ*_;4iOD|A!zB)3n)2iub_QmJbt;c%u`28+&Nb3%Yr7lv`xY`C5`A1G
z8Yv?w9pYK}_xxkH42YPuWIb$;BPUo>_mC?zVW5u`RQ|DJJ@>5#J?`^OOU#a2K99aV
ziFJ{nCt_EYsfKbJj0yl8rBIv)ABLG?w$SvSLT<uh=mZhT>@6QR#cj)YZZt`fRFjtV
zERD_Eer?91z-X!ct7da+^R!wNFzetu0vYzixi)*+-x8?~sL&*>IOnvC6<F5sDe at NJ
z8S9$37$jZ)Am2-<5lY!xfho6SMeu9Vuj~j&fQ}~@{>z{JCxHA47t_=1s3EeXlDEV`
z9Fu142T}YGyo?xq0+N&2;*dRhW3N3P+KDk8fWa$nzTf at hHI^w3HV%}~aW%3Obey?g
zC%~{w+?d@|v)&3_yJ;KP``}<c5uaxP=gO8*!ggA|0M1lyZr##gOljK&pDVZix5E8(
z>Dizdhxe0FJ|B<7jpu?=hSauAdoBVd<t^&h#~uv><JY@(pLx{PuCuj7xwZ^nE`D^k
z3|%-uy*PBZ2=Q+JiTbazO at SNYG!YF+jq6dr6FsI7WvUR779wK^?bL5jTh<)RdDm#7
zQodh6<Q at dk4v}sHAIDJ3NXy|{1nAGeou8UNxq#oLFY86^k4J;;&$V${R2!$aO+Z51
z(jS9 at EY)S3Q%@}$rnnXCW2ae3Rz&%IC50(2;mdOjczEl9OrL*6 at JV;ZoFJinlZ$Sv
ztZ#M<<?omM at oXvBa=I2ilmd$7S{{CflZ``zq>4?)%UI0x2?zHbE211eCc~7n5 at 4J&
z0}tu)y>_rOKy5YBqqn4$5UJ+Z;kH0)EP%?qL6ymOBMd8;=6Bi)2}AH=r0%9ftt2o$
z&dR~6{n*>(2g;{u=!*?h-#h<GFMj^!Cb1bu#1;#^h8WCW>ZoQE02`OX3j%8hrlb16
zfY{5fZI4hm<8K311tN`!tPxM9;trvd_0r4du1CWP9{m?`On}W|!_ZaxUt*5#VaJ1G
z`9#kKr|!uYAW~q*!TfgA^3eX=(C|?SMWNnKeoQGmW60r0o!5`Du%<d at rCC5l!$A}!
zoEX|5hBJ2v^B87~fK0t;M%(mYI)y_}{2n2P2C|Z4;hgxCvTiSKChvuU9M7`C3tTRK
z3kwqB2`%qCs!-;A0>==Q4}L+Tq$P;&on)frI8Y0`%IoMi8Oo_MmF(%<v9T3<r!3WD
zU=p3^QIUT|z`D*<$y&i_beE(Jm}}U(h(s>@?-hPz6l6y3hiwAdBavXa{d6F`iD<Y^
z at Js|hwYR)=unkI_0GcxgHyO<rfKTKtuMl(2#Ic=k<Kig+s{Sw^_73NQWixrj!9{ji
zd9-7Tm{eJpDfhhnrTe#OApvcMVc~SLZ~x^3c0!np+-3}wz*!qaLecvh=>^@c74YDp
z*EMv8g9)B(aqrgym_cSmv<wmhsUMI^r?kc?FTd<KmQBJby0G7f{8eB#%~j+6JpRh!
z*wE~ds(OZ^IfgrwX1vI0DYqsQT0pAAlWfO(lIX#F3(&bwd}3jD`?MH at tBv9~LR`QL
z?~t_ZH8q5jwZAA313(_d at B=Jro)3Ew&$1-zD=9U+A0hrjfiyEys{W1si?I<HlNa7n
zw4vz8YzWYD75lc+nlqp$%i_Ws?Myr_P#F*l$Y?tMIrv1r;=@B);w6eEPo^a|5oSl#
z;_AhEvl>O0`w26WtR(y)LoSP2Hjz{4z0JP<mpms0fGeLfSGvntA#6+&NEOy?ue(t0
z53BN*eaVp$J}K at 2`s}6G#U6<L0>1ofTbZb~(hBIpQq1M(Yn>go7D;yuV#d>Iyt;)o
zl0mLK3`TMepxIbZNO~e4d?FJ3KKUSZbTaceuCj8oxr+W+numDWe5~hL)6#RDXICDm
zZt)&m-6eMamvSsw)nYb{fL$M`Q-t6;B?BiD7IE7 at x$ZypI@^+YmkEW(hQo`jo<^a9
zyI5cKZ*N!sQ`7$&fo$Q%qYt?=<{Iq|$^3|3#`qfXQ5vA&MYipaen9~tt*jHixE#jS
z<FoF_#x4T;A*x`wahHTLjRs4)KuZ3KA at F@b{!8840cR$jAv!GAYL1L2M17LfjzmV<
zYwDM)eIpaX)W5Q(%;Wezgs0PP3p}rvg^6r(e*+Y)j<|w{{JFjn2ZmrCw-p*^63_V|
zV_9;88xr_ff`5SD{opfkKy3^{UQ`e+x#FCR at I@9-6^zl4keTUiK)Ik84%4%{R-XZl
zAQ{^u9y}ReFN;G^HhqZ6OdVo91u9igoJ&SrSEf!y;4bElF1;jAIpMGAm7^E$xSAXj
z2)ewACb|=D?SXoP!XmA|5A+Vzm49Apf0^wMeu`-`G9354E5>aS*STGe>6$W=Ny|ME
z;WMT_OMWNF#ib%@9P*MKUbCfktIF6P=Ka<9#040Ag)_XwT^)4;4<cI#$$F9Qf#$+p
zdZhM-ncJY_#U{1LI&K$=a*pMo`5|zQTP>M8T+%R(T0w-Lyi8RCzZ&Wve^Ao;m1bpX
zkGDj{6nQOsEi*G>fn|-0gxAYH{Ntf96p9lr84e)x%0^et>H7=khq=Q at lhMnK$VoR~
z;wO1Jx9LnmY=a*}0-oS$t&H-d`|FH9fDb`xeTA>ZlBG&l3p&|X!&41%XIVTLknciw
z8OHlGAcii3ZGdSv?6Qmj5xC~G#mc^r+0Xk7B2EK+V^$U#b!_>{-zRK%m2z1Pi$Y+5
z%w^FF=)DzX;KBtIl#@f at qkdDHLjr33jqNZllU+VoSrBa)0N1vyDNjK0MTsW1mT`dZ
z-Ib}|Twf- at tfZH{e-$m;$?Tej+sih?nMHCv9F4X%rndV>i;U(!^U%&tu;Na}LNckM
z-dDv;Ra|*G;e#t61sQ{|U9BMUP93LILvo9xI$Y=-+8~c4`V}(oJOek+1Cj>H4kI-<
zi<NA3AS;Nv*;^-)G1v&HITX#5)|ZxZ75gZlv&O`pC<f6qb~OquZPO1gMBcchmX~>6
z4>qRY!kjpj!AE5Npf6nd9Ce$FSn8c{EE;$4NQNL#5I(r?Npf(4dzm=A^d=rLfV*-Y
zimHlfRpM;P^A|bTX?qe$W^JGjfhZP%%W+T&Ll!1L4e at PX=REVsf-N4>j|4^WVllG&
zXaDx~^K6hY0mX)%^wbfR+Qe%uyS<iTH8!G3M`JW=d09a;t0?Cvu`>zeYbVOZSG{B5
zbW<?%@LeAn#?`M=*1l)X)-G=$E;|=c-(Ss2yZx&8D=(A>m&yuEtRY2X6ozlr=s-+6
znj0*;G(?K*)f6kmQ3~XQcT(>{PZOI8y_RVB-Lvy1)2C5~zlKoLxT>)e<`sL1SqrJ5
zQ^lIDqate at TXA>i3Gwz~W`=N3@?#PA@%*rO2Z6c-r1rYGNcIUQ{6t1(G|KS|J$%|U
zNJ5hx)t4r6A|FN$HRX=s$qfQ#JMDI>%=JB|&M<m?aOQ!Oczqt39pFy7fh at W#^fldV
z6<Lxdlk|2gZ6~K|Rp~cHKc9Cb at J$Ja2J~oD{3-Zjn^bb-k_Sp+WS?7<jHcD8G5q$f
zCEgV`j}BvijuKh2Gz*lA36q)DsgPj8%VhiC6)Qi~bF+>nT#$t4jV1d5b3}}sIYZ%Q
z!o4C10yMdT!(R<n;LV(YVQ326K(@Cos-dq56YatWXdj%9KJOwjVGb*pgH2V#l$mZS
z6~z&{g+?=wyoBPQm?6KArxGomYh^HZvf5nbL+W at Q7$H#P1FO-c9CKp|K?AG+{EI9=
z?9MX^_aY|ipq8_HEU0gOXuh|W{9rX~&}-+aJD7*ks$M)s;E?AmdxSWFL5j)T&oE%W
zbL`QIy;VHr$IHAZh66WdrCkbqyf9U@&GX}o=EY?n^OXB#5%ESpcZes?6#tDXF_$B-
z#x)+3Owbu7Y~eC30j;%P=B;Ok9XJGM<9iJwS$u`w_(<?mBDPJWRyppA*~ty#bt11y
ze%K_<eqSsshlydyf;fdx$Cio1LuQy=>Q^b?%m29qN3-g4zj_B8fIG8eS8pbn%n%Xm
zdaa5;C}wD(;@?l|F`OJAoVqoW7Ut?TBY-f%JPYBs?aQObpLDW-a6R6+g)JVK at 6Uwi
zdik}wX8_Yda>R0Ll!?6aUR^hXDgCT>U$w=U at EEJ*&Z3GEiy?d9tMFR;+VhxT5UT2s
zsTN>!S7QqHw~;<1&IGmO!l5&Qtx5r#IRoJ|QzWW016l*c-*~?=H42EUbvhW=W2CF$
zD7eqjqg+7FMtnm{6K>oqC%OAjAuWBkW7$lN at WLAV<brTJidO*`C%MB}0A3a2699Ny
zEo_XpHdGeM at 7x^k@=X=6o3oA#la}5g7D8vFBDEcj2+~i%Zgg{;L0Bgy$1>w+3kya=
zadlReBpohh2`5}s-|QlZ-5wk5*YsOt=uMd&{tLiU-Hm&%bSab2%f)C$7;^Oih3W{H
zUYNuIZ+?*NiY4ZGz6;YNVf#46>JtuoCQLbQxG;4dRv7?(yx|}F;|F?BIxI^=OhO`3
zV23}YN*pdP)W95l2z^G9k%pD{SeEGPewkIlEYrQ+PQoNl2slewyKMT3I{oYbd7EIW
zySdML$kOmjH^1_MT<1bRJ at +X-4mxNAW1>~jH5J;oZ`wkh_I2xdzY9AlTT*T#20jyT
z`cFGKLss;E_l55K4OkDaZ1_p``k>L~{-O_g>saDj^p57*@Iu at OY@7fsy|Fq;HH={f
zzQX5%6 at Cv9rh5--2&W76{8P*BGDS+DiO%%fn}$qxS-lDN1pd>nUpT=G7E=K2&f{-8
zJ6l6SJQGU*#Jmb<v3;$A at u&vaWbxYuA!vx%d`OlUb6CT}#GgkjC^d-sExh=mw`?%b
zSd2s9cEss9V&C~;+EGum6I1Q at Wl>`|E2|zK1BxDLyj=KlMp_v`z_25C*U~XE1hY{C
z$*_4ZY|bEO7GOOUQJk!391jVk={i4`P+X$(B-Ck_!C9G#$h_^woHWB2Q_>$JFW99?
zoNrsLn<#sLER+g7$}^Sn$Zk~Z>is)=k`Fj6)+uDp=|sQDr?Fky%SD>H;w{d`<A_bt
z at BlWA9cb<R<Gx>lM$DuP4gD?a5k%CH1<H;A_5?^|2|00w^!-`hY0D|EXJ^Z#|FS+A
z?*sz$6pFV#MP`He)ne*-L0oj9d~EO)Fc%-M9Kje{wseA&WOm~4*01RFA~`#jeu?hn
z%SM#F*>*R=bLSJsP--|mZAj{Jliody*b*33<0KpbH4u&WOxxFR%I~u0BU_A}gWLhI
z#oJPJrcHK4Cl>R at NXUkxfwUvc>5(Ux3JSKjo{#~e*S(mvX5Z9`z$1SH&sY6Su?xC*
zy8bKO%k!4(zEcgSgA=135Lu5qp;gy&WoMBs)PGH+A$iH5JKo-d3tQ?1wWFj%dUUk@
zF1zj#iFB3+b-!}5&(qrZp);8^mb+Smn3TKlp_?v}eQK`_k<2SrNKP}3-W{+|+l`q&
zR7|tD(5q%<&la&RBW=uXZahGlA)n}uIw0f0KpfhasCFQVbfp#RVs3+{dR{4f0h55@
z3l9<;#3SbQv%Hk-Tj|?!U4`QdHwmZySl1nnoqn+Apot9XTfsPxjm5rhUKlpcp(%_P
zAVDJGTn!b#$%P9+nm}4CX{}5Vvq1LSug(9lfP;)|g*lA5e`;L2xEm^p at -}sFhCxoV
zVmwldWh^!rUTKBa52zfl0zy9Z#_sri1T0=7qjGvF2l4%Wyl at k}ef~#xK6Cq>X>2&s
z?6b+_&QgAo)&QMaHdus@?ks~rJClA)I&U?4l|Z{ux;%DK1v62>jp_|I&&yisDy_o%
zV7e<DGlpF`nUH6#(KTpnoqJsaZAT#6tsfOaQh9bcszGTrR#E{3iH}A|-2ekb#rjJ)
zDwOUW_7pWZx4~~$7=BV>;qM5!;b(8x{q~2ko>z7{x4vEMmCvVbAy+x_AkPs#-=AAp
zzTx|KgmEx&j7`hxjokZEl{7u!PJs@;zqRxXN(GpS*-ftv>hVtAKYKLTp4qDF`C$kq
z^8`3sOL2udQ;zPgDMp`Yn1mqbCI(?#&}G{M<-t=OM4UCC+6^nuOPccmIEO3%tq^KD
zoSi5C%CoJwp(msPV$PhYRgz~LUMYC~AY|am0B at F+Y3!I-w70B6^caF_Z7RFNKGqM<
zO$0x<2f#FHt4(K12J^5959j163pB-VSS2&vp9F6wS&}h!bPnH6{4d-EUaYdql=0CH
zd&a_+J)&y(gwJ2<(TVG1`$Q0;*?>41VrT=u%=sdQ<N;!q5Cu15-hnKir_LN_hM!~n
z9dK4~)k=`+qwP*`1Ci{auQI&5i#=-=w^Zbx&ho>DVbwXgow96_qYHK`v!Vs|_#Ik#
z{T%qRvVtFMhqgWBnTpd)dDkcV*6Z%~d;~R{D-&GilX}vbA_yspQGMJEXAx_Sn3p7$
zSB!*94wO~7-idkk2_kP*WVL5hwZ0{?+#bB8xvn^5OWi;Ab_D7TpF&3GZoIJ*`sf=@
zRd|P|z3|fW+7Pme9v9sG&QBXD_sNXBi94C9xGa~wFfYUfbGFY%?(1F&mUxoyL7-*D
zEFM97(KrsKO0&uG;=%hz-|z#oDKMXoATe0I&MO7wvGeEs043Ek`I;5Yl(0R2^ce1?
zrld7q1U8C=jxsu)dXNncG9G<*LKD3Cw^|8Qg)z1UT5+|=VP{z6rGjctl`!NRI+ at u@
zJxGcY+*b;OEM~y<Gd$ErxMOa at Jru((l+6(Al)g#51qvc?!j8R*&y{1`Tg(eWGS|$B
z>BY-M$TC!9oJ=(R^c`rZSD*-Lh6#*(Pjiz<9+qKMW3U^fe8m?v)XFQ<J0!@jwd}^b
zL0C$71NR^ft#gus)DAIr%-In+#KKq$RrJAlQks$JijbYART46sVa-sa%vlGKVscf9
zx10j!BVX%$`Dw0Ol$`{dyO~S}VbekXNg2;#Wl{9gP at Vu5wAI=0Q1lH(RboOfr}JJ>
z9KF8>Vr9k>YmK1QJbimTu6cuva4p9)N1@#OD)cYRk-Y9Lm#V?@#eT{V?PxB>YvhE}
z80a9h(Q~Bm+5>&Vd3)TEDzcD`_b=OaiPO%mwa1x<zT#0mzf`G~hO%710rMa$LN`o-
zuWy%Bfd}i^g6&yO0mp2o*J<W&Sk3A}t+%^8ysMj)F#+K!>Qz at W*ga#VQnzo{RBtyC
z-p)=38QbAaf>g?z*Ef>GiB=c}$eb6KAQ2SG&Xa9_vJ?^nAGjT>I>Fvd48_ceJalTk
zBr&uSnY6Rv2drVnP!Jah1UkkWI#J?+M4WD-8i}2@{Tnk}<GwF8c=|F_i_ at ytY?Qd~
znUeEtCmGmj6m~-*Ims;}w~be+jJn303zrAHT<?R*)>p=;G at J0|NqM$JKqWdu!NuOI
zJh<d6kj6fdN`WGX>8V1k_dLRZ!kB8dqF&AbgN-I(+EY{~o_;{Llm`6cO8|0;&<E6O
z5#gylStXYgucZ- at gbB;hWEO+8V3qH=IHm?v8-b+tNH at 5Z^d$QR+JUT!B?ZCWBoCA}
znUpR<d=+#kFi1p_!9EfFrYjrwUkGGIR9d<qWH{*yxl<5aKJz=r%iFGKaT at t?B at Iui
zFLrT|mbW%lnDR&><Aj-?x83~Jvu?XUw{}g`z?G;YB*kl;ta|Th$!H3VZ6u at pLePWJ
z1E49D=AD`pZ@)!x;Vo7pX(o~ocyZ%*tRl4)gpG>f{rK6A%oE}v<|*~?+44E`+|cX(
z)GK;1S<Rj}?h at GVCT21rU$eh*QoVQWx;V4Z6j$|}H4-~uRaHD|U2FTN{DlND=8E#9
zPcKG*FkQqxK#Ni~2#tKovoFkxYSTZQ&m{NkQpCAMa44g*xPi&jqf-N|A5NCS&a9t$
z at +<G>0V`z)2j at C+WAC7MRGPqpv7htQI$j3qj$$1or6qof+mhd@$DS8~YUf)BO>Y({
zRw$+|l1l*A$Yv0=l<T}y(DW1W1$T1}Hc}Jej#aHA_97B7ZmrDgnqEk+>5GTb>R;;N
zFsvQASc);Rtaru(qL5f)38VmWsY9 at R5lb)%f-GRSQ-HYkG4YeCv~fF<Ai_KoDsCla
zpF52mE^NfI03CMw at E?OtSZrFttoAwERnIQLi(Iu#qEMkw(=9#GmG^r<$;T9(FPicr
zq;359t4Fx^d}$8dAx1t<qnK1LOx<_OJ*CSpK*4*w_I1jR^PZ>#Nu(}z<MrR^SHmZq
zj4S?Po at Z1C+C<es3uZ@`^Q%2$OCA)|E|f$Z+XXEz<V+(h=NS^bX1!uhIap_9vV!fw
zuo>e-zen=+OS0agdRFSvJ-Z*x>*;B7I)9Q$d7}W+aJVEvLT~*iz&+o!x;q}7oEQCL
zne#R9xldw^-wAvs5b|O-z-Bo4?j+5*a?m7{+IY4=-X79PlDRS5hGQUDraqcr2NynA
zG!0ha!D!FE3qtnpsA6^^$X3T3&O-{7NpHj3jYV0aX%OIcH?Trh%`oCq>RtNI6i)r7
zo+guF6;m6}j(JTugY10vg6&?*lOcJFY&TZYR~=zbC=9p7{6GluG`2G)k`YCd93^Xh
zl$;VmsVbwe5rXG~UzAxH&znese!+Tr{MR)dc)mIf&UWDzMnW{f0FwDhTS~O*Lq0C=
zLPwwFJNi7qYvJa(;^>5Kz3~T~;F6nvaqtaPA)*gBO6`MmbZ#Bm0?IHZhEK<uo7B?W
zJd9s0p)(7_6V9&&lWcO$CRTnvB;nJxtu2VgQs29wCZK>Ff+%_Q3$;g?o;R;cZ?s;D
zH7Qy~zBoOPBk35I=>x8U>95$+`s5H{kF^)1oS#I_i%9gq=o*LZv!1ICYl)L@;VOJ<
z=%Y0U87hCDkY6YB{DX`b^C%Ei+F+j;`gt*$15-i#`g&XQ5%lxr0O*Om+FX+T!e at te
zDNNgJ at QM}i_S1D$SL`4U%EveTlbytjn2d}LLzePsjVgpkPE!eA0cq=3(dDn<MXELL
zY^YfH0M%1jkJ)}(;3Ho^@DjznswMoi at Tur4w^tv6ml(8Tk<`{DZdfVQQOI9?8Z5ry
zQw~Gnp6td|7H)2-{Ay?emy!2CW}=h<AznL}Ov`=}_5o~YJdBVz{QD(!D(R<;SK1`}
z&GIMd6I3CC!Bq`?<@GUVr3BaIi6oV2bISd#tm*nK<AvdD|H&-9HWR=2n`DXs`{Wy5
z6JpaU2GkH!tdOSW<MYSlv|X$5-3lxqfwr4{qPgX^uw*+pR+ytnzp6|-rl73MBn1oc
zrzs4MM8~6l+T~Eu5C-je@#-FRJ^m_;BdmLDWDrij`p%2ZOC(384b$L;J4%0o+zp*3
zAAf_LfGT;}uEb{1BI$}Be(;%9F<=as{!J0)EBI at XX!*1F_y4==ZDpmp`~Z0-yYJ(7
z<@B#qarsq;KLV|^ZTw(HLKd$|KH{p-PyUk+Padbsu;$Qs@#Jp*#oo^^8`gU~I4D<4
z4qFw#@E5W_(fbFQL#00^wB)(s*~eyNqsVpKUQV+<YQTQUjfzbsAwy?@UBUx6)=RNT
zKTf?=78c{4>HqKO+XlBIElS^09 at 02uO?>UFb{OpibNoBV<hp`2|6L!p(U_ at jIVlmr
zLgMHWvj~+Tp+P!Q5)u|$^#N}7j}x$f`ed=n%*W>`68rEA%<sU?|Ns9s!UVK~saG|w
zI_OjzL_sOdz}a=&5i0VQj2N=9JZ>H9+rJ7`cU0$7eY&Ow2a$$}Jx>41ROuAXTH|m0
z7o6or36I*B*gAoy>Hb|rYuwz}{583a&UGN4_^z!fKV4j1Ze9U<I`P at A^vbXq(S!OE
zPj at F#JFSPr%SUdJI}eB9mZJZudGnKEhEV_dV>|iV#7;0vPE)RMc5~sghQ&s=KX_^i
zrl@?drYG3xrGJz3V(6o)A{1(p$7a-0sdw8oUJQrwZ1_ld!%|1r*8SS^s{WX{cQH0S
zz5!&W;)hE<AwSLmw}d|iNNwDVL-#vIYV}92J+bcB(18bj-}B#`Vp(>p{Qmu at c9C4>
ztf^afq`Kw18Qbggss{vMuWFz#^PxX3bAt>=eOV_Cc6aGr$QzuFe**un7Qh#JE;|nN
ze*M!28LDkM@$3e4@!AJYF*zyH&fgsUxbDu$&K}hNIy&2D?)NtnyJR)|%JHu!VSNjB
zNd;kljfr6XOIzsJE$qfJ0B#Wx at 4vkMwVqzE?~7cYzZSE{9(AR7&(4)v8c|V5L^~g`
z{pSPZ-_}afwIuO9G~fQt^@rH~>2fGf_<DyY70!8v(*^l^Px8|SMVL~}TQ0UI7 at CdV
zM}acWHzIaU+<brV-jh9SgNy!r28t09q)^xwj!6a!t#5rKf(j5+lj#(bb6CPHVa%(7
zqT)f3Pf>?-={!q&))*q^xAs(vi8LG}nXOCVgXn1spaK9%-Y7ssoQ2Qf>7S$wAhCo6
zX16e4GVt?Sx}NYc9@=e<SH<^XrEFAS*K;mkZABGbb}tid-LXY4=6stG$RhFe7mSa4
zDgR at OB*R^5VMRV7FN6%Vs##)N<bqDu+fS{yeYGEpj_R-aV|)AT9}Dwka>?}5J_=V}
z7VGttIMpx$$fINEVo>vE?u!fn3~cD6^47^%t^T?zeSVhB=EW?v)R|SoueqyWE`QFj
zewR7PXhKYw>zi5Py2yGVhKc~=m&ql^<$znhJsVttsxU^?u!iVl?&MF_oQPtVVd?4_
zVV0`rE#5Lw?r2BaipEh8{e at Ak<~@>hGX0Q%d~T!PA?L?o;t*<Phz3wIGWgt0biuZX
zwqxZ28YAmr5%kBgC1#qRG|p;FoqS|yjb+)hUj>*|DPumOuR=cZgVSYdGAWKZ8dgXF
z`;dru(m~?Mm}_+Q5n at Qa<zvpJ`hEPR;zZhLt)GVCy?nELyhUF0Hm9ds>NFSydCxvS
zKzBO>_I=xY{j&eo*(V}*TCIC&d0DQRPd+9WJ at km@ji#KsR27Ep=8Qk%=h`jf`Tuon
z`Mq at Vqf-T~-h+EDw|)smz~uI@&%@kLXBrd{?490E1T at Ml`N3{O!Qk6kiRaU0=;B|;
zRnOU0(#&xE%sVX?h~{KLndPVMrU3hwIw(j;Kn+fN5);oU5-cx^CwbE at X-(0cXn|op
zuzN0Xcz#Rq%%UG7f2LVVhW_^E2Imuy{mN5=#EqWR+S|3!M0?PhH|LxRB*9wNWLj1^
za%FdwcUxn{<nGM_DKR{)mx0XZGwpU6c&t5C;bL-Wa?SFAsA&KYJ|zX`IRFv^nQxWd
zwUu0>xlqlOH<CS#s8rs;;+Vglk}DlEB<f(gk-dGLd-{B%>Q>y;4A&mfPf^d5faDq3
zz0 at ij@)!{#CP(?s6V+%BG`Jr%m2CBu`5a&v)fpu at S|1BbeEFujL<~QyXeM5ay7R}2
z5uY>b=2&;pg9w(F3S4)e`ghnT-mlG`+`+cc&_zOHvCrjVOZS~rw$JfzSHp5>u6~t{
zy}?<LbuHcd=E at g2r7#+VFga at 2n$leM`#pBqQ at ZdLFlXKbweNmFyrNfDN)G$)FHCV}
z99vYn47pOf1-Dm(CqxIS4?zg})^03Ge(D;W1T;8XiE+ijY2b at lzho)eHBJ0UoDc95
z`dhYrsdh&K6Z%6YWQ;}ihQJ159L=<XHFLy?=Xq*f!Nf~#-}7tAMwj$J^jbXb5`u;R
zWN!rtsb63#&5(6RPpreACxWDLA99;Mvz@{1t*rc>$y>URmgJgdmYN at yF_%Fc^XO13
zoQ2E4qn`;k5|g0axOPo)b@{aCy$87_!5o)oi8+muSyJ%LK>WRtAM}S84xb6QD-WsY
zq~mcDy`~kf{9{Y6tmUSTznuPj2)U_eY7|E`{)4RN#buYW5%UrQwq}wy*FX^(G>$x<
zS5Mf_Kg9hPThKDc&v9RUo?jDJacOklbg1M|2}|+D#u!BAa(XT&AE+mrV>yM(7w!4h
zTiyPX_e{r(yOb9rp at q`U`}9O&xlIvFbt5lse_A at Z`yg4g27KjuS=>~+jXxwl6SwsS
z0P^FiAy)N9NM6cB8kotuhS$0B3GV?K$whxd`&It=(GnGCjKlZT<D~nS^u-*q)}hhT
zSwKelq6$}G+uZ$dGcJBA`s`1TJa!(wVYI3p*>4ITZ_Xr}s;}dIi&#PXpi|i at 6}R3S
z<5t=G=D$3cD}#<lp~C~t5uLvO#9;<`=hKz=FLVnFK7rKpu#5eKc?WBfjlyjvJ~7C$
zOL7uhLZ~)YER1WV`p}=glO0ii*2zcdH}ZNt<D_EM^Zo$EfGFy{j|6NZdsVqaoEGw)
z&vY)dD at nHuQ<x^mX}~P_QfcwqzAK4mWUNYWb*vaYaSLFL#!FGM#zOlv{x$wm{x*9P
zi^BO2JVV?~7}Yh&R`F;Ak|WGYO-2p|C<<iVdsR?~!<JmgiJnJ at Wh?%$o-WOcd4SQT
zgb(yuJRI`bV2xV;X|d$m!2Ob7 at +Lt@Hs47nsGmw4MaPv{A}fPo1qB%^<*+CO!rlB`
z(e1rsHAaLYg4#}LoGDmHgbE6xHi at -It{QavqH}z2UPUVnGsgJ*G~ZEloKLLKS at ECl
z at Ize|J5jZYnqR~_P<z&lUTfx^zhirAAe`<3<-8~M*$^o)U-!O6C#smMAQ>Q%@CaML
z<^Sxo_rX!R0^bS9w+{6IhCatfr>lhVOB0yUepJtXS4BLYWCMFCca1gjG4kfnE1P^7
znu)})Az8v9tHNMFr<pZP;)*JG|0e$`mvnggYijf;vaWN38uh&y*EIdo&#ns04q_}|
zMCUXtJJhgj?&j9m8V>j6p8>5HZ3OO*x$#EB8a#Q;{OsFYya5jB&joz6RM+YgKq7C;
zGo at qep7;;w*n3b>KHB;cx?KGunCa|rNq7FSCGg`wWQG4<yAXKvUyfQ at N*`u}Rla&D
zw3T*t)Hjqg)X}2Qvei at V`bXByIzaDoITh!cUXH-OJ-h^r7oiIz+4U|9c8SwR7{3nj
zUE<9(qSbJcBa1zd8rTcxkMPxF4(qrvKp>Ebxp~oFJOqCCU&@fEAiw1-+MT(r&$k*d
zOl$x1Mcuqzrvf&q`F(d31jidchwehJU}jILBfe<7VO(qmCr~0wCd69?0ISuF4z&A6
z at 6iCe_xDowywOHD{8<wO^$D!F#j|V3@!b=-Kb>#mx}%hehK)bng^pC-Fh##v&NtQ_
zEdRhN>|4=@Ei7PqkWgFt)RgsFKASKS-eGKzpHA;J_ZrR9w~xvbt%d83MBf*z`S+3H
z##?23(7mM)q=`brZgW%UP?B?I;7#k$X%j?G=)N0zxQ%NQ`*5YXL at cTm=*k~_tW}b#
z at DPMK)?hWaeMMdCg_ApxX6anDX?^w`EQ&JNK6f^RgH<{<kmGXL(aw{ipFG>3e6rG?
z09C at QbJTEodA3!yo?kSm=*(Z_q0GH;v~jfCLrLH~@pK*b`=%M5b(~W-vHE_5yes->
z)(yTiv9KKcbsPzjOMJ(ESmxSBF7NA8py&2chs~TNXO6PeKm{X7Cxet3{b43cMzFF{
zrgWa4dPzOT9`Nmh7U$#4xT=^h>E_9Eba3)p`iWvw;`lH at FMA%r5EGdak^z!Z0gC85
z3YcBBx*vbi`l;`du7YAd*}mQ^p2cjmRW}-nd~PB8B|hlTM+tLuH`n5wE@#cmk^kAJ
zqsC4+On8|mxNc5&oL8G#)`&^DlBS!ALW=9aoHN{aoEMs<%NFa`_M$!|(D<qM)`+D&
zOwrOPn1i2={TVuEi-}D2+ at FBe70|?~{xRPq39X7h`)i6f-xQ(aQ_X3f-jr?4%n#r1
z)$SpOhlk`lzv+BnDOAH6U1ARhVYji!G?FCEe`|{?9}bR`vf@|LC+ywKjZVb9g|zmW
zdzO;izp*k=%P4N${i8oFny_<g%kj8w)SMkiXnHyHtSW4xoo`pwgyaYp?kVL#din$5
z<t#2sWJ)gO(i2nd#@v at n;z>`~%RRK*_hr*DkEui9#B$J5y7ZfIlE-F>S@*Q`G07)*
zYeEC}=6KL>57~cRe!FeCtjh)xJ{P%{V|k!nYzuQ%7sJO~wvcZvSWvZhe%=MH4t at 7-
z8Ergu>S}R2sub_>plqZh$Z7_xX?ldnb0T?;l1?yG)N9D6+pOiQH0=JfU8Bh;Aiw?7
zu7G0fUh*+?66V*d1{x>X6pvvxY#{k<n1Z&Dw!va8zk-kd93Ya^MSY=!!mx+YG}^V_
zwAoS5$AjUSy5~ZCJ_Ahuv5B>u at ZBF6dMLngL+WY0sy|He<kPRaeBwiOyxDvS{D`=x
z4 at 38v8a_SN&kVdAFEB7<=3EDpPtAumHy77K$7NI<R^63hsi4yf-gD+vqcdaMwXJM3
z50B<r2J}fV{#2|7y<4NIBL6N7XxI%OWy+c~>KN~dy5)Ran02iR8^2p at 7cckIE31s$
z(}x`ZSt^LQIoop|jlz^LV*J#@K03|Sn-$u9o{0W}SbuGauPEpA{+l6VNHu0{{FkF=
zrK8aJvXe~3NuzJj@`-7;R7J%*H}4+-jE~s?38dho1?xuuDE`ag0a+RX0f>zXz?Kd<
zdir`sY$MMAWiNG;e?0MIfBz}A23dNAJC&e_6MN=YOC at _#5|s{L4fKNuZ{?m*X>gP3
ziA2$!%tih+2t`eQ>*Q2b<mA`SD!Cs>K}uiLdW_)F+Bt!{pC*znOV%ByU1l123HBKM
z<}ZLf=oF|k3`i at HCr@7A@@l-lNY<2MHXjNnaZ!xUJ{yTK>s#57%mBsxIX~=b+!!iu
zhvkWCmADs5ex(kV+cmVZZVaCDBLK~a7P2eu-JtIs%#+BC4Ig4e`IQ(X7)^a2>t>;%
z<w%$QnPYjDXuDpO!}2Y##zG#EPi;?2)nV7dC at Ma!@`vE-cL`turxYnNed7+z2 at 48G
z<7BF5eyCEW)Cy<`PV2lh=gq{*tTEI8%k+3ohhqeW8AJzYpAC(SR;l1C3qDU27sJp*
z^N2p at gs3abas;bl#RhZjO08hmR-3yAD<H~nv2jdXHxId;U|zt24B%|nnyfreInRa7
zN+f&>Ypma<v)G~IFS82(=3MhEW at QAviTVk*?ie35HDb=(yAz)iFKTK{G#+Z6{e?;1
z4<lrbJb5?0{$Ut^K^E%YQ-ro_`DdOao~fa$7HgWr+9(4QK1Q%W^blHnmxy(G7;dJh
zZCQdnf at U_sfO8$FSt}Y-AR*EvBj375+Ade<=LJmH{n=-;+?zhFeHfXm-f{Hw4YQz0
zE0Ksk_77zj^JfYc{JpP|MEP%vpq%Sq7EB-8CVd+Er^Le7T%FTvZwiW;{*uD*r^^OO
zw)_du_>_8Es;Uz=#oZj7M(OkfZ1L*;kV%h|?^2A5aCrB$cgm+HA5E4Mbf*#?+Q)MG
z&ciun at M%ub-#`Bo+0$q*(j=FsIAb9bu1a)QYrp(VH8p?t at FcpYR9UV36Rgk{6B%D?
zL#H4AFe(x8Gdi;V=Ut>J>&1x4vZTZ41W=9QY60ticzVmAxVm6#7y<zjoZ#*d+}%C6
z26uONcZcBa?(P<x;O<VaAcGIid!Bp0`^}H3si~P=XIuB`?$zDt0h+p)B|8co-D2Y`
z&B_=!33;c3O}I>_Xk at y|s?(Vk0+xd{!ucGZ3hP`(egsiB3e*&t^x#rkqtwdCxa^8a
zOHJSuH4akvtWcnJy6NK)MAm-IYq^|-#JC`ikY7xYreAoD$>NxO-adpu<dLcAuS7z!
zJfJ<BE8#dC1Q&+8+^InE61?G?&9-bMPS(PBcdiA+$)2%bMfO?|m&qg_YMMr5>*(J#
zEYEfJ2ad&!rP^KP6DSjCEUYYg%LKdl($kkUD%=+sX@)0DoZ1Amw(xXOVnB6v1SO9~
zB3Nukze<G(c`&q#dQ{mqtFl^bXfSMKA-h|Q`T&OxQQ{5^sPr7o at 9s$7^u~SJP8J at T
zH)VwYb&EfD?8NRz?VgtyP<&z$%R4?DP%Xakvmy*TjQ8#xJ!96Kja`26aI-VHI)=Ad
z06&b^h1&x-Sf*MBNMDjqsyjvqIybKr0XfG)-~;@pxv2=8WWYo)1|0E_89?xvYVigE
z*aC4uIQT}hKy)w8a0_;#U34N!z`M${Q^%@u=8DiUBZK3zb0TJ&{27v*zhvPtQF>tu
z)5S#+N>i7nq=@C2_0SFt7hOh6D{T>hmr3{XrkM3R4?S&5)_i0sf|yH1$hOZ-qBu!J
z(46%`c$VqG1V}v6x}<mp;s?2ww2{fG;#0{P$kMc&)#%xw2wNR-k-V`m at K-miu6hl!
zmt|<#3JG{+IvWPFb5bVH^OyBWa0?5`Ps)+;dzUo4HMZy3ia4ZGJEOy<Pg;b{pXQ_d
zG>(KN+3yX18*T}^RD{OWTK?V!dW-?4_n?BVSqYi=VR;i005xKh&7{J_%!$U=zCt!N
zN)TAmrWyVd-M`Va{q<SrbTZIQ1TdhHvZju*Mf=tx=aHgoiBhT4&*uP`a{}QhU`y?S
zDfG})e8Qej?@qAj#9tlOi9ZC`w$2a<ItnY3fc;cRE+;ABI<9+3!NOEMDVAnoiJ}3c
zt=ve<qc#7bl{-GiVe1iYn*4XYle|{Pi*|+vRE59BIN`!QTSNf+UEy0tvUM7(VCSL)
zJ{J8#=Z|PYgqot}b<`D{cthCA7UQ2)OXW*e!%qadXrv&?H20MI-V?2kHi5RXiI+Rx
zSzWe!!>7iJ1%js#AXlK0b(#n2dt+suW*Vm#=)cuiKoJ9JB03!Nj#f00dJ$-qwq*aO
zm#x^bdC at Otae77fkO;0Y_=tH<09)+C2Ky4A9)G@^rFaC+4FSGp-YV7HR%eW4UKy$`
zHIJx6_;k=2apkJ_T-7|bgo_e)dy!-Kw9P+f#X^v4Mb5M`;GckNrE%9=WZ?jmHWV(Y
z%0Sx<x6zt=<H~1e#6f~is0yUke>e8Ayv+mv)ZAK9Jcx4|T?7=dd+5S*MGUWt#LojH
z-NqUy`$LE_HyYQ9l4a)3xs+X`FXt!x6*(fYykhU-%ScqL#sb%o3Xhz9PgCMswPIm+
zkUTvJrp!}j&how;aFI6BTmNeLRzzzVQE77CX;$3M8ozFhw4a~;DVT2zV!-1>G-(N(
z%M!0sTFJA9l?#r#38WxUTim{{=cw%r5#serv|Dc3^O{<xwhqlN8d%5vH;q0ZlOwP=
z$I!FZ91ta(1eaM$wNygUDbT)|P at IiJyAqK4M8(JG{n6Pilg5@@gznXJW`=M>fXH=t
zeCR#qneDVJb}NyqzcP{bR6SAQ($iEMj&)E(V095-y|y4B?!G&xH0-plm-c+>UR<Zm
z at MS(6g*_nCo-p#ND*J6wNXA4y?f#^P6t>3|S~-m)RlDk+uRyg}F;EX*RW`ZQ1e48S
z@%IlX6#D3OPwKQ~i`=xV#FMk+3B$YX#S67#THVEG<q6X#{s|K0y at Dgnj&3PfQnq$_
z^Y)2Dj(slRCfL>Hvwp*cNSR1+k!#yFHq9yWRP*aQ<Q8AYOqoeYzAyF*H`OhIayy(>
zH=;EKS>;n?d?uKj%h30g_>q=;5)eP_mol>ghn-Z4`f1X&BU?}5DaO?EC=@0mGwm==
zM(e|>V*wJP$9)_}u;F{>tBpp5-BWh{mD2B3rp*FY&~vxQS_5s~_XXQ>SGAzAC^rN4
zu<r**HG<<cA?%mbZRB~#?k855Z at oyc?k8xRz64*;tTPr&FVXPl4{%+AVJ;A?Hni;C
zi=XOTH$@!683Y%+>wKoj`Uwsb;Ngb});X;7kbv`tuD0=+V0E_BNMN%7s-u&luht4M
zWr#Y{i1TZuXV+?+$gq6rr)YEd|GOSewEg=xe1x7Ox?OH_c5SCFU7Jp4w$3yb^K6HS
z(G10N7K&9%8ZA~B`ap^3BOca5RTs}FnBc^>)fQ{@0--y(|6&r^<O at t396y<j30X$!
zUC(~X^IZ>-{iF5ozOp!;&Z*YvxQT#?Bw$P?|FW>KP_5ChA2ESWQ)z*%X}#9zN{h!~
zQ~p2Uf*^9PHM=$(JUrvW at f7DE=6yB=dHJIpOyt3gFZZy3?q^mJl00h$ciC=m{H)gK
z9~v6MxBo9JVkD0~%RPE?I6-TMAJS^Sqj!CR((M1?2mFZnc=Lz2^N)4SI*o=xBMI at D
z=-mH}O>Ac**xUde>sDKB at u+e=_Os^~okq<1(`DXC4%wa+>)lkdozFKrl1gOK8eM?=
z^b-32c(msB>p;{);Sk+f93wu?tWV9SvV1)lL+x&UN5K%g(eXec*XQO3B^8xsgVAu)
zv@!w1)TtR|4wZ|b#dV>{i9*Uq9S}bGZ_WPqEiR-RY_r*(0GQ?6!7lO5^Vaei8HDoC
zlc!&LjYpA|t2I@`vuG<VAQQrAGTWF0)cCZp<7s-jm<}}lD2u1$0s|R`kBp9<f?w$L
zx;^Aar^(#R?i@(??_~TKY@@5Dbd<#5q11r>zU75j_8=hW6ipG#C~;M=$$aVXFcCc$
zAnuM`eezhs6$g~E62EOY{yQ0yiwEiaqAhbaUwNkZ{|Alcbmni%^`ycj+VJ$slN57%
zZbUvq-5FT%#{)5`Bo`T9`XtHo$&-GbUtrXgw?DLo|HX;^ccQqLV`C&{TSBLy1M*(A
zD+Nqh0TR9^&!Ku%ueyelQN{GPb0%kB%_S%Y{y_>UTa_-9s^Rt(Mq!qgSG_rTj8_*1
z-<IvqO-QDO<$yf7dv{o<JxL&Mo!{_bH-Zzlq!ya7skyni|Fqg}M1Az3pofuE{j4#X
zNTr9RUqKy}fkA82q6aqki<!CkF~W;auO|;PbN~0U?14(Ps>;f|0}cI&-&Q!&o~ju*
z8QU49mdrJ(rRhHh*MW!sbOgj8>7Y^c{vla*Ae>6Yf*bDiT)rf~zG%4G9C^1To<ghw
zC-}d1d-F1kzWp#%-k?*rF22{R!A-xH3mu>9;bDk7!#MR+Q?BFm%*_2jfLOEXJYzbQ
z$?lvf#GhyFI^6*5^JVv~{50RK>~fvHJ~!Javl-yY=c at BxoSqyTlPb`#Zo%DtF}jrf
zzs+#@D<6}5FJ-B~z5e0kWOXz#enMTX8h}3`FW2F8_&X5le4{PCs;>9>v%V+_bhh8~
z>83ZRhwtfcQnuT=<;;M+S51#z{C|Bgt7<!==H})+ceb2+em;2v_bw(r-uXDkz0u?k
znuLS|O{gP&B6BHMn}0ESYADd+M^_SO^g4*46c1*y%`^Ax`?3*v*p at p<-%8e*1!p~n
znA+QM{|`w@*JAk(JpmPgRjwUg%o2LMA}?5AC11G^7?)flzX5#;e=NA at 34J)Z{T+%t
z1HXtL7jnf#9;6e)Ayw|gQ#3B$0No6o*G$t84+n2QLzfKIY+THr-D~uCv4c0Ak<0S@
zp1Tw5K>PqjTRa*QLw*Q;ZhI43<vbh+peB+7Q($FhA3iy;P+N1z-WTSccPj3Wt*2WR
zMnM^MEbsuLqtI6dc=OnUcXtT)2{6X at xEXm}vl$thg<d)0WT}h%?pdTi&@yW<0Y}E%
zyl-GXXag7%P3yLLr_55iZN<D;iL4${vMDx^ykJEEo1nswtJAt?Gf=W>sdV9DUk5-|
z=6{Bur at gzoo6MrwChA8FY6_I<l&Y4PIIsu60#iTJ=q6N>m$Cod<Hl+s+FS(*>a(Zq
z9zsdzTjkdmK7lu7Y^P(OHK0v!jREp=#)8GMhX<ojAT4gJL_ac4vU=SL{PAVU`67W8
zvNTf-;3O+CWgO~F at h-NMu3IVkFF)Y>g`2nD8%^K<5Uc3zQ+$zp2<2i0I#T)d=_jA4
zJ?uWZm?5>*Ja$h5p==<)*0e?*MVjqA<ftPSk14{M6n{I1CotjJcjMjdwb0m+MQ?k(
z^zlGNp4Jnu-)?m4{OR8G+swIFNc`rNIK$KZ&cXP%G`=(E)4%+$r!RfO_x^W%&U=M$
z>P|vPHa*dGf~)&Wf-hdFpWh?YQ^~)-5cP%D3H<9gvaK^_);yd=z|e^Y5$)!Je1r2g
z?}-&IGELu1?e}+jz+RY|l9?sVZh`~Iy|?_Aevdzp?huM5IIm0H`;ye{H4!Nc!O$jM
z_6MvVce;c-E#Y=X*qW^gRsQc=I^OR*dM9a$hyWPPh>Ek<MEjje{smY9t~eYbBEie1
z;dyp;1kru2BjCb_Yj$z*k7gFR*Ox*ts^Sz(zq|4fc=c?fZpqYvpR}sDlzt?lPph|W
z)FiJsRyWnONN!E at E#_})X=i68NJZjXX^$Zy7zCpj(`|FF=P($eqlH5nsvZnE>j!E!
zrR$Xi-^R`2CXx?oiPFb8ZqI=LhOQ&NQZyM;htWi1j9#5WX345>X0Ki}b3i{zNUC0$
zOw-zcmS_(q^0HCH=uf9TjI{bn!XqJ%D>}{8xeKr*$TJb-cUETOw?(VTf at v5O;3rtH
zqj2L21L=s53iAZMwUK88QwDNH!3_rJ^(lCR$zIPm%ec-E)$7X*nT4e?T&KB#WCzPk
z$Xx32yruO3wh1S3Xl&%^7w#FAE2CfBO(Q7cB#!8YHcS!IcV9lqq;?p+-D|}(2s?tv
z<(Q!kl<HQPgu1ej=_|!ibG!N76U|~ctUM5U^z!@?4aP$2env+QMA#TKzq~<TL5X4@
zX78Hg*;~^a#|HSBX}Ye{YOs5;b}?ZaLrT)eUA=&rFlr7E`yM4yS2{PrTa34neUA{=
zd9QihR-qKGGfeDJWFxq)%Q;|NJ<oj}BhCpZ&JTF~_pA@;J4ycmJcSq_jgd(mpf at na
zIHp1YH=@nS<jB$L-#t$>7Ngn6`<uAQ&kyeHoby3$xEcZ~N2_sD5PZjS0vF4^4-aUM
zX{BoB7r|+hy32VI8_`6AzmM1oT(~Vv1~VY4z6?6-iN?xa(wbNfOrFzi9qAFi3K2ZT
z{~s6N8ob(ar>y5XLi+p`vs%Ko(ZqNCmX(gbHIV4S3l``NpHs`~IFFLS=5-+Y at Veca
zWE$yE?~R*~=Y<5Zn3-wcWp#P{t>tb1`17N&y#JY%;kYtdp&x1*PsbW>=jGVj!$yCg
zatiCZw2G1VF79WUOsbj3aqj2Zg|#1-y=Rcw7uSb)0z=?^$LXFMD|t<R=}wT6-P at ln
zKK><Bm&5Nmo>NOUnz$^i8^ydmDP4Xpcnas1B5VWeNizrCDx>Wexl|3p<7on~!o4^Q
z`{QSI$JvN7QC-q_Lr0U4xqeqa?fgApD=h0zUnkoC?XyO78(Zx#Ty{Q%(+OCTc at z2t
zP?e$m%yl7L(RKcEpd{3^RtVI7I{<G^^T%Hd3<Es`POUwr*6^ejl6wSu!ihF}qv07e
z2Yoqr#^c<^Mx6DB at 6~f9>K01ao1#ZSy|LbeTjDz*bXpyev~?Yc9$viQ_rG==Jx5v`
zb@(MapoX_xB8QF3l-EsH^My<xOO)#J=%FhwKSRWL4wu3A!kXLhN9 at r#o65%JVQLql
zX{o)2>-dw7?-B)_H6JgmIRaB-+}ZY%eFjf`ytjZmyn?w_z36i9zSjF&)r~yemfk>S
zq<{jS7t~Idd!~Ai9e2BVuR(WF at 3r){TOrvG<@Fo^YjvL7_G2=>hgF2^=1*gK=)t-G
zt%ksVIwtuQ`#%;|)$cVvpURapI)FXF at BJ`&>h_?MSL542uo23klsNMM)30nzfA8fx
zJ=quRtMGo3STpEofaDG>Np;#}e2fGj?~rfHtUv7$95CSlj8t)ccrDj>e0ct5$SY>L
zOCdt%n(Rbvo?efP<)_fKR=kwEzg_1SR41T$Fwn$dFi)rr>WP(flTGS~fl}BWR_}W>
zz1-G5PNqLwb6!b%dW|L853A!Jdi-PFFnPX5Byi)IoBr>pVxhv;=eQ~F??{$=)8%<I
z_eV4Px##(JGyYwY#)a22L7!0FA}Z&9Bg32E*!b%NBEi^}u;!LDUOyM!q#lGtubP%c
zs?-L{1sIW$j=R{E+c4`|qp3okwQcREM_7TWw~NDU- at OiK1^;;D*Lz7%gOT0&x7VvA
zqJyptk?D at RuMAwq{C}qNfX5%Tq^cRIPoJps{<hM)M<cJp9A{{!dp0?Vps at YSE%1IH
zuF?7A(^?(f{<PpfYVLnU?0ftp38{<l9g^r{a%$+fJ2%h!fYx%${hR+&sP{?fmx~PD
z&6~rSs|=!ZldUx@=W*%BXT*;jMn0c_-$MRwjPcuVu6FI$3_o?<2-I`hqO|+2NCZ4V
zbR+Jb=dk*RM15VcEyvwK6AS{;*Ovlrt*kop`*U3&!xa~Q6w5yra_`A`n{Vh_<c6Rm
z_nRli_jHdzZXLJN&}^oo)fO-W>lCFo(G#Wr$0;bWmMh13nlFJs at R^S2X at 821l~qSi
zM`9i{cSdExkcKx4f|+Mi5S^KvoXy)(U}dG#W#%|`{;Z!w`0{XJ4*qNRAZK^b5Asj5
z^<&4%?L$+2z6pI~r4v$ot9W!_^QnAvuo+8)_yhFANF<k)l|>h>{>P7atX}ie7@%$f
z?ahUUMV=G)S42$DESgx9y_T%l*LvS934PBU0r)IYwM1vLov?l2fS>Xi$ggtqz0^PL
zzD7RPy at fr0LnbQ7qm(?qBCzRM%1djz1j at A}mhdJbjf<N}^wO1>?vDXcezDI;Jzsuz
z#P~ULg8i>4dt2S%`|i8?hQhQ4YI8iLwxzu#prWVSBiujcH!NJVtF73cy6^~(us#;-
zoz^;)9_;j|bIa^^TM6WT+DEM34*71rFQEFJeLUxJJ1gmR-dC;waWlg*=2=j~yZO#&
zU9S}xYtsu()>=PR-wV^$#EKCUw)NP2vRRXYpd9R>nrl#b|9nYwLq7tZ{MzK7(wV>S
zIh)TJbxa+v?5{*1?{D|=;VKGxu^(A|hmvh}$2C}!S0`~uW!>O=9hVVor3=1VA6wa`
zwf$3y1MD+y$6Lzfu8^N)6L&7~V>1-o$3MJzI}Tn14^sp``fjFaIp?kP#>8fi4tBa@
zs~EYySR)iWjJw+Jt-~u6?3`VP0gP+^msR!lm!&Mtn>(Q2jL>+O-*Fn3y?BniJ?lZu
z4}teJqT6*rAN~UNcE2Hvz8e9(E at qRDMbg^dTTB6PO}NJ>j`nJgH}V0N&P3JpmaI;l
z^R;Om<>~$Ed+{U`lk>c72OYGFnfrpaFORy82PG{fZj6o(j%H%LHMnT=Ifba<U9E3m
zqmDPadckliF+yR>171PTRe&lk%P3B%M~`Uz#joAT{XhC$?$&V5PDkw8;mXy6Gj2P{
z#Y;@XkYQ5R`x(*gpjnKJgy&Y>2S*x%TwYVyw;A&v!hn4OC{V)eRSPyG9Hlzyl{5fA
zXJp_2Kq{NTo-w?7Qbf89ppA7=fgQka$X9RLpreW{mAk}b;`(aM)(BcgzAReCuJn|N
zwEkZ#-Gh#`nER at 9e_yuj(w6(Sg?*3N4xm@<cjCABL-l*^>hY_r{8eA{c?e|C4$C_;
zBKHBuUg)P(J2QB7nlR!MhfyrSaT6C3|HsjfR5?V+I`t?Ah}B<9GRrK4B8(Fe`(IM4
zwMR1>cq~(eQCR2U(yb`4KOvp(#PUAr$m25)*O!?qgL5Ytj)U$GOf033=%OXgptqo0
z8iH^4JzoZ(Hb8$z!RM3_P`I%z*&qMlVc>5(j{n4jZxa%(9+un6w!h)&m*nwegNt3$
zb2jCh?|f>z?@W4MpOCNmc{!Z+!(y}DmOE at T*b8H{kValuwL6|9k>_1=sqqhz;Ta0&
zw)>I#Lf|>8Awdq)O(w&Ubk<wbCY;8fch8~AYO;UxhP&rJHy+YOfp2F`#<^L$EW+4Z
zcb-HaLSc^k?^P0Q!40&&WbF8s?U at T{u<dMvs4UF51Jh87`Xf(Ry1#=t-&p-`7jXfT
zb0&3R`frTNvO&6J0N>C(43%9+0Aia at T>MUbmg||qZnBE};UYcNffi61Ht^RW>&DZ2
zn_EIDPAzBX+4<gS1`_SMg2U~_2D76Oz1|;F`}V{V4)0RbV90LaGzc?IiKeB}rOg>*
zPX81lklsMuE2H43Q(gjslHW3}gv82KtKcJRt>x6sEWQ5T1ko#e;m)h*w%4|DW3zJl
ze<>@s_Q^@)Boi$E?!7)QVoE*XOyUA49*FF__;_<8F5y$c0|~v3ld^TAk{_p(y>Ch0
z(J-9b-Z3rbd3KIF2MV`KM4KaB+dhcux^B#YmFYM~#Q1U$cD>dfpzFY4sDu_E%bA~!
zlbH<K;FfiG+gldJ;8V2Bym?Mh1z<Sj9&#hByJ}m<w^tP`eWE0o`pXozDfaQQ3;)R&
z*M`p*{$Q)D;~;MIgcn?mJKlXxBWS=H0reO5Nv`5Ld4}1Jyaq~FI<YjAHL0u+mWV*M
z=6<GK=85uVMu#rODu%s~?>4Y(LGF44bE=^m{1o`i^xFW=Sj8h+3A^!fpYwJ-T7mQq
zk-_)n<?-JCmV;rtG4l^>?_juq4^-R5L&!3ETPufw4LN1K*)NF+2aew`m>>epbt;+L
zMCdeAY~#G|Kk%9vk_X>46L<flh at orP7{FCetzc>Fw_x2&yX#G%CEX68Z;_xAIWZ>2
zV(AXP_+9k8PGTG at +S?vF=e?rncY`35EZ}<qNteh5<X(B0%gA#@yT7g1-8c(6b5~i>
z_r8=UI2<4o2K9Fi&Z23^po<R`O?14*t~igZQ^dq0d0g`6*abB`MW@>2SI>E?Q$LzD
z$#ppgQ1#ww_PW^*WceMYaobx8{d;W+>yTz!^c3|q`XZBBv)4SaGlo%>$>*>kdMA4o
zWDjIv1IcO5X2q&f=Mv)ZD;WUsluZua{OS<eCEV0<p3M-H`=j at v285z9k)h3jDuLSL
zHxOki!+pCbSFPWa$mZ<9r|k|pW)yt?Z1+090x!!>m*qq*FXDM8;n_3I-PuEk?0*-{
zcgO4B|G*2Pig2#BVE)W;y}jW4J>KWwh41myzhKK|UsD6eR(!OL3<@2CPg2CW`QrWU
zMYGZ5#~g%^*$hB45y?l^YCFZ(#B4lO>l<4t^UvseU4 at Mt&_8rFuPyyslt0_zBm%uS
zjd4j`+2A!LF#y`?-%`*W(v&e`u?OJeA6BgQ4C}+Qs~IkCt0E0}8IIndwra3=YiVAw
zOEAj8^CXA)=?Z;I<Toy3*WW8;*4eIW7>kJ^lb(P(p at qxH%?cO9I+9jre7nDt-EGRv
z`JNVk^BV{#h?9)C-dYcb8JLi*=(IIRA at U-t>`^XXu at ib<p~@3zOV(`}nSH37=W#`*
zkTGjc7^ELPz_wkFCt=Nj+$`+;Gb=8?*6uJ(E4L*in7~#k2<EY-uKdX!g at OELTy&Qh
zqIoeprG%bqS104$DaX~B99u?bIQ6^~0xK{w1$fBTtw$q at 2wzGcSXqrvTFuv3+2sVa
zv)UB1ZH<DJmhJdLOK4Z>o0pGokuQilU-3B@<t;gu9p+5Sgfbz+=H_4=@ds9)x}R*1
zvG~Gc+}dQSwt&EX68Bgl;l<DBIWMWY9rM<Xc*(x^AH5Fdd7SSfeaA7wI8$cPTJ)51
zDy8O`F>JVijq1XqtCho0Fty_==$P(;r68xh-#`)4&4rqe#d_mX at 2NN{z1X;~GF(&y
z8N-;$npA3;lEVEds<0eR_4HqK+B0Fc!sQXKdy*+IbW+!4PadPsSvX&#E2n?&CG at u2
z1^c9%iaf6;lzEO93rsM$-W%li{-Ba~-0DqOm{#obfVX4**14qP`RB7JK}IN-a=7#R
z2zU74?d*<!?unpJBG<jiPH+6F{To)0mQF}HYZ~ejDdE$j9CY7{J2u~j|2vZWQ`U~)
ziMI~i4vm*5Y~WBv>oTDuagl at B08_DE-9a`P+$Vs>$GmGr5;oyozG4mS5yWIPSOVHx
zdEvb3SMZIR)AvI at uCD&}IaeSIAmG~YPfrNd{F30GCdeR_{)Vb`VgOf^o;2MNLVMYj
zhbQO&6|d{VLtBWcASdsz)ulHh)g$qnb#0O<s$3EibbHewK|it!d%D3#djMNvDvVP9
z8ggH)b0^yST;gwfRD5W&>cpYmbBxvg!T6rg_x_vw*k1F;uV(IgccLmr57 at fRD>(m`
zoxah1ATOk;TpoPd<zaOWz3sP5^RrdnWNnPV=P<8tsyB9m>oBHCqo at 6PQU+=SGiTDe
zjyDO}|H8Rg<+x$~d at nAKub+139i*Y$bPgF*E)1@<zp{L2vg{u0X#;HWD*qH`tkB{t
z#$9%-?I}T at zsA|_+m>`hfz!P;e5ZAP{k=eIZ2O8Swx0W1vh-Ib+bHdtepe|oS0?7!
zu2pHuXO~CQTl~`>8TWL0_zur&RgY=*e&HoYB9rfu9iRl;y93q+nAV*aMxVDh4m^3i
zQL)**gf7B^5E%y3)BRYT+gj_#jd;J*cml3?xhe at M?H5lgtDv^t1FdCwvCtSP?mQV@
zK1XoPs|$$D+ub!?j_|Nc-<ghkQBfLjIZo95qp_+w<cGi-Zs=fE25UC3mxW?8q_
zsDgz`^eEte)#n at 7<OdpjeYSLX5%dcJ5k+Wp*`T^^7;e0QoBUtd{7z%dQO&;pnb5&W
z#uzLp)O~gym7)BBcN=^yCHbA*J`PqOMR at LGW;<*2ht^N<{*JqURb`b|PVQ;0uc=u&
zjsZ3*j2NUaY7o<|L}BE}Cb>EVXTQ#r(~^SSWlyBzkDFUc%DHw at oh0kc-)C`AK>=SQ
zn3$OGnjU%=A1?a at y`~2%+NwIMs=7L>D)T_cta%xywO(nr*~fh5f=e!YT5;WMNsThw
z;uSGdh+?cPCR(9>d~Xg;EYaq9{)9X4bAykkNi&1 at KGab`qsW8<m$w`THEnwF#4*yH
z2{rmXXhc3UpabK)H?+&QcZFXQ+>i5|{t*OOocT>fzU#d?GT>$_geEDat8=g)!ke!<
z2^0o@<(H2u6cI)dJDST+#6g8taBLVOZGJGk5Iix^i!-lqlC3qvBZBXUzu`-_L~$9=
zn!&z1k~Arm9cB`|4!gf$fer<HhN#zl{4?J;aq;oR?Cn7 at SWO57U)k<#w}Wzv120{9
z8@?xvI-9fG2>SD%&q^M5+G=cUAn`l=I at t)j_q~`!|2>OA?S-4gQ71aDm~Tx}C^Z~)
zuia3)B~o10a2uqnk%q*~!58OaV01CfzuH at i_d^9L-}wHB{zUdfQ4O&a4dT=<yRV1n
z2O?ZDG)HzDj%5#9sEQH<S<_eT7v4RDyy3OEPxC$2^<G;~?RSYa^*N3)F$x1JXeS$P
zs1KKV;SVmbJV^mb6Gkjq;qxs7bsZOO=h`JAmfEqlRqMZqc%qxgkUE#ECGAHTC^}0G
zho84r8>B~1uBh=%>cP(&4i~+#ioVE62ZJ7$*XE9U^lgSoJW&hZP?teHgl+n5c$B0<
zG6uI#T at 4*F!;fQdjq-3+-mDM$y|7j5w%9Z%r?#uzzGR6s`DZXOv%%|4U%J}rB+SP}
z6w}4rSYRcm3_vY)qp at 8-iIowm_4+V$_lS{*c)w6}K&tDxF?)5Y8y>d`6sy?IzVS7#
z;eV|Sa($^Col-v+5sChFxfR#L>$Mk$Y|M8I at e|AKaw~f3O?P&wy%7%EE26-7l!;4I
zsM4Kv`M#CxE^5r$+Ho!p11<`w`XS{+F3jQWYSVC+*k&gz=WN};N+{pm;B0zJBaL}>
zdm%DpfAH2vOzSHiLpNGm_bEqq+Lt|gCs+t^C9x<2(gY3klBBk-zfA?wDlA2ox<TmT
z8Ap)1bfKyXY}wq-FtqBm)f0vzb$?XQxN{zNd}!P{AoZ?05TnJ5_Vx^2TwE3}a#K7a
zEtKNYxO!-==Z)|<zJ2><VQ;UmT#{loL7w!d5-&%pyS)scVCPp_{TP2y76nG;_r~n$
z>0urJp2!Te&**=+*pT at vhc50w0IUCa<NNr?58m%c3Z7N{yxx&%GJ5ZDfx#Gf47-4k
zP~lCp+G9&b=(~>toDCxj7yLAx`foj3Ir{>=pdt;rD0#0n8_X`Z3mR*>S?9xBPiWzQ
z?d@$#@62Tr4;ScfpjYqaJbcMIvq5SPsa~+0LtO_%hc}VfKXs~nQOHi#Sv_}(MT{J#
z-kWbO5- at BFAx|gHV|qRCk-ZqCNn!KM(ZhuvN88(a&24QmgJv0l>%WpnfXq5dN=h;F
zrld0Yl(9f2goe&OeS{rbYwN-OU|9W_N$RLi3v9!`7;&?I_^Th3EU0X)eq`bWQU?%)
z1Q_jg)7lNlQv?x(SoHm)q*e+chHJRI(XLmD+=YcC6&Kc?!R$T?vsDQu97Ktli;J%7
z{bGgw8<~tc0_B8Y)phv3eRsS9D|!Gz7 at Jh~em4rwKK<FBiG7U4ciXSqu8c)3X1f<@
zWvd%iiRu37wCq<@3NOQ8O;=qy=}#15I3401NX9P1+YVej*`*F>$bou9UPfOEH_Lw=
ziT7}ZD8Fw%i6sQR^Q-T>Vp;AV`zapfR))rU*Nvq5-Z7AT+6l%JXL2E+Ar*`C)A1XW
zxoUI<BLyq+`RA9`yY4KlzANh;v$!%k5C7bBnD9In5L9DaXaTW%1b=<>3)q&!+F#NJ
z_nzb+K|${&4-`^%IsU1#8!S1t(iwm=dRzD6*gNF3iJc=uA82#l`s^_^(sMljr}UrS
zYkp9;oZQ}kwcT$4dN&PmNIpTaou{<DRQP5~`Y(mEdAJ;zYjN7!_3%o&gUA7snHL_z
z&$s%j`9oLr^(7nvGlp?Qsn__&PUD|;M%h*ZOF<*>c3Eo^dbOYFKC=8v(PG<KM7K%N
zD(~Ez79wuH;?OU7$Q^96?i1Y9w%tGsS)G1oc28C*&&nY>*$K1UXRqu2>icGW6<X(K
zJ&x*SXP=FO-+y%i&BJ1gf%mz&rR1vet?T-=f|dFR-s5%Gd9}lJu$kJKzPajeyOIkc
z8TbPsGPrEckTTy?x7^+vV-eg9sYJrdPW|otJvV;RHEs7?zZYlR`%>7Xy#AKqwF at NK
z>`p~G!}yZD>5-_B`?Ae86<U!&0$FW|%Qq8jnK^cRJ7&UCsCHXjutOb$)%gm0#gA2(
zz(Dl(Z#ac9LJ at Vq8O%a2USBU!*ww`5y7N}L{Q2OQN02!oDF(Da(C at rbjc|<K;}?=~
z0XU{5r75uaH=?VaQ&1r_4a+Hq#xu8l^l=K2h<G!#dzNK0H0e(8E$LZ4DR-d-F1<{;
z9Sl!u$sPiT=#hlRpD%=WqD80dPIHskqFt_25!R^#4&j6IBc{}Hpz4P-rQp^6c+asX
z#W>H$v=Kf7d_{XQtHHiB4?!jyN_r>z{EJgba_zy3-xoQqoPVBhGm^p;N10-H(<-m5
z*%GgB=2817zFaw&GD at 2NGBch^pXkhoo_ at XWP=CF&VP`!=NN+FP-r0zCee3bq8~W~Z
z_<}qz%LZ*2;!_Y|9)~|zf^|uwEh=(je%v}WM(z(i<LL1CSkV|J%l_h5I&+hE94&5v
zOe8`IagL(++?BuM$m(;L9dp-Hf$m4m#mR(J04f5zt{DCmBouz$JBCyXz27CFR-&fy
zq!sTj5jF6<^cI+z2ft<3su)eq4jEPEFe5+#0;)n)TG=Ndzw#^E#oOZ)*dHZAq&=50
zlC%etBHX*9;!kI7v>+>i>NOnH_tIoLap~{sQfG#Xbj<^rb`FL*6{<6?>qX1)O&G1C
z+Ve at u{VRdVu2C-R&jtM-S1vsJ6f8F$GVjs}IL}$z8*Eci6_(Mq#GIJ}v<*HO?9*6L
zg$6!0_~G$A0n`X{3md^%wQKSAn;$5-f_`5a*LsZC*?o3K;|T%wqM^~?x&ZdER-gRQ
z4bXa{T0#Oss6a!=;|?KFu^<$+kiZ(XI^D?uuQYNpmp<as8*Qv(wzV#BJ|pbw?>3je
z3>x8!qT%@!xNL$#=pm*#a`#-w<eA9t9Z&HsJWSG^8FM5c&s- at +Rs_+ocT8Ofd7M<V
z8{*==16RUk{exR<s~?QS;(5vQ?G1}#-_;y(htGJZrAsWeA{&$@_A02O%7b^65G$F<
zOM2!!BNrlab7J`HelLy7uw60P`8exYsrn^a;Op5^9JG?tR97DJw0?>p-E_G>^tex9
z93C>MEj%#rAPr~Sb|>Pf(Tvn7h at g%VlU^6WWAOoUeFHMx4P+^L$;Qc1|EYLutE=91
zznO{k&=vq$U)zmDxfOCHiI5Hp96q|C5}=szoTXysrfy+&RbiChY*U%FBr!P3X64Z^
z1VUkk`5JW6W=X#^{)*P?G<f+Cs`CFXLIl{=7BkNxI%I at 3`_i4ImQs{Su6W&&s0f6I
zyHhH-H6=FOxR3$18|=v6tHLBU>-R3)JZ<HwzVFRTW%bEguxmM$Y_Z6>xSQoy(#U5M
z3Ki at UXEZkyRuxs}mQ>QT+HXTFJb%gcx#Uun3#}}_3Wg9J6g at e;)SJCD;EO6g<++Qy
zQ_ZRV6f&43)EhA-E9aW0hEd+87bv8(7fvGLUTLZN7uI1KL7`;hY(zD(zr(I&37cif
zMJd^W-Z%_Dt|d2*A^}IbfEc;BvU1F<sgNwGIiG_3$d7tb@<$nv&JUd!G>!b~6*SP>
zjrA%*U9cpZU3>J>?TyDzC5OW3Ug!1QkdLodk?qrwKI>pCeeQdSC9cgzEq5WOz8=jA
zrFXCOES$61zC2vyKc!l`sthYLnrq$cV>LOTbrh}R$4p*OVR<|FJ#RObvlmS-R4b4=
zs=ly_V2j`)eG&r_A`FS|ZdK*+uwS(OeO%^h1h1|py^%eQo7FLRtd-7VW10B*ff2Z`
z&x_3M;R?ci7Vy4?S}G+>2nhuE5?5pW6?=Zd(9LC~M;~e at m73E}qzyiI<WAMs0pmIa
zPB4F;9>_JMm at V#n9KJ;UWC^f%B#i%6s$4;_7S5-<0LMMe_c;jWTq$Qpxn+nVm{JeF
zZ?RhphI#G_1l@!P0J_j98t at rg{_W9`DE(<)>++`Z;^j5S<mtVeg1uTzQix_KI5d$_
zmxNue{ny_?S#;$?R9aws7)4mE-(@Bo)|{H8ooe^H%Z8V25E at -5kJ{j|&;RRF0&{to
zz}vYp#OUqSfS~V}Kl(W#71j}7KU?&<eJ`D|`1Q+x at A5@JXC?H2i~YKBmq9vX*K@~Y
zcabMSMMR{KLo}=mN;CEIL}RMX>d;`H49U0s;WP9MKw?FT8U4v&h*jLx`~DV}*+qB%
znk2DD at g>p=)GzJ7Tzxs%o0Ekaih48r>3uJ^?jRhQKT3xIJ{zz0!kZ9gI(K-FOww=z
zv$Yl!e)gG~3yER1;j{l^E9b7L{|%Ck at 7l1#v at 3DVQiAgL%x~?4>x_L6Wel27TZp?^
zJU{t8px4~r{5|%L6$X?7g;Y?=zv5F2tQ}A}o<n_nx?R{256=nt=@95zmEZe*2&da;
zLz6xEm at vyGcfx-?!n;&B)XabxEk%x2*rZ9BB;24;{j`sUhUUyGyMHPaDOOnUps%B(
zKiLVJt2Lr>CA(1FVd21R(TwhcuAo9LTADz5ew`t4dq|;KHSc8+%6|C$m&o<J>gN0U
z+0|d?QD!EVumz~W$5mbZ;is$>qm9lKsa48GPuO at tXY`^D()WGczQ_rN?chAV2LwIu
z3ygM)V~+HZWT<u5t<O~%-@(2zOS4Z2yi5;`ytAp%5TcUD at wxqDjDjJ9FPx$s9<=BS
z0pN4T@*VF_BY%|c#CX<85wGyE{lPDAo$Dy*ITf85G`T9vlXQZ{VI%#E|B}&1V$M1N
zQ33#fSyzHo(|%Xoxe`gOSv0g30)(Yq>8zCh;{y1lN}51K$Zd^z*Di~eEoWwU_{JDw
zGa(ciS~e?&-{@GN*O7f9{%4GvAiw#m;{FM@!c5}mm647htHO-3He~orRPU90b}n~B
z^8GyL at eS;ceQ>~yPCyj@`j4CMrs`O%jFlP{U3{1yycO@>{RHto+T{<MSvX*9S#)h)
zt{TpwO<p_?E+P(SDg3s#1qy#D?F&k9H>{xX8o}4l_eNM_6#OLk)xerYR!uV8iWH|p
zF&JeX)*pG!)q4*!$`t-%Vq4)d&lGmWRlG*PRV9~pXqs#WXxmUvCj*Bf?VRxISNRUf
zAC;i;2;JohInIanLiz1%3IEIC7 at c9>-2|o0F~ZBAXI7LXN;wN8LAJP$$9=EHuj{m6
zV>Np$7t!!zSO<PAKkVO3vel>hk!rN+5Q-=;Bsw!$OTwz*a$hg at YZL{+`ly#%pF$vI
zM<vsY3U{Q8Vlzgp*dqn>CACRH)>jZOg6(17ZxN|^;@ITL&G at 0BhDisQs=0%O#LP~1
zn{2(cypOctoyf__&31;ag at aQ~+10F$jWAqppOK>oIVW&$;k5Zrfg(c66Pf*r5#BA@
zhus+${QFyfkMQ`T{rl$cF<GS5FSS_Y%2j*Sqc}n!*u?v_?RyA;o>(k=?&suTBb2+|
z0tlj#_Ucp|_9vrJac<DnqT8|r6CRT7T6t}oO*Bf-hw~ST0{4=Ny<o0F1%KG_8DwEb
z9z_VTOe9koqGnFL&xgyjyY^aNRvb}s7pM*raJGBoZ^oTC&qWJve<`UnF^hi3%RLre
zaZPYboj5H0P7ho!c=uUHdmcG`dk)i at TzbDJNI67lTz*oOO9D*NoJuV{tC17J8rvR=
zMX4}^x(^z2xLLo-Wt2m9_rsW2rzuQn81BXwwT+=d<$ucbE0tn(hbRs3MQ{Z~`BnU}
zX?pd>nap4FjW&*)Ui^F6Sy{IS at AI3fP`4V1o~yvZcvHgnP{g0|D}>Z>{U{+BzoPtw
zXUFqIn}BCq%{2MwKAO}>4b@?Q9c0?&LbBPA;K;%donez3R8ioks9+#rh6g@(x}H_?
z;CnO&J{UHAcQgr^YLTG!E1z<Cdz_v1!jZo(Rnoc6ibiF_W4uPPudIw>x8%?(<e7Ss
zXV#}V9<o7gcald~|L9)8LrloJFo at SL+iZEXscfH{K#aG#Bmhxk$HPn>YO&7MD_NOU
z*02|}l#7q3u~1gN$y4}cMl#ak6fKS6Lcq}>4)@BQr$J=z$5 at YeQrh{bMe+S;X0WIs
z7!9nfWI{0Z8<9nUmMT$p(8cPk9lYfuM~h74yU*cum!?emRsM;ukUNW6)VmS~5l30i
zgJwy at YkfZok^5(6f`l-N(8~R1!TO2s{!`;J(Ws}^A?^r45au(v!&g^VY=cuw2sZ1@
zKd^tZWtmeJ6)IBi4n=+=rO1vkP*Y2gFKh6+w}KGj$Qq9PMpcS~XcCZK8u|Y2N1pWK
zq?5snY8Z6-;`fLD33Q^>SzA<BhnyiR(LE|FElpePn*H<o;pBdwY6raMnR}wAK~I0+
z+~6T+)Pn*I3Fs!k6o7He_CuS1ZC0S>QHiFbJ~cDTH2VWBpNTF9Tb#{FMxwL at 3G_X&
z!=T84C-Zs_z1$t<_mJTyGbK4ujYp at sOkkI5sz~{?U-I<#owJcd6lUz|iplSxDKCXh
zD1XPC1;@qBZJJu<gs1jwe=>vB<8OlGF7UL+!Nk9}d%OWQ^jC=Av$H6Kevf;N71ezI
zI@~U_8qzvYMZkA_$W#isL!!w1s!Cr<k~OV_=HOV<|5^SX+F?Wx^~i-Cb+o#iRizj7
z%ncVQ2rz1(jtQ|kYdO)hv?w_1be+3z=VQc-rpAm0_Nx~p)8mvu7FC$2nbsn7yiJT&
z*;xx;61dJPBPB(5esnmlMLX$KcrqzMQ^1E9h|p^$@YvqwTW~UDSzKwgaEs=jW=4;c
zOD{JH_658VgRQpc(ZiNsk635;g5epv>xa^*)nCw{A at N81PZ!F{a9Dn;Hn)|P!4B`M
z{)_jvYd4}eTn77Q3;5#d>gt+?XC($*b}}Fl at Tj&DFoz#-IpCL_=CChevx&j#uIzEe
zX=M2bFuv;}LqP^GWsV7 at pUM`PAKqlf>;v- at DS(){{rB at j3QPk`ZQ7M5S`vaH70ctF
zM@`EU#U&2Sd;ARbZg|Q60L0Q{wP$Vxc&pGO-0PD`S;Ew{qsbu^B5In2ufv7Tf1>jy
zY$BKtLcdk6d47lcl)%fM<`pbao>5`eGgdxj!U8C^1 at w;oeqn&-8hrwzp4y>&;z{V#
zfe!-<Teb!4!rlFSBs#g><fQ5hD;rx#LjyB*m{Q`=$U=sE4o_%*e?Lx9jLGAbOW_)+
z96bB0Bl975Sy>_V$?0kTf`VWyy>{zwSKYr(+<$MMI>m at RisMOXlc%NU+MQ<P<E%GY
z9dCg8AGe;UTN&BeA;6wSlPCE7=tdPsRjxosixg91H%F@}qxviiG0`|Q7V6n%w(LsK
z3mR;_NPM06|75)&c2<SACc8)^@_G%13Bq-`Y}FWXVhdl1J0*{*s5?!zeF`;?f0>y}
z;ndGtQAAuGUS4J{E-u@?_S$G*;>8P=>80Fq5-7fanYOx$4RGqquA^$t0H<5t5q3J_
zlMkV&s3>6m1DX(9#Yc6pKs3B^U+!bmVblY?Q3tlo3`QSRqusVYCrR`fqFDL6M=n(%
z3Vcm at +F6vOx7kcCKSoiXiE3+03rULf-fn*|urz_77YBUUP?3V-O at o3N{(Vuog<VfV
zAZa0RdRqRJO}}*adxj66tlS8K+|K0jZJ{{pmC*#-moJf_ygu!-b|r7a(VNFAcxd41
z)~J3-P%DaU=7HX1JGd7EiAxJ?X0xPo>S>vyswS?kjs=KhfxNtj%c7zpYV at xI`McIK
zVKJZ=kG)W=kiAh*jx43&Ml1E-x}U-kg>Yr^IU at S{d5;1(ti2#(4-ag>`>0lD$euw^
zQ{27Y8teP=u=jX<z~yp+a`W_BxQM56*9nLtUbk~0b#--3(L}%-X|vIa_ at CUHE0Sd9
z;GiUxy3Y+Sq5jIl!&46s-mCTd2muN2J;5zL0lzpLV-xS`%1S0Kri70E^>YLB(K<*E
z0MB0H%@_oq;n(C-oGi5E-s#9=+tZpbz*6j})n=b?fP%Ng2~znzJ-(UDP!LH;Nx;M`
ztgUG`E~pShfnfkot63(hjGp^MqqG^9>WdHX6Kq0432p7Hh*o99vERQTUNw($>C}Ir
z*==wDX(Mq!4h(%|Qec^>lc-r~i#qz}x3 at QqF1MP90LHNH!x^5m;}i>i>@X61&K4d{
zX;RkztWvoGlZwi(qmHE|K2lOrs&z3bDgqtM3s&AylICWW1nH6T*M$#SpLL1`z`k>?
zHl@#n8CFdDqBmN$<;?c?+Hv+rjmMa0o==^V&{m5EnUtMfU5-F)C(E7h=wH**(}ldf
zyCSBCtjXgD`L&jrme~+bT{?%-Gpd9=p6 at L09v-6hHv#i%;*g1tkB<s>MfrA7>QsUi
zkt=8F&#vcoBA4+Ik66;bf_>E9VIMustRA0x@|jy{D^q|mk+L}XYqoHot}#)orKB)q
zNSTJOc(EDxakf{YU7qZ=U!+I7YTQDgtvCZcdu=($$_!x;cpTouKjc7yOIeE=A+VVC
z_I2q`5<uZX7APnvQ;_L~+mERUo3F0j96!|500NqUjSWJin8>EHk<q7vgM$+3p^j4F
zn%aQrP}mL<Le4R)h4hLC&!_XM5^PnP*z`lhC_Uxat!`4*?%l+7YCv`mGKCB?kdQPu
zM4baZgs<q>m59{1q!4~5q%k_w5VGu$)VKrGK}47kA&Lbe>fan at -uehXS&<~q4l_NX
zmmgb{<rd`xQ{Q09Ddp9n)oVyJ6lf?eR>WEQ{Uw8oR>aMgh_yPg$b=bW`Xya5yS5ey
zyb{5x=%0b<tkxR_OMwfe>`<VAusp5h*<@dud|84NxtL_*+HY27xZGny0|SVhoE*}r
z3*bIn`RZTcA+FP*e^suZsTVxFm6lRX4OfjH9mSl~R6q$&HjKy?x0;arRE6QZOhKMH
z9#JvcZ2b8v%x2PKSMbVyonPgyzo5<T*dH)iBwWYX at D86Z;`>qA*Go^IZ+8QA5D>7p
z at dw87_Mw-2@#RP$E$f~wW&H9{c-ZR%{T_7xH<iyHcT!)=W?l(oLtKx;pJvOmgLDLq
z6#~C`J>E44{?>n29hM|izPc({A;FP_aAh-p)UzyQEms~_&2D3t3$8uW=x{RC3|_qD
zLqJ6A2N>#C3iKY55)xuXx$TDY3kzfj8CJ?1<s)H&!G+Y=xVQsAak!f&KA>z^+0t=(
z>6eXGbDK6DdfQBKzyHy<y at i-}=nc8*P!Kn*ijt6OYN1M^SZP1ILc}g$4Y)tMkUS)P
z`YaI8$L|8Mk#l@~(+l1o4IRB+O7ag)UJit9b}RoT_&ZO>1D%NPfguLL?~|>yU<gsp
zJCokViyQP23~?0ZWPaod&m@~<=_csu!`#}j3#FMhMEv!@8P-9VDUiSF<I_&wD?{(=
zfcKR|4_=OLU0v1>(cFg&gm&rwJedbx<7R5iSCI!GA+ARpoh4t|X<XXtx26xc8KU1U
z$G%wK64bGh!n{u^OXiekGAdf%7+l#FTnQ>vzXBQ_8y`R0Oc4PAA-}Ir9~)5#y+D!L
zz{JEvi$E4#9FRq#EE(t{2%OLpa}f`fmYKjegR86QkKG4cT+T-bKWnr?$t2 at st19Yk
z at ls9IHV>ScwZ^ATEmOH!0l421oXzIrag;qneK`fV3u at 1z3?;~AbyrfdG(-yJC8m7}
zzT at V87l;<SRM$xJ!(ll6Q0cbX+BvX+#?SGANF!(b9nyiO?{RrA_18b{GVbiUrC_FT
zg+FeJ78FoWR!|xFId*!IlRtu2;ooV(3OXVzyh8sp(O_*{mZRfN*Y$V{Q9m;gHsGtK
za5{4Xt%bo&r!3zGefn(vMgqM?B)TB0)ABIb?lh%O#<H>>xoIqP%`G(duT#OSP=(bT
z at oGK8X%0tR=@%fH1Oyn&`sRp78X6iJn@>(o0xUBNuljJq0|2-!_YFX?2zn);n3xy?
z2L}{DK~c<<o$<_{-o+$jc#ZcAOVps6Jy9jHGov+K((A5-zA3 at GFr=6FvFfsA$VQDo
zuuRE{7#XHChgLc(<{SOykBs>gQW+|wG+S%>>odw{<5i2hy{#@n$$laUt%=<Z;%I#V
zFy-r?BgTDD-iND2hoploh_~KyDTi8Y`Ub5~(Q%nSu=&%Y)>pm1MY<FD`4Cs(1!4mE
z>CvQ<$Ii1W>H at UsccTX4ke?uC7o=!lzD7kch<|=%Rjl_^vRIJ5r7AyBTX99j_)(%f
zcIZTrcgu%NMn-n>?;n~3U;{AWk7jUaQzl3eC;drgH#76b<T+NUQ2mi0$d0?KM4Y*v
zD_xR06u2<vq&qF8sdXGJcH0m3HS}K8T2`K)qDztfG9k6V2EeFHEgoqpsY$yrx at 5(8
zl)}LiVblP$PQ at aKCt_qgh(+}LbfzV8x+X*h5ufL^EC=%)|6%{Xgag9~@Wz8wR~_bc
zqp*ox1tzt^==75akx!VdQ1^`Qz(5Ncfkx2fhNv_FKEHy$2+ggde%I1{G9V#kh5sXy
zQl31!jzWDL7fp;T$!aLEr^=>qCK6K4U}<(=&S=dR9M(t*s0U#0*o-BV(19(DAbnv%
za6DgaXk;rG at Lym%F2?>vYM4n0-~gcR;dkZNath~H9)5m)(qUPevJyVpB9x{)_(XGZ
zxKvYNC3NOKE4{7BAY!2g4LU<M0R81N0QhGey}^qt;?sG(`>vfchQy7+?$}t`RnhA=
zjS>ig$XisaQ)e2>5c}-6o%ZDuVQ{6p at zof}D6a$QB2pJSKA at Ttf?&LRVTxvnT~&pA
z@}mcvaGLmQJ!=Erhn<;&(+%tiK^L-M?jzFADj^zA64G?U89~=Px;VJ1yA+3u+k7nK
zy^KKrA;Ti%QlMh`GR*I77_t7uxnk5anxh+86RFkK*tj?(1SBMRXJTc at -pWcqdx&ym
z<+w3aRcbL0+i>s<Yl|cQKc2n<DysJT8bPGHySuxF?rxD5q&ua%J0zsL6%<e!q?;jB
z6p)4ikr=v!@9|x~|92Nl!R2u8+<ESE&e?mPeK0Yzd{~n#YkGR9TwPsxHNBtP+rLi?
zVVHiKcNnnQ;?Q0p$9}kzl2_$o&NcVq1cK9ekTX`1pF)OTJ7kar)qI~1W5{A;td!Ni
zeRN8SZZH()a_~Q>4mz3MdL;9s3Z*bWSbXP?@%nQ02~Ym*)W*OYQt}5ux1T4D+ZCv}
zevjh4 at BykXd%5uZOXu0u2Xc*Q>JJFt1a`7&^9ZBzFiQg`3Q_Tvz7mFpEWqHuUL6kz
zK>P5>!w-ypMSLr2iW9k at _3iL8due1!DM>=k{i9`IlwvXT>6P3tOzU3z2fByVt)5xi
z(W^1JC#-5M(Lqji&{~tDN$3j@(E0G)eJNw<Vq;@pE(?PK!Z62gX=y1sLe_lhn)cgI
zLM8G|Rj6*=ujcxCdiGcO%w~(`Z&AJT>`11+B821AKMilOhi-z(nMo~wh)`oeAuLS#
zd!zZX#{uWZ>$}AK?CW037EB&KI|!7Z%<;%Iqd at oH2Ju4toS6ML8U4`buZll9w?^e|
zo)Z%3>)Ta7^s#*;pzwn{rC}#T=$hvlypf<Lx(h at 69ZAaX({uAZobx$BI4a&{rDZDE
zM>xug;>6n|EW)*16>0*tkFfE|7hfc-EuE9Se5D`~hw`aWm+T?*8|lpSvp{L5xk8XJ
zfG;SlrpE|W_MilA{`seMO?N}O>aDKwd<O(Y62wx_*?7?^PPS=SpIvr0CV0M&*ReI4
z_R7bHFxMiG4cwgVGLi~?@OlDmNCYSj0T_`eri4F9AZV|oo0T7Dm*XR#Z)k|QQEru|
zOE~@v0iZ>kvj<htY&vDE<b;ZY=QlLyghO3SbN1huYLxH4n7Y{d+AVS2OL#{$J&&^c
z=&UB1lBKww*RH#==V+Hrxbm}8LN`CR at nG-xm?ubb)RUK=pZ;`0408}ymu!$%?K+}H
zYFeSe|F4#x-&HHLp*~TAIm(9LICDlgH{_Rwd1HM*<25xk71i+A7;0nhtrHm3oaxiD
zb02qX59+;frrejo!IYrTsPEK`Q8<V!WIMNSWW9-n1z6uQPv at cy>by|<Z(~22(0JeH
z{`{mC-KdhC4XtG^LeIi9MTAvO<c-UFLHlZB!rQ<<Re5?M1&*MXG0QDy+$Me8280|b
zE^~nrXl{=ieTEEsHvR}Q(L-)fb>6OchAuJ!&`B)(_5(`?<g+fz!~%47n^2S8DZ$JP
z{nXb2hq{J_p4TT<f7bfKjK^*}iZQk$0K@?Bg#uyM0U$s4Xf+s%FR5=Gu&*lUt-c@#
z7My;T)($!n_)Kqs0=BszFM0^keI*bl(j{6x3HICQ?8YhdyAv&$L`f}Xlc$TKPQ5{c
z#KNX){@vYOL#iBGVx$H$((-5Z<UG+d19f-u!e76Br8G8j&jG9y(*~d`zP{Nj4cS+}
z&DJ#kE0QvREtL4_pMr9L?EviKEhwD9H-zYNS6MH5yMbe?YTcw+*{CFnATI|hqSaRq
zoaE@}p?fe;&-!a(k=Z7}s56n9XW%FDlraoLj-s)JpA+3f`fp9l=@{kZ7Jb1fEA{G{
zKM5>g!@WyN4qWo`lGzsoK}r7lcr^uJFwMgMkuKr3#())=s(!=DGdQ8xpCiD!FzRbg
zh#r%<iwDVP{dj*Jxt(^<DI^9{GZ8S&K?Zp?6c!`nO{uJ8$H at 5G=4&gxk9i5- at Vm?n
z{2J{B>W39a!8HeYjx)Tp6Cw5Oy6<i=+X$uJi=SP=6 at jp4e4GpN^zYw=x!CoO^6dB_
z*8;P?djXNOxK!Gz+O$1Z+;^S$lH}QGB){`2BOmCgYLh|y{As2pN7}p{UH46lKAEf&
zR|tXDu7$H<D2P?0>fcTI_#D{h#qv4Nc?t;$K$d3Jd<Ap~69N@(^_{0RIL`3d7QV(;
z>vd{Xe6mYz+k1c6HFS_)-QUa!AfntNu|d38y1>9d1%;Xw(ipGvyaYR&*;yKXGY8EH
zUr3R9$jeWkgi`bb^rt0e&d==lM at XWIS4!CyxwOf{Cev8Po(Pm+Hx0a{iyA(IyvSkV
ze#bh|dc^uK0jw}1X?XtA^6S#4rP?VMAA0gnnfG)&U*%X`JuRG=#C7Rzy*$f at 59~lN
zeQErBcn@<rrz|qqY1FLIRRGqN=bzaNO(9zaUaDeDTMhWvLIu8>zc*%0W)d4JQxt;J
zbWL|}PUKZZ1SXpmK!)B6YUUrGx!AbrbZg|Bv+1#OY`NNvK7Ffp7{%&U((NS2GHCl)
z$d5Rd&Wnk3cz6h)k+_3S+chxC?fmMBAx~qV`5hUC{S9T_HH`HzV{!Q;t0fQ90cgfZ
z7rrNiYF(MSVb9&XZgcj{R|!<f5^!=V607v?mk;>3?MNrfM5YbcvVQYJ`~1J9HDB3&
zhmI}OI8|xhBe-O{iBw+ea?IaUm$sT9AxJGJ)3^y#kqb`*@kEy^jU?L|gN7Ip^cY0S
z(Fj;Tq){y&4$*c&HCytwS8FNjBxv*Zm=;>3&7JH&gY>5*C?I}z)fRx*m5Y!`e0JTM
z;Am3d&Xxc8g0PO>XWH&4 at Oe^U{=soh3!gr>=JR>S8~9UXT@~u-h5|C2iy`?@M#i1k
ztn}Jrs~=Omnk|eZol9f#LS9vd<cR4}@mc3iHB?Z;OJRv3mu2pas-M5P$YmYP;_prk
z1eQN5-sajGGx at CVJDk^;!KM3{$>z>O>WxZe^B|r2DI2oTktSzj;sIX5s|sxAZx$`O
zu&Jr)M}viJ8 at jcsyqygV-_ZF|<6hK3ov+I?9Q^Vl7*~<H>UKX_%;m~^2YP-={?5|F
ze=2JpTQY1aByu3m@@6~}@yE^7rlX=oVmT^!=ZWQ6q(jr6ch5pB_ at C9<3H8?aFMf3T
ztv4pCs)Qp(-F}vdS=n)dvyXM&-D&}Me!k`CDnwO59`){dz^-Vj3XV&4{3pTZjO=9m
z+b`>c-kZS+qL#Q3am}YqxGcd%%zeS|DfoDhQqEfbJXS*fw`_%-kX<<|e(~kaHZnBk
z`Lqg4qHtEy1gA)z%!mvVa{6S76BZ*s_h$Df^v0=4xr8OE-pr`==lr)EB=#x;vD7HJ
zGSubI=^wac>NKuE+~ZA5hg@}-aVL%U3(Ok1$%S>r*!`q0%&mH378y08sK(d$^X(H_
zh)nM>5J5ZSGjlS7bn%vz%V!q;xqjN~T0aD-N-N_}t?g$Gp$ReV8wX}vr3JwZaYg<d
z>~l3|Djw?M6qa~y#+CwIU0QqcIR|cZZHDe+xweVo27!<HK{MYYTpFR0BvH0>J8}Z!
zm+gE6v2-INEFP!hcknaV=!dK7wIQYu;(K2F3m=G=u&`9*RvILHPP6HY?{b$FixA{t
zC#>J^@-Lf|k2&Jca+Ymw5pKuF*-v9K)pHaEO}vZolp?9Xh4T90J+q-Ux#%R$*SFD~
z?9j=#bk(oTjVhB*A}Ngp80h%?hV8f$U*JC7^l*p`QF6ovAPeihcU^W}jMlb|W3{}t
zE at 6hnh@--(Z&|jllx9a>tft;a(Ye|spJAm!0fy}6o4F<c5@(qn=k*?Ra-$FHLT;v;
z*3bGxBbB{^J{<QL(N0MK2?A-!l-z<Kqbmm5vcgBv1pB@#reJ3m6pNl70=Lz{%Qb(I
z%ci{{h1LGCF;+ at woTEla4Oh0p+yx(mAALbE9972v`EZ}mM{{uO2jgif#`4#U53W9y
z1gP{_-es2?gK+ at 5nwXK*BSZ!;3Mi5QkI%|+4AYNdoHMyA_E%Z-1pqvmz4Nrwl+NBy
zPfCE(0!9FO_A<YE44MV#Na<RJ7Zt~1nhOBGiRR63U<r{LNGl(iE`0|8NX-Q`dZUX_
zH!m$b9wG5|T at 9a1M^^mz)`i0vlO*fKA&AnD`PjDJgXh6lEq+_ at xm+uCgP|{9jFYKD
z5lSAnN#NJ}l>7ykTUc!tiFYNEDHYn?BqD#6QMmgKrL6{`(y7P2e+IAjIPl++ibtb7
z912_yTouQzeI|Bq-}>eMtIE`4_XY(XCUr$b$`R=KXI6mq^I^Zl<F=LyZ`{ebkyL70
z*oAI#Ao=s7N2K6OcQ^U at s|H~QY-&in#Bn!4ok9JdV_+mIbu+HLS;Z4lC#c707hTQ@
z(0Y}c1 at J{mL(}x at EnUnIFQ#ZJgIoq--9Li%*seN6CDDO_qb#vJUfzX!-xkBuvRDnd
zv<!=Uviarm=TfLODgThVLWPougP^87z(aX$h at +J7@snI<XZrwQvpvL``nbub at h*Vu
z($WJ at i+MGQ=I@^Id0!<`#|8^LChR7xeOvo at gr)IC$~b}c)_!-)CB_5NmBmfl^`8hK
z(U4oQ;IkU)0am$>qN$d_`z`Izu4j*z>oC64DDCy0urp7W7mrWQ_t{6ZNj#<{9x=mu
zB@<AjZj`Slazo?&ETj|D{@&59`YyJ4o;^dZv3MJ;I+w}5b~r-eK6HI8Ds|nDqot04
zK8Sl9w08GzZ-43K)g1i{@>hdg1iw-q)L-M{s-DDOU8ZKs2C~^EUU9UEF#$gKIkWRm
zf!4?CsT`%B-Zm<=^@#@TOyyV at x@)|PevDSipXjm(R#i?Dc3p5o+WSQo^UF-ulI%j$
zz3b=vRTnQD=X!1wY;)9P6Kkv{y}dTDB9%gOe*Rt+bqA3%8K-1~LHjN|!}9;M0F?d3
z4epT%g0Iax(XJ%Vk<5bnxjeM)pEC3qtuJ0S0X!Z>{JT|*AEox)6EOUu%t)bkuh+q+
zearte2GQ;Bp!4kEPP%yu%H8wTBoyuKlabcM)M?X?K?`bx-u4-0Ekw6GN*OOg$ShhO
z?XO2h9}v at g-Vf|Fbs#tWx!Qn6d<R6Ft9uZI%koH(-)aJ&6cD}u{6Xq=E^YI2*<D$<
zfUCew#I(V;BP=Jk(I%hSz>p{^6J{tNe at I|xNF?SAr<WaniI4w{%Kxk`B%vI&_c(Wo
z(J{J5Inh(Rh}gRh0xj at U(|IpQ9~BFAbtD8VC16n8<?W;nwAL;{ED5jmB5WB>GOb7f
z>_u>I!NDVBve7qm?>PR*X)BQBg!R=4HWh6ZpOB!st(3O;(^4vlK=~0R)H4 at bL^@JH
z$75Ghq;y*C3rF(SpPyFIR(REpvbqR7dbq?aibZOKPjrNSyhe<DmW++H at kb_H?lrzu
z?H6Gm1q4E5)N*fM2dik_lXY?mc(wF3L$`+)!f5d=^}`KPSkzF>1GSM2V!P}Gc3naO
z8l|WQ0vMAq=xljsg7C$t at 7B=l^-o)nP8Tx2**Y(5(pN7Rx)d)$DTaNc%p)1Wq-xKx
zMdKLf#k}t2Ax8j^KWF2B^4;uNHxtQuWiX<C9X^KD*pv~jS5)kLdk#5xhTqZYV-)Rj
z_^FaH!U*B>dVo{}_i9emx-LMKTr|_-Vkrtz#f~YjfPfx%tnBmicwIm2lGuix<W-dN
zNle-UPw?F=@59TrCocB`cOF+^knqK0OAIcF at Xh*PFMj at t-LRC5ig4~MJ9ws{iA;!`
zSNy5{e&Eyfo_%jJ)p0jo-Bubv=S)^Q-c#&`V-X>gvytU#yhSkBw(!T5_Foz;E^7FA
z(Cy1x#BkzEfSwp%?xE$pD~kPZzJzx0Cc#Mv4d^@v at C8>x`iTBCBV%~oJKja#;SRB;
zv1EYb?UlSu<v`KnRafDB=-1lU2kIDbFLW;n6(bz;nI`NZR1RzsDxOiXyX~CAXF3yv
zlJebJc6D7Y$g;F{33xnQ!Ul#huFKZtk~GM(?6Ju{_p0R2cf+tGe-TsD91dZ%^- at y=
z&7V->>`!rb?|-I%L$$H!Lk1^3V2{B(QdbE)o9<y|GRvJw at EqxObff$4%kU}bVB)Y#
znDiGz_v;XsHE+C`V@;WF`u;cW4|M0}HE{RGlPgsI1Nbt{^((Wlx&4)$#LJ&ul?t9P
zUJ%|cx{U;w`o6RH89@`e&wW4HHj1|->3?zefY|g0Q-}3y at lwFwi^Zg=Vzt<0!E2_8
z!;AK)_r$%pBbWh4wJ!w|=>hSlXKv$chnCPmHFP#z0uwL<8Qq05VWK(ae-OFic7<7G
z*>}N at F{OBPnDTT at 4twPXok`ZLd!4BY^mL~oY!f=pPCqq#@}b`IWwLnWf!~Muo$wQ$
za!#`IU2Y2IyPN#d`#zNw^en*Q`{&q{%9H03618UNh8_82n$Dw5e}5{MDO00&ME(eK
zwuBQ0 at 0paYUprX#(HuXl8}edO>8 at A2VEv+bG)(pAERAU%0~0 at ihyKB#+D at XD`$T2*
zFcReP%e_DcuiuxF&>Sb>=<Gzo?@z>W$4T(Zoq(nRi7N+>9#p^kEA^M8;syxCrV1a|
zXAaB&T_yD1UCfx}YWj5PtkQC7w2Ud44Cq%hnALCZ?s|E8H1P3##qW3POLf()7X+Um
zq;7qs%q%)A1~gutMvkcPZz9JRtmJcjjt*w at 8MvQFFJ8QIik4BrbdSX?VOmg0q=zwq
zLZyC80|^2{nru#2VH{eaSoBqQ5VRcZ#&fo-lzZOQPemi#@l{CRY^P;Ebscrs?DY~1
zQiA{ufIk{9=IxSBYIQO#ayB26oQV;hbvUk#@4P57+oL~tGh<YE`Exi+Hv2MV=oHC)
zPhe5De<2wl9qXNLs&jp=%LucC0z8b2CVxv|8Muaq!)Dlvz9d8KI)uovR`H!;t5q(I
zQJA?VtoSLIg8<)_i?Bc?ha0d-y)Rg(&Csvj%e&zu_p<3|lsLYqiW+O?1eIRr>F}fA
zWMQevs=0NjR>Je_WenR|XboAv9yty?pUhZ<p&#m|=GcS`ibHp1gpF}V+mU8YRY$ah
zXQHGLb#_!=Gv5+AFEzolimtN)jxK0<P^+kP#o5SI%v76ft^ewA9Gp*`hjwd4agcht
zTZxgwpI->R6s0yVy%QRIGL1#9#ZsTNd2BFVpypF9Z9|I3GxtPs<aNuOgVeJWpNDVU
zYn#DLb0!BAxu5Xy>+1)aIXzRSIQX|jQ{N`YkocJc>438CrrEyMX5ti!`K&&LUk3
z``-&v3xDfu1s_EYT^n6a!xk%u%U1qG1hOigV=FM|eYP*hGb-OyBU0p<V1r%MzNz&)
zL?$CTmts5~=dH_%#WxZZE2<4mSg0=UCahTm3;m?!%`QyEKv}vTd3!>mV$Qu0%FyL!
zSgl;u!+tTf<G8K&w4 at oyNf;Cwa%DQW#P~bYZ@`o at x;avGR+4MNd?u!FSfO6!r^4Jf
zP7wbZj?P^<A{(AcJ>HU_^h_-!tQvwE5|Njig3K``%KQ_Gz4>`YVm+IJ^n<w+U+(V~
zmY^ehU;lIqk|5=ai>p?-xSdyYzBiF<0WDY^IT-F!Sq1V8A0ao9<SIZCu^<%9Ctqi?
z;;la1m&H#DE}|WsjYe1z3Ey7*8!L>-d00!M`|VrI&t7<M^Lo`EcTqeV=Hg}c{VNNh
zN(}rC6LZcTtgH|!0Cx{~Qf`oDy)C*rz3DEcS(MKYk>;|^?NQ3=pVl#A{n%crfndJq
zyvi}428U=@=4G_y<|DR7zRXB}f&C1N1Q9M+nwPa$_13&43&n{`&`A-=PPn3arGMU`
z`>V<bruO8FT}$(7s~TwK0kW+HLB$Cdjy)=P>#v<qrQt4XwO2}!{!x)EXKvF|c`4nh
z1_A=6sTI-D3IVq6Y**?G$KL|KPqm__kne~Ulx-lvDyo7l5;=ih$wfHHhCc!9W6)`1
z2Vp_Mr_i%>t(q9VAFSO*&RKk at i2n(Ca$Hng84h)wp6Rg?>TnV()=b^Z8<*b%L}7+G
zi3&G8L&(aJD+&bC1=3g`o^(4y0Z(3lx0(vMDyOvavu{N}${!K&<ef!Nr_FYR0vqTQ
z;uRH*2dMko>YqA}cAv)BG#7?2c}G0~+BE!_+pxlb6qDR#{Soya_bsv0 at uB<TNuqUN
zu}Ghwz)Pnk5k68fq2SZ@=>HA{+gGvl0-s%9d3oUj8hG#UkmzO|pT`>fsGLTvXlhCU
zI1Y^km)d6t-sX3#iL(Hzi$cM%UZ~at5MhTI_Dyi8?5>$m7vI)hFR9I+J1L;PFfz(r
zA<=WonR=V&Cn7Lm`_-4K7}oz^;%;XG(ujY at R4^+j#hi3lSXllkV*auFVp5Y-_4S*7
zezpL*RgOPTfjv9Y*0?;%Nq}6yV5JurP6Dq at 0)%iIel+Nrf_(gQmqtA<S1@;(`qYlT
z%kP+*@4T|H1F{jY+FeMt5NoGL&G1)K@~p#`i;j-3MULTWas|6Ha86Z7<3(pGD{J{)
ztd0RtxXQ?arVZSEW{s4ZRt3~xoMI9gNJjZUGv;+;60O;N!cSl6bt0l_SNSvuAteqT
zA!#hKxe;z4wwYywqp42+??O46#sdaIXq8Nx%U)SjISDsf3b`#bquh=(wl;U%u0=HT
zUKGGqvvYI0-gk3$xk*-}^d-<Opd14jCJ+|?BTqpTNYr2u(}qo$e*Novb at WTr_ctLB
zQ$@>_(NZ7`IoK=<1K2;wb@?-0hDto$^y!pY at qOt*C#jPp&p-MJFXE#s5K*ErjPNEq
zMqL9%XuSlGP^Bu>6K{67hhY1Kz;qpgRwJ$+zY`}*Uzp!t*!LzC&ZQdl?HrClyhM&}
zZqO8TfUscdwM)?ch3Ls|j9KEC_|h*>>Jc!d)Yt61daWP%@B8mXYO?9lv0))=aqzQq
z-)r~dK%u1y&)~DOlA$&lilJMhzuc?ci~Z(dS52b7O+f=*MtPa at mK0_Cg^A153;mHa
z<Do0*Qz=O2%@zEp;C7>H($upeA4lqxwgmc*0|1;TJ-O_!E|Z(!Dl+~UxhJ661^fvD
z=bLd5JHf{MFPgj+lBoUe4;JB%-jFWRc at E!Nk`$9o3 at 3CMB>k%XHi+yK!XwQ3 at was9
zc>|@ogtCT)K+3XIr3x0F;8uTKJ-Y$Z!1}_~)<Vf6apFE!`$LNR;5So4$Z0&Hp<%j3
z7*pdCGURlyWOE&-FTCmfO7hx|+(;Uyv7QrDrKRuI7ZZft;|rpakSB{trF+lxs6zG*
z_~%yW^&;x)W__^wx6y)+SG!K8qv*JMZ>~<NIofFbZgX|AP_67(+`63vm{TQVOCa~I
z!Qws0H2#CwtYwJ~*K82}+1T8bUUF6&K7Ts|0%RPp3N?Jo-4#(VHH}{fD?h{X6>H(d
z7`Da(&m9o>B=MJi#v?Q;M<(O5`SK#ia6Ywzh%i(tDY5gd>Z|Hze0A4++lJkpASHb&
zL+~^K<@$K-H!*!Ce6)-OAbHcP%d+7{OCZPbNKi7yr8>e`8#RwhqhAZba|`;V*<K0_
zKM34p$p03bszs$LA7l4U#yu{ARj;(38(TUU_wZmXIeUWdel6&ze~TsL-HTrd9 at e<S
z-<n2)R-36JC<I%$kYu8Y!>}#;?sOqR&quRS+(sKLoAFTP=4TPOB7B&UDwj(e9N+!c
zLclAn#hZcL2#$1KZf?5KK&7s+?w3Qf`;RQqmZ4UJ2k_mscD#n=6k8S)71^3HkF5Q4
z4d$BZWrwQ#h-+SxhX=4l_SJbCH<0p!<Qsi;=UwlF550-1x&Cj>-s45eI&MdOCCOsI
z#sNsuie|<i0L}s!4jq>D6}po9g1+VmiRfW}c(q7-+BZ6#KX}KWEn<{X;0<^$-H-JL
z!JD*WP>H_$UJ4iDa8aNu6^CxtC=<GLxe1&npq!kK^X*XudF)SGMt<T5O8-o7VonqP
z8>;SW$V!Opw1HU+McG^N<goY at hM}>jh>DCyFZ0bR`4RIf_()elH~x!B#6`n$Su9<a
z1HLvyAiOuX7k|Grd{m33|HE490rzT}YlBgFLkpE^OK4FydC0st+gW8hMJ%0 at -sCs5
z)^a|1dH5cV$V-(u_o1s)iahTCCF-&a?8cwaCkZ=~NPtw#P(h8VCeE75E9>2BbtF=Z
za9y74tSSZJt%V^v(<}xXhS~cN))#xU){C_ql<ChW!a0!7 at rd!TC&N>Gy*YYPhk~;y
zVHre95q5^&E**wj^X{<yy`_AqS#kl7WIT_g7cTgSRe?+JyY_8OFg5vV025KLEjk%D
zkIKR5lr(Jj;CfSJq5Y6(`6U}{mEC9Koa&3^V=l)!We}lX$nM$o<*&7Y)vF#n$yYU=
z{zG4?Oa)Mh2qZwaai939ImCahZz~SyTAf)|Pfgpb^=m%4h^6m3>UaiqkM(?m8U<QX
zzc<lR>-|~+P!GVV&HDE2=9w{N<QcFdL(fVb$(w(2;wMDoD$KY1%TWqHC#P-aSPq){
zNk;LkoP_|lw_hoy?tMgeZEaDN`2w%el~ZrVP$mqv`*{#27^&~}(R|FVmtWM~oU|DK
zShkE=`&C0P?L)fOe%vK`d-7NGbSd{`93HKMT?iBU`X|fyw!V)fYqxDd at V&MN974)3
z(@j6Hh-97;B??4tDW^TD2vDeh<}W6y8=axg!Z-IBjbh<hB(Fl&pFym)KBA0*(YevS
z7 at n{LGKc_g#B>qIhZRHd;@665ZVeorW`5~`AZjZxMU^ZqL6_f_v3;`nF^jc*ZViy%
z-PTuTgr@;}TJb_87IBtom at B@EA=jIIq4*4K-NcfqNdQuQ(|7F`e7}$SrUREl_|M3W
z(V at Kc9vdX^`-r;58V(bJU>E{U at Wp{>hA%?&SeN+czD<*NB1nSn1k}j!a-ug7uRvle
zn2_knF6R8>gJLkuxn%T9ozd2A?$sA>GyfXuFEtN4R!`mVGJ4RBR(!B-*Eh$v;$}bH
zcrp4CscnOCmseY>D5><bSWmU6CA%)IVD+z6)_iQYl;q^(ti>q!s~r;wTLQ4ApCW)-
zC-%Ee1ihkz4OV!xf-gnON*@#ZLM^oqdN4AD#e?|${tim119Rdq>aXRdq2s?dRj3Ry
z->@8DkJzt!ggJGO3^n5%4 at Cd2%O<y4h9`9*K(FwaKCfdv?o*vOeoro!6T#ezNb|tk
z|MbNm(y3|W at c52*wUqS31+H2kS7XRo*NK<3%u}lBx{bEAt3{^c+FJeLl?;jGL8zwn
z!l%EpxO4^@g?={&ANDgz7LE*lg_k+|Hsxj5XGL#wfe&N(6^K}<h+tRtMyRSRATtkN
zLPO-|<OD0QTgMmab7*7I^QQ>x8k2S<v!&UN%~jD-14OW`oPtGKq8J#VH&Lgfth*$8
ze=7lBXWoaONlu^5cZ1O7YJYeQ18d;kzr)8)&p4;kr&#E~!N&n{uWxa{eQJHAGd+U&
zNgg8-0pOv+(?0O_TySgU$_?=p$)CIZjFE~yL1MdN*FmfQ8H2%X5kY%Gmxh7{js%mJ
z#>7AfY_)uOZz7=2<Ksl9+G1BrtGpoiRF?L at 9wZbw$OE+Dh02m$vii;(n*Y7XHgqPI
z4rH!?P(t#7*@C_ZrrZ97;ks-a+^0b21>!c4d+^Hv2>(qW3v9|jlR>rScYvzgY36 at -
z={e%J354**19}3NM%-79lF+CvQEPk-W2N&J&>;^b)N_X#|1ST3hc!2-K#O5?iS$5o
z3|cUFG1W~L7i|Er_JaRI?6V)Un#)T|v&+j#K(g&A|L+3-cO*Dr<yn7>hr>PpX}g<q
zK$oU+OGkO-6NIX_KxhpL-#aNnMOo5V0005Mf at sJ5f7usEWa%@&)y;p%NRM|ln7Dg4
zJosUS*3p2hFs-tX3ukpgf5tVV7R7yzI?K at xP?%sMv43%#i!cTPP*WmlED(AvpFv2K
zT#I;p#SuVbLUmCAmB)-)`JM*I_F}czvj>0=A<!B`g2b at Bkz+~JNbgTQ9>R{4(Y`&S
z4dBv>4#n6*Vnd}Cjt}6)@TlHZpLehSQe05)e0SuANJ>dr0MZ{;<a87I3DTwm2>~Km
z;1 at z-;cq4DA6Ok^bSLHgYvE$E=UQ?zxHbLG_VXijh$h?LP6}d<p{ZRYj;yHbak at Q@
z{HCHMq^;O~PHtkqW8Rz3zY}j}H_t!+vE=M|%N~`t7}Ui0_yy*#QoM^)lO4~V3v56@
zs4&hhF0$B}#9FcLPLam)RY>wRfLP at 0fXG7hw`Rf7N;Lx%hxU0I&w$>ES5sfXyB34o
z_+>C@>haxXmk-zNJCNynf0a#nCv;m3{weT_!IhAcfy`o6Aa!79uj5!t9V<HEI6=Vv
zwFDUNMU24 at +vZWUxJ9d?Q~*VT1#H4}1;70q71UJFWkfI7lk(wGgH_zkb)8^oAFC=c
z|J5=y1W+|2J{l0)1FCm5<DCiU^m?FMLq!;pz;pE%OeL2BxMs3RXKb}2(58QOO)A0D
z-1{3(>_cNc57KUOjal#czc-y8;&Yv|CU~xOe8?fsbqV_=T3@%8?cIX!e9c)C>Gy^u
zc;Qg6^2M(db)N#wo~}0Vl0gUOQpsA4TU+MEl%*)=s$rXZ;}6(*xWFLqkbsA~Kw4HN
zOMdU*V(R77x%eaP?$Ij_m{nr4o>7LsviuUse~ot_XFZxOhymQ*-t-QJ<>R%`zIlAx
zzT~xdMld}&F3(U30G)>K7Fy<(PCqd&{rD`Y**n{brwzXn(A58<Ue3|P#2Bh)X!wqA
z9MeQOkc4|IA#AU6h+t^aNAtFDOSJqBV_bo{s`POgW;Zk|zVJ}iS9d+{Nl6#fF;yd}
z36bsA4xYFvwoGe68u#X|P*s`_oWCh^%ujdij(w9Te{;3~bL>04V18gW$@o(tsdS*q
zAMO9oL&LAao*~f7LO`=+dxb6lPcdWtm5Gt~tM;?>WAB*-PcluYc5C$o(`wmO878`+
zp?bCBS<pfk+`j5lg%I8CyyT{?Y&jAf0nT=4l$n&e6 at OI~V%S((>|f;nPX_4=gW*Wy
zYz3k$at!c-hm|Q1WzJ8yC+ZAYlEggifa<=eeokU<h1qxzs={r5-R0F2b%5>J at j~@@
zy`=1F!<l+fLR33<K?10GGskTbR{M|5If;i?)1Yk0XM&OhxdD}axJ5TNBTW>G5_`sz
z`&7aOX@*+I at yE{dJrny>jA6SKe(8nzs>h`;mVluvlIiewm44|`{ZO7wj7%zc3kP>v
z`_y~zOK|Yr7y9-)#EKlvJBr8mwYp_t3h!sJDMe2r&SoUEd7rpa2C|u8>ZLkvEo=<o
zxS6QnTeli-#>p1WC6va<$?{?vJ>Bm*54nXHZFca3?wa5=lC>QaOfCqSBjer{Rqfs{
zhbJBUDs!ym$}54piW+7*^8*3JM*LlI9P(x#x*ARC%_v9lpb7=4t8Xxzt(9)YBvD+^
z#m^l?@mvjVscQt_NWXGJl at I#!O8mZ5Xp*?Yrb|*VSRT54K%B|tDDWJ7ql}WUYWDKX
zp4I{$V#&JGdyFxhUW4yZ40>V*);CdDVD?%p4`%0*U{9FbdD at q*M at n+q`s}>dC#)O~
z&3e<ZG5o}S^N#buoqFP%FBN!G?@)d*G|HTnc)m)DrhCr?a}0dGNy6Xm7)r$E*m_y1
zk=g&{O2w>WH;(Sm-bB0jK at Flaqpv(dfp*irsd}%`E$>rRGE9YN##RMmme08)KXhNk
zE@@PU_S+)D+&gK;0f>U^J|DtXKU2gV%tLS(Kf320SnU-n7$RLTode-va}4G=4beOx
z$Q_l%%{mc;i;XiK$!sKAKoCa*GOrUkdOeW^L$AGGWi`sfkmrPE7R+|%Bpn{-mf(XW
zGs4TChr2w73ns}o(WJIg9Fz|<oi$2e_98tLk|afIg(&SCviy=qLN!-A!ODxYz4VGn
zVX++C_ZpQ-a_7dk(ndM$3o$;Zfg<HxhX;A**nuP07hr`|R(khDZ4<7s_)zu6+09FA
z#&U^x?MZG1D&J$4eWLG)nxqNL>DZ%cZDZf3I-jZhF>-<3N#dvDjT{UX{)48^=D}nN
z)@`uaap_vd>c|zgpS3}Q-%z%1D6^Nnkx-yAX{-mO{qvrvLP>A%Y}~<VWyE at -DAg3?
z=fPvp{lagv!fPg`eO2}@t7Hcu8vGqY;d|d9S_Brk^V at 1RN(Zw`_QXg)HNvS`w2Rn(
z`hh|AzG2b;{{?+R|MRJFLHN>R63mdvuZj83V_`HITg${>4}U+9G2GXj2W~SbH@^!y
zZW4yR5;~nuoyJtbyeO4XbwX)pM=GZ$yleJhHsPMbX#(gy0+tR(Lh+_^=b^2t{x*>u
z#w+YQC_(`fAf^_h9PK2~@K+M*4 at J@>Gp?xU%+pOc7ds4k@~{ScXvd}Rr<PV>4OAY%
z3GldiG9#(FgQ<T at X{1p1rr3%UG&Id-QedqN4of;PhL2%rt+E{9m1~ZKX+`E_J?-R~
zi~k;R9Sz~Ac0})-&4(kUE1QB-LRE{^Zm}gP(EK)W+;oPp!rS2rk?BFg?YP@>L+vPq
z$437_|HEZ2%df}(I)=?tCj at ahLh*|BCAW%|k2JU9c+iG}r7Y=N6CSswRj-dj)<{NB
z;gGrfNz}%@%&GFLkDTi7GO8VcwoMLg8=Va<No5jjIh=wBJ^Ke3n$wXb-OJGD&xU?<
zH9gUUcnvV*v}*ZaEe)>h)i`GaGa66!#0-g?KLo$vXT#n;p?y%V(%U3+gk~hy*jF5%
z`0eoLW7m02h|LvTC$Gj`a~{ROGNd<kk9rtQ at KW0Q$*-c%{%SQB`mKC)?NTU%;o&#x
zc-@$=5~^LlwJcCh6_xI2G(Bx(gsIGU4afPv;kaWg*nh_yAOj(~`Y`{u!*g;6*XVoj
znleah?y`F)p<LVzsvGMWDw#Dy3$1<~TNyKkCfb?m!A*EH-b@)_gI+U>+xWL80r(Yp
z)j=ocL*K*D*b25}|LP~Xzp~G<XE at -s*ie;?VsEch519E1pGHvR8KK{RPBeF;U%DAA
z1Kna$W(3O;g*u|~`SH3jIs{$*s>~M_h%%0xsFp4(bG4P~-{|L|Ot2^m=Gr=s>@bFa
zSK|H+sK$XZmw&40QG#)aoPgcDwU1+;N`XWir+u{_DpO7(jj<mPz$kbmSmC!Dh?3U5
zkbf4y>uFB`{-^t9DwW&)RHfh7%-_{s+C_~A|3vTTVpo-!n+j at A+A1BM?1v}DneU&0
zlr}>Jh#Bz^w~Hy<I_A7RlJc_T-TpG;CnP2cp=p}P&@&s6 at 7)r1lttwWTXW|UP$ZPo
zwW4*b(~VS?NTljFi>cOn at l;xo4lFww=lDx6oox4P9}f)f`K-?gb)4){PucLZ={Y%U
zrQ1#+6G%$eu;BD8*tg^5sa2^tXd^~qOD&CoMNCa^o4A^^TBE~?N~a#j2Yt`Dp^2`$
z;yorgI1~gyj)&x(OPK|1AtpU&L#A=iHW_aFwnXI|nM`J(9rL6liIDfv{>9jP;9RS5
zi%t8T*g)6ilNEHV`eim~&cve_AsqB{KBZ)%cslZh<o~n)jOo|?DnVJ7$Y^1k61Rgm
z7Wk_xqC1Y%S*c&L?Zv;2CCCOP&ui|HZCQX8Lo@{XiwI>B|Ezcl?qO?P2#TU@`=)H`
z2Uk;8ch9Q)qXx(PA1&vptw#SMbtZUwPkBHxw at vBif$KV{*xw!%y*G+wBz_Kx5TK?}
z4cm!I-~X`XRj3@(o*{Fr6coK0!%?zwHi_fjxJS at 5ADC&a5|n}MD-OBopIETvn#7N_
zyXVX=Eaco!2SH#TmoaLropC4GzZg^EXg{UKFWqI6T5*%AoF}dL>@1Fh3?AuK&HzVE
zBOSuBGeM!2rKhg+V^~e(uwZ-)XpOa at W|O-wtn%i`R?AjMSlDkZB|G%qq`Ad}3+Lvo
z?8`x90#QOrCPhpHW||<@YLKBFc}UUR8RX;f9wk#C?wUtWRLSDbIkx!nW};9?3B|m^
ztK!Q+{T$U^eC=7^=ASMJtFp~>)QXjoa%&9AEFzdU9ZLK;4j`dvFJvTB7Gzpw4)kQm
zIvTvd7LOa7WrU%?>2eoazpt>3F$kE!Xp3SUXkyF8{?JLr)kNWGgP3!jbB<k)!%`Ie
zJ>A~KLzy(K5?sSJmYB_!u76{kr)2K;hRoIe6pnIR(B1<wE{Omq8h4c;DisBk%qRu@
zM!(qy#ykb*p#?cr;)P<`z>$m8e@)8{;MpUawq-`x%a7Gy*2nMHs99igOj?+q(pcae
z*Wab%pYegbQ<UCfqf=mYLjwXvyRWm=$w5fhcDr~aw^Uc*Z at kpwu({~n4 at MTa{R0t<
za<1*K%cgp2yC1 at 9Bxk#Z@^U!DT6rsjJ*uKZl_L`u(t;W~Mq_GHJb1)N*n^dDsq_?R
zmhR6Rv$oWdRiGM(F&s-P?MXEp at Kz-Jc{4PICA_WEsN~R at 1NKd}V93zenNvqxK8271
zNx7t}R5 at D{O?=J5tZY6YUS&rmYqllni+5vf&Az}{@oG at C8xqg(*Sz7axS=xogo#1b
z2{-{WBEOQ(XrXIWgK3Mt=^k7A*o@(ub7&879Nt5gLt!gr{rbZGiFiHISEpx3iDtUh
z_PfBp27S<baG!U#o1n>i>onPh7VT9a&gLr<XFVr>bPBe-75#BrbBJcTvV(sQW>}4X
z5B1*?j(zx;&b at cxar{+4bi6WCKqA-LF{5QbB9*pf(j>LG%+1}biI>#QDXT?Pf6rSp
zvPu;sm}7C{kfT0#Oj4sfl*~vW{`)yu@%(5{>N$7oB|Kl&;%sP#D9!&gi<+NOOgcm4
z?W7$)W=FY7>pI(q!rl91h8vmSiG!HU#dSQUK;q)t at g4R>w9UCuuTP2wETgvgYXW8o
zTUT_qa39_oZ3UxwiFRtdMG4l;k%h<2{ROa}yE%ZhR^xrv$=8T<!uo8VYK0c$?`d*#
zd2+`ySCnG$sx|Ae=1d^ZA$l<DK1!t^t{j{bIQ33b-d3pw9)OvDRsL=5)FJDi)bE3n
z52#l1v~DpZF+`Zb7Jg63Q{#8yBY8y2FkDD6U%2LAnb8vcJI8K8qP;&yg)y2Tyv8s?
zo(ZhUU%8W{ZiUZ5Y9wISKFC#kIe8&H6W6^$+vs<~S^e`o)kT=&`|+dwanB%QNB!AG
zo3&BReles)%&E%!P_4^^5LXs8g7GP$%@a9PjAc>+7k*N*WO&@iCzIi-u_bu;pApE&
zIAv_IbY{BL9K5kx-bffdJiHaFS`d;H_$4XXLU42kIdge?RBzgLBze`%^1CxO*v*E9
zVvhAWr)jJLJ>Hlxx&X!)rhO7*H-(1XjMgicsLlWE`c>%5xkv`vc=u=42j`O1n+oGE
zRys{NiIHTXmh{FZ*OE7~V>rZ(tn;6&KfW;LXKKqjF(W?Gf?2&1<T<DB&>M#dP$td1
zqU0D}_WnNe-oMpR71bcoXxH<z&ovxE8|txezYsC~YU(By6@!l&XEK2s2M?Wt5Arop
z?#h2afXl6zU}*57-J?`Kr%5|>9ey#^!vJZ`#PH^h9$}!j@)}+v(=Oc|cuOO0rOw1Q
zl8sIfO(c72ePUyw^&p0ZnybZffS$$zBMx at EfmP;lG~7$VeFr3s6lQKLU?^xt_1E1V
z7$SJgp&lo^Y=O#*=l-JD;}j+gkkw)i=asIhabmx?xWVTEa^lkGq8nxQu<hb^;pg(u
z at hir(9_Fej(}I9 at Y8n!p(VYpwX$i7I{~0Qt`2l(KYw at iT7Gzqp>u8wMEY8lHhhn7Z
z=fRr<#?kBE_3a`k6O?4rip7j>!#OdC{@QrNmJ3I6>$!BJ!-?|=JZ|f<V}2${BmJ8o
zWoN&9jDIg9Te{8oZjAQWtXxn6hfpEmnIGW{&E|8TO!-PoZ{%px=|M63^O^RKDaVGz
z>Ix+_d~j=0vl;kVHtfn%Y-AB1$A0H7_kapwRj?a3U^VDH(=)lXPX$r%g!DuaeCEBW
zp=oaPHrArPOgP65?Tt<;Siu;AcAVS{avcXZom~vrO0y6!Lj762eo)LXhz`IA`bgfJ
z&r4hvg97xV71g4Y{awL)7Yn`|bZF3O92GxR5dDD4Y7i?er?%41BSiQQ6`A(&dfD51
z&Yjc3;x|E;4vnlNaTI+1FW9voYJ_B<<5;H<D9fJ=0ZfJ$4G<sUcYYp7O#4(Dkk9aQ
zY(-r}ek26=3(V<hN1#pR{C%Xv{>`9TI+ae~{!6?9eMCVj_H#80Opc1eqSyv<58GU`
zkl at IG6$ut~h!2OEYa|EtISU)|O5}hDl{R6er`PLg5j2#vGe#>dH32+cH?$oKYzxOo
z8eT at 3cH49oH2nc1(SXE0h#S{>WD-XdgfrF%pI(IBPb^mbcLq}d2A9^Y1Bl5E9_r7g
z#dwJOvstK(G`6aQWKiU*D49EP*2XrR;rHAoB|u^DBfT;!9iK3 at 1BOCICE7iYV%#SB
z6N_bVPSU at e-mlC10LOANSkrr_fDnvd*<3~Gt?u}MNs_&eA_zsIjmdeVcJ!^(cakd@
zVo`$aPX8KG6W`S{cm?A->wbwC*6V?XU;$4U-8n;dw2DGVD`3H3J`7ue`IOGR2>6uG
z`*DX3p|TPll|UG<l)Fv0%^&fGp8EU1qR)@6sT4Uv_bG3k0mE|9h;1UK0DrEwp^O+Y
zvw);aES4i59`vAXF<djNtum^WSN&L6_p`94DICsbc4r=z#clEyo)0skAFI4s&BCL;
z3qlFD6PZ#n<mftv^Nm6`Z-^oNLK>)pR`S7XvrCL(Uv}88q`a7tg0wgSe(VJbx?2qw
z7}0O?vr?kV--#5~44_fwN_M}+u!LISpy3(JOYHrMzQA_VS?AB{TN^*eZglYui6~hx
z%dM;Qn>E1(o3O+Pmfpt2lq7%fuZ2!Zu(ZZ+1aZJpTq*jnDl3jwbhomuRy?CNY&}pc
zcm!V$L`g}yL}uwz*zH*Dhs7O at CLAdQqR<dXpS9bEqki`X5dnV_BpDyub>AKhX20&e
z6fN7ez*eg(y%Nt@#cLcGlMn3JNO@!a(B1u#q|c3sfmvk4aK6eBE5qzPC<BU*KCJfJ
zGQLOQZ_WsnKVU0?qB!TRstP(K&n<}MWw`a;*gc+3^6<21oZ{EsuMHLYdolCu8`W{r
z at l=f?(>y|Y%z8fz8Zus&4ZWvd*&LD=atPi)L^N}V<`UaDL0FP8Q-M1<1?ze at 5lE8`
ze$yFn$sg#eU3%Jd`h|dPzok;t!^pO(IcXzNtQ$hZf(?<)I+`YUh^O4~>Sz{Kc8l2h
z{_Mf!d}`%ZQH}d59qyq3?nz`cA#XFKmpbjQxOZk7YDO!E<L?cuo<QGYuDnq=n?@5g
z`ms;GVy%8QEj_uY*pA7B<A-T_Fj$O;k8fkRIbr)lZsNVS!qh;F<iJ5LHitN*9dYP=
zWVbkxw4ncurCUJRr=e`|V!?^`la(Lfn^@gXMM*ld>=ko_>ECB{5lI#LD-xSLwyq97
z*Xey6D0A5mwFDPMEun|W$}Lg&iZDfKvYQ!V78%cpbGB2ay76~98^4j)8_LIGaxXd8
zwW+4x4&mha-G3IuZhYEdpH33CzPMGE!N at USt2J14I>@BEUy2!26;R7`WdrA>D|VTZ
zx9*UW^U5%ar2k3kRzLQ>XXC_~8i(3q!Qis^yS`Kj&)L8!yRQ`kDVgaQ#)x`~w>$ZJ
z(<8p!43v$QloGzm^jXqDriu=h%w%L>C!+DO%y0M#d6BH$Go^_su at 5ILqbcU(M?fP1
z55z$A7&T7TOKw7P?EW4VY=rbvS0O*Vr^m5bLb~5czSooz4h at aQ%7^GhrsXP6pQvDf
z3_&vO&C7=X`s{4AhktoY at hAuH{QaDmRPn0pDGTVaiy884a;=&u%sx-`Ku28E_Gb$S
z4UMgEACnolf*hvl)d|*tLXx2V`{<z2AT>EP_h^rxk7Q#7_+<k`ZXHq+S9n+J(^;#!
zY?_e=*+91pdOK~!;r?L%-23xq$hGa)v+S;%_J$&1gbajHPu#RoT~@-`wKW<>Dy{FX
zc^JJwbkq^6B&<Y!Y!Vd}C9wL^g+1k~(~TPg#g688h)!l at X^YGI>F(coNeLqwa`}rL
zmV31Z#2syIB%qH8%ke9dDn5UnhUOYW-q$@Lb9MRVva&KbN9!0rz$L>C*bNQs at 9KmT
z3g1)Bu#i)*@ql~GX?$)od1rDwX-h#fs&G&-?>i7wstYyP$1F*REnHx#aPD}{u$?t4
zvD>)HH)n76W|fab#)c<Pqr9g_l2ri at TcU}`NwiFQ1tEU)BCk53xR at Hi@?eIm=u2Zn
zM8q9ZQqu6_I|o-+qBnd`fD6w*10_B at f>Hx^D=?(f7vm-dc;R at Q@9BQbd0LGOtZA%W
z(NF~uwx`8CH=n9i;pcD~<10|<sL4p$7fra!c;*q#$WIsV)c~6oxIZPZE+8t9L_<ZT
z{XqiRR(#3X{ssR`5Kaj<LyGvguIM~uf{*K^CiC)j<f)`lqgleQF24$Jvw-OV!o+}#
zb1(Pbn9WV}7&&8W%CxSj9k0EkBVq~@ng4&3+FkdiWpfx=dw6_!XF_=_ppP-(WjB!E
z-o0&aX-PxOV?l{27Y#v0O~&~s%}ioromyYQU?r39Upz#KHYF at 3v~a-pN4DN}g at r>~
zL*~zWpePHLN>iZM{f^Md%`b0ARSxD7k7O;L*KmJ=`***qPYVzK@<)Pk2$CRXGUm;=
ztGaG;Bx`XLR89EWqAuH~(_|!&e>|C12!q04?!8{iZvHstH)zd#S}R^{GJQ7I_Kq_0
z)Bhc~xTLGOub3N3;12mtsE9m4Qg13_-;k~<n7y=;(<KCLh`<l5xi```gA75og{r=0
znncu{o0;~1hmMwwe}82jb`_S$V{z?E)E!nGid2t^sXS7SrczU`Cj at Ux*0D4>gg!JS
zOr2n<Vx$mD9H(=rq=bLjj?Bl#e5gSHTMIICF%6%xcMz8$`rnPm;<V%3tC96)&&G?1
zw;GQdSao$z4%XLcQ)#3vzK;iYLMaUm=a!ZdcP4Xlh2Bu6`TzV(B}gjewT%kgd0P8O
zdY=LDa1NJgY)%d_-bG9Jj?jB$Cu9L8{y~XIeH0z*KNtK=Pa<L(HPDa^WM1xKp|;>b
z?pY}l1ucoh8rx5CYj21x6pFFy9|E_>@F*o-V}dSNIS6$L->W##de`O011P&#VDa?y
z3{rdwL^MELP#myJ_Rh2o8z}1wGW_IT{WF4kl_nXhSs+~2(4dZ+kBn((SmtQ*E90eY
zh~3yPl;rk at S~lhmjsJZNPDX;`Ix4QXDtU$b_lbGT{FU0XY4!Dh>r5<vx^2h(hWz0H
zfNRWe`aw6Y=YCc0%pNHOD$j`DKaxW65zL3Cg!tovF~IeESd}!(pFg^<Nfm}Y+&DNn
z<<H%CnUkpJax1E<WBj{t1NImdM*62Ch%vUt5q{Oh#ZI=|Bp|KxV at ET&?Q at F8;@LOb
z_hbA at o|15+PGMheUpl>t8eww$sh-T9p%?l-9OCHFe6tgm84lK<i$1IUL3{kriyY)p
zPeifz2jYO2tFQOAC at b0fL(2oYWo;E>=`&CTH8~iBys4TwU;UG{9e1DE`Gnl|;*5F%
z2O!SLfpW#9lRqs`YcM8wOW6G~ga+78froG0#!Kl6Kc+ofjS2L)R97<t=aH9SuG at e|
zFM_N^UfozfKNOQM2%OoAVbW_h%8vdZgHd(Nra6A(Rs23X<#Eg-Q0;b at QFmI=;(gob
zlp_CVR#)lMtD_)Dtf-;CalO;$M~QMHhc<45*~ysux43w@)kOh|s+n=HVBpI?=20SE
zks&=izY%o7u$pk2%=4*8t>1n^YX-{7N#v#ctrN4p%^s>z*)pBztw5dZj6p%W<QH-y
z6b-Nda2XyUv_;9X`mO7~(3AVXT&;4Ztho*$Y3o$xRqqxyWzEb=er?cG0K5)>Pyjz6
ziwqkkFosldAPydPncu+Y5wKH&no(Ay5p8zD1o`8av}AvQN!dTEkRwxi;C&4wgoD6m
z?Ci$VmNRA2vrs0Xu<oz?)3s*c$%9Oor1;}A)n3si<b}TnB}@7fLZ;^}bP*47h&h?x
z;!$Vm8<fT{OMXOwc`YFKI)3Q at M@-Egbnp8swsQN$qCK6wGa)YRaLDiB2BZCWo%fnI
zN_4)s=A<g at +6W@%!T?dsaeZ|%D{y`2PW`2nL)*~?{QPq5&Gok?8o3c8r_P+i08#i@
z+R2>uN;pF%deun8kK(inzfdfi$2e2o(%M%?hn?K9adCWK{ZMfpH<j+s?4?q)&8~2+
z=dZ$&Ud6zhOxg3sc2G{fXqF73JUno;-`%{c71yh><|fpUwRuXsYqE*<9q0=(8R?3&
zP<mE~mpWk?NEs?mH8nNC%8zu+XNYZ|!+p~s%Cbe|i&}!TqAo%uox1f at fe)}iiUt}6
z{^j#Q`9~i!YZ?vM=}Mp#2JC1XpTcEVO){Tk1wF?w2<58}l?~IoeqP1c?8zwlE>q09
z<0^zuz3NL##Q}MKSMC>ea^7kDU}zLX?X8V5_L1YVuo*O}v2ON4rBpPi7$wQ<E2*dY
z{;k6&?6oM{Y#mm at jLAA%?qJo-Qsp;$7M-M?zF$uV^G))qV^%&=U4J`7`LMUrk{-{I
zZb;O4(BJIR-iV~At8{x<%g!slLC7z220X<yCgm<q7TW*924CD{a)}P7(>1VvsYNzs
zgh1mMH)0SmdQsL|blHtrx7Ei2nZ_o at 1SXpCyI<1hW-SaQ30$WpSSO4*oV+~=3A1tI
zm-OF+iEOM+d6}KExXU-_4b9PE<On<<a^x#+``u&vQKr+eF^Lwp(sCw(IE{G0-d1Ur
zqs9b!$p9iO=R;;=tRzStb9 at J^fiMZ(%@^%^;;Jpm1&ZvMS!flUuKzkowm9FoNDhl!
z`wv>=1&(m=wp{_pUlu&xsG5>@mODvtsK~<?|Bt4#4#)d_-?$pn-8tReIo-`P)7>^q
zcXxM9H=CMn(+m^SIm4ry-~IU>$IpKp4xZ=z+<9H+`8t0#8GhHX+NGpY_;w&Ty6;B6
z3-4;N<UU%aGSG4QRzE#2+C~xQ-VjeV-<x3h5Nj~k_ at 5YWtk*GC?w1w8!)3qUFaO9=
zzw$5Ux8ojXv<zGt?q0k}b at SuzwB|#*MuE)^s?#ptx%&PG0)5vFC*+B;dKv&X!pXV<
z{_tf>F3i}a8U!V`=>_MT4OZt2^~yc;zdt^2yHf|KdLD6ah+S*e+uk_J<KE1?`?uDP
z4l6+1xH!abeypdPtCcjluRcmPv at UikG3|obL?->X&7-?mX?hz(Hkuq2;eV<4Z!U%Z
zdCk4CNkm=7iZkmSiPt{jU8U3AGFk4ZppAhKYqqSs>i!_>zvUN_ru?A2<LQ3A<BrYW
zXq?N!H4~Ws)*JEZIB5uuoE+9VaGA2Hpo9AOy(MYJWj-IAxo&Ks8D4Jn^bYfSUu~*w
z`LM33<!1edNKkZnC>UWo`!}@6XBg?%`Ul~iv08H?J_d%aZUk3Y`h7PzU%ZQ);Ex;u
zATRR&XlBwd``B6UO8uIwFS3#rT29^rnY`m%K8LBQ0!zB%sW=f^k5%WHUR_8~pSV|k
z41f|4RPi3&9+GXHM_;;a1*2SjTQAp|R7(CDNO+EX)M0Esgi8*LBlp2!BDZVNCja7g
zF8K1^Oi!6Uo;imE_!F}l77Qni_{W)$It_Kil^3$uZ7rKTqkldX#q~$DIdPCaoiT4a
zJ1_Bim0gcVo0K-aqbGYkQFT3VBDZ!DL1nPUNDzTAr`P?3_kEw%>~(izQe-~KVAJGt
zeoX!+LGmKve35JQBRW~{v~w4N^KTd07CXVtS?fegLQJY?U2d2=PW_IKS!M<o2ZWnV
za at W;>SFEnePrtuaA^MPaqN0m@!U(v at aF$pj>TOx|5A=x;a=qEtR-1VD&)1h&qdtHJ
zD;&O8TG5kFzfhd~Iv1k<7;kR2A=$dK9^}+{SbAXQD2r7^-4}r}BoZz3a=T<>&_Obl
zB<p$$t4eVhq`H~=?T!7R_u9*Ifmu&Cl7WijKoOmP)FatyT+dyv&`gxNsuD%!&#;mm
zi^hY-yvWb_36h?E_&qE02rOMB^}dt#4WAqzGjHv(X`}C<h5cTiAuWcn_-sGTGWah1
z{URZi`pnv9bwu`vhLM+)5_kv0`jqG$mU<1$$di+k;@EaUKO=|Cz<0|Iyrc7_717Ib
zN_Ix>3;D2YIMM8`+k=QWNYVr{a4{V}FcauDl?ov`*fJkZ_^bYi)t&A9b|xF#?0Lp;
z8VkOp!#A6as0(Hs(>|L$zfyR2hKCnvomi9W#=~`*=W2vMWX92utJR7qQ;W37e)IIe
zyVg-n8gQNDxs{rlfIZ at th>JT{u^_E&A*GWW&a`p!fjW;l{|wIQ>BY(Lehhu5bX at aL
zs12!g?G9G>3wKNme)ZwTEjO9h&;C`hXATEPuFd%Pp(bXM4C-D+iu35!O_6%T5Qj4I
zKQ95>Bc4x~0ZsRoiC;0d4ux0&HK9fwk045_P$s9r!<J8LXqb at ApW%Z%?Ux9ZkB^gL
zBdkZvzW=&(3dcA(zImhiU)ScioSCx??GeK_oZS1 at ++X(eSst4Q7E7pWr7|PW(vT*S
zO at 17|XY13LmY5~MoV)6;&<~+iv{}9~Gdy3>c~|5$ijTza3k9haPB%G!-Kx at NRJqDS
z+)*^?|KoWww9nUKdO+GU*wQcP`>#Z&WRfFkxdW}|b)WCNTF4~ap6xFh at E!gb-D`$C
zCAkReslW4nb7du*J1QD&G+EzUZSqL@?_od{@+Swru;)yKzw0tAIg;uPvD+x=M$kw?
zDWpTE0G{D867us`krHAMb7X99zn-G-#0YzAM{O+fN#4-TIfbW$_5y{lUtPUGU8?Gp
zz-mj<m<43*Qpn|YKy|zK96FU5p^DPn)rZU2|Ax@(eAyZp5K;+c25z$=Nq$KzR^9tn
zYDt{pqf at jviY0f$+|!{;bUa|)<xOh;iFkcmKhYn4+!0ihYUyp4PpGd2wrt?8Vn<0;
zD5WSb=@_CFPgfRxZYFkVXoDwzDo6ilo`OEloUm~PE!Pw+eKJ0amtkr}Ewxi?W31Kx
zGyT`wWsYsRVaqEk7P-XP4Ih;K=w=uFW at z-cj!@)vYvIjHEeTJGi?jLhk}LBGFuSv(
zOo(;I9~-R2Zb*oNtE%Ow1sl93vE)+cw-dCWFBRz^zo4<BQ2!9DU6aHcuo_NF`jkgY
zj-W~SEW<k(uf_`b`@(kj+<N4;*b#nUHVLwjV50h5cU+Wt)K~W>!t^oFl)BODx+-Zy
z5&pyHPw%SaAt8UASPdO{j5`+t?e!oF-03Z&USHbC<EwWP5H96vbc5GU4`!U(U7$Uf
zqqcj4jOag($>pO!{mATFC!Kz$>4q_j`i(_DsDf59DR4Jg^E}<N6H^fvVf at G3sQ+H|
z at 9s;eMbA8><y#rV;yANz^3~IB<l3A%i5RDM=F5<+zD5?WI^_3n$)Ta4gCK+oeii^?
zBvq!MHq;F8vRc2hj}@Fs|C*+Wme3<bmtr}!?eRXH_Bld~XXK#d`;+pag)b(^9NG at v
zJuT-LN5mbg=A}|7E$P0KhtRwytX-sAWnIA(H`LgCq}rV~XQ6yTA{$dM$9<F<RatE@
zC6Lj6mxY~7_;*SXpAt(lmO(ccn^{mE21hSE$xgQadd3IBo_lQsk-R6sl5sPnmM2r+
z_9MrF(o2VmVsQwN641eY(|snP;pdf)?Ce2enIrxoaC76z51p+I+qdEi+{)%V;VwUN
zYGs%PxO$^jP6{C^YQ<n$STbteuIa7wkvNJ1DZAxhuB8^qBn_|YA7X*h2_jK>kLX*c
z1%DzO%vkE4=36Nzjf0DA<m?Fl`Q8v(7@^l;54AhSH0UDu%7+UJ?sKM>+a>xE-5mP)
zy-$Ne=UjUs^?Ev&q%yzolRKZ}w;nR1e?jgtH_MK*zJ11gd{BV+;WAAteLNoK{YDp<
zxfrVj$9_r6Y#?sX8b5GPX*do0l;p`)EqL{Br|tL%C7n=p^QI)BpBEwN_QGpBzTkbl
zNt8~l6IqHi6{O!73+&Kdg}w-6dlYJU6R}d1Kw!||C}i_nWW&wc>uuA4H-NhK7g3Eg
ze!f=l`1}nv8D_O<W-(cYG3$M!mW1jCg at s=Kyife5`>QM0%l6Nu&261rlMkEaSnn!7
zz0e_-a5*B6ocW_nol at EOPsU)H%pppr7rhTge+`q6?vBWJoF16Ym}&epkSUXi9oCD;
zy!K2UGX#8P<Hdb{DY at cz{=2E{0Vqx-ul4Y)FuyU50qYMu{F6sQr>8~F&F2M^&7o=;
ze?hAM*8=EEAZOrw!sC;F-FdXUCxa?Hf?pBBlk9k9_;)CPU(Q|W;)^&Y<-r^T4KVWr
z<V5#fViM_si$<}Yb#BnMp-S!fG3HG$W6f&J`&%*=1eMad^Z#}-U6ELO{tl at rA=jM^
zuop+#a5fDP(ktNDPx*4B*S5N>LoVC)K(1tjXE${HEKYB;8a>`tg=p$8Td(o&$H9;H
zP!C^_O9pB&`2PAp0|z%gk&8^WU}J}NAGsnEWTl!l)Je}pm^>*m$V+SFV+)3GGs#JB
z^*V&N?Zw7iNiXQ6L-*4@*3*6;)$afcf<JE1-5DdBt_UXv*z~x_4a)enM+B5r!B at pB
zUh at k^E|!QbClvF}<_Y!1m5!JzSmBYjwOdd^%OCodRlfaK#If5Y$*b|+-piB^!scxH
za at axU)lzXb=#bqrmil~tA<F125)E=O?w(lJ{BJ|NzAU}-J at 2^Pa&&IP$tsRZQ~cpN
zTxk!|^hidAwsyMi)>Zw(4nCjA(wg+gz1|XkYyG}i6L%~do0!SpT9=Ifb!Db)b0s;{
zNbH5QQ+53<i-E)`9eVHMn029=w4R)cA9{A3*{$kX;N|Qq90|fca6Ir7_^|md5ql~v
zOyu-FEv7`;S5)a6%r+`mgnO=ky|B6Rta9Q#hlirXBt`P2Pok~qIW%fpd<<wi`XMIu
z_j$?8TPmUos*d`dnN%SI72;WMWQ+jTYzR98xCz-aYDtGP$b)ph>S=!B9P&TmXTCc=
zUVCqHW-Bcl9|NOxx{o9XFuRzKl+?AQxCybS>7!#K>%`M#3sf}<D;$cc->?|v$r0Rc
z-Sz~)y{zzhFzZDjZ at dT!pAWqbEIAzx+?TTjn_14f at 3LzUzreBSwP0_&Oi>-Ke<M>g
zD5gIRfI>*csncBwy7A>R`-^?|d`1 at 3)qxw6&L%7PAwQwmmWbPOPzX0xPaR`c3+{T6
z8Zjvn&4}#&M;Z5)rL#W^+4B?ndFd-b|C^i)anH*`u_lD|IlgTkHd{%l6u=Q~Do*t&
zwIEcS`hjFE>>}d-6hgj3W9?Dm{7CwnOb9oi*_4O6C$a=R0QR-53!D7 at SZri&|C86f
zbh&skb!K`<5EX~;<qSveLosqgyAaxv>kw<MbbsJ$SGGphlRNTI${_k>)PAG^!~Gg_
zsCN}_pTL at hb5U*S`F^CEm04q^+(SJk4wLGGOjlHIv*mPXn)~0?*4JL>r~Q0{^9Z`n
z6ei3-mh7<6h;aOYWyGZCIT{m|<%g4w4>E7PNyu@}rC8hTtRun1?s<vHIv8#EB at 9^=
za#nw7U~qfb<bPlP=Dj2T0j*4faH4=SMfD>n7}bP`0g>B|B^+E#Yi}t86J?vRf-d$<
zK2HCY)_tC0+SI!tXrhjcfnra7%pbET1ck97F&KIAXN6JZ9e$Oph_YzMKo57O4>fvW
z9$F!FNBo!DVgm);%wa+SuQ-WzeRFBmvq>t23`tVA7d*Oi%Wz|tMYe+aD?b{(44FwS
zV20zVmNi)H*)cm29r2XVWbFLCeMVjX?8JoT;6rdL(v5F-YxWhD^eCOTMz<M@!F*8R
zqZG<FR{eO*51xH$T3-!>8thIKsI>_F>En#j0|zhM&*Pa)!baC4AkC|1z0C*+7zVBk
zqW1}BeT3)!!uOD8uYXz3kQKg<^OY=e-|7Ywc|G6#II|UYIeYfvZN&iyhVt_&>GvLc
zZ|=sKOwa-j{Mt^eJxxc>ef8Qc^wMX4rS@;*+RrRtA#lV;)|Gs>M_kNrf=g0QP!P_4
zKN9_2x4n&!GjOyxW2a-<AL_t!7xIhhb|>lNN0PICLap^@3OtUP4jbGL_5T1OM1C=Y
zhGM-FMkiob^7mYBU&}~- at B8C>uUC^-+{IR=NSTsD-A*L?3^oa^l%LFT(ai7utVAu?
z>rj$vZnfuQh&Ic47mEQEJD{CSIt_ at mI3g63oN1I)-QTGkwI34R3oCQWrr!1*RHiqT
zUiz^p^U5M?i>gU8V%q5oMN-U at Ol2Gtk*_vEN(x?J3LY*z&*#O2qa-Tfq}2=Uh{%?2
z{vkg)UESY%0<3^feK(1bV=Yvm_2-iTuypOvzVHQ4s0~iIh{kMNcSl%ENtKg`Q(IGg
znxsk8Pl24^$7UxVNVXV#Gj<czr^dCdh?Fg{dHz>>xcVKPfTlWanDHit-D1$Jv5-_r
z<XETUen01VoUKQ=f=uF+Ec&rD?rP0_dh2RlwLooDE*V8x6M8yqFE-T8HX9x>@R%Re
zU6RlGJ{yi^!@m)A at UhrTu6eJC>s1H4M7%83Q3l<Oym~H!--)8V^XJ5mKOUJpuq^&c
zu~Ak8zNtzwP4 at IyJh+SzVua9QVEcrHqa1?u3!8wjgqle$&5e?eQ#5oKnpY*&WZc~}
zLH&iMq640g%;7PtZX~%_T$8#j9=k08*9d(w1xcAyh<4;U*!r`B5WSelzP#*#071(^
zKOt#BP3)KH-_Isqtw`L;ga_Vm{SmsnIiQqlV{4nmJCx!%vDXFPpDrlM${<z4pcC&e
z`<jmkKpS)gzF44)T~)o~%o9yhkYR`R(hw0ejh?VoQ0e8bJm27cpu%j@?W at 0zY{Hec
zUp=Q^wHvneEN+v_m30ZMF=*tXv6kcMdECoV%A5!Y2(yce;Wpfip{8+XE*sr`ASP(c
z0;^Hi;lnQJQAhmAYODD`I4bUSL14{qs{Dxm=uY(k&&ROEsumlcNQJ+flau*w>#beS
z?9iuAd<@_&Pre%#^CuYdswu|z7?dOKL-)UMUxUmGsWal7uiLLjGO_x5H+U+Rg1!|B
z;HZK^n#;f69G!bC&J0|<GhSo#v#YDf^W2U8&kw!)eS3j5mA}0ojS^okHfEie<Zwtw
z>xJ+iZbjpv%R|=_{9*H2MPXpEo<1oSy_{_foHz|P20Zbm``>#u at DREf?uy>&e-(XH
zDYSUwZ3%p~0|Nu#%ry*Hro2vTk>D{*+V5od>RNDS6~=afupmcbU~r*NQ%LdW!-^_w
zZpLo?^Vz`L*2?X2&TRX8!F?I22|+u%a>gqH^StlYhLY*I61EB<zRSmsJ)@7xFMno_
z4Xi9nM^G3f>m2)89=o`b2*S+M60Ef(K6ci}@u5Mb)#G*)kbdEXf{-Fx9mY&$dN*;b
z*A7e at o=@TK3*2>^$3J#<pY?K+HeUYaFC_M^ZD=B-<@%N|#@>gk=#MIxdenf*baHi{
zr6xn{?Q#yA<73`W1}mQ&EKrQqutiB{s``e`hZ?_JsMAjHVInkVSNo!B#u`T&(Vu^-
z_Loh<zEEep6(`(@#Q|Q}ZN~eP!H#659F`qoHgCUT>L>i&reH2rgOJJNrT#|cr)~6v
z_i4Dl0n4s2^bZ1>`FQvz^HYwdbYJizE)}DYvJH{9BTbN}{17VBdtBhrE6B3D2#792
zye}e+><~3e3|yqGSTf>~&|t=ocZ^F{Nrv|P8kuOVcjz^p!|t(!Hdr9|mY(y<ryye2
zJ1FUsa69dT9m|BD>cJZ^YddMeEQT}%aoB30Me!9CTcI(o{BhF^S{1)~yI8go$sPi<
zwL=P`-b)1Ic&+O&`kpk5ShXZ~DnwJi7Hw#HnpREmFO!6cy!&e7stS*|@pr)0dPINw
z65Ci2r&U<J09~GO`gZ4R>y6?!;u<PJu`+X($(9hk+?2Q!<jYcFuIavUD=vQDD}LW;
zS$hK{{9JchfB%tZFRKybT<?_?4tEe2MCRl6U#P%}L5}Q&%{x>6oa#)Uxk#)@=qv`j
ztuuk>%=-7P&;ie!Z7~L0?W|hLvcA%M6wU}r2yQw=8iLS-SZkR<YkEwWt1aYBHSbyU
zAx8DZ;!d5ntPPMGKhXkNX1wZSqM&_A1d(UkY+BGja9r)5qo#04M*pmV(hj5Gla at W9
zyaz>b?30NCX((E*(sEHnYW+8N2gKn&Nn8_fbrx;ot(v!SZ*;@P@{8#$$1<*`uqXL?
z at So*(bq7b0C%zV$^Cqrx*0WRd*C9_|7BL{LyAGA!rNprH_Rg>yPFMf#bDS>Pxw|)N
zH66FDR^wK_gW7I9v~lhn#>|4;l7gs7hW7)9_jAdi_0^#LkzG at G8KN^Vj|IAkg`H<^
z{OY9LmIEnJ%>wYUX+^M!7FpWWxNo4~hX0Zap9d)96E>YDCrj<oFnG$m2OT_g at w&qK
zjj<mXEs=aM!cWl=ei*a1sg_-sOK%PC+hpITTS`$TaY8ST!lw8T--(our|>LzZ|{cr
zWH5T061ArvDj`m5QZ4m4X!Z|z3w+9A-`G!P`u9aj)?E`TnsR6K+!zOmhI^>QCR!HO
z4C}*{ib*Sc&)oo3+wrV*p)I2YRCXCf3ZaZ(TJS+pk!c0>F>qKfrUt^;QYSm`qxV?!
zFUfw{mG6MLcHTgd<8&Aav(~4I;}Jo(dSxeB3ahK2Vt_AVbi_`|tR&Ea+o!EK)a{B-
zX%gis)u?1XDo7=8QpZMCdS7 at 0TSHbF`Lok)kBcY{KKj7pOj>Y4u6MMCXi_UJ)=p4G
z=hAQ8HBb0MN1f!-bvV-jHYV}kk)g9?`hMPp?}Li)m!7r+GJ32FN;NcOUlvEbw?nTj
z0FzAe7S4|9Pcx6RSyOJ-`7qIxv?dNN6W;e7^wpQQ8`rK&0|`49I^8&nHqb#xo-#g)
zNVP{e7t;2>-oD$}qAM84_d_`UdD*ggUGMKb1gTZnsV*}?dzM0hUHmHzIrGJXSjtV4
z2D*PmcXK-$Juo6SZWMl9ayP<>;B+D1;7Fd?xqr_LvvDcoFLCd^<wx1cgY3NFE?`{0
zhN5I)aa8Jp5?xxr+->;&ec?F*EnCSyZ?gX>y))SpOa;?EsaRM^+}Fz7seA9SFYicM
zmGussTMdx7?j`O=`P@{X>??)%JeN^9+p!XJg#I%i$lLPU7}<|2FJeiPkkWA-pFSHt
z?Rp$pYW6LxrHLCNt!2XqpM^9j6@}Ue$N%Qmp5o#rJryW_uc7rG=IVtc-fydCGgV2h
zNlS0PcjV>l6>FC6Mp9GjE(|L*rWK}&^WdhbcOpnOTsdkY(d~WAXj9GRYgvgyRbb$I
zOB(vz`NCsClmY%qbL0#MQ9V<r+)+pagI+pjoD3aHAUn4E;Eum_NJgMe1Sg95Vl7Qk
z+uI2pJ>#R1OW_*B7MvUvJ$Q1ga5p{QlSi?k`DqdKW-SuLjefar6aO{H3;3Z2*c+_w
zDckZRl5I_aWueY{pxSjFUn~l2paKf%JT&I>Uf#_4mQ)W-TuB05#L*{x at fErc<JK-u
zXWelxA+o09fpm%x>fQ?xlxy^l(|pchH+!oyI8hRfB!wcV_f^Q7%TsNo=V2(izc<^{
zt_9VGcPHeMaY7vv!`yj)eZj}bJc}ULnLC=6qvou>F`<#*O6igc#K(GOa8S_J2J=u4
z+j{a~$HMEo0K@(;{Q!ILTKRHIy3Lwq78|BG`zt&7x@{?jpR(rp;!+pV^r=9s5^KUA
zg!pYmz8AKZ8j}znMIp>Mn^9aP;VyTvhi31mKR at dG1g!Jpe~|mZ<L3q7O^MlKuVibM
zJX=mA`KH1rhA2o;5yqK9kk6z}w~sMCeY(R$1^a(&KHY8MD{i^udK*k~Ro}WN&MB#?
z#Bw)zZG0%Le3-?4;q#@*fYAzCy;@E7U}SDq*!Phrclv0o+~ZFvgiTP`l9XnW2t}h=
zm>3mjA1iK}JB2}Qrdj3QVYf)rc}l4*lpCydJO>X?N|r3z3Rej-CCwkiH@|u at YX4IC
zT+?;PHGk)wYcIf+_V!EL2=4Q1 at ziI-*QncVqk;!Y;pqXjmPjG8_4prTNl*pd$1qK?
z2L7&m>-Xv7ko$yJToe(QjoV<_yl)31KXknQEeOl%(I}70%rh`;uHUsb)U}gkf2E*g
zI9!`g*y{46Ku1Rtwt-+?T5u~eZYLwrI7>Va@<28&+;s0HhSs&xPU&u@`&ZABsR85}
zoSiwO&8m3gU9Gg}aW?r?3b`S07UE`baAnS15x6sQ)NUFV<|^UE#^WUC?a9;(6r9aQ
zYSTDgu!{PMQWjQ^BvD*4A1O;ld_xW%ZRF|BO_l<%4xEh9jdY;p8XWM;90xudzW;y`
zC$se+Dr^#5R|V-zDNMK*{iWj&?mG~%`H2S><lwv!6h at 8lBUKbOzmk>x38N($@zClV
zeC4Ur=i$)U`i2&OK|$+E+%>a9gv(;fgM{wTNF5lZRH2}Q2>EN;FXR{6RIE;AS<Dao
zbjl2hwuW(~)vZL5wkmYqFEyu+Dys@`x{LeI>+4snzsh7#*6pvMO<!uA{u#BOl)V?t
zZw2sVf{ys(^=ICHqAobAFKxskey|Os2$)8ao(4=)YYliz86JI~4BK`_6BX9uE8{&U
zgs%PM>V*(4!uKGr2V|Qq5rHDIMLAP)&Lq<C9R?I8-`-rTvWEJ+*fuE8uBpQc)W$@0
za>5|vmufIXqUC5zfz-{Qm<Sw34I(ddo<;~99FfnAYXU3}TQ1XEPp<;jdkm*tdGNC3
z)%W6*%S)1VyjYGpM31|C(iZ2ukS+{q=&_&c=B)o7X>u=L-))R2;vC%8?!Ro=ha&3L
zqC#kiAAR49eNR*DXfSid7v6yNg~BR~#lvZ2{y{s(jmyaea5aA9{<EPyUr}Eo>H;s)
zkqgNP109yBcC>K|s|imp&{9!wS&><)J^a?8I<N at wI`;dak3_GmMc$4owZ-uBXzU=I
z|CfMhW%T|d7Vx2KSAWnhol&zPB*dgl8qLMtj^9b;k*&F&$^GZERaT at GXU{r`jmucr
zvs7%Tl~O-iy_saGIR8zcH9fLM<$L|q7`KX&jPCt`*9(3Ixz>4{&Pa9mVMM+3MtQSv
z4dlZE^B>P*pUZ~d3O;S=_HlfC+*2vaHdT{6h-WAIKh_c|iH=MDDl}~k_oZBCAtwAt
z|7+I0(+j)lQTp+7DWe}0y&!hok_*)a<hRt+L_hSIJz>ny$L#%Iqd;0AE?_0C4k+Vl
zdf at l~GSlLS`H)(eDcBLI<t11%s`a3=6-_m_4ocaJDs|sft2>Pza^fG1e)`k#R++_J
zYAG+~Yi7P>cZOrxEjI{|bKo^tyw*>q25s}3o14OeRWGSPY|43V4t92oE9`Bc>un^M
zJK~0dD?m=cxcCV!Y#xH7IOOlla6ia^m_|!I5K9o at xQbg3QklW;ZJ&D)_GQI#PkdT7
zIU-dqZT99l9&^p*m<+KeJyVKXxRi;;hq&lMi`zsx|6)Rh0Sr4dZe?UVLOp$|B)N~I
zm|;+Ga8*JSRZ%(z=?r$dLK$J00jDw_AlsMRI&SZWVaMiVBGg^%%gb!tlOgBUMTsHz
z3RZ?oLqL55 at LQ@{hSM2_Ziv8-1^IC<!6wJ?59pnqZ#PUnY(@L`07#d^?*?cnm!~_|
zHNV?GJ3onxmKr}De*khnf{wa`qdcj_fDu<0psrdAczxdKrULN;H_O)M%T1Qr<3sIA
zAN!|eC+(EyQRMbLYG^iYO;>q=7)GH~V at A%ascXQJhpr;sQaPti*1kuJu}F)tk9)F1
z at f>M_O)VkoOLbOSnpN2h=R7y;-eAj#fISBuM&=|Es^`J9CFMXt`RqEOsOm2f|GH^x
z9W-L)hfzvV^2Iri#O~z_hxnbs_IAQ>Q#ee_C+77=a|B+;6*#^0kf#R73Z0p$9$q}D
z5d4ViaN--~`I&`<FdzfcOE=Y94E+k|btEERaE?5_pd=NY3&n$MgGQg*Qx0zxQ_E#;
zWdOp|OFxbdD`47<*iY>=m7-Sy?{3(GoBY6HxTz*^Lg|-$-Z~RohxlL&cJUE4SD9 at w
zVAl**uCPl5-6JMbQ5Tf$X3cV=0)`sV3AN%WnbFd?p;$i`6@}WWI9JkzJQDr1PR=+?
z6b at b$hy-0z;#S>)&+0y#9wSMN8dYK$f}+(|Tw{`yvJ$PK0XHBXt#OjPf4Nz9H==s)
za<a2sfCiOA{$V76eB@$pd?fUXE0z+H4Qs{#h~^yD<rbNil$Dj;>?$%w!=5ZZdjyO)
zknqV4#uUn1>VnA8tE;O`kO+p&NcL3~Xu-gX>r77R>RC?Z;#wyAx-r|#!^iiZ^h>wN
z0uiK8{Et6RvcqG)n`y(Mn~p2B{O#K}C3^SD#Gj4kBf#$p9yR#Hf!VDPL1m<ymMzh7
zHE4v9EFs|tpVnhCtb|TI(!NLy_>MKvxk}1-lBq!u72Jo#`$8MUw-X<VxiT14ly8*2
zswpoZ5wdRSF?<fF3wE<6`lFUo(|-vq{NyGY&Nto!G<maYYq8zk-5k at _dUy{H4}fV=
zXuCq-OpK07^uHVb41r=N^SF(Z6Dw8d!oP8#%KTqI=~$tX at QLgN+{y38lB$DUzrXv<
zXnpegE8p$U at BVA@S?S>cxhSEy&DVqM8{`bw_??gA=`7eEkYNL*C_ye*W5BCF0GI%M
zR%l>SxwD`f#lZR_nDRB+rrai86m{Zmb*JoHNOX$SSV7le$*v$Xf;XL&q5(r51^@5Y
zifR1B;;Cv4<-M7l1oy$(wzy0x4J*bl%E?a>k`b$hD15}uot-~*fZ`8m?-WYsGOfu8
z2;N&;(}7huQ<$ET76%XS<|ojsdI^(JUo6cXjNbbFH+%t;9Aq72m%XtVb|v{wY-eLr
zL93x36X93~@(#8qxTXie3c$h5jpJp>pOjmN!3yTV>}=3NwN6QOwY>zT{JYBX{4b3E
z5xt)uZ>fMhjeC*<KJ<v7o?0Fx%<6V{Fnp*tCf#+2q3uA{;iDAbDlN+ro={4rCJ4t&
zeZTO@&zLkB2Bz8aa*8fNQkS0RLjO|vg`3mYs at wanf0}0lhgg3)yX+la42YGCdk5kg
zsd6TZb(ty25<squ4eO|)SvD=GRS8=K$R&pYFI6I at U9{23-G4GOetv?r93;?b49m~Y
zud3HZZO?IFc0c*^B|k!o5mzf9ud*MZQy0#AgemP94J0}O+9DB<RA$doqIUiz4Q%>r
z6+Ft!40bipMcqYMbWgAJHFX^Vg>#VpQ8<62W%r8wmRYMw!?p(kYb6@)a$)rYdk+mv
z#HSx$D<;dmi*uvKkf4=PLol6$`8F1 at M96O$m2Q0Lgsj68d^n}!rxq6%KjiYenoYDJ
zhrxh4S9W&xM*^9w)|4-rr2H<0W+M*L>NCH7;dp(bH>^*$7Wn*+U}beR#1MY^G8p5V
zz7Nep_9Zv*<HRrh-=XX0W9-9;)}`4PV#%bP<TFZB0&z*>zD3ro%z%XgW*Z#YJ~%ji
zD+E%*L}8hGu2g<{yo|v2=D1`Ug8RhuOQux_lxJNW<Oda)MOKEc*$H50sLoctVXeUV
zQDzH1OHf4~J-D>oa3?_k8ub5C&Ky at QcQbyjYGC<;RUScr4X2oQHnSfolv at 73=)9R3
zHH at OI4ptBcl!?)NZzv=5q+;)gq$K5Drii|@;+ss2tP)OAS+-o$`}Brya3P0EZ$AqF
z4Z&)ROA8#M)oRof6f<ohWwVQdh*%ypX!0<=P%Q_&*9wVH1PU;TP}2y^^-y<Y7V<%?
zvg&TgP at UmoCbdYtQo&9uVGI_B3Md45LgU}J9{0bkyEpw+`A!ebWqH4_M{nW1E8HML
z9-k4xJ?UfFjmh%`j}Zne1OVd+VEx0w)~c%L>1-zPV6N!0jBSg8?Hq7d&&mE*@MM<T
zthY+2tRm79DjB>6#3GRU(+lebwl*-gYxt at paL`h)Gjp`trF!s#QlO_e{<6%oxI-&m
zZ;m11py6X;VA#YaPp4(eygRcxuQhTW?h(Zr at g%b!Y1}apH=Ns&!+P;Mz`Z+&pnlq|
zjGLKwh6?l>%Da2eESLO#)9c)z at Dul+e!->1XtwbqefP@~P1{QnfzuZ=MEHjnWK8+I
zn`;c#b|HgBjiCXFImiH2K_5Pu{qPc5)XtG#Koqs_9an?(K2cF64ks>JQIRiLnr0Uk
zc=qoPl}^vj&=pQK=6WpkfH=QG_f$t6=iB%1Z=}kIikZeav7!buv1UQ8khtv at _~N)1
z0Mn8vPDR(LeWe||E#1t*ZAwtUIGvemD$DxCp7J07K7Q9f5{GZ!{wntfXZaL|l9yDt
zZQ|L37}IpSRkPT-HM{-!>27lb at _D(}C>h!w@(MYMo8FE=5Q`4Vcc$pxy=-eeIQG(h
zaBEv}>%Ao^OTEA<+8K+Ba<lT95~s>hj7J#pJYO)<G4npx>#R7Lb}_kOeX at A<aY-YQ
zq<j|in*Umt(r81uENDD6;Zau_jSz;@*NWzkQo3U@#4zTbsJ`mzbA}4}SHkZz={S17
z|IN#$t+Z`LKyca5s_Ogbr34g+6am6TFy75aWx=oj;iVyK+JMl&n8psiXwipn{Q&EH
z5J+my3nE;!vZ>Y&-jO9xrHsKn*6A{DgDnzFlwPogj%X<Zf88Onx^2Regg)c-QI_&U
zIQw6uw at L-^U+EPnRR2bCC${s at fnNKNm&TgU_eD~m=2(%R(khZe`kdplg|-o)nPVKK
zQ-8<HYT(Bd at 6&rZ;JJz8$8ceX<Vp6*CspGoH{7z>U1TCTCK8JJhdj87TRfc#ReQOd
z$Y(O`^61+rQ*v-#DX9zBs;krSg4f<f{noZNpLv1fj?E33TsKecPjxC`w0Y74R&j}X
zp~y7|TOqyR`nSIbUe|xgC1x|W*C+lY*7^m0ReBU9JR>}?drOo=2vqLJg5a?*eX#~g
zWw7jq&{`!_cm2N>Af&|+YzpRJTPcpHYi}1AO{?VfR8F at 92VP)1!AsxwCIh=Lc$9%)
zQ|1&2l-NZX(8c((dJr7p{VvZ3<`SWadBBwf>|DU(s#DO>#E&%I1k=icNd(R`Bt+m5
z4U<I2O}Hl(ZAP|}J7R5)s<%OA>slyadp#c-#`tlMK6w_|kPfDu1jHMEC-xNa#H%xS
zQT9E9SO at l-w-r9KHC9~fr#@*66nx?(_vgeRVLXwpM)|FPt+XNWV<kElPVNR#t{YZv
zCAKyyg=actHtXFFa*mA<WGH<id3i|{jl^V}UO^Oj6W&_)fr0b=7zrs0kXS}xDux$R
zq|2P{2Z+`nDX$p3cm52}M*&yXk*jnNcL_AhxMLGimooW;^2r!La4~5W@=AAx!ZreU
zy2Z2fAQoEL=iY)Qvw*qOi2jVr*%vc2r;xT;lNAb-ltEH0GaeK2ImAz_E$Y8wxA>kF
zG0iW(yU1$g2IyW-ioUSDtQjadH=IN*4<dUgb5v@*5$l2gp7qrS-lxU2kiC7C(LD0O
zfHOY?QCvM}E>}_C4ck$7-tFbGRjPjjvJ%RD at D%rW)OQV?SXxlYBoPTmKLSdGRpSg5
zcP2HYcsDiCk_>`tr3(8ID4^Y7{0Exr at WNq~lF)y-msM6)#!k#w11fr>&1~^U6<{(_
zb5#LvNN+pf``EW+YVmn)n`}HBs?CKkxAwKn+c{wF03L<Zc~`ku3eGfC-s^otqzUJ|
z$Q9f~_0oO!#AZrq^`C!#L>vbogVn^pL7C5RqtA92o<wJdKHG;q(+4L3?S;Sy>!Z|%
z0i9&32n36#vRhh*Yd78QUH9K6UPz9^Uux{X(8NFDJt+E6Nao{Sa%&<b9}DS{{|Uv8
zj#V-x4o6nqIq!RwY=t|Vy at pu&t)SoO^~7(LC>~1~8^CRN&WK%c2^X|uyIK=4d?#dI
zgzn~}a_82YE?)jRv8Z4JJ`l#VDqWG({+|^TAP8P<DDj(zpoo*ee$?=wh*YH(;~@*z
zIu~uqSd%F40><1jqgXZRfW^J2Awx-cS_*EkuAErfzIn at uNl*&x1qHx?=tvp|dRs+~
zw$%|2PR#Yl(<9l3fDamNw*ks|(EnnK>K(DyKr}IAv at hY~*_5KX2WjqxFT<2g06Mct
zI68X7L>|A(_OaLPTs_6{`0s3g*i)e!Rmf$+_TG8(%!&slXFe)7|CV193{(nc_ED;U
zs4q7YgJH{)f!E>8#`e(xn?xVe7Ota?srO~h=EK~#g<~Y9>;+och*xLYR2Xd-R)dQ-
zPg^q)=OCm6)(Gaq at Zwez%@P$GVW4xL*qDzUW3+ool+t(e%_6H^+ at gLV%de}S{%hJ9
zExGQFCUJy<1p2`pSK#vx{1}?@T7BdvNtRbuR^~d+GTubOJ^$-dmznf;naK?Ysw(Wb
zh}2Kf4upUZt*WXzuy5TR*ck{Yga3t&hRPhu1z~<<Od^2J;!x&tQPni7s;UA}#aEzE
zXG0;^XY=*8 at 0v6>qXVbBpanNSCxUV;l3~&%4d-c=j5F^6tMk)!t;+(d9K`j*U#wiL
z4U{o1Or7i`O at o;Ve=f}vnQ3AgmDY^mh=h!mPDF!b{NBrGHR?C6-`||t-2L*XgH>7i
z+Xa6Ol{J+pyyV%y+5sJ-vjH<g8vO5(J(XJPJL)Mno_ygacJ--!hbt#-A=)pZlw4r)
z15G?`loW4{bU;9W-ggfFJP*M*8*Y6W3p+wKo(s6Zp&0y<`g-Sy&d2TqUFQEV0f}W_
z6f39r!eYm(K&ozGc{##=J|$*6><D9<e4umv{O|XF(TU&fmlpHr-m!}nR at q@R={x&(
z>mSXykd)WVH(-2#fr-OCoDciDf>v>&q#hv7ZleL0-9oQ6jVmv$Z$R?2KJX8DDXa2@
zlGB3v`xFPYbqDTxWnEZS#oh3dhM_#Pg5B_<5|2B#L0X~yu(b9hD9n3$@_q5~8R^uV
z=N>s>DX}F2RRX<8JxIK6rWa3<Rdn%xA?Dzg?dRub3D7m|HSg&By78nxcaL9!NX3B&
z^qo0HHrxoKFz*XtbYSK<$aP0MZ9gCbZgUS054eRII6N}LC26n?U)+ at avJT%~sG#Qh
z6S%fn+ at 2Qr{-poM;!M$fV1tfj6MJ)%+r at q}%;4T%FLyQN!#Rn>@r9bw_C;$eVTpNg
z@$(XnH)PfMT%k$nUwTXwj(L@?j$^50b0_s|eAg2-1D-MXk09!}XCf1j2*I%*Wq^J>
z&DNqIYx$Q_v&LCYRH}zwdZYC;S+3{0w|lV5G`E+#)Ob_F=M#Mp0Sg<0&xY2?Wmbn*
zmM_Iwy-xBRIH6YSbMX^H5o_!fJo-Ov$XkKc()8L*{Vp+2zP0I6-qD(RifbjJ<O4z8
z^y|JKJiMj}L37?_mJ<9u^NEi7t0&-g0YpXA1F!2@{aZAi^HfVhF!aHJ9FTPS{DAXK
zUtd4iXY#fp?n^#P!8BE#3LAl>WUa+;i({$+4LJOJ<wy96l7~u1<53{%ux-oCFnC)5
z@@0|Q+Y5`)zY?wvz~&JrK;muo=&SY1QZJl&Tr)ZZ&9kMz*<DHi2}fUjS{O4bOSMa9
zn2PH%?`ggnD+^@*g6jb2fNRs7YC02YARSK at 6n_HGZ2O#FMeNxFSdsYSVL_>cKqiq*
zQshwT?Zcf+CZxmYumi{23KRqybpe*yTp~KGyB+f0O;tU$(#Hz;ugYveZyf}XS1^Cn
zTTD&y25z~Z=$-ez4N2l(R}P4$SA;jf{RC;s_vT}gnF#)pc<l~|0w~Pq+R?_ at xs4h!
z6Yoa(u3N#KKDLMu7bG!xcs6UpJ%d26uCpYokiIlu`9s~Emw01GY6D*o=V!kiu*U(|
z{8=oN??!}ew)xbzj?w>Wva6XdDlp6r@^}~+6|d~MX9&4fRpMbR4_OXqi~y!l#9Pp>
zSAoev`nU77-|Lcl`RrgvpVBhhO at MBkDcdIBN<)1I$)I+FPD1k8m=U}((DAITtu>FF
z at M<SZ*_(iPm%DH&&j&YR79mE!DW~J>D3eV%OlDPDIf5caaiqq*;f!iqdE}u;Gy6Mv
zjl_M8)^*Gm^wpLkdZY{RFz$iAx0!`vrZ<ilZ{>2Yuml4aiM--gEqfY4Ot1UDrmpa$
z&NRxNKQj&$5gl?z9T*c-K&YV09A8Z`Y{tRO$A at 5<JP^lu)UgH-=GkA*<_mTiw%wvl
z%!}=lg)6wr+OJfIq$5Lvjg100g2E6^w`z5aQ<Df42IoEjcz$2YNpCQq55U08yQ}?o
zZ>Pq}nwf8yIf!IBn&(ixM8sieNTh_}50WdN2PJy|yvG$g_9g?TM9i3>V3PFnMd<4|
zDlF0|>Fu6_LF-P8nTB$ZWs7oMmo*-0RmG{EnALdsuGkljaV)yhi+x0kYy9A{PXe5u
z8-Bli`<DBI?G}umD9P2=HZ|ue87+xjRP2KoPN{p&t at y1tUBye&_zEaxo_AKw_k at 4n
zgncFq51P#3D^a5d=3?;DHyg^;zJb;E$~P;LTTMOi^wi1F_k0N4Z5x=GDB@;qaAs{h
zCU|Ja8`b~IKH2O?W|IO<cCh|19>;l3wzuFNKR-Dj2INj!$n4 at ECi()qC5SHGOIeh*
zqVJ4Nex^4JRp3G9WuZ_j*vv<KW5XNh3CUA}uDvcqKbV=o at 7Hl0YPI{~F;V{Af<T5{
zEXCWpUm&l!bXuuvFtw8!jDG&ZN_zA&1W9-~h0%gYcF44*Dgx5U=3s^Xb{{g{3{Mon
z>@|-v@~{k9K_&eUy30Hjyi;9A^t>>VEseMcg~KdlcO#d2lrs};{H&rFjWk4UZBtO#
zW>pT&LVT;VVU>UU7?XPCqVec4F>fexIJ!D%>G*wGBhF2L9EX++Q>|LZidW=T3lUXX
z5`*FGG_1G&=pnzl6H+Z|lb433k_MR<IMqljFdAjZVKKbp9)|E#GvJDB;QY4hL|^#e
zh!QXb21tlN#?7OYW%Zj-G&l;E!e7c(cNy{+nC5mC_tN0l{u5!r at WZdMXr;Ps89uQb
zHg_pw!iTJ>Yi|65DCXw{uiO0}N)%Y{slO&uDv2%BAu7)^?zd?X>wk!vaPceB(Ehe8
z!)*;)2 at PE0AG57C`?77~>3tJKGbXLJe)DQfvdr*&Qkj$%872w3M|J8<rmn1O=J@^Q
zTSH`LB6}%>tML$Yw`6ULx_IzW5xUPLmp<8KgF-J%&@VafzO>8s!@QyfVx&Ab61um9
zRi*f<-`5F$>Se~r&}%II)l+OXRp#!<lq|W>uBH*8d+fNBpMD!5dSMNs&?O}Y_&cnH
zzJwd)emP}o;H(|6EIst*yqcMT`f_^$lkU|2P)A+tN_hJ+PY1cYe0lTg?ag;lrkQRa
zH$>b|hCx}7tK_1wGU_R2to{~Lh86=pPj7dxR`xUv7Yg{8fV1WhTRe`NX`v1{yE30X
z)=6VhQAw0^5zXKG0`NP~3EZPzX)2>BiChjcaZKXsQOjeQH4;FjPO9^qwdcd>)%}_%
z{VsKnyCsla_nq5FD*RRktHSwZU%wzr0YoVM04>25M;wKL-{<3JTjQQ03AJZ!&>LSi
ztoWt>V>@R#kTp?K5zU%PapNcw3g3s+Z)X_1Lbn<=qp6Gy90i=;^8YBoy-$t{Dl*k=
zfmKe!<f4p}E@@yU4jITwB7xfop&qwU7%Uv+4CnO5Q9{O44#JG0NQ>>iw)n-l3d+&I
za*Z2D`@c;O at butNKaBWHr#$!cK5g7u_?FBpGw at A*h0VahHapg|wV<M)P<t+t{}9#w
zQ9Hwu5Lo4v<O at z`pal<Y;`jTDbQn4vI!2V&3tij?mH~4XEI&Wx8rAIJ_KDic%{n_V
zHf{lE!Sq%n=7*<E+rCKsK#15Ybbi;3w62x)?7Tb7@<76NfYSrHgHW=p-L<#Zjy>N_
z_p={=$K|}&xU+%l)ZUWW-lf>!z`?VK=qDANf#*la-L%v2ZNM#a=aqutGavaN4Ke=C
z=xGEbX4M~EU^(>phiAW|DDv40#Ak-#+I-`zJL1)Ib%3Bjn_2L+>uz7H6HR at oHhV_+
zemCWA!df&0oQb2~B?48N$^B0q7tl6Ya!AC~)h+Dy0C#JwD6KSeKGv)xYDD1Z`>$+`
z%mNlmusNHxyn(aY#Mm8cZqAwkwNWo&V>~QwYz4tdZ1mFXNrbOuw&1t=NR(v>)-Bwn
z0tzO-@`G~*&{HfX2ljfDB>&eCwP*&T`B^^K#s_gd;05pM`RUB{4EE7wsEpn%L<lnA
zycV2x_DEFMV}Tp~*?B~T4%Pfw<BqMJjIYO=2910<Y-1w;rpp`OiXp_>=?5ksxd8UY
z!(Na1;pyvOdG{5nN5HwJ+`v##Ir=tD!9DHEgQRlXYdHFjZ0mZAr^&CFdf!)yb at v@r
zNcIrx&Dpf%kd3Zk+BC?o%P<Aag|_oy;t~3S?z5d0`}(0UeB($5UZG)v?=ugwh)O8i
z#HlM9)84o>@3pm)6iS2nmB*Wc?Wn<Fhs*PBmaJw(kOO-sg__}zypQFGD{Z5fscdpz
zAqMQ0ptgL;g-g at 5ex{c7yeufY`=_LFj%0FS_oI5LJVhs2zZi()7=RstjNbgwy`9s<
zIG_LB at Eu!K)CC=$nXpvyc2jqJ9I~%d08?)BuERzIj}VV}I^s+h@()XC9DWvUgJdwp
zhtuowhjD^sRm2s;!KU;{NZajuv<}9S`_y?zF)GvMGMYy9qU6up{zJnAWhTqD%aR<I
z`PcO*Q{}Mz6$oRjXD9iHD<n$Q7iP)O9ToH*5+zfn56%}`yK$F{JW0W|`s<SI?lJ{C
zpSb*Mr>k=<Jrfk at vxE>$Yb}YcG3YXLLkIm${Z>g|WKmkEENYOPBY&@@{e5DUJq^j~
z`X_D&xwnl~%55KeY*T2!YRfTF-geaMbshAGYp~!;^U$j7u at IP@_MOJ)8xG at Hm^RGN
znW*Mje^(f9e_A9F^GA}Zp7nivRc?DRCJpP``JEI%(&g-r%Z=zlg1rnRQ=c)b$|PYn
z??ip81I-%wJ7l3oIVn5P<N~wC3+qi}K&yvR-i2L1PbGcx9-RJz4(=g_#Qtu`qIZ?I
zJF_Q34UhK-kb4ucpoD;Da#yQ~h!bt+#Ge+NcfZO-!+>COtAzZS9%}R9xPIjOl5q?;
z_0Q6CsFM}4!!u7jv&v(k47`oi*Q~OVLFGaQ&n{Gc(R3>h6C=|*Q9CbkU<?mpc#nde
zmBPV$I<zgoKt~K{QinTzQA#4~;gw&s+OT*G+$b293w$gbR`ZiEgvFf(eHWrDPsPbJ
z_BvQemLj|%==6?lFa<9&3pT-FTiwrhv#qbNo~Ok9LVPCiQ?CysPVLVyhJG(t^vmW1
zN_7%~nBp7p&!a*ym^>af(Qxv~Ne%|V__g)}t=*nNync7rk>o4!bdReLP^X)Dph|>D
zB!8kVhUpHS2#SErh~wt8<|c4`fVq7={d^@J!JGy0t1t5eS at DozzHW}hPdY}Qa6xx%
zsB7Xt0%sIsvjZ*7I={&}oVECW#C1S5J-8HSZnnv0pkTj55W)luM40g=m7mb>ErL>2
zRm at aA7xOZ_m1>cr$d5fAZ2~SO%+Z-;EZ!kpgzj{eVJ~{ASuj$9-*$prs0e<hH^Uj2
zNcslaYmdJujD7FRT^B1AH#2!V_Y^-G-cY~nbsO1q9Af!CHJ=UW)c25`y*QCoF0l1I
ziapvILgHI@`lkI!bqu{>jc at Bz&CEUVv&{vs<gksO>k at jOr!vmj0xpf)D$~3kKLtcw
zrk8Tmd at JGk1E&nXEki;|N^0ZuVP=_mYh>ez=;g5*7E(;wc4%JEN5djIVfOs4LC3_8
z=YQdi+QeyaTli2IQlZL2zdtNGj<q;KQ8ljrifRYFMcf#GOR>Yh(7YFYo#ke!xa%7~
zQ#tsptsQ1cApV=-c2sGoV{z04hLSt~03;0^b{Ow-WS<HoTM~k40a_U0MGZ at Kj9cMX
zx0S-O{L_&{ni_QHM_Ro{gdRo_0Puj%LQ?#@;@OQ;KK8I=HuF1Y&RbKFcL~^g5jJ+n
zFIU83LHlWm)3{q-sG?sPbbLu#yBB2ZK9-n2Ti#u;=t!hP^~y37ge-eNcSD}X3*`ds
zGd{|1^p!dxW+kJl9`_Q9KJXZR`Xh%EXP-r%szfcsx1(7Q!0}H5vy8=bdH=Pb>lUr~
zxau at KpnOBnPlgB}g2oxsbJkE<+ctj_ at WrzKzM6qy2+atkrZ$o5rZZXJrSW|)*Gr8N
z64%FDOc3ijf@;vh%!g~xWO>by?Y4S!@Vql6sPB2K@`H;?dHL9Tf7Zt8RN%3u`9{A-
z`xgFbr(Mv2Zt(T-k7A*H$lgqMi0 at dKiMf?fG$kO|?~4fjvaynHcHZ#G=d0U+WBg);
zG7x#3Au=5k6r20XB0qQTY9loumvqgJvZFL9MeOhIk8*vYMmS>;i=Y3tt6!|%R^N9{
zAWc*WKH-o;X`XurbCfcHmUEsxNtja9RWIA7yeu1AQbuuiUP^RH>o6;+rHS_?3Sn2J
z)!j<Q%?;rdtJF|Tq5oh_gRG19L=648&hOVX!h_*W3YNpo53 at RQ8q-%9_0YAzX&542
z_@|4FHYZz+e+yn$T^=@8bm}fKE+cI+T$)kv3089%j;l at G>d9Ys9JFkmHOLJZ(<Ct9
zu=V|Api!dNVj at gct}n%G{DfgmvuO>N@*0dWjTxnbD1N4c>=MIoyxW+lp8%;rVtkt3
zU<lnbpH-MB!9h;2yRV?~MtETuBLQyTes9{QEQC~*%-vWn!UQV=87Wsq&MI6%wnD~O
zTN~W?L8rO$D~)`%M0ipL%J~4iEqVgZR`L5cYOE=o%GlwigPQeTySa7B3RYFb6sLEX
z32${Z7qeiGw!8+tEeT|vq?hW3OO8H%ZD$6JF6-yHBafj+@@i&Rgk+&FlnG at q%nN^K
z<Ptv+7j9ipbBs*1Sh^+1ZC?QKj3FT}t2I2mtR?A4rCf}Lg(G9W_dEGH2kyHkHK}YE
z3C-z>B$Zg-^A|K26mFi-US>9<okC5x7i?%w+WAD+LZ#yaSQYw`{@3t&dANf?CMet~
z41~jl;y7%cC<n at WW94)&_;?sS at D9+%<eI)#*@2h3gZgZkPTPcjs5`!3Bd@*C_Np~^
z7-bQ at YeO6KS)l9qkm9Gy!GzLh@`A6GG}zf?LxRnVSU1tL6BcVgm-!b3Aqy{+x{_Ct
zmvCussr(<5r`q7zkX*Tq)?lnEPoh{-;JNM<KE%2tGU0I06=RBv!#7TNM>|e6#rtm6
zMnRKy`(f7wqk!LJ at T~egl7!&FpI%g%HzB at NQc}3d(O_kq153HD>T~wf`LC^%+H$KB
zWfBEvm6q-lZl0(wD$s*nX*@z)fPg<n9ZV6p!(UNdEeSGp at 3)hw<pp_%({Z4oHAJ^v
z+G-d*b;F~3r>UuaDh5iqh-y*0(8CJP_o5zPW|S0>Y!{Ju&SK`Xw1nINoQ%UN at L#)@
zY0Zr`=`f~kGhZrIz*X`tD+zL{FSu#SH|N+O**5CNj{mX$4DQ`A=#$(iRH8BO$ub$_
z=dL(&;cBD`c|fJ@;nf1RXUA5}7IiHX4dGV;enEUIv-Zya5%tzlQGIXwFg<{Dcb9;|
zhmN78J48TITBK2iknWV0h5<oPY3XjHLrICD1%aWPcl-UVXT59j7i;F6Gw1BH_r33{
zh73|Zm2He1DU<-%nueCvmdTBbEP@%-Ab2(<UlfWAGCBGMQ)}<&W7p@{RndM#lV!n8
z_Qc)Er$;`Ur;RxlkfZ~rE8ErrHq~S$r-=kgrcY-x5>nenUtPJ69C*h at 3|4268<RF^
zv6^+YzEBnLNLRQrh5-QpkQE(8l~;{H%aLwCjyo+TG3sNCpDXWl at 8^y&_nes8E<4uA
zcCY^#5NxS_w{wjav at i9aAjU0m{6)4ubJbszRCFq(xV2*`teVWG`4yQxBny*3I+Pzf
za(6V8)t8i2iToG?K4pOa1 at fdvvPHECCa5DUK)DAYWB|?DaK|in?M1Jj`a&onKhA*T
z`Vyhg%eQ#m|9V%>i%0J};4?2I{;OTAm|%jNB!-B;&dS_t23i>qV3Vc>C at U(8yx_#(
zFCHyty6_u77eQVB`}c3)gO)a(S*}y4(>aza3940qMO)k3HK%`6)D7$JS8Bb#-us8R
zuZw|o8noSNeY@!o(~wZUdo_*}5Mn<Sow=ES_t!7$jY!2voUJj^$Zq9g-7Y6{DvtC2
zolsMx;FF%9#O%KtiH%lQU*B&}rYik-XK$~kP$BXk`aNU=(tz-KKGqjymhlD-C9}`f
z*s4QsgVnxV2G`YUVqF%{1mt}<yfJEd=REqJB-t*(A3)xakbW~eJ7dGXd7Rr3+<8G(
z)u|nP;TNkO<8faHIU<#Dg?hpq9b{JvHZXLA&~c`NLa_6!S!bRYHUFRt?et#rMTK9!
zf6Y&dg*Fh(s5Foxn({;;21MX-fQVnU`beT6D-KHsT>0@}QWV2(G(tzkV8YomqTW3{
zOSa?*dD?o~F<E1p#rx6)R~mIG03(9PAK)8hQ#)@gZWPHM=DY~3+mr$WWkAo7BSlUi
z6SN)OkG#s$1rti_IRG^dI8e<sxLV|-6`r)%d1g{`4%hJ8kJ0hItjCLwkFRoWK@?c4
z){>%6EHloc0B=4p$w9}2vC(##pLTs at Q(f0t@;HneYt+OldmSXoaP{9oz?(;PKN<VC
zMR`Np_Hb_Z{t{X<)w!)j5Edan#m`+L0zd#9e_R1OZ8aip_y{CIb)TX?(^(~7>CRng
zCj7E;hx*mI!H%Xk%wi$7<^Jj=>_1QD`~4!yLb+PxrFKX7ii>nm6Qw`4Xzri&`j>~D
zK<P)Oq$5N+s{U*J&zEs!KY3*g%;sH0*~6v%n?H at z`Ax4F(D-t6YlPm->swDKJ at Ap?
z0 at J}~+S=o~w$BBdFrLJ~8?}M46ljpi>XL!3J6Jt{101fhUGrWU6E+wZRUVsapUZL0
zW+UmHq-k?aP>?t8=#;g at QeaFB@`iiCWz~Y#S$2KF&!LLkqJ?01moRH7uZnX~JetTw
zX=)HzyJ@&1iQMNM^IPF`o5Z0Ik$Nd#Z6y2ppiIm&I`K(%1LA7MpHO#tWwmXO<VXSk
z)7`k0t3hHzLotyrCYdv(6^5*CVYX`VS4RfhM0v4KXt>Rh6SSSRG7nD=d`lQPTY&<4
zP%^zs`cyzIoDM6F6nQQv!C$pa-g>z|j{M#0e|z?w6QvOMQy?VIcY2_lXR*+i;W(V6
zl?kIj_NQiXGR2Isjne0(IJA({Hs?jqg1)=E1B^F%<m%5%G}B!Rvsr7-gdD1Ap~AiE
zx+i>Jutu=e<G12U=GA6o6e3B+w@`6ve<u~<*lo<j-Arh#Tv#7Q`3=>y0%x3RS~pew
z&2R^|mb`&nnWYePqo84#(*V;tUd(aNb-fycMYWs&JG3S<*H^XKvU>Q$a>3<SbG5s+
zHWDtfE%V`#t{wD=?F*sL-qX0n^1o<j47_hA$6j)z(=|Ym4PT at 0E%LtS%<~=XDa%-i
za^f?GJi)b&<kT1)SV+-Udb(#h>y)eV2N#a5^Ar1bWqZiMzC?~NWbUpT{SrBzr}SS^
zFm<zA?H6Prp=q?w+v~5>=o`HgSAt#<FC}slf^!_4?6ZLQ;ydDMSAF&^P^l~L*e5R+
zdpt(loysg5V@>wn9UO6K-S9E@@7MTtQw+C{DEY{qG6Y+AMil{qH_q!yBh3Df3jkyT
zLRjo(fBjThX}?EzxXfoF3Ep%YwvlIa97^PLh+!_`7tktC_|L|ABUb7$+(NLU`@b7i
zi#-ZsHgKiPTRyO!j5O^2^BzsR)tAV3TEf(K(|2TuqmTw4yLG5CJim31 at XuStaET+D
zyxqhJe?*Jh-_26izl+!`|1W@%E`X%r{ze}gN?WlUG5w-m4xg1vje*ZuDk%NzP|jMX
zQ(e-cxBV6C(-y=lURNhsmLxgP*T>gPy>}u%&*>5;NDH=Yg%MfyF=Irv0$x-c;(P|?
z1Ij03Y*OqD6FiPPZ9IRAQ&A<Hl&0&D at pgv)n#Z8!-hBbAEhx2ZGvh~Nz?x%*!tEp2
z-+~&g#HMZr+i8bXe_c1>RdbAD!Lzetsmni8^}jaLgdy`@BG<RQSCcGU`;#wngI708
zt6siLkTG&#($VfBFNH?tzwsre4ZOrnCHm++rg=HnVkq}05fAU9x&NzK(OQ*e;N~S0
za+9~y`O}^+Of55WB2;vn+kZF3zQ<?J=k`+hVs$Ma8V9`EP3k~4qmvo#So2rn!dHl}
zpY~SEJcO&&`43cyJlx4Azt-+(E98}P|8u&a6&Ju*cEsC#gX+0aHE|M~Fs6ZDr&9G4
z%=u^594Tc at -#0%C2)-VS0UG=4Bu!(m)MeF^`Ksi*p)WUVh%dDxsr}cpQKgToovQ5;
z2=p=wU5j?O96qZv<4Ue=5VGpLX}vwARjF*EKEY!&SM8comx<x)n3h|)r@!3f3yc+I
zY$2?)Xr}lQhtlQM&yz&haF6GIzrc2I-Q|j$;d70waP71$eH!BvHUUDa6 at E^uunS at Q
z&K-;ldS at wfO`=`}Uw%f#J;*DDpMP1aue*QPx0f9ln!o&jW-bAfrkMHus$QY_wQ<xu
zikG-pk})n=I-iTNG$-hl{i7DX2#z1l#OWad-hH5O<gs3SH;OO*Z#DNaz5Cc1YQ1<Q
zW!ZN%yQ;L(Y1RS5Te-87sc6|X<Ch|=U$<N-kwnJ-WhS^t{gB&&;WQ2<- at X5Pc_&R@
zYW^L?q(HXXV!*6nIT7`F<frQ$8kDVkf2 at UgqP4nrHuA9g_+;Inses4Qw at 8U4&l_#z
zD*Z~&+JTeXt_k1=_pCfnx!nEYfPF$u?Uwl3e&qbIv~jNe;;l_aUP4_VT2lO9?cec`
zyuFZ2t*-I6%q=_5c%6U9nh at a}u>Y$K*tq#v%RkX*P|{Oh=ZV_rwpH$fcA_KMoX+`3
zT&8kLS1G>^|3jQNf|O?ki~T3o;$-#d*I{Im;+`(9{Ks8hy^N)(@x1MRCmjQP!*YVr
zCvSIrw*u%izIACj)3kOfr-H!Tm8F>ORUyIW4LY+kA#XM`n*{}ZJjmpPw^z%x1Boe}
z-VT12K287Gc&*^+elLsKo-F^~lSb74dVK9!C~<AqW0&~Rc%9$o`wPF~*(pauv6u`r
zzC!n2*X4eUq<p4Bh9CU~oo0`uw%%STc}5 at nCK}&F-CgJJ4Bh`p3i{_T{XF;01Kwt9
zH|@N_DQv1!Li));Y0l65>Z at -b_@7~rYI-itTYO4#fnL|Dt#*&`_DNQnL`h(T7JbB@
z5p5`J|M9*=xQruf>xryB=1SH?o^#9tn|Ni>4+wb};AoVZ#f8Ua6)>R{bZY#x)+#s0
z{a4w7i%3&gZ$4-=dHKpdq8|=WC?;$~G^>G!$aC$@H1LVy=ob|<3opJ6_+uQQmt91x
zk{Em;x6hNIv|80Z)RX*Q-R5N))n9iqlnC|+R#g3hE4#xdtuebi8*?h)1XCKN{71|u
zldO_L?T6|j|NaFQoR=TE%K1U{S6=0wmYLLpXntz&{2RYc#a_3NCIE!N0-p)InjOPN
zRUdw|2|yFs@|F11lZ!!NTEh+w$pYy2#uOUUpmY*u#3U^>{yY+=#Y at mb1d3HK@&T4#
zRD|ASs^wz$zYF}|FHL6qso~{TWkm&&o=P0M`Qx&Fj2IlyPsZ7gpCFpX<%l}pni-{s
zgF+T$F{YK?54tD+yVn2vqhWs>1Jq5Ev$K&~TU&D%Oxq<C<sa>oYV#bSS+>SNqXL?;
zplGeD1K2zxpdhMnqyVh0!u{W~v<wT<#7LF0D_YMe{?ogu@@M`JnIf^5S)#3~A)!i^
z$~?kP=SMo5>UaJBMLmAf!^zt&1U~_=Iol5hY;(R}lQlbt?XGaeaMO4=Ks`M at 1pyTo
zaM=JaZMC^#X%)-?(a<ofD8K_BieuiHC{)1iA at V!lPXcm3p{EkCBPRcqf#o(oc0o2x
zF2LJGv7%C&PiAw>DR!g*=segU0Z0$Q;GdN<lAD#4OU=z!lr%CUgPsaOK>?g0c``)+
zlL9y&2>PRoCd$kEJ>iedFqp>ncm751tRtPgoK3{uW6Gf@>LNOd{8IEc#RxzI9-M1J
z=*bvO66=;2fnJ$GYXC4~GNyozgH-V#u=z_3ADaZpPAtbj-2k18zjvj=0z17T!Bd~C
zR at wZ*y@^_s&1Tsi{#OGaw+8s(z(P!^BFK&Tr4<wC)O;DT1eBdfEhK)&UhXuz_{*$Z
z0O%R7=d%ozE-}w~^fuQ2^m+^(vy&G^xpptmWEVpU|=7S$<9|OnkdsWTSqa4cl
zKU5v%$K)?2Y|BLv&_>`rH8s?n4%=(~Po at kKckpFTf^HysToXQ8wCCG*Q%s`POn_9G
zuKP%7kPNPySK-#u*w=3S1Z+%z7-Yor`SUd~g8%jIj-Y&74Tm>iAp94oT3^H^@h6uf
zMHQH!g5fQeK>Cm;t)2qerPn>pvNu=daHKbN+4VFSR=b6h at k??376d^}?m0#Yjs70X
zlYWKcBoDg*{&Y}n(G#a<x?rjg2GoyAK!ERGnQkf0JS!FiCbw2pz*F^?j8~uudfFVx
z;V#M=Aoh=+aI<Li at +D(7%k0u2P^Bu@#j0;#XJIYY6Gt!u9t^K~o!#r0;tTof1gttD
z3)TM5?#ap at c71kEnkxp_d;AF}DBBcJs#{|u`s at E*9$v0YEHj(Q-lV{k1wJ{_fP3Sk
zl>eNJ{hoJMHd&oUn)Q!^3+Eu#hubOX()^QP5w>a5l?h4aTsgn2bI9yuuf;VBLzIA)
zL>O%FO7kY{G|Y+$(E9;q7|;)P+{E8D#vK;l at piDO&m8`+P2GRmhQ2^+>OFPmFzO%j
zSd*INeOG=k%-PtmwI2vwz}S#tU0 at xPM9?Br-Ow48o(c4<NM^84mDXV)8lofz^I{uA
zJ46wj1N3ziU=VyK&R6cHXA=d at 84trp2L<C((iHBHN{rR(2$;4}D9bAA8bL*@s`So<
zbss&Q_J^;>=yOd8Y<FrmDa)}@k`89Ykt&9;u>5rb09R+(y>ad42edh0>iXP0^79RN
z{&DZc321o^n3jnu9SEZW$8Gg{>Dji61;rAI&Ze4`VkK3S!4;h{eap6Kr8!vji$1^7
zX$;*b8sZod`deu-JW{t;(Q<HTSYb-dBR9#sMw=0qiji&36s&$P)kem0K!+(ubb<I#
zQw%A{PtrNsCu)1MP<IM%axW5|dhd{n at k$JPn=jave*wi`0cp>M{>IqwYtSWX5t~EB
zUcXcE_sM?dDutK`S`iagXM>8?n7&t-GCNYl+A78#Ix6zYvK)9lxK=Dh+Wsd{KCDPn
zD^gcQtMw4IAKJHhWRjv`rs6~$(fPMDZ0N<Zmy*ouV`=n5WKxpIbeQ%<k(0ZvmVZ%x
z%6^RXkT~qq-gP at 8NWs8G@Z3px_YMXnhpf+Tp+wnqx#wIO4>HB5C51AyYe|3l08<GH
z4$#VH^?|P>#UX3-tK$-6 at sK&E5OHLAInYrsV8Vx*R`oS at YFR2B6F=x}VC9DjFDTnA
zsaSaiDGDeZM$+0gGyaYp#-t`9NN!?4+-}z>3yh&tFGZKUSKMQf>YGJn!iwvqT!455
zB09Lf6ni(J%U!HPw>|#&n14-i44fEu9FN*Wg;!H*zuh{F+6eun{je>Y at oOv>z2eY^
zKj=_uYUuWNasr2xtWvg&=r=R3Uzhi5!Gyl~Y^<is;$j>2^~7#P9Xx4j)gvD&))RPk
z9k1zzsAk)W^>@sWQrgGzH~OZOK~zFh4?g?}=d|9pO?PX4$)_SRQ7`d=jxH!L<P at 30
z_E=2N#o1cP%;PpZmb(5zyi=bobzPvp&y(z`d*_l8(L;Ya0_BpwSeFPpac5hSJMKfb
zVG{+<HJGBAa|qvpc7UEGXzOD2FdX8l>gt)vz;mz)VNK?pz9~3!*U`LyJCPDTyB+u|
zk-_KjON>vPF%rBAq0me98bPvyRRTyGWySc_UDO4eYw?5FL4i|rW9W(}*OHtQn-7^g
zWMB$f#e!uH=PGxjh`u0$u78Yy4gV#wDE+M7c+b8sE0RX1;*t?L(!V1C)+S);{mup@
zh^mZ2lrbNDlwA5QpV1dg$8@>tSeX?HvA=}y!8 at 3b-$Mi%iQQZuPUQJwE7U`t`ktIp
zFQDvtHFxt*NpN{|vOepDROrAW!thwX<;I1SI95+?W#@*4$%4>Cq%d~s)G3x;G8+*Y
z5}_*;1B}lZ$MvGM2=3 at Fe)y23hJ}kjah~`bK)bbs6HWtsIO3JxsC at R>2v)w?u}Cfj
zF7nD0S4tZwab$Rk1K4w*LCRD-+EW_{MX1fPtoN}Jvwf+93^p-cu`wK<J@<pKO`j5g
z1tQ#9p|x;_J6PL%c_^O`8x7DyVe6bJL%7tR&OQ{b3yfT8IhCxW)NCh+BZF-Wd1ctC
zi%^0q_WqOIAP(@QV3;Y`VM=V*JB_q49Z5i1;v!QomAi0!w{6%SqYriwB)UzVf%lU4
z!avtWOxyuJo;0>j&Gp}Fjd@|30{P}hi0;lpz4HqjbeKr2B>OGXe`7q8Yir|!XJX${
z&YuRqWN=#(9%bV^{hBIXa5HU!^I?LaNJ=dz=3K&?NwuL^ugqvAiu(Nl)5J2O70i35
zBFOlSBzVawFWb7Q=!ZCf>7|p)@cq at E%Bah~x?dCM6m$UH<d2FS>$-2Is4?KG<5QAs
z#%#H=351aM#Vw%0sA#8&;cAMtJFjZtdB-c^OV$O}Yh~LRSZ|uFaKrGaRule~Z`Sfl
z;iWEm?SmY5sb_xfyp5sK%8j9W22WcyqK at 9MqKYjj(}84KFywQkamhR~D<ULevO$%(
zi;wc$S?@Z}*aqlh;JpH)?vOyp#?f>hhjelZGa{kzS^>=HsePYrK%?&vl>r-c9^I>A
z_mmI#kG)57ji+9iMt%rjU0M^<!ra*|$d*=@$XX{zR&}Y|i9ONxQh^<P-2V{O=E!%<
z1RXF0(|>ay*d$_89I0U@$o1hp9v{^E8Puo at BML6h>n%sg6Gq6ezWjILm<tNuQ#1QA
zsh`Fzy<FGjCZGWF*&hv!RTIM-47s2O>t)FM- at 2nKv1zj9LOs1CQ}Jg9g%5CM#a=l=
zMbtqi$E*l2080s*n2?{*of&+w^muPK-9Bj%;A at 7g$7I0OmgLqMByjLV2~3g44#dGs
z)n38&#c(c(a+_!o#=E><oFWs+BpZ{$XgNz(1 at WW$N4?f+cPa9SRTYC{xYZV|oWU|6
z+hl4OrUtqN4dSCE#<-2=r!pnJnYt-(I-277Phgl{B)JyQE-kWu$ri*YKZj*yvLtNm
z1L at ctF%zp+(h~#@wMDXz9#)B?p%}+2gRD-RafajMC+3D-7o at g_J5oCHSS!Q+56RUV
zHAb2xyJja2EK;2Lue);%77kCfz<4O}!N{wOmR3HNo#c4B?PYN-$&I=m6r7<kd0*6~
zaTs~Z<h_9N*{xH~mY`0ATe%pU1ELO{=p1(5b$v1%Gb{`eFR3-2K6<5EX+`xP$`-q)
z%|6VS<XhV1Kqxu}tWkRMUve+%kWG#J%Jb<PHc#k{meZPTAXI*=i);vm+NS*iMv=ae
ze#kskS;tv66Psaw6h}B7<vx&C17Q>07&+eI8xjsQ97FeAp~E27R;*GRAM9d6Wp0+<
zwLud)^{IFPb7X?Rp(oG3(WM4Xo~d%^ml-I&jdb7~((+VJgmkI6>}JA5IKf at s5wBj(
zv#%;MP2B(Rk$r<YFhO$XBK3}ANv>w>;_(1Iv`Wo4U6K`)^!3gI1o(WOTk{IwBQ&oJ
z at -p5{c`nwQ1!t?&t9qZ{k<U}zo3b3NW;(`vJb9RICsI#nS|7jQ<lEk843+%2RLHMc
z+g-N(7qeo|5W~nvB&sI&ryHb!aOr7mFg9)h>B?vSyvj&>l`FQVF57+SsOInbzR;^I
z!^8zwI9s2kRR9hK&w{)dIDt$vmeiv)0+-mRi{eLpB(}ch-M3zR+!yON$@Xhap(E(O
zHe`;@i1~2CyFUsFRtqZhrb#7!^~<AF4uh$pRBCSINe649{cPQj3QM2eo9f?;(bG+x
z6Wkan6nKP2&xZXfCi_?abj5A>2L!YAXe}|FY?1)nfg at 10wKznQV}p#yfs;v|HZd<7
z1zS6NDgq%ts_)+Gv{2WI7pkleizdZMv7)L*BJKq1v|LPKnYes`Ye`nV8ND**_ww?Z
zw85p}yFS=LNN*LTG+NfY`wd-bJ##2IZwNKR+2;HcmrkFVbjjhmcY0JCDj+5 at 2Hj4P
zGlLfIKOV(`L|SbEs>gmktW>6%CvT_{XO4o<4$BIp2IwCNh+%X)93HFi at s%-OZTN2y
zV0v#1t*sKjG4KDu`T{DU>L(X>PI3q{W(wx_<+K^Z{*1h~s at _k_$e3Co?huEST&T*?
zwVNXZW%6Uuee*mx*Nu27*4yM!QZgKMWJAs$6TUh+Ci-{hZR;L;XgQIxRxVv3*abF(
zbQno8q$&tiGLG~#lbH#mefmpHGD+^9SfHaqDoSxsbbE96B=Y9hn^WVULqe#m?oZ%?
zUFyPIZVG<=LZeic9y;TKrKSmu&IK3!^nM2 at DgH5cBtX@X{uYe}dc&Fi;PLWDsOCo1
z(O1-!m10Qa==vUKr~K`9XIzehuU6jU?JfZZ=&II}`F964$8D-wgnwxdEaSr@#XfJf
ziJB4~7l0BN)<GgAxJF<e&=cxT=RNV=$Mq4!vlTB_((3kvO&!Fa(*6(}fX4QReu577
zx<kfCqJq)>3+nyLx%+~FXqDQJ!Dw at H(}uEqji5cU5f7wozm!F_I&gd5Lk}hDRbSur
z>1EK)lVhbO8m@?{gu*)AA at gj_G6VEWs_b_IpbCM~2_~UyH-<tC#W{-oqB8{-1ZVVn
zFCNcMvm7uj3X&YGHXHAAZjU|29NxJ*d6N_+31~*Tm);s<c#qkR4;*_Yhc!#5k+JZo
z at Eze;{3bRg41bmRs7<CNvB|9>O4X#mWwB=?g`?e==_0r|l9iDgAw7p(fy#VZ7-+50
z8eYETkJT%%o06I3Rte}T8B2su;)iCt at d>Cg2?|tEk88-54|}HTTMZ3)?bj0UAUgh`
zo^o5?S6dU(Bn4i{pblYLNGdAA*dkNW6F;6bKX<`{Nu*yY$HcOTv_e0GKDj?=wC)}@
zP+^{s_{{N<g at UdQdC^z&$HoC>n3Cb|W~*_S!lQEU4Xx_DU=8GZWuft1kFVMyw6sdx
zq7izsLy<Oy#G?olEyi|y at GxGD55_q6vB3A9*%b#uM-Fv!i_zNAR}b+<5wf=kc0DLp
z=fx9<KJ-K9UXYJCRwB&3NX at _a4aGRGp%cnxf<zk6hkMrclaUzgr&n!`u15m=(i@@n
zV_ZMRh9h7lA2M!{dO5EZbQ`6&Y;$gXd@#}vR69Rpa3c4gZcBQLT((_h^>NtgmiR=I
z{La4LoEM47ioIAPwz#Ivd%N~7Cgbx_0H%istWBD4ljuU&)oV)*!@NU#H4);_D at UL6
z at QRP#^#=$2s56BW>tE{%#`5_W9!shXo=b8!j!>`w+Y!Kql4x+fkCIgxKCc_e?&q#H
zhAu*gUq%T?(JXa^va%cy-DLIYIT3pwtx`db=)8|Ko(|B{<&Yi}>>2dX7t4qrFwt at S
z>3*Gn$G5xbp?00HSGMK`ag8oGO9+#UVr27Na$mo;z~fDF*$g(BI(b!}x}ik(r<0z{
zTtIVN!S=8fH&n9J^x+8AY(oXPhSPc)d$?A;N-!1*jxwv at -x&J2=;X@(?--u5go_Xi
zot#>Ofq4x#T3OKNS%^8=e?jH~iRYdrF>UCr35m)&eHwU=74x2x6jkP+LdpB(B*x!;
zU|!ucHQ?^o&%V8YI`!cbRi2UEyym*&6B$1~Wzha~((wtu-;bwP17&5Sj(S({loyJS
z_b>Hk50T4j=UC at r@a>)c;y;!ASr+CMpONOiK1lm;b+i3m)zsbHa!_5nx5U_G#)mCW
z+mm$fa})D6I|tlqv+d>2td1rPPladWqwx)5nQCvaioYM5*xxT>3wh{tb>WGln_ at Mt
zv9J%wp_^rklAc7!dkDeUvNF()@8tFh&pZc0GSZ_v6SWcRtI66`Ynpwngpr2;(M0v;
zzB&~=&_H_V5 at __25H3e)P&1(6F6ojwU5j6?Zzi@*ezc#z<i}hd7`&ksn_C?nH`PAk
zB^n<)*+&hegf8&jC!jxL__^Mu4A=0SM?6P^r^r8S>sRhv(Ant!Qkk*xN5L3JoRC<#
zxb{vxm%fcSw3eO-R~BnJQ5<L2%3t4PLELO*>Q=B`_9~m}4e)U9P^&Qb=zI`0n%?&5
zKp&SlN)|J}R{LZPHR at wsf?f`Ca!kF)K8<FN1>FGu&ml&S`RNWmzhlE(No*C32o+zx
z={!rL5+ZVkFy;tSEOiZ^Ufyg4WmSeA;#40-Ww^!?5NG%$NcQ&oEz2+?2=3p2A&4h5
z)UN`jFCuL1m_`NOJJ5cZ=XclX1YLj^gwZ`d06e$#1Z61048ku}G9Atv)fhU=YcZ{2
zlyxEEkqJINPM3h`9Tkdu*}hFs4tf%<o=b)0um5Idl4?V%Swg#W(MW(2%RSXfjg92L
zxs7FBpc!;De8p<^U5|tTlboFY;<T5z&p(F+(zG;ztYgcM=__ at L(t;=+?o#jiT%~d_
z3~e!GN}4SxuotpzYLAAnP$6RSX=O}8=k$BCiHFcBOQ(+n=oU6!>9dY=A4L(kzFse|
z_!_#I$(^UWezpt69O@!miAwzgHUXgb<$juLU(dx-Sk4W|7m8&#KUGqa*SFv4<fG-A
z%RA~++eg8kvC=;_Q-4q3FMu<|25Da!jK&YRb;TC*3|BK|tDu7AiZOCAm)u>6xk&fL
zzFz2a_->SJ{EaN4w5!QlQwpsv at bjrUo#c<JPM=Ox?!)S$n-9>FeJlti-O{lKZabmk
zgvxlg-~^QYsn#!&?6E#o7<8R2{aw=6X%+Q99mE4KV{}Dg+L8D8(zeNx0boB0FU$Vb
zyEo<&&43J6Ql0ku)P;RIg5lrie(>swFA;tmhXWyM^-o7rTN*^>q5n}Y|E1h{Ms5~~
z!Vlr{=O&(=HcfBjO<q at PC8sS>WFXoh&A#nhBlpKf{cDx%NI>DZ;@<g#w$Vohl~0pc
zFtXQMS~UrsEpKgO(zzNZD?}R_Iz-Qd(3H-vM6rUt8ov-=BpjBDkCNP(S4niMdWr9S
zBp`A?rOO|+PSDQR6v}fR55|bB5air6uPJZq?0zYDTfa%EoBo#iD(d&-DnT_}&IR}6
zN_3;bNW$@IikOM<KINAP$xE(R_W>}+axn%oI;x&fyt>3oCI(_}H~U!a<n>^!JjKd%
zISx}<sjo|qw^A%sBffw^>98(G%56+uDohY5iH)v{BdAHbu0RC4+Hq?Pg~^Z|Fq!L9
zL|c>PNwN48t5Ji4(TxjkfubOr&rta%Vr0jZ`Z$U%zqnH_t;7+qM1X-%B?<-frn613
z`l`v0L|?b)?xxz*uW==IT#$j}Q1q95dH;IhrS#N^2ARc|JOASR_{|H2Z?%R#w1095
z23}r2w7<Vm+MqrhlAsWfF!7<^yQz2{q3m}DJW(__1UH2HS;pZSiQW%CYxp9YwZ4Ck
z-#Q%nJjI`ww7lykAVufOsrOXr3lFE-Jr0-7yxq5P{$+bcRgTv`C%=DnhVO5v_%nVR
z!DA2oZtBN-?g~Gpo7Jxc%W1cFv?K?Ew?_KkJe6FrtnFDLd?3Af`}QreF!NOe%rw$2
zhS;;ZH44Q9uz=uP at _v4PP^EuJW7^E(Vk|!%FnHn3{130~sQZyoo9}m<UjDlGH}8&^
zpCp$<2+t2!5*1 at 9RP9u<+!ktVWB-9gnjb30K*HbdZt%7bNRcWZESUYHzq3S3#;J)^
zXa#2gfqp>d2<&j4CxU*6sx8T|8ymeQVyG{<`~>?mFHf?U5c08+9>5r+0Dv;XW;Q!H
zGZS`w?F*uVNMqmyAZroMTS*b~jkWTGoxlHv0UQ&EKEqjA|9=Ps9Jh%1&)Q4im(twa
zjF9G9Zji9!jBYP%0?I?x_{3+C1oYjlJ|`P5KLBV>NcZg+_y$c|a4MT){f~8+^H{ZM
zWnE%&kO!?g$Ua<3(eBB7T_!(qrMTP4h>XL|n&S_=zm2I51>Z_Wabm&C+L%6qk|>X=
z)A)9%N~=mN`~HCq7Q&R4jP|FIbAtXXImPqpUL|x_jNgA)?~fcAUkgbmPe}>!<R^{-
z)aBn{z at I^MQG#*@8za8-0*)2bVRS%B+pa1&(Q$i4JuCNFWWf{)3eAOStzgf1CewDf
zUEx^D|8W7 at OMM;?Mwb6~AhzAXFk}-AVxDs#WG9FCI-pUH-oxgz@|uyP#chzK$rr$~
z<Vzw=8L|N~`N@?PixxozV`>T6g#26e6?J7La51EEdKoIoH8OtZA=n1?G;W{1V$p|C
zD-wf9HGt$GrZTNJnPz5Zi at tqx9;^{G;h}F<c{o2krTfVvH9z)3AoJPFm$bmDq}V>3
zP4llT2(kmRHRQY?0N&V4TYsf!@ozD-V=x2e)@Y|{@>qQ8Cu{WdQi1$l4+f+Y#{v2>
zrJSweG#Hop2x&5^b?QvOAKU-kLJ1_H3B%`!;r<|hsm<>K-qJ$rG+Xg4E0<Y0q8(Ts
z)w}$TY4Y5LfB$~=@gTgtT^f3^<Z0C4LZ6kLZL59G``x*@qK7}uefKa%K=4N=0Prr`
z2|;TfqWpi)poJ7LI-!;W7k8k-v`hX5h+t{5(H0vU8rxCOzy at 71U_*caB={ck7pCqb
zV-bkVLf|{o3f>Pud}5?{YHB1*I%w;@J(ep5Bq!kY at z+>J|Hk?M at V0N?@cG(KNyfyt
z>8K)@$@_VW0R#7hSC#YE{)kTbWDPGcy873y=YWofI%XBQaM5xv2rM0Py!OO<`**1I
z!p7yitlhkVt?#>`;15=*#LLXgV`%_83$@@2qbhUnMgI>ltohn_ZN>3N(D&W=3Gg2@
z?bf;s3HdCzc?Ar^fdiM at R;E3}bPR=uP1FG3ch9xImjnr$P#YNyGDYx|0RQcO at 2!iL
z2tdhZ-vW#Xg(+p|pFkR<p9;XFAE{0Y0Xgcl5HW_FW;4^ff8=6TMYf5&?dNf7w5o$1
zS5N at dkwgUR5H0DIVf?Q9P>+W}%JrrFu*j$;NySKoN&<~br~FnrSF2k`2t&5-FqA21
z at 2ZLyJqyl479c}mOM-z4m67chDEI|?0yIV3^ZdM|kB6U$b=@pn+__gKVS!}6Sbki~
z9f_KGyi_jvsN=70i|(t<(q!x*<y`z;KvanmWB3z^6N1v0EVWbkrAh<6#0o{t)@B&Q
z{XJ4NDv55^K$H9Y>%5yylUms*d1Ln3kzF}5O1T4s5fWkWYm$OVvcz#L##>!0#?}}}
zgRw(U>YaOllq<IH@{Od&PQr7JqV)HoQ+{xV<IYZ5(+c7A at x)n2HgO&@T<}?-9%4Np
z$2E*47fX4PvM~a_21`!c_94H>==w3Q0B+UbYNM~6124^|z@`Fy37A-<k}laPqc3U4
z<r%9OGArBNMEU*g30KT&D%R14nKxSLQjofqG0JlyqyHA9m)`ekP6oPh2AuD$tQB7@
zh3GHraZ58sFz+k8L>A at CL_U(f*UkAj$wT*K_H3dh5c2Nth1;>uUea at giEqkTe0&vs
zXVBAw`53cYZY`Myp<*IS-or2g{68|SgxV{9j0=2iINKEt;d<-C-|7R#PbONtCEqdN
zxi4ImvVIGr+WS<*6|y%scd@|nX5o}%`OgUR?>aJ3e*^`u&<}Ppmuf;jnKP7t2gK9U
zG=HigrJU1qZ$x>mc91leg(>m&F{W5}DD0{la at 0F~QwTy&x}7Qp7GDUlhS7BFnMz0A
zEsCy9DhEW~BJeMV3BM}rK=eIAe at H`yICm#Tw2a{>@rO5nRR&sy*`xBaXU3xBsWM;6
z%K_*M(zxoKtt~B?T<$-S6qVt<iu~b*x6OZ)oH^usI8zI3{6N;N=`8(uyTacT>&Xs9
zt at dpnaHuQ)_CKqrWruc&0so_y0!NK7E3x*GxNRSBRIpTTtVVfuMUqxccu%}PBJyzY
zAr(&$G$Q=cE%cTvYBhZGbAZrCwd41U0B??ot5ImKc#+zG6q3@>QlGS!Uy-{g3>Aaw
zJS(i&hfzo9iqMtg4$lyUG0Wrq+7e)2ZzRAvZx8c32zYeH`K`M=73;YuVpM4w at TsG6
zC9dheh3jo5?7<&Kw~y8>PK(Y`pBuSw>p<cu1Km%>d-w~u)ZUzWnL!GeaQ#o;G6YTL
zD-?bR2|4bPKZOs)e%ii(5?WCi-saO9m~_CoHig^I&<+;nqPJ3BtYfIl at n1H~u=X7m
zKHB3{Gm^NzaOwYYqfqy<4d&@eNw*o*rA7m$e6)oZxuIuIaOf7QaT0GYMEO75I{Dk&
zK`(hXH+&fAZumu3JZS@}YYAQ~UAn+3p;40e;~feQKQi0`vaw|1eh|0$^O*-Cao+s)
zK~YI7ke9=dEtdj|l_op7rZKjnE?9-unF@<*?n=rOfv*91*GQ&;hxgYS`VA%`E%>@n
zRR14Y?RwU(0i%|Rmq}@5wr$BJqPmXMRu?8*@9aLyM9^h$#Q at Unt4~nwE<F at QR5-tE
zwGNOb#0KX*4SP%Ppn}Gk6UZ*`ZFF!OYogYk)3lbjIlpHum}Khg$wxtN0-c at SygM`O
zGmI at h^N6b__)&18 at K?lrri=vM^zs&C5q2gHE*4?u>CFNk<547M<8xoG^ajzx9kn3o
ze3^+{*g8`tZdbyGy{)N+Noj!7<nlPOqM`?zl~&SX0Zk at F>E!^6kqNe6!K2(<DXu2e
z<hP?nHNbx(nFie3V|23}>6!4>zY3yHgoGMcbFnAqrxUrj5oeSZvX3*nLpFIPa;mw_
zO<WJHHd+Xn7v0eoX!PC8D5WCLSq`a;8e!&Fhj46{3W#LGJC^M*2M5Q2<4=!*I+eAz
zQ8zpYD83pcq!xD7tBbWhXr{)!<30G?vli;-R at D;qt6r#?(5sukpl-w>PVuj%8!r0J
z{sFz|I>lTW#vhY~g6;F3VczcJzHiu2#`o`kQ|;`_^>n8>I9GAEVuCb^Y{wk$J4*M3
z=TFa<9<(nPSkq#rzh)=$tUP4S84rCk!!5dGy!=b*hwKuREC`eHR~^65T{<CQ at cR}t
z+;K_RXjd2!EbP3qauaxz(qhrwlrK)2XZEbnNIu}OcJ9|=*w0vnH&Px7vfR at D1`8^J
zUB-$EURWq6A)ufmlKtcb>*>Wn0v_hFU5ub$`kO*A4a>Sn%j5CM)EX0dc=cD|D0#A2
zc0dp|;KsKm^B9}`kxOH2DB>6WA|U>JVwO3V8d#KO*(q)X)vyVfxOrs@$d~EJR;*eb
zdUkY=i=H9scwBm~uZRP at 2O5a-E+QLkoLS#3JxD?4+K4!Lo#c16s$DPScxBc#sIJV(
zT2bCZE|@aRBgX^&NC>?~J-*AGyPvs(S$c|^NNzEGN}XV&@78QEMMKd^BdNbTXqZb=
zVdgqt{ieWfdekM;P0mBJ>gC+y-Eo3larI*b at l}ZwHI{(-byRzvIffig<oRDY9FF7H
zQWW-*$hq-=_`l(JTi-d{U at I^AGt9y+R$w>=ErgN`%@D!^yedm8TCz&)Mc3}|*__1X
z9`q=AO2|cPxM`~Ft1&pPJx2`7r8%+oZ>00;6yNF{C7&V@#?Im$+C2~nT~2pgGZ883
zkV7Q%e5oMW*#&;$t=}tYzf at fEyNFpcsF}664G=O6oCP8=b7s<?QC-d5^eXv#Ux;7!
zub4-5- at iCYk!0w~A)U3<ddZq|@Out+Sk#Che8ApIk at h9LV8(N%TezUWO^Q~G_Qkje
zr1V~xUHcOF{;B})bgl3(5b}2RR at kMvfL@oW<SQ%81#r+YW-F8J64CI;j;qWl+ntIg
z+GrsybiC4~nA~tN+F~wTv=xQ%U at fw^=VJDGF`XA{d!u5Gj-(=ON4)2e_AJjm3g#q{
zgOwuIL(dt*ksHo)F%EbhK5s;~s^dIH>#$3T3sHlL%lOm*Cv0@|?Ci{4$!uzZApTzr
zXe^Q+1x4Q_`So`xv4t*`BA<lD+aGTyfBwe*M-bxJ8p{l|;g<Ru%Cc<T=+T%oCQkEY
zyoakhm{VkZ)mx;y!OY9_J?g?rAf^yk(bj;@Sl*0x?Lc&4;FDpR7nKH}>Qkli83b{D
zKyE?uDJhI62CGQVoWYOrhWr4g)rFsbjrYr&ZSt+9s8CNxg;Nl`QwZ<#lfRAoQilq)
zdc9w?m!l;EuAvo|`=#!`V<=AlP41WX+Q^Z6b!0-5gs*o;SR{i?kh=7RcuvP>RP6U+
zTG&5zCNMFx@)g{7F)w?DXS<(xt?%ahQ+C{sikQ|M({aUM30leHpr^i}U0xN;D!~z)
z4*BV1xVo0H(#<~W+Nsy4_##lW{&yR3$DwJA_QO^D$D->U at k`u;yGp;K9h}nDV_P%W
z^+ik7YC7L~=w3|}3Pu2i#dH$Xota at lBxu-WDJVP%vUmbQNKjT)t~J0sLSbMQPcN(Z
z)6y8rKvAxkYoZ&9wV*v<FVafytJ9mH92l}Fa!<E6`<_JgdAMWdgaM{(7<SO>k19qB
zmTbzA)J+az+rQ`BUejXvUcix(7JYmHClX^<JJCihuOBl6e1DYDZjVmUqo7^ExcK%F
zj=tnEOJQdf?~a<W2y`GE4YRqBFdr)}!Bk$9^-atA%SJyZLKd0s9Q~(#jOL9fR!lRS
zN~kgQ_<Z7o)a>$PO0vZ)zdtH%oFObbA{DI&DsT5)TAOa|{H>g&7;eol95jwfxIQN1
z8cPTyi`EV&6 at JCj<ViVn+xVv-McBDX*Z4GJP)GO;6z$4ACcJ-)ILmE0x-6kYZr!`2
z(h){fSamJg<#gP$<pdl{7)AGfFphh at O%ZQv5%=Aq{~aCP(iygZ%u1L>vHYGFk=eVa
z at Lv&D&K}<d(`^jx-a&S`(06YFn(%F*=qO~0(d0OqCWVhFUrDV`h#3Z#`_7&3J#<(4
zZmkws+ at p=TOs|Roz(Dt{*N8=M__xO}bZMHbMO_)r-ap}<Np%KuZ{r=x(Fx9*I!(!c
zN1nqc+_A<?XV4TN-8za3I;+i3gRtAD;yksDV>G&-jg7;LzN1cVDR9Xu`sAkyqP&-i
zoSe1 at bJ-cR%TB7$E;42G#-LQz;>=rFPK=n=Qf!-!lpavF8S5+mgjL`1opvj8xav(p
zH0NO(X$PHA;#(dHc-wc(W|B1ZJS;v63{+h7ww(j%I3nOBg!d;qOZn7*6-CY{vi8>#
z<@ZxT+a(j#9+)%?3sIB=&9LlpyxnJ9C`92$-+jdFpVJCG3rgy0Ey2i9fLQT3ag#?D
zT=w!ntfIO*t-Kf{;#71$XxUFnct7PeqhAw8QBb%1-QuFOw|FwwaA&-9vFGPLdrXRq
zZr~%fDcnz;bc(|Ad9h{dGbcMf+|f1uj<0**;k9^c at cW}8Y~9uFcz-Tpq}jhMWkSAH
zNk9*vs_Kuj$D>8zoewrw&=R75JYZ at t!Ft8TovwCy$mrbbnzw{EPFUF6Z`Acm^c>N(
z(h)ZOLMl43<IsfHbi&;rMJO%uXVxSUx|@O-D^1;Z-1!}Nyohixo>17+0u1JEot(##
zHPh at DL;LK16o4efJ-LvBUVcUAJp5t==nNic(f?Y7Y3ZV9o_+AtWTSbRRCTio!B>_P
zK!K|Sm;XVwkpcc=+HY&O9wrdLgzZoHS}!z&$O`6F$Ex?%p-z`5t=gHY$~+M}D at nHM
z;qmQdp0kbyrfwY-<Lxk^y#7a-0<MX*p74m^7lF}-e}5s6gXPN!&p9~?%bgp~Px6)b
z?g*`iA0 at 74-uNaN2Rs#d)5y|Jf#Q%A{HBh!;Wr2(xFc%M?v`}9LeU!JCdc2CBTBC&
z_V4*3f%kpn(d-EkH;sm{?9hwwt20?DgG`l at U0H*BA2NIo!LM|^(7~-Ad%;;JKd2cs
zMU(LB5x*E^!jf?t-(k((4{=tvv*XA}EEL9cuEd6TEu!V{LmcvF32GmR+ApRD+<L-?
zCwCy5)e|vjW}-=|p9(U3Kb)X{#9q63x_^&W&;akF>r5GcqwIk!gY6APf;iaT;G9^M
z`GnFuEkxMc(!!rHB^n`0N|}J0p9^fzVR6TAFon`>L6^WV?or-Qvk)HI#<36H#v_N<
zZ-VTMj&897h?ugqn3JkjeWX3ESm0cpq%X~T4ni9co(-mng4$-0Ze;TX(KW_10dAK+
zbB_p53)V)2Cu$z=lt&yplwvPf8e38+?gTn9l8MT`8-h|bL$URz29HbkHp}yMFLnqw
zM|52A^22NaqxAEn1N>2xJcgCj(^hx%DqB{UyXy;Nuyz2--hyCvf0S7y>#QO*cE+J@
z6SbybaLJZ9cK&>VsNYy$avXsS#?&sxFmF^+IO}Sw=?@HttPr2Qih&0cV+IBM=MWY`
z2swEaT4O@|1O~}l&uV`90>9<H%Ob-3gh6-Wh at iA8OKMQxqCWHG8Ef-E*Wx3eXmceE
zxQzEZIvS!x<ThhH3mwfj!D!nx at JDFRvdH_CXP3}Y?Z{yKMp5gd0}gCz?6iG)0Mo8|
z!y6N1iL!X%g$N<ntWswellr~GXY0Pa#8&4*`r3ijf*Wpdv^M8MHztW)#A+IqfN;Hf
zC at +!Iea>{eCLw|*6;epcpNtjKZoXkkX*H>|L#On at T&{?u+d+~t|IVVcZ`_jOhlgGb
zy;wpl69$|s%&8?xkJw*Ew$MglTKKar#`wirqt7!dY%ZE^e)*>sK~~0tMl{f#?wqT?
zDlLR-yQ0 at e3F0)XXO;sM3?F$adJz$L*JA;+U(v<s4rqh+wshV6pQ#Z*BwDJOcu$~N
z at J&1Y|NaR5Ea{^g{;n~gDqa)e|N2KVm09sn>c-%pw}|h3W(jr1?&P!SvSmTRoRQ}|
zr7RwFv at OeX@sRw5FipO;h)Vx8{mTjb7jQm{?wntCIW at 1v1<Kgo4D`|Z5v*<#N+<lj
zAwcMiqqN_L#$W1*ggzh6V4>RYqtT3>S22bcRuC%^7jVPY3rlq`5e<cm`=K`p(>f1-
z`DBGpS;vgY<YtBU15T+o?vD+hu|x0~TS(OJFFBs=UxvN*FH5IR_On0Vaq_U+iTY at w
zvQ5cmtD!$)I{QuMN6&0HT7-+NBK8w0N_&e7$DQjyM7`@uwD#Q)WCBh*A;c7hHZ4&2
zMY)Ewyu7Qpoo?%sqlphR%jKg{`vKlp-{Zy0#D_-o7pDF+3#X|2OZYi{KNl@&u!Q<i
zG=Ey|ycS<9D(A<iFE^>^dM<=+2=_o2sT1j$%IhpjbPfIvr^f&Gx6!6Y@@VNrU|3*-
zFS1_v at 5B-+-NFrp9#2I#^@;hww+7d)kdznJa{9QRL>mw~slB_gS(65Df*G9qixN99
zoE_1#w(D7~*|EsqWonlhpi_LyjFrsy!7Z(LBWGp>$@96TK3%8d;^KKbY;bh#DuQ_W
z*W;^`*U^3`VVBgdZ_fNHrm1b~fR{KI_vb!!7Ct1`7K>rq<}0xUis9v4o7>^I+zY_?
ztHk7Kpr8T1rt=g2G<)REI-k77udx1lA0w|{5*RD~xP&s^++*1<x;-zJW6j#5Ny#yj
z;9Ye7SSUJh?22vpO=tF;-x2?HOH7nM;bMLuh1M`Mr^+9+5;|gT4g;~~6~VUgCx4YU
zZJxhBrB?IRdk2E|r(4Ut^bY~F`?2joGLkKrPk6Kkn$!a#Z`$vqxDF*AU1w_}CZ*oa
z9hFU6p^06!4!a*)8kT*K30pbe?`K{&ZQcHD&w7j=W+h}R`UlxO;AYQ?6bN6Zzk?bo
z#pd7eFZmcMAgx7gmXvtZ5sg=6OzH!qC`cSlAlOY(87z7D?^t`f?vl+f%R~4l!Q at wV
z2gMp<46s}8Z3j+2tLq&DJ>%^$dF^z!Or7eB-fLOvD-q*?`yd_<|C)&p#qxLbuv?dL
z>8eGCA7@^m53PjXwc9oyV|RW)9r><7d3lkZlYZdOaUR^|xn}zF{9DOCEglY&DcAw`
zfD-it)qsTnGpU at 3|Lxqv8BcM;UxhY1xtm4CwfL)VM%Q`6M2*Y3HwF?<l2r(}qJYTY
zbqy=Gs1_N1VHvgQs!}^FEF!{JNMxpK=K04Vi5&0I0rycH@!JdMMCQ+~&pZ|AlW|Dj
z&huu`{Q01ku6&<W5**R*J7YgJ0m)6!;D`qRM)9bJpe5W<T>7|ad^I;#4fbX|(fvl7
zu}h9U^s6mhQ>9@*4q(goM_|p&ezMw;p!u_>yP^Xr`XTr^CZze(He!osw&-Myam{Jv
zRyq%MM)b$fERpYF6f&`JLMO89BYDt%;SJ;Y82TxeR(H0Q>dO`uY;)4jeZX0!x6=H%
z``PwA!J$bpOYJTF<pg6+SVMp(ZTs~Z<LbQVH6nmup|->ku at URiwMid|41IXWKgyT!
zBj+^rm(t3zmJ`JT?SAIPMylBrFPss2!qrIcmBjX@!(NM}V-Yr#k8e-hfBU(1C-)?-
zuH0W)91YKUnfjmaI+SU5O=t?u%oY|hKYCyFo)ZYS3kw<E&XWnDyybb?`6SQ{_gv~o
z;dW8<9?}um_9)&-WVQCtIFvH*`1$R$s0a&myQk6D7)>I!)vZg=3;&bCOZOEiTI8G)
zb4_|EXJ7!N-E;iWkr4W~zmKXKL4#W}5pll)4cfj4Yg{D_j2<^{q|(KhvDL5Q#g8dR
zFGu_Ry61WRHE)F^H4IVey*?>QI(PJm4*?hFZe<FAe|Fb*0Lo^4Yt}ykWyj)zwPZq3
zNl&EHQ~sRqE^+CRo$>`^N+)=7(2$SOdf31)+GrA^yieH^)N{*f$ZELw0t0l at ckJQ3
z#DVsLV$9N75F+WHQ355Vd3N0=6B&CFjoTR={TUB`JC1rRWTGp2?n1jv(6u{`1iIx~
z)PUEWvgl8HWK(vfqV at YLoukpkcdrhEE0_i8z8`eGp5<v2!MZ>28>HJApnDQ+u&j7z
zYcJ<K#&VoMS6vVm^atVqbrxP=A=NAom*|tdv$#X~eM5+bCS%hPSNz(8li^b0&)s<_
z<1JJ3^`9>Q<_2wg)7f~Z*&TRR$y(YA^R6smr-;K$U12J)I5UG5e3(Z%3JRJ`P>B-?
z3oMWDH-7=jkrbg7ncPpjovaZ4BjPaPn>X0wkBAl5lJ*2~{TZ24yKb<KZjZNK;FC7X
zcf7FL;U>ax`;s7PP>|hEJWjw2<qLxUnGm)baarvlB&UiH({8)XJSO9N_XN?Wo1{su
zM6S$?hlZhxp-_o<hJoszB~!V}Usr@*a(EL(h96-l?LSRRSN1iNqweF%=j+z2u0Rgy
z7hYuJLOnr-eFNWMoQP|vYgMsMxT8bb?28#AbEW16D}o>6mSnEw)YYa>A+v7*oG9cN
z6s`8MJlOfV4dzDkknwt|FZ53WIS~MfvqfF|o8RuemY}p^L#+C9Nk{h^Y!Gkbzt at J~
zFvju%4G3@&g-|>(5qf+WK1|YvUY+?d#MnBC{l3=P77y5H#fCqkWDs?G7D;}7c2)?S
zT8C`(;Hm$$_lPdT&_OOqMFjz1fo`Fna+qj4&(~l&{rXz=+Q}hNC;DE2P%6y3<L0+A
z<}>JQpF+n<Tx9-2oO8>&o|A;s86n}BwU>bpKE=t=%(F>q9BzAmFIFKPzIgAdqs9Zh
z(C=5_o`^Q5MG-74tO+3g0@{6a2*GOG;d|G8D);SRG*W<Ny3s+tyr`_e)|yx;2SKBR
zP=d4cK)Kj2OiqzHW9H$#<M#xSKT&c6&+$jDh6Gh)<?1|8Ph0M>x^6l4A1-BHt>upQ
z2pT-gOYF{Yk-f`s!FnT#_4Uf1;h)6&@K70myIK;vY`mt8RV+blj$6|J8;MKXfmXb~
zIR{BI at t4N`&k*3vQX?^WR3?iXfaB`_!kV#VFazfFYC9uIFUcdu-4o)7Pjgv2JR!<*
z(<_+mv7G}S^5fy35!Y}5;zQa-f`rZ at 6fJ(!Z~hprZc^kZoX{E$;!CjvnGGM7=ap|$
z(eSwQ4tKVxuf0)-t{9dqKd(UCFwCzLLWAx)7HAaK?0dd3My<9G+*+~dAtcK-0*$&9
zXeKqFWmpB5ZDzlQh3Vr?pM{RUHYOLS108(}4F0}5^+5HA(EIex>uS1qiOC3cFOx?1
zjn$l!=#7-&99Sc*_nU+?1;NZsDmb2d6WnjIiSegR^f2oX$^RGa4-)Wq04YOptjFvg
zubvrEUL at 77+ooc+xR#z7{y9z8 at y@rMg?F5L2LAOsKg2^%Z-%C7aD5NOl8s$^_T!|L
zOOGm<CVl04K2Be~96x*H83dk-mv-#J6&Id;)V)Ttp5gWhe@@$Tpgy at 3mKP!g6UbUH
z{{9wtDGOn40KVs;+#H~y+&mj1v>mj3`D4hv at D(IpKLAD7U_SgZ at E6syGSvc0(wUiE
z`=0E_Xb*|4Mirx(`6PiTisDhtwr!936x*TxKiY$x#_~6#HDa~?zLxvd%B#tIp7HRu
zRxmNv_dObAI~_ObL>N)g*z?jJUDsh*Rz=`pEZ65zL;~&<C7BE`I??Zz>nAEB6P-Oi
zF=eb-4!VX|&p#B%pQ<F5l8FutP#%+8?pYkWQ6b)Q*{tR;&Ll at hg0RVR7^cH`=HYCd
zC>KE(qEsxPx3?Ez6rrUdi}h<);@(G|!t<}}z?v0Hj=F~L`*``)t!Qd&L`zE(5?Z+*
zwzq%aDElznAb_#TF;E^E9lf>>X=u>H2+^8F2v^KQ;QKI41IgBUAc%m#gOW)=sY^js
z6lnDs^q#d0*7ki+bq)GJ38)fO8tp-zl4ds1Xm%bDtI3&Bl=68kRBA?}CFx(wvgEi~
zNs^AEapyJE9C(_h8IM)3l?de1^dPzykCaShP{Ey;YR(=xFyx%o$|IV%Bs!J6v}!8r
z$)Ox#$}(|TsufId$Az3fk}00mlJ-Q>RC7otbI*yu-F7^LL5QSf;d39n0XJQJDY_2#
z4S68u=B+#N;8QQ)g7s_RdTy-yC)$w_KkxZIl-?Z4v_KXB01a(PL_t(cDCOfL+8PjA
z2Es6eq3US=;)mepBB=ZOp#48LBg`br(_a<9Y0JXbRhR%2RgEXhPSkoO%^adW%<<S!
zorKu3tavOM85?q9eBYPcmL%yo8A0w`P!F4Fn$UGUE(@C|BF9E7)8d(oi2$M#1!lz(
zDV|v}3?p`8CYnc at ra{xRqnw(ln57X*$#_Oa(=-@{5oh!!5?IhX7)q9AszW0kwej<f
zmnP372d#YMg at O7^3Yw;2|DkRaOE%h?8qn6<fFL-!JW<m$oU(c)?t9{S+;#sGu&nZg
z*=#zALZN_6CS7s%-b6Z+s;WXyCCk%Ml?Y+J1h^hx>4T$LEm+_BW2lOX!1ob2Wk)Lt
zBRKte_(1?u(=oWfQ9G^EaeTg{@!4_T_mN7aY90Vk(KC}sB;xW6-}jNpWQJ5Sk|aqQ
zokLQqF`*4k02IJcrDT&?n@^yVz%P%uPbA2wg-;wDh>f=7#L#*tlSky(R2wRAym=(b
zl2}HVNF?HH)nrFU$?4`LdK1Z`ir&iOc+QMi+9>Vi*!eeAOZG<UnHlMKN6I)2ENpMZ
z6EE(7?YMaM#aD6hx$EH$jxMgoo7ScVG&j`2cFKQaC at P+PaT~h3dvN~xb$G{lXAC>w
zWVC!0`!B781#d|^lt;D!ngVRw1HZEuO4>RCMDxWX=S~dj8Yf?X|H5l at Is{;7h{6bA
zR6ZbF3_=aZFG;h5R8 at _$GvgY~OcN#y!+>R3$Ye6`JTLx|j*KKp$If6<+Lb`4s;Wq*
z)8j5FtA(fud?Lqbj_32Dvqw{SC?I25)-fNAE0$MHl)fA<pZMe=a%6N}M>?GzSJ~Zo
z96xbn?L_XK<GF7o7#qLdn~uE`we+r at vUVjJ>as{!2L9)#58%N5gG1`|D2mY1)PQ-d
zO>8d#`C<v1x9vi%<RUdmlk*a$g<$;(M5+oX3e1Cj*!#6R0OhDf#%onI4R8MJAtZkP
zIt)!mRIs64cru`?{A}|nyO$*$`~9OR3X;hrOw+6x-&CA46Gagm$ARm*C=?3teLpTa
zk-{ZO(y=k<yn&sj3#L-3<63gT`$D+BI9 at bVrr~&waur8hA5R`}r<j+OnWlN%M+S?L
zH)&fW&1C1S+Ie6rmM+HXCG!9%=<Mmi*MImkytQX9JkK564-o?2M?ROsz(5YkWCF_<
zwj)9W&-al^TDanZv+(0 at d<8dOa~T}h9apfaTIME-B1EnS{lb&sFP{S?2;o^e7Txg-
z-u$QkK`EDqj|d at v5P%!_C>Dx%?e6=b{=@Ca8WuD^05VCa at 4E=09}L+;Bz3^-ChFU#
z(&t*JVwzbxordE$&@>IM>%y|isl-}GrAd+`Y4paV8b~)y6Q*fSnRQlkXpZFw=W0Bn
z!6j3r&YJV%cr?6=j*M8MI8}I5ZM6M(2U$p(c_3#dJOiJo2mqF8;)W|O!nQZ|qiEaM
zvTY~+`8z+td8e+%;*L2;m<IAi8?V0hCc69c_~Q at Xh|^D6h5Mh}f-_D&5tp5J29__H
zk01<TJMM%z1mbnVFhp}>6ZU`kMwlD^H;m9kXc?II_4}~zx!0gvu^#%e`GBs$+t-ES
z!_Pze&1N*%A?noxlu{1*KmH-26Bi&X6i4l7$)1_n>-^VReWLS=6^q4q!)3GCxSo-F
zN>aciNvh2-jP$ouHbvi0CGa_!MrSO1;tlNN$WYK_D)MPG=W|VlEQuMJWHLG7!y+bH
zhQ=dHlU2G_>;0vjoETs;9eQT?&#O7;Lp{&RrHk<QfASH0?kit|s;Jm|=rHd3?GvyJ
zeefX6u$*yG6x{XeM{(1;FTp>2{-bDVsE4Mia9p=SFN%{2hg#!E&%t|U0Km5$w4HYv
zysv%&`1F53Pg<~49rK>th2H0OqL|PSAVTE%$P_))D+cPc1oT`9+Q;4v<x^L|DHM-7
z#CWLlgybHYoqOK0thlA6mOj^t!gAmD<NA044KCX-Qn(~Znw*WyL3$7b at wBq3OydEc
zwUj~diDkS;W~z at vK9=hfc@&0W?8r=Y9!+QaBG1V<Hhi6qYaQz6VH9D>g1Pwq|NatA
zSkeL4_u&O03bu<}p at gFCzz-vMeu%xDJqRM8rJ)`G5FG16S)&O0^%p?-+9wej8kE3C
zQq|Dz>FCHsm_HC<fvsYJl0=iQLU%)GAHE#g|Mw9%N;GD0D)-Oq+T(^{!1sMvmK9G5
z9V=C2W(Yiy1H(@Qmn2Ej<ZNUyQbp6aro-CB!2pv95-4*;XE7Y_-jA^m1&EG?Eb)xY
z at fe0Mm1SwRIK5-N-bCJCo+C80ju-jj`ym?ZviO(3{4_Sd`Z}I??j`K+?1ATbuuK#4
z=d|GbGuC0<%B2W`a7Z08QB(AW`@Etkh(2^FaLO`7-~0uX$6kigGk}C2LIn`13Xrv+
zoVgV0hc8ET!+9v#4*bFM3ai~iW?&@InU<=m!uS1(p<^{UGt`tB1VMcE009Tj^Ww%F
zDR`13jl4O>Vmx>>oz9S%F2qMRbH`&c?!(V>nd%vtYR=eXg7u-C;;Ek98x90dcUv>u
z`iD9-o)3>0&;5qG=5S5oW4(X1(k1a4W4%_bx^z0oK(%Kq2OkuivT7MlK5-em!A5yS
z0ZiTazwMpRPUBV-#=jf?K?ni^EV_Uax~V!81|by$&%lP)=<D<uShC>-Sj_BE7f485
zR7}U^-vY%DVmo$l7xcI{j$=EJ5K_M1W;9I34%f%`p6{M>&w;8agke- at PlFH$dA1S9
zG0^m()@s0SzoPQ{pD_OT8x^mWlwZcmcZh%a5#ho#!iOeeEwwD~yQc5QGc)fG%d+6Q
z?z1xq%>Q->B2+4sB*ddPIFp~9o}O~V2`RuZ4Ag41QVxwSWMn6O+$M1mVd?$`{Ww8+
z|1aIKUYhxi(>O^<<bEA>Jq4>DThbd=j+>ZyN%PK8?(}9=Y09$){h8^Xm4Z8Zx$h#|
z%DR@`z*R3Bp5Dbze^xJ{omVbcj{v^pT1AfeTM;B>&dlhMlYZtn{hW%zQ|V;@2&1s{
zcTAr{DYDC6=V%JQYtX`@0 at TI|@M#4d^_E32-!%&DHGQs6|89 at 3okmAS{(d!^%@-B&
zNmf^J5cGq!a(+gPZgq8)YMGD%lu~$jcqqL<>M23vJRwOc)u4Na=wtNUeA>5Q6H-iN
z7-OV62>`|_x|d}~{ffSELe^N{_u>0~QuIT9cf&9+H8lm(G?O*Bmk^L^wOTEBo|iP)
z6=5imUU3q_FofrMT|z{}hGkhvzlUD;7Qq~bA)3u*$35kDkb6%~P9}NqMa}Sf^_dx`
z=uEEy0D4q;81|%BF6?K1$tzfp|DpnMR at 0agJ$Ksec1PbU`jkZGJ(;6kRLv}kA}FO`
znr27ph&0k9g!J!_W$moW0xgHw<-D4_XXBPyp{G&loxF=27kwft+VRvkT_kcmuH&RP
zj_k*ddfAdVH1c=bwv(vLIFC`<*)BUyqjHY)=tH_MQ`Yl3J3GV4$w^mgonaW*+uK96
zT20P8r6U`<(-}n(uCA`|`SWK4LD2EJ$Hzykt*v2ma}#kK!*LuOA0PKjKb)ADz|PJN
z78e&`+jiHz<(WiL1jljk<;$1Ecj$61OcT4iyQtM_9oH#ilX^sHls2r}Ufwg+?Nt9$
zL|?1b8cMW5>`BC|=XnT%0AUy=>x*nM>F-85S_dEz89@*rilU*7XS>~o at B8pP55DiC
z)oLX+q(66_y?P(WGnZ;+W!J~FA7RSHZf|dsRI_xbRCa7GFE2Urg!HjnrdI>ZTLeeF
zXb);qN>4C($gc6l#YJHyAQ`7|jLKw<Q`s?+`S|AMrf^b!&$gtLLKH<KU8BTN0|3``
z(P%VspVh*`0=BlcGNTcm=OvN6GU;A%9AkZbJ at en^=jTzc*8x05?6$YJdtOf*N!N7~
z0i7kHB+9U{v5|W%+qO}!*E0oK79z45jRri=dlPnS7zRw!#MRYRsdG?EOH26n?OR8r
zWS9{MeQundp2p<lWU~G^j+0ydSdJ1nj?+<1v!8eGxdKd at 9Dn%mArUx^<FF{eJ3}JV
zvJoTaJ?G};O0AEHKtDJ*i1+vRaeaM_AP6|Jgb+dqA%u`uC5~gv&CQigySHr{M at L66
z^VCupMgXXg2_b|KLI@$xMZvPnp;Xz-yyD&cJ<iX+qVBp3_Ypz}A%qY at o-bvT!tCrU
zepsntrdl1Yn2DkY=U at MVdw>7G$WJGP5JCtcgp8K^e}g5fAAcHXgr?FhX4+`nH&9^}
z2|@@Vgb+f=08mPy(P#|3VqTY+F-;RQGgUk?y^Ih-2qA<JG63Q at Ms=n- at N+X}x0o?d
zTmByH^EO=fj%Q{FA%qY at 2qDi#DTUdY8Pt}Shc9LTpjxfs=Z_x|MiGmd5kd$dgb+er
zpk at Hee8p;Jz*D-}Fm6Z)A%qY at 2q6O%GnQp>GzcMt5JCtcuTC7ts8lNbiy5U9EX%_D
z{5(gI5JCtcgb*?^K~omnwxN`Q83X|i4-a|JpAbR_A%qYz7AU0<1Ofg5hf=$3<6K|$
P00000NkvXXu0mjf{F7R-
diff --git a/plugins/kimchi/docs/kimchi-login.png b/plugins/kimchi/docs/kimchi-login.png
deleted file mode 100644
index 66387fd70adebc3b20b9520974a127ea7faa52ac..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 318041
zcmYhi1y~ee+cvy}bPCcbNGKA5OLs|&2}mO)i{#SXjdU!Hgi3>y^b*n_%I?yzgt&C~
z{=@UW&-;G|HOw(Pb061z)p=g$L_gP6CnsSd0f9i|8qZW-fIxVnAQ0|1A_Cw{-{zD6
z at Q1)sOI-zoz5Oa^FG~T=5Ia9JbOV7%X>NaTK-oDAz)3=P4INd&d16{>;Rli}0?fcE
zMt4;McV#C>N9&L7AZ1r;3wP`H9G>>>b{y&&I?vw*Q_zDz93Tx9#aCW4TkW3BChE{r
zZ0@{nyXxE4f63Mw>5p4ZBbXn6`}>jR3m_azn!C?JKOKZBJUh@*BKrJdYC(ZS<L{q&
z0!Yg+!LVvNj9aVDr)4eG#CAb`EUQw|%~N*6cvCa)SVo2t at vdxZJWICTX4<n-mCbic
zWW808X_Tj*f~_}}uwU3nprF8Ef++Zj^-wDR%Tn#E+XGhq;?$x^h~;Tjy9B0U%EFND
zVH%0RaL6PCybOH0Dl!RGzmIJ{u8hh2e?MpQ*&hvC46DKrg at 9Jm-#J;onsVL at r?)gW
z2X*X*ij?yG-vfXHNPm{&Z1d%g?{fjVLY=tyZhYWi**kCMC*OaU at t>=VY7JCcjC*=}
zCE^@Y$gftU7lPG_aZC{RSb>GMOT~S9W6Dun;4cH`%qHkzu<Px9{_A^Iu!=G%@g4Lc
z{lOwx+>@h2iq-MW0}}-?TwIW7X6=90j7c<s{&{^CtLM+uKj%svCt{afTJ!`kg0#oU
z!)%Hvu|g5{MhqT at ur^I=DbDY{4o4vi_ at NNoIDl=;&<JPSTV1*9N<`*xZ(KyA4tFD`
z89!Z6Vy4^zJ~L3$Sw~e?Z5sVGt+R_{lH4EyCn)%ipmF|p?2qt}FF59VEcA*yEjbEP
z#*lz37l at mffQg%6`uM?K4_D&yJ)_=(r?!@Z1+g3KMv=KQAYEfOCbi-7j!uhv7N5p+
zsETny3W9Yo0TGT>3Dyo{{mGo<^8%`4ND7GGM^PRV_P#>2^9ADo{PQbWqT4<7h-0!M
zi=}@YW?_dPC-OZ>zf>C~Vtt%DzEZ_LAIzE-yWioN6HijPoW#Bm!P~eM at _oxSN51Y(
zlOLLp&#aSa<MB5RBA*;QVw~gty}y-<@L^t)$dtE&AzzaAvekI^_D*l;^#t2!wGzyN
zW3o=S8BZL&K%R40d?xLIp2LL%hjA9AE_ZFYOGm%WJXTQU(l5^r^0JYKtFd5e1%wHt
z8AI5NE{GN%lV$$4-i$n(nysDA4R at f=jkbn^^IA6E$Up=Xp_}{+k1>o0a@=|6njHsh
zoI1q^VX+P(>XCN=Y*j5j5As?LFPq(pq8!%qqf3-$Qp-s=pDiqTrFd-(EOxPCP73PG
zInyf{dcN2;n0|f(zV&u#4{^~_`z{W<H0hTx##^`7qLYAbp>Cd-vdNL-K=()57yBGf
zW$&Cei?2{tNz#ONe>wZDiU_?!VJ!Z4pn{|yG%s9$x%w1kM!IArw{R+s#SH=FvAc_G
zJn=df*_!Jhr+K9wFB>FVW*V#S&w}|Fh(CMs!F-H^Dd3YCK|cdaS(v#0mS}UjFn$N+
zxb1{HUTaloP>6_vs8L|kPMS?(fpE;ljw7=5T`1#68?jG?Dds=!86WPCuZ)Iq?#Z47
zv*;A=8FwuS#a&d+6Hq`Fqx&ng_6gZLDC(mq5r+jUx9<GXV~fdAeUUs|2?*_h3ToVV
zN#wzv=icbMyom4X<Y)6R(@4eYU>(ZEi0XiAkJPGbZaJ4V78&Se)86-Y>`Lct-)fyP
z?FOBlafj9I)V#Bl%P`N1NYMror-0obE|V)yaBW%i<elkvj4wsED)ckg`kMFg#Fs}b
zrZ2Q at DR(aO$CrbTs|#xO-nSj+imx1<qtAwR1DW(5w=r~{FEm*U22Ec(8a~k83S<+4
zI9U>%qHpGzVqW9vMB<Qv+-jlM?ajw0mo?UNcSJUpMuw|<UT5S*_ncIt_2f^93?}gl
zarn40>kpK!{t*V?P-6eEqjyAToSM(Anmy9m(kxkxq4WLM*c0!$6HD?q at 4e@JUk^<q
z#m&5N)(s|M{EG~I(B1Q=#*IE4bLIF8rhZr<`B-0`STFP_d*2`4-+QC-*IE@&!Wy5o
z7h7KcT>fTU$;r8F3qTBfc|V at -TOl#R27gqWS9P4a at 0C$3<p~AQIq-fh|3|qr9*8v+
zkl64)i*Fj~M>k=qJmrtXD7>V;y1iM6aj5QdctgHCIExj!xlCY{z+SU=ze`U*2j1*!
zdHs?n?cA5{j6!RvIELJ2Wr5H;ib3OnH;2s!Lyu~0MziN4-K#Jw!GvsGb=Jc*e&?=Y
zFr5mMA9UZ|RQ3R8o^<BpC=8C=ZvF_P6(|bF?MlQCqpm}icj41^xLw`H0bRzMAfqX9
zWwh49D<Nw&RPZi{S&tR6nk=afKRm-T2*d<hPSug_wIa;opp-IUvpaK9Zh>p=ZC7XW
zXWg=iO7FbyEO?LIJtOQFF}7Rtp(?UC=*xKi<LGI#%?;5`$ED%i=@Cx_V{WWvNt|mf
zDBgT1M at tNk2Vu?`6-D=5{NeA=?^kzoYPKn4uvg>D9|H+YT|~yDM!Q4hKZXPs)Lw3!
z?KJK7uKpr*M#J7%thD&L46rVS%lT3))cvz;+gSfIAsj*Yv6Eg%Z^oeJ;60gL(CdeV
ztC=-3Ne`A&q at kv9!36k+dj5}Z#{25^!{Xmg&qvH6=EE=5GFDni=|hOlA6}I(<@Ua$
zTnM>lCIyL&m;?xpNuxr5yKK>0Y=W%u!(R};5mlJ~wnFX{NU!NeP-_J@^4my<X8LZD
zH}9t!dhIX2a~Tlt3^gQm>Nj+1#gYDaPMvr91|89q7u{0K<#n>~&KVOrZn?T8jvjqP
zG(CU$a_(Xg8`={oABJe#@o8&2{^qrnzN;u*6&yeMp!sIq!Nrf*WR>~0Orj<&A}oTa
z?$(+<IqS$j_ZQP~P~9f(-a^&uKTIpY`0SkS`?GiKq6;J0l<HBv3+=wOw&QF9Mh$#d
zrh^!n|4C@=ObH20&SH3Y!Fa;BLw2*WyoKM!41BAXd>LB)G8y|DQZFvv&^GSmb)gWZ
z at xvqWUYl9@7TE4<yJoN{s+RGoCq-4~4!!dY3k^;Q5g(NpPCstu at L2Ebj81}kzTmvJ
zQ;j%1<Q}E{nA8J1P?Sy4{x8q{@x at s(`1?Ig+ZF%aA1t8)R7Ln#S}&*^aK_r*`8!-M
zS-m9f%%}UrS9(`Go#pWqh<Ho`aI2BZ&0AN8&L^7#g(Biz5&2m9JpYgM3w|?M5^G2L
zkharHq_kwh!QgK1tZ5SoU2fEQz!nwPzLZFzuk?PGBW1zP9ikj5viJgTb0L{VDw_eD
zsPE#U<ZVa4Ly>=9D%967 at h-QeY`EY2I2nHC&0uTnb5BsF5cl7#*TGnPCO1Ki#p90C
z5P~vEib~0Z0kcMzu|ZzTkDG+Zg7LoSvYZf3Poa;fbCMi$Ho?w|7df&^xYCX0mmTB=
z*bzD7tJXfRsizrBebo!0`A%ZB>qSjV6 at 9PIzM2OCy+*=v{77-4Tnru|g?0=0$&(Pb
zaar*xwJ at rX$L|`=G1HYCVdi5wlE^l1(MG353b?TIq$<7j!bGa(17nxIdtQ6pg!?_D
zLJA0|alrYSL9;Vw2#3i{C0O*fhLy%Y0SPDwV~lgm0+<qIu)-ZKvqTHm{q_1!QJg4R
z<ww}!?Hc+>l08|HcstM#gTNCn3e|7-8G)!Lqm5&jFa(X`8GXll_BW3H;hi7?BD+WG
zVIuC_--lt0{S0<X=9ZR4-?J<#^UNB!f^&n}4vs}U&-)CD0`Cc-VqLBu98$?VgA<Wh
z(Z*5zjq5)3JENTt!&PJCI|icVx_PZi{kho{kKdMwZBLynzK!i_2|C3d^CN7-yBFlU
zM&Y+cnAnpYC<B-j$}o4q<+t5|w{4s~_B4EB at 2ub07(3h<^GKKN!?l_zO_e<7m0hHS
zeMExNV9-X3c`8l;QF-tK-rTs7*Q8`*ze$B97DF(96el0nZ~Mw!ao7b0vidB+4?~<U
zH4VSvH<(m+;{+3s3{-WK^N|%zE8f=oVu$-B6HwL&k*9E#sRrZo!<9~E28K-6$GexQ
z!`47fwKLMnrNUQykI(NST726Z59EDkF*k$7ev{jK$9Fv|k1nJ1XUD3FU9B*Whp>t3
z{hD?#R99J<=+%z9zdkO{_S%Xyz;6J~&}L42RV$L3ksB2ruFTB6s?kkp{7TnHNbWjI
z*{n!TA5SN9<PjIC^F_FA*XIpOXwu5&#JjR`7EdO+%*6p3On!IW*T~w9X$#oPZhPKQ
z!dWbBz**&N4cs^ZBV-mME7V3*DG?S<N_w|FY*!CdEkc}OpDA8P#w)<qTbln=apuqL
zD&h%Fl}UbAFSk8bojm=)&7+8)^moa*V&7O$ofg}V!vDRb!!c!@&7X}iROXS=Y7+UR
zbdOYxzNo;dx7{IM$@)QG%Dcwmu?UyJf7JMdW<8HRugDU<GuY-mAFxW44;s)jPSAQg
z_Tta at ZQaq%-o0#I3L)(w4{e+L^5;Vqm at 4%}g>lPWhv^C&(A6rhe0TO!2VtiL8BkYm
zuS)6Z@}fOFf;=-Pr*|mrk$yE|f2)2R7epsu at JYxv;sw(i{O15Tsk7=X--UntJt+*U
zY3DTFKk?)`y9iv#yX=S#WS<Q^OvKAk!!!C(XR!3c4*ajipG1w{ctEXqxrdUE at 7Q9N
zTnv{Ihpa*ZO=2v$yuwR~B{I8V4A##~Y`UIt6{x|Lh?inYhz)x3eEQ<YrcVLU5}3(u
zh5}bp(SGB--nL8J?8}5)ifwkWpbNn*HM}aCASOJCjpN;(JH6`lsIZNvljXj9xa=j8
zw&+%eQ*`<d#L6Q0igqH>d1%e4C(VJb=maUgci2vwb})Rl{Pu>CtP&R_K7VE8<v|l)
ziX(29JK;S_!1NJ^t;D>*8AdJ!WzO5^Ht^v$?euxH<8z>Ug}KS7b>&v5H;qI$7Hj(H
zaN;u+?`;t<ku&ElR)zE%!E^{_E^>H6XA^u{fIBJHAGb8T{_4Fm6zej|{Gs`90o%Vg
zXWNahXg&6!?YN;{Q3KRus1Dy(;8!lV=Q4DsTDfw4rR?;EQ0~-<Ce2XGW$+lW++zrp
zIS6I9oTsDAz|PD%k0!eytNo~({0`MKFJZe~8n4NNXC?vEw#CpeI5^mgF%+j9wV?sN
z<3wIPyw_Y6yT89bx2w#rT5HgIyXk>9ei8|I#U at WhwLV8xi>^ADT{8W+xxg&9R$Zi}
z-FB=DoRtJw<^_sc9wqy_hvpnAgba5WR23MbN)@?2KhP=O4%7lM;rBR{bs!2go`RGw
zMH!V9HVb#V_;4e}cBlS4wx1BY8?ce!kWCREXa>qIEk1OvIBv1SN_*oJrz%Yy)3GxJ
zJ?Xs~orxt2E=@^4t75%(-%jJCi0KoXkC0SJqW0Xz3nrGCacW#02Y=H6+3-cxGyk(r
zUL#(-=^@AaOu=f;E`Q**F3j#0-KK@=H$dJ9a%`e#X%&GB_Y{zD;zw9;5QS(f(hb+`
z&F==#6CfJD<opL at yzFOa^T6e__cS4!NeCFen$X|@W$tnjVQu!V#}F3>zR?L_?Cw&&
zhLNrq=IRIf(jBTLXXK>F(Rt at k7Qe@rFnCe2x at ngtn4Zy_Bdlv9R{wJGp!3|<<7Sk~
zD-z$j5_|W0-iRF&4kJ5vJ=kEmki~nLf3`nvxhEU_*ouhim>K7{Eo+5Lb<?8iE!sD&
z1k1 at SOwI9s3}LWp33=p)Eg}Kk?&j;7YKv$XTl!wp)lBp0zpGvC4}6kOmpccfV;l_z
zSA at 9LSQ)HjMa&sH-p!o;9FmGw{^js%!K^a$7IjQ-JUtQitC|`4f6 at F_`J9S9N%;TE
z86>Fr{z<i2C$4IAghS`GN4<cWmaaV|mRTBYS<B#oLlFY1!t}W0yphwOq&CWHwl$<9
z30Hc5u6~Q){zDXe&)T%)qQS at U*j<RfzC5)uH|MCc{{*D!y7Pc<VNPFO^%SYbnllje
z_xIO0&Ne!SP7M=q6XD`3f(Be_+&5p4QBr;j`|#h}&5RtuDOe<efGd};4#x+Umdt-_
zeRXX}ZTE?L5o1#yt<L6+-&$pLvW4>6 at 1qw1e0d~Kmbta+)EeI4xog_C*F!3SjuSO!
z{TEgKKWqxHOt9!YgB6*y$5z+Z*WZLCB+9eH9{T<PsEuBJptn$G_opqj4|x%zS%N#;
zczMEzhlhu3_Z80`E&c!PXY<b{LP6YJcu{@Y5ohw~jayw;q#mW&u~<I?Q#^s1nwpfW
zwahrY%0ya3Oe}10P{S)P@(wB8(o%P5IRazQ;dck at v=G<gwoznM`E{~rtGtPWNZ4Uo
z;5P;;#uP8il#>3a*r76jEtRv5({jL#?PO<<*7<*}g3?BgP-T|fjcFx_ctihTW-f;P
zY9QCZ6)x at aVo?2JA<SYi_7v^gB!i1?^ITbvUFRgC7>|e$As9dG5iABh=cC=Lbn?eb
zf8E7sn-jb}+f?}Gn}wYn!)%k&K$Xdl8VG9N>)#jNNxR?s(@hJRoZ}H)04a1y0qMN_
zNjXVIOG>~po8J6^FFm%v1FwoifFJXVBplaoF>?1Z3;YDMx93J!6EMXvCTBr6W+az0
z^FY?&)bzhQT4%p7LS>L1KP!JMay2{N1SjUZDvc1o+Gj_L!4;+}X#VLe<vC$NC2k9$
z!@5kmvh(q-T{7bs=TBttpsG!0W8UNAybb8l)FhPE0kIG%<iDA}<js~YC`%DW^<2|s
zOmZV4EpOqZk$FFB+>fbamsIi&ez+!MZxx&ZRP>IIUg!BP$Ie;g_)3=BV(g-vFRiKg
zByUk+$079<91H214M4XWnBy-83NifHYk^^LNpDuQnk{~ZYQ1*iu%36?;V)ShO=>9Q
z1l`zf>&~6cJUtsS(L-<DQ;sI2&My5j8u!2P1Sy5sfRy<9o7&^f+0W?xHtR_KvEkt;
zJ0G}Akg?}sg6;9eh!n(FOAFzrGWe;%b_CilBX_k|x+LJ)uOA5qPT&^f7>^TL;kR1!
zOc3KP;!Tk;FyR!-`DvOnNXa0&={v6^uX>oPdWY_PQy{{zB0IfW{U~#}C3-gD<d2__
z(pI=^ZQC;S=G&h=&%o1`-^Mtzjr)a^*SdetaF|HK at y;S0OcUGLJ8ANz2D<VFZWx`e
z|0eFAbYj(wUH9)XWWS8i<8S at yI?RCE8Qktm*;U;0MY4GBiexNs7+Rh#>owoe`2^@i
z$vSo;*M{m1rb?WzK$pDp+Jp>|dG!Cc+gxo~%cbw`(30H2X978K-TXBP42kVLs79V{
zuy at PCAJzW;Ub~X);Bx+V_-y6vZnxYl;bVb*Y56NT+79fUx$`X^nTxD(%N5T+JT10s
zUcYnRYEW2F!<DArQB!p<soCWtzu^}A{G0EHrTyybI|09&8Q8IDh~m%81|D-y=KRM^
z%;U`a4(@raPDa*Pz^5d(e@}@X$0hmN0kv?>ead$)t@?_WDc)xb1NiXGfe;p#{c6dn
zz(C+&o7Ej2_T>)pYASF*9Sg-<I9#h<VdbTQ_*)PutKxNtM(7A_hp~&*UKYgO`KAk3
za-`3jYi7OJqH&()k2Tj<;DSPYE*K#wM3_i3s4U+H7o<?E)7G}^0?9778moH=cmmv9
zdtk4vh41f&rH7bNzeU0l_aPp6KT|$<x-5CzA0rq&Zj8w#&$2WH8>*QyKtbe*LD&A_
zw~5bRgW70Y|C_l{?yvwjx%kzf25)Zak{=aAL?XH8d<=W_VvsG{IseB%JHj`4Qk2ZQ
z-Yi;G9ZWmQO%_vMJ<(2qSXK$AWrmxJ#Lk4L?B`@R2Z+UR(#nB7dU?yUF7*YHOVoz*
zHt!9^TYLE)b?k|%-yW%1*KXUk-`3@#Je+d$+dj-m_TIaWL-w=D*zx7fjc;C9r*<0B
z7_u-sgEl+jlkM41Td++0HQ@>Rd_#Pt;pKRjDt!mfF}?&5?tgOgelLyk7lsnrSbCxU
zzklskFpO3VtgL-oD7TsDQJ`vD&5L)2^ZL_c*cT(4usgfx?6o^yzxxwA&zhPmeFy{v
z9lHkPju1$B2a&kz#FcMm?Swxd%mswbh|X)?ld1qNK?Aai%b~J;RQ?t`hm+OU^H0rQ
z7+T+>aar2z2VQ))e&+Z1voY*KEQ-E^f|qQke`5hlh{RraE^h^cf~C&hOpg*rSS(Gd
zv-h=mADYjCf!tmygLlcxdUZ`HZiV3P*81TnkoB@}_y at 0ulyPswHaP@2-8GMCT&bH{
z?|vffJ4K~b<A4wx$(5!DDhWyR|L$4^7RF#Q0D#Yor%&KrxG^pC?Toup^-%=Oy>^2X
z)pyF5Qm5#G#T=1 at jTR1W%+pvbdlw~67b>>0?_qx~4K+S()kfj|(72295pIrH&&2z~
zy=+ojv^vJKr+t}a?rPzw7qG+3Z~g!Mknqmzwx?J5`s!ixzajBu-$g9A5rT at N(K8M`
z9RDHgR?Uzn%4IZ75FDm*C4F~kL%x}H_hPTiW$@tPTo90a+=oL-s6kQ at iDseVCV^bK
ztWrV!aPi`RU+Vh_h_OD&`0r=G6V18_6Bpx!7Nw%iZVq^z`=SUCq at Ym+f0l9qqiFGY
zXD(ef58;~Q(6e(<LYF>2a+_MB6wn9u;tG1Sq^RXWoLv=jfyE_KezNy{@iEl}j%uxW
zkC^-4*5K{S4|~_3IL4P0pwyB7)^HCAf%=g+{g~jsZ#6bhMsmH-V4V<Uor3S;;LpNA
zA2!MS_IBl?V<X7%#e#MToq0SPG$me=_&bZl(7bc*dcaTzfh>weFIy`M!(e;ofqpDy
zo#*%4&N|Kdw95Rcw8+>iwmI&R+-W<Gz=mG#V2K4gS6w;KYHB0oOBCtWhG(aNSdxyt
zaG~N!JMNu}kDb?VfMjwBlvX2VX*C?1B`EvVJ;=?;h6`ptzw6Jpji6v03#F&ezmOGK
z;-u0F%NT^oeZ!@rN+l3D`@xF;y<OtDQH*t{6t2A8JY}FGlqd}sr$kEgHBHBMXyal&
zNq(WWp?H6ZdB?6^k~wadf(G10nQR<_!ck(-Onahh=7!7W<t5wDrMUDG;7)1pq-aO~
zi;<N4Z&PM1YAK4A1{-(!$B+^P^|-M-2X$b2itQw4;AQAi#5F$lNZhRFuuL$_La)cr
zi+I7Kkzx at _g)ew?4}pF>jAg){m0){O%F-?akIGg`&GJL at 1CHyxZ2IEQeo&f(<Ol3f
z?(Z&oQL&%*9X|g>A*s<?wM=gs_<Dzpt`5F-DJR&n`ob$O|4d4gUsrnj=;zK~H{G_o
zyJkKh_M0QK!u_Pg<#~FtAwl$S`N2Z at hNLxv<tr+A|BtwxuImsniiGYa&6j3XeoEH<
z;5<>9re!{Qa=)t#-Ows~4t%de-hepoVr2=5g|1MuX1YARWkRw>v^vFj1Bw0r86eVL
z6u#t5XL^WX9~dMhb at n3=jsYF+oh)8b+1zulxL7-d8@>t}U??wJZfLre3UGo?Asfml
z;zr;hY4rs#sRj3`YIEnPp0auu`0fqo8 at Y2_3ZH>xu6!9*Uh?N{&L_|_Wb$ia8S-jx
zM5Ksk8R_F5_J5^}X1_Px+D)BaYiW5&D?R)1BAX%7vc at 5$yrnBSb}@SVACuh8277<-
z;te;QHw7d=ScE-3g1jT#74uYLyGQ?bW%2aU(rev;$biece(SO9eZH9#ZYP^(xr at G(
z>yy(C_89mQ3X0q&arLMq$l!F-fLISD=S4RE8i~UppQX&l!8M=W0}&DN{1a>olhgG6
z`uTsFbf7#RTdsEAU^<adgb5)6nuvnAo6wtKFA)1$okv<V0;Hhl57YJr<u4=xj^D~h
zos+JIiqM^;Pl}O;+3opL=4~vSVb}7V4=)$kJLt^!SP4f2iqbB%mn8)=KPuYFm4EEv
zrma%9FybK!>VkH~;gXS?2jgXA^JN;H8FiZU&(vw#5lNY0Bnz_dyd;zvxKm3a{QIMt
zVa6K)y8SPD{v;dufpQdVGEq+*ra!Cc-&_PD&;yB`A&<t*LK54q#qh;i#z(9YWh3gx
zq)4?g1YdUnK=nW4Qh#v(;$80s%A47*7yl{JjbR<=))DWd#9jnqiK_#zh0L!ncx#*%
zP1`Q#cl-QL=VNX2=Y!-gisifWuTl9+GY$)6Q(}Fx9C1qe?u+ITf$!{yf4Lh>bJ}Nr
zyhqV)Bt*29_OAM=bVu%yQ9bA;!;r6h@>@j{P25ST>=#fFB=Ahjb|t0L5A2uUvmf$%
z<MG40U;mr5rk#BMKx|fX7&ZCn9vj8UUr)(LZg_i*Itb!$GC_VspLU$`013~hJ>qt2
zLNTo-8ndbVurK}MqK4uu3G|;oTCUpa-lD|+fGtOxi`8aTN3{?RqDNWL2*+6pY+$?T
z+hP at z$hmeD+E0pt>UV_N|6UHBFJ;AuKO^ey4kgs*qkVFkreC^c0M_JB7cdNAmG&@q
zc6K(BvvPK>F&Q%c?;{`=BTE!m02B1^-Qnck@^%$~*qrRl$BK^20EEKJ>y;tX<2Tg^
z7nF6z at -6jU_`GXp{zqB*+w^?@+On6w+c=DQw?{{MdwUzy0{<5vT36pC^%ZIK`{ddZ
zhfa{*nXu^>CX=~2L*Fv4Aag%I7Q&NVN>*AE1YGVBekI#I9KCW|vIzSKeaa9IPnVrN
zVS=eTBj(R1>pjr<2~Nwn?z_6q-u&<HUg%WXWNEhwO1)u4Olt1X=YF%SCEEM^zTqp3
z8Ykfa_o-<Al8>oZt{sy$`V*5-0d4T&L&M=22w5RvJUf2D_7w|3S94&~>VLHWVsXmU
zoJs(;$eie!N=8ahL!OPayMgaZONZo2P)Q+i`NHna7_A?5MZ6%9CuD{T7x31IJSJtr
zvRd_zQd{8>{n@^cr23^Vc0XQ+3g5yMv26ZQAPs=N0VikZm(_TW!P}>>gAtrc+c(JH
z?yr=&@$U?OSX*t#*GE9%wl5s&EvO+N1%%k&Z5P!UG|z~)6<LIZ0?j&C^}Hx=j*~V`
z*tohQSlj$%O~u|1Dy1c<vBGp+YBUeRFU2*tVSt=wK`5HMn07(GCqg8mNapRV$0G96
ziC=0Ou$sNgUV`nGi)XcpzH<N4<4f&@U2BpMXB1#+hpWl4ezCY3@|+Ph at i-N%dhKSh
zlNUD%<P1Ey-#}d|MB=TUg(z#lq5cq$Yy56HxfKHoOYhGu6e!4gINhQz=3XRNRK}+k
zig{y~9kG$;OCi*@r}RTbM6u-+iBrf6AHJSRwvoP-!XZ-tIy^VLRBRG>WK3&}*mm}d
z>9hPxdsk@!0*3D_$BCqBmMDws5N+Aiqf3X=h6-Uk_{To&Ye&?$YWxq=GzW11xa8JO
zLzf9F5SYijmDh_yYp!0oB6MoiXO|D^CZV)iB`RP)g}Y;=vK(jTYZM}!_>GS2u2KBt
ztiL{)6i>QBh;SSifBY=fuWq8-1;bQ4>>)E-Kdg&4r8F5)1+tmv%^KEl24GcBV6NvA
zEAw2;xCQB51aXB6c(AThiwz4aL*a1ShiN+XsF{MM-S$_4o-%InYQ^7);~C%DL;fB6
zV9v*dtDaqE4Uee(ydLc7ud7HnUyrKe#6LEAEXoWjCxS4P*bz<I=u9P}7zjvujC1?@
zYquwAC3%pvvCGh`c+N_zFAx at 9<2EbQ9z5C<^*l!N`wR{2GgO=F^V5&_kt$XDc?c=@
zSj#E7qfPUdd|g!Q|Lko=;~o4SGTXCiS&3S+I)IfUn}r}0Wmp<~yLAhz>}5p{9&j?&
z?N#k&kCWh0Pw6Wu_nMU8_$}<ntIn(!F)6xI#E;%ofH?7ihIM(vojb`cn_#w4y5oJx
z3&{qBpD6{a2G2F6-#=)rg0Jv4Y|{kW)DtsJ>=BBRam_U&8|P<&zhh++jrKa3;|XM3
zin%~&d4mCbvr3OEj;HoG<s>N_px+<9Qw+xWnFtbm>W#2t(p+;Dfbqwc?M9N~%OBJ0
zov;pUB2h8Sj0LY7IP56Fa+$p>g=)o<Gbj>B0}G_bcLNfp_?sN&N&#LmC!qTHsjocf
zXX$gk&-K(r_w6C?ZT*ItH7s6Yl5|9a0e^pqA{z7K0dH$iC=B3I*HQD-exQeBcG)P{
zaLKx*efW-c=Sz!Us`=NNH&iMd54lf2&H!E(%?Q<bZ7FIUDo|q)r(@0K=>7}oC0k<;
zhKVM|?~M#XG`&$oWuKlf54cEuwWSNklguK|r at V_II%VrC&49*Hh17|$M?>yYQsRRn
zEZo`H&H at H3N~{f+)oi4YuZsHPmtGwYl_rPk{FX}Zw;5tubOMVw_*FyhBWl|q+}MH9
zP3)?LDB2HB3+^*T5gjIts2!2R<8>(^rDqXSf5l at RWH>*g-Nan>(Pr5%NOY#2SH6Kq
zk(AIL`>=lYS2mihT|$I%WV*J$dI*KQ2WY9xfu;C6<|+6*wNko0ECa;yW(erth{>5V
ze4Olf9^-L58jsQ|!sV1W35|5k5 at fCg(W_?9{U3)K+HI#smFZq49iIEGBN0M*SFO93
z%RI^XcX at IJVWlXM%woE?`-+sTiE)tkWl at y<Tz#b|h(`@S9pJ)pA6K85voH_Wxz<yE
zbM338&Mk!xmQLD at 7=Yu6BA at ImO!dE}W!_(an(TUEH*L72txH~fv6A~|J-3>hSQiK5
z2Kxp7jUbnIPe!>5RQ0XIS<`$^cu<?9_naJ_*`t>5_a`%}H=gX;gvQ_K^l+UfjDb9I
z)o{SannubRm)S)wIkz;RZV-b#YVAKAQp@{xIa*4;ShIMeM+erx7<{gu4|U4yUw6KU
z(1)z*m{$iJE}xK}-vqs28dGO|A_}BpoC13$AO)N`M-{%-wD)?U%74cmbIv+IT+DYR
z6}c**>wseisv(XTHRQ9uhyNXvxmLI-w$!Y9X4q#*U0RA4&vO*i;~*Bq5mbmFawiX8
z=KR~rhPxt9g!St<Tzy`|=6-{>7f(fVfY;lnHOCkO6Qgea86mCX0`Wp-nR%Ktp?wOU
z|83rp(0w#e=HG50&?7dwCzWWkk16r!ReO)V3>Y{T1N-gqf%hTJXwLeif!B24qN&sq
zZ5?{%fNSTvWyHB(N`}syA9sDNz&G at TdrdSfu?QKpbx=oLtp5a7{t0lpRhK{H%;#Cd
zLp+XEa??n$nHL6Q#q?l(H|Skh!_xqsIOct+#h<;k%VQVI=4fxzzs_T{;OnEnRcHlZ
zPBTcW37Rs}2`K~?oy2Bo1k__%S(!zZW!5Ie9?!kDCC}~G2=Y?l!I#r0kmj*@=O+Aq
zB&1)!D<LuTyX;;AowGdA^M at H0U={{la#cHXa%LNaLgi3OdY=}2+oE8b at AxksMo25)
zE&H)vhyVkrW5%T}&E2v)@cI5?+2Fr}q2e=hTIeUg8W+~j&CPw1I&rlLgs<C9xw<2U
z2`;-M^7)QZ$mMai({&g;5-hmXA0#99?%a>o`Auxg!d$hnaoT@;C7Kj3p>YyQF8^g^
zF+(q8YLsUuOUn{&mLI9}atMza1tdIVZ|=${E%=~085Oma00tlUxi_P at H7NSX-FduU
zB|?6!|J!^&H7b>!LGIaFgxuq^X>w>AvEixQpTCHR(RsqW#@v4y;a3b#!zmgWp;{(X
z4ALyQ`%$G=`1#z97TMw7)`hR1IEL;S6B;RpuF(pAh__6CO41{CW(U0|{tWX-7^FI^
zWYLyTv};ADoyy7{-W5cQORi8T5fx-t(+(mWVD>^Cf=n=HiV^}*(F00R+E?#9T6_06
zIt4c<RR>vn*##akcZiZJzmK4%nC6T815_iE`pmt)5|)EOuemCp(%MNeo!U(<W^b3Z
z6k}SLQlao#*h>m&JznO0A9<v+#(i5ZA*%b#Q)1FcmGD(x3ogyaMM#xeOnSVZ?8BJ{
zb<5{*bq!n2b=1}D4v<xvF|Izfjy&#Jtr(9r3%K}`oOpp?T}v)C{*?EghA3 at aT{eC2
zit*?J1s6!sv`CiDFDVahlslUF1c=oh9!FN`WQdAAYI!g4piVORCUL{t4h)+Rt1QNa
z3;<nYT*5s4qG61Y>`h_VC;k?)QhSdpa~V|rbKGzGT~{l(BacV$j&Ue)WDu&)p<NH<
zCO{;m(Ms_CAdFS8p-P|aL^Qz^H-{-`_+gKjkvv~`gwlM3Ed%n+q++*}hlgJ>t+KgB
znU}s#fJ<_+^85RHZIIO(_utUT&6OXnD1J0AlO^s~35}T0*S{;&YpGGJj*w(sVl*=9
zNroxvr*6s>$4QS`ha4+pwJ$CI<a4ctG^0Eda!=z01u9k}-4KOrlnp13)?i7<POQ6)
zQBiM!8fv}GRtv6i_3QUsX1i(e6&t&0Iy1&|q_8%(?;|{$?ve at d5^rZ4b2AB(BX!cD
zThHpL5oZlhZ5uf2bOkS3G*?IHHnG`vSg?VoHnA-BV9`-=2pA?z#x(+?mS3cz8B>wX
z at hjrMy{BjOzARck>gqVV((0p&;5z-fGO4 at 7Z}sOViW?Gpu~4xsBdy^LpK>X-^-&lh
zjEdzq1JR`U1<pEL#l8+ljD>1GY}T%)h)s<|8Cgg}JG(5+<{BsEJuaGQou&1v<)sTk
z08h`AFNH_MaO0=)iOYo{n`vCK^qwz&(>JogLe!=?7v(zeYr(e((mUZ$4OwBChL7 at S
z{^N`+>BC%`r!-Dx2?8M|mV%7py#9##`Go%b=&kNEz3gwcQZTW|r#iT_uScus!S=4B
zS^Yd?`%x(hp2Iw`4FW>2&n;5X<bnQ8n9LD1kJewv&!d0Tvq#-4_NV$vfy_?}gRfzK
zc37B#2kL;7)oC~-cGkhJHo#?VBcl<im)usARcg=5d`~X3FDk)n=KeniMr(%YNMUt$
z)nM8s0-P&JL7s at y;&tsFxAr$t+K9qkR%MHBTu20EJ^=`a?^wSo-6e=BZY(<#Z6*l{
z9A|qj+$H90UJz5Ksuaz_iJy{^l5}B6 at j!Q6C<2+Rn_)e`^-zXkKy9ZM{wVz?@jJhs
z$8 at n4e+WbrQ_VI~7&_U~Cuok&WP-mgLe9)H^cL!Y-qwGpISHEV0yzuKiPXtO=qFlm
z)oWSadX0|yZpd3nW~FBjVSHIyw9JM>E at CxFu{b{=E6HxY)?9B|mrwiY)o%>_ at O&kZ
z+?#c(Eh?QT?$JNhbl^H0*<q>a$IJ_d_bFkfh}v?${?AY460uWGU_-=NK<#ZE9a1wM
zC_;|B!frU%OV0SiO|NWPmh`^7QmQqG%gEYira5+Xjc#vvsf5}WCa1xJ5UIWiS!Z at 8
z#2}>`XmrY=yC{1E3mWX<EUevfce~u$rxU3rYU)Du_!}?TP7=~Zn%byJ(Uy?+AR0SI
zOTLn2&y4SWMSb?yd?kA_lt6R+hqz^4py9=rFn_1Bu~bSb5P&~M{6dC&>A5%0(aEi<
z18^6X)Zw+~^=zIO?*ucH1@&3y)_T$0tnX9DM05zVc&`|~JJ1vQrmDTN;lkL~rys>l
zMU~c4vtOB_xCiZiAypo1oTS7XtBF&>_#9oBm|NVf*ueTTR((9oFbUaCKGxVR43%39
z;t{iceO`u6w%B7*W=TqJ9bE1VvE6W;JZQxtq)r7l1*tM<oIrbP$F`fq5uOk6<HKr#
zvyZFyHLhiB?!p9a^s;3hR?!CJVBG|2H4ey&4<c<I!UQ at je&;E at hY#F2ohpOa_${he
zz9D57gbPc#CmXsWEWMSc#PsWiYGi2W1SIm}+qr(|H(?5J$i<)FluT&TJXKq6bb3e>
z^894I3HE-bG2Uen9xxwNidQ-xw2;6ZJ;}ZBjMt$G&-2K3G&_89Qh#ga`=hIF*>Pnm
ze1LinFSTc2W`-k?3}o=Gn0t?E0<kxHi$_I2bbl$vv_d-eeFgx{_b5ypy;+t|@$Kkm
zHuR<g4u`XHD##i9I=V6h-#6YsI(~dDk5UOYMIT+cD)}|FP*|E8z8Nqttx2->b%9)z
z7`}xhID!q`SP%Z4A4<$lb at TA6^XQQLdJL;*$(tH2&6xWt06AFwc?1KRV~^&8v5Rh=
z#|TlalFoq2{q{NySYlnx;J=ZL(a_wF;Ooq9=+Cy6B0-x!spal=aPAfsW28QOH`?I&
z6sRE**5?`F+U^h#YI$xghxCeyL%_j0H0A)7?m=yI<vCd;>vHV9W4_m6&ly&*j9m8J
zmlM6R@&23U2`dd|&YSk?puC at J5H(+l_A&i=T*u4H>(YIP-W*WT17TbU89g+Tlqt*g
zVB+E70ca(;zpV)=dUA~4-d6VmD!~1vP)d)V2JgXscWF>jh+?I0mR|Z~?5??7R%D73
zF_3Ub*xr3gdEBm+jl5W3oDIcH7n)W_h8q6X=zsld at E4^@`XiM;i}EaxRo{%K1@?$F
z7n(k`Dy7u#8+||<M<N~jbUg)WmrciS`<EA1E+^_r?sMbG#Oy5>V at dPcOg=&9SMx8i
z$B5>C;y`mJJ&pXSKM_z9o%~3pHVGlpA;A_4N&d`Yh*YWEAGixEzv4{NdDWSiHN;aX
zWm_%V*$WjA0`8Sf3`xEyT-$U=TgR?ii_YJc7?%LIPJj4ERG4psTCs9EAt<}~-A21j
zuMg5C8~RZOzu)QkZ#L2R!e#K%9l2~cR6>V$&TyZ-aMG^p^g2Cf<W%{bHq!XpA0uqK
zewV$aLb33+#@`d}qb@~9*Sm^TVfjMowh7tz=v4~i<UZy1fbvF|tirIK01(<n^X7p{
zX#ae;cX_f6 at 9@8@@xMGtxa)OAi01LI)%ohqmB**@hlHLmMW&lq_GjLP#c=v#BoOg3
z<I3NSwkHt%_9^JqxAv?HYhl&p-7>5Yuex`0p-g?HZ at xi|$9vRd9?({^6N6o=Lgx^i
z(K<8DN!6!AJYO?3=lCsYnOg|jf2!?x33!wxO824B55LNFdPz)Bf-SFa1R%Y(g7G at 9
zDD&Pvf;A|SxU_C<TBd;CZdh=cjrZ_;8P}!*A22PF!piYltkTHGp+8#_)~vZUe*VN5
zyy*NS2DZl-FfpUV<BSFptik%kyOG1#Xv}$9hEC4noYP{>JMh&4>p-vt1MA`-mAt}K
zL(MoD*2$9pJ6|O`C5?-H7Jo#SF=5Jk+<FmaolZv0;bwPjvLtGyo~U>MRtM_I=d5gs
ziiBU8RFhDd6^Y%y_?SjiXzrvArBM)nB1_#!`e`Ir)rmGz5M-6!$Z=C3>b~{lj}0Ll
zfF=xoy2^xf{7|ZhBi%Y&9=H0hO*W614(TJIs5ZYvO634cSHX=TWjo^o-VgZaRk at M*
z=ezxjiInTd7z7-^D+?=kWBV3OY`Dxaw6<L0?dFcl6NWUd73xj|KMm)uZ<<gcC_ldi
z>!Tk=>%3B5;|A+zL%r{&9)E8?fksI$%lv};`gb at CY27rLcmykV`6C2&ZQ9K0RZHdS
zT`PeOtK|(J)+`_D18LgZzWu08A{)hh?~0mcK^0uLrMsh-8mTj9%nIFA4*_~i9_d5<
zgD+xW*I&>)s6f2V43kh@^gHxD7#AA5x_O?4z;34L$one;*zbdl-}n=2Q8=qj$M9CU
zW_nTR=hU7C?Y}nEjRWTY at PE54wX!`^4VB#~c%N!sB-+N8 at i!L3#B#%t9l>L5{^m})
zjd|7 at +?Mv~fbvT#q#m*HkV24g3q=u6?(nd#?D4C(xH$9w(b<tH8~f4Jy&t>_2(&8S
zHT4LSkx@`sZvHB{rA7Hl4BEUz+)V}^Rkz^|xB!5ZfPmmutp}(|Zn;}OKN+%iqx5?p
zh;*iUfiY#z{F8C at mC!ipijG~Yo2zq!8gm?$f$p(fX=;2NV+6TpXIXxLlrf_3=K4|^
z96i4t{PSE<|G^1GMx#Wfj76%AEWeB7W5lwZEzO^&5{Wh at sS(H02#Z$K`$4?uM;S9h
z;PzE1mV}(PfVwO}S?uIbwJnDdBtxwmlnEx#lIKlwFv1NsoUZ*i++J3 at 31!6q_MAS;
z8nWRzlh;snyvXA6lR)kv2o;4(no2l7OrK#lq?IW+tJXz36^H8-;&A(ANmZK65ss;1
zln-=5H(JVB<%9KYX?;gz6((lRqnW0fsTe!I0N{y^XF`mekTPMJ17}1M&mc%7E at 32O
z+q)dhgj^xB^n<j)C!di#8rIMQ#Mx))#DSH**joE3o~^kS(cfMNCZeDm_g at +e?Cb*x
ztkUM$Jiv=px-$DJKsWeN at avz4x{_<OGDj222CeS=>4GLP(b2?YWMt-p$q&44&Nl#w
zcb>43^(+`*u_Y=DYH`!83sI0F0|7wOV|jgXT;s?LFfkpwaA7iIzx_T2Ha3cqVBQ>O
zTtJY&L&3UsoAZIKwuC?g;u`wG36orC_&x?%dmKb7<#kZ#`@jEn0sb5hYo4%wg>1=(
z6s_vJKvq-svwrgMSB&WS{z`65StV(&iPj9!wxoFwN{vz(WK7_OC6FZXL+XGScmX-X
zto?gkbo`Jt<<a%pHsKQhi`ecs*Cds&T-(q<g<ZK(t4Rr}l~w@!y2>v%<+qPi^G5cL
z{&9i4Z?Rzmdn3*^ZKk%R($jQaSyyjbPJP3=NuZ8qv63u6m6a5I at PzB8z>?8SvVlo5
zQwNWx0n{!N(#03bB*>FXFmz#>s?ADsArTXPpCmXu^m}OZgOfVDYX++VoW58z9i0G6
z#FuknO&)>D=+G0zI0qgggYwQa`1HzB)vJdV_EK^RZz>FeYimVhPUqap-+W_*h1%3J
z?x>xQy_zFt_ndR_0xH36$-SMdZ{&Ki2?9JbLqzbce#`e{OA#1GgwvZw{rUE`7$~WC
zXn~PS*zG?k$VxXMJDF#b at rQntaDR>0z9pdJC#00w0|9Z?;`(5HJU@{}R{}>*_L!E4
zll50!xzX|y=Gs?~oH<37EBmy^zchV at vY{^K2hVc74(3OjqkTUerm}BE=qwzB+OO$e
z4yw76mBQk$Msx^ae6oRenQK`-7~!=7Np1YqD_zqjNKuiAJ!Carmkq43mT}q5^F<8$
zyLo816p_4sA68yB4{YktAr)dSpnlV{#WPDMH7}5-E;?nBTlG`QkjFq;&u&C~CLs(6
zEOA(y!<BpergeP2J*2lqYRE|!DEy7Sttb}3MPaR$Q-O}cvui+#wEC5;&c=l7-62bs
zQXz=xj6;pOL4s6Jn<`#Ol!Wgen}AKIh<Rc=bJcc_n{>)r-QT*t?w(xl8&*##)zoOx
z(TSx?w)9kEmLv7an)aU^WGn5e_UCUZjqda_L_|i`+D#S-yWTC)pob=35uzF$nNM~X
z7xjm{-Q8*BFHz$)ZX3G5Gyu at SwH^J^YF<s&0>+C<rCR9%!5iKNO&?i_I4yb!?2b*A
zU_2chkeLR4<D5Ld1C87K*d21mYdy;rcpp)k;8}K~ghs~We=PitX at BU<gf?{d at A|nQ
ztjiw#Q{mDWA7?-M9KdOKe5Kz)0r0-RMS0(tYYss_p;Xegchcj}=BLCkfZ;I%xUdSJ
z8z7K0GIDtlh53+Q?g&HV-pih5sJ4vBSkcCKkzwN0;lQZ)RG*q@*+E?rB_%Cv2c>fS
z0*Erniu(Yln$fy>4j^refe at r9`!~;8x6L35;ERe$46pLDx_Cyho9Q~~#^YS0JcHt^
zlD=1fCa-dzc}a)M`{lDKF&d0DJxTbOaMCV(pE$}U=t+cYOGxks;?(cVy5Q^@R_V6x
z8b7zo!?hT`m8x94jo0Hn!ZbK1Px+bTl#5XyJVlgw=1T(2HD&3k@`nm5?a^Hh-;J6X
zCDu}30+yBX`Kw|Nyp>7L{6SY+Tj5r}$+&(;G9k3x_cTI2&)TrCSWHX|f3^{r1m3C+
zA at i+IuM*lcVFnQik?bvayO(kRT at 1`$87P7z-PYaza`Z*%(q+X;AdBzTC4Y!kw@>Wj
z9#Sg&RGyML at H#a at Ow(5&fjJ=Nr*gf9&rMqkg@%4O0PQ<E3<ORps<+d0ays5rttW@;
z7{z<<w^|!ULjYp8I9TV^%D%Q$iic)qndeI;W|92bci@%g;T|4`aZ>$yw(kkYLp)k+
z&zNAJ&-qB1lN^~~&3W`L4t`9qHpwUUJ~yUFm2-J-l*-z~ss-0+)}}4nPxrdPAN{r#
zDYV-_1KiX<{FpWw`Q8wnD8}qkr8}Io$z$upQ?ne6bv140yeZEvRh(+z=Y6f=0}fyU
z1bk|s9tO?6yV{RI<hUU2k;5e&_8*huLnX}cDH5Tsn|&smw@|8h5L5RYC+VdLtGS|J
zCA$?FOxy{WOmvm%z?^%Cd6#a>Oe+-AqiN~4 at pDm2Mt?~@v-~j~JhJVL1Qu&~uGqo6
z(HUy|C}&s2`{t9ucP>rdL2O28sP@!htklnDV?slK79d1RAv}r=cb@{Vl0cNzo5KaN
zqI3Xolm-WFW<CK)<QXm8wVMwRg^TCPQ-eIZ<MJjD0DZOBC9RQpBY&R90sN&?l`;#g
z87go~h2$AWw%vB84=FvQ4iyg8f38|g#pjv5r+NBTeU0c5c=E~O<_Ml-GNg4s&<6LG
zA32KENp)h#;2J5G2O4O;EXGBFDDpBdX!Yk`aej9jNaR?Co<F2jAPU{k|63ZY)=p8~
zo<yzp6 at U{O4^E^Sd_ezb(0hc840uEg1YbjI{HJd^K6A12XkvH~1sgwRZ1er;4%bKF
zIg)O|wqrTZrFb%I+*x?9U|933_F^%Naa})QC<_}cGifwTLJlc24(n0ds^!Xi2C#;@
zlZr9BfW=aws5*)l(*TI6i({7L7RoqEg(iCsQS!vY0_;?LtyA6vJg1OWA1uD;Q;P$u
z)<#>>m&xi{ahWALG(O0aD+^yOgT;GY8(5{hYP at u=OR84aP)$avs6KAx_smYyNw1st
zM*a^;sZsL98r+^<Dwhl?Vmga)gT7*WHX}7XUN`>))&Lctgb82_*ueJIKk93e-0Us}
z*Pm7IN2ZKU-r^-VLZr4NwhF^KsiiaLy}x(gv(%dZ*{d&45m20>ZcFe`I>o%O;tX at V
zKNNS|6CRNYw7!xunXfFX4fsO7(_HeG*nyci9=CFAvq{F?;ZPwBjx~~(j8yym>0fJt
zX34Llt-wY9Q^hGU03O+BM#a at H?+Q8K6ic-ovI~4DhVObVw0SRk(!hdU%i^$ImPkp>
z_4^pxshm;)h>Bqz;D<sSh6C{oa<t;XEBu9j4L(1(yUy>)^jh7Yr#^`*Sf9M4u1+JR
zMFpTZt*yDtHX!eTF==woFLh>S?~q+y7 at vlf5Tsdju~O!rbHaZ{2sT4f(>GOy$e-b~
z2dUEWAB1_O2t;$^kqjbL!A^AEuYM1D$)i?tzx_xeR(~BvlST|6`VS{r8S#H>*c>3g
zrq3$SrSHJ)75m<()qU9Eh5WURs7VKB^?RNKVjcHJv~Fba5v0-4Gp_=Je^^0$2E0OG
zL at s*z^r at YV<W at -!T;*WwWrZSpiQxt!dfIjU%VtmGJ8J5DhKUN?ujvGjoeM<RX at K_w
zHl`}naVilQWU~v``dBXWiNi7^`CmmW1Rx3O*NpZA)dc^m1&}u+-1KGxYFZ*7*<R_T
z(F=2&E&uZYct3_L at TmM{51+r|Z}W6m(k<hADwbPZ at i=|g#3tiSzWmp>n#NViLQntR
zx}$nKJLJ7=AQP+t%|ps;xSsrZBk_Z_ml(jSji}cygMt3+oJWYcg*~c#c&vvfQ8b at B
z at n3|_FXNo>crRd#x3+_!8i?rZcsJTQqBdPoR;z&_bmd0w8Amp^HONpnFah(fe`)bK
z!=D=ZZ4CjI?(^E#acn%x^0s<nZU8XtF*HQ2x~vx?qwfA~yU}BUNp!Zn0~=niS3p)S
zwpfW5g&pM%WQ52PUOh}pkd5UOynmpkwj~M|zwi3%={VjbIi9;KeS|GJI!yyt2 at hXb
ze=0)wg=60bpnP6kt9qvzn`Y^EO&QzW3;N^!yx+N|nW&xwUsbjX$EaINh#jASJoof7
zMVUr6REfxAdnR11ICyP1!)jwJ7un)wYal53H7w6qErAkTOTwsUzH%C{)P?h0v(^Qz
z2Cyosv2 at G-zE$_%>Q at BlM5Lr*0BC77o+q2s>geJ;RM(<e5&{qb;eaClQ~zs5O%lo&
zE43Yh#~5yOf4sq};u!l%Cmte7ZE&ZkpIm76v4cvn=F4FOU<=OEa+-KCu>O+_KJWqY
z#$=CLMMFw2&rsGbFS99&N=_mLJ&fC=k&if25Ufv~@e#FmXXRO4bh3J1Z4wma;u_A?
z$Mb<T)+!@h=a%=bN=N-{p_&?0%S(I at uFLCu3)Hlj7i>qc_~r!F+W(KH^A2b0f8V&G
zsG6l#%$lWDGd67%wX3MwBevMoUZvCswMMeT^a6){8Y#NK;vYW&XUdtJYOTm;E=
zPR at Cr`?>Ge`<-54y>7tk3!;YKA|sE2EWuip4dP&*YnH&apuGRJswC&{or-F-l%o(y
zOKbmyW3r<qa;}KB&TR{#7+<m|2uM(k>*Z&hza(`N0BQQ{rEnX?Y}H$7*KZ+x>Bmzm
z93mEN3}@yvz at S26R<gFRIeRa##jxXw)~mylJlQ37<f at kqY&^LrP6otiNq?W?{HMtN
zTay4NUx48++h#N3?*`UDLZKzg<_n=A+>6n(KP4Pomt7AQUd?#T2mB|-073&{)(%iz
zq~?GLW8NjwA at Htza?!^`X$fJMj%oCAzPJpd7)Td=SZ(lp07*%R#6)mK!s>bx36cIe
z at thK3%4<&?q7x-26-BiYMRRhjHhqBP(n`n;(_jkqpVxziDGR&+336mjOumv`+)0Mj
z1p}59Hgcb(`sIohRkCFo$GrqU+LJ$A_GN>@PB|Ek=b6g7UzgIyP>9HW8|g=Y%A2i-
zU*D1jlBEkExyhsjrWxQCn3sD2FI?jAS=CZbz6F{cHGI=Naq><Xl30aOx<mtiBn>?(
zfhbLh4Lk{<!G4vkwPgyhUg<NjV1BEkOOALFm2c-_ObZNl@{d8|ON`zVMBfE*rnwG&
zhD at Bj$_-W|`g#)TYGXQx7f%~VK(Iw9&`*Mwi|4|HM}aGz`Oq(ier at z1g0pC@+TS_F
zYVr2pe#CY|c7`fRb~CV=98+oa5D4bsdH{0;Hd+8C{{I$a09?(%sgd9He|5(yrHgRZ
z(|88p_7+>$xf#;)&4D&*j{g>L6$fi)KY;*e;Lirxi!qn|=JVH+r|&wHiQ0E-=gHJZ
zC6D}o$tCLaJof})VM-|2)YD2%ZpaM-A^yJ7nKbix6ti{9E4$&JNXPBIc%Duz`52T9
z_~0e?lCcLow$$*#D4ymDWnRNH4yJ8dAh93C^epr8f$9@}_HY#`8v=Rys>U&3E)oHq
zb~FzN at JbC#bP{Vgz^?AqbqC!D%Khh#vXWDn15dRKAo7au9!InRrg$8L{k&d^0n=Fu
z0V4R85Bk`i=J(c;puKOOIuuhJtgYC~50#?SY3{l!OUiDto<SQ<gM0xOvL*YwX(t{o
z6P%uTZL#@%PH?n=j0B<LGr2-LhAkKu?+Q*|-h=s3!JnJoUAQO&SXl96aJ$|MRvH!g
zKjMn0e!xcbHRAoR;2iTmzwevBf8 at 2(1ylR@?4{e<ss@&^5C9yWnozp{OJ*33{72TH
z-tQCW48}d1*-v=47%#o3<j-DF{Cxl0qXJk>sck8AJs-twp7ZP*@@qn7m$HO7yl}7@
zcnp1M2~HY$O65OQM_Jur at ln#==uPrzN_n(fc%k-dedfpO6(|^}-o3QxGR~r-)o^6V
ztM0#HCDuNMCk`$ScDw%z_)<Tb`vvyhYl07Sn8*7Np4YW+3!zH&Oa21$j{-D4VD|Dw
z0D5K2^YBd~3$K+G6=%rcf2e~EknPtu0M0>C!m4><O)QhsfAh*CxX6E0S0-BRAjsF8
z>U6-ff6e70Tw0**#sD$AmDEEr=~1A2PemnjmFXqu)PN2*+6`q@%0ehDAb`VV7uNxc
z%Fh<J{Uf0Eks&0XQY}XFllZws#93hx%TbxJEN4<sMWKqA)~d!T6`?*My&j*m%FsNl
z=HuXtrNyqiM}ENj`@mHH7eslPi+5PlnzoCJSB^)uoLb`9^AEe<um_Q>k+6&deyQUp
zAQN;M{M&WBS)#~)cep4OY-*#)04Tp4kuamzb%sxsXu$rmTZAB4Qve82^<6XXu;K at 1
zXNMNr+E^xa=!yl74<83-DFo0FyNJXOnfjT<qnJ(w+}std%ysprGCzQGq6}EFSt!M_
zobNTLRs*c%VbGF)htqY||J+z+aJK1>HfyfSaMv#RPMnbM`NQ$TR3Gr)_IiF}BEJN-
z_h2LXTmiLgqbqa at w!2EApwqNpk~8 at A{vIcO$?o3>5PjcEk<WiB$dGT%J~I5gcj}u9
z;ZE04<o|7CpTPK9_Q7_Fx<Q$I62FuN;nQtK_T%WhtAEPB=yUsM*UZ_sFOe0>BUa}L
zK-ULy^v-b8{S<YbHwC7?w}pYM%FvaB%;pNpavLjlepW#5tEB#jP*32ODr#wI!pTF#
zujlfBm)ccY-I)?Zwt+E8#$7lWwv(iQP);w7^8~y4ROkco-zBnAx$pQJmZKD+4`kQy
zIwH3b$%z+WyLz%w^#6DnF3pEu3hS?2kXkK^1OL%CcIgv`^Q4q7fy^)a9TBZGf{~Y;
zs&@ogSW!*)$Bk}*fu_*urxEYxVVp5{9MoTG8oid|ha#k8Y;<OAmQwcZEF#FFP-+=!
zLe*eJ^U2w#-1<32(Rja-6t_+<2NNQCa@^=IPI;c20>N+*3!v~x>bpf1q7s#Q8?E(C
zr4q3{R(t?@kTR at Zv?fG_?U~F~5supFtndI%qdIO9N^$20NB9q*v9G>s1e|v{pchC}
zq`@*wlei{hKzgnX+qqxV6N~_NlYMa9wVrGikhgAmXr;=e+<9n at r0aP!5UrQcf+HNt
z2LC9UbW_7Uz|9wON_YUjaTZ6K3XgP;XA7^pSjyk_ReB#!w-)dD?Ye;{Ye`BeOR(+>
zv8^Y?c>O~hb@@^g`Co#uYqv6H_r56N^aZ<B6Q@#$yb>_ at ZDz4Pc((5Fvw_?Z$BdKZ
z7nWwAlAzlWcaXJ>jMRE~GohIK%@3U}QDRlq&oL?uDIq}h?1;D~EdEd&DMTmH^xZ?H
zhp^GxB7Urqb&pyziBF9dRCX8x8CCx%34;M0Rwq=J93*kh>u>}esf!#PLc#b36`xK2
z0GBOc-aKA-Tl|fq-zWj|wM(8%4E}7$NJpVA&oyx at l)EflRmbaU(;BD?t4w0e74iQD
z)WiT;xs-mq>7So~=@~LgY58FH_=%Kn^REhJc=55Uww5FA(tp1gtBcPy_L&g$fyFt<
z&b$DR)}y)=JQ}RnhsN!ex%L^dI=T88vaEh=P24H-3dOI1&bICj<a3>X3>ga~P)gCx
zblu^Ea-UhhKSGamf<`@MjEq)dyM0!Plit4^4erAsh%>zp*~7I(uD#4^#PK86RZEI6
zPwlg1poz)W|30P;1QK}eYi)BuI3zfNq9QSpCs-W%93Hf=7Ng)_k8ReF`>n&jLu0mm
z;&n!ZodmcyFGm|**;ue|Fpi#FFL7{BFr-=uXmMU7sI=!Nvn2hfeD>(4G_(_ at LJfbG
zehSzPtA9O!2-gs+T876Wwj at 0H5LB-yg99inOJ*@UXr=hE5U5 at R2#Wz*4_QG^NB7l=
zO02AbNz9I{cxRv=np4$XnZ!;G+WWXNTymbM&TP{HciUG6$cD5&DJNemb~$%f8Sk96
zttyyC`hb{bnLG_x|K!?r$Y{<r(Tb_RaTrJ at UO4!txF%NpmmHNt?3NWXfSQ(f8E)s`
zFE*r8>)>xPFW^M=eO!$C_+`T(DRRY^3(<>24T;PPL;@t_e at 5yJvy`Q^(O?%{=(70Y
z-MZYzu?Kv2?=9XaUcZ+NZjZ;Bjo*7YdJkpx?_SS>z<0ZL2k<)~B1Xk~@=Em|U)tTt
zj at cG(r8$UKSQ`pNcv2IpeZNmyGaal!_qXtmLltk(p)7CCL>xD9?})G#0ekr0oU;Cc
z{-a1m6R=in#P at P)-QnjNYft*OI@@`+%DQYHPfA!@QRz(?q)2uC7~n=Ms!y!|*%{kq
zAd<4Y00D$=f4GXib}m}82cGA~!{`iXG(RF$Bt}r`I&yI$;2f at IL$HOYbQ<iVGPjeg
z3PhWS+BczIjT?k0 at k*&Tu<oGM>{>ghh-Zr9NONWeTbLMp0Q>x>3B8%WinH`Wm#(ww
zL~lP at jFti*AXiyW$KpxQ2<Bu|Y~atD?J4PTB_PvRUO%{&?IMk1+k3s*XRLgsU*GAH
zH&OoXWp8GfYQUH$p6E0IDXu^cUe}{2yinG#R}gBXXWI<&A#92x_yY at r!(UwbUjpGI
z6igMnTp|}dgzglKJZ%F07cJzdj}a!OWn~oOqn{lvJ1Nq<jVFSm4CI)fY)8U8Wb7-V
z<aGWs8y?sgc><Z05ut=Jv~r~fxF;_=vrPePj}xgpLgUrJ)wihvVW0dNC*`ONq0$YK
zd%EM#f#LXZc9IDDh~|F?uevPM1M9ElmOxkV$4Z1!AwZWk6=8yQ+UjH^LAXjFl at K;0
z<$7-6?Hhe;o-QXm654tB)*85XpTJ8V{nP^xhees+>w4*TRJv%5%W$Ov=bqfWCI3;a
z^t9HmUf<UntWAj3CyFCa%T{FtDl^!=)5$M>Ijsn{?kFV5ExYH`_O3L^JUCm0N70{!
zum<{hx8djR=ns{8+=7i9t&&``jY3fdfi?lchi#v9Up0RSqBjv$*LeBZ3vHoGb{l%=
zJGnIYEyyeIJtsHkq2K-&*vE$%rg6ljQH{0|(mh`J*P at k4@<xogE5vqC at 7F1e1~OCs
zDFwd&Aecv>z@=}UihF2}I!w<bfM{`-05<S9|FNf;j0yWGu#f2o5ZJBvI5!Q3skN8H
zbSAUXlyl3tR~iA{@Wm29H697mb}RbdcpxGZ>c2u)>Lp>Mscwv=08-O{tN<9S!2e32
z0$}hPG5lu;MXD!tOg)Deini#1?T)p|p(EEUX=snDaKOn(4Cr8A6pPkP<>unb2cuW+
zK8}h|y#6DgDdt-Pc#$|<=lg^bE;tIKZSSmby0XnFXe(@S3beX24_zzHybc27NL+Py
zd7l})EDgl5df)z4hI~(h_y;}_uG~zInwpx&?D6Y8<F=rRyaO}l(k%Za3f*+Uasm-e
zmbARN`#{t`{&T30OXY*u51=iQr@@Re1xm|9jk4r`;F{D|zfaH at nzJXPoCwH`)*zsg
zahtm~!{312_VY`8SONQBcv}-74H7S#pp|QqZxE5Zc9{{d89q)s*(l!BDL#-sb8-ZX
zQS>dJx(qNN#J7onkBok#Z2x at -4=jV&L66R^qY~;@tP%_IE<GwYJz;TM5h-hTJ(Ue6
z{vEmKyWVZknz?(`zwnzAIPyyFTENx9;>op%HduHmHiBEUS68m{1t&kN+lI~<?$M8I
zU>K8OX>jO}tsoD(mOGo<F|1sc+`nEL;1+h)%_hcar)2HAmu{<7sb1{ZUz5`4crIV7
zSN<zCaHBSGbbh(D&DnR$M5fGX+MtHRu=we8j+$1+%Xl231fHMaaGy1*VRA~>!B}zE
ze8#=z`xPcVf9iesj#DWSUT^&WO~2&Ak80X*`gkImFcAv&A>A*R*(o!5{lp^aA59B)
zd5idZVNu`3>#CaXee{LhO%qqcd?JQ>0^Dp2?$PuR;nOeJ$xt1X&?nATu8ZOI+IDN@
z_tu8O8ofqq7)%#b75nb)MioJy*qaeen(X#>Gzo&iL}Mhdn4zI|YZ$(5EL!KdSsVCq
zveMNqx&X7WAjx&_N*v+JX;ss8kTGEO6wVoW&uX-$R7>9d0T}ZB8w69gqNQrZ-)iRW
zg=J)CljIU(gb1hJJ(Cfs#5R4cUo-%}FmSR(>cj6g&XpknW~M$7=0q-J2LwKW-?(XF
zLL8p6;CZu$DrT<Q8eSR^g{U`#kl!1gFf;2J+l%t4d|+KUd(Sa6Ke>R_Cna~)v36P|
z0l!I$pB<N{_>sw4`@g^PloM}9 at I`576}kG6W!d>G7hgNxwulMnz at FcWqWBVcKG$FL
zTK5AEUR`G4tGgy1l`+rpfHMwdiYt>l>@lvocK^B&>uiZxuIIPsgx{}AHo3lV8xV=M
zA)kdV;F=vNC7=lwNW*d$`XS5-;$gPq$tL~rv{N=rG at zeO4Ad#o_6h191Yl<NA@?dv
zBXuO at TQN|mdZyJv6e&(#B9tycd>88y`$P=OL1{Ib!=v0$An>LH8=PHY480mMN#fkH
zzYjmzLr~h^Uf%wO=GcJ|UHLqJ#~d(u2W$=NN$Truc^HA}IhVm7P*!{)zTi#>6z3u{
zE^P2=t`;3dSV((*5noc6I<>-ALg?1sr9S4{sjVnHsq$6rL at e?tD>c*nu_PGh??9!N
z!>I-MkOXd-fEI|gvQ@%Tps!wom8X!D8SLE9CJAszs5<B57AJH`Tu}t2NR-#R3H5jR
znvxX)Gl+||lDBAzhDp=u4{|9#3M<AGUS$h{>zS4xfTl at sNP4X$;5Cl%RA3>LX2k<^
zb=|Y%H?|^oT92|HfQ#Ka^ubRtwzm)jC9V(HGB>L>@p6a=lzul*nbse4w0yiaUY~6V
z>GbXk_j$Wy>+1B8QV$>q7w;ci+uS1ObG1gmh8oz at v}{u0W~D5J%T2o1RR>kF;Mun0
zX8s3#Wb|PRM-sG{-K%2VI6=lULL#DM_Xl~v8dy3833tRiOB-`~y64S(0iNfqkiY+~
zTxu1b_G}(4{^h)q)#j$zI&E4lJZ8*fATidW!lzpqtbE$P=R>FP^@$H?^%ehTM`N#{
z<-FD>$8FzeCA=HI!6-0}5m200nfnc93nAt~n9x@@-1oRasD at Ot+TAR9oXbVl`9_8T
zFkA&W+<3&HJ4BzJuc-YF+}xE(7+%Rc{2@%8k)6m7te_QKi*^IUpMS57g<aouBZr43
z5%<#b6||{k-~w-`ySHxos3L2MoFYhvhwQ=Avl<U%CXwbb=8f1hsJK!xB{)+Otu-`_
ztPD{@J%s~TYd_WqUAbxHg9o0dONX%6y-c=BgxW`|Gj>xbRfOOqRHbVA at Zu27#Udpb
zaS$;uincv!@ViIZ>{xvBua=+Hsn0(knCYS_ah!?Z93d<hHwHh3kd#zV0{7UrGAR`j
z8OiFw92&l0&o4C`&>W)d$KBrAS#7A8L%l}f%6l%D7dFd2KxEPSq1G{4@<oQ=oO|bm
zHWnJ$Rl#>xZwKbIa<{l$wiq3(SiG*9ad{StMw*L%TgL;x{wY1f2nP+3a$_(%;m}~W
z|7r-HfJkW5<)8ZOXj0k((-y*Pd)tkyJ?nf&LtSq?qkUoNS(}6JgfI8XDvQ2Qls2r<
zH#G0Kmr6XguXvdJRuEbXGO}^2C17(Ax11fa57;>_*~#1|CtS73&)Pq at X3cuY?;^g_
zKIV5UUGCS+pOJ9yjqG^<iycMo`_@)RgB70%8S>9Ke+X4hZ_^tTwNhqVSrjPWJZCL3
zFqTR!DpZz at gTU3<yizp4FEefA!9L?RE%GU^SRCpxZ?TzOTvD;H^?w-X(%z}#^phbd
z7 at DL`r$7M<E_86?G^GS1+Vh`9znYH-5FE5d3SxT_OGKep>#vEbiTZ|6YZz}?@N_2W
zep%^L5cw}(Su?6|ik9Ga(nSpkwT}QXJNvl>o0kjyDf{mf0sS7a>l6hO>qU{{<`KXN
z6!c>%e>)hz#UR`9;g*!}215t|6l~}q!(fBQrW5>e&|0bsRf`cJjWU{yd<J3XC1b0D
zt0!2Pf_=%S?@z8m!Q2(*n7s|(suWn<Sb>9QsDB#)k0R!cD~Xo-*FNix2608~ch{Xq
zP_kLSRzWb92+kvf)%n$w>}`&L7GUwg at QjjiFq}bGH?|T1 at lW6oPkJtpat8&|fC4(C
zQtk#STvz2DV&3{ZR!U*|Q1O5StnTH2_^dA4&NVx*9)3xRSY*U5z6JB5$gyfG;p;tc
zJ11|oIe!(Wx7dsf(3B4{?T*@t&H0thku^VlkwJ}Rdy*)U0=LOgE9K^iox!hD135$F
z++D81IWl;9Pe)aSe%sMa^sn^LqNjnJsSNF!yKbU<wLh at oi-FuthW#b55lmI!mBjdv
zZ|0=kjWiH~9nZ|>M?llHzy?Edy^6C&^_cGyF<$ZNqP?hzS5s3EIBcEt^m?G(x^Vq`
zc3Fkgf4=n@=%3H;6<uf;({79uI-HdFK{rO=lqJ?Ykt0&NSMD?H#{U5vDD>j7l$m{s
zFoZi2u|8t~o}<TxMUiSllZ0aoQ+F*o6zwhZu^vPF&)|VFBhU+CFn{!7i=s70tk2E|
zOr4}FIVPr45RHmG6l+(Ul+5^J-D_a1yUGLqO(%y!u~bkNAm}3xr#`MGKvDLVDHX2k
z;d6a62SU)n$IDpddUL6GPzuX_Q at wtQm@pazv0q-VOB*(jmU(cW76bKr;j-nW-ux%^
z)BT$0^a+}uQxh>`<kO#?>5m-$8JF)qLw>s4)_!pSw-)~JR=gWE{@0BZG-)PH2uh7>
zC_XOTr9q-X151kcyOUwXdc at V%RgG6==EAxg>lTn92{;VB$Auj at P4gMXsCm``i(4hv
z*D!Tgl1)9(wJR!hL|Qb&9lExJK|oPU-yL%uqy*4ii26)Z78|h09X$joa)-dqe7c1o
zCA^&K!qG~CV$w=;{%W`GqX22aPVVY`ciVs`wq=m-<$ATHvmc8J9u4wnod*qhHU5bI
zSl85<YJi>!#HbP?Z{^`3?+ZZoi4KOo_Dp%Ve{6FFZoWLTf}Ag;L4<8~Z5{5fW9kwv
z1;GtoA-B1+Mum>6>XpD%^m3PQs0)=`!Q79kVQJ!nLg6OU&#l#koRPy<*k90-3=jk&
zwk|~r`gi&L$JSHmj>*$?%Vm2b;AEK;J14?s`BtgHC)E3N;4*P=m-XP8UrB0Tf at NSy
z`D5c^Kv=o%BtY|*zSl$<ccAus1ZkJ$?4cXSPr<53S>mxnDR(iVD#nQ*eyii0)o?Jp
zTJV;C742TX$Own`kghsbl{L<ToP3yX7G8gCS#Zel3JG|x5K{k0Wh(+r2RivzA+uI+
z6=GXDpM)+eUhl%Z$x{7zY8U4~Y1C)Ui>;x;GvL`c!p*YqA_F at lR7!x|KNWbvNUH-q
zM9-zX{`l%)Fab=yH#=4sOl0>Xuyz2G?SknaYo}%jLQrFQ2OYdVZ|8f<2UYAw-c~*)
z=Cn!t3#oB&>Ir`ZR*iG|lZ9EgV54&fbt42b;OH^IRq{dzl$yK)D9;Dm3}Efcq2JJn
zHMueCbKvA$+r*-cOp8UK{Ar*vD<p at Q(dhAZZl>70krU51rh!`pytK5P5qf!)hW<{G
z;~MJZTH6#evfa*!KChbCr_MV0ok_#b;_0ZlF>zI2UYdHw|2;7l_G9U}UAQL|bZ4C(
zoHWY-b{|1#W8eMmuJ at ywQ2>`|OtEl+wQsLk#K0b<nGocg4_<oM660cHS7<EyyR`jI
zxR*L3d}~^udu_%QN(z_Q#7JOfe$lmtp><-iAjePE<@mu><>N0fYLo3IMeC`>cBe|5
zV$`^mU;d0wU>ND)^n((g8kunC3Eu?^I{&m8)!VvKSMSX=O85Mi<kD-FDRtBQv~>Rc
z%}zZ=&6u1&xxNmwVHi4Hf(Klc1^RNyu;=b+7RV1nL5WbKh8@*PiRy_(e#G$d)<^JF
z-j)$`?c`b&i*Yzrub`LeYUBg%BMhRNOdB}Nlk2OA1 at QLEHO#=~<xqS09D^D{AGGY8
zfUZBz5*+WWKgx1P)Wc>DMxYvK(jl}p%wwm<z2kTtP53hGK)QU}ee at Ka`%oNb3|6Jt
zU)f>lx|@_T^s6!7jo=@#qjD+U&Fj=L$pPhHR8^pA9;0eiV5+6?Fa0dYXw7c#5f7Yn
zmaY70nQ<Sg3{N5josc(REnog&vNEmVQy?X_4lJpi?%9XpbeH&o*7*^kY6$(WI2wQp
z`i!7phZW-5-ZjQ*GO=FkK at N)t at ZZ(G8iCaxkby<geb(~pGxgZIt(Q&-z_kWEVbr0R
zpi}+?pkddx%yz}CCw-?bha|8 at LU;Q8Yy2zWFI49IBWGNq(1MrbtPNT94GluFjY at KL
z`~QfpUve_DPfGKn8$>Y#ks+m&x(2e at qIoHS9~|y|DLoxESp+bXuoL3_lj at jkJ44GY
z;=z`{B)I6vqDMO|jRK{=)YD}?%*T+RSoGpYa9c3U24VLcd`nuf33YqXjv5IbL~NS0
zroa-0-+ at EW;T*^9Ak>@xX8~SwTWPnCXKnzC at ZEdQV3paiE^jQ}VCmp56Ox`=K$Ima
zr3qPvOQxY7aX;J<i%J!nW!H|E$)W1a34pkhPwS at xy*w+GOd%b%dWbV{tmwcLX1x6q
z!&p-7n}F_ARC);(17pM=k;7pK=2;;Sd#rJ=y0;=2%LqF4Pa?JQQU=<sW~IK_%<E-L
zFpM3g4Te*KKlWJrX at DK0XV_ZZ96e~dyy5Cv&xV2+p=Tc$r^^ONCoAi1ooo?LO at 7X}
z#G;MSq+b~HloRMaOok7r?H4xuVdCO8NzXr^8SB}ojo0^NjhqsFxE-dAr)i|1v~|9j
z7ipN1X-1OqamO`cBJLsf&GXotJ&ExnS2j3<f;mQ}z(7_uH*^f at j}8}H(GO2KF6(GG
z={S=F`)GMYcGH0bbM?Itf((++t#UoS<wBFlju at esUl<HG83dY6 at QXpu>kDafI{IXM
z2N(PU|82krIH_R=D&5^Ho-}};2B=C1t!3b at DLlJ)1k?m=Xx-Hg0m!dZBOw>N0ZP?{
z=A+bgv!4tRLf<;)Ct}}8bfjVaihGj4e at j^X*Un_hL_mQY at Dn=lgu!!0F<w>7M%dBd
ze*=w<W3rQ{Hwj4Zw&NZ?`(<39^WqmQhuzfaiDWV?z|02ex*EPoS<ja19xE*;1;6h)
zfOPA4HK(>VlhAbeedeIB>5^<c9H)b8HrNN)AKe*Pu9K=~l;OoB at 1?huZu4eHvApfd
zft5}V>ag`P#r7tj<K>vUWYm*4v}0GWO;&7Y^~rm1vFJ7#E$gK6_<Q3srASg|!}|Do
zHn6+zEil|q4uaume2`vN+R|qzzcFEDIyxpZ=s8?<LeeM!7I;Gkhlp%zfLD?<keeEZ
z8h?+o8Ur`Dura+xDfSbZrJi-F(3A$&IZ5~zpqM1!l$t}<<!%$MxuYx<PALD=8gad(
zala{LdBvK3Nq&<6i>2KStfF5SIn`-#GT~BG#8B+yun!%#eNT!l9qyhA9iKp=H(7`D
z2`vaIWWIL;H3Z66utT^my#lxp*qyoj%)1PzQS-a}ldFOWNwv*OM{u|8MCwGy%zd!-
z)N;K+gzCm+w>=Y1t>|*}0IH_c$YIk*13Wo78IAn`hcOvBf>lqh3o7(M-5Tb|nu$d^
znY$5#2)H#eZ^E1xH4Tj&K5l&r-7{d?`B>U9a=or#A)E~2NB9NByLE7)o<pE}Z=8Bo
zxCo%OvKBJ~J$$c1I5ZY~V2AlB2EJSOGxpvTT$j{muZE5s{R&^TaoS`ofId&f48X8G
z!+C10azDId^o8I1t=1bKKZTmvjSO|<E9%okKf4(0LRDF3)UaegAk$Q3kkOw!N4cez
zla-On_?hbt<Ll4h5)P<m{V!0cz`z*vo+KDy4jkCDN^{%10{HA{wxu>H=2`7-W|nqA
zh28YTUt`nH=<hPZ>U}Ad*=K!#$f*7B!U|8o<@O=C-{N``x at OVT8=hU%rwq2zFSGd1
zq_Kg-fmn&ImBH%+K`E7XhGZ~E<gd$LZXIw-$h?XzxO-iW#O}&s9W4e2#m-s?xs+kO
zozl`MaMef68iDy+!ZM3K{8 at jy&%?GrZ8xElP<;>6 at 7IL*VK_$_nM;Bk%2PKbGQ**5
z@(G<3pYeW5zV&G1d`E_o*3peDDk at cYwv(A^6;d>!S3EOv6k>aW!*)?+VoC%B*UY>^
z#*3xjYzkR*^qOfXVNV{0pcT2Ewy=m}sHvc~Bb}7pS4eHJ=lK-}qWqWpnCGZWD%774
z^bv}K+OQ)-X7EA54cy@}PDgt-XodGYV1 at JZ7GP8DmVA1RF*bN5gi1j$=dGNL<qQVE
zIym7IN6H0IArbX$vu;9n6=W{da%mWtQ)xiWJ;Ptxx~%IWx3L1zq{a)o68F0^EFNMH
zVgu5h6fqkT$z(L`5 at 6rKwCJC#(4^#C8?aU`6emQ0grZydd~QIZpj%x;s9+@{cSs$~
zs9gDqj#=1g=TwoKM&W$MC>r=?JAn=*V5UudlYtDiG4&vgh8d}DrxVD*VHzYx%@24$
z4Ic_n8OTYv$hccXCQPFtTtnh)vy#5xDldi#e3P*y_BToW^~rS-tR at Q9TZf<u{Z=Bz
z+*kS9I2AZkrUYm%I{j#4SGA$~r{J7_O(Gg;fK<&<ruV8uXa=3uZAO<FyGK>VFZY?m
zEr|<Zu!8=XXlqNEgds6_>FSK901B3Nhk;5vP`$-&oQ78-x`EdAJLcL(0wmRn=q6=3
zp<uKbE!UF)3A%`aY}kML(WE~pj$M=i3CH%XbHNcae``#cA<G8EyEA`f)(6B_B{0yE
zYa7YfG#{ijUNkI2cnua+fg!>VDaT+w?Q27M9~D at HnM*TtbHEYIKqg3USiD+y7%&tM
zitQ5g(=@N_t;CxuelAVE2T!YUblsnm`E{IlSNQvMc_m6UW}~up*4;<Or=ltl^oX at C
zdBCumtVuzCginCQmC>`j+~FVbvmF}2df~k2nWPDFc7xVXfL}V7Tz?$M3p)1wCIyx}
zQ~}pGTK$#DvPq<e=AC)RzzhkoygxXsyJ469J&F`yi&v$1&61CWp&pgYMd*7yb|hm@
zY$ro7%HzJ^{`Ikg%f$*7^IY1`&~SCxKE+R`yVx-EpO}qNQ at FbS6F4c|acqXRJJc)&
zL<>r<Q1Q`m!l&?A<^PIbSg}G3EIxc{k_9cdLe2yQ1vbYI?MhVtFk4nxQ?LKr8?GV|
z7OMWGp{!xul~KK7F>fM7YBKlGAOeEjQNq-nT(ds-?NT8)X|FArzpi5mgF`T1zd+CU
zusd8BlJ&87LvmdxZ76Cj2_4=idSBvZm;6UMDi*SC>E7%;(=%BBY&S&yEBzHyiF3v8
zZB!H_yDOgqdO-qe5x?7<H1I2xr3Ix*N1<23GaoN^W9p7rWE1ZWKs}_|kQ at 5)c%b>M
zC<507FZsG~JsWU+O>TK!4y8Bg-wrIg;P_o~a<Yj!BV%NRV+4H`o(6ZA7qZDH7)lqM
zPCG at Cy~k<dM?~Z8SeV}KTl+A5RqM+?y*9)BUBYfqdg{LE at S@+^!S>DMcnChmQ4G^{
zuWSh?@&$!pY_WJ7|Jk>UkAy-{Tc6<IxYnEE^2Pp0yJ^RuGuDH{zMEnsLZVs`CF*4P
zo&b_7jIuVsU8xkAXCu3D$~YFn!)ucc7dddL26l|+DaL5qGfiw<8dsCKr=PNcoDVZ9
zAI42?RK}Sj6^G`<NyIg*{!`$};FI%mtK}k_Cd<-L)zlj;3uOL8`}p6Z1gPzjYnmix
z(;%W={1Y*}o=#48yMiMYjnLO7+%EF`*l+Dv+QE6u0!OFQ1*tiC6T at lw#7;D=k@<=j
zj8MA7EbRkxJX3jVlmubeORc_zEkEe5OvkjqPdfdCKOZsAc~dWFYsKWO5`Csnezbg;
z=-_{67n)O|^?}o0^E`lvg0D1-;-%Jy!v04GGTyJV*4`A3>AD$D7WNZ6`(ILdA9tJ|
z2FZ~x{N}6tP}rGcw|Ges<8Pk&_qg1`J#SAkifU%M>*81HlQAopar)~OPT6Poaak_T
z{2r5$5+2h{88nbQ7(Q<brv3Rin0(<Itu34(b3f!a4(^ar|NSrvyutRdpy*NRl7#(V
z!;e_l7JNu3NPyQJz1UiOaGRRtim&#Qmzao6qU{*LKDFFn7jKg$&G6;r8~?vAvKuo;
zzQ)#fl?<13D at Uc8*2k60oW$!gMl|6x)^>^AT}imy5#Mc$(*<383O5kAP+M^6VKwDn
zxX)Y at rQSbY?Vb{Psn$U0D?7rW&~e{CE?XB`htno;4H&7a+lrdl6&n3}-bW^qu^Kk=
z)!hzQ47^R$_m=ZiK6S#_Gy(nF_qMUqx at f}uDQL=JA;b5!UVNfvR~f4DJ3h^wegv8?
zvYl!TIS;A-eZ at AJk^3IQ=^N;mi{!Y|*Ov3xOm70lv6hL&<@Pm&KGFirKo^1&${#QG
zkbj}LMK{BJ*^5Br0kG8k-?qcD{lwhOfcnXAF{><bjCyomLsxOR;{l&}_}zH~A+<>`
zj|N2q=M&AJJcdn&Y0sO^dHtnmzm727-onWbLRqBS|NZH1HvZarilr7554_kDZZak$
z%Aw1;?0h`uPm$dxe7#b at vS5fMaPA~2_rD#z*f$7gx!Iu)j3S-$$AMP7(xtu_WigiL
zaDvxok9By2NpU at eL*zkU?9%!Z{#X#jc54bX9gmW0O){DW99!wg`Fv*iK>1mq>qYA!
zk+ac#@3Z!Z3l#a;#XE2BU2VOKC(>W_m={LPL-$*57 at b8)?hf3^+oPHwNZ?&d{dCWp
zk+slmWs))I at EG@3!f at 5xz0Y_rn%!7T=c?XfXf(6-4q;g<Z&_qI*S*+k8Y3<W&JC{@
zcC(fY{T76?d>^!43H;$FKG>}-KU_}eIQI8nq!N^EtjG0^W@!zAdG+;(Ykllko1y7Y
z-F>k6yzl_hbQwvf8FWH-w^lG|M)LMG`Sat$@gdni9i$y{YPI4!S<9wD`%g`LE{R)j
zRX%^K_1?D&WnngGJ3j2snhlYghWx94PPQ-8zWgulz_8qyje>E%<&JUw+9x*WSuiWg
z*?*6?+&SQSC#`Mm7lrf90sS1>LE8V@!hXP_?B^O(-296Jjoo=(IHIggb!|-Ny>*rj
z8V0g&_18n8pF;B=#Yuoe3EcUx8Pkeh1DV(^)H`Oz_=;GGngAm#23+qx0R%r8(-z*p
zOT}P|5W(A#%Q&>PUCiBmIBgc%aV0#}UQUp<TcZyy6RtBmwi)DJk+xapD$OO6 at kO9a
zBlX1dFO$lq=%awdu^;W8Ia*`S12>sFfDdY`3y&)nCy02dU)z&TV5JMGZ6;sq*O+>h
zvCs~Fi64$`#t+&yiIlr+7tQ=97<k at aj=OKP9BLaa=7oE=HZ+eq{;=@s&$~VMYqh4B
zRA#xZyW{U24=t|Gw%g)b&*|o$<L_}Y|3TA`ru^F<LJZI9$5}!4r*_-b$_aO4yFHDw
z9T~jUXx2HEKmQ~>TuU`Yai41*wBBJwKfRdm*!RCAzUwwMS)RM`yXaGGYyDT;?d{<A
zrS<stbCb)3r?(qYe*Sx>gcnL#rw8TCwFmwz<v~L2EJ4eT*M;~kM_9s(<bR|sdd>?z
zMfx<y-}bW>;rpu>6{H7ZEk_i0&teaPZmK%t%0SSgf(z523u<O*|E*J{i)q)`pgWDw
zPmLXNx4-=AZqKwuA|oQyLxPTfkR0GOxdq`>oY{gMelbpwC2Oo86rlXBf0uI{4W-NI
z=IZtrVb3~;$VH=yx}3beoXhqc{*GFXn at 1m>Tr!`t7%y(eNniJ#Gl$Cf(+BOJGDWcj
zem&<67g at 4R#|^r=S*IB2US}4#?)75HCARRtQ6)b>MQ9$H3bC}_uE{rDT|c-zu%VPa
zN3maTJ?<voqR}H4yC~liyXe at LQEaaNBX`-y$J2U_FXxQEWoUu4)DT3u1O&)P6m0lf
zHj>n9{8_{8e7YQN(mRTSNJ3A^3h_6N3W5zD33OTStju!86>a<eCG{Ps`Nv<8J-eA&
z0n|82T99GiVGhC-bwLky*quAgF#Kc9|J$HLaa~Cpy0do%)Xd&%3G6`WIExkFkxhVp
zXk#+cL7C}dqty*!*ZL_SjV?rE8)^^^fF%C{=9Sc)avRd=r%0k-O$j^OQRd;0<pn3T
zXRl7fBk_#!t6M(MgyAtC$GnJfkKJ*>k!E3|;*sd!Qg83TZ#_=dI~WRFeSCeRc||nN
z#di?U83~Q*#2Isp)?1>HyQ{z_$7`bg=RNquKX6-FYPhDW*pU217fD3Zt1<m{6|pZ*
zh7L+>4-Z~_*4)GGd==Kh(kQ>}H3~g3qp9Jvec|<Y->Syz74;KhyszS2 at M(hi8~s?0
zM}=8db+Ow1x4eoJ1m0J3!q;^x7njTH;#H4tw`NIvrk6swI?s5+$}^tIdY|K6=Rxny
zEph)Nc5eE_V&eQW>{%l!vEcp|Yg@<11!el>+fbr-oH`1O>Ha+d7r8b#x%Bl8#h*C5
zH=bXz*gFd@?pbwEa@>=3mqR&_*Yrf45rHi-)y=p{Jax&r8=SdHnv6}hUskuuIvm38
zuGz06xN-k`p*wVW0PbB!d22Wy7pEVE+mnYw9mUfW`z=}7Dm6VwMmbrWEDe97eRA7k
z0y&=#A))3-<-<kKFX9hex_JHfXB}qdzr4&?P_>KRmpLBJ={lcByVyz`Rd&+uU3&k!
z!ENV4b%?k9D~)^MB%^cc!SwY<61r0PnM_bhTxGndUrJ_>)Yvx2-Cjzz0Duq%fAa^6
zqez{VgDJKhERCSA8z-`}r<NaAlUW!H?Ux;Yx0avGg<$9!cC3v}i^ZcT2{;aURHD(B
z_Dm>yvlJxdD756%HUakW?=fEt0W_ToW4Ugz90ef*Yr77dU%SfO;etQCUsGA*c3^rB
zR|lK0vzHhUsC6C)S0c#CQ5X?VWIDP*5(BbCvfiaxE^AKqU?Sd!N at 6fYp~h|2Rb(qP
zZt|(rpIn{9I}|5`HP+=4p*u~N6`8PsOZu&R#msdSqnM>NPTPH@^gOc?0uLsY#R_Yk
zeJz(*BSYW!Kl at TrYo8zGd^5!3Um%oCcq6<2FQCxa%Xqo%iT~p2^EuyE1rFltVrSXV
z)V%|#tOJ}uN=3>9 at epyMw&Qn`kE5D8Q;gY^UpHm;4c4J$yQjaj-S$RYcoDK>HD)aw
zljAl~yIf<Xszm~*)ILQxJNPe`5 at ZEXEW<Qq{}dat1YJ%J9hh*wqml3)eLYR>nUYyl
z!I5Rb?(KYk+oHqJ4neqPISNF1O&e98%?mX+#JMGVD*c!hwtVB=b3%0{qm2v>IJIJ;
z9(uRL<wGlA^s;GO?_<wi!J1hXW$~v{vUycpE`q;m;k{j=3)#2RGotnhnQ&&Sn|a3J
zN<2?%W}o=ohF;v?{}e`8r#ET)neN#so8{wFk9UvWd5Xx^^wPA`TqK!MG<EsO1+om;
zFLZRc`>XC8e9>cG;wAfQNeCPop+wnW4_8#qUj5kDiP>#+KkL$U=Z47wyQrU|UsY&x
z0%v-tNaK8r^_HZELTb9C<N~6+0{g!0>@DsGo>E;*#|d3){U*LllF8op`<h7lMnAM&
zezu0^m_*H|%uj79+xOMi at _;?!Q`rurJWS-2E%Ra6tFOCUuSWaellet1KdQHGaL)Jl
z4=!18sc=`18TVygyrbc~PQ;9j{Em5;*Qu<89Ii<T{sv--hAm{g?H+Nux3iY?Nx(ca
zLwFXqd_8HZ%~$r3=sF!8gJVP#oL<b8kzHtoY(*uDZx`{29#`IJOp>U6SP(-k0}|k{
zE0X1lSMqebPi~j+DQI8g at b6H)h<d~6TP^~hZZ0C+JZ0%YE)q)aWoQnMBBM6=&0brz
zF)x!CKUin4A_HbrEav9;!!k4(`WGSCt<KWDQkPH-eD=tbM0zXj1lQz at cv9q}51bN4
z?fKs=A%nk1F}BUOm^wD-#Ua$6GjtPMMF#F9&Z=Y+G-+flOVh6H=VG>D$4?M>wGdw|
zITZ2XB1~N?202`BK7<+w;sK at IG4>NYoPhsweMX01P05-y(_UF9g`>ONI~vjkgNle1
z^kLnI%Gdfo`0lhmT;^WJC5uT}_z#6k)=&cA$c_K>nV67A?&k21ZxpzVyBajMxwXID
z_tmU&l2@@|6Xm;Nk~q at y?ilhjlO-+IgXV7B7p=EMrhe2vOI4_KVT98-vcVk06|{oP
zd(tAXml;AF>i2(k4Us)&HtxFUC6u^bo*p`w7$x49mcn6{e@}bS-+GHPKS$_&n#}ab
zWz1~h3E>M~mltjQ=F#0l4%gjY!aFxO<m{SP`n9DylDu`p<Y9v01J+0c#uEExQHXwk
zLIa>Ka1>1=Ft!O3ev$60ul9MZw|5DxT&T^M<<C|GTfA&3YdKp^&*f440&^e~WV
zUKSqbr)2$j2yMuuo#ML=&bRy4Qq{HnK<T^F;Z-j6(3z<CPfS%X%ksl>x;ekrHnF*0
z7qgL%Z2e?~1|j0+FWD(BWdn7Hq=`WO>pu!E?pn^>uQz<Ya3{BobA?Y<U1$c~u-zV|
zwS~gsY6g_B-(|P^G4Dw2GS@%cv1!YvTcxe$wjf0E&g!rv*O#Dn;Pw*p=CsB*z3+7W
zT8zVEA9BMMN{f at Tdc<KAb}>`@^nE+qXPokj`*Zyufvs0B at c;0%2gEOf=5L<1Tqfc=
zZYVcuyEM(dxfs{Owe*4MF%w{Xf^8k7o&1}c9v)0+W-iG!`@veTu<lJ>Jjt}d#c^tg
zZ=~C6F)Solx|-CMMz4^TiHYs_=D8DhjTfJ1w%C{1*l0RRM{EB1FQdA`36y&Cxw2+=
z+7nmlrzV*7z#zBP)?w(%dVGLoAv^}nwfzxu^V+CpR{7C3#-U>PQ-PNBVE+E40#=6x
z{&$N|sGZBOTXC>Ha3&*;R1(}gYp1^SU4wB)@|)W|xJjbyPO=*@JhY38Q!p?bW-Zp6
zPZt9h1iO`HT2P^5;Kvn|(U=NK at L8RKSi#KY&?a=nSEQSZ&IYMlO%bL(ji6tX`{V>{
zu~_UT-$6Wou3^Sb;I3jo@*?h#A3Vq$T45ngvlhOY=H77+#3v>)VWGrWJd}2qCw!?X
zIh<vSne6KgKLxFHux&dHZf2SNELNOHc)XY6!#{%<$R!^#7|5xbO07ZTfwAeXbZXHd
zD=_%(Z2UQ{i*%q{TUM(fj$IfF0I2(~@s%%R$?+U4XYIPqhMT=!=uKn{LipWp{Rets
zzWhM?^5E(1%`uHaRr~z)ANHnC$vDruYXcANWeSC71>LP*47`x}b9dnx+v>e8u@|tU
z>%aL5pM`P1^^PRy=+ at nqDZK)^lrd#-g9QK$G{K)=iPX3Q34G$G*9etoVK4iAybRb^
zwL033wu^O9B($t-!A(4D>5qbLe{^4fvVy+eZSqN7-~?V>NZg(n^ieW6wihIDq5Af8
z7JY->NqH||BRFMm)?O^`?@LSH97x>WL_97#zb_uQ5|>Ko?{G&Hv at TY5P@VIqk-mHM
zy}?fN-Kb1v&?e>W`uyyopR*iFEbxHtVn+31)-;v^N$4FI&=%xfj2iEMv0N*cXtDip
zC4w>Nq%@0N56&A3lOLLY+~G=AsPK29WYi#{^4Tz$)T8@%dva4TSy;@WKKkmkTC#M(
z_L}H!p;i_~m at Pf)f6mRaVA^`aC{1#ROf~%@cLzUj+akVOKQBKt{X=*Gd^7|7%24JK
z;l6CwwEn}j%eSMXnF}}q;TFKKhvm2^Z at p4Z(*4pML1Uiq#O(g<u~+88wy8IL>-hnL
z+_hb#1M?Fi|Lf};yxS+<!9hpxEQP;g7r at 3`hXu~}($I=T!2jl#HIAml!qWFoPV|WC
z at 0sMS>$(55kv~CNE?aEad}(u1Ol`(O8}@<ShkS6DA#W4&Kw{zihV at +-5L4swVK6Mk
zjVPqEl5P(Lqo5$^cVH3$HP4Ap<o@@RiPdCVjZ;pwGN4j at y>c-R?Cap-CF7$0PnBBb
zaYjO^X|AIQrzrjHzcsUdOj+6!by}_S6UOA2opZBHo61c~0slh%$#f4-A at N?oh~8Q!
zmAS*zWs at l<!8om~cn_qoF);XU4WtXF`0iUM`n1|o9&(MT)7p0~nP@)`fRyGd%tCx`
zon{KdJV$EaZ~G;|+P=3pEz!S2>6{I_Bq!h|xK%DQG2 at a%o_wz`whz8pgTk|$7IpW3
zRZc8vO*@^=Wk69V^oRjrK;@=|FxY8q9f2ir>v*=kmS-~=B94N!-0VU8h4qJQD_naz
zlpxpCAhvKQqr1I;6Ut4#FT4{GOFDBIC+PI~r$e5k0lTnp!A3^^(F~m!(z7D;6qTWE
zC>2|eA~lYy#B0*?Q__?yz_ebc-o3w`+rMGH?P|TCz1Z_=jjpjf*gel&j%z)ps-{nv
zH57waHEIa|6Y5!?-p%iqB6-fTGF~k4(eTu0Z$cVXq1E8 at 8|;u2uG=h2VihW*%bxi7
z at m3{{H2DIq76Utsy{fcIkH46>si+;7T+PM%RoKht2`%f{TCl!4U}>-YI at T?%T+iwr
z!BbTP-q%fOHo|?bS-SQy>*XWmebBpm)4R!uu&RZ`2gNmIPE#~Kb8 at MZ(VK4<D?i<A
z(0(>DmipHhK6xB~uSLRU>0VTm@}AP0L>2;ww~Wh!00MGc0FZSO_s?3KQ`Ng at EPr!R
z>ugiFvRim<g0D19EHK|a4!*yR3rk3R>_b3AFmGeF at HOFi9ghEeD7Sdox!=n|;|7+6
zxpA7$wYK7as~9~qLoQ{dxstd7GGKP5MA{=n`hLlIowxOSRzgQ%x>;x68Ab*J1!5OL
z(RmuuYba95dOSjHpVTCgt^F@}Uz63iP5|;TIo)e~7)-KKR|MjB28-(z#B2q#A0Vdl
z7I2BA3HZgyhRWH*<qtL}Z~uwm-(Hjw5ZbC9GpMtzQy&M5lSuU+n=c6tp_pE#J8ATX
zfj2%{(tElCSm_sc6(S#l(Q+|nAgXpmG|vsdKscVGZzaMKcJVvUM$n2<BAa<7t(AoM
zOFXYB6xpFG$xZ8*D=1DqrYTLE4jibL-ZHeupgEm1ta60KhKk^xMWsm^bPa{}1^cAL
zFH2-!nVcH;AmyFU=O)|4C+w>~e1d+5(lms__Wj<D?ux?&7#LNCNvq15AF)FRLTN*!
z3qBRTo`|H|*2<SH_M7Q(tqw*H)VX$D%&AO(KK3$qD~gScZO4Nb-fgRAe5;<aWbam=
zKevAlTC=08PwM-B7NGbVLFYVCdRU_XrYs-<e-koC7B;5(4I(MO{&_o_(*Wd(@J(^9
zL`Nwx=@Te$9F4hd@{<|%27WW&t|NM3WLE4}0h=3j!_6zUj1K9(;pii}@`n>j$JUkc
z`a|I>audGzZyzovb+#|o3A%T**SU6jAHU-TTX at IQZgIuE-5xjC1;jJJnJMC2peI?D
zin9W~iYp)ddJ*uT_3mG5oZLmI+=jC?K%#FmXwf~<%lz9S`)gD|{x!)-wLu?S9iv*4
zsAs~D#?KQ+qN05{Neu7XSD(;ur|dQCG(ePGW5lCKpPNqW%pQAFu at kdz%I*3U>XOEk
z`#N#heHLKVvu(%~qLbESRTl%83{o;5nT<$U91kJd-Bd at 1n}n)H7(E0J5u;v9ISj>B
zO*G-NqfgqCj8y|CC- at ewyXIhfWQ8gZ>h|o}P?(EMk&w3*Zq0=vo0WIpQtF`;ghKiR
z+EW%?TnEj2eX|e}HvFTU;Bp3}Zw#Aqty at RW7_RBc?C-pNRZ<>tLI|_;aIoH&1R at vw
zTNUuCG`yj#aea22ZxX6gYxj+TzP|-XUH5Rz>}P_1<Lbn<)4m^wx4G{x8vDJwVzj}r
zEB~20ClgyNrxELc6$`zLleDJCvLa2Q5cW`PcEM}T|1l|TU9IZD+%n!-5xKg4>Vo=x
zxp(foPp+`{p;0+6W%~2ABJiTry at bjKZ~!1zONchxivLaOu3bQBx^@OgR48-5Khb^g
z-UO|&aB>*Ny+}2EEF;>(;^ky+5sO}U4F<yV(9<f20F28B*ZJW=3BJY$e`yc5jdM<h
zG3Z^cV(HxOk2ISg+k;`(vyRiBc088M>__%#K)KeMrCo}ydtAC2zYLI>y+bNa at G8Y0
z54#jk9{m&qAAM+N8T+AL`IH;;j(z|@$kY4OnX at dYVk(uZ2CVMEWl_1)E2RJBv};FM
zNTilvCi!vJVx4)1t1$eo&Q1Ogm%3&jDWuPuA7$un4 at Q-nvHyZ3p+C<E%${ryf1G=!
zVNOMUw5ILW(FN5pZqC$hI4f!$ro7>De&TGcw1PIG59W;ANmO!%;re=R{F5cazLFs5
zp_<<PG)nrR(17q;KgNWem$mNQ6ojHtTa{2b!|Ao$OGbqsT-9X`I#*F at +m*`0 at nf$h
zj1P8iDprrB`}3GttV=%!@@tm)oEw>zZmmaj1R8BER>V&`c~L<tqG0^t+bwkSsZ4Rd
zla^zkBRX~wnr4YI)64U+w6;>TY_81U0n3gT1Nl832iu<5_jr<jtdaMR!=ad-I*A?f
zAO6~tzfPf;HY?jiCq-<}XMl7cLjLBh$ZyYDRl%j!;b9;fa<7P_!e=v2+*W|ngZu{5
zpyK8oN at c&$eE&KEGf3-_oavh%eyGfL;@6@(Q<yZ{n)taj*Lbqt`T)G-0shm)r9YtP
zFyU9wx=;c=k`GU*73;Q!pb&Oo-20o`3x4mJtN)LtGmnSz{r-RZPJ3u9MJap8ZHZJu
z$?`^s#yX7co+*u8sFW6lWQ(zckloBM*@f)J*k{I2Nel*M8M6PbKEKEJuO5$yhq<r&
zI_JF3b<TNS&w2L1&nuMf)uF{BT4`5H&E?+K3AXAyjK;^6C*ck3iMKte!{rX^uCR+B
zILt9Gme2>Smy?D~{k5QHrCA<uhG^JI4zJr at cvo>k3y(l3Y(5tHhG!PWmT}(Ag|R~o
z+>7@=rj9F=kBG;5<@+c+Fn2oczo|+<PraVa5jnDhVU6LD`Tk!3Y^6MCRol1p;q%nB
zpO at t^zu?3E at k{qO=Q8$PEq^4}PAXd1cI3kT_iQiPg1WBz3C<nY_h;0!8wN~VH+HQ|
z>jZXVl^f8X-%#tOtlu(D1;j0>kPgOMkmlBVnI%cl_zn+v8$VY&T>c}A;AHw4-`JFj
z9_7L$>7AOcL&zcrGI81 at oAI#o_2_<G=IWpHZC(ulGsH&meKHVe$iJO<8aI0v@)k)r
zOW1IL!imOEr$=w!#ZR(V-W<sl)oY-bw4eOR02TYj8B)T8d+BonG*|Z0xtFI1XAbc|
zW}s{6ofaP<^s_FRNEf5~E1K<9pn(q1c(N<2$>Dgub8jcnvc^0$nR-)@%=At1Q6t!$
zM{K5(T%DO+rD`U}*z!>JxaI<!g=?6Zt%9>2HB6a5(i%cy-?QYef}X3E^~xw^Rw>(h
z<Lx7L_ZY6Hvh3pF$)DDBACdOtNf{0NjoPP;DVf~SD*CD8D>0k8yV=#eJ;m$O(XxKr
zsj?d!SVqh%{p^f>rPSs0kiMmmyPW1*+jDgbW5enxi~5x`wUUCnvj^CA8Tk$tWPy9F
zr`j3&&b-NHe)Xt&gO3rDc5F~j;6DPwWS+mTg!8?ICSi*_hKueAp=&W8J!BBrlkC&*
z8&@z9X)A?z5kxVYe!>&}`mrlOg!~YIt~>io*+u6&M$0*hy-Kkqy529mJn4+q8pz0%
zHn at Ms`ib5l6 at 6&)BH`Ta3R=312AC`xR-tErLdX3)KH{7VWWXw?^TWuvl(yDL($h3{
zDq4|ZE at v-RkY{9fTsw~uqpfN;YQRVq$H6 at Z$*S^AMGhI^_nRE5>h|Qv6T^$sQmr3O
zc9g!y|89T2xQB76<+ObWb#VQq-Ul;5f)noMrkKjht+1g#<BuA0%?q8`tvt~xmI;XQ
z3*(`Q2B}*m1?w=fzd&`ZV?s!dE%Q!gJ8GqCK_D<2Uh(<)5{&Pu;Xl2dJ!rzQ at I2+8
zJYY0Yr&6+bsJ}n2Ml^bNIt8DUpLy{Oa>aVtVrk=KVhMkohD_fAwW;qqT9t@?Zl7`R
zQiBw-eaiD`%;JaaxD+YIlQdVZU5wZ99tXLzu>M-z#eo-%&kX`~pvfjuX%gD>gsSR!
z<QMTw_-?SMcxq~gc#n3(=SFcMk^oWUgjGDx6fJd0flpTY4z9oQ1FF{({$XcI at 1qb-
zeZ*xeWiWdkTC#dS`oNDG61%}2BS$2lpx>vIzP$=}8AztY?npX#KC*`s6=pD5Tp)-#
zF8Mh=6MTuWbGKigaD2n_+mpT#TZ10;K}5UWF&gHNy25NRNDtw0v3>c|7c$FvmxUwV
zHYg7%yn_0w{fgva<?nwSezzYIj;cGvY^fg^gOMKjskm&CF{k?g^m^7^sWDW>vB3=A
zq0P8-!s)5MXcJpIBFm;NR1P(2K%N|ZUwSIQTTl`8*p99FHPLF{(@O`OWEyTj&aJ`H
zP!_&WBOA(qL*;Gs?~RDmp|4~4tuHAH{yPwB^^NT0sXqQl>jHw6sCIgs%AFabW{-uw
z<4FoQkaIEW<&TcClLtP<6%@J;Rr>7Svdk!Xqoq-6d8m2ss#WgMF-(}kXHTZFO4oH0
zsz3j(+*d<At2yX<Pk;Mdp&{2k=CNIK6YX=@O#AQd8@@$jy|lw?8?S=mqzb;5rg1Z9
zX+gC)Md#r&S<F8JU35LD`yAmDYG;ho`M|z at yEoCmoBXmY(x|bAtaMeI_8e)EnejMw
zp`Ce|M^Y<ZNc2DeG%S&lDC}`!SO!{?fcT5kvS|>4<}lhLtZUz;kqxh!R*f<zf`lOi
z+C8j)VS{@a at fmG>L}N<@arW;uvSDc>78-GdAJ>atdBVZBi9%pBVpb5Iu$n<fCwJ`8
zCAE45pAEtL*h3TFYL7OTc(m^#oU>`jiW5idAv`%D&YpkX`wHdGK+=kt2<{tGc$XvL
zi7_;Fs^2c!fJj_iKSdz&e<w=_!t0H2IJcz^9aKPBT)*6Oh4~&QDN;<F7pauRoJCxO
zxVssz#F*2Db`6XjQ1=+)BY{dC3+06fN`7R;EmegFr+U1m3x8?i{1lV?a1P;w^ow7r
zc+}-d33KX)muH7}n$F(7@#?8~prKgBFcz>`)_R4t#H{WOj;biYzdUsv{WSQ!dD2$h
z$J$7*7k)g=i~jx2liM$JYdcx~@P$=6&o=p-qe>~qss0Z%%fj(02?im#l82zEMjd7Q
z40v%(PA#CWy*Qy~A(A{2S~|*)n7k2_P<`-Nw1MR@$lCbxJE?nMLQa8sBAb||v#-;G
zTssR3f$2#Uv2`!}(-^vLk#t96f=--799Lt&CYLCo)G~D7e#GjKsrURHW(nI)%dKdf
z(be=^xl^b06(5KS(ae$<0|%14QSgI!JS9;Gl|fibfah;Rmm^x!v8Lv_;6{+g#|Sf6
z|AHC?|JMD}%X at XhHQ(XcXG=j(s(661b_Se&>wNwha3ls&UL+i at _O?_$s8$xtOys|w
zg9uqRZ?}d{LUv>&1s2A?X6WHjgj<ndd)(fG|7L1tjamqeV+-RsLtSW`^89#^M%&@N
z+YseU2Xt`LwuvjBrk+Z~G&~t-=8;)?Wdk at X0ycm-S=6PzqJC(HrCpm@?ctt-+7JD>
zk~90q7TSuvV-y5jwJxN_JN4iHld~+m>+HSzBM%;r3t#oEY5tsI(KebmJ?KRgbY0H~
zkrKN)nLI$FWSJw5=EzVOZ<8~+54A5};pjBoEzpWP%<THM%deZr6H+Yo*Wu8oHY+RT
zT(<EinZMG|8%)w-^?v>*=@&D-GO#ywnEO6l3`@apD;F+dJbCIjb%KU&5QJmKvZ<jF
zVTHUm1B<G4VisRZgw6UD9X&sqb+MB6jdffSGJBDmueMa3VjDE{Y)OyEoG|z>E7s6g
zcGf^}p=!b~!gFVNCo-2abp^tfY}kG8tzV>n1{0%v<vFUEZ!QY#Lqrz8mVshbvFVql
znyj03hJC!?zAq&3&U(0*CvPc3H<AS>Yk2+t8;ncoSSSWQ at EG(ughxpE7ug5bCI$%O
z;fTl%iP#u<YdfnYp}{L0H}2z0*q<Y1t}IHg_yyPRUpker#|C*Sq6O34pHB!X!z$Q{
z9mb?@i(bM5Wlu}LdEyFx8~m^e+Y3A3hGLu~&fjz!I-lchX96Cw!jM&s9+t;mMpS(J
zRG}DRpz!Ve+X#ZJ{6nh5>1HInSe6?gwo4Uz_knm at XlIV0c)pv^9 at x`5(b3cdx<Q<)
z+T7KfX!@FhqqjX7Qo>%7rcPSTNKq?Jj*bW`Ye9jUkr6!BVHq{qFXXcqtpv5Lahe)f
zNve+0 at k|YGHOTtAWY6FKT2gHNhZdCrI`VfKYvvgUFN$1!HCN-hgLrOB!sXCshboQi
zX%EzxrpJla^w}tt0is6)qB|1tZp#yXPMQ(^rRgT|+fAs?N<%R_!XaA4p^6$hu9+FT
z^_6I>+1Dsf;CVul+zUU(?D^1ySKKnjwY3C)>WKg9>%6HLhp3nrfufXqhaO69b-Q~x
zf{6+AIpq?j3QC<yXnv%nH4et2)Rs=@U>SIVdF=T`caLjsQ+t#YZ|p0v%1zt(>a4{P
zN#9e}FUPL=aLqKoFY86UXiwhwaA4ew$vQl>qx(|$8DEy)i^K4*`r?4V6h2Z{<e=4_
z?e|Q7e6IZ~DU3x`J&OGxE%|t>;Q(vKyrR+5<VeqOtQ0|&7H#3EXRbSZq6ZHnKb_b2
zLr<+#ir(p$sFd2*o9rIjdGy|w(0kL9&lL}>vG*Vh85g~^ZQgPkQt&^jc}cbYGo_6v
z7-AJ5cU5w9E2Q{tjfycZ0yc2-aQ~;eJ-pCK`wYZ!;r6UjhHr|ikxH}9A*LWHUoP~%
zDi(Q_<Jznv`>4d{`X{5gJsNUdyPv%3NGMFpT%BG at IxV6+^A`WGST(#Dtfk#fChNBN
zfhzJ5$j!0EU#vht2<~%7$kL at Wu+Pq1OMk<)U#$8MG|hH%3~rx$Eu))X+L&k{U!R4s
zph`dr*%uMk2jwBG=Y<D4O$PGvSgW?sD~v9Wo!#FZD7?^69olW^lKW5zggDF`u_H0V
zBMA|B<vMZ0U&ex|b{S0u-<?C7h*2J+c3K$EN)?>}DS|<|5@>qq)ibEjY(@7fH4EkI
zR-DaxXYo}2S5s at HgVuPAaZ(=k?q!Q_ZQl$OLd at WB)$>k1i3a?kZD&xSc$+XUd!kL`
zWkQsPqFuDp4@$u at KSI{A0Tb!fvocf>d#l$#Gkcpv9s<>ny^vaQ7T#q~_8dC#oO)(!
z?ya+*T)_jgu-!7tizg7x{?BvPU*e08_EhI0lnYA-6HUW#TGt)aQ(Jg4cFWtaLwC3G
z2(1{!RWduqL#>mp at bkz!2{w?{bw%`;<!NZs$l}R)wAW~QQ%Ti`b;=e$JSg_4p+O!#
z^-D9CcOX{Tr`(=JK8jrKzVjcQ`xmXlQuI-S(SwKGj9eOYBHEA at 0IsjVmn*~Du+5%-
z+mBFWTCZ^P(Pv+Nm-uQ&Wtf>0Z!A{8MwkD0j#DRoqrf|^mODnP59VC(Rd&`9YBsjg
z<Zfo=3uGGhklrYryEgMfFX&6?z|-fT6K*@9GqJmFPqM||lygbdDO;dD5w+8mDNQiA
zv8hoLVek+Qy}UzahI|kxRz1XckCn&46Q$%?&W9pzItidr0wAk^su=vCh<4_oe8dHY
z%k3w1O>yU}dWaH`mvx3XCn~0V5njc1iNW&(C-N0B1hyUdc*_L}McT^~H~^`!P at E7$
zlC=XP#J8*y!wia_;j7JA)d}Ow_q3wILUAU1fl=n59=qbr4R>eswKH#NY>hFdy)A~b
zc((DbEs$=%+BI<z(%Fpm>LFc?Aa<)j)01AXAi^GZygW at sMj5Gwl}$mQkC)q5o>9(!
zlQBPT*yeu+j%efQeLd9WtY>~<m^Ja6>vBy+koO4kqQ+^2OJt>-{yyKhQ(axx)e0F_
zUignjg<daBH*}{~Chd5SY8x*v7ZzzPzi0&aOQ-z!TWSRVNr?X)#rv_xXia3j$>LAB
zwQYuj%gst`*ZfA8jfDPW;Uu4DvFBS;7|5Z!oX?2{NBH5X+|$MTZ#mzMe{reWo5F;}
z8DHv}242ld<6UTb454Jh`9tsyf`N4rD*F9DozNhBrE+GVZV#XRXjP&{lmY*)Jp>BT
zUFag=@t06p*^o^wUTE=*)0KwM&T>;`$yCf+Qnv}~>fEPOWMZaZ$=bR$vuq$k6&mpW
zIL6ydirW3jzScaNXTFj7qaIeLIc8vQbJtT*$3xH7U%LF0A&8igEu9>i{vj=$1z)lY
znNtCW3k%|-_h>rO4!wePq27Nxb*+!AsZip0lnmda#iSw5f=CGdHvvvW$AM9;XcdTY
z;vnO_l7cuPB%126LK|-3nc=T}Mh#0sSiupkpobDRCkc#)R+4{d9?B~4 at lnjkya;Bg
z_wC5U>7Oa<`{DyVa#I$6nl*gV+(N8(#d at z^JN=j at Jhi(J9&ai2%&r_SApOWNIg*)b
zR%G;!|2qFOrSn0Yg~&gX at xR5ytZrZwEe3dMHl<ScZjCR`B?s=#a&xJW)1N`^tv+bd
zOU)#UOpE_igObHJU^x9Ygw`FqVfjbii<_I|*;o1~`>0v^)5`{C1$_sg`jVM}+O-#s
z$KS&rHAWPm<P_U|jad^x6lbjmQwJo%CQs!M9JSmXJvEQCWfkq5EG&p^ECwG4#h^jK
z{gY}BSzvWxp>wjy6Yfp)>UJM!P2#*cbA4ku(kWwod9;`DyyUn~O%lGOph}wX)vi~?
z|M-6pxA;NBMM4}y at w2mCLtm0rowyRSg;w*-;L%R_?|!&%e=fSgk986XE at 6J%10-~e
zhN75PG0H=~U+q(w*j<^gkDzZVh`OVH<I#$#Tj5ReXVDH-1nQUBjqnwk0XuY5KIklg
zPfhvIZ(pqMX~1?EksrAIdooMugZ6{L0l5g25)q8(s795SdA>C{$WVH}bJFi<XsFWY
zHI8mRVnJPtwP<zKmB<cJI=|T&Z_{vx#jh&iKQ+C-U)Hx)^9TLg-(9&C_4kb=r}tR6
z#07biC%5?kkg~?sBdC~jO^xb5R_JxFL)^#ZW=>~!LFKIU5@~1mM_e=4fu=KYyzeM9
z5q|7c1R-wlu%5=2D)U6egPl&O3Dn^qGwO)(u2YrFkE8H48LHV&`MRu9=0%BSZRV~x
zZ{H88rP8nBNk?}Oh6n5vt7a0>(c&mdtariAaJ3_4jF_=vUdP5V54yPo1c)2AF>@*i
z$)acPxOfr~BgIFm1H?*a)7Z?6lsSEvu at 6B(#>E?uw$HD339wsA{kJ0=mTh`ePKCZQ
zays5oJcnlZesy5jHSm$n;%0Y2c&hlm0b+NcL-=aiC=;gK_wAD$Xbr`aZY#eo7akjx
zPeD+Ir at AKd;ZI7XVol#w2n%e at jPkQi8R5M3N-L3#XqQ?r8!1h5W(=XRzDrfi&S2~%
zWyd^RgHFGq8si$}ZB(G!dk at 59x9x=Ayp`ptPX`uG-;V3Di^i(G&iPMhh$}iNpTp%8
z{xVDZ5G1@>Gyh>P5uM-n`*^O%tu76 at H#;!Hp4r2Le)T(>=~tJJ3C|pRxx`SM3Vu$?
zU0p4DENtuNl_#z0Pf(dD>ECVCeaB^)zE&uue5Qk=yH9ZG+_io6Kz6JiG?l*Zm53 at n
zOAir3m{lQMp=6HEQ*&F915eMHTg(d%?<goT=YbT8>g<d5<ZVt9Fu}vwmp?4N3Djj?
zBaUbghACUq!)244x(*Mmz2t4`O>cEPmKQJvdlmbg+Ea^SrCx4+P6t(;#ZjF$<P;X^
z1;0{nvx{DW?a19%ITJIxme;C1M~=ksaGI$>-yb+Wf6S{;s0Q7*a~o>vhrL at W*uq}D
z$K!V0>JnCej!!Xti<R3Rr5l_3<*uek1j6gI*kwfj<H+S>XTCkcb#{5+3K$a}WY%ry
zYlSg61mHg?d&01W`yUm^_&XO(zfF+6`Kv8inN*&->Gxd>J`=r?d$IDmfcDuN3fXPx
zB~1qEZ_7&zSk>`&$;P#sl~>;nqBOG0P(v3nMD*TmYwQjGUxLbOA!j{?Od!vpFOSad
z_=3O^=Q>m~4}7~0sfBumPp!ndC;VO+=I}r_79SaW<4msf`QtE?q|eXs+X^LsGIVhr
z43gWD;V#^tM?SQ_^_Jf=RbYi&HFlBoZMbb&{al<NS-O3et<|OzUfhk-yS4v67BuYa
z)A|^%n(5>-WEHkM!SoCVRC-mjOP;sf%WEx51C4p1@?m(Xi1Qm(!*@N04viU`S*GW>
z9UG19c(FWx at jmT)B{NN~O&nHtnDH;B{~QJmj~ydyfsl%raTOGsm*W0*a at 24Lw~u}c
z#yV|wd|XI<Uz|1?s at LqfX=?5gzJ5Wt$=6CuD|vIGEKOc`BT0?H;jzrCTz^^2!Y-yA
z7f`0G>utr}Upd^d-psH3>{sZyCdB;3 at 4uVz*PQosQFB_tQ9Wl#lZ?#UJHDf}nyBK#
zo*wz_!Ou at NTyZvG-gru48R8LX(r+XX$3_KWo$+H-$DtB~5QX2U#}jL>TKr9!^55Em
z-wd at 8_O3*R at KAXU?|n6po7O$52g>X-ln2mR7)lobf0+6(9FdF=ZYi6)SDSt0TAo8y
z%HE7U+guZOgxiness!&8q+I<m$#t8z%EjDwv<$@z at _AyQ*Pa61^f0f8ypPMqM!jVL
zHgu&o728Z{PA_{uL`&T at d(l?3E!AZ}>+p>d-x-@{blZUES_7Q1>23BLQplzH-;ZYu
z)+bYg5%kz;->Tax5*6RJz1^Y=$h&=R+9cC7Z0oXA at dlF?b~Uo+!jEXb<9UzV2VEZy
ztb9c0^=iDp*LoSt<Gi274(x4G*F9}SY$e`qyi6$fi2e_nd^q$`3{E_)ZTiDTt*%K5
z5aS(pGR=IC4}{9HK)V#vH(iQCX14SuZj#$odwnReS0|;IAF<Ht3Zo1RoZBcgh<g+p
zUvO&hXwZkc4-vjrd873=v6FgnN1;Oms&`$|{kp8qVou6lz(A=hQ)o7ji_D!m-~^@(
zYXfYoKu=B|S)%<Ip^P{lbE)tb-XnwgN$T+mvvJYC#DD0r7(B#@5>~#>f95PaRiRUN
zz<ns+ at pvNq*w(WruG<603nhtN5v<^XQKntW%o+4ghK2&$(N?NHD*<gPXMcR at GmGRG
zctryn6M+o!CMrZI4KFl|bm0-S<>K2fN8LV)HeGOaY;)wtqmKT3Uz{V^cfHhQ=$g{0
zq&KK{JjzT#RqP&EefV=*qG at Y6<M|#!&bsp@?5VGRBY18v(IW|)EB19()mP3d!{|q#
zfI2rcI?fOIMHqBgL=a2|rX2k?$xjRf?%KV<dw$J?bD8TGgueP>fAvr1z!Bkd2E9N2
zb7p8S*Qtj-Nx<v_<52#nKM58#^&yup7nz%BJXv}lpWUE;`#HEwkjt4cTJik7eWvKJ
z*3?;zj9Bk`emaWdY0_afoC_-N&Y4+huB=MaD)5I2qPlxX>NFn3ZPnd5Q+t9J=(RWA
zjIE~dg-<WKWGEC#J&JK&kcqd_INRBf)l18znVV%+dHt7KP5($EM$w#-b$d59 at 7hl0
z1=l+Fa?S+KoG*Of8DR%zWyA>|*Q~W5Ju!cGxUYYDKde5UvvXftXwLB$HSe(kgr2v<
z24v$^%eJiCmL$_vCbp9acc_A at h7FB&CV=l&dG at -xUtEYg6yBP`KbVoyZX+=YTaD^%
zdO}P7o~lszc1!et8Vo~C{$ImI^$Rp+0RZQnXQ)9^%eU>h540>#eQwc7m6dahZc~dw
zF(%ZGP<2kx62T$d<bYe-o*PT(DP|XI4#m8+|0u%)?(lfg`J#mi3NCcwoSD$8XgtLh
zVz at XL&hdX=Uc1+>)BGoE4XeidHj%_i`V#u}?{0Wn#oH1}`lUSK6p-hzE)Rdbv}Io%
zb-mWyh^#8EoaA77YIm-`y0W^=mSufbnPR#9u?zb$#{3p$#zSSH=CROl`M*JSL)#F_
ziYe?g*VEtzEzU*_>k#-?CA{lXEvMIcqj@>- at AW5Ew+|s_4|FUTE2C)#-Fyy=g96uM
z&0=)S=1c+e^L3eLR^#a_Ikdh1*9)MmfHm;{o%LsZrAw!9Y{xZ at ch7B;%Q7=xux=ZM
zPNOTm at OwI0;!Oj%g254|QOr1gZF#6M^q>UILqqcg59*M|F)!LMTz?-$X2NH_7@~V~
zO<zB4d`Qy1vzQdhX|`nS8V<;Q_jT5;-p*8o;T!MVz%pJN!x80?&-!i;s3U^q5dj(%
z?H~n+h6nv1%EG{T#{24oQ>3Fe+^UTn!A$4IndyNkz9=5P^nh9PC at 69jzit?1Ot3zg
zI;@LAW#<TgVYoASOWIyhWONwrjNS?-mwST#J2<I)gt$UmVIm>r=bx`W2<paZZG8Kw
z0!=yXQ6OJBG`Bd}JFC5VE<ET}rzCZxtIy=hU2c|VGb&eOcJ=D>w854A*-9wEW^4K2
zY|GDB<R@&WETczFd*l1KzZJt~q|bpC6oi1`uxcfE!megN)MxWB0^g1IKZ^)F?sJH6
z)2mQ}55dyiI03D?`S2iSK5BU}QJ^hXfpN=vY1j@`8?>L$IbZ^2Sw2|9&(2(8-2Hfe
zksra5^yUF;@`x(YFtBzL()m0o0Om#i?ncD=4v7-VRhH6;Y3^Ppv~@sf&qce1D8E at q
zl+SmFJ-NwGIKM)ZfI9_7*#H&56~{GH*8gKt0KyUXJJ<QQLCI2+^YDy!)9RSp at b%Qn
zd65cYI=qOdzFU78wAF;pDs-P-4%l`5Np7ybku%y~?cmv%I60v}*_r*(v#JKtt5PLp
z0ft3<Tv3+`PSqHvtrx~XE#}F^itQWy`avopQ=2|;vxHCnz+x7&>>1k%LJ2S4VRX^3
z7e?ho5fw)(3?M5pP at VCgOb|ep3QZk@)Fd)inRkkb$6w-#iK)F`f11GIhD=^SPdN_=
zfpXL=>2@>N<@<9KBm8_4AQBC<BsHP)2XOld<<I8}$q80@?A7B`YK|%6R`uq1I&9b)
z3`4jT+K^Rs3{_q}D1us!YapN((%GS)`(VqEKeS0^A0C&;6Nvp at 25uOhEx)5$3|i!9
zTAEi-hm22*WX9XvU{U at A2FLKQAOERhb-1`x+`6!D2WmUW5BO!&tl}<rODSv&^<8(X
z<@l5K=meiFWG|gO?WJ`8UGZQ@!k#0R96Oujp5#$0sPMJF1+(M4Q#L8>0`DCLW3&y8
zB3}u`U!ChJ(&R$~990jc_9dw)Bm5Ib9Y)oxZK6Ajh+tqEP)6=YUe$yBF>}rFJjuAF
z*1xLE_x_us15--yIAEE0Olv!7-IoSkIxGhq;1fv#($N6PGP;9vKSUlf1sj4a&>lPh
zdm>?*Uqi*Nr-5L&V3hKsly0L~Ly&Gi^wN58>E`!K?!rq+J=2T0!D-V6j)_^54v68e
zljv`Y)s>KkXEb`KV*($}_Is87srPF|%_aIt{@C2z*SmPm#1GJxHwtI9cha}wQeGu3
z2Mw(Hc=QmiX(~%UkBy6L`-N1ywK`NIN-h%FYo+<9K)tysGvrW1 at tS(*hC=zfS}Axs
zj}G`$rOh~SID8tV#bm;ZHw95(qOYdrsuZH4rF=)rF^JMJb`MIJXV=O=6!Zok90A1N
zP!8<*urGDkChzw#MDjH2!tZ9lWI=(72VIQsUt~08mbnQ9)uEH9fU+<IcM5?a;t6)A
z)ytFeK?c|fhXvzK9%~pYrYzllOyu#O?KOWJ<=Re*H~jz?rL0xY`6(ebESJ{;AE0>o
zw`?P&Hop7Q6>-Nu1!sQ)cgNSM>YACgEL5>>fupsnPd at W(Q(tvbXbOMkN57d}DM!B<
zIa)*0 at 4Xx%_q=BNeOl4pg`WE%9d0$wJG~~ICq+&pX8?h1l$(eT+)(iuRBUV#?(pQB
z&fTec0TJKnAyIj!IPC(cuN7zv1eYM~c>wh&gc?e!yo^{~<Mwk*APg&|qiJkWxe1*S
zVDlKzTdEJD84QJZ9Eq4pBMKZml3kqUUK+OzPfUp3W}OHKA_K)lqf~3{Vb22Z^QXK8
z2`Ci(FcUU>jmjoj9v{U(vWib4r4Uz|Y!j(DD>N&}-C<qzkyhnw$LxxiDFEaB`&5vi
z1U#u9`KsXBVz%Zm#&L1a{pIAv|CP!VHw{zQY96S6wgtCu6&4nTv$c&qg8|pBa=37<
zGVUA4AYMwjPseH1d5^MUg+2NoH1<&8;nD%4tsQi3`ZsIig4CM09{SDIa?WbE%PhOh
z0e9Z%?gdxd!&5wo1x1+_**ErO$AkcKUhsT*O<c`61YP{k3CQzIIOZ}EhP_3UApf)c
zs0_Ze$b$$WaEWi%{SYuA7BpMYlYPPI4kLV$^dOA-zOTV1k49}O-Cr_x2uzuo7dL|?
zvwg;+ at zlB<-3nUhh^l^lm|}tG{c`v at Q`n{6pBM5TW*QW$o(B;beS1^!g3uN5t at 4BA
zX;gIAkndSAq`p2>K4MKJOs-|nl;Y*fvoMZdRCRkF`q`PE*jK+TJYlcfpo}VQVU}Dz
z^>T4UyZ3Ukv{9`sRi~)dp8vECk9Dd*^+N9#m!2#m6#QYeonB|8nSG7RO$+2sz4I?C
z30j=$&kPa#pTm8<$IIv8Ny`IglUl20)JGgpoHLqlU?gxWOom0Chz}&oE>MCOb;ck@
zm%F?Fn4wX<%`RvuwmPVqI@<#yU%$Ll_`^ZVXbuUx{JCG>lmhDEX%{|alLT<98Su1$
zuv13Js2pP`5L#LQCrSSXs=$CT%Pu1|lBlY*CD6_jX|LtvBMYgOYbZr@^UR+Iu_aMC
z+jX%2kY5Tt5TcLN at gs(}##c6*eM!MPXbVRhm*;x=or$H`yW`;T#S07FwfxcKw7m|C
z=-y&<mZ1jf^~*pF7u%;YQI8m#>;CMCDKV{sl&1AUj7;jCy*a5Yb0TH8h*#l5=0t^e
zmdHs6xAdH%G<q5;OrOP(JWjqfBofySCxhOiUHZfXDc@|^^ZL*`DZjPL;}C;EiOnwV
z{%lVfo@{<WO^WUmB$S%)YOn#Zjw`DYhd;8z!ongNh7r~Q|4>}!J3QloA-%_u)7-f^
z at O1BYq6!2U1}ac<)5+27p`3BXgw;!cPt$f(WS>(3SQ97I9n1J%nrz1fj}9Kpnv=}V
z`wcpuYV1U=u8F6NZW~bWozYVF=f>A{@$)ohGrAf=&g=`Pq3Of!?rv+5#)?`>>82Ls
zJMKc`?-b~Kl&pcLQ}@}POe^-Sy%{qZSk3H^1l-j>2Ws!Y$V6 at _4C5!t8R4qw(gjhL
z_2VX`yv at aFG$TL?AO}ra?Y)nf?%|bl8lC?xLOwG98+I>LI{L&rD4OrYSuh!|UrO0q
z=do=Y(A1<yL?S)IlmViWJG1OE#~l=JLCHN_C_kxw{GC^^x6sSHPLyl7W-N7(e at m1I
zT1({v##wE_ovq^;NeEdg!8#DMWm<0>3G7t;4QQ9p6|O&*$@SL>u$ZE|D=Xdi`=A*a
z##0)fmCEXUVApZ@{?<cldPbsmHMuWaW7W;vHf{1X%yGxO+)=UC^P;`5N%O9jo|E+H
zw|N6kPiYu`@Gmxw1m$&!|5zbF*8t~5FYX4AYU3$Y2BVq>6t(N7=h at ltv~?x5>1uZ|
zbK+}5BN#%hWRyW$rvHnuWF}*DO7I^V4?JQ?a|}Mu*E<}~yX|vh)9jxhL#U8DE=wYg
z at y6f_+HLCpbxjo$x$B>)p at q6QxI}D-pOB+6{*O5Xh6LT2`oJ^%gXuMc5or;W7CR{n
zU==hQ$B)TxYC8Z-9vJob3)naF<4PM{=m15(s}RCWWY-6;X^C<FKa9AE)$cy78WIRC
z^Z*63EFSn>`AN9z07etOugRIGYwC#U6}7<lPn-kPLa$<@`mChVtimq<4-rpF=)L~!
z6he(bv*tWBg|kW;?=Z^}OAPv-cCB0nz=t><%%#tFH94g9DjqPuND0Lo<{~xZg6eem
zt($(IM$i`|G-|7b3!G3z{n;ddK6K}<y8pwLO|!)B)3%J!D7u<7Am25yN>gy~tjQ)h
z4s<91EFL%>Pa#ml-YT<5HAI#1+ at o196KdFEx6MQZT0(!QPL5>I5muUx^y!tF?{i%*
zHv3wxk-H<@40`#M2>{C#e0K3oXN^^VWk#lzW_%2)!{I^B0Bt}xQsZ;cG-iJkXEn;E
zj;h465*;h%uFG0P;D{cRBmh0ENkO`6mfa)=VIcs<P=zjE8v+DEaBzyNDfQpPkrGG+
z$evgIfa{iQWRJ3KO>Jw6y at yQXF<1g(R|n-;VB^LL%ufjpPev=2g6Afix5+o7b7H*0
zsYDN024P`BX-f1r9G^EvE7C9bP%di%p2k1C+g;OU6lfixegQ7x{|CFYJ39gi<s;=x
z{W0pDM-4cVKp1MZwp;khjeSU4Tc6LCtIM3NA}62F4&OTih`J~z)#v^iGj$mRhtr6&
z{UOe-*jtF?9<SC6+c?VW-Xqou3G%up{0Fu6E(|{R0;{of-DkI^|JZDgDu6?Nn*l_v
z=BbxRdKj+Ko6e_GluS#r1jeerQ;(_N|1_NF(JGXcF9b;0==<!h{M3LU0Ht#0uA3hF
zKoC}5<bvb%_zt-!U7`D$o_vflY-Q82!^0mjJpVX$t{Yv9q${!bJO17l063YY^pE~1
zWk_w5ulxb>l0wJLBp?RnmdY%Tjb_iMmcrA|y$lK(-dzRvYfj;QX}aSYO7~XFJ;Ij#
z(rJ!W76FK+et#2a)fqWG?Ewl7NTtgV;)@I`qesDtrqVyeD7`*V8yO+dkZ8&2R;S^n
zaxvA37^7Q7Q6+JagB{&@mTqDebS3Y~;U91COI{BxCz!2OoCD!DQRVppTy~~fld8MU
zj87mhDBqzfhj|MZB`Pl)=rYR+_gc5E^CPO=MaTu7t^-E)TFqv?mv8lY+8NzqGDp!o
zh_$JHbc3o$(ye^rqWTL17UfmCOIPo+PSt>+aH0SKX9@#_n`kDah(*Fk4c{gPV<4==
zxpAmWHI_Q$uXRN-m4FY at 1Y_vJS0IFiTudhT`8qT?K~UM$oofQ29_<dOPT<tx0G^F2
ze*0b6KfeHSitGmWkAgAOqz-zc&erq^!ky;7S+2#y*knNdkPp%u|M_kkQ$B at 6jGig?
zz`f?L{hG1 at IwCmi{G9kEq7sah-+Zs?1!H~P!Zlw|&kqok<iC}E(+3bDv70Dg%K;a+
zi1e22+xK0BJi<xXZFLoZY}43Mg!{W)>s at He()lk>vanqxJU>;Q91*lv5mb(;{<hAc
zWoT9g86;*2fi`O$dh5h)^PTic5un;LopDU_2-l58-0<1HfmOWaA1d?k;Dt{(ddO1j
zdeW{}r-XpRP;MBU at s5U@Jl{4mj#n at kg~I=y&q)SRIdWVmTo%HOjsy3~MvdwiErLMo
z8aWdhAMb$k at +xf`m`{RXpB(vw_HqV;(>=%?Pl5r7O4$%87OCbm1TwDHQvdvc5kc=y
zt0x|GFx$<Z_#Z;7J&!JI%>D{snG9TK1PV9*2 at pv?q83-~X7m9`y!S%$*S``F3SiPW
z)GgXKf=sKI4ZT8<)s{t4yL|5YvuZ~S>zzz;V9EEJawC7D8IfsMG``lTHy>?g#mPYF
z*PiWSe9-k`vaLACyZEp18Jp9&+ppbz_22U+j!sUU+%2*YO8=!UmGH;Le3LBQL>u)(
z#$g^y688z0O78MEWBG>LDl1og!U$SX46*Nz{kYc*aaIZOLZkN!20E4#e6mT>k>7q`
z9|!+kYsq-zkJamjDWZl&#&L%oRQPpnO1$}biC28<icY`IP0jSXJzvMpZRJF6UH$fb
z?b1{!^Y`pC^-?R0zxk;~qT(g8It_s96w5d#(18M;uvva8?{Qtn2vytA?Oew|>xd3f
z<dQ;RgC9(mJnR at t#I-?Te^%pN3GF}B%HS~t^(`k>Xpy^TMedAjG^h9gdYIS@{?|!8
zvYkQ|RS(unTurA~?rkF$Vg|Un5 at ij3<-8V8**+}kceYm}F#{tlND5~Bx~h5OLXnt3
zGKs4Flc9|vUrew?6TmmJW>w|$*LFahc{^L3P4dJL(rc5<OJ7i at Sc<<0?x&RR3tpvZ
zDC<`jZk4Mq%+1;Vk`Gr8HIC8gb}`EiroFlD8DP!GI)O*~t*)wYbUz1Q+IWzGe4~@0
z8W_BS*sw0y5oq)MWcF{_yZwhc^bfNglP-&NzI}Ft7}7S2)9dN|>}yhBXJgVdcjmRG
zY;=1=mRsa8{~V&CZT!#IH3%muYaOgL>+fF=GuDy9w+GH}7@?z;+LYU^hizgpCg5UP
z*#N#dFEY>AehZ?(0dYm6M1SGuE(sW9qJIizyzZo|1EN0LhJrbvPABq=9AFc9X#Hkj
zJ#9-dC$6~=oF2Z=rp*1WiNH+c*}lLab?AXyCkEO^FhB at ae4ytq%#se9vv4Aq{k#WW
z%a5cYGR9<cLJ~ukR at OIoYnwgvN0j0>{HVbUqvd6=QtKD+$E{!QM1!ba>??EfQNI-J
z7#l_wGWY#Z0F>OaxE69T_D&R^Utey&%Z-$To_ at FdSK~h~In2Lo8++tv3H9dZO&yHT
z$q=AA*V~QbTgL5I?rO-4`u*W*=L#?Il7Cm-+q<I#zM at eZ(Doq=78CrX&XTTwRp^Fz
z*)45#vGmrRAq=_Ad)0|zdD*HOW_^sQlx>G3E;c(2ijV!U&B9bI1PM^)WNqA{m)eV|
zlAA5|3Slt$m1B7!<`hPt_7Ll at VOSo8ntr~N#1qK1#VCG<!m{>o2Aejz+l%p9*9V9^
z(S=U(S9eERIU at L4eETV?Mw?`S)0NoBgvok>cdj4P*zyCL#s%veOYuuy7`G_`)M&Pi
z1e6R-RT3>$R3IyY at f#HhM{&zTr0acC(fkp$kyWR<87?<Zlundf4Syf*@SZ1w>0kFW
z=RseF)eNw;3GSLH%gORoznhnvX`r{J#p>)EF}TcZ<v&Z+1K!YsX=KjbEX{^Y{JHB>
zUTwcjep?k~pIf}AO&e`FBK5xhdS~yk3*+j$arU}rGYh|DYA@)_hrwE`a*QWGo7sfX
z-PfhSDsUk9CHw7uYX(R60KJR3`RuV7WsbODi@^o4I#_-l!mNkJ?{B>WmglwJt-$(p
zM9*tK4TX5=?shKNl9F)2HAtWa7~<_Z<fa>8g>pMh+$Izwd!>m+=BcEGIXrgTxt2?@
zcYd6L*-TnUjlqnMX$HGeJbeF3mXC1I2n&tgz(=gRc>!}vot4IFGBIz|BW-H=X3UQ^
zj9iLX*x<)F9yPw1)Az=3lx;jEqV4gfFOT{sOt1U57ww^A+t~bK3U_T|lI`*IQ1#UW
zee{7+1(A}tt|Oe!hiJ608p)LJ`z<55gqJAw!$Hvb{S~~tkCKOXxBuE(^o;W`mNK%I
z{rp(rAjD}i- at FG$i+- at l!koITXwwI6t}3vQF=Ax>S?l6TuRrVUFwRm?pjFOR{IFvJ
zJXZ0Z8}{egkOi=(fx3lMXP;i%HyGIvPH_Y#uJJGMP-^l)2^jI{))ziO)&P8kCTKry
zYHtaSW1^Xza!vA|soJ;(3k<<)*~<E|a#e1XDtDMxQzPJKb2DX3Ucl(*pFbDp^Ixe;
ziN1L?-X{_(+HSPe at yk-!FHToN&p5ANtbM+PbX>BXgdP`VO>~+`#tINRPADP}2t{92
zhYfQ9>bt%fgdsahn*Ow0S}d>pYw^Rk`YK$eY32UE{%*=o&*(&i#9&kgyaj)0W5gcM
z_<;>z92`qY*n6`46=vY+w#<E#a_!JpdP*~t_qM{K|KINTbiKBXS19=kb5;^=xN?E@
zHlXz4oUbKiq}-|>3Mw2ZHE6R)r9<s at vh6p8ZAvi{kv11te{Eg at +migZODvTn?p%Lj
z;sKvzT}<<2b%|J)V$3Bx&8fkiD1!FC6_XWfl56L2B7}{H#$yQaQCnpgoA{xJ%;ZNb
zeeviV%*`*U&II+dm>JKwg<sU at R>wAh^rD2>1pBd;uXaKL<qHmB at t8~2nO*i~RfpmY
z)~B8RT(j|E<%h7hh^%pS^|xko>wIHRKmOHfKNkx2aXeN%5 at WL6QGh-|QdQt1Qq|!(
zNlG^--W9ROw%Msj%C)8glEC&m4K`i)%3+{|Q-aM{`So5ud~8E4!HS$($?(FE576yX
zFmWqW;5jR52Aw>sE30Jbiv0q>LdrqCB$hHKq|O;c$MSEfv6^rV+EpdBzlQ!}qrc5&
z`L$ow&9IO8`4!3-xulngKGEp*=i%%X&hnb#4#es-Df@#{tloK&beMUb($2NKo~Ssz
z%!~2u@`AjyUG$g(Z)^HQ^F at w_m=S|GKUXBgvX7oV9IVHD7R%P2TL(ddF=_^ns&O>M
zS$%G$iU)2_C*?J)s152woGHclf74#3QX)Xe{CMJy4Ij(p%7zmo)a?@Ip^yp1INL1&
zV?Lsm)C~3f)-1w|%eYqRvpPoAst&PK=yjOUgNpQ0o{es8j8 at 00q{lSL?+ozFpISs&
zzU;s#Om6>F_&>`4!R1tPUOUA=GGgN%CWB5VQY+-IHtw`+go3F&wpgq$aLgKtSGzrg
zr-%486Ov>*)G_FRT%s|)<x<pb1A<9gdRy?_k_n$)(8+aS-6)|ke4olU`||@2)P;*Q
zgpo~N_fB%+>*pmVe{$6Gui7A?p4xqf9Z#~5C+Q<*EOfuNqeZLNpRkHUB9$!=w$co4
z`1(`Sck at KdXfCXHSTi7jGWU@qN;$gSOK5 at tREHYH(mNZNslW+GA(l$Y7VvE&Bzh_S
zdwDyFs(!vMjDbE1K1J?jd*r(#YJ!Ye`C;r at x55Smmajq$R`C8VgFCOcBfmm&K()-4
zTPio%_Wj?pGAWif at 0^*Q4abnw{Wp4N-XAs2xtqas(W&`x&6}lyG^GHArN5cM-x;8!
zm=JY+Z%EyVNbiLC=XrwTPJcdWXY}5^QLdlpVT~+xe=0|!N}7-s96c at S7UU4gHF_-R
zXl&K1UGgDPu`)vtJGQ{l;Vp^k^e`JphR&ThdlV|_GB>gx3VX<G|6!arDDK4ut}pMe
z+h?kRZFMfj#9Dn2eKOe7n72c%W>o=0b`xBaXEpg`0wE>1W3i&?FK}SM%hy&7{Q)wm
zw98Ui`R;ZpmG?I62%(i#zqOa48Q1%A{TxT7r%LtU%WhG8+A()BCw7jV&vcwEO~;hz
z8X4?_4nKBi_^xT%(e>0qGL}EGxwmaj)P%UXDypJ&fYVGQM}7ewILlGW^jJX6p|JI{
z4l5 at 2YTHYw3ZM33MvJo5PRsQ|YT<GXkc3}7P(&l{64du3gQ at h&#IUP}(*%DdQ^|O7
zS<OAH4&1viHM0`@sQZ>10sn$As(FF+ at iABZ^$76K3buj$Ku#s6(4jEku3)Vmt{HPY
zU4AncZkYXDr9vshnD|5#fp)2J(n2cu1+(!`ITmCQrCgMV$US=@Aj?}>W{~!2J=-Lw
z5xqbsey%)<M=Od-8ozE$(2x%+OCcE;pO6=h%s|TO7SRbrp|e2uc=;D*;m;bP%j{#s
zip_rQH7$crKR%k~F8nR^VW^i5xxEiD0Nxw7`6wf=m^wZ_euGuE>$@4NDN_JEb^EI)
zz{U<uI)NZU>NbPPg&&=B5jab*W3i`(%Rvm+8 at DK>x?D~qQgeIy@&=oZ_kbAV^k0M~
zAM4{8oxCIQ!2bL`2o~jGhC~Wb1hZe?<Qxc29&i-Kkp)8hU4_~Rj4#{diX6zMam*E(
z8l}8#=;2AHB5fe|a1BnB+hdx)ju%8D02 at 0Gt4*#!j8zGYRS7o)$%RVkCE{rMDePXw
zO8tp5v;~1wrG|u760B2gFOY&ULoTVS*SderKDN_=YjW at E$QiC0 at kx7eki`D05m<JP
za!14J>nHvK at 3|sjn0 at kAXoA<=x-b%aUxmlh6_gPgh_rF%^V at -J;}r7-Pna>qm1eAB
zeDmE2evHut23mmPYt1UVD;>hA0LIKE!O??kVg%-|e;X8Y#b8A&{$h<j>*KqXFh)}=
zne%tbiH$a6eY`as4^(bBxE}H;2z%zQQNYJrrj1f8Pc;t^soJP at GX~mtQ}IFh948S0
zWC33*4-G}|L(<wycvStK$4T(I&7XC#1aBIM4;zc4 at 12-^vXU|L>Zz8H)rm&W!A$!3
z6Pe5Gk~{J?6c1h=8tss?4(iN##MgOaJ((BW(FreM^sug7j$_JbomrZoTDXGm0Zz6k
z{@#^9+KISGm0NWJCSn`y#XPz$!JU-3?rET=;=wH?S{F(>AiayWAR8FUr8A-R*?QsH
zPD+CEJKKIpqUWEQKMBiYK6hByW?~o{u^7R^+boaeZ5TzGNc92Wq^%$2wEw(!V4QSo
zwlA>sx04-dqk<WFDZ#=XY=~(y#<=K8q}B)e>$xHV#wL5{q4mF%0BpiGo}xAgWO-Tt
z2}CwK+xY;=(M!{^Ef~?Qwn?q&+~K2;pznTQCe%Ld25*O>Lc$xL;_?rouPHfnPVdh!
z{L5UQm+fPZV%o<(Hmyrukr8aqrdtRw7b1P)`S6DE*Po1g1<Sb?HME!DZBm^PLQCx=
zJa1n6;mz|P`0kp>1v2G5nA8b9a>me?MwW6)*bF+b2S{-fF|iNBivQOOu(mMRw0{mP
z*zG#IQ*~1&SA5Nhc%NWeC4HodV#)0+Kq171^R7KHH+z-D*E~=P+`)z#6CJCvgaV1;
zLMpHY3xQGFP|T^ZP&V`Aa>cmj*dtZS=g-;R;HeeaBw*B~R>_8MO^(}~6usJb&Qrh0
zr*c at 4(oNfcs`<8UUVq|^)_pQk@$J1DiZM;HS8UPNg1;nDY%k*DoMgVRhi^F!10X=W
zeO8Xl#C$qm^JYfYjo|fB04%^jEc$UjWlm<CbIUXp<mcB^hakgU$Yn$8EMNgnc?`4=
zQ_pr!;=3$w*5C4qSC~^Hq^%)%bafN>C(ak7c~pRHGb9mQ(pi4{_K~6nuX`_PWe0Y(
zfZR8tTA!8ll2a^8U!b)@VUM~0KmRtw-YRV1#36uk9~i5v!LAq;n1{{z3i_oqkBp2g
zUWsTP1=p6EYWDnI9{uy at p<1`;(=>WO^|uoKqtEq0ceKli=H}*Z4j28VQM%nhUAWm%
z;dMqv20vcMbb^UTD36QoEOFL}&O6tUZ<6!X?$Y~}OEp8Gu at ZA|nBy;%9f(7FoX;(R
zr1jU=PtQjl?g_S5X^sgOl%JINr0Z5SaU2o<V<Gc4htZ at vTNI6ntILbS7noA)m2b7K
zOHw=@&j8W#Cnp|*P_6TVM@@)W#LGuzn8yMGei+k#36drak{t$VnenzXOdS3fAG4`;
zEwUA=`8XqqY4~bq&AK>J1+zK`?-V2me9c2pPE)(+MP0X*Z~tOW%TJCQAx0Cdvh1-@
zVEK4Fz7z&0E5Ow3MJwE}6O{5>*s>02z8 at _9!lQ<;UsO3M<r5Z8!NI{<Dxbif|2=xJ
zuGG<d`KyoVfsstQE28 at IY+~LeAmbRr!}yt*nfLnQy=)!U1QLk&1P5Z9q*(y^#1R5@
z92x$JV}B)R;N-q>YtQd~@<w-t^2VJ4g!YX+>{wMVt9P0yDFa{p&iED*9xbYT^ui~;
zTo;{yF}W0fmoJj9Uum3=DZcxte?P at iH+9Qwa9nhCjZLIVRvsLmF#!qNP at NnJ$Qoeq
zCx+}#vN{&}*+hJUlI`CAMalEYwS#CP=Dnv3nMz8w#Uj4Dmv%tyKmP?L(mL44RI^{2
z7OsfYPwPs`NEzjr+MK(Ry`r}^-%z4dp1~P(C&d0kA7RtH{w&cO69439!tZY`m$P1k
z|4MMJv?_oU1ropQ5BwBVs~LE<omBpEuIgT`Hh*_})54uQkF9-A<c-I_4nd*`?Ozva
zVUUaMePql+LMh)d4a5Z}oRDlU#IDP?{R)A!HonoT>>}l_*AF#hEau;Vj~l`1J=d$8
zmtBhYQ3;*~Dq#g219Z0UESF{>cOQOENz>Hx5R$FmSq=>1!WMA-ryBp}{d$_;)*4_9
z60^D}Kg;qoaiP`6i7l^w(RL)T^>*`O8m<7vl2z0$LS){Pjn6JRSSZ0D*m+5??n=h0
zsHv${UN(Ioo9vu(9C?afcX(7%r6nf+yvN(CK_5E=&o7<A1RF$EoTrxUQ}aG5eCvR1
z0LTk~AjZEV0ZnOrn+80cO|3K#<B7l_RrqeUml$OC`sGmOUU#b3uT_1V1_ at M2fZfTC
zRc&~5)5SQx3llBME_DAFDM3UxIjB_B1LdfA+pv&2f|YJ8>4t@^dvL~cFCkW!MYf$6
zxYodFaC~B7B6ASLwCHEU*67UzR40$=Gfho2>yKA5;^f}MH=q9G-jy`XL@}E#JhhB7
z2-J6brk<dm<)xiFSN|;FBy(0TQvpR2=nOC8{YmZM9Gln5{<D7f at -2=3un!IGdnB|c
zj|DtVR=MRGNOvop<Vb`ZJovu;$pD87vX)-D>EWAOSARd1CiC#^mPpG~KU><$y$05x
z=0O{T*BKq69OZq-u5TU?eGFVx@#w=S9JvLOyc@^V(TqMlDW|6VbH{{+>2QijG-gjo
zUElusp^i$Nn$f~65(tmq at rm9tWS$M<HfZ7BVZ~n#pQ>^_KM=|l>`;pFlY3}{*HMtv
zhOHa_i&e5nh{of=0+M2S=;L}f$Xo<bBstrvixH((1+g@$I%{I>SacAOSIrhhZlI}E
zT)f at ku^uHL7DtwjDDcl7PbPRRh#2aF!zT7zf8JmyThC{f)QNu#4pyY!pd{-DsKJFj
zP~NZ5_D(ztZTxLr0ca>c9Ecq5h)0fq{Ynd)%NhDl)i{N%SgJkwxpo6HNBF)jzBy*Q
zdA??SzMa8fyc&6^Qr(q9ES0^W>*AN9TR9xzR;m`bFIS!Wy~C99V_zp<to*i#Ym>{a
zuuOfNnz&^gHGJCXp at 4z^pucs-C45VaUCWap*ED){L(b9raZVuRKwnBH@#Hy13 at xaq
zRwkQil5e>u at pnHeSKq+CEAI9EFW4emFEw`9{^z;#As3RpY%VvCx;qxJvr-Lab{aQd
z4|Z;@x22J!)sj0Cy7N8T`@7F17_!CNNv;lQ%LC=z!M{y+d!z0SNqr%<XDb>cd+Q~(
zryVHF!D&5~R+`|h&dtp&vi+PFEro3Ju;Fk97XMvhW4LjLN?a!i&b?UwBX7%`()}B^
zo)3v~yhNn3iyPJcA5GW&NcH#sO9_#^iOg$7BI}CCCF|ORi|k0a*0q(9J at 1uyscT##
zgtEumUb(VD#x*Y29v9hs at 8^f_AMm>OyzV{cxgO)N)F7>=_Ds=3SFw3Hdv`_~e<KTa
zl9H3r%Az0y;##TMClI{t87G$&{&~PJGEit~;uJz{ef?@=^5C4>ImHJ4-oLV;`&US*
z{hzDGq5O?DT!50v<M9&{qqq*EJw2glx2`Fs%cEvS&Zv8 at Qk{?I967GsRpouaM{~zb
zdBBjySyO0aT7H5(rZw$7IaBI$7HAbhZoM|8r5uZ%TGeylh?CP#iH3pmA5V7pgcWwb
zkZdw6)v=kn7{?OB1HW3oZBUbUWXJaxtMcRcL(cHJ(V)?(rY3~<!wLBe2@@(VVkdM`
zP&J8MZlmp$JhyOv<$V3J^mTsQ#a7#_=2<LOb3u4bBe!Aw$_H?!aFs|8-c=p-W~GiM
zYKUM(r^qF7#03AyVTS8Zb`1>;sWZyGA8pO~mNN!z2)t^c$GmNR!#-pkywNE6zd&td
zvklX#Gm)|xiK}|&Qh-VC8WK$(l>RhSrzqQG)FhS03SLznwDrNij#+OdPyPHp6L{YE
zdqfH>d9&2%9{ssG_VIw at s>XTS0*=`XejNuh#9Co(+UBkv9NMjZ0~vHzg&vom;=``-
zr}KNECw3zVp&P_v(A0J;b<K;zc8i*Z2AvU6C>YXDEEGyt`iXP*x;hO1im}fd9#o_`
z%cCLU-JGMhiBUD1>pL;xz$Z3dl#M?UTl81VOGUk_pC#7YDC?^HfG;hN?%!%sjOci?
zw%5|HC1zYP*dglwR#9k{5hVHZ!SRpdfTO1H#x&o**0Islr^Lst7l=u`6#lEmEwI#q
z!<YXk_h(DVr0cL4D2<Oeb}?e2xJNFZz2wO{?Bt#8Um9b-%+rU<Bp8-T6XAeAS#q4*
z+#_;MGoPZZ at Sn>b;Xb9743D7WzvYiQK{Dw0?;%(X=8=J|T*TNJ!NFv}m;!(gObiU%
z=H}-9U&**2rDTQ_6^=y^^Z(pjuJGph)%7ouZxt04S-`KrExc*|-s0jL*D2$VxsF7o
zP64l(GbAcudx=s)qhRz1ybn$Vp!U}IUkNblFyg9w){>KwoW6wa_yyf-4h{}h9RIcM
zqcC2Wbgflq at U`G%-LKhbR&vA6uB%puR7l===Ck(nkwSj?f`)U$)Ru1FrIzB61#wlO
zGJ=PJ$b74+z3pus29a~V=iFy at S9*2h=5UYS@{>qJg|B;5;~(eG?W3@%MpRRBwy79>
zmRiyMH@?hleWwuC%a#VSTm#R~IJ8?45M9fY8Hdp%cD)D3;a=-7&W8_m+ne3Wy$eoG
zrds8{1eJW^<cSpt#c8hwF`^xe1QP<?=iOmV+MTfjBA&+=j1jBlM@^Uqwqi}P(b3UH
zVP8pdDc%u3&hMLWLAjzD;d|T?@r{cO_-($uu8?{Z)?NF}S;(><yDq;G;-G!bcc#Vk
zme`^Q_72t6aIB<YCNUTcRW7k4yZO~<8<Bh+`9S`Reg-_ES~of~c}TcazffZh3TQLI
z8GKA`%(oLd%vUdvd=4X!B}ln(;R3jbi|Zw${fw3?lryX_MPqgGd3z(Qk1u|6ANbD8
z{~buzTwOWJ3b=<bqjy)IEqP_+MZ9+^kBAx_OmGWhzJHl)Tt==n{%<oM++O$&Z?{b?
z<+OmM5q)ja&(I6X0?c2+a)?#n66p$K`j{c<Q;si$RpM;Z0%!1CpSZ-0<3OqVK7$YN
zUQRfE`A&ljeVf<aoNTW(Q^n)I`yZx-m?UlgD1Bw?D1siz&scj_F3&`nbPQ);AS0IT
zx*Bh`cWXpgD)p2{x{(i!*>WR=<VpO*)}Rj^xb5UZL^=xN9zt#c{2ZcmogB9t-pwTD
zKqu3kopX)Id<Sqk={`@)&Cv1G))bl4&1oF+bgeASkI#X?F9;{ZV<F}Ky-H{F<7x%V
zg=+oVzfSao^L{JUJb;V)WgMSLZybU%I4RM&oB#R)$}PJFxc4G=6X>6Zzy$t at sUfC?
zc?6X*=4}NWx4&)S9f5we#~1R$W8ThQrMFVk%!+pm{X>zWekfyp0z}^?pQ1?NZxY*y
zqty|>XU&zWKYzV>V`l$k2qpyG->p^x!UICoMP7->?L*||Uc9z_E{hZujMP~R8S8av
z#I!IN`-(eQBA at +LZ~F|gM~`P^{VhA-yBR=5W9RRb-iKVb?B*)vuuBB)9%+Pkeg9ZY
z0(bs9P at 6>c<~uG at _GfK41<#pEWZ)B-_2w<?1jIWmjo9hu3u&VJBh$ovk-qNc<eR=s
zDRJI4(d-iEvIlaAyTZ^#?^T51wQ8M`oLr`SU)-od(9us3<D-R at 1AmK1ufc(h2DiS~
z-6UB^?}7a^z5<FLmqnLMIi`^s8?D0fL$Q=0!tdeu05=bhk?uE4{pU(zUmikvXQg&U
zFx9MYo{q3q;ouaaz?D+cw!Ay*kP9^s=*v*Y1%L9m$Gki^GhI&@BMD;^(^Gm8g$T9Y
zldvSrt^2xH0gScJ9^^1&A8nj9J&CuAD+ZnK5 at fUW`*+>wDP_>!+RfuwPc0E(?dueY
zd18!Oka+g;Oe4|yc~wM2#KuEYBi+58-sH<qL&{R^F4FAdK;azy^$*WpZbF3biL&6b
zoDW~@X}iOT=^AMCYyG>CdJ;vcHQ+KXdt^v`*Nc%_;|)G{lk!{B at z-a(_NbNgBCZCJ
zm-jRtpBR`7R!dh0pI>_IM<$KZH3UEUYANC{-6}8<A)?F)lsb6h46%9 at GD2(~YR5a5
z?pK1qoCWl%8EFD%+R^D&FVg0XZMSNDn&-1pTbqKL<`h`Y>k(9y<)QvOD*ktXx#zn+
zi`)FkeJgAY5xJQd-TQo-^Y#iVY5YvVZ2uWQ5<M+^Bd)+FqJM0iO|{WXx7l&)5xQ$N
z$m=vx!vH<sEU6W@&hHC=j2T5GwE at w(IEC*q+E5<p^c16vI9|9_bn%9~YjzP{j0{NQ
zzLEP}_pLd9F{1ux=5EiIaYq(CJO%(2b7*M(pl>{*9z}j9vaPBsI7 at E5xjN;bl{(V7
zTDu}ln{IjLqmf<5q9E|h{q|q=5iOW{BL8{0 at xcgCc(z=-YOw_PHPZOs at 5Yr81`__+
zjf<^XIuX^9vc30Ts(c*9qi^X7!n4*QhWxy%!m+~jj{)pj+a|b!X1X;LP&+fhI)mGJ
zT(fS}+v%fd*w>rSkb4Vk%wRFhs`iXqVbv;_>fF_@%ZT=EYsMb;SR<6 at ZZFT8#E*wN
zE4qL+<zIBH_{^KrLfw;u{P`YbMe1rwaHho4O0L}?_h5dZpOmEf2z;if9r~JU$w+5y
zhRTsn2w3>VHv3bxWY?TtqTO>!JQ8Zx6`Aqlj!cKo+9ao^zq}2g+x%6LajFJ?O4|i7
zJ%4;x)32>UjkE-*QBXRpO%hlRv+sy=p)~n&XcQvCCsS)iU4Irs|C1NXrezr08Jns}
z6#PhSJ~6U!mEKo$X;l`BJU7x^Dvq7B$HySO^A(7Y<$EE=$zPFhMOwcma*ao@@PUS0
zAs$tqeWm5GEor&tuI_tV%^N5Y9s!xxD=)7&D9j@#q5Sz4#XXUx8Pg0jcF9bf1LOK1
z-k^nj4b1z00o|JVYmnl+EMmgdZ^mk0<=Y?&13XEW-_4|cfjfo|+Wi+VClIA0W_$~+
zuu>y&=hj0Cw1L)XrhbigC2#y~wUH3(k3);uj^_V6*>|OMRnF#*4~fI!zwbv!4i5ti
zd);Z_Az;$!+m5$*WTxexFw)p|mM&`a=NA_$u!xlzB1=GXLgySF)N%klSkiSYTn21D
z<8Ql<yVwG!Dt8wq`Uhu(3sfZzG?7FOt#4xF-I9z*&MBX<95v&H9=Z=W*eF*uKeEx8
z-ICved>`$S(#x`%*XWEz7$1N)eVI=PR^fW1W+Jgf at AEVq@NxeD!`v7;SLcsWENOF(
zTW-n4uhQEb?hD`TQvo)+x_nv#B1`sNiT<I4-f20_XDkT0 at 3SIdU%S<bR>h&<ssT%H
zM~R-tx`d;P*I#PR7B6{1VfX<rt+Kt(;mXww_(Cu?QTJi5FtbALH_4?5*ot$;`^&k_
zu(l$|^=}rI8Ut;~TdF4b0Y8RwOk_G~4SNOdRuIq1^@j(~+A2o|G4gc6dEXe6FpyMQ
zN3WO-iL7^qs;@^DGE^083`USdZucZkDv*<JPlr at 2UOE&;NM=Mc7Gz;dQndxdlMitH
zr!W|~6k2nRM$_h(Tp at 27?9=ca-YmJE$wo#Eb*0YtD{ZD&<Q#O3<5xUI>K`O(nccnt
z^UVAFDTDg*4<t^AH9kD69n(d0rOYiz69fk{o)WvNd#qeS)^0X&g+tv$cltq{LI3IL
z#L+wamzorSa`!|Qwij|%C<bG?zCj}zor2J$sPyk?tgmvP#(roK<2NsR#c!jsx7v}_
z0Ux+*ai<zU^Z$^topc;qhrf1^XM6rmz%384kxPsDlB%Fw-hJyej?PP{rEMYNqs{y~
z;tCdzLO4nI=ahL~D54{8r5=98_wq-N3n4kc%dh+WPcry|lF~JccYGA2KzZ2=oZ90u
zb0xnVtm|;z$C2qqr1 at SVFV?+<I!vJh|K%x+XEP5JyXB_btORj8$m-Uf&O-|Fx}60C
zsq~4(*|@V+`J~gEC&ut4b(hf4dyjneDU80Rgs1s-6yH5`?9|x(04T&@<&~6_Ud8}2
zJ{Cfm6||m`n=PtJUnN|oUfv5Zu1UlsDtysV749gFG=b at Nz^&wDOoixGgviiSm+qKj
zpHVizNEuIY?Xn$74N|FUIaAN=^{ragH{%-rY^nZ5n&>~sr>$*#)Lu!Fjf9>{W!N$0
zE$kuknpuc9)I>`S-}b8Q_I*Tnk at AwBKq30MDx;O?aKZ_{ao_=QO(?$R3Sr<;C1&Jo
z+Vk#D5VA9|&gSC~(kr{%<!;mO3WSGj5fq64>HOh4G7`ZGddoj{8Lx8aO?xR at SyD;G
zJ{$*7WE7G|y+p`&6vssBJtW6Fywt;*QAm6}j*|~>s_CEm`!_p}V!>P{a0d4W&*z*D
zOB&~odsuY&03CU`s}P@)lQZt!<=wG%`_N%Q{@m`l+1k9CR_e$r8@=h=N565yPd)xL
zE- at k?{AV0UZm$*ueCTALQusEdS057IH&S^CYR^BhYRqq|C;pSP#sU2?kNxB#V7ITd
zB?DkW<kel_N!7ERg9Zaiz%63|zNwEi-5Rx8zs!B%YQlVF_8pjD*DT`wnt~&d)hYVm
zr<_3ic8bV;t<W}ccXXs0k)~Z)+3D@=X{R3 at Cf!t+mOCrh3d`MXPT~JCK2W+pKAi<t
z?+D))^7A;h3J~{qH;ldAH at K<D at KOuKgJ!({NT=y&t|#it-*js;UQI$3fQ#QZK35B{
zj<o{ok9?ZvwDPfwFI_}f+*Oyn<$Eyg>tOfatpZ*Q%QRiH*z8v8g!z>Bn-lY-smapy
zC!~E22jEVH$z?TZoVTF0^>s`X4f0F*jHY6 at 27&sak*sBhK`iA6QXw~YI>iQe5zT4c
z;}8#$09xg)e?L%_yF2nx+t16Psu(U?!K(OtiHQQPC9hO%J2iR+Qh=p_1Q4H}*a`er
zdJa&^OKUjNNO(zj-Zs^NE<6wDeJ1c@?$a<y#+=ysojA4culR%^-44v{N>+FhIs9Gv
zaD=NC#hSMNJ$pI$J!TR&nLsK*e3WxGUNEZc5gOcP97UT$*5Vx*&5*ZB%inn((>GNp
zA at F_4Q<s^9y35yqJw*1twZ3AsuIN=Lh1(N005)a>X+$~Vu~u3)W(NFamY<K;g8mvw
z6ooZzW)aAq@%A$;sj1<?1K*b&?+=!#b_Z0RhbXYPn#RF3#_F%zvrUOhYaDAdt<4xF
z{Th;a=M;fRG+PiB at usU*-IX=qP`jWl#Rb_Rw&>U%%?@$zV<c(tK6$x{tA4ocQVQ^m
zCLIO7*gLz3b$Fv`G1E=Q6SXo}kXtFGY<Imlq#96c_1L30GqsD)1$g{|`~bS4E+D9b
zv9eBK>EX^KxdmKldi%dKCAZ!hn=g>@@%0P(UjNKkO*5VsZ`u16s6vf-R+e8XXcCfr
zTo4nU_ftE$80-ffklm{Y25&JQM=yK`tWRZZK=>eK$AN=;SVZ5Oy{ODQ>BC*4jJ&nC
zh(ay=%_)hZU05TPHrA}pw?)Y|;IgHA%23=G)@ch94p0T$Hx!7`OijK#gE(?%xzqn!
z8;cXRtNFsYZC!h at GK-S0^Rv#;mN;)5SNo(Dh!N#e>o0n9tdP&aU at B-5X;W>qnwFny
z_w?%o%w9IT&h|FZIAYm`I?qaxKL2=z;`mVl5rR^E?vL*uCJ2|%lf{MYgA19f2W9Th
z5h~8z6^xAA4OR0k{=OP})@UN)5bSYBnWMSS_-<OVgQ{*6KOQMhrk?33$W{3n(9ipo
zJ$L%tP=h%(SH^%hbKD2a)Gt9;{3Qnxzhi$pq~c{Cr`Ica6EBD9|4_=m8||h31D0Sk
za6kGoR56x=B~oSH9kKUET6PinlvgcXyX)m4c+#Z}MBHj293O6{!N_vJL`9wN^^v+)
zvQv^`%gC^QqyECquip1_qf)2*leWExA>xF77>~h at co#`kouDJXQ`YZ8HgC4(=qd-W
zdp+%8Ff)uHUlxc9An0bA_EJYqFy~2&ky{$j78xJ`kjc9^W4|TRMl_}*{1Q(e0j690
z8&I!dX<)qk`X0wn0#>X#HRDlj`^xUFrmJ5Fx{iyh`}N-HPY%Rj<oPiq08P#fBY!5$
z#26}9;8Z;LTjJ at G5oa|WFT!!g`2HW00rKYsMh=E*X##g10nIBV^-P|2_HtVO3gOZb
zGh`=3hMrAlAO*N%y`4$r<+}ZA^bIsVLhkz+H!?&ZMYPNgQHQ+eet}jF4_~Ft2h&h7
zfaM_>+Ya at hpf{Ni%BSn#Unl>0W`jsrCCY}7hCd^I%LqaPWyC%D7qvmM_w;lhG*op}
zcj at fo?uM{v#Rc_*JgThPo456<m9v9AQ>4iY|7<Wn2tQ*S7=zAKI=rmBgC>cTqNUkW
zq?^LxrM0MGT%0^T3}2-SFoPW(9SQF#9*-lJ9u`xH10DJChCLeBk*<D-i-{XElpgpY
zjNyqeVYdp9uvu2hAP}|$S3DD)hjtnxGCj4*7NztWqDItXqgKxF at 6l+(uV3uj#Eh*J
z1%~pB1L$NqsnJRp7}7KP0f^UsH}m_LU*x`i<-B}QZs;K-b?ZN15%ATdB;iG-Phqg6
z<j&=lcmT!)vFE$bD!$<|6U*>s-i5#xusi*OHz5j|0*h;2lcUh-crB-EXSn7NER*Oj
zz80JO9r#VI5NJ-Eg3vl)N%5R)e$htbB?zGh25fHAqwS@&U^(G1?tCESLp)N_wlL*3
z2RFv?QK_YKHi+wNTv$2 at W1<xj2i3<WBVnV=!DAXXD{V?Yn>7cT;-v5QJo!ZbzCf^k
z7agiJ$+@^7jCx;Esfqi*Vkle*_<ESI<R<8PUnFcNiux=?TuC)dtwxDdnzL+>R|ktU
zQUVu{mmglm6IQ9Y at ofKEO^(bGUW%9N3Vrh)LI>0*fAk+E2fR6{Hx}tR7`4^uUFok;
z)LQj&^Odnz%v0MqB5b~FY^kBDBrC&Z+uh!dtiGd7FMzcfh at eg|yFwsw*LMWpBZwZ_
znXtC3lylURR`76u%dah-0Zox=W*;3E6PjPp`ADf0%ddA-in#JmQ(ms5khu1Ge?{by
zzaL6%4KHU1lTS1Gx>5rV+|?24F?o}UpSDwwAIxgnaRHKg`Q`h9jUCQAbqFtfpwfO$
zeIGTm;$B?Ia?Rbl3dNZ-uN-JP7mU7DFJ(+cs>V}OQ`;$86+er$uyU0QAij;9VpQYz
z-%EZj0)kC_bMh}|w3+P`VGFkf+<vd7H%=JfRUfka{nQa{73?}+o6>*C(4bp8sT6Rd
z7>|mPB3=({EfN>g)m1?39ko$X!iTM9UTH+g8`aO3<6uzk at rz%ilR0CkC<YbdT5%oz
zQZ7raN;yU>N3EMu)$^7&rZ54U<Au&u*iUGFq24?nM`Bb`P_PnXC>+O|?B-<$yl2+&
zda%gw=sdzj6*&7kw!cQxVJ1E*D?lbz(=TooQ`3LAeKhk7^I`;IkaVfV{Is$Ty|_6x
zfom~%5y3zwsEZ>*2CfMa6sc*FQ+_2Ej84Z0r8}Q0<5C+DS4&Ira<Wln;9f~~U6c at k
zIA`kyz-|7Y3y{<jBlW}{yk$sH-Ilyd+T1)huV!vxhILqZ*`5<i#&Bn++}5B-^~1b<
z8TKJ3=daU+35<lG?ZUo&E+^GJDVU)VDM}{zfG3AWoJTB)Y{@{8!x)dt<J%Rnz4O0P
z4qoWbt0+6;z)9q8Qa0-xT?aBpsN5Vu@(B8I4D04}MQnMMFS%w4?Q)NWi}ktryWx}_
znU8F?NuTlzxBX6wy5C5Rv03AK4o;r_&BvYkTXIc9Yc2NA*Y^W6EBq;AD+(;xe?4iq
zY%ywwo{6{QVF`RKBbAi{oG(UV85{uJ7cdytyGBS}uP}=Q&t(oQ+z5<sbs7HPT at G>3
zj^c`cp>grbH=Qtqv!bZ(<Q<(#YFMN>w9qJA2iJHKSZy2uMl}D48hMe%p<=AVXjivg
zF7Y>q0S-Wq?wjLs8}-nAm&;l1po3BDwf*)VwO$DnM5M>5`5}m|_NhCaL8URu&`D#N
z|53hAO<ez>IYrxq`<*IG17lo)RfjqeqVs`$q~<{K14|ZGjQ|PYM58;ZUDG?ZA5tQw
z at Yvbe96^O#)6{j1r)@*)3Jdu)+2WEqCeo at ZkmYHLofb|-mbp>BZ_3T`kOeivx~&zs
z at vwWXTe<j$^1IN+FWwH9s9N$#nDYk|bxWM&QkyWTHlV0m)gQL(EUz%xxXG;;=dm{*
zuh9pec9SirJG8xAZq>ZJXb)k#GE~#KN0<2SU`fM6<KJm$@Kif<`}HxIfr3Bn&ECz4
zi_i6LSTA<lUCp}t2m*D!XA&FCKZ0cD{gPJS>#Z%IVi#|<6E)9%k5+(5EEj^ANcSUh
zG=<Xbf-kLtug|*PhMdNq_B1y`iSWk?mixzYMwmBHrfjkVtg#6~3>B>_-SAxdx3h4E
zo;povgBU@=e=AH8qLV@(BE`24TF)`*DnL*~LBxBAqw9 at _vHkJ9pIWVr%hO{F<u?x$
zulHwYMjNh at 4`B5<X#A#})~Xf`q$Uu=o_{%YQhl~Nvh2KP6R)!OWcT`78Fjv(+--d=
z*LLwwg-R=tc!>T6)i3{<l|{+0fxg^YlTIM55&Wj}x|H6>uG!Q$F5+|~>_RMX)m5kW
zij{@qpm%n!x7kD5?xv&uz+`p)^h{&c;Bjk8tC$8eP5U)J7bAB!W|u#k<G7#V!BF(U
z6>?<R{Mzpl+rE&L*uS#4%e~wl?a?ja;n7V4yJ1vT<W?)6jA at yOt5-gM;_mjRfF>zH
zBE<M4J6KKp1ETx8Hj056?Y(mGf^$=A-CRvAHF-H_<VNcH)RQmtsy&oG(XiXJHbz3}
zLRzp{Ik7z`OzNJ|wShnx(~j#X{j8WES~th`L~}0aNo at O7j~>bpV}H{zbubwUP-<)A
zzQHSVb#o|Rfr5`rMgLX|_aBOhpxaC#6f^ek-o3l0S0$&$`eZLME^+j&v`M7>)Iwvf
zxbEZGQ#(~&hV`LitO(}GsHeO!^HY9iAelP;{O`|q&W~cxcd0vyOCFes>1QDz`qB0^
zDLhoYCm(75_KxfhLUJ)9wD3cf;FCUV--?RV!gcfw)6L4cI at Kp4MW)w4yj|bCIiP^S
zCX^6hT-nZD?@_nBzA=A#bf{5%LHs9MbB5pQo~aaN>VWU#EOvSt-#*Kc9H=SD4b?z$
z?EYLXd{O-Yq91D0(Py$q-?T>GJ+}dxxWl79r~$E1;I#`13cBZBN|N)$8Y!Re=VB}9
zP3=`rZqA>dy6-Js<TK;mS*zH~K(f;|J at xswU*vNriH;l~tbT9Kt5Y$+8E0A at vr?EM
z%KZcTD(e2()c*+PjRn@|_mgw_A64JB73W5Bo>Ozhy)F84E5)qJyN4t_=tQo9H#_=O
zWtQD1B)=6^8MjW~7)Xr^jcI4?ffrc+5LqoT6_MoR>>ZC*?p`TSQEO!OXge{On=Vmv
z*_XRM+A%=H8*rYek2VH~ZqAd9O6>LK)MI0if%05oL9)Bg|0a+1`n3>AT+{E3QTM+g
zw+ev+Y3%#_<&7PUQz{~=W3^6(YkWZftbz(c|AEavO%S75-Xi^v2 at s$1E3zE=Krfx{
zZ$M}!t06$M>=up$m_*|%?ms$7ic6CfDfayKEwxSi?zrYTXzg`Qp*xGn8;wYy|C&ob
zaA5Q#;B?J`<s+?HpQE4rKR?pKjyJ3`>rdL+Z*&#ce=hHZosCadYES`=W9*dG;W1l#
zA*>#C%?BHRla<rc#J5vh1`o~nMhL7&WCmr30*g}hM&qP&^$@`?o_}$kzl>AYv>zTH
zii`#0No}7}n|bDu**@787kyKm0)@anua3U`ff{vF+asRCql(u4PX$6CDUnI71e&&F
zvgoc%<80{8pPdHNt-g7Qwgmh<?{30LLC6krI=)M;?K%`9s+?5CO=bVi19(q)F8*pd
zk;cQL_h1|i-CN*ytw1&e9I7Mk5f57xH|WoF!lna#y*msA5!U$04!y*MUT*BxPKVrF
zHOz>hAQhm3g>1n;5gkuzu2<v+>zA(*trbrRwntm_%K+|nI*tP81DpI{w)|th(1Qba
z#uZKJ*&V4TtX{h@&4MFcJn^aND2sAXqu=w;a|6+&_I3tX`<Y1HztDiR-x~6~TRkkq
zhsh$K#xixw|AIWaiF#z$D=p)}mD7Lmz-pV#ZcEuZy8???US-W!G|fdqAYopP?pDBx
z|5lgjQQktLN50N-LH><B<lSexn`q#{Wd1H_b;WYDGTqs4-}8Vc<Y!l~03H*<@0#l=
zFUcWVTB>$m&`2a5rOc{ktu`UDDio(E!(JiO!%zHu86}gNZ?5uFJ=&Q(wtt{57Qvjd
z3kkCx?R00OT at 5!~wbOfgb|=HIWhZ+^n)WmCdmyRZ%Y)jtHet$sLq)8~pA1CIP=*z1
zt=94CR4ZE&ZL#jAv1|Vlr{9~PyaLg=!P-i^9DK$x6TB)a^dTAd(bU<Qw0}Wzfck0%
zuYM;1xcIr3AagFJc4d!*b&hN~MeW%Hx#MBcB(AY6#kO;xm}Pa5smmy+v>*PaHtoJ9
zCW2`j1Nayyv(jNer46he7hgU*89}vsuiRxC#U^{Shq1Ooh27guLXWt at IFkR-@CMp+
z7XXMkJ`oNnHLX%BkWRR;nNQwrVB|oyHvDl>bGa02YY1XQ`tcEjP}PUvxwe at YJT{EM
z=4PLtP}04&Fzk;{Y|U~Kpmf0Bil<b_0$<m<sAe0=<Kpg`IqC|>(+7?`{LnNKX{pes
zu9S2J7ae=5Ok~4)13eO+oba{8sgk-*7#@6vCNy%dJhA~i{s2ugB8^@!IvaAKWOQ0$
zzs166*fun$+xReEN8}26eDCYGBiTq+?~cmg$0rt&%DmF~2<j`vvxG?da|8lq?wXJ?
zG at w2t-3Q*`T6~oYPI>BS{uvbHEvm2s-d6T!Hb<alxAJt1U5BTep?vOE at 48_&3-P;h
z$^A_SJM&d5F7 at 195zf#X3?7P at L^a>Mp9_&rT0z5>+uK9AfU at rD$NQndSCcS<2^ptX
zd8Io?oHR9Y0-y6|H+<P<cm5?P@@Q(#IjWM=1aJl;A*8#8JmP6%@x&3o`lqBqkEuO0
zyhyREiFh?;3?Y1>bnL|Y>z$cTAkG~$i5V at q*0!X-!bqgOqm|o^A+)94yOxvwg;0#B
zG#z-!K{id=F=)At=@#xwW20%6k=<)>5`BAjNO}LbqoQypq5s~z+$PP+-wWkL%c;78
znYo14c|R((yJBX%f(38g+|`R9v6%|tM#t#PNi6<HtV5W*3e!@zIKwz*SN5Q#R5f})
zracFPNDG=59`vexW!$+j(A1>7<0nc~_~9nOb8b!tXXq1qLq>p6>h9I)d9!n>$3hHJ
zOS$cA8?3mVY;Rw{US!Bu=jXTbC$WMxk$R;gR6>x9W~JPtEq<lo%K!4ng;V1>VYlma
zGdfgyHgWxW-#7Ri?ZGSI2;ILlR}3TYvje9JEac~BJx_&{&bp8>^EuV^260}Fet*+-
z1yfhesq&SRzJ>7B4Z&G8<k_bdVp at kyjV+OH(|LQzM(kd<eBhQh?u?=rBI&p_y5WPN
zg%>~){hR>{ExynFW{=mokL~5S)WdRnx+KE5vD~`Le-pPxMOLdvT{RjFV`B^y&&L4=
zJrUM!?>*E7z`Mgv7e6Gu at 0$Sw{|N=I4o}Yu_3f`ek*REFYbJiD^lbIdT9y^(WE3z@
zE%dLVrw$Mxg0qIc1QHttYE at DJ0V@QfbG at nN<V-QK9TGy#FC+{KM|#S!cEcmw8GCGl
zZ at zKBzi~v5kVy)&8$5iTFmmlLkq2h4w&d<<9chcfSJTNZG%&9kK3A{=j=CV0_ZI_>
z&I^PHMoZ~`<#sPOhWrhE?5d37_mnR7{Qae4NH&e;?(V+3%i0p)+_0af&E_jU5#VI2
zV!n+CCJ+g|zZ&g$3hh43l}&gl?}^u{;0FsZWS%w3A&sIrhQj*4MFh6uQWLyIq%(~-
z=1RSF8N2 at c`J)5KK1*EYL~G-`z%`nP=)P3n%AOtBI^HIl<=LxHMBl|h4-0Jh!WrJ+
zN6aH}yzDs at CF;U8E$l(FJ0%D~N!A3E^}zD3nN82h1xR``VD9FK=3qxfIqn+^nO<J+
z7vtpf^(UbXCyt79*yO6VCXRr2vhLe%>ID`_3T}E}Zq4~$9zF|4kP;oOFrr+yUxuK8
zND^#v{$JVlw^x(f*4NFILIL#g!F`pKs(!gw>1uJW)^*Bx(B54|No~jl6H8$g9U<ZO
z_(6*V at 1x_kFoQkKYg%+k;Ae4iHS3&g8nH3*EMs_1 at N>L%wTfQovqPuVy1}4h*e<{@
z7xmtV^G#fTipEej-%on=vj>OnO7%|}D7A_Xo at l6X61&E`*a|QpP6!lqV&S%yyfW^Q
z4=OSyHoyHrdMg_R8V5TC5t#{Ol9>)rpNYhhpDV+&+<nc!^yzI#JS>c0yZvlSQf{}m
z-~tPhQA)ai?e&JX(e0SZ-<zS#q#WqzPVo}Mgs_F{ZSXcLN_~A(dcd3Enzr4$E2WYD
zjov8gzD5Q6#pacq68~+JJqfPZ+|)?sqdbIVQ4>N?kSd9DW9x}0_8zbhVe{vP74lkW
zA9a?*;q{f at QrNBK{=+M(*pZq<`rD+B>~O-v>t#*~viu2jVMEnY2eotALqHX|2yqb*
zzuW_0^M(Ry-W~Mf at aA+~h`5)H6IPaF^Lxx_?iqOOc5~GG6>!qcufV75MIO)REh%{Z
z6_|yN0fb_dBGQxy%dcN-%?vZ#dGocvJ^9)a$yRom^6C}!gLHQvcjx|dgXBN%qINf1
z{u9YU8GI<^1Y7IwrLK#EtLrECt^iQEZyG_hOa?B!7u=zYK}hu<IY?G6&K}rFzD7YU
zT`M}dAP3ZPwQGHp|2+A8SaxNn9vjbrG~o12wtJ%B@(I#>b$Gf at 3?x6HgkbKFLlABX
z8-L>A-u7Ria{yz2nxDdBQG$VD*hKQY<rM1KYGbZfd2d0C+|@2Q^>*+OS&HSV=RH;3
zW4EMaJ&G;#Z-i5M$o<jBsQ&nMu4B}nw;;*w-iT;D`<1`LB^iYNc*E||tJ9-q>z2dX
z_Skn7n~aCz;8!>R%+*sd#-f?-m at v>NN>Gfu^a1pJVWBG$#wIaXgGm}YkikmWv(<g!
zvL`joqG6q&GBF3n%W0MO^|A%VaitZ+TU^vi8FMVB>}tXo(_1)3;sduKv#|r$hyGsv
ztgXa4^BV4MEYj64f}Ean)hKPDYbIu^=X-regSqFMnpGTE2mHMk*gj{QU<PyfWOq{q
zzPV*iR#F&PQ|?$FmNjobXk at f&g+)F9mKojO>=2|ygBGm*EQs2Cz+b2Mhk=79tct at 9
z9_%CjI^!3J;s6cfWK?I`GV3aw;?Pkl1=`6Zwp!57$FpI<*;)a9oTs$iqh7?G{zv^N
zDZd+zj$l1WDv)LE*&*sJl>G6gEg>PYM5$HJ{;Aw1vDRpujngXS+!^*uXr5pHcdz>R
zIvN at h1pKD}_xDmvaxJ1Cu4rxe*Sq6?kvPnnd;$Iaut&XsSwoMjr*>D)0$Cwc;O|)p
zKtnfMjLawF!=i5u^wrXd61mO!_l4AJADM=tuz&z3{G8+oKb2V{fFq7kZ>e!n6)c1E
z!Luj!Qt_$}>mY%vA(0x at OBy|O2wKLyyS4$0PZts4XEdNkM{IZd_<4I>NF#ZgE%J(U
z6S^wh275*#!x$<{V`JdQtL4I;OJ}L<UlQyGbA0jr9!?87p{2zo=OJl9dSzMF90)@u
zc!wpi(~lcZdjIobbA at 5>g|EaQ$8dkp$nv5;<M2rs+nxz`A0YpEf^`+ku$M53(V*P4
zVBB2;YMkUHV5gX+=J7PaqMXaXqgO*YMA<JVomE$Bv^0YcD4-2Y_~c+sxc!RpC{;1N
zbxq(RvZG%!g`uDeGb(<3G4Slo<a3YwXll{-Tdex7-3;8?{zh8%c|jbU_*cANB^Vr8
zk|+QHk6P9v<4*lYPgI4zkng6X4XpYFZf+emA2u6gTVS$Jtui`%H4UsBGA?~c1+}ES
z#(G>b?f;-jH!+FRq34QiK?EzsX>ri|vBVV>0Y3{mgR-7x<+Eo0i*wTn4h{nez2!I3
z39Ki}GaUxTLB!i8{R*r^LDr0^Grjg{m8*rpQxq8!USvtznh#+!pRKe-P_*3Tw-)KU
zw(I0VKc}cNE0}-Q$YUAZgB7%#skGD|3bpyqCGWugR*#B-7$c?w at Mvg-Ow3A``wt>^
z1rr_pTcTElP1f?}vlw<t*jq^CCRof}zL9M@*;Q{15cQMcz4z0VDmi&&U|caND8N{B
zvSg}^$S^4|P7=z{l4M6ptFt4Ktj}+F^0s$+u`RVs at Bx<-5#@l8a!69}zF6LB&_Vr_
zWvZU~=uAoP33fh_yKJi9Zy4uA7u0PbR7&REq?A6b?<36 at CY`+-a(7NB8`gz|gA`*%
zzi^CjDJDTnnUP38&iNe>o%w`<M^7L3F381;^JFiSz3cBy0<ym#W757}K7s6{J$^oU
zA!&Zt$Yn!L-fZ4lc5rnID#zaQ=il)3rd!{^8(<j?^>PQ?84BU*IV4Nwd*=aiF5s&0
zJ52Z?y~jC{m=8RNp1ysIQG^LVv1DIaBW+q~-Q|(AG=R}9KYIjAYO-F2lDdFJjwRHa
zIIalU(==w6wJ&Fr^jAtUq^myur?+y|s>Qg%%RX$#SYU{Q8xRwpn)3>yAEZ>R{3jg<
z%DHOsm at q&DhxU50VbcjqP>Idi#J6`2!3%8ZjpPD6$&vH+svt&6A8~26)g#48#otK8
zmE3cHnaV$JRtc7MF9zAKwqn5+6 at RGI(%L3qrJngQZ=RlC5susH2Qw^yGx?h)I;W5|
z8`M)Z$0w!BV;jP5l{0bc3-Ns`UK8pX2R&x3(<Ptn_K#E&U<#u%ZW=dd<LiIeB{5nC
z0~ZG3>AV~d>=3Kfv+f!OoNA4x at w^ht8#Kz@$F02Q5sDTb6ZQq8F}$AubLDRISJo1!
zv4k9t`J^39F8B%niqF|w#w%aQZA!l5=yB;$(d!+c`&`4)4qRFl`I1%jB+P*N(X`cl
zrqLZg=LVuPkEhvvlM$a{-!*w#6hSyYF-{I!)EWEW{mZ}MT_Z?f5oc85?+N3GeJ`+N
zV|?QB%Ur`IH`yH3wmZ=&nsG(H>*xa>MQ2D7p$G+*LAnygeqoWN72#`Xd1*q=xvUqV
zg}lI%(py93s6Xd~Vt1}6Yda<Fd(VMA(KzBDHg4nqD&gLG?6e(vA(y99^LBeK#`WeA
zSLg+3ZoZ^@6e>}fu9fNt7b5Vw9tS$iIIvF#&aY$|*S^L2ODxDWvC!<!Cu*!}{eWTP
zdYynz6DnGbin?E@`~8wXs5bP-?)&(a3TdxK;rzudH<`w$z$j^MvUF^9(bkW`He-6l
zF~!c*b%v?$Dp#G(Qs*(0l-8ZiO!gD|A-~&M|MQ<0AG9%wAM}~w(dqX!IkkbK$wNxW
z*T1TtA~`ck=+-*%;?bhN6e7y^l=dHNdeNS{x8;;Vs`@HUlw+0`WDm~vZl1^SqS{Vu
z-Ja<oYF#-h-pXtmFa~gP{#*H5VOfp6db%5WuK8mYIo*0?yKQV=+<)j;s1rkxdUT~i
zrQhZe0pf&-O0vObtJ#*dol3vsrtNpN<O6ODj{@gesnt^*R~!EAHbYx4bg62@%9{6j
z$Yl4rxs`8}4_+2=uKx844&G7U-r4Et>N{D+IOq5NOum*}5OXvTxi>1>$~Gk{%Zn}P
z{_>LrY4NOV3Y#>@ea)D!JX{dt)N(OiZ;yVSR3*3~v<ltizesfq_~Ew at 3lqWiwO-it
zm?fIF)LX`nzGa=+S4$NiA_x()rPra~kD&my_o538$EKViP{8%kKtzmC&oL~NnY%UY
zF-lH2mpYl++0T#`n9J)3%)9CK3z!fs%1r2^>p~y&;79mebD$RmC-!KC1m^++hgCzJ
zB<|jVK68W}{p#9r!-9Cv^+~j3<y-=dQX7{|=s9REXgb!foGo!&wG#V0NwbavKKi70
zh1U<5L)<fOcjuC3Wr^i}zEZ3rA;uM;biEN&J?{Q1molRhtvuGKPrsb$&64^XLwU~(
z%iTSH7hySEBPN4DQ04a`N2m*k!S9{N`#y)X9{%L@?fC?xhTifPK%@HbAcro(9Z|oK
zM1$q*mc at p0**x??8O|oroVcr%FT at bm^`Q81boE8Y$cnlEaek!HJ;3h at nMvRXvV{8F
z44vX!o^2ivpPruQIRE>2+D5I{yD`*yxUEP%80yV(|Ldc<)n!-`gdD|AzWS)IkLORE
zX6}zvzL$=Vd*zu$axb?|0&W960H5+X at X(a<6j$mLJdu&KCuKigVk`oxos82eiitkq
z>Mb0Lv#iG^4;wNUXykW?&4qDwo%bDF16LZn_u@~h$R<nN=M(aYnIdR*^>poE>R{Lu
zAmgFKo1?>9^}cs_%M!Xjj6CgH at sd{9>&9aL#s_=S&hW=~c(P7fOVlVPyG<lt;geB0
zCI$U*({0rZAejUM8F}~}{V at ns=Mq0L at i7tN#YWD9V!Z_j*d1vh$BEOXU1f0x)IOcm
z!QFjb{Rbc-lFga;^6hgLqF@(C)9A`}HX?o^K09Pq>kmt+0c`2?K2*ZIev*tIRIYTD
z(ZLOuJ`ZpUP9W+$Ctd$1<V0wPaA#}h)k0Auf8_((YKNk}d_F+W*X4HW9{$2!|Euru
z2tCX>oeH~}YVgKmsHy`*HYi$V<81;-U_$9b2AO{vlnQ&}BO7r6P~Q5$^RIf!>c%3g
zZ|f~n at uUv8bK=l at F^e`|bh|o15cMTjMk2!dA;L{6;E$R*OCpmpkD at q_4jD!yC&*QC
z2B4_*kZ~~m{EpF6Wj!>Ka`W{sPoqlCRKfd1G&Jz65kVxm5C69uT>bS?v;v at MJ$G)S
zdE><Uq8vjiFU{XYr&P43!Sra*wdqfTcoXwi$tAx=Bk;M8`}BJQ)PI-;8wb_r(^h^U
zh8e+;+I2r0PXUw<s-*{|7krC!k0{T~+L$K7_P>sXimH&oIe$C4yn8T>^kl8-LgepX
zx;S at 2Afw$3WU6m6_YHSe at 6sB_q2!`gZ+mq;UIukjO#Bq$9TGGUH!B`XJP#Rml3GT1
z8!<|Rm+$7D-di!+m>(d*hJMRAWs?@tL?CB*qObM)d$kJY>YL;F^|oW#g9E?E_qq%m
zX7~v${sy-^+|(%i at FenHq~xPKx6>(>sS2xw!0 at s`9o2J^HJ0k1lUZ4uhHsY~(xzf!
z2o!g<VU<ECNNKObz8IJC!yZfSVA=}TU(zhau*yk=$D1`-NY*3S?Onsh`0Eed4l=&e
ztfNRTn<0{>Tfs(FH$rjbe3@$jT*!(FxHmNLFJrVIT=Rb(PSQDmTPkPeU0p&h0nnf9
zJ5Ex9=3JAm^1R?Yt48CvfzptkpZZThOzJAkjv4}1+YqTF&yGsbwvE;(UVXepyCubA
z$*ndOE2z%R8qn|Pn&4s_z3ipjtLfz+4Gp+`@lG%OoAl_YGd?nFu<RVj^ZPK;oE05h
z&7(OpN7{Ex7dcwZgJ<9<`;@L#)L*-8oOh<?xg5nGc&3ISn)RS!jC at bl{{<R|#Fc8z
zZ2u5LVfT<)#rc9492}`UGc0<U*!h!vsI9F0lekd=odPWUi|`5js(}_V&~gn<dhqoG
z7qI?oi;B`(AjpGA&=vb>N{zzLyUCyj>iB4gQu2QMQR%1qo=Et_QBKg?=@k2?n9FES
z;b-9k1&(c<&u+VdPa{7|TA$JE&9#KMM!p-ADSSY_IRq3?OT at rWK@f7xLttB2%#$#$
zAs1i>^V+ZoNmle0*gJ~EfKwsk{IJ~SO5}PY|5`Zoq#29Uaheuz=qw at Yk31yZIR7#3
z!=7@~M2*&#ZPR}!3gTK_R|%}PX0hGs at v36@X5*;d`tiO5<Qh=KA at Z)2u=>Zwuc;-4
zXCmIDB3y!n^z296?<ZgZ|7l at 7QD|B>#Sq#vm_Beu912lUSPcZb-p(s#hB)+63*Ncg
zNUc-0J`tE=SHx=>w_WUzMN|hJHcP%q3B&CRXIK~R7!6t?Sd42>i+GWjRCx+U=lSL2
zbQbEWiog=DMcfI|^@|NX;0 at YkY<@mh^hH$=w3hMSsxAkgrp*&lb*G5qYR2V9d2DhQ
z-K&4-v_}AFAkyBE`TOPeHW&QEpp_v1gjxAdHW$~n%38r)ruvxLAZd1_-)%I0H!6JG
zymZFU%}sh`_~wAdK$uCAHOVP0K>XzJ!A=q$T?hzZY_WH3`JF+(xfE0#?pFBh|G5A}
z1;3NR24ta+<R>J_9D^-|9RK?{TMerX9(%6T3a{BYnnRtw at qTeTt*TU#Pk4rHQc^k*
zS9OW0CO_QW7t8pXX|?&bIX!X;PZ$-?R-JTxmYvp_93wWRlmc%zTK^LF at CA`H;q}5~
z(haV+h%}D&6`2bC3weZ1tt&_&0q#|{fSSEKw_~ICB$gS&y>_(zG*V6Q{Eno!$R^ok
zG(rJvw2yT|V5%inNF&%MMH88)zB2uw<;JBSgYbY=(a0skS1M;T2j at p*grc1Bq8W)$
zWyfyE=0OC&OL3h4kcmoSLf(0GZXh*Pna2)PH;P19kslMS=zD~9A2R}2yG-tSX>Ceo
z?+bf9WOOFq0ups8A3Z2laf)V4qasgzohjzgHNrV_7@$3`p19DcB2Mb5#6L~scK<Qm
zx!a&ezr+~!XMNm2BZjGdwl>A!D=ywteweV@<7O&E#$y*%<|JZ#c~YLT)M&f%fq{($
z`UnEo^;ioHuk*Gj%6{prJvJ5 at 5ooPwmOUf?6tdlQH;umU+a`tZBQ7kG^A45CKn&B-
zPDP;qH;9!}k|&v<_?#~4fLG%+zl7+m at 09EN!hZT8P#PNG&+e?u-v+;9p?XvST*P~w
z8Et*LKNL^A32s?Oif~agebjlqihF&x`1=4+(4DIJ_`(5}jYSUpkf7o3oj5q18+tKG
ztvXIVR6wmz#NoT!kP^qh(fQBEeNBMcCmgb?F(*6l9x(}a`F&Wsb!BvFu9pqT9+iD>
zl$|<)6j8wiqzLs>3-0AgKqp at VL72%OI$-d~r+qWRALH(gcJv at m1PkRq_j+K&SC%|%
zMxo?J+Iu0gy|F1!9%#y#c3y^%KDYIP3B(+b{nXGYV_!H=R8{53n%|!=_vEAFNA0ke
zjuk}S&4}J<LN}uJg`h`b&JXi9=mu(qDM;qGk<GNPVkFLuCKCKH6ji)lA8 at 7%&PX0?
z`Jz{;Ta2)+11t+?Ayb4a_eE3WdkK-B$o%FW%^0d{`wzoX(R5zqL10e!6h+GdsX2wo
z!?6E>h059OAd5MFqkA9h5Xjo>`{bX_y<FjCU`+kOp0^vB7xD622n?Rr3|o-jN&7;>
zQek-85Y{>M$a91ew*5QfT)cr1r(Xy~auAFIDiPm+VKMTzyk+sG0elF!%sdaXLgb%u
zKR3H^?hW4s+g?xXc%KVHPCCZhkzsaq(P}ciEm!|FzHzg*d68z|UtT`#pS2iT?6~Ue
z24rJSNFvi<<cD{cT(Lh-*otfWubuUBL%evD1L5{Zz1seW^qqCl)>l3UH1p;XyE9)-
z1ghI;6&sy<S1IuaYPi=k$1I%TlN=K4=>VM2G~FUWNkJ0(crhL(r!;Z&Ns*R5LmrvA
zvuo<yi`nKX4+{14^mMvtVR<TE_ySVMK!;QtNNoXt_-hU9<OC#Mg$vV^laTj?Ax0ff
zBBH=WhFPiHIy;MW2)?4tjsv^6SDBp#O%tLL^anrB*;HMFyPDjH?q{IF_rzMmS9 at b`
zTt-}Xxch^`rWWJcWBTz%`!NuGG37(gY;_k`Ek1fvbm1V(qVVXL;&DNj&#xx+O at 2*!
zQxwVPCyZbwP7<|#UXxGc5j<kO6nWHB{M{N+^dSCR+^g5f!}wQ&|3Gi}RmRK=5g#*s
z1+8$~qud8q0ph}FEg><00 at bayjaiDaQUUjELSwtZZLMd(fyEl~ajBzL6EVV3DE|k;
z8l(KE7MWfine^9p2lIc|wH?Nfi;?Q7J~PBYn6-{>yNREwYGdbdhBYllIH|PP+bOD@
z&wMM7JP>8D(|TFc%c~GT)@7<}dc*W at N(UC2QKW%N6~1y;f<awI31XM2D_}FHW56DU
z#DnA9=6){k3(qU>R(s0{z*WHlq^WC_jH<a=+dv+xL?#cd(uS`Reo$H_c5&T`%(X(-
zbBo>eC6f1fqC^h8;+t_xc at hqZwx#FkvjHD>#=XH1xvOK6tP)E6oB at RYXGUCrhe$nc
z3pe0(LN74R79I147>>H~@t<@71ay{B124xRhfD{On}2rHteBlU!MlkeGO0)~AQEOY
zJmx}*++dV)YB2h>74l&*=xvPgtFkPLrXmqPBF<1e__^a)z4LJELHhS%C244;7L|0h
z?T6nZ4EPdkUu62e(4h6;Vq44Jw&2d1jz${GXmxP#qoi3UyDl=VhC8xThP=}z@}~hM
zZeOX($n^I9ODq3xa1w2x^xn=S&v55a0*EM42J}TIJ^tg2zWmZ)WQ^fy`wUm4zsmhE
zNRa}QJ0pr>Gh_liedLY6FJAWxxf}}ATy9UKoD{}iM6WRg5ciknL-{A1!}Mw0q~4{a
zBxr;Cv{e5NnVmKvbek#-Bwrl^!?3*IlIWNBeZ|*tNl8h?bxeIxAU^20IH at Jk)8f0L
zo}9VPK6ndHVZxIep2+5B<H&K(jPT-B+2;^ONP2%jDj-Hr>nfHyujdwra19ZUZTG$m
z5krvk81lSSLMi-rG>Q9fUkTbY9F<KZA6_f{gop3n at q5MOOirhusF<s{OOY=UXLsLw
z$yzjz5+5K`N)Y(j{mn?hbokCQlLqA&(jU8gl*WXy;4TG<ougw$q^%)QKVJ;}1%Dr6
z4P~0M*)UJ7dX-1Mly}q<9`0}0SE%D02O%4r33 at rgB70FO3*J;rIumDl&Z5Wai+}Y7
z_O|uqm*-@^8+i#T*rBB at B002ijNj}mnIL(lbmnqy=d~=y^e6*PDK_(iZW|N8jtO%j
zV4 at ZYvcbr@$%}EDYKq;uB0{Nz#jzC>H()qwGGcWtByjrD#At!7Goxg4ld|g=8~<{f
zzU#cUy<J&K-Y2j8E!mt at 7Ye>F0#-Rb%$_sU`M~gyxuMD1E%!G|v-C5L%LQWsX-oJ4
zVQ=tEcy?!42Ruc32i!yAp|AngJ#?BHavD<$7Xco23)gUT*@(2{w2?E=C_V9mA7wMZ
zea$Bw7j27cSnk})P%ZXMS>W*{r)?iHC%AdvGu7CxcI(4x*gX}9DQ)OnR*g2H5U}<2
zL2a+m!mWu)9ra1DKfe1 at 96;o0EDv5<Ga6|k<LFO8xBPnM{{RO;_`a)lc6W4GsYT8X
z2st`0)bwITUQo}DusRar30q at gqNxNEG6qk|FSBEzVuIaWI&e-cIB`)Yj82M0BY9_j
zk(D@*lcPe0vXw5En(F2d6VD`+(=Ot!HPZKqk8fP|u`_K$s0W)13?SZJX4g*yP at M(&
z6LMsDZU`+SCY=OOcIN!flHBW3v?-+>LWBqbVu0WzjfH{35!eZ%zy+tIY<!T^t>>;g
zrSHb#fKyJ{j>}64=Vb76^(u!?QM`l`AKzWzlS0CYNB||@(HHm<2BY8OusQD%IxmdK
z0T$3aS1NS$d6jf=X9k}oxft{}EMnOWcdn+o&*adsgUY0fusu#hSm3%sWU6@}f51XV
zcz*KASZK_%En&d=?k)nsE#<DVs54Kv=nIjK><r|PlHU%WVu9?<OcKVq--ldF=0lvW
zD~39UhB2H{_blSbwMb37bS~uUxgvsaFRGR)nRgy6C%i7OF;7KNMId9gzB`*j@}=bD
zoe|&w*MUXh*4EY;aS~3eI-Sl;Y?(<|ZK6ZMJE5$U5a!}%!l%^eB%(y;#%<#}vzT9S
zYC5lYXEN^JjmdqAc0i>tr)22;_55TzJsURc1eNtQ0c^5!`cCO-SIlMJ%;`9rmz2_H
z5vOxSPM&f*-f>O}8KWr at F?Y`ll`DL_$SR(WfJ8(UA}NVseE<bN$1$cjGSzBzh6AIq
zw7P_jgY?75(W@@H!=rqB$PpJi3WVXXBjKuJDKZ+nzp{<X3(|@DRD#niF2i~ulu$h*
zXPP3cyVkhx1EEx`l5tJ}RF#v%!%ny_BlUeE9Nqe!7m~i2kWQsmPd|H#2jUPRCQU4&
zd at QYt?C;OuO9&5bqX5BVmrjy*M#TW9S%m12%un8#&V&jzmrv%MViD;Y at Z8Jba;Q94
zsl5$!f=nzNd+b|(Q(ZzfP8{k%I3_z~44$;Df;#UMZOek3*k(d}$eofsXj=v_+K$1M
zjT5RzrKDih;iQm(lPFmTIai@%%3SibOgNbok+4oK1Pf4yxv)d4={XBr=g6?}q5_yu
z5Ecu1ok}@uI?cmv^K}>4V6fv9(Itc(9;HHt&=TKHPc8%($T6vMyuEBgZWPs}xc7m{
zJf{x67t6VxRIehek0KNF2VCAqkqJ)f+~2Txcm9z##K at 5$-k-%ir&%r at qKOI#?VO%-
ze-VFP{!@jF7dp=6)VbhPVctSb-Z^hdrE&n}Ixae+h8)#G=h at ErMdB;E<hhDCk3))M
zi<Ul;SLW(bzJh_x19tU2*{5%(FP5MVi#RTYB>bDAHTpizf1VXDDbMWx;j(mZRuVeT
zbKy#VIyah(`IJ-s#wR+=ugIyBujRr{azRsfhN2YQA?RovUy;B#!iJk{t?%xFJ#1F8
zvBHUsY{w}i`O)OfJ95CKqjeU%naL?A_dD|a^@nkc6R;{TB|G0bP#hc65s(DQ%9CA0
zCxoe6BL^ubH!ry9BGMqfN5*y1T?bu7k-B&sy$V0e4Wk at 83#O7Hbg^^p-5#pd at bBU}
z5NFBGduqcv$+rq_uI9ptj1!N&5YgZ1;HkPnxB)S!J3Bkm;#S>ZT|~k9_{ZT-gkKTL
zp}$j2CM6=l4x|zzeHUWV$sb||Q;8}`kUln^r*l3lNggxFILWp8E}TN@{k_x0q|2qP
zN$Tdr#|i7H#6kryiy*-fJYh^F4osSakL8`>BrLV3#^DZZ9{An{es}T#C?%be{pOAx
zAGvd5vc8|Iy)gK(aWMp$pW-4eckT+1<Y_o>Oz-8kVM0k2L&wC^UwKl-4y1Gbe9}f3
z at jSIXo*SJj`T#0($ydu>Iyc;{MBAqJI`Fx=IEmsA1H1gBiUm$k9H!!gbz;`pd1nWc
z6BzOl*|ef<83ze(^4&~SP;y_)bK#;g^cN{9dxxG8%1Yl!?v?vu-%}$#0AY9JYAP1Z
z+asf?0U<yX7jaIXb6|8QHDOR3B6N#tl=|+3hOv1_8Gnc6)oQia-``I{2HoHIUM${e
zP8D3))E6TvPHC#Z;$BTDCDWAUcCtQq$;~V?$M52~(w-S|nKa=|#UZYj at aeSv5UoR5
zZ<6_asUsW5UIcRWhENx3G^K3gf<8p<u!xhtAXJN-JozKHjqf_)xpgQkCv7h1L+Cym
zevF%Jr24{eof|g631JrW&Kn<W%y`p>uPe at xW5b3Vr_(OaOgaf0y}Uz2+svaau*u{o
zE-wOIia$A-(TAdP1ywwJOvDF9a;`&!7`%NeunrqL7GBj;p^BX{1yVh1mpk<UL77P%
zRyh}!t at LD^hrL>@#{T~P3<lLPq{KNAmn~aRhEDG<2dAWq2`k5!+@$Th2V@(nImrPM
zuAo4tZjR#^x$RlcRY|Fwpqz3F2kG0OQ}3_m=hD*(zT}~hgf5v~cAq(RW;cilEl2Xi
zm$GxtX_b?6oqMIgPws>|pt8T8D|Wt#5oM9dWSx*i!Jk;rQ#FknlL<+rG&PHV-6{RN
z0)U9RDuh%NbDHD{qc1uo!BqZ(&(&3gxVy>y5tDh at U5Sg2rS;hz)1D%2vxDmVAQpix
zgrMNTBGGZ#E+OnBOfJxsbhIxnbh5w8c5~`^cz8HdAnRP}bwXJQM_~7vv490GVKnSQ
za!ShJ$Idt>DpUb-;S`^!D8Z9$<*U4*M)EA-nuILMU+CxkyF0;D!IjMm{yuFfcNHNe
z4h-JvF1r*gJM+GKiT*+jG1-6xw5vY}_C{U?cfIMmF?pA-mcQZhKkXD_H<~ctEX$@4
zY6|{P#&uTGygZ|<<wam>hmI=+vbo6S0rL+wUYJkFAL(@#GCCJb=4Cs+Kbr%D!Eh2t
zseBfdo12@{?@LZ0zdPfUFNGA;mPKM}`7!rWIicM}B*-61 at t+BuXL0Yl;A9*52#F=>
z9JuYh$Q0C-YJ7wY3XS6nda1(bDu^t?i0V)wLmsS(E*0l&9_X{nf3parzaamJaZ!{D
z!iafp#34 at YZki{S#N3Wz11xZ5J4Ys at COQ;Da&D6gs}POD39f9zKir|?1#r1sj!vgD
zb0?HndtU6mmXwXDXaob06HI-#K`H?G2#h0rs!KVhodJxvZQo5W9*@ru+FeVWl_ at un
zvKzz%Qci%<jZE+y9>osnJW>*IlvF%PCF_)(ESJkuAq9uY5R=ZaGbMx_dn_o3;~agn
ztiFq at ThYO?NObrUlWle&2!mlVo?7 at M2hR%I&lO>F44%4(lqaNvr(y~hopGe!Xf$S=
zqzWAdPfoK4TceYa(@nvvyi=th?l2YxXBU~EzCOE8gz)Ix=ygIKl^DAGAu;Xjpt4Bh
z#D~oVU;4;NnJfK~Lqlw?t3%Q0F(Kp*9>SMcP%9y27cV8ROu2Z+9=nPVc^>2=sE}d8
z%8kmL;F1qOsEEUKSwy&8sqadmFZST5B8|-qCRHq?{JHA6t4QOd&ll9Ot4V+4lRk%@
zQA|MojLm at 5w2UNbz0Sbyift|`!z7LcFqiYCxK(_eus$VFvMrkn>K^MeyM%E{3O2Rx
zgHRCtKK{HCJ{EDlSBg*!U!lOHEd{%C)P*=a6s1v-sAeRmr1EF7jT4W(`>UU4jMkl1
zGVlA)JdTmn?FBSZ8-C{~D#KlFES%gnEP$2lbE at jQTBdtu!0qzAS(GfNKhfFXol~5X
zZFFaK=6zDA27>O4CLElida_KVLQaS{p=BY%hFS_9<$Oc89ieAzJUf4yzu%W$vtdW|
zPI9-XzR5`;$^KO8^Bp at b4nl6Y{267tDVmkyV)9Osc0j^A&z<~<kWM}&B~619V#4a^
zkH~c->VvR6LZ}JR_T5dK$aFfLGl&*W!wD($0-0P-<xE`EDrxE@%#59QCmz!YIfsV9
zQ^Cvk)KDUi!Hrx8eJKW4R at Ef9>gSy(NYXVEQg-HD3f7@#?2M;4Hhh1_NjkaK^|Za4
zM9e#rD%!>+J4u436LYAC3mvFXA;~g at 4W{x<N}bB3X8HLXlTJkys<rTS{yrxARI-s`
z2bZRD$Bq}kDY6<d?J9)$*$F-KBF&Y%G?tzxvrA~1E~Y0%E;7N3%qgZEmrp6#+1H)n
zZUM)f6FMet6}vHxpXHq+L6rN2bcWgKqC7LFQS={<za at u-gm|7CcBTkpA<RWh3w3bS
z`E|0s5(5?*@-6Ll`^=6VHYZ&2lbky$EcteO$NQ7lmfCJlJU`EgHxHO_QU!>KjeL8m
zGtTek9Zq&Y$!C<UIc at SgN6sC;JD2t{ad1wZ at 5Q1j8Wozj6O2;&JU7nCONoP|wuqBh
z%mUisnwoCQpKwVmrKNf9h*_6EVF#57=XgAxfzhzx=EP;53!OWk>=RZ;E`u*+q-{9C
z^)&)6lgs8r3XiWlDIeurP4YP8uYA!ei*-W3crN4*z4OgQt>jYB-#BDZw)Ol&=bFCS
z`9&<0$P-Z$*7GCZ=i&R%2*c&1PyUL0M<>KP$HpPnY{)qmLir7gFp2^2x%-YCB1*WF
zk?<z+G+3ylB+Hfi`M$FhkCn-|^VUd+_w^FWt at K%#JI>qr#XQ=5wKrM`pW?!9HZRy{
zrNBmNF*6~Ho;MRhtuxO8SwF8cC|Pbo7M*)e)Rn`}*~q1Qb4pE^vfs?le8&!-1qCva
zoEcS)?2yjW3g>u}1rZ;J6F|lFU{XhQC>?e>Xjf10jsvy4eMH9YEum%lH;&|;TuWI?
zISOuI_gySHjIJe41toPziMwV8G_~=VooyF7APJI^o+)_LJQAc6y2!C{`DGR!3J_G@
z;=xk4CPl)e{Gk_dI?O)NA=k)Bls;9UgLi#>-!nt_6QLA(FXFOw?g^{&(W*LGghz3t
z&e5y>8(nmY4RDG<2oSr3PKM(GIXyQPI!b2QtzqK8q>Cg>FY*XmJUl#{NerlhsHs6}
zk=VS~$=yon|4W*h39)SJ_*!;@ytzObU0;&MC1%dqW1+%?l*PNNASwV*ez{hw&2(>F
z64bd8vMmDy$^QCzPiUR+E<5Pl$cJ!?I43p?zDzhBuE4}W6Ic&^^nJQBde*+1$w}8N
zaJ~3fF+eCSw}=zsqkB&oUY;v;9yyI-Ql_&<`DL9eUrtP4O at SScV@$@mUx>Sz)Ew}g
zU&OS#{BkNWU<cHHzblWXB#f#2#m+e)*PI$qdCQkRst9C*Oa6$91$`fgLxjj>;Ai(;
zDU9**oen8vj3!*uxt`n+q`&J<G48Q>pw|g?B{$1OBoxDm%Fy{FkCY0JuAZqFz#V|x
zKF`=ne?wVrLf81m&lPRQon9_I?a918V+xK**ctC{rBXSw=+uieuI})iT$D#9e2TUs
z{F1q0mSwTEwKc<6q(5UblSn6*!e=g;QoGYRm%kx$fcX){j$A~`VZQREg!!|nl-eVs
zW~E*yWYG5qIa0~R0AzcfEB(A;uM3b7Nu?r|FyX0PowV&_f7c3U$CXK)oFuspo;dJ<
zQyD}5=EP=>M%g{4JhB{_4!gq<lz5SdM;Hs8oQ&lXz{2x8q1~k)eeZ)RN8c0Ug%-QZ
z#1`u^4Tr-SNPxp=R0Qg?u=`6V>05U>%_5o1t8NmmxI;&0gTa;fSiQ%=!NJs#c!8|Z
zDK9Q1LAmQi7r=w76Hu8{63_2b1r?e6>`quGDciftMNv$##q2IK@$gBZ5>lN5ojW;R
zj{JpLC;3*R+Z04eL4Z6FCQaT+<DxHe9Vo*~$c)~bvX>;Y`b5QdRwyyy&I;oF9bZe5
zCLO%q at 9^+&=Gk$(Jf&p$^Qizsf8$e7c0lQ`)CJ_EkQ_Lj8_F;HB#sLNS;*+Sb9%M4
zwKW4fkuT+)B&3KCBTB(4sgf at z|B2nx)W&5J at VUs9P*t7_E>>pT at aed|8yEO;dc=fL
zT|y=fj6<A)rly!|?2w$xZnIuzQ;K{6cAp7Z)c**hQTJHSj&V#yEzb?lykLLiAGwMT
z?+o`k5YJCv$)t)L8BM=kn1y#{JRVP{ZJrn at sgkG;r(HaE<ZG(CtaGLAFq376Jo=JZ
zq9WM2_M|O!r<kz%?j^#*neb9tnnDeZs?h6%<q>(nbLA5qpQunNP<B;wL1#l#Qu%6%
z5lI|`oorW0l&{wBlYBB8!8})-b`b)^MXu!3$+r3ol#}Pa5Q>lJxlm!!3psCsv*D)u
zIGIeQ|DV2&a7s>?$tzRC&I$31`D|9|Tya9f9D#REah at Dwo;yy<*eKQ%)OQT(TyP at 9
zrj)PVkS|yKR)I-Qp6A`%A;|R<^cU`rSafiIqjE=b^0ePbe^+j)d&vAs=jzO!897O+
zOR?Kb<q6_rT|eJ<T5!ZhyuV`&QyboS8Hj@<{ECN}8tj6cC^2!3dI}ZDiKqkOQm?+X
zmmLKiRw{{+Kg4c~l40WUiD}ni^o5vI^$^U3Nmt4?`mBU%FtMQ04Ix6j$gUj0&bRL#
zNG<aucZwYem)PUhU+1u}z}3(5A``ks$RkyRIGQEYgRfJjm%CJmucwo&)oN!n-n|gw
z!c2#`xQ at C*jN~Xd1=U4&jd}e%$IjfT!HEmGRgNw8kv(B3I#+Bw=v?{oJ34qd9^&=&
z^LmE5b6%jjiV!(@OzNDor(~Ro1v{in*0~d79*@N3o7q{X8jKU(c^_ScNQIE at v@dN;
zZG&dQ>s!QW8&`u#?QYWlXO~YZK}@P-8|T1K)r?7(^Mic4PMC^!;e4-yFYsmH7f*wd
zpOiZ#L6lQapBm5~5p$l}kwd(_%QN%Y&AU_NJ5qXDe<<9Nl2j*5M)y6{8K*=rJNM)Z
z(wFKSy3{@K`n*%V|A;Ucy;o`hFDJzGS2`CYb<1{yvFN>IJNjBCT~xPnWC6KPoMQU!
zC69A_uAaa6o;&W?Ay+dMhxFYk%;IoO6)G+Zt~=l`VTZ=EQOd>8YNRMp_hzH3p1C>|
z_my!9N-n9dk8u9<Xf%p$w>!<}QoJ(v)q0&fbO>D|e4IR3ojFc)1oKTTO6787UrOzw
zHspGGUhDf6$?0>YKlfK$QcJXuV7@*<PASIe{b at U%JEAr?#pD###fEq%NhhH%<sLh4
zj4;NNuQ(o$r?J)-=sJX&le#3#j0vj_f#YYHm^kU0hna*hI!Oi)aurfs203uS(Hyhx
z^2{#Ztc%Ft$}ur_7o;ATtD<@ElB3Xn<5LG;21=fX6I2DeBUgcmgG+i6W9lP$;`O=p
zH>G&u62d7i1E*EKON9>JwZa|lz=W09VkS)~GCqU1a~)U!bENKMek~KN)oN$pRV1qs
z&Y<t7*9qldhmxHt?vZg>OJA}^9rzRx(C-}gDll<TVnW=tPx43vOeO1jjwv}*-6`U#
z9Y4z=&389(V&l@&N=Ws0PI#3xDGBlAe5oBgoK`t;+4s13f$Nxb?iZp`jy{XaC(Cx^
zrO`Hg|M7S{vrU?vE<)2%opo|}6bOBBBH@^99&p;kB24EZ#s6`h2q$^EC)_*bMV{_d
zY6-3EMLBtO=?I(Q#DyJJD&25`!YL#%=c%R?p<}uSzSqi&e=m?-dfL1GBp$OV#dD$G
zMPE*tU2$jxpYpv`j1|sh at JSnCH6Fv6m=MP6iwnIwtm2$fv%Wuw%}Bo!ByDq2=gM4!
zkNfo8A&G>0a=OkOgxzA2qRCI<4jw`zUBH79!roYMGCuPUD*3VT!E?ubX57H;d__WZ
zm~ZfPLCg4ulIUKX%NOhC*-Z3gopDTda?u)crzG^miIUC at n?B6#9Q8n7>P4XMnep99
zl=XJrn#UoY8}evV-<{0~SG;8-n2izN>A7V-*Z=?^07*naR7Kty(Kds at V44^Eej%<{
zAZkJaIofwdK_7B-7{l3&q%W2~BhQtbKrix$Byd$UPBHz?$QKjk#oRL~0Kn>rdfW^U
zO4?M-vm+sFF#`k-6BlNBfY4Ne$+kLGa(tB7bAA5QVWiwCNAld2!li1y55%#4#7PoD
z!~jBEret*We!is5aga<bWIsAdK2R#@P<4z|FCjv5Lh4*`YTz9S;%}MEGvOrWT;H7m
zhtsCXWO7EHFtwwH0guT()uq at ab&{l>B_VaLMpv)bXH<gN{bf?c<$Q9IBw;csbNsD3
z<IWeLbRz=_VRiF%HxZJ^se~`rQ#VEDj$6d#fcf3&ptYn{PEg4*i+h(_X8|khFq;R2
zs_J!i!d&ume}8}aEUD(g#D&4t<=}ZP=!A(Mc2zP?dz4V>bxy0fY}6A at 3LOxxKxjv*
z6Gdnl<(GA?7(87n*5RP!LJ+g=+n~Akf&SA~$=Jc<)PQ at fJmGXzuz5>ld8eFL#yjaU
zw>k at 6<fWuyDU9&{v-j??+OGLs*YAD~>wKC$oujjvGJ``1t)eYhN=hKmq}H|sC84y@
zXiTu0SV=U3nn;>p48#}+|CkyGB!rZzAlg7uv04)>q$!rb)D&z|Ct7x=hyAX#-gm9_
zoc&|1&%HkPcU|k9J<};8`@QdEl6m*Dp2L0J*Wq{g9 at 6(A{m>F_O7+?mO0N?FQu{ij
z$Bj88E&m}qVVkdLC~2!W;KE8u;e%;6q&Yc*3H7j_2v8EsMY}R?Y<qT?Ee_$ri(z%_
z)ehzpLSxx)C%{fnQ#gen*4?P>c3W3hSN*wX-dY;;dM|d at k~K#V?ft0b-IRoN))eng
zR7NVg85NP<OPM6P7|C;W_sB&d1bbZNPp;?b>1qEu at kR1HEK%$Zt_!(7<9#-Gzf0q2
zCwXa3>@KE*{Z^sY3AE#@goZhorl`a-F+bYKhTN~<?Nn8rpPxTLT^KHPette!Q$EL9
zv;%h;EouV_$@e~+%?2F`)|_Fo7LhP&g4oY-G4sZ-J>QGZDceg>RK_O2LQyFO;3Bni
zibN(DQt0A<f8Ud2h7a{0IgxSO+CiJEN5=Z4(hiACy2HAy<xMB0WG$1MrjacIs)O;A
z2Xt1ST?ym$4R1=A%jM<epwa~f)NluH9DF|SPn;xUW0;H;PpBRP1)*Z$_MxS%ZK{+G
z?5{J_%xaCX#RO)q@=d4HelqiWO$cKnG1nmt?u`59^Id^S*-UQ~Y$&Pvk$xaPyiB4@
z--lL((@-+z4P&1McFb8SSE-igVBKS5;<PcX%qtRDE2a>zCbTReNG4Ibt!%Fppb+l#
zC4Yy2FUhZL!r<jIL1rx3<Q#B1 at JQ)tKlj{3(`}mXcjY_}&#ZLu`R**3WJsZa1HxT{
z?C at r=P6gD7kOPP0IuKA=gu?qt9w1H at T2lB{m}Jd(ja$x?{U&9-?S*203#$O7q8kT)
zLJG}&V&1s=>v`Zr#e2C0G>p%8(B#9F=jy^s&YKjqvABu(jx8k}W76GSH{l)59_x{!
zodqbI04EH_{2e;5hUJ;(nw>zn4$SF<5nJ-y1;6wc@?MLDLh?WiUE}Y~A7V|j_i^ur
zM;Tt_PM at J?37<-bcE=aYX+DEBmq{F56qBkQbh-PTa8Gw7Qkj%QhQ!El((IPC3cXgJ
z at _u4ON&3jRtKc)!iB1OdaAaD=M&<<^8vFFM1T at S6W<POk$h~pS8G`NNt3A0aHjt{W
zMjqrD??k8tWo-$!q#qjh){-FRJ6JOwTc5#}u6EJL4T3aUH3ZUew-Hl at Od73YgJJd?
z&`qteGjbqBBGSy$B3tg{W!&uqHa!HBhia6G6=^M5-tw+A-1CXgj1MnYOj3Ti1&=a0
z_c>B_3kOMyjKkHNU`s;J*kzk-<pXI!$FlXx;p8e at 1_o|xyJBHtv6XC$UC!4t*tWE_
z?~RRsih&aqx(bG8F*YXpWo5m!kj(>m&WJ2s#0fks-|Pd&usf14lj+Pe at nlbzakrHd
z;**=0IWUIh at oZa_GIOUqFPRsvd?$~@N;;_?)q+R)a5TZ510XBs>HFZZ%Zi1$RmRum
zyt2ZQ;h4z}viFj^JDyi=Tc<Rm)nJmV!2dTyC&$hr6vjfkN at tazl$B(^NTCCFkR5PZ
zDbQ6u8v&-$PQoRgD-Kxx*#WI#Fs=@#OSySznf&`%q+(l|54$s9b3V(V^0yAET;WUu
zx`Z>N^mHn|`CxXCV+c at I-d(tGVBwC6;hbp_YfrDN9_N1H4zSIK-Bn1>3KS?)Dxcsu
z=ap5<(y80ZUMbt{Gt`hodpCJMN*<~S=MJLmPh`BliyP)?Sc2F*5MC#kw?n&;2RZMU
zS00;mw at +oSge-c^r-Bpvhu2iXc<DlB0-n`jLt#0?3251GOx91&E_a(+g;*zD6c at ZE
zQkcamVUCYdyd;$X85;{?cx(tr-Q}?Cw$(FRCbH(OG0)R0&PK1Vn-}H?`-~<=;2iS%
znHPpjdaq9b3kxk7k at 7leY8zUnw^M807?SAN&IzvX&AwC_JGv;9zEqZHHvfqKZ+=lr
zO5ZSJ#;(OLO3897pV~OpT+SAsF=f3|tjOowbG)->rJ21 at TLe-jfG2YjwhSFhi9N#+
z98eOho3L&eix+Ad|5%zaO&hJO<@dL|4;)k_oWV+5&&i#-lI3K;o)>l at XQ6ZN?zkAo
znC|q3Go(bZan;7h64+l}UJklj4h(?Zr4Nj=^p-kR68*f1nMlaINV0z7BuyqW48{ip
z2Y=#U?N5~C+SEaR&I={Sp5JPWX&yihs@%Fw13OojU9m6*G^;suDZQpzYc9JE=4Pcs
zI}jpQI2}|O+snQCFv1gq at u1_vSWvC8T1!??Jx>e~0`A~0XwDl47OWXIHLnQ^XqY5v
zIEVKGcLl7Z=RGn555FJDP6yw1+BTHcT}*dufX#6~*)?d*8xE`7GjhK%*CFMVlgH6Y
z5)CbL;NUfpa_^SVqyotvXMRvZ7A+!?>YDa_Z~@Lnt=ToOfvz#>>38M?HvQ22eitsx
z$+Nt&tHX)sw_Iw=@65rv<xqk60fVs=t!2DjK{Zsv#AToR7J)Ea)5V9DOl}%8yIARf
z(+G?_M+`Lu8DLJ{$;rte0rr})w6qIuX=>f#Ugg;5yfG at o5FS3C$~OtDxt>nq46AeT
zAkP{2iuPhbV%UBk&)EpD-&jp96Cutq&V}>y^C!px!+MQ8Fo)Pmg%18HI=P_6csNO8
z9`Eh#4S1|BXqz9D=ERO)h at TQ3<?gllMTWW>>Xik#l<iJ6yi9-%IW*@k{e at gKvP`&D
z$CB{w4zN7{*^4s?WZtCYIb-j03}gW32nl-53$HoWOmb{oSh0yM`=$3AtFBti$U;!8
z85jJR*UlrJaArtkOw>u$vJB=Om}GUCh0Xw*LqmnrxNFM`o0OClP#zNPzvL=df-fOL
z4w4KF14GItl2We5khZFXJ|L|2VmU%@6y_J14ClkMrO)5uN+glc9yqR+xN=1&jlTh|
z;D9kXH0d+bf+LvAkkuGhP~DO@|Hnj0zu$+ean)=D-lW_$V9up+VJaB81HvZCXA*21
zZ_lP+DcF>5Z1IoWR&K#HJ+BP!@;W^{JnSnlCJH)W%}N)~y5%CCo)_GkiF|BK-o#il
z?nbo&O2Zk<RY3CG)gO3imLN7nh(wD6--LDUkNt<PgdvNDa=7C{N5fDqD>&MR#v%}|
z40%6Ecly?TlZ6+HNF?0TL76e{4q%h7XmzVJsrCI?C?U;@U7a=T&fTW$ej8TjM8zFh
z!<$$$1T_imvKRor_44v^04ZYL7$$5;qC0&FIn1#!vVee<dCOi-V8NI;Sogtg7|V0U
z&2V5)r!tqpWPi?$%gf6FRLyG!IHzGVPBJrSTd&tWXODo>-6rt*KIfd|QIO-iTI!t%
zEwdt=d8R&Rp7ViW?9ybGe<OpN>)lY*<OsXl)q-<6DQxi>J$9Vo=CZob<8urS4EIm+
z?{mfwK%**>S7tFHcU)K>sIGcVCSNf<dXgWM#Rq?Xj;*`b6l at 7dSF6<k=8FJ;tuk`n
z7&_*AGY{2kDrK*U&C;{WWAAxqz9RD~Z3MjLtlVXj*@TBXST{VJ1fP4(;sE1g+lO3J
zJ|~Q}$wb2)UeG+A7v`aQP0~@ixVRX2?07Hs8SX^I=Ul1*yThBlR&@W<7~1F9lVrw+
zpE)pTY-l`x%Fy}nZ at It1CrD{Vs?P~6vniyFw3f@|K+z<F`E;+(z<>wpEF5exf1e6U
z4%V44t|GXj<H~!!&b_C!BYc5W8FI_si44I$<7WwDV~aVwTrINigOj}UxJmOp;}nzJ
z>kK(DqAj=SRIjp{R!V}Vp;Q`XI%u?ERGLPnTAoc4O`3LML16M+r7FFd7 at KsjH!<4t
zlueB1L(r8NQLjnXmmxr{ZkXX!3HMA6jXf_C(wMT9&sDNKFOUfKJmUb$PF at R-kH?Pp
zql9zPX|%+!6;Dzc(wn6B8+#kLqvHhFgm^0;Ww8I83XlWRR3&pz$AQ!G3vnkP<(X;8
zw{Y1B17_?KD&qY$l>|9t3Fg_4lDG_fDq%7fjp6Wg;KIS`!!Lzf_&4*yo*3rb`11`}
zOn)QuP%KAk+_vW(=TLGzJ?~7;wcM#Yfv!;6P?KQYuN#(UZk3BtzL2 at K8lOAHsR-u;
z+vkjnRtX0+soP0l!a=P<WayYXKHfW92E9q at Hd3I)ne$$0n62TQPQY8T-|4-?IdgS&
zHGoh8ugXHOyZ;H#vV5~uS%LVpIw}@!aj~!Epl)PAavl8KZ30VW-SHBH^%UT666&H+
za;s3+v_OaX(>8@<-Z{p|u7nE}6yz)-;k}wf!XA8S=<Qf9Efkz+_?)vjG5bMFAS30K
zTWcocYIki7N%VeX>k&(18wPA|MURbRL-vRDdOh%kN;qah=P8^R-f53P_DUnCC=Rd(
zW)kNZ!bm8qcP7`<U0u^zX3qXv_*u8WOoB9lG^@kLU7PD*kB)>#S?<&=w)8?_le2^|
z0cpx&Cd9~@s|lkm@~kJ5-)~<A!}3hl2V)9s&bVt6(t*ji66W@#14_fIjN5irZt2EU
z%3*SuJlisLOhQ<itl2$2v+CAHkc4(aNz7rftT$tqox-eSnR{iKUE}$^kdw>cpv|gh
zc|hdh=S|j|nCA@#dwO1&P at b(*Z{Q?a`P?(;GH%)}dGi5$0NC3gRfbFywyb0xo=MI%
zlq7j$<`>zdt91Z)9=np&k{C{JB_9weOX-%r_oJ3KlUwp8v?pHQNfiO76I2IL_Q1(X
znX$tTIJ2wJg1&j)_yBRD;tntK(%p6AvRPA}w}!2mSLW_H2bf_lo>%s5F)Yt2JuM-H
zRMN2 at n#sE at se40=e2yWU(&7YqP1zXH3QF!4Q(aDokvqIjfUTnF!VB+b-f~Wwf0Q0Q
zCVgk&gz=!lYIl0`8S{)!3x(`rI+(Wal!I+UT|r%N at 8&x?Sf at Ii92oCM2?w<zTq?e~
z`pa0ld(M92zxTYuW5<b#rKx?6xto<TyU(quJf{-QN#P`Ut|^6|owDR+`QDNX>W+=Q
zRt(`u(soO>+xv+X-3%?W&rI?_e1<bGIHzpAVc0+CAcYef_|nmFY-nZD>>#rynI}$k
zTJ{ny=-Ic*h1M1)uhpeZ-k5!*%;j|QZ(2ig?mRCNve;5lwCZchekVLU<0C6n`W$l+
z+y!`dR9XUH&`~^(&5g?aB<J0rGvkUyssJ%rTB;mwD?ewFW+z!6ZagqoTaxr`oMX!D
z+6|h8ZRnYO8;rAbOUtTd$Q!!bWSLzSOLknmIMUe13yrMW2LLJ)BzrtCOEcOD+nXd~
zlaiin;t6BHDcd;7gu!G-$1>UQ0jv_#N)la>aJw+gM4ce}fU%EEcAHFAOLDFgjr6qe
z!A?-+mOc<4lORp}174M?9Z85cp}tim^a16Co|Uxp;7O&M)|&HkGe^dqIMzf~LsC}K
zl_hg%z^r at yCoj#?i^lUC^WKtI_ShQY;x+G0j^cs2OB_PXQ`U@&HV#sZIrqG1`OKI=
zYB~2TocK8#u0RE|)$;e6@;rNvlV|L38fH3?;c%p at Ku`uQ+HlS+D%tbGd#!~I3}bV*
z$<Q)$uhO^5a7*t;7LnlDI*Bu;-9<H at V_6)?>Mwf+?{!d@#)kI2GTGjV2wf}oI{O#V
zaWSXP!91Nf4s;49K+l{&)9G`9n{x8*5N9XQ;vg0a at Hyq`Fz1+gp6oX*saVz=>&!t<
z@<7-xoXD6<*>zptiOaF~*m>TWTb0SXi%yngH=of#m*bxlcJaJPvrZR79nfZcW4U*8
z=2|uY$%D1Mg!ghM&?daQBV&k=;Z$kdZ1qmYKFx>ydyKkZ&A6LowMxq`x4M{%#iH+8
zxESe9n&IV+Kg@?Tl+`gpu1WTr7O#voXZR>dRw4tknAzfqB>$&X<aWo!hL-N0=Q-sf
zvtj&>U+h8XHRE~Xb0#Spv)QbNbGCf+97ANcD<RlUkkc&P=a}OkkBwvbiL3732;d>`
zqw;|<!N{(%MP at hxuVs7C`uqeYE$ngPBpuLN3fcpj!MFnpUbiO(ue*InYm^C_UMp-Q
z4#ry!ryNp-1XzC1YA+ at VCMKPYfa<NQyFPqqAG$hh$e=NzEhq=DH*W+^ggBfHn{z;H
z{4SF at 392kMDq(3j<*Yt=9vq$ow*)54L(5hg_iXqS_wL^gKHl&rZ-UH4Lx30?SGqhe
z=oEU>^t>=UtHn=pW#6r1!=GAXlaiJm*IYBq&lWd|gFk;8_wQhx=kDO%YtH;5W7dJ^
zSVGvrK7n}h)(j_gSHiwFY?36;CViWHYf^U0 at t7*1H)Q)VaPX7F0 at X+#nddycd^of2
z&d$yTIPI)1JJ^1%3u-R}2m6-E&2E)DefB4^#}yqF#;?WMbBDzH5rKoDtqHqpd4Boe
z;&5ygz08F$f2ie|;f{`B8cu+jpI%cA##1?qv9akizl;5Vy&*+w7#oY`*tdcGi2V;Q
z6?e1P&-k}(0t}Vq_Zq4J1Sk_Bo^=x1y>{70+)bkL&YaFJW(xk8E5N+*8aq2X8}O72
z%S-r^*PJa9{PzUB+^fgVd`Cl!-0dRC<Xmid#aQvp9bWI%_O)si>|9WD;iJXX%tVCo
z<8{W4bF4*}cVWeel-C&hA^(m2$OSjX0r<EDI1=J))zd@{xD)6^!aNJ+1;qt-n|y}1
ziqtMjxgck;02cr+FE9K12FB}o=7JrCq34iJtT}#9nj0r-!-bVxbB33 at o0URNF63H#
zg#E~d;Wp at X?C1A;|KWA7c{dEqmo(BT_hK9TI)?FH{G>BuuN40%vf at -&Vn9>6(bb;B
z_of<*4^Ox3t-+qEWqx45TrBzNj*M~F$+NI}l*x3d5 at eo+;RKe!H9po^wO!852S|tz
zz6~bCgP&y+vgbvr$xsPP2vWMwd$L+h#-@(mfD<0&P0lbDYsj+ at -JVSOK}&|ZO6bLt
z@`NS|GPcI<qKINxpWF3Ti^)XC)nkI;mi%BE)R{Y#9U+h1#l^*d%-d4!@IrS>A4NCw
zJUn*kGeZ^9iX<jck`!1-fjLaaBfAF7f4-XzqN_12hjyDnwu}d at Ld3K8CYbw);ZrFl
zV10cPsne&%ZR_O7m|MlzxJzodrvujHRx#duw=1wth+W-n>E|CD91Pm<nZ$YQ4NWuG
z!cYri=7G`p at XN!M{cb*=54xnRce_!$I_<#1FkX99War<UI+J%3s!9dh`%(HjWXH!&
z+lE*9-tB9Zxa{X-xs$JGckLFO)1>bdO0Z}|@<0g6_<NtxbP8Pngo}`C(%da~>ROd`
z!#OQ&Z8>;Dai5c-O#@$wl`eR>3z`BOmTPx)*XM+TYgg{`-p%o4?%Jp|rS5s%XRx2m
zYPITxTP$5|{t;^iiD4I=3}JHdfahii5DBoAO<VHL38%EusFSpoX|)p-!-P{J*!xxb
z59RCb!T{TIhdSk%4a;-a!90&tHM11Hd9p2qNEiGPK9z}x|82u>#>O3Q7iR3q#hkal
zk*z%pyECWHQv4n}+YA_)kYWL#eSmKzbl&0}6!enYog5m+hPme4T_;iDxtk}O+;hi<
z=GY`0lXJ!%Jee~LU}ou{o;Ph}trQEeZ-fb;Y+|XrWkadFsU)DbWGhWfCZKfX$<DWi
zATfa~TbVBC9KKYC=?tU<v85s%klM5;tHZ|6GC9(_fGSqD)Soki;{BE at B?wuqRs*vw
zb7b6pv at v2z@NxKBUNASoREP2==k}pDAvVbjc&WgrX9a<QgDxj=%-fVOCLqmfPkIvo
zSMb90yfVzia0mxkE#k4EYgUxYO(><QTkt63W3Bd*0c$G0CC7#NVaan6T$5j0lAkUv
zq>_!-oE1l?l(|sCchiY5gem=t^4|IFPGHlU!1re5tvs9wXgT1#-&it~0)Zig9L|RL
zq~xceX)df7&X7=9=5(qAnfv7~3D4FClnWy+ZkV)f=$Y39dj|)5%SbhaRa}%JV0CdI
zP1>vg>BGuvCY1mkcsN-wkvWYEefYMxo=$KRLY<g(_9L%%7u-?=!d*^xB^-1y?<_6N
z{_Z5uoIQWO&5;cOGQ`?zj^u(f*wD58{rv%k-+_bg&9d7*L(SbvcY5;yvXkb*hM^?P
zyX4%Z#e*S2-V<`a;l8Z0=tRczIDKL~FL-X;Px_saAiE&uz246yc_QhRLIUdo7;7>O
zGh4i~ly6Q|RZHD_UO3(|4}>$;ohb9xTzqgxhI!$l6G>bvc1*)>l6Mz+nO80<+lwyG
zDMO at 98z3>@-Wi*G?nXuUjOSi0ubigT-fP{JuynQg)t2o}{!rQ!aKFqOVkURj?G=|C
z7(>^b$Yfk>k3qiM=EbdUQWor7;J3wslQd#CL!jM_vPHtPYG$q;8-CSV=q<v!gDy7c
zB)fT``+#W4%-QW3>?MjK*?Mg$b7gzb8;J>|c>uY}=WY^R2P)qLRT=DCLNp0ouJSQ9
zEF^cUc-=CQ{%y3C4J)x!>}s{@IW*=Mx$AIoaWT-8w>%+or#2gPHO6D>B+x-u@{1gh
zTFuUzP{QiCUmMsZNz%R!e3yxOY=TbWQU=#uMssY^!^hkzcO_rEcrhUQB_E(=rj_K{
zRF`UL%sYWKtj+<cja1WY)PaeiTb4BEx$v8=uCAU09{#-!3|y&VlLlX#N`HJuLIU>p
z_Xo*^KcBTvpo4%0K_Yt<8?*gF2#PQe^Vm3fw`jzR7cU0tD^$MiZD13})6>&_Tn&Xy
z*-3t%yIG8_$J)U>&@y{?nAFXjut}xYB$aXA<0Q}lpCNyS*znw$OV`)egTs at 9lfyTK
z66gx>`x35 at ueU1eyvBa#!<cTClT>#K*|$@GgWv8>iG8s+r}#|s6?yI?VeC<v+*3Jc
z-Pj|C-)_DalI4c|xzJ;18U;0<Eu0nJ&p2CvTYBEmfkQpha81^fJwmLOM^S}9&B6F{
z62S?9_B=EU*fs)&6nae_9UTplPGof1kAX;Aq{3%3P*r;~wM-)^ptSrzQg|hO^3r(F
zLIL)HVcvMn@!R+I_6E|^Dd(O(cb3Ubl|?7_Ev}}O{>*`4Y}kiWmDOYCLa&QP=7waF
zXN5__?p+j0L`fDtvIuUtraSdEWn^ABadNQEe%I=9GF~q5TanEiVh8KoyZJ?)SH#84
zNq1Z!>yy}}&{K=+=`{mo!fL*TzVmwe6B$<L*wHzIVaARfEiLUNi#20jmB-FSbVJLZ
zm1gFPleBHAG%%ukP%CqFR_%_B+tzN8k$n*$01>i#JU7i`;Q^)&yEm!iaai_}AP`AU
z4rd1z#@D(9M-b>18Vf8{&D?@(buCc+u&E{!B+WwE2$CRb7z~r0acyCTEf(PJR`NiA
zM-iB?iJC0u#pSL-$`kr^Hf1(x?%Ap#31>)0V=G(O at t7)`m9?^~VB&DXT#Tzu3 at G!)
zFceD&8wYL~Tn_KV=O%}y1)p-o!}BTyI9LzvR=Jwv3TGd%J_LP>#ofb3QdPC9gZ+cr
ztXH*KE^9h{Nb+`7+ug(AdU#ap)iMs}T~$5KtD9FZ9|{EbpTF5`s;jQL$^GHHxVx*#
z<Ppj-nM|u{*H<AIcenlTd3pV^rnBjz0 at Q3)i at V$Es;kv{U5mwCb={;^%lklV)m1$p
z_-nhpFT8a1(4pPmd$_knAJn at Gy0^Di>(#P0>u%tsQq@)0-5)Tk<)XHmZB3?=y1INZ
z=n5Pi9o2HNsO@$$z!q0^wcBm$^z^LmZf>f&dg7>jUsyS+)pDVEbN#USKNb%bcef9F
z&bDrEZ~D*gx~jeT>|yM71JAGRc2~36w5F3u|N8v_xv0sctFD{eKaWXQyX_`8dsUOk
zec;1$bI?=O)oQt@{r!X5Z8x=Ct*Sb at P51YGAIu-s;*P|stDBowPY9;V#a$Fe?%&^a
zUG2?hb$5F+IH&ISs;aKLPmphKUdeFt)%|bX?rJu_Uo$taUOp6#Hg$LR`2N{!T3yZR
z?)J8JyRGgI)v;M^)~njA at 7K{?-?g}ZHuL%X{`J+WHrve;^W&qV`{%ma-LI0nhxvWK
z$5b629NxcvKjrJ at _U3+m7u~4CTHM_gG3?FF{p-~|DBA7q*WK+Sd}DF9s9o&_$-v{h
z+0 at O=ZT}oSw$tgf?rv`%&iMPWna^icyKUXPx`$ldyn0ou)p8(CvYm8wyINJ(mEcp4
zoWAX5Q_JnPYPYMq#a(UIo9ZT$+HUVV%*(}{c(nKH=l<F6>hSQO7Pq&xtKA?Nf9w?A
zuQ~Rg+q=7m{bU%lxhS}0Hvj-207*naRBK^Aq~)3U?M|@I&(8;B{Pbo at WiP{@9IPkI
z*M^%;Bw8}L#7hL67Gg-aWh!U6^Op7$$S*T5C={CyNfHUyAyvtI#+w_K-c1%CA&zk|
z)7>r?SDb*S@)m*da6cF-k1`%ka4kmU4z92CdNa>sI-L##gBW}BFD<m-Zk3Bt7OY80
zbH>K}RznigY~3-u6(|$3n4&ZwjZ&D!MQJB_hVfe1#T^>^%%pddg=08pn78goxgp{B
zhGfS at tU)r<a>^zdNV!z=4-&7R)#1dX^L{5QOekZETLyJ$-uF8FellC%EY)8RsFOCs
zud-$Ds+2M1Ez(jtlx9W45FsXG`hi$p8A7 at pm#HqBWNGMG2J?mty4u6Wl&WNwo at OJk
z;*#HQjHfH_Ho!Bi&-do)vdMQ;$K8HRiDF~kUBzc1o49LdYqy1&cRsuf8EhqKNespx
zC{1RKO*RDbIZV3o{3%^+5~bl+mbUiT5JcSE+zenP^ZC4Xn{{n!Qt!^*su$gU-OjgF
zdyiZW)?5!`I at k;#1O2A9tJ-WgwV7-Ng!{>4Qr+x+(_7W5c89w`waJ_2V!NpBtQ%B7
z-$}F3)2dw!E5v=JuNKwKyMffL)%uo;Wp&5H&v#(6+FuRGzWlykyrH}A6xOb4GMx-6
z<-6UkRtFCR)!jqDF`Wz!iS5aDfDeAB>#CbSl85W)5n8r4-y{C(5BEB)C&XxTgu2si
zz)kbmE|<&N9q$JBe*gaah<UkO*5q_DC=fU>S=YL1uLcK*=k at wvJvf}1<K6t>_2c!R
zBgDMn-nU2F`}nh~K>*d?`|)F-FrUq<x*Bw8yOVAp6YM}{xm;Fv_V}D!7^$jSZCBMD
zcTYMG?x1%^T|e(!JYZ}mXAk$@O=>ou4LE`8Ze86$Hz+`OO|1{sPr7CGkjShz>)IYa
zj?H{FuWmAwQ?26~1U5M@>Zk at C9q;YS<+8TN+rjI6cXjt`l6xC`{_Nqb*)FQv>-xX<
zn(56_j~)Y|z4=~0j=SBiR=ZVA4j$)?&-m?jTkCFJlkVa5>14pMS+Cc%IodoSjqi55
z>Z)qDx~rqvbsgWnQ`6ej@#)#Xqr_*d;g*IW8^UAgm^m)y(0EQ*8vAt)@2s~}s5FN-
z)%1K0xocrqUaJ#m)mBSc+w{>~OJWvx at _0Y{tNDy6`|a2;z2JyntafLABTJea&S_eK
zePXiXV>9$jbXp#Q_FGG+YZ|R4v at 8w5z0b3kn$O4?Z$2ZjpLw*NSLWb&J<=frVPHt4
zq4$h!8iqTuNRL5tgr6()W`n at 0WG>_;-;pA=lTs((wlzs^me+)#^8<km!_3GONi_VS
zCe*v at V7Nk(+1RjB3Kn9sb<TMpR3MGdP2(Q(K#ad7kg at WXy--rZ&lQ)H$xVa0lvhsv
zj~6o4Z)=5Tz-b|Z491NWw3(KZft36-89(v*>Asp=2v<lg9cjXP9sq8wre_8BZcMtn
z2A+)8pwEtr$IfJYDqHsRa5cuC&n5_e$Xq5=J9rk%o0P$A$s?vvf?a`Ktx4`w9-h`&
z=XD!mnyZi|YMH>gYGz-D<#KtyUN`G{w>zo-^Y}N_=Xa-dwb`rP-sC<i=_qdQY7kXh
zG^BrBFTU>egHRmV#s7Ko`fm8|FZuO{|9)6s;_J`dTa3 at qYwmsjbz>8+<*?SS>aaC-
zeE05|d+%N|w(%v0-Fv_HC!hbiv3U>kV*gh%Z at R{Fd#__tPoLY9d9l0yeXkpvFM8g5
zIbMG+b9(oM*UbK}#+vIMf9w}}c1OR0vDts!*zBr1+}3HgsJAxn)~9~yZ&&y7-8wuz
z>EU at 4JSa+8KHkuI7p*8p`gOyA=}1tNvS)_li<H?lgxtY8P*#HZ^sOSkatFrel(`NT
ztx3{%8Y3EZmtq3uLRhuTFkSPD9G_&D(makN`x`=J4h?^6S#QJUtgdSbV#d~m3ZrT8
zVzKX4DvR0=&2g{glZ`krC(uQ1OW_*^Yi_xDs>u;fbxnISF;_tIF!tuerEIt7g*^yc
zW}hxZr{9^2NW`927Bx2<IH>u}DF<&l3iE~{tCO at 84;dsgEEYSk8;5DEACu9UtqGoN
z7*-{-+^G|hl;E?@y0O8AN7=_AWh-e5Tk_LzE4Rpi5cvV|`3`8U+{0u~c$7)!#_XpM
z0f~;4AzCit4%Tf3>fd6umGo(G63Op9KR<6y)@-d>8r$=O$!@K1XYou%@X}dvFkzj!
zVZ1#_qKV<Hj*LBc%zd)ji{%Hwx4QddjHs(IZ1|R?v=0pjjMeN69pm$8y}FWS#S_Nf
z#RFH_Jg>};p~~ST&hGRkZ5vy>Ua#w_JE_0@*6*(C?SB2i-}>?TuCM!Oy?wD?lZMRU
zc#YS1jn_XZ*KW6~&%L{-zxa3Fsqg=>pR2o*kJYdHhd)pk50z&p7*<gvU^N#a4R)VH
zlvp{8&vyJneB(-W786~RvP>>#A`b2B{|;zVWFn>N6Ln#gMW5j=umKU`tl=DUK{9zB
zCd at k-vDqjAsgo?DWgI&iHfKI#dZkzjpEKNrTq8<|9bJ&m*w3g4VoTdk7#U#rH}^)|
zY+)9wwwgA;*je<&rjc}uT)Z`p%kwJDKHUIFuQ<N{^73*ZxRG(OJ0garWpl%vJQs4E
z=y**bLIPUHv<WBB?zm(U>IB*G>%cVAJQIR02W`elCZXL69VmcZ%$e+7h)MQ$wZvr1
z%$luAW@%|xQ-A>Zvgd`9G#<d&+1a42?99^8vvkIF#lsJr%DUaI{lH8#c6-vBoC&7p
zWq1QlEpN-AvI&BJb;TkH=Z4{#unvCK-Kx|IClR9Bl1|)i54zHoSvk+fZF4KWdES^{
znr_hvn=?+@#)NEwBm+JGY<%bggZG;&@tjO<I=C~oUK6f(Sh_K>$0>tLHOE~}Z-S52
zlx?lIyZVXqf1&nI&g%z$|7YqOzWTft>s at WL@;YAQHD2TOPu$hjXFhyX|M|Cly1wIU
zzN-H9zw{64bD#XyTL0vqsl)w8c&iEXc@|iKlC#wXIg|a(S9JUWsv?yFfoi72u)7+Z
zQ$9yh^~~@o7u*c-NzW}8^sMA%E<-}=SF2SIp*F<G#Zll>*|i|fFa$cKui<f6yu&Jw
zd5+m<&qk;GK7#4w at KW%!%Ax(vd`8;~%E7of!rY%@$CTw}-tgNTU(rP&SSN`|_*6=!
z8 at 5Ns#{Pz>NSm;^L^9=^PqR^;dCL4#sI|9^ImX1 at R$;S3Wvhs8F#+46nE%asbhpdJ
z=&A?POaf9CgPn7I(+;XgWKv=;Wibt-v2Vrg?d^bPVjXs}em={}681_lS<Z<-YPg$}
zZPO(FmWqWp0&9I6D`<?VVRZzQJPaorNboVS!AYhGTdG%)u^%5FKY?eN%fw{1VKkj}
zR1 at yo#z_I`?nY3$91T(mN*Htr3>Y0FN9P1-COJ|>q`O<XLmEcPKw^}1z4QA!?>YOI
zb9VOd#C=_#`?{$PUYSF<kyk74?<WMev^d%njrrNa+%6US-ZlRMEgW)D7?Jlb7f$mQ
zZvNypFApa;bRIQYS?K$bt^Z7DM{3;0V&QenTlyAsIFztu-CuD=n3Q;*CM@#u=r4B~
z!(Z8pFK6E|%stU>n_bp}fUo5j3OWyyhqo#Lh$WC`%VJ#A$iJ=F=2Cv(tlv=L6mYi$
zI(rqk&9l3^#(B0|5~y5;a=yMxX#9x@)ICE(ad at M7Zk@Yyo!fNVZ%^nCj-1uOhg(G}
z>B5X9-=*2OSVSKr*{A-P9deE0N}b-VSqTFSr3!({j-V<oyxQCPzw2Tro$s$bJW5{>
zRE*SyizjoR=Nas9H01%~?)J;Rg!_1#q|x3&#iKM)jmcQd4{swqtA2G!-+o003o_bp
zQMy(2L$5~fn9+suba+(R2)R~11dP!)ru3mlh+aYlvp!eLR}5liATZ8MU(zXEKF-mU
zoOELaCD;@4BpjU(9VR`=zkDl0a?19>VsI*!y9e%I5lKdf=&BOQ?%TDt$uMjv5zt^+
zwvaPqKFZ+PC=QWP0#I|#bLS0XdhbmaTSK8z3$DW%bEBMH0vR_|{_IgPVeavAK;Vxw
zk#BaWSC!fuUnqW}Y^tK%4u3e)$z+=Gq<s8dVqUb2?ne!Qn0r0GTPjkMRIlZ4*w)qK
zy7c#UOv13=Ny~F-iaO5R-|I9Hso<9bYaq3ybOElcaZq=#&)KPSOL30erAJ%9`?D7L
z)2_uB_5ZD#cEzZ(e#f4e%M4FkiJAZJy<HU2x&!Y+LXA#P(%FIov&Ky(CQ_+NSgvEO
z={i#+9N$OkFa&SIIgzl0s!U at MAR1y>*g`@eu-ULA6x%q?Ox?X2%e2-&{$Qn8zJ*Y^
z1?Giqx9a#Hx|*eaqAP~eUoBB|UEm`$6nMUU!HBC!WUeIF8(@j?xEIM<pcdZt-UlT(
zoiU*$yXGfhm7pZJ%*!K<x?d9+xcipa+Lkwxx4x3a#V~29tIKJ&&k39nS(R~f_I)K<
z;VY8+Nu`&d_+!I%N|U~}wAigA%^M2$(y_InW at 1-0mdi<gK<J%gS+lC at UTn+?w*5Su
z;P6%+6nHLg?zUdHL9lslq1P8eXZQ-?WTy`-mERhY?pU=k>>TpR1yENnex_vzKXoKz
z+_WplDSOwK;<p{-{H9P#2A<2ugqlxt1l3G<1cNARTS|$=5M|&wObTlTn+*Qc at h4Hi
zNa?GVU#D1uTH}zLh{|`3*Vta^-DE_(@aCM at tlBGC8NovFZxJ;9of+Y_d5^qBKsAOR
zW7ii9NIdF{W=c}$Jmq96e%;yqyZnHHV*gIh!#RhB65pGRT&;`dW~obaC)PFdOm at M@
zt}~DRC(+5!7atNf`Gr$q0V}TD=k{Y9Snt=~L&lC6uL5E9?`XD|^3n#=p$3WUuc9>A
z47LxW$TQVMXxhC){VWw|#iUO6b5w;Lg{W_$bmTbRXL2$4rl_-gpViWdlsl#cOFX`h
z53nJ^Ye;<zz!Y4jV0Ej|`*OOMSr>SoD_Yul$;9x9EAEnK^iv3x5g-$*RkeOO0F3oo
z)SRVNwK}py)30(nRVL)z`J_fsBkCBC6d9M`{#fGae$A`Ir3=*MBdT<2r<<Numq~dm
z?V^z_t1f}skuh7bM7bv`vF57_^rSIbn1l-x&xMx7FU0%@CDj(|`VuG-z!k_4I-@?&
z at l_xKHhIJgTi1A9y^BXpikcI3k7+ymS>|m0QwGk_RUYO9r=wS1w3p#b?C%3 at cJ+)`
zPaxKh=bK^u+Xeo4$2Ca3g0YsWUM^J>)DX1X7ka*@mKQ#K$dfoooYCtA28#|{egHAo
zyaU2(tX*1N930aNk)$F3CN@;4(bFyhez<vY_Clm*oylzT_vZ)2$Y15o`oPZrE!?Vu
z%i at g3)Qqo0*_jQ3R<fd^0?+TMqVWlHS*O*Oz)i at vyKuQZ6G%fYiJz3}vvW^xm89Xp
zCaZZyOb~|_MdHTgPH!}Az}E7S+lq^V*b>p at 4Rh}I)@lpS&W;aHL#i<Ay3(B;NJ0bd
zXQzI}3Hc+9o#MCzsqH=}%~w?%me~)$wwUUCFjzv+bb$)RjoV=>i3e|!K9!gq%Qri&
ztQUQK1m(|YxkS$`j?q$HL_y?%EC4Xzu`CB4^}T<-3L<gkNPkKNQwaXaam5qjJ(B6F
z)oA!k_+|CkH?hq at jR~vMb|NGx3CSZ<SW8O_=It;vBPIQ`+gW|G*=Wj-b^z2DE;77A
zK~xwYBl7+HiL3CKRkbD6H?B}m8Mi{i6w{Hi$Rud0{~S8y5#y^$=a5T7F}- at Ogj5px
zn at RuSO5=X~{Z_O~obsnB0UXdiHl6s5x|(S<OGSm(GAhTqTU@)R*hWgo;8ITx=xDMK
z`ZjecjsRYB%l?VFBWo3_J;iPPPCfK5H^@<#aFQ`(4rhj8m9aNW!-HtsqpsUZYK`Q4
zAaC>8@$@l61^RR0?fvp0sLhBp7bx)IfGZ&EVtc=mmdQ_KP=)4i at YqdeH8_=BNxpE(
zcBV^qn<~cwVuSTse^v at 4>CJu$f3u5~9d_j(#Gxfw=nuWQ<Ki7WtF<M*wQqhDcegxQ
zwNV!4iFe8s;@>XA+Y`5(Iw_8fq9YDh3y+?Me!>>OmUhX*wI#gu@*_HFj-XQ0$=opz
zn771)>eJVQ>SUV at Q9V*!p354E3sEFl(%mhh07u2WgRI|;=_&&v3U4JgI0K{EqdcrK
z)eNr}IrOn}=pP}lk-M%*&2ntqx{R;>XpAPiSNiHTtwCe*HGE(}wXmmF$V&;*>1wc^
zi!l4%B*Bey<=bD4JkNJ1Gg5|(QBNV&3F%1#31>#V!xt-|Gm!m6R)5q=qF3!wE5dMa
zF<m1?Z{++dpP}=W)VmP8q)WqiMpH3wIFa9}5?1|7Z)l2NvG376ss9?bwzMZo%W%*}
zI_umCge(yGu0wQb+ at 90Z^_dqiUAvHMjDlc5V4MV}m_Ud%TLg5b;C)V$Hrme at M0>NE
z`HTgr{SK{td&F%3_)Xiqt0<nS$9(`4?&G+r*w3>+PV)WAaqL;YL?$k(QHS_R at IQdg
zsPCrC_vNh;7)T-v5<d<NIC<(}7$DY^*_l7Z-5JQbkmyG7l4z2VmeBA;r~N&dt{+d7
zK$OJ~d^+gqsv{!t0)^FDP=*K at oS&#(LS25FBdiTsT3S*(o?)i<sg#vqG_(1t=x<J7
z^On|M;-b&x%>z53K|<t_<H)+_vXgU*jHkc+>1QsOlv5(FGVh(AkDLs8zWkb at OncP;
zb;s!Kc8ZZp&d6V<j888{Nx$Sq&lSbUusyLATUaH@)3O>UmRr*)6DtWUFERgNcpW17
z4m0%kEN at pM`)j0DV?I!U0)XvZlKC65Z@|Rw;kP`pecB$HWQrS4EZ_n=Bj__dIDYve
zsec}l-wFD at 74h?T-3B8QBi<%@>O8h)fEmx4cW*c9ymid#_XXEve8gDmn`(LYfn;8w
zWE;V|ca`KNeDCbIcX8m`s49{6*(`Z at ve6j5E&X_ya~k!b=%kzR!Y59~Oj0_YcUrE7
zl+IN*<}Ckq(6KM9e8%1s53_1)2rU&ZM4PhP<TR|2s*1bg#$>4Nv~HyaKpAgHNyFP%
zNMfEu9<+dR(gv-jaz13b3w><g4-0C{hPqI)l6R!-4Ia8%rZBTBhbLj91s9J(iN)_*
zdEISNmrw53 at 3bgt)HEx#_<QHC at 6b*RHeC+&f)66o#!`WAYGE0{WSjF#&&vH36o+0X
z62g&ijF>Sm6%DL12!^Rx;#s~y!RE)9fZYO7O9x#*Rg>8mVoAAkS$H^qD20WlR6Ck#
zdSX=}6{sM>v6BjdrR$(xLzJ|=8U_Z+&G0b6)>-ETEhHL`<b~Sa?mOH6Y{8rE^4*||
zkB`So)9YBBigu1YS$h9+?0cf~M^OOxV=V2BkWrf&#l0`3vveOiQe!!y{H?0^f1{yD
zj*rgowPMt)k{GRT%VlK$D0f?VQrO4v0v%piZ*mo#Pk^-_ at _KTczgn23QWEpblbnyn
ze%-Lx$a}sr%D7oQkI{jkCSlYn$OmWGK`6PR+ at D86##g&XE!l4{Dve_Lz0h73Il3bR
z{c2C7HSRDSscBgWJ$@fEvJ2kx{G65Yr=Y}Q$B==Qd-o?ZHSI_wxn#rB9k-WcK-Wju
z7LT4`h7T}PG8)<3_DCV;g=7HGzLtRlrSh2)e6=QT<>CFjP4}3~(JCN~SeZ1^vH+;6
z+%a|3QhXq?V=gmzOBWbs>*l}dOn*#UWx)VFZDqnX&>bPhp$%z@@i=LNpIUxPpnT$P
z0(KNFM=C{jO<cu98$;83Qev3L7g at sMOrs*2f*6Ym4LaG<-TWpDpGS95_&Kv<0;{TN
z2>S&DyR9fVen(_d_?j7{6ahPlo`IL<!v%pFhyvl1Lr=`YET{DSfdPmpNFq7{<=4<E
zQo)G5`#BsYO5<Bkdv|sF at I|54T>!2p_&4PieWhw~pl#8)=#QW(`pv;T^}lZ*Hqrr7
zfM<IL<_IUtl9YFeu6|RM at +DhR>Q*d?r9OG|Mm8iwWgs31Q(%l!5|=>PfVaB~%JLe+
z+)>@izp>e<yVU?KQ8qGSXZ*J}#Duzih}iqyL|o<<l-u>Z?86|LH6Hp3C1^3Q6Ou$*
z(fcxwDtkk(l29DqNORa_X_nc!s}n*XbjT)fdB*C#SoUE}EJnog7Yy!4YUySugnH@$
zAJHNABUi_?ZL91_0F}3Y&%Bg8*m1z1?lyub2P<V8(zRD_FwmF=!d~RDBNTvGA<Gg~
z?IN$1TXQepe6^U-jZeOd78TUO6poLb*>%K6;k5Pg)s(4&3;7>)&XY)sh*aFn02PQ^
z--Fqu%{4`he&%bmgQ^Q?8jVe~tkB0Z-pOERzR$zVjP7cvQN^66mlwd6r at q=!A4Mr|
zU79m!k5ki{Q@=}_ME8heEABD;^SZYA3-yzM9W*(yBuPo$P(}>jbXf>*i^7C&$`BK8
zo at U`RGg$qUj=~?Juo|O*2*2v<YF!$;jY}CPvO*8UZlV?S<$(y9wbFUOiHO~wj3hsW
zUD%a at 6>810A`N9bCxlO<vtfU6z at 3=pf9$$<HQ2T~-$;gxDhX_u2Wpds(AA~=?=o>7
zb=7j!q8HSB)mL1MhS1_6=jZ3wyv=u0BZ-4wzW{k3+w32{B<ZAnVj$k%Cm+!MR!}p_
zB1hRS#x~TC7jDEnbWE!1tlX+d;>s<<wiV+7!AWY(_1Uw`&jU?RNWLoL)zj79pp^XC
zF45iOBi9cYeXah8C?3p1`do%nDN- at g(Bwy5WHRACYRt9o)Gw2bv8ZQ{g^|KUerZDV
zw2)Z6$G2OZ`{JdE(-3aOX at K4rPi*#&pi+?{>w}{Qgd3Q)x>smpL8j}u#4_1v$aqZ2
z_#G=g%%w at 6yXM#tr{)={?M6JSBvZ=Yn>9>N(>Weq6EAJeGFO&JV>18>-SqHCC*_iJ
z?KxE(F>xy^HL-m6x2Mv8@)4P|3vQ*kE~`Lz1kweV2RV`A`-sLwm_3hb%8 at 1?KVDQP
z_>={2l@^;dPr{^Xz}>q$pBvAHy)RIwq^mjAtFzk;cHbn-8-D-sX=MBz8w!Dyw=E31
zf8B%}LO$pQaKJ82C=8I+uNBafeHFDS92>3l!h&%ZH5X at ST$i|d&uv8c1uW3t7j0Jh
zjPu%{_5bFLppSX4?UMt$(<1+q0#gG=SvM%X1x8fWwglly;8`ohxVEX?bU?tjFs*%{
zPg9;X&NrO?Bk`vy1$6Hh^-WAnh}fn`4Ay-YLqmd--AA`G?<StEJ?Y6P{{#W(t-PLA
zxz1xR7DK;!chX>Lxxaf at d-T3jUpCMyVl6^*=VbNV%`XE$AW*>Vi at dq0!~+5RzANW^
zQ8lP!1u=2WT0C(#bLmnH46;6-c=<`nGT*19x|zMx{rTUO<1dW(K7S=yELMaAFZYk7
ztN5ydXfmRLd{7e{bot>L8OAg3PoF>O_MrMGh9@$ZT&ZL9#xgBpKem&MQ+fFPqtrpv
zpz6)|5V<p{5l7>5wiH&4dr}x8ylngSMNH0C!#58g;da`|kaGyR4>+A46eSm*wS`CD
zLL>Y5Vs6?{LUH7x&kE^%e0A=1JYV1ew0w~`pWm#i|8pu5#SL+E{I+YpY)YsvPA7wI
zM3;!+A&iaKd~Hy#S4Qp<_r{mhs&M>XG3Crlf<M64gz2cYG8oEdp>sTvRegK1va%8^
zvsGpBVg1OjB1-*YxBPy2_2abf+{_ZIT=D90QQP88|MJ2gRLWUu&~E*Tsa{qNYOcY5
z)FNx&3uyFTh4j(i%}U~Tx~o at 6v#Wj=!n=7 at KvzHK_&l#F^|P);)W`REqS1QKHeDik
z@&QT8MA|dF)l_wtMBXNm2T43|=5(5VD7s3i4mjZ-AGu(x2W6916poZfP)!lWiDgJq
z^_pz(C^s-^h-u+0A&-3bcP=N?*Y2R?4At}1=eCN!WGf<rg8Lf2yfLnnL_eTQqO)l1
z!Aa^d=FZ6wAaqvdoO4oRr8U4d;k(x at R!~M}?iMG|IaNv=8h3m}L#P(d!qd?vUgMV3
zltAz_HosP;ggEa#4`PUVfm?KJ3LCXs?Kz*7CdoI>H3ExW-L&cyZ6t~;puc+|(6)1)
zW*Q_gnnuQ{4d_l?X2J1F74=+p7~%_KM~@kl_7pxC%m#wm6XkrE9Q_<eSS=|t$G5|{
zoZHMuiE>6l)@!u2v>w5sQo>pr^N~gsV&?=M;8#4%@mX9(#PM;&_8bfEss^wL99b~D
z+B~twGB`wP64RRW2g^joM^F2f`6zT;sQO5LY3|M~`$_$6DgLvid3W=07riLha{Ya^
zU4Qj5J%7=-Ec;-ivF66H at Kr?sd(n>Rf&Dppl`lU&6kOvSqIM4|?#%->6 at tuoL?1D8
zsJ&eH^WQxeP>~v(gvCWeu>Z`9-CN`r=qV<hUtJ4Mj|B9n5eOs8UEVX at IoqaWHJtcF
z*W;I?SvQ)zb}@gs&;<Zlyh-RMvt?AN_o=Km5cVGm1icKWdp!I4r1Xn*oN#feVUHF`
z6|VbEt>N?839nPhDe<Xu3KSrH>EJRv?y)-hk%UYpycPT#TCYx0DZ};sNy3jKQ!1Ie
z``?oks}r%W^L2O*wLE-ctMZ2}bLfY`VmzY)+L*CSe*H7IUfIm98mFi%96bUXB;z?Y
zd!n07KXh%-M$`7qbjTTJSiO5$mA|v6k)>o4(I5X|%eBLhdI-A=JzJWDPHZXbKyq>i
zK2jjRf0dqdh|cIKd&|2%^NiI^m4Qpcz?K<CESCvNZ92angL^aWBqpYMY<3 at Yd}d
zqV=cw9*fNS_KuF>RO?9N<#5&UOY at kgh^LINkDFs>ijn`%0<>r%wdjpfln8F+m3vPx
z@)m#I8LM at bxA%>M*@bqh@(&zE;i_~-FMsrz-W>T|ooub0ne2?fZ&n|A&%{Y=OlL|<
z?yml-^Uclgm)Aef(i!E}g)Ne>S;Pm`l&Cv77`32r4K&MQ*HB`3asAEya9x6Fq%e$R
z>(0-+Zs|`=O9c~`b8DYN>-|GeQ;oKMH?Bku(CgWSnIj9YtJ68SyDLf|lJI at t0&a~z
zBG3WQ;~_G$tDAY8DI&<#VlW7D?^~J*Io$Tl=TO5Ub_4i-uB!PICner4;g?6I{iOBr
zjx0#@$YqTEwD8 at mXnc<>IVWXsq*S8%P7t at KK(<=(ne;pMv8s&nGO3*(M+&H{s`J*g
zQ5(;I07OSl)v5OriN`ziz`^-%^iMBPagUFaXAXQ2S!&)&rH|o=A5`hCh4E<&-zX2C
z2MxGqJPIb~X?3ps#UDnczmkqKRy^v-##V<#IRiR%`N6O319B}T>cX)U%~0+>tkGb~
ziPw@&HO>*Zxc;r=Q&mMLhZ$4DWxmy-Y2a=1=l9Q!Uc)Bh=UFPg?2NO0R^HY(CnwdU
zPzkuEsfmgBAo!VprZB1;n=vE|lIu{Ucz7WbQnwM+i?RIkw^U=&m$DBO<U&k%H_lno
zT~1ec$0n0=+ZToY)yH+&68_(t3>|;2P#G`tnbo|{rOf)x8WLc$>G^!%w9|PiJrj28
z?t@?@`}A?vJg8-1THF7;_&%Doskq~~rsQUSv*diQrTq`~8EfFCT>#j{ShvM at +kFmg
zyABD>k=~6o at A`M#XRY3ZG+(o>6m=X$w=CX#kDt*F+E&f-h6 at qNlobCdE$O&gy>$$@
zd8jSFJ~F)1UzIIVxKsEz2MP)_KC9}!Za=&?xXTOj)q|slBQB%=J^D&I^h$KQZY!tx
zgfnzdqD1p%Zs&<rC#fwIFJo$3b)HhSBn*KTezM;U7=e6ri9hSnADuMEQc2-Sy<#3Q
zo;;A+de5d*KVBId5*?d48IZWo9tHloX%#{jd?7jiecpD^(%*6<%rjB?$>;TuBgdp1
z;)CEg;t4UlWx-~~Y?4=f$GY6o0$dawy&<iXI=^Vrl=sfAquwed9W%?k at A0x+t)3OW
z{zUh)vi0{G-7Z?=o2tO>zK(e$sv7Ye6!$#HVZb8V%N$eWBju`jbHmh2ON at USm&BHN
z)*!MxrcG~IUYw}kC&+C3bRM6d+x){<om38j&AzhyG0Qya7`hk5DGP1)ySw&B%{<{E
zUw>FOg5ztSn{b5&;I(kK%BXvE4n4 at CN&P<8di;+j8ZY;Lhyl`nCw5xSswQ_v_eu_J
zSN7A`uLZBQyq_7d#5`v`X$5;`ySdkK at sY^VB9mza$0H7HU}E&6^A?2cjmAioA!>qX
zT%Q$T!1<bp*8<%K{ZxYwdK4a5P8&I<e(&T;gea*T8kTe=7G^*XvqG~SC)+_y_kG)5
zXL}vz*k^u0!*&54RcK#Tf2Ans4_^6h)>SPk at Lu=MIA}d}_tX7kIg(Yj)a5?*(^>b!
zrqFCqL$)5X=I*Vl{13|ji(IuC5BVbL3_V19>ETtP<{h-6?Z at hEk>Sji)7_-P>DBe*
zsM&#bAIpDr=#2UJh1ud_v{;&i#{3MpgLOx)>j2%cn|p)0>?^j76It#>W^zC{&WFqw
zF-tZXvED!K2Lzt)^$3yJ61QE at qs%ixS&zVMDt{({<zc{ADlnq~oM?gt$1kgJCHz2V
z8eUh9Ev-x$fL_28Gp>7fuUcM)W72KjD(mdy9vqrbj{7RRf=Ow#0 at pDqi;7I(de2pl
z7azOJeA6^P=;E1}8SMu`rH^Re0wW}7-;m2}1ZJYaG*{&wEGDFWp#u4!La{AZqca(u
zBETZ}!**urGBx(2FZ+?KSw4VAUxchXOU<ma2?&!fKAc at _sc@`+kXnFrFfSShvU7)T
zxrp6QPsMOwA7AxhHMiONe9>eTI2hoz^(1Q~aSX-zwNURxk=hrPa$HCInMVv3Ld+nV
zX^dLqy1MO2XqL0p74>!;XtrZ*{@SJV+f!OpR)29UN+e)knu(Z#SxAL~-o0WZ5mWTf
z at 2ojFKnlM^-?Tc at 1u$RlO<*<V_m{24C$iqac+H>UFQ=D_OOXjLU^reM`*O`)JoSV2
zD>{nxVde6-#`5nKE?okv+aFpK^n&)iGiQ$j^&bvbZz8URf^75^?te*~!Sq{-)n`~Q
zQ6Kdm4myq<c0YA&mtC)cFCiagx2^T-5ETmdE)R?7(D?_>vsXb&>H)U1x at FG0742e0
zcMDcAEB_7&2UoW~_!|pFW;38r18pX at 7VPYRCyC7F+<qf3KR;jb)y_<b{@orF|B1)w
zgr8X<=f;pct`H;XcafR{2}dGL_E{4=-n|KI6Dhn{<<8fRwk%OkK1T(q>9FlF%3J5i
znn?sLR7$)1KLZ!`$45{Qxoj+ai;rpBAc{v1nP^;pscE27OwGvss$V@@>L*mcY2NM~
zU&+EkcVVvpPl%0H0Xz38K(#UxKV89zRqlpVD#UXcg_ELG7X5dG5jlxKped-4wy(Ah
zuW?nK`w^5vURd^Tc8(Rze&Co0Y`B#WtIQ4sbDs9$xI4^z<L0hqf8ktq0=E_7rV+lv
z&mQr=_mF0G6(C|B9wCo~@bIc>7cLa?F)Vo1+xMf5eT+aWAL=9SP5$-QM**%@^HhdJ
z8fr3gSa5gR9>W$HZrM|v1B1v&r|vhRD6a4(xwOj<0QLr2fz!0>yOi?p at ZUpl8Awc7
ziy=DcCCoWhhI_z<AtPn1AzOc0;bAOdh<o5rJ(1w%v^L58sH7armlDV>Mr%NMd$X~z
zQN?h&#pgDQ?EQKlk6ujpw9CV^MO#2)*@BgE#}(zx*?FL at rq`MG!+Np2cTEx8RCh-4
zZun!%N4yr#fJ at 5$vohM2YwEjPMEPzR?7BW)vjokWmc(&;%C>2P%~o_hfgqcIuZXYs
zz-eq;nX#aLdBHR(wh{LcQ{2z*GjX3a!gfDoDrY)nis1x6>8etBUZt6fAr2r2CKj~k
zzcT0|T#Gn*8rTwGvjZRxl5BVTny7 at Qa~#!XG9gAqG>r=?&pXtOzqR+HTf||!r0$@-
zCmWZfc60hcVAOvy%!NJixKwhul`Zjg%}I;{d+n)Td|ce4;tH*w{C~eJdjxj>11pw#
zTEP@{V?sIF`?0jlZqR3pNE?XRWD$p<dX07oBZy~=fY$-K{Q at hkiap3hg!A#G-gX%U
zh&zZ1wqPZ-_oD^Z#uJw^yV}y?1IInc^BI7GM{D*MAU-U%kM13hMPP@^yvgHGh%$o6
zw1(~luY3BDHK$;AgNAJbUc8vL{s*Izk at J^%o`Wy9V>_X#W6fEAO-)USzldx2;7RvA
z at C=H1O_~xg+GlVAn^b`shCBTJmHq7!53}Oo)p=AM2&Uv^E>q%TcZqMobJa^dE)pxW
z&*{b)S>tBa8~nu(<sK$pPeyRw=!>f at JBlL(izTGIrCSGG8w1s^x}BFO_YXUA(O}>7
z{tEtgGr_q!M5#mb(k!^9Y^ytGl+>oK;SY<n(o%D)@r-kO(H}2Uq1lhn9V<YYA!58l
z{c=5K*XAGe at qAve=fe{=Z?beUyUnYz$}f+<;I!_`a6N`-8M^jw6Lr<A+6vbpFTju7
z_1^y#y&W3LPoewHw@!HTSULDoURqw at hM*g at oGi>AFSht2GUb{I^aCboDRcV5(Q9m*
zhZKP8cM{`Gv=$c=V5KJM-zPJvzEvJWTxS1<AGF{s-|f#j!EYzj74#-MG7lJ27LC-J
zdV1t%#@!J)PyXl6?`*ilBMCVvVZn0lslkcBamL4l_vPX4&G;xm>*5)R?4v;<La8uM
zBLg%KIvzK5HQUvWFfCFu2#q%nM3-TU(J5>0Hh%_3gPS(Gx*K at Ymtf0;rnso&2vqQF
z51>S7o;q#S*|SKmzxT5%v^>4vA~U~43gy-0nNca*kTqJ93;*&xR*GH|DPfWIIeZ&8
z3ZI(h4biXU0p~Ah{3EG0GQ7pq at d(AzRCeHZ!JRzAg8nTS>J;8lyts0CX0;X at irtCe
z?Tf2-tB+_KEVy{DcNM%<_pK<MwlA8YJbfmuo$<Wjvd2SL;eoJXx8m-1eVi95+)<*e
z;^D7FK)><QbwyB9$-`FvYFWqad3pP~tEs{ztYX)_q}XV5cj=*N^Ex&MQBw0qv(0$;
z`o80w at GN~*x+3RhKl(aP-&FU4Z=d?0_}MSn{{cR==`vJpd7XBx9guS9izQMVdb55N
z2vkNM+$Gq;0D<!KM4B&7_+V+_{R+%d>B4<}u1-sN<s?9w^*7Hgagl~tz&3S#9T33v
zQdngX)Jo`^c?`WvCmd=Tq1R$xj3lGwi<-;ap#yAhJ7<?h7X&&R#(3OrVs!{GsktJY
zz{_t^6XuA^wil!TBU(8TMEps~)yq`+VqPYKsbS#=RgaDQze3=zz<6eO#QSer3oe##
z%)Im1VUiO1%T*!_KelV7%r#l*mF-Kf9F?T8&0E`bpI_$98oqMK?81=WB79G=>Qc>+
zUV)wA@#6Wys0kiTbj0IqqR%=~37s`n7QR_Tx3bgk)?0!x4CzBxd#$|cpo3#IxtklB
zQ|do>a7;<>v(1;v40sry4nf#kC_yni0^Wr5WR8B6wTsarU!b>!ld-G25zb$8C{199
zAL1g~Wdk<duS?qKr28-}$O&Kv2b`O)vnUfYX;DgxMAHPtCC~J<2eE&$NPEzy17U-|
zqZ}%tv5{-7`gX`0k!{wN>!OFf;`R$r#r0T!NpI=>bkNb at b^Jpe>0JEnU`|EORa5HO
zr~6wcW^FIeEBg<7`b*bNt7m_%FXUHdyaM%BZ#zuqNCN|n70x9TKCWI<nwqY7oUOMN
z!y~Gbc%*dnVW4Kd_zr>U at _#iyL&cnq4gNVnkK}gdKqqNPei9ja&`cl#fW at U`mzQ9Q
z$>(iopHmZlIpD7 at m@kSJFh)4(E*3V-m&w=&>1(I+V?M8mRnw^}#`+LmQi75-3k6I^
z=?~{CB8t&Y-U5Ma at so;?nkpk^koanjdhY1huUZE2IKs8KJ0gMnO^XQe)6^>`lsVlj
zvT^BU$ulQSesvSguVWWC)pYOQ%n;R?A*%>)Sr{!Xl4^BY+&MP6Mox#0qvd=Z71qP2
zFUIESU%MO at 6u%X7ze)H66b;H?sFHMCv}Jk4%kRdCjLI#{5&&>(>z)~H^53F6h0L}Q
zFu6SI6n%|L%8p)9aLVM?s?}B>LDGzvVGK-Tiw|!Tnd=(FufnG4;gA2_PDZSWX&((K
z`yOxfQlbwd2Y#A(;tN#pVz at VKCNst$J at hp!f}(T)sX2XAG~Mrwi^-0oPc;SVGvjlu
zST@>fr<ZZTK{^{Ich3Wd#cIgXC6M!tQ|J!n@#F|c5zJxV_hnTHA;#AL3m^=9vucwS
z6KnlUVDQQ;5xq|}ZGK71rA;q%)y8eZGQ40J9_Wv$X0!U}_tWc%ihz>9zY2F&0f%$U
zvxfS0^Im7iAKlG at HsbxA?kZNnZ};G;0;K1=<998r6$-cGEYs**gtlM#*S}V860hUB
z{l-RC{NMlD&Gs^AE_N0zf_++bt(GW4u_vaF7wY2uDh{|e)<3=arbWu_=_^^*{U>!c
z{C{S<JIF at nDKB|#6VOs8s-y#F(}VhLyQqcS`a7Ij5AM?aL3F-XKiSTpm1r<Nd)+ww
zo;d<nQGeG|${Q5oJ|Ig)L0{6=l>2h7t5U2d!7<XVJgjX%1L at rr?}J2_Uarm-A#0XT
zfS4RmF|<O=>n at VAch)Rq!{F;OjeGQL1z4j^VGg(du(MScBfxAd0_driU#&5)yZj<0
z{xWx7S$He8rF;*~wdPsG8IH#Jz~V?+SvMHn9huw>Dxb2$E`^NLx|aD)$IAY0JEx4w
zmqoq|9i3+=`}H at yis#Wna%{kU@<zlaO&Y7(aQ~B7&*I{7BEuJByJeu!;DVm)rJn->
zhIZYAlO}klCbE%w=c4|f#~U`_Rly!AM3|!DBMfH?DK;E$%Lbj3G~;CfDf63m?X27-
zPoP)w-T6drmZk603H|xA#2cJV4 at 7PUQD-`SJ__nzu2fg>OaE?Q|77?(VodQwpN+`R
zy>P6U*?H@`M_maP8i9B8iS6CBA49k4Nd)j3mebVTMj3#(8Ej}Ladh8^RX>`4+WL%{
zsZ}B;9pR;465p<ScpDY3qq$w~DSJN()}8a-lfLRyyc<-woH;ABIqgRcfOUmj4(;m}
zbQ(<OR<CZ$?`Kvoj<3h%8})ykH3#k<J}3pOMwb`Er{{ufE6%^`)<GV#8=GdLM+x(=
z{>WHm<(CkmtuxRM=svvKT at 2VZ)79KX+30!?n+ELWKuYdW5`neFaD4%NPe==We#3vK
z4HafA1$(Y0A)a#oyr0;PWrsG)qniqX<CG##QH&k|TtD<!7K~T^J%Krcp}jH9<s~&W
zHHzyC5mp<l{jZ*RS<UDxkDH7*PCn-E*q at KTXd>G?M7B|dj<RC0B+H9(**x?5eHm$4
zG^u=^F47TM^_&*lS}=)jgR>u_KJw_sbjPz{cmiOlu#_|}HgUVN--t1~jfMc=HvwqP
zt at Ct3t?)~>*If8^SH at B6oBPBT)40{Ap)!efMRzA=A4D^8niCv8hvN$R6XRf%wwqsd
zO?TJdv`ReY-KO_Q2X11D7Y**dM=^Y}k2D4^Q$<g}VpYO1YvvwP<LP7Yhk(5OHo0PR
z3XC>2KM!V@;PF7b^q=28>+hQoYp^N1M2}^lO-gQ<P~=gxhE=B$($`2-p}B=XK?Add
zsw(y`B?8DO*F=odrO^<PPf!xN875??$ajG{TF{xi`3S41&L|L6-QExN!+u!gi1ZE9
z7Qu*?l}uEel3mYW0>ltUC2T*@mFKB_y5MT~JY3TzpvM1@=fTTZs617-&R?_O^#10f
ziBR!g%IF-)_oeHaptIAn?vir(0Qs`8#aZo#)#&S6FJruiY2!1wjz8bdy@!qJjh?lb
zw%vdYO&b{ektfckCA~IBrtq_JGZVpL`=_ at e|GhA_qUpN6Cp68u_rZRr?b*?rgaVWo
z5ON?PfJf|QpXj~dz!PvMu8i_9zN7%TV~zWmNRINkZ~nY3N!6(ApL0p{WZuT{XJe+r
zGT1?2|Cz_L>aU-IjUO+n?&t}-_`n3Hl2|o`okiux5xuWZRn#^l^I at F8D{G|gXZrN`
z7=DT4$fj*<LfmH?Mnr?XBiqv_r7;;y78_>K#J^iz!3iwVDKj>Xk=l+?N=ep>p~>MN
z>X%M`zC4BA)mb%V=}4Vt)HOdwTKMGoRx^H8-h)Ni<0rDqXPcPc8Tdf6=`;G2y^v~e
zU+KbgC(>p{_%ALlZhB(QsYvH#$$@u9a5m9KfZS^#DjLyLnD{sPG7c|visp~jmapbY
zbd(&%CFnM$Edss_tGeFk2#_{9BO}d&*d*4C!q(Q1kY at obYa{s9$xUK7OClE}>(Gau
z{ds9}LrA`VV at TIBa#8aZo!{tO$Pv|~>ye-NqHrpw#Gi|y&sye+N6{vKV0COg<ug|)
zIcs|i!V=v<NLzGt*2{%6es|FP{cQB3yMe-eM at K2^T at b2xRu|SlvU_nG&02JLlhUv|
zcUb07We_x(b7%Ij^dHBcI&RusI8vpl>_RJZ00YhFaq0o!nxuzFCTxcB_WLf<Kv#?h
zEtStweTF}t^sO;ri2ym3`_bt#KBR#lB*eAiNA<}9PUf;gB-Q-^hx?<_9xobGNpyIG
znkvt3m(7lW_upRLtNkWAJ43sb at wOAk*qF7`os6Tqg+#?NLENC2KJ}g`_F(yLG&LU7
z=bp|9G{|}qdB^ljk6R+Eip_aUNw6y0x^3OLV8d96h505OZ25c at JvsM?)^bcr{Y at Sg
z=W99{cv#DoML`D@{+pdU*jSAE!dM)>8pPb}sYcvL2IZSq$o^1QKbMB3vo8OnX4CYB
z*Z5HsT!4}|O!5;P4B%(j4?Y$hpvm#tg&+H`DKT<Ef<v<(&O*K?!4*&7=#~ps$5uzM
z|0CFfVZ+ig{YY5F)_taxQJ^rfSkr|^yyt8-H8Eeda2M<dg&nK{y>NE{5Y|oFo%l(z
z$qFG1N3>S1uCCZ1jjgTw9fS*S8th^G+xEoN<ofJW)bmzSyt?wTWq at CyahP~k`~DSn
zNyvJUWI@=U+a+Uxg^vdgby?F5cPP?1 at 4%ZS-5NuL@}!q8+zGKFU|%)wuNwHT7sIE`
zFm<LXVTgwXW8)w$It*}b$>$<P?%Ksqu-C)KdOh*!+P$y$_2;6pP&kAOH9*EGxw63|
zwmKzCf`58 at o`UU{Aq`fDiRC*?!ST}XlqJjg0R2M`*q$Hh@;MQ2T*H9pSj01L at G1N|
zxG}{?ZVRsbS03c$SIwS55r%;as?I*|=6M=(N&25mz7X`vfJfxUhk5p=kRU^-noB~?
z9_2jD8oQib*i<X13!nCJ7;6oT^1YG#ZsAVVa1a8U5Z$mj{bY0>O#=qcP1!?62)*yo
z)gG*0v=zq`U|kzZc_5?gkH5%2)3-|DdSWU7v8EjR&^}?H02^YShOlFISd#4*{Cw1}
zWCP=5!`%QXp!K_U3FTnf$@CZ<Jl~G^PpXzt<}Os+kDCQFU-f=-aW~*cS8SaLT+$zw
zJNRh+U at IFp&D7WX at r`#uGe!tW at TKL^1}||u&WsYSdVK at 0+U_d4i>g(09FZ&~vs$g5
z^ur)~Lg_Jz4C44<W+dU&4doM$*qa)0&Zq?9JR=pw3S%CnE9upT<Q>z}*(Kj&Fn)pS
zhTQ)uvyy<TO!gn4I|nFVULCO30<<#_WQW};wY7!-$yOMT4w2cn>RmdnX|Krq!i#su
z-=QPR<!W6j=}q=7(GMvWj-OG&>w!km9ZLZnNbqiMy%?Qk&cXY0%E?=a*suCpm(Y!)
zPdKi|>5 at K}6mVMgL{YED6jv6P<iw8Ke(sHly&6Xsy?ZYlr*bCO$JIvc7n~Wv++35c
z{EhE=gakwVR>))+MuB$rfk2wBsGP=S4B_7sQXzJj0%r0+ry38Q1oc-Tc&polB)(IK
z`^!roVRoh?qlKTcl)UR!E+mVY1Hn(k36^BZX~NbG45hrSS$^sjr;uls>y?DCMumBn
zXfGJfGBG&}Y+Dtc4ZXDEx7c7ZW at e<RW`2)IwtZsP$4gP#qU)IDK|$W~Yl;8M98BT2
z3a?un4WT)wIXj~-5+{AoPV61ruI at K60=ylVzF(%&|FZOU$x1w&OqP^3TJ- at k!l+;D
zlcf?C%SI}JZ0*I`NAzG?`U{;x=l<EW>R&18PZ#NAnhm+EsaT<{)fFZiYp4WV=Ko~S
z)_XTor~&$}cz^q>BNKpiq{6h{ASvpfv%db!;x?10Vx|Oba+2AHy3r;IJTjk|{W9rf
z$V7+bl*hyK8l{%*h0))8oEQcPCqakjpbc+4OSb%wea=nG{OI&J1^n47e at g}B{>b<#
z<^KE6P=~7(;tJ7*<$5;3YO(r}Cv4Gr@^w$cU at Ey6w?VYN#<R at n=9Dt^RG##3^s7OU
z|IMpj^#0Mq!@~>ss<P~qhjm&rnix{P at d%H}@`iRHG8?ifSdbh;e3K)YDB?dNT8*O{
z^~wGFHlyfV*Ec8qpQDsrV%-$J1FR<yf!0jphFdREU+LDu)YrSEr&oIVt`ytma>Q9o
zKiHX_Vv3%xL)gabM=7iLDzDTXKRbp(UET$-(GPOXSYmKvRVUDcZgMNtGl1B&@x7zm
zecp!W<bjFIsMs)-vWVYbAl=^dLBsBWS{<u|3)1^&<r8}yT}JWOc80oRWhSUI$|vS>
zFO)?HoMWzG_Ygk!oR?yoUv?7jyAhBhZlA>)*xUo22>;tNF34WUx(XNbqN(t3xyp>3
z2Y+l1v+~;*4IfDm?-6(mtGoY0ddcoPXlhLeU6}g>!aEd_1Fu(9gII4cV(oq*t2cal
z{HcZFe*enf>|fUQO$a_Y&st5tq*KGvzbM8RF>8sgdPsVgDvaCt>^;2 at wY(2X`XL>4
z`b?XLD!4oT!xK~X-da}tHY)6?23ObD&8#xt3d$<IAP}jiR5 at 8$#L^B()`g$}fByc#
z7yV2fQi58_8fH8TCx_VWW8Mo~Xq~#r_*}>%4^Z}8BfXML|8;iD6^6n<rL3{L4(>=y
za9YF=v2R`#8A0EHaK;eT7!f_jFy4tvH0I@<06rP%bZc at +Nr~ddR%zBybBRdGz^Rqj
z%`eiCZ}uxL{2!e~b&d(@%XVxaT{QiD at Z6;_E>=AcPQx{+dBO-yx@>$?JZ~!vXnsag
zrR?zCWOG5Nvc&KV6Dn)mCR6<dz28w$JCT5UZ-`Yte8j8efReh8<(BVZbV8V>cq<W+
zfmmAFTg{Od)A~jy(+GqzeJ??m7rV3_l<Y=@G0&K3y?4_j`1ixlnm&WraXVHSFKq>+
z{#!O1(GOu?$xQHRZ}1adJU4Ltq*RC-^mKQM`N9k?TJLK0cK7v_HQu)#e59Uh-_qd-
z4dIJJX5}=#sGiCI+e>HoYqXroQaWzZjUpn>|DpNnQ`+D;1)%5mX?aD(jlq<Xb`LoT
zk_V=KSnyLy+fl7ks}fb^Hi@{<a$MXXeP_iDa7>SCo=@YTh{~uO2)k0GAr)p{L63 at b
zEJ<4sb_c-EEMLmLxm5K3ly~Oek*EtjNcS5%b$iwSvaH^N-Hg*2*~Fj;tCX at O7*j3%
z`$}S1J)?~sKB&R#-n2Od{!{>7{I;q8|15wLf6no}bF9(xn7B{Oi^L+}n+bWbl(k{Z
zf=$az>w3MbK+uf9wy`#V_YmM&tN$4$I?P!pjSYLgMZlgZmFC?rcrZqzFhICq<&TA&
zPS`dye3j)4TYraoX|3l>^mH?kqNjGBSiSaywo--?+4hGXZ0k(32 at FiIZukR$z|LCp
zN`7xU_gjtg0jAL at IbGcQ_0<-B>TK5eZf>0~OS5V9p1*OyE(vY?JkT6KlG1;N4$h7L
ze-w4jtA#$7x0TkN##PI3W at h4QxkT#I2(}wh!fqC_la3zac5p&iIW8FEn2{*~JVxH=
zu9eQ?z at nB^e<!`o_JcC#*yIoOc6kJ$Z(N1R&Y6_;Wy2%@>1MzoDL}Q8BK1gE0sqn`
zTEXeQ?n;>;O9DMdw>2i{tw7DETuLhna>h{^X8`|r6;BoE>Y)Kb)%7&Kx@(Q at XM_pt
zYBbNn`N)weNJ{>Aei1m~LGAsMU&s74_URZi?FK7Pqn1(WXCz1GNc4&@Z8tpA^y<~5
zWlc69>~N?)%#FLDWVqFtL?dZNV~0bmp<B9w5t#m&YeBF6MDMjii)#IX<8 at pV9~M7F
z$Jm82C`;wX7Iyc`<YMb|m6IE$w=IZ)n!Jp|dNFt{-#e07G;|6RFCF9RA^M&*kf2l0
zW9A@=Y)khimE}$5YxG_ at R2jk1gohw4!C$SECw|k46n;n!)BIco+OK|s>K>h8U{so%
zMM at cjtt9l)EKjYxQO6NCu>`<peBC8pivJVn&-%P<@H0%Jv??U9-jC7bTKu6-{ra5S
zx<OJ{@Y4FlP`XnUXGhNI{11G%8PBIVXo_GXJys9I`gh3HIL<HbQklT7d*%u?f0c(-
z(8dZncbz?@O2R($rY-?1+-po at m=BKUP=%S()gz(xmbtXsO at wsj$n|j at G>#nJgt?}b
z#vY9_!eB)MAx_n4gBJ_!p;hZH#^>bc>oxss?!P9)kg+m?=mgsbG8rR-s5w}WlPcf?
zuj4mq^t6Dg9QN2}atB-&=(u(<iQ4v0Gl;hP^)Z_omi8|PiVb?q2^6L7oA>X=+DlhD
zu{E9nyr1CfUEL9Vli{^;ZT+_pgBtK*GUgl4BSiKHvT|+FVbr(ydHR{C+2sfwpKbOa
zdQbq{8;N%lhJH%F`0obV5(cb$!&V*QnfX#0Gd5EElGwVWMD=9#`^LY=wXSmYJF?n1
z%n10Q%94Xmueg1x30m@%dqcPJ{*KrSj}QXvc;>hUQvO<1Sw9(a#pQW7(!1YN6(v%i
zed=6PqeT&iQHoARn?sjZo12?Ak0;a`S^uf35`TA_Ujdc7yO}HACO5D*h86$)oX@#o
zj!q*Ft^SR1b85=u$$^HmEq@;$yX8#J%X7%^X0Ai~^0V!1Td0>PoPdnM;=Nj8fAuP}
z<^5 at CX|a92Y$ehgyT`o~*zCy4%>0WhueKQ{#jlwaNf{c at AK31lAMw;C!&Qr;dv%E?
zexA2&!|}r0w)u`coe=%!0T<DiQEv6?)<1`%D2YZJ?CISi2&)9aEsE<96o*J;20xVy
zpnB>fI^)x*U)2gs(l0bdUyYgYB}T8`=6wD$LY}>5;q4%Wtsd01GnM2UzY1kN8r{SA
zikr<CQ6r%|+{ti#gE0FY^1Zt#031X9oPX><oua_;0a9HZ<?2$tT%%rq7k8z)45xn6
zDmh@%HYrIU-v8(f&s+VyZZ|Bw*LF+bjTl=0SbN7$<#&`umcv1KTffg;(B3}ih3vGN
z!@TqNR!1u^Q at yPgFsqO>zvKkfzDKh5(!a0>D#h!z3K6}TT7_X%4qdxHxE63m9bgg8
zN%`stD?Q-RnA?Yc>XYw>ia{%Bw%jmjHbLPcc<_ucJ?!Aa#HX*YP1YO8H`a_zPTDq#
z45S!K91%!7Q~?J%h+X9;cVXkxL at vfg>hHq#{^@)ZU1o%t`Hf!0s8R_rz*t^<Pzc-#
z6r%E}284*?rK!Zxu?bL6$XoYHAaT1I-_iGw-i}{5>p-c2cP5Q<;i<;DGc4gqXiFvB
ztszkdsddZ at m^P`H3lI?xV%-b99J&4ah2Pt8J`{BtP>;+70?7$FXoq1m9@&@ZT(mN=
zY%Z}eq5}y_JL^TAWj3;};gde#?|B8uEgC5`{?!mR0sb63aoyok5V8JG%py&8xwRMm
zJF;bSdm#qF1 at s@VgxJ+)eY|NLFJ_my4jdg=@HaEzCc{TbnlXCSv9x77k6yw`nfHa&
zSM2K;TD9~J>Yr2eoKNHde<j(}0;@|DWf^%ym*L3*8u<B1eHRey20T()ykL=vlrk>G
z`T^{ySx3O$>S0Q28-dxUis#}nnmNzAO~eKhxrUh1rwu`4V)BlmYBVR(Swmakce;q&
zjsIxU&9nQ1KG}UY(;2HN;xStadS!nmbXN@^H6$(yu{ny#-Oip}Rm_J8&pRw%W}NBT
z63eXV4wZ?+<QF&)TfuG6dtn#p$sh#haj>(?>57{%!SQa08diGSx*ADGCIopYqrO>F
zHqv_oV|DtqtMZM`Otlhq*<-0n&uVCywrX#{DiR!E2zDeA@~(7Va6ut}sg`PSckj#Q
zjuQv(sU{(9x<5Q)EOzAG(6;hdP!$jQDKAaX7G#=QO)az7lMJz at +hj`@c{%;Q#;amH
zcf at EjMc=FPkZlArzhtgFriE~0B%%D%6DZ<mbt*yfO^>1xmQeDuec{J;OGmtoL^$ba
zLOBc|3hY)^^vwuPt6CQ$uHeW$VEwE!*x2C#8jX1UikrBgbO%|wpoFh;XBt(F^U+Jg
zAA>6}#ji%k5^SY5by>z0W#S>=qtMk}BC at hpR--kX6S0{h8?+fmnI*jm92I&EGMYB>
zzf9XqLcjZ_xI|l1{j~Sph5}oz73-j&bcWNF-z>P&UUhrTi>P9=Hh;qk8o0<J{eS&+
zE)q6!Wqy8TgXThypbo9_An|QF%&+Xzoxupj!Ez<v!6v#tU#Vy#7IhAPUx2e)azR+_
z at 7QrNGc}<r`ZK{iO8%R4Up=9V^JMtq7jY`WsvnK{$v7{W#KI%X!+|oid}Y2itnxwG
z5hVCX2m)6Qg*YZXhIK66+TH9Y+Fmx0T`<&d)3MoM$GIdiKF`v^LvZ&&zt%VH^#lfX
z^!M3!qI{2}Rh_-9BH>N68 at pf50OBidH8M^#WDX0jBmqE at ZaJP54N9XOZdsYx%mcn_
zEqEA!Pt#x_8q>RkCQ4R*-k{^m7tzqz7z5jHc0Rf<e#P>b6es2>_V)g0ACyS)=&81i
zKC;MG*zi~BFFI}gKGWD^C3nVobYwVOhzIh=+(;MuK9PC(%4PP4b}v9uUXNF7E>uM@
zf+{BLn~dd*D1}L}NV$rL(A2SHRWG_<pJxPT at j^QIm0S$5le7G4nUPW9GHZgWAZ-2Q
zlvs)_>MNtQ@;f9mccp*(s0yrS2eM_aZK;AtaVFO|Ac?&d9Y05VC6#}w2~H$Dq`X_4
zboJ}@-gX)ixpw?#;F}%7Rcu6y!Uh8mnhA*iU~Y%DEpC5_etASryxG>=ygSZ6CPJGx
z^$OZHuL#dOg^+N^&ziZXEP79DU!wJBTCmix38H?aqlE&=K}X$1Kiq`ZI%wufKf%DO
z&G9>U8kjmY-2)Y*tM_3E^g{BHD;Szin at 0aNa=W$Mk;PS!FQjG^^@?M5;#A`3si~3+
zFDRlnmLLlrGoG5C at I@hRzcMj~27C}4VHVvARdN~QTgou7T&~I+y!KB42GVwo9(#&(
zvPc&h>|I7Zc%eho>7p?~eNh_Go0gkhnT{l=@v*V&r^1F)l3REJi6H*mEx2i!us^T0
z*9Rd+CEC|aYflf3P+sZi-Vp^`<}(k2i<fKm8ubNj<aDfiehO&Ok)MjPT&;&GrUeMR
z6;My1q(?(pcqoLEmrE%0;2m`(XZ4ftgDT){aSM)f7P_saM$r2{sar`u?7>FOa?aD!
z*H=1NjbgvW>411;h6Np`^?y9QWmJ^!_dTqLgn&p2NC*-VLx;4|jWo;v(%s!C-AKyN
zA<Ya8GL&>k=MY1e4BgE$e!jo|v(~(rm$T-+uXCNV_da`1H>szffcz9!JD0qLzz7><
zmQ^oFrcW2EJAp~R(?6!)z1xD{TYP{FY&=loHzsu~$NdkF`vSdvdD+64WIf&Wu<uWk
zT_Mchpewij@$giOucXBl1GLv4Bup;^sHR7g)LDvrI#h`cbiDc{EGO^PNE4ZWnfY9s
zs*80*U- at +w5zG;u6%Ee(cE at kRqH_*u8_<*6T%ryQ^A&9SwwE(Q>D}u(*D3}e#?7fY
zNhM$oi&J|Wn6*o8DKen!QqGn$<Z2oxsKzCN2sL-L@)FN6e{gpxms{HjYr=9+2z!G*
z`f2u~s9uAx|5=PK3X(>n3 at d!vTsx at OD{d{`(PE{*bNUh2v|0tmdI${x$%?jW$JEx5
zeWjHM<{y{5<&dAdcvdYGj15xJRO&aOU8l at A`DXYb3|g3jb$M|4CScR3bvoNFHuhS$
zG6{Yv!NmOSF)2*-Vu$M`Hv;5;_`5hec(Wt+q+9-O-_-yciaX<-Rn7a at Z<-{ZNkp#G
zu*b9h>}%{K4!|7H`U<sTt;`Y`aA4NpWop>ZjA7LEzDrQ_Fw^dX_bA^FienF{gXxEh
z%W at bL_BWWb%VJ|F=HJt}y-XjqoK|Min#Mc2Nu3{cMJ1rOI2eZI833ljXhq!klyp6-
zQ0%tr(9^<TYc!eHiJ$-r4_zjL)g{V`V3<>WVuy&y6B$u5pPc?@lCv6eEX~Fc`mtlx
z=x26yv7zaNJ~`Dn!S;O)Z32DbqbLV)eN}>t5aM^<lW3X!KSQcRGf$Q#&*tes-AX7w
z?JN`aCks4vLrV(G3;Wfsc4=;eYd}eKgYE{|yk*B7Jw<|%Ea6dB$rm8g?GM&t;A)9P
zY-Gy;|ErT=!xAu7J#p%lolbAoc{5;hDB<gj828Ht`<*Fu)m%}O-|6Mn1x->G{Zr})
zRxBea1f40JdDVUt`WtM(2PPbc*ok2 at o9!XDYF*r90M-n^z&<}O*xPL}>zkymfB=g*
z^ZkMb&f*7I7Bvyqsoh0Uli+P0C+Mb$U8WJ}YbQ4Jb+AET?fM%1=z|n}mDpm8DF4|I
z&M?Zis(AP#!sU{2w`;`4eQBl1 at 2WcCD1a0;`xAe*ZNdGIewv6}WxN6Szi#c(@Y46h
zpS$b9N{zg$%Ns%U`gIoER<M}zkskNM<*rEa#2Jj_vrAkd7f&c~LGkBF2`Uif`L<cE
zdBopCSW64#@A!y7EcM9;T5r0oezKr$y&u)@j(<G&-m8}E>yvg#>KuN|TQGwgke2SJ
zB;Nhq>;I5uVW?|P^1$o-?YY0Y`w%viHazpuDH%`8_8R|s$TKL5^i_c9uvE1%7bY1z
zbDW!8U_rK*v4(x68OJ*P>-A_DC_P8nndVn<f}#qc##_5Bsjd$SoZ0$Y6iSRq|A`1L
zXQpkYRVm&|Ipj5^yf8+n+ooFZoDG at rcYSAbj!D#LkU`Wt^#soj%->f*C=)1-&=*j)
zmFELymu3w*FOHa^pS>j*T01e at bSD~8iW-dScWK%qqWwvt940CEZD7km(?m}G?S2i?
zMzM1qNJS#<**ijlX&SDFd$8hV=iR=lZ^xVZ-185D;vx+92~KT1Zq^45Xvi?Rsm(T!
zU+s(brW0M_BBNuzij}IWDkfu{hlq;aAB4j!4fFylKgjJ->0tCiZP at Og3~*^y=dx<K
zG}m$yAZdk*ziq<d&XxQ&x;6FG1vRUpn2g+KW-py2A}SU)zb27AiFl=hG4=6L&=)sn
zO`vJamO6rnN at r#`oIeD!J9<>=b}YBw!Y$6&nVu!n*m``0J|2}tgobi<&YraGIb<3?
zzQr3Jg>$Z|@z=TCB^6C=jeTHmh^LmeS^MSZ(EUWa-+j-jzPV1+d2hf{&|_F?2*J(-
zVGj$spcUgzXKK<Sf5YfTO`nn=^I*@u;wn!6YY~b1iAfki98BE7BQXZu22ESCzE6}>
z-x;}YF1(__JcUG|Kdlb-w!HWC^}T=AsH&t;pRjZE5JF}iJ)Fb`s=SDN%9IA+K0v&p
zg)u^7KtkjDlAZ-uo(=fqpyr35g1T2hObaH}WOY%98zn!sNZj=_d;1Lgg#Ie;Q#;+X
zp=i?Z-jm^`Pr_cRe6Lk!Hpbv=(J$f#9I{`tnK{za_lL2q9ZT|s(8tf>{i(fkVeEHk
zP1i|XWM%TF7LLc$`c6D1SJ=KcHHYpgcw+hwkw)SjOk62#W<JrD@)Uh0vqmTRQ!xBP
z*Lxs=uM<j2znG}w@$D72xTQ!AN|XVW%nsi2AzZ$?WbmUD=MBh^wx3X?pDwk_GkWv1
zF9`h>LdR#CLrEH6-%Q9KyK$?(<KEX>ZQQnuUD3B>=xqJvQ@*JKN#v_Xi1dYL)gj#n
zM3EBjVzskhXUm%By!g0;N}Meq<oiPudw05T3MDxc5T(WopJ*M)4x;BGU}Z;N$muuj
zySMx?h4xx2-sGvwknYZkJh!Pj(U<w4Y=SW#Zr^uK$mv(~mSJp$KqJF`>>QKh>u>ZU
z1QQJ at 9N*!t$mzpNv)cF=0a_i`eq7fYU~30(1rlnbRJy9VL~no7f9aj1IQwOt7%^Vm
z%{d4{$@X8m9;UwMH%3{<usqQgG2Y9nnxLrn%M;`sNU)Y?q6jeOfiBV~?exKQOMYi$
zf^O<mj`NJ|2y5glasAlD1R|*#L}~>}yVHsu+9CsEAfN*=5%3QcG@>8(AyyxH|A)*l
z@>{#fX!QR~3%RQ?=%u0*4k#^SI%59*Tx>h>S!P(8wSL;k06Qb09nohBK_h4o?FaT>
zU`od~PjlX(qbSiW7qPw+r+lNGc04}FowT26j%WcRB at F|9$gz8(b)?B_9`ZLJHZu2B
z^eGV?PdpTDJ>-B-y+-ryqmpoyZ!1yhS>k%z)~UC6Wkf=SMff=e*C&ZTB9(T!2U5Lv
z`NZ6B8x#ZTT7L`yR09$q0z<SGEkINz-|4S0#n(Jd>oP)u-!A4ey*h-26<)@Ij5N0f
z+OP<%hh2_8dVeha{PCkg{cpXdY4QqaN{0x}D9Q6g`sBA{oMv80lBU>espTBH;sF9l
z)4RBJS%8l1imbTkXF$yD>^(c;)Q=;xdON>+MH=M2!cCJ1yI&S5ql<`%1<)lM(a|0;
z1qdHD+Ez9bqRa#+>l|7m=Zbs7RIGb at K73$RrG4%RXc?Foa9sc&y4LqV+aY-KqbZMD
z^uu>_FY!Dx%F4F!6NaAYDFvuCED916Heh1#ZQ?NVUp*oFpSJ-~68Q_4uu_dNZtI1j
zgv^c$aJ6Z3t0tlMitBsq!<GZrm)#M at eC+(`NTW$<Pklm?j>EdrckP(KPk$si at 5MgI
z;<}I0HMDNA0kSAf;<MxtD847+b&xl!BY~5!ZgH9{SHi483@=6B7#BNw;3COeL#J=q
z%K`rWq7hG3P-Rs542eWOE$iyI^AoE?1yz0OW2BAOHW)T35%u{c`!04zn>=BSPFUJ$
zO}jVc5+oHwKmJ{s&?w*!O3?f at a05PaXQP<jT)T}<&ij2kb~W4Yktm0}=3PJt>)`=~
z7nj$QZ#zy&|F&FzTV`WEla&ts)ZmlsoR-Q_7musg1gadFp^V}9@#m?YxR!WkJxFVa
z>@(&vpr(yS`Ddv&Y6E=w;{ljHzUP2`go=i7!1c-irZtl$YdA+m^M^!|xNfzGh&-vj
z24ZK<&ZKAe!43tURgdC`#Q&R^-rJK7wz#CcB_biDJrLk30Z1x0KXmS!7=nvU9$r1h
zTCSjkZfN~3b`td7i_O*D^xHFOmm;P_wQ(@kXwtD<MVmr#-<6~5p}z?X|3LwcHr%!P
z?3mA6NV(>=UmQmYwy8)RDO3-&H@$Qc6~y_{<|nvP<U*PjKLECbqI0DZuxc(}i;Zyg
ziM_>)a3pk2w8-ubNQ(lx^U+SE3V3u3RTo4 at HW<lyZz}yny(lz=beYi!1NbKTi|*@p
z9<pH)kl<^SN&p3&(PWk22zk>p&W-1l|Mmjv5z{jF36mx`&35(-h0r&=r=pi3Ez1Y>
zQ1aUUt`b_q26=KaQMETMq$qT&)KuKqJjL^URV0^+)8SXt3MenzPPJsJ<XH0^KmA@|
zv at +<?5Xo(HZdO~j;Hulk+gDolEzZZ}9&08`Z(gzIaFjH?)&V9DiHil*{;sSM?e8A-
zZ4}{wXeD)`a`*^)yOii?4lRTE^kPG;Xvn+Dul(Y(yy>Vxm`KACH-@`~Z(mT>X4e37
zRzP0gEo3V(OkHV<Si%W3m-61Vl1$j~=wsi+7c2e at yq^$6Dt~)FW{lP-nXk^V94DTD
z(Wytu$TaaE!0pk-5+aKmb<%`wJ5NR#^-ga7Q+~{5c!ASYSNq0l7NhNf%A9-9p4C<3
zz=zwIM%rRQHew&__jr#ZR~Xlu#LxOA*bf_HpKO~^n9P^Q at nrKX*P)@!6Du5%Cx$I)
zhbmhIVBC^77tX#pj>bmq%%7SW^q=1XSVG+~+j~Ud+Ic_Xlukq at UL{qdkYv;K?G2+G
zbir2jY@$4;pv-F8<%E-=A;mQ&6AeGo;mJ at _Ni~|sygI(scCH5NI)!RpoDOVeUi$Cw
zMBh(sbEmyaiEc6aW*!MQsC%WQ4V2{&>%gBOc53EQq*)Qn(%e`y<hX0l7%^^#Zk9c>
zYf-adMxRTMT|0Bx(ea6jlJaZ-2f*7l8usJYNdtX^_mu}{y-rkNaciW7wlcR7UCzRw
z+k5 at k)#bTVkG}4Xmh)4{`F^NX4jF4vlcEuo+q^FX+U06*n at x3TB1d<`%we`gg&ESM
z6$5w^K!`2M?{Ti|jWYQktLctloXg=`HKXh|Zp#i+OD!5fk(m8&>hNWmfQ!PWj%>V`
zQp?sFfBgP+UA;(UMT;6T>xep98EAzshX>cxCvAy8*%~tDm0QgSzLjP4Q}$$aJ0-5K
zY$eAFgle6FtFG at yofgnPsBz`pyZ465NW){7o?0e00BDD<bW5<W{5YE5NT{@VGDVUr
zz41}0x~CNHN3bwi$Hex;=~tYQJAeqv4}o}a18gR5Y$_i64hc1S>(ovDz<K%1`{2yC
z#Vp`F>#bOCI|KwRy<MLjxv^ok(q*amT9VNJP<yLZq;@uQJJyxBUCgTYisr!T>+?Eo
z!6W7xi??!-;XGUs;ay10IC;&*W8<2j$2#uU-~uYCzZ5 at diSau=s8eI%cW}3CMUH`u
zYMS;l$GFzt8|W4L?+n=V2=FIXc$t|~VG-dc_ZV|MNu+d4jIsC7N5$)Lw~;LP9o~^L
z5=BZAVgm^FlqZtrD5?1cvuRETqa1ss#fobWRI)%#@?-^s+vus=$&ks7$0HaCqD7ty
z6`k_SW(LbOd$=oc8+uVSkofl2X|oAs)x#tuX=qu{5YWDj_`j3klfahtMQ$v0oAN20
zSHOtE$|^BiwXT!e3uq`S5`FQi at HlJBdo00ub@n)NpTVnA+O-PXDSutUom3d*WNHo>
zw%}R$mbRS`V4bNI*1Mn at LKbQE&t#a_RYh++)mM5v)vPnBE|(n_QoJB7Ym7?K{w&AP
zuy&c&B~dl%sUu4A%!w=Us^_({Gb1;4hN7gCiTvBxMUK<n(?LoqCg+1N!3%R0Uprj+
zjoOK$+npV&uRrO;)&x<J&X=PII^7t+oz0r??NC+GP~ZiUS2gB=c0ln!dl at WGEwgJ-
zaE>?IF~+Hi_1KTPz&g;aR_Uqsh(1ru*qGmk$?9dlx=NB)1hC~cE021YdJ&<bb5e$`
z=DH&&=#qtY at 2IQ3`YrYJNVn$&jq*hfLJ;&_O`(>!rQRHNRp1COZeOA^#x4nu{1t7c
zL-RZ3e0l<|@zIe6^aaN6g-8y-rJZ6@$TtHEuJH+3=h3WQRNIBA>a#}%wD9-mpx5yQ
zhNb!8FQJW+#}<O>ntzJ?dCg&n`}VsE9bkAz#T2&xfB1^Lj!t~GQJ5?$!gx2Gk#T`2
z=01Zbo$j^a`$#*^rR7g15;33c-8mhpZE*s6$cF at b+8n!_)-tsF!fS{7pBFfb at Hb3Y
zkq})!Zk2NLXO5#dnzwT}ak**Le1MK>hNpm%7bfT<7DO|#7tR9F%d(3Dy2XFrQQ<G7
zrrB<y!HB53ZZiAnd50Pp4m_OOkEGtGwfSAUynQ_kFOq(ST>+p}_Yu<if?(#|4BB`u
z6+yu2?HGVqii at Kf{xYbNwQk~qaWHI^{nzcL+paYnd at Wg#`MjG+m>aqw?D`JLc*XZ}
z;-Df-l^i(J`RU|ZdnD+0YkT{05^Ol(*z7bnF$G4qI#?epPKvgi@`~<_jS&3e>l+VQ
z>7EdF#*AR^?5 at YYrK|^=>@83K_K{N8vSwSsY0+n<z9L>Y-SDrXFCumJs<~Fa(gsP@
z1SQHw=F`(XD$>(!s!>Z}zrdG65BW&gKsE>OH40`TL+fAg60m@!8kXJId5_(<-MR-N
zbxci}vRP*R<x`81VwWe)0kem&wm+6!w(Lgx#wfpqxM*r224{`*>ZWO>a^<q7av(3L
z(xU*l=Ws-nI_t>sG at FDViTAknbY9c-Z{v?#pC`<C_q*kl2iHV at 1E*kwiB`pq5`U80
z91v$d0B0I~(1ATSQ6dTxyj?yCtZ49Bd9MulDuWqvN8Ric?o5XIa7<Rc`;7ZaWR6GQ
z7du)G1-9&-vT5(~6~{Pi>sz`#ZwxwT4lWnZJdQ7lCm}jN%Q)$06e8Vtu_anuBxLEz
zlOiqJ*ASAn=kPc0lnuH~e>w`Uw#8R2$hWn66AhnNBz}Zf699{Jq9ia!AdzEx5&b*_
z>0kV&+!ta`mXsfR1`@cAdHDnXpB8|f{~KN`&-Et|^*6>}AiO8`@=@+t8A(Y=t?(+_
z+IPI`HgC|~C(jb=`WF`uqww95VgiYEPQVMBoF0 at upNmg^fb)+S7Jj5No(EgdO@;i>
zgXx0o)>a$Nsu&uXINqbnZDKnorZW!UtIHZhsP1==x{lSc>}xME<(21tu<nDgH#qoy
z$GfmcX#i(ctZmBCH2RI!-Y)wfA+6zgJ at fvlkCTfHbE??J#@+yaP_a#{?~|!r)nbDf
zt7!LVDZL<ojOO2NK;AP^m+bSm<y}zB_^MxJeA=kw3qyGFbVIpriX(+g(|Fy%)aaq1
za^r53!$$p_HPH|MBd}mh*N2!NH9W2 at 962J<DwCGIbm}EIg+@%XwXJZIon*O}K*ups
zn@(3bYFRO!9!ds at dqcr)CMG6fY$Jj<&tX|a80)<Pq&&U`S6cGfCqr$9T&@y7W63RK
zWvb~?6mcxhiNJ<T2F>zDkxG_TB3i9GMSQX*G6osdg=Nqavy^@Q0pz39DX}Cx^c8H2
zoEm7M$XODi-qS=J6#L}_3^wyOm2EO`9kzswQ%nbr&w>=`vKW7=Y1PUcax4+myccgq
zugCayDMlQ-?qwm~S$xv6gVCQ?`g~^iJZxz2E?Iry#h~UF&Jx>C3Ss5$W$`i7uVTL~
zhA2&J97dd<ej--?Y3OmK;|@<6ulN5zl=bTk#WS$d*>&5pLz>CcvYPsVbA$S+Vp|7!
zwdlfI#&PIO;iWf at wxyzBeacLzD{K6_OjObwzA`1P02ghzy+!9ikPb5|l-D#o0@`F!
zTs&_uod*5Fm&&}hf^=|M($VS(3aiIfeK*6q3z}SNrq(xaXWD~Gjj-f}ZyQtgqCSe?
zG2H0T5oQ897upbUzL2M{CC>~6d)@uFZWp43w~K3Z5Z6LHbnnywwPUul+UBFB={`O_
zH_1v+)KPiYnhJPXHOr_<kM(&wl}qY)Hp8*4={1f at z;~-`Lav18`E&|s>uShQ^*eK}
z6NKk7;uM(hPCsFeURmNM_Kkpt7-#I;(4N=F#lEVM>eVH31&MNkg1uN!98;`yi{W_^
za8+9AYSF~Bnvew=fWCT}+724xJRusgNfO8`inuNOtV9rriBG-9yz*kZLJmQJ1l!_?
znX4~^E75>KjSl+;KfU}ApbRrX_Q^t53BSRSyYa)8(-FfWkz)_o<bpFe at _V#32C^)D
zF5O*X%LFW+ErdMzs9Bp%rXkFadh2`z^kcom15K1dqp`VI(sbJNGR>m(IEXi|6woU$
zN|mZpa>ZEF9IKn)J%S_QdGu<9T+3ewnP_ZK5z#u%W<_y6r#nw`X_Ld$HQ0=_gMA(~
zO_`sjo^s={ZsIq|myT9OrK3;2)L~_-y&7Y*{?i`S`w4A@^W{3H;fz|IUH0)oVHR_z
zzECl>s83zF%<BqPxJGr&eN$`OV3P=ti0Xdi#&2~sE0{v~&pWlLqL1xH%XBBnU$Vz;
z$Z5bIbaD6Hu at 5MM%A*)nB^QDL_!6NcB3(?7yerwOL|0b77L#Jjq6<=wU7>XniIVcM
z<@tdO`JZCE9)g5-382Cqt+A^$d|_^sbWgi?+8w~?X817v(=KE_?Scpt<@BlR&Yxr;
zbVjv5uYt)!v^alZy)XW<LX43^`LWm1TX^m>{1nXmm2{L5*P=|3+zw?Mbe8KlfDeN+
zJm?BKR$G at a>*USaJ3oKA3&hpE-6wh`l+px at 0FVi@cdjvF)G1FW*Ft5Y<?*S!-#)Jp
zi@;bXyf0cckM<tKx4~cun4wqX)(<&*upimSonZ>_DBoWcc|W{k;*eFJ<_l at 48VC<l
z{Y1*-p=$-MNpHx?T39;$cZGme200YwVeXqSXQIq2y>eC$a>Y)VD)dctk2W433(r&S
znVLi7lg}g9|DM9jb#rAikpe`tmRvg3YeC)~A-ZR5CCbp^AQ2)8#&9_FTfke=gjfNK
zYSbc-i}bnh<f&?2 at Q6J2h6dIreCian{gMv~W<G&qo at zu{<v_=hmcp?~kpd<W{T)9`
zKi7A=649aL?Zl?K8y7K$_q6JnAfneqLxk9mOYY;X0RBW81klz1yH%%JIol4Ya&4ZV
za>GQrocsi{JmdL;7^~Jyt|dr9-KDG9BQz&nxM`gq{Y>=?93{-q?k%RF%D|I2tr at iQ
z3CiMhxYR1Tm%~Z<Y`zUXQ!;HXFTcj$g~mea<l_Sy86CakU4wiW!ro^bGBU8z0dVqk
zFt at WAw?bv~%u?KgPydcNfP^G|fT4o~t7MQVI5it<c86D`=YD52<ESKBirE7p_`sPG
z99ikEQEOVDsx+(3 at CO>&;cmYl7O611+&dM_{!Piwak``p<d6zqOSJa~wj45gJKNpt
zv&>@2{(`~gHERCeBW6)S?pc1uht5Q`5QGrk55OFB8H#bgQK%)7Hl0?03?3c&SG8I)
zO>u6PP;UE`yEdPu{*@e0kD<Y)o?bAPGTBk3#S6XaYM!x!K2(6>K at 5LF8aHh6u;6NC
zZOsJr#~lxxo$j!)G$8HD%Z)fIZNTzyO*fnytvjPWa|)Xx6(FsiginE#OposR^U#+H
znr8}X^=#LsdB8lnn}-o6>!-aVq$ZAwzp8@~d_P!zU~s%H)yy~HnsG=8`be7)HCwk8
z at u-ogYsZ&V2cbJZTSYF(mRhyd<#0BkxIH9a!e6k@)zK=otS*C@=^rEK7jDV at O)qm4
zEO2}AU_OxWPXWL86tG;u2bB$xFM8L3 at UX;Uli#pH6$V at t2|tk-Ypm(vto`P*Dm+da
zF~46pL7UEX?>D~DSK9UUG}NCAKR>$}k_)Tl;o{02&Z-g?7y$mA)Ewv$30{S%iOOlf
zfP at 9E$hB6_!=(dSC9yHKc6Z~(GR%${I~=zL3uU_EJ0rd3^ovn$3R{#s^-(XSj9(rE
zPPd2DU+{kl1mPRr<sQ^u>6)|N;?-x}wxZA{U- at Ey=jscCB>KS>jKi#U*9fcsPEH{u
zC=Bu3d>*%iVg{KtN^-{-uN at sS!kiQ<2GZzH#35iN;R%&uHZR}R?eH6`6=JX56&K|8
zhnh(G>|h15yiNIHmZ!b(tu8p=aKl^aQ_fb=<&J<!-fR<i%o{+-W}-S>jUKpX;{}-<
z((v-KtTK_#9`C{G4Z=9>)!}Kg7E=m=c``oh$u7&s9_2nD at tIjfry`=T$kXJ0OxAI5
zxPd^t at dk=TYUOjB2HyxcRNP)39zFz|42HP!D<p4hvR1RtZ+E|Oh*sRh2I*tivs>`=
z&4+uK8T#(mi{3k)H=yi8J$>dugn^>C&ML`~8H2>nD_E#Bn>^kf192}lDR>85-+k80
z at 3G(%Ul`H0O}6C6KKqn8*1*3?th|v>vb!35Fzi7 at j9J?KWfq#3I7pcE-9fhG5%M^e
ztiwN`fuS*LyfAW~A+)OvyV<9DYa)lVNuy8wj)TlttYB`pQ*6Cm@~npvo4*p`Z^c%s
z(&ANnsn*lLFBtud(OFbOl&C&#dUVuM2CL_P_xzt3 at c0`kYFpo8X~+mOL*jWP^GZEP
zT-tg*df^ZiMR`^7RfFB~@K68)pF>Q8arUZEs+gzN^|Sf-fcsA739djx2G_^-{kuCq
z)d0N?YT9K`rK(ia)4FQoF+XoQB13i?$xY~su%vC9JIg(Iz1{~r4;>MH#I{x!@*dh8
z&|F<mG}9~FE8t?KBzAMRWr&{>DaY)w=wq-0PjwHkYGF1&=ubIU7fiUH2MiA_2i)$r
z(yQ<_gYRrNSQsSx?|9M0!T4=neBP96h;B3mg_`Fx@!C{**nIGY0y@&s%gfvaK2B_&
zCsUS1gUu(y4Ug%sXk}o1w{J(HLOR-jtAmdN?w?bBhPH2hdpE*W13XpBpES`zg1n}9
zCvA*pwbB5d;>$gJ-i!(yEEq-$P0Gx1ana-MT75r9Z4hZ#?)yG_LpHHB2%CP at gmCJ*
z1NYgPZ-r-WSt5eW=_LcIHV2G*D$_6VpRk%kz%$YrR!G=rx<Vjm_5hjGzr7XkZwd)N
z=8m0Anr!818ua)!s~P`7s0e>}gOxP%g(z}48H=5KCvyxbHBN5svRP#{B;rl!ZdMoX
zb-Uk~6BWpIHebyQZzz9D+vYH(gq9&o6l)DLs2-c$RP~%;Ca5^8+fK^?JkDSBEu%!f
zOPAjJot2pxS96nHmM67<p>%W=0=Cs<NGu_Ff&zujU;&95_qfOn2S1C+<s}b)a?N<U
zKWSgl<t0ed-aqxHH*$i$ru`5Mo}r}EO<&O4NcF5#9k$?}j8BBynd|Jphvv1s5;>QH
zxs|DKY?}2nQk2#^m)fQKcQ2!!lHllm6nQo=It at gq7rk2J!9FhYL6=lt^ZMf-V6pG<
zTtNnw9Z3LyXPF6j)3vr6`E?%bRrMbxJe#~sL5B_0W6S`3U6CgHtGsHZ6PvxpwmQ}_
z&E{IZWxcwkHm&t=zU0JiI0i=mAE5<)rMy0Nm082vNXCRj-a|xlWAk>BaQ$@R>zW-#
zt3)RKNj$^;kMd^Wwzh-H2mia#3n^r6IrQXGxOaXyT$Vag1fR9XK4pxNS?^k-y0p<6
zDEa~x!H$jvzVCmUZRqG9s2?)YG;&24J^~&w7VOsQ6~>&Me=W(ai*HlRC!6E=dI<Vk
z%03xu06Q`8XK4ZA{dViJp5K%&Wd72h#N}405-_b54eu2n;9+eP5%r-))$H)j?=ICd
z^96QfH16X2J4zaML at R`Qx$cZ~F3lF-miTOBEg<K_vH}5TXIPoejWaZzJid>_LZ8t)
zmm3Q$im^f>KhG|m!mQKvKJMbZLL)A1=D<FDWHYHXd!$~|8{au?&SMlJYyf^|HhrHk
z>#3UgGv%6v?!<RKq(}*>|C~w5ORF*i9#Uz~rHtJMwBs=Xq^XXA*kw!!pBoH$)E3p5
zN(m{)Cl~I``+T=Ry5V%`(P?l7I6GHQ8asBBU$~&Y&7NB!tT?qA%V)P4;g^jLyH|A<
zH+RgS(unRokMjTlr{M-AH+{@cFF>_g6E|W#Ps%QM8yTzomuvgo9O$Xz>^tpsHMsqS
zwhxp{@M(wtyVQT05=KXJ at vi$KA&nkST{>XBWBAk}@ZjE2lWonzAq}P5hzE~!3lLaG
z;#aNQ`u51j^^6xD_pK?;tjNyh=t70gC|Y8Pw19VmtRVToqm_;Wpv06MosNtE&htmZ
zb;}-f302<4&R-<p7eJl8S<4I~k0KULqkLnX4xUE(DyWj{54o=U+sjKd<l38IxNuJB
z`JC3@`l!OV1ADIUx=0Fi(l1(jv9gFm`4sn);#dSwvNlOazwA};L--c%uzAl at 2;bhB
zsNa=S<Cet;Eme>EJ2yzC=`5Ie$98q+x7hLB8f9^@G!bWYKxeVfXZPz&GWAW&l$}YZ
zQX_+x%0wkKp(q5<B9;JBF{*5l2rJG@`bqyKN9gaQq@}`M{oiSi)OC|+dx<}b8|wF*
z);06BGxH3eJd%ikX^}A@=lt@)mX-DrFYWKsR}`uoxfX!#4(HVb&&sf*<QJ3AJskG5
z1w9ePTZSj#?>*LM^$dSRLFJ-52vE73v7B!uRYuHjKZ`Y*bHB1mn(<ME*?--96wd$Q
zC&*Ve8E;j$e;yr;kVf|9u at o(X4^D`LwC{LEkJf1HpR9SG!8lh5309Te0Ya=oU5YAY
zEz$Ek_f36=>Dn~iIvx+GWqEnI9Q~0s!0Nh({)@CP-kT}KekVn<pz5rbM?l*lR~2uI
zJZq9u%^?8l(pp=*xE{90E}<iUL<cw;#BKotK38Y;46dlP_WhdSS){v&`NA03-(+oI
z&oI^#=Za94%R7$8L$iL)$PJ3J#ny!*(p&s!gI}1X5!Ds>TMWu)|K-szLJ3-y`|OC$
zse^@#*>~+Rxmb46pBCdQQl*f_04fMm&{VkcpT}5)Y11da;)kmm&dpTn{Q?(<02W3p
zj$xH$y4-nRh8soVsd)tk09j`M+`s>N%=seU)_qB$6d~vPjG7dKW|w~Ui=cDDLhpUX
zUmkvTO}_g8kKlXivnv6XOl#s9$41!ki16XwRuNyR%sndcJBLKPWZ4~ctXxGJ(kCQK
zBY_1rao?XF#%g_NHa<NnuV3V0dhkF#`CEI*-!YkiIXQ#^QM$aWiNMxr)=z};jB9P*
zvPh_9tmV8g-0!Jf&tHi at VqRTOygpClfouC~M8uiMg7in_bp?LCOqk$&NFOu=)uFMj
zPad+R)rPIO=-26{-C3=_5oC;F>Ced?yMjXKomtwz^d69t;$r3tl(arus(R3XWrkGs
zJpdryqNb0~FCPTzkHfe=E!9vZpc-CMlWun|VRzCdNxhV}IQBYtUJ{4JV3>0~g7eVe
z_=j8p`R%z9>7$h!@c3hTmm&9LhMjm=up5`c-CUx{>8FDt?Bh}swP?j`*~mEXg5P(D
zpRLc737-aWmmunqoF-P;;s~s|Pyt^JN2i<vDsn<R9d+ at Sh!sjq@>$aHCCvha#l%V`
zu`1~8%EI_^2qzRZac6LPd(uX1VlM?>D!E=Bt#*n2n%P+Cr%5j}XKnyb!Q at FR%5P{1
zMs4CFB~I<o78c*XD-Hadkroa{uuN~2J<Q4DBwCg0^yg1ZpWY*o^MmQm%F at Knh?Bvk
zz{5 at 2{QqHDE at W=z#-ERe at +awUi$Bf at YH`=3;6|`<M${qmR#d5oTGvA2+(+!MH?Co`
zGvs!h96$10QH$Zt=peH|(~tqR0Ms;K_?x0dfx03`hqm#m=c?qYud_BHVdVD+pBjm<
zINu#!<A_&abkE?()yT+ShT?gL$5i~-JL^2t9*+BA6j^L|LL07|ZOaw at JRnw6@$07e
z>w<a=kU-n=hXz}nfH}+D+xcZVoQN-o$LyMATmODhM+bXOVo%lX$mL=d;HZ9kyOeCo
zTyY|KaGApxssiRD25DVOh<^vTmoZlt^VmnbQz$57B?w4Gw#wUNQ&M1SG3ceg_3mml
z9)0nij~`cPYZ1}pYFTM6Q0qa1v5D`CkYWo^E10oep57LZe&vW-AF$K<k}WH*e>rli
zooHEKhzaRdc{jzM==5EJlz}4kcW>UfcnQ6u&_Y>DUY#js|KGoVHS8 at TUFv0Sp#cjm
z9>b!R3`6wQQWDsw*ndvvfjW%tVy=@512*xPA(+`!&4ha^=n(KJlTLWV)_?HHZivjA
zr;&ZVue2xdV7MPbJ9OzYdX&6jq^!sbD_nyb(>v}}wR}3<E!MM(g+{DHj6WE4C%jvN
zrbm_4bx+GrMtYe at qGIop;~I3yPjWw;4kR(DemV at bvQ0qcWLHa8csa6dSj^0k+gIsV
z0VwtJ(C#B)*@+_8!;C@@RzdzA*eHvPhds{)&hdo*<@wuaq6QrS#U1|~lKqdmhLwM+
z&)Y_%tXMkrN>bWQ6Bg-}nfI`jPr(`3UWYnootKB#LrRgY1E-uw(mq|fNolzYM~Tfb
zrK^-N-lmtW?L9)Y5*~hcka|OVgi2)F!wj~)bB2}Mz6;Nu%`dWjAg^j?MyDW)+e)xa
zK7*a|OO+3 at 3%#8e8<^)Xh{5J_d&I>x%NO`VZGIlxr5&p(wir<sVM at RseH{be4436E
z>XR7lo4X6By&~JFk97{+>=`9WNwYHs;ZcA`=&*60`5 at 0iO->C$bjLL*<IUaFcSnTs
z+`$9jV0iqgna6*4```C(`N^#+Rj3rCBDcREos39Jo6ko}+G8bTKW|(Te>ReP3VM}`
zn)X|zBsOQgUk(y9nDR7b5AJx348tL_4O4so(m}2Z%1NZX!Yjw)Xts?g*mqWfK51!z
z^_-}0Jdw4oYIhsABm!lx>=HM at ZO`LbKJj62K5#iFI&n0X-Og|S&>fbN-T^z;qe|bz
z%t=A4vT{*zx?yC0$Y$w#OIcZO^KAz)4b+N^syp-M*beP`SzUa}(9G=JA-F@`2|Mr5
zS9b~<o1u5TnqHcKn!oQ%kr#TA3Q3IOmb*Vy+v95-XhgIG%luf2^$BOT&+pys^x2YV
zekwuD_*n at p5U|NhnCt5bXvX{A$tL at b61C-9dqt)kk=M3?mFQm}vs*BSWQdlQAWXnP
zz4aiN&1^g_I^!qj*8^9`^wx}x64mQG<Ak^SjB|-~iJHhM_qqB@$H^~p5AhjkC&Sv|
zcBQJ`I|r>-qjQlNRYK;?3*8%ah!$^G&)n=Ult01v|B$Oq%Fb?~V(xslw8pngF-$wU
z9Zg4vV^2Kn=>2tK&SG at tYW>?n6r_0x-jKL3Vd`SVPfWZt{W>xLb&sC1uX30*x!I6b
z<V*nH(Y1cwz_izMJVTtsYmy-6m4BY83knL(ed=Pl>Ul<>y$xmw1p2<f-p{H=ylGuS
zX(24{aJOQkErWzZa}|1taY}xRi#nxmzqs;wrIN>ZtvKl8=v;ZQ*i>uT06mvEJj`aD
z(o`qqZHG_KvYw5&GoZVSWH~ps_}ZIZB!cII&1)!V28qT68^iNBYMyV!m+fn6XFe<4
zec?j2XCt at E51;u~hb_Pgz1R7Dw=-TK+UM4)vb*y^P+}6e=if%A#+6$;Z#pBI!n_qM
zMzWlItBCPAhrD)|f6VZ*QPx6Zq)OR_mE6kVrUhFx33H--+M{89y$F&3N7bNgikLUj
zr`xx-!mOIPz&|ME;6a{3g3?36egIyUU1YRqmc$E2Z(E2c*H;vTu*bW#pj$C9ed4K+
z99+OwI57pHBZ4egM=&Qi-QY}D3(E1({Da*8%!92t0?u~EsS`jVfm{;Xjrt=OYil_d
z>;LpCLhGz?q;4da{ij%KlY!ysoF0VgY<UKiAD(rNKu}A*2y(#dPN_nkHUe=UQXk>)
z%~!T$hLmgM4vmWD97)lM11lOnN155#2joE19@(7M`-i{nT7R;l?6Nv~ByAzBP0S5Q
zL*m;~7j0alAl7(E>L{x$sISB!i6UwqrOO!eWhN&P0<5V1{W~TEu_n?#ESEkqiB25a
z>XE2Cj?V{P9v~Lp-HwjN2LjAZJ#Jcls4HyXpJ(tVftk73;wG^7WmzydTR&U88R#jC
z^C8OT)}f-!Gl$LIBJ9!Kqb>TRa?+?1xfMbB9vK_>bCAR<rrC~*m1Kdv`4mqFt{=Lk
zUfc`wwbGXL#meQR`j-mSa`><o+yOHN?gniJvnI0U2e&aTK<$mWw7CPlhZ%)K5bVW|
z2qn3K41H=D#xadH&V)$9mBgSedu^DCii(G=G8}{t3;0Oo;2$=|;XbyneXRtaSa#_>
zKO(;HbaAOE_Tex8MDnttj_TjTF>Z+&P#Op#S#4QCVVhb!<*O%}cpronHPeW}Z)YXb
zV)R2HCYC+*Xfr{7){3DJlROdK=oAfizUn8-j(tT}7TQbF{X<gH>{eC6T6)FqvihpS
zV@%>8tJb=3;#Ic@$AhBpK_`PeVuXCvS`qbQAWH3o#Ve)*uSZ6aa&#bBo>h9{#~!pI
zQEBM|LX!12!u<Ch(OLQKKmiY_J#JEQVpbIB!~dB88W&%OhS#i^EQN#@)@5wAR(F}+
znItS&9x&&SgN(GEuf5(YYo=Muq^^4~9Nv~!*u8gnA=<AIFcuXmlH?Gv-}9IK%WX9@
zBw9lYe-p2ny3(Fe!IfxoO#ZKR(#KeQCd^(lTI#-J3(X?-Ow)FAo6tYsnBfjwEcOVr
zjFDeNKBRT!FTv5~3SU&sp at 2xy`$!-EKRNwIZKFPy2+vD?u7$z$PzPtLviDe~8l;oY
ze%5Ov8*Z(Nq3)~3vx_g9k?wp;8IB9R+OA6K3uN;fuvvR_gJ#>d2G`MKr*OSiRD=7k
z$1UwWzx@{fT*llXcm(t+X`K$!;s#u=1B$4J!}WFrU$>Oi(q+p&0`8cvk}X?Io_vb2
z*lZnT5j%0m-hPgx5M*VnD{NzqmqOy<4D`nJs%B~Qyq;_gU=^!*!+_b#(}p}h&$XUp
zRY8MEyy$fZXgiLrMi9SCzsub!g0oJ^xpE19aEVaXR9cIvL_xR?sp6vhtT8#<xQ<Xo
zG*rO*>~My_Wv->6?`$QxmGs^kyor6+B$Y^MFw~~~xF9xukXdR$mwp*J<n_!xL0P1&
zdt;8eqQ=4e%ftnJbG>dz+;dS4e}z#B=kMm(q7kJ`N|HlMjy<0$Q><^`YZ)n*4rv{~
zcJUBZVqZFa0hU at VTZ>Kd9$lKpHT5V4WTpf^EOIclCIq<D*4}NB9;$86HNdM_IX`h{
zO}y1L<~M>4N7sqH-Wr*;q~jqXsP1ZYD6VYMNUd3hRG7~`-XJRvJFdijwA3PN>Py|~
z!;9&N23f_uPs}h=G^&*!X+xiA-YA~bLN{0iz6i=a`5#{>IKnY9TTYx}!Bw~G{B4Q&
z*-<9T4$)SAi_5F+rApN$-aYM at 64&0ZoN<nk{hFjHm?j^sbv`0-X(jM*JSKU471!Wj
zwW%vC?>4X&?79Dr*Eyf$03<T#2c6YSyl(bL9<eqR<npeVbrENC8n61fQd)fsB$c&h
zSWJG<Yg^$-YtU)v1M)-z)Q(N?&;v7&Wmm<^KQ_F$LgX_iCJ>&L`&+{q&F&=Overm&
zx1eWjfhk($YT<yt82A0dS_U96Ux-_RP#}q%AxN3uF7Mh0|KuMLxhvmM`~uc<dM=<0
ze3e@&#t?2{fzYlgb~EXyn}{;_F)@*Z$?dqa!ICyNUz2o(ILs(BvnUcBat|I-V(@E9
zyY*{+2?|p)SkT<sJ?->D^^}CPp(Inrs5WWv%>|WMKlQ6gVwXXWMqOb!pHd?W@&Bg<
zcoh^E$-~#-;4n{*8hX(GZrMqrGH~$AY&iW7frnkYz{#7}eCZ$}GXbwzW%wquJ>oVv
z8~d4C64G7ZeAdv{e$=lbb_La*9 at 4ZR-#&5rul?HQTmkne(T>o)7DD=oiv3*T=yVE+
z*QrbN92cCP<H7MbF~jlLM3%IWpzE2d(+*{6Fv|4Go_t`eYdg%K7AAFJ3b7LU{bv&w
z$bUV_D3R}6wg;-fH8kHVv_YoEE6s9~%+`G#^XY2J7%cF)8fvP2=ZYedFmoohD^Cq|
zv!k4Qc!s}x3!G(#<dWq|RC3)AOA<m%^E`c6&&hjJhhy=+{T=6NLjHqyjz=~un;ra$
zLMR)cfS at -5vv1R0g!&G|oCFch at 6+?<v6lqZklG5+iUbxwyY{Z?e%a at RZt~pDCz4%+
zmH26GSsgi4ar71S2rJVvl)HB+o1MY`-gh?HJu34+=0_6e7+<R6-H_Ir2_*5?cNT|a
zkFggPHpeqiOztTJe9nN|36DA?XH+Emd+Zj8wO{FNW;Flc8Cd8fZDikCOxf{z@*d-J
zeig$4;!eROxx(?!68bOYn&pGVVV328GYa~ob<yUn=o5B!b`OQ%!Ph<?>pHT<#jb|_
zJ1c(#<Kiz?wX&WQCKYp+9-W|RuV(<Lks)OEU<shpE+vxf6^w(WU=&}ElXix*C2F<^
ze<?&3)oT(o*Ro1Q1<**G16({uyu)5Uq9SqjdK^yTx5(K~e*aX=X??Mm<(+kG(CErk
z*Xqsp0IqvpiRhNimI*ZymLq!jY1b&Bio&Q2vKDf`5D6{U_Ym;6Rht&vhafm{>Jhaj
zif_=>g?80dp5hTDp)hu`B^akzdJDH}Tw)9OtANGbPthKBFjqm$-Q7Q=0;s9sxG==|
zQmNw?<r}R5MrL{QC}6qvmc5#L*A0Yl-nMlF`i*Sdp~L`_XH-ZG)+dw)Dl=OnOX=q!
z%ek6EDO*JE%J6GC&Zcr_WqUENQB0gF`JcEUQt=X_TfHjb+5 at oMPKRmnu#IX)nneLh
zo+2tYmAs!F_SwbEVxf`#$aTO+^&MAXp%!1QDGzA3lRzXh<egk%CVqN*qtu{O|0Szx
zNxC9 at m0o(Y5d3>&Bd}cS{~&ku*aG~#k8}#j=Kx)8-l8XySCZ_K9oCUCw|8u$sS$1}
z<jZL#x-o1RJ25CUq^!J_bzD&U^Bj_qFp5e!`nj|vV};6kSN#lisc$sScs)ugY3CUx
zFsq<?yAbM_ at mYl<`AT{;YBW>W^hxw$KsKe}@WgosvQ|2IC;mh0S~3}XWCoos$%;KA
zJThsWRa|ZdZ1dZlU=v>%D2X(o=*jr_Bcu*md at p6|Bk|{KymqpIVPgt5zF-Z_$Yx%z
zCJKfGo!4AEC^PdOKQIWH%Mu1M>ZxeR1Zskf1$4vDsn6!E?ImjMD-u?_!tp($6(dEc
zr0|@y0 at d3-L!5=#F)}f3EsFeS_9*0jvB+zr{G_kMtj8RVi_ojVuOW%9fusDoTBT&Y
zv?A4`t#_+3NdAbsRI5CU?O7;G4)J?W?<Jo#WXuGMp(YhW_nBM!+9V5xK^sNvs+YZx
zj2W4lRR5gsy`>%k@`<}88DB5wAfQc5tuBp;Ne7M51bL%Np#15}W&Ym2cp94j8%qi)
zB^HD+aehiE%U#TR{W4k#(w8>yznYKMA_c6Zr?>)0i)g*xy{vu;Iv&t;-)F-HYAd;T
zcr;k5(vC_^*Fqadb+8n)v{|=%K4{cgFbW;h?WXbSxZ7<E at W1HQ8qJ~>o at 6>4FOXHe
z-XLdPY7Y$bL`eJzDH7b{w^p1GZ0j-Q<F7a>$p>B9_X;@w*)Q?hPZBo^ve_#!k1CMr
zaY)XgX@`x&{$5)fU;$jS%v9C-WEY6mGfV<qF+%e<HgRV6z%`&LUld`x2TW6*57JQd
z^D#Mtfg$)lC~1Pgg5lyIo4e(-qPfK|V2cpdi8WwCjJ&!mrSr?aZnR+2z7R(S{k=Vh
zTPJ1ohA)jVtCEG)9r8qGgaBx|p@#>EW>sujECNm2_KQ3OpmsO0r3u>uB31&$0d0xy
zFgQb^Nv$t?n>6Ot<cy~C`DO6<l)v(M*Ta(Jq)c5ZLn!$Lv~B05%F{(qFtn=w;ohFz
ztSHX_@;BSl9D7@?iX^GIUfp9OM($3$y+oDTv41 at lN{>~>^$d3_%X4WCCoJ)cHo{e5
z)i&n+vA04`Sq$)Z8QI6}+ at 2wn48g)P at fg6U9W%Ai%>$Pz9Q}S|_}jLH#Ja`y@;o{^
z`ut+S at i5EvB%B3K!tuTqG<N;3c1*Rf!R1-Mo3g6X=ZGeKh at Q!35t0lxxkNC;l1Sbf
z at I-3DV3))>yy8UaB{ivGX)J3L?QUVS*u*ZnXa;u$YrxPk;#EdqvAeOph%`0Z(d$OB
zX!SfBFkZ;aYU<<n#BG#e6S5;1(-)1RSG=sv1CRebi`yuC6axh^YWyzY`i{R#`os9<
zx6%)lYc$b_!EX60^&rRclO;SY`SQ3CJH&iGvesuTrzdnQUh=L2QHJ6>jlD at RG-=55
ztdnRoL;L6*%YpBBhnoo6e)85)Q8mj0WL~>Qj!mV#Hl6R{^0#V8X6~j|)#&qna(3PE
z#+E~62b{&9Wj(FdxKL=57Osq6lc9S$vnZ at d$xNUgr`OYfEswkYcU7ASI?F(z;#kDr
zguPu+vkgP2hiJ$j{g0(GryM+*$L`nkMP`m4R<ycdWGYa4hBg2A(eI`*aGv=pUvDV$
zm6aNfL|ROx(jp7v#qx^-EN4<J<2=t7HzB*P$j7{?T|P2s5im^_R9(qJi^u#&tJmIz
z=7tz~e!;T|#T_Bbm6C7!+~IX<>Q|t%h<g#OXR*jCqM+xHqG-8zS3#EB6p5kUS0v$T
z*&^+*&s5YGha6%5DaIitQ1;YT2Do@#E}yPSQ1SQOB#iljCm}tRed0wO-`pwKy5s6?
zd9WBwT@$>MOUO7eE_sF3)vn__SFe<m$s09r&5H5n)`c?gk3v5hMCv8%guN#<%AX2;
zkN at -S8LD~noi(lR{W at LIG%A2ijPt?yyNO)JZLTGSjQos_pb7Fcqxpf~Jo-8}iaF~;
ze<Z-6K(004$T$5Pj7- at Gv7)Fs|BKO11)c>r67^AXD&8wZ6*~OcSVY-NtN|yJEXbBF
zb}b>pl<^;?B4fp+wNE5zfAiiEOYBu@{Z7;eRsSF1v9Lo4eu?zyAa}*$n2p~<(cYda
zZbhWY<VSzq^Pe^IKgF2r71-a*J|?NE%SqD@#}>6Edq-CBrfTHtlvJPVkjXmGc66-f
zYn^TR_cH5q+sf7kLlom-(87FY&HBKFp=-O}G&+mTdeH)d{Wnqz7a(QM!M)<02T`7N
zm7nYFZu-x>(^F(FUZ-vgLRiWN3mJ_i+BbBVesT(SABQ)rWq2=ZF=XI<UAs6i9pfJV
z0F4gFsWu&}AEVQFBFXhMLAxiQ_JdJkNx#;t16u10unz-N4;l3P6QO1K9!ZM9lfr<K
zu at 0$ano-4)uJ65=>O5(G*X2&oSw4>yLOl1t3U3tE`fd9WMlyDB`DwYr>+GRS5O26n
zA+bSIFg=<ui?j{6){%2(pMbat*xo`(%tgJ9R+z2QT<=#pf?Eeu+FN5$(LEU at 9Uk~L
zI4ag1FC(Z;Xrw^p!{r?<HUNs)rnLR<Q}(-!=;19bEsKh1w at RTei)7;=vwDARsD_ at s
zkFm<|o6g=+bYwJ$M8cIAsPgcA_T0RD_U-8=3yPb5`QKi2SpE;}9i;7Ux}O?sK035^
zSTqFC6`GiA8{Jl$NM~L1kU3V)$o&3VbCn<Hi-KGX=}1NNX~=LK7=^N2dlg;Gpirns
z=-OHv`4{rf9{yRPC?$ja?>L3W=Bpx}U+_vY8J_V-If4hoA^5HUI(#J^vC6hF!ZR-=
zbDXJ%u0sGF#fhD4^*Y%Y$bKamIC)#Y#F_9HsED?yJ&Zmhv3JIyPOk`*xK!XBA&!)j
zGyYRxnGSgqc;0e$JM=6DQ2bpY)R2IQ1Rv%hjOsusebJuOKMpl?exKP*KY)G;sbF6a
zi|N*omBenf^p14X*kehaBN<xYvqJ0n&cB+NjjO9wTw^;<ulzE0U;OoH@)vCh)$2`a
zw`b~E_WK^z{ADV)GbW at tHn!6<rP1|YA5cw#Z)Q4f at y&h`E=mE^TI>|(0CPy3<Z8k+
z_$wpoBlK~;?wrXcDGR#};6&^DseMEHxpjr<RIujn%5rF8CPeudVj`!kuGLr0AkKHR
zeib6h|MX(MaY$~z|GlGbp<->>%jhi&QNjPe0cKM#Jb~-!d?dHYZ`CD>`{_KIezArI
zXE`M}5bpD7f8NU6PRado;@8Y;7EOwGb|mkjQ8~sYQ8V4f<4iKTH51c7Po=mR%a*A0
zR>QqitJuLWy#bwl#h7_V`PQnmcF<MFLtF>w1{{vZ(^3B&WVaKDf^?B8)lZ_~Ku_Wv
ztT)6BI#ulHvQmo9u3S#oHFCu;X~>_o-GK5)nNVOQ0^K`3uMryKxaYDvTvvba(~p=#
z`4)RKYg6^dZ~jJ!XP1fOv@*(RUjBs>C@|?lzc=Nr_BVO2=nmLPu(HXtCBumVVdsmR
zToq{WK{b1?L;o4h|3}k#hqL{?asS()YE at BG6{WVKYVTI5Qls{Wy;o=vYPUw!-h1zz
zSTRDVy>}(H)+R=S7_pvDf6w#$>vFkrIXUM(=Y7B5ubYB}wO*w&*-E0OL95skP>UH(
zTeS^U*tkIwJKXuW<rPa%r3Y^@vo(46o+4-k- at TPI$<EgX;bRvU13tXZ{xNrUsa?M7
zuoJmjZM#+De#>O6M;-g=&hfE3x=IsQ;8^$M7yHaY7}kjlT$Vpe<FOyibDSH_Ox<N@
zvChtZtTMBxeftqeid>ecc;sqgV#53IEZ6$~3iF!}?>)c!zV_-7&*W6Td>61L!|rxD
z`zKj%>wKL1N|6iDpO5a$#Cy`r!Tx*!=I=gke=Iwz5m#bf<ZsA1JToq6LS)fm;6WzO
zSa=CX%~8`gk_xWNR>+8o|HN+rO)lx7PII1yggXhx^=_t4dMi4O%0A&`9-9b?c>R2A
z^IAew#k!)p5AmuiNga!FF}aF@>&<*>TXS4AaD+|y%k|912hiVT|3(~4P*Eq&QmBC#
zEFM#NZZ}Hvr=sWV47<8`CpR$uY1-`#Lv6Ws)~PbvMU1NdD;K$rVp8Y5J{lMl$$S5g
z!M&+LeiwpD-VOf<n>-|R377cWao;faUM4sm(Tw4Psd+E+rhyNIcG#1IN!sK4#Ws7J
zb1w6EtNsFfja5n+4?Yiun4YmgYi=b>Be;q_?5iBHmJ#M?1L0Uu4Jmi48m(iCk{jC5
z+^H#O{2F^}oj}z}Xje$7F5Pk-ak2Hs7T$ZOR8?(uFne`2`bsKEkz8XM5EostNdJWF
z3_p6Q8_Z*0Q(=)mB`%8mz4miP<1;_s<Aav<=FzXNA0QC9zDLM3lTUta51FWvTJ=|6
zso;i*ozt`QDtBK at k1VpP`ok6WtIQT=YDVS4f-j%3{WzMy3`+u{d{&1^#!In38XYYe
z8M_=Ca8F)rP$b=Mw*jZfz0y)1#U?=$EoF2RdPzzxu97$49n~?fKfHaqnfeK;6g2G;
zzY7!Y6Vf_puF>M0ZRcClKH~jT*DoFNU^h|0uk5~aW?Fs*+HK{n3%v at Lu(_D-D49Mk
z4Xdas8yk53%CF~k_YU>T2)Lw#gkjFru5HfYx9vA!94v~(@}<i+|H^_2F!XGl1oYA4
z>zYOD$(*B4;oqhQ9>SHG9}4T><>jgD@*OMM!Wek1s~5d8X`@mDQK`-nF8OXUfV6X@
zf+yK>KttcO!WN<1#Fekm+CFjPY=4FZqh>65j1wfMpJa!<KZRo&Stj0 at 4aw*mpKAEs
zKo?Q=K)=O=nLyId7&e{mx#VRl?SJ_NcE~X>Dc|dyh<Vo&&&!rE=D7740*_wu^Q`h*
zHpV=o@&o)@E77Z~aOXusG^`DOedB-Yd&if7_aTL%}`oVb5}V(wn*9})?B+3Ezv
zqcsxJey7?ryfZ-UOf?`KH~4gOeI;#D8#WHiON%C)Z}K_aH+eH8=ZH-U8(Wib`Yf)%
z$a&xDwV`M!+Q(&6za|B%&@<>C^K`MWU|o3u=%~gtJiG+e2At|JA+L*@CxZIU6d5c3
zexhOy!rG?2Q)7B!-NM$TE(k%cseI&U^m$SxA_}b|74<_3?;+yinG0X)XN8y@{bzq?
zkb at +xzWU))H=2%;A1H0g-LyI1(W at B7HSSI2kwIXU&_a_twX?I at X6Y9H4Gxb)59w~q
zo{q|wM2E`}tUToiwI+Fs2N2DB&Ks<^%h^mE8+vrv+O5onY}rZocDH7PIrY(z%9Iw%
zt3l7Mr_FqwA4!+S&#oQ(N*a$SIuImM+0Kv3jhcy$txeW(Q_*JMRkt;4p|N=Jfs)O@
z1F7=??_<qdVVBx}pA3+-i2vMANlB3$aHaaq_{$`xoB=c$2 at 2<6yYUdGCi%4Ju?O*$
zc*fqLZE(P$o?VHlz>HP=_j3Z|Qbm8Wn^Q%fbA2q)nR)!bHgNU#VGIm51UpZMoF|z!
zLzz`%Z=wpxn<;zA((X8yrBi>zaPrg239wF=1m}?OVxHF3^2QXpmDT|wLC9|eM|PfE
zs_d|MjAzo(O0(EcSGr(UolkZ2I+umyDw{JxQIF(Uom>vzdoRj?a}LC5^LxyUwH22u
zYIWQ7wpyg-M*U!mGiu~Nw;?Q#fV2D{r+BdpK|_y9dbs!8p};vlkyN~M<VyZYn3(+{
zX9f7q>zHhWIaKS4Hir#UMVb5bkA#G4K|`#X+_R{da3+O3fS_}#yEM+1ra at dq*d=eZ
z^p}@_t;WBh$-BKf>$V!v8Ztor8_}1<;8QaZ)t{_gT>M+XGc0b;|IW1xcu2FiI^1jh
z^Q_U(&O#-F{*O9nkxw;hZG70wKm3;6W9w=@DTjy`w$-wA8zOnLt~nO}HKebT+wa%~
zI<Wk~+*{RgEO!uY1V4k at WDw4eg36h+rk}sc=!zbHl*TzwpRjo=*WHr-xLfB!Wnj4(
zxY8Y`rL|V4EqH=Qvhp8D7X5@=dF>591%eD}{=W%PJ$eB+Ls1v#D!nKQJ27EM7zGDj
zqO{D^`g(e3%+8K$RpYXWsQ*?dYMM3xOOiC~9!*`SrmYaB(sAf+*I4n8dC_7m`1Mf8
z*3lwnv4Z5i<fcS{UjSAsL=${h**&``T=%tP#IGKSshL@~_dn{#y}as`?|b%E7~0gh
z$`yWC$z}`A#n$;hms`xZNRuBGL}1|hP1KUkpMx_Zcpr=$KTC|1mA=nGUf4|K at BBx*
zKR;v+u-&o<S`ICNNHs1s<K}~37if|7UC4;PWPdXCwgkc)@ZQAlbg^k}2G*Q)$+BAD
zwXE(t)6!r5V9}Shf{Kr;g&zERZY3ue3aBp9jpyv{5#!XyDj~&dcN*PMw(G6AHI=pW
zC^#Y&OvYn1j?+<nC?_;sz at 9fmDE=ds*zPcN;lAO+@^I=(&_p$SF7V}NuYcZ=*H491
zuGQVNY+v_?sy<(5ns$b<)P^KPMxx+N140Kji}x^{hsq}LMZ3#^tRkM!h%)8?fB!Z|
z&}nsQ|FM5x at U$wK_kgRh4}HB&p4Oyq{A@#YkJefqS?wK{h`ZbAB1)I77sHu3uvOEu
z5XkxBGLlc`qy{G_dn$-Y at jp*NP2+C40=ElnYs~6u0#3p7ZwQ8p>84xad?3fDMD{Gm
zF{@pSI1JJhvhF?#kx|uF6p&Mj_4zzrb21mWN1Q=0zqbxD`E)PSl{#3Fy8Gm+hrpFO
z{8sRH)%y^v#^&3Hg}2{~8Sor%qts&Fz#7G0q>2z_hDC?hE9;T))+x)X*6>=K&X)vN
z at Bh7b5pIOb*iC)B>**}ocxa~jG0IfM3gP1FRQw(#1n0Zf5T2IXrwMIr24MR}fO)+I
zGs at AM`Wui*4(4=x6Iz57nhZmGvY|efv- at C9*3|-pk}^b5^t17?Pl)5FZE<Fv#es=!
zFNvB(6Vd+n`o}ib0hFB$q{7p;fm(NO3N+eC*~Z$k{r0(HZ^P$^MLxxW;AxD+{i&uB
zXizMhwKs&!xyDeuF})5x^Uva3f-s=G1&*2nYa$F~K90lU%K#U;EL)zf8OW#Fk!L_?
zreVnZqNbs_lfrF3{>WK?ei#&1JB7w^u`v6iRBJ<_j*fh5{Z7amfU~{`h+Q$h|Lf{7
zh_wY&!TXRqOXq$d2LUY;uTDCfdBZFmZ?p<pbH2H&0fPP}*{tK~3=DudeGP at 7fh~wn
z%efl%{&I7TpX5I~Ltq2V_5mY-$;M|d2;6^L?|R)3jmGepyk;gRDRUKGd*n=Tv<E9!
z?150 at i?*UnxTufITOIi)(*D<kS6T_zoO}DFcnRs_>8bW8w&B$C`<Pqh7>QxA*qeOu
ztJBt#u)&x9#BxGBm>$Iu)y?{z;Xp55^1!xJQ8sRNd$y0F&I>a<x*qRb*u4C{*O>RH
z6qQM?2D!Kx2&GB|Z)otUGly8TAnens9DA3Vo#X8moJw56<(-Uuo->#2XJLncn#;KN
znu2%P<*7-Y-h-%dI46A%e{bHC at 9NtaiErHJ!k!}vAxo&LACF*OFhN12X7Qs8+45Zn
zWw_FPs&`a$ZQ<Xk$=C0Iqtw=+fqrDXU?%Q>%CZ8{?iWi|W+W!o7Xq0D)M17&S0|Nw
zkK|sOQJd0}vu!H|8Hln4`N2kdWQwR;VBp_c%|nFEQS#4gt{WV+a0ROM3e$)($J{3-
z7&&Xcnt=w|5Z3Zy&4^ZrbtgBoNuLGvY`Q4<R~Z;96b^?2ZfG#QdJKb(ENiCnMvB!o
zBK<IED&r^j%&yHWQT^mJyO$Ss-;F~1DFXw{^sL8Jzx|-X{{SI~F#Dh3{4#pp))Osz
z9dJE>&ocdsr9C_aNsDYy+!pGI=GLXLRDo0kLPv`~(q%mlU%IQxV>jheux2&)!TsK;
ziz|afmt<FXK(XoEi at WO4)%P<kT4v(}a-Fh^Q!;6Y*gj|d!3G5-7pYn6<;#~eb9vOi
zhJO4t at 6wLc+pW}}xkSUaP7V8op?gO!L_7{&EU0z10GH at A$6kMGZv~zAUqtm~rKK0c
zn7IP2HH#F at b9nQMAUaNl6h=BT?-+yY9y+SPZvI3vlpI4Qr^7{6zmcJnK0|8E$E<3y
z63MPY5uQE+!>sHPr+QNc(+>co_WQ<XG6`>2gFW2<Blu}zT~*Q%H;rF*Ia7S{ZmEi8
zwvtDku|4`Z(I3XU=Wi{}h1i8=P9S$i!*C=qX|MF$92IT2(~mEVj4V{Z<Z48#G~Gh<
zIuu1w?^(<;GL at EuE?#`lGx3spAbe*pPbIF<LFq7fYS+yo0lYZZ&@h;++f4m~o4Cr@
zy167j<MO#cp>w><53RRLgmCA0LhBjx&l7T#No(~aa|q!#i}5(;J8iydx5Enx;CwJX
z^z33C#JAQ|=YNhuQy;VI4C&F){i>mgAzF{o;88v8!%PinW!bm^Ed004pE~56;IH2}
zU~BmhyjtZL`%Mgg;*i|$zA>j7uWnzXk^LU#bE02KdRw}gSgw{=^TQ6*Qedo%GL0Bc
z<Ncv?&FgXH7^{k1Is={b7a=)eeSQi|T3YbY=+*}OagSVi$8n at fV6=fezl?;etZAdm
z@{(4aARnI$7kkq4Rlg+3bqoj_H-2%t<l}-an;Lg at tx$0~9-j!9U};p?*%lBp_XM8Q
z`;igUJhfUSPnLZBdZ&G41g+oKK^%0U(FlDwC6OR&Qgf%Bp?R#kI|KqB9UVQnZ(Qd5
z=o5%elr!^Tj*|Dz(Zw~5Y6Oz7x}na5kJn0gYu*aTsd>6hEVy at -)Z_)bvVEOz>J(Rg
zPrGC_-;64)Mxspv{L~>YB1^*}-)2Dsia}?~VHB!KmJVT!6!rQo<lwu`JI=p9o6UW+
zb%c|dC?p^ZfX-|-w2I8wS(ln1=-b at rA`ev_JX_bj0ynp;a&FDT691wnF1 at rVPDROW
z{`?SSG$nWUgVmfi at PR$DGBKOoR4e$PW--6 at 4MyMpr8cvdKfAlvJ6lAbvar9JGG8<k
z*X|8Qsq>W#=5cfB3~P&PM|}VHIU8M4wp6Cxo#FwQ(B_rPblHnv9`~qaai?!8_e$^Q
z5Jx>nYfXMBx4Kt1^+8Qm$nW^rd&<uQ0Eavyz<3aaFG@(3g#Om{<!PvFG9oo|DyK~S
zk*M at x3xDBX)XX#P?6s@%CVOA&6nXKHVtz*B!6zjPftYdVz;gpf)2(eh-W!SSrO&u@
zpk7 at 2r6&I&XZcFAreS7$jfKsM%1kmuZZo0^G(~Ksay`06oA&z&PtN1x41rNp#h?))
zvcd~0iA=h1ZYZ}<EvF_Be+3r#7XqV>n0-Q4fsS?ZT<wiA)+^|t3+}h-2<=i;Ie*J@
zkj|%C_mO%&ShmbiS9d;$waue}9ik^Zv;XF}O_jw=Y`{N8Vh3!Yd-#E6{t`Trd>8+z
z+(^T*!3T`)Om2m?X~`Iz+n^Qb739yj%~#AfgY5c>RL3FgYt>e-e^|oilN)MnSSD|6
zA~f*ca${1 at G^YTQLxV3mztBr55sx2xbqDvg*?%-JVv{*d-2MB5#c*2T<}+WZI{uyN
z9aB=xxQTsVpPCa&X2Hr~$HCIz8m#I-jNBbSkNDzwgrVaLo)w%sUH)freQozfy*8kI
zaS$;sWbI2mtC1#jzcnnS|8~Uhk*E&DrnXWpM)^zp-x8E*P1g8X+t7>(>`~Cg?{%c?
zT3}f0z&GQlGX<=v4e2-?FSr8`*=0eb760E0AS$wO$e~&2K&+7T(c#2?0rOHxuq_Sd
z at _FcA*sP{N;Cm}goSIgffxoAtjV2$vkyh7VI(p|3RX1A;-&c1?v6pWmyDu{Of8E>3
zAC$^CW<0LtHy(6+?)6x8OJCI8W>5O#y&=^m>IfOrp7_9 at b3svOvI#?Gj=EoxjKgRw
zb8=F at 8r`GH3e>5%RF)iMa^S1P&zt<xuOWkUW+(@*(Q<V^b63e$QYr(l^1inqFDLw|
zavOO7VY3Nb at GVU)5yB<HwXxmKiEbQ3laN2(tl)}yfg5T%F+l%!k)5;m7sQg~RfX^2
zq)>3W at yBT^?+vME-Lc$5NXTm=V;NcF*aApB2mQak?R%A+o9;b8Q)WQ^*4*h4-COSY
zZ@;LsOQ-b3_1X038>)z=>?;?Yp-7iVQ{rdyLpU`J1_!x9viBc^<gI_{OmOsmbvJa`
zqHd(Vaqq3L!_e`Dz5~{ClI}+3Eb;FrRoV#YlGelEY}{<G$0A7r!SwDUo>%^9GD3A3
z!qV=+*>tkPqEnq6!4u78AIm=mF7TkE!bXks at LLAmD8jLsk4$uX9O0(nMXe`eMRN#h
zJraXVY{FP%R$J3Ljmv3#8vC(9_fs!c4>IkKljQQ}uNh_*BUinIZkb<sBWW_lh8RR1
z&^5j4tKFgd1)u5pGU}i#D(_{%(MqG25m;Er1q59eT;g^`g7$#_91id_BEv(Be$4g8
zqrLqGc|2u<k+|z-A}*`k at y=uA?Ka0mZnX*dZd54|^lz!*NkbOLSQnX*FZdwGm}ov>
zG^-j3g*l8~UP1 at ti&ZC;lPAN=;lD=0cU|UZofGBA2FV+2O8TPX*Ik|PU}vDyXw91=
zO0-rG)c!AQOOn)t+#0LgNhj!%OI(PEqNoq8-f_94vIiB7dqt=94-fj#5EJ}Js0S<d
zJ~qEssYPl=<9Y$gvz{UxlkbHFB^?phB>Y`E7$7fPS(fTcG=<W`t?_oZB_v;sg_CVw
ze2^#gEwRT5K^}c(8GCDYvD-AGGyb-(sp&$(o at 6SZ2HFMqEEua^_vbMNhfDm at NDEUt
zV)Ny3_}ZgD6*p`DLIb-b=Bc%<PH|t7Z|dzwz!$7F!0*VD|7q$`+)Pkfni1!7z3Ph>
zT|;#BNp{CQaG92V_FpGiNp99l?m41nkk2HlJf%l}(jIFu%fJ;?SB!=|3W_Bwj6>3N
zD!iHPLD!==9Bv7Inp at -~0PpNEFHcyqT?gVRM7)k~Mtbz&d7)tL{QF52hHHK<cEvik
zrNaCn#dC$bTTS0QO)n}bv(8 at XmLI3Zsif?@b1R}KXQ8gMn6RBmc3uR$B4Kb;mLye{
znWye~@d_x^wq1DFC8x;qYZG|Bm+{>>iL at T|GzRi_Kq~TW%0@`m3~ggVQ6`oZf~jUy
zmxIdL7KTL<AQR!i9wTllO<JYl at 4__O1+$fMI4%cH>2El_q^R=B#2iJrYYGE5N9`xX
zM%0xe1Esxs=x*%3*fXP8E9F`2k{JWDYW`ieBLV_t&l&writm0teW$f!(KY&)h at 5u9
z!b$8ZOuqi^NJ at q^r7eYTxcuXJYCxxM#i2kg5QBLAR*hG`19)IkS5%E=KCYiuXxW}S
zFE~4u|4o$BDo?jhHp#SatYDqk=-F-RhoLzAy&p;dzTR?DYf~+NKxNUB7ydmMFuFa=
z>UH{tD{wCc=bhwMu&h|@<@+MPHU=c{OklKTJ9~Bxw7e1F-v^D9MMoVE-f-&Eni`U5
zcv;h8SnD8fM-bFhTgz+xcVY2ooZqJ$;)+#9RR>;EhiyRN`A$WXsCa^k|4P45(pCB_
zEvR^2_?Ot^#=jK4p0tA#8lP`$^L~uy;IBNWNPn(U-Av({dwHm>kOBTIyX+82<jTMh
z_H~gKouy=f>2*%k`Dsjfo=Kn(`t=CVm}2`cZAd at kv`l6Py`QFRkIUp)@Ac?3g!~7l
zlO030wpXoAE)SZg^}M(KB$>1R&E133upm`~K=6-2XJf1XmE6h<XJU2FowC$2mdyH~
z(Xx%v$FE^cCKZQ#10eYUp{fUPW_5V;>|r2}$KuMkP)=`jf at P&UJos#XWX&XOgF at q#
zj#fmA<1;&L{+#{`n_UsGYP#%df)Yn_Tbl{s)%D?So8+(=1z*}*w at 0`H<EWRxd9C4D
z%CS0ryc9cL at aF|%OU3_v-FxHpSc?ORZhWfJ_$mG##v1O*fM}NKXMd7VUq5Y8QJ`s^
zchEp!yY5SQg=mOxdes$4R&oSZTJjBu at KRn2bK5;_2-C^?nAYi_6fsfRWaiC{;7T-8
zEK(hmSA4bP#KgU~wUAhkl1XF|3W5;r4N#rrqD-_=n)+EXufVP&LG4J^7h7pydnT)>
zpX at TaQRkF_N;V`<P^Sa at a{%*3rk%dH=Nl^Nbig^u?SNf(eFN|i>GjmXCCxok4l-pG
z1tyNBxFlG$+accx>bm@{Zv35dN;Xf>K4eph?>xP)#)(aYLw*&Tb^4O^k|4qb*23=l
zp;_K!hlWMkR#SFoS$3AJ{Jf7l&E%m_3fl$#_!z(ZmS2cb9xj1NC`l>AcKf+j>+ at FS
z>thvnp(tPmv6=K*r^-hKzQ-*JA5v*ZJu2AC<st~0bw;8r6cQ{GLISaIlPJTN?qClF
z!<6(S_2@{c*#T)<P5oW_)4|(q3`te;rM7Z^LhVSD(}!w4JKGp7Ei`<OT9m)wyvv4v
z_e~&5+;bq(n1E;X-n^=v4&Jb0YP>9 at YEyytCC@{D|0=CegT}uv$OK1*6UkqcCYtHm
z at F>1pC*mj~)TnJYrcQV%{!&X3xy+N2H>St-0+w{!!rJ3#YrDmJ5vmYju&qe`g|@;*
zZ;-#jcbz at MzTiwBbSSfxaA(SeU#WU!yzAjLeEGTOpt5dKK7z&=7S6Wfxc+xWIqO|z
zRZFg)96Goy=^3CXFiIYV7LOu6-TQN!Q5PYsuB4X3)uKAOckJPfo7Ovhka*|O*8h~)
zUR#|Xu_u(o`;WB4`e+aMnLZEl40)0=E_u==+JAe=7Ct|3dnp`8FvX$%MH`!L+f?qL
zHT~lLSn{)&o?e6QY$^S#Q5G<*79A5rZGd8*lvc*MvZMuR!gUzIUiI^L+gWkD=nQ|{
ztfp}m0|ix7JZfM<X9BqPETjE+-!=Wi9T<W<L2iNxQtL at qej|HpP*G8jjPQ*0<3~5C
zoH|>)N*RlsEjq4ta`TTxGrDztfcJ~7BNj at D&pKyb#2-Lx3};q|N|xN;Xzpk`-?bSr
z$Fl3fh<4r_C at ul_LfTl>r<P*x#YN%}o0}=E|J*mQ5ccoxx-W$8m9t4FHM9QmeCq at 2
zXe*B4Jt at osFV7OBN^IY&j9*W``NyvznE$s`l`UrEIcAK at tso3|G8pn?j*+OM2cQIP
zynAZXfpD8*7fEVlQ5p>osuqv>IceS)WC7B9pk{gR=$|M51Gnw%R)Q8S?M_u_C}fDt
z at D`b$jl_a?u{%zup+$Aj_Jy;yqttG7JJ{J`#oDJhTd`@7ISzPnez`@JPJ3Jv#bLSL
zER7gE*M5){>~Xp?tMg-1BbOG<oDCbya|93ZgOoh^O&#~%tdgN53D+f57y;$PTmrPn
zJ@)0#BE=lq(5Gh at IPIBr)M+ASdYpTykS0=s)Uz+PsAYkB7ZWnAzx5iA at ww|=R1&gB
zcOylTUL5 at CbDpg)1APlkPob;R1vm at q>Z`DPHg71}8;&iwkZsYybDX60j+~PZBu$1E
zv%>U6w*0WrtWKro(mdu#rLEK-kN(8=)>L_sz=^3 at Gr*B`gn~R8aetR$JOxgFyT7qf
z)E%vOFXdQso_oqb#UtitAr$OTbK1DMx#?4G0|Yl-{3hMd;RRgr4ozb37mdOEbE>s-
z`I5-NhtgZprN%kNLC&QSS_)KG0oqb=|G6k~c715M*IDt8nL=9OFf!Lb-N#92$1W$q
za{9Z}Nh9Af(69s+)d^Jy3-6Y#!&B<hw#@w5k0Puag}Xg}pETU<Fp4D9PO9cTe?xT9
zDO^>k3UA>yzw%EgL at 6BUH<oW&en`h+SNq12#)e^RoDznP$fGlhtA()u8>Ii~34Y7v
z;<3^=7GE}Yd5k!k8^F)d`eI=%NAB;-v&ja;-N_$Vx`A82w$IA5<}?OsGry)g4Ko@~
zZ9aQPFgQxYEJt9bb+7SEv9r0u^;S`c>1v6=78pib%bVXbMlSwP{ym|m_^X8Hm18PL
zmU?f0#9`Hqeq at it%b%uNw5%vE{>cDIO7+ at M&qf&|8!Ya}Jv^+73c!m}#kHCCn~nRe
z7FgWRvt6W5kdg$H7^lYmCVj1e?J+yb#&x$6-mve>y^7&d!>k&1es1%A07Z!1OWH;5
zBE*r{EA#1N>Q$AONmsg6qhbO4X<o^%(238Ws)e=5QltW<bp*QA(3(8|XS}HR=R{Zn
z%+zsB50Z_FBc==GkhJ$qP8X#kl-AL@*Tm}|3$|^3IB<+Nqa$^pQx<Ln*4E1ELv!a>
zkI|}`-}ZJ~<nlyjqUm7?^#uZp20cpmTI$yKi=SWX3QLjkFa8GHi=;mf^ooX+le5H_
zlD+<$0jJNbW)u0D{W>_k*y}b1jJT*QrF8ryoBfo^hk{=yopu0KyxDLH+vF6JHdJi+
zvE at dP+o!0ANm=ssyb5VQqeb^EHPu}g99&Of;4P;zUsgwODK|0gZEbkZ%qm$d$IU7(
zI0|T3g>{%;-Xtuvm1fcfoddnC-O;xBMwbH!ng<Vw_J|G{@r3C*G?+sSn9{OK((K$v
z>5jdeX9cj42U1)z#1QkJ^tAN{Q{HcJ!=qtbumy3OpZ1C+ZccJXC2v~<e!4e`iU{q$
zxK6`Hpo{C>(Hx23bcw-l0v^7}v**X*lCrYPSr-X6FFaeD&@<r9L#ZyDtrM at kWd0BN
zxANg(qw<+svaCgNc4<Vr$;@8{{MuE&z0?^}kuPM>?)Im#?&2%Os-DVSL+S%9%Jwg^
zh1?8q?z4$^ul}_SuS%5+C#6kf<HAl;9+^<)cW3Lrc8R at JW*kN1p5(&R>+I2iKo^k0
zJL;9vA5YF2W?kl&rAQ;yd;_Y*g?HIX0Gp(fdSvP0ci^#!{&}*>+M at 7Cn_&p$9Htx=
zO-&d=S+2hYVPQ5dsJ at nYYNh1JK)0S`%QlqfWIc%*{HnJXR|!lo_2Kz0WF1{LXYN>!
z*1D<#37;!~f9 at 2X4j+@M-gdye+t+rp{`^`&Sd at CxBqwbX%5&uSEu8_GGrrIa at i8{a
zs${x2UN$wo;azS9L_66TZFN)>J;x*dXh1#38Z!Crudh!d5QxG#NPTpS>_f1a|II<-
zxlHqC%Y)_Y^8KZznrNA(m@#}tml&&Md(q}Gfu7L3viz~6;7ps_=BV?*USwmgo^KuG
zJN-uw5s&Yl$#(-Ny=_GO<i=ji7;NoD(t5p2QV3B`BmL4#_tDTRg^AUIl{M-qZN$u#
zhxkt-j*(_RpdqAHUQYQdg3MN+e))f)=f1PwdW)ucSZ+6A*{Si`vp$RUN5@<pI-GfD
z-TH&_z0t}8-9jI7Z1Uu2`1$xy^e(M6jm~Ro)IKx;_ZRheVPD>CT?tw6zR3;;0};fV
zchkPqXFEsKUa1N@&_$L;*o8_`$(hO?P$3_)v9jHRFPHZdG6NP%S|Pu`9egO~AM6VM
zIxRi3F%s+_Q>EfWmwnyTNAj$4Gs?NF^k0jz&xhUvSini`+Cnuv%!<9vNidz7)NnBS
zXICrY;*k62FMoL?muOJhIZhW&R_e*6l(RG(2dk?R$pW#}?y at fyy0THqY~tnR=E91v
z7AnO!85aHcW1XJ=JpjhVoa9<735w{kDPI-u`ve34g%ZgZcA%c_J*e9t at N1-Y%67e<
zwYp0&&|YaNu}J%~{C-kwr+-U0SY~Ss^vSb6+JAcam()@-ZV+F~e`Aa}@W(S%!LH^4
ze2}gO1sFX3{*M)`M7xwpz|n#4GJZSfIt;fjc~Ci(u!@75;v~_czN?Lu1qoA-Rl6#t
zvxyu-+3T2g&#Ua^Q<o|xd>oTO%(B0u- at 2Z!h2M_Wa*hAWrff?aKqAV*opg;sm#?Tz
zYp?s6 at CBHyjS;xam+v>zSB<C}9CEqQAG;}22Zi#Z^n6z$P$g~aAoQXSlQDWs;O|E6
zU&!OowZC2YpiQ&s)s=|yA(|}W)}+TYEZ~<*bmh&<$KNQF*~@$m-v at rYI2}8r+J2FG
zLOmwY6=lwCLrlSKmUTkOZJPz82q9v`$r%+E?H2zfNZrw;w!hf7kR@?7$v`h1xa=qD
zHGFie<_~zUt<=RjiUDSTQo+shX1uZ|r;$rHsONohm6y2|SW2Uyi+^|}u3Z`?YI@)%
ztgu^k7x6gXO4Tmaj**Ivf`{dueB#;gj}tB>N8?{{Tp}5l%%^!=s#lMOD=XXh7d0C=
z1$9`On5yo68c?l5`=|DPry?(L125ZFFR`x$+6$Nfr}B1bg{Se$idM5UTgt9C!Nu~X
z3=E5=6&os*W`{xPQHB!_ at j9T{bG;wA^de+gq_Ighzw}Ene#r)<-_@@Gro)EXG`SZe
zWt$Uy$$~KXeQ}|NwJ!d#<O?HOz71%Je4j&<&VQ1hJ at Ca(hMhimnlj4zw}vk6ww;`Z
z8 at 1whDln)jPzxq1;Mc}FqK+4=sK^^2DWPS%*gP93IIKK{#bUkJ;hR0S8-8KvfGj3A
z2&7r&e7fD|YMB430w>zO=~5|+E4e=Qc5Pnn5N~fX<mlVPNVctKpsFN2(Y8#j at V3*7
zfKSNNB~#O7Y-pRKF%0hflnG{fz8i!ik-bR3NVZ>r&@BhXRR`y72gWW}IRS22PfaTi
zE`N!_`e^$wup83=pT!GcY;D^*`E?k?%d1A_;_m?d=w|4qwQc7^`zODtoHI+z&X(0x
zf62`Np6BMm)cEGQ{j>zd)42aMaJ=ga(W`V?TAN}iR{{A=l`J9(E-gQ;F4Z7}#0`ic
zVPNX-Q%zonh>B;gUPm9Sg+0pA|0Ecf_As9=R>tdajSIS2Nd0Kp{X2;)znKoo`(7pc
zz0O1Kc+WQPXeAWdr>D6l*Vfni6JxD;c`^hnH~@rE?*x!_v at j`?dS1~8M&<0TQMaqS
zRZ*x9jNWeNyg at YSY^4#op2F|y^qYmu_-EMUOH;8Z*XM9*2zX2<7tZ`OaQHcwU;l1(
zasG8ItYAh11J&P4%SyA_>Yi(!DZZ^00ja<_DCDo at 5gOATD|t+v_4O<S&B)bao+Yd6
zL~~I!Dkx7jjic6qk)9s`Bl6W6cfG!?Pt7^t&Qw05tMm*Cd4{{FdjI~uBNdfpIjwTU
zv_nK#q?jU7tysu%xk{>TPobzN<f+Hr6i4q}I9Vsez)|mf15ovl$^Px8N4!);BFyOX
z<2;Qh=WzLc at T96?Q{bR4Rc#YI%>IkGHIM4Y_1`lSHQXG>l~Egbtk0Ob{4tEq$`n}o
zY!jHv`G$Jc4UYe+8K)(Ct&Zlnj#_R!C2TY?z${<A4fs-3aJqT?!N1QCExHe7y1s5l
zEcu-7LGW`IM18Y+dT7yrE;Otz#@ET%6ownh at oT#NvwQ=>j9r%8^hh*Afc>9Y8Guj7
zF_1l3%`wTrpA5mBGokHAr){1{>|hVRAmF$KCE*=_ylz;&Ccw1c<XrdRVAt#Xu$X}D
zEZXNZ(ySt(So$reOWmzemHY6gRL!Iwed|B%h`G>tn?t!yhi10b&H at _QKa7d5UO#$1
zr)fPh?&E4EA(~{`kgMA&ay~&No~s^NjZpgV_b6n48R>J%1ua>5BPf%8La7V_*-dx#
z>FZi`$*-2SS~Kf?NwRnwe-&~G*OjX*-QZ!d{%|rcxNxQzW-%evtEJ3Jd#5S7*r~C`
z06U_>5 at E_MM?X(@q#n?-vTwl{r_w7s5>hSAHUZKb6vVs{TRrrTQCOkEIz73wUBr at C
zp>d&}g0&S-RI9?4ae-~hgLA$ha&0|$i2?SmUz<T411+;0m5jB|1j?aZm9#AQMV>Xj
z-$}YuXAb;f-Xk0B{Ii^NQ7AI~%;<BhmH^v2u@|pyg73J`N8 at 2|VEi9o?v5vYPB at rX
zH!N`KEr*;QnuhQlsRQ}`@o$Y}ADMn>sX^NGTy;B8MvVMhhL{UKUF;*dhw*le4i at kC
zDpgr>W4lCZ03J>7bA73opO6p?>f+(V=DYuXqiG)*o0wF=E^GOXOwZVW11E^->KMPm
zf4+kplWP84>wm^{6M-YYz9xq at E_+vhNSAT-@BxmQ1PK1k>DtL22sqiy(iJhsYrXh>
z<UFQ#L=QE+zK)QPF==#OG*OqC*@dAd at G0$=ZWwGq1kUtE^k$DScXzSxpz<_ZN=6<L
zigo=t3^iQ{Zu;u}gj_A;{hh&QlK{-nt;D<7>H-*`iUYiX41H#Er1x`bYi0gyPknz)
z9vwFLFyAs?OW<RB99KexSxmSSK_bobh%2d8g$M57>yzJF1jBE-jvv>b%`AAJ20AoW
z#5m2KuJY=e+-i0!5%N^pVZAu at ab85gX)gvSXbfekk}RGC;Z~@ShQ;^0BVE|j6`k>!
zk`&LcqUwWr?J<B$bwNV3NAxhG#C$`Z1x)k?H=6)jf;aC6vYs%a72GKa#MFFWH%jom
z8Pe{2b;PsvDpx!ECBrez3h749y3_oM6ySSwX~p(3S}AEZ8+~8m-<G^T(T%4Y#w?Xf
z)zJlzyu2P)ImB0aM6lOa_K37lf_lUJ-jO>jmo0fzBL}`|)H?5!66PE(sp{0VnUZ<e
zo$S9Imn(wlH2hF0Vae1tDJlRr&ui4Y6@>Q+&pRYIXa5VhKmJH2>=O%oO|0bZe`UyE
z6v-hXkBxuL96 at C&x%m#7Fr6-8uX}F8p>C2ID~B$cPNl8Vs$T7Oe{XF3uQoJR$)0ZB
zwBXXlF1tf>KD*ancf?$s;oA<*9WkKx>r<Gz at AiR_sA+SvKYo)5I7T|!Yi<mfJ~=Jj
z?4K(97abFgo*?YJ<<q_mv}+iuAP@*r=6c>4c7TW8m`Q)%Y6jdTS at Vq#7-9fok(mwu
zj+l(Z(tHI;KRda6Yry6x099ZVa`HGy3WxA}W at csWK|VEH$|YiBD!9mdkV|fyR)N8u
zUYvt#%3ltKp{_19P&e-D$WO&|!yvB%Qjz3L8sh94N>qzz7WV4eLNUlsTr!*s>@^T}
zB9JO7^GZKw{3Q{FDqCl_R3Q+ns+9Y_#9&w`xsFPdiaO*$`VBFh-~!+huJ`i$=R7rQ
z)+ui*|9P=CkYIeOo)?_<EP_*ml|@K>p#Y^b(AY`9#(kw5rHO2?#SfQOTcM<x- at S>|
z)(5(6P{ZH4qa^yOPQ#=+DLcz+EQKoO!ks61-Y5(ClJ37WLcGjDG>%eX&ZWQrmUdPb
zK3##-DW at SqEh4j|c3 at ntOJ|=4|NauP#S_-h at 2urjG5YJ50c@ov1g0}L=MYo1__CPb
zH`sO25tL$_L5_&+rd(Ju{owyZ*ZY}18RcZt`jKW}g_JpAa8jknFCcDr0G<T#de!tu
z3j$<xNs*&BIqYCagoLjXXkJrKqi}ii8+O0tKt at jpXG(H%ZI|-*>E3S}Ccmp`oQwbT
zf$7a(#hX6}#O3(dHb=ltAG*&Zz}jz7)F0z~<$EKGr^WP+=N$xjhOYM>97 at K-pzvoL
zZBAD!>b~BKQf(%-?N^Nl6mDbueAzs+7{JyyricCG#VD%gyxU<F2-B|APSd^!1L!Z(
z-AdSrM;;X1fNBeROe4d_jQrXp*!1<2>z4?Z<FL5pDLOFAbJw3=^5oyQQ;7crJ>2v)
z{g<`f%-qTHUSd6FZEf)qnK at WEewq>XeZ0m$qq@~zR^t*tZ2hRhy%Ts{Q;_50B-Ubp
zCntbW8jAGXmA5W6a$xrCg^Q3jG-=^)hFR*%t*9kK7Ky|YJ;rVAOf_~n>s7v>wMiO&
zEF!oC4scb`F*U|xg<)zn^%nnSWTx at 9lauiz#mzfpeW%V0=I1HkwjDu_sE{-Wo>16s
zTcia;sN$?#vpxwF-<#J;H>}K#P%Yw-<O5YV&oYvxv)6+oOn+g(7E|ZCyq~D&9Wp$p
zaB}uF$G^kfGU=NbC9aUc#{*IEtCO8%jKUC<4m8#38d`UEhHz{w=V=NhFWR2|4dLXP
zuCS+Z0g!dPuR?ad<ie)xcZCYcFeCg*O?Z${y9EASC-&Q1e11-l2&mVGz1bP^8)()M
z-(&N`nt4Genj_#quc{r7_V?xGe#LYV$Zwc)JuGV~dwJRx;I~H7_T_3u_9hG$k#jx(
zq582Lnw354Cq4)H;=O(4yI}{Elgfj$UYO}k7obAnNdmU{Ve0;e37Bb+EvD}D00#Ut
z2Bz+JBw8gZgRgn}())3H+3JyngZGui#qgu&GoRam at J=?VOX-i%5VKdh4GQ9S{TlV{
zL*Hdr*`AR;Zsb17wyd*b3w_reb~p$!3LVXp0oCM(&-nS<Hq~TxG?{RN>c2{`3(o8x
z+3wm|FE#Hi<k(<X-m$;R8*CpBprQ-1w`^bHZ-4(Q_;1PR*)ALV at uL2SvqpJ22=%n8
zi<i7}#f<8An+p&?2#p39b0A_f6@&dH(?fokBa1Toi_vIRw*vQi%#K^n$dqaSy{|-g
zXg?UEwH2GRN27Jq0{z<28eFX{*?r=r0Wg at Z!c(-~IkVqU+tFsNapiYc4V|j`I_>a*
zN+t{JH@<KeL!4U5$)8&O?#SKCs~L!Ro<2$*Up67BI>%g%?D>xSr2 at xzc6@KLon at EE
z|MvoLSU76y!~j#Hj60c`E21N0UZk_bDUOYKd%a9Cm1T&}fN^HC!_C*X^`Cu)=Au9`
z=ESg(ZDvptp_XX!B5vZwF8=C+dwK at q3DPt#cmt|x#9|Q^OsE|;_~^+v>90Fh4M|li
zJvZ1ipQ91c9EoQlIkTG;yhrr-qnLo*0?car>Ia!&SCrv0{=jz+FKv1R!T9)ZDWXjA
zJON(Fh9#5bYlZ+{r04Zg`?b0_{%;a6D+F=@r^m>ilehaIu?nUQz^u)ypTMv01%Pf&
zW3K!0-L(Eri)}t0KPt&r*SChBw$I22b`}70S|jV at pXSu~<+>?PIgZ(x|IC_j6_D(@
zXdV3vl>TS2J}s}1pmJN+uaF#CiG%ZHaUHa|cZX^Y9rF-%AWkwN=+)J at _5)+gTc*^N
zum4_}UMmYNo-X9~w&?a2N;ySajPqZG#~@_omLq%+G2959*P?CX_uE*xlQhIz>)!mv
zBv`IWe7vtr5iX<N!9>9^f=nb=;6%Jz<<~J*pvM_dJ>i%2PLJAYw~L!|1Tb9-?9J=f
z9_XT07(9DJFULvx%;G(IjzfV2wzCX$Lmm{$l(Ije>f@|`5ou3Lceixe#<4!4!7o+*
zZ?aV0-T+`PcDEB11PgAtt&i`PDgKFC33 at cD@%a{6!Ekw%m<mxFjmN;(>1-gh<1~x_
zlj{nk)h5~CEZz&#!_y0{+ae5{pvIy0!E-on^%=xxfgGS}ZXly$>4OY>++a`hziT!W
zwV=)4SFywSf}yiSnS?*8OsSlD{=+-tF81nG`z at A@HNAi@&_5b!3+<ossz?K at n7Fu?
z^Gd8~MBnfQ;WQ3^$S(s5*l53mp?Z4O5pCDG-fn))*K3~F9q_gz$t6?E&4VhyuyNgA
z()Rf(&gG&wydSf3XmJI-*_FNd`QpIA?+Wd^jsLFh-y<R0e)gLmie@@Pz>EWaV`R>+
z)A7H(&McSl5KN3823_T5763zf)Lx%4T{pn5|2FPj^+pU0-5K6}X%fvhPtrO}vOv5N
z?m|3CELOr at QEr9*ZBU)CsyQx3#?N-4uIcg6HmOa;J-C>fswXdvh9sO}Acm_=LvEJE
z(0M04Obsx7I8iZ>An#?;92XNt8xxNG{l{x+U6JVHwr~{VQ?@)Ti6ARsF at h0}IqXv_
z&xFSW;)?Eb_?FLndg74YJxxY+4K5kG_bpbA{_cn>qr^zcLC$;bk;w?=$f37jckmmU
zix+Wfz0)I8$yG{jRMu~VO%&?G$rQe&b%(e+EOC!JMwyp at 1=A=njReedEW$dUKT^$o
zog{+e9IO|Zs<PoyaVC0-#xN?KkzhS(o;Z!bFMPdW=6i<mvbzV=5<fU+MtCvQ7!G;6
zhODZSV;`S~RboHf+zV2}`nv_V`NgpC!`Hr729(~$IZ}^x#&#q)Z`t+oiw^m$8qFwW
zR82El<=IKw`DFuCk(-H8hHLw%Gm{*p^iM%DrnUZHN6_`ui=pK9g9F2od?lh<`VL);
z&a2D}{m|u6CZd8VS}x9(HWMGQHDk)pSmy5CvpeD&!19zV9r*CWplAf*>_4Q(@vluO
zT(<3H^uIv4NSOB<kRT1cuqdBK9C at zXI?BWaGMk at Zd`AaFeJAx+g~jb2{(Fh>=V*Lv
zA2TyD(6}b!FScywNx9s)rB^lZu9&MgOC=Bo|5xmt)YCOuW1Mmk1Pzg*JjHPt3Q}e9
z$}8C}tlg-PzYfBlc(t2u%?1acqh9$F%Ur(@ilOXw{c7yV&VA^^y_WtkCASw2Hr9TM
ziUmd2ER-4)W?wQ-h`5fGw2upsOv~D_81D4nb<3z-PLMVJ{8MmQ7(`)ojk9 at GP#auM
z4>I8}zY2Dpl at ly=6`)n&W`051cQAjbTvK4_Q~$MIrP<6x4lx-K2VH+6hVb~Ku{aJL
zL9GMt)RV*}cT?5CCP!Hyl@*k2 at Hy3(ga??hL5dnFx1Bd2wWHVC>w>E1=U4><;UxG3
zJF2R7^WuWD_qw=-kZdhT$a15EpI=*SKjRMLF)uSg!f at G`OW*>+ZgKc7syuc4B^Jh=
zexJ;ds(y0qNdO at GE+HPKR7vGQJ9I%iXH68wZAWWf;Xh;orq_W5={m#7HY)OagtE64
zY^vDi0zzG}q_uZdD{U^Emgkigsd=@GB%e+%&rI2E(4{*N(hhnJf$BOXE}OlSA at E_b
zCNYQBIx{ycL*+jyrH4hDxMux1ln)&31Ce>d$W=Gf>%R{40QkKDt>AJCYt|zZ+PGIi
z*y{$1;&BfGFC*HldBHHPt=|UN2+gT{b{jo8p%|jSYo?MZ9xE%lBTdaspFD(D9uDQ8
z+$D#SQAL=+vy$fYcV!+0kuk;G>8J3SEubS$ST)98c-HTX){+ryxG8r6tiLiZBTGBr
zRTH%)UeEtEL61n918%NOP}1!IJN6ZAX4SG}W!(}Y%=rG{uR8n`48Qh9odBQV<DDPF
z4k|g!q5m(pY^J`0#R105^3_Q>R94$>qqC&NQjus8V(Y)e-;G~_os|D>C$T)JRn at fS
zV-6j3ZsB8TDbs)jS7&HP7^~Qg*VY~?#xU+F;kiUUK_ED7U0LR+H at 8*3Rt=Jf|C(;}
zsB!Rk;spWAJg-}MmYK)5kyzx;aPrKB$cYtXuT$OJNF^qklJbPx?SJr|#jQ;Am`e9|
zsTd%5oWHy5Gum(Kbg&=UXlMP9#vy;l at 0RTw$g5VlWzyaV0cH2yeNg3YBy^P}9{{x3
zHiW%X%2dj>{bCisJW1ogbL^0P4Lq(FrMXg5_>t>cmWR*MOMFC=TI9p}vD3c<7 at cm_
zSiC333#re>w~`yTEkuxOy9;V?#Z5e#hiLl#I!FKs69hy?fI>T92oG_w&sLGD1;LL*
zhtEo)M}@SOcPzN?PG782HWo*;;C^yF(BZ0HGs!Fc7jU8AqjEa9u(5r|A5UXK*FKAO
zx7A6 at C(1Gk4%<X4=~>DHL?}s_axJcc3TB&ek;QGCTpUl_jsZi$w(opU<>e8nzN&WR
zM&j1l at A+(yqckoz8Ioe8?Ik)f at yNb&N88uU*=gj&0M>dq$XDUwT%n(slp>5)sz|pi
z8bZOUuF7_5bOd694PNdq+;8C-aMWseE+qace$lYvpzUHm``23Xal!Oc<{0Th5JN`d
z$}tmVtr+N};kd`zMMq0zGTpW%5%Pe|Ky7>b6q=pmx^r|_M;!2%0OU7dLsbEo_6~J9
zuY5ia6$z>m&f&H3`{be;lmwK0J%g>&J74N`H+b8)?+a0I3?6%kgwH+9F1lM&JR{MK
z#uDK^9c_#t^+(V0W>n6!LO!-oA{J%;rRQT9$vT;Ugj7ke_r=K`vRmctr$3tn{Vqrx
zO3O{F)uzuTLK6!-PNfaIfW;3eCXBId%}i-B7ztfCqLWmc`xY`|LAshzrq3hl>sn!?
zcg1L_DBd>ex4=EJrPGRQ33qW)>!(U+5&Dx(6BaT`g3KX;-nIk=g&YzX#o8qE+K}Zo
z<eJ+AY8iCO%Q3#c)jD2pZ?qLO!_Hb?X=WmgA%b}yAWu<%BQKgnBVweXrkp{Sbz$u|
zZi3&coWH3|*i-j}?0RUY;_(^6N*JlV%O0lXR5P?ayV9 at XcO_!&#b}(tkX1<6!dO(1
z!?ygwOZ7QQWTLEeMM6_?QQ458Vab#O>YVs^!v6y`^;N{$__04a>B-R`IYJ3wn9U>J
z{=D0K;T+oI5Jvc8Y(c1u8u~J!9%z(GrEJB%eFYHqA-EORaDHyvjb5yO$B5kYuEbUy
zT734YiZy^pcV)H_s5^}?`ujBT&hzqoLEm&u`j4Z63%NCJ!^<|lmgqbn^WXh-+RU$4
z7BNt9sl$vi)2ffYh1n%`rwQ-fewr}svMWm9<BgOrl&iA!?Rk$}D~`#onLqwdlk{~b
z!p#!h(f!6bi6M)QKHbdm7<wP=>vtHW{B_+_9WL1n!mp`byDRLQ{EIzk0rYGXlItYn
z^XCGHAlZPeTHeja_H{s;E*v%dX>qFu)A%ef8K>~XM2%2OP at QLU>E(bkuMO4>kOqkM
zAgT|u{yP6iN at FY(YD#$6V3GUy=US6~O)Mt&s7h=AAV`5g*D>V|%J)C430CYc2T~bm
z*ne))Cp*!qc{u}R$?f_y9sAzM;&l?O(1ZrBjl+1#eVo}K)oeOFS|Kd*Rhn*oc_9vj
z at JFjMu;I?vO=gpIM at HqX58HNGyv4r9z^(ZVM!Ue?w3(Tiy8z@}?;c(GKxw;6Bc{3B
zkV#As$e!@qxSj>d)S at w6@@)Fa*a4c9I%I>Je023 at DreZgEBa{C=<TtdL`9O<LAJA5
zjb@^EG*vmsHcD#DI~oF|=hU4HY=b$s8wWyCt0f}Rvfko>prVZ7w{bk;9?0Uq9 at FyF
zZ4G at 2qqYWPiV(_2u7{EC&Kw4&LaH5246#6SKxml7%}ro>SAPD{oiED~sz49x?zwt4
zwr-q9mXk4}G`gxeE!^49gb46DI7$f{Up<T<`;fl=5a1`kfz3vrr7$1oKUAMHZuu!?
zSf8%Zk8`chOgc?Waj%2jy#nqqUy9C1Y$EjwAor%Cx>UvyGrzW(1{FHvy4mUp7vo#T
zgDix5QFi*su($34ElqQr#J?SR)U!M`i<_4wZ__r|f|?IpY6$(xuf70bJdEya4OiaO
zM+c9BxyL0GsnnqWacWfKl|R}OU>~6!RMY2rWT at 3E&Az-oz5pm084bLC=L%J!`{1P8
zlHYVlivcvi#gfm#o|2%<hZ^~rOhP%wx$wTVB4JvvtE<iNUu;^<D)3mml)HHQ4^4&;
z0Cf3^oK~hgrKx3{QQ4*hTj}(nFJ8W{d+6imhumLoZzo|~jNnNnW=@yViz2tp(-ZhF
z0CvkZ#3<<8BG%%+_3*v-?!D<hR0PMozJosUG+-7mq{9B*z+3Xv%r}h94{Ej?-XgUi
zvwYhet7?fDQ)hI-sxxE|4~%3vKsrmpk*&HBX}yXdf=da$-VeR}RV`I#)|wJ1!xni(
zDi>;(hzuRgX$g5@^9dQ6evD1pvlOE~hVc2KxlD{rdfq9>)>W4NKVtDJI10FIdDKK5
zEbk5v4_BMD5Qz%z2DaD{Sy|iKT$L*hC~UnUhfZ6}|GAQV){=G~(v?W-^gOO!h~ama
znBm0MclRqToXTpK1Y>+<iDZQdJCz99!o%{V2F0B at 3ounh0n0rdf6X&A6xlpGsUbRm
zSyE`N1uq8f;dmprwV^L5C`=7M_%S{N&n%)*Ki-uX!wi}yqqGo+7qXWX<mEep+znoP
zgEl7yx^Bgl)=9Mw81pQpo0R$0w&g)3*B<1l+p^l!HHAh2%%D2QDu}l$-sl{l$1%^y
zMlQcD`E&Hk-cKWEF=8k}`q$fz*8V%j!|R3(DGiOf{r`uiv+#=g`@X)?ND9)8gp{Oo
zNT(ozGzbhZbi>fyLwAE9Al=<L#L&{+AUMRp01`g)`9AA6|G<0Ay6fJ1&g<^8_k#bX
zd6Ci7tC)d7u_I2~v0!C|R<~BS3NKTcJ+VO?^#YHGTi<;`vNg6|@zDFJEG`0Cj-!;V
z`CA9{Jr)-RvI+#5ln1_~*M%tvmWSNOSzlfiuuIO$&fJww+rx4Vk&1zi;R4dQMs#I+
ztenbawq#^5cecN6Jr6j~I3X(a)g3atQ0DVU1PdSX1YRNTkD~kK#5J~7#C)A|iuOtZ
z$(iVlf@{hn%04KZlNmTc&pWaK8PH=Jv&0ext>~CG2%9Wxq!kMvdQ*=hkJF<4(#J0?
zdc9cs8_r_vPoB!3*qzW{&uQ!<fr&5LJJh+JZ^v2VCRPWpn6LF4Zz^`Q!QX7`!^sa>
zEadw!KgFw2XB_%?8VPW@^4=EWB*Yx;tYbOxaR at Ez;&C?w!T}$wWk|(d*xx&`eY3vX
zXCbAiK?Szx80yxHjn!+)2B?19sxjO68Nv0B>n-on*J(9l<&?IpkJFA{3m9NNEGkHa
zv>v2ZJW!H<TGrVg>mtw&<F0q%{L~3?(|x at A3PZY){zydI!)u_nR5UG$Smb at mo><za
zo2-+q(()hS%h<u`II9#jg`a^<U;mwu0GEpH${H2l1Kr+UtI}n$6>ysW_)h+XH)sHR
zGEV%>G%_;8ljJ&t!{nXbZR4p9iIm<CK|xOPrGQ;zh at No*ozy1!9noUw2u>(cvAIqq
z=ILa>F*5m=d;ELW=?K3`@dDBE$bO&p{-y!haJ)*)?V2%&A+Ld?ejC=jWYcK()57~y
zMg^kgUYcF&#^0S|<iy%&XIf;Aa6<yB|M8?oaY7oUr at 8V-2c#Vf$$4#k(ee=AG at s(y
zfSDOi`ods~;V<BV4s6GE;Gk`JJeSC4>eE%2gkH)!@<k01=}$>#qSp^;+jjjF>qu=Y
z%t~?i(~SDBUqnkl1wI3U-$?IMmaf`Hf8m=4hwdr4;l;|Do^b=grSb*u7kYSErAfxV
zVZ0kQmF^PY7ppJn$G&*&4NX^w3KFlM*#CDvnFK!F&@egG+$-}q7_WZHmixFi#a5GB
z(CemT{=e`kp=)T*zklEQh7SJ@)`Uf5k{W=&HJL`?d~Ya6=PS8Fj?)wjJXCglXwOGa
zgZ*Kos_L3R-(Ym86kiL(Nl-EO!btV3{Li6!i6#bh{@rsHt#}VCb8dnE^?2lTjY1&z
zS<Pt!UoSJ7r7ojo4ayU2Nr(4xcXyXf_Tp9Zu=sF1GK9*rV)la&a at ZP5!d!e`m-98L
zr_HfqKz(5;>sT9W5$Y!cQJL$=4*=(hru^h`QYNv?qXKk_fF|Qm$k`dl$fznwGH(6(
zkCv~q*tR)M1&*`%+Q#?U(bwcV$qk+V>vcAqrFwt+n4 at yll~2v!)#DwqaBP`&^m-2Z
zI0+dlThY1Gr3&o(&-^xM+AdY-ek^?a7~)dGAmvRzWqj_`b4@(k?rE-#b6DoyypUVo
zRWhyK-z1*IrlH4Z+AIgs at fiQp)<j-u{gb&S1~N2_DC~?D)&1|YhGZ?*T4BTpAqH^E
z87osEqAbRyMr^@=NqV&fc4KPC;&3%pq2yKVL+tg at eY^R6E*0_Be=4 at Gy!d1PKfTR<
z8a8`5Tl1SX at JG<sNQ9{wN#1qZ3AJ6IL+$x`BYoMW8BjV}9k at 62Kn2BoO(aSx(9_6d
zt^e{L>33s~@~L`4){g0nZRJ%`mxcwG6LAd#gSPgo@&9~(-qPKV(u%9p9LxQ9$6zmA
z&p&rp5+B>E5uh13FT#d4PA=V)fOtKe|BAuFXTygb!Jg07GgD at Dipy=no0LT7z__>m
z-&lih3yW(QH#c`dGEctwix{~#bf20uPHlbo(W?nc^^wXx{GB9^;wHcP!Cil$=u-+d
zW$lhtnHuA%?kQ*$Ik{=f0e_OsoS|CFXqQr2YgqqvU~TX7-+UzHA<lC#h8pU1pO{wQ
zo|6u}yG#2`GS8`PZ2(>fa#zv4T|1?mv>oqi!MfDi)g{QQwvBzHUmI|9^pn7!%*{E8
zT{Ck3qhhEblQ|@YeLf$xF#K-pOG)fWn)#x!;^?q_Yo$d$+TueEWGc1!Y;|}VL7yJ>
zN?E(b)zkhkRJ_wzOBn*3VsgoLS#hZ!2NIQeeXQ*iEWms>^PlJ|;F&BS!2b~}84!g}
zu$RcxOTPyUgaMZnrLJZ@`~xlro)G$3=dpJGYWbW%>vF at U9d1={-^xn*>kXMYq5-_=
z?-Xy<;_JniuzP>s4#SV1Mij?cD`7T$D-<R>3o_;A3f<rERe(*(>Be9YAz~d?{a(h#
zv7nj1F!1A%Daf_6gp2&`Pp`Gii%OFvAK8=Ngmk1FV0lMm)E;qCVyGPtH&J=ps>kv=
zHXRwhRoUmj;kKjyKv9Y|3{EokTT;!sE5;d_+1ZJvKdzws>9n+cg*_zaW2+-I3%i7t
z)_%n)3|>ZYm;WM&hJ=66=4_9JLBo>LD&n>PIsGVS2u<o?&6*_DkB%X*C1x?3FkQoh
z*eVkZV*KzhGRU>MR=)UDRA?Lt^ge6yR- at Qbw*9 at z*!cnUHKmkY5v+-8Q;UomvyI8I
zAW-FUGyJWUJ!@(V*$X-8nZV?NmO2~-6il_m2&m;pFXRetA5OJrQC`~4;B at +?o9A#{
zc13C9otm(#>QDHMt7q at CQR$~Ss-(A$s4)UnznwKAL-?#MISgAnKOx`+V^v5K_?zg2
zK=Y?Z?#D;u)c$=|p2hF~tjoo>qIateTNhb-?ubu+vj&*cbemFV>$_L%<#&{BI^<un
z at a4<utd?C_zpP#WV4uqriX8zN-H@~gSvq!0H1twuPsO9Cbg#Qxlj(o<vj|odh#w8A
zS>X4ou%mp)8Wq;flg+zFZ_2wg46uF at 49^t>-Kc2lPuxLFO at 1lW7vFvo_%!}wL~7*w
zD-x`=lwJovt>j<8<;&RuO%?f5C4CqX1ppE=Lt^j&%Bgwr(1|$o_t_`cy?s8ZwO+3-
z%3d$ueSPF9bLwwpWdu9AeKsGgc1+g}@3v6DEtk%y)u7%F%lFXaG9{+j(NcLaRTKFi
zN5p_Th_|erspyFay>^v(rL?BRMB`vHnsbbHnPkCrUDeWL9L`gO4C&)iyBgYSdA%&U
z at VR2xfCJ=H-KIB<)Nz}7q}Z1dN`qJA<e&Trg4mj7jyka|E0{)_Zb4k{5sP`z3yTV7
zAFTflWzrjtvG+H7hzr%@M_r60bBe7CxMx#dAen*?vXtw^k6Lt7Hjj>~Z7tXTQ&0Re
zJ3r^|)a4!AkkWVw1gpB~&qh-9hbxKss{fFjR}W<P{@&;O(a(6Rt-i()`6ARa2$vM_
zZ+h|bNFE)z!3Q!*AN-CoH=Jo!;{rtqny`;^Z_aoMKRjPjCu3G*&ZV!E(Td#9P!x=k
zWnZuYdW(yT|5H+Y(#su*dP0o3Nk~eX{O7UU$dxIBMYPK*Wj$@R9Xc(B>_5?`CpC`l
z_M at YeutmT6y_webY9ksj&cTSA%roKeJWM9sY>13%DHK|deJOy(Ey<3-t-uCrBIL}r
z{>yDJlpZM2X@>O2{T|L{QMc%W93^xqy!+_^WGwD-<@IdXI6x&K%M}BkY5g!i;@=D7
zc)Rq&YcO^Dw71OU=FeK|ZR$Yo1&h4?zDcY6B3?m6)+SHoe9J#5Cv(_W&BR|4X{}v|
z>KcXGHAepB)@pl3Mw at jx%Zdm!icRHgS7M!zw&DNqh;gK<d};?1i+45)$yp~uYd^xU
zgL|@8SXrL_*YvHy+Wy~G<Y<NXf+wOs-~6SDSj%hulP~%D-UIt-2Q#BdY_F5)4dl%!
zlUi)jnAn|uLYqZTeK3D|?FJhbeKEg5#szf`*{FncjG=R#ZsrygoL9sy=@x9!j^5;n
zAp^pC%)0*q|DB0Gr+xGO*J?!9!S`R&J1#6CY9O>^piB3#+;N9+`nEI(gtcpoNJf3o
zwr(&jyZlaVH0_n9xYwsvQ|9Xr+}3$4(#;DuLVB27c<cN$IS^R{o+6_~%7fgq-+SVd
zRI(}TpK3*o=}q(N$wHsS2>PFq9)$6+geND`dfx?({fk6cM5SR(L8IA&_^B1u%+h&#
zDMuAe&Dgefwxna7i04wKDGy!=ceS>?^fd<#QlgVzPoI^f at m=NZ+mC#(ZXUoA;hUJ3
zZW~Y;Sn9Wc^cR@`N-OoZ-c&DGW&}0fjLvl0)baxu`LR#>o$UcP#jG|4;yFaVRuQ|@
z3$JQFus^Es^`^mlCaOA_&i*rASC{T at 5^_`7&Pvm`|Hz=UF+*Bb!QfMFZEMjy93xw8
z!NEeT1N=}L`6(dr&hQ{@P_Wc!_C^4dqG-Oh)Y70}uEO8(e${BOa4OvotR>5GFOL+?
zsTZuXudT9pPj)`iJ%wkBDJMFZGxvE^`Xq+FZHq>VR2 at axI~@h$NU{(4`M*2t)_j_J
z`qLo+3e0)vX|(;MY<IVebf@*$+aEb<=6CbIg>^jcvo0-U1e_T3ef(cm3OW_iiRe^l
z)9ZV3R>;>*Qk??u>-}goaCo(wJyFWn_gq#pCNg&^Eol6OO}<QQVptxv6L0S?5bNuw
zJ~;nK2i_(OB0Yv0=N9n36~N$(20v)Xx7E2jOg%_mz*Xn-OlTFORW9en_gbeecF8vW
z9FRq05OoOdoXk=F^-GZ<)&u`?wJ1HgIr~LH#?itAs`%jW_^ac at gk-B}idAYA<KyM@
z_3~^Zi$QQit{_%vSK~%avfILGw%BX#`GA4L=;>TzHHcO&g`qu{V6>1*y~BywZE-8q
z>9@}td*8w2qy>fr%;sTw8{gywpP4U4pSe5FTV!}>7C&?notE)s(4=#57K}uvC^nE(
z-I|vFoHHk({raJF*zn`p`hw>M-zVEpm>K&RGN5@!buzB at c1<;m>7jLbjl9ym{e9_B
ze*Y8hVVSOq+tO2Re@}D-=IFnP%}&V`&qYu`um9=1zxq~uygL&OHbZ~VODd{CQ&R!G
zmc0i{BC!^TTQn=1Zp9b2-m%`4iXZH0%6w_jka&q$;#};@Wm+uSk)Sv{@-Q?RdbFeK
zgLR)<ST}q(cX|=%|6qfMX7ACtlwC9;T6w!^CvmDj4e#{hwtrE>!eG%i5PmJNbQmM&
z7@)*&pl at YoR|&sWcVBnec}5@*>24_26a^ptMb_8Fn*WBcb at s_g^*9MoF6b>}E|pe^
zmEVUF=oq)pVTL}<(gB~yabZvAvDENlZwP<vQ#yHw>FmY%b-x?qzSn3)O^b7#-s^u3
zT4zlO&PC>4UNMVa37{e~ORgNg?34#v^bZhje5Gpp?0UMTkq_JRiXo=QJ!ZaHLo~Fs
zwEWkS<y7*1mIf~YIp#|7Pt<3!Sr^?o5a~zPFGLjM$^WMXK*1FsH;%ae=KlEWD!cJ_
z*1fXA8jq)6FLCs~4udov^I+Y-^wF at Rye(`udo>Q{Gb`R=IhW?U1?*~#<L;;6vrk#_
z?&ei$g$d03Mol;M*d4f+yzAo^KY#sbK}m at o3uwn${c;$Osp31cU_;!3Rf?Uik3~*6
zaV$#in5D1pF(}ES_8Dc$-v8>wq(_~sO@;1dgI-AH7>sNsIvKCnIwSO7$tu9RUyVrF
zlXKE~tdr at A!pE|qH$`0cO&@-lWMB*H#-s}MkF~TKYo1zh0xs#Z7<6R|B&e7DsYdkl
zWk#n(BUVJ<kf42Th-IMblF`P#){=t^Ebrjp;8DTdq|+|R^JCrcH{AE75L4f+&_?eD
z=11hxJh`Z+)QT>;*tEwQ(#(7LBWQNtE;>B~*G<<eHfrd1kBjTa=)hFSXU%2AX~+-^
zpUGgbOiUG?Q at tq@SEHO;5;9jdt8CKkJG6Nv2-^EmOCqd{fp7!jRpYAtfT-H#3BJr*
zS_0RB at gI#V_7p;2j+-$P?nRNdi!@|pZ~ru#<DfzMTQ-Aa0jZev-_1ZauTId`lneK)
zz-q$z{6*;TgiDSqj)x?9GN#_JFDSsKs5Jkpv*}EEtHI5??)?p4lh;C>IhH1p=ReGR
z`y?tWA}G|>$m_#*1jrasb%2JRY^~p-ZW^kWQ}yIdf2`pQ6MokLgM(71Q78E{&?rQ7
zIsF_Ce`dZLMRjEyv_N#DUhZtg*5*xGHMh1d+4w(Lz5t95wq7%ComZ`zzYw?3m9u9b
z13NAVa1`kU%)mp?qvc0g5-c_%p4#Ki!uxEw#i_O)>;+Fb-$bNe8fo>kTecj)p;RE0
zd6%p$z~%+D!ORC(UV7)4v!Ge%w|)7!xj2}DOZQ=k<p&HDHXJ|E_jI(ho=Uk)qUCqU
z#rbc2dR((=rg0x~+li`%&(^AjH;XsoKr at Gh;K2*0o~>6Yf|yOf2<BvC`(`yq1981y
z5&l!*Mj`jeI;JFy`*v4?r#A0Jx+yY|&p*OqoRDeam?$t4$LvnnH&0|}NLOd(U^Ci3
z>QlSWdE>{^j2{;d{o<G30c0Z!%1KA^*-38ahbk1==Wr+vn1Z+V>@uaGHJi3y^x<h|
z$4rqo{%(vmOkGBqC|VOAA73<@I@*LKI`$?Uhb;XZ6}w490K4^v(o~}WWJ#GiP{VJq
zai^Wwm)Ni)czb!0Q9o}=4P#GDTf<X!Li{B)r`Wayp<1b%{D2AD$lsT;q0kWv1((UI
z(DItTW-3LS{HU>KaY8CQ%Ek1lc9AS%QH8bae}b9`zSCrrILbbGUiO)4%6gz=#pYq8
zSgUGmhu40JhU&Blem`b0w?o&RO%N;Q;n=QK9x at 79&ipyrd|3p948L+?8Psp#JNo2W
z8T;C at 9~nQq2k0KvzYOz+EPK-?{@~T+Qnm3u2;*$Py3d2VHCnWHXBcpKxB5I3OZ_dD
zn%d)~Oo;Ed#+q7D>~8T*U{-L}9J|!089t1*;GH#!5@@#CkQ5d^K0|jljjbq5nGYfC
zN9FBeKggJm=tFN!&-y9ChtS&FgtDnG at V**DYiHBhXKcTpbtf^p;OCs84gFZ(4g#gv
z$L2Szrqg at cTQ_RLQ?L#t1j`jN8a83(KQdw#&Y)bk%UQnp)Mk`~i8qtMyw^R$Qdiy(
zRzX}L%uH{<aP!${(-6wKjVe;I&e|g=Bt<PG#>-~}*W*j^5`KuzT-U(i<XD3(^XTay
z8p<&GS;g^vy at WG`B2w)DACdXhjDzRx)u&`Dgp9pj7Q;GRZa2e3ecDr5$7~vzIOu<*
zYlJu$1)&y?YKXE`8H~-{=uDxc7zZX%mfsW)I6aG3<9<tC;;?OcxO~fMo|qu57>CA;
zP2({dPB59W6a9(<iWHPlSrHvZLc-am)n&bIsM-t#7k;xiL|6W^xTpivbZs846Yh~B
zQEX5>LCa9d at wYZ$v8~a20omVhJ|!*sR!g(^-(ERt;4hAcK0gN-cX_!`fC#soHx~e8
zC3mz_8fEh(4e7UEQ5KCVtEp8!ADZTSYzEK`NuebUNu9mjgv`|r`ZnE0YhxJ8xDTQ3
zJVX~Lp at 2Z31n-i}K#NnnS0R47;J16eM_ZG;f_~I|JpgWa0h_Cv1Cz_y+Izl-cFGPI
zemEEDyDwtcYSulU7!u;+ZGC+^Wy_r*L&lhu_Z{RbDn!xY4yws6wcr_bZ6XI*+}|=>
zm#Fn5iZb|5Q)(<Jt7~hgLyGiCbG at _Fl;#GMZxn1ObQE2JM1G^KZ9pm>c=$1#fxt4<
z4~<q$p`t9YlMd^mmh_xbnMP6C>81lR7L4z1KJn^*`s>IRpBN>q+1T-hV4aH_ at R2L5
zPZq=&=2y5D-Pzfhhp_139P8)pA;n7iCdg`l at L@<|*#6)LX74c${1o9<B<ramG|rdE
znY>=vt!@yJVKRgf+Mmob@?;Q at 6&`iYVy7`I%#Bu~t-qQS2nZdOf8)KM9u<}XPZ8x?
z;jOoCNfDrux!)xBJuHXhU%DEu;sgt|sae?ncr}vhTbFfAB)A0R``^JfMNByu6zxQ9
zM>w+ at yg^7GBDm-TC*k6?k4jELR}ictYwv`0N66Ifn5Cz)V9;Zg6r10r;5ahLJmUEl
z;<zg85jtPxh>3~i;m7;`J%oEh6h};4jB3q%IXE~bP66MTB#Q}^zh~Ds|BUa%h&7&j
zWiNW-%Nn3G`~fx}W3Rw&Ni>>2<yKa#^|iUXyPNa9ugOJTY#cESB;vhJa+UC+`|I^b
zYf*0|4)<%NCTe63sOy)HNh^3LWIFsWnPCTigS7YrFJRt+U0O_1L(PZFP^-o%u|39?
zJ#L~BfF%Fou2tW0kg)YGSXo=xnVz{5z-M4KcJWTP_C5eEm&{>?j&9KSn9gy^NyLI(
z@;3zg1Pvab={?)^Ing at l9R;eb&B#9H3TDJqq at g{jiZf#pk&iePJN_f>MTO33nlFE;
ztH1w~ULA~Sl6=kxtvsD)ww!b&b|S`J+s-J-w879sq at c6lt4_ybLm|TaC-qU55DWYP
z&Y8$^SYk_Yw2|JT`+_R!AnjY6Qd at of?5qulId1ZGNSVuQME+%K^qOZ02i}LuGU&Bp
z;59@<;vI_5lR)eef;e8ol|X&K_pf&*#I}}1w#wKWIK2lydmDk>`O|VJ2AuX0&gHWw
zvCz-?kjbF13DCk=I#L#F$i&J>$&8Rl4_w>Y`X)2rfTbR*kR*D)a%Q$NIes?^2;3P6
zk53E%yg(@Dln~P~vm<XeHxpcf)*azJAe|)UUOIhCd9x--Xum1j-C*}?-Oxps?-|~9
z%d~)rZn$^y$7zn3yrH}Ih4b<PauR!1tdv>&Jf5Y_7L0Q0ro#r1h!$q$fJQOFi3qix
zYaQms^fpw5koSC2AS1QXVj5Mku^Haps43eGM!@%=&rW=lp~p3$sOnUr`lU;#Fw)FV
z3{SfT1JhY-dzORBs@!}lqWC2$7GFAEQ!@Zm8%*QD9*fu`aJYVwY0{toA0F>UwF*&j
zb6?h3#AHd6y9|VHxiv9ZgwK&9G%ZiPY~pCD+c16YSpjxE+dd%6df9k5BmB~8v+mtz
z&21AkS2bZ4ZXXry(%)GeX70SiuE*+BTk=SQZR!0+P)a={k$y-26HAI@!AZjNae|w7
zTd{O(U;cjcYCg at OSm|~=SYZ<q<y7 at vekrJV)mL~}3A9C1x2g~%L2xHLEWJy1J{w=l
zxn*Bd)=n53s=O5;Y&Z;!$T{Sz6B5Co&t!?WNH|=bbZfSGd$e-2+#3BdN*Q|D?AHL!
zQcr~j3U<Xjl)VMS#{ooGMbY4g2Ei75t?T1Oq+@*5L7C`py@}Sf;o*js at wIyfvJ;=V
zCfe2_HsAjglQiG_K_NQ5o=O0bQWvMzeSoW5-1!M|Z_n_+;+ at VCQWYTr^L);Nf@(Er
z+<A>}Cx#9ZTC~TgW8Hp;zTrkOChuI8x#MG~ME~ZR7U<^Y=3R}J%F+ca`t>D}?`(>%
zy9PQxX3aKm at 8d;p)YxbudldW9Lufo at GKJR+w1^_4KS=@}!Z7?=Tp=oYmMf(k_Z~7b
z7SgG&e7s9dLO_bo(QzphG2)H-GE`ZJ<6f%km?hWckIuryA*4&$F*VKJ3n=ac)!3ym
zW!PTz65RY;RSMLj`K$^DclD(ht$pwkr(JU9J$ajrT##qs*1W9PZ+ew at cmOV;H#m1+
zeM*{Q3-Fw-XdO45Y8Kp|rR9a`(GerJ|J_sAug6VA_Xsdk-;ZVi`n)+38l0T-&qp*S
z(|lC5I%n+mUp!E5u;9$KEg#qO69`Ip+1J02D_D-LAG_;A5I`|yA=Id!sRe99>Urf}
zuQ(E+?PnO{did=F0R>qVqKBbCSydcm{rb4O at V1hY!&4F9jnJz{bpiWu>2-$$Y6vTR
zG at mDvCS#4 at 2GgY6q*TK$mrJkBD+Rt;ao&w^z;VX&)xpF>bjH;L8*i+dk?5Y4V#!w*
zXK*5Wu=0+P0D*;I4i}v;K|&2G!D~M@?&Qj6$A7#ZIp1hQvh2l8Nndfhj at Wd#YWU88
zbH4-CtU$cEXa at FuIOw;w)$Xn86pFpai|w~EX67bD1DqD70qT{26!Mu0(H5oEH_5(7
z|J3#JODMc0%eS0H%_{<!k`luS^)^>m4IrZn4QY;XQ%CRvQ0H!<a%!bWdEj)HMZT9k
z-%FOHAK8P;2I*_?kp(7 at rtyh6DsTI=vQ^;!&N6Rttf-Z9X$MYJhU($76yyam;gJVV
zzhN%)xXC;>F91x-C at ej^@ofWtiC8B5_ZjL|WO3KFP;Q@;XpA|-r9T=jxLqS_U`P0%
zU$p!{`jP`X{OdP|Gqu?MBQ2DyAvO}1jWqh at qs^+0-}N4>lfHG};5T9$<?v;ZV23}m
zr0pT+p&p7O>9FIwUgK?6#J))v#La1?d3z-(isfM7(K)Atm63T;VZ+qf2+DueRW}o2
zgZX}c^;^_(I%s?e;-A at iC^wGXP%xRv{oStb-|^3j#N+t=gwps9)|_de-9oiiWp at A9
zLLY~@WHC|UTx5$(Ygb)LD`<>Uvq6*KSIDwg){s8-*wZ at 1+p*iXtRJ~SzF;p#6^JbG
z7IIJAJF3orI_J~G(8Fbs^5V5L2RoLWwI2Ktu2~?fv73dGwt-b4t=I^*eSN40;A0Zf
zvAt27c`WQ+))75N7F9W3y}+=*(a_hv`=^NV)v^`Y9Ck}RRGm at 8i9`@|^`#>l#L}*R
zqLJD*_uo!APJp|AmInS|qW=(`;~G!z-M>>CPrLC6*n;my_3DZ#ELSwKx**}?c4
zYVxs9$xoJH$qz`j{w`v*e}gb at e^f6(MDw*ynul&5&1<)?m8IxEK^iMoFL+;kW?_M&
zN`wNFiH7?s4Pc1FQN5dm3r?aWfon$>i!a^+c#uyBjd?}nO!lR>AQcrA#H+!`mt{1H
zqWM)jQ(;8D2m&=9=BtRv at wQB=(th}0Ibh8o^kO~wEy8_Z(oN`=oq00vhozC~+0kL-
z-s5);SoI=Xa7sJjNuT2v&*THI*Y}+L!es3&EuPTt8|E+7bfkDxMSS@}(3^C;aW+%+
zq%^Er>AX#0GUSRj_zBo{?Vowt)sAhMqwyE at gJ=j-_C at r73}#6x(PqhAOigejhqjXz
z0dQ5L1qX=1&StmpyJfymS1u<S)9XVk?}n=)(U&C#Y19<5kmFz8_H&96761o_YCzN&
z*j`vV`RPynU^6^R;MHE2kW`LY$!iXH1X;H{qE)R_h>-Zn%TX|uFSYT%j^^*4IE})~
znFZ${+nTT?b4k0s15Sm8gnEsvGU+;)+ at K`CcF*KjXGILG1~ERw%G;j0Z)->#o#5ZQ
zvx at l6uze#5lo7v7Vwlq at U>vhU?>f_pcqZQBsd-~=95&LFbcZF1x}@Hp;M=IkV8TI7
z#%*%ub;cwmRxM(miF~t;^#`Z-f!gLVcZU^9x&Fz6`Liz6zYBKCBcfdx0R+?mV*b~-
zYmJfk(;qrD56LJNfk|BO#>swVZy*s@$JfJju@<;D{>YTPHN=q`qQ*bQdC#zS()Ny}
zhCwA=$@3tOY%&j>6#f0W-bWK{md48}HNg<UI!{>UT`;`p(%<w?EP$zvCQgBdn}moB
zaN8&CD)sDdQ0A!Hpk$!b&s~w$X-_ at mtzpH&0XSM@=MLdeOt(VQIePz+n{xUD$!_yF
zGY|!1_9pvP%Mo$~Yr*)7dCi at ByK-aHbWZeK^Ge+2Ec5sBe27eRal>7%WTp+4X|Yx)
z64OM=0{l3q2WZ8hs;$v(n}>(iW3HgeuKSL)18 at 0-kRMU|J-R^H|8`6^^y1%EkAEle
zkWYf=<Di*%Z+kA{x~MKYI at z0kNa)a2__bNWphmdqQh!&d4T5cO8JFRzyI$k$&mWJr
z at 9AR>mqtQ at g6R*`0XAs6>jeN5UD(sZ*;@IO&GQ#9D at s>%J at 1>1Jx6Ym&OugjHZv#M
z9MXR)8$X|(p71q>06^~pQnP$H$gb-1^NRgqFpO#}HQZ!^yYr>#u#nqy7F?O5j?abT
z at F**Zo*%M4Y+<qntgT3ou@?smK#?&tIb`uqU&a#Jfe+a5Y|*h;yyCuMeUL=SueNuR
zd+~8*0v3<>dR(L*Tl at 5z7pO+XX{u80nIlpox2r_HiYPTGl_nB2%>>i6jUg|wHjO*k
z6Vu;vr3V-Jgbbu?z&~tSNA<i?Y>*LiY)4hYcfs;2&(is7v|_q#xV7VBnGNfQ%g*`U
z!)_YX2PLW*qRu?0g`Ea_Ep1|gh@@b{VW)YA at tDv8L)Q$yT0wKm&8AU%^{{mx^lzu~
z0+#(xoLWSA at o~)4c;S10mEz|o|2FkW{%_0J)8JE2?KUG<#h0S6F+F=b-?we at 0SY(W
z0&=m|sSL&J91*S(C+#v)qKhDeW4>rF(ipK442l!LIq#@Arv7fKSqpWsJ7D-ZF|m(*
zcj1k at 8wLQBZh!y&-QYag-RMLqI(^6IiN)-l(1IB^oJ>vSLl6;o#>jseyz%GHKfs#^
z at 1J9I=Jp#0b&NRxv}9fo&0PRdM;NEU>x|{~I?=;sO$tZCHZ4UI73f&k53PN)1($m8
z++jY|mrN1#E#w at Uxyn%Udl|9!h%RwWuFS~XapH*brt2yPTe+L%mnE03qx+PQ%o)Ca
zI_v_{UZA4n3Obz+Z%vy;wJSY-%MA-F>@oSDt65<_V9^lL8=5D;)#v(x{>rP)7o|F}
zU<+WRj=@^^gq11-644Ca1tW@?BR2keIG;J{Pzt&{nQW&V^>>-SMm-u`zG586bA?!n
z=Dn|<P at ikCoSryPA$PD54PN=X|Da_eVpv>Gx;I6=Y;HHoAKwFVGKGqOL^cE^l>zy9
z1Bvo`cAu^RM%{#YrKZPJOTC(%zMVi(;or!Tj2mLg^Yc&jpN=m7dnoDKSW)NChs}!@
z<w(V+KRY-s8kZ+yo;S$y4lkJHnPFL|;e{m^*)1pUSv;Qf&)fEtm?Zp7ynpIgnt$U6
zA4)J2I!#&q1HrNYJ(}nU09H&=wG5Z<v9kE<m?U-1pl=i;JMpigU+w*oSiNv1`z}#S
zEtCV0eFW(Ba=kIAe~b4*OVDUY{kVHLb}k@<e6T>seX`)T8<?~fV~?0&@Vu6s&OH(u
zrI=IXPHEat<JDbXr;p~xb-oY$9`X5W-fwQ9KS8a`y=R#D-0aeC$@U8;$MMF#Dq($I
z;Q0O7+RYFpVeEGh*>KX3GNt)`5O?<%BZ^i&j9a at snO02x#wHB$tOgNICbRT!7_^p+
z8bl-&&+6LS|MVC$k)DxkUBcT=TxMtT$%w)N-+{w9&eUitd)|MIGa-1~pY{PpDNv0N
zI~yBW2>q#BHB^5BC;3gBLh<UxhJ=;p!Q?pkmqLK at HC)VGS%Vm_y29$@_oB?Uw`@_W
z=$UqTZWn9+FQ)N(KNF6WG_4(eesbL3B^lo;YP;?ZR`m>Pck0e(kTqH^az|IhAHsc}
z!P5(~vzo^K7q(ne<kkxnCTQVjsM;Xoeb=JB!ZE@!&R;}7iFq0 at eX9jevWw~&KDK<W
zTZ-P;-N8Ddb)b6Ti-MA1J}vLhPE3Q~ni4CtBxv}YiW71M7>eJ-<g%Dqg*5CXKhooH
zl#u0itDT|FQ&J(U$;dX4qzq at 5^-y_4D*Bxbv&-S=4E>8&N6Ry|y(dx@&-Dix8!ikj
z0=QEf6#}T}238*JlarHE;*Ei?-SX`w;?-o}8%YcZH^1aWS*jANbu|b}lG33RovM{^
zzr`WAPoKplOS+Il^DBgiL^cd-`KqX)XvZ at rtyM`NmyN}Y<~=F_?{|PmmfQF3%@p8n
zOsHY&yP}ILN>ytv7Y-h0r!FWyVzRY<g_OHPjHM>swDh2A9ahD1$}hP1GZJ&x?$%9F
zaibwMU1uM at DL_=*f%LG9jEtl?sI4OP))cIQ4TR%N*b?G6{D#l_w5%F)%)Z>SxgwvN
z6}M}JwtN0-T^nz|znp4|bC4Gr896s5#XRE&ypBRL9%6>W9^y0KjqE|K*V?#|gFesq
zN2hoi;`(bD+`2c;jmUCNE0B{E+~M*>b+ZniUU*9&HHS?<HGb2{=k#o at g3B7aJc_29
zu at Z@th0UL!k)!1CeB;RRDR505?wFGNXk?{HK|~`e_(pi1FxNEO0{g at UA{8OW8aZ-t
zDIjUYN!r}mxhCDW9DqU_^@lTelsrwk%knFqs7x$Z6fuPC{j$rs!d{{tlEcJL=Zkc`
zPv%!=l4;T7Q51Gi4NBLi%x3J^F;uUjhNdXBliPepfxH;{Wka_kEHEioeW;pztX^W~
z1ob|Ajom<8 at J4iWd2Zd6RmJ9M$Gg8R)SZu$z&blcj*KpznIFv|7kV~IP1YGJrlp=A
zd5<9&X3pRY#>-R_%`}J*^7vIYZ&O`W#Tn|&EvhDn5gwE#-OQKK+~@rQ-}+?qVyj08
zV`VPhQOckr>0fEM6-Y<Jid33aNbpmG`K#z4j#r0dNnhb>O!^ir5!@w`Jt=Z2)m15*
zA?fu|?S}Fh=AwCv$jEdtsu$E*OpWb-pc5IkJlmWibGQPNP2z&;VP3q|($g~i!un~@
zJ8kZZ!@5k6mG?oaqec9rRU;BJ8tNc$L4{nO(s<I)B%G?e_-GSOO?^&(^?faEv_a;`
z?oh@<7RvsEbilV1dfs<Qf1za0S5OlvW7M2K8yy~%TBd4%;S}Masv~y^y~-Vxw!ddG
zC4ac>HKgn3e0P!0A8!aIJ)A9bPj6|RWF1*G-~Vj(qNSx8Y^3gOGd)BpB&Hd>YEu{y
z6yrnMn?}tlm#!T4H$af1gFa{-YvEV#{<ZY<^u$sa_zL6+!ypQk%I(`-1th#EOF7sz
z;rT{YOz#orV$v-XY;H~HG;WLlUMAL2reP*Zao<Bf9}R<>g*@TIw4~3D<e5{+=eb|?
z=d(lME%poui9>z>mrKL0ebT++21=u at 3JYUX-`oXTqiw4?c8mTy+}BsA^{C~RYwH0_
zm4{CH7F97;kzPd1y~p~RJn_l$QJ5A7*q9Gfzp+PxH8dxsC0C9N|H!sh_iIwJ-rLU2
zN3_%{UF5Fw+AzzgTbMZ5$4a!Ud{tLq?c-V*-#2*)o{)z=((ZkQcL^n4M>8air}tEP
zF^Q_9{NdkA_eVwmTwHe>8oUl5G**|L&fU(|Jp_%DYaL#@i&hUmUiZmhgi6Pa>`BU;
zB|P5=hQfQN0ODD{oO#4k_T)98(J`S8m|vAML47CjxR=<84rJHMkhz&T!tb1DtdYy(
zr6;n;^2(b!dX+~p(yqRNYzY7u;Izt4{lu7Jgo!9msS??4o2hoyePIv+Pz2fgo$DMm
znRDf_K_Xy3^%y3jW5bKO2&kHq6v_@?tcCIrGe82U*?M!~Bf}~atgK%~;qlA!srb8Z
zVH*~{AYsm;;VxBqAyyU}xpSHK_1_6txATRtx!}usV at UF{sWBxI?_q^yRsOyc=_J&S
zyZEOkn_Lq`#m$;roHjF5P_~yo+|XmNG}aT?j7yDbMXMaJN#yHkcyp8mbzGtFN#}DJ
zLGj_s$py*_!9RMvp6^}=bKhh76F&}4tLeoKv>hYpsD{dzp4d5I`ECA at Kg3u5aoM~{
zKSwyfY;IDMVo>?mB18y&c_$Bq>HB0amM!e&zJN1!EZBO>m{_omA~QPd9R+h}23b<}
znP+FBKdUNk$PH?TUN+yiQ?7|2?=4vWhE}L+S at u5OpXRRg=VR2zM)KT$&8+;zjfO$a
zx8eSCl2$fnYKkmr&D73TjJxo at Agt?2x01}vktr^U^})eGfDzh$QZNw6xF_L*q$uAl
zZHTwY`#<xC_)lp;nQEL5)=gZ`x+5k<UYiG&WscGkoW-Nf{(NOFG}uUkx*VE#H+U4S
zA at 2EJ-O<s}QylFNx}u-l8Rj+gypUu==`%lK&&QzUEtB_2|6mv6Pu3nKSyhOE*BN=V
zMHD?ic3q`tFfd0db#8uHBhlLQ&yKf at J<vMS45W at yeGNGmi57scqy+k6<-ePR%65Ch
ztyno)pt)nN;!Les$E(8p;n%4Z7D#hNTn8-q#WUOJZ$^WgMlL)N{0n4NHGLLM;*HoQ
zeU(I!V;1g3d-93)%V`hSIG2nozax_NU*}Ru4qKpfpi3?uZ6G{+XUNr^V%EjD2M-Ue
z6i?SAKd8Gys~Z#~sKU}Xsu~^h+$+bH-z3`!%}&^IQ#-qy;hx6F5-SnC<aT`&gbzex
z{ryXtwTy&9Qvg}Yd)$H}ePpM at g)W$D;e%R_6<#|{t|L2rhK>8Q`hQvgp*}Yuqu@#C
zdd2*k*qdm%!0YIf73Fmdpi$Kz(SQP#y^|9i$G*W==tF9WX=4LShPxN at C`n>+SRu#2
z(3t%-SM^=wbXh{4g#BFR%pwJK#2q1&_#^R5Hh))Vr(w#N#hB&F^764)FL{e1 at 8V@9
zI4z=w!UuALgtqujgAs8j03aPDLN4alSv%LUc!AK5L|=~vo`PvR5a>3us{#DGkOjAs
zUuso3yOU at g<a3s&^cu=9*w-JG(++}c3{6IqX5FeohMG{Q0tUHm-GFh-E$&6BF7-zw
zT>`R at hEdodRusuw3(mYx#DygD?r1M!(VNtAL%lJu_h=oLg_U&^h{4wQv7z^!p!4@@
zN?oIQzptLi^03h#$A!+~!5kPm@{NhX%1b9kIbrU6s+B&=r$Z!QBc=7phUqxgoV0$g
zSv(0qQd3s?xdhqRn=d at H>82|)4ZlQgx7?hd;lF- at CN?XmnJ8^uWpR0{-tnFr%*DFX
zG|XAz+L(jyy9}QltFIX0TeM<>cm at s!*U|N at MBv1uCYM=QThn1&I3YRJpoHd}ONi3~
z!8S$&M{Z0Z{Q2MMf6Z at W$~$}v;6t}%!COK%-sJ8S(|ksTm(1aM=KxRB=@9CE;fGA-
zcrNH}H$Bbz%AWC=8t)G|hdS15?LVe#4|=ejG2(i&Qh!)bd=}lGyW##ea9l)Wr=HFG
zcfC#wY=~ps&_76P9(2^(DcV()FwW^*6PEY+j8}a(Z8_+ateSLO+;7Z at hA_Nfhl)Vf
znX7T8<#vc+OV0iZ0K)%+F#9<&TG$2UQ!BfC(|S1|ziB%=0GR{5{qXJ$&~2!~ifahj
zA3*%9aGg{@e{*9GZ8DvQgK{bpMUP2Q>$(_lqC|LV{MP=^R68T7u4&7*mdU$E#<iCV
z+#J0QCpNkQ<gH8(R7a!TD>%$?!I^4Y0ff;iS8};n_nTf6&>e>8Mt2WNbtIKEVJY`X
zUuR?CNJ)_!p<$@_fFNsN#{>WhC^+(&B^N1g$W2P|JH=>O221Qq%siO9#WAUD`N-5t
z-->`NCzuo_zFe(yJ$wq8kVzr`oZJ+)fPDG}!}hnhZg-sZ8s|~^^|f!j)dH`Lvl~4E
z!Na at I-p>Cj%-Eh!%qtuQM(T?ODJ}XFE393RM$DY)<07J$<vT~u&rM|)lIce@|Abv!
zEb~Hg8Ke;pbvu@>K{U`t%#OW*?iHs=8I4T{HK!pnC-PZ*r5La)v5p{SGE>)HW<4<_
zjBWM1T2HEXtq3oK61zY~9_f45#Px*xS~BXwLuQ3-?k1%lXRrF-3cA at x*$YLoQE|ai
z?`7i|)Tpf4URp5%-Y%Y*6WK8bzPq0%4R$sfcXIpl2$~@D%dOV)wOuy*g|r`9-0eb@
zVHLHASGO?Qu=-dn-oGU}yX|8TK!>}CtZTYPYq}Z}$wd#LGkVfs^i20OB0n`x4yX22
zSEQ_;S#s&(9muze9a+9?&JqbVLFb~?$ZI4#e$A(4)c2|VGJk0!d>}V+w{EXW<)iQc
zOqPV~i#^$O+bH+y-<E%9$%G at H_3sQ?UGld1xYtYN^Rwh8s<k*4nqU$%Nk{N|Bt8uX
zdqY5V!9RqE^F&#_yFfaoW}z=zfJkpOHn#TmGgrh*;D4AqcM!C|_pH;};FF5uhmSC(
zK}cpFX=P1ZP2eLRs%ZW#hxGTi$OF~cf2}h1Q=2BgpJ4T+bK`;e<Mz|Qo%4ien at y)#
zqh%?6y<}Twz-&5;9Ey7+1wfWd(dy4PE^z?BTc2GvA_f#I?Fn)_b5&8`+S(e8SNqOh
zIr&mZO&05J4YFIvCw?h%o<U3lS{44nG(j8e?CxK!-hfLXP!u*8ZZbl!`eMlmMsk_7
z$HmI`aUzH_IqH&@XpNEqKp;K%DhmRe(%T>3le!KGFTfHy9`D3l2z>#G7<1Z_H5GIR
z;ns?>!J*LP3 at 8bviF&WKnoeMVlT$4`NZG=G1ba2m;+M1adX4+TYz5uP#njDrHR;ce
zv{-XsM53}5lP(~)J|#`8+zrCad`)inkfc|Zhd|Ex7VR%qO1N_xPlko50T=iao{*3z
z9ZXF1Vmd7x7mMB)b0j+^oY;P3io1h@(i3<n->eiyHg?9+ at A8tsK9KSHCTkvx!OKK1
zpU at APXz_zn_;%`s`v9ZZQiJH2Y~#*+;!8)eyDdsF<@H9^f2Udc4DR%MC}+6tmw=TR
z4Ym at E`c#;Y$_XliIl*+009gG at OHk0FwoW4^tvA=YEk|xC7=Zj`@tER%`eNZl(hKlV
z-(|(D8<L8}e97xuj5l1pIVMq;P~S={Muh2Xd}fw@*{t`%80Q?IU`hUU=cq%DMM)_}
zf=>3+uC(9Pnbf}5#G}Iy*1CjS?8h at 3{5Z>QV<u3DTCURL9(hoR at TIEEv>#UlwWyVl
zVuT$Mi%y{QfVZJ8=2C+&+-l64tW><p%$G;|Tba5#du}`ZSCbbAZz)1irK`X)e%XU9
zh1lpL)=DRvU{)J8%VXRW<!Fhzst8>QoY9~e6Q;sOoDM?^v{T2dB-{(9DK(os*Z7R!
za7dU3Y|<PhHjX(WPV+<0qJv$pHOrL#Ur`QHoiMi|(<$)U9A{DV<v#P31;}nGhP4N@
z3PvQ=H^_^wp?m`5cJ&!%XP<(aquR~=s!6u2PaX_#J7wSXr!kXagBU)Y!NJx^(W#~C
zPrg0Vn<@xeQ@=@$P>_}GHtBgRFq-idPF$sgy1Te%Xn!F-EVrTW_zjx8Kk(RTaVM at i
zuqBWL)emtLVP^G)gBWGMFh(x2J9*%T|5evHrOR$juqK6I_z&`QN&bjUD#?QZhisFA
zef8<59H<jk;w^>lNJ^>$EytrZ=vAyZ{WF70{fEesN}A7m@<6+UrUIqaAckdi>V{0^
zy8Q9th#ub!9tZk8s=<jBfU>q<e!Dq7?-F3%PIjJ9m*?N;j9&uYl3ju{MCwte;yzjK
zvdW=lY}se?$LAEwUhgv8>f76t{q~d$T8YxeAPd{?ZOL>FutnYi3Xrz-WtP|3m~B+z
zhW>_(%3bnWWYa&dyFQD#tVN<;{Fxvu3X_GoMg-$XGoSuOQA2E=p{ck)%4~dmylC~O
zR!qp=<(0fu)m&&KbS}ohgy;75RxFL-PFl?b^Yo-%wt2)D0}ih88o2R2%Ze?pI*2C_
zR;iGx8L?mlJgeJ|=IoE&tQJQ&CL3l2Xu`XA^X=&)IO8FE2N-?gbw$cD^Hr<;1IM;8
z-vQ~mh#M-yGx_+_9q}37lp8KF8>Np#a>O-#Pkdzr`1tA>QbXID|NaKS_W^vgOBVqj
z=aGWB?9H`Cuh at uUbw+8ARe9!f03w8cWlNq}_Vh%&j$1D+wpsk?WA4w)&<R?YUCG{n
ziKU)l5o4A5Fr_MFSlSHZ)E&;{Y2oo1Oi at x~=t-ic`mrw3*G*{LT%ID9YEfZb-hSjc
zdxjt34BAvv-F}#)QyEkt9&fCCdB%;?Y=f|IOcN6%t!M1NStg?L*|a2rWKLT(suL-;
zjxN%~(k!X0Pu{%zwD&wuI3Jyyqy&|Jn9<`LV|-Ja9+g>;%1FGATYh|Kx0gkI3e}5P
z;s%po%<0XJ6LqOYq2C1)RkiPKzdS0+8@;$%ISn)2Vy8Z79$-8m+c3g3uvSjzXJe;(
z*PBN)aPq>b+8Lx>^*8M*j0qj7y~GaO?UkU|AaN$j=nqg4>iBDR>thOfl-OYB&TcX(
zuWPg0Rw08AjFXg;IIgI`B)(ZZr?cy^H;63Xf)mNVkn+Ov<fmxGO~H5){BJlrjTett
zquniIeT90*qT at Ksm`2xCJ$E^~kJ<CX at o|++L!HTfCHBtm^SfoUAC>Wbr^Hvh>6d!6
z?!IVGSg3va9r!g8d~dgUAk1IySwQ_S?!5H*pSsmZ at l+r(BCM>KCEZT}LfB^-+fnC_
zW}GHqCCDCv-;UEgHfYMtgO(MNL$gBs!HoB<p<UfGD#6iKS3(JHO*<j}VG7;;7Lcw*
zH}+mWKEWR2mBGjcU9xyGnG~7t3m*bOZH|<_>gs9$vRCh4ksPR}+q0pQ*ySMO5B`=V
zXcqiEHKAozj5j_>3D#CsRplPDte$vDcjc7S$5+Nh`uXP70b at 14!6n|@V(ppot>0h2
zKM_5hQB${6!v}J#orz2;@j383KG1kfQ>nCjGDXO*u=XEU8Q;=V=>@ykd5cI<oews%
zN;r;A=4BKi-1%#PUz^WtFP=EjMqY`6LGnX-11bCHh8I=#8={&nA0o*%@_2fWovmHZ
z3}DykrH3Ys9Q_uqJWd-PveRC(^8#bYzoDV8nyVhvJftO)X`8%bs>2+r2=M=VowOsb
zF-)ZEt0vfJ9VSG0`qP(TRJ{-~K&~md<*FvQKa<9Jh{uii`}glv0O!5UiX%w6dNqkj
z6=W~0fszN_FUOAQiPrNLrv7#GZMixSA@#4dxw~C|aJKu^?7<}X=J~d#l{WB+s^Ym6
zqpsHF{VXd65LIx2RbcCHZjZ;Q4y#qYS`8QF@)5BK?2bi*@6DtA*0y=+*J=B=rWA&l
znKr1Vpxb>}N`ph+J;|<w`e|~?UOmqAkvaW~w?Qn3VgTS2A6}+KyZYOhc5Qvo0r2tl
zI`+?k5*tjGJ>o!@bC{<KmwTnrwWnW-$-B+H4NX2Et2a{wEGJo-`XleJxiy=gSqezY
zx5m*w`0^tq9|yNL^nUiqyN--pjjeZ{u&6UCKj%g1b^K*&B7mm?Gi0#iEjQ|Uuc6b8
zDNx}gUfMXY8aZx-73&Ulu#kS%1P}SdadNYvKfA|b+=3ep7r&TnB6*#CH{bThV@@e0
zq4Mz82M;M6JHDW$or{Y)mXtBxlM(l)Pt-s7b=gs(uz4s9iF~R1D%%2u1)lwZJ1Yh^
zGNwo&-9<hberY>Mdn{Seyttm4N|xw}F`H at _V|$T at hSZ>7r1Ee38t)4DhamzXsZy-N
zaqqpkYLV`3Rw9LCQHN!q9LXNmo#hI at 21C0_s4Rt9bBfz72X`*6!x*-hp!PiEzpRC;
zswY)%08-cP5*IT7k6W1Z(^!FjN5D~NuVF8OAh20SsP!Cl0rR(+NC;+6=(LS&)L$^y
z9NgJ{7BNi)XHVi++G=ueklBh#R1H5(jfSVCi5hU)dj6B3iHrC^tI at GB@?gA3iJQLF
zT(ysf at j+j|eMy2k&X$LKvHyBI?VK{M5+l at r(<eAgl0wY*wpEXFN&p(`D=aLmr{j?_
zF(#P?yV(TJ*@b(ojRuEdm5>L0)ty`jJCgRZuzZjCL;t?zdnu|oA;)Gh4Nvx<d9>Ls
z-IN%;NBtZ%*&wW;aHPAj%w;pobFel_!{BHhXIQz&yZpkGi at _e`9h3Cf{dIDAZ_>qP
zjMcCTGM#r0v_C6`EO#h52qf&8bAUvWkV|gcJ;rd@>+ocDpas`9iSyjP8*SLk;!otH
zAXPjYZM^PkD5^b*+Y*6nbn&ZSse$xa_;a_-v`FgkJ2*})BC<rTiZ1HPUo5j8UR*er
zvyb$a at TD`zJO^OJ#RL<xwKl0m6a!=n9X!}U+UZ<26gc{`XagU(KFa#hUwJoB7TcW2
zv*Z|Nuymnz7H?$B$xK)k>zSwF5s}nv$bC$H>1OK6*SQKHvQQn&M_Z~knJ};lSqnib
zhg(}(bdY0=6X9SoiMTJsq9eESIxNd&)ws|kb>s1X&bO%%+3LRy5 at komHkbrovQl>a
zq&380)5~6E8q>MbV2ul#trG?$aGm>Am|A_fBfzknc(v=SM_})?uz*QdCC_EcYf#?n
zhiLS$yY-=o=U$`>JR7{(&FIx`Tro5DH?7PMIQO-E7+-jpcGu(fJ2?0|swnm4!B at yu
zfO-*-Ag(tp{-hSCqkDRA>U*O|_w2mU_Uwv>8S1nD{m<Y2vaN4I1iHV!{rmRM?&&(=
zS+TkP$&^Md;rIWe=`F*e?7shP5fqT_?g3PK=tdf8m2QUa?vU;d=|;M{LApVS0fz4G
zuIIYH|L1oczV+2L?7j9{=jU9$596!lryfQfE7vQx^JYAiio%bg-bXRMT`xV8uis|f
zz6Go|zdRQS>G<9hWfw18DG1)2C3);1W|s^f6cVe>s#UF)tUj&@mu27QQj`imY!w}j
zvIyu2UtitMAFe)3JdEvTSH<{T^>XsJYn?uwG|lRtfB5~lR1$n!aQAYjK&xoF%<9OO
z>4N<x7Op%y+LpAsHX4V*y+Sw)QB*{F`h(FIy3b*#)fY)o2*<9HBKxk3+6t%B=nqfN
zxUgoSc%FFV55XeEV=6g^-7Ai6Zq4mn8w8GSL?n*-+J&yD-R?X~K#Pb-80)+J>64%*
z$Gj}n+?h>pk4}!Onm?i6u1yv1U~sZpBU6}sMHElXB<f}GrRt%v!nYy$+OCMPNT%8)
zuazLpvSqfLVZ~Zva>%bKkA%k-?twpV3H!1XoU{?>Uvh`63UD at 0?}m8a&D)IP#}A>W
z^?nhAxBSB=JR%XN6L+PaO5OGW!74adgKeCYs4Tf<*8E%Zv$!-fA)t<b79ESDdaOg|
zC!9`Hb20hgHFCyU$(hun02aD}zoeGz_ow8ffC4F5K5?<^runco`JL`&Zz;<L+Q8V|
z9 at kb&{m9QO4nkVk`epHKRc_PE_B9+vCdX&u4)E2&v7DP!m;8Q(d0(*iB*tK$G!K59
z9oImf7;pbTHLWLJzC<!PCW9toe{y7iIVMhVQTz&v7AW1gK-D*?=j!EERoQ7u2<AJs
zw9UGVd)3SbC(8kRY4Voswcl90y}NWDMjWqinmS8Xo-4a_xQhZFR(*GyEPZ!9R8+i=
zN!qTLx*n at 6F8}0Y`Am8q9NYRz>8vhS<>#9(w|XnRZoqeG<>xP5yZWpxUq`!o`7URX
z&o1*fS#JLQ+Tr9~)%kKUZ^1)2Q?XR%aUQgLz#?>;TDqV-UUpDe)uBxw6;V3fjL%uT
z`g+z?_PQ%ZQO>RHS-o;U;X1F at X<zp8_`2Rz*57kXjEcyaK5l7ys`@<ldf(&m1bE<E
zvLA+9pUwbZ>STv{*E5T68F^Q$&Z+mU=Yb=OSB22EDMeL}>zl7zy#IwlbPY at p>JW;P
z_Zx64)^(23i)Cx(^<iTVi~b_%hq1b!xV$;${qoY`6%5~W26$5^$u89G4e_KDt(o2%
z6Bt(<e5KwN9}Fcr$^OII({BAXbTrf!AT6`J=X|L8R2%Q4zYirdg|5TQ at xNM`al}A$
z?&g7JT}db!4)Kmn>L#zhJGMT7?D9U1&CbfF94+y(!r)!bOi);tfv#Ogv|i+#y_fhm
zv8T;0Zs9P(KWv?C8aJtIg}tX=!i_S;J=c7OvE-!et&*tq$Wn+{0>j3UzvKzZ3?v?)
z*AozdOpg(a2Y&D!z5|-X at RGe-l+bNY9gWHGcZl#`e`ZX9ThUdmE`R<`<|(E8v?`b6
zk1VyFr7uA5xj`9KwcU2!YS51DYw@=!EO742Bxrn=qz|b!e<QiQ3{Q^hWqbs0?PFAS
zgHwZnXA364!YSlPfPg8Fnc4_Ep8*Fbwp<7&%&GBOz_}<It*`4>M27R<<IhK5 at n3-n
zempBvee74i<n4)Fn|b}6sHMLEY0jBKp0$u;=E6}09F_ME2iMQ7-lm$_Pczx`Boy8`
z%sM{BjjGHuuE6M6Z{<;I<znuk==F*FV7sba=}_yJ<?GxrG5PU4hVW(fTw%p%gF54Z
zpzq_OB{1ZBiPCbmJKXkoReUwn at xBVvWW>KdaqZ0i9TLJRoHj3pA*?)at6kNl67jI1
z)}<OFbSFYK9&>O~(UFEqQT$8y#iQf6gj)seeM6mV*~`)7YrW4+$g4ufwx at 4S>CW{G
z$%^*t=Ie#x;p$WRY8l1rzFs*otZksF^L+Zj at 3!N0<*|csM)-BjcJ6WIMd$j3;-#jv
zr#j2)z;?FlE)!$M=~dSI3Pw at 1n@N^+9GKD_mNTZUIEcjTLafm(q#!kjNxgYb27h;{
zir?_?o3~R{M}99Ai{+{FmMY!CQBdIrOog?6EY{i)@28%|Sy4ZYJ@@E=%5b*J7mPjC
z5tg>4?V9zbsE at hOUGaWohI7S%H!zkbN_y~4HAr#J5Ft3b>0~+Fw!~wHTG%(;vpGTJ
zB+A`%BxsuXhP6I4a8tE2=B_uqMUsoiCTz-&x8LSXfv}R0>*WF3Zv7pc#6=<pJ+ecd
zSU|VK%wRkb&WgSMWH>y$O&7-dK5fL!kH8a=5ZWUsBmYs0 at bM%(g!T?K#-ZBQEy<mH
z*zY{TXf_%b%!)t7cjQzHYy8c50IHNYXaxV#@r&wmmgps%(MHHDB;HLS{9c*)E_jvO
zU at T$b<g#6QKlDgnz`zx_x5=miK})G5#wxYiTd-q?hJoeJ^ybNGbdR?kT72;}+(#40
zwY*@LXJ<=XD5Uk_A(JhYVlS28?d6DrZhVHPRlM5H_&=LYsej+!-WESPUTB3zMDIjA
zJY17FUryB1CD?ZW`%9|0g|2@@sWJbU%@KMjQJnwPd8a*oGTE}9snyWcq@@zj+TNht
zi?VdBMRBKgJ=BXa4~Y at fR1`Y at fi}3=+RRr{F*<($Pw_N=eb+E}u-G7VI83jr$53Xe
z5>U!5bpOM9yCr7cOZOUBrRLsoUov<wI*)NMs^`&I*<s$M>#-jJT)Ho3&j-89X=JeC
z5DM=+bc|E9o22pC#a4%g&a>^^QvBO<ScH4WvAk``{(3q7rMo;vi1X$l%gpSlw=WZZ
zK-y%C#qpm4@@9v^&eqpIuB4x5D4x%)+uKcD&}-&Me#=e+o-bWHrgglHgsUg8-rvli
zL_LKcK`0hC)1!jWo at N{j->i`~EXJJ+<@;St#fzbJ&0{~YCsFEn?RT<TU1?@$kBR-U
z<$EUSaJ>g^Ht3c67H3vuuTyyIbu0Au6O2<NLbDqfsjm<f)g83k6Y>5aRo9Qu{4me)
z4u`jvHp#O-yo!|B<owB%Tt;jvkmpAs*tzr`;pIq>de?VKk0))xqKds_plJ&6!FF6Z
zO>{&z9Q{2hCoB1j<ZF3$-Hufzan)%=V>@NV5D?mnegu|LEE79Z8|`a!4P}+zJf0cd
z-m99JLnJN(GLUEqHb7$ZVu5l4Mfnid2U3zdu>qC8*prQH!^jmXx{MR)rW+qZ8vfKR
z8b(JGfW>+RY}G$5M_oXnmi;fHbY*N at J0=>c@%pQm(G!GIVBMcvCUI{}n<83vcPB=-
z+|BmQeO3XR&SWOSL#D+#q{PS_%Yl0&wh#8Cuu)MXvb*7;`ZnL#*aTd9+j;nSkSmqF
z=d={uYv8>{lU+RNeGqf#xpFht>aZP_HeYSCk~%y6v~uaAfB5Y=U+<y+;b>P#Z&L79
z+xueDw~LGA<;(N4-d$m<n|Z#^z3~0Q!&BYle4U<KqtJD(aCt+LaIxOqLUvgNB1L7H
zTH~RjkV}Wna at yP|i+737iMOzZ>j3w`_v}YEYvG$^X9L!<@rq;5Q$r>T0aBQw%)B?i
zV9Xu!hMiZJ;&Wz|&#VcJ*(j at U3YVU{)o;<FzE{~iXTTfzQuTi7zaJD?Z%;K%v6wMM
zB67bpI-<&vfrcG>*g~n1lQv^B#Hibh<G|_N+UJ7EF0^((r6xXbrBxlXgSX_ryUQ0J
z&wjsfyQbk?>$_vovUR;5b7(B!+HN6malG-9VNW*bFh6Cdv at _QrIIB<zcZx0F7iMoC
zZ>C{0h#4Xam!kF|+FV*e&Tu7(DulU at _`MYsJc-YDBW}exJ84%Ud77N>za&eUd?j)&
znJxGmor<C-p+mEFvSnnKI?OlVB0~CIR2x>P`iv8Hm!r>Qw7p4jr{fnU6^un~I_7jS
z$Tfm1-Vh_%n>^R!n>@BGr-(aloA6f+ljz~0RrL1(i;If~(i^<WwXL}Gi3eylzSyzx
zGC+JN)3)f}e(l9XuPIEuuN`R-H;kZ2!o`tVOk^~o9f-$LeXs$t#dJ*sZ?Tg&#_IpR
zi}<(+U?+843OJ;oFCBQRRy*4S1_I<PRl<5k*!q=&cWQiom2*?ynkFN>Ew%R at il#_Y
z at f%ZK*|;KEWPXPQ3TWj(l5Jg<U^3*jGe5N5k`><W2NRu`_2Y at XmkG@1hIM$lc$*Ni
z#4oCqR%`<65?-2Du5V6DZ(o;zN~`OB{Cev!yS&Hj8}Qt06FwwhnE|$dc^>@oc{!aG
zzMp-~Lk}UjUg)}WLzBvHZEpRx`nbHR(sg$0)A};1_t>Dh+^U*=AECJ7>B==<CP{Eu
z=X-BefsS$5Qx-ErqW5alad+ME at TYEa7J{Ku5%KHfi>j)css$g#EKs`tQmM-??a2If
z=oclc(yPpnT{i5d#9*1;(B)e;1rbV9TW)W;4fp>63}-Od9~+~m-DdVbDDfh`wf=$V
z+1z%C?~=<mmL*vee_H2(Tl|iPx=~3#o1;F$yH8v8hRxs7OaJb1D_pnB$D8QQTdWJs
z)}|)cF$P*|1Z+{GdbCjdlbE{*8}xq3fpIfp$55GCFtX8Wong8%LG&^q$<26XW+tTg
zgX_P)kU{J|>F<u#`z+#-Yo{Uk5Vnto02rsB8C47nF5|c(;`%ai9hPg%&-24LL$OFb
zv3#2?4Sm8R*6ac^mEh6XZ(*z1HD#OZ+4Ltg$l|EoGGT2hxOajqA04vy*de at X3~C^Z
zz_EWgwLxrx0s`7XnCbSvN8R85`y`w)LO|zK7*HZ;*UZJhx8Mh~EFsd%{j4R!#8<<Y
z)t-!yy2i#vxkM$OH~ALPkqn1V_`uxoyDFNaY8Fdtoejw+u#12i{b!Y`Gm&ztY-|r+
zmhwr(0c#a(AK}?E)Gh!wZ&_+9w2ksu<zGhh8NKjt4|U;i8O;uQb1$OS`UH~!L7z~i
zD8n4N<i5E79}Dou>e(kfDh+;9A(vkWn0wRIu4B^m)|@}A5c2Pgn;(pM)xCXl^1e~}
zDB#O%P=oCC1-H%2wXIivw1rZ(_f5oq4`L--_bqEq016qH827l}COGV2P_r=J7F~w6
z>C`QJsi>@&tyl`VhB;=Jgiy3<5-^v~y&MOmk&({?q1 at u1k4Ig%-T>lvn%9%nxrUHN
z3%m7if-cwJ&{Vk&fU7v}p|h!@Mpaey(5$9-RO|5iZqv5X_c0D*{-2`o_k`Jq>-|aJ
zR-4myZQ<(#VTaR7#4ke>s21Q-kH_2gx|b^!A!Q8V3w51EXeCSMU4zGd8OvPhOD913
z|8V*~>E<%7sSuk{92uzRUcoI+Vg%R!Rra{eQ-K<isx!!a^u0x at DKhsTAe5N%d|7UD
z{q;_SAbi16L}yEATYT)DC=DVZNj@{GBDXKGC7LUf2s&mUak8lqkmOUl`Q-oo4af!J
z<>$)(vX;t6IT0O^0EZ%2IG6)81TENwzLGP}LpU%tKO7i>QyHlu7T&P7!=yj%1eqh-
zAQ8I!y1|MjJH9l;5CLW!J}z~zVc7*6f-}KJdiy~%4bX5Mwaw=h;>vyM6CQr%d+M}u
z6J#Nu`XE;tEPH1n(In2oWpX+6$aOWQS#TMDtUIyTL3GqQmk-u`Wio#U1D(tkJ4Ro)
zZF}MngX8g8fB=!8d#tI6f6FyrsvMt+w^-LV6qrmNj*=R}U(At&<%;#bt_v7hWG_6M
z!Lo&mOC at LSGVyJ4B^|QWx+z*4yLjx^gkdY2xVGal=-GYZwu?kB3DWJzHJi;CgRMG!
z!;waxHWFnIr_uDC_6n~WMB7_t-?CS5`9fF)?!3wF)9uXY33G>T>tMOhMu<;=&{ghg
z+3rizYB34{-F2(w{J~;=l~yGL*daGV;e7>h=Gb25D{T_EZ}m7Bx2<~S|M%eg`b>Yg
zxAr31#ZyXODX49GpLN>R)F~&~(AcTVedBUSpY_t2#)9AAVxV;Ri=y&S??Fz`<2qLp
zxC$dADs&0wV}vf9y!S9(s(m(_UX9U0^3zZWt|5~GI#r&VO9y*qs+afA=&9JF5=;kz
zr*2x$tB>3VO+shBGb1Af<eppWtzP#I$H1lw%Q>{enD1F??fAb_O`)a(+L$-w;^sV)
znqS8fcDz8;eNqT2I|kJRm}BWEJ(^i;KX3JAarr6b9>cfRn%8!`Ig-AhVb~r+m{nU-
z%(KdAgLS6ZV;Tyj5532-6(2wNX00~mD9kblV0LEf^KViJZHn4oh|BS>Ju>cX3a*GM
zkKv&_q- at 3;N<@=os at t7vY`IWze<JC_3^n4-;g%YZA)ow=x6G)M`DD72Btd^vXX;lS
z=_?KTCp8Ik9CX>~KC><1GWB8a_XBdg6Z$=0S{<?ioj&gd*Q5w!kKk%2 at -h#2{pF)&
zgTi1(awcz8g&<~{;c$dv2S$A;TEq%KYIkgIGp at 2jHCeh>F48*%H7k-4ysv#|lR%IQ
zAQV6hn~WB at iOc(x-u>uKqR9|>^%qLe;BSdLu<}%OYahOrA+&Zz;b+ve)qa6iX9~hE
z34I`7I5DA6<N@!K+?8uR_S~?AD4*z>*LRvA^7pT65_6_)R8?W#W at BBOyn+#`=@@`W
z;js`8NU*cOG!DBj6b$Un$3b94-KAo^*DBwRf&BBDH#RluGbFmM4Ow?mz>mFy1wc7;
z#~RdUfaaaj>q6DjMaLv_nL{rzYOu3=;X(G(2+O?ou6n?Ux0kN)gR5_j&zAQoP)z-}
z%=e5Rd%Y8W0iLKn?F0D+rt+<|9lFA=?7}{$sj%1Eb2BFlfyQEwr-Q-=Tc787OE5Xh
zq?(G3rdCPz{j}+U*~?35f1YHo0h5JNM8ER*l`8<BRv8<5B)5UP2i^4ixWAh#{0N at 6
zxM?{m23?Ky57cAj<P1EF3-z7C^-!IQ)DK87i6x_Tn6dy|NRTdr?E?Lj<B$$UJkOx;
zrx+_yp<?74Y82icc?<VcJMWwDx`m?2^xd?Y%uNEJ>>9na3eQzJwl|MgMED`6<3K?K
zj;qQ2jgl-WkC}p_)lwGQKd_~W#l1u^-N{By@}cGAWm9ak<`!y{o7}u8Q@|_S7wn~%
z=gf0zL+Z#E0WZ^%(_(NcJ$VnPpm3lNR(4&dCe>vjP-s0WDTaUwkW+1iY>Z7+b9SX<
z+!|Taf}h5LZ#&5G_oVDzWMI?2qN<98paggfEUvDeHvbNwDt!KR-23C@!U*B}-c7#N
zl-y2Yu4CRhXfjxd(a=js(5{<}m<07`A`E{XP2ul+?`St5hd!kUz}1X=<CZ8N6WPX5
zJ~2WV8PTGUoGC6pDMNWX(eri^C64$KG_+8{zBL6`jbpSEq#_;5$W7XV;#cNnMQO88
z*Q5S7p%3BMyOOL>B!Q84w-KDJ2+h3b{(-Cr?AC6=td}21P<u{4H~Ya!oOySDj=Y=P
ze5!VTGHs_$GoHJB>W$)StDb=(B9tM%ulHEoA*`T=?X2o;GJ_{AM3dx9BHWuqDJi|z
z5fK+GLNfiwGt-l&CW+xT8m_UaiQlt$li+lHxW|B^UJYhgQ at p&qJRxL~C8I(Xpje2A
z(Pisy_PE8yb at X~82JiCgcj(DiV8Sy5uf<q>+mf>@nA|rSilamnESnl&l at -P>6iiC&
z(^*^lmkptbn(49HTE^?tsh2dOfss&~htmnwEvYaxVcytRBH`XW8P|{uVn=?Gz#roD
zcAxm%y|M;xsb$oEtEEl;1ghSE%2TxZsqFciK(&Zu8NZ+l|M);iW%(sF_E_6EBqgd1
zUrw@%@DtV%J^{fvJh%B!SiFox<;Ob-P(s7{Z+CJ8cdmjf>SP|NA*&lvw%0+K9C&YC
zu&y}yM?4f^uO`IrDm30k4&ZoHw>Xc6#ya{y`Z^q_D(eJ~2bQBmz^Ok?!kq at bIsa$J
z<I2Q^<s^jpiH7<kG>t3j`LD5=KZ*5Zu~Q!&K}QNF*4XK_$zEOZCVmVc(tjv$m(f9i
z<A6HACOte at _!RArin!0~Mt=ln7dyW*YhC9i at D8&74Nhfels^A}koNN*^A=sX;|gZJ
zD%(FDWHB#TjUW72mW4au)R2z;TgAAp$ehx0ajd`0_70Pxa+y>o=RW$l9Rmm}HDE2(
zU}y|*uW!G!^YfjUq)sWYCG?h>N|L)-p~ig0ApLwRDFkvFlMZ22RVez0UNGDv)Gt>V
z1*FP*uPDG*<6X9Qxb{Xa2_ogq38sJA2WQC$2FF2f`zXV9YAnil2kzQ=dbmP at o0nv$
zFDLBe%bMMF*E@{Nd=|fhq*7|^1={3H%)0ES_nk$nt#!p6h+uJWI~#Jbb7iwdwVNAV
zihmPuh!8is(@D#}XX+ve8D>d}4qELc5-OEBoQa%0uK6hAZLadzmS-=;F#3bIy7Q0L
zY(lZDO)H13EnU$VSD!v;n at pPvrwNNU^w%zAa665Oen>Ur!IJq$gRSmLd-QZbuwZSR
zuu#sKwQDWD<38wpndkn8zpQD4__muG5?NeWZ+&$z⪼mDSr{tK2+EhOBG_{{`e&G
zH~MVEN}>O)*KNHFdsndCf1J?E-CXp1VE$!h`-`Si>xZL41yFpInX|kj9w~(~f^kK|
zdLc>!rO=%~za&bXdgjPM7FWkk#w=$C260XNz%>5*A^-Gep=Q at p$fr9oR=F{FaX#-G
z)JNg{m5Y^S=bUD<`e+01qX0lK6UU!>txBflkuX%B2AZg$V0*hej-`-=d>)g)F-cN(
zPwZgEf+zcZa`%#U`%jqopV5C(1E*HRHLWBAP=00?*umY<N2Y;gBky<-`n3vC8{+<S
z?j2Y3*05cHn(Y2Jk%`1jx;~mll^OI;=0M1czFK9J at +9T<i-~!dKyOlpGe$`7;=+P?
zYaO^pE*L at u1`SvI3$(Rg(Ltnx$WncVSH*!_wtg#R{u0~vAuBQ?KP`c8&uhin_ymJI
z6xnp56-V_~snI^a=)8Xrk{jNzUzo=LIso6Or#^>825empxGkOyPc%MN2--+vds_kA
zG_H}?%5u4rxJ`)<p=R>m7)C<@{sfK+lU)T}%Q(k|BHB at Ffl^*eua#LG&!cLj2Rna$
z;;0Al--^E<ezpluY<vFk$S5!iH`@tQ8gj_xLO#8 at 8qtRVJ!+l`>K(&^s7z}EeQE4-
zj7MfmLFq^UJy0-6iH?BRJZ)Q;X0!e&^7mcO53)K%IS0XUV>>L^$;DBLLIL3^aMneK
zZvyh0LC<Kx#XO!)7e}+RG)LC1wl>dl%Q(_aaS1!Zr1iU at 6$x_w6Q)_WR1z=lRf*~e
zV59b!UcU2MH!B9|tDRt<RPwb8tPS81mA^V;2?XV#j at D5XCn(%0tG+c-SYl0}=AFc9
z4Nj-uw>8uJ`HU6gY(mOGq}z|s at EK9(-Dl!YG`sjJst7;>T|Z5Ki4<RYVS at Db=7ulH
zqt at Z&Ki)23C`SRHPj1sOX|SpIzzX<delo(Cz4=FC31Ekp*SesAX7*HXYoarU)2G!n
zTtPU>Nc$DYWCy=Uu<4(T^~pABQCW^cBC_(frG8QU1=$3U-*b!RrVU<~wVbIcZZVIY
zFQLhWr%zlefx<zzTf7{va!n~>w!Q!Ob&GL!L=M0E$E^C93)uL at +jPS>R+J}u%@M;-
z845+tk8{W0H`)KCi`)P><aEJWWM|vS(|0F`ZG*&H`=E7Y<V^01pQ7d;9;#LA2Kj{8
zgy|*BztPPXhokZ=?EZKE0EUfILo*d76bAqXJ%doxx6-k_t%*5i!gd$Q>vhxeSUfq?
zKysnpcrzOo8=!;pR|laeR#w1--MLkzWsrWdZ$xVh3!5fhPRsF3LsrdGmlmTh>?cY;
z5|v#CNW<p at KODR@Ma~y(duOw;gI_)&<a1+F(;<G?-jDQ+O90Pu`M9>AB^_}GNegKt
zym5>~>>p~=A<`S at GUvK-rE~#8&62p!^s>*EADCBrI>%p5$pp0o2PXoVuxz(ditpd=
z_8bOI8{yVk^iRVWeLWlrOa#1;d$;Lf$!G9e&&!DIn{2kcNP<9SHQaBhe>6(vX*!hL
zjw)7<hoSK%^&2EmL!4`~r6vKVc;T(fU_~~3RS8FlUVz4H=Dnd~qkE<2+|eo7<cGd_
z%4;P_GUATuV9WF3o+WKneiB-y!{_BvOkgD9&x%?anLD*rVN6EeGxSNL&g*3OOW{qw
zZe_x5>Y?zH&cL^N9{Dk+je18k7PWa#+-vi0NGI?rY}h|zGd*$GI7VUf3yEM|45kz`
z_TNz87LwN4U><l!stzM{%EoyDRsCLIUersRAjI>Q9KfD}O;d&Ypy|8ocL-UQrSZxl
z90K9csd|JBRm1m#(Lg#7BNC$6TV{2aS(AU7Ni8fB&ktHa2H7-N5N#ga1 at +nuA3<Xg
z=nw}Wzs$(#tNTot%rw5Hu{Z9#@zmXhVqSh{ERwc9{rZuNG}?X;kojI(+N0flW6h~s
zDE|-nV8N@^_2+7<`rXDbf}d4xl&sBIp<>$DDb&Q`o at 0~#`-)nIkcB!TR!<zKlr&PW
z*)BJMH*GYQN0N`LT|GI=MWUz67IhDhWx18qBN at m^9 at cB!|A9!w?<@E*ysuZd_dG17
zmm0Y6w=r+C9($V!9CZ|lmjmI}`xIOFJQqPPFSy^%1Z2=2Ko{;<vg{RGy6#x=Hc1TF
zH^pqQzriVCI&{ce5-%8G;wi$3;@v{chcQBa`!SaS+#i#%-YA!Y*jW1(zEuwg>Dyii
zN%oBQPaF|%37JH*dJ4QY8N0OThNlwAIog&mevJeo?Ps4nbCqz}4VKSiZrv~`ynaQb
z28Vbap)O at B6p?Yre_jD|!MOWH5i3-kWP87gB{uug^Wi^H5h}(ZI);9dyjb1|gB}T3
z%Z4t8Mr7&}$8FfmSaE4Zqn+nK-fS3(^_Od!Nav&U{|;4`4sYg-*rMk|3Qf;MOi^8P
z4Sy?~$tQM5*2RN0dN&|Vqwn}z>FDUl$pPqn@&xxx5pPJiqKwjsB5WeK4gB0---OGP
z=%-8>jm3M1|DlQg8N3~lfk{o5v94y`Y|i8qkKk`lN9`v}M$js=lT+|0kmQ<hd5q|P
z at E#*z_{ftUi_K at Qn!A8No`WMYre^msjzU{QWB*59ElL0DPqmiKZ5ve=yfNMy0V<gs
z=f9T{^-tM_*%e<U-wOksgj(2>kmDcNXCGfrPfuRJUV9#4u}2K_N(b(>jh4>=P75O|
zxqv=Q!KLo*k>j#}+JIfj)&*qGxbgV-IC`3$O%3;x+++^%@%j9itO`$fue`JEKab{F
z`p+c6F}63NaMC+CdYEHH4#`+FM*-!tl5}pXj@=(PR+8*)zTDVd3VaMF5<T_~y$jnK
z*FnC?WgJ?7P6g at S0D3Ixcqq=k1#2Vv?`7+a#s3byQ0$!Jr*yzLf?FhoA>m+#_(U$m
z^(lBu5LS$~^(*XC<iQ*HO=`a2R9uEs;ZV4gbYMw#MKpaBKUZ|cohLAXd*}P{6Hx{t
z-|2flEQaW3Lalthqq at O%hxRRKO!J}+E=^`A+5V5hX9Q%h)C0=G>Y!uV?npzN>D>xn
zCXua6iO5<weArJMB1NvxAIwpW2EWTbVNYEwSGuViLNOx6Y3(DueB*0vms at Ao?Fs3J
zBgR}ER|u68_N6b74l;|^*n0a|yM}_lCfmrVuw8<_wJ<FG0f`Qv6L)Tj56_a)p=9!G
zhUt`i-Ah&Zrw+aIR%0B4XA4e5`(q8k=Ux2M?xY%EPal11h$TzIRyKYHOOZ+iGKpKs
z9R$2PAe(6)F5OTlC2TzJukpQT(~%Au_^7h9tN?;Rp6;ARu{HkBBx|fq_7`(zD{BEp
z<$sPq*WId3p0qA(j+((XBoo3IybNej`I!;P&(edTElsOXg?FAj at 7PC=OuJKbZSdjs
z^#W-&y#w{3 at 3?Px{Y3 at dD#m}L%c>hxNDEtBUcpE0boI<@L9#YCyP?(kXcRxRn?V1k
z!GyYRSH7BFee#sMqMHol82UZ5r^oBh=z7x9BK!--JbGS`E5XRS$xm3HPC_whFc0mm
zv;N_hB#=zF5~C&7!W0ry+HTgUl-C8{R3v1I3 at XC-Px1O4UB4{1+kMG03Y}c6EyN=s
zmo>pY49S*Ool7l84q#&&RR1Ct2{WONTW=4zPUZ`E7JzATl8$O_`(Tl=wk|>bQOioD
zUyUPtH8<BR3!|0m$AJheH%Mnmy>wEEN0Q-8UxdnW1row49OjNd6FrT~8kv35$y~_s
z5;J$|vPTQ>g9$_x4x{{Sg3|Hx8}u40)w9zzG_~Bo03eGyL-D942r0uX7S?t-1YH1)
zv!n^SWdzb5G4q1kzXL_z&$Q?P{J5M8GxH(i^R<aD6rtB&)?4;fuO_dnOso)rX70w3
zZrA#E+$*HyF9lmd;$C9c%?%+q`5^m+u)sKE?eDTGvpPY^pUYbE6+oIMyE~tuQo$Y5
z;7(*FSxfYrk{_$}V6%&mjAp_W`9Y959P?K#yz!xcz?jEHx%alT#rwLGzBuKMQ}%4c
z{YE|{nS3@}R}391q_=;^9U|BAYI9GW<TTIh!;6^L*sHAf^)X1XwX at oUv&jf#6_?Kb
zK9Q#vvb#(m3sj*BI${rYkPI7{TXIW<K5K(crP;F!VvR~f+v<RFR->-YZc!TbP1^L_
zKe~JgSy;s^fSYoR!+i?a2oDPYWF?+$ThtO|aS|geX$Gzd!v+7S(}DWve4~E?+F}_S
ztY|b&my at t}w)z7%1BnfvDTZ9LtAubD_`kl7ea-ozbEr;ZC_#E0Vy91eU1`&wtXFXP
z^lN{|ph8k%pK)b1VV~73VIJE}u!c2_M+ur~S?N3+BNh(T{QP4pQ92ztdS!*bnkxvE
z(apxXDzZMYyYH0zXAD9h2^qQny=?#oQ1aFHFD at 5`Ly<DG`-AHTY>(tYFqkQ+9dWcZ
zy4=Zks3Omf^xh&+4ND1x5yJmK92li*Z%g0uPj#pK0Z4c<fAH>VvWG!1b{9#r)w5E2
z!!2NKXzhT%@z**0c>-Yk at 1fD>GVB+KzRG2L8Wzwea0s&vHLmN<rdGlKDs6*@Txl(v
z at uOzYv4iMU9Vwi!I}a0<t}<GyW!!rfSjBFe%3Y$l1B#ADsllwt9-Ir_*g*s&LHL at b
zrNCol|6?^)6BvI-m8jpjoE;J$tHKYPtqx>OEreIK at fQafZy+5}_G$=C9gB4hePTPp
z&j8SZJ3@~EBV#Pt-j4}sJd^PDoWYcdph<B-2HS?xPd;o~gi0)FW;1OK`yUc&{9&Gr
zLC=hG$+F+ at R1oPdo%oKmg{L?aO%9W_B-0S4XR&bk8M8CaKI22^iIY1xUXh*{Hn$}v
zNQoc`f|KCs1)xb8D>_}h%b)UV&G48;jCyOXnBUK7G~?<a^9v(olARUxq0O&xK6%z{
zen#Gt8losk=VH?fO*Ls2oz@?Z+_#nx at 68`7myesa3f;@X^QUXgb2%1D4NYCHwiH4E
z6-41Sz?}oE9!B_*x~ue=u at H*cXB at Futq>!bU#J&~Lp1phc=${#Mhm|4Y_)##Q+>%O
zJ|`xn?;T^rA|`z^B%xnAf_9pXYMP3x-s3k)rW4sW_nF{Lkb9q!`bW%Fd)vkx$~kj9
z3$&Q8qJn1(H-PG=b9I^VvPcJk+lfM5r?j<|#OQ})#F-5R(Z<e}T2qeJ82=*$oyO|9
zB3+om`_N&=`tDmC$Ga6A<o<@1B?*`n)yLiq>9_Yxo-=O-ozM-%<gsUt5FB&>5Tpre
z^(3Zx`jeA3{CH!ZU|6HWc_cIScR-0&U2>SCTJNy`(y#7(LXkuBrYBLxeA%YqW3g71
ztg-GQxxKFx_`*|OloPGq$LKpUtS}cFnLVNh390@&H3r8*=ud*T>7t7?gSR$7G_|C8
zX*)Uw?>pcav4|ZPz==0g1PV?S=dp8W!tySfH#;b9t`sm;LIzoCbB&SHX};`u at Y==~
z8naYPPPRj8<ePV8`r%pPT{s%!(N+Wz5fO{15i|fo=nfJyUpFbFg&}YzVk-7OWzawO
zv6vm_=YeaF4QIuS&unqFH+EiMdZI*A``;kdE(_jj%2(SM`O6cKIW3GvIj8EUJ5Me<
zKZZfEgd$Qa+k5?}*t%(^fMl!=W|tcVcVL<zY>ET1+>VHmV@=fh!4Gus*61x<Ijw&Q
z?D5q5G&tD)G&%;gtPUfJ|DCEe=R&r754nvS!TbR9w>tKD1j_IZfqlmbFeOR&NC1kH
zyu~EBAR3Hz`Z2~}&s|!|7qn)D$-^aw&L&NNvOL8RlL--yph|V<v8B)WXVHyIz*wM<
z&Q_DVx^H4iM^7_?`|^zf*qfdC6SO4lWF(NfjK1~Aw3&_<g8EV3qn0l at 0d7cq;>D~2
z{6^$w@~ox2Nm=~)*%S35UP?{A;d*03nP8<lXuYgI&H!sm;u`9SwcTDO4>at7Ab4uz
zNnc!X4%Osa+n6k;V|f~t!yJ-T3v#K>P!O at M_`i_ga7mQLT?>Wxm%J<~B;+Jq9~l;Y
zX3O7iU*X#w&fGy03*`nOj#b^O4lD{UO#Ax^BqX#EN+=MEr<12WCj`of{=7NW|3*9W
z79Kpu4151M7pRB`(GC|IEIEnfEjm-OWuU1t_ac^>KIY7-nw&}gX}46pk at qiGVFpZ%
z2EVC9g4=5bail=0tE2?}?qY}X#fU_JjT at cSv;9^*-~MAUtrRpAYf$khml=A$LN=Bz
zb@;QM)+LeaedX9vZ^-HHqI+ee;|H?lDGOJRfe}&p9gNg(aK~>XxXVWG9~U;!+Thb9
z&)Ef?ewxxM2A<|4jjzV`6?S26Zq}F+c`Q}`B_#obj(MSqdk&3#kw;Sd&1C92e>eqg
zy?lIqyAsYWCTNAtQpZx7Q42;i*sLjCjkH at 7wm&!;ja^o21}sGY_mK;5P;+ynk6Tz;
zTJomWZHi5qtAI_n+ZlH#c$C*ATrF#iKP>zij0f?qIkC!Pn+~sV)NQN?x&Tb!FMm&N
zm)IKa*C7&AfCcM4`HDL~;?A;IITu^Z%5ovmFy+T at 9oeA5iL|rK#Z`cb9;wpp;^M-W
zj$QG6fI+J)toN$jQ7iRp^6V9KjZw6xo$Ce~7M=7GiN(1Pb*Q7KcPcVDmdjQ!z4CQn
zlrJow7;?mR8GZY~>sX(MhZF7{GOc6vf7UdG*BW(33*`v*^dV?sYEEPhT67h|?Gc0&
z1TOF2u>jId##7rlQO?58LQn?v!B2O*l<zf7YThEYQ^G at 8zFp4-uOVa%ZyQb0r6`Ic
zcS+=ZG1T8n4Y2Oa_8yY3A>gj~Isk1mv)-;acZ0=!G_gue0J0=ajPBIGNt>6%pG;N2
zay1D at wh`|L*#C8`WODLRJK at JJ-?U3ZGu$c9LU>N^Lfy at o+nytU43~wit?hled!ytd
z<|<|#?@7ZTrG0Bqil(6q%o6Aq!j?S$8u=PZ#RNh4<30b$f=`Z}OpyA at y(A)rNz<aD
zq7?XJN4N<@sry!!pi}B1{?4p<UKE7iWRLEDKjnRkJ2P_0dv|38PMrZRD*b2aL{u?I
zZ5v77&&%rXJ_~{8_(T&CiS#6RXnJMtq_8$BiB9hLAgl3KV=1ll8heTSYw+0-QPq}T
z3cm#QP at NH&WN~}0gh7YV;hws#d&<G}I at mM64dEtbRo1E&jb%R=aO+nrIK5NI3O8<R
zag7&=!RS&voUP_j)3WM2u!tR;^LT6 at vO!6R)re0(BgtF+3%`&1UJCd_1OEBWA_^Iz
z{P{l?0IrP+2n4c$Deoh5$e-LdNN(^MYzy~L16>9Yg0t4~cB$3>^y&=JzGwZx)RM8X
zdt_>u{!_f(uImJ<gmmLtc!3XRURq1sdF(wL=yoUeGzTz4eZo6_XRCdReWrAMB(0JH
z5~x#oOa=2OK~|oq at d(61Ha1CZ%J@%k=kfLM5qMa_P{`nITK$`)c%Gid9Hm9slvD91
zqXpY|`@!eFzLOznHj)-LNeN#gh_0wt`e_Rx#dYMJ+h7ZRT(uR~Y3h3NV0>!gJ+0+V
zUO8!xxSfPw02fvW!+RT?d%u)2eez($878i#S0G{MJ_ at Cq?+N~H<2Rip`wb@{Q=e01
z5=q*$PGeVsmQvm<HNcj^S6Rc>`G?!|lL)Zx9;-I6s!ds&KOu_Xcp?*6F-<9emDMm_
z4I?(bC_=DzvC44P8mIL(if7#khr1lR at Z(as*t&64#4f<muMClx=sNxE$6(IX&uxoI
zr}5XN5i@`rX(wqtCBsyp-QA>U!VZ3bxY=)9^4OYHw+$-A@!uD+XU0g^tW&MyGTjzT
z>JTAse#`>DM#sSL>}pt1T!^e31z!Zd<kCiu!~IsW-0O(Lpu`}x(h^$e%AR8HEgNH-
zs0`dBFy#0D at xg()0GnZ5*-Wp!UIa*s2NeJS)?gsvPeGVYTvAe!Ld{<t#B?EId(qr8
zAikrjrp6zJx@%pdf7dcCWPbdmhAsCxQfDQ-O+&%XeIgo7C-C;v{#faAXq${t3O6|k
zNun0p#HGJz`EHas;!dXVV6Z2Z4VP3(U<AVKaNBNFOpTt~+pkSSkqPwzx$vrG at w_!_
z5^`BcETu9_Sw}9vcHet{M{u7TFabLp{}_<pQS at R=81^C84UF`4u9j!DVXw$2ujEPD
z{qh%x5^7rc;D5^9l^8j>@*&c;wvRW>8Y(j%0+{-ZZg+^ZeIw_4j_fuazxnxj{;;nj
zx_`ME7sH=J%6T@*Gk<;BP2zVB28o`5uxiv$Ajs1(y~vCe^IllTA{oJ{$Yhrhat(p5
z9~NwFJ3k$#1g9oH$(_RC_w+so2<81h->@g<4<eOy(Q>L0Qb`r1V&`jUD9)NnFoLq6
ziLdmJ;Aa7=6mw-#wIcaa6N=3hYz>jzx!`q~5trP%Ssrj_liY<vHq8s$e1gCBC?+gO
z`=p;V6?K5@%%p~Wd}=&QfdzM!-()vBM!P^)N9P!~C2Fpw)~qzxUU*-5ZxV-_L?P=u
zZgAyxCEPatVm%re`E6J at zaJ@nk3$^H438$NncHX7p7Zh#GQAVtWQ1x_4E$c|ClY*B
zhl{SO)OCsN{+bw6jPgRqlMz7r7aTlIeEr7|OiG$M2ebiZk2?~fqhpCTA9t4 at oT{VE
zjbxnz5c}LA;>)UBiUAT6Ok83==@Mk5EWH3cJBdLpIyHz7#kAJ(6=>~@n)X8pKZGE#
z`HIbV_q0<fE8v at DUNC-7qInLAZE(t4*C*Y#z@|OP44esMT?~n=SQ-fiwK}JXqU<2D
z*)s91+u-Rk!^&n)<apS9hq6s|d6a86WYWqt<{p7xWPopjW`uEDhuK0~STxq|g4gjy
zMB1nq+iCv)21GnfVW>(pqcFO`zFED5#)S~2M?<FFx-<REP|UGjxK4n}p#R7&7u>Lz
zjHWRrhg6S6%X~-l+o})s%xQzd_1#`^GuXD7OTxmCcu;s}sD9`HC at 5tY-@qM5k#O^6
zke)gM!}_;y>~L22;b>&CTW{yB_K4481WiI?LXm;*{ZH~k2d>V3B2k!842jPYrtoD^
zSj^Grt~k;Q=6vQE1K<-{xsARK!D5eIVoH~1OMbL3!f?0DF$O6stjHLJPLpL9XtV-T
z&LcCPA{-;V!|l;uOPNG3-Ao*a^*7A+*YgJ|Cz|!uJ~lYKj#~n&_Q3LQbn~#`qtm8(
zYeVtpN1)ODZgBOl%Z@(Sv1$$*Q8+y~O%4 at 5oZ~$>%Ndwc{8NFhtmwYKK_~!yV8o3i
z>8V|^?9OkdSPaoc(w3+$9W(-Kh>o_0YF;zqDLa6*@>efL==##NjF+9twt1)5PN|gB
zJhz!cv`%1c4TJI@;q?xK-bF|8gHN(*;I^PGOi}K*#8*ESC~+<njAfTCn4G+{z1a#_
zb0L_|?f33jS33Y7X2EuP|LK3{nh?gE;p12}1;4&?E^;#l9Lr(#eJHSfwhHHF|M>V=
zfepK|$bci73ea?K|E*W2>~5^7=Vir(QPy9kqt6}pB8o5Sey)6IE9*8bX}?^}Xo6zx
zLVKB#6MxU048<}6#oQjzZPt_*4K1dYgO^dAa=ssGRjo5(7)9}i&InJ}qb>CjX<9%+
z0@`V}Z{HMUL2e#?#GiH;42A%1ZQdd#BqI#*^dUZ<uhFbEET<vnXdrvaZ=@u at E0E_M
z;?pwu?K|fSQ{s3yxVQzA$8x%jQuU17mWj7z at 4f*RrUt{zYt&?ScNq|&lI&Vb$KG67
zfPH5+9KAA|0=PqcY}4*=_HQK2lUR}naUY*JVO+ygh;_B?ykR2k`S!#_Lw5?YDLyls
z*Y^`l)S{M+cryUqa+gJF?bwT!K3rj1-U|=b%3f$SW-cIn(<N^>2X><Vqycnf*G#pZ
za%W;)`~3-$3g%#+0d;WdlMk1OCjp__adgzZm`_ppgF($39Pzs2jEE^Kt}=et(;wLr
z|MNn($e9FJ-L1hb8+vn5_b0hlHPGMtxn*ApZB_bvUs>&0BQ*rrpVq`ywz!BDqfyv?
zIc$;g?ONYH63d{!p?Oca#$mohY7j5d+a!lVIZR`|wg{+8i+Nn?KNYMW?)YKmBot&i
zoqiIuK8(Z_t==G!usIngHHaY#1;Sw8xNTRoUzpy#1ZKCzT3Vt_&~uDWRTmh6D!LQV
zDTDeDxvqYToI)o|vLiDgNMf7o!9|NzN!Mc))Ituh3>d at Zg*m31)nC?sY+W(ATB-Z&
zkW`)~Ke<St4MavFjLCvvZZ*^^L*}CEM8}tq`l~-R7a4*Y>rOdvVQ*_^^dusf!_ at m#
zH(3A!f67FIXVs*8<Q^#W3VCC70(5Gmd*yNVGNow^#)6f&1UKwh6<Dp@@Dj!^sZTo^
zh8nhzl|gVfA;BG|{Q#p9VBatphVD2~p;Fe+Ot$~a5A6>ri7dlI`}VJdv7Kaq3TD;h
z{4#SnajWpwQsWGC32-W|XAQ_9XYF4laGN^*Z>@@70ms=Vu|aUB%ohq0e-h=llSw&a
z=O~_Wyx=eoeWoTh>POsp>F%Lh+FT(C>vqH?mWtBkM;7Vu2m%(D4f>lJSnmS+c*6C4
zeYV|^DXv8LyD53FQ?_~;UUh9up~fc}&^tE*%S at w|&3^}<QwF~r?FqvAdx6fa^S}w<
z at g3ZWB6)K(9c at dvRByH>Fa(OA<qfu*Ub1i6B%tr^)7|;~uP~qYOH){L3iEGeO)h`L
zLSqSTZec(j($LJKZ%aQAZG(Fr8>b}6hlS#y!0c^ev(mnRd;p`Sp>#HUyOK=-On8qG
zHcL3ONYkAfIagMXCEia2r at 3@y%F&GyOhciGYCFck at V&b@<lE&7a76 at UbbMX?4eaZr
zk-&@`{XNIM)W9Uz&n at SMq=q$M{X5e(3yYzgOIFh4l3e1i)g(IBKUu6Lq4A;!BE15s
zXzBUKWA2VdPwu at Z861^WRj%<UpLHVN5l)vI8LRb at rUH~t at tmD77xgGJt?1jz4UN?-
zi4kDUO}p0L at ZjHUF3BzkmEF56dYv$L)tft_D>iumWcJPY7ZCj{180D*S(AN6Zj)d^
zIa0ohoarjnclOc9#}7_xg_mscSkN?-i|m(Ek!eK}eB1IqlkkyX#zdE}B`wpPa5UO|
zMJeBVJqIf(FQYWLN5W<LL1Ey666S2x39ef at Be6s$F<JcacQV+0ox1UUdLJGl{^2$`
zcny at IP2tIU4xHI{J{uToo57&pAvw<>kpomWP8$%-KSp5Q=}=A_JXeW3?j06095;^t
zv|Mp)zm`5$Sn0-oXT6#F;GoMZMagBvd~$N)!WSe<8f(CWd~W|3gSb&CVzN!IlSq35
z6RjioDjLd2GdMa9zZt|4{TJL}<XJzYR3VKlNUm-%)+U&GfHq)8ton;*WF|*(Uvdln
zp2YRX5s<)Oi|NJg`?P8mW~f;g{9IW34kbdXOrxSEkTr=}u at Xk9E)vBwk=%x(!~*_r
zLUE}bbzc8r7;vB!%^r#OX9^AcBb+IhW_3|zVs}~mI|BlP_>h!98mp&cGEdZEgW71d
zm~VFlF=Q?XF<AWRJ_2Lz|2|0(#D_z#vH|}}W>$rsuMeFo$jY7w_1u22|NSr3E`%h5
zbDB|x at 8wR|?_-ij+6)F168G8*J{3?22`PGQ14CB|S2QnMjcWEZx;Qw=OG5WGz-+r?
z$0M-AzDeB_hX at MN*lJvhfk+vKZmG2$c0=u^lB%aIJ|{Q`@w>kOM;gpw&?TDbxJw#q
z>GDqo>7X#~nGWi8dtT@<dLl{(G&xqfP#9~<y>eFa`s3mvCM<p at i#r%svwq|>@)KU4
z)&%mmp*3~zralZ~jPM&yWBEkvtSLlfdG<^~t6{9CS&svQFxA)v51@#uaMqOZKijR@
zsKg{@?MPflSnUzqo{YsKer+_Xh01_ieMCT?vlum6xXULrT6j5Jp5<dQ1DEYP<_uh^
zd#@dBZ`RJK(NePm|IKD4x;W)Q?&f58WJ=kx)CSPo;*BYYcVr%B)N7b>Az@^{zneNT
z$TAQMTT&3qCX;xMb<jISe$f7$eD=7%csN0Rnz){(yB4ycdj0=@g-tV`8RVS>%a19%
zB638_Tkh)3L3cw*o{0a at 2jtC6_3|KqE#`Ts77D%iYJl;3bK~w~?)k?Ex{%;LN);`~
z7{r&E59*&xh=ooJX(3DDWaG*TF=V}6enZpN)N%H4OJSkoBI6KF>Y(1`&x6V6b7Wd+
zddHW{S7};FLE7;mF9YGtV+>h-anet^vT1yUMfXDV)gpD8Qy!kEX*Qx>iPiixQH-PG
z9ZS9+jXT&)t3`s9RfmPa%Yp8zawdBz1**;PU+Ds<M3Yl#lyf*O_PG%+OFm0h+h!r+
zA^ZHR_>R+w)Eza;KG}PqJaJ at Fr(p`N|BS9%Fh)}&KneFLfdvOo)2vduxnmC$*B4l`
z>+=jQun3`20G=(wV}E*$Xw7TWA|xosdi9m7IUp_vZqW<L3Q+AoH(sapSG=&so%?3Z
z-ga>11qdv}Qj51xtj@~K`11?*2Xk9KW}ys`@52s2+IVSvBg!d10lbr$z at he$QRc)Z
zh4zcP at IH?`hV3oZ|2v`%dxK#+CD at otr!*)H!7VA1(1R?`3L9r_sB6NmK at H90&=eb$
zI-QRp#pQ~5Wxz2Ns-F#!Vf@~i_t82jIf)h{t52A;0mfuaVYB%n96s8Kp*ru3PK2D3
zrl>N0yhGlf>jKTH2v~6c0{I^aJD$!@^74^zjL`v}n;KfJizYc0&;%&j%zK%PPlS?@
zv6P<VOJcDKSrwcaur|20=J=Y?yTFtc7z6!g^!<2LZD|?CBMGq9ka?A8)Tb?d8^LW)
zd;osLh?bSz$%-p|_CHK?Dl8{5o%Ma<Tq(hO5}}sXvGr&<7pIKOxO<J2*vde7O(YeB
zHh at f}uu8>;I|l0^eQVTng2*Kl^-vF8KS<~T9^H<P<>8TWVM8n<*uKj>oR~Pmpjig}
zh;HhA>tfHS$UJ2N99?5lgLLrGWxR=&6(x*2ER=Iye#aDxc9^wk#M*q+$#JE2#U*BY
zq4w_a0houT87wGZ<7LUyiGuicpi^-MRMK7**<v2-3sNQ=#Lh-cXk?q0S+1#1Bwb7Y
zbzXo7Glsv?oQh|E4M9!JdDoVEfgX{rZF$qMsS_I*rGW^yHo48s;=1H2yso5iUF#_I
z<||dFLp8eB$i;Z at o5I1U?T9en@{E3Ri#yydb5Z_VlWYQdzb7Hj=3LXG{Stu#|Lok$
zlu|8ClA-L)w%OTP1 at Icebidp{M?ZyO2CuCrvM~3J89*dZ+tq**qzAas*uQ at qxiz84
zINBo&>o at fq;FqbLN@&^b6K3wlQFH9tp<v&=w{{%lwPIldRE>^~bvSx0qvlv)CZ+?}
zoi+v<Dgim;)g)>HPa<+p_FN|5bS<N&m;Xe))nxqj*)!xEfrz(irAQNtOy|F_J(I&O
zBaTk6=O at Hms;xxZX#<y+Yol9EmkVqijUr>l%Y{^iQ^t~q;3Z9}a9`&BMxVI3gVUve
z95X-hPBHYB7Ed14x7HlnaZn~@aAKKtq6NoHIzI?q(?nCd44AlhW(Axslk=-oHNWLY
z7Jo^7ml4$cB6gzr+X`6MZ9+Suqo8)L-GBL~rm=BO8S8%!`xl;=kfhvp3{ZQ9NVF)!
zVHrx{$<x34Y7an!9n3tmAUp9p=17p)qfjx6YUbX(6&)ms>oE>*zfES=nQMyQKn11m
z6jhFT1ijdwjg!lbt&5hT)F88c)%3r0yA=4 at Un2!nwc6iYt;Xs&ug1>hQG66?doC5!
zGuJm&S86#CZzp{+bkI(ggVXxdm?#K0bhG$h*?kvpcP5KITMl4K@=Z^t%FzuLlzcy*
zgE{;dwX%$trbTFtOmv8z7PaT);`n+5Y_v<8e3}0LX!^>yCLgeCX{8KG+5{2llF=w#
z0#c)MFh)p+w1NtVh?EnCbd4UJBHgvo-6JG6V6gG-|2*#lAAt}2cHdW=bFOpN6Vp!Y
zs at Rfd1f)QrHGY;P at 3IqtODW5bKRGDkvw0|gI7GNgeTcDH*rmHl89Aw%wwwa4oKMzY
zzDE6#rSrGh`=wPeLJB?$q!F2h%LhKlymO#>p&}JM(a)?cS?8NnK`%~6uiY<Ju#%_X
zVdnnak{rqWsMkh5uUtShah`vK=DRq<F{|3Ya#<=ZlLFRfr~{S-jh~LZhWk%NGF`~K
zvv*Dg=X_kT%_50Hm0cQ>CxITVAz}Id8z|VprPr?Ud)T0y+;eeDdscT!>~KY%_O2bb
z%q?Z&%@$ZfMF{K3OS5;x%jETWVQ}rAykq6#2eN$S+Ol>Vf-I*N+Y+yPyL#tyEC+qY
z=Im301DH?mrGPR^&OE6muruBdYaLHBxgz5-exF5Kn at z=m)_87kth~NlpFTd*J+^4q
z>vU(aGv{EtXX9=9YZ*{WbOKc=`?ZYASO)G3eSk>W6EnBYT&F}I#BB1i4!hKRh3S;^
z>Xi0~oYEwu)SH)-nT9j1cU990aWZk;WO3sIf-;9&&+EQAo#M+#q$rHPk@#-*#jbzV
zukF2Qd?6nhNcpUbwBFA(BFXaSsRPPt?O8Pj95A)AvU2SBXvQv4?0u{;|L0G<{7WN&
zb$Mpw4RvoJWK<e<NuQ~c;%}vCWL>D#BoA?u+W(xkvrh<F)UeVNJHCv**m$(1%WX#m
zQ6*}#CNgtZza_uuJbs}ty(?*!8 at V<7pOb_?^Sz{vVyncf^|Sv(jTO at NuQgUJJk{Nk
z^O$t1*3a(G{eOZw;65Qk<uO)?Wqz846IPMH+M(R at w=ev+3n3I~C(~XaVs~)#M3lVW
zc<ae>%|~VB!z9mP`F{Cz8&4wE&Uzg#TX7gm48ye5g~_%m><hf;`BfqFYUKW0Qr7jR
z9=q}ZY4b<M7Y at rr$>-x(3#Cm^f at 6Yz#lGAbc7KjDl)+vrT<@y0HS@~l at aXS@=#>Uj
zaR0|9{R6N2K`B=cy`6vE at K*R+^R?yI>wDM#%yk{oPK<4|%<nDUT75?}Z#F)HWcdi2
zh+ar3xa_ at t{O-s6GBFB)co0Zm)JyU-Y2mhwy?u^7rL!RUmStZ725ir5qG%8~Jq03F
z at P9fO6+yLHI_(4_I%}0Wai=qPGje at q(k9;N0fe3>C8mB3m&hy1_?!OP{gpORwjkWU
zuhcCVVs}5RZM#Ny0g)x3ac{fqqm1L*C%_Lrp<>AmM3?1koMLiZAZgeqbWE@#;{J&N
z5`{{zeY at b;mqG+xM`~3VYgqYW8JTXIn7{aABXYw^)xTtXFX>7A5|*+954=0<wssnA
z=e?W(#Wepf_*Kx8Mak)_ffX at 9T7Em>8nXQ(W5pM(x4*Y1{@Y%cGVa3zf{5N<72)AJ
z2xWaJRp3tEs&e_o<Gpu_ojaeV7ZxjjJyeW~PiiGboY>cp`UeblRD$_~+3nGhS!<0S
z?l;(Mm3{o}eQ=)J)UvWdw1(bqAFVk3VlT_bEXw?Z?EoCGNBkFL{=9X`*S%T|-1>Wq
zaA&D!+B at yiedgdrWYW4mIj`SI^ScPxpWsKyX>G(<vtJJ=gzHUs0TxZMi=O4 at bwqyr
zYoq6J0^k=bzx7L*DqAPz_Z;86#`u_A<sdgPvh9%DkrY0zlecr9Dna7-KKP;QWyJEb
zSH9dxl6y#Oxn-p?)Bcavz;V}^Bf)p8$Sa8+V`TQ7ypzvLCEPQk8CXp?i1|7iSsSVQ
zT<A)vP~=Mu=ES#US-|$`G=9fzQ`bZ?Kadf9toHPa0RURoKa(HEoA^6v%ORrn<XENN
z`j+>=BGawmYR|;&Cknk4a^1sI-#=`ajR{nC@($6I3E at AVH)AkcCxLKn<DiMb|6ZGy
zsXb#?g^!sA<kz!4$^Fdw>I*|i{<bw{(}CUh77=*3SN5Ud*T0u9N4WI#g#|bUD{T{`
z5<bZNI`1Jeml~12mk~rMhur*|bK|WgJB`25(P}e#PiQJPc>`h9RC=+UTE4K8`6l}h
zNk4S<$JVAtDj!}wIEi=Dvz>8QID6q`o;frB&j0N*Q7E(Ge1EgI6u+BRDbL=Mp&#+D
zbJv at 5p&RF2&fIpdU{qbi`sqLZi6XE})mHj5Sqf;o*|Bay<{rI>_a<=@$%?}QHH-3S
z0&#!ulYs?4uuzj4i at q|!o8Nh0e^KhcPg19gBVG(ubvihw(q$}1OsjPlvzOrtxIaZ%
zbKMkz at lzL7XMTaaAm<7r#*=jO_Ej_2-!j)Y7p456GA>k=%%?tBsswWgty^CZ at ak$W
zb~xxY#fdz{rKK^uEH}&f?OFdlv48kG{_x4LyhzHvlRnWTzIM)jEm$v5`I08Fz3L^I
zfR^*m3kA<|(+ at y<w4_fX_K#Ne^o=u at d+W!GF)X-G|JzwWqB+ay*$G3R=`#G^BnO0c
z+5oNivH<7uFYdhrrO~1`%1AnD@?7Xz>O{mY(|%*fbEA>4C%xYH-uHiEYBc)G-rh6x
zs_)5Iv$6Ll%U;C&@7IgP_R^Br2-bw2f$4;IufOpIKAL&wGV?Xf-d+f>#O};>qWuD=
zSl55$!k^@HMU1jOfeB1HJS2Oya&^H7^dybF^TQVJ((87c^OE<c@$%ou;H^+8DJhvF
z$`jJ_{05V2?qGke>dV;_3_d7d;sAkMY<^(KRC5o0cQ^dy)br=yr$BOhV8LrQxa7O`
ze6V2-!VRZ3 at g|3P&eS{){5-#s&KIKcDAI`WVffoSjNg>3qFadHpgr#3utR*qh;O-x
z+j<CU5lwh1Q?Yp25VM47ie8f)S$jFmx^9%%CpnAcwlqMSR~sKlc2sy6 at Kzz`7`Y!C
z7TJzF0MAvwQjn?m&aw~F|8vyX%K|#gWIdfdAnAK3F#35b{W9_`oF|r*s)XKPWc<3G
z4>O~C)5Xio#8vNQPq$aDa{JoangDfT=z=51&pSF;7ntd-QAHj$bDL1$9^Xx<om4}c
zZg- at xz^5tIzNpe>&X`HfOq!+f!VQf9Bqd<?O%T>ybk-Qy=Sn7!G-a{VAay9-o>ng9
z5p=z7q-B!E_H(nDm2PW@*hL$|t_j90%iFZ^ZOKIMDfFlDt;7BFGZbOg`qEW~PeLhU
z>syOKu3yo+BTVGy?Tw7J{izI{eN2Qezx<cloSVMGnJ}2g_r%p4OUCWb+~VM4j at WGb
zsy8^Z{m1#;sz8fy1;yEVB3A>ay3Hk9ke5a$!4wh`<^xHpdSb4Qs;o$u%0C_YN%A>N
zyJokU$#jWno%MAz$sei8caX{ll-rmagea=pncfnH=7N41$$v=mgga%|=<b!A|Hu+j
z{BhUd+kIxi&kM4KUSre1 at WP(2IG80#nVVXbN2Z&~?uvbd0{f7wV#*Wy>S*%PkV1|T
z<|a9 at FB}^h{r=Um(`YX|Pmf_oFwBKzR5L)uZgyMua+8!ojBP at Gl)gahTVl>mxK at Jb
zC+LDX0+bnUfZjPML0L|>lzB%BK5}_T{bO>uH|oV>kr1Tshm!X%WgeB3SMHU5{3j at t
z>QXKXL;E!G=h#XNek^Wl<6)p|$2SF=>>*Xh(JI#|S5vfRen`Y)2I at mccjd<PK}{?6
z0HfN)rC;tzP}hD<OMBjhiSa$3_f13%E%Va3W5a=hoayzyC^fXrNXVS^CHf<(1Bm{&
z49?(y`}$NMkH)4NL)_qVs4^tn)dbz$2TV2bxUL&9dB4rChze^|OBOZ^cc;P>Q<HWN
z^PK at Zn((Um%L~l3u5daEzzryuD6I_*rPyKSfI%)Oi=nl0)jsRa^5n%^&2OiCth_tV
zd?@MKK5-ID=pQ&}jMYupZc2&sv%M6F+Zi+AGk{03Mo-f|=fy)|A>WeXR~kN;QCp#>
zOe=|lUni&hRAV3R9eH09 at bJawtL&A(zsGMn)HGSvF3L5LW{`gE+uWIv5-N~y%qn<N
zS^siIsb11dd2PlUv1(UQuAd|lRUf>{&M#(;B<?)4veXWwR*sB}AtUmFf^SvSyeL3j
zj`Z7m at 1a9wG#4t^LH3q*876k_-kKSK>ZR}!-{~omDV at RK+k@uOnKTO at ffxD@_IYv(
zi;ou>tBu$)?CopSgoOku6brV%GxcA-S*=ohj{jKZB)}+UJ_}6w{M~wPTKp_u?&G7|
z;{T at w_}vj6(LYIrX-qG38GzsV0JT_yKMf at DgwBhTjaD^})RkIfJ#0|~TEyg>ID08>
z(2vl`TltpDl;?6tCeY1WQ-))imV%l?F)Xd!2i0v@;`<iJ3HJ?fgQI&)&{#wX=IE>p
z*|X4K!5wzyh2KtSuz=xiZJ{URkL>WDP(rAkt`2~lbuc?t`orN9`UU=kgoL_zIh}jy
zH>w)movXBDr+XuQeaWBtU2Ig*r3~u%djo556o+as<m?gLO_i(%B+c^b<&cbY6zk(X
zno0}gdH`E{9Sm3z^-~U`q at 1;%Z0YSdpHc+XZ_xX%?n%IM?^L5(Bj=W<$M^X&k0LKL
z_J88I&6w;)STrQHMfGxcqh2DmC?8Rz<C$4`4d_9SjozL3IPRxoAx>f0ty-4Ab2WVR
zRAG_U#PR_7_2f`fekP3*?r!x(e4ak9H$#5mjEzm>*FH0eQITSkZ+Xk_Q=8tx5GCB7
zl6-+TrP3+poTPkA-cV(8V{`wdweXprJo>uL*gO)gOWhAGjl^{4Kj<p!J_fO~mq;1*
zf?)TpQ)Nm~{`MvMk!RTg8>eP<YnAq{uhcLK)o4#U0zHhi*I{VdbPt>hu5}Vzw~*Om
zu+Q(;*;`$;GZYCNQ?AvEYu+W)^$DaL*oci;w$Raf7K9cZ8Y)aS2c_Q_hP%4LQP>Br
zVf*D_ndoCMoEJoe?%V0WwW_&>EKJF~Ey_V0ShWHDJ*?n*7iqB=_R!fK+%LW0T6!dK
zWcW5#iEhjA`fO*S0E!=z56oPN#8{Tbv0!A92$taw<Xj}BbnQ!-S5yFZM_4cS0*4)Q
z*d=3uo2&vM&mk!E7_5}-r6h&Er6`s7m!Ih;mRq at 7Z<&&JW at o2AGFVN9{t1Q+DbiIr
zasT|6gadD>Og}cMy1+p`HE2xV-By?L-rJnk1sNO;1u|^B32MNzOr>1T=jUbzPWg|J
zx0R1@$yJ9X{vbXWWe+Q@&-<w3e*AF`sb+0_0iV&vH`wHVEFI_(WM8mMG8 at gepMVsL
z4`^4DH4QUOARvN1yupkQ0)HH9g=9II at 9Dy}`ADqrit~TTb5kT~C`mir8S%zsPqhjn
zeXC#TAW1oVxl#lMHpORRi_0yWY8$LO&Mz)58Us%@d3qs9qm)%~ACdyGzeU(j{;hNh
z9L=ul8~bjb0gWZq=Z%g%9 at f2FD+E>v-4RvKbQg4wG=58ZY1xRF?&*5qp4u0s^os<7
z{EWXmSZFeLRqkKz>gozwi<gpwg?M^a{LaLjQ2@#`#F!g*5c%}CZ(Bc?s&-W~LC+om
z3$}u at 5X5(~?TuN|b+9i+((!~a5ryGY2&iv8W!FPynAaiOuEjFp*Z)9rmLBtsvrYHC
z`hYi=)Eg at Gtjb;GWZ(`ue!JSw(_n12LsSkt>W5X?6AgBMbcH<}!z2+0zxdJIWuocR
zhf_g7NG)=1 at 8|zC$Gh0NVBODjQ`QAb&+af>xt8xqbKFeDqNW3)*|mRc at 1HUDo(6*w
zxG*YTE;<tt0{UvJOlfC$p3_b>Ea+E6+(|`cati28apK#WCaZ+x--${jW$u2)P+dJe
zsg79O at ATe`j+Vv?v#Y{m%qG;sJrZ at W@Feiiqx4|0rRf%_EBqmSoA=hRldd{+j$90%
z5b at 4!)9KdW-XY_Fk$$h<+((P7A5QJPzF6QGLHHZWfjMr#esD@#$+XQM;GOq7 at sAi(
z5C{xOY*Ie6 at BYgr`(?$Ves-{-53}T2-cqYVS3GN!(td28X9QK$81NP~0SMUe-vN6K
z9$>xqf)2!rvEYa7S-=?v2+gMNFDT&7j?pYovb?4&(_N(6+ua@(937z>^9ee*7w7t5
zqPenEwxO%(W%dx67#oIpv{C@@;n3euTw3_{$jQlx&hg6L)m2{KxD^~x#$E1vvJTG3
zJp7F$&NbKLWjP2gc{x+-e<tpwLRZJ^XsPSc0<^b0#wTQ!*Q&HL3Lz+Hz3^LFPHth>
zl6OcY1HGrKK$3?Y+SPSn_8B&HGda8;V%hVI?Dw<fjFpLo$>P at lGge;5O_?=+R)V&_
zPKH`Rix(4nWjfspUrD-eZ1?3tuL5HGuOEf@!la5W#tZyxUsV>_=crDDQ@?tMCR#ly
z68;RQcz0rFr%+^@BriBEb%*-jTu>+Jt6O{B!%o|^i|S2JC6gP8#q^*Blr*EiByrih
z_x#Q_mR|w_M|8AMSXS2`Wn&o(P70oMQjh)JFi%eBfkt%ua6*}w#FiTQ#idE(zI^ck
zr42LcNNPd8lvRzoK31O;_^9s5_5krHr^SYeUCT6bX=Y*Z3 at S2hL^P*gbSICn>VgRT
z4TaW7lik(1N4{nlc6xraCQ#YNmZniI`aD%ew&{R6bANY^5`OZ*P7I^eB6x;^#Eyh4
zLX{P&pMHJ at H}135;hwDiLH7J?y2 at WElj}rau}?sf!70nG&&su1lMuhJO<$j%-_b>T
z53!LF-0bqwcYkA7%=@f+DrgNk)p+f|J-Ann#|X6qc~>DPsu6^_w)gh<zVgP_(47PY
z%eJ*Gc}s;|G8S~-OiA6Q;IL5bcXcE2**Uo_&1v5<ZO)ie{*op9brWu#_0u$?xgpz}
z)_natd+*x8=%uD%5d=MTe{~<mSEeR49X2US27M056r;4P-pOHfCd+HD+A<9XzT%P)
zHk8bwRNX^@ieSi~Ah0v>iATn8<}JELPqGRT5+zyW(RGa5raMp at YfU>h4QkClU6LND
z@|mjBfkyX&*&Y^hnsiph0+7?bhuG1(YnSs~Qp3Sf^=5ext05;eWuftEW8L at B#Y>(C
zUUo*^iT1nUsST-{4yoQ^XO3ND=;Q|SIZEZ^2fiD<PEw-<Y4AcLrS#J$Wa;ifv)q?K
z;U)t%8P$7K+0otk>dDJ-F9d$ibgG>d at q`;iNJ?w9G`ceyndtgfQKndas`FS{ys?Q`
zL>Qko0HmM8HCbOQqkW6)fc#|`zb&Ap_^&~M^_?I|m9&sdrqpf|HD;N)pYbl4j>n^y
zGR at S-kZh!~PK9I!!N)$)xL{-JMN5!}kqGEIo8Ski9nyK55IE59t%Io}YJ|||+ZzV6
zZJ{UNkY(hCRZ%mss@`^d<Lw5&Ee|ja+q-UP4PE4JttO-rKh3h1$b5ED63F$k+33s|
z>w?vb6UD2EFi};fS3`<9jTSrR`%^PQG_$0o#C~~!KziE%Bz4Ys<ZsQnD3!KU;gJBU
z0^QdcssKx<ot{4*R5?E?BfM7eky>r0$>&*u-)_|8Kfh={j}?ZYxXE5^;l)e0FK%I7
z-Ga2{kxOT2$ZpGAf!_1?Fb|mAR)&+NEl1M2-Ho9y#p}t>1V7QV-S0iMpvm@=xXMJ1
zfy0B_;L?8-jC?2WNO?HjkaKII^LbHr-{jd$fMA+5(Y*TXU}28bGMR-JRj$FHXArw$
z7QIV#stEFvZqbUJ65JI0>mstJyc;2IN?}WioKXt-a<O*I=j1(c9AQR)+BFcQK1Na+
z=%{viCEo^3<Tl&_Ca1A?lok&5J#U+e)^>}ejL=O%AX9WZ=~~bJ3P|4ZT2U21%S8l|
zu}T+E2F^+i<Up(dl1%`vId$#26lNgQ!F!hMkLIH6)vpO-3of~!n&FWVsfdJ#;hNga
z5T{v(p*Jr*avx7av<MIwx5qhAVvcrvJlysU?G<vmAM)hCAvFe#%cP1yOA$WLp{1^N
z%+WI!#PE7?Dylh~X78gRsik>Rw^iscAA`?Is%Lj+%x$UQBjVR49v`B?2gmXHF7hN(
zDr3i>Kq at j$1 at n%kco;~iuD!<Q&6TZTUuYPB{_>+w^mAP1nU(Te#ksRNq1Ww at KV>NU
z+z-5tYd%Q6Plv&7mBN-ros3C|kNoC7a&kfshNzX!LD=-22DLWLGda$c{KQBA6Q at fj
zV at q2w4J>)RcHFe{pllkjvMDa!vLr9I*fcawhjp~&liE2vTxx4$FfVR9z!aXHTn6i?
z4ghmTwA&YYy-c`SKX$2j3o<|Mq-=(!#NJn*+o&$fay1C|IoS0Tqi^buauR<L0wlO5
z{R}s(u;{ikiNW at fOes%i{e#yn&Sn#DxCd#oynbRoEH>2!wzlbb0!^TN#g8WZO9m=d
z at 7?!Hnn^Bt?)m(ax79k6yIJEq_dOm2L{i1;afRzY3>qcHc7KR;eFUs!)|DTog?3%@
zC5A<ec~|pSu-CAqZ#Kmwxq`j4b+}IF^Y(SzD{Gp5c{<HBo>@2f?YjxgXc?ym?#}{Y
zrx62nO5I$b17ZPPA;F+fII%D^(boS^-s*Z^D7aaEEom6FQBrYZspufsU1uWAMU^q<
z?_k4ME#QsRZwxjbaVCo-(@uCj;s|m7;lx8SPCn##wG%XAX5^K>?#M^d2twUVi~QAi
z3wf>oj`&{%Q3LWbu!^-$v=-cdkNS14ng(YHm0p;uP;!O&dEr?sC*6lXUw32Jn)-eU
zvx4sh&w6P|GnQ)6L2+4SR%d3q_&0XfGs1>JxXD)YqjWbtp8*>7=R0>`&e7rsGuv1E
zvb#AnHhIH(At%2~upq|kX?qawP^plc$Z0tB+h4RTi^`~lVxfgM7B@~(?jX{=71wY~
zrj|rwJgqk{SGC*oXNS*icZMI>(0O)0+&?SveKQH~g59VcY*Jb*8w^~6i+v<&6^ZHA
z!Rv(#GmcB8VjrLSsw8k1i_h_hM=7!x+uMtkh(7Xbb^9~&QIb8rkJES?MY(?oudmTC
z{$5V)e51@>gGwE0>T{!s)Ewy^wKQd~2L4GSgx8O-fjZdlTwY#<qHA8jjQUCWw1$uK
z=Wb?m<nzyw*Mka#m}=|mfoQSNzZZ>u&9 at ziOCiqF(!>?+TZNQ*zcq&QC!D*YwOR=d
z3$hJCOT3I<6BhUR7z(S3 at 7V1B8l(2(VfPIf*Urj%tSH+>c*;VC#?QTWUn<wdcE_``
z)84`JRV<=;_P7*6o2O3A1quL+e3Qm8P7~<v?k``MU^7u5>}WcunQf`i5dhx>G859}
zyZ|VV`T9zYd~n+ytK8+_k5X9$1?&GB2zgLasC<tT93kOnYuM4+_cv0}jH!C8Df!Qg
zwKL`D%5H^Y{q$k2iPj0v``>2alhwkFheC<wkIeU8O8i|JopJEfl!p|$bb%yg4#S|@
zPb^3B?dQBZv{SPScO(Sk^FD7UWMT)XW8$u^I$Fz4UPHspLKm3cKZv~0EZ^GNGRF=i
zAJTHLy^#>b0 at H^rTihL<$rbAi9#j$Q;%4OM*0$nE9INl6iH1kGACYB|gPN-of0Ysf
z at kdMpOcYI{PPa29sjH=iVl5*pT=WXft=O9%4MeiCc(EpKS|&AoZ)PwL-KTw91M+*U
z-aO+ip<d#!2zd6XdUbWhpIF-APT79=3^PT30L7P-`Cv<t#X%q6YsX?9&K2TLC&Xma
zP;Y at Q2syrJZ1wor@L%P;23Vk}xVTHLPgKg`3b<q`<i6|Sp=ZA5&}+9~kJIPYspGPU
zETQqfpQS%W6xf}p`<=4u92`30+{p7W)u%=G{IFz+(xV<4k8_6YYu{|kTD#5#mMCg^
zhYKsWp$0EXfj=5NAfV2F6^`fqPQUFspVJx&D->ZQ$)(iMv_{8wa-LLJT~cADz&3wU
zRwh}=XWI%d(_2hSdwq1JjIq|g*wQ#mI-eU`YL3o<RFiH!WiT%J#qtzL^LFyw?{K(e
zU|@jGSGx|tK)B5<KM$Tx4+ToCBB3>nGarn3zKiq>+wce-?IgKhj8frdUCZ4ft|5N0
z$l~pr$jdRu@{CfjGjN-(vE?mksiAPb`{Tz^E=hBs0egrj`0ckPUm9ZCAHy5JL&=C5
z;FO&Uhrm7%i42qJk%SinpR)^))7YvmSUEl+J(Qf-UCh^Olyf6uK<EGU*wqo{^`U$X
zygw0J5{PN!35Lcz^(Lzfjbi(0cBKEoMNE)vaHh}*svb}7mGtgaCUKCpk<N4jrs%Ra
zk;c=Hkp7b-Ma8vbRF$PjI^}CEn6c(d2B0!#VpCTdn}O(_(7i6)-{4?|a6F<--s`jk
z5sGG60){OQxR-UFRen-+YX5t4e~yKP1^r+98!vpFaR{LyE4=Gh9(HwpWSrCEEG$B%
zIq8?es9hLy)7x3(g at ks+602azpTT-M8IahUk@R5^7lIKKfQATFB7y#giwl4xZrOl}
zsbS at e5+sr`0`U3c{-pABq!LO@$0Iv_h)Y%<uB)qCOPb-SvgDWtUqZGNC06d*+$fzZ
zKQ9Ot``pUktKIZ8lX__#DFaP5u5_^w2diJZhEGq6yVoY9QCk0``#7Y1Rm)Q<iLtEo
zW$W=ge1Bk7rm+>j|I`VgwUDmy?-h#{gG;0PTYyp8M9glI{5}=pb2X^@zrNJ*;ea-z
zO+0;v$*Nl!RlT_6fXH5TFygnp5Dxk=DH#?Vp>8j+V`%s-kM5AT%&V$T^N7RQ_vK;q
zxmz|<%4jg0(~Z)PsL&QDKj|LUPPDKN8RcJS)X<!xDRrG#Q2x65Hhd0b>YJvNJM)vL
zW|*VTPn(Im^@Vg{Us9ZCw8mD#G*a1L|6vD2J>Wfn|x|Az!G!!zK}_v_u}#K*Hg
z!DLA8HdIFHxRMsV1rd23NUiAjyVC`1I|9j at yDq&vnQ9h90Y{MXX?S&OHCKFVo2NHE
zy}T9MO7BcMleCGJc8S#6HM!s6;1t~Qc^2zv#$Nf{LC2!W&y8$TYmzcRtI+JCZm1oS
zHiJHigW*S;0i85{jLoSZGEey!0#;Lp&xfy*l9Do1^_+ImdE;iqVkXn?B;zO3U3XJy
z at 8xayQkui7T2w%u_m$sIIwI6T6QLeFcNj|1I50)NCXB?hUg~|#z;<8d&h^sASkTlX
zy138t|DuiBNm&o&;yoeH&E9sA+luU@$ocEk(Ee%m?{Vrk`lDc6qAfd8`z$6j&HDL}
z<CoR}tJHVQ-!`icZ2Ilvco=WIKVI)ksW7Ad#t3aSrye_%Mn#rql_;t}iBb=*3!ie)
z={KW}LO+VR#&dXVjN-~EyLI{>fT^q2(<o~N`1t{GTh1;<vzcXF1_P&NQvcF2ybJCR
z_nBtpOM+8Qw;bL=+O)`vh=1hHb*FKtp(EHMUWaBz8%cZ!QuZCsHV>hMD|sooUGrY2
zKR at fRlB2av5~!BfoMLOXX3`6($@SfSPTqn-LMRM7${KK%4cekYn}p%2iKyspXN6Uz
zt~JaG-E$!nko(dHf3bAz9I}YM+`7JN9Sd>|A;6jttykt>QAaD6hXfydG1#{2DYf6V
zq?jPWicb6b`n}xMV at LDdkOL!1eNn3HH>rcC9A5|mly7)tC=PpidPc^efKG}ZRnPXS
zr7B^Q6&fV7jwy@;L$pg*!3Xm*BpQ2tm&|#4qGbSkYbh<u0|KrsBS`N(!-Nw30ueDJ
zrKR!0X at D8wb_jX7q->mx#PB;Y4S0z6tst0Ag!<XU^!-9 at w}2BcWgvxZr7>>b*fiG=
zJTiaCz-|l&57+Vly?Lmd4)c+=-l06d;ihsZkdx$Dtg1cMpCwD6>IYfzgVHt;9RFxK
zkWy?-rHkU;c=D;b&?+jkVrg-`L=4Wxss%Kr$cOn!zDqvpS2x88+$k<CC^3WCGCb>O
zO}}(WMDY}k1gYNCb*h$jw{v+ at Gv*F)s)kGZQAC41XC0tYEp2TX&|k8B7PE|V=6AtL
zvw<kOP)fj1Y-aFGT0ok>+XV>ix9as5%Qds&mIICb-9Cq4hhI`DSC-q3uE5 at RNzlh`
zj6dIsC&<cz%mUe-{;>GBXq|%I1;e4duJ~fTB@>W*cEn(hyx9_gYRSU-+)zm2{m2R!
z?u+-r$8iU?${z)A55E6f9);jikTHc__8gQF*TjG&Bj>+DhHLzkMBb|C?$_1%&|NF@
zU~-a@;cV;*v~MsJmW~;&9R58mj0FUq|68FXBhSBdBYvdjj9cP=c)<Q+IUM}#(J^##
zsQ1^orgN0Gsbfm#Jz`dy5dt!HM0>6YRw2y1mB&-NPT+qn<<F~$(r0E75nq&m_8#1A
zJKM;^S{BQ;f=ZD$Cuh1QH8Z6(mHG+`zkbDUN)#5}<E3;SmSS;VXhd{<*lpMYKUun@
z0e}@&(6v5hXg5u}v+?R%C(P~Gz}@~ovT}2zJ*PTM_x&ivB0_Sc*!h5Lh|Z#NJ+?R|
zRtoD0Rn$Q_CBQGnXwvPowy;OH(!bV$fjLNA%iH%Y{J6KV+CoQtcje^e7sqc?q at A36
zwUWr-pX4@^ulboboU^Q?R_D?-&okqYaEw~w@$#`vuS_G784<dR!Dk0 at b$6%Lrz(wP
zp0?G39>U9)mh8Z!BTg2xWV6CziFP#|q<ogrw2{<`bKmkOh6WuZgtRG5{c8Oq*fo^)
zb5rtKM8%LK6Zo01LLCE6=+*qpy9>vrVL>Dgu5dXcLwR(Ge(cN1Wf8L7zc2+vM_!j%
z-MN1ebR9~9a0$7DW4b-ULhv1j=IG^bhv!=tWq8c1d!xTH;27!awG7PO`xYTS5D%~*
zYtg&7+R@|@szqMD&A7^-l&N{(MQ at 9Nv05+!&R1GL4SIU@*aiXnX(Kn97Ck-K at K!Xc
zdAMl!O^KQ9{iO8WD2SNNooCQ|@8b5-!M6Au-WJU(<TQD7rve+D>1Q-;jafs8(_Sa&
zaRC3j$ah6V6#NoO#9ko>a79hdk`^G396v<*UFEc1U9;uadV?+a<P5FPDwN1hGL|_0
z92yTk0IULO8;B^Wv2|;ZA=cw4_N4665Jn^fuBEX(DZhD^=Oxl{4=Eod>vFyk+wv9#
z|1QWXA^C3Q>*rVdF8`aBvr8?N-7URxFE_sh2Wp-{++`#4pNWAvo#J4BNR3Hml73|<
z?ui5-UWbiM?A}G8j2S|2c<k?1ke62#$%v!N;O43M)b;d0-p~yA`!JBQK1F`Rnau$=
zKlhqOd{fzXafr?e^>s5j(*LrzW^}!W8XMBa8NWeoes`>KOtC*O=Wc}kM8sLPL_uD|
zY+-kPFp9Q)QHwK_mzUT4{d%gPeIpXL;$cy0eUzk&VhNi<guFSalFxNbMW=@1c5tV+
zEy|)MIx$RP*RweOCBJ&Xghe_B`3tp7xHVyI7{yKmeLTYOeYjfG2udgr?~IqS_G`}M
zI5;1a8b%&o6tSSo3GwV`4|xmp`kF2(?AXNwJrXu_g!{oA))>0lQi37lmNg5*9cGjs
z22@$W1rxX{3;p2bmt{Ga%j at wWjCCkB=}hkzR at Y9A+NboE*ky}kaNc$nqcF`|BYbW4
zJ-Plft at 5AmuZ5MjzJ!ajy#r~qS+ZN3KYOi!qL<F{Q0ac&6}!Dwt)e`w+apzEJK^g)
zd&=DV!!#~_q9u<k at ttT?O at +PB<Dv_rCfZ{s^z9O*#(lq;sDcLr4!`kHkm-eL=vijB
zNzjGhJiqE_^8?8Cbg{=z?Yz$kxddK*Pl!3oPiNnqfVp2LLULqx`F-X6llJ11y6CJ?
z>q>3`U9sJ&^DWh)3^!|wa-UW)_gEB8 at XJ<)L3{Tg=3RL)@UF$Z<a>Ax#iD;f*v~r=
z63_HM5s9xm*#Cy=_E1)e0qEH7y8i69{s%fiZ)q03^i3+)-zP^On{dwYIsFe;oZvNH
zFnRs!*DuJ6^HQgVyQdfL;y8mb8m&vuU(*OgSVVlQT^N$kc~m?uE;Rdk!MQ54)@Qfb
z*$T14xXv`s__{X0eW|r2-QPP(&)z<|1ERsidYkCTW!N;OeCC-!xEg|LNc#*0w4cs{
z{(0PJa`}!uof&`%$XTINuRlx>o%Q4?t_`euSkN?~15p^NFzgPleWe4p&3y#H7cHH7
z;>%zGm0*TbJ_X`W#M*YoaLox#7F$%QXjBN+9DO at vaShWH)_u|V?jrK}a7HzT`+B|r
zE#}^WKTJxHwro3OQLwr`DG#U$o$pw|H7)tphmMcDuW8+8kvHeAzU`$@ieka<qtPX;
z``aN53VwvM>tK54a#<)DHYh at MEBn?X5|_h3?A{DzDQH`)>x$HXU5ur0`i=$lw?6G7
zeUQqe=$xTxM%d~0m@$kMp2y at k!c1SymrLAr_6##h;+Ubv1GQrg9pI_l7(F_VGo<wW
z<tbLJ_jz!?h;MT5oU+8oEVfiY&BNAB-L)VYgdrsxxa1F63zsL06!eLSjKsp;o`lKw
zxk^LQhlDpWM$3{6SJjy4<i=ACTRt*Yw+`PX25u(9w;VT{j1UvseKwn>xKSdE7IZQs
zRTotE+FRdLwke=Ls)lT*v{(Ho{gm&q8g~GRK5K-$KfURspcuWEB7=i(d5UVD-i}Ae
z;bO}WIRF5deIL4J2(l1k3#m)@4_U{M9Y$yhpciZIxQov9bko(+HC|s6UDBl83^$s1
zK5-pKxXDcDqQQYFsi~<WW;YeypL-6R$!2_V++yvmdFiL$vu82aT>RZ}(kg4Mx#S+|
zY$Q54#Te9`bp!RaN55^-DLv7X0kXLLb&DsTD&!iwxWR=6BRO6`9l{|wMr7Mn5}+-R
zkbwCXaX^5b*$*T2F4s>mCT%+o2~Vu^(LQj!%Xu}lRI6Wo=mN_kG0qKEhM at N-YdhCE
zEEgh_g3w`?F?C1<*(Qs&RTg<O6YD@%{Jc;@Yo<k+?^R_1T8I$r0Y3?gKEYmW%=%=t
zH3D5NIZB1_yHNC5XxA8!$kc9}m18#A4t(&_LT$D3=VX`TgE8o!({r1Uj?@K<uqzX}
zAnVge(OVcI=Rx;|cFFnkixx0gB;o7V9v#8i|I-3UGXLFQ$Y7$ly_!RsJi}0WW-PHS
z<rf`8Li;w?(d4eEH&@Qzzpkf8mU5(Y4giy-_a{T}Q0MYC0*+Zly`lx#1pFjCm!p<Y
zdv8FL2EYrCF7nX5=8)Ha%t84Lpb&g#wg#{_b#cgg;9U)V(4rZ4=RPV$CgYQwceb9+
z6=Qzd{zDvIQ?S{eF62Ai;FmAjS!{hV34f<+1uD(9V!tm}Bf7<d3?w~$d}<Ds+O9be
z5bS+%p56yJXR!&IZ%c;2kX+Z<)Xj$e!T$(S;{22{mmF at ib<6ibHBDgB(+YR{S2Cr#
z{w3j|Hx}*zX&Ty+SM4|Fd&eFS?_bE{@bMe3iX7cIE=sAUd0YCe_$GwRVVJ5Lb?ytZ
z;3rS;&(W%4C*y6TCr*qt{E|>n8D>3Bb*OW!CjAy;skyw*?^+EBX33DZ+MwEQ;=P_s
zt(%=wRE>%IV#?6x6cmYm_;iSi_^93XjdUG53DGpJe?W<0 at D#0Q2 at j^!Tr8w#Q2qY)
zYt*m!-h6?8WZr$6x$WF1t)(bL4uVh}hVE<hb+gV0Y<RQ0fs?q#ZQ#_F0z*Rj{LAVP
zf>f^fjPjPs)}6Hxq+W9f;%m8esrBjS7_?sKL|;%42K(8Iu)vEJ3jO!b`ek_N at u>|y
zBh0hrB2&$S6YgP_ie at M~-0F&{`%#IsCIs`MuW?~|$iA`5$7wqpMz^z6Du%8}b4gaM
zgl1euXcj7p52$7b-An2q<#ok(RMZ8c7 at b%dr2R2-M6<bPDFANDidE5$_iW4z at KphR
zN#gX1{*Sk|H at p1Ivg5$sRBUGaAzR(wX<)PHOO at 80C69f4L>NCHW6bH_<pII)akZA;
z0|^L=YFb2GSxI~b<tqc~DQi8qWNqH4?oFM at z%Xl)8UaJ6JEjkEr<bIcJYaN9j+Z`d
zl%k@>xT~U-79!=Iq7&38UgBcgvX{|hQse?2 at h4iST)r?B!l9}1eQ!QFs2UUa#wS`s
zc1b*2sH>q?`I;j6A8UVcwXKiW(GMn*e~f}kdB~$ktZo!9w|x1Q?zLk^qRE at HV8&E3
z^guT=PqtT*nqQD~wtJCFCMiV<qe7uGj?Mk*>%sO^+ZD}RwV~MMQ>~viDI#|7%fc!b
zRHPE(+Ske at 8y__(42Ku^fdwbqo4<O_0CmmXU4q3F%fwxG5OkiDqF*lH=Y=xWVfsv|
zNa!Q=49`hb2 at k-PEC*Uhyh&s33hmhP->4d=2e5`+r|Y4D8hgGA-KK5^UiZf%bh)|8
z3jTH`jNC?^Sy`1O0L;+K+hBY}R21gl>GHzz1{i+${{258jzJ4c&eDQ3N(;{BA$6Hq
z7Dstv@)d%RbB)I~*1ta-NFLmUW=Q@<vMwx!5q%GJy1K<`y;WOs;+T}6ObkV58TJ`X
zV2ICC8m+1G1~GZucSss-)ZWKO6zZGdcv(QqkXP)GHo5D>94kuN;a*^BXwdj^{tKn6
zRn~I-Ka;o3hD6Qy<f~kA&sF!NcMRDGd*gbCRd<XBJ?<FaF$qUck2vJX-K6pPtJj1R
zDyD;#l^Z)yhr=f|tYNyHwl||h5j)07PVej_BUzR{Ci at 7uT77~&&wQ37tp3*h*ut?}
zbc_)@c<g9nrqmQ}D4-1d#B5Dtq}0S=fS^szx(d-jGQX1T;+u6J%~#2sEbqfqU%eDV
zlZ>|qg?q6~qf~W8+MsDPh&~}b16N{2-<oC;9+np#U!8rDm#Jg&wGb5A8d;t>R0^DS
zY(2K7>fKu`R<DXLYm4`KNyd6nMEz%ena%;2*2FRMVh6n|BDV=W8LFfYFZQ}PlS%Pr
z_%UwU)fE@*-CD`NJ at 0tW_L~{=h;};R+}(hkfYzdaxd at Omg<X4RmcdSnK*1%OsT+*|
zi=`_hP-?N>H0XGtArv8hwCstWm_U>X(xViJ2rYO0JA|ax<v%dK5LHIF9%=|#KK at Q#
z<r?y at qXX9&hQ~EtaFwSuCh+g3<iC)UrA<7jC=I)88qQ{`BY#HW%VRL5tX?^WkWiE!
zSytTic?)e>hx7*!BR#o@@EwJ)o5Bj~Vt^@PG*R-ZnuZ-~1`daFnEDnL-!WyrbGXZ}
zcBvz3LMQrc7qgh7%A at +3NICWlwW`KOTjCy;m;tq<kj4;dAK9FO^u%eQpnz1iWlzUL
z1!?IS(V*Q$NVNO)-)AvnINIZ&;c9`;_Dv->vM52TIXlR?Lqk6sSlU0Gh*S-*BgHsV
zXD<)9j`l`S7UgY{ae|b<Clt^;$udKo!7L_nCMKU`sIMQ=S+kYYy6)dpF;sds=kJ>e
zdn(w`__TcS at XXxzle~n~_ZlUgX9EzdRpk|nUR9rapl9P(1PNMx%)?b#?)~|{1}9_6
zd%Ll?eRr?_0AgxwHg at Q9OvreSIB=9r##Oyqg3#hFVDxlwbGozpxn+dznqk(- at ApXa
zPvdm&4=CH+4de!1X2t9IXv=LPz6<txFM@|&Mk&VMt5K*Km%4pNO2ZdKTv3RGa*NV?
z1zFSo9TO`(EDi($6$Vj9M?f`RS0XPmd*x45_q1+%aKrVkK1^Wv!%n9f{c4ayXcP3-
z^^XEHL+k!5ZdZ*8eYLZKQ at B2w!b!k_YUK~QiNEH9kjJTIz^zY3QZMV*TS7U at FiT+@
z at tDn|DBpivp=kzj^R5%0duQLQxhfC;{TA-aR;TVEwPO6p-ykkGOfTpM;7-yYAlR3i
z!pzuauiae%F+4A<4C*2V<J84D{V at qq1-<_vRdgizm$v3-ocO4|y*PuHUARkh?(eU1
z=YUT8HFZuc88oXxRK?7zg4doSwme=_%dd9~zS}-vB&0|Bmslnp8IZIqY6LqvQWyzn
z$H at nsIx~c;wV*!reNi9roqc at CF=a9r`X_MW<;<H2EE7RyA$|Yp-xSJvqaU<iY1-Ys
zw=z at SATf~XpX+$LQt6nhm{G>==ZuPW_ft&v65CG=&LWjWkWtV!KE6L)cqo!%)5#kp
zu4O at uDZM{qD_2R_`@N>>pqkU`1 at PF}O*D3<?w|Us9#&;As``!oZ at 72rn>P=$*iR=9
zr-j8pw=Cse2x0MHhgs+5CC!5`3r;yxp$XVNYSs*YxfrX|B-Xmxv%@Nr16IU0CyAnq
zrIv=i`37$ge?^t1bhQX^?u3%%zRHXH(7emHDRo(+B{QWuT0NE-2uJ9`<bp<SBybbD
zH*n>leMuN-+c_4nVB#!K%X(hod)YmO+xu at PSm$k}0hV)flwPll5MldGq7I30!cA}v
zA(V$y$X~)Z;GMxNXhRRKvLynjyxb$K3b{dCDpuQkTtha?L#hae*ULWm1 at 4!o+`f1)
zzI~&ku`x((`a1it#Sfvoc+ncwS$FL=9pYJm93qNt1Gt$&{+1mE2UHLe%A0CKH}vE!
zLByB}m#;>lm-cwYKMFkj1N3#*#YX=)40u<qIF|Py29pAzN53X&RQZ9v9OG>={@TXH
zAGbNEgZtj5xsd{T8m$pGGon at n6cmDzrag$Oot<{<D)7a5C_ at 7U?Zn+WZ-m(5>+-m?
zVoR)YqRzzhXP7om^j)?#(hN%;lkt+E0}4$wH8u14`X!#SMaKd7jJ{GPa<Z22rmAw_
zE()yK(L_P|^mdCi+WAO at i5sKZuj6!Mak`1;PZxHy@;bYANmCMHePjV+Rj7%JiWq*u
z4OAUp^~aLAh+x|N#&Q_r%!862KOY+U)Hc|xU&h>B9kmmuy)n{{5*z>VQxY0doAz_C
zprF8<3j;_IH=AW-EY*WrW;ATJxXON$cTVADH*e};L5x%`F_8z|IIVM6uKt;85{Q~#
zuX5iDb?R<Ew&NK4W!bMj{iC$%-P#z>X7i6)lLxEHLhTTUQ)eL``LDwz-$P?40CMW$
zkr{l>s>ovD>#-AT#n|g}=x&GivwXYAZZ?UKKbz1+oyoqmxZZ&^HPGu~Reo}7J|Al&
z;!;gvrw$n$7H%$vU+L+QsO#kpKs|sc592)~?hC}FM5C at 8*>TZ<i&+Y3Ze6*&jhvF1
z*p+G9C&p=ptq0)O6WUCrZqp;BLV8wk6tGKY{4Zz>dS&Av?i$z1jy at q2xT4v)OA%j@
zLD+pMR2yE!1YN at 2rX>-Krb<8_5*X at Gbs^XCKQGiR^+xECsUasvxOqJpOSPE8F&6^;
zKN0W6^zl#uRbjqK0@}(d>!FRro62K_j+$Zf%&1+({Gzy9GOPmQn*eLMf=Mc~j>NzR
zCCb6h5~7rv8Drx)-zl^ORO-hS`^5lPk3%fPZX_i}m_y%b4pgt&9qX&TbO~OZd*9~s
zj*O{<(tzIAa>}`%D^jdu$s1N~9{=+eL0B;W0uE<Dm&Ah?hrpA2ZKe;_8^0xr2A_VQ
zqkEr=AHgyhmM%5B32N^Lkhr5qo-~%nx_#YBkS4aOdq#TgC8+`Wb;iR2lZ#DSo`N<t
zz?@*^@`5#IQ8hZK)v`e83`o@^UXnUws(}7Ajco=W5JIV(LRDZE9zIp+U4>B`+-(|#
zLUdK*@8!2tCG8U>y03!0A;r|hmA>Purc845-5&5$yh^fcwT30Qgbmsr^h0JVgG!M#
zp7fz*-zJGIqKMjtcq#LQeIH&~y?Rf<4|fP1;_H1O?91>XTuOa#XgE+t<vW~Vp8-xT
zSq}8(YAq|WS{jVy)msuHQEEG>BkUER2}w~H>+6r~u9izt{oGYHn=@lLE$i!%iqgiH
zrq(9{yl7V^MP-VO%hoezJTcp5%Ud4j6VkzJQCf~4&+%t>9X<^4sv%r0Da^h{c6F{{
zo-WnnL7)+Ol*#+G6 at qlghw?T|f*w*K at WeA@T+OnTH!KVkd63CU+co=5bxk^lsg$vV
zfQ(LcMDtPvtv)7uc<HNtBqCOpw&bnZ?h^cErhfD?L4Hv>H${ovlA%j%rbz4Ou&Jcs
z?QJQ^Onagv=%%?opZ=VOG!Z@)T^D(yuO_pw>tM at xbLO;ii;J*h_Nn~Oea+|D`CX5m
z-$_#P`VTh<F1Q;B`ANzYRX;O0p?a8cM7d`BiqpmI_iBr^m6dy;?aJ<d=;;s?QWtFL
zir$=pr12%Wh-Ns2%km4xXGAPRZar?TG}|T;`y0(SJf8OK5NsS?%4F>pk14;Iej$b6
zo{fA~JmqRp{x2N^iw_xp-kayj0Jh0K_t}WCoLU*nQ8SkVSk>GoADpl=<${G9sntJw
zZPZD6qO##+|I^0hA>=fVpsIGqQmQn1XJMg*2Dwl}eGC*ndUARBBAW9uGIl2#WhdSX
zJr(G3*WEm50Ve}E$=1!rDnaq2L!`HMhz7f*h=n^7amt5%-zRP~MU}<d1WmKQoayWt
zhs2any&dUpuu<t&?5Xl;3t`x9?zz!BLu3-qSmexZ!#GP7jyF(efBvPO<4nQ^Cooj<
zXh_I_g1ps|_q&GBj)Dw0_w{-=PKtmX171d_9$ti>nYUefhM>>d{G(V$`qUD*-0s;*
z)QFGv*_pnXkrtsi at +-gnD%WV6Hi6YfMXlNKfo+xO)dPZykV$OTt#~_vRjT^|t2_fj
zzmUlN`S~3hlR{d4hg7ZQ=tnaCzUN+LOMW7v>m$D~^}=UY{7=GHOPgR5Ax64jh!a;x
z at rXYJQRaSCRZBmolTl*RT>Jq$AldTO7`4PAYfd*lwfCQL$tHZ~)I8hxc at u7jm_zLQ
z-_1t5b^do%gN4iexw^W|qS`si>Bbc4kuC+E4$#w)FL6p)Q_n><jbZ716h9L3hvp&g
zi6D31L!JCS at P+p*`)rHE*lFyGXwYXJl*j`2o`uYQDyZ$wrLXu5Cp0~=a8=CB%U at 2I
zPuY++8}F6W)d%$L2z?lN^fJ at k%TatVUp!sm$9)|s7IuJ+NZV8ytNPA4(xYN07v|BW
z+Ve7_qnO;Uyn3xF#NnqmaYBUJ at Yb=AMVJ{&ejD3y0+-XiaZ}y(fW-sp9x+k-c|5&c
zOdMVI*h-(`7}KzIM`cq8xnL~B(!#2lw+L9k;)-X1;REo)BeRzhZG$L<i{T_p4`J~L
zAlCro4qmgtPn9<#LUCdKuK1{y&7Ba2(W`h5xj?-MIj!iR;lACM3JOcbn)Rq?4?vGk
z!M(Tp**5G%iA8j|rW0j1S?+jKaLenXnmbrpY at ATy+>A&O=1UnTwA&uw&D2XSS}@$1
zKUZz?<=iDzrT_x_dtjWCTOcJV89zVu=;4=f2cvDLtxLD{B71m!K-Kffph4_CfVakB
z)p&tiHO{5T&9*1A8i{PGF{%pju}B)rE}5>;%fx}B+7DW!Ej{{)W at LW#b%7I?5?^-l
zqPlx>MGl>5+5A`4WBF3fUN4E_wHozHB~C`5^A7t at 2#{8*{5U#xu!gF%W;RPF$Vfks
zrlfbGcU&=F at fBU1jZFK@rU;2EQ_dqNGCF?2>g?m}!G>&)60_Z?pIHE at fJ3?Yox2_n
zs!PmLpf*Xq*xq-B3=lPF63jeHOzPayt|qc(+s2 at W+LIkhB+D^Ka}PH{t!4&vzQ$Vc
z)7?GxhLK?ZMF~IoCdu^HS5nLiR>e<rcGFIjff-899loqgTPie01snn*dG@;I19gi*
zXv_Vn;OQ^h+n(?x%t>Y`H-QNF2wbD#brV9tn`2tOav=dVgn8?>2EzPQ)3QHjS%}0w
z-is5C$y at TN3LOy&I9`08 at 31FxwqN1?z+hZsjR}4XdQ|7#ouvv5<G%)8=_*|g{_>}%
zSl3z4|5))zOs4Q~TvL4{=<Z2YaZJQtZ3A?((dDf!!o*Fb3ZmO;i3V0QapmFuu%fDf
z%g9*tO2&Ysp#t#%c~V3qX4~4n#Ia=(tlW}Gy!tfRTc979m!55!e821WmitGmbn~}8
z#j7<B7+m_h!#UwI-cQ5;ay07wjSV at UKFe2P)Y4W-!`;&RLUAFztkkZ@)M{tfF~ZHr
ziTu*<zHcRS16Gld4)KrH2d58sW at _XtDsco<2Rlr*mtrJ87K|tW06^kB-n3Ww_-z?*
z`WerNKC~eemLx~-GLu+LkEIa-ORjypuZuGbpX#&wR#2i!gV>AY7!RHM?-~!C_b6HG
zH!Q=oK;_ at w<B7AOLQAC?AGvCKuaWGkfD_fbdDtk)fqSJaijp22u$}~N4~lws#xKHj
z_c)u(zQeEsMx>zb-<Q>=&%=!S^X%=ff0MF)^fAt%b>KOxr<+u at b&DKwiKqO3G<}CZ
zmGA$55{iscghVN_WgH<ZD?6LRvDY!P;}}u0$sWhb<{a}l_Cbm4J<hSoK33r<I{Mw-
zpWoMCa6GR2x~|vtoFH7<>C<>%;5JSEi3sUOors5QzCY>O-*bgq^b8Uu1GvO|{|^7_
zptW6;oml}}oF~LjPaK_YC`iK`EWBlRWAD6=yrp5Ec88~zTPjCc-bk3*OY(>G`{Fb|
znoN^C>aKIw99C##>$v2uHNyuB^CGew!hp!w3l=GOCSWT0<m at 7<)?3#3A;;391ugBk
zJ0`+9H`#P=Yf at dw@S~9=Zg`z9%)yyPtj8d$=ziACyKus}UEA~O5`Mo;A8d^T!@9O~
zT~pJDjDvZEU>292R55Z{sZyk9HHJD>|2P<8h5sp%6JIQ+)fa(Dbcr-kvgZt-ekamN
z=Pu1SSd=P+Z34WRoJV{oNS;{SkF%ibEhUbvWtdn6S{Vl_uDLrdP(`{Coz}1YFwLtu
zyjQdN;~$g}`Yr`TPItU7<xufu_a}hAA=}2|xiy-UhFb<`tP(APuhKE_DmXmQF!?6A
zecnCsG2F2uC3UgN_Ssm-w%p*xpnVaMp~Heomdr-r_}d%)!)%N<D>PBRq%qUcAnMzN
zy}HvKdno!!!=`O<m8R1J_IR{)uq!{@)F6=A0&qgYpf+!I&Gd$XP=P45*?A|{l(8*T
zDaRb_q@@K=R0Yj<pZ!`QSO!gZ_%>+8PtWbG{AV|1BhQ@%Tbx2v at V}*-Qs3 at t1WW+m
zny-BVT8=>uKg^9;*ui|1$x&*^JM<C3a~9ujV{v>Xm=&Asjb!e+SF{eE_EXQxA`X7j
z1|8n40qQWG5l&6^c4D)@!w|xt(>ugghNb&_m#o#h;pX9$&OnE^zrWj-3D}OOJAGc>
zM2tlxmFaEct2^3H+_|Hy6 at F^lFmWhRC#dd+-C<p~#eZNezSjRLkwKgk3#p#VdxpB=
z;YZ@#XMaBU0fOdh9OtSWVK+<{6Z<CaHjgcsj==bQ4id;H-x+26_Ot$0;@6#0?L4<@
z5dL;XlOe<4T@`$(t1ZsYwdvwTAXflOsI}xkNOIQnOM&b3v5m%;Y682`GWNxp7)2_5
z9@;tmU&qJZ&cdeCh89Kfh25f3OIqh&dfZw(Q>Z;Zi-QcP10b7GnXb at Xz|P7g6i0J=
zV7smOQ%%|2K7owt3 at PPqFE$V^!yjF2l&bUg78)5o`s7LH#}wi}%u=`;U3p??T>qJ0
z8=gC<K4lJ1sWEiiH1-0x76-)m<I4?R=a83j^uvfPfT;1ufqA9ui8EWJ?BT#7IPWZq
z(OKH`Tx|&O)v$fs8Jr248G}vdn*1G?DB>RaCTRG?zPe>m&|*m at z%IS`-a>m2YyhXv
z>XNVNP`w?%aDp5`6o~lLG;n7ShA#-J2$9GbpU*wTik`<IA_t)0s?|sQ+JArG7h3B+
zLOP^TS56cbVAuht^x56vxA59I3T<Ly5TWFw_+KGAGN?;{;V|#EUXbA|uNY{k)t1cq
zgGT*Xa5;2VT<U;RT3sYGOp%lofRwaz<JPG3Mc>vGB;9&>FM!b(d1b6^+!k>)^fwo2
zTurh3)}%HYxPMIAilCcm`GPglnrK4q`FXq0JVJNdAXRJN71p67+&t~<=a29B-CY+{
z&7EI298b=2i85#B=xIZ`Qj{Vy(|O|7Y^}OQ3SRjxD_i7CSrHmS6mDwL1AJ(J$&lIk
z<#oc-_{av-J6<)+ND_3gP}Oc<cgKaPsQHt_m0gTdE54cesU{dgWdb;{22I^D==E&B
zbHZL_Qd{US4u>nT7DhcmnHY97hMSitI%QfDA+t#HbPEJt#kygmUemDk)ZFj0IBoHQ
zSm_k-zOOnOKx@&=oK59<w6y=8kp*`gc;zCKf1sz$UD_{w8Bn1k^pbyDJk1j9JZkUy
zS+&>bhn!5i<T#T4!^nG<oNJOccGB0<Wc67{7P3UqH(skj)YTtyD3$V+TjeC{4dk<%
z*RUG<xqQ>+oV<D@*&ZI^ZI at H`zP+QiR%PXq-^%h at 1lC_YkCo`;^zK~7rv}hhfVS6)
zf52UsbF`;=jrW{fI4?Y0N{Dq;)q0!Yce8#th1a;y$!b-Tn{1V6(9}~qGD0GNxX#qo
z#99ZPDCp93n^$sk#~KV|ZDPy|jNZp?3{_pkLTzvEJJ2;4WNxcyzn*6C5z4TB{-sHr
zPo;h&JwPmIGG>?Z at dj!6x8mP2XL=!dJxa9;fy?8yYv23ty40dy$MvIWK^c(>&iNcl
zWqsJwAvw-3EkiG-{?(7d82t9<aaWOm5ZE at ZVFpIuRql}pDkY+rnbmjP3dki{AK1UQ
zH(H9lZ7%A*`U%8XG8Xz{5hFe_S#z8 at L?ykp{$|$V)m}<yY_TD2WNzjCVY5D-setFu
zlu!KVsWKiP*Iy50$WF<7eUd at H51csO%7%*?9q2=42*c}Vta*RDgYXA1FJe!~(YB-v
z7;jlUg$1185sx$eY|uV%6Eh5|Hq-Sk at rW@z%@Nn#EdH}!aD%F6uXtR-(MwiLn3JXZ
z$|X8GJD at qaFPu}(GZy0HSajWo(0yOXnC>5Ri=(p2>y at 0OPu)($wWAzoP~0vC^WY+}
z%JxZRZDwe{z~6C)wU!+$?vcC-7<TAg62T9|)E34!lZ8q~FkPGDE%q0I7gKCdD>BdI
zCLi^vLA<6L9{1CnvBc4384Y~_(wpY>j2OgZ=lKbfvjOq0DKC>N<KtYigPlX;TfAXX
z67Dzc8(OX$cdo5Mi-E(iE?c~^j624v(CxfezvMO&;o~R_F3xx<?H})4SsAO8yb!X~
z5fW0G5D*%<{^d_FfAn3-S&WYn)F)Xd*kL#8cPiRXqFo{r{V_#v`=wFjOmTZ}8Mc<+
z)G9Bt%A1`m%k9n(6=`7w!>swf6J at zhm;lGbAN7#nLITZo*p_H at mU>uFxz*5*tK|&6
zYf9n=C389OL+>XdmeVJNR~EW7_usTR!xfuv7$$Caiuk|IFBn$;oPU;eiudtoo_3z8
zo at P5+PnbFQ`$v0*jo6RJR|g&SouwT}ftN!5Ssoz&Gnp3Q&)L}8xRS}j&M&WslZXj(
z38$dnoN+Z(4&y26YCiEAPDER~$ve8!A2&Y|`b8c(bSrjNM8!?Mtt at TrD3@<YS956F
zv^0nsR^xsZAE)_H`uilsdVryI0LXX$WZM|AypTWm*sE{!qO!g8)bV3cyiL}_%<G_^
zNc3_2Q at 35pz|B*2eDcd;zAtK!*`uT!=38RbMSVkr+x at p~nZ+74gb at i11vZv<2~>^k
zfDQ#tsT~?!0^y`6`Y1*a^duE1`Q#?CoxjSJ<IotExn(4{Q)i;jk9ILSHS}SR-Xz6e
z)oN|b3Tm*n-ZpyUW^YclQb(NNTF~tOs7+?2`@Mv*Nq*i%!%-hH>ItZVH-Dqjl>HW3
z0snaeQ;hK69mV=BI8~5jTD^ogA%1Un4CP!WM)>s@;I$Hj^-`~oU%`$D?&MC#dbyOk
z`kmT$_poa_<1YX;7HYNNdn-H}$4VLpF;Eld2E5<VIQRP7Ms(At`IEWLEVx!E>XwP~
zFJd4d5<Zy*?Au#&M)=czt6ca-4B!PF@?)*8{u5t#;@9!xZO~LBTebVYeZS~Y30H$;
z87zh5xpN3nr24%O;jQQYX#vptvJ!#X<RUrL4h{~ca*jLHq)2qSqo9n8Ot2Qh<OHZd
z6_pb9XC#wsyG1tZ#rdLcpjjWV0MAxnUxnPZ$b6kVU9IzFH?a`onNH0+<y2u;gHg0J
zt1SESaWmsyzL)Wt|5Ek#%iph at veK0)LOmcO_6C+Mbsx3AcJIWvJa%Vmlff$iTH|jn
zyPOv{I6gop4ZEj3%#}KBi;Gj(({@58{dj}Op at QSeOq~q$-UmCYVzoQLaB*orQe()#
z+1|=(j}0iv&)h96lN{prm;xi{N>_?E4vjS+Q&I_t;_Y>!D~+p~tOMGo|FaO2pa1<E
zi0BG<H+9=E3>mDT<HeF3s!VHkN+yNGOM+MzM0rPFb;gDfx->cWG9i(udP!CwXh)UR
zYsJ9O_hIWBASqY|w4-<yG)vF0MnD2~Ra{0LH+d`wP_h|oX0aybFgl at H8fiE-m13TO
z%`=Ppr1!4?nZ5rCHyl}1^Qw7OyhdXCsx)ijtbdiPf1j1 at O=>q0;P2W?MDd!6sMj8B
zUfT1&mr`5?V#pGcM`pCoi;hl?cfF-0Oz{+X_mP0I?8gc9Qc!*S3M_tFJmg>{;CR=P
zxSZT|vb!B%>V=|p0-QJj@;#Q7wC4AbU8jzA%30B&gUG6MNQcLd9{Z5R;_y-bdQ3w;
zXKjb{v)RTy#&L6CbSGAN6?)l&uI0T$qn>qQo1a7Uqzb1Bb{;&DR&ziux>q-rlV(ne
z at CxL5T{M*60zHL?#=7L7P$>SG6`^-Db<BkO4<5KR|J3S<##W;|$E%soA$RX4uaWyt
z at TuaRSY9!I8~T_Ab@?`BJy2!^SVy#A>u=D{O*q2L4>B1Qcfe^k(vJOVZSQsak2Nur
zY0ST%N3V#n<fvov$Ss-gyYh(aP{hWYZAoiDz7G!%=i*PFG3r{H$5;(`+1>FZ(!G&+
zduS>0Ob}3HUyj8}O35lFLSvkXn7S-DASiWBjk~ldtoMQneMzc=ac-i%j(*8N{0YTd
zZ{dNSw49+GmTNqZT{wiE;ui;>9=D>5d>=NBmX5S&rmtmy6BBdStwlJVky)h9qZ=Cp
z<EcExOY15DJ65=)Qrb{Vk125!>^$IF<v)`R(1FPD&iY$WVn$C-?aYZy3#N=s?fP at x
zAdJPr>!T)^J6~ZKp at ox%mA#r-OE9?A!xQb6jXde8M4WK51+ at hK(Kf~(T2{V)k7$e$
zrZ`}5ybRp1U=z+Ykv;sqEZt}*Fudf`leF;&qt5 at qAY!=rN(+se(_L3rD?OE=Pgk>Z
z^j27Mlr<-{s0WI2Gbbq#e=Z>RKHHW>ZK$&1=S8f_coE9iB^JrwO53=WWiouV-)iv;
zXVW;Im9%N_dpd^DQZxzMwEUO0$8n-z5-ML9wY(@xKSTum9I2XqxX{r}dj9R+7IsrB
z$fp`nI5jpcBc#VssQk7P4V4<7e`Pp&;I+8c&%D@|X6lp~HOm7Enx4Gw%s^-8zW?fb
zeTQ{wJChtfz>n{B!ol<v%?Cv<`XF`%Pn8LiTLZI--t4bk*p|iSTnruw$#$O+2^9~B
z!)@(xEo4QwZ_v-B%E~kGe>#hdwr9t%lXykS at mLMl4DS4#p;wh^*EXgY#r(N^2Kx#w
zzIR)va?C<vx;3k)=Xqi{Zw0s8;ThCf66MY9Hi55pQ|*_b%dyqWw=bK|Tgi={Ws>~b
zec{}<sA)|6WaA8a6<RjpO5WL$23=@Eh~kymsXYh+HOP6+MrU(<)wVXt1&&(uboUha
zU_a>m(C#u>!>WH8cC2zx(03=c-XdW5+VfJST4elFWpZYc^X+!rrZy$|F1^ovi~u$r
zJk7Mb3DB(WyfwNtGCmc0hBYy at 1?BO_$bHNQ)4Ood7h|PG7OFXy^mzbg5QhD_|C40a
z|6_Xd%&UqeZge{e_qh4EJh*ze1g!4- at lNoi_uuKW5bW^ImGt_V6OAA=wPdN-Ns5c3
zJfAdV`eTzm-if|=r?C5 at wF)Wr&m4rlrLLs}*`yISX!{Zh6`&fFSQ5FJo_?*-y5WZX
zwYf0PpwViJj&`z)AD^5OkjlzmQW?IETe|E!L{*aH4d0dKQ+E^)<yHZtP${lc1xu^%
z&gH!GqF+wFG`PQk(WZ_AU;kcpo?+)uS^UpLGI9SzAx<+?tz+t!m5pF!RoT+b{+qYs
zqKk*baL1qW9`!=*kARx5hDw0a%+Xt3yX%}ISFrhNur<)b>N at U;+~)Jz!k>e-OuhP=
z9uFI%&@^CruVk<Hr&nr^_5c+ar=DHo7SooQnHe$$5yX)Oc%KL}ykMOGie$$pyeCeT
zeqvuy0gE^geE at EG*b8}j8lc*MJC^K}%p`+2$y0luwcYm2Nv-3YEK8ZpLPkR+ZDd8H
zYNSAr)_~*4JZlC(!p!F5PS3`)<+zp-^eaYG7<^}-<<n1V+T6a9OilxGX!7D at Ta9a!
zWt$>$wgQJ)ypWUh0ulnwq4)(cQ=u}p+opsIh&{=W1aA;M<A_|D+S)EZ4*QA~B^E()
zT=ZB?V)ux8RYTypdkQKNl8|#q{l>CgzRKU?y=Y;fFpcth^dC}4=*x1uP!H~x6OW8p
zBkmM2s2^9zbd4i3{m2f2+nH`{>k*YnKa<aEDn5ft(((#~t>Z?a0*YLP)}X?Tp2fO4
z8;*o=O`QkD=F1 at 0x;xH)bQ{w-TP0~lXjmWUGVsE+Tn(zV&+S~%rjBu~@m$iS=cfnm
zso|*H{g4=4tnni7wc?L%+71%1K5vJqL`>|nT0&5P(NDQ5hh5YnEWGL^%E^^y>aMbq
zF1Pv}xc&KaQ2pORAl at n+-6GxM0ddRKa(=xw%geQu8yX!N4)gf^-RmjKJfzBQB`>Kg
zS;o%3O+6q5JUT2na)@&nQFJ?XjtPG%x5|6cI}wbtwUIP26?*zAp<zkF-^U02gypFf
z<38msOt6pUS{u>#OIym9;eUq-8U;9uXD*wYr}s(mWcI-R9dKon7HcEp*-6)&{Aj at p
zXN10O?RXlqFp}*@&ru{R9OX9hb(?|jha#5^+Gqi8!{z2Sq>6~~<RT!NR<b_nK2IKX
z9&;#(Ry1_Fu~f2*>BzjB)9JC^RmJT{O9%3IF~*S^C0i?$Lpf$hjT)_F6R#abXGibI
zrVvr@%kmMulO^&;p+i-zhWdBD4%MOVkF+dkv7IpJF1N?N3ww*w1fh5eb$q|FSD&j#
zVwH`nQ#k`ks^Il6`f<|JC929q{*U{p8?O0<eTujT1HGu-dCbU#B7af at Et}f~W;$T_
z)o1 at P<3$Y2?}!LR*w0w1my#Wl;TB;wg%A2Pu*lyjeRVq9fo|gxb43Bt14A^~0LF%<
zb@=Z}sa}1;`t+<B=HEAc6Xr`YO<2uL$r>(zvTBg4S*1zTOwabWF>ZZOqV(2yH6-J|
zk|(2}<F}bDpDmdb+(9m9 at PyL#8 at rXli8Aw<D9DN(Vxg(*lriy#(U at SqOKLM!Faxl1
zt;PQS|7nvmW-LO2)CD2kB_hvj+yxn#c!U2H?P=Dq$pFi1X=12!_u=~&kRki4OG_JV
zTYi%vV-l4zE$lij&tY4RPxb#js?9rNBeiAX&T@>JGt~=9rxrI&wsJt&#T9y0986p8
zHe2>=sh``ad#7T(9S&7YIP17=JNsi*n8?CqTf(;ZJ}(EQOIszMtaL?~5}!{-rHnb!
zWetv_?;ql4s@;`BD0ld!5Nxw2EmQ2S0c6Oa4jPVM>^Xxd at D%Y{T5F>OZi3>;<Gktk
zfbaq8T$_ov<QY_9ET$()zfAqMBL;o9q8W at E`Lf>(ve(pRPl|BI7*OuzOnSKvy56%>
z?Qke(k~?TDuz43qJUba$DO)d{<&(%akk1hZ`f!(~R;<JZ+y)F=v;6=a2`s!9xbM&L
zsqJb!s?hPK;t!B313i&?*m;~3Yevy4AjIQbTKsAt(KOD at ArSWGMFi!CYboQ^<HFt_
zD-z3{=rRO7Sg{B9btk2_jp*4 at Kg}tT at Z<|wLAwrB7ii~j(ifM^+2}7o5WZO at Q_Wu4
z@$C9;^DLKO;Nynu-^xx|%GW0ro6Y$Ep_b~O`TfbQjJ332yW33_AL7j5;zT1ldy;$!
z*8PUBdQV3E?bNTkw(jLUUDt8p3eIY&+bEtCNj?T}k3|zMd8iKvD%~JjZVBw{d?&-Z
z%y0bTwKg81|FnQ3${doFCpN`RZr^0e)N-f<KCP2$L55~oNRL<R5|Wv*6<o3nGd@#}
ztEzDP(QFa3sYGrnTPX!*{RJS at 2?G7e9{lBeuIV~Tgegy@$?{_={&_s)nV#6PjMq%o
ziLW?%88mw590+-18M}kWD+y${Bl(*Tc+}HX^<KO8Eoc~~wrmt(D9(2GgQ~b0ohVi(
z&7mLiZz$R at Rky||Cfe9-YJ!05+W+m7ttk@*fk=;4iIQy%OE9l7y{8 at rlHn0-U6pjd
z^+nf|<nB)RIP4m7l}%PQI-##OjPIwmbr7i_tQq_JHFa#?%k$6N8-iopZw`o%@jOpW
zu_#x;CIBsBt?cVj)e&Y#Cs>4jig)6y^<#SS!94&H=a#o{z{nUu4B+giyt(?K%g*+L
zdy!FjLRz1wX5H5ay*eE+)xV;!UD0^dw(pU>;WIJPvM3i$T5=Y$M=gJ}cCg=M>*@jH
zzVvlJL;EZZqGJx4uM*UZENgmQx)l&z2alAgF<)AjvCA)Hcp1~q`KoxVy^8{D(j4VF
z^;yo|lZ5mSzpW4REG-YnS=jGDdNLS(%sCKZB2{rTN?H3WpXmllF!<u;2WBaWs#LZ)
zZ1n7&)&aHwyDNl1e2ke=E(cAz?81?D4>#I=wo;J~dP9Yuq2ybS<u5I3;G3XW&u2`_
z;=U**!!OZh(C}dLQN2MnyD?JBboq~(SkL}v{_KzyKvE1pRT0PP|DvHeb+iYDEaHip
zd9EHo0WO*`99^+A9!S<DlIUE0XXNcq&3gc!xA_SiDF>H!FNpUURteodB_~kzR8Sgg
z>QbyqOc8OTV-?C_zR8KY1DCM^>w|V;s$XEtW5Ce01c3Jq%+^_3C)s$jR^YwBFoh9m
zt2MBBLHfiZ;fwH`dZdL$f$7g}6GWbXDoZ;z&REWb#FAN}+m^C%-|1R)@GDL|8^&Pz
zIRN-eQL5d}7GK>hU!Y`UvDI?I#Ji$0w{F^gb=NsahG^j4kvMupj1-HBqdUJ}aCCB$
z_0kkwI1&r^CuZqT-RxI15Oi^6;qzAx#)SvNvD6Lsm`AsFK6lrEJkmr;Gqg4<pT5)^
zHJF_J;G3)`#Hl at Q{tz^wTdkL0)LjF&e&WG}nyE795h&SBTpwwHjwGD}XeOw-5lgwx
zC+NiH_($7;pH-(I_env0qfWXc9i!S&y#(~hD0N3%emFEF|1a_GvIF at tYQk4HE{6IU
zn#{;-hh#ZxOs=b|VF>MEU}{%b2N?IVQ>9)cQ;EARVkZXww at KEDVUrp>xGxa<P{KfH
z)nSCFW%Gq0*^BQ*{k$%O6aOARfg*zpzy_%{mRLF1w4Z+wL{to1 at X|kP-pshOx8FT|
z->S=)@nXg=^CSWH`jZeZPuTXb%$ItbLc{u{Dp1A2C&?0CutEG`9K-ijblCGbb#J$b
ze<dvD|Egx!@dROAzp93E2fI&(kHp%94m4c@{=t)?!#ZW=)F2%Ic at oROKhV9W%gi;W
zl9qPV?+;DL;hPZ4Ka^m+HXG=}n^C)|<X+$A=>6m#t$qVt^v$7H*gLvEvx-Nq#*ur;
z(CsDi8m#BCfA^jhWQk%h(0*va5}M<_M`5k}HCiLjeOqMW!xh9jV489*vD=*IOv!N_
zx~H*|6{>H;dry##`yTem^ubYS_?sn%PsKMr5W+7AxXCRb>jFMrnWAu_AQ_T+1201V
z9#hsz<dZ@`l3-?6+^(2 at vL}O{l?}k-mu5e5eb?)^?$F$?t$z{z4qU)^Z6~GhN7TzN
zkm-rEaPf$x36wN2{Qx)*CTZr&td at O4y0%T~toD|G*j}RRoh>G}5y27e<V at 5^F1Qb;
z%{OW<#;vU0VZ#5-WzfYh08O)_xSQ+{ar!6t{1E4?w1aVYYvX+TTmfDEX;IpQKI=vq
zN!rib8T+~x^$6|QpncmPW$I&PJSF3kD%voIO#`eTI4e%SFd?El%ZS`Vx^yEvAonmK
z{!LsA89D55uomC=al7l~v&@2a{08F2hu at Ayrt}`@XI;oU?Y&uGr_5OTa_CAmzq36X
zcGtveTZEk at V>%Zn47{sjc(=}dPTp7rPO1b=dSPCdOn;^rwav+|gl!X*<0&^zbOc}X
zc=FL at zEB~}>1<k9a+NV)f3!DD at yPW6V4^TTdss{l7<bhN at D~oJ0o??*YXLcoYmS<(
z(5BkatTFbg(}o+&TcRMaUgNEys`j)TAV6j&N6N2(=P|VODgkW720$CT=|c@$*TpyE
zUdkUV$PG{jQ<4p>-eqsB9dt_83eI|Q?=eH~AbT~BmG|}Sw27A5k#q*5PmYEMz!JNs
zx13H70t>TOZFJlMHZpa+Ciz41V2Z=nEi%MjSU3kSQ0Z{MNSd9STSXhVOggfXcL9Q%
zZEv at zXZ|5%pSaZgT)C;}O{0gW!@m?MyxmN=x10Ses?x_Nj(Q54 at w*M6QKtdf{THOY
zm at h#x^X$pbgwWVJ(&PlNkvi2)_o0s|)?EQPcbb$~@#AX`=W%TkQc`o{v|=FZ@}$%_
z*P|ZxY8b8Qj+;1Sr07L%PLAu-C~H}`X0*F+6miOEL{6zu62=uy<lI}T-6k$LM9l`n
zQbD}_<NKn~vz9jUb(YUxGvs?&DUmq+Bz#Vt<Iy>3k-RN(KpYicd~3rS%{Xc=Qc4>D
z5b}BqU-eXk)xBHQs#CQpDUGitGus<2;+h+l+(brA9=Ny!EJs8{z+p2lwQ0}ZCTV_p
zo{uRVakq(9k@(Wqq0N&;c)t_VAbg%dkIiY1?Fy_Se`$B0k2XMVYo&_c?}(G8Vg$33
z7bdi{WVW?9`+Qz;Vzjp_n>B&De!TPTvI)q at V$wZj4#?S at D%fvyiDqfi9P;$qKA`#p
zL=#=0r+cz=f`47kUcer5GCHp<0dc0*_f1h+RBm1?LY at Du5|Ir2)x+ZM@&rt37dl#I
zN1*5a>=PW^?vH_uwl{mdp>NuA6ihsF%;<d}F;;rV+E1&TUzo|!rpvU^&Gq&dk<7Ao
zE)9`61uVWuPN||5yZ`(5+ro$YJ0}7N=n4Do-?Xtud+wmP<3;sr+Hr4wa|Yg?=(YWU
z1nsGfs=uGu?Nu{7@*@}K?CTO-EeCF?y_?=y&RLG(_{y6l7^eq3yk%ELF|!UMPE)%p
z6EAj8Zm%Q<xQl2bQWjz`55+^b4atAxustxSkZ({d3Gy5>2$4da&914j>YZ9CsB_B+
z=ywR_sN`AQ(1_Mat~?btVFQA<`g)%3H28nM`p+b7Is&p|q7#%@In2<SrE}8hV}?S`
zlZtp&I$7rbSW5$QRt{UrRm|P|b;nyGGo~NCjNti<byeQerMc_1ol!7aGjn&gTtr7*
z48<?ty|naJ8xLJDqZGaQz+OQ^B0pJ at Q*0<&r$ePQyG~w`tl@^%Z0_`w-UsZ`uzfDd
zZ at hhE@V~Lxp#4q?MT_LjRKR{g#Eekjc;L{WbKX3YENaAlk-Bak?_lt`;=SfmvZAcJ
z>t$l)Cl|gf_8$}M4ZhksIK&NpIMm65R;LWVg?e%BY7n-OQ%kQBD0ks&G#x3g4sPc5
z_3j6O>0s^+jx{_wtKh$nG5rL3$@HCjTtSF)Zn*|#yB{v}TdVdzBjmF=4Xk9v1XdXH
zT2I}c2)b-}<^6U at w=EpeHUg1u?TfoGT_hzrb^}?mvmWq}M*H24CXtLp3aGz_k;2oU
z at mBj&f3`?)6i&jA{L#Xi%lyR4>EN0^uzyY85?&86+B5yqaFA1a2k3BP!S`?$?(2;q
z>ggI>AUB4qI+YVW$QG^@8{PFeJ)d8zU&b%#sQ^dbJ`&_IYuDl8|2kmu$M*#BQ=5EU
zPIcng{ki at GL)87&rf#CS*yABMPRzJA+eSnkl^lW~sO_apim9jTcD0C0l=!|+^KIn4
zBEX{C^U at qWl^ZtyyeQ}bpm5VTqU3Ysi!w_k4*t9Ffd@)U)pS~!6#I<%oH=o=FPZ;*
zUC!v<>ZJ~HQe;lWyQf0p=gBZ7iSy>`RLY@`lHVm6MRRWK!aw1&Pv-gPZgoV`QYuQ8
z*7*@`9>f~r+4<cGNy%Xg65{aBh=eo)E3$948-0C!<Srvlx*1k=k6QfRlkmPEC)J}c
zy~09($KEE}%l&C}g*3B5Ui!!ITi(#1_F2x&P;AYW8QbFe=5kCH^D at NEr}Z#y5*7CR
zyi at f1O-0es>*@o~Zy25KYS3T<6n+#zTF(34;$Dd|e}Z82IT>F!UR8ITT^p7W#&A(t
zx^8T|gF^*BdC0}BuK&VW1sVP5f|81F>)7`crx|?qOx{^sd&2{+6Xh{BIuz(GbBWWb
zJLa}HaOWGErJJa0gy$QC3+vc{!F=RUPbQXD&Nn)!;;Asj6Qx;Cu6 at ebgYn*82#ECA
zUiw}62W)KaVr{#)dzH>3W}miEK8y7?OpA9HML%!hz#cyj at uw!fpvZ|I3*lARj-)n&
z?%Z=x-HZrCY8wJ${=ey%$AaR(`rWV$3orbQv*5w~G2?E<D%IlQObAiVzDxb*5Woh~
zU!38q-S-x*0#-+1Qd{J8NA)$rxf)irG9-~^8pivY`#N6Z=F*^yA0aWZT{?MQk7`B2
z7x44 at LkdaHSHnpt>AV?oEIS at I+Tgw7&L-XS90IF(r^Rn9digEh>(ywqL>sKYq5RUk
zpw;=ZBjTJIJofH;lArNa2!nwV<+ss9cp-`+Aymue2X<(+SAffw)OI^#jK5p<lI*o_
zbD5T!ec#y at s?q76MoWqpKspL!-N=xb3C8`h%6rBiwr2+O_iw%offbV<*A;z*S!6$!
z<0J00d_GEh(XP0Ia$0^_5%`=-{S at Hdz}6zyv-hcia7R<~6;NPO#5U(;BG%?^dJeKh
z7E45HqRYTLaF%4d^`}vWW|Wpb)1IURi4lLX6KU2f#9Xy>gVf+dijX&`TE*7n5Z(;I
zd!J-YyGxh60c``n4F$r0ywkoAL<Kb#R71cU7VY^0w8(1=&WhGm)6MV at +CTnH;O>+N
z41h=iXIHhY)kl#sFGy{$D%ae#$dEvYpEmD5!@IMH^HW>R`Adk+<x)n)5UiszXTG!;
z?BP*c9I=~CmAt05vB-A8Q|JnRZ~TxLjCcT6n=8rRQ9(vRQ-pkwpnvrVkl)HL3Y1Hx
z?-OC^GG|}jQ<%~;>m1nNBQ=S^P_Hb(KF3V#Aux>Kf#U=ZOhprS>ME4I`bDr;-jaK)
zMr`O3>0uZciXxw+eo_c+q?cqxt5DlsFa3mdd=6a#qRUGC)<+n-(G1Jev at PEDbC-@W
ziKCnlpI%{`*{)3v at bz1m67rg*RYP%$9FUG<`lDkq{ocRtdq0V`IfH1A`I at gN&x+LP
z?;39Fv%WeIEc{GfR?!pt0_~o=u<64NrJrm!@uMj8Wc2)J7%PZzN~0yKm)V8HdrpL5
zpDxyU+HLMXp^mfLRI3J3bP3DP=<VsAJWoHHa(A}c?^kSA9g5asX at eKZXH%j5ABwp+
zz44UBo0w)TtdA_c6tD4&-v{ftT1uWUT??qz^V{I`0u07gOTn&74*&PA%-I|t at p-*-
zKg;lZ56xLwM52C#u6UT&A!qOOj#{x~*e7>|lS7Pm+`365FnwCSM$mGP*kY$?gerf(
zm(6!w_s~sb40_!bHHNeKZeQpW%hkTU2t3?rQx$37#oQ`dFyY6$qv-Z^(=3HO8}eQ&
zOrT;eY{k at F?zMZEYf#6=tyM-EvkU#<_Td9*{R^>iNL8TLJW at 83rf-f5Vz%*V(Y>v{
zmYbXF2AzP2JfZlSX{hR>L@#a{=V at MMF*iP_NDVKZdLXy3?f0kV{Nh5U^SRU~Ag)EE
z>dwQU$&*OIf`)H)`qIRzVxzvodTS0w?U}m15OizBbX<ECb}+mOVL}+tyD3g)!TiJ+
zG;M86g at L+Os$dpO=Dr0?YbuL>zOPOxI?1NQ??u`eSk at 6df{}A at vmW9V(aX{}{zJKl
z*wSz{q=NcZ`MfvOFuF2_CtE``CKVf<clPF?S64a3X*)8Dy%wP`iRK|`l}!VRcdP#(
z_02IyTrkD|BIN^~RKGvjHy7Z2$zKYqv{$iy2Z_C7D)ee7ozo@%5x$@z{P;)}lV|Xr
zX)D7qr@(1sD@=6g+BYsB{`L|5lK1ep=ZWom65J?u<){{FCSK0nqIT1TBuR#kLZd%p
z)4_u6S(xR3Gy-E5M)#YzA+ at ina0yv$pK|hi&R87e%(48>DjX{}REfK8u$MZd%**3=
z^`T5wlcd?-M}KYJ9JGy>$;Z7p;}H9*M`}aMx*1MngosFf1vW<7hGt~B-J8z_8#n&i
z(`I;u+h0j0<>`K9getQl6HdeO<;+^?=N4NxxCMa7J>^8HYK~kJOA8(?6y87FSD{+w
zEChKIqWU2HPtD?DL2X2t!e7vX?2BIEU&xP2d3Deqce3q at vDRBhE|Iu{X5YP8`w8u*
zSWIc+Hclf*=cr$<<Uruln1uTo5_aH(0>Aat-;)(pZ&fC`-Xv=p3I({Xq0QD&7|7!l
zi~#DYyW!#$kUr9aOMe>SS|a^#{{OT9#?dEY%Z|DFNe8F4FdX(WK!G0cVx$%SuU!Lg
z(7Ge?gUPgRm~fl;k8)c2yV~;#qurZ}Q-YNT(HBKpPyS9WBE8ZkYliv1G)<ldCrHK)
z{|rkrKR6lzl3P14sP7-LV{cRYNT%a&Vf}m#i0+)Vg(~IYukdsiNhYJ%Kj%{4H#TGP
ziX52Mp!ERsT;mY{Vm`Zfjj$*I3Oo6Oi(5c8iP9Kc?J7Q5hTfO%^0A$`HEiy6vVvH>
z$5FC5-{z*}{Adgt-pVh8ZTQBnZF;b=tD$Skt&emkVdoQrhiU~KO|HkV7MJ+2wrnBz
zu2q0tz=y-ge|$M=2|LPn2xT77QGPb^4Tm2u*<R<#vM3w0w*rUp^tH@&S#@s-ql{a%
zdEdQXKsiPof*4gMol-g=pDl|`4^A$#^rH3od8^UW#Pid}xA7#i3<Xb~@1-LgxibLm
z^6WLRYduJShsV9H at e`cOuBC-12dp{Ut+`KBI at Ua-i45+L&mzVIfG)wY0;6vJ{pOiM
z2g)55Db^J}XO>;jg!<z8U02#%n%<4}DptUr2A3;jpD<S?Fl5AOj0_Khi0_d}V9x~E
zxs{abM>!LLmrxnH!@N&DE&}Frqo#t{zP<SB$Y2YhpQPtamkT`|`6scTKuA6HZ$4c4
zbb&~VmtJT2N`mS$#80Bk_K)PLF$uly at 5<A01EQ6QarDpg2z at JgQ41yUXs<sfGZst2
zhndV4CsPFL?IWqpYlECqTzHO}1&RBG#UhIztnb2mG at UZ*Lfb7w-T|D9PSAcfBQ%iO
zl8d}%$x3xMH)yte-yJkW!zQ*#yr=<`&6>J?wB%YVg at -9ov(tJu58WD6_a at _69?u4J
zJ&+<8?$qfJIfJ+V)rz>;71a at v@ulYmmVrh$2BYJKNH&!%8)n1#q at 8@L0T-~kqrGu#
zg<q;UtYf{a!1%oP`UVxJ`C6nfq`M{E#rHhOkk$SZCvDx5Df<d%u|oD=WA*B at B9?C^
zsm}olmGT$o$k>H~XUr5^=9pt01D)wl?n3sUey8;H?j8lF%ylKy)d?GOO1V at S@k3nX
zlyEEV5o|XbsFbmL8~{-t+0cZyKk8GJcHXTB?A{AXd|gwU6OpVry6fQuj4Zi1GIQTW
z{)Ynml9YTgyOYj<?gd(Rzh8axWVeLI*U-f`b9T4DPdf)lKU~|G6ux(}jNYS~vCE&~
zGR<$`W~aI5_`u$JN%xz{TJ&NG3)HuWVe+xxCQ&q+lI_OgMANGdT|>)9Saw~J$0p2B
z%YcOXHr2eAVB#5rGF?Xs-Mmsq5)UIwDSNrd3m3;nfL)&9+lmeozw}Ib9)rrrrhqS^
zGhZTk7Gd%(Bgnic4O)~>^!&{$F4dtv9|%l<m#C?gZga`kT*I^I8-FWzLU!4T`2QFR
zO}x`~pyYA}DiU$&z7tCE((jn0hlZO3^qa%LR|qx(vFdqAq!mwJEE_35+`OS~=J^6X
z*qqjP;w2Y^(HzvQpny{7pD0Z{8gcp*JRgUlG76Ylqh#)Vx`uD%{5M at Y@Ts$}!pEDc
zGCbE<;CtgfCdvS3yaHKQ at _C$=Q at k#gS;~vcW{gv)mMUju*|tb4cHpRi<hXKCh|a>9
z$bdxC!!Z@<hgMI#HoKF#v>PNhE8?=AoR>Km-Y`XxOOngD75uj<#FGk$5q?3g<bxUb
z`g`i3E4Gm1Gl6K7=6%GLcNMm+3G)Iu$+Vd1JmJEkGEhOMp?#)zLjjigG at EA0*hlD=
zlur%w*{dKy`I3*yyW&IfUz5kvJsGG4dwX=!*n`Z1lA@;f7v##=M{DP9M|UXD9)zIM
z=fAlPu|R#sH?AE4-WYsd!$R&);3xIcGafkgN_%)6iK;3Kf4XY9x$sR^+UWgx*{Nad
zx4%ykr!2$;cWZ6(Q3#6shQ)q^BvwZudlI?#F`7ag#(7K;Okym(fP255r)-?u=*-}_
z3_9Y{hm<QD`Vy;@h|=V^d(K$4wP<P6WzP7TXDf?|LQH_a{*gM1y<{dN<I-!<U)2UY
z6il;H&A!)<Cd=H#s0l54!K>Jk8`4o9<Q;4#>?dqpKA$%ltOkH6TYz*OB2J^8w6o4<
z1YJ8A{92`P|B0LDX+S_g%i`M~ar_mTM-`gmafL2gBj%0iS6QWZs8jAs{po9UX?74n
zLavTDx(}r?vA2Gjdx``PlP+H}RI5dXNe3n`-X1RRg&YhB|9|{!$E at LM61n}3?ZN=2
zNUm{)GX63b8y8bLY(TX_ICv_PLzbhr%3FT!#41^8FH7gclPqxvJWe&Q3dg<a82XsJ
z!eU2~s{rr~L>Q;F>q}RbQ1rAim#)w#CgP+(8z=OlP1oQh>-VaUaAtyjT;1oAFHy?Z
zTd~i@=qoEMZ^J;7_0k`Pi|Aud^HRQ{r^y*lUF`pTzLXeQ$)ok0EBSYfZDtODNOrGX
z%G>A2tIIt=@CMP4y at t8?RwyT(wNx_2gzbR;UAO%si^mTBRl+u at mdZw;>}=YiUl#Q4
zEdke_a@{j}xA8J}U4{R+g6DZAaDg`dt*382xu|<KQBZwA2)+9l7rLl9ToD$}g at Uz7
z-Xt>tYm2w<$WhuNo63IF?66mkXnKLg2`$u>f7^pYn5d<e7`CvTYK^Vl>=&Sc_i6KU
zk8i#jQq&ZeBE3aC#jHMnb!HGVhs|37{@xfKt~`M9c49C35q0&&z_gpE6N0kfzLXTF
z_V;ASLIImhVABa-w)pt1s;a8#FDr`~{{K-kPUczb-frq4Nx|mq%M#NvvWTTUv~H^g
zC&7Q4Nh(6}J((S44w<XfwUHqyzkQcsnr$6UPmEvrPfkzQ0RD?@jlKIf5jer38BK4s
z(0%0i9j at 3>n4o|_uJf5OyN$i95JI`+0Piy*Uv8KCrNMY~3Vp>e08rrclUrNsk8Puh
zhSML5Ti%rdk7cHO*;m<VmCsgnqq?Gd1UDk5u>PPrhrd9EMaFbH%<4siClzAheOEhO
zwhMSOG3i-UlB}l-m__%zhQ$SknUz8F6ccx=yZ+>FeHM3ATHp9o-+oPCHT3?ggOTkl
zf7&Of81L{-&&g!WifTbd0H|*JyQ5J;U9Fiou9h)YcFfJ5Lp%A!cenrEu_+|-0+g3<
z3Sv>yyx83h7iK&IBr6OQX!cr7Y3jJNP&>YH?3P&~0#~J37ilh at S#g^`Wh0v!&R5KE
z&7QlwvSB(VF6aI at w?5yMhI&aTjIh=BxS$({ElaE|nBZ)Tslt)y+-SN2kuP;F(Hwsu
zJ$_?tL~Q{6;Q0K_|HlN(bHAVx26v+#W~8H^K}<`-f4cmg4|dPX?EHJp2eOhL>~6Va
z{w8PT>PFS at n~|vPor=sv*X!e0ea!Y^kz?uIlUOYd5wf2sC57J(JJr%&4zQ^DJ65to
zS2V1pd{^0iM)kcym;@POUvG{rvVBDUV&E<GYI6EyQ;Phej96$@UE2u9>IP{aRlyPy
zA7KwLPn at XRzQ(Vn_q;T_kJc#BXU?P~$8;=}1h+0dAn^VM{x9B45>Ml?2CgBNa at Urz
zJ>*~t+Q^Jy8Lto>?Z7xv_ZuVg=Z*d2tR_&$HfLeUiN9Cp?horJcAzA7{f+QY&&SZ8
zj<OSHCi!`WU+j%j|JBoK6eb^isCr;$({_p at 3HCKgT@?M&V8fN+?%~8BgrM<!zpe_Z
z9nfc5)&lak3Bo3EM=mLn5(Oyl9nNB6-F-cjIEqh3OxRG&<vAJwwtG at dYRSx6&)p<{
z3UNKeeAn!uZtKXqufr?scIbPuAO;9*FpFl}hrGS*KvI!p2p;!f3 at 8P;oX7^u`IBYV
zCFse(XDJ3(pM^OD-atN84st+JmAkH_ at _>ky;Nc79)2Ck=`d+(+TxzgXo63tP2Vcoy
zB{tmW?0V^Cwq^WsR;;_uwxS#+RaE5bzUo$|UMQb6*@z@>NmJ1WkU`^6gaH(;`S*8o
zZtL&EhdmDDJWqJJ(82KwF at sl%PLu}dM|xYX`^7i}LO`!c_C?3)BD7r!4qwZg-7_<)
zYj0h)U`V&Vh;nu~k2IP8ls41$tOVQbEqpz&Y9uys4tR&W1W_{Tca!iB2rN~OB#%_*
z4<0mrySwaiyE*aR);)vMAf@;)IRv?Op3FjBdPBi@*R+C6<@+!%5(ld0pB~B1g`?{>
zhK2R_fJQmBL>)gH!Fw}Ph2iGQMP47*A(f2O-oAgzI?8SXy<F#mTaqP~i+vR%%^@9#
zh>@6M^)%nPn>>A|aJcv{Xa2&uQE2oE5ZPw;1LQ&*2{aLIW(}$#M6Ls=(xf&G#nJX(
zI&j&$nN%CaHkaLhe0`cS8L at y3;Xg8FPnVuudM=oE=PqeI#;=ZZI-pf4?A&S7I0NwX
z?!1y at E1~flM|m$D$L8ITfOWspL}ckF4fVv}1k<VWjt_YrE#!sy?ZrtKPW`=<pHlG>
z0`d}r%V2qz9du8csn67~<)O9FpJ{wK!)$y-;~VlaVv~57cXX*fv~*Bj0oo;^0Mz~M
ztE92EIlCl-mkT2Ea{cVjz>A`KPUeo*I>loSko?<(n7XnCr`3&~=2Hgj-i~$=eZE%!
zf#UWYPNipav5oJ#`)(d$@VXESUAVMn_Ll0zgBrHPu6M=r{ji at mrxFK$<$~TsFJ!$-
z)f#%PQ5jy~DsrR~SihXST4=c#8zw3)av+(M at iRlGIZSYAiF0OcshcF{FIakmYep!y
z=<K0uz~03y`8`){KV)X at sJdBh(MV+(uC6ZL0d?+d5W`TROzx{ct#6$cPT#6|t0=P`
z$A{R}J?im)Cbc=NY- at jiH+ybl3~M~@zRQbmaH~h>GDYOhd8fet;`R;R#|zLdVc at v`
zA^R9f+PT&NKE#h2>twCRgwQ+8 at +SY_)XjDVy9LkvhRaoH2H|g#Ig!dGURo>=1cRYV
z03^U*Gy5(lH4F*<fY}}6Ky*F!vMK)9BhtQxw6S5g`Lxk2zJU0ulDl$s86uxwFa5sr
zSb_35NP4HOQjn9w4&+3OMabVcPhE>QbZ3*~e!mlPHdn9r<l}^|W}uy1RfCyA{%!QI
z^Im3YpV0x-yiAi(cF!q;DOY3^YCc#i^5#ZsIAphQGwa#sn&Ql{P|LK at Yq6ekWUZcL
zq?vl9WAA!58`&bMTw9`>J{7V-^~5Ra<&;??@`apx9^@Cea;U2pDz7W&+Ak6VIle<b
zJM<_BEs?^9Uc{LJC3$)DMVAk8)Nfx+LlXDXs*5td_({>`FJSThTLz;t>L_U=?x=}e
z6Vv`hS*5h-KU^wak}XrO&;wN+3vg?xO{Ed=v!(6rZNsjifUUQky|*gIOF6PxcIt_S
zd^2qxddW*pedaBt at f_o<py^4N#{YmAGC>mXv6oNH)o;TRFpOpna#Qy%?e+?1`!~V8
z?y!||AG#&Sd- at ymple6>MQ<S(^ihRR6|EY9iX|qd?%ofXmNJ2Qy8ccd>?TsS&;@$-
z?bq_}S++DVmqlv3n6l%o314_$Z%g!6Y&ARow!z0A8r%&%>=T$>-0j%H3~YET-n*_@
z8!YcLTnw7LY2ojFM9i`kO9O1;{ghwRR+A-sQM7SU^BZvn!;q><PHcBDX7RT%yQ8_P
z0jx?`FG{_${Cy|D8nhZ#AN(zA85t2+Baz^i^iMqJxc`R4`5&CVpnG at q79CF+EfVhG
z`1vkb`kw}rE3KlCc}k_$HyNQ;M?c+>EVEFn5Q`tif2v_)cfUCS0WT#saJc7!Y3UEu
zC4Olhp at mKE=Rh)>b9_#f<uH8vx<j$s*{Kva3bQNnpU`~MLaD5F>)oZp-nIaok at f1{
z^6-`ErN!s7k1LyP6$YEW#A`<6;gV>y|J1T7kL{nen<V1wAkt_9a+y~1j+T~LmMj0e
zGjIsZ=!Ms%lWP_+7qd576%X18G|Kd<bd+lRcHMr%!A4>3rZMK=zO#F}j9r&{PNN34
z+$V$BV?Fo#A}KESXC2+05BOoGtyq~U;;Rra9-@~O98&EU;uI;p=}WR0M#c+emMB)(
zLm}!<V90L<uD4H>V|bepEDIWw4<0<Ix>SPd%uR(3iUc=2NsOB?<BQ~#__H-uNZnw9
zhn(9zi)OY;&WRg}x&4KVIqQX82a?d{|3D`3%<kXkjkYGE`8}^jyO>nT+9JZh*v at 1@
zN6koVOLX(=A3s`Oqm at w#+f{w{+4my!C3DslAY+5}=Y>91jwCo-12y6xq425k(p0nW
zRW10-{nf^HNBV3_GwQg>T3m!OWg?YnO*P8spIc#MyD012ntTuI^puTm*P4W3RFbcF
z_XSz9A)FZomua|HBJ-;C<+fh55Wg(tGz`RgwHia1HN4|425rIlTzL%QmCH at b5m@Uf
z at weg7=Z^SQz~9VL-~9UI;9#-vCddyUh-sR7?2{WR<17>Yzj$)FxES*eD7tv&A*nQD
z-=GeTQYp~_t#~b6A}jnoQ852JwzntQB4hZ)0|`Pw#fKnA+gL{@y_)4r=u3VV&hFU{
zW~U`pzB3q!Y25+I()wJG4x(IhWCKuhvY3IV<oK0cvU`U23C#OzYM|DM7!sGs2LyVS
zVG(nBM2~XT{AEyA{nqKh($d$PtLZ at Jh33CUr2HM#{&pxGmI;J=mJJ7}J`tnpmb~m`
zuF9$hds3)q=FFD45&qmL&OJ2NxyN58zaAz0!&W!qVR&hDufWJAlm8C(arpO&Fp#IG
zp+j{Fr#_2{Wqat2Pg+hUxPb0cC~FJgrv8-&;Mn#K8w)Pcgg*WkBDXa`IqgWNr-rD%
z#{N1FEw7k4f$i`YhWMSZ=LZm&9fGEnj{v?-7CJ=bpMt`rL4xMK-He1YE&{!IIsB6B
z;QM3y$oq>eKF)|g+iN4tkJVb?LADk464iIE&PvSG<}}RzD)NaLQ&lll7iVqm{$(-6
z$bD0^69i~f!4VV`=l%bqhEv<_C=R at Etj+;nhYIL87JX$YbHs84>rz;=kcj*sf|3)H
z{pnD0UL}7nhPlOht>3l(0~|pMZT?<ed|R>NqsfM)%2*j;PG0Ielm6EoeRg&l51f84
zFu9KYIo_TCoG!-`M~mliJ1(xDh01MK;gCw%ug?idda|~U!~z>)RBdn1Z89{#m9HB<
zoHP{kT|HK9rDu#uIE$lSiX>J6!yKU2_SYM?3T1y7+_A*|x><EZ5~T6ggK$OP at O8o4
z9luy6%G;Hk4 at P#wlMNme=J$^~(jt*z1tpvc2k9|0<Ug!m>q8nWUOy+j3#3xz<;l(n
z+Wxx7J5&)mX44*SHfp$ynkhxE?urzeyt8u{=wE>89P!b%jFJ^im;e$?9j^`*d6<p3
zcr7Ee at c61<?OS(pkDUlnNxDI2i>KHb(vGEZ6i`Smzv|sHYJ&7HjZy^q3;FXCV5b{i
zI<lhNakF6NEnAKJj*EJ8Zx`6VD)t&=20Z($07}06r825(Y-~*O{sQv<Ame6WRoVo3
zXBo%dsoN7;LN(4kj(O;duNopwIh~3lOjgD;EOmi?97Ljtb8CY6seRX*Z6iUorp)I#
z`}%f^4(#KYEPp{d6tw8HguEwu^ybypnVLLF>e|96u+IZ)l+Z_qKnLVxz&VwKdjS{W
ztZ10!jwUb&bBG~plLBOGi;rG{;;=!CZfU+;7n$*BU7A9oHs0yyh=6NzcXWB{Wq+ih
z#zVBmx&6<P`>h)tn8a@}re6lZ2Tpe<)g0ZC_ at 1iU@OP+R`R^us_2p(sT|VQ at rn}k!
zAC)0gOu#lBs4=kBeFrWxNbc{M<mw^UFkrP$xZfNG_+j1!0y?);WSzHfxR&zw9+w2x
z<)M4`6eR`P7p<SZaTW#xCXUqUSd0u8d_<mubTb^Io9&J1(Bz+UJE!;23>ux}y34LU
z=bVfxJi2y1>tk;_+LToprLg0E^e#i|d20Zb at szi@Qp}M#07)-qrXu*H&*=>yx at 9vc
zDJh^oS at iz{jkguB*~U&V$)w?lx(=N{7ul6_DUttkN%evK;w#WX+x644<JK-&EQKd`
z-t=VsKce2lkqtN6AMT=xE}GDytyx>`QlnCPuUN5am!Q<1ty09^o0=tw5F<9F_NGRN
zP<!t^`^Np=`+NU`Bu}2_oby>{Wkx87bAruuGd#;6_+M0m|7s=Y%=iTg&7fl;Ys{cy
z1xRFu<a~V>0t5-H4*ir07H-D<u>Mo<_43xI-$ueev>aYCG2Nm58dzG&4Chn?OFT{L
z4WDw#jXBLYO;L-iMD&G<<mHwhXYwvTo0q&wnpvzFxl~yA;bBvg>g;o0uTF;~+Z1Q^
z(R$Lc>C)|D=l8=Tf5h36q6ro9{B-Xp_)0UU#yXS{N|8?;v$IQ)Q0dPqq&eDq at _v8s
zF!XVeHd=!<8AS4|7}b<3bI at MEq&4}K=z?NLqWlr9BAdman?<THaD at YOOcz&ge}lFo
zYk1gqIyEM33rj6bMU~du<a4 at b`~2h_Kf~;28?Z`_1MO=v at R*fJ+Lm%p6jPzH<in)W
z7u{!k-4)EpZJ4<-oNVG#v<}V7Z4qY;ujwT)4}&T*T#1lpX(C745OU&kt5~THAq6O7
zsQMUa^u62#G|ey${c_wCqSeWgZ@=1Jg$8%jDGn-boFZAC!D9s_SbmX(t$$Gm`s5b{
z(Xyyvs|Ak4OWr6^#o>{~f%=;hDyZ9Lvm`KSteHC{+fCO$ntO(CK%a}H3yzO=c0R2R
zrhkye2PSfkvz!vFaL=<G!&7jsbq?cHJ_^_evW(h2-8F;U1E0vO+JrOS>T|lFY>kn%
zOYBJ~@-0v)u4lmKAn?RvETo(DadcGq_qZG(n7`1_Yp0l>^#6XI18%vvySpn`Jm=RE
zjw!Osu5cBj0PCMO<lo=8?77LUaBvJz)Vnv^??H(*>$v6e!4=rGcw*3*a95M}kKV|g
z<2R8_pP+M@#~Tq5FvorxO8OY}h~gtk=3hPHRk>Px+EX8sH1lFIB<AM?Z&&hL(;xr&
zsn+rP_wUhXSF1m>P|i>4^!-<RI|cPl;`QErW2c(yUf`xjM3|R5<c|SwF;zfuQQaHx
zybr(Z-%Wy!CjuU^X&8n<Ie>1=^~Zt|P=?N+*Bn(i0I~LaHj`4T0>uNtr}u5<J2 at qE
zbAE_!;S5~)$Vw(vI>!pgjN}$s(u at M9!|<#njV1mX{&k67=4^ST%lZ!@wi_^?(*~~{
z4Wn$x!!v5kDWMqq$BY{Cekpg*8HW*hco2!(J!kzg%Q9YX<eyvIj$AnH6WDjdqi~1$
z#+yYnoK!YN4im<;uc_?sB(4u0pQE}BG8o-#I9t~OjNhI1 at H81V7c7EE=+=+%>p`>7
zQpfD^$nJ9M0hEu~LYG_Qgwurg%!w75?Ui>Oc%8^P{AGu%C07S`<fp8Xs0ax at gKr_V
zgE_OkemOONs@=Y4wS6~mWF=U*R<KB}P&~@)?d;0g!_{oY4qbF^0w$4>wxhtTi1u%-
zyAVmBfGxFyAy-n7=ji2Io at Z|x*ti&|sA#I*@IW(998s|;@D3$TAgChHJ;RbLQCRQz
zoH(2dNH50)T)cf>esdb at wfVL0WWdLmNnT+^5j4=61A9O7ShT>{ElmGjeVLoE0&W<$
z%Z6~+E5c&z7Xw^(OQd=X3u8|gJvkp}`q*z5byW|KMaXSRdNOeE*1u7_pYDR;QYarD
zmDLPThxkC&{0GQgz+Lg=?r{h%{0zT_ZFT}@wSuipO|`9X#-~x89I=<mUsP at dNgriS
zksvWx1#Qm1gu}Ybefybk4>oI!Osx2Ft&@o~H7H?Y*wf?T9Z2(YjTf2Tdxi-wQR)zS
z-TB2wPh1Tbn!UawI>(+ms8e6meTMV<&`pYW#IsJL0*{R^80r;mQpae3Dd&*1&L=Y=
z!*BLuVjj)B)dpctWFKbC<+fvvjq9syp5NPs1af~(u(o3`zc42^ZT1H^(WJ$``iBYC
zrjreuf{8t$;dbe**3ow)Yh(Eu^)w%qtl@;FO<Q4i?ompvSYmyk!&O~9oi6p5G)~&{
zw{BOs*I09;&<aI6!_zHJ>h0{-y&?z8MI1~ft~m&*Q|x3)={-tGdSc7wn8O%ZmSi|C
zMG_O+;z-z&K)yq0=A#G_%N}A%;!(GG3ZlMl2q#7s!f9V05plE1N<S7az-XWSaplR7
ziXJ}p<+&f1JJqCfE at 8VGpFNY(iZi|N!-Y`2)wSn;D5_G;y at xQRS2rb^26>kg%x==D
zy7?$;LmRlS#un<`33&v^cI(;-&ce55lOU at UO^6tHLg9mrc8mzu*MkBpx9g)gqu}}G
zR706DJ1OV#{mxg6-J^lZa<-7 at Hbr_-;(hichwz~q>vtTsb5~baw at UWXy$PET7A56s
zw+xFqp|Lt*8qK{YR$(!K0J1mZWDc{lExFp`oO-HY at Z?t+$G7aj8u4I39wQzRjTdBe
z{2E=XmCLpp;aNb5QNlEBQt#oE-(t&9j$zW^?w at ->AJ*nd%G{|Dd2Z;FJ9YA`tpw_h
zHXoxCyfOE1l~)gnZP1b4YN%#`K6>J~Ag&KRIXhfesxM)Hth27Jnoardsa<s~I%XAJ
zI`}Zr9!z&Nu4$QF##e_e(??k-Xc6bBkU&a69g*|ZbD|{TT4o+K<lVgrlMZ}83p8ZR
zMfhMuSTim1cj1;aQYqG>C%PrZMlrwc>ygRp^3?r<cF1VDrx~ObUI1}PS63}(iuGPX
zt|O3ic02G;bWeroI>jz&dzC93>Q3{OmO6-{bw;OXm~$jDlIv8I at A~N1UXDJ)kJ;|4
z#^xndEF~!9g!U5t3ne4Q$oLeC%%XpJBYXd+1(>K*2zC^Fj2>Q`C8R^oqKc#S2%~Hf
z-#)=Q6(&4#9sH2-za_=Hfk2UyMxxHN+tj~({AM3<|NNN8q_KVtq`gsLM^DlGqbI;f
z<`-cJ<MZR=<D^^2!q6YqEXD&_l1)!CsXPZostQTxU&O&5@#L_;+ygJyE$6TsPq_xb
z58r3+;=Ms+5n+41 at WiKtDC^BC-DBKkf)60qr7 at UTbJP_Kj)?M#YKwI3)7IwD)7>Zp
zl_-4J)!=<^4)Iy?9{pB|KEEy*OfiebfTXuaPE~<N2*ssKVayrj$3*TbIGT#PXxQW)
ze6PogV{~^_Lg^D-7~yJgxX#ADDSjJxT14$Wn)3Lz!8_X}TcE at GXb}4c<&zPLT7mJd
zYPps~8Y#VB#Gc@{{d@!EUq0tQO)4F=K<!PFJ({-YSVqHIQq;or-QtW!AK<>Nui2fe
z(ON2Grsciq-mHdFOvu7hRwU{IPk^-x=e7FwEtq^)Iw6D*qG=D5f`r5b!znm=GNPMP
zgHVlr(V*po;y;^K`h6c6&j_o~QKCV<(=%sBI7c4pAv{T{Foh!Cbl~KD7-Gv&*xh&g
zc_!TynBL!Hap3<QlP4hDOSa^)wdK#-Z*S*=MoD%b$1qHow8DrQ`c2=8PTt^zw}244
zF-CW9pNon*L)j0y520f0R@{8=WFV5l_bQy5{H)t0m6TYE20_i})om&q_{lN(H0X1i
z{3f$DO9JNQM!#v}HpC`T(!R=00}xfzcmx5F>dM>FhhA>ZrCntXzHW;SHwsGR>Zo!6
z6Zx3`ek0H_y at 1-rA`+{<&$dZ7{Nax*!O$~*b%VM=mHQX{ByCeCqFAChr;G3Dq<vIS
zvAV<uicvsJX-bdE(tC;b%^tQXvrt-Bw)B>H>-N<B!Xj&ecJ~&05Zz}f7iB!k?q>-+
zhU3PIcgLX>O|QfhSFoucpCXk!w$CF~ni}48++SLkWy{u${b?&_PA at 4>zNUXZ;4l)|
z$DXrc;V6Y1Y&HwiGXF?l_gLF$#dGqnih$076gHjiY0x8R at fjy>@nC}efybaw$>b9%
zFAP%`^RsR=o5q at 7ri8DT*yR}lBK<$L=8S<Se`{W}Itk at D<7 at +$a971tJ^P1z;_qFT
zXU{R8D(WT)`ti17jAvo{sUKNX?9WM&N<XVi{ykF;<7 at T+-u<F}E&Q&Xu2~q?S&B->
z-HLj8f<w%(nU3-?;;P+mPmei|2G{j)^4I~YOIScXz|ee*yl|$Y$+nI#`saJUZBZ_a
zHO9o=CthA!VLj#FV2U20xa`BRDrJp9T9jDWAWLB}8yI{JO}M4IsoR-tmGxGLrE_mh
zu+PUVSSEep^70Z8HBVR+nnX1m81Zm0|G_z&C%)n7NHMP&Pb<>o?s1tH{W~MDz%v1k
z`R2JZKQ5GkeaG%A7v#<O7ZsZgll~Yg_iPxiJz8J~EY=G at KX1rmQI2beDTFFhn(z;{
zSHc1r$eoqfx&_=+p965 at OSt$s9YNsrD`N52*CAkoc%~j*%o$wJmP0yDFrI}%$7b9a
z&T6Qit;e=*xf}UbDIVk9XN-iT9!fTlO+_aOFA<j<e`&k9jUQVj at ck&4vEri&mVv*d
z{pUg_|I-O?o at vIV1l7n-Vz4y{?#HUPH3w>#E4=&NwrpYspH|}C$=oRB7QNU*7{}>7
zM&RZ^MwjnYj;obR<$}*0r|WApXAWrJM$S|8QhgzI5{lu=q)4^$`Rvw?2%%y4jV(1R
zm}iGG2&gvs%Z|-39PEXW$A;ORM~s)4nB3c{_t>55Ha#aSr%b{wY;A2_NAT~xHjH{c
z>cim%`=Sr#%eL2)2ox~r)t1jjuODw{0^gDvnee+ at e#>Llmgmy=xUq<BeNiS7%N*9#
zWan11TvW?Fyc*k^obfaqM-f-*@Ot`XO3mb<`a|zmh>1k5>eo3}4Pea9F%=oLTAp>0
z?~3dX79Sd^Z%ZuWUq%78Wn2?8UvyU2&d<;1gJ1YnYa%G*P6;nPBH~AvEs+dComB_7
zwq3gW!HbX*0+3 at V)1 at pSdgh~?t4SA;M84btIc+BRPmJ0Xa$gI3JiL>iE9rOPv5Wo4
z$fdXaStUWSbU>&%!O{5N7od6qYAN{MUdsL^!M==o at FFhAJ|p#S?Y%=zu-Igtmzyvf
zJ%#665uSy?i;MjM-P#>Gb+xU`DTdVl#uraKoxAQ%_L1!=tb5R{ef<=CSiR3L at eA|^
zCdK*vYSYobZqN2!`yUBke}DhOnjJ*HDN!is`2pl~gY85sMr$QyjD`$-Wcb(s19Px8
zlf`>G1uW}z1)|e-dkFt>=D(Zg>~Y)|@GrV#!K5%|?>&T)o8kl5rKr|9v~OfwBFF#5
zhKfzn09;+0jy^0ajbyRee2VkcM0HK|cwl|?1of{6(a~+~jWa;BW=u78&4ak;)>@;>
zM1>z9k{(C5>EtOYVIITsb8o_l#}@Qwp*>W-qUUc|v8;B&zU0}XeHtG{c=rEQo5Lr{
z?QKkyBY-9;=1nE4wSc>Va|yO&9M#3+Tlu{X;J(&p-0goHG<kZvw)D8_yCXvt3<ogH
z^`p-!Th0yB&C=q#0g5JR3xb%Q7Y6R<;4xc1r8g$wg#aQ?2Ij9ixzBniM%tyq3*mHJ
z$ZBxxrtfxTMpEz08&WO~kt)rj>)C^Cm<#HV;e?P!UX+Ex4A~pf&MwD7WKA$`m&evL
zJ_A77Y!Qs&mlqO#)iMHA>x8+6XKzhe|FCC}7_c#RG9lfO{G-9^J`Xd}F8OpmO48WL
zL$DQEGJW#%bDlIyr#6xBB}kyp*kg2md4NX at vY0Y3A`<4f!G1 at hOx>%!MCj?@FWgB!
z!+xfD+vhzoW$81+%(ZsmHXc{#8LmCEjfX*1?6=JM!TBB^Onfsr<fYRzmUjZ%f2#ps
zK9?0+G{^Xsy}hhGl9aBHxE`e5P)Cts_MpzlZEwMWjm)pW7Ly at XXGE$}q%-cXt1`e;
z>}qk5>z{M{iHKh-(-Tr+-Aaf5fM+F at C_YO|c>7o92u#QE*>JvvqWG4GQ#7uY3+wRV
z5Gw8%H_<yVws{Q&FyB2{8$}>m7kW=VF^5z6;~djER~Y}4Z(#+py^ch=FU5_%4zPTt
zeb&()@zO(!%nsZYm<b5)F|mc(^JF#?EK3ftOXY~)4zX6k at Q6I7pDO*ZZxY<DYXRSj
za}@rK1r^@-F5TKVQ?I{)uIKZ$IBTHdF*bB^3H*NDfblt=AG;~&8q_fj0-Ne9$U^sk
zf2L4`ThrLu-y65yfK|lcoo;J-KHtm-9BfSY=xWb-+*T!PFrt?Yltc6a>fsD&v~&GC
z2`{HjA*18{F^hcESssy38C at Q*QICjBJZ&O+OV$8DZ`yX=<o09x%N4_R<P6mrt%Nr&
zrMLn%M5#?Y+Mh8VOm9Ae@|F=AiI9uTHv*b0wBGmj``_N%b_+}uZXaQg)n=wF8UZtC
za at zTfc=Nj{_ZH at zENA&QhR^E at cdKTaL!is4>&Fqn1YAsT{DixzJN;LGFC|X2S?^5l
z;lqbXFEqrnC7qWT89Un6_Ca4<+5zk1?{R`Q*>&oaWGma31ZM-4W;H%9Gk+Um&r2Ck
zM&Hq9I%92e-wTrULefv{n#~{<L;iTM%fe1dUvZE0l6|5OXD%pv??VU5n#|a0)T9zn
zKDSvI at 5<BkQ|21!ND(#*F79VCve((R5bV-6{)FE=pEC8$c4T&@ASyn(bKg#teFE>j
z`$<cPU;>iMzhB*yCHCQ8BgWZ0x4oWlVVAGp)QjW!6a4uPC*ja_U-&kU#Se7#lNS!W
zeS}f8YMrb;Fj7G}GK#grm=ekykVR-9+896b at Fe#;_RS<MuZb`}#57rt=lrNNZM1E$
zUf47BzdBv!7%c-w#eS=6t~b{bV?nB>eYrBu5zaVYCt4Q4V%fMhMe;>|UVLo3EgkO?
z85UR=UE9_zDw^ZEAxor$V?sT6r;v_LQ!pLm6A>l+w7P4aiccVgqXNUG_<^wd<8mdQ
zbwSfyW<6x%+xa4fF^~u7d)XmTW=eHNZIVE=?*PCyEXLq7p*I-Pl&ANLO?;j6OK0?O
zjz9M-ZsL!_ojvId&A{>T-~wgLnkQx959C0b$PuXRim)tHPBtW_c!(u;kXO<q`!?E3
zA}x at 2x0owWB~ZCcSzCJ(3k!VHF;X_!dWP#}tkQqd3qcPGTQ4S!HyG1eQ2#BacKJvR
zW>!=U>oz7pZBLFO*Pm5*w0fY#vbWm at k|1Eg_HB1Z_LhmhGO`>((Butp?c~e0D>t@)
zzstUIIa$HxVKu)$FRT3XGx8O`p);o0rFtrr#I*hY-xzY*t|MoaqA<rvVHE*o;`q;z
z)l)S_LkcBN%pZ7`x*Cej?~ky0?xx4BtIKtmSuT&jbzQgEc?@%Y)Pk+6ceeYr78Bl9
zRoskLZ)*Rpv$QGNxxce7epe=a1MA+Dv1=f3=Y_DIBkj8A3eQ6Mf>fbT*<Mei%6@^n
zmE2EH4fGIU`Nbber)8DF60<u1`};>3R1I&J!RERh1=Z(oBFXOR5h}nJ7&bEEN}M4=
z at ghBLQZ2*-?eTY;C%B-gq_&i`R6;Vriu*=fHRJPvV7<`@`|SzAN7if=%H-De5RL~#
zOR5DFk0DvHv8l>??14MlF?w2Z+oQnAR1hj~ruKKLO|^nS(e}jnhT<Q2-jY;`&?xX|
zuD3~6YJjT<AKZcIt!Lt$%m{ltE9Fzj9>u-Q6M<|RNM(z66)u*_y!Pyz<zwyH_a>tW
zr4Q~pwDFCqwdk4gr|y@*@s)<gDG3GqTM2e%^uef_O=q~1W5DFB6$O<cKkZ(*wQ$yd
zV`Y+OXlWtec8Y@~q{Z91bkNK4Q<B|}BJ-Q8GxK~SPOF~@X7#AR#CuNM606~o-_*k<
zPY6rzz#Vz0Z$NUQ{b6Eh{XCL&5nb{jENc$}4h7w9k0j2^FlPWQI6e6X-N1^#gH^M5
z=6(nG404%&5o`eNqJyS?nET3MGi*Jr;UCj}$fl^<qpBzGV9s|NQbUkAxE8j<m?3MH
zR at jv^OSNmR&|@@-Lx<(50xthaQ2re9A~Pb&K&y{~=8<lfa+rkJKmFG;vZg`{AbxMk
zp2D&u{8N(<3I4s$nB1J1;AV{1$fcj?s%_{vdu1E=Q~h(%t4rqkb)R*!3F(5o78T?@
z9<lBq&W$ZJD&S3*Q1++z4kyE!t1XMDe~j@^OEwi3ZRWV;4`vid)P0Da(P%QiW!P2`
zQ|U26Be}W0>$^fGwYs=V;+>SW?{~k1hF?i>w=O>HieSI#o~^j#zdP3kw$t9uZy&Rb
zg0ZrM>Oi2Y-fwgb3lGl;ZO44q?gnt^zw*(kr02M7$omU86)0atMfTXB at m+uvuz|C)
zt#SidZujF;n1%Pf8O1w2y8uzESQe`NQG~AUr at eT|x?}an8G_8B8F6gEsSB<J>`k0a
z@|CK-4zK}O5V_vsuY+ at d-8t9%i;jK=T?J#h$EWWY6k#{DyS)g_(Hb|G8u;pS#Z8fh
zb~(Zqm*B~~XYlX%B2>D^hIC>(g!QAt6MkXGL^pNlgmoKFdknD1yTmy+Kr1ubX`}jp
zravvS53A7{Qd(<vI%iDDydSYRc)^^~Rc>}$byfwVnviX$c``W1xw(S<u4t>`5zpju
zTk{pdqKa70bM{2U&81iQ1;4$E=`?{D{Hl8B8P*HbO*6|nrcqo-&_BuwBIz34IZvy^
z#psWgYYRh7x+&T8sP?Lw&&&bAApsl~f4^T5aQKfk{#O^LC&B(F!5oHG=6_`Wcsojs
zM3CNQPf<;`2vhTHnH;7VR4mm(YiOV%duoZ5g!XsJxu#@aMsbct8S(dX(1$XA?dHLu
zhg50 at iY?eaHc}5$)ClFj?%1CB=M`r2ACd{>E9YMDG}cQu<jvhVyL1HPi*;~jvj4{E
z|A<XB3cj!R_9sw+xx4i*M*1DNY_SG7!zpc at y=zBeOi@)Zp84%sV<x&hhfQYnl(q9o
zR{5%sFX1!YL?D_6ZHWy6w5xjG=y)6v`r`z`Z>=iQ1|uR+CRRUEt#Dm&x1o={B)2Ja
zmY<evhJ63qvc+jNMynp9lO4!UUl{91w!^}}!p9Eq-o~%DM<U#G1CVIA1YeIN9|~BM
z*A(-q7eG?C9c=#ssGb_sqv1qf^8Osu)7uy?xwSu%HsV=TX}4ZEqnU!}uGDKXfVu%{
zOAKtRzT at lYUQn$O_uMZu3ce~%iwE5$8iYss5|%;o48w4VI)|KCf^BIsvKQ223#od{
zx?6?%1?C*#<<WaM%_LV48O-H*UmzhN{-4$!V|%%Z>aC{DHUd~2DdJ}RT#Vg&vz|f{
zhs}doRdq{$2zmm|&{5DV{JZhxaldJg(O0s3I@}#4n0*ad-8%jb|GAHO?|)Zi5K-P@
zdQMn2NToO6M626eW+nsb2(&11E}W?{9T&0g=rA=r8L7p&vnbX&sF{Ss*rfLF^!EyK
zRPi}Nmqe;5eiK(jN&P0pB$xobW+wD5EPfgIlm+SKXLBqF3AL%wYbx5rqg7AKlL_l#
zwC%ZsD$R3)P0h_?>!YRXRN5X{6S&Y5=YdK=g+$yo?j=^*s%F;u2(VX at A>1B`PdlRA
z3j_9<$N1F6vnbO1OU}z!e8QnZCtQD`_+}Ao-5yj3{~pLQtJae}A!*CPdBNtPt=sJK
z4g2Nri&xReEyzjSF-3j%%<&?3dxi8*|J?9&p5E at Ne?}+6jnT~KI1P=QlexRM{>evW
zj%w&K=!O5p!|ln!;x_O)#cUt>Vm^K at y<}}FL{3RB^U_-SzrVa-e*mHg>Z@$7Dm4i4
zb+}arW4^TSuo7llj98bw_mDMo-56Y^ub?I(U=~))s<)}3qUQOrE)PHzALSPJq$-1{
zCZPbpS50W2u4j*3%?!TC at KTEpwM6S%mBj1K1I!gwx at 5lo$lCOV*0ZT%wM=VhsGi?P
zqIs!6vE^8`qjU;m2OqHRd*_DTn1MzZlpWFSI;hmfq(Sp_%ZPt4Q#{0F225TwpsV3V
zhGtNWf35mhr%hOf>ddgki}0E2%<zCvy(lS4!;eJkM8|scV-9+4-B-p86g?4q1S!v5
z5rI&{i6VXpLU&XVW~LwoJU<`S5a1h~?-&@DE0FF0m4Zk>Jp!TPfEz0;_SvImb{cM4
zdv|SP^fQFkw+cwD;<zy~V=8v=>YLWh75c~m*)vyx(|{8jC{|i5a-M+)Yo<YFcvxiL
z0Ni0$tA;U0^kGzmhn&i66}1`WS&BZ4TysTN`-IJ{UJ0xdwa90=Q!{RWSgH+tr3O~V
z4eEC?OJD)U%+Pi}9x9j3z#{?S!ou+dZj_uuPPciQH}Pz0)o=@pta~;`gv}!SPK~FA
zk}s~mL5|}?motL9e2P8)g;8fi*b*3zd>JN1MDvz|0roonqHgJb-leK_r6#}2!*N99
zaZeIY3GAmc7wM#qCxV|7R7d-ei(;cucLgvv<#<pfKt2;-c=Kl=`2d!*GV^`rZu8m(
z!wHn|?wh*fO?GxVs`D~FXY{!OD6;hVhXR~FxQe?I)m{10QH6P4ZaFiDZ+c09A(w`N
zbsZGg&FU#Uo=)=e;13x3b5QHTZkw$_b%qxuK?y3AZ at eE!0Z8}_>j-n_x|8$^7R#r>
zi&>w}yGO`duoXm`=x<450;i9mM*VNECoERF#=6+!x!h;Z`#88hT*dZod>Ow*nN;Lt
zCb~JtIzvbY&u95?q-|RHMiJ3tckzd8)l#2V50p%n{X_LZclSef%Bn$rv=6A~pjAIB
z1*mj$Cya{c3MG&`D3Jd&NUm$Yv~sc>vGHTyJ}bpW`{`;G_^>c{I1omnSB8%4VDV(R
zEne3Rc>H+tbpwHtR%BMW?~OM}LrV3m0ofj7r&hL8?y!sF3w}=6D8zStdA3ao5IA0V
z$QF&BR_dpD>xsza?yv%PLEpMJv8Qg#)&U~m;#rdTFIN9unf*0R4}#$gkbX5gJKLT3
z!_;`;%WhZ;H+X9?5g7f<g{woBa;txqG=-jwe5rWDofxol=(!vG`i)3S+YJ^~x3IuN
zB at f{*zK3h0MR0i2j3-{i=5;+CO-BK!Y&S|wC+=5(p$Y<Updp`qoE%Mv$n$CgGwI5I
zP@(5)1%?YtIF|(Kt{OMRhs8!mq-6-Vwe=M5odftcu?Lw-x6bRGxW*>#X!=zsU_l)i
zt#Lgtt&J+KxJ+dDZHfHW^4U&T6tFlqH8Z-IBP+#0y=80-32{;<?*H;<qo~(ggc}j}
zd^|^*h3?qEkT`vAaSbb<NEx8rAv+tuZ{A#-jxcrpeyC-p77}IQkJqOn!(JX;W*XT{
ztRZp6P$v#vXk~$l8y;-b35J~2!<*umKgxXDmEe#0M4uMI`ETWXyQzr at +(*N~>gO*h
zj4i1&$XApR&Njm2<L^YxpM)7?a`}Th+>8Z|5WB`bjfxq2Uokp_St-=!PvzzYR{n-7
zCFKiTgOT6Af*zm$p}_)pY8W}#wb13h)t?8s1Ff4=9`-WaZaiH|>#3O%DM;4%>UuLJ
z$k3i-t#jp9V|O0VYy3n%*p2e3j7|K|=quTf=s-8mXTYh2yQ4C^LL21ceheqEp|L;`
z*Idygl{uz*8eGa9;`Q~Zu}=Jn4Re6FoS>pBA at x1HN*c$?Vk&IQM&oQcW+wGdZXU6y
zOGVWq%+1Y>h6pw!Sfd8n^K;PpkH2#TlsvAtNsHjx1hHFbXX{)I2}wRXKOCxC>n#*V
z!ILTch_Y=}!@eC9+?UUQf_%LG2K*+d(@bWW7CW`^E9bGJi5n~?&D}M$DVywAV<@lw
zsSao&h&$VmuklTH5dLtFmd4ktH#Om<LpCf+klF;yA6H at Ogx95gN|i{PC_z=ATUoFb
z{cK-lNj^%&&B$lKqRw7dG)1>Ho5`WCG+npB{Zz8stE5R?g3mQqKoQ_fEu?QrQv)Wz
zKCjrU_1dHy61e=pe~_5!rLobfZU4hjU0o2VYZ|Irsmf#Nf4KP|7CuOPnP|P?J&tYg
z*nN3j&R^6_B<klFnV<7-P=B=`;o3&sCvx1aRWp9xqX{eN2Jd&~?kCg{SUnhitg!_Z
zsF1m=-EBxbPt@(q{OlM2($jP&U~|<HToJm<=`u?y(iK;%5;5=pG`M{4*{!rQtx|ZA
zlECWryh}=lw`%#YA+&(kK?r4-B|bk!q1P7uq!})6RFA&M$s!E>-TpQ;;OmC1H-=(I
zhMkM~cmK2-?~DDHh60g_enu>zf;`I8JmypWBmn^Q&wE<0P29BKO)+Wkc=HnqA|g_~
zYLVbjO?p|}WwZ1%s#kc%=d(ugTDCy(Mi3GmbrW%?xZ>CO%vt?C+_LY#Yutj=hSAs2
zd*~<+ZlR!yJ1k9ewF;S7fJKjPTe6Ni`Vu%ff8KOW7VlR$T$N)9`#<}?3JQ&0hik(h
z^g<g6fHGNd!7;e<rvi0knJ2TKaCp&PAKqlU>~@O^>fhE)v{g2XXkUiwVZxnjeI1zq
zl4$NG`ecHFe!CJTo%Y`B=3df<n}T$OAkNU^^6YT2N;qcXykv6N-M-62*(OV@;s3D5
zqcub1-%(?viTuqXG5v34q+UdG8M}7u6OE{r1>goOO8a?br(L!XeP)CsIjgw2jFF4%
z-3Up>`t{$|uN|O2;rjkf=&+s|KWk8-$}PszFydh{RRgKrXqZDw2NxesL%+4_`ou%&
zG0}B<T^U1{%diyo`Ub*RWq%BF9%`DAmixFimq$U=pnWE;!szWL9s=q;AZJ!&9&fV^
z8$-`)?)|AR{KPFOnq63#wIW&4AU$}#ICxM~f0j at HJgWMh>f4l_<L=9Tqm)_=9l-H;
z>dt+yF?VfN_3sXra|@!$`k6IN#zdAE#quhmGqr<#hH0D*X0Fg at 0`$@<Apv+`Z4;HM
za{^m$IP)!b7gOAXLp+|-Bw4`}d<qtex&6m#s4nFFJm~Rzc(xXqejLlJiYwxxejB%G
zfSn at V$HXQ$Ixt4F7FJZ=mEJy7&MXz->e5`5sf%{gW|~i0C_auI{ZZ`E`61>;tu6On
zRDV6$#!B_aq&p}BV>~TB54S+jta^u8{Wp<pRBjy-gPk7-nzLnbl2?Bgev#UL^736q
zZkSl-fW>`&GWH-fg<lV1a>|l~Zh(4_;bAC!&qZ><pm$V1pEhAN^fjxDo!nfsE5zrk
zJ7ad!Da?$r$3PAtj{vi07rZ6aq#M>DfCQz*yTxbAXPx!F=SQUdSC_{#Ce1Yqe at QY-
zt`1uU5;n)=8<|R&G?+%Zd6E_cskCLdrnPrfYCD`Riq<AQ0FX7bdG^?nj7^$KGyuvv
z#3rQt?!7c at Q0RVJ#Qk-k2oH}0f5T1y{MN98GRffHyM<pPuKHY#5Cr>Y at WhrRM4##v
zn-u$sev|b(_Wq&X3Kb<(OE*s%tA6(2vZdwRn0ZGR#>yb}^86yrv9Tr=YX?oR#vD#=
zbMUYtQ9#4c_gTlr2siAN7OciL!eGw&y9V5g^FsrgLrQ!<MMJVlF@{<L*NrhwpwiA%
zZxgOlVb3W{X1UTK{}>$6UtvubBlz|3_*|UIKq2|=FP&8k1x6tq_R5X{a%;-lp7Lz7
zY9_Mom2mXL{~(M#o82RLn-Yn6TXy0f0~u1_M=u7R-rGI*B;uc)<#2l<UD#kq9q}kz
zd^s>ud<lTZ{#E-wEr4z_!c?6^eHlg3c9yRo&(pY;zD~PG(B&_Y7O at AXwhFqf|NhyL
zE#a9lwD-yTh`R#?+DPT=rZ--XSp2|hRk0f(TL}3z9$ex+RX(A at ml93muyL$+F<;*E
zZ`C*fKbF{P&9TKDGg#O-Q>AX`WA<&f7h}=k7BMZjKT_wMMk7%dA2AlMSgdPnHTR}3
zHR-OIWz)SnqnnNfpV=*!Fmr<zf?9vXjUV*I;&rSW7G#E9DSR<jLBgwsb=?%}gVRbz
zpn5-g$dDf0k&1S&;&?ooiHp<0LdX+PyH<PeC{3!##X5mf%MR1 at kH8&sU^BX(SO=mh
zGEi`~S?#n9F1K&HK(Dkjf>JG;dA&|SQ0Ms#_~^u0g&no5w#*aClqH`TcWB~!M#F3+
z`XKGmRBLvO0 at D;hp_k+EXAZ at s%*u0ionx8$-$8`cBPYj=N<ymkx>C*lT{Bj9a7MGI
zxMT78AW8cR^Iz6Engm6Q^pn7~B%O9L&3R`7ec?>~(XsLq>!xjgDg&UvOmg0r5wpB3
z8gd?guZV|9auol5V$~uY6w)s~YEWLAGt-ASTn4crtO{mWv%KwslXfLEgC~mPiDm4o
zW7~+iund)3-i;omZE_miimGG&PI2`MF?Ce{(BLb_kN1Q~Dx%aUsy!|D-xsFDldQ4|
zQ3H$r%*+r=)t4Wpc$(1&ooJ^_#^%(o-ckV&lb(5<;w#dAnaPv6Fv}czJKZGpx^9eD
zJLMBU{~`+{^C(U)VV5JT^d47ho!M^cu(aW8|0=@hlTdTSspO at ZAtm$X?Q^S|BEN$g
zJWB>4M7b{7Fho&_roQQ#`=--7ACT^JNJ?99qV<1T_qqW8KCL1S?2!N>v9>aFy|sBz
zl=yQvoW?L%H*{_$?T^C~>jV_a!xE2}g8R+rIPA9%q~#KT|N7w%<Gd5n{WYa9HWoer
z_1W?NLmGWNx8liL?O9`nE=mT<)k8Y61D&itE+dye at k%v&ojc(@BPhqGus3*D>gi&x
zP=+Dp)^F#3v3?&B(fQjHWcbZ at KqDw~0Yq3TJ{wDZkYSd5d6jC$vs!0XVWvcSgaz0@
zVHr9pN at a~cixD^HesMmun4MoIxQ`zdXP4JXzcP*&qsX>&n^(TEp7>N4vSBE#un#Bx
zD$h8&5l>t7i1XR22P*h{=UZWadv-S+A+#$KW4AlGt at kHec7P9+K|OaDTK?tpm(wN^
zymlF0RtH)4C!baCTtqoRkrHJ7>@ganzsHc2M(KHbUF@*r6jZN6oJ?pf3qrMdH7_ix
z(z43$1x7U~n)^W+Q*p0L0$0HI%IJZG6#Irrzlw%e2T0^3>ihQSm^C1(-QY?+iJ<j9
zbJ%IwTNspoVt710T3YgKzC2~rkzu6V{#;Xv6x?MX&-`43q3$c88}~PH(AF)B<51bG
z7m4GkD7T5NvV9#9F_4Qqc5~r2>P<`h?^2L8!X!ysx3;%=h^n~UVDhW9l%Nq~NAl?1
zii|rE*$CAVpU=B-JI?mR+Mg)IwSK{)G6u}vO^8 at K@jq{Gm(<x}w#1=D%9mDXDO_it
zB7K9l_5kbQ_s44)Em~UAE)25^DN-^WH`&&zHyTnp3!`bC`iD(5;FMo@`*k!9&_tQt
z5#i=A+N^)%HB<lE4Vk8;Y4~ao9dlRb_J^PxSci7HZ!h@>2t^lXJ&<XH6!yw&m;ER6
z_8oACYIOwb_^RZ%LS`#$ARPP^=#^E>7xbpfPy19VR3vQIrED_5ph(|x>7eLw&(Gf<
zi*fu<jVl`m<ni{JJ-2z2t1OMiO=oox06*FefDfFY-Q)7ZM8XX7Ye~6~9xw4qWR*gW
zg95yTwQWC@(VNZXOy~jKi2VCkX5I3dHWaUr{kF<sb{r4b6D#f&yW|G)&w{xGAZN at V
zmO>V=Ywp26{gqU*K6Jw0nzIY%sxwq{M}{uO*uHN~#q`$H%wS%hL&9)GmZZOgLt at H*
zL*dbx57z)^tH>LDBL1)lFEhPQapunLmMiCWB#lQ;yfR!OUE53G2nmm~-X~40%BGga
zqkIEw8i2EvBEw0K39x!$*NGh^!2Es9qxKtK3nX-85~J9A`z61o52>T1c^O2wK;vhP
zctk#+GY-$hYctW!K_)^D_n_^tG;XyYHONKt>hUzL9*5D5W27S^f()B at f@LcrX=mpg
z=6UEt$u>=X?_^N152LF7c<r#dlwz2p1W9xXXGyKb-iH9h80$G68`>4$<n*=;V3j-}
zh#1J6YSOqrPr)zuq*KL+kwiYuHgk#<8bm6H0Ch4IE~nd_w{$pwjjvt%tL)Gx1~m^X
z2b`D{_u{dCHa_3a2y_c|1as6|f2J=Hs8lefP0duh(kK-b78eefuG??7g(YyJ+ia7v
zQY4PH#|8GTD?P(+wp(Zr3G*}fm!QY?P6 at 3O6uQ=zXtd*piD8qEtJ4|LH-w9})E-0t
z9 at Zt-N(o!@r*Jjf#|^3fL7!d+vo-v$u+B4djf6p)d{AU0WlY3ovB6YwC4!=xJqpJ8
z$Td6LV>x*_aF8&D{=3pVc`^s}$+-o&nJ;t;)I1je<9zM+SmKHhdB7pi5Bj|!^wIwV
znjcl9kjZqoDU<;~lMNCiU}HF=mFc>y#jeyleitXZ*D4f3m~%_SB|!oqrza3OC^Vn7
z6l?SihGy|>>vOWuehztDEGlXwUMInWdl%9K=<b%5eUYl7{meVt8nm9KOC}OuvRSXq
zrtY6pDaZyCjpIy`G;;bOc$s8j1%ciV(68~Rrl32l_*TP8&pF$GtP5%&tBI7$N(w1N
zT8_We#1urR_7m5?+a|yf at Xhl-YLZ5!rD~aCBG*6_N64U><fTjHBNdhrPu+}`Z63)&
zWD^>P)LWGgdW38jnC(qfqEJyjNI at U2nU&ge4V4Vw4 at NX3Bj*Eh1)i2}ZXSEPvwKer
z>-vevXY1FXeqnSHMuij*G?g$$U+c?Y0d~j(rL=S!kA3#)0Jt at QgRM1KsZ)S)8Q-$~
z2e~WXq~Y`<Xv)XFPvF%glVY^eBj#Jv*95!6c#=#0l8sOKa(erqFL%ZCT3LN;?fP{j
zg$oyF0JvuRn4?ht6Cy<CLhH4ou)K%%vh77?tzw3GyBZLl(1riJ6yEc<{H}j&Sgjc4
zwwmWs<@BIvt~J|`hP^7N;Ub43)T~Nnn0!pdRAo(U{t#xz8H*S4vwa|N1lvG{NN=N(
zf8X((pEDZ)P)3`Z)9Xe;joQI=<&2un_P1)yWPoUn3L(GHPYJCY2%~IIPfHL`$>MBA
z`Ad~KWm6}p1m*%5@*Ov#`nW`x)_N>-tg4h1kTWxJ2J6J%bStBK#Ase}JiGojzp~B@
zSCSJx3qPjHw0I- at l!Jj{>URh{oqlXP$;7YbU8eGIs_BP&_L8ZFc_Fc at qbcl@&ZY({
zmW!CmAc7;ln?LE02FYRmY8GK?;%U_}j1)~b|JN7<ts5G1^fzJa9+h%8_9ftjN$7{{
z<Cg$rm7aiN0^>Y3!>L4P%$t%PvXKfF-1gccC|9#-6El4wTk!o;-x}SBh);d&6wVg?
z7Im9gftgq#|FeVD-79=C&wuheKAu_gOsx{*hT4FoErO7{fav$uA{iGX?0fZtYZa;s
zJ9#&0L0wY4cH+(zf&Efaej;EJMN>y=y>&qLA at LQ1n)&TvQnVeT`UX>dQSwie^l}Vc
zTF at 4mc=;pLOSK*LVv%qYX)v at DCGAAu(~X0SXO-IBtgoal?H|7)!a0A+fyNu2oQp at n
zZ5Xl at Z)NE2A~JM`fjX{G`k0obGecM#%b;^en(*b(@B><$M3Q9jrS!UnzQZMr{SE5#
zd*hr!^?NBr`+q?R2O}V^Uq*C?#7O^=?0ijIj82=v<Q)4xWEjK50MWkm<!>l+uw3(@
zCkkXC!(>B3tiHEw5p**ONulyLt#3L~561pp1g$jxIc7vwv1vP%7DIz`(Gb6Ah2+tU
zgzqDdJ-=NRk7;*JO1ER+32-2MzEOft5h8bB_eZrdx5i4T5ra-(q$<NMwD;UGXrrXe
zE^Y}O-<;4jH|~_0x51q%OEyWj-}lQle;!!;H2VquoS-k}`Fym*|KCaEyyf?Qmn;x-
z5WbxbA&FU at 1KKVcwB9^QFK1<Wh>?~d>L+z(kl3IooT^MXZgl)w9FVbf)P92lSXzK3
zTE~AYt)Y8++aTK#NW<j=dlQqT?VRIM8444Nq{vvLrV8f}`_T}z8 at l7lM!BcQp;;pH
zZ5h?3oNeCT7m*Qo)b84KCgIKd1rDcaVlCNN_UZ$40I6usMcmkTxkwS!2Gm&<w<%NR
zxXgQekH!{IDH0FMR=g7uOY6%B3N4)^Gm~n4_vZS9&j8|Qk1jQBAJ#r%mO5_P?8M%@
zx2{{DlQUvA-4<J3{2<RO4GY4}l$g)Y%=C^TC#WVJ#|-WVRDkZ9Jss5-RuJofDeW1C
zTyB1<k3F<6c9U$GyH<?W6A<1#{WxEhsK6Y;{2;B+Qa8#J*9{ksh}i3ni29y*iCfAW
zO$M$h+D_^`7*3A<D&0sC!@s&(u9%pGE32YhDKDJNUL&kHY|p+eKW-}AJQkNBq>xA#
z*}sba>qv3qzxuu#ix||`08d%G`>p(q{r0Q*G_wLx7I0Qr6saDUTleQ;Mok~46cbNN
zj%`Kq65i}b+5K!}Xu?qO#<<DPH$hpObM%R3WcZ)}WpTjat!WsPs1*PW>Zigf$XAt>
z5VgRV521jeI`_D*qzzu#2h$k4>>`YWcMqMgF}q*vPdlXEcn-FJ!E+nr-{!&B_Aspd
zvFKR(2qNDhPM%SvhK2yvfk+8y+uU8!_fRAhGv@@}QHE2&!Rz>$oGc<5Y>&S~*lVAu
zQaQWSM_>xsR8{zCHrmP+41uz_B9UT`L*L?DS^t)uO)<PSt>iGxVR%p`ozrZSTNIF;
z{A<qK8*{CiYUD^PQ9fSmNupvnBrtV*y|%r_Q|u^v;U1Lqd at byiLk>n2NAeuk+HHF|
zW!smcQ&l#pB4o+d_GQxb5oD?*k?CWH6=2pauHt;D9<s=dMy+2Nye@$UN49|;Kzz8E
zY9K5~w>`K#t2n-1BXh!G>>4^s=|J$#%ocVbZF#`n&;|#HL7YKdULVb==>N?kRKC8A
z- at 7`qH`2=(896%|rW&x9ZbZIkRo32>%i6n9&86xku!IaExE--?3G1^Ytrfi^3Km6%
zPsWWto^3DKUv7r~yE at -4x%1t{l!sc^*OqQ7!J4~^Lt>r0>gD(w8i?!R2D`VuSjCN!
zM<9R5iw06ZVjKse;bO(3ltnWWF&X>B{K>ivW*RI1R(+#$VAJ4@<CwMD`|Tg+?J8HB
z?d>OROniP7Q{29LW4Wc$@`2&<uRgfD)hQRQ-$Cia`{Jg1t~sZ`^!hD=(?%cCscMDj
zu`1AEs-?#pC5_-MgzVhE=(3ED73FO`SAL+<O#zl1S(_d!YI6K#dtTaAXyMF*ys10U
zGlqz(>?Y*>)oPr at kn|uJ%|AhOrWZbL)COjXU?PGC8tD?Y at TkDz@c<`EJz)yS9+z~V
zqWuf68>|l-D12>45Z~QdBv)AU+ulFNrlx09PT4Ds53LSrxZ$jIJO3*Go*qL?G1EuE
z-H?%9kAf~6?{21+P7F8wFPF%lbn5dp$z5m!9IaPR`xmB26V8#vIZ*in!6a`i)52-z
zI4fd3E_K)+Wa9ddsBzDtuAlt3_|L#dFv(Fm0kC&O!OHjEZD3d8tf9->h&6+Yazm1=
z;?Ky>o624WGPwSe*o1%&z9&y?hkJ at mPs9C<S`gUSkc9Tn9sLX#Gr2Y%YYD!--yWsR
zub%b2b*wcR^$GK)duuMq2I#v#8{O^)3^-S=P`Ow#`#o(rP#_#fH{33v;3D$t$~R(R
zyiTDrCnQP9x`4`2{fPR3rfZSkNS at qpr4M{zx!T(XmdJ$E;@lkX20GxYw3{D!w0{>h
z^7xIRe(MmmoTY?7DU#6H7FV~<fo43M>A8=7+#24(=P7xNUJG^`OTPOY?_DeGF`ox3
z8edc(@7KYC1~EaSMtmj<ak_WR-nzO$M>HI#lS4>W*Y`vG9QbPI#@x0fg at rKrZNPCa
zdsV&7Re#F)ryFV_mW%hk9f~|`GeQLJCl6ttO6c%4!B`aK*6|}V6u5P)&$W2sVD}GK
zPR;ef_@;FAz5v)Aul+E|&|+aA-MeEi{5W*ICWqhG1f2tmAwFMM<&iefYVU8pcFy?W
zs2OY^%N8=c2?~M|8-8T+g8NWIud7?Kiz!u%6+v_THZpcXrd&g-=RjM))T$>9&A>{~
zsONV_2J;vQnD5(V|CC_8VRk^Qd{|13J*RV6@&rNG*tYj=VWOQ<gH at 4-D*Hn}M_lWo
zE{{8W`HfcKpH~BSY7Vtyt-kupFu?TL&5pg at a(#|OBie-9zD+h$<0cyF6s^eR+w4XE
zK2x=qY3bE=CH8!YuLupljrpGB1el~fAiH<VB1kGLrLL}yqb+vwn+_+&74oZwTIbdJ
zvws!56Rzst8kghLQEw3nW=$LuDp%3dtSxgbQb*6{e%Y8=c<*$@y`u8dXgZ#23sXv(
z=aqS4$ua(@-1I7Z19;>tnFPg5ad4=xeXbnhBIf7w50>3l5v*T2CEQwWvYJ*7{jEdn
zs-Hih-$rcd6pv5iqa?3RsD8hS(}5sFSr7+R)2b1^qrgi~=ssy3PI~!G<ov1dfTINe
zf5l~ww0(M-E3lTjz1urTDTb053EV)YCy}&fv#~-#O;1IDt!IYxEZMsmvpR6V23nm1
zsk+q$3<#2!^xRvxl|_MOAeCN_T28--pi3#9;vra49KX-BZ1pSCM94WOZToXHeuRRI
zkm7+d(4ZgTQ3TEfWX~z)1Ni)nsCz=cHT==e$)D2)wslUl9r?)<|5#ia2LQ3LxpnvU
zTG-})g-FM4m`vH{<gn|*Fzq>K3n?Ti?;zSCKqsr at iE`Y~M`QWb9lw&;l-JR=U+uar
zN*!YfE2P0uo1G_o%yeu|e)LzT*zuex`)1$7_iBJ6S>BP2a%+=$(oLQVr%J4~F|?1O
zSA(ztT0jp=w at tT+KHIXoX3V2A6kV<XV!hF}Eyq^vCPs9X0 at ETf>6~QFNbG|14=YJX
z%Be6XtMMEMIdHqaJAf25RCG;_zP{=3ezU3=IMHHEVM$9(5Yn|Po6^vX_g#yPYmP--
zt<CNDhTljM{BS2*b=#=F<PGBzjw*}Ix$uru-!bORcUNnOlE{H9zq<e9NcPH}6{~#l
zxae<$|3O at _@#>?#uW3jHYO~mv=y1L}Nmxr(qSoasGBZOfX87Nhjk!xo{L#l|j!~`k
zixA16`A*TTE-tG~g(pfhpEj85<=%|@wJ?1$Z=xWoQ*!>aE~FnQLAk+u5~)cqCwmZM
zwbIRhEUc0jo&~E>rbxKtF3{}j_jcT1Jb%S!$%z3ewQRBP;6?{^@`%5_ZcwoRhFWaA
zI$jGmpTas!ac;i6Ivjqs)`^r4T$kNNoo^PpeADT#^3`L|B14WL5)OkN5oKvUtUEH(
zuSpBh`{idM?8PyD<wvGa?1c8Q4wb*{z>t?&xhcL|!oon5UYSpzr7@<pD%=;vgS;x=
z0{w^_*BTBaXmQ}N;a){h@<J7%FSw9tRKHR)cNCQ6^P|f*nBlN*D4X`3F5h0ZBP}9?
z1J5nx50AK&PX;oLBRZ`*+HcF7^L9+5HD+eU-~-07AMJ!<Ew{_K3uCh)RHpAhiib?(
z>x*o8ic<*C938>Fwv}V$=Dz-)u<i=|>h;Fwx^ajyGQ`TqytE;QfAieS*rlK3;V~_N
zRh!{n(`=U`9%$!j`6-%o{{-n{C(kYH?D^d80*Wp}eWRr$i)&XiYFBHMl<+2rY9ITo
zoMI&Ia^a%^$e~TtdBpykX|UBQ?oC|lBmPTk%Ew_b4R_7o`<iXYCcJe24q2&W)PU-d
zqxV%u+9NlC{JuP?F=O|{$_05FHAvusnm>mEtI<WKwmHLC>SK1|!SZ5;;t*iN^8{36
znFa;6{t=NIb072<JF$y`oR=B0wR8*B{cuc`gI_u7oFM4G_G>fm8*+Xi8#NVQ(GSxa
zEh}4E9JF~-;WddHdhCTM);g6U3_m!fJ4lA1?ZXWnSo|YDLZbTO1VS(Q4ly0a at 1%{a
z@?tz(luzZasi*JrU at NdxB5UEQR-FHg_kN3N#%A+_8-mkzabxIG{(@8^ntEBdvxRNV
zc_wawNy^}!mj4V>87T~A&-}MfgSSA3^Q?-?1rcBuzgExQwZ6T|RciIax(v(Q`TX@>
z+?J%jn1ruH<ijinhQ9xK%KWFs&!e&;)v^f2r`=tiOaSP|;aiTBH(~yPja1?8vd8$%
zNcTwQgc%W<aVgirtwn;X{aqkuaxpxmO}Xv?yMM7VD#*-t=S-XuK>sfE{={Q;;?ma*
zM3tuQz?!O;x;Ki6K!e4#!1IlWK4)lPBG*Id2dc|Ro#zZOoX*F`flq{l+U@)rk5Q&-
z+kFnB1CsxI5?G%igWn8gwn$s{4Zlx+V)9YRtjrXO#UA)a^l5^W=e&S#WdWO;BQ*tz
zKgyqcgc?%9FB4mfzE>r(5frI$3MA2^mI)1{^2O;iBMKP)ANKDI;w>-CZf+J9lFnIF
z&QSyx^equwNxFKC9!w4IC^IIbVlT<wWJJ4>_Q&(Lx{_|MJss`A_)<6OcqHIi5WM!W
zI;pfYm92sa8#BRi8|6$VNDM2ndh9FoV5COMVQrmGgH4<rrK53tg^+&T3`Mrk_sQ-{
z at 5Q@my)7h at t<TPdczw+b<aOX)n9>e=u?VAW_5Y8ivkqwTeZ#$qAR$sR8U<lWmvjk&
zw4kujos!ZGQeULIOG<>%F=C7X(lxqa(h_3=!lcjmopb(Qzt5ice(w9aKG(sqMZ!|g
zCVrmh1C3k&1H4`6`hF-^3orobYQ?Np8+^HRxv at l6lh7P|>2VdKi(nFUZTMdkMs~4!
zWX1JLx8~NX{d%cvBL{V})^fYIul7ejq6Pj}tlE5l{=a={+rs7|L)%S29x<~T+w9Li
zAtT<mGqy2d=f8Fnd0mQ;OZ!~^`HgXK7o!Y}h_6+{w;k at +DIWCoIcHcr!0C~E8aeAh
zt)fKS1WAb<Dkf5-;v9F<`IYZ?6$gtvC)n#h90EaP+Tg{sf{Ib7Y#%v56epTsX$kjE
z5u>8R4~*v0D4KokM(qGYf*RutJ<~Uxnk#N&@Qm6y^Gf9FUy*N6Ny_y41EYHRN7Vw)
zLdRU*e at LFs{%{0kZE^U=nZ>a`Q!2%wx0Jvc96=%c{3HTA at yfEMe)ajOFCK5@=zaZ1
zXUT;onUsFu;<R7>>J~1te1-1yX9yMCq@`kH>dWc*$&N0AaRIj3esp$?oaEK+<zuh1
z1+b;1u;Ny9-wsZ_sQWST(*VQB+~hu-E6_>!-Hle&rW2pU*=URisie%1P)*@>^2z}?
zZ325P!MgORVWY0Xl1`@em66 at uoP|wdX^=~f>pu32+d(+Gs$Y``>SSzqaZMU%?>M;B
zR#n8}e2G&a^j~WBAGuu5-8OF&Ag(>G%5KkP88w|3M*cUge71XvGsgY1y{!oryXi$1
zBw%iPZ;x91FUqX0D_p>TCozsr4 at 4&FXd!!9QDc3w_!r>qFl8E{cHGEF)yK at 2mX&1l
z-=gcT(R3}$o%=(MOfaswc?FM7^0JD)*5O6FxbP!T8P9OdCR0=D<yAy*u)qj+{A*`!
zJ>8@;?o135pz;zkSJunw-TS`ZKtZ*@up|hV_0A6EmZ{IoS~omOfW9d7jF!7tRsjCf
zkMNZY>6Ojf?Hlo&)WH+E&m))CK#3iSkLf0HE8~7>sDL%r|1BLaOTkwqO6}RiQ(n9=
z&rxgscspC at rq0#vC`-RwcS)*kswOlU)g1V8waP3wY8alX)AjmrqH*9$Bg($8CcL(*
z{ts75Z7)*f8~AZ}5Qq-rLIk4%H~%R&X`!8-QE_3RPn1~jxTZFRRoHPtxiyP5v~E&T
zn(E4ntmIp$BNr!mo(dGHJ$$;cP<opfr5=uLaGuKYD7F%&o}Ybb1J_ISGJ30l+cYPf
z(;m=e$3X}6<96YY--V6Ei9I9LuL}%7Wc_E5nvOP|-S8Lx4tbrnY)zSDZy>h^|7vck
zZr6 at 5w+%1*gE6R^!+)4tNxpdRXEIC$GAJ|K|GS|ws*If2YR2E5$OgM#@!d`Z2QA-T
z at g->9B7?o8f`fQkYxXi_yvq$e<3I6dl__4j+qO&12|qNIZQK&nshu)kkuUFZOLKwD
z0r;BDywbxtY8Z7JXuJOXh>!Vi)w4lrCt5CihWe6-3^zS635&e+#eQU6o5wV`G&`he
zY>}NF0MKc)hq*@awRM#;eBFmnyY_-4H}Z7d0;G$#;<2a~m;V3l3)qFoHonJF-YTi~
z0XqW`JHfci4oX`5$5Hq|yoWuc at Y5!Z_zqQ4V!9R!IEl;s!8MJ>dYi0b{azzZFEGNQ
zqCx>38i)W>tGkSsxK|BPz3;0{AxQPaH?Xpar)S`OsN9Ytzo57$C`jzA16gD$G+Psg
z|5LLXB1Yg?%flp2o!3sK#iQAIu}<{y#wjbdhCbR=noE(_ww|+F<6p}H?~H at C&IhF1
zunbRyC(JgwEI(h0zXsN3%M(jFu%vG)rjyjCk9PxGfP$VwfVYcHssUp$X)depb7TZS
zk1J*~D}PW<0?Vw*oE*rM$-Zu<^@f1BKlHFT&w#TXVHFg&n}bsuz0J7mG<LfqD}IB~
zyx}_vVfz1CfU^GEP1%14=G&9o355R@^5)U)*%9jM==^AN_Q(HDY1g+$r at JSvR~ff|
z4*#L93T_bnw|l|2eDTO<sAqgPWVnTLnz9icZlnbopI(6H)8rlDgXHbPTWPhNJIgbM
zC?_Qo(#X#qXPg*z>S15{q>+~d!4w7?<O-x&#sHR87sDVz1FvlXyXJBX2@{Dy`gmwv
z;TculQ6b<0-M;KMoA6AQ`OY~Uy){-+CEbt#tsTD}o5)uwpzpo68N3un>Gqqh;{;fe
z0wD4Gh3n5?XmSQqs0H;NR3g>gf8ih#obSjfEJCZt<y^gQuhC1*x=|lg^06+VMwHEo
z3RD3U0@)7LUm|k-Nd5u-aXmHlw8<t+?jSk7D5gwF8;F_L7B;lzf&A1ki5linSb7JP
z at XLDLX)}Xg>CEW#bg$*|dd3`c8DmcUKxc`sJGU0**(V$o^J1#B!3pb}z6A6E)*Q^+
z(eLUhY`Yx)ci-s&?MOz`CGY9)g~7J}a#Y_!T|qpPN`25%FLvDHbiQ+Dsie<5B`pqr
z9DQx9T*xm?y`oC+G;O|4D2ZdxA$NtX_ZRfHrxfpkz at Wp6W!~>d-jZ58E07%hGf7uf
zCE51tjQ(Kk?e()~x95lxS(zL7?Fwuo_y}>$7oQ;N`Ty>%q5Hc>=l?DaH;&Mk1 at X^r
z8*YF598U%NN?jgaa`jd|muDBIUJg%R5FUStbgzV;<47xToz+Xpp<ZWQa~6r@`qN}X
zUil0YcWTKknVyJ0jQfl~p4%Qj*L_Wx$i(6c-0!Sr*_K}--WJBiKnYFk#?F2IXy+d_
z?WL2fc?Nf))MaTo(tEAh6@=l6A?Qu~Oa9nP_i<zDWBfp!%TZRj8d!4s*q>y}^9fsK
zN#Hjb2MnBch}Bai`zTSx!nMx#%U3GNh`!Sx-l{i^2}JcqReexiJ0cV(bnw3O0d=T^
z at Tj9;!QhBfe`y9x(ADC;=!C$l24PP9F at OO>mp<#pyNRBOd0T5Y-FLe2amfP~3jT#q
zwM!%T{-LgHB4r*ZV-b+U^n}QqC$-O<i`m{4>j)8PwrV_t$0-(>VpjYe at G!=(C<%QH
zg-X55O<d-la)zl+GVS+S)r_uo%t~b-(Gjo&$a);(SZ>H}=cwMPp(Q$z#NB-Iy>5kc
zIlbfaSl{<LM-6e2ifp17$l^K>iwm4En(fy`BE&n+Yi?sU5T`XabNxBbZkGCUYHk?%
zFJGE6J(Il_NH36iR*-<~$4HFfD%lpv!~82=w~NbL9pOLN+bx{;TubBEUAf+c>ToDN
zU%t&jV)7Ziy)zOLkc^8339 at k>nBUB%U8=YtoQ&+TFA5<!7JR#RbMvoz2N at 9L?Y#yt
zmc4xD?cr?{c(c=hod5hh at FoDKY|cj?B5^Nubu;XZNVvt}LgHnEuUi&-FwDMZ!Babz
zCQQS9XJQO6*}iSu+h^Fe)8}lojO3so+X!Tp?0;yit)JCuzzrU+hj7hU-*&w1<uLa4
z-&Mlp<<;(qHQ=D(HmC0})F9JV@{4o8)!$vSv at 3D1;E_m(ujew8X8sjNS`hquQ1Ah4
z%J+0<9w!KQ#hf at wikvuVa`_$X94Y_1!U`XqAJ at n}3;tm>DJ*7~(vLE9Uq+p_i}PNN
zx(bTmezahgtG4aKcx1nB|K$eE^mglLv*6Y={$;`HGo)#Idk;Q-3a8ePrSL05-mm}#
z^S+CL7MkYOIWi5JlZN<s!4}p>0N45fyg1V4U)v~cYM!_6uNR*B85q0~c=v;7rkrw<
zBB^K(Qddmbl^?bkIzT4)ZN^f|A=b>ZyMJz^-E5Jywf(7h- at bFrLswf|x-C9Vs_<{X
zV*8^A^U3%`fwHo>rET)O!Bp|P`IRBRVW&B at k3ZEpn1X_~H5>oSJ}N7994L4)SW;9~
zmp98)9hLSSn&Y`AloI-dJbNa*y4QMZ8IT(E9K`+jmGN)rt<DVpiM!jhtN7GUk#8&2
zp?$JkJZKVk7ED8A4bLyn!n4+>RGwNBs1c!%T2rT?&z%I7xNk1Z*7SGxnPXN4w=$bi
zK-GAykgx<*TL0&G+wbo>XvpqSPXbJrfOFl-alNzUDhs$%;Z|O?M{$+5;W2O^nLndv
z{=Ql1Fq?*O#`dQIu46Mp-N!#7QOqW`^~>3TB3|^~P1}o!-lL5Du2TLt=%cH{=8b>4
zw+S1)JDUBM*kDPSpeqlY at aB>4>C}!IIZn-Mdd=J-)ha0ycyax?;{{O*BKSh7{W?+z
z)1MIB11(5^Nq&v)cf~E4qlC`=mWLXe`7+}9%hKX9*8)(Q(`MX4EyH5_al|p+t`W>i
zXF~A9$O1n9iIrzvH<x73;*r4*ulijXk%yQB*h}x=o(Av!ezIr0SKq3_%h`NR#pPDF
z7H$a}dxiHM9hcy?;_(~*?oI#2a&Awl-NWuq^>6%)Owc7dOnDjnaLwCWcV!y3A(p?2
zy3JST$LNT)A!1hw@?;=g*Fhh)B5`P*7Hwp{v}FGB3R8h{E#H0gGs_M3Bq&NZ`RZ+Z
z-3He8=%vCr*6d2N^%QkGqWyfNKqg2^=Gc*j=oW^;TSo1SmeDO;LiUa^mM8v#<(~&!
z17ubax1Ud$af0Xt;_3p{(?bjn>7d!)U~4K+6E8a!vL9NAudtJ6>Am|I5qx_&P#o?f
zf{EV{qHG8zh{(8JKiSzBd`1}7CqJNa2?5=V at z0g`?^rwDD2H!-BV2PcNi{pfn99h~
z<=l)GoE)AU?N04LE)mMFP_mMT2;U$n--{LYf$O`*6prk7=Js9&*S;b~n!fpMa<Sxs
zFs5V3cV&`#ggo1eb7 at 0{8e86Tdf-(fdb8{D_p;)<Fu20O?+K>{k8UGv>1EVQ$fu?{
z(=Mohyrp))i-2X;maC#TQ@<eOFSHHai>J>bpdUUQJ{FkN8-AAjXbBsZA^H;86RRo{
zsyk>dkffKd#6(B&V)8-y3(JF+lOftS^SQP`QOdU~4|RRFa4@@hZjTYRI&VwX7pf53
zG`xdsiudJ(KG^ESu++Fa*#&W%*G$%KA)463N2TSXt?}dX`?g{#gID<Bs(*Or3IUmn
z`8bvkggAn-OKv!ztI34 at V0c0NMR@CYSch<y<h{9>x%gP>M?|KcY>YYVC2A%q8*YsK
z5gSDoQTMAP_HnSJ{yW9PIr2`?w at xFC>yX|_pl4u}iyPs`?qp&bag35&1oH4|yhvFb
zPt}f9Zm}Nw95+VX0(n<JYk7QSu~=$6J2^Yx-aA&JhKL`N8Zn{+7AI}K+7CYT+t9Q<
zQr=fkF0}WQAcl>DCfy4!1FgBF8PSPQ-zF8%*7;V3X?zXhx?yq;2x2`W4T&YHWmCbk
zxP{fWf~-`~NKUgyZ at L->16wSql6G`_b)gfajl}yw!T5s9rpuk!h0DM&PRJMPdp*3(
z1%7Y*5CooG#481cLhN7U^~2hTQ_lbMcagnRf3R!fuvR2|ecBv+NCCu9Kk85%=zZdN
zvhFZO13^|XQB{#jrG~=U41yo3Fx8G0O3VYQ!qaj`8Div<Tu$HBe%o%~NW)+Q6ELfA
z$&NK?2HJ;;*Eacq;=Ua*8i3q6>e8#g(i at G*@C59Yqzi7x at M)UM>8#fHvXkq+dMzgv
zXnB$wuFD6_M~h!3ob;hg at xLE}{J%uU_1>?j7IBWt%Qwj at B(UD^G^urBeM(k>W$y2V
zFIyqt5(66Kg*Sb7<|Z>?zd`B|n5=#+m&{(!<5?PJP;%Mx1bL!prgEv$%r9Mj7)8%f
zoc89(3^tb!cm3LLE}$KQFHN{L at DIE9PPirldVQw_-Q#@i0)?25n9V5&2Kie%K!j$I
zl98ONv!5EM%7`I9NED$GOKG|?@f(7Cu`W;j1P`m!eE-w2&sSOa4QHr1U)`4<LOh9k
zs-x}K5Bw2r#Dg``%dPv9cJECJ=wtJ7n6yV2s&DOnA;$-_QdsI{fu|ler1t@?%uKnH
z-z&=NX)6nvKQbcJN<kr!ocoY6H1JNms#a9Imle}xKdq|SpCqvF6suNWL9YBtmldg@
zU6XP*tH?VYaO<v9J*H2fERBd4{`7kK at y(`{Xp(+>T-8dbZy5S>a$q%m{&BE$&3#L1
zvbxTtrrPZKne^?rlY=|{Lk09->%1l8L3YZWd7vV!<e=GU$0?7P<F(#O`bD%t=BqY}
z*EKp;R2h{r!H>@P5La#-w69$Z3szuqhXj?ly<`c;|NkZ2#iz&d>-C^og*&wdu^8ya
zK|?=lR$~!f_^ltMjV}Fysk3!(Bo$1nz%GOrWz)iOsV&Ft=u#jjZt=iIW`r`1Q9+mJ
z`mt~}KxNM3O8VG>X5HaO<cGDFAdp0X2CJu~WnvqVBeq)hOV`<*vko*;*VZ0v>PkWO
zhC~=x2wxHsvyBR6vg`luUR}3Pq|;-8Z3Zd3js6yNjx?ava2RtRX#K_LsgdtWC(+M<
z>8-?Bs$;^(1Y||c_Ae=uyhm~0#6{N<zC9RcjM!<ncU(p(O26h)_se^Wc33&N8`P{^
zdJ16SSQ7&wk~|tgYZfpFOyYGcrv64TmYa-i!<LGUJ-k55*R37*OA><}yELbieCw<6
z*0kAu`n)Q-EAr{8p3fUwF8Lo^20E{mK!p50;ky}S8xF7V2I+Uhc5vv9Gkc=_K3O<}
zqE~oijX#`mZ99U|>Jw=-2kBUjF8Wd1lFRZwikBDqn{mCQLGw`Oa)OvZ|INNSM>>y;
z!C}j?I|)Ny&?qjE9Sb`%548JRppx!C<FgW@*!Wrm at Caw5`<n6;`Q0x~-y7YZ_R)dL
zQLwtlBr1_HyFvlZUue4D$!p|5niH<MAkU at m6PsG{I4@=5xgA7URg=aMmY7#bkPALy
z^IRfzsCUx+$*a)S5zYx|2zFrsIPQOJ|HEMzfM5B3yLXN^!E!4Pxt->Oih$CMU=QT!
zbvtVJ!t0m0mI4Vlbb`ibAy&dO$Lf=QUXr{d&5kCGI1DEjlT+_oy#gm|GE-k$$i+mq
z;iujQYklK!!`~ov5WMZ|*GU3IuWMgTyxQdrahj@<Uz9MMLsisVyV(BI$CFNbu+NWG
zujVLx4rWptxDf494?p#N-i}*noaHkgS~1?g+JF(Ef6pmnmX^7;xpkm#N9tThPY=*?
zhe{Sh##6wkj=4Uc2t&Ub)ga=Xrv^njj`u%3s at F;kElM8Y;p9+6&69YZGVTXYr9gyt
z+CL*c9T;eOA<!Q=t)}L4!lOiL9maRSsook*+naBPJjD#P^YGE7XbNBm49F=0^~MkT
z;HymgStS=gDx%Hnzv{N{QPK7$V<bB(mJum9LguNxMyn~cm at tiGfA&st{bh%3<5vpH
zuc5rw9xE{#t6KwNn2YN)-LqIzhI`_?_$OZY>$RC|e*fk018!;Y4#ce<lcV48+FTZ%
zQ95)zPuQpnH9DHY`SI1F)-`T4bQFyL9=Q4~5Br}rY1zH^ez#B6u#;F<XxU(O+do#<
z_ilbQf32FX|NRfh__c9LpHlwYoLAI%54TL;Vj|K9%{k6ajE7|R++&iw=1zZ6fM1Sy
z&-?*r8+e+`Eu|r2#ngn0SJ*r=WVO*>8NC2H3-1hwq|;u~e}+BD@$~;kT{#?5C)j8l
z_QZFMTAm<#MB_g*ew$wAc(uJ%yf^1vxH*ln1aL@{q0)O?zY3R*@W>4u_u-W}^-`r-
zb<e6Ls2%8Dr3?FzJhKM|4PM~Nn48dRknm3pM>0fOQ)5+oeLB!{lp*5j!5=XZ0?&2#
zJW-}<r(|FYD6Ddu)<?O>h=LHFb- at ECacmX!f_tw$?v8R(cc#)rmtJ1tgd2Pgwa|t|
zjBQ9*5hHNEDvNUnpMU_!?!EujQL+4JmJM1bAou6w8$IA*syk*iP=v}6V=N3K?E|5x
zW}A`D<4sJ|EOAcbT^Wy4!wm^G?5Y>z_CBAy5&3K<OT=8?-ZWc@?C1 at _p%_h8LC%wq
z<avK0)%uUMz-MaDt2RFVsn4f9)bKONwDS;2vl0%f+M)F5FL(bDUDwsV6N})}X|lzL
zF1dimrtiUQb>Tyv&>&V%@vY6QW$5?6?c_LJ?I*cvwh4t2_c7WxzyDaQ=IE|OT3z(5
z9xkk(2jj{K2y430_;wZbN<;O3ic(Yuq1_#*`PVfhVwY$w>ioCCWZNHE=7bg>>ixcS
zvx{~CVE9TtJgLL)>agVRkjJkouR5rq{Sxu3&zZ#8O*-!S0PGpx`aOMob)H9Q8y9um
zk2BZuUTzj~=F;S~dRZ+(A}Z)#5Q;A=C_TZ^f%$(?Yuh6yl#roW{8q>T30{$VY?oZp
zaCt3ufLy=dteJ1#ecw?c at y4GPkLI7$D<0ld;WwY9Y=O at YxW0Wze%W8 at eskBj#wmF&
zGb}dgyocP?F~fl(zNa`Eaq6yzPh$%tRd_9&u*x-oF)Ij*8>D2!8lL`V;Gz1IOZG>3
z at _k!_4bt$g_OVtc-U>}3^N&iacq*r_SXAXXa8JszLoT9BJ~nsxM#WcYi?#xe35+iW
zDrusT)fQ1s7@)%pvp|UifQu#9K2q<m at qqlZGq?y}kJ&7`9x at L9{ep@>Cu8}JF9-1A
z at vIxkc{OAH+okctYi3y-K6?g6nGH?DinKoYiW7OpJUp%#Y_Vx82nTRK!3|j3Ng!GA
z8n;*+vBH;(DW5*)>|hiXd|h*UIwRGzNX5I<!}a6chBj+sq7poBxiQBZ-x|Nd%ZSm?
zoS2<QwaDKET%X!2^6TIdU$Gl*lu{+064|%PYmIH<i~)wMMA{4DgTRNCthm at 3ib{|~
zVOf><TrBk{yZ+Fn{i^RcO)NG)`0A*iYq at cy@=5<$`fRE(CHqvG6m}uKz-q_jYyL?Q
z*2Y4s%K=6_+O at KC$86=$(OWyf2H~EC_!H(g_EIyS at eU64eCLj)hpUl60v05GcbGmw
zhQ~-0EEqRfoWU+(RNDeX?{+x+(9LTiY-O~5f6?>RIu1Q&M}JfNTrVWoNBtG*j%hg8
z2C4z)AJ?Sune0z^mhcSs at re5-#b at cC(r=sW1%1kBDEeqTCXAipst)W8)Uyg9Uri1+
z9-xt#p+o8Uzt at RPRkLrd!1C(u;v{An|AvLRQbA86$zQZSk^kWjPE(ZZhm17y@;p^L
zbGbrJ3xUp#8S4qrCZAa5x~meGLIXb$_R3b}_*BQ0ecrtZa?qIpV`@%YE2=NZsA(YT
z_GRxCMPqsrT!&*uH`67{B4!po?7~qfl&Kv)+Pq4Iq|1wEuDG_&)e-sas7U0Xg)k4B
zD>xx=7>Lu;C`uK!_!goK8Oet at r5fsz`1}wR+;=M2b%q~~<`Iow&ecyHmx2kzldGGr
zTl{8tr*AawB2(lH`@VXq(6>7=z;G?7Gxy$m;ZR}mbSwRF_EsJ4+C7j%c4N2)jB?2U
z?V{^c*TfmCd6Qtmv4&HtdDP7>O8+d;HHI$D0A2QH at Z@P#3%pUog}Z+|QeOXZFlpuB
z;noZcW{Cu|rP54C-u;zz<qF?bWPhrXDvY#6xojjoEH}3aiE`-Ha8sG<uJQAN)FiX{
z<0k%|n9;P^-1=;GR&aOt+OB5Fy~saYDlMGf8 at EXa91R(Ae;nHwE~fiGa`_z70TE33
zTyVIu9+#N5C34;hQoat!)urZBEmFN9-Hv$CQcz{}BUgqjvCkPVA-Uxc;)}2syvE4?
z45wfi$@n7TP2;7j^u5miZX!V55*2It67d6t{VYsz%$-!p>xhIycTA8ZkY<9^yEVrC
zYG0q5bD`<aFOefV$Lxmcg=7UMq6$IYxd!(?ckXc=VRRATu_zzwJrZI4%-A#h3iq at 2
zE{MUDoV9Ld at B55B?QS2ESIB=~50&6$X9iSOTp09AFF76FrWYlDhTK at dU6b%`xSq~C
z<Z3qhoJWL!Y2U at OZ{K^{|16iYqjvwB;9Qa5SX*ZD^?rP_ChjnQ6a9i)YWbgCYssOK
zd`ZM#z{sUbp6Kw_)7ga!X#J|6a7cPETHG>Ys_q!h)bGmS1w}02gU;2e%T{<(6wcqu
zoAWRZQ1fWv3>ZRDxL{*up+=9Ia*|KYFyT_p?Dm=HESVgCglm((EAn}zm$~n7flR~p
zD`p?us<YPM`0dtb`<MIE;p-h9)m!!~iW&?7+NyeJ?wQ`BNg<0`lG9kD{cblru!WwW
zahUCrk2tTbRC4bJ-X|YPeb=<1CL|ww<Q6SX_#t~NgRa!+>El7~(y1&O?FGP-qtVn<
zS|;OPJ``(<e)fIdcGLC&7h09 at Q=>XQwmyUTowFOXieV{PipnhP`BB4=Np- at ArIke3
zcPBV6qCaArz~w>vXZ(J!*xQh|k;TWu6%Tm|S9lfj+GR}Nj)GwBj>O6!{>fN~@F&HY
zy?Uoz>2LI8TdKmu4tU;Fub&$o)KjasK7})o$y#?oIzRn!U>{oV8v1V^xDxcj)i*4#
z5bX48^yJPsB;ko>IgFHl65&QDv|tu6V*$XR#0d3`P?1%ivp0EompbKJy4)@{C45?%
zWQZ5TSH$?j>(5pXo(wWf;Viz^1u?^b>RN|tc)-?bO0w`P4-IiX?h8Fqld=5Fzx_S;
z)UCjQQ=tam6TIpV@)>G*bsMnTCN&o}<AN*-GC66U?BS$R-~feFPAV&sXMmnDvreu`
zRtp6>leuttg1(m!ud;`A4)4E?t8Vf2_X=BXT{|8CM4CnL`;;p3c^XaPYcPRWs<pK$
z at xiM;KF<{7<F1Gd>;cf%O}vT4Zj`6TFX<6yw=m!1Rhk>Cx|3MQZu_{}*!vC3KO7NH
z(qFF6>(RPm91iAYdyu!O#R!<{(^<st*tg5sf at ebK-Uxd>laAt@?X1e?<wFZ4%eUe^
z9dpD at eX_Rxb?uF(rqlfH8#&ZAu11GxgtO$TQ~l0EKVQwnh1!OFfBt5#f=}S$4m_n_
zmt}pwZU!pMUY~5eeL?%gZSZFOIgRcLuta~hf-CcDrrqzt1{0wC&yhvX{1u#bu~t}d
zZ-vOxHKpp9J-4f~XRwmH^nNL)td|EdrS2>9qXt-FFM?jjldp@^FUYV4OeB4!V^)9c
zEd1S9x6`1WEvhwoh~Azvu}(pb47C#8({E4P)LxgbvAfGoOfN>rMCE**DT4^<k_WKo
z8n8FgPxiHg+ACDr<Y0q5!OFfLV5!dIG16xzhc90J7d2=(7<`-aIdVHMPnvx=?Mh1R
z0qKy$Jss9Y)mNLHV<Az>42 at R)D)CG~%+6k<H_SSoYvgE}vEg6o@&ZpKe#DgHZU#1`
ze>6U?@a2}d$$;g`525)qLsu1ly|>2?O$=Erbc=opq_sbnk-jA;p?2DPM>2yu+Xg)&
z7`C+yG1dzcoSUY92G;qQz9 at 82x98$6r+$$Y_a;#>M%AJ4+hmz-i+?#26Vsx`O-^$*
z6GN>*CPmW(W7_^F^Y5p+T3hGU5%OQjS;pe8FP0bJtHRV|vpzP+)^&!B;_CoJjVh#X
zoE0xMra7~G{>wT`cA;n)$a-daf=#WuBvjh=zf9X8mND2_%;^Lb-5;!&SpE at g`@rDe
zxx95CjTiFS$%MP(MKf1GeW)aTxoQ-7okb*g at eP6w(S|U^D{Rnyt>M~$qVcma?`6IG
z$O-V;5w~V#n>$f|eo(2l>(6uFB=b+!kcB_`c<jBTkd0T9Z{=BK9Wpt+XZ6m+ui8~I
zINzsNRLqhp3NkBXtO!vPQ>9`7NlOGo<Z~>10-KaNkP4j=@awsx{Ki&-|6ZTs>HFFg
zXk at C*uT{<dMdcjuZc?(ahgM~F;P}3K{4_#*+weCd-yE6-beoEyXBC81<;7N_JJ}#9
z(ei5L<cpU1w0Y<B<1nCa{I&d7b>_YKzlf#}Z2g~<zJCD?6bH~jzKn|R{I at xCT1lSb
zT=t%JB8#@OA|2<%kIX4SCy!_(l6Gi3*s{^TnkR;Ygc;Ay<{3vubU9Lw+sDRtOXrN&
zg<hXMWJ)p=imyuEA^!Z=MZzpxi70EiI^tyPC+HO<QQ`dFetBWZd4(>KxRKa*dBXK*
zlI*`C<oVBI!Oq~WIR8(VX-LkD?jab^8JLESBw+Ts)JTkA5v>VbB!C&Rgm3-D_ZFPc
zj~JjXP0IK_-5xdczj_Jh*WwhI{8H`yp7#eo0Q8l+CCkjg at i&HRkazm6_I`4wv9 at 8B
z=yT!E^WCbJmUW-8lV~^Im&k at r;pSXfmbh+l>9P*oIGp6Rb3IgG1bnFR98|N!_Wp?C
zT88)|4ovB<-Pk8Q(Qw*&Jmer-SY(bdMkJ0skd!$#<9SFz=3Ub`zGUL;`mNeb3rw|{
z9IOEWJ!q<}uZ0rxCAWC<kuf(Z{>}G9zYL%0tpRYXiSL at gSG-|8RsH!0HlMW()yEEm
z)eAoyRFk+0R>lyC4oO<<onAFT7rSL#9k@}I<%=Hu1ZJGYQFg;7g~YrAEjk9Fe|V_a
z7nJ872V3FPu+N!F$O_2^3W3`W2Dn#IvrbuQAu-|a2g~Kd7d>8|2|PDm7y?8JwvpO}
z{h0li&AhPK#8o#r<>aOj4XR02;0*s^t9|-Y0r(`U1jzNliwVlk=jhD-Hp9npecGyO
zvix{9yXE}S*6l|i;+~_xMk^xwm+GQ{Vl#TW+~^4VOA|6)k};^SE5BaH#GKNZuQ9mp
zqy`(;@VGPBGD{iCfr3%9pK3d9W}!`UjykU*lXt+Y8ndAKIzI>MN#U6_J8I3XO5AyN
zsLVTLW+$x!+ESawFU`mZ>vQ64`|<y^0DV{wpg?=ye_X}>-w}x9t#vdqRFKLD|4n))
z{aFjfuzftEtFBJ1o<CFQUm6nlboRa3qwuK2#7;`;xlF+c!<AFGs#engXsrYu7+81k
zu<cnDSuBB9G*#o=ejs~^)^clm<E+u8M#Q7S=kX4`_d%32?^{3C(J^rDuiQLkS+Q^S
zxBkO%E}Lw7(x^v!)LlGg=D%O|y*7rC5l8d>hpSOw0IzjFFRrDfa);GZMz3aR+s75E
z-!v$j9QnJ at 3!7 at yI%v)?T<2vAqTY5nN>E9#4^Sl;+8m at W@OV#zm)gIW?P}68=l6te
zBqm&|++}Se?wYQ>y*ui&THz=5kQk}N7sVy5Hbq?TJo-i}ep at D|C+Y+jUzeb!8{2HD
z?3-2cagd7UO<aZ<Ph~E}`ie^<1^H3Y+8O7hL`{HK%tyc`cw$uE3DbmVepkV{&D-Pm
ziHQ2qfz56iaJd0KD>ftD)v_S$kYteb6!{r{;OctH>RqKVT3P^2Py!h;$M-P2poFq{
z<kR70ff)2W#0=@0tJ=Fd_<B0!riyEa_exw0TM<n>zEoM9b5KDV1E3NxAsiG_cfozQ
z*jX|<SgEJ|LZHYN2cZn{&YU+e&O7A<F~{e8{cGYsM*wOYS*n^`dPB4>oJd9aYwZ(c
zF2XL^R#-WpGEb}(WNRFQe&>6yaXftDD at EE4%Pme!@+%b>;w-_X;Z#(Y{0$ULIy*;u
z6gynYHjqXO=AF>68*J#Neo96m>rk67=i+W2gXbBev;C2GA%1ifR)UFm?u38(Sg;lu
zG}}ZDZN{+%9#I;A(|CQR>AY~&p!}ER7*7hUw0MmSE)O${#*61Me;Rz5ZM5$6MoQg4
zXcW>va$owNhE at 1V>-U2n2PW+U_wc&=E5Z*&@#Ss(;SU%|QhXneeOlX4 at 8am9MIZ=Z
zUPfcznDZ^Ybi&_|Ff6Qpu?jZlzZjWU418P at ydAaHP?Nn1$P at 8J@ov$XuYCDnmud7+
zGL1`v2RXBevh|j|#Hp at t+}<zHsfB#B3Ss;eaSckXh<Rn?F3#^oTonspeC2I_{+9X$
zNaeMP)Ct(l(O9Uee2bg})^Oso6<`^j4>C^|HZ)BlIG?iRjLQ32ZSGq^bo|#Pj%iEQ
z;Wxa!VTF$}Z-T^H(ic#^)j3mTU=^C!9hb8eD!~U{Xe=5Bbb;iALOfSbO>}<`)-`MI
z&>aThS{LhY9QxoM=7F~URX-rJ2VOS`xDlgI=d|iyCGV8i4JY4GIHo0jlpbTLpgU83
zkm=Mw#0x^Fh8HhHyA_nTc<P3)JBFwn>`R_~HO5m>lb7DCeI2xZO$v2rm6nn+vfgrb
z^Rub!kLQtq$U0e2&XNwzJ{@GMCAPx^LZ;x_qb(j`&Mdm+XP;BvzIfQ*sgVB_^rrV=
zz}bU at RsWn+-gOD`;nG at 9h_`%9famPbuV)zDT^pQ|)D6cgNKbU8v`woS`vstREVgg4
zm_1`x<J%NJ0F-bJg<g>kLFKvf5z>XY27Xm+%|KXAX4l2KWv?~ExQNLL3~RG>g{uHF
zd>4W?%x&K2mARS+j^&)T&p*`j$w>T3&1JXh<6=9rD}(a2UhAn#N`-fj$Ww+L at md|J
zpVgzZKd!J%!Tqc~yjO*5NQR`0sONn~0$Q%+4rc&qeth`Ai}z9D-WmkfPA+!`z?odr
z!)ao6F+SCB9atl*+Ni=9A644bGC4!tctEJ1I3-_bYbs;u6POZ0J)nnrL at F-*c4;_c
zdFg`efmO)J^><(EIg2z+;k4Au<yGe`n1aGqjW9gDVXgs-3wv55iTF<EDC)x5c4|V}
zHcRr}F3aIqePI}`cbG1?>QL!;R4B~;*Lc?+q#L6ml5`YX{pVvW)n1XU3xeOvXhx8S
zXpeI`iqOEt+y?0rm=2z{k&KAZ6W;*qvo+&gXC{WO(Bn%;z2ppdH9g)yquF8uo^hmj
z2}n!#Z)z9neaO6DlzoqnrqP#0U9TRY_)=1^`)6rR?m3_H`=dKDyl1Adkf*>Ff3v9v
z##LIgG;1^(`INY_Z=PLidlu?Otz`YH=Om^8BtJdKW->;@s>`A>F1&m|t_82C?xkFW
zJp&C_TIs{lC!tV)pWJ8`RkK$7)-z!dKQeA58^Z$QJ9eMx;uswHWNxca%nS4yTF<Om
z;+zpb6t}<5)+}uo(GVY5zXEKD$#E7mj57G>{Yd>*I=~5$@#J#dWr=Wuriv&x1QZO@
zSnibb<UG0{*e4M5<8e|mp;adVeNDKype8eN=dxXF|3FkLZvL_cLy}US%>G(~bv?Tg
zeSe~DkKf35ODKsb29LnFiVptZ;2yRW<H<fK%=~m{v27y94BH?aVU!=4*Z#zRF4vx)
z3*or6{7|2=Jc1e$9_^poszSr<Si~wm%W3YeXar4EXeD;LVG9(6t|D;?2<w9JN46wf
zD>Ww;BwU`P(Bc=<mJrwlzum!d(DU2|v&#_<!(*p?{z>eiDDIQ{9>2+^F_aehD*3{b
zOL$+LEw$-%JIM0bNN%k2jfH#H4S1I40UTFya+-_ki4r+T-4!ask|Ym!9!~l;FiXZr
zkvlKUpC4{5R6p&Y?2FcE#L$y3ax{`JnJh7v9;eHA0h3_5hOdcbW~3YEcm)>snrv&k
z{O*^39s_xLYUoOhb6KY-uuNuKTpoB8EG_+=Fr0EA!Vm}jmTX#mZ`&7rOm|vzvS6s)
z-5+s(pL)l{@PWk_-qa>D!<5C at GU61@`oXQ&ILSLur%C+m4oNVP6EU`rY*8+^AQR^o
zA>6dhks=f~x`8TxpM?X6<od%qh9$MFEbx7o6P7i{V%Gz)Snxl8mL+;ms)n{o-RMVO
zX+LT_Yc8&*9_wvXtM}-vG<$asWT9!7Rl=^3aCO}a!Wu%I4V6joCrG|Ua91zVI1d}M
zGi(tVZZdZ;^Q*;!@PhDE2R}1aA5%F>^3imoGE#Y<J`izE?bNh=<61$O#Q at F)_2mPt
z90j2 at U*19TK4Z?cl=4P59U!NjcA^)-Y1$%1-AcZ%t!>8oJ#dX&2BsjcVPdRpyQya$
zf;$X(dSi at Rw!!Y3G_5N1iPaa=s$Cb(;X>iV&}>VZX$>vHWJ~s7<xl<F*B!b$f7efS
zRcaL!8QZkTe62~2K8>ah+_7XTV$Su7rUIpL0twYuU0-xs!dKi&A-dTHc3I@#s3pWw
z$PW`KM0w<Nf?3E+HEc36wzHpx{>|Jh8~kGL=Qr||#rwU1q7h-^BbXLwZiN1?L06;v
zqCbkwNtzE}(zI!i2i=<2`)ufTcr0}wG2qSpJ7v71R+>E=^n~Y+<XZwgkK={K80{2?
zn#O<Mu8xU02qA`8KfKx5D9#vLMq2BD9MNiACObjyDkNe&&J>qk6T8D1sfcK#Y?a{b
zmE}Y)44yDflJsr{&p<*6eF<uGbBP*DoX+F-i at kwtrL@TbZ^eIdnXoPk5PG7FYg$eT
z9ao3$d(|9X=Hpa+VQ3BXRx~@i7)ypWU;0*l&iK&j0i%II7m(gdLsZVV6>EWb9 at mY?
zI4*Siw4+y7zN&W3GnYHd)Hg!{Lc3Ejjm|UW%r18$;(~R~F4Y7Zd~SrEXz&QaDEFOR
zo{!&uZe$S`lHL;V4&2~r|E5AUQ7YlEA6kPlP2OO3_Wx6JoQ{@jaE63e+*2g?oJuD9
z<{hG^u%>(L&(>4Gbme3LeNVIV8(4C6tnbesT0U<f?UgOcw8}M6CSH&aQ2UR|PP@)(
zD~IOTZp&!7DI=tdZm#gB_D={JTvhWHrTYkuyNBJW&Oy5d`YsUh?hLP06@$vH4kN-s
zb53u4^QJ9c*-x+!;F!mH5e at +ULA8b<U9ASI8}>^7d)(7Me`@lE;i~b6-K*S{9<tSR
zWSUW31kB(fu$02#tff at q)AW34f3KztP8d&_GYoYB7Or`$tjnP_P`K at V*aSmyM0HpN
zgD9v~^+wL+#no$1Bj(`-UvX`KVYu6BrTXFe5we9GadkYL=ACk>LaYKW^IQk}4huJ(
z$bU`1*aTKR?bP$+NVy-#^faF1vsjoVZ?1MwVy5?;!pXM4eNto+=rEZaAvfU#3op{E
zobK!N-I)I^<6{2Pw<*XD-D^neIx6B4UgY;ZyOR^#NStg-zV|@Yw-KV%8f52I at OXO;
zqh8-p+tyI@!F|yd6Dup^*;s*aJM1G@{YMOuOo7I~Xh(J+f`PRY%s;***n4uxn<ur^
z>1O+#&jD<nZt4g9b-Pf9Hc@{%$n)+NkAviFz~+|jk&m9x7EA~kggmBV?|;|ScDgB{
zT>?Vm<PF{#7CVbdxxMMO(M{1-`eM5a=~FNNj<|nE+|m@#S#ufw!1+#4yfK9l_MVFh
zy>ZV;FVdooyEFAcdmrUL0AykBS0H{~HU|y=WvLAvMi^Y5S at V+hbjo+bqTc^06Y-hR
zvoAMPX+GvrvLPyobE(n~bPn&D?>3xUm2q*?S6Q-;cV6UN(X(z$dC4d at XB@`cs_D>C
zw$nRAcIJOUQ)RV7x9Lh%*l#oxQD1qU4}uDX?z%zJ#T;v$Jr$S#;<%?#lZJyx(>o7%
zAw_p_>Vf?)zRDV3_wASK^e!6JKmG29JnH1UPoHRjZ#2Ictt?ivoRBTLvJcU%scy at p
zRQJa?FSZHaO%Q%%Gi!D4g$wEFH%GVJ;DPy at A+_y7;{I+5m9Zo+s`Pqb6PG*J@<+RD
zhwkd1s(xn&ehjbRe6hd<X9NP+fDe!>z&UMM>Z6;1wJVU?HcvfMnRPmW)-S>X>6~&E
z*-fH1Q^6OSHDl#xR4l4~LTLj&fJ#aD$#Q(06!}~(vD~3C=#Y!pv#-Jr2j4E5SO{v0
z8Ygg)8*Y143IP#2=JBkWZhmpY;J3=NE+xPaJn!sd^&U88Odd9WR_7sBS72-8+Too$
zajY?k|LpEcWtGw{l-3(DLCCYuO<B!;RW9#5*zYDB5tz@;x?en(&AEN#f@@*Y0|G;j
zhUftA_UBvXmc&WCytnCWSQ~MSXIfu(z$Rc7UJK)S(z4C1x=`LgyC7c7YKaLX at q@%K
zU`ok-zx%-4FjaIZkEl`Hm3jgE=FK7GlggmkEg at XQoS18%)miT3uoFnX+0L3`(MPFc
zy&O5BN|+<9AL8^UEl?^2tb;C9T_Y#~3a&X+J&AxhcX!~3hMd|W-;7&A`RN6A_iI-%
zE=vZwX6(o5({O4n at z-7jMqeov^0*Dr`Z8Z;ep5^QKIspj3te~}<j19#2ZgtMtmWJd
zA71Tz`_eJYQ{V at 5IwDkzFIQ>ZP*?sRPTiQ{TYPilMh&0`mVf-oF$(Posdh)pBg4^I
zS1zIsgP(z49i9T4hu-Igd*FqMd>(zM at ujzf#P-h{fh0;QKE5$&d6kbdHsQ~!C?F5P
zu9Hh{d>_c`=TRW03Tz$F!L^v!UiY}c3{{tc<2r3~huq-u&}V|!%Kf(r{h<|KnhttP
zE}i#fa at ZD+=6}v~N8HFc5G)q*9gH2ef at IE>*vFY-kKd?eDohbvV*J?NH`jM<dj
zt1)LSHXX2J`b{cDtjwUcmY(bl^G34xei}B^ezMAI>)+ao7h`7od9>e=SZ8%{uOXmU
zi1tsnp3Vo48r&54rYPVYi$vbi(VGAaK?@*lQS)iGfSk!;dN&uksX~p2EaQbG4QS&-
z>tpb&8Uc5J<M<ZcVgrT_Zo+wN#l@=^%P%7?Br^T0S^ijlxD7?ggtfq1KQq8i1#9cd
z$N%Zxp3Pi<YY{dvnbmCh4INP%K*#G4kCudpp0dKFGK7A2C~_nz98Y?!(puU*;Y_vz
z(eoIfv+Yc>-oWPU8~5l|b{tk%+~h2GW|xo6njH1-KiRmENl?;xz_>gmWTYsF&wKET
zUX~|dxd_Q&+ec$@IT39`P3AeW<x8mT8>{^L`>V)4Qj@?SvU{!z$=M at q$Z47}{u0h2
z<ukt4 at _jQ(Y^JHQR)WcD_Z}Nc#)j5<%SdmT`3-c_(+rE1HZ%GSjczV}(KlTkHeMeg
zOE;1~NVSMQzEs<s`aJY)NW<;=jYtTz^swC^_}g~cXCA{F!#cg6>Tx=TRBpJ)D1%!T
z*Qx#Kz}a+YDPPp_<6wu$A2J=7Kyz-jze2z5-(wxQd=KZpF0Eb{Ij31-cE-47%3ouI
zvYOFGTmEyYnWw_?pmPVV55q$GtC=WScZKvy)Vx#V{5MtHK2y|e10ZJIHB at Zz+~XA&
zB{YmsCMrQk0BE3>Xp;b&_l_AKozvXPz+((c-vIJ*kM(|5Hh)h}@gA)-{~rCx(3eK2
zdU^Ly$+jNlKQ?e`L^wXg=aTG|zRVY}7n|^E0cEx-Y;MLk=N@)mF$`?4Zhc@<_&k3N
zNIyn`q%-G_gKLR7-3w11Xw}wI64K(@Nxq&_+Zs7>0O>Npwxf6S9M&C2oz{BI7Wa<g
zoeHqnzs~hq?I+y|eZJJX4gX4o8-nZrT<n!x#!f8WvZl_d(Jdr!J}_jedF2Ps1#NA$
zqxY?TP@?TWU<<r?`cL|c06+nEfc*y5+E&~Ky%47TldSmuL;FIr<Z=r5&h!wR>qBMR
zcV+g#11LFT#)%^z240a3e5BVHzjD-Ytt`AsJ!n6A7YY?U{E3p|<Dk{eM+MxrO%Uc<
zT&vM2m1L4h4K^$rI#~Q}z#DeIG_oMzp30P0DsdmXNDQ(myJ03fRHUv8T(6riPFYH=
z)zsPBe|Fs~x5#PCo+oVvws1*v^E<2X0FPzpITlS5EC3gP^YWa7^+Txp<EW{~?Z+8B
z at 1_;{zNvm4Yx~M4vY_!tfJ&IFdW>t0FgPKniRh1I8s}&&apP+X<EyGjQwRGL1xSDL
zd0MjZ?rsGdNFSfKs&4ylNti3G-_^#kC2EA&?#J2se3fIVN<RHxr_lBKJY5;sD*kcs
zqJnS~H3pG*Ps6$DeGM{}S(0o0S9|TB53H=Qv)4Ugrukp}%kycL>L|uIY>|g8iOg6A
zGF=D~h|4#W|5C|%BdvlIerBRsRrLit$n}HLJ-?(Zf&%~b>t7)G`7o3-)F18k89LSM
zRu10A!TzJnsGR3uc`d?OJW&mAC&Xt^$qhR}tVWaWv)$1<xi?AxvIu|Pb`_JHzR2Me
z&wQc+!RLS?tC8mk3cNoe67odzCkQ+*qPQQw``YM+wp9(Sro-zw{c8YfT)`~w?{E4(
zp>y2ln>KN<UhR$v_w2WUXQ_)JA0wK-0Zk`DS8>|EoAns$10Uc^K67|{EI(ZFvQl%E
zj;0ZH=DwA2y#$D6&lME`a2X46d3?sPjb8i~(spc(NJ&#bb;s0M9>pngiT4mUf7PK>
zDYY<)Fc5$3U{cvKfOBBf5R2Z`d+ZbXvW=xijn4>OtHs8B><Y)}5Lb5MeY$%Yq at 9!s
z8TT%>M{^*RlI=lw^nHyPl?to&1G*phPbwpTJ^h_s#0OyIQSP~AB&R78`yG@}FG6TS
zKf{IWC8Pmd0Y0AcGD*%~LG91g)cifu at Nj$<o#lO8Gj--iLz`NK2fJTh;kcsqZ;`zc
z(omh9VkIi+DvkKJAR>_F;+Um0=DDi;pQI!s_D`b(x2(!_P}=d>ug3)AP#JdCHX?(<
zzxU>S&1-{fjO at 0S-<u$knzb>&sI{Bb?8|b37ox)&?RbhajoaCI9cb`E(ud9>al}Jy
zrnt+F&+Mgo8aJeiQg0R$774 at Zvmc&~amuu;aYfpj_j$j_ExJtc{;m~TzcQM0%F9o|
zKaZ;Z62y?~(#$ZU*GdzkPxE~V!|@1(`d`wlga|k|(972qn1pk|{&q8|@`+OUrpU3C
z#!gVsI at N4CApIkUjbr&*Nqp*Xr6?H#zaC-JY!5z}ePG~#3;fFy<+5+E3LZTjn=Xdt
z=oDFMHKCCERXYiyHWP#JJ4sP6OJL48Z;d)fz>bEcZJEnxoVUiOPKOVwNkmlR`G)z5
zUC^jdm307vB4|Lj at x^2iC8qLnHx`5N?jtEaVl?CppPW=%Jj|U{*Oy1^fxAEORO-=|
z7q8Q`-Y@%2<Mg0 at RS(0?=UXc&GEBYVJe#lGmws(>Qtj$$QXcvvbSG=~)JvQc8lko~
zVd>b?q3suxM{UtWWG5vNnV!SG{Bh`=l)j`)G~N$D`;9_3q6sCIf`%q?Jq6X@&=*#O
z+6jDoQqP!us^)(u(s}8E%{kzDZ*G&E&uFGHVS#@ALAwsuFdTe?2dvYJI~RNn2lpTs
z)AUr3LLapU-?0t12 at KH?%O(Fs1I>P!D|K_`i1l~|Q)@24V at RQrK&5w2VvLi7s993(
z&zR{<x)uT|5qD_l%lZ3-S7x^+zTFitus=9^!b~PJR=?#R$aQJmw#v-wUM2Pme<pgf
zillX!Q?!+o8%OT>(Y}fg{YxVOwcL at 1w)t;AE0Hrgv0x8f2}rHx{j6o;>AG+{t6qD#
z{N+>~r?GYGYGWG~>V`Rtd0K{Y`_9>#VjdJ$$Qd)_w15aS2p%wZbk{8N&GK2{OC2b?
zsF{ES<Mf0hQunpk)n4 at j$in?9Cn|{CB9YAGKzjT|8JJsXmt!+O>!*MSQ^1qD`(+=m
z<Q2gR-S2-L_Db at 7Ts5FFpwa_%zkX!$WC#!_@`rzdVsGs_b%2&!ty46_<aZXoDb~-|
zsoThluX$=NoA3b~*yKg+A>hKzr78}vWy}_iXk;jms(0uUx^hIgjS>nRuRPq>FE>ar
zN`w0`BXty=bUrLsha;US%1<j9+qL{sDwEZdo?LVuh_e^MPn~fxJs<XP(GCMT6k9m5
z?FWD+eYn-$7Y$2pTe^jNQ at j{Gq5exD!AB!M_AT_;IYZNTTyJs5C}MG%IL<f%UG-A$
zC`HEix?nHYD-+#LV(p2rLpFzT>6?~(>E_-q&d{55Ye-e{GD+K{^CuQh4Q6}j&%ppt
zL-Xf6_wQRGo%*}@Z}6c%Nvnub?o at OFF4+ku!bU6MjXSj#P;@+&+GOSKIJ;Gvhw}`2
zvgy(j<h&}^d^j$Gxs87DrQ|<K;*xFqw7~P9DfU8HQR-mO;XDO%klrJuJ$4Utgrp23
z!E|`NRDwfgJLcrEDOZ-M^ueC>FcpQZeujIX6{G2*obWx#4kOCvSsEiSZE~2naIWAQ
zTw>=mWMS(^c at px_hRI_@zAs8eslZ<}W1}wb6(3T1DIfmlRiU*>5R;m&oXV~}3Wl6T
z?rWCB9!^`Ft#Ub`vtC6_%5O^ud08GP|8v|5QGP?+?1UYVSDF!k{T$jfS$#;OS at NeW
z$pKAp?yI!7Z?#KR`k~^*C7K-ziXaF#o#9#R>G3IPHJRDN at h^Vusg?e1Jn9S7edJAI
zww4W2X+KLFY%3tSZj-142(s_zr0O%$lJRENsEPxZ{J@!s;G?R~YHOO^q~X8k#TN84
z9<fe)uK3UJu<umd`_%nX(9FRyqc-0dH;i`ElUeW06P$&b>#F;eLeii(^jhYdm`-#K
z++hs_2mx>c1T!vd#QA~4y4-*o%+A)q;K`pS-b3ZxA2H=<hPBl9$bEL(DU}}8-h0F^
zpr2-%>Y}W$2Gjk-dO7m)pwpMhLg4t}mfUTnwEAWrk=0Ll<35d;*`_9P`y&@^CEjpG
z(}HXHRGr6f-p7wdtxQBe|35UHby$;s*u`xLl?D|>x?yyqGC>-N(J-XD25i(olu0W+
zT9EF}5jsK|q#KFRZ1iZ}{oeO_|KGK1yPoa)+|PZ^`5cgc2Q!FxdG|~fRaA<onh8x9
z)z0Evi75!XdX4K&=NiXKY1y~$CbwBwH`W9C{V)~|S(z#2FOs^d;S0hTTs^tAm at znj
zhCP*jCZ{e>LQ+ at -N&*w8bZg%1<XxLrpz5oqYYH(SpZ(J3zMrWoMPTU16*)U8Zc$c=
zgi?_<#9V+!j%w(0cJ72H-w-Ot8JdRBAB(D8wArTzG at 2;?e4|sH0V~?9sEbzz{bI}&
zcD^EH#3$9Z(X>22OaioWU*QiOqFkMKhzf*QPo`qdKF_h=u|TVa;&NPGB53?oCy>D<
z*^DtCp7iHY67E7=#v`kkjqbS)v{lQzC22aAUODkWBX{iSg04Xos$~%)QWPh#f3BXw
z?^H=34YvGeNPEm*S=-1M7Hgc)1$9naEzIMPgJ0OJD-mfv7F0zaLHJI*l at rp%dahL`
z5aTo-06}AYA1K1EZV2el8-DvHx6xRSNfQIQrafK`A&tp;s0FgTuxmV?@(yd(y!R?-
zS*W8#YwN_6)PSu!N*tA+wlPLNT8Jj#PMj?U)h94eVqx%Y?2G}C^AOpye=~;vied{2
zz72d~ThWOh!7FEMTWc4W)b|=<Q#%hzuO at 6@E;LK4?gd2a$w#KU>&A?e8{^n2swvqU
z_Kv7=ok{9vjJz)URtqW`--BBx4K$Cre5z=jzcf8BPy0n(w at y7848u)$TW0;-uNwHm
ztio%xHE&h5`?7qxk;*1tSJgmaNX at 54M_W?F&vk at SZ4J}k04ORM_j9 at UiBD2`N$(rZ
z)^j*)yEc7q>auVT(zt|tlfCDr at RFcC?wJPYcFxlLgUsrd%r{}DBWwFUqy?CLT@(}R
z9j7jG$g&JV`Kee9Er;RL!W*2sX at Gn;(|$$!Yo$qrN9N;&i6uOE@$5>t{qdQf9KoAQ
zhWqbLUly8Z$359AaxsAvAW>H$m8Nb9za4g}895)RSX8p;hqbGmO8L@&HHAyeCumdz
zBpEaysiu*eZt>C^2_N`HcF^0ZQ(HBTj at 3C%Jq<nAlt23_?CDU?j~^&YC&m39cP9iQ
z{Z4+<TwYPCz=rWJx3ybq{U#n8WlrZ>J*-|eLiM3cSiMwbupKt{*G>!+*HoL-1Rh=q
zX&NwY!z+H2Q<vm)f2&2h6+u8Dc#Yt+7g)&GUbpuD_X2=0ipoQMG!2)G99~^<yQ!w1
z2+M at 81ltVLC?hPnVfT)<U at rO3(huf=%XOp)rMJEk>UraQ0X?e2%6`aD&GF6=IDWZ`
zZQbPq{Xa7^v&HUO_6u+q`p173UvY-8OBT{%$p-yIRPc%D6W))opj{V=MDdMeO0=|&
zbR0DQY8I-rO}xei?q13$jf%T^Eh#|==v|-)ety|s%kdJl7JQ3;iF=#cBLWdGR7lLU
zZEQ_fI!Xr?autl0=7%Kw(B-SS<MF<8JXs%|BcFb!EuWY&{Fd1kT{&mFXvnqW5|zB0
zT$CXhG%u at 143_lKkVULcOW3=Ye~-LupHU_H;}3_!`@YY?M90Ni?K`+d29$r2bFw9h
z%kh7(a@@`-BQDH~hMqV(b(2wcp^n9$1rlB_ at JK(=uM$pfo0~r{-)|QGw3XT;SHXLd
z_W at D_d(T_l?d+XnNrP*A#^T}vO4HjKF_N;Adw)lbi0SI`?67BFG^3{l at +lME@s*gw
zifFeja`pJ%bk0y$m-SODHALOPLs+(gI!tq;$9t)zYVGqSlew4kYnjvj9i-HO8M(-2
z)u>LGnPAFRj&#+m&B7OK<|Lml()drrvSVjWs;8c{9dVjYlvm2h#q8z*q$RDU^NCpw
zmYb2r=;XhZ>CO7h<&TgsW#XS`tpCaVJzwzYAvgdS>MQ9xT|S%r^pjgC6y4FTN6}eX
zZQ69 at Dpx`fa%I&gV0%pfwMU7XzDcbCSLeSfDZVrXuD5dC+lYnL8MFKbaqRligY=A<
z?pkx{cbJ0NP;+(pojCxl=XIx_zqK?sH(v#yB#}oy=gsr0ctA4Z7gyV$Lf|U3PF65l
zkW|;1NyH!xsgH at PuS3FqkrB-ASi-uCqrT|1pdUj*3v>;!kRl<n1Y*qbz5!a-<5n*?
zH7w{fh`#G+=id<npYS`U*}XO~#1TYr=?E@;wak5uXD0AxCaD>Q<{c4q2X9ZDRKDpA
z9zkZn?ksJJGHv^7L;j^}^Pqx1qMLE$4No>Gk)lzTCIuxIdWJZ*IUbeWNZfS2{;E`H
zxLYsx*}@^VBUf{xbSQ7Vi=G&>AWX=e`4N)A`Ste*k6tuf?T5uXwI~IzqJuAKMg|qd
zCAGwrT|<7~kBtPGL~jHa3|O07dsPn^s(Na^rXv#L<T$#Yzmh7gqQ`nRqj^(?ec7E=
zdcNx&G*hKwY<{w at hD~wK2Ubf546VOxhUaoBST<Jb0jMLwdOPWHiN>wX%`$KM=EP}U
z?N2*3 at g<5TizlYg^DpqepVrh-d&_V4xDBu|J^1&{&DqdHKVpyIGYef-N1T172{CNQ
zsWD?MQS3ARkeRe=0CLA^Wi?!JR-9gGY*OV|o!(|`gsf9dG^>*xCa1pE!YCz{sARCh
z5SM4M07&<W+l`e-Z!n07nAQ9IA+mrj`26DFi^(wX(+<&w*nDAdm|{Y`nAiz|uu9gk
ziP3wNd^J>g_&(qFC_XxXYiX)<D at P+YErO%!n<A6Ufgh;&08*^@eg3DHvOlgUT+*n;
z|5Y#9R&~8Fwv{I>>(sz~cF2m0r>*3DGoi8!XuuFE6I+ at dCjkgO2<dpBZ`cRVCP!Ce
zEBKfEaLcwFNF(K84I18H5L#P7i_XIw22T8<=J46ru<wmyb5c$6QzBdP_dH0sok|@Q
z>CE%tOG0AL)zO%6&1l%PCaQmG>cVL<MD at 6787mt*R<AD+l5`Nes?t|V_eHksm)0TA
zQaovprSg at dRX_zPd#Wea%O6M9TKB8OxMGLA-Q~9LTJk2w?*_xdMj3m71&GaFs=_7^
z+rW=7rFaj0t02nX7`^19F{1G`AU#WpQ6HeGK?l7iQkzKH)X_$wd at M!b3-tj{3GlFL
zl at -{&FL1ytAl~8_juvS2CcAo0#s}qE5}axhrP*?Z?&v-FmVO+uV>Y;emCP~+j;{7V
zcjGsmo2MiThCk!u{ktOWHZwcl at cdB#AtXOlHeA|jJu8DVg at ngVIn@X<zv*t)4T!n%
zOWg7MFfHT8tn;MOwrkF9n~{3luYazXL3Wl7fr;WME&yQ?Y8N=uMpE9{rF^!8v^(#;
zCb~uRx3QUcEuK&D{rHnyE8`6!3d-;6i~94ubZZS08c2EzlZP*RcNu2GjK=vMfJXlE
z|8cC at nwqv9Z#<c<uIGkPI|yMhzKtg;M5FstF41d&yLAnQ$Rkc?AGXM{sB~`e;tTZR
zdbM+n1HL2J^VFDhXSYwa&N%m_I$J^_!FpAQZZ!@I=nSS?u?N~CaRk(*_bC=l;SV+U
zV2|9c>sI&9vs-Q at 0F`R_&h%<!IY<uF9_V|oRc1H-Q1~}d^feiy=bU2IT=3(MRN|M|
z8QGI*DNIdVZC{`*BuER5>TL7A?#r6LGmTae{1jW4t^(Tlg*TFftwbq|XUyAfdp5ro
z3Qr&md at jb*s*@vF&wOU+CdtbDId&R9{X<!Yep~O-&!+2809>%6TV~tSn31e9Pd3R1
z`<<s{E>c83UEy(VI+gyog`0DCc at b7i1o~w$aNE2Js7qSxu}d9PvEAn9q^!I$KA1MT
z4d)-L6T46IuL0ZW3z0o6ouRINku0jG(yLcm2zI5M(N&%s;sx*elj at 3Q?4;4<p)TK#
zKs%ND<<ul*IrVlm#s%p)MDM|7nwfXGH36;W0}+7kpTva);lJ0M{JW)#qd(uFZ^=)q
zf`%JCanmJt>~F5smeZCGBl$)fB&NqbT0UuvNqu=sVn9s%NNu;@rPp4#n(Af#qDC|i
zqWt*lzLGm7M-1x5xhjDJ_5Q6E9nH~S^v4^S0(-}=KTCoW4RxlvOJ~w6S|0v*R{7__
z-qoSoq{Fa2c5D^gMkpVJ-uBNznLJig4eh+3mv~V~=$fW_={}7hDs6B3;ap{A+3rhr
zdL~w^a~}};@`$_6=c#|4?<=QO7sVV(U!dfwyXP(~5ma*L&bVVPRRWq~M=8mBhq2f{
zyZ%?K7d}iGSs at j1JE{|;KHI$jXIU__1{9wcwVYl}V2pw6YF#-iLeGm!piGEf8$Tbu
zp289<A9IxtH~-Cc*DG(XSAM_US}v8mU3K9Eo953+=U2q4Fv3{dBHHm4IVGm8w3*P8
z?N?S=I<-i)9D=Y|#Vj|*$m3b+cCT`f$BK6>c$ybHamzsIvk6gz2x$<F5Q&>e@&xDc
zK~95=TbiDa4Q-z+i)s-o-1st8q5+!0^<#c5_!`*TvW?WT(?_+Jb at Gc3$N)x8uIIzw
zS{7am8no8_6;^9#_hLtUdEN)OuR=AF9 at R9uU6~z?9$aNx(8Bz+=uM|KngRvc+xAK?
z1bYtgAN&$#SM%P|VrO4_iXPns1MDdw23|Z&5eek9Ra1kf7)NU+%jQb=s!RDY`TKBw
z4 at +58uwS^6mc{~C5iCq#p>tM!5jM#E6$C=SwkB+FW!#}Obkj3WKSYWHBOmg`T>{AT
zXgc}=fKPE5 at C!&Ks39MbqBDj at 0kmG=3Q4XDKHCLYF$uE9bp{;L>pnT=m|6D~AAj)c
z!A)y+l!auMBV?0lO8Lh!OX|6v(r;#u`&9%sv6UCl>3WG8ME1M2{_4uT-LV4IJbkI?
zT0mvPPCLvMoPGv1PT at _BcHmuIa;x6WLS*n6E~1^^nP``9KTz(PoIlpiZ}PV)=~b8E
zrRJx^bd97mOLkUtYePrMK52jN-IJ<X95R`I-lDf-bu}4yH3{oA29u-DUu>3B{x}F0
zs^ekyiYViXP4^SU5GWME_Cn73zg!|61Vk<PU at 8ouDnMkLrmSF^k;$-Nu9ax~jKbVE
zbncL=cHONOi?{dlz9sO*^WI@&@XKqK!IvOkI6M|y9{?pqPT9v@(FCcy;YL>oZ{`eJ
zwQ7>0B%u^u=+?{<OsN+uE@!Zo>%<$UO}qqu!xY1QvF%A*UbItpQ3k;h_|DP5xT at Yp
z<B$5a{iHyXlV!wDYG at O5En|O#-4N_!V{VTipEhmHDHVtRI1MEXeQ09Cx#WZ)k3z-?
zl=5BE at mzlTJF>r5cWBm%iGsu4Ns2^_`;}u!&lEBY^M{~oJk39q(1SUnT$abeAce^;
z;atgz`K9 at n1VJ?Mb!vBklS9_B>`a(i{yKtaw;v4i=kO`|tD7)>r$OvCtzm|w0_({_
z%fs!f)#~JTyi3&Y8w|D at 3(%`<9A?B8%CoKd9+LTK>BHeO!*A>y?Xy_)L2rb1S)42;
z{p=U at Ut3BFjZo5(8m~GpM(varL|w8hB}F_FJ0ysJi at F;<dD at 3RdZB(HlSY>6d!?2N
zFSb}lxi$}$doPQ>)(;H?@>==BAd-lAA9noB#R7iOBz8?BX<!$WQ`)#cYLRDxP_48g
zZHfSoNA+$%<!zRk>I at i^inkns%-)+9)h0cac<$wCq-X^ox)PsYGhw9M=2&QZe)Qn9
z%(>@O1#<oDg`5v?|5E?c!kEH~Tw-hGc!WOjamC6%Kch_YYW`QY4bES77FGmsei|rG
zD0X*iTFdRZHE<K- at aJRB)>e+bue+Sf%ZGw#2j4*`djB4m5}8=9&7A|{HlfN2 at -2*E
zM#!qfm&iLW9fkq!_CdTol}T<b+B;=ppTrA`mQ&NYz9cQEiWX3P`v)3fEbMTr`~zgJ
zSM;@ckXqeM1?2!ZBhBJ=;nxQT2M_c&{N~^A>}8pt=9hfIM{2!yH}6f?nyR at Su*d7Y
zdY)e)1`ZzQOV%^VK^haxP)|rHW_(SE?SHh4jIv7x-drrc`bX|uA|a}|X4blban$V@
z;#R8TvTpAO{sGF<-|o3oN#XgX{rXeq6^O`>EahL1?VK!gNx6&xj!F8^Pi#pC%agx-
ztkLw`W#*QX*~B55xx!z8p6B>3mtvlGKxz!PIgOFc`g~XfIdkrjtnkGJA|y51*G9KJ
z?v2%LUbDZKf8IO!*h8?r;v#QmUbcC&-!oj58_Ef#iG$%9#XcXadZe&h%~<(6W)pR^
zE;bApsZB-euvIc3G}J)4FIV at T!BjGehrLsiiv*s#N?|;mPXfQ}*1kRIpSg$cHyHxo
zbe<<C-#jg6J>-eieYdBQ=(@O at QT3MgTcMRtLU=^)9s~RV;7!Ccb8bI!su2sdMM4Je
z!H+Gw2?~Q;Fb^%`<WkYh?j>!t3w|;Nbx%vN*yTN{7`h)kut~)tzfS1h^j;y86cw1J
z^UagqexhbB049G)7H$t)b@{X?_dE}doK)aVEIH{{zECL&W-<6D#V}W`uQ&2!Q$m0?
z8IkA{{qjR1OZLz3u#hl?moqmPZ8sOU2QyRDqBJm4 at vlJqpDowZ<C>yX?O;buwX>}U
zpShZQ;XE&Np3U{@h1)N#r_?APjk5X4X- at ZQWG9|F?G)Dsm9;(CAP~V<_&&L|JmhGQ
zfI*yA0m%kL4{OgfYoBJ>vzwx^b*}sYe_zAU##jEi7MT88zhd#Ydmh9&Dvd?)D+opr
zwWM$ba6)~v)3J6;W)s}IP*GCUZELA@#J~+{nZK?f*m-DHHN$=OjEC=_IfUdkW%yQd
z)h*f-JuU)2y(toR#^0zz1-7hZrlgacgqv&Us2Ff~`PHdvo7hcV(@P3<S$N!v!*Qd>
z3umnY7hR)*3I3txvD^&xKhE7;+&YMC+8dSMiKOnt<q|PxC%dy>Ix1{!hNQd`_TL*+
zjuxqV`?2$7rb|t|FtC*OQsd}`yzG_c3F!oO_{kXssk8W$5D*Bp<VI`MpzfcrON+{j
z34e$EqV7+-^z;E#Q^StAZhhw+L^0TxF3mCPMu8o&+Zin~6Q$0L>)9q7)wb1HN*ok?
zFUg5G_)1)EVCq{U_v-h}vHIq;xw%ofKO0tm{l|)!M*_ at R`*!_tD)Tq{e_r7T*qYN%
zZd`bWwwux<L!e{5cNhYa1LbAS1Y5!5y#7p}tHbSa$OSs6LuJU=zM(c4^{IF(-;EUt
z`<*$zSnNTtD6g9I)CahXn-shk%z1v7FVv8j?g^9A2MkHz0>2p`S~Xxg{034t|26K{
zChLdG(ubpcI(7y<)zI&qiz;rl!!ZJSBXz|47#F}39RqOZt+BN>#<$=M_1=uLASLqo
z<dM{0_7fTEm&KZO?oLql9fO at rlo+Huyv@tW8E at GAV^~ad1CyToX!7l3-zahUDCd{7
z{hyS-I-Mtx4yNecPQn*%W(&IrD0-^*+7MEv86zhMisVTHJsl)rBPEs2Y>LOpstA;l
zqZ2fr7bA?hb2N!90E|A)89nT#2nsr3vw{#bFY+{WSXz0p_0Mt at rkhB(kQ_}3%uOc%
zXO<?`K3%_hjT+^qBID at T%`{piE*9oGRO4gVMd^F>hed%oBfMxY*i93}CyJdfeD~$6
z+F++A>Ey3cHM<VjYXAU%>tk8`_~0U<x8ULTVc}dX{(^7hh?MKu%@8&7JPgZ2nha!6
zS7PfRO*hT<9`;#DhIunZXe{pL&7SEkG*-<WP|#UQ<%;Nq$yC_u+O<?PX;jaNS1;@>
z)VOO?O^cE7-XRrU at T(^>c~WihaSuXjg-5jN(j}W=v?Jv6<w#6G(_?=9 at 5`b-rl$IK
zn##l-Fu_7pH!Gsuiz+?LEfwqxxn6}UaaL3cqlBwvTWSscp(^$|JzXKMziT)pvYhf$
zlaC%?P(6`3dA@}vdmQ30;!WgTRFaqU3STh)bRYU<uwreTt{2yzh%cR`MP?&^i%{p6
z+|Ih3OIz}~p}%gxkL(3AL|>PnS_GcaBywkO-(Mb*u3EIIxyyK@#-c4)z>-wfP4#)z
zV0O at lxPTV8bv$cG$Fe0?92moLwp>;3+VKZG5?MB|;I*XF&OrAw$Eks`olbHB_~%aD
zUcv9;jA!X8Xn!9cpHG0}b<$(<t|}bQSi9BY+FNOJ%KJQhrmpONCeFJ<7srKHmgl?{
z8_H=jG3n3BzpjgCNODyWy>OqlM>+^PJ^`8J#AaO>dl{7P;Mvr7MU?02=sH^c6i?1;
zrh?{i0`8oT)`m!!&fcj at uwBq^&pzdP)Fo`(h^O!%wJ-5a80EH1r=l7%p_+IutpDVA
zD-8)_f4KJ9w*b06L`vgsM!a2|(>TQ68c=C+zxRqC{!D5fy0sL%#;iMO4#)eoB$GTY
z9x=ltIBKK1dIrM+Y<-1IE2Nkrq~8HUZCY(di=yb17rW at q`D=f0lGP2L9ej_ktM&Oe
z!~0hU-Qf12F at rFFsA3sF3ym@cKTL7#x!HZ`kmoknmKye0n>b^aggti;@i%5MdK)b;
zggTqYA4u`Z#mzOo?TrYT-aUtRAE_>ud-%nOtZTV+1DQEOx*+tW0WgnuZ|aHSjcePS
zWkysrZbt_2Gh5ph9rPEO8L{eyw?Xzs9?aZZoJnFSaNCrB9})Z}!6txkEuJ>&%WjSI
z>1Bg;DWo63myp*1RCfipi+=Meg}asx^><bpDrQRU&>QRjwbCT}qQ at cTWvjc{<uY_9
zo7nO38VSZAi>>2N4C;2keY=4R)<1d)PHy+(Xo-yoBhkS2_I4^$92J$c&NAzbQwf~n
zESzF~CiHs?$uqLp*8n>4UO1*hVe!G@#gl{ZU+mim9*NtPe#SC4{Q6WOj>{`XJo5%`
zqL*#Q*B8MtEG(4<1{sc)bb-V_S|7J^M4^wo$bmWM at rcO1qVr!wg0Xx2GR46 at Y|@y2
zV^+|0IB{+#{$!qAiye*}4l1(p6U(AKjyXF&-lnfnGsJa`94LW23e!+g6uJ at A0Qcpe
zL<+j(051O at Ee~2$2&vkw)*@TP=<ae=A54T68MxY!LnsIMZYquM#K3IcId_IpIppIA
zjj`oUQkx-q2v!cS?JYW>^TAHCyM<1zG)|754LI7HORhqQm{Zu_=5wEh>)d3KIK}S;
z#MB|ag$+;1P7F41BNmo^a`#SC^)~$wy!mTsE4ZIL)IVs-7VIn))?0Av&vOT{s5Fv|
zff_#-p$1WH-L<-5;i35GcTBGld3=(vEw{o}v1vLQb4#m>Ibaq;aD-ytBy~)5;K~f=
zL$gMxdVZgWsf?g_Vt&(QfsV$?fJGzrWQ1BT^z at 4F4$>IgAGTGH^vTEF(yJwz`fdSP
zMt4vIvQF61#qOGgw_J0=R|hMr%bTgA%|+MyjUKf)F at RNbk0c=LPQUR~0$K)r!amIw
zkly<?u5Pd!FS%bSK at JgMOM96Y3nNw31bUlF5f`A|p5R_g(`{u9MV7TOto|U>oIfrj
z=oq)1LJCzRALvRmctr3|{{EG{X+0pn{ks~A{oI^`RY#wk@$2tb0zZW-<K#O at e|5C?
z)g&FMCTc(Jz0*@s4mH>f-B8a2j>eX;@qt^vz4xL3y!Q;b$o~=Gs}u^;oV`z7j(a-!
zq$qYBOpfqq(xaV1{Zcb1zGJ1Bja>hndC~keh3Ds_Y29|Md~1=FbTzv!K?)1>u0ubD
zuD#ftYza_C?so+nNP^w~c=xt6q&rK at Lg$?$-U1eBghVZ_gtI==C=(_)wxr(ZsszHq
z%oF0wn)&=@PCSJUu(`jknpE%e(IQK&b%6v$c(zkjniSY;rgbqi<58bE at rg3xvx@gK
z^N%x;o;wK#NlIPNXFOAI-eGq6P|RrGTr0OxqgIxmj#K$P(~{6G^xBd`D15 at e?sOqa
zzc&B{4Jf-;iHL41CsAi(Fsqu^2#p$thR{VE(^qP3=4iZXVhj0FtNYr}KqbpMqO%u3
zsyz3y9Mrn6wED^aF77!;*MX);r{1S_;rjLJVTzg7%O2%_6WSd;#|wWr=6s7DIb>A_
ziqUT8{>*8F)hx4!R(hdJavJ at 2o>wLs=YAYo9=L8*$6^AIXKpmiS7*S?s9fJ%UfNVE
zM>6xQ?7zi<X4fNqeSNbX);?YwLUa}iBHs`hXHnr!7g)Ye<u+ at OEI1w$bxckOB>@5-
z`!sGI*wHEep&9?8xp^7FRnQB at gqa96qV3YU$9NQSGnSWFAB4qGkMaw4f9v#;qlUHc
z7rlJUqfdG}fiL*;QxNxEeY>O%%zqe{T?FWd8G}+(M|>6))ONgW^Ye>jFQjT!jn3NC
z8H9;|I$MM*k5h)Xu=JobXinx6Id|`HGO00yghe*&*pH=-ZCF}bFnt at jr=Qe6@&4I@
z7cbb%tWBqn3Tc{~N at K5!v2$N^iBL#iooRt7UNVe1Oqt2Q1w5Us3pDF*8jgqhQEx<V
zS1{U+u#Z{V)-9-~i<KUNXyliYW^K{Lb#-)eA8|&O^7qA>WfHbd`l)B?2G6g3qG*1o
zyXNiE&u`a at N#p#mXg2kePTEwZM>^P<shIhhGA$OoO4t%ma-wr|yTe;2K_Ne9lGW`8
zfR at bIRHjXU&WBm-VY9#E&JM=pZ?dh`4V)w5q6>m*pVdEn=dtVbSvPENdDw(IGS(Fn
zq!%<Y*u0=Ni#(8WqBUC8^#Nf at Qi3K9f!^_H&F4lm+$iDo;GXyE7L|E17ygSMz;lD3
z#*Bm8)L~B_b=l<1n<FS^N=m##-?%mlG)@9?UaTxwB8f|FT`F1+WO!qtcvw>zQyy-7
zwdw1ELUT99Nl3Pw`jAf747Mhw<wF>J|4+2z>f1e-PDq{1`1x3pLns16qgut}&@6PL
zwL926?uQn(#ZJI6Gt(vljW+}_>>dBsOv1X9OCpskZm%>-huWU_c#1;IHo#ht>5t9a
z0V%U{5Z7vjKRTTbVSIA+{KG^vDupyc{2C{ha+d6$l|AXj`sg!DiQnzhM&-X=XVYvT
zmVg|m{p+oZh#xdO4G~3MUxz;OAG|ecETUc60Eur{hyeJ5D`coZUsfluBhO(noPphy
zHJ6#H)*H;xGg_B_-dyj0at12|MwRMDQi+ at 1FfEaxO%jhJ&Uk7{9QbKtFx<RcGYq<x
z0dzML at 9pgcQy_L_9ltA2V#}l&=tf&f^8#4>09e&V^4J%uRn3u_Y$f=0^(KBbR8{P8
z$#Agx4Rh*UplsTE$=LdTB_V_Sp?$}bgqx*JTc0pY-Fy3C)u6ZF_JIubKXT)p`;4|_
zqrB4H?Aykuh=)JPKZCh=Dz>*X1^TXy at rX28(z)}XlGA!}!HJ2FWh$Ruqb`bG3-KIm
zIa<qjG`%iRbe}wa6}wFs!0{jiNgcGvRt#+V0D^HJ!|fy!5+cCnmY$|0PqxwHqk{~d
zd*`vA$LFT7rD?Kf3N*D8QrZAX+&_pYGO|1gjBbJ-5{R=nvT!$MGU!9XVIDSsE!$RW
z1VnPgww8O>ypRjEIE&=Al=PZfr1o+9y(Z(a at Q&ob6Ijv|Pel`P!K89Imp9sq+Vh}U
z;*KA#rO|`^eZo747?g(N`?;E{;Mw?CN0!n||MyE6v>Z<#pGBv1gH at oU2=Zo_#+A01
zRJ7DQ&rv5UpYS1W0t7k}R*YeOXKyryFuA&n?cS_A8rbncE4W3Ze(FY&^a+D-eQ^r7
zGnPcRw0Ftck=aa(sOIt4hl7#)X-J-md4^&Dm7a8_bfn)BElFpngA*syl~gG5ThjwC
zBw6H?84A_;=e$vdJfB4Mk*6EoLm!``ql3BX)S5<U!mF_(cNy|GlfeUw2FrW7Lv3Yk
zsc>D~wO^Yt+>UUnyvlrmK5(e3y_*@)5Zx{{Ng{c~=*Xy#9p?{_esJB~u$F?*>;5RU
zO)6y(H*QELWg~QbetwSq at AkGAGhMx{jinv~c4!!~NuyjRmP*vhl#vWlFB?@q?{rvi
z%M`qy)G(MwsF#V$At+Z}yq<ee%(OJ~dGdo(UJE0KKg*C|rjBD`K5bzd?Ar(Zl&2x(
z+_(MJ&yPyTjY|$D_!-aMaX$vfiRBmUx^Xvae-)@%{eLfj$LoZ8+CEcyxK-MF!#Thv
zw~2XR at m`*Lxf(Bj$g!{Qw2VMy#c*S!0pS<8oO;RJ_(V)k>}mnG#rolX?sGjc`;o(+
z1M<4$Ep+U#E!jzLR=moFfprT^|8yrq5|hd!yDOhZOX94;r#0i3%GeXjpPIl{V=SNt
zFB%!w5UgM4vugg++)gKr*)SQdv5j4GHWFQ;mRh?v71kSjCi|V(l7bELi7z at GGBdr<
z(J^>>- at NWEgS_2({}0z7XO?=an-o2>wJty0#f6wdz1WO?ys>q=+J`b*^?cdXv+pGF
z$J50*XVLN(J`ul0NSfE3_@}(JCX5lvy5yK&;o+LY`Mud<W2=ft7Jt!)!A)WeN$slB
z!+IUkbHa9`-L~c0AAK&mN<u91Qii_0f61fYzTo2K!+ at qBL2k(X__FCWoZiroEUsl3
zJr{xW-~P<6G&5f+QgaY=eMq1IA2A9x?Jx3IEAQ-Hxa^X^+^kxa(RY4}6%ALXuusFq
zG^xK7IpW?I>-s(0H!v^_3()H{p52#t6x+#8KgLb at H|FY}PQs&7QXeX#%1LN!q8k=?
zU@=Ky*jWdCQ5T~A$br|cK5vf;^Zm+JdGfKg#rI==axoT9=a<8~$>Fy>k9aZy-?%>1
zIp(C9?|9(1##^PQR4R-L25}lveYee^d5!8hC7 at Xkpk4nNFWG@wS6As5;Id<{ieHn;
zv-XMewvxP2;v~0|K$~|DBO at wEfuGMNy6{C~#p=0iHQZEX!_yZrfvc at r*8AGeOF*U9
z?`ZF`iAkS5KdTeEK|qqmJeMsl8zYkuioPFq)s#n0Ak<KfNx7+g%<RW%ONA{)FLsTx
zDD84!X89fOA#s-vXI~+r5z2J2*=l72D)?N-!qvw6H4ZSkqhhzAgSWh^YQNZW0GrxX
zCP}lg+z~l63Vf_mf`Xfn-MV~47jC_c08_4jl2|=jTMnMGHKW*MeLIGTL!+_HE0YTP
zUb^E|eZb#-{Z>AHb&sVzs?%rB`%5-!7H<e8I}bCICN+H4_u2X?3z<y at 5V`jyyvThj
zlrzr0kMfRhom{9C4nsRGv(a1^*N5T4i8xbE=TZdF`5wPkYG1xh&vmZTj5OFApDV+?
zsu=)PsG{E6azg{<bsSa at qg+F2`&N=kjX!J$FMHumGP4U3aGS(`Te-~sy<1xZo^C+2
zbPcJ&8w%^y874kDVB|*bpk~;T%Dr+Tp?!mBP3QNW6xOeb({z1+?&GAtj_(#)7`u;>
z?l~Y-zg4d=em&Bb)v-0*aaTm?D_Y2 at HQyA0WnH*qI3B*g&rbS`43hg%_QklexFOEq
z9Ni`rGd%<1bH$ZKw?}=*|F#U0n>4#C*8);`Bo<SUuK<85uANiK9x{+uw|3YCIgUiK
z16yQXZUV9r;&*aBSObPS at 0?JI$0<cz**bW$D?kWli&#fY)b52pp_QEJSNYq-z_H4j
zv?eV5q|F`&0VOqDWTWp at l))t(4>6)9(G2~!6-{zmn?}7L<icX!Ha8b8#vz0#ayW0m
zt*_stf?92>ysuT3R5fdv>N<elql2?4qzIlG!Kz@}G}%;|_B2=5BHy(m_~JVE9XPH_
z7&Fs%Y%-$T-vk at zu3hi|ucGT|riOFs(7a;&+#yYCpI!qHil)~<UB1H$efj04cDy)d
z`0}_s5FT-irN1v9tmx(3aX8xuU0x=v0PV80&Iqi1ICSO5uweeWF=16M)(JuhFOBnH
zTnVv4RNxIhFmNxdFcQ0bZT+ArEUL4uAWHol^oLimOPHhTZANLU{@RCyefDj-etn7c
zjK9HpQyI;*ozgUpJfvmKRl@|(wKId~^EFv!PbWWfb%=*>%p<WLy6?friPvbZP46P0
z77fdYQF~#OqaTxz{FL2+L$<y`LopHcw42-$!s=(SAR>|R;BA>rsdQ^<zX4+Q?=Z+6
zX}k2{!Cz;wB{_6)Nea?{Xh_>jEo`YbImLUd{`bB9h{c$e)M-YR+g^ys2Isir*Qp3i
zNda1SuVb(3+GvWwidr6uiqokFjaLC|2mDVW9W6)3YISL=<us<TP-<UEhlO>KUU=oY
zJ=(x-nqLuv>;w&FwX6jI+rn?tyaF_<6ogKFjQ9op4w$PINO;i0J-v}zWjnd@{xohr
z1yVk<*<{kusoQ7lv1o!lf%fja?i;8Yt!1sBXT&EwfY2m+6S(%UBoE?a_SuBX5{|Dg
zXug!Z7To^C9sEzJ)nz0u??i1v#=y=Ppl{uxu9oNxx|O|ZQrUSRbCeccV#ej4;BeHv
zzYb&XH04?JKkJuJ*q!0s7btYdVsR=TxcykTyzm#sN9%@(^q)$Gbb_0i%VOkgC2?iC
zhb*KwYg3jzup1A4BZ5zV`BznN5Y=jRNg4;{EZ*+|Dgfe1UxRbsu8c1f-#>V6b8(Fx
z6|bc5`fIRL(+B*+wH*G)oL`JC(pKy}$z3e<Xjd=Rtx>0sV#~I!ZN3oLr~{mASy9ND
zx}?XIoKO+^knuWP!-TEi6sc68JCnmsN%xogb=r96dws8FS|KSQ&Y}vbv)~2cE}m4f
z1FL!fA0?ms>c57%qMqr0lXkicrK6|5M+V(?ubr+fV=%H4FU-j|foU|iir10*dGV3x
z(Bg2LCrimE8NxW-sIp3bN86Z<Rta;PxKiq&H>acE?mHDoTWM>(BI!_Lc?{L8oHKHW
zk;|~{bR0Up6KR}<L+p5{M|ITT{`qJkZke)peM!sKX)(U^AJY3=NSqy98ROB(CZ4q;
zS4UJ5TyYR|;e(0nj7|aZ$zA?uq!qv!)8o|vL$OOK!w%s!eXa&uv|-Q}P)UBJBsKbf
zY|&-KIb;L5nXCa5!T9A@#C*jMzq1_uXZ({en{2rjqCZY^S$uj=*P$|c8pCOiA}IMV
z>7mC!m5kZ at ye8(`Af(&STzHi-Kreg2<(qAn@}iVF4M$~l9iw5kPQJ1#@B2D4&AM(%
z=2gsOSMQxuLZkWOKO)+S7RKOdPGiFc3}syU5KWlMXwkifCw4xL>}kgI(m`y8IN8!d
zYdSZ-fW3nB@!d_|EQtYz4#nKJxu*$e!2UEamm7#?itId3r}<W>oe3muQLQWIwR#XW
z6FhlGZ={~Rb~4$+%yW at AHLjRZA01YzqsdXBAz4mbdN2UAMa0@Mqmnj;W-El5YNt0d
zkgz&9O!*RfF#~E^K<#nk1UYUrs)OH at 8aCcL)Yfv!)^GdPc{j_2nO;7gQ=M=1Z*UcR
zwOBJZVi5>zgptyCh-a0|+~S2%F at WV5aN)kCoQkfNJ_GM_>tXE9t9r_sF+{1PMX|)`
zl%jvFnoTr)EYZjZ=Fl0dQQz)csp*(EJf`K}&06%He?MvT!6)?3exftdb2*pjSbKw<
z_K_44V{vYP6PN}lzXFv`m7MatJ+$!+yMq%W(>(9XQkQQ*3;<p|s0$Xm^le?RP}
z0Q&~a*7}*2&ep423_M|wkn)bj1J^Cu7ShaKs#$?p4^j1*uUCX3;`ZgoLjZ<F(rnF`
zbD+plY3h-65i4(*0Bz%o3;&0meWk5W0`R7k-#Qe3){twHHec8v;^~kG?I<!HcN2Rh
z1nr3v)Z;<6pwg_f`=U}obzJS8rr1>71CQsmzsxPN4DDnAC(SE*x~%A&5-Z6pCU&v%
z@^V+lz-N^X>`iYgYYi!^9zqpnJ}-P;Z7nC%Lxq$g<m|%TX*(hwYLImPGJgBN>P^7)
z*?I_i?bXfcpD%eW_YZX6>L2fD2hTQ at 4;T9U5VXDle~8ck6&>lfk;Sodbj;HEiJz18
zWEH-<@aHhOa9wPbRr;;RuWJ_a?I at wFHJF;US#_}XbW+W8zkjo#(+{t1UAwJlqvN<;
zYtV{gGx5N8$A<2Q5N4P&+R2t5_<kN=OPPg09ve9MPa3J^<Ks^4xp!2C>JGI6nm_}y
zVmK_73__u1AUn#;7Cb&3U2X0yS<@HO_(&M<a&pNNTfT-~C{@<I at 4*fJX})IBjpfSC
z=6g`1*`UUPNq=kv$alSPQ7FEaV?QLZ8 at mlAf-+5@+9$m=72Ju7I~$3wgdd(j&Y`b*
zN4?qeate1TC;A*+;?RyHM%_Q-npBDRl83+v>WB~@XoAROh>b1uEaoh<6Qy9JV1IN<
zA!vEKMYvd`VbA67Yq3j*0VYLxGCAC7kpOKiQ_(x`de|klvQsL{GD5KnkYBKNd4YQq
zczv1qug=>NYgZ!Tx*)q|l=5z at br~KeYwQNF6(^kYiXWG!n_u7+`n;ld0)HFidH;kU
z2OBJ|Jk{#%ZkyYO)P_6hYv&|-)6DXJ2zRFC8A{>aWmK`LCgqeV-YcG*oWxPbKEMn=
zn+*0wcC(e2d_^^2*%>ezGz{awRqg{?5gzuB;+v52#qQSD$LNE!s)jnCs1&h?AuNTh
ztSN(z8$*qA9bq{tng7Xlo12wbv0*G%FEn%=KuCCS<vvR=s}nX0h)ME<+Zeqyi+h{;
zu=C06E`<&@c!F^w!&IippZ<kq at v8npN?I$yEvx*8t1#@#eqQVkXwz4F0KS*C=*gC}
z&UuHD!EVRe^22dNvvwt$^F`y!G0}(dJ-W}0l1(LrC}-H3^%o5JgIk|;Eu%ldq2}CC
ziX=4ME983B2E4DbG-fntBI(js)w%VO`tz)x)1Q~6e=P*oU`vUYuv~B(ZlAKB-$`Or
zyVO%s$O%HTQ(amMq`c{*chz@|WL7vC08p<U=7N!gd6G00e(h- at -}deFS(B-zeeFdE
z6%L!Ea<?YzVL at 5s8>)|o?2*LwvTb!Z5h~N$CSKf at jc7iI6?Im{Z~<42ThT7*{4URs
zzq%aYTLihCB-+ at P#yNpkTu-0(BYrOS3W(F~r`fNBTi+e<wv3yB6An;i54<VOEHv+=
zEazo|t9;ti?}_ at PR68?HyLqt&0W}U##P`0Kn1|b*bJAc=$AO6S_tQ18%ggtC+M|4Z
zO|Rwiht#MhbU%X0QMWp1!5tY=_B_Uotn&DCZcb4_&1Zc>yKY;dP9wGdj6<LURUHg|
z&+5o2h6q6+SyY#`sFse>?=N*9t^S~G>xIF>nkX)d2!Kr6s=&AfXr%E{W=lQu at +0aK
zZO}JT0F_uSgKT$-c_BZW`!u6o+qYPZURv>qg>6sA$B_}}d~hQuV>(Aw4dupxVnfXD
zLOg}03O`vMvRwcrBMgy!jKta$L|M--OlgB;<1`|6ns(JT!pvg|n2m|^zQ9D4>Qp&S
zCWW<J65TYcAukQhqP~}UT!n0zehf0n2#tOx9e-R)>6_Q#hH95S1Sc-<JDxPwQn7pd
z_TC*)?&TkA&x@`!G62JiS=mYZMiI?P9*_N1XT*X$n-)6S?R7a2X!X=+7qU90dgcKx
z0(lSLIWd37e~w!^3G>=iW6p at tY4?F)$@fTnJU((u5BSN+$S1E?*na(j5CUBkt#uI2
zM8Q*|j&r#e7J*&N&KCyeiCOHtDQdmXhk|)s7JIWzM=&$-W}acU3GPX_WlUaSEdf3Q
zL6UDf=H?@1#?OPi^Hfd%kyC!%ei}rzux6kJtx%czW6#N_?jzp2sWjXfjSEZ8Vu>L?
zSG^JXDh71DMoL+T at Xmmq^Lg=J$oB7*>eL-S#qX~`6eXCT+O>^pKeCyBI9U+aWgkZu
zuJwjEh~FZ2j&I0Bf$?N0p;w%NsE@~b<sd624i8E>o2_ at nT@z-1*+^kWaCWjDsx5Z2
zY-{LAA+nf?Onf#s8YI+8!a`?0fA2&35wI`*RgI>QB!2xr;CV=;$4ix63GX129Bfp4
z1mDT>D|x$+nc%Ua8SJj`i`Dnp(4vkSo>GIGER_N1Wq!wxo~u<&f-JyW$6Zdn+uf63
zb2KfI#w}>5D-<E`!&nxz=-ksV9PwY+XDN~zQo!*wTVGOS9+t4fi!VAgl-_1nAIIS^
z22^4ZxLuz=-H?wRqxgOi!KqfGWhRPY(vO<DSuY;w0zP0g5P8#*`gZ2z*=%9Y9bBA)
z&!{2ZY<<snd~c5hL;b)dd-1hS%}=9W78W<x*2bHOETk$MEUM>cveSxA(HKFKrF`?!
z#;%grkwXi>JfX(U8hSwdU(w2`jQAk~i2}_iF`KkiA2Nb!@Vk6i2$x7}cyQYUmSu^A
zjl>>{_467a1^9i2N4K{aNN07p+x$NrSQYnUj^=XYgC0d`J2Qa(st?Zh-)$o#2!>l|
znpz3}yBd4|MM%PY-LuRW&BXSNI#^>48TNQb{;|_Ws^mWT39j6)%dvINBwlxT34Xa5
z|D21wYv8doRk+cQmj4_r^MsN*hSeI!cbduIRH~osX%46S4^n4a1(WNuPWt2b56GGr
zhY^mxHq8&=dXhrn-^bYBUTgW-D%{nLe}5gVGpuehaZ7&}yZrfy)<{<$O))(Wp+m|C
zRPwTXfmroyT+G4NSlf?yW%1t%?Qn)+>Rp;}U#aA0o@&n;my2G0!DmXPn2P65SxVy$
zWJLOFhAW at Pd+&gL7rv8TLFOY~4)QJ2deSSsumlXXXmaqY^0Io;kXYdD1Zc at D)0-3{
z(}c?^M6+DuhIJ;itcj&d5&#p`=t_5DV-kS3<V;VjF=oiIqe$;`B5x$h_jDt9Nu;+3
zd|YVyP1nhz#DoL;<_pgT5d488LIULt{$}yE_%+*$QJ_5fQaJYoCTo@}&fAV-Fl^u?
zYFH4}cQLC`t>SWQQKzY;toVBP&ZQKPDr+hORMyh5p051mV at rC+6US)rf(*BjPC^(b
z-yCX?@VWFHM5W!RsgbYl%X$I(ynQt5Jqmo+MuAs2zCsjfe68nxcYN0!y)(0Q=H=B3
zLRJX_WK@?u5^l|6cuam5eyxyRdW4YXUEs^`wrO6!K74a?_}fWy(?J@?!$_Um_?%}M
zP49{@E|SuF*DIS!T>j$OP;gJ{V at Xm9(w%d$Zot&b7GWmOQrvs=IaVNx5edwdF~};@
zMQUI5*w|!Q2H<Vu0>gUH*)qbAeEzC7oe*E}RDX$oH9k#e!fQ?82_c=WV%H!k--i`U
zeUDmkh(?|ASacG*kjD7#*imIl1W_&bLQuGx`l)mgSN1sf$%(IX4b%|SSG6gWb4>ns
za8!b79UT~(^MS2pce8T{(w=KFhAP}EWItT%EZRSNtt!p=X0Cbq>wF5o(d~xvU`uep
zR}HRh;q0hiUSu at 7?qQx+hd*xo|LySM=8dM(Du(yf0 at j7IH)HdnTgg%F!uC{mMCy(9
zoh;sNFG%s8+*c$|(JT9$w0+e~cbp6KEF`Ku(D`HX6C(Og_7Un+GoxB>$B;_*0YoQn
zu<-YL?6%#`K?S$Il%JdpvAs0}l`Oq0^o;+-?^~|7+Aa|prUG<h?Tif_Z_{#`iLw|M
zTjA1*TkKDC at +r&94HK!7RRi4QGLyVeZqLJXZ}%*k**i$`_d>uyAE^?SixMttx_R&f
zAD#4}*G!q`O6zt`DWKs?SO~6Gu1Zdca~mOBM??>8fb1b|=~7;)Nbqd82%q&Aq89EI
zby6p;uP0!jW>cLyBRVoIJ*^jAoAp2Fs<Aaiqh+19bg2=L0-{>Dq3ah%=g8U!+w10$
zN%ljiK&q$dooBS&>`$T;U#D&*rT*hzAVO7#dYbW7?)TGdHA$BWykHB3iH~!k_EmtW
z00!Oj!+wb%=<=Z&(<bC20JinngVu;$ZOU&@Ia4J_jLc}GK%j9IR at oZvc411>y|LQ%
z+6S1H>gHf)Xo-fudK^%0H8+T=th<&+Oz6M#c;otwStQWW^6;&KIKe*e%01h%$YER7
zQ)8=5yj-jdSO4S~N|5~h!uLm>e+bs$o)Zcf)@7w#bJQu?N-u*iEg|PnjyhnY7_}(z
z10%hh=Mfm3!~i#$erR>~7t(KqzP1S6ODwJFOh%{(WfV)`3^N4ZZ(XTrx$gdp?_f)7
zqxH;1XtWS0xOuE%*a?r}yg(PR at z+g#`{MHV;>_#kBMTQXNdZ+Q^|e$t-=KmgUgo#y
zI#MKvWGOP(n7~QjhbuMigV57*%>>_kNU1)}?8!VHXVmfdm2u-3T>npRS&MeH{`zc3
z#|>9jeY*kv{EAQ7`NEGj=0VT>jq{*WCk>hxKGMF&%aa?9*;=`D2{t9GHlk~6 at YJ!>
z9fl5|B<m;aooJ#4t2r-tT{$!_%|>~v474*CO!W+-qR3kE^%C>jGRBUBkdDZYPnfR#
z)b?nL#Imu!2I|vmDr66dt;grBD at 1ieeZuYWxJhCZkf<xd_l at B_-?P+cqf8ZVeFZHI
z at MCCa4osVatOL6zY{nxg0W{n`aIOLj$+JBlQj0t07VxoYat%(D*mqB<>GN`Asqf7x
z5^91DdX2Qo at B|Z=8#V~n!z~YX<Q4W~;BAC*;S2|FjX!<IJNKr8>()9UR%&bFouI28
z;ab^3P^<SP+JyBG`KJ=zXgkY5z at hut5<)d}(@E}I2Hjcv7Uay5{!yJ`R5VBKl=kf!
zq<7V=@bd%>A!)ou>#5r~w)qPJohVIchL2iyEXrE^gZ+Kp-`yCai3`@B%7VGY*%ONG
zA-+TL^wuSMpger$nO2tLJZu)fu#Z&utdLk_c at 3xMIT+#Q&gL-4E#zBvc)<N;2ENYf
zBKZlA?zok4_Df>Uo8ao{PQ at Q~xey{9EqYpI{z|FuGnUpA7w&7s%e%->3nxe&A_})E
zU4rRCPr>T*B~Gb?T>MT|rO at 2{>YK%0ZM#IOXvnkRH>T+o<|FuvR>GG2C0WkMxR=a=
zTp9D6=xdW@!KdHBoZOsz=Cw+^Wb!-i(&}C_Sd4Dk>fR~s-7f=SxA~X?=+3OyY70LH
z{bW at Yw;119h15jUKXC*Q#j&H>flpx39gAhzmGY{%px$Ku$_mXU%7^MU33_v_M?&+M
z##+jg$tU*G7g(OSx?NNc!0g_b*u&Lk<<Fk4;>GjC<@T>BmGBoKDB9Q!qlmUr*yu^F
z|LwSAN at AW(L&61!FeRt_F3N2Du%^RmB`m#!)}3?@b0qtPSH+Ib!gDwE>f63ruudq7
zR;3oZzr4%-D`iYi)&Y4Kn at FkYC}8_nlwg3KMGIr-xU9=<yDWa6Di#URPQr;%gqzcg
zbg1qo?)dnaY2V<su>BU>xeBb<*9Oh$?!C=9DHmF8`^&0zk6?~xE9X_y_pyn1E1i>o
znV1{u0E(iR>5t}&gk0Uh02;it`m??uExCiwL~uf><L{&W_7F0%Xh+fn7$G%yK`88d
zcc<CU<z}$9R=7M8i$yG05;pm_{tWgH{v$ESS7s*L at i)GO&!{>DP)|tvXim(hJL>V*
zHQ}IZP660y-I7w?)9cwz3wmFbMBKbo(24)-h8Ky$^+%SeuQSV03+#L!|7&e}*j;P;
z9+#KVm>yHwGF;8`Z1I^{Oy1MD`+liYjyC+RHSWx0dh(%xv$fB at A5(VkG3<X6C!=MC
z8#Zw+Hh)bYa#=9t&rfS6j8q%mT|*XmM$1T0N}kFxh9Gh-R{YURY=2xYy&F0(h}wEg
z`V%En<Wy-DaN7VJVv6QV0u(gtG>yVo0eYJLyRn*HGiG2g!(OAVh}Lv5%MG^#mtWyg
zb^sG;tSb8h4=&<rx8T@){FPs{x(uu7?EbK$g4)GiCHpLtGa|brCW*KdcSWfkZ8gn2
z47bg9Latn=o3>&ND}QV7`JQdHFq?Sjd|56-{O-OxE#LJM1aUc222O&(;8qr`-t?lB
zj4*_4-fO<z4I|E}+q!m3(;|Jgxce0_6se7$M^E#`me36<)@RB1^<p*u(!}7C&DZ)L
z+ku4+0ukZ~k6??`u4WWr2Q>5Iv<dADJRwD&SC^yG&sy|lTOQcgR0=_=s*)1^diC0m
zs@!MY-@^!n%C$-OohLK`oC=gr>Zx2k(D0??u_+%MT%o$bHOo;$i;%cFwfm;;#YOcx
zA`sQC!KI$4u6AilYKM!7 at YC%%1p4!v@#LHH-KjMo_hJ(CiR)5*l=)MPP=E7~;F1l2
z5${6loJ$Ix`1<S=SaH(*9ujqNsr(3Q{F;nDh*V@>i5O?raGGj#P5XI*(y#L0 at 9k3Y
zDTDqGO=lg|)F1b8^(Rt-gn%NbAl==lpfpTsG();ua)b&~LYmRt-Ms;l(gUPpNDPpg
z<b)B=^?A<oFXwR1xZ~XWy`Rtf{d#p6_s*a2eO0haGeK$Hd8jJzRO|-$Iut9xSlx{E
z$Ca;dvX8!=EjvhCP}&9MnWc?}MpzO1CDw0!Ko?EX3yTrT)YA!d2|FU^J0^_Yly1|E
zqgRcOX~IQEtK5dN78%U(PV&Sc$tcWdxzE?dznslW46k2YbjfxeryBk!mD=XDQdQ?$
z`fec?-rgPyh=^bQDiSqBw2<HHYNr^*myzU+wGFx{*@0p<=6wA`Ik^cHkK1htwaCto
zLK3&}!kH&tGwm|vVcLXeSJzRvB%+6ezin2q)n!Vn#-b{VQcy`1T^?fX`}S8~dvo;s
z+b)?8FHW^N-ws#>?$*{en!aRrJx!f>TUnO?Qm0jq;KZqaF!Pm!wCo&7?CjPYRI4OJ
z4`YIeQB-U?EnTc~JWE{#>XZ={k*E0B*A8_D8{@v7?o3lT{Dl2$kf at 9O^rMh(;^`?I
zcicJqiQ$Y4KS4V1ySP-FOnK40P_ryEHZT1(rp{kSdvzgg!|ho#Rr@#nuo at z&er;Ap
zjGpO}@E<fT_PCj%v9qWERbUH?R`al1cvR{NmJ~n>`$w9L^JZWD8$3Q?(6w8z_ at -Uw
zaYO<G!;}>YG9{Uk!O3kcM6{&(J!8yRDydj$)(5 at N@uDdbGDHvNQ-kF5+2gh?p1d8=
zt;8uCYw+kd at hBy3tBeg(TnbVoD$~ct=K(LLr`hnJV?||!4@#GM#`a!^*=*|nX8}5n
zzFs(i5=O2 at ZX<u}VD#!b&SRp`j%EYyrCkTTDjC}YOb1ywh++LC at gZxqNuPM+_e$8f
z&l7e`*Nm;}O}nEf@%7$_Z?#dV%Ss9^qD;Vb`E9Q~{Ew?F$>@HXc(b7)SR}IUB9|AP
z(h07u6zvmcDkc{n$=*=PcCdlA;+bejX4?5m7kh_GKV|x;#7|%7nGVIB at zK`ybwAd%
zee_b#qr3&%b^)a84_6Hx|LT4#%{TsmR=dmJ?(}0QFn9OY0nFs?<nW%()3BE9Xi(oy
zL`X&6U{FxF0w6^CMv`wx`27~YVU at sRS??u%HJ&sl1eRsx0<t{9rg6`gnlSrn<$8Yw
zeRZ*0{lF1no9(ZP(=hiN;xCtHVaW*(AyH)m!<JQsARoQ+exm5C&TtL_&BGd}MHm15
ztGZKSk++f({XRMIR0`>ndBe)23a2c8xTptKN{MPxDx^ffA_kktciDC^gk-2r*>+#c
zZo`(Mvad(#4pfLnO7FFS>&cbs#EKU<ThIdc-zGpA`*P9RZoWX>V42lz71|J+s at onq
zuHtd9g~_a}KX_ at vll1O=K<#j`63QYai_ZHozskGT9Di}=%)VV8uAJLTqTuZgDs6+?
zWPa9O)z$IYQL%Eeq4NWy3yd8pcHO at _I9IP83;hz}TRJz+HNVY!|1a>C_Uc($Ca6=5
zfmUy83pCcmU)I*<%d(=C5~-3J>y)kyk2I at yw?%J$jG`{C&uj?*$WYGw6042E2L+?j
zkSyhCNlYurp%$ff<QEN^dy&TS#(bY^e#w{cS`9rYGb|;ENBrkp0v~a$3p|uq at U_3z
z<_u7HuBR-q-!?LdKgQ at Inhv-<mClnk#XV%p;|;8<ME~%v at x9DHqjsd9FIkq>CUD2w
z;I8N!5uJqu4_`uV6bMB4+9IfJ*x!~N!e{jg*F_(KX-#FM&284|z}*zdyj>sCL9YK1
zAA2zB_Wu#6h-^lQGYik-wz5qxG3I-$Bwg<HJ2eNe+5*RwcYRGe*njS=QCr2Ms&%<l
zqM%N2wYLv{h!ni}-sv2|pxZ`hFSM{9273V at cp!e7<SPo2eE(3c92sA-E0OgK$rfwH
zAWNlQADyc}aUiXa2td5<l>^Xw^7gsf%w`x6*`H{mSAiENnz}C+eW19DC}lezF6R3-
zB+8j0<S{Q>HsL8F+(0QM-gOpi+-$R=!4IcW{u&HE90kp!5z_LJFt+fY{t>MGt!r_(
z3Cy!xiHkL(yC}JGYLAO}3f)F!)7_#(ALx=)7&pL1NTS-yhc<!$r`K(g$%0Yg*0{h`
z9h$k4qoh$H>U7n+(&n^PT(0F-!Azo{9fv#Ry4TN>y+UZ|#Y~zQCs)fbC!8usD=7A-
zux&RI|7+GPIB<>*M8dBik>HL9L%n_O6rgKvZ>!2t?l!W2&UP<i!S?~LAvTqp#U1P6
zs2>;JSFPcO(H?j*KP5MK*0-NFvf#JU#wDZ`RzEtFCME`)OxRgU#(n*&BH7jcobY=L
z{SNL#(Yz^(`Svs5Nh7!2f+-qmSX=MoEK~PrA+>ent$1xIlTU7$yrHwVe}B?S;+s8L
zHY+W=tD*wO0H^roMuYXfKwt}hZA>QY>_n{c(C=44<q~J5sCROBzu|!mHMG?<@MuGk
z7^T<P*v%~_jrlIY=tCu;a?Jc7)YrHd9BOf>h-EXs3D&ckmR7NwL&pIj$M@{6P;Wva
zu`Z`xlG!CJ{_o*>h`c)|U70N{s}0`~owRlLd%cpxz0GaiJPRc!i%Hhr-Dsn%A(Dc?
zRdBSIW-~P=Y=kdsFf-kcP?@-cz)gJX^W3#*po8APLnxB$J)O2t=imj#rE|!WZewQ5
z%Jgrd<^!_gJqT1zH)uX|B0M6wcy4{I3Ae|^Vt5OSuS^#S*ne+vPo<cg+k%gVIkK0v
zLDj7My9je`tlVL})GXhCgpD^n+kHieLTuoMku-KUbpLt!Eq(ZU{C(3S!`j=ZJ(4%l
zxOG(ygrP4O(F1O#60$3<V6z8XCCKc)wT1d;@)7SEOC!Q)=U(I-_`w_`&d%<XQ{yap
zK5vYT#*<RVu+q_f$_l6d_4|kRPsP!f(s7hY%`R<o7Qmc*fXjB?G;1qa6SdEc_{jB}
zN0P#&&9lLPhj5_Vif-bpvSp71 at hIjD3jFunYi3A29NMErY%Q{iJQb~_Xe&B;XW3Y{
z44=5#Z(e!YmLngKm~}SNx+P}1Vjb)!?)(nn9Vr+|NHv3rl3)eje|;VMS^CtwYyo}H
z8pvL}2xcl{&d{066+2n4eU0v at KYxGQ;kNU&dGidm!@w0%vl&`D$KvMLeAl4o56yts
ziMKw{v*u4FLMfkLa&=2m3Oy~oSSXr`P^JcvE>WRLvxUSLq11<yC{h&$kN0>xpMXeW
z%hvPc^O%hGz?Vkd=yD%q7>(uO9?=<OL`fvIQEM05oSJjDwy#s+J?j_D(r@!^MpJUY
zi557EX7!MCwv&2p5G}0r0<1|FIm*pjSKe`s3cfzhwYTnZf`x at W%yw=yWtu#FbfUh%
z!S_u2Z!3ONI{UGBWctLj_;LXm<B*i25jJq&9THU8hxGz0X$wyo!!2X$Ww9hZ+MkrE
zroE&;U4B at uyfaI8lnXqgF;{Ejq2<GdIC~e9N3ZNO at FG=J#=ZA5r8riLjlD9xvIn`b
zM;=Z*XfsAHQeu_ZQzNYnx#T}D5#etVnB5n<%g^>e2;FQW at qScahCcIL?I~t-ioDbk
z6Xn4Fh7;b&cW#4G=l#gN-x65cUKiMW>aowYyT72fFyRu-IO<XD<Rsx$1Kn3{$>azr
z(9|z<;J4;ok24`cXka$T4#t7k at Ff5r@&jgQHaUgc`LKX<S(_j)S1 at 3T^q`3t)@z&h
zZ3xw|aEE(v$p#MYx$N&+=P{Jwi`-C|x8dzG0**XMP>gJyZ^PDny=zRXcYpbC at W37Y
zrvsSpF8Yv_FEoCz=s{BM?1{$qjSX&D=bp;CWmLeEi2Hv$r8AsWr-$EC5(d8Cq1Ji1
zM(_iP)a9x#*WJqsJX|p-JxV?-<BGr=NA`h2VJsJZC at 0oISk^v%VQ!psERgk~_fIZt
zoQEhT)wjsR7#DROGhUzhxcDjFkC%a`ZN!x%rp-e-Qs9- at b-wEQ*tc=v;uLvoWJJqI
zBu%cvZJtYHD9(|~T|+XekH(?ykof~-BK3%jP|}2F23PiF1-~S1Z~zBF*^@KCRnwwt
zJmZ-4bnMJ7<#GZ8T$7!*3NA at e04MHLr#u7iRn!rZszRg_q$!^qdSVI^?QLL2%QaJQ
zGC2x7;+96pTEu(}ZX`K_ah@(bH|)L;_Op4_Jlt%hXgK1f>3F}ub3e<Kku)JM5F$A>
zL`sY8B;zn2o+t-b{>+Wi<0deEMM*tm8^PwC#@GCtzOpS9Car9TU6{KnaZqG;N8C!(
z_olKHa>=c0w^4e1J)YGUdit*oyGstZA44a|ZNZ^?6_MGZt0r;9tC%c}L6p~dlPhgO
zn`={(nvso*blAJWTG<3|z)2j7VBHM7tu}Ij)-TSWl>*ggbki4$j3lzOHkO)W_;S2z
zt2RFtxFpo6Dq#`)zd(~nHx0x`NRvPR{+)XKZt5}$Yw=Lbc5B6_-B&vqSjV0rqQpIl
zoyg~`>Ds)yBv}i}w{0p!(f2PJ*LqdZ5)$+?m9G!p+7Ns`RQ&3-ZYZ5220AGaU~-n>
zN;X$8dPR3{-LHD-_ZrM`>w|Ggg+dN>os`$B$Ud6wSOM3y8lTQU{S-B8k5jm?y}LzT
zTaikp&}AeY?Nc#o;I$Y1e2k7xm)M-ttxwhION2kgrtvE(CPj=ty(?|~={9v<#jj|5
z5yfVo|7<^wOJ?Za(iSTFS?K)@c5uhPJ=Kazp4m^n1U!0m*mc9-h1bUScWV7(Kqlt#
zVs)9u-A=e}iQThvCHUq_+U|;EJM&!i9rVX=$TB{V?OqLAo=$iNLN+_rv3QhLNUSmo
z6C~Eaqr21oLG;1Nqa_s7MkIH+S8td6m_PC at Qw*4PS=REu??_{so&_S2B>g13bV_PL
zQ8~hC+U1v4c=7dZE=!5)`W}Fm25uh)XB23DTeXGNmR60|9&{|;8Kt5QNu(Q5e6Qv*
zt3utxk_u|+{@k`>5F))NfH0h;M3b7akMNlt*58XOkB!T at NbbDEEdTp!b1eK*A8l}<
zkimLce||g*4j}s6qvepu!Q!3|{;x+2k?EIfU8YkiSH0K7K#z&tO<aycI(Y8dP0fu5
z7LX(2H`u(q^LO!@k2E3&OrzBlS^2Oz(yUs{2ASTgS|DiB(vZDpLFd(`fsd_?&ZofH
ze>tPO+kij!)d$ZrbTby#$GN+2U<mjs>eia}LEJg!`ahX{@ZD9Icx^v>?}(;Xq60K+
z%)g<UKiiAFiN8Kx*#ZtvEn(py#Ln=$ytEGVzf;@UJ{@p^he;NV)f46x at 3h)vg%rV+
zm<4 at zbK}jTlDE#M*UXe-W8X?2r;iUbnjqmkCWZ%@t*lm<OkzUDW;=Wni5kN8Y=tPK
z^hPuA8CQ8bb9E3CEga}%`PyC1$vk>%6jng}p4tKc{*af;TT#^sH#T}l7<zG%GFkU%
zY{KTHelJ3o838>dB+YFkBE~MrNl<el&EsP4r6a^?vgC8&C>d)K*mOFi8r#S0;wa5(
zfPEWTL31M?;QfP-yy<n7pF7NOi7w<eU7D+0kf?v=Yty2*mobCaY`xCpVMKBIT73&c
zwfZ?dMN>hY0_~Zt9zT2tjX9j9upM6ePVv&L%c-U#_T=OCDVMpK#0quS>I8=uCM9J*
zk3_j~_^nR6>--%<t;g-fPE$KN^)}x$^^e81=<u#M&yb<>P8=Ymitnaest7_;8qsL+
zHE&y>;S*pR{po1NyTpf;_xXupNz}Nq!qS`Y#^l4F>t6E9_wc;!jU}<v$~1===i0;W
z5+M-3blUDYM(7%t7Mggu(wwnvpqMpeuI_*kKk$BVk$VKS-$mWs>DfN){~Pqx&UF}c
zx1nJE$_r==^MTO|p#;N1It`vB{e36wb7@%Yn-__1P!XzqLvQSl-)}5<jWzQt`ew6#
z`B~z~#dL6SB+toUfv<|+RD17_#^J~!*w$&}$JvVn=vXB+iWtw6^Yd-{X8Pj-!asX^
zHu0ai%zT*00TJS^khcwCKQbjr?UXLMv%j%-|LHY#6wnv9GZ*qG4vjvCMEbef1|F(%
z8cbVp(XE6|sr({&T#U`)T!;JmrIT7rVuTvZZH^95$*-oqEWPB9d1F^)+uz%5u=im}
zSU9C7wo7aS5S7)ALTh?g(>}FTv+$KOZ**wZY*B4++Cw|dA_)@w%%L5NqBUGN2wdR_
zsYaXbkBXCqgzpg&+pM#~Iz7W&1Y(_(c{;y;lS247m%d~Kao}%!P{i&Kq at fJ8OR4{~
z)C%ZGMi>s&pFscy^5=`ith+IUb+WAb^*Uoi-dHpmyRu+-i at V3TG@$R>5}jHD_`+Dm
zw2pVDTV>HYQ!C#WR;tG`^HUAW#z`lC9Ow#C$=sP4c5&>yqZb#+h1UCMc^+r0${7$x
z907f(2Ye<2$mnZa)hMrXL)w!h?{Ndi1N~^M$2PTMg<zZ;;p#oGa#^%Lt1OvCIfHS@
z-@>ouNesqI4J6Fb-yJv#xl((r5!~%2<t7t!TqA{O0yeg)D5)JOYyF|dNACo8*B&LS
zCl2SZe at Qu$N0B6GNp_RUzu{#1%2wh1d?VHOlhc0(TcTR!itUP}m``CUH~*SKuf4ey
zb(L3vY~eFDuAv)Z+ZJFyR{N2DX}-^sezOC3A>S*+PnLc<8ili)Y#FQkai=tTy~xPd
zS-hjQ?_}m^iJPxIJ#+ps!)7Xq5c*yJC+(S1g1t&S8{V5US+gpKTCbTi2L{3<z at C^~
z;H9alBD2pwRp1fW_P~i-z?Tj(ZBNY*OBMP3=Ede^{0TD0n%15T391HLdERmI*n_St
z3>s=}Hr;DC>kJCq9-EOfl_>gIr`Bd<cmN{fi^(|bS7!*q?>B!9Jzd)a2hF2q{i+B-
zmaX`Hw#l65S at w})1QHv5DSKuqo}^ak+UahNNS;ze79<4T{2kt7(QWXw;?M$TvYG*s
z**Kxef=o7(@4=umB1fv5iz5%Uw4V-SnNEE_C<T&N&5C=%>zk~L#{5jL9mVv#7p3dR
zYgHdT+0Be5MS0Ze3*O>=n0V?f^vi0}*P3#Ru_HkH<$9Jzn3inkH%yk~lV_V>LWudF
zA#*G<1?bjHdfaA>Zbws1e(j%MUQI3E(#QH{YdGGY#_XJm6}-C|8v!2pj^0VoX=v5c
z&`pZ0+M~%GW7Zhp77P|bCE{W=iZvV?C`(k=d?rVXQ at oT#!5&V$4|+>src$h- at I~X?
z{1wH7LyOz(uRpxw4gJwu09uUiCQAb^mqf%e>K21VQ_4SOhJV$(PYU;5ZJG~txPMQ_
z)(GBcl0N+BXfl at H1xnT90e}!+B{Y7hB)hxcZ?aTodQERpmb8Uw;md at 5BX*R&13lY^
zm%6l60}0szqwx3q&kqrcP}PUk#vi<5_H)`|G#K{QocH%)t8Srj^B8+e3of}n*<C-a
zYtZVw3$YT4=GyuffT+RyFsWs4J~X0&yZj;%t-)1g=hPz1{;Ydg2R$Ez8*4r+K?;%5
zSo6c<m+Q}u*<y{;+h?- at +t}@X$2z{RHm_csjMz_|wS7tT()1~-DT=#?WHp>Yyk-j3
zuv25GlG0thm*x`$q(Hl}M|#(SueXBHSG#66{@>lDqjowNmgEdp4oI-^X*H=eXX?as
z7r@&ZnomEML0&Esy_dDPQhmRwgZwD?;lQ6xeg>Ur4O!na7X|tO{<;t at b`;B)bjQz<
zzWlZG%(J;=uStFWRu4f~yi4^tWS3uem4<q#+eG(cVzr3!+FDGkf_aBnW!g>3e{%sf
z^&OX8^0v6&=)P&)vXRO=PgLWR3G;;XkF%?y at T#vUH5^X+;-4-1HUwA2K+^TlZ^Zo5
zZ at zWfAEK=~*cyXyeIY9I)l4-8{)Q}%hGAKL#iaHPlswHQg10K!xZ)d;^Cr_vS}hoQ
zBZTK{P20%pY6DqH9_$AFrGw+qKMy=c=>V}@xvocy(;L+fJ9%G{Y?MV!lm5%GVk+CN
zHI~BW3A<R*GYMhn<LFACF7P|3oCRZ))CwO*YGUQiOo at 750<Vc_pi%+u$mqH0N3*=i
z-mcIY((X6}%7LkYj+rTFy(<t^Hdta{0q$%BXh}=&!w1RhcXXn+?tkx=<s+7f6l0Z(
z^fbw3u66xn75whmW2Ga}pGIq<<fB1F5H1jJB75R<hvaelBvrAp3EoHd?=)yNSXv7f
z8RPxw8i=McuxsCW!ni_fo;L;Bj+;>MzOrAoq<+Ev$=mY`L6}ghv!VMYV2|o02Gs2R
z;zBA3o$6WHdj at 2RUU9Uy1lG&S9wa8b#P$6{b at uO1@-#rWAOb^rWhhsmE9myvVZmU&
z!@U5DO?qXOYsIvdYJjBJSqRnROLiL<^Pb75aobHz`jN-uqp`pfy5zIVhj0}kOcd6l
z>Fdi2d_|i2?>PIZp^`s|s;@tNIDN1;Hw$vyH~9<Hp)D({%WPs%$ljl2ncSM`RZI at M
zB#uL4&(>yJYHIzV<|gC&FxCpun??Kt)@k&ss{W$g`~m=uqV6e5B&eY!@!rJmaV5V@
zr+9a(hh at yBSm5!h23=y~;0GWCUeVvFk%IYrVCpoqaNx#EMN*mkAM-aqd16>!>a)~f
zgN*-+1p}r&@q>@&@5sb?nZ3$a>YcM4UkFJ0wCg!-44p4Z&vtjI<Q#fH6>0kEU$ixi
zwtKsVr5QksAZZ;U7*H$L;Zu#Y5q-~E)V+3Do$lfd9hVj3_l_Qp(SJs=-47MBW$j6a
z(=qST5xiKmn|w+JRD15m>)jQ=lX30P>$f=OyrOot(R(}m1&yBG_yyiNiCzH;r0=}O
zmi1ROZ1}QMqQgaK%S=lD8s?fUUM`M+7$ZWaD2778D(`-%GrCVF*0LyZzsaRn?MnM#
zzt#$v$+ZG4Hd6mOh4}B~JRmfb1Y_cqT*?sT>#yLv>I0!wyl#*oYDf~|)}DmH9DqEN
z&Hz)UX?|YfLfk at JCTT7(W=l=;P0EFyHLK5fk+~?nDfz+r%5KuKd5&{kSmN^_t_7^d
zlQ=>1%s4REwEuMO at N>;;Gz&<gWO6dOz^<@7vnI{g*AIY<oCd}cYP+(@3hc0%rbOZ$
zQa-Q~up!}Zrmc}rrMN>$yl5slY*Bo<wVH*D>rvrKh#wKR=T72Y70 at qd{jg6B|CHI%
zUMyulES*4Tf#hP4S4XHyiT=lXGGe=eLhz?0N(vs1*x7M@)6Y&WM<9K5IHBe~(m&O7
zNp?MlO8+Y7R>Al6I{az_Y$xTFIKq5@$~ukM{1#g%h``DJ9NqpkDP;;Za%X1q)1R_F
zeMu>dLy|FASD`g8sA^{(U4NOo??<X#c#$avc2eFpv~Jc|&>NVtdGCW1Sjij=G;7tN
z^*fDEFtb8(aw1T`$+W=v(6_H$@=HRuZI&7430Jx4YT{M1hgIl1_*U+tIEoxv3phs-
zp>a?GfTa1l8N_y+=|cAuV)RK~4Rp=hol!<&coJQ82h%6pDdB^*oGqx1GMPTw7~py3
z5L6HJtV=xXv}T~{18ZZ68a`wJ;(|Lqo$BSdz{@L-@~TUv0gLl6?)RpPxOnxz`JMv)
zIJ#%$|3QI?E@$*O(qz$Z#ct*>e|gob`^)_DUpG@>npg(@w1<)wI(<LN4E`q6FtVQU
z$=pOVT)FT!1NeIh-R$6Heetgh^zPFZGv#i&2FvgdG-J<EJrmAXuQPh#$X&T5f*Q`G
zP|rx^kdl-SG#V@@+6z{jKo=CPef-rTaeaAp at 1Mea$g}{HBK(wZqPo{s>3~}b^PR~4
zp?CAGPVA<^{2hOV3`h0 at f495E8uwZ~>^2}YSpMcAV$gp9t>B>`e!;nwI>EX%$ib9?
z@(M=614s)g9iga5ahWDz^v_6S9S^H3nq#vnE9t%wG$hCa(-_GN5!$NX7$ozUFf04J
z&Zx)=v-x4Rib(M`1vBjidDHzF7m|znT)P<kLrUryS=5;ZX`J`rkXnN0mTbZ7;7rwE
z%i0V2C$#i4EBtruh^r4(s}qL0#Am8o$9;9}Qn42vlLx6~w#l1a9!%agJa;rejRxC^
z6QNVRZ^KsmqC8Z!YCrZ_z<V|ZDm**xIifOla^OXJ%5pkNPaJ3p1<?=vu_6QZ(-Eip
z<?;yi8Rru&FYLme$>Vn<uG-37UozI1+3+;nZJ|0R(+-waQ3-*wZ9mmg=%zKZAK^4w
zGw5!%+DN&aO$pSFvyUXWHVPia6I8YSQ%~aO2b}9C?Hdv!`>6XA#Fq8=(2CWl>;1)M
zaZ$u_>kvNx(3$;-L`I=$!#!kYV?AHHg|9t|d3XshTX?X*WWbFi1n6~my{~pKWEUf~
zNN1R8DNgY$cd%yN5B+_IFWQ6O_upe-#~BNouXHb49WX65<aR8kkIzb~z*>hBFbqy=
zmAFh$Rh>1@`mOkjmC`Te^lqqb at 5=&K0|+O)qpCWDxH5UmdZgq8vPwis<xPzF?o08|
zk78 at D&rH2l^FBsXV<y?{U`t$T8P}RoL-vQ1#XAN@<kzYy!Vub5+RyiqRdHE7lU`ZC
zloIGI4YufLn|6z)(s&q<tDPPLf*p)=u8!v`T&6-+1b3A);}ZAx+Qug{Mlb5=dwI<p
zJo%7iCWN`<Rr^`9;Tpj~Zg&)(KK#!huJmmizHZ3GTcTNv_7ixx9C>t>IN0GEK;2P^
z4}HYvxi+-11Fp-~clwoV7UZ{>95ToOH?yc4g>`*YAfGddZQlIQA=E1WoYyL}L>KHt
zCZ4cQI}Xbm!U2U+KX04RE+WAU<WW%2;Q;ewC;MigqoeIIalJ>ecMR^vb$=m%V$I^P
zgZW2400OYAbns(sKy1O4s%}@ucFW%UEAo!B9BqlFE<-3 at g0(Wbt`pDEek)g)P~S|i
z^thw`jZal^2&*8UicHtsyhXaQS>7aUr{K&3sUnWhYbB4zXN;$DTI!{FqKitjMj#UI
zYNUZPb-=xj>xz5G?)(TlEe^RiYQ(!~bZSrLuqB$^IarT_HhvKYNVFyshjq_zHSOp9
zRI1+v3z<GAg**<zI<7Ai7zzj;y_-=+p9JEtFPmdyUmybwU0QFD!l(E5^C`gWUI^}?
zIIUF=q_DG^RIT4oYUvw<Nz{<hj6GsqZPZ)j>?jAT=Ip7l=8}w+O7XT#`mi5w->ei+
zZu(aC1B>&)=Q+}(KcW at 6F9d=+<-GYd=-ip)0n+0}waVi4j9A5r7olnEWV<janIM*J
zmepy0o-E$`_1T^=wld0uIH8W!*`r$3yWI022pxCRks#FF=UfflTi|^AYrBE1h7D*Y
z-gmg?E9+~Lo(9`_@<QtmFg+kUuByNV=~ctoDi8)fa@)&R?(MjZhv1P`SnL+K*l8Mq
zG@*Oo-4!E^Ay|Vo+&MpzFI5i31M6w2(f+aP07O9aCEbQMxkeG(xKX+sak(}<-KRtR
z;}#!7cegV3cEY(VerzO5DJ)hdx~z-nble^xkfNp<eCV)jYv~7X&2ZXluOu>{(^PN6
zn#$a;9=*T4hcSe)^4mUfNd|COwH}<_HbC_D_py2 at 2;)<3u~c*t#23?36yIwGzK<a^
z%sI$fz|M6{;D(^se-WiWEGo;wf4x at 76bqKC75_gA@FH{oTH$+x)=`tm_?%W#={_ke
zZ1)Wo9{bj^F+svJ(LH~MrWx2wINI7AS_pO<bgl*Cb`JikUHGG_a$<BMBNFyp>hUsF
zAqpvfj)o!f%JsO=JmJW9z_RqbYTmx1aIeWt9eyvfZin~`AR%}c(NbTyWL!H=Ja at 1}
z35PW<l^q`Oe9TPowXGf~zcH6}J6Sr)5}pCE$X6w5PVY+>XW*~!<aEh8pK|-^Y06;J
zUU`-Y0poQ;+}zntKl=@A;`DdP&An*uQpM$c|6)59Xjxw?`MDv~qx_rxaO9{Q+eqH6
zuTe(0UOacLJF|{Df|^)dr*`n-r7pKg9<X>q6YLUkq#H66E;E|*fb}&8a(n|DyP=P=
z&c%3?y at e03gD{F0ZR8r(z8XUdqnvNIJ at U~ujp-KRB`?mY$d=VbE0%1Y6adwN+mL!q
z*0VGbPX28h at VNti4THh#0|GEIkLW_ez7pj7TxM7nXW)LpIBBo^AoDxlsX}jk%CMv0
zlTtu?KCJcG2?L6>$8LMsx^%ACC%*084~cu&4C!7givSkB5o~k}=C|iSdOv1(8_EQ$
z_X=(M<Jy at YXU>`Ekn&$#e9~QLV>IZKbMQ5!%HLY<kBVg at 5K))V7}{u=st0;1hl(rr
zG%R4}JHODr#gD$j$~%4)AWU#rKF)vyA-K~CvZlw7rkCpNZY4{>yDA&Y)}_)u>8R at _
zF*+FsmBAY}+XZM9UNQGBsZ&B7mm>|cmArkuCdlmY^60Dg=1C=$p8g|sjq20SKW&RB
zo`b{oGO8u?KWW=LMu9|Ir at uE7J4<@?zgX4pKgyECK5iu!^%8mNY<A(Ye7u-kHJS!8
zc4cQ~J5JV*=<CD}0RnQeJZ3;K8NTDwti0Hf!c;VP(NR6~lv(dzWaTaE!?AM!g?jLB
zPyJCuO18S8Q9+Lw1N5?GxLi#g{D9|OJ{QK~T<bVn>;>H}AF-u5G^i7x;xBz;Z!C5*
zo3DAY(ElatrC|3pAGmH<$p)pxFEy(Og0S~qJb?RD?=^o&S`K*^Xj8F3S5QSc_c?LX
z at 7}z{7>smE at Vq;Pw%Y9PRD6~5uU7y7%LOWDU=Rgg`8=**u<|+mgvULWgQH at Uj@fS(
zpr;3t5*%KV288rUdQ|uL{|H7|@oFrT-JjvhQb{H>>roHyliv-6 at a9gnXc9#yYxzBw
zE-71<^-Nyr(AqCmNfn at RU&eR-BQScM<6VFupPo+1SA}9Wr*4}29{#y0Cv#U1K{Yw!
z&ux;OO>g8SjV}31=Q<W1&*m%1w`F=pX=?Cr736587Pz1aj(&k?hSVH|u13;x=B!8u
z_SLS0+r*BBPPRE?daah at +U~x)31T0)klH@?;+#+UCeGxQx1KuRcWGNY6PS-jQanX?
zgWk><9O52a7a-c1AFh>M1t^pgZ at r}R3GB)b_2BqjTF at FEzP#KWAkA6+6%<7}{AqqA
zO(^N9H2jSylh<T(aB&E9x{%~e)k3CYeIPQ$;uF%>`gYk8Lh>Ut0J~hELYd-jx8XN;
zYq7)0XRh>ZdK5T60Xoe*5olahjGH=h;eE&=RxSB{{f&EW<QA8YTB{Fcj;`k+M9Ukx
z)m{2&Cj*Ke`s3p4%x6ON<04Q(tI58xabD6WS9qWr;)*fi+JXQvAVllTb68e*-%fIJ
zvba$fx*lHzv~E4PS1KqzGaG=zPSkhK8-44fO*(~{zKRh(l!}ela*XbyAPv`8XsDiJ
z>{L{k4#4c$x7V)l|IkM-ScjEnAP at U}YuAtix4`70m?S!W*Ojz4j!{?5E2XLX4+g9a
zFgA3kxXZHU)z!0LaPrZSCrjt(0S0K$!Un7tT2PU^=&<rX#qCxJQittaBGbb8Dqzz<
zG8r~<+D{<H1&m{{YD)+WQZtH{OVvYfXS!gR*+ro!`-#McHc_ at vEyZ=isFXays+IM)
z at 7VZl#AxL}Z{br`oV|7p_kd5UUgeleq|TQsq+@=^&5xL8&lLZto#C!G=*aF_c6EgC
zu}rYIhbshHrR}9Bwz|sbtes=b8$QCf+0Aty4U24+qg<C_%?dn{=e7=60Q&gxzPjPZ
zMc?hzdNteImEXTGKjdOL9g!SdgwFO>?&zRcMjgL%+b<4(aJxq!wi9E;L$fAK6fe;2
zh33s!6!9<uQyWriOG0<QLGO`-ln$oFzM)y>OPK2`KbqViBqm%IQ8O^hwNL(VTKE#f
zQq4 at g>%UXTc4O1osaQ at wH>e=M)aWLt7rCVmSI5%M9vpq4lIMNvk3If(5>pmRZrSUc
zH_Z<Vb<E$HKZ6T30>!5T)0hmJ0qD#PKKKUvL=kds#TrVwTKia&lJx59M&Z6XFM8j_
z<yfv|J11%M_EIw2Zd4!W$UiGGO%v|aX%_x|RZBhxw=(o#0YHdsWj}kq$X2oFGZc%z
zavIsgsg=yCfgq`)1X!90nMfs+`eXjcyR3aTTfis{(RdETfkTjpDEPi~WFS*Gh;av0
zO=V6X_63lmTUoxjZe~E26IaDKXwiAdVTgc{z*wd7 at d%)X<#*0b_I^$^DBU5mpqA1X
zK6v1Ju6UHs-zc4~cVKq at 6Eh-{VspLk8Vtp2M|<O__*BN_HIT29)FEunq#kNk?I!JW
z8u2 at _&r9vUcBy*t>xRXyI45rj%LId^&+z}C$4$SymAy=6kgkO73Rya2SAKh;tyOHO
z3+pLPW6$<0Tp!9`60TI&tMIKPJ~QMMyrHt7nL3lTz>8@%2hd8pePunq_nAw?%gIsc
zjZlZ9PUeZDRcCv#?HAvGAKm!nU0r7q9bfS2DL_Z#?q(GERtI%t(&>9hR=8u~g44UR
z%Xb(k-m35Yb}u9SA^ax)uzWJQrvl-6cHSn4DzJb_J3Y|<R7#QC_XN at Gb(_C>IIy17
z3OXuZ2w?}6Kjf$E0K`$cR$I$)!R$g$2D!h~9k{B*4{Z;f3qSo$twX&aTA>>(Bq(U!
zAn8WA#(S at 6%=w#%MsC`Z2iQ)7-y%El9AbwC>H@#%t=t{+1 at joENbL4TPTQqR7gr!o
zxU81H-<ThWK*XMM<}g(pq}__-p%_|~^`=oBDwLAj>9v7sPS>#dO0|&63Zv)lr!XK?
z-eJ(ZDeXO`P--;2cskM56*f4S+d?mte%LE}1;zc7yG%Z1^e9;)wz<h04GySB at T^Sq
zhbIIp*hg^8qd2H?=`v)Z(je)=a|Va%(~oNL{hLa;Rq;)ylnh*N46>-xX{EZ)(s_m(
z_omEm^kd{!93_2Db2-1wUT*(ebrDjSYJ##4%XA{exTEyDL;2UODH+p0Ljrn(e9|+M
z%{Q&*_B*svr+lq)fBIVWXefx|P7m(DsB}fC*_;>x6Ko*bALJAg+XL9Dk^EkAvKvAi
z(9(?T{AoQiu&gnK*KJh^S8LzF at 8^4M*DiZY@`^%1)|`F4H-Kd2flcl-RrOuKeH}&E
zeyeO~qRbRSG at Yy3F>R?d>7}yD%@Ue4xLy*P1sh=Ff^nxj3Trg|`eCrTM!MMW>O2xE
z+K3qXHRD at D)#H7CLuzVE!FNiEwwpL9QI_;BtvlXC;tk>l8##QC at w_R18x){-=_-r)
zRC31bvQYZT?XKt=cPEeiBC!iDD%p}|eulvf=snI!xOeY1sH$JgfXuk5L!|hU$6bVT
zS{%UvO=lo-XweLeJ9Q<H)d|FDfI>W#cFsuo_9PPA!);^wXoMBoS}@FFk5`2=^LtRw
z91*BX at QSEMsJCU1*!`E|*}}K6wy(k9aKJ87e%RYsDsOrI4Jb0{b${STMfw-c`Tjm>
zhq%Eb>Fyn?*C@$7qXt>J<1~2b7v!8}IKMShCsbA<#c8<Ow<2WRx=lDQFLFian<%&p
zJ5 at inEhZBJPdYNucFhg<xt5maKp at PnVyQnu!3ej!mO83@%npF at _pNkPrb0(y0HWHf
zVcenq=yMzWyDH(W6I%@zY^}U0jeKd^@>(A{hQLm?D|86rhLSfN?&Aqo7JQNZU$TRt
z>|MCXN{7G=Ct<&@SLJ99o;JLn^jzuS2@~v;$jMUSWxm1!I@`}r63E8`w2M1DuYhfL
zhaQ&f1D>jHcHuVf?P=29ve^))+&uM+{CW9K-3f|K?RVca7*A?SmdfZt!3eqys+VRZ
z$t$zfW-Dz!lDjg}mx1wt!bscgHuPO%#J#^msxJSvi2?BD2bZ~PuKO&KQT5X6^`$ba
ze?QDA4!T8eur`q1rf+cSEC<SHrt96de>mB_{`El@>t~6f_!$*bY16)f#XvO9t8ARl
zJaT~brKs4+of=Kf-wS-`HeL|pbgcf}yt@;oHf3Mn5_|Qs$G;2->tUKqG4Q+KQYB_{
zNg=Mu`QHvmttM at vIM_%>`X~Xy0oue0?!fi^x2in^x&B|iHxS^A{Y5S{!>pZOzjh8U
zY#4yDg+5=JwC$wQ=Fb`89&SxoXBHWWG+Am?nV->t_o~jjI-97S%f$l%`zq6fD%1C~
zBEwcC+UID??);NCIv`z$VR44M(mxu4De{lHh`on1UrSM at yE73Baxu(s(nfzK(4Qt;
zgJEc0(*sFRrbCcxEU&dVUp3O1 at jbIsb<|&p^uM#LI!&sziqG)?>a_Js+Wxfzv+=Wb
z|I8`%skM$EI}azP_klomTI3Raem&cHeM(WD$!7m1Cj)8w_b39&hCHhHDEdqXVwi$u
zrDB?zHgK{m%rePycM{|46wKyq2y!e|2nl$B-EMz!Oos~n$>W)l=RWh^L`G<~ah|iG
zBWfXSV1^xAhvs;-UAHOllsC)Z*07q+$2UV?6!MgdBVstpUVPJE_<j~U`7=4S^`&2b
zy1dHO3Y6N68bY>Rrdh*Z8NS$-1$Go9I(v>)3(wcx)F2uc^+uD at Nm)!5?#$C#1l($U
zDCNa1+wKwt6rdRQbjkkP>FskFa~pIa#}I;*C-rmxl$7f<+QK;u_(BN-JA(`MRR<5;
zT!m*jq1f5y&AnEAgE`MLjqJ3GieYn>WW|Z6w4V(oPXyLgiH!g9m at glfpsG<LXPf^{
zM4vsVA*`Pl2`ZYq>H{6eXHwjfl?OehXZ3^4x*`c8_NPhjS<=;_*xnY)#F9AaCLw at b
zm7m9l4AnV5vs!IdhJ<NVo%9-d7R-1ep?2z0rE4z31)oIeA_7v!_b(&c_gN*0;4HpP
zezt50IK3G-7w>RcaeX(JpOgPizJWG|H(qWXcAo{F at I87}68<&Y)r`Y1NM+x6o5!V`
z2nW12-(#%z`}NiaZ-e(vP|j`-vg}t(Fuw}n`M{;ZcO7&z_!8=TS4Oz!Sf9j9Vrwj<
z7PvvLd;#T%|6asaPiCX4-hF#2gI~Ji*8$$IKw!CO76VT)!^wmaZA)dg%v8Y7nzBmi
z-!yZwDk+X-u~kO01C37$-@`SkH*Gm((CQG}zu^17K<pdg580$-^-MV6*T3d9<cUhP
zh@(%kOruvBtH!&nQ+_X;pA*DYm0GrDbZ-Jt at Fj$d9xRWm=!EC1oAasg;`w8BgPsu@
zci~DsV$JOo9Zk~re)f)Y`>uv}`Shf<fJYzC)ev+stnskUchl&%aiNHpW$n-7%u<a+
zlH=vAGS7o8n#?%8aRZ*tIbVF{t&f%&Qi(2m$YImtS6A`@=BnORPjtNq60WGA5!w5?
z`3z59 at kdX{+mBbXf*BpvP7sQ2>1)2 at ju&%f#$mBTChaoN@!l{93exhXwh!Xs?b?<~
zqSPXQ;W|zkd8KpuXKS~H4;_pjbBR(hmZsfDx;lR`J3T55$YC5}E0C8If$8jHuJE`A
z1um=P>n&khbTKRByHd1tPT2Vlqqr at C_r)W3{N-jy`^hVoGb*FrzDlq^SL12|?@Y at s
z2R1hHo~Rq3pMQ-MUvu22YO9{wqB{;sWuyP at Xu;joa)(ZecJ_5M?90U^E%P#+cQDRL
z+Km25*>~M$d#0}k>0*kZ6MMFqclFGF-&}Rx;JjODyDclkm?|a0b~L#{{Mb|v;7_c(
z+Oy3Lnb}=UVAnx{7&cSK0kC~B*PD(fsEj)dz;s*;ELW#p1MczUU6g4_Q+0m1J!)l(
zmbZakAF&%b2@`HlSzy}*p1`PRU4hJ6Vn6XWyn{+IP96M1y~r8F!Mf;MBYOrou*Gjj
zU1V|!nO_47dxvtM-Ou*@_r**HE%CBA{%IuaBGuWbDWlAUVE>tuVv}ZD3%S}1{9OF0
zzfERUxdT_8wPU at k$aeerJEpe>?o0p^k~cKtF1cUL);=RJ><4n+P9LORLJa+ERUeT`
zJ``P*W!)PK%r^;G)gKP_|KW<-ZJb=YPIYQV3Z)xu_JK^6#5?r;s+@^-P;*~QuquU{
zQKu1a_ta-k7Q&-58gPvKO?6W;)m-xT%GNBU*SM~yC+rZYe|pMAJMXUw#B20orsM^z
zR`XY)VWo1No#3B&J2|gjNJbDWeXbTh=<UCSoY)mBkKkaPUFcgJ7Ei4jaluf+$`aqa
zI53h=^}Qwl5No1q?Mr2yuHBsP at -t7p&La>mU#Ft;bO=`|*fQ8sR7dqHtr_+BWA{l5
z-@~$q77;|h<J(TzICS%*cIfzw!!+3W;;;A(&|`^=WFZ+knz(j_MFk4c0ZBo at Lpx6Z
zm$Aft)1;6UMaqh5u7>X|)nn^g+~z~R*fZ~T at E}#@G6d4fCQRdVU|k$Iz6?2!JpxAI
z$IZang307HXql=P=mOX?sW(Ts!5E~>Av{1*MkPIn3Ak~snj!@ORh=*-<(u(qz=muK
zW7JJZ?7(FWdJ)6UBV@)~TCd-fJ%Ui|I7+$dIM`~JeEI3hB)@-c^gYeZ#aWk at M#^Rh
zSe6{hkN9JL?N62)>G4ZolADw8_#+9P9S5Gkb1$c7<ZCb7TS7mq+f$GAIh at M^e&7m`
zS7|byVB;uE8Hbb#^oxvJ8Vgg<u30csyQ;`sduZB_8nwH2RS)ZcPEf<(Uv&9-f-T72
z5mitlvzi7g8~V?_4sB!M=eT~;!oQ^N|B6Q20RGm}P>Uu{=!DKFuGtE`R6AZBNN4HH
zF19Fcj8L06`&_nA1JGozLgn8bg^WO}p=D1)vIZmTo3T5olx+|L^y0D=0lT0fL7{U$
zBa)!2Oeu9QG9fYe=a5$25^dm%D!G_@*&df1FWW-T2?o1<^|HCXDH}4^wodj~qDb)K
zN6G!r%{qihNHrP=*rim&tXs%)7n!bnt<)$6_po7C;M}?CAEpa+6DYll>p~rT+Ai9}
z*m$8$rd6jUhOxVSu9UtsQqhXT?Nm>#*`aP>8d at 9jdpNURYibu(TC(`S=I&zeTD}2a
zzuybH9TTCWDoYVug8OQA=>`&;SHS&x5lCtIvxVmVJ%%Qqiq}DrcT5d(<h1{jN++cK
zPHIO*Tur<O)J^^){gd35c>B5=KTBHJp$8SC9`B~%IokNeA<qOnL)iJCrt&zX!rF|Y
zwE*>GB_gxtXy_Xps4AGMHw9L!wn9|k8k{f#8BcjrXAm%wHsScXgLwGz^xxrw7i|i_
zj47!nuaMz#?a4{HzY*3*ikRvLBj5r6NgS%RU5*qlwBQEi2}GKNu_kg&mXa5?gyH7W
zNIP(uDv<)SeuGHK&lJpue`%$T>|}-I!xBALf;%@u0u<n#-=>WbmHCpYqxiEb=M-L7
z&6Ym-9!2L>t;OThcpciS1#z{Z>!ajOB>vxLIa>zMX`rd&U9LOaUm60;DYm^2L`N#Z
zLfu9J*;SU=5=DQR%C|kLv&9{^C-+}0>$I=Ky7uRz^fw~_^sFmSLB?45#lq!}q6D(~
zNGL1SZ>mbc>^Z2tXKptSe&y?fXXvq|H5gZd*n^EC*BEJyofE)J*F1b at ezV8p2Z`HU
ztZ|RCUq0^F!Jo?dFRP9_PR=CH%w*~eFK!9{3{~0tAh^YqB?0F!ta2F#i&F1yJ at O+i
z*Cdm+U3<>R%`afwn7qZ*P@!E{_D<GwO^>qB<tIJJa62p;0IZcAP>sPWPp-B<)xUmT
zY(v!@@1xNqDwbHmrc at lkNjkp9a21s7kz5qd<<;=y180$PbRz|olpZ{r*4<*EZ&vE4
zd9l8+^%AyYnSZaH980J8;pV3EYOz!HkGiVJ$#d*+*Xc$jFQxHXt?crhnSx;}zZLze
zH`d&;!jXi at KA*zFe1l;RcOb45&33@$)Fh{Q*UxLjK3d?oEBGm#zVPKb9j9RjDtpkw
z?9k5l+VodX1y)@I61A24{cFO<;at<sm^AtSooA$%04#FxPk<3kZh38D%5KQ~cj#Z>
z5sQ5Z9LC4(o87hTcQPf5S&pe&mDeNLy%|p}CXlE*KG<oi6;E4zvqJ8KRkhKoB{t~{
z(O;DVA&xpXd9u*(QIBiBpUO;ck0wRLP7b#38d9T0ADmsjc{-OVn)T4Nn#*9Y72drv
z^*Sr<sZ6B!5g`{UpzElCQnS+K5L9oC{R5=j#C_o=AObO9H{2uC#Uec`w&#>#r)v7D
zKC^r|_mo}x&kt!xHI1amrV<;D=D)wf^KRAw7|Sxi3}A12E!3XWy!y6q<`L#^6EP&H
zLGtyv3e-E-+Fy7OQ(<3VyJLjtTixddI!r}+EIaeo$GJgvwC2OvCl(3Ar6d;4N|))U
zL{m!DWtJqoQxEn(-}YGnPd6%-i at g|)<b4fWg=lyXbc|UP)g`1$`L>?r7{jqgy4q9Z
zjw%}7A{A-+QMA#TcBv8UR5F=TCN}!fgpAVCb^M3EnS6y7IHwDF-7{@<1Q at X#Pp?X>
zUz5IW&?b;fYpz$>&BQV_tWe at q=ve+AV$L2BFvR_ieL1x0MPTl8u$?xGJPq>$e_7wq
zQsrJp?fOQ>GswJ}^bPFRG`GV25|-hMf&0(6%~U7P|6IdG_^oQ`LVpV7I%mzZ;WZpi
zQaRtfou<Gnl;>D!+fdqz7YiXkM;lxwmrOJ(7w5n3O9%H at V@;d=#)p4~R;fx;t!0+@
zJ|0>Y`mNoh{WtVB#H7*IW=r27>nB(77JU;ZQ-w$)vH>W7{#W(Mlv<D4Xf>(dqOcg8
zU#IMZ^w73l?+xTpvboH;y2^Tt3IIq9M|^*$+Ym$Ti{~A>UqVG7<huuc{MR58^|R9;
zDmEmuC+=VjQDe=doIWM_+tX}NdU3(Y8JzQQM*rMKx<tN$Zr21M3fddN`cyw|>(n8=
zmpvLDSqnjSB5N)Nc=Y^j^nqDk at Fua%wa%lc%iQkH%z?z=Uk#;X^%x}&lZ-6!`5D`O
z={A8CTa=A$yVZ3cwXAojGF at 6xVvzGa8J!~&eIkyO`b&G<xG>nDPt6|{#wPS?BEN=W
zOEnAMdNhPLJ$>}Bso7WikWz~q^WZT+GvQ6^H*ncI%ZhKFVXo{SZj9kLsmMT*-vY>`
z4 at hLWt=|Os<Q~s344(tN?TKXb at K4Fv;c~(De$QtK#%qt<X1j|k%J~0+rFZ4yd%g6T
zRGf~;Bcgw>V)<V4Z-dinsi6KAbA6t|JE?*ml^%s_hO7uO_SRcX*_~D%vL(EC`lJ at E
zO=5-3_on3bs(ph=DSt$w1PX?hAV;AVk;9)R7Qata$i#9Lahw~*TSs;C&@N~RF!471
zMg6HyRvIe;L(gbbQCZ8Rd2U}a!>_(s+>%a^?<pHE;3*sztR2nLGUu{bP`gNiT6dRN
z9+AK`#C)F0QXe2Z^40rcmQ6pczJAzpbt9lw#uXA&WkOfAhNSf^T9_Ze-&6*5hKD?r
zjz64bOnSZ0n{)Xh*BX?cK4PXr at Cw-YbllJUth$NCwBdHA<Pt<k=l1Q}Q+vUSB1c=?
zR^yHCD+BtvS9JiUw26r at v8m~oXldE2I1)H`hN`F at m8nhATtgAZ?m>x`F5MN`nU`Jf
z5HSA`AKc~3ACn=*joTxsmS8$y883o=mgz626^a;}V~Fj{*X$yA#!uHEqff(#u~>K%
zSIh)x*xV(BRMntGWldYD(>lZQ1M>Eri at wL-b~UdX4hwd)fvfTI^j|`;QUh$5y{rQi
z&VOc~e@{$cuaqn7*aTMk?dzj4EbDYy7C%e=><lMa!M>d*th at sYvW_-C;Q0va7Y{C-
zxLhmc3M1id5sOgQRUd3z+3FtUrJ|uY9uegi%X)<Sk+}e^vw3tgkG$l+_n)*Wq>6RZ
zZjAlRH&XWwV4M0^gniyqnxh-wBFhhC{(mb_8wEa5zlIs})Cwr;-Tw|sq+mMyyZDz@
z4)J{NDKu8?dFJ>hE=#g_jMP-J+ylm3mc{o^fUK~nAZ43g+*g7o=N4z*2W?dyp!)lH
zcpNMUeAgnphm8V7MaUX>g{*1)7Z at blsm1OtKm<~4vmS{mnh;JrM>bBp>lLmIEL24B
zt?wT|<lIzd&)~hA51zf0QLq1p_r!jCfO$DEdNl7d=(=*y?qfzAY$T{dP#D-8u3RGa
zg8iLE?Zs*QA*lilNqLuZD+%VA##lp&_xfP`X{Mm0SbCYnB)`~se7cX>qjv!L&Q$M@
zWVp_R`aoVc=h`{%<Pd+^@ZYgvDiA*+Q-wexbd<<8_Nz8KmS(l8a>X?ptFFO0Zop^K
z<=ZIBdtcE#-rZhrd+v0$SEEmily$mriT&BDpn%xR#xRq*sx>R%j`aYOEKOO4zl8s}
z{^u<XsZoPb&0H-*#q?YpoNptfJ+K{{JwRndBB82VFwnc0;>hYBv<{nN3;GZ-R72s>
z2E45j92J#-O&f`pg4tv8^Mu*JnI(_7ec1Mq{7;D=HzYu!vHwHUS%x+F{(V?blu$up
zlp-JlVT6Em>3)iYAT at Fu(!vPo94Ij929Xv;x*N8EBBM*XySpd-+&;(gf6EIv4tDRp
zuIqb!KIaK+RM;q)fmT1hv1<5l#s9JZepYVYuBeTM;(cq5LC}c2 at sC~n!Z7@?pTQ8X
zoXaA4VqDD*ac`luX65fcL*M(b2!@N8MPuqaPvtw8M9n^KRTy1Mq%v%7JMJdf#Y!yG
zJD=r4Zyjyc2kO00TP4hM^_{PYlnv>ruHsXh7~WIf+;Z<&qjT&h`6WhDZ9RBUuWyt2
z)Oz(4Vt6S3w at Z>!JAG{Xa48%@Qnh^?>rhm`MJib4_S8!%SYBIC|CR;eC#d4l)%+f?
zQ{r~c^BT-5%8u&jqHq}J=$oqQD?gRC4FEC)`J<OpyA at RXV7`vbvFEO&V4d%V^Q=Yr
zNU&e7nH@#8iZ3!-IrK$auV!77V<Sz*154$2CuTuOsN={|$kRNQbmQ|4U%xm<;j9EV
zTs+>!oICY5XP?#BQe9-_a}C<>k)21byR#1SS`;QJRIz*l`+Uj`f*HVrh)AnlN<h#O
zCfrZeLlC}b^o9D(k!%93Ax}9}4L?bVg~V5xk^)1fZFHI0`H!N4=;jM~e43l(@l>jf
z(vyU6oN_uLTq6c7HsK7T-8`)C6J|An!j3}zRH)9~*gN+U<s}GNZP(2BdVg at f_(wWl
z{X``&L8MDw9;fF-5F~*0d4)gRlBgd;!ktRVKz at -=-EE<T{WP6!Rw_+}v~Y6wR9$93
zf{FREAXcw!8JR*#@Ms<J^(xrP%G>l>Qwldz<<VzJ+2<K*@2>uT3k at 77uDj^^al$}L
zbpQ;Nt&k8j|49A!aFSa-2fu at NkB3>g{6V7_MD09vQwA|!4=AtmHD(|u!5AYJp%*ZZ
z-ha5^E#w1{w;SJNE2NY>3$b)*vD-7AdSf at -ldJr7B1_l;ni|DCUEe7DclXOfxig==
z9N?Z_3{}Z at -&wl{Al;PVTdnBchRKpi>xem1uIYR)m0~?z7V2;_4z)L8O<7H|G<bIP
zcOi=U%yK<LCIcp(uv6;}mPK5BYq4Q<gTff<VtX{B<ioH;UEfDoyMQG9O-xar0XvQ0
z9M!<dansq(z8HInnJ}r1 at Crx-#B!5Yrd-c`G=NXpDdZ!i&>bhRT^K7PvTCQHY676~
zHfT at _wO;j(;sx7XVMbU`HIR^az&?C2!x`&yjX$Z%56|#M{OGXe!Sfp$#f7P6k$+w(
zRQ_(#*Euoph=-lW4h?@O?jY973Weu-oORaB8K%INN;SqJ1I#RB3cdS)Zua}gbC|n`
z3CwQYsY!RKm5TE~E>1Aui`g7)z{Q22ugMcN_Ug6?(Shg2o=aha_^E{i-^r>9qpb1i
z{2O)D*lRu#jEfrZ>ck7$7XpFOap`#p*+~7#rc?gF_#bezFGm>P9RK9kw|)#?k=OJR
zd(`9iRFuB$hQTsa8jT%eRB0>GRs%|#jys5qB)n{*_tN;6Qt2(j0RkB95L0s>WL8GA
zED$YWJ?>$SduQsLgz at TK72sUdhz!4<vh^YK#%|YE(vxX{W>1bjCn;Cn#J=sMy_FU^
zDQ^N at N=#>_!I$t$MP3Kq(C<;<PZ%v4 at hhO%$4Tx$Eu;!Mkg8?>Uyr#DK5_m(!K++v
zb+%%7A4Z80CGokw6-yP^^6nC at W!bcn1V31itLS_re02{gcn-Ar33yuO_nvsqAXOO+
zL<Jgl3Ec5pjp!JS|7__`;4*%Qr?l0)=Y`)&%2(R(Ioxd07I+3gc1tRQe5%u&lCNqV
z0+)s)9mg%SJ%HW`0%*8B_OwJ9bC|#XQ2;Z56T}Z}=H8|lRhJmbEQH)o4pW#KhkI6t
z5uAF{)MZSLtx5!R_|3(~K%&Ltp;TUV;bEP+6wt`76bT15b||7J|5L4j?5fkd!21+_
zd~0G#$XlL6$l;ye&oUkRK%R;8h5527?Z`!=vfq)&Ga{>k;iC0&9Soh(ct0tj{b(%k
zjX|c2p+K8H7vFy0^FO=g%1O8IJ+_j{LeX-$Vakc`ryFP}%R?O?3hy|$lBPMGFG9GY
zx5+eU1_r*lBIyh%vLFlveEQ1a8e!nCNLlI;OA9Xqt8lJcKA*XlLhm4aQV-d%9mY_*
zJ3lRImD54AY%SZ~fxeITa&6MGnrKl;On8!_+AwCVH#1fRnf}`tc8jGBsoj-E8BApC
z0T9(jN`q^WJGG<cLanZEjdNQ>+vcFHPhDO16XP$rVQ!Zf-i+C3Ij`Y3)ukf4yM?Ls
zR?mW?G=K-rP~L2&YOU%HHi3T!d2&IVF~$SV)#vTK+a*x43At&HJPrQ{2B3p_j{B|V
z#lN4N3%}2NAs?7uU9J8dUVt*L+ezJB-<?K$^-3tK{*o(PaR#`r=*)=;?mm>EiAv4s
zygzc%O8-tLdV|l;)>CVQbnD00V(6GzW$-)m2~xokj8d**mVwt)S>O8`;qDpk&<`|j
zc^j>cB%?!%d5IgZSqt2yk at wab3|L9Pfg^rOf0CSP?bP2Xn9$)RebpNETwlMeUTXU?
zG4|wOr6^%fNk<VSRP<A(0ex_JaTe6F*Fi8M_sky7C~I74eyO79trA>0xfhDF0 at 5kx
zQ&Ei<#}n6Y{RL*JLiu^iJj)W0mCIRCGYOu_l6CctTkAc1gQjYO%|P3Ne2cty#*fn=
z`Ae_~LyHsG0unZ6sn>JJoQdwfqNmKwzw9&yY|%0hGDyR5{r#E+n!8#7G9ymH*^ym(
zD!Nf at ueNRa!XiEgjy*5>ZJ1f_RLp%W-5kb|Fj`2f8xnMWpF`C2$&l2@&hH&lQxgD1
zQFE-vg92Y0AwyIBeX!O^ch49yruMiawqCT;@R3lC1=1HpR2{$j(0l9T@)Gp1z~&fG
zhTXDn5tVIxx&A{P>^s~!Zm-fmU^+g<c-l4ktFmlff1G_SeYi%YZeU({W3pk@{onbX
zrbN(L0S}u7@(DD4(iPy(h)9r=7b|(5&Qamc03p_+{RfS8VqZ(x{p2Ihm{v#TqG}=j
z4`D-S#WLK=7Ab9H={d(8pD8`aWVwn|zLA{vc%AgZmNiwHfVnMS9x2z2y3Pvs6<F
zU;lQL7RHCf5@?$_9N?4$mHz#;zW8XJZlJ-27Cv7_8Lfu>{E!|l#uh}g8k;|zGQdqH
zZpfOmGoe4GpWeKyZtK-EtjJV)rkl8zPTY at m9$%t|Ib_ePMKCaoZKj4@;~lH1mH1rJ
z7I5<B?3<jPuMWKOq|dvWIbSlQ%y4Zy;eo>p{Tq;o=O4<&k2h3xV!A&~=QAanRf~H;
zC>AEpv(9tz1&JN|!^M;3Rd==?nM^|qW{86SM40~-8q<wCHA?D&8ar8?rR^PyhgvLt
zqSE<Zd7QlJa3f~)3^p}lsbF8 at f8*}Yi<MRN0i}fRGVyvFhQEvDij-b>8&aoDRcuia
zu62<;d}|4N5r&<<H|aJ#bR6~Hf&wGS&{s=njoF+u%xxW}zrW&Ef7{elX++cWj;NZF
z_nK*(-jEr^&VJD5S3dJnr`$`kCNJJ(rk}r4Ya$cxp7ttSowMiUj(2*kK4$Q~_qs;Z
zLBcAe9YR~yaMz6jmN?#Qina`Fmt=UHDKOg>W4!}v23p~?F}XioRm#tth6-Y1#eyNB
zCX9O`EEA;T)`O9{7 at N`d{VCfTr37}m>vZGkBUvi&s;OkcU1QWh?}7^aJx~C+o^ttW
z<JWgi6~+pE)3i!-3HJcENlM`enT}kC$C7tdoGan`QBmxQiI$tPzY4rsR0v*)*0iPf
zg^>uv|9;^|7e%nEaZ|rM^t{JdWL6Opc%OyG^OSllzWh2iHeG!NQ!i+)>A*w$F=g?R
zYq-$)B?{NNc{%=6M3{!NvcG?0%|bJACg}-l2EK~1qn;S8t&(GqpX|9D_=2w`v*f=$
z8xwwU#^Hiy%em98cpZZqy4O0>Xr;a~sy<<CjFP3>$pa8xE8`Ufk$H7{hWvovz9=GX
z1ClwF*Cd+WGX0BtL;bgkJ`ha84qNqBIon~L4(BHDaLzZQH94}Pwd+iFel34Q)#O|5
z``J?3 at e58DN(R@>oF=WIs`$dNC5w>cGm7gCeX{uupc=Z(Kj(v-<>tuWc4#x5-$re7
z`@_1nU%l;Lmb-0r6-a=>C}S3YE6%yE%iUh0TMbB2O>noJztE<7N8rmz2}1a8uByL2
z?T=eS&)Az=durZaZ+yn!$7<RB&ThFy9r=VRYJEPj?cItG+FUo`Kb+q!t(^c>sD5!k
z2mxGyA~*y&fj=>tjW3Jmm4}U*?9IEm<m=d8p)t3I(XLebBbI4q4A4 at W<1wz8_3e7W
zWz$4hlR<zKm3eoi+fy5&8(4vAS)DBK5r2)%91LoHI~aLQ_1z3-sg+Ths}Q*-7r>tL
zb-V!F5YO0eDSqjGIp~~aZ*}hP_4q?sgLdeP;0!S(iq5z=9{Fn0nxlNr(z~0|cE)78
zkyS)eeb411E#b_IM;S~UP-HR0WtP68%GS6 at +imB$F`1Mg=;s#e&}Mxq;7w_GobF*T
zh7p~XT&ws~ehCF;pjM-3i-C8-D~VBE^Vvt}+QnJM^4#tZDAc{bS1W9E$JOgeDP21{
zKesC=%FNNdfm6LbUEq<1{Z8>)O@)y7ufK|W?X>_*0C#Y`hc`9iEZd66W+c*B<^~Q2
z3zmdzy1udFsC3_K@(~(EJSj%0SU1&1zZ%*Nltc~M$gYjq(Yj`*^HvvyY>tyN6%bbd
z!{eSw*>TdVUTAN!qNJF9y9+ at U6j|3-mUhUSHJId56c}}D!8K$2 at vvEIc68kwhH39^
zwPQK*@m7jepNHAec&sgMm+hd-?q1#H%Z=YF(ep`@Sh{Hjbpx(At76i6BKKyoN5y18
z)v!KnxGE}o!MpvJ(G7VeQGl$_<MF(Qs+qB$tkP^H;mWyk{mbeMAVdCbweb@<3)fb{
zYslVK9vZVabgELKORR(6qykSxGkR5HI+82L%4p)YM at J)HyuT@<sy9E&WRPcol>=jL
z{?U<o4R7kDG&3O3f{*W87|!zTp(I**;%G7k-{NFpK6I4*2S+EaF8rj7iA9uuxM3_Y
z%HIZWt3EhNTRcLaM%^-C3LnVdlGL9xY6Gal8p{2+Bgz(2i5B}3<)r>$H65@;qK-6y
zhLcNqfJ#ZyA90?oS%g+L*g<^Dw9?|$ADNaD3V+#4Nd>3VRgS(O!lFdl?E8nv-qJ8M
znQ<&+^;0!>!rrAm=#$g-HLin+>GB5##@a8ugdYR!pA3hrLjn$UX;oOF5vpp!GkG^p
zvGDW}#mN53X|u;3D=KV_c77?M%8emLwFj|7%7KwfiOqDYCpy_}HJ=H+ at B#-5$R at 9P
z+*KP^t at kf!yKWFC>B%XFeNyQMG<K<dR1)L__HkCJG_0K?KP8w#;UNH!RPL#LeApYn
zT5J<JNAF6wX7kP?Xktn{6LBx-@)1{ABcibSXBGL=nOYAs)T9pucu*F=`hyFdg4I0E
zWEU_fGmarFFLLbt(?-gc0{Y7qIu5A%JU=N$q8(B}arrMppcA+=<*mZ?%u3~*5z#i7
zZXs-d3jlN$8im>M32<E6h<E(5w)?y(lvCmXdNWM&!TgHBi_+eD8-P&ee8E*UsOE;+
zg;KoHYj?mH508JZ(#+iX_oM_grL~dgs4=d8vrZtUN(EYd)93p}5UpX8o%!3PpC$kx
zuxAJ}n4+Z5bO{Y#eA(8&68o;s8n3+fCB1T=WXb3b2dcf~CR}r?END3=Jlb1%V6JS$
z_hjvZV3N9z{qyofb~p#;*OXWKX<wXLJDeVJ(Tc~qA54U7l#cIhjZq11T-r#q<u_bg
ze~}vo+qcn&HG20ZfAX1Wh5l#jIKv~Q?K-GNqu_h~_x)InxOcP>78pADi1tggW6#69
zgo+|?5RSO{VpYS>tY9HE at ckK8)K>bidAEJ|Eu*z{LGrK;zw?EM)Mi`%SS9B>f-{0`
z|9B;E{m4a`gGhqjO%IA(<=a$pSla8b-+~+gJ*j-=u}6e>;?(6orMM4qUaeO!q`Y&&
z5>tyB+BYo8wn*ucXs4p=uYVk{!SyEwtE{~8GQgN(4+7q308ZV%e=im_XEN#HH1Zqd
z9&Oim4nkMQ8brnaDFHtwTH*{O1G?#QIMd!>TU}{T4Q&jo6`?%fBB)v#rLBlB;rkA7
zH$L=_#=lJfpf&Pbo at sfPicUG|!ADvKzM7aw;5PKIV^bVl<*89-Aj>PxUESYMe;cv|
zckewkXmFSEp5J3EnQ3rt!jV1 at pS4w4yQrjmlOJ@9NM(0l7KBwK&@>F@(TnUx`daQ{
z;UWM3QPx>WCsLADIlv(cni at Jk{$ljq-;h1js;l%K$r5^JFk{?i+V^BGmqSqJyR)g*
z9=4?is%EzfShMuUR@{5v(Up?bK92T9zSgn*s?T4e(`IttM6Pj|$03FcB+b3yFpWD=
zEF%8n(abU0iE41<3{P_(u>9pywy*eO84$bJB-LHeO=5dEenY65c<};vc!9zl5^Zoy
zs&?OMc$OYc<O=k#s-9gjq#0cHQHWMh)zxk!ST$ssN?2nR-#w_zm$q2EPhHHFt0Ix1
z0LcH^D)>f5er2uC&%$Ycr|1t-XbWVs8w5E$m`<2Ga#F5q>eOIsk5pG9ufc8-1mURG
zp1JCP_eW=80?0b;IW;`wK at 4o!Pzo0IQ?W4_D!ni9j)Kf!W$Zzk3RnF1`MF(unAFuH
z-{>ix1UH?FXethFgna^62d#QQ)?|Tej?k0poneXzL4<-tCY&@^n~aFJ5h5!)ehI%N
z$2<PtHY at hM{6xp*<vqAFLvnqy-l^tjI*CzkFy9NeSlqMMpOzl3p_T$$Jz{Tfd(j=*
zqM#`|{&c939sm&;hoSNGw2v`&uNB4Gh#(^qDWem=pDR<n_A|!eyGhXx4r5|)1!bsS
z?s!=3k7&iEMAsCMjZ;!cC{}RJk+a{uLZ)c7d;giP+<-^9ILY<`hAE-crm%Lv+0(+Q
zz;NQoo{u+QX0zGS0&BM_ at UToDuT?76_4+jkIOp2WUkG7-94(5lxk at Z~TUY^^g)$${
zauwqpEJDhY2g6A<{yS8O-`X(Yzk>`)^P%s$39vsD0!%L|4=(^pLQatPn72C9o|6=V
zuCQ(a6VHoxb$6%dsDv7&H<~^~9BhpJ&<{pB{W~qFa_ETGqO}W$9}kIg at b`)4k-sd{
zRj2|gyncgnqX)V-j at hK0QL`wLaX&zMYvH%oKaA>L4#>TIu#7pWFX8`iRIQ!cfgUjb
z<DmmAevV`0!OI5kQWT7-K4Io=X1e)fBN8jVtnEX1E6p;g{_;H$*!$~mY-h2)^f>kT
zWR<y3I~Lhs$A)ICzjogQ!6xk;P32#3U(*WC6iyeF-o5u#tK1DGxI>a)-`t3NM5J1%
zGn{pLcV72^)|1_)&3OAz^>64(+4o*6nhb`I8ciN}okh>bC)T8=T>)0$P`Ngc^u{s2
ztwzFEt8_;0RKB_MKi-KsbBnL-<4YxTQs;{|`rC{4HFoG>lSe8{B_V|x5il?|`4$RP
zuT55WvzO&jr=ug615vNx8EUR!Zw#aQ#b<&-`y~Jz%*WH8XPETM#fc;Nn}$a^I_&`6
zqGGYfd at tk8M>Q(Q@$Jse5fiWs_@*&8DxD&XNPE5Rws-_^%OhLQVnc8e-swE(qx-Mc
zQaPHeSTVPg?$1m3;?I4hLueUxGl?OTJL?bcBD8d*CR6msoe$}Z`}*h-h>Et>Ql&LU
zPrOW at P;;D*vKsL-!BIIjWKWz at BSf&^4T$;MrrNd-825>Ac>keFd$I;)V=PTc_lH#3
z98&M7q6}ajVB+3lLySNfnSgI)a~_P1>;JSd+^TTkD5w3U9{2frMQUTG*?aJS1jiI-
z>3J at 1OzvIc&{BeytRY~gb=nbc4y>YhqXr$#@NO;XMfOh9_cxa8IS-uJv5mI58nZZf
z885p*DVKapjFU at op_M(UcPbiEoOb0?pl>d=aEar3%lP87GxatzRHLb4lg|%1+#;SE
z<VC`tn%T|wX+U$$>0SKf<R6>om0{YqwCZk0*2%1b1;KaoV*XyJ)i-Yt`9UK1*RAXF
z-c$6(xfBT+(e)kNsk+_xz<*nVX97>T;jk!a11M?g>Y$@O^h;^d-y5o at x|%&-y+cR}
zDWglP{G04`l}BzWQ^BR4;@wRg!zKjDt3qHM6tSxf6=oc_6 at 7}HSGr?&a~SCQ=(V)|
z#@;7HpKdl~Y_d_E7_q&Y!S7)E!!L0$_$Ro8AMqP~gUxy7WVXFk<tfN(O$^eB8{qQx
zbGK((%ZEs~4E~<H at 41ItR1M9#Xne7_$yD<%cK+L?9yR6DdMilU9}!8 at 1$2yYDR*W;
zB2XVbo%lyv*p8xgQ9a($EE`WVtXmohN7P1G)fab)eA at SfQq=Uwp^<;yKsJ4R;99X^
z8eL>4uHn_x93 at X2Cq7L!&et8*S&vie;EzsN+D7CXa*t>`FT_U90MHx~`Kt11wU^_p
zkP_P<mu?Jdl!8~ny8p?5RYmZGjC|Xi*Wb!x&=;99;iR22a&TVsAGU9zBg}}G;&jVL
z*Z;iA-r=@Br9JdqrqI1-Z9DX6#h(Q7Gn3#S*PtdT;30GHjW5sxxQiN1gHjnj)^Qo`
zn)swQQ(|84?hvCZTV}w_RmM~$4+IJJUf8NLMfpGFi(CYtiGr6d-OQ{`r_ at C;Htx6+
z)wAqWv$%`xGP}01U>I7I+-av=w1#e6-VgY0_t6(Dh}Q22ntyz+1sezqDpvcj_m&mU
zKm-`xj9$BNaZ;d3-1*=1#cyf_pX;87#DuVsj8)#Q*Qtv`CJdxp;$!yZ&uu~i{Z0om
zkpJfPnZHeFw1v+0<u!t)VlL}%LcD8$V2K)}ttc>EgE~$mPTa&5Jke<}Y7M(;=wRf|
zYRdU{1(%oyO?yJ8W#J<9UD&VK<$M1?Ljf#Dgk0tC`aS~yFSW$02aZ-|QuVpz<Jbdl
z*d%i;_L0_h9!a-xvr)+%d^PgmRjrFAz>c-bUaYmy9)`Ub`(dk9eRorRoc|p-m1x`B
zReXM;;uIQX_i$TZ|4n#3H-uumfg;L*WG5b`Wq-EHk|&cV%4<L;K2s3#aUd5)YD;O8
zQ at EneH(dPv%n47Y!z+?mbuWwdO*iAz1|ns?J2^s{4AC}+$=SINC*WHG9FIYXQ`7(4
zrT-Ofjx7r1#Xhz-stuqeT;Mtf+_5VD;z&Vxvosq!()i4wV1w5+jEyu)cDe0kd3#!p
zS+9$cycaU3ZHM-_%_BPvxq&t8loKnDTIW+tWiTLwDhY6ZYjq?-6wPyzwl_855G<1n
z?sF=cw3^<7Xx<<BB{R8Q{=RG2`6LtyN->OoA>BUUYYNOXXDv7j7(>sWabTbx)z6Lr
z)G at er+bBgPQ96g_o1GzIcYnTAR-aCnVr&0(_?h^bZ7!k=9&>9>voqi*+$)MVI`b+<
z?dTzJfB0i{m2LgCV3tP1f^P$D^PX?oCu{L_u3qk=CaE<0k$6KX52}dh>kO7n9(so3
z=da=ncl>Yr$j}i?J^7mg1@=R8LcxfWsLz6&y7UjN%Z*9Q9UFra>{x(5VF-9Q!kIK>
zU>(%OIz`{LU%iJ4Z at N$rJh&C!Ss`<S6H_ExmP86u4n+a-bjrG>OtM&>;T^A6$9{{%
zvIS-8c`sJUq0)^;c at cG;;Y5z#IZGjx&&LZd;eg48zp3Ed2W at J|8ixk>1OlRCRjS0o
zGZaU8e`w0)22#kNo6`{-ice*5)F6Lu{pw#qWXkBrTcIR4I5+`s+gp5l2l||=vxqOb
z!>D6c#i<g)%xoMPhDr1|^9NeMbUh3|H3Wwmcj5<o8z*y at +D6GLRe4fPBAUHgAuIMP
z at Vk-k1^pTb{-n%K-$ByDYz*F$=|^2-vKqj|sT7FS6eSdGI_;OoeXUoHvT};!Oi=_%
z$*<&$tj=TqL(K1U-%aNQ+)G9+<DEa%F)f!<M?8F)u27tZ at 5{$eZ_zW)DiBgsDf*ym
z``XTcLI*`RJA+hDpX9sa#ZcvFGn?gr&I8pid%_JIhQzkisWP9Afk?L+4kPbWnZ#J$
zefytA-Y6u!%?P_)_Ev=N31yVlZRN(wge|0$7m?t#`eg<#@8yf6_;C`mt7Uf+fCnq5
zB&aYEWja=oy9cw$VZ&>YpLdICK8890vZKLEK5u~_%Q~102NL{@VnhAIl- at r4id-H^
zVymrep_M}`Mr|mRGCK0Kpla<P(MZtdzk3CCxd?w*&}ea*56?nKs=~<#$Wz=&VjAw#
zx-{hQNKbvHUsE^GG-oG`_hOnYG^w*z!}_JzGJy3n<6Fj+9dTE>HGKwD_xYq+SL%!w
z2&$Z$+~KUV8B(PsHNT+0WrM>whECi9zTEmFXq=V_bWId=rXa$$<=bSlOM}mcCVK_b
zn0oxbz>a|2UkPJZApi>pU<aF(c~uUg`J~wcM at tj4tAjnn`I8}$nn%3Hb)80cyIAN1
zL!3f>gAd4N>xDrd5g<7%lNNDk-a#f<g~nlTMkY+ at U5q<3Yw^7T1x6?^_#0_%WjA!6
z2pk~A-_6$0Q8NIZ=E*#=L(}m)T5d){8BDAk(jZ{>NEDi97v}*b;?FsyM6lurU)Pi7
zRG}cn?Lo00g?($DBdKp51NJ at RhuP6hIj<itedMJrOK0MqC{pYGnC4dJfcX^M33A^e
zGv6$E=D6kNkMn6M(D3BuC_LX+X9%2aK6*-GYg78gg+qR0wgH75I1*DpzM<L?z6cpk
z^`N?!GsECXSeF3KJWp8 at oQ+LDW}d(;SxZa7c4ki*#S-DV_5KVqU$+YGe^~$_<e?|!
za$(Gx`WL%Y+kyP{kH8YkiQ=v&V11hHbc at LXLQ%`tn#?;%=)0m{VQJnGo)4S;Ql1bu
z9Qla9Vrw3gbLUVQ|1M5FTnnT!#PhoSPIvZR3mX3V;q>?%=j~#FFEMXe)5LtDL5;Yb
zgmz};DH*X|JNPbU- at w&gV(!g*@88Je;q05`?nJR5cu!AdU*&A7x?CD``+>dh_sZ%}
zJI<uf#t*titOpG5w*^gRN4-lqj at Ww_qXfas>~yXjj0Mhpu4#NmuE){NzTjVcx8CD?
z=(q2|a(6)Uv at fsBiokn-2Ps}qRy5AYllSR-{a_+S!*!D-rtT|<bUxqpf+3P!cQ={O
zrSBic{ikP)@nQwUYW;8D_MYkM1T#E6?9`XfN<eUeh-?}oLU<>-xwppxxL*CZ`y*|a
z)aTdy!AdW6X*?h%_IpG-cU4UX-n5s=aywQn-MqB<RAshubiGd6K=pO?*#?=(K5oA&
zB_8qO*_CzjV#U~rVbT<Em}LQvDzL6ibg!A-jeUDd)7ri_+?Qh{eQ-hXid}dvOqrT(
zsiAZhwyon+^du?avD=m#-yGR|FYI}&`+Sm<v1 at j*hq>vTdsU|{u9h+eqj$6|O;;Sz
zjqz=?qA;vxQ at BLarEP6eG1IinW3RsJ<6pj|u-M3_j-dV7w0(LND9P%uDD82Rk2dTh
zpN1g4uEJA>c-zW01ux)#NadsQE{T+t at 9lVBg-H&7P20zwuKgFFNM467-W-uDFoH#&
zTX?c at V4Uinmh9JM|Cf`1ufTl_jk3Z+-#jj)ONd1;glI=>T_W$)EjdX)aIkZmapC5p
zm8*c>$9zr- at BBf2Tot?S^k5Om+_{A6Sc3OVt2d^d%OH$11CMAn<sfs|RN0j4;AXKj
zS<(Ie`SU#e3ArJxov{>0b#DA|sjQwgSsD?BxKpO(Xvgt=v)bpmCPUL~@np&0;fB&O
zqZqy0DC4#N%-C=?Zp%{y2>OEF?Oqj!%QUAW#z?p7HJKjkxw_7x|MvKog^3$)1V-0R
zp|psUp!RS~D2%A`YaPp;J-O%;;aLb5@@zu>?JzXFP3|mAE|~i389RqB#|v&8n2jus
zuNQDRd=f(*jxp-;FhYGJC0m!QCD~jyCoMP6KsU}<=h)?5hpp69WShc+T<d5dN9z?S
zm17(X9c8<@N24(X>?3c{@4R-9_WMsb0}FndGtL13AL?GqkNoh=dCNJ?Emj3%$z~NA
z_qugav!J1h?6Fm_wSDU^>v-k3mE(EoLI8@<!OnA{EC2JyVa?<d$0>k1*OHTEg~H}r
zy8dqJgqY8A6$8$I3c*FUHJuWzEYrPHqqfJo<@ZzHk5M(o`ap;_3^QDnBWPVhk at 8!L
z4KcNS+=O-FxmQS7aAGeNfl66Q3s_M$4`pOH#C08H51i;J%jq7X9}M%mFbuu^7I;lg
zn=*dJY^9#`R7)VP^L_g)k^nvDpi|@dNrk2J8orp9%hRq2X>Ia>ooH6J1Xjx7ZQLhb
z!wu{)I&OA4 at C~d?)e)O^(x5rQe$91RcYQjq&`Ley3&V8{UjT at LF{ZE5JYSf9Bsh{;
z#UMW<mvyV}hhWvTYTDYc+ZIRQUytmwi)<E<XTh^PJ(V(FhB+Ozjn`Ep9n`j`g<dd6
z`%IG&xysZ=%qzl}(JH=F=E~r2eEC!&^v6Jcvje?qthWx^xBMh+ip<>nA>K)?itdB$
zLj+T4--%rtg_O?8;Qe2sdLK6)6!UwO;+%4p4y~t5E*G%Ey?1W%=e#NVjwuJB5)W45
zwa99MOcf`I(AL+*uAg0>uD4B^BR5O3!y~WalPXU6=ALp?I&bS6Bq3T+Du)JbF72c3
z{RS|>X6SQW`S%tcX at 5t>CYyf?B7qOQ>C~~7c~Lr7y{i4MJhp*K9;+SXO2SClKVI at 8
z9TUFa)%j2h-BE=##}i7C%_bP8`;dtcTHv>jk$Uc(yOFrFxbDg7Hk`zcO;x$NU@=_`
zTx!*X!W0ilM+5S{eLum;N>17lZ(^4hpqp9>DNJ22?mnfW*c;p4Q&DxewvGRCgCdGD
zyIj%aCZep7 at LjCZ#n_<jkVx!0+~K>&&;N!k=**@!i|qYb52t$BH4dm-hJemzoOcY$
z&UEa at gy?sF^Y-IY^y9$NbWqE_oG1ibus`f-xk*c at 1}TPsN>u`&2q9j5v#kzD3jJ8L
zvz8UKUYu05L5#!5LLkm_NJ_7C<)5oosof@%J<oe;P0#<Ye?AC;Um4yU at EB;=M_Avi
zPe%gFm6eL`8)9@{^;<!wdH!fH?rakzawU{oKpt;3t=5zgm~Qa6Juhy<(}16ThfjyT
zj>fR@?Av6aXqmjXdN77UNI_}v6FkJu-?;sJzu)#o3Q9T?Bn{HJnvd{&vn5w~(g|h3
zx9ZIBr`w7&`dW2HiR&6G7KBd2aaE>?Ws{uS^PjQREsdMJ)xkz at gylRyNWnrsaHmjK
zT;G$O2e+<4ZZ!@ApUqaoUb^pN%RwKvt_lyy0^O>XguabZuC3hsPmjt4T!wd*tzWff
zc$Iw#4=YLdGRcvsk;j#D3#}Y$`t$-lcbo4`rBvWl`!8YPH3zD=y02VrPj%AYAvP}U
zX++6A`>@vx-7$CXLlPwi(_Aa9d5p9l0r`uEZB`Wl_3}?Qs><QFWN4ATrrY>ylQk1_
zF2+(3Hq_f>yZ<yXLTAHhvkx_ at 4m8;0>k$0obcNg?<#_c`nX)?at$aMwBB%rirf_K-
zRX+Jya!nEOll&WYWl5SoesMA{9Na}9b)UN#*#$G&>#C3XtN=V!`y|zSw1w)J95Hlw
zXXzJL;VqEC#Di*@*lYDx>Z>EjYg>EsF=s7kcV(KCEGdTQfQp;=&=>l%ZrRm+dtLmQ
z at UByq%w+na)H8AUVRLaNRX=AKNH5I>Z4Q at FvqifX?0<K;qGaIbd1HK&E+~QDcon#1
zu=8<o-*T at JE?01v8RdP0u*r$1q63-ga3b%%J*Nv at A2f?0+czJ%G0gcUeKR!5qm}CV
zXBpQd^f9{nr+}`)LGnSQ;B=ea-?f|!w$P5Fb|Yb~lv~9S5ez2XEfusXnO02&p%S4T
zwIzok_mEXSEz@>%`kw3{+!mGEgYG5zDuXIn6W4E?sq})>ZaaBE7wGfE&&GLWqQ=Hv
zxVMG9bvoeq(JgJ_Z<)qK-HO?MUFV=HHcavpYM|#q at LtujIEt*%#A4c@(HL(k&Ee$l
zJN-%J+@&}F0(c1tHvefE>dVlLX`AT$?=hgdkWcAMS46)n;`+ZGNTL;^Qbt~Qu~6kb
zU;@(uO*}D<Y@=OP{gS{K|NYVD5p`{n at qkU8rjRfsFG?r->4M;2Az(1 at tcjoe82vl?
zc(aMQxzhXN+Qi%W?;8H?m<M6BVWI5GQ(z0DT>7UNg^+t<KX=F+PtdhvjE2kP#$DJa
ziSh$6eu*ni=C at _Z)`lA*Rg~ROdLk%dZ4VI`M+NQHL}b*EpH0kM9zWrQzX=f>xolw4
z!hZ0w%;l_12kpP6j7`^k$;ThPR2Q6CbA954BKlOYH^Kj?%V1UVa;HM*UNA#u at H4)#
zMsu9|02$|EAN1wHvyecUn6)ljE96=mj6`dA0(eoT((v%eH!YvO@$Qhr!!d$M$tp4k
z2`Rngdh}8}bgXly;cR;dh{7VLH-^YIUzb>$zlWMUaon%A9y&;Hv9{- at H_a@Z0BHJr
z52mE8!{23od*bhN?c`-Iw|Fm$(AGsnB6#8=g0gNt)coqm?lIeuXZ=784+BD9C?0cd
z4L|q*|0$^{Q$^of*R$AhpWkB!h%;T2i#tcnSEQS7El567=fzWjbgd4);;lrA$$kSi
zfQLQ>xP<^hQYG1d07da$`At0c!c=QhCxgnnhxVe{A!Y(BsekE(FsS1T2D~+bf4 at Fw
znA%RQq~^~A5ivA8ZRBp^%RW`M4?jca&@V at BshZR-=`FLXd!+x$ssF8OZb}xAI at lgl
z_Q(4BD7UkfdQ6Detbjr&NFx&*n}@dLAAXI9jF`!(vTN*QU?|e|HCx~|#4PWoF*BgN
z^%$hn!ull9#yP?h0F=`Xx7%a8)$wuuO-Yug`@pmrb$?gnY?EtBbn+Kli&{){VBtRu
zai*mH%uNYzeYu>wG1aawj(3Z!TJ~k#vK-1CNVA$^v+OBy3%sf|qJ}Lgb_zy^myNsX
zr|83;!9Kk1*xZNl=Zbtw&HJQ at PYEsL7E46E-zko40ZF5(e?*=VV%E;apEC$G!f)i<
z-I$n_p9EU-$=Q_idqP(56E(75vA5$y5G_k=Arr;d*Y#_9MVOJXOC5_Wi|GuGh;zP~
z<_IlI;@G%KI)WqUNUJQMzSiyz58<a9H{gNlu6!zTun&OSa&Ceg(}aJp9{pVN411ME
zmt$fYrB{B?ogyJ*?z^CDRqZjCB+8bT<?Q&N9+&tw-&pB^VkQWANOezSnmkPV_Rq*%
z+NLeY&}wS&$b~pFjp1?<OdV+<hz;By-Yl)|fzmE5w!3Oj^vxS?$3M^*G0hNYq+S at R
z4>zV`#+ZSSRpx#tFTJiYJ7{SFdq_Ucm15C at e`19n945}0a at L|h^=tV;rp&yT1 at +Tp
zVGALBPw}&-cMFn-8?Zh_)fJ7UIB=@bHHdn-Ryh^5L^{QqCg1S<RnlwwGQ-QhWpeJH
zpculVxGvPU1$qr(E|{_2Y*SU9$LETiYeBi6#C)fhn=C#HD%3A}C0u at Xw)$Snv<u7&
zW&bwv#(yRFTREAy67+Hms2=L|Pd1i3JzA<*Nkj1$nJnY0?<XC_lu7O0mUi&11Z4FH
z_m5iR({mTTy=M~+jp*y1lelr2hVvDXE}gYe>rqa1P|+h=WgU#vPu}jym)lHA2CBdw
zIyaVI&u at mz_~e(bePT(cr|}m=y(+~k_%ZiF3<_YHYW9&)Cl;whCq{5}Q29aV&4sgo
zNgxR#{nHZ=Ri^)}Xl6hHPhl|D=WYG at q{jLN)-4i=X}7)QOxOQlOvabL?Xadgh11bM
zkYG9t`|UL2Syv=;VLCigsrle==!?Xf$egb4?tDUmqz4IkoMWusy~mlARTIts)%x$}
zo*kr_vdpS>1fr0ntPtk<h$ulB6MhvL;Ab>(>`3ia%xA>uS^C)4S2tlGmrd22m48q)
zSnx7^(P&Ql=6mAHh{UD7$9}e^Wr8z_&AU(*Jxnh8QBY6wZ~a1ezBxP-#T{<iq1XJ)
zbtXe%4nZ-SV5~dU(QF>luCnGX49Q}jG+9cqOLb9C<=$E}hWcO at Pw5cy!sv%X!c&au
zAha8g>qUdc7*6X{aKC35*ZXObyAV2(+EzTdz8$6}S<|P<jPi6)?U?rN(8o=ybw0AT
zTeS4F%=oo^JQf(ReWOmlfo20k!77A_9rG}lP8O+!#GyF)XO6p$r!mu=bk at Dzug<1B
zw@&NI#yzq-=Db#!P>DuWFVpMhPBG*W?irpzC42=S3WnMS;*pBxb1jef?v8>GI}+S`
zb*i-N8SzD3&%u at g0G%~-z=UGFi96q9uo<7!`mQ(kMgFWqh<KJ+idz_Y)aRk;TOq6O
zdB9S{=V?C;0P6RH0yT*Cc8BSNuJtTEW-lgwmsA$GqA3g?sW`IatTx_!SM{3<r!%vY
zG+TUp5z`0850V7M?~xIApqKFQHK+Hl8~)wgKe7Bw-PinsG4)2-%VY$UVl9!X?vo}u
zz1<_FeH*|6k at m+fiH{w#dykP<>8F~Pe{RZae%>N9PCBNpzneR(>)CWW4F at OOogj1B
z^mX;SW2$=SY|I;!&t=(OPvT=?i^qX(4pi{I<Jk6Y?fAz-ylD*4`A at 4RA2>WYp|%K(
zFa8s1-6C~MPjs)&vgr-?I8$7Q5T_eiyIy+aW*Fm~_E+McE(vDZZ_o<fXrr1J`FhZW
z_q{kJDKTDnQ5?{WI68qnh*S92#RyvVFB7+3m*3boG+49daW#!HqBeQrbgKKYzq8^6
zqN-s&ynIS^eA}t2jduL2LbO%!jW-56s<MmBGo at 8$KsrF8Y#I%02q;1{ViMfl`2LJ(
zNTG-k-PglDB2v`IA?hmG7@@I6>t1)Dwm$(8qmHizMHv^`<A?p9hnVEBOn)!Ja93>o
z2kX>nt(5wD?Gu^P%XGCzb1`XBGQDmsOMD)0s&-<H8>Y`x2+{<Xb at r=PbdCQrJS+Ck
z^nV))fSBSqBG9Q$FQrg#74Q}>5i)WWOYS3BAuR<<zlyo)zCHc*!4C9AVJtk}uSoX1
z!>OQty;+f|M2VFrAA&J<ek;|y|BT<<zgy~Jxblw-oC(N*j;N#uSCWqCqM`(71B{Y4
zOQL^S;0mL<)W09vYbASMbkJ+nrmNj8InPYUm#BHF>mG!y?(i{IJjm(o`VnAng&@tB
zY`t5)`>8?4Px8LGaewz?M^7G+g5Yuu8n7JjS}`+8)DVFSy at _m>9x$vDx at 9?H$?+^Q
z)0=|~;dhy%aIrS at PaP3T5+^Rab%BGvLwsEF(w7uV*Wqp5Ghuv|@~3m;u4xEHAE`DD
z>J_ at 7#1!_WN3b=$6;0Rma=(!AX9x1;E1Ch{x^Sb_)mr{)4?60LXIyfL`lG_5P^GqS
zAukd$;AC`@l#>m{?^WkCxpSevho5ROa9j`3xa&CMTE94}Po7Z9!ZfAlN>Y;NZ)PR+
zbc4~9WXjua>tDe3XGAo6zOoU?bd{Ka#2m2CP2Wn|pPFDUzlOZHjCIUpab?ykce=B9
z3^28=Ik>_V?FavbKq5kl<V73{0#VCz3-p8j((lHcYMQfxTB`%RTu)Ak!{}+jjIs?8
ziRsQiYl&s!osLv*Q>f*PA`*N4x=jP)oj}~V8bAM6{E96fg616=zlw)U)W)syG-oR0
z4<r#U;PRRzA|2K%gwODL2ndzElltNFV6<=Vc2a?i0GFd at sn`#HJv%F$C~u9;!XHX_
zZO)P|*@L*50k)@^h`iC^@5>+PScy2Ki^^OWW!Zr}38D~`U{Y)@T7L7}?hBcfZJFLl
z?oQP1M$&lT)8hX!cH%XCHD(Y|575V6jf9F&S+f(q<>4C=#-izMS6l8!Nt$cDEd=qh
zr8b~ldJ>5%pPg8i0kS?G&m4ngS0hLK-p$Rad{&^Vijl$7yrY_JxPoS(cR-+TBBzK<
zE15}}wJi5I at oO!Nz2Om)V!rZd%gr9-G-;$On9cb4yS-z#p7VaxYSy?atBd1Ifp8-Q
zDnxC;Fq7N#g5Tw}?Cn_HYQ8tYM%9oSmIKxL&rfD5ZT70zUhLKUlYZ<{3I8<Kh^lXO
zP2Q9&JUo2)`YtCI2fX%$g0Uww!%jG>K-kamZE<7(#R_<=js$so6(j<wfGj#vpE^AV
z+$FaPCa+aAXFI$T%S{PXUH%+9TIz49Wm at dFq&nFX^-as at Qp8xWU)hTzloMjpw>vRY
zu+>2XlH`t1Z}P38USu&szC*=}+s at X5#D&C=KhVHELz?1{l*Sh(yFRwbK2D)st(C!y
zegJG^oN_>wkd at +&Xh!Uwr4TtQgnI%)d#|~btDCboutM-{#zXioQhk6S+c7-p0q$Lb
z+7{}vjVZRa^!H>rZA0R)ig}lKK+>*zxGD@}B_<k*oduWC07vlAKvKV-(m8gZ_?W<b
zaPeR+cK-op2|-ar$1Jk~vfi at W`FkV-(KV7KZ(Kh+GJt$7^JPzGX83ZPZp0McYp?l3
zdL at 5Ifb)gms=B!@@}wiGIHSa;LaM2SE(ZaURx^kgdTuQcomf$`o1YBb`T;Op&x+;^
z6 at -wv`USa!tMlF~S(;Vst9bTmP2BWr)cWHL;osfUM_!x!0-2(&Q+xfCFF1?LPgIN@
zWF2XFCY^7QcbX;aj8+h*8QB`tz^r&^V?6}wNlvt#Ih55BKka4t1n9k5I-0g^j|~C^
zc6{aBQWtr557dM!(gcTeC%c*+4CAM>+B<eR5hXqKBwmotdSSO0xKzVk!h!e6)%ig$
z_493J<c#1vpOHR6<r%`^x={3`S-&Zxqlt5Gy%fL{8Tf{AQmWT2QzOvUX*PY|r1d3E
zxeN6 at p;PI80dBq(C;W at PqL@Qx=J`^QYZ%gZz)h)!e3HsE0N!g!f|q|%A6y`*b*&nE
zAJ<_YLGdk=H^OqMa1dAp?RaqPgENeG>v2z);)JG?F&!YsxpJ6y*-r+)jU+5rcbX-0
zGvTf~w_cA6?Dkd`5Tqb0#q at Ejb&iP&uPUfst76KPB+43JLbn{{ocxD8HLw0TdfOW!
z+lsoq3=a)D9mlAk;0Ix{JPk(V0<RRw`_g$+kWLIZ9*{h^u!OVQd<0Ovk9xS)jX?Mo
z4spE`qHA(l_X|Rl{rq;y)ZVFu$~qUYTL-!H4tDT#4#C-!&Y;Cj+^OQ!OOH-ZimZsK
zYIzv%V$BVf#SV at b92WJcvQV_b*D`VOM7=d)s7MXdrv3qgLZ%(fzr-lrdBW<XK3>hS
zB440nOUcz-2UR3`odkoDobD~kjC;C=TCc!eRq?uTR&Z;YQ-`whiS}imxZ-E3b at MmA
z757c<{2I~TuxYMFZh(1&iY&jY_=?|3W%+CCZ7Ke0bom2!W$*Ej_${}Y!u2ueMrRn-
z$}r`~&CrBl2SnVm5GnY$Q;a^dk;6+{se8ycw=mXy?JP*_9bGA~(cR|JdW*Vwu$*IK
z>7<XlHrW*!qTus)H)7%- at -WS5^)>1i>`MoWdQnKqBJQr&^LMZIn=)P}-*>Fatd7?7
zH4y&b8uz*LEomV(|I6``)*+E44Vll**r at b37D^eB at F-0p!ceRF{r5XiAe%;=D$wsH
zny*Cb*QSmgHC3MSeooI7SG;`?du}_E7r2nsL#5JY(ta%cF-4N;Lz<2Xmrj{lI)>uy
z%dgF58CwgjQ9 at 5X{Da({0{f8vTAx=GPDhNId0Jnh_kI;<Wo_<+zKHjDI<DK^TjnBr
z&v6Puf>Ta9f9T1{GRfSmyN#%GllgjaW)gMQ3w=JWmxhVu#0Iil9oaHczu4hMKRDk^
z$Of+6yvIF&StCR${qizd1mqW6<icf)GYZx~&5XPL5)!YYD$E{e(l<<ry(^>=_l-7+
z at -4*zs%NDl<wg--Qf%6(VHI_R#61nWKytDWqaTwM?>mq1PW?5qF|iMoCuA6`ZTg6e
z1NKCB*j)xi-V+_!7p&Jtph$zAizEqcl=rW<lQm9~(xMEnK%)@(Z_rpaY1ZD?qp72h
zZNKr?H0X*y{CwryZj-`ZE&lJleze at 35;QYo`91F0#b~MuK!<!7JaD#63{4vD=0y>|
z5S*;C-NE at y=Y){3VdfMCu<~?oXGVOz#BgU^m9rob;EAG`wx`&~6(1(O%pz}v$B^F%
z5i%|ivx8suHWk<m=lVZ(&p+ZHrlgh-`kXk7D2?- at dU)~&HCq7365+XlX{K&(0RLZu
z!Fe$=kHp&kE888|*W`f|8Kmr3&&d9Ew?OySqV`SKttkca)8MEox+QXcXI4lr0Sk7|
z&&qw?-YJ%vMUf|aF9C~#ZxzB;<DaZ<(6qR{dK<}@Ccj1AMb*q%*b9eOPLs;?U+wr^
zojqGuU-1254tu__k06iPu>>UQMkCo&S?+WpTD4=MWLbARX(`fJawYp;C>A=%Mh)BG
zsc!q5z98JimT=*2HSWvQ?C3O&W%UMDHJdFZhz-yt59`a)T2MqzMf)0m%g`!S-QAqg
z<E{~X^h)tEW;gFR6w`C_IabQ8pHf7+(gAomihxriH){Yy4l9x- at wR>U^%-oti&eJh
zT!VhCMdA)2;qfkmL;aH@@mlr>w+!&i_BdsU2y<~CMbBH><pxKuqW#3^mqNbaKQf)g
zMYUT6R800pa|}|>VXVe^KAv{TKY5J{Lp8MfreCIcGR$p$rCgZGQf<7GaE<6BHg^t;
z@~$&Nd^P-pn0C}#(+&j^e|7o-9n?|iKs^6QZatpk%`5eEUklVZuI~v320E~}LZ%0)
z{b;}<xw)@)0HkZ3o)8D7XK+7=tBXqX5MEo2{<Q3iEfF+^%)z|hz&_Z^YE>#a(nip2
zsdrXPnNNqjrm))p->A>BBa;@Kf$Rw91VTX!mVd4Y=Q*T?0A#rs#Fr?Y{k|um-IWDa
zq0PM8>Cmj+c;*&ixa3<U1boHQ4RZ^2E)9NfYZcx}b{MFeRR8ge_19Jk3`}<^Fyb_q
ze1ZEiBBvi74zc+tRM`;H+4P(-lrN~od)NPIeaTY=#sr`hQ_^q)O<yH^Ri;!p$9=oT
zgZ);k_pXVEwno3|i&)dR$gQlkFZ?IEb=q`vGDLye{UR#43ZqJjtw<q)g^(qhK^w=u
zc=g4nq^tPJ7nq*D?OxN{VKj`X)AR*w89)iHYZ6Cerc`#vC^p8Zayv!u8CE~KTJmfw
zGZ;|3BQ%2c^}O$9>?0I=QnN7Y?Ow at uD<|u9BMDYBVslBT)?xU`K$+_qlu7MDAAS;K
zR0y~BBPNB_?VzQevIaJ1m5>vF8n)QP(sG+$Yrl-ReKPpcty>WjT3Mp94D?BO^?Emo
zBS`91m281^E?tV4K=A_;eLu-`+B6`s7AR-G<kJa@;W6DS5*cY>^|KEuze120IfCO|
zWEM=v8Td-0qkpo*f8WXXQ0mS88@!io{#JNR`e%)h7xl)jV3%I)ikm*Bojj$Qw<;C)
z@}^E8g at w@{<~rC$0x;9xVV08a_(eR~?|IEKGWf at RBZ+<)2;5TM`BHg=6rdG&k8!6e
z(EjoRnnmgow`JvVHLDF_b9xTKH1KxKzb|=*`Ck?Q8&@-&?&@D)UN3 at mswn2v5X?KK
zW1RWJyCE*B=cyx^bKiIiXsFO}M7R|sSOJQilmAqfjOmh&?CWQz7 at OZkBnq&+MDUwC
zF3szG^O)1_45IJJOH5UJ^ye9<c0y8Xd1l!^PCf_mhZ5&*8#pYxN=)lpAE>eU+2n)I
z8P{|2@%xt}vsBv4LL2hyhAS=p6z5s|Q{4I%SCR14Sjq!^7`SHt+a7H`OkRb~iCr^v
z9wnET5|y at _5D<QjqmOs{wh#}DgHxtD%VuiK-n;s3r5Z`)Pn$E&+#3U!9XQW}J9^K_
zxRs~e^v|a4mI(-NCSAxmr(FB1@&i1rH|wH`Z2YKpxwf->20l!m)|`%^6$c}Pbt2z{
zr`OzFY2xq#rCE=}Yp!j8D|prHt~D;I<Jq}{4HuPJguWJeX6)ub<~E%w59}OE=xQE>
z98vc_>EKel<u2z at e+|gIea;hZ#B_LVdem``F;9=mH8KXuix{=p^4MfdZEq!8!(60d
z?rmEW$3(55*!Q<&Ow{kZR!a2XC#gdJIk-up)%Hy3+f8hG5_shJ$}@ZMXRv_y*PR=6
z=tr+wshXGl$qJ*DX9yLddiQty%YO5^*qXS{A0330T|+)(=4n>$F817GLCPP*lwnc*
zOM|mO^bqZ;W?ns4?UXB)a7bkUt(T2jVyr3=d_$FqnDT6Dl+%WW2X6fzP3Pgx*8l$h
zzO`DURa<McsJ)_Qts<?eSu3{Kd&j0|OKO!`p*FQgY+|pXh`qO>u}RI?{hfY(*Y^+L
zy28mh=XKxD=i||5lfdD?u{i9#n)7|WzXM|o6zvKBq#*ph&Yq1pj(<+B5L(>Or3lDu
z(Q76wYisMWV214Ene*y?Jp4q&b at x}Y2f=&A`#cik$IU{}gEpxdC|mVMENfX`8z&Jq
zJ}JK7x~o`g*42Hrijt9>FC!Vt<MpubIgGjBglWO2T9wP{Mt79&EM7GLq+X!N18OBn
z5EY^wU7aw4>dMO#J;Z%U4XzP8z7MDHJ~uEXc-(!PP*508ZNM(mYeNa=lriwhb3pqZ
zB!Nv}|60b(GJ>$auU;k%b<0#jJm<4M6 at Q;d+5h}{-GP~AE~hSWZn~w5wqjHXVD=(R
z%(Cw+ph3 at A5*t6UoYd(GOC%Fl)l at e6X6%p?*p|+1#*Y!I6ms4OWRsS at f46c^J3OcK
zt%p#t*3JD5pT6|d%V<Q?Rmh?~5p?s>F~ifkx=#8zTE=#MG#?Aks)3<2ShO;RQx9FR
zq5Gp1k1p$g{M=3CL>e%glXKp&Iak1ZJiocbnP_9E41h`(h*|piF=(`QX1_`x5gD<_
zZ-$64y7hd|OO~%w3g_Ts_os5Cfhhmq^P&FigkKNK$2O=M2J95dcXN%&Sb)*PO|JS!
z;*!e2^^cTEBtIi+s6X27ed0Mjm-~>wN=tHiG%O?I>X*QPBM^Maec8e|c6yysQFLaV
zZPv+c<1&Z<bL at GNqx}s(xok)dG`@V^Es^~Q@@heh&1vbuKK%m`Pra`N^{&H>UzAeH
zgPYW&{-v?N@>#?s at j(qxHj&QMv}R)n(GE3wq#PO}?B)jHv2h8g40(I+UGqeNK at -{2
zxD&Kc>*sH%NcNhZvUKyQnCgS7Kx>{4l at 8UaY->>rj27o?1Li-5_N$wzQe)G($ax$b
zIcrqjnxBu-aeyAvxM`A48E|KfHfdNw=s(<SWf%-Cv+wNFPgnVvSK%0UlMSrK`91_Y
zl>LXJ`yAQxe5tV4`r|^b`-6_P`k7<FchS#yd53Y^A-XQ?4c}W*>EIN9<V79b%~p13
zB)Sg~RNS8 at Z18R61Shk?{g5}Cm&GoP;NR_zgO$Khq71b$?Les`)+9i~!SD57I%H<l
zR;ckUo9HUTw1|)5e55|wr-Cwnt;%oOStq`+I}8 at VHcX`3l(n4&sy at g{(ev;%koqmS
zWYv6?tsJ0atLLzx_a52852l8SGtA=70QJL0OUS!dTneeHO#ZrlFx%CsIaEVtemuDz
z`VkpVOSt at 4jMwV@xFjun|1M2#x at EG@i;LzfNEv{oD-M{DYyHw?K%Y&wA32muyiwdY
zQ$&$jVpJ at U#&^ijP%fh(Kn|Wp7 at WDQQqm4>WuRZ#yMfW%L^1w>1r*ATFk<t_7Z2XE
z)#B#-mzo(=`*pTlIJ&%A_g;c at E41=sIwp-O9&H+RQMwf~r8zK%qXtEFE~43A?x!No
z%hLQeRN-asdq{p`cYTwIEx6212DWHf?(~LCaQ);aEOzx()J+`$2EOBV_`L2uZgrBP
znwX-I(JvFVTNxS|zNz;XNB1Z>E+Nu$hKK%M#lI4&gT5#zrAYD_YA|Hm&=iUCAkO{r
z6Ku*V&3~xX*DbCcK5WR~{tCz^#@$n6X)01+7_GguE^i|@sukUv)>F!L8E*f_C93OU
zG-7h1e=FUdJ+wsDHor<gMwx!~Zhjz!%XZkKk~GK&yR=?O%SeVx4y$I?;=fUvP7eia
zoYQU_EIBYg6H{c3H+mQOdPQsR{3XUt%RAkiV2KdJh~wAO%Qz at wZy1I(!y8*8TtuGO
zLte<&%!tB at WE-qA0W61!s7~rM4aRu>@L68baNie8eK1)8L8tBgIIn}7UMnN_mk*1F
z>UK7=pVY|>C0(mrjArWc-ucgfGjvT}lEopeu178stECV54jbMl8f0;*ZCAa&8$;qE
zXjd$`F0AY;n{7Ak;}-P*+V57%mym;BH~Rx$U~yArqfOfLpC>T*7D>3Df;dHcIVG-D
z<>>a^fZ}JnUU7!r8;wS&e;w*Ne4S>EVo9~I8%|((xMvq&>Q{HV7`*^qzH8N at +a{Bj
z*1a<yt1lDND7}NKAyI`h?h<S#w2TNh=wce&S;4HM>z_sh*G3Qf`3Zo7!3s$_7f`V7
zy%XPHDzK;DccbP3Ry<L@`Vl^|U&5wQMztFuWwfouz4A?Org;+&{co-(tnX?+^@M$7
zWpVvuU!9Fw at UoNRj4Obh_URJ+Jr(+<^1oE2{d4I1oy(L`G>}2y{9xu5r1)q)MktZK
z{I}ptg#$`kQQObpQMoG5Z~|djzY%-yl29v}X$XU&IIMqw9@<sv=D+{uTYvwqvrS;j
z>eQ>BXXb9s&pZQA3E0*+PY~Awzw|eJmZOq>zDy1ff8P#bPp2_k3#?$55eN~bOEW-&
zFOKUwIKlac`u{Y!><NKxUW+zBF^m52^DjvSN%4SY=1~R1<H-7{9-(Ki=f1m&2Y{>=
z!y{Y=7sco!y-mtILlH`qV=U#({?{Wl&jps%*)$x!Qs34KtBIOg6jMv(=elb7fr-kX
z5z=`F3G=F!gjOigT5Myv19i9*6%*$l;}H72VH+l!GyU~N8GnFtWD;q9>R#L<;2R=G
z#r~|u@!%@(FUpaTXZm`t{ZV^TWW`+%^C_O!QoV7rH&+`nGO`~g^wDb-OLuh^x!h3_
zNJ~*>nfWOFStW77eR_ogFX673#4o9Oxwdg}i{@Wd=h7gso={ZOI8)@m_Vts_2O&H_
zoPfZWaml!;(IMq_O2Q<nLHKv3FQstbIMnzl-SEWrkxOVzC0szbAjZ at 3$jctQuMO#g
zTfq@<ql4FaX at oWD+$;AZ2saZQv#ZitJjox%FU^HF>Bto=FALG4`*Zs+ZsNk3F9ZBs
z at ns_iD#R```Ed^Dm^Xbl81G#ilFBQC>YlzC5_^nVu)~LN%l0%4rM(oScR)0f1nU><
z<(4dpb at OD`n3rXCFdNWQ!VfMW8oa_f_kXPl)(o*j4RiN|If-H%)}#wq8{ZVNXMxZO
ze_%%t&TsM=oxF$ryZrMphW|y;SyLoMb^EV#uQrELsf|`U$g_lyA at 2ZT(JiyDm<B_i
z1S2(&BOVz>UH}z+SXariVx(C=yu`Sl49s>IlCcv- at EN=v#BevE#B{t+&nVD>w~n}m
zAr+Ikne5;4<mDL2v2$Fx&!WXek^Ta at TwBEGm9n_7AKci+8HuK{wgX=-I!d7IX953b
zcX2UIBwsJsO0xkgYES)9?+1?W=0u^!t?Ft^dA&^t$=V1ZOu{N3z_IItL83AS*@cKX
zzv&<w0$)X*;<>fZVs4#ZM$u8>2#Z2Q*$JNYsN_PU!14K(@<rVtNT!J)=_STe$~Nhl
z05(=PefzNHE!fcIwn at xgFIb>c at xS7#k6&p>#W(LJIR{ScCHYUzo`uL3&})Li{X;_A
z6=Eos{W1=l at Y&hJo;mmZ3J`E!2Qzw~oTszWOd!d0_)oYgMC>P72NlzZbH;PoG`Ne3
z2<EqsQcH2kl*QQ|wTsHP<rmEkCXF*t*Kv(|>cxrZ at K=j*L&zn<{Vi3!%Q87W)|c~x
zid75v8SJc&;aNgo^Rlsslz0%FSsUG$a0jn)dSuF*PM>Y4R=t}xuPB&pw2Uwn&^=g6
zuAOJFZux5~=rCTys at Z_&7szJedAK)M7MB(N)9Otl!=r4bj+{>&r7o}VT@;Z~c=9O(
zLz(6;_5?L%ezi<|T&0Bggb1GJ<Icu)6TIX%+}V4k)=tTg#gaJ}p6K)5%q>-T_Jd)e
z0)9gDp}{gDdh6czw%E(5vzl=M=C?~0EMOYX(P}={N`i*km>mFMjq9@;^XsPmnmE$h
zcOxokc!|}qgYVoi at Yzd&8D?R444shz>xk%CDS^atiYyx?-?gEjDCDWrvZ{ahe$0Dw
z#{^)|x58W(2waC&@4CHf0FlINc06d$1go`T%yKV{43BS;d5!tDJ5MDD_Ke#Inep$+
z*Yel?oBcc4X@)Q=33S0LqcvH2nXA_{HYv(;*>FA at F%&kp>C4NMXK6dbb!Sxi`d>x6
zLuC>2iun%CwLzE8nI<@`i at 3>uiZzHVydu(;h4;QZZ`L<>cyNC+U(GHZz5jp6N8g08
z8`+U|%iU_a;Rr>jV(K?9N#LJcUQ&MeF;xX;>$$kW_TE>#k$Lx27+R>scBk+`VaBQX
zTis4 at _)FEfZI<oJU)EYXCW1zcQHakcEytUcKN|BD%s<8-YeQx*4i6)L8~ZZt at vIo~
zsHW3pEEXVi`J}cr)wdxa6P~Z;l7;kly3_7GFeEkuGf|qd1tQfPm*3x9ozu5HoOIFo
ztef$(asFPpX1bC}qr-RzG<i4S)^$MqlLF}-)vVleueVV3ImNW3sbbdcTThMT%<ior
z-+#aq89p|qoMOLUtc8^uXUlr at p|6p6-K#V39GgT7sr`&puA5e!6S8fNtpJ`W=ki{i
zG~3)=n-W?ecegQ{Qqu1u=iaMkf`JXwsl1>gq{89-yUmKRGP-5Pwgw2`97wS=U1V6c
zc{nvCpd~+e(oD9xki7H6C`ZSv%OPur%AN3qp9=}IPbeBcg?siQUp0r#7$?o?&HbYA
zfw)z$)00Oo{p31~{pMLdYZ*yAY#xrlTdCG59&I-v4Xr9Its~qo=H!29sW{KmTvcpC
zn>Nm17Ad=u(tlj%GW8HO)F}KZ?nIi>Ysg=eZE*Ti2UmX7)W6D*T+6$gn7+n8rA~3F
zmko6eiTlgoM0y8 at DW_NOT5~9GY0!3?7ihux_->q7!38c2DXF^U3zvs;8R3px6bAq|
zK+E)pbv~h2<zW?@;`-Gp(Y)-uWMI^K6mpu%9k-cRqG$QCePDZmd$!@xJLs1Q5^p)b
zO at ISJ8l@i1CfDz&*Y=g5-jz at x)>HX+uke-|tI3Fl;?ILscB|DosL7uunIp}Hh;~&@
zteb~zQ!@#br^U7!r?C at yJ??3ZVa{%zWut^f=Q at A(9k&?vBONS|ocNq*k7&|o8-D2y
z{DNhOEf at _Ie%`Ae7N)w7lNsM=^8qd_&}O$2m|=XV&RQ20MaG&3!@@kXXBYWqUW`o}
znqre_W#*INyeNw3%l=4Tg;R)}iY;Fi&9oEk=x?K?nd)1utV##95Q^^HQ~{dT!SHVb
z;C+L#SGYyRg^b6bNbK*T586_3mJI|9o!UB6hM%_8T)T5Yo+$TLEd+nyHAH9MLp*@K
zL^UOXR=3$8Sp2#-<ehk|Mzci$jz>Dc%`(wHFG&ff^$3TZoy5+~ox^CwT|Gmm$CZba
zF2B1^RG&zeByt?e0 at b4<Nx9QYE`Y6 at 6<bW1<n)F+#!W=XiIgbY%K&Qe`qctL9dyp~
zgcxC5{sQ-$kE{%0GyHp9M%m}@Ar|w4b(px~iA;dWTGSuc$S(LTLSJoMO+$9>dEB`t
zTDQ|@I6>=Oq(8Fdx8Mt_iZc`8A&IVXUT<$7ZvfbxeWF&aGwH~TD4E+nz6yOB=tGuw
zm{IhhcB^@$=K36t;frx-7A`Vy*1 at M8sQve4$Y|&N;w!^2UdvIgLaly;aL>nsftfQ~
z$j-UbvaQU@@8PRXyF{`*r#tgm^Ubq&Td&f!ZneuaZbNU#e@@BCmG<bgEf+WKSIn3X
zR!M9sOTd4_$le152Fxd3(yGi*?6`k>NYz2s=Op&w>l-DZIWtd{D at XG+YY~lEJLK>_
zw*H?~9ZvoUo-krORM$%TP&1u3&lFp_8RmEoDrR#~%TBWsZkBBUuSj>N+(ec+SC^Dp
zF}o*=N_gq4sPty5&0O<U{@C+n{=$Q4f#;h?8XM-J_zu%_#A{>j=*K)an`Bb6jUdZX
zu`LhL{_lPRlzj~qg;NcBMmgl^UngEM7SV*08lOL}({iB&pe$>7krM>I-SWFN`b50e
zEnN9C7AvYWU(Bb{MNi&c<}W|IYmqd3R>@wYly3qrKGde_jamEtrR<Kn;xw(Cc3H4$
z9^yY`*^|RVxRcY>^;EuPw_^HLPKHd8UeGeehjPyRx_ELnjf}#slv<*W%q~@Jo}rMK
zW5bzxe#*ZH(yg~U(M~YeB^#Z7BM&6kc2QsUMW030c78}F+CqMR6x01l2EAn=SgO|!
z2%p777<8Ck5!F^2wf^R=B97OPQ_OhlU9iAA_$ECX*SgbUPc!#Y$Br8?)=4o=O+)0m
z!oAOm6Mernl>4137r9uq at EsZeS*cXl2p|1!16501M(yZ77Y3;9V#*lov3?;h-p<Uo
z_)#71(>s)G=>Ex##ea^ZOmJELL>oUY+G3`%nOK<X&B9fF^X%u8ULv!<5K at 2G`Ka95
zV9+N916KPJvuAa+s9V*~$MN8Mo9CEv?J#ZDpX}&{?%OtR9$fr!Wh|ZCz!8wMFclew
zdWltsRCLp%CfGsH)`tB$r)|o`tTmFz8AwmA0*8|{JY-RPRKH<Nw;a}T at l)pJ;7{B1
zd^@=zVgfSHPf%>(R6B_3-^o(SA8*F7&|RQU?ipZ-!RVXTB$tdw at PaY@>CCrbBk~u{
zdv)Vh%vz>@2#RH$t85i4S{_i{-o(w<E=RYwqWQs*ki5*K`eunu3O#C2jQd)vp4~Qp
zd>k#UhlhuFWoYSbs{qB*5B$&PoCnoP5 at 5WtAbs8^dO+~qEK*We^vzfnEvy1wM5r(Q
zJn`)&>sam}sgqk4zj at LRrO9&3f}2-yWl7(R4qE$-;KV8^2L5@^c|3NXV7C5ee}Op0
z&R|>Y1p_nccQQ=!7%e<yXuVPAS=$LIy{CBWZIX>rfo3UqNCq;YwoWY)2-r5!Hn+Bt
z2HgCkAO6xxttmRwA-8STzum<5D>%QlKuIcXrpC)F)5(Y^(`dMSKby}L*w*iNd)mHB
z9pJIgp;fwKUEE^3yh~Z9ZlKk7+9Lj;tz2+Qjd2R6BK|)1KUGKm)dSD3z;#IY6dlV`
zFzjQK{aq|!8yfhR+FGODs$flZ!(XOjU&-33UL<O}l<?ycaRu3WME*WGeF^&-=IO=1
zS=tN1osRJ({Tuc3uUa~6QPYqP0IRhD;IhPf&HUNU(lSih*J#aiyA1jcqwZZ_x-7Q_
zoLwO^hIr&3W~P7YpN2hgib7^6?2r~%WeZAF?**)6h~!=Hi}q1_Zq3r at a3qcQL_CqA
z`MY=!@Hwr;+-^rFJJ%)AHv7=ty-NPcjHUOjgI_{x6Yas)8v)^;qu(&1Bv!fqB-9ku
zxQn}qB?hv0Pbr^23vb~bzgd(h^skhRqlL5bpX+}(T}^VRSh~|`dOCY~1ys%2JRT>&
zYJM~rtf2M?ziLAC6o;W9JD0VhtE`C6=f<@0&at_FV_;l&-$%;EyHTbhXKUvfpEu$v
z;-yx|_ERzMx<*lJ%I6Aux8nnzXT*(56iVvAf?r6|We_Vy^IW!!eKEcT`EYSXawqad
z9~y=F*aPZvFW}0(>@Vu}>Q5;wb@`+<jQwp~Y?;A at A0))iWSTfM9rX7oUVh)GrLT$0
zR0~Tt;Qg9I+zTPa_VQj8 at n_}sLKOjo at zbZjsHs053aBtNG9+P`p3eqY+=EUEW-|eu
zl>hi+VQ0w7xm at LVLo?6))S>2n{Z88ufu<?;+&v5v$-kB97QudNz3XCs5&uGV+g2-#
zRJD5|Z>V9UdTNQlH!3^nkr73fUG73C25&aG%lk!#uUv0d$Y at D5aCsH_IS77NS8;^P
z#@m)`=f=7cMmfj!gh!eWr(L+$nR$E+RB5<E{}e;l$H1 at 06;e}0(}A*umF?Hw+p+GO
z-X%mHN^?y!MZsha1r&Ri*n!%8>>c(5(Fud)NYM66>cMB`Rs|HIivVTIE-{L>U<c?Y
zCezHZKLo&(l<B8$9L6_5j7J%Id9tx;G!k<}j--{=TVtdHdlv!236!StPE(;hTqTu0
z(BY|e at 0Aqpx)WdO<rW^*T11cur7eA++O!idP8$8v|Diy&Nckx965u*`oDmzLlLNa#
zjeVh^JbW=RzHjOs12xnSH&bwwq=P~S`YUk7aNT>eU7e(PA^h<YlIN=oY`Eg*Z47il
ztyPK6ItrOQmAW5r_+W)|w2|b`U at z7XA>qK?PtWbfY&{3xsNTP77D+hF+Ui*Avhp13
z=2w<5$^1rI+$=EN6HxFsM$Q!)villE)Wrtg6dynF9=zUNRs0TULGEa-7``-YB?WA1
zkM?J$-VgJqIaFV+1C40g6iVtQ at yKE5-Rb>d(R=)lRQ!7hptw8)!-eDO_eEW0sl;a%
zQu^;eD^OVA^xUyKR&7xMBLn9inVWZNJp(GF`mhwEd*E`aMIcE!QxS<rw_We80F1WM
z`Y;(B9A>wTIdX_>e`)eE=d!0Lcu5)ZValYJwCsTpy_lNz0x+i9 at lA+3QHi)eV}m=w
zwm))^e?oL=NSKSXfwi_n-t!B#8L5kVCp}H+^V2Lv8RNe+S7RlJ6pg_3E%(G=zWFyq
zesyG7*pIyLEUpnDSiOZEaIShM<cA|kvMc{I;9YFiG%(;VWJswE)gv~~D{&&_)rKO4
zTGT^ifkOGd?YLc}u=|ITxcH>0<*7!Cyxknevr7<V>mdie{{7GVWz6}}K(Df42crhL
zs38<-TvlLXFD`)j8+-XXVJttUYO&uB_>NZ1O>cm``<u^JZvm>{c*9v-WK}j<e3TJk
zkk?t|-)7N+(@&!<&_ at G#rWN^d&L2E`YC*c#2HFpPvpUhfI;Hp2{w`nmZib-D4e!1C
zR8-N(|FK)Hcr)LA_Qt51H`p at ws9P>Yuh8|kHSN7EJ$(x~%257kf at Lpn+ItN-qm7P)
zAht6g?0P6*Kpo*`_O{&nnS#PXZTAN)LNneAM1rfnX}Njo9}emSsm;#EyQbV<c|&aD
z*&_oUR{8uz=9NCHRDX!?CSiM_SVJ^%R-u>;<EHs2slnBb7A=lLJ(7*vfcVfDu#@Y%
z6y(PoLP7 at l6na=j+A?!dmn<(r7I!f7vL?lt5zXvRLknyt_DMt10gp#c at b;v~yWKei
zr%m3tClTjNz{DzU6C!@qpbiD?D&KDxnw-cI!nRfiH)w^6;C8${Bb}YlZ>vA%-y5O^
zr|e=-+u{h~^0Z?3AE2KK(20~<MG_^kMz<H0<rIe_<9vq~;_A}dPZwF8$`zt-<o=;t
zOa5W#Wk~|O_^9}!zW`zHXJvkqBy5hc=;rD;V~f4=wwsGFV`rzdH_49w02PP&I%Drs
zW9J#(`Zbyd(0eVp2efLD7OaWx)`>IOyi?0ecahG0T~o at nmI5-7pJVHNMthv1S@!h{
zr2+Gh^w$Rsh!>b2i*NprFwf{|Kuc>cfp_)WtCk4eDGvh~A#%2oxO(|C8 at 1N#Cm~JX
z^0wt+zHg}+lCf?k#u;V+pXO0}1i7MkMdfOO`@LJD&1t{NzKvp;eW(S~lb77nWbw at c
zOIT}TpqRIY;tGkkmpM><t|j<1TA(c0Snj7((z?epVQFweWjrt1Z)T^)m_vE2E)|Mo
zDuK~zvs4&2h7A%5M?Kg}YnpAA5?i^S>KOW}bC#QTOBD4EkWLfv3H3q;Hfc>`wPSXD
zX$_|2N=GU`v_uH>*&35MvpnD7#+G`2ynIs__S+bg4ARtF)flrBbm1tuWni-yJoY3h
z$x3tmiSE=W2=b7z?Q(k~wPvfxjo7kR*?rduQp}Y{=z0b?({?nS(Kf2~d~wqq0je{O
z{62S2H)uxKtl0nda{x_0qtobgfA1Tkmmku-gUhr)R<4L!kB1#g0in%|`D9+*k1g+`
z!}%?Av6&prA}zIqs59>j8{Qt$6doGh*Z;XZw?KdvxRn+r<u-gfiSrx|OUF|LtLkAn
zW|Kv^3 at K+-r?A$1#{)wbUOng|{<Nc%jQJJE;>x=oCH%F0t%7K^9PL!YjL^a0mJI;u
z9l+MC^yo_~S=@DIdXaf0AspWXd(38~Mx8RFccyqeNu^o&0sE12p$h-aKQN$xhQK&5
z=diG?t=J0gahg$c1p9RJZ+Ewla~;4T0l=MpEnUpSXeDFblsDHPoITkc1^I*r at U0_0
zzE5bl4On at FQOh`A#8>>~ysyi{{SbYGQtCYbJIaL)e^7g}`hQt~U2RC~TKA8b$k_({
zYLD!blmLU at Tu)Y|9~q59-jKRK31&Z1ZEO0GUeBwbXW0QS5iT-jlZ}+6M=y3<41`e?
z#+DQ$In+kQlKh$)&W~5uwP at jt8Mk?3qyKy-S|`9PI`70vJ;jX at _-vTU%EJZzUu?^c
zx at z&F#yxwsg=MD9E8RF-=vxh1yv|89?cRIIC5K{`jzC|gq*83k6KbkYSU!~==V<l&
zs__ZGb~MS0S2n$@c%V0MCmI%3(y_<@APSiw2d7k<&S%PZ#5cx(sAmIoHS?0%;fx91
zr?b;49(}Gnxu(o+s?W;<p2fcFju-i1P at hkt<kc2{y9lVS>nus@{SCH^DSaEbPPgly
zG_g15h_(Xq6ZYW#2FxDCC6AX+14;kpelM)|J8rV}a>wNF#WpzT9E0(D!FED0V>h`k
z3D#}G00nVTo^w0hirjuh3xB`KKPtsjBbopSPdT7RGCq~f1{VR~UXAAWUZxuH%+AiC
zz5IRo%1blnQC=n!>eXjt?A3w|G`{eC8dx4xE5492btpmel6K+;*G at keJb;bst9{I5
zZ*F0B&}p4F7#hd#`{YpNbk;Z(kz{zMSj7P1*YTc>9eib%T_ssd2D9?^<KV|c#RXZG
z)}D`O>xoDz&eDd?1WYDZ`nplKLnx%RN*40;H`#MDyi<k!t*Mgr`VMU>8V9envncIT
zbkpo}{EA95!))>whSxhfeH?nlebFDB_sWI1_&W58T{}`n__-}sup-t2sq^Cjt*YCR
zac0i-X_CJ64hy at ixI^8Enc3Qg`Ya`7P>G>|Y^9CECkLkp-E;?ED;f!98;w$1{Nk3-
z8n)pN7qhI>qj+v=MU~<NGM(5iCT)d|t`5=-tMBY4vQK)I>`9m at GFVT2nwq>CbynXI
zvQ}a)cO#p;zO=kCot~Rv(+2%-@^G>t^Y@(oYr4bL#>`A*)qm5)z6aIDLw7p>NXiQ!
z6nghD<ySUOe?0>ZkdZW)KmGV5)~&dLjENbN;w at 37+u*?b5~WJUguK{wjgT`=I#jLG
z?NIEll^9QTy*Q6-qbA4=3sH;}Yyv1jLc4#|s1tvh2?ia=GJxh!N`4drn>1 at M+3kAc
zH}Tw{g(;xQKaJ&pnZ)H$CP(;#9#hI at oA6+{hksy(bCvmn|L}@S97-i{*2#)K*L#{w
z4Vj4ypzJ at b6);7j`N at g0%>YgnuSg;fe^tM+97*@LqzdjNZf(!Oa0GASBhEJNeZQ!5
zu-+n at MD>#Db+kijm#ag;?{g(0Tq_sMcbK?)CbQ($R<h^n_fJ{})A{i%G%4-errEBM
zmNyh*HdicW-l8C}djjXiPm>Xg;@1Fv<mUAr8 at +v56n@4puVx6ck+k7=9&V({2q5~>
zI0?)Ge|s3pRJW|1>>50MH2KHzj)?=BbicTME}_aD=I+53ax$Y|JsMfjYV-~Wd&Br}
z13h6=bOA}H(0EyT4g=o87hB0xBs+7w12YWmit{YUFIbS3@&1IB{UYO>&1{z_4jN;#
zvZ5Mc4+rD at S5nq_*7MWPdBDJ$rP;`*{__%OS|wRysr8^YsP!o8n>L|wW6vCfKwDOm
z*VIbrvO!6vuYLQ{^rsxO9HAgWL$goyTEV=MbpXoRaP^uYc5B;V^5#CIhD6PLEQzyz
zzsgH0#P3)tY2+icwy#RAc-fn~g2J0U7q#~fiJ4|ity!_XRNVM$%xvcxsDdciu*K*?
zf7IfciW0`L&M`(sGZDP;Sc)-K+da~qk{Cy<AJ3L#PG?+IlKsMta?be at 9n5P+EE#Q4
zl3Nhr;B{_L&e&HT6#LC{G3!BGSrlOzVu(H0e6HzCNA^|UA*NloE#`#Xb*^rKJJO-R
zE{VQ|tSD~O{B8Qt%XdcAMq#b*M!>_s+55V|W*tzcfhj9jk%Vrpg!1fDmQ!7p)G69u
z4Fc7P?RIj!wRZTgN^Ev6H$}#ht2u=pFZ073rfp^?;3l<+#zR4t&nnDsv9o(EUHV51
zm3}FsT*$Zv?q}1=?{&@f08a#WD&%lT$HRI!fh_YzhMq at Ml*;*evTjki-g1+>d9I6&
z4a}2k&GUITDQeLU+G6z7qB79JKNQdZrIrqLdWqVjlXQ^DuJLrp+4v0K3uv2Cc#%K&
z5!pxm(%Pbj#Yu9<Yba6-tH>S6KP^iX(=ZE{R<^xVkRg}$y0}r*UPw~=;Lv*#7?RN~
zY4~i~+#gV2(>0`E#ni%DLM12zGJk2ItZ0a?3*J=x;h^_(I~;h|%%OZb at BJ6pbUwYg
z-evpJeaJkxm!_0ZJwrxSHoL6%BH#Au<Suus?ya1Y_@@&YUM#E0_5oP3HlTQA<<t`D
zXwTzhy!HkF0ky-&PdLWznsSU71gGUEH;$WVR-`8Q%Jm6VrfAW at gVSVmU#hcZ?A<+q
zppTr!v;_2a4^r6m!%E-(+Qu6e8Xfin8!qj0ybjB7Y;)jKxVV8Nv-3q|>G5}HHRD}h
z7F0<PCd8vfn*yZwq&KgBlrXR8_u=c^nBs*z+8 at Ok;l{A)5mRq9%ir%jKYDZ^cU=lF
zpiWuSd$o`*;%G%^Qf3mCCYd_+I_O`E=IkYjrBT(Au|O=Va&d?sZ<3t67$^@pI~k-v
zq((c?SrSq!?x{C$j+l0t^IWOhOYmjC-1n1t93&O5tnSGR6Wo8>7BVrEv90ITxZ6A(
z<Mw^^7+8YCGHAb8O*@<Mf{@hZF3g(Q&x}?y9~;CHrz-9BH68`FMNpfy_ee-?ux}^X
z=pN*L*Eox%{R?!m)3FFXDz8*cYCQYP&XzQZ_tzIEA90+&M|+eRUqv>rF8T at 0R=CgQ
z)`uyk_BF at XpVU{1k1YRh2E}2rk~jrBt6$(O*l3ZVoSMr2<Uc6}MUNdRKhue<iStc`
zEP^6hzXjEJDf^flS(piS+B)_UGxtC2^6x78bWqHqGMa)I^~hIkr!}9LL*@F~n6K!n
zi7QVa{v1m$h{3nN)QajX=&D8uch|XTzES}<4&`bQo`3!~W{8b6k+0`F<c;BTMb{_s
zG`{2!y{+q}b5nEJyB=3;)9QD!{Xa^s_S1NO6EkXTsyughx?skv4|yH>${yJEw}`oj
z;@wS<w6wwY6nH$h<;Cua+V<>xs=osGr&S9N(DRRZbuRy1B1GL~ZT&cT)I;Nbk--An
zn3}3eK5Znr?*bMW#G36LwZQg`?#{HjyA=<kqA^8}*H}p9TQbj%q&4{Cf!gFIri4e%
zYXDZ`KjTd5r@&&n7ct`KK3HYc#0XIG8Z#vax220D*5wQaE>>Bg((bu!>d^=jC$f0S
zyoZBA4;c?Gc9OHVLj}?7X at IjqY*<2HsfGJ_vnyt2Hj&3I3ibegc?n~Zqe)e&!Kp+{
zsa|~2iomxu{(yasoCasq&_;65w2SiZc2ai<zcC6uK{z<CS@=Ft>aG(tmQ8P%`oZGn
zHr*(PuIuM0$w#YC-n1!0O9P&r>wLqIn9iKTTnJKc|6~6YF*U at zVt&h>pcLpO#w(_L
z==6tsGHbW$1g|Qrlh^B0os=}r?#l|&-JDItRKRgG+<PSmY=g`1V{w#0p9ga==185t
z)zTO?OTq^5EdSPTDAz3(psr~~QmJZP-s1poNb1tbcW&X at scOhj`rv=(axa at IUbZz6
zuUXwzchAl}Sml8M!>wR}c6b;?e`G06I=|`qP&TA9MFv^HJzXYTt9b#MHi9&@xxCuf
zWYb#Q)=U!gu8w`*J!d2Jka(xtJfQLmcA82X`GXope!`5m&#qGIH;8PxH)ulh<VImh
zh2$~s_t&<`S6L#v3;uuXHT~DUOsL;E+VgP?2Rvh#2#+S)&vSH)&N8UD+5!>mQB|?m
zz3-t$R`wp at lOoRtE!X2>4cXEdKcWJI7zxG3`*|Wy46)$@=c12I-rWy=Lu}Qzclck|
zFf6*?%l&jCHAZREFR_%~vU^8)W*e at a8H822bcRLWO?Hh|sufkG5Ji`@IKQ#tqm|*=
zbp|m*<p4)Y5CacLyoRWS!a!UA)MQu|j8I!veQ$rc{<T at nOA`<Dx&Qyf8y>bATbfWx
zh$G?ZMG0<Iy{(A>a*#=7!8aIiTl1Z=y)j~p&{iCXdAg$#5J4XPjH96)Y6$T%<Mev*
z;QKW`!XFQ%{X%FTwA{7EQd(}g(J8L`+WZ9HeOWH1HJmS8TZP=-z#D&><SX+N4`Acx
za_`ffkeUE}7kXCE^Q|Jo6yWm&&u1*@@vt5M1^wke{j5$P4!vQLY!iR>UEAUr_5_cD
z4KLa9{i>v#Ae^A62X{r6bpbTVFTbiv6q!cnVJ+!i{AXsg#@F>=EJg5CEFH3)yC+>>
zm%FXe<M+39+-2D4Ql4noYiQcWnmLsHQVG at Sd$cZhSNBl_<<!a3!;DyqY8Em$`inP&
zK}-jaPpvBJ%*k}o>L*xyQ(o-o#;pC*C<8$mJCrtlfY41AXslChW3y`m0;vBz7_aVo
z=7vgv*cWcK9v*@H!(}A2Q00UbX_EBM4BUB_)h8!*REXt0KaD1gGsr$CKjJ`118qxl
z*{^A*Ks*rXp7gLaYQZGv`sCw$<L9M_$Wo0fKk(#>t$l;sxTptwRC65ITOt!c1=DO1
z9Wily?oi33a?b7XTCJ29EuYf+(dC5 at D0A$pC)YvY)Q>|iIRc{-3=>QjYy_xrzD&mW
zDn|0D|C~Om^eDeTm=vv7WzaV1GxFdi?-JyhBQnC>ObWvoGAT4AYuHG4_}kQ at B68U^
zOI8B6zTsx{j68!3>l6C?{&1KHt+47YFGnNf)NW#35hA7AuK4SDT0%DjRdc<Vnd+yC
z=+DMde@`#C9mxS*@3OS)bCtQdA2&CdH^&9K|Acw!KY_p3B1V2{<C2#qTuxehJ|4q7
zAph{Ya(cg75+x7~0Qz=*lpcxD{|q#1n`^0W$Bb*5k0$fWqQO at I%;5nWAeoYy8m*xS
zB;N;r9Y$o+ttoYPU)BJzpV#v%$MEA8+IO8i{{y3^B47XM8Oy-`BdMse66XfUFca*Y
zPgX-2%D43 at nn>W1I7!6SzZ0J8e-d1VTU&A8Pc+H*e<k}(X&Vq#Ujph8<1DdH at vkUD
zMgH=v69J?lb-0Zn?zhP!*UI{?ZsPKV5 at lqm_hRdoZ@G_^*i8Q9zm9EH9iSeAu$NNP
z&ruXcBZX_pvMGj6zX;F`hEMNmb!1}UbNbU&zbFJb#f|B2;fnUT&lMc at feznt%f%%S
z%}}2(##vjO5TeAE`mu1566MCUW}ajdIi}^vK|);ZX_Vq}<1j7S!MPNk)aoyqegpha
z>&!c%AcGZ}RC3RymLJpO1A2R`BSmtQI!8H3|7GhH63bEwQ{b7KCc+-kJx at gQazFVG
zsY#%E<#~z#sB*}564GOx$B?#PIW<+g(@f*9X;(uwwrm5{!Z^rluoAKE$sS}!DX7Us
zPL_Eh;@)!6bM9lPM+Fl>Yk}VeN=<rKXK9)i-rjWnoEp^E%C&sX_5 at Vv)>TL02a1n<
zU7xS8eI%(VmJEBEEOMC;Y6fk6DcC>aYsM*3GF9KTEt)Eyu_n`G=|8gLOeG5?oex)J
z4Bo3VqNG-wH0He9pp47`we#oAtWtc9V at C?<w7LS2fG&J`iq4DC%J1IA**7hSPl{2_
zBOr0 at 7NzDO`OSaRIRQD%2k-P2FMR94UM4hD=<(VmHOWTmyGMY8=blvCqFn(+XTj8B
zU>};j`ffHr<6`6`z?+-AciL&{hTOc4-c8~xJg#xQ3;n!XQTB64q8XP=VP8d}4ERR&
zPv{=Q1RL3(^er at ky_UcICZ0BOM$TAt%cr#><`a2F5p1xa!PnHcD?WIc2(v*Wri6GB
zCM~bwk*5R40b+LBaAa^bfZwk{07-=Qe#y(r7TpIznVzQ96nc4WSQzTwuvaTMBQzJs
zHc<ZX3vrJ3F~G}u>cb*Y!-L<astMq6^OZ3PtFf`h6(J8${>>x_aeJyaw5z*}EeH9z
zCAhjJCCt;R-ucfdK(IdI)5%^d1#G`H*4w(2KU?eS^;`3UuKk*@xJYz9Gd`}EcF74c
z-!}f*I^L6csIzU*g{H1RAW|zT1DldjepNNtv2Tte&#nL%7b?AwT=&K&;_!<^nE*hJ
z&MrcOdG%b^*h(wAPIUL;COsKAln*a6f%;2m_i}=A2&*W8QgxoC)S7+27Am$0=CWkr
z$Ac2ndLSe36rv7RIin{6oGD(irQ5n=<G?Of>06{vJ=QmjFOjv#<2&t#wl+je&U|{k
z9_M4$?yUVyKprHL1bsWl<jwYk{SED#$^9z15sjR+jtA!EU(u=V9VM(y$=c!pV};tC
zO#<IYZy>`H6twis+j^0i#<BOr1q^@jPy8S~=szYo*qR072*6~3Q6}q-mLzoEiHm4U
z(rv2(*WGq;4WT=6j{8X-sIw2vppy&veGipZWE6&+HKr8JEAlj*=2-c3GOJSI?=J`a
z+Z(K4_vYXVj;8VANNW#qr=ATdmOxRYtYh^)l#c*F1Wcst=i&XgCcf5`UlBxm!(efr
z$jhup{ZacKSF^2LfzIP^my#LB%*O$E6Wp)JNVBGA4hZ_DOt2Zpu2*}nC-{kQ3Bgdj
z_$4i%N-^OHLsXp}En&-|;JDQjY7Pw}OFUL71&1?Xc#QnZe>1wI1>Aikx_t{+FsQMQ
z#vkt=9IIU<7~=7&5zWEV8*e<hsX3!gcAiyB#VoCPWln=t^?n^n{qBAAHRJ<Wp`M`5
z-}`}A($C7UcxYG+peH<cT;@dJT6v}<tae>4oslOnwdKPhs`i;Ho9-{i$8aZ6n)!*M
z5xZih<>zM;>tNbBYv5%W(-e22Ebh=9_C*Yp&K+*pD;3;H!Z;7f8OCK4iJQuCJslOY
zTI=eRlc|X`VO6NV+S32nY{MVRcf@!8>LQQt=ZxMSPVCB6c4SzW^u|nZ?eEsNz7WqA
zO_EO_cMW}WlNolX(^R)H`qrTo|G))IfQ?4{dk_$uqgQDZOn@#DvNXAxC($<6L5P7Y
zHR-&nrnLQ{E>IF%_jil-s_H)CIVrx|l4?A&aPd<3d8NQPAjo{BAglYUcsnaZDR9or
z_*{<pjbVsWEShwWI~TfH+OZ(PB6$#VpZ;N2FlWz|L@&>e9XXNqd*l>9TNb#@K2rNq
z(5D+DXp0<71S at ol5~op%cuq~rs>OyvJ?7PrEM&B>pvs>eTq1Ptht?a-T?)G;6^(oZ
z<@=R=HAyz|(T5neHOL3Y_q#QH1kggeHcF#x at 3mfO<SY8e`>B8#>E%`6<q%h~0Bsbx
za$<8cKcuNrk4+{@9gyx4d9v&FLpSwQIheyKRDwCdOE-r#6&Rb?21?4j69k#(^e&Ya
ze2>mKVjAdNt;I at _;mCpHtWU at -)YC8qhNenYX6j^D6aFN*dK-K$nIf=xhlro27jm8y
zGt>(<0<4cV#g(QZYG1=JpZqC~bxaZ%+*WOVtB(UCbEv{MUA_L%rtUA_acOgI55_N>
zH?&?_EB29Nsil9xGTXQ)orG3~e!(kX`zD{#T&dav)^`Eko6=klhjLZfEYJ?)ttX^t
zW?lCmnRYaDts1NyXX-cOFp)$$m#KTh)_I6mZ7#e}mU_uKf+fYk2a?Pqfvtld={^r9
zTt#@((5`=0yFmo;h&w;iF?`sdySGK1UisD#^ckDs{S)5=Jd!U<+WubSz+tgYr8O?K
zgke*z2h}G`+QJGiwa52XKlc*4zxwO at A(`uO<Da6qK8NirmWaMHHMY)~^-sHUVCE8T
z6O+4ruFALeK6s35$AwLT=-8#QGtqWB27Z-+cSk+Ts0Ep>l)_)$?%+<D34qzXX#p_+
zs6V1-qcKWf86$fwd1(Et-Ts^(ZQOhGE6<h%y}}Yz&XN|c5FUBOvT`4E!f6L`;ghn@
zesq_BLxQo4A~FN_j})pnOYy+lvd!l&kPeVx{it+xdQPLWKfh;tyvxq6wznV#E4zNS
zWk``HXA2GStLuL6- at u(^MmvIm=2Q;N`~#RslmQVZJhRMO&$0~T-nD*%IcB~-UJd*J
z-FzKcqmKi{dQ<bozM-rxQ#q0R&iq`B&cCveIBq!rzX%G=Kg-6)MJ1hH1B<s-w|JdB
zHD91Uq4r+Ktm-e{>%w(NWxigMF(l87TClKs5j(@G at udk7eUKXjr~uCXT<-DY9V7a3
znTqBzHn_rKx@^P+cuwq at tDA+W;|z4;MI&8OL6Ezue%v4U2#~_S;%ILEIW at uc|L80K
z9wec;eR}%|6aHoRM3b=apAjm%bG(jf)#_%Rk;Qs}F)=b0mFYefl?Pn}3nBGFHe-b{
z;e!LnIMn%Qi~aLi8xr3y!-eW`Hfq>WCmj++;lCQTd613A!leZIn)T{Bc?E+mztgYD
zfzKi9ZDLcG-wyd98ft4|E0nd8KiG1rdSDKEzyZKG$H1uJ`vApm@^cCzdZhfOt$F=-
zaw)?V%R^okF$Gs8?mGsy3u<hBFnKzOc+E#sucuh5mT8rYv&W3j at W6#fA9;t~T(si|
zW$;WlbpfO*6hv;IbH6rQFWB^f(9?+Ixa;mi at t%FAa=&1T0LeqK$KH;7Zu-6Lts}^*
zgg>=v(_Z8|{3g&!sW{Si_ZG>&5m$sOhLm>8)y+r-0&O5(hGr>bt<my5(CeRbQNO#7
zlsR#qxHcc%@vq}Q2VR*dn#5`9i^pgFg9e$*7%i8Bs%mS)s+)Mf^gw=kKWm*Dx>l<O
z01P#yEOyY*w8ELm_!4zNKH3#cg61rX>!_|<D!er87M)yFT>&}G*^5 at U%ZBU7vX?OZ
zJjxj;S!d~KUghRi+P_%CJf-h)Dr+?&nu}^W6%x{3+NQD3EL@#UdQV(COUP$MwvILq
z|5Hf`Av%GH=o|LE6X(5jzkPNwvMK#*E<*9)K2uspZ0mR_qJya1U}@Is?%W(eh}&+Y
zZTp<S^L$~saAZcWOuW(|=f|bmPlq%QYn^><pM<I<_B9AyQ-P5r2*fy)YH)m6@@Bdk
z*X<l{OMJvlJ~d;z7bONXNZMcg=S5e0VDDR_s_6etbT`BsD78rbiJ0t3rKYXyZOY9v
zZaPsGnr&0DzTU^!c$jNFo3cv^OF;A&!?yjk5~n0#Yc}LOJn=jJnvC|8t*6a4Ixqvo
zP}!j0 at i#3Z494Q8&l>QmUAW$z(XjO6AOHFuJ;56Clw34V*cVwoWBE5(FOCwaJYdW5
z5m=D-38CZtp;DSdivgq3*juLJf~ilXDV1Csouv-0B&5NKDLY7Xgi(c^rL)ZswSIa3
zIReAK%o@}Vm06)#s*d!NhnDF}Z8~71aRspw#jkyJ#Cv%sPBF&>2TaOj##%XntpYTR
zQH+1Z>Gtp^{4qvNi;2j-TJ^?U^9R2`CwgG2_=8VbgsZDI<xKf&mGn)6^->SnuJ{9j
zD#yKq*}8BujgX)FRj=CttxJ4eMhjPZy*=f<$-G3FiH?zUm at fn>a$h1^2OG|tW@^>s
zZL;4wGHxCj6knWfo>D>LUUVxlwRWKp!CN-r5I>ZmE7j^c2#RlQt_6m!f5y}j7C0O9
zy$nx3x$cEj%@XrGnXEh- at H{t;LW1axIFx!<Zls7t;oB;8d~Z)shXb4*Obc>(jBBd6
zX_nz|fFA`2cQO8w8`E=dZ%uB<XCn{?Bqz2PeA;zf8)}XrLYp$I?293u4J3ZnM#jx2
z2_u|PeH_n{qZ at d*Qz+hG at ni{$JSj6wT{6B at dW0#CMrpSi|3%mkQzl00YYhrDv5;Zh
zMRZb+>ur+sctbcl8-b%B`tv+w8vH1V5;h5j?pMX{w`%mDFFSG-R+6CACF-+R1y^}j
zKUsL+n)~O4j9Xr>`n_!WAuR+ at xM`EWxCm(x)u!)>Fqn{*QzlUh#@w!cDYR#&N{<2a
zJ0mMZaD4zoVfo=Xba=nU9@*e%SxR-&Z$Ixb$D*;4C=%si!bhvsT~9qzxKh`ubx1w9
z=xAQP(3B7vfZL129#8iEQQ=hFmkDPy{=A&z)Hin5aYp~Q?^jfBViYy=*zmsVT9o&3
zu<#MLJJ+BN*-i}Iuahp@>U~h<e6e|-no-=Y$EUH)s^C+=4j&q;L;H65Iun?&D?=v3
zR4YI1y)DhP0hPrj=f_5Iq;CRryL*cm_a^a_oyiB4WV0;q&a at 6cs#X6_0Q(xq)?E%_
zcQIcTG at 0OgKblkDgG@B*=Iy30-VpI=8~0oKci&>I_N)kLC;GbGf*ScSOw(NCefCd9
zw at k<ucKH&P!Ih!+2T1O=fpMkLAxpOze>XCFp*<gnW>ZSkQPMA`^8cm?<{?mxm=p6_
zjLQS=f2{f`J~O=P_f3J_eaxq-1sIbmGn>W at 798ZO&Me5~U~fuh{OtKk;!3shdOBUH
zc4-?pLG&BO>nlP=JXyJJo)q<$SFA)xOXU!bG&L~iO8DOOJI`Id)Y&QNn`6}y_ICy>
z<1 at F#-uaXk=Ua8sHV1FHAh23yrC-1^-tA)`%r3;?yH`Rd=0|@;K0O{@a at UQ7(Xp9K
zt;o?GuRRRRD%9ru&Pug!{9rHS_Af=wZRw^K3*d>*vvH3mpyyWfVia?_>IxsfEMc%H
z%TlkeJi+u`93ii4VDfL+Fqr?+$|Q-6HVquA$?_0XDIVBq4fl3M^K;d=;eq_-mgH<Z
z_r`{en@$szJ^*CBuQ+KNsl$w_23M{+W1~^12Tu^!lqHzi1Ga?xyd?TP1%mm%EWjHj
zFKP+Buk93bzdF+&OT+z6{|N?q;rPXWuo<R{U)A$^4Rl~23fy$~`l=zqqvX^<OY!x9
z=Dp)QgB)+<4ewY;V~>pyRFK|!>D6L(afH6?Jnyke{~~;@c5r~C=*Am2w6VibI8`#*
zJmO35?7)8UV4!r6Q^i`c&`X$Q#<12z5H7JJ;kOv;pW1P-5?4I!aZnEE5KI2?WZr*X
zYhi0Pq3F`(P(gl086nI|Yt|rNrkcxhr)aB;Lc7Bxkm^PG{A(#@imNbq>BX6`Y~*8I
zC5=v`WrOEfnFQ%Q{cHzFG2K!(YOd>htzp!~Dbxb{vOJ(VE?w at s4&mGCQBWesx)Clf
zuz;zEKx;VVN8 at _#!E2Q;KK_s*Dk8qSWkVN-ksgGBQ_OsC?Yg)b#+bYm<H}oafW5w?
zJiAJYS1x$K>fo#sP4XpOJlhJ^gE?|d!AkO0lBJd^nQzQSwket<Mf_n$HUXwh#qkm#
zT<kh6N}FcgSG039Ki)lOuKdg!=^>owXj0bx`P<%*wm_^zE(xK}!xw!nO0&z9bJ*8;
zpivg}Hd0 at f&MPX)GeE2TRA5KR?^N>orsoc&Ci2$2H(S1_bwa<1TISXFsL6gfy=0`=
zo(R6C^&z#r(k$&ms;fWIFq2}S at zVx={~@qVh>sQ$zG6eR9pFV>wtM3 at jFQlfBBT$T
zyR|Fa7jlSS4hlN?cOOt|%rI7-GHDJ_OeU at a#^lc_-aNb0G-JVwBGdR-<?jrI(iYo8
z^arNh9k4TK@*SMAI_*pTE}NFr8g=zFQ$ndPHrQJc9K;VOpCG$jFaI4FmJ2y)j^+xK
zuxKy8NX{9pK=V;+a&`sp>HGjJ>xkki(BrVq>XaLNE)1G<7_yYsx1)zI9_%3^dVw`j
z{Etwec+BPXx2u6CX}`%E9mb&72M=2AiIO)NZe2J9)tZqqnRl;uiXPM4+yL>Wm?I{-
z5byiBbCHVilgO$>^XslsJWgWj6rng#ZBHxV^?0Xd){l5tg0z!bSd{0vo>ZXm2h#7f
zU0ziDj+JCAO?S#r6)hm;N5ZJArmLJ!X)zx$mG!l;j^KSmEw+cDIg0?YOcfHgdb`ve
zB^4tQaQunPdkHt6jAu#w^Th5lZm+eA;CFbKN$rRLa|@|Cp%3n#J5BfBBI=hCm8J4s
z24%2JuXA)OX{V!T7_nW={J1#faM@}&<ABJ$-G(M3w#)L^ZSIugUD1brq6MVXTtI&;
zAYgF|ak3 at j>ZX^X!`G(?-xJ!ORMP+lF%M4&JxvCl$4_M&wAK`pmMNwdy)lxM?7XZR
zOUda~Q#w97UQ5#pGs=K}0;^^`4}g}p8(D_B<O)L>lGz1&J|NENaCPTQVAT^Ye0R^Y
z0$iujwkgTUrV3XSN+Y``Y+j{Q96)}XwVO{N9caBaq}M~HeI~2tjRcmy`4CwlLB+(V
zW}*1Sp*Biu;-ekvf~>DN)w791W@&exlg2=65^c`^SJ!#Qv-$pQxIeAds8%UDP!zGX
zRa&b`sU3U9Ua_~>v(zfJ_o}^P6EWHtwKpMz8nH+15#xXNdH=*auks<euj~3==Xo43
zv;Tbf6D8 at 1kS>NKB}X%EMd-UfeHT+>8-e0`{nsF2&d+t5D*drK*DBQ>ECHDlGs?3B
z9_H;hP7+^3cvIRJFt=uOtM8inufq6JD5R%67Ei*im(kMiXM)hm5 at h)rvV+*GB(AP%
zBY%xmyVet at Z%xg(wE6S=&9AQ+Q!l(%)ito%9ICx at s`O=Q;KXa);Y7ll#n2Z9yIG_a
z%X|GDzJF7lP@^w2=){}4P}<D;WjQO;GrLvk=T9G~qKb%1ywKcLF9DEkug8BH$M=3b
zF;Qi)L(a^S8yLW*SO_o$Y9yLLmctCxj>5AfPw&*n1kB^ul16qThpz!Kyu;@UHwbeK
z$Kp&a=y<EH_f|XIqlcw=TKks<(S#nE4Y<=giz?NUI(_+1X~ua<oOn}0oZn;gssrL0
zNTYSoM*1VI4BK^{f+V+9LO9<C4ew5f>o}Nm@>)p`cT)VflObHMZJA0hQnuGVy}~LG
z`CCiFmh{mVOR;34b!OE#)9F9BO#Mz%gnrifl!b4B?KdJa7rUkKY5uoAF(TRycYZi^
z7j+#vEK4bP%O-arpxt~d?UrPl>Q~NoQ8Y{EzA#eN<#38lnpL0p$`CQ)M&O<$_2;ul
z?}o%<YE2*(=>|{UUchX$uC%?%>Ln!G+(cGesy(O=p7I{*{Nxv-26%=9GFN)0pIBw0
zy?gUNXO)x4WU+^+!1~Sy8s*Lq<eN=eneDqq!}-we_V$=g66wh at b=%qCQ4iA&YkwYE
zwPDh$z$v(?pr;&mw%}bmV%Kp|r`v>5^ZXOA>5D$z#ihXtc{>~h1+a>lsknO2RqNu4
zpI={LPvW3U7rS7`R;Z?oxcyW}^Q+%g)nyJE!)+qpfnj-u$0L?59 at 6QvPXeFN{wj>Y
zCYemy{85*_R5tvV4W7z8+$}A>ARjFI8plT=tbsSlaK^|bRmF_&GREO0OwlZgre9P{
zkdII!9 at QKW$3|nSYi^6%z?qvjZ4#&DhyO>lY0Sus5V+j#dq{FzDqq~)!aKmAi$c~U
z&jxBZt8YjZQE)=or<As<XrE{6Co=H91JN%sL*(Oy;%nyfGB at OX`#v%mm+k7(e3M0U
z;Lf(`3rROeYqvIM{kI>$J1!`QcLL;UT;=}mVv)%makd3?Azjq{FJ+-vvlcU~MDZy@
z=x3QcyfQqoSy6F^XOA_$^hCqIKRmoJdWVu%3>iSNM5ep-<E56d at LokLvCUi=9jEuN
z@&%dXqUeDo=)2Ut1#F4L+OJz&33<1s1-Ax{^m+4mPqAym*)Mn)&=%FdvNncd at SmSV
zDr-^UG$S;7l|Ve1`^ThC6sKG8_7ASj3f)Mb;3T=f3EFesmHT5i$t?$6_q0p2D8FA*
z@<3kSqFP)z>iq|rkR08B5hHB0)Joa2l8eZY&<EQBPFyt#_c6c4u8zh at J4-#xDBQZ7
z_o}(8LaJR6{qi$~$#{wPYb3SB9}$0xudkG!wnC(!npp_GYT9()y{?83Hr|K%Uo#Z*
zOc2m!(F*tYo^TB*%2Hhsa)P?Tn6kc2$=?KeRFbXfk3YwbYjq4>_72m)pnfk8KCYMT
z_xO$?6ZVRGI>$%^reGFFGeEez&5?uYo0eb9*VNYJUGeAEt)~?0gLFV>^0OcdnUF=E
zmh3T(kAtU%iBhf<Ub0fUPt7Np at D@9j%wg%fAWEM^n_{;DV@>+x6Hccwckj^6P_lP=
z!Qn-#|IIb7cIC3-S=OBMp3fdh7ZH~$M>7wE!gH^z((__Kz18!KR(_TkqT1+jl^E;2
z8pc&(^)AxP*RXi`CmjN^ehHLe9*R7aO%h`Ap4spm#g%LI^=V>ublghasHjU-$d6`1
zU=^4Fmg=H`N}Aw&8<2=7k}{q<L6c*u6w_ZDJpLL%7sVe^w>(-~l4dc<)24~zd3T7r
zr`iZ|_fni at Mpl@lhsgNDPb;+|hOp5Fz?kCxD#t-HZ3v-k!&cB=2GZkK``W%&HY at P8
z5LO!lgH0^{kXv$Fot=@Zy$9NUCT<d`W#Zw4?Uz at Zk?#cyA4VvY|AH%P$0sE|F<=WN
zpygP6;&6XN&U!cB-rQcXwB?ooklfk)C;62n at W<~oIxvf24<mIPa$jb+U<+qoCdWuX
z?KOg at WRWffL3w(_i~|q`L;I0FkhjkD(YVsXVWe|OWt7kF#KQTnb6^r6NlJjl at K?tg
znvK=RHvnPPuC*nr&KoDWrL1HK;JdI061d&(4Qcz>4wuM;?xM=!2OE6u-YQg;Huyg8
zk6i+$)$YYUUHyi|P#S0T+Hu(&>;hn0Lob;8@&G<FjT|chHfYiO^+76!1SQQ1FiyE>
zkF>g)v9Xx6D?z~j(NKxjT*1eujdGLd5F>a#;yiL*e&@OHo?H^>=i;678-BZs8w|1$
z+Z at eF+7ZXqM@}2*TuCMtmp$<iL?KQQ3QH)<zN+|vA!&a8-xwVQ5xM7Km3u|0&f%*E
z2c05(zmmb!B*IplC+HNQXF2eAbvE at a$ZALEclwJ8l}m8#Ksx%NqI#FW!^iiXhrQwD
z6gm5n>zB^_G?nbh6S*UWNtaBC_cJSJ%@*oQJ{pA8jpOBCs|9?Qd^)6T|5Fx(jSke<
zFxl74Ql2~R0{~`Sqh-pEWaI3 at M2j^S?KEF+TycX~<<?7dSHl!vzHQaiJUK{+i6E?l
zENeqNp*Z3lTSzeX=ZQh45{O^ycwu~Smc9u8lG3UVCwAJ{verISjVShg4@*ijY{`&J
z4wkI{oJG)k71CLv33W#k56U)-MVF+w+`g3kGEd4(u~HfrzJ at +DStN&X>8=UoWX30U
zas8lrS5cjheG<Q;F at N#w$hPa#l&LgZ`d at aj^c2 at c8qmVs$s&bfmbJ72xJV5aN;$AJ
ziP}6_15CD{VKcwQ`z&{Vy at N43pdbOsF77CExUIVlh}jAK`FfOEXjYu65E-|@LLfh4
zivhBm?F|7*0lIInACg|yHd&{C21HOYTMF2?V`>Sy$DLNO!S0EzQ=C#I+Ba>)#Y at aU
zPX16-aZ^FB<%}lIvQ}jxxT^WY2rr at Zjgt0=8Pxu!(dKqlCyuo<qQ{nz$-z$Xr6?su
z^5D}c|6<>g>3}^u064bX|0t;zDk78_K2?c^%(}f_V9(3=U|K+HHu+ks+Z~~0W4I_<
zbdXg14VOrzB*JIoW%nTG=hyv}d_9if9^ZocuS79a+cUI3>l42>_2oS;bN6ZoLM-f0
zY-VXL9<ukCj=J<+J?7YtHgG7^2!`yQhu>aKRqy;&p9r<6RmB8aW}di4eIIHnt$HBV
zVhWkvoyKYjU;d at HF`QARWWAi)toxGWnT4f(mzQ$9bKr>}cF}1H4EZ#Fhs8uA+Aihu
z0cUGUsZ!p!o8eCXgHkgA<XyW5;Q<uQEeuJ_Ix&K>>*3$^8E@}j*niCw;<A_v*c;x%
zm2iaidMzO7)C)>zN*BZ6QQLLp(Lv(YlX{yyTt8Z`)-bZGG~e5mNnhvmB?`syjuhvc
z#%v!>s5tIqZr8&x=_bl78IjzYcT9w5QT(Dko)4!({>AfqW4&Z$R4beN<(YYU>fKSS
z-ky~zDKs)r>(=xJ`C^IqJ02Pj+%60XXwSv({wm~9JW$8Ip3fhK{|QNkzI2adMK{z#
z*vd0Of^R{IlAxdIbym;V6^i_M_nSK9 at +K7DM@s8g+EA1QsfUX%)b at J7x5#jHeX9ZX
zV~{(##awen;a&Xn)T_=MW6XDj6(J?S%`dkj&gqFfIs at +Ols4zS`o&tiC+xLhz0kSz
zKOseNxm(1$baHR$Q!dT*kJ?z+5HM}=mhBdG>4(<!KzI}EQrPb at WV|sSzdn%&pq^?Z
zJUF0J^7$MoQncmFE=j*$MK984v3&8P_l53g>b$pLkb9lp-P4dL9bY)LE?o6bX_{3E
zqNR=n-w02OI5N<zk|v5-8!U|a`}erF_9?r6vqyu-11bmi<}BY%?&AU6Vku@*6qh=8
zDaTl1SEt*la|wv6C|ZTv7I??3M4k20Pf+upR*A%yBfret(yl5sX~MJaA_PC3M at HC#
z+i`n!4vD7JxPm$SMQTNcclC8rkyf>?aS|!CyKmxNu5-%nN!o0NP|ng5x2JIBbw%|a
znV_Rj at UJbU#`vGWH}Bp=&c=ih%XO#tiSm at jbg<@cbM$Ysw$kQX8{+Esb8c;g&3>$2
znWG4Gt4#dM(=c6%SdlX4{r!c7cT1WHrZfDF@<#UFMJ5rU2DvVf-PX<|ta~!#=Z=>N
z8<PF>;Ttr2aP4~V-Gbg9BGiGG*wu9w1h4ue`on7!T-8-=U((lCdKdLtF=53b{QN=X
zA}$qSm|dT5t?~5;hKX$rk0LH&dhGmkMc{40_5h)5-A{p6#6_?6V at Pwyvi7^JW{Ed3
zSvJF`UR|-nJ3v5%#`f<&fuyL2h#paKS6N%q3ufbaCWp!G6^WEESI?7k4e!_VGZ~f@
zI3bx_R|=5cFD8{X!|;%ONf}ccmBWwInQDW_7DAp6-_zB~PwW2));f!i!(Cs`w=1%<
zh;~%j>_W at qKaFRNZUIoixzHu?n+omu;cVu9njx!g9}kbFkMF>!S35R1<;=&hA_1&H
zn at P6sWC?Q}evV3xJZ^cInm5B at 7Mm!Ys~A95_xty6`9^m#KAV<uwrE;91c|^sfqOA{
zjojUQc>dsOkn%LiwqN!*Gw~J`Sok$UN{06?(G`gR)K9J4Q0!s4CK!!-$#YNJ`x|#%
zi at anx8-0y6u)|q@=@KO4E{*;>*N$xqm#zsC0<|qVmr-B0LU)-j$6WaQt5xhq5s0Gk
zb9D-D2VvQ|r-<OwA*5&F;JwJhEc4s91e;qOqB6Y&<gkq}8&hS!vd}*fGH2H~=Ms7j
z*8$>c#1E;zBw-b!_*lN$(id{PrPQX4-n>dtRPUZTyk?f%QO}8-$X7I}y(gxf0q_O@
zbg_93`OPM-?I2XHH3CjWY8eBuvMD>^iHYAXV6{tke8zknsAJCca5c_F at g#(^u7Sn;
zt}NvkzY68*5=Len1D^8w>-tLnxf9xp^1W__yk#hCQt$p9(&J+9mYA-#-%Kh#JK>-)
z47b0`Zv2z+F8x{2HkS5slR2TzQ`-v>La)W#vXmOrjSyyzjgn?{yhL1m$OzEJHoz_{
z7!Kt-4p6%H=PM7Bg1~aUn88Q%ICT^$s(w76l21!ymOY<|EY5)@9=O!yM~<h~R*w;y
zP!uo75LQLShSWq at HTDCuLIQGory%l*{GvU#c;Dv+tct$ZR6SLK4EGCeP5 at bqo{>vt
z?==L<T4}LgSh5)*nIRIOnUg2kMSvhs3+clp+I4{4ikA}UI&f8Us>*MY(qy=lmV-~V
zqy`_ at xQEcvEGmJK;3{Ebq0*$x9t7A{529G15j-30AiQ>9Ijc3V2K2F8w>d?BWn}Tf
z2SxYj%EjWWz4}eb>>uARtgrvrz at Gof>pZp;+TFagE75NIS-0iXT}#{ibaH%ryzAl0
zR2vX!j7WU`z2%Ei^<2FR1>5BuyXpAKGrkBi9fo(+D$Ek~`olokQ;MFe-E(gmr<Hw2
z;IXhO|Jc`zxV2sR<v;@ZQnm&MzzbJ57#=M$5znzj-8Aoljl}MQ^+Uc)dBi$2ovXBI
zI!k57HN(LXO(gspE;2USZOa8IGmlb9o9Ax}g(bZ&zsynoPXCcInf@=za{I(XoXA}}
zRsV*&1aHRN at I>WH`Kq^Obn`Ip-HBWlH#Vwadty4asHVh?C5Ef*tx;2u4H<ve0?Dwd
zv~Me+Yngy?3vQX|t6Ecs+`GybVV60H_qlsofaIJfFZaA3i&$c={%%sHCvma2I2W<Y
z?;*&~2*y^zcpb_{{xyj9d_ at Tg^_1D}wE0Z$#;>dOjs|h@)=ob2g~VOJh=7_NYV19T
zd*z<*C(qEqfQB}nIb at Uk)_WgF^D#X1B|c7oN=<LpEkNv?QuYK`eG-v+&(o=>Rk|RI
ziqwHcJXy)<^K!ldykSu|RMF;`jxFziJ7c(0Z7_LBK;2+SeBF_OJ++k$M*F{=i9f;V
zfNI2~eP1T!_cN2ECm!D`B&*dTA#<fy+wz-$(rP(;+$P at BSl~eN@$_`~Xz%v;*I79%
z{QI{((WXL+>_-^>+xja%VGdCb=f6N?-ut#|Fz~wCUJY?AO#!vbmv26{<&AR*qOhr1
z?8JK!LtM0K555&n9lULkwj~h!#r at -Pt|g_Hxg+=67ARV2$1DuNTFdF?ALrc|wiT^$
zpy%Q49(8x7OBYZlom(>w<<ei;vX1xN>Nl=-T2vSJG#B(lHXO(#-J2Dy@#$_YvYkkS
zloHvL+wlsH3ZDP%mDZa?L!vN)Wez0_5lbXNTsVpUUL!V8i&}$drtMBd{MH6WpOueP
zTDt>;e68`-nPu+V-QLWUVuewr=^u}UxjLnbX8?&A4<+6HwOm9cD$X%XqfoiGo5vs|
ziJoEhm)`ZrGa8|bqXUSkgcve!((Lulb(;3Jx{35|+IxGAU5lw0YvVwWv?-8mDlRuk
z7a!rtORUdy at uhRM`49_LqI~+gaEVLbCL7sCR#}04Vf@~pjrH@@ht^auiL8E>1b-*1
zJWTk}lvXCkS$xPhsT>2g1DOjE#RJXT^T0Y0aU$jIDayO;S`s&XsIS+kHlo3$((@B&
zJTS;JxHadg4gnHIN*M*}2B>MLnc?)DguXtWB+(>{GJ8jzI6F?#>POCmFL2ge=N_Aq
zws4wB+nYJ+^_}mIe3k6h_kdvK=^Lvph34-{s%I#{M3Dt1$3%M+K2k at FrLL^1&bg at T
zG^bd?wM8q<08XHq-RLcss%Hvs_m6tmIu`|HZ35eJ1texCL7GwA-4`SP|4PG=heqw(
z7#B;^TyS(`<yEN|5HDu#3h_2|vuRY;eI9Y$s_~ITrz&pMro~6d1*9=`yj^2#VJcO;
zvFq6toq+QPR>E?-Ob0>V`A;^~%?1u-Jm$43k_t91aa at KD1(^aH_r~}zOmJ<0DB81F
zI@&9?=}x54%97abyzkdeSdREHHtrnP8hRXSg?(&a{m5s at dNa`FAhyJ_iq;6kvuY at z
zNaMUN%6g=*qMog<{yTy$T*UGj%a|NdU64qwo9zhF!B#y5&mYd$Fq3~B#5bO<8u+nN
znkK at zs4Rv#%TB+C>?iEx#fulb;@ss~$?&}1{HMYn0h(U(A68*5yJzN0ozyfva!)iG
zUa35?c~Yr&swJ$$u{iC-w!i1{+eukeE^hgQBeES_D at S_)IBxBJ{#(kID57fuct)%C
z^Rdk4?2V9G3F0kYX4>4y$x)|3Bajov%yykTst|AedXMG7^#@)w#l!f+INw&)%f?qp
z{+e9txAQLl^cHK(Ps;kuL`yEz`Y{j^EUIk<w|1H%eW=4hXX-DHr)tdR>-R)@g(2;6
z1oh$*C11m(hAa8dx?HZd;r%cfy58AEb)yba3tv5jZf}2<!#4Ytnt+Deoa!CK-)$Cf
zKGxvJha!|V_Ijb}W2ay<1+E~Xow|(`vZ{H)Uyon}b6H6X<HL;t*q1DLlX-pl$pZCp
zh-Er>9<>W5XB1B1AZ&nj3-eybTbTlK&>`pDB#~L&b1wk`iC~OY>v!Pqum)vmDLtO{
zWyyEi6C~pcIeWh`yIV~!+ at -r5i`6A`pXwhJb@&8arUswIc}D)^CrvB at 7_>(%-ZdTt
zLW#ZC9FgoEFKzY3UzlIml}}e~4hU8!eqm~q+hbLEg4$&AMNVDN_yWW-&z%d}vZO|m
z1kvZhH<8+plF*rI(6&S6dA3t_?Rfz^%`{z}LT`-lv>C?C$M;AffNFg`y0J;So&PlP
zZ^gmyOd_{Jp`tR8%~Z(uU&o(p40{XaSnI4|BveEi`u0r{>O20P<>@!YSypW?hwDx9
zgdt9pdnK7YL at xmSa=c)*@~E at ravua)4fCE@)6!JcLx8bcssKlf5~v8IKbHLrp*1U%
z;CLlism}G2v~aZP;)0XKJIGL{KHKP3<fF-9NzV at Y6b^Cmvio<+rgBTWQB+fkUi+6H
z8h6xF-yUBFJC~Q_sn$e4<kk&|D94xi+#=h&5A5S=qkAi^46=YxHTe0&l#kNJ#-y=(
z-DVe at Y0g<2{3;ca;^Oa at ep^B`7*;RfCfxQ_N6Sp2smOk!?8Kx<e?1wGVlNrC_GLWs
zRH;{x$s^CzIN4PAAS$ZwK~L)2e`kt0FIe4UBI~Ij`&J5<j}58za;(&JT%}@n)H~mk
zDR9qX1YxnkBt0O0xVW+zV|{&o$2`%$uG%Z=p<=gtpLNTDb8SCp#nHC_GtM8Sz8c&3
z54^gXRbarzPF(s?XWS|gIrmPHOv7<3W=xbLf1jDLMQwsoNwP8s#pShrqz4!xibb`C
zw^_}>1nKK+A?<IPQMKyHH8D<oR^>oUxLmV1qq&1Ru<Wva+(Gz!3tc at g4;E}x9>umD
z&TUn+it+lC5?94^n$-LBW;$o(lykOk)9s0>)!6<3)T;uinignnOPAc!X}YY4ZSX|~
zxi at Pv$fU)|F!i~RzWdU08%z%PNZ=};y+FZrk(5u{`4A*AX);;rPc%C9Ha38S+*+1S
zaa5utwC;KuJxF${z&`Dwn||HyUOaw^^J|nI9Hd^I^@mjAyna>0`ao58Q!Hr_Te+UW
zT(H7~HiJ+5ckd_neoHR<&wwz{b*xL!OS at B6sG*@2sKxiaNr`;ZDi>7wW@@QTsqi~p
zosltXOCKLF61iOqV9z-=%V|0}^5r7rERRVynB48;Fh?=k#bKrnMfxx`+C&n&NOe2a
z!m%Oh*fdtF-L>@zvr8<HD`BQCJ6Xat(F7+$vHBqtNs><s^$S|3b`x9$vnGlMtT53l
zjpSDPZ#`X})e}60y;9Vpm4|Bw%-^{y8##C46aFs*$E!BcgLoFzTR{Hd_~^(ruwlc>
zI8>cYmhyQNv4;0(CyX(c%E^EMM(iF}<eF#wD$CusM8pM<`_iWWD`b$?3-2RPM)pxh
zbg5+#Q+O<Rf}?>-NqycLdki|L#Wx<~{}O16k%#Db@%Fb`FL3cdLi$dWyV?~wk&bd&
z>2<_;IwARSaXhf)NooKI=<R at d{SPtGkJEXbLl6sX_FyWU<0~Kl_Os(<|FouKQtCop
zg0H}}%^6CoDEU4Ea8~fiuK2KCHg4j-t2DMK1NJVHAJA?}Lf>tl>>MlS&7io;9S47;
zho7g?Odu5xPIURLf}0XZ1RS3fW55Sv45y-5 at Wbzz+coEDu*?S62fqay{0)`NxOI!>
zTvk$Cy<JRu0cExl`#5s;UU%LHq=?p!N|r+`qXfDco&2{AT3Ww{xWGf6#}Z16Uu<K!
zx1gG8#VdzEJ2jcMW2w#8R3ysKuI0TG9AmS~DcYWv^WLeXq%Q196nM~I)6<pkO+s_B
zAvY8*tVdLbFZJcD^Gj58Z*GIuY{XQ(6GKX+6+d|1>I|PUtoDEhR*Gng{?cT#Ci9RI
zuei7Pudupi(JR|9OYBtD!s}xJ%Vko^GeZ)p$<KY+?An{isjj{^6CU&7&H0CEE3riz
z7SRpXR<)2W5}p at E*e#YAduW at PTc%A2!gHUq-L{5nq9YdRT+DgS&NW<pXmz<BVkBYp
zrt&mEbw=)Tl0~nc2AivuglA4L3LWpoytw`w%6lfw8n$GU{DQe{k|(oI5Jh%!a0y(+
z8v=(g|HXnO-1 at pkEOGB8$i!u>v*cI!3$r(SIJW!|2884X^E#R&kVs#pzxVM!UY_4B
zC at VC+jmJHn%b16ReflcNkfB?n$0T0p6tIS7--mU%?O_lCpxR-8LH0fQl!w0EcM<x?
zxv3^0D|H-0MM?djT7sA}aC-~%U?BWn%__>~;tVJ>@Sc6;Sk%6Be}KEk{ldu9w|ya3
zNmhmB6V-EVrTe(#DCt?kI`X)0?NGV4oUXd~$}{mcnve&Y9#ZTxQSWvZeO`EF1Ld5S
zpG--IXw1g*#kUKh3u_QU*&iy;BdH7o&j-pGS4;TX?lxb&6Ljz1+#US0$nwXDrH?V=
z7VmJq*_^LwG*C6Zu^j{bXw4to at NfjTCc<)a9TI_*Oi=<?G6d&xN^fHao>!oLBf#75
zu;SJ5o%(~un$P(+5^+HdZFu7#S*C>b;3)d)>IzqTGVkp#@1f;n7umw~n5%gT%Bm~A
zH!R%dQBV5}p)K&&&RO`FynZp&5tFad5*B-4aX#)Wm>dr+kB)Ql+S7&BoeH@`IMxqc
z3`~#I>Qpg3T9xkV(D<O?rTeHN^E1C?Op;OT+S}5#q+js5JEv2G7KJq-;>rWfvhl=a
z)|^Wa7Aiz4buCZZ)ZqHM3$L_>DA>6a1hS|69<*ZciY|deK77g`fP{tZWzo^HkR5uX
zl-$XOZBc%l>G(#piO#IZn4*Dt$#jgh#rpN(RvmZ7ub~#bP=dfvZ)2`DvBc`;k3K_N
zeB*?S#N(a0YxA|G-eu9vexC_}z{=J=lY5;K1q9Ql2Dc1{qfSD^7Sw-_+S;IT)->>s
z%H)`#i?p9ve~2jdgYHwS)4<yuLx#-o%;z{GF3xkHbst?79txg|<c8VFW770CAq9bO
ze0RQl*mu0W(<mpx3RF65I>tiZe#2 at zWTxLv-U}$AgB!3|tY`<7Jyj3bLnD5)sJm05
za!I0}W2Etro6B9)Rg>sfp{i8QE1G3l{4VhNcl0hpB9TyuR$3aTg`$$L#Cs at inpGPb
zWfb1|Ku%ZvLT%6<#9=a&IB6h8p03x6=zqD7 at Fn|D-?>6zg2eVi-%>A7Tvn&I`dMZf
zBD7%ck;xS{d+qt<{_>W|TO+BJ%Is4#ks-;v>~p?p at I(V{l>E*E_zL1woeXIwx070J
zsq2X|saGu0Ft6X|SQ}amynI24iZ?DijiIGIos?KcBdvrFw_Z>CDU+|8 at h*Bh3=<n}
zo>~qYJz{%!!pyVu*tK;|GvRae0MkS8$Xn3Qt^|E=gxV at O)|CHMNR1{DaMk5mJpOEP
z)>kRJqLszkH1hN$%14IO5~#KcDoN$Wd`j#FI}V<-{QYb6bARfs$>d`%M23WZV=P|k
z^?0tJ3B--CY`5EgX-8-s_ at CD7td7}vX?#_WcFb=(2r^*UGHBObjLot)-oNyGy|HDr
zXz6O~&T1ZsY}hnZ9q0a5d^Ss0;q at N;25CTEf#t9X&)cpK+2OBnuB})I{mZE#nm{u*
z)T~+)A)}p$96cp?uc(($f8-{tND)c5;qGbo2-NwTfwf^;c0tH)&vMEt<!h>(*t3rz
zeA9zE_fC%8rp;y<fCnJJFn<Nwt|oXQ at NgxuBw}?7=+r)sZ0b4$MC{jXowHe2(FIyk
zqr}xvxjaqYcK)2m_gqRH-QQ@!IHZ?qLgL=LX|GQ&RcaY6=UcO`>eY*;e?~n8Q$F3l
zcFs=vwEVa}{5!|DMoHGA0+RVU%BPDevmQDn)A~r<!x_TIcTKtW_Jl<Z+j6D;U~Xxz
zA05IhcUXBJf0~9Qx9iKspNF`k|C at B_M^k=fFF8PXS!Cqey8H}}{=g^E{<tF6Ki_C*
zezY<(>gkV{HVSO1H!B5zi1In8NO-<5G1G;t9Rj7Caw{^l^s_-yJ};8?gDuBiO9{|?
zqmd62+gE>gkL_kZOUF+I&dXel%vt^9sCX55>A8276;(a`Rj+Hox#+Dlx^r at PemFII
zeP at Nv;WA#Wu}zD0JiL#H4l=Jx#?LbPPHeNaN4S>VwA#*o##>B>ji^YE^zL%_K`+Nt
z#8mZSJ%N#gJ}{ui&1EbAhh8Jb5Q!Wms2qRm!E?_8L!w*TICjq|1`c}vR$^u(dx6E9
zHs>M(a at H1Mlx_i?bgl3;1cgT-6OIz}ws2614WjZ6BT&DY9*+BV&6DBdz!G5}IojrR
zZ~ZrZzf?c5|1f8zn6;vS=rO#1YEas;NN5xY2{>JX@$vq0kuD?r`@vz3OEwKm?0P(j
zH&T3&DfeVWp&>*h>lJSH(J1eVBo_cWvQJD-#?l(QS4MgG05mu?lWP3x%Bhns@`E?j
zNZ6QDv?47MZ-JEM3})!9CU~durpTkQIY1(8%DZ>1ZNHn at QooySLrhduRLP7(^KzRa
zUI~nb^mqhLUx~^R at s{8x&H!;~Q5VG&8aK;i3n;Q4WTkd#l+n9c)60l7j93}6b1Wyo
z$Xt_uHWNJG<<#gs0{3l6=E9Tnd^$p^GxAG9WJu#*GwSchHg|A>9JrF}?3PhXN at jt>
z5(yte!r(J!L~+x at 84M$wd0TWoadC-SusEfLFv`2NelNuPgTM6k*7Ci0D5;W8GIuQZ
z`eaX(b)YM}|AG=Bu==9$@&g9=5;_Ic7dbAlG0xpVmwfqL;l28}^|i6SIXB{mzz-Ux
ziUnzW$LA_&scgEVqOTeCX0!5G{nIAkaj4*-RPAT%jam(sW;ZVPi2Dm##*$nR-8lCZ
z`^VTcju(?8hRm1AQA-!P)YZ%#_~+_PTUI$a_w(6O&0P9XO-de4Kc?hoR4o~vZ|4u+
zanJTJ?|S0<H)+rE&`9)7>)PX$Hx6wwe5e1>3d?(-kE#b-9KSq>bS`jP?LrGB8Tj6G
z38uMLI41|99t7T*;D6YH+qGt>qAciWe(4X$XUpLdagr^i_C<H25+Uh3-9C!hVqwEz
zWG4k_o?wZVAU7nwfn^+rud2zAQzFHUn75#{igO}28yEb%S<$7R*Vsm at 4|Yi at bt5Ie
z=t&TR9 at 0;mFsqyxaJXI=@P-lm7%yy=EqgEty!GRpN<qVr4!K+M7?>@Wp7B*=LTWjY
z?GE5=_CPRT+|%mV&r5RkXnMe8u%$frz+OK*D?(~Gfq=Fmd;TsfeQC63VEK)5&780A
z<=Or@;%h%OjFVRUCO2yk#UJ at D;)~1)6*b$#PG8fdnv4(6U!;BBt?SK~0cXrr at Q|~N
z`@%)hJjm8dt^`{H84NYaNSn)&2?1y0)*Vx)h4)S>#8vHZjQ*Y?TO at H_ma*t;2w%@T
zF2-X7u;4gb%8%slnSElAv^4jM^c1kCmf%K<@5g>H4FAF*vHvjw)OA3 at SajF_Vmvzw
zU1>EOt~CYS7&!8S8O{L{c at j;~&n*@-zSfCJM6S)OeYhU7EamASv6Z2la#IKQ;&J}Z
zYnOT*%O~8W*G|sTt3;W8eRXzrmN6lSQ#YBOo@;Y!<_YaK)9oCvYUW91H2c;2Nt&u7
z{=31A+S|g at wkSQu&*C}wZNOmL^f<N4WHD`bc2|5kR`D<M;GnOseqB^CNl{9d8i=P$
z)g=JO*9^`0!|~m=W4j~tVe%=)WrzNsrjanZBF%x^8a-d{WC+_M<^}5T+zei=76pVg
zVKk&AONv|OlzJ~GsCr&ell*A=IiNmNmB*-}{3H at QRT{DJsu?_^iQU at zBjW=gYlo(i
z8GXv1oobeDac~6}OF2o@)ueFjbJ3!ryDxqg2fsXNjPi(EsdL%&s1CJ+w$#Vo%YCEy
zWW-H7xvHK-ZmXD!#$>W+J4dLxrr5T8XMM7={W6E5Gzdnlzh#d0i_+F`c_e1jsN+Cj
z*vRR~q|+CxQg16<yx at OxCH1SzH*Yi4bc52O)x at Zkm<#o+^=@jyEsXc+eXqg~{@0h=
zgDV)~hi;oyc!{3e>_ORVAA&E_SvqtWI$;_I)C~!IjGT|4Fu8VmIi5h3xM-v%KJ1Gl
znE2pdc_aJu$Ye^?MS_VYZ8Zd>pw-mjMZ-1cV(jMb?oJc-J*G2$4v#YW_HNgTu_yEC
zc?7Ep02GP>D1*X3$}8$qU{~Q83|ml(Q%`_H#|40swh$5|{4HE#ns?FYt8L?<NLg>z
ztMe9R5lT+izyF%@APITxc3kx`9zahynLzD(8>wX#e|O>W8JPARQN$fDgX!~z9%0!<
z;Z`j=wUmCj$Gn%9X4MSpn*41VcKU4P;~bQ#Xt2a(+DMu|k$c>TeQc5OsYFL`UfG0}
zX{VLnY0PO#jHGcVe^dhdUNri%c!`~cp`CM?b5k)%ync2%8Rw7V19)pk@(XT}Io4WA
zMlxPuHRl-gva&&M7J|y+wdS5A)VK$XMt^g~C5ytHe`{5s*=+_x>ixABH~~TOf}g*8
zs02wxW{3)+=sJ?)+*2v(W!T)ojeDW(09Rul at 7{lVCyjn;;vV6@<I=z{-%4L>S(Z1z
zN}-&Cmbgs|%@3YmM&hEk57@;lV>qqUn5KhA`&8Cb19OI7KK_IwX?>)?)k5no(zK!{
zT#kC=<H4ET at -@kO<gvA~eqZnrb%W>YT(Dk4`f`t7eP^;a%Qp*_Fo&nldCVLcKZ3pp
z6Bhz*!4&0h>(t at VUb9-g*0U_?6532TtY(cOFqoa(SEYG{Owu3bWlgK8`$7BnE5$~<
zgavyK3E0FNpJ?|irHu&HBsUh?7W^#>(j!h#p2#oA{7URjKIVa;DeJ7AUU7TsJ_a3M
zOOgqGMN5^i9pF{?)>qFHhoh;`k^^)#<(yA3snz%`7u9B6sivins at BXpD&Fm2QV==Q
z1P&Uw?E>@-)OsVuwDrA>0V|sM-Z0H~>#XfMIUR at 7M8dMaZ1D~8BDH`(G)TE=cbb)H
zX-Bak5(E^zYk_SvXpaSvi)xe?@iOE{k7$17S01q>YcRtMXs6($ivsg(Iz0EM?HllY
z+SrBKTQ|?zW!7iVf7Im8w at i3`V71GdCnbV|qpf~g|8VVp;&dLfDkdr>eApdt at Xksv
ztgdiME)4);X!cU-w3*_Y-S+5hF7)Dy5ABVsH#5Oxb6Ql<oB~EDr0V&zUk;|7-aT{5
zPLEsXC1%+cT4>YNxD0fI^jJVu&SvTd5KIu6AR*6D(4j&JIkdcj9GH&%r)TfJ^no~5
zz~9;qIA8Fbs(bDqJe5);>ZepO8Q)YLc)}b)vlEonM836^b6GRJoLF&m{BNS6Q{y6i
zK`l2ME~Lmk_0#@$cVpZ>Ph)8}Zsgx(nc%DQ#;pL1o&JXPqGDfW#F|#7Id4j#zHftu
zQ7MO5MMYIh998c%3oFV3Gf*l$BRZ8Z`lV%MhWmiJwvx8A7XXdupEG=9{YHW5qA#m*
z<uC&SeTB6X`pll~^}76ZvwYnc&JAa#<u3aelG_*qCo{jeYEi+a+4DHbnKo at eL}8^`
z$Rsz6>aQmKxf)2g4fb%~xv#pD&V!!vJr||&e5A~B3ud9JZBshZR^b9P(@&dOYu*04
zy5fXbnV6X719!PoVG20z=bW&QnE}t0rkL%{!%&;Bh4;SmyH%NQ{QaBk22bW_05K+k
znaiIfouawoW|zn{F;6htIs1S)i|DKt%E)J^A~T9?Iq{MSfM|MF`_Yp!Qn<8}y-UB>
zMM?QmI0cYBD9Y<Kgh6DM!hbhsJw14Y%eZre*??tBp?u<nVsHI>+M4$<w9N4#sxcO8
ztajAXvyN(ip^+`POkx!Qc3~$Ety>-W;3se?tXx|Er24j{=&!!-EuctgiDg9(t!b&(
zFHbW?qWNEFvQ)DdEzy_iq}_g^1QgEkwih11lMU at U>~}Z^vW3)8qEs)1_&JY3o2^Kt
zD4Nx-Uylmt-gfD+Urt%1&!sP<+<t76Jl+^aS(GO60PmST*8f9AQTuHa;aLQxJSI?Y
zMB at VT1b&*4Wza>M7|uC%x&6$KH$%0#KZMV8a%<f&5t+eZi)%Uv;Ax`qATFV$k*=2~
zg0$RFD4gbyLSHQ=j<l(fioSJy`i|Y^i#3-AN*uEvqxZa_>5jeAxF*(wQ0WY#*nGrF
z{<ZOvF|nR at rmXyjt&vThq*1!z<U>+%;hY1JxdGNKx|S?t%07<fJY#l16seT`flk!R
z3kIgs^^TOFN_m{>m{uTCn<+qr6)>(RN-%1+&^nk(s at v%_=T%xj(gcjuooHls4k-+K
z73Ejx?}__Vyg_u4h7YDqM65O9kr6D;d0t9aEuV`c6pGJS^QG-I at RiU}%tT=H?Uz~Y
zeB;ACy|X4p1!a4?yII5P)e^lf)xW_3tqckoZ}-&3TK4qo#Yi9d8m$CsGr*z$MlJ=P
zFm1%nHLnaQF at Ok6og&RbWg1TjW-J;e at KmIe*Nz--oxfIjpfRtzr)Zq0$Q2<S5z3|I
zD)?%ab~@jdak|TyQ9{51m?tUt;`{42uD0wKyeo{+Sq=Ddad;OJ5lBtyoV~K5!<Km&
zy7D4Zq$7e3`^C$?+$z7fh0t+NT(xPOM|dq$EK!=K&pH-#(<7{X*5rPccJK5;;N`pj
z^XnE6C5}U5J*;8P4pCapoNr&i(pXAOaDQe)!Gd-xx(s{4TI|p+(Qh>TiBXCFpf_&*
z{{AW?|FSJVLCfJiSY0Zqc7H%V&XHC^dRYHjt(=FKYi3G89THFB1^ilIm592kh<&Y>
zKs;r>qod=HUO8#DFagi=0Nm~(h79^t5jAoRCuV1>F)yztCtjVyGWpa9H at B*{I4XH}
zXMy<sRrn0A&X&I?lfqbJg^BFW6ctE><Ob!&Ty5L#dVmN)yibHT?#{#`vd?CM{&>}U
zq?`oB7-8_Wv)qifQ3EhLO<rWaBGt?NdW|;NiJ}bp5XDr{KRc9^;?hO5Jy7<Bskf$6
z`nQL$27vrrLumM_r9AKoRXIz*k_$_~#xiv4)+VfIDj6iDX<VFU>Aq6j`|^jlx#6>U
z|KLF_{NDFcTd%(vkJB2KjZt2hcaPSv?$i<n;O4v8X1_GFG4)Oyi>WSlCknbB;dObv
zA^u7{olBv!G<~0tCuwrj-{<lUzH_uGvSmICOV|9^VU;+?mguS{y!eo{#o4hzMkG_#
zY4%xl>MeY$ej6)k+Rcoyo{QOe%(Y$ia at vR8y1wvlHfTIH`*fh915f;pr%*Iy&}7rD
z at Cl{vb19Cu_qGR!)vAeRwRbTSj<v+Nw*9O(Nk~l~cf<A8*%ig5r%nk0$!zJY>Q}2x
zoP6!ME1d5KYt@{4$9ZorlM8_Dhe|CQULPcD{mY3H>Ovnl9>gIhQ_;v?4;DjbQ24y5
z%}S|4Rm;ac_UACLHeh0B5jV|5ai(dOy#ivmHm1M0{d at V`<W`SuT<o|hY|5J)zBzn=
z>>)xzpZ`wwH>+{@qUdq9QH%FFkKD&4yddWM at N1a6JeauOeNMamgLhdW`V^fK+gQjp
zloq at Dcyf3*!CBPrTjJ_FAe`sa;#mv0-tW*Ls?;VjYdE$|=F6SxBvf(lS{I(h0$>Nf
z<K^#S*J%H}(0{Vr{-tx=*RzGTYxpJh#vXp-e{FlS>ARoZ;&6?`Z<;T(`kW-!dm at Sq
zPA2;?mxdqIZhCD_oh`1RaL9Js)iK)8 at amwS_jlCs!T<BKcQU!M`Ql#1LeB-so0MC?
NOI8XjSt(%@^gj?LcDMil
diff --git a/plugins/kimchi/docs/kimchi-templates.png b/plugins/kimchi/docs/kimchi-templates.png
deleted file mode 100644
index ca3ba585b02668de97015bdd9ec4af64265592bd..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 329678
zcmXt91ymI6*9SpDK)OpndZjy+mJTWDZjf$Jl<w|M=?>{`mTp+drMvSRe82wz&T{7L
z?9M)OpL>6`!HV*dXm5z#z`($ueU=hahJk@&hk<!jf`kAZ>D`?I0S^d<GLm92&o4h&
zt%b3`5#(=DnvO6qDA+H5urMiU1i(Q=r_XZYh%3lAn7lYm`HAMhAwnl{4JT1M8ygc_
zCm2x&69Xp`<9DtWPUi0<Kg%hq|9FcJ1M?2%v)HFEZi@#iu4&7vt<R@(w+ZxGH47K=
zSg$m(Ucn=OkV60P?vg<YAG0 at f?rOXwOS^Rsy)lPQx%^FzwwMR*tL(r8cvSkl=vA&%
z>&!D7=)+S|`rwFZ>;Vm|(TxB(I+=mlw$?U3doxrJng&*qNo3;8fJRH_7gbdBUwiw#
z`)C!8A%aBl3q$0ghCaX2CbhbnEoSijpmB at _C?Hn8 at N?l*o-+N=@G$R282hFr^2;-k
zD6XWyLiZqP`W!lu*3&-XzH<Q@`7|k2Ra^rC!?5U*_y3;sYktF+jd0at{{u|v-JOTu
zyLZX5SnxmK3IBVI9x}#gsjRr1- at lP*Q76;9&UlU4EUcFjN~nI_I4Qo7p=Tj#C2sFl
zO7LexSn0(VU23)iH@?SflF4DcJ<mS}BjlnrpA$L>jmaOqHlfGqAoB|M#}GLnQz?*L
z`+-Q-flP(MqLDz|$|e%jN?W4ARlaYS992sG>P^3M)d!SXaKQ|DmHw&pa&(~mPNl;I
z6D^THa%%GP)qU+1S#S0|8nr1tXRU=<=YGw+wonkVk)#TyilDIHA%-JKhdw2_Fb8Qv
ze^7H1Wa|eM`|`%MsjJ#60h}>v2{zPNF(c5#uG~!5ES*7?m?a$<XUOce8#QiK9rSTV
zoNOpHgC6%_ at f35w6Ov+zTO^EnMb5O12K@;}EvuhT78ch%=fh+ADxXRoQ$#lQ>*rNx
zya<;FQq|n#SEH~_Se8DiC`^$9Rpou*P5;77Go4!{?OXrgxP6yZ_r2o>qh16<st6P1
zV_bpr23mT4Pf%bu9c_rqscV+<PFAvOrgvKWeP%CgF5<@5;%}MxTJHC!?Pr}?Mg)Jr
zbVDl{N2`?<ov0bU8{~Q6qgmZd`g@%-VtoaN-I6ye7tUG3yxU#p1nStwns%|Tmaa5U
zx?%+&n+}%k!C|`_H7D^<x0MQmy}v&RCm4qxcEM-$>~SFm8#`L2uII-AT`mHqtG?XF
z9GX08l2NQ7PgLj|VN(+9zKhthR&w9^zW*dtv$2^e$-!Ad=lMijqkBgT1}{t9c6<sW
zP#wMb=|DWF$3^jLzL~doPy(nzyy!&3jg<J(1Lt?qSIN(NMh}m5O*h>NTg_%9vZ@>z
znWXMqG-oG|=5y%gsD0lLdFJc)Zer+s^~45X${#YH#W68|O~^ltal-#LovqN6E2+2O
zW}oNrVemf0GZngiTS5#9Qy1q8^AJKEArN35+=a9U{~p5dr}$)EX^ps4uVfwuJ3RQ9
z=2`ydUXV^Awpeep*aM{j!xZ%8^2zwoVeF=JH0?L45&?!px~B at q4|I8-?s8o#VY!Wz
z%RH-ywPpxUC=u>DBJ3nH)h`UsiU&5f2<<l%J-RaVppB~aLrM3YWcQvu`E{+t%#W&3
zrVC5H&{f1tD&9*3AD(=4$4t+p`%Lf9>TY?X at nZGlnx?SNDq!gM11*7z2a=XO)-?Cs
zUJ~BCumLNB)iC^|t2 at t9ySYXaQJ!bUM8|K;vHS%M(Q{;t;e?K}SmaJHP+d16Y=qix
zU{{~c<xi6Khxt&}+R4S+LR^{2KklqDv&Kc+XsbmHQeSwC1>g`^gi5wshHAjAeIa<{
zTUTp;jTF}6jNa0;ZGW<DIV6?s65mC#!SR+L?@VlWV6%H}CqFf;8UC#9mHFF<Pm*56
zLC1!FnArCL%~x+Rf)y4PH;nfHek{#_$J<aR at b~!cux6t6s9C=no}V-h$4L*^&eTK8
zPo?69tnhGYOqBa6ZSGOJFM_P^Pg6}5t#2T?e3?P#{*>Exz9xrTfJU!AP39AC1hL-W
z#gg6j<?I`V1Hy+3{tC8}amL$4sAclwvP#R%tN;;QYKTxSukGHK2r`vXMDXK}XHOr}
z*z!A?Oyb!tIM=5L^e)kxMPIKB?-*&3C=3xNQ5^AyZSHo1p*Z^KnVHKQ89vB$GOG~+
zl|-2S=0G&i^K^Y5o%_NFyMr*P{<I1cn$rB5XC#E9Lu at d?Ll;iZwtNWIcI!O-Vv&ha
zNs?%+Noc}~QifJfTv%G|H!>NIDzxp^vcR5nevqljwf;?>=akNL%q_HCL2JOQjpIjr
zjo#+q?y+IGPy`A(sr3B3NQIkid7v_$jf`;4V^S`!(MLO7uTxRo)P}G>ZI4oMiAo7U
zM)dV}=_MdUZefJbqR`cxh^!nqLn_*u<2|Tm%Z>K~=Q%Q#D9`4{NN&9$eZ{<e2((JF
zV1n!5+nBI7YFVi6)-9C0yZo>l+DFn$tsd5!lS~M19U7_!!AX*T%zs^F9Fqsd+TYP+
z;B(mJVKy3%Hte|BxNXR_{2XO+IMRN;Jc935cFZ!yXNXa3-X`s%BGbTnJ!&@J!tz$*
zg7}v3E&n?SP;wqf7Nh19vA96;`-EVr*SKj;o#OBBzf{?F?hD+F$lj4UzJ*4X80;>A
z&mKf0mDzXRyybl)nH4<e2>n@==6KY3vA>jxuIC+K26>2D#RhMVD1{_fv~|@yU&EZ*
zY4=airi~7%UbF2d_g4iJY9<j5EvU<yWWMKTg-9V$JaO_w{8TOuZBGnfL2Yg&AFg(2
zy^>ba(vo3I?x{Z{JElby?PA$1Ygna>9ULDY at 8}CBCKPb{w$@Vr?7AwIgel at h)W#>h
zq4_pG8c`xU{K!0`L_}pJDWVhu;X>#PRsP=Ek9Ky%MAe%SyD+2AY{lP;<5`f4+lJ=Q
zOtaaR_t1xYOlaSj=F&d6mSz&eq$3H*wWl-9;b0=p%<A^<47$0+D3&duqZ%JPnqq>?
zU2cEl{pl7 at IfWG2NW40kOnh*N2l5&1Z>6dqUfW3q%je7IrD2oPB+f$j)MQ&|aCGAP
zL%x+<TBByPq<uZe-Jh>RHBO%NZoW+*j0v3R_sQ)Hcd2J)WtaI^!!d2PVE186l`ZiI
z*K85tLMpTm^aa_UgnoX(z;vf4k%_jje#i3jn at m^KE)u(iP|7_GiYS^|Sk(d80P%v}
zTf5)1xD+3e)bWkvfmX!Z8ZQ<b3Y(!HuPe at Puuzz%{NgPPu7*H?WR>KPF$&ckNBuq<
zeM*PiCnI-tZc4rpf`<e&YIl{kudTQ~=#M?fkvMl@$O{{>$sDJT-J|I2MLduMqW*pt
z=LZYScAkNj`=e$KE-qVVz2nu^+YvLNsj_!DafZDixTRm~-sIzW-(48oo^6$C)*$rT
z^PCM(HIteH7^k1qmBg;?mPRH4)LCy6A$X;MfJP*SbLe){@QV;=!g9nNVq%<`2FeQp
ztC|m7zW1JXOhV3-xaA9M)<aRL&l3~+3Sat>;llGlSz*P$C{8$<LW~j0&=A6v-qr^r
zy&9N#tLWe7)*|qhk8-k!m$FZh?RTqV5^G-;RpjjKtacJ>6KA{AAiT at Z)ydgH$UrWE
zC1hA~fg(+?Nq8dl&-hQnus%9}8&m at fEXzue{{%vr=<El#pJuvlfzwe_w@>1T*uw~7
zwiaNS!D#0r?Kco8Jz~w3`;q&Zjv?ID+WeG!mgUUU^7B`te(jXWcKTahf$XWs8s>Yp
zep1DB&u~9fpZTvBIW|r52}aloeDFUaClJQP77ccu5Lrqo13I&Q1{K4yKD_g%Q8(pB
z73ree<MActe}n8-grQeA82^2&VDVH@!@R|s-zU#L?tv6X<RIS{yRNU^hQw^2kS4+8
z()`Kmbc2DBvEffe;XOSgBUS96zGl+|vJ#H-!q3_jmY1QIsSU?dduKnS-X?z*>3Tk-
zrEr38a(b(R-nlw^{5gGTHts^o`nI<;4IU2RK-8Z-HZj9DwYWPFi;G)@%TO4hw*mgW
z2it4mGkVCgvXA{#LabC>eQv|~a7)YeM;a1)jPfT`BkUA+|JgqUUN=8boihKDJ8rY*
zP-eML$f|j6ku*NTjBGavT%JHQp%I%0MuAoKgUY31oIeqI`E^<k)7t&stpwPC?yku?
z+eC{su5=M*lv>Nq>kD?)O;yTj>wiZOe=w|Cmn8hNtf+ZGCJ?}|`VM;^Ja7M#LaNGi
zg2A#_M_Q(V at Jox|4{t=w2K=+VeMfrovRnOLBIN at 7*#0XT%ex at 63}19+u3tZ|<yft*
zP)(1yV~ix`q%PTkGNeZpeJlKMBBH-T;<UK5)QtPCb~cPmFy+r5J{Vn}Ta&%Ly&Xuq
zFicrl*~+5AQyLyf<D- at qajs+}O}zB!S|Ir=mT!MMGDedpzTz{yLZawd{TN8G;1p7u
zN<sX^arreqw&0CfLHiYkujT4M-rC>%DGk#2-kfpTSovr)P6;b7W*NRiYzd+=(dq?`
zUAlK&2GgJVS at UP0TMe1p5!X2KUNBG{!I&RaNX+S!hqq#jS#n3vF!HS6lPL=}%}6P$
zTBb*nikc6##tnCi7BW7S9|MIJoQNQy<MPyj8E%+?B~h|8q8P?fg|GbR-Y=L at n#rw<
zurs%fk>j_#a^c*F5KO0c{%M|h$-Qbf9+z0Q`P=iTFNzW7+bwQCwlRAi`&*y5`v9ha
zywCUcugX}>A7oR)(y5VNr5W^pTc1~LIqBr^X?Lg2^^`PLrWa_>Ri}UE7N-a0B3D~X
z?t(teE4?1w>?-&KjfiEvA#K(5p^@Vo+Kec1%ul%w7YbpQw=`QUdG3F1!Rr=RS~UYf
z$#^i!C?8})YVot`D5|l-_#faGm%Me|FNJJ92lHD at 31Y!Qp;VU2E$5pmBifkX4rZYC
zedBo5R(8<jz>ES&ou2;ln@}mNa12A{>Dk%(mHTF5GPY#YWLX3w)UB<pn>Ga*8JWoI
z+&Y?QDMfYl{_n7GCj#h&xt6A`9wBGGX48+?5W6v<duuO9qPiwh)wLo+!$%qf(yag;
z&D;2GRyvcP6Z#y{Ty(=-$_(5ba;^euKO%B+Y#LVQ67-5O10sxwMDs2a99dEZ6g`Ca
zFXKQU8Qig^O`+kwp-g6dO|E>sh^+{j{tdoo*r~5Z3ob`@J4iP3ec*zP$gr+zRofFC
z$%-gSZsUrQ*HR4!GIn(lBlQs_&b8EFdViCx2=%kHH&Eq^yG`<n(n%|Q2glU7{K~jJ
z9`(vY9Z#KK80%BT)zvZ9T-VfdW8X*$$A9O<b=i~T(Cw+w%7E}Ts`|;g2P17_dD(&H
z9>NMwijAb&UmU6=DJo10;)uc3?}{oqsi8oXX+YyYE@{k8Z%=<<RV~M~k at jWc%}n=@
zrfAZk<2&y91*<gCmP-eEY+XGS2=-(0B#Tr2bt^1E8aeu$1~J<O2hh#4Wr18}=Aa4u
z){01k>Bp;2_Vq0p(MJ#AdQTbwEIUp%;S at O~b4X6+(&efc2aEfZzc4b at K79Dle9>IP
z15aq=G2IjcW>$vzh;&Lnz-ii?-ER$rjxE_*>E$=1%A-iz3a<I$XHIb8mvSt%88x at Q
z?Mu at 6gHS*Wt<OE*IjUP-b)H}4;$LikX`VqV58PMSJmtXb`A467+Kq#%H<kZ!a{!#+
zdRt1fLungLYc#ze$Fqh4A_sDy;Vx$#tY9$%+`n`oC*I`XbBFWKF4=)x!uHH~p_q~V
z&7fzxe=lZWO6w<!BR)MhSL1$e3bf>AZ4RlRR!xF!=^L8Z&j{#bVH-Rg+}t%DmwO@|
z3-K^m;+RS}Ywl#-0cg4E6}oKMUtcZ+%hV;XuTMg)LU%Opb8Jy@@g7|>1KNkv-RwG=
z*uj%A{$u?muDZH9kj|etSU3blEv-<SrDkdtP7aPr<3X&qd^_(9wbaCLUKEEYmKydj
z)>5s82v(y$MO9Vm&|e`6Wnz?_jrJRE*DJ2}I{0Orz<w~USy*ui8yb?{+ut8FX2UXl
z`9M{L0fhdC^GPgu%~c;YU2N^E>E2IgYF}~~q3$}RthRb4j>IGTeMcjnRngIr1KQyy
z44?~sOi4+R%2y5};SJduPMoUH6J}sw*j%A}+7ee1laoXH{UyYSPiH55VM3d5X{ZdE
zji$pCq;bZ}T)Kie at ERYu>YfY?Qyg2i&t3H_n`+s!$*KbG5RQNhM~Zt|QI|A1)YOEw
z&JA$OPse$GZF^(ioSj%?jy?jvcXXv}Z!jYJ-EY>~F++QKcd~wJ)R=M}9v*&Czcw6A
z;k2Hw{DDbzWpK2NE>)<K=6Q6xl4O?q4IBAjoQn9!3mjQZf at P1$oO<Y_^8w2Q*@-Kh
znN-G*ws*t6i{(9Px9w}f?+y5zY-XD5*w<xiQPHg~jnW>j>c_Y*D}9sH9Y%>ae6|d3
z1CvAae&Snnh4p?GzQaW1d%KeEobywyK=|zapeXZN&HeS_T0^rAX9sY}7Vmf?e%dU!
zwKa4f{(MKLsnB0<127v-pX=skB){(l-2u6AB37f>fj$L_ySpvtW6*+BpHBn<;*M`{
zPS4oBaEWuhGU=z2Y23*QhWdK5p9?$EKMPeccaB{M(T7gox!zpDq3|4AC9;hNziH at C
zM_YF3^<_WlZ{J93gKbNw`_VHN=vn5x#$MI>G50&7t{(Wdf6g9^a-PIf?9r?z28cTb
zfC>O$2<ar)e2xz#>TG`*pNEfywB#9B=ujtMyQ|WoI?!1XL?khXs_jWrS&)KiKWV-#
zx5D<Y;ixCr>kBjdsEV3P_3*BT!2ht3r=Ic+T-erMjW at ZXB4yu5Qai32A0w7{Zu98F
z$T$)5ary`f+8-#%eRwkW+n(eE?CyWi=(%t~%&qL~ptD+bOKaLctht7r=N=`q*AVee
z-Kg4yHpGa0Si&<&_bTmYSJLiV6C3}kyRzLDZ4 at 1;NEC7Mt8UE_<gmzzic<Yxx|>}#
z_p40%oXH;=QvF at u?3(%g2!SX;fWO1mO7tnGE<sh(=<zH*ftC>S%U#8I-eie2>tFBL
zu%|>p!gF{O7v3)N^Z^%S`o!+GO0bWB*(}e#L>xB9ECH~&z&a=beXYw*`}0FEgzd1~
zq{VY;wAN?e3f23X>B!Cf1D%}1CQjS+v5JPn^Yey*9b0?jow+IG86uD_6hiK`D;87V
z9kfQ}W`Bo5kW0YnfOFh(kB5Rcve9vh{in`U7Rt#1sDw=qXEKe at 3}HYytZ&j0AcI1M
zpY6(<wyoY{1$(u0yJ%}O8s0Mcu6wrYbx^x55942{mVQ;1bMB(JNYT8S at aUow^^OI1
zup+VzEOsEG%<0b^4O46&U{C4)#u?roHR~-vm7n=Y69&PDkulR~(&rlfs&YZd8UYt@
z-9?b9`*@GpuoceeB1aHlUe at sD)*l?oRXU$k&?Jbji<5$ux`-qg>56Ad8OG6CvVOpx
z^{PZgwZn_v30O^$pvYA3F<$6{+cPj<<u^pvcqmYG-4YVFLHbYp6(`GD`vih*!YGAc
z(;bV#wf0Nbgz%;$Js&6v30G0Fme0jIXGlwMrtc+XM9}DZdnT9HRw^{+ at f)U!uNz~b
zhQfKP9 at AC|<SF5q#||s?=?*)?L1AOjvA<@0;@-_;mvZ|<`QPFSy at 8HjpXfs=eg;-s
zOi64rC-ralje>MrqTu?;d!i*tTD$GO=h7Jt#!w$LKz#hO4Zm6ipc0Be+PoW at TUi6z
zyziB at mI{pwYr5>KN4$0ngpj<qM^<}YL+;+1g at s}7fS6aFWS(^GF(j$+PagMe4ID=?
z(ngORj$5Y|qDK8}H~od5k^`y=9d0m^+`-I^w_9=-zw0gL$H%g~ud_$AMsu%)75)@6
z+un<iJ?@uGli9zzSDSHMQiYhD2jjC=u~Eh_xAl&B{aoXDVPzM`kW6bX8Gx2G+ at V_A
zp5M%<3@?lq+!P57j|<_JmfGdoRluXn=4n>)jfS$TpDw`NV>`;s6(~tp8FVAuUG7Vo
znB;4Jd$~OaPZ&l^ps%$>&4TO**cNxB?lkzMY42=`cTz|2jza0omVf+IN(L?T&6Ez6
znvVH;`xnBrAgEC at n4exzg>d*_MCslO$$6ujJ+B6Y?SdyHr_V0ZE^nYDL%4~v_IvHZ
zUG&19VQ?OVEfIcFz}QJ++j1iFUB^@_)fn at +pJCmt1hgDAS)Vc4sv{<hqA&Q7DwxN@
zw<P%98~Czhnm@=bNVE+44SPVZ=PwouBc{MYnWr=1d5|{0=_kkrO8 at o7_{ILiL4KWf
zje?-7z*3)y>qFFrht|y}_yp17*F%Vr+ZT>w(C at lr@g?PJkGFCp+#OwV at 4w+nMPN2l
z3Y!(Ut;(`OBBjhkxf)E(WuQX84Dvqr=xF!%)sxOzThgLZh1u8Nz4{oC{G!pX$BrKw
zm`YeN1cqhXS`+SebQx$W{rqa+3{Q+(kw at u{G54^C5OJ`Du^Yq^cCt9TCCy_MuEY6D
zZ2t|Bx41KCIK{-~f=DSmRkP3TC~fo?d!+HM-tks0T!ldqwjm#p)TvvVBlwnE*K at -p
zBHat*#6ExnMjPO+G^`@<y_*tzxN2~Xk}qsXz02 at C(qw9XkX}D^W11&K>s$L})z)(+
z>C;_v{}46Rch#w%#ga`lG+aU#`9sa#LzTMHYKS$OQj?IX^g3vf*j)ClkyyMOjzkkQ
z7E+&+a at Htfm1^uSlY}-wdOs)Lk6~!G8R+M4&^Uu3`+X>{_r$XM0e4?<C<?@EB(l;r
z;^z5QZ4=W!1sriGv#hFhxrYZH#C&O=^Hg23J0_>y5q9>h-)T++I56&ne$dQ~A94N|
zR&YyheuBD!$b^w-mjbxW*`RW@$lj53XH}Bvqfm*bAb#I#Ga9uD=xyCb(?f~3+tzAo
zvhbdlZL2L?#qw3=!>*m(*(jJ?Vsdd(s at f(rRzV=Y-%7*D_M5-Kz~*2-2K<^!!_-&D
zzdx}5Xp^>reN-APHK-srz0XvSqsNY?YpUs~VOq~c^$+@&WP^0a^tzhULy2$8saK|D
z31n<rn`)7JZ4)xtYsxy5629GZ;-mM}gW~+yeQ&TH at 71QJW41>j^3+J22F3#(28niH
zQdKGJe?Z_ at R~QA7A<5$m`L~WN9$oVebILo%&W4Iy8e8`5>XH+Le&n!Eh<Jz@*Q#x;
z`eegg1zE1X2odF-E;jP*4>Dg=tweN&c_DWS626tc3iNp(Ee5ad)h!cb1wxO}Nq=H%
zka$mU?=-CT at 8t;AvWK2JUmiL##1E;;ER7w-DU-%ehTLbPE?jXfdJ}j|`!8E-J^U?%
zWSv6n^uPU$MnmiSl{ck%hB>5Ax8aNvG3gU>CHqlP=*Rw(HyiiLlOPi-m+c|^)5cQb
zxE{2Ars*f9v5GN2!+^=s(ka>sQ}BnLD<SkHhEZ$Oyc&Zw_N?zIy76>4W%QZ){QGp5
zdD1B_)>TirqVMgn-iW4Iy8rRL=V9!HcP1jaR}{0)X=sljD-0kEace)rwLNTE5wLuN
z=}YQbWJ at r~juR(9fdABS{Cv$+-gs8rRj-dEh`vEHFzP)EpAlJQG*2V8#8f_c^P?}k
ziSFH*U>J6PRfiZ^n at e!Bn!!?KZkRJ at +YmF}me|dlF~Can?`@F=iR5J1{O4dXzs$!2
zGuaf5;DQ1gfXuthhdK=FK~E+R>SU8S;_P(4y^CIb;$yEd9bJzSeQPjZY2eTaI9*6p
zOTC7y8E)&r8S$o1>N7Lky%|vZTU_<Cd*S8YVA_n4G~Q?ZsR9J1wi{(#&qGzAhi|ZR
zde25aXR+k$mtpMoIt at H<>pj at Lquk3~U{(jXNo&KZ528~C8eYS*E-ghZ4z^kin+JS0
z`+bAYn|&K+N4U*bXcCg<5M9{sV^8Oyh>qPR*vO*c_+tDIEzUF84F8aMv$tiJER>i1
zs};a1y281i;@%<g-0cj~nM9A8HeO5)SJ?!9DNfh2ZNi0IyIPv3Vt5vNCGFb&J at GRS
zq$oHylYap>B3&c4mW|H15;=4XU)UJigi}ZHo`mD22b;wX;xmKSuW$QLU;Dumy*$-x
zxwQ2WnIYfY(vp%a($!OkkmAY|7>sX8hyFP411#lEBSJ}4bw+7O`{kwAH#R=nb{#F&
zS)sIIB$ynkqCE!$AiQvsT@%cljdMZwGvigCdmHUJlgGQu=6hmzfG=6t+5!yc|49JT
zF!=H{9W%4pbdi!)m#ohxX~;D&vb=5`@R&3zJ>lde-RBHxTu*F-+GO}yov5D$Rz1$;
z+-Z>vP!mknc;3pTa{Gn_MrWG>^(bZ*v4H^(EB)DGF{5@%GMsF5Kq;4{?=O#hcKF(6
z>{t|q==j%IsrMRfUcBt9UfBK4u3A3}8Xc6GN{U3#qf{>pQ`RLEm5k_~{TPRb{3-L_
z?CVK6e*U+H2fNlwrn9A*B;M0XO_-us<}OmO$8Gma?a$rh1pF?bdK+wUOalU2WcJ&S
zMw)o_Ho0|u=zcnHk#8|#E7Ibg at jL3Rt$_h^7~!n*h2p^Jt&l(M6z2DkpNjV5|C%U<
zp+bILL0w&ZQEu4>oB1OP8!JYfi#@N=wDm0gu+Hm8k;w&}Pc*3A+EKwAN+o?-<OZl;
z4pjoC`k7i9Z~G;cevMrZi4oPp$`~|p;c+EYOTUWv at 16qg-qE`xSsEqj_>sX6zmmNa
zB!#A(>c))~x at 8Fhnx1nounD_nh+G}hC_V`re!(ui3M&4JY_uS<gWQdQR#Y0eG98kB
zD)kFM{z%yNerN9uGA+Y4)+_THB>J{dUaBTYQ1jHwsjSY65Q5fAir-5$cxEM)a4`ay
z05;G7pF?RLx?PirrudFgtRl-&gZKArNlHCmUXP|uT1)v31k6`2Z`2_Scj>exoQ0?E
zV1K>fX7a9*GK^Ic3NKEsvmz=Y=OtKaC}4rmkaxXo3}ED7f7Wt_RwUaj`G1@;Ng70F
z4(;C%Q>slwv(Wfo7GNqqh)>~Wu1~+h{<lS`Nt)w3(VS?Wf-sJh?>ycm2#OU6Ta%Uq
zn5hkMu!n?wN}cdns4DghRY3-r`sSRNmo}P0N$oL&fixCn42-+U(cHoRy|W7O_N3_w
z?<Wk5(B2d8Oj(+rHcR;iea<T)bED+}$?Lj=@oE>kdc)blpASm<4JlLA*u*4Md at 9Ay
zqg*u5hdvsfI`q{R@(8VFA_p_v(FcaGh}D_FzGevMWcf;6gpy5Tbt(qo`P3g(Umk++
zul4|n{wuk~t69rQL4b@|_Om at nAq#1NaT4(9;Xi%f|I at t89?M*&J*zRMu at BSNj2&ba
zYt1$qH%DFB*HHDxg^)O9R)2vjcvLRTT;6^<Te5rnQ_E}#iGL2wK6|~;=s;8GH=?f}
z<FQ3qVMaf3db?GP<gc8+(UJR49{`9tnQ7k2B7560Hax5nPP8lyia5+00~%D(AwWv#
z8YmAS%>Qs_ddJFT597Tn>NqZcd&(q(o(it+GcjJAbkjtivzKDh6g|d{F!Fe|{Dzz2
zRG!!$p$La28736s>uHMDI$I6{a#D?Pzdsb6t}bU`-I=PC(mNGny at mO=01s9Hgckjm
zvXs$4?qS`XY{9zzn<vG{ruyWFI>pk0epDtSoW4bB+aGecl^;C6;qU&^2=N@~%-ZM%
zCSDF0v;9&MYc#;d4J7TUeo{@M>zJHS+n*AMwKQAc#pX3IBE?Nz)cAHnr~6y)GhaH>
z`?_>eQ#^Rs-(TJgSJN>vGA8TCwd*ICL`%K at MuJ$8OG`%<x$)<SRxOwkRg{Q`h~UMz
z`m@=O;&N$#><0t6t^$R+3ABy&zxlT}6lg{^mx|d&O3ehoRH)q|+12lmq`Sjd5y0nC
z at 3H)mFPj(HH|SEoHlyQyqK?L`-t4(8wbT&b at dw<`>IG2r?0o!I?L{$-bbckDh?qfZ
za>RGTFoW5^^JL=4jrSi~Ue~aG(r~kW()J_*#VG^A6T8U}j-{2A`|VcZsQ~(L^?+$j
zZ9{`&7cwo2^*oEv&0n}}aAu^<Qku`*Zp-zmCkH3z8qZk&(<_GjH*=f4_<F{77rV<|
z=c8^Jb6Xp^bU95;$#8FZz5|Si&Gkr|9`>IOcB=4}UFS7%l~KLT2G3hSerYV%YFyd%
zvOlLUJb!&WhBD>umg0aD?DonkSMILX1<w at kZ+@!??kmW(<5CmXt~J6;Rb;szunuuU
z)NJ`dVH9sf>E5vRK3|H_#I9NC-4op()S#o_f%Gr;X52C)9Ua+eGric_pDrtIcXA_N
zWG&XdZ at c-4XEPN(@yYCF4lB-cxE^&v$hYw1 at URgZfA62v_F=a&+h<c=KnZ{d%A1e)
zfEHdOV}<xHd=s>SZR#;Oi>K8#f9$oAwq6 at +2ZN6oeAGgx<sb0?n~nh<&G~V;p*B^U
zgG{;^V7nD)i8~vJ+<kZyIWC$1HP}SU{zJIEPPHu-q>P3w%bK{^XabypKs19Hb2fvS
zLzk1E at 1K%F<O5)&$<@`d%Q-y-Pfvb;5CL!^me+Bc#b%KM*g|i*&xDS+ebvdo+pN4*
zR8i^9jTDl`5wESQ8w~s>%B*LSn7TM8Y1(TYO|h*@&;wu#P_{KSH9tdTfL&0Mgp1C)
zq}1KuCYZdQt(%~%Q7<Rf)3+E7KP<qN$Mx4;GYIDsMjZV2^;N%eOFLpC#rmI1&BB~&
zXx%!IuoE<s2H0{wR3);UmjwYV)vlJhQm3bNv$gg0SOF9O0m%%?3Ceufq^+&3jgp6k
zV1YC$zsoSU#)X8u0T{|BjHp3lB)=?0E+*kGWu>KI8XyTkXIZ7o$1yQ60i=quF>X}A
z?y$B+(v_T-d5=ZiOL#Wdb1uMTv-qW`IbD_}xYyACJApVR_o^EeE-o%`O3WN!A-{l;
zGlPN>{i*artYCPvbZ5LdT~C{}tNY{j%s?`aAh}eo!<lotFjhdd0g&b=45t-#Ak<S`
z+O>IobmS%zHIYY^Dw{<Y`6=J#ouBHX`uLZ&WQ|$sFv>4^^<Vo7N;3S{-<ULI;Dvr9
zo|Sy7<Se`w5Wa0~MsJhde>Pgy((W#3mmfI34Fstc8AcCx<l>*XQ%AAjVcTy<?FiUS
zQC*kq5zn_r8GoUG&lRQZFK5)JCMUb7A_YVMb$E8xVbvXK5AnVRT<>9I+O&_9(fW(E
z79h=Pc<^}=hXs}-nfv>QjTfPp#rMez;B*E_Uuj|u0GxzME|f;EQov$7fI-r4Fp(qf
zbul6NB5SUnB+D1_KHY2(a@&$v&6cj^C+Y$QI$-()=L7-3%eHY10gp+0Al0so-tnKf
zOL6s`Woqgw$!1C0X+m7vWx<5HK at a#(HjO8`q at vBE!WQ~FhxhW95=P5E`QiQ514hMq
zvGG!jZ`cIpA>UZcm2Q$4E`t#Pu9eyM73m?Xjr0vO7TaF<0|sKqIm#zf&->#CL&kgu
z1C;sY`JU%|tP5V__q1vteU0|7S5}sW1B=cN&KqsUle;mrO|2U^0Zq=p%-k<;j)+wd
zN`ASGg_%Bo#`j|?E at lfA$N_na2#;BJq#IorfF at xCtbV{n5-rv9UN1XZSX&zdnGi2v
zH*KG1J`225gjuFHmz<p3K at C_)+hLG;+539MpJmgXY=5o-y07=lr>^6S%gG5y<{W?T
zh4k(w6K_r<ePzA9z1OsL=C<1Ik8=O~AsVhODl6LxVFW~@lJXqD`%~Ono0MVRidWZN
zYrS3toYsM~e?~%(uVHQr|KZdapzQYoeR6rr8z at HML_Hr~KtbX^b$f_KG0j%cw>CVY
zRr$az>;Z!4LKsFi;eO4q9_L9iqXyg+aUYHU{QS0<3R}~w)`D6T`xpyFc_er>*Gr0b
zW|wI1 at -8N8GWMu$y}w{->1Jb{;fhqHPpAs@{-PppsH~84Vk}oCR>N|*CH0WB at cb~A
zMsB@&n91mLy?5E?{&2othwVKRdGVRSh&>4)J8Rc4d+*9ToCFFRZ;vFCc%5`=`#xU2
ztkV0~&o9NYJ(?={V)S>DKXu@@--rX;h7*`*=C-!mXT!`;e#q_Hm!({SJaJuKUix!n
z$kNEXTKrv at F=P}e*r(&VB8~z7vhe<0 at WQu)3g2`ZHcyokG+%b_x}J*9#dN)F63Y)3
zRN*QXqpl#>%+{D#5Aa5IzuEc%xvvRCq|UgX;vmUN56iTR1!Pg=YDS`$E%kjuaW=6U
zQ!@K5tZS^GDyFV+m1uffT;JMsx;-FdI$<@9^kT#bmn)>iiO@)+&61k=>UfyCD*yd5
zfwzacW5L(Xw2|mijkzFYr+uDVqxt$#RdpTz*_0P=1n>Zt?Aqlhqv?3Bu0&>mA{-Qc
zIz<PvC|iko+ko)CF)oU}m7rz21}K;P)gVB!>a6g&Wc0b|CTDXy(dV+B{|GEt(@7VK
zg at wf$G2{jT at UW=&A90>hS<J>rj+&3#y1w!N<%$kXb9~!R?km8(;xwfuj_hJW@#Uqd
zAyw^%pjclzjg4I0w6z~T5{eSQ>uVB_W`}nL_g3N(kYd3rmGe}ZtTn!Mu|HPA!3w}c
zP#o&BCk4GWpb at _`YwK{oUj;*se3NB?X1lz#kx{qt$JQWE$tNO8CG94Mt_wh-qK*6%
z at 5oKl++r$And`B;qiDz!Ciye6syed<!|g(yenmLV%?x=YjnvL+d_BMVni(6Dg1Lo2
zlK5i_GY}O?qpGtrr?$mWJ;c){PPtU0$}f=ICn at vkqVVA_qVUT$G2G}2_xG4hzn*b_
z27<8E at zQ|7Ma*rRm!JRoJG$^g6kW(06tA&VZuIXHxsvRjSJn~{B%gJ3NP)3Up2}sz
z5QYpA0<X^*0fr5Lb0&8=3<#=?2V=Sjy0S$BtF0HR%Y;BHgna*5ZbD at I{3E4hW#O7N
zruIA8fiCXPK%4d3;L$mnlD^ok9cIqDC3ht7=&>hRWHw&ZvxEBkT2l(`xiPi>eJ^qC
zxKMjzL)QAtif3lnW8;5S^JO-Ds257oJ+2#a>8Q80hL~w0zG(25e(v;=YW+)`+*+Sr
zc<<zS<JR51M&M)B>lCkM4J$bSdw=0zBmvu}b&cme45h4iE5%g at X{C(Q(T&&#v;0uV
z%N1GJpj-BMOv*q=TF)R2%g(0m4XBS&biF8V#G_(dtg>!c65T$7Vv1w>K5US`AhcVc
zm5u!E{MmFi#OUc%ev1*~%Z^JftVc{-UkZ&?NQjS*hbh%=s;(T9SBEy1y;Jo{d-&Fw
z@!sRVS~8O^oLY9C(*XdUoihYzn<E#yQ!;olAd8Y_lLOy_{AG`G^&%aibm8YiLcEzm
zmRzPyh3nOx&)(c8eI?|I{98-Qw}r%nP-A32)T2hL#%EtUeZNc0icyWO0r2xL$ip3R
zSlDY0aB?4tOidow*w!iH5tP~2^Ct~RXzUE`_BZJgiRt#eQ29O{1I0zrK8kpFx}hVE
z%LBZP<~K&h0n=&%6I>Bl`}pdNfxw^ZWTbFK9kg4LVhGk9%1o{6nDra_;s%3UOK;eE
zKV<{OGhE$xSii)xn-`nJ=gcrwAZK)Su%HvrGIr0z+s<^fzt;o}yoUXvriM4f?dptH
z?^;@J3t6>!;e>!vJJqzZknWN^o3gn0^=0e6#@Ft6fn7l1+1S`DI}CpqN#{@WdA!4w
zKybDdC9<j1PV&C4Xng#wN%z`^YmnDfyYnQx9hzt5E91DlZ8xQM+Ogl at aNBf!a`|kt
z8AGo9$?IrT`#$qJHkdKPqb@@-^BGSi@{zdR-IOAf>&9)%>PCN7_N$>iDF3_mJ&A*8
z*Gpz+0Zz5$t)VMj{+r=wy8IJ?3XTzt1XU at gbQxN^<JYh(Lph5aisjWeZGH7P6qOt^
z#Oj2Tq=<|{$r)`Yx95{;@N{uX- at BBE@~Lp%<l+p$&)0|AXeJdw!*2jP(`L!*ehIS8
z?0bs>c|3A$x|ozX6{r~IUaR-(zFKYRZD7ndH#g7v{X2LtmKJ}zYm;$gt772_Z}ea<
zt^OJo>)+C40<zKP=F-;IbO3mq4C_5%4P16<d!6?Ba}q1??Y=Ki$b8$eU(r6+&~{l?
z7KuFX!Cs at zZAkC`3A-1O#lo1Ek<2T?gZ6V%Zq}t7S#se`!(%@dvsUi}m36|yI(14q
zyh%hCM{8dVqtD0=Ce=61bi3 at B<A~jd<*OA}y`z?MdBZA=MDQVyvDpUvzYn`63ra}<
zkFw^{Vte&F at 8YA++Q_<Y)KMjfxV<de-UE-li{d?Of4%1PY$CGiqrrwHpTrMbqAfvW
zj$Sk;8Qz<Cx%W$V7<*AJC8*6g-1hCTO9Wx at hRHgCWoj7J8!S`2?{V<qH2yfzzo0k(
zSbosEU!1#{i1ZN?AcGtc+k0l`msCc#;{oH(45+{~KpR|k+X(mC*McyBzHk0v>JCI_
zPM(I$__)M9P>=jSP5qVpfJOXr7f>3~U02;v30PptI03)h{cN+#JC;^q8{PK?E>YXz
z^KKNo(YrSdvI<$b&plD8-waXv=)$rU1%{oL!-pEk9j|kD8Y at ozc1=f)fsK!rn_iIH
zvO6^Wi>hjTt*2en79N?~-ygPe$b*nfW``&}9(G~sZh9Ymdu~N2g&e<7kl)r6A-^q%
z+!!I&2}I=lx?}}z2ivOSx|&)cr|{h5P3-(*kS-i!mI7Xlz$c8(nkOEQxyB0_V>bx#
zQ0>Af9X9T4z`}$FS1*25;{jWTih^J-ePLP`e%s0G0=d*a{^J%Ey70tQ=D7QcoB9V}
zK>i3R>A at 8idbY!WU-sB9dx=&3Rw;DYjFw~r;4Ki!0Y(Uq at ZChD8vvA1S~+jUQXpnf
zM}}2b=>HRCLH?0n1_L*z8x4OR0fx7_&9%`VNgI+AGa;xI5uI6JP+4u2TvZzmBt9kD
z`F+J>O*Ygs2W~ewtTK}&3%uDYyl@=0ENGR^J2Is--`r&k5q4|2`Rq!%5s3(k at G{Ya
z1X-`Jj+9R4h=(=;^V|Jyw-CkV at AF;7^E!ZN7%Vbfpeb9>YtIbz$$Dl$$9oPTUR^<B
zm!^NH2gGFZ4x$rxJnjU8brX;Ud4M`sLYpb(qKwh+NtlUrBOHY%?nR86q0bRZK~vMA
z1MDD;l>z1yMtX%F^U+eu3qdakEx`S=7BY<427v{XqKVbHN?LY>cxyY)sA_v2){SHe
zlg~M8HrSE^<FTv$P~=+Er_ at lFGCB)jk>SMLcvq?9UE4fw0qx`D=0ULrg}EgPg{kp-
ztUO;ZkY5AhZ0>u%3jyTD6ox5VI0ewRgb|zKq9T1Dc0vtX0K|l at u3S=5Q#}RHrT<my
zfvzC^=(6gk!VEIFkHm`gIyj~s_Fvu4wwrIdydhhw%|q_`66}(?PSoD`!b9PaAZoRO
zoBhb+zYoG*>HJTH358HX`IZL<zXl&Lc15{(Q$QX2^QT at 5T8F`2t6TGPB3;i@??pab
zSVie7m&32}yjwVAz7O_Ct=GCQN;{bX?~e~t`e&ppx86nV4_nOJBkbUwY7ju>r0Jh-
z`h^{qY#MB87(~<!`l>-B{hjro093M%E*)#7NQhG;)C(={A1u!Wil-Qh)abFI1G}6&
zZ&aWxDy_a at pJ;7*TDUU;#4UiPa at 4E#CfE5h^5)onnf3mIH-z?IoafZLJ&#E9biBrk
z+W!GQ?*ZILkV8iae5*#hNta@{`i&|+5C$6bIcJuB;n{?yOZCAyMc?E?L*X{bH{8hp
zZtK5vX6FJv59;3ll#il>*%_l3CxN1e7F-S59!noiHp>`X?+tBe#xTWzmrdu3|MTaM
zZ3E<m=$&3fsBx&Z1Z*(zWL|NTZKrR^X^BK+c9OCtgME*9Brcs79wtB;4@)Yb(VpO?
zte>Fx`}Cf6Il++58O8R$a%8^NL{>lH%S~9meCu)7+nlfZNrwVGOU-<Y_i)%Bcfu6|
zrVcO!D(g)YK-!H_FZu_zf<P6<JOFeDX){MI0o4F*Q-=N8ST1JW?%`aJ!)ng1$Hpxo
zTXkkyxlf8#f-jnq4M6}dq|1Z7*T6(ep|tURjWV9*S49`G_6ZXXkbGikXlzAF0<+!n
z$|_R7Jxd>;1N<rFDu`o1CcSlbKkH}8h>P=;SHi(v%}c*dCAU<2xLNl-XZC{L$0<|8
z7T>gad7oNyHLv_nCewxHbJWkxx{w4GW_W}E$hl=H+}8-TN~6?iPs)@X{J7SjpU4yx
zj7_U?iFdusM>XeZqzO#I5{|EME at 891%=Z0q%-h>j8h8=d-31#yU)>*{Z8ubHScbZs
zNpb$LD72lQ+ge#I?H2b*{}v%$Ca7_?Fg21jK>f;=41!NNdJ8*@nDP$kP4;^f4o+ at Y
zt1)S4K#OwIkTG8RY+^8ne6lE4RkE=r+6*gVzcW%x7E4~~IT2U0k;%-FZeZm3Rr-Q_
zSLnYA$jEg=n!jor05@!ahWAbtYswdW6AqocGpj2}Lq9x<HVr=aUh_w&ww%WVKP4RM
zFX%uTYHaon{W<2G2Tg0J&;8ywngT$+x|B at r0iu>gpIm9j(TGgR9YBom*GwkE96FvC
zN9mv)_KF*6oK%qHs}*Repw$Zw?yir%L|(s+k))sI#4kqof9bbXD&akP;nw%U`8jzo
zAAx#a`>{f5THiYTJ2yzSC9Thm^HVj6I^kVCH<q1UpBQEV3pus=^Qb+Ea>A%-zX590
zm?`Vm+`3P^c!z@$%TE>v2i)Jq@;fc)C6)M^bh^U+)5Wnb0Y#dw)%2F0G at V@<(50Gf
zfLf0%Np_A;tDP0A7gee7`IWmDgtmmQN3T|@)7gQ0{&~7W!d(-DI#i8J8c2gf{2^2n
z5uLi`Ml@`eZiyzy%p%mLj}(LLAxig4c#u)QHCwnm6C&<wLc*`q|9pTevGl}G3(3X0
znOwb89bv3DZF+PGs#vCR%I~p|s}~MzKL<<G*AjP!5s2Pyswlz*7~GPf68EO0_!Nng
zD^^*cmCwl&ST5T5%l8lpnd%KCfM|>~H9n`#%rZO-aTOy{6Moa at tV4{$EK!{IVP2ed
z0xeU0`lrbOfl9SD<!>OoeUFI|plW^;oWH-zC at 5_C#dbl&k~IA{dcKN>pt8ghyMiC1
zLfvkWtJE(+4kM3((CpiD8;M$b%2qPRQ2l(;vef-|HH5H=Jn#UU<z4^hxF)f_?$t*0
z at RG%GK6NFKo~rDt|Grl^kL}E)Ono?e6xwS at 9q-rhhW)me-1F<Cn^v51(L4Q{A@|xl
z6%8_lbt8xU4jw>5Cud-IH)LoL*&V}`EBy6icd_bxeK;3Ud!l47Ci2i8)_VqRkV!P_
zC at S*X{M$o at uc?W+c>T-qFf{+xwucte^v at eE!~PKVkmGy*rSx^gx`qZ7U0rz)-cmkF
znqFdWwM|Q;P~P?!F at f)16Nr#CV}`4i{-=qkyJp&2{d&i&T8i07R$cz<_S~fbF0QRs
zh6R>NLY?Ry?vyxbdl*`*R+cc%(8RxpWEoIgX}00_4F5<Cg at NfYV4(qw;?<~{LEp7E
zP)4 at p!?rtH0}9i at wSAD5XjR|V)F;)MFk;paCr#=IKWSmnjm4Q#uqjgRvSDPhY{ABR
zPAVdaiKU8Ojqr=`JC^J<jg-RtBE6a*AVULa{K)M8V6Vu*pn*g{@?qM)%;#`*rA at O_
zl4ds1_YI7IHCsZ{1avX~c%k5l=|$=N7G9qE at M;?_f{!-5ypU_4y&B08qWC(7M6*j^
z&Y~Ao9Ci2Qk8;=+(e7{g$#SKB(4<rOH)w+dc>%e?x+j7 at Kd9F*Px*IOOR@;?-G#pZ
zZO3Yzq at Y;}2sY%u7IFTPToXrG392>0=H-g8G2)lE<y6UMp}_~DT<=jua_HWNa3BCF
z!kvL!gDXQU$JkP5BGw^{09Z|M_pm8)7Y3=g`3F1r|A=8=AmK3On^y;PsX)t%(2lbm
zPj(4%2sH*0ssdm}H1^wCzz7{EP-(;-d*`zC)L37)Bv1K@@^whrzC~(;I6Le?&Jx^f
zijZlpn6lRzXLtX38NQfCb*4Y|qXZNSq at 3o)SqxR$A6b>82zFzNP5li_7p(D?>g`Da
z3$8#iTpZXn)C~U?0EpbWKS)i at XY>Mt+$0_cmJXHupIs*gN`8+72a+++tY-NAuZv);
zXZBAvRq6B*)H0=8ecAD#mwkv7iHjloUoXp`m{cm4N;1I=wMm}SOJWDShf_Ba$hCtY
z8(X37e{WZX$kM0(y(kyXw1g#gzkWeke&L<_f4de5ur1g=wuNax>!{1tS+D~r=)`d>
zqITK-D~BLKigBllk)DmyF200uaSKxu2cwBRt^Yr_inh{*c+MG#N at bGY2se-rd=7X^
z1XP0mUrRxPqSH!wBhD)^ODKZu2_`^jxRa+z+&s_hf9E4A4t1SZo99-7O2+wBkk~Vz
zfP)>8p2}{7N`TDq|CivK<3*!1)CHtal(hm0`|X2rkVq|>4F7k50VbMFzgddPp(C64
z+4d_05gP-z{}L%ct_!nvmZx46gvY39R)Ap&0GRCIf*aWX&O|x|8}s$0(8s5;$3k%m
zNy|9v>+&ONI<pl0eRmr_RNM$niTA?Pg~yl|nD3_QEV!Q5_uezD>M2~W%+#-}xI*t;
zOd&dlB{ymO&(HN&D>F?;J04zX_eXne<*QVl>ut^Ft4Dj6v0%At$WrsU<N4?I2G?3U
zce`OvttXm;h2ukCfADDiD%Eo-c(ng<^-29H_1$55<gT5c- at n~gIOXEcvT-j2K&u^=
z4i{^Ot&w_?mXg@{Rqv(dR{kYdSIE+mi`mu6icRw$U-kM&o~zc}C805I#O%K657sm1
z*HQ}L`>9I1+vNu<U)#;r566cJ_mE!-8=ju7$DZn|_s#c?HHEDW*LmRZmImRBcH}++
z?K$dbDGcYu(mW1FNeG(6Gxl&2AzXxL`!jeoHP9+S{jwF(dd;8qdz<XLt;efB$!6xk
z0t|lU?=ayxgWyhyWKk^*r)e2ht-?MBt%{*3#qLMZ?ey|wQDQZ|lc!_jTG5|EyZERu
zV>AkFnIbzPhkChsud3ds at u>=aQ9soJt0<(OXI!rwueKXJwpo=Of3-5n+FJc1$CZ)5
zSIIZk=(E#iXwt99Z>n;b$pQ6}NsrIZ9 at Arp<5XVZP)?vvoaTr>a?>x>yi$z#m`kHK
zspWgq^k=O>DDT-vp at 4GVBeAwcV7lC)xVa5}JIgVzTKnDwwbm+%(TYf}ApeM$FBU=Y
zaR2jlS-kWXPt5zz|9<t(Vm{X_$j0t|aj#mH*#2c{>a1hMmo9BqZD2Z8L~=Bqs(UKt
zeV8GEUK($CCM&19Ym|AL<8#PfLX=oH&0HH*Cb~Y6r)H;7#B8Ca#!zw at 6ywnp(CYzX
z#aHrWj<^E9>5G}ij8$eKdE*t8#{@(+o_TYRGrV96!D+++4dM3mS5A$F<(9`HHuLy?
zX0=Ky&D?p0&kxfENXh=&nH2em9a<kK4XG;AR+Go0_M>ddC_}s^%}m|2 at z7n<9a$zw
zy*;yJfNM71z2(dQvH-Gm1}Pl-0Vi3U9~tGit=Ef7Icf;gp+pys@$9?36<!IeUc-e>
zmwI7wXme02u97b{BdV*+9P?R%@}`#(I&HEGeaji6%4*3O*Cq<nS{XHY%@HFUHVz-S
zBrolr=RPoGIz{{3e$IdDJYFfVkG0Cq1U`Ck at y$bc-&FYHqVdpuQ}x-+&F=xu0~>hz
zREZ5uYR=>@#>z8A!l3C`j>8t0|E>ODt{4&hF#DyaV7zngg7xgvZ%)&@$F`6hMc#Be
z at EB@XW`cj)TAjiS`oVlfg=c^IACofWbm(HU(I?N4WSW_ekaJQ6rDM3cy|Qbmg)Xwk
zYu^Wg*2BZOeY-yYa-X&MJ7GPijH_9r$FWQw-S&rDRnFdz72dm37X^h!<5|hOc0vxh
zK6mxvtxsJ)n7nr#FEY#&F2>p)TAtcHGM_f)bn|H6vXi!WwznNe+RovFe*}Fh|4QC=
z#pS(|BB3cXo(f*dHu808^*IXoJ*_v<ev?pgDVO-xd1vg=<DB1amNPb^ZF at hXKz;fA
zdxQX#t<}M#RL=`~dH457=0b+qH_YSuVD9>P4c~dcc7j at 6K;Ev!S}Au$=8t85A)M>M
zoWkSQ3ZIlwaZHB&W$a}v^L%bU8nO2_d&3SQ#I+(N6g;=jq&rQWD4=ree)om^W*&N3
zlbN=I%j{X~v!lsBqsO1~d?v}ghkjgA+gP1*?0p-1frgK+svvm>sHAB=TQyWB?k=-O
z1J&)Kkms0l=auI>t;b=ooGPlvAAK{0*v^m7H?Q&cE%0aVy3fgTm+YD}pAQ5BFV>mc
zrG-5%g+3_EU0hxJ>bAR|OYJf52DYssFM2wa4l_f_w1mH<3poLASdsB3XUnwU`sosS
zF-0z%QxH|`zjF86u3cHLxp|uWVaEH<<^tp0C8R}{obdW0Uhn_7dJC{7-|v6idV at -d
zsB{PjD&4h#igXFm(nvXa<R}#-gn at LA?vl=dNaq+e8p$z6NRH<JyubDF_rET#3wE*R
zex9BCoY(z2ulw9*mk%!1Nses0?bTW@=TSI^I<?q=r2h%n-t4=hYYoYHXg5h6%?A!`
zl at p22`nBXVZN(Xiii(7Wg{w4?^=}t0b6WiI4xZ~l<MQpkU`glSf0D at +i&FkEhV7~Y
z`%cO7 at Kab<F4wfCiblh!(kV0F_ZB=xCXb$)upwsRnd^w$k at RyTtincD-(HMf9huKX
z at om^)RfwHhO?T=obJE0&^7VY(Sb4U_n_912V5k}CGN)FtQ5|Y>_X2HtXYrXQZ}UtL
zrFsG1W4YeWksk83o_&SksHIEw&Np9zx1ONJomw?v=zta-siVy?dc*>z?sA0lpf-#T
z!+gceH-eYGkU%abNM~aFm#YpYu=C~RXL!pEKJN8#Q@<AfC9F(gK!7+V#pF=<;*U_*
zX$3wH{|`G|p>CePpQ at AhnOdWDZBF_*0*mvUh}f`V24!3wc3Q$_fzWu!%v4w)<TnUG
zl$%a^Mz$PLmt&6i`VU*gjB?-kAHlZ#CRSlX)Bea)>TS)M`hu_oJlsay$L4iR)a8*h
zPN8Kx^mJy4_hNjj+ihVnDOPFcY?2Xn@=0r9m(vsH{0zMHRb!YBRGz<cS`&#I0#mPV
zEu3r5UA)8KE`njOd7+_EG{Lku;HcR2jn2VgbFR;U#^oN2an=QKnJy-+BICT?eo7(s
z;52F{pv=U1j`J|CwIUDWzrTMdt2b~Ep#|I4lTmAhjVmr3a50akoiSxET&)$mjq(M^
z2Q=swE5d~S8{3uko_^1Z+T+%9;*aGR-5wd>^^B)JAtEmIet#tbA4Ant6}VwO at QB0}
z%~7w{U7aN0lEqqIGoRP0)MP(@*KRX6VwnF`1c|t8qw-vrO_$8*Eqh`-owAXw06UHE
zCWz2Q3Ii^`sxhB$vpIOsc>#HDTs#=kl)ACjUV}J`B{{5Ad8ETck5}|2>iTVdfyJU>
z_3sy!5Awp~Pv=_SjjmGj;Qo-+;q#D at qx}R?tti~i<+=RD&Y4XkZcVnajuuZn-(>0;
zsQ at DkcDtdMsmIIdt-iWpYCLfl#5R4_R7gTzI}A;gAoAso{`)v-zd1k2MoR<K^jn-p
znZalrYO>VdxX at 8_!q~Xja5huS*kIj(8TNvNy2KW{7<h{JEuTO3!p&z>ZHYV8wQTpz
zHTo7#FcKnl(pL8cxbsfSTTdx3M)A-6mQ~WTD9-;R;887yg2p1Y+M;+!mE(tT?=ouB
zTG^{JS<m(4apkj}dX3hrPI=R-$;^$siH)1Zr$5OkY)d}~r>MDa4Jy=}eST;xVKnOF
z1QgY(Q0MqjuS*daCt6QNiG>}zP6r9|nLcq!f&U;cL&Hv&Bc(H}7b=<FmEzi$pZH;y
zp>gieh|;SAz6+JBk=FnEHMAX|C6Q9Jumj<zsn)N854<<X%d^uS>WjC$`fap8-|TmZ
zuyUAh58Z*}jEner%wkmdws6!th^Ibgt(WL`JHwWUOVGv9LVp~F{-5bS_<5-0Tc_ph
zuXl})Cyik^X9HvjdZpIqV5rGPvhqq7i8E$HZWMt}Yx7O>y5Tz`o~_G6hvtQta-l?q
z5sH=z81gg;i!Vm_h5DPBX4hR_lEJRpT-&Gn8`EuO-lyg*(+#@tUDTG(9iHl9CeA%q
z+#&UANW`Ok1mg0GUt<R5Em|0cI&+$+p~B$|veAZYR(N?!a0*VJ$4V``#4&bNYr=lu
z<!C_>M5IPr2mX!q?F55Za-Xl9%qfq?I2Ae57`3j774?CRO#@5~X~N}XNgivnA=1Fx
z;8xy}Hz3kOH}|KmZlf!(rVM$we_FWv^)$JE2%`rMkSjKA*11|k?O+V!)83Z|%W$OO
zcib>Xfk=<+5(eBHbF<0L<qI~Rt%-m$4ByDRbZCCdzFC#|ib&sBL60E34`w+487wjk
z^u2%-7wJm83)tD4-#>^cZ`2+~1|R;+8Tsl16$zezR1lJtV~TX+u^;-BW31C&859g#
z@=cc}Y&njh=;p4bqz=(%%ByNT<5LEewagI^oBTqo=-IofUN6vVj5Pev)B0$zF!fHp
z&(^3x00nkh{cH_g;l#9M^Xu7WN_Fk%^raSvD%ntNwE9TdW+<FZ2<dNnNM!rL+j^^0
ziv5zO-#LJu at _}A|Q3|}FxcyA5h%#2;Af7Or9f`dB=X4h*a(aS~SWkq(`j#Kn7%}LS
zGvVJ7llY-x9_7$SY~0~%exY}e3ll|~&UtGuc-a+tUe1#>dW(#HP1v63LnrATZBDev
zdg8JEJC901XAP$Z^t{8%^Df2YYC>tPd<hY1!gEb;O>2tBn0@~cU2HEoUThF#6i`OJ
z2Q4?@d!#W9y?#y-OukNMV&T2dOq;eZr6cgO48IQ#--J|_X!;ShVBI$pY*8B*r;DxP
zEIiyey97RbnP#a?k!Bu at _cYFdI}1)yI(ptGAL%{OdAioxY~1RrP^Jf72KjC0(F;$7
zY>K!);n_sjfpdom=YR4K+iK*Hi#~ih<#w^-z>!?Rw7POm#uUY>z|*-Vh~L7V;?+i-
z(`aU6J{O`|;V?=$a-mL^*r~<X>1171!>@Pzv<AC55h2s608yI|;4qlHDKcT2cr!wW
zI at 7to202xOFU9-{ibX#0n;CC%+lLcy?F3cf*@hfW9;-&|AJyd|^hm_3s$K2T#tF_H
z!_jxGo3AdW^C{N1=X?$+_;&CF8BwiyQcObhhr+U&W}kF~5GV`NvOn6GKbf6=5!GKK
z3*R`~o at mO~7^7%$Hdr{KhMZ0ZcvUc^>lJZAU<<}<7r|+7FN$T(KW`^LXguDVqhl!3
zF4z`llkD0+SJrA^r*|)>clz&LfP0M`VGi at A9_O^`^|e<X$r%4PkS6Kf4FB5`N3z}=
zsn at iY^xX%i?8;k%p$;<2s4v7wCw at +f!<OA03fMwwp^$l1%^YYC^3E7jhWhLWjVRl4
z<FIe3t&;>?vI_Tl1ctbRDXT)W1m0q5tVeM$J8MIEW3hEULdTy&TOE=5sk~*$Jobl4
z+sLC)*in?q;r_xO-?@V=61uUsew#vdc;Wy82P3U04C~~lTz(GV5Xu-lk#6kyS}YRs
zP_3}_^7r9sXo9p(z=4x#VHm7tyAj%Y**SBiuHd;nj`Hi?KNyQM%9bTQO!r@=^D|76
zCS0bt&v>>fDzsYUrF)~OtIxlv9A5eFkdxt)F4x-A$0HX+446|JC0yF<MK~BzsJhr&
z2wo3=5C?2U3~GsS8Z{Ns>!{^@(mjl6JrKB9sgu_83|Nj9HXJ3Ex%5Wj_JehF;MQtY
z{%MWqk|MF>M at mJ{)r#Fe=p)1$7n1{FUBxX%1Y^;$LyWKb!eJ<}HbhBhyg-+OvBh}d
ztc~PA<qFg9{`;r-MQ<q;V^fZ1l-_BIOskyOWegVohfnwvE^|_Uxmq6Zx)YLK3c1{`
zsxD5#LB;0s#9Fq#2Sv8(UoGqKjmfpEQf#)qlR2F+9X5{BeqiokU@(yq9>rDN+3L_(
zE45}{T;q2a<7h2Z%DXwP(TcN!okqNhK`ZWfUnv}3q$55wy8$I38#cK8E1dG&Q4-`}
z$@HqkABGh=q`unSf!GO-lq2z at r-3uweMC3obdZ{kQka`{3t66}(i%Gf`znV&(Xyw1
zun~5tR)%Am7n1=<-K+hkR-<4Op>d}R9QgE?ecd;JB)8xVOV2Oz at qtb!#EmTFZZi&^
z8$R<MfsQHCJ%De;p5<ApN=<mwvCd6e4nBhXS~>~apLBO9iz<UC at EIU`>2S&eGaJ*!
zkWDv?$E+9ydV2nVNn=?xv9(roVTJ;K>T?TNf98WN7OEjWO=t2c<y(UXTe6i-)yP9n
z<+C+a#GOIWa=&korsA|;*?tZ(ABMgtv`zb0Bkt_Z!X{C-(x#J!OXvl>5#>#@c*ChK
z_o{{S!3F!4OMI&d(nN!Vgd{n9;=uHBljCB2$F%q*-_C8ay#R+ at f?7#y1Hm((w(R*}
zUbo6_QBNEJdbsbtY$rIcc=}AR&_0&$P~=UO$!G6c^TE}IJ#!6Y<A_`3?j?5u(bu5P
z(;JDZqRpra3vgr(58lXj7$teoIYIE-6Trb1faO%le_^{Ovj4r2@&zKOv+=rAnl?Sr
z3`_#w#)7feDtZPpTrcIz+O5~E7=FtK(N2i7)+uY_$Hbw$K40$ibHE0roY1xtigKBk
z8E+6G_ywVL$YUqrwD=+wC2x*ZxHguK_W?chO<4lTHZ|Rm5FjaNJI-n#ip2(Ui?k%b
zCZbaGkLXsWlwM(`EmUihy9d`+GwYAe&+ at C3;h5ryZnI&Td8oV&+e0u}a8ll=vRZ?A
z4*6X&SVLvr1khoE{z!Q8jeLw<1CwgMXqP0H at TS#sBJf~DiJhop_3~G~VH=ZoIIe&V
z$+;;m?IGW-L%+AA80_g7p=s#nwDdT{N&cBQZLWt<V~6#QL>$EFkYP%x;Lf|!)>0E6
zFU*mwA4lp5B%KU$b};lM*waBK79;%@;!_L>C at kHoGGDNz$0*zUn)2dM?KhO!S3`|c
zTwLTAa;w1Q*_1|_<`2tGK3EqQ7aJNFXimgueW*R&D|@+pdZo=_eo+I832M)3k2WTT
zLId!ntu2l*@3qh}{sHu0Xb=h5_iESZV*~y{!`MRK&0$-l$*<lncD$Dpro$Z$ucb-f
z^2JUpKUZphiH7|nXw at A+IK#^aUY<fC_Q-<Cca^*mc8TR!`c=8I)t8yTPowydo%X1`
zQJwBvu?@oAj%$l*w%FfZ>#mbr6IksGnw5rcUwto=H1t!9Q!Jz`qaBu=C^~E0e;Lv|
zI5}-xJ`{TjYxjSAcu_Kvk)VV$nIxfKo}G+&TOPnWZ)flUqoXnLuGQBdJIQTvzQz9}
zEq%<PZ_Ftf4hi-fO&yw^|6uP%2l0~Hca=Po&u at 0BZSlZl0@c(tDLmU}ZsmR)6G!bX
z93|yjj*N|IhY9KLdB!;Bit|0Us+LtJ=WCb;rv1f_)N0`b87-S%f$dT$<zInA*Fp_W
zOdCRrnI<#&P!5pcgoh-RDAMDt6aVPMC{s{-CP$3>v;m2L4-&BlN=P=8iz*MyHA?Yq
zP`7Z0g!Rr20qYInJ>gB-ubPzL-RbdXCTH6I^F#agSlYV%%WZ;nv}5D;K5XuAM8M~;
z?vRwi8V*XuI5K^L;A6XvGaEhPZ6puAqHw`Sgt7jdsgkjq-PRjeQZktl$eA|b{r=Mh
zvHT`^rcl3q#edf`-$KM48*7Jrp+$grjZCZC{9<$F7=stNf;IA<-UUiZ86zRb!5|a{
zPW!L4ruJ6mm!EZXs)JyPy8D$dynTvg+%4;ZJ{0;tSz0u^O^mQwX=9mo+$v1>c8-X3
zQITOe>6^H|{pISc|4IA*`@Is-i2+Gy$@-zTy3NKR%)xuDL0SkvoagyeaaBoU+GTwy
z|Ihnv<TsRSZt{JS6xF+CCQMhTw?cPt_SlBw|L*+nA44C7YXp^$S#RR0=_0#1>4X3j
zlhZ8FTS*S@#^-)BSdo+Tj%zwT_28-jGhn2X?DGxhJj#)P3^i1vv5HXl2$(6Qo3vjx
z5iPbBClKUs>LeHH^HKZ(4h}z<=)r0Gf>JO?g(hdJrCUNZPE37=1ZNW;Dd?qh+16;`
zk0bzI2}v0WC)3g~Hop=^{tIa-9?s*QGkNd=SGaS4=rA5{3yYNFIQx at uhcLXZ2A>Q<
zsGVX=()+}@rA24)%kf#^qu=6FH5wll9hPghfYDLzMRLia^!tO)c|7JudzHPN>V9-8
zt>qO78Mp9{Q1}nV9B>7=hn0cH^rA#4dTTVi;i=m-sEHcC#;*`2Tn#b};$-8HzR at C)
zc1XCrmEu61<jp>DR5;t;-cUQ5<gA{0XU0&&W>3|YDa#KkTC$~pPx_H|;ZbDs>gaa*
zok7}3pdp-BzKIik)M`Usb_EQH*no>NL&pa;8g(1c;kEDqdrwPt at 8cZrd(c1pC`?K3
zVf}_9a at n+1U8DZ^2J(1HV*+wHCw1_319Vt*y2*rPw;?bH+wtVoqz!$kel*f at 5}g#d
zW}b?2<4E-`EIypa8{{>X>F9K;d?rNDgK7X7aSzVK`k|;gD#jjJmaIyR^Y{DBvrrh<
znK{w*c5A93OXe&|Y@^tJy%iUK+PqAe{Fm#f_g at 3#+qk}>k-fc2>#C%_%2Y9HK$eWR
zN>=4~-akb&$gL8XkTaU&M2D-)P4Zv%G0kRFA>q`H_rhqjyevOUS{OYHKEvm>#QbMe
z37&O>I&C2(o=*Fr#EQpN)%6Ab<(xX>pnP7XXtHN1stKfehy6~zU(1?TDv}5KsOGCY
zvETex)yl_Yyz$KVoe0vg{*(temH(Abm0UNpbo%y<F4|sL>HM1nKO8i)w3bZ!AkOeX
zFv(UlMOm$s;}eSgrL|gF_c#F;Ie%{4=)AD4E-N41S2U3u2{vs#v%FF)Kd&%FtBucB
z at df`UG<uT~tijKPl2o<DHinXDNr~`t!ufG9IbNOISnB$aMwJ4)7)<Rx470<%Q#&rw
zIPcSl*=7)K_LM at oRN8=m6-i`m#(T$O`|->gR at A?o9=ChJ2HSbp@~%lYUfbfagY|F;
zH_rx819EmSE^|!MXjhr_YDS-pV%N{f=K`FHng1|of7Cq4_M?`W=WOl0WoED~d_8JG
z%;sP^vi4sufNrRYV=+e_U4$sZ8SGxtAG1S3LoMK*!xuirg?1kvdY3gC@?CrLptD)P
zk|h5rtkE`eB#bYy5TlZr#NKW7*y*6XJRtXI+elN#Nv1E_D#;()ZBovBwbPnEE*MkU
zVXFFnmaYT?Dr2On;}|`ujz)gpe)Av(QEV;BKt3)EZ&@rx<m(w-#0tAAsej+C2HCyN
zQ{e?&fshvqex}Op%KtZtYoFEuak6^;^L{OZ_%z!A(qLHtFYWkgY~3AlcD<tId3t3z
zbc`YHu at l<=cTx1)m^`~`DE0*aN<~GEmh#aao0FO2<KwlTtmD^T{DozyRq{8kWT-5B
zEV-Jp?dU|*M%ViO_+yKbR=vv>oeR*mZe7gWf4!fbA~M#hP&Swx2b>NVeJ_|)eD6q6
zN%MiBk<l1%0IJ%D;CKi_s=<?rinK8`Fr-PHK#Wz=x2$0|NpRcJ-vjkFSoZu|vUdt}
z(aYv4Z`Q)52l%Tjz;bfzk|!>0ljVcS8Ar;Dn?yxy&*!tAHl|pwd6)IRA2DG;5B%qY
zvP;zE*wHbHJHNmfLE$Dxl?g!IIlutwfW13zpAP$vjV63mpd?k{G<Elbb<M5mn&SO4
zo2n%F>?n`z*(thL&@NSDOgCP{$%699Uyrx48P`}=6L94Z-cLe}?d`cjdLGDSf>79K
zJhOUlrK-DeaT!EJExVFiBuRCxk9YJMJt+|#d2sTe^;~XJN}eVHO9z)PDti9^J}faj
zX?$GA7^qf^b~Ef!9Tf&<mabGy2Lp%6WyZx>Jwz at ewKT>HfO9N7Dka?g64NPAYe2cS
z7aesLAM*ks#H<;#`YKhe3^*+R6L(6{P}M|L4K at zc{?QJnkTh^X6kG6Nr__}`L3JDB
z%s<?+kH{+K_0Nsphs}6=S<u7O^i_`83V(oF&=}bz=OIzMULXb8l>Q{ZWdqw@#PqV$
z{;wkXudP#;gUHBY-wFifjaF<+9m%*``W5df<;|~4OrK5aK at 74T6l{|7?Ch-bQcwI7
zTb<|(jWK{nZ1P at v6Q2vfY9+UdaMgcMO=;+5=Hq+t<hKH!BLax7oM_|*pP2*`4TfT5
zOioGwaZWPLBf<J8WhwYCC{%KF><w(YO!2dx`#yybScY^2yi?M<1#JJM+Q(qMA&gJ5
z{~wF=hq&Cz0g5Efob*($&kU#*;0?z`9d2W{`32i;$?UAHBPBe$)TFVt)&}u*=H at Ri
z`~%ATp?`Un(h!*?$EE-C>*33qv8Nq01EOr)=;Ph1ceFa{p|o&$V16CAk{Wtc%Q2%s
z)x`MUUU_m~z?$Zt&~hj1kJ>utGcfaymAo1u13x~vHmisCxY6pDS&OEr>pb}S=+PtL
zl)*K4Qr1)Lcq_=H8~Cp%28f2gCC6Ifuvbr|YE18IVsZu at k--N|-NI_wH8r8hjpCPv
z#<<Iw?U)Unaj$?p)&Bne=_*f6HE9iv8E(@&ya at Hv>_I`B0mYG}r7U2^-6R1?=|A((
zD`7v}k^U^ESJiXj%ICCcx7;?KC**O2JbX;ChWr_(@#Wibv5jRyv#PhkX at Ey-HQ`Sr
z?xDsh5zso$>!OP1?lu0^&ee<y9~(PsLcF<B^?!y2eCAz{YIv70WA%^2zV~cuDQCi?
zOQK~)A0}q&rV>8Ps^)U*{UiJ3pKJQJGx~pT5Y8MbDgnR&{LpFO;LPu#Tqf{}O(BB)
z|Mm0XMBJ%FOa9ZlJbdIi<MLLbX<-9T-{nVI8E6=sCCIyjb+XHZ<K$~xX_WSZ9>NoC
zolgiwMZyf^B6RRZHX(c{XxvDg^RGZ>$Ce2!8^!Y8e8018v;J%fuXB{JW at oLIjkZ-I
zj_`XCoNU?0zB<JOl%wj|DVP*VKOSK#<u?6S&$AbWz>^xwW|l0i49cz?s4M|UfOi8g
z@=VG-E$r4z%JaGVg_$Dbu-<~!e>s)}fC9%(RYg`|Bq(%MLVEF~8NVJ)N!jzctDnfz
z%?(bs9}-!rNqbB8!OMFA<=r~LQfC9gYI&}eq6$K6HQXZ$ji>+GNG<=Z8b{0#9awr2
z0Ak3izk?+jy6|I4wMe;0ew0dDEJar<W_euIoky)pXt4Ij6VYPB+Bi)sAlTa%-;Cm_
z{hT2GD&cKr{5H>4y%E+De;Ek++Cn2?iw1Nq(_gtP!CUbG%BGVd+`748IXbSF*Z;E!
z-?$Y at do>~D=wABn4G=}6eMEm<&MwgeWa1vItj6++qlz1<H8{~&Q6C4PWCPzTz<~Qc
zs$x=Yi2zpsT%h;+Ul*=0#J&yfvv((RpA;OF^-V{w)BZQSjt>B=svPsyApV`Uh~i&%
z?VWNQsJ4pMXs@>u{UtbcN4V;3lSxjq!=oe@;jXv at DZ76+>IIVuxcjNZ9sar#yM$PH
zQYmThmSVgW0O5vA>cSF|n!JT0ifZwN=t5(sDia~i|B4<R1Qz;F|C+5ekU*5yw7c5=
z|3|SEP9<l9h#QSPjJ%LD_BY5}G-I*TY(Gup(D74_qP=2<+F00Gj}G{5P1%bAjt;}i
zJd%q#9r!D7TqEd&jDrSoW>>6DigG#yiI1Xl?EJKKkbahVMMa_&GV<0-sGJ0N_wtcb
zsXz?2A#c<U^7jDIE3+{)yW->DtkEnIjD>hZD}xWBDTB1aDYRz)#Ro*!muwP+tk13W
z?kN5bEWd=lG5p_Jfd97W5F at ZISiP4J)QVrVqZi8eq0rH>19&2c2|(u|ooD#0q&O=H
zj7?Xq3S<DF1R#_M1NjW`f9Ov%dv6090Ietlxb!i=35AnX)un#9Hg<()3yRtn6 at 54}
z_CSx#mQ-=8 at Njdx5t1ruVw8pc3QbqXJ_OjuZKa2DYpO~i8?6Y42 at bC=*sKP|+`-he
z03p&da*>0qbfo at EHXg{Gd8$NC44LuUmZrY{+a9jlO05eC?2KSob*>M<oxrT<B>nr1
zWspM{*cdqL*|_wL3n&Ml;5ha~dWtjDS|ww{lRzjPObuXJ`pmzlxVM25$n?As5P)Nx
z9c at WjHtY>88km?kX1_)kxL*G_WuKSzbS*v5X^-B*_OFi;&5n()e%J;B1D~|u={JR0
zA^^|<d%C;pWTOj&Bv*W%f6E$7k!VYN_U#pL2P*^VtUG_xG<FFgEuFXsMyWiY*{bw&
z(&E9KG6+D?fR;wR?_DiMRWT6WZ?7N_h@{t_j7n}Pe4kL&_CewKmQn0+v#ByFpwi|-
z>m7;dhy9cZx8x?iP7yy*_?9&RCR!F*okz8;SiiiO&{*ca_?24O&?#|>HYq9x=T_w3
zTHXy>69D>`B%EIO&!oyn13e*A-nG-Ac;n)+4M2(pnCQ%>b-{_sZ4cxmvxADdX;U07
zlIw#s at u3*PR-jjtCwW(OAAGIk2FRk_0(LmA8nL<31-kHWy=bNiJ-)CXYQKB;vI%1B
zW8YV4ztd|ZZQ7mgj<lCaU%*1Vjr>pyY>_U;m at VwFQFDYTGkLHBo3;$<y`Vw*v5Cg=
zZoQv}e*zZBTL4B}9co|@U$g(Zg*AmbDQlh3bijnovP(W{L<EcPcq597p2t}gwwVn}
zm#23^+91zFwJOKA&#Js4hyq_qT_H52Tf1kV09PCnhM!(s&e9bZDgP@?4q8JY<Cqn~
zezLj+SAQik4^vN=a2B^0<HycfuDGlrPg+3!{v7l4DVE-#eUP3(JOCnTJ7L~#6%=t;
z6h1W#W?&HorKGw#PX(T at k@I-~o@(3R?R#YW`DU|?OghG2M`w%fw@*FM`IQ&Q5tCRx
zShMCnHPN&X;#}oPz0>A{ZuOZzmt<67QYn)i%57~&38krH4<fK#gbe{V|C}5TzEhK>
zmV6VJi-0n_1t$Qd&eE|#*l`F<GOd>2g#0ZMYh at s{=D*h2+1YToSh06p2 at y^oM`3F^
z+<%@}e=fwNr1z%p?jJMNj-Y{Ow8XkpZ|~CWCGQ!L5d}&#iebK`qh!uZe67zA$oOMl
z&2lK??s-;3QIT@{qO<yrv;A?^&Zh-5{!o|>K8-&!Io}5u>#tw0-gWjsS6r51>%SNg
z^h at MovuxXDd}Kp~>BS_T$4q`(AyUm(bzxG?<OSKjj-b@~c0xd7ePBAlYu9MM>Qqu%
z7B1zRmh}`^L}x01RwA6gBkJ=C13<*a_3aRJBQEnN;{<#{2XRwri$P&_(XWAa`_HlS
zWvO0mpp-ayOZR9SBLW{HRgw*sr)=_ABwzN$r)E8!-WAuGHJ|JD8~rL(R5UV_CN%>&
zX at qu#JC)hd0TF5ol-QB~IU$-0vldLMruyLA at Z$%+Sd#7oB14cOK-ku#cjT7vygWRE
zjKfScfvITQF=?-I41_bqEF~icgU3x)SWY)Uu?&+O_4(1Yt|7`lse}N#^zKid{I1$N
z^jz^StEmwo3vTzY&=+w8AcrL3TYA^G?m?0^)N0^Qj1hn+-NoE0TeA&S$b?<562G&f
z!B2N?G)-pogw+7g$j4W=(Cs7eCueETrgSB-MDFHPN(`RmhV17XTrxMLBgn{}GYbM}
zu(eMLOdne!VW&NTcp8`zAdw-ly>rij8&(F6oKN)Uy;%j=BYFK_KUd}0@}!o_1j4 at e
zeHNpXM>S;nTBgvHgJn#lJlnsClTHp%?mV=`hI!k?9%*uMKCi&UiJJP?V?(gRchSWE
zAlc^^bX}XtDHzK6CgSQoAGjmM?!<zLT0HSA^hcoj+roZu?tY+A!q{_{7T^#!<QVqv
zL;ArGWPOu8{b!LG9gSazE3Z>tS+iLCEuO3xa$c)cuZTDjI(FZImfw`AdznM{)anCR
zta0$#EFO)Y)Nz`P2`7eXKG<Rim(Ok>vY#0BcZ^JEL!u&p4A_UT?Qsr97!lAfUk`6q
zSOtpEiKD#;u>Dg`n!O8ZIrKaUcG~7qTm4lXdfi39>!@J^X~U?HiQaVIB)F(S!GQT5
z>3f+pwD`)H&;x+&;81GZIv;$C9^tfL<92tr_xIVMm+MeT7+GuyF=+eN-b8i>BM?9^
zp{0mL=gAwks1*0m!(x|D*NX@#JC>4ZKt{;J%UhcsR-avlKLYL6pKi|F1rBMJ)h?S~
zG|_IeJOwk(E_%<Cdg`MbzDgCuFmrGJxakg at sZOg8JWW=2Um{<+vqWCbRW7rT0DqkB
zX<Q!|wBz9%96$h}Pu42-PnK)8A at ruNXDKl<F5M#|T98{KQ)a#`wA;U-Q;*-zR at B!|
z(#27F9yjk0&Qg}hmz%bh$m!YMEt03ZPoVu<cU(YBb@(aEZJ~v;+;Mcd_aNl*-vi>~
zyx}J0nCA>!<Sj#kFJ91sZ!}A&j{z`9 at t9BFiBwvcNBzb%ClHqyIY*oL!{F=3OG_3~
z-=!1D486>}skH9g2YJ6l7h_$r?pMEBdPV5^GwJ1`|8jK3EO-58%(aAIp-=hc*!DQH
zUt#eJ-K~^f(@R$D7C`tx!2qpD2QNq;6r7)jA1M1EkVGZgNcGK%<ti5wo)#wL?G~GW
z348|zIDEh5>0Rca4=XvZqp4YZ{0i0XES@@}uk8w&#GT|-9we at M&okv2o!v6O1qEd0
zu&}T#!yj#waPZCdH^59L(q=SqyH)zsUg7I6516u}aDEyZmEDNo&v61WRA4;Fmo*WK
z3TGK6kq?Yk9&3%1&z4y38KU_t+Zs%CAKYfbj4+KvQjnClm)VlFIq9tg?(BkLAZlvr
znTDKsVQ~VIa+AvU)T994Y(gCPvY6WPplOxU2}F_o&paEGXW(smfrIaY$!*~6GxqO4
z{C~^~vE)|B{T?U~?4E;+V1v3t%)T&I`0)v_%2L#0ZGiQzix<8%0SVdN!!uFMmmkJ_
z`r;l+;eGP~ES0vw<lQ?6<}=yNh?lJkn2n7OQixkM;Ty-z7TVEf at sg3y-`G_cZsYeB
z{zM`~iqz<WNeaG1yW_I`i}98Q;2kDx>xbS>7t}7n82qnazwQi0$1IXpJ{}+typCzT
zyIw2sXG;i+_k3K`7rJY~{o*^|UuNnz+H&9xrOv at 9SG+)Eg3CXjKx7GT+ZZR*qE>$j
zrA~fBTLe&`YD1*F90fjTfYvaD*$wH)GC#j%HB=bNcD|~+5Asbtkau=bq`hhyl0tb^
z>P$@g7HClp6?bf^ZzsQw2h;hWGf^Vz*t%tSePCN8?`)g25K}9?Q}b at U!1B%Uz8;da
zd3!F$8}DWK#h{q0Tj^1iYr&R^3pZscC at B1WewXIp<XC at Nc*UCBW;)eA(#^}UK6biQ
zGdmD<bdRT(cjG2!(6>ayQ?31GaZp=J%L10{H?~3!C1?9_DII5LImY!lc0F#9M*q_k
z+s~Sx?L&kmxes3l$zI$HTXy)$5Elu)fAH(Xhw=Flc=S!^yfB?$OYo$)=<~Dnsr{}c
z$vx<v5Tal4CVxm?-TX%uSPSmuD(pvhS6}zXkZ-ei-p|I*8JV|@0*wN45F^Fw-u(Ql
zF9*DL-PaZQzq7x|;q9v|IaH1=T9WYm@&(O&<L0)kyow at c=rz>uSb1o;q9N^>r%yT?
zKTBG?rXyaD?g~L4$xL={!$fNs#CtF)=j6n_dEa~MGF{X4=H_jX5&*E7Wk)tjJ{d9H
z85orE#p at Sx#J32Xg(B$C7vJ=SbNqsaLo9PbP%muacH+9|4+F8ImX7z at ut)B;ZgP at h
z6x#qn1YizEKr+!>EQ`BFp4p5vBBhaC$D|Xh2q^?b&Zr#B+!(`SHAN1_^X>d&5?C!V
zVjUvo%Y$zZkpf+6D!46 at m**=|aBPQQH9Hui_NoC4ymyey^3<{;R#Of243mK2b|Efw
zbSt2|cHgt3NZYtRyVzC7&Fv4ZB7~j(*R?ppN)=pYG_!_wI|LmKcnsOFBJF;?ms)f*
z=Bw0t#t-Ol`k at bv#DUiv8TV2<dW)3B2(KUy&ErC-Z6bPCVL2E}f$Iba#TDze8SQ)e
zB#K9#&Sk9IEKIYcp3V^$J6-fn+CxS+$Vua*WT(h+r~Dz0{T;(;46_9HvT8 at ZDchKv
zn-9gPYHR~ZI7#M-6gWh;s~I8Ftw@{=s at 6yD+TR<NQk5H!9qMxeGN)DOo0nBusnkF#
zA8=&elc{BOK4A*s2(WDH{73B%qGPt3Q<gu^SP3H})BEaA_?aTHtoD?fXy=-&Y}Uub
z35bHplW|IsvagB_yP#y=pKzQ@)+d$eX#j|k^&sK;%%wH9YgyC at CZcqIbf<HE&}>dV
ztrQz0W+EdAyfyNc^pO&N at o_&AyR%;pa~h$44U5>BN?$Y|Onr{Oi+Tv&1gUPy0m_|y
zd2dhXPA5=^-<}bFaL4r{_>uHvy_mNjmmVq`sS?%IrN}~n<#a{er)>Y at QOzIunb?o|
zupM=8U+~x<?2tK4X^cX2)8ch7EZk&3G46+Ym<e>`PN~mD_yn~{K5sehLM}sLhY=hc
zPCo8FC*K7sa{~cw6JZ0(-pjHHQ9_c%x7Y5(E1~zAT`7D>8InAN1Aw)l@!5!tMOi3@
z$6eSCGS;LvYU}RquAbi2Oms5{;Pvv?o39kZveZNHGm^=%f|3=@L=qg~9X?3!05^15
zQu(qw$|nrvkhZ!jy3O+QvDdQX`Zt6C^H23#BVf4Hu_Vr&($i}wL`s~<ct~NHoG#ie
zDCw03=pkGi#Vn9~_>9bTLBUP9GKZ(TcNyQ4kD}U$<7ITXP&w5a!|#$>C%>TH{*wrs
zzq6rcYBm2lr)SixnwO(%n$&Yx(fptd@>mN6BAUPIU=)_O%Mh&Vsb{N9to_9}pKzYy
zLdy7OA|)!Wf_7V9Uq4ZbxS4?a&c6Kz><}bXUkCVQ83!YDz-Fl#c>UDjeb);Sjz7`L
zZGp+>(yb_?P4UniFSJx=>RneKHgLzawBCXP@<f6PK92Gs4CHlByhITt79(;Ybdt7`
z{LY~B9=$}}3NbH0L+--o8QwDcI*jNJd}a3vBMOf at 0G4e$IJ0hs%E?ifP5Ge3c>qk!
z1X-Yl#(?<Nl09AY8?061{_KzT)qZ-#*8TAdJ{*w`5MZX~Xo!98zz$2IMMo%P;%+xR
z)Z9FCFyS$OA-*y9i+2o~WU;~KQd9W5?TeUKijA=^-;w&vK-9DQ?nV=RrT9mZj^TQU
zQnPl}N-}-O=?l&`2Q&&l*8_VH-aA5p&@#S-R!rW*CxxZqABF`M!Acu+aIFApyK6br
zbWhRCJ3SnBB{^F6d=oJP?TPbZ^120_q{kq!36cq_D8w3a)h9pui%&A_ at n>)O>8*~8
zPdmGL*dc^3Gwbe~l@?3kj-RvT<z;0<jJ4s~l=@!01wKj*W-a%_)V(&9VlpmsJtu<2
z*gz8)qE({12ZGT|OD8oE)|V9EwHz(_=3%_OnTql~Ts%TnhObRE{5Cp-->=W+bL%L%
z;7D`x1Wm8Uo-{@{jOe at W14fR6wKK^}leO8SvkM7Bv9>}CU3Yr#DQ7#Qi4ai^y6_&n
z3s`4cBQr+o1J9z+=vpC(7tgvs6M*gpf<V4T&2}En5_MPOIcj8NB)-1gC#Aj}mX1&S
zN3z5;T*~&raFWXG%ShjxsnNpuuTnjEKO&rOwUBuJIPTG{Z`YO`fqS<^-B6!hM5@*j
zy8zt<M=M@(+HzaS+MCb5Bz{A^ow58;oNeh|<()=nVw`ISqd;Zv`o3;`AR4?xE`O74
zo24`H#7E$RrBCN6G{U;;-hJGi)Ri)2x!Kgqxjyba-NL7do3i(qxLypCXhiV0f4zl7
zu<Z3E84cXy1P>p?3L47pFe0xrP{C}PHT4faKVS_?&&H<rW(ouc3n!KJu><=yMz(>s
zd?=Efe)dqO$9O*=b)qv9c$R|T_2H+XV~FgA(kC`UUBQg*-+~lN9(C+QoWn%DS2?~h
zslx2)c`d!B3AX=i7Cjc`ZG6?Ex>o)9{g)UMbr^kp-U)Q&>nVVu>~AWg|LD_YD3~dK
zr!6Ep0L9F|bQHq|9%S?0rD%g=sxg at u_Ch8jpYu6wz8weow~6cyEb6BZ(vxCoVQWgV
z*<#Zm6VzAmQ7S}In#TJ_rrfmsLDByA{IXo>Pzej+0=wJ%_wU*1pkEwbR_=3_;q*^J
z8Z3?W1+wlvyMLf1rj`xl;JTdAwSZ9dW8|TdwdNhzm3XVbbucUlNBT#yqAVlklN|YN
zE#EGFRFJpbL5R?Y7hq;^w!iKM^$jNGNdXPG<?pH>6IHq&2(gh`()+YqVIRYl`b*}i
zi_<&r28XM5_&%18qrG4OhuJuEFd799q%9dZ3j(alsoh;@w(YL*!1XM1fMM+rycHGX
zOB at vpC0rD8y4_dJT~&KvzYRlTStOG!$d^2v6~b5cODqo}<6g0C{}FN|_S6q{43cWz
zX5Id=T*CEAVb;8xEv-Scxgfg`TOecm6!>RB>$+{W^zUTO?LP)TXJ5?Q0HElZ1f%9+
z7EEKYu)7 at aeJr`ix*g)JlmAVs at rN*(nS8Cm=GSV=jf{yz at 4c9Gkmo&qfha^s;=24-
z)npptG^O(DO^f3+#AMm)vc&HD;Fwt>($=nFuKwbYX=~d=?<eFZbf8I}SCJfc90x3D
z7PA`qy<p4S at 4VC3V=_Q%3=ldi0UTyuxxCa=%xu|u*~d$biBz+2#CgAdx5;6%lJz#1
z?wb>5%I*)Ys>knpQp~-$02Y<BNqwDMqS)8O$B{PI{8*HuqSKchHgkuSt%vP6#N at kv
z-`Fw at 6(gH5>g+3`lBOa@&>|{SF>EPyG+W*>8usbq$Le%jmMY)(B_F%pRqpi|kpv}6
z5N^F)c at OnZ6j!|&C`Y|1addeEp|o`^yK~p#nez=XEi%hXMuI2~JfAJSVzByMv#dUk
zw#F=WVtGkow`$tU<q4B32JCq7<^FFv7NN+%Wep9!m`FcyiRgP|hOoPq+tKhFSgi_I
z)6LZvA6UpvdN2_ua-g#%*jjy+*G&?hAFmy99MFo7<G#b9g)<Zd7S9#3qva%SuVpi_
zGJgH|Sd#7b3p;V>g<RTTj|H~^lggvfJC(HC8H;o-#A)(TcUNyy5}Z32-F^VsrAmh9
zVg$`Di*XfKKq#f*hBf~A%?^O<3yAT=zp!Q(DeEqERv4)J4RsCJ<9?F+Ew-URDwG1J
z9Xi&gpO-8V6K?OmNG^G|(K+}~4;Zowad(@A{_&&4Z(~+V<aiZHwGahw>q+l6MbYfh
zlAql^HWE9Dfi#Q;l%8&L`+#T8=I5L_5PR|mCreCnw}PpY%q?_pDW$&F-C|AqhP>Sq
zn4|YKEH?M|x?MK94L+^I6ye@#M+yCWd-C at 49&D~4XL>Y!%C#^PI at s4^P`Hr*Uyv at B
z9ZjlNJZN*nfGVb=QMrHb4`B3-d~>;LZG-K5!<0tdf{nb`4?F6ljL}^5T>8VeGYILu
zsESKzsz&4^yBDy_k^!0_4li~yi_a{Dvg#Xa*MCK?g6`oyg)zC8%_J7|jZ8(|=-KPx
z_W0Q+h89|XZv=C&XmFv^JQx_J{f+!}`^K{;QA<k=8PVC7EH%QqVjFvoolN&`rHAkR
zIIvD27CWjB4b5}A-?3q_VgxN~I)$DvO|}N9Q!^)5FbB6WkdW|y89Lm$+0?Jd4vvR)
z?6>2Ss?@Q!!kUjI$o7&Tlrdkj{nzF_=gl|OEMVUcucLzW)A}fl<YO#;3ASm3i*|eq
ziz;Vqi%!R!eX&%3&UT#{8~8C&GPQw3-~<sz%~qG%Wlg=sc{KJrN$z8BbY9Mn at 6#{&
zZ8by<?z`pO>j9MZsf`<2d4m<Purai-==!2nuiFy&4Q5H*^@Dxr$d8Bz6_Ya0mdLd}
zmk_hci98}+e|}>b+4bsy+XuOBE>t1!EG2wOpNxyH1t96XsxN{yxKDwEAVa9XK2S3L
z;Q);v+jhvE1p$h|A?xL&^#iL1-|GX%%qyvY^@?nqclKpI!x^WX9|PAr0Etp5Izkkv
zw?n>~(wv0cN8Ldvl*FoZlc284HvzOOFG7CWrGt at DMd+?#I1_+><pRm#HUs?U>N~fn
z9d9+;|5_uqw0O_mut~Pe-bh2o`C~W8N{|LwTkTP5H2LM*Qec=)M3!FYBP-Id&etLn
z8#dwzDc>JUK$VqH7EIT()dqG#7d_vKSd>%5CmsdW)Cun4ET23W`C4zbZk{tf=zC*9
zh)lT^BcV0Vox>x5{iIECQ+8CT`MW_ii>QpHogoMO9s1Z`S5FUn_fALqSIBfm4Dr*4
zIDqJrQS3*g6%4Ff9{k?D7uHNz&)iG)_~m=RQMvbkjQYll&lEBgcK5 at 7{4nQuW?8oJ
z(8t`%w7Y=&8JT~cVpCRvor{Z0ndc2;NeeTx>d>Iz*OAt at V(83QFM4jUju{+$sVsTQ
zWi{2`xmS45Qt^sX#Vk7ccYzSqfVZu)8dZ*g7`k at _YXqnZ&v<S<F&Y)tEr{`x5mvT)
z4Rz|Y6(b{CgWroC6=*AXRr0e_tCgE$Q2;)ukE6}6f}@Go4BimKK+PWd=byF7OoC%&
zME|jNyp0QJj=<2UWbLW`uCJheV3)MrV4eLP-v|A*uCIDvV{#9<hcqc46g!x#lzh7X
z&;mh~@*dXe9jRa$J)U5Z{xHHX$5IaED9oX+6Bb9>TbB?0au7S{Ox)@Nhz3!``a`0U
zl!;dl>EC#GH-}1D>?9P7HY at -M9<rRo^L2I(iRYvcYNuL#3HU}9Ey-xhu at tpZzaS5h
zS-4dZoGqkDUwLll3E5Q19Z|6w*<c-Jr0Ev7`OutoeV|07+aK?p%DVgSWbLUv^~EYk
z4*{~IUK1i!z-QrTQ__WR*!sojCTJfdHECK2 at UR7PXhx6dpCr{&R{F1vA8)heLc2(*
zuYHQRuCn>{9`bQX7gay0f;9I_1`1b>IP?->hg3)Kf%<Z{_dlc+hS#O02Fs(kn8D#k
zL;KfkuI?MQr=Ux2J6d22_#Oqy1^HOobxpP<BJMtCf3DA at RU!G{VL=nbhplp7^wX2>
zWV2tyJ=U7+e2!d?TM}YJC!?CeCSG**78o4NcUDfGr;oorw-@*n at p~}SenF^>fy&0O
zo{FWbawck{yNES>^W@&4Q2j6Rm=U{UZ@;KLg(8NB&v5nvoF6Hf*Tm|-JtotNq}s3Y
zqUpBQyY=~&i6-&)U%xI!b#g<5D-sVJoXm1+?>~6m$VlZ at xX=3LXdym6-q7g*wz-(i
z^WYEcB3c(xo(a$A?PF?#l|*;lez1REKf=SsMYB7CF-7VHD;bx3O{v0^zJ!*sV#=<U
zICb>32u+KT at 0PCx9|;Ojr&d23k*dE+I-|667_$`RwdCVR?d<LCG3Z2e$!_{|eR234
z>m{Rlj)g at uMvgOV`9<V*DXF~Al5qFi93L6y_{i8>s$ubLK`|!$EXXg;%fzLb74pev
z4l-sF(=B2_CMn^^Oe7w)qahnIl-=`!{|%?V!1nLc at Z3D_AsWv~n!^SGpbW^FI1Jh$
zu>d4|{e%0FSlbT9fwx)2K6ZA6os8UjKLCM(a##PEi2OTC;m`YnAgg6^$(RtStTt*K
zBI3&^CB5C4bb^<<0sv#T(>Ot4itpe95j5V5-Y?Jl`@A|H<-q0Wo>46%-K}`I{TpVs
zlCCYYOe*<V-!`Ab)2pl`aw~)2>BXcNx7?tx_9*EdrDumObr;;EyF^|YEMhb8dMAT9
zInKW^8pV3?Q~BG?_982wUc{kWgG<41_8=r??E!`7XNk4y*VDws3T~PYdUV1OT0tXh
z3Evw?&cmr=D9l<TgCBuMDSNsu8E;J;)T4b?P-rf7E390PGoM&7vW6%FeMb9Cs6vCn
z?nwnJ#Yx7|pAND?Z|o;#IB^icvL_`a9U=(ZU8jwRE2o)`(3bvulqgjTYzG{DGE4eh
zzqbDATksQXY*0Fdos;zqE`_ at m5%PL6;giJQKxSoj+Y(xh&DM<5SVTyy;Enh4q~505
zo5J5L_V{9IalPybDL_J(mjmAW9g at p+Cmiflk*-~`F3-PHBqY#Bk82!bb5T=hR9T at I
z4O71P<%xe`wxy29ntjK56$Q@?o})WB<q`Ok6T8?S_i0RRBFI&;x;}X2p!s3;k?drh
z`n;eudx2izN9>Cdlw`EJv*CW_tUBKt`+oCpgxfk-c-w3~`2`t$5yHZ^#@Cf&D5_9R
zzIfj8!LEWJTawc|OACAtB16?b*Pp%4F&8l9U2B!c-p07iMn-Y;LxWb|Z-p2FTRw-6
z$dvK<0C1%TGCBLqDBZNQglLT~)Bbj`l;M+B=wQqtk(;HoGZa3 at y=U>_+-C6)S^Wc+
zcNyxhv`-VKMEz;d|CM%4@~DYT$DV7p4JH5FhkE<B_kds5xwJg7SUaQe7^_;?Lvc&;
zXW1%Ip_I_l^_Bc>HmXnPx<Th)IP*p{&51?wC#oBU-v3(*kS-*dS}Fu=J>CWO8PKwM
zpWGfUgt#dZsR9cwMhUba3AOI=v-zc`YIwvEN};hFZ1M!w*Ko%{po&|d$<fDb5*iq1
zlSP~qUrF&eP>2b1(1*V7aXZpvKk<t^9m#c)ec at vRE&rZQ>zc^2z!<ZSCcH<{f9f?|
zgzTp0%YaVc678SDKJCBG=w6FI;y$@F at JaQ4BXB*6_#*|?<-m7W2D~C;W^h!7q^?&M
zT3O?cL at lXLxAhO{A5%Xgt1EkCtbRTJB*pf1UTXVc2P^Ra+Jf*tsM9;KvXQD`Kp;3Q
z?)&8W0I{B4*-O=5aBUVQVT8|(>qj{AR$5q`#Sp!nClfw5H<zkFO7+d5_{kgAuRRbJ
zQQku@=k&ygpOvZM<jy9R=-aS_^Ah2)i?q$bU$O}F<LB=^G9tQ!k&~LlS~foLACH-0
z&ZY_?BI5Pkzsp<O&(ofL{Ly9svQ>p!y?#FOCM!4rDQA0aSW1z9Xo<;%fi*yCjiF2N
z+so?Wy^i;9Z^+IQXa8QAh~d4Dk{h{96jBamW&30l+ at kR4#UHN|`zK_@#eKA&_TCGk
z0ZD)X{3ZPmDTnNFZ54K;d6K<2)U3OWOe|nbduUSZcJ#(mvu<=oo%q#kOb4S!k$kdc
zI8ltG+U(2r34(Ha2R<B76cF`+L`EH^z;vGm3NyvuwNW|+cvY}=$#=OQ_;i4N!BKFj
zk^n%HVo$0MB-7jaZQVw>G&~vkv{IMhVyeQjn_-&;91{@_Y%9sz)#oWyMM4@$JUg_O
zKq_nw<y_PPqP3i1p%QPl4?9_jQ%MAG&=_RT&ya7MnKSHAtoZ=MZ8D{V#Pd6AuPu3+
zh>lKLqENf6c#yp%Cu;I>tS*m_1iz-F=+ at q#cLsyit~JZBc}V(`1B++|YC7-56_FA8
z{tXtito%=P@?0_rS3cS$n?l_iJg}k0zEc-p at d;fIg#As<z2s7wq#x=#;z*KPQ>n5+
zBnF=&;ZYV*!L}C){?-QrRfU}3tQ^VVxBXu}aC~)l?}a07JhzG9+`rGNXjy)3zV%_L
zoyz%8PmHyLFO%|sP^bhElSaG)+|R)mu0I|G at _v5(`TLvOG!J*rlInXnY(*b6-gj%r
zQ!)*YGTh6Va_YiZlri;pHJT@%#nSlx`C$`9sjFgfQ+aKUpD^f61(Xwf>|P5p;am9y
zWsXv(qAIkMP>m0U&(A5UgoV~~8`I*xl{M2qPP(l_N-Su&dZYSe&8#jPF!!>THZ>@H
zg1%?<YbD=u1V9)?8px*5VA&!!*6wB&MbrU>lXJr|aSwK-&D^-PKCd5CMI6;ARqRU(
zg4 at YuWE56vg`(1{>k=1~%&-_GO^chTdg7 at ENt!%2BPVBq at Kc1&`-Q?RcjjrxBHf<I
zv(cWIv&SJ{HYy)LQG%gqFVeIj at _wOG=f;2o2 at Bo8C2CX{&!Tm}k>fvT8bTWAO?GZA
zbugAZ=<-|lvFQXM9s?VX at nma$LVLfmSO?z0CG72Ohg{nbfX+MUte`rArKNLGFnY&L
zde4P8`z4SS^dyH47B)F6xXBCJNv|nJ?E&A#H=>xwYw?XZO^18<y=5$V7Dyw`aGC)^
zd%YrZ=L})a!#@{kdp-uL*b6E5K&5MIe?yO%*20s at ir#8V9$XuF#r`Dln~dxE`tH%E
zX{)hgAEnWZgipat67Hbt0?-{IO9H+iy!qqQ$8h>!VO|cQ5&8%1-vvBBJ=skRXTWh)
zydqa=k>~$;SESmxFwrO>O`GXP3(ftSrG0&xj_-FnZ<%vS!u&1AKACmHkM%D;|15#{
zbw20ajJij{_`T>QUnbJd*s3I3k7bA_21{d6*Bw|bz=3N73B!FS{3FfX<Vg~p9u~f;
zsJ7;oP>v*`(7Taod%N at 2Ti3UCw<EfjB}~Lm`s_jSZ{{Bs=9(<}=L)DjzX#rwX6c3I
zoA*mpQ_}W>t7PH{ffV$kLC4&hNm?jxZlfEbp9jl03c_uN&lup>H$JUPuph!TdnTKn
zU8X@%LqjVa``6gEQ1h=~Y;3s^XWuB9b)CY-|J4jk@}t_%AJFRvE9$dK#8=tG@@YBV
ze%?!$VX`9efa<f~BeeLFRo>60CZnj=H=}&rZrn!DihlPZ8X2}OCz0s~07Ctb$Nub|
ziA at Aco1U<?#mvos)*U`w%W%f!rml1y at ldYG1P89!m*pn_#U8I=-TvJO26h*vb;m3L
zom9YL#mDNB!iCt~dEg`@%3hMUNm*71h1353Xu7JPwz at 4`q(EDw6qi7O;toNB7K%H;
z-L<%DDO%j!-QC??gG+GtqQ!6ihkKqglbLh&?6uZs%MLk(8FuK<zeLqhl;)$t&;>DY
z2q>8v$3B>-9d at gj%MiFmhr(DQ{hJJZ5B4=o`rRLEJ%_F^(rLMmhOtDg)3(-VsX7*0
zaR=Qno~gaNj(j_E>8<#at2M6QH=`Y}o%rc{N$pc-v9&Gx%oBDIIf0g(-L{#NAr^iM
zV-m!Dv!yH30*0iF9n*-2CX at ifK3?Aim5~3M9rj!$a?+_V|3o&6FE?)NJZv6G<@&=3
zls|{=W#7qXe~DXb#irpYK^>c=7#(Ghsg0b&A=H!s-y2Ag7|BHM2$S at DIe^8W*<Z76
z&`~jpBe1&UMBpf)<StA9+Wfje8CAdz!vLS<RP)IAL#9TLsW24=YV_-w6Va#zq1jP?
zVrq&)hWsZQ4Zj6mP)m@#kMvrv9IUPpC12cuNx*59VAIn%ADR|P^<S1hWUuNOrDaJt
zB2dnFjgN5&UMSdxlFNr=MK#zIs4|%aO;PXs=aHcA;=z?nt;+d1HNm0xG$k=}lzc2l
z&O051sBV+i&Ha@(;|(F0E~>YGkc|0G+xN}AK5Ng!bcc}Midqv1VX)jL3(Gob_xI1L
zM^mYu=CDE%#Cr}3 at z{>(kIjEm!*^G9qK at B&{&_2Wm|i8kCM+&G%4SgyGch$1O-z9K
zV1v3-`R*!%hVtPt-^G$!{}StC-bTN8FF;R$#X!>kj7k+^8wfJwx?WlhIB4=MoD7TC
z+;10M>oFJ2M;#E*)fKniBrbDtKn(#Ix}PMcPbuw$Bf`MV&p>5C`-<2*$y74O1e7HL
zfDsdA$15xOXb700MLy3S)>B<m-Z_Le`~PFZH4AO-i;M^Xk?VxVgiBBu)sK4q!ft at w
zJYlW<9K#K=2fP<)l)EWu_)|W2sK>nkFF||cGD0i_r>)2(=FkCxWCYjmSp+VErj^Ke
z=JnmVUyKBVZge55QnrCrMsh`@zcZ!izMzw|q|1;S6^C+Mc)y+Qo^Ald_O>oQ<5$?(
zyc1{kx^&z=GT0RsW;u!Y>G6wyIKO3CdYn#0hPbFU(kWNn0mhCss2ENb)!dFB2Jx$(
zBFf1R!}y)DVG6s#p`yi;hS02d&e;M(9z74c!<LW&_7A=4?v}75 at JhP)C)(*%?6yot
zz(eY*_9>6Bkj!OwsChWbG=i<|hq3xE{hveF54uOg-czctPY1iB!qw5{46U!nE&<ua
zc9*zgDOn^Pvn%ycQr at jj$%dvUl<-^15EhbkTT(K-pIn2VEjqNjeB(49mfjbj+BCRj
zTzEV1luR-3{p2FJkAKOc-yldx%_o{dKM*Pd>`XSE at GqtB3Y~XIo;&K0jnXd{#qDsJ
z3(oiF_816o{w=p3)6e&v&^Q0C8pyLq+e1jd!!s4Sf#*q%iHOBOu)AbYQ(q4(;?e*I
z at W^u}qK+>QM|wHKV+vC6|7B?3Jb`8BPt2$u^_cFBFC{~GS9lkFjm|$?7%;$pA7w-X
zo<Nwg`=yj>;HW7+FkA^?v^dv%qE1J3jlRPvEBWH8 at P_F+%|dmqZxeLndrAoj1W6E`
zSZ>3_XxTZ9IOpn`n!Lh`{Tvoh9D8KP1a<8{gBmcZ1yf>8I30^<^@}UF{Opd*OI>U0
z%Ii<q64H6+yA at 9~WiI=(rC(089)xB<J9VmLB<iVmygC-Z+HGwHu*jP5UBKcgY=xgT
zCjH3|F`JaAFZRI);m!UBKh$gttVg9``nKJcNJW^y&br(qU3+T*>C+qTED#2_+M`-z
z=igqfU3Dz?n0kLMYf!YUGw*|mrHi>=gzn;5%mPP7JMCRWquLEUw2UBp(j9Ee<L`pj
zzo at c@==d5PiP>sWOF|yQZhMV5Fi1zk<+w3B>B&;FBES_(w>*ib5hQp2HO-v(7Ovr9
ztRoo>L*8A8&${LR$vDJ{4 at P(TA>lPn)bya3SP3cR)7<ghf9guiiTaUb?yAW-Nm-dB
z5KPqGl6b>eiKN0C_85`LLa>a$J{gH4f%<rE8L7YT{R{WVLfX<V0gpt~*TWS3pT1)6
z4Cg65X+DT)Y)6x at dVmZk+&Qaq7n2LpTU?9+dOW8`?hp^luXen}R&aV+7MU!vz at wS;
zB+oKe2OeMb*6yYAVx~k2h#c?mQ=?uA41ar^j?1i2IyN3U=?C&xiV!Zoq7!8zy4*-y
zIjc5>MliJaXxM#)ptQSq3A+4CR_eL!F(ZeP|28M>t_k4IOGBi}SNqqgF2)1#Hl)xe
z9AdEUasCdFvop$D(r4R8`CRRa^K at y2L?AQSSeb7y+;ZbR>nFjBc2Ce_rpDeOkz-2o
zrHWt?m?1LrH8hCJ!sU7L&@Ko4s*@7maORyV-x~UP$oqg~qITE;!^C>hk8xQH6fvyj
z at 0iTT8`_446-k{yYI5f!pi*W}egTZrX0Ya~=`}BpG~d}YZtmOJVhw4g*k<RgH^kD~
zM<Z~x%YZ=+JFzjEiT|iwLMT&=qIeRUH<-?|?K@!AvJ!@p0@*nG0ONt at bjyH}m;XMb
zRaUb<ruufII{!4jJ*c^F3Pv|J`x;UTiVa494E>7Se9{$CQ=T<~R$C<TL!FcPTr4Aj
zmH3$^_(^-bDgIv)iWoUO6%O~pype}}@B3 at RN#iahEJ8EnGz@;LFyQxu at VU`7t0VDp
zx*Pk5?xMu$4cmF&tPPrK$hdtIPf7 at uurT~hWR(;rKRSRzU(;{X%o-qFmNoZFqK7=2
z%EWI^Ns>O-Z<yz=m$*JQJ>vj8@~)g#$_#xsAMt+d=YCOyNMtja&-KE`V&Rx9gX_XF
z+s^g0oZd!R<Q{sG1tIHdoc}0pgV7O51lE{iPR6{j=~-}lzHTI)1W1nLYY#Y7vMMfT
z|K5}5qOY0Y3rTJgEj8XfWrH8^48!Tjox!{<ieOH%GtERil0eiubrrT$oJ(S54iw|_
zq#A%gX6kU-qFpI<u1NBPO at i@+dH8SUUUVIiD(=1xDK(!;&n6fX_K;l*9>PVfE2t`-
z<UT|*0pb)i?3t)K<4TA2OUj$ELB)>Y?U@#zr~jE?1H~dL#yT3?e%Y!i%T{io+%)TQ
zA9N-jIpl{<yMHE<gBVSfTCK^)ko;(+yS^p=!31e0L4|1xKsnH_k?u4zG*R>E!wi35
z7eG at 90t^;4iGLSYh2`2`I0`IO&&)*Eh8UML9pS at jSdH74i<BvtYF1rptu-{#=3IHd
zIwp3{8 at H?&)?jfu+K7tBDZ at 2)8ZyCn$4DoB{59eI2^Tx$Sy~t(dTp2*Leb_DG}PW7
z0+I;!;<iK1P+c7W=<x0ZK*q}*MAw;4a at d{5X^^SOR1b6Djcm}Y3THtha`~uxb$1ON
zMu_bU!ox}qGekp(VhAnjBQUu_S5$oHp^5=YRat8so<2i`1dGg+p|#NHH-jscl(-&9
zFpz~n>6=1PATgFq3%+|c8{Fzg*2GKWNcd~E;?Fx|gghIF>N+#b at aSq7hOwDLw3V!r
zAmQpo<PGsYE+v%K)Bu9=L00NFXpR$!8=tWeB?gI4jUr{)eoU+R at w<b-ElpDJDMfdH
zexz$TI(8dbogXQNoD!AM$cEb{M52Jge{^Cq-rZunEd(0}9-a5SA^gws(*CE=`D8<q
zcVqny=!OZb9(jfqCdXJVX)rye;|zi-Mcx)(NmtDq#yy%dJz5gJI~mt1Z`8;@xW4;K
z?Kf&ah21HbB4)YhuZa|@b3oR{JAcPPhYA^{gPx7~&ruz at hN2NB5<H2ST;hhr6I4)k
z!e&Gbod-0A^3N1>&za`c1FzURDwqTlksk(i+;hT{>%QR8JFqf`;6xj;ODX9ds$Z^o
zRC at ocJV|E8j>uOJN(28mcGyO*1VM&j)x#O>s0Y?%JBqLM^xwf4KDE9cbp`+Cyf8Vb
z%~A8k5j$i!qkh0-N=S3x6Z8I3zbeK!Aau`vSwDHIyX6FSgd}bH0Xj<sumS%I9&O7^
zkI<U1xQ6ws_4p=D#Sq&zIxf?8GNx<vBt9But;tf~jAI{c;~!u_1eUWaVx+9e+iOUK
z4nr1V+w72sXtvP}$qp+2ddj_bt&ZLL0A!yP_R2$#t7H4r5yUVv^tg=}rd`a}?p1fQ
zJ-}4T$M=Dc=g&B+J`Sbh3xSO>V$g?Z^sE6%a^IM+l#IM1KjV1+Fcz0l=RYDIT81K&
z9z at A`-Gi~=?^s(_KMl=cQ2iYYrMk(F#*&Q2;&0w{7|J(ORr=d8yNboXL99icQBxJ&
zhV9vjqPbK*VZ=`or4{-PO{oeHJd$EG5ZMpz#?+48nHv0^&*Hvj#N~)fyty?(CtAZw
zipG~%6w#e98WQx!YR+ at by&2 at O=e%>fwD%{>{ZqIPOV;Ql8id1eo>=WM*Pa+_->86#
z^dk(qtstjb<PkH~7#RLF{peqiipJMW+J3KbG`x75T%#u=LsM{{s2^=4>%I3k1R1l#
zvk)3>D;tWF$HW?H!;hbqP|HAvHOCXI`^mpYzY>wX;|%y^>Fp2Fw|lOqQ1$zoQj_pR
z_ty%nWv`^E&3k+K)N9#LcIl|0b+npN!ZI2d^6Qa<VW(_s7%SK@&l;L?(4wlUy8j4q
zf(v63iH*!v_ep-7xfZ8-7oitLi58;n<R`~`Q8aA5`G6}eJ&PsH+%mLyAUe(-I<g9r
z0xYeiM53OQqQI1Q`aie`Cm7JIUq%I#@_GL9!I1W6*Ddt@#vi3gNBMl966F8rzMqi5
z4 at hm~uH%k|>uO1HQ4v)cv%Nfj&_<5h^W-8E?Ak()F12%a{=`t?S>}qQnyK+&z|03s
zm=qU$dJ+-!==yMsL>-muqlZfUfEokKd{@ZBc>C9FbkIk93p3-S$sw3d^=|06GLjqf
z<nw>B2gAViBPWmVI3iW7Vht}|<w^wh;^Q%NV-D-d263Vgis4Vz7_Frc^Pd&B4sPEU
z78W==fs1zB$)EnrY*PjHfAqsKMxk*>8G78eF+J?j(bAeVXH$%UWvqI_)&?U!3g4)5
zMu1iBDl6Vd=(%RJ at Ic>(@|8JVN>4QR%IA((B>J|5+?gg!3nEGQVS8|63hR!LE@|e2
zhirg^RzHCdYu<U-G-p+ at SXgUq9g?g*7&!!EfZShnxx;bYdLVi1_^3{&OUFq1#}?BU
z7QoD68_WMfRO?bah&Iejh68viGiKagQfg%^k2OE;ebAVp@;FRk8Bto0QI8V)Iwm!%
zd~o~2Xx^mks3vm0(J*B+Iat`lAd@{Wrk#`4 at ia*YA$pTfjMK0SrP7x032a!?8rOrG
zl at u(chM##a;{o5{r;~7j+KI~2VvA4k^)QN(0hVs8YZ=8Fk%}^>jyduxqcvjiQ^y<w
zlCYW7E^yW^$3P^yH^6(+Qw>2?RXlW^ma{E<e#MYLmlMUfKE%Z2$QxR&iRVdL4dy&T
zU?^Bl5XAJXXE`2h=Y^*{=HdlQyx;d+`W)qTs$QBhC}!O#*)dFG$nbBA--L-TOo63$
zV3cnyk72imL-w-QF$ibfZ7Tm*Blrt&W at ZRQU@Wb6h3I1JUeZG$-$6`B5`jkm>$+ul
zLErc5Ie>FMqNT;jlpxz(4<>?0u9NB>5coFNR1-^nv|-&M<nIUOhr}Pg+kBAt3X}9_
z*O`Hu{imcG;fBa at JwjEW_#aGtwn|{&f__X#{~>Uv)4~5IZ<L0$pJJ{$PIyalO_pZ<
zmg_B6zCQ=#9}Kp4!vE}gNo=<K6t at +r4xbt5NPeD;)q_68)G^@QCuQ3YU^v92|Lbwq
zue}Vz%<>!l`l#3cI;pgh9fDkhBRTkPz!viyvvwK4ra|vKKV*6Wm_wCe%K2sEwW0E1
zP1f?As-_iJoCm0K&Pw-wenmsg(ZK$Wti~|XTkG`9umLX--uS at 4rXA*G&5U&3L4Fll
zBt1I$!2Iu{_g-CQabfDD#ulbIK)@~Qy!Fgf_BiKG_Z6Fet9_v5Ui~P}p&KDfDw>R+
zxzfnWs`Y;5{$%Irlg{mF)wD8`&O!&5w-^`HCHUNTv$#;D;uT_}^ALV;)FR&|^TIHj
zgW!6yg3+PZ1c*UB3R at QfO|^-t`3{6R4P^dEQ22d=)E^{eoqWjhwZr7 at l*RarhsWV2
z<h=bg?{U}6R+Y0|h}mbNtikJ24(c`w&|IpKPvUzxYPGXVcab2}MYKddZ`B}uxYRqc
zyZhF0?5tOyBMWnZqQfO6RPhtStYsCz0Z{>X8V}hKM(QLE2*wAuWX~Q;Ah^4nP~_bh
ziVk9VXQm_Kp at G4&8N5^_J3Y0SDLIs3pJ&{(uCeGd#_`g1K<2!}R+t>Jssj6xK6c<}
z;MPWRwuBD{THsPx5cYWGvF2$sF;V9a*fKbP+iCjTn3N-5F at L8I>CvYc4{VB}n9zZj
z!>e(a_4_}s0^E0IyVK%{QlUb&TGylqzI7ss at 8zlz)WWA9us{>+_8f`ACIi%WAN4u-
zAn47($%6gg<_>#Iz{#-Ep!=a)(!vO*b?GSMUEqM6;W{qGw>5E~6oEl_px|>xzQEOG
z)WG*vx?Wb&psy)BNT<jKI)(truRWcHNQX|uHRObzve9xRpMqFwk`k(O4aTQpTDK4W
zGa2YnpN9n50lU?)X>eC^{)(*`Xky$K4y_`gm*skBx4$lNja&J}_^N^;%8`$`lx~)U
z()fQo--m#f-X-o$|KV2;pk!mWmH at +vM3WD`m;r=&u?1l*X7WXEZF at f*D+~<<opAit
zylXOS?K20aN-s4rWjp?U65#!lYjCvdCa&!@@t+HTsXtFZ-is6lC*xWg2(}OR8r*PY
zaygm*eZJu_O2<R{sQQ*CM}B_UGK_LjvW<RR*(`6=smUiok-#s8q!r2?L6Debk{n%t
zoP>+(w0p;VyhHj_OlLwDni)!-1h(SLC at GPSz_sewoo8Oi&MXbuHee2Ih!~FK`Z#9j
zQO9b1ac?&>Nj)wZVF~#6Tyzto#U4TW1k`z%lU4znq;cavB>k6##qSg)@S1c1ac&}>
z-FrKvzVY_-C_O1>ytXotn5;~2n+5&^j@};|_rUz8^AS|RHq%e*_n6)_OJ&qvw_LPS
z=*N*5ubu1Ovl4sOrBw8Dq^P$e@?M%xT}PlBj4Gessg|W}0{65!b%M(4G8~Krxr>YX
zmy+Jk%C1Lx?GLNB$)<%~MmtZ-Udaj%8gS8VBk%XkU}-SoQ6xX#&P7ZdHkrI1m9wTT
zuhn%Puhb6zJ_%O5y<}oo%%R at KUOd`+za)g6?eBSMK0N5FFLx;KJY6h^3phqlsqsm_
zJ^%2`Zx_V-YiL5CDzgJ0m2qqYFTjOjL8Utd9xdk+i7FLl!cc~{Bx(Zdo+_-X at Pv^4
zq^c927W?=OjSDg%QMV;5_SzuQnr|B2wU+Q{pp;DD+Y(Cj4YjJ^7RONwS+s$>yhl&6
zaxazNxK at a+imGmSAgJ7|nB6TTTEN06FyfyK@})4LC-sc7sO^_9QaALq_HbTmu{6GO
zpiHu-u%+o~p$&$fiV7@|EaloIR!qc$DUYc9<1W8YDdO0eM`cP at w|(eKxCC5*a^MWS
zOT8|PlND}^pyssWEWQ)CPBlf)6613dV!to~5;i2HExAR4Kkc(j`wx?tj~f~7(c{Kv
z8}*v0sdW(xQai%^do3+pnY_uws5B$=*F^vxsw)Iy3prfyEMS8FIZpwu1Gqc$#Zo<n
zIyLe=2au{e(do}>+)1S`*)0j3mBJ$(<X7<xYCigN at alwk8_pmR(T6(`4J#(a?33Iw
z3{A}mTu>-KSM)6*Gwd7HthrjB5`AL*9Pco04irD;$_s6`J)tAQ93RV_5jyyCOYnqi
zqOo9DtX{e}iCu_RZHFSQ0}Bh|B_1OM5%xBc_5;EfSW5w*d3Ha+yFX;-mp&%o23U{2
zKm at 4ExB6mR{a&~q(C(`0W!#?@Sk)TN!F#K|-3F5#kc5K{qxF3(@~y;n1`1LLGR`!s
zYAzt at tXTAhOP&Too5)$=LmrQ6UEnD1*DxSq#qou}UD4xVk&R*szpm}S7~A>xd+Jv6
z3KQP0M~w{}D$W&Kc8b!l9E&#Bs?lXIO#T5Y1NUWz7%Dd&u#~`fJbuQiQ*fsA&U_xB
zys4(P?#z2U-QodVdDt1A?|HhIbyKzE)>eRm>55K(Mc0#E3iM;rv8kLM at f;BgViXY=
z(5e~pTn{5*hN^P&i*@hOIdkXR<VXNd?qB1=BkRJvduYzflep%xcV=otZ1_+l$%1)1
zdI&CVQoZfQ!%CZ3QX~mau2I>L)9ImN#L&qiY;0SpF)F&t at a+Vvr6ypVz3oyvJ>}1>
z)4yiw+CBV!jH5hLUnwy2I^#N;XLfHqe#x4)eLDs@%^r6=ZUzgM;R){ir86sFGg0E0
zsjPyzVlUKA=fv0VgCEPRZ0C<VNEh_hZWtdM=^X*wUh2W<0@*X><zgp6bEA<N|2eaf
zUT#+oFxGstV2OsDxN?;Mkn2(V^_1Ge9IwN_Xmk?p>^(r6(`z7}C2z*@@Rq-(4&dnd
z6BF2$dub`Yg-tTA57~Klm{rz{UA9c at 9_n6puDx8cr}I?rarx_<HDu=hT7XDmfp(wd
zg_GcyN~mZ3Mf>%_;zH!7oAM&vLix3JJ+96t=*pYPMnT682kqFw_vO>miJ(Fm65}&Z
zar)-J1S=+eB1s*lDEz9|$5N=qO2%r<8#8c0?G`dDwET&N#>+$M1Ak1Mj7ZQh#QfQb
zJOqf1j2K)t3#f;KJD#){n3#?aXY#0b!}?dAYUWBDagx2P-$|k~5z*D=#=xaxSat=E
z>>_y}QRV|44`3$wMn|ztSk}@il9ToK!F)aOP?P|-u9 at qBzd(u5f*mx6WIbV~hO9LA
zUksj;4_wLjt}85NSs#7X(me^qPWwbWvZmf~`Z#_Y`I=6`s}#{3EO~aEi!@l93A{-@
zQCMt%jXIiu&-6r)GRd8RUx9nRKc8#DS at Ue1SgM2l?^!!?V7I*^5{=`%`p+>Be-pzL
zR|A$FrknPl#Yxx#*Z(ZAi8CCxOYefO`<`JTklF11QzR7DyEn>BHPxsf&pL3saFnBs
z<a<Nm;L1|Jam?G)!o1)Qqcd at 19K*x38TvK(_4j%Vcw at sDi?k6E`w%x`!@e&32IrCU
zTpCR}oJDwH=KGu>7nld*Y;pTmMkEr+bv#3#TrdnjI<VUdcu^s7VqoENf;35*mcL3n
zp!x}E8`kke1h}tzS88QFWjUuiH}`-j%ynmLEQ!$=Pmn;><zcY$d0?2(0DD at Vb;LMA
z2tq)|t(koQk|-FHvbPE&KP-x1Mk+Io41XQUY)P#=^vf<-g4B0+uYGilA<ZF}<N3}y
z^oJy$AnaGd at 3$k9SA>n6%lLLlI%tWLm*7^`k6{T4{CK+ML)vW9ehBx+oy-jMR+bzc
zI68lKsVz2U-m*IG(W{;-D?1jCAUv_AKnht$lQn+M8dlCif+huP-T>V1XwgV5?Ob!8
z+$G^h&~{@HnMORxl0LKOBiIuYhacfrv$EPWN3Obg%$tkx$`*C{N}P-zSib<-<?QT!
zPhMZ at djiF~u3pYBRy?aZ7V2GWI^>)5?nPd97uxEbbIS`qYIe9}FnLTC at VY`3EgQ>P
zk1pP17OhF=Mh?;|*Y-V~FD6 at qR5OY{F$*Z~fqb%w&X at 92PL(P=2c>U8RlM>oUaBCQ
zW~r=)9)2a8lt at 8~7S471s>0RxfSPmdmz64hy|Uoq9A=YRf}d|&2RF;4HmViNN=;D3
zR$w94lv}Cp)$g!|c7^$*w~LMA$a4p at edPKxE7Dm|*W7ffS(mP at _oPOtO`Eh}$Eyd_
z<KBM-rqoOznt?6$uGRgwE$t+#xYD*m2K{$t<vi9w)KC?pq)Cetv~U>cdr6{GPnT!v
z9(=yUk|WnvmT<uLLwZgTqy<r4e-!3tWaKbCUYXY}D$3$0z1>(XIKK&xm!glGC<eJ=
zr9jv!)a%5GGCY3UXmu%ip6ICDsc@*oP&Eo>XF>l_K%JgCRs=K@={d4FhB7M61nygS
zPXbg{y3Eqf|E<qIZZY0lsI`ze7o2W7WISzeOn=IBYA>WBT~HHzWrecU$W*=P`Br{P
zG;_KDEFOjWzDC}0k`y(0Z(}5!xOjq_j_<OLu9$ta_MWRDsWWI<FYMk%9%4~%FHy&f
zYNwEhjds|a(ID(;)+!}EnxuN9(RI6V^E)o71bS-zU~k0{+osYs>UvClpK#lb<sfC|
z(6P|Wh3uC>OO&2wPgwz`yB+a|x!~w--Dct*zi&hwS`x2bA_fTvK|}ZLNK5R%5(Y#~
zniY5boW<|@-r>o<mjs2iyP(61$yK%m+W$%e;y{Si6Rr#lgf6V|wg`~HX#aB6-mCbz
zMYPLPWutrKCsfl7f21f=LeDR>eQ1RxRbB{@>2F3;Vo6+0=A|m%Y=qQFI#HVzjRxm$
zWYAaHbA}z814*coQi2iSFrf1k^UN*<sM*hQ>XICvBP`8g9EP`iAnOtac5FSPof{am
zB1rCvNC|&PExyZ;e^^^SqMiub|0$=$V=dD_=2C<T=0Udjwa0Ph%ZZ=o)wS_q0xeIw
zZs1!o_LFCOp>%=Lg=@_D$TC(bO3atx$#;JIaA=f<FCYzqhOOExv at qgAT}75**5GXv
zZE51&13pAw!HGM=CSG_+-mp5)iT>DMi8q2nf|XjX1s~pZAV0V32;XTK+Z}lmy;yif
zby6W{4V6of=JHY_SJ2Y+KRJHy?vJV`JI7T1{VbOYSCB;-Jmt*~HVYfkO;3pk3`$8!
z>HIc-(76L=h6_kq;@|c#wl-oT!1)?yE%F==h$2T at dCLHNsXF4;J9izFbG^YN$4P!4
z;tz8$7m%OZ&HUO=dA(@Ib1 at 1B85;a9$7kdDw-yeP=(}~D^-2v4?dt*9>(x5$sPFU=
zx5Y>fws>cx4F5D+jiMtvy3xj|-P;<C&#xquwRn4lwqCa_9<HQul{P;DJ8s;~XzDI>
zz3*4jZszGhgaFUHNMadUE&RD at 1=X}g`9oSf-Q1a{&MGY~zVZvb4&gwf%$!fmd{RxX
zyQURy>w-rhJU*2v;xn3r2 at 5-Yg$S^8$xPkNaTA|xllPf)>w{m`aoL7Oj+)L at KLUXR
zZ^d_kB1rAf(KB9p(Y*AP<wBA3Tg2kwAW>IARR#Z#uG^cun{YkPKvN%>lW<LO_SmfR
zN0+OV;#rIeY_rA7Ntbp3sm=NEoFns$V-(SBzX;b6vfy*2092z;&}|})qh-$p>NO;W
z#`jn0<qj)KwNZJoG9pc7eA1?VWtZu!M5bhx03ulwDRo>5JujY3dG8SSRHU+T|LeTj
zObTivN1f?YF7*(8=h9ji1x!%#^k{0dwXhgV{8`GSX~{X{v~4dvSNwBMXQM-GquskL
zk;E}b_paCZSZ=N2!e_ at +=OLj!vGZtNv-VByW%IF3MR4D#W7|Z2;mS*V at 6TB&W6DJC
zY)bhRf<GN at 7~!z#yybkt$S#nDrC7;DA;sptdpZ)L>9dCAJmPr1m>}3L9$}*^?=i4?
zo3BD(qRKem>DgJ3wRV+VYo=Y!mF3y~(bCfJ8h0<$F|tjEmcL$8Jh66#a|Uwv)Kuy@
z`q#2)g<lgM?mY&hD*I{Tc&YbI`eqMS#OIRo9~4Y57}+w;50@(g14orLk2D$!Fq(!H
z;!qe8{EN%0Mf-e5!ZCX}Fp#^RnBGx9KUqNmg{*Xwd-L-tma$kUwu)D5yS;g|*k0kk
z_Lr$nfypD*KiP()J%JNMXafB5B7H!QayPWUnrnNZhTmd3KS!+O8pba&Vl<kgN<R|u
zEajI}=M8O4ETgwlJlPq~Cx=SNh-#Yv-`zR4)(tfb=GYQ#4j6b+X|4+*(v<(YHd~_n
z!%oA;QnIw~eX=C9X%*K;V=^A80sKjY7B4BKO)4`Dn{rrp7-%SWOM0=pk~---U0n*%
z6adN+Te)pK^iA3r`SXywuc2O_X_RYb^~0s2!B^yGefL`z2VZ^Ce;T!$E(RSJg{S2U
z4t^t}yZ at nS4_tOsI_<>>6V<il(|fkj4s`MBpGuC`ej{!J%DjGnPw8$o-(3>Ij9Eg9
z@*&B;ad63<F~6Y+m1}I*^NLtI$*-<OIkeKh8se!dmJuVcx`4~NmNCsx5N*XekR;GD
zJV^h|fVc`?HTo_;&x9xCy>X7MsGGv}z;}SZm`6sxNcM>xX`hcC9cBwb6|W{Wd;TX-
zf#SxpCLBs}Fdd;5YlkfUg=TOdg$|O8f$Unn6Bhu&%{BHsbC;bs8Sj55D?)ljJyJ!@
zk&`3}ZaS%y^~|>xJ6q9(I-YdV%~zJDjTCdV=wR4Fb2zB6=M&~E8l6w;^s at 1E?Q+i<
ze=hQ4Jc}lzz}C2My`&DhtXBdspatGqg$?#Y;cP|(lC-cL$DP1Jv-Zm`{65*GIY(N~
zPkXMGCnBpr6 at ONZwgT@sWjf+}dO|JVD3WH+tWkE^gft5r2gaXnc2P=r8M*UAS@{Km
z9dbmxKNBJabj;ElM3raRSKRNNAD0(euL6b7Htv4eK${dRR_bdJG|swqsD8 at p6mM;3
zvmKR>VyqWveN?H??GP*Cd-x9MqAPMKD-bIvH1!tKshB=CC{e5`n@{m3cq%GXS-<{O
z*>*(-<(yf#GMa)&XF5kBK_)a>)APZN*;f;Kb9x(zN^SEB{2fwB&vzHcC1WcqFVkYs
z8VjWoZLx_f8>sV`tWp`d37h5VdOoA)7_aHFQUS<<<NkDd%BD?398jZVCC at E;klC)v
zqa+`nn&zpr-5xxb5U=E8-m*a4CboQXp^}$2QyMo3!IB#;)~v9)zO06ngj*6Vo+S1p
zs#a+h#7(+|F7Vs at Q97!>dPt8anY%L7T!DhU-)ttF<iRjEDOZTZM~S%wYWzP};XtI_
zoFBYca6-gNW}h-}h)Ep&em3dtKSy<+P)tp$(79kn{#bh794fwSt`wg85e1nN3JAG@
zcWE!S+1}V8(<Z$_-!32gH(jY(=FQGJ<Jvt(jchSmD84L9<vin0K{y4=UL#4~gzM#j
zYn)FRul-`;K@$9(w!!)rZi&-5>Ob#l$k;DZt=&#>QfoeZ3fUlpaT(Dig4!>U8z#V{
zU9#bCSzr#*{rtw5FC)8AkY0u_q9W3Co)4Z!vptAQf}{gqxQV9%{GfPxO)XEaOp^`x
zUZ!<*^;-TV5;%W32!urIv;?sbWYJ$8D%e`KUsxo~7UMmmv9rzfWi^xGfII3yEUJuf
zNv8Mg+$TrJba3!(W!hDkG?0*(r-Tu6$TW9wO39iN%^Ic|t<lw4q)4nL at jN=Mg$%De
zVoK(Y32Xm`!HQmN7JeM60A8gLZg+bmDno}DkBnS_7+y+nP|#yH#mj?sv%WZm6l>Ze
zQN_1nCMm+$i=pjL&!C!jBm+vx_0heOA}Vhr8?Lb-a0gw*4kJ94N`=ohJVV$S2YChu
zQ&_GFXv}m at FuC4tjQ#H=GMB<(nN4@>9n|^vNBoDkhlr5(ytvWmfgp39%?+5AL70__
zGE)A0Iwf_;_0*;n)X$gXITa8+&xQHIfv-TDGuF6k%_Vx=Xa+tRN2BDVPfbsr?l)Fx
znNegU1*9hIXXG(Cx4y3+Ayt%uE<dE$h-bu5G&tCC+DlHrow}5j$>9;7&ix8qt{k1k
zDL at WNxR5$aA(#MSd}Gg0m2NnaeOxya%o*#vLx6U^lKot6Rl%D5S)feYV5Vs~IRYS6
z$IKvcx|ozHDU4S-E>>Ny>cGNEEo}sAHfkG5Ut2oY at xK1WJL;{AnuS>Zz*u(=>%3;x
zo5}Ls^gU+hvR0ysOU>|1 at n##%FIZa(Tdy;Va{1Y+wb5~v<uto*ffm89Tjjo*=6p4*
z-Ow<b(SagavX+g6{7I^)0Q^%5<a(wEN>FN5QLC6$l~O8GoZ0Oskv%P=?Xm`sB_-yA
z#RF>`Z$j}hOKQBtL8P5pTweDlk8?w>O1|y`x3F2Fc=lX^mbM^rr6REv8o81Y*@}#k
z-EorCdh7y<t at h((ESXg-o1YuqnVKy)$SR+)*1_2DOsjkvRCyc|d<hYF=s*U}CM(u0
zr)G3WPVpNk|JnbQ9MMyLC)&ql`*BJtT8nhvZ^=7{sRK^`rj<-Q>B}Et;~TP`$=_V9
zJ#a^?HhZ<Dm`Bol->x3KNKGo$8Sd`#5NhJE!|1-1OfBz5&wC;8Ah9(%c%PNyEB8dP
z#iNS}6ff8Aw|_yt%KK2J^|<e&e8v4J+wxsP+&PpXd41ber9$<IZe0$k1^18^tIVn#
zRlF;d29wyIiGD{wfqPhP296YIKVp_WpnD7%&@x`g{lnrU*;?5k<X*UdmVPZ7emBx2
z-Qcg|&HdnV0?msi4K@(=*m4ej4f$hH0!~${p$3fLh+H6$S~`tTO;f!OVylj4bnZRn
z*n88ZOL+WcnJ&4hdFy%o9HSDQTZFgam({crdz5JZZvD+BP;nBahF+2s-=&6P?DvQ<
z!&mO39fscrtiuqN5Ek=4Pyil5x#b8V{l}c<Pr|7Hd*q$AEb5B{X#NtE?UGHxK|2Hr
ze#HALa5x}RdbPQ!Z!5HHwL0Yoeea1v>7M2m74y1_n8kLdc$b_jl24O at zHc_<EGuO!
zv!076xRbc3-k_O5-9-}Sy*?!)+R+6NCy<8?Csp(?-nNT^u2GREyk7UBAeoqZhNWQQ
z!;kjLZ)=#oc=pI)k~7WmAF$1W$rDWtx3i)gt{Au-I{(~g?4Z-3eR2If1=C}qdz65W
zCmeWa?;Ue`3d{^))!8jdvf2MH-8Q;Qp2j=Va4OGVzoo8u*}=_Q at I|%nF#@%jilhnv
z*lGFO5PQb4y?PPG3hjICmvdXb9|)EuDrt~i;~xVvDy6E8Q^MQlr*>f>G0MoV1HSv+
z9KjW7?4CDutLG|zL*g5uUBb6cQh}6xgbceLdU2z>b5QRx8)$~2%`S at 0RVvqExzWeg
zmr{(AFu`)Vs^yeaC#nJ`OSvOc!=&R|VYFQbLfr>$#<TT&{*(mX3(Bg+x=Ft88LA at e
zd;BZx{KXVuvS%wZ(>u)G6_ctuZ7%0?k6Kl;Q8t=YCtVG?RlFDKXpFS9X;X9sv}ei3
z$MrKBQJH^a1!wO&Z+}7?N(yUsvWgEnZk7qtR<ik_ia64BNbb=1Ig5q*-RJugUjbY7
zjn?Pc#{*Jmg;v*<FGuJ8i^pB+yk_EvIXNZZHURHPmYH9=MNYZmF`nvvzQNc!@HhcV
zm-)!oakdst<#M*Lfb3IV<@;g^^*r&A6}bLGNQX|Fl&F+K at N=zRxrlgqzCTl^v_Yxk
zV1qwejW%JDCN9(S$5|wuC-vNUWLfl><!WYaWY^}R^Wy;8*-DEt#`<3o at 3+Ucn;qMY
z0yRCiT%=UlhE$xhDwljGv4<^I6OI$Ex at eiNWorWZDGK<g(QQ+ca`D&^?GCDpBkzlP
zvAKXPm2%wb6*|N5 at d<|LL&~xNH>|1@#fD<pqS5#`s_EhXSZp}c_$?LUdv+P#gDM&{
zWeb!nGS~SYCSL2*WpB4O9}<gYjO7|Ta at 4(ds>$8kk$k~o;Xs7OtO*M<j&!F)nh64x
zzGsrds_o;?I77MHnod7S2nmnN_ObLa(9uh^neHhA;#2k>O&qokBnSx$qT=#HjSNR@
zkoQ)1o&z at YoO&Xa`ewW!i}>ELhtwk3TW^C;IinG9el4d7QUzS1vO+tq;sTydm7JHG
z4T_T)PGlD#>MJJR&-#ymi16^6UjSjmvL>HO-C1CgW9<)jqu<&e*{h}GFXb<LDv9Zr
zwBIDJDPsn|e?&Qmh%Jsv&-q)&`p!`%kCx0HxlMmYkcKz;=`~|_kU;W{FAiP_x5YIX
zaR{9`O9e(`huGm~P{o0jcGpNJzA%b*w_v+CSl~}AE6`upxb0jVFvt|m9^s%CBOToD
z3Wk9h!uH)bL*hwxgu1vONyUcA*hR!<>fapws76>~0jf$rCcb7n+1<n&h^GSS(Vu4f
zB06b(&e!X_1i?^8$kv6?nrRIaE`a#{koE^CNF2+xI!@A(0d$j2mcIo1Hehy>?X%tG
zIa^%6=8HcdzQw-p!e7p_$*SWr+#%yL;ZrJ#=wk!!sWQCKJhFmsIEj36Qvz?;(CZeW
z`iBMj+nEe5OYTL*Jl*+on4#Kpp2+Dj24S?o^i8e_v|2N4%3il2qD<>wW>a+kq9m1(
zLi at 5i+BN$k9Y%Mto+n3F<$NMH8%l|=B5<z;SuPigQZF;fIB765t+Hu*Jz06o13WHg
z#EtH+k;q#a9~B2lizu~LLIodlUl;i)9uvZ{s;=dHOPSn{Zy%p7tQVR(uV|qUFN%Au
z?4=3R^*qj*0{<q%I9eWx9<Ky9D*a3-=&)-`&(gqk%hQmd3RTuL6(j4w#6+=rXNRtH
zU%M=y+jIkGj=TuLe?jMKym{IJWiBRhowpD2lP*7k<Q9oG-2Pmp)U%Z=d!99#&P|Zy
z)J=8?xvn)xp4_WCUvpK>x7d0H>e~Gsc^o$3I_k;tlJspkLZ&lWv7Cb~Bqf?H^Swsn
zrMix0dh1`z#~A|?4wvby7MV6x^weN75)gtd^aCULT)<7|^e2sFf<=IWN|&>xN-??$
zu$q(!+o;*BRFNq=ECI5Dl3vxannJdTu=Tbq3sPvyy!cS%UNA^~v0x_P>3?M;&7m-C
zVQTq(!c>_;yb4U4G$YedIXLI?leQ^gq!8%STQlmsQaTC8jQouXD}NRL+c%y<$65F5
zI?FRDgkTX#X4XrCp#WjBQ6A;qxeaAl^~0_~{hTWmk74=-xM1~B`vPSy&2L`Wzi^tq
zy#L43?*im`tAXGml=yS`m0qM>^CB|wi5}r}>r3eJ#-U=YDe=eX6drQQ9VtTcB-HHi
z0_Q!YYHOh+6Cxc{M{rvQy}RLOu2Nc_ufKyqB|hhJ16w{yzqh;DA0~IZ9o6R-4+)S3
z9Ceuw6eRR=A3tXq#p{~>g(Xq0Ss_F;XY#21(ELWri^R{QP;E5qXEP~KEz<AY+lA#P
zce(`m%vO3K$}a4|sj&I`Pkb1P4El1xPP9$>ROnzP__v|jve4Aj=tWvR1(luLyXONL
zM2lhkxQ%Ag<o++owFrc=*dKcTWiGK^wcb7Mtw-swDxsHH;~`H0*q0lO$om^4XFei$
zL-xsEI0TqoBP5MX(hY_EH;6uwfS<@2Cq7hfa4gbfeb{qKVfkXNY|s1{7fmOn;Z6U3
z at VEHsI?EQUczVyPcx6o~qD9~Ds*B+Wr^<O$%(nizNOQDC+eF7jhz<2f-wK^$ta4Q<
z^QwsNuLRR|kc-}s!VC_M)WQBB?RL*^&Hld;KW#-8|K3-Z7NjWkX9 at r%g9qg(C{r{p
zVH!WHq~^X2SN&2V{Xc1|^V)AsVtF$~@d{=0;Nb%xFIb at os#?T9CPlaVk at x)f;z`u{
zUpjuDiC=d%oqG3z^%_s92p+w&Q;QZ>;v8&jxmz+?6$=anv}t1&drKj6mSxZsZ$)YG
zP{Q#ENxVWu9u+l&zM;cqW<L26?>3J4;iH={y^_VwL+uJezzjrNtK#nTK5-$vYU3qC
z+F3NG at X5AKg-E&R<OegK?u4cYU}6*v1GQ?dF4OssoCZfR?AY?#y@{-JHsyj#vmN#R
zB6~cYFfD}M)N}r9*2DO at UU7G6@A2vg+y9Ug8_9czSfQgb-I<Yg)9sC6{<NOBpnJ*N
zaWUUT&Y?LPRX(#5rCBH=w&Ji;K}TP)wUvvc>D<t!<IF32w$UN7+ITU2cedJKzbfDi
z(TG4z0;ZpoLTyUQ!j)pB=;dd}vfSHO&LUlYwkvbJSvM{4y)-=L3A(k&0j4bO3z2WS
z`?NUb2^Qiq{{l1I`m4o;qUMjNBg<G}paax5i)5Xxq<~s4d&BePQ at zKxs+fYE*3BPP
zvn^3X3*-H&vW2QAy=LiEdnrLHXO&k7?u_*N3CH#GDL-?~cZVHsAMrBE_F59}F4oIE
zFP5{V3bPZ+7LJ=KLQ_{7G%(hEvl`DUPl}5=zrXD?9F&4)6*^e+uJ(iLn|SiPUfnXh
zEfp&k{NU<L>q;D2)^;k|987d8{dvs at B~q at 0Pb$gwa7M13Oy*VOO0CpWxqr*6+IkO*
zl_)@}+f}`ztADexuw+|vuI3d+bMEwI0kNg%;zY)Ha1mJE1n4?`EbF`Y<r)JMf{XV>
zzaHujYkbtRtx-RP68Y2i)RnEzun%0Ad3dx|<q`n;0ZSQ(k06~bLzVbUVbpXVB!PYn
z9Frfdx>ffN+&t<;+=Mb>$|BSs>}BgrCXaa^9%Qz)F&)R&yP}{CGE}o=3p0y@$R&&T
zB|x7kM2>tT%>1 at GGX*R(ZtpjLe}8WuL>Wl23+|#5`231D9Qb3Mda-^3D-ND6J*I9F
zAt9b*2(8MNdN%O8 at PJ`W6P}S at pA|oyFlLCy9a*WRy($eIvqnJAhs;G_kI5RBZkHTl
zv#)oMr%&(6?+ at 5*;WBo`qsF`{4Vq^&BN7qUoo4W(@V|HLnUYSlW;+Gm&}Umv0|0`I
zgN8zV at Cas7G`2Dc^blj7cd$8IPo667Xd)LM{Kf5&IG5`)h=nP3fZhK$fzJ?jw0-*Z
z%06F47HeCRw%{q}Q)jzt$5eacvln;Xe!#TOm&fuJh2#-qkJ^`ZCYM2O<=q#358#w3
zu389x$~&b;zDZdg;j($l4(~xZ+~CO+2?gK)40&&FQvs?J%6RqzeBK27xg&-Bux49A
zK+is<jtd0HeSmyyu{B{678ecNUcf8#CK{F<W at _jlY!Gqi4ujUXl}GV^Jf^iVokqre
zJYye){@9LmSHG+sV>%IddziY2Q!!T9|Ee1wDO1E==MP0z2upQAV??FP8XG5~yl`5v
z<kT9)``Ga())dw}IF6beXoj(~E5Yh26X>2 at M^;AeII~Q!V$8N#J|zb02ITvQo)JHA
z-?$p9BxMHa$hlRmD^TSs at bglY%u4al(UCl|mV2-^UC(mfKV-Q!LFX-9B$6s%AKi0&
z at fVNfJxk=(DVaYnt-TF?T+-9Yfi81+oVBf&IS#`9GvhJ?8CY-<5rp)$ZE>f*sFrZp
z%;SF18d%_ at +G5@O+eW<N&e~9Y^QmVjSd=Plc2kJ#L34%CnSFV^!9`1!V<kgCQs}Ky
ztjzy at K+v*Gv#gA-L7D4$$E5XcKZ5ssj}!vR>iEviJ|SQP6UnrXjP5yXn38$Zse&ca
z9314tJxaeTjs(PxqJBk%#O%mC64F!O2wc8!ccY`C7HczEnVT062~$r5zvEC9A`qov
zl=1k$Q at m?i_g(D3go<Dv9n|gF7`So{RL_T?%33dX=o{kSo?6_QT~66VmsxuaTC<9e
zh@;cil22A}e0=)97U2F2fq`W6bb(s}q#kR!_e+LOt9)<<nr1U;J>giL;Luav{bW`m
zBR*-5&6wQ^D2qY50n$ZSTAq@`K)wWDoqZ6ZzSL$~%tK1%JQR$&$!IP_!$(Orf0QEp
zw1{Sbwf5=R(-gP*qs%Yqw-4w1B$2z0;y84p-P9$-4vl>my?}3!b(-d#ETf at uLEBk@
zDn`=F{7V9B7N1tEvzKj4PEa)FH at 3oo6jpfabC9YY?K}ykt;US07tHtas2Jm896fSQ
z5U55Y+RFqtpZ!n3szEbqu-Cw5YQt?xx%gKG|Kzzsaqr(CwmH6oWa2vMUK{eA8jv+u
zE8Nn%ovO-F3EXnNRFU0Ea1ZwbXN`Yr#m;OVN<`N at a4$pqAfX6cxM|&9%f at m#$8<r-
z1 at UdTp4zbuUJ<t7MSzx6BB}aeY8&xFg}T1c+zk8fyg#7kpm0Z6O8Mlm<AHuNg$IAl
zC0^TVjTS!Wn1M!7itmGKwQ@=TXz9VSY4!0~t*dlAOz(LcBi#uid5tdLDEzX)Q_kHc
zG}q*ox>@eBQXydD0(7yQ^b4HS9uZ9AVVO3HN<i>W2GC|G-FEuUqn$Jr$7vMSG4skB
zl_Y99jwqKwRjJaBh}Nw+(?;`^y&=EiUrriEQX>S=e7cgon2M;rX=9+SEQ@@tU at HBr
zE6PY at V8T8cUOvP6Kr3r0F*X>vfVqQUInFO``rO%w4&N0F at p_pM>nc^@jZ2Y6PwU85
zE}QpYX95%(Hxqt_Cb1uK|69Is3n_8Ra;#T65?JPcn at kZCfd!8<$J7w2R&cI9%1p>u
zj79z&jS`e(erl)#PA4l8z0$3N!GE?dz4DLT*c~X8UP4s7k-g9>9J&Qk?_<Ouvn=8q
z;Y$8|(YaUB5Pb)yF3PD?Aj0F6=+Ff>!gltT;607(Y&n54OE550WSwu=jYXj%RA}v@
zPvxf+N*sbLwFxANc**^+uCG_5A6fc_Og}KpYV0ER*<GnNH-|K%FK;6Z&H!8Jk63s-
zHRXIjFp+PjRS>)E-|Fp-{z-HTfTB&>#)LopNKK}|`+SwlRGI^6mQh1^&<i3OpJ*OE
z at Sg7lTfL`X1HI+&l=GkaV{6Lv!-Zlrna9GkP;4(3tHr@>UGK6hXD<QhV?=c;$pE=}
zKN(|yNWEky<{Do9L`tHF!i4iMI*HjR3N~%fmy&PxssRWc+ELG>d%J+Pe;X9%o2Zx|
z-F$aNR5F*Z5(oKPO!o$-F4Jq%zFc&RHBUqdUEH6HG>aEW!)(B0d7pUO{7$jiN+LdL
z#8k>w5tS-k31mpLVhsfJ9GC&M^Gi6wjMJBmg at 2!9edQvIb3h8!d7ydR%%2$n#rZ;t
zb9uNfGS(%-W74xI&$E?CcgX&Be{c4e%8QXo2mrZtKD@>v>cAkK+)cEuEXjhvpSgco
z5ANM6XN#h)C-P5XBYLhWQjxJ-?V_g3)0~t;3Ci`lUWM3p462eFV%Ucowc?$_keM-L
z;Axc^-1K?c%${KI7!3b$qN{+E8r|j>>11DLx<oE8(3bKepD(W$VqzfBT5u?;CJBWR
zR9E at o1k(TrDcL at J)T~Hcsfbj~@+w@&@QNjA@(|TQ{T#b0Q)CYxN3%F2(gPQuZFqcq
zEp&qvDyFeJ_6YdQat&27jLAeAuYPIgK24Y~otMRP>TRVy9;Z&vH(8E9W=HPES)B()
zhue(8REkQsIfQ7h_~r!P)PK4n|H>wZfVZ=05YksWcaLhXw at N=^v>gIIo6WQvyktro
z*<YGfhiyiG>5nfp3FJXXcfbv7S2_PNDqcGZKn9n@?r;F;bNH6Lv(mk<UiIM#Xwky?
zE3;#Zh=L{1t_&%o>L@!+uhW*%DBO18#`C*RekpaW`67DQ3#IFjU$jX)P%Ng7gl173
z{SKE+_uqvhEb#77TQ<1l5Vxd=Lny8I!5g$#ZGjK8D9C5_dmkv2-0WBwlp*4<Kp_#i
zftAt4BRJTXA<_+&HR?Tg?U at W*RQ0XvSiN7<(TL2&I)%L%_D=VRmgxacgFq<sR3b0j
zW-pyS_af0(kd`Ojwg?Y<;A`@wxc*ovckmqJVK?G0Cs_oaZFH&{#7ONZpGj;M{rf+T
zX5kpvaDOsDqugmEJCS%Gc}W0jCK=*cy8pM^80bX^=pXtHv7$`!KVlw{qySLtezU~i
zTnu9Rf3V&n{pXgz9gl?{oC{ep at W=EN$8IhyNP11=hS%O}TR~vaw4dTHA1oeRr}nV!
zyY1J^nDjrPbiSv}n6A~c!_M24V_Tc(9uszhf!E+cKs?ji{U&-Q7WStQtJEJWOYX4X
z%GAjHmJGQf!IT<oy)}hrGm>{;_K;FszB%(<5m{$=IYE7gvphJhHmGW$0@%V_Vl0VK
zg|ncOOhyl*%n#Ajx<e^q03+rj<z(ve;5B<T1|r6TdP;7SSlzrLuVZ%H078EluN0LS
zmrLWAyR9M_jjA_okJaXI%DZcI9&0gON at 3+)=DOTLT#6%I<oM=~mcTTrvNA9ow8&>b
zzn4r$wb`&%gjaJ7e;r$QR$#nEj(dq1ZQ at k;dkPro{gf=XpV9kBaM&<fAw73+3p6z{
zD46)pwAa8A<034R4h)|wh=j&-BqqlTud at EntK@D_3QL&#fLG#-&CNswIu)T}eSU!N
zmQv5oYKGU3%xj{T0)FryKS-sMN7VFTE>xRl2)~h6(s|Ya$K;k<o`!zb{_88VvgB--
z^lkLue>8n{RFvQMwMvQ74N^*{q{PtON{4{-&<#VUN_QhYLw8DtbazVE&;!!_KA-P;
zfB#Odb)S3hIcJ}}_i?!jM2`U(9TD~9n*N(M?GHe2PY5kS?N at lG>2;&R)HF2qbG~(+
zXLdpE_#DBz(|gv7;O!eCq479X`@<7NR$<i-FCyq)jNHTTLQXZnWXAp1^rd`YYQhYC
zLisQH4|5Iqjtf7Nm){2oN=GtS96zWt5_oa-35Ad{co_ETz7z3wC%kFVMZP5CIH4|2
z8s|ob++;FrVD%9yX4l4#HK8-~=_7>x%Ci8BfwuZT(Vp=oWLAzn;zu|fA|P>d+yn}K
zB7?M^8Zq(r6hw556$y^A at i(v6Bzbb_PjVvJ6R<_7h`tEV at 92WoTJS$_Vh#PSwd{mN
z at Ek0>chR1|LWQYRmx at Q;$~mDC{*~)>W>w6SQ0wB^#KMMid%7<FOM{dCVjTJNJray@
zrh8Fqe9b&G=<*r=9rrHh3D?=#c{TM5X<I<ufeiYA4tS*6a#kF+oBb4z!wzkgz~XmO
zmo;tJ^E>Poa*kds`0(O7h~8m=Z`QirYe>tG5tZvnSbhc%%|uJY)3T-BI;$QrKTA#-
z3QLR?m2>RR83f~-8x7Xe*>xMm&0=9C$B6>k*-{bP%bJ!hYn022Tagd3TrsJLBtllL
zC&pmKCZm6K!l__FEUj=-j at vc#H}d1uIuV24V5Vm+!s_crQeH|*OQtM~HtEN1&mb!*
zA=qO5dEn+Ph8A_v#TIxS at rl~i=qx+oO`p*qf|Q(G2^N1!#>9hzNnA`R)$Ulv(Ncq-
zV9eYtRVA7EEXQXol%wQuQEs$u_9E)oQ%zCHdn;EiT+en?7H*<8^dTx(UKyrVO_l<i
z>N}xka<ASKH&ym$xGoO#*2hN9gC(i1 at _Ln3z3oSQ051{f`hj^`Xm^5LG1SiXzIID3
zBc`rx&NbXiZj?xWTSY2Vjr%smiY8vWUhEjjvNQ+wA5{5g$;XZJ1I>p1NA_ZUS!*!C
zWDcXG+HZzCvFdkyw`6OTZ&9Dxj at of>WW{l(n(~<VTHdH?#s#F0M`!WlLRh7?BKv*=
zULxY1QlX8(gjU3rfROFTRUhtlHWJf0KE8~iQ7PIFlWQ_ at mL$W0Z^#u!GzO#a01|4L
zvlAQhp|ml2jZmuCb<tVqM$a308~#nKK5O-)_ at b2R($VjUJer$Wro!&k#Ut)OD|XzU
zNP+kdg^;=rWfe|m8c7yQ3;{&y8JMs$)u}(A_=iGY9cZIu%8u=--GNGKaI<kCr%U`F
z37kSI>Bfx46fNW!TpV}l704PR&``L&EXp-l*WX67?{Ox;RJDZkJv^q#W7sAv-w+D4
zxcZv!l9ehseMw~lp&GH&Rn?3d$&iuV4xX5#E#V3LNMtcXiA%Ga!l at BQz0LLcr22~U
z->$Ce#b&h7Mq?P10cFKcmkBQB#?x6#Zn7<1Q;O^PS4Gapzl^;~?=v$onw2LuOt|k&
zP&QivwbsI7uUX5?c*eu?f{De>Y8WMEQ=X}l{<x}8;9>fTLXd6{-juTCQ7=;DHB}dX
zFbjouTY>W1Q|~Z4n>+qfF^fN=-7znc(YTlh%c8mL&&Dxn7YR+&a0M=T;<r}e2vhMt
zn!L}E2pX+hIVz(KYUf>FY-Dm3u2dtbAu=n6vN6 at Glq9VwK9e8W_sK}laV%q4Ezh#p
zQH&V4`(-{d$lNNMzHF_#3(~Y}>EQ|)#p~2O#r$PK(*{}a55hDz513lmGCP2oP-jA4
zd)!Z4cxvhb*$Y)Ax;{rT!*dG9$At3O#1}fGBLT at _45oBZx=c(X;h(xhnO3XMdpq#y
z908N%arzCc{+Hpuq;`?!_cwrHFQ_#vKnac9lz|zRxePGVs-f*TCq}<ho%%RA!bQn3
zAg3cA+)^oCtNp<uhMcC|dwNWO)Xuh!ED6 at B*LhE<={}Z>_mWBwMYd{LnaF=@q+J%@
z5%0 at kY~Ap7nG7Nc;!H=aoy15uFOzSiA==iNFvcAh{q-GGv<yVuP~p7I5BcTTKS2+X
zA9gs<A+%#7rv)Yj`@w%HaM?F4C%VykJyFxm&L9(n8HA=<lq3s}AQP0N)(!sU-XG(^
zT=Xwsg4O5ZR_Ycvu;8BD6Azq8^kjwi+YSHL3pdd^f>jofCtPb{<jMHnn`2Yx++>Z|
zf!{9H(R;B;%{!oyX_?4LN7VQz{gk5%3wmpK3d?phn(A6gsvG#Yn>)r#*Nf@%txUm@
zLUktu!L4=w`ZPX3O5<BZxsTSO?pY|C$yipeK<H}?-D=*`a2Fo^UqY!K>r&z5*m7gG
zy^q}jC|b8gSAAgVI}C8-0<Iay#q|w!jHV+osm>+PSn`cNuHGaq?Wxx5P3E)0R%%^9
zah1UTp_Org+lnK`&14Z0g@}<%rd&7Ui$K at Qurr$KB~f at 1FfHjaf3VM@h{Pl~Fv63y
zCL=r>=#9ZbI6Z~-qK>U{;L_`u;|97o`7})Oq`xsmwnr9f)w*-Sd97B}DT?6DH2WtP
zY=l61wpTRcrUYTBh6~VpA4N(vLo(>Xe+Fk2Um$kMSil+--25(m;s`lYGZP82<Y!^Q
z-{-8`dZE^~JrqtBaVT0|CekI_xsI|Ik48J0U?Zi8rs()Yvc<ElOFYxqtR5Q%;ZTEi
z*&xv75qE-u*K6F2Yag`WG<LA$ayi50{Gr|ZW#f at Sm*l}!i7X{xXSkcnKbxL?+Qb^m
z!GZ8E7E*o5D72^!Kp{s&dDuIzFl<EA_73v*EBX+&D8(svZL<)uB{+uY;sDTb>bBI^
zuu#zE!`Q}pbg0v=o5iLh3vt{_B!>^q4^52}b(Y&nJQ;(^+eW0BItdw}TgGyCLBTJ;
ze3l1NUP#=+sDKG|o;p9+dzbWz`im1sc<a6;&+d>)S)Ef(qMf+HJDGD<mUjMtbH9Nf
zuIn4QD!Sssl{J4TXA^WD!6uzru4NT!PqT;sa$EZY%c-Gok3?IuU%#Al%f<xc-W}nw
zs$u&X8RdLrti2zoz(g}oD4Crxyf&(tkGVa`=%AJksU?xO+mt(xEWhM`p@^f5g8xce
zkyN%GbfVdCEigh7CF~2BV(oZGj`xqx^1N-AHRKEFV^SR@=>cyaUfgpP<*HH$oNV9V
z6V%d>fOx81HU)SfFgfh-5IN-TCx<NE&{>@dSt>3dj5}}$r>k<sQ5*1|9H-(qAv_C$
zxRp?0sB}EIm(MN~UcOu>&5Heq-DXpu<g*)2mpx0eEE$wcT%(w0eXFMrH^hb+O6Pob
z?5`afA3R({{N)_5PKQ0+tVqkA>KOb+&%V|n_`WX4NwVptHWT<qn4PsRnjHQ{zl%O1
zSY9;Yz1HkL*0^tv3Sd){ImPC7DBMfZ2HZ6tl%0sRb{;_(tc#e`glY0`ozUhPuU|N!
zB>=R4x$?pX5fqw?3_K}%&3T#=xx734FY0#A at 0Yt8H%XMd>P%Tsz7M>hK3ON1?xA>k
z1j3SQ8|`w}m?!yBp(9=dj~P`j??7!dBA|1{n-3l0xZ+(9v3m|Xpu~VwnJQab15Lx`
zy)H*I!V4_G?K>CDDnP!xaTz-!ZvK*ieg^otKkqc$wh`G3FFK7zBfzNr$=X6Wjqi_E
zN31`5oe+7QX7%fp7!u1=OzL9w5?;PQF?(0{FUc#vstSI`gle{aY1udLSo$#s_!6!i
zjJk(j at u9TvE{hdxR!wgp6uhvPJ<1|`#3W9M&}4KM*BvRv1@}pu#1;_K;;UUe^fpII
zvBXD4q$^R2CD$P1zmq<mf~U=+c9pmd;Y~98zG8-aEH98NHO`H><SxsLVB2DZAhEKs
z+I$5hzBPw!sdr`0ud`RAwWR?=re>0B^dxPcFJ~gciN|l6MoZ&iwTnc%8`57!j1+je
z8y=y}`mjnz;TpU{UowyhP_L}w%Tq|xe^Sj#oYB^5FGAhA+(u$_et4{C8}~>R?7YV@
zV_;R7tXb;c2D!iUV4P-5aK&fNQpF5+HAyG0iP(Tpg20m(i5l4Sg%4T$M-)j at a)Y_B
z!fV|~sxsGqj=LjbN`JNj<(HyOal}Q$Ia^RzfA-olf$WuX<b(4xyjep922ErG#Xgn1
zu5la?7-CfG{17~DcJeNKSZb- at B}as*$mfG9+R$?@T;Q?Fo(0e at Z-^H5%PJ8-(>U=D
z_iTE{yz#yi_%8yW0YM%x3D5${l{U|u;GHgm2a!Uzc^(4 at +iF=0ZVG=Wj{4YUaKoMM
z)`CH;DKr4uFb908uNLOqt3x8K6soykp!A1A30Y`-_XGJBIj}W%fiW(hi6Z{tLcXwu
zxqK%`+{peFh4Z+-pji;cxwB$g$lRAiyKL+u&TaTiNpF+E3kwJtAL#C-aALQj933GA
zp*hD3z1CSY$H^1G8y&vk$P~N5Ig8>P=<^J)^e}hqxqan)Yr+>)K5F at i__FaaV8H*A
zbhJjWWhB8YO}rR!$SFw=hO6$zmVQ*W8xK#O4-FbQW*$=+4hzM_na&=CT3 at oY1I%dR
zI7366od+rNHIGMZJoj-4P3f-ukggD8-f#3-XUo0bH!q4=D)MS;lpQeXr4z+3jJpH2
zXtRRQ{8kABbDHr&k}-Kqe{f^f%M2+eUPMtaKC>F^q2Ck>5tYsyc~wbJvdAZTZD+{F
zZ({6YI4#V2_x8T36gQ+obBF#>5i)wjB7Ljl5vCv$w at FAR04@9YQacg<iW1(*Y4xg_
zYkWZ#U)24(4hq=ER`M=$kPIBx8e-5JZ6xRwG#MKkmViwK*%yfE8p;4>NWY|9h+CCj
z<ppQytne8 at sW1siZz)7<7GA0_S5;HvGUXzZNAe2QZ6Tr#>ByA(q~gM)kn^e~Wla?j
z%KdZ-qzS(3B|O61{GXGM{Y;z>UHVwxWGOrCrL6z(4o>nOo9lUFOF$HwN!2I3mXK`|
zZwt5*nW6TW*tSw(9m$pedx%CsNp=|*G)j<d<d)ezSBC_o;jZ-bTd>UPO@|ygdB|9;
z(`PQG^(v9KBJCnr|J18C<2IxBxUvCc_5FsI5qK4mLH}FzmNk34RG)qPaIXKh%yPu8
ztXC?bv3p+ZAsuL2eC$8L#}{+gZX-$)!+})k;1nCHst6Dr0Q6zFxIB8)xfttRm8HzI
z;U*RXNFzE*x<7a$+LN1`A=}6K8w-nb=@!QaK1Fhj4~5zBj%AEG`}D>C`l7l at LIN$y
zwbTKsSYb}06rZkT0Q(SD4clk{fiN?M94Z=`HvziySAhZYkaF~%g%ysdE~7wAV>Gt0
z7dH at mm^71AiMRB;Z4eTfDXwFB{7yKbfw_Rxkb?UKB#him3q^ROKRN#qf1oK^-h!uL
z`@Kp#L(5N?c6I%z0^v&z?9Rrg{d7t?!{dZl+Kv%g?jbR+w#F&^N3r-ws>dgC0+SjA
zUJg;k3I_m)LsQ~5?T at eJD0@{?)g`911uCJDrh>@{(1_6=#~y}#cy-jAYQI<CdyD^y
zK^;lo>gsM|M9!5ZCcX$c;9_aR=dF3M?+edzb%78x==>Yd6b~i0Z`463?no~d{$ov^
z*Sl+!m4T*JlKWH)b-{$6anYkrKVzz?gOVHBNn{sC*M%|>^?(*f)w<|lAlKU+qxh5v
zRCU3dR|6AInCA=(EY<?#YWpAMgAw{P$inURZ)I=@;!14p-fX=<Vc^duxV?E|*BX6n
zjp*GJ>Sh1dQ5lx=$?HH03~}Cp!Z`4e!a1wFDO%9pqWe$avkS%o8>%w<2RnVE;q)hM
z5&h*ZmvOK<a;IxGSe(8BX!iBn8robuLQR;QWXB`Po#qD>GYXC8znk!CJ#Vt2L?Bgj
zj3U#IIXA00d_i1;xVfhfB}iHSgClkrRY!uz_6_wN^b1A2qi_N4Dx<f`*SC5|9QML^
z%ecMtI#m`aA&o#sivdWwCad|!d%9<87m`E?PSzJB6NSP3u|MY{GlA=^UEq$A4k#Kv
zjOkywSu~!Z`z%OAAWb<{1T6B05YT9g{u;ds;Q9Lv<{BF$b!uM0PiURT%8EqDQu at Fi
zq~?$V)AA-iGRt3>Js!}t_}9~&eon*Vn+Ib7%kwwd;gDgzY>IuIlb4S37v7Gru3yro
zGg3PUPL%moMsRN6%)x&*>bTW1yo2&ix$;5ZQ&~PBWe^wSHTn0)b$#pzTj|zhYq-%s
zt=dd<VNfI*LWeMyrxZ=alrJ{q-8?$J6jqB2f(+Hxy@!N94;vewnrzHjSs=|kzc)mK
zCv4l;q62w~C$q<e{l~e)B!7ga-BjJ?y0dHIHLG-nsqtiINEEj7SnT9S>M`##U#aoe
z^iQZ_C(hN9e>|h*FmtVqx3$i1 at pEX;>YxNZ8i`?IoY~{oStuai0=3v=NkYC3;^q`@
zHjke%2IeA?71I5$h at 4-CdUPB$%6O4=<(1ASj_lr<{0<t*MAbmOh<q2PwhfC`>pH5c
zkyKE?MJs`}GMWZnXTb;a(7so$+(!j0A)@j~IIY6hhr%#+egZSE5t(<(k<>v3awae6
zpADyx7c>IHo%=%mP at J*K0r5&lV0g1OyOtUm#?IXI1?Y=zW+|(E2f`hz9}eV86m!LX
zD2V)57$|j_ZZxOH<3Lz!WDDGNYe5tZ_)h)+npto39NU~zGaG5h`t?++wMs9GX{RhR
z6|4a3ca>1nK-0R)X%tNeX&7kp)Dwn;2h at iE2D&h;atkC>PGrReeH5zfONX7(fbC76
z65?>-@%=E(W+o7Jr*<r*6lvy2rbER6|5ftrG?}-+oIZ8;`g==@lMzQp-k}fiLp?{L
zVSmROsDdePT{SSnRvDcd`Q at Dgn|Ex*<6cSl8E-G*wmQBJOXRhvKaxAc36K9l9=;_c
z-uiP-YRvmzCsnX7xn;zx%_{ajHmp$^{WEjgnWWx#@zT;*Ath3yJ!P>s5&kjQgKEVy
zg(}@D1axs}9GqhRyaqRR&!KPYvDHedzX*pcJ2cO`2)o1zhl}tpno9pHH$qL}cT at _*
zq!iQ$cn=m0`pKU&B-u at fO@*B3cOe4a9QEGCsh!8VJyFg7etgc)Ek;K4EbMN{FDKuD
zSz)8*(MsPoP9cUq0(DSSs%X{TYB$NVwpQ8x3(6u*RaMK><mq_l6%lJ8-rdVsJ+}Bx
zYr at w<^`DS?Q`<KhF{OC10-knkKZO&SCH+L<C`$fG#|gwIh2p;Jo;UADL*@T+ at H31K
zYr0VWIZ}`w)X_2 at jJdw2Q>K3sFfTKGA6gy!g1TZ~4m})QAi;oPL*oy$BkdZ?H?gt6
z>b3k5MIhJ9veJ5|-R}hF1JD?*3VC!n*j07J`Wk}2M?k9&?QSskPHH)hwp<ydUPp&^
z4>pD8g!cA3Yzep at Dr*7ofB<jvx|$y+-`=ym%6qp_;t<XKO|jU3?#Bvgz<EmvKoD>a
z&mto={qHiQmc at _uF6D{30kE8*>?q^Ee0*!<5vUE;0CP810F89Z0Cs9$g(@Jes{?*p
zo at Y5U4f@In at 5HEo$EY!wB=CN%1Mp>?!fWaS5QJ10TEM*~_Rv-EF_W}e(mOcrUpKYH
z&M%L1jOD}zXlKB4J6|4l at g5m@$nUhBIQw|Bn?AGeghL)WKqLF&j4chLX-GnZiY0qF
zvii at iSns+#&IvPT;EUT(<npp)&RA(l(W!Dq&f#Q>WgT0JK8Ps??wVqJvVcIft1v^<
z&ja^r6T+rVCrK^=$NX>w^LD=UG_Ek`(#)FhY8J5{BJ|{CuM$4s6KdYv=RL5Mh9IM0
zHD(;HThP6ZiC%W1=FplEuvA=+9p2GkPr2Wd_OmZ*?>+e4R4z0i_swWM1}_O28+k%?
zEW^in`khG)0le=6UsmmV5u>)XJTorOr6WA<0Gau7Mu<wgFcU4zu~#6RABq=+)#g{s
zAxphyM%^c*wcZGc|E_<-jl8QLlHq3RmULhl`CchY&MpT7tl^SZ at --eHRwAoXX1-A`
z at RAAHle5Yn%4Mk)!rxQG-O2Erkoip8=i+>6YJ&5_!Nd2cNL6GNZkHiStvL*ats$+^
z?UWZY%bdP5McYDy^X*6dp$+2UqIXdhjzcN6TvA%@@>H7o20SQ6ItoychBrV0^G*bs
z(VLF!ObRpVyP06XXsE(aU6=(OGU1^-naTQpTmb$%AKV+RF=wrCAX0t-X1J{FG5xtW
znh)ayy4k_=$F*tamOO?#E!8$YJru}eld|JKGJy(^-3NBo`>4!pL%w|Nm3x;Lp?k9D
zoYl{{bpPwxCbILs;I+n)HIQVjt29CU8MY*WP4}ht?}!e-D`6$VANt`a%i0LQU$OrH
zK(y<R77sXEmYb#{8;u&fRt^OUVq#%j<*C=RTb0ZWLSo6s_;MlsKL5L2AOG(S?8{@{
z*D^G1w9_i6covNqFAOybWSve^LVjY;N#su4w>%g&({tx=3TzsSXK}M|RCFd#$s72(
zlY4ml{%fbnoYcOqh!Vl?I1+dai&}rNot;mcjhMAN<M)9dyb^b?U5RfH7vV$_1o<d&
zy;k5S?rCU$i5ZL~4m50mDjyr8H+O$e;<KmhKVK*@Dq(Hj6d6AFu3$nsgFyEDiAFP~
zJMKTWk$et*l8&Y+?+^jGv$4Q*FE7~+1*y({%}6w6W?Wj)-Tw%;!QuvOhS~rhih`Br
zEOM1DQXIzVeC#Ny1`BR=(K^8-Uzm$A#60tZRw8#~dw;+xBTJ0C9tR%_bQg{F4l!qr
zZjtLuP1umf!qay-_*u^NMV+cv{8MC-<M78fNkT?x%tsM_$Fs at rim2s7Ao9#f3cjL>
z-$)UhTDQ<vPP!7^(VdA;^Vyl(=yR#aHy8keP<U4ipfD-oY#Om*-!-}~yf^zDQ{cr~
zB`x#P^yPdmJ_FIM9C299QL74lEsPMjRXi|Rfo|~=6)*uHNV<~<u!aO?xA)jC<L*?^
z__CuzV!0G(4EvgZL>eHMbyGa}E+aTss|OUa8A_Br9R#vGVs1fEARWd{a at d(tzS{ny
z_l1Y<YlsvoHZZ$bmw?B}IqUn!s9}?M`N3Vrx=!w-#%|8wUN(TwzkwyH4x!BJ;mHn$
zx5>HC#DYVTe*lG}2W9`_RVc`ZB9Rto2Kq$~qO~l^1GWax=f8k{g6hObz01GffN^S7
z-ZQJvqE7+&FH|+*uhI8oZZ*1A&yv{#p>qyxviO+}6BZGyr?Xgdkf0Vh3C=#wkocn|
zWzX2lmd_QAy~KTU9vUT1I4(&&FVhmS at 2abs`^_fCp?c+G)5KuH=vHOQ*6n{Fk9q6*
z_AZGa_vT7jmyx1^Eip>oznC=-M>@Ck#PLb(3nrIq=4u2?=JJFLV+2*ais3K5-cb6S
zdsC2;AN?ApE=*caJ`gy%n~;hKu{b*Ya!kwYa0Yr9*SL$gz|_7mp<ch=B#ZFlRAmPJ
zvmYFeIT!Ou_OYLIVZ_Q;JSgt#S>$#9$S=FYOp at SL`7t~U$Mw#UCLpG-cry2I#co**
znWZ}C=sZ4?==Nngu`S2C|J6n(vnbjp-^N~h=4 at qso2N&^>2~(?S29Cc37JKdyTZK+
zCR3Dj%25=VKQuxY%xQc>HO1c4;7s(S4l3|@?j1GXjO$Kpum)8A(7^om7JkUzLLw|M
zu;DHthvgYL85g3``S~E7WjeAux-`SnSetQ3GocwDbQE1FB&%N(wuvPaqa<$n-q^yT
zz=1uSg1cgz7TvY)13e$IZ-&+Ij&qxf2s(tHvg))8iyo0Slh#-OMfOR2;RgduY?<$r
zfk^3oNW&&@!q#pBh){k|K+||!vVpC_QcPOM^*&0iy at x_0eMc#=gT<@(2JtWQ>uUhq
zIAtw3eOn!j=$9vIk)A|OtF;3#(>`UrXdvcUrc)LNPj1JD!vL^KT2T$2M=nB&)gujL
zff^&w%NJH7xDctqtHy%Gs4c|Ko*Yk at h5dTa3-H83Z<xVZyBYluV@*)!n~#5$GK at Fg
zZ$-|`BC83vzG%`dmOMUq^R;8LBls=--OHPn!Q$QFNH*3fGZOOG6Ax`=SsdJMgx}Ld
zULv!|Y8;tdrY8Al8HV?oWCx*ePZf2H9nhnVd3MG-jCU%lGiZ&c>Qu*%c9mI9^o27A
zs_|Tz+VC>(NEbSO`|X+O_i5WV;Z;v}92$KkQ#xzBB3b<+pz+f`@V7t<5D``t_$k7o
z8Wg*HKwGR#@4ubFC3eb@$I8J%hOD7_93J+%^bxg96*DF$n>jSG(=2~5uo@`hG}&~+
zA_+DBS?dn03#&e|jFm}sywi%3d%4r9hkU~d1I#KX<fdh`Mrgp9^E(1K%vy_lVgC>W
zuZ&-jMPTTo at t`QjS6u5^y#FJ)9+?8ma at NV3r(EMq;MCfo>ByLR^jU=oNNd}ri`CF{
zyA1~#{hP at oKR4jSYSeQOMLLmXpn@@|iTtX2kCpk(=Tz8nA$2_n%=Fel$luht*8{h-
zGJ`if+`XDi<um4qqQXo(>L7T)qp#w9uWkmiw4O$yZxq)aGMIC4bG#~`?{eggK+ at aA
zYA_xyxZH#eq##-Qiwb_zcnyW<PDRpH{>ZGN#ii>L3%2R=86%G)?UMTS3RiWcYsgOH
zT|St+#Z|*#YgrdI+#l@{Pv8(qq0s|9#lqhhs0*V&QmbTiBX2=9d)2G*X%RVJtvH1z
zAx<pZl;E2Vqf<2A*^!d>T2;cJ3hq4W7F9ON7T%fjg at IXF)H%>EsXia!J?@b8dXGXn
z at P)d<WPZMS=8y+~S=*yDRxc0dSrqMUHTupZf2F2QthRaIH>T^0O(HYO*VCsTN}u<?
z9$?&0yD**`^#4qz5EVU+Oow()q2zPpy}715^!*kd7fc?~M&w0_<~?@?f<oOeBF`v#
z59OQ3V31Dg3%S*K2?Qk94gc%OnaEasKO(}PPhK}TL{0<ytEDnSc}EdFVP+rpRV45W
zX9iM(<FIRwB6t>Tig><`<&H(GY!BrN{j!iPziihlY4()qi;FsXdU~(G{V&(47k*d`
z?s=>?5;ipZ_e5&CVK#S;bLSEW4ki`a74O!H*SkdFZ{?ZY-u4DJe!?b%5;s5ps1UY_
zp=%q4!6}l0HtQ)4JU<dZp&_bMEuRHhHbJ4$GjE0e-ms at K_P}va at bkJXTAy!}u<Hwm
z!@tTS=tcMx1Y}*-VPK0+K7g=%cIJc$5G>V-FJ79`ODY`@FC8MgJDo&ww`y$LeEQ{k
z{!uAF9{S<OXo(!M9*jG_fjA8vH9l at t-jOUqjn&9mCG3LQpNeojPdm9Ifr8KdM_P_!
zn`&>wxu%K=f1 at G5mkT~eZJ87ankP~&Eq30$cezfbUZN01vLIrLw`_<5$PV95r2T(e
zDf#$MA|kw#;^%jqn_|Xx;ri?;-a#}+b$z4<jEdvDqxNzaH8h#43O1AX;bA06h&MkZ
z5Seq<^{eA9C!EDd at +`@;ntVh9d7kW6{z9^H<7OK_Hw|FWT1U8viW<YuBh1ZcfP;WN
z`qt-gt~?$FjTS74`PzD;`@rh=1R&8-Kj|45E+-_ht!7I!h3_b^jj`4^tIt>$li9w`
z?7P-kjFMquVzTu`_Kt7DJ5CE1ZLOW1)!u!worsgAES{X4Y&Q!c5Y>WP(c$cCRO=m<
zRQit%zHWI}fJYe7OW8;-9K!AP)b=C*SsEla@}WtEak0RWJViCqT(qY}CFz<pm}k%5
z44QGZVQIzl;p}@IWjH^Lh2>ZFa@}SG at 4E_?Xq5^#h{0L}!%pix<^m-bcx+(vxTX69
zzIn|bm<(8dN`D#KUJ0WI+pZ9n0TONzPP4RBi{0<AFN_!HxRV5_8ZITx(&h%!TO$gg
zsK*+|AATfddW&Ma%d{5gvKsv!Qh>2ze6gEH4 at IOUjxP*ew8g6_2I6?>I(cMs+f!cs
zzB51ilQO)s+VWrWG~c5_uIZch;6yL%J|XZ;!8VRAG#4)xKMmMVY~R{_45b~<YJs(V
zn7`k47AV(mQX5YBINyyex}1;#BsXpE%^Ko$2}j}QOAU6vfE6w{J3H%5t^V&Dcs at 0Y
zWm;uAxz*L2b_-SF at qh+(2EHYwhehXv`E$S@;*=DB{oqj$IAn7%@&3oen)FjU7{@kr
zkTxO-JaxdR(Q_NYs5tD&Gba9Jz4sioU1WS(T2MK$hORB%fH3_7NJiEh_3oR%t<jW}
zuD6%0^t25`=Rw7~UN2kpwQt^XaZYEjI9DkG^)8M`MI6-~{gKs&t)0rhQoM0Z7|v<=
zLh1a#q<SF*2ef~72iva7uFPh*4oryVAD4aO!t)F}<F>lbfYeu^Yfd~E3V=qgab~xC
z41cvBsZjhPhOM6q2#{W6t=rPgQ}+wW at t&{!UaU at FkCC`B<S*TW9P;iy^dNF(tuNhH
zyqF4!o2VY5DL`I17Pzsjeng at jLR4tE&=?WD76{@bEmKCN9a{>mPx;p;D<2>It*xyH
zPE%mnZ|NdPi!~HvseJ3MPFDUhEW9sH@%VxgBabXzBF=_l_fV^Kz!h-D(dhpP3l*P7
z0Zs4&L3(H=@hfAjf3li208Y`Z%o7Kbst|8VAW9eMTkK=BQMvr|?bkCq3Q`%FO%+ at 5
zb%w9+iGpK8;DK%iL#`_aoP^EGq)ORQWvCi4DVAdG=XY|VS3Uh%;E9oJ%O)pMkkDA*
zohkJQDdSko<hz0Om7y4w_%@<P^1YSq>mG1-&*<idj58XPiCVoZ^M7uFi at WL3D-uMn
zp*U})wd8i714R4z88puSY-g)1iAG^5D_ToAQkUG!G-_8F;ol8y>i8_{_5M2|JF+L=
z)}WxIqo;h*$UVv|Kw9g%KP4?z^WWBr4@&S6shpftRaR2EU_=M1lQ#EOd{X9z|9`Ag
zu1%LYczI{}6lKYX1g?;+kEC!2TqagU2w967gKT5X((w{7`e2r{iu(p{IB;5>t_Eih
ztm{kk%I8vSC)e1m3>U=WoSQDa+R)Yoyd`SCU^%KAj2VqzP$QWJt7#uHA#4v418WlK
z+o^)>AW+L_+f%CiHRvQgA=AoE4j0KNfffJ0O>TAlI5{(hpnweznKciYu$!2uKZ9p7
zp+(Aw{0s5Ad7Sc(jII($n#2CnwjyJHr#=Kzi0EmPG;%vRPua-3Gbj+$7&%Kc9n0-s
zxLoiGo;e5MGWi1q+vgo%Zn at 4z^m(7kn2+#Dr01h*X55UDVQKdM$jC@*P_QNjpl%Q@
z|Cr{)F}UMgqQOi?N~#+<5|Q0I{?Su{TTrmX_x@^B-PQ%AREL#0d)#KN-8X{U?Z5X;
zM)v5qc|>8bYF~NAwa at 2z!8T*%Bs!k%!Lx__McE4Z8pRsBX;ow|-VHd7b#@NS at DaNe
z7xcWe4_5Hc#z%F}#0Wqq(%qo9`#I|e;R49Li*C<Y4DSoHIZ4g_P|J6BcLPMX|DG?C
z9TH?J2FU)tZORM2V|gf$td6JDY>^XyN~5gNweTvPKKNwlNY_e_-Q0kIkFB+^B`J^r
zC4 at Jh3cZ!6Ns{EZ-w6t8m#wRoQuZ%I`S}+V4;EBi{&m)m(5B?!9r19a<vD+?UDN=I
zKR1VkMYDLxuP7bb>a>f+k=%?KDesda=atXx8JLxpppd-mV0=7L#r{_j4j!M++SFgu
zY(`7u=BO3Jfbv^gY46f8bGC_)C^LXq^nZ)E)~^;;X1UlC9`Yzr)BN8{oA8uFNm84B
z4CYvYu2A|viD$f3VXLY<J-l+<Re5T^5-35T(=X!0{)&weI%!|;vza5PribDa#nW(f
zRp!OM334z<<O{#Sa9sF19>PuG(;)B1`$VClks+6?kiTk+^Rfu#Mcyd#ql^!QhNDY7
zczx`p=Wsfx>FgZl!vnU;<076N*~3Cy;tM+qQAxxIjkW2NM-S;{WS at EErljH9KeK|}
z9x^hFWS+SdS`&t3p-x`wjpv()->ibZi9&l0>xeFoU!R)~rAu<~f8N+zO`MFy+ex?5
z`>w&DO^Vwc!=ywINMlx0VOnS0Qy=mt`u27$2%+ys0MN)<WSUn`CQK^osRGWX5D~L)
zMD}g=^T4D0;41C8<oQ=()4okGrv+;tMhDWX588SHj7ps<F+AA%e<lCCXa_vX7_BK&
zKkbBdcPk}g*rV5BTrt|bdz{4R)30`SN>Q8Rd5qqznRJN`_~=!9o5o=rN*|SRzW#tq
z=k<tDgk_;OF*2fr-5BrHKNhy-`9Qi>>QBt%^^{t%4G|Ad0GWJBiK=VjcRfKw{EYL%
zQo3S<AKn|+$Qq;Exp~?-p@#DmGnP|<>@U#65%Y&3Kidpt+bJ24MlEVn82O7$;9O(<
z6Dfo9e-0zY<NuvpIET~M`=t1_tJ<d>Sjs2A at +oYOSwQ($f72$2n=8eiAWDxoNxvOu
zNmBTDyRT^RfH(5)@i+2NKXa-sxy;izx*XBk-;Lwn&!N6>>y&4Kp+fd;|5_4mBGKnb
z`H>EDHuk>A?B{;Gu8UvQOUWR<Xo?E{`*F)DJ9#~?oT_QlFmq7ZyU1omapp+SN7SEM
zumkrNVMj9 at z_!8boP^w>aFMojfyc-dp8iCRy4C6sY|ZR5dAUqzrFF>UpmfS!Jg(l~
zkzhas;ac!L<z9EmD>h4fxD*NplVD89N8~Z&f at EOmH7q*^&1-2dIcK}}zDh9Jb(oR`
z$?Tht6E~fA!Hp2_yjB|j_R=~V8Hrtb830EbxM6%LXzwS#&;}sg^qQyw((`frK~WG8
z?+df~7in2u2pSthA`Dvjm&Z4u34RLNpr$<i-}o5x6+V7X0t~$>{PLgAL423P^LrI!
zqf5$2ZZ#*o%7c~+w>=~mPvLJMzC7ID)@cMVe9rLk at tISGefz{?eyke+#uk7|(|kDj
za&V8$kFq5j)^Pu!Dg#@=(&y4L7~ff!M!Q*u)!NJJ4%e5;^k?v%>CWQr`K{rI(GK|R
zzg0Kw+wjjwB!M}pSOB^t>`-phMyOGMvNZG1Hre*1dSB-fxT7m00dG8u1X=Js2k}~G
z7WxagAAe=1H8+Tb@&F>S<tFf-w}#Fyi=2XIv)V<GFmvrD_2R^2R^2=RAM*Z$goGq~
zx(64ByG6WNAnsWQ)TQHn@`Qx-mIVigIcpL5PMBGlwrYVR=;is%$KH}l8cq6h6B84y
zZ`u=N)FU#?_|q<hCujx+NoVUU#YVay<Mm(I#{B!RLbLt<bE_!-5;f|_>_=Z9Melax
zV*o?_2Pbb~v>EfHgg_r6+X~WrZnGF|H{hcuCW%8=*#e$s at z%zu3hBSB;oe5z&`e4Q
znq7fnts11b@!LZrkP|u-gdKRZmo$5WfB^DS5x&qZfZ=|$kn7b}0Yuz#-P(fB2J6*d
zih-!M^xGl(lf!Bm at cMtrVzu)%No9re0{bAkH*PBIju9Q1IcAPw3PWEyj3>0)Q?$kX
zSgl at fb}C=7-s|$9Ut@&h_1_Nvjt1MsynMx!tL=Sa(U_IgjqXH^(B9Ouh$zy6U{Xex
ziFD2%=*iENRxB4x8%<(g2=d)A^W;pSu#Zg28igNHⅅOnbhWduq*EF?|q_xg7h<I
zWPII)w-bgdc<^86q->8EH_$`}ZkhlgIB(t>T6R97YlePE&BY=p3#7E3!Nae5_VC at G
zo!N7-XIgUgq(P@^I3P8X9BB^Fgu$t{Y`6vx?kzyrA_L4B=rm8pni958$Pm*u<5`03
zDiA3D+6MTrXU>1zCddT&i4tOvD%NyQ{AjK;3iaWd at 0d5!zc>82%GWMCU9%Ul{hglZ
zT%dasPJvJTjp1=8Bhgz}?RflJs at N5Q8C_Ksv2%%#N-~h2;>?7}E^~fNJ9|t2`SeSd
z6JR|I2(AQoQ%&z~pfUNMKmD4$xoJ#hHz*0A^3&OO)q?`nqmpHO&_l=Nmj`L`qPXcB
zx#tIB6b1gy`D6Eb|7SlS56}HvZ*t~hWLK$EEzwWq{{USTckGQ-=^$SgCjXMCQdsW-
zR~a1{5!yBFTUgNfXaQ3ze&&&m{c&|E!O6Ja(GMZ*fXDUp%7VsX)$L<Bd3p0O-+cmH
zuh>z;PJyzAjEZU=ogrfaX(VPBVPZZTz~QCE&ly at BAQn;67=K5;iMgk2{C;+b(4xZ4
z+dGwcx96v(;}|scKqA1rN@)Wht6aTn<P~$Pg*$j}U`*UC{51v^)>Ys%aF*tcU3UH=
z9ig^TYF#4=)igAQO+HBEGi#j*blTx4Y at h_$xxdYLeXD=HX1cipCxaV4us_<DH}6UX
z$1kZ8Eg6t|Wt?930yEK+^}R2ij5oXOU$%VIpPu|3ir$djfo}(ydjNA5zvrC*2szm+
zga01AD<=@4E~fg!Pb)mXqs~P#Ugj-x&6iXr{dftf0GN(>C&GJUm>`{Gwn7H{q|3W-
z>IaiG4({zASVc0>+&1s)gBkVDz9Z+ukB)N{2BiSJVdLT9vD%3*ip7D^?3YF!E|`Ix
zB>Dv1McVsx)H!s|n=%)I{P&<^4;yXN{bacqjnYHxv)5EYo$X?cG%cQ(ahu`1 at AXRI
zSNkSuaJKIibZLVFoJvTB#sU$;Mu`S$Uw6c6x%y|}OU@*zj~9{LX_5c^vG+-ntYR{&
zfaQn>tNzD)E#EyE=9i@|yKCoga*!M;2L~q!HDOPZr595V0z7*&8OnV$aJ1U?^>Ds&
zUI3l}t*)-_HNu^fgHBF7UawXDa%k86- at of2zh7JF?5;&|eWWLe{MRbd()wii-uR3C
zo2V9K6 at sFY-Vdae<KbT~Ugzq641{d&-7l(o1RN-w;E}khcZIE~vl87`4B8`(-CN)^
zrb3%(_+y7RO}ZQ5D@@;7vawOHeVz$GIhNu)$`|JxhNr$-rJ8_g$;hGp%_G1n5#{5Z
z$TC-vX;ks?C9i=Wh0mjH5x04lnZU2t(+EXP*P!BU_-I&J34InrA3*JiNRU4V{BX!7
zxF0q$zI+C-FxuT2{<44Ydb~|1>1V3jfNUf890sdRCccfS6TIVA-A$_%y2^mk@{Q_0
z8p>O_#_y?Mq1~*IUizw0cdm6KC-%lkrR!?A at oQW<z{fK6>aAxxS`H_U6^dt$o)r!9
z6V>>5Qv%)94 at y{=X7AJdKa0c;ngNfJ>v*l>+b~cpSE&h1TUx?{e;=%}sVj^>0(!?%
zy5T;z<$bWFXM1UP(~e3Zw0Qq9-DBOJw at +n$pMh2T_v4-x1e6)gyz{u!;0bj<UV=6_
z3vS-1yDoE<Ce0q9vS^o-sMyaJME&B`wX^bAWX^P6Vj^SNoxMe&Y9KH9TW6KP-gYr1
zO;96-#`0_QAW>aqG83{|44mRUSb~bz3?8!f4GC3Ik#nO#S`v%)7!pd%&S$~QxrK#P
zpb9Mo3jBVvSG(a$7f)?V^=?r2lk%bjg<>9|66jo3jwV!E`Dm$N<!gh at tkvg<p^d;M
z<idPk(7erbbaS-l!=hfYmG$#QU4gs(%<i$bhJ$+&8;134oa|vLG)4nlP>_kel84qX
zpQtk4*Xt^nFJUa#pLxY1XmT5?_TF=)))Wc^iwfuR;(TbS>y$3oQob2_0>$AjnJxKb
zzg(pFvCUOg*C7xNTx4#WVGP!fcb8tLU1;_8E6uWY${-a|ABI8P`w_bQ at 2+e}M9xRL
zx8 at 8#HFy}%xw*O9K12q30p6H{i_S#dovh7SvV)$%e%g_``dpczC0~<mcH1~eX at rYb
z?Ee!ngKzfUTdHSapr+AIIP{HojR(Al4NF5rsGO6_#K_ZIS!a2lIkto7R6fv{hbMjr
z{<2m{O01y={XjNKhd!4{-3;A19}HNc;POk!e!FjKh=h9RXP at y{0LOTa9I`wj;kd28
zd6CqV0rM)4RoH{~BX?Hwqzo4W{$lZJQylN2WX6H%!L;`vXf6X{P~*!Ro2vUhUxmu|
zSSRYtzX-I}WP#RG8ybV4-<n}emZyno=XLydkWR*)I=3l3gz=yg057#F4Idp|(b=Y$
z*Vg{BFhL}`pDb2Bs%wt&d{xMY1xl!xLc8?@+BGEe#f$%HwoI!QPHQq>4xo{Y8oP1T
z8clqL*CXCJ%%88i)v9<*dFmw{7EK?QaJXlzUJm+C^bV(6H(<%_ob__jAl&m^{bauR
zcK^6rUn=E!tS2t2fAO0~<Qgd{s;+s(Z>y4#W)bojk4koZXo`5UdmKJ);cYSviN3$Y
z-v65ISJ^ksHVY;z`Mg^C(Qi-qE~3(5meZ!6r`q^ewD;uw#cfQ7s%hrfN7~%5>o(JV
ztn#nF+0VqD%%2)RY;Oz$nG3Ly528UQ6HJ8}T$M at p=SuMgs!%i}q_bR+9cNt@?TUxb
zytQ-3?z}=mWq>;t0K+`Q9$q_MeG<oGamSiDDw8tW=@=Iu)+)^hYUhKi(kBhX)1gC2
zi&=d#p<enbU-1e4TCs!A=Dg<W75C#4w_zSw-?#8-PnTib56oOS*5+SasDCHWcAi|Z
z+R>2r2=SFhcp_vkwhX!j-Oc5>>q{)0x9-}ozvZR~SLZ0FJpatPCiZr{OBkPxSNghA
zF=NX%X(M_HzZ?A~thsMr2pKJQmHAb9A8U9U?NDmCRvxyb+U$d%Z}Ta>I4|1guxMm)
z`Gd|d0&QR$8zE<uYg}saxpiJ~>Zj2AZNCCl2zEzVtRvCB#B{v%ejG<lM;$2mL3%Nf
zFH)jKI#UxoAj(i=Ci|0;?#XcM(+$FTycy3y3|O3HMU2<&BSAT4)uo4&SA2~CeL~oc
zwL}cp$jiR>*%oJ?xgMXA9`mT|i*uTx$b*B*>pgM={D3wNuay#+p at HTG-sU*>9UXPH
zav?1ALS$2OYUoH&0`ab2Zi{YQzlwX4mXX;~b%a`h(7U2%?a-{x0LjD(B2i=srsIzg
zI2B1%s`<Lp6RGxB#5)ti88u1?^T~dSv^X3N-=dARnLx)K_kPo$koo8TxBxniltbv~
zaQz37m887tg6mdc7t4Y}VTU(*cz~>OK!)tKvMbRWM|)GxmqJ`$W;6wb?;Yu{l at Gl|
z+rQ4QcvPNv8vP<0jV3E^SjwzWa}jHg1!SbLllUqiEn;D}%q*X|FhFDItG6Dr-F<Z)
zMDFaC#72<cHGR?l?I}6yH>?D(b*Pw9FfUo+*43u}r7Du5$~>znlAzU+parSe(X*-J
z)fr&PR%V$#W)@AHlw&HafGISU>D593Gl)ecy|lVSErs%vGJS)#%(*G?VnG_r7=ol@
z9$rm{;>iQ%6nUlumEzcO<^+Y(mCVoH@`Y;5ky&}a{cpIv-12j&{BN4>B<SZ$QyZ4J
zo1aTMCaL_r3PpSlu`h;9(du^kp3A`oclURX=UJs6TW#~3%db8X2njL*1ze95xcbl1
z at yi5-{5-AFSw5=Ma~~Dh+f=f3UwC*V_N?Sf+5X69TSOdT&X0<=>3yK{U|BGGe0<D$
z?cS8<#RsKBGMIhGwBu|=IK^bHMo}+Vi>6htrwN_a%mot16GUO6TB-2g;v<W<WFxLK
zmW7GK1;A1;B^;E at 9Ta`?EEGBG`naC~(J#Pmf3gCMrAkzkEw%GuCiMA_#gXAObeOwb
zxdy^H5(PyPGV$~mpQ${uE7JVR{T{Zk_ndx2lhudQU!Q0j-{uG&H#j48GiTjM`92J>
zxb}(pHgv};lmf2IuD|ictN>Xpysi1+0#bZ+yf)9h)}h!mW81qksRM-x0>$|4;q*BQ
zupaQ+Gr8{|%KiHs0!~a~Q*w^czHpfeRQ!M%W(OSUUUv0vD_T<g7`bexq`xobo<~Y}
zLvGQpQe#OqYNr3dIsscJJok^Oj<;ZWZEm_z0<LF6hL0Ld+$04(Y~Y`)?CTweho6!{
zf=^H<2pmpb-sgt~pZG=dz_uUb3XZPf>`9t`mM^&&ubM-pO~-m2Uu1H#Mz3gfonsKU
zu&aD|z2HglWbi~e{QbV;-t!dVGFJc~&+#3Ahm88>770>IB<cmbt*YMN!B=mMR=+-h
z)dtJdz$H*CXN|`MtO at QmQMTX{tO!JytE}2Tpjn^2>aS$xD at uL?H*_y#r%!ys@?TJe
z%BrQ8^SEsAYn-2>nxrY|sqdse-BdoQ!aE)$@2LEp^4onM4VIcsCGZmx(zCL(>eaOJ
z)#heq65Wr}CVq~#T*S<;mhp95a|=G3Q_ZaTZh)*CmYyyABf6EFEpnx_560>VYOOSf
zrqlKO>!0q=$7gCbj0yWyCf_|@$y$%tr8?J_p;g{V3hyl75{76Wq9E?$>3<mjp{ecf
zghqbZJ at 8(p|C9nIHnvUg{>KRhhoy2`y#q7uyM1rU%8jknoX>vSZhD!+R(qOjs_(TY
ze?NDu&8n*y0_I4 at m=sP8t8R;zB at M)KpK59Jyr%>+tFA1gh^7Iyn?_+-_Nq_i5V%#|
zf!{Pqq4#~c(BZAu{!()LSy*LJSt8|I<fzv&{D7xy-M6`C(o~(Lf0HNf6NzJ8Gyuc1
z=_Qql at kR&pBiN!KcYmnv<aWsWq7Gln(!)cibj+jp>1nQQs370{Q~tZ>Z2bC%M7{$k
z!oPZsl|s$$fv4?QT~yU2x|y>HQt0=u334zP^KO1(A~xFd;Lvq;MO~p#y at YT0u7$W_
zj;_+Xa`mx<!DetGR%Xr+_SyH at IKM{MT+sVseLHlH(j`*iw$AzXWmLI{R$+FXLQ^7^
z{Gmc2EYMaLBC4T!w!m=Uq*yy-26#yd7SuCj!Dy1<-cFpnviHZC6pLjw=vz`u^7&^8
zu1m!X)|Y$h{vJm<k)-FQfXUVufG^&ppT&27asI^5nN$6K|06IpGvr(4yf+0V(pF&L
zOQ3z$?uq42k at rxCmLzOu-$8;+q+L2o*$I9nEw5Laaof at 2xE0<Yo>O|C at zy2YA^_gu
zAZ9sE#(<}F^+A{s$bEnwebh^m#9Es_(S#unw at R-klrd{-ND?SJXue_l%JF~O^oHvb
zw1}@pXc=--yKM~n+oO~Q1_owHai_6oyxmN{^xk@?d?}ECAu2f*?D*(WeyWsD91B9u
zV&crX^4<(+F4oIJIdfr%Eu<C$u$9T~n|8~CAz#xlmkzY?ce=c>gUq8=Or9fBLxa)t
zE%3+(%C at XbA)UPRC%LCASHTtVi=kU)2%<Gc9(=C1sTbjr4cHM;adIlxS}UN<%5FKP
zG0$H#vG~Kl9lPCkM at f7|i`GmD)`|w&`pwqALB7x2y(QE3%n1jUi1r$hhr!Cjq>gKJ
zU-(_ij5TC8dNi9RN!EoYbQe}}KV*LQK-^LE(SQGqf$s_uvqPgyrDxaI%W2cqJcm`E
zkoK$jkMq}SSGH}t!(S6sAUwCh9TRj8PZ=scaM8o7za6>Y<L8p6yQ}Coq*ev9Gbc8y
z`EOSrP%`hLKOQFk^@EA>yVUv}G7%rBUpFKvLXt*_W|q!)AB)bNA8nr#Klwb6TF>eY
zl?zHDZbhH-e%ap^x1WX(?}tO$m9>|v71Lxr4j1)RfNR29Q)Aw?%Hh+2HDmeQ&%=5<
ztOcRDX51K=`3+HTNZ&p0R4XN0fCQ7eHiqumgSjss(DGt)tKZ6At9a`VSIB&PDs>$$
zpWnY$F|1tknc}`|LK6f|i_)jcr2-qbHC)70w1xI>- at E*~C6Hl}Xp2{H$>>kYhksu$
z!>^Zfi2X0fRvxAgFTOG?m#_Kle7)E at W&^Gac7ti`b{D9M*J08Us9xRwaWi`LHY>(b
zU01JtSHJBP-TQL#`msXf;&=A^?AlF*eUo>vb<~`3TZ)F>P_oL at u%TChMf(#`+e3%1
z#<$i3vd7bJ4$}>T2eztUcJ?`XzJnze_G#kwQxpTg+nwgk?Dpai$UN2by*a1F1>}<)
zx>ubEDhMU9DyojJBw+FPQ1wshF{7wiBY!l_T#PTbqL7zLnbk*?;;Dh}O7EULv7CO9
zNm<8<w<j<MOKZ&(a{y;XI|T|!Nnl5srL-|S at x1d#P11;{33v%sdstia<jir+ll_8N
zlMFb%mODgda7~oC_T09qGR|*tPF%}pPJ7w(?Cle+S`;czJYR(`{7tdV5YfUAj^Xqa
z99A{I)!7*UfPo0oJKcNlq6YYR6<}Ic?C0LHLRlUu!lP2hM!C+OGT*dj3Wx#I%_NS$
zhh}0hyjRr;KzT82^S5-+dsO~a1oe^Y?X$12%F*6p&*NuO at YrPU+Qz~*yz^Sg7$tn@
z;#6J at lrG8pyvkh4cj}96H=XTs#Qb<@hs~UMP!juVD+mIAemKgDFR2IYtbwuhTrf4K
z22IUkUJW*F*ZI3BulsBt!|{$ArM7dn6zj#Q+ at _vgIL-~7`4m$zZ$7B<x%~?M^}uzB
zOu$^}a&Go+v1I;m)!!o}daq%I|NQgCVoOIs;d4j!l&s<1n(Oh-n%ZF=_8|+xFN at 2-
z>iFA3wSDW=hn3YhuFT`RKWm1ix$x(x_S3cOQhRN^`?Jsg5AQ$_zw6%bo~zINpYQ7>
zA3a~0R9m^R^Ywv0d%4!6q-J48`=$nT=2>UyU%q^${_3)wYIbTWw$|&jH}BA!&RYG5
z2<Z8NWqQVWXDD~sC-g^GJV)>T)uZ*$H$JN?AF3;}s;ZgCFnC||2kHkV(Zuc12JHTQ
z3?Sz6Mo#g6wPfW`<&V6!>2n|dhQ?m{S^fQ6pRI03I`(fqt-G&#x-R?7^}6Jb&Q&JW
z)xeP#=-uzSSjBc*M_%*}z3W9^(5J5cx?Xw4>H5T<ep^p_-%s?R*Pf%9nWm2U^G|F2
zb6%qBe)^D(d+LZ%D(J~Cf3x2F>=Tu$RCVs9uh)@Z`Uh>@U(<=l9ItnL{_8sO??0z&
z{^@`J|LnbaoE>GEJ$~M*yWiVeI!R|E`$|Ft0YO1zQxqLQ1yMlMpW`sj$b5BlMn%wZ
z#03=>6b2aq9Z(S&ktj2Yz^EV!%94aF3t2lM>GXQ{rIz0xw@>BV>Q2%L2_$gKPd<ip
z-&<Ah`_^0MJkNQ~gC9P-5tY~!ob`#T@$C<vQqQFL08Bme>IWcS?=6luf9ZDoc)?Bh
z at BjHNuKMIRvAM_KsB<pFl~;ZNuby0&#d^6OJoe!4u_5BrYi1HNG5yHbV^&uZW2)>o
z%{}9#+(Q-29mwZ}=U_BjEmyf;glo+d<TEos;KR>rZGqYbhkL2$_Y$PC at S4PdSr#4|
z at zq)pb(GSM?BODJwZvuJfp)6bEDq;^08=Gant at P~p#V2*9jsmLRcfaIQDsUbI$BSp
z^(9&yueCR<0U<ypX4KjXwYw&<)tU{CIp<Zata%^WXp#V1>ogdx=e1H6r{t4FizGs=
ziJ1vx7DF9pNrtpAUL}rNVxeR~C3ZR%Bm>N<sol7)XEosp_u1q5I7Ylj$}=g)(;6b3
zKmJ^ap_&eG9!VOs0WHT$Yn_M%bPaP}wZUq*PgA(xlV-bg9g+-kP8D}(UC#(I6V at E=
zPDdLqyxiRpjYjeNKR<;}eff3_X7h+d415o}aRW23EQ9{RJYIdoTwM6}*W=hDXQMrn
zfHA;ezKTEmbq&6C)4izWda>-DN3mwzc3geMdoXSC*qht!>HaLs2U0Wf(d%x(S#2d$
zT_3rj?YQOh-$M22|H0A;w*=Sg75ahdL~O5A(cL$QX{R3n8$hL6MKL-9Crq>Os1KM*
zKc4F^W5z{C2C2EcKMlvvkKnOQtC9Ckh3|Waw9dt31Ng3kVyS}u4Ugc;_g{=>7F>uA
zp8XEApbyTPhw#im88FyopNQa}O&ve at z7Go#EV=OCaO<jPalyNf$M;*~a66B}xyNR3
z*Y=5M4aVlBkDxX)GP at tAU4iWVse#wRbVjiVIJm*4)9HFm$9~!~4%YGB?X{PBuzH}1
z8E at dTT}A=Zar|5xw{<^<qW4<B_YiNLi%ABkxejXO8ro+~MeoXfRQlIoWe(VQ)fwpg
zmVxgBzUN?YsEm&c^~3X9;F~DgGwm<{JkJFXK>}rzhhHG$X1xv{`P{Mi|2|PbZ|^qT
zcjIOFf1kVr$G&+5&W=W4%y989cE0F5$AJf{o}%|1_|d6&>xVAKn=bk&2D1fhd~z8+
ze$GGO%Tt!(hJU*NmSvEhc^v-jhFfrCyfn;R4D3h*zUPm1KpWQZ?)u^EsW`p4XY9Xh
z)&AZylw at cPjP}OR&g%q0TD!|AF6AqX+!GjTVLNdQ$x^sS2 at CHDg0<I7K<9 at +EWw!K
zqe7t&04#z=-G_OfN{+M_h-NdiiJ at B9@_Q5vsw7Gy)k at qnGETxnu&1?T1n30SDsxk5
zkM=>~JQfOtfYd07Q`b4IA=2y)zn}L`aH`j at SrY}kYIYDNF=_;{6T4YKHbhB_5 at t&H
z!me9kgC(ttVY9}tWw)9rFv}G_kIJx>U}zRAY-XT!>6+<LV#5qhu~=;QekHs-Ka1~m
zU!}vC+HtG#fm$<jd?>@?`L!nv=YYRYLd12!Iz5gtf2O2RpCztMJ}V at bp63P4Qb*0q
z?5&1&ESujS|MCnz{>9r-E)`)}W{)pCV|<j#4zBpv`MBhQQv%5oC$F<3gE at yCk7(Ou
zeB<W(P}}w_o?f#VpZv<t at a@lCfcDmOT}HKEBnJkOC=iLp;9DM2sU%urF|?fWaol(9
zMMxS0kHxNuc66Ew(y25G+xy|eMYUQ(tvrO at ybsG5L{hD2PsY)=b~9YeLAg|hTOGiT
zUI&ReU5Fbm(0mvG-Y}`yvEh%nukr>g`|j7UxXnS|mM8FF8}QUF#xjr*cpg08z;|6Z
zjtf8H1MuPatvKt8_n~;jc0Bdm0LD*paqTI`AoKe3Fav<&A3QJEretLIQPvlW9H@^z
zH$85&v=JRkX6EHNe?II)D>@P}tX{hbJ`O{vJp63;yGXQ6KomY452y`p#I_R9QY)ie
zE}_udi)5w+E#oF*yfIkv at 5}J5bGlHe4tE-l#L&?-3AIvRKpaM7(_Ih6Vga6CcZam&
zNwkiej8o4%6Z3EUB_8Om;l1-((c0<Z=}kLOt<Hqwcqo-C$Zp((nmrNI+JS1Rj6&5x
zEE<KeVn}5ybS-=<{`P{2_|(RA$X18#@xh|dorW$3ql06|ap1Tfhzs2sQ2&p*-r8|p
z#I%o%<J4<#Bq|(s=Goi5q`7A_N>dLckr^!jqFD=VWU1K-0wM*1VX2N<JFBx3Bg$$)
zt3ZkW#`+bK7HvF8`BOTb4!|EXLfYt2`|&AW3OAOdjV?hpfj{qyq(bfPmEdVD0qvZX
zv}tgOpCvF3JF4+sIhHK2CPCpoo=&F&xfjQXMcvxHoz}wIM48zWS`lkTjOGA*hj0wp
zbd;onAe;bJNgE||YNkNK$9JJ-O$dB-&GXu|p{QmCSc}4r_1uFhl}b=!q!|p7K3*pa
z`_;->l at m&|ltgiT^E=h)i*u!R%gm~=w~sbzEf$LnmgRI#<2uq_K&)M1=1|ucuQl9%
zDH at F;m&=Ws0oA=)?~?%pj-yIW!`9zQTu7Yw-TYoY=cQ7qL6u@@1dM~VKWb)t-$(cJ
z{rJ+gzeKT67_NWW{f6l{E+UaAzW?<P<HHx8QnzAu>$b={2eu9#Cbvb9>YR$UdB-D?
zNaB&lSK+JI-!1Zq7nUZkFEj&9aYPesIO+7$(DL|QxZ|-csF`}<Yi+0-8+&}DGLvxT
zn_i7=KfNAzKD8aLTgLW3{R}@{>mg<v#3J)>{#i?~<@^7J at 7?zlwrt&mwZHxrzVqxj
zyy3hzq7@!2A(I9M(O4AebPJ;8ZCKmggK{N at br1gr4?NNbchqj&K)GDR*3BESdGlrr
zmK>C`z1Xz=Ic)DQ!b4s2{`>p?4}X33dAQX+JaFA7 at r@m?!WX{qCIBw{gZL%f{NwKt
zm>ekS2n!wga at I8XO9L4FQU8Y*c?J8v4=X(n7oM{S8@~5BeE)Y(W9!yUSp7fW!1Ze;
z;iR)qMg}f?SSarJ1Frked$6v13${LWH*Wn|H%@-tiI{lUNx0;^X?Wz8Td{IS6?Vji
zam(o4-iu1P?ow!lh>T at e-{&LS`!xRRyEoyUhaSf>tJh-v+Ld_l-uv;~&@7xbw*@Ve
z=HP_W=Ht%q+<;&HaXHpLw-%e9z8BxV=00>B^Fh32Dp0NV;I8YxkK2Cz0G2<!8ta~0
zjpv^DHGX+t9~R77i1vg9&-dY!bJ(!vS*%*M3TxJ^!G;Z+Fjy#$81-7MhJn8A*tC8f
zwha~mRPg-zb?AP+4^`JishG#=zx)P2zyC>8y?Qol!- at y--#`BYhTOUgsDHx~xa((k
z;+d>F=K8>JCawABrP((WKx=fKnSqv;mIjclG9z`+A{ZjMRjCRcn>2#1*&l*MO3Vn-
z2pn5lS^_DYW`lTMtx+JTQVE<Ags`I;?P&@6m`P$0wPrL3f(aOT-CAfJb_v^wo1B0Q
zB$LSzl01!elZbF`QmIrBHCI5Y8G+FP3EcB3Gh!A<$tlOBrKP1I6UB at M3(s|4ND3(%
z;~bD&h3hqG6v6xDcWZ42*N$GF5>TB}7QnMciy59`u^5msW-PQMgLOePFwovUN_Ysy
zd406NR)V92{NZ{Ujys96y3MhepL40ioa4^tO|zQJ>QH*dIahg~1}?R~lGYcc)9GMb
zSf at lHrEYNySZDwuOr-c7Bx5R54HLu>nHd%X?T<bc^@*`?<u$*+nho1gcLO!M1R3?y
z)f=gO^)naZl;an|b6vn#L6&7OS3<4kAel;GTYnip{oOjawF;uK1X^ai3RwRrmfia}
z+FO(O>_^XSa5>o9YmX=5Xt9exF^if6Lv1U9d1w3`e)x?cT=u1Z#E*+rSdkdgZR2p%
z1=r)$<EG%)5B at u@eeM!`;+!{O;^YbFJZv709tYf?^I*ZoDWCigTr+eju6)m#_-ZnW
zN;QeMUws>{c<VSs;34H at Q5q}__j>UWjYKf}sB`cSr~C?+zxQppc0xPaCyhs9TpU9c
zZ<I|2NJa;6>*bf?2Y*?E!Oi{1;k!8Z(f>l`#2fJBPtQRHn{n%x{~7l_(+k)hl82p$
zZ`}Sfd|-wT$2qvWvhUBAaJV1Ep(+!3F|J*;>zak(#<#bT^L?i;^{BoD3&z-W%0FTr
zefYiyA3i+ag8^WS73 at L2&zG6C->wRN0&l$H`?$JrDL(tIGm%KzDA!u>?(h5rpLk<C
zYPlgqY#*`qSHXScYk1Ff>(IYr5cA*t4SeFl*B}KS=YHc3Z28P(_{8~dgBP)3MbntL
z_$|2V%ZFp>)C?k(L1c?H_`@%zmQ)PIp&UHRMkW=-hTq?eZ~f=hsCX7Ew~ShH8ZP|C
zf8wIqDFAU?^e at +<_tPK8$1Z*cU`K&k72}WlC~o`q$1w>WoJ<R>Eq}n(H~$9)3l$jS
zq2~CQe)1Lg*2m7p<dy`sn;gm;ev6O1{S2f`eb4r4Nxb8W-@{cGzaCMjM9jjDXYRoJ
zF8DfnD?NY*Tyf4xxN`E_@!Pw<j5$ez$L{zvF1hDz*z&|ubi^!d`@_w6?`0eC(BGVj
zW0EmgYwyAZ at 4p%!d*VENW1NBO_%G at 6aj5PY;T~o$)}BF-%Pd3yJfyyZk#K!yhe;5N
z^%Xo3I4KBIIgu9I6U-3=X|XiPhSnl58=*BET0C7W76US-%>`Am#lm)NXbGUf;Y_7c
zjP&!G_!-SkFw4avZzT at ePsa~QIhp0*e`}|B1&CpXI1(aev^1-sL2xAw+Dk`kMfl#J
z{VwgSwb5v)R6;713hsf|qBSZ?d{l18wZiNJ0Ws&9WJ>E(_`RGflDW~cdd$r5oZ1^m
z$u+Sw-OIG+jApPn-+Yg%34u!Rl)S0im)7oZJ!}1r)>+Z at O#=m7L%Qx#sniHLp7!G*
zIp+Lv&bju(wJ|Cm3^&PT=8r#T51?>{N9)LV{c5HWG%>yP)?59v&ptcwCO5|5`RAWU
zTU%Su=OcXBwvFY>mt*PDr6UR~>kn}RcijC5K6TX{h)2h=>HDZT9^Q2FQMmdu7a|g=
z7n&MlVS8U5mtA!m9$m2(j^iTJ+6upYChV5+uzYv83$=~n_I0TCu7e#-;Xl88F^*n3
z8}2BD at s&yiJv}{`K7IObuFJryWRWccnf7)>ea%)F7&s^uiYQkdz*w*%Q6!Qn#3RF-
zh*L&BUxEV*(L at R{r+|vxindIoZuwj*AzvuN at c=6tN4h10s2MKKEDa%Bi=(|g4R~%a
zK2EiSLZJfB7{ua9SY8!wG=tWJJxY<QhhjE|itE7`3x*NvNDIcb#o#+N6bl7ZYA#?|
zh{n^%q~d|A+)MewrOo2Xl`FAi$&w(I8rDXS7A4x3$e}i2I#dou!g9GB1_lODEEch4
z%NCq}{`tEdr+qnW+s5OMKaL}gI3n1XHNr at +(A(RKWHO1iwzge<59f4mi?aP;0%Dm6
zEMvho7IL+I3>3E_SKEPnwGX}z*d~H>tOJ?Y1au at Pp(QpBo(Fhv;rkw3-$Beu2BgUM
zJ$SymM`Gi;E;eo2ggJBO?BUuCe5d|wyB=Ug6Uek?V0#V*OGP~V&x>)<!xv!X at -HLV
z*9Xr;k;=3n5#5=t_nmV6^F9D$Ar?;}nTWx_Lp48yS|o!^DhA*4;JY;x@?|93S`mSd
zTBU??wF;;HVc5|)(&-dzvlH03)e?%OO8xsS8;Mj4QgI8uH=Oo&DyWpJs5<pM&sY&8
zQfVY(Hay>lTN*^R<TqF|`#um)w;&xK>1gNHO2}nPfX%3)2j3*n)|Q4150z3DB{z=t
z)+FG2sFjPzmwdE!w7`N7uUbU5P(iZ26LI5>S|h_fWA*CQm_B_vCQO)c!1fFlFCS`q
z27z5Ro5kSZAPR-T0o^m6c;X2xUc7jO%0u at Ij-?iV6F^bYs(?)asP=kMiHb^jw2Qcc
zUTwaoU|ai}XyJ9ZZwPy!sYH#982SBlhoVH6pphhn;E<UFk`}dpCfFp&AfaGXUL*1f
zAXTcPgh;!=lc;G^MiMY}D`RJOf^mXX0$R;vDd^N^EFO;s(lwQLDZ$jni at IjRq=h7k
zH6RL_nV}08)~ijmk~wXlsw9?kPiYo214>Mk#BeUP5hrWBw0=bisP-<?tP!PE+E`TA
z2iLqh!6|toSyCdRMjIp&YM|l!en8GigsRmlQmIr!(^3W|v~XX?o^zzxFKv9v at zPp3
z?Kz`;i8yck95Y=?y15RFF<7>2Sv at nu#m$FKwWniA<A*Z?xqJy<|K6_<j~V!504|oP
z7yX}g`m2!`ejyrTuwqp=F1YkN7#hr?wIu}ugTcN&SpB_7PhWy~$5fbMP!jK$gmUjD
z_)Zny`_cWlcG2_^k+iXBhY6odEQ9vAf$ur+MnEeI at l*zhv>EZjsLyB|E$s>UNjqWy
zTsEV$<H)qh&;5F%PyjHAR<tJ#e7Dh2&W<M0){&Bbi8ttq!=NhJ(u$NBU0?6RLL%LQ
zq(&J%_a%=shTS{HGH10~4TWM6(MSZTWCF(8HNdDxf@(-6<FM`e3n$y(11mEDlRH}v
zxvb1+H8cBLMxvXbT0*MqOr2-;v}f!sX!3{qJk`81hAKT+J at 5xS)q5{C=T at Lp%OaMH
zz$RcaK0Mb)wd5fY$zWV^8fLT|g}H67#mx3&@z}OI@#n3#VeYu&Fg1MyX0;uQ*7yX(
z>=dF_0-is5&EVMOIez`w*Js;v;0{NL6Sfc610t4<_V$h-``Qq6vE#_J#zPr^dIlt#
zZbQtNde#~MtO(Mr85sERd>?i!flNF(BCz2}ZJiZOpe2?ZxhHU*?HH1oIFh3fIsmZZ
zt>{RYT|U1f_V!2uZQ~OArkX1N03ZNKL_t)ejB8y!98I(!3e?G&@57EI(H=K|U;jBG
z3AD8*0k{qKv8Qb9p7sp()<~t2u=coT)C<xHQnUR%Fv$)~n$UqmrE8Mz6))DF!Kf at r
z1*6{tj08jB=7|I;nM|gk#|xz|YU8T?J`_+hJD|~K0#{nZs?0 at e05rl*0I9}E>2!L8
zD;w{R*QI?}NPI{@Sl__^4$l!YC>mi8JD8DJ=yzzAN2Ntd`oi@{N=~%bi58fvvzfZ2
zX)Owgh-QU|DQRuYIpKQXxN4smEtc1@;W<<;rKCw~r1(e4fD$3zKV at s`uBHuMIX-HJ
zpzDU?9F0bU+9S224x3h}6Cb~awKxn=s$(42F6V}lJl-!QiCiZnbKy1#9493lYNt%O
zr3M-JtZLSavOn^Ka=9EdHPyNpZQQAuEG3rOH%Wt1>LjSLL+xk88mAE!=z7Ddlib%M
z8j0YWH~ufOg&GXJF#;B#qb-BQ^QYC%@B1i~YPjmUWhj@*Xlu>X7Z-e3whj0`3R~A8
zn(ly!)LqW(SOQie1;3QVid9?ir$^V|b;r!#txRBVqzZfc^8 at kOy?xodkZU+tWfI|Q
z&gJvyUiBDOJhcYXPJRzgpVx+(+gK#YjV_xV!j@;B!1m}=oOIMYM57i49{UY`Qa&1A
zyx at 3v!%-E!i1`49Ndq?)wI0-H(B2$c{JE?94ikXzSiBhXs2X<ac-2~zk-+^p;jpYI
z3blSb(|aFQ^#2c5_dbLgN{B}i at O^`rm4c~QBZ3W4%ZG~^`YP+u+q)JIb>E8C#6-mG
zBy!GnJl=OF{@U|1crGwK^J*-fa2lq!z6vwjj)7f=*85EY$gxYt<CuB!d+~uOuR#LC
z<{ta-Z0 at Oedw-Z{9Eg2mZ at zPP4rTje&nOfM*t}*1o?Q79CZ6~%ylFuv9B<^FVcRxx
zxg55vS%GbC2TnL<F(MHQxo025kG4$374JVCw(mB8op60fc+b$j3yhw=7<<NOfyftQ
z&sN)6?yam%psrrslNf1ck-uhh)GbSkhB<z$%OGK5FB$GtJU595vnt`JweJ543<>PC
znWs9YF;hd(rN5(*bOJ`!-DsqIv>qDjl%+P!dd&ox{2YO$X3$fq)TmM{%HSNw39PGG
z??RBy?>55?eo5B!{i=4vnz7KRJTp(sF0lqfBl&83t!th2E0m5gvqEyqvE}_S2%(nP
z8r>%#=6tBbnr65(3#L}sI^PU-sF8u%94o<8xfFvcB*dDHVnb6(EOjk}=U?|2ts&FB
zh4-(Y;rQuz>pA$HymqZw<2|O+>EIb77En_LB_b-VWTuMqpxGj3cqpsn-*x=ejjw^s
zFw&|I{yyLj3=9?U;3I2b85d*y8pm-laeO<*k81^tfdydG^Zi)y%m&1wBV|-R0KZm2
zE!T%c=V5gXyk*0VrBKTcU?^L_!%sYi<BpnJciMTGb{&5u9HSNUYU)3qAHwG458$?+
z-igYSlktZCI2R~ZP%ITOFqi|3K`IeLI+aAZkVE%V58?K{`8e)~*@*cLI$v`(J~OTp
zp6g;@U=W2;8PSN1L_CVtOd77|V at K}*tXLFL--8Q-)=UbCSQOb at 5xGJUv1kPGSQPE8
zX&4xc)uGn1ENtGq8TouZcv*z+J(J0xtE+27x944r%Yi!7kw{<m3ZC|t?8d+#V#o04
z_Pg-VwjW??{uwxqTQ|h;Q}Aj#>+k$s1x!2x&ocll#H<J^P5~9C0N=A=T!VNlfkop_
z!=&^A6sv<+x#Kr at KEDblPJ17G_<>{Bemfi&Gv56beA at s{t%hdzlb3GK$mOzl{@I7|
zvs-UL-=pL3hVNepyHrK7RKmbu7BB|ML=2f!5|u&@+txmY+g7FVsv{PlE#jbc at oD(v
ziQ{1VE(V8&kk6M8jao>=V`xdI;QIzU`ubs_QAB+gE-bX9lSsy6$mUDP<_p7nMg(oG
znZ4dKy1ToP&*uYqQTX1|=`<!yn$)moyx74Hl`N?(tr9J5hNv!6;i#_a^eJ1>qI!NW
zU9kWJu1N%R1Zl-$F=)!Ejr){*sx`AliPc(}KV#uHuT$@X-=|GIwSIub=33{%bE)OA
z7D<y75&#o~7mLLPaHyFI0)K7psEtH9AN*{1&a at s<?~V6LD`u_h(RHc)a|qg*P0*|m
zYi3B=)a*dzMg-&9t3=Ha2<&-3;pWb~C(6v#_(2QPIVZd}mH+XaDy>uLDQikdG}V5Z
z;}>oOsdK}h$K&yUV5&5Y<4z*NERz~gXdMynQzc^BcZ$yrKd%<t+M|fiq&o32)2R}4
z-DkqCcbcgQTX9p`M^g*VRTy_ at kR%{${7WnrYgkD87QF?YS-S;&L#5$GHMULD^L(U}
zF(hI(T+f4TS;*zfs8*f2V~-gbCH8&5bE+_w1>be+5Qv)CXbg|8+=ybiigYs8Br}J|
zvAam)X#Z9!l~5RX9?!1bic>Fo4<7#EE%;UUJMp$Q2R%J~DD|zx&u_R9_dVSMt79R~
z``1g+`@8?cn&<zBi~jT at Oga7%ymRtn`0v^qaMgQ`Lf?+fSpC2qxasx>(C4+_#Pj|R
z|9HXa$PKN<&p!Vp>^SlbC@=pbHkZ0^(PzJeQzw_O;s1Vw|M>Ae=q~uk%s&g?{raVt
z-5MElY`<2k;q0@|-es+c=Xp5qyz}sx&wQpKMf+kOjNa*sUL%RxgXV>1WQtA>cdq>$
zo-5stQf~OA>Kkz-9_#%}wBM`mBgPmQSV$+ at Fe7s`{<{4REb2TRsb~jQ^*)Ft<KKkV
zc-H~hGrU?A)#hXVl9HTqxs3c!FV?SJi=*FhK33lGQ{1`n-FVjo7dv|UQ66{-%l`95
z{CfEo_^tEs&ddH4m3w}LXEsFe!N- at O^QaHu{YR|F&z_%)&%f_v3~b+m4UhZ+-~Z8l
z*j`QIn6o~BkA3iOP|9z_9iRCuHoxW!;IZFhU9JP~y8J6RbEbpMf4m*n-*PuLWId#3
zosO?v^>Hko7~iXX@~pGYLVJ7rF89XMPCE_X{N^`<#)!Mi%p8cdPLQe at E6u`CE<<ww
z)#X#d61K at Dc~elT#6mMQnl&kx%Rwf9b-)Cb#5 at FADmM$;AZyopeitLkjGps*wSb=>
zQ-QSBrD)N;Hf<y^AlOsFp#51GXd<9xfxTt|ITz`4I*|EM!lbo7+`~C0;iiTB9)fh<
zH|Ky^GbL4pLIIgfCdh)Z4o3kk0Wv{0e>aoK1ar at V`tUrd6>}<;3gk=#`RW9x1?L3p
z+89#J52!*Q381V=$&IcRf_nB-VYZB8r`FQ^Y%Z4z=87Ply?FFGNUT&c$T>?S62bc5
zd~qCAEuv-vTzkA{H7?MsRHaf0-tF2qNTpv~Gn#?bz^4-ONF)-->6n?)W~N;0{9awd
zTBF5tYyC__H#u6+g;V5vihL=VS^4ZH3=C#rnXv(my3^3kg3_Iu%et&=w8C7!-s}KY
zG&x+8GaU7CYA}`sz{ko}o3L%iAm+{N8dbt at C^qkVxgW~tcUQZ>zh|>KWVb(ub$xAk
z=ke#G<Inftt{**wQ~rJ_YL!j+#aFII_T206;H^gk+gIU{{uD}YJri4VN8<+{{~Pr8
zZpDK){Ryt^qf{*6`IYzKwm<p!!krIdQr|=P>g8AA_Q{9gEej*?N+l#GzX at Nu?6cT(
z=f`l_*KWd*UwIvFx@|d5|Kd;ap`$x7w0!`POk~XV;I8Xp`t<3z>#n<S at x>Q6M8imQ
zPCM;1eE##FM=qBeF%G-yGjkwnW*BV^+(X1g=Y`bSDFEszuE%YwKaOq1r(tUGhNiGD
z^p-piNF-t?Rf>QULDemx?B&q!tb^?)Q87c<URsT|_ at oA4(cCi*jXh&e>&^FlWOI2G
z`qyLC1`8*jb0KCt^E>?a%@5$re|Zg at N;iJ_rLSPqo4<+Q-+Tfhy=(C2o+O-iybBwj
zn}F|LaWTsM+wiB`z6;m$Q7V<u_uL=xli&8 at 6F>SL=GUIUw=erFZeBJW=f5 at zIAtL5
zT732P%klg#KY@>a`Fb4l-M_()Z~qHk_n9B!*4Iu!p|2l)CN}10)^%NUb#>vs`|iWJ
z=bjq?S<RpxfBf;d=9+67_6#lZ4-=aGow4EfDDb4to**ifN(F=_kw~CWC^UfMR4Nt7
z(6~1!Kv$_1B}ODdDm_tRz?vMj#?|O}rBXpAlL_`-trt<}Dt at L=C<Ivvk`9t9Eu7{x
zFe?-WZd$X$JvKZ~JU;<lxap^w0VpA$%#Pp5?;*KV^2f{pe~%G#t%p!47uO!wAFoYo
zNC?gqgz|eyfYRyoh$f9Bp9+raHEyZEgn{cxW!}6dZF;Ik3tE?<H8Hww!wo65?~d9)
z^YfaS;kc2=r~??+iaP4i&REA>O)}I3f^(xzV3uVCQZz02S3C1$G8tSCNl-Kz4FU!#
zIn<ge%DOU{OkgvvYg)6OYIjZo$FXJbL7!!=-)J-%IGB;Za1O(6hB{{?@BADfeP+m3
z>D;hSQLjo3tJn9yb4M at M9F55Y`n?c%HI at a-7>x2G!1rM%(ulQ;t9QaS^@4e~QiL~b
zzgjBSu=3f>u#D9NATNW6YWPp3Qo&FzhfT|Whw8LN=xS at l5pO*S*@te!@_qxe{UJO!
zxCEEH?`WW0LbYW&rl%d0D^<9)GP0!#a>dH9A$Yyeyl3+&%zgc-SkMMkqEm6)Yv*G9
zh7E9yg;=TuN4()Rh!lok&sd5HwXG<(F2Wfn&BF4ZejA^?@>{s~nXNFMJ8H4*?s`2O
zal{e0{`%`1K>fhL0N(e$_u+fr`yTT7{7c?5LiNdE`GR(d-p3h+ZKBwkdlo-gb1Amu
zo&=m2eB<udd$1xt7POy&lcs(U at eGi4daz`|n_&BKOi0hd4(}<f>i-=KEcj^d885dz
zqgt&Zo6BR{ihHnQ+#<}F*p4IKb~0*zx&;q!2dv&l at P9oE@R3VSfL$)3oIVUQT3nPX
zRXDW at viS;fg-XyU888^=UV-sPoq|_QilSsD;kZ+e#J2U%qU>9UMiN-^#@8cJ9E5e)
zQcQNXAfKL#(@&a at XYafYpZ&tsxcl*qsGBtG-JUUh`gHu at 2R{fR-~cc*G=%fdKOaB(
z(T_KaHMfj+`b4++``NY%ZIvM_=#&2T7yQT;vt5E#=?AlyNok$wJ-7M*M6L7PT0
z;;(L3S{ScV7q!Rb{;iH#%zhAnmdoWJ;?2)9>qMzlsZ<Iw at miBe`HkKuBkN)NVXZ%6
zwuR%B&*vM)l3<iTIh{@iay&IUV3eF-QeEWO^F at Iu$)=hq at V}WkQ0W~1pWs>7DoJHH
zs1}|FM(io$(>W%<=UjxFpQ@~kpHoSn)-v&a)MSD{orG6wakTwOkWCPGFs+s0b#M+f
z6U0Nam;4TnE3cabN*&I4?<$2<^9Uul9A~wcR>K62OSxQbkSB5+h#4q@)JCZq^iU^0
zKF=h6iaV5uYlgNVGs6_BcKY7i2wA1#pr<zn%dWR~)5yZk#Zqtf=EFm+TGzo>Yc<qr
zJGFrI2g^mdTt#HK&x~ywL at W!g>%fY{keRv=RwN#{9l4bP+;U-<(fWu*BUrnBJB(%E
zJAPAY_A&z}`FsIRxf_q&zXH#cx8QTn{u+KQi!HrztXSTSGdfZ*UJ={34Pv4xz{C>u
z27 at qgt3?#@c{olD!~U~KBoeSAHj3FH^z`%~J2V92xrhXtvVo7`^sM8-hleUUapwE~
z0ZY1{$NIHT;D2wt7T$y_ at s0(ZaK>0LM#;r7#~g!Y%a-AU6HY)Pk-(=u^(lPhBOeJ~
zI{T|AdS4H^&x9=<S!_#ZlYNt<*chs8$B$QEiow!WMEvA1y{tE`HN#{7g4d8|uzu)a
zoH6rX at aoK2Sia+KY%8orU$Gl2d;b>;I^Kw*C!SX~8rg3>Xqv~tuy+7JzEFfy-HN~7
zvm9%OHsA{%`y=3F at qC|;zyA3-%$=Qv<(IH++W-!W6yZnWFaSINZmo<$J`aBw6!@}d
zl=JmHqcAuG%X47c5g3E|`ZXRL*R3~=hL5V>iqqcnA<WzIJT^S{B<}sm^{BR8fp@=p
z+L&uqNz4{4T7<jqx(ly+-RqD at Byh<km*BF?E*o{vcq#hK5PTDe5u6u`#Q-P~peUfB
zJCa7T2 at o0ir)FRE`gD8BWHJqs7?KIiKqxq66q`U!duVB4x<-}>@F^V%*9Q at lQ9{GU
zkm0%&%8wLCh66~2LZLx!L*mChnes3#R99PIb+gh8N4Z=MfTGqO at b{D)RjXBGGMRu#
zaZH(6Q at NhHlBo=g05_dZ2lK}9*Y^vF4C^t%H50tvYPA{!-&HCWc4FgaxZXIoD%n%Q
z6V4`ae6{%|$pP;#pU*d#M(DMZ3~)}_XGpW9N>;Sls#-d;6h!Nlct0vVRHFmUcBxSb
z*M`<jY4(R!;v`0z^<e;ogk0-~Nc#C)kesTLgwKOw2wpSopEWbZXCjO{xG#*5nR%Xv
zd_Ip<D%H^Gd+dP3Ld|h8lrO<DRy|`9A~K#k9F6fT*pURLOi9DGEYxZaCQckzANb*m
zojAS~3+K;3sa%C+fPArvp+W_z_AaC*&xajP!Vf0Ypxn0wzV86A>b+GggP#8Eu#Bxq
zWL{2W#`8RQuo3P44VK%-;~PKw8Wu&$7#JGDU+?-d{`axJ;H-aqJKi$=7r5ctU*Mn5
ze>GYP-PqRlDopI`K<SCi*xuid)|iEOto{gO(ito`@<janx_j`)qh?`AvKtToWh;*O
zz*4klhF}ka6U(-dOvPb*gG%3O-1Fo*OrJ9yix$qqqxU|73hce^VZjZftE&quR;<9~
zmtT&Le)OZr<#MAE8I9uZ&;Ag*JHk44x~r)B%L|#?Woxg*P-Q!O*M=4IVOthl$A_`%
z{T-`C0KRzv850BeKC-2LEbIO>lC?=Vb>@e$bo`n1P1CJlQ~oh*&aJ at I%;9i-uSsYQ
z at gpp)@?ash<+u2Ac`3ej$9HgKyo`Zt9#8$|tN6)Z{{Zie=isb)x8eG4-huXuk3)ND
z3%0f_#e~jrsBGPUZM}WyO4~@pqA&nbsU&6}c^V48xfAz4wgks at _To>!TZOsrd_N|%
zI*1HE5|(8nm5KqrL3Lmw?tkhjbj_H7`3n}{nFs!avS(nKy7%W;pJnbD<Hn7{s#UA-
z{`bEhpZnbBcDZMSWvMU5o}rO+0xhk at ARx@=^MMqG*32Xy`Fy^?6hM2bgc}g at JOuv)
zWQ<Vr{3=)BXG^7006Gb*!uGaWq#cXJg2sp>Y6R_Sx<L6HvjL1&lccd`fZf}f!Qjv7
zEJisI0c|3Y2mmXI17%*6U@=RfvNI)OT8vGip-y|6txzeWX2R5NndFfKfaeVx1gI01
zHn8ON at -teasr`WX4&vNuq&}C+jcB&0SqLRonnhD0%P}H|XNFG4hHH)Aseqo at y<{>O
zkQ&V(aZQsTX0zE~p2N*2HDJh65RzsV?T3jUi4$wM^jXmB=Gx`&5cl&wwHFe{UB6T1
zX8itKF4s_7#%t7GQY4BTW0EN)f+Rtdl5x(}6d;T{BAi4ve$wVuyVJjiH$_fjwOR`R
zhws;8tG?$Ul59b`a|+ye2aZ}W8DIR+v6$4cYf0PunO*qx5C3Ins?zas%Wv1>#$T^P
z#PaIB7W}$Zb1m18a{rcLB2$-{834snrQQWR<Y)b2N2i*{-Vv6u5a*6 at aXh!SisLT)
z7+!x^D=Nh}Qke`gZ+$=3-u@(Nn1T;|`#Q8<djqby@@`lib8+4$Pr_?Xc?-_jcmuBb
z>}8mI+~4Ek!<S&;PzR#XDCQq`7Cu$2;)g%}E`IH`;Dq;HfeTKX2UFaLS&I%wYoZS7
zCw3i%1&iln+W1!VbpIJQ|LP7 at trQlYaS7hJXaZcXw$IVybUKY2Z at dxNY<8bq1rJou
z2-W$9U+ntw-|Lzg-^co)$FRBbSNM)WEFQz6_S11p*SVOGnuUr}z;lCt!lOI>8_yS?
zhUWmo$yid9da9RxBR)p$edWW2=MOi`D_I!yyK%?5kHff0q^<EVwu=erS$O;GE8+QG
zJsUJiO+j<dI5hVRz at Vc&j*V+ec=d&!!09vEP%g%i%Cw;M%)iB|n}3I5xf37w_6=yg
z?s{DN#e3kl&cr+Z^#mMu+$ng++8glQFMJxUOFx8vJn3*OjCUdyjbO%-H{w(ORK(3c
zz7Bt=CUML=ufPY+S%PS}8#51I0+Xsoo+nJ4hJ{NOVA}W=tlj<?{_B at _qJlW)pYmRu
zf6PpHer=yEuZ=PI`OkljY&N at 3HFO7J&rr7}byXq|;=Z9kM{DsIz1HGlb%tU_L#1C@
z!=R*t*Teb;0!f}jK`Vck5%93vl=gtp$TzbWYETfi<|bHXlw5o05D*i{YvV+1q{zs%
zz8eTSNeDEmt?pt<{zz_lKelZ*G{{uTX0=4-IFn$Ja8N=O?(Y(bL{KOcf^|URrt`&X
zQaK`>;*>Ci*9ga4YnsyObVIESuP=;iHCvz=KAwvtlk-bc1!i}&W`;E at YREuhz&Ri(
zP;$#T=XZLZhhnkVU_-5SH(|FkZKuLD%(boA6%q%nuTu#o?@{}<aBP^R<G5(ng#WJ+
zNOhp&xN264|Ic8I_P5l1f@?CIUDLI$L>2(dt+(FlpLNz*4Xm%Hrw1)9ErBn2_!zC5
zx9fW7AI#%#KY0_nxAhG-LGu7(BRypv5*<@uB2nZD72Nvildxn~2RyGHd4-Q*DT%)u
z01MO{5AXc!edx`WVcQYFvQf+SAh%&9JhvJ&Of<&8 at eEFT?LvI#3m2nObzsTj-?3u{
zrcImH1SSVzB$XTElTSX0!w)|^=t|2!I%m;j8VSomv0QIVSSPnpq>?dID;2n&K|Gm2
zJQ at Lf50zpOC8z$fNW`P?oC-=cAa1!RR)(7!#^OjN60j at -w^l*1T!HKQh^JC8wKB>z
z7d~vH({VVJ8cZ~bcq|Ib7`U}6N|g#6=fE}~WuzvT%LU!MckI}Kcfb4H4c4Fg<FIWT
zD^{$);fEjIke=4U!BVLdM8sNKTX*?APe1)M7A{=aNDkoR{>|6o{*C{ENYutVW`7Aw
z#=jX)_WcIk*_DXf87vrg5+<h?;E!8>fO|Jz1LN*=i}Oqk5i5pNv<+3ajIx`B<wpVE
z0!%%q0b{VV>kPzA1~pSa$;ra?TqNyQ#O(|w#O7dX+hR=590}Ws!t>n`<K5lejajp1
z?YD7l9{YFCa9tN`)~vzw>C at 5K*}3aIBaueZc2FogI~(KK5u}oF)T&iDE)Yw^5syV-
zd=HgU5v7`kcp`yBJO<ybpj7b at vwf7S4jk7-BpOF58Lwv(YZa8r6*$9thE*%0RCD3O
zLOPRxQ?9{8qKL=qdxqy!Q7TtZJHUH}=XofX%gE(&7#bQvKA%6Jd&bI at E3s(Nq5$-0
zJw#Y$LW!1=2g-gJsa6YN%AYhcte{4V*%?t+DUCJ&=6SRWyV~cf+tz4u9)e|Ns|nUg
zoRZ08a1Lfk2*$L)oaZJe*IGpG_bRgs%XU<vqvVfLA1$KSMx!dbQZmSYBc9UUB3iGY
z*&cqEx^HP+kAi1r4zx+7+F*}n+QjQoH#DuK(Co-)Bv;8msZ<K;T(~Zn4bnOx&Cuz3
zAkk5>6<*UMUJBHif#ckVGmUDgtaVKKF4A5x>UgHvGgVHgD;r6Ky1c3R#Aum2C1oTp
z%+k278#n}NT at Kg2${o4>NlHo7SSLpUNnF8s(#*|HK41cQrssKBwrp8r&5Zi8?{zdr
zW2L at 795Xd&ow*dzmQKL)0k6)iw)PdVWL5_(%Sd>2nAGe>u97RcC^`m_SR7uhisJLD
zQQEO-7_e9k#0Q>__SRJWQha|D7lGz+C`Mp)ldBf<Bdl&+r;1!|=f66+DvAx=)O{2S
zHI#}wQ|J}>e6?IcwOktEWL3)N6dE9(8_vE|D<~Jum?EGDDkA-2oKy9%1RZMesm at 7b
zK8z2?En{o`Ntl>}`I*!3s)=vIub#US%X4>ND4Rn(5yd0 at H{*5VFTttP{{dyUfIn>h
zJ|b2OK7341ABnfkxeRUbNpQR>Ru4RgdpCUxWhW2cv*AZ7c+JEM at zz<N9G*EBo?i!!
zwy|NENbp at g{1HT^c^uk%M)>)tmPXq%YRKhwW>cMf6{XOgQ7Yt7D(rkeRpdKsl at f+3
zW7spY`JH=4>BZeM_O`L={x}~UyeMHJs3EY|$f|-gW&^a at Aqj?dG1n+CrB3RarF}QF
zaGhY0#6|mKFsiK?l`y!~>s4nfEmRI?KnQSoz5Fhf*JwQo|FAZO87bDfs3`)2v}&3_
z;K;F5 at XC8+@S0=JK7;ClrA7 at Z4P%ywZe%1Ybf!}BK at hIMpFii?P>G#pQo^ol+N?4h
z$>+}rk~PDigpJw2ump_bqkV5Qd!xWy<yn;eaqhXUcn=(NDlbS(IbX~c5~PQ-X*>^W
zgqVd1XPeZ>K at BT-Em||B<_aV`D%T8WrL^uy%?k9H(>WlY(DkFvbIh7jibf)%l13VF
zDB-5mjJSjI2T08ffWRX01?k`Gj0B!jMP|x;#M&mpbB2rW;G-oS$CW>L1l984SU9~C
z#sIGCW77B*v}O{)%@)fwZ0#A^No0yu+;G=Q3~bv1zch$)|2Fuw3JjTkXtQ=)53^@X
z+@;NL^Efn#%>L>=zCXL1zt|Z*ZpvB{aG(z at lGUO}Zc_WwXU6mD<RMq<h3C0g*m*Lt
z<sK{_T!uNBQ*g$@PoO)y0{3=bgWqiV3Z}Olh2ti at 8>_STp)b1)>2w-r&;55y%`Aiq
z2L=X+ep8VE03ZNKL_t(1Onoorw!aoPJ^cY>%RTUX51onWu&pRuzXlso*e2Q#;b9<V
zzc<Qk9tZr`U2m!vQd71kx#Xd?XN32Q7mLtnq+EN(P(ngIe?FfN0KHoL(r%gVW2sas
zAVca-MkyAFiAsi4_Cl*-W~z9d>d455uhtf*tCh-RG?T#JQNqM5jdp?827;^$(B2$s
zi>%ovUb7advpypdi8K%b?bSk3$E<@!);V_k9y(}|v=HP{W~OreSS;3HtE-*jc~2x(
zx(1beDzV|ul~k$Iofh`1nS*{_|4j`HG;62@<s^UnZ{kIDB-7$}y<Y87uf$R7JD8==
zOrnxY?fpYi$_AM<m|zW%5)G9-YTqKR9j-6_tXwV!5<JSsDwRq at qgf@{>iDOo5+vDb
z_CpN7-(md^=a at F<;Vh6oM+`3T9Gp9TC)a|SUg&uPGQ-JJKkj|q><kQi&x4)FAlWqw
zzU$UC>ptL?3n*?|gVInhE_viWBw{v<Wl*lvaQcZ$@q?=`f#>_MjlttjZNx>Feg~Ef
z7$0yvAMkx7V+OwG!-_;;hM9NxrB?qZ4-4i at 9@QecDK9&Cqo~c};2cY}0#%n1ZggX5
zv^&~$8CZzfDZl^~XSn#+En`AzHcGWY%xpgfr{iPz^^VWt51VhqhmZOprp1pzU*hMm
zYZEacH3P1{GZkNTOPG+Fg%2&h6*oWqx7bm87F!EXBVxtjyZaW{cri0z&13I_9D7=~
z&3VHf-4OTp7^(GaxW7oa(Ii2c2CTFug|@HE>S$9;trKC5fJX62D412yjDYsX&}<F+
zUl3IB-?a8dZGQQkVVO`Ok!XmlE3s43pxGd1R5W8mX^zU at XmhJY^_FD?5+ar5aokC!
z_}|)BCL&l$$sBE?mH365iW2a$;bJbA3qYr4E_BXFf;6MV?@}O6BB at d^&cDi$!eCs-
zQ`b2612v$~enO*V>PTuhZs8te%ouVF77B%+_ at 4wN-05B=X?$Kt-Zi6 at N~MC&aJ{Jf
zk84LA!T9gIPLg;&10)<;f5v-J(#TAU${v}~;<%{GoX%m8R2U{dB$aBftj>3ICewX_
z_o&%RH6P%01=iilvY9eecDJXO`>20+9i*nr0IUdnw*t$u;Z}+mdhStpP6ZLmMq4IU
zubF`Xq83W!O2auUV-SfL*uzq^sHr=?_yCN}YTwZ#bH-ShbyyeXOrO}0-rUu-H;;oK
zoP>3=uk>-+lQYr&HUQAglREIdX(~C|?-*lXTTyf+=VRT_!+5mk=Qv^Nd$F|hZFpe&
z^>{S*LrnEf#F?}I7191A28&za`oM|P-Uswlux`f_aJ?FATdY-K!SQNni%-V+^RC8k
zw|pHd2A1Is`M*QLZb8gWA#SIdgyt2pXM}4WUg_hsyDayCXqu_fSe2j<6f(-1PNxGW
zB(43>UNR&{s=-%DlS+luzFB+55Kw96i1>g⪻gYAy<i$*4^-X7~$4F9lRG_zXCwb
znrID+%ApASbPNf;305f+WAtA$KjD3gpV9gxmE?tGU<8tm<DjLbrJ*6Hx~cIRm~BzX
zQ`qTCuTlHMXq|>;?RY*OVG_gf2-kCt*85Cli3;?!zDBb<D%s*VXf{q8m8yJ7<%T5i
z;eJG#K~Yeygfm<d!}X*F8yxG=*0eUDRGAqMwHsH$p!G9+1~jv%YiDPp`<)p>UDIl|
zplc+on$md-yVp^QsF~03z8=iBYTNduW~L#vY)24p8xP+dcB!x|<TgJA&#Ayzk)TG#
zvdpk`vIX0w%fj&YfRiE?fjiH#+iP%K7e_ChiF7L7ESGtiy@;C!Ub3c{x=C_lr;b*8
z0gO3%3j^Ckv9SFVJT>?~=&d}5UvIb?@0xoxmJXbWs#m~*wo~!wwmVU(<S;og9|pjL
z)NGtJ{R_xX?uCIhVm~m$)@EJldAMl)^;k3T0G{l*2TLZL0oz1?eIPT<<K>Z&Xa+%E
zJZY**bO-<mdiifEX9~MEX~u(pS9u!Gp;2CSr3%+*r~*an0~7#;qsOcZ)ZQWLNXE=X
zSW*`NtYHAF<E=F~%pA40wl+lfxwjHfhMQxOAn{(<lu*IE5<W_wbT6mODV&|6n-|Fu
zo1C%{YuJ^I?*m<Dnh9feEgp{t<b={9m2zoa4(F#(C^TfT!p^iRlT$*=wV_Qt)lG{4
zU7I{=c7p_p(kwcbsgoGrc?9qL9yLQyqX{L<;XW|TV5qgS_SDfe9kwD5t0XkLp&3$M
z6UTuG3|d5Uy>Z>^xG3S#o=Zx0)L4Sqw|qVykPuzdDy5{60OfU at H)aF1o}bw|o|h!N
zfy_{I$@JF?*fL>7;xKj;20macIF%A=g+Un09+g-a at mi&KKwz=Fm%Sd0F^EMYIA+NV
z#A6XO-(`pH5tfKF2~A_PIlR#w=(%9JnCIp}{px6uu(90Fyv`G`XyDCQF>n_ieEw!^
zFRa1wQ!YTl8i$9r-hv0W-i(SV<J1KoM$N0%+i4mLZSg6)4QyD(g714+*m)`zkAD+f
zpUzgzO`%ElUs;D1#=jV3MrA(X`Xz!QN=)bkMcD`?NZL at 7pD7lL4cQCFaZoCi(9+V<
z09w@?KuHnL$%wJqDeIo5awAH?lF1}8nM^~!4Pd97j5QM~d(te85<8XO at V*Gvip63>
z6koF|YMrZDnsB6?q)*+^H2c6z0zq>)JHr5#c5P=p3&|(5LF^Ai62&?uCA5_7sVkc{
zOC{LWc_YzazZ#WOshg&PZi0E9gL4#?rl~qWWqRR$cIvRk_btJ-I)G{RP^DPB9 at YWT
z`HQ65_x*<X=KGZLLd`%ZK_v;``XQmx`!^vI6P0^$PUG=-P-{i9!KSKw4m5kFMgzL9
zXpn+)p3mn;%%#c{bsqG()ec-q9_wrP9VFu;GBaVF>OMlAIvcU9;lBgEW#GHDVE|!9
zp+10T49u{c%me_*f#><K%--qTjWL)zYZ6{}?EJcnt(lfN<OobS<*N}zec`-PfttGA
z>`zP8-5u)luKgRrQnP)TZ}`C9%)T6%?r~T?@C!VX`z=;JeRthz+p^G^o{lpnd>V7w
zk3-ch55GKY_`bKt=i3--*uAVNHF`Pk8R1M!nDoEW_Y4*XYXSO;5s1=8gam*J^a+^4
z{ZTYqqeZ|9tOy!;Z|u>+?@(DA at 10{okjsd$UbjlN2*R|PqFU5yGfH+n*XVS(7mfCz
z;qMTTYDPgDdy*h&eIl=)|IcW)5*J3U)v8z<X!0{WAA{Ni$?62hLVS&`Yn=|=!+1>u
z<T at 7N%$sFdNG6jb0+w1IqAqL-x>bUuy=R!|p{+01h{{bhL#SC8&1k8UnGzMw1<9c9
zEpE`neP^ai*SNaiX;x4PKJS~vkHkWq!8GfrCJSN5I3*71h{y3$qX-f<evX+LbqUl=
zo7S9ZHj`t-xeCiL_4+wB9B+=FHUbTgAJ?y9#1UjBtXbR}{ky@=o)N|jlNZl}Z`*+H
z!j7k5MWXQC8hqbs06>w5jZ(IPxw9q*nHk^rF))-zwN^vKj_(EFGVl?>d2cxy6UViV
z>fPV0nK`t;2_Hljh`o}53D<0`Rzs;&LZwm(q9LP2rT5o48A;M!4*GMxjK{KPj81&&
zwR5LUyA+GZoq<i+$I(|^56iNUw#H+2+wqu^S%j)v9>aI-;yzwLHm12}9C}#@f`R6q
z;WuP3%H{HiPVf7BZI4z95tiMkbuIs$plCFiJ8LzP$z%iR&}eQv9*66?0jXeyfY!I+
zD0-N9D0v9?C{j?UGAG^-&#A at K3d9KnG<|hY+uiqcp=fa_?q1y8S|~21xVr}l?ox^s
zcXxMp*I>cj-QArx&-b0*41bZ#By(;)_ny1EXLl|`E^p;nuy7~)9=s(?#z`~zE|3bG
z>X5azi_iaSliNUE_{WTxG=a}j2st!@n}-_FL|m7+M`|QK-Qtq*wT=F2Cv~cmD!$4R
z9L66PGxqI$S0F;co!%9h5Ds0=I!+N&y7Fu6 at 3R-oO693L?Xo$DU*eyGzb~o~n;DMY
zPI0O&k1Bo=E0oF!#b&s~hsp&>3fYE0nZ5YQ8%LQT&NlJha!vjO*wV8`Zd_HPyhx`l
zXZaMOtcnn35?eUW4)<YwFJ(KT{dmU^v%wxmVvQJt>9_;(HXlBUt9(HN9Qp)$Ev at Ot
zBD8dJLh{Q;<+M#tJY}=MSk8qeRyz;)anBQAF(23mBbXwTeCME0G{UAv16jvLuf%0V
z#tb4emnrxiaDOXGvYOsd97h$TR8liE<^rEAxG~T_3vepfpY^R;7cK3q;*=J@!RyQH
zX&62T=wMCtl<=O|bUVxhl4UVL6C`+AQi=``6C_Xdx|nG%0?><j6n4!ap$1|BcF>ku
zDAr(Pw2^+!>G2y{%urEKRm4|!Tbo1BGw$(QgJ`;z&w8DU*Fq-;Rnn_#Y((|XI!qLa
zCwF0Rw*^k<rY at 6x!xT-GVix5eaoFB=o{^Ax^)J at IUT;&noZm({l?GO*qTORJ6uh)-
zWW{sOaS-bN*42=k1~4N}Q5J;kB)-!g?N%!OE2GQJw&G}u00|2kQwMfgD=c4=s#0Ey
zr;OSm899da$UGrE?pIkkGvrv at 5&d1orAa@$yKJ%<Yn=OL??g(y^(BqzvSl`vQ1`<s
zkyT5P2r^Avg6(SG5xDjw5shD4gM06Qzs~sFM7GRNGRSe6L9m?>Os+YUTW##<t;`0e
zH}_Lp8*bzM0WG_(LeIi<35Q-4{z0f2dTMC#6Tw-MfWYtO_fb;69d2ss;N!3)G*NAB
zNWRCS-_I}{SQCgWBRqt;Jyw)3&)93TMN@(TBb-#^-7hoiS+_IX{oMXw3)dsc&;P>n
zPHyCqQ+v=#m<Vj#<QZhDX<=#k-PM%`0>A|bL42LMav#F&y@~znY*z3 at d|si5apwj8
zu0_o5g&63)M54QuevX&vq&uQGG!gp4Z*3VwixWnk2IjuyB99 at HqUBv6K#Qnl(4bA3
z^1+?5z=jYgP`{KZiZ*p1_URX?TuNkwaA~Qg%9hdd?dVRW<VZbDGOO{t*96i;($kzb
z1s#A}lG#YD6VYDVq;}j$qzMQ|f+7aV?EM@=8B#zcU+3}a-3c!Z^F*vAXBQ3;rdZnF
z{a#AINsn`~G*&o6=?BhpVc0$vcPwz$<$K~zfDe=rNvk5ngB(X%z9q=?colQ;omf7O
z0d*jN at n@)c5A6hx5;22hvYV%EuNc;tWQPtm>mdR!6uM&0$mXC1<>yyctU?rllokS}
zfR$eyd8aN_Jj{5=Ct!mmrFi&8ayB2hQx%5ri{6qs)(ch1o#GP7yjVi<f_;PKeAM*2
zL3QKjU7&L|TsJoy&)WN^`O1}lK;jf3oJ%y>^QrmR9 at Q*iQsTb+Voe4|i%zc=oFavc
ze-Hy>qB6CLAOB5UJxY5o>RW!I)<GDNpS=<MPtgHi?-DenEALyT=izG>6kd~h#*hZm
zJH!7pIX4%0w$fw_iHNbVvqKZLDp9dI$FDVKEp2nV+WyQ>LjRS#d#YC-c1!DU{KWLr
z&x*edK)vQkJ<4tvbt<u8liD1+h)l&3rDS=-{lA~$HwLU}Qz+OdifIs3rUywF0o=v;
z;ZzFLvWB5wyTb6P&0-%p{>)SZWCIKca%eGrujn+8&~)!P1G^5mtU4lOz`Z*qfm{C=
z`XbN~{ZxMxXDt9A{f`xy$1!rzQlY&F(K>t`(%7VhM7T4F4CCzIAMzBv#AkdsuNl=N
z-*k2gOtLOiiIu7StOCGnN-yS^(bZT)2Wn|XLDYI<)5YMHdoPM_CNvV(EswACz}>n^
zt_CV|dRWyzz2<TYaWZGOn)@0zd=>~e_SLGLbw$iQd6q*$8%R_}eInwWFP8OSAsiCq
z-@^!<?++j&4|TXof!AvBpoXH at XRpgD>nku}Vosh=ha`ouCS2wLB}UkeBdHJ}sKbhe
zXd%F6?q#YQzTFHwM(!?7fkEWH8*_MmKG^Df5<PM75b%9ql=2JM8RBQkW;sp8sMCy|
zk&ywP-`8X{sOpjpuH}5J;qe^IK|o0J9PH^ZXVh)Q)@}s!Jl~zfjPB`Oc}lpUNK#-x
z<XnbZy at AQBhW`ySg)m?z)3X_vXnAVTxv3f8pDSTihLQE)S2X5nFj8bF at I*t~z~C_>
zA2iVUeZkc&`<xj2)5U%P5PyFG@$H9_rZk*PB^Zf}H#y9d{Un^)9**&3FF~$jmnWn@
zs~Ns9h9F#(k<GDM9uvzsl7A>J85(1 at 0dYGnm#-5`<wAaN*m}e)Dy^5E$P*{S3Cn?8
z2k_8-73QZPMP_irp-i;lWUA9Ae98_!1I_7t=U}n=M$$OBzX*J at B2N0_dp6h4n9AQ|
zIS6rNuufeVuwKXxFe93S&Tts}kGVt`5!$)pg*3UM+$kxP-;_1;?j?SU(XQtS+fn_1
zD8gI_2Z{3tJ{3#YXHl5+`JRTr8sp<_{81+Q;j{ClzmTzK^&4^WRKj;KFyNiN@?h at n
z@)D!QM(}x7LdRnuBIIZA+T^{ciI>KZ$#(NO(#1f&G!_u7Yh7bt1s5lPRc$bt7 at Auq
zG{tEoB(C2H*|qA-CkETyZ(KC-mdA|FsPLZ6eMwiVQ;g77Dms5#V?qQU4d#$lA4})M
za at -%YJjZWa<k2e^63a;7Z2KWvGGz-3IQ}wl$kt<5qaiLUi{#LvBbN8$ow>k7OG-Yv
z3XC94gl*3zyZs^zp{9NrqbCkwc&X8U&7V1fqexaL3h-cpZikEo8r6hAJ_WnP+9_i}
z?nmJrm!W}Hi3)*Kpv+W#x86&^-wJzao!TXUy-xzpx02m148O9L05f+46E5SQpDM1o
z$5}-BPShXR6UtgD3DLigtMmS-I(LBtSV6U$LsS}6z;sK>ij-`KpNXG+B*Vlo8`6U?
z1sk$<nB!YXM5C4iR`-p8*&p!;Yo-_}81Zz++?|Ss?>Y;miJM$kDWfLrJ+E|{5UFgc
zb~G7v+;C7LQ#_FaQ_;*(x0;T;ATQ+PN#&b<rt*g43K+LmUhT0)(-z=~#-B4im+e9@
zW~9Pmlgn6)L`iEx8wFF)p#cKanGBtsh2O7Fy@=|v%W at Xv8uqh`Sc3J}9$+e4j?SO^
z at czj}Gb{au`*h_7ElDg)to}NqnJidCd?_ at RlHMDeV$=M7&UI)Jx-({6#3^2%2Fh_i
zq?t|!O?^+t4Erpf`51eE6s6QgV-Ep9XEJl<OTjw at OB@<_irvK+0H#wlZL_nt9sm^5
z72>t(bb+l_X^}a0ifBBBe!_?q at n4A&ME<YYC3j49R4|b+x;l1LKg0RURKA_QiW}v}
z(%q9xNd(J?H(2PUi9j^?=b$kO3or&q1!<XY{mXvKM4SoTWue?Z40mV0ne&^}f^9y|
z(Lyr4Is*v4>b7A&)?kNtVj(zzRI8Udpw#kJx(%m4&SDZf8v<eeJcVr7&bSd0F%Yl|
zIDBv;RWySFdp7n3DC8)An0}OOeWUCguZ*7|gMbw(J{cCe^WCA+J1{w7Hd97NKxR_K
ztT<LaQd>C7?(nY9T`eVlp3PEC(z?ExMn!n}5I}?<Q!_Vag6G=51Kf3JiGk#hWpIO5
z()wy4+arXAKNS>g_xdc at 1pS!|Gpwfqo3;KN_}Vqfv$eakZ at h1a1v$sWKSW8&7HkG~
z6f64%&xs-2VF)Ofvb7x=t`bd!0o6!}uu8;*eElgg54c@(W2gx?ml_sg!&<`xwZhG7
zrbioYI+^;9`%}$6(4y1c8Ov^buM%`5Dw92X^_PX*8PgIoWgl35hQG>?>N$A0lkcDV
z`MU|HRpr2<6SOR(7S718>D=Ftc}6KMCp{5%zGligzijCdP|3fh&r=q|gijN_3-3vd
ztru6+-Gk{Mck#FH_4azYV+eE&W<SpY`izV5u at bnBnz7J>5apU<^4Di9gyd$&wE|XQ
z%AZ|fYsUzRO}iu(r8Rh6=|M77nEu|)W_E5J^hvwUadIWP)!cSeHL9T6YH6s2=#isd
zoSo&Wpx7UnTGSR}WLI_Z1(rDU={ZPMB9)YpEtnFKZDs^qLqjKXnZLIHB%nlgNi)n8
z`Po!vZW+~YMAU&gAMx$qu4Xn0IOS1j;+ at Kfl%#17Qa6hFrRs!HOo9mia at Q><p`4!C
z2@|ZiAa6aBevsxWN$3E&@opc?fuJf9e;!6Aj=^qrIEW9DRN+>iBpCJ+L$$H9E^elF
zUv7)C{V`(j&h8G5;q$CQer(MatU3>ry%1 at bd1DVdoSmS@?>C7Ed{v|Q*$&dwPX+Gn
zPLdF^ZyFTd&YG|e69&$MxXDCa=Ge;7Yfejb{lT5Pwhj{aFEU%HhstYRwp0tuj+4i2
zI0*S;1v|W~9Mm`+4 at Qr!+5dB}d12{|?%x0{ex^~igtSgbTyk5N`jeu#;4=}39 at 1Bn
z#c+{?k3eGF{K&pVFO1<->DEbZxo-)5i<$OZFpm_?WT*S1iAeyh0=-sU5+O5<U~tDz
zSM!^_yJf2*rW{I?J^{j*+EttGKRqhU^xn7$3R`_v0;3iK1LnPfI?nP|B2;=JAo-K|
zUKFaYo7QT7cY4S0r1OOdiL5JdDMAe=2r_9Qy6C0vdP)3;M;?=dsn27V2EfjFLZICC
zm7AC^RRS^n)Aj*mKfiqO>?OvCFe_&0$wdAnVVw<<ep}q=#J3Z)WFvVUB>=2(SJ%B3
zWSW#Hq96Yqe5g?tpy|R5TY)4pvUxs>GbVH3*P*2$;8{JqZAGp}@NlG8$NJt$CL_ at G
z*>;|$O5WgU!z6hI$WShRkOO*J7!2}Qz+y+gqNi6m{(F%yCO=)gEiO*{m+<G)cu^<;
zfu)&ijj)`)j!Nt>3vrE%?B2i`0w{HLF4%(hdmUz;+<i$Vv$-ufe`YAIm*+{n#AIpd
z;LNm_{8+&TLN&w;nOcNg%`VZnPk%Hc%1>I{z=EW{ihHVCmDgjemN(<o+8JiC(?^_;
zu?EP26A;KP{db(aiWU$E-cXg!z$u9Ho4S%?Dpkdlq!8_{y!$@3%$nC%QxN)zgTX0w
zW|?dp|00kE{ndy6=<2ORD6C$oES8*_oqlWjuH64q1={RsTx%pmyp(KxW}TcKbT-uz
z)Ib~CNjgl}3s!t$gd`1|$}AGA4zpWNJAwaNA36!~+@@@ao_ at O<3(jaAy+rE#U12zt
zUczhCW5_x$42|2B>3k)KR(a3|<g>h!8$V3R8T=qUGr%g?pAv*fjfhu&wZtevXJeGE
z5zDdFS=|3>F^7)*|F2;Y!fL_%h}Zr$Pxfg+;vWIymTNIGt&VIicgJ#hG&>PA7qqv{
zW=SlQL{h_K`W+zwA5Dm<t|H{t%-DknoiKFO+JK)k&xkHa?`KRC_H#`ODfir_KG=-g
zf9E$NPQZ(qlV`miv6VnM3a2!llr46*^~P5&*-fvnUts%<YO+H%YRfkXR58C+exD{F
zvym#Pw4;LGT4o^-MvuNBB9h$}F+)^oEVlm9wt%HmMwnSCVv|`a9+*W=zSpMgiC*#=
z{(w$XYDfuX_QJcMm74QV+Hs`fQPiMd<&(1yZB+y&iEp<{xB=>3Wj5f1WT8N;n>YlU
zBAe!WEYVd?qTN{XV)1bn5BF=@P)hUiK6i9<B(oV0A{ZEj`|o(z>pZ~nh2lS at vH96_
zvFdi3YC=>By}QG4X&Cd6>fLW=?|jLVH+*Y6E_Q7)KV7W(4AH&hnK`4WvCnL5Z2a%H
zyC}(?w}d8RgWZ4GC5<`@mg_0LANZxM&%|4l9=a*TfgR6NvMWibf{AVIC~W4L%!Ob~
znUH|djp26WuDR3w7P}w^`WB%UC;s;(=kH77Ut*>dFvYLAKQ^(%)L~ZQ+0H*<nyo%%
zKZp)1E-J~qtgvp66X3xf!`v at VWuV$G+XY^HrKYsnD~}bTrpWWAVO*I;M)|DDKd2Q_
znL?%8RQhZBG;f?MP3C%?i=o&03(w(fH~A-s>5eExp^4bbroEmNoU;vms49fD-6UHL
z^6wY-Y`r9yjnz6?Bm!C5!_JaOSzY%4HxKH4!i~Q}4+9T8ws^0-pgIrqbEhnR^>g5`
z#|@hptZ>7@!%Mz-b1>4@>2+sil;q=fmMk|$KurEAQsmAXTE5>{kW}3U5aQ^UmwKvM
zcAwuPw|3v&-4SC3K{eVKuQb{~P($#T9OP{;=z_B$Oi*8XsJ?Rp;e8cNnW$)MG|F>C
z!tRO4i;)%z=?<y8XN(@iDf}%smkpT8uJhz*u+S+Jz!>$l!H7^5IF<}jGiH4R&S+^W
z78 at 95yv-Mru>Ta)TB}N(qQrw9s)R&%amz;yozjeRm<?Zr;969*Aeni8HWP8o8HTrs
z%2ew|ZZ#bHA40}GA at cK~RytAh099%fs{|sr0eTPxqH^}c$)u4}B<w^E7s2uEXgEA5
zbP1-Cfr~P9z=(2?pCl^k(;X))LYitZQOwTIlqR!$y045lVLco<Cc1T`>9pW^V5bU6
zp#*9?w!>-z&OZ~qg<3eYSrh+<bVyJ1OpM|~H$_?Ud(_?rM&Qrb;XuT|R{w*yTq-A`
zn3xzuO#^RZ%r1NiDO$iu>*4XSm4rr`<jvx!*xOmda3YRM<ep}_pga42wjJ>BXwO1<
z5Xn}9R>gk at -F{7!XAm at 7!Z7+I2F#REQjEi&R7il{X75j<zA<?>G{bC&kr>Q@`nROz
z*Vf7~NH?9{2Du%5V#mZA5Z5{_ueA6w-S8<D_I1jlK1VpPJ3L!8Y+jm*PTlza2j#}A
zE>3Bk#9uPiI{11Jjp!~O>q>s$T6rkB(ysX|ub<j1%%s(d9B!3;oRS^~NbRf~qC7R2
z055+VS>dcJ;G&Ixx_W^?bekFy6uCjc95|}~rv-pb9o{;Sik4<=(X(*rqfC*5g9*J5
zu~{79Cr(fWdhrP#%Shzrq}1Ar5GE*Ge at N3yk2R~+voTe%B*^4wRlo^3-+DlPr=Jm3
zzv(usV=QC~gRGh$7(Zb?km$f(BKCJbM7K3GW61&z$2d?w2%Nx0#5zbgQOWuU66V-K
zF;Zl)H%5j`u>S4r>?D%`R)2k{U4*108XnJ<1c$d5xN}AYz%E*IhOoHVWEW_r*7&^-
z$I<3hRk2Jukd}K&a1so}e^X8+-u-Wxf`!Ds=eNdMqWm4n;57IVt+**mhE=IMx%t^w
zAqD9p0_8)4OcC8i6X!ny#SZ-s3j{(Q-HVo^2}tF`Ime=`+0 at CK{8ykN199tyo)(Xm
ze_)bHk}~3y?Y91nWP$m8<PagdA%%+al8T^RBvToTrcova{S#1B2%9Ru;{y&)Y|XPo
z36z0T#VLA>p^7rlviZlgJkiiUVOjW{L+;s5&<!OW33gy>xwJYUHL?VgGU01!N?;@7
zB=obr+IL`MYtj{oG at TP;y<#l)yGkssZQ=;mh`E0)lMiVq&&I`;MEUYB)e}9sqkP2A
z!y)&bTOM0P(eZJ~tPl(&(-C5TK%lYNI%^&?p&*Wn(*>~WhQua)S65fxbg*abc;tE;
zJN$1KfDrp=-rq{s(?!J!P(1k|W;6YvSOMS*1Bl+Iz}^18cjU#)TGV(qGc<3bzPH_P
zPkO}IH#yrBgSuvXQpi#;bpD8fTP^gXS;-dGSz&7P=1z*!<&jDeb?~K3*ASqJ=AkUb
z6k&Ux+giJ<#4|-T_iVP{;$gz5`~{2tc!P1Se3F5a$WfSFe`G5P$a{=TG7Wf%#8F4D
z>kI$ARF5Rgy7^g4?wP~vX#uM8gEzo;`3*n#gNa<tLYy+J6!WK$scutMnF}JAK78-j
zZ-yfogl=97+T6X}<Ke%MP>K4%Ag1ChDg2Hy%0HV^pmU*BBi&zlCw>7*<=9bLy0}Qx
z5rB*5m`aG5q<X&s-0doPQd&rDg_7*3KgF(n8RtxU5NAcmw%rqQA0Ot)S`eII2nLsW
z441g6%_zs*-L+Z4Ft8!L at QwP`=&+2w)x3Vo5D=nupl5;~q%T;CWj5U^SEd6ElwvP4
zDz~<)JebH*S40QsmK|)Ng13 at 6@{lb2edcnsnybX>Em+}<S$!ImsurRWe$dtC;x1Oj
z=_*AV{_o!}L7xh0(;I==6pzrdy~NP at iQTqs|Fm=Kjt{@)s3Inu#)r%t4F)>|&3g9J
z|NKV4C~8hjFU#DtC(6BISQC_c0G-sxm+b?(Z<9tMC}vck)`ZT6E~g)u-k`<>aBx3&
zb&fjll~dJ<?!UkLbfuI~Pp*u`<!&cZv8Y18PDH at 69&e&Z!A66(eED^vXnA*YC2e%s
zOSR_LlALdpIb8GW4O&c)Tr#%l_C4LBF|A;^1KES_(yF7iBIkKwtro*H`D)bk&KZ8g
z#G<(I)?uh$G!if62H7&G0c6=~Wp@)%l_dwG++p$$iS?+};A#uvc($o$OD0CeQTlpK
zs84(nR&)$4Rsxb~<kNa8WphO;V~ppM at 5GK~PD8sHD1!#bg9a8F(CySSh05mvY<Q4A
z0_c<N-w2zUWX6P-OR+VaLkVIAd(KQ*0}^+zr#8MAKV4Nv3Sv3<WE#t5v+E#PLZeQz
zVT$;~qrl0I<;sghUkXo4!p~OYiGDV)YARaBo}F|8MtsQ7W86EGtZM-7mjcn&Ad0ib
zSE<^k0i&8OTQxOp9Zc`wvm=TU(+)H$d;oQ|O{j|28~xhd+P|N4o`%$EHm;tgqvZru
zL~U|3j^#^ru#1+fW!@@q;LaIFv|)aHhktuxN63ddC+lbHnzilEm-(to0DZC*KqI6^
zBIX(DEAg{tleaI8 at rt=n6>29MpOvqQrybVr<roA?$}>=)HBx|W=85f96DM*fo?o3N
zy~<P5ANg=x7qk7qBdy&3a^>qCJpZfD6_{8}VMd~?e5)ol{eK0k#&@94P9nz$!DPj0
zR%(g$G5gv8L-4b*QO39tKYQ=E<gbJXR&&$u#t|#2uX2%Le$5qoP3>s@;{Ht9BPM&1
z15X(CjhM|xG?|TC`9z!yc7Q$Sia0~+RA&?*J}2WrUuniSO7fz~#F-^zB`p#@rgj6w
zixEr<`FQE-SNs(^rO5ET)kBZvzWT8`Rx5~xb?`gpWP at k<b%~Sm at 3TB2s5F$R2`1dW
zYw?PmJU)$c6)m!!d$rmWkqlC83Dbwg>qY>U^62Nfj-=ZR%(7_8g76 at 55+@e540%t}
zgz at R|a+_UxNv(s4%9efGg82$cqbH5jHk*2zstOLPmlZFJ^Fwp9T)OSeO~0+Jt)kme
zcw<($oirhA-5N_XLWGza{KfDdyzrjtPlGaxTEc;!-g|nWAYB6J*}S-Y<Q`P*ZH3)~
zYf+0iGG9}p<UlwDTdY?0CRGR9*oZu27IN##z{DU*Z^}w2)L0-uKj5t<={m~Q_-TqC
z^XN1R{0V_|B`CWwCNE-t1v%lXA^K4Kj)83CZHp5NF<3oY(=*P8WypV4*aD?IHt|f;
zn8U?mLqpR#fne!wPFO=y1s}T1zVK-|D33e9XcVczTuqc5d=(pCkNvotUFzBKD9~DX
zuJi(UA+lU-Das&bXg7Xg)l`BLNUGOy&>|oIhe>ChA1idyt_d*<J_lUjoxrRh=c~@w
znR;@U8P!#(K`Cm2oVo}yR2l4{XgGFWgadzUA*F5n at 4@4-JA^f%)SWlbq}cuMIYbVk
zmJO at R{$LcvIIk{XY at DS|0}I1;157ljt)PD|0q&FIa!;d1mQc~qN)}GMGlNCryA#hg
zD=#n>8*-@|FT!Oir~6G9YOH(m6JT)Ao5n-GGWktBk7=;CgHcOf%g|2cW(Anavfv`<
zt7?~^PKYccRQb(c1~hux_nIt-zs at C<S3fe(OD6;v)j1>vm=Kelj2(CGQI)k<Kt7x>
zy- at n(=v`pD$HJFd3_xsr7Z4-YxIcU50{Jp;7xNxw>?xfb*&GFL^IrXIP54+RzqCNK
z2!A@$Yv1K3#EC$VIbp~*hfMi{YE>JH;?AW}BhR`hBO}r|5=fUxI7Z%=$o|ahqjtRm
z3X*N~X*>%PdLY;vXnt1sg+5De2bD0rdi;isi(_TgY;*E|<&tQf=aXM0;${EuIW!FR
zD~*6diY`i%D#b?hz{gs`gEC%O5RVLaXIV9pZ2^=-K9VO|$En at aDug8jHlhaFl$TVV
zKg;o3rJoa0O3K_Ucpy;8GKx~`Yay*1>3mwa=d1DlUaw$TO$R?VKDX?&<e<Be$g3$F
zY*Kos3Epr>gc)ZFs<+a$I!tz9W)zWJ`s#12O>glezb$d(cr;COVlecigrAsBKk8W%
zyQW22kv5*`%*`~sVP<#Rrq-eOP%fvmoKx)`ed}0J=Zp#9Ry6&~{n?z@<SKDjWAO&?
zlWf|2JkkH?;;2>u4B}sj6<P4MwsDpy_sH;B7%5)?q at W}g4t%+Na1zNhwlcf!o at oF;
z_9sG_CDg%B(L=nWq6armJ{J&Eruxoz17yIUfmfYP(5HWXF at 6OUL(u)A`WbS4*EfJX
zaeqN1=AR=A4_YbONb%)56 at JwSgN+Bl2~jwHGUn_s?SKp13~$01oJveTtn5a}y4f;!
zmz^wFaY2mV*rHR<x0yGqUK+bs&DzDA8w*?#9VzUq*agZ~O-IKWCwkv?Ps%sslW36I
ztv3K5cTWYt2Z?D&ekC=$8kxvjhnf^QQ~jg`XJmrG(lsNW^oZQzX|T)<0B+)smnp!h
z3n$*%2S;(GlXYHtzG3dy^u2g(1fz|+rdG(04VLj=TFd<4of?HkCZ$=vMujq_sJbN?
zX}wWjsVr9p35YL at CN;k|B<AvT*|kmgOW+TEn4ay(P7WKC=(%i?a64|gr_rw0(eGIi
zJ#JsJ7l$(Rq`0T~>`gjTC=sCFpQ}DRqNhm1i-P=`5-b}E3>!~}=<SCy5jY_xK^sX-
zR@`ZdP&WR3P6zhdRV<$h$v3HgnLY{86aQX{U?;^{EmawVc4LrcYS5?%6lU0D%w`}f
zy=csLSefYiBMa7_vSW}k7<DVxQf)OX0Shk0GMN6 at m9j#E$+v;o80V9}ZK77tVo6g~
zy45?Wa9@;2Ze&RT?_1bhKY4XwD}0zONJfU)gadk7MO`7=e&KE5OSO<PC#e8WSV2W!
z?EXK5a&1#?Q&W{h^9)!9Is at 6se!?0@`3L)2>JW!N at zkm<X_?d~ZpX{~<__Bxy&Bj*
zLF4u5R>M*&GzEzQW*iM_v6`L+d at 7Bgu^W33o4G_>ZAop<<34J^Gh~nV>-_yMLH#Q)
z9%nu=G6)FAZOoeKU|)brBbqx_S at DF67yEg~odlv6)nCpJsjOv%j)vB5WGl3KVG4=+
zjQ&$8i!^(hc4bn at PceIq|7Rkh(dY>Foo&;~tW|@tw at f*^R)?NQqUw}4WWcT{KX0!8
zmt*Z8s5_6hWa#9x46Gn>2-p2_;Ucv62~lpjxWl;|TNm<lWW^I#?|q-ILAP(3?n_M@
zDJ*9%6i%yzu5B-HqExsFif2OC7ne!Xf*&=6q}qFLmXmOBBQ02PT5zX9nxpq+jTk6h
zefANDe4DByj}8S$kYg4u;wOzj{!xZll}6F7^)iR{UB<<R>bGQ=cV|5a<M^>b7%|9J
z17+xG+IY*iGCBY6+mL0nhyg5CeqzzxypWbZlu#5su9q5q4mg at S4eVneHXc1M+s-}u
zd3sq0$@Nz3LW_*4mgFzXzxl#pn<HPvk5l)q57XA*B5G3j9bcdN_t8^F4-Mn%vQyLN
zHsK4w*HTAW{n2+J?+m+RJq9b90P|51pA3$hlmE`y#c+S{qX#l!1dc}SDw=kziL8ps
zmt9^|NZ~YGJ!MZ5jSU4_v{$IA&4w4aa~Zdr$CGlm?o*E^a;(dchwq_l`t9B{yVaHw
zjcVNFYUHvXGz;|Add9fb>i2B89rF$1_7F={WH-!BBUSg!6MD-7@;Mk1c+2d~s0#v@
z>S?u%{a@=HQqG$45ZYvJX7wc>68C>Bkq9&<MebK|O}{T<{!G)Iykis at ltHqNIMs0$
z+4j>&;MRt$;8Z)HBp-ISLF-Jz;8%x@*TzMbYen5z6lEaS5<#2#vMd8;PMzgm%Rt1`
z`m&EW#m-7BkWeZ*pumx(Xy9Gv!3dW8cFn~OKr`pC>ZEq&KHq{1N#1MT!84agGZtv@
z$;`1L;aUg&f}clU09rPzaBABS!MEpOYtmeHKb6Cf|D!mLfCHwZn?YZ<MDqeOJv0|_
ze^#h{2IZ&>Io>Y2ogZ|aBH6O~yfs*HYjbMLulk^vUKn2Mpk+eAsAMex8m_#felUma
zxKZglpb2E4-buuHF;iW7r&f$leNN}&R`*scTRY0?VT~h4 at WRxYPP)LF5{zQSLYHK#
za3P#{Kn(CxXcDWNgUCCgue>ocQU3bqM&CIv`u-Gy5eG0eFg-oCza0C=;H(wDq<|4P
znlmNK5*qQLQXs_myYYKD*L%D3hx7fezQ@~v|DIhe_^I8~ra_A{l}YEIF7*bG+;j8F
z(ukiaDNMS}|DM!{FEo%Naj}E~omzn!c at mAn(G4sT+lceAqjsC9!MD+wI9m$mJz9wd
z(1;bS6f9ZAp?qflei>1Z?*N^tI$|0+)VM0mEnc9uZCElZp%5S%mD`WAsfiqSzGf&J
zkF7a>0QmU2!Z-!-2msdT;F_Y9kHjYE%?mAJk|wkuB3RjAmo&X5JEf$<Ms1T6Gqf_H
zs3%HpRAp%!RGEvT2CA0MdNJwumlhoHRc}}lH*ng4TymTGy|w>nRH*&e7K}%TwhD<g
z0>IqsDxpblU7zYRs`kK(jQ`%jG921dfsh!4Is!SZ=*o_1O)E|UZ*o|^_+{+`L(LjE
zKJ3QTk?W>%lNutJ49l}5p_ymYx5)U>e#ze)<G)L8Rr<6}cC91g$)}$!E}YG5s>sg@
zzFz!F1e>+qUL>X&pZ&d;GH;vcsDbY<<nKa=S1DCJPOwoUWvs1Lrgr%;crboBy>~+e
z=7+a-ZGJF_=u->NVzR#;5oq^l6>Xav1nQ=Oao|@*1)E)y&iZhkLd(1!1aN_oxrmLf
zf%|jC7neth8%3!C0}t<W)-Yf=C7Hnf`5Dcf6mGeID;7^n8qp%%y>-uvnp*v{iYi=o
z&W7#?b^UB2HxOzANq(P9;2Mah<;5h;L$Js7<L-j>m|9$Ny@@2;iDz^DDSUCG8NA`!
z3=ZVkFkqZ9u(pgi-4!e{Q`}4&QmarqFgW9WASqY2q=jk0L{i__-&1zyKRd5^-cl&)
z>v_k~W+22i$H5~VQ5IS>vUX0(dE$_Zzag?+-L~6U+dX#e0uOJEDRY&~)2)!es*y|)
z6jiO@*YjVq3pTz#hq<{ZVJnrWl&HIEc-lwpoqf?|4+k?|PS43UpTPxNyS8}x1_qdg
z<L;-ly$ZDZRLZ>!SvIi1zc?sXd3q=UP%7tzgf{Ap!p|o%L7Y<3lKwV3JOYX at 7aJyN
zP?MGm?w3<9f=kP^3YeGd$QiuD)>WND_IQE~nLr}t6164IYc^LB8>KKww-<OjM+&FT
zc<`YUC2G^f^}|I)-R1F#9IgOBNRt{b%h1p#wfhaZUDeu|{=~J}^W(7ND-Q3|^h&!+
zp?I73YN9j0E-G5%qLv=50N=!}MauG)%SMn~WMawL>fVJ<Yj0rF#{Oz3bPf4}k1`<0
z8JUrE;KAFfVVNyd|HY?Ltqep&a25mhDPCW9NmRUng*gO7p?fE(YR0}+*gVs|l20bu
zmLKveh@@tyVb<M$e+}cL75(@oX2Kz48OV)<2m1{0C2oUwP1pOa-n+yQ*O6&h16t at C
zdrD-M%Eb(A^1<i at b9>lV3tZ(^>EJ&awjp1wCp!<l7UdG|SKl*L!FArhIpI5ab^(PM
zlnhVlwyl;NDy`-fNir}tN15r$-dWgNj3Pt#UKsCcngx678iAr^zs!h<GeA1bl8{y-
z5o)G$7+9kzS^<$S3gU=HQ!>BIT5v)pDM2#G6_@^J111yxnPMkiS_h0-6Qpr2jSq!&
z#Rt>tC(0 at K#9p$+?&nA)GX-;tJ5w)Ro6 at eybq7_O>WR&+AI1d4!3;>uO}4_hs_EO)
z3EzqV4vUbDv2XpHyBUg&%`?p!V7tHvyyMbKPs#0UlC9G#A{;R3WgIYyu`QDCP$U0G
z7D?#DZ^Q2+&hxMM;$jNW5P~&ic7u$9hT$wgbb2v;PGurSN)&>b)I39 at fXQx{n3I!}
zH?(T-`fOL4DTXCUyj+nSr(U%QV5zx&6no!zL-oCEV~J5g^?1Hkf&ls3 at KE4o?y{))
z&@VIXE_d`xws9F9Uoz-=Z at j(~ursqYjF2z=NRb;nu=hn1K^We at p#q8*&B#j5YYPar
zx}tTRv#Zdvva9rej)lpcCxB!^{@~>7L&BwzqEAz??nv5ve`n5c38qs(U?<N!_${!y
zzm?&+%MUdcIaOkFvw5!@v<6L%)vxEj^dv2l1M2A^iSWRhcnHl4VNEI$<P>jO%hlq`
zUWt&lx0f2il`-k{(`xupv<3&FPGb2*pM)s*U|qNN4^XHI$Y-bMcsnq6pwt3;llWdb
zk~GSs3%dpayaNY7O^=!kTgQQdkcG&{iFDk$X4JEZ>yWs3_7qrg^9j-^5ie6Km^xev
zA&biq<doZNfmC)1(D>{bJG_raKtgj|?`gepgiaehii^+}t+nUpLfd;ov`t5&PZz_o
zYsqcJX~mVx+cRN8mly;*{LQyWi-j}1Cx(i4Z%>@{qeQ$;FK-EePTRr%Iz36pj4?N2
z$U=`Z at OO!5&%xcmG4c<Y^lZV}zm%?f%=hyzqq3woS at -;}Jr`Z!%0k&d6OKP}i*Y>_
zXVuRZ5iVxw>UusY&^9hE^iHip)yi~<S31RNs0fbKwM)psFP_bMqLsg>q_-*4rV8}d
zcCNOCwgZxLa at dW<ehR{462;!bLDoo)!}m{^dLghZ?Q{W)Unwczt>fLttd}GzTW at J^
zYR&V}8J;JF!s-?v)k%oy!OX^Iwoi*cZptgTn5Sngc;lspigxId*9jil3;Wv={XB)=
z3mo3Rjvo;-d98{9S9h;Nrfe#_AbF7iz!N$;4r5|r?R6{vbibOj0>jV?HI42>pQZgM
zOC{*Ck)-pZT&YgcluuQDjVSSluH|B8gpA9`A+_?{{B{NQ6*{$|#q2-1SB!rm<&T>Z
zYLBEy#Vy$k$DV!UW(vJ+c29Yio(?AtTAn4a)%AOLOK2j3CnVOKqjLH33F(jJEWnJk
zlxNu1AJhwgI$IZoJC6?EL`L}jM9y#8*`E^Dtf71oC{a;Rh?W1=MM at BXc5j|K<?0er
z8@~YQzhjX~cBq%n))8?N4o!JYn~N_AtNzkxG3U$Tj!PUiDW0=>WBdo5tQ8F4UJ(I}
zoLY31NBet6GIq%x=tNeZUFCaEx;KosgUdrbUBfA9`;48Z?y^N#mN97&Gu}XqbI>@I
zYnv-}nTEbMRJJ=J*H`n*SG`n`Y0=HXsLYhKRrbz4$;GNg_lGnh?@md$K9 at oSC)!TL
z!EXgGUMdgCqjnAtJ#e-(R90L=iu${+PTkW*JeuoabP<V`k{x|h#U#~thd2+Ub{N5$
zt!K<LEbZeBfrc*Xwl_T$#1cgk*@Q~TsfBed67UxD$H-YNBiak&aX`2|vybVm=;(ev
z=JtCy<2hxo$DNPyvjzdLTer-VK?+wA+pQpSr7~&5eIl_r+EW)Hi&Mv!bs8Q$dWVa=
zv{{`b+m0VR0t0g=xJ#{fj<#nCH+`g?z3<PuK37}hT{m6tB%L!a^Ku9)O^L+<B<ttw
zA|D_cyVosO-Yut4!KfeH0XzLvdR6T}z!m{ZCf)C)HKVsJCX#XzOcM?#E#g6itUhhs
z+#`1<o}?D<=D>xDnR}u8L|k`Q?<i$+9TFznUwX}=EiL^M?_1nGi!hp2rz)7^Iv=RG
zH2meOZy_%X at Fu~MQpcXBJQ7duq+J8=0cg!_>xC)^((OdJl^p{qSi(STU!nUYarT*`
zJC=WA54nF4*8->$OG)Z*t8Uipy1KXK;l7`IYz3_8F0UC)n7QHWfDGNv+12+YrI+PX
z8JZr0(bQTlgMG(#dnnIWeZ<$0ax`fLykizB_41Xq_svB*<yqOJdu*yZ7Pe+(d3bq_
z>KrbxNNjk9f=D8`$Mie`Ll1>TUIsA5X5y&sh*4XqD?6T;26Ih?JwCXdtK`_Qwj%Wp
zz_|Yag0FrLq_~d(q at 6#FFW5xh4!%~tu0P;et{wy^W=8*|{=q_%?jE3yV{kJ}jFa?m
z*%xhFCjB%k+wORVOoF)KR<=XcuaxMxuwhW!BK at A_(_a*Iaov*#i_?nM?CeWS8%J%+
zGnC2OXW^NV5h<Il((G!NaV^`&=yQvq3ZgDmw+zN=zdbfZz33Q~w9b2-LbLm|)H*TY
z(*lkVdDgwYrT at x-zvx{r4!*KSU3eT2advw{>jcN+Vzn?oRhx5M{#p05e*eNEmr!zk
zR(<uz{h)q-)rY*MmX;G|j at Xp>%T=g-P4%4f{xX-JX(F%fD&)bnj4}Pj-OD${{+ at _7
zUDfA3FA5k0`sN|uh{m7ZeoxFiK~=u?kvu>vU=kz&Oocz4lks}+^$cF#Nn6#bRAw~k
z8MS{Nxv;k!q<v0ZMAoLKGO$XhV2sArsMSnz5?9AZT*CIp^A{wHz<r!QU_$GGHW|gQ
zF_2mK>b_1N{B4xdkKq$Qdb#nYg=wMz!#xeC)F_aFQeB|=?-3~tG5*V<>@U$29KyRs
zeCiWc;j)d;?p)QkS|U_a8bH0?c=CP)COsd`JYW5uj at oLsS;#In;v at ZUI}Tb0g$C3{
zme4&dgqh=X%W-IkiIj%HM&|>g`m7q&Vo<f(zm-f{u&k#YG202cwom-{-?Om16K&8O
z=4Qo=Nm(i<t#&I-L*qP#ytpP^g>2i}x%oGnmb~;U^E+D^9`?BhEzl(92NT-9yCCsd
z0iXwW3w6OZHN+;1c6cSqtA4pZGb{_ya;|jNimBH~YSn7ztK#*bb`@(vnf*!M!{e}`
zPyfdIBdV^5$@8 at H`zD%i7831Xa%$ROlpwR$$%~FQf~LO5kAn4cQ~hP<#B&iN&pTmR
zPhGRh_C5xd at tkgzrbh7eHT~M~3FLmTvAt{2y at MuVC~|e>jW&Up+;z{i?semA7A9=C
zIeF$1vV(eJO*qRxo`gw^7k-fO`KK1KeYUFI?-FM^6Cr!zR8M$7Ig_%bm58-qOPid_
zmLQgooZ&XIU57hVQQ9v$6Z>3dAaq55DT&>^9w0@|FDzh3rgZ8e*p;}d`?SC at KJIT#
z9Lsfp$TM at Cza#eAU%4YHp7r)Yar^Fyhm9Rtk$2Dc_o4?2PE-xewd|?$$+P++&U?*Q
zr+^rw1G+&(<%6oLvkRZ3uq1`J6PhvI&Yq^O7kXGsqKT8M0G+6AG`ti(knBPg>$c0H
zre2=rnxUm*)a5K;yYmivUtqKxdh~?(QDZ45WfTAylCq>(C{ZiPv1k2R?i6XAzG{(w
z?O+*sg4(hvR0p0VE>F4YR~gq3c3uA&s;y7Z!ba=3PRV#il<+30?=|K7Xq4^LJ%?Oo
z+u+5=$;N?6Vc-4rXO~yL&bx6}x2s;x;HdMu){Re~fd`Ioxvaf{1zY>ZS<}5M??#tK
zxAsoi6FT;dk~904eadA$zl%UQ{pOL(5?bj0(*nq<PsCZP@(Py6Ij5bfwKb;@^%>9T
z at N$I*2b?^cunVtGy}x{i^c-XdDvM=5AD5tw<Lc7W7$z%-Yg=0-D%_n0Q@@`3I%Ito
z^z!|+Ei-+?tQ7&5V3npb*mp&g`tp@~A(6M(H4-2Zu=gVSSXab{LA49<F}cxBx-zE2
z`LWt88!!4|5Ey)NHUS9AoRSmWgx}<)LgdxUJd!=YqcF5M7VP at y@`^etm;4iOB3j4^
zir~>V<JaFCpYlApc)#L~Pz#)ExXXJxowOvm-n{4Eb2R@(i?~z7d^7&gIf2BINl8j8
zm*JaY=X(M76PIYA&rz3Xf%@`u5Djkg^|9*UpX7{!giN93#lf_;o{M((h^gOFoA4dy
zw;5j|DrGh3ID|MrV;bkyrW`O*fTwT>Qi@&5DVc(K2dFU>gl@;_*6yzIRc=Xw?Me-M
z_8;<><^ieXYdO}Zka$;}=~Rgz4J{33C5BPjhS_jh_-B9}w0#1p`&K3xJZu-#N_CH}
zX-&<`vCN2tPb}zn4BYWreansuExeXB6Y`9Q_q7B}t9Au7Y~%KXG{*ncqG`!yAeK>?
z%N}#;^9>$zQGz57er!~9OfS`>V`(><5sGX3*)8;QJJ0F;yS4M(;OBl;C_6UGpg(zC
zycPgUms-xVNo84{glkJ`DukWSnJv}d-<!`LsRx~E;<q{t=Xpm~q}LK*pD5=Ocm2q*
z5AQRD6`bygFiydDH&%;0bDvV%c=#5Mg5~tEwBgpjd`JW=lQFJ})K90d<O#i|ZFV|?
zF<*gSec5{{uM#w?1EvCYf059~_CsnO*xxf at HatioPP{sWq|?P7kVfV9J#l`yjVdw#
z_wn(25PERr&Snd$H0I7Ti8N6Rl32TK*pLu~hx<<&N!iCcZh<Jfn%VT-V<cRQDz9!@
zcs5kj$`hiU1?0h*_4Au?(OxAXb-M<>)%E_1^BTv=KmDdAR>}7+ at UFWQReC9d)IAfs
zWR-O%L>;@{Q6nQv=amb|!k&Q~=j<07YZQ@~L<>Ek+Ox-8xe5meAG{sxU%Q<JU*$x9
z{J;c>LM|#C5=ul$Whzo%l-n<_IS;g6R-Xo502Nh}ye*%klQ#QJ_1ZZ9#rcu$hPG+<
zQ&9o`?ubTTMU5O9NePGH4TpshM*%wJ at aC_8hpmX2Gig}|FK(H#*{6lL4#$BDz$CTB
zrM3O}X#%FA{xTN1x4}3M(-4&nTS_`L8!5~CgSDuGCv1t};r<nsMv~fEsCp~Td#lGl
z@<W$HGur0IX<l<?wdRla7sd)fqdH)u7f+4`GbYGpyEtseQ#=E8$tzQi2;(8vxq|~!
zlB(I{?Jt#r6sA;c^6QwXZ8{UNH(h?GZ*V{2x35Sr5$IVk+sxyOVeK~(iL_-a0LHb0
z_Z^z9hu{SuG1>XAs=1J58_Xhg=C5*k2WRS}HMKQ;({HLIRpRY$72ndE14Mjc)b-Q5
zrO6N+!%aOJkDHW`H%Ax4ePA%`)00Q;aSWZh*A3%%9q?1|0~Pt3`^??<3N!`D5bB~i
zOPc*=>hR|pR#r9F%wKQ6>LK$yZQg%TiuXGaT`gR1!dJKeCeVFm{=QFFOZt#`QcR3N
z>i<ux;75Gg=JcHOcs-h?*Mqm(LSjjVXH8QU7OwkQAfgo6&@TD<-c`&SkZ8!n3v-rD
znEn3h&~F=aKWNCz7#fsw)-RM6L)HA<@8n0eXzmW1<Gb_rDf>#Bz-mj24A;obenVWz
z$@_jLY(ky}Yz-L#1cAp68|XZ(7;$3s*Vv<LWC;X>tBhshLN)#Sg;V|I6+r{(a)qvW
zX#2O<v{$?(x<N#4h*g6}xr(Hp(kdcYdZE@^AV1tRbn>5r^|}M^^ea6dH~o#$UwzDu
z#N8 at uhEiKXqmio^<?NFsgie__fU(lg?L8?e<|RnC@>aX+!2nzC+f?AwiVLOD_5o_P
zmo)FEPb&D at 29a$zBUfbmCG0nL0B_G{oMA7SCdBc30NnqDotrDw!~KV?7xrEc_EXoG
zuU(tpwp-ZDiq2d+09w-0<)j@~7$MxWRl{?nP2Lp5|M at lxpPJ+L^qBF}8**YgjdV#F
zk%FUTgBJFeK;exuO$r<}wqFWm&h}1?y{!3D7PlYigTx*_0PgCGF^wuM`1ckiEl`f&
z9j3aX?e*5O(0Z9&+}U}ZCIj#);U?Vt;jzm1h9o|S?oqcfjqT}*ZxD%u;i3cN+gS%{
z5P8QM{E<Z!3Dk`;a!)QfvTQtOs%hS3-{xMlLcSU)fR(@zF*$h${WV5>QTiJNx}0T<
zGd32~c=kivQ6gCJ{9B}NOmk3!=|&|D54uC(AU7NYSyDFx0|GkW+?bI~^gjakOrwWk
z9xFf3x?gUwxT}a{PyfRg{vci#<mov(vz)(R2HFi9_E*$tl5X#n(Ow<`W!O`YTOeFt
z$u_Sp{Y%68=Qt*|V-zewO=BRNY;A`u?YFIGVMFf24E%|rc+%YTfV&1sFE at _SJzT{Y
z>K>pV`!Ki2`-|dLP|#2tapN*#!LYjmc*5SzH+*0YewD?EZV<k_>ELPpj(rc%yFX2l
zMZ;XQA4IojG*7bDW1VSO8&4kUVa|p7%nO8$lw`);reWJu7GxW+0LDZ}Ufg`I6K~L>
z%?XclT3XU5Bssv#!Yk-(irjJMt$b<t#uwZ3`<6~V^OeGsW+HHUH%v#MVf=*w&HVw_
z6FXLnyVQMLud~~!q}TT)Eeq?b4EAeshez<~5D^w^)?FIUQ(D at I&il?s#*#9v=KCfF
z>4p`?{Jcff1kk7$#&Z+Brr{pFX}`MjfX!u}>R=+uvHAAz+}uwRGxMQF7mX<9%i|wG
zyhj-cI>P;-n3y0?33E-ep1GUF-+awHO+|$3pAr&-Lu<Z60q|&us5}-Jkl5O*p3fu~
z{o#?3(|m%vla6!|itIvM!|QpHjLZYbN`@V5Jr|KtSeU+fXA(3B2wu49aA+dW)UseP
z)Dzv2gY_+KbC6p#&*(@I10%D0_%l<ZH6OEnN}r+;CfN|oZY_Cc+$JyETwf;Gp5v#)
zP2S&!tZKI|zqYoYX+)6+aT9ldpq&@&FtPX>RM{0-uSdhs(ImwfSKeCuw%1)ro|lV?
z3<+_cQ>r4fB8yDkp7%J(RR)qXbH{%?`ow&-B504CL-x-m6F~qbCI^N;OH=C)+t0h~
z!u at QUv7^t;K)F~qY+4$8h9nKhDD8!7kOh&7^w4&6b=TeBKHJ2aP^DwfGTzGIofazn
zxXk%~^GF(6?_m at bYU1KCPEdUQ)Y`wzU@;iKYfzc`|9sQ=u;U~E$*koUQ%R2e at hp>~
zo1`+ZlwB&9^4qUE{kMm>)N)J$L2l=NYSNFs)F^~gTk;S at 2p`7ZQ2JFOkDL2bU1;q0
z{Qd%<T9X*D*}(Vz1*MUuTT>w8;IzBC$j($YuS%cr+^vb~KOR6ttcvjMhO9{9B3X`R
z27b3Saqs5<P_9DF*v;(`k1k1!`T#Ofx8l8?DgPGPA);+-TF|g3dPt;wAbw&iTMa0b
zf3fnV0m&aIn2&ssUv#ZeMXZa=UQ^HT6+rXWJ5X4{Gxa=uotel2`;4 at p`$~w+)R{8~
za-tD_`VW%nXwo4KV>#_8lwI%ey|H at -e|TSQ4;XVLv>x8bND{&8 at EC0GLdWe98FJ^d
z3W5ic^!7)d at S#}@nsvysz_CooY~I&`RjbWo(JNu%UnLY+U9B=}v(WcP<-ilsj=Di0
zT0GM6AF-Qe|KzgL%{}(9Z+7?u7pQr-M^6vwux4iD6cpJw*v5X5_utiqPw4J~)mfrl
zdv1to12N3Z6w#lV_hOX(>4`IZWA`;n-P-zANF#x;x+{xF;xz;5dso}t<I2>ld~Eke
z9t6D>@&ttk?MwP67qJhRyC49~ehwC!Aa~EBy<2 at 2wV47FD~D1q$kfd$F*FAAX^Tyw
zFZ1>2ag~#@Z)a?b$=<^wS%+C{^B{%aJ1BGu!)(8h&Wva^d-lbVdE!tiQV#u(_GbSW
zop48aTGlWJ_iu_Ulwq9U6h3GFBz at 1A+ygcrqx2jjIEd*|Upl{I>~IW*L{P2CE3(_q
zeVly=Z4z?@oo*2F6qon+drV3T{)jso2+ScQGOEEB7UveOFu}^sFUM^)>8uOAL2Wf#
z9C)+p=I$@o^u25imS=Q#3AfqloeDp9<MHNz7qzXeZES4pHbSvgI*}qmf7X7%`SYM6
zGb>j-?O4!ma8a}U6M?!uuk_(F<R~7EWr|Np6#(7w=ot;2b?n}V8ILig8+ic!gvJnM
z?kMA>9W0Nsu<6~Fke1iAJ9Xb4-K67v<KT8oEvwSWA=*#=e>9zUINR?R_d988by3?_
zThvy2k5;L at Y3v$_k=T2-)l#*Jnh~Q`?Gd83Qq+vtF>8wmHIg90li%}P&voUm{E_SW
z+_~@1xz9PT_j%{C7H3k%(dLVdVvcBZ(<Oo;lF_HG+HwptbXhr2P?)UFg4_LGdUP_s
zZ4l0kl9r;a-}~_Y4ut2(hUX3xaF=WXnFm`Mppezy#j?REf;H{k>Z2e(aD4JO3e7My
z3{&n6k|UXlrY`eB4-Wddd^ZNukV+FBTdS?gl>a|^h$mX3RQ71qzXN~BpW~q(?35F`
zBBY=4_v|LGL9Ro9Pv(`Ff&qYjJY6yutFt6FYE4{TYG8X?b^=~1D<MIVDslhw(alxv
zk6n3NvQ@(WNu=7s9_W#6+|jlDI#=w^YLFanN#E at p+m0EUqxht6Nuz)7n(!eH2C*6Z
zp(2G3)@UE~EVXrWZ|dhc`GCKnR)n(t`+Yz&oSVJ%+bgjP`IpLhbF2S0`P#&h1nr}6
zcA25c1;w=<xt!n5ej(AQx_k9Tsnu(De~Ngw>QCjZ^a+Cg^a)#5(Z{lhd!IcPwU&Q5
zjk)Oa1zOKI2L@&w92|5Ma*Me at Vm4}LH$SA$_*C`~jfwzQCe!87w`y7S%h3fmUXLj~
zMhs#@o9SE0sVL&yR at E3;f71d%9EK0J2xWdtXbcAmfzah%0M1x;7POOl2INs7lv_&^
zJ3*h+flO~k at 9kRJ$#DqCq+EC4C~jzhn!ST_EH>5*dI4_RFJ@?Gj~9<3-FQ+uJXF}g
zU9|*T{S-#3*Mj_(wI0NoK|S|TrXN=KJ92Jezge|GdIf}3o(bQ{7s?A~z=ry#?<&n2
ztJus?{U?m<m8T-W36|!k1}wt!ntfE)8~6}*DP&|djNRQES$QWrV!1j{-h|p~Ym_5L
zg#=g8i8$%uA}Gx~`!YK>w-dNbe!Tk8b7w2{Dfdo5tgemY+=CwPTVZ)mV`INRNs`gp
z_G^85Td5<iny)b6Mve{f2Lb)wqm-y*?k1KPA^_65ruH}asWFrHt!tf^q_1~h9hmg_
zh$#<^lTY(5<s#2YBSYe8iEWQExQ=%wLm6CjClfxep2(3{Qf2?PiYz{pm%q;0K?HPW
zJ&na^Xx1l at vmHKvU)m4NjiU&5l)n(<6JJi^IB}Pt#g8fqQIE0sh<+m3R=72JpDeUG
zX0kkf9vYeCZ9|>%(c|Gth{#^Db;DXqP_<6$g#GDa-oL#yrPZf>19^WN_rqdn9J#B^
z*^mlfUVM>dCU0i2H&+j>u0FP?vBhPG%sxx8%_WgY>PG5yZ_c}OaswNdU7;)NxWG<x
zxi8zyP?TM$2@>|3LKI|dUX-5qcb>ib<av3|(+>8*Bj%ZWN_(+I#}Nxk>hYKRipcN~
zmBK>#<BsH{v#n90N@(5Mv38oD$eHM;!tew~{5LPs(QdYJ)UpQj;8Enkqx1Plk|)W2
z)fW<dm9ITe%@daTaq^TBx-}CGo90P5%112XpD~I(z~4s5^kc&Ni=)d8a32U%OC%fY
zmyV`aGqOSN`8%?EEBfnOXXwjxdvk=%6fe5gpRK4I4N+V9r80LvukJjuvCSODpUtwv
zgcAorp#c~f(s at vBe|sn~=yW54q-v2E)$(~>=!0r=!tUI=@)4KWl>aLJ6_0c1_#v)X
zT`^1!o!?SV_P5e5wiTZ~rBFVStO*fv+2VJv{WfP+#EIRe6*Nhvf?fMSh`4zyWcMef
zyeht`HvU}+du7A#CbQ{!maK;LHlA<pBaq1Z^IYnoE;FY3F~VGMXH5Ysru at dI;Z^}a
z*u8sG6!@p}w{F%0=Rni@&cUyJQY5(q(O|3KS#edlS`05tKFX)|sc)q?KUN69 at 8Ml5
z57X~#6I`V4m3KodejaV`_o+H>6!wI#QX~A|=khpnn=Ju3Y+*wb?ugO{0$uK&rhN3V
z+(BRHZuleK|46fK!n)^yM$Cw162PH<l~FD_9G5+jCk%OMS<Y}k`IOt`RWrXenlFw?
z1HI_vJ)%Qo|Fw0=HxWztIpn}y#r<BiM}I#vr`?S~>b03I(}tw+pGa1u5|`bog!e;K
zc;7|e!2x_Mgt8NewAU8(WA=O_woaBQoP+04Mj`1y_H>RYOEULz`Wix?X?$P at 3Q3>x
zZz|H(`F5Vdh*#R$U?IWOQSiK at ZzHuF*(8Gd$^FZ%OaHVkqN^0tfP4-J=#DUx|8Y=x
zszl7`L+-&RZ~@x^)Y7Y2(rdoE2S=kZ;SckOSv8YDMUaY>-5l^=)<~@LbsL~<M2t%F
zLDtCFnYvNNvsD^c52fAzHjm@|W1V<<N^h}hTJ&@P2saf-b5xxPux$!|qwc}9tvjS>
z6$_jveYdP4{7S*LP?XlnV-4Ec>1>a^+=5vUqF)BnZ~PMyWBS*S!!Xa#KX@*H{k92z
z^CF1#E6uk#aGdZ>cs{!P1v>uA(@e<2rE5C at t&0|ODdfg>BXEi8398)8HOWjK2)}FG
zXfj}A8LxUT)a;5A9DQ*)v0*tUdLU$3WzO|*o^ny72Ry$Tx{R<E6n2IXrM`Uch`Of4
z)1+POBlO^VXv0pp00(@0P~O0tdjvQS9!MkTbu(Gc+g>Me+Tq at Cr56Swrh9-&m6ZtG
zMp1a(`<oPEkA0_Yp0<RYK`V8>t8PTmm7^CqZp+W+tg~9#V%MTMUZ*TkY>atBUY03y
z$J=`e-9M~UVd#6rFwZ{3imV|4f^v1s!rxvXl|=;vS!Sy#$e3l7%|q0ga6Jn`sNY9O
zD0U8b=P6bGcKf at x?ET>>?bsGFC;zJFtrNf%PqV?NZbk05-_e-T7=8hJZshmc7%6q;
za9Pzm1<S4m6~PV6PY2U6+Z^16ycdZbNO|?g7FLbbk}+yTP%v_uzb at yd9E$)Bo;MM0
zRUNbW);SR}kOa{#Uv668qa at WL8CV6TL1UMtx&3Ef&d_2Nb0voYa(56Pb at CM#B?0b5
zq{hS_jJGK^my*zt(h#zX2coQW$=}DP>du?Ffv?APvW_kN9!(VC7Wb_W5zzy8gtt|&
zIa+iEzB88C^MSHDiu}ofIXYa87Hf$1Q4Ni5V4~QZT8jk6zbqVA!xi|qj5~jkruiWO
zp#Wt{^}*&JtY+%IUnijJL8ot6%5PqiE|&hEOrle{RtLKoxfm0Uv0~A%iaUqa?sZl<
zTSq;wWwC2Qfu&t3)X at jTy98k<3Mr)8kl!bN&4(VG<z9%A?YmbOE(DJ85 at djRjPd;g
zo3-D_=D~o2h0{$OVf<-qx796gzkUBI)DGjZhdH9Kv1iumg8N{d6XDL+EWATgb=t;=
zm^ecJpt_)-lbkG*`rM(YV5*>3xzI<#?1%M`_NBo4rmIEnlUTg6ONNO{urfl8vNaWX
zHH8-33dv0G+#@I=2xeKtjyvm_4fbp4CvLwIJZW$jP^zIHePT0>Hk#H`G04N1S4>f#
z5pw=u8tBw`q#(h3h^?=qo!WxF&DNJ~v*1$ya>z?dITQ2YE3%v0ZV6yOmKgw^=tOCy
z%wLDztVfnk+p?5M?v24gLp*stK(HS^m`>vV2?XRGPSqJbn)e0%RsFv(H%IyrH?#o!
z`Q~r)J8uA~Am^LEX$)_tcID<UzgI}>_+h$q|KH7cp|_mdAgUX-6C<?#Tt4(p```in
zmdn_YZ_f at z^IdSokSnh58<lIoiP|3Etw0)8EIwrU{k<zyGgyOzdk>wP0IWAF*K2Pv
z4`sn~_!cX=JhF*zIYeky8=D6IK3j9(DTBo3`+vT%gwJDqGBzi0J->OD{`jnQ!|Ka}
zYEm7K8-W7^f8+`>B|0#+t!LiJpZ5_bR}+dTd_1hNVKsw2Xy{4(j_sX@*KXE{vHn5p
z!{~Z-tm%A&%$a`Lr(zgK>t%pmm12W1Y%<p}nYJRkGThAIzwpk7BPmZQBd;pE^KsbY
zg_5jtZhxx!-v5iWM-NI>62dJ5y#FU>qUv$DbCt2e!wJeT$Xz>Vf^d3m|7zVy=L+JU
zYZ?F`5(VLX<`7h7D$jdfxUa9-HL<?_zxPa3{_eYao>hAQqX=7-IhEGmMM9-31+~TE
z9qH7BKb!kmE<6~qz?Ro@<C*Vin&_(+qPCHO&=Jljhm?|=xS_O;{fsd>uc18sUAdY0
zgcQUzXWA5-j@%*<xobVygzp$qNb?SpQgDiDjdp=h=?nT)M)A8YGy8+T#>iHs^MhXV
zzzhL=>Uo1OG{poofJvWtyU~RU^WV=d{m9)AfoL!~GK)4zOfXBM41)n)zAF`1rd)H#
zxngI{{-1a8LV-G2Dsn~X6Q%#XA8plsS!MX4x<+b(;*p2GX#f0#;uUp<tsxmsAC~36
zyRc7_9UqC>eVy`Azx5^Gmp`9atdTs44=BtX1#_h7v8#v~0$Cn>rMrG6F4oyMwu13%
zd8&oX{Fp_XISF`(pLG84-*(w5?G<!Q<0wqOv~;Ji<B3{LvNIe_mEu^RRgFDHY7w^I
z$v`QL>JwUte>WGaLXC>)jV8&ugD77u=G{dLrAo!`w4ZrKOWfn~{PpD*KU3&SqV at Nm
z#O|KcjJbG9J^n#7OHR!npkJ%a9E at IT!Q{`*tFKXxTV{lc`GhNJlTKcXYU!jb>;jGe
z(YSj<_Nk;L<aOo9zogeF3bk5~uDz^22us?{Xkcm20Pera9H9sIUH*9cr2EUN<yR+(
z_G_8a<DM$1ls^a+EI3e(og0qdO^(ia0Oh&+p9Lmi(9x;qcV4ZtsyV+73)7I6QAyX}
zVhImO_ at rK2PkObQWV&vNjGETGMm5OE-{MI+y!Bd;WM3Q!$;#QNeQl=SW%bTl->$%L
zyQZ+70U;B&=?dq<&?bQ2$#M~34g*9t4gQrYxH6pJb+4eHSv$KSy89U~u`X~^#O?sl
zr~zaNdJl5etW3367#|9T176seJPjBUu506cPj1l8?l1s69;zD$nN_>$T>7O~dA%p-
zxEK7V${bBrYGQweE6(M>ejDURwG=nQTdGIf)7~_(h&gj^s8_61m|kPd|0>}K7h7H7
z7n~Elty}tO<8)_Ci7fuXW6}w;2Hj2GSZK6h36M9fXa$RijI%2A#)0%#A1J}8jG$nx
zmhk(A*ss)0d&c<E=7Tf2wt!MTwA*pn#7upsr-{+xj~+s5t0H=VkGE&HcPK~MsAS5`
zL}B5ryMOFR6mQll^CJ=4ZQ?s-+C&!ER#j}5Rh4aFUF+yhAAMthZnfm-Zq`lNH>(GQ
zbS?VVey&IJ%KC;}ErpNt7;xRw7xp?krp34OEp&E{oM3cvvbdf+ml`GP9v41KxT6yn
zI1BOn*DfyFhG#AGP*<F7sW}$<!;BUgGk1NZKC(3*FD=;QQNMT~dvu76549<u3P&*Q
z8w(;2yFbA{`b9cJQ4ouuAQC-w&fh+^NB<N!93BjunSnJP`lD at Z*AM#WjqZ#26YhgR
z8khhDb_)G=>;$t^c$_K<_u9KA;aD6YLy*<q4!{a6cJ!XTrLj&L-=@tF$t(V=dPpb7
zhYa<6Q#w5t?<V-zirtwo?Ao>?ki=Oz?tR6&zSu}VPcDuNcld9DI>^yCM<Mdd<}dNM
zI4JE%?pAk}R*J{g5kv#tcen~cxI+}1eit`+i0#pV`z*qlo=&-6>Y*SsUcz!{joFRu
zJC)dAa~54z^&u7`CceeiSMSik599aince{aKsg0zc`#{aR+*Ve3>&g)_6Jb6xKZ`H
zHit=0z}(i-r|&Fq{-*7{a6y at zJzi1cmQ8!O<e+s?=-)r+<U8qUM^oXm%T4>#f_)A{
zmp8(0{={?E>1U)pMvyfcsC^!<$Ct3lSpB*-1h2iKqSemVuysG>-rw}WoLw#DyhwpK
z5Jw=af)X()_Qh&8MCPluS=2Vm@(-lfO2eD9gQm;sq>=I|1OR;eFQKw1t#4evX0$>0
zQ^N-qX{cN8v*R29^-TGKmKuOX)XKaJ>9Sun2kYe+0m6wKNbwhoNYn#=_J2`|pK5=t
z at eL^g%En_IzMruYGZ3x_Yl?!r(Gq6as7-qPYxQ4k_uGxHZjBo4wuQ!JoaAQx(naNQ
z)IOg1&zA399ty5ZnNpdi{mHyS%g5<6J%b>{kCI-HkurS}rVo9J at eivqt$6CKn|bir
z-9Ovt_voMiHSR{gw`<c*rAo(06^ZnaQuc=|tbn*g$3N$&H4oQ3EHiLHWV0(a_l9yU
z16|>--a37D*}q35aJ$aTTFw_i`IGSql?$gIiF?ARJ;bby9muza-j=FGN_tv)cFEJw
z6Y;~ef};FbdYSV(9G?WN_=Hu>^mdWSo+J<fwo659>t2^P at 16cSIqVTAo7JuUla>dP
z`0$?&H at L2$VYr8n+HWoMXWb~dSlEp&L%$UyL3x-e^VCFe-wOAX+th5lTj$drZtgD+
z6qlc5AXlE=p0Z5n>B+Tmkq(tEoWLAIG>VN2jH?K4WvQ8#Rikf<Lmu`Xy=J96{_x%o
zYbahMm+Nn^2yRDY>X}aS!&=gba%Wp`Mo(gB<)|E+yq^O7X#sazz$eYXrM0a%6w7P#
z|IY#le;DIp&n+bCz^B&jPet}4!{Ykg{SSM3o>J>9%<H^v at kh)^yOM%^)G``-=i35F
zR}(y-?Fn?!2*IZjw-)80?pQExs;tS<v_gt9z;nNNx{1Y%b!0Pn#0xXYI?2EQ0L<k-
zIL;Ph=(A7&FDLjN&mOwm$QG)zOt!oF^s4ClFlh5VX5(X9XRSLw`R`_r0RN}f!+yz!
zoHASsd<?Ss(5zaon$4pecQj6s<}NT^m8J0$X80p7P+x$ktgx*ink`Wh*UJttRloMD
zd3?S82X>`oRIv!}{hwwj^+zeUJ`Bd*uogZ+ at aUUATLElDFjda)>r`X{Vj*%)gY|#z
z)v at 1Y`&*wfu{ty>E{gM{^vvvZ^6FA{DeiX5?tcXS7Q?L&SuU(9<rVEXBS)RyN>hZA
z4&tNk5n_<yS}iD3{ong~o at wqWB`ez$;VC#B0K%(>1W+z03U&mE>{kDEDX#oT4=@Hm
zx!-QuQ%2T1x_!c=$XCVYXbaM(^l@|~gbhxde($(fjWy0z=-FNjL at x&Y{<W<oP~qOt
zeXTc{n?7B6W4fKE9Ct%hVYt}Bwq)`r(jb!Xapi%tTTG18mcg2*qC+QLV%}TAATijx
zZG<o<0M$=70cn<bC_5bNy+p9xOU$5zl^IzTrQa)k!Vwo2@@po}^nrn~K72uBToVi3
zW2VbJ&!C4Q|5{Z}=zV9F{%i71B2EW-D{>);-mzsCgl&4e)#Gz5X*PqPOBC-E_IB_x
zixa3rQIgw at v$mn*6<ngb^DHp3`^8xC15Nf_uEP_Nr*-`&0}{hP%Nvc6_TDvGfh~bS
z95cW03(B)MW6U9Op_IPgj at qMs-)A{tu;q4TJ$KJ6uFDBc-OIlQLB4JubZQp6E;m$s
zOIQ9<UG?aH|NhFdg*>>3XOTrN4 at oS1f^1|-)Nv(9t~E8y+J$y4O$NJFxJ#aY&5HFd
zA8Km$Cq9qCG0T{2b~k3QB;@`>Ui#&&{=QYUb2Y13;v+O^7Q!nV(X}48yf$Z=0mDm~
zw<yzW@%`{rTKTm|0#CNe>i at wA&NR!aXh60^R7j`ydrW#JiA0y1Pud8Cz|6sZ#go>~
zx6iXyLnBYF1FIMQYsJ4KN+T#sHgk0A!&j4xrS(ag+Q?divc_IfqWsgJvWfMtZr|o%
zvTYe&+2f>M3`fvs(<U$-aAZhFMN3>Us_5S7qiO_ZEt3K-skeGQ2e2E-$*vEOb4QqA
zN+V^)FAx_`Ja94?zav?C*=l#N27_z^RzawPC^8fZVMlVSgu?bar4343MpekAcH(D?
zDx0`dqtWFcj?1XL1J_0ha`7{n2G!*fme!-uck|iJk5kqL$v$aGvA2X&%a<hF2p}lc
z+-o>H9ki-0i;-=`An?tjpC(6Y&_%d$TXuziG#H(g*3$?83z93FZ;MH@(hY9-Tn0`Y
zHH?VA`fbr*scN_JCjGT%GyPfo#iF)V#j*C$#N1$qyUM!y+=ZyXQQgs4E`U)Cdi!2&
z6Dj~|R!%wV!!c(36OHTkF4Y2>^`rH;14kWrJ$m=~FRH7K&N<&sDFb at R^$Lrr{_?x+
zZ*tRbQ2QmW2hACa$bB1>oeQN{@nE|E&tv`4-lvHmvRs{?^?KLSm;Am{DUn&-H!k7I
z2AgxEYTutyHOZq~HPf{F*;&$z-A1LKI9<Qj!r<Hw*65dpO$Dl$j0~4}cfJNr`Tv)i
z=MW)a9~c at pcp*Oo6|VpEAl{kqGkohFqxSHy-o1dPAmU<-pCZF at thWYJ(2>HjW3HLB
zg4`z3c73qecR1mr><_lGmrcQ4Yos{v^B%V4h!~T?+j$+N+a#OP8UBUXKf1PmcXVie
zrrAhK69$+Dbz$;Dr=R2w-#?aX-$QA!uU(<^CQx-oIpqF at 7GLPp2$lZA_XOYg8?wxK
zcH-j-k{ol3(g$PwyixSjF^mE+?LPuve8BdCmD_rvdKD^n`QmlsQ$~W?Q`nLZ5=Hid
zIMv)!ix+u&(QxbFgZo>cm;vC6!6$1u%|Y+cD`A&vajQ?Ru=LXg>{f7@|LUVs1>e{{
zie7t{r||3C at 6XBwQ|LUl5-fGAK2?`VV4<D#j{LLhcvte&DT84tRCUPvwzb!wMB4>!
z-?z`ov5G}3l<?TXR<?hjPAGAW!0tH1<7Nhk2+C;OyKNgun$MA2 at ur}xv#x~t`dsMU
z_`H?kiqZiJmS=_LHF+ixyhFQ%%q_|^8tj}wD``2%hM*?d=mG)|a at L*5wGk0MB+Q{G
zQ%-~$_s$@7L!qg;6Jd}8wJ*7alF{9{I2s)O{A7;e)P4F?B8#3B6Jts**pNtR>h^+F
zn){<d1B2=xNk}TcP(DtYr-kv)JlWo at Z?oc)36B;OwO#FAxOFO4q$t^kp?Q?aB~194
zvbdMLpK at 38`sv=~y_a1UU3wpP{F*|C<cwy#(U0agY!l<n-0H`FUmHk|EclE7XX1=f
z(gBF^S at YmQ!Us93+{CVoG$<lmfBiG1zURo}BA}My_(Z%t;f<B6y^Y0 at MS!)>pn1fM
zj|$i#5X=57l&7nDm!fh~n3hCU$DF0j(x&BTIwz^0nah<CY7L*UW8I&4BoXxY{pNi&
z5<mERfMZQ56E=N4ZUmX7IO{A3CGodMB3McYy87<_tI-C4Oa5q^552FepUZ}B`20al
zZdIAQh24^SFYsv+?!Z>P(+2RSk at H5ZkNbeY(S6D<ktrqV5*I?$wjfjA8EeQBGw+!7
z_}Q)xxMnBka)_Mu{~%Ny|B{LO!%TsSCRbErl*r4zzY-paDMo(r!gISbKzIEg^N!jA
zp9Q~`iM>6z7N4}q%m(}W!Q!{p^y?gU8j!w(R4>Yt{Pg(0M^H!l94#m91>y%ay+h
zW0;0peWfgdo0#~-d&=md<e(c*f9ofsv-t0f at NyfxP7z7aP(NK@)KCA?U}d%w{fvnt
z?fc4^u88#-ew?>8#^%cdXK5(+sjg~@Ung@{<n>>Fj;5caj@&z8S=bS0m@#<%Q0CwR
zt=7U5wbZ9USzjH3zYR=SWM$<Rg`eEb_!v;3(P-SOC$IkVXQC!>m%XNq8Q#*~6Gg4J
z5H`HN&gf9{rx-gk;Cx at 8Q65&v8l3adqvGaLzSb%w3vd#G^hgT!ySjf>nE~d=>jhv$
zunha&V>^Z&XZN2}qGDTb6hH6Nq=`?8_Z}5pm4iOjk8Vx{W#$Sb2iADYg$$353d{@I
zL{|iBKcdloxEe~oX#OD5DW%Rh*C{M#p~smu_T at dw@|l>Je9QSLl=OO)K0za6HEU=%
z<BOlA6g^aLwMdg8sg+~(r^Pj+3W`i%os)sf)41gy)pASNozg}7%fEMLd<THy4e~ZQ
zPy0_T>_8r%WV?vtcX^#n!wW<MwegFpfEHooo-afrljqOJpCrKrJC&X{<K1-EQe@?Q
z-gFH)J)=*P^*(%60xF4hGw^zEUaG%Q`+|4x?$tzWDhuH6#v^DY7<cej?K<E5%5T%G
zk3w5^&HBoIWs^G%3X95}W%F)oVwB<|9#D&NVl!%_6Nd1ARZY0*?}~96qN&aQbI8#x
zwwpnXP6-~;xl5U|^BA2ggD`1l7nK7siOspRq`hL&vi{HR-OS;~%Hb+Tp1XOy0w%?B
z^euLR- at kf%E5lkweA at j<c;VYLn)t3*xk9O)r_aZ-=m$`(YFazrgoWolz*!R<o0;|!
zVceTu!Oiz8mvLUqWb{2deN~~j5$4MiISu6M>THS|4w~~4`WCMLPWTgi$4Ma2lvlSX
zz<bb71D9o>^BC)k*pI_iIl`k_(sA=emEU-FtqQJSC+AaMS49aYn|i%yYxKKa?B8Wt
z0^AqH(OSh!Qz>)^?F9))6vkkNq;Wnr8QuScOkUoD&NHq$<z(3A6iF(+cs at L~IA6RG
zeF9VB^lTW2i4av}BeoGXSEP*s;y+FJK2(sR2-UcUSLNyd8ZmP^ySRKFJ?sw)x#Y%T
z-6b`Faz=l?-VQ5rcyNQ$<JwdD+j at KCZIvU7NRkO6`*~v(qjVF)c8gc-MP_J{^yhay
zWDY{b^V8a%(LrU$QUmd9B(1GSXSbJ4#=_Wbk<q-aIGI!QGWj~!az{_-<-ewLaFvb-
z?dK;+&5vwX`tTWYk#1kw^6su{WU&RJmn}E;O1XTAqXI^}`F;*}N)aO-d`<xoxdSQ4
zUuRVQ{e^W$nU`n#mnnH7T;mX#Su3lJT6C}XoRH|!TgRH`hJ~arG4I~RfB#;5)=4|R
zl at 9w!-+U+pFT6e9$~d=ZRBe;>{S9YH&Jc>SLYR*?P}~O6mQE6y$l#PQjGrqf7&RDQ
z>lKpdvtS?U_(&X}h>kzJ)$^oKy`t&F>3|z6I5ZhkB4;$5G7zLG-NSvW?Fn|}8iey=
zz4PDx<wO#|vu`qRn$pTG#L1c>(g9&VH53x%7J~k?$5b at LrG8se@>p!?x2 at 8fTw2Sx
zTweY+F<;TZuzxgR7dE_B%#)rG7_tK?EOb)bV)Ip2NebL<Q8K<fJ!PpMrB}IZjr?0U
z9~gAWcbO1r>yb<oo-*rvwqRx(if0tb$t_ at hdINn=KQYvlKoP|b=<O}o7GQ(Fl>iTR
z6m}8UOSU$%SZ>QL%;raHV(rr|FDxPlRFoHr=UwYN5yNWjQELc*O<T{7KEz(4W0m`z
z8{4h9ah9u~t9}%T!yT>k_39rDx4IFP+5q->t6u4=5C5dJeB*(J=4y&$Jjocscbd?D
zeix*C32>%t^<>C5pG at sEu<JKQhOgaeBhO}UwNyXJ=TrW&r$?*_g=fY1@#k)Uwp$Ro
zv%m#h1jhF*Gi8V+31OQ<@zIXl?O4B26nimkG`Tc)A!#09F at pfTNPH(N6^?&d7*eu7
zVcnoI_;5D&1%U|R`maK_q|qcwbHpxzk5UBZ`s<$HFS60)CUWf%)A!BNvt6O;DFWyJ
zwC;*v<$s#}_jh?ht3szhl*0b<b3|f!j&<5^0B8CQnaSUi@@(m;&ZPOGp;uLYO=jYg
zik6zzAp<g2jH=M^alG(et(%WLykA^G{tBi6ePpLg|7lf>4=G}3v(TLt4r|uUu=L0d
zTndhY%Iw#M?bF-xA}1+Vz64p?G~&PwWi{TH+>Z>~FF)d at m_7a8TPz1fm928>ynHDM
zyY at EXBUWbVKhgo8P*vsXmcc=k=d!(G-Y+gr2bUkOl%dYD%-<DFOTHqF1ejO^80Bc=
z9uD0UXfj97?tNur<1PdHYz6$;&2rT)=!vRwo_35mY at P`wPYK at ehMFt>D7Z*tXYF at 9
z8?-vNKjF+15~*u#)O(Y&GQJ?&gI9`<89Kk*Z3m^=Y^4=9S2xApxPL|M?tizn9>QK5
zJ>1at(5@=a#^k!`sgI~ns*|%%pPv~Tap5183^kPP+~-gEUV1C#pNK?F;1RbkhjQS`
z(<_6&Z>=ib`|q>lR_;+Yxw at S==N`yPP2DrOuxe>#NB(8^<7}s*CFrPxX+-mQe5hu-
zSQIbSF>VeyDOhTiPut-L$MLC5t}RA;KsY9*&F#n$c8k;1R2eGMKjx+n9*idtm(3~=
zRWMktIq}(xW$R9^uY-HtiF5H9Pv~NLNOxQ)bsqm#tB_TUD3$=tXb3r;5Bc6c=@Ov5
zOu8T*pVcf)_V0HTTNV~-=7yM;8b~&V?`F<bT`$+JnV&pqj|(A<8&5fI;RgddYv5!h
zo4KXwy at pcrP#w{>LmMf}8cdH)-j8Yd(#wAn``ai-2rePXoiy7K0z)Jcn;OHxIyhTR
zvaMY|;%v^6V>bRk!NTu!$B;72WBgyq(wV<i61hKPYF~OvA>c(hz5m9c>d~1sXjG+a
zZQe?LdcOkUuiI}B;NKQuW})0(XjWA$+J2sKwj^WVF3k#Nx(n{h0(BO5Dk2K)+DQc-
zHm%jb{d-Ej7YzYS*CC!<CQX1Du(Zm<06>{71T&;^LStqdZpLNXS>{SE>L9dx?m+Dp
z$JZ@&8c}rZksBsu)6;O3i-O#3sm9RV%tQ!&YI&z(2Il6s;fSlTl<$}r8(~;BgG|ko
zP4qWh8*%U at UtG7nF=6 at y>nHz;{H|~?K$lsF`^xYTJ#}bPW`<`i_%vua$|zLlSH0N6
zXiQ!&3ZkuM!Yu$3(L`m{iES6(VSYtVJ4pM^q$6wfhACd$Ii~lhGAZBJsLH&twUttd
zu~45zpMN#-1ddssKtL(=T~z7A|D6&udk>aP3&l5`$SM5^`&)J5T{4CU_(tUiEX4-N
zc;%~~&;)r_DDCmx>Wl;5W>wg$J;g^^JgdyJEDq8iefv8E1597vcItB#W3EIEKl}Qt
zvN&%fZv#HJ))il at lIpk~To5lmWcagWXs7M<qL9h`;)&O#-$t_{)7OS*fAGNKHrrG#
zPmvZXBs6k5=pBVq5pF9W+2BJ=VEQ_ZgW6H3_bsZ$mL{!>#&FcvhH(e!38#R3rlKkB
zwE@#1vsbtPlY|f(Mh<ZPfM2y`dvyT3<RGXVy_z4X4o4XlKOQMD(JPUtGH3Lc*Q-j`
z(JS$l%BGvDNQ;WN(U?6q(!!fs##CNDai$w(UGYhya9}RnVyNd&zhCu+Po0sZLcBVe
zynNYyvA2J*_dfga^bTF4mGBf+N=tBr_krFc!A46uvvi#VUXvnci*i#pw?->!sLi;~
z^BEUKltY~{9BoMXG#aBQ-vo(Ig*6+OPMAA4j|E9vv at aP}oC4J5!laeX$-Pu+=U1-`
zP;-UlXV`|6iA_%K6aClv==69WQ1r7TkjoC8zdU5BLXa-zfgVW0Ou(#B0oPMm(U6Ih
z%o3S$nKtDIM^Ab*PP$B*$>k6a{36DDivTlD;uC%m_6=4e*P+kzM!qcL0xV+)ppp=H
z0kG;jDoDW0eMgevVen?fm$?z-$(E(C6l+4`8*QAv2|l|Rn31i|o2|R$hRAj^6{JQQ
zSCpX at cMsdGT@<sb{p&AG5G<Gf7%uZW$@87Usyk#zbgO2KBvfAtCd>ft+mV2Jdp*-B
zH=S~8WZ1%wNyqbLmyWy{mC9v5?r>|GFLy0Q`2_ at 3OMdB4i96NpK?ONVT)dNBYu?Hg
zBqYDjE}TaHOQcxQ{-7-q(pKMkkN=NK^2R{ov();YRX@!+x^CKw`}r(}rBQ1ApA*?&
zoP&l6JCOVlk_kSpYt9a|BF8~Dp0rC_m)iczc~F;RqqTVW^ZCDTQoj)- at Xl+Er2d=+
z1^IVn%6+!N)ejEN><d&B&>-M2fN5H*PV-Bz>$%dP8Jy~yK0RCO8JhpxK7VhkXrlMv
zJG^hR=35xA|8wU)jO^@b!IO2;8CrMi$k%62DRAil{gtov{ba1vSMvKXm2t^3*?v|w
z>6i@#aUEd)EGboup<>-gI-CA`zi-`}?MIy_y`U@>fjfr#<Os^!1r?@jqr+d#<V#2G
zn;?KT)pviOz&a|`-A>O7EWxZxWc@;UReLXJrVxmrOkL*wQ(ZU)lvk$$UBC}lOlkL=
zRt9xYW0L>9YT;}EmdrN5%Lt%}##aGj*8cU<%X#GXF&EiM=HA?kr65Jh-sr$$qsV0B
zW+>%IS)W=Xe>O)nHLB*q>Eb&3ZSOOPGaR8!NiqHg6f?(Pe><cdWpkDrN5_Hjnn#Uz
z3Qv<+gO1noUe4N_Kt at E0LDLhXaMlrv(mQY|>(lP4p=IburrzGQo74{8ItiLR<H1UU
zKw1VGPl!ZG!Ox~TmdM#gdw!=VGobvNpI`yXG%afrRek`|bGC=5rP;S{i)L7EUA7gT
z1eE`9>g#x3G<*_~I-pLDh!h?liB}EqCNAIjJo>oKN`aI(EB8m)lT)IT?^h6@^8w-7
zTTf<%rx8pF8sAueCBwvG_(sk17SDq#k?9zn>WcjDX?duvSh)5Di%JxS+I7Df+kX+&
zt at cdOsBndEe%ctrv?;ZF4HLJWAYWi2<v!1K99bM{xIl5w`1UM|0$OdHK;taFxJR%n
zH86HIVDYoWl`Wr6Hu?J=+OEY?pn1h=zwX6`^l-cLFu(6wM#ozu7P3DT-Om!GlJoGH
zuICb(_wM9!nX%^E)-<If&K3JA+5k(7FRq<lYLbVIR01d89_QzI*C5f>oh0snn$w7{
zd6$Yu<o{kULa{_&BgpT*Vd`*#{K?C?_)zljzMI5-^>rmm(!WPUL){%EI$l2tjrEg<
zNoh00{Q*S2{qGO(9r{*sxU#ON)OJ%y`qk(Ba=R94{sNlcZvV{~Dkd;ocNzAot@}@H
z#!FTxBxAPjwLfKUJUZ)8-Y@!BG7zY-(B3}$cJQ+tzu}GO%DA`vAs;+-7Ug?ZNkKUj
zgstGsG+25H7hqOpPQ%#Xcja7&lL1((dx<5I+?9N8eb*9{2m(&%$g>9Ana2 at WnTfL^
zOf+~B*<nG~=zG-afe)}^9#`$mL>2)bZWHUT<K*hr-22C+9v7{h>N?YXHXHfL#G0V7
zqMK=nshMyEmJAsG>F6ZpE>Ap^Uq)iz3j|OrEh|@S9sc}UpvKB?wl!-#wT}x#MD+;W
zr at 1V%&iEM>p5GP|K9yB{kRW4PLDwZ4e7L^ZwQQZoa%Y>6q*3^o71I^->(A!d>Rdd<
z_a|Xw);drwg-W|<!7v~Tz@*btumAfS at 1r~L3 at SL+#gdDpWkr(xG&hH}W)naW8PX*r
zS+cek!WQK^ZNseIdeM&@n9JHtA9Yb-gwp=UAKleqn>gM219};t9wDCfP*0358cy{|
z|0_nx+=#MBy&&hFez2F at e<Prh`{}<ZRE5nD_yn$G8}RgpSbBXw=gTO+Yc3$eH!}`%
zZ(A2do<)v^@!-Bb<dYU`>{&sso{6U=0}|LJm`3+;xGFi!E^+NZx+*E$`hMYrx72K)
z`8RUh8%;;eWqlP1-i4T=TR^4>>=3Do_%CSg)M at NpH~r|I*o0>PSAS<siaz;?nZ)7F
zx6w_*vsGI-T33aPF_8J|=Ua94=8&<m^f=Z25fCUnlb1X4KY4O}nHt(U5KX6WOY8l2
zT46RlR<RU~ZkKj7A*ii!OY at W)W56I~;=>Y$Q2<2mgJhJ*^|$l#nlU_#y?+DPZ*}*r
zd8@&W;B$b#q&gXT=%f3F_ivccau??+!1S-~Zc8%zu at 0X#XH6Z#CC+dkB9k6)=qKIV
zAF+K(4`w- at NPfHdOJ!ef<U%Y0RFNasswTJdFw@?5$fL=sQbnO8CsZ0JnMstW^M3YT
z-o5sac)nn}wOiUV_mBxEF=XHW%ML^}2zXq>D8S&Wf4+z2igxclSt9<+nJ;Kc-N(yh
z=}K}Y(S)!u_HIuaqvOeMU-vwr$ewOj3KyoZrrk{H=J>Rx+0&z8%<^m2+O9Hg=N_>o
zWjSJU=Hjwr at VgI@wA3C^x~s&MUUvfdUIDJ(kW_+D@!y4F<FI32<&SFT<3p8Z`hW||
zK*RTfFzdr}6PCgJQT-2vb?DGf<rPJrljl9(fos)40%qMs$S+g;#k#EbUEf|bNr<)E
z)_57p(icUb0Qph9BL9|NQuU4M&tklkZeR7gb4?7|6a5Xbvdh!cp}=`PF#)bYbrEJe
zD#)QHO;ddR*Tv&pE1>bL!EcraphiUz=k^dG)xXWew5scwR|}jZ;KpEOifxf3GwmIK
zhrrV5QlIwjNDmkayActc*Y6(fulg|k?>S)mJ$BOJN+si<cZpxqOd;FHxw6J11GgV4
zN#EoNHs4=Bmw%y!k{CH8tFKOD$1npIdZr-~dw;{8OSJM{>3WFf?M5{31sYAj+!z<`
zM$)1}JRfT!Shr2o!y^SMzFunM at 3Q$^=02e^-N at Hhq#<%{4&N*mhx{Q|Cwf7uNASTA
zN-Yot?ih1;ep!fM39A-|*2(XFYOoZRk-q*n-FWZfrIzzVrZrrxn8(<HFICHENNule
z>+_)YjUs;Q?(B!i+gShIKX>oSi|hY~&1SylW77FKPuKae>ISF%+N;6U`m$n36~7-R
zwSwECN7E08mzo^ZdybzasecC_;x0uiv_s6Pn~8({E;2LXkNYKb=O$&ckAJHT4u at mR
zpYW3bS)b=9o9zA!ft+;YKDc%wUYeH`)$3r?CJK$M&+Q>4I@}pfc|N4dD6PV#A~7RP
z^Y>J_+72L+ at o6qQZ$|pV+V<{~;#mHmU-I{Bq>Rz$OA#KOO?eY|2~IwOe_f&D)~`m*
zT~yB;rRyGSbL74h8YVq`S&JBv(hIPRRoGS6=dQ8?ee34D>`O*lGx+H7KCx*H15EU4
zlX04UXOrnvQ8tS$A$oC^CVX6S6>C-;w^0qGS0WNGG^>vm1vK+sUD@|v#`t|-WV7%O
zjV!WkFN0|!G3xuOgFdngGk- at RxTF%dhF1CT&G<QdxkeA=*SvMs&@b>BCi8sA?c>-E
zzn=yKVqjw+DO~{H!5O}qW1d=9ZP#3R04~_8)AZX+c4Va`_+balM%?{jvi{}@{h{TG
zzwcRS+uy(2Fb~1)?RiN5-fY>If+hNs56_fY=mY(+gN;4mhd%-kq;a>?P&mu^B6TAR
z9BtYvQ at u02WH@DMq5v9o165R<hLx<?+eIzT&#~#7diwjFB}?o`Vp)>{{IPv{2_?Q$
zJ9?0P#qXN>oT>Cr(n+M&xmN#|6_$2M%E9_+81<PNTa=5qS!<*v2$?(P^|QvxqT0>8
z40AHd0#j_pkIm73cw4R|SMk=%)9s<V*zEfp)j#&n3sF>?HzPTd7k6*>_ at i(EG-s7@
z3mo{SiQj+fyzjfS(O#pg#RZ|Ra(ns0)CA&LK8^?1ne at I^iHh-fHW2u|sG6~l_H+N5
zw^6D6S6BPYPup_TiPxE$MgKnwFgEWk`44a1Qr)vA&rB;RYx?k52~CSytF^3ZplEr_
zZ+K*XgISwka*Y0kwumM~G32U92Ru!SE%yq@&QvSZm4quO at 4ty!Yc5f}0TUfxd6xaM
zbkM!Op|A4#Q8q7QioOmN!%qV4>l?EKpRruuX-zEwcISzwT3e5CDF9Z`${WXTYTWzo
zHEasTeh%BZCi08YEwq7|eLpvc#hl^yuFhIBFtz9G?07EC^g>(9 at thM)k>@sz1X1iv
z&7~zNuBGGL*iMvSnVr~IZZ24ER^cX1&$_Ay@}&d{;SA#{bF)|D;5x%XN at 4_<3F{aO
zk~b-SY$nJk#ZZ_<eV7Pe4J=OE!S|`<C8N*tu^|-&7{8J<fgS%jw?;Qs>$BHf3+yhJ
zo3HIo4_sl2(^F272CW$?;|lv>KQPmY<s=zAr4MpU&d4=}M40Wj;p;5>E$7-pOs3XA
z$A@|3*C0z1y;2FfnvT+$rSsQ41K#9b69ZTG`ck&M3ypod7Vbt)RA9u}6aN?sJfX&J
z2IgwEMbYh(N)243V2a;-A!}RLyTi;W>TJpj%3j*B1e+K3gF$53v^ZR2`GP^kG|<b;
zv-321Z at 4_<9F6D*t}MlP6}c6Ex5U}+Be!VuYWHU#8a7qHmvOynk*xFa8imy%Rn-`9
zM9 at hDP{Ix0B0tjiek4<P(nCfPI@)0PimY!n0 at N!M<ihq~Ls=Ktw-5Hg*!2TpJ*v>T
zc0%1!I5s>Xl+ToHVT?4BJCPT at 29Qdh!H+_@%9|HaON~(DNKL!Ti#%*tU;!n0K1g6V
zo^$7NiS(g_{X+}CHt|WE;3NE~rbWY#{cVLv`~wJG4R*0<X{>6%I7#tTk9 at Mr?<yYg
zY%5#puAk&>0d(s}`!PiBBnL2%_Vc+vVdB5EKUW62^3Wm?=~rbXxG#jRcbk4+J!0{i
zL)jBP`^iT2*7qewL`+NGr6skaD|*UZcH3WEy{1APN*W7(n$~~xwm)VxdMl;zMNtk4
zQz+?=ioR~MgxMW`z9#=~Hr0INpgy(hPy7284x#HFK-)}i=YYv03=*gr3Ir&npDSG?
zE)VGQWpP{p6aw5+y7OJQUJVT6cRTqbM})HSQXgtoKUdHTXgl|{<zrg-XSp6E7u84m
z%(;LiKHqonj3ueAKi*HrWWKF53 at N_w>q;Pu^Wj7a)ZJG}wbHiH&1}k22agsG_c_Sc
z-?g18nl>`gF*8HCNRBV at d17!xm8lEUIr$^!_J8MVE#zMnA*8iWoJ!AUirF5(LRPi#
zeKUBdd#HTGo}3bKl111f>_^}d`Lzs{ZzE!Kn{D|t8c`t;ezqivALWyPDKw7vX9P4F
zzbdsoskRL&Dum{B6wEBy>|mEq%LDAlk8ChXW&7d#Q2EQ%z{!@g4qH-&T?I<fbT2c(
zA9u#rVoOfBIO`Y13_>qoT at ubnEk~;s_}Mbhap(C4JbQ$<<!Dc3Cr{;PRfP;l-rKEu
zW4(Uq@^4FvLXwL&q+oM}O#fX)Sjs%`7)lhy)}2ZvOqs)_EecVlRkjo7+z{DOAYcOH
zmtefo6VQSw>1gKc0zM=;1zT~2djUYDGm_;EQ<b8oRi=`xNs=eWkaqG#e~U!&S!v#6
zoM at O9=}}~{j0!V$cvRcMBfcSg?>6ksA}S`sqbzchrTyQ6oUmtD5k<yjI70xr5ezWc
z<q&{ELR$6trWE<CCz(^h2E~^_sXB~G)NJ?mC%O^`Yw$yMN%)1PT-3?PWr at KK2*1b`
zZjls at vvRY&G^`;{V9RBo<)(t!$dZ=eHAfp8*i7X4fnW=MPX!x!e)w|nY;GdNXRG4u
zz)q={5>6EMFXJvwVe>6vkP?Zl^zq{_OQEEcxzbTL at 8C)ec-i1jpS$a2jg#ej7;=*+
zW+;J;RfNrLdb3=H{&DZoz)Sgwn7{K`48}ovSH;6W-^5WlRGI6n9sD$WE<QWZLd_It
z#S>=~8YLBFtwGRQE(l3~&k22+?Xw1sSL at _|4^F}43Q%=dK0lCXU5Y|qcX&QsX{`3e
zD46N(1gf4^6zl%R*FiG|z;x*W9DM!2p(+}FN91FmdF(26z~@~*O8NG&iMkd9Xs%fE
zkow=rNtRy1p><I8)={vUBmDYi=vh4C3Fh?pr;ol(VQ;pfbnr2#1yGiUMBhzfn}Mnf
zxrL?+5#{q)q019%j`Ef at Ggd>BUduu3Wq13dGb8qaaKLAk6F{>;rTAuL8Hbn&OS?gi
z)GFuOfKPO<$t)36z^i3m+h7O6mBXOBft2Uf85xF-(?lGBj$%*^^(u^7j8zSm5bVGa
zWbtgBQa=qZT6;8F0k?MRc;n(j3MZ4?J5iO9wn%0C4~>kavB*$dOFE;gbX$qSNdNJ6
z-6!P;lCaH$Hw;(hhfgK?ogVVEUsMG8hx=F~+y2F~t|j3wFV+;Y&9RokkFptRFd^jI
z?dQ0R<Jqig<#5vX06s^YO-IogTGM|IWwIk#UOvU at CJ8leEFXLei$C`m`UEVjD{pt)
znG`IaR&W!dnuAq0lut^*Xr)+|Ch^#pQVRXYf3m89sS0QRreq{T*MngyOW(|OMoOiZ
zbc8MX{Z?MswNg$ju^NY+P2HNbs%kKPRguOy=dUVKU1*x9YQ#lZ3`dDQBKeECWi`To
zWuPNKCHUpO4Vw$8TMnPDGxA7Bj}pluBXQU1=94hZrAXHR9E3b1TH|V#yxD_oS(Gh=
z_gl1_FDbN0;xMR)S27~)g>iYdsG8+4D~o8Wkj>t$sVtl6$kWm$$+GF9jTc8NbT&1)
z6GJs&FOyUd#e(}0l?rQh1kuRvgBTO}z`gjEgzWOh7S<6aN;$6!$S%E~L#J8p*ECsW
zW>ytA^@hGt2H;YbU6PvI*8^?w4$lv9*GbCVcbD!cWUvdj=`pdJ_>`)rMKc15IZmI_
z9@<Fn at Ox_&WnecGYO(j@@*^a=VZ5i6zCMyhA*&VG?Z;^Rf!5Hvv$eh5=E|Oasfqe2
z-RAA`BrX+O*~f{Go91z=fwb9kxPSw2QF2yp1LfA!*=cvh2<T3W7zTPfElKhyyrfi1
zuhbU(zITh_rT8=HwOt{tq*>v1*H~S_8KbNI|IVAW at 0Bk`es}KFBJ~rS&DK~Gq6tJ|
z+yzg7H6T(Q#XOPQw|0<y62&2AoR~RaZ**=i_NIdC`B&oBNk at Q_ZrS%6UZoTK(>!p4
z2$iHb4l|R@`huqzs|Y^iJ?DYNm>*~`1)5 at X)S4^!r6}PrKR^G;MD>+|j;O)}C?>hx
zU3`KfC;S3VlwhOyRh?u at e6wAnzZO&zr02Wzj9%UBSAC`F-pwS~OgZrh-1H&*-z>bq
zBYEX<!pH2tl)$sNZ>eSM%v0qikDuBy>+}aSS%8i=CiH~UjT_CU&PO47?u=C>q?U-#
z^3)`yY6;jUriwJCsfn|`A-f6mgq1O_C^wk!N-4OyX2YR)0A`c$NWxz<%*Mbj$QqQG
zXNa3FovT2YRtZT>xROu!mQfQ1N~NWoDm6>%j^SRXCN}L8W1oDtOaZ2TE1H*Dk>ssq
z)4=Bx at RRt!-Fr5?!?vcvvcgRY>LSL@@$cBoq{_$ZD{iT+h-gbL7OB?XfvTMQhL?3t
zp3hN-><8#A?r_+&H}g&Lg<MX_G&Yr2SSFhfl?Qa3eGiFpZ+R|PKvOzzDPqwJQmK4I
z_cK8e8vVcAuNmB5{vB4+kw5x3+e0_dZ^e|<1vIV5-p9FFR=qxYU%kwZ`JHtnKM!;7
zNMV{vJv-A8-CoFon7Pe|>|h?@i~EyYn=4&fT1yYW-wCOrI~bZR{PsYq+d at a>qP9-j
zptdh=n_A@}F*o=O5WaE1*U)%k%4K_ at p5bZkzqk9qO{n-t<-`sjdA>pP1Ivvcj{!|h
zQ9cJ*tY(e2Q*O$r3$JHYOyiUjLrZlXx7hKW!8X*aGYf(#=DPTli?(zNSbNeQsIwzQ
z at Y|THHpgcv2jTS=0aIpWuPciERxvf$ljD-=J>v0i%--9!jTHn73tGmI_p`(DJ?)FR
z0x?xxywG)hnPmyDV`OT}8kkOkqdHKG at V2f~EwAuc<W0cCrIE*Uf3z5n;P<*x`!+y4
znI(g)QJO`fa%;cn36%`uvrmf?vV_JXPH0W(jyg^7BaUu&wKYMFmaekwZtm_CnG)mK
zVaTE}wCnSC&T8#5U;3lF?+J~A%!jdGqzo>CLEYzVqup<4yH#GIZYFZ^hx&zOsyT$G
zZ*>vZT2B at McB{z3&r$o&+39KebERHVIsk8CI30n;iq*NAGX=A6oux;wJv#Lr)-al$
zQ=>xG-4xShfWwBfA1&u45-C+kil7-sUZwgGtMFQ(xW>42r4H0skOirxZg!jcQl9q3
zJS`1j5UwTK=J!hG4C&H(P)8qx(Syl)8#m6>luyeS(AdfG&{gjYu4m2-4H-9954!Q2
z2^d$EyE*fi6{VH$z+?+HH?pa?Itz#j^DXUxniEx}4HM;Vre&`iTg)fQcqd{l`Sh{J
z1X9b%FHJXsJ{AS%lVS<`zI=YT+%T_HTB97U2Dh4NXjK at me~h#1EE0s3C*lzelpy?Q
znWVZOF=>kLW7I<+cT8KW4;m{%_7i0M9hXoK?34?4U~w(Ra)nEya!QwA19-1>6AV*k
zYF060R>7|B-IS<O_Q)>6mJe$;u1}1<c=+P_E^uU3Tl(g_H540R(HNpym0~_8 at 2w^p
zu@(&ThyW<S+*8cUr`hDaLp1TH{pHdK{JI6FnRAd?hQ|M)=_;e5>c6fCf;33SAT1yu
zFysua3?U#bEjdF<cQXP?Hw>*b(j!QRbeA;JAzjk--e;}%|Ah}T7Z!8p-1FOKpMCb}
znJiu!Ez!`l1b~S~92bro`2HQ at rmlNBz2Ry*-P>U|@8h5PGQ|hn{U0R_I%P^Vp*rYd
z_V2~C1~1Nfzhp_?9<fZO&wH=*$qUha7<ah83-}8^C6&0lozP!sD2Fz_9(p;xyh&js
zIW_Ly`aLsq!lvmeZn1Gjdw0q*>Zhu8;r!J4aH03ZnTV_X)bA^N#N<qC(Yx=6-%ux=
z5sCTVt}UYnK|vEG8bFuweVP84(n~iWZ&kFO2-&|H*>(;1 at cb5cPze9tNWo4X+10kW
zlRg)(#YBk--mz!2G8ybn##WB at PPjHVQBEq^n`{quqokWZHv5BVEvuKinr%v`qA?U%
zUleT_n9?;h_^iq}2+s$53Om at nuGAG?_(|O{+>}}u-W(HD1(L*^@NaFM68WShJ>{TA
zI_x4R-LFprXVw at s7o?>y-{Qu|y)QWM%JMUw1>A(-nCg^An(e?|8yj&3s at -0f>224k
zHxx4qV{0n<6w?g5PP&Hgb{O at D?*Xhd;V5eOvi5 at Blki$h<6~O<ioeGI>;}a-wIb0I
znTlp9z56OH7wrPS*emifuD|eo4(T(T=meG0nct1;4-rT-57hu%S&hDmkSzrd6~&~1
zL}tK&fw!^{Ao@^@$k!?^xtMu--FLBhec0+N|8N`Q at O@IE;Kc`D{k!9!Dw`kBxt%G&
z58RV>7e6M8ZK`yO-FB?+t}arp3m>ju-i-v@=<e^kTz`M~2ig}zG|ZOR){Ezu3~sro
zP^m~9Uq(ybPqLj2i&vlxv<azHwujw}(z8aVYp-eVMm}uUyfxQ;`7&zpDxdcbUetOo
z)mm5~{t&-85ipq!=*_j~px5`rtz{E;wFf|bx|vx;8CCCpI%RuZIsQ8&<z9Bl|5~xx
zaYs at 6<y*gh-yceB-+$ai9X6FtB&0V?7FpNp7Ejsjj#adLn<%m7pL=gv_4|bB!YcKk
zP~G9 at ylvdq|89*nI8CKySDS}Qqj`2}c%tGj>7?NE1BSWC at P?R{BB=-Tm;0O6*1~|R
zo{QgmcH74l68U8|Mgv`MqIBekJ{p~Ny%}<UKR=O18IhmX)0+3(FCahQdh5eZ%ENVW
znnBD?;lsR#TL~NC93c;tOBoUI#%y(g%a+H#v7wmXzUxmUs*ENbwclGFhL-C<yjzwg
z_9jLC&2<HF>Dyek?>0C)<vrXzT(@NTUhk%<+-p~~-oGubFLUsF at PT-I`+m2gAmR{H
zV>Re{ocUpUwNXgo`u4+){44SDiv5iD`PJk3KOeN;OEs4wTF$B&jP|TYOKrunOQx)>
zw+3GAek##d<t?e!wW=?f(ezOOP4DQhXLNN8Qi|FP2b;Z&pedypRHI$2>r!`ixmWzk
zzbw?otR^7MLJ{#Oyhgk>0NcHMjei+IOiTHzF*!C6>f>DHn4ZXml;-+3JEmZ%7z4s!
z at R^+9H^VvKGg?)~1_>eI5MMEbjzjJs_{o!7m+};*vo9zTs8q5Y`=6-sIRgU&U`Axe
z6*9N9^eSV#w9%P8YL+0_3F?t2Qa!VvDnzkR)QJci&X!Bd&wRcZgJ+)gLW4b_#9o^p
zK_Pay2ks;w&W~<p5M8pH={vJ596H?EvgjT*U+1QreljgQE!ZVI<0u#+tXya@@tc_}
z+8FGQvqr>K2)NRoW>@&1qqEC6`3#%AYf^KD&bpfS>X-0~rs!1c&l=NI3TP<>ytLhX
zKtj7hgrO_|XsVc2M~{u#)c^LCoUo`>EBrI+TMN)m?|)AG241vkP%HGRRPUKUBEL`C
zDd<~6P*#Fj3P~l`&9#)L`5%|+a}A~?Cu?Gs#u}$}uFnJR4J0P%tpY at KzE9{}RDO1C
ziEr4a6diXVJP%7#M%dKq at 3_tZ!&7Oh#F8B&3!JnyJVM#3HB$7Tk3Yh9qC&6lqA4fp
zv2&}qCQE9sK|=+n$SPf4V&?8Y(fUIT*vPTh@&hG0fWqhao3YnM(y!6V<?+znoyqSZ
zZ`L-inQ=t*Z9y$DwKQQj>uMmy68gEwhR}|<&4DEEKjmpduPqB_zYbY}0;|R>%0J#L
zn}AfPY(#8JlxS79Y=r3m)K+4Z-)B*BZ1HWf<ePCt*`#yvyobBn%{7}*^JVm6z4*ky
z!_~u-OJ>|THjB`_{TYNurQ3WcS)*|BjS;mS4DDqCF3}!>YZA(v^CZ7KYsg&9F)B+2
z3T#>eBRVzpGUNBHOOrM&qb7ooN=x9gqU%F*k5{rFl{EYC*T{CYgs|W6rlVi at wp|_3
z^yx%!17)%IFsIpyJOEHHhpBd02yoi)?VMfflV`SNK0}ux`8>^aLb`U5?IvXk3uE3I
zJ-V+<V*Bqw{;E*&(ibMR>C#hcZ_+4ageKYcpRxjRN{5u0zD)hL)$(eOc<XO-Kv+9h
z$y@%@)j at Kfb&^}~yk!qF{vC?bROJbX75d)&*UYClRbnu7aEhYz8Tlw0DKQ-gW*pWj
z<3yO=0XQC5;cCl9m#twJbl49oai0+-&U&da#F4Xn>`XZ_q9o6?5mPKFA2#KKbQL%^
zt4^%XbUk<vR}_bnGanh(X0O~Go-O;WdgY&bksmlx?)|?UV9}M#@{eI;?^1#iU;57Z
zzFt)zad}86G6=>u>eHB={|BG<^y~Uxo0{<hI}Kll!=pXpGMzM)7qqK1O|gdyC=dfV
z#eeKnL(H~;l&9*u3k2=K2y2-jO_U&1YaUpCGMBD09oZ<-=PCHxRlqpHU2*(=(GXAq
zG<xgOH*K|}|Fk@@KMQfaIrr|A)wdR;w-NWQYxJHku8I5k^~dqTzk)f#>}mKqz{rR0
z3Y$Az1lf1rW6nex&E)7bm)LAYwp<|*XA4#Jp*IuAz&=l{r{1MHFL{2!XCxzgSX9`v
zC*kD6<^io7<h*DaKw{uAwdlw2a6eH+Q%f8<J~x*Ci`>>qL1JJqQik4^#qi&tnH}7g
zgJmF#%9lM@%bigq^GkJ)-MUrm{uVz+{sNzNgTl%M8bZ78Q$vhI5b?Ua<NxL`Yl_g?
z>s6;jRS)<Q9YpxIey|wYJ5ra6tRX8013TnGXp^&pB&;)>MBVpNv5_)gV>fQp+J}Z8
zp^03rbgfihjOHYNdzwWCWi)=3I5xb8wGnnVycg1OO^xXTk>{@7GQ4z<Y7B at O`6Vfx
z^?ZV at m~w0D?S^2uCZ7+=7DD&MyA*Yo(*z91aGk%}r%HDp$IV^a6mzHSihKnrN{nG|
zj?{ZE1#W$}&@Qp&R6e0;8UE1)0JzQlM1}=p1NTPfKE%%1x8C_0ljo=&w;f*qM9X#D
zwa;AxvnKLJmP^nbbU^xr?~I&KwRH;q6Yw0mUU(Wg7kRUvAeAvxR1~n2VJz;m;!#bL
z_u9^``%empO4x^0l%=fSBwFIN0 at TGQNakxhvs?s0-9kX8G>V)%m>W`j-~6AxfqU?{
zFp at jFCufY*T7GEXs?uBnta2~mpG`xDG#Vefz0*SWmp;uDnA(b+0 at nB8%lDhhN!u`v
zMEqIFTshuC=PVs=Dzu;tC_yI8m`hRQEW(=qMg$t(ZS}3K4pIS)L7um639HF%>C1mc
zh8oC)C;m06F=v>Owh(tcQC3t|N<)8kjcuZ;`;Z|vz)g$EskraVqulsMr*LA-gpUL7
z{4R at AvVD$csl!#g91J<3e54>B_gffl26k+-;{;6&QiDRE;Wry*XUt0gWHzn08-(RL
zksbqrilqqkq{xLzjOooeL*fu{4WL3fig<E0v8|OmR`h5#TA^_>XUwYfETnJqOCl?K
z^MG`raRpWDJ4d at l%eEOi;fQXZ;&{s!1I$mb4D^~D^eo?!(S1T&&Htc5Lg1Df{;B<j
z*xOox&Y^86x(EW2KzLb1?hM10dt(_O_Rx80%9VkS{(>O^FI_vntqg6S#e(-`gt+XJ
zY$FP+cqs9sV7ao at Gv-5APK4x^1+&@Rfpg}Av at B4j0-<YgX1(dxW;9b4*%DNHQ#r`F
zmHOPuRHvUPGV`0^gmJ6ktJ{X at Mi6m8?e3TApHUz at Y;5t7^7qb^151d4 at iVa`B{{&1
zz>&QvMfbG2wY4>w=j~S3tWC^IOdR8E<HK&E;m%9{JvNJlI5#MFh#uJ^M{j#F(?5ps
z2L`Xu^(~?)gl=Uz6N`(+$2F>jXdSi2`j(mLyB$m6X{wjKZ<1bM%8mOHN=HFcN%_>y
z4=as7B}!qcVhY0F67(wQnT4XbbPA5uwEN=Bprl$>=45gY<q-?BETM-hvTm(~wj5E-
zGoMD+UY~JkF5R~5shF9(<@-oWVN0*zWA at Vx>Uu8*ucZzuWQmo<@|SO|04X58kIPtI
zcw=f}nj<e)9Cb%G6?!acM}i;cwRrte-;NMib}tq8&qMIz1J&nLHSK*yVsXKB+Vt~G
z`sjD(lct$(&!3oujt}$PEI1DKbND1eF0L;iuJ(~2^$JDdT(@^jQ1NDC2bHh96zdsm
zr-un<TU&YNn{zDiou;g27%-@|@<uNw(0R^wn4r<8;?zTAnhFwJuZNj_CDr76blv9K
z*%!6}Zw7inv@?cSD%gD3&e%0txZnemk?=jCj>pH7Hrj#LI^VU`^6L(C8CCn!T6+r8
z^6b>@qvAda=l*j^kW7|aRg^G;BS$*taG~!@yG#NDLk<|ex0|Smf at XcXb0$=i+FQZG
zd6%NdUv^ZPV#8(Ifwgzs_rsyZ_u|7iEdR2|vUyxT`VmiI*Wdr at Hy9MSlDs#9NHh36
z*wbcgYv#$(Sh?^nkSD1|XZP*K3kj5J9xojEm$swP2n-Mx!04q3^ek<q<(Ob*dbN^8
zoS=i)Y(uNxk;oBhnDW|Maipj`5gUnGn$?np#Jcayv?bW4MMIwOHn~rw!65>b|CQ_j
zJ{Rb>VLABwj;kBE7d7?5R6(zxUJ1X<(#=fP|CY)SM|=i>3jUSmUJi4pX%{QA4Kem*
z53u{@EmFU!iep8y4zsGE!n^ttEmd)iFyCTYPrauey`m}BnA$zV^Rh<n9D6pMOSmf`
zh at VTfVsNpQaHh7=QpZTpS$QktGVf!hVs}HRM|d(Zps%#5nH}M;dj=QkPn(v;qS$5!
z#{_x^%ALwcO%Nao%VIQdCk^13t0n%NqPKK;`vPvC-1EscWn{GiwX>D>5=xZy904wh
z-Gr6+4|884?8CPtceO9;UG26j`ES;1HYHZYT>YLs5x6B9{;eifzH~^{PB=k=gAB5%
zN%L+tj*~H8Vrd0qvNn}qz0 at +BF$4%bd)^PKG!v;;l}g^dKu!W)p#gRd9exK8&v0l^
z1_l+-HP-0~6L`qurg at 5xsbg8h*2GROCu1_Q<)bE74bQ|APPORq(1h<PlbT$4%{GmL
z22>82b=jJGNiX5(;&zkD0=^A}8xy|Ryl;9h at -vMl*3!sha)VftzTes<R-NhA%<n&@
zZ$K41*at!xVx}MKx-&-6NH7drT)OC`m{#ua7p}?3$DfS*s|pj;kSPfXmSbw({T;n(
zNo+i)cQmR@?vJMKS%}U(K6Vt<0{Q~G(;W at elr2!Qc5c+Pkalk!EW-=j6)h+Xt#uc`
zLAD#I7&P<lOMAb%WZ0{C-6c9w1CpJBs<0=RDeGphA8)%i%Be)%;cDE#a^wEfeMM at T
z4zJSr`1o`+oZQS7zvah&$fyvqhV#Y~YMTH@=8)VZIfM6lFGLA$8u(v)O;cS6Q2!uX
zX13ybUxi}c<|<I0ZJDVu84AfvO7yh+5MJuXzg)XYZEZR%JWA^5STMb-s1aAp_cxc7
zAOBZoKHpO?$BWo}B`OdOrZeViShixEIr3f1bNe4lNfNH21&L|3WS!U%+`|Q2DN+&9
zfQ1ZqU~}<nciu=A6*>WlK~>C%J<hLob4eqVP<!5|udL)A?G0nAg{S+O>{$WAyqZCV
zq;~NvW2)g#Gsnlix<_rQ`7%DjviV#fkP4*C^%*MZM4VN7WOttYH6m04W5lIv at 2hs3
zI2FMojEwI8X#tcpc>kydKV;8}NaZf2&vGBC;A?yOrsn^n-(WatQd8)SezlwN8LF(v
z^NH>6U}fDfW|NbR at bu=jnX#nkU{HP{M}$G~PIVR4e?e#$iXV>KaQ9Hlxo3+&nM`S>
zhW=V)Deb6gR#YO(?FM{Snx!=gE^oPW;Bi$T#(oC$IZI<cTJP(P{beTMjNY<6UAhoQ
z-XKkprcLUPLf0MLgf~uD(Ks>?Xa`y?OYZON%Hnv>@FLwzt$taJJ}4VR{{kwtXAU3T
zzc9s+IF#8!y3v=`n~^DL9HwfUyN8&OVNVTXi#3||nQP4KRnB at LvZ;mJT_2eH-)l;@
zUF1$EQ-~re77lxM!?<xNZ_u!=k!9}qOnk`M9!`fdS+v+iknI#TK at Qmnchb_(+IB=~
z%!*?jdq>utEj0<>WVI&@X40G!4RjXXn27ub20kp<Iyk&5RL$gyq|4=ucGu>j05pn1
zSy%r(l)DjL`-g|SRXq$70RH&PJ at _ki(Za-P!E~#K)bl|qs3^BPF)*JSjS(BP<SA~P
za3|!EJ>~>~Y0;avw_q5ZuYox%$<)SIxho7Rrtx=Xoa=wz-{0$F4%$6d7{h2uX*cc{
zNx!zF8+s}c@#~JLU`@<?*<)zL{3v|Qf$y-Ch7*ygiYU|RT%KRE#QU1b1c at 08zd{wK
z_9-V(4F0{0)k)#fr_`tf!xSwvXeEdV2CF`HA1e0DtHLX$U)t#DYOX8CS|*~C*&`0_
zpbR2X>9#f*nauW4C?(0(fRyn;a##-8;mtA4tZ0(YZ&!u>4>vU2NR<_Wa%&}<MvU)Z
zb@#f|cEyGEoKB-*f|~K&vxeHAKizK5_oFNqfxCn6O^A&NY at yE-_i|Qg7 at vFCyBoC=
zcDucF`cv<M06PK^<|p%NTDFd;efVwRgkEk-rS<b-aqdAx;G`D05<T5Q<w$sYECxD=
zfz5?56g7z&f_scv5N6mN0;YsxWL<J|?$z}6FF<|STeOb at 3NoK_rP7e2g+gWWK@d#H
z)Ql%L=VKH3el4N#UgcKjb7Z(313r}9E>U^;-5H-ooHzqu1!X%#Z*;L at 7vmFid6&@)
zOgu=K$Iw-v`YbdoBz%D!$o$%(Cz{Hq%5#r!aTXc6^C9D%R7~q4!0Kg~P2E?@u+yme
z3&YKC2kWspoc8x3FCK^BH=S>1%m+D at QCxgks+ia&mpZ(1-i-K0XS_7{##`maMWV%B
zw)#2wbTWwP at CDao+%vA?oDouw8P0!*Q52`MgjOoBsT>k;-^6R&R5bt7p~CO7Agm3D
zxPXQfLKGNH#cQYwt)n(Q-sl}efe}9pc}0ZHft2?ub;xnur`~X9Zx(I)n{y4ngu7}O
znG;Jy!1*qrFV9hJhUF7u%JMYhAmdOXQ^_mZ41w?i2tJqCtfGt7+>^nAUzHAcEE~gG
z2C6A~VTpR@%^dG+eFpTgFV6T#UL56<rMjo6J_n at Hx(~d?ULPM>zo;(N=^9Z!15X9U
za&_9pFa1G5F9?tQ_D2DYN)0S6a&#Vb>{s+?Q;bhdSX4y%9C5 at AjIngpBhqw*gIGiO
zrm3@|B)nP6&JvDC>JL8G2>T!I#jQ*Er|hk*`mJ46X=Jvl9%Bms`IqVr0Rhcwp<?^2
zGrQO!f<%zkAz_8$%`;<zEF5fxneW{rYiIF(PNGxB)5UNdQSjz9F#EFJmjI~pXo<oA
z(&@w7!&~9^Hti3*(}!!uts`4rx>+kRE14pP7d?#yATcrj+q&yJf73vaUd>ll50pk4
zVmL#+ at y`@cs at cJ4&h}#3DM$G}mP-xZUl|=<@a=C&g(8N8?!x at pF?A8}n>&B?x?NdY
zOdWa6JD*~cE at PJ2#CRb_tOH!TqV=wCj+m?neS%1W9F>3*bR|djKWYR*A)9{`K`Q#>
zsqWD`j7OL<m<m(w)Q(d&LjQfz2C95#y;rLURW-%Y5oSB7bc`QcA<fQ!1>fAwTYVSm
zJLUU^VneKKJ7%SzN0iP!2hFN8>7SnsxBR?8dD>UOyB{r`+R4{&(;>nFC1P*6fm-Iz
z#|vIW0Z_QO$QCY)9H#M4={vO)<@DI4Ze_U1-5L#-fo)x-w?B`@Db<Knylg!Ls00(f
zx?Qn)VLvJ8$)5W9S;vw~s4IXl^ymT#4rTfadP44YGFF<Y4j5}WGH86J1<6$_&TsC1
zHRd)M2oHQcdE6{ulac=2dhHFNx6j8t?}4ZCz>|LZrtENkDc`jEMXxL9th^bQ-g at O%
z!3%{Xl2-&fUeIRckx6684NOg(3^_!>UTnbj6Zv5$R5FxKx$5n!o=j;sQF=<!F938B
zM4Y%Jxhcand1IQjmF-yn3i)tLh(wpFwZxJ7!EmYfFMO*bs;3|0lN1{r{(VeXKV3Zy
z;HY3p+5nqXaQ|l1P!V<`BiMPh9-+=eSHfR5cX)w+cRg!Y0O&P^(jKSBT=@(0MHhHV
z4sD##9$mX_S)DXAGjO;mqAcb0GyE?aevsz-GDE at 8{@R+F8u!b~*rSFOrVidAe<|9x
zE+fSW?{YTzM;3{(JQ)H4q6sDIceGSZMI29#?oi^tGp^4~huH&_k*6f)uG8*)cw#Me
z?>u{t_zGzgv(bS1UG6pKsx)8k(^BFiAR#po?>~YD&EJp0pz#X%&ykFpoKIan9nKdk
z?a!Mfq<Gye(K7P1S3>3XQa`i1Oy;yW=8ZILnqc+sL>-JhYFTP0u4sPH>{<Q-cL~Q)
zEe*_Km9ueutl~(~VvdfmjJwNVFqcZ-niZboQqp>MLeFQm>$h>Y<K<zIj*zgg!q2&L
zSS5-f^U1mtYo3~Y7ZS2aPc=tAhY7cOdfwX#u<jv4XcfkgP(jYa*Cpo1E)um_Qot{;
zL{yw+How31=iV9qTz^67gu|~7SDA_FK{!12sZf!^&(z{Fu!OOp^(9kgJLBt+TUgWS
zmcC!0fRmJZVfzJFN9J&+r^EH`LN>24BD80D)_vd<Sf#kNHU~V|U1`;_G$5;~U}_If
z at l=qKDc+%h*|V5{aEVLsj8*bK+3^j#clPEnAZTrJ&5yzQtuCT)`%~bwJ}>T>u0v8M
z&C+X}_}*8GBxH}B_xb$siB}3)93fcveZT2&zxm*`i9!JGQB&cIPaEv^iil(m=hHud
z5O=1<GMNi%kEvb>D7~nD$u~(a9;@2dKtt8+>YyR at N~o^+_{!xs%f;i12Tc&NOMl%5
zZj%8rA*}PYB2!S}B6{}9J*HVCHk%E<`j#8mB!hnOlt1Ui<%(G$ypE6>zvY(On8h`t
z2>0Nkiu7C6dE?C;3hzS3+`NNX4(4=Qx_LiGV;V#oA<Ow*A^dT!^Mai+nyiwPS~Iiz
z!bC9IImn;)@v~OCjZuR#o%R~b=bywQX(laP1Rq+bNprOrp5G5$37dS2`<h_GxFVz&
zxQWa(`f``0wf7aRklT&PNau1*3{}<C3neXzRLcKFIO!>Vp2)r-K1Xxhaw>jwlZ8*`
z$q*lzb0Y1i&K8t2-LUj!M|x57hhh`X1#C{Zyftrf#*3e0H49N__51*fJnwmBqgXL$
zapFGB8nPH8X&{Pd`M~v*KQ*p4*w9J%WPqdjf-WK?fy`mvA~udxvo)qCIxr4{Gs`JY
zX{PT*8{#=(|G0O|i%|>dPc>M^2+4GN96xsSsc>!{!L8TOP0L<jmb&(17}YL#;unO3
zD!kETW~;uP)IJI$YJ~idWopuqkoskvaA$4EEX~^EId|-j)Un at IQ%1C~ubQ4qNEuJK
z!UV?msy2*G59uKPIzJeG*Mj8sKC&gd9dy+dFDySix^-5r|7b^SA7+PN_aHh=B+G}6
zuTk6X6=;NgeGECR{p#<ZWm-E>y2~HR<QGE at Zf$hJ10hP1*+P#F$#&I^(})T|WY9AL
zVG^H8_kmQd?I8CYmDg)&&T0U3+5PEBq}iPo&7TQ-!JV4JSibD7)Ig8S at 8lhnBsCbX
zI%$lh?YS4Wqt;KZsR~45ia0c%O(BLOMN}TM(^<mWQs<5_6hG3{2ldTcz=JWBhVx%!
zOBZlI>)4e3H%@K25^DJ-iBtMjn{p2rZ=i at oMk@E4cyDpU$Uk^Nt%R4bj`G!<wK-&{
zRXzm&RVV<5lbIZyG7q~xKPF~U(%Gc0u8+ at 7DE>(62g~6E|GheS at F@lFD5!NPn9#m~
zB-ldML}Rz5Nj`xEvaOwA^q~5qjM4VDTc6i@|4QYOa%QI{V$hPndQ;h4+uAQy^er~W
z)SqGcExvGDso%sU+7FDaP|?$>C>&fKGxjWVRB3#nQm}u;yC5H#Ax77ACd;WaLWarX
z at 4>*k4nmVMP^5_C7<=T+T$5b*5hmJq6kWZmlnqBB$s>CO%vGe at Y82%svwMX4v)?wv
z5z}MZ!l~m2hTZy_2S0<oR`uR?Nj{cjQCK at Z^=SO_OMRK9y#pmzu*a*S)-UuH at 0r+~
zdua1L2chzfjE};NA|eBUnG{g{S3G at Xb{MTYea?qIXmQX8P^drgQUB7rMZ6I*dpm3^
z6cjV<D?IS_${c>@^^uQJI-Hcv0Q_>@uh+?vOyS^5qGYXkl8_)4iok at wsNE@Nq8q&_
z<A{SSl(dch1;PrwzryJPp~}uq1uB&*0W>WU7w44a<Qn{UZ=$c)4loRX<C1xZcBBcx
zzCa0n0rMrsH at +|>CLadetS`{NkB$sY?jkPCs%3#cR^AA~^Y9!>Ss^mBo+z=JD3*O6
z3XNav(tkNum1k10Cfn3 at hTx7v2<^`LN<rm0L$d0Sl34S<EJzlGL+g+}<5HTU;1S82
zJ^g>biB;Fu+u;q-!%C=fh>T<|4c5<pq1$EPsD1^rmQPa1P-GaN1O!eg+Ly?hXTf0o
zTrdz<p`J-G<@B3L6(jmF>Z=)L5T_^{Tf8<;hCjD+NX0xgeVUXA^YJhlOGp!f@~Jn5
zfcI{fLkE2MO&1xgr+TeIDrR}ccI*NEDN@`#n6Nc>nw149n00FxOgYR0qK1585RvCb
z at tgh-jhLn0W@n2XnoJcanE0!JeL<6nQ^9inbopzi*gBJPpas_l_;9r%s3$fvkj8J-
zbG`_yCR>>zoymyA5d%G=)eU~5G2N7cD=c<V`{Gt_f>B&2vcQ?h+F<W<yz1YYwpFbW
zOnZ*@Cuod32Qf|Ax#u@{j*@>3C&b|Y7N~sKQ<J;ylB4$H4^<#fWI!zKkvZUT1;(~O
zlAbKaAoceZcVkvR3b^I?2Ef54Ul=E3=rpqGLUHq~a?wuA#mvS?-xpcWGguyT2Y(`<
zCC!UVOSu#HOMfb<*!YhoL2ezZeYQ6mrSe#EF=h4xoI at jeYNR{V)9{^T9kN|xT=&F|
zHAm0~Nn<^A&3cey-udmqm0%_(u9hv`9X@?Rzb3G-BBZh)!>H7gsmeIrobDOl@*x!J
z*}`vCH)RCc{cIv-Jqk>8O;G}DIJIkzEOqhqJ&i`T=*Lb_-im<QPR&T$mwjO;98jCU
zLfl~*a3I4pqMu`V at CCKCVWy|YH at 7PT?_xSy)blO(xTSiIphU_y@;u^=q!D4%pSGY*
zVM|G<9`2;x&AQp?k38Vl_2R+w#2g@!=S_JQu{*Jg{8x_Amz6GDgjmE7-edtDN0%GG
z=qFN~pr2e+!8#Yb5~NZX72>$}S?NoM;4g7%&@rQECI1F9OKUuii?i*Oa_Ng4go;v-
z2xTS~?cLxw--*gKR&G%=Upg5ydjuaRmR!ai<jx+MBVnx|$c&N|$uWn&w8R5-UEDfJ
z-U>}gj}~d-F9|Ww+wQc|X^pqDS;n>15~z8)(7n;X_#F2VR`-;)X!AAE%VLz>GkIz0
z<+pPtB`KAQ!A-{F7|pO$iErk8yn_V6v6QmL-1xz`(llSputrCuW7CL8axJa3XvR(?
z&%fGms!hd=&G_s!6X7~m`v`-JOYay>&M&<xNMc!I*Y6qCHYM43CN7>6VB0PawN1Ie
zq5IMVGM44-)j|hXUwM|9Z0798|9GaJ+)@*T+5T%R%`{`;C05hWp0!Um33c;!m24hv
zYAtqrQ#s%V+e%%!(9gl*1S{-eXNRjVQW043C-menfy(kk_>Ve5UHqlE1gq8{oIxm+
zuQuc(q!%7v{aBJhwZJh;$Yr7_`DY${qn+K}1f$Nw2O-e$#aQ0GiUhCrJsHT?*~UC>
z%_JdGAZS`}_HlaxeZCQRcoG1a2&Fe{r-$7|EqG%O#EW|HnZSa~y!3+UHI);NeY8}}
zWyGU&<)`6VqdH_Bmw!CFuTCSO)IbO4z=X1uz=Kc0Zb7EsF?t at kN;KufKbkuD96sg$
zybf8{eaXD*5BwXqSEVERE^tp4n47?Of(<iP1ooBWQQ!MK4^<io7)Te|k*Ha)O9OhL
zdn{|2HkIC%#VwX>`1>CR8uhGQG?U%CWN)<}nPo#vj=_kN95Isf#oFjY`4>}++ at 6Rr
zFcrnbC~2GJj=1I|xAAE~-l-U%z$E8 at o(nwNcNK^*M-PYUaX&U-D31&#$r}x_AdfsV
ziaa6+>!|5K70;1dGKS5s_5Do%5yRq!9BO0)I83_()AqM35!eahH at SbI(T|+7nsD^?
zQiM1cSq#4`gTc%exk{L at GJlxDtvF}#- at 7c^Iam3L=MVu&N17_3nCw5nWNjym>prYJ
z33A=ofAr`&ORKE${6CKT%=CKhK3j$QO(>lDGQyBQ*dZ*u$>9Kls`>_vYy1?OlTImp
zODHoa;zu!7-F9c3^Bd{c5P^Lq4Wp;*pt5`ud5F!eq#mZBCf1-KF{hn5>7!tC=XKmq
z0}ZYdUL3i)TUiKA1<a~FGY6CQwkKDoipS=RQ7Fpb<Gh1$MZS#$8tK+BkQH`H{I{-0
zn&CM4<H`0R7xfo(xwnJxWVhFa`@FfE)!n at K$J at H`J3Yr&_D=G8Do;o5s?F>c(F7ij
zgvk`QWFAN2xtY8jpgo%SI+k>cYqO;kAYL+(YE%hAPv`^G7TT2wyA-RxH)mpv$C7zC
z65+;!Q at 8jp?ld>PN8%}mgPg*u#+w~+b_=NqF48trXFswX<bd1f@^RWh^kF_LMA&J)
zbEZ)PcfcjKeLB6$<lqBW-sWy<!G-}8Q$Pl%?Rb|$-w8g+C-p8Suk3#(+cfbm+0vQA
z8t%7)MRLyPO-IFt2e`~XGqDpxgQ6ehYDU`JY*FW%T7(!%L8P^|j?wYq2{>;wo{oPR
zgwRh#@m(wQW2K9Fp)L2HB}r&7#I3;^Fr{K}TBUMJsU;i7o?*rLzvg-*M+3YytZ0n&
zT5Dnj9k*tUX(?^&?#Q<@LQ6(DY54(zvZksiLu$)s9v40OBv(<qQrENRF$AWqU|M~=
zJ`#@}6jHGi9mf>dP=?TOzEC7Hb45vq{$q>rbI%?2VD9R%O$@n+G(2$}LWb0^4XT}-
z-Wv0E<|&cqsuLtybSA2dP}^J7rq7a4`cBk;wIB8-n_`QVU$UtQhZl)!O|kOIbbU3t
zXfVl?o04%RgkJt?{wpNw#??v}0aLV9xHc()R87SPeNL3z!05Mv*kjs9`gkAxsb=`i
zrExD29PpSCw!3?FP0PXgJ!M(U#zvSTki)y(57o{eQ=i$DHw`a{->1=Ne}$Rlnl>=S
zpIJswH%7y5`B~)!imkW6UrQR?_O(Ni)(7%>yJ?BogKyW7{4}@@`9l?9L&&RGsF<uc
zH$}d-a+RPPbskz%kd5PU>BpIxXv<bbm7fOYNJ4dXf{ekIbu1UEbDV2LbG5($NB~BI
zz3we)1Bn74pE*Zk&pANKa7(hcV9&%-{E-)6-A<6<QoZ|tqkIXaX1nn5m!9rm9-!6x
zH|b562I9- at t=>ERP$)IQ#$40$14jFlGa-f)Aw;Mk??-okD at qK~NK32{y7>OrIsloB
zZ95*RJS3+7ItB&%gp&{?8gXoxySnPJla6SA**srLXu_IHK#g_}QYUa1%#Ty?yW{R<
zU&?~jmCi(VXLdEYOVU4aPmBpES+5f)Gpv}N-VA9A1O?yuV$DQyc}6RqouX%~#)7I+
zGVv&BiZ9GONcnS_uw)~PG#O$!KlFbuz|){C;lJ)aXepJbdQ-i$w5Dusq*JHDw>NUS
zvbDtWq;F`T`Yk^T56VWB?FV<LO20HroTIWmE!?iZyNIo4);vy7omOh9>$viS!DBt^
zRN0L(T<ucLeX4scoy$gVzC)655uKMGn<bsI3bVzUcD2)B<4F(5FJU3JfM{|ehCfq=
zXcU#m)o?@n^ggV)DcI1-Flo~ygb%uHD$`*|aB^q(lo;~M0=P<{2FxjbiPG-><_mvQ
zABOf1qIm`LLM558E}Cbk#_#7 at uF$l*sS9W`YPMvzeG0;U%%7d>JG}nz!sG|0j8{Mw
z4yW}{u<evkwSzq5srZBDF$cvvMa;L`PVn&=md-ksk*Qn5IjfTk!f0StoQYjF{VxGT
z4>U^~cqlWg&n3y5GQf<NE!5yjK>g1-FcRejuOXxMu_N=afRFu4&vnEBeFJ`2C%G1J
zyxKbrtLr!mC5TR1AsTKRQO$}I->RE_=AmYmjUen|{|wa)Q+^Rhg9YFH3@!3LOV
zAhPtnKm{U{dIH03ZyBn7EM=c=OLXQur;+T$v#jg59G~SKd6ItvmXV3<CHR2dO#K5$
zhpwKfDpDnX+5rxo3e(}u$Zs4G7NSA+SiB at vOq@?4)$1))k0zJQ1))Cg)#R8ZEMc>X
z1IHL`4dk}>6T3sfGF)%e3Y)n*EJoMltU9(Z7wFPC+akFw4k at HssicYx2MyI{JLP^x
zuIG`n5wmOfW;FaDV7dt=S&siX^fzV8Q2=EHD7$9_|DE7=YUuD&6j*VHmq(KDL$q}=
zl;lxe#gVC1V&oLC85Wj&6-5ja${06^?SG_>qoV3_8A4dfWeA%r!+<INDhz5c-|RHA
zWekeVJT{n1mOeMHlqAw+SirX1Ol8EhV!AOR999mg at 4({DOE|VANRCA~U=GRNudkng
zs3q7a!mPdEm(N&9nj9U#q6x)*(KJZDVw=uyW=NhX`&ew*FM1mK);)Ssu}?|}IFe at D
zwG=Fjluybux1;=!MLHXp)8h|VKCY=W#UskZxn8&8!y+T;I^Sz_66CfxHp(^sL`pp4
zz|UNhPVaDwP3+jClkr*MCf>!WPKTgB6q~>rf&N9f&xEA&fgUkj=2@^K>=f4!SAeFD
zIVaDay90z}L}Q00%S0(d7CAq at Sumv=y8cw^#gyMyhYZ3DMgy{3xwQ=Orw5GMSwx~C
zn!5PP;ao`K+A+=wf2oBPCq$W2HCI1yGIc-m$YZ9|w&e85l-oziFdpO(is5<WU1EXj
z^<Kr>#_qmw3Y*>sjyWW~`_tK40BVVTejRQdE)cgPztGNLuxF4&BLgS;lJBLXP5|V|
zx_yoX8OvIrh8!FexKUgR^6yClcLbY{gQ^{&nlL+?zTRi;7{rf=)F=<C6m?sdUSUV3
zXV;KN`X&~$i&FGGH4x at t<_QaMi93z$XLu>jhs)KAx$gJ0P9VP*6WBzDgFSH;DVX<$
zyYc(8woMtk5?n&YrLZ_IDp&Rzrigl6*VLBv0?X{rdzS-0Sc|o^rc71dz!bnc$`E?7
zQN5Hl{*m%A!};IB2=?GHtf^y*eL~_8?$73w{O!+flJoGCVJ=0#5}f;Qje^}K_?n*=
zXC)9CXue(wa~mf)Jxuh1J2}D}n{{sK%e|DIpa-R$cur&AGCe{#4v>GhnvWlTEsvVz
z!q!av!nIp3=hlfeOY^k%x><{9wdLE1+0^jNF(aSZ3jekXR$eU<`!D%FN8!wnl@>(5
z7`joYo$LuKbtY^6FBCsg68lTFIylIpL_7Zejl6IOb1GYYX5TN9If`+kh5ED*v|Yp2
zvB#$+^6z;AYC<tu`+1%x^aU;}Vq1%BJjplN<gjoXR-eEcuvXvzw^Z)Lt>Lgr_zqB@
zaVXFnEYJ4ry|4`jDs<yhJ08=8cJyc4G(ARt)q`1}#<B<L8vJVA9vu@?T99cVL_g{T
z)u$MW3?2_`rhI{N=>GcbKlOh0UQPSRzm8?sKy3I6l-iJsEDk_fIGp{nT8Ub^tI at uN
zBS@&PD*J(goJsg|Qjfe|S%5iUr(tC|FxiaKP5Z|OS>3Bj(wbbDC_OX3!*{|-{}RBk
z;PgAKB?1n66&7MGxIW7*aKlnL%s%OG>o+d at tO;no3w0%F-J8bga at o#462Oyg%cNgg
zU*>0)TTAZez@^n3W4-#3#TX5eVIt-ZrlOpPpGGygkL#6&b`@x0DM^|rZuBv{q_-V^
z)cEJ)F{&Wmk_Ek|r0QP=R+7ZBzb#7BNRA#FN+c2_h6s1Q?I)vnt2^EKnn`R+`TLg4
zn`Td8^Sp+*q(7Hl#uuD)Z#xEs_Bo)FT?&{Rmq`>!r;Zz at FfLqT9|mb<q>G>E#zzvE
zs+W?lz!Rh7G*y%VrTRQO-+-*x2jNZbfz>0uOK{fP at 8&dh-T|?Yw&7_@@5^oF`j#L)
zvho)UAM<eIr#d^LG`95u+PN7li%{Cf5XJd;di#^ZS;I*|P>B at eElMK3?!LM=$)y)U
z20;|ZC%f@;=I>mvcOe7AZocHCF$xx|CPFt(6OVUrVO9~i;~L*GWVqqGnyXnQwuzhU
zZgKx!#e5CI0J$KRn<Zxh!E*RTTCgr=_>2Bey44PNbUZF2l?WY_(wKT35=E`i@@!#r
z(dA<k%ukpP|1dP1TvMSj34l4CtI=4$XR(B2n0y+kJ@~AgUoFJxkx!WmD5$}6E9yNh
z{-*^159s|@_|u0#PsINrME|z$K}WF5F`{dxo54E_{}BZyI6c8A1*pB`PilHqj2OH8
z*d3?R8(#p52VMa%x+geVr}nGDLL4FB9U<`YwfH~AI+pC81i*1QOT&_#*$Lu=#oEgO
zaZPZ4*>to}c7`&Ywx`3BCl(D9&d_>eCfFV^g`djl&J~_Ik at e(rBtd+ZhWjJHE|3r#
zDa1z4I~=K2KrQ1gzqQ4G-5&hGpJ&%bx3 at p|<GV@>UsRE_&Cfz!NY9dQH#t|Y>K`qV
zzP}{9 at 2sqVJ&paD)oFUZU9``H^>Xb*wx92%$Rc}HesKuymRDP|YX{gJ&3thOTy?@4
zm$J=Yn|Ey$B#Pvg=jBu#65PCr4OKWAMDm<Xp{@};)QxKbWGLqt;k-Vv;qtjie-htH
zqA$`+bo2!$bhc08iTa;@r2GIb8M?>BYD-LEOEuFfQ_kpI0`qj8hqdF<-jTENJ&EA5
z(26|v<Tp!>vcV;4S}euu`6t1t<6B;x#?hKyY(UPy_~<yJ`YXdORWY-oH>EB4t$zWB
zXZBbNyEIQkIbww;iQCH(ag#^pEm3$Yz}evMuUR&O43=p~e7V`KOxGo(Gli949;foR
z+T3Rfq<+$%9GXV+4BNMf2rzcm7mj<fhIJKL=M1WZ2a;N!tYqq$NMP*J4mMw;!2>9!
z@{%YR!LQ$5IZdfMOK57O3{!H75PkG=An^cDUVmhs9ym8SO4$1OXQ<sNwIzT_u)H~M
zSAE#?1#dRh{)Gr$50=M^#g*uKEoyKFj at -|$5(V$?Rdjj_0fjpcu)eNFD66?vfa|ad
zk<9P&+A at IR`{VeMzSEH3_EW$Z at _Bui{<lt0BFAR^TX_`1V3laZh~}V|Ajyd+{hC4B
z^&L|P5Q<xH2e!G`L9-=%kGwh}r!XX52L38hIGNgCWL at r<6}eD&MAzzpBv_Tq+5EJd
zlPvYmufDka9R)Z-L!~`nPx*=s*b*eYrzp#^hx|;|jhP)MD(qs$qXbwZiJtifcvuWA
z(vk}ub*gE9N=Wy8<E-6W1-knYbf$YLsndG=Ys1vWd}vc$EBNdCp<h;ozfW_HbVsSx
z at qGnpfyEYOePrW-H_|`HT>lVqsw|{xrG9f|&HP)fIwV|On!;4+KBlYjG2UNuimYpx
zp14ww70aEb+2Y^K$ls2 at 9QI=U#8N??u59bquSt47zY>uw78>M(yiEwn!IH&p*jznz
zw6I9%YA7vR0mr{SI6mrPz^Hdnz&zG1;CL-Oe&Q)squRFVvAVJ$vH5uW<Il#awwSiS
zIF^7+lq at BgX4bfE=q%wdDT^VuC;L8M629VdX6-nd%)D<i?tC|}o!9Uxa6-2v#~>dd
zBW<J|amvzo6L>oC*J-vzDUFKLNBoD;L!yn8*XN0LbG3oC-u9S5)l?lNy!2_3Cse-h
zs`CU_Q7Ms|#C%N~gOLWJY9<Aoymb-#lKq@%VDl-uJNi*{V3)Z{2_Ysawp8L+KAw&{
z$(H9F44oD0x~oNG+04N5vsA8+plX^(h6JFA$VcRWZyzE(j)*oB<umBFV@~?z+X~ch
zjl<GFsv;mFy9M{Iw^3i at _l(n6;85xM^aXy}>Tbt4U&{U6wErAg{{<?J-3_YU_AMk>
zj*VL})+G2rMgWlB;iOg1sr7K>SE31mSr1I47i8R4qb=}9#kQ`JBtD3zbdrf{rmApu
zfVwIDVXH*dZVKuMlNlF913CTmJI644TyUgaO&hoNR2nc-{Og|7qf(6HiPRoJGTtLT
zhzTt=%Uq<1mkU%w<!Z8;J%tlL{h6!sfY at 8<qcx7VFcfD<y0K}&$+oVOCY+e?<YAAE
zPFEm4p72`0HUW=@v!mx&mz&Zy#3k?T5ok{aOfkq2;A~Elf07DEY8GM*r19qGcC>(%
z{Z1dPeeIrOcdkG^8R*WOeUc7Kj6=I}G at 0rew0HEb?S7WbeWKNA&Y~QxsKi&@D31S9
zQ=)%lY4>bOAYk!QoLjFk5!AVTi8$@r18jji1edWUig{(XUPU}ZFIPo|r?}abm-SwY
zMAxGk@>-5es>lA_StshnDi!uKieS=cZJS!OMq&;MWs-W2+fmcx{TVQ(P(Dp?Z+prb
zB+6pVO^I-iR(G9y1o!jm9qU`mT0`@5BpG!m`T=VRpByQ<{n|^k_mROPv4vD0vtr_M
zs=WsGtqXH<M`9x`_7ZV7>+<*Wmm{|VYu=zRoYW<sU}=1AGw*`1Bf00z4tO3~k+y at p
zmavXBWgH|8(5oBYO8sIc%?h?M1edb(Z+`i~X=pG=jn0`~`|CGQB+BN5+g3CObU7{$
z36uajXl?>P&S-bnYR&aeD1&H1&KYqL&W7bG at Ij8gq3{6P0pnSy>XHKzN<H|p1C%!i
zK%jQFjeDa~WWHZsbHUxWiC%6VJz)z0J_St}+lvE6owcj<)DT at UC!EaXD_>)*fIe2n
zMb>2AT>g|Vq-uuYtF##ib8Ki(=jp6DmlIC0ck9c89Epv40MqlmRb7aS`aLV?!m~8;
zIWGvx@>4kg(v^@NL)`v at O5(2okp%IL)_*2;9+o)O=bz%-TYrdrVX3fulorOF|EL*5
z at ALNIY2Xplo3$+8y~ts{{R955WO7JFM0*%zvvKPO8WNVXkq}qGa4mc at Cl<}bA-D?<
zB=yNp%f%L|MOO$9hh`-AC=(Oox#yfo{C(#S0ib6*qL;YCA(or6$1xD4M8Q$;`-->p
z_*?Fq$}aEhYN4UtN=sSIFRYp+<i#f0xQGmAK&~`v62I2X0h%<?g~GQ2pY>Um7|(*z
z4pqf0;kc=$`7X+|sbYIrxisXds)b!?s$%jbWuw-o)QwNm8O3~X_``=J`pVbD9W}Ni
z!;HR9a&eSkUC5vPGr`IZV`DKehSuU2|ApnK;BnYv$*>*9Ma6;BQT=hXU&=-L9?4*H
zrzV*$_o{CS$VYG~?4c7ufAs`adg7x6f~<t?SS at +8+jB-PzQ(gt#4324T)RqeEJbCw
zPG}ZPY|o959>J;HA$N;t<JWrVZq+qC7fXZon%KHPqFS(U!9HtXVHE2Vu8qrm!Ahb}
z?vh=s88!W at K6v+e6DkXFL?2O6o3p~SQF!wKQVZ>VJ<8c5+H>M?GoTA6sdC1CU=o}1
z at 2}l@>ee<upyNr9c(B^G4+iEs$}8<Kgg|xIhZKBPiLzG+TuD6mo(|c$0&pBY;22gF
zyES{0wk+;r=2fbT^B)6Vnj}f)L6Qo+*%$=2{)wkoH%qTZ=T-_LmEZ=B!<vk&8-)_j
zyFr}Kj=UUky2?L81wKoM38wRsX_l(%W}-~LW<IFq<9?JaJfx=B>YQlIeN4Wq)Zb7Q
z at 4Y<YwmxDbanB7AcMa~nS;N>EYA5H%FKl8|3^H#RD1QAwko#E6c$pQB{F$he*Pp;5
zt$ND8(aRABC=;V<Qq5j`Kn+thDyJO#X!53=J at J2Euvc6sn@{TfPt^l#-fo9KQ9PSd
z7J2e(5Eb=#%UYbFf}$AQ-(e=8#Q8!*3`5Yi^J$CNLDs9_2k!CnL!T&i$39q~*3Gvc
z-!HI<14e|lc^J$AxuficUmq<FgxA&I%2(s_SLJ8(VPcw_8EDr><4mhxm1fsU-FmSN
zEW5_-*kO1w;p`T8k}SVyK(#|GDnWNzzB%4Y;CL1JAT8=v=zj4u-n7>EX?5SLU6-d>
z+Y9`U2WW9)8tr+vNnCxK{dxMVAEm~3{D{+mtv1D1zctzPGACOf#Itx4N2-5vP+x#c
zQcc+_6J<eqS$S?57Qz^23#OAewOcuiE9r&Q{^*<aOu}G3z at JKHyHxV>g2gN1<aa3a
zB&u-FZt;MpEo};FA8N-4n3Gqcu>yaL5rk47ZHN~5oq7ui12{Sur}VkyR{&beL;h>0
z%=H01w+jt7e#|gbm+Dd0pXI*tuSd_&3;&&lr8p9J9<kpBBpeFc+WR_*fa?WV4#J?-
zM4y2&&<wRb*pQWY$gbN;b--6Mm<{+ at y7;|Xkinz0{z%XO&{W~shu!{&Jdy^Yxc02U
zW%PLnH#WQjpdgl_v<?U|l2)R%tW<2))$2N3T47-DyNS3rB7w|Z!Pa1(iuF#f3B;B$
zt-`xBmZ;*85#%4@;o<5?S<e;qFFg;#t}M;J#Ooy5xjzm4`tZ at vXVewz)+Zy at uDiF0
zGO5(_ at 1?Pp23Nx1a3t}~jwo$g12WNR9j>JK>vsl%RD^|Q)+iG at YzS2}|8CAOoS*O6
zic=0oo_XdF#r9u*gUtsK68?%LE$RneVjoDT;e}wgGR}<`h-t_lhlc00y?0ANK3LuK
zF;1}VIFB9U0!s&x1#C+~wMB}}eLMF0k%FH7V<Ff_>iiL7;yljL$|_!NXoO}Bpyp0;
z&fLDOisR%ImOQe;(cS9sXB79;ZC&ZeaKkS(J<%UH7|zp;M+{$=C-SpfcE#yKv0G9y
zG2|VrrDhRK#PaUbs!UPUdxb2?UNalCXXu%OJTuaLtf0CJmfZZo%2{5rH`VvUryKld
z2v-0T!^$lP)C7Z~h4x9e8TQ_7O4+e2e>OW`=!G!M)hp$H1E$K|`4D3+ at N?XT>hrKO
zJuUuq$sCtA#a8on?%G?61>|6s);y!}dXw7VEeg=ni{4`~87IPdv{wCFU`HND2WWPU
z#R(^bK_UMe%j#VRyeiMR+CZ#FEI(;ruNZB;CzY_u2Ji=ruH*;3{wzOc7kaosN4{dZ
z(*3WBXD)t$7EdMLYM88E0M~qzrdxLjD=GT|^^A5p1PIS5*omDup2wx#jd)$h?7Zs^
zb!1_~JW!X)JgF{r-t#(tabR*jc40!2CR{?`aVgdmhO&0yixw0Lueq%SBI?KHpamf2
z(Wi_VciG6ROnH*@xwlzG@`vVbX}gJ_WMkg=Qz)$hmj(=zy8SCoR+cbDVygPr6*y9?
z#AGxTp(%ZmSX|O&^}a+kQSL3La2t|~PBh;5*JFz*GDnv2;(>ys$gGpV7fGWy_+5ko
zX)ws6`WQtvPR%7HUV&U$+{@}X1dOe&V3svXeBaJJN#K`q4EQFVi;G-bLA%oK6Kag3
z#5Xa&<8IcjGbuA2{R;Q$pPe_#O#!PEwV2N|qF<Isp-Q7MPazV*njcr<;96-#aEHdG
z;`X!vk)rvdljGj2<_kO~r!4d#wseh2B%-WGyvs`rwj|CM>~6vV*X#jC&z41R<fQvB
zGk@#C8~*l=!3y*EZ&uZ~rp}XFJGzVW^v71<u3&3Vay*lX(Y)h4qph at pPyFb2vpB4_
zCYR!St*;vuwgi@(fGU<S(2r5`&**NHx?AwQR-h7*WbRGgN;Of}@YBYxE?KiT$T+KD
ztpj_=ZL#}?L_*j4|Izf_(QrP_*GhyCOFp8;BGFqUN|Z&2Nc6s|i at thibwWhch!!P!
zU%jv1d+%-a7HxH+zt8u)=jT7?V0m`T+<WKFOkelPRlni0HpII%v+t4HPLZs9=7X;n
zNe~+zYp(mJ(USC`G_k87oSNA4O{#G^bC#ez;R44_ at E{JLVD@&`L|&62$|8efRn!6o
z|GWf7lcGAoZd(A)r_-F4a2j$dodab{;D_x2^q<2Q2qoFdEK-sk^}%;1&K2wpGb(G5
z*;({KkZ_{P<}kOPsH}Z-d6Qd~DzDXvw+AU&5<Ms|q;qw%3KCI%y79}gtNb32vhc8w
z1xg>pU!7-=Y4D0jl+d<xZ`q-rzq{sg$z}xBj!uWOzBnl(%cmsEdSOGAFz!h^JJ~xN
zTi;^O8u<x$QKy)b)*RfAuH+YI$Mj1vbBSCkrymUYe~)EU1iTgDywyj3jB3~q+7x!B
ziCJpEhFA*CMTHR}^e9tLxd;Y_tLVJ!c?14?K}8=RO0Z*Ew$%A4b~0FRLXTc!C!IEf
zF(jPel)*IO8JLzs_Lum_qqL#Pr=rx<<`JYR?<m0WIe%qIGNif$Y~O5bn@%Q03KT#A
z1NA>%zF+?#&F<nX-c%l{s~r+#s~-iXNn3F-&Wn?(>%AnR>Kn`Jm81iO|A}t at l$7Z=
z;?xt<XIku#x{^3-roC=p?qi!(u@(3*T%<`iOD8|iWG;0V3^L|8Jyywl3ZE9BYIIM@
zPNM#5{g|(U`qhs25`I<7{+5!J4pNKvx}Szqu2Ma*|I~D}YlW!N`4Roj<gd)Zz!b3z
z(VyWb=I{9+N#e^w7v`EOI*C4#TAH7FzWcD#iZN5MG)<TsIGUCcFT8t9<X&^d(E&D?
zU}uTKiby03&<apq!(Ia+-|BFONgsBC&55I$JIt4#PaBd(pcpIf*;79>v|j=ftRkaX
z4#C^(J0CT=fgfO6pz`l4gP7UnVGyM8CqZ;w$!tg0sg<Ss#B>6A`3LI2?fpBo?~q0c
z8+=qP`<piNj3r$c(I=fd8vwO?yfiz?D~-^~+9=O8Hd+IT1DWrJ(dkw!{(n}M^b>Fb
zVAb4mZT(b2t<^%0NxxGJ^#Q~Qq!X7~fN!xmi at LClyYv*vCq~hof;Ul?M>ZUt?V9~4
zX8jQ9vT&6Op|F^K1A2uNz95+-!c9{4xSa?w0QoK1OeZk4{Q4EX5yQ(7GuEl$J%CxD
z*4{ME2q2IYo2XMzG~b>^E4;?MBDi!{-Hm^CyrE$(=$d=4{pR3`QHIr`_sqg7Red-%
zISC)k_%zk}Q|?@0tAD7 at 34k;7ZbfqmqtrgjDSpbK=2i%Sy6p}5e12k=cOuN<Yd8Kw
z?IBG%NZ4-fZ`d$bmg&Zfd6|D#TKKz|($t8q3jFBHbV(XUSz0Nin3)eAW9>$A<$ZVX
zn-}?SaegE9*w<x`@dBQyk5D}|p62M1oFxi~6~dU!2ULWI%+S}3-E$#D9ra|cUTT%C
zx7QPmn<Zc~x*NJAQEQk(Z8+5peCzZmoQn6IB_WER<Hjd9I>{u=CdW-I<H|J}nD+d=
ze$*rmlVXckvT2<5*BO_wjtGA;+_|MzDMP5d>ork))b_5&zoxc`6)*6WwuJJi{fi;t
zVSxj_ApbG=n at UGBpQ%}*P;A~c(BmgD+HLi`KYwoboGRf-0YRl;&S$v>f|!W6h<$!e
z4 at fW8wqT+AY<@C?ie6u+9Z3Krza}0Ps6_18r%LG6CnJNFWbL;8YJGpY0(xKR`1x_b
z|I|q1s1JbW>93aOZ9WM8BD#uYp0D)D%<0ut!VqIl<aWa)XJCYHFwis6&TU1=pxd}8
zQvfeQ8^iY=;qtT*V*KUtR3HIT^E=|3{SI+eOBrz<^psSas>4)9nn##-yCl=IF^AgH
z{w;QV>E-aRUG}{(qeLjK&|<s*Yh7Q(9L-JLoBE#2H=hKwp8{LZi3;>^uuu3bi~fp5
zv-U>LX5*UmM~*0BCE!I|7(NL|_%LETp&;#9;_dGsHI|Ubm`n&?vf&zDqYqT0s5*6)
z^^*-up!uiKaQv8+J`rt9vBa18XI+L6L>!SkWcCr5DITL3r`~bNmNd)_bk&I*=WYLU
z{#aqt+$5iW^pSNqjc2MYx?<hQ{F&CR0=3oQ9x!%%cXwwju4US1qoq9^dZ?@<P<^j0
zA?E=_ZkJ_HUL8m3ydaG_wQCTddWy+ZEgJ#7|J|J|ow>1J$ri1x>x3c}p=vu at O3(T*
z+`O0WP4zY|jkmxXRssbsmljFo#qSk!t at rG6fj_*9Hu*w?)ZtZk&?xsD$0eXRog;Aj
zJ9+8Z)Nr9DXL4GWD?v<R>U8sjZbH`7P1x(u{i*E(d!s}>(+d|~f|zP1gWyPUr$v=&
zD?dNK;*eKn{jxX1b%v4<v#Gk=n1FU)fyeAm>4YVE>jgg#Xjcu3G{z2^^AM-%c7lcP
z+3DK-u^jP7UZ(xDdDOfAc`ee$Tp#G_|1gUB!Eg3BG#?Fr3N-zuFL1IJGy=`GmfLjG
zF7F?ndS^2Z44PA8j+{vmq!4C|A;Y(?WNRRiCBT3;NbYywi|PR3_3Zni0;%7dSIDlP
zULK&;UPgUoBK+*oWcH=RYc<lP8*ndCVKHC~e}0HJexsGx&eG>8Yc}2qeyU{})oWt3
z-HGam)h!Xj<Y|~yGAg6XYinz}GhcSUCq$q(2TA|AXHv-;!!1vac{c|S`4)%24!&L%
zXR9RO3VS#;WR)=H7h%LaVpH(B=1Y{WsA9_+1LWV)${CP)@tpsUVPGCVUb?s!e=uU?
zDd|N1po{|@Dx(0 at hS#a{<i$XCMA?H}fCELl8J`44R}@@!J7Ek$<0$gWn*>K8(1C;6
zQU9cM8~YP!H-g!fH^OI}WKQ&#i9`~1);oS3jk}e$U#fJ0Uwm1h!CI$l<@~I_FO6bj
z3(Uk>8 at Tv*lQO9vv1JpheiFTL|L1Tbsbu9(LRtD{cSJprc?R4Nz<1p-d>k7#=o!9|
z8Y7kR%b5l~jrGRlcgn7Z46l>ChdGTYy^M`qlB+0}LEaC7hDEYBWM^+zVzo8ish(HD
z9l7_&s161|7aBvxk6tG~g%3T>auoF at -YsV8(|JzUo0yWrLE&|s9g{2|;zCMgsr)(E
zdj5<Azj{!|5Q~-FYHlx}Kgj0eUiH+D3!zukSHVxl9)3SbX5>P_qvofyrs at 6+QBEig
zyMBu|J67J5emu*}Km?JB`%Tm5hVvgkx at _I<0*l)NJbpP&L%7sZM99pw#${hCELtq&
zFBJfJsI*x>^(}o2fi!*|0F)?7x7-9H2E4b at po#;$7lJI9Bi}RU>~uA1jLg at lo7Ko{
zh`MBCP3X-JxLSV&kmHWpE)COu17&l at qJJOm@rk49moXqe{Q6n|wD;UoneL_zyZC<d
zx5rKck+RWL at vySp2KN1*H%0F0XITmJh$n*Bj126G)>5+Kv{#+~n-7Etu)f=)(&AaS
z%UHBS6w6n}smVaH5D9YP;Vv;&#-vJ&QmlDT4b8K^b&oy%88J<Tt<)jg{~xh0g>D58
z!Dd3D>Z_IY!+&*DbK992``pCw5n>(<eM5Q2M$fp3niBMnyecU|)!KpdanCgK<FEtg
zD3&-UFm95BVoZ%Wl8~t>Mhkk4dgT+uWY2-0-)Z8kNlHiBZohI7f3CUC_>9whQUe
zsXrSZdOzd?ZsOzE0J3bta(2qLH(`|n7xa=o9Px7$i4TMM$gHBuxgwQH<6nLkdoojR
zmj#JZ)x|{`V!RG=DSWjL@#)s);!>);T$Z#(;wmy|882>SSpO)!B60I&Vb9Bc`YcK@
zZz2=>g_$XtQ2El2b5%XR>@&wNN8ZPt3<BZlzhW8O99i`liHfOX8RDi|dPK5qXk<ev
zcDUv^ISa=2Tbwn(&&gkDzhAF2e)scK8U9O~W%}zg!wQC!!}tRn3(c5U{o-`q%HwrZ
zZ0l5xkyNtE=wD)sKshQP=y5&+vW9!tidatwD$r?i{a6dw9<SAqyZTQw-GU(H8o<KS
ze^rpee9_d!;)Dp5 at mnCh)Fe}H0d|zVf&}K5x?i80tb-och_d*8647{CMT&3`2b=`B
zM+~SyjmC<kTA-1v(Fs&Evop(ii`3sPZrXfGtltv(fnr(;AaqOJa6H>uF`n!gFSIP&
zWF at ld?KEMom7d5!C+=kjxD#!YR0rehkcu6~nz)*aVG5(SbU at Aa%?&^Pq(?Q^__{hr
z9X9d3FWNi2*K4&*D1vD5#Sdw7YU*rfNxbKNB at yXywoYUftE6IXuiw1D887KKE#~9>
zJD at 7hVf&V2kWI0FxjZV~dw6me&d-ue=-CW-Hx-@$_tbX}6*~ik8-Cx2u?;0%j!4Bm
zJE&Nq-UvHs<*-ie*=AIX3^u at FcG3c-sYzt%J+s*y#CWF^Nt1rP2zZAaoI7HzO=E~K
z>A8M;L1MJZ!#LAtuN>j|;>CCzRmLE{P^C+_DRZx3RHg!zzf0LZvs7zqN1!yuGTEK&
zS8m6?zyae|K`^%Y813S~a5pu9%;??2v0G`MBVAubNd~8+|E{Bjs92`hP->SBHx5H>
z$oSP}S)PF at w&7(BV`WXeO!{tv=_k*R?x?-K^1uwW`tv=<cU{!a3NLbcCS at BtP)G_6
zhn1s?i<DNUiq!^lJYl8W?+eypO*qrAg1AwbzC*f47hXY(2z21iEzKHJR{|%)75lo+
zRG7L+ou%idcvUnz9kM87t%p=gK2_%Bx}bw}Y}RcFLq(<pX3o0)8dM&mQph16;?`Z2
z`p;d}-aGj!X&V((&o~6f`8fs$4Xj4GS$AQLA5mmAZLLLKtM!E+(`u=vBXt*U<TEdt
z)HH(al~7Xb*Ihbckra`otC6Zt!f^M$yKVJ8Qt0<^4Bo8~Z&?GyxgESa1i#LuL<lJ{
zV2<|PNid{oA&@@<MNSFQ6=WC(x@{Uv{+sVln#48LdO{&OlYEca6A$kiDG{;LI(VI8
zMBM*n>xDt8^tDA#eQwWZzWnY}_*y;Z#YtXcvDc`VsK+cHM|@72Ph=_llZ6Wx=LPM}
z+0I1Je}PHpQ(a5fwhpPl*X%UrodMaPH~kMWY8fBK1ES6-1O2P8JVJEO<YA)On``wF
zkoOt}+ZedS#LD(*&AF8u_sC*k*WSsc0GO{JMrx-zZLm&3A*prpXRBM;42CpYPE{ZR
z>Dh-h{x74xLNi6)2zSQie4JCciEv+HWN~q^%RetL6oEkS5Iz#vbV(ts;0V%Bf2rRp
zRw|sfa=$UI>(S)~+b<&AqK!WIlN_5mP8d#^b#-=aJF+lc<H<Fmjf`^v&t#>FyM2sJ
zsvcFxKMG(cSv9aP)L8f&kc{)5tjP^R@!~O3B*FSs&H0AjC;UZ7l{iE8amItX$NtFs
zhsHW!BTIsh2zFoBG1*W~rALaq<8;Ssg$NDJVnJ*QLw5?ovUe?p at PUp-V=xPAfZKA%
zz1Q<T3OuD1MI#DayF<1A^8zf_P5DK9=5$=bfhqpprn74-=d2YPd;ROi?r^d_H13cC
zxaP%$IV!3W at g@c)k<~oPP#xRL+EL^J$|xzXN7NuU^Zfuj`dR|-c5v!vLh?FFisa>X
zaQ8YHMyt_>2QxZzNP~&Wr~pYgeh$(Jg(x{S2k1KnKdv3WM*0e01oE$tVU9%qQguB+
zaDg<i3d|eb*ux;xP_kP}gvQGfR2D}l%VCy32;qHwwi8s5h3Y^#w}YFV#W<90g1T9V
zJfJGBwq7L*)jmc^+EQ5}Cbd>us|Vi&9BeCL^C<FEU**kPPcdB==+nXtv%**X_OREZ
zl;c*D0^2%6SjDjgg|=l{x%TOkZ^rlDjXC}s at n^*=k{In6k=tt4RdmAtkz5qJK5rE=
zqDPn(8|8^h at I!$Bk115i1tcr?JCmrGg&NgQDR?C^^d|N(!-H!-9qa+Zw(F(RtR-QK
z7~?pxWUKogdanMT5Q_B^u~pX+Zq<Ru&J(o|r9Wp)g2I>Mq<H#Z3q9y)`nHkkIjYz)
zu%%IlhyvvOJ83h?kvJJ0Pci+ at cLy)0|L+$jK~F3Ty9JhK2g6j>`oN761;|{nso<}Z
zC62o}yUgVU;~4XT0}Z5awsAsw`rZO&$CAhPXSf0Sb;YaacoX6`-JkFvFzh0Y>x*x3
z!^Kzj%gtiyFN(!s9H=Vx^(uaT$rcGz>#*r?-J_WgaJ`&xh+xHG1*z(J5zW)2L7^fZ
z(&NDy{CvVt)|GoY^r}Hk`Wjk2#<#TR&@nfsqJe^gyV;-ve10yx3Tmt8h;kDSh3w1B
z8b#6VRdd;Ce{{?>y=gWU?asGGWyyI$Wgx4OA<lXo;F6sghtFc|qEZ|qw=|d|E_O`*
zkIy+<ijm5wb<=+9XL5~WuU2(Y9c#a~m1e3^ZM(pP3C|H)8X`lfDFE6k4M>y@;8>no
zGYcs>&Ow<3b&3HC0Jkoe{oeNjXEM}%JxTmrdy4--<F%<r9ZPD{2if!)27U;1+Z5K%
zwIo|yzVX<E{VH~PPB8aMU7+*A>8l at crT5%p%N?zyTI&1}MUDh4%_&lkY`I(Er}oLp
z>2}iQQ?)1kP((pxol_eJ1 at T6b4fP`p>tFVIc;WwhrkdIq4939!D_->%zq|9ftlo67
z(7x7FWH-(?F?main at j9C78}@4R_=!LS6vmpc-AqI!)6uhrvhK++KgXJ8=5A2e^u6o
za<cEPKzcnhWfGt2P&?80+fowr#gQ{v`?Dla<Mo0H8HyIk?tY3KvRae{6s_iWJ#LFO
z%-=I8sfm>^>0T;s#yTfR%-)S|gI#kOaIL<j+rM{p;#o#(3(ZtXHLKk<lI*<6LoiUK
z{#3injBY>Qp7)~rth-7s&7`0-KSn*8Tx78g(m5CG;~&=YE at 1t((sT8!K#k=%RBgXW
z>!|Fev`6Q?t|T7zIIy1bdOz4$pmA^f(GZiqXR-JPfr94=`&VdS_tOt752YgAohy5V
z6Ys at lS6f1v+IaN)gZxkk7e7I(h7wXaIC`kG*m5L9EnOL9;`m87n8sbVXou8~Sb2dt
zy5yV!^F~-?s4t|T$omBxJ#nK13=pt~{?mHoNrVs;7dKGJzgEDz99{-OVQ*v`_E2Yy
zlF}3I-v>Tjnj2jMHPGPhu*{6(SSNY5gDHY@&i#NiazztQ;6BZs_65D_gSxPJCnHc=
ze!TYCv1d4B*sD}#{!xoU00n&~n5A1ygGYpKT}#B&1K^o&e_#T9Jw5A>DrSFI;btl5
zZJHm1?i*Go)sLha+-w<N9Lh<-FtGbH=XaoY1ytsr*m-pOC8xx#Qklw-96!DyxUCn~
z>~isfV*W$>Ujfg}^YrR;JIqVdV0wS~(b>htMNo3xA`aZ=(PjT}U0wEP at 2iu|4~w>v
zSI5W4)KoAN??d+|VZkwd!I$chD5%q>_yNHIH4mF?%Dgij&vJ(}BXT%a<9bFwzs{gQ
z at I(rNMjMF;H?g$2UJ1BA9CeV4+;p0 at oiEDWNt_2{pTcs?7MGXb)0<}XSy1dI)fg9s
z!=?FaF6im#UUTpv;eEIiKZ<oQZF|@@U5hw at fvq$v)NJ at T*}eJAj1P0);AzKaXD%5w
z**3LPB5A*+#tNS!#B}QfEsuRX+_kUbesT|)9XhRiA))^I&pgM?wt0d14eM at sUw!n*
zFpC|xEis`|#9WRt^r at u!lqYxG<IUSv<KcS+lEhHae^+to^kOzx%OA8GX59MS-mwK)
z<IOwQNUgX<XWPoM>V?OZm~ChCL94}QMU$liC?*v6p}5sC$f{yT>n^43Z3VR)F3l%{
z#_Q9egZ at 78hRcbX(v+bPemM$66;al;Va$fxyxuYZhR82cKKEC?Q11kDzxn~;kFW{y
zwmuX?Wu1OO^4E~PQ_UUrj`iL5X!3%ct!;Rn(qL3rnznbQ7oH&Y4ag(PNB!EtDW~Tt
zOTZclrcjEIcMf0BM%WJj^w35KMWetJL>OL)rDO2%WM`F&%iFR_4k*=ggiw{eHyMJ;
zD-5z99twF*6XSW;4(|@qXIHUzN>)>{25ZP8*dFw#)j4^+X0Ht<JA05{Tc_LBL?UL^
zx024RIk64$`lZcBSRbA=NP%VeviMgflO<l~49^p}bA&(nkMox;-lrbhyZ0PnS|m?!
zbBKof<F>Mfh2wmoOV+x3M6VwA)=*eKhKJ2?<Vy}Sc^#blOiNhd+Ih6)h*gI&HJNm@
z4?El)_s~-&*YYRPq`~wp_Xa3hY>%y9pNzjE-g=B0{xw%{<gDO(ZhL~IX4+<jgqlL$
z5X$fCYcytwQ+3B&v)hi$w2r>c3(SRJX=tFG|8sG<$bZgNpfql!0gvf^iB}lMzrNU)
zQ1&Sq`Tgql5`La1a=dl^aW{OB<o)f at Q`1K}oG^E`_=>$d;Dl6tk<5=u>^OKeTg7(m
z9VW at 9wjqVW#6&XmNq%s}CC@>x at h7~e(@hjB2!GhSj-|9EJ`SG5TMQ!SEn(<Qqe46S
zg*a~EeX$l#O;Qxm8C0%necj`YDo)s2UM#NYDlK?B^GZC(l^DUMR*|L)AEkbgc50l$
z6+%PT@*TqU;Yt|F<V}Ros;0!PW?W)gZ$e2KdI4YjbfwX;Kq|tT6}_5d8|-wbAMPBj
zF1`w~EM;~5OvL2-0K^D5ggg|&F#|-2TkCBRxt|hH#=cFKcaz*@UO;XzVw^<FYmpOr
zIX5L0d*k-XjL#mpG5Mb5v1eo$s%fv6ScWPF%x#jHctp4+l&-?%Gz{~PiybqF3bA{;
zUjH86kRyz+9b|dkf5d%M6QFxvd%1r3o9Ok=s at r|o7utIo^0v^izj8EW+Rw&WKfSht
zP~+UfRvtw=(Z%%^J6FB1oY}`pC*Ri}L4K(b7m#o^__*ytVsh0As`GFdXgYZMgCD!p
z&w8RmsX*&+aYR!`P283w%E{sUtgP6&a7My1dVXURSCQMxj72P}P{}2eaWc`J7S4GO
zn}Bfry$wqDyo4i^CAis^o!tnu`C7%ZSf-%4I}Rn-^>OFw(a at k==z&P^`pqc4>0yVd
z^eXPo`(fC=*ZGI&08icy8(K9v#O3@;O|tX=z2)NAXwWW9x=g=AE- at a?-PCGzHeEiR
z1-nQ8W{DqPlM9349ekW|EcqCk(r<b56kc8PCHsR->1;8Z^c+=YUT<I6htOz-kM<OY
zeN+Z*DL&n@|7qi~Y$K<KR2;JSUSQboIJ{@n8bq?vQ9-~zzphAXnnN%cwFV+81KwWk
zFP?6WJ+dFARlm_ZSlXZ>*Du#V)Nc;@wf<UWvSYOH&%Z(B8YmF%O0rkgF)uM?y_*L4
zi_#Il&x6=cyCduH&QrEo(Jv#$eaf4POC!4yLK)Z`m at 6~>TMxyq@)Dg-40=Tr!`(Yw
zsOZol#2qO<MB5Ssd0yfH1YPU0Q2+GsLmJBD@~qVFZg1-|ZUJU4=VQ at -YzLpPOm0vI
zW3c>BV<(l<yM_1lP|mAjC*4B~CRKReS{NxYE~!shb{5#v(-Zdcjypd%I5<ptzqRIt
z=ZIy?<@w%BScg`GT>*(RqPeN5DZSX{yIER`RA*~uHgaans*~b- at P04}eQF`oLa(CI
zqG*o0&7y+6-(uic^#;4Vz)8}KEj88bVF?(+H|L!8Uow76oLbC4k_uGUuhASE8j<>l
zJg$Itg~nphAuCi926th?NFbxLt>x{Bcd{3?aTYgg?F7G6Qq(Md&&$gTOH8`vMcu!f
zDDxK%(e|6csPBA*rPP#A+<v-=p(#JF`PiDE(zil9v%It<j%Wky3niOx<P{g`oRp+^
zo@~B`HX^Nl$K{Q2Q2ayi^!v=$%^|{@oq=~SJh#<EdQ@`YxM*+J2EWtYXlA;@d}^3E
zcL9-Sr?#DZMmIO#*wW&MX_c?eKS^8?RLib$`{T8sb9;Mr8rI<$oOydhu25r8(;^pK
z!B*zAtP?Z+SGx-Fg-k65e}`^!SN`-GAg*bbB~$V~ihqb)n_F87oo0tWLkPylDGoWx
zj!#G4zc1v9Tz!N6{jO0?)vMXdj$4PotqXj2N`}doi`haNld&gr(#TnR5F=0&R<BW&
z+W>^Ds|P3*i*!K8u$(x6bOvwtpDyq@!iMHTi+L<FbSIL&Xhymp`l7n|U~+Q;=$8rA
zZ0o1<4>uq)iNA{P&<x~SX{p2L1K~kdi?=@iO|O9z-JqtEqpo|<(Cs%NXBYaX4#7cO
zVn*3FKqV3f0)9VV?TfO$Wm80r;DHJSVm1Ub+j&udG9ipu1HrG{d|!LaHQWJzjD0Hb
zacH!BygBfDds`2^%7saNxQInb5&a<a7e$zNzoqprJIQ<UTl7%u8?m9zvk4QEG}}#S
z2Q(g=gezHLnNi#a5{hl#qI+S2!&e1M4<+YJL2U0)fw6cUpq4$)g_pCoRWZ)?n>5NN
zep6?HRFD|HC`QW5ot+)wC~d_r#ul|^m+Xq|)=|H?zG&c<b1M~Mfr1VbT at 6Q&;m_GD
z8KLboZ+tvGJ(mo{UqIf&p5niTcUryhc;V&JOT4Bd%WnH=)Hxc at jjhQ=u>n6WS%1YX
zRdUCe<S%nbiC<xaV(29tT0HOiSO4YRr(kPvM=`JPj}k7koEH&9Fm~4$OJ5mt92sN`
zGbL@{439~R>8u~4KFVTc{x=e0l^*E6;}6Z}EdEF+-{gp7ut5JZm=iJ<l<0Ata&V&u
zSx|ff4K`@*`wQb1xCcC^C~$yMEEwpwo4P9VZ8niHAN_9BEw0+*`SF5)*1ammXxq$s
zI^g?aJ56p4=}HsysvP$UmsI}WMNy4lZC=gDrL#|}S4+w!e~HCYlvw>E$DlA|_|ED?
zWRpI1gPZ`=Rk0xrfO92lAkJyn5v3qnGsgkr`zHh7UgUIKbiF7QiF8zlHrd<Is*Y~`
z@;=OGw2@;Q-?&}!h%|cjsNtsV6otxq#nS~Q|IZ??-paYUZMG;7)q%4`=r1Q at eNgr&
zlP_T{GDdS|`b+?AWK#ze%=u6VvXd1<^^OfgWq?tbyy({W+y&+(nzr?HcSp5?4T4Ru
zyTHx0K6!F(DJB&^n#5jWv{oOOEOM%Vn*Fw|?)SXO4~X39Ys?#^FQbDTX_^8dNnLRx
zxh6L3q>sBmO(YvS1xt#rN%s#Cr2nG;wBvEYHWK9l at Gu?qdb2vOf4Z>&u7%kg+E1eQ
zc6F{qOC?E-bGjwroTlSOx75-Uk3cxD^^NgTmu6C1;+i;g3Puj~BE1a+XD}J$A2=5l
zvT?+S at tVvF)t1r-?QqDj9X<A8wl;M-#3f1JFS*5(LL-7dS`v=iWf#q1zmasH8h1P9
zpj2}ZxlysZ5OHBG_9e-Ny8W?qYPyb8Hm?VbXfDks#t!q$3V^{y_X4msijT#ioc=~!
zQRdLy?&yC`(?0ag4gK;&<2gYEG+7&kvi`wV1=O(BM at 9k3)&|r*-Qzk%PV*tLuvbSX
zUN<)SBXnnBW8}~Bc_VJrtfKnnFv^4>XHv{t4dO(G*;iM3oWj<s?b$QuI*#OUp+{~=
zW;qDo_d>1OJ$-y5e}xY5As*{SxMW5p8+4gWg*^vZWu;i&1c%<~c)Q#ssCdET$T=~y
zr^2g|2Vi!~9G9u&tmpv>T at C-|h`)2kbZAw%LOK&dWaD?p^jkL9$;=XtUn~QP9~4Tu
zn3G<{H|wCs5^2BMh`D8-MF^YxY8B#kZAN8v#jZsTV_+0l-youu*~bs8Ktb~XP*DPh
z&Jhj9;@4PWBLz_>m_k5jlnYa)!Y at 7a@ECE%rOrMqB#Jg_2Z)+Vi|{x1LO$~zQ*$Eo
z*4CAV&_7rQOhox^i1Srf{1SHE6mi{O at e5v7_OHDv$9212d<~Uqea(Lr29DNu(1CVX
zWvJzf#CpvVO>1;jtbGyw6xblCV<i>WB+9j at b<+s7(;zJ;pU3UN;%CryZh=MO;n4K$
zy!&#W6J68aNO-n8x5mfocyP3iw5pdsydp{{`f$MD9G}%_06juBo5AH71nCYfO$bG&
z7p-e0qTHgNyM6g9)FJ?f4-sCMOq8Jip&NM2l&lS)@1NZf@$<Z3E3`Q;8NzLR@=ZS~
z=^qVc|0&|=NW(Q+&4 at QEVA1m5lF*icnuzmE{cDRj&qo%!TQd<0iSa%o7UFveA|DON
zbR#67g1lqkl%Df~q8s03BmEqRa`X-oe+O(XU2QiWF$P|m7OHX_l{A1yYdooP*1`rA
zWP#d|xpREhH#v9=+hVsMX2qNwt&fF2!rQS}orS^ec|vZ{r}n(to)uxGt>N$l|K%&e
zuT9&?j?uV)bFbQ(n$I;`MRv7Bha#FAZN}OSwXEoJz7C&lbgV4$c`_MB$YZAoA3<Pc
zMihIU_g`kerrJ+*TKC6G|DX`^=hlC20qp!e053NM??&4sr*f1VM2--`-9#G at QO-XT
z5;PqfW70yuj2Bu39e_$!K~wcgC=+l#AS8Z(BbJT3bWtXU|Gq&)@&P<e at d0^#lPYj9
zXP~}7hEd7<B2tF*p<uqdWgY+sM8|+>?g6jlHR#TK2;5mE!XRLK&n!}n*~T0meo3&X
z&)5^0UwsK@)(|=NOv;z}To%y$QN})&BRFo!DA%$}vzjuFec#-63;xi&Y~7$(VBMCq
z;zYFZQCszSs|T4!y`spbjPL#JRc5^zkvjd$!gyC+O06fEE)ms8^Gu^2yFDq=H-tZ4
z;njSe5?ID&dYDQ_Du*0ay3pwd5_{r`u{=vz-`T!oIPf<i?t&c at AH&#LV2efHp%jyZ
zDrQkl2G|w+gd~r#<sd3 at L_|0Z%Ebmd1*X-`hmQV^qKkL?&84SLZXy9VM>%DVz18<f
zIm$0OqU2;8bNTy=uSdzg8`f0E(6E0+6`jS at JiWeQtWv=vH)+w%Y&x##*NNx`XOwSw
zjtfN6aNQHn;IRs2p^`rR4s&rpQg6Pu$>yS#<*#B6FQ_7N3>n1F858GUy?(f_!;YfR
z-`H=^%yzOX=IYj}21^KHYpa=2_Ld|XsK92Gac3!H6iitJZCPz!AM46Pf?2=3jw%}Y
z2HlL2kazrC;9n91`eFZGI8F1HKd at huawId<rArFH#l`=0pmiuI1`eo-?Cp$0Paow+
zOLr5fW6zqLqCqg^78E2{KMhFA{aFy}4ZV};uyjA`ySy~tdJmwUL><;-X_Ax!LJuSG
zt at S^l?3@^tO@)ir`ujCd%gD!$j~0C<5c}bGbtF(TT6J0b^u+~2y_5!<nF{wjxI5&Y
zMRAyv5>b^r^BT>*6k4o=TIc68m%Ib^3*rjEdhkUxD5I=3x3wTRH)@rw;=MlG at 1m{V
z+nGxuNWASQ=ZNtS_f%S>`VHUtFVxhzRF6l=@tvAI*;3fLh_?P~KE3DTK3fD?dlO5j
z_`)i7m<gIL<#}Qy7{%6GFqx-~3QR+G%(6#akDE>b?K(+vc21aWvb~{B|GaE~qhVWm
z_VLnE3h1xXS6k;K87kWS&?mky%ei`Ofyyd{7zfDnJiFckLYx0sRM1h at IcDbuH1>70
z`ykea+`aPje;*6o6qlaPTHR at u`n{E*Cy4n9x*}}cPq*z|_=*`{K6^Tf+tHD^$kQeL
z=RJqmUnY6&P3gGt at Gw|_^=R$+;hpA`vOuX at -GJX^3TEVB>uFK{#Jh5p@&V8~h`!Ke
zZ#;3oZYz8z#hN;zIFn}lMR;1tYRp*~`Tej(N%U?dC9PK(5vnFPg^!Pp>-aA^_psy;
zeR+0t<nZWG>RTLnMS%$I`-lH2q+Go({q&K)4L)#?3&>swd%a8f9-V?H6DgU`>;K|a
zYrhIAnCup5P#)K{dTtq<7sL#$?*tEb0|khyT{fs1=V5sTl=x&h5VF6a8DfX(5NP at a
z5VBYV1>%R}zVA~6muxw3N0&EFxeJWr3|V5S!!ZpWU1S`WO(w7rtF<`r$k6%##Hao6
zK)(S8W|Xf8mE}CSmyT)p4l!*9UPT1Hd7HKE;27NXt9W}jRo5cfJ$8G=%i(hYoU$)G
zusnxwHmKaT)T=_ff%ZV1d2m%u_$O>o|I90-Mk_~Ho11+oGqB7x5BfBn_S8x7yhWvS
z>7{uCsjdVL9SO%(qj at fJ;_qTscvU5B at uR7KMXd$s>3(?;3H|xVL?3)6sPlrS3RWAu
z^jYGRCdmRbKB(_EqPZlMHv^_8GCPZX(?3X<S)_xa-fJsM-&{4T9 at w?;SP&4fA<q&u
zYzvaD4L-NPB?{LSgh7j`v~6p<7UzBz$3gjvnLJP;mk!a7FSPe~c^(=o;Vd|GysV|+
z^`QfE=ZG9e)Mrj;;YlPzVenA+h4&Y6&Gl at 2qwPhO$#S35qzxw$Did|`6PMgWfvcaD
z%*YJ_oT7Yrqsm#sT7#e}3T2Ta8 at +;+ujQ?mss*mw6uUbwkK(U0TEiTdH(Fl>?oCsd
z437wLs+w%L?TYkdjiq|Q at w(KyIF>n}72_x4k$RN}YaU7nmW&jR!Vyn_Vs(?+!NmGC
zP-#Knk{i1ypA`il=k6J&4)Vyuom2BVmWK)d!Ox>Ti4g=^!0xS|hh5-d0!uxwcJP6Y
zoFhjNLh6i#n1XS at -H}C$aOw#nw%U*~50$lSk8ghH4Ub)WoO&)dM)}}=KYwrx7&-R*
zX9YxoxYJy+Ubl%@kuO-D2VjYm4<P%bGj`9?6e#OADCA(Mf8I7QD|)8NzKvz)*E>mD
ziA-`W;XBQ;Z7|y>a<~>E_y=yR8AraFdd|sVBCH7`#@M923tLtcW~dvPA)b{pB^PGd
z7M56lskX8qS&y7pUth1>$E1dc$^^UE)=qgD;vZprzFq;mhdSXN;FyAG;y#{jU4m>W
z{#n7vhP77DYh>`8JaGsJHD%FaC15TGSiJ+kfW8G}Ws1RAz<p{TDuCzWWKH=muenmv
z4o>4nrOiGuAeoc+6^q1g6LojRtl~w&*N*n2{pYG!I9_#L<E6J&n7xXT9^Gl|z<Avh
zc0|FB at +6F_J*_xvT+b!T)~tf<4zq`MhM@{96WE;v<SF0hmBpD$cJ!B<3#B3y^UuIh
zxQ*LfvoDmFL!0}dx~FmqA|$M7nyi at Ne4o4P^AA?F#+(5o0OQ}@`yEhY{qJbCLwc=I
z0D)xUbS<7&lC+Ow%E7<6g4JmzLeZ at rg(GS2-}fMxQ}N_)8pY__iaubu9!>{&OW1IH
zBhOH^?U{v{vBe#Q>)%}VZTu!WG<d76Ha4M at 41Vfk98THo8>SBHO1a`~w)OY+n$rF%
zw*J4AQ}=??R%-qiR=+cxe2Mv^j?k>|=&aqIX;5-;jGIf&<2bA4_v*bLhMNGG%7ZCW
zdmT}WgFozMcfcj?LxM?obZ=aT+R`W+TX9JVr3bD6*P$GV5nB6i9LW$|1r=BqfG|F0
zmcUioAHxD+MQ8YjE)tkzJ_S4Wh)?)5o|?OKu7TFKo1LG`uyuL$r07qUmO7ow*YuED
zyp&C<CbUeQO5y?dxbxs}3AAt8c_3gG=s82tFTb;4qB8eHkJ!vA9cG0c+QGWY>c1wf
z3`aiqum9K7Rd6t|>PJMDWY>a^5DG)QExa7 at yFY!ny}vme5fr`mD3s1yH4eg}T{~z!
zqSy%7-{KLaLX?AkC6;qjiHnIXq8AsN-YoLsUNB4u`w~smR8eQAQWMG0$k>(xy&UmV
zCOlUd_eM8z-i_uu)!-T!55V^f&hJRUD=7B#a+o*&LK-~{uXef=TXG`H8c#=7Ox9$y
z>CJ!j9tB5(ic)C*aDFU%)ZaN4sPaZbs;J*)q3^%Hx*pX|HHI~<nL0ltRXnpp=EM<k
zbe2!l-V}#Y`9q0z9nSr`CBj(paD9kKtuH;b-05N4DKB+053x~3Q;z#!gZOBp+H~kR
zXoW<}O{sUK2wT6dZDR0?@tSBq$h|>SK(Y8)34`R-D4q$kD}v+&-S5!9o)dN2Bk9b|
z^)fRI$~qxkPq4GB9WU!q^UHH$Pe%_7D7-|yFZZG73Y3axd<uBxY&t^pFtmQZ{{Hx<
zpI)z_y=}OX4&tn-v{`doe6#g1(MFMnPMg_Yb7<BMp~lPt4~KQ}+i`vJ_<LBVTbxqc
zmwNi&qn71rb0dfM at RNpZv7|(Bl$e(^*9E4?NuIel8#C++*~?-(@TNq_(AP}3{<m9h
zy}e&B at -Xwo&nLB|j3`^w)v?ETVEST<;Y$ZNZYu4Mb8xBR{c~RxRVVm(^e4xjkToV-
z)uhHs`GCoxL6^}7FNfd{PawfHcF=Iwd-st}<n7vWYz5b?n|LisDrAjA$;zutNR at CS
z6!%>W<^OpBCe_B9fzaXPz?69%3cMiFh#*5uimcLL{#~{_+y%faB^&ts-9lP??>xUk
zvSE~n*&qZ<>7)Vs{<swId#SDcX*s!DDA!Sy6uEIU|K#txCdfg|T3s-83jLf-CG%N}
zlz*=>=52j9UHw!9^!EmeFq~N9oSnLt5`{_9IVdi<d(1<rBDxQ0EqauZW;R_EUW9{B
zN64W*S(y3w=lEkJi|Twg#W%?|YxF1moPpK$euKkpysx?mp){y}g_*Cg9L)QrPCD0%
z_}$@na%pcf%DHs~J(us6mZz&E2C7$AjoVET?JN5$nZ at RTq1LKPo|{_A_v~OMQS22k
zSAYf-%D?T>Z28u(FErR7qWn(~@2^^YeZnlLfS7zqA2vkZacvoN#@*a|^*fi5=l;2_
zQtC5ZFJ0X0 at v3@u?y^2L$bXL!ic^mW^JZt5n&sY?R2J_buZwAP7+OOA)~7A3mjrcn
z%gM->M+Zy_9QYJc!5FuY(4>#-HZK*CU^`+;ZluhON{MD_eHBe`VQqKp&v at QVgA4Cs
z<$)6T^ZC$Uw<iNUf`B7*1PZmx5!mA!(<~myY`<Mo=!c0?nR%`()y1URvnUg~YK0Wz
zkLjYM=nIeq(?9=mqsOc&Q6|<tL4!cEeY><1d at iv-J@#l2qYBrp8U7BrIOXK;cPX>B
z%*&5u-l<-T^!x;LR4=(PvuR-v&t{RpcPw(p^A4S<)mG(h>;Tp(T3G<U#;EKrChS&L
zi~`M*1T2IyB?9FK1Q1n6{KgN6HzncZ4~S`vjHB~V2*eWu1PIHY6hChg%#l9OzhBXa
zYX30l%v(7;$Z^F1Tv?zUJ&!sw`@_bliv?K`5jE|}Q)?9$3T)9RsmUPDKiL?H!XqCT
z1iMsqWE7<v_F!#<=`nwdxVl!Iq|8=}tB)^yZXUnbAq7;@3CU%Bd2;E=cZlP}1gco2
zeslT!nlW0TH0wjqa?EZ}Slx5t;29BG7ChBue`rWiKq74~54U2vxID}sd8D4h%c;gn
z^Px%ZsTFJzPXd#84H6cuM-JsDa;$JaLy#mB#MxPDs+N>8w5`lpA;BZa{)EP=1+Vd@
zOB(P8n6&j8;bV1jotkdiEsak#xM_tBH$|QVI at n|zLTM|NwS>#Yfe%9X>n~BOGipl3
z9QKEGKR0z6mUL6VTG50$Ir4C5l90~S>6_RJqs at xNUY}*;`N__K`F<)LJv|Q_m77t~
zSpyy9X!q;x&9f?9z49MZm1RNv>n2mNk3=x!JE2*ve`19O^i)zck8xTM$3BjWK6#hl
zeKo|E8~mP&6*Su8fA_g;80q>8>|3BQf#JQUrQpHjU+0q>j5s)c7IR0QRUsHF(<en|
zs=8imI;D`ix~Y%Q7j7O@>4?odeByw^<&#$ad@}-?S&z_G9wrHRzlQg8%HApgT?=$x
z37=&-pb9KEH8gmUBPQjfLiNgf0d=}sv%abI_8UYe9Ek)pWoucqV+05VKc_=y97Svo
z`vpQ2BoMIqHVTA><B0%Tl_&x5Qs}#x!>WHt6$bpk9D;USs22T8b$*clG&3L84p+u(
z7kH;XuG71gtMP~uJ~cTvU#{G9GB-&#ZS1M5qhUj6O`--LnWZp){c*ciy&`hPf#Ncg
z_(F-hj&T+JB$*H#?yP8#yaMmA?bo59&3;9bAOEzlmFdt$!g-Oa at C!(B1~+?G&DHk{
zIebqQx%O__y;}SyOA5?kPs at M@H1i7wzc3zpRs1PlPLX3B$yXbk#qvXujhtw9siLqB
zUX!+1d6V{Vl@?~zvs3_1>etmxgx<rj@|OLdi(QT9RO+-<8rK at Rv#Y|+ at SHur2<cWN
z at Y5`&9vXk+?`P4+<sKKn&vgy9ha;><uAap_xZz&h-|{sy$Mq~ZQ at PsB80W|vjuO_B
z7bih?cN=dey0oPQ3qHUk6}dL8bXTVqdJ~C9p4DB96BSeF#$Exf4C((W9xR{EA~T2g
zJXv-wop__I6%M%KQssu-6Mh^Z6!eNx?S{D9RHBTJjh#ikG$AiG)8)UGM{{z^OOl8E
z8vZ=%czSDJ+hw<Vv1JkM`s|AW8>Vdcb;^+#%4E-ZMA5(g!JzSXCI^ue`lWl!yFC$g
zyICus*sO3#_koH}DZVs&*UeHw;8qEif8s=5D>|2Z1})qHJ~lD)Z5gy<=$==uTMUpS
z$Zwt at _R;grzna!>i}agaf8h0}AgCi+P*TgK6atsax^SRxe=iOR>;x|?4`-8vu}!Ck
zCIyk0<(_xGO$DX>K482nXQaoxcMO)MCobWxNp<Kc_-l{wUCep7TYhMgF#uY!{=Dc6
zzv!TfyGv=_tmwEne$FuQZ+Ph<Cm5q4_9{9o*6O^ZNZ}3ZSBCN1M?bZ%n`abMr|?Nw
zJz`)XRziUD4>1;PkTXb_N3_~Q at 7H*>{`0+^oxOb;rIkP>_+ursq&|YWsCd$rG#K}i
z7GD&}S=v8WYrkwqM at N?$SUS>8m at y^8xe4QZ%0T!!HrN0$uRr770LzW at n<V)}SNU9I
zIdLoErn#CQk6^shP3E`wR at ni@tZ|Q{b~fJaegKq{o)OCsY^hruPttNOsIq5Rzu02y
zOQI1oqMRl!78qE3e1{-UyGZ=sGrs~1lXz^uYYGSz7EWPX&<9l~Z~Uv&ORS9VE+ at U0
zMfmZ}Ks|Q`{4H$<C9B!w964&muMR}ONcyQBuL8NLrHRy>xRGM|nPw~5yhPT*HP32`
z*A~W0c57?jyp&|en;7x%l|qVg1ID8jOrf?;?hU)9!$mTZi`e>+7nb*#XGQuQYbR^2
z#PN_yUdO;Eo?5ZIeT(Asq~%iPti7)zkDb;i8&a7W)b{^W&ffr<j=NH)U at PWS-2*8n
z12fTw1ekLUg~hOD1aovv{TX at WETK#vQQ`yn5mr}%&76Kf*cb%y{+yKR3jp;SMyLx)
z>LM6rf_3q}4LrVg0Uzdx7%#Bsu`KbZOy;CRi1$*LauC2y?g40js at nz5A^-ox>b;+@
zlK7vVihqc9uyN5^q at 0wOn`}yKU&U1yVbC9k;3poC!(mYlmGs~*aOKifP@*6q*6r=-
z$jI4FjO{m6$H&|c^26i at HyXSAN{82OC5`w9t-tR9i<_>t5WpnM&%SZ|PkVIf;}2<;
zG3U_Ny^<8jMwrlbn>(+U3 at Gbkxv&i~>|<NqjC2h2XPo>Ih$;GGNt{ZU9c%KsbpBnc
zcI6r4(5uUKffiA0i-nxsq2x}RKyoVU(W!Tp+*+L73*oRi9f1RE-Q(Z at BJ2=v4U%hQ
z=|80+tLdBejO|ci4dLOHal`4|B(z12`sEVgTCsxmqN+oBV0c{Qb5qYBv&<8!I=exO
zV9r;=`W{*wHY)RQc7ubm{CSpt+;=W}R`@<}E4c~I6v=aDvA7}yuU6qa^Dc|l(ZJ3*
zT6PCK9}tJUvx<Pl;m6b2afwT%eW%`KN)7Hl(Y~BLqm8d>KZE)?yjJWL4=bOKy%Bb#
zE1(mBIUcyDh!)ha=pN{Lza8T~A6VW)YcxH|Hr5a>su(ENm@(4L_$tO2Mo<Xj#2USd
z2?%1oZr=8^aRrUaou-b|pW`Z0q`57nZrtf&@fjeKcIqZKT-QVlO2MQJhi-5U6<)g}
ziP>VepEnqe%a-%Jb}h%?e&kIFhoBs*i&l#>=^E&5RM78o$)zxe_v0?`c<ufVDnKPF
zSsljp at J*bQk2r;dK}3Hmp|aj<qQ|PaF<SfLKwAX31_>0jJ3xxw^{R3n*-oF=727~-
z5~{n?Q5WWHCF|uIvrRA5Wqv(fO4k3+G5D~()BMs2kRog*1xxQEIP%!dp#uScYF#AF
zrH?kM at FhmbU@sxu=wzlpH>^?iDL~^l1UaGby}7n#IrdA^lt0OF))11Z^NSBYq~_*M
zPPUcoLwkqr343#6NJR)E%S#+bW`5gWFHCp8zV&C!(==RtI)>zPiifmh at +JqS5H(xp
z=?EZVXt+cgwGE0USt+%vm#r-}&J*JhxNg1kxP20hhe`i+Pup#ZZz?yGXMdS89g`GU
zHmV*c);f<audh$9#zc+eSLzE?xI|c=?d;1!6L(ctM=bdZwft8GjD`=cswZ-!wN<AW
z3JugsiWg^?B=(5a)wy$I_SnmD7yK9e_WS?+#Q&tY)c=;k+p7t43~Mf_^BtJDV2Isi
zRy2hwW0$?Hk1nB`O_|yC<?EXuvZxYYPu^;e;}eLSJZP4XBdw at jzkfa&XFgU(f*tSt
z9`od|!O_hztCCh-a6GL?yD&+K<5l{r>Cn${zh|t{#TnEne1gRn)WhTLjLuy{j5vF{
z>6d@@r>5kI6mWTxV1&QUh$A%8Kt5j6DV+$w8a6yZ^8u||zcoAxm^<KRN|`i(o}6!8
zvQ37uXy?X6iNm8^+QGO-YAt{-em5T_l|dOc4AGTu;-i}b7kX|v^puQ%jKi$#S0jfR
z$q{D?w#GV#R9zl_bouJ6j;H5hT*;<WMxEL}oLZ*#3UTI6U;!B at q;k8ZV%v;cwokC{
z{8m+?<4OQhWcK|>jv^air9CjzWhn5AMVZW0{?l&Z!PB_d=ZQ`PeL9FLYtpTJR~W at 2
zrTY(zQ&L#jvAugUgPSX59pKAJUhJN4Yxl}{R9{d!OQFC9B<*TAh}U44zMB2Vqmb8j
znMP=H^KevOx=5;eAky_Cg*%Od7?(i$K9)h8Qqd^Sn|~#RQK}NPhBa>XL(c^MJm0Wv
ztPRbGi%;{rzuG$89vKO2NwF-yW?>kc99nf$eAwu+uOvb%e;|X2#a0Nsb&kx(A%zhi
znDRf1x|kqL*=uzz->%#(M;kTJf*upq{QkiXx52SK$1p{`)ZYVid`~w|Sb5$VE2ja?
zi5#{%@1m<Ej(rcXkfLzIb`c??Hro7eOHxDFh#i-%!YyLoj{9rEyOuQ?Odp+Gvvm^^
ztqH47fme>}Ow_0m*WTl$v2dL<;^EG4l(4Q(gTh}dUoNV3Z?Uf4sG~cF52nvjXO_~8
zNh27^Q_G!1bRwP)GD{AN&k9#Zv8rhB`W?#Wyn- at wd)6&0z}#x$bc}!NIA9vXM+&T4
zPG5DCSeoH%s3ma>7zlgj_ at x9EW1EZhbb@h?07&w9%uVeAA at Bys_B$~F6MzD#_7|@f
zX+XonrDuaNT82kk{wmk#r7#6Ne=o~u?0z?+I=;=I?BJQ1FM)zW77Z}7E&+-Tao^j2
z?PVS)sVmEo%HkGRna_MnUVh%*jaUDU*AYN;4JDb%`T^E7?_7a!*k~uU3Hji6h=P!J
zH!E5-M!soO?h6ItZ*tA~toD(P>n$s)L+sy&ByF=8Px%C98og=r8qeHsYZO;@o^wr0
zlr=AGwRP}p<rfbxN71=wtB~542`U|4lc>9_#ypA6m0cXRgMzB+>K42w0ihGLZ5T&f
zgX>av#hh2RS(uxrM*%fr4=~@2GvrZb`~yaj9uJ;KF-!Xj6V*J!{&PXXfMLq2tV-Hr
zH~|09qfv=?tLTXMPhw+onGM6tOSq+KKy`mrDpDGk2ecylb6&E-a6 at Gc>$}dS)sj7(
zad4me at VW7L!^g#&q_;@~a(q!7TTxB7nw%eQKm|+(8?tx{UT80}R$Xn*e`U4?SChap
z$|tG;-jjTBtz2s^_d`sbAC=zh8&vB1MUO6>&VDU=l<(-SmJ7R)Puoj^t=iovsWddL
zO734H3(qAE{D&<PL5Z9yuN2!&yTvf*A at PY>7O at X~|3DWa at 82NPq`_hc5%?RwH(><#
zmBWEsxh04g6*AY$jI$U}t)^??ch7O)Fc@#mo at Qlr`a?1wHY;If7hy~shw_0RMXqOV
z!(*k2(l`o1@#hEvV{VorteV3`5!%l!02wMrWvQ(UkGN0(!xaGmfs-YYj=@hNFS8Go
zV#aI#A5CW+)%5$maU`XNA5u^dRJuhJm>`OPbZ&Ha_a-1MqO`zhkQ%YUq#2A9P(ix8
zq+_EI5d6LUp7Zk@|IwrWydR$DzVGXGUAJdc4HOt>H()VL3{ywbp4R{jKV?B3%Oe_`
zrv4tdrB<qa$NKGofg#q#&;{E$;AvM4cD3+(Ri!6;>Rey3lF9RhnX2o#oWsGXSW2+e
z2z}fQYbr10{(&5)t=xO~sp~2)F#uwO(PAv6VLIGpNX$&P>@tW|nWs>0HpaGC=>vqT
znrfJ~IQWA2+}yb1Q-v*EnSC{{fSTPMcGA?WjeK*v7~$JEk*i&A?iPxz|9BiZtjTda
za+yDS+RiRl^Gt- at nG6>W<ZOI+MsDbDRv8l#z0pJDK2aWUjkR+VzisV?_T7gkD7GAP
zPN;ePG*r9_VkQt?onOKn67 at g}0(Xcbr4IP-wZf1S)|Z3sHL{rH57G_+cBaP&9V|pV
zCSkHk0qkU!ALHa(RWgFfXvN4MUPWZ93_Y97^XT?lQjKyxn_fUiYjHe*HQX&qTVFXb
z=F{FQ at sX2!SDqLlpU0 at w5tqxwa|1NyVmWbMmpLE;%YJByzUf$J68)u{c7r|63Ce8n
z$<@!OeIuV=qlA&KBMHA1{oIw{BF9_zQ^9DwZ{Frbp0oV7l8XKut8Z5WuMn;GLpM2b
zkDF!h2%e5esa90t*5tpi%O&^bb_=ABH+=1y5C1 at k(jSGH3vcUt=_BRD-z6=YG$5 at 6
z(1LhA<dn;F%Rh-L&pZqMh8k|l at Y^3S)4Z$3cCPkI3r_Z_EDuPYe_jF+#(RSRY3iPX
z&b7q~C^@hU;L2dCdveD5(nij{_t-)JtxQ2Wt0-)9K;R5p3$rQomGe?=Su#$k_^XT1
zo*h4w&UWl#zIYZ04VAdgvQ33mB<)hdX$n7pon at L_(o4HN3!Nicm6Nl$uYtZ^WVP-3
z<V)5)K at X$IWIG3_GC8K6A2F%l<Y(D0P=2R_3`J=M>7^;+6~4yda53^L at EQBmk@cla
z)4$%Ui1 at h;nujJg%p&a&fpi`c%PRkY)oL9a_eI<a>GSH-5d|WlzUlqjCBhS;7Okdy
zjW?y#?OV>09TMH%kSI}9y3JDO83Y*w<9O20+IL<l at h4F|b$3CeK$#@?&Fmm&)9iA3
z&Q*|Rg*@Fap!UftGfx-ZjtuI_4NS?!e#L~)O=w;rXQ7<1$>1fJJ80hG^Yf5a&&|_&
zU~$X~FcWlX_tZFS&hH1s1g_+8L)A>x%A3#Adz&L^#A7vzj_7qDf1RRn+L0iKHKqhK
z?qP;+on0O&^@0RUPGjIvn4Vro&5BS>9j8FIL4QX28#+N;yHbXdsUu#Q<EVu16U)F5
z-$(LG&F$dzg+eo5|MBp*lb6=XJ09aueleg^^M{geFZdGuwoT-ZQ^{+PbbGm#Idg7b
zq9%|SRd>vu+|`{Qu40o)R_NENY6WYV$Tku{EPWj)ADg)$ggzPpN!H^4jL{34z3G{I
zhPumdVP0~y0&<#z=Ei`JmjRv!+7G-lX9hSgVwDY+>=?(9;-dP3hXYDCSMS}s_u0#s
zX*e3JzUeH#mHFgg{xe}0Za*MVh*bc*81UT%phm6*iP;-K%6;1hDC at Tg=REi!Y|Ge7
zJB%<U{$fF-Yh{!Yp8jml3<MuDK}MG>Bx8RuCIikv*|UUu&s#runPuTAe2BcFtkta(
zx{(!&vS$OjT9Qy|3Nq`7{Ke~*#>Pf{iJEHTEd}&IvfAv=6t>EaIkyjFZ#pukYgnhu
z`-t_V1J=w5$h~jQtqm><g8 at es-`w+Q_4!(aLOee&- at iWHo0TY;CTdwi|Lroa=eVuv
zmg>CLVTFL^7Fnt!Ho{jz3yQ<*d7l0OpB>h<R?zRYKPeL?Ohj)_guV?jc~9;qSTj0B
z;A-lPbg`oNGm|mzoB8xyj at FXrqaWRZYzP2+oJ)hWXL`KXS0A_I2#5Qo-425xf!(wo
zeoA{VlX2MnXRm36+>o;eBWJJK|Ljo+Zh?9T!Aw$#^w=(+Gk5OR+K;`h9t73rl}W#v
zk{5;YhQ%)d+lREgfJf7r5x>RfI0_8Y at xX7s8%>u}9rIjg^JtYE`h1chze2eD<N&g}
zgsn%VMNiIe`@O)W5%P<J!dl#3w91{SR=_FpvmXd=P$afX+VMf{`faH2WUsu<X=UI^
zhq0R8BYAmYV3=Y;<2kRQ1N$qiNfltiCFulN_nWjl6v^o`5_1~qeT3u4c|Mnc`<z8u
z(SxfkV(Wy~&lVtZGR|FJJDJ?A7Hjme at JP!P30TaT4x$F=cD`~OGQ$^lDYDgEK8fo%
z$1^!7(gUWi-l-dvH9DMtT6!#jG at S1E4=$w)AZ2XR({2<1C+Dg+H_QrXxo3-1i at bAI
zPp7BvM!u~tHcepW+0*_27RWG@`C|4xz<6)od1u(at at ot~5rEZ;Cli9x73ajAF_f!G
zNPvCWkO;zdS||F#VxFHgRihuY`ko%Y1KURIUjH+$+Lz6k7 at +!$DsOWz!8g_TnM}0q
zkkMZQ9eWxv(c!+n@<HBo=SaGmzzefV#A;n+={bT^QIao+(={X~wv_p%LH=WHwrtZ^
zk`+5kTTcS*PV_^klombh%b2Oj(Y7?EDupPv$Vb^A5d(1*Pjh}bv^(y5S?p^DM{X2}
zW&N|K5&4gi`tK{K%UHpNv&{8LOD(nY&eXvOUOFD>>VWwl8W47;yh3O0U?oLfl=Zq2
z>_b}wrrvAqEH}keAhLD!MW`M1+dH#x=yK#d&ZR+ff(n}c!Pw|*A(nPzF=a6&pwuIF
z-5>eswxyugo=>%|;rV*<D0W+?*D7mBhL13F$T2T^c6KJZZc$Fu#G}Cs{wq<lR6!lb
z6&Dth5X~~>#9ZF91I?W1t(h;DjX*s;58mx!YKCE3b2)T7?ryqv56Ol^59e5wUg!r!
zliEW6V;Yt^ukj^!+enjmzjIe4f7ocw`bT>{rJ4iJr78M at eQe!JmumMLR=JFls&&cb
zG%b`ZzE7QAu=h2L=1DYfy9wC2J^zW<mc$UVNq$Xff&+?yCmOmT<1I%3sIZH=^;Do@
zMnV0BbKr?0b~+pHz;h;@>@XuhYdGb|DVcG_NW40cOq#H_YRvghT*XTnGPfIl!69tR
z1UDp_X$9()n9TugK(q+w%bg$a(Enj~som)_$WMJYCuDTsm++j`+a1?ZY-f$SR~Aqt
zg(s1{2}-ON%^~<|%tDf(|D^rjb#>5tkC4rRnl)I$^vO%2b}lE}BPgxg7U2cq7PL{B
z0S!G%`N*`Y8e}MGU|wo|Pe8ghdPU7^vk#T?%zcXqdRzARa%9!}r=%ZNC*m=;=ue8;
z>XpH4ayqwVRw;CT+q)mCNi`3e`V1m}2rW|SwGhkD7|_vDOi~@I^Q0)6dG24jjb{oO
zu9-)^82rG~f|#2a_YX7wlIQJPaai8FgYzr|pV`!Pb;^$lMQk`}i1JMbO(&Y!mF&>z
z<azcxbcn=vG;wf~EKT-VR<xrSc`JTwc=z|?B<L at mWQdh*uIDey@^ce9j8$zZ%GhD`
z3aI;W0)jz2cjV2|ikZHTbd%12mVx<5N<qU|ZYMqRYPu<S0JrO}vZW{6-x>0E%5Ii*
z2%|- at C7Uu&=#9Y#3%yR^S*^Qmks|s;4%cd0NEKiHx?0L~?STVZ(Bz2Xvj^KdOE~YA
z(hs~gc at obCe$@r8Np8!FSi*<e)>{Ui`C%vG(>^8+nwt<0IxZ^Th=)weOf{q%&gmG<
zLQpZ_)Jode^MU$>*gJrT-rj}UVA{Sln!c2to#S{)=wR2dj$_LCSzUvzd2?+7$`qWb
zd^Lwr82nCEe6z^qxGd~2sb~eXfy11?fK0Ws(s)Is6z80q`LO$!=0%Kj at hXh8E)JkS
zg73}&%~V%%Va-P{w0*a)2k at t|vu-%V-GBiqu*_2*S~Zsd0sN+Rn_^_|E(;0kci>1~
z1Dbjk;HzLkB`c4rM||U0Vs75sAEt0U`MI+vZ!>G|4sv*26fibg&{2@&3yP?(Ua>MD
z+`REwK+*o4eFymwvAcyP!bH`-tZ4w0BI`ou_SX!5BsJxxOdyaKl&ilcGcGnqePG(p
zjGxYQYxjAf=5=5RSNN$Yd|R7RH9(Vgq+G-(zqG5S$Agxr0b0Sxrmo(M++b=qZt-LH
zm^TTMWz~b;>R8fe802__af-;Zrh!e8dLy)+aABk~75;F1<A^<RtEzGKe3Fp at vix%p
zgb@>yI}&(`S{wh>GZ6ljR^Tb^YZ;#vOIL?e<JkS6z5TjTu7tNe{kc(-OMx?NhZj3*
zIwX2GV%Wvj-oich3<KJqD4{D0vvDqHa>rI1Ct<%B47^>kjgvcwB6^R;Z=z#Lm+X-Z
zHZmj3dqXo at I+@D(aF_5~78Ph at g`q4~!4HJWc5)Zy&@s45iDGLMBaEmGcquNZe8v*T
z;j^TATjOTGCR+8G25DGX5z7{_rfIr!`CRKs=3Y^%WkBa^v<~#(Id}%1vguP5#lahY
zl80g^p>xBsItSq^pqLzH$!>P$u()pK8{G=s>;e5#(@!*o;*F=0!ppn7j3k(EGJgC-
zK9R8yJ-mDV_z7?#w$*AJ3Zy=;r>=k)sJ)^Xtz))$UIHVK4GFTD-$unRfw^AMJnhC{
zgMlXdX093U+`)q6-qib#X^K;$eYgTXfm%R#kemEEw$cGi{zZ~AoXZKf9y{{8m3)pE
zzxJY}ka_0WU%eXKYh$4{Ow>&B>TELXHsZ6f#_lcuGOnEuQrVIVc}!7mVl1)akpiVs
z+7-sJ^URH1huS+0+Pr~+cT@@ZqjD;fx~U`9AOD8 at F$zZ7zRq?cM87u%$lf@<t~scj
ze1rLxkPJGNF6;2%-UoKbH=Z=_z(34C^coB~EOYVMrg6Jp(>Ci<Y0Rr!*SYeZwK at C$
zS%AYf^ycHGN_g$%R8!3b-}8m&rHS+QggM(Sr%QKk!3sybym#t%s-Fu^{$<cOv>X6v
z*$#ybf+kdjt5HR^UljIvMlTm2<4+UOw(G<fot>TCVJ(+vt(38v{!dfOW%3_TF6a>z
ziu0|K&$%{f+wXS7-1_%&rdSOfko4y`hc9ZJdH?MeK`2Tq<c%X;*A at Y$*EaOW$*$|r
zY3N}Ohv`83&0NWBAz6jWh8Aoz&a8><o}8&K;pby9ygR{Fi*L6&h#xIqsb|3}h#y#%
z619wKC+*P065bFtetl06y<1E15S9p5TfQXt3CMH(Y?s_LYF?a|@e<8q<P)oETWoCs
zs_Fbz$sSvZz?_|_i`tiMnxAvVZ?w;+0kfHP2K;6V at PUC(n|p>wO<in2ysC4`mqCyb
zU~<QdFLEWYXNgVMB~m$Tpa7<{^Wm*vYIw>84&S^DUjecIqL}%6vGc`YZW(?vlU*Gy
zr<k|H0d;(tPzLn-zjf!hsM|^H9G3o7bmAeOubA;e#vQf+>_;o{+`-H?vwPD0IZ%Yp
zqF{@QxYFFRX%l$|aQrvwB&30xGX2MCf@{SJNcpKyv0w1dm2<^MzrrEj+GTPz%|KuE
zjLzLC->BW|bzsLtp5s~wor1qn|1Wj at zG{d(zeVsQXFu at 1I5!jrnRrrX^Vm|eN!S?M
zxwdzxHdXj-S$IEYCx(kPbygwnBc7UTo2q<=5I-%i2Ppi`s2EpxgaKmEmuR?ah|1Ez
z()m5|S%HKE$iGn<rQ}fkIM0E;A at 5<_&m}vi$+)tY2@!+d4dXuzeCD0C(5i>;*_&$+
zLS|LpEKq4<ve<2hU(JG%g7bENlV$8qjNFewUSXlm?oc~P8-~2;e(wR5#$9g=@<|V&
zUPkZZR0|9D^QWuZG~@CrWtKtL^?Pn{Ca#q$g1 at yPTKN?H>*~ZUgsYs+8Y-o!3KUT^
z at tqOc(`Qg&$;NV)$hViOyQ<=eRLHER_umH$__)l-p3+%5Xr7({tOd(~&yJ2o=Edgk
z_#8r|nvv>JDaXkCaeH-O>j`hv!mFXLiA*jIs*f|6iNGH9x62Pc=LO}p*K`}A{t%KV
zaCywP$h!piv at NjxXc|)?4g*Q2$wxyD^rDgdtknZ%sr7>R-xnu4M-DMy)s8yLqPNXe
zvp({3`7*XwhCnS%|N5-Xx%ouG|ClY+eb30#DEltn6YB49_KpO0nr3Yd4$CZZp5R+k
zo8z*qb!ptF$Cw()qUI}pV^`fGDHxh^0W?}MYmS76lP5{gKHF0niP2ydMvZrQZ>%Iq
z9rSvBCkk>{%9aJBDrUe3rux(GGf+cKiogWxjMT?6npfhPN>h%_)o(dOgS$o$hN&a<
zaB20HAY6-MfzX73=H>kiCol$7<^JyQ8Q5Z!(}W6I1Ah^b)w`V}+QH>;ua{ZAMfMxl
z)BW^4 at avMk>^$}DY@^*$tKL7;&b2wNm3u<bh>s(W%N<Q5?|yh%iD0$?8w#Y%9Ids?
ztR#zY`nh&2lGx=WuxYyGr;2RU$$01vtgA50D<Bsbh~JH7p0drHo`gCl=^RNh_(rX(
zem~r=$?<rZ at 1TWax|k{bQzyAc)Ee4NRZ#ooV%<>u>A@$S&4o|j);czgrOODAi^<+y
z;+Bu2>(Z+OY(ivC=v03(97r>mN!0{=Y!3Hhc#WtR_{vFEK)>b(hR3(BL`q0<e3cWN
zOmL~@;KDx$nIJ*GcZRlTgsN(Yd1*sOrwm2O$|Cn>dRZ4Y$|cs8gCFV0srZ6zo-XN&
zBcku?gC?w#4~pks-$0qU*;%A%Q^&>)M{`PTlsTu90om>9BH0>=E894;r|l97e)Y+s
z$+cCm`$%cyQt5tLRTuFC!62o3alj2>_GnVcDF7xcqX+qT;4+R^{X$m at zPG&J;?V0E
zRq%{C9<WdF2lF`B$?dnW7S6lC24cXPt*V&uWp*a9Zc}qThqrMKg(s~5`2$BWZ?j5<
zKJ&xzlmqW5TeA2Z@!3H8z%4W29`n{pk!9!{E&l<;D)ezz==7PBE7-i%kQ27O;>9W`
zLYbi5bTAMav>{QO0q}^ryV2m&OVP1D<6$_7boTn-1 at dPlnb&}p5H)0AoMu)vGAg1c
zj8oCQ3c=o15`RkFZvR!}C0d%tR<$_*t0k=zyaF(=WJ6~QcMXs2V(oPs{GR4 at 6oc^2
zJ7^iZ$RQ2eaJw_>vvqAJI(`Oazbp3pLVw{*%;Qlr`G@=e?T$ax>>wQ%p$SKX`d*`+
z>4W(Z)+yW8XalW#+!-hIrT!KgGrLk3&*@|%K1pz0#N573w!zU1BV)IOG{HJvG2LGq
zoL7S&y`E3w(^fb?l$%zPV+KgFj}K*6WdiNfz9622#Z`63XCE%18VxHD_DBavj99=u
zCYm3Gn67e)tjN0zoovqTap{g|nWC{hyrOd+J7bG+y at ML%kaC`c_P~|VO&u|L6-&BH
z9V>Kc1O8o9VT~m$hIF?LAiHYlzMuZK&LRWRK?XDMzq&bCX$G2E6`(JeYvCT5>MB-y
zyR+7|WXiFW8mW8c##T(W(prv_-!bp1CRaYlm#`~e85D^zxn}hNrkceKBLI*d at MeTN
z>Nk-VU<=!;y)@^lF4^#voSvC*1~?z@?%ZsToc#8+b^gL5&|k2gz86OfzcqzdluL7T
z65 at lLUlcIA84w1D3>bVjB{%6;+>_ELf`$`!RLG;N0QtQ03edw=a2Td(AWCe*05DFh
z)&a1(-{Faxu1ZyL2k;Oj?M&3GtOsk7e;5n2$@H2ghAL~$3GTeZZ=4dUnQC7<an1St
z3AZnvkr&hm{A6MpU^w>BB}%71Kjn7qcFn{{dj!dWy+cK8W{<nnm}*<zi>6oo94@!&
z9V$_C%<*@x$yhdQWo#_9Yr8js1WGo-5lOn=ZNV>et&2N6#A-*@v^THcew>ui(+w`a
zbu-<d+r&WmdAPR=g)<y*C6qfMmL>#xat9}%L9yyXeZO}OXP5sDCy>TNt(hNB2;U-o
zBPEp#ak6!ifNDWhYmD6|2i{el8Td~N1o8n(GCLP*W-Bx3kuf`wg)aNSgB!x0iOf}g
z<*}8a6I?zW`D}k;WHoL!0M$)y?ic?X|EjNW;xQK=p3d}w+*T$loD|6`LC>lAIiD~0
z<HsVrac9}+?J?;%W+nmd3eNB&`H|t&bdP(?u}1n{W`qTbiM!qnSyl&yN2IzOXZ}?0
z`93;RXqjKNH>xT%_5GaXxGMZg4pLB4(0$(!t>O0}?WdWZc?<{WZ-byYQVMDHln#r%
z26$50z*ED at E%o=R@;kX$W$-JZ9}9AUfVyPKg?&Gxl4Oj0I%qFn<ee6@>>#P6mLY)G
z7MaQjA7%oW;@xNG9CO33j79mqzEe>E^+seY1AgeC_n<4g+^><-MCXqnOM>*xISqTE
zApnz}x(4Rg(K>I*6A}^z={E|;fD1*p01(q%bb!?7mNyQce%#hW)nOI<{{oULP9OLW
zk7_mQ-$&(W0RPao at v+Km0H0$2O2MV#mx2MMz}(|NlUHbC_m;0vnp<~fxb*}8ui@?L
z%eTWBjY?WmF&Jtr^<t_wMYL%jNFF9uozw;S>2=hLfOQJon;EQOciBhuE+rnQKV-Ru
z6yAJ=>$X8|Fz(XMK`m*mp=W5{@q7z(jP6a}vx-X;Nw4>vv>#F)*5C7cy*UJUdt(Q^
z=Ju{~&M<=YV?{w}X2cE}yBNOY%^-u^ae0r(c>$lOT}HA>$@z}&7qz$hXc<9 at 6CN++
zf)TG&sp+2?ugx8$c#rr!b?Rn&C-b1Px7s(6*!!$ZrMcZEOkdtB^DoL%sVrtMpmrPi
zRR?zq*g)4#b^osCSw?Mm-Q^69erUGrZmC3-LD at G+E4U)3HLxEyVA4G7O;A`-C_j4k
z#BBu!*KV!OQF;OVJPJIoAF48XMQ5uKay8v;GFfW>V at E*fQw^UsSquNlG(T9nO%3cz
zaC%viX^TS;E1`es8j?!2e%6~DeP=9LMqGR0RPktg<2DXSiq9ESD;n&=0xs{QXaUc0
zk}_fm-his^+!fIIdGLhOywqQSe1G!|5$+oMXt}C$#|Uz_aOZ7uYc)fC)RUOz)p?N8
z+K?nSKz-i&U~FopJP;4Sfcc^AQ&JwwAl%E|>>W8#{N|e%4AsmFLYe78|D5hiApVLy
z9w4g4<Pe|(KLDMU1M&gww>>~04N8m#o8nFm(PbL|;oKeZh&WaSI5(F*zD5q42!)0Z
zg5-dEklNGa=<mg3n|p9MW4-_-$f at F@Ot%ZjGBAJRU0Pci_JpNI-qvUu)R+9Y$Sf8r
z*<@H>MIaDF$MQ)h(8Q(h3wvY2jsT at wbY@U8+B>n5B({)9WfFCs#F(b4>mlCr;5f95
zO;=F7WN_v(<7T*}_DqU`jdv)LHMQPGu~i`n##X+K54!zqW~8F*SFrnz at +ivXTMU$s
z`BfUxwp)#)$UdfMh1_5HMxskADyI4ujDS+I3v3NIfNBN>liQ3ZrQr25^|;96%n+~K
z#Sq~IPLrFo-m9{V<zFY{VFV|_9Mz}wAO!jI{)N4q_*U$4$cqFF{?a`xPbJLk2Kv}M
z<Vt*--s8k+a2{^lK^!(Qfw#XsVV5}Kk|sZDc4c<=hr!pDr7 at AD8XuqK(<TGjCuIO(
z<R|HL<d376l-6q+?XnsiEV7sx8Hfo-aICUXWcnJr<+7OvnFag~gi(^#4?_05>P!Cw
z-I(N8QX`;slPO1Xhfkf(55pZ9yvuTR-^UI!W9R+`;z4&rb2FcrSTaiN9>osl?sT)O
z$?Y+VV5BV|fM5Js6{FH35PERa5UgNr5U?@g8HGygW{+V<)d(*O;2mQ{DjRS+Gik&R
z at ue9RwKW4gyTSU@zJp&Jjh7QKPUsD}OP+rhQH>lsu(RxkXJV40^2<OnaFksNK!pj}
zmhLx7x~u>W<0%KjcJn#BP+H#NeIu_Z7_+c%FW at 6xmYfsMwz?7E0uZNMcmt>UnjSl<
zx+wsAp393APhQW;%2NBBAzbwLGUP9zAJA`(^4EbtZYjjm?Bpso{+2xBF%!;v&x4zX
zQbPbU;u7^~s5s~5UvZJOp8b(-zO`4fM?vqI%*TWDH^e%O+98#eqDChvLGP2w*nT;g
z8*GgG1(UBB#O)GgM3gbTEd7{&N8#L#ffNyz>1kN!`Qs<7dMuaw4RXbZzf`k{KG%Do
z#C}3EXHocfc0n)E;_B^&4CdN;dv)E_I8_QA!lGYYyPci0ORwL3GIa&R#x3eMlH#L3
zyUr at Sib(u_nPrKgMaHI++23Kpy2;L`3Z0}}?7yyFA64qC_>b|D<bf7ogc&0rx9J5I
zUq4}$ZgKu2BJH;?8(lQ)&S)Tds27zI26Cc;$je-|BZ&4_&63*Ypot##79VgXhuSAp
zzAZx|cPt4I+MU3H+2`%lFhe88CJpuE8fzYL9CM_j$oGODSIn{@q9LC-!O>b;T2KG}
z{{CEqUfSVi?1tLc-8cO7OEm`JwU65Ml&bGLZCIZ@;2eDwFy~Eo*3>cE0WJ%Nz~=7%
zVnpdLq at YT8_3b)^`Bd7<X=)xLAZL>w{p_s|^yb7lccf)41rX)$Lzu$=k9yf1yl3mm
zJ0NQbI1$H3)eO*kOjqIhVM(WU at cyFG-k6yGP~E~W0IqAGFyn(GrgXQByyE&nu^^fA
z*#k2pbV5)u)~5Xw$b?cVkfnnfas-2yL1f;5Gr6a(JC+ChZEJb?A9NYAKnXXbVFN8(
zI6HKOulF!cz3dz)=I#eH)3dEVsgx>SQDpJ)6u*UF!nn`O`)o1H&!04G_&=(%oTf67
zz<r_4%y3hhg at NVY-a^M_>qo1z^%Wqq%OPzV^;C`So8A`l$A?7?tmuc<WX^Oz#0!2M
z2nAc=c9Yl(otVFPY+ClT`$=53Ig^z0&CPJ11A#(pq(R6%C#a-pd31u?kMJvD8g5dJ
zccgQwA-&&gaYY%ak80)M3{+Pd#$KW<-gBySsbRDv31(rcq$ZNP*<s^l6=9(Ff+j{x
zMK{ud21C<1hwHY>-&4f)i~>W6?j?7 at Fm_b-WW4(>xCkb{<09c{Cs{H6pWqroecp#v
zej!M35j7cceG}NJ?es#I+?nRh;cZ8Q;pI6<E9 at 3wK9})mM#pn+qUBA<x;)w}0pnE0
z4ZcbHLsb=CI%Y)oMME{~C5a?w*7yFNo)*<8-d}Z4XbwebQ_9CQriCvSZ3}-+XFXWh
zNxux*s#`iw&gAcf#lk=u)iQd8P8Ly@!t&U(c{Ld6v0anW&d_BK%AuvMJU3uM<%>{v
zV7unl_Nb-D9+iv>@BSexAprV1<&nWfipY-cd;MwC6#<0Ct-`tTLFKt+)@QN0$aa_N
z%5L^RI52ww=)gb#FEmi`MH~xAp5xTg)gL!J0cvDWl#8bzauW02A$h|Z*J$DZ6wkUv
zK+%-l^q6Vg at qST5>a_@<b{z^o at v{I5A&s{v>w0)S(BC at IZw$<Q1n;KT)vRU!k15vS
zpVzsc&;&p|$B;Ro6ax6%3)8$~bIfvlKi+M^I3Y)z8m7bue_g>0HxzryW5BotSadE4
zZG$6y&}t}cCDYb^Zby#*+P9Q=0^%`CKk2K>74Aay`lmJ0|7H=ob;3DpTmUB$oaRgE
zpy at 2OMJ&sjP3gRoDzIpwiOpLt+FpO3^kw%?0!7MUF$u5Q{j=S2Ph&;?wC3%{YY`W*
zDNv!o>1`;xkIVY`zigYq0KV?&I*6QSH|w$RjKopPY3T7Zl;>>qg;j$+MN=3`p at TyN
z{b7b)G-_61HblT~6D%uTcj+T=@n-5WUck!@Qs)+I2hljxy6aDeXnNN0MvRk}TYdC9
zOiqjByWE}6`FSU+a-x=F&yl)Sc-drk2A|1`Bps(mkbLz0xIr}=iSzD5ELe2aFGIWZ
z=H^?gep6(8j?@_Lbar;ufh|3!9H#y at K@!5`dOV}0xx^$jUFWDjx!scUEo{MzfEtCe
z#`RB5)V{nMo%33yc88POb<s+Baz}5uim1E5D0vERaieCw8TPQKy(||gKTtX$nf=86
z#3;w!s+*l>h1bVAQl^WYiLyG&cur^9-eDBOFFLViej?2vhU4CQh%2TD26T6)9snzR
z+|9o5xrUXjUl5c&1yIE`EgB;Foi&D2(sH<OHk4BFoOnKoRa-J0vhHu~4FGjKsPe-5
zv&85c5Z2ra{0@*yql(X7XV72+N7(<Dx1GbRmZNjfhI|+UzT4YyzI4V2Kb`}^IrIC~
zVzL2+#E$Q-hJ+SLAP?iuboQ~sP~R%wn-{B+c at JFH_Q*}|zHAU&Z8OObbDH96rZxMV
z=6s!YxGW3NYPQ$lC`RAU^iw4}B+~x7Nc!5+NUyfH8uYGgZNWK at 8WXX@&Ql+`b(FSZ
zcT&h$5f(@GAo&$ZKFOde7k)n#H0Jy&P7_ at 2VySnHJ?xXb;dca?XzIkDQ0mTHK2+t(
zGh^!RU6r>c3_292E7^TVWTmLChZaRuhs{n at xu}WNND31rEjY|Bl2kNZaLDy08gu}8
z)-dxKt6G7H8zHp!D^d`G7}d1ASC*CW%M<aGufxhYgj;{^DRPU=8(h5Hl}>YqOgn`6
zZ%8(O106i!e=;C)Al9J+H8%H4{t)zKWZduS39#-CWt<z>_nR;8%*S*QeOo}6Q+o%9
zKbTTeMt8ZzP=&KFNR00lX{5gr85qCU3ol at FE5qvk++EFht+JDnX=k at kQ>l1AEMjp(
zsC%rdTvZJ`o4ISM!5w5ax=`ZPWTr=b19GmL_k!{_P at sgK0G1Y=MBtO6 at _;ZMeW13<
zt}_|2F2Z(ZkRykbx5N*C7bw{(Unw>B2EH5C2ZUkn{FDUdz~5wmvttc&SpY7DVu11L
zBOkQ;JNp^XD?cm>WoNuIS#{I}ZVgwB7;x+zTs%M(bKzyN3cdA|-zec at y<b_SWt&YE
zV7D4Hk3~|Xe+6R&`kNJTOWSHDiYrCHOn3-{H9>rOx;>|{c5A$pxmFe^z-h*e#LtM5
zU3RRQX+YVxf3uX+wpP?iY0tJ9aM>cV-G1wQd~8u|X2#-{{Hf(wr(*XHmer4r<quy2
zn0J|MRu5d2OC(~yQA+xLyOc0^ciSCNvQ*b9!%G!u6cX1_6o_?K^++CVTiUYX%fai*
z^3A)SodLlBz8cJPu`llj{aRjLE|A^vGt}^XV?Le$!ci?SmqWbETpE`qNgM{@l-I-=
zj}UEFr?Zg at e<yOsC)i4j4&dfR-$G*;ygg?9=W2cfsN_-WY-Z(;;pjr5*S%REYs9+-
zP-ZbOM_0gk-Lzwj$P8!aS0AX^-2iyYH#&QDSq%yUot;4j0vZf287d$=O!uoQts}K9
ziU6lFi<ubzJKR10iJ0%qal6?93oF4DFVl}{=+rtwy at yP+bls2xDkRTz#^0KgoZ?wF
z%E<F1E9ThTZ?ww_(00D7b-;WKoxkUBD*z;@CHzL;?#Hx1RFp}F1$V1r^|!^V43{^N
zQ9uh!IDd at RovZp?Q?&kS>$Dt5IIU%{?enZK<OAk(Z~r2l`Ae-SFxXc>MX_7{ixU1=
zoDneGDLDZrWP_ja<}G+E>*3-GXlw4mu;=aVmNDy>g9R(`%=evd&$vfC`W+y^1lKS9
zy6S}erH{q*&X at I6*2!4q@;uB9>1O{Inu5l5*8MwI27+JkcTK#MHN>>GV+YVN;Cc=v
ztKi`bC+eRx*o at i=(eqqTxSzyr*Sp4o4k5=S2X`Ud!<0}<o1y(mGbQ6RgNRUtQ)sbE
zfYVNuC3MmVr@*_INY?57`>FCVkjuLW_>5)Yu6<u+H&6B}1Mb at m;y;|}O4dUy8(yGR
ztlAkFsZ41x;fPF0X<l(oE+)kxXy#n-r0rB3Axy7R;2e+9!MO at N+1pU3saR51RNJr8
z5Hy^7Keq at 8xY+m{5`2A^pQ*xhS2}J)r#CJN!IVM<C7E?<AAdDVI%F%)l+C>Zezr@`
z%6XD!yyU$ULhv74A5+wgRMK=aA$*HAi}95?>%}+9Po2kudIE!B-1>TtdK!W-+V2&a
z9DH|&das at iQQs=chW5A(?ykOa>w`+WKif{u|Ah(M!Sxzk9J%H|=SxRsF7Hx1A_<MW
zKerZZG8wQd_hB;vmvflRz~HlAaz at V<IL_u at x6sQ|A8NiYgo;*VHo><eAWvR7fYn}9
zFWE%pZEF+fFcTqRZ?r~sioW`-qjcK}>kU7;%?bLn<Dp*4f9E%LGtBd;aFHN2LH&J>
zIj&pm`2B3{uYY8LjRG~YIwk)uo_61}nSln>M<B+~-x&Fv!HJr2C0;;sMg=jjE0n90
z4&bBL)BZN}E=krUDxqe1&FQY$LiogZi=!!E<U9N!+7 at Wt#b8Fwrd+SOC6a?aZ(X|+
z<Rf~6;;X8K@~rBXC6!+bR0C41<xjDJkJci%wSS&@pHF>n#7f_eayG_PSMW)q$$i%1
zQj<KLc^gJXmuJXjOuq0c(#&2ElOeeqjC{@gYK+-k?I1)3jbJ*}7qt<a(6WZAxxRke
zpenZ*HqIa=VoSOnU?=GB0m|RkyV`q=M#Fw$6Voi8jSx^$`uc4aPj*$zw;+D at +1md(
zo`9czi8t=!-z8_c6i90B^q?Z#d|u><bb*J!w?Z-*{;M=vOG;hdnDi)!ig1|}0p!4Y
z7O!1rPYItP)-?;1+wIiByS;wynoJBa)F*H;73SB!Ih-e^q^hX$EE|*XBhQO$WlDE4
zTi2~Is+wC&pbeQX#U#ITP54Qn{6J|gg3rJFzHHMGKW+nF^9zH?s-AdV;l5~jT|6vo
z!SeTO7Rn7KFnkFKln-sb%)DDxyNDvt{BCNkFgHKi<BwD1X!0o-xuF#-uy#C4yYE0@
z$~fwYsSdW(P)C-(sTVHRe^Ew`yl$*f$sH$_kLpw=VNQpR7)LK)oZ5@^tG<E4CPKo&
zZ_i*V#|8fa*;4*I1v1{^&Q{`K+}-T>Js at wr6;}+ at tQz<jaCA?7T27<qUs|{j*I{$D
z;T~HRy7G3JR3y6tf=f`x{gC%}16BZ8Gx1+83s6w})5Ea89+CoX7L5Pk#fT-Y7@#3A
z{Uw0y*Km`W;iKq61Xw6H-IoPE7LLR!G;4cQQh&~1pF+6oawf{LK%b+b+~2G2Uer5O
zr0e^HKo$p*UA^>4<*(ct8`(#y1wC~=Zqr(de(ObzPYBza9J?%D(31)LYq9^~@BMpw
zdp=<Ec8~E<A~yqMkCGW?Uj5E7I^hTN(Bu~j(WGq19q?m==&;b*YpR`xd(#zEZ3^R^
z_)NpF?0_hBH at Z9f6^B~U!yRDh8H7Y?iF0_Jq+60lWU;f7F0qzUq(xhBkkxHII&+3v
zxu|+SM7yMpbQy%U=u+ggZ!MG%s(qjd_gsv$JOYl)Q@{i`7;p}wo{z#<_50=UJNxzB
z{zZr{^ax!DWbOYxphg>vyo2QkvJX$C{i3QeQ&T>T`t0z%W_<rb<94#?o#bg>x?J*k
z<PUvmuf_Q=n=_k at K-H2R?Jes{#{UQ=8G2Vrt3TAlpYWtVe68jevRAV=wG}cvfbee7
z{m<nGEHLo0xfreuKC8JZG*oUpso<lso>43-C`w5RYF$u3#%GRY_g(yHWfnfWKFxp;
zul-Gnu6<K5n2}Q5RNtW2>ht~gjO|bjP_u52|3h9lu3pCems<fO&~C;edb&uzq^<ow
z3!u`oB|MkE6l#_OkW)og&w&7b7!mTtMCq`DKRvw^Q==&mz7(Z001Q#g8pyOKYbDGs
z7lMjiE`UD}d^Ii!_Rcw~`OS&nEPvx*R`hj(dRth?OlEH(i}1DX`E%hI3gaNx`Hx@$
zkNK87eXKJq=xI!UAjJwfe|WN^C_eE&9i7OSujkMIo)7*#0@|Fm+sv*FFH{ZvD?xqI
zMUcWT(bR_LrOGkcN4=wN3jad0*Bcgt1IZ<IX;8RDqhtUKct*m&l1dRf9uApou!Jx5
zTqZa0PkKOf<7UeBU54rd4eZ~DYT7(WM%1g*=E)60wwo8pqMX(Q2_{D+sxfSQ6)-e)
zTZEF+KzK95{*(Rk%m%pjjrRdFyGCPnv!M4;Z5^)@Yh1uO%BBy%SQ)7~*1MCwjo)#>
zYcB=iO*^_}s&T)8UL@;ZE#WJL);lpZT$&NvoXDk&sSOi2;A?RovA$pIlpYlo`~X^D
zBEFMf8F=e;zz6iLhAVM?<tVdxi@=h=+#myDe9ua5sXMzXW2um)QPphb!bR%6Imtk_
zP~pirsyZ*d9!ucyYgPU3IEhSQqpMIIHJ0>v>5&HMmT8>!9!&dVaB5yf!BkO?$<{hr
z((fHZ75xbwKT!8xi%AH#hY#Ql$lMtlH*4l*+|Cqathw9g3!yqeU!MQ{b5ui at N$8C}
zSo!Pp0XwjV<2j3w(<e at d9>yk+IRfY&@z?NOAk{?w#u8AN3<CklZ-KCv_0bY7QQ#43
zz;*_`0TNQ27G*rIZLv1&D!@y6U-jgOW=;;ZQY3!?40Bf=)%ovd?6GNipB!O_yUyN$
zi%6hXr|-Z#C$2i>=2in!nd$-Vq9STFu4h;8z?#lcm}O>*oTER$E`mlN(Y^kI{q97R
zgWTJHT{aK557q{S!298(d8X9l--F*b)<+d>2o8Jb3{Mx{10q|v`}<C-o;^2lAOk@?
zO>N0r?Y==stBjq-drxce^Wh+h%D4U^b0|@oN|U|K{H0}pgIRfOXdE{G^NfRLp+1p1
z*R-_a*=s$1L$3~faWtsAm4uEOc`)~biO%t4w!Mfl!)+CWYWj%AwYtY76{5cVP6!)~
z at XGR#V1<d2vZ5YrAs>fO$tsy1&4vcnQ)dVAQt#@assp%x&*kfSmZT6QZ`_zgk<$ke
zZ~K}?hy7XVRm5!wWKAtK<mnr&V8UQ8sM0Iw>Fz!m!m;E~jHG<=d4Q2sq|_YQ;<(V|
zbD^2=e^z$y at CyDK_csk|D#3qpYh=}D(E3c2yT`K4f%o1b#@2yPCfnVvuTh8svIk`?
zftS`&wWfz`KlTNwCkhe4-JtBHhl_ZAn~2CrT}fk=39*`i1KC1NYgS!ebtu^-rj9KQ
zbGgzas64;Ol45?OT}{2tYMotso4?}6N~a9wa=QB-!GLDzNQ?u*<mI9k5_{uZz^$yd
z<ibE!`ZTATT at aT0${wI)<VwO;fwu*+02H!ktv)Js>HG7lcj_WUlYwShMd$F9k)%Bf
z+|aY!^ypeMhNLAp8k|D5D4VGckO~rUKyMwxAZb4*WAO|#b`D%nN3WYIv4!?Obrpnp
zqQRsDKxm-mjP6zcNB|;AKefM{n3(%GVINBm-*pA{)fnn at Hh=XoJBVhpRoj6O^&YK9
zKCVgfay!XIy*p$j18)}yY8iI_2OzSGVe7&G>e6{OzsU=U3iz0kR9F6+jd$>pp?QMa
z*gfb*I`K_*tcc`G%YSz>O(L?8{}$&}slvQ>-ux6YxctPFDtafcv!2#bO+diQW$6%1
z<tbSR*z0JF_ at 7fy2tFuPP1r&C&>h0i&?1lT0`=pQ9z_3TPw+QF=%XNr+1lubl?Gwo
zo?9$Q3{kd&vF-?%+p(&lOuBHC(et7`f+|6v&c$H_({~-*lMZ>g at r|Ywd3VdE(q)=s
z#%lP~KPpYw-B1|jp$}18yv=_TYKRocewF|u@`H7NN^4t~ACo5P`jz7+<*VrbH2uUu
z_jcLz<`u4S6ln2R0jXxW7fVxQPCBLEoOMAhTGULxei&?NC9hRDIjq;WX)rRv6G5x+
zo*Ii?)_I-0ox7jK$Ga4`K0 at A~1<gFTnFJ2xaV)Pwt=tkA_pg5f+ot4cKg~{25alZi
z>Kve(rk;<PF9BTFu9FFhA%M6vm<semVcCGDtmQ)s-&8nd#&2fgX+DZ;@2*c5R4=#U
zB5#H?C|ugyyluh5#tE6- at GLmQX9~Y!glF5=3-Uca@|j$oh*V0m{wPqy4Brh#a;06j
zz=hF8k&ulqwdBBu7fWp*k)3m}b|>D=o(zcrqa5wiy0APF_5?r-7{-dw!n!f$E({Yu
zaOr!ChY~L0GL<FjpDBKjGc^o>X#(N!Gt={{f8P2JGa3Ug#yD4FDrZEd+{Ue98n;<=
z-N^4MNq$<WbzbeUDC|Uv6v4#n`2Z<c1k at O0f1UuPnVI=4SUz5T<&WGcir)>b#M!qu
z+(%~Wv+Nqrc=u{W5K62LMlDepenB36m2Tn&WEGl(H2?wwTDB2^$o8|QI?+65maTt-
zU?3kX!>9SAzH5N%hX6sP|E`n{kb7uD at ssZpJ|p_2W4(-}^~TGkseI?p2qJl+7Rl at L
zqm2hly5^Nj=cMnLf)bB}k!~s<qqeUXHnzE1H(D2GGoiA|Mw6;fsHxBcx at 7|c4}WmG
zPrmfro-^(S7qR%=oaw~Qla>YWAWdeQ!~;W{4C;gBf-Zdjiy{|$!m`vVcCdeaQd7Dz
z5lsz@`3J>+ZWx5>$k(%qppi^;V#^0|vI_dv|Kfm&@~N_JGHazwxa3fwPrp at -gldI|
zApIQ{7e1RSF2KQ$5jMg(IL_&=WzvU`V?B+2&8|1Up?G1j+xJif_DP%{ygV|A;vNu&
z8VCU+yH9~%|HcB;=ntQRFSh<o$P12inzb`iiE7x>{2sOd)Sh<q8yCCx<3K-TUaqAD
z>0u_c0TshsPu&~TV^3Ot<PA_tYLmg7m82P}-28#AA&`wdF*ST05(dt!WW&L(cx!yS
z<D8*;>UvjtGBJW^z=*oP!4BEa?PC9z&Q{MYmV4HB^mg~p7i{NefU44^0)~W>-Rw^&
zogH0?gN#R+W%jb=o;@>N0y6|KpxgdlUp~svnb7blV{eC^7`PphuXPwrmv$|h|8TrL
zTML$2>#ASzLb+-vm{A(8B~&Qwah$l{lKPyKLFU0txcG{EvnN01sG0aEl#c~E{oH?^
z;~_bj{{cFW_O0RcnWq^U^m7*EkAVLE@$vB=Ie4Nb!df9~#FO-IX5?PRu76G}`m~Qx
zJ<+>5 at E#wl{8oE@#5%QZRtzekFUd1G7YJW#o9eo3^}fofo8}Ue$?9y6*4oTA`^%JU
z#O^Ej1^u?px0$SzyU%PC!elI8?fsPZ0&0S=EzhblJ&_v>1Id;?b95Cpxb_>o?u?>)
z`cE4gv<NVX`#r-hc4IcoayDe=@6R+*mOrbi_Pt!@BPF+9X$+pW#)-x_onTp!{Y5`e
z2p_Vw)P$t5<$klj*o#)5s1I4C!u4S4trz-=vJ?juR4_3teRa6ajRB`kvtPK8XnlPY
z at 4M=~IB63FT{hCUf$LD*2~ADXRJ4r)y}Bmk<|AfUu}aT$00S%C-ovegn!nIIWuKRW
zW3rdr+}}vKCj^OXzWS>QKth~d;ps-s8Q8)DcLyz-ejtDLAXvN!+sRsb0j5mV0v4bn
zm>vr|mhJP**Y&9M69?5}js&K2QjCP{4U2%mef9x8{I~jB17;g!K@)!OnC^c|tipM0
z?|Rk$IBPtsJE<IK5r1Xu5a|QR+F2yW8Uw&mEv+tQY?n3AnCB8o9f4vdtOKM4(UxR1
zdulkB at 9+y4B-+UiVz>?JR7=}t1HF{(kliByswJwLoSG_(_tenp-v#!GpuVG&yl+Fi
z`IwyUO!VusSbG at v2U8@?(;!GwlB_)s*0!#V&2!tk6biOY?LYa6Eq2~fHj9o;`UHiK
z-B0s|7aSp)R>M<Qv>^{93?Q1t7_UdHHAyCg5;ua at I6d6m-T%c|klr%+3borC+U3wU
zI~<bgzvbu&q~r7S5hp{Lca at GqjS=}HA0R`(=jhO~G(Y+wOYKC*qmFbkqMW+~@Y=RF
z<RE4?A<_ek;AE(Np)9y at K04^Ot^SI%j`(h$5D)fy1q{>V=wMJeo^P{70xR3y-Ms>B
zdQ|ELn6zk}3T at QnJ^Ca;3VW>n>=fkp!rfqZ)m2uk?tTnJXX{~%9b0rS0KRp`$3>>>
z&9es!@br$?3p5pJcs6YCuc3StWuHAIDO5N=Jq6jKEB}?a{Q!KXScSZ%%`p+rucpUK
z)LpL2`S84+DU$Cw at rcCfb4S^ofso;uzUb2j>;^>k5MPK3cmQ?%7$$5bxS7oHYd0m(
z4Q2I+%6Z+%TUTZVP>dz=&{Lf<^SS>CI7y4@&E at +Ztc)$3UE{pFF{5Pxz^Yqy-Ldbt
zJ*<&G-U+~S^lCVFG68~NF!&&vEOr at WbM2{Ir4i{3R7p83_4Fblvv9u!4X6G2ozc-z
zYG;>?YH0eH)afhUEAu%WnMLd4T&)Z#pcngCx^j1gcH^*qQSd|6#{DaxV7{1MiRXFB
zO#iqz#mO3uQKadXYr6Lb56ljW>Kx0)j!m$I-&+6Opg>>Ca at p8Zg6(v003BM}+dnlM
zFA(^I6?2mvfBYS_;G~VBc6zE)(?`rBoy|V7ON<usrBMBOz8kiZ_l3I1y$(|D**W&z
z3Q|72M at 3GmMEw%!dlQqIXsGz<YaN08`J&Zfa@#w~ErB}3<w<UTt!%SwIZP|??_O%l
z6ZuvbLf%$*)C<SY267H at Tx1`h%t)u#%40S!Egz<}Ae at r7*qg`;8CtexUi{)=nJW8j
z!_+n|=wR?{bJzKGOgVoc5o%}ZZ2#Yw at tK@l>wfGoc95!oX|sYvPz>?}WgaZJBlmrz
zv3v?wT%oy@>_xwMJG9DsE3<xPUe+S+I!uqCfvCOkklL8I?H1Mhdn2^63MZg3QdE9n
z02zSS205L~hYv`ODkMv9vE{6lJy%5}rgV?fl~Q`$NMPr>k^4Bcf`p<6mn*EDVqLQX
zALw4`+iFs+sJL6!gX8r37#Q<97Y8uMRGB-N!=rG6FMfls%e*L>b8gU!ZQVeId|>BP
zqzj<U;dL4wxjzP2<%rQHjh6l?Kovs8t^aEI6&f%)MHO9TN5AE>5=`a8d&&YwqvVZj
zQ_k=94byvff7x<pA-4S5E?uADzy^AARVOmVp$B>5inkUE!W;^)3N?6OE#p<T5~sTH
zoX?#PllZ*Dk%8v{B6V*B$bpS}>~4c64|%H2%2nWit9WnZEudpEZvyfbTs+LB!@fHj
z7!^EVgA6mm-(H^XJ<2cw_Ikg;qHorbVMfox*Pax4C$8O2o!toyI9Vcd+l$||Wb6N`
z3O~=+JK2{hAKBCP)X6F at H|Bfo*RJ2m`}AX$%bgzBFZ+aN>5w+ogyFESJ**g%L2xi_
zW;yh?^iM3pAypT<QyuOKG0Xg<U>OtwN~@Pydtr&t_vH0NG~ItQRdbIen925qO~hx!
z$|zB(N^kBosO4&bvbO1yWHDMg!|Z__|M<5ChNZX3Y`ai$GPaQ?n$bZ4gEu{q7PS|@
zmW%J_kfalT)ln!Cr(CDe6`<TZ13%#Qvl>*oDD5d%yam2>;=iRnY at MNy&CyJLy0?hg
zQf&#~Q_b<()D0-0?4#!c>u3GF)1uC;N at 05jA}xdU at 7*R0&D3RXQkOR?D at yG0xqCP=
zHrXza&Jcf{sP(-`N0={Z$FBdp=pWl1!xTEa+Muk at t=Oh6SpRwdN;%C}LqDgY@)ytR
zg_(&E2SPtdp!iSFl>N at LkY|FBN00oEE(KrtWcDO2)Dn`owDWKNQn)hbx%cI61%9iw
z5C}_u^l%(L*#yd~RbW~sEeEl%bWy$4(!B(BK+I$2fxBTow!!nebuj>NqJMM(ONtiH
zWCQUdp*b6O#AE at t?jZ1m>*<)Q0K#G3XhV2nIFK6tW<3SP?KW_pw*q2fL>dA|4%P+y
z{l~nc=OcV9e^t95RUMa4g{X1)VJdhs at q!GgnFZ0$cUPI<uP5t%neYI+L4HOi4~|%u
zw(VRp!=)CyzOv7Th&tN;N}Z_kLs3B^zxkngLs`t7ULm(qoN6;StZX??-p>#N>F>>c
z`=(pkL6k~9Q!nl-dq?d6UUVg-ry$ss2==-*DTH at Tprg#l8!1`AqbVkjqzF>0UzW9;
zwZqouL%k|j)_IJ+8rRkS^J-D~)ZgDxHy<d12npVT)E(8xzCFVz`)k)Zg|x-h7-9bH
z$?*$FBKV!Ejk83=j0g4)_QLCvR>6jTjR^iI%BKzMHM299Kwxb at FhTGdKJ~*Wvn5p!
zn!vMV$Mb}mlo!Inhqglww;&l`=2I)ch*DMY*)a3SHWa6%v{`wjt}q|--0d%<kzjqz
zbu`)J!tBb|qDDb(7t?Z?*ofs3Qw_!(y-IZ6oXb2O(L0t0&CEIb75kns5A+8Hvls6L
zK`Bn3-a~qPpZF@;_Q(5(5c2mj+#O4RM0!P>U-Xp9 at CG@D5QYK}Z%|#35K3_Oz|vzS
zkJdb*(R>qrGu|T`+#Zj4p%Y&jK7(IY?P8z_A4rag at II+{H7hx9{svf>!u4DCNGS$N
z+|*yQHCRm$#cTUI5`Zx6KY`RQM*#7<cP;H;S-oQ-4BP4Vuymri5o;svt4O(J^{ov!
zcr^5hS=a<syBEfDR?8id^U{?oUtr<@&2YH at xMecw;X<uOW82NS5^uWMtM6c{{#{*E
z2`M9E62(+bfs?@SwWSeA4Yc}Id4h at R2OLAx-Os%GR32L&{%uv}PFjosHz!aA<}~*n
zBSvi8C$U$TKpzux-cxa86*pqRL|ztNai3)+zIVjpwZ#9?bk<Q#zW*Bs5fD&7DWw#H
z7$FL%FhCHIPTA;^?%rq#B^41E4N^lGT_Z-9^ynNZNNz)ruHW<dp7Yz^oWnVLp56C5
zuIqIHWi^o{3tQ|)+CAA+P0Jrlo7sO~h-D!rW&&kgAg2PdIOd?ZS at e6tu`I3TYGGiE
z%VR!l{$>%YXx4NIsHL3xHLYA9q^vOhfi2d$SDsFiC17v at mOR^VFuZS|zL!h`Mc|8G
z$BZ`(Md^T>o7vq{r4-p!YfJFp8TgJXdb>PyL9Ho;8ltDHrrqaB*}PPFv?7q4rMY%*
zj=*^b;^|&sVp2(Lq&9%m#<RE_m5CUzy7*?X+Cn3 at T5~IM80F{IQUhi(re%c=e!ZO`
z^104r-iy%8{#l9S$TS(S4WDi$(EHLIF+h;1mmER0G_|27_VT~S4vXb*==l;>mok0V
zjitOQ6TdR;Patzpz?(It at KiM&4$g(DSkCe~O;ArH%HpVc2scCyN^x2)$u!{f)xJ=b
z%nK+K&{@nqeX8`;WIzk1w|t9Iw*+b^h%Q)4eQsX1-4I%TfPDUrAky7jE|*`pRM at eS
z`a&P&@+DHS at NI^aS6H^^=##urg at 7b&aTUzLjKK|ITIKhAgyGj^lcYSoe}VbTiiMRO
z3kygnCp?_!Y7^F_w0TlVj(!U45&UhSbAo|eHn4UMT1UWwxAX2SJqpY&<Pv@?hI6}v
zuVc>rdLZa5I8t_MM>$c;IT>65mOT8@)s*1_<XeAK^kIglKQ8Up0g|&k(OuX5=SzpS
znN at Tv&=0TqnQUhrI@)CioO~wc11%f}(y%$!I&rp|x|Hk{>s(>T@?ed9bJTaIv4CIK
zP$gwU-ky3YHHFGX>K8eGz=lSCBPHoBW8#ulV(5Qa+;Vtsz!mrW at uH@WS#XnCZt28O
zjAv%=pm}?tVhBw>`(zFG+K0(#xtPBokv>b`SUoSV8%A07+SvvX5PicA3R%8Kftkv$
zI91ss4q|7j_8*k@&7Sa+sr!_kiAV{s_duE~<i3n5vOZWH1)cEn8d<sO2(5iXW)_1!
zz;nZ at Qa`FUk6*wB`+o&Zko9?$xa~ANR at MRUI!{b~QeVFP`St1+b*iXial1- at U~!+y
zpoff}*~70x_wL)-aP~mM`2G009H(q3ivq8M%1Zdn5pG2Ez6a;KwQ-fSa<+s2Qk}AY
zhrIeRKY4-LfhddceQ#*Ak(}9=QsJ}nO|pH*2T>H0wRw6dNukcpT6&WpvCn;2BBOlt
zH(lqUe{YC<0du#}7?Y|i-BJ2qRbj63v%H-hpc0n<x$}0 at S<9)l0CIZKT)hv?SL?|;
zI88qi at JAbdgb2^pM1l>5i)Y6&5mh>)0TLqmxQccC{%e?sE{^|dQu%D4atShNi$FyK
zgTH5`WXFWt<ahFzqU1X{I1V{43tOV7v&8;LQ;8`Z>^TY_Hid!vqRPufuh`rauoM9>
z)Z2!$dreM%J=aIXaLcD2UkMmMWdVHxY&>EqxVh(~L78HFK>psVUNKySp5yJJZ8=iF
z4&nK-OErwHsTqh&%H{YzO?;&=^JX#H@=tX{f>k2FEewBayGAR?jLgTl4qkzN&LOe4
z?syxV{#0?Kyr_?w)0g5M<@c%CQnqvEwveJKjx~4tK=f8N1j26=AC3DVX5I)KdD%$k
z&mZDGr<&f<NeP;O08;?L7~kjBsn%jy;R?5qfP+A2)m_8iURE<BEUkCy+;v-(tf~h1
zAv*2v%oAc4cPoV^5N{w-18Vh0rtfEzzb9G<z0^HzEqr4sqrbxQp!SiE+HI?;ii_HV
zo#BPU!P(AuB09&S()lOEY{@U~)b0rIMrK)6F2fD75wt5FEI~7BI0?jy+)*vNLS!`6
zP0AS9lEFrW1R-c+Aqk=Z^wD7oFYn%U&-|&q%PrX#0+Mpt1FsbrM~ghet4c&{`k1XP
z_*{>tI%?n$UsuW_PDHpl%yw$mJ5R-Jx4s?tfL++0^xRYl>4J6bNC;*gW}({&>D@!9
zCT!Cqrqy>oI4>~W`cBfgq at 5g|nk{-ZAnu_>r9{5$rdRiT#;rMvp>XB(qHqL4KfbJj
z)&6b4w{JOj&O89TU$n9mkS#8>Na&=3^Wu%OsllnEPa#EHvDH-ui0YRWfWD#lSfW at n
znAR;Evg<`6FxmVWyn|+f_q5OWjUodb+Rcd!gGRWKCfA(D4%$1M1 at s|xa^K at BVdxh;
zH_dF?)q(Kykh?<;Ut|HuRY(IIjH~lDd0jDd57T^P<NFF74`dExerE2Bl1txq^91xg
zF}4A46lh!jJ#HC{o2hl4q=H9;r{Bj(H72K|V79JJf!xtnM<nDpGzAAtETX|JY2I$b
z;-HNhBRIhU&FCs8cjW2mkiDnI at U+U5-)(OM?h0v8f3TV3_G~WD<Uw&lDI;5vt+I9L
zDS`9 at Kb$Ilf!dH)OyrILF|~vqzkpgmADF#?Se0$<rFk3ucJqtX&(`5kFE4$VVgHKu
zI_l;JKa4w4McoUD&RJ!x>98i**{vK`pd6v3HLyz977CgrLN4-^Aw#B0_4GFiN0G|k
zlp-eDq2?MxBb<AnZK}B11#)`#aQ?ZvCO7~Q{f<kyNtDss<>%;pTj3$OaP;l<<uUud
zdKlVxY|T%1%hRFNKATF1?>=-F6q41ODdL|YKE7VGuULA2(QD091s<ET<XSL3g<n)w
zDk9-auBLxz=0!3;Q-HGP)5$9Kr`s4Ksg at _jv>+V?OeAmuuPQbws&XAnpfZ>_0C<6=
zZ2bE_s9emVSR^yOXdBpPXTW0s?!2B|#jsXDLz|(*JJ?qzG^je8P3(A+;9xqod9)NW
z*av}{c=5086$RDnaTCfv2;o&A%FzaZX0Ka0QoOzySeJJTV<p?{Y}n5ifJ at AoKm}JE
zWQ6mcKO_vlI{YtpM_MG~p26)tf-RQTO<@Yq=OiQozTI+$;fJ3;|5=GadHaT?CqJ0m
zCdkF#FHDFs2a=M;3(%t5T|7(xi1fp52B3T=;N#=+0Nn*Mwhgevz*b^1TaXn|;JhD+
z+_oJSSUljid@;rBc&nNnN8F8(lcNw;L)@H}E*{M)mgMF4w|99-Z at 8wtQ0@;^i-O(a
z6o4{-SEo9=9UB0b$>d<&+fFreHnlZoQ&*o$w$gFjxQ)^85+?~3qYG+A?P0N6?l>p~
z^&dyCevw3Uez9HsKh9TEua<e%L`gq8=&lKrX{_-tR)kiOy at 4`ju!+dbO5OhVLeIAc
zETXCWg*Yvgij^VfegZ{4f$lZ#b at OaaYri)5d^^Gb!cO9rrAzYAwGbQgPnJ>=={{MY
z9rXiSHae$GD)HEbd}J#b+e22Tg#BRD6rQ*8s$*@xSTg?)=IjU>E2WxF<Jz4?Rgv(L
z{H3HP`B&{72~`J5WX9ZR2)|>cO_`xj_^=>jx{jyLth*YGKp7v5>ap=h4$m3`p at Q#2
zAKbS at T#{U#`O2+uUY<!pXdoH_vBH0+52|goz9%q$2i4DdblW)ZJ(WjRZ*}iNGx+oV
zvJy4~WNBzKUyp92!+}f at Z%&L5n+P!P6Dg_dAOtxy)X4?YSyhSwN)Okk^{_cH=WB+!
zN*H+NuWM%??zUin&Pn=jq7CK{;8t*zU~^JEQNVu7cx*_{m%@`Cu+G&ic(~Pdh^u4d
zyRJ!F5T}kYIZyysJQ|SSarzvND(3ULU?uRD0{^=1DIol7E{jji_1m|c7)f~=pTi<r
zrIqud+$*(XI;r%uDm*7HrjOa7?Oud>Ga33;Ngg%rS~)DJ{}#$X-AY5_s^INd)X$08
zJsl}Cd)%L3VzeYVms+kUt0&n^bEanKgliE9dYoZ+TX=%LqV!NqN^l7zs6g`b9Ck9u
zDGiDeG&9V2fgdFKe=R^<^ZElLy1e;XrdZYwGjF7+s9u%tgo)a*6l;{IB at yCT_1c1z
z0*pPtXTzXR*mAPCYv3v4LZ;G9ZDx)I_$!EOLkBt`!Iv3wp1bb_`=oQrD92GtPFRPv
z7^^(;i53gp%}o%bi-i6-yWp`i1Pc%K>S=j+!(ZzLe at 0nv-YDbRJuj4WgrND%Sa^Hn
zm}6i4^OtCpvQ*2X762`1B3={<g(x&pH{@^Qxq`M+6V<KG7fi|@7N(kqe?d;*eTr2y
zmC-tw5k0kHg%i8Dv6N1ShwN%V0R5evdX0?iP3g*qrXFLy{NiO#ys({WH?t~=&)%cr
zWlUxk2e%N=jUztA)y7b>g^T=ODuthhiv6DwT!oGWaavI|SY7>tA?t?B0~&rp0Z)=l
zo%g`UbSDqAtXWasKR`22PAErRnc$WIzO|wcp!W2=V1$n|6ut%)TnW!{>YsFqYh4vK
zt(Y%>vu68G^k7tW6gZtn08u){1xPYXY&KcTfL-TrrA6e?Tuj;a at V?pE+Y0vefoQNn
zmhVUkAN|Gym(U>DmOH(3cRAm2US5k*9yTD=lFgS}L-IM@?Ypje`swI{@N7T;ppZy0
z6>4>7NGZNCyvhVNeUJouO^p2=7NHTB!PdPXqJL)}&|_v3Jf3g5%hm})Ym6P<li#yC
z>1#@7tgS{|8*IQRkBQ7wp&IRrW%XiCTmJ#|-RE>$@uj)WG=@qB3t at YHQ!`^A%8Un0
z0`cP?EaK<_ZSloEh|o*2-Eu&m^q)vUGKy{yNshzfc-#zk at jHlp5*kkKbj~{z^Gynr
z?{4M$ayY4BXs?cce`7g4%D7eJt0s2NbE&m?=&Q1WeNikuJhE)mHqzTRf7ilM->rRB
znQZD-6#ueN4Ir?kOwx$Ug0cd12aGX9t+(GnyPAhCnc)>DeWl;T%r8=(uZC>7Qupme
zZNKQhshbw&3Ti-2iS&q-#3hi8Ft4GH=KjX!*m${aTi!wbx4>FpI1^tFRe#<;R~zki
zN}=ys5dJA{Oa&&Gse>GPt4%Jj7%4zy)rB|U!(i at x$*?)Ftn{|{*>x9hqz8@}f&k at e
z!mI;#1Tf4GCko=8eW at U7>$T=+HH{eo!N5R_`oAyWyd|LF5v|3EC2Xw+zW<|-GiNcn
z{UhTjx at ccpD{lUJId>fDCF&Yje0e42!w^6;X at oHwTL5dUeHQpmJ(H2kqEi{22XLo&
zzo<{_GXZAE43usP at hQMH^1Si}!0KP;Cd5|a_2lg8GWz)#y1WbS_7z+ZdWZb`zuawd
zbnC3r+-j&QW$7JYPSyVD;86Izh0e$UM}7R|`Jk&)m5ThZ-au%%wJo{;O~u?QI%q`y
z<KgG0<tYL4A8#c)Q%`6XJ13LYGR-l&OlaqUk^^Y+x7(IgV`Lkp?=%dg)w2l~+v=AT
zylg9se%yqL)Hzv3pJ=2V>u42xNMK6c<IWJ#I;}yel?v8h02;HW63k?HCvvzt%9t_0
z^##U)zdA0ibhD`}ILj-Webh5UU+G`#Tyu><VUprzC`D#SBzk#%Y)Bxvvp&B_T6@#_
zN2JJ2(4d~UXWhY-1>Pj-w`5Gdv0Oj1yyMRP>%l4R7Z0EKTqt*nz4Rp+zGPf3e|t>?
zn~#ww0`ZS^_=Y>K-zauv%9<-F3Rn63be76JMomnCKNsSaaA`SF*v{JL%fCF=;qdQf
znbQ$QKlIe at 7^_O|z{+<+<okD8$n2Yszd~KZD?Q_+%5E|Lu%=LVXz-xW-rRE2 at -e3o
zLM$Vmb0Y`zGvc$}tv{q5Ka#>|{4Sxk;UQZly|<`TR<Whpy~?_oY5k!%i<KdOBIC92
zySn_ZJlq-D4yy0+rj&n-SYq|E-UBW1v&~)iBjeo5dW35{g4I$v*YvN>lb;#lY45iN
zT-?I301qu;=mp>L4S0gVA27=jCST<z&=u{h;%9uWa>GIS7QbW|^k}Y0Uv+<DAe6_h
z___-+!gbWDcY=>x6`C$3w%-GaE>vW>pJVI7<5n at jcRB*V2>Ea76I7H3U|*0IfkX>#
z6yCMDv%K^DnE^W=!F5st+G^t#t_r+&G<BGkm!ku7)#$J1yL~r^6t!lzjI<vaHD<W&
zQWV2b5zkATD8prPp2r!oPvjiQ2+5nvjNhYpS@@v3w5SB8q`Ohx0AY~ga->oDwz)J<
zvC??IXc@}Lp;Oa7MF{RVhJ4Vf&ljQGV=2;lT4Of#<W~E=JSXLNu~7S|-1$UhE7pGv
zOU53MF+PMml1n`MTF<2g&x+_{=ZE%Q+9#@XuctH-_PA*ZTu3oFNH#L^Tc6rRJyaY?
zrf2MVAF5wm-AT)F>L at ngk>wwGS~}ksPZd=40I}@!83N&9m>nwBGv8T&WoB1h6FZiI
z^nrCB(8qyBeMB%?qp~}#64*5n^qs<IMHM at F29wlTOE!Kp_6r3brMIvl;xa0K_vv58
z+_*`ZDQWrDA;XQgDR2J{_bX;ze_cW(a}T3SVPyJzrLq{f9RHw!LymMY3Qle$R#;4;
zIB1I(LNq)QMjb^(CE@*bU*+sAekFsk!R`ZtT at VyG>{J#(&dy43Tm&9MCSMmv$jgd$
zYVscd`{<FX*_9z~Ipvs>pozYa!eu|)DK#%9#lDw1(&@E7(wMP*ritMI2oT~Qjy3=V
z#CD~3wOCVChX;_87MZwibulj;3N~=%=g+IN&}+CRI?pf2>n+Xp5$Evp-XP#j`3{_J
zBZ at a6K7kOyGj{ODO~>QNFx&R#yZ^$h^B=07go$BNo`)db8<xEW6!#g3d-yj at NkSC$
zS?C5o#WZqOUi1xXGs_h*vpmTy&W1K68wc6b%k_s9do#?bq3dgHDCOKzU*jqyN?%?$
z7nqYO0ZVzR`M at a<{G^T|YgAH#>`}`InM_02mM5AF+-V2Vn#d~=EFy(UF}~f%N+s$>
z?w|vtBB0-=k7k`>S$FsL_WB^E03vCCIFpTv=qOwf3L5{Ygk(IJnfpuMDq1)zA{^nF
z)huGeBcD|=!5I^x5F9gpjSke}@vI$nCGGL|jeH(yG`^+etUJm#RYz5(A-IZbbT)lC
z)v at 58m<<(@pBfn8K36J?dQWF=Aw&MQcy#I$*6WpT&NYF)d78`r;#_PY(QGA9iBClK
z5!xn(l4<8k8Rgj=n=ov4H7_4md`|85RNKd*!02DvC&hPsALzy|0h)$~!D&ICbr>+9
zK20{Fn7n6<YRZ8ZYk&r91};tY#W)`Nb8hBY{cEqRMs6?^_6o;OrpI)5m_{*cMx22Z
zwyr!U3uvGGx;T`HSAeG0tF#qR^8XcZumQAoMk=sZ06vksT>(%pa7-Ba1J)8nHL=Xb
zaPSvdl?Kr?NB_dPCgQHte-3^rVb%>Lf14IlUq`oa<JQqC!Gby%2Wi1#Y at G!b(C<m!
z7dTB|ouTcqar>nMq%MIdvNr*6`V+v(6i^^wAHWRnf$mD%m-?lii8!}}gFD?(+JLm{
zDv%DoGrMquL_pJXSS_aE+^A5MhJ+%G)<M_WiDlcI7hyM1XoWy>;z^*PCPH~MkU}sd
zc%1#E_z0OfU4u{!bnYNoxb6E-Q;rKKcFLIT7K at 3t#EJ)FOOwUMi?lDxBh`^X0UC%0
zP|z5mKVb~^&8Y at NQy-NURDqw~t3#^v*1mXO#`D?antO;^T^`*gbh|Nz%oQPAY(KD(
zNHGq1t9t6#gi$~bsqCX#B7!>2Uky4Hxvw0(>g2iWs`iTRz023WWg$-9RZThYgo%2(
zedvag)^I at i2_GFJCTXb1=PH^(*#cGM at _=LB<(WD$W(Z6*{FURHw4J<RG;0Z!V$)RV
zdp>^d7VS?C>L}lI?&K+JbJaxH1~f*mLzGffWeNcnBrlQXEA?YIlA;;(V$zO%1I at nO
zW?R<6?uxl_`minxMf;>_0ABv8yw80z!z*U-N+ACvBSQhCNPp}VYiQAzdPzml$*lqz
zN~E~uj`p6_2bY0<q?D_ONcP$p#?EpgLRM0o-41|b;=ca6l6`@=<k-O at BnE(q>)_1O
z=RK<8bNsz+p88K^B*ltl`I=1;tm%PVm8R_!{f4x0`)CAUl>7!Xz1EPC3i%+QVIG<u
zGN1tirxf}w4=~F`jIOKf0FqGND<fRRD<E{kPXSbT`4muCXs28NcgLjh`bvz0j#2az
z!(VAmLWF|y;g6x<&R5Zk{K?HJDQ;sYvDXWsu)Z1GHBF}C%=<;D$s7h^Tj{~d&k*t@
zl9jl9<tHw`LHs);I|Ph+A15n5Y9|);EoP=f^wG=w#rF#M;0?jORFFZFkW(?yCapb6
zCN!`qKs0PTtv%Sq<_^02Xy0U?M3M6RkE*dng>fix4DO6{mpg?_2$!e4!ec4Yr5^k1
zBGh1NhVwJnGK(eidWWhK$@2FGp|Wjf`b$;5289~|L)KmY0<?F`N$aC at 5YVLldAVwP
zJ|_?G+>6gi!Bu<F_y!=$>Tmm2;aP`RKn~6mOZQ;%XP(GgXn1<dEPFOp=On?U<pQSl
zT}&(9+3Xro<YlSiSAGPvA=yk}X%C1Ql;sn3t3BNst^yX%n@`wjyS86y*U0mKKZuy|
zD3_^Nta0GM4-)h^Dl at F~LRO`GTIaNQg9;j;<j=N#XFdKq+0nqDQh<DGzh$jZs1)?K
zT^(_xy$J(LoDNJQ52PINPxGB)3ac0}Lxl<IuH8*fgvUIO9tSvmcO~y*xK(=YOXC-H
z?#(e2q=>IJ)WtnZRCN25X*%D}@d6$6JJ6QP-r<xLaFY;kmN?#$%|dv&g{$x0Uyk9v
zu4aOaDx1#HsT=KsWZ*D$fKP#tUVys~G&o5+^zlvKfOyq9V4mY*9V;2HUfoK~5D8ZA
zbEGXKHYq!Zv^kG7t!M!+Q~tnz9rg(;p at 2SKo-0L+nzZN5=&xZ9zdEmH2G(kB;eJhk
zUBPx_X0T)=+Oj*_y~@kbu_O$fU|2?O=zYzsh?=9k_DMr{xeTV*n{BAi!Y8qxcKd}3
z#)P)Atypk|+x;w~#vVc<5+O9rW{cK40`GlWyGiYCuzV;Cqyq^01P>|wRSv9WdNyB-
z+?pwz&R$q|M-gDl6VpRc2_)zV&Z181O=M^dqU^qU(HuwleAsMb(iI~vVH at O>yWQ*a
z9h!eQQ1T@?2;YGBW|cIeJG*Hkd;O+g8MNM0^rMeYy=J4`(#CMzgft}Q<|Ison)dnz
z#9aKzB7!&>R6KifdMPjizQsnkSD&vTxr!Q{mLDdwdj0gZ(bJ^&0*)W50-CPMYQxCT
zKt8H!akooWRma~9g at Wv~7Slq<iAM<7K_J>%tr8BiH8GU$W+F{r<1aDC4%5zE8Y?IL
zoh%K?GEB|wgP}B`QB!*3;%q)=hT+^(nLa;5X5tv*UHJ2(A0dMh-qij09`jJINJD2(
z7+>xs6 at BacW?R*>22O2QN<ZT?=J`yuOvBlt$d>rxP{=maF?(Y;6Kid$%%-!fjWchv
z8tnpH^0dZo3Vi>D{@vSFzU at Z`S4<PRH*G)<PhTDCdd&P4(><%kM<|$0EWTyYeu!H!
zuyKe6pZm{H5t>r{rjC$xzu&r5Ml8L0(-f>~3(Mf4iHp|)&@xXufkM`5%jyLayw23$
zB-6NCiY7^<p!7zZ8Z}0u(pI{iBRcIr_BIpkK0J!e;d|DH6}HqArs{beB!na1 at bgc}
zDVUXi<nP8)o6!nK4}y8$^3js8j4!W1JdUQiz21KI)f5s|ZCKSh5_Iz8>U`bnu5&n|
z&1ClN$v-un>n3=Uoq)QNBEjaYhHbBWvyVSX^CoU!%!IN=l&^mvH^TQZHKxvESvq8D
zTOaGu2SJcXLR0SZI!<saK6ulQGvI at R12%x#ra7E71 at c7g*UJ2liBVLsqE~Tso!k#?
zW}VRIkx79S%vF%;YiFmN$*Y8*;;Tr9EKX7>O(P81+UPsBr4k{(vLdq*R-u*v;trq{
z4UtC5HIWPltYmX<><&+>e){)ly<T!dA>+>75*q7eE9{$4O(1czW|@^&MtdNa`hzds
zOk0U=P<ZBe5ue;luMQxAE;h(@=<y=%WID)FD<ij6xOhLSmSxe#u%+oVRzEjE{*d^j
z`@LU%%(_7RQdC;kW>zO~mQ|0uK`Clq6DAG)R5Ybp=!q=l`?V-OG1NcZG;_*HlKA3}
zfBN=>cqqtxVq{@;Gzz$FuJAUZIgZaNJ)bj>90k|qhSlK%6T=FyVL^dJO$~n1KMh|%
z{|*{)QakJ}zZ{I0zq$SrLkthKoK}s}kf#%uV*(B(t~2n=`X%h)kJ5TRGQ)4=XmD?d
zp*bQl?<f7|@W1H40ie;1%hro*>Kva8_Ne?|s$zmC8?nG&-7mam>!v^xMExsaa%THB
z{HDh=7o^q3xUqzf&k_;}xtX7lGO`><0oOsF4-Tj at IT-x?{!!c at G-koQ1^!?b<=$h$
z6r=Ugah=!=xWX1(cOb}N+X2+*Ilrm_5EkZQ0(@kLU+f1?0S4FH2~o<}!#n+UI5FDc
z9pUmEyp59Drskg)NgWUbx4;t at HZ7N^25hPT!N71rd*t0^`2-~k&W`?l7KZC()nPDV
z<hG6_!>SjrFSbo~-02$RtI>{jH(JOc-x at MxzX2Gh2KV>($)6gYb`!dsds at 2#Ct;Vs
z)Fv&c#qai8s<8hc11NV3FF4a*JOf=W`75$)nfwXM*K<;WuA=4eyC$ubSv<URfsNKe
z{CX~knJ838K1i-6?!8>E#59IwM>~-KC3)}w<w*#NFtbC*+w9*Q!arp51Mv_8%kSiG
zX8e09b?30DsK-fT3S(2 at efIwKt>9Xj2I=>s^oN9hkM(7HxUeuH^j?y3<yIYIvHPXk
z7YBMfH+7jp?d8lg_YJ5AIiL1d{+fAnEB*syH6b%&xg6AT?=vf!`f+i{3kv6jysqnr
z+JwWzmNGuG;4~_Ld1l>ZrC+cEQ-*?7fuN;qt=R2>9VM;)gI!L-U0xuqk`qnIYzknf
zHH1p1#`>HOftmgM1E+FNcJQB3fHVql8fd3nUOQrIIsn$0)lR`pnBZip<lUA-0UZ)g
zXC+{ZSiWHy0>xE`iS}h1KffsIj00{r)>3$W9w=pQzcLFZRr8S^uCr>sef$WQeFZEY
zD}b<%N8Hb7!6+{LAy8iVz?{evZ|dIruhiPYJxeLnkB@#Au3MCe3}q}%>w<4+mzF*-
zG7W{s%$<5XvR$>!(cUkVu$ntGwCXy{##_FuL at X*R7z~Q1d{gR5d7du$`!v$Cbr6;%
z`1c~kp8YcL>+vCuk%!kxl{LCrW|M<Q*sQj at gSeX6BxfCD^J5uc#VrXpoom at iqE_#|
zy}s-83*E512r02|b6|SUkCLXDD~C*iYI00?AZ=-KXg?W}wVj0CHCqP?+wd+7o&SrH
z#2=!^6LqHavwrDZMs%->OwfdYn4(qwGCobvg(9NqN!S{KjbZChsQf)&LFpI|%Pw at Q
zHvh;*8-&SMQ)e#MMT%BDJ4r-uu_MT-kU+4B1lfbv&AlN;=K+ZnS@;j*E$xKt3a!r#
z&;{0)*AdJeIF^tsSd}UX<Kb?Q5ab;)19pX!AI}>{o%fpQ^jh#QL9H~Jp(<ex);8bU
zrLv;(>^;>K?Y((2oE at XOZp$k%vc`r~zDcjL^mD=Aorcto<ujr~IHp_`K8u`Y;`@NX
z#`CqIW8mS>(ZD`{42|s8hUjbk@~1Uy`tk-cB!8u2ill-rb(n>L-|*tVZNKIl-N0aW
z{Z+c07&p);p~7_g)~$~PP|4{4Z!^Ahg%&Y>35+qP-d5G+iaZAIBircUI`*a%0L0vC
z3qmT%7YECn{WQNns(uN0rwWVclCFpzhQXzua{<L>l1fneh+}pS{1WKf*VM1FyAq-;
z-$}W&^aRf|`5SlLYUJ>C&(E!X7JOny+m6nA=eAJi?`n0Dr>00=(f3H$^+rGHNaoVg
zXD(od2=2iJ*E=bSm(!Z)7Z!f9$S^=EGFoC3nZ%~6ro|X<Oa=QA$8Ba$s6w5?n;rDl
ztC$)SVr&hY)R)%2C!IdqE#_JZ*`}pJ3eJB~)&?6nyzE!ACYce_3CNS!oUnSDm1H4w
ze<87c^!plKWpPFX#WK+BCpdrW>0D}(dR|Xx>+svrA$yyoRi&xAqUwZEYRMbhx4Go8
zaz91PN_(4rbiG;(Rg$G6Ur$$!Gd_a_e=%3{mw1aisToO15HpSAJ@|E2nYsx!K^E^b
zYYX5lC0s;F=7MdDP9YJDt#A{SXE!)H;A-2vv^S{61%#*D7`(qJ+h|(}z@*?pDttZx
z#_E|`UK1~%K7ry9+nmJNm!%T-Ev-hye%~Bk`1a;ShM{W)h8Zt&9P^K>q7t*NeVZOr
z8wF0 at 0TmgLwQ04$-od41NE~JJ>*TE8*{$KXP6dGa0R{#ZL(bU%ufgkPEH`8&=JXBK
zG(@Ia#r$Eh&fy9+^Q6I3d8M}el#?KA2l#PO1#3QyH8lr-iL!LN;u?1;Py+1~Olu96
zY(KI-nhH5Di~w}rsM1C8!+zIapF|REi+}%g1l|n2r9&L*xov<iaN~$_9SYPI2u&Di
zq%h6lD^a2-*AXhXKn3fzxnt>(YxpfnECYi#!w!(%BR9JjM$XVzgYflYZQOgXD2uYh
z^{NGi$1*X8cOZp}yHKp(@Vaf`ThPI4POpg`eX{pW;c2GARm4+(OY4Ai4V{CMY^7;q
z>8+r*a at 6Xmvs5_;Dp}5(1I`XnLpoPU0SlSNMFFE6?BnsK#mn&spZfSTzGEPZqe})o
zaR&iQz_XFmQZJCsriOV*-P1wR_?S(3<j9RdHz4=*+XaK14swEwFPlVI&{twFMXAv3
zwd;%2*${g9>v;-aq(8V<-U~Gzo2<UPww+h_#IyrTfyQ5r(Ytp&2g&L`iv)tHi7&5?
zK3>7I?@pkb9ki7bvfMl#zIUF50|4s>d5`PQT(G$aU%UL&4W$aL567a6&N&Z|x$bk&
zuEaXT?AF1AqBhDL^ACYZ9DOuzvE8Y at Kba`<Ma(9FuIypbdeFbQRKizn(b(E)C&}sk
z1Ct{Tpe-qz!pw+Zt5GCSEtTCRX-!BK(`h%;S~`!J#T%j|YP~8$1k)7VhBP6Z8*3?n
z%A(ZfioC2$zc?E$5*=Mq@^n5-s;3##7Y$_CjN0^HA1RGoZ#FZ+aamRCfWWsh=wh|)
ze|jx0S2>f<Tx>Uh2zNK)oo$!92|KO3hn+G9Ln;`%(VwqF!C&fEXlHI`)b0mFg7Zxb
zapt&Mel8%a&N};C3da?o0v%MSlM{Dd-)8h4d9=-#iyz1sR|dD>?zOX`8cLmR0>_o=
z0At8)l_>0?O$P^obkk-bEtj0zcvNig7W+0YLAZhuUc7sXpR1iZs`9$p+jFl_Uwka$
z-qk--qm91>d0s`<Hg%l(^GBIye&{?m>4m=R$fY9(+nl4duc4WgqeOB3a<&IA8Mm0(
zEH=i4zbB5{jIBlqDjQETzJ7SHJw+qNCSu3Wu=n&o9JVehydyHu)J~b_B_Zk#5IS$7
zIA@@RTK_g>a|RJAPpKp7D)(hp&2EXgjS_9n)iIi08>Q@}q)Jy|D1Wcxx|jhNEptKA
z?xd(z=riOmM0Y~wIG3JP<5|6Xy at RNAJA{s89ZBu06YVeob7<x2ivNayNcx<h6a8HO
z7X$j=lYQO}vv*o!^H<rA&(SYbm at idfag};iq&>kMZi(MhN^^^y>ho3`Qa066)+Jfj
zJk0EBHS!rXaamXUBF+P;AN>h6hLB{%^_D7OR5Ii$M5^j+zr29*F=~TQ){Q at _-kk0b
zTzVV)))Q6<HpQZ~tm5@<c6vkM-lm2&B3sqol}A>PgVkNUM at 4j{mxNaGH_4|0cYRGm
zh}Wu^I?^W+`mEBQNf$}$eilG*fqAs!=RoiYzJ-{ikK93wrge1N?<d|kx&2zG|NEPj
z;Hu%x+&}<EY9oMZ{3}y96R=PWfb`_IYph^McYTeU!od`lFC)sXqBHG*>FvsFr^@eD
zU=gr{t5U^jRk?y+M&C~rBi?fy>ZsYwthoV}Fm+P^{|8*W+qHgBRreck?v%YzHKsvo
z6Fm|eeJ+0hrj;{bPIE2*PT!`6IC%h*%<YFMBM85zURMi~>h%Fo6ZO!k36_^;i4vN~
zC*VhCMi-O`Qq^lUt(BoTY~t+d152-Vjqp<xHAnuxa;Bi<T~S58`<t>wBa@|LstxL0
zPA^~RS6?*R)IQGZ!0tI1`v-7OoWslKLX~9Z-kM>pnI^e4IBcPUoqcn?^F9c>;CO7c
zd-4=$h=SgZG(>133Uy~fEbsmsFiS~;A^8~74E!NvaCNfj=SPM5O=yY^?Y>XqB5Eu9
zLGDAQpUGTbohPoeIo2lOm#Svvht1(jsC at 3Zz8wQDU7=C?q=m-^BzHWg(lxe}PL`05
zd&TZ2 at 6zu$eu4;GRL@$KOotK&ER|ae-c~}q3O(1(SvIP3q3>k_ViQHbG|UMVP54CL
z?lvS<$f!ql at S@CgjiL~8^HFB$ho!w0jMZAAc_s<X+v57Unnzc(t~MS92XJXwGV8^{
z_1d70^~$K?ah*lH%<vsSERO|N;$27|C_RO~*n0~*SHcUkZR;$}a5()0hH<1aNQAqB
z6!~0pAEs!p0l9=r0ECrebcoG1dHP-$q{U&$7{?W%n|dUL8xiL`8nLER%VZASK}UhN
zx at sR9x&2a#Y4jNUxj!;wl0l%bz%l>77C^0!reH3^VCwws0eCqk^BY8RPAXlp6yTJd
zawRs~>AqusLWotL3Q71uoP7?R`jflxd?lvT&cf58$FDB;jhGcbP-GqC%^Wmkr#O)r
z*6fGg8V`{dkG<8imgw>qTvroi at -;`trXb`qM1rzW;~E*wTk9dAAo2!i_pNreJMTx!
zX8$P9EA>}KSwOcASo7w4XdP<TT0#k{_qAUBgWO%Mr-mJVc~RYnP14v|ehMj|ouL&k
zn|)Nbd#3AiP at ce?C*VAnugve8^>wV6C2pS*^T(;Kf%gZa5tKX$B<z~iS*pG?zY6iM
zeDg8KK(E)6S<%(u?BfqBn^st$ahDnj^vJ*iY?GnxFzzG4kW32&)2ts5ZFEUNHNB7f
z<a$FJP-f7{tv~_cn*Bzsp5*B8a8#D at w-AnaCno=`>}s#AtbnP1nTsp&BooSc4@?@$
z&59qqYxqSAwHQ47y--hC4^gF4w)u#o<MH^d<y!kvx7_UtvQmeT3g0@|t$2?#i0eu)
z-j=w^V2~)xM!c)O0O>tzbBD=VX#I|r>Fh+yKZwUe!ZO76E|HH6Ni?<VR)j|z$am64
zW}3^VwMf&oEy=A)Oo%fCK*msRQGNHJ-zw0iH0~UR%u_PN3|)twE`~&&sf}#|=)1o>
ze;+)V=mKIi0DL|erMxciZQ%(3dEWU4D4`$%fc%^O^@(&R2j&~FoPH2}ve at zwI0@{n
z1(~&QfR`vhAGgd}%LXF2TKBIzvy6U7tCJ%iW*|(@?inEKfrEqE^5?^d&kfimT074n
zihxgG)pp5n{2tJ<^Ey6a=)R``_)&0`j}8Td;!^%ghjX=qYYO%VZj{{tDUKZ5v(3nj
zWINYv{WNYN>hV`nUjB!Rpotm at D?#5)vekQ1yq82dYzO at rYDM!F^N#K;#X_H>Ix6S%
z8_sFsX|cDDts!4kNX-(cfUV1#DNI_I^wXU at WqqPJb@vqaVsPR8m at ETLM;5E8wexV0
z*<N%>SkKsjLD>nl*O;G6U;CtJ%^%~^jFLj`>1!f|k?vO|OZ~)ZWf#gUdqYk|WUW5c
zp3GizI{4Y`iVwAZ3r%<rz&^LAGd<g71Q|RMHmeE1EeBGvi`6B#XMfrRLM0ZCl_zwj
zf>&U=8DGoI9+vdCxwI9v&QR}AB)-gQAbp3ip^fzAt*LrcJ0mn#Bi5vM3J5m1J{M;H
z;I2L6Ahos{E4kE%IM(Q1rFMN<Utf=oX`}slvMm7hNgMzxZdIBssK>jFzX>I$r>w$X
z5*Do60iI$@)9r8H-%HyZ1MynXZ$diuQ at b<%yx=gKH at UdHIQx%(T4eK0B*D=148!V8
zy#?pwLtsAnc>eH;LtoZ#+S*JwM{>%bf<X!IqY|H;in5o~XBel(Kb(@8jhm&lB^pbp
zE`Ct9(F9@*3|_%Uybq3#y`L?judCojs(i3SpkRs43e;kL5}*N$1Dh)DmUQ?*bRdcU
z!JvJ1unQd=h9ALaJgA)5U at XurbKR)PwNceV!IS%aco;qwopx{xJ%(}D#T^3x*`LY|
zQ|XPyN@{_%3RW0Erl(<2h3|s7{fYzZPtzAf31*j<uaVDl<u78O37jB`4O|WpTD7`D
zdtvYYYgX*0N|G4Fyr5}pCFbHHE#+QSDSEHAzVCMlPncZiR*Yea_KX#abYZKpC71>z
zSS?skjZA^l$?%g)U_h_y!pqQ?v;`oJnGi#H+i(n1yI>gfv)Ci;l3(@-eIh&^QdXk#
zu at s{5>U>mU{d+R^BgB>V^o@)2k5S$*OLnxVt6_x>PUZ)Po$qLzXFhD$L^<#1y&MWc
z|1VaPrn%d~SycRx(+CPX6d}9cOjlp)g%_OYm<04=_!suo*2pf}UX+=i2FAH&#lhNc
zYV4wTvn0qPbP0B?cp!b%Un<LSUYAK8w0MX_z>LS{-)sL$eQU5ATU0!-)=7t>fxMkt
zcT#)lHZm~v3f=U3DK~>b>PNA<iWp-t>(s1TiE53p<hlnV#V&`cpldZGe$BYU|Hbty
zrX^u>G{aiz`&5IVoiiNK`TkDoAtyQ?LN*K6%V6&L at i+}Bq*CD?R4dnb%@8Yv_<Ow-
zmcDiHfk$7gA;YbkwCG2-u at ozXGykf4YFga8)tjmpzhP1bNkukMk$Ezs_4oLzudR~y
z<0<1i0LIxKU^3leAjH~>wA!ql*Z^9DBEU6yv&|B5)ya`6GFjzP*MSA_Xt3gZhmeiT
zaT?$V664D#2~=32wetBo2!v$jbTSGG&yn7NJC?mPe|Fd_Y_J0&OmjNC+!d*_ShRRK
zdsOu1Pv8}!jRTc=@PuXCkrP~lI!{D#Na~(PCx_HnH4h(QI%Vn0I2C*&yY`cZ{7pU!
zzf0yObY|Z1z1Qf{h2epnusRt?a_l>8wPV_7IN`(Vme6i8XUggz&(|%e1(3Eq#!pYY
z&hD4o%p7_gdB)4f-=&fosq`iC2WdWH=%P5T(7Nyz1??_Gt2i`*)d~>?iBg(S1x*x_
zdCbL5ye at mL#$;vW3VXcTY+x)H{(b at ZU_osm5sip#cu}^e>l;o)k=YLE0HI0LYpBN%
zQPi`PacYG8_1YodyEl>7J!$)?GbuCu`beJ17 at uk}8L$@!-G at 6^hnaF0ILXoo`_l2W
zFi$zG&8tO7#F~73OvF+<V=6Od_)BueziA7qy+~`U&;QDD%2#)#_TqZ2Un1<e!z)lm
z|AFBM;}iHAzLusyvf8thHqga*%C<H{5Yi(tcs$+YC8*3`l<t0OE;1haVLdD7{()Xa
z6yBF{npeJv`bSI4+2SQb9z?kj;`6%y?pU&*Q`NImOSJ75X{JGSvMX57frA^f{P5_f
zdY$el^J=|E6BGMtS#WpOGF%fy7;VJ2p~v*@_x+jSI;y{=aLdKT)WN6fN*VBPhy~C=
zS=^b}U1s=A;n at rjp*)vMBx_&3d$wc~yAm at h8t@|{7vJhP)sF?_49~haG9o9ls{XS-
z2|$^C7A|d`Ne+Gzbxs?f`qmdx;D at dvDsN*nUPps*Ke!7!-ZLNTOfu*KgvN^e95Q at k
z;3x1U(9zUhBjMz27&Ew4k at K@3L)l`c_tTCAVVok7Lrt-&>8qIRYTR!Le?9ti)g=>G
zMA^NHH&AouR>(4c`PR&VM?r&%|Jq;=_+MSta^qWmILwqib+Yi}-#JIle(TmB=SoyD
z(n*u=)sW>lZxyjR<PLIqJbg%JGt2yBASC;5(nP?bn6iiPjq&fs$YKuHiI26$h8-{X
ztW17C4pCcx(L-+cMd>5R`rS-&yyAosJp^p@>^r5$<UUr>QoLeHRqyua7A)!ZY5FNn
zce24*01HAbJifadB!)h@#3%MiT>|vir(Z_;mP at biM`~9c5Cn7!-$Kk#JgO5HM!&S(
zimgvL1sn99p-0hT;`F*y^U at mei>xw2(9(XBNY4QGJk{h at s<`WnqlVP>ths=lc1kY*
zmM3&N!+mDJ;@$iu=l2oj&sVx at Y07PW6iE*&^=xbFs~&HYOsm}uzyiUPlcTiw=hWOr
zV;EYyioW2v-sdTfN5~&8j!dp%leKa{0!HR~rqpO6!~(cO7&+t63+vEcPpgcB(ajVC
z6kr!v;TW2HRrKuhPw31=BM|h?GTj7tk9c+gB)MmE`{Ra$w?CA~X;VF&)b!aait?w_
z-98(ChD8}>*^v%-yQMB3HZj4+HRtO*m8BhpBEau{)cWbr04!s- at OFBjp?V1HwHLyb
z<C&h8%WC1wYp33X?|hn1dcHyZkq>j(|Fp%3TZC2ZMeJ6&J-I2T<;(1+^?e}isXqaG
zK))Rgs#sbKUZ%zABlt7|KblZkZ@%C9Yv{(Ld2$a;>DO9RLP!r0gi~TQsF}{1HXT&-
z3w{oHpZn1Q@|wE;e01+COu3!jXd)}eteq4}K=&LDpcK0IxhNMB?j?>Hl9lW|fdr2R
z4JacbL)i><|3z`u)uXewDW1x=U7rfbN{W3D5V|hr;na at 5`5BSex3QJ|sHv?qq7Mdj
z#NU;0$ge^N7xt+bej{iwP>^}aUakZO<pc`)4HebZ!QX{et+g=MHu{ogEH0l%{i_C%
z7JhtMWB!plV1Ubp-{L}2ja_XCTwaoj4a(7}q5e3YTM#$q*8)Dqv5`fTa at o;e9u*k=
z{_9|-H|1+rh1f;M=i5eC4k0oZ8VU at 3?A*I!2AOJ3iL*QG-{cFsSV+@|wjYm<fLYKV
zQvm#*w&hG?o}0`na_DShz<<k at Xhl>@jlwz|{rMsv?sKFHEMJ}$#Eu4Sub5CeGgNik
zMSBg6G?aeL9n$xigevR0u~@7fmdq~zwJ3JJL`(`R`NQx=%^Q;+w}{zY;>c9s4;Sp;
z>ESBiJDQCm-oVJeWOL!8TX?c{pr`g7Kx-vnC1&gQfKbr%xhwb^5KH%6`TNt67th!T
z8|;=~GGK0_<0>YkC!=?}|EM(L6R}ax%cECNxB(pvRu$dJ!=L8w0dJsQxwu!klg`e5
zv;{tyFfi`jsGI~yCq7*EM9el_o-JNAN4!?~faGhwO;Qe8cP)w at GS5ekCCVxVS1Q{d
znu6k~Z-!XTe}{b5>v|XX2joC8Vb#pWSzM_W{}3#{Hww0Rc&j~ev+#|rYeQ30Q-OD#
z4?IGUM3-D%IoO}Lx$MGatCJ6|pSZ&WRy~(ke>6RlO%z#JrxmCV_P at l~gu1U~fuB}l
z{aqI9DW?c-OL+;eh#fauD4UfGm=tclDspr-E~sesnug~qhVH-KJLMnrkK57_f{<w5
z&w++-t($pSv=x~=H-1VEN2ieA*Dk$jjUFs%Ewo?JtpDR5;ti(lX61W;>Z}3jQ+<&A
zcWC|OwUp-31tOu?5aR%M8=ih&{{ehsh?V+K9bw0?b-JD`lWFT1;@#3Ory<=O{x7Zs
z|M$u5-=~I!ua&q}Xl897eJ6R+GoO|%bEfkO!V>Yx0{MdP*zOl!*CouxgeK5jxTN<N
z&DCy2i^07n<t5^Ki?&;R6tF<?yiVhioVjMG5w%rEE5V|3#egM?W)W*QDR#iQbG9Bk
zhZsL;Wgzfcm3UME)FQasufUH`iZgb^sp^+)axr!QJ9UKA*;t9`-uThRv5-cU1jLYb
zws#Iy0F&CSq7IJHLN$_34y&8M=E3Ik7r<gKr$XJb{R!OZZ{_6=Tt7O~RPnd7cO$P}
zMNf$+Mf!qoLtdWUB)GzAh^pp4p9l`!tzQQMpX|<tI%{}=H)kiX6A0}A3g&}<ci_d3
zYKI1{*0Uycl5hS2(WUFajRw&1>d`Xl)j<ZjP|`0TAqsyRwL>$BFLh)!BzYb*CP|_d
zw6ZA^5_v-Oa~`-Qh}Utge&Pt*v~~F(t_c}Ozr|aRu#;ad^FBLUnF3)({6%{(9wXb2
zXLF0r0FTHy at Zw-fH&oWf_)whYvTt+7x%LUJqpD+DXtkysQm-FW^SLG1D*is50rA%-
zjhRJ|OwGJgd-e8nGhz^9M3L;`gT<h2#{|-k#J6jL{GGH<RZ38Az6aOeiAeo0A*bvX
zgg0kcFH|bjv|`iOpAPZBaF!_QvZ6^!{-b_C%(c9B|1(Da=N~R=31L(yn<%v=&EHl%
z+Dhe+c(k1Pg0}j(O*@WE_hW+ZSwe$dc-yfxvbgFUD=Do`DW(F;eiuzY+@@#I5ftR$
z)?#WUvX&+0Rk~R at g*T9Xq6vNvQmp#OqEmd at 991rIlYnub5!AE=ZOlB*koQmr2YQ*p
zFQ`)c)Q|DCz?T8^c)T{s_n0GQ5D22FOZ|}HY_QJpk_+%v{fDw7 at 0nCZOIv&(i_U`n
zmz3=b*P8}51lRuy4RF|4+E=>fKlOU6;$w?tk62|BH$j+>0scy5=>m99_G5thq|Jv8
zUe~Smual#a62$+MLaSjh$8vL^kHb(kq1y}aOzs0-P8yt6x1w7(5EE$5)9)vim=FiV
zTLiKdppOm5RHl^O!YeKw;g&IgxFTeIH~6!)n}XdZ<|#?jgQ}STy#&6mK3HV052gfA
z=FkX~ehz3^;b9RGS!@o#_yGK-f}tMyYG0e0v89$T>LM?FylD-cN&h>W0>@y_9~HfM
z^YvG1Nr}fJQ_Ta4H8SI+lJokMB5G|r`69Oin^*;tK^K<l$e<DjyJscGsad^)j7BLW
zI}04;i6&;qyy$UwrC*xF=a~ys=e4h}!D4j7GmR}N*7cOElXHbRy>KfmoRKNu>1s#O
z=_>bOKq0DnYdR$QoufAI7OSI!aqCjkjz>xCnNWf>K_I!rxkv&fusK)}FpILP*-T;=
zQe<T_z{An)a9)Tf<#1*iQ)S7C7pP>o*1_t@$Clr|iJXt-%a^8WTCjjOzCm;4-n4yI
z38f-a49F<kvwGn+N8Dt;IjP^`v)(}|j26>Ql(>RUHiAP)TQO;uAo4E2HOwplY7zU7
z{6{^LyU$p6HlB~q*cdDr0WmL6unbQt68>Z3;-c&_v!4)Vv6tuX{WYfcvTuUL7Ln+)
z_h%YB?K@|Z7G=b6>A*}ThJ|pAx51<D`QDtkSsmKZoclydB?_I%&Utjsc$aW-@!x&$
z-xEomDL6kV>^Hzw_$AtNi`6pjYuTj5Hiv^}E8GD_xCG0&K8`C{;1&>yq8XH1m-~W*
z2V at LBLtrli2)6731p2yK{y!q+5z8meUpNV|)Q6k|-fmuF?KZ9nKj7kew~nAbI6wFI
z0N$>V$nmmwI4y(8Oo&@JnquyL7gcWmkCo^hYNC9)KEmjCB!?<yNNlC#NE1jEBigtr
ztk0oMg>0=`fXbMksMVFG{WVXrdXVoIJZ&m;9CrC1m$9#@5y;)N at Gg`!;K1{XIMQ=y
zmLu}>s at Yvw%F<6z=Zy3*`PB~P+FRxU?m5h>uXM+v+<lTK$XvFEj;!fLNJ}u4VF_X?
z+OYc3x>IP6>^z0hlSMKuSN)n=Qtfa{jnKk5OIC7VgK%T(=!4aJHE;e1?IDml*H3 at S
zZj_)i8bHnBBwxR7frjOA=nTsYT{Tb5g!!0>j(i{e!~OJb0%m(4B!i-8%KhK3;DuS^
zH_Ik_!o!VPEk6R9tzEC>8t>2kLm-QJl%&jdC=}2B(!-j2mfh-?(!_a<6=*9xUYF#<
z&2;%rnxY~8bDQ5MwO at Zz>Pbpmk}jP6B57 at rcMf}^eeiD at OAILUd)D_w+3shbRhOP}
z7n|Zdc3X8(O3#XSYJ0`6(E2BtM^-1-HvT8!2?IT*WC$<VCMx9F<4yD>F_u7nz8?S3
z&Pn;ROA~s<L?YX-pYRpp5>1!3?g7mPm^w3psR=Kje}YK5qsqy at b+rdCcije3mWBb<
zulK@%E!Xne+S(uN>#N3A4j9DY!&Zx-G2FWCq4kskUkvaPbdr;8cVov+&H$Inhuq~q
zO8yql;G^64E#=>Uy+CzKG!<`BwQpaUo!2t{C_WUBV1ZAgN4l$)i~6(yo$qXlvBI0a
zgN2N)`xYh&cm7>FzX3o0`|Ez$K77<ea8%4qVmYSkj at vIn$KTH%HmRYT41i|cl at mH<
z=oX&K-Nmu83`qGpDsVff&-EiZvKws<pBwjjv_&Nt`LCMPSN8OgXXEKraRCd_|JYw9
zXX!b)i5&vXFN4dIIAjmxO<8!lY#}jQ=qUBey&k-8Z<UvI+g7E$=TDzh3K*Fl<%ue{
zs<jxb=y5?Pwog)GdRlJw)1>n3An*YuU|l4QI-G`c$Vr{T!I_FtP_axeUFm4NaVahG
z#REVH(7Wl|grSpdpv4WXD%OgU_!fvBAEl(>CTnwhyL)f^n+1D>S)Tu?nSqy3v^PJM
zZ6adaCqwGBt-mrIfKbaB8P}V_Bz4MCep5-R8c28ypFE~(0|iVZkNLUHPyWnyZ|<HS
zyj_#(&)SVXo!7s+X_kR6xVgS!@_#g)Wmwbi+s2Vp5HJV<LG&lJ5h at _Kks>0U8{J9`
zkgm~43kKa?8ynr-f-t&AgGdd at 5u(r6=Q#c^c)=?UIBxFU*L9xf=PU{GXiEB~I33?6
z$qDZfo38RD5-z#JPUJ at obICe!bvDx37US*MNj3D!MPqtAHN}ogKQviTbk4ojyUOFE
zuT at Np)~g~sFXusNNrwXrw3mBf?SV`W-Njo at w&`SDUiZBDk<ruZ&)iV0D-dEcGO_II
z&s?1YOtp?<AV2}P-kB5rVsroZO+vXiOnYN2m{MeV5)Y}n>vw0j<Q%hKS1+f(LXAp)
zdo10_K1PwySC<D&;AEOCTfO$cT5k2PZhf8(P?EF%P3`^WLq8mndog6k|3(Hy4IoI}
z9=$5uoV?*V6Ips#ylIg_2RmmF_VRDJO)~S{0STMaYd8(|nD>Q0qkRR<Hck$1am*ek
z$-VZSt;&UyIEo96o(*q&ju9HAdeLWvw!lP8kEr<omC)WecCYcEdb&Z?!2B^5l}2;l
z*Dw_7(jo4;D3PcZPie$ibMdgiHmDS&ydmS$j=h9QN8SyXQq}m=;>zrJ4^2LqU3b;6
z-G4`66NB0kQdI~vPqGLg9R2z$$v_^43e{O1i7F7-yf%iljVp(}y*biYN%QjNfZ-a}
zmQ3}08^yvz5-;6qriV%mEZFnEn`^h2_2YKwYe&qR2U>DVm+l<h165?h6g0tWKCp at R
zg_rN0WjO7ut3y^j^eNP_MecgLohc-cHW;i3mE*w9S2C;TAgaY_I+uMpOx$4+LB*R*
z)Ib|Es4~9hC)fxjly^;teyb9Ht~fr9SL1tz-SP-lVZtA=UNYW-eeCkqu*^U3x^zeC
z%Vykl(kAJ;baB#U#g)9#4&a48h(=RSAG3QU>J^kpTmjjVeOdhIDv%6OY>RSUjqUk_
z;)Aq}oCpz~+;D$wTb+}claZ$<zZjf7eF#t-s%Ag**Dnxi+YIqJr1O9(zz}xJlb^%m
z!JGahYCvPAGrk+G^+X|E!{7vKm|B*{Xz>}SW~Q;;l;!saEaF*&rdcVCZGYsq4+G+R
z_Y0DL0(DOJf%4@$-|i-Q;Iw*LE)+}be_RjQwu9yStqEH$vkh(ht6OwMH51x*0R#1^
z(u1Fz=ICGyCw#PnxzM7EL(SU!eiT-wgKqB6`CKFpl`N0y<TUlBu@=Iyu!7SJeYu%c
zd+~vooAX%a-|#~%P$F5%q)i>^PiQ5ZPD_An-heYrDaHxHTyD*^-z3<~VFCAaC;%Pp
z$`JYo?Gp0%h~nDIn=EF>$X{kz-6sI8je>VcwC>7pHF4hRc}e_{fUe1iz+|~gAI?0v
z)IoLU%ae=53~s;tW?URGOxD<T|E`U at O<O_{sLtlhCbaEH at ua9>>fsYTxM^F$pSX~d
zRoxf6OgG^lO8DMEY1cHwI!+pd9?o*`oqa8n8nJHvi4TlYgQdBQz*&oj6>o=-+EDq@
zIFhe`1o{gWj~IM;Ga9c-?cP#6Bfq08q1*iLxoUDPixD7?xMOs6@)$&jVTd`psBHhN
zs at 2)Z$_;Nj#`<T&s#1G1kaX}ply?ctnSB%CCUMc*8nA%9Th*Z-6;us(_EbydHPHJC
zD)q+N$MlW^qto>4f>vrbJF8}vlS26Be2*qcyC>pcSrTvl%rSU_KfPXVLp?zm?L`E<
z0RQ;d0CsG-#?A<*QXRaozV;vf;pZjDv4j8?>OKmr+KyQPM(}X`v-b=dCE=Pt^}BC0
zkg=}tD-O_g?&F=Ed&_I3BO8JXsAp~s`1=PCFt^-*bZw(R0-Wgs!z+q-mFqy#z9BU@
zRfRzrDp!4PJw<@<>)g;OuEYft40P8*nfpI>xCy;akfmK2s7PY=M<S8VvWv|$w*GgN
zkW=QyFc4MxeXqFQ+`M9rn at HJ1vJFLQR!rb-qgqJP+N<vy&qIC#t{HhQE3>X7t6qEb
zl$;V^+tm1;b(#%pEMG1h5Yd9!rE-hm<vIrqwFd<tXilpux*<=2J=dhiigj8smcxh;
zcNe`)>dQ|7zt<j(5JqM`WAEhp{1Si9`4c2r;<$v9*!7$3zw^16bUa6G%We|3)IxJV
z!vPiiWqRq<8H^;jo?Pvv{sy8wKY)LNPNNCO2(78L`R#6jH}h3V7TZDKWW*zj8ZYOL
z%W-s`EA^P*{I#m>caw9H`Ehk!pT^SW7*o=G-TyG>kyBr)#R+mPAarUU!}=~7W6ScY
zTQ(mqbZjdXK}1?N*Nx)YziZNgD>+qbj%1)DlI8h-?X-*nn9(P6oStfCRJJkFp2JF0
zsN$`v5qhfw53@!k3($@iJ2ubb!yc~<_f`$WTKmZS8fI9#UE6Zl&k7csu3Ze^IDY<<
ztZHfzPLA%aGFqtgzPlPb(={!UzRUVKOJDZCzcs;|D|jI4>+ at XY|Ha&TfuXr;n9zO!
z*j+-^_lN5}zUtOOt6bYt$o7HG(@pO5BSue~ZtqTZ)i9}OC_i_jn2yvDk%+bHU-`Y>
zSeGGxI9QtoCXDdbKO$>dikz;0%{_839PsCemY|W|D_AD~y~iQtl?nQ#POo&+JouwP
z;-sz`B+2-F#c^as<^E!8wVCBLbXBe at 9Tc&3IeWB(EDOW|&jmy}z*Orw5z9!Cw4n+^
z=~c3wW{=-e$JQ_lFt;psZo8sc=|-M^hJN!~eY<aNm#lX~AFU3rEy$aY7(>-}`NO{%
zaeBZ91v6-iJ42qei2eZITimyOHo4tGWxXZF!DN^&DlAg`yhFPppW4ytSF6}is>noD
zp82opah)C%q*phxYoJdi8?$>wyhEgrFVS#Oo97TMPgwo=*)1V6KAd5f4`yUJxJMgM
z7|+FZ|LQM15}C|L10KTemk)%|C2w2*ckhHFAG4=n{Di3){&k+IO6DbX!7&}NKyeJL
zAmsW#F90YPM*_3`)*g^MZE!G|U?~3_oRLr{xY7Bc4>i-DV-lrCH4i2$H5er{__JZ@
z6Kd1nm4M!ctFULgzh at mz)oYZNn4sXyq-foT`zA2f<a##>S{hj^8{B6Ne1BlE)7<l*
zsg1G5>9grR|FFDe^{}pUAPT<SY{K>W?xT0BY&;b81*O#>)L43?A=gzwlD@=GmYlZF
zoFlFQ`!2vcqF_PC+En?Wo2sYrIRTn9ah@^0-?#{@NTkY!mt&vN>}sfo>EksA0H0m5
zo<4(%Ds%)B8e;JfaD^U>BI~<AzkxO-n%;WOP~4;HNNsE0w0fX$DJSCuqWO)LUO+=^
zF=ZVz23$6J5!%M1Gj6GDqCYYQH&3+gdKQxyg$3^GHEd!4n$V5NiV-hs=05Tv(yY)1
z0JXRKnI<a**QO_Gv}#fA98pIYb+MX0oqu^h;x69j37x%TRU;?y1ve==Q2av+b6Xbi
z$kfC{aPBBr;Q`)l5SGcyYnKgMZcmabx7-N`Ux=*2cNq<*3A8peqkLCM8V#0lcwVUf
zf8re at s1~|pTdO%yOHLP8=rJJZ5~Bsv`-c@#@Xs^rQ&BG93sl&R=U1EmsLA7I&ji&?
zmaA)?{AB=3(y4j|y6(Fo3__~e+qp at bHeYO{zWqsDDb*MfcE>DU{X_kWieu9_Bkb-t
zo{Vj0D)s at 7WrSES0xjz(&j-5m3+T&;w*G1EGPfCgcQWxf)JEPv&;wx6qZGp?i&_I-
z{4yM;LAfL(i5R$x;dV&`J~dW0E@&SvrM<D2<XtOysZMhj>3F130kzlK8T?l4Vi>2T
z^;(EG2`^|W889`<+`N}sK&JG-WU~J0+ at mOV?WN1&;$T(dR at ky(c*i+8IFB30Wb``e
zaMrNn-~EhW^xj9y{fsU<xutcrnXkir>sJ#@+HSR}{`pBGDy(Fxz|Iy{$Y1HE?taU7
zg>*7o<#Am&J8u%xV!i1wt#co$J at X6F|Hw at 9V0^U$chrL3lMMJFi9Z0!DNMhupgn#_
z98Oh-g#%&Q?G=EqXdDUEnd2vvv#qn(6`h@*pXajK-tN81d70?1O)UUe9ZC;99rsuX
zx0>l0{(<YttfNCKfV08gA9w5X4gKlr8zX at I^CM`;#adIfoVbXRvL$uu<m){I>X%7n
z^E7Fgy4VW<h7qr}5aFK5*NYwd%!8_Jw`f%!^Nf{PF)87KjNM;ezP`Q`cOCgR-ce|3
zajr|C1xy at UQc`Ycw6NKqC-`S)1qscQ$>@)Rk|&~Hx+>0}*PeUqBQ~kA=-|~VG}10X
zKtiI_k>5!v at 9xa(#tYbQ_GMNLDZZ!u<5DkX4fKC~b_^XrI>o)G<#*C|F8lA0?kn9O
zn+?b<+d7y%@O<cc>V448HEU5npoL=@BL^eq^Xo~DUmw+HrtdlQ0i4vPTXwJleI(LM
z4HR6N|L2mV2=BhM<nMtoo;=8Baf_98ZEt8-KBx?S)MnDJ;0IQ#PNU|({sSXkg0tkR
z?KP9y=dgnRNZ|D3KvncUitfCoCAi+5^>)cnHtw0;xK^7bRsN0YvCIWi>N{`fXD`da
z??Sz(*6uu|dJCIEy{+O7*Q$oI*U;!U#<_)YvGK^MG?gKx300SumtrEy?>r2D&v^gK
z3`3YLC2rg7a<Id(pJFqZtW{OMs!ZKCBV^ay__%2qV;{qX5lL&GW%<%475JavNDtmm
z0+he`1u=KzbNRZ1at+`Hx$!O#nzepQ)d6UE*LbNHc=Mb4gLc+uuK~orNsopDmB{sp
z-B~qx=WuGZ`AwvBuXzU$5 at 3iq_!~2fz4Y1KQ%L~v5XueSC*}550AN_&*-=sbB)UoO
zH^bS$MmZGhtY8iHbDYoec%XKa9PI7fhb_1f$6&T5TM(--UEN at 2j?UEcP+$Uw_aI0d
z!e=(?+zT2_u0jAv#PHUWzW_uSu{q;0Bs^VXxYMdVs($nD>(quy_YDcuhsQBJf-wRk
zW0D5%m>F0G*`vl_ at MRmuc9!`4r8ZNys8SNcq1nwndHQl9i%!%yS*|}d$W~MwF*9>b
ziR!+3M%b15FO4|9CU%PE4DFfKy2f?0QVGOeiEB}8`2dk90nT$ja0gN at N#Kul%Nrxz
z{*7(?2T^8gw>zxr?#;HN(jdWT1f^AFfj2sHybKRa)(BN1%Hh|=^z`;AiBSTsj7TQE
zg1MSp&_-8HK}0A5&B)34J6&i*y<=Muyn&`vaxPg-V-&I_Arm?rrf}gtg5~qcV~(}a
z9h443Gw at fp-Qe>}qQXyUz$UbV6lyL%!LIztCSTX3p5@#xp5>4j+G4Tx3&;2>+rAiO
z-Tk9KF$)=qA18c`BnFmBY at yUpbL*Qd$b5gjJz>X*J}bt<q@<)Y;0)>R7hl{enK=b+
z-DyD_!Ia0#5;iQgDG{&q-1#%ga at 1kC%kPnU at 5?abY^JdMM8gIt at 0d53FSS1;^!aKR
z_i?3M$=t{UNYW4EIyb*}Mp*!~&Z)QZ*(j(v)r-)Uu?Fxy+T`##-<0^2GTBdT?|N1@
zn)-^|vMqYOZJ!lG!2ukJThY+Dejr(AuS(NtjJBW{_B at D$T at ju7`k_UL?xUGk<G43|
z+09r#z~4zBV_9O?bn(EQqqpY2A6w0umMN}{JtnJk#A(3oK;`i at TzZAB$2L9T at SIOj
z(>yEc?LBS0^lEHNoLFIs)ySbG?5Bp~<n~9-_C)WPuiF;}liV*-k!Q%ysSVz=V+;2S
z?Is5ve!Eh8(T{PQvzW|RalZ#HU>(j7-*<$(d!b&9!QCq<!FDRr4yg$XD;EzyrAu<o
z>9!NmmW@<FT_Z{}iQ|Ix2i_j9UqQ55)Ji+!535P`bN1VG?eL(4>4%v9*|gNzN!986
zUpm*O-dzHCu7-b-D5g=_(xta3!H0gZwj26tI^`bP7e48*k@?u*B;uBc&R9kI)?uFL
zNhOT`fo>52WOD;+G|oeTVs&F#SD#$IJ5<DRle>kKb2^J6`z~=NwluO|kwdTCeq$(q
zu&c2 at V!C2qQ1w;O0dDu~K4br9g6=Z3 at oV^J<mj30U{xcJ89xlA7@^hRQR5dIES7-c
z_c*hsDc^gdpCH<Bdv`ZgVjnbS_7OX_VXNwCO0b5 at p0a>q&EL(<l$a^X+meTo at -Kx_
z8}V%J$5~8H9XC!fF&n#jNbhWDKfQr&U8Rfjvh2U%X at j4^Rd#|!(<hOIjyv#?r7reN
zU`EQ}mE%+ONDYUQhXHzJl;XW%Vhe!rRi!8bQgRnxBBAlGnM$YCIz3?k`B`C28G7){
zs+(Oa6Rd2))vh%h1?4AU_KXPn=$?tBR&ZNF!huDeMA7LcwZiYi??PgLb6VFqe4#tD
zfd at ZI-bT5u<pl^DtbZWkZJTTNO*S73Sy{oKvU#xze3vy9&Z*gkJbAnzlcxw)S-VsB
zbxUquR at kRQDnR5qqa0JUdm4vO<6bvV^J~J-O4V#U2p1 at bVkw_~s!2frx*=mMzWsd3
zMjB6?kyQr2ozx;a@$XM4mFP%;AFRoNG5DZKjxo at X{eitnUw+rX?(<oc3^E+CFo3QD
zYeV85U8n2TUm<c<#1#+Bv at R{1%7eBj*|(D{9y{s8SPyq!+Gz>ApZL&D-es=Q!*z<M
zr9=PPGr=_L-8Os at H&*Fast^(yE;--S)RYE%O^fQ at 4#oWKp|#$Tc(cv;ti19C$BTBC
z?u~8ca%`}O*;{wFwrN>~cb3dF{=d(h9}XEoa#|@2)q~MMACzuvt753|eXK2?I8Rh!
z!rs75^mgUdyUJ#3E`hwlRCoiEvMRyj2 at oOf=t3OIR1TQ_sg7rXm0aLngHOCav0C(u
zbvsEn)l2wHoF)oG{;k#j$zD56OP;0LP{(>sc%!QA{lhD&T%b-q2lvW+X-V`6<MV}Y
z1<iA^)nhNHN2Zp)fB)W-sq3!n^U>{2319T+9{=Rg_bSELG9 at dxa9+jto1>($Vd1Qb
zg8q8q6*61|8(BI0sCODLZeioqe&N<<-2?pnTZ?Ug at t)5ZN1N#s{zs-#Nk`ew%ggJk
zv}XiBk6a2?bl|j|!-?5H1Gin7=-LAQ`X2#Ff^K%?6l3xeHKQ(e?y9lku-nnl*On04
z8nK*sE7RA(8Swy9c*VvV&Hju+&|^=jHi at -GZyQ<lpD)0qkcFB225=R^Q3fR>yi<n0
zY$ow0h7X=tzup5{E_v6VSPcQhEqNZ#s#H*ulBnO_;79P^e{uN=yGe~3V;;BeCo<OS
z+!zePUY&z#x0}<r2*TXo5mwTKJt<3iWn&+)uL&XVN*h1zb0T(3)U1rt>Yh^C(`Y?E
zt_k!VP{Uj(BPwCoxzFKeHvE^dz}g~uXWn(;rIFd>WoIbib2b&R<k7=${R^0}1<}>#
z)<jR!p1pSx#{iOfKAVPvwAo?G&y?}BbjrI0u4zCEhs?pz8A|WO(HrmObsW4K&N$Wq
z3Q}2+m4H3EO6wkNW}a{VQPPj~3zvX_s>OXtK%e;2oPl$P>%5s=(TC)t1h{Ex2N=I=
zJoD^0{^x+8pm4gx#|FWOFj-<%!QOT5y=oovL0nbj?$mF(ZAo>%DyF+c*QP}0PbXvs
z5*nIgpfpB)KBs{O-G!oKnf>>}$|iN;<st<=CdAl&Eyj;_XFEZ>Cswa>FW%~X!7t6r
ziZY=-SG5R@;62@?{!I+QKQ>EeL8Z9<nHpoQw?VJC9&M83b5VDCX0cuu3cGohI^xYO
zuvG~KN#b$3S7GGA++_qB;)#?T=Uel>^_NloKsXg$-j%tKNwmmxX^MIl0Y&M#(|TTy
zC90sS=Z-9plXTPmy8n#~8B!a0#zM=`#o=yPZmMVp|6%{vhNQ!gXei^g*`^F>#Vb;v
zvxQ^6WK_LWYmzCHUr%6VCZ$GL!3?1F{dvE<^hgo7_j_OFJ=Ftk0gzAxX1y_^2PYJ*
zi|@La<sGOJUh3?O`c!EMDC&G&MO8rk`(;PB-?YZsdq!1Y(f#V(Q<wU+f9~RcM=TsD
z0TGNb*<qYHDVVKZXzsZ+`FM{c8tQ+(k))iOBC$Sjec*QOkZr--^SW!g6nBJ7aA(i|
z2o9c(GM)c%T++67GEC$atxZ&qa?ldp#T6fJ<g9c~d%h!ayf(DF-NCI<R*@92 at 2RUh
zKcIfTPdVfu7?f(|yNyEV=%yH-%pmk?x~ysD2KJ-^@JGgLVe)kcC%>G`Mss%A at 34O;
zeONfXnd7+A;7>=&(j-c!H85Vf(?}KdH4nB`uC%vwgA&|t*J&t^#<GM|?5i1HDk)|C
zh&)vhqhCEjC@=2p?tU`bg~YMxLWErRgjEf;n<~5X8cP{BJV+MSw4_S$FVHIx{uq}4
zNAs2LI>D=gj4(!LiHOFc<M{GCAYSg3c*nM=Up&|88$nK%q+>hq3&lNartkC57nM?G
zq_)lHL}4}HXgjzfTb|*sS&j#0hPwUR$XSZ9{NIC7250unP|EviE(eQwC|6LcqBE#Q
zN3`l%DqR(nS)=S3)D6nR?Z!#b?--;4a6+Zx7;k|L?I)+-%Af`tEu*k*Pg*x)k#_sv
z38_!J))&bw78sT;fkMJ$MzR?P?T?*Rts?z*3AfbKr>d(LxyXU#;>BQD$q;Pt2XL=c
zjg`U0%gJ{4=WXYYW>{}~?n<%yX=rNF$9sIF at _N9*A?RBGd^!>fOptp$>^PbzXtPwb
z)icj-<sNoX^Rlmn6fbA_GTpKA(9ipTaDF{=uTliSCt+Ds0l1&&;OV9aKkWC`2k5Em
zdvX#8$$Ofz at ITLrSRb8}zyzONI$BhCOhyXvXUM<%8aH7RBea1}MC##MXmCUJ39^ly
z1}p5_wU5j-g!xcfU-7D<1PV&Q*oA1A0 at S?Vdv(uNu12|RY_3c{E;d2kI(6F(yPFx*
z at cILiNan($5kR^PK!7V6oBgMY!!wV`ugNjml5fyVM3EGGZ8$YHuR%CzK0*gQwGuVs
z0fHM<CPg3|3EFeGEz^U+6!~pN(L$=TRs)R_BoRUWlkdrQV0Yd8WsmSKhY7sy!)`w;
zrg>+W<Ljq(1YqT3DM{l^?j*jGFV+$g+E_yx3A?HNmY%qk>Ou-`rU-lzV{rMHK at M4{
zxREl26pDgHU4lfl5{(;w8A!D99Q})ZxsW+7WeQ0}s<OUQRbo4exz=kuZBVevJUkV-
zg9J=}$ci1Ecdr5zZtZ4Q=seoYH$vdXX3h^bOYOm<rakrAPYa9{H at Qoz(;l;it7uR&
zC_JnSB(mV0pRt`l4PR9snc`O#h5Ktm&>-VYuP~^NEyR1On5nR6VyY8>LYnw^WJKjQ
zR!j?_D%*knROsGe+J^?<F$99FsubEYS%=1-{(bMHU_C<lmGR}BOIFt?WoVK0$LgkY
z4nna`6UC at fGgJ<+6lM-7XM%15v2$_FXP#le#NYU!QS2?f2#Y(N^5jd}$QJsi<wRc{
zVM7>h3RM|ONy$awXHI7)dXFWrH2K>kTJy^homEql_qnIm9UqxJSy)ZKDx5AW9t}@U
z68CaS4>aIno2SHdBnkX-)GOgm%>`C*QyIdfj^ztPKzj(CFAKzQfDuB8)~J=QB0Tg_
z0wXXj&?7Tq7YZv_R}kWM%Tx`sT<F$MkvH at q1Eo6l+->h<^QKoLt+M)y6dLTwdss_<
zhs;WG2rUk28mx%!$#Z`5SEOC<U_o*c|9#2%dB=yU<FVcl3Yn~sz?sdGHkt4V<6#iS
zTU>}^x1oP20B}(J)F8M{V-t7KpSm)Y6DU3R4!x9<c2iGC;{8`uVt at 3QWGR{el`nE0
z_rOg%IoZv{J6&(P>)ZA#T}m%v)Cjoli3)>u^O~U+^G8Kp=eWG6d%H3cinH|9)J*Es
zFOYvlF$_*~CnZ^55;Vb?+ at w1$=lhMV(B}6<Eo%7CnOe5TaUvZP6q$$8Z at RSrjT!Qg
zQ4y3ZLfG%6?_g^v!+O{$k`o|_xoa<+I@!6?Q2Btu)Cyp%rY5xq-<p-WN^l1QlhLM6
z9F^?vRiN5bQ&^4W7A{UyGvWDPKnM>SNZvpucx?IhFLo5a=}qqCwVfUN#W1dUQd)0`
zFu<<}|K%s}PWoTE46gtyAPWKbE7<{pX~5M9Bun?c_GL)iOsG89v|@A;Q}{=WVG(0j
z#dYC#y+bO1cjF`94r=%Q&)?I4m8_^)K44fR4!TJX<S_pg)=K_Tu$;k%{vL<V8q%U!
z-=GEHb)st%Dd((ZEg)v(8!0 at ji+s)H4aFn)y#3IQ2;TfHx{{KbHsF}NzA$jb`h|V-
z%6E8Lf=o^DHnHx`%CDX0y4DZy<ZzvxhZWLst_}H>oQq~JY!$$L+%BZD;5)6*xPfsz
z?$0@}Lqr&Qv+V#-kw>@Q55Zc;P94FgJfT@*47!muX%&f$W^M7ZLFnx2_`Wgp%@1&E
zig*5rq_ at Yo=bpp+ReMtJ?)9_WfPN{sP=U`3r0*Mk3FJVL8rqtV_1}MMACyftSKz+@
zgg`Z1j+qWplnfKzFKnZiTM=_C_n?+1el`h)FE%9S>He}kfE;6V%AWSEPfIhG+J}vi
z!o6qUm4*kH2}kG at ma3y&k!9ququDstGCWn;{8tP5m5o>_NShmsrIJ^{(@P5FhfHqD
zmkIE>!Q?9~45Q+W3m1+a=R*HliOG;`s)TGt_NTgh0|34x$scD|Tqw<fdI2}*zCVUr
z8-TrYVF-8)d#AX20PExo^%@%Z>^Y0?A7J12)6N?Ic!QN-qp&pmB&Ymv5!aG?3phhr
zx}R#8VnlhaZW2B>f|B9O?}ohtTF*QE`u-yDnh$a=e)>{+0_oSqe;qq7^Sk`8ZR4Uq
zbrg`aituC9n%$)H)QK|cg2z?;W%Qh3sc{0>0Kf3!?i2U<KF_*GjRGPT*>SB1k>>l@
z+(nYQqx at J*on5q0?pT6ym`ECWH#e;-yl`iiw7~&cuqJU2rhp<e|4`@VfizO9u^Wl~
zx5o|goXIhs|FZK$KT_jP)ui;hTeK6(_lfLU5=uz at liWRzf&!}ibyO{=noO6126~-x
z6!QtzLjJzCOx^V%WiO25dskAL5o0o~)2Sznz9cyEzSdo6lQ62?-eEiKVVUtQU7zKt
zW4aWjAQ~H`Yv^4pGIzK;Tcb*@tYE)9NMmH1<IaepEaFbVP3#{5$#|w}&wU;;RWj86
zWNfgo7~}PF!?CHRiN`^vTPQdsWBAW~?{+tv8sPvQvR9!pr$&W;xXR<U|8ua73_9!r
zg>JFssRx-ghZS&FXEM??+I8z!4WLF?(7OXLh)#ks{d}BftZ^h9<0sZM<$iD1%ai*h
z%6x4^CK=gv%^T_mkGU#}^3TvMhc2cRxZl+|jQ`Ix^-HKQdeP&ZO0uLf|5SZ=>iyKW
zyTchJ<zURNZ}<#aqtX2d-u&eOU|d;H+HyP1p1St0>JLzu>TtL#K&2Xfx&{zDHA7!F
zSphGED^<X;x!c@}O7oF|903UVKcy<Me<?i0bz!C)O|;X!l)Lu;*WZsl0T4`Uj(}{_
zF3UzOVqHN6rS)<!6>Hy&7?<jfb3Mr|9X_`Jahfy0<kh2*il%60m4)5~5uQAC%qeE?
zh;vY+1zNIGB=cMB(SBM~@kSVOOK>nHU&jZX>+I>uWXbuNfv`qHs;HaEr14|u?OGEO
z6Vyolw!K)>sH9$EN?A|ij)|7}_tF9Ggsa_=ED_O;kFcj`H&FYoHB%|1Th#w=aLDj^
zerL^gPKOSak+q}!C%C4(&j(knv1aQ0+AkE!sP+^cKKdPN<^2lfs+!!jMkDo5N{;||
z?v9tCcb}4Q+1T6gZv%i<LNyGtK?QWjd%y0u?`IRA2(O^6U98gj2&eU<RFXGzh$EYq
ztn9M<VMI1TGr<0=E{gjX{8i_6egZ0}p4GXgEB{kmg7QWPhLf*o&)j+pZu$`H6#Vl_
zt>zdC<)O_VKqg$Am^lwKys490Gg5B3Z8RR$9G|whjk=L*+{E;WUqe5~a09tBde70w
zHLJ-#->qa_dxJmj2*ZXRLvGF+5+X4z*PMto+j1U9AJuWF8xqtr9_n<vo+Kv13PJXk
zE}Mp at A9vU-ds=#<kyP9dds(t<C3)1O9#aSc>li)7Ef~`;;7zE66eRq*Z`-MhU$Kt(
z6a}@rJ;DO`>4xhv4SQFBLfj^VMms;o3858=V#2C%qgLtA`#5?Q!{`GKfi8Bi#pFGg
zdN~Ndq%aKjuoY;GfQJ32W}(5DS{_)nUltLvP=HD5&Fhr~q^J7O3&j51YHG0J{tb;{
z2C)JS=qsr#-~v-h+#3*jj=DG#uJ5{xYyIhMetVgANTo3v1cKI|@XWk6M5t;%4M*oI
zR&O9)BML0o1|LfCIl`Le$Yx&S$;uujaMp at MT&ZK7RHK+klD4K^jV%8Q_h~v;2J=aF
z=Bu3Ba=Bsb1;zChwRT$n&{1ajz|S}^k7s|tI%lKS>6EGb6Yw6cyNmgIv#Sff3Syxw
zeze!r$=sA#|2?&XYo*JK>Ly9i4X!^OU;$}WukGO8--{OfNBZ%C;d_e?9(S=A3VM37
z!9`c}V at lP{mg7gx0y8mR)Ul<jz+AZ_tL+ at Qr*4ZV;MEhDm|fidQrWw4YCwxVoXy+|
zt`2I+emRiAp>sH{D{HD!Ui at D{-kxXEo9L&wwY`S-s^E?V@*g at ex_|1ULIE7)+j?Dy
z${xR3fx$+C5Qky2)}Kc1AZkvx86>iF at dnC2;|Igu at 06clgTu|NfL7K{z7CYdBCx_9
z0v0W3nyW at Vri4=*!;A*ZDZDgt(gv6CYSCNVBczlH>IgH$yYI3<+U#ztOFyxGlW)!f
z&4(+gisF>3Mrrb2Qj+e1m{ZnMII)d_L;0)11?oG_hd}C6bNLqM+?S)d`0m89YU}?9
z#b=T1ZqReUY90&#@TC7E*ccgqG+5;)jNDnCHVtSw2hbddo9vFMZ{ijO26pE(Z{vZj
z4Ljto<IcdVb%5+iEMAUveURC&RdLK#b;j#hQa|LR3muQU4>u|a%K&bxEq8!B-AGgs
zPH`tV^dxxHCVd0eKbvRW>~mZb``^`4XB2>@<!u1_iJf16g<oMYh$Kj+?G+8V>E_!a
ze3G{wrIcvJq@;w1H;r1kC}q{!nKPTon9ogW#gyjnRqd!B0f(n!QYRRftyA++GQa<c
zk~E?mPouqKtcIZC-5{o_yjiJ0l(%a}sj8xnapg*@*)Z<|jwp{%w}iSi;Xg#W6bfjI
zLp<L^%dAqBaZ9bGYHa=u2sG!|HRG*lJ)+aBQ|kr}-jffyr$>HLV7A3&S)+ujYx~ck
z&_Q?W79kp_0 at D>dZ*?7ZO<1HuGzqcSqfvuc`Q?KBph9ac@@DlCW7y{kyV-}WO61_F
zm7Jodh1hP&C$bn}W7c2 at TY*xhVj at -Ivq}&CjHeZ#iJ+g5+sHSA- at CiJ^a`y5$I`i9
zd(7p#O{G^>%MpJ^zD6*2k~<9h_J at t(m6Mf_?&<~t3)w{A)a+ETM_^oH<FC;JhS*+3
zYk`<~oX4E}Sd#pc72g?|2vRD#eNWoN*cR8m*}R2)Y at cH}15=Df2AS}zo|XYBPX<xp
zyECnpR~Sj%nXJP5dMqV%PcBr1A+eaWP)eXcz2>v7d?C)&!6B_X5_+E;pwed~{rjBy
zw?+&-t^vK%Qi&mIJ2KjD8*}$y>Mi##fw$h!a>G-vr-Rrp!1pc`)J+`R*3p}t-3d$o
z^8)m+`vkkSP92$)&$_Mx99V!g%LI^JJ@&x29ES)H2BQ*U?Byz80rLH_YW=&cSaUcP
zsC*V5ezBCo at Es5&MCX1kj(_b1URC)^Roy2-3y2DwuwT99nYwH!hHd)ICTAUYOc(B}
zvhH1BP_wzE<$iw);*O*5LJfzXmBg`!>sV^3gh`x;)H!Q1pIvn|rx}-`K`^}^r at 5FL
zP*I|3YcEq>sk1?DS{Z-S`wWg#=Xju+KIN`gQzm4by(5~u0#$$7ZtdRfI3V+$>ICyM
zRm0#*F_o<RO^{kS^)zMB<is at 18`LM*iv}Wl*wK{%3|>1c`n-L5$-Q1L#>=qTu+B%=
zey!BiYWn-iBK7TRT13;I^&%&S!XD}d(0jw_rb0S>vG({fL&gVNEVzp|=(y9T?e#SR
z;d*xJvVk|!USrweNpw at PPPVr^cnWH+x5nHx9`^XK%dwlO at ZO2m*2e3re{I$DJ at -at
z at T?E<=kDG}(Qt#@45>Ew8 at jOu3~bil39ltneFm9BGTFM6G*3u8eta89XKWpCoI81@
z_(aNK2u{%cl}`-DAG9d*g>Vm!C4mfun%c=4T?)qpPJNTQ8?tu#I8PL^7hgP_r1uj<
zhJlcTfarN9S5*5{zI-5e&s1=Tv^8VP0%Q$+S$??2<nytuhkafQ7nJb>%x}iRqizRF
z_zYkLG=P4C<cN9s+M`L~zW at x>*#!uwlva*O<27$=1D6!YF{K!4_>@u5@}qcO6&GC`
z&_c;lF|7170w`-9Rbl!DWHU|H6e0dQ`qJ4x7JihT^-`z4A}Wi>vQ5~QsRh>Kw;G(P
zS7j-whrZ{L-825g+HAY82>hInfeK_O9nSwYatJbSI1Y&My?tpZDX_(9$(bKB796^8
zyQD4*<;7Lg9#DAdI1+_Yd}aE91ozmEZ8%Hc>?h~fE-Qy&zNe)Yi773d9$G164<YFg
zF;2gs70HCJA`xS9uR~)=?fJOil?KM2eJn{_<=iyJ1Ad=_(zbr`lhouEzAc=5Lc1}S
z>y~lzIOVabzy7bsef3{QI0muP#!2_rF5<3h7<wNpYm^jPX%wv&x^ly9Fw}`VrcPj0
z+%+q7pHx%r)d}4_cJm;^A|KV#_4jocdmi_!mFC!M8o#s^_Qz$iLt>-ECfM?NP3FZ~
zzoV$JE;^p>;6o2;kK)OjD&Fs8BZbN7j<&_y^4CT3g#vt*`*71(*Wt0K)C?}@BiyOZ
zyYE-^o4c6~IZ7IQTs@?TJAJr_X|A49S7pQRK5nJAa>T|+dNa3BUCK;$t#$=7j|Vz~
zj^bHAqE6S0Vyd(}z-oV#a1wj^G#Bf|Npm`%?%!?Z78_GywN$mw;L^B(kwIoPq=?0R
zS_=4kl}l!%6nmrzx(-^`#8>PX<j8|!6CA85A;~Q at P02z|fK$o<TD(5_(3dL at Xy&r^
zp9HpPJc<b7kHD)Np2hVWr2s$AT+B$5!CI_rg%0Y?jS~1h8)Ms9spnn!^4F#SLj?4`
zCZL3>&H)}{0bmQ8|7l?2iOKBfuhP01Gt&Qh=CF13c@*(<eVzgtQ!Uo7 at 5)1oIK=aZ
zm1vlBzSdy6ZkgA2#fJAH&q`MR(agJWRX0&$c2>1|?0Sv}T?c2|2Xx)B+YjHwTRco^
z+!GUvzBrcp8CUT++viyWC>dtqN|o)#%XiK2^W~Dvuy~(iR4Ro&7crFoGghhTns@>i
z!@ZHeMNz6A$@vIxuYS4XzfgPMXH(S>o`|s$BTn6oO7_NDX-qEtH+SBVm?sIzH77}D
zH8Daly-^+hg<Y|Ztl&<{-j)XoiIU5hNBe(NBQPE}=5$6%9>~5Zz?tkp210eGyaHNZ
zFc>E=-xTY%2}Xpz)`px{?#y|7L+-!sTfaJ&Nr35Fo7qbuRpAcs4s?n&7bmjbQF@*o
z?G$lzYwY|&7<5u!1|c_MK8<5p$^=R{bvvNvI%nz|RvRN_oz_L&>+h$<J&)ZNxt}(l
z*!jBuohmI`l-8=wN8U44xeree=}%x2 at M8bWkiA1&Y2D!0^1)6q5PuG5-*aQDOCQzQ
z+XLi+M`~}_2&`_Z=tBUQqHmBf&GyDeAx0FDx at mG^olx(-?3s<KHt8q<eZZ=MD-%GT
zwH at BgkWzHDbx<CMiInxEU=KSOOYrOe3+T{s`$VU3ofgs_KmxT{s>?zLL`<Zw#%2&N
z2oX?f8>rB##B#hW(5!t?4vJH52jDlZUrrPo!=MskJ4oxXx3U%WUF+Qz={>qlZM~zb
zv2zk$#>lC$8$De(Qzp-|bbIQV1)Yk)-0;dV1jpc<%)80Bxipgi*!61h71xR#mrnLB
zHQ+~=GhNHK0 at k~KQvOIs%l|t+u1lEWt~A_7wxJa at Sd53p8ENS&h+OXM*XmE>PtcJQ
zbd+FkLk$->D9^}1!Eua3F1uCme>I(w_B-u}r2H^V<ZK?+YdN9L_v^?msqlzyaKpvC
zlxNGk(h&p2r^OdHj~V8W&u`7!&NS)rzVrzL8VepYjjEwIxXV%Ov$#5~yoV(yDN3zt
zO`S~hB0ykAq3`Y8Tiz`gJ&>FpXio7|S6CWssl}@ndAO)(n}!N<sCrMQ09lx7!5Dzi
z2~Qpf^sOMS?hi;Wy6aPH|7xQ&B;}!Z$vT>{V~^h(BwRrE|N9(gQk)y7SW=h+|E^-N
zo9XtZ@>rhFmJF~}Ni@&r;9bR2V1$5#MI9;k{nn?AT4)ZRKP~NZgk;9{)B{y>v|M$<
z9j09y*2}&J0Y=HnQ@`I=$c{InCMUBx9Jh<Xi*huiQM!87v+4OFh1jj3{`jvO_Bz)t
zYs3r7zJyZg-xO7Qe$JL{Y>yWD%AV-cpX}RMv~60|nX_#NMS?n7kp`<)2WHddZ|7eQ
z7Nfcz|D_>(uHYnmE}Wfd!Yay}QqL8b&0b^kswLTIUINsd(3?Ka;aZ~wR6?1<>U)nh
zwD3>o;*J_lZdXM&c<$NfSG at q#?Z-I)&Ad351IXf{etzn;b6JzLxrf+n)S3<cVf;69
zcv05&!=B4MIp*jXL&++2WK}Rr=1xY!UMeBwt+N>d4iGv^zb*r=!@ZQ%*ne>&{KA59
zdI*k<g@%Dk1LUg*<nbzye!{~4F;988ZasxJOa20L8OfI`MP7_K?D)iCX23ZHu`T$s
zxZyyu%i7-3N_fVe$bD`SF_t^z1}XC|wa#BNa%`!iKYEUgTZ^R{hHFbcCSQ*d64z*u
zU2053#8wk80IS;4zaM<F_C{D~FC<?t;}Vl{_yB#q*8ORNB6tm+h5DBFGPz0*_xxnI
zz<$P9^JIYTv%m#z`i<(YOgUNY-W?C|;TVU|W_DRF{{q1`LZFjwoGvu}&pDw5*UV8!
z`N(<&^c_qw(yizd&6s-;R4ikC|Bj8K;oZj&3H}+(TV%#!T at q!XUEnrU0 at m~~2WTp@
zW%#KZ7vSoOk(qkXw*!l47u{Q_A__ at Xho?u0!XlpKRK$%xgoiI;IH`FVW}m1{nT<!)
z4$pY$K{CyHgHv28xUcz#XENgmFva(m%AqeCRxT>t{Vk_0!gK%7Yn at Ac|Hy?>zyvq$
zEJ at C2&hNkZ>yk0SS!?_-ngdz)|FL->dM4SmtKxksEiL`;&(jh)?IFQ$QGc37 at +Lga
z?#FEFz7r1Z+ziagRS_%p>wsI-ce3n_>rm<wB;gMb$yFy9r+)Uxl)>lZ?pUCDvwDwN
z1J$~-p8}P*tBnXC+^I&nwHk}Dh4tm9BtC-TH5*)pg at NdmEzQ3MkNq6^8<U$VH*2_y
zbw6DyQX6i{*94W91E|Pe#73KP|J3(k3k!f6ibLqU*R5M+))HZdI%5p^<L10N*^5Xg
zo~C?RE97W)<wd0NfwzMu2U;hSNq-wB--qA*=!a#f^0`(WjBWfx(?Di+sExjC*<nBX
zS@=B7p=LBO`8f6B^K}WMn?*0e1$@Y+na<`4Fr9O$OQbah9xj*Id54D8)NG|ayGxyv
z7D-e3$++3+M!!P^1cRQiSb;EfdU;77Hs2NiY%E2K37fr^?t5MuGl^JG{EajR&*@OI
z1Ijn_lZ_SgIf%o;2^&67(*MG_ByTd;Gwv3X>PzN<UO#+SB#6ffmjwhV&83Hb|El(4
zY0L;oTks(PYe}Kt6XJR&qohR92JA9sdDY-kq_;I+HMf+~K0AbBDTz|{$W_Hooy<zj
zn}COKLEEGjn;z>9)2<4PV96Mj0R!83;1OTM0mpJpSBKYSdp}}n6{dfC*B6afJ>Gi-
z$<vZ*<18iX#qprjp1-RbMef!&N$<#WPfq8n^fVinv0n=q_9l~_*0U&@c-$LRf22_G
z`JTeZJ|<I<NfZ9LIk2&QmgrhK(CpT{DG`YM*gDa_8XNT9Ib>oRAla|Y2LO`vt>63v
zja~x-Q!WewV&H9KnFg`|hG}Rn#U&silE2^wRD_2uGo($KFM-;@1hv&ybB1TTekMF$
z!k^i)GH<u#>;Fs=GIa!cLrkrcJUmK&t*Cq?I%)!-zmfa~r7xB?zk%0HFn<Ei-<yQ;
z>~||_=Gnk4bCKX6&~}hA`WV$Q2+!p<gM3ozs(8i|;jH-rU#+6v1G*OX`%OYMesDmK
zz`gm<EL+6OFy=|U0JJWoiUce1lf%jVr$ZBqS30zqZ-Qw at rq*HipJ?&2%s2c8FeOs3
zcM at Jv`2(vuM8jnNMaFfP4BcOTpa*FCpAhxE-5V&(8 at Ds{0LqwlfH3WI1b{96*=C|;
z?ZJ<fM0M44gQ&LD=*V<keE0FOZ$j_fbm9Is_G!I8^(OUtX{tSdlB^pKL?ay-=U|YH
z4w_xjCS%4yzha4l)9&dqQz7yvyHBWb^M~-8G8H#NCLv$P@$cnTWL&facW#x-I`3mU
zd?LdppkQ~8FSV5L8bmqKZ_2*LxDiGFuLSK!-I702^-c5QpYfG>r6- at XY&E-bJc-Ax
zWeK}Vp1KFGdqChZEi=_Sj4LD43LsnAqW-DX)<@JASvK)??p5xHcU}ugJy%!6spB7y
z>e at VQ(jL>iq_7db(&q4C-`o2y`iU0kV}T(XBg%Qfk#^5}-kj(MvuiNsnXWYv#f9#s
zGHFBB>L26Ova$QzRHC%CG$W4(1lIwY(P0ZnWbOrnr;QiCp4jcD{l|F6mu)q?QeO0)
z;?`$XfceI6Gl1ct4N?Eb+jo9IoAKtq--p!mrnQ8GL^GCV=r-^I_V+jdMu at Qa`M(}?
zfSI9bo4XaTv$r_&=i9%P={g1MRju5QGcim>&`h9 at -B7)NhRIW<d=((To!2AeAlQt2
zU at E7V_XT88^<$3HOk#5YrRR*_UC#&}CWPnnIrEw--!FqR{&@b-*~TcP1QNV5o=o(`
zY!Bo*kj;d-k%fWOxcP(Cm?ME(<aNw41DTV!>Ue8odFljgY|JrUz;3=6F7*6t$6n#2
z#({$1ldk+FZ0g!~;@Jd9Jma{7h%D&hPo_3w%1)QpAmVrRO`1W*9#i*!A9>T}2LQkC
zOW*8-ASE)IYQ|T^BJQ at NwKK}v at o*je<yvDuN4iCLq*^;T at T5(>D-T9j(X!wCnd+m1
zi8Txofp*TGez^QAyB5kbgpDlO(TK#?)~O0EgqTzrc^fZ)6&mj4rr`S(jk9fTg1uad
zfd`aFJcb&afTsS$jd8Cr&8|iKfMUq2s45p2jpO%9^;pn5r=qCrEO7E^BT};0rbK`2
zmQhj>_Or0a+IJ{om80^mVBpd<zFSU<!>F<z5TCTazx*w at gF6Niv46inSg&X&!D5W~
z=xp&saaeP^;l~HuTXFi0%##L>Vtp<?>k$5zfF5KL5g{U|$oQ-lB5ZN8KxZNudo1_#
zg=XL at A7$t8e!IygR!d+o;=?f_fkKUZg-B>BIbg1m8g5xbEoV6ODZVN|X;UWx8O@)q
zkc?2K_9!UBZ`)1>W}ptreDjo*@JmH=bU4}awvBvU6eWY_n^C;~Oy)1VJx`VK>bTd3
z`mRoZ!Y5LB(N%nir1h+hc$hGA#?|^2gw|Sn;y8V*P at i`%8)&>;AGPic-;p!^YO#Yk
zeoSS*ad+Fzh;M)$s3F0Ksl+gEq)|UMxH>M^vzB at CXs=UVgY_lzhu=Ni>hM$i=P at 17
zJAv$<GO1=VzXSpW>pWNjPEHK<YqV at V1d{a%tmTq<Sb8CDp8pY$3IShId5znLu`(Y*
zZ0W+p9y)aHzW&KsIlMG0NG5OCj4Z1iTu4s%v^V%QXdG2M+}t(2SQHXLnL^inBMdap
zYZf213 at M*)c&s%Ln&7#VlE6ow%VD<>JpHs0J6Q0a?V+v90wJc#bYl{&R-ZlZZfo9d
zT`$*g*iTx at N^Iewe$-Mz6%c)&BbmE+Ae-7g#=DmV?SvCy{cn!NNj=_CJIQnMV!LTg
z*52I!Qb1BIaf~~6=dEQx!Poavn*=F-NLe at Cz>&urXa at +Dm=QMlbXcI6R)Y-Dumq0U
zbwybcD9fLe{c<f7={ENYj`B=RO-hN$hDn$_uCZG=&GkV84-jw at p8Q~{ZyXd~1q7o>
z^DoMO3)Rcr_{SL`F!EJ1B`MVyc~%@hoyJs^0A*lZK&ard4v?egkR_1ZelzEA9Sndy
z^6bgSDi#60fuYQ3fb&4C|2j#?S@~h$#o*~hfG=QB9T`dU`!naRxbB8AKrawhin#{d
zIh_}34kYz`lG4zy0|1$pTv4CrA8?5U at Z_oAzNS(bsb1ahhVU^1UWG){jOf0O$>YAz
z`gZH4i at r|}#QvW3Nej~LNv^-^bZMwtHi}RR0P)x*^ueuytiv6^n4;iOrio{7n)JV$
zu)V^+IwUX9;w>m$&%F~F$6nL3+g@`c55*lUI3z)o at ccz>2XZ&Ee8X(33OR{>!OqL=
z<0uiXhL)-cEF=BG*bWP#y#AUU^>7~4L25IJc>bVj$K+kVC}P<VIY&nL@#BZPxCb#W
zuYu~DRUYNdQgP at ne<cy+7h9?D8Ce;0Hv(F~QBSCmOar~cbgr3?rm)GbS at c;%SAQxY
zaghGT>|us~+rK>*mXrnbbpIr2O7yEcf}f<7E9+>yy;-5UgzK`vpAu{}s;I`rN22MY
z3!+_>Zn2rF_%^*a0^?rY{0)}hzV=o=VBi1Q54dkuR+dn{TTDU0qfgYe*5I>=kCh^I
zhkpws^))eXE8{B%nrLbna-Q74D0~WLBn(N)alu<^B_BZ9TEC}qz?J+e*8k1dx4-!3
zvg)4`2`Mgr8OMqls<V3>e=O!8mR^uobg$0H9M}jl(W~-rD{o2<xY3-Y$DIK-mbk7K
zfMO)Ly|)|z<>%kM`LrMKk^h>e8=W#D_GGrzTN3pY*MJgs)%j~8h4yq4EV=Ie1zxPt
zs6zOW$rYU^phvCVq=~-jJ6dNYJQ;;DDgYiSP=WHiz->=2xcyKh^f}wcVEwQYcY*3l
zA_o(dsOA*UsCdmVO6Zf453Uw~r-^HCpD8APCoBUQ<7EAV536)+bPA$XrhuRB2f&sI
zCRj!{VjiRAcNV?Gm2*ara*E;|S{ruk+tZ&qwu_?;dN^NnLE}{^$-9+slQtDy>RKMP
z^~9Hk8FQ4<=QYJlZ{ImYJ*20nXHKvT2uQyQs&wA#3#gkjquhUJhIXXFN&h+c6y46%
zR}tclWCl5T*P}kZO>A4PmNRFYqvfQ1yKk1kZ5@)I_GTKLyYPd4TT}C{BD!_5wXDIG
zN|2qDNoB9GwruwfoZmcaoZJC#j8>E)gTk9)xl}f4=GE#>@W^VEPJ_Wl0PN-bzWtwe
z&}1-{5|uHpHM?_qdU{emL!4CTk#)H?JGHRi2H0f(MG#eG at Wh`U0&Q*7;;9P`>NLG|
zf0I7iG1)MW=oR6y{hL$AnN`En$mFGdtU};Y3f=T}W|K%0*Ah1k+=@b-qZ&>Aekjq!
z%DOJ<ov<y&-j^1tdLh7jh7>)-WcLJ4Dqfe7E{+T6_L_ at Idjm@y(^}h>0YV^A_bw9o
z{UJ#Y{d%d(FTFPlcgny1nWqZ&CRPfkC?S)k&@W0ejAe6RmX^g7k?x*JZd-`Q?DC(d
zg7!Ul41BA>jdrc5cz{w<GVTvd%-x-j>+3DO0M8qF*T9<6)?K;ed<M^(rqze<S1^wI
z^GCSs*%)@h48F^$&mVAQ at yFEXbuy_+37pyo4ANOTf4>xAnb9wKphp{xuH>S;I9Ti3
z at jU>N3iNSa&f#`7Aaa9zlje%ME!fUX=V&)TabPzhBBw6;89b{E0YSaVzl1pL)VHYM
z9FB_Ub#M;XgBh8PmH<m3U*~WN)nUJl)Fn47$UU3OVf)!Y`!t*Ou`UhlJJmXfwpm}%
z!Zotgz*p`uJ}_|}&U<y^n$rmI7tvd;IrDRik_P9+%GK<7?7t|VfXx%0yU{7g6qX0~
zC+eSroQjkx+g+|<k2~!u!E!UQ_O at UtL)xEn)Qe4Dg__MaZ(;ZQPV<$#3dCNF*ip16
zVr8s)3n<M(Qd~K(m~o>Bkw;LmR-q<Wn8>r)Qk|oIPKN*<-lwxHdc-RfYC_a(1Sas^
z`pG-)malf7w;%^8G^ZSZU`i)V?;KQTHvDQrRLZF_M7gI2zMH-S!eFZ&jmgKeOATFP
zyl&v<=k4t+X{IJpEcsx~N;dB6pwI6KNuP}G6jxkexDn%j<w*Ud5LS>uO%fe|Ai-8|
zMoc^{p&*--vS!45WG7`KhRA%|6m<8Y%B#$x;A4_oKV$x8_*f&?tA9MQ(wedPNbmw)
ztWoRNVCQq!aZ^4c<clYEtGK7{DkGSomn7N*b4t+9;8kN%6<IhQ+{2qqM=MqY4thQ;
zXYh2(BtGs0st3i(bnI$e#(UWRH0&$mS55#-u;OwLU21*TJ$<{J$W at D|df=vUTK1FC
zFI{QVrJEntzB51jIw(L=O^p+%GgON&#XOx3vyTJjpaFrjnM5tX1MHwDgR&?-_yNe1
zUkg|NkEZL6ruzT?R#aAzSu{RIW_INgl0CB5wfElF#m$H$Nm<vv_U0P*y4RL1d%L*T
zEZLWgD at py{eb4#*k8>_Buh;YWn8j23h!qZ^YtqmuFLCRYiJw}n25Y~DW&eXUV4T_2
zJ9npD;0qf2+#x<Xqdh?LJxaW%mN9BosR$uEf{PptiP4l{?PTkG@>?dqd9*{h^ifaj
z_fy(J-TqvDu25#=((zB!6hxM}L2&k8fXKfbfP)3yjGmYwt}5!aP502pzAjEUmq%P<
zpU<r3E(R*!UI)VzAl>_Gj)^Hzep6=$N{zOUxTeN2zm|4TWPJ(zR)x2&cf~NAc?W_t
zj)Lj!i(0l-X3m8k*B`8Osd5FL?VXM6UQQ3?;Q}RaOpe!W+2lxs{W=SlT7%>nUZu#k
zAHTYqN_9rE-^`NL(WKSvaKEiF4iiyDq>kOI#W`A9RE$@jEh|qvcxTk#r!RB>wi%l+
za#&dd5~Y_OpGDeY5lY7CsfXBv1J0YNBHyuJt5K853dZ5W#0>U*+lK5Gm~jE}7(BI7
z{8;Ey<!W@{-I5-!2;Cpr3nnT?REDPkKibOg#YFgMdo%44k|@7(s%iQ8+3a~*7Tym7
zvffJk|Jr<FIjgL%Jutda$&@sh##F<30-&&-NF%MKSB%h^y4t3q2g;Ne>q%Mhtk6J4
z*PpGY2LVCzU{E~Jz470*UU^X4CIq+uxNh7f&b!=#rk1v!ncd}W<=ua8ZZsvk%1Ja+
zvvmQeam2IPYlwQ#H65w6Ak{%pp!Bq$(kkY;JAU=4ss1~@Yu7b%d<W*f0-9lu9RQMJ
z&}TLP>46(_7mNcfwI|v1$E%T$3ON7tx<MGCER+!{{1*4$j=E&kWRf}2`ghcuz$}V<
z<B^l}dWy#A at q4E72UgWelR<f2p3!)+c!Mz$Gxu<;t)S`UH`!gK5DB~Ek_C==ig~`o
zi-TiyRN+kd>y=7)eEyw2&L#Nqft?%NQ;OWl0g`9D*;@J7Lu**0<{KLBLm71<1}_x+
z&-D<3ekfjk?kZrzP%LYNrK(td(y_^4xrj)Tu&wiL2dhA_4!f}Nu`~$$L#Pcc;GcD0
zcRii-Ht&;GHP?$+3AR0|u<c?3N9P27<Q5DSGheDVFiYuVa22ibbbhgD2G^Cb;juM2
znta{O8N<<2oPy9kNQD|xp!+>3(<x&5gwC4kjePEHdKKdny1(8RyhlnTpet8_doV_%
zPbxKnrO9G&Np>DWR5X?`Dqsh(jg3kF+2^XvaE{XB{DfvTNXd!Wz4Y0~WAq;2DQAbA
zT{>lNyz*DB-OiWT+LxWV>w3bfbT+2q5-Imt?HW@<nzwXhcx5M4wWso;Mnl;}TuDG(
zdKaEMjkW}mH%m1O0Lx|RjvGMx-MzDEw!gD?9-3=*IP-Av+hSDAu?(R0Ob23K?bZPY
zr2&u`O!1ujmEVAL1r!(9r$DtC#3ZGGjlT~87|V$>O>!ELMK&dnwx*8UfA=P?p~1;T
z>Yu{@F<=LP!N%Y0aT4o1I^+SI&UjFWcqj~U{?U+I5(unZ$-_Vaw^4t?()bo`47G<A
zR?JR}bJ8vS44{4J^K}M=-GuRxsA8J3whk|MHta1vd}&F!v5HGP^z*J5{LV`yWagnv
zA>8V`H>!5BZAiu2v`C@~E)}$eG~V$;8ynWcTkh4V_ygd6z4(>PixH<86BTHaNoI8_
zb%i<u9b at nUIUZ(aU%x=(7T|vvmJUBSxsiS(v(s0B6e2seGIKM2kNthd%-jFICOMLC
z#-!qkE5)4bvMI$hrTc6GXU!l2LIxf8R$6fpoefAWSo*~B#Xv(A$A{_maHZ+fEx(60
z*rY9FnKQG+g34EWNHem at 6vJ`?;vN651wbBa)`j~1BAkU3`E6yjIjY!x&l#BOcV-vV
zT_fn|uz*7(^)ag`3=XqxhYohaw||_A@?JUq at IXg`YcG&*gx%q$y4##4Y%#$q793)?
zRCzjH_p|O&+5+L{<)P_!bKAetFl1iiY2u<GXH`$1iA&=^4la?kq at Yq<&t0{Tyi(g-
z{|=)+GlhdKXcM`UH4;MPylY}4!D>DssV}VJ`#C~~^^9kD#XTTpb!tF_P6Ljjb^cxc
zp&=){l_{v>7RA<YZ-5gRv8Oh_k*h`A%nGw;PJcelp(V6l15~lgPG|Sl-ZLPq<p%!g
zmIefUEw;RWPTw9~o{ZEQWH$A13^5bgpEMqmI0*VaT=7hN6YC6q6 at 9<{X&Zu%tpN at p
ztG;Ht&O;Mu|H>PTtw%Xe1DN0 at zR~2?)x<w#>BIJg?6!b<*iIV{k`K9=*5UEkY>&Sk
zyK4mR=0v9>F`K_tvlhsQ1shXqt-Y&RK6!g~wdAdJExkw6cCHC-gk3}tCOqtFWI?$_
zk>$}-*C|t>`>V$7vU0bm?D;Pt6)IN69nsWYum7^z!|i0_ at B5fOYw5)5u7jk0xBWAe
zeFwG)`|@Sw-Zzc!gOP{la$Z`Z(`nBq&R+x0)_Bn*0NKBrV;L<p?Ox|vHaS!vIwSbg
zh at dp|iQHy`T`7~sjlR!B0RN2B>P5=9JTrMx^aAz45qh}M<VwkI&raPn8_Ji=lg2j1
zP-B9k3V($Ha%;{CrcnqRl3#0igmB5 at pAAs3G2i5Bni4m?A`0=zYjt#ObALVbo(rD`
zp03*AcvSrp?r(5Cy1u>#ebio(T0yZeZ}a)Tu9Db}xN!O)5SgI#kZy0wA at U@bIz)$a
z|Hh1XM>Oix-xamV2~}KK@$!_fc*s%P$guYd3~990|CN_-DZ3#%6Z9Rr|LD;pHkY&q
zSA)Jbik>~QMCa~O>{xvzp;RO{c}&%PRfh#Xe_*`wTz6U3SOf$Rk$N--yPpg()xeH?
ztpqmQRMJ+ at v{_{d;vwGI1sX4gd;vcD97v#lh_pJW>VG~io+%8tFD+Cuo(Q_?YkuZB
z2%FpTVRgj*DILP`7&L~^J{gm2B;zIeRx9O;7O8kJj>2yTye!T5#ReJEB8%we+HU|V
z#x_Zs5kfU7=Ep!o7}*y;CLJK*<SiP1bEoYXfD$!~aYf_v87F+1+rGKk{p2=iDEKAC
zuJd_EwFsfotKor=8TLVQ<r_;I at EPn!lx9lK6_iuD;j;?2WEKm!MlqW?*HN8};-e=%
zDTD1Y*{0rOL=%?UpwIqV;I4WD9LEiOq`cAotuN^&&L~wA{GKu1 at 9V)~wOXXRijIuC
zds*f*10^{)c2Q1hc$A<7uC$JIL)Nh0(%j6xZsqhJ{hWyp!N%Yd5FNBq&WW>AzP!~h
zj#)IkJoDd2;C)^77dshvXVa@?JKEYTss3AvLcTS|^v<K^Fmfl;cSha9LLRX^^KD-k
zJiI(x1-N68kiR3V-n at -0fXI#eXU(|2O`3W_Zb@$yO)iVqL4;D6Wr#zA#`v7Z*R;S~
z<P|r+AkEZqV{_G^@2&<g)A$8GS(e%xfwV?vFoS#UasnmOYp<M?bz1iBT=kT)yyG-(
zK7zdMW=bI#|2Qf?Yvc5(nOJ=#czbO~Jl+3Qve*)29vR5}+>g<%Vyr*_ZCPn{*<_ir
zOJ=rL4=&cgy3}yR at Ln~kJ>x>%)in-?&xO^Fna`}&3&xGrsNXkC*an`F)+y27>`b8S
zOT at nl+(uS!qhYBI(QqTLIbAP at O?!)&lwuaZdRsgMV&q%W?sPB1*8l<Z^W;GhA)<Td
z0R8-{z&sI1;Ulf=Mq(s`k4lm=Cq5SUm3$0rs6u<NK+O`vfgp%zP%*7(r;`Gjs at K~*
zMSc^}%VobU?wqy<h>Q_y|G3Ez(B6AX^-O$AaLUM4nODBqlK(<5T~jU$Hj=K7^m|p?
zeYEw<uX%5L+q23Z_vAy7RYg&4{U?c6QSrPi8@^hx;#(EpH}2bAQPH&lLjnYs<OdH-
zi<XsS7$-T==iOe?#8nBUMRK_tGHQ6Q!00}W{4RRqQwhkhv8o5OYt%#p7F#=8^qAe7
zi{pgms&RbPTC%1D-&OD at lfJWKWRM0#PxJ!t0v9IizKWkIF)5uZMgC2O`=wAjNyztV
zzdw`zV;=KBDkbOFDskMLO(}&sfMSNBS=I&vSuk&s&r8Wm`k~xWBS{YXV^Bi6qeIP=
z16{5<e!kBN-Vk3i2)9zWRb?fZo$$*g#+<pGoDSqNc8dtzH%egLd|fV%-?{}vRSxW~
zm9~Y(ZWzx at KDI?I`v27e*U|2fdrmbp{fEH)#7gs%Nra?|@<H at 8wT<sK#v&Sh$?y+i
z&uVg7{pTsV2JbW;iLkT;+-t2FrBVl<a;bksX9+`Ge~e~k3lhx_f3zjah>FdJrf8Zf
zI|${2TTL<=t&Kovv8K&Rsn)an!9vMvtTYjTtN5Q>GRYR0Hb~#L+%<OvLE+t8Q3if$
zCCRa%6QznFJHOZ%3703rOz=O}1bvmBAaD0Aw at n-IPe8ymd`ei9_N~ZOpb0F8ElciS
zl|tNepi4r!FD%DcTwg9^MFWxYc99C^H?h!$h>d at w$rtek^fq>GyCTlBKIzu*D9tFg
zh~hz6cT=Ao(%|H^;i9GB#WkqWRTaV-%wPj36|zHpGcR|$P;2`7L=sJpy<VW`@@NN$
zraDy-Nt~4qXM+Hmyqk_}zgay`yl?D<7`9FT=}-U7H?Es84|6ie-tac at Wb3=%{%dke
z$o at uRjcp9_7CrCBvk=;#F*<XBh6je at tStQ}U=Fx9c^N at -Be(H~uI>`{{EmBVQu)~I
zuap at j+z#SebT=IzijtL2Nirosy_WNodVo3+84saG{?bTi`kC><2Pyg*yU{YLFt{Fi
zMg7=Jj4%#Xacfj*d8=6NHHY2Ye^*{^>|oL-o)w7r&1kW0Ah7dE;ZLxaLL=Dz)L_w$
zap(%p>eG;!Kj{q3 at CdXuA6@r781Whv<!Wz!_YVBX-Ck%l?YS*YMJ_XNhyy`^?FUPn
zkL)Bu=ASj(7IG>@Wmbloi)XXHVIdkXB%p)(H#JrXR(T<ttEocBcUrC0|Fd at k3*>D|
z3&tNQgbx35KAW(9tFy7F#Yr=Q)Y at ILa=AL12A00CkAH3kk&LL(Pk2Tv#xbcF17(~%
zO9Mn#E2ewQE9htVI5sZhcaT$;JYywAbGsz4_RP)!xg<~Wj0ltCcZqc=kBEmO)|Nkk
zcz>VV+}!2B{o6%WyR7p2VwvyWfr3nc1E5{J`^WmaBd!c^$F86;olOlrL!Pu5 at t{=g
zgUo})KR}k!@HI8+y*BF}F2Ofh+CDzgNoY|0&r87fec!}!$~~Frf?G8u*wI*)7}AQs
zHYKYYf`N)e*MW*A2m5R53|Aif2KmL_dS3rxHry&6&>J_KWSN`Oq24XRNmf7ud_{OO
zoA(AT+Oj2H8E`=Ohj+#|*t at B?yjHi>M|$dvf1^sH{;q5?groPF^F9>JGpKWr?m&GG
zx?kyYaApDMkKf*6du at 2-I#%pEezMDlvS{24XA8IXJVVGnShitF-U|-N7+SC?)C(^*
zNT0fWMQ{I}(MZ8HWL%Iu&})zxyrsUswx|7OmTe;n8aBpl?0)KKEs&t;D==|8LvYD<
z7szGEZ%}-3XkzLpgr$Dod<u!PE@>Qu=Zb}W5Ar0@!J2LbBDt2=4y?=it;f~^6+cU|
zvv3^V^SiwMuEa}y!42M4S_%r at nVwjKDJ2L#4?;?<PA3suic?V5tWzlM4r+tyWZXln
zJvArdT1}9m?0B#Ng~YRSZi^3sm=Rr|levyhWz?fuE#3GJ%Q0)j%gXSm853xUpa=lO
zzTBt?S3p?RJ&{?(p1RtNJ(cNFcCoo2y8F8~PQ58wN`4QR_O6cUUbH`BA1gq-zgy#0
zHDFMrwwBBZlq&pMUErOG?U5t`c7X?uv+^uRv5uy{l?2xuCgxjEGexmdj1~_|-BJ!9
z%aR1cFGRl(TCzf_>(Nt0gTGh4gQr<8Dh6y?0mEH?S^Elb2dyCaHbDxO)600^CDRcS
z!8G+y4e6eYf%EpC{go%^Kl(D(0i2`vX8 at VC91FnE7k|+~wS#`#8mPDTEBa^^5eupZ
z5s%UD-6U_43DnPSrl-rFKA@$N{tt~!Q_tUNbyN)n;t1ZIeyHci`~BEi<kdD?i2|{@
z$n)1Gb1=$lZQvb;8D^<PZ|_Y!g$a1Rcq|~%d4A}mRJGDDSW92$erHK4O5}7_La*_c
zd4m^=C9NP;0^gnR4hfF-A7=q+zd$$Y!+%<TT3zaTcd>^uX$|*cpFN%vYS%$?zZ(0h
zx4Vyl<!AV^&g9VDciiMRZ>Ze7Cx#(1EG|;vqY8dy47d2`KwD0i<9S!a!(0AyQ&}FD
zF&h at WDw{_2G_!Gacqb`gdtZ5~sv{r5^hxGjE**WtTupEP^>H4mXJ{F7sF@>Ij at -S5
z{X4XtB`?6vw at X1B?bc_q)w5mdLB}Tn)}O;DFrz1zLgp=>KYy;<BMm+ at v|>z94nk7R
zIQfseGI&u$YutVHSrf&lqR-hB_O+`Z`h#N<oIYiMp)RHRaKhx*tnx&&h;GqinP116
zGE{k9vW=l&@Qm>V6*KoD1XiW5y5M^uW->@HFCmx<ygeSuA at f;>aOU8aIlB at iN@Ymd
zzO>#*I*7 at ei#;F#hwWM at oN_4fgG>MX>#X&UPpki>27hR{mM(Xyz1I}eUu+R>swzS(
z=j?hS!aAwlnY)fmSZDAGi3eH4h}k_Py0Yx4`Kn#$!5uYKYb%|*ogylzDXL7qoWNve
zEsH5@&ps|kfuza+i~I7k=A&jc{$?(6fZ@(!+e7 at L$t$~OxqW`5zsP-pjuu9CzXP at K
z;cq({crgZzs(7z4FcSqC--8JJ#G6&Xd6O;$xQk05L?xcqbWj_~ai-UAUEXdKVHM=_
zdQdTZ3LA8DxLgRyl#ltg?W;*?ii~JHq!L09te+bH?XW)Ii56K{v=r{qtLhr!!Ya{y
zlrdc-!{)8np`j=p<G7^iNiwC&?_NXb7YF3KF2Db!c*B4cZ at IJPk6W-BT&Pkt-BjpZ
zLGwgoGcwl=C*w%wBC*Yku?_aC3#tv!J~9Ve8^wUj75DE|OSQ&rChG2LdvA`oo}Ah=
z_S%pI*oW-?bSSjG_GYy4SO2HtI?cJ_66UI~yH*}1PNa}us|S+qk1BMk$0GPwtF)_i
zDm9gKg5iucwaQ`8rBZESDtm^z=p!@)_w$Lbk3v>713gK?I)x%HxAmC5dPLT2$~~hR
z?SUd)Fwn#6Q>2k2DC3)4OV~erm-^xURZ-^Y^%jq-sP*Fa<!Iv`pLN;0(?7>PlGoe4
z<y7M54S818w=8Q#`~~4W3ec9_OA<RL1vGw-xY%zT&c%{j=Nl~$a}k~uE*|>@rhcgL
zVNB(+m2C$EvuQ;rAT6J*NMEuNCNW0<)6~3cf#ug?>&qI`=KSZK8%Gy6DG%!Lnh_D}
z9}R76mYm~3JO_Y}mdETZ$o=BLJpW3>EN_4HIs*>78~)FmJ0i3Z68=Yopbr)2nhK|a
zzB2{BLk_`Z!lvOj at a0{59s^}<3Lx)!19<lCSJ*vAyG&<V`T$jUITi`fM_L&NAs=1=
z!ef|Wf{p3m2OEP;9vTzx0QU<%m~BNzys}qLW at T2G{McDtTGG%}*9)+7^PD#%MB-@@
za#t?XYFJ`lGx=4936-N0(qx~5&hcSHihTKqqRF(sSBbNzZiLUc1|Ks1WhbsvEPv82
z$cr!?v`D!~?Jo`Yn!;~Z-M;&E?{~psfvBC;scM?hHSps)y1xv;CH7ITVr#d{foyr2
z7GcETyXw49gOs}%97%RNO$vcjez+?WoRx|GYn`V``Jq$S1m)2(CP_O(+I`3d33?BE
zxuC~*`}4GW`d*{AQwI$_yROrL at k2~x`ZWphMkWW|flVRGg{M!)wvMb9m1lmUm9=kc
zE8wC0wi9*vmp6zpDS^tZ+M_oYYmEgC=AXOV4RICnnH-uE^g^a5VBkVPey&(^kd*^h
z!^4ViITEm&Amu`NZHc&NHs)dDYAIs4*uTUB*YdACfhqJ~7b-_{U&60KbQXIas>?i;
z at tZ6SCv*K!b?JcUssHBa(#+y{27 at UB`;Wvh7XcsQ-`}*(z?=l!8h-ExaUenRgGgJQ
z=kF_i516&QsR0zOzA!G#J)h?-j)V(%TP5a?N7L70qo=?Q|AKkzGZ1keoUjY|0~jYs
z94|Gc9(Gx=T)qK)!1Qo+00ih(zM=7hteGuYY`}7WX0;Vz^7S{(9Uf`p_`vTUCF(vl
zPK-7*^*nJo+Fm&4BtFDGB<jfslZWO=8d_y>Ob_mN_kc~=y$pAKYQ9^N+RfWolG?Rx
z6mRoydez=Gh}H1^5t8A7cz7dl$JZr&=6+ at P_b5}!%obJhQJFWd&v*{%MyfCLIQSRR
z0R_+U(#nbrt3DDX&FSlh5ntRMh<cZGU)at6IMkP=c+tTg8=f`RN*^Y8`sl`>ASALV
zPOZx&R`_}y)QcN6J6vVTa&I=g;hOU8^e`EZN>*1e`SwBRXX^n5GQ<mEd}Rb%Lxm2>
z0+cZtZTtEXnAzROhpbzmI=0eWeoF#B3{*F>o{bi=!<sg69az3#z7#~lJ-i!1uav)H
z^~045eoLPO5sKkK9-qNh%}6Qz+YTPD42E2K+;ByaYUh?T`<Qbx59jQ6 at EhYKGdG*q
zgX^kXhYOl-$p)!Hj0GGTTySQyhK%`R4wtP at hqkd8C_%bNAjUYSziAMH`)1wj5C`A?
z&nuHRBQ>pwn+F>B7`^C$Zr+S$y+F0 at T<FMJJoQb0E(Yt|ai1nY`F}1-dyB+ at c%*qU
z9ACA6B4K3%F-=A70r+9f7TJK>CT0GKkF7V%!Wp6SRp!hEW8ZE<Jzsjw!~kp){#hn(
z>iS2LsxIp(V7W`;W`mmfc`|(uamEw^a&iXz-7;AI*?sEmEbAlVYeh{xkOv$98jN`A
z%Ji_yN!$0sTex at 1^7=<6N+#C*oBO}jQgYT9>OI6`T#T(wvzoRu%=o_yQG(v*Hx+$E
z+t*Y%_S-4CCt2D4YQyce(NCacoZR=~Zpsl?_|rM3Q8e~sQp&ppvgzEzy%zltRSl&=
zY+9I-toavjsr;NfWjoEa?MJMMM@{aTp#16p5Z#>fC at lQbr%$GaaUNL{#je at C9%me>
z_buFlZg-Zpg=7v#Jx+OS2I?K8v{1fog?F@=Im8XkDol5q>Qo1PWDqf=@rHQhO)3?7
z%ewH<O$gK`!ezJD8t;0(g-rYC;Rinfp8U>0)SAq-%oMFWxMD-fCl}^6%qq-;d;J4l
zE!z0*g;Q#UNM;@bPTEJW(al;6mK89&X1UmJ`rricNm_qbZ4jU33obG4Z_(_N)4r0|
z!LOrcF)6le^oOT2X_D)wze2DpR>|zP1;-As911bB>#+Y4O=JIJFEiNK1%6wr3tQ}&
zdtED;Qn~wV at ZKGxo!mtWLxc9{8S`r<&xf5G$(szcBO=fZR6fXHQP#m1dDPpd=UX4K
z5SK@)DL76Rb!~=JT3Hfw*NffO>qyw#jQN(I8Z!xK7%Vv>klJegv-`RVlpAl58a*1~
zGMc^u{|bT}zE-zsosdG8{%_xUe3we^MOSvtI;v`~Ka5_`fi2JPh0#LQAKZd&P4E(*
zEU;gAQ}u$rz6WW)(C+kJ`^Z;3^hC(7vSI+pAi5n+OMKF&q`{pa3Jf4|H3C3KW-2)=
zbnnkfI}8vco&-8gikuq~3do13hbpNImgP0FlGjpHe#d>O8BFNKG${-3hAWI^E--3`
z-Z!*@UT1!t#<NRd$EXOSw{Ui^FeK@{ohJiz%6~7q1YO8wQwSX=iX3vYmRA)lt>7nc
z9pqdhGlehv?|W=Jn{!z6nZlM0?|BF`#4QusnVq~AtsU~SVH_BEBgGA^IcgosSV?0l
z1U2hv2gI(zs6KRhR5mf;L~JRbp)o&y*3Ote7DQf at fQLPXvxn{@Q?Id7ebDr!rbAK$
z`}~vr5T8Z-c{Quvnr~S8Ww3+jw4_ok8mz~z2>*~FwKvh2HND!=j)bG57u?~y1qN7c
zu69YvhQ+|T>RGxH21;{oN2_5F9aR@`VLVUaZdIZM<pCPLG-z->Li+trfkVH~?H`q7
z2pJ4E$D4L_FiA06d`<9JblZ2D;G%Z<AbP{X5XPuv9)f7Se%)iB4dW2g#b@(ci8l&9
z;#Tj;9R3%aIQjZZ8F at fsR`0NS?RC?T?QgI#dU1^a8N-$I%iAXC9Fqgg{uxbZ^$r$S
zitZsj1K&i2%v*Q1Q{vvXhepsqgWs}28zS at -rRmm=fyP^eY=8#s`4|F)Yob5Tt+HMb
zA*|T~T?e~J%8Gqy4AhM8Rg=S!p5K7)bDAHEmOgnu<^p*`E-o(5uC}iO@|PTK8mi9;
zv!qdVZY{#%ZCAo6ffd?>1M9OB%l9A|L*(s%Eny9#0GzEiFPVA(k!Sq1te8E|`bu+x
zG@;&1E`>_G^hd=`D!55`U1MZD7fpj-8+}AacGB=z&v<2b&0^_LgETqSp!1%gDwzY7
z`ki8)z9orNM@>QFNJTePurpLZ`K5D?;;lyVQB3>KvG638Ek}E{T6&16_T~9Nkg)pR
zm7(hyiow2lzw#FEt|}od^JjC at B$0H at GSz8;>hRb0H0k4`7eXmmvd=mW>n7O#-L!M|
zx>H$^>2#~@#Y$$)l51%Qozj=l-xepDcjtd|Iwfhw&CxZT$st;dxnF<u7;{e}w~1Sh
ziuO<&t=gS>`$Luu>7$YD#_>uia>TU64>422io4jC<Jg?qYsSxaoS~p4ca&Fc(E%d9
zc(podk*_XSw8+*1Y$)74(H0Zm3 at a+etl>Z0h4qFVaj#r_5jBR_@;zoK2bI4R<hK}c
ztOVXV&I<I#D?JRTm>D21+RyV{Z}JFT?G6)tXU(Ge_3GE;ANYzbFeM}})u>7!#-oHp
ziZT~jOJFQ3h}C*8`$;EOIVE`-LqrR)1syuyhU at U??tC2j!dY}Swi8us|4pQ+XiCrl
z;ulL5Lqz~WVaW<zvgGCYJY^0&vixYFP5h|{k6=B*+Ajg3Z$cQrF8fVhF~nQB at FH$K
z1o8vgFDs(Tv?rHkac`T7;PJrUeDfCq5Drf?t~0FI)prkC{Qi3#+K^>K at bh=CiZ1)k
zs(C6KYI_i|neOeq&VcL(23$eu(Ry1kLP2(^%L!0AhOTCVbHr}U3wsZuKE%{;-*(-4
z4%sQoH?8QEc}r6h0d;SiBAR*C(mr3%+sxdvTliXMYd>or3(e*ozM;M1?Y#4V5S^|s
z^$<256`|!Xq66AepCC{hZwMkxMDVMD_~}F4i0`|&+H_kG-|WGpb=}@h<Ov0V(6V@=
z1>%s1iRdnM-&e(dbFPh^6+=oun5xhOnU=i2fH{Z&%sF>CQWwXwPPRWd`4WANwf=~l
zW3`t#?q^YXD(q$}u$o2ME`XW3B at X63P_|fp+W#arv3D=ib0A+ZMFEwM2Ge=hNM~n@
zVA9<r*}>#NRte3PhiUXcKCy^}&^Q<R3F}}c158&l)52V at dm}aUubZ$mw+ZU8jL#3N
z8`E~q at mhRjGSXVs^A1JAx-zw;jIu1J=NBFDTMaZyY~6!0XJgv0-0kb2tD%o;YOi}4
zPyJy$`%~lM5i06wk|Wd_REdqOzF3y8rp$|e%0*FrGCVXf=Z-o1Gd7pSlp=q35TqtD
zlT_!JCmQ0g&UGCbqO=fT)mYtYwtwd;*phqr(X|Kpzk&Ryg)Sg{N`619!%0Y#xaF(s
z7aKIi;2(5Yd+#UU&#wQT`Xulq>Ii4T2G_~u>Eleg>Ih`kT?!Br#kNDfpNnL=#F%MU
z{)lhtc{a{agiPx3jWss7nBnPOe8fXM+)HUn?VYq$VNvuOApHOgQSo*ejlOCyn9$3{
z#})*A=1Te2<Qqd)Y(4<NFow}yd1lq-4rycP+t+7-s?Xh78tLD=Du!W#bXQEVB26)O
zF_sU%N(8Nai(jGs3oigA!CIhRLHKu$bza9L?v}aCR-3Z6Y%A}38{DM8ciB_!*zI9i
zo&V1Ca<m6jyDkYGTIP}TZWPh7Cr0RP+ZWl*A_pNlvzrG{c+*2I!UevywoQd2pDy9R
zB3|P$f>fZXPs&wz_0t#f2od*nQGd?p+Uxvr?yI~;6d{bc79w*NGdtO;w^0S$BeY*6
zT!%`i9B7|Rf7qRpeCtN{&hs1afj1%%N}T}6x&&xcAMw2Lf6dDyTat07(bV?9ndVF9
z3CRSJuNy#L>18t1G!9=|$!n~K;VkW+pTE8MVy-hr_oTV|RwC%mnBXyk$L#`0IcH?H
za>k1hqD$CwizPu!Dt!QTtcK#|BR6md#H@(UA^Jn;2E>G|`iUm at Op?ooJSG+|{l<@^
zS2V7O?;V)tH<QaL3V(in{TF+>Lomzh;Rz$2F-&?yHH4L3i~r7Vfe-`{vuf~j_Sm^{
zryj8M!DiE2HriDGnWy^K@`|&8Fi}EE`(T3)J%g{Dyu6i05%z4)hnY(B`<|6sIso%p
z`uMj&8qsR`qQr8nO=cn!tB}iBBolNCB}nf2z)3|tB^6=U&zsVKym*=S%!;fgEd4VO
z_}b^{<nrG8jaQAy1JCiiZ%cE3R{FT$ZAAGwzMoPl!%9d@*CV2ty$s?0p0ww{|7!sz
z=SoQodY at xJp{$u1?9BUYu)lvUXNCD#u0S5_-TT(K$}ni-H?SV>ud^};2H1?ZC<Ujq
z<Tw-i)LnXL8|;ku;MCj61CTFY0#eX_zmh0W8o%7LXV$*4EY0?guwIfkfaeMQCqdz~
zqC4$O&qtX(^pZ6Pa|fZ&B!iZqb3d8c7fh+lQH$><f0X&&ySLu`--p=<O%*YV!b at YN
zJmTh(>qC1PUK$Lc?9`oqYd#tI2Kudm?V&6;U}gr&BAo=i!VfGFD0-Q2eBe%`krT(x
z{Y&r1A5sRuqG?>!48fi;`RD*Yxwbonf=}e1Ru5wL^NF4}m3{z6iX|KGHpCrheX#ws
z at vK)f$smpMR{2wajcYrKUD?!<+7fhq(9+{SZq28Q#q&UL&Cz<TE3(+xK9yMIF6D(s
zN(r$stE1uXQMG*Ge~4sYn321NfMLm;6?U-cX>!k{(Lz#MBc(8(<5<tcNmp>8Ga;NS
zrCBqKFwLY;7F`}KwqJ(w=e=o=tvk-Zzp(3QCf&K*SNTDrkYN at g6BSoooRc;Q%G*=(
zP<D at PpSv95;3E0_s%8ZO3diRCkl8<fdZ*pmPUbVaUA`Fhw0hCHZ}D;^IRrKq_-<WY
z&OD;3ssCvI6EK{&0`2ia+J64B7eME2lsx=hlY=UAAD2lmkZt4k8>nP92h!3oT28>#
zbEzS%$w{1twa0+=UW&y{>HuZSSd;gl>cj+L0ir8K8OZ)jcQf&4GXUeTEbb=d{|L2W
z?Bn9Q$?rk{(gFVLcYvKBI9dPV<0)CTvP+fqj|@20Jg<F)XU{q^K1)a0Z4S|~YL{ZF
zS)*C`F`Oc9zyE9M*&zYAG#^`XIK#>kELj^^@(>5j9qP`OKZodFb*80YltdC|G|F at Z
zTm7Ono$R><9RzmYV?DMf)S?gF^vcW|VrTx{jQ)OH_1f45Ph`9<SN2Z9QuGh1d~Hs_
z5;w_w6cRNf<L%Ss{iA%~RLraYv*XyaYaAAr7b2NK^clq_Uw5Ij{>U4U`OHC2^6A0r
zKOASlXKXmtus^h=12?K}?(01nUebKd`T{OiPGd}Ct%glz<jQJnm&SrKHDjqb^+2||
zm$eDCnoA9QjZqII1tdM4CSZ7LlCAKKv!`Gkg!IL?h^5+=|1$63Yu7C~87Zo+^T`n}
zTjYPqdCt_nn!!}l`@`PIkpbP#2`wWHg~lE(ypluOs??*1>a;$tWt at 8mEHCsSmaQ+G
z>g(su#rMBDl#L^eYjuN6DYmKHO2Q~VYWB$9-j}+$1ex2ZrDg*KLcMpsZ*{7UkN52w
zzl4ii)KvF-*<20W;dYYvFA?|RJC6ePrn!8C!^!gN7ug?mhDv$mv<rK=!fp1~0Xo~A
zS?Jy=-OdHjZ<*QN&RWB9aeMFDD<PsDH-P_7E*QZXu+ITfQ>XAR1F=rl$rwY)jClH_
z5d3_Lm6*6Srxf^k^C at 6~9E#KV$ou&{$jBc6b;o4C{QNev!CgCD%yi1oAwmvr{`<^>
z#h_{kA#@D1A3kdhbN?+uys`PO#Q7E=OxBI|(osLNPPjtq`dmJ;wdXLM%%-R15FLU^
zqzD-fa<3ZYlz%01xA{pLmkG1$9DaOZy;0LIBI0kM_?SVhfAJ9b)dcsBv|M64RG%Sm
zp=tKDCPM{i+y4r+OiJ^;pnY1NA@;zBe&mD8TRD#C^$I%hwh6z(imYvF_0MNkj90KS
z!?L*Nk$~gypgavzZOFe7q*Jw$ewq_lD1Q~PMd;NvS;UwvILE3~DlcOe4oY8WPLvuZ
z#u_3SF`}Z`MIIA#6~DZ@{4Rt&<wS+{6u~9;WQdRQ6XIkvCcO>r?S at t(JT|XpJTxnj
z3)vE4l)T^g+|R$IqK2S6Z1DTfiu?FnyJV23rs)IQm)d8}h#E`Es_KMEl2|o%5i|3%
zbieG_Fq9#+bN=r$;E9#qYZ|R%V3%@+PLz7TzqqWR()})jSKF1W)b4YvN%)CzT3Np7
z7)bXzOv$U%c+Q!nyEk~MLeu$WG~x<BVkIz(&F+EleaGr)rbR~;Ei;V|cC<8>Lu0=f
zbY8`SEb+j7(cumwuzPy~cSDdB;`65L!REYryEHmn3HF4v_u)zzdG3Dgjo(0Yk#RrZ
zVPR1cE?CpJcr7^j>n1 at z{)c at 7Fb7BY4QNP&FaBKw{q^x1U=s9;{dxQbbcY89%-2M~
zJQGx^2{?7z_F+xR73CMIQO_lM<QvR76l{c9pnJck27j;;_1X;yYuvc}7eFOzh#i at 2
z-T+xL%R2@$^j_nrSXkRg^TrTK;in{Zm52qe+L%fO>tulj_ZI1qFxpZ;tBhJnD>g`g
zK4}y^vf%HPJro*QUhfT2cAk1Mr0jSwtORa75NC2ISbV%H&%Sy^#Q6wS!yk!0^~;jM
zS1<O9jo$aPAc+|+Itqkm>)&(2h67BwUEoa8MSFOj at m<Dr at qp<~a8TMpvH;tQQ}aQ<
zhfpUxA6Z3KX^?a!@^#j0ONClA*J9&0az}I1$eEC<)cOe5Kyc+{-I?Y2`)d`8kh3oK
zm*l_yEQHU5RR&mC2%!D&O%4iaEk9-XgEFi})u`0>>-`d*vb2l7l-YbVIq}w%%(G~F
zT}S?$jg63wmuy)y*Y_hnUuYpcy;kZOxB~gW(kAWT at M0K<-Evy;dS)_6omUXC9R7r{
zpL}OX&hbFLb9M)}QU9I!88o7Q2WyCFcVYe`|JS&Cm=hYF{APxIlBB&;=-6$EW+1m1
z<+TL!Y1gD%t^AwDB(-^1gBW}=0-OSSxJV~}Qsv+eKtvaUF~`+<LpuS;1f&dV{a=?H
zNUCC9tQ(P(B62$&;0;L=K^-~+7HwCc4-+mxO+Bxd0Z}Nrw2$*53DiV#OlW_~4}_{2
zO0P^R7J7EfPTuX};<MMSJ2O8Bhz0FQ;yIr*`vRa~;P(mO;po5L=o{<6sHy3ZvYgB3
zH^39t!_}k47dfPsFb&s!nO5_y@#6QJPulCX$(dJfyng%PV|CkyB&FGy*|=W(p>qyG
zOteTC?bwY{z`<6!K81#+KeePxC+jMeq)gH#Ff<rSmrk3cV?3Om-azSi=f&e51uS34
z+)lgvVgAosJyc^#3JOyS&BKi^^;J3~9Z`1Gl4 at ipgr~9Q!x#r9De6EEB>C8j=_?(h
zSeG3IlFxj$KC*=OOq>pq9^kc|=8xiHN&S+`Aa^d at K)J*@)75J`<x)5Yd7Y19O|fM5
zmi|8GUGZkjwn$$!)*J5WJDQupO;Z at 6cZ*Ko^oF)qM3suk-<pxZOUtr06pnk{il!>#
zDi5KE=;8ACsY_*#KE at 7dX@adfuw0$8j+VVCIGps(uN_!Ij^HTL;^cJ$UWEouABRfV
zxHQsHMV at r^E{sK1YC4+0o%WF_ at y2AaZCw8DK=kx`&6M~18`Bd*44y=>wtX5WR9SDn
zONuV+3IpbzDBcGWL583AhBtkPfZyOst_Z^hJV?tA_TkiXtsqDX6qF)b?~S<E^NawL
z&VmOQPB&-(&jvDdDq>4__vnBYe$9{vkQEjIqC!f+$7X<0jB0C=UmueM^Y^baIK at M<
zkiX9W<OBwk=CoCscz$Ym>w|QIU*U7HItI>DYRGqwbMKhLIgZ^`=M5*YLhD_tpgt}V
z=-2XxFd+D21>01F^9Amh#}M(h7*I#p1&IQ>XPq- at ws7(ZAe}z3Pgd&1`m;hkS6r<+
zc0(s6|NBy*a4G6|yTGJe=D2xlw4rhuJJ={|uZ84#-b_;yZ3u{=Tp~sz5#3capGVCh
z!+K-la|CJ`NCpZOwT<$CcL(2dlWaZOka at 429sgx0aW6{#snu#0P5Ei62+-aZ5ayq~
zc)ToGY3yAK8E-2YmdM{vm&kAx-+^B1nElpbVuGy9&ZP%}IyJe4<G_Pr?B at ippj#t5
z_JRJ7B%TNjG)o&9Z7VLlU({|UGZfjYi0ye(uRJ`IcG1odvGm&Ev;bS{ehO!M@&R|i
zq>i1!_gj}xA+P6TNSdo<g3kiEN>WpUC!~U|zlQ@?@J_6g0^TE^#kWkkitB9E{Zsm^
z{}~$AEm#d3eS;y}=v5@$@K*LL0mloGUhn;KH;{N+f86Nqy`J at qT=g~DCF#Zd#o58Z
zKNxYNa(?CU!mYMB at yXt4dA-2|QFT~aRZY-4{}fOjj<h<Lm_MD1iW1wX!{3$Y%8e--
zs!sk-jooYsJzmk&vpGSY+%Hn4bwO7W#`SAwlcTklOI8PfQTX`x9pvd*mOwx$G7G>D
zg5=DB_kzbo$W)Xl_8KhVXn*`)Q<2X1n$x8eYE4elcOWCWg at egwa+~5T(5*4k*>NB#
zxKaKwa98k{xjf8lfG}iSgI{#N&QOQ~X?6>2w8VgTOupYL{kG_?z7a<11!SCXeXp~+
z70ggM$sql=+|5MO!I7xXk=4J3DTor4+-4LghR2*Y{L)^_einD6gmx%q{t(aS&az0|
zX}PEPP^f&)Z<f63?jk(vDxzjdrA)s&4k7>o^SuaiiPu2{N3U~cUvcN=mc0)ND0dM3
z at 4I{`vg+{F&%?Dsn_G at s-Rp`oGMu{cg2$*S6fs!z(CP2XmoH66KHvl#EEF9gA2GKa
zhzhN7`imx&gd*R8=wGd1U`xwp7`uKtnY%lc1|imvR=8tElRU6wlApHolea74|J=CU
zkiCa}UWND-nU>b+RlT&*yzJOWwe*Yz_MGZBzKj at B6+luBk+(RQ^T!1 at c%U?!d+lRC
z)1<AO1NJT<7XhLB4v!Ja^`~u3_Y_UMeJgY49qb;d3kh)Pm6!eHENxUx714O$7SlT4
zY}OE7$q<k3_KL0;ACO*y;hg8(+Yc5MBo|Dq9rpH4jd1(TUtt*c6M(%@$%TmhaQx3i
zPLpRF<>F+=a?1(dA0V{F_m<R#MA<rYgmIZr?so;e%e`mv!2Lfi9v-Yr$E$OHr$<$C
za~aNseiVjf;Z*?Q1{<heUevPl(e_hY`Rgb?bcc&g at 4s|ehR`v<!o&pl$`qTKSNEm=
z^;LLl7Go%iZWrx-ouLV#g|dS|CW at IyK$ni78<U08;J0RbPQO_A)vnL-Vx*Yuu_wS(
z68r-w*Ot8Mr*>@&3~)@}mfwTq#?Rz5JD<!i$V>bNpusja7sUkiDT#K$N}O*j+z9Z1
z=e(6SS%Z8uhF~y1yUFs2bk5qX<kAsbiW^<)bTqf$2_@{jS+OeC_%K at Qz6(U21Va?P
z{en<FyrQxJA%{Tn7kME5;VdI@)weS}cYdd_>c3R;o39d1{ohxIT2f|5j at Ut+8cvx_
zTak!zj`oqkz$z1ancMmI$`<W5I~#IDdcfyN`OY2%x_oJ~jSOs#+6;Kd(zK;(y%K*H
zi-J(iu}WNiq&7$I>y}>5)*<0ahkq|W|2-=VfstF{@sDge{^5K!L+$Q+9#LybGr4?-
zR4MmFCsUci{VHuVQ>wgAl`=R02+e7`0BYQ>d|Lz?GZn&Wlerd5q>s68L{TbzB%wI-
zzI2`)`tVLs7T_MeV^b%dX*0=&wH`_E-Xx*-Gv__(Uo?Km_>n)$s6pQak4 at EXynMv1
z3TC|Gg5L0|eb2KHh=T~?+i}iD at W{O)x|-ydj6?rOCzpFjXXM9_KYJWoho*R<MgkAn
z?yFK^$MFhM2ZLS?W$KuHzeQJ1EA*g7 at U6n%-^c$foPVNtrj;sK9<4Ye&`_@@z*}7q
z;#x;^JfYunMjj8jdO(+~DPh#_L4lFU4=Y~%KsG7&Ab5XPng&Lp*otMkVT_!O>I at Ip
zfM>)JV+^P3tZljH_Vv8 at IICxJY22Q}t8-TtNRB<=jBq|Z at RZt62Dam;$r&*2e{A2T
zHx2W}N{=0~!E4kf?5RWFAML#Cv{OL0 at X_H0)bsP7tHi at gjJwz0l+AXy`L*cvk1OF9
z`;}3$DO`R7V;G>eiq@{&2=LMIc!aV-k$@X27omar5$dt2B7vs2 at SUQ1p=vg|jryru
zv&09Y9}wQE8gEMgIz9>PqzI!;Tt#^ra*x^KhQT85L$s88^0$d{iYs2$r}LyvqvPhz
zCgq4#&%uPCNc!Gzl1!|VqSFKJJNwKMb?l0sFLr%JF-Ib7v>k!2mHh2BDv)c*8}&oD
zj=Z#|FR at D|6`og3tn**k)0M#N6>!`S&1Xq at Zm4|cr6Hr!uVZ94-w845eYRvv)TK!8
z0 at 8cS<mKp-8!Z!nd};~m%WqJ1&oIIGqhD79hn52+j}H})jeKPir4mHE3&Oq~($Z5J
z at Jb5Gj`xldy(n91zc>1%!no$5{bS_Nk>h?U{wcbQwXW4VE|(ah!6Fns3m0lX4!CrI
z1?+k#1o)#GY_vF%gdrs&T!hW=sileeZ&@<f`N$S|qrtj8baj<ZQ<NmLFU=*~%WK8W
zCB}7NxpY|~T{H1<^swY))AY_~Tw!(!Zqb_a!Yqe>qb)Uwqkm(ms$bqj+$s-1{%4Al
z9}E2<#a}&y9`JDkFO1_p&@mVSPy{pOMe;pB?NU-PNn?hDB|8!UWH6Itj()K?8$!XG
zIc{b at wf$I~LI4qlrJgKuT6Vihm&!|Y*l>C1T;Gd_?@b^kpiLJ6H;}qMH9lX{df)Z>
zTnO;aL{LH5tAOi=blJmYUB;x4@`9F0^ViEJ<>%m at gt4Cs9ez(L^D4yScl)@j*#exa
z>oT6)3O2 at J?;+!(!dRT$c1+Lm at 63I>Cykl(W>xqr^=5Lk<w`;6yrN+&JgvskQ6hQv
z-R)Z<LLlR|2!1_Ob&J7Tly%uT at k}sgdUEjTEzKA at 0;)0U3gb7KHlk$eR`A5on?Ygl
z+HKf;SDp at qQ%_axoRwztNaO|)KlOLcH2W1O)*(;f!kh6>_c$o!d at pM+$okWzEh^wo
zW?pO95%9RMg$e9m)(;wieVLJC@~&UoIU#2l#T9Ob(+<>6P;n#UV?!lH7pG3xT#E&@
zMcJLISPzMC<b%lt`Jwyx3C|Bx3H2I8_BLMcSv7DBrgufDdx%_ipkFyWQoqiKIm$xJ
zbaQV)JteYVG^Mvi=_#8UAghUcNXu0R`ME;M^#8;;ag`#W9exW^8N|gF7F2V<@ZR%t
zxv)L#E??gd!hAuyncId<=Ss*mnMy4^4DR{a2!rt)cBb-tdAc|Ru2pGPx7|i9Nc#IQ
zMe=o(RkcEGujPjVI*$lGN$dE4+X)^F`UL&9sWZa%j^>Rj;=`L;+IKlF*FKWI1hISI
z+BLF at fkQEl@qQ(-%%$osZNbs(-wQohwqoKCnTrR>G6HCb)T2dfKo4`U_6C&WF->Jd
zGyJhh at 2C;oh<bEU4}8rcusNRt^YxlsL*Er#l*ABVTQZm>T@?R(DE>g4H*N0 at 3Ruh0
ze|%$cRsq6JUxv;JxPG9N3uvM<LXf;;=~o(@W$szjc!_zjf<Ikwtx{~|h5y<vy!7I$
zLYC`fgYQ{fNKY@>)zDz)KJ3s~t)7<pM4z5?P=rt}vgWVc_o!~`jd6lhCY++OXqhAo
z5EkAhNV-DFfS at KX!x2scunNZ)u2=i;?Z{zcuao?{x3Mnh$R&gA!HO?0zB&$jz4b{h
zJgLH#4>hMAniVWy1|us|((Ho%ORq2&TM2s at yV!aMT}-{8SR`HV<Wv^Y_+}|r%H_Xc
zy}-LTosst{xIiz_m(FCGg^sQmZ1veI7Ye$c*Hd>Hq)QDb927 at -?8aSxlo%eg)8v)?
z3Xwhm8DWebi_c7Su3GbdS#-!!ggkMv>LtB`>I}V;^-<z$lDvt1Ij2 at 1R)_g2b*k|!
zwNb`g0PW>}`H%a$B;kEb6A1Ak at sixdCQg@6&7D$sz8b|=V~^%vr-K{&<zBzr^Nn5I
zHsk*}P4E80L81lBCq9OCgD-h3bLNFFT`vi{F7t_2l=pD&@!?3VO53#~doYb9mQ6cO
zlNqw$C{&!Qv>$hTe*11bsCsWN_dN*P-^;~6(7Mh*zSZcnLL?p>JleD*&-5 at b`6bfi
z06Ss at WKGR6pujmMMK-89yQfYZhyd*B$z~8;BfhO_MgDpGI2Q8H5NX(8P~I~?*TA|G
zp7yQx4>;T2tNCTXU#UXbwT~K&y<EHv5kSnyvgS!bL+V2ldyhirE61$F@>d1~{VA7m
zu)Whx6ri{g8y{0Ps3|q7Ybs*-!UoT*S46Z4-SCs-xYd4 at msO@H!ET=N;d~txj at ofU
zGmK1D>>+OF_1anurFw~zb at oE@?U_|aCjGKZlrqC(skr0AJx9X at v0-<Fk>@l7^7o?V
zb)I*Q?8%p))-Q1Xh1Qd`o>;9SoZQJied1~2xgpB&Xje9+0y9$eV!)uhD{z*dnVnH<
z!$6{c`h+3p*}s{0<`g7+FAQki)?A)wrspy;L+&nrqK86gs`u?<*%t5o{QditUHopE
zF;2+5HDv=;BM-?$)%#wo#4Rv!>}=2e&3?20r?u3oszYIa3Qo_V2<C<|a`af7GrxG^
zs~cA(DzS)Mj4q^1p~)h at 1UOXF==TXaL;ekAsg4q=w{P!POp;!CEK(JA2CYacenT63
z<HB!z{UW at r!@lRzka;3?rgH7eKVA!fu8kw&s9p+T;Ku6en6inUAit$crx?f85pMpH
zDAab8-Nk#tMSlr`QD at 8jx}lpv?79H*7|L5M6KUZxMw*ol*{9=o0wIO}Noj|UTKS&;
zH-&Y+QUXY1Nu7f2#?GZ9z-DDP0Z8_<o at H_gd<FzC)S;-YXHTmIw@>K=h<XhF2H>--
z-|ky=e~IDsg?|7r)~QGtKA4>B#P#^)aZ+_ZVDvWXLuJ11;mX>32O at c!AQmtgzq1kn
zsJ7wEGkEI_C<vHhn8N>)np+Vj&gU*f0N;T1_>h(w_;;a5O553KIM^~J6DW|=u3ul-
zaXO1ab$yNpeUw0pzuJGfH6g2|jPXG}Zkfu}g<%SG|86b*GLAoZ;}xAJTtPFN!NBOw
zR!F9nXb$d@$U``KTv6IpX4D@(kkP8rNL8s&`KDNO4-?%<S3OIxII8|$KUm&18X_mN
zW5QZT-$sU207JCs1DviqNmY65AF7+vrl=#i;7K309~Yg~?Yu4uvO12w;=~)agB*C~
zCF{da2G-v at 3+l=JJ+o`HPF}rdh;7>NxB4n~(%^e~&vFB~2VOdLEdIde_3pHD&Show
zz_yW7%QL~#%9wv|*{5#hFVz<18G`|Hv1qQjKw#(pc+9$#4Fk<@kxv<$Qr;4FKA~z`
zBE0Uhrb_?BI~2aD2pZ>$C#i3T&%RynZ&;K`zjYiYctDV?)AVq1`WTn&MAACt2zH*y
ztd6 at Jt3!m5j6Lr*=U&3Dv84!}xtGZ5bjX9?uQB#p3eU<?axj;C#3ZC!?AMBMQ&n^3
z+q~9`OE}eKY2=QBpL^P8Qi72IkdcZ|@~4H~dJ_lAK_3AmP$<iQk;NujCJ4`_Pv$9i
zBarhmk2A8G1sWJM2XKjA>UZx?Xm*Pb3cjI}7m%a&^eM;Srk;SUz#0OORfeZr00y6<
zCQdb}df*yL-Nm?62dfh7k_)7a*4=mi(MUmnj5ovRu`2LX5xb8y2;z5YK?lH3PJRW9
z$aA^kkG_w1_UyE+c5hS2!DaDV#lo60MhJqL?*>g;&`bJ$iR@>^@Fl*>A9~BQOmAj4
z+pi_8PA2CkV7Nc<<INb)m!SNaAWFMzyt7*w1Ma;0=&w{YMbWQW*rycJt!Ee=((m8D
zpO<;{oIEqkjHj(ubUjm;*tDC9TT9~v#VnnceeD+z5Ibyy_I4m;M$V5 at exC-w!PmR_
zX^zNlKABBYYn0|qlaPmbQ;x~l?j(NA-M?qKa6kJ5|7}Iu>MU``^2%;Y(w9GU<%pp_
zM3B-KMQ at sf^D{)S=W&zh3z%A#{LGThxrvK^Mz8Cq{X9^eVTCRK-0;!=@pRtdRR90~
zx8-dWMTjVy2pvK~DkFOwTh=j-J&r at iR;i3+uVZh{!7<LU$tYX4W0Pc at Bgr`;`n~#I
z*XQSt{&1a3UA>-O&&RmmZ};l6Am-d~>=D~g5yN#a(u|ld{YF*XO4~UMZRYiqApLXA
zD?gcIn+iJT0-+af65a%dE#0J2%2K236r6G|YI*sz`jQiT*nUyrp8Wh?)ypqmEzGr7
z-M6k{s^T*A*;ZA23}A^C5-!3lUXsm9wUu!R%_Ps}B5B2fUz(B4`8$Cj`39=iOGb-!
zQMf at nUX8RRV2<0t0qB>+Yw6^|w*?=jTwH~psGyn2eiE;EMHl2sj78WxOd=BY)_`Gr
zGN7mZt`;~~IWy>(3;aUsa>Ob3sS7jXk0nBs*Ar8go6<&EELJ-2QhFP_9e)mF83_BK
z5Y^2~y!xSx at O?hPP{0|W+r6jX-sh{G%+ek(x_H#`sub8j;pIrcrpfNO7!<%InX{Q*
zd1v0@!dq<VXHqhiYqF>|{#FZMp5VT_C15)2K)8wJa%L83xN<{TYb2wKT7BSINRDNx
zx@%1xeW|z1>50PLz60jT!wKl@;?pi650V&R0SIk;4r)V5KV67r{+(VKaq)Y*4G^$B
zr;U%2qs~r`RUWBEwF7^J&Q*@D$G=wt78-nfVrJ;`KM^Z?Nj4|mfeU1L*_=yaG08?%
z7h(J(<EKB?dzUviH%sRn$3rQ73dYn9rwmkWb6?*utT-Ft_NNyF!ZXmMmj^*nAJ-zX
z%WqXkP*}VNb2+gtMXf8*RPJ0`^Hzmtx1^1s+)KfX{=mQ|<HVkS_R!l;V{l%rEbnAd
z6&yfw)NpvCWg~K&_NXI8=5h7)OUYhumhf`T&{RwbUZ=JrP<9`aO&xLWGyLav`O>yt
zWOF#@^XY0V`Lh5{grYvg0<%lSeHK02TbIcwu^RC|Er4s6IbxJ!IM=g7#SC7he=PO6
z;qS<Qz3#*)?FLut>Q01kTX|R~_fOWF4{a_GdysPu-leL?p9FvXGu?f$@r<5wIqYZv
zCI&X6FOrwsyR7DR@)AfxY at ztlT{WSeM%S$ecebKskCkG9Xxn9iuA=sEO${f!20kMf
z?zaUL826wuFAmJP&VftOtN}<?(t1POPoX(!!}Y45LB69<{f6iJ2}d0)&JsS$Wb|__
zraBrY|KhM%oJP#+WhbDD{bEVTj{2t+VRR}wF2BcBhXG_;_a)Cw!wkLmGT)y^NTl$7
zCT3N5HmUT&s8`zdJ at fig*Ax3658}+)K=D}&F|vc!0Oow+n=7FWlyev%lKlN(Es>?}
z=2P4&<#6D9WTbJGPe2V^n^o)~rM*9Q_zL#Dw*Q+iHY`W+{)fqNsX-cT2n0f%(X=Ry
zRNc>>IP<D$3>w42E}0_9YXbGG>uy=QZQo_~O14fB6%I`LMThH|JN4WLO&DGs8FA1w
z%g8g03PU6WF&y$KTs8k at T;xTcF55h849=NOX~AkR{>5mzI-|TZggLi$cs|xhJ611Z
z at ejlp;@XihRg<cM82$_PPraCy85Dkzb-DUEv=Ez4m$%PaPuX#9it$6%8oO7R^;4q8
zsNFVCwNHz`I*t3vX%GDYblwzV*O!io6jOwq%}?(+DeC_=E80;!FV7!HA~|JV{?6jG
z at wK~etgD`LxTAJoLm?~r_FP;+|KuOX%E<Pbe6s{hy6l&7Ma%FmDIK1x;*sfM;2><+
znkN^8c7S=+(ze)?0~aCQ!uHZ4Vd1Z}``(0YZOh+|?Jm~_L0|sA)0~2fw%X0t)HfF*
zkAO$GrFg%*#@hw<DLMF`>rvYItyTCoR|^??05^EZ==7X0qo+jY4_gI<F;E<+kh%E`
zG5AJp`NUH0Ex>oMP>Qma2wZ_X{Zr8~%s7%hUru?}^QY5#$>ACXu&bG}mjkN2 at hNto
zQURj6ChWo|2gm&V&=Za`kw3Mbxh8APB2T4(H<SKPk-z7HUiW(ZY_-0A*Afl?{y;20
zCs~0$kJ$EaSVz0|%%+tOFtX_AaKPQ>9cA0L5&nC&kDP6mxl<lkF8#=FMS&Ku8%~q9
zOZCSQX(Npc#s^`b0qFOU0ZF*~Z!ngn6wH^4R6GCi<HyHiXV$SiR?1hSP{xv7A6k~y
z4`T2A5C3cZl??yV;wwo#o1nR{K#|eY%EGPk10*t0STadZ0PRtM%^7%nhuaC^$e-4#
z0a<a}pvEPi at zLxEJ*JUa6}PnMids*hfnH2nQ|qZ{hUbA1gpbd-6`Q4o-7R=ITCgn$
z at 3C0;ucs9pFF(}$%W8O>H;JgCUUm%|?GuyTQ|o_&^?mDU$o-7WAH2iA=92yF{nagt
z9w)C)+f<)Jx4Z6Ri!?mLwl6~Guzm)Yi*k|%-}9q2wr%7Hj6aT?SCu`g#=t_6t(^D>
zP`AUiinM#`c{7%*c~Obb$tFYjZ^~`GP0&Z6*$KYNjuf=J(AzvsLR+<mk%aQt8I)?L
z)2*qS&Ur4CX_E+-nfuz-p at rE8Cy*0UfzcR=0DV*a@)6f2^jPBW7oqx~3B>z0;(6C3
z?_4fM*eTEzsCDPhLI5lSHT219XA^cUQ7AAWj?@OsX583{C?7!-5=-uL-Mmx=uo at SD
z?s#?G+E-Ig<-uQM7KX2YB;d`8 at Xn+GFnHV88Ck#B#EQQ>OY2tL72ZtE2JQ at 5+hz&!
z`!^+sbsv4LdI2-RS)LfMbsE0 at H%+y5)yy{&_s&Nm?UyB>4YrF at CXEA(5!ET~4qPvJ
ztwC`;ae2y2_I85 at +r~h{JuI!oCz_P#Av4LgEZly7A`qQeBP2%IPtk|z(H`0LT7A1Q
zidOk^quYJTuaw at UbY@9>rXjUrZ1U at uaDfKjnD|(9g8 at fHUVeUUbaQ$gcyyZgg;ulr
z at XG^0mGyHB_`bB6075%;_p{@Iw8NlzS?j^0!94P<;?>7`sEfhZGi7!NQD}m7kU^w9
zs31L0hrT)E8 at K7Vxp#>w%-(By9O+GP(LDQ(w;K7Id0R`ysgv%@P*7pbOx{jOG<CO^
z?(+H2Sg`#iI@)KbHI`g1oTlMO;#`$6eLX{W;3VG8=9=5v(bEq!fl8DFyt(=j0?YA@
z4Gg~(%OtMwW6eET;>38e#KsQ+WfR#}oB8ok$H2CahAB?{Y^6U<MYHLUXi{2Bs|6Mm
zPMCPurF}a1Xh9=D*0EG!fR@!(U3-*Xi9$bs9kc`P*!A36Y49)Ya~p at A83^?_=CI+j
z9j~8>uUkAi+^g-f<Bo*+OnRB#s+6pJnI_{%-fxi at mgEN;SN7ra=bmCa;)MmQi-Fdu
zDNE&epUAEE5I7lQZ2Sae_DJuWEO0kw&w~*L_;jD!f0w+rc}K)QlsEwZ at SOd$m8|)F
z%j_HZR|UAM=W}a+0fXZo&s$PlpGa8r^8#t?8QZuO=DEJvk<Lw^Vec>&SrTZTJf6Pa
z;%d&Rio9gNfIax}Qn~6S8~ly+Zu0i$*BdMdN5DR%bB!~OWTU*_3N+d(2{M67CQnaq
z<21?@25+X!K9l`FAmJ+*l0Gjv0W#AHS)jl at Y3py&@W at w<lzY~Jzdcvou3#$B3j`<)
zgMM?RU$m;vbQ5W_#XOYVTD<H(=}mmIqb|j-L~)kd!2q#4^W*e1`dg at Af-9hH@p-H~
z#-fwkn?dmv at K^X(3|C##vId*ZwelA?PxEgx at lr?Ulvs9=R-u2>=!n at h;T6j$kI}sM
zY)M0BB+nPCcq=RM*+R{UDLPZgyYRe7SC1zP#??IXlggQs=T;&-3&&~4sP4hWVQ5fr
zuIva9+g&~0m<=gF!^-zwG-nX!Xf>if<+bR&=JjrQh%>oW{-+=2vDH1aP1VNliQ!W}
zV9ALZR1!tK*EFnHdL%p~{$|a&Gz at _vap@b_-MF42ayQ7n1hY{OxB39^<GXxgOm*hp
z?amhJ_3RSKc_^zz&fsk9x}<=Ur`JpR;D0KbQo#w-=N5N at +4n%N1V-<c=Pwci{m+t@
z!E*5m9(BiIdnF~m-0P2PyDnPKe(g-nyfD|t279c=X`u9mXr54Ov_+gTl00Yr8su~}
zIo71M9B>;YH(GL$uKl<1PWh?#RrvK-5%LY9MKU(Pajp&SRy6g_I3*T%^8~yw<IrQ;
zXMh^-x4}_9b)Gyu)|HrBgf>hqz*h^v0<wv{V#A`H8oondtu)zlMY^9CeVFoJuWL<<
z-m)9eLfLJwAhkV8y^dFhCOS1V_+w20PZY%bzfRa<h%fIgubYMU)d%-FeGrXhMniuE
zRRi5&bYF?6b1bRWl;~57#Pv210A3RN)lC3B5I;SUe%7Cx#o}7ykvUonmJR)Z;jw<x
zRDU&h{ta5#qWm6G=!OMk=SvPKE@&!qa99^lUDEp=?S!dWl$2j#c>uZ}WL4AiXs;9B
z8g%j{-23lAlu(5XBl#jNWgh`H#<qA;KKZ7rfZ<ikF-16DhRhkr=Z0UbBtTa1i9xrp
zo`mRu at YMucPK?q}+SYW_nD%m74A+FMhmIJtO>1SQXvp`)OHwhL(;JjbtkO||UJu9@
zoG;<F)O<~?L7l_NVwUYzL$fy=$WvtqR{H#|UT0cLWYBX8QvjFpez6uT at aYlr_w0#%
zH7>@|S1sT<*;A}bD${45gwG#YOu2X<C-)R4WG%(AncPt_1_4=0?Z3e6IPYNDQWzu8
z_g{6t*7knER};JyyqHwAzXt`KbcT_ at _)l*6&YDd>_U}G9D{JHgF)Rff@#(ztwAEe_
zHCuSNqB0XSyO;i<NwqITV?e7^5<EqM3*T2}rP-FRhU?(cXIB0uLqvwEBg}W at W8M?8
zKql5^RU<nb#JcRSz9WDb*X$;@<cVZ_aob<?w!FmI#UDQ8Q?f2W<ud&G-o1P72f)s8
z_cdOg6MpHs&wAq24W7T at sy>sh`?KfciVyLEamw)-#0ElKYXR|3?!pHKeTn&gUY0Ii
zqOZNX>!l$1#lfb11R%$J|1v>#GFu8D2YmUZ8=@!V$TZJqA_Yja0#}^;KFuQM5i(<3
zDg$5gR?%-$LIXO$0OFcGgdwAtGBVM6INhVaf at NBFkj;ah3Y;kX3~X&=%Q+3;<MM61
zXfm7p+2aF0XXO;IIAVJ4WXN|9g#tN$bn17qnS+%4Go$vRH_B>Vel{Ax;;g3JBp5Nz
z?{s<JhB+R%b9a=QrwDYMR12B&nVvWFl$}#|I`t$b3rpOxp6Z<HgwwxaD6pN9U#bK(
z37{yvbLNB}BTus@=7(o~qQ|jTyD9<O6a?kKSof}Eb<Fr|Z>z~{+MfI9cf=0OAxqai
zKabj{B6bo7(+PXdSNZK5KML7<*1oO at bA?)(U17 at qmfI-S+3;N4sH)M3!p`7=#qRib
z(8?<_2HxgV<hcz*k+ATggHLX+4fNZGws(Bj at ZP3zeqq8#9W|P4-pQrDu~qjNSQ=$@
zdT>x?pB3su8ZlRzryiniofVKwcJ!lXlF~NkcJ8upo&IIZlVdXu?zfpEATS~|nC&rP
zMU*>23$N+CWg%iL at nE@}3JZ`^-6>9hf<hp?yv6 at E;(`UB00Xd(nKlD3;STXfKFbHx
zE7Z9mNZP1uE6aMRerRM22b>S)?PqV^Dcdks{U@%BkRX0<nIHJWPQ1%NjK?PDHYotb
zu;I0mqnx)E%yRmGO=0)N6}a21!+51DYNlh#H;6rn6uqbP2fXB905ELMixYa%x=u$>
z9PgBYO+k4B=!ilsw*L4oa at dS8KYP7Z748pv-kQe6Ll4ROKjR$0#W|jkB$L&xZ=rsT
zKG~%H^0k|-Y9{tYX`2I*wUDn(=}`{LS<#KFxPr}f+uJeqe at KVl=Y=lUtG9(I&^ht6
zH(M^L0hOzy8_E8s^0y$V$2tjk1&8PF8?2fKvS;Rc0KvjTje()OyR3K_oz{SwmzC0g
z$_?_R$X~zi5*QRbQs(4K^|MQ-Y=x-96W1a<KE_o3yid at 8Ky)RYUqTq^6PXJLi_nQ3
z&-~Ur%fY}*wB8Dpa at 5zAj%0I!BW>?PIOM5at(?vDpSgbb14j&v$P<sOg>{%nY{&bX
zs&-~R<Z~~gynE$WXkQ}H0pE>vEZv;!G-0TaQkE~42sy4hEbw_?f at y$<b7$`SRaR{6
z;PTofJh<AEr;Q at JP))$Ssluw+W`vLXu`O#0zq<B(_L0a&Ghxv0G3R>M#=WN47VX!P
zHD;t%5W`QUj&SWHUBB&`>)5nGH%;5E9_>dEn8VDAQMw!T{1q_t_!vz}!m$f5&^a{S
z_{Kq;KYpWZrN{;kypPhM7up1ECH?a6K6t;zGQMsi8zND55}qa?-?INX`er|Giq!>R
z>tFZ?BpmPPCcjoz%A9g7jvu1L;BUlDai_dfmVblW%?9s;#_}{jNb4s1#*RPPcp9x~
z@{Z+21fZ{o{N0Wh!Q+0bEES&ZJLbJs*kCyz0EG|vMcT-Tqcuy$!jdpjvvV}u$`Q<6
zLhvK3NS-gAG>=>QHzt%wyn34ucG=}%cX=_cShaH`hB<EdM+g0~wUzDNg4u<NsgzN>
zx!Z+OCfjjQ_iaV~Fg;s<h1XGr<dk<@YFbAVEuXH&n2EeoLhr8{97!oT%;`xVO_X#O
z>L6~C-2TmdhB~d at O2GZ^*F at G65o3}SN4ePs!!2p*LEJxuudyc0b$3Hou0Mqlb-4C<
z7aFqpx|m#$o6XWbLZwva%bx~sJkl<pyZO8`v}N)?<@W;`g~=V^SnX#q0TO+BfoadD
zwe{EL3teqDg`cviu$(qTV>5BE9nW{de8|*Jgo4ZoAeBfvTHA=b7KQ&Fv|?N;DuV4A
zYvekDWt$fa4oNBku1R!qu`na)c>iIL%9zsS3gTsCixz$DLW)>q%}nFo(7S31J56bI
zV&?&n|A=XxZ8P=oj6(a_wUqQ(mc}(i*J_v(-a|evGCIZI?WumyB4d=$nY^l^a3(Ii
zDHGzOn!7i!@@lm6!&fn4g~#f^718zSsungyKh3Q at -lV1V+#G6o?euG05 at DnwW_Y0d
zNS=|O<|t1eFR8?BITT30c at G$I+r?ex5sfzkF^m7yn&?8HyE-Pc1KRD90iCqIGP#Zi
zT}qkr!9GpJbdn_TW;S5?bo<e2SHxcpoQ7H_$m_;L3wA&fsDrP3_uV2KqDr+Zu@^cP
z9KgL};$RGlj44jT!S8Rcr2KSV)_ryt5ElDE4lbTRT;jVU-!OT}O?y$$3!{x at bHLvw
z2e-V}^usc);9Z(4O=oTSJ6 at SG+Idl^;OM!V#de#8=IiMlYs#ZqA#xCAS%Pej4$irw
zF at qE-sq74vybIf{d$CVd`J%yE>EKbLz$A5ve1BUIBxKCc-F->zc>-?oZ3j;lns0Ut
zW at yzAURV!;NmxM!1e=vYklW5Lm#Jk at cZP?gMzVU3!;@VvwJZPl62h!g4$iW&zqUkt
z2sy5 at O*i`)+1gaLxLtTdS9`k?Yu1n*9 at yC@SWbn*`<+VZ at u`G9;0GxgN!VGwTWull
ztxVTz%O&a;%4;3m^}n1G)ygn)U6ry><H9-9Rzvs}Ax9=^F*~TPM*D|*QJY85xbNVi
zdxDk?&PTBH&!++6KR$aEzV^oKyDWrzy=M1UC3ya@{b^nehSA>H3?*)%D6LpH4IPKb
z5>c)_BPi%2cJ{evo1Zrxxq4)&?Z;z>oL4LIQO*-#guI1-DkO9i)|`*j>Dn#SuCuTY
zQv&A04Bx<%fGfH(`vlOTtN^~r-tMM6Fn-IjEuah7H_d~jWx_oVo&{S~`miI&`Sng7
zddV-e%bbUR9YWvC{mtC#JU^E;vA(hXMo1pz at xfpqgHWaLDxe2nQUDk0<214W`j9B<
z8XV`6{>%J|V5QI2X{wr*U|<DV*ZTph8Ry9#AUW<GRZ96au~w3b9QgvSKWZ at q{rLts
zkI1Kb8 at gb--pRIfAbfqxlECA2Bjd24zUJW%=#xET=Ozce?!`W&{ECCB)G3IurOqlm
zNKPWQ0+svL;JkH|`}m`I)onRqocY|Ux)<SDl2G!UnYq9B?pWP*7nb^r32FD2fgRDx
zD6L7}wV<poZ0s;gZ(nqix{i9RP8#a9*h$)NldRiwmK>OcxGvU+`PI~Vrg^MFb7wA5
zH=NrvBzZ!HotIueI<WM at sG~2AsXeIPj1^Yob!xOvU$tgiLHLB&wnXX{zU)EmSsX#U
zqM8ovFkqG6=w9dLcUdJ`PVql2Q>s`Zyc$pp>1Sh)o7f&n+z;>E?=r4R{{k^rv6t9x
z;GVr+b9J~dVBiyX>gTID4-O7QP}cq3L!&E|9RjiiyqEXR&%6noH7!q$5A;*bABy=o
zKC1RC>VOYjC3ER`=myd~<P_-wMv#8ERG7Tj%=E{H4Ft<-H6jf8v*w1Fik&|yrZnv%
zB_r9xc1f`J1qaxBt`LV7tJXzfSbjj+jI`HQuwem8IUz1U7%{yz{;n-J1YF-5!%d$S
z)mod|j=o}WQ0~78uF$2})1RUF%0av<p9hHeYEmWI%4joMcg5O*&{l|W(wWXH+9{z3
zafg2*O@%(*fD}M|rIQKVYbvrE)1-5*2B7kJJL}mO^|hb(cKvJR)Gzs`wZJk0a4re=
zJh<}85#R>Y`MYdY0fx+(>%xT_+sduQ=W;}a)l$E$m&*I)$C7^z{$3okReNJ-Z?JwJ
z8%?@%_r(1`{4O{9<bT8RpD~ut_kqd2nPZ8|L?n^Y(N}@uyFP~E>+3+5ST&pG#mL%g
zK3uFQV(w}6aV^VJ2{N;9+kGr9JBv8Z6pmNnw%`peN5rvz^s+*o&B*S{z+?k}={`LF
zVOZ;_3M?6hx$N8u_{4xH0@?b4b%%D3!@7V8uq$hDMUZdd`1p|8 at E69wf1j>;edhz-
zH48^nCS5?<cjvL7ju`d)AR)wRXINW%jt~Qk`iR%9R*_0wt#y0d^Cc>R=OMBOlMgps
z5*JeffNg%PR_<(nX0Ls|zUI&rTzt`d>c`rwEdo{v4iE3#J*;|CG4{;5tEm%+daZwr
zmw+oBkxtRQ;WW1Uf`Nir`uqr at G;gbQ<zxEE{~Y0~ahfd6iyeBMII`$sOYlZ~0{BJK
zZmnh1i+vd~rdH>U*UIuy{Xud19JG%U(MSynw`9g7S9*+J{GBQ{FqfGh at I`V%unAkj
z at xl>p99~8$DQSA*PcDFoZ>`0bQEEA$n{xoIJKrl*>U~$Ow}8OnYoU+rX*CoklEFF&
zV5Hmo2?ls$Q4y8K(z>T)&J^|`5XM#8eL&RSS#<228YbJe3W{$5s+lYoa$vO+&?T$K
zJ!>LK6DtCWaJ^+GT+@<4jNSdbO}z(9g6uliKpTlF!@yco at d@HnL!T62ZIZGK`^YP7
z+0Sd{Wa=$WoX<|ivB4X6w>miCfk46ifKfH<H1OIH>XOHx&(AYJQ!w*MkXZL=z!hDX
zkv81VlV&Y^cY~#Lzn3>r2)Jv{f32ALX)Zqs`;;*h&(y**Ur_i!i${mLkf%y74l%DE
zn$F;nQn at z3hDSR@KL4E%i at z6&r$YEFj==s{)rA1WPn=-|(&wmxTK>+S7%;mRrLH@@
z9f!Bek`K1THxHuqpJ66+q at d4Ll05hgbGrE6lWbFAN@<sn+NMc`bm8N5y%XZ^@2+8^
z+5$94l0m^xB&u;jPb%1$u3TVXWh%N0+%2n!1o89SqOKAur{;q%?^e at 4kT_Iqd3R0M
z^Jb8!mjnwYgP`DhGf1tl+b{n>X#!Mk%%PrSU%nLr8!d;{(AO7yrp#jD at i?B at t>9iW
zsePO92Jvlocy4<6YxyK&IsY8KdE6bLVLdw*U72V*3I}p_?7j;KwJonFu<6a@!;PEF
z&V}BP)<%U_V6A6Ht at m6EwG+Q;3GsVLt>~7>e_D(+qrWR59_?NIk<D%>zOhfC+5PWx
zcY|>zuMQ!n)F2(<p{2Ii)am(1k4FwBa7%(&0`JF#s<-4j>}|M$-v*juK#rG$SE*(7
zPHPpgu&DPq)YndDUs}xh8ZLj4^I-laf4%r`dH0gETXO)(L#Q9vN4)w2JiOuAu?X#M
zN~8Lzyah7AJL5>Rh1vx|iR2|I;>3l8<t8A$>K-L+;OwAD&Y=&032)a|3v$^B8rLh>
zfz!yfSQ20WWMIZWoS)v(J_fd%>L`FW&G_k!a-cEt at had=5WG^F<9 at b^WrfX~v@}G3
z^`wYy4+Vb1h2&DyZ5Fh7R5*W0P4;`=-a!onisXx<EL!YbONT5aQ{Z^79`)l>y3njz
z^1<r!)0ZS)$$*1(ge^FI;1|lWp^UQC73SFf6QxhIRYTLw9aO;TDO|>TpFnOevt;db
zdW0<MB%Y4jwym6`zfvZ&ftx!Ka<HtRu+h289&FXqh8ee5H^3pYb=Je0>~yS}`CG{j
zmcrC}+roqiULcwnnsuy1KQlW;UDEJ0mHm$W3ZNPu{9Gd_iky%#V%#L0|J$r8*3UaH
zM7fEG2<AUoei15-Tz4AJUi-K^xuGS2Z0j-;r}4%&Nv(-ne=x0_*7>a?l6BBV=29+!
zRM9G0Z|=oSeev{zo?+NPz!(+F{WII-x?H?8I0f{y{?Y1C`cV*RL4=2d&zuE)DjOpT
z<wu>K1J2iK${?`2P<-<Wy?t6kbI)?{Oiu<C!Q|#MUJ5;X-4)bR-1vVd<N$f*9DYR{
z>}3 at 6WyfY-2RO7wtvQ3xSVrzhrX(ea?(s;}Bvkjxd0DBN+0t(FYSlROey-MOBuLbo
z4_vpSE;8fH at XefOpaCYfyn^`M;Mh~Nquf&c_74u=52+{xCS%8HT=CnFK%>M@`fBf1
zG~K7YRDXT`>mucQ(%L)a*1UdR?zHL19RNe|k_^N`dBa3xQF4n`*KP{fEfpezy$UsF
zv0|$h=1cXioiv(qksFEZD*)o`pd6<$*ZHseJQlaC7YDck-n9q+qH4A-ixKM_EwmSb
zEklYKS&*kM(8Op+aQItyArxd_(oK8dEv%|xSfXDqB``FCZzz`c$*)hY7ScElJ;g8<
zK{PzxmIql?_C2(gH>AI{P^MDs_0vlh!szXSwAqaefX>4U=ju@@d4zz9w#-DQrbU!q
z!(^h0Y8Lg at 1K6c%)^=v+^mYO-{@}kLh;*nFU7M9Bmf_1#)-?<Zwpz2bM$_v<$AJ8v
zr8qX at sr$Ox5z9`>7Iu7L;INenuS;mNd61O0{DNfYA?NRvi2Suwxi!Sj&H86`1<8;)
zn1$ANs#8)Z#t0xh^u6uD^3dD+-NVB6h;gUD#m%n>?ikx==0dl|-rkkDEB~L1-b;@h
zPu4fdGES{brG9G3PX{av9Yg(mZ4oJrA6A;A^$l3PpY*DThis{c=Sa3Ki_HvNn`=Bh
zfD*8paH&M2{Uqn6UznPK?<}$M%|5el^aeWv)YHZh_0aRkXadzWo{uOyN%Zs;4|^y@
z8^=zoEB8&0!Y+gu at p5FAr!sB3jMc<H_>{D9=&dUiLmMxZmBuw%+B_TICIIW^Q^0|A
zjTwN{XkD_?4m1|vgnxbs&}yQ(&Prt66O@$#+qENU7FT<CVLcexg^(v80pLDkmaw@^
zLb&z#M0*{3&aHke*N)IuXJ&)uc(LvP^|gCiT7fV&4+v^uyV}pIJSFr*=f9R_&pBV!
zRuR-o08EVD7SGC}Hnz1*bpgdy>yJe}Rrplj^FJ*B<WlbI8oR?qtPdQBX3B`MmprQ6
z0o>u)(*Ix%AEF6K=RdcGmw~j&v=JwD<0Le7 at 1P@2ufxkXaH`dC$iH%7HQMkKlxx8O
zh_nv0!x(vvFNs@~w;fP4et~y2kV}Whx#v_~LX?z!C)ZzqCG=lk#?;ew4ZhcXM5<x>
z#z-{-h4b&Ne7TO+A8q=Bu$p4_b`pfB?oLnrJlWSg)+f8_g_fzK%(k8Fl)Fi~N=%+)
zpPN?8F;xmPlPv|ircsJAL at J{kRk)r`W4nTS!%u#m40`+BTVIdoghSby{|9h at CWxQQ
zCG928UC;=XB0~!A=`lh|d1ro-e}A^iVyfr>%T5WFr59#D2pluZX$4)WgZDiR-wJ|~
z6^;g+M`)nqKaRG?&9&3dU^35CE-D4W2Ge5{)5_9oltz6H4T)>thFVCH|0-xRf?rpj
zcpF#*^<ogCG>R95x|VUDoRc?}9qU|#bUvpRDJtl>;z*^U<Eg*ze5ogUzn at F~AbdR3
zLSw2lykNSlD3xZi`jHo(4^$mesTgg7KOiNMLVQEvHh=&AJ^AvV54G|n^!)VLSiP~f
z45#tC>g^j94$>kQr|v^2s`g#KYl&H1SQ~evR`ThRhx{QBEtqR3S=ICAt=in)9pDvp
z0SDS^gXRbicaIZI-&mRQ*Y}^@@Lou(rUK+Rgaw&A9?tkhkx8e6_KxC2nk=QY;S6c>
zfX^gXWp+-iO-dDlLjv`g%Ub`yMAvx9!LL~3yO38OFA#$vEg>hnq5Ovalr#82X4- at K
zUzIn8^=3z`8NcYKgY#?T()MGSh!*^|ppoxTvHSM+?h(?T*SuT2r1kE~cDtxX=BP{i
zbMaArxv&fR7_)5b*YF#NE3ICj_r5!P49QgHS{{H>rtYK02YL}XHoxD7??jtF8>1_h
z?LdlquotRLep5u6(R9itlN<(f8`sAu?Pi7n+vkS3g!rZ?fMLGdQ8$v^>Y<*?oWq+~
z*09WG!6R~qku!JrryF~#MmXZJgxe^nQM#$ezh_|EjAH_Hr!H^G2EiKtEcr4Y4O$U4
z4Z0>qar|3ZchY&RN$|(_&>LA$a<rLHic2*e>do)vwuh_bVc|12<`>wGJpr$o%1K>h
zVq;{}sqHX4<!?5%q}cOZu5RQ1Ab%6yS~aa$c at 9@dHDCWkBQd01bu_DD%&>kD78|jp
z0-ce-+V-ODKR;y8+SH#-Z%K6k={McPq)})x1<y90mRS|l*Rl!CksNo%R!!1sUvrQ~
zXO)&g%Xvbpz{(je;3jd!X{-154FdMpLiLIv$AcvS6Q9+MJ4*st9#reC0Nz2!|6t&2
zP}qYFmMsAAEaQj^+92%#E?upwm+X}fh86XJW*sA&ujiUPUu&}@;3xX_R-rd-1G%Db
z8u%$a`%0?oi9>%3dc{`XDRV2-B*OSI4}ipOYR>ALBu|}*e^A*A&SD{W>c}kGW>X9R
zc}i`)9FRlgkXO*jTp&-`8#;8J1*AIAu%t(sU^yuUU!N_>z_!R*ShDqxQWT{@+c!*=
zR&?oG;MR}u2X~dph4k at k3Jbp5bl0ajfv99msm|lnZOQq at -QwX4Zzr#dy<gvCw8zqa
z at IkOcZY>MU+)di|2ItqS<x+lL?Wt7PyW4n{V)k>TQB>u;MV}Y1_QGHn$2=)7A at 6JL
z?c;8%Sa>i4!r2!|*`PcjrXC+9Ogy_AN6;N^JWZ(mMumcuTs<nrZ at bP;Ara$hzI#?x
ze;P-c{dw6LA#RK8iy|UNOtq-AMzEBA*dvgaA+c1jFs9S$)JHYF<BkshqAos<PD0Pl
zI>$qzFc6tb7mSw_zdy at zHhoY!qFo6ViUz&UENf4G{I<&My}|jtCY%ar9nb#VuF7nW
z#VEgJyq{qS1gWIOoICPPiv`$>hUO%RI8B*uOy`#iXsFjmC?xSG;aAv3_UxKGcKD%A
z<+27d%t|P2zF;)>CsJM`6s%(zz~HAzKD73W6&$wq`?N%QryNw~%`1le)!u+b(*ReA
zLwkUJQkWLe)-Q={XT1;Tqb33Oo72Jhul>b?ilw2dai9T<CcH2!Y9=3nmyDd4at;m7
z9|0!?vCToeJiG$L-X at +4fxGW<eZNFoZKNExUkpT*YE8yV`qSm_L2w#Hzweo&&(lER
z-?JYMR_aYFf47pIgv0JpRNO=y_aV1 at lfUKuA|G!w|9YNY%x<{2h8=ItYS8-x)2YiY
z`PMdPdJxb6Bb0OyX~UllvaIhG%?x0zEVzWCc4UuDHVMRX;~4!sKAxTRy2le2qU^1h
zkKUhKJ8%rlM5Oe at P@*uMd>)wGMKMu;qO&beXSrF^u9-9!Wz=c?ti7$w>yHv^i1cwM
z_REV^AAc{iLaAV?T<|>_RysX$-_ZDqkGfM%BQ~8zQeH|aznd~vSas~B at 5A>$>v`|D
zPRz$YPwwdy&a!kBRg5253xBaK%tBc9Px{{7>xr~=rP?CKMkS!#kqx at gROqyPBZGQ%
zbol%625K7~joi>MkH~V2^_(Ljl!iT<P1K>Pzi#kbcZ}L6a!I2fI(#t}8P}9=9yDFm
z5ca}a6WRgW3XHU&r^C;;gMblJR;kQrNl6Jl`F^#7d;t7)Ha-YIBaJ_#`K!NEscn^#
zC``qB$<xs}&BTRtwHQ$R at 8{zWhVq^XpZoa6eq9(_90N(Tz=78H6EL7H^z=0QD76B#
zzvlo8=H<ea%cI)1ti8DljZ!1vN$YkvFIoe^CaXaDdIjJexIox(1}bL^gS=)M{)@yL
z<vgws+|8B`A!HLL)=j7Ztgj3MFs)qv$jj34=gQK0_)d!e at w-JF5VVu>soC4}PS!o}
zSlgb3XS*!L$+qg>kpA!cw0iFq6MlJj#~p3qp9 at HAK1kTP9cJnA75y}jsJ7Th%Lk^#
zZ#Trsl{d0qnqTi4wWWjf>;re>yPb-sZLzMPT)sT$hO$OanL4Y9ZHDgE84G3Yh5hDI
zi-<0Y^^E7?Er=H{Ui3(jCX$ZfUxKveli72?kk6iX8#nANU(B_``6I6+#S1OeL|O)?
zD<Y+)x8)}I+rIx_yt?d-@!m<-Gr-8|&@(#@Va>kStA01bJ$(!SPS5{25d7<OCoP^1
z3HHQ{(zOlRO(TcjU9x~&9FLoCI5nZdZVc7!Gnfq59%XhZ*wz{sk_wT!_iR+rF@!E!
z_02a2vsEiBV&`Wd5x;S7FV^eQ>&G|Gf^tLZ+0KYg%||*pxv<FvGix7G*LVMNqo_&o
z97UL?DZS5=Zps0jn{bqD0GJD+fpYVrSYPRQYa?-m^wE>o`(R8qSf)pjmoE_{W2A)r
zYNB0-M|j06&ke03lMP!#6`f6^^&{I3RLn-P7eM9!y2_7KJoKwM-{bI!Hu4&M&VkqT
zO2{$b%iuhC{-YV!Y|*)gt$ozyU#+t7mJ;Ik>5j=wzfZ*BvyAxbQbtzLnf;f_rch5+
zQC1M2*zM)`d at 2J5fFYhm1g?y-JvJDyU1s}3ti%=j0ojz|uP_GyVF=WPE6#^(JRHmh
z3Yt1Ub)K{S`JrrR7@!=kf#W)~&d|pgfMMi%hd6N>!2t9@<U#C4B9L1dzz(mOgIogu
zu}v~S++=w*Zu6gF<CmPGUFp}Dj?a!9>>2AUXR$U4Y{J0#E%{Kt^91tL<=g+4bx^13
zEj}~06QUNcK<63TOH{)!41oSKUs`SQsS2wm{r)8@=MAMAT~t#5l<AV!<vVdMmCFJN
zyQ_%I>hq%)L-PB1`q`Vj7x}6YoykvN{-MuOtlZKUe*6x~8_SDxp(N1HyVQ%gjQ{?(
zy^&Yi`?!WJvtAw_h|ZZm(PwtX{Ai^{db08EH^S?-x1+qco-ahwe^HC9N$=6rt4MFf
zKdKsU#uvuDk7>o*&-FCxn;Zy;<X8-5dkf3oZly~LvJz-ou=elk?Yx%Go%j#PbsV-I
zAbG^21y?&!N%Q at T!<tthOz- at iZJ4PX3|G1|j;I at ID1@}qqv3rBpRS_5c#cvuV`(GG
z?Y>08Xo0*NmSJA740FvEMY3#@XMQ5sF!To$6xgYqz!m!R**&W(UQK3-d13sd%cSl(
z=l(GF;}YT{)Ct4ur*697sloZNYlk;(bXWb+R(Q6Ync5lr-6N+8QnmL*++|spb{+k`
zU)yQ<GZn8K=q#yjv1|DCqT9tm#NV at jNU<ly#~XjUlLP at i9<JhA&329df>8e15g^?>
zH4k^oFT`mqv?QyZ3B)OjXDBjT9M`Ob%h>_$eLeg5jObAvi#X*_SGmRzAY(`7^5g*F
zpJ%~}Aq9s%@!P9T`vDx66>C{sleH|c(_YQ%O$Pe+ymR18bgToNkNM*_*EW$@fTZ>T
zsx!f7&!FWO>sN*AZ4xDlE*!)casQX~wd=Jqw<_S$8hT^)4;70o9vK<=+ at sYRKlor4
zjBYMfaaL+8n2gbrmPgb$_w-A$yZP4N5Y15%Hs{bin`n&=_ObfnezvP}EJVl}Qk(A%
zgl@=wmJCVK`_Z<`WOQ(neoy7<jg_rG3A=r$@avw4&lNpab1Ucx_GUs#RE)@)Dl^zg
zc08(EjRHO0--OYLO}?~jsicnUc#!Up1`4_<+F=oi^3Zk_2Ss`j{tMm at gR*MbHrk}z
zQIROzUt;RXium?odA<DQ$hZ-yF{}mdMkQ9UPjjj?xkFK=t6hiLs|r|g&n!;I%BqsW
z-Kr7Kz`}9R@$T&6wsh3}-z}}Prg_^xmQ^%2qdiNyzjW9rBh>ZCjUFyc&^xKF at slNb
z%Q$-P1V*~f8XC7bOR7F{1&#Z7Z`m?wCb)BF(z$=-8+0>Wg;)LqBa1T5=g at c3l+t^Y
zN?gN#+!P~P7u5Xr++29D^`@d~)z2EGOCaqG(`t__YWu}nh@;$^<KIlH7k-)|8H at ue
z)K&s}zW4#PaUQ=|kEXMd?DIJQ_5cLR&OBoG<%-x^Z)yl*1Yi;77nYZU8Q~UTV#K>f
zMBnegr(Uxn;V>(DozhTxQdQ;yEhciVC*z}WVNI3mIfSWy$?EV5v&O%SfK7rZzlMbm
z^^N5{e7goDFB81;p|Ql1*eS_=;P#Se0zfwGvWJCx1H0dVu}c870Xe21BD_$us_qx=
ze&!-sn$sV&8I&S^xLW|?8tbf(H*x>qD%4v>mJbfHH%5m3N3{NleJMJ>ATTE^T5dg@
zM^L<@_Ma3)#<~00LLqqYYUTJ+PXS#!p3L%}X|1#<US-~3eT41V*^t)|=@Lt5xIA%q
zEq7>IWR##*$W)0DMBRh5(5CQSb}90yTR5Ki)&fpI&U^SDgwHpC>K9;p*L)s%`6kU6
zMLTp2UFc`U284xX$ba&<xp#(X^ged+%q(z-b=%g-Y<GKg#{~FqaCZOO_3o97L6V$e
z28E$-33$0v*wv9a)gaGa&Z`=Z2NV!Z8R~G2zik0!so|M*Gp2=leQbiVv($Ib7IeDw
z>!02=G@)d6X}>Ad!X2|8hL!EgmlNBea7_tAN`ndwF$<Q@&dA}|_>%3&*-~0+YJU)$
zp-cPrCI}xlX$iF&9sZad={YK~?BRnnmOzxe at b+2T1O~J-3*Q==tvvtM48=@wbHIbk
z6wRv=z5}exGZ*o<*WmZ3P;Uz-Ex26jwNj?>1J-Z%mlD~D6FY<Bhe(fa4o@^Rr4i5c
zDrO`6pq-tslyk+LF?*K3ZsRuZX<53Lj90n3`^7SRbNmIIs3?Zdj*b4``n8w$fXfG6
zDDwuVAv>Ix4zPT60~z7Lvu~BH?30!zZAVt+_}c8kq=mDP5!fcBN3ikb&RXsrt<X*&
z^~-DbdfIX?qsKSBi}ZeZt<3W(&iw};rqr75to$2Kurb;4PyHC~GxgYO^m%@AuhpvG
z+i#9*C}!0z4$=etO}0#dg;bbMnJ1JndUdckxspdny4$u9$u*afltguGo7BR{o at zPr
z=fE2jnx4RD#L->yF}X9!=U at j=a^8AAzkd6&i2)i!Tq%`RRrnn~3#uo3Qdw^^FSOu4
zXB#q2XRZYXf7AZ&yRt>ri$vXjfQJX4Xs^KLl;>%d=(0NwTDCru2n{P;5fKdB-kvEL
zgSWDmyj6yiGn2j(vFDwA3yKVk6{r#`TMLTxD^No`%<9;t-STdAyfY%0X$~+wE&~tk
zTJas8Jw&EHe6FiYZuXxr<IgF~&2MyHsc|9KdYV+gJdrXaj;#r>C?7&hgdA{x*bno5
zF8$3t(D8WT{+%~&tVPE7j at vzf<>8D~v~?so-Hi!FJ!=t=#UY-&L>R97sXT}(D4KB~
zPn at bZIi`QOYI-TzCXOX=Z$H+m%o>Hqs~r1E at p<wp?bw2P#^Qy<<z)@1c67 at +Ol;R^
z#21g^zF>yq*saaamitBN)qR*xL-m|J$L2l&!m9w2!2tGEcHF(5Ca76-zss at AY(KA#
zK5&1;i4D<ZoCHZdJ$p*(%!N5U>VN~?@>@&5e`)t;KNlHBc6LI-O7(&z{FRz_beb~F
zE0+XY;v%fOfFB?ltDLF~-cV?-GHZ1$(mO!A(|19M02BC6eLzkSi}>wdr>4>0M|N#^
z8L({CY;r(#{`xu*2-Cs+YPugV=zI=@=9*5Z0HpK#8KWJZ&+$O9t at zwe6G;#3NDqAy
zKzuerasX8QvUl at y%lI)3gc^1p2{_G{Re&l%Mq0{{Go146e%@$ly7Tf^%$8l8nvP4g
z#@!5?@3$aFzoHu{^%oY1nswO6qs)~wkIirQ#0eQIylrkpHhiJ{fKdj7&gKx8m at KX?
zqG4-9=4b|No+|YV_<iN;=hj-3W!~KBr!&RX$LT$3kh|Kpw{{&izoES6V|-NDh5hB1
z9{&3`G$PSx4{KP#N{+{%itA?k95klOtQ_1%BZO9GMbdJKcv!E1y-N#Y81$C|a|a#%
z#<NIa9?~v0sY?}m!XAgbq`;v?nhs4Dz4|@)yDyTLW53aZrIg-`?s-Jp-}Vw2x2`<Q
ztKpljAJnLmy&5qFGgnOX_5zc28-qGXB9<i8e!lARm97Idk1s=E(78K%7hA&_)heFH
zzOnURA8+H_3O4dggtsrxM6n9NR^rZ`*m#i%0m=8Dm6-)RyzGo=dbdg%7;Crc$I9+-
zZLcYAlD-+3;)|bz at k}OEBcn`B5`@D&(xopqi`z4yHyvCDe>ZrHpq(plPUm*wDp0w9
zzBpGvSTPHx6$mk0DvZ}!lA(aUav>A*c(P=53u^$x;$3vGEuNVDL#v1(Q-}s7zpz(F
zGnw at mK?WP|?prMt4%weP39;3CWK*5D3GlD_C*FC*j*HWC!sFjqK#l>rUdSJ<Myqqy
z6HfS>umqXbL*SLvi0rj|z~-)#wj4wJ0>C`;PPmEpuPC?ivFrT(E1tDb^poPKAH;9<
zp>EJbER#NcA(!7qY%<)yy~o?0Cs?nE at mFVGTKgY;)<>-A_&l^@<NnH59m`Q|#(gp(
zm{EK$RlvIAopG$wX`6^wRl?R8)A{MBo8IL>#ly9gqtz(XpC0Bf{4N1*ISzXQt6eu^
z>JwHk;-j9}y3!b?(70CtM!58uH6yRuo+bW3i7W2 at Tgr=PqK3aFKK#bFHMkpe+w$KR
zc3G<(?9z at j%ddAWH^vMeQ6*^y5Of!L9Pj3gS?PJPKT<c#@@3~>rP_?qn+8Bxly|C+
zfw+Ut%t>$lnum*DI|k9?J&#vkPO5nLtCm at 6S9z|iEE3z8zc;n3*1zE8aCNF>fbwL)
z;{1?JR1LlJF3%;j&Q_gaR16Xp<#|lyo{S#_Q&T;pn&V|W-}eqCuQt at 2i>X+gpQCoH
zu4J?WJlV7B_B;$<_$UxIHP>hJ;HnBmPsm#N<ue#z%BEv5?cKYQ6kl4cvw##pfMC6g
zww%$RH{kdh+=*wOet265m-jpx<oaUzC(MN}>|5J=fO)jl06gH2vtL)kI{-dRwS~88
zH?W5MZR|hw&KeP~5)nic-Dwlzs-cA;fmG!&mn(?ihreyD+j at D4gMg3Ucb?>tZIk&@
zG|ehmj_s>p4+lIIXY>xxcx^1`i~|*I?9&(N+~de<!FrV?;}96V at ZO0imxw^E(a^@+
z%0ZO_w<w^)pn=RhS_Qlc!$SG`IHx_ryj+9-Vxy<Bg}I~DbroiUKc(oWiJ=*dM+;N#
zK?z$AqGH*j!_<e;ofGlXyBp}mSCD%BhtH!+&-yq_j&r5DX at lsavwqYh+ut&rlS#>j
za?{4>tdkzxXubc#H+#1#?0a;&c76v)_NOeDyfirs_d88gEUe)}J at ubd)9ZaqBRZPG
zM at F9>ibd}0o~5NyR#3w>nnuH@>`QOj{T;&1#O2R6t|8QL7surwuR2q1ejW^50qh?+
zTQXVonoYk4HRg+N$Hx_Ft9L!mnpBH^N{=qbKeY-oWedJV12sbnZIfDr{1DW8_0sB-
zd=xRYYw&9yb%X at zQdO<Q8XpOW1p at Q<YbJlrheFfHO|gc;`qhRKEQ<=ry(W;e>PzmR
zQgLEzf18Pu$98$3eDco$p$I&M^?I$1#vFev60B6^V$0?^`IKvql4f
kbi{8Dx<
z4x#hdz&oBQ1E~Ri^CuoWpE?%ottC4DsqpHgT*R5VyFQXFK}Ei`EzerOGFoY=9&Q3m
zZtR(k&jD8ArRILdG{?@@%6K2wtukkCR}V7=W6gR37WhR+m+YJIoC3Bv;V+G)X=6hb
zdu}30Xk^FaPZEc87AJiAdevJZu#uEPlw0}@%>$U3G(#aW;GYv^h(mW|tGvZF3j>DT
z+|nYO8fxU?A2jsoCetQVTXzu0o<2L$d$bEg?b2~<usD64jd`sq95)aJ$d?@#fC725
zivra)omn~6x7~3y=2dGCFxzLWE=-5zAMZ?+a~i*r{h^Y&KUKf_1ZAItKK=Uwfw(+_
zuZNh}raRZyxWT6I!5&$`jN#IwoJ%fB&)UJ!`Wl5pk=MHiQY%Gfn$T>Re?mCozcoz)
z3MuS86`G^7mpfIak<v3J3_Ze)3`XzfnZ&-H4XfB+o4>ZO#e%I0bvdY~Z;M at 72EKp|
z7vuZm)6$$8txNN{ZWD*CO0h-EQM^Gy!KvDnpkhd<<t at rijLDWKrdS@&lk3GXx1`SR
zIr*hiT!@x*NphgVe3cBlzn(YfSwI_#JY9lT9TaHjEpzJ6t{lxv(ju5M_B~wqd6o(b
zt+d)SXIbm|YB0s<SNLRWfpkj_QO1f?oeEBPQr74nu)FS4T1H_DS`;t8=le`@ks$VQ
zf|(+{8h34t=#ZUNVVw+?sa<1L|Im8Tx%4yj5rX^=IVHbiEuErn)ikgC56~5tr&cYm
z^e)6p_%AB`H<QArM|V}-Q!%2*cS<RG*856q at 04e&g^1s;N3n2UgG-`0ORPWS(Ef72
z>&fuAx<%Ln=^6-_>E8N>iN9_55Ar at eK+}pBo%~dxGi5W6-#3f{h*M^d>F03*W;hR7
z$LrP;DG6dv`gm^}F0TS%J(<8R!J at Kis>I{Zw8`{^2z&h4DIn<*M;fodfx>y&Ys7~Y
zz9>zylh-fRFSy+TD7c1#?yzx}N8x}%{_nn~pXOO&A5HSDxIwUY;_Qel9Cq@>>gT-$
z{N#tVZfaD3{Vt7 at m~ELEX*r=qP>m}tD<o(0&Q^xrm3<HOohGl_rymX2O$>A~6xO7U
zQdeHjk(D&vY59c$B{ipfHTqYeO5ei~r!a;X{?AWJcpC}~&P;f^A>Gr5i%j3fe}{;)
zJ+u at RS(JavR=4x6=$D?aL**2Fu`?duK5J!MXJYbFzQ_BH=K+H-DtxGDi92<+a(`;A
zl_O2cq6pn-3rzSfW}Y34+ej0w?^x at lc7>e<nK{m07?mwhta4rAGn{#<EIC5w!a86r
zN1Yn<y>;V94~ar?(Oz!}nzX1YSip7SuLMI-pnlHM;ltms{H(To%FeS8%o<c}PZ&N_
z`R at gte|#nCvY5FWZ4qf&$mnU}%*FJ!sYo6bY%41c0^4RQ5jR>saHso{celEYO<boo
z{!6PN>=Ev-wPQOOcYmIyhuqxZx*5u~ZB_ at nV@&KAH~+TX`2p$Gzl7USO>;z`iEx0w
zO8X;p|99=<XQBQW_u6^@wFl|ZyM+I={y<``W~Lat5o9}dG><S2x5G98t at X_PxxTzl
zz#gI0!tw-|EKiGvoJk>cQNd<K03TZQ{MXdKM&Jru%N}+Cu5G|+)KrCG#$Cpz^D+Tf
zR1r`NW!ht{Ox(8s)1A$b;0d7CqXqbV-+yew-YWk&0~;7%{QP2Bf`|G5G1mCKY5+d5
zOI72jq0o?D-S0W5PxnczjC$O94Fi?e#V;DE{Os=TPLB`?#)dqX_RX?xcy=6toU at NE
zyqytKbVJIFd7b0s%9>rqTzh_oWduOOPs>H0bEY#95DSc}a6-p at ZJQs3`qPugY8|RR
zYnjTXt_!I$O*VV>JqtWU-g!x)O^!?|6=b>Dlg@<fBa8Jfm4vZokVMlQ%rW(SxUlEt
zdGA;rv(J0hp1|p3gcO|`AUzN%>#eHI#A`GQ7#SI!M<OT0$Wftfyr8&&Y0iVe$iZp!
z^KT_1 at 6(25%4Ea##C#v&WGNsHZJqsm62ai>4+^&Bw<)v<*~+il=|7?eV<J|4N<&7P
z5R2<6N at TYQ0iOHHt`c0dw?%{v?liG6=BET5rm3|yH)s4)u1!sX-ODG%v{_i~)n7I*
z5?X4!+_pv-Vba(Crv->OKb~9m={hIfQuiEBn>id}50jVe<&|>Fy?kQPzZ_AkQxC_?
z|0XPA<0|8SUar1 at NFPEc)PuD-58ys$H-w&)bE!rznfXDdB>9)QFt~5od|&vr1;0RQ
zrvWe@@gd-%-g at l@dVJaZRUZ-VUw<C%_sRXFa<AXn@^`gVIKWp^OuRlAu9(se3|O2R
z=UO~C;ea^m48L%&;NUZoe2YGX$eX*=L(|*O`|NW+FTM at lnd-j+Tu&DpiAZyRzDCk%
zDI>31Pi-WwU#eer$DLhD-uQnson=^)f85296p$H&gyRn?Agv$>j0uP!jl}5gZbl4{
zP!SM8QaVSCj?vxSqd`h~bk}q9JlFFE-f(T##qRy$e9!ruUqbs>s1Kmc=b7j5^bAzy
zt~fX<)moPX5_>P(5{so&S7mrxs-3j`7J7ot)}V1heBZX5jn|{JZtDUnQ5*h-uQE3*
zf!<VhyjQ<o at 97&`R8wH6T5n>2rdQrqk0=~)<@W{*p6}>lp(dz`g+b5*K}vN=-4kyH
zSE91~PY7kNbA;oaID82(Bid=lBpnhmv_{Il<}hn6`^U7b38DX{7G%kfmJW~(D0n6_
zrE at Rz&H7M at Rg)Fgs`15J>ANmC;^sT0o~URhSDu=FIR$k1S^$YC>y)}ypMS-leBym4
zUtZ(cjp(BAWGl0tUYT36k(Rr%X1q at 5t}g=8pm(hRwZLywuu{_6zn$HV1)nLOc(jXX
zdqlDGmyREtN{{c?5COYq?A>4WB4%8Lf&00SdTPE~qqS;AfEItD4HqdYDPMfX<d(pI
z)PG=d$jNC7v8&DM-~E-N5tdw!s^;5)=6{hKF at -YV@gm?nRj%bcVz%4?gBEg8^cPqt
zq6W at 6-D&lJA)|h+zEwiKf(Zrjnpml)uFtFGn8D<PuBmOhGEW~)#n0B<UY#FC8 at 7p-
zI29L=l23MgJAvOdP+;|MFD95aE;~hT90e8W0l>ymZUora=6C{>MZv*t36q36=$WY<
zv}%ggTx}??`p%u$QHR)cQE?RHRkwN%I;_P;_ElKX=giO;ekfflCEiSioRpNO+wVrf
zfW5aOEC%4F4})g-N(C~@?aikL(iTajr5rnBx%CV4aMhZvcDE0w2Hyke(m(lJdr#bK
z08{8m;S9p2-8y9-h&wTc0dPM7w%@E`Is47Pd`#48xA2XBG}~Gy;KDHiFc&#Z?xa`;
z>W#pM{}ql2 at JH<?J~H0;v7uM?-$d|?L*V4ZAAqNH0Vr4<MsFM at O8IdStUyyxoZKHK
z(r3I*fWhJvc$ZV)v=qYW?HDLY1vH&B0x`GLl0kEg9)VZb;!jg1b|s&*w--UC&P$+3
zu(|Y9&*GnN?FsC0aSydRikRHQ{F_ at sB1)c8*8?jacCOaV?SJPMY^>2v2ETu4UzSZ>
zM9bSY`r(+RHvOE(M+MYG6$q@@6V39-B!pIQRLBe)B5<pqjedKeL>(Mj>-qqTlo#Yi
z3%yi+400X|$ze_}Q|A8ra^+YJOr653sc<kj=?YT*Zvv_VqfC!%b(%$KQoxUR9+<Yu
zYgrRnr|UK`gxD@;jQIN1_Dg?$pC#AtJN><Zi4PDLxU()i8EW6Vg+k<nyM%@{W$h3+
zC*}hmMhN=Md{PV%eJ%|uc2y>xM7o?4<KHKU6^g!?3ZB3;1@#!v&6=$Jn4_L)(t#Rd
z*VK%{uR9sj(+B6fVCpkyxSC^$QI_{k#GiX_cQW0=3eA^GIf|{jTwmc;o*6F0{`;?D
z?&(iDB4Lek=6S8hd)i=E+nTISdWgZK_`LN^(d|W1 at 2Rcr&sCezi<3HDh=Maanricx
zx#CE~hbgD-hw|ibdqix<S5QC{a$b-nWIL{k at AXjCipiGwEf;yAjh1u#iI<Fm2UTe5
zP+JT2N(yVX<KLY9FAM{lvH(Rk>mW at C0hiQ5(4Nczr#fyEb6`Z_#B=YjbQ*xQmWl$h
znl$r14*%jpZ=Se3Va?N?bvxnVhOg&TEZhPy<!IB=ug3t})@fr;=h6nvO~qmj<uEH5
zsXt at Eh9BjZS?a#7cZ+ at s!o?b>0DUih&T<O%*|L3~oPr=iUBfi0u3o~w$qN|=(@uhR
zp*{ek7<;<#r7<3F>ZT6J0p+k^b28${ZnYHwe{~@fw5<iz000&=C at T-lc1u5Ahor@E
zTIN2s57_#%qICk3-5z3mYC<<|>s9fVb8>W7Kae^gJ7khDYcmnT)POV#wDXv&&DQ$L
zb#J>|rDB9f#6OB>jQ(}SA<ESh!SW2W(Q+_Xkv9Jo#h>de_;?+%+xlRBW0JoGy at 9%L
z;dQ#_oNy-3A-rzltfSr|jZYlI+lx*(asjW?8du2AD7#h?wkRO^n^-qCQtNrTS<d5}
zkTU%`_5{yd^U5Ng=Nj&6-YXUR!eC0AbXlY_3=z-tG$$WW!=K(V8cEMg-Lm-l9maf5
zo?P`I;q5TC4B`H!huOi{%$(e!#Hw%et21iBzrKftjdafddaU|DW6Vycv!T6LSCNR=
zsuxTDNM~%n18O?>J at pf-R6*a&i_f?%GKHZ<;B?ll{QQ<4Ehbu~J-NRSO~itdx+D_a
zk#(}NW9}Um|MbDo7)>|tFtzT}T(<j?Q8YxVZ#aTbqh_|&kS|%|+!IH++~w$DQ>%n$
zw*W+zruuywxF!x%CH)+I3Q$LlyJd=|CQZ{b5?!Sms#>R9aNQjP*SwM2Ng)&WegQ)Z
zy32w8gau^)x5myC&}ubgvRqKr`i8+ZcQ!dUS9M|(2nkMj7NkN101Sb04Und=vUvXQ
zd>1iWQ{2N$Ulxcw9j8C)5o1aPA~|ZC5zkS73#^WSCSYk5&U6_YOrHp<VxIe_d=9}3
z?oxgNWNwz^$1id#4 at hn1{4&@~?R8Dae<~Z_hqx~@>*q<YfSU>|(u?RD+&BH8)>goE
z!*;s#UHjJjmtLLnG0xGIj|+AdDH*FD*kOdlHH at 5lDAt7()QsNe%G`0u_4-zV9B`dK
zHPW#cLq^4eR``kC_8m=3RwIC3b;|sdupBpTwv!9*OXxeq1a=U}?BI)l8FJ|YX>T_z
zz2Ul}pfKLo5acy5nGH^xceYdfh6yb_mbLQKfK at J3v-1?4pyHy|Bb-WGI4 at VdQxfl2
zGFQSw**pGoz0ry+TrmBK;tJ@|Mn62!N${N(*sRTko?wn<`+C^;8$5C}rz_VC5tVw^
zwPD>xp}GWKxF47QC<J30wXpn;Eh){E4Z5GqIn}Xzu{SV at NG|c}Ai6gV9FJkbR5)6K
zn_hT`XdUAd at c4tyW`BR4$b(470PAUUCX1&QHDPL;`!v(~#znnfZVprK&I0Vx$%v-&
z=gi}_0!7y)%#?bUCfdxr9Tt9NO+ITyzrKe6#R;9juEVvJnyE~rPvw^QOb#ev_lyB*
zE^Bp0mq5$6p1W{c5DDL#`0Z?1j^DIDgq+B at JhkdqR`MV~`#X92)GhIWywJ?xR`J7L
zwxBJigYHGp-1N4X at FECo5i13ZN5blPGofVwV}1L at Ezmx6P;CyxDK2k%N^7%bRBpb6
zLePXM0Gp)o_KwZ52uYb*(qtNG9XZ(oY$V>mTd3-?@fy27fa3)in{ZU;l^r+VUw`^)
zOn_@|w^3bf*3TqPEs(3MgTTG4o*q-0T=RMIs%97anQ`rP9k7 at 2NK85*Y(GO2#{)0T
z5$_{?IWK3|JREw<CvBLthdRon8Eqc8z1THiKdi!sC;Ypcl}uMqrOOib4s0XJTU;^C
zSd{k*{YIbqE~S%a73DBQy`fi+(!XsL)~};3ZrnUQ5FNDH=IpW<6V4k^AqkHMKc+QS
z*?PFfzFUpv{j2AB?^oM5chWWg8(~eiz&rr3vu3X^wu;<<GfQKk%-|O9y3PaFJj9oZ
z)tv{S-HgJIPWp%_PN7(^d6`Xt{Ydp?!L@#=9FOw}Qdn462h?y(A!Ty^?-p~`PbE#v
zO&zcH2}ld33 at V1Ehi1d~v^#}3rVz-W7HZRl3Q9Ki=*_;J^J2y?yB>ed_Z#?gK=wyB
zRQmixpFEOBm`;_=Ka$l=SsR8$jl{I~E_}JYe!`9~c|z{7YwWl7z|7P%`iD at EB~+((
z(mPD+c(nK((#7=$kLA$DV6tz){+r1{2^8PXnyRM`;$kPI-KROXdk))u!x_p~o>w7L
z?DO at y*8H~_t=2-JzRR1mYbY3hvth1=kBaMNC-ITnA9v1y$@RutPWtXB_N0p6dbx@~
z!(EKyXx_f3z*}c({;4t^F><#t{x2!@H=*q)K&JYInKEkqj4OKyvpI63QfIG|@p at YM
z7Uxf*?ZmRjoJ at o{;1V%y$&~9k`wq$P%9%WGYyxZ7o~S`e4ICTLv%rR_Y_{sXWjI>g
z0i-cnt18+KfCg!2qst`_5jK8^4Kfe8NVz>vVF$>B#cePnz`nM(8wTZ#$)x(Rtu7ed
zXBt5z`apRzOuJdhlh>DlPJ<@gPUOO+@(4}m<~xm>1rp(TD)SG27-3-zk7(BuE!|K@
zFW+sH#ToNuw3a9i+kYx$7E|T$AH1X*4zzni|1b?PU_yTL^D7tR at 9S;3w4Ozqnlixw
z^Mz*5Q8{#;NyN69i_ at WxzT{L-bb_}eMQ!$ps)k|2>h$60fXgqIBz!DFC9r_<7^4XO
zjow!rk$3F|T_;o&a2fE>o$#O8ohIF7#zypap*FY4gr9u?K<J&NVsp?{tZWxW^-G3J
z%kz|hf`ZIqn%6O2y at ao1{zd(ku8K@&{<`}f+oH;dQA$vd82NV^`9DWdtULIY58Y^3
zmVL9pc#zFY#cOx9N_^JR+S~KNFId1Mq?d1Q3i99W_);`{j6x;8(PDv;yV~kpH>eRR
z@;CACgPM{v8`PemW4{2ffV=z0)1YI~;?Q3H?3p3XVc6DT^@Ya1#(}D3<wAwbJkF8H
zyC-Z|qRXE(yW`7{n5GKI-=(*%ahGw}ZQ(<$xkgCQOZrU?%LQB1H#J$po|-iws1Bar
zPIJ2mQ;B~XQ0FXtFO%e+W8fyCW1zPTXbAngt}5e+i(_XKI$Dx54038)W!w{|RRbB^
zq{!9<d~S=MmjPiix%Sd^*YKpb=R-8YHL319#7m?dToVAVxxP==Jqt)0%&L6&pHFHh
zh4M?2<J+}@nt?M=Q_NBLgPd{nrS)#hqz`Z;qX**3)bsRn$2EXVku+E9-b%6r*zWDu
zDh?F(+jai6fg!g^@<&D%W(9<hbrdGL_6Jn;U75-#=PAE$vP+4=^8%KtfGLyqL>(-y
z%7|gLe7!E+*!T=&5w?*?Co0*$=!4kb>`PiUC>}Z)bIJ&yA``IE+6gFD{D)sIlsku~
zWBywU27mPzgc9=ZdOyK6Az_Q>LPUk$9Af^wFoi3}E^%`2emaNiDMN80SHebf7FqhW
zu}qlNM&5Sc?rYJl%@-l&ktUHB)BVZil@;mZ3bXSx3E#*>dx~t_v3+<`CU^w~BYIR*
zfE&1qo^7K<q*LZAo^d at rg8Zjo#Si<{>_QLhXgx%pBTAN&U+`UrUI^1<($(CP#*boT
z!a}5CAv at FWQQQmWq!!~)6nE^O{XHe->{%q<16!+k$U at _UtHRLe7A!cOYhh5348G+>
z_)y(eYK at BJ5mhGXvz<4&<r>o2TUh)kg^0?MM3k~Sp-_R&>43J%bi!xPLc9Oeam`l6
z<IuYmWDB5oc1z2L6Ms4exnD&}J at N&N^fDUdF+jz$gGgm;Q~hc+J9aP0wLwD~lsyQX
zp4Q)b%#rRema)Cf|Mwuf{X&fpK$eb55&s1|j^iZ&hb0IDRM`Xbeq-w!fLmyy_P}gc
z%kgKGINxW-PlzP>KQlyD$A#WwNwVco<NtyXY6q#%tR8VdBLAt9Jvj%>+%5!K#ha4t
zbt~r^y|Zr;KlbmHWwAqx028$4g~FL$>S$1NM1}GX&#${>cjT^8JfvVxu;=7`JI*yN
zE%-3zw~dHOuhPTi7&+5>eOWt*l6{*~lukOYbQJa{>*Uf<!M`zlC?SUAM?iuCM>Kzs
zaWGhJOoBOsn>X9+=I!n$gD*zOW6_(XFZPO1vrovtd0wAD_jULTah6Sp at +m}5+`XCS
zijC>z8KOOiKbmj|=bX$Xaj!rt7v)p8o<+`A@=*JgOQ-f%GNTdt*a?v190XHs74Tng
zlSM0PHJ3L_CwAI~?diTpLcWK9?GB{a$;K5Zf3Fpn?l_Sna<sgi5`0>~Ji)6UiH}mk
zy#WDV{Fx at K(8fnQ1VPm4jyIa9x#HE9P2|DS%KTy`J%6Yb(VV7{Kd$+}k>|-xzReiD
zDqc9VEm(_PEG at HnMFM4P>;DN|t#B&bd6w(9aPySfHGC5%nz(667U{3%p5HJNwOef-
zQ7o_+XL4LrXfa?O at oa<UFJ$<0syLP^@Xo}LYm-~E?%RBw(Ox5+Bc2$I7TQyPzV#I{
zEz9_q1_f{f7h?Ya;Pscn0EdY=sl${Q=o1R0oCJQ1GZ~AKB}yJ`*O)9;i~}W`t1Zsv
zC2oihvx^p>ow(@fWK7~OfG>A)XNA7w!xbcI<VGGv){T`EWF|UFP2CtNnr4D|cCHJa
z%vass2G!222o$}rY^CmgPT&hvGo3Wj*|$E&iHKP_j|QtR2#|d^XuD)<F$}`5NeOe_
zG=Z6#+SvnBnhASrSYFPU0ECy_A*h0*q1*uFVI7jw4)%TzoaL+>1KsBjE%yyXvKPy%
z#ADh|4il1SLdkSBxMJ$>!`eHPFxe6cc0`THK>?sxD>7j`FV0q8q-<b5UiAcLgb^cO
z+WZ$ZC9`FLRPm|zdXJ*vqu3eBj7Y$v<~o6fFr^4V!i0tmxdr<?;b&n74d8#<yoGuV
zfsPYFN9{1`XCq at NInf>76IUQ1ozwHfHBx=IMqbfjk{}YR0q$-BIF1hTxoN8Hf at fp4
z)zHaTV!6N+<e{LKJ^}SZDC#Zz&4WEptuBHI+18~1UMppG{uJi%PP;(s^dkx;3xZwd
z-^v|cA~H}}XV`ORA}r<<bGH7P4dddI8}+mn4#NWAOQ$utM6jee0Sd5H9XI)T-MTu#
zx&8l(gf5p8R=aA6Flp8%UvPFwpqD?3aI$YvI+bWyKkYsKTQQRqPPL5K|6EC1b@)-A
zIr16VPUeGYv3bNgL}k3^`CRhGD^99g$@-kYDB at JrM-!<MK}_xg&cDn`sW<1#{5P~l
zXVQ2LqP^z^?<^LSzpb{b1jj+gMQ1Bh8 at n^r(L8KB0RFVNNyE~9BL2{+9gOHqTIP$H
ze&hI%!fjTFT(L(Ucxbc$`-al{MG&-wExh!2`+V6W{W0>*G#~FQ8bO0CHb`@6SjIo}
zaKiSspd{ER=dAW-pSL4`5+miAIO<h(+EE7u$4|9P+}zyiH*afW0o0m$Rja!$NyA!v
z$-!M|z!Kn$Y|{!Z?Y at zAS^b&;*eT<cjL&4`Cb(r-0bz;Yc|Gpd!}5LK_Wcnp?^E^e
zpG4XyW5P4gM-mcks0#O&hn<Y9Yb5ANq)QTge01eK8kDGzzcr4 at YWssx(C|OT*)#g$
z=u%!KCHc0siof;|jO|&v1#0DeYVsfOK?7~~eQZXjXtWrLwO=5+NK)x66HG;wh589k
zpBZt0Et;%|N}n09m+NKJd5eW54iK87!jz#W9%}kXHq5o|qfLW&>8Zj`sXK|1+A|}M
zpT($^4wHO8$cHga9qvr?dQ9JFx97`fv8XSquykQcafbgC2Rla^k{6B`3Xid8F|Jl9
zm*%l~FvxoR-t~^aL(fzpaz%b7b1C2BT$*f-fj=iZ_(&er at sD;SK*Cq!h5ExizXiCD
z at XO5)b_5f69$sgzFE~__D6VxvX6R<jQNh^PrOPOhkfhh<N<y{e*k1;lFNc);0!DwD
z1lqX{#^k+A)pKAybCQBl=E;ol$5G{Uzj^nMWTl{qq!d3qdbiS|)Xg@%*4dFb9&BvR
z5GBhU`f-RUb`HM|%t`tHU~indX^l3RFCSqgisHzcAnFXQz~bb^lH|yNEgpJ>4bRKF
zNURd~UGt_^2a at YwO82adL}nMORVsw<Rd)|Wtht^ALo!ETp{l{D3n+KsYb5b*uzC?R
zX!{1xD9_xMK()g>R>2UhKOPUUdp4Zdoc*g)hrlh(qPGMA3eNL|?ZCrwYUossD1F3;
z-E#&|Q66zj{sR&d3DO)pQ$P%)T`;Bfw;2YW9Ox4;rB_E0&!!~!lGVX6bwOgKV=wij
zHWS{Z8x>~t4fC>FlvRC at hLYW0jeYgZ!(x{JHNBX&)f&Uj8aUY|{^- at K6Fv26XN@^K
zUr7_%hw(O>sWooq6^iqyfG{qrqLL9b+M=Ll=6XMz at ->%Z*`~(eeafh-8>emUg5jfX
zn&e>0oVO|i8<<)KiGFu;o}PQItwk5F%*!{$3OAU(*_oku*(wBi$AZsr|NPozo=*~a
zTt#zsYIkyuOGQ?k+3!Mc8F(S;p8HLE)aehH-_3p!T!L#uS#$FQw02 at JwAHp^9u)9i
znvaV2GX!O*j%ue^BimA3X3Raegu2kyp6F)8C;z)hjOI10)PTju4jP{pACHJn|IvS6
z9`v=_WJ54MM2LNqTFAlZ6Ouw!tm>^vWbmk=Rpt6v(kq<Y4b<3!l%f{gWAowH8nm(@
zf!c~PWeIP!d|y at MNup^bFx+hlm1C^1ntY!b8d&{M97p6lAkN^e@)auEv at F+9@ZO)^
z1`LT_l^u`Cr6yVjzL18)qdB$C2He1f-bJm)rs<6DmE=pRGAO1ad(^$-GRxx1wO{jh
z^8|@3f|eDGcY&s>yCBc!@Mc^a$H1g6!1J0cH>=c>1js}FOrNkBv>ga6X9KIll3aX}
zeZ9enpglla;6m;v35^=zEiVF(jWenp+ at U>46`4<t-HXG73_L$gF0!gb5Is$y3H-FW
z!OZ~kblGv{_R+7we#Z+{duL-kwUiX&V=0K7bUC{LXvA)Jwlb|bHP%eJjgmC!*Z_BW
z<va(PmmR2bg45+Nk$LZ%tMlldFgg#R!@Ic$>;qBa3|X;L$*xMglGV&~oBt(2T;A6%
z%Ow1j?pBkO#sK**IL$%Q8Pd51sb=8?I+}hlzt%b?ol7HlC4SoGz{r3>f}V$Il_VLP
zwIv+0beDv^TRNXptRhj?yHIY+1Baa5 at PZ}3lXF&=U;T!A1T3t!pi|att((e`dQwT0
zNevvZafaOy#T%DaF9!3l3GZlLm9a0yv%Ra+I at NwUz!g`8GO>Uys2u^*HMo*k+4Gg=
zHJcujw}_nHZjrcPz<u<i4PziL&gpAIZ?JElQg&^|XkcxPKqtRIeHCOuF4ueA-to4V
z>hzxahwR{?wi8^PiVy}<p+`;snKn7M=ILx$`HPc at yIGKw7IYL^WJFBoAP`UQxK#(2
zmYttBwZ?<2R?KnB+}J863VVG0=5`7)VE_2Gb&e<6e4H)e$)|}Y=h~H*KDFi-4M{m(
zJBd}DI*QEC{lRO at S?(3P*Q>Gmh4ZIIGZYc?0T4;Y(x%eWdh=J<^~AxGK;B<v1drSj
z<r3P#+UnY)*di($q<8hLH+M1}GBp^o{V4d285m&xc$Zhaz-rw4K!O3rBgLGU35Qdl
zO`;<hqE`IG?QMf>+`=?9cG5%VHiFIM!e(p#fPU66-Sh)XRf?^zwaaCz>+W>?&<}e3
zB~Zu};yph(M-!FXWD;y-J~KB9t-M`n-v*|_wWc(T?G;q%x70q<m at WHJ{%3mF_y6|5
zM1y_X%hMinNiA`(CzyGr1>xaQ&CvsGy1u2FXKT7ZYM8P<^$GbB7{=XYB_SAy5Jf}k
z%~1cTozIs0m)a&*9IQ|jLM<csUzaqu)f-e#sf})%bR%^{RVAkxt40~F^zt~{m0rN1
zYF>2f-fEFJNiPfUdEPUja}5l6o8si5*dz76bM#(Xxw-DJx7ww1J^$OdQYS{y&qy-^
z<%_t3FQhuaBYiiK at mXaw@y|Dqe0SiF<eDXI8`(pvpD0kidu7{gClkG#Kc?lkzzYup
zm_poPw++5R#i;7&w+zie(YMfrizk}LXgZ{W at 4tMtY^u5kzu5lWmm_*c6m<tZJv};d
zaSgYAtvNI*rn<r8y215OpGJq(WyeZ-%lVdzDsE^ZNIQjdS6j5ARWU%>{E42P9#@o7
z2ov*PB>kAzL|$&;SVq#FdDHjLAuIA?yjiFF3(+6ssB6_^HFOGJdlXOi(tEi)Y5AZ_
zHkR{jqp4K71Th$gPeApvTUqLDyz`vuRT at QthmaI!!Qf|e6$sr(Pd4#7TMm0v#b2}E
zT^i-r4x2*)io?)VSJLmH!=BppL~d^_)kP&|7v~)%v0ovc{SCLk>T-qI?ZF>bC}eQm
zl at Iv_+|u4V22!Y#e<1bev*z&CD`kb+U-qRrx5G9y%gm2~#MYD|-W8u0zu4qW&V-_Q
ze$r*WKtz at JU}bD<toj^HEsfSa3;cP7nnOT~Bp(<$D-+*q1<R^Vc&jS|6Jlp%k2L$=
zveUZ35{D|cX>3mE7yx$!htziz0L!F3P+9CzM+A)g>f_^bhcn_d9==@@aEU9j$w^&!
zpvh1ds+B$MZ?`6pf0Or$@6oIw7lhFNHR?TC-(@m^c&!NdLzz*{w_V>{?lwP*TF52M
z+>EXU%gzaiH{~P2kpgv76s=M;GkXl-Siiwpq1 at Y3y#gHoyU}=1%L-2YC)dEc_G`9@
z&2-z_!=l;)pO!uq+?5~pH85<j&%lDOYjK4Zvm+EO!k4N=JY`tU013BI7k^AV4!5yQ
zIf?Qe=kkp|0&!AN3mqEH(f_{}KrW}XCJJZyyI5CikDF?I$iDcdcrD`688%Rpb^1)z
z#94$a{AcMf4bjBX{3+m_qLlwctls{b at I4$yTY83($1!9sz=xoL{mX**)XLDyzI#UG
zv&<wr<u3ZF_40XfGDZi<_TBS^Whye!6afQAi9()*mSX>s)1*V^c6W$Sg?tau)<v`l
zgN|$cuLjr~Jbcx=v+)KB22jNn*LF{g8D&Ln88al}dp at bh4Pg87{;GX|ibP%O;_}@C
zks5j0!2Z>krO685vznT_|Kh~v@~|K~rtYC8-#agK0 at Ja_FaKbEPJCENX$R|$c5p(S
zx62bXSg@=FKY+yzAK-J`Wg!>eyPXVkNl93LhsaC-2P4rRNqdx<q5D`C$3VFk=A1v1
zmO$U6P8N7bR7LsH3hu{5P3|uKVurBOUTMxMT`A8F4 at 9<JV;{rhk~*!oIWsoivM)eQ
z$(ImSt#PVf1{e4&^*O3!%yf#!MPmbn9jXJD`+iV9g at QKO>=4tN5z#B)N3OIdLzO~W
zf~u5$!cj6%XGc~R_V$$(x+VXKfHt+{hzj~}{|Xq-ib4vAhdq8y6qg9NXVY;}Gv&)?
z<#$!bSwDbLhCtaDQU<Llg`?k5(C+!p45f)y63adOt{WhoTK at 8$mHfYaW!cb!b9d2k
z?o2l00a}5HMX~bqX3KD$@a1?HJbO-&yOJdX6#Sq7hC*q@=cxwEbNrZeoEnrai_$A@
zRsHffwC+Oi0-t(Mv7<!!DvH!KNz)?dUCWIR at IEHyPcrveg&1JHSZVgM`A*PcfnxQx
z+H!$pyh}}(qHgC16VwHhH!)W$>FK#lt&;Su_(Cw%t2al5%fr%Q1kiO<e~#*>fzNwf
zCO#KQX5k)peE0(2ns^=;lo!#*?56gR-E&zu5$OL3O7t#f-<hWDV^`8q_pA*AJ++>;
zK<d6`Dd?s7#QFiwiU48XSN>uv&|8KLj`+6&Gm(K8*D6u0g~Q8i_3hw+=4}MgG#oT3
z287$GF7eL+e}5(I;YniQ&w at A8EBRHeACIW88qu}7Jg`y1GgBE=wZ?zLBlAakB>~gC
z at +7}6Ma#CAK$gGS!CE>RD*zNoCG8qW%fDYwv>exRBLf0xC3gin#u)<a&y+cAV?Q36
zks`57A-H*&1sSUlC&H{j!1N>;;)<1=-s+aB+fL3i1Pq<q^9tp)8J1b&k=`31BX(sK
z at 8M%@`Xjc8k*{O>R2BuW)7FO~Iu+jt80t6j=2hFpQtb_fq7;3x|Mv8te^I%1)<fc>
z@^+_fp``<o{ReOH59sB+Y$Ab@%)!{f-{=zG@{_U<hhHrj#MAWo#8Yxi;20_n5}BDK
zno1aqJi6)u$xI@>lk$4v)@vN%WTdgHidHE3Tfybm1{c7x3M+7`>h~z^aTXF5dJT^#
z%5P2=EhhW}2j?e~`tDG>r_ypjDIVw?KMh}4&}3PthZWBS5M_Ys)xgN6io;UtsrZ at N
zve0^l8os(gea62)_`is4dcKjOqT3G3a97H*<i6`bvFDccsU{|M2=9~33Z|#Gw|8|A
zQ=`5iJGBR5&}NFIWmt2c;Aaa6{&<|~q%T;sd}?EF(;zuzV;SK89sXZtv&W-^%nDg8
zJbp;bh-i|0j`Bi;#fE#qW)H6jO(zN0o%B{Nxa`Q};07NcZ_O0Fh;4XwbLr!ws&Cr0
zg;U73zLN0t5_}OYgN8D`ezH!j?uGV=X(uMXZ0`!T?$UacI)2!0uKqjux;mYlxvv%M
z`b2-klF_QM%>6kwT+g)yjO at 6p7HC5_b_zj9Ds<JCeqA8S*8#%M6!qY=VKLO2^ba&J
z^H#&Q=*y(gU-<byU05{xDhe#hjkSnvH4$gv1dw?XJxzjHDkH_mhJKxGc3W2F&ZLGc
zvn5-~p$;|xME+E<omXL-V2W-aLCEcl3Twe4v-%n0iX8{^OUEhPbR&s&FtRFs9k8ub
z!>iOM-I at Ar3~2dU`AcAQFhv{I9URTiF_Bx0N<}p6si+1G at Bc)+G#mVsH@{NQTodOL
z)-d9ms^m=)mR>w38pF0oi+%7AgWwe`32mFQYx63gGNZ3tUVWywo{2=HfMw>=Y+UPS
zJN at 4^*F~#q7vlcOTih0;oAqXi+#^5R_L!8J+e->e;PD?Zi$X?|R2}c6p|>94VB^^z
zZ$8S`<$*XrzaHsQzlwCTm6!(#?3of=+?od1`hj-))#?27-rU09(Fe(F_0$hg7-iac
z%I2PT>Xg0rmSNG)bP8=;ke;z^HVo=ov;Jvwk3&!E^vTDr>-W12HN?)1zV`q%+NxF_
z<2UV63*Akfd2rBLZ5YbE%IJ6dJrVoBHB1zkWkP371fRcSy&V|WfQAY-pya1Db1>8F
zrxW<9aBTklU2iu%+qbz%hH!l^HUF;m=b<>zzv}C+L0XOlBQg0nn#5FJ^6r~X%xY#c
zO+o)w+QY-O at wI33kbXy>AUsKn&fbFd&;QswL3wWMH5vIyf24VeHC)cvQhh^ks*lv1
zu%u4qI-aY7{l=S+aqJW|a||3`9~cJ?8Ly)2&O~MzllL_-f^+@}44!WffIM1!w(c;G
z7+~VB-;0{Oi?xw at lDZ|DDRA)D1j?>ax>+!Lwt(R#PmM8e+;%T%2DlWafqkf&htwY~
zrRJcqJ<-r)cYRW%ybs{SJuzeRO=T^(Lztws2=ka0&M#DM`Rjnc=<_9TAn)Ax3UIox
z^LoR53PPvHkjWItYb>6F)XXCLy$G at 9ZFxmdz0~Y$++eniF;_1uVzVT(U+<~UZ$Tz%
zlA{KELuHFQ1jsq{`qzo%IXwwtTQSeFn9ZE*Y`JR$pd5t!E_3tWU6fco|IYe~>mZ7j
zf2uQM0%oxOyQma<oS02xbIZoE&1DQGd1|aTzYW-b)~b*H<p+>3tY%Mepmk2K6U95B
zZBZb5Wp5tKEt}YAr-%QYN;5rx2}KCOxCv at Qwp6!ia+geuSdo%!0nvN)D$Po)zeg0|
zbJ~N)32)9Fewhr~6Ne6V26SJ$=S9g3A3+p}^U86}4Y%1ee-{QgnG*|(QmB=b+UroA
zRjSwqy6V0%e=PiG+ebisN%(8PhBE8+h>h-4yIWFi)@m(edALG*@1L(TQ8db6MJsCQ
z?;v|vp?aueb{QSpE8;%cEdl9~&2FbW?2PLS at 3hAXhu+#thy#~;Ls0CcsKZJ{Ek7Us
zT!V{VD#5)F`H=)P{amfG>s)Vv%Tu?U*R0s}JwVc990x8}cFA}nz=b at L#!@0<X_9ka
zZcpclo2qbjFly-+<wsQ~U{YU8p2VcwmP2m|n?Ld at N;^7r=nVeU3g-I>c+MKL>jQZW
zffuN6RhZkS8qG|<{F(VllOyk7G6Jwzrl_zQ7AndMC-F6Y1BfpQRm+H|#R4XCwa~bB
za31NM;0^e`>sbJH at Rl1Ks9?~?^vpY3#=_ at g)`1wBQ;+VL-Anc^Lg%L`VpSx3a8LB)
zvn6NWev+W^R;Mi8D->bwbEJWv?+O5N*z|N;C!Iw;I=d#J{qvZ6-Q%@@cBwVoPyJgL
z16D_Tl^1zXfD4Hec^4)sMJ&zh)+kG(9Jsr4MeRGrP<fbkxr^)9)YKEv{e5 at Zq<ztt
z-9AbCHw49|^UxbL#L~+B&P{hBS_G5Ofkj5YSkUiB3ni=?mJJSr=Z;s3_e~nr?-vJe
z$i=o3i~XReXO35s)q?5kJfgrXe+q{wf^U5gLr|nhutDF~Jj!m*#2g9>n at 4TsEhZHe
z9p6ANYq?1$cZ8-Y-UQ{9q!WF6PIAnV^Y;@ng7ZTnraUMzsR*!Z^e%2QI0echD>S5c
z_s|SA- at OW-vSYMa5{&759Yv?C!%J6al!S5_>X<`8T$etCQAnMs+^q*$gU)|DtQUMX
z^Nm9Bpxl)#+ll38={4rC^6h-VJsYRRW6$~O6sRoW73Y(R;vt%Vn#9v7z$!ga``vqh
z(@B+WE<K^DH3j(mINYn|Lm)1nVyl&A-{hqe2LPfTr*Q~FrOS#+a|a@~QfAF97$V2a
zSw;O{Y?H;u>1*|{mOOnf*3U}|!-RvgOTP?-S^v-qYA3Q`9YEPPuMiku*`QJoLIFna
z=)-q{`J#UNO(rt4X}Af9nSY{yn)HYiz=wP??FCN&1zTPxJdr??Qrk$9DSx$_!bFur
zW?bBP5^gxB?8C2wvaANmIyQzyo-eXBab|lg9&*>S<>TzMN4qtAYrr!~&<`?138)R6
zENnGNO~uWkDF4%S>*dAT1ksIc4f&Rq{x~3x#(*7m!i#r@@MZWI<g3&KReV$*S at D#a
z^AEjXC}jIg$szpOx=Kyr(Y;}<Xwc?Niz`{JkIpFC*|o?H={eXgbGYsep$2m$_Z8SW
z;~A|HO?ymU#&DI_kN?fu4HI{P390Cz+XHuA;6*Ia^`rm{TPRE5wzPC!{&VWmvW%Vt
z-`RS&)~NC;B;EMik+?iKb#HB9V$tO=wD7G>ZQa4Jyt44mpV<TNSbvUya{tN~R;G4d
z=T7v4NG)x8u4KH60~~- at QIKrM<9i0)&)z<sgJ_r*QA)3IpXBeH>>2=sgSrds1)*lB
z?m?qb>lH_$>vXLxWh05a+FWI$yuw@={44X&@E<)Hc_`1eq)b_vEJwlT;b>4a;uovP
zEN%;C#Mh*sm%Vl~F`~Q1K#g2BcND(hWfuM6z3ZItVf5#D;UB!JBLUV%fQ5&zjBj9y
zl?_{5+lW8xzlvELAZ@?5-2^Ndk8XjuBzxWn24jio;#xTok3I^9sFv)++kMKQ80ZP6
z%g}vDWfKgc2nY6}SN+?2o{oXwK&8_p2_TPe`JOd(Ga+YJ-SHFIpf~dpXaar8nz~R1
z{tmEb^kxB9;j7fqm5Oh{@J|%2IYc^B4+d(j1O5ul&}vN-IO}Q8$gX2-!Pv8%$_2f}
zUjv1^dcaK8BQcvl<4S#16Z$t3`Dcpc!?iuTJYapOc!ga3c&+hwyLoX)DU^p at eah++
zlYHze4jLzmLIX1feFn~^okyO!@vHYeLtSGlY;(D#W-1C4dVbR<S#(cZc9k9S&U|(H
zxvEW)BS(lfD2S)~NrvlBig#;9ycun<C)}-<obzgcL$&);_P_mkB;huoD$*A|`3RvV
z>>Bvb^*#n(6{re!;-g`oYb%T%#E^U^Oak%G43E)CbWgh)#J}o-#!{tTOkn(j0*vml
z*#Gjr6_vR+geiAgoI%kEx!!cNm5$x7eV}`&OHM0w=kD0V(HNO$JQ>Iuv+u!`lOGW7
z+d3R+&4?0|HzydI37lWXWJ;R&V at L48%F)WE5eB%*toD&t?dnXI_R{OxniT8tXCNHx
z%}GA=;Z+~p-y6O&AJeECDM8AU^bIu`fSADceLr{O23*Ha*_<JGg~Z;Rk_gqp%8^Q$
ze}%!&fm(B<(L1clAd{spd#UPmPg&#J1waaczS=bYfE>}RO}#{f#IuQzxoJp|yCt^i
zwE at XCDh^84+}%GDKw01R`|W(|wku#7rfog)d1|NKio703fdtl8wVpRt0{PobU?VuN
zX#*EV0^$7yAP75IqrtOxx!bsK7an(Yk%bl%jRQElU6+%8sz+z^*kV$k+tvotMUyrs
zo>J-9Syk)CYC944hCCGr2uPW~OiCb6pmG}%R%8F#PE-E~I0QdKvnblc6>OkPvNn0a
zHa3WHHKinDdA9tHGX$Z~xS*D_(+k)}$GwY&&!+5<a-Wg&A}qRYOvtdPWlF3J>Qaqq
z7?LR at 5#B*-fXgCax6}{$$1|RJy%l^kxxu9udjN8oxly6a?{J9 at ci|VUcm>N_X`uaa
z8g at u~z(=;%qxjBGpuiHv*(05dDTl?4rr8`UH7g4m+{$Sh-b)IIq*sLt=Pv>6G5xtb
zx$|3W#ZFGP`u5irTpMCL&cFFzHO`wj&uUt#GoPzvAs2JYN3G-{@ytIyaE~4<un0`m
z6^n$gJvhND at 5z~n&8^!RupSF*GRY~;lv#>jmm;=2)xvQ+uy$1IRFEM at M&gw<6_+-$
zIM~h(OR3+K5tUt{-gJ=UL?yRdM?OULu<eq`+4S4>!;pRVu1Ac~S(M%zb-#l0T00>k
zB-GkNucz{^Y%SG~KOH23$+EMYkuGE}F=6d%wiBa&##gRBuJX|w#3c)1>K{>QYuc
zNL9Y=PmCc at 2R><CLdQ?uL2 at 7D%D4BD90INXeT7iu0ok6!W1C^w&+PrOK?eIHz-;2i
zZwZvE0Yp!YKA6t~W2i&G(<QX5{$lm|hT<Obk+r>2N5`qdrwKbTgvjn!hyuYW at ZglS
zLqBtHB4?<r+;omBNeFEoawp$V&KeFco5)=Njt<{}6LH7DlEN3{w`ZLqSfBOOuvr5p
z)6N-K$Spum$m3Dx{!TCqTEOz&;V at 5u_Ig>2&U`^&pkIctaX;VMjdt8LfglW-$T|5T
zcIkBrA+L;|_iA9l5A30BKrbD4vDFeENrz5R0s(ika(GkoGHr|IDoy(!nMLs#z}1Ao
zq<N+MV#JfsYzdQ-Nx3-wg+(>E6Js(2AWOMpXX;c(dA7{dtJV2lwuk=#V1~~b0Q6<o
zj>%`DCM5-TI8UIk(L1JredkHJ&`W}JPObU}`LA}*6~Pj%l?7jPe-b^B_fa)1J<P6-
zZAGkx at 7}1Y&+ty2QvH>Zo<gvOb|U8aifS%^PyywhO^|&OneW9Evl{6p+p1I``Rpz&
zl4+Y)5~ci1>|8s#QI4?EC+grRUiQ=Uv_o=RTHkORev?{OG&-iClJ6Rr%;=d}<jY`C
zIW96p=W_vw at 8nw+5#?2^EHemw_3pOWuUa11JSbcM{-()D)0`d<F|Yk+?q(WeNkSqO
zd`LdAFJA_G_;%=H-g6WffyH1&3eN8uv^OlMw9&hj3KTBI+QravzJ|jNL5SZC)&piT
zkqrcMeu3JHoHLEqF)o1nOR4akc|W|L*GZU|SWs4LcF`Fg{$=C_tg4sqk|LY**lqjz
zf!nLIC2t$WpNvb}6Z50RkunkTV^l0cy~P4RW$l`9oI_+dP+jfCAG717)~_&|cCiEm
zH#96-3NE5|t><V69=#QG{Z;G!`J4VkSB?h|G)nNS_yIBD+PRSo0E&|YUT}JU_Ikg$
zqQM?oP-`yI2pBNJr8BC;8R;B9g-Sgow{8MT3XcVWw42nf?e7&UGqb=M-)6$mJh_*#
z3a&viD?*n_9wIZ^fcHO^u^VVU+`-<FqwZ at z7IJ*|^e2n6+rhUI*_CHM$K!3$oL2Hb
zw}mvjb!z42vx(|SRl@?kJ1u|cfUKJT;ZEYFid76^Hh<JCJDI7+jmer8*s#0f5(N&f
z&`(gHuFk<Nc<=@mzpsfJp at TZ&wWsmCe0$n_06(ejSyzu;Puv{g at WU>1L!Nm?5q21^
zBGLh>Bc}%Mvh~hoC>L+X%Pm}1<2||bbpDBcJ_O4xpz!PWhDkb?*A!?@48FIY*m9dX
ze)Gp}Zub!WAL&>4fX*P+kd;ox#Hx-ZscoSwepBZ+jE&&YgR_CfjZ)yhwuh$9E-O`S
zy7x}3kb)YOlbv?CzX=_3gM#YRv@|a=o+Q9ER24_Ed&Jzy_x<oDf+ at bvp`u0lHBK9*
z&!;LTgUH(+sMhESSIrQ+1B0E*JIsHtj}AxChY8RM5NuK>PIN&kTOVtWo|+v3glKic
z{=#CjUuvO9j>;jYJgF3uyrc at vgGP{F5{QPPR>bl(tf|bxFt%e#!8=d#p{p$rlf5 at r
z1|u%_{{X1NT1iXO4y_J>s{Q`VWQKre<5eMXR>?WAqdAzaxm!1wO<dTxyq?BapB_Jn
zD$&OHNy`Ji*Y*>;(<m4D(@>YRb|KScg5%_7U=1AX6hRG_R*CmMiqw(M1}<TwkF*oo
zW0K<b_3om3%~0TY-7abw(s8fEWsS}IQ(hPL8Ks-*lS|H7M{7)#OklRr_o`MX%q(Ki
z*}CR~K*swJUOo~Zrv5sspn^GCF-tphUtux=8N<@_N<1|J5_2>B-z*zVXq5s50ftxg
zW at 1hTEqMzTL_*y?57o`JeL2ob+IO2(S4sQ%j?;1|9AO_5&vW5*Z)@461^&xeNg);I
z9Uvf?!P0+pb%#A}k9(jU1;4OK&?e^9uxv9^e!aJtb$r2YStB|HKgP^<%XY~uNGC~5
zN6!&M*@YfHPaRqr8t89hLVu^yfE=+^SXpa1)Z!Tt1w1K_?;i)(GuuZySKLn(TaI`S
z)lqX*=PB<I=%8D*BAa$qx93?rEJHT9m%7=QXSB|#4JSR$`IyIRfL%cMD}pU*aj?Aw
zrv#>cwSQ&5J at tmljjcZ1-Bo|=29 at O=KC-hOr8Zs6D|;uiC7WHkTwG!Be0PyWLiYFf
z$lQNV_L-#A0(MpkbI{(|o9Pmu=oqgB+57k!$?RBrOGa8su7A=>dG~*;Y36DV=(6IJ
zTJvZ|&@TJzc*Qx3^3mF?8Cp*dD(@={lFF0pObaZi61fk`^s~u-d`nFAi0;J=3DyBV
zB#?Fx?KIwF2e}1AL1u%H$H2ThmO58tWZ+q?C>2ps=j$nl!hIn6I;(cvKWRJMGO0Uj
z7}%iP1>BzGKL7!<folF|{yO9+mB21RwGhPt6mY)&0KmaX(}8Capy8>O6jq7L{3Ukl
zVkl(*^y<kJ){mK00nXbU57&5}4n{2ljR>MWb^iQ^<!%7<ktZf|I_6*YpI%^k?{2-;
z-FSPwJ7Hy}{2``#7f*F9{F0?AddUFU#J|RGWJ&>a|EM+Uh((gITA=eXJzXDFj=NIk
zVm8Tt_OPmVx4+E1d90?GKbg|kr=v=HNt3#Hu*I7f(@;9Zr#hms1Jp-XMHp6GEMM;a
zb3TOMq(uOw3v^97WBz!x_ymQ^jnhl~1{Xi;lhtaVZvnpK+4G4SFRSW-Bvx%?SJUU7
zB(Y3FJ=9kh9A%PF at jr#8^&E*ow5#a|RS;Gv06htIDy%c|`x at QTlN-~>2`zsTP5<$-
zQ_Tl8OOFF8xBqXqMlKwzMpd5h*4;M#%S9bQ+1%hk7#Lgd@)D;dZ$!Q at 6DRJcRERT~
z4Blii>iKVJrKHKZ|6s<Yys)Bts^9rHoKsYPHSU+9^j4dduhp(~T87*h$%gat52j%~
zJk2E#?B_b3D- at 5=;4t6Ld5-$GEwR+nigdP_Ce-)hf^_xSv~Hik^h+J at h2w+`;n2Se
z&6e^CJ6Xqlb|dQHwr((>huuXN>pic{4t$c;<L1lsj~Ha_*`(^fL4+Z)X%*z`(3`Ii
zHjI&x-WJhms&$2Pz|Nxzb~vfq*({L8XDAx2lgI`3E~KvgYXa&cAJz`wn#F&o1qyQ2
zSDFp%HiMZ*krA;@GhA*!@D at F*S*>OFL%xT;c-;V~FaT)^Ed8Qt+%B$3(Y~5RB#8bR
zL{%B at 8=ao(%_?PJ02`R_(nyXftd!g^p+G!v^%s0n^WDb90Ea_ at G<NW5-|2I<>~);|
zyr&TS9&$U^0sexcNSSBJqF+^uK%BDIPi%;VZH8qS9hWu6=Xlk|TQn)2mJ at v+`-S^B
zG`?m7ij%j#cwN*|T8NROrqp!sL#dX)i-{)r6KMY(-yizickkl*vRkFKr!dhgaFdP2
zuBnvQoIq28d##qjXQ;9*_&3bwG?kJVCYcyl+VanD)x1mg*g<D}<E7V7TRPr!9xi2$
z)^&u>5Z_K}s>}BtKhjrGe~-&5vm^tRS36}i+ldk%=ESF2>suP5lE6A#m6P}mgLQ<Z
z{#v)*Tk3n<|5X#M-&|$dV7xVs88`5bDV;U+d`;9lsvso4h)vm at a9urCJEkv40Dc0&
zl;IMf@}Sn%5#0SUo580_FY4Q$`)zS<oQ{0mDpGUX$y4=szwNvUdjZRFyiu*T<3W|C
zC2b at v!Z8FV$tC_bckQUp4JAxDOt_LEO#o5qo8x8wOX*o9WZ6Y&js|dm$ZPb_y*vaI
zy|V$O?YLJHH-Iq91FR?`S)6*FRJ-#>+PMbZB*h&OcO*NpG$S(7SX?9WXx%`Z>MC(9
zC*yL$Uxnv at eP|{h3d}=o=Cc8Z;7f_2>r5F<)+Ng47R at 8+lfYrR9p5T5AM95p4j*?2
z%wS|Ls5KiLjr=74NdUOcjU>4Vvz}lZlL!C=Rb7PHiT~SBmvBr#n at pYR%d*DJLDI3S
zMDPGCpmeU`>0Mt6U$G73GehI~j~>Qdt)5Vqro!M4e2 at 96FgXfCylewhomWr1EJ+{0
zwIAT~xkRdLx5T3If2*;+TyB7Dt#srSh1fb1z4b1<)I|n>`?UAgTaM?Wj+}L?S#5RI
z3Sl at J-&ntVLh at 0*#eW6o%~w60nhc`*QCf=W3As{4t<qVk5f5H2G;Za-{8AY#t>(@j
zl8&m3CJTs%U5)xxrA*CVoHpKi-^FWD!HL)w<saMgN8wsClfmfdg?=9Q#zOLXYT91>
znU0W)M(UZd!6G;R3A+PJTvlq7rLO#RCX>4crfck_#5ZUt3$opP5Hy?|VG2<{Ca05f
zrSDoA#QbRYCp)^>&TO(>5GpS^s&`gnenfAQ6kziV6PUG$2nk at euW{U}Fj`Y#VB$>Q
zGCIXV==vQl6{WT3#uN*;E`1g<D4mwm-qwvEKV{4u&fPc>rX4Yo- at Xro7l7-~0y&>l
z)-)BwXMr3&)7QUQ1VGt9N%zt|CaNRlrXJ>aenlyBPLF+*0YH4l#+QC6w?R8OWP%}t
zJ;3NwNQSd~-Ju0o3;}DPs%5Y7N=?<)|9b&?wx8`MQ?bW<CIjMP=q!Q;VCHn`q?QjL
z^L}t)1!%Ydn?0CvGM>sUM+Z3nILw75S5N+X|K%a}vyB<Tp}mAw3=kcef9uXFnGSdg
z0-hZxY9zidlpOo0(c at -gVHq;(dbQvApIhVAL9c1QE)%a>dS6fcD$H9-f?F)uCERS)
zHV{r_JWfs)aG|R$wewR$cT-MQx3VCs#;<aCC$F6Rg{?Ww(tBe{^n6)jCo{X+b2S*c
z*8m57ts at SdnL;b;rqcVqC%t#WMvh)BNYxI~spwB-Kg;vVARhH`8~pg%k}^-act<fH
zPd6jd#okmz-ezS`U19XZN4rbeY5SGH%j&_(){-=%z at qwOxIoe{E2qpOE3qaVrX)-2
zZPhoZk!T-YbVemJmBBVX?Rx&pE!V|bDue0alF{Y9uLh;58E?l6igd-zx9~+SAw+5g
zH<iYp&8<z93v?=^Mhhb;Kau+%BqHB<3}Jdjr{f$m+yAST7*XFYKUY9TR1KnD35Gup
ze=RAHkXd7DS at RwRhvL7ZJrhh&p^eY#tNiyYnhqVz1{QaHxhw&TpAMyRs4apv>hyLn
z_*D~UJ2NsrdM_Ty3n70Wrrau*Z^dQ(ZJ~a%dTF-TvOy+%f$spIj6FWqgh}N81$34i
zsUR0^zcOCyqza+MU+^LYbD-avl2gp|^y78J$s9=u at cdjV15?MTID-T0XQy>JB%8!;
zQi{8MA-j`*p37!*M=xlSR1#wVt8q1318W2DDkG^$ya$4=@)KTYG{gHaS~L)u`BPUV
zzRx6~@*UDf5o~@%1K1 at jmz6`Tfu0;sNnqk+fxYT6 at 8D3+mARcgsV!)(QPeJ>s-pX7
zrzHPO;UpYB9A}tNFLbpbIV#X4S|4ZzFX~I?tb at h&pw!zxL{l{`JT)^tQeB0R3D3B`
z-a~*#l7QQbCy|hj9O;l+q|0JO|EsxfG}3F6Q}QVq_U+5{mj2U?ZIFZZYKfJN_FP*<
znQ#r0Y{uSRIotZB64e-=jvYEM#2Pcu-d)~bVaubkOB2}2mmZDa(w_ at R8<-)S>>qHE
zL`K`Nzg3p6`yv*{fH^fT9TkMIUtnVioy_&|;jWeMs*Bm``8WxbnzEk<19T~KI2umf
z6^ZueC*UOKhML03;*Dc&UasbTAmDw9nu<^D<g*p#`F<a(_3=q&oQ;fx<+}zVbKPQs
z`vpTDVFQ#E&v(w#oQ9Hvbh`(bw4}#6bMSgP{6X#7Ki7Z$Zbe<^E5D$cIKn?HgJY%2
z9wqM9ZODa-R}@abY*;*BydDb4!9$1GXE06KQs!@wE7^yaK5WC?YAL*2bgm4!gw854
z5)4|iRvZUd1{ON|@`3YH!pf-fDk<Hh!cI at ic^<j_ycmr$rL2 at g+ZSvA67HsD;$MIO
zHRkd^G at W%+lmGk1K?D>8RHRfeK7cS<LfA+#VDw<4TNvGJ0 at 5OqqA=<1jqVO9snOja
z(woxF at 9}%i?+?%62!nIj!}Hwl>%OknHDTU}Z8#z>(L(64g(v)4AOq)DVi7AhfXU{(
z!wP8>Cclkp0}eI#K!P_ddf(8#89|{xyL9|XQJ-8%@47&s+>}{Z7~@pLK?iG-{DYeZ
z!DV^cE1oN(R%XkGn*Oa9z|>PAuS>q5ofA(MKjtE~_#LOO{r-jd7%%u0kKvE>{{-CV
z>du?tk2}A_rXm^juyJAf(kYm5DW}Rp99*WSMNEUq4yjf!P4Gqd|5_uK9J0l}w~y}b
zU08F})VJ4<(xRvcoMMY|5rxC1-JwUfxjbb-YC4|j40q||Cq80~Q{~B2;l%5j36WDd
z^W|b2R at F+ki(HG2%7~SqoxKARoQF-|uxwJOV0}}91%}%8%%{cTERFRZkEPG|a{Xip
z-RG4D$fK7g<yV!@t18pmvtj9o%R?i8uW6GVvXh5AmD!H3|Fm_}f?<gCZ}di%NH&yX
zf_Fe3FW<8D9rj<`q-$++v#&*+t*F-99mI!fMuul!?}KF5rNxBkW%GWo%CJ2*Dkjk-
zFX^a<kBHRctaDB9su+gj!j2A6Y947d(t>-NbNUwHly?8PEdP|P-ty;vMJ!o_lTVzF
zCmr08sE1nP>_zv+>XHTWUEky=Vvr?5uSP~dD3%A%%);8VQ8;B(b__v6&3$M<$E^8i
zk!2FUHokA%%F3WTB}|X5Im!;<Q4;v<YDtu;$$UM^x!1u8>gI3ayR+Tbr4L{=ZMJlM
z?@|XW)AozQ7kCM`m9$=~o~#0&!56eN2f%>aVJFHF&OPc(aa5AbrpxNZ1{{@zHFBrq
z`uTxt2Q?Q8Ih>vO`us$YZE}hSSSg&c5xD;AS~L1ePOiDho&RiN^4{gZ6h1kBMw5!D
zpe?l&X}G`<fATN-*&8&vuMEWI`|zp?7tTWy`7?fSroYk4uZ&|br8G$I)BTMfOd{*u
zwfc{7{?ip*kW|w!k1$JrCBk}{s+2t9qT)58MNHaVt|plwUmyCZ3bql(bgToUGCE1M
z*VJ>kGE^IF?60MIUdE6$Zp}U!iDxW#qx^d2Lvy$iE1(l!6E8c(@u$T~yDu~~Fp6d$
zGO23#DplLRtGn=WJfZ4ZISt^heLo!iO150yQ2GPqtbP5AziX2zshht}ozCi%6mRDh
zlT+e3jkw!)tJnTeHT_oWY_+Jz6Q}QPAeSu07NL0Ro@)H|>5ZR9L}6Qo513Rtr0jgD
zVyMfq{({%Q&L4tqoq&NOYvj at N^*<2hhxdyoU$U-748U#~^rDPW1NaTap>_2}zkc>n
zLiNA|KA5D{y+XB}$_=$c&U!$jt2{%j4zq#Pz1K>=DJQ?;Wc|3%ZKhkA<0?CE>OiCY
zN4tgBjA$cqGS$|S%R3uEgF4-&+K%VpFF~8#`I9AX^A|Roo{-Y<sYC8U4=NzN6d4MT
zx(iV+-qh#3#jp}eH0^?0ulrsqqQU_=g#Huo&L at A}iSG~@xc)bxCUckooMv`*^%|>}
zjd~;T_8}hatW;|?%{vXfgC_u53jF<O7GJF6_LP?KghyIy!>4o~*cIrModJg_)fn4}
zii+aq00{4JKf3!zhT{1j8|SXyX~0VIq0%6i`%%*?<<R)M7gVe3nR|e;*>o8HmxE8i
zdRL1Zez0FZDLI=3&wH==XXHv^eM1H at EagNlg@KQwTcMuiYdsrN($bYCDz6M4uf9mI
zK0CLQ&}+?q5i#X^LPS6dPaW^Pf3F*4eK2zbiMRAO;z(z;+%e at 493!m>{-fntAWigk
zvsy?Ox2Aa(8apP_uK at Y1{e_wb;&4A7IG2K5OMD;6I^sqh%z2Wl)YTGBrIM<fv^sIu
zv*0tkcG;Zbe>QJhOUz-yi?AUWQ#n5(7K%biX|e7tItgF}Me6)Z^Rz?*Q?(Q)+>wNH
zpOuWX1&JV3(u7fUhV;NqI$7&X7)kbu0+0)^5uC8exm%6klv1w#BFPR9)~FiU+HNqx
zofTQH*sLhiAtk0V-zu6{2^%??l)badU$TU(2Dl(iL4k&}@8z5>LOy5 at cgGwSbLX>?
zT;a2RcxUR(DSn&3-dZ#rf-AnSZQTP(<NI56J8i%IUSE$4q<ulS<A-VVciKYz7B0eV
z*GY0Tq1#(ClmMJV<o3HEO0%V@^bK(Srag8PNb45hhq@#58|Y>{Zie}H0NI!9cPO#U
zzw@>i<uz@@JJpqB+hAZgUCQ><X30DV1#6gKlD`iD7v1xMWVO_MAW!v-pzhLO==7Ey
zP-fO^0*Gy1*1^6+MF}FRC=Bw>_q{#pZn76Dd3tJ7^6aannD+kZT`idzS=iBzp&u6M
z_2d~mm-aRytjS)-`YmF2JM#THXd|!oi_K#%LBxR#Gm>0Zac<Zr3;%xdCq&vK_1LUX
zWM?2(((?6mq}<83;e^Achoc8)u{6cdx>WkSnET?F`4~TY#%M~OF4&HqXh|baYUMSW
z<Wwv2;a~Q|H*3G3!V}5`pNu$HaXO<Wg at JV!SD-*$Q&c9 at _PN4(ZAqK`mhtK{f1}!2
zia)0}CixxI=g*98YiA5?8qw=oJK*URZ`!@Jvz={K3-pK>0^n;vhZJ1f-0Nqp_)+4P
z$v_%b3<0LzhCEVV_zr)%Lvh at Arc3`8_l at l7nQF9tqe<3E&EfTNA2jLEawT~V>@j%V
zD|AGZpFxYIi~O=E7*(bA^m%S*M%#L3$~yUPWfdCA<l?)1aqAd1?8p3W#Z}#jS`R>%
z1wB<@DbpNd?_BQ7W5SE4SfZyT=9?;+C3=F%Nuw!_5<+vZ_7e2ww-}G7B!~?`Zg(%5
zz*!4ZUlO+J9^Jd4XBQJ`1Rm`!{td8gr{i4pl3juAat(#yKvQq0;!&Ekd<W~n!x_(e
z_kbCbl|M+K^R|;QPvlbV;LBJ=EHdtpVFvgL!p?GJKj(Lt-R at w9I*r<nUtKURE9aei
zBWX5ByFqr=`J1J~M23j|M7!A at ->k;cgRoTKhU2;U`B^B0mv(1OdHWJT;l!7nsoqKG
zP<x%k%hs^jx2`{E`d0X_vjA)R^Bcav6J+<UG@#zPI}tc1j9gqRGO`qP3{83~-84lt
z7Xnl0iz&Oq2SNIqez5|Rpq#M=i-m!Kfmo77rwpH`^I@``eyb+Q!+xxFFu5)}U2gS2
zZ*I#_Mg{-LCljxV+K|t>M;t)(yrfW^uV_~JY2n9=Jz8v7(x+_@`E1V_?K7z`EhW7Y
zmcm5<1F)OKAaeVsj+}K+e_+G>YlH?yrXXSdaG8rj>D9xW0&4_~gG%_(CEv at R$p8b+
z*my{$im+v#abChOPh(t{vz1t$)fu^VINoF{^j5m`;p*Q%DqyWW4RE<_rTh;D4sn{6
zDzoj|NRJ5+<=ECw=87#M+xCG%VD#_OKyPA+V)cHX<3iKi#RU;S2~n%p&4Ko<i-ySh
zkFdidmuJADcbzHYo#WBwzb?a#;bXSxA#isHf78aDGS^iA=vi#V;VBUF5+Hb2H(%_8
zT2`%P7Jv3bdX?{yFuLq7I at 3jh^{C9r*+5dpn~H15={rTw^Y*NE4(*G*I=9OyKfd|v
zDwFyl at P08cGyr32WXIJ%%o)p3uRyawvNgCCsNfsn8p9Kmfx%`zbv*~`Wsf)e`})7m
z<w#JRL{{_hZ`XN`(tuoYIo97^RX~?b(FTL2+7HU)@<EKzB9?NXNUiD<IS_7#kXb&T
zU5+X>*nVcO)Mo75HSU2CRC6t7<Y-Sf?83YOo^tNu+X_{g2f&Y>ZER?mode1<`!$Px
zrhkdIJq6H-;YCkY%`O33I- at Lz^N9mm#n!y+NF=BGA5!b+A2_9BsgXWR!^;7X<7{;J
znc*piY1(p?^d=oGr0O_c+PU5<!=Rt!X}PcZk0cxZfhW;`ktCaUh$^1pF|ISfTz`Nq
z1|gwbc3mE0!SJj5;yYtTV&QJP;YZ8afb!E-D`snI!#`C$pX9J(B>?H_s_xb|Tdi!D
z!QcOZ)pwq3nU=KW!hH|MA)f_)O4Gc=Ayyt&NcO_N-;<9zwEP2<)_TH2W*{IHY>U}e
z54I#Zh+NWNR;Ek7eY2F)EIUU>j%5*;3q_1g7so7g2c8^FkB7LiP)@4g3q2+B^beX4
z);w2rezi+KK#!p0WiNGPp45|U%>%4I=8MCf83u+l!W!Z$1uAP=1TXHjN($fD#D2Q@
z%bk~qwg=7-#Xqc$%*s6uTEsQ#vl?n>p))n^Kb43KamNk!AQFn{(61QKGnJe)o$^^!
z)~33#$CAb+Xg7_z(&#@gPM+cX_u~XRj^Vkh=MNG{w3<eb?Q?tZ#@;zqOo+mwhs~pq
ziBpn15yll?Da(g{3V#laS8a7jRh}(K3#9=1hM4WYxYFJ7k0|D}nl>*GLC|MPSN8|8
zrRwi!Wgh$a_;7b$O~wnxTL+WY)oxqo!0|X-Yl>s%ygnE(X?Y>S!GQF#e+1l at P_=~Z
zqVasAv<swjm)SS at BVTg#=SLk-MhYO9pe1wur;QvPSHP_{NBc48`06^EOU!ISbF7b{
ziuV|}I1if3#JO1U1GA79x-afb+u2YrE=SId at Q4b}L_7<rYP at lfQ#cv-cg$d9+?KL|
z<|SK$<pKrw27?RvoYnmoQ`agBIS03H>q}I^VUxc{S!SwmqoCl`g8_}N8Rr+Le<zzX
zJAQme&Ls5ojYla)X_#kF at lV=MA`6Bc+;iLV0+1U|z3}&;49qu}Rrib8#Js+f?`I<`
zu}!iypm at I=VK%n*Rad<Z;S&9jL%{-AVsIl|Yhqt-+cDm@(nibIkCTaw$~K}pz<_0@
z=~+Ex!2KhowQs7U5zztB at c-x`6LoGR{$GsPJHtFv*MH2j<TKJGR4@#VCBZJM7qj?$
zHs0X{Z#vA>O`QFZs<4f1a)pKCxDCS|VJF2kvxb%xX{WAROw{meV)pOdzoW%_Qm|x#
z8C7=Uqdn&5t+JZ^osj38{CL`X&`TYv7xF8aGMQ#QJP?@<pC_fyuk`u^Q#sn>gr2EN
zDS&w<@!7AR%#9|-RO=7b-d|hL8hrS3rmh}1m2phi^i at Vx{2Ml@=C#@i!o8e><2qj|
zZbWymCR at 8oRU}-bF4EFB{i`?3GI2H!(ONqLf+yfFHqXWu=Jf1tU9l0IiqyfUMW#Xa
zq~&wJ0s8|l$(RCg|7v_ok7z9&0E$J=(L{LA9IzHzP+D`HC1W_cjsAIE+(X!-b87W_
z`jSsRQMZFB6!IZ9oBqmpk=9wOu~YI(_O)iH<@hd$=p2@=+E%r9>uG(f)S!PGfGaY%
zCm~4^GYZhZ6;&g$ruERIrzW;qW49ay78a at _8W!CBb=;*ZcgZ&k at 9Fy|{P;>)=XRHe
z_ZlrkjyBB0kagdHakiG0r_OSY8v5*jPL2R-p%7rI#FWhyW2&z;-0$0YTwI2!+r7L5
zc#8bCNEuCM%2pf9yJ<$TJ4aJQJ?)@7A1n0oM0PLFuE(i1OtY4GRg3b84tfsiw$3y=
zN<Hu^9F0k^3>vxSzo&DpLF&t{n;{Y$t#7D}n#u_6e8<obr9ba)ZS6oVS9Q2W()4Sd
zs`7aqq1*j=wqaa_f^{^NgnK&vF6uqZpZY?EH$Z_J^pi;tu{lDhnCpWdutKX{m!9O@
zkYA|~equO)2aOG+xpK at K*H>@VDf(}G&<fU2fnqS#0A{m%%@~t5oDuU`EMG{Xq;AgD
zbZd&%G>ki7xo}RRamK&$W#NPK?r_a`V_XGxdF*`!f+Qt2z!mocIs?EXjfXzi9Om6R
zNo{4Nz2P{ZeE;+#WR^~!nszhQ>1~80?)(r?P~)bHGTh1x18d9|797wQTUq4*Lh{?n
zPCTHfP~Yre-MO3EZtJiVnUDw)IbfT8f~w1YZj=58FvP?yumFj)5`|HZtfk1It~%*Z
zNROYo`!>)NyKFY~6lfk+A+i8AsHCdrzfnp%RpM{=*k;oeck2Rx6IKEHTC3z<lD6k-
z;Suw!oh<s;_pZX5sgCr at +VhVW1J_MbZMfka)}m@@rLj#aSef9ldD3brai$;)qwzbQ
zPU;p483r(z1n3yLsJ{E%>ywv|ZMG7J(@-R~I(6ul%1SeK&Q3$�#jfNGR9ga5FKn
zUm$g!S?&2%d7AB_3pYse6+DJSajt8J<Y+ybm`l0%=l1s|dW3_8Llxks(>Ha~hBzj~
zO3Rgoy*AIDP%aP>{Gb-mq at m8CeC)@Dc+&%^{V7O+w$JhSm*>m(<Hie$lb_<kGF^E8
zfI at g%5<h0PVi#>De);Q>V>uW^o%rV3Y<>lJHYO*L4}}j`BFE-iq%*5`3b6x<?%dUN
zfRXA2L$U~!$j#Xc9*Mclazk3WpFQ`KtX=y at CA`Ut=QD$$9MI%Oz3PINsUxgkDB#-K
zuE at AO9CLjc)}gf at J*~~+Y&f`zOqK0Ti4Eylzh8FuVS?DauKzsvTaI<`OTh~C1+W<5
zFc^CIZPNfHcJ32qE&8ouck at pPMQjlUJCOgp+SbFzr)gVYjA4h1+D-*^bn6mG{&Sg^
zNzIyG(~Y0^M~0E;1J$fq8;MC=FHLs;FcP>>|6T%hQyEX%!gK=Qnn}@aE5Q8XDkk$+
z+d0^c3oZ-XNxUa4e*v~_d>&xB+Vn3I13sQcFu&N&qj|xImINYSzZI%2W244C0~aXo
zr!cz8dtdo9K7CT`zlpY5-Ug52Y&t%R3Gxo|ztJ|jkg93>_%0dpfRWJ`)a(0W7^3NO
zycE3k?oBZnPT|06D$Jei`@oFsZ<8vz*Q<1N{|VIHtwf0a8i$aqE>*vN?)OeCzxQv8
z94op%d at c(-UQM=4s<oF at Wl;D>Nmt06zdvVFD7won&e+}~V&T5>%+#dUBr<|ueXpYN
zi#Lj)R#^c=ZgtQpmi3^$r+D at h@2z8fkD2+;zi2m2-=<Kh?7!bK`OCuTpB+pMw2M<d
zMn7`c%_KSkUd>>svxYMZoCIp8XZ7^Y6Q at r9wGhI22j3!F=R?;wST`t&%)TW1gY6#7
z7EC723JCIS%<)IFi4%(N?~G~aI5_n)dOIQxHbsR?7VT0(zGFq*yNa|5{O08G8Ii6E
z&&*#h3<WgWsIzrqtg6enMSqe)7xv5+mQ$!?0%Yk)eeqd}n_0Gc(FUz6vWYKm(+XYf
zrCv2$`vm)TD4{<R#=?0W7La|<<~eUo{$4c^T9 at rA0CNtnoQVx!p3qto)!XN3>|lOz
z|MPIpP6M^b0bw_x at K0S1PwiaM*()k#CwK)eyJdc4d~l-JSRmu&H5tsIr1o}36-a;(
z6)<tEKCMHO!ef{Dj&Qg;UV#j&F+ckKFblJB@{XAr*y>OPj=tBn!M>RXvU1#Ss^idM
z831yEN*8cS8C9u4B2ffh=15h$b9!^&A|h8>u&8(5DTAwe#r^qi+<OzPW2ZZua|Hu3
zPfJRK2#C?dd<c1)yKlRHCz#$J#<UO!;oXD_4Ng57JNaKY`QL!+{@>O at wfGu~=eLXb
zIw?RvUarseJzsf*mbuYFAQFo~EiOa)hJ!5A>3s>aR#fk{3Z{>#wVsJ4YWkJ_AUv5j
zUAEkUtrffs|6OJ~5;WKIjweI3YG#f3-L0f5J}KselUSRKq#TpQtY;2mE)(KJ3isBF
zhfEQQS{z|26p8IS#9Zc;#?)JyJJVVntG|3rl$r?m)5seiv{lOL1Z|RXLK8UjSZygS
zdJGzaS(y`LLCDP|0+Q- at TWtJb!h=mtjt(goy1Qb3pzogF{MnUiH`|b&?MBmo6CwB^
z@?+7X%?qmITiZM5;#ZFwape!^_2G!^Jkk7Uiq+YqF&W=#27r;fP*0LI>ycU+;=fEY
ze5`EO)2}UrkEg7EsV|`PJ$w)0RxP&0^X{mk=M(LdRQ41Vk*p=~12ak+#fifLp;zU#
zczqh3g0ph;n(&@puP?Du*IT;qtjM%AaA5LjYFcrQ7sd?1UAWe+_-5wF at u_AViW{mj
zo%G<V84NB`T)r2;$L_(HcRAsz==4i(53D?Y_yOcT-^fmryGI5*C5S*sQTf_-7O)3`
zrr=vXLnwecB>ZvVjK)<10NAT!H6be751c26pGNkMPl^^rZ%8Itj;B0}ASP at 2&;f+w
z+vtkV>$gmiOe*^fan3Z%UGF~ds;b3c0d{F^&G3&<+gy;5=by<+bzN1(Uw|A8n8E;3
zxZ-I0@(AA<J$)3Q2U^1gAVd!PGU)qG(vIdL_Kk`7p|4&$?zjQ!CNh^~%Dg+@!)%N<
zo#Fxm4n(GqT#2)rZW}Lw{4bDP*Xu{D{c~r>82xIbwnTk_%@knkYRTU at m_*b)#1_V+
z-HoDkn7(8*QPzVgZt`1-wiXJieb;lytccN=M{sYKB(_e8mZ9^R0~lC%UcfzdgG~p#
z6w|tk_A9-MgUjIBsoERtzQ96rZe?YKp}!4eDuHKJt`-(a2$4K=j~eH&Mcexx0zv$L
zIA;$$txUq~gMGt91S`5({|wsk-B^Y}j((SRjfP!XN~$q|y7cjr5<~L-_C^LPj=5}%
zvW*L?X};VrRn~u#t&>Y*HW6dp1P at 3t0<iq>5^m^e3muu1<SnuB|Ew~zjqR;uk8+)Z
zx{n0ETEGGvJ|4Y6aL}--f$=pMWDww7yuG~#+#3IFy|p_7IMcD3{CJ)2(YL0Qalxl4
zCqS^9gJOq`oE;@;aOU+0Z$%}UJQlNTd9J^zKJXMmj;bvHIY#VA%mT+)u6v0x)1p5u
zOSZHYg#3#Gd-cOO%TvgjWN>Yo0mExb&^)qZl#OI`_JfGB5naxD?_uU-GM#W1r|J8E
z+qWtQ<H1jG;_sbY*-q);HwQ`ptR5`ItIw7mKy=qNE>Ty;0Gl&O0%Qe$YMf~}kiJa2
z;a0 at NFb7a*@q3{Wai0OX$2AWY1wSfxh0Qu|zDpeZ*S%K!WMlm2VH{8mSj4z!vs=4$
z7yX`)7b<aXHH^US9=;2k>|m{wWMLSi4XVjpewcX}64(sXxUY`=$J+ZYtHyl5Ak-?6
zDn%Z}iHRl{-GxNRl}wrsO_&Xt5f9b+!5xA1oJhNg_*!;hcM3KV#&+IGFQMHY9sxU-
zw4&o~&9r&`-3Xj<u}e_ACr%8+V;!(T5<8|y31Ye~@^!k?aL~SFeqiQAx1 at Afr)RvS
zi(u{VC3_AiHdylMUqv|@)HV<;Tnvnk5$EQWdN5zIXL-#OgCh{g6tHi{4$zdbk{YRM
z5Eq16b-ETrqp|R2i134GHMh70Bv)7Ua3%}_CeicFydS6+Vl#*d!_`juAOc?pM#j|B
zceKYphtSN(z`_8WBmcZQOltEte{7>PTYv~XOBfks@$eSK<Em#UM?|UNSI2w*?*(XJ
z<fh3k=-%78UnpejF_!BPxc>v5fNdo{oImV3)WkS}M;ovI0vxN?(hho9Zr~Jx-=GP-
zr>LDl)FIC8Nj|u+4|BQb8iW6xhRq<&rUIMTai|xwQ_F_3>bx2<w{eE%4_r9fPLpb0
zgwEExdsM&YI2dsVy<0Y1cPNe7Lol}l7_TN(6W}jKLK=d^Iq-ATj0EMpYDxf9QS_S`
zCzh8HPwcEsE85uU0!os!b9~9N86PVnVwG!-LLnkwc#9X_naFMqEJi{d9z58-WDKvo
zp)D7dG60;h6)K%+2r1QTF{t9QEW^a1b|55`kd^{W-hdK>#cZtoSHmw2SnZJcJ!bI&
z at Yivm(6S4xO5m-8Wm@=F6-Cx7C~MIgFdylZ=m>S_c>Q4I8Bfeg9(RKrF4I!iMqZnA
zA31NV$rR(@+dbl)x<pGs>TA(||NZ>|LF$8|@E3rw!fc4g`nN>`wcVDb!lQLc-Kmlb
zyMu8i&)rZbE=3bDCn at -6K6V}pOvYTBa~me-zuZPX?=b;8;jOot4BQ*M6h3q&*%#MI
zun$jof3 at nfmgwoo58B^- at hO>lA?Qk&3v04U)al=BNeBa?U;!)~%GHVh{|Mx}fJEAk
zRO*}<N)VyB1i`9+rBBlo2wWqBCZ$=n^vyxAy1~Lj{lPPqd^$Mf8|M&oOfg#p3QL~F
znT;K&)5}+`sr5Kw<Q<Xi{&sX7-j~-tti9s&E>g_#vbOd9+YQZu!k^t&uB{65IB)<R
z6hpmHf>}Iq>t~U6+0{H+Cb{<t%Sj3TbuQEfHmY2Y7J3>>3kN3Cl~dCPIzw?rx(I=Y
z-21GFX~~wyypi!yDR)&?x)rZgbbcWVLKGYkDE*X<TqBCV*#_%7riNm8i~jM~zKy`N
z$CoPVr~RFfudtvsmd0h>>}oZ)=f2ertN3xnzcrOP$)%VdYZ5kZ`#duIm))aP*$jA+
zwA$NKMXTH?RD$3^AKF<%M|Hju*rek5p;NX(vRHfgWzrmwG)emXnH<OH+$ha`3A}3u
zzoZfxc>fYE3Rjx5-hgXUV9%zP02$AsHD-Ffi3$DQD2xGo<*M`qACPop)yECQ=00pG
zUNJg%;f0;was$MP%5A~;m@>eTX%<aI1x!;vo~y6{9Lb0BfM;jjpdkash~RN4L%+xL
zDbTqx;~!Tg(sSus<OO{BAb+x&-0yTJiPq~R^_imS3&+<t3$QoAs&{MIQV?%e-=0c5
z+dveLERMd*3#{D|%qu8c9F}jB?{6D!Lo*203*mYYy>leE_L7)fsjz6zc#I^E5a at SB
zz%yAbQ#=wzTReYfEYR_F6I6pjHd=?<iL*(mB_SMViEyO8(r4T3)=?|+4qm{8a?%vY
zYMP{NAZSJ!h_rm#4psiRd#QB_UM+F5);2s$Q at W&;#}{@-n0s`%SVqc27W^SMAaL}O
z&3M#DFXfaQpxD3zi>bOx_NJ?^Ud)MVduqiS$i=mdbSl$a=!NXu(jq#ZVMCH_>lSO;
z=2FNoN&>`Ma{of4?|98qOwMR{QFoCwz{CF7B%FKgHECLiN58cSim|v}2E;%J|AHAn
z8NAgH4&iS(h=;S)?N*ZeoTlG+ex3E&6=Nz$bSvS|K*U3vt4lTJtcxWKHJ~!6dh;8y
zM7RYI{t1n!tT2cw+v{mz=FCP;>PN72HNfUD3Iwm~tQ&nLZOJzn6{X5~%d}#0k!8E>
zTi~iat=Xl5Z*KK~bVCAAjwCfBW;%eA`++#t-&_g at ehY{5zxEITObiz2*`vQ#chScK
zz at kekJ}G%9u~(`HYq1fCe=GI|pa$IHMJl0XimfbdV;#lo#<Wk8SNI|ySy%S-IfF#6
zUD$ZeNbiz+4T{!U|8ZNy1xNd$cG;ZPl at l-+tYvzY7ps+P>G-=M at X^_}#m-EF`>Fl4
z8tlO}<KSOVo;^<#A8jc(YjZYKQ9DAmP|SlFv6 at eTI&dxN=W%~qSwLD59jrnJ^aX1T
zl<Bbx%<{K_h1sZ-1RIOy+Qut#bl|Go?j6@#yca*AZ)<F3VMah2q8fi&+*FQ}haW3*
zQDkKW>%1<5jkmWQZG8yevn8j16EzI77}D^Dirl*%_p}sf_SV2!2LHh+xi5TDE$HQ}
zbAY-sT_;;x6Ikjekjymsqd#$R!7{~bkx%JRHgCTS4!qH}<8ftBynQ1TTms`Q2(MCF
zk^C|+NH$3 at syB0wkpYaLwEN;t>*MT}_a0D2QX3pfi#&BNjEnm+y;fOFmPa?#{a?R?
zg7wVm*W!BfrIzyY3eD7b`3?&)=B|4}`B&cqH)iTJ8?{b;HZG|jQ>9}?RK$T$5~FVi
z>)GWp?b at qs84T-FAnFDPHjrj2xAUtOR?i`={m!)=kMXImOSEI>Nxd6Rm%#7@*J#h^
z0iFj9chPazLm*kazCc+5y9D6dj0b{DJ54&w>cG<e3OLFSEr{A5*>0JZ!@{(c1c8<J
z19Cv-nf~|o(*ZosSBam28a8UKMk3?S?c3aDPx(~t<S#{n#_}yuuZ5!p3{ueC2<be-
zLG}reDB;@=Cim9{a~IvxsK-TxW6(RdRB&^&9JS(-H56iYC*9^E)U*EU13SL7sT1UI
zBM+5<1~Ix=nj%mu(7dvSdu$#hS@}zHvP%lFiu<JBWK2m?*q}vGYbe6Av<io|>K*i8
zPY83S9UM;dvL$<uS&?&jHm9jp2G4>d<tE4X#o(25g}0~dtvb|7CQOF0eHRxOJal1f
zc`69(pf)scPd&SvTWw={&NQ3uCFNS7K_VCTu7>yfiG3 at o=BvxIxwV1R;((D5!p5o5
z((9FS(l<C~sIF(t_F!B?c91{lg<|)%<ab-oiRyQ1f<;r)R+LK9_pWgVsjO60{Z<Px
zm77ZGZy}DC?*$u<5cukKk~vB|K`r({j>PVF0JrR0)%`Nh0lc5MtF}H#JsTN{_5tz!
zw4AzI8&y`S#d(>2C6R^lgC*9BKU9)AEQxyZQa$Yz-S at db#Vl8IeczOzh}HT_5YdCR
zkbU7BY-|yAjTR;!(T1>x^V>3<O4Z1d#uZw#kQ8}e&3$aXQ~)X$(wWQ~ToVD!g;S_=
zsNZ9A$t*VOcR4D*oz*C?TL;jFd#5<+U3|}G7Wjocoe#Pm`8J#ZYq*7W)?p&l at S%_3
z{4|D#FbU=&2oeBI`5ifsj*Yt^{^;- at _yxF_c2N&hYve&jN1N6Tu%%lQZq9G%<%9+S
z%}>&!UQS<==eJh>4sZ`j<ei-gG710`q1#F`$;Pc}vrFaEERN5;FntA^?AiG~Je;Js
zTb?AK3w?><iy{ma@?Kw-ZO>YU0ZI9Nvj?N;uY8L|uJN!`xsmg-8D&r2utFKr7CDfL
zB^KXQ546GsA|Qoa+IpUe>a}3HAaVt{Pl+px?ypLIMWwU?9O<?JJhV}KvwhpQx=z2#
zjwb-7!g%Y}bIkb+Y0lC+`bLMEo(n2y&(%V!nQ04&W^-C&v4=Hpp2Yroii>%D4rbIo
zchK}0Tji0bCwk-xe!oGgPN;R`rrU$6&s<DjKuoOAvMs~}-QmHWbG}9IFzLaAE&mnu
zTuU2#N6ecQ(JEK7Tk8h>qf=RjF?H~p_H<mx>4(Sra|FmH8JtMJ;2jMm*22b%I(CG(
zDYrIb-)PdC2TxG`^z<%bSSh^HQ7FZ(^G0=);YCFdDcA!%vkr$3AZ3O=f#jigItBZ8
z^u88u+nc{5YL{rfwI9eVw3tXrn>{1+CC%jx4?4ud$E#Z7;|t>f=SfZg`)3|PUg4|N
zW#Df;KZ1wir-^!{qG>GsMPGSYP1~AbzH$9JBPMGvscFQwm=cZ*Dx6o^;Ukpz at sdb&
z?@?zY=K}DD4?{;lZ_tViFlfM%8kWv4I at m1|0P_NALl7iO)r<f8_kU_KVH3~<sm->~
zf4z^&WrU~7y<iJ$+(`gjv{q{37&vH67cc}@ku%(w6s|k&yKy`AM2R}_Nh~!?Pd%85
zNFea at DQ>`E<f9?6h^*Pnog#pkhFh#7v{0}W7Vrt)-+!~Eo;cqx(JkSz2QsRR_$`MR
zksV9?a0jMW^_P)7JATItK~n-2F{Pl(Gh6`JJ=x2+4{MA=;b~Mr{<yl?5G#PdUq8Tk
zK9Ed)5|v<HqM0zYCT6_^|GZtWb9O{~{{}e*;rfhay|q!)FnBBfiDEj~8ICD^IG0;!
zJrM=++)1$8AvPAf;6yfL7sn6h6KOlEyx!V^BD#)j#&W29*$l9ErYM+{f39hFy2zBf
zmks>!jXveetsfJE8=xHZ_g2S<wI1REV%!Fc^GtEjiNTK=WGZs?=V$Y0O(U<YY(1$|
z{%zeXZkO*|{5w?aJ!P2F;jPkZURaRSVBNCy%y;bTzSHE4pK2W5lMHVH)~*sJZw2P-
zT#4Ikn}L8Vu$v0t;^ng&Xda`*I%?896GHkA>o;Xl;(Y4jeRkS&5(%K6mF4PWQbDp=
z&Wt4jmb^v;wmOGoTS*ogoQuWRoHR9cF=v+5&Lh@;a7yP+Ae}HM?vxQHQT;?kO&AYE
zr-hJ2-)(Z|;H~NSx{jc_G5wY)iS&<W<FAr;yzo29!p;ET^<Q~(!q?~4>*wphviYk{
z?FR^~DRDUxl?^NtI+Ei#r~g*^J^sV!*UW^rQhe;K49FqEe0-rYVGzbJ##jL5Xaj=y
z0x|1k=Gb;thRQz;l{1fNcWx!U_OZq>X2aDgZgUc%^creFgg?9hR+O5En)oN$)yeg&
zdococEd@=-HGAh at n1Q|k1CC|vkyKMUA=Bmb$fe2W!qXZK3PkgiTDzD#6}u&GJ^;P6
zD*F9rETGz7`KBbUUCHR7n47%T{js)UJ}{2 at T1?|F@(9vT34S|u`Zp_H*0pD+JUZLH
zC`X$F^$g7asPwcKb(i~z%+t+`5%dlkWi&1+_D?5q*bT%sOj?wCYIRQ}=wpq>@k#p(
zQcpLZ?lk<5Ep!4#I^X{^X4=3o<9{2O&qz|p2w5cf&-*t<v!vgxpx&$+-U17-_CJBj
z>5LUUG%$9DJ4s{X$1roQGy+m-+19#uhS%LFKf`l9Rk{33nTGH%{a=Mek=M+IfAxis
zERgOElTacg_bK8GVx`Vi;Ri6B<g8m5Azfd-iX#?Pugy_#e^fTMJ3=vAo`^_1ngtS|
z)zpKtdN9+zkLjaoDuzre4ACqcqqHF;xfMDS?_S at SrH<A<oc*WygOU`#4w;OKHonS&
z`_`W<G<ny10ddYvc73>1x0 at 1qfx61hjaee+ug>FZ8Uyd@{qX%$qHZN<;;M+6&C|@g
z6F}pg#ONQbHoFbue=la&4ZFw$F`x_5I9C-(AJ at 0SeuYB7blT<XK(;#3Rxz==3APAd
zi(x!tBn;B2-9Mp%rg$F=Y)HCTYqYU?`Y_9Y=?rE~ziG{y#tw+`0jHiGAu@<H-a%r^
zd_sQ7AAp7!LcW>wUGdbkoy9D#CM7v%)U-tc>9xsHe!`z5AlARm1$ad>#~=Qaf6VIc
zq20y}J&XV5xRx?{sFW00S@!hZG{Jn(RP$!gYc|+;MaM%IQDsEwr^SBPuNPOqyNV^%
zH$W6aj%^Uuf65P#Bu)UxMyD>EEVpM*@AZp6yfsuh+csP&CfO?L|9zfsP%&(Vn5&CE
zWQu=K&Crj%y+a}pWJ&hda(36aFb=E^ZnEYkA^!;Jo7OE^)z_2PFO+_OOQ;W~@9)Fw
zCj-X3%!!CG)gVeOcKVu~6YP2A+OpFJ%!h4~+MGv^9u<RRI8!|%ZU|yWE76wMmPM(J
za0tyt at 95zB$JW0rsypH|Lnp0t4P7y_`<@~qnju52nslE#IO#;>a-d+Bze*ggZ{DWW
zZpMzr4KIPb=V`y+OrnzD)F&I>%_QgX`4ZeXnop}o^wiF`Lyk~weCSM~ykqdaj%#o)
zmEl252->keB_aHzJj}Hy9$KJu5L376UQNGqWgCi{G9-7oPNGjIZJwVBPZ4%dg5$j9
z@;PX$m4q}WU&?YN+X)TT-pDpRniYAyQ>%5$B)2LMK;|(9gm)-`087+(lG9smz*^&-
z+d<;o75eIQ|8vNvn}-I64^^&hSKUL$%p3fro at gMSf$kDn!XUF`m*<L0qkFHTHqyMg
z^&w|qB1enNMXh21>u(^z#?-CD+0pA at q>{&12P#mvXeqS7u&Mco0I2|Gwaa4X-~v+m
zdtn;{4_#7Nb9D}!e|$O%6u-A1{QdnL at Hm}_AP3bq;QhB051<KCxB9{t$k(3kn-qUY
zKc4^#Dai{SAD`u>U(p7R$EImTCHy!M+-Bb<C)U|ro!o|a{bziTMffi$%jC76Zs~Qh
zg)-Po8;;TA2FBJXc#CvcpCX3#uZ?O|sJ}EHCPMTluBX&%S6KPd4dO6tt6dbi!dcCK
zd at YqTFq9&%Me~Iv-3<$@t&_!=WeyD0_mKZ^pz4KPq2~hQJ#4eU`W-FZC-<xzFLZ>8
zhC`A+_7D(T^NkCw19iG;=|4%mgSE+jko|{PC`hTp8;+nzRd at eX^%inr?q>D$&mSGm
zhF|?M8Gsw6l%0*pH`-3GS%|uAnQy^1TliMM6D?o`##aR{`uQ;n1{xn3=pQ;UXbJp{
z>ZyEXF=2bl=Id*Q0zBAV$J6!3C1HMVK<4U$=)>8fNj^2IFt at o>QS_ci;aSDfsr!$&
zQ%;Wv_1YLQHYG<9OQoRl`c0p?z1SugnfX!io)W@>r^ftczOhDquXix)m(61JE7`v!
zNb_v%*m-TpC*aW`DR3D6&<fQ&c3xG}cAyW&{T-rRRAeZH6GLB$lL4W5=JM$XV$w&i
z>QA`bfE3pdASKYJj=avJF((QDXi&?+kgV^z?@LUyH`YyWS_~b0#dfp-w}_J}eO-(o
zQc+cyeSX9 at 0Fp(g_kjs5ZfpL0tyX(>3Ef1Au4qYHP6&MutgqJd0mCN?7tjTQes7F_
z+61+%(xIV%A4Gw~BJ)_2ZB8KKvo<kfv-eRz8MGmn4fUt9DfkC172M3pbkMWPeAYKB
zDths*(R{bP>`}0BEM{vu!jQ&^W=89k at Dx@}-dcVvoLCSs_P#ZI?-8pGhH{ROa8xM^
zA>Ixo&`R;#eAcE8vBTeSC;ZmJlw9K%Ee`4PG44tCYjL+;2A}p|smF3;+<T$aUk^>;
z at 3pR_UIqNcu2vO5x*j`@ui4b2cBA0GroFUOdXY`CLfDURHJ({c;u$2k(Oy at Z3ij8J
zLPXA;!CU!80T?lqN2Q0mK|o_h`2_VP6J1oSjadoz@;(55&mM{T;ZA8^xn!@Yxcmp_
z`D7ax2~NbQ at 25Eigj)}GUQUXBd-<e!UT!Uc(;-E+O`4|%cj%$OAOBFh2`Yp8Ks;mO
zQKQIan{|&tExN_Tg*vX^F)y`nwxPVFeJ7VpcJ2;l+RiV6hlb398Q2E>XZTZ`KX~;b
zCkdl at uQ`A2c&195d-ba-NEvQhF;l91RFdD<othJT;y#~KW9~}ha#o)@$3uP;TJ+wB
zKz#Gx>@;Kv06Y+DeE>7%Sc|W7*Ehuhj|(LDCvhNrtW+3qHJH9^ssW0s333n}UqJ5<
z|2mfGpE+SIS0USc`SI!|L6DoDP|~JXdjaf`8aK;XBDo0aibENPz$*jTA-`YQYya*0
zXuj|SZfon_-7KtRfpas;-7=j3z9*}*U=g#x{}z*gM4PPu5EUnV(EOK}gm`!gt$;p!
z_VvG7+2PF>dp3(!oEuR%vVf{oCO<gFD#OCh&Y}$z5q~Z=<Ch)Zzz|~?EX;T93ml1V
z5x+q!iGEN7QW{$k5dEQSKwI_UgyUmCm{cabL#-_>+dsxjf(@rQP&gHcDv3GUOGr&g
zDLU at zxvl-p3)8jxl4d!fU$MicqvNp&lj_Oq?BcBoT=iRP&$B-JaVg4T=L!A`janVD
z?+J&6mSCr67K)0S<RX}U$%d`dttVLt>3ehmOdhQm!|F`4><-dX`u-M^+}uIJ4FAWN
z_7FoW!TO^i-5CEnbd|&7D82_7#KE!_^hC46XTy&E2 at xS?t|H~*7L|p8aeyHnS#f5W
zbip>8`My$b6T(DN^q|4EER93PJC!fl(ys$q{3Dw(bDxI(6*UBJpqm~;HDq(FSf?*B
z10K}o`-u;T5eiOE&K&$T88^bx>wOgh<0&+MtRR|J*Vp^y=%n@;k1cPU#(u{ueB_rV
zA$_J!<%>MGpoI(Y+jlM&$RCk)k4r<mr3me;FkN^z2!l23-GK-N4tIb!6bpAgl#qWn
ztS=8*jvR_RY}nVZegb4%p#aJmYD^f2jv)dB@)`y1y9JDB1^pvWjA?O}6AimJ8f9Rh
z1{~B;CEGv^2Y>}FcIx}x81drSW;*L<z<g8h4J<%y^0WONbmoaX9m59&lk(1QrGhGM
ze3c&e&>8p-Vg`Ic`Cs6M(^PCYqIZ*bsF-OE7+|*30LLbSg$2!)jb!%y;P*7jh$<V)
z7k<l at MXeZ8CmTi-MS%|$Ndc96D`E9Zmz{gIEB`a&yK-yTOSrQ-rk`{crjPx|8CUFe
z9MXx%EP%3tf7+Al%d_i`@`D*ZJ}i-mw}!uNA9tJi0ZPx463Cm#Ds_p(*v)#<KbD9x
z63(TCruNazjoOS1<f&M2XPb&TYCe3aS|q2-GT at DGiDi|9H-5K*Gx_>f4eSd(=Y|yx
zhawlctpA|S)Nb|+b00R4*X-Ic(B+G`amzOGOiX_JNbb=(dsq^4pN^6^vibcU2x*{f
zKt44Lw0vk8W0$|p<<P34#GGZcL$s_bT(avASD76PZ^cX}7$2G4qp5#DhQ&S^S89z6
zylGQAO7 at j=p+30ZU4o?G=^|)l>sQ{UR_Iq7A5H~E+-Bx*KxD;3f318?)H&*gHt6u(
z^12r)YQ~}WZaCh=&T-lv<2k1LZ8&i!)HC850-3KRFzV7m7{9AEp~wCDpzf>LCb5AD
zt-PcO@@lrVZH4a1#_vOs{Gpl at B?ezG6^QTSCxY}TfH}93+yhhvB<3H+F`>0~^%6<A
zU14ZdL+1KH(WiXCaeInyb|^mlXp#0cSByPC67X}&yDDC!t(TdB at H_{8L|htR1iiOd
z@|nmRJz)Rd-K#GvjR>{;N=|RS9NHD}LMZ at DjU9~CGBl4Q2l8 at V3V`d+ro7}L*DtJt
zy7*+QFMR)L;Om)r#B=PFVZ@)Rjzrx`tntl$a8u6&0;T?9r|}nm`z}FbQ6x}AXy!*A
zf7Q_hw0aTC|C<bSt-}8u<xM40E2SAKCE-ojwQ~o!N!4S0cWVm!Rl+;VYS6^D{`)51
zXY|37Vk;zH5|u-HX`g0ClJlLiOROXRjJ_Hr)6-L0D^rzIS-2q=aQ4F{qqX#sqssWA
z2#lWb*cuq6vp7Qs*ThiLvEW=>!V3$iI5&Mu7m2)mEoF0IY(9wVh04<`npG1$W$=X4
zvTfm`ivv2rH&d+7#i6dkijJ!@{F`PSpGMI#2qMN(Thq8h8mECz)pZhLoX$7e7A*Z5
zsd*YeSp at RHc8L43mqhi9c(f*v5vCE91UvZJQc{>;&P;^RO`{jUWJ01^`NV^Gsp{>0
zeKfbWH$a6xKj3Y&cSJN~EuAuQ(*q`;CN%9(PS%ZwxQ+jK)w1^ZV3d$awg;oz$<Ug^
zA3cMZ4rHa33DZ`(L`Aw}tS04s=u7}o(T9K!3Nf4AjlpULT23U~Tm_yK&f0a~j<m-=
zH%WH9WBk{3Nv8p%l`{9d at J~Y_4dZ}kH+rMcxlOzVxp~4<R2Kx<o(48JT9eC>dbHa<
zC>q8`fILUc at +9?$^uPm?GVzT4NwH}~KdJQys`@;BcmznVi~`nOM*1ZGGvS&{&J~6q
z-zYpWeII}V-fvH!#3}jjSRuZBS{V>rLe}Q7_E)Imwbe)coYl7xueZ}MM(i$vnE3ge
zO1M$>m)%>1DN~lQFjJh~-;aDbl`kkst~cCg0!f#U>jiSrNd-Cv8<3L at -$MvZ`%bhP
zsGi*uVte$+xbi}UD$!m0w`NLiNc`-YP0W#ri>y6{d?KfN1gH)r_yECxUU%YcZy>|5
z+RoE#{K%hG6;8#&FswSv<-s<MD4{OH{nqUFSsVQI8^mfo44(I)QwfY{^~N02sM{`9
z4Y=jieM&@?-%@}fZY^?FGt%yN>I`Dbow&b4_K((ZDRr^l^9SOS1NF@|A~+TkWSXSY
zw)%Zn5ei}T31&xI%fBwfQrG9tUe~kUgEs5U>UQ<KUyj;MsT7ixtz}*u;JxJb-mG(J
zDoL)!evwG6zNmXukj!YItCValI%`vuOoi0k?%bA)(+Mg?gjTk7(q>V$zzMj#h{b8z
z)F0Q9M<lyz9Co|`w4Mw9eKo!Jn+9Xj6U)huCv5)IJx;8AegXjCE4~?y)ZIDgR~I)m
zI6Ju`+B$VnbS9e9=><eh<Ts3mTL8~g=o2j|8(Z78ueN%vn0_1k0dB6vX5jzBsPBtG
z`<a at z?MAw6JEY)-0L-Om=U=#K2M}u2gZF3Y36lwI5%^Sep~p^-9&jhwPnxP1<VR37
zk$0eivcEE*<F;?1#m{Ut>{zQ9)Gb~EG+^=aqT64SONKL4d{k at 9L&k5SEA~#LW``Vr
z__e9&RBhsKl4o$S)G_$;ktg<#3jAjRN7^&S)K2Vn)pK1+C}*JgyUtYzdwD7c9H5qi
zaf48Ylo*@7*@Mo~GodAt8SL<H#ylp2*q`TzGmfz~N@;`AF8}WZplSRiPi(P!FxSs*
zg7axA^ul5PwTY8}CDtj3HkpuP>(zmtfEaqp#+V#NUZAjG;a_<R6bkh2&M^nwIwZ16
zR!?*KRaodT;P9N=@f9=Uv`KDKJSz`wi8|wM;V^R-7svGh^ZCe|CU4bXZ1CIpzp{>u
zyG#}u`3|6~<0gk|slH7QzwzASjf3{*iDXmCa-bt<$aT)*@xvz$KL4sG|5fB_pABK_
z8muQims*_t>5Ua&0>8X40vtg6TNAb7xEMx<hdujqI}%f at h&yV67Vd>^kGNSm9Yv9b
zv!&(w5*|F32s;KhD~$S!(`0(G;4p8hr{Y@`$ZXz{=X0FJa2CMHYHzC89C)HXg7OhP
z-|=sH+G<u&^v7iYhh1|jznLNoN7c`);`+8_=h|hVUuTH1MgQFxd|^&3u?)~;dA{^5
zpr*Na`@+Z93u;V%<o69IxrLPBUuYGM#sTtep1=?gU952hFfT;HUyZh`!8{#cP3&_8
zoPZ3+AJ#STqIl8#p^)$)*c2lZs+icpI-~Yn?>c4&rsaM35n?%2vi2Wqk)pYZSr}xS
z4Y)B0hb~7NuG~bwpAVNZ9eO#|IG6kW&%h!r@`7<Bh6F9pOo^V1-%Rp!?&^NiuKOrL
zZvm(XbGN^{?YiJSjiE;?1Qxe$I|bKxeHu#1E&j$riM%*EO?104)a-g=kP4kmuJo4Y
zq8(c~)}8Pk)S;{RLLy;@)6TzEP|ZkyT4ZkBD_?Y1<Z(BAv^Z1#03(IUBfjdLUMs?K
zxGOl`#z}*M6uKuZF-_{^QB~fn`!)|P8S*9H$`v-xY}Z?UNbb;q)g#Mz7iwdmv|GD{
z+&SHKl$Dkr3c+rl6#l at IFJPn~fx7fr?5EnCi>}Cst=fu*^^b=?Y8BDHf1i43G&6?)
zD1>8idifKn-G1l{5?;Z2<o>3Hhq5~xBzxC087ZNd{Xl at xZs*3%pqJ9`Mp!hb7MaE~
zN3MEF&|ihFT@%qK2T}J*>L_~uYJ;bij{Uh)L%M&3{PujVS at qJ##ZachCmZVBgkRgx
zchMW^@zx)LD4s!kpHo1h>WP@)b)wEItiUTk^q}0%8ylMQxW6)stzcx at XSb&8R at Lag
zEJ%SQ6}DF^HVNNE3`9JFA^2_-?dh6u|FnH>>R%T0F9{ps9cB+qnAY<Z!V2VvO=rMB
zLRlU$f})pv2FM?B=FV at Ub>W#wtbnfyyj5Dc2kZcJyljg{e*ncfUx9y*_>zDjXIkPe
zdepWz0MOUu%XdMGd~96s#sJ{Dh{>q+PLm3%X<LpGs`oMgMxOEINP1Px+Oiy=-Ox}I
z@@V@<63}ou6q&bRIGZm1rrxIsw?r$HTw^}54<%`7Pbcd?;B#U#4-N+zIdsw<6+n at z
z1K2EIX_Bq5vf)w{D|nwNoW~i at G5Tj9P@CWoEkHL!5u=I8!*ujqOi%N!M=#_>J21gF
zK3q$n#ZSGNMN%#A_ueK+*zk(t^JBh!Jqm~S at Ph_V=BU3Mr6GF3d>gg0Iho0913oaM
z{qjorMPi%8!PnhVisZ1zyQ_!1rH{V$gP!5F4^FGeyDKGqjB%!y+$`Ix5;oatk?%*4
zX+_m;6>>`ax6}|IYw#FL6*<Qe{j&aJb`thYcBtMej|wl)O_w$)njp#IM*aX&lNDOw
zYEy486kaGWku~d_&#;v-x^v1-Www<4^e(I~YpM|E1ieP?hT>AG1L_n_o|c^bS!xRk
zHGRGC&a>hfWnyCA&3Uy=#ekC at +|iy^$gYpgE>iNINRelrURD!0`OHRpglx8P_=j0o
zgs7obi-k<Rstr<Q{3by;6*)GJA2%7`4|~Jl?4+W*?R4351ZXG~cZ=$xO$L!egnr=t
z{E&XVOs5lRBPqyY at Du<cvH<k<Uf at jI=sTcBTmgvT%!Gs at tDiT~ZiRr<FWy^=%#Lwf
zsjHB#&rC^1*<s?u*k%|;-9`?!lfEQRGcs;lX_uDYYvu5o4`f}%$5(t_kYFDODpN;Y
z0vNjYi@?%z1ikhqn_t at yvASaV;$o_ui;5C%Ph=#B_sfPrHiPy+ at l*YTMed`~Z94&#
z(2wO5xPS-OC4Wws0Rj7 at LJZx^fy)*67H_qxY~7a7of7Ec?R>J-OUJ+{P?m%ah^A$$
za^<lfjLxVowooCkgffutuO~{Od$ThM{RJb()c($b=^c3 at E8!^Z`*>+f<v~f`bdViK
zTaRrv`RcY(BGw}fp2MLI3D>?b9P2XOvhN|k&+Pyo)4%N?=uV4F<;bllzgtCwW4@{J
z5Aw?BQ;pN!Af0LQ?J*VgKagU%k?k0MH!Z1lGl-%Y6{IY(b6&$)I9jm`YOxMzh<hSs
z(h*DhIx!qb^cjqQ!hpH?7^$-2$9Y{y2C>P~GXGk*rYGS3yDSB+E0Po4FKmU>qjXih
zTay(l$9CAn4zBJm&YYG(H%N<bd=j$Vd*(8-#Uf%N1pLOZx+Q;a4PF>p at Jl_!+G&aA
zph_MVJc`ryu(hq)f4ov1a0~CE`}6;3`tE2d{Qv*#BBP8_h<Y2 at vf`SlWRKiyuk5|A
zomB}X;VN4;*B;m9+Ot&GcI~ZeUdgy2{9Zo4^X;7esif0=o!9I6d`$7)XVRkygR#YG
z2~R$%ONd-E&^A(9E*m(+FtO1DpLh%?GScDpWetVaTov6Ej~ygMW=`onEB?4O4Cm{F
z(J{X50eF7Z at Q!9)4R(pnLCK(De`XdR;MT*gVRksXL<cbwI!sO2-hsadmk;MO-4ln%
zZgw~X?8y;MJ8fCKnUjE(mQvJ at 1rpvX2iWIO6)@ZEO%b^WM!2GR-YS2d$`e?9M`-{+
zigkq=^*hm#BH(X2v1o6TTnXfPz7FgIcRORff?-0AKqX-?#R?9zAmu|J0gg(=Pxv9M
zzr(Ai9`k!%7PEK%2}srom7e}#iGxPljd_pDGBuNR{uul6b=QyBNn|K{vt=D}QGUG>
zc78HOHYJLoIt{NHWpaA_Cs`|Ps&r&5XvR7-=E50yA;0xw at auSJfa5<WZ3yqyY7MUS
zu2av9YPsD%d-wVeh|ZESA7Ab3^%GN0Plk!oL8%C6oZH`1VgQ~@viy=`_oxg-gg4|d
z)YHX5<2lBSj{ca(!Y|jK?h*C7D~;xy at -)evbFHjxwbXnEB2|g?&cV^|Y23-#psaO?
z7CBqlw?9k1tBZTyQ^zb;wvySbMxNOJbZ6Ez%+*q)9Y}x8**|A;dugR7^T(7&juZSk
zMvh|n?~UK?7GD0(j9p2JWXfNr&YabXk<|&x^VxhPSn8qzoXwSNkuKh)yY#^a0}`h@
z4NZ8zJN}}+DvLb5`VWhKq5K}Gt*ODJtCOUR=4s9=6z=N((quSflQtt{bi~Mt58ZyE
z!h+AQQBN0mtr3*$!vOLLZ-}G6UBS#t8wRH7Fsw;5PPF{5J4Sr6KKIxNpFfp46rx|K
zOj}oO_K8&1Imzto)=kv+s^Hm-G~i!y)8`}%>W-&MrgFF5v5URYMieLWoE`{fA^QV9
zp?Q&Nx2|=4RWKi$Ch>lAUPhg`d(Ecuj2Yj^d+!6z-!btj$oh4eg9sBQFbH8xZCEWW
z*5Kg{qQ%UY>nZH%7eQ<8h&j>77qo71kmDI<E-~eDzi_ll#3%47I*>5S-elR$d{+D1
z5!6;}6@!UcbN{Jq$|FIZVxFJF8=+D>KlPn^*o73B{r|obG+^=17&WuA3{*57sgxD}
zBcLIcx{-9fcEfp^y0)CR{lVo%BZ-f`x?l72aQ0TZp~cq`1svO)-ejNsK3y*qdA0Gd
zd`g4Xlfh7>2Kz7hxe4CB!=8ODl!GUlW3;ImN2WS(b1X817v{88rKUH*(*VV^<MAhu
zvq_dULYGRYvVk%c5_#ae&Qp_E$cFy+FYOj;%(!u2I43{hudA6MrmsKIM5sdX^`%)!
zy{aPRFFjF_u<X=Y5e(0%Tv?r8l}ATyFKqRm#~qDD$6Q^j;<AI7TXhGU?K#m(c8>(!
zS^4jds^73O4NchzbqSw4;=%b+$f01A)PgIn@}}MB)t0JBD(;z8m|<&6axzvf`8v0i
zU)c5(`<(Ep$~i at w%SqWcFK%V_e}3bAZOCWgT^RTRY#kv!7yrq}J2EWHqk7-~wNoBa
ziZARP#6B%~ldtKz++qc<p21Ek)V@^Rc2|2|chfueTEVnYOQl<+%Q$KA4y=940;&*F
zZO#&bwo#j(^C<8vZxuKN>e=^W0=dP>Mx4ALlWGXyw~?6_uq?bm=&3914m&t9ts-%d
z7ulqqNy2eeFLk`4pSEGyc2dz51_}~$w>O#ds{=s$4q;ms)Sq}yv6fJ$I!XZ!GTfYm
z2}%aOoP|twWSk_>OVwe`xy8y=m!YrTOsY$0Mr=lx^)N|451m(MYYYXg7M8d#_h at -?
z;M4ExEwUqTEX7j`wdjlcT++IwE^Ztc1O1W^Z{;!zJ8`5SeJM~heHF8ASDgg$y*c$`
zl+$V~G+h;%+fUOJ1NAq#Z8XT`=@rGy88Eoh<fhidC&6Q8<$w97)=YnCoO!Gc6(984
zwJqq!?h{GA&0wp7PE^f?9BhjGJNwg5Q;VF0mvFbS5jj-{S7+TuTF2KvPms6L#{P>g
zXgO>ec7EqfT0?ZbURIMX at i1zWj}+k#ebTS}rDHxvzzu6{R`4hjQk7;>J4QE12*Op1
zcGN^}atS~m(I=v2L*Kw=&G%r5+Y3&y_$hy#PgC%;Jmf3X81b}`&H8=;Sv-$cBq8?p
zvyc3rVcW=xg~)p(A0$}DP*Z+VP7<)u&)!}W=q<d4c~zWMbg0#kGMwfr>^$>zP0duG
z2s5wgO<6ViPmGouMNn6#>LO(`64)x7Vhx&BJ7R=wQ5st*QK=qQgd|u{e;8#UdT9A=
zYku0P5Pjqzr(P at GQBP*3OjZJKC1UFWEr7Cxe_!uj*HU~hJNU%EcCnvTycs6=(=-8Z
zt&g|PCcgf^JYRVTEfCo82u&wJT#)+yAeUKS)d8k3|JgL^H>kXYf!`b+e%BDoz5mjM
zMRvxT4LELf2Y-Pj2v2#jmk+4vK8d*L1l}Wf>tJp>SkSXS`DDfEXlQE*+M3+g1|v1!
zy%zyi0~Pq*Z{!mJxcmxI_1<nnadAnxTK;0G2DY#p86sUNze)#rb+^fWa|bd|A2%qw
z at UN124+&Xqg$wqzR^%ZVe5+m5S1uK0jL}K~in=PX^FL9q#Q+`TRov=7a+a+ZCBJj!
zvdB6kuQ_=DyP~+-{RtD}s`LK^75 at 3-O_4V9by!kDlIfCx%9#X{o87o`n<CEm((G4x
zL1M6raeq%G6;=vu|2Z!~f)C0&Cuts4JiAxfb{1q;Dm(Rx^9TPkEdz?z6{gU4<Trwt
zAKrA%*$t)r7f&UOgXy|H;Ita?QA_Joqn`28Gsc}_i>XK<fgM=Vy0j9`*D;uv<fa%%
zLUOljXET{{qb&xO_k99^Os=Ckq+?rGP_V>JC`{A!ys*GO*0wK;GlVRtesDHBNT^NV
zdOIm at D))IFW<Klx*5v(2lzNrn at 4N3u4s@6GPPr+kp85+gh+acpt1vGuH=RFUbM_Nx
z$O}z;#xl6pFxp|_ASjsv*V;^~b??oZ$Ew?`w$C-iZ$I`3yHZhV)HH8s{am)P^CmRO
zWwlBBH*%_fKzgy_Jk?xmzH1JOxEu$`h^e~G)5>~^Ony*OUhy0k*FNE1C-%+SN%@7B
zYBq9 at 75;@kx7KHBDakkI7AHZ_uvpdEa=nh_Me-f at f;M|Bi`Uf8s^{j{K5g4!@IjM}
z7MVoQX`;E1nf?5WW+jJLv<n^>r1o!ocq$;>8_RW}tV!o at Hr8dLLW{U+yJr8d!S?>P
zqeI22>GdHX9=|y#_J)y=@NuNx8_e;GyXt9;XACIhbdAu5a*`mSuik^Jq9Uw+|L!io
z=5_L06AJuMIxbOsf_EzzXY!<J-jJpn6B&^|BLDm1e~`yT*{SxR`wZQ01V$mgwO=9g
z_9P{$b6qZWG^T!2{-LI3GfyMBpU-46`9^utfr1TH!el7BmlmpYbmYIz{)~=1?e^^o
zBU%KN$w(6gVp#I3Rk`luVR=UZBC{M{I{YwhB^>nTcBK1=w%$Yf({NBKI7pRZf3cZh
zJfWYCfrL~5dRqWTdA}`>uq~g at _H@?Dhvw?=!qtU6(VIrU2NCdfIoRqmm#@EcOAv<i
zED<3{HIPimxGi-Y&piBFNleBY?%W=x_SU8AWNP4{u24%YRdo26bDH*yWT^n($RLWd
zJ=<SIeRuN2=z&Cg2ne`1C at WZ*+ at AUokzB>^F3fXvX4^rC`eEK`8r<?K`CoQ*^kyb!
zf!Ek+&k9!B4f|uV4|}ARG!>#xQrgK1H>av1H-vxX-x133sWd99ZC?$p&vBGA)7{89
z{PwYVcoX~Dzz#|_5 at h|1hJ!F+?3O`jtq}B|ysYmcKL9R^O*5~b`1|sz$H|#4xB~Pt
z$TJx$OKtxLV>WwN9kB_<XVT09Kf>rFnprlKk_R#zDL*3EYw&R-umL_L#K7!7iZ9!L
zU at Q%f&r|`m?{U06z(tZYgO2&cZaMIeK!G0vLW}Rf3lN)RYw&DweCre#ayQamO(QU`
zA!hjDmHZM=`)ml_samA1eZ*6CXD55oEck6Hw0oibfyz0ROvZ4Lwn{Nfhg^Xs_mB80
zV)|5%yKfwMJ&HG*5`XOn`Hi;?fjY6*iZ;GevfsEWw;)ODE0&FJP$#eOQy9C(j7m=T
ztN#4(Ta;gM*v=Tf_I0TKq#mR>lKMnkrkpa#d`HdHJnRN-7aYt4S8U7vB20HMemO>D
z<IWk=?1``!0&^9*v&rQ at f;p#2%B)@^ZbrjfEXK~Y&!~nq*~Z=Q!#lGIV!OXDIobJi
zG%pnWiGi|gm1#Ly at Y5P!zS%CmST5Zi*%%X{(sn8wI6o|J{(UZ*Xdlrj+2)c=_uqV2
z^uTz=fR2g1e7SFh;!n%KHDlMrG%nij<X>ZLoURRzz4L$<yD*e7M2CdLS at SEHXw8@~
z$r+B1P+Q+0ilmA at -n=%p=ZH5dcu6$dr`lyTfREMc7`n024a at ijHZ0f{sSPgw&~jMI
zxUFZ<{TF}XG21K%bMP8SWp{X at 4%y^vuqvTMw1&|H!qNXuT0~gyfW0W~7j at l+-{Mv*
zbv%n_rnKZCaHqL6)v*q!LoLeR0)XwZsJsAxAmh<p-I!Pd_IA`IP at SaJ1Qd2xQ?9$|
z>xXdy5C=r#F=n>_g9z=+`<<ou7YwI#I^shwm?!15zG?(Q3qZWLXy7pzd^n!PW;mK$
zC at E~5ZH5CO^F6=e#Oj_O+l(d2nf{eJmJsj%-)}L<xKxz=vgy`nwd`bRUHHZYfa;0&
z=aak#<91>uhsLqobQRc+pkXT%wL$oA&<Yo-oeFvB89#b1D<DMnfJT<WlkC1aPR4dj
z`N=e%UsRL!XaDY~|AyK0e_!-J^Oq)9PF(Vk>?E;9tmhjR7Z#E%&7A}F_pFZMsqcl!
zi6UXEvoT`TjCyYTjie`(W>zuV3kUwdYN|l(hDrLyhwHHg^JrrfM?)cQL-2_v{rmZ_
z^V6C$#OJv-$QoMGHn-&84rvF7kf^ZFDQp^1Czj&XIceUaD%q?2iv7pt^}=9_W6PZf
z?vI*J&T(yLejg|6)8S!Z=lwqhyPh#vvkiMqhyMz%IO!s&(r3wkhZY@}-g=AjsctE;
zMUk?%>OfmdJ8QzX=Sm{ymj*#%c>u{!us!K-^-3L*r at G}sxmQx6GdbN{>Y$Z99gTtz
z)9U)#(<;B}dcz$NfxOM8`s<Z}WtSXXX65hZ)I2afnrs=^uK#vZK&Wg7_w9pnIA_bG
zpMkgy#s{`x7{he4aYv3O*;X=!&oN23AvZopZRiy+X(ErPk|xTnlX&q`{humDjE~M)
zMp%N0KmMg+V=oee7U^t|YIs08;OiYa#z)8FUJphz)AE^e)^_=UrX>gjwDfsyy#<Ys
zfbaH&Gj5pU#^crIgl2XRHgTAXZ$Q^q3;|G{2k^GUU%M&&J`nC#;Pr{pap{-q%F^uk
z81OD2JU^H}q<!okhP at mE*)qUnHDn7a(cLq(YWUtXpNdaL=RN(%VsRk~mAlix8wc56
zzvdqR-;t3bICZz6mjr)}a at B{3UW4T}9^Mb8Z?S|Fo7PUN9uGo;0InV?%QFmgHU~d`
z0ImNH;GZgM7KSqO9kwD3xA#d|^4aV3y?(@wON~z*_~{?|L)wPaE6HNNACl9- at 1&Wh
z%)3*THKoiZqMZDy=kNOJxr$8)4I=Z@&0tRb+;u-2f7S*Qejg}=Sv at v+Rq7*Yd|fG(
z8*;C at TX(hT4hSY70E4A71I8d?m at 7Z9ctIkk;!o`D&U}YGfj!oV`R##ZDqo-NHY(3j
z at 8zw5aMPc2D8&_x%3-5D^>c at ujY|!0EJ~$VFZszFwn*^>TU|DqjoS9!l7Dx&Y9dHc
z^vmRr4~8;jUl49oBEf1IS=jJ_Nuwjc^bcKnmhDT5Q#xggJ- at GRs#lWu^ik%K=Nqk(
z0q-LLhmD-wrT9(t{zUzuUK)r##sdG2{F3)K0bb#PvAf}Q5SzM%C-kp-9PyMM_k{yR
z1zzdiCk{U^9ko&QX={*?9+0r9qu?A6>`}_6CJdO3gg%9YxODR!IN*nu4#xi^?xsnY
zh7$KOYNzVgqVpTe)Sn~VQyyUIMM7uLg0tO^k_S2oO=IhpVW$VzZyW}v*WYTbLZiti
zBEMIBkIXpfW_?>;4<-wNjj~yOM2p}VaDR7_ at VF0u5Db}!Sx?<;enG3hopO7g5(d4+
z<o_(mkHhF=;dANYNU0w7JZDrKX!XLRxGkrG)}7zkppnp2P`A8zV@~9W-f9*0m!H*~
zZMW^z9&~1L@**mHz1dW*8fk1PX!H4^kQ=U@{Pi3pF;>_!Y1|eGHFHj9*P*atG7<X*
zd%st?5FhjdbaTiE5{j(}OGJU})Qcky<he}buB3|6MP_KXIXaNM+uM;99hqL2EU6qz
z_4$pnvy%X$pizlRqt)=2HmuLhhamrMl}dahskW?+G`pZxq_ik?>`cUkn8t?x_ at CQt
zeT}=uIdhY}TVc|*?^#K6ibsg}y&9yuEs4QEU8<(@_2MA9)Q=q3I0!IW0e{zmS?ZiC
zue=L*D2V at _th5n={NEbrIfUVR>uY#IJE%X+HikCrXSYCZRHfSyp(A4#5j;^=>(1_k
z(|6xK#_Ev?z=RMtn2cy8o}I`<XbR+^kOfwB`Lcth-%N1PR_60u>;vp)N!pTA?R0hy
zOsKh8Mg at GVwShYNK__9e+?X3JusGY^9J*Z<X6IBOW^g|Duui2jKC9hJfeUm&sBe{B
zu`2s#;+e1kdtKLmw~`v)(Mk=c`U294assVxGBPt%1=|;RL&c9y4<=+{+6{U`PV7TY
zLU%5*$VQC$qMPV&y&1QnQ0-NrCW<BczYQ{LgG{)&7?m7yGUmOE&USZqp*_Q-iJQax
z=*<%e6>r(|CZ2Z!`bc<NtRA{GfB9wug$zrloC?xlP13}!p0B|@AD``D>J|Mi$~>A$
z692G(Hcq9GA5_oX275m-3nNaWVS9K4p4ZaXQ{S%nKXl-K0 at bvq0@0q<(MEtH<7@#c
zNSVA~bRIRh{2cBzIBeTD3<4uwRcJYt;B`NDB#Mm}NXG2$8U?yz9uq+Uw7ysLiw7(y
z%|Z3PB<OzxUGu at m)(c@*Mu8>kV{WYpmJcKrROLAP>-QKjb^!C2^|s at -%-eDx5~#Gd
z?-x*TLQWS{1?N7BLqL$3&?P>Kj&wJvb!*EphUhI>O{XUvuN_r;!`E|~WtVvb^(773
zMN^T1UwYFImc>eBz6p=J1&Wv*>6Xwbh<6mo{$+13zn{SrhYCB*MB#3)7&Mm%u2neE
zn5ajwN2xmnKVwbyy^hM`8nbelaxTvlj2=7;J`nXjHI?)-YR&M?ZrmA>oYhX}EFH#~
z690I(?M#VX6QsUbp3+!|ytdPxOXWpUe1eX`QR-zskI-l-k*yqe81|b#_j5ynX;r!-
zj?H~OGb+X<j<_duwGJ})_}G at Pxu+)!^PJmZeit-|F5GsNH4{L5KgxxbP<+J>`u0|L
zQo-lno$%E2aPiP_^lAv+a0veGgvA-to*U1&9$*r`!)KEpOCOs495wRCIqTmIue!H+
zt6|f&VCwHYUBuW%zdZ4(?i-v8KLok`d&1iE9RcGzH~iwg*mw761N(uQ=ht}%qT>?P
zB}xDua{2C3A$t)C;ojo)_?_Mi*Vi4n<@Hd2K8Ix8Vw4W_AgKoF!O@#oLaqzw%E*_I
z{8m{8q<?uXQ~4M$YR$h=-KfqK at KUuI0G=7GvslJA5UCFaA_xF~J1(F6<wdK!QG*Dv
zqyT(C=qZ32oK+Wma8GU9qy-N-2nn4t_D|ySGuh>ifBXaO+0xq0p}LY&i5x at 9s*G>F
z8T$PEta0BvonHz4^2Ybt)TK4TEfJ8>9{=KLxRbbZ#J7==k at q2)N{>C8`QZW{`cEX9
zB-$^xr|kMK8o&nHkyXk+>4~!^nW(06DbtUW9pdga;u0ugX0Z33aRH<5&Cw9bV5!@Y
zwbS(*S=4vkn*sKjK6&YAJ94G;)CjRBD#=w9X)-cizOE11x^;Xa=_~oQu0}@vE&Fi4
zJJNGyvBjS|$6#q#rRwGFR(g`S#HL7KO_+;A$Y!Tgy+WM%y-IeJR6u($7Zq=0x>Wqh
z!$_Nd5O5QKss<WWehV-NL+~p*U*}1{@aj0T=}!5blqZow{!a^#`%+0D@?pTdwO2N@
z#aml@=@{Pla?APQ?|ExmdM at P*m(thQk>^=r>OJn3pPZX+j)@mU)oqeCfuuXrt;Ao;
zc+Ji!P%&l2{^F29aVUU7uGib)MH#x(9VRIikv-#MH(<*2;EfT9`|COWMsY?cvQA^I
zmZj{yFsR2Z;e|#gO|67}cwsiPhzF04{N_1j&cAoZ=5<Nl^!{l0_VCR%!eacX&g4vx
zXJg-cO9ZX|_QnBM!W<A5RVZoqICQhu7!wxhpgP+DF%Usn*K!@0nbX#(X^N_s>Odh#
z8r{g4O`wi?W-ds$=?0zo5<3sj<#R&z5}nwWWQ&1=@^xT{xOxDhLZ9ehf?1|}<C~%(
zg5AJHli^ZSiO##ZjF9kw(p-cTn2mE>PE&Mu{MK(Kz$U*nmEyASk=hDcF~?5k_A*-p
zHcuH<w;v at tB$7~0R at 3!0qKw-EhCrq)D&yjnT9l?*_dRDFJ_(N~t7lsl*nGE?V3b;C
ze7iHS3P2CT)qEHY)titr_!{h+URIq%x7&E=Cpi!L<`(?-Rc{Ij%8yMg5Kq^lF6VZI
z?>U6<5{VvtCAQBfm)x|ZQCR`TNY}Q?P0iJ`mgn4+R17G%K=ecB*bIBJx25JBg}gG$
zp+&Q1%FUg$q~UaQK at +ghe)W8k36jV3kCPOZKj;_I#k~X?<HG)zxxe`q=SV_q#_4{N
zFcHUI{76jZe#pzL)N^%;74dSF#LTA7yH)j^Vbr9>?a%YqExnBMCE|AuEKG(}lsH?4
z9gJmylk}mO!>d%W1vXp38P8pNULv~quOg5hHMot!IfY>qxdFr!C0v%3BJN&Ppud86
zHplvW-M+*&Ym;z#ik-8>i*ESkdOpQeD?|-(+F3mtO1VDj4*02B3|Oje(+cVQsTi&x
zKd&&qKMYN(>4MYyGc5%5!tR<t2a;A=_e?=J5nNHyMNaRgR&OjMmX_`E&e?Pt>}`+F
zBA`#-|CtNP+;tcLECg at XM4sCF;Hg)`4(Q<Dr^c6#IA*HFf#rM4`ReoWR|YfH at _T@3
zLeNycI{?gV;6`ae8Yu5FYG?8PTzCH!r}i~}M;4 at 8J64!`G4p)3K88Il0pUG~JwRgL
z(OYqbrjM&kTL0yK5S&0~Y0Blz8F1Up`6i{b^b_TD93T(;$?7Tj1#XeX4#Q+WR0kUh
zDUWeDJZD>(rKxW!|CYx56%~RM<yLZBx_3UVm_%m~i1GH??6X0_mA`j|4LlA~4&}}t
zuTL}gL(_GayHrPYb&rr)An3@}fKjgt4Cj`qsWSfw4_0Z3_>Zf6?e5dcuZd4 at nSmv7
zkvyYip#6({B+Ize$|T`*Y^bzUpE+u$DR|ggdWe$edRFbSn8slxJ|PoA;Pi|t2$_IU
z`03pUxE#B4CCE3c6J4V+;8*9rCO)41NGZQ0tGb<BJB*)OOvf1>jN^F$3w_ at P7j1f}
z+GElaB&L}+blm?JgQ;xMs5CF#8n2nt at t)r_T|U`j at LqPAU8mUAf6p5-e6xjIeQ@lk
zkG(8C4oRO#>CN(ooR@&VMb|J)xcWJl1-8GLxkyA at Zv+`;>lyj4uXKFavoG~)tSpE$
zalFahuU@`68NZ)Z{-i8+FTh^L({e`dLxCD-4}#&2(&)7Rb;Rp;pdT?(G-fJ#zO*_w
zs at iBy@Zsd0;rewv4{&A4%pDi&(F)_&q9Hm<F)ZTpra&`%Uu|1^yrmUw!=9FAomK1y
zLOe~_MJ6nURG-c)UY*S<QqTt_2YWrD&}l$*`ArFfh>&*_%v;@>+jnn2H}x!=@u~L3
z1OvO~QbDlNjNZBA>z5&fv-A7 at u+=gjPry^bs$pu=@BfDTvchc4M0KBBZS0f$nKY%3
zsD#7QzKnSyAAB6Ehw~J)>*0;4{!!S$1;_>R`aV~0KA2Z=<Lo|4;m9qxyGF*9J(6Q0
zocHe$GTOU9gJwEZ(uSqmcu2OfZ9M&JcaQSm##axY{XjpKo>!w*+f|?2>j?7-xX>bM
zf#6Emu3UnK{KIcCSq81-B&PS=mT?1lV?W_6W$wmuRW at 92Ih3BiF!~a{eM%ySvBQ?u
zyVN`UYPUneDdCLt_&Zx at KbU%H{H1;eZY$rgZDOXIu1uM_a=GaEep%GUs>IGD|DKsM
z!t00R_Cmv)2-f)u-S*A0KL!5K63^Mb{t}#v?U;v6HEszb at 7K^wx!nDtfY}|x&NB*h
z%{3 at BABd7b^4ejACX#u8n>Xz;iUwDkr&40-pH~Z=c&hfo?(6nfwXy1i<ph+E8pZ6i
zPF7<U)q8PCl=+W}*rY!{dHenD4`qFWYmndLsV`7zqEsi595<=^(`;bd_n$7X63ljw
zuKWV+0|(E}*`4g6nvj^ow-Bar-PZZsuZOK at 6;Wdn(y;|O#Z2S%nQY*7<0GsIg4>`g
zzA3l_5L?L<(V(RE{Sw{sh}ufGwlcGyknZKbvpPgj4QM(uM7MsO2;LyX9JY!$_l~s`
zcFS at Hn8`Vcs-wX#muAlcqCNK*92 at ml08S2b53yI5tU7Ih*T*UQm8WqSZ(m@?2X~a4
zyNW3>;2|(~JdwdaK&7r+Graaf`gE}?8d)+<SOq_RwL`7Ho}Ys_sOW)gMN6{$49(0c
zNNtr%y at _qy4nQ`K9gt}F?-A_h47;cWkk0s%!Tr5#3kO+>kP8sAQ<4?J`8VdwNXTm4
zk{H+TT)6rD_y+iY7^EeO%m&pp at y|E62P)-{Q8St<UyMUq;lCG(r{1{)?YL#=o<3Ni
zoL;R%R!a(@O(dbUBj!F)gR9<+JZCQ(&crGG5OCp7-^T`QeW=tM(zc5E9af7reCg at w
zagy>Mk}Di=hIlW^_zUxG3uV+9>6&aL+$sOvBvvGV$<|d%fYJ4dhA8~O*O>u&*Pn)+
z{{@SA8MLwc4wJI~nmt_;Fks-^E>rp2A8|X%IW3?RO9;1kH(qO97o|QK23#IN=X-l5
zl73^>G8?28%V(|UV7vLHG>f0CuQx4-*|<n77=R&a%TLng=;VyLMHlaEdwAh-mSHV1
zEfkgo%|=@w8 at Wm0gpf*0i~FHVpLv|He{Q(YA?a2>b9W?hDv5u54VtIxm*pWgKmhA6
zc6BRwD at S%PSXMD}U{YqY-kEOpZhQ;@NO3D%Od_(d0j0%oASz`B at dAsVdp=vfJX%#B
zxS^sZ4}t<L&cNs0b;0w<-w>qU6tf|{Hz7!vAikrNys`|07v at Pk9XdKX()&*btmgCf
zbGM<y78e~a3a`GZsLirH;ocE=2ysr%RMr7Smu+R9W{WrIVK?mqr&06Wb__rPHnR<_
zR$f8&kAW{|M6xyLP~(n|uTATt>5=sGYyPeuK$F6+`{+}-BU at TEt;oZ8fRYowfP%`B
z7q&F6acW(jxCspQUHN0n1#kusRCrg7)gWZTm*Xg!kT65~w?ce at AIAI|y7Vqpx@^$R
zqZrF8{9F5;6tiX^vSrUVl)vQpWTqU%GB9O4rf0JievNG}I3#98*Ik8Nr~OOzkVmoL
z#=`)QC+!=^ff{B*dTC at 4Wr=xIdtDv!C-cnaE53FsTshgByy?sCurZeQ;J-lw8l(rP
zDra}G_9)v9&GNA94-aOc&}+ZTdffiVga$Ky!m=07)$qqKrIyBDG1=llJc4#yrajS)
zWQP{s{#`tjYrr<W)SIQACIE3={Thsv{*Z`->zR!dyyh<wY at 1cDVZKi<DX<yraGH%X
zBh++Fc^4{z))n^asO2T%?S>f at 5Jr`kDOoZR7lUqPjbyrS4tHX~ecEy&@Kpv`wT=$+
zNb-cRSi>#Vd1)31Y5}-APF~*GINQ0;9(WgrRCYy7^l)S{f4zpT9(}~4_Z~u`slOW!
zk%#$QwPW6pR~qhRgNFJ6!JYYwD|6<~h2q(nlSk`C*`O(M%8StpSGRPH`tGwX&`J9c
z at 8rKPKT}<A?WKNcDt-a1!8h{Qd5JaJdqJKtkYw_?TbuvfU&qO9f{B^$Fi at WOUVe#A
z(SH{v)vq?!Y7bnMgb8sR#vO0!r3!(xYP|OVL_1b6_5>~ztP_l*rk&{Ehd4NRsR{_b
zflj)(l%l(gL|>0A#czKA7gNCj$hiecl^@V589572Fyfi=CW-$M5}Mqoj6!~ewxy+(
z+)DiiC&|5 at q`)^lv>KOEXh&nr3w0vtS36uNHY at IzMMOgHHYk~L6fjGhzUA)>@I3ib
zDs9oE*;uS4ykTf<7hpA|t{wOl7L#8yaUFFKm at 87(beEzNRdA-9IU at 7z4!s0T*{Tt0
zSeT+qa1Iq9xeAT(k!pt(biAOd=Y&a$A^(G&8st348Qa%oKt(AX!RTcL=pt`SV-M~*
z_vz%A%V at 4M3@d9hKVYWx54fqhMLt1&XYk{_Hbn?`2~CD~810YYKJ_;7q2DjJ1vRRD
zPGu|q>uXygKMN5+zz_{EGfS<nWhtqTOO9>Jwi1>dFV8CSM3kN;r#Q`QwPTncFY60r
z6Z9P3o3MHRZ1Ai-Z!6t)3ZHQQSeG4n)}N(r&0p}fTa`fsF(Phz;@A at pOWhQy&3$FC
z++#<}EPs1bhzp^vOuPP|*OrD~-}c?L(%;5%YYc5sU+MBRY<5%Y9iPX*20jr~Nsd2X
zd5H=x at NHj;Ctd27p~*S}aT9{Q;K?!q>7Ofw;(-T082w$tQghJS@{C~0acZ2)d(A*Y
zJKG1`o2;H5T0p<vEDd5C|8`ZZXMGeOU!r4X)5 at 2%*G;u1Vg`Db5MFIQFpysED!;V@
zAucxBew;kgp<zJ`xL4~<S(JRkdNBKMSzLIoR^vI>bn17m at qYi~WQe}Y1X7fW1qlI?
z;yz2H(<YTnB~Y2 at wtURzX8|?`dBzZ3Y}IU(+jYD^$Y0pW at g;%#4`U;Kec<T!MyOu<
zosD%t=dcT-5-S-GUmBK}(1(%5`qoB-x6GVjv#iH@<QQ(TK~{{Oqtfn<rB1&uN=4*6
zr7Q2+;+>CCH*Y{#?g=7gh94F_`t>^#cXxg&N{w(lr*kw!*JxaTBv~h|9IF{(TjkcF
zYiZsykCL<AftIE$=;~adp+1&F+%OlHqZ%pCp9~$`uW5g>NDiUhRR8<~dvmlqpC|Mn
zu|zsPyyVdpbJc^JL#ZeGbh5tAW37Al5L>RD7LrY}P{T3pcAx8WYm0_EB=k%InFvz9
z-}9%=-bT*3RH#}O9#WpCa7P6Dp)oEKvoMD3n~Sg-Bu#pPP9wU9o3A_lw18YLbJWBa
zr_C6}NWcg)j?#;DMFkxhKQbs1GmD&y&`(2O7PU`xS8b&72oV%<k0 at x!^(YeJ1iXom
zsL{x%f!`pO+`aTqMbV?hEB=C6CNnktW}sg3Mno~%hDppz)$Siu-R0`8 at hu&JoVspU
zO6)8P?mgZdKb_A{@4xnFM_hNT9^}-7Jb8HdPRG6qXq9*RI&Ds;{sj+o!IOYd_`BJM
z;mWx#c9t{%uqixWcgqYDL&5GI&3CYW`o0<qnex)7s9&aeaR_(|@HKy+PJ8A at W=z*X
zywas3tcSh*c>HYK1g#sRY{n^gd(9;e%QbN_^=!K>{{u^?xCTtIyHc?sjTEHs=U0RY
z%8H7L^ZyB9#(#=jWi#LiiZ+ at qFL&R!Iy>2Ey90)eE|B2)zCXeDi{0unZ$noOe at abH
zu(nT~zk9b7p>=@5e6QDwsl1eqsq}5VLybcdYN^3vo&(qhJt*(Z=Fpkb+(Mx)DnM2(
zsaKvtoGyt6O0Zf8)I+;Y=lHj2ggLS}%s32gA^o(b?dv03B^y}_Ni_=e8wy=W?Wr_3
zKC#Vgr$5iF4W8wgs!j24JD4lYW9MHrB+j4joS(LBVk{|4By&%<?3a=W?&%W|8|*dU
zf2q*>m(`hLP#)FgKL at WSiAR~`{I|;d`L@$6Ei5knX_h4`MtXB+ANx^_abBtHKZIuw
zN7qw2f4z%nw>b&R770k(iM6tiZuPN)?(*|hY49$Dfz}ohJ=kW3^?o}_G&ic2`KTNN
zLSS5eJmA^32rUAwC6xh0Ns`&n3Ki}i9QJS6zrHXtBG$eWjux>Fz6c#L6P6x(3h5;s
zZYk;+=#hrDvb1HqcOkm&I7?A+%mue$v&L2J2i)*`FIr~Dhcgbv<36U}m~AyEG~_Ri
z!Hqloyds~cE;7qn>^&L2H<t}!imN2&8!fz|_tk%@M?-AQ|DI!jHXZAoa#nYK4%#*3
zK!Ww`*Yuqh_pCv2)8m at 1VIU8JBA(U{%x!%}+az`bOE1ygPs0Wqb<Z}|<E?ie-9qT^
z1M36?;H||No+R7#q8|1hIRFFv`hpI<Z(~cuw<Zi5_E&FwlGI`LU+a?Ia{Mw!EV9LX
z`*<=}I~w^0ooD`NbzQ(%NNA?^DWc2z7r^Ik^ArDsm)xNDcTHCL$Psso|KZf<Do4?>
z-yrH3C`EWG;Wxmk<sp%+;v(uvMht70rsVzkY&NDYvbkT%I`g2qWkD$Rlvt#bZBb82
ztX0SnE+x75v)f=`B2KrboYGZR|8^BQhUY4b6(3#I;{vHt>4Qb5RZq{khu8L>10p5q
z%1#zE*7GmY;x1kAdaYIcNXpCEbhi$T0-vg3Wmkbl_~U#LgX*&Qj^F_W;x`Hpc9>Ve
zXgFmBste(TpkCKhU5$gjGa1u7{x)7mqO at EpU-^CYk8_SWe~*Ggj#iQ=QB~m1Ng0-W
zYl=$t#B8g~wNhlwmr at 7ohl%own)5l{ZkVrd38M6dKWrE{;2Xa4=vE99sm<pYyXlGH
zett^p`miPXwEtjQs at y#IaTXsI56yARfL7Kl*)W~2aV0*cIxySehH||ieMZa0>Y_qZ
z?W5NpK6U~qo at j6eZ%c2KHw>W-oD%1%BGYyaMXh at bpnO0(Ky=fp;LKBxFO?;um^MXR
zfd{~|xh at Oxja?d0nR9`k)vBd0Nn3n4L53XgzZqL=YVRdoe7MIm!pxx?YyP~s=M#5S
zt0}i3G2>!TqtFDjfrI6*&g=O=s1qkbn3!S_6cESw at e_<(-IO&LJV<)z{)Ss)HsgxY
zmfUxy3aZjU?n(14g6E-zQp;xjh_3ZpYo>wMJr*VXy}UFp!p at HHl9OQIGRkN456BAk
z0AqZ{kUIu#W27`wO`7Tjy9$$ifx-8%2hU??0M{lCGMl#M0z5#;;_}jmztvm$!))oz
zS9SO-s{N}^8_!d6fnX9#4ixA!WkZ?wdY=s(!+#tC7#m*v529sZIrKx~Q4+l?v>=O4
zKfOP@?gS{)Q+G)h_^jL=J7A$K{Ike!A35%2Hahk|zriGN6f&el#=fZ))hbgPb^5yD
z)|CV5eeJ|Iext%g)!1!}4#Wx;vSM&D8A<Sl6qwe_B9{;Tt^^Z>Uk28o&{|eyL9+R#
z;;sDFM_DVZpKjGlRycibSG}*~AkcKQlBpph7C6rNJO76rcke0gr&&E$C9b`oX^4)e
zMALkPy|p1|%q0m9ZDS4_Z?P#8trkOT{FEs#N^^xZ8T1GQf&$8fW3B*w_VT-=`ut{b
zWWm at JW?w(47cMUbUbbW8Y#Eozul*b<>o$(~q;S6lJ1LAwviN>TR7$B+VJyP(Jaovb
zc at N$^vDIqBTSmuo-$I)?l>MG6{!}qRm;Qarug>ELUj{mad37qrXZMR{SYOLC4h*IJ
zf{~~n*SEPeds#Z$n>fEanQ`82;xZkfX8Vi|(mBbZdq(g17sE at YKr5$V%pz?dn9sqp
zSpkH_A at W2+TZ2o_8jr9jBM|<XVDbF<0wZ??Wi5CDQ$^wZXVL)p(e*z*onCqytZb4a
zyn7PJoeMs_lVHV at U;shKn1h<;;$+b9-0K)OrN0BP>VenPVwp=w5RVO-(FP1J=TOW)
z$euy=utUk+ at P<-j<Avz1dJoqdpIpxo%=#aTmj1#WnG6%Awr|b(wf#xe%Urg7Ydh`s
zpo{bv)#r>FvEG?|Tj;L;mYiw2`1?~GYWCp2$RIz**@z|nuMgAp`gZ^5wE=kdH^4IU
zOmeH!$h6A6vqPlGc}RPb#O$LjB!iuwZrx3PTt=0$AwydMqaZ?%kx14#S5pALN-6Iq
z7$??jys_%U&kq!Til^!xFHs&O`8iB!mOdSTeSLFlc1DXMA6o*`@9#R>{k_Q+ug=HQ
z%oBd0X(zeK3uVlXBI?m6`@KbF!6YyC+j<jRly=7 at rz@r-bPO7dTRZ9`4~ok>H<evE
zXD|=`8prt1(>n^qaG3W+#szEL_b~l^d?`7R=iyA-f$!S6=ET-z$<#ev35#bo)wf&=
zEK5^Qv=w|I%A~5e>b7Oq*X&>X^fmJ}U-%gr?kkbR>5niqO~^ycJnj~-A%h2GvY?#;
zq4R#mRJ(Nc#DBZ~c<r|T8a5y-8|0*|Dj1JmxgK#@PGNH+CtMJGBBs14fpg$L$8(DZ
zYqdTVJxdV*U(_>M at Pau_Fme>8Z!x}C!7I9Lo*!*)?iDS8>$&R{{fL)0EFHAF#94rG
zmsoWhnSKnC2Z9d{o%~zG`fhFqf3g7CC~>t|zDikuLWlpn<h~j#uzwFwn6MeH<#z2j
zw2DY#Fxtk;$(7D)On!#zrG(h-l$?h-Z|_=A&D$@UvT_6YU7)0SO|z)~vsM#wp^<3E
z^-QM$aA5()d*7Gh7hAbs=lyl3MVSU}v_n~c7u(x6*e*OxeHyjsj_wNcu3?`!a1i)#
zf3?H;PlX!d)=>*`P0&+QXSP41rU)8drH?d*GV_)Bp8j3_fJ^;C_a<n8?`_VvY<3>$
zuV-_3GwOHE+VrMW$vPG2^1&^cAJ-<|R~^1UDlLb}ehz)$jl7mI)*a#F<iKymS8QeH
zx1i5Vi!2Z3Mc5zafD-ow^AdCEZ{zW?FQGWyR~;&5vQflZ>gMZl<$v5~Jx~i0Mi$HB
z^iPN`^xXI-a+;EzLT+E(Q;5#Qu2)L2h0G6e*`Nsbeu>!JCna4`fdkOStYp^_B*6kP
z%e#FPFaIBuUHlDSo~%M66yl^!>Q&$d5_sN1RvP_1cpIJ7B$t?)LCHd+cm#5v#>tG|
zq25O5w at FCV-qK*vYf)q*hwt_qnRemKo{ijoDN-H>Qf+oJqGudO<avdYypS#B=M^=g
z_g{-XkJ)jde+H+OnPepT%-8)x0W4D~D|R4hJp5lcd-1fO26MLN1D%>SvX2Gmbv>yj
ze+>Hr(tH;FJHn?(CfkDU%<~6QQ>>nc?R0L at C;mEJO0i^DnS`?%0&G+P1u-S*d_#4n
z+NC8LVv=J(t^#msFhLO);tAZuc=IxD6N=ibG1Ct$qjGuqo$Bmzi*(D?4h25nwLqdj
ziyx56juC2^{WF at _)t_j%`JOj?EnA495XUew-#g|2GWoI?e<7xfh*OIhF4z?MYfOyT
z%n-TV&ALn*r&z$!8#>!B|H}TGv|W7DsO(MPTf^M~!nSD+>}SiMEQ4Xv6acgQjc4yi
z9m<lQBeu%}pJ%$#8cDt_BYg!myRW;NvU6;IxEe7RWyG*XY;ddGuQdNG{79e%&Uv*N
zx@>&ds-nlL%qRgJzr~;_OkP-ET7p_xbYXUkUcW%&c6 at FR_rL13TP<t)#m3=rPy+<F
z1_n<OIexvoW+1R;rCVa^S->02d2;fys0$sdaQTPaE5ye`&Obith~0!_*sqxn>T=L8
zNkn(QI^UbjEu|{+u`gC%G`uXsuK(K#HhwZ|Oj at Es(;TE^l;Ig(S8Cf!g4~2UGd at E)
zuUXsaTYiEw=1`-H;RejPX+J?tHJ61_`K$U}TtyL7j$WVMd|k;8?ccT at v2?4fI*U}?
zycTLOT$#7evHY%UlLgy!$GOn3ajkrPn^pkRYd&BAF`!<&oCX~pRs8-aKKD}G5PVI0
z-xV(?=fL0MoM`IYkoW`Jw-HMS$$DJ^B2OUT?O at TBwsF~QKgtX4iR+0k6)Sn!czV!+
z?&1n$t_4Ixw&XQA5OmU?_H2yTGe9S2{X`;5gQjvS6JOOysW8HFL+h<zkP$gZ at x#x8
zZHxs0_A<CLkS?OZpnY*G#};j!3I at tpJ3%<}9Jdv0DW1_-ma%CYYH0?2cIk1iVgIKd
zPZZ=M at SQ14n)21`0-fS(83g}!u2cmZM11xgzr&R@$bT-s8QyKRPmAV6&CukOhfGWP
zRH+?*B5MwI$_qpII2GW6y(b1qo<?^iZyKawl|28j4$<WI>K*hut`1vOU%G!;>>0|%
zmizE=haSsxzaRSw`_qc^ACZXmajswdm#;izb7!hk6E|h>Mvqc=e!J7v(MRe&o!InE
z`|TIRNA-^;ACr--`6DTqZ#G)_W;zA-ej~wE72mBW>`A;MTHC*?H17$aib7L{x%$;4
zKcnBw4iu at hYfqk)E47zQRJ%tb at IhK?eY-guTgE>fPuL8)hNkm-y?L@&jGh16n6psT
zr>GtNrAfWv#wp*YjR>~p3<!3}9$|fZY?FF<i at 1p?XfB^+gFM5uF&C=SY{)X^*SX|(
zJ20OI{iZ2%5m+!w+cmi~cSNDwTO!+HlzSt+UtP%H3KP7%mA6EfR1!j9Dc^t2uUoId
zW0mB*bTwj+KGQ|kn7J73$ZdT1<i6I40!dTM$8SwA21!XFyJCZ+;~!Vv#6k?#0ZVR4
zlx--CgG?2iff=0xY`Z@(Wga7~8eG at CqB%!N)yf&oMgXV9%d0z8k$~=c$jAJA3MBKP
zvzgx4q*<`(=^pENMi>6jx~tRwx=2zL_VE9-0Fk?Zl~{*+sp5C at oxrJCVy?EQ$dT<b
za-K0o+iV)nd>P0cp3&bnBRim(b^tF>LX2-N-pzc%EtuZ_t62 at FeIj0NC^7X8dn{w}
zGxLeUz>ts-yZCw<Gm7Ro-|&zy%dToQY7Of at 40VrMpEw|p_AkD_#T`wOnhT83DI*@S
z+0JvxWAVw%a7zwZ7zdAWQPv5Ihb3yE-MNGR`N<B&z3D1%bi=y;pu65P#^k-W?oo1Y
z<_7{6rvGR>)$g|g7pF|8zOGcmy;V)!rj4cyljspczlxz!@6>5m1s^IYig-WWhNYsB
zM&|E+#)oq1?7uB28MeH&s@>d7$ijVYl}2o{^RaQt+if~35`n~4K~6zot}eNJi(oAD
z7wP<<zU7;&`v=)UVRQS<j>Bpt?5n|@L>}jlHZDO#_#bN%3PaW*^E~~E>3gs<O*&Kq
z{4f8JS^L at k{(gT5oL`CO7Hle1aoD>swl36$%4T3XwY-Oo{-E^ZShv<fi)2f^BZXF}
zIie$j?BgT5o?x6}%$WQ#*p;He{<KXQFlfm76OB~rR2X>dxU2LMvty+WVYz=HO~4se
zU!vEK?hb8LhtT{>3BchOHgT0WY at L|PP7mFyefiLoee>ZT-VV7vB6iRHf71Qfku^}5
zmK8iu?LRzhbBJ7+SQ-jDCx*?Jbzxoj)XEk0F=4|GZ&bPrZcNI~a24ZzDWf_7rp()b
z&hv at P6Xf4D`@-`6cF}^t%$MQRCzAwx|E9n?I0b8__2<Hb;xQ$N%#_krh~D at tX|mPx
z(mZGAv_luW`h~ftv>6;Nh`^zO4%%k7qyPLxX5vI9w@(;4jLnI`e`|}6;Q7l2_aZT1
z<7==2lfTik-LOrw(p%1|uAtT9Ip#9e-VJ}CT5Y)IFQ`E4FF40qTQ55J!L8 at rHy@C?
z{hA4%t!`?%wI+A+Uc$$TldcuPudA-(1obODtX*a4U-i)&&8d_lpf<|bT*VEPzdl)9
zNJl^pu-|*26}}>>^X%fwB9^T)S8vH)-fB1Y>!YZ*&oWJhKW;{yny*WcdPRL;{w0s2
zm_h|2wwb at uU)nIOIrn%n&02)I)9}`CY=bkcJm3iz(=$)=mnVnYix)MhYceN|UKuUf
z<@b-4NXOjtqsqu$v17+9ZE@&sBN^4CczMQ%Li5y8!AZ4=Hsq@%!H8NB7dsb&NwO|%
z7vZ936 at kL+4{`&rP$w}N?#Uv!-FbCzTXgog;kpSB*M8tcGuy6*hrT>E5mFFz47xON
zaG&;@^3T&O_6oRQhS<kagG!R+5~6#NRrK%ozs}CjLq2ua-!*-rC=dis<6o<qH;yjX
zADhF+YHUkrT7Oj!fM%8b%i^PK?c45~#RDwu=Tr?wVX&pM{f*9zy!_rZn!M<NiqHYv
z1b at P$Otp)7O{w*lg^u{H at w{(!HOufvTP(&xDQ{NKj6b$(Kf}0Sh0DXoj^vn$aCrrh
zI7e)O at Z#ZBzOT<q=iRX{LcCOoX>(pIl$s2oQb6PJ0sO2wr<vh80g<BlzI(DS#2ubr
z?A-zcBh863 at u$fBVk5P6(+XD19f1e*{(^5p!A+D~Dy`<Fx;hQ!AI?l2R&%uX5|0e&
z7Et%Rn^>8O{0(G3I3-4C>fJ7Opp?ZyFUVcHIdDyC0(R^hUVb;ZoQ83L5$N(Q--)q6
ze__yhWy}trT&1?o&q1U&{RQpzM1OZJjkc2fl3ZEn$AfECLC*Hh{&|#ceyLgf(L&D1
zM|2OQYt4CPCsX7(e~Pj*O#L#eZ{B!FXR|&!&9&;LAigV`xzl4bG@&^xwJ4R15JKAB
zdRtod-`}Z&MlU(X{IKmka$UGDn`7O9Iph5#(fJR}-ZCFh(*+<w+vrZtus>5;0wZPs
z8TNW0kE-$Z)VL$n1KLZdw<p+UDGW7%#5C`?c<TffV_ajUYR8#JtxQOQHkW4H9b~ie
z`5l5Q?0Z%2flIs+?K0OjFkTyCf{~`gD|j$wU_GI4>W`28QY;25k29D`;IQqdZf>%U
z7JlM^8!#DWoMWe;(6jr)+fHF^b25^7wX%W~V~@W)z|)1 at A`4N?ySuGa9qI8!ojT5J
zy}XBe*)*FUX53O)l$^<~{AI^f^!Z*_`N;84gYZYpU$*V=gA)2%sdt6E`t7v5sa|Zo
zdba1gEp(J%0o7rMK0aVANp`iV{kCu^+@*{|a#(SrTAaK3_`#LY_xFdHD4v!|8JB;0
zIbLDw#>qc(Zz5T}$zNd2mmMD7gtifDx_T*z#3rw<Vq4NHx{jE}bt at YBk$q10b!Dy!
z;OMtOzK#qBR0OIHJZja$c*0gHWnHiWbmasrVl$0mO=P>n%I|5hJ`WWOKL5DlpOGxA
zgH{o=Z at w7A6KY1z<Ux1D<}FJYbu-#~9zz#TQJtC2^H+%UnW+%L5%2wXq%+Xw6?+{Z
z#isR*4j4`rqwiQ~i0>?3^)y&EMHFl};P|xW9HUn$?s3$?N+G`;sH~#9NeiG;{NH>h
zFvhj~Jf%AZ1mme!689o at P5us(@^?)|@UXx6w07lESzU>Y`;!`G2AOCMPv$ELFBj_{
zj#LM~1ne|xVTDoDLf3hHTB|UE<2LG1I^Wk+)a{k}8;>*jo2Hq_Sc2VYT%Z3bE%U&k
zl&Z>g6i4tiQFAAoqJ>xT$ad5*$4Bk~Q8pCf$qch?o9CmCv9DYPew-Sq2A<EX=-nIX
zKc8ByVzka(44yc<KFI2#&g=c*_UD2CI;#MyQPWN(p|F`r9*1o?O--icc?&Z{?2F-F
z7R)yhn=PNA6w1g9cs2X*r<dz~rJVn at OR*fqCu`5O$PiKWZp_d5BljLN`>vOnB4?pP
z>pu!MY)My1=p9H)t&H15aIasJGKx`9*&l8+>p?E_l=1{Yv+77oyr+~(@iwRL^Iu*b
zey>+F$>rcK_^>XD at b0bJ{#=-Y3xv#+H3&K+=Ro;(OIupXCEVFekG~P!#frch0YA?Z
z8OC3cpnx at cA{VXF(~+cBTC+5*l9!*l!0gW_Z#Gj6%0vDDtCn{%&nhd>AxcC5HR;Ny
zKOk$>lHwUZ@>IvOj}Yq6JYUJ5VNMY at glz`dJnb_+p;l&4xv at vl5SYXtvl4@*6E9-r
z4<E1S;prB|0oS;faS%-5Y+D%KzwUEoLS$`GENZ5UJva-#C3o^~4%=}Cu9- at RI8xMD
z&(O&(y>Ld!!LaNmwbU)N)IxdeCzaWvFZR(tRxXcs*=O5X5eI9R at QNE>1PqOv`p{vf
zg3G0)i`yhladSCttKW0n8oGj^`1vp5N!LsdF`vBjkuP4nHVj;1l+WpkLx~Ak&WsoR
za)B|DXR_DSnh^Zn-JU1(#B9#Te)JK*RLG|{Q6h6~8VZ&!aVXJXVL>ZD`zI|#XDR1T
zD<T(z1qUX&^Scnx46&~nnw5uheV;4_Ev`R^RinR(tCPr=j{=hTnIGE|h$?T(Sj`<}
z&o5EL|I}%HOGQgaxv8eQUYzJv9C@^z!V5a;$joiT3N(?`mfRA^TGU8UMZUxiX=rBG
z=ABW}?}uIX`x!dLUTY=CGhNz}wJm*cmJN%RMg}{NOx|loM`q==?k$tEre%XWdCay+
zHD3ES^5iY^?MzCb%>B6?iIh-CdA^C0!AA}1<YteKt+OLgMy<u&tROJ0m_<R6*b9$7
zpfWJMTzmuP=yxC|#<gDtg4?>fF7z=8gjmu4N7GqHHTl19Tv|XtK|s-=ev}#^0+Se^
zh)6dZ-QCUT6p<8xAxuX1V04ZYK|(@c)aZ~NN(zYl9=_-N{6qinaOUyZc|Z64zOL(a
z1^ff&h*$FesX1_CKzOn2vlDL$-$pp8dSm+&%-rR>Rq83x)YGT+ceo2j=9hr7V8@}M
zkD$NH3FWTt-{zZ)*(lz<gYKlERkC)mjjlTu22<{dZIMs)1+W}Y97}!5(@&X>uiU<X
zl)?bQ)3~nml$r}|WEbe at -i)x2O&wIEg)_o#Pb=gxt&&pd<awpzjJ`ayAF_A!cjLw;
zP%Dz`oGd!L1OB1J0mKjWskK0J!U5`CAhw9h-`^fo;J-^6sqKGZ?--DvqcPktJha(k
z|L!4vqH+6SqRYf{Ec+7}mk^J^r+j^Dd~ALio!QJ9P*v}djS|B at 8C&fe*7#57n-x`g
z3dBjbb1^3-;()sTpQHjEoHYGRJ0*O1m=>FHURCa at W&N#mSFV+}J`DA6XPxR8pN<gt
zwzyrBD)i74|8S<m*`l&8pBE>a!zm4Uh&0iPfb1=F4ML0|0)$!ulTr?$fBp<nk6}A%
z_IE{Z4G2|c_kH&2YnFkII6ji0*1;5d*eK_S45f+OHc}Mlk*k%4vs>(@fm!#=jYIBX
z{vx|w{#(gz>}!rlgYK}Bm3?o>-3>F3(tU8ZA_#A_-V^u&s-kPB`D%=&Au4kB-w?%h
z35>KQ;!RB7a^|p7N3jtG-_<Q}x<8~BPv7*27{)MZ5mf%Xk}v)hTVhP&fm_v<-K}m%
zSKU{l-c)lGpU|R}4>cuH(33v?e2IGTsSOLBlQr|coXFMjs?zDDcm5#0=cm;xOSbwQ
zc9I%72Y}aRsA|mb3kdpR=NN9%SnG{TZ&Qw~iutS{Umfv~SB_Z?r>RAU$b1hq!uf0f
z*r*M(^^63{E^Ks(;=^a>gTEWNr^F4m-x+vGpl5!m$srum at k82mxJv*%SIDBlm+x&e
zfZcQZw)|xx-7#NU(+ArPqRF@;`d1B#?7ACJ=${T8PGDQZgVH7a#mZzDA3t$wy6T{{
zrU_8U-s$oQDq>7twM}sl6FIV}a>1c7ilF4XbHSL`wO!`=#%nB6FERBigXfiH;hS#8
z6%>Y(S{dXq<<bKyb3JhCK3RPjm<%7DeYf>&jxr&Pyo5C9x6L5_FMxs9f$&D5sCTbb
zwMuAUV^ChC>klPvwyYbji5sqkUpHKG!P1{jD$cBSo;<ytl)52kOGQ=?ia(l1Xg;Dz
zuA}RoD47R;GG at h*w5>P4h5j-;aTV|OnfW_Q>dLH=kzQ$Fr8^2gn23Ev2Ycpzp)gRQ
zUFoP=s at N)9)`<RFct5kE*>rtB!+qmM{9a#cO<jElpGK*XdsA=g@!1W#<-$MF2ar+R
zjbEr?YQ2IeF++_H|0O4Lyx;###d&@szK at J*e!Z^?bC6O{rq6r<c%?9pjy(1agZLI}
zfIDYxe=U-wYoYTJ<>TNU50Ca^TUAO)+2@}|PS%9IpI6R5>+#1F6+z0W;;J;Wb*(Y}
zoyEO{_Zl7N1>V()LG}HGr)3U3rC!K$2tZzU88SsL(+|=#^n7{(_$EM#>Op|GRM{8>
zRe4q53cRfXY;ALg-^ec0_)qmYjkZJPUd2cJ3|QYjV at b?xL1ol9$mg#QS{T`X*!_N|
zJt{0tipBp(YZC{=j{PS980up8^q@~xO1f+3q&RR_4N3)cuuSLNoL at 55V~9*(VXCn+
z(D=(Vn?v2`C=;RN9(DUG*a7(1?io%)AB~ph!@99gp!WjR{3GyL#iX)8c*elHp5LW=
z_Pg2$cWbw- at +pD-Ovl=y{c(}O%nv&g%E#!`&+(Jrhs^~G;N{gbJii1F%=oS4sLey*
z*;?~Jt#G*1pc07O+pNW<474gesHFpOLEcI3k*L_iU7YUMs*{Z(eIR1HW{5?dUz(oH
zAb(0a23E5Aj-D_(^qka2!8bi*U8GZ;t)s<DO*35s6W)AWJv{V^Y~xro`W0rc!J7=>
zb=;p+v%_O%auR2B4isT+Wr6AU`#<c4R^uIbEs1xTJUIC1wtU=n-cs)<M`-vo2%Eqa
z2N1`hZZ7ucx;HCNX1;2%p+MNMi{#j<{R~XcRuaGU;FhkXXOv+1tLEpZT3))HjzGGV
z9X1^bj|GVMuyMQ6a~5en=?rcR*4}c^erg<2u4D!^M*U*GX^8g0=GJi1muD7dDKSpM
zX4iEeQ8LAiB2^n(1PbyH3q86~V^?zJWBmp5O{v&!&RBc?>>Y%9!cQzd<YN1O+lTH^
z at x^K14FG`sh?@za*IU}37Al|d<MJudO?o-NO at 6(^U`JdtL}bb32Qa+crUS~VV!@n}
zWM9LbpjT}(dnU7*Gr&uWDH;F``V;`Mif-0|q*#2ZkO469gnR*URuY+FuW_2raPbkh
z)&I12f|O){bsZVta{=g>bJ^vsC93rU{tSo|@ui(?mCwucdnLhIfQ9-W(5iRe)@D_j
zZT0)V$v60T!tqWumadX_-Iim>CARbh<u+4%Hy=UHJhZ&4HtHBVw>S|~+D5ZIaYyI)
z%OIarFYSyDGgy84(^6%w;->{JL_nDD?c#oC|B)@cS){?)2M4jCdpl<^nY;0_XYnL9
zcx8s1-}w};aqmFyJ-$%H)tl{dW;C9|(Oz#SKCN~|F)&<_yS57U&c|_k=czt;gfsqo
zYKf6CkKH+rU90?i>N|6elK<|F3d|hM1RLn)3GF}+SyS at 4c5WuJ*}nAt*<I({kdLg`
zPdBX6$4xsV22 at 6rl=|qW=yyOqY98iregw5Ve{**n7fdK*y}8 at OrhI}pDlhI0ooDqI
zZ7SN*%=UfnX}dccKVd`VFLEvF1 at v{fVtF6I;!jDltCoS_&ibVBOn$Y{PqI6>_5Nyu
zG*7q!g at R?DbijJ5Fqk>+)~fR!@dP12L-X9SO1v6OI>RGcs9<?3zpNS at S~KRN6_86q
zyALgMTGOi(X at YmU?2_%!8>k92CR^xp`Pr9nlEoT>@8R8=8)e<R84zL!%SV>d5?r%6
z#vOp1R971;2|Trlbn2q*e5Gu_kgT=MtYc47(D$~{l6fDfaS$D{1;$=JIL|-x at 3ncs
zUqI)cst=_?j%(r{@X{R3#{jmClt&h2f(d_4&VHr82OI4JPGm=|c7)WeP+)@=-*@_L
z%!+Wz#0^IF>BM##1q>+x*h00MRp5(v(D0$wSZs-&c?_WZPgMnS3_4MqkH1-<HG0<&
zF&*=n8IIYY>?yV3soN at Ke!u%jOoYE3-X{%N at Lt6FjfS7hEO9yn@N6w%!fOWkx_cb@
zp64OKd!}a2N9s{t3z43T=YJ`V01Na&??LI176}DL#YHVE3w$@I9?qnmuumZ%(L+P8
z3_JL>ukWzo at Sm9UU%<&)2e!LeS);u<)h|B)afbX@?eFi%^o$xa)HHOPk#JAwvXV`o
zWXllP;JySGjMg{8z6{oTC45~3Bc{Rv7s9kM2!?={MpQ(eF#B&<DbbkD{?Wc~1MAaI
z1DLSaoywb^k6u?fE(S}{@nt?iO5LE?H6#;u#dLW!{e#gb(QHYlXjR*0AL9Cuwej!@
z0M~S&{27cM__M(mYgTOYar8gcFU*QOb3gJuParReai)X(&|c|Ehy6{n%b^D)KLYCE
z%jL}y%I1&W)HTq5)n%O6o(^(0E`L}blz+d(HlsT!%x;)!rPk3%V+A!2frDF(ym+UM
zQkZ-j{xeak4SpODtQ6q*-8cs|T95fzyJzxuKTyg$&LEAOc#~XQl+d`>d<&uQLrAlp
z7noIXT#>1P3+EYkOV~akTA^fLl_56u1pZcs$;mKZDOJ9g(=ua%`+$eJxf2A7^!(ua
z4o4pgO%=gkZUL#Q_0NDLu`EJ0vCGZhcM}l^IJB35`z>(WqJAI)LMO;^vb^&*U{-vx
z%}%ULp0LOSwzhpA^u0ZVv}<|hZBJD*pXY25K)>3wi1eJvN08QRPE)DznDL~l(Bszb
z=NNom>G^oeXv7=A)*H1wa8NH_R6E<{U^DMgLx{+%P at mi506PP`A*7KEg+CQF_q<k5
zk2_Kji~!oSPrtxp)D8q3s&!8X$i6x1FP3U!vIjbB at C8B`hiF}M<$vp>CHRT{bf2_^
zMWKhSiwj*Pe|PqMk at fXSR>)bJz;#`6BQ}kuH#2 at -++zYp%!xBY4YCf(bsjzS-#~?B
z&r14gwg*mD!`yOXVV#)j@^HD3_Am5Udj`IBzB2ZPgXOwC1Nene_W(`KV((VA<QWJY
zE*Hy<3~RR~opJDhe)o|&nVqDlB1}n*Hi<S(dH?Y_mRCoIJ(PO{=HJTvU775X*BC0t
zG^r6}8JBZrAZ`c~U-i$NjyJtO;+X4o-!gQL^+Z!9E8^Etrr`4|v9-AuL-*2r^}Y-K
zoK$IE2#^@wQES$nC~3%By3o7tHtewFFxl6b2S&Ra%QZ4nLosWT>a at yO`-LXq+Z6dj
zo#2AM0OeMn2*flGkh?Lsgxex^J3P$I)W8PS<$bd`=}STFiGP0VX~LF7#ad`&&ocQ*
zme}i<Le8<wZNSx~IyVnAOEqTA>|OvFoaBJXs(^*orh_s1m_}Jk;u&YU%6q7R7?`-B
ze+UQ`>j~Q>G)c?!6~_2QEC*m9vj-}(Cg|;fOz6iu7?W5)x19T?DpW&dDs at IdLFN@7
zq9Z+(OOVxD`z|XlYEajPiFUqb-%+(Z7O(eG%s`!C(`E&ixi32SkKi&c`sxK!ShTE$
zfBKypbZ%=A at aI1$blMIKVmJk9gcZi_G-5s<knVvkhC1{folJW_rcSt>EEYC>W-JDM
z6awGMTzsRbAe9J~aiplOj^s>h`^3Jgy=aI00&$JX>ui0KSg)r(&%ah8amNIeIJp<7
z64e3?8Bxmk#{risOPg@>T6iQ at ZeG}KC<s<>5GE~9sr7KR^*#U5)tmN6x5<--GmHX*
z{E9D`?HUzNZ)<=bP#kbJ`P9%<^UC0cXJl{-H3wr at MTWp+a0T9XJHYXgVsP8u2xQU)
z72vpCZc{)?N^2$cVN3MKBLh6v%Sd;6K)}jYp5W)T>*Gd{HAad}CdWjb+v3$_O3qa{
zq!>a-S{x1C(aEIR6eQ$H;T{yasn<Ux1SiGJ&1?1hTaZK5<8p}i<ow7(mJ_5NtZNjM
zi9z%2UNgD>e&a4bed{XYQrrz9{zm!FOfy<$#Pz|t37!Pc-6Lj1Z7eWq^jKMb1>Qt?
zUyt(CqeG1)^3ZS54*>hI at CHyHBOGMI61(&BJ(T7PU?R2+(Md22w+ZAQRCXww%J=ll
z)VJ6KEM$&VL$858do at LCruu-!JeAPV-JP#}rQm>N0QKMcSk=4H(pRn2mM#-^r&ZBr
zm7N#`pZlM69zQ^zF8W!A6mL}^R7LBge7$tJX8IoMkKoIz&_~~pNW5pLLwZh<2Q!V`
zP50sfv$0g00t1kUQFljVr3}U+&3P^>sTv+JI3(rt?Jj=x*VR$ya*eKC>FItO0B^8z
z6k9W!C3csdL>uI(m?FO(XG*Lr<pe3Y_&C!K=${gPYA8B+WnSSdBofbd2 at O~34#iuK
zz6Ld_=lLA=sSehPrlgp`yqm=mwR?bq)?)uz>6<1HTa at L%sotg{?f=a>4!ir67(QuJ
zZD(C~TaIDzcj at +?1&8iPB>-5BN0*!$I$!LD`U5}OlLi~|PfOFFK~W6>u#N{;Hqz5Q
zr;CjTOM;dRq*)PUU*PEwh9eZq<D)qT#6-T8k#|t?bKwSWF8<y$N4bVK*6<%HsYl%Q
zCw5iCTMI)8J_>JgYP2_GY(yP&1Pd$+exnxaKhM3k9d1y1LDS6lNaSPbmJP={g1Dgg
z at AR`aUIr*l&vIdPQvkyd&G?x0&k9Z+!0YPZv9p68%4fTzDGMALYQIsb*vfLFflw*z
zHd!waP0BW^ZIryN6*uwtj;9$w!43G0-m58aRzx=3Y^-aoQTcTS_<Y-e_84KPTWP8v
zJ9r5&(Q)47d;;A5$M2M-zX#^l^M+{SNQ)gaUwY_(Kk&CKP(#EU#nwZ#ep*tekioAZ
zR|*<F at a_TOw<ib)jPEF9=KtcS)bsUaKybf#9RCMk6YK!P?haqF at h?DpKR5xD9Kh|>
z+GzWH4{|}f>&1%DBd;Ct`~q at L)N9cdD^_f?J?AC4Rw6ef!Toe9ozl>RQX1s+Sx at KI
zm)MEuaqt&<8DkIi at l=VZ8G5ApbVAb8wiq^>GPJnhwScEScBO2qBf0l1Lr(tw{d?ur
zqQFu{gBZ^bj4v~HMGh%see%kB2blg{oGd($4*3_T?OZzt)DYcn0At16OtD)N<A3U5
zbInCx))v!XfHbH2aF<b>)q12M#%Z6^?02G<v&6UYepAe}hoyXUrSn3Lp<hb?CHS#^
z^hYggTYGd~+h=Xq4>C<NxExoQJl%QOlyl}+F!I0}nyo~2*s9v3+_4 at Qx;N at jLdwDk
z#o0g~*LNs)C;!ZL>pn)$eWp01+mU$k^d{?{yZ6eQ_nI>}rq8ENh-fJQhl;7vawexK
zxHfZ9W*c=V#>9WR&7xUWrq0)Wp|M0d{GMZbmu7~eeoNxndo3Y~71dCRrvwJ}%5Yee
z-`sF4h at zj~$5i0cy$8H=4GpeToFdQo=Ts66OpE6Nf}|uxC23hPg;o>Tv_hn^mchkg
z**(L~)k>`eC{z9s_421|MMoHTBKK|echGD_O4EOA)f|8auOyfgH5$f3<>QjU7z^P0
zk7laMH-UWL$r13TaWAUPZ6#<y(33FsfV~YMU3aD8=`Nmygh8!LYeQ at 3&yI(Qs?C1^
z3UkN2FN~IIa$yfh%w0XT2x0Q6A(7KK!#MoDEXCkxOa0|;nSmfshgAI<n0$mDf-73q
zTghK9#Tl;*J&4ss2jCCA0$M?`JZsAd*iA60=&h$fS7=r4TlXockV)H~2$@Jy!r)3*
zz1GH(&La{`#k^kpa(#5mv~x#&#|;qzIT+p>B<gmSy(6&eS+7VTqeZ^8X}0+5yi6mY
z<5Tjcj3ul)qF&MjBStBOc|2NtpF8=oT`5VXWk11YBK*6yg at IcM33{lLU2Pw`TxEgy
ze=opV_t}o4+eUVQOm!Qn^aH;|NIwvS^Ir?AvQlJ=j0$zERy*tmxwIE&!s0JcwoUI~
z!S?t@&<&pGQQK9oNlag-l)Yck-TP6C(Bfh??e2$?I&Tz<8?;X%0!n|{8OoEUmgjMN
z_rVxEt0rKUEG-krnrYxE9$+~owol`I6{hX;#gExU^I5^NyZ_3SkhPC-^qif$|EA=A
zgOCSL(Z$3;t=jy-6#D;QxnMOP=VN+w*vuo7(hrBX(4&S^No+OVm9pCDM?Q4?De2db
zex*3n4YwN!Ot!jf-7X8PopqDx9nv0N*-h7a?U-U`<ei%PCI%_7XWKkUSxAvk<Wdz-
z_VSliir$ALV0C^a7+?$hF$@^9_$CxcB$g7I(;R02W&uv5N`t2H;0aI$VLJnStqQ_m
zVDAu at EHCxuc`4TIxjd^s?Geyp{T`lV at v2<g1luUv!M;1Ez&&1|+*Nxp{q*MdDby`8
z-9H7w@@UBObRdJL3S7R35U|Eo$Ul{hU9VDWo$+U1eF3!GhpWBa75J2HXdLwsB_qOD
zt!?YOPIaA)H&|&ZS6GA132t7;Jbj!Wp;o^R*h1oy!v30j?_2^dzRwe>RL8;XcZ<Ss
zNncMwqrHS5crc?WLs@;jb$3IzfctLm2x%ZvK`w`}hcC0`7sTuB680u8WfG at Z=D~>p
zEGq)2XL|@Ag at iX|FYB3&$DT!f*_zatZ}o_#KZsXby)n|3SE^3`=kx1Sm)u;PsBf@`
zGZNTXKirKYus&>{-zvVHoVnl at IIwbfVcoeL6H^<&Gey*B5 at slRJAK?3?Ydq_&I<me
zkmqTfnLk+m$7lXK#6-6FjDlOg?8d&>4i_ZVo5m;WYRL+iU3bjY7x#?t!gU1LHb2}O
z_9;h(!stqc4G4Lv{*qo2H at 8*70LoWp`DGAxua5Z{M=!)|4)P&W)TA9C8L;OQHfCCV
zb+!zGM($UOMl;$;=(OZ_sijB9KSR`}!dz6vFp`ZYnvYjmaOB*iEA&6$-Y)3iurJu{
z+mp!53*Z2*pl)K;kClq0g}zXoCy$K>1=zMu492F-KILI_LvZ6fJuY<{yXe*2qlCQz
zTmV|l#In?E&fC+_DQd(<`xEa%&uTz;)&s_*(w<#m;9bRE>k^Vm2`oTmP at r*>bp5~^
zt}?5+P@$Q9d<xXYR(zNJ+zXf{V%4oh-z#67clUaO-$9hfME#~wu0JMy!E at zpVZi)r
z9s?X at xQvYfAa;OV&z$^mr(SF~6SFwl!~D;9R#VB+J!+X$`K{HQ&X4ic6VCLKRYyoc
z!O^&(Z1CF5;0ZUY#1qWcSmzY~!>CQ?6TfQ`mG#r~Oz{+yst+*lMvvi40yVG@>><Q2
zo!(}5aiZoM%~zB9gc>-8{HM(zD8KaWhFH<4eyPRU-_cO?Y%hf%)u~QOGO0y at 5lzm$
zDRT?I74(mhNB^Q80PV|wZ26J1?4Tm7DybmPNbI4 at fL_64C^`GrfCcz}TUJkx`n at 05
zy^QXJ at uTZXL&Ck(O5kL?_5Mg{Cuk$6L<-mX0%{8nV$Rplu?RHaotF;5h$6FLHx at -S
zc3NxCYR`|&Anpq}0Zm5ObApm}E7<@2MoX)=^SZ-!&6iuj4cTtzf#|zbz6~#66<XeX
zE^<)~y3yV}uO5!kG)f+feK+TA9xC8IFF%o?d)2_u at Zm%fCYzGvBne3kXdU%cQQ9Ge
z)ylXt;W`TheJ^qIB#|U(t)?WAw?D%9AVb2Z+oun^tsTF=_U-7{o5Fn-`7<#zq`1(!
z-r&WKyMS~^4?4EVA!g3;+OIow`{M!#e{61fZ#$oRoj4se3 at xH=L9^#C>~i6kaot=@
zwL>N;Y(?L+nc|0R#G)F$c6m?ht)DLW*DM0#$&@iJ3Od`)LTT(dzhdavEF!<=gC6|o
z{D^p`eE1d65Mfzc*x(jLIcNP*0qqksgC?BmjRGwsS{2HtGtzD*Koj2&;ubKABgegs
zo=5d%Dz?wt#sZ9;A$OR<tJxpeQNZ;h1Vq`T45?3J^mkE^?cg=xn%F8fSAyc1`r0S;
zSJ$}GjW!i1uiHx+cJzOBAydTPx`TYc!z}mD4abMv#O$MxNDp?Z>|@DPJ~}%+G*8D>
zs+~8vQA;m_b?S(p7Y-h#&<2mvM;Z at fr%BAC?jo)^Q at +gRW1UJZakkwIF!>}qPRfw1
z9CcsyJp^70ab32tuJbhIj0ny``pKkb{WvYdBKygSrwR|IJ&!V_Zu^)*H3Frz_%kdG
ztDA-rUrr+6p=O;O*of#lkvyiszDKfnxkGyQVO~t510t#bM2hgqi74?2WeG_+^B&Rp
z^{hWJ#xz{2T~|Vexf+b)Y0cf at gW2(^4mx0&&%tufE8AOIT4vPgg&l=<4w$Z&8gb&Q
zXd*E;T~skP<Bu$C{dEMu__1NP>`C!&>`7-<clMN9J at -m>riMQ1q=AJ?^>m~6Q6Wm!
z)t_4++INpi6?QY%CLNzGqN*Z_+`^Y{b2ZtoN7TOvFpm9!?dqY4^!NWK2DL1j^E5^I
z^7sH<S1Q0^5Rd7p;7lNk1d=9g-JtV1rh?W3YjE|hglb&eqxe0p%iLvpSl4Z*yUbd%
z?nyqtbxQA}#~s9hf34g1h{aXE+GC+AB9akr?(NiNaaXcH!O`vKY#a5SC4#^X*ZMxg
z6$rWXzSLlzlCqOg$|%#Rvz-8b<i2KcyS{r=beUK!a5Ixf&BPt7{rJqp)-w9H4qGN)
zIM8SP$P`lZ;QW=E+L%&HKiVm>T%-W*TaaEd?Bdhnuthq{K14bqt^3ddrrx&suFZk3
zHniRWX1!S!syA1KFF?Jeop*`Wsh!)Fw$$JMc{hW>Eo}yjN}&c32ur1#=`EN1ZkSNE
z?z^Ez<G|4<T5}7+1POCjP~A$}k~LKKTm(Qi+jN7yN`242N!W2w`C{q|y7bDcN9$h*
z>mwM%7_uGGClUTsXw|93rHQ%B!3_`2Cop=#1+fFgC4=$O3NY%Tz=Xf_zNGLgO>d+$
zvMd$si>;fnsT+Fxs-h_D&HBA9PjlUImokqw<`uWLm!(OyA4}4ZRKZ#uC03O+s&I4$
zB9X?N at 3z7)vZ?KP>{IVp)+e-1#$)j7K@;FI{G8!0{j8W)M`Y4Y?-YKTomo)%$1 at w(
z9;;^~t8xwo7colR)rmQ;tZ4P%y#+VLZN*96!3Z#VCq|Clkw(XYakci4qTZ-2t?Ikv
zV)U0Eum%-Tt_y8az&CRC*XnNKT`F>l*vTH-^_1hCf54mno<Y^N`swOL&9>l@*r@|L
zKMJB;o5t1q+&y*c1gQToZSLl<PC`T33_JHA*xHA{KEpx<*Kt?Pa{G3i(qG&YnZ6=H
zW_|)t0Q4E$qxQ0EM76Bq!+bvS#Y}Yr;L<6nxzoMbdEz=SCimZdCatvQ_(MD9q(qR5
z_y at 43x;*JneUd*qVdUqyuQPk(2PSilllGI1hSpzBZn78x#+u^`CIfK1e^!xc7WKRC
zLXL>J$3E_#$}(GAC1h&@VE(w#0~jNK+<7|nI|K+MqSH022fJp#UC)31yrwhfQI&=s
zIJmgdyXlu93WnL>##z;?!c<gfF{O2G0n5MV+d`8d1?^8j{aI80Y7 at 1{Ypp$#X}KCb
zzs2*iAJT`)cOp9-vdU|c+uupkQpgP5R?yWel+>_BC>tch<aqaK!}qtHW$Udauhq!9
zMw}MBRtOR7&5{tOd>C<Zg&BnzR#|vBbn`|#{tQWafc?_@{PSL8#!}EvpqcmYueE_s
z_YNjGO4;Y>jRY$H_Yd1q$#EDCK3Ai7f}DW+!2v62AakXJ^B(F at UbCR*wKo1P=3AbQ
z(^FgsLa&)c-Ern_3 at mn+dy2odx*cNuaQqSBXwM+|lcYrMwo%)~{J_iAYhB>aR|Yxn
zOC%>39$O<ongF;)x6e-jF9VXQP3 at go->WX^fOE&}Mc}TL<|{1fUgH)}px8;WSRUC8
zAH0s-m^;`Otnumwi2**hNe7J5+xYX*8^<aLejoqa at +FmTYi<!+cMS_VxB0Mc-8O~C
zL#ZOHEd-gVQ!5#VJ|}38x9tmYk4f6D1Dj#n6Ye|XJ6O-hv3dK%hMxtJ$S+Q7jY7?w
z(%3%Ws-ugzA>QOU^SVMwHI~2`tV|i_iB{L*>j>N8uoz|BO~I=m++nkiC`Mcggkb=3
z=kaHAphx8;Affk<>Tb18Q06%_J=e8Lw6M<g&2^bTxH(SM7<p?jg-Y#JTj!&IE=Mzz
zM)4V^??SqHn0J78z#=>GS70$oOXPdzk(1fy13`>zA2;2Hf7Qjj1)PQ+K_#<XN8#rH
zRe`-N at YG{Wl?k|`a+Yxe@>zDn!BrYP;f<DQAq#bC!2gH<in^L&dyT<lf!LLRFK!#M
zeO}*|WCJgq0ux!h3z$Lgogl$x+ELDAjch9}v(5ZZg%6kFy2M5_+j8&KmQuAP(w7tB
zZ@%Qe!*h>Y;~Ck>O%FH!msa;&Po%DCv86Dph_9h}!0q)q(gn90ntXgq;Qt{z!ERLP
z+xW-rIxE}}WjatOKb$5o%0rp;KGLAJzhSYC%ysXzpe25im`c?MGfcKNoW|&=@GI}-
zb2hQx*;S%D^z)^;gKWZI(@fk7ZT)hiV2JNw-OI(lh6NboG4F*V at y{A*y~?{)TUKtz
zBO;n5Rsn|n(qph#-DfirrDIiOUtv#E3SkROO?@mJI_XK2;OwW?j at 8=)Ub3`;1v at 31
zTb7`P(Z}_LfZ9>#(dOv5Rwoi#Uc^CnkLa~~mmy_K^bK$GXoC7CBPpz+b6No!553MS
z<!n2wx3!aR92W4#2X26%8}cTeQwdTW`KTGoXVRh91ogF>4bO5Z{bKp)Un_ at we5dCh
zm7<QLB<^*S47bqq{rO8_qnwM#^6BSK)t3}3nVWV=+MG8UtqHOWKLTtzI+!h+`?VW@
zJWvAEjW at 1Xd4Pj-9)gc_1lQxt?PD at eMiaZQb6Fa$dmLx%3IUwl at 3k5uq)F at R%Z|u_
zuOPyuAvBW~xRGQB^DE6(L9$2fR{-SmtHklPxetw9xf7YLfKm>Lr2^mxJ26ldE!NAg
zAPe?qV~oBq2{Z+!RR(HH5dQqkBa5vl7Mkw}Fcsnk6BOP<`BHZ;2>f6ow{b&X3Prds
z={0uB0b;|_u?KKF=bBFm%P2v~GNqAZQG6bik<7S1@|iJK_+~h>^?lyy9a-+IY9rlC
ztVg8M0T1bjnp{Ld*vP}0NHfv~$BmBF=Y^BYVKuTc*IKV}^UHZYCe(wxT0Zq=SS4+{
z<|NlhdNSRGMcsdRGy`)@b}XyP2CL%78$h`AqUKqE8Ad0iQR$teE26<~UPlV;>wxi*
zJGVW>Y(edI9F$IrMan}az=e^KXAh>TD~1(HOxW+kOC?|O<~eygj*CO}xGecVSwT^R
z1+ZToo3*#W!)h7-0*}3>fGoS~9-g~IrB=*qch&P%66J4|%WFBM+KuRM at PsuzoGTKx
z;Mq{4<+h2yNah(JgP{Sbm}=#F)!N)^>fnR}8dApibEBF%%8`3tr$rYq-QlAuXLGP5
z#!7EhWz8AH-hww4 at vn5-($+MdnHTTE`Wo^W=pO8{H+6MRX|8_aJZwN?3L2w$$|8~<
zCO*a2`b~dw*K(z6GqBtsrP1<yGb93dHl*_$TEL2*qDbp)K{8xOZv|M-4ZT!>j6<cE
zN77H%B%si*Qj9Z{6*1MvjJQ4&1=Z2yBf3$(Hh(l}HMgZ|r6$zZRort`3mJ6tQylQT
zGti$UOebqW?97)s at 9q<)&gu<IZze`pP{*X$ue(lAL)vt%^^1uece(X5dX$(Fmw+Pl
zKuRE2x{??Jcz8y4aD~Q90Y63i;{LJ2i8_&*Z4D$PCSat?EZLND{mh>1?oOzrG;i_l
zSFzb~xCa9kM!iM0MDn;XX$Vr9R<3$EkA+2 at Q#@%CSqq{o1bKLlRQEUz!E2coId%I~
z7HzuaF6krUk>g=?poD=&h|kQ)hu|uQW|I6u#nJTRb&18Ze`sYPH|iVC#%yuN0_8S+
zBz68e at _V3FEfxRD3Er1|-y~=QZteo32ZbC`jWun+`?yuS(XrZg)Lgd<veFUKO}+X$
zU>68I<Q9-NztG93`BGeEiBSR7vl<ak%I$Dj&9?F4`~FnbhmKXbyrRZ283C`e-h2C|
zBon`<DmL#am<f0zK**p8ixRw)eG>dzd7uFY%%mo%jG3--CXn&=FXQc{#b51?Gj$xw
z*@`g^5t*X?$mt~j-zV59(01E=__LNSNW=TVwzE~_*s8MqBqvuUqRkbW*K>U^dfRxc
zw2qXHewLOJsp!o=eQUhyO^I79?5MK%Nu4m1EU19*pZ08yl65*Muv&9c3*C0`;7{{B
z?)1gy%D8{C|8og&yhWrI8bW8b-PFB^3THk{xo7KXhZ!+Xwi7<F3q<5*DoYFkJ{-P>
z3NIKDDQ7_CURVJ0W57~;oLK9oFFI61Jq0Knu?EB+XL|q&)u;x>5=g5IC2XL8?sLyS
z>TdFQt+|scDTP1)s%l3x<b+w65d4!?KVMuPyl|D^=A>x886a5h at C5YAzDr6Ev_zE&
zBXA?XMs)Cvfm5k+KI_f5mkVRU*-lFG1%n-v6JUGDYw#XCE9RXaRn(vcUi%U-wLSop
z0oQj5gZ>nmpm3okJ&h^KN at NN6lSqcMM-&^n>XslZX(Yc+a;lW2M0eqJdBi(*0mlR2
zy2zAJ7ET)#WgEzYx607xrG*!4>kBQ;ray{DU8PcXX9mTKO)TZKj`$~Q$%46b-J#I!
z|L)#djfPHbnpJGKbOzVv!!fF>hqn at G@}5RUAK8!}2g+Y;UGNxg3Uk*fdyA~R<M%@L
z?WCTWwA%1i4hc<%)pGzH3yWQM>U=kiVyIdV9uu~=E#iEZP%cPd+ziIu#d=AXJ4gc>
z1E)Tr?le&4W&sJ^%PZ=uuKC-sxO6IotnxWwoTxMdk0vj-U$3}lWmEpx{jhAGtePO6
zmnD9gpqo&3f8oXl^@Z`mSSdhGc!&E2;`I6H7+KYy!&)f;I2t)11>H5Rh73WIk)WZW
zp9;MCQR4>+eMjX5SJ9EORv$<M<q_`I_-(|_Jd3=_`zvqHMGLTpGxpQ}VnukVe@;6e
zQs2sjv5n_fQ%)Mja^BFIkA><$XVZad0JltSC3{<>4;^qIftZsW)@Ib}8388z+e|pv
z6fjbhK5@(~xH$|MKsUFcIJFo=Opqk-FxDj;j{itCuIPwNJ2~PV8w%&5hIoKY)rjZ&
znV9$i0!1feBeuf(Tz{4cQFg%bMtms&ZO!Ra-SqWI-f(K)ArSM^884636%i)9JEPgr
za6Q*POWL~O!tSc1-?;y`EOCOoj8YXYp%bO`vG1kuP)&N1*_fmIGhe+s<P_a5LQ(Yv
zjrvP0UVegDkU%AT>9t9jFeBm4RoVi%XA=LX-i>!fw~uhqMCEjG|L4jxjh`cBU~x)3
zTduy0E_lpw0aw=5gs0}AF1W$}Xr}O}Be9)8P5^q^SnH+d60y`!a?~ruXiRKlz}F{1
zBr2heEbU>lYN5tR%6ugUA5~?!X_B at 3VSU9q930KC^WSsLg~pDAbLCzYnlh{+qSAv~
zRjFh2ZiF_iDFuILBlBf_T~JmygG>^$b7#1cm=B{=3ps%c6~o*FkWcHW>i4uz;iQa5
z#U6uGb%_L1C8M=Zd*x5NH4Mt8GhV62uZ>QU6 at a$j^aW6-__WILy18jmX!|z%brsA^
zo>~9=_Cy61k4&pu<Z|vwbLCRFIUaVz$q3Z!2E%rB&BwMp at U=TT;!NCw_1V2 at xejQh
zzy|JYkut9b_*}_Y$MI9(LB1Bh;!JP at zwxDe&dr4J5{nPdq-K{6++3rfDo#|5>Q~@E
z>46`f%DN(b2U&m&N(1oTIL%LrV at n4!xjzSBfzNB>oB?1>DO%hnJ9UPCF?yPS39zNK
z9pH6s*l<3=%2#~=`*Hp-xI6XCAQuc8n9}giMLTrUJ^#Kpt!=+2bkm=o`P=4B-R~9P
zljAP>G7dI`#|D4qERIx*8ZwnRte$vEW^BPLL}U4-!j2R@#&e#K>CiEikAFT55LBM4
zUa{=%mDQ;<_D-T#J7F)7i`O!HWwH3Q^^2+&o`JW)`<?(qCb%(cF5dJk26T_tQgtzd
zTEBWdXmTY#Q%(!w)H%~LpM|klxe$GHFt<A_k>dO^1-`zgd-R=5k;fnkvR!2H^3yx(
z(3)4+oCVVAIdzOV%(x1}(SiLG(`Ue-A5k(Vp3J>wi?%LCrFSgQziZLw?dsve`J$$#
z!-`*_sakB1EF3#iz7Ok at 4L4`O!Vvoh?~lcK>?>Y|g<h;48%>^rPnzK1d3Uxy*z_DK
zd2}fSE3;xHQ&muo>09c;^O=N%$)5&QUD~efwg5RUTskb&t2<^vp#<u!lCOs}&}x4Y
zm3mYzK3K*><+|P#o|@7<bh&eIFRvwJ#dcF3M7dXH6IF?f$7jiveh`tDyWXD%M0cq+
z8{lxB5C%joVG(+m?&4$PcmmwgS#Q0C{+-v_fy!^TvLF<m9s*T+Lb^anIbcaPNVeE)
zV#$jGfTKCK-><sOsWkM(dIH^}hMU_s0S=00B|yoJZp_<19r7XYK&oc$R=t`9dZ!~C
zip-}bgSgq9k{(f<0sPyR+X&xOV1(gI0!thKK0uTMaOy}-5_BpD>_>&O(m$uC*B?1S
z{W?nj=Eh~AX7_gn{O)sfr(X-HXZsl*!mAALo_I4at1C;8wTm5<{lU^^WLTq2k{)Qx
zYC at HsGIMy-7-AmPx#3S~0@?-Uvr~eZL6Dcq>z_r!{qH(w7LDUQSSRS8CbRM~f at +C9
z6{jV`PPG2JN^<whgf_{EId!(i_F4?vY_v3`k{RXKpB5`YHWLjAmlzG|INq6&81H0G
zl3$cv<)qXObW=kg?q);ZI&rB$u*o7m$%8 at vUelH>_64DLEHNeE!rN}#wA+H~#Nn+a
zqB-LpT`xTk6lw<hc3PkvmY=b!<V1sti#4&8yZI(ve{DLAGi|#0?qKIDZK_jP)<?BU
z`nPi+Bo6%8X~#5)i(+u~vbOLuxp>jT!3pg9eH5``bg<qgU;17HjU+D*@6l8mU!_K-
zZj-D1f62|0R$3n(CI_v{gPYm|^fc|YS~CsNv`2r-&XSU_THSntcXTCdDEPDv|EjDV
z*WJ8x)3e^T%Au;{ncMHYpJiCCbq+NDR2!fyE(D+N_9Xs(3nfPbQo_rYC}@2<kgfbv
zWURwHQCq=H6x7_xSc<Op6pEIlJJ_o^d}x5^mbnBhH~RpN>+JXjqR|G(m9GL-YQ<D=
z_o#mW))qauKMfei8GmrvVF4+?R#iF7Sn>!}u(#Q_>JL|%{TR-o%4uiS`Inuzv7;ET
zcmg%-^3idA+4yZ2dm0EFOffmj3H~#6$$5LZe}WoUIMaC^G~V47X!*x%6SbxH;ejDF
zoL2?EwGc_GLbc3tjn=0C#Ls;t^K#8f)EML>(oXHv_v?E|V8ZLOdCK#X8jJKll0;sS
z)8As*xsD>Ik9ym0r|jYC9|C(PUBg&c{rKb4^C3guz1<zLl&wU<KbLKr%Tx(`ybW?V
z%UiIPnTbJ~%oAhg!o4Xm>a3FT7s|Y%X2FEDFHxW$ap9Et*8($5<|s*g at FKXSwBydk
ziNJc~!?jX;JW-LX1y+7`&FKZ|HB4=6>o1Up^v?2DD}Cd`$ri4M at mw*7b~QkxD!4H!
zqjFpPX6w0cQnaAtgE$6eUobw1Z5cb9QVZb?Wb5<eCae`R>PoR5d-g~{8<=}FPIpCa
zKMiHNEv~V}hSm*3E*i^j7Uc2%$;6C^z04Q4EhvZ=hyPI%xohbu6<`#gTz~Au;`+w^
z84K1o$1F-j5GTvohq5%7_Ig at k0XMuhEOPR3!A~ND{11*2-J+glTAFR9Z~B47H$&9$
zKTU`VNv3fM>8U at 5V$tFHaSe+QKn2)2kA-qZ8!`hjfjqR3Md1Pf8c&uU)B<<PQv6SJ
z-roMBc<Z)uTIDvA4P(RWH~1PKUfr8u;x8kUxQi=V=~Y%HPCL at q|6f1|urSv+|CV8Z
zPzc^OE4lpCxH68sOPMI}hn*<cHd(ax7JA&GN)Nv=`d}n~vlhS+u-thE&7cN!3_g0`
zg+vVaCj{IHEi5O1eKLO@<)1h|fGz;A6x`5ft2b`GTD07 at wWXTqM}pV)WKwvI at Dvyy
z!)$g9dNE>+4$HPOa%?tCGWjFZ?yH&+54*MAg at 7=E?|_r at MW6X@ZYo)Yk`gSm)Ms_r
z at R4SY%VgzA&OqH=UwhV3jzBn4V8YsfCfa3|-3s03E~Q8DqVMnB*W}DvV0hJt#`cpE
zJ&LCA`!Z7<Mbaz<Qi>D+j6<v+{^9RJM@`qBGoFY$G%fy`2gCJ4>Y-MmZ!&}N4J>~r
zVcs2HiXOa<yKxFZqnE`>Jp2Y3&FUbQtkOyBLa7OQ8*{%f>EmzZzI7k+7lD6%{kj_K
zMXyzF36DN*2|lsK3<DiXCwTH2kDu&nr1X}$>x`1w{tF<~?%(L&K~Y+hpLE)^jwt6@
zSMI;6C at H(vSR12_A70wf@{#!VL~cZF_}}C-3p9WrYiP=8$B8B|5G%$K8;J)2T(Rb0
zRqXqQJNz1+mv=lRY<0lt793}0dR`eD3bs6~lf02~4$^Y}?*(u!>J%sn2<oN_nWsl}
zYeDtk=AZv$PSlP+icRln0;W{kvT#u?#%@rL2h{y2rl#XZO)dNuFm>oDJTp%<w|F+V
zs&*jDEU|5GebnO7yG;KZ)hK&l9PhuY0vuL5&vm4OL!LgitCDH(w|zo!Nz}LP+<s)W
zEFHL%Uf^_i{PTDZP##3y1G~5TGs-C`X2g5(SSa6N`gn9e3{<JeNmC;ZFs2^m3Qr4T
z0f{0x at eLyR`*;1;^4U_EyT$pS-YPHmnJ><An)D8H8<17rg=yK at 1>^1UP9A)lO1;D%
z9!R&jE;E9B2L*w577P!$eA=&p#LcXuG-hJTy-M$m1=xRCe^)2_-xNAV*P6L}1FiC(
zRILv7R{oCdiQjfLOm`N*vz@*}HiW9)mnd57tO<b4j}N;EbRSuWYD%}IDC3 at u>fLyc
zE^sS`3+DHB%$ExsG%N0*CO%G)n8(hQqL}Go>2_6!t!GA1!9DYqI&SY*<^L$;RI!xr
zwjG59wdHLpw9V|jOCFjBgm7jc+3F0fC<Y at cbUNW}YeJJEBlM}I(Znzk^zVX#$`mdm
zlCTSG3RQ^!sh*{JRLhzqZM|W!&@EVEXF at Cb0q?fbwY`h;b527;^-^nUGn&kNU;X=<
zctz&IAumOD!K&H6KPOyx^J4hyZaN at zhd+{10R=S&Z>CX~DaHlpC at p)5JqRip9fH#!
z<yvRwd*ZD6dFT2N?~{=&zdej&Gv!;F2gSaAS`k8TPK;`xa2oi<s7P?#*bn-|b)dN1
zi9bF at Ut6ZcU^xM0ytQ3D`~uiRI=KwS0Eyhc$XLDV%e9l^KDVgS5@<*_h+>#aoek#&
zZKtR$jbTCPxafr%&K7 at 5(i=DdP~3rya^XXB at 1dyI2yA7eCB-;R`*_cnb^Td$Eo0YK
zCZfjQFRzNC7XcOYa1{+)=jG at E3jCC!`@FtVRuybk^AS^32T>h-2oU>4K9UgF_jgk^
zZnQWNXcDngLrcYIEN|6r at B`n=?=&ByVr0f5%ljjm&u}K75VZE`+9y-?%*;#^(74Gk
z(Q~@dL6tTfMJ`dixvcBa45Mzx{M3NZ&EXiIWayyT+>V7Mz9`ApkY&HFX1`x<Bd$|4
zfOGDrR-EFWsT-Usfo;>L)G_9y6dsT^-!i1|>VlR@%tU*tkH!YJpG(_&!wn^3Ig7Di
zlw)tZY3Sj#-`5Vr)j$ppolY))0ly9py~w=y*%WlANY>}sjx4r4wtrj{=T{glUP(h&
z5Q`DX{Kv#!f+WJ4Jl3#uZJuXmFJS(9kxyi*7(WHP>nY__#(H;7zT7PS4?9<mEa#al
z#(zNx8!SyE7iE(4kDj?uNh7mep7p;SeY9{ElJT=jC(M%w at C)u3-(u#0miH at L{^E1n
z_<Pk+C%w&~sC7~{(matdHf~N3_;MT at S?gVWgq?B<oqNFX+ZYq;P0)rp6KpfapKuKu
z<5kvK;=0b*H={;}iX(8?h%oVsY8`W-&e6Z4mnJs=9V?Uj0 at o-DjcRcFW{1OSGQFiw
zg(CD(If at EZ-vMIDi)3K4)|2t<o*Vv2Lg6~({+ at X!MXA86O=&B|D_9CDacw>!f?~`3
zHS{}+3*T*2Ej~iNou5`1P)_A}56=#WXqF=29%eIdIl=hKI^i-OwI0dB$*d*#j1j at d
z(s$jXU2$RN!XV`)f^UNFs&LvU2CCMdHjf)Nxxu|Q<R^KL at r-Z-;rsLAR~N$-DWGDg
z5LE-{s|ip?u6nW3bZ5_<<&)gCpSs41`mdOhE{vnT?x3c8JeQ!u+0^L=JkW8S``SV-
zw8LS2a7k}dUHRbJh~~Bzz;nAc%i;Fo;&7}Bz^U8oEAx+WYp1IxC&BCn8oVm~_Y~Z$
z1brF@<r*R at zGuneVAK14&z}h|jjVJ5Sg1e-3aHkap0b?V{LAPrcb at Iq78-S=T3H+K
zf+IztNRjg!CN4kRXe6Z@`FpJgWjcDNg5nL^!ZA_C1O1{d#&DSGkr<DXPtmGC#XVg6
zJ+qm`)7e_O#PcQ^L6H&-5|@P+{c$b3O3^b?g4cAVCnIbkugg>)*n14B*YGKs(pdRy
zh-v4lCsNSx(D^W=j_dsBy<-7W?XYN&Kbz<FCbH5hqDF~k;2?Z{r`q_$?}?nh9+m-^
zpwe*#o{wLwkF+6;<ykz+yWjOcy`gV<SO3|5Ry>cYFDbhlf7LCx1c2Pn?xJpduFV=>
zS9!>6GPU at xaYM_XKo`oI(}}4a8bV@)Eu+3e0<@@LiTP+>Tn!6Or^_Kcud8vg;SYzL
zm!plxSHllJ;hzF04DCd4tr)a6eAThBD87>#q2m)2*^lC5&E5q~>P+}Py));pW2}PG
zW8P%J!M+j#K#9o$5TM4$^IC|f1h2&VJ_jqnI9mG|>`f5Rc!sA&jNh2LD?JTuqjHz$
z!Dz+r_5)dOpVx-Hb(YT0%pBEbbOC0&$>59idzM9p{kU#&+#Bmvz65X1W at Bj{)Kz7K
zse6<Y$W}%Eyk>jtZ-a at 9k7_FKcVSgt%7gb(T|qyu at cJ@<C5Qxwdq(L^3EDO)+9*x(
zT<ViO5Vbqnr`kXoWHQFZYO^mrM_{}`i^ADDP4X_zynE=~#IYvTsz`&#QmK}(FgO8B
zZWh}pf-;HnszW_MGU}WqQRh~F)Ozj23#X~xPdIba`JqVjsjsa3RY?S;BU6mSDuHoM
z<5zgmy&p>7=xw2 at P;zCSjr;G0UHZx%?mww$fryL0ipnaGbee0BwOJoH@|&?l;U>;I
zm4cHyQ8L8rkl^4p=@m`AH<5QX4Dcoh3-miGyZq{25=0R9ossp$^PSA9 at SVleml1v8
zXUE7O*Jb`X?9dl>7y2If9a->)z1A9b_R;ySi9;!rc7Y{D0_U>NO<s}z*8P8Ls6P!e
zTxr=ezFF&CW2I=u9qAHK2TJwl9zUABu)Keej%q=@?L9G#W4|-<R)dH`*P+#kS;T?S
z`x2k5Ucn=NCMWi^;i#)Y>B)QgwwxJ$x31BPO-TtwKdmg$X)&HYYt{pSUP3+^XC#8_
z{#$H5A>&3$5dC!e{sO at Spx#x*<96Ki-cu5v%t>Nyz~z%J-gldl`3_-M9<XiTOA!i0
z$SYR>8l?0j6VXl32wdCuwr`Ibk=8K>I6B5M!!pH-rlo0VtA(tLZzK5JOG|2M<_q5P
z6M<a}oy4sB4yr=Fdkt`mjc&h-CwRZ$iKbuV?H&K`%Vta6J%HxcJxH2XHM{WRac at m$
z$euX%4%k`m4REnn#%TG8dPEW1?od~elrBBR#y~xrVePh2A^fa7RHsCShfw-=Tn|Hw
z^=S7tXh3e7kLV`{WggyrkehyCzcCVOM5E!C0GeX5qAr!}4QkU`2UkIVt=4GA82C>~
zxG_7ree7j04bKfnIY`2j>3U#q7*(c?8M&_;G*dceuD=5h79?TLTR2{fqMM(WO`HlJ
z(N at +4l+F_1M>XggZYgze#PE{UoekTp8*I9}L`dDhQigo&?QkIy!_&?3Uo=`7W4CTh
zRL$fol8`W&5{}t>w%NS1>#3V4i`j1~bLxE9N0DD1<qG|-$AP8xL|S&7Lbq$xX6fq<
z^k=i^c37Vv7V$I|9BbvzvAxv at SU)UM(ucwSz*ldY?wIdZeyR;$@3YLO_R|o^kOBl*
zx^racXS5uQ+Vlz%O?M at o@B{Iam$e1Vl^Qg2QIrGp=BIJ4^otC3yHaAkd>h(MGAsH_
zk;Km|4QkaV(o~xcql at H*QYVIqWzd#$B2X>W6J<;*r59KvtqTKWLYCEkpxGbO0Iciw
zi<98ik9=)M()|B2R5V*TnR?l3CJ=i-PO6+eAD-zZzv&4~*R`d<`>oH9sWd?4E>9Sm
zi8bn!9-#R9H#ew$M;kh<pVt=hkBVkuNwVdU+rS0U?NbTAp8ylbPP3)a5+n=o{CT=T
z{C{|UY0a9mSD*Y<LQRW at k=#_xF~HZJEry(Qh$e2=WGiMcz^^@R at N6RwFZ|8L%jFzk
zS|A{7$s1Q+D|vV?)Zq6<UGtqX>3(a0%UbGLQvAH4DjDR`v7=bIX4e8!8}NZr%x at m-
zI!*EMSm%hBZ~&PB>(+>rDcR9HcRnR1n&OPXy)U=GJkTeUPs#z8dH!f8gjcv at hD4Kb
zn*MEQ_K6MSbL&ba2JHU0Lp|B7(kL;gnO)+;5Bl`Z9}W{>Bl;*q$(y%<JUObg%y+W(
zfG?bs#L$|rJb`$gLWv|6e at Q}D4E^$TE8iaN^x){{<<(z%P9TQAmZ?9WC~`@OQ9Ez=
z!io|3K)L)#{H04+Hs=>u1?Fr9>+UhxvoUm1cYu+P^k^p=KmR8C{jK+~d6gAjOUf(5
z-Ba~EqqQET58hg?Y&6!Vuu>^jlB at G9>WHRluNA}j!K`Qg=@)H|FP+ at K8Ao?N^Q#r#
zljeD3+MJ)g%6<ks^yM|<D%RM0xFQaF(vosIWO at eEud+kX=kK(Xz|aA8SF&Qb76aY-
zbkzx5b-_Mso(ouThB_ub$j$x$06tbe%+2>l{{h^JK@<z3_qv92MWej-G|d~GAI=~y
z%a87DeQ)P5<(tb1Y=eMvSm{0Sayg+C$zx-6<9RR^sM;a8MR`75rZ1U~H}<KBg&J|i
zoGNgbe$kj+YKf%~o@@l74M3*2YJJBjHByczAd><3#zo$=wTXqIVy9YXkLI5U+tgtU
zc3x2khR at r4!l3jcMLK*1?|dbXf%TTIRyzp5|I=Y%x at L$TlT->x at PC&gG}`$k=uJEY
zFVj?aewZ#VAN=n3?*jy85hb!8 at 74X2k&nVIlHj(~rJ1X5?y=78>GETwNjVjdgepl}
zRZaRw`ks7W{6Ct`JD%$Qi{mIsxD?q}Dl4O5bIlZ)S at +u8&EBs2<&sd8m0Z_eW$$_I
znU%d=E|*Yb-CN`e;rHo}Uw?YsdOUjExA*&;^Lm}<OX0j|Fp}l<z`#J+hjh1~sIb3B
zoNrFf@@Til?+}K^UOi@$8uPtmu^=wz at v3sk=hA+5UsKVP%=bg{?n5T`HEcU?$TMC;
zj70ZB$Me4I2CNlMvCHBKQ*Pi7`5Cu_CEoItX(=mA4&X;IGQg_U^ge#)Ln0_nySmXt
z=yC$uJ4m$2_ at 1Y&=ex*vpM?|SZhw!?c>8R;)DYdl640HwSCaR;gn1?Y{Co+uom+aq
zvmWu!W&N-8lPQJi4h4tuq)!P@=jk>G$9V2~#<JFHx0V!r;MHD?IQak_Bc$GGFBZrJ
z&>`&=)xN^nyBt~%YPps_E{CTD3|_{-a6tMFsm#EytT?7yVlD)5J!KCpA~V>w>C?vN
z-0(^XuEC$d0rV{1KQc9Zq6p=HF<e|hugT%ysaP^T3<$8(%L0NCo$2RK+30Qp4HqsL
zNLM_za47(6ofCUzpk2T|7!b4JcSmXI6!6O=+(VO&f$i|1Bj6$8b%&LlKROu&ng(lT
z4X4;XaKRFmok;()WBk+W&5U~A7$4w($QDVwgR5f9;BEL*>uw7#fUf<}b7uNq6cJ!F
zmY9)N@=WBo8K=Nh&Q1JmdG$r-@>_}-Gj>c1%Z(oi<a at TQO~Sa%oRn+Tqr0m7Cbbcr
znE0g?vzzy%v|0vUk%)mYQ$w+Y`)saq>#+Ep;6-w)TK)R^N%lX3&i9A$okH);@!4tE
z8A?Vh&wXfOt4x(G0!dlKJLws=V&vq0PZ)NkqU+lHuwA1C&TdM;umXli#l6B4E$+!z
zaL$cDvA0BWrUdenWHoG$hA3AW2Bos0;dMv5Dpi9`gFgmWm#$SymJcD5*YIWuLr at D!
z8>f#LYvp0#AVvNBJKJG*Fu9+ZJ2XU|T2!4j4>30SI?H?-+X+Y&uG+;Wt37D{SZ4x!
zkFWc2L2Q!u&_Pp|nrK!)O+kyX()O8%!rq~!8J}|RIfdu%i&{!s*&Nw~{6w;zPI8i<
zK{h2KV`&(91M^Z>*D(>=u3#@I3Qv<_!$MtasPjRH2&VFx-Y9RJiJ?GQ5}$1nXUTPU
zCyn6yK)twdjZVK09OrOYQd?}6!x9r$%c2k(14)Wo&N*rx=9?&TmCy(n2u|tezxVcK
z$Kbek)WLgTLX*mLDj~Qce$)@3vG{<f%<4RVZlvL2%IepUv)hC at Hd<Qc-UTec`{ww7
zab^dTn7{%@u?EdL%!i4`hB$5DZFyg03RS){z}O2`V*Z7(r^CPbk!QMO=U^8any%dF
z3}n)v2ofttW|u=|)8xXqFDxXgIAzkBO~hwhvu6WotatX!L+L2TcrvFxNbv~2ac&#a
z>V)a5csKMJD0<tx{c6etU8REX9Zn at I&vx5xx%iC+sP|}nrpTh%Of>#}75Y&h)Ts7K
zfZ<9&cdLrg%}jpgiaC-s)WolP-{#^3cc^Ga_}!Y$K3GzJ$ENWBlxQv`ZkCu_J8nsF
zKc%kD;ffKnf{2!YqoEe;gF&cO?$>s+rv^ps#_9X|Wit-nLooo58^7wWi~4h{%=n~x
zuhNP1QtT9zeJxcu+U{uxL5P}4OR>Z#K=ElhOKZOlU&H1V`XrQ;0o1ZPVsg9X6C-FF
z^13s`c#^6+rjKRoze{~QC*MO*-m{y-p0C7H4c)Zkn7*2F?=Lhp>SgPkC?(x}0QYcP
z{A at h>l#Q{#DtQBcoO9AKL;6gT3=mzt*#AD<^RGoUzIjA!jI<mFB_r?mxp`MNPyIGr
zFMUxU8sJcWemz{ftaa*FK)^h~s21lq_^H5;7xo7V at nv;zGrIV+N4b?FSo5m?j{reH
zvkx4i1pGo%3G{*Yn#3Y+B3T}|S6J*aAx&oz^hAbNE7;EfSs<1~u89traspng)*wSy
z_?^s+V&D=17QtXKsls?7eMQy#Z4d2di#1}zpY-DDsEeDmKENi6Mym_(S4h)G06MMb
z_)*pH<aI!PtOG756Q_4E^@<LD)K2+Uu3DXS#`H(a>6KA4zy|Nr=BQ7?I#TlmtTWh|
zut)G~6++kYF)thNEu#-_N?M$v7KW6GE7O at rwo)-=zGFlWOAYKm$gk;_RnNkBOMJV9
zv;9>jw3^N(_OI)11A8zG?Ba_!YOALlY^d4i4ZN5UYkrLie<$1RjS8LJe;6u7-bPsf
zkshRGwSYCBoK%?5I+$BiDZ6RLoaU0k*pzfviMP6IJ at cLB8z`t%a<8)3-SB4%#UT*3
z#<evX<SW$Lyjg#0o{RYEM_bzEG#(t40M^VQg|7mmagigUfhRdlARhK&k8`F?oA={X
zY`5?19mRy?R1|5*m~@m$$-%z#(LBfi&5hofI^TX%<AzVz2K`W6?8~#7R&pX)_)zvS
z<(qkco^Hp#i8^bq{V5RIU(PQw1h#1R*Hu<fuyn}S={OMBpJ}8Kj&j-mC|V?}ImD^0
zEPMQ at nWp_YoQUu@;eC8N3hX^5vu7sMY93S;d=aj6F?RNV-CH;G{O_><5F8Kxh4mlp
zU)+1Hno(PA5fQ-7Z9Z4*MRIoPn)^L>`rjt3=&W_`dIjs>1%yqKDaIF={SQPH6%}z+
zmG#Y!ZV>-+&NoLv^3P`vm&|x8=<+4R3WZ+r61{WEI$Dl8O+PjcS3a%cI*O7gzsZ9~
z>hY|Uo&kb&$K!AUz%3WCSo*mC0tW~1B-s_Zac+QsWW}d?41C~9Gr&m8K?N920GHW2
znBL1Khnf(luCeP58Q?U4?x?l_Y%rJsv%cz|fXbkcf4MpC60e`}fv~b1_VT6IDhT5W
z_5R(qh|l at t>ND{0`6h)3{w{zPnC6%;DNF-j#a(@lz7yy9ZEjm^?J?U!<FQegNAu1V
zs;I|j%g=L^2=yfviVIR1rnA at E>#k}!vL;+Ber`@c=~36WHh}OZ at 6ROJs=pa3bIW}K
z<I8^~5weeiWs5%5Rao(Nf5opANYndk>Q;-pNg=pq14>ja9(F{i)51l38jLYj%eMXi
zspc^ZwdX99A(AzGKVCBu3P&3^mk7{Q$dir`C#+0nssyPZihnMS&G2vcEkY`z-*y|Q
zO!SOjTWxXYkq?k!xDUE(uF7IuaRUAD!M9vw^!^HNoS-W66MA4ta~qrh_&a4*Ut*_r
z9wJI=_kZgOAVd3O_SnK&dkVGQbCrW78;ZYXn({|K7e=yL%X at 7ERXppTYfs`nUI7c6
zeD;6CPNyk$vbzAv-R0B?ZqYcr^@yXUr!cnI>U-bYp|7w>Z7sb%kzH<gux!;_yfZGz
zaH{{L!hxh}$2 at L=j^xmj?>*~bR8|N+-v18WZ0*paa at u3Dw1|;|bL^To=Hx5jKYS3z
zw%g$fqY<s+S#)cl?zUXL at kI1!*#3?{H>+Hd468fceHjgxRq|_y`Sq2KeXGp;Ca9-x
zL-&E1av30ETF`Z`03OS$RZT#yUVnQ~FkmX*mbY1|Ii350RQ?xApBD+dY{i at zgv7pY
ztnbKYQ!;KkW=pG_=8r4i4wCz#F9+Pp{D{4JZ+g%^r>`wN0k&X_(1lb0J9p4~?Q8L)
zEkJXA==<C9L&>U2s8jtRBOW0OyF-)}kg%AC6)EIiz7F#)PZ#@|#OR?S6yhM$^wgNd
zfM#bzp&vwH$qCf%m=(p*^O?4>x!kB0VS_QM!NEP-gI6(8A1{*Mw^I;5qowuhB*OYi
zK3B|?y^DJFTuX%?3f)f-xBot9C(9^FiKfv!9QMGTR=R$Mw+4dc8Jnr>H|rG~D>imC
zzPZOqYKw3e9pA#0k2k4%?dxG$tel3rpCeYY-pCG~C!2VRuXWc-<$dkTu8M*=3Fg}c
z%zet%+FP#FYP%Hh>j}f(F@)^bEx*}_0#$um{T975l(ChYhT2Q)pq^8e{P>1aqWoR&
zdhfjSgu%Brva?neCGPR}>tV89FfucyN2?ka?B<K}5z4I;axiX|xS;i9&y at m;fUc#Z
zyE%)u*Fn+R?bVm&q$+Y%V`P+u1rp2Zue~UUFz&9>(uCF>YzA8|PrDSBAEXO59wSc8
z_sYG)eaddE3m_`(#=+wvxV at 6E-$EB_>ZZ2SmroKv05M`lu<DMiuBcc#lwTK!G%GJP
z1`K+5<*R at 8@@bR$z)FI%6uPM*h6YPD_YpKTz_4Ve6mZuG&rI1n#B?apjbB}faXMc!
zT~F8H^3ib8j)BD94)}J{9RMb+XDE5ROsO+19hgH8yaqO0i0OuVhHD`kA(gBufGECs
zk60~n1gr?Z$y@```2#^jwbwK=fklb*8K>6l{=$oss*9jM22S(vIN{7)CQn=RevM95
zJ(Jg`{jmnhBg3M3qkCVXDKgtYtUvyl?#zFKS+^ro-V3oUeS<$RA1gL|wNKfYP)^oF
zOuzLT5)+{A$Ol-83jZefqPdDWfc$Op`$l(Un;LUJVcqy~k{!#8J7r2s?dGJ`Ti>n*
zhNF&xza`6#PiK)^=Kj1 at 8wL#*1XH*1My{EmHkuPq4D_Y{V-w1LtOvFF_T=1%v1Yk=
z(!~~qr--V>-Mj;{*-F<Bns5Fh;TDbLohUmx>-Y=%2)7}Wv=0~Q&-%c78JgUlVZd59
z+ct21kvUU#>h+4u0sYT$$+K)cAW*?kH&=3sS!g$KK5ObLV*Iafv!%smI7|1>xw@#B
zw*3n2GDA=!k at pX<p`%Nqc|Qos0i`yF`;P~@_1xYgoUWm1Du&D<6a*v`zRlE1U8b4h
zsas|1NA(*sD3vxV_(C~UOSIyJm+k|Y+{#xD!RnQCG6fs=zcG2HCW>uG1%IaOvrnBG
zURvU>>7e*)Mcc}ZO+OkV>_Y_`?}jE7MU#(KLRa2?k(FsWb(Wb)V-lG{fegpl{DL1q
zZow}D6WU8l|B_D`gzzNOHhtgawA&8uo7ApXEJ@&dvG3o%m#HyEXwwM;uS(h25Mhy4
zb~T<~el32i62Jg4BLD6WKVbalxT2iOYa0q?62X-CF(Lt7cQrEoJKo^_>1#-Xr}5(@
z$Pb0JpTjTD0Z<jL5|cGhfdNDedaR!p3Ay8s3ULE0I1N?F`RPqK^>qM3-q8()Uz*>l
z7P_0|;gfd|RoR{H8qM6Gu6_%<{=Ll_GoJ~qozMGS*S89sNgrSwY$+KD9GRu`7uorT
zLBATBz)z%x>vgNH4S^mWZqkU-fE2h342wa~^NsNIuDR%_9*av5sIy3d#SOlciOa(g
zE7x){jUI`=E}eledTq}!at*n&l8w{YYhhiup{STf<2S!7!P3Z{;^lAUI#C4qVrwJa
zR%#IZzW$$Vb&YNOc4q83WM2-t%)B&`s-skMz;j5R#5D9f!P=m;1{_{tj&8%k=@@=S
zN}A_Tni`d_oZ at K{$Y-SyG at F{An%;#S$P|3Sw(lXX{>@LAN%{UyQ}T@~2q+GR$}g6z
z--#j+%PO34-{<mgW^W(h>WwuHz at W-UH(_mT)C}DDggVx*LQ*zpmCbBRt|>gL#G%Bm
z-1(QM0K{*UWOCC*f+GBVpK;lYpo&*fFT0(OZPfg~z*TC>0x8-V-B-Z=R;PicUbV3n
ze)-VeS>*GSHW at tiKAEE4+X0Di>#!10l)3`TggjD5y`?)T^K~h*-$YY)j!6}l=LgN(
z at 7ezzEH^xv9DG)bF at cztzD={;J}!7}85UC3*FQP>s`*yzWPgayz>R6U at HLP_!tZo+
z+QvCbf}hH2Q&HG?;`T08Gry{#ArQPO_W?k0Judq^`!5T|^H(Q*%o+&8zT;MZC`e=n
zYXfe)pJQ(Us&S4J_7cfrC(8o3z at jex&4vwhpRicZrzf{pALb5aP>-y|XOUR116~i&
zRUGHjb*K|Z!39vgkD;+$z>_IB8H0c4&oj9e=o9s{A1z}tizjbtOpm}0D$dzogEMy$
zQi-=M|L+C(PqlHORy-{IB(0?7p0SSK<Zz#nT(7H7Sw;hHShajPbW1=$Z*0S~ru29I
z3 at C)veV`&JcOVk8JJy}LpmpdC>e;-Vup}VHR5F>k{nTST*{S_iQ!ZBc=kj!y1$1RQ
zyTdj&&_(JiI5Fjch?HjO at bZV*O!+Y_M9F?+<ZDj4O8XkArqayZ?u87_%Cu*Yn7rMh
zYsS#;kb7 at rooxFo`byE}I#1bMd7OFoQ49^0ThzEPdkY+t+nD2-N^=ebdOOQ3;lKk^
z^TN+}_v~+J;5~<(k%g|Ixx}e;808*|W?*8F&%U%NeDc%VwL4G=VGYZcH#4H&HFcMj
z02l9ipxqmHT(x76W<eCTX4Va%Of-{A5OzjL7l8;ou$VW%P9iRUWYev at qP~Hake#;7
zN>sh4n~gxRqB;Z2x#v^%*VAVIvwBm?c_2TtBd2c!7b&j9uriuUt*ktFc~5fE4eD#z
z*St5)DP^&0MKzy4imZ|N*O=2;vHALFD4LY!7ThlRd(r3}b at O2Ay~4oIwd%VBDKVlD
zw)~xOD^<9zZcLUGfR79y18_$x$yVE&LB5~?4qKmr3*0h63>OI2U at znoxkD+8`&jnt
z!-Gk=0|TM}?m8u(-PyNdq~d8Gp5mThiR at G35*>6`|54psIUsZM<P2<n1r;E(y{cA0
zxbu{+ at nkC0+=(2y at R%44;iTdBQ)WZ{$rO=#NsIgoOt09M>}pg8hJmqA4gPfNrSnR~
z*|NZ`hLG|T*Um-~6gRO3LVZrc5k7-07L6j>0}nQurRsLm<HZFt=Ehimd at k>E&q$_c
zM;+7Y-QPgJFbe6k)$nr5IQKW+&utvBG2#7gJ2W=r%GCuQ!@sI3uN3cCe$R=#loT{D
z9lD48+2u^zO3}ODo^yAxt!G#@Pd-ley+*&rV1%mrD?W#s9Lyeztz`8A4ZJ6dG*YO;
z(K(&J+rluIO<I9yKY4KqJaueok#IvNA*{`(<ToDNGc8kU3;AB6hx1Y*`qJ(}S2;wF
z%FFxHg=imQis#if<x^B8C{9|FY=Y*YepcbCxl6(+BMq8~r&=0WP}SKx7G?|Sl}Qtk
zU-;LgmpL1?vNJ)E+sli0?Qdnshm@`DSxqhI*V-$Z_dAqHV;Dh9!jnu%#zzDWYI2ve
z{Nzx}&KO^S8oT!X5AQiGM>G)>EoEn-WTyGu<&X3CN0nv;BK<ewSj{mDeg|0%CgVtl
zI(HGVmpQcW_T9<^Th>Z!h3>jrmR|nLlGm=ZvO^}0g`>s(kORc#5H8|d3lJ8hkb|dk
z>_MIq8}i2!L83Dzpc5saVvQ=3=%<Gpg_Dh9S&{yx9wOR^<HePC5aBKN9BT#x<4-I|
z*#nJT|IgsXPAE4El0IXmX66VOUxP)roIj9}86&e#tD4kyMdpNw-pcqQquk}&pR><^
z6SR3v{wnayDTIpj90rFlAlcE85dS>MF^&Pii1-Q6UyG;2Kfo#uMbm!ur37B5Pd~=G
ze)`>e`2`(3Dw(DW;EO?7J>;5gagKI5JA5xVBoTXv+U=!y>bdO>4 at +_9K|_`%+5q9f
zsjQNKfYV*EWmpE;M&?U+&+?+<U7ldX!jFW4*49=hwEvOyQn2*M-ncZ8E`UtWDnt&U
z`_#JJGVFdJDhoNym*APxxbt(X9Bt0(HR^n+xypPqoj%2C<@9$makEe?peNws%eMuU
zqMq5*7|NKz?@2~OEv+Pf(MOt%M_nJo!nHG;j&^s{g(!{^%CH;DdtJ_(@n25lngiWh
zBCcU3%ziyGSWLg4m&f-k(ztnE@^jW;om(Ae{Yod_)QcBp2b|Y*wq5dyjS_Y?gubL|
zzb9b at gmoYC2M1K3;>Q4_NC~(9Y)QW-x{9Dt at Yv(4=lkTjHW-T|$09Ew?LohDn#X!5
z%0y3haPM$;x3-0Itb2srDh++HV&{EBe<<$qa-y|4*8|qdqQ24?71WXJ(_V at Xy^*$k
zVV^F2gH1Nx&pLDPZHe?lFQWO{BmP{mT%t1{Lv9CB&b^C+efM_dWJA`co87Cuq2Qx2
z3I at VexuqU0E4nZ&37oFQTW9dS31QY1azg at aCWw=w1)nNlN>whis@?G<9rG{Mm;ygX
zuo`#Q_F|iQ95uB!G?!n5iMkZ~mpA2YzI;^ch}g_AjhlRHJLpO?ncOtJY<4Hash<`J
z6vG{FAqoRhR;60 at H&YZFfiJR*vePCSQeN8;36Y%r@$ko3t$a%wVq)warp`$<@ab?o
zLc}Z=%*0OTI?)b%T;Xa4pIG4VN#Gyaq|np7M(xN_bZkQewH at 4;jeFF2r at Eo%%YGnN
zMd at 9(SpT;e;_dK0Sb!)a=_QFodLUsk=e7FV#!MXUlic>tpeF+?`W`@krvB|ZT{&Gk
z1-M(m8`+4^&`@aPQD}-I5uA}PD`ierb- at G9QK(A8$3}+LD>BRzA at 9`=XPoJD{QI_k
zKF&(mD5`WLP%RU2XZ8K7HM(?KbskIU4F-r8OafI1Prp}~mQa2JOy?fSVlDs{TPda$
zMOLh}5|0Bn2%187+61&jT076kiy8kkliqyTEEPZH;0?ht8PEpWdjZl6{I^Yahy2I(
zXI^r0xbt6gQ%|m$5jS#b1Yb>5cg;r$p>C0f<ucs(QK(z~Yu9__-{22TG$$&ndVc7b
zBCSx7*s!d71IuUR8Vo)i7Mp4=HBVUxqVRN=4oe8U`Os6DbhK67FmBvo$8A<#ocBG5
zrD1GW*}N?nAbljrp<vq^ai{6eMCbP8gdnAE>Em7piQE#rC3aNM#o!F$j_J2h`AqzQ
zt(5P0kwl|om+o6-8syAP{ddhhxq_jSJpYY9Ui#=?ujYX<2ja~8{>c+c<4OR4Vl6c*
zq#vLFT2%`aloA^6UgqoXH36JLKOduQtyCIq^qST)ygHh{#vi&H-!Nwzg+&0joT&PH
z(cQqkwyL%FeHuO*geKr;rf}cC8Wy~GkvcaEC=ieQxOer#+MV&mf26jz5cQt`zG>&6
z<qbrgm)LnkTCvGW0UWcxYH3X?iflfEv6?dHW*B3*A7(^$<csDKR-%4E^Q^R|0spp8
zdg4Z9w{fAaB2xRH)~)49eP{2g3XiwNYiX~o^0n}WcNUGT+JAXo at T}1lYMBI_U7Ae(
zCEV$@ZY9Y6z{T6Zbhd^TdW`0rNv>&pOU;2<nZX}8mXujKxX-@&kF5m1)^hUYejtUp
z at 2=?0?~?6GjN&;N0i(%7d$jlFOO9H at S_7iBK05|F0;_vP8|H-zNAU5a*u+bw46vdN
zb;Ky1N93 at KP|(AF1oDrndt$lH#5_V~av$~7-T6AL72yl=m?Et6C}^v*{x(^dH!m+Y
zV!Bs-gTArImPP}yspPb&(WK=5H)L>Z_Oj!+we6m&(^ODxz6o(kPF at NvwEm!MUg?$y
zx0IlFj)k28&ySzI9ViYjv+*#QoH$#Rv=q%~9mg!0tP1$e$rXoi*F<OZA-kiK+cSy)
z-w-LXy!qgr at uyxYZsYcYE@t+)(tQ@%93*MkYLBu&klIO0FZcqcO-;&{K=q$jok?KL
zfK3I<R^Wv}1HlVEUYMywo3(iPb11o at ytFCreriq(q~6U-`Exebu{4A}Cj#QSYqU^u
z>i?vW^#K2jgyQ$^1)p2%(nQWSTmgoVdcH9K^30dC#9}-^fYSyjl)AVdv`FXkTm@^h
zZSSbw)JF?Xo*(Juy#E&E*3y*s<k|YUTa(&UX;aVTFCmavAWJqjQMB%;G+ at DGZe-DR
z@!@?H4?k+R*`5Zo8ny9q(W}Oev5i|P?VRkE#;57()qZNC(*a8AA-gHy?XGWEi2gWq
zN4rtcUd(mp-87-*V`3}men3I;B{-D4l*Bpjc<-)IT at mCx{AC(pNV*|ay4RDW0r?K4
zUz!-s^zdf3^>6 at MLCYFRf$~aK_?2)7zjoGrOE+gL8<=j{PR2+yNd>0*^%K2TYhQTx
z+3u?^rUxM11LV*R=`H;EFYg9q*Wn4k_ASeP7;>P<gry{6-4u8YY||_SABjl&b-MP|
z`DtF^^jJ$0O%*Mw6%#2J_s~t{b7>ejx;SeE-xvRgKbm7ju5^apI&c!_vmm}?u5P(<
zi-#wBw8lUH&i|NPIeW_tKla91e4#K9JTGq-yc0mPP%0KqyZ%Yw;SlAblgXM6RhKnG
zSyy-nu9W%PB5v|Y+4Qzl^dBHC<H0T|yN5s^+*I3^w-g8RHk1~~^VtP?pk2S~^&TEU
z%d~G{Sg^wq<*<c>mN<gm6<v2l^lpv9^WgEyi>>d}XJkcp&ek3#WWUJZa;IF?Qwj at U
zDp;xd7>C<j15tK{FlI?fMX9U|0?wV(LZAyPb9xaqtVK`z_<4wAVjDm8#raXE&A0J2
z5XWy$Y4#ip7$~_no7=%_ at qL=;yAC4{I{*6moIzGW-`!e*0xy(q!L7J>cM#Dbikryf
zWA`XXdNnLsEdE0#l3+H=;+Jh-kNeg#aj#DI9Pht~zR%;V95eQkU#WL0+iWc!Iuh%Y
z9VT`MfN`IeoDGu`XIcLar3cd0t~817b=6ghwDP8LQbM`bpX>H-D>Z7G|61r_pLfZf
zVAuw%a)zvacN*yO3RJ-SS9+7JwyTY`&7JD&T^2S!&K*d8K+uF&J_|yk_G+g=tmgZ-
zCvHBO&n)B~sI9HDqo)USZ7(8;RJCF3-Vm-RAYvB;*47eylrU=Zcxp8Y6jhp+y<6ma
ziCL%M$!xq=)?n%ay&KeJ$Ln4De!jUe>5P=!(2;fReyhInA^r`Cprh<wHByPQzM7^2
z*93ak2TFcU%>H=)u%6`)H;Skj&8*Enjxqe_5&5>E045Re05vuQj2jm&m$^mjTsYnk
za3HO8c5=Uj9n?GHJnP)c9vK#fkRHnngfu8}S8ULF!;LW-?u<I69}5a=KE~yAKp0zK
z{CnMt=g#ZZzYtMPnrYDCe-^^g(DThuYhk$dRo&kxCeB7`^l96_*VFHDNT`TBnUM4l
zpT5WEulkorkmZ+f`P_QsR{LVVye6grTbVKDF7a#suSM0+m-fEM!{SoI318Ha9K^QF
zY*BfrKh{71mPJ!2I*e#wSGpG~e%oh&{AX_EB>)fbgB_Jg_jg7 at 8k{m)4VG at -`{B2e
z{V#0&VEw(awNll=p8R+oF=OxhyhJ0L`jVZmb9p1%&zbjb1y7f5vpSEv&`3w$1eE-R
zN6pfKK+n&Nkw?9Q2-ws~*^*E%=t^~@tNMEXlbzf+6<`s_TLaCC0w1PGDpp`{u}-Yw
zK4c|2zxl>W)R&gYwB$NEBc=e?7~U}?8!^Tvp{|w9!A2J4HvrrOJHRETXuV{oJ^b_q
zdHT7s6=t8B;>u#pFmM{!8UpF`72*8aC<?NyY?H2f9*0BJ!WNBEvQ5l$0+$Y_{8lSE
ze-s4gCHzNPZf~XH!iqrC?ah2wB;4BdI$3jNRmL|yYlX`zlAnj3Oy6Yo1mc9<WRki=
z0zxf<YddNirRM?+D{`yC)Le9me$07jCp+x)Uzs at bRQyfN3VH3}xm-u!to3>k3$>CD
zVs~zLUS9>})^G_n-Zo>-SRn_Vj#xET`V2{P{@L3qaZ9??kaTC}Y#`Ea^KpG=zoK-4
zVxT&|gaB71311nY6xZd9GhrP?6e+eQH*Gh;3oz1|sl5DPv_k5V0`Q0HPLoqTyTP5$
z)_0>KXxX{L3um6*eV=CS9=FR=C~<4C<@gc87+^dkkIT1;Jz8|Kh<h}-)s{;MCx8ff
zS#{rn44f()3mcBZTcrz!%jw*~JZ1yj=+S1Tp*H*<kN3KSmzjcVe>vbVJg=A4i942g
zxug2d36M135qNQa_MK<X;s%RHyQf#iJT6ydt$TY-N&7f({R>%L*Nso=`JjmivxS2I
zc`Y6^AWEE1>-^^NDzwJo@*GfY&dQm;(|0P}>Hv^m78mj#fquJ^&1w6$dxMF?H%;bG
zL(kmU#CW(SaP$RD4sM^@ovD7xHT9rUbewH6cu!b~KQpHkdgR=Rp<y+ at E?9{|)<3mH
zo1d5rSomn<e7re}Un9v8V;4B8+O#u$IM0cv3r9Mt4w+?39hYjQf+p*~aCq5^(E>8v
z5B94^20jB{nBgcTq)!wm16Wg?G*Oh81rHYoT+NT^idsBo+iu*ks35}xM$TV>CVc+O
z$GL84d)uyej$OZWC7fZC=g;GSt}lfyjO{thsqT-K(|f*d1mqTuH%ep6cw-B0WYW*f
zzg-DSRKkg|W~4JTISA_htk1|Ej-xcC5WD0weX(o+_F8g={i46B9of#v*oF at I(UlPO
zY7h>tZlj at m6BVy04Q_DOG%xue9S6Qvy!+KrV(|>_TNW|-D()0YgK3EtiV!K$r;#Ce
zk^kz*5 at aq(%3B~FS4Zr+ at 0MwV6wsUdNK-Zxji#>sYye-OVk(Q&^_J%@XPCaho^@<@
zjCvP?Nd;vZ`A+f`DoVpBmM-GjD~gX5F|G)q(x|c!p)6C+KDQkevm}+3i0Y`6TI248
zip>e02zh<8M_&8(PYW-HiC at 9cW^2L*tZ<-VVE>w^43pSB-d9{mDR|m6J8l&Ln at 6#M
zvao_`D*8K)G-f%!e-bzQDhWAGsk`NhH(PFM?bkmb`FRhxyqp2z%{GS3IDj~qb6nuW
z%YijeSoumGrrjyl(}A2~JZYFB*nOD2&~*&dGy8}9OOyXe?yDm72<IJuF}2w+ at b-1r
z*qN+=9LT3aiQ!$wTJx=mp*0X(_r@=e-)zWTR6v&2pI)#o&z=deXwK>LHf4{pD*dDH
z7f>5=bSuB)QM}*mxezfy^g7a6z|ICUzw847d3gLiu-YOA_)FArSBW`Xvgf)rYZTPA
zb-orhb+0_Dzpb;(<D+sN1DQx at b>f$26p1hjSr6%^x@(iqWrcj3TqhO?drvI1P at Xyu
zDUX3$GRNa>s&YPG%9~9TzpaM=`;};?w^MssbFi1`3h-0E%xbnhFw4TayBb-WFrJNZ
z74PL!3|$)SuT>nba6$B8@=8h+!QZafF at 87;VTNOCP@%OquV`6C49&Y$+uBY^&o~aM
z8C at wjosbg9Gv)pI(KPTA^W3Im-C5C_Lg^&@6S~xj$8&Eg8nzr9Ftocb9Vao5bgft0
z)9G_I<Ys8K2BU*cS{|ggVFQ;OKh{D0C3ZyPq(fUGgPH;-h{_ywA!HR7!UfD_3-5C_
zxB7hgdbdSJ9JPD+Cg&reTfenWoeQvJ7VPzos85~an;QqW*p(RsSmt+FOSrO~Ug4Hx
zZ8H<3u(ht8DQ6I>sxfg1y=EnR9d6-8r3?5H{JHjHjt4rw$+3FupF*CYnYKsfa~3-M
zY_YjRb~CWjhB;k-Ole?_z*kTffJaU`Vnwnywg60lkU|uXO*llJ?K=?ESe6WHlP at +|
zy8USD=eHE^fyi6tSY~Ip2w+ut{?PqC(b=I5`dH)(hVmtdSgl<38lAtj{PC=U9}|p(
z&6X#>gSh5?{5#wZ`~#E=LkO|@xRlV#$a-;O!-Y~`)Lsna#EHLpCFF?UCnKS4hMynI
z6m>fTpjJ;WDq?z<?gv~-j-7SbNyvp5WEie=grHp5y&S6MQ1BV#7rK7PVPounG*KmN
zmJL?u2p0*6?H~g@(vv?==l%Dk7F(fv1_MM1o}HSb+Ym=|0Ub0zrGJpx=G~k7GE|_I
z)k?%AKKK*5Z8DO_anaVo0a1Yd=&6RMD%vd|cfuVT<{CkTSVYKQ!1ia-5T7N-yHhF`
znG0pA6&N53fAPNhf}332UUftA at Wk(Tt&4vD^XAC7ztamSFN9}FY$;_?;-$28aC%F@
zUb~CB9Y0hCpfF)xlXDGRZ|7~;V#VWNZvHUI=6}s|xi){MRJ8srpbBXn#{1a>J)^to
zR&C!?liL~bRSP6KK|;F5mGK`C-Es{xCdB)}ubYn?N19!SM#d2dMSiXF!{zVLo*%TX
zyEUyM?iKwGX*_PfoP{g>t1<9EWDc~twDP>FN^~sDABN2g<IAm;7vtdb6Qih&8a;qY
zynZxumv@)8zLt<JxUj)rb1F*N;`GxcGWtv*rb-)#0$EA{uJQ?amLYqbFYd_^D{<aQ
z5$HJhC;GsMYQtqfUw|3IM?9PxpMShU2lQp*>EnH1*wM*|=W6_z9w&h2suRS%j(|pI
za{;9aML(a9#;M&AP_mQ?wiMD7BZ4vxPu-gGN+Uzmv)X~GgycOnn5B*WLp(m;={(;l
zYwC&qb*^_~WVryS+~|nK2WjnUYm&^tn|3#~fohy}M?TJ6?u>iM4qDc4F&_D%6gv0a
zDGE*Bqf$iIcSZielt44O&M at kmS><9_{UyhhP13f%RYu+psOHsz+H+p_w7NMIULJRM
zNxYF^JDjYgEvniu=sk!Yd+0!q`Dpri`bHyHdrs?V38FwAci%E1 at g-4DOj>2oSnMHP
zN7k(O6cWV!CG$jKrs4j>@|>=0sx0GjNqn6|?x(g%irZ)slO!V~qX`bA&Ft18+ppL&
zh7NCJeRsT6<SU%<6#0PjTK&Qz?FhMQ#<Z(x;!?LY56O;Fw+wmox_i#BwYFnuG!`uF
z8dN<arCX>mZ2#Q at j-me1>ZuuhW`)}G$L)xw^1nZK&!`aFaa%2`OW$$U6W>mwz5#Yz
zS{7$CL5HFtG{c_C#trbE3I-y0zOXwYQHdr5#PqDRsZclkvP?D?#^7FDg07OLu79ra
zHEfPWc&(qy?ADl*$olfuD(tyquSdVkl`LT%vK4l_#Px9(iAT!i14Tj~QPQizP>>*s
z-V1c3pX&AqY0MTRPsnN#+U?+{QcIJ<v%teL9p7%#S=H3T(_OLE#{zc(RE-0-%&hN9
zC?Ky|+5%HKyePKxh_-TH8azkd<%0l+rsZbz5xE(4#2*$7!Ec&Vbz5^(O_w?VF%bT!
z_}zhfM4{wK)|WLUO%6GmsbPv5J_CuB=8}zA`y;!Xrbn&z2?A67gccKEnv?x&=#SJH
zpy3j<Mc_B?W&<#<l{}z}S94jeb9 at o|Dg-dsi4hhRl+ at v)h$~af`d9_{;ImN&ucfdg
zjBC?R2+Qz at ff`lD;=n@=3S9wz{PrEAp;>E2><rH{s=NHxUhGoosm6Eb)2|V`)hxmJ
z3uF*~+NyY_bTrEJrgNa~6*@vvY0;5HNc?$w|MhTT85<5N!bn4!d-<*PDeJ<a97oSK
zjqlci0)!jEPRP{%9{fPGqx8+M*9rC<-AD7UZ;|wq?Iz00AA2DMA6xXH`)Y1X-CLrP
zN5`Z)`Sa)>5y@#ZDsifgBW;X_*be3O*JDOhhDTN1W_8y^v at l<xi{<fwK0g2zdOQ*i
zV+F3Rq4b+fWy{1%Xz}%Aw??8D4=<LBZ6>*iY3Z7do=(k;tNb at BFG9x1rvmy%%Zm!z
zyb~a9<01Zu(ikJcOnq?U6kN1S*B?xcQ6#0a#yA#Ghi5Bdyqg86y(=LY+I}9|0!3zB
z70F#^(QQ8o7r)e8*)H}yoq`Y;&D8caez(q40qdqWkYFP0X;L2xa^|}yl-g&YqUr8k
z;)45A-PngqkMwbr(^P#{RkM=gEn_S9h(AesKp^!-(m)3wCYbE4RJ^YBD=DXX2Pt=E
zp%W^RG7uq7^gbSJIJ4BX*J6)>M8e%+N4rv2fDfEMPo8hKzj32Km%pj+X&faGi6kdf
z$b$UiwYOTr1)!4K<$;m%- at 3&5ime+ty2Zfo8h2Rkq)u`g-ZBpyQgA&Kw3Tjky_=oh
zE>-`adm=>33$<rIdnU#e5N2*4FqzIytNz<7CC;_3T=dL3pGM`>IH<Z}1a`4&lxMVX
z4{SEGHZ0k~k>%KSWUCxo`^xC<FV>QiF>ptCGWgE+N{FW?Q<TUMOVbPaKD^W>pYJIo
zN#g`HTbr}A%zei-(Lr3atF8u^_EeVz{{Zx=ap4r{L?GeEM1Vt-HiA5%)8igdo17f3
zy174ZGNEp?QcxZ!buKN~AZ~xCHQ24g&t2bmRM%A`Ra)od&fTDDDkv=`3h|z?E&*!V
z?b>paj9AQ_=0=4~_<_jBdB2}sa$D_Ejm7+}S6H^Q;~+7(OK*5Ua89HRz67`6!Pk3s
zcGmaCH|i||vG(JsjmXpRM$olo2p+M$R`AV~slkodHMytAs9eCnGeULN=MPrgD>0iz
zo~k9(DlXo}YURe=){5O-EQgkOYHGb=eGjk7qLbJk;NX^e>g}D|)$^@<@V~M=SW~*n
zf8;q=e4Rnj5RkH&LS_jD5xrNky$8nn?3l7Z76u>K=j9X1u`894f@|?D6!>*$-krg$
zy`G9kniNL?Ko_1gU(w_+IA0oTak1EmQd)k0-)W3olJAYPSi0RU;=HV+pWGbM>36ca
zx|-(R!ag0nlJXTaPQgDRoK*fb<Hwx$1}l;M9sluN;zQcm#1-q?=-+)`-``TUewg0W
zGY<^>l$R_g+khpEzK;H6^hv*&T_1Su1p)szYsf|SGCvR5Ydn!ds!2LbZp$(Sqi5*J
z-=ESR<*{Zj(8^ZROqqO)1fPb4i<zMg-z_>@82_77{2S>HFEO*Vqq}z!?l%4U&Si<r
z(qopP-Fm2z<?foA%hR0PXfctjija~U^iE<d_Itp7>*3NJ1T$ms(3FCrV*4=wNPU2l
zba?^}+z#{Ve66P6Zms<epW5<)ppPI`BjIlP8cE`ORQil|8E^*MfAf`XT8lgW!|DH#
z-wnk!WMiS&%+hcD>Oq%zWMTjJ0^mmHzMLMBs)S({r|8~Y>)8rdkKNYm6NB|~yk!Dc
zblb43#I6bIeZu>o6|xq)m%OB2l!Bm{iMmkJ%BHAyS<mt*PRwbRnadqg)T>sye8eM(
zDkSoUsh3^lG?g_`llFXNv=FJh7)gW;RwRrj{uec#?u+r?t3I$r><L$x#*(v>Cxm)T
z4XrJR|J1zEDu|j+K30f_SE$J-d!w7UO9OuE*wdJearW?#?SYg09ba$eu at +XqnmrXB
z?C{M;?~zk6(|ga4);9cwdbq-J%WO{9>hF*iiq0xq&d9xT`g8p at 1r}OGePA-PX2MNm
z68rBn`ub=HAC&bjTW3nKh_2*T!+_3`-K7S#yGJh at z4)y5sDJZp`<mQKR%g}f;d8=(
zNOEk*8AZSGfSMWss#Y4GD5&cZ5JoKP=#`-Np%1Jppb(`Ta`KxV$sS|f1BS8eBrhyP
zv>fiGY4e)L89wE$Zp<m|5m&4N0(E9_-Wmk2J&#+&YCJGGO51GST3$S<H9Q7pv@%CW
zM<!2(mAraOBnmuNK_b8HxuaBKAi|+mqQNgHcw;_gm6aDWycDY&wk#zr-<j_-twg6K
zy-B21YJSR2A3)*$3LR&ucc;oIDq~ncmgcM21T^Me^~#y~{rbte7RNL#4sN!f)2oi<
zr+3;JwTH0hzspX%33`_UQ8-A`a|Sc&M5-BiQEc<<W#2Huk(CBRcWB0Ei#XSNxRo-a
zFSOjUEZQ(jCh-loonARwa5^*%4o~n5t{OJGiKZp2tk@{#P-{m~r(2Q^E+<t~*Qc#e
zVk`Q|XUAj7{;pupKI5uD_$>iC3!2I;P_5C%fA;IUy88Vam-oT>{FF)L8T;8Q6I!1e
zHWg#9L|PD$dyC&(70TSqxb9%`M1723)FJP_61vSBSiNI<$379duXd$v%o$ND-hDw{
z^r{kWX-zpjJ#{)rRrrq at Ck=bg!rb<!{IXiceIlyryAM~TN!Ip5BQ(F+j<l?W7#8<s
zr~EgWC9jc(98Z1yG+2s=_%@RS->lw$Mi74Pwj>8eupd}U!XJg9V{aswxPFuHRX2F2
zE20hv4&}kXTjdz;)hx__{1GI*WS1yoVf)Bv+zosMDF%7oYmvyNB at 4C}xnw<9*_1~f
zCgY;fmL#As+9|to3u6LcnZ02^xbWl+p>?2uxeS=f%896pY!^kZB$SzpWgB~#>#W&d
zhre~7`O<!J5}l>a0j)Jh(XJim9pxbJUn at rZhhK-Y>WiHLBtq_)1(o=&;#hy$GN1B@
z4L7}ma`AO0{w!a;a_zE*o|iYTU;W`GRRlYqE_$9KIv!^oLy)e!reOKs7=?3B^L|OA
z*NQcD0EY|swd3jb(fNam{RduvvoUA%rolz9{hD6fUihQBBiCQES8(Aq?RTvsM6*Xn
zYj?K88(+;lM5)wYd}45H+<5Fyjtu2Nm5w}lmmQ|*?Qqu;JKP!%zAsHX9Go*(Uwf(h
z{f&1#NwxJiE_rl7KN|*=@e<UErXKJo0*8KFx)t+~`9hI~@z>s24!}Vk(q4HzwID0K
z)~Gq2-GKMU8B9d<f6HUV4LL7O&pMc7f4toHlDaHnc6;b5@<#n&3Tf%uh)U)aQ0oIU
zkAo_67XAeeQP}WBd?k at n%Y*Ev)u)pLJA2q6gswOI)=`PwuV5#PyV<CTnE-Ndl_kgX
z+IKCkWUIN|PjmCNU9}b9;?35ojSi4I_^LZ%i5(ijSTry^B0Os)z9H8*zBOTal;@k7
zT>@?@&kljcR)8}IG(X{~R=4_71i)F8dHHQ1T^R4;^ST3^RyIkC;vR8Au6%IuRyVlP
zg+^GrivhX2;_uh`2BK5n_#%_Z<~W(w#_W%DLyk8PA)@_w?&?<n;T7?y8Jmv#w!?Q&
zcTMK!^0hzOfFku&rW5){!|^%3eZ?hbm=^iWdEUrcV{r{+<#ur$IEXu_Mm!;3UCzxX
z3a7tx`-3xlY^Y=Q){!lWHzX7gJDo^xA+Ei@%bf~Gv%t^3GiDIvn1){!^EBDo+d5>_
z4yubWHKwvEh~36XPx3^9sPJnSt5LV^bHR1cG_OPxy3MnGvi at f0$mq-J-L*&Tw at uwV
z{G*tf)#kRps)LrsW4Fu&(_9CKljbA7-FCi+&KOWLVO^{(ihZxC!DS1+f3Ih{e_FAu
z#$<UqJeK?_{A$7V<h<E87Cfx6NZTw$ZJv{D-HP2AtOIG*30Jb@`i*+$oD|;IfeWOv
zIBIz}*s!2h?UZ}jnB3qN)b(O#A$LXf6%Y4moqLr8yN>a8?0PzMLx1P_;SO1K#%$u+
zif}^s^E5 at 2j(^#-YZJO8t6l1zQ$<WjAx~ljyU at Z`?z2r<S_-_=*Kr}2YSjjDWoE>>
znv<oe6(OCOJAPKOyS{tbbrICqu06<bT9^stop$=va0$kdKIR0&kU=^udK=W0TOpM<
znuc`r+U2FjOm`=wL&p2fxE*>C{bjV_y<>p3CBgi<U%BE9LfMGtdz*xqhXtZkzS~bt
zb15jJK4I=d$yxLnq$b?yJR2Qv7rrC^A!tQ_0tGCD*^O*XOo(r5mG*+O{gykOnr>d_
z8by35ovBvK#b$&8cMthT6O{)VY-<^%7UoORv at OlVBj+~$J5?vhXuASPxx?6_W|UDj
zbjdC_<%tA`c^+z$Q*8OahIbH8hUi8_-jVrX44{xAQBGB>@is4yziVZE4QdEmQ9__n
zz|kkb#_F)s4E4BKNTLw<2`Rw{hXdA3$E#0*F(c(EPd2*0<zA{6zQ9LJrB6iOVr1U*
z{a2{`vng=HI4O!5R at Cc{eevxal<r2U{MT}qzKFmv22(s^^i!wO=;fpPB_&SnqZZn}
z$xu}B(EZb0Zuxo5+LmYRO^!BXl*gD=-uJF3_x91cvFiC1w-3&1I|!+tNoT|-KPeSa
zx&9cV{Z;o at 6}P+7ZVI8ymdabb&`D$Mzm)v3Mkmv^^&Qr(DD6Iyl{&1bZCs8$Tb!54
zut_NwHC=e!>?G&Wbm`8po*Z3nrQ~@te7OZO_zZZzx3;~F=ys2`n0`<wGi!(y4a*8k
zd<Y~c)vEqIKR at 3;CQp{&8s!bo{AupuW%sx_5gnCjobJzRuV!wy<-3nZbb_E+?*Tds
zjqi5HU1ksJ&+L1upW5trXAY~l`_79;X^fcL5o=8CeJ^ub4<Z{1F>^D9hmHfn>o(f^
z{mu^SV^QeqI-A8h;UCZ3tZ1;6m5u{PFAjEZP{z>-P+yNdCW=T*w{*122tX at XQ0l0;
zAD5eVCi>gs-wT)t{M;+4rvhO9lIpl;cH=s10`KTWKKFsCL~%7C^4ifdw{`&qF&q+b
zUM1Y&*BIf4naK3kKvxcBMnfcPn%_XkB%oCycRZJ<A`=4`W3;nl0D4#&!~3NmLMvCt
zk6x6I#-=-<J>1Zgmx_jD3a<Z%+iNVP;TA4+)OW8 at 1b7IQxD@ZG{N6b&D+?>G{(pN#
zF at HxWGajtQA2!NL3}qMai-0_!cAt7{0RgR7$s8UC9Pz3b4l#V2-UD at V64;9hDOZB2
ze1sj%$Js1&kNz-TK!wTxPS>K-luGl&b)|(yuukORy)Nm6M4$5PDsv6S=rB%jx_@!)
zh2yK252i0y97xl9k3p-Gj{p4mGg3L>-a0*q97QA=!t|MJzhchx<%@S!I)8_Md=w-u
zH at 5TZjMRSZ3EY}qoZ*S!D-WZ6>0m(>5xa?Oe6B5ghcA@*^0khZO8hgADUs8EK?v5I
zC)C%%p=IGjgE%ICf$LX?_Jt>Xc;ZEkt>zjE!LOTarvt$P4?K95Ae_&Nv*((O2Qf5Q
zQi+eQ=2A9V8VzII(SxSFIpb1PiIX7~f#U^6VRj0yL~bsc?}r4WexwhGgCwo7Yq&<Z
ze)?)>d}^C>2KwC&ap=vSjuhXi6{M(|Z9P-PDE}v$&TeY8pN*I)eTt<mQE5Gp4EWQi
z<=|xox7^W?1Zj8t=7GeH`*lUvp|n(>cbV2}Z>|s7 at kJzGHm$+SA8_NaqsvcMJ`j;H
zlhOyJ6;+<rP}OnOvR{}8R%AVgC5I^uiX3Yrh242}aFsc{T|%>nnaIRwN?m+b^G<c#
zdoYQaSlm|9)N^k;>i|KA+zpI|n78kKHP^IdZm&21q at o1Vn-tm!fTgCQg#}q$=u#CM
zGP4$MZ&NU`1`>JGGB$f$^XvFEgzr9ojm{V_19CHoddwgUd$hu1;(^T{8p<X8eht}n
zebG7W21JxZ2<U^$re0r|iBI2llGoiG=lO);zsgG2 at H-18ZGT)RS{>6G<;3_KMwQvt
z-r30Q63{`h^FrUtIReOx;ttNgZ)NK~Q6VttR2yL(>AO2b?AcBW5%9=1c5``bPu}Sk
z6e04;V at r4pi(Uj*AgTSOn_7+?7ZIJ}zYIYWx3j~qcaD$lc6aDDoYtp}=c{^LsH8^a
z9eLy$FP6R!LI>u=s62Iv+Kp31j=(tbKyNW00~iCv;2Vlh1e<SAeEHF=$1o(lETZN{
zQ7LV8#pL)S2E@!ZOt at mD>ZyvUH9Bk$*@P3NuGHLdMhtAnDgIZcjv&U?j<w7`o3E#Q
zd0KOjT;ICXJ<|mBi_m-5pp`!ZSN0m8diMzJQ}()a%r(&f7PQ-mH#ZJ%K$NH@&-$Hy
zkVk)f!3 at 3;Bz~^1W#1<C&J>|;-=`?#EqR{CRG+qN{a#L5Oo=?=_B?&`OV%UDp6Z=y
zP)e)kf~T3sUNmI0$2D$DAN*4!p^o&J!+wA{sqK1i)`*Iw%up9%3&nt}ck(%HNmQ-K
zz~U7FUqmvP!2nn>PPb^vyChNJxp&msuSA0!2{f$jI}@sQkLa8_l}|V0KL`Yzed)Ga
zvKxV$^7YaB;@uLu_l$1d2a1xiR}TOUoQL)ua5{<r#Fw%DyA9xrA1b<02~@lRM>nR0
zA;QoL4WMp5)tvGwhn*aWragM=cC`4qca#rh=a3y6_njnt%e)XhxNM(-&9T&=Yp!AR
z(0Ah)>3i7aKvAle!aLHxE~U~^J%bWP{>V%oBRp)~%>-rLag4xHVjuLb>fj|gosnlJ
zwJSg$qnYPlE-zK$wVo!M6yhn-$Pm-P1%D!KPg=nK8o7jYdn&e(jS<Z{A>rSYW_eQ0
zUz&@Pe6?z~v9aGQ`e>TjCel7GEO{cU(t?Inril{ZPDSNXum5XrXWzi$91W=D;LlRZ
zVYrH!o*Q-JYA_4Ma$9_$5!MVL=DN7|Q*K=oT-LT+*-mC?3T=#EZbu;(H2NVlxkLLd
zmlj<JV at BRX|Dl3*0WMzm%kD8_XS6?;atJ9#H_Okiz at 9c;lsH!(L5Y!DSow-?%qh at 4
zO?RC!{(P`TBofU+)vewMBP)%c?z_5wUB>i~9VbIbFp&oJMpo)aiBhm7M+NxoQM=m)
zL2mswxuuUI13qzfK}HR-l!?xdOQ|E(lQliLQbXPg+^>uRA?w+y#|t77_dZl)z|wvL
z_y1YzqB5CCPvag!DhC+2<Ij8sN- at A!Y6#Z^;uhLX*W&vNVfXR=4~P#x9?>hTf;4ZT
zR(5NE3GQmP+*MC8dZfSYw=voE5Yp;vh!$Tn&1FJNfz@<Buxa5#c&4pe!-oYPtRGwS
z*~~<tG(3lq_R<m;IK0dqJ4YDXEAiU|gogcw>-33UePHcf?Q+dKDbE1&&ZBp|=na_^
z$BloRC{$AB52^%v)aT5bui4JAIQFc12D8aAZRQ(fB*FP|va>7eN5+_&;Sj-MZ{9V{
z9A~mi7mJS0{{lx8xa;22s*UAugMp1xm9(^EtyHayZ<7q!<5M}@MQUkp0jG`|X1x2X
z^=@>y*2(!qXDQ3KGRVqMWJBE$-+lMpWsOw>zqPgC`R?7jD;bgN;rs8ufAjOtKR at e>
zGWf2Vx92<kv_qVH7yF*|V0e)19_NbVoQbz at -(KnV)yrDqm0 at pVoa?>z*t=d`ygI<j
z3Wfy0Z@>L^Nz9!^VAAb-Y?aEyT=|g)fz=iPnoL`RX9)~}d8ds#J4UHR2 at L_MJq<GM
zf at b$(2lTn-)CPM{S!ML#DcG5YefKDHHwT;@^piF%akUy?VqgMTw;7pOZKRa}H2Lm(
zUIVjo$~AurZXA%QoTy~c{#}i?2W;KBtS;N5xzDoizysa)D~K=iw}W4ccs1gZ11cE=
ze|<h}RMpkTxmulrr7dlTe}4S<@v7oA!m#nc_0++ek|H(z>Hm5rof^`0Skg3L>ra!C
zRSuU#Ea6ddX)ma_Lwr(pU8$gnxmL~l{U*8gVOmvoJ#{up<vprQ1o*rDlXbDxM`MmL
z_QQt{SMP1lz!+5AA^9LU{v)`<?~@=f*>{eJR`!w(Rs~Kb0AehYq2i8?v~ZBFl2&nt
zxYWIM!W|tdyt8^FmhY~^Lr=Iv3EZj`TZ1RuVa4r)JC;mqTyuYae_8Jv;`<uzC~+z2
z>v=Eku%}AWw*yGU9Tpz;_2I*ZD|0XV>?+HYq!V|DBaS^YYq~YCZk~nNyzF!tijzb@
zCQIk1TC at 7%>)n5McXxTg4r9|&xR#BzM6Qo{hlaJGvi%cEVk}APfMNE!FH3i)X3M&-
z*_Y8i0UNbu3Ejj^cc?bLZ}ZkZwRV7QHniz;6*8S^wpo3zyN+F_P1CY?CQaLHvRbpf
z?$4c?@V6;s5Iu~R4A}%OGimv}t|Rrd7u<Fzs?XOZ{Ozx~=}kVUF1VAtPm&ckxxrpJ
zl!Gk=Q=QdhRn@^{GI=Jc3+$b#vo);@>NGvPvy<9?u(i^r?COf00aEul<pxS*eXl0w
zol<Y_hs?6zdA6vX|5C}!oaKzG+ZXQ55;i7eHbW{g5 at 0%LQ9wTsr-r;qv;9g|2<-b&
zepI{uIc6>K($?Q3#OH5f(3v+ at 8D)8uAIV6!nf5e4$?AkM3mI_bp8_HQu=}Kq*H#V3
zRtua2ohM1~-i3pm+pnog!M&}qiPZ%`{2JIDR3~vFh&jcFecxiI7RQo%&WkcmDdB0a
zjWKPwL$^8E=~Xbq9oqDsa7Sk%`Mh1zo>L>J_6$#hf_pCA!X1l8RtaCj9hKtN?X>py
zUQ36azJxoB%MMU=O)uvC at WT(6HRPI8_0X7p3wMZ#9KTS~SqXdl7S~@{C(9*+RxVGt
zW9!*HAnq^*SzYW%4X>}bV{^1#!W}wUIu at h2qju*@2vlp-rhYM6OZAhJu&o%y9ri^w
zhFf_OceJwani3oQ5!}&p;3}Ch(^A&71v*xE8NOx3+9!7KmI1u3H3lDD6m&xBORdY<
z4)Hee?tYve-62-nM1l}yH4AVytXUeh)ZNBgD at +4Ey81Y5w9UT@+}aOoPdZ>Ou(15@
zqH|GM23Ip$X8V+Rw*gs}%IVsc5yzfXf at 8wcfMNEpc2<jQr4}yy+5mbO3iwt*+;FIs
zMBQ{Jn_4yGJrtEORJJHctL3vSnSD5xuU*qN=IVkbb7wQBiTtibo%9;9Eq%9-;N*NW
zGQ$Q=NrfIxTW?#pOMngh>xY=+M=4H+*IBlAO&bebA18O2Jwt7NbzMBM);_-)Mi`&0
z#;khayHW16pC160$+aIqNsc`-&U)FJR-$9?%&lfj6Tv100|@(Fow-#u%_Ol6yE--Q
z=R5>85YU;-!%f2j?enWCFLS6=MuNfQV&LB?^qno#*$2jTf3LC%otfG<X|+%3jE-uH
zPbPobq}CD0IHmiOJs3 at BJNw1+(1c`3w90|b$f<?wiI~}+D`7Ti8Sdz8q9!fk4)KC!
z8g;?jnwClKUKhM+f;14kJtnXe7;ZnBh`fY5>>tqqPuIWh1(WJdb$<<a$ih2pd?bqo
zBUWPUhw;q)9Nf`)hLRSJ9H_0bvOuL{#T}<!pyCeWuJ5a|dXp`2hrQoc&WcH_jtqB<
zX!=sz(caBlxWnYjWW#4!BGam~eMnY2_q{WJ5N~^Kh&v=3_fGcTOSt2f<DLdOi*wJC
z8C^LRAZ1O)D5|Y?u^Mo;k;Z5YT(}_XP~eb8o3|XABqQI6@`CM_EKR^<W7HzsgjXjV
z7o%XZR(<txH$XcWZJTjZTy27?Ro)3CtW at 8iG)Ay)9`-YA!>H+2lV}p+GnWO|^45mp
z_GOH<8GEPkg30fsYP+5~#>nJ3F<loSeaa2&KGOmTXN%}wBP(P at a1x5&e*5jxsJ5SJ
zaH?hP-lqwv!>u~crp&g|sFmiGGWbl_1m0nJK1&&?Het(Fx*si3Z~ZAx()RRZn`>!Z
zazi;)2lkm*w3kCkP63Md?yQI1w{t}VbCb&mm}HZ5S~D><`Pv%3zrVjQeU(UAt?Gp2
z>C9)hsYPlV>pO2_7N`;gYW8~wE5kLZ*gcqR?2M2pw~DS^dJ{=WsU`)T*`VadKbyR?
z;=bQ)BIla-ejLgvP!lw`W+ho<=J$D(9_=hK?s<k;oe*es`gsRE?;TWfWS^15(#{X(
z|8xkhY_8R#4n^L*uIc>Y;o)+=*PO%3z2gZ?7<I>VpUWl}cPJ4wF4o!7^(ryC`%uCv
z?$DyWxWhB}7Va?77UP(NS`l)sNH8c7wx`X+SKOg2SlnTche_>lhvaE-hv&xrZSuR?
zWWR<xIy=yJsZ7$rm`bX3VzZ)Ag8VhyAu+VyF;&veF8jqRwL2vb`<W8iCIJ#@C){D5
zlTLeElNvpVJGMS<;f_56afd&5!X51`l(ZiCH-(GD$@cgOcN7C`UG{8qy$^r3w?^Et
zYrRTlwy8dR_;59u)5K;6z5|d9R)R+#fMx*$$;x$>q1o)?234DH`Cmzm*{=_7n#yLm
zYWR2P4WyU}jw#fY$p%Hs=-Xr-(6X)0Qn4a6&3Ijhlou%J^6>8Lp7ze{9gGc_WY1(l
zAX>u#0gQ4(1K_;PW!?7kHcFca2^JjWwm`Rlpgd*oPe#%A*$vpFp!)K<mYnQXoyabj
z_rO{+@(y~3+YMY;>X*@IbNJrN0=m+PU5_(tlwk>U_wzE_%K4nUY>*ec)bY*owUtVf
z1(Tr>6;>5=vD)4!INUo~FsqDgpRu)kcX#*Z;o;$`6kf|)88XcnwTI!G1dniSh`
ztGl9=>^-xw^3~}}p439!YEKgrW5LIdAK$!t_wI at jc1D2*u at xNMa%{9O11Y$WZPX^#
zgKBGDfbX0nD?z*7#liM18rLR~P&dD4^7#08HSkvVB3=0Q?^=5sKXd{zIh5tLx>om}
z4m(vcX}qzow9a2+=XVw_5j82&gv2=V%{Sj%Dvdho)s|QQ<vq!A8?#oux5s7cV*A`P
zq=PF3CGP*lo87C#z+%HK++p=lDQ(SoiaShHPPjuL*s1Ns9VI%4gPb)|^NJ3*wYRhO
zxf+Yq7~wRS(Cb+|^*Qc3x8EG7soc%p=-NvcckFtGwftRMGmB3<-&D8w&NMnwhG&Jq
zc`hc%oljTX;Tlp7Chn;G(Td**cUXxL?;6h?M&5RZ4y<fXla<`!4oSoHSS~hbdSgt|
zF}6LblLJaf8SjT77sqemjy+Ff=?InKNu|)IK0k4X#EO>HKJ%+&MxF0zs7>cvbk>I#
zRWR}W_us#HczC!f51uR~1+ at ki8=z#<I at qm4l+-NlA<5==7|L3#cf%Jh`!DEJCo5C2
zV75kG7k{<G_7Taf$Os4`4Khm1ERj0RehkLIpBrrDWD}19)0U5YXM*zrRpo_k)>Px#
zBvSUGzq>M+lP<IFGbSu`|2Q3pHUjsZx$zz!A20XNY2v53GM0DSoY{eaf-G4cH at CV}
z<vv{(W1MzfV|I2=Cz-{mans?mONgr3_WK4-y>EfE at uB+IN>>B`CSP at La%PV<l66cw
zxvwZs5Gd%u?}1ghrq56|teSfNuKHu&Stn3;a(68 at ci2`&S7#;VI2{t}8fq^^b@!)P
z5~p|Ap at zyR+*dwdfleKY_I#Cfn9OZ*xzDumNU4I)w)eAlxb?R+?fIlsv(43=lVPvW
zX^3=(1Q(cX-3~OgqURay-V_vj7CB*E7eL8F%_FRQ_nb9u8>1a&DhS`dkC<sf;2taP
zP_`@CP+R7gaEIi?33pgI5_bs1Ob)uIbw_kooAFZORoqeVUEHDM$ltlxCGMytadC&e
zA~ixW&fdZur_mV7+J-y!UNuKhHtkuVoX_`PJAcgxjALR^D{GPr+9QiGJZE(Pd<l0*
z0;<ALj{X|%Sn_8NkfhJ{)z-8IFP_E9A-(Uu-{OvrPI2!ScNAk)#<#WGYOJ5<Kv&mW
zamUVYhkP1qo>?=SRh2pOAZw7krHfQQekzR{C~THgt2|ISu<I1vmaSV|DI3>@Ho>HG
zY4pRdqnK3^89rH0oqA*m)JFSUckl|>YBy-FNL?>vEcN#ms5&9nL*4i3zw316!PbUG
zH>EmfH%R-i>Y}3lzm40<x0HFPf&TdM<ArszCqS30CK&~f9$Y5pb=mO%?W_#f`YI*@
z7x#l&bE_Sb?3oCaVcuHaT5S_=8S%~!@ZP%Dwug2I?mbx<8Ca}SkwJMnYYB)}|7^_f
z?1SCIdfb$5j*;?k-tW@!MQP{L)6-=?S~1neSGkr>U8nh0-9JhX>|fDtc1-gQ3)x=R
z*7l#?{;sWChhjlufzzrrO~z#FOv<gsd$5#w_jf6I-S1kzfPELfa}V{M0ahWbfQ^t^
z<;>>q+1KhcCcD1(zvrVA+9de2rpN3%nOYF9d5ZVvbKco%l|}ci0x$<9njG)5KYsjp
z6%UNj5 at B_Z8hAC?^*lE*vI=U_B#?0aoP?xqa8FN9m;2FrSn|MX|H)9H(sE;~AlQ3T
zsweKy#ZiYyd)i*Y9S%<UoLt at j00mY_L_t&?$iIa<dN1OR#nM&t#T`~h>^HiFJ636E
z-|?x}%!J>)u5pP5M)oe7EDU$_96I3+&#~^Ity|BXlly6#;Kdzcs#Z!Q;VL=Pj@?9h
z&&Kz0!X0ywEWuOUaceN=E!-i&Qd1ohfcC11QFRjC+Ho!EM0y&q>8z=}-~Em{@O6fl
z$>`RmIH-Mc_O2FpSaGzU+BNj7XJ$X}_U+qC<~-n_?4nbL)yr<dS|QnuDi>2$WLdd3
zs4|dl1OvT^gcXJkGpgfIo1;73bQ at BOx|JVSqBSG+FcWN49 at 7caHnJ^2J4p~suv)@*
zc;!h4yFfdD<UE<OJJUnj{O0>Lqu1ZQERE8eF8t~s1tD8=mPuu^OhRQ9WOik+R+ZZN
z>mXRALo%W!$dx*&ORu!h;LwEe?c29kmV^cmWo<T|FNpX~YscK-n{5=`^|)?Vs<%mZ
zzh^(Yy`){OiIV>N`uO`yW&1mKN;#n#Shehy?N3dT%Go-}e!)^p%$3t+3hM@=wQT2{
zbS8`XbPq)vcD?Uv?@cDFxtAq&uYCLMx0l&LnzG!Q5zuMum2qsXjy+S}FaWIFwr+6t
z?>T?OHEmzb_Mg(3&i-+q*FDJlR#7mC=4l9H->a;&_WW7~FX42**n888W)J?Y0W0fP
zi_4bp9I5=&vq{;W?w|X)fk~@U`@DgBi6(8I1vMr@`?KeZeH^-x8TSPAtxVb^z1Sn}
zSVCWOks6HHAZ=x9&(FRdo3&5Qf&%|9#T}lrUxGVoalH!7&Z`sdknmg|r?^8xb7zz@
z?;LNj&#f%Z7$xq|fzZZ#38WM5=o~xOr%t0M+;JKUvc2guv^uLiUV=k_?!L5Ab7~{-
zec!?zjRnIUl5Wa1Pq;(*p_0$f!5t1^6-R2X{H3^~R_L$c4l(VnXH}Se-`=$@dAD#!
zO~6!-Y>)oOfBeUrZ~pq%zyAK`KmYlP;q&3yEU3$j0ZgflENd5jts4dCmiH|m+1y&&
zX9K;Ao`AL%mMw=HX#80jsl5axM at oX+L`s!9!M0Pj9b#n9$;mNI`ICA at S%}&Jx&UNO
zPHrOFYg*3U=2`=@V5)1NPF4mDnVk+|^85O3dJxKz_&disszomYS-U?2q#AJ>C at m$Q
zeEeOzrwO-p7*PghvSs4xfmoJbmenR&4<aR^9{z#^_1R4<+FRB+9ZH5O{iqeH_fU5!
zlkmQC-M3_>WOequEmv#M;2_O<=<nwQ?<T9t&-{B6qyl)q=d>qf<?ZX*;npE(1&r<?
zhfum!wf^jyE;HNrX`*;yD?OlUFWd(1N`{o<3h3I4W{*rA*G|pr?HTbMmt?a#-e+Bl
z(#~0G71802UDGy}TSau=m2EAko;B=%$ey1K<<6UMa=P}vm2}F`pLz}(Gku;*INTpy
z(^|ZaX;&_Es$?58JN!`GA&@=oJFopqa7QI(t}*3LUxGVMvG;VgSxNmI+|k)9ui*~k
zuJ8CI+|iK<;*Rcr6$GCBjY~@)_x%15+|ju at ui*~+V~ab)6ffZpd%`{!cZgZ*Sok@(
zqcVH at f&V*kNB8>)i%6<{3GUEZUiHTx#T_b>T=W0_ at BjYhn}7SafBXF}fBDN*Mc~$#
zAo)wb{*j;k|MK;J=^1?KwbZ at jbAR@K^Pd06 at A}{RnXg~}f7bN>_4WDnz5nya=s$WL
z|C87M-|^Z1+k4=jb^rW-T+{z(jQ*eaJ^xH=+P<EzXTqB+DdgY&_O~~G`t<43o4 at _-
zZ(kqI*RQW%U%$S7ef|3S_4VuP*VnJFUthoeX%hcWpFX|$FITqO at z-8nT>t<807*qo
IM6N<$f~8PYD*ylh
diff --git a/plugins/kimchi/i18n.py b/plugins/kimchi/i18n.py
deleted file mode 100644
index 253f00d..0000000
--- a/plugins/kimchi/i18n.py
+++ /dev/null
@@ -1,335 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gettext
-
-_ = gettext.gettext
-
-
-messages = {
- "KCHAPI0001E": _("Unknown parameter %(value)s"),
-
- "KCHASYNC0003E": _("Timeout of %(seconds)s seconds expired while running task '%(task)s."),
-
- "KCHAUTH0004E": _("User %(user_id)s not found with given LDAP settings."),
-
- "KCHDEVS0001E": _('Unknown "_cap" specified'),
- "KCHDEVS0002E": _('"_passthrough" should be "true" or "false"'),
- "KCHDEVS0003E": _('"_passthrough_affected_by" should be a device name string'),
-
- "KCHDISKS0001E": _("Error while getting block devices. Details: %(err)s"),
- "KCHDISKS0002E": _("Error while getting block device information for %(device)s."),
-
- "KCHDL0001E": _("Unable to find distro file: %(filename)s"),
- "KCHDL0002E": _("Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."),
-
- "KCHISCSI0001E": _("Unable to login to iSCSI host target %(portal)s. Details: %(err)s"),
- "KCHISCSI0002E": _("Unable to login to iSCSI host %(host)s target %(target)s"),
-
- "KCHISO0001E": _("Unable to find ISO file %(filename)s"),
- "KCHISO0002E": _("The ISO file %(filename)s is not bootable"),
- "KCHISO0003E": _("The ISO file %(filename)s does not have a valid El Torito boot record"),
- "KCHISO0004E": _("Invalid El Torito validation entry in ISO %(filename)s"),
- "KCHISO0005E": _("Invalid El Torito boot indicator in ISO %(filename)s"),
- "KCHISO0006E": _("Unexpected volume type for primary volume in ISO %(filename)s"),
- "KCHISO0007E": _("Bad format while reading volume descriptor in ISO %(filename)s"),
- "KCHISO0008E": _("The hypervisor doesn't have permission to use this ISO %(filename)s. "
- "Consider moving it under /var/lib/libvirt, or set the search permission "
- "to file access control lists for '%(user)s' user if possible, or add the "
- "'%(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x 'path_to_iso'."
- "Details: %(err)s" ),
-
- "KCHIMG0001E": _("An error occurred when probing image OS information."),
- "KCHIMG0002E": _("No OS information found in given image."),
- "KCHIMG0003E": _("Unable to read image file %(filename)s"),
- "KCHIMG0004E": _("Image file must be an existing file on system. %(filename)s is not a valid input."),
-
- "KCHVM0001E": _("Virtual machine %(name)s already exists"),
- "KCHVM0002E": _("Virtual machine %(name)s does not exist"),
- "KCHVM0003E": _("Unable to rename virtual machine %(name)s. The name %(new_name)s is already in use or the virtual machine is not powered off."),
- "KCHVM0004E": _("Unable to retrieve screenshot for stopped virtual machine %(name)s"),
- "KCHVM0005E": _("Remote ISO image is not supported by this server."),
- "KCHVM0006E": _("Screenshot is not supported on virtual machine %(name)s"),
- "KCHVM0007E": _("Unable to create virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0008E": _("Unable to update virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0009E": _("Unable to retrieve virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0010E": _("Unable to connect to powered off virtual machine %(name)s."),
- "KCHVM0011E": _("Virtual machine name must be a string without slashes (/)"),
- "KCHVM0012E": _("Invalid template URI %(value)s specified for virtual machine"),
- "KCHVM0013E": _("Invalid storage pool URI %(value)s specified for virtual machine"),
- "KCHVM0014E": _("Supported virtual machine graphics are Spice or VNC"),
- "KCHVM0015E": _("Graphics address to listen on must be IPv4 or IPv6"),
- "KCHVM0016E": _("Specify a template to create a virtual machine from"),
- "KCHVM0019E": _("Unable to start virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0020E": _("Unable to power off virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0021E": _("Unable to delete virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0022E": _("Unable to reset virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0023E": _("User name list must be an array"),
- "KCHVM0024E": _("User name must be a string"),
- "KCHVM0025E": _("Group name list must be an array"),
- "KCHVM0026E": _("Group name must be a string"),
- "KCHVM0027E": _("User(s) '%(users)s' do not exist"),
- "KCHVM0028E": _("Group(s) '%(groups)s' do not exist"),
- "KCHVM0029E": _("Unable to shutdown virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0030E": _("Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"),
- "KCHVM0031E": _("The guest console password must be a string."),
- "KCHVM0032E": _("The life time for the guest console password must be a number."),
- "KCHVM0033E": _("Virtual machine '%(name)s' must be stopped before cloning it."),
- "KCHVM0034E": _("Insufficient disk space to clone virtual machine '%(name)s'"),
- "KCHVM0035E": _("Unable to clone VM '%(name)s'. Details: %(err)s"),
- "KCHVM0036E": _("Invalid operation for non-persistent virtual machine %(name)s"),
- "KCHVM0037E": _("Cannot suspend VM '%(name)s' because it is not running."),
- "KCHVM0038E": _("Unable to suspend VM '%(name)s'. Details: %(err)s"),
- "KCHVM0039E": _("Cannot resume VM '%(name)s' because it is not paused."),
- "KCHVM0040E": _("Unable to resume VM '%(name)s'. Details: %(err)s"),
- "KCHVM0041E": _("Memory assigned is higher then the maximum allowed in the host."),
- "KCHVM0042E": _("VM '%(name)s' does not support live memory update. Update the memory with the machine offline to enable this feature."),
- "KCHVM0043E": _("Only increase memory is allowed in active VMs"),
- "KCHVM0044E": _("For live memory update, new memory value must be equal old memory value plus multiples of 1024 Mib"),
- "KCHVM0045E": _("There are not enough free slots of 1024 Mib in the guest."),
- "KCHVM0046E": _("Host's libvirt version does not support memory devices. Libvirt must be >= 1.2.14"),
- "KCHVM0047E": _("Error attaching memory device. Details: %(error)s"),
-
- "KCHVMHDEV0001E": _("VM %(vmid)s does not contain directly assigned host device %(dev_name)s."),
- "KCHVMHDEV0002E": _("The host device %(dev_name)s is not allowed to directly assign to VM."),
- "KCHVMHDEV0003E": _("No IOMMU groups found. Host PCI pass through needs IOMMU group to function correctly. "
- "Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify the Kernel is compiled with IOMMU support. "
- "For Intel CPU, add intel_iommu=on to your Kernel parameter in /boot/grub2/grub.conf. "
- "For AMD CPU, add iommu=pt iommu=1."),
- "KCHVMHDEV0004E": _('"name" should be a device name string'),
- "KCHVMHDEV0005E": _('The device %(name)s is probably in use by the host. Unable to attach it to the guest.'),
-
- "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"),
- "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"),
- "KCHVMIF0004E": _("Supported virtual machine interfaces type is only network"),
- "KCHVMIF0005E": _("Network name for virtual machine interface must be a string"),
- "KCHVMIF0006E": _("Invalid network model card specified for virtual machine interface"),
- "KCHVMIF0007E": _("Specify type and network to add a new virtual machine interface"),
- "KCHVMIF0008E": _("MAC Address must respect this format FF:FF:FF:FF:FF:FF"),
- "KCHVMIF0009E": _("MAC Address %(mac)s already exists in virtual machine %(name)s"),
- "KCHVMIF0010E": _("Invalid MAC Address"),
- "KCHVMIF0011E": _("Cannot change MAC address of a running virtual machine"),
-
- "KCHTMPL0001E": _("Template %(name)s already exists"),
- "KCHTMPL0003E": _("Network '%(network)s' specified for template %(template)s does not exist"),
- "KCHTMPL0004E": _("Storage pool %(pool)s specified for template %(template)s does not exist"),
- "KCHTMPL0005E": _("Storage pool %(pool)s specified for template %(template)s is not active"),
- "KCHTMPL0006E": _("Invalid parameter '%(param)s' specified for CDROM."),
- "KCHTMPL0007E": _("Network %(network)s specified for template %(template)s is not active"),
- "KCHTMPL0008E": _("Template name must be a string"),
- "KCHTMPL0009E": _("Template icon must be a path to the image"),
- "KCHTMPL0010E": _("Template distribution must be a string"),
- "KCHTMPL0011E": _("Template distribution version must be a string"),
- "KCHTMPL0012E": _("The number of CPUs must be an integer greater than 0"),
- "KCHTMPL0013E": _("Amount of memory (MB) must be an integer greater than 512"),
- "KCHTMPL0014E": _("Template CDROM must be a local or remote ISO file"),
- "KCHTMPL0015E": _("Invalid storage pool URI %(value)s specified for template"),
- "KCHTMPL0016E": _("Specify an ISO image as CDROM or a base image to create a template"),
- "KCHTMPL0017E": _("All networks for the template must be specified in a list."),
- "KCHTMPL0018E": _("Specify a volume to a template when storage pool is iSCSI or SCSI"),
- "KCHTMPL0019E": _("The volume %(volume)s is not in storage pool %(pool)s"),
- "KCHTMPL0020E": _("Unable to create template due error: %(err)s"),
- "KCHTMPL0021E": _("Unable to delete template due error: %(err)s"),
- "KCHTMPL0022E": _("Disk size must be an integer greater than 1GB."),
- "KCHTMPL0023E": _("Template base image must be a valid local image file"),
- "KCHTMPL0024E": _("Cannot identify base image %(path)s format"),
- "KCHTMPL0025E": _("When specifying CPU topology, VCPUs must be a product of sockets, cores, and threads."),
- "KCHTMPL0026E": _("When specifying CPU topology, each element must be an integer greater than zero."),
- "KCHTMPL0027E": _("Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
-
- "KCHPOOL0001E": _("Storage pool %(name)s already exists"),
- "KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
- "KCHPOOL0004E": _("Specify %(item)s in order to create the storage pool %(name)s"),
- "KCHPOOL0005E": _("Unable to delete active storage pool %(name)s"),
- "KCHPOOL0006E": _("Unable to list storage pools. Details: %(err)s"),
- "KCHPOOL0007E": _("Unable to create storage pool %(name)s. Details: %(err)s"),
- "KCHPOOL0008E": _("Unable to get number of storage volumes in storage pool %(name)s. Details: %(err)s"),
- "KCHPOOL0009E": _("Unable to activate storage pool %(name)s. Details: %(err)s"),
- "KCHPOOL0010E": _("Unable to deactivate storage pool %(name)s. Details: %(err)s"),
- "KCHPOOL0011E": _("Unable to delete storage pool %(name)s. Details: %(err)s"),
- "KCHPOOL0012E": _("Unable to create NFS Pool as export path %(path)s may block during mount"),
- "KCHPOOL0013E": _("Unable to create NFS Pool as export path %(path)s mount failed"),
- "KCHPOOL0014E": _("Unsupported storage pool type: %(type)s"),
- "KCHPOOL0015E": _("Error while retrieving storage pool XML to %(pool)s"),
- "KCHPOOL0016E": _("Storage pool name must be a string without slashes (/)"),
- "KCHPOOL0017E": _("Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-iso"),
- "KCHPOOL0018E": _("Storage pool path must be a string"),
- "KCHPOOL0019E": _("Storage pool host must be a IP or hostname"),
- "KCHPOOL0020E": _("Storage pool device must be the absolute path to the block device"),
- "KCHPOOL0021E": _("Storage pool devices parameter must be a list"),
- "KCHPOOL0022E": _("Target IQN of an iSCSI pool must be a string"),
- "KCHPOOL0023E": _("Port of a remote storage server must be an integer between 1 and 65535"),
- "KCHPOOL0024E": _("iSCSI target username must be a string"),
- "KCHPOOL0025E": _("iSCSI target password must be a string"),
- "KCHPOOL0026E": _("Specify name and type to create a storage pool"),
- "KCHPOOL0027E": _("%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)s."),
- "KCHPOOL0028E": _("Unable to extend logical pool %(pool)s. Details: %(err)s"),
- "KCHPOOL0029E": _("The parameter disks only can be updated for logical storage pool."),
- "KCHPOOL0030E": _("The SCSI host adapter name must be a string."),
- "KCHPOOL0031E": _("The storage pool kimchi_isos is reserved for internal use"),
- "KCHPOOL0032E": _("Unable to activate NFS storage pool %(name)s. NFS server %(server)s is unreachable."),
- "KCHPOOL0033E": _("Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is unreachable."),
- "KCHPOOL0034E": _("Unable to deactivate pool %(name)s as it is associated with some templates"),
- "KCHPOOL0035E": _("Unable to delete pool %(name)s as it is associated with some templates"),
- "KCHPOOL0036E": _("A volume group named '%(name)s' already exists. Please, choose another name to create the logical pool."),
- "KCHPOOL0037E": _("Unable to update database with deep scan information due error: %(err)s"),
-
- "KCHVOL0001E": _("Storage volume %(name)s already exists"),
- "KCHVOL0002E": _("Storage volume %(name)s does not exist in storage pool %(pool)s"),
- "KCHVOL0003E": _("Unable to create storage volume %(volume)s because storage pool %(pool)s is not active"),
- "KCHVOL0004E": _("Specify %(item)s in order to create storage volume %(volume)s"),
- "KCHVOL0006E": _("Unable to list storage volumes because storage pool %(pool)s is not active"),
- "KCHVOL0007E": _("Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %(err)s"),
- "KCHVOL0008E": _("Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"),
- "KCHVOL0009E": _("Unable to wipe storage volumes %(name)s. Details: %(err)s"),
- "KCHVOL0010E": _("Unable to delete storage volume %(name)s. Details: %(err)s"),
- "KCHVOL0011E": _("Unable to resize storage volume %(name)s. Details: %(err)s"),
- "KCHVOL0012E": _("Storage type %(type)s does not support volume create and delete"),
- "KCHVOL0013E": _("Storage volume name must be a string"),
- "KCHVOL0014E": _("Storage volume allocation must be an integer number"),
- "KCHVOL0015E": _("Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
- "KCHVOL0016E": _("Storage volume requires a volume name"),
- "KCHVOL0017E": _("Unable to update database with storage volume information due error: %(err)s"),
- "KCHVOL0018E": _("Only one of parameter %(param)s can be specified"),
- "KCHVOL0019E": _("Create volume from %(param)s is not supported"),
- "KCHVOL0020E": _("Storage volume capacity must be an integer number."),
- "KCHVOL0021E": _("Storage volume URL must be http://, https://, ftp:// or ftps://."),
- "KCHVOL0022E": _("Unable to access file %(url)s. Please, check it."),
- "KCHVOL0023E": _("Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)s"),
- "KCHVOL0024E": _("Specify chunk data and its size to upload a file."),
- "KCHVOL0025E": _("In order to upload a storage volume, specify the 'upload' parameter."),
- "KCHVOL0026E": _("Unable to upload chunk data as it does not match with requested chunk size."),
- "KCHVOL0027E": _("The storage volume %(vol)s is not under an upload process."),
- "KCHVOL0028E": _("The upload chunk data will exceed the storage volume size."),
- "KCHVOL0029E": _("Unable to upload chunk data to storage volume. Details: %(err)s."),
-
- "KCHIFACE0001E": _("Interface %(name)s does not exist"),
-
- "KCHNET0001E": _("Network %(name)s already exists"),
- "KCHNET0002E": _("Network %(name)s does not exist"),
- "KCHNET0003E": _("Subnet %(subnet)s specified for network %(network)s is not valid."),
- "KCHNET0004E": _("Specify a network interface to create bridged network %(name)s"),
- "KCHNET0005E": _("Unable to delete active network %(name)s"),
- "KCHNET0006E": _("Interface %(iface)s specified for network %(network)s is already in use"),
- "KCHNET0007E": _("Interface should be bare NIC, bonding or bridge device."),
- "KCHNET0008E": _("Unable to create network %(name)s. Details: %(err)s"),
- "KCHNET0009E": _("Unable to find a free IP address for network '%(name)s'"),
- "KCHNET0010E": _("The interface %(iface)s already exists."),
- "KCHNET0011E": _("Network name must be a string without slashes (/) or quotes (\")"),
- "KCHNET0012E": _("Supported network types are isolated, NAT and bridge"),
- "KCHNET0013E": _("Network subnet must be a string with IP address and prefix or netmask"),
- "KCHNET0014E": _("Network interface must be a string"),
- "KCHNET0015E": _("Network VLAN ID must be an integer between 1 and 4094"),
- "KCHNET0016E": _("Specify name and type to create a Network"),
- "KCHNET0017E": _("Unable to delete network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."),
- "KCHNET0018E": _("Unable to deactivate network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."),
- "KCHNET0019E": _("Bridge device %(name)s can not be the trunk device of a VLAN."),
- "KCHNET0020E": _("Failed to activate interface %(iface)s: %(err)s."),
- "KCHNET0021E": _("Failed to activate interface %(iface)s. Please check the physical link status."),
- "KCHNET0022E": _("Failed to start network %(name)s. Details: %(err)s"),
-
- "KCHDR0001E": _("Debug report %(name)s does not exist"),
- "KCHDR0002E": _("Debug report tool not found in system"),
- "KCHDR0003E": _("Unable to create debug report %(name)s. Details: %(err)s."),
- "KCHDR0004E": _("Can not find any debug report with the given name %(name)s"),
- "KCHDR0005E": _("Unable to generate debug report %(name)s. Details: %(err)s"),
- "KCHDR0006E": _("You should give a name for the debug report file."),
- "KCHDR0007E": _("Debug report name must be a string. Only letters, digits, underscore ('_') and hyphen ('-') are allowed."),
- "KCHDR0008E": _("The debug report with specified name \"%(name)s\" already exists. Please use another one."),
-
- "KCHSR0001E": _("Storage server %(server)s was not used by Kimchi"),
-
- "KCHDISTRO0001E": _("Distro '%(name)s' does not exist"),
-
- "KCHPART0001E": _("Partition %(name)s does not exist in the host"),
-
- "KCHHOST0001E": _("Unable to shutdown host machine as there are running virtual machines"),
- "KCHHOST0002E": _("Unable to reboot host machine as there are running virtual machines"),
- "KCHHOST0003E": _("Node device '%(name)s' not found"),
- "KCHHOST0004E": _("Conflicting flag filters specified."),
-
- "KCHPKGUPD0001E": _("No packages marked for update"),
- "KCHPKGUPD0002E": _("Package %(name)s is not marked to be updated."),
- "KCHPKGUPD0003E": _("Error while getting packages marked to be updated. Details: %(err)s"),
- "KCHPKGUPD0004E": _("There is no compatible package manager for this system."),
-
- "KCHUTILS0003E": _("Unable to choose a virtual machine name"),
-
- "KCHVMSTOR0002E": _("Invalid storage type. Types supported: 'cdrom', 'disk'"),
- "KCHVMSTOR0003E": _("The path '%(value)s' is not a valid local/remote path for the device"),
- "KCHVMSTOR0006E": _("Only CDROM path can be update."),
- "KCHVMSTOR0007E": _("The storage device %(dev_name)s does not exist in the virtual machine %(vm_name)s"),
- "KCHVMSTOR0008E": _("Error while creating new storage device: %(error)s"),
- "KCHVMSTOR0009E": _("Error while updating storage device: %(error)s"),
- "KCHVMSTOR0010E": _("Error while removing storage device: %(error)s"),
- "KCHVMSTOR0011E": _("Do not support IDE device hot plug"),
- "KCHVMSTOR0012E": _("Specify type and path or type and pool/volume to add a new virtual machine disk"),
- "KCHVMSTOR0013E": _("Specify path to update virtual machine disk"),
- "KCHVMSTOR0014E": _("Controller type %(type)s limitation of %(limit)s devices reached"),
- "KCHVMSTOR0015E": _("Cannot retrieve disk path information for given pool/volume: %(error)s"),
- "KCHVMSTOR0016E": _("Volume already in use by other virtual machine."),
- "KCHVMSTOR0017E": _("Only one of path or pool/volume can be specified to add a new virtual machine disk"),
- "KCHVMSTOR0018E": _("Volume chosen with format %(format)s does not fit in the storage type %(type)s"),
-
- "KCHREPOS0001E": _("YUM Repository ID must be one word only string."),
- "KCHREPOS0002E": _("Repository URL must be an http://, ftp:// or file:// URL."),
- "KCHREPOS0003E": _("Repository configuration is a dictionary with specific values according to repository type."),
- "KCHREPOS0004E": _("Distribution to DEB repository must be a string"),
- "KCHREPOS0005E": _("Components to DEB repository must be listed in a array"),
- "KCHREPOS0006E": _("Components to DEB repository must be a string"),
- "KCHREPOS0007E": _("Mirror list to repository must be a string"),
- "KCHREPOS0008E": _("YUM Repository name must be string."),
- "KCHREPOS0009E": _("GPG check must be a boolean value."),
- "KCHREPOS0010E": _("GPG key must be a URL pointing to the ASCII-armored file."),
- "KCHREPOS0011E": _("Could not update repository %(repo_id)s."),
- "KCHREPOS0012E": _("Repository %(repo_id)s does not exist."),
- "KCHREPOS0013E": _("Specify repository base URL, mirror list or metalink in order to create or update a YUM repository."),
- "KCHREPOS0014E": _("Repository management tool was not recognized for your system."),
- "KCHREPOS0015E": _("Repository %(repo_id)s is already enabled."),
- "KCHREPOS0016E": _("Repository %(repo_id)s is already disabled."),
- "KCHREPOS0017E": _("Could not remove repository %(repo_id)s."),
- "KCHREPOS0018E": _("Could not write repository configuration file %(repo_file)s"),
- "KCHREPOS0019E": _("Specify repository distribution in order to create a DEB repository."),
- "KCHREPOS0020E": _("Could not enable repository %(repo_id)s."),
- "KCHREPOS0021E": _("Could not disable repository %(repo_id)s."),
- "KCHREPOS0022E": _("YUM Repository ID already exists"),
- "KCHREPOS0023E": _("YUM Repository name must be a string"),
- "KCHREPOS0024E": _("Unable to list repositories. Details: '%(err)s'"),
- "KCHREPOS0025E": _("Unable to retrieve repository information. Details: '%(err)s'"),
- "KCHREPOS0026E": _("Unable to add repository. Details: '%(err)s'"),
- "KCHREPOS0027E": _("Unable to remove repository. Details: '%(err)s'"),
- "KCHREPOS0028E": _("Configuration items: '%(items)s' are not supported by repository manager"),
- "KCHREPOS0029E": _("Repository metalink must be an http://, ftp:// or file:// URL."),
- "KCHREPOS0030E": _("Cannot specify mirrorlist and metalink at the same time."),
-
- "KCHSNAP0001E": _("Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."),
- "KCHSNAP0002E": _("Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0003E": _("Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."),
- "KCHSNAP0004E": _("Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0005E": _("Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0006E": _("Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0008E": _("Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0009E": _("Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %(err)s"),
- "KCHSNAP0010E": _("Unable to create snapshot of virtual machine '%(vm)s' because it contains a disk with format '%(format)s'; only 'qcow2' is supported."),
-
- "KCHCPUINF0001E": _("The number of vCPUs is too large for this system."),
- "KCHCPUINF0002E": _("Invalid vCPU/topology combination."),
- "KCHCPUINF0003E": _("This host (or current configuration) does not allow CPU topology."),
-
-}
diff --git a/plugins/kimchi/imageinfo.py b/plugins/kimchi/imageinfo.py
deleted file mode 100644
index 8a22495..0000000
--- a/plugins/kimchi/imageinfo.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import guestfs
-import json
-import os
-import sys
-
-from wok.exception import ImageFormatError, InvalidParameter, TimeoutExpired
-from wok.utils import run_command, wok_log
-
-
-def probe_img_info(path):
- cmd = ["qemu-img", "info", "--output=json", path]
- info = dict()
- try:
- out = run_command(cmd, 10)[0]
- except TimeoutExpired:
- wok_log.warning("Cannot decide format of base img %s", path)
- return None
-
- info = json.loads(out)
- info['virtual-size'] = info['virtual-size'] >> 30
- info['actual-size'] = info['actual-size'] >> 30
- return info
-
-
-def probe_image(image_path):
- if not os.path.isfile(image_path):
- raise InvalidParameter("KCHIMG0004E", {'filename': image_path})
-
- if not os.access(image_path, os.R_OK):
- raise ImageFormatError("KCHIMG0003E", {'filename': image_path})
-
- g = guestfs.GuestFS(python_return_dict=True)
- g.add_drive_opts(image_path, readonly=1)
- g.launch()
-
- try:
- roots = g.inspect_os()
- except:
- raise ImageFormatError("KCHIMG0001E")
-
- if len(roots) == 0:
- raise ImageFormatError("KCHIMG0002E")
-
- for root in roots:
- version = "%d.%d" % (g.inspect_get_major_version(root),
- g.inspect_get_minor_version(root))
- distro = "%s" % (g.inspect_get_distro(root))
-
- return (distro, version)
-
-
-if __name__ == '__main__':
- print probe_image(sys.argv[1])
diff --git a/plugins/kimchi/iscsi.py b/plugins/kimchi/iscsi.py
deleted file mode 100644
index 02886ac..0000000
--- a/plugins/kimchi/iscsi.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301USA
-
-import subprocess
-
-
-from wok.exception import OperationFailed
-
-
-class TargetClient(object):
- def __init__(self, target, host, port=None, auth=None):
- self.portal = host + ("" if port is None else ":%s" % port)
- self.target = target
- self.auth = auth
- self.targetCmd = ['iscsiadm', '--mode', 'node', '--targetname',
- self.target, '--portal', self.portal]
-
- def _update_db(self, Name, Value):
- self._run_cmd(['--op=update', '--name', Name, '--value', Value])
-
- def _update_auth(self):
- if self.auth is None:
- items = (('node.session.auth.authmethod', 'None'),
- ('node.session.auth.username', ''),
- ('node.session.auth.password', ''))
- else:
- items = (('node.session.auth.authmethod', 'CHAP'),
- ('node.session.auth.username', self.auth['username']),
- ('node.session.auth.password', self.auth['password']))
- for name, value in items:
- self._update_db(name, value)
-
- def _run_cmd(self, cmd):
- iscsiadm = subprocess.Popen(
- self.targetCmd + cmd,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = iscsiadm.communicate()
- if iscsiadm.returncode != 0:
- msg_args = {'portal': self.portal, 'err': err}
- raise OperationFailed("KCHISCSI0001E", msg_args)
- return out
-
- def _discover(self):
- iscsiadm = subprocess.Popen(
- ['iscsiadm', '--mode', 'discovery', '--type', 'sendtargets',
- '--portal', self.portal],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = iscsiadm.communicate()
- if iscsiadm.returncode != 0:
- msg_args = {'portal': self.portal, 'err': err}
- raise OperationFailed("KCHISCSI0001E", msg_args)
- return out
-
- def _run_op(self, op):
- self._run_cmd(['--' + op])
-
- def login(self):
- self._discover()
- self._update_auth()
- self._run_op('login')
-
- def logout(self):
- self._run_op('logout')
-
- def validate(self):
- try:
- self.login()
- except OperationFailed:
- return False
-
- self.logout()
- return True
diff --git a/plugins/kimchi/isoinfo.py b/plugins/kimchi/isoinfo.py
deleted file mode 100644
index 8de6885..0000000
--- a/plugins/kimchi/isoinfo.py
+++ /dev/null
@@ -1,506 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import contextlib
-import glob
-import os
-import platform
-import re
-import stat
-import struct
-import sys
-import urllib2
-
-
-from wok.exception import IsoFormatError
-from wok.utils import check_url_path, wok_log
-
-
-iso_dir = [
- ##
- # Portions of this data from libosinfo: http://libosinfo.org/
- #
- # Each tuple has the following three members:
- # Distro ID: Nickname for the distro or OS family
- # Distro Version: A function or string that provides a specific version
- # given a regular expression match on the volume id string
- # Regular Expression: A regex to match against the ISO Volume ID
- ##
- ('openbsd', lambda m: m.group(2),
- ('OpenBSD/(i386|amd64) (\d+\.\d+) Install CD')),
- ('centos', lambda m: m.group(1),
- ('CentOS_(\d+\.\d+)_Final')),
- ('windows', '2000',
- ('W2AFPP|SP1AFPP|SP2AFPP|YRMAFPP|ZRMAFPP|W2AOEM|SP1AOEM|SP2AOEM' +
- '|YRMAOEM|ZRMAOEM|W2ASEL|SP2ASEL|W2SFPP|SP1SFPP|SP2SFPP|YRMSFPP' +
- '|ZRMSFPP|W2SOEM|W2SOEM|SP1SOEM|SP2SOEM|YRMSOEM|ZRMSOEM|W2SSEL' +
- '|SP2SSEL|W2PFPP|SP1PFPP|SP2PFPP|YRMPFPP|ZRMPFPP|W2POEM|SP1POEM' +
- '|SP2POEM|YRMPOEM|ZRMPOEM|W2PSEL|SP2PSEL|W2PCCP|WIN2000|W2K_SP4')),
- ('windows', 'xp',
- ('WXPFPP|WXHFPP|WXPCCP|WXHCCP|WXPOEM|WXHOEM|WXPVOL|WXPEVL|XRMPFPP' +
- '|XRMHFPP|XRMPCCP|XRMHCCP|XRMPOEM|XRMHOEM|XRMPVOL|XRMSD2|X1APFPP' +
- '|X1AHFPP|X1APCCP|X1APCCP|X1AHCCP|X1APOEM|X1AHOEM|X1APVOL|VRMPFPP' +
- '|VRMHFPP|VRMPCCP|VRMHCCP|VRMPOEM|VRMHOEM|VRMPVOL|VRMSD2|VX2PFPP' +
- '|VX2HFPP|VX2PCCP|VX2HCCP|VX2POEM|VX2HOEM|VX2PRMFPP|VX2PVOL|GRTMUPD' +
- '|GRTMPFPP|GRTMPRMFPP|GRTMHFPP|GRTMHKFPP|GRTMHKNFPP|GRTMHRMFPP' +
- '|GRTMPOEM|GRTMHOEM|GRTMPVOL|GRTMPKNVOL|GRTMPKVOL|GRTMPRMVOL' +
- '|MX2PFPP|MRMSD2|ARMPXFPP|ARMPXCCP|ARMPXOEM|ARMPXVOL|AX2PXCFPP' +
- '|AX2PXFPP|NRMPIFPP')),
- ('windows', '2003',
- ('ARMECHK|ARMEVOL|ARMSVOL|ARMWVOL|ARMEEVL|ARMSEVL|ARMWEVL|ARMEOEM' +
- '|ARMDOEM|ARMSOEM|ARMWOEM|ARMEFPP|ARMDFPP|ARMSFPP|ARMWFPP|NRMECHK' +
- '|NRMEVOL|NRMSVOL|NRMWVOL|NRMEEVL|NRMSEVL|NRMWEVL|NRMEOEM|NRMDOEM' +
- '|NRMSOEM|NRMWOEM|NRMEFPP|NRMDFPP|NRMSFPP|NRMSFPP|CRMSVOL|CRMSXVOL' +
- '|BRMEVOL|BX2DVOL|ARMEEVL|BRMEEVL|CR0SP2|ARMEICHK|ARMEIFPP|ARMEIEVL' +
- '|ARMEIOEM|ARMDIOEM|ARMEXFPP|ARMDFPP|ARMSXFPP|CR0SPX2|NRMEICHK' +
- '|NRMEIFPP|NRMDIFPP|NRMEIOEM|NRMDIOEM|NRMEIVOL|NRMEIEVL|BRMEXVOL' +
- '|BX2DXVOL|ARMEIFPP|CR0SPI2')),
- ('windows', '2003r2',
- ('CRMEFPP|CRMSFPP|CR0SCD2|CR0ECD2|BX2SFPP|BX2EFPP|BRMECD2FRE' +
- '|BRMSCD2FRE|CRMEXFPP|CRMSXFPP|CR0SCD2X|CR0ECD2X|BX2SXFPP|BX2EXFPP' +
- '|BRMECD2XFRE|BRMSCD2XFRE|CRMDVOL|CRMDXVOL')),
- ('windows', '2008',
- ('KRTMSVOL|KRTMSCHK|KRMWVOL|KRMSVOL|KRTMSXVOL|KRTMSXCHK|KRMWXVOL' +
- '|KRMSXVOL')),
- ('windows', '2008r2',
- ('GRMSXVOL|GRMSXFRER|GRMSHXVOL|GRMSIAIVOL|SRVHPCR2')),
- ('windows', 'vista',
- ('FB1EVOL|LRMCFRE|FRTMBVOL|FRMBVOL|FRMEVOL|FB1EXVOL|LRMCXFRE' +
- '|FRTMBXVOL|FRMBXVOL|FRMEXVOL|LRMEVOL|LRMEXVOL')),
- ('windows', '7',
- ('GRMCULFRER|GSP1RMCNPRFRER|GSP1RMCNULFRER|GSP1RMCULFRER' +
- '|GSP1RMCPRFRER|GRMCENVOL|GRMCNENVOL|GRMCPRFRER|GSP1RMCPRVOL' +
- '|GRMCULXFRER|GSP1RMCPRXFRER|GSP1RMCNHPXFRER|GRMCHPXFRER|GRMCXCHK' +
- '|GSP1RMCENXVOL|GRMCENXVOL|GRMCNENXVOL|GRMCPRXFRER|GSP1RMCPRXVOL')),
- ('windows', '8',
- ('HB1_CCPA_X86FRE|HRM_CCSA_X86FRE|HRM_CCSA_X86CHK|HRM_CCSNA_X86CHK' +
- '|HRM_CCSNA_X86FRE|HRM_CENA_X86FREV|HRM_CENA_X86CHKV' +
- '|HRM_CENNA_X86FREV|HRM_CENNA_X86CHKV|HRM_CPRA_X86FREV' +
- '|HRM_CPRNA_X86FREV|HB1_CCPA_X64FRE|HRM_CCSA_X64FRE' +
- '|HRM_CCSA_X64CHK|HRM_CCSNA_X64FRE|HRM_CCSNA_X64CHK' +
- '|HRM_CENNA_X64FREV|HRM_CENNA_X64CHKV|HRM_CENA_X64FREV' +
- '|HRM_CENA_X64CHKV|HRM_CPRA_X64FREV|HRM_CPRNA_X64FREV')),
- ('sles', '10', 'SLES10|SUSE-Linux-Enterprise-Server.001'),
- ('sles', '11', 'SUSE_SLES-11-0-0'),
- ('sles', '12', 'SLE-12'),
- ('sles', lambda m: "11sp%s" % m.group(1), 'SLES-11-SP(\d+)'),
- ('opensuse', lambda m: m.group(1), 'openSUSE[ -](\d+\.\d+)'),
- ('opensuse', '11.1', 'SU1110.001'),
- ('opensuse', '11.3',
- 'openSUSE-DVD-i586-Build0702..001|openSUSE-DVD-x86_64.0702..001'),
- ('opensuse', '11.4',
- 'openSUSE-DVD-i586-Build0024|openSUSE-DVD-x86_640024'),
- ('opensuse', '12.1',
- 'openSUSE-DVD-i586-Build0039|openSUSE-DVD-x86_640039'),
- ('opensuse', '12.2',
- 'openSUSE-DVD-i586-Build0167|openSUSE-DVD-x86_640167'),
- ('rhel', '4.8', 'RHEL/4-U8'),
- ('rhel', lambda m: m.group(2), 'RHEL(-LE)?[_/-](\d+\.\d+)'),
- ('debian', lambda m: m.group(1), 'Debian (\d+\.\d+)'),
- ('ubuntu', lambda m: m.group(2), '[Uu]buntu(-Server)? (\d+\.\d+)'),
- ('fedora', lambda m: m.group(1), 'Fedora[ -](\d+)'),
- ('fedora', lambda m: m.group(1), 'Fedora.*-(\d+)-'),
- ('gentoo', lambda m: m.group(1), 'Gentoo Linux \w+ (\d+)'),
- ('powerkvm', 'live_cd', 'POWERKVM_LIVECD'),
- ('arch', lambda m: m.group(1), 'ARCH_(\d+)'),
-]
-
-
-class IsoImage(object):
- """
- Scan an iso9660 image to extract the Volume ID and check for boot-ability
-
- ISO-9660 specification:
- http://www.ecma-international.org/publications/standards/Ecma-119.htm
-
- El-Torito specification:
- http://download.intel.com/support/motherboards/desktop/sb/specscdrom.pdf
- """
- SECTOR_SIZE = 2048
- VOL_DESC = struct.Struct("=B5sBB32s32s")
- EL_TORITO_BOOT_RECORD = struct.Struct("=B5sB32s32sI")
- EL_TORITO_VALIDATION_ENTRY = struct.Struct("=BBH24sHBB")
- EL_TORITO_BOOT_ENTRY = struct.Struct("=BBHBBHL20x")
- # Path table info starting in ISO9660 offset 132. We force little
- # endian byte order (the '<' sign) because Power systems can run on
- # both.
- # First int is path table size, next 4 bytes are discarded (it is
- # the same info but in big endian) and next int is the location.
- PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
-
- def __init__(self, path):
- self.path = path
- self.remote = self._is_iso_remote()
- self.volume_id = None
- self.bootable = False
- self._scan()
-
- def _is_iso_remote(self):
- if os.path.exists(self.path):
- st_mode = os.stat(self.path).st_mode
- if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
- return False
-
- if check_url_path(self.path):
- return True
-
- raise IsoFormatError("KCHISO0001E", {'filename': self.path})
-
- def probe(self):
- if not self.bootable:
- raise IsoFormatError("KCHISO0002E", {'filename': self.path})
-
- matcher = Matcher(self.volume_id)
-
- for d, v, regex in iso_dir:
- if matcher.search(regex):
- distro = d
- if hasattr(v, '__call__'):
- version = v(matcher)
- else:
- version = v
- return (distro, version)
-
- msg = "probe_iso: Unable to identify ISO %s with Volume ID: %s"
- wok_log.debug(msg, self.path, self.volume_id)
-
- return ('unknown', 'unknown')
-
- def _unpack(self, s, data):
- return s.unpack(data[:s.size])
-
- def _scan_el_torito(self, data):
- """
- Search the Volume Descriptor Table for an El Torito boot record. If
- found, the boot record will provide a link to a boot catalogue. The
- first entry in the boot catalogue is a validation entry. The next
- entry contains the default boot entry. The default boot entry will
- indicate whether the image is considered bootable.
- """
- vd_type = -1
- for i in xrange(1, 4):
- fmt = IsoImage.EL_TORITO_BOOT_RECORD
- ptr = i * IsoImage.SECTOR_SIZE
- tmp_data = data[ptr:ptr + fmt.size]
- if len(tmp_data) < fmt.size:
- return
-
- (vd_type, vd_ident, vd_ver,
- et_ident, pad0, boot_cat) = self._unpack(fmt, tmp_data)
- if vd_type == 255: # Volume record terminator
- return
- if vd_type == 0: # Found El-Torito Boot Record
- break
- if not et_ident.startswith('EL TORITO SPECIFICATION'):
- raise IsoFormatError("KCHISO0003E",
- {'filename': self.path})
-
- offset = IsoImage.SECTOR_SIZE * boot_cat
- size = IsoImage.EL_TORITO_VALIDATION_ENTRY.size + \
- IsoImage.EL_TORITO_BOOT_ENTRY.size
- data = self._get_iso_data(offset, size)
-
- fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
- tmp_data = data[0:fmt.size]
- ptr = fmt.size
- (hdr_id, platform_id, pad0,
- ident, csum, key55, keyAA) = self._unpack(fmt, tmp_data)
- if key55 != 0x55 or keyAA != 0xaa:
- raise IsoFormatError("KCHISO0004E",
- {'filename': self.path})
-
- fmt = IsoImage.EL_TORITO_BOOT_ENTRY
- tmp_data = data[ptr:ptr + fmt.size]
- (boot, media_type, load_seg, sys_type,
- pad0, sectors, load_rba) = self._unpack(fmt, tmp_data)
- if boot == 0x88:
- self.bootable = True
- elif boot == 0:
- self.bootable = False
- else:
- raise IsoFormatError("KCHISO0005E",
- {'filename': self.path})
-
- def _scan_ppc(self):
- """
- PowerPC firmware does not use the conventional El Torito boot
- specification. Instead, it looks for a file '/ppc/bootinfo.txt'
- which contains boot information. A PPC image is bootable if
- this file exists in the filesystem [1].
-
- To detect if a PPC ISO is bootable, we could simply mount the
- ISO and search for the boot file as we would with any other
- file in the filesystem. We can also look for the boot file
- searching byte by byte the ISO image. This is possible because
- the PPC ISO image follows the ISO9660 standard [2]. Mounting
- the ISO requires extra resources and it takes longer than
- searching the image data, thus we chose the latter approach
- in this code.
-
- To locate a file we must access the Path Table, which contains
- the records of all the directories in the ISO. After locating
- the directory/subdirectory that contains the file, we access
- the Directory Record to find it.
-
-
- .. [1] https://www.ibm.com/developerworks/community/wikis/home?\
-lang=en#!/wiki/W51a7ffcf4dfd_4b40_9d82_446ebc23c550/page/PowerLinux\
-%20Boot%20howto
- .. [2] http://wiki.osdev.org/ISO_9660
- """
-
- # To locate any file we must access the Path Table, which
- # contains the records of all the directories in the ISO.
- # ISO9660 dictates that the Path Table location information
- # is at offset 132, inside the Primary Volume Descriptor,
- # after the SystemArea (16*SECTOR_SIZE).
- #
- # In the Path table info we're forcing little endian byte
- # order (the '<' sign) because Power systems can run on
- # both.
- #
- # First int is path table size, next 4 bytes are discarded (it is
- # the same info but in big endian) and next int is the location.
- PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
- PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
-
- path_table_loc_data = self._get_iso_data(PATH_TABLE_LOC_OFFSET,
- PATH_TABLE_SIZE_LOC.size)
- path_size, unused, path_loc = self._unpack(PATH_TABLE_SIZE_LOC,
- path_table_loc_data)
- # Fetch the Path Table using location and size found above
- path_table_offset = path_loc * IsoImage.SECTOR_SIZE
- path_table_data = self._get_iso_data(path_table_offset, path_size)
-
- # Loop inside the path table to find the directory 'ppc'.
- # The contents of the registers are:
- # - length of the directory identifier (1 byte)
- # - extended attribute record length (1 byte)
- # - location of directory register (4 bytes)
- # - directory number of parent dir (2 bytes)
- # - directory name (size varies according to length)
- # - padding field - 1 byte if the length is odd, not present if even
- DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H")
- dir_struct_size = DIR_NAMELEN_LOCATION_PARENT.size
- i = 0
- while i < path_size:
- dir_data = path_table_data[i: i+dir_struct_size]
- i += dir_struct_size
- # We won't use the Extended Attribute Record
- dir_namelen, unused, dir_loc, dir_parent = \
- self._unpack(DIR_NAMELEN_LOCATION_PARENT, dir_data)
- if dir_parent == 1:
- # read the dir name using the namelen
- dir_name = path_table_data[i: i+dir_namelen].rstrip()
- if dir_name.lower() == 'ppc':
- # stop searching, dir was found
- break
- # Need to consider the optional padding field as well
- i += dir_namelen + dir_namelen % 2
-
- if i > path_size:
- # Didn't find the '/ppc' directory. ISO is not bootable.
- self.bootable = False
- return
-
- # Get the 'ppc' directory record using 'dir_loc'.
- ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
-
- # We need to find the sector size of this dir entry. The
- # size of the File Section is located 10 bytes after
- # the dir location.
- DIR_SIZE_FMT = struct.Struct("<10sI")
- data = self._get_iso_data(ppc_dir_offset, DIR_SIZE_FMT.size)
- unused, dir_size = self._unpack(DIR_SIZE_FMT, data)
- # If the dir is in the middle of a sector, the sector is
- # padded zero and won't be utilized. We need to round up
- # the result
- dir_sectorsize = dir_size / IsoImage.SECTOR_SIZE
- if dir_size % IsoImage.SECTOR_SIZE:
- dir_sectorsize += 1
-
- # Fixed-size directory record fields:
- # - length of directory record (1 byte)
- # - extended attr. record length (1 byte)
- # - location of extend in both-endian format (8 bytes)
- # - data length (size of extend) in both-endian (8 bytes)
- # - recording date and time (7 bytes)
- # - file flags (1 byte)
- # - file unit size interleaved (1 byte)
- # - interleave gap size (1 byte)
- # - volume sequence number (4 bytes)
- # - length of file identifier (1 byte)
- #
- # Of all these fields, we will use only 3 of them, 'ignoring'
- # 30 bytes total.
- STATIC_DIR_RECORD_FMT = struct.Struct("<B 24s B 6s B")
- static_rec_size = STATIC_DIR_RECORD_FMT.size
-
- # Maximum offset possible of all the records of this directory
- DIR_REC_MAX = ppc_dir_offset + dir_sectorsize*IsoImage.SECTOR_SIZE
- # Max size of a given directory record
- MAX_DIR_SIZE = 255
- # Name of the boot file
- BOOT_FILE_NAME = "bootinfo.txt"
-
- # Loop until one of the following happens:
- # - boot file is found
- # - end of directory record listing for the 'ppc' dir
- while ppc_dir_offset < DIR_REC_MAX:
- record_data = self._get_iso_data(ppc_dir_offset, MAX_DIR_SIZE)
- dir_rec_len, unused, file_flags, unused2, file_name_len = \
- self._unpack(STATIC_DIR_RECORD_FMT, record_data)
-
- # if dir_rec_len = 0, increment offset (skip the
- # dir_rec_len byte) and continue the loop
- if dir_rec_len == 0:
- ppc_dir_offset += 1
- continue
-
- # Get filename of the file/dir we're at.
- filename = record_data[static_rec_size:
- static_rec_size + file_name_len].rstrip()
- # The second bit of the file_flags indicate if this record
- # is a directory.
- if BOOT_FILE_NAME in filename.lower() and (file_flags & 2) != 1:
- self.bootable = True
- return
-
- # Update offset and keep looking. There is a padding here
- # if the length of the file identifier is EVEN.
- padding = 0
- if not file_name_len % 2:
- padding = 1
- ppc_dir_offset += dir_rec_len + padding
- # If reached this point the file wasn't found = not bootable
- self.bootable = False
-
- def _scan_primary_vol(self, data):
- """
- Scan one sector for a Primary Volume Descriptor and extract the
- Volume ID from the table
- """
- primary_vol_data = data[0: -1]
- info = self._unpack(IsoImage.VOL_DESC, primary_vol_data)
- (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id) = info
- if vd_type != 1:
- raise IsoFormatError("KCHISO0006E", {'filename': self.path})
- if vd_ident != 'CD001' or vd_ver != 1:
- raise IsoFormatError("KCHISO0007E", {'filename': self.path})
- if vol_id.strip() == 'RED_HAT':
- # Some RHEL ISO images store the infomation of volume id in the
- # location of volume set id mistakenly.
- self.volume_id = self._get_volume_set_id(data)
- else:
- self.volume_id = vol_id
-
- def _get_volume_set_id(self, data):
- # The index is picked from ISO-9660 specification.
- return data[190: 318]
-
- def _get_iso_data(self, offset, size):
- if self.remote:
- request = urllib2.Request(self.path)
- range_header = "bytes=%d-%d" % (offset, offset + size - 1)
- request.add_header("range", range_header)
- with contextlib.closing(urllib2.urlopen(request)) as response:
- data = response.read()
- else:
- with open(self.path) as fd:
- fd.seek(offset)
- data = fd.read(size)
-
- return data
-
- def _scan(self):
- offset = 16 * IsoImage.SECTOR_SIZE
- size = 4 * IsoImage.SECTOR_SIZE
- data = self._get_iso_data(offset, size)
- if len(data) < 2 * IsoImage.SECTOR_SIZE:
- return
-
- self._scan_primary_vol(data)
- if platform.machine().startswith('ppc'):
- self._scan_ppc()
- else:
- self._scan_el_torito(data)
-
-
-class Matcher(object):
- """
- Simple utility class to assist with matching a given string against a
- series of regular expressions.
- """
- def __init__(self, matchstring):
- self.matchstring = matchstring
-
- def search(self, regex):
- self.lastmatch = re.search(regex, self.matchstring)
- return bool(self.lastmatch)
-
- def group(self, num):
- return self.lastmatch.group(num)
-
-
-def probe_iso(status_helper, params):
- loc = params['path'].encode("utf-8")
- updater = params['updater']
- ignore = False
- ignore_list = params.get('ignore_list', [])
-
- def update_result(iso, ret):
- path = os.path.abspath(iso) if os.path.isfile(iso) else iso
- updater({'path': path, 'distro': ret[0], 'version': ret[1]})
-
- if os.path.isdir(loc):
- for root, dirs, files in os.walk(loc):
- for dir_name in ignore_list:
- if root in glob.glob(dir_name):
- ignore = True
- break
- if ignore:
- ignore = False
- continue
- for name in files:
- if not name.lower().endswith('.iso'):
- continue
- iso = os.path.join(root, name)
- try:
- iso_img = IsoImage(iso)
- ret = iso_img.probe()
- update_result(iso, ret)
- except:
- continue
- else:
- iso_img = IsoImage(loc)
- ret = iso_img.probe()
- update_result(loc, ret)
-
- if status_helper is not None:
- status_helper('', True)
-
-
-if __name__ == '__main__':
- iso_list = []
-
- def updater(iso_info):
- iso_list.append(iso_info)
-
- probe_iso(None, dict(path=sys.argv[1], updater=updater))
- print iso_list
diff --git a/plugins/kimchi/kimchi.conf b/plugins/kimchi/kimchi.conf
deleted file mode 100644
index 1bf78e4..0000000
--- a/plugins/kimchi/kimchi.conf
+++ /dev/null
@@ -1,37 +0,0 @@
-[wok]
-enable = True
-plugin_class = "KimchiRoot"
-uri = "/plugins/kimchi"
-extra_auth_api_class = "control.sub_nodes"
-
-[/]
-tools.trailing_slash.on = False
-request.methods_with_bodies = ('POST', 'PUT')
-tools.nocache.on = True
-tools.proxy.on = True
-tools.sessions.on = True
-tools.sessions.name = 'wok'
-tools.sessions.secure = True
-tools.sessions.httponly = True
-tools.sessions.locking = 'explicit'
-tools.sessions.storage_type = 'ram'
-tools.sessions.timeout = 10
-tools.wokauth.on = True
-
-[/data/screenshots]
-tools.staticdir.on = True
-tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir + '/screenshots'
-tools.nocache.on = False
-
-[/data/debugreports]
-tools.staticdir.on = True
-tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir + '/debugreports'
-tools.nocache.on = False
-tools.wokauth.on = True
-tools.staticdir.content_types = {'xz': 'application/x-xz'}
-
-[/help]
-tools.staticdir.on = True
-tools.staticdir.dir = wok.config.PluginPaths('kimchi').ui_dir + '/pages/help'
-tools.nocache.on = True
-
diff --git a/plugins/kimchi/kvmusertests.py b/plugins/kimchi/kvmusertests.py
deleted file mode 100644
index 35350d8..0000000
--- a/plugins/kimchi/kvmusertests.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import platform
-import psutil
-import threading
-
-
-from wok.rollbackcontext import RollbackContext
-
-KVMUSERTEST_VM_NAME = "KVMUSERTEST_VM"
-
-
-class UserTests(object):
- SIMPLE_VM_XML = """
- <domain type='kvm'>
- <name>%(name)s</name>
- <memory unit='KiB'>262144</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- </os>
- </domain>"""
- lock = threading.Lock()
- user = None
-
- @classmethod
- def probe_user(cls):
- with cls.lock:
- if cls.user:
- return cls.user
-
- arch = 'ppc64' if platform.machine() == 'ppc64le' \
- else platform.machine()
-
- xml = cls.SIMPLE_VM_XML % {'name': KVMUSERTEST_VM_NAME, 'arch': arch}
-
- with RollbackContext() as rollback:
- with cls.lock:
- conn = libvirt.open(None)
- rollback.prependDefer(conn.close)
- f = libvirt.VIR_DOMAIN_START_AUTODESTROY
- dom = conn.createXML(xml, flags=f)
- rollback.prependDefer(dom.destroy)
- filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME
- with open(filename) as f:
- pidStr = f.read()
- p = psutil.Process(int(pidStr))
-
- # bug fix #357
- # in psutil 2.0 and above versions, username will be a method,
- # not a string
- if callable(p.username):
- cls.user = p.username()
- else:
- cls.user = p.username
-
- return cls.user
-
-
-if __name__ == '__main__':
- ut = UserTests()
- print ut.probe_user()
diff --git a/plugins/kimchi/m4/ac_python_module.m4 b/plugins/kimchi/m4/ac_python_module.m4
deleted file mode 100644
index 32b9d72..0000000
--- a/plugins/kimchi/m4/ac_python_module.m4
+++ /dev/null
@@ -1,30 +0,0 @@
-dnl @synopsis AC_PYTHON_MODULE(modname[, fatal])
-dnl
-dnl Checks for Python module.
-dnl
-dnl If fatal is non-empty then absence of a module will trigger an
-dnl error.
-dnl
-dnl @category InstalledPackages
-dnl @author Andrew Collier <colliera at nu.ac.za>.
-dnl @version 2004-07-14
-dnl @license AllPermissive
-
-AC_DEFUN([AC_PYTHON_MODULE],[
- AC_MSG_CHECKING(python module: $1)
- python -c "import $1" 2>/dev/null
- if test $? -eq 0;
- then
- AC_MSG_RESULT(yes)
- eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
- else
- AC_MSG_RESULT(no)
- eval AS_TR_CPP(HAVE_PYMOD_$1)=no
- #
- if test -n "$2"
- then
- AC_MSG_ERROR(failed to find required module $1)
- exit 1
- fi
- fi
-])
diff --git a/plugins/kimchi/m4/gettext.m4 b/plugins/kimchi/m4/gettext.m4
deleted file mode 100644
index f84e6a5..0000000
--- a/plugins/kimchi/m4/gettext.m4
+++ /dev/null
@@ -1,383 +0,0 @@
-# gettext.m4 serial 63 (gettext-0.18)
-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper at cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible at clisp.cons.org>, 2000-2006, 2008-2010.
-
-dnl Macro to add for using GNU gettext.
-
-dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
-dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
-dnl default (if it is not specified or empty) is 'no-libtool'.
-dnl INTLSYMBOL should be 'external' for packages with no intl directory,
-dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory.
-dnl If INTLSYMBOL is 'use-libtool', then a libtool library
-dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
-dnl depending on --{enable,disable}-{shared,static} and on the presence of
-dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
-dnl $(top_builddir)/intl/libintl.a will be created.
-dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
-dnl implementations (in libc or libintl) without the ngettext() function
-dnl will be ignored. If NEEDSYMBOL is specified and is
-dnl 'need-formatstring-macros', then GNU gettext implementations that don't
-dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
-dnl INTLDIR is used to find the intl libraries. If empty,
-dnl the value `$(top_builddir)/intl/' is used.
-dnl
-dnl The result of the configuration is one of three cases:
-dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
-dnl and used.
-dnl Catalog format: GNU --> install in $(datadir)
-dnl Catalog extension: .mo after installation, .gmo in source tree
-dnl 2) GNU gettext has been found in the system's C library.
-dnl Catalog format: GNU --> install in $(datadir)
-dnl Catalog extension: .mo after installation, .gmo in source tree
-dnl 3) No internationalization, always use English msgid.
-dnl Catalog format: none
-dnl Catalog extension: none
-dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
-dnl The use of .gmo is historical (it was needed to avoid overwriting the
-dnl GNU format catalogs when building on a platform with an X/Open gettext),
-dnl but we keep it in order not to force irrelevant filename changes on the
-dnl maintainers.
-dnl
-AC_DEFUN([AM_GNU_GETTEXT],
-[
- dnl Argument checking.
- ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
- [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
-])])])])])
- ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
- [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
- ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
- [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
-])])])])
- define([gt_included_intl],
- ifelse([$1], [external],
- ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
- [yes]))
- define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
- gt_NEEDS_INIT
- AM_GNU_GETTEXT_NEED([$2])
-
- AC_REQUIRE([AM_PO_SUBDIRS])dnl
- ifelse(gt_included_intl, yes, [
- AC_REQUIRE([AM_INTL_SUBDIR])dnl
- ])
-
- dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
-
- dnl Sometimes libintl requires libiconv, so first search for libiconv.
- dnl Ideally we would do this search only after the
- dnl if test "$USE_NLS" = "yes"; then
- dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
- dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
- dnl the configure script would need to contain the same shell code
- dnl again, outside any 'if'. There are two solutions:
- dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
- dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
- dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
- dnl documented, we avoid it.
- ifelse(gt_included_intl, yes, , [
- AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
- ])
-
- dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
- gt_INTL_MACOSX
-
- dnl Set USE_NLS.
- AC_REQUIRE([AM_NLS])
-
- ifelse(gt_included_intl, yes, [
- BUILD_INCLUDED_LIBINTL=no
- USE_INCLUDED_LIBINTL=no
- ])
- LIBINTL=
- LTLIBINTL=
- POSUB=
-
- dnl Add a version number to the cache macros.
- case " $gt_needs " in
- *" need-formatstring-macros "*) gt_api_version=3 ;;
- *" need-ngettext "*) gt_api_version=2 ;;
- *) gt_api_version=1 ;;
- esac
- gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
- gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
-
- dnl If we use NLS figure out what method
- if test "$USE_NLS" = "yes"; then
- gt_use_preinstalled_gnugettext=no
- ifelse(gt_included_intl, yes, [
- AC_MSG_CHECKING([whether included gettext is requested])
- AC_ARG_WITH([included-gettext],
- [ --with-included-gettext use the GNU gettext library included here],
- nls_cv_force_use_gnu_gettext=$withval,
- nls_cv_force_use_gnu_gettext=no)
- AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
-
- nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
- if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
- ])
- dnl User does not insist on using GNU NLS library. Figure out what
- dnl to use. If GNU gettext is available we use this. Else we have
- dnl to fall back to GNU NLS library.
-
- if test $gt_api_version -ge 3; then
- gt_revision_test_code='
-#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
-#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
-#endif
-changequote(,)dnl
-typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
-changequote([,])dnl
-'
- else
- gt_revision_test_code=
- fi
- if test $gt_api_version -ge 2; then
- gt_expression_test_code=' + * ngettext ("", "", 0)'
- else
- gt_expression_test_code=
- fi
-
- AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
- [AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern int *_nl_domain_bindings;],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
- [eval "$gt_func_gnugettext_libc=yes"],
- [eval "$gt_func_gnugettext_libc=no"])])
-
- if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
- dnl Sometimes libintl requires libiconv, so first search for libiconv.
- ifelse(gt_included_intl, yes, , [
- AM_ICONV_LINK
- ])
- dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
- dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
- dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
- dnl even if libiconv doesn't exist.
- AC_LIB_LINKFLAGS_BODY([intl])
- AC_CACHE_CHECK([for GNU gettext in libintl],
- [$gt_func_gnugettext_libintl],
- [gt_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $INCINTL"
- gt_save_LIBS="$LIBS"
- LIBS="$LIBS $LIBINTL"
- dnl Now see whether libintl exists and does not depend on libiconv.
- AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
- [eval "$gt_func_gnugettext_libintl=yes"],
- [eval "$gt_func_gnugettext_libintl=no"])
- dnl Now see whether libintl exists and depends on libiconv.
- if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
- LIBS="$LIBS $LIBICONV"
- AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
- [LIBINTL="$LIBINTL $LIBICONV"
- LTLIBINTL="$LTLIBINTL $LTLIBICONV"
- eval "$gt_func_gnugettext_libintl=yes"
- ])
- fi
- CPPFLAGS="$gt_save_CPPFLAGS"
- LIBS="$gt_save_LIBS"])
- fi
-
- dnl If an already present or preinstalled GNU gettext() is found,
- dnl use it. But if this macro is used in GNU gettext, and GNU
- dnl gettext is already preinstalled in libintl, we update this
- dnl libintl. (Cf. the install rule in intl/Makefile.in.)
- if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
- || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
- && test "$PACKAGE" != gettext-runtime \
- && test "$PACKAGE" != gettext-tools; }; then
- gt_use_preinstalled_gnugettext=yes
- else
- dnl Reset the values set by searching for libintl.
- LIBINTL=
- LTLIBINTL=
- INCINTL=
- fi
-
- ifelse(gt_included_intl, yes, [
- if test "$gt_use_preinstalled_gnugettext" != "yes"; then
- dnl GNU gettext is not found in the C library.
- dnl Fall back on included GNU gettext library.
- nls_cv_use_gnu_gettext=yes
- fi
- fi
-
- if test "$nls_cv_use_gnu_gettext" = "yes"; then
- dnl Mark actions used to generate GNU NLS library.
- BUILD_INCLUDED_LIBINTL=yes
- USE_INCLUDED_LIBINTL=yes
- LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
- LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
- LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
- fi
-
- CATOBJEXT=
- if test "$gt_use_preinstalled_gnugettext" = "yes" \
- || test "$nls_cv_use_gnu_gettext" = "yes"; then
- dnl Mark actions to use GNU gettext tools.
- CATOBJEXT=.gmo
- fi
- ])
-
- if test -n "$INTL_MACOSX_LIBS"; then
- if test "$gt_use_preinstalled_gnugettext" = "yes" \
- || test "$nls_cv_use_gnu_gettext" = "yes"; then
- dnl Some extra flags are needed during linking.
- LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
- LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
- fi
- fi
-
- if test "$gt_use_preinstalled_gnugettext" = "yes" \
- || test "$nls_cv_use_gnu_gettext" = "yes"; then
- AC_DEFINE([ENABLE_NLS], [1],
- [Define to 1 if translation of program messages to the user's native language
- is requested.])
- else
- USE_NLS=no
- fi
- fi
-
- AC_MSG_CHECKING([whether to use NLS])
- AC_MSG_RESULT([$USE_NLS])
- if test "$USE_NLS" = "yes"; then
- AC_MSG_CHECKING([where the gettext function comes from])
- if test "$gt_use_preinstalled_gnugettext" = "yes"; then
- if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
- gt_source="external libintl"
- else
- gt_source="libc"
- fi
- else
- gt_source="included intl directory"
- fi
- AC_MSG_RESULT([$gt_source])
- fi
-
- if test "$USE_NLS" = "yes"; then
-
- if test "$gt_use_preinstalled_gnugettext" = "yes"; then
- if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
- AC_MSG_CHECKING([how to link with libintl])
- AC_MSG_RESULT([$LIBINTL])
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
- fi
-
- dnl For backward compatibility. Some packages may be using this.
- AC_DEFINE([HAVE_GETTEXT], [1],
- [Define if the GNU gettext() function is already present or preinstalled.])
- AC_DEFINE([HAVE_DCGETTEXT], [1],
- [Define if the GNU dcgettext() function is already present or preinstalled.])
- fi
-
- dnl We need to process the po/ directory.
- POSUB=po
- fi
-
- ifelse(gt_included_intl, yes, [
- dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
- dnl to 'yes' because some of the testsuite requires it.
- if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
- BUILD_INCLUDED_LIBINTL=yes
- fi
-
- dnl Make all variables we use known to autoconf.
- AC_SUBST([BUILD_INCLUDED_LIBINTL])
- AC_SUBST([USE_INCLUDED_LIBINTL])
- AC_SUBST([CATOBJEXT])
-
- dnl For backward compatibility. Some configure.ins may be using this.
- nls_cv_header_intl=
- nls_cv_header_libgt=
-
- dnl For backward compatibility. Some Makefiles may be using this.
- DATADIRNAME=share
- AC_SUBST([DATADIRNAME])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INSTOBJEXT=.mo
- AC_SUBST([INSTOBJEXT])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- GENCAT=gencat
- AC_SUBST([GENCAT])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INTLOBJS=
- if test "$USE_INCLUDED_LIBINTL" = yes; then
- INTLOBJS="\$(GETTOBJS)"
- fi
- AC_SUBST([INTLOBJS])
-
- dnl Enable libtool support if the surrounding package wishes it.
- INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
- AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
- ])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INTLLIBS="$LIBINTL"
- AC_SUBST([INTLLIBS])
-
- dnl Make all documented variables known to autoconf.
- AC_SUBST([LIBINTL])
- AC_SUBST([LTLIBINTL])
- AC_SUBST([POSUB])
-])
-
-
-dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
-m4_define([gt_NEEDS_INIT],
-[
- m4_divert_text([DEFAULTS], [gt_needs=])
- m4_define([gt_NEEDS_INIT], [])
-])
-
-
-dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
-AC_DEFUN([AM_GNU_GETTEXT_NEED],
-[
- m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
-])
-
-
-dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
-AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/plugins/kimchi/m4/iconv.m4 b/plugins/kimchi/m4/iconv.m4
deleted file mode 100644
index e2041b9..0000000
--- a/plugins/kimchi/m4/iconv.m4
+++ /dev/null
@@ -1,214 +0,0 @@
-# iconv.m4 serial 11 (gettext-0.18.1)
-dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
-[
- dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
-
- dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
- dnl accordingly.
- AC_LIB_LINKFLAGS_BODY([iconv])
-])
-
-AC_DEFUN([AM_ICONV_LINK],
-[
- dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
- dnl those with the standalone portable GNU libiconv installed).
- AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
-
- dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
- dnl accordingly.
- AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
-
- dnl Add $INCICONV to CPPFLAGS before performing the following checks,
- dnl because if the user has installed libiconv and not disabled its use
- dnl via --without-libiconv-prefix, he wants to use it. The first
- dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
- am_save_CPPFLAGS="$CPPFLAGS"
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
-
- AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
- am_cv_func_iconv="no, consider installing GNU libiconv"
- am_cv_lib_iconv=no
- AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- [am_cv_func_iconv=yes])
- if test "$am_cv_func_iconv" != yes; then
- am_save_LIBS="$LIBS"
- LIBS="$LIBS $LIBICONV"
- AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- [am_cv_lib_iconv=yes]
- [am_cv_func_iconv=yes])
- LIBS="$am_save_LIBS"
- fi
- ])
- if test "$am_cv_func_iconv" = yes; then
- AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
- dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10.
- am_save_LIBS="$LIBS"
- if test $am_cv_lib_iconv = yes; then
- LIBS="$LIBS $LIBICONV"
- fi
- AC_TRY_RUN([
-#include <iconv.h>
-#include <string.h>
-int main ()
-{
- /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
- returns. */
- {
- iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
- if (cd_utf8_to_88591 != (iconv_t)(-1))
- {
- static const char input[] = "\342\202\254"; /* EURO SIGN */
- char buf[10];
- const char *inptr = input;
- size_t inbytesleft = strlen (input);
- char *outptr = buf;
- size_t outbytesleft = sizeof (buf);
- size_t res = iconv (cd_utf8_to_88591,
- (char **) &inptr, &inbytesleft,
- &outptr, &outbytesleft);
- if (res == 0)
- return 1;
- }
- }
- /* Test against Solaris 10 bug: Failures are not distinguishable from
- successful returns. */
- {
- iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
- if (cd_ascii_to_88591 != (iconv_t)(-1))
- {
- static const char input[] = "\263";
- char buf[10];
- const char *inptr = input;
- size_t inbytesleft = strlen (input);
- char *outptr = buf;
- size_t outbytesleft = sizeof (buf);
- size_t res = iconv (cd_ascii_to_88591,
- (char **) &inptr, &inbytesleft,
- &outptr, &outbytesleft);
- if (res == 0)
- return 1;
- }
- }
-#if 0 /* This bug could be worked around by the caller. */
- /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
- {
- iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
- if (cd_88591_to_utf8 != (iconv_t)(-1))
- {
- static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
- char buf[50];
- const char *inptr = input;
- size_t inbytesleft = strlen (input);
- char *outptr = buf;
- size_t outbytesleft = sizeof (buf);
- size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
- &outptr, &outbytesleft);
- if ((int)res > 0)
- return 1;
- }
- }
-#endif
- /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
- provided. */
- if (/* Try standardized names. */
- iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
- /* Try IRIX, OSF/1 names. */
- && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
- /* Try AIX names. */
- && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
- /* Try HP-UX names. */
- && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
- return 1;
- return 0;
-}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
- [case "$host_os" in
- aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
- *) am_cv_func_iconv_works="guessing yes" ;;
- esac])
- LIBS="$am_save_LIBS"
- ])
- case "$am_cv_func_iconv_works" in
- *no) am_func_iconv=no am_cv_lib_iconv=no ;;
- *) am_func_iconv=yes ;;
- esac
- else
- am_func_iconv=no am_cv_lib_iconv=no
- fi
- if test "$am_func_iconv" = yes; then
- AC_DEFINE([HAVE_ICONV], [1],
- [Define if you have the iconv() function and it works.])
- fi
- if test "$am_cv_lib_iconv" = yes; then
- AC_MSG_CHECKING([how to link with libiconv])
- AC_MSG_RESULT([$LIBICONV])
- else
- dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
- dnl either.
- CPPFLAGS="$am_save_CPPFLAGS"
- LIBICONV=
- LTLIBICONV=
- fi
- AC_SUBST([LIBICONV])
- AC_SUBST([LTLIBICONV])
-])
-
-dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
-dnl avoid warnings like
-dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
-dnl This is tricky because of the way 'aclocal' is implemented:
-dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
-dnl Otherwise aclocal's initial scan pass would miss the macro definition.
-dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
-dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
-dnl warnings.
-m4_define([gl_iconv_AC_DEFUN],
- m4_version_prereq([2.64],
- [[AC_DEFUN_ONCE(
- [$1], [$2])]],
- [[AC_DEFUN(
- [$1], [$2])]]))
-gl_iconv_AC_DEFUN([AM_ICONV],
-[
- AM_ICONV_LINK
- if test "$am_cv_func_iconv" = yes; then
- AC_MSG_CHECKING([for iconv declaration])
- AC_CACHE_VAL([am_cv_proto_iconv], [
- AC_TRY_COMPILE([
-#include <stdlib.h>
-#include <iconv.h>
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
-#else
-size_t iconv();
-#endif
-], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"])
- am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
- am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
- AC_MSG_RESULT([
- $am_cv_proto_iconv])
- AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
- [Define as const if the declaration of iconv() needs const.])
- fi
-])
diff --git a/plugins/kimchi/m4/intlmacosx.m4 b/plugins/kimchi/m4/intlmacosx.m4
deleted file mode 100644
index dd91025..0000000
--- a/plugins/kimchi/m4/intlmacosx.m4
+++ /dev/null
@@ -1,51 +0,0 @@
-# intlmacosx.m4 serial 3 (gettext-0.18)
-dnl Copyright (C) 2004-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Checks for special options needed on MacOS X.
-dnl Defines INTL_MACOSX_LIBS.
-AC_DEFUN([gt_INTL_MACOSX],
-[
- dnl Check for API introduced in MacOS X 10.2.
- AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
- [gt_cv_func_CFPreferencesCopyAppValue],
- [gt_save_LIBS="$LIBS"
- LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
- AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
- [CFPreferencesCopyAppValue(NULL, NULL)],
- [gt_cv_func_CFPreferencesCopyAppValue=yes],
- [gt_cv_func_CFPreferencesCopyAppValue=no])
- LIBS="$gt_save_LIBS"])
- if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
- AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
- [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
- fi
- dnl Check for API introduced in MacOS X 10.3.
- AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
- [gt_save_LIBS="$LIBS"
- LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
- AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
- [gt_cv_func_CFLocaleCopyCurrent=yes],
- [gt_cv_func_CFLocaleCopyCurrent=no])
- LIBS="$gt_save_LIBS"])
- if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
- AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
- [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
- fi
- INTL_MACOSX_LIBS=
- if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
- INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
- fi
- AC_SUBST([INTL_MACOSX_LIBS])
-])
diff --git a/plugins/kimchi/m4/lib-ld.m4 b/plugins/kimchi/m4/lib-ld.m4
deleted file mode 100644
index ebb3052..0000000
--- a/plugins/kimchi/m4/lib-ld.m4
+++ /dev/null
@@ -1,110 +0,0 @@
-# lib-ld.m4 serial 4 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl Subroutines of libtool.m4,
-dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
-dnl with libtool.m4.
-
-dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
-AC_DEFUN([AC_LIB_PROG_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- acl_cv_prog_gnu_ld=yes ;;
-*)
- acl_cv_prog_gnu_ld=no ;;
-esac])
-with_gnu_ld=$acl_cv_prog_gnu_ld
-])
-
-dnl From libtool-1.4. Sets the variable LD.
-AC_DEFUN([AC_LIB_PROG_LD],
-[AC_ARG_WITH([gnu-ld],
-[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
-test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- AC_MSG_CHECKING([for ld used by GCC])
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [[\\/]* | [A-Za-z]:[\\/]*)]
- [re_direlt='/[^/][^/]*/\.\./']
- # Canonicalize the path of ld
- ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- AC_MSG_CHECKING([for GNU ld])
-else
- AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL([acl_cv_path_LD],
-[if test -z "$LD"; then
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
- acl_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break ;;
- *)
- test "$with_gnu_ld" != yes && break ;;
- esac
- fi
- done
- IFS="$ac_save_ifs"
-else
- acl_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$acl_cv_path_LD"
-if test -n "$LD"; then
- AC_MSG_RESULT([$LD])
-else
- AC_MSG_RESULT([no])
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AC_LIB_PROG_LD_GNU
-])
diff --git a/plugins/kimchi/m4/lib-link.m4 b/plugins/kimchi/m4/lib-link.m4
deleted file mode 100644
index c73bd8e..0000000
--- a/plugins/kimchi/m4/lib-link.m4
+++ /dev/null
@@ -1,774 +0,0 @@
-# lib-link.m4 serial 21 (gettext-0.18)
-dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-AC_PREREQ([2.54])
-
-dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
-dnl augments the CPPFLAGS variable.
-dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
-dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_LINKFLAGS],
-[
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
- pushdef([Name],[translit([$1],[./-], [___])])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
- AC_LIB_LINKFLAGS_BODY([$1], [$2])
- ac_cv_lib[]Name[]_libs="$LIB[]NAME"
- ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
- ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
- ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
- ])
- LIB[]NAME="$ac_cv_lib[]Name[]_libs"
- LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
- INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
- LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
- AC_SUBST([LIB]NAME)
- AC_SUBST([LTLIB]NAME)
- AC_SUBST([LIB]NAME[_PREFIX])
- dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
- dnl results of this search when this library appears as a dependency.
- HAVE_LIB[]NAME=yes
- popdef([NAME])
- popdef([Name])
-])
-
-dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
-dnl searches for libname and the libraries corresponding to explicit and
-dnl implicit dependencies, together with the specified include files and
-dnl the ability to compile and link the specified testcode. The missing-message
-dnl defaults to 'no' and may contain additional hints for the user.
-dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
-dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
-dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
-dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
-dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
-dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
-[
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
- pushdef([Name],[translit([$1],[./-], [___])])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-
- dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
- dnl accordingly.
- AC_LIB_LINKFLAGS_BODY([$1], [$2])
-
- dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
- dnl because if the user has installed lib[]Name and not disabled its use
- dnl via --without-lib[]Name-prefix, he wants to use it.
- ac_save_CPPFLAGS="$CPPFLAGS"
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
-
- AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
- ac_save_LIBS="$LIBS"
- dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
- dnl because these -l options might require -L options that are present in
- dnl LIBS. -l options benefit only from the -L options listed before it.
- dnl Otherwise, add it to the front of LIBS, because it may be a static
- dnl library that depends on another static library that is present in LIBS.
- dnl Static libraries benefit only from the static libraries listed after
- dnl it.
- case " $LIB[]NAME" in
- *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
- *) LIBS="$LIB[]NAME $LIBS" ;;
- esac
- AC_TRY_LINK([$3], [$4],
- [ac_cv_lib[]Name=yes],
- [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
- LIBS="$ac_save_LIBS"
- ])
- if test "$ac_cv_lib[]Name" = yes; then
- HAVE_LIB[]NAME=yes
- AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
- AC_MSG_CHECKING([how to link with lib[]$1])
- AC_MSG_RESULT([$LIB[]NAME])
- else
- HAVE_LIB[]NAME=no
- dnl If $LIB[]NAME didn't lead to a usable library, we don't need
- dnl $INC[]NAME either.
- CPPFLAGS="$ac_save_CPPFLAGS"
- LIB[]NAME=
- LTLIB[]NAME=
- LIB[]NAME[]_PREFIX=
- fi
- AC_SUBST([HAVE_LIB]NAME)
- AC_SUBST([LIB]NAME)
- AC_SUBST([LTLIB]NAME)
- AC_SUBST([LIB]NAME[_PREFIX])
- popdef([NAME])
- popdef([Name])
-])
-
-dnl Determine the platform dependent parameters needed to use rpath:
-dnl acl_libext,
-dnl acl_shlibext,
-dnl acl_hardcode_libdir_flag_spec,
-dnl acl_hardcode_libdir_separator,
-dnl acl_hardcode_direct,
-dnl acl_hardcode_minus_L.
-AC_DEFUN([AC_LIB_RPATH],
-[
- dnl Tell automake >= 1.10 to complain if config.rpath is missing.
- m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
- AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
- AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
- AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
- AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
- AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
- CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
- ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
- . ./conftest.sh
- rm -f ./conftest.sh
- acl_cv_rpath=done
- ])
- wl="$acl_cv_wl"
- acl_libext="$acl_cv_libext"
- acl_shlibext="$acl_cv_shlibext"
- acl_libname_spec="$acl_cv_libname_spec"
- acl_library_names_spec="$acl_cv_library_names_spec"
- acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
- acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
- acl_hardcode_direct="$acl_cv_hardcode_direct"
- acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
- dnl Determine whether the user wants rpath handling at all.
- AC_ARG_ENABLE([rpath],
- [ --disable-rpath do not hardcode runtime library paths],
- :, enable_rpath=yes)
-])
-
-dnl AC_LIB_FROMPACKAGE(name, package)
-dnl declares that libname comes from the given package. The configure file
-dnl will then not have a --with-libname-prefix option but a
-dnl --with-package-prefix option. Several libraries can come from the same
-dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
-dnl macro call that searches for libname.
-AC_DEFUN([AC_LIB_FROMPACKAGE],
-[
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- define([acl_frompackage_]NAME, [$2])
- popdef([NAME])
- pushdef([PACK],[$2])
- pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- define([acl_libsinpackage_]PACKUP,
- m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
- popdef([PACKUP])
- popdef([PACK])
-])
-
-dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
-dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
-dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
-[
- AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
- pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
- dnl Autoconf >= 2.61 supports dots in --with options.
- pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
- dnl By default, look in $includedir and $libdir.
- use_additional=yes
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- AC_ARG_WITH(P_A_C_K[-prefix],
-[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
- --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
-[
- if test "X$withval" = "Xno"; then
- use_additional=no
- else
- if test "X$withval" = "X"; then
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- else
- additional_includedir="$withval/include"
- additional_libdir="$withval/$acl_libdirstem"
- if test "$acl_libdirstem2" != "$acl_libdirstem" \
- && ! test -d "$withval/$acl_libdirstem"; then
- additional_libdir="$withval/$acl_libdirstem2"
- fi
- fi
- fi
-])
- dnl Search the library and its dependencies in $additional_libdir and
- dnl $LDFLAGS. Using breadth-first-seach.
- LIB[]NAME=
- LTLIB[]NAME=
- INC[]NAME=
- LIB[]NAME[]_PREFIX=
- dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
- dnl computed. So it has to be reset here.
- HAVE_LIB[]NAME=
- rpathdirs=
- ltrpathdirs=
- names_already_handled=
- names_next_round='$1 $2'
- while test -n "$names_next_round"; do
- names_this_round="$names_next_round"
- names_next_round=
- for name in $names_this_round; do
- already_handled=
- for n in $names_already_handled; do
- if test "$n" = "$name"; then
- already_handled=yes
- break
- fi
- done
- if test -z "$already_handled"; then
- names_already_handled="$names_already_handled $name"
- dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
- dnl or AC_LIB_HAVE_LINKFLAGS call.
- uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
- eval value=\"\$HAVE_LIB$uppername\"
- if test -n "$value"; then
- if test "$value" = yes; then
- eval value=\"\$LIB$uppername\"
- test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
- eval value=\"\$LTLIB$uppername\"
- test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
- else
- dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
- dnl that this library doesn't exist. So just drop it.
- :
- fi
- else
- dnl Search the library lib$name in $additional_libdir and $LDFLAGS
- dnl and the already constructed $LIBNAME/$LTLIBNAME.
- found_dir=
- found_la=
- found_so=
- found_a=
- eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
- if test -n "$acl_shlibext"; then
- shrext=".$acl_shlibext" # typically: shrext=.so
- else
- shrext=
- fi
- if test $use_additional = yes; then
- dir="$additional_libdir"
- dnl The same code as in the loop below:
- dnl First look for a shared library.
- if test -n "$acl_shlibext"; then
- if test -f "$dir/$libname$shrext"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext"
- else
- if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
- ver=`(cd "$dir" && \
- for f in "$libname$shrext".*; do echo "$f"; done \
- | sed -e "s,^$libname$shrext\\\\.,," \
- | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
- | sed 1q ) 2>/dev/null`
- if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext.$ver"
- fi
- else
- eval library_names=\"$acl_library_names_spec\"
- for f in $library_names; do
- if test -f "$dir/$f"; then
- found_dir="$dir"
- found_so="$dir/$f"
- break
- fi
- done
- fi
- fi
- fi
- dnl Then look for a static library.
- if test "X$found_dir" = "X"; then
- if test -f "$dir/$libname.$acl_libext"; then
- found_dir="$dir"
- found_a="$dir/$libname.$acl_libext"
- fi
- fi
- if test "X$found_dir" != "X"; then
- if test -f "$dir/$libname.la"; then
- found_la="$dir/$libname.la"
- fi
- fi
- fi
- if test "X$found_dir" = "X"; then
- for x in $LDFLAGS $LTLIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- case "$x" in
- -L*)
- dir=`echo "X$x" | sed -e 's/^X-L//'`
- dnl First look for a shared library.
- if test -n "$acl_shlibext"; then
- if test -f "$dir/$libname$shrext"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext"
- else
- if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
- ver=`(cd "$dir" && \
- for f in "$libname$shrext".*; do echo "$f"; done \
- | sed -e "s,^$libname$shrext\\\\.,," \
- | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
- | sed 1q ) 2>/dev/null`
- if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext.$ver"
- fi
- else
- eval library_names=\"$acl_library_names_spec\"
- for f in $library_names; do
- if test -f "$dir/$f"; then
- found_dir="$dir"
- found_so="$dir/$f"
- break
- fi
- done
- fi
- fi
- fi
- dnl Then look for a static library.
- if test "X$found_dir" = "X"; then
- if test -f "$dir/$libname.$acl_libext"; then
- found_dir="$dir"
- found_a="$dir/$libname.$acl_libext"
- fi
- fi
- if test "X$found_dir" != "X"; then
- if test -f "$dir/$libname.la"; then
- found_la="$dir/$libname.la"
- fi
- fi
- ;;
- esac
- if test "X$found_dir" != "X"; then
- break
- fi
- done
- fi
- if test "X$found_dir" != "X"; then
- dnl Found the library.
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
- if test "X$found_so" != "X"; then
- dnl Linking with a shared library. We attempt to hardcode its
- dnl directory into the executable's runpath, unless it's the
- dnl standard /usr/lib.
- if test "$enable_rpath" = no \
- || test "X$found_dir" = "X/usr/$acl_libdirstem" \
- || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
- dnl No hardcoding is needed.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- else
- dnl Use an explicit option to hardcode DIR into the resulting
- dnl binary.
- dnl Potentially add DIR to ltrpathdirs.
- dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
- haveit=
- for x in $ltrpathdirs; do
- if test "X$x" = "X$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- ltrpathdirs="$ltrpathdirs $found_dir"
- fi
- dnl The hardcoding into $LIBNAME is system dependent.
- if test "$acl_hardcode_direct" = yes; then
- dnl Using DIR/libNAME.so during linking hardcodes DIR into the
- dnl resulting binary.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- else
- if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
- dnl Use an explicit option to hardcode DIR into the resulting
- dnl binary.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- dnl Potentially add DIR to rpathdirs.
- dnl The rpathdirs will be appended to $LIBNAME at the end.
- haveit=
- for x in $rpathdirs; do
- if test "X$x" = "X$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- rpathdirs="$rpathdirs $found_dir"
- fi
- else
- dnl Rely on "-L$found_dir".
- dnl But don't add it if it's already contained in the LDFLAGS
- dnl or the already constructed $LIBNAME
- haveit=
- for x in $LDFLAGS $LIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
- fi
- if test "$acl_hardcode_minus_L" != no; then
- dnl FIXME: Not sure whether we should use
- dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
- dnl here.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- else
- dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
- dnl here, because this doesn't fit in flags passed to the
- dnl compiler. So give up. No hardcoding. This affects only
- dnl very old systems.
- dnl FIXME: Not sure whether we should use
- dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
- dnl here.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
- fi
- fi
- fi
- fi
- else
- if test "X$found_a" != "X"; then
- dnl Linking with a static library.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
- else
- dnl We shouldn't come here, but anyway it's good to have a
- dnl fallback.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
- fi
- fi
- dnl Assume the include files are nearby.
- additional_includedir=
- case "$found_dir" in
- */$acl_libdirstem | */$acl_libdirstem/)
- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
- if test "$name" = '$1'; then
- LIB[]NAME[]_PREFIX="$basedir"
- fi
- additional_includedir="$basedir/include"
- ;;
- */$acl_libdirstem2 | */$acl_libdirstem2/)
- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
- if test "$name" = '$1'; then
- LIB[]NAME[]_PREFIX="$basedir"
- fi
- additional_includedir="$basedir/include"
- ;;
- esac
- if test "X$additional_includedir" != "X"; then
- dnl Potentially add $additional_includedir to $INCNAME.
- dnl But don't add it
- dnl 1. if it's the standard /usr/include,
- dnl 2. if it's /usr/local/include and we are using GCC on Linux,
- dnl 3. if it's already present in $CPPFLAGS or the already
- dnl constructed $INCNAME,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_includedir" != "X/usr/include"; then
- haveit=
- if test "X$additional_includedir" = "X/usr/local/include"; then
- if test -n "$GCC"; then
- case $host_os in
- linux* | gnu* | k*bsd*-gnu) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- for x in $CPPFLAGS $INC[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-I$additional_includedir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_includedir"; then
- dnl Really add $additional_includedir to $INCNAME.
- INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
- fi
- fi
- fi
- fi
- fi
- dnl Look for dependencies.
- if test -n "$found_la"; then
- dnl Read the .la file. It defines the variables
- dnl dlname, library_names, old_library, dependency_libs, current,
- dnl age, revision, installed, dlopen, dlpreopen, libdir.
- save_libdir="$libdir"
- case "$found_la" in
- */* | *\\*) . "$found_la" ;;
- *) . "./$found_la" ;;
- esac
- libdir="$save_libdir"
- dnl We use only dependency_libs.
- for dep in $dependency_libs; do
- case "$dep" in
- -L*)
- additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
- dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
- dnl But don't add it
- dnl 1. if it's the standard /usr/lib,
- dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
- dnl 3. if it's already present in $LDFLAGS or the already
- dnl constructed $LIBNAME,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
- && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
- haveit=
- if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
- || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
- if test -n "$GCC"; then
- case $host_os in
- linux* | gnu* | k*bsd*-gnu) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- haveit=
- for x in $LDFLAGS $LIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LIBNAME.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
- fi
- fi
- haveit=
- for x in $LDFLAGS $LTLIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LTLIBNAME.
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
- fi
- fi
- fi
- fi
- ;;
- -R*)
- dir=`echo "X$dep" | sed -e 's/^X-R//'`
- if test "$enable_rpath" != no; then
- dnl Potentially add DIR to rpathdirs.
- dnl The rpathdirs will be appended to $LIBNAME at the end.
- haveit=
- for x in $rpathdirs; do
- if test "X$x" = "X$dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- rpathdirs="$rpathdirs $dir"
- fi
- dnl Potentially add DIR to ltrpathdirs.
- dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
- haveit=
- for x in $ltrpathdirs; do
- if test "X$x" = "X$dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- ltrpathdirs="$ltrpathdirs $dir"
- fi
- fi
- ;;
- -l*)
- dnl Handle this in the next round.
- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
- ;;
- *.la)
- dnl Handle this in the next round. Throw away the .la's
- dnl directory; it is already contained in a preceding -L
- dnl option.
- names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
- ;;
- *)
- dnl Most likely an immediate library name.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
- ;;
- esac
- done
- fi
- else
- dnl Didn't find the library; assume it is in the system directories
- dnl known to the linker and runtime loader. (All the system
- dnl directories known to the linker should also be known to the
- dnl runtime loader, otherwise the system is severely misconfigured.)
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
- fi
- fi
- fi
- done
- done
- if test "X$rpathdirs" != "X"; then
- if test -n "$acl_hardcode_libdir_separator"; then
- dnl Weird platform: only the last -rpath option counts, the user must
- dnl pass all path elements in one option. We can arrange that for a
- dnl single library, but not when more than one $LIBNAMEs are used.
- alldirs=
- for found_dir in $rpathdirs; do
- alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
- done
- dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
- acl_save_libdir="$libdir"
- libdir="$alldirs"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
- else
- dnl The -rpath options are cumulative.
- for found_dir in $rpathdirs; do
- acl_save_libdir="$libdir"
- libdir="$found_dir"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
- done
- fi
- fi
- if test "X$ltrpathdirs" != "X"; then
- dnl When using libtool, the option that works for both libraries and
- dnl executables is -R. The -R options are cumulative.
- for found_dir in $ltrpathdirs; do
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
- done
- fi
- popdef([P_A_C_K])
- popdef([PACKLIBS])
- popdef([PACKUP])
- popdef([PACK])
- popdef([NAME])
-])
-
-dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
-dnl unless already present in VAR.
-dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
-dnl contains two or three consecutive elements that belong together.
-AC_DEFUN([AC_LIB_APPENDTOVAR],
-[
- for element in [$2]; do
- haveit=
- for x in $[$1]; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X$element"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- [$1]="${[$1]}${[$1]:+ }$element"
- fi
- done
-])
-
-dnl For those cases where a variable contains several -L and -l options
-dnl referring to unknown libraries and directories, this macro determines the
-dnl necessary additional linker options for the runtime path.
-dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
-dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
-dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
-dnl otherwise linking without libtool is assumed.
-AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
-[
- AC_REQUIRE([AC_LIB_RPATH])
- AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
- $1=
- if test "$enable_rpath" != no; then
- if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
- dnl Use an explicit option to hardcode directories into the resulting
- dnl binary.
- rpathdirs=
- next=
- for opt in $2; do
- if test -n "$next"; then
- dir="$next"
- dnl No need to hardcode the standard /usr/lib.
- if test "X$dir" != "X/usr/$acl_libdirstem" \
- && test "X$dir" != "X/usr/$acl_libdirstem2"; then
- rpathdirs="$rpathdirs $dir"
- fi
- next=
- else
- case $opt in
- -L) next=yes ;;
- -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
- dnl No need to hardcode the standard /usr/lib.
- if test "X$dir" != "X/usr/$acl_libdirstem" \
- && test "X$dir" != "X/usr/$acl_libdirstem2"; then
- rpathdirs="$rpathdirs $dir"
- fi
- next= ;;
- *) next= ;;
- esac
- fi
- done
- if test "X$rpathdirs" != "X"; then
- if test -n ""$3""; then
- dnl libtool is used for linking. Use -R options.
- for dir in $rpathdirs; do
- $1="${$1}${$1:+ }-R$dir"
- done
- else
- dnl The linker is used for linking directly.
- if test -n "$acl_hardcode_libdir_separator"; then
- dnl Weird platform: only the last -rpath option counts, the user
- dnl must pass all path elements in one option.
- alldirs=
- for dir in $rpathdirs; do
- alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
- done
- acl_save_libdir="$libdir"
- libdir="$alldirs"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- $1="$flag"
- else
- dnl The -rpath options are cumulative.
- for dir in $rpathdirs; do
- acl_save_libdir="$libdir"
- libdir="$dir"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- $1="${$1}${$1:+ }$flag"
- done
- fi
- fi
- fi
- fi
- fi
- AC_SUBST([$1])
-])
diff --git a/plugins/kimchi/m4/lib-prefix.m4 b/plugins/kimchi/m4/lib-prefix.m4
deleted file mode 100644
index 1601cea..0000000
--- a/plugins/kimchi/m4/lib-prefix.m4
+++ /dev/null
@@ -1,224 +0,0 @@
-# lib-prefix.m4 serial 7 (gettext-0.18)
-dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
-dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
-dnl require excessive bracketing.
-ifdef([AC_HELP_STRING],
-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
-[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
-
-dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
-dnl to access previously installed libraries. The basic assumption is that
-dnl a user will want packages to use other packages he previously installed
-dnl with the same --prefix option.
-dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
-dnl libraries, but is otherwise very convenient.
-AC_DEFUN([AC_LIB_PREFIX],
-[
- AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
- AC_REQUIRE([AC_PROG_CC])
- AC_REQUIRE([AC_CANONICAL_HOST])
- AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- dnl By default, look in $includedir and $libdir.
- use_additional=yes
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- AC_LIB_ARG_WITH([lib-prefix],
-[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
- --without-lib-prefix don't search for libraries in includedir and libdir],
-[
- if test "X$withval" = "Xno"; then
- use_additional=no
- else
- if test "X$withval" = "X"; then
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- else
- additional_includedir="$withval/include"
- additional_libdir="$withval/$acl_libdirstem"
- fi
- fi
-])
- if test $use_additional = yes; then
- dnl Potentially add $additional_includedir to $CPPFLAGS.
- dnl But don't add it
- dnl 1. if it's the standard /usr/include,
- dnl 2. if it's already present in $CPPFLAGS,
- dnl 3. if it's /usr/local/include and we are using GCC on Linux,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_includedir" != "X/usr/include"; then
- haveit=
- for x in $CPPFLAGS; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-I$additional_includedir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test "X$additional_includedir" = "X/usr/local/include"; then
- if test -n "$GCC"; then
- case $host_os in
- linux* | gnu* | k*bsd*-gnu) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- if test -d "$additional_includedir"; then
- dnl Really add $additional_includedir to $CPPFLAGS.
- CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
- fi
- fi
- fi
- fi
- dnl Potentially add $additional_libdir to $LDFLAGS.
- dnl But don't add it
- dnl 1. if it's the standard /usr/lib,
- dnl 2. if it's already present in $LDFLAGS,
- dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
- haveit=
- for x in $LDFLAGS; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
- if test -n "$GCC"; then
- case $host_os in
- linux*) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LDFLAGS.
- LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
- fi
- fi
- fi
- fi
- fi
-])
-
-dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
-dnl acl_final_exec_prefix, containing the values to which $prefix and
-dnl $exec_prefix will expand at the end of the configure script.
-AC_DEFUN([AC_LIB_PREPARE_PREFIX],
-[
- dnl Unfortunately, prefix and exec_prefix get only finally determined
- dnl at the end of configure.
- if test "X$prefix" = "XNONE"; then
- acl_final_prefix="$ac_default_prefix"
- else
- acl_final_prefix="$prefix"
- fi
- if test "X$exec_prefix" = "XNONE"; then
- acl_final_exec_prefix='${prefix}'
- else
- acl_final_exec_prefix="$exec_prefix"
- fi
- acl_save_prefix="$prefix"
- prefix="$acl_final_prefix"
- eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
- prefix="$acl_save_prefix"
-])
-
-dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
-dnl variables prefix and exec_prefix bound to the values they will have
-dnl at the end of the configure script.
-AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
-[
- acl_save_prefix="$prefix"
- prefix="$acl_final_prefix"
- acl_save_exec_prefix="$exec_prefix"
- exec_prefix="$acl_final_exec_prefix"
- $1
- exec_prefix="$acl_save_exec_prefix"
- prefix="$acl_save_prefix"
-])
-
-dnl AC_LIB_PREPARE_MULTILIB creates
-dnl - a variable acl_libdirstem, containing the basename of the libdir, either
-dnl "lib" or "lib64" or "lib/64",
-dnl - a variable acl_libdirstem2, as a secondary possible value for
-dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
-dnl "lib/amd64".
-AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
-[
- dnl There is no formal standard regarding lib and lib64.
- dnl On glibc systems, the current practice is that on a system supporting
- dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
- dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
- dnl the compiler's default mode by looking at the compiler's library search
- dnl path. If at least one of its elements ends in /lib64 or points to a
- dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
- dnl Otherwise we use the default, namely "lib".
- dnl On Solaris systems, the current practice is that on a system supporting
- dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
- dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
- dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
- AC_REQUIRE([AC_CANONICAL_HOST])
- acl_libdirstem=lib
- acl_libdirstem2=
- case "$host_os" in
- solaris*)
- dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
- dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
- dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
- dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
- dnl symlink is missing, so we set acl_libdirstem2 too.
- AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
- [AC_EGREP_CPP([sixtyfour bits], [
-#ifdef _LP64
-sixtyfour bits
-#endif
- ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
- ])
- if test $gl_cv_solaris_64bit = yes; then
- acl_libdirstem=lib/64
- case "$host_cpu" in
- sparc*) acl_libdirstem2=lib/sparcv9 ;;
- i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
- esac
- fi
- ;;
- *)
- searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
- if test -n "$searchpath"; then
- acl_save_IFS="${IFS= }"; IFS=":"
- for searchdir in $searchpath; do
- if test -d "$searchdir"; then
- case "$searchdir" in
- */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
- */../ | */.. )
- # Better ignore directories of this form. They are misleading.
- ;;
- *) searchdir=`cd "$searchdir" && pwd`
- case "$searchdir" in
- */lib64 ) acl_libdirstem=lib64 ;;
- esac ;;
- esac
- fi
- done
- IFS="$acl_save_IFS"
- fi
- ;;
- esac
- test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
-])
diff --git a/plugins/kimchi/m4/nls.m4 b/plugins/kimchi/m4/nls.m4
deleted file mode 100644
index 003704c..0000000
--- a/plugins/kimchi/m4/nls.m4
+++ /dev/null
@@ -1,32 +0,0 @@
-# nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper at cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible at clisp.cons.org>, 2000-2003.
-
-AC_PREREQ([2.50])
-
-AC_DEFUN([AM_NLS],
-[
- AC_MSG_CHECKING([whether NLS is requested])
- dnl Default is enabled NLS
- AC_ARG_ENABLE([nls],
- [ --disable-nls do not use Native Language Support],
- USE_NLS=$enableval, USE_NLS=yes)
- AC_MSG_RESULT([$USE_NLS])
- AC_SUBST([USE_NLS])
-])
diff --git a/plugins/kimchi/m4/po.m4 b/plugins/kimchi/m4/po.m4
deleted file mode 100644
index 8bc921d..0000000
--- a/plugins/kimchi/m4/po.m4
+++ /dev/null
@@ -1,449 +0,0 @@
-# po.m4 serial 17 (gettext-0.18)
-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper at cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible at clisp.cons.org>, 2000-2003.
-
-AC_PREREQ([2.50])
-
-dnl Checks for all prerequisites of the po subdirectory.
-AC_DEFUN([AM_PO_SUBDIRS],
-[
- AC_REQUIRE([AC_PROG_MAKE_SET])dnl
- AC_REQUIRE([AC_PROG_INSTALL])dnl
- AC_REQUIRE([AC_PROG_MKDIR_P])dnl defined by autoconf
- AC_REQUIRE([AM_NLS])dnl
-
- dnl Release version of the gettext macros. This is used to ensure that
- dnl the gettext macros and po/Makefile.in.in are in sync.
- AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
-
- dnl Perform the following tests also if --disable-nls has been given,
- dnl because they are needed for "make dist" to work.
-
- dnl Search for GNU msgfmt in the PATH.
- dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
- dnl The second test excludes FreeBSD msgfmt.
- AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
- [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
- (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
- :)
- AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
-
- dnl Test whether it is GNU msgfmt >= 0.15.
-changequote(,)dnl
- case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
- *) MSGFMT_015=$MSGFMT ;;
- esac
-changequote([,])dnl
- AC_SUBST([MSGFMT_015])
-changequote(,)dnl
- case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
- *) GMSGFMT_015=$GMSGFMT ;;
- esac
-changequote([,])dnl
- AC_SUBST([GMSGFMT_015])
-
- dnl Search for GNU xgettext 0.12 or newer in the PATH.
- dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
- dnl The second test excludes FreeBSD xgettext.
- AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
- [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
- (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
- :)
- dnl Remove leftover from FreeBSD xgettext call.
- rm -f messages.po
-
- dnl Test whether it is GNU xgettext >= 0.15.
-changequote(,)dnl
- case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
- *) XGETTEXT_015=$XGETTEXT ;;
- esac
-changequote([,])dnl
- AC_SUBST([XGETTEXT_015])
-
- dnl Search for GNU msgmerge 0.11 or newer in the PATH.
- AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
- [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
-
- dnl Installation directories.
- dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
- dnl have to define it here, so that it can be used in po/Makefile.
- test -n "$localedir" || localedir='${datadir}/locale'
- AC_SUBST([localedir])
-
- dnl Support for AM_XGETTEXT_OPTION.
- test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
- AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
-
- AC_CONFIG_COMMANDS([po-directories], [[
- for ac_file in $CONFIG_FILES; do
- # Support "outfile[:infile[:infile...]]"
- case "$ac_file" in
- *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- esac
- # PO directories have a Makefile.in generated from Makefile.in.in.
- case "$ac_file" in */Makefile.in)
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
- # Treat a directory as a PO directory if and only if it has a
- # POTFILES.in file. This allows packages to have multiple PO
- # directories under different names or in different locations.
- if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
- rm -f "$ac_dir/POTFILES"
- test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
- cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
- POMAKEFILEDEPS="POTFILES.in"
- # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
- # on $ac_dir but don't depend on user-specified configuration
- # parameters.
- if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
- # The LINGUAS file contains the set of available languages.
- if test -n "$OBSOLETE_ALL_LINGUAS"; then
- test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
- fi
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
- POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
- else
- # The set of available languages was given in configure.in.
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
- fi
- # Compute POFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
- # Compute UPDATEPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
- # Compute DUMMYPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
- # Compute GMOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
- case "$ac_given_srcdir" in
- .) srcdirpre= ;;
- *) srcdirpre='$(srcdir)/' ;;
- esac
- POFILES=
- UPDATEPOFILES=
- DUMMYPOFILES=
- GMOFILES=
- for lang in $ALL_LINGUAS; do
- POFILES="$POFILES $srcdirpre$lang.po"
- UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
- DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
- GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
- done
- # CATALOGS depends on both $ac_dir and the user's LINGUAS
- # environment variable.
- INST_LINGUAS=
- if test -n "$ALL_LINGUAS"; then
- for presentlang in $ALL_LINGUAS; do
- useit=no
- if test "%UNSET%" != "$LINGUAS"; then
- desiredlanguages="$LINGUAS"
- else
- desiredlanguages="$ALL_LINGUAS"
- fi
- for desiredlang in $desiredlanguages; do
- # Use the presentlang catalog if desiredlang is
- # a. equal to presentlang, or
- # b. a variant of presentlang (because in this case,
- # presentlang can be used as a fallback for messages
- # which are not translated in the desiredlang catalog).
- case "$desiredlang" in
- "$presentlang"*) useit=yes;;
- esac
- done
- if test $useit = yes; then
- INST_LINGUAS="$INST_LINGUAS $presentlang"
- fi
- done
- fi
- CATALOGS=
- if test -n "$INST_LINGUAS"; then
- for lang in $INST_LINGUAS; do
- CATALOGS="$CATALOGS $lang.gmo"
- done
- fi
- test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
- sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
- for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
- if test -f "$f"; then
- case "$f" in
- *.orig | *.bak | *~) ;;
- *) cat "$f" >> "$ac_dir/Makefile" ;;
- esac
- fi
- done
- fi
- ;;
- esac
- done]],
- [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
- # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
- # from automake < 1.5.
- eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
- # Capture the value of LINGUAS because we need it to compute CATALOGS.
- LINGUAS="${LINGUAS-%UNSET%}"
- ])
-])
-
-dnl Postprocesses a Makefile in a directory containing PO files.
-AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
-[
- # When this code is run, in config.status, two variables have already been
- # set:
- # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
- # - LINGUAS is the value of the environment variable LINGUAS at configure
- # time.
-
-changequote(,)dnl
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- # Find a way to echo strings without interpreting backslash.
- if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
- gt_echo='echo'
- else
- if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
- gt_echo='printf %s\n'
- else
- echo_func () {
- cat <<EOT
-$*
-EOT
- }
- gt_echo='echo_func'
- fi
- fi
-
- # A sed script that extracts the value of VARIABLE from a Makefile.
- sed_x_variable='
-# Test if the hold space is empty.
-x
-s/P/P/
-x
-ta
-# Yes it was empty. Look if we have the expected variable definition.
-/^[ ]*VARIABLE[ ]*=/{
- # Seen the first line of the variable definition.
- s/^[ ]*VARIABLE[ ]*=//
- ba
-}
-bd
-:a
-# Here we are processing a line from the variable definition.
-# Remove comment, more precisely replace it with a space.
-s/#.*$/ /
-# See if the line ends in a backslash.
-tb
-:b
-s/\\$//
-# Print the line, without the trailing backslash.
-p
-tc
-# There was no trailing backslash. The end of the variable definition is
-# reached. Clear the hold space.
-s/^.*$//
-x
-bd
-:c
-# A trailing backslash means that the variable definition continues in the
-# next line. Put a nonempty string into the hold space to indicate this.
-s/^.*$/P/
-x
-:d
-'
-changequote([,])dnl
-
- # Set POTFILES to the value of the Makefile variable POTFILES.
- sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
- POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
- # Compute POTFILES_DEPS as
- # $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
- POTFILES_DEPS=
- for file in $POTFILES; do
- POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
- done
- POMAKEFILEDEPS=""
-
- if test -n "$OBSOLETE_ALL_LINGUAS"; then
- test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
- fi
- if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
- # The LINGUAS file contains the set of available languages.
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
- POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
- else
- # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
- sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
- ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
- fi
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
- # Compute POFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
- # Compute UPDATEPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
- # Compute DUMMYPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
- # Compute GMOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
- # Compute PROPERTIESFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
- # Compute CLASSFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
- # Compute QMFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
- # Compute MSGFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
- # Compute RESOURCESDLLFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
- case "$ac_given_srcdir" in
- .) srcdirpre= ;;
- *) srcdirpre='$(srcdir)/' ;;
- esac
- POFILES=
- UPDATEPOFILES=
- DUMMYPOFILES=
- GMOFILES=
- PROPERTIESFILES=
- CLASSFILES=
- QMFILES=
- MSGFILES=
- RESOURCESDLLFILES=
- for lang in $ALL_LINGUAS; do
- POFILES="$POFILES $srcdirpre$lang.po"
- UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
- DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
- GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
- PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
- CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
- QMFILES="$QMFILES $srcdirpre$lang.qm"
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
- done
- # CATALOGS depends on both $ac_dir and the user's LINGUAS
- # environment variable.
- INST_LINGUAS=
- if test -n "$ALL_LINGUAS"; then
- for presentlang in $ALL_LINGUAS; do
- useit=no
- if test "%UNSET%" != "$LINGUAS"; then
- desiredlanguages="$LINGUAS"
- else
- desiredlanguages="$ALL_LINGUAS"
- fi
- for desiredlang in $desiredlanguages; do
- # Use the presentlang catalog if desiredlang is
- # a. equal to presentlang, or
- # b. a variant of presentlang (because in this case,
- # presentlang can be used as a fallback for messages
- # which are not translated in the desiredlang catalog).
- case "$desiredlang" in
- "$presentlang"*) useit=yes;;
- esac
- done
- if test $useit = yes; then
- INST_LINGUAS="$INST_LINGUAS $presentlang"
- fi
- done
- fi
- CATALOGS=
- JAVACATALOGS=
- QTCATALOGS=
- TCLCATALOGS=
- CSHARPCATALOGS=
- if test -n "$INST_LINGUAS"; then
- for lang in $INST_LINGUAS; do
- CATALOGS="$CATALOGS $lang.gmo"
- JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
- QTCATALOGS="$QTCATALOGS $lang.qm"
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
- done
- fi
-
- sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
- if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
- # Add dependencies that cannot be formulated as a simple suffix rule.
- for lang in $ALL_LINGUAS; do
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- cat >> "$ac_file.tmp" <<EOF
-$frobbedlang.msg: $lang.po
- @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
- \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
- done
- fi
- if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
- # Add dependencies that cannot be formulated as a simple suffix rule.
- for lang in $ALL_LINGUAS; do
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- cat >> "$ac_file.tmp" <<EOF
-$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
- @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
- \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
- done
- fi
- if test -n "$POMAKEFILEDEPS"; then
- cat >> "$ac_file.tmp" <<EOF
-Makefile: $POMAKEFILEDEPS
-EOF
- fi
- mv "$ac_file.tmp" "$ac_file"
-])
-
-dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
-AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
-[
- XGETTEXT_EXTRA_OPTIONS=
-])
-
-dnl Registers an option to be passed to xgettext in the po subdirectory.
-AC_DEFUN([AM_XGETTEXT_OPTION],
-[
- AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
- XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
-])
diff --git a/plugins/kimchi/m4/progtest.m4 b/plugins/kimchi/m4/progtest.m4
deleted file mode 100644
index 2d804ac..0000000
--- a/plugins/kimchi/m4/progtest.m4
+++ /dev/null
@@ -1,92 +0,0 @@
-# progtest.m4 serial 6 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper at cygnus.com>, 1996.
-
-AC_PREREQ([2.50])
-
-# Search path for a program which passes the given test.
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN([AM_PATH_PROG_WITH_TEST],
-[
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
- ac_executable_p="test -x"
-else
- ac_executable_p="test -f"
-fi
-rm -f conf$$.file
-
-# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL([ac_cv_path_$1],
-[case "[$]$1" in
- [[\\/]]* | ?:[[\\/]]*)
- ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
- ;;
- *)
- ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in ifelse([$5], , $PATH, [$5]); do
- IFS="$ac_save_IFS"
- test -z "$ac_dir" && ac_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
- echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
- if [$3]; then
- ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
- break 2
- fi
- fi
- done
- done
- IFS="$ac_save_IFS"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
-])dnl
- ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
- AC_MSG_RESULT([$][$1])
-else
- AC_MSG_RESULT([no])
-fi
-AC_SUBST([$1])dnl
-])
diff --git a/plugins/kimchi/mockmodel.py b/plugins/kimchi/mockmodel.py
deleted file mode 100644
index b269c26..0000000
--- a/plugins/kimchi/mockmodel.py
+++ /dev/null
@@ -1,627 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import os
-import random
-import time
-from lxml import objectify
-from lxml.builder import E
-
-from wok.exception import NotFoundError, OperationFailed
-from wok.objectstore import ObjectStore
-from wok.utils import add_task, get_next_clone_name, wok_log
-from wok.xmlutils.utils import xml_item_update
-
-import config
-import imageinfo
-import osinfo
-from model import cpuinfo
-from model.debugreports import DebugReportsModel
-from model.host import DeviceModel
-from model.libvirtstoragepool import IscsiPoolDef, NetfsPoolDef
-from model.libvirtstoragepool import StoragePoolDef
-from model.model import Model
-from model.storagepools import StoragePoolModel
-from model.storagevolumes import StorageVolumeModel, StorageVolumesModel
-from model.templates import LibvirtVMTemplate
-from model.users import PAMUsersModel
-from model.groups import PAMGroupsModel
-from vmtemplate import VMTemplate
-
-
-fake_user = {'root': 'letmein!'}
-mockmodel_defaults = {
- 'storagepool': '/plugins/kimchi/storagepools/default-pool',
- 'domain': 'test', 'arch': 'i686'
-}
-
-
-class MockModel(Model):
- _mock_vms = {}
- _mock_snapshots = {}
- _XMLDesc = libvirt.virDomain.XMLDesc
- _defineXML = libvirt.virConnect.defineXML
- _undefineDomain = libvirt.virDomain.undefine
- _libvirt_get_vol_path = LibvirtVMTemplate._get_volume_path
-
- def __init__(self, objstore_loc=None):
- # Override osinfo.defaults to ajust the values according to
- # test:///default driver
- defaults = dict(osinfo.defaults)
- defaults.update(mockmodel_defaults)
- osinfo.defaults = dict(defaults)
-
- self._mock_devices = MockDevices()
- self._mock_partitions = MockPartitions()
- self._mock_storagevolumes = MockStorageVolumes()
- self._mock_swupdate = MockSoftwareUpdate()
- self._mock_repositories = MockRepositories()
-
- cpuinfo.get_topo_capabilities = \
- MockModel.get_topo_capabilities
- libvirt.virConnect.defineXML = MockModel.domainDefineXML
- libvirt.virDomain.XMLDesc = MockModel.domainXMLDesc
- libvirt.virDomain.undefine = MockModel.undefineDomain
- libvirt.virDomain.attachDeviceFlags = MockModel.attachDeviceFlags
- libvirt.virDomain.detachDeviceFlags = MockModel.detachDeviceFlags
- libvirt.virDomain.updateDeviceFlags = MockModel.updateDeviceFlags
- libvirt.virStorageVol.resize = MockModel.volResize
- libvirt.virStorageVol.wipePattern = MockModel.volWipePattern
-
- IscsiPoolDef.prepare = NetfsPoolDef.prepare = StoragePoolDef.prepare
-
- PAMUsersModel.auth_type = 'fake'
- PAMGroupsModel.auth_type = 'fake'
-
- super(MockModel, self).__init__('test:///default', objstore_loc)
- self.objstore_loc = objstore_loc
- self.objstore = ObjectStore(objstore_loc)
-
- # The MockModel methods are instantiated on runtime according to Model
- # and BaseModel
- # Because that a normal method override will not work here
- # Instead of that we also need to do the override on runtime
- for method in dir(self):
- if method.startswith('_mock_'):
- mock_method = getattr(self, method)
- if not callable(mock_method):
- continue
-
- m = method[6:]
- model_method = getattr(self, m)
- setattr(self, '_model_' + m, model_method)
- setattr(self, m, mock_method)
-
- DeviceModel.lookup = self._mock_device_lookup
- StoragePoolModel._update_lvm_disks = self._update_lvm_disks
- StorageVolumesModel.get_list = self._mock_storagevolumes_get_list
- StorageVolumeModel.doUpload = self._mock_storagevolume_doUpload
- DebugReportsModel._gen_debugreport_file = self._gen_debugreport_file
- LibvirtVMTemplate._get_volume_path = self._get_volume_path
- VMTemplate.get_iso_info = self._probe_image
- imageinfo.probe_image = self._probe_image
-
- def reset(self):
- MockModel._mock_vms = {}
- MockModel._mock_snapshots = {}
- self._mock_swupdate = MockSoftwareUpdate()
- self._mock_repositories = MockRepositories()
-
- if hasattr(self, 'objstore'):
- self.objstore = ObjectStore(self.objstore_loc)
-
- params = {'vms': [u'test'], 'templates': [],
- 'networks': [u'default'], 'storagepools': [u'default-pool']}
-
- for res, items in params.iteritems():
- resources = getattr(self, '%s_get_list' % res)()
- for i in resources:
- if i in items:
- continue
-
- try:
- getattr(self, '%s_deactivate' % res[:-1])(i)
- except:
- pass
-
- getattr(self, '%s_delete' % res[:-1])(i)
-
- volumes = self.storagevolumes_get_list('default-pool')
- for v in volumes:
- self.storagevolume_delete('default-pool', v)
-
- @staticmethod
- def get_topo_capabilities(conn):
- # The libvirt test driver doesn't return topology.
- xml = "<topology sockets='1' cores='2' threads='2'/>"
- return ET.fromstring(xml)
-
- @staticmethod
- def domainDefineXML(conn, xml):
- name = objectify.fromstring(xml).name.text
- try:
- dom = conn.lookupByName(name)
- if not dom.isActive():
- MockModel._mock_vms[name] = xml
- except:
- pass
-
- return MockModel._defineXML(conn, xml)
-
- @staticmethod
- def domainXMLDesc(dom, flags=0):
- return MockModel._mock_vms.get(dom.name(),
- MockModel._XMLDesc(dom, flags))
-
- @staticmethod
- def undefineDomain(dom):
- name = dom.name()
- if name in MockModel._mock_vms.keys():
- del MockModel._mock_vms[dom.name()]
- return MockModel._undefineDomain(dom)
-
- @staticmethod
- def attachDeviceFlags(dom, xml, flags=0):
- old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
- root = objectify.fromstring(old_xml)
- dev = objectify.fromstring(xml)
- root.devices.append(dev)
-
- MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
-
- @staticmethod
- def _get_device_node(dom, xml):
- xpath_map = {'disk': 'target',
- 'interface': 'mac',
- 'graphics': 'listen'}
-
- dev = objectify.fromstring(xml)
- dev_id = dev.find(xpath_map[dev.tag]).items()
-
- dev_filter = ''
- for key, value in dev_id:
- dev_filter += "[@%s='%s']" % (key, value)
-
- old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
- root = objectify.fromstring(old_xml)
- devices = root.devices
-
- dev = devices.find("./%s/%s%s/.." % (dev.tag, xpath_map[dev.tag],
- dev_filter))
-
- return (root, dev)
-
- @staticmethod
- def detachDeviceFlags(dom, xml, flags=0):
- root, dev = MockModel._get_device_node(dom, xml)
- root.devices.remove(dev)
-
- MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
-
- @staticmethod
- def updateDeviceFlags(dom, xml, flags=0):
- root, old_dev = MockModel._get_device_node(dom, xml)
- root.devices.replace(old_dev, objectify.fromstring(xml))
- MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
-
- @staticmethod
- def volResize(vol, size, flags=0):
- new_xml = xml_item_update(vol.XMLDesc(0), './capacity', str(size))
- vol.delete(0)
- pool = vol.storagePoolLookupByVolume()
- pool.createXML(new_xml)
-
- @staticmethod
- def volWipePattern(vol, algorithm, flags=0):
- new_xml = xml_item_update(vol.XMLDesc(0), './allocation', '0')
- vol.delete(0)
- pool = vol.storagePoolLookupByVolume()
- pool.createXML(new_xml)
-
- def _probe_image(self, path):
- return ('unknown', 'unknown')
-
- def _get_volume_path(self, pool, vol):
- pool_info = self.storagepool_lookup(pool)
- if pool_info['type'] == 'scsi':
- return self._mock_storagevolumes.scsi_volumes[vol]['path']
-
- return MockModel._libvirt_get_vol_path(pool, vol)
-
- def _gen_debugreport_file(self, name):
- return add_task('/plugins/kimchi/debugreports/%s' % name,
- self._create_log, self.objstore, name)
-
- def _create_log(self, cb, name):
- path = config.get_debugreports_path()
- tmpf = os.path.join(path, name + '.tmp')
- realf = os.path.join(path, name + '.txt')
- length = random.randint(1000, 10000)
- with open(tmpf, 'w') as fd:
- while length:
- fd.write('I am logged')
- length = length - 1
- os.rename(tmpf, realf)
- cb("OK", True)
-
- def _update_lvm_disks(self, pool_name, disks):
- conn = self.conn.get()
- pool = conn.storagePoolLookupByName(pool_name.encode('utf-8'))
- xml = pool.XMLDesc(0)
-
- root = ET.fromstring(xml)
- source = root.xpath('./source')[0]
-
- for d in disks:
- dev = E.device(path=d)
- source.append(dev)
-
- conn.storagePoolDefineXML(ET.tostring(root), 0)
-
- def _mock_host_shutdown(self, *name):
- wok_log.info("The host system will be shutted down")
-
- def _mock_host_reboot(self, *name):
- wok_log.info("The host system will be rebooted")
-
- def _mock_storagevolumes_create(self, pool, params):
- vol_source = ['url', 'capacity']
- index_list = list(i for i in range(len(vol_source))
- if vol_source[i] in params)
- create_param = vol_source[index_list[0]]
- name = params.get('name')
- if name is None and create_param == 'url':
- params['name'] = os.path.basename(params['url'])
- del params['url']
- params['capacity'] = 1024
-
- return self._model_storagevolumes_create(pool, params)
-
- def _mock_storagevolumes_get_list(self, pool):
- pool_info = self.storagepool_lookup(pool)
- if pool_info['type'] == 'scsi':
- return self._mock_storagevolumes.scsi_volumes.keys()
-
- return self._model_storagevolumes_get_list(pool)
-
- def _mock_storagevolume_lookup(self, pool, vol):
- pool_info = self.storagepool_lookup(pool)
- if pool_info['type'] == 'scsi':
- return self._mock_storagevolumes.scsi_volumes[vol]
-
- return self._model_storagevolume_lookup(pool, vol)
-
- def _mock_storagevolume_doUpload(self, cb, vol, offset, data, data_size):
- vol_path = vol.path()
-
- # MockModel does not create the storage volume as a file
- # So create it to do the file upload
- if offset == 0:
- dirname = os.path.dirname(vol_path)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
- open(vol_path, 'w').close()
-
- try:
- with open(vol_path, 'a') as fd:
- fd.seek(offset)
- fd.write(data)
- except Exception, e:
- os.remove(vol_path)
- cb('', False)
- raise OperationFailed("KCHVOL0029E", {"err": e.message})
-
- def _mock_partitions_get_list(self):
- return self._mock_partitions.partitions.keys()
-
- def _mock_partition_lookup(self, name):
- return self._mock_partitions.partitions[name]
-
- def _mock_devices_get_list(self, _cap=None, _passthrough=None,
- _passthrough_affected_by=None):
- if _cap is None:
- return self._mock_devices.devices.keys()
-
- if _cap == 'fc_host':
- _cap = 'scsi_host'
-
- return [dev['name'] for dev in self._mock_devices.devices.values()
- if dev['device_type'] == _cap]
-
- def _mock_device_lookup(self, dev_name):
- return self._mock_devices.devices[dev_name]
-
- def _mock_packagesupdate_get_list(self):
- return self._mock_swupdate.pkgs.keys()
-
- def _mock_packageupdate_lookup(self, pkg_name):
- return self._mock_swupdate.pkgs[pkg_name]
-
- def _mock_host_swupdate(self, args=None):
- task_id = add_task('/plugins/kimchi/host/swupdate',
- self._mock_swupdate.doUpdate, self.objstore)
- return self.task_lookup(task_id)
-
- def _mock_repositories_get_list(self):
- return self._mock_repositories.repos.keys()
-
- def _mock_repositories_create(self, params):
- # Create a repo_id if not given by user. The repo_id will follow
- # the format kimchi_repo_<integer>, where integer is the number of
- # seconds since the Epoch (January 1st, 1970), in UTC.
- repo_id = params.get('repo_id', None)
- if repo_id is None:
- repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
- params.update({'repo_id': repo_id})
-
- config = params.get('config', {})
- info = {'repo_id': repo_id,
- 'baseurl': params['baseurl'],
- 'enabled': True,
- 'config': {'repo_name': config.get('repo_name', repo_id),
- 'gpgkey': config.get('gpgkey', []),
- 'gpgcheck': True,
- 'mirrorlist': params.get('mirrorlist', '')}}
- self._mock_repositories.repos[repo_id] = info
- return repo_id
-
- def _mock_repository_lookup(self, repo_id):
- return self._mock_repositories.repos[repo_id]
-
- def _mock_repository_delete(self, repo_id):
- del self._mock_repositories.repos[repo_id]
-
- def _mock_repository_enable(self, repo_id):
- self._mock_repositories.repos[repo_id]['enabled'] = True
-
- def _mock_repository_disable(self, repo_id):
- self._mock_repositories.repos[repo_id]['enabled'] = False
-
- def _mock_repository_update(self, repo_id, params):
- self._mock_repositories.repos[repo_id].update(params)
- return repo_id
-
- def _mock_vm_clone(self, name):
- new_name = get_next_clone_name(self.vms_get_list(), name)
- snapshots = MockModel._mock_snapshots.get(name, [])
- MockModel._mock_snapshots[new_name] = snapshots
- return self._model_vm_clone(name)
-
- def _mock_vmsnapshots_create(self, vm_name, params):
- name = params.get('name', unicode(int(time.time())))
- params = {'vm_name': vm_name, 'name': name}
- taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' %
- (vm_name, name), self._vmsnapshots_create_task,
- self.objstore, params)
- return self.task_lookup(taskid)
-
- def _vmsnapshots_create_task(self, cb, params):
- vm_name = params['vm_name']
- name = params['name']
- parent = u''
-
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- for sn in snapshots:
- if sn.current:
- sn.current = False
- parent = sn.name
-
- snapshots.append(MockVMSnapshot(name, {'parent': parent}))
- MockModel._mock_snapshots[vm_name] = snapshots
-
- cb('OK', True)
-
- def _mock_vmsnapshots_get_list(self, vm_name):
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- return sorted([snap.name for snap in snapshots])
-
- def _mock_currentvmsnapshot_lookup(self, vm_name):
- for sn in MockModel._mock_snapshots.get(vm_name, []):
- if sn.current:
- return sn.info
-
- def _mock_vmsnapshot_lookup(self, vm_name, name):
- for sn in MockModel._mock_snapshots.get(vm_name, []):
- if sn.name == name:
- return sn.info
-
- raise NotFoundError('KCHSNAP0003E', {'name': name, 'vm': vm_name})
-
- def _mock_vmsnapshot_delete(self, vm_name, name):
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- for sn in snapshots:
- if sn.name == name:
- del snapshots[snapshots.index(sn)]
-
- MockModel._mock_snapshots[vm_name] = snapshots
-
- def _mock_vmsnapshot_revert(self, vm_name, name):
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- for sn in snapshots:
- if sn.current:
- sn.current = False
-
- for sn in snapshots:
- if sn.name == name:
- sn.current = True
-
-
-class MockStorageVolumes(object):
- def __init__(self):
- base_path = "/dev/disk/by-path/pci-0000:0e:00.0-fc-0x20-lun"
- self.scsi_volumes = {'unit:0:0:1': {'capacity': 1024,
- 'format': 'unknown',
- 'allocation': 512,
- 'type': 'block',
- 'path': base_path + '1',
- 'used_by': []},
- 'unit:0:0:2': {'capacity': 2048,
- 'format': 'unknown',
- 'allocation': 512,
- 'type': 'block',
- 'path': base_path + '2',
- 'used_by': []}}
-
-
-class MockPartitions(object):
- def __init__(self):
- self.partitions = {"vdx": {"available": True, "name": "vdx",
- "fstype": "", "path": "/dev/vdx",
- "mountpoint": "", "type": "disk",
- "size": "2147483648"},
- "vdz": {"available": True, "name": "vdz",
- "fstype": "", "path": "/dev/vdz",
- "mountpoint": "", "type": "disk",
- "size": "2147483648"}}
-
-
-class MockDevices(object):
- def __init__(self):
- self.devices = {
- 'computer': {'device_type': 'system',
- 'firmware': {'release_date': '01/01/2012',
- 'vendor': 'LENOVO',
- 'version': 'XXXXX (X.XX )'},
- 'hardware': {'serial': 'PXXXXX',
- 'uuid':
- '9d660370-820f-4241-8731-5a60c97e8aa6',
- 'vendor': 'LENOVO',
- 'version': 'ThinkPad T420'},
- 'name': 'computer',
- 'parent': None,
- 'product': '4180XXX'},
- 'pci_0000_03_00_0': {'bus': 3,
- 'device_type': 'pci',
- 'domain': 0,
- 'driver': {'name': 'iwlwifi'},
- 'function': 0,
- 'iommuGroup': 7,
- 'name': 'pci_0000_03_00_0',
- 'parent': 'computer',
- 'path':
- '/sys/devices/pci0000:00/0000:03:00.0',
- 'product': {
- 'description':
- 'Centrino Advanced-N 6205 [Taylor Peak]',
- 'id': '0x0085'},
- 'slot': 0,
- 'vendor': {'description': 'Intel Corporation',
- 'id': '0x8086'}},
- 'pci_0000_0d_00_0': {'bus': 13,
- 'device_type': 'pci',
- 'domain': 0,
- 'driver': {'name': 'sdhci-pci'},
- 'function': 0,
- 'iommuGroup': 7,
- 'name': 'pci_0000_0d_00_0',
- 'parent': 'computer',
- 'path':
- '/sys/devices/pci0000:00/0000:0d:00.0',
- 'product': {'description':
- 'PCIe SDXC/MMC Host Controller',
- 'id': '0xe823'},
- 'slot': 0,
- 'vendor': {'description': 'Ricoh Co Ltd',
- 'id': '0x1180'}},
- 'scsi_host0': {'adapter': {'fabric_wwn': '37df6c1efa1b4388',
- 'type': 'fc_host',
- 'wwnn': 'efb6563f06434a98',
- 'wwpn': '742f32073aab45d7'},
- 'device_type': 'scsi_host',
- 'host': 0,
- 'name': 'scsi_host0',
- 'parent': 'computer',
- 'path': '/sys/devices/pci0000:00/0000:40:00.0/0'},
- 'scsi_host1': {'adapter': {'fabric_wwn': '542efa5dced34123',
- 'type': 'fc_host',
- 'wwnn': 'b7433a40c9b84092',
- 'wwpn': '25c1f485ae42497f'},
- 'device_type': 'scsi_host',
- 'host': 0,
- 'name': 'scsi_host1',
- 'parent': 'computer',
- 'path': '/sys/devices/pci0000:00/0000:40:00.0/1'},
- 'scsi_host2': {'adapter': {'fabric_wwn': '5c373c334c20478d',
- 'type': 'fc_host',
- 'wwnn': 'f2030bec4a254e6b',
- 'wwpn': '07dbca4164d44096'},
- 'device_type': 'scsi_host',
- 'host': 0,
- 'name': 'scsi_host2',
- 'parent': 'computer',
- 'path': '/sys/devices/pci0000:00/0000:40:00.0/2'}}
-
-
-class MockSoftwareUpdate(object):
- def __init__(self):
- self.pkgs = {
- 'udevmountd': {'repository': 'openSUSE-13.1-Update',
- 'version': '0.81.5-14.1',
- 'arch': 'x86_64',
- 'package_name': 'udevmountd'},
- 'sysconfig-network': {'repository': 'openSUSE-13.1-Extras',
- 'version': '0.81.5-14.1',
- 'arch': 'x86_64',
- 'package_name': 'sysconfig-network'},
- 'libzypp': {'repository': 'openSUSE-13.1-Update',
- 'version': '13.9.0-10.1',
- 'arch': 'noarch',
- 'package_name': 'libzypp'}}
- self._num2update = 3
-
- def doUpdate(self, cb, params):
- msgs = []
- for pkg in self.pkgs.keys():
- msgs.append("Updating package %s" % pkg)
- cb('\n'.join(msgs))
- time.sleep(1)
-
- time.sleep(2)
- msgs.append("All packages updated")
- cb('\n'.join(msgs), True)
-
- # After updating all packages any package should be listed to be
- # updated, so reset self._packages
- self.pkgs = {}
-
-
-class MockRepositories(object):
- def __init__(self):
- self.repos = {"kimchi_repo_1392167832":
- {"repo_id": "kimchi_repo_1392167832",
- "enabled": True,
- "baseurl": "http://www.fedora.org",
- "config": {"repo_name": "kimchi_repo_1392167832",
- "gpgkey": [],
- "gpgcheck": True,
- "mirrorlist": ""}}}
-
-
-class MockVMSnapshot(object):
- def __init__(self, name, params={}):
- self.name = name
- self.current = True
-
- self.info = {'created': params.get('created',
- unicode(int(time.time()))),
- 'name': name,
- 'parent': params.get('parent', u''),
- 'state': params.get('state', u'shutoff')}
diff --git a/plugins/kimchi/model/Makefile.am b/plugins/kimchi/model/Makefile.am
deleted file mode 100644
index f4f4750..0000000
--- a/plugins/kimchi/model/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-model_PYTHON = *.py
-
-modeldir = $(pythondir)/wok/plugins/kimchi/model
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(modeldir)
diff --git a/plugins/kimchi/model/__init__.py b/plugins/kimchi/model/__init__.py
deleted file mode 100644
index ca7ede4..0000000
--- a/plugins/kimchi/model/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/plugins/kimchi/model/config.py b/plugins/kimchi/model/config.py
deleted file mode 100644
index 464ffae..0000000
--- a/plugins/kimchi/model/config.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-from multiprocessing.pool import ThreadPool
-
-from wok.basemodel import Singleton
-from wok.config import config as kconfig
-from wok.config import get_version
-from wok.exception import NotFoundError
-from wok.utils import check_url_path, run_command, wok_log
-
-from ..config import find_qemu_binary
-from ..distroloader import DistroLoader
-from ..repositories import Repositories
-from ..screenshot import VMScreenshot
-from ..swupdate import SoftwareUpdate
-from debugreports import DebugReportsModel
-from featuretests import FeatureTests, FEATURETEST_POOL_NAME
-from featuretests import FEATURETEST_VM_NAME
-
-
-class ConfigModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- proxy_port = kconfig.get('display', 'display_proxy_port')
- return {'display_proxy_port': proxy_port,
- 'version': get_version()}
-
-
-class CapabilitiesModel(object):
- __metaclass__ = Singleton
-
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.qemu_stream = False
- self.libvirt_stream_protocols = []
- self.fc_host_support = False
- self.metadata_support = False
- self.kernel_vfio = False
- self.mem_hotplug_support = False
-
- # Subscribe function to set host capabilities to be run when cherrypy
- # server is up
- # It is needed because some features tests depends on the server
- cherrypy.engine.subscribe('start', self._set_capabilities)
-
- # Subscribe function to clean any Kimchi leftovers
- cherrypy.engine.subscribe('stop', self._clean_leftovers)
-
- def _clean_leftovers(self):
- conn = self.conn.get()
- FeatureTests.disable_libvirt_error_logging()
- try:
- dom = conn.lookupByName(FEATURETEST_VM_NAME)
- dom.undefine()
- except Exception:
- # Any exception can be ignored here
- pass
-
- try:
- pool = conn.storagePoolLookupByName(FEATURETEST_POOL_NAME)
- pool.undefine()
- except Exception:
- # Any exception can be ignored here
- pass
-
- FeatureTests.enable_libvirt_error_logging()
-
- def _set_capabilities(self):
- wok_log.info("*** Running feature tests ***")
- conn = self.conn.get()
- self.qemu_stream = FeatureTests.qemu_supports_iso_stream()
- self.nfs_target_probe = FeatureTests.libvirt_support_nfs_probe(conn)
- self.fc_host_support = FeatureTests.libvirt_support_fc_host(conn)
- self.metadata_support = FeatureTests.has_metadata_support(conn)
- self.kernel_vfio = FeatureTests.kernel_support_vfio()
- self.mem_hotplug_support = FeatureTests.has_mem_hotplug_support(conn)
-
- self.libvirt_stream_protocols = []
- for p in ['http', 'https', 'ftp', 'ftps', 'tftp']:
- if FeatureTests.libvirt_supports_iso_stream(conn, p):
- self.libvirt_stream_protocols.append(p)
-
- wok_log.info("*** Feature tests completed ***")
- _set_capabilities.priority = 90
-
- def _qemu_support_spice(self):
- qemu_path = find_qemu_binary(find_emulator=True)
- out, err, rc = run_command(['ldd', qemu_path])
- if rc != 0:
- wok_log.error('Failed to find qemu binary dependencies: %s',
- err)
- return False
- for line in out.split('\n'):
- if line.lstrip().startswith('libspice-server.so'):
- return True
- return False
-
- def lookup(self, *ident):
- report_tool = DebugReportsModel.get_system_report_tool()
- try:
- SoftwareUpdate()
- except Exception:
- update_tool = False
- else:
- update_tool = True
-
- try:
- repo = Repositories()
- except Exception:
- repo_mngt_tool = None
- else:
- repo_mngt_tool = repo._pkg_mnger.TYPE
-
- return {'libvirt_stream_protocols': self.libvirt_stream_protocols,
- 'qemu_spice': self._qemu_support_spice(),
- 'qemu_stream': self.qemu_stream,
- 'screenshot': VMScreenshot.get_stream_test_result(),
- 'system_report_tool': bool(report_tool),
- 'update_tool': update_tool,
- 'repo_mngt_tool': repo_mngt_tool,
- 'federation': kconfig.get("server", "federation"),
- 'auth': kconfig.get("authentication", "method"),
- 'kernel_vfio': self.kernel_vfio,
- 'nm_running': FeatureTests.is_nm_running(),
- 'mem_hotplug_support': self.mem_hotplug_support
- }
-
-
-class DistrosModel(object):
- def __init__(self, **kargs):
- distroloader = DistroLoader()
- self.distros = distroloader.get()
-
- def get_list(self):
- def validate_distro(distro):
- if check_url_path(distro['path']):
- return distro['name']
-
- n_processes = len(self.distros.keys())
- pool = ThreadPool(processes=n_processes)
- map_res = pool.map_async(validate_distro, self.distros.values())
- pool.close()
- pool.join()
- res = list(set(map_res.get()) - set([None]))
- return sorted(res)
-
-
-class DistroModel(object):
- def __init__(self, **kargs):
- self._distros = DistrosModel()
-
- def lookup(self, name):
- try:
- return self._distros.distros[name]
- except KeyError:
- raise NotFoundError("KCHDISTRO0001E", {'name': name})
diff --git a/plugins/kimchi/model/cpuinfo.py b/plugins/kimchi/model/cpuinfo.py
deleted file mode 100644
index 299e445..0000000
--- a/plugins/kimchi/model/cpuinfo.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import platform
-from xml.etree import ElementTree as ET
-
-from wok.exception import InvalidParameter, InvalidOperation
-from wok.utils import run_command, wok_log
-
-
-ARCH = 'power' if platform.machine().startswith('ppc') else 'x86'
-
-
-def get_topo_capabilities(connect):
- """
- This helper function exists solely to be overridden for
- mockmodel tests. Since other modules use getCapabilies(),
- it can't be overridden directly.
- """
- xml = connect.getCapabilities()
- capabilities = ET.fromstring(xml)
- return capabilities.find('host').find('cpu').find('topology')
-
-
-class CPUInfoModel(object):
- """
- Get information about a CPU for hyperthreading (on x86)
- or SMT (on POWER) for logic when creating templates and VMs.
- """
-
- def __init__(self, **kargs):
- self.guest_threads_enabled = False
- self.sockets = 0
- self.cores_present = 0
- self.cores_available = 0
- self.cores_per_socket = 0
- self.threads_per_core = 0
- self.max_threads = 0
-
- self.conn = kargs['conn']
- libvirt_topology = None
- try:
- connect = self.conn.get()
- libvirt_topology = get_topo_capabilities(connect)
- except Exception as e:
- wok_log.info("Unable to get CPU topology capabilities: %s"
- % e.message)
- return
- if libvirt_topology is None:
- wok_log.info("cpu_info topology not supported.")
- return
-
- if ARCH == 'power':
- # IBM PowerPC
- self.guest_threads_enabled = True
- out, error, rc = run_command(['ppc64_cpu', '--smt'])
- if rc or 'on' in out:
- # SMT has to be disabled for guest to use threads as CPUs.
- # rc is always zero, whether SMT is off or on.
- self.guest_threads_enabled = False
- out, error, rc = run_command(['ppc64_cpu', '--cores-present'])
- if not rc:
- self.cores_present = int(out.split()[-1])
- out, error, rc = run_command(['ppc64_cpu', '--cores-on'])
- if not rc:
- self.cores_available = int(out.split()[-1])
- out, error, rc = run_command(['ppc64_cpu', '--threads-per-core'])
- if not rc:
- self.threads_per_core = int(out.split()[-1])
- self.sockets = self.cores_present/self.threads_per_core
- if self.sockets == 0:
- self.sockets = 1
- self.cores_per_socket = self.cores_present/self.sockets
- else:
- # Intel or AMD
- self.guest_threads_enabled = True
- self.sockets = int(libvirt_topology.get('sockets'))
- self.cores_per_socket = int(libvirt_topology.get('cores'))
- self.cores_present = self.cores_per_socket * self.sockets
- self.cores_available = self.cores_present
- self.threads_per_core = int(libvirt_topology.get('threads'))
-
- def lookup(self, ident):
- return {
- 'guest_threads_enabled': self.guest_threads_enabled,
- 'sockets': self.sockets,
- 'cores_per_socket': self.cores_per_socket,
- 'cores_present': self.cores_present,
- 'cores_available': self.cores_available,
- 'threads_per_core': self.threads_per_core,
- }
-
- def check_topology(self, vcpus, topology):
- """
- param vcpus: should be an integer
- param iso_path: the path of the guest ISO
- param topology: {'sockets': x, 'cores': x, 'threads': x}
- """
- sockets = topology['sockets']
- cores = topology['cores']
- threads = topology['threads']
-
- if not self.guest_threads_enabled:
- raise InvalidOperation("KCHCPUINF0003E")
- if vcpus != sockets * cores * threads:
- raise InvalidParameter("KCHCPUINF0002E")
- if vcpus > self.cores_available * self.threads_per_core:
- raise InvalidParameter("KCHCPUINF0001E")
- if threads > self.threads_per_core:
- raise InvalidParameter("KCHCPUINF0002E")
diff --git a/plugins/kimchi/model/debugreports.py b/plugins/kimchi/model/debugreports.py
deleted file mode 100644
index 48e6b26..0000000
--- a/plugins/kimchi/model/debugreports.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import fnmatch
-import glob
-import logging
-import os
-import shutil
-import subprocess
-import time
-
-from wok.exception import InvalidParameter, NotFoundError, OperationFailed
-from wok.exception import WokException
-from wok.utils import add_task, wok_log
-from wok.utils import run_command
-from wok.model.tasks import TaskModel
-
-from .. import config
-
-
-class DebugReportsModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
-
- def create(self, params):
- ident = params.get('name').strip()
- # Generate a name with time and millisec precision, if necessary
- if ident is None or ident == "":
- ident = 'report-' + str(int(time.time() * 1000))
- else:
- if ident in self.get_list():
- raise InvalidParameter("KCHDR0008E", {"name": ident})
- taskid = self._gen_debugreport_file(ident)
- return self.task.lookup(taskid)
-
- def get_list(self):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, '*.*')
- file_lists = glob.glob(file_pattern)
- file_lists = [os.path.split(file)[1] for file in file_lists]
- name_lists = [file.split('.', 1)[0] for file in file_lists]
-
- return name_lists
-
- def _gen_debugreport_file(self, name):
- gen_cmd = self.get_system_report_tool()
-
- if gen_cmd is not None:
- return add_task('/plugins/kimchi/debugreports/%s' % name, gen_cmd,
- self.objstore, name)
-
- raise OperationFailed("KCHDR0002E")
-
- @staticmethod
- def sosreport_generate(cb, name):
- def log_error(e):
- log = logging.getLogger('Model')
- log.warning('Exception in generating debug file: %s', e)
-
- try:
- command = ['sosreport', '--batch', '--name=%s' % name]
- output, error, retcode = run_command(command)
-
- if retcode != 0:
- raise OperationFailed("KCHDR0003E", {'name': name,
- 'err': retcode})
-
- # SOSREPORT might create file in /tmp or /var/tmp
- # FIXME: The right way should be passing the tar.xz file directory
- # though the parameter '--tmp-dir', but it is failing in Fedora 20
- patterns = ['/tmp/sosreport-%s-*', '/var/tmp/sosreport-%s-*']
- reports = []
- reportFile = None
- for p in patterns:
- reports = reports + [f for f in glob.glob(p % name)]
- for f in reports:
- if not fnmatch.fnmatch(f, '*.md5'):
- reportFile = f
- break
- # Some error in sosreport happened
- if reportFile is None:
- wok_log.error('Debug report file not found. See sosreport '
- 'output for detail:\n%s', output)
- fname = (patterns[0] % name).split('/')[-1]
- raise OperationFailed('KCHDR0004E', {'name': fname})
-
- md5_report_file = reportFile + '.md5'
- report_file_extension = '.' + reportFile.split('.', 1)[1]
- path = config.get_debugreports_path()
- target = os.path.join(path, name + report_file_extension)
- # Moving report
- msg = 'Moving debug report file "%s" to "%s"' % (reportFile,
- target)
- wok_log.info(msg)
- shutil.move(reportFile, target)
- # Deleting md5
- msg = 'Deleting report md5 file: "%s"' % (md5_report_file)
- wok_log.info(msg)
- with open(md5_report_file) as f:
- md5 = f.read().strip()
- wok_log.info('Md5 file content: "%s"', md5)
- os.remove(md5_report_file)
- cb('OK', True)
- return
-
- except WokException as e:
- log_error(e)
- raise
-
- except OSError as e:
- log_error(e)
- raise
-
- except Exception, e:
- # No need to call cb to update the task status here.
- # The task object will catch the exception raised here
- # and update the task status there
- log_error(e)
- raise OperationFailed("KCHDR0005E", {'name': name, 'err': e})
-
- @staticmethod
- def get_system_report_tool():
- # Please add new possible debug report command here
- # and implement the report generating function
- # based on the new report command
- report_tools = ({'cmd': 'sosreport --help',
- 'fn': DebugReportsModel.sosreport_generate},)
-
- # check if the command can be found by shell one by one
- for helper_tool in report_tools:
- try:
- retcode = subprocess.call(helper_tool['cmd'], shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- if retcode == 0:
- return helper_tool['fn']
- except Exception, e:
- wok_log.info('Exception running command: %s', e)
-
- return None
-
-
-class DebugReportModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, name)
- file_pattern = file_pattern + '.*'
- try:
- file_target = glob.glob(file_pattern)[0]
- except IndexError:
- raise NotFoundError("KCHDR0001E", {'name': name})
-
- ctime = os.stat(file_target).st_mtime
- ctime = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(ctime))
- file_target = os.path.split(file_target)[-1]
- file_target = os.path.join("plugins/kimchi/data/debugreports",
- file_target)
- return {'uri': file_target,
- 'ctime': ctime}
-
- def update(self, name, params):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, name + '.*')
- try:
- file_source = glob.glob(file_pattern)[0]
- except IndexError:
- raise NotFoundError("KCHDR0001E", {'name': name})
-
- file_target = file_source.replace(name, params['name'])
- if os.path.isfile(file_target):
- raise InvalidParameter('KCHDR0008E', {'name': params['name']})
-
- shutil.move(file_source, file_target)
- wok_log.info('%s renamed to %s' % (file_source, file_target))
- return params['name']
-
- def delete(self, name):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, name + '.*')
- try:
- file_target = glob.glob(file_pattern)[0]
- except IndexError:
- raise NotFoundError("KCHDR0001E", {'name': name})
-
- os.remove(file_target)
-
-
-class DebugReportContentModel(object):
- def __init__(self, **kargs):
- self._debugreport = DebugReportModel()
-
- def lookup(self, name):
- return self._debugreport.lookup(name)
diff --git a/plugins/kimchi/model/diskutils.py b/plugins/kimchi/model/diskutils.py
deleted file mode 100644
index 350e6eb..0000000
--- a/plugins/kimchi/model/diskutils.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.exception import OperationFailed, NotFoundError
-from wok.utils import wok_log
-
-from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
-from vms import VMModel, VMsModel
-
-"""
- Functions that multiple storage-related models (e.g. VMStoragesModel,
- VolumesModel) will need.
-"""
-
-
-def get_disk_used_by(objstore, conn, path):
- try:
- with objstore as session:
- try:
- used_by = session.get('storagevolume', path)['used_by']
- except (KeyError, NotFoundError):
- wok_log.info('Volume %s not found in obj store.' % path)
- used_by = []
- # try to find this volume in existing vm
- vms_list = VMsModel.get_vms(conn)
- for vm in vms_list:
- dom = VMModel.get_vm(vm, conn)
- storages = get_vm_disks(dom)
- for disk in storages.keys():
- d_info = get_vm_disk_info(dom, disk)
- if path == d_info['path']:
- used_by.append(vm)
- try:
- session.store('storagevolume', path,
- {'used_by': used_by})
- except Exception as e:
- # Let the exception be raised. If we allow disks'
- # used_by to be out of sync, data corruption could
- # occour if a disk is added to two guests
- # unknowingly.
- wok_log.error('Unable to store storage volume id in'
- ' objectstore due error: %s',
- e.message)
- raise OperationFailed('KCHVOL0017E',
- {'err': e.message})
- except Exception as e:
- # This exception is going to catch errors returned by 'with',
- # specially ones generated by 'session.store'. It is outside
- # to avoid conflict with the __exit__ function of 'with'
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
- return used_by
-
-
-def set_disk_used_by(objstore, path, new_used_by):
- try:
- with objstore as session:
- session.store('storagevolume', path, {'used_by': new_used_by})
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
diff --git a/plugins/kimchi/model/featuretests.py b/plugins/kimchi/model/featuretests.py
deleted file mode 100644
index c53d1aa..0000000
--- a/plugins/kimchi/model/featuretests.py
+++ /dev/null
@@ -1,259 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import libvirt
-import lxml.etree as ET
-import platform
-import subprocess
-from lxml.builder import E
-
-from wok.rollbackcontext import RollbackContext
-from wok.utils import run_command, servermethod, wok_log
-
-
-FEATURETEST_VM_NAME = "FEATURETEST_VM"
-FEATURETEST_POOL_NAME = "FEATURETEST_POOL"
-
-ISO_STREAM_XML = """
-<domain type='%(domain)s'>
- <name>%(name)s</name>
- <memory unit='KiB'>1048576</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='cdrom'/>
- </os>
- <devices>
- <disk type='network' device='cdrom'>
- <driver name='qemu' type='raw'/>
- <source protocol='%(protocol)s' name='/url/path/to/iso/file'>
- <host name='host.name' port='1234'/>
- </source>
- <target dev='hdc' bus='ide'/>
- <readonly/>
- <alias name='ide0-1-0'/>
- <address type='drive' controller='0' bus='1' target='0' unit='0'/>
- </disk>
- </devices>
-</domain>"""
-
-SIMPLE_VM_XML = """
-<domain type='%(domain)s'>
- <name>%(name)s</name>
- <memory unit='KiB'>10240</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- </os>
-</domain>"""
-
-MAXMEM_VM_XML = """
-<domain type='%(domain)s'>
- <name>%(name)s</name>
- <maxMemory slots='1' unit='KiB'>20480</maxMemory>
- <memory unit='KiB'>10240</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- </os>
-</domain>"""
-
-DEV_MEM_XML = """
-<memory model='dimm'>
- <target>
- <size unit='KiB'>10240</size>
- <node>0</node>
- </target>
-</memory>"""
-
-SCSI_FC_XML = """
-<pool type='scsi'>
- <name>%(name)s</name>
- <source>
- <adapter type='fc_host' wwnn='1234567890abcdef' wwpn='abcdef1234567890'/>
- </source>
- <target>
- <path>/dev/disk/by-path</path>
- </target>
-</pool>
-"""
-
-
-class FeatureTests(object):
-
- @staticmethod
- def disable_libvirt_error_logging():
- def libvirt_errorhandler(userdata, error):
- # A libvirt error handler to ignore annoying messages in stderr
- pass
-
- # Filter functions are enable only in production env
- if cherrypy.config.get('environment') != 'production':
- return
- # Register the error handler to hide libvirt error in stderr
- libvirt.registerErrorHandler(f=libvirt_errorhandler, ctx=None)
-
- @staticmethod
- def enable_libvirt_error_logging():
- # Filter functions are enable only in production env
- if cherrypy.config.get('environment') != 'production':
- return
- # Unregister the error handler
- libvirt.registerErrorHandler(f=None, ctx=None)
-
- @staticmethod
- def libvirt_supports_iso_stream(conn, protocol):
- conn_type = conn.getType().lower()
- domain_type = 'test' if conn_type == 'test' else 'kvm'
- arch = 'i686' if conn_type == 'test' else platform.machine()
- arch = 'ppc64' if arch == 'ppc64le' else arch
- xml = ISO_STREAM_XML % {'name': FEATURETEST_VM_NAME,
- 'domain': domain_type, 'protocol': protocol,
- 'arch': arch}
- try:
- FeatureTests.disable_libvirt_error_logging()
- dom = conn.defineXML(xml)
- dom.undefine()
- return True
- except libvirt.libvirtError, e:
- wok_log.error(e.message)
- return False
- finally:
- FeatureTests.enable_libvirt_error_logging()
-
- @staticmethod
- def libvirt_support_nfs_probe(conn):
- def _get_xml():
- obj = E.source(E.host(name='localhost'), E.format(type='nfs'))
- xml = ET.tostring(obj)
- return xml
- try:
- FeatureTests.disable_libvirt_error_logging()
- conn.findStoragePoolSources('netfs', _get_xml(), 0)
- except libvirt.libvirtError as e:
- wok_log.error(e.message)
- if e.get_error_code() == 38:
- # if libvirt cannot find showmount,
- # it returns 38--general system call failure
- return False
- finally:
- FeatureTests.enable_libvirt_error_logging()
-
- return True
-
- @staticmethod
- @servermethod
- def qemu_supports_iso_stream():
- host = cherrypy.server.socket_host
- port = cherrypy.server.socket_port
- cmd = "qemu-io -r http://%s:%d/images/icon-fedora.png \
- -c 'read -v 0 512'" % (host, port)
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE, shell=True)
- stdout, stderr = proc.communicate()
- return len(stderr) == 0
-
- @staticmethod
- def libvirt_support_fc_host(conn):
- try:
- FeatureTests.disable_libvirt_error_logging()
- pool = None
- pool_xml = SCSI_FC_XML % {'name': FEATURETEST_POOL_NAME}
- pool = conn.storagePoolDefineXML(pool_xml, 0)
- except libvirt.libvirtError as e:
- if e.get_error_code() == 27:
- # Libvirt requires adapter name, not needed when supports to FC
- return False
- finally:
- FeatureTests.enable_libvirt_error_logging()
- pool is None or pool.undefine()
- return True
-
- @staticmethod
- def has_metadata_support(conn):
- KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/"
- KIMCHI_NAMESPACE = "kimchi"
- with RollbackContext() as rollback:
- FeatureTests.disable_libvirt_error_logging()
- rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
- conn_type = conn.getType().lower()
- domain_type = 'test' if conn_type == 'test' else 'kvm'
- arch = 'i686' if conn_type == 'test' else platform.machine()
- arch = 'ppc64' if arch == 'ppc64le' else arch
- dom = conn.defineXML(SIMPLE_VM_XML % {'name': FEATURETEST_VM_NAME,
- 'domain': domain_type,
- 'arch': arch})
- rollback.prependDefer(dom.undefine)
- try:
- dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
- "<metatest/>", KIMCHI_NAMESPACE,
- KIMCHI_META_URL,
- flags=libvirt.VIR_DOMAIN_AFFECT_CURRENT)
- return True
- except libvirt.libvirtError:
- return False
-
- @staticmethod
- def kernel_support_vfio():
- out, err, rc = run_command(['modprobe', 'vfio-pci'])
- if rc != 0:
- wok_log.warning("Unable to load Kernal module vfio-pci.")
- return False
- return True
-
- @staticmethod
- def is_nm_running():
- '''Tries to determine whether NetworkManager is running.'''
-
- out, err, rc = run_command(['nmcli', 'dev', 'status'])
- if rc != 0:
- return False
-
- return True
-
- @staticmethod
- def has_mem_hotplug_support(conn):
- '''
- A memory device can be hot-plugged or hot-unplugged since libvirt
- version 1.2.14.
- '''
- # Libvirt < 1.2.14 does not support memory devices, so firstly, check
- # its version, then try to attach a device. These steps avoid errors
- # with Libvirt 'test' driver for KVM
- version = 1000000*1 + 1000*2 + 14
- if libvirt.getVersion() < version:
- return False
-
- with RollbackContext() as rollback:
- FeatureTests.disable_libvirt_error_logging()
- rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
- conn_type = conn.getType().lower()
- domain_type = 'test' if conn_type == 'test' else 'kvm'
- arch = 'i686' if conn_type == 'test' else platform.machine()
- arch = 'ppc64' if arch == 'ppc64le' else arch
- dom = conn.defineXML(MAXMEM_VM_XML % {'name': FEATURETEST_VM_NAME,
- 'domain': domain_type,
- 'arch': arch})
- rollback.prependDefer(dom.undefine)
- try:
- dom.attachDeviceFlags(DEV_MEM_XML,
- libvirt.VIR_DOMAIN_MEM_CONFIG)
- return True
- except libvirt.libvirtError:
- return False
diff --git a/plugins/kimchi/model/groups.py b/plugins/kimchi/model/groups.py
deleted file mode 100644
index fc63d68..0000000
--- a/plugins/kimchi/model/groups.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import grp
-
-from wok.config import config
-
-
-class GroupsModel(object):
- def __init__(self, **args):
- auth_type = config.get("authentication", "method")
- for klass in GroupsModel.__subclasses__():
- if auth_type == klass.auth_type:
- self.grp = klass(**args)
-
- def get_list(self, **args):
- if hasattr(self.grp, '_get_list'):
- return self.grp._get_list(**args)
- else:
- return list()
-
- def validate(self, gid):
- return self.grp._validate(gid)
-
-
-class PAMGroupsModel(GroupsModel):
- auth_type = 'pam'
-
- def __init__(self, **kargs):
- pass
-
- def _get_list(self):
- return sorted([group.gr_name
- for group in grp.getgrall()])
-
- def _validate(self, gid):
- try:
- grp.getgrnam(gid)
- except KeyError:
- return False
- return True
-
-
-class LDAPGroupsModel(GroupsModel):
- auth_type = 'ldap'
-
- def __init__(self, **kargs):
- pass
-
- def _validate(self, gid):
- return False
diff --git a/plugins/kimchi/model/host.py b/plugins/kimchi/model/host.py
deleted file mode 100644
index 75d4de0..0000000
--- a/plugins/kimchi/model/host.py
+++ /dev/null
@@ -1,476 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import os
-import platform
-import psutil
-import time
-from cherrypy.process.plugins import BackgroundTask
-from collections import defaultdict
-
-from wok.basemodel import Singleton
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import add_task, wok_log
-from wok.xmlutils.utils import xpath_get_text
-from wok.model.tasks import TaskModel
-
-import hostdev
-from .. import disks
-from .. import netinfo
-from ..repositories import Repositories
-from ..swupdate import SoftwareUpdate
-from config import CapabilitiesModel
-from vms import DOM_STATE_MAP
-
-
-HOST_STATS_INTERVAL = 1
-
-
-class HostModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
- self.host_info = self._get_host_info()
-
- def _get_ppc_cpu_info(self):
- res = {}
- with open('/proc/cpuinfo') as f:
- for line in f.xreadlines():
- # Parse CPU, CPU's revision and CPU's clock information
- for key in ['cpu', 'revision', 'clock']:
- if key in line:
- info = line.split(':')[1].strip()
- if key == 'clock':
- value = float(info.split('MHz')[0].strip()) / 1000
- else:
- value = info.split('(')[0].strip()
- res[key] = value
-
- # Power machines show, for each cpu/core, a block with
- # all cpu information. Here we control the scan of the
- # necessary information (1st block provides
- # everything), skipping the function when find all
- # information.
- if len(res.keys()) == 3:
- return "%(cpu)s (%(revision)s) @ %(clock)s GHz\
- " % res
-
- return ""
-
- def _get_host_info(self):
- res = {}
- if platform.machine().startswith('ppc'):
- res['cpu_model'] = self._get_ppc_cpu_info()
- else:
- with open('/proc/cpuinfo') as f:
- for line in f.xreadlines():
- if "model name" in line:
- res['cpu_model'] = line.split(':')[1].strip()
- break
-
- res['cpus'] = 0
- res['memory'] = 0L
-
- # Include IBM PowerKVM name to supported distro names
- _sup_distros = platform._supported_dists + ('ibm_powerkvm',)
- # 'fedora' '17' 'Beefy Miracle'
- distro, version, codename = platform.linux_distribution(
- supported_dists=_sup_distros)
- res['os_distro'] = distro
- res['os_version'] = version
- res['os_codename'] = unicode(codename, "utf-8")
-
- return res
-
- def lookup(self, *name):
- cpus = psutil.NUM_CPUS
-
- # psutil is unstable on how to get the number of
- # cpus, different versions call it differently
- if hasattr(psutil, 'cpu_count'):
- cpus = psutil.cpu_count()
-
- elif hasattr(psutil, '_psplatform'):
- for method_name in ['_get_num_cpus', 'get_num_cpus']:
-
- method = getattr(psutil._psplatform, method_name, None)
- if method is not None:
- cpus = method()
- break
-
- self.host_info['cpus'] = cpus
- self.host_info['memory'] = psutil.phymem_usage().total
- return self.host_info
-
- def swupdate(self, *name):
- try:
- swupdate = SoftwareUpdate()
- except:
- raise OperationFailed('KCHPKGUPD0004E')
-
- pkgs = swupdate.getNumOfUpdates()
- if pkgs == 0:
- raise OperationFailed('KCHPKGUPD0001E')
-
- wok_log.debug('Host is going to be updated.')
- taskid = add_task('/plugins/kimchi/host/swupdate', swupdate.doUpdate,
- self.objstore, None)
- return self.task.lookup(taskid)
-
- def shutdown(self, args=None):
- # Check for running vms before shutdown
- running_vms = self._get_vms_list_by_state('running')
- if len(running_vms) > 0:
- raise OperationFailed("KCHHOST0001E")
-
- wok_log.info('Host is going to shutdown.')
- os.system('shutdown -h now')
-
- def reboot(self, args=None):
- # Find running VMs
- running_vms = self._get_vms_list_by_state('running')
- if len(running_vms) > 0:
- raise OperationFailed("KCHHOST0002E")
-
- wok_log.info('Host is going to reboot.')
- os.system('reboot')
-
- def _get_vms_list_by_state(self, state):
- conn = self.conn.get()
- return [dom.name().decode('utf-8')
- for dom in conn.listAllDomains(0)
- if (DOM_STATE_MAP[dom.info()[0]]) == state]
-
-
-class HostStatsModel(object):
- __metaclass__ = Singleton
-
- def __init__(self, **kargs):
- self.host_stats = defaultdict(list)
- self.host_stats_thread = BackgroundTask(HOST_STATS_INTERVAL,
- self._update_host_stats)
- self.host_stats_thread.start()
-
- def lookup(self, *name):
- return {'cpu_utilization': self.host_stats['cpu_utilization'][-1],
- 'memory': self.host_stats['memory'][-1],
- 'disk_read_rate': self.host_stats['disk_read_rate'][-1],
- 'disk_write_rate': self.host_stats['disk_write_rate'][-1],
- 'net_recv_rate': self.host_stats['net_recv_rate'][-1],
- 'net_sent_rate': self.host_stats['net_sent_rate'][-1]}
-
- def _update_host_stats(self):
- preTimeStamp = self.host_stats['timestamp']
- timestamp = time.time()
- # FIXME when we upgrade psutil, we can get uptime by psutil.uptime
- # we get uptime by float(open("/proc/uptime").readline().split()[0])
- # and calculate the first io_rate after the OS started.
- with open("/proc/uptime") as time_f:
- seconds = (timestamp - preTimeStamp if preTimeStamp else
- float(time_f.readline().split()[0]))
-
- self.host_stats['timestamp'] = timestamp
- self._get_host_disk_io_rate(seconds)
- self._get_host_network_io_rate(seconds)
-
- self._get_percentage_host_cpu_usage()
- self._get_host_memory_stats()
-
- # store only 60 stats (1 min)
- for key, value in self.host_stats.iteritems():
- if isinstance(value, list):
- if len(value) == 60:
- self.host_stats[key] = value[10:]
-
- def _get_percentage_host_cpu_usage(self):
- # This is cpu usage producer. This producer will calculate the usage
- # at an interval of HOST_STATS_INTERVAL.
- # The psutil.cpu_percent works as non blocking.
- # psutil.cpu_percent maintains a cpu time sample.
- # It will update the cpu time sample when it is called.
- # So only this producer can call psutil.cpu_percent in kimchi.
- self.host_stats['cpu_utilization'].append(psutil.cpu_percent(None))
-
- def _get_host_memory_stats(self):
- virt_mem = psutil.virtual_memory()
- # available:
- # the actual amount of available memory that can be given
- # instantly to processes that request more memory in bytes; this
- # is calculated by summing different memory values depending on
- # the platform (e.g. free + buffers + cached on Linux)
- memory_stats = {'total': virt_mem.total,
- 'free': virt_mem.free,
- 'cached': virt_mem.cached,
- 'buffers': virt_mem.buffers,
- 'avail': virt_mem.available}
- self.host_stats['memory'].append(memory_stats)
-
- def _get_host_disk_io_rate(self, seconds):
- disk_read_bytes = self.host_stats['disk_read_bytes']
- disk_write_bytes = self.host_stats['disk_write_bytes']
- prev_read_bytes = disk_read_bytes[-1] if disk_read_bytes else 0
- prev_write_bytes = disk_write_bytes[-1] if disk_write_bytes else 0
-
- disk_io = psutil.disk_io_counters(False)
- read_bytes = disk_io.read_bytes
- write_bytes = disk_io.write_bytes
-
- rd_rate = int(float(read_bytes - prev_read_bytes) / seconds + 0.5)
- wr_rate = int(float(write_bytes - prev_write_bytes) / seconds + 0.5)
-
- self.host_stats['disk_read_rate'].append(rd_rate)
- self.host_stats['disk_write_rate'].append(wr_rate)
- self.host_stats['disk_read_bytes'].append(read_bytes)
- self.host_stats['disk_write_bytes'].append(write_bytes)
-
- def _get_host_network_io_rate(self, seconds):
- net_recv_bytes = self.host_stats['net_recv_bytes']
- net_sent_bytes = self.host_stats['net_sent_bytes']
- prev_recv_bytes = net_recv_bytes[-1] if net_recv_bytes else 0
- prev_sent_bytes = net_sent_bytes[-1] if net_sent_bytes else 0
-
- net_ios = psutil.network_io_counters(True)
- recv_bytes = 0
- sent_bytes = 0
- for key in set(netinfo.nics() +
- netinfo.wlans()) & set(net_ios.iterkeys()):
- recv_bytes = recv_bytes + net_ios[key].bytes_recv
- sent_bytes = sent_bytes + net_ios[key].bytes_sent
-
- rx_rate = int(float(recv_bytes - prev_recv_bytes) / seconds + 0.5)
- tx_rate = int(float(sent_bytes - prev_sent_bytes) / seconds + 0.5)
-
- self.host_stats['net_recv_rate'].append(rx_rate)
- self.host_stats['net_sent_rate'].append(tx_rate)
- self.host_stats['net_recv_bytes'].append(recv_bytes)
- self.host_stats['net_sent_bytes'].append(sent_bytes)
-
-
-class HostStatsHistoryModel(object):
- def __init__(self, **kargs):
- self.history = HostStatsModel(**kargs)
-
- def lookup(self, *name):
- return {'cpu_utilization': self.history.host_stats['cpu_utilization'],
- 'memory': self.history.host_stats['memory'],
- 'disk_read_rate': self.history.host_stats['disk_read_rate'],
- 'disk_write_rate': self.history.host_stats['disk_write_rate'],
- 'net_recv_rate': self.history.host_stats['net_recv_rate'],
- 'net_sent_rate': self.history.host_stats['net_sent_rate']}
-
-
-class PartitionsModel(object):
- def __init__(self, **kargs):
- pass
-
- def get_list(self):
- result = disks.get_partitions_names()
- return result
-
-
-class PartitionModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- return disks.get_partition_details(name)
-
-
-class DevicesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
- self.cap_map = \
- {'net': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET,
- 'pci': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV,
- 'scsi': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI,
- 'scsi_host': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST,
- 'storage': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE,
- 'usb_device': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV,
- 'usb':
- libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE}
- # TODO: when no longer supporting Libvirt < 1.0.5 distros
- # (like RHEL6) remove this verification and insert the
- # key 'fc_host' with the libvirt variable in the hash
- # declaration above.
- try:
- self.cap_map['fc_host'] = \
- libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
- except AttributeError:
- self.cap_map['fc_host'] = None
-
- def get_list(self, _cap=None, _passthrough=None,
- _passthrough_affected_by=None):
- if _passthrough_affected_by is not None:
- # _passthrough_affected_by conflicts with _cap and _passthrough
- if (_cap, _passthrough) != (None, None):
- raise InvalidParameter("KCHHOST0004E")
- return sorted(
- self._get_passthrough_affected_devs(_passthrough_affected_by))
-
- if _cap == 'fc_host':
- dev_names = self._get_devices_fc_host()
- else:
- dev_names = self._get_devices_with_capability(_cap)
-
- if _passthrough is not None and _passthrough.lower() == 'true':
- conn = self.conn.get()
- passthrough_names = [
- dev['name'] for dev in hostdev.get_passthrough_dev_infos(conn)]
- dev_names = list(set(dev_names) & set(passthrough_names))
-
- dev_names.sort()
- return dev_names
-
- def _get_devices_with_capability(self, cap):
- conn = self.conn.get()
- if cap is None:
- cap_flag = 0
- else:
- cap_flag = self.cap_map.get(cap)
- if cap_flag is None:
- return []
- return [name.name() for name in conn.listAllDevices(cap_flag)]
-
- def _get_passthrough_affected_devs(self, dev_name):
- conn = self.conn.get()
- info = DeviceModel(conn=self.conn).lookup(dev_name)
- affected = hostdev.get_affected_passthrough_devices(conn, info)
- return [dev_info['name'] for dev_info in affected]
-
- def _get_devices_fc_host(self):
- conn = self.conn.get()
- # Libvirt < 1.0.5 does not support fc_host capability
- if not self.caps.fc_host_support:
- ret = []
- scsi_hosts = self._get_devices_with_capability('scsi_host')
- for host in scsi_hosts:
- xml = conn.nodeDeviceLookupByName(host).XMLDesc(0)
- path = '/device/capability/capability/@type'
- if 'fc_host' in xpath_get_text(xml, path):
- ret.append(host)
- return ret
- # Double verification to catch the case where the libvirt
- # supports fc_host but does not, for some reason, recognize
- # the libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
- # attribute.
- if not self.cap_map['fc_host']:
- return conn.listDevices('fc_host', 0)
- return self._get_devices_with_capability('fc_host')
-
-
-class DeviceModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def lookup(self, nodedev_name):
- conn = self.conn.get()
- try:
- dev = conn.nodeDeviceLookupByName(nodedev_name)
- except:
- raise NotFoundError('KCHHOST0003E', {'name': nodedev_name})
- return hostdev.get_dev_info(dev)
-
-
-class PackagesUpdateModel(object):
- def __init__(self, **kargs):
- try:
- self.host_swupdate = SoftwareUpdate()
- except:
- self.host_swupdate = None
-
- def get_list(self):
- if self.host_swupdate is None:
- raise OperationFailed('KCHPKGUPD0004E')
-
- return self.host_swupdate.getUpdates()
-
-
-class PackageUpdateModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- try:
- swupdate = SoftwareUpdate()
- except Exception:
- raise OperationFailed('KCHPKGUPD0004E')
-
- return swupdate.getUpdate(name)
-
-
-class RepositoriesModel(object):
- def __init__(self, **kargs):
- try:
- self.host_repositories = Repositories()
- except:
- self.host_repositories = None
-
- def get_list(self):
- if self.host_repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return sorted(self.host_repositories.getRepositories())
-
- def create(self, params):
- if self.host_repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self.host_repositories.addRepository(params)
-
-
-class RepositoryModel(object):
- def __init__(self, **kargs):
- try:
- self._repositories = Repositories()
- except:
- self._repositories = None
-
- def lookup(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.getRepository(repo_id)
-
- def enable(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.enableRepository(repo_id)
-
- def disable(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.disableRepository(repo_id)
-
- def update(self, repo_id, params):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.updateRepository(repo_id, params)
-
- def delete(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.removeRepository(repo_id)
diff --git a/plugins/kimchi/model/hostdev.py b/plugins/kimchi/model/hostdev.py
deleted file mode 100644
index 31211c7..0000000
--- a/plugins/kimchi/model/hostdev.py
+++ /dev/null
@@ -1,324 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-from pprint import pformat
-from pprint import pprint
-
-from wok.utils import wok_log
-from wok.xmlutils.utils import dictize
-
-from libvirtconnection import LibvirtConnection
-
-
-def _get_all_host_dev_infos(libvirt_conn):
- node_devs = libvirt_conn.listAllDevices(0)
- return [get_dev_info(node_dev) for node_dev in node_devs]
-
-
-def _get_dev_info_tree(dev_infos):
- devs = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
- root = None
- for dev_info in dev_infos:
- if dev_info['parent'] is None:
- root = dev_info
- continue
-
- try:
- parent = devs[dev_info['parent']]
- except KeyError:
- wok_log.error('Parent %s of device %s does not exist.',
- dev_info['parent'], dev_info['name'])
- continue
-
- try:
- children = parent['children']
- except KeyError:
- parent['children'] = [dev_info]
- else:
- children.append(dev_info)
- return root
-
-
-def _is_pci_qualified(pci_dev):
- # PCI bridge is not suitable to passthrough
- # KVM does not support passthrough graphic card now
- blacklist_classes = (0x030000, 0x060000)
-
- with open(os.path.join(pci_dev['path'], 'class')) as f:
- pci_class = int(f.readline().strip(), 16)
-
- if pci_class & 0xff0000 in blacklist_classes:
- return False
-
- return True
-
-
-def get_passthrough_dev_infos(libvirt_conn):
- ''' Get devices eligible to be passed through to VM. '''
-
- def is_eligible(dev):
- return dev['device_type'] in ('usb_device', 'scsi') or \
- (dev['device_type'] == 'pci' and _is_pci_qualified(dev))
-
- dev_infos = _get_all_host_dev_infos(libvirt_conn)
-
- return [dev_info for dev_info in dev_infos if is_eligible(dev_info)]
-
-
-def _get_same_iommugroup_devices(dev_infos, device_info):
- dev_dict = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
-
- def get_iommu_group(dev_info):
- # Find out the iommu group of a given device.
- # Child device belongs to the same iommu group as the parent device.
- try:
- return dev_info['iommuGroup']
- except KeyError:
- pass
-
- parent = dev_info['parent']
- while parent is not None:
- try:
- parent_info = dev_dict[parent]
- except KeyError:
- wok_log.error("Parent %s of device %s does not exist",
- parent, dev_info['name'])
- break
-
- try:
- iommuGroup = parent_info['iommuGroup']
- except KeyError:
- pass
- else:
- return iommuGroup
-
- parent = parent_info['parent']
-
- return None
-
- iommu_group = get_iommu_group(device_info)
-
- if iommu_group is None:
- return []
-
- return [dev_info for dev_info in dev_infos
- if dev_info['name'] != device_info['name'] and
- get_iommu_group(dev_info) == iommu_group]
-
-
-def _get_children_devices(dev_infos, device_info):
- def get_children_recursive(parent):
- try:
- children = parent['children']
- except KeyError:
- return []
-
- result = []
- for child in children:
- result.append(child)
- result.extend(get_children_recursive(child))
-
- return result
-
- # Annotate every the dev_info element with children information
- _get_dev_info_tree(dev_infos)
-
- for dev_info in dev_infos:
- if dev_info['name'] == device_info['name']:
- return get_children_recursive(dev_info)
-
- return []
-
-
-def get_affected_passthrough_devices(libvirt_conn, passthrough_dev):
- dev_infos = _get_all_host_dev_infos(libvirt_conn)
-
- group_devices = _get_same_iommugroup_devices(dev_infos, passthrough_dev)
- if not group_devices:
- # On host without iommu group support, the affected devices should
- # at least include all children devices
- group_devices.extend(_get_children_devices(dev_infos, passthrough_dev))
-
- return group_devices
-
-
-def get_dev_info(node_dev):
- ''' Parse the node device XML string into dict according to
- http://libvirt.org/formatnode.html.
-
- scsi_generic is not documented in libvirt official website. Try to
- parse scsi_generic according to the following libvirt path series.
- https://www.redhat.com/archives/libvir-list/2013-June/msg00014.html
-
- scsi_target is not documented in libvirt official website. Try to
- parse scsi_target according to the libvirt commit db19834a0a.
- '''
-
- xmlstr = node_dev.XMLDesc(0)
- info = dictize(xmlstr)['device']
- dev_type = info['capability'].pop('type')
- info['device_type'] = dev_type
- cap_dict = info.pop('capability')
- info.update(cap_dict)
- info['parent'] = node_dev.parent()
-
- if dev_type in ('scsi', 'scsi_generic', 'scsi_target', 'system', 'usb'):
- return info
-
- if dev_type in ('net', 'pci', 'scsi_host', 'storage', 'usb_device'):
- return globals()['_get_%s_dev_info' % dev_type](info)
-
- wok_log.error("Unknown device type: %s", dev_type)
- return info
-
-
-def _get_net_dev_info(info):
- cap = info.pop('capability')
- links = {"80203": "IEEE 802.3", "80211": "IEEE 802.11"}
- link_raw = cap['type']
- info['link_type'] = links.get(link_raw, link_raw)
-
- return info
-
-
-def _get_pci_dev_info(info):
- for k in ('vendor', 'product'):
- try:
- description = info[k].pop('pyval')
- except KeyError:
- description = None
- info[k]['description'] = description
- if 'path' not in info:
- # Old libvirt does not provide syspath info
- info['path'] = \
- "/sys/bus/pci/devices/" \
- "%(domain)04x:%(bus)02x:%(slot)02x.%(function)01x" % {
- 'domain': info['domain'], 'bus': info['bus'],
- 'slot': info['slot'], 'function': info['function']}
- try:
- info['iommuGroup'] = int(info['iommuGroup']['number'])
- except KeyError:
- # Old libvirt does not provide syspath info, figure it out ourselves
- iommu_link = os.path.join(info['path'], 'iommu_group')
- if os.path.exists(iommu_link):
- iommu_path = os.path.realpath(iommu_link)
- try:
- info['iommuGroup'] = int(iommu_path.rsplit('/', 1)[1])
- except (ValueError, IndexError):
- # No IOMMU group support at all.
- pass
- else:
- # No IOMMU group support at all.
- pass
- return info
-
-
-def _get_scsi_host_dev_info(info):
- try:
- cap_info = info.pop('capability')
- except KeyError:
- # kimchi.model.libvirtstoragepool.ScsiPoolDef assumes
- # info['adapter']['type'] always exists.
- info['adapter'] = {'type': ''}
- return info
- if isinstance(cap_info, list):
- info['adapter'] = {}
- for cap in cap_info:
- if cap['type'] == 'vport_ops':
- del cap['type']
- info['adapter']['vport_ops'] = cap
- else:
- info['adapter'].update(cap)
- else:
- info['adapter'] = cap_info
- return info
-
-
-def _get_storage_dev_info(info):
- try:
- cap_info = info.pop('capability')
- except KeyError:
- return info
-
- if cap_info['type'] == 'removable':
- cap_info['available'] = bool(cap_info.pop('media_available'))
- if cap_info['available']:
- for k in ('size', 'label'):
- try:
- cap_info[k] = cap_info.pop('media_' + k)
- except KeyError:
- cap_info[k] = None
- info['media'] = cap_info
- return info
-
-
-def _get_usb_device_dev_info(info):
- for k in ('vendor', 'product'):
- try:
- info[k]['description'] = info[k].pop('pyval')
- except KeyError:
- # Some USB devices don't provide vendor/product description.
- pass
- return info
-
-
-# For test and debug
-def _print_host_dev_tree(libvirt_conn):
- dev_infos = _get_all_host_dev_infos(libvirt_conn)
- root = _get_dev_info_tree(dev_infos)
- if root is None:
- print "No device found"
- return
- print '-----------------'
- print '\n'.join(_format_dev_node(root))
-
-
-def _format_dev_node(node):
- try:
- children = node['children']
- del node['children']
- except KeyError:
- children = []
-
- lines = []
- lines.extend([' ~' + line for line in pformat(node).split('\n')])
-
- count = len(children)
- for i, child in enumerate(children):
- if count == 1:
- lines.append(' \-----------------')
- else:
- lines.append(' +-----------------')
- clines = _format_dev_node(child)
- if i == count - 1:
- p = ' '
- else:
- p = ' |'
- lines.extend([p + cline for cline in clines])
- lines.append('')
-
- return lines
-
-
-if __name__ == '__main__':
- libvirt_conn = LibvirtConnection('qemu:///system').get()
- _print_host_dev_tree(libvirt_conn)
- print 'Eligible passthrough devices:'
- pprint(get_passthrough_dev_infos(libvirt_conn))
diff --git a/plugins/kimchi/model/interfaces.py b/plugins/kimchi/model/interfaces.py
deleted file mode 100644
index 149afe3..0000000
--- a/plugins/kimchi/model/interfaces.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.exception import NotFoundError
-
-from .. import netinfo
-from networks import NetworksModel
-
-
-class InterfacesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.networks = NetworksModel(**kargs)
-
- def get_list(self):
- return list(set(netinfo.all_favored_interfaces()) -
- set(self.networks.get_all_networks_interfaces()))
-
-
-class InterfaceModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- try:
- return netinfo.get_interface_info(name)
- except ValueError:
- raise NotFoundError("KCHIFACE0001E", {'name': name})
diff --git a/plugins/kimchi/model/libvirtconnection.py b/plugins/kimchi/model/libvirtconnection.py
deleted file mode 100644
index 73f3dcf..0000000
--- a/plugins/kimchi/model/libvirtconnection.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import libvirt
-import threading
-import time
-
-from wok.utils import wok_log
-
-
-class LibvirtConnection(object):
- _connections = {}
- _connectionLock = threading.Lock()
-
- def __init__(self, uri):
- self.uri = uri
- if self.uri not in LibvirtConnection._connections:
- LibvirtConnection._connections[self.uri] = {}
- self._connections = LibvirtConnection._connections[self.uri]
- self.wrappables = self.get_wrappable_objects()
-
- def get_wrappable_objects(self):
- """
- When a wrapped function returns an instance of another libvirt object,
- we also want to wrap that object so we can catch errors that happen
- when calling its methods.
- """
- objs = []
- for name in ('virDomain', 'virDomainSnapshot', 'virInterface',
- 'virNWFilter', 'virNetwork', 'virNodeDevice', 'virSecret',
- 'virStoragePool', 'virStorageVol', 'virStream'):
- try:
- attr = getattr(libvirt, name)
- except AttributeError:
- pass
- objs.append(attr)
- return tuple(objs)
-
- def get(self, conn_id=0):
- """
- Return current connection to libvirt or open a new one. Wrap all
- callable libvirt methods so we can catch connection errors and handle
- them by restarting the server.
- """
- def wrapMethod(f):
- def wrapper(*args, **kwargs):
- try:
- ret = f(*args, **kwargs)
- return ret
- except libvirt.libvirtError as e:
- edom = e.get_error_domain()
- ecode = e.get_error_code()
- EDOMAINS = (libvirt.VIR_FROM_REMOTE,
- libvirt.VIR_FROM_RPC)
- ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
- libvirt.VIR_ERR_INTERNAL_ERROR,
- libvirt.VIR_ERR_NO_CONNECT,
- libvirt.VIR_ERR_INVALID_CONN)
- if edom in EDOMAINS and ecode in ECODES:
- wok_log.error('Connection to libvirt broken. '
- 'Recycling. ecode: %d edom: %d' %
- (ecode, edom))
- with LibvirtConnection._connectionLock:
- self._connections[conn_id] = None
- raise
- wrapper.__name__ = f.__name__
- wrapper.__doc__ = f.__doc__
- return wrapper
-
- with LibvirtConnection._connectionLock:
- conn = self._connections.get(conn_id)
- if not conn:
- retries = 5
- while True:
- retries = retries - 1
- try:
- conn = libvirt.open(self.uri)
- break
- except libvirt.libvirtError:
- wok_log.error('Unable to connect to libvirt.')
- if not retries:
- wok_log.error("Unable to establish connection "
- "with libvirt. Please check "
- "your libvirt URI which is often "
- "defined in "
- "/etc/libvirt/libvirt.conf")
- cherrypy.engine.stop()
- exit(1)
- time.sleep(2)
-
- for name in dir(libvirt.virConnect):
- method = getattr(conn, name)
- if callable(method) and not name.startswith('_'):
- setattr(conn, name, wrapMethod(method))
-
- for cls in self.wrappables:
- for name in dir(cls):
- method = getattr(cls, name)
- if callable(method) and not name.startswith('_'):
- setattr(cls, name, wrapMethod(method))
-
- self._connections[conn_id] = conn
- # In case we're running into troubles with keeping the
- # connections alive we should place here:
- # conn.setKeepAlive(interval=5, count=3)
- # However the values need to be considered wisely to not affect
- # hosts which are hosting a lot of virtual machines
- return conn
-
- def isQemuURI(self):
- """
- This method will return True or Value when the system libvirt
- URI is a qemu based URI. For example:
- qemu:///system or qemu+tcp://someipaddress/system
- """
- if self.get().getURI().startswith('qemu'):
- return True
- else:
- return False
diff --git a/plugins/kimchi/model/libvirtstoragepool.py b/plugins/kimchi/model/libvirtstoragepool.py
deleted file mode 100644
index b22856b..0000000
--- a/plugins/kimchi/model/libvirtstoragepool.py
+++ /dev/null
@@ -1,264 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import os
-import tempfile
-from lxml.builder import E
-
-from wok.exception import InvalidParameter, OperationFailed, TimeoutExpired
-from wok.rollbackcontext import RollbackContext
-from wok.utils import parse_cmd_output, run_command, wok_log
-
-from ..iscsi import TargetClient
-
-
-class StoragePoolDef(object):
- @classmethod
- def create(cls, poolArgs):
- for klass in cls.__subclasses__():
- if poolArgs['type'] == klass.poolType:
- return klass(poolArgs)
- raise OperationFailed("KCHPOOL0014E", {'type': poolArgs['type']})
-
- def __init__(self, poolArgs):
- self.poolArgs = poolArgs
-
- def prepare(self, conn):
- ''' Validate pool arguments and perform preparations. Operation which
- would cause side effect should be put here. Subclasses can optionally
- override this method, or it always succeeds by default. '''
- pass
-
- @property
- def xml(self):
- ''' Subclasses have to override this method to actually generate the
- storage pool XML definition. Should cause no side effect and be
- idempotent'''
- # TODO: When add new pool type, should also add the related test in
- # tests/test_storagepool.py
- raise OperationFailed("KCHPOOL0015E", {'pool': self})
-
-
-class DirPoolDef(StoragePoolDef):
- poolType = 'dir'
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # path:
- pool = E.pool(type='dir')
- pool.append(E.name(self.poolArgs['name']))
- pool.append(E.target(E.path(self.poolArgs['path'])))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class NetfsPoolDef(StoragePoolDef):
- poolType = 'netfs'
-
- def __init__(self, poolArgs):
- super(NetfsPoolDef, self).__init__(poolArgs)
- self.path = '/var/lib/kimchi/nfs_mount/' + self.poolArgs['name']
-
- def prepare(self, conn):
- mnt_point = tempfile.mkdtemp(dir='/tmp')
- export_path = "%s:%s" % (
- self.poolArgs['source']['host'], self.poolArgs['source']['path'])
- mount_cmd = ["mount", "-o", 'soft,timeo=100,retrans=3,retry=0',
- export_path, mnt_point]
- umount_cmd = ["umount", "-f", export_path]
- mounted = False
- # Due to an NFS bug (See Red Hat BZ 1023059), NFSv4 exports may take
- # 10-15 seconds to mount the first time.
- cmd_timeout = 15
-
- with RollbackContext() as rollback:
- rollback.prependDefer(os.rmdir, mnt_point)
- try:
- run_command(mount_cmd, cmd_timeout)
- rollback.prependDefer(run_command, umount_cmd, cmd_timeout)
- except TimeoutExpired:
- raise InvalidParameter("KCHPOOL0012E", {'path': export_path})
- with open("/proc/mounts", "rb") as f:
- rawMounts = f.read()
- output_items = ['dev_path', 'mnt_point', 'type']
- mounts = parse_cmd_output(rawMounts, output_items)
- for item in mounts:
- if 'dev_path' in item and item['dev_path'] == export_path:
- mounted = True
-
- if not mounted:
- raise InvalidParameter("KCHPOOL0013E", {'path': export_path})
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # source[host]:
- # source[path]:
- pool = E.pool(type='netfs')
- pool.append(E.name(self.poolArgs['name']))
-
- source = E.source()
- source.append(E.host(name=self.poolArgs['source']['host']))
- source.append(E.dir(path=self.poolArgs['source']['path']))
-
- pool.append(source)
- pool.append(E.target(E.path(self.path)))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class LogicalPoolDef(StoragePoolDef):
- poolType = 'logical'
-
- def __init__(self, poolArgs):
- super(LogicalPoolDef, self).__init__(poolArgs)
- self.path = '/dev/' + self.poolArgs['name']
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # source[devices]:
- pool = E.pool(type='logical')
- pool.append(E.name(self.poolArgs['name']))
-
- source = E.source()
- for device_path in self.poolArgs['source']['devices']:
- source.append(E.device(path=device_path))
-
- pool.append(source)
- pool.append(E.target(E.path(self.path)))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class ScsiPoolDef(StoragePoolDef):
- poolType = 'scsi'
-
- def prepare(self, conn=None):
- tmp_name = self.poolArgs['source']['name']
- self.poolArgs['source']['name'] = tmp_name.replace('scsi_', '')
- # fc_host adapters type are only available in libvirt >= 1.0.5
- if not self.poolArgs['fc_host_support']:
- self.poolArgs['source']['adapter']['type'] = 'scsi_host'
- msg = "Libvirt version <= 1.0.5. Setting SCSI host name as '%s'; "\
- "setting SCSI adapter type as 'scsi_host'; "\
- "ignoring wwnn and wwpn." % tmp_name
- wok_log.info(msg)
- # Path for Fibre Channel scsi hosts
- self.poolArgs['path'] = '/dev/disk/by-path'
- if not self.poolArgs['source']['adapter']['type']:
- self.poolArgs['source']['adapter']['type'] = 'scsi_host'
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # source[adapter][type]:
- # source[name]:
- # source[adapter][wwnn]:
- # source[adapter][wwpn]:
- # path:
- pool = E.pool(type='scsi')
- pool.append(E.name(self.poolArgs['name']))
-
- adapter = E.adapter(type=self.poolArgs['source']['adapter']['type'])
- adapter.set('name', self.poolArgs['source']['name'])
- adapter.set('wwnn', self.poolArgs['source']['adapter']['wwnn'])
- adapter.set('wwpn', self.poolArgs['source']['adapter']['wwpn'])
-
- pool.append(E.source(adapter))
- pool.append(E.target(E.path(self.poolArgs['path'])))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class IscsiPoolDef(StoragePoolDef):
- poolType = 'iscsi'
-
- def prepare(self, conn):
- source = self.poolArgs['source']
- if not TargetClient(**source).validate():
- msg_args = {'host': source['host'], 'target': source['target']}
- raise OperationFailed("KCHISCSI0002E", msg_args)
- self._prepare_auth(conn)
-
- def _prepare_auth(self, conn):
- try:
- auth = self.poolArgs['source']['auth']
- except KeyError:
- return
-
- try:
- virSecret = conn.secretLookupByUsage(
- libvirt.VIR_SECRET_USAGE_TYPE_ISCSI, self.poolArgs['name'])
- except libvirt.libvirtError:
- secret = E.secret(ephemeral='no', private='yes')
-
- description = E.description('Secret for iSCSI storage pool %s' %
- self.poolArgs['name'])
- secret.append(description)
- secret.append(E.auth(type='chap', username=auth['username']))
-
- usage = E.usage(type='iscsi')
- usage.append(E.target(self.poolArgs['name']))
- secret.append(usage)
- virSecret = conn.secretDefineXML(ET.tostring(secret))
-
- virSecret.setValue(auth['password'])
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # source[host]:
- # source[target]:
- #
- # Optional parameters
- # source[port]:
- pool = E.pool(type='iscsi')
- pool.append(E.name(self.poolArgs['name']))
-
- host = E.host(name=self.poolArgs['source']['host'])
- port = self.poolArgs['source'].get('port')
- if port is not None:
- host.set('port', str(port))
-
- source = E.source(host)
- source.append(E.device(path=self.poolArgs['source']['target']))
-
- source_auth = self.poolArgs['source'].get('auth')
- if source_auth is not None:
- auth = E.auth(type='chap')
- auth.set('username', source_auth['username'])
-
- secret = E.secret(type='iscsi')
- secret.set('usage', self.poolArgs['name'])
- auth.append(secret)
-
- source.append(auth)
-
- pool.append(source)
- pool.append(E.target(E.path('/dev/disk/by-id')))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
diff --git a/plugins/kimchi/model/model.py b/plugins/kimchi/model/model.py
deleted file mode 100644
index 0c94f63..0000000
--- a/plugins/kimchi/model/model.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import inspect
-import os
-
-from wok.basemodel import BaseModel
-from wok.objectstore import ObjectStore
-from wok.utils import import_module, listPathModules
-
-from libvirtconnection import LibvirtConnection
-
-
-class Model(BaseModel):
- def __init__(self, libvirt_uri=None, objstore_loc=None):
-
- self.objstore = ObjectStore(objstore_loc)
- self.conn = LibvirtConnection(libvirt_uri)
- kargs = {'objstore': self.objstore, 'conn': self.conn}
-
- this = os.path.basename(__file__)
- this_mod = os.path.splitext(this)[0]
-
- models = []
- for mod_name in listPathModules(os.path.dirname(__file__)):
- if mod_name.startswith("_") or mod_name == this_mod:
- continue
-
- module = import_module('plugins.kimchi.model.' + mod_name)
- members = inspect.getmembers(module, inspect.isclass)
- for cls_name, instance in members:
- if inspect.getmodule(instance) == module:
- if cls_name.endswith('Model'):
- models.append(instance(**kargs))
-
- return super(Model, self).__init__(models)
diff --git a/plugins/kimchi/model/networks.py b/plugins/kimchi/model/networks.py
deleted file mode 100644
index b579865..0000000
--- a/plugins/kimchi/model/networks.py
+++ /dev/null
@@ -1,382 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ipaddr
-import libvirt
-import sys
-import time
-from xml.sax.saxutils import escape
-
-from wok.config import PluginPaths
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import MissingParameter, NotFoundError, OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import run_command, wok_log
-from wok.xmlutils.utils import xpath_get_text
-
-from .. import netinfo
-from .. import network as knetwork
-from ..osinfo import defaults as tmpl_defaults
-from ..xmlutils.network import create_vlan_tagged_bridge_xml
-from ..xmlutils.network import to_network_xml
-
-
-KIMCHI_BRIDGE_PREFIX = 'kb'
-
-
-class NetworksModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- if self.conn.isQemuURI():
- self._check_default_networks()
-
- def _check_default_networks(self):
- networks = list(set(tmpl_defaults['networks']))
- conn = self.conn.get()
-
- error_msg = ("Please, check the configuration in %s/template.conf to "
- "ensure it lists only valid networks." %
- PluginPaths('kimchi').conf_dir)
-
- for net_name in networks:
- try:
- net = conn.networkLookupByName(net_name)
- except libvirt.libvirtError, e:
- msg = "Fatal: Unable to find network %s."
- wok_log.error(msg, net_name)
- wok_log.error(error_msg)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- if net.isActive() == 0:
- try:
- net.create()
- except libvirt.libvirtError as e:
- msg = "Fatal: Unable to activate network %s."
- wok_log.error(msg, net_name)
- wok_log.error(error_msg)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- def create(self, params):
- conn = self.conn.get()
- name = params['name']
- if name in self.get_list():
- raise InvalidOperation("KCHNET0001E", {'name': name})
-
- connection = params["connection"]
- # set forward mode, isolated do not need forward
- if connection != 'isolated':
- params['forward'] = {'mode': connection}
-
- # set subnet, bridge network do not need subnet
- if connection in ["nat", 'isolated']:
- self._set_network_subnet(params)
-
- # only bridge network need bridge(linux bridge) or interface(macvtap)
- if connection == 'bridge':
- self._set_network_bridge(params)
-
- params['name'] = escape(params['name'])
- xml = to_network_xml(**params)
-
- try:
- network = conn.networkDefineXML(xml.encode("utf-8"))
- network.setAutostart(True)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHNET0008E",
- {'name': name, 'err': e.get_error_message()})
-
- return name
-
- def get_list(self):
- conn = self.conn.get()
- names = conn.listNetworks() + conn.listDefinedNetworks()
- return sorted(map(lambda x: x.decode('utf-8'), names))
-
- def _get_available_address(self, addr_pools=[]):
- invalid_addrs = []
- for net_name in self.get_list():
- network = NetworkModel.get_network(self.conn.get(), net_name)
- xml = network.XMLDesc(0)
- subnet = NetworkModel.get_network_from_xml(xml)['subnet']
- subnet and invalid_addrs.append(ipaddr.IPNetwork(subnet))
- addr_pools = addr_pools if addr_pools else knetwork.PrivateNets
- return knetwork.get_one_free_network(invalid_addrs, addr_pools)
-
- def _set_network_subnet(self, params):
- netaddr = params.get('subnet', '')
- # lookup a free network address for nat and isolated automatically
- if not netaddr:
- netaddr = self._get_available_address()
- if not netaddr:
- raise OperationFailed("KCHNET0009E", {'name': params['name']})
-
- try:
- ip = ipaddr.IPNetwork(netaddr)
- except ValueError:
- raise InvalidParameter("KCHNET0003E", {'subent': netaddr,
- 'network': params['name']})
-
- if ip.ip == ip.network:
- ip.ip = ip.ip + 1
-
- dhcp_start = str(ip.ip + ip.numhosts / 2)
- dhcp_end = str(ip.ip + ip.numhosts - 2)
- params.update({'net': str(ip),
- 'dhcp': {'range': {'start': dhcp_start,
- 'end': dhcp_end}}})
-
- def _ensure_iface_up(self, iface):
- if netinfo.operstate(iface) != 'up':
- _, err, rc = run_command(['ip', 'link', 'set', 'dev', iface, 'up'])
- if rc != 0:
- raise OperationFailed("KCHNET0020E",
- {'iface': iface, 'err': err})
- # Add a delay to wait for the link change takes into effect.
- for i in range(10):
- time.sleep(1)
- if netinfo.operstate(iface) == 'up':
- break
- else:
- raise OperationFailed("KCHNET0021E", {'iface': iface})
-
- def _set_network_bridge(self, params):
- try:
- iface = params['interface']
- if iface in self.get_all_networks_interfaces():
- msg_args = {'iface': iface, 'network': params['name']}
- raise InvalidParameter("KCHNET0006E", msg_args)
- except KeyError:
- raise MissingParameter("KCHNET0004E", {'name': params['name']})
-
- self._ensure_iface_up(iface)
- if netinfo.is_bridge(iface):
- if 'vlan_id' in params:
- raise InvalidParameter('KCHNET0019E', {'name': iface})
- params['bridge'] = iface
- elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
- if params.get('vlan_id') is None:
- params['forward']['dev'] = iface
- else:
- params['bridge'] = \
- self._create_vlan_tagged_bridge(str(iface),
- str(params['vlan_id']))
- else:
- raise InvalidParameter("KCHNET0007E")
-
- def get_all_networks_interfaces(self):
- net_names = self.get_list()
- interfaces = []
- for name in net_names:
- conn = self.conn.get()
- network = conn.networkLookupByName(name.encode("utf-8"))
- xml = network.XMLDesc(0)
- net_dict = NetworkModel.get_network_from_xml(xml)
- forward = net_dict['forward']
- (forward['mode'] == 'bridge' and forward['interface'] and
- interfaces.append(forward['interface'][0]) is None or
- interfaces.extend(forward['interface'] + forward['pf']))
- net_dict['bridge'] and interfaces.append(net_dict['bridge'])
- return interfaces
-
- def _create_vlan_tagged_bridge(self, interface, vlan_id):
- # Truncate the interface name if it exceeds 8 characters to make sure
- # the length of bridge name is less than 15 (its maximum value).
- br_name = KIMCHI_BRIDGE_PREFIX + interface[-8:] + '-' + vlan_id
- br_xml = create_vlan_tagged_bridge_xml(br_name, interface, vlan_id)
- conn = self.conn.get()
-
- bridges = []
- for net in conn.listAllNetworks():
- # Bridged networks do not have a bridge name
- # So in those cases, libvirt raises an error when trying to get
- # the bridge name
- try:
- bridges.append(net.bridgeName())
- except libvirt.libvirtError, e:
- wok_log.error(e.message)
-
- if br_name in bridges:
- raise InvalidOperation("KCHNET0010E", {'iface': br_name})
-
- with RollbackContext() as rollback:
- try:
- vlan_tagged_br = conn.interfaceDefineXML(br_xml, 0)
- rollback.prependDefer(vlan_tagged_br.destroy)
- vlan_tagged_br.create(0)
- except libvirt.libvirtError as e:
- raise OperationFailed(e.message)
- else:
- return br_name
-
-
-class NetworkModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
-
- def lookup(self, name):
- network = self.get_network(self.conn.get(), name)
- xml = network.XMLDesc(0)
- net_dict = self.get_network_from_xml(xml)
- subnet = net_dict['subnet']
- dhcp = net_dict['dhcp']
- forward = net_dict['forward']
- interface = net_dict['bridge']
-
- connection = forward['mode'] or "isolated"
- # FIXME, if we want to support other forward mode well.
- if connection == 'bridge':
- # macvtap bridge
- interface = interface or forward['interface'][0]
- # exposing the network on linux bridge or macvtap interface
- interface_subnet = knetwork.get_dev_netaddr(interface)
- subnet = subnet if subnet else interface_subnet
-
- # libvirt use format 192.168.0.1/24, standard should be 192.168.0.0/24
- # http://www.ovirt.org/File:Issue3.png
- if subnet:
- subnet = ipaddr.IPNetwork(subnet)
- subnet = "%s/%s" % (subnet.network, subnet.prefixlen)
-
- return {'connection': connection,
- 'interface': interface,
- 'subnet': subnet,
- 'dhcp': dhcp,
- 'vms': self._get_vms_attach_to_a_network(name),
- 'in_use': self._is_network_in_use(name),
- 'autostart': network.autostart() == 1,
- 'state': network.isActive() and "active" or "inactive",
- 'persistent': True if network.isPersistent() else False}
-
- def _is_network_in_use(self, name):
- # All the networks listed as default in template.conf file should not
- # be deactivate or deleted. Otherwise, we will allow user create
- # inconsistent templates from scratch
- if name in tmpl_defaults['networks']:
- return True
-
- vms = self._get_vms_attach_to_a_network(name)
- return bool(vms) or self._is_network_used_by_template(name)
-
- def _is_network_used_by_template(self, network):
- with self.objstore as session:
- templates = session.get_list('template')
- for tmpl in templates:
- tmpl_net = session.get('template', tmpl)['networks']
- if network in tmpl_net:
- return True
- return False
-
- def _get_vms_attach_to_a_network(self, network, filter="all"):
- DOM_STATE_MAP = {'nostate': 0, 'running': 1, 'blocked': 2,
- 'paused': 3, 'shutdown': 4, 'shutoff': 5,
- 'crashed': 6}
- state = DOM_STATE_MAP.get(filter)
- vms = []
- conn = self.conn.get()
- for dom in conn.listAllDomains(0):
- networks = self._vm_get_networks(dom)
- if network.encode('utf-8') in networks and \
- (state is None or state == dom.state(0)[0]):
- vms.append(dom.name())
- return vms
-
- def _vm_get_networks(self, dom):
- xml = dom.XMLDesc(0)
- xpath = "/domain/devices/interface[@type='network']/source/@network"
- return xpath_get_text(xml, xpath)
-
- def activate(self, name):
- network = self.get_network(self.conn.get(), name)
- try:
- network.create()
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHNET0022E', {'name': name,
- 'err': e.message})
-
- def deactivate(self, name):
- if self._is_network_in_use(name):
- vms = self._get_vms_attach_to_a_network(name)
- vms.sort()
- raise InvalidOperation("KCHNET0018E", {'name': name,
- 'vms': ', '.join(vms)})
-
- network = self.get_network(self.conn.get(), name)
- network.destroy()
-
- def delete(self, name):
- if self._is_network_in_use(name):
- vms = self._get_vms_attach_to_a_network(name)
- vms.sort()
- raise InvalidOperation("KCHNET0017E", {'name': name,
- 'vms': ', '.join(vms)})
-
- network = self.get_network(self.conn.get(), name)
- if network.isActive():
- raise InvalidOperation("KCHNET0005E", {'name': name})
-
- self._remove_vlan_tagged_bridge(network)
- network.undefine()
-
- @staticmethod
- def get_network(conn, name):
- name = name.encode("utf-8")
- try:
- return conn.networkLookupByName(name)
- except libvirt.libvirtError:
- raise NotFoundError("KCHNET0002E", {'name': name})
-
- @staticmethod
- def get_network_from_xml(xml):
- address = xpath_get_text(xml, "/network/ip/@address")
- address = address and address[0] or ''
- netmask = xpath_get_text(xml, "/network/ip/@netmask")
- netmask = netmask and netmask[0] or ''
- net = address and netmask and "/".join([address, netmask]) or ''
-
- dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
- dhcp_start = dhcp_start and dhcp_start[0] or ''
- dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
- dhcp_end = dhcp_end and dhcp_end[0] or ''
- dhcp = {'start': dhcp_start, 'end': dhcp_end}
-
- forward_mode = xpath_get_text(xml, "/network/forward/@mode")
- forward_mode = forward_mode and forward_mode[0] or ''
- forward_if = xpath_get_text(xml, "/network/forward/interface/@dev")
- forward_pf = xpath_get_text(xml, "/network/forward/pf/@dev")
- bridge = xpath_get_text(xml, "/network/bridge/@name")
- bridge = bridge and bridge[0] or ''
- return {'subnet': net, 'dhcp': dhcp, 'bridge': bridge,
- 'forward': {'mode': forward_mode,
- 'interface': forward_if,
- 'pf': forward_pf}}
-
- def _remove_vlan_tagged_bridge(self, network):
- try:
- bridge = network.bridgeName()
- except libvirt.libvirtError:
- pass
- else:
- if bridge.startswith(KIMCHI_BRIDGE_PREFIX):
- conn = self.conn.get()
- iface = conn.interfaceLookupByName(bridge)
- iface.isActive() and iface.destroy(0)
- iface.undefine()
diff --git a/plugins/kimchi/model/peers.py b/plugins/kimchi/model/peers.py
deleted file mode 100644
index 7577364..0000000
--- a/plugins/kimchi/model/peers.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import re
-import socket
-
-from wok.config import config
-from wok.utils import run_command, wok_log
-
-
-class PeersModel(object):
- def __init__(self, **kargs):
- # check federation feature is enabled on Kimchi server
- if config.get("server", "federation") == "off":
- return
-
- # register server on openslp
- hostname = socket.getfqdn(config.get("server", "host"))
- port = config.get("server", "ssl_port")
- self.url = hostname + ":" + port
-
- cmd = ["slptool", "register",
- "service:wokd://%s" % self.url]
- out, error, ret = run_command(cmd)
- if out and len(out) != 0:
- wok_log.error("Unable to register server on openSLP."
- " Details: %s" % out)
- cherrypy.engine.subscribe('exit', self._peer_deregister)
-
- def _peer_deregister(self):
- cmd = ["slptool", "deregister",
- "service:wokd://%s" % self.url]
- out, error, ret = run_command(cmd)
- if out and len(out) != 0:
- wok_log.error("Unable to deregister server on openSLP."
- " Details: %s" % out)
-
- def get_list(self):
- # check federation feature is enabled on Kimchi server
- if config.get("server", "federation") == "off":
- return []
-
- cmd = ["slptool", "findsrvs", "service:wokd"]
- out, error, ret = run_command(cmd)
- if ret != 0:
- return []
-
- peers = []
- for server in out.strip().split("\n"):
- match = re.match("service:wokd://(.*?),.*", server)
- peer = match.group(1)
- if peer != self.url:
- peers.append("https://" + peer)
-
- return peers
diff --git a/plugins/kimchi/model/storagepools.py b/plugins/kimchi/model/storagepools.py
deleted file mode 100644
index 0db2ef4..0000000
--- a/plugins/kimchi/model/storagepools.py
+++ /dev/null
@@ -1,490 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import sys
-from lxml.builder import E
-
-from wok.config import config, PluginPaths
-from wok.exception import InvalidOperation, MissingParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import add_task, run_command, wok_log
-from wok.xmlutils.utils import xpath_get_text
-
-from ..osinfo import defaults as tmpl_defaults
-from ..scan import Scanner
-from ..utils import pool_name_from_uri
-from config import CapabilitiesModel
-from host import DeviceModel
-from libvirtstoragepool import StoragePoolDef
-
-
-ISO_POOL_NAME = u'kimchi_isos'
-
-POOL_STATE_MAP = {0: 'inactive',
- 1: 'initializing',
- 2: 'active',
- 3: 'degraded',
- 4: 'inaccessible'}
-
-# Types of pools supported
-STORAGE_SOURCES = {'netfs': {'addr': '/pool/source/host/@name',
- 'path': '/pool/source/dir/@path'},
- 'iscsi': {'addr': '/pool/source/host/@name',
- 'port': '/pool/source/host/@port',
- 'path': '/pool/source/device/@path'},
- 'scsi': {'adapter_type': '/pool/source/adapter/@type',
- 'adapter_name': '/pool/source/adapter/@name',
- 'wwnn': '/pool/source/adapter/@wwnn',
- 'wwpn': '/pool/source/adapter/@wwpn'}}
-
-
-class StoragePoolsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.scanner = Scanner(self._clean_scan)
- self.scanner.delete()
- self.caps = CapabilitiesModel(**kargs)
- self.device = DeviceModel(**kargs)
-
- if self.conn.isQemuURI():
- self._check_default_pools()
-
- def _check_default_pools(self):
- pools = {}
-
- default_pool = tmpl_defaults['storagepool']
- default_pool = default_pool.split('/')[-1]
-
- pools[default_pool] = {}
- if default_pool == 'default':
- pools[default_pool] = {'path': '/var/lib/libvirt/images'}
-
- if config.get("server", "create_iso_pool") == "true":
- pools['ISO'] = {'path': '/var/lib/kimchi/isos'}
-
- error_msg = ("Please, check the configuration in %s/template.conf to "
- "ensure it has a valid storage pool." %
- PluginPaths('kimchi').conf_dir)
-
- conn = self.conn.get()
- for pool_name in pools:
- try:
- pool = conn.storagePoolLookupByName(pool_name)
- except libvirt.libvirtError, e:
- pool_path = pools[pool_name].get('path')
- if pool_path is None:
- msg = "Fatal: Unable to find storage pool %s. " + error_msg
- wok_log.error(msg % pool_name)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- # Try to create the pool
- pool = E.pool(E.name(pool_name), type='dir')
- pool.append(E.target(E.path(pool_path)))
- xml = ET.tostring(pool)
- try:
- pool = conn.storagePoolDefineXML(xml, 0)
- except libvirt.libvirtError, e:
- msg = "Fatal: Unable to create storage pool %s. "
- msg += error_msg
- wok_log.error(msg % pool_name)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- # Build and set autostart value to pool
- # Ignore error as the pool was already successfully created
- try:
- # Add build step to make sure target directory created
- # The build process may fail when the pool directory
- # already exists on system
- pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
- pool.setAutostart(1)
- except:
- pass
-
- if pool.isActive() == 0:
- try:
- pool.create(0)
- except libvirt.libvirtError, e:
- msg = "Fatal: Unable to craete storage pool %s. "
- msg += error_msg
- wok_log.error(msg % pool_name)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- def get_list(self):
- try:
- conn = self.conn.get()
- names = conn.listStoragePools()
- names += conn.listDefinedStoragePools()
- return sorted(map(lambda x: x.decode('utf-8'), names))
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0006E",
- {'err': e.get_error_message()})
-
- def create(self, params):
- task_id = None
- conn = self.conn.get()
- try:
- name = params['name']
- if name == ISO_POOL_NAME:
- raise InvalidOperation("KCHPOOL0031E")
-
- # The user may want to create a logical pool with the same name
- # used before but a volume group will already exist with this name
- # So check the volume group does not exist to create the pool
- if params['type'] == 'logical':
- vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')]
- output, error, returncode = run_command(vgdisplay_cmd)
- # From vgdisplay error codes:
- # 1 error reading VGDA
- # 2 volume group doesn't exist
- # 3 not all physical volumes of volume group online
- # 4 volume group not found
- # 5 no volume groups found at all
- # 6 error reading VGDA from lvmtab
- if returncode not in [2, 4, 5]:
- raise InvalidOperation("KCHPOOL0036E", {'name': name})
-
- if params['type'] == 'kimchi-iso':
- task_id = self._do_deep_scan(params)
-
- if params['type'] == 'scsi':
- adapter_name = params['source']['adapter_name']
- extra_params = self.device.lookup(adapter_name)
- # Adds name, adapter_type, wwpn and wwnn to source information
- params['source'].update(extra_params)
- params['fc_host_support'] = self.caps.fc_host_support
-
- poolDef = StoragePoolDef.create(params)
- poolDef.prepare(conn)
- xml = poolDef.xml.encode("utf-8")
- except KeyError, item:
- raise MissingParameter("KCHPOOL0004E",
- {'item': str(item), 'name': name})
-
- if name in self.get_list():
- raise InvalidOperation("KCHPOOL0001E", {'name': name})
-
- try:
- if task_id:
- # Create transient pool for deep scan
- conn.storagePoolCreateXML(xml, 0)
- return name
-
- pool = conn.storagePoolDefineXML(xml, 0)
- except libvirt.libvirtError as e:
- wok_log.error("Problem creating Storage Pool: %s", e)
- raise OperationFailed("KCHPOOL0007E",
- {'name': name, 'err': e.get_error_message()})
-
- # Build and set autostart value to pool
- # Ignore error as the pool was already successfully created
- # The build process fails when the pool directory already exists
- try:
- if params['type'] in ['logical', 'dir', 'netfs', 'scsi']:
- pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
- pool.setAutostart(1)
- else:
- pool.setAutostart(0)
- except:
- pass
-
- if params['type'] == 'netfs':
- output, error, returncode = run_command(['setsebool', '-P',
- 'virt_use_nfs=1'])
- if error or returncode:
- wok_log.error("Unable to set virt_use_nfs=1. If you use "
- "SELinux, this may prevent NFS pools from "
- "being used.")
- return name
-
- def _clean_scan(self, pool_name):
- try:
- conn = self.conn.get()
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- pool.destroy()
- with self.objstore as session:
- session.delete('scanning', pool_name)
- except Exception, e:
- err = "Exception %s occured when cleaning scan result"
- wok_log.debug(err % e.message)
-
- def _do_deep_scan(self, params):
- scan_params = dict(ignore_list=[])
- scan_params['scan_path'] = params['path']
- params['type'] = 'dir'
-
- for pool in self.get_list():
- try:
- res = StoragePoolModel(conn=self.conn,
- objstore=self.objstore).lookup(pool)
- if res['state'] == 'active':
- scan_params['ignore_list'].append(res['path'])
- except Exception, e:
- err = "Exception %s occured when get ignore path"
- wok_log.debug(err % e.message)
-
- params['path'] = self.scanner.scan_dir_prepare(params['name'])
- scan_params['pool_path'] = params['path']
- task_id = add_task('/plugins/kimchi/storagepools/%s' % ISO_POOL_NAME,
- self.scanner.start_scan, self.objstore, scan_params)
- # Record scanning-task/storagepool mapping for future querying
- try:
- with self.objstore as session:
- session.store('scanning', params['name'], task_id)
- return task_id
- except Exception as e:
- raise OperationFailed('KCHPOOL0037E', {'err': e.message})
-
-
-class StoragePoolModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
-
- @staticmethod
- def get_storagepool(name, conn):
- conn = conn.get()
- try:
- return conn.storagePoolLookupByName(name.encode("utf-8"))
- except libvirt.libvirtError as e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_POOL:
- raise NotFoundError("KCHPOOL0002E", {'name': name})
- else:
- raise
-
- def _get_storagepool_vols_num(self, pool):
- try:
- if pool.isActive():
- pool.refresh(0)
- return pool.numOfVolumes()
- else:
- return 0
- except libvirt.libvirtError as e:
- # If something (say a busy pool) prevents the refresh,
- # throwing an Exception here would prevent all pools from
- # displaying information -- so return None for busy
- wok_log.error("ERROR: Storage Pool get vol count: %s "
- % e.get_error_message())
- wok_log.error("ERROR: Storage Pool get vol count error no: %s "
- % e.get_error_code())
- return 0
- except Exception as e:
- raise OperationFailed("KCHPOOL0008E",
- {'name': pool.name(),
- 'err': e.get_error_message()})
-
- def _get_storage_source(self, pool_type, pool_xml):
- source = {}
- if pool_type not in STORAGE_SOURCES:
- return source
-
- for key, val in STORAGE_SOURCES[pool_type].items():
- res = xpath_get_text(pool_xml, val)
- if len(res) == 1:
- source[key] = res[0]
- elif len(res) == 0:
- source[key] = ""
- else:
- source[key] = res
- return source
-
- def _nfs_status_online(self, pool, poolArgs=None):
- if not poolArgs:
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- source = self._get_storage_source(pool_type, xml)
- poolArgs = {}
- poolArgs['name'] = pool.name()
- poolArgs['type'] = pool_type
- poolArgs['source'] = {'path': source['path'],
- 'host': source['addr']}
- conn = self.conn.get()
- poolDef = StoragePoolDef.create(poolArgs)
- try:
- poolDef.prepare(conn)
- return True
- except Exception:
- return False
-
- def lookup(self, name):
- pool = self.get_storagepool(name, self.conn)
- info = pool.info()
- autostart = True if pool.autostart() else False
- persistent = True if pool.isPersistent() else False
- xml = pool.XMLDesc(0)
- path = xpath_get_text(xml, "/pool/target/path")[0]
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- source = self._get_storage_source(pool_type, xml)
- # FIXME: nfs workaround - prevent any libvirt operation
- # for a nfs if the corresponding NFS server is down.
- if pool_type == 'netfs' and not self._nfs_status_online(pool):
- wok_log.debug("NFS pool %s is offline, reason: NFS "
- "server %s is unreachable.", name, source['addr'])
- # Mark state as '4' => inaccessible.
- info[0] = 4
- # skip calculating volumes
- nr_volumes = 0
- else:
- nr_volumes = self._get_storagepool_vols_num(pool)
-
- res = {'state': POOL_STATE_MAP[info[0]],
- 'path': path,
- 'source': source,
- 'type': pool_type,
- 'autostart': autostart,
- 'capacity': info[1],
- 'allocated': info[2],
- 'available': info[3],
- 'nr_volumes': nr_volumes,
- 'persistent': persistent}
-
- if not pool.isPersistent():
- # Deal with deep scan generated pool
- try:
- with self.objstore as session:
- task_id = session.get('scanning', name)
- res['task_id'] = str(task_id)
- res['type'] = 'kimchi-iso'
- except NotFoundError:
- # User created normal pool
- pass
- return res
-
- def _update_lvm_disks(self, pool_name, disks):
- # check if all the disks/partitions exists in the host
- for disk in disks:
- lsblk_cmd = ['lsblk', disk]
- output, error, returncode = run_command(lsblk_cmd)
- if returncode != 0:
- wok_log.error('%s is not a valid disk/partition. Could not '
- 'add it to the pool %s.', disk, pool_name)
- raise OperationFailed('KCHPOOL0027E', {'disk': disk,
- 'pool': pool_name})
- # add disks to the lvm pool using vgextend + virsh refresh
- vgextend_cmd = ["vgextend", pool_name]
- vgextend_cmd += disks
- output, error, returncode = run_command(vgextend_cmd)
- if returncode != 0:
- msg = "Could not add disks to pool %s, error: %s"
- wok_log.error(msg, pool_name, error)
- raise OperationFailed('KCHPOOL0028E', {'pool': pool_name,
- 'err': error})
- # refreshing pool state
- pool = self.get_storagepool(pool_name, self.conn)
- if pool.isActive():
- pool.refresh(0)
-
- def update(self, name, params):
- pool = self.get_storagepool(name, self.conn)
- if 'autostart' in params:
- if params['autostart']:
- pool.setAutostart(1)
- else:
- pool.setAutostart(0)
-
- if 'disks' in params:
- # check if pool is type 'logical'
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type != 'logical':
- raise InvalidOperation('KCHPOOL0029E')
- self._update_lvm_disks(name, params['disks'])
- ident = pool.name()
- return ident.decode('utf-8')
-
- def activate(self, name):
- pool = self.get_storagepool(name, self.conn)
- # FIXME: nfs workaround - do not activate a NFS pool
- # if the NFS server is not reachable.
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type == 'netfs' and not self._nfs_status_online(pool):
- # block the user from activating the pool.
- source = self._get_storage_source(pool_type, xml)
- raise OperationFailed("KCHPOOL0032E",
- {'name': name, 'server': source['addr']})
- return
- try:
- pool.create(0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0009E",
- {'name': name, 'err': e.get_error_message()})
-
- def _pool_used_by_template(self, pool_name):
- with self.objstore as session:
- templates = session.get_list('template')
- for tmpl in templates:
- t_info = session.get('template', tmpl)
- t_pool = pool_name_from_uri(t_info['storagepool'])
- if t_pool == pool_name:
- return True
- return False
-
- def deactivate(self, name):
- if self._pool_used_by_template(name):
- raise InvalidOperation('KCHPOOL0034E', {'name': name})
-
- pool = self.get_storagepool(name, self.conn)
- # FIXME: nfs workaround - do not try to deactivate a NFS pool
- # if the NFS server is not reachable.
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type == 'netfs' and not self._nfs_status_online(pool):
- # block the user from dactivating the pool.
- source = self._get_storage_source(pool_type, xml)
- raise OperationFailed("KCHPOOL0033E",
- {'name': name, 'server': source['addr']})
- return
- try:
- persistent = pool.isPersistent()
- pool.destroy()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0010E",
- {'name': name, 'err': e.get_error_message()})
- # If pool was not persistent, then it was erased by destroy() and
- # must return nothing here, to trigger _redirect() and avoid errors
- if not persistent:
- return ""
-
- def delete(self, name):
- if self._pool_used_by_template(name):
- raise InvalidOperation('KCHPOOL0035E', {'name': name})
-
- pool = self.get_storagepool(name, self.conn)
- if pool.isActive():
- raise InvalidOperation("KCHPOOL0005E", {'name': name})
- try:
- pool.undefine()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0011E",
- {'name': name, 'err': e.get_error_message()})
-
-
-class IsoPoolModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- return {'state': 'active',
- 'type': 'kimchi-iso'}
diff --git a/plugins/kimchi/model/storageservers.py b/plugins/kimchi/model/storageservers.py
deleted file mode 100644
index accc5f5..0000000
--- a/plugins/kimchi/model/storageservers.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.exception import NotFoundError
-
-from storagepools import StoragePoolModel, StoragePoolsModel
-
-# Types of remote storage servers supported
-STORAGE_SERVERS = ['netfs', 'iscsi']
-
-
-class StorageServersModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.pool = StoragePoolModel(**kargs)
- self.pools = StoragePoolsModel(**kargs)
-
- def get_list(self, _target_type=None):
- if not _target_type:
- target_type = STORAGE_SERVERS
- else:
- target_type = [_target_type]
-
- pools = self.pools.get_list()
-
- server_list = []
- for pool in pools:
- try:
- pool_info = self.pool.lookup(pool)
- if (pool_info['type'] in target_type and
- pool_info['source']['addr'] not in server_list):
- # Avoid to add same server for multiple times
- # if it hosts more than one storage type
- server_list.append(pool_info['source']['addr'])
- except NotFoundError:
- pass
-
- return server_list
-
-
-class StorageServerModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.pool = StoragePoolModel(**kargs)
-
- def lookup(self, server):
- conn = self.conn.get()
- pools = conn.listStoragePools()
- pools += conn.listDefinedStoragePools()
- for pool in pools:
- try:
- pool_info = self.pool.lookup(pool)
- if (pool_info['type'] in STORAGE_SERVERS and
- pool_info['source']['addr'] == server):
- info = dict(host=server)
- if (pool_info['type'] == "iscsi" and
- 'port' in pool_info['source']):
- info["port"] = pool_info['source']['port']
- return info
- except NotFoundError:
- # Avoid inconsistent pool result because of lease between list
- # lookup
- pass
-
- raise NotFoundError("KCHSR0001E", {'server': server})
diff --git a/plugins/kimchi/model/storagetargets.py b/plugins/kimchi/model/storagetargets.py
deleted file mode 100644
index 4090b45..0000000
--- a/plugins/kimchi/model/storagetargets.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-from lxml import objectify
-from lxml.builder import E
-
-from wok.utils import patch_find_nfs_target, wok_log
-
-from config import CapabilitiesModel
-from storageservers import STORAGE_SERVERS
-
-
-class StorageTargetsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
-
- def get_list(self, storage_server, _target_type=None, _server_port=None):
- target_list = list()
- if not _target_type:
- target_types = STORAGE_SERVERS
- else:
- target_types = [_target_type]
-
- for target_type in target_types:
- if not self.caps.nfs_target_probe and target_type == 'netfs':
- targets = patch_find_nfs_target(storage_server)
- else:
- xml = self._get_storage_server_spec(server=storage_server,
- target_type=target_type,
- server_port=_server_port)
- conn = self.conn.get()
- try:
- ret = conn.findStoragePoolSources(target_type, xml, 0)
- except libvirt.libvirtError as e:
- err = "Query storage pool source fails because of %s"
- wok_log.warning(err, e.get_error_message())
- continue
-
- targets = self._parse_target_source_result(target_type, ret)
-
- target_list.extend(targets)
-
- # Get all netfs and iscsi paths in use
- used_paths = []
- try:
- conn = self.conn.get()
- # Get all existing ISCSI and NFS pools
- pools = conn.listAllStoragePools(
- libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI |
- libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_NETFS)
- for pool in pools:
- pool_xml = pool.XMLDesc(0)
- root = objectify.fromstring(pool_xml)
- if root.get('type') == 'netfs' and \
- root.source.dir is not None:
- used_paths.append(root.source.dir.get('path'))
- elif root.get('type') == 'iscsi' and \
- root.source.device is not None:
- used_paths.append(root.source.device.get('path'))
-
- except libvirt.libvirtError as e:
- err = "Query storage pool source fails because of %s"
- wok_log.warning(err, e.get_error_message())
-
- # Filter target_list to not not show the used paths
- target_list = [elem for elem in target_list
- if elem.get('target') not in used_paths]
- return [dict(t) for t in set(tuple(t.items()) for t in target_list)]
-
- def _get_storage_server_spec(self, **kwargs):
- # Required parameters:
- # server:
- # target_type:
- extra_args = []
- server_type = kwargs['target_type']
- if server_type == 'netfs':
- extra_args.append(E.format(type='nfs'))
- else:
- extra_args.append(E.format(type=server_type))
-
- host_attr = {"name": kwargs['server']}
- server_port = kwargs.get("server_port")
- if server_port is not None:
- host_attr['port'] = server_port
-
- obj = E.source(E.host(host_attr), *extra_args)
- xml = ET.tostring(obj)
- return xml
-
- def _parse_target_source_result(self, target_type, xml_str):
- root = objectify.fromstring(xml_str)
- ret = []
- for source in root.getchildren():
- if target_type == 'netfs':
- target_path = source.dir.get('path')
- type = source.format.get('type')
- if target_type == 'iscsi':
- target_path = source.device.get('path')
- type = target_type
- host_name = source.host.get('name')
- ret.append(dict(host=host_name, target_type=type,
- target=target_path))
- return ret
diff --git a/plugins/kimchi/model/storagevolumes.py b/plugins/kimchi/model/storagevolumes.py
deleted file mode 100644
index 99b17d3..0000000
--- a/plugins/kimchi/model/storagevolumes.py
+++ /dev/null
@@ -1,542 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import contextlib
-import libvirt
-import lxml.etree as ET
-import os
-import tempfile
-import threading
-import time
-import urllib2
-from lxml.builder import E
-
-from wok.exception import InvalidOperation, InvalidParameter, IsoFormatError
-from wok.exception import MissingParameter, NotFoundError, OperationFailed
-from wok.utils import add_task, get_next_clone_name, get_unique_file_name
-from wok.utils import wok_log
-from wok.xmlutils.utils import xpath_get_text
-from wok.model.tasks import TaskModel
-
-from ..config import READONLY_POOL_TYPE
-from ..isoinfo import IsoImage
-from diskutils import get_disk_used_by, set_disk_used_by
-from storagepools import StoragePoolModel
-
-
-VOLUME_TYPE_MAP = {0: 'file',
- 1: 'block',
- 2: 'directory',
- 3: 'network'}
-
-READ_CHUNK_SIZE = 1048576 # 1 MiB
-REQUIRE_NAME_PARAMS = ['capacity']
-
-upload_volumes = dict()
-
-
-class StorageVolumesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
-
- def create(self, pool_name, params):
- vol_source = ['url', 'capacity']
-
- name = params.get('name')
-
- index_list = list(i for i in range(len(vol_source))
- if vol_source[i] in params)
- if len(index_list) != 1:
- raise InvalidParameter("KCHVOL0018E",
- {'param': ",".join(vol_source)})
-
- create_param = vol_source[index_list[0]]
-
- # Verify if the URL is valid
- if create_param == 'url':
- url = params['url']
- try:
- urllib2.urlopen(url).close()
- except:
- raise InvalidParameter('KCHVOL0022E', {'url': url})
-
- all_vol_names = self.get_list(pool_name)
-
- if name is None:
- # the methods listed in 'REQUIRE_NAME_PARAMS' cannot have
- # 'name' == None
- if create_param in REQUIRE_NAME_PARAMS:
- raise InvalidParameter('KCHVOL0016E')
-
- # if 'name' is omitted - except for the methods listed in
- # 'REQUIRE_NAME_PARAMS' - the default volume name will be the
- # file/URL basename.
- if create_param == 'url':
- name = os.path.basename(params['url'])
- else:
- name = 'upload-%s' % int(time.time())
-
- name = get_unique_file_name(all_vol_names, name)
- params['name'] = name
-
- try:
- create_func = getattr(self, '_create_volume_with_%s' %
- create_param)
- except AttributeError:
- raise InvalidParameter("KCHVOL0019E", {'param': create_param})
-
- pool_info = StoragePoolModel(conn=self.conn,
- objstore=self.objstore).lookup(pool_name)
- if pool_info['type'] in READONLY_POOL_TYPE:
- raise InvalidParameter("KCHVOL0012E", {'type': pool_info['type']})
- if pool_info['state'] == 'inactive':
- raise InvalidParameter('KCHVOL0003E', {'pool': pool_name,
- 'volume': name})
- if name in all_vol_names:
- raise InvalidParameter('KCHVOL0001E', {'name': name})
-
- params['pool'] = pool_name
- targeturi = '/plugins/kimchi/storagepools/%s/storagevolumes/%s' \
- % (pool_name, name)
- taskid = add_task(targeturi, create_func, self.objstore, params)
- return self.task.lookup(taskid)
-
- def _create_volume_with_capacity(self, cb, params):
- pool_name = params.pop('pool')
- vol_xml = """
- <volume>
- <name>%(name)s</name>
- <allocation unit='bytes'>%(allocation)s</allocation>
- <capacity unit='bytes'>%(capacity)s</capacity>
- <source>
- </source>
- <target>
- <format type='%(format)s'/>
- </target>
- </volume>
- """
- params.setdefault('allocation', 0)
- params.setdefault('format', 'qcow2')
-
- name = params['name']
- try:
- pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- xml = vol_xml % params
- except KeyError, item:
- raise MissingParameter("KCHVOL0004E", {'item': str(item),
- 'volume': name})
-
- try:
- pool.createXML(xml, 0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0007E",
- {'name': name, 'pool': pool,
- 'err': e.get_error_message()})
-
- vol_info = StorageVolumeModel(conn=self.conn,
- objstore=self.objstore).lookup(pool_name,
- name)
-
- vol_path = vol_info['path']
- set_disk_used_by(self.objstore, vol_info['path'], [])
-
- if params.get('upload', False):
- upload_volumes[vol_path] = {'lock': threading.Lock(),
- 'offset': 0, 'cb': cb}
- cb('ready for upload')
- else:
- cb('OK', True)
-
- def _create_volume_with_url(self, cb, params):
- pool_name = params['pool']
- name = params['name']
- url = params['url']
-
- pool_model = StoragePoolModel(conn=self.conn,
- objstore=self.objstore)
- pool = pool_model.lookup(pool_name)
-
- if pool['type'] in ['dir', 'netfs']:
- file_path = os.path.join(pool['path'], name)
- else:
- file_path = tempfile.mkstemp(prefix=name)[1]
-
- with contextlib.closing(urllib2.urlopen(url)) as response:
- with open(file_path, 'w') as volume_file:
- remote_size = response.info().getheader('Content-Length', '-')
- downloaded_size = 0
-
- try:
- while True:
- chunk_data = response.read(READ_CHUNK_SIZE)
- if not chunk_data:
- break
-
- volume_file.write(chunk_data)
- downloaded_size += len(chunk_data)
- cb('%s/%s' % (downloaded_size, remote_size))
- except (IOError, libvirt.libvirtError) as e:
- if os.path.isfile(file_path):
- os.remove(file_path)
-
- raise OperationFailed('KCHVOL0007E', {'name': name,
- 'pool': pool_name,
- 'err': e.message})
-
- if pool['type'] in ['dir', 'netfs']:
- virt_pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- virt_pool.refresh(0)
- else:
- def _stream_handler(stream, nbytes, fd):
- return fd.read(nbytes)
-
- virt_stream = virt_vol = None
-
- try:
- task = self.create(pool_name, {'name': name,
- 'format': 'raw',
- 'capacity': downloaded_size,
- 'allocation': downloaded_size})
- self.task.wait(task['id'])
- virt_vol = StorageVolumeModel.get_storagevolume(pool_name,
- name,
- self.conn)
-
- virt_stream = self.conn.get().newStream(0)
- virt_vol.upload(virt_stream, 0, downloaded_size, 0)
-
- with open(file_path) as fd:
- virt_stream.sendAll(_stream_handler, fd)
-
- virt_stream.finish()
- except (IOError, libvirt.libvirtError) as e:
- try:
- if virt_stream:
- virt_stream.abort()
- if virt_vol:
- virt_vol.delete(0)
- except libvirt.libvirtError, virt_e:
- wok_log.error(virt_e.message)
- finally:
- raise OperationFailed('KCHVOL0007E', {'name': name,
- 'pool': pool_name,
- 'err': e.message})
- finally:
- os.remove(file_path)
-
- vol_info = StorageVolumeModel(conn=self.conn,
- objstore=self.objstore).lookup(pool_name,
- name)
- set_disk_used_by(self.objstore, vol_info['path'], [])
-
- cb('OK', True)
-
- def get_list(self, pool_name):
- pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- if not pool.isActive():
- raise InvalidOperation("KCHVOL0006E", {'pool': pool_name})
- try:
- pool.refresh(0)
- return sorted(map(lambda x: x.decode('utf-8'), pool.listVolumes()))
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0008E",
- {'pool': pool_name,
- 'err': e.get_error_message()})
-
-
-class StorageVolumeModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
- self.storagevolumes = StorageVolumesModel(**kargs)
- self.storagepool = StoragePoolModel(**kargs)
-
- @staticmethod
- def get_storagevolume(poolname, name, conn):
- pool = StoragePoolModel.get_storagepool(poolname, conn)
- if not pool.isActive():
- raise InvalidOperation("KCHVOL0006E", {'name': pool})
- try:
- return pool.storageVolLookupByName(name.encode("utf-8"))
- except libvirt.libvirtError as e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_VOL:
- raise NotFoundError("KCHVOL0002E", {'name': name,
- 'pool': poolname})
- else:
- raise
-
- def lookup(self, pool, name):
- vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- path = vol.path()
- info = vol.info()
- xml = vol.XMLDesc(0)
- try:
- fmt = xpath_get_text(xml, "/volume/target/format/@type")[0]
- except IndexError:
- # Not all types of libvirt storage can provide volume format
- # infomation. When there is no format information, we assume
- # it's 'raw'.
- fmt = 'raw'
-
- iso_img = None
-
- # 'raw' volumes from 'logical' pools may actually be 'iso';
- # libvirt always reports them as 'raw'
- pool_info = self.storagepool.lookup(pool)
- if pool_info['type'] == 'logical' and fmt == 'raw':
- try:
- iso_img = IsoImage(path)
- except IsoFormatError:
- # not 'iso' afterall
- pass
- else:
- fmt = 'iso'
-
- used_by = get_disk_used_by(self.objstore, self.conn, path)
- res = dict(type=VOLUME_TYPE_MAP[info[0]],
- capacity=info[1],
- allocation=info[2],
- path=path,
- used_by=used_by,
- format=fmt)
- if fmt == 'iso':
- if os.path.islink(path):
- path = os.path.join(os.path.dirname(path), os.readlink(path))
- os_distro = os_version = 'unknown'
- try:
- if iso_img is None:
- iso_img = IsoImage(path)
- os_distro, os_version = iso_img.probe()
- bootable = True
- except IsoFormatError:
- bootable = False
- res.update(
- dict(os_distro=os_distro, os_version=os_version, path=path,
- bootable=bootable))
- return res
-
- def wipe(self, pool, name):
- volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- try:
- volume.wipePattern(libvirt.VIR_STORAGE_VOL_WIPE_ALG_ZERO, 0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0009E",
- {'name': name, 'err': e.get_error_message()})
-
- def delete(self, pool, name):
- pool_info = StoragePoolModel(conn=self.conn,
- objstore=self.objstore).lookup(pool)
- if pool_info['type'] in READONLY_POOL_TYPE:
- raise InvalidParameter("KCHVOL0012E", {'type': pool_info['type']})
-
- volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- try:
- volume.delete(0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0010E",
- {'name': name, 'err': e.get_error_message()})
-
- def resize(self, pool, name, size):
- volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
-
- # When decreasing the storage volume capacity, the flag
- # VIR_STORAGE_VOL_RESIZE_SHRINK must be used
- flags = 0
- if volume.info()[1] > size:
- # FIXME: Even using VIR_STORAGE_VOL_RESIZE_SHRINK flag it is not
- # possible to decrease the volume capacity due a libvirt bug
- # For reference:
- # - https://bugzilla.redhat.com/show_bug.cgi?id=1021802
- flags = libvirt.VIR_STORAGE_VOL_RESIZE_SHRINK
-
- try:
- volume.resize(size, flags)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0011E",
- {'name': name, 'err': e.get_error_message()})
-
- def clone(self, pool, name, new_pool=None, new_name=None):
- """Clone a storage volume.
-
- Arguments:
- pool -- The name of the original pool.
- name -- The name of the original volume.
- new_pool -- The name of the destination pool (optional). If omitted,
- the new volume will be created on the same pool as the
- original one.
- new_name -- The name of the new volume (optional). If omitted, a new
- value based on the original volume's name will be used.
-
- Return:
- A Task running the clone operation.
- """
- # the same pool will be used if no pool is specified
- if new_pool is None:
- new_pool = pool
-
- # a default name based on the original name will be used if no name
- # is specified
- if new_name is None:
- base, ext = os.path.splitext(name)
- new_name = get_next_clone_name(self.storagevolumes.get_list(pool),
- base, ext)
-
- params = {'pool': pool,
- 'name': name,
- 'new_pool': new_pool,
- 'new_name': new_name}
- taskid = add_task(u'/plugins/kimchi/storagepools/%s/storagevolumes/%s'
- % (pool, new_name), self._clone_task, self.objstore,
- params)
- return self.task.lookup(taskid)
-
- def _clone_task(self, cb, params):
- """Asynchronous function which performs the clone operation.
-
- This function copies all the data inside the original volume into the
- new one.
-
- Arguments:
- cb -- A callback function to signal the Task's progress.
- params -- A dict with the following values:
- "pool": The name of the original pool.
- "name": The name of the original volume.
- "new_pool": The name of the destination pool.
- "new_name": The name of the new volume.
- """
- orig_pool_name = params['pool']
- orig_vol_name = params['name']
- new_pool_name = params['new_pool']
- new_vol_name = params['new_name']
-
- try:
- cb('setting up volume cloning')
- orig_vir_vol = StorageVolumeModel.get_storagevolume(orig_pool_name,
- orig_vol_name,
- self.conn)
- orig_vol = self.lookup(orig_pool_name, orig_vol_name)
- new_vir_pool = StoragePoolModel.get_storagepool(new_pool_name,
- self.conn)
-
- cb('building volume XML')
- root_elem = E.volume()
- root_elem.append(E.name(new_vol_name))
- root_elem.append(E.capacity(unicode(orig_vol['capacity']),
- unit='bytes'))
- target_elem = E.target()
- target_elem.append(E.format(type=orig_vol['format']))
- root_elem.append(target_elem)
- new_vol_xml = ET.tostring(root_elem, encoding='utf-8',
- pretty_print=True)
-
- cb('cloning volume')
- new_vir_pool.createXMLFrom(new_vol_xml, orig_vir_vol, 0)
- except (InvalidOperation, NotFoundError, libvirt.libvirtError), e:
- raise OperationFailed('KCHVOL0023E',
- {'name': orig_vol_name,
- 'pool': orig_pool_name,
- 'err': e.get_error_message()})
-
- new_vol = self.lookup(new_pool_name, new_vol_name)
- cb('adding volume to the object store')
- set_disk_used_by(self.objstore, new_vol['path'], [])
-
- cb('OK', True)
-
- def doUpload(self, cb, vol, offset, data, data_size):
- try:
- st = self.conn.get().newStream(0)
- vol.upload(st, offset, data_size)
- st.send(data)
- st.finish()
- except Exception as e:
- st and st.abort()
- cb('', False)
-
- try:
- vol.delete(0)
- except Exception as e:
- pass
-
- raise OperationFailed("KCHVOL0029E", {"err": e.message})
-
- def update(self, pool, name, params):
- chunk_data = params['chunk'].fullvalue()
- chunk_size = int(params['chunk_size'])
-
- if len(chunk_data) != chunk_size:
- raise OperationFailed("KCHVOL0026E")
-
- vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- vol_path = vol.path()
- vol_capacity = vol.info()[1]
-
- vol_data = upload_volumes.get(vol_path)
- if vol_data is None:
- raise OperationFailed("KCHVOL0027E", {"vol": vol_path})
-
- cb = vol_data['cb']
- lock = vol_data['lock']
- with lock:
- offset = vol_data['offset']
- if (offset + chunk_size) > vol_capacity:
- raise OperationFailed("KCHVOL0028E")
-
- cb('%s/%s' % (offset, vol_capacity))
- self.doUpload(cb, vol, offset, chunk_data, chunk_size)
- cb('%s/%s' % (offset + chunk_size, vol_capacity))
-
- vol_data['offset'] += chunk_size
- if vol_data['offset'] == vol_capacity:
- del upload_volumes[vol_path]
- cb('OK', True)
-
-
-class IsoVolumesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.storagevolume = StorageVolumeModel(**kargs)
-
- def get_list(self):
- iso_volumes = []
- conn = self.conn.get()
- pools = conn.listStoragePools()
- pools += conn.listDefinedStoragePools()
-
- for pool_name in pools:
- try:
- pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- pool.refresh(0)
- volumes = pool.listVolumes()
- except Exception, e:
- # Skip inactive pools
- wok_log.debug("Shallow scan: skipping pool %s because of "
- "error: %s", (pool_name, e.message))
- continue
-
- for volume in volumes:
- res = self.storagevolume.lookup(pool_name,
- volume.decode("utf-8"))
- if res['format'] == 'iso' and res['bootable']:
- res['name'] = '%s' % volume
- iso_volumes.append(res)
- return iso_volumes
diff --git a/plugins/kimchi/model/templates.py b/plugins/kimchi/model/templates.py
deleted file mode 100644
index 4f0b204..0000000
--- a/plugins/kimchi/model/templates.py
+++ /dev/null
@@ -1,303 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import copy
-import libvirt
-import os
-import stat
-
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import probe_file_permission_as_user, run_setfacl_set_attr
-from wok.xmlutils.utils import xpath_get_text
-
-from ..kvmusertests import UserTests
-from ..utils import pool_name_from_uri
-from ..vmtemplate import VMTemplate
-from cpuinfo import CPUInfoModel
-
-
-class TemplatesModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.conn = kargs['conn']
-
- def create(self, params):
- name = params.get('name', '').strip()
- iso = params.get('cdrom')
- # check search permission
- if iso and iso.startswith('/') and os.path.exists(iso):
- st_mode = os.stat(iso).st_mode
- if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
- user = UserTests().probe_user()
- run_setfacl_set_attr(iso, user=user)
- ret, excp = probe_file_permission_as_user(iso, user)
- if ret is False:
- raise InvalidParameter('KCHISO0008E',
- {'filename': iso, 'user': user,
- 'err': excp})
-
- cpu_info = params.get('cpu_info')
- if cpu_info:
- topology = cpu_info.get('topology')
- # Check, even though currently only topology
- # is supported.
- if topology:
- sockets = topology['sockets']
- cores = topology['cores']
- threads = topology['threads']
- if params.get('cpus') is None:
- params['cpus'] = sockets * cores * threads
- # check_topoology will raise the appropriate
- # exception if a topology is invalid.
- CPUInfoModel(conn=self.conn).\
- check_topology(params['cpus'], topology)
-
- conn = self.conn.get()
- pool_uri = params.get(u'storagepool', '')
- if pool_uri:
- try:
- pool_name = pool_name_from_uri(pool_uri)
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- except Exception:
- raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
- 'template': name})
-
- tmp_volumes = [disk['volume'] for disk in params.get('disks', [])
- if 'volume' in disk]
- self.template_volume_validate(tmp_volumes, pool)
-
- for net_name in params.get(u'networks', []):
- try:
- conn.networkLookupByName(net_name.encode('utf-8'))
- except Exception:
- raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
- 'template': name})
- # Creates the template class with necessary information
- # Checkings will be done while creating this class, so any exception
- # will be raised here
- t = LibvirtVMTemplate(params, scan=True, conn=self.conn)
- name = params['name']
- try:
- with self.objstore as session:
- if name in session.get_list('template'):
- raise InvalidOperation("KCHTMPL0001E", {'name': name})
- session.store('template', name, t.info)
- except InvalidOperation:
- raise
- except Exception, e:
- raise OperationFailed('KCHTMPL0020E', {'err': e.message})
-
- return name
-
- def get_list(self):
- with self.objstore as session:
- return session.get_list('template')
-
- def template_volume_validate(self, tmp_volumes, pool):
- kwargs = {'conn': self.conn, 'objstore': self.objstore}
- pool_type = xpath_get_text(pool.XMLDesc(0), "/pool/@type")[0]
- pool_name = unicode(pool.name(), 'utf-8')
-
- # as we discussion, we do not mix disks from 2 different types of
- # storage pools, for instance: we do not create a template with 2
- # disks, where one comes from a SCSI pool and other is a .img in
- # a DIR pool.
- if pool_type in ['iscsi', 'scsi']:
- if not tmp_volumes:
- raise InvalidParameter("KCHTMPL0018E")
-
- storagevolumes = __import__("kimchi.model.storagevolumes",
- fromlist=[''])
- pool_volumes = storagevolumes.StorageVolumesModel(
- **kwargs).get_list(pool_name)
- vols = set(tmp_volumes) - set(pool_volumes)
- if vols:
- raise InvalidParameter("KCHTMPL0019E", {'pool': pool_name,
- 'volume': vols})
-
-
-class TemplateModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.conn = kargs['conn']
- self.templates = TemplatesModel(**kargs)
-
- @staticmethod
- def get_template(name, objstore, conn, overrides=None):
- with objstore as session:
- params = session.get('template', name)
- if overrides:
- params.update(overrides)
- return LibvirtVMTemplate(params, False, conn)
-
- def lookup(self, name):
- t = self.get_template(name, self.objstore, self.conn)
- return t.validate_integrity()
-
- def clone(self, name):
- # set default name
- subfixs = [v[len(name):] for v in self.templates.get_list()
- if v.startswith(name)]
- indexs = [int(v.lstrip("-clone")) for v in subfixs
- if v.startswith("-clone") and
- v.lstrip("-clone").isdigit()]
- indexs.sort()
- index = "1" if not indexs else str(indexs[-1] + 1)
- clone_name = name + "-clone" + index
-
- temp = self.lookup(name)
- temp['name'] = clone_name
- ident = self.templates.create(temp)
- return ident
-
- def delete(self, name):
- try:
- with self.objstore as session:
- session.delete('template', name)
- except NotFoundError:
- raise
- except Exception as e:
- raise OperationFailed('KCHTMPL0021E', {'err': e.message})
-
- def update(self, name, params):
- old_t = self.lookup(name)
- new_t = copy.copy(old_t)
- new_t.update(params)
-
- if not self._validate_updated_cpu_params(new_t):
- raise InvalidParameter('KCHTMPL0025E')
-
- ident = name
-
- conn = self.conn.get()
- pool_uri = new_t.get(u'storagepool', '')
-
- if pool_uri:
- try:
- pool_name = pool_name_from_uri(pool_uri)
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- except Exception:
- raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
- 'template': name})
- tmp_volumes = [disk['volume'] for disk in new_t.get('disks', [])
- if 'volume' in disk]
- self.templates.template_volume_validate(tmp_volumes, pool)
-
- for net_name in params.get(u'networks', []):
- try:
- conn.networkLookupByName(net_name.encode('utf-8'))
- except Exception:
- raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
- 'template': name})
-
- self.delete(name)
- try:
- ident = self.templates.create(new_t)
- except:
- ident = self.templates.create(old_t)
- raise
- return ident
-
- def _validate_updated_cpu_params(self, info):
- # Note: cpu_info is the parent of topology. cpus is vcpus
- vcpus = info['cpus']
- cpu_info = info.get('cpu_info')
- # cpu_info will always be at least an empty dict
- topology = cpu_info.get('topology')
- if topology is None:
- return True
- return vcpus == topology['sockets'] * topology['cores'] * \
- topology['threads']
-
-
-class LibvirtVMTemplate(VMTemplate):
- def __init__(self, args, scan=False, conn=None):
- self.conn = conn
- VMTemplate.__init__(self, args, scan)
-
- def _storage_validate(self):
- pool_uri = self.info['storagepool']
- pool_name = pool_name_from_uri(pool_uri)
- try:
- conn = self.conn.get()
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- except libvirt.libvirtError:
- raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
- 'template': self.name})
-
- if not pool.isActive():
- raise InvalidParameter("KCHTMPL0005E", {'pool': pool_name,
- 'template': self.name})
-
- return pool
-
- def _get_all_networks_name(self):
- conn = self.conn.get()
- return sorted(conn.listNetworks() + conn.listDefinedNetworks())
-
- def _get_all_storagepools_name(self):
- conn = self.conn.get()
- names = conn.listStoragePools() + conn.listDefinedStoragePools()
- return sorted(map(lambda x: x.decode('utf-8'), names))
-
- def _network_validate(self):
- names = self.info['networks']
- for name in names:
- try:
- conn = self.conn.get()
- network = conn.networkLookupByName(name.encode('utf-8'))
- except libvirt.libvirtError:
- raise InvalidParameter("KCHTMPL0003E", {'network': name,
- 'template': self.name})
-
- if not network.isActive():
- raise InvalidParameter("KCHTMPL0007E", {'network': name,
- 'template': self.name})
-
- def _get_storage_path(self):
- pool = self._storage_validate()
- xml = pool.XMLDesc(0)
- return xpath_get_text(xml, "/pool/target/path")[0]
-
- def _get_storage_type(self):
- pool = self._storage_validate()
- xml = pool.XMLDesc(0)
- return xpath_get_text(xml, "/pool/@type")[0]
-
- def _get_volume_path(self, pool, vol):
- pool = self._storage_validate()
- try:
- return pool.storageVolLookupByName(vol).path()
- except:
- raise NotFoundError("KCHVOL0002E", {'name': vol,
- 'pool': pool})
-
- def fork_vm_storage(self, vm_uuid):
- # Provision storage:
- # TODO: Rebase on the storage API once upstream
- pool = self._storage_validate()
- vol_list = self.to_volume_list(vm_uuid)
- try:
- for v in vol_list:
- # outgoing text to libvirt, encode('utf-8')
- pool.createXML(v['xml'].encode('utf-8'), 0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
- return vol_list
diff --git a/plugins/kimchi/model/users.py b/plugins/kimchi/model/users.py
deleted file mode 100644
index 2fa65dd..0000000
--- a/plugins/kimchi/model/users.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ldap
-import pwd
-
-from wok.config import config
-from wok.exception import NotFoundError
-
-
-class UsersModel(object):
- def __init__(self, **args):
- auth_type = config.get("authentication", "method")
- for klass in UsersModel.__subclasses__():
- if auth_type == klass.auth_type:
- self.user = klass(**args)
-
- def get_list(self, **args):
- return self.user._get_list(**args)
-
- def validate(self, user):
- return self.user._validate(user)
-
-
-class PAMUsersModel(UsersModel):
- auth_type = 'pam'
-
- def __init__(self, **kargs):
- pass
-
- def _get_list(self):
- return [user.pw_name for user in pwd.getpwall()
- if user.pw_shell.rsplit("/")[-1] not in ["nologin", "false"]]
-
- def _validate(self, user):
- try:
- return user in self._get_list()
- except:
- return False
-
-
-class LDAPUsersModel(UsersModel):
- auth_type = 'ldap'
-
- def __init__(self, **kargs):
- pass
-
- def _get_list(self, _user_id=''):
- return self._get_user(_user_id)
-
- def _validate(self, user):
- try:
- self._get_user(user)
- return True
- except NotFoundError:
- return False
-
- def _get_user(self, _user_id):
- ldap_server = config.get("authentication", "ldap_server").strip('"')
- ldap_search_base = config.get(
- "authentication", "ldap_search_base").strip('"')
- ldap_search_filter = config.get(
- "authentication", "ldap_search_filter",
- vars={"username": _user_id.encode("utf-8")}).strip('"')
-
- connect = ldap.open(ldap_server)
- try:
- result = connect.search_s(
- ldap_search_base, ldap.SCOPE_SUBTREE, ldap_search_filter)
- if len(result) == 0:
- raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
- return result[0][1]
- except ldap.NO_SUCH_OBJECT:
- raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
diff --git a/plugins/kimchi/model/utils.py b/plugins/kimchi/model/utils.py
deleted file mode 100644
index 53d719d..0000000
--- a/plugins/kimchi/model/utils.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-from lxml import etree, objectify
-from lxml.builder import E, ElementMaker
-
-from wok.exception import OperationFailed
-
-
-KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi"
-KIMCHI_NAMESPACE = "kimchi"
-
-
-def get_vm_name(vm_name, t_name, name_list):
- if vm_name:
- return vm_name
- for i in xrange(1, 1000):
- # VM will have templace name, but without slashes
- vm_name = "%s-vm-%i" % (t_name.replace('/', '-'), i)
- if vm_name not in name_list:
- return vm_name
- raise OperationFailed("KCHUTILS0003E")
-
-
-def get_vm_config_flag(dom, mode="persistent"):
- # libvirt.VIR_DOMAIN_AFFECT_CURRENT is 0
- # VIR_DOMAIN_AFFECT_LIVE is 1, VIR_DOMAIN_AFFECT_CONFIG is 2
- flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE,
- "persistent": libvirt.VIR_DOMAIN_AFFECT_CONFIG,
- "current": libvirt.VIR_DOMAIN_AFFECT_CURRENT,
- "all": libvirt.VIR_DOMAIN_AFFECT_CONFIG +
- libvirt.VIR_DOMAIN_AFFECT_LIVE if dom.isActive() and
- dom.isPersistent() else libvirt.VIR_DOMAIN_AFFECT_CURRENT}
-
- return flag[mode]
-
-
-# avoid duplicate codes
-def update_node(root, node):
- old_node = root.find(node.tag)
- (root.replace(old_node, node) if old_node is not None
- else root.append(node))
- return root
-
-
-def _kimchi_set_metadata_node(dom, node):
- # some other tools will not let libvirt create a persistent
- # configuration, raise exception.
- if not dom.isPersistent():
- msg = 'The VM has not a persistent configuration'
- raise OperationFailed("KCHVM0030E",
- {'name': dom.name(), "err": msg})
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
- root = etree.fromstring(xml)
- kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
-
- EM = ElementMaker(namespace=KIMCHI_META_URL,
- nsmap={KIMCHI_NAMESPACE: KIMCHI_META_URL})
- kimchi = EM("kimchi") if kimchi is None else kimchi
-
- update_node(kimchi, node)
- metadata = root.find("metadata")
- metadata = E.metadata() if metadata is None else metadata
- update_node(metadata, kimchi)
- update_node(root, metadata)
- dom.connect().defineXML(etree.tostring(root))
-
-
-def libvirt_get_kimchi_metadata_node(dom, mode="current"):
- if not metadata_exists(dom):
- return None
- try:
- xml = dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
- KIMCHI_META_URL,
- flags=get_vm_config_flag(dom, mode))
- return etree.fromstring(xml)
- except libvirt.libvirtError:
- return None
-
-
-def set_metadata_node(dom, node, metadata_support, mode="all"):
- if metadata_support:
- kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
- kimchi = E.metadata(E.kimchi()) if kimchi is None else kimchi
-
- update_node(kimchi, node)
- kimchi_xml = etree.tostring(kimchi)
- # From libvirt doc, Passing None for @metadata says to remove that
- # element from the domain XML (passing the empty string leaves the
- # element present). Do not support remove the old metadata.
- dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, kimchi_xml,
- KIMCHI_NAMESPACE, KIMCHI_META_URL,
- flags=get_vm_config_flag(dom, mode))
- else:
- # FIXME remove this code when all distro libvirt supports metadata
- # element
- _kimchi_set_metadata_node(dom, node)
-
-
-def _kimchi_get_metadata_node(dom, tag):
- # some other tools will not let libvirt create a persistent
- # configuration, just return empty
- if not dom.isPersistent():
- return None
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
- root = etree.fromstring(xml)
- kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
- # remove the "kimchi" prefix of xml
- if kimchi is not None:
- for elem in kimchi.getiterator():
- if not hasattr(elem.tag, 'find'):
- continue
- i = elem.tag.find('}')
- if i >= 0:
- elem.tag = elem.tag[i+1:]
-
- objectify.deannotate(kimchi)
- etree.cleanup_namespaces(kimchi)
- return kimchi
- return None
-
-
-def get_metadata_node(dom, tag, metadata_support, mode="current"):
- if metadata_support:
- kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
- else:
- # FIXME remove this code when all distro libvirt supports metadata
- # element
- kimchi = _kimchi_get_metadata_node(dom, tag)
-
- if kimchi is not None:
- node = kimchi.find(tag)
- if node is not None:
- return etree.tostring(node)
- return ""
-
-
-def metadata_exists(dom):
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
- root = etree.fromstring(xml)
-
- if root.find("metadata") is None:
- return False
- return True
diff --git a/plugins/kimchi/model/vmhostdevs.py b/plugins/kimchi/model/vmhostdevs.py
deleted file mode 100644
index 0cc6bd3..0000000
--- a/plugins/kimchi/model/vmhostdevs.py
+++ /dev/null
@@ -1,336 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import glob
-import libvirt
-import os
-import platform
-from lxml import etree, objectify
-from lxml.builder import E
-
-from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
-from wok.exception import OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import run_command, wok_log
-
-from config import CapabilitiesModel
-from host import DeviceModel, DevicesModel
-from utils import get_vm_config_flag
-from vms import DOM_STATE_MAP, VMModel
-
-
-class VMHostDevsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
-
- def get_list(self, vmid):
- dom = VMModel.get_vm(vmid, self.conn)
- xmlstr = dom.XMLDesc(0)
- root = objectify.fromstring(xmlstr)
- try:
- hostdev = root.devices.hostdev
- except AttributeError:
- return []
-
- return [self._deduce_dev_name(e) for e in hostdev]
-
- @staticmethod
- def _toint(num_str):
- if num_str.startswith('0x'):
- return int(num_str, 16)
- elif num_str.startswith('0'):
- return int(num_str, 8)
- else:
- return int(num_str)
-
- def _deduce_dev_name(self, e):
- return getattr(self, '_deduce_dev_name_%s' % e.attrib['type'])(e)
-
- def _deduce_dev_name_pci(self, e):
- attrib = {}
- for field in ('domain', 'bus', 'slot', 'function'):
- attrib[field] = self._toint(e.source.address.attrib[field])
- return 'pci_%(domain)04x_%(bus)02x_%(slot)02x_%(function)x' % attrib
-
- def _deduce_dev_name_scsi(self, e):
- attrib = {}
- for field in ('bus', 'target', 'unit'):
- attrib[field] = self._toint(e.source.address.attrib[field])
- attrib['host'] = self._toint(
- e.source.adapter.attrib['name'][len('scsi_host'):])
- return 'scsi_%(host)d_%(bus)d_%(target)d_%(unit)d' % attrib
-
- def _deduce_dev_name_usb(self, e):
- dev_names = DevicesModel(conn=self.conn).get_list(_cap='usb_device')
- usb_infos = [DeviceModel(conn=self.conn).lookup(dev_name)
- for dev_name in dev_names]
-
- unknown_dev = None
-
- try:
- evendor = self._toint(e.source.vendor.attrib['id'])
- eproduct = self._toint(e.source.product.attrib['id'])
- except AttributeError:
- evendor = 0
- eproduct = 0
- else:
- unknown_dev = 'usb_vendor_%s_product_%s' % (evendor, eproduct)
-
- try:
- ebus = self._toint(e.source.address.attrib['bus'])
- edevice = self._toint(e.source.address.attrib['device'])
- except AttributeError:
- ebus = -1
- edevice = -1
- else:
- unknown_dev = 'usb_bus_%s_device_%s' % (ebus, edevice)
-
- for usb_info in usb_infos:
- ivendor = self._toint(usb_info['vendor']['id'])
- iproduct = self._toint(usb_info['product']['id'])
- if evendor == ivendor and eproduct == iproduct:
- return usb_info['name']
- ibus = usb_info['bus']
- idevice = usb_info['device']
- if ebus == ibus and edevice == idevice:
- return usb_info['name']
- return unknown_dev
-
- def _passthrough_device_validate(self, dev_name):
- eligible_dev_names = \
- DevicesModel(conn=self.conn).get_list(_passthrough='true')
- if dev_name not in eligible_dev_names:
- raise InvalidParameter('KCHVMHDEV0002E', {'dev_name': dev_name})
-
- def create(self, vmid, params):
- dev_name = params['name']
- self._passthrough_device_validate(dev_name)
- dev_info = DeviceModel(conn=self.conn).lookup(dev_name)
-
- with RollbackContext() as rollback:
- try:
- dev = self.conn.get().nodeDeviceLookupByName(dev_name)
- dev.dettach()
- except Exception:
- raise OperationFailed('KCHVMHDEV0005E', {'name': dev_name})
- else:
- rollback.prependDefer(dev.reAttach)
-
- attach_device = getattr(
- self, '_attach_%s_device' % dev_info['device_type'])
-
- info = attach_device(vmid, dev_info)
- rollback.commitAll()
-
- return info
-
- def _get_pci_device_xml(self, dev_info):
- if 'detach_driver' not in dev_info:
- dev_info['detach_driver'] = 'kvm'
-
- source = E.source(E.address(domain=str(dev_info['domain']),
- bus=str(dev_info['bus']),
- slot=str(dev_info['slot']),
- function=str(dev_info['function'])))
- driver = E.driver(name=dev_info['detach_driver'])
- host_dev = E.hostdev(source, driver,
- mode='subsystem', type='pci', managed='yes')
-
- return etree.tostring(host_dev)
-
- @staticmethod
- def _validate_pci_passthrough_env():
- # Linux kernel < 3.5 doesn't provide /sys/kernel/iommu_groups
- if os.path.isdir('/sys/kernel/iommu_groups'):
- if not glob.glob('/sys/kernel/iommu_groups/*'):
- raise InvalidOperation("KCHVMHDEV0003E")
-
- # Enable virt_use_sysfs on RHEL6 and older distributions
- # In recent Fedora, there is no virt_use_sysfs.
- out, err, rc = run_command(['getsebool', 'virt_use_sysfs'])
- if rc == 0 and out.rstrip('\n') != "virt_use_sysfs --> on":
- out, err, rc = run_command(['setsebool', '-P',
- 'virt_use_sysfs=on'])
- if rc != 0:
- wok_log.warning("Unable to turn on sebool virt_use_sysfs")
-
- def _attach_pci_device(self, vmid, dev_info):
- self._validate_pci_passthrough_env()
-
- dom = VMModel.get_vm(vmid, self.conn)
- # Due to libvirt limitation, we don't support live assigne device to
- # vfio driver.
- driver = ('vfio' if DOM_STATE_MAP[dom.info()[0]] == "shutoff" and
- self.caps.kernel_vfio else 'kvm')
-
- # on powerkvm systems it must be vfio driver.
- distro, _, _ = platform.linux_distribution()
- if distro == 'IBM_PowerKVM':
- driver = 'vfio'
-
- # Attach all PCI devices in the same IOMMU group
- dev_model = DeviceModel(conn=self.conn)
- devs_model = DevicesModel(conn=self.conn)
- affected_names = devs_model.get_list(
- _passthrough_affected_by=dev_info['name'])
- passthrough_names = devs_model.get_list(
- _cap='pci', _passthrough='true')
- group_names = list(set(affected_names) & set(passthrough_names))
- pci_infos = [dev_model.lookup(dev_name) for dev_name in group_names]
- pci_infos.append(dev_info)
-
- device_flags = get_vm_config_flag(dom, mode='all')
-
- with RollbackContext() as rollback:
- for pci_info in pci_infos:
- pci_info['detach_driver'] = driver
- xmlstr = self._get_pci_device_xml(pci_info)
- try:
- dom.attachDeviceFlags(xmlstr, device_flags)
- except libvirt.libvirtError:
- wok_log.error(
- 'Failed to attach host device %s to VM %s: \n%s',
- pci_info['name'], vmid, xmlstr)
- raise
- rollback.prependDefer(dom.detachDeviceFlags,
- xmlstr, device_flags)
- rollback.commitAll()
-
- return dev_info['name']
-
- def _get_scsi_device_xml(self, dev_info):
- adapter = E.adapter(name=('scsi_host%s' % dev_info['host']))
- address = E.address(type='scsi', bus=str(dev_info['bus']),
- target=str(dev_info['target']),
- unit=str(dev_info['lun']))
- host_dev = E.hostdev(E.source(adapter, address),
- mode='subsystem', type='scsi', sgio='unfiltered')
- return etree.tostring(host_dev)
-
- def _attach_scsi_device(self, vmid, dev_info):
- xmlstr = self._get_scsi_device_xml(dev_info)
- dom = VMModel.get_vm(vmid, self.conn)
- dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
- return dev_info['name']
-
- def _get_usb_device_xml(self, dev_info):
- source = E.source(
- E.vendor(id=dev_info['vendor']['id']),
- E.product(id=dev_info['product']['id']),
- E.address(bus=str(dev_info['bus']),
- device=str(dev_info['device'])),
- startupPolicy='optional')
- host_dev = E.hostdev(source, mode='subsystem',
- ype='usb', managed='yes')
- return etree.tostring(host_dev)
-
- def _attach_usb_device(self, vmid, dev_info):
- xmlstr = self._get_usb_device_xml(dev_info)
- dom = VMModel.get_vm(vmid, self.conn)
- dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
- return dev_info['name']
-
-
-class VMHostDevModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def lookup(self, vmid, dev_name):
- dom = VMModel.get_vm(vmid, self.conn)
- xmlstr = dom.XMLDesc(0)
- root = objectify.fromstring(xmlstr)
- try:
- hostdev = root.devices.hostdev
- except AttributeError:
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- devsmodel = VMHostDevsModel(conn=self.conn)
-
- for e in hostdev:
- deduced_name = devsmodel._deduce_dev_name(e)
- if deduced_name == dev_name:
- return {'name': dev_name, 'type': e.attrib['type']}
-
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- def delete(self, vmid, dev_name):
- dom = VMModel.get_vm(vmid, self.conn)
- xmlstr = dom.XMLDesc(0)
- root = objectify.fromstring(xmlstr)
-
- try:
- hostdev = root.devices.hostdev
- except AttributeError:
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- devsmodel = VMHostDevsModel(conn=self.conn)
- pci_devs = [(devsmodel._deduce_dev_name(e), e) for e in hostdev
- if e.attrib['type'] == 'pci']
-
- for e in hostdev:
- if devsmodel._deduce_dev_name(e) == dev_name:
- xmlstr = etree.tostring(e)
- dom.detachDeviceFlags(
- xmlstr, get_vm_config_flag(dom, mode='all'))
- if e.attrib['type'] == 'pci':
- self._delete_affected_pci_devices(dom, dev_name, pci_devs)
- break
- else:
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- def _delete_affected_pci_devices(self, dom, dev_name, pci_devs):
- dev_model = DeviceModel(conn=self.conn)
- try:
- dev_model.lookup(dev_name)
- except NotFoundError:
- return
-
- affected_names = set(
- DevicesModel(
- conn=self.conn).get_list(_passthrough_affected_by=dev_name))
-
- for pci_name, e in pci_devs:
- if pci_name in affected_names:
- xmlstr = etree.tostring(e)
- dom.detachDeviceFlags(
- xmlstr, get_vm_config_flag(dom, mode='all'))
-
-
-class VMHoldersModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def get_list(self, device_id):
- devsmodel = VMHostDevsModel(conn=self.conn)
-
- conn = self.conn.get()
- doms = conn.listAllDomains(0)
-
- res = []
- for dom in doms:
- dom_name = dom.name()
- if device_id in devsmodel.get_list(dom_name):
- state = DOM_STATE_MAP[dom.info()[0]]
- res.append({"name": dom_name, "state": state})
- return res
diff --git a/plugins/kimchi/model/vmifaces.py b/plugins/kimchi/model/vmifaces.py
deleted file mode 100644
index 87565c8..0000000
--- a/plugins/kimchi/model/vmifaces.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import random
-from lxml import etree, objectify
-
-from wok.exception import InvalidParameter, MissingParameter
-from wok.exception import NotFoundError, InvalidOperation
-
-from ..xmlutils.interface import get_iface_xml
-from config import CapabilitiesModel
-from vms import DOM_STATE_MAP, VMModel
-
-
-class VMIfacesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
-
- def get_list(self, vm):
- macs = []
- for iface in self.get_vmifaces(vm, self.conn):
- macs.append(iface.mac.get('address'))
- return macs
-
- def create(self, vm, params):
- conn = self.conn.get()
- networks = conn.listNetworks() + conn.listDefinedNetworks()
- networks = map(lambda x: x.decode('utf-8'), networks)
-
- if params['type'] == 'network':
- network = params.get("network")
-
- if network is None:
- raise MissingParameter('KCHVMIF0007E')
-
- if network not in networks:
- raise InvalidParameter('KCHVMIF0002E',
- {'name': vm, 'network': network})
-
- macs = (iface.mac.get('address')
- for iface in self.get_vmifaces(vm, self.conn))
-
- # user defined customized mac address
- if 'mac' in params and params['mac']:
- # make sure it is unique
- if params['mac'] in macs:
- raise InvalidParameter('KCHVMIF0009E',
- {'name': vm, 'mac': params['mac']})
-
- # otherwise choose a random mac address
- else:
- while True:
- params['mac'] = VMIfacesModel.random_mac()
- if params['mac'] not in macs:
- break
-
- dom = VMModel.get_vm(vm, self.conn)
-
- os_data = VMModel.vm_get_os_metadata(dom, self.caps.metadata_support)
- os_version, os_distro = os_data
- xml = get_iface_xml(params, conn.getInfo()[0], os_distro, os_version)
-
- flags = 0
- if dom.isPersistent():
- flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
- if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
- flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
-
- dom.attachDeviceFlags(xml, flags)
-
- return params['mac']
-
- @staticmethod
- def get_vmifaces(vm, conn):
- dom = VMModel.get_vm(vm, conn)
- xml = dom.XMLDesc(0)
- root = objectify.fromstring(xml)
-
- return root.devices.findall("interface")
-
- @staticmethod
- def random_mac():
- mac = [0x52, 0x54, 0x00,
- random.randint(0x00, 0x7f),
- random.randint(0x00, 0xff),
- random.randint(0x00, 0xff)]
- return ':'.join(map(lambda x: u'%02x' % x, mac))
-
-
-class VMIfaceModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def _get_vmiface(self, vm, mac):
- ifaces = VMIfacesModel.get_vmifaces(vm, self.conn)
-
- for iface in ifaces:
- if iface.mac.get('address') == mac:
- return iface
- return None
-
- def lookup(self, vm, mac):
- info = {}
-
- iface = self._get_vmiface(vm, mac)
- if iface is None:
- raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
-
- info['type'] = iface.attrib['type']
- info['mac'] = iface.mac.get('address')
- if iface.find("model") is not None:
- info['model'] = iface.model.get('type')
- if info['type'] == 'network':
- info['network'] = iface.source.get('network')
- if info['type'] == 'bridge':
- info['bridge'] = iface.source.get('bridge')
-
- return info
-
- def delete(self, vm, mac):
- dom = VMModel.get_vm(vm, self.conn)
- iface = self._get_vmiface(vm, mac)
-
- if iface is None:
- raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
-
- flags = 0
- if dom.isPersistent():
- flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
- if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
- flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
-
- dom.detachDeviceFlags(etree.tostring(iface), flags)
-
- def update(self, vm, mac, params):
- dom = VMModel.get_vm(vm, self.conn)
- iface = self._get_vmiface(vm, mac)
-
- if iface is None:
- raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
-
- # cannot change mac address in a running system
- if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
- raise InvalidOperation('KCHVMIF0011E')
-
- # mac address is a required parameter
- if 'mac' not in params:
- raise MissingParameter('KCHVMIF0008E')
-
- # new mac address must be unique
- if self._get_vmiface(vm, params['mac']) is not None:
- raise InvalidParameter('KCHVMIF0009E',
- {'name': vm, 'mac': params['mac']})
-
- flags = 0
- if dom.isPersistent():
- flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
-
- # remove the current nic
- xml = etree.tostring(iface)
- dom.detachDeviceFlags(xml, flags=flags)
-
- # add the nic with the desired mac address
- iface.mac.attrib['address'] = params['mac']
- xml = etree.tostring(iface)
- dom.attachDeviceFlags(xml, flags=flags)
-
- return [vm, params['mac']]
diff --git a/plugins/kimchi/model/vms.py b/plugins/kimchi/model/vms.py
deleted file mode 100644
index f37b5d6..0000000
--- a/plugins/kimchi/model/vms.py
+++ /dev/null
@@ -1,1307 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import os
-import random
-import string
-import time
-import uuid
-from lxml import etree, objectify
-from lxml.builder import E
-from xml.etree import ElementTree
-
-from wok.config import config
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task, convert_data_size, get_next_clone_name
-from wok.utils import import_class, run_setfacl_set_attr, wok_log
-from wok.xmlutils.utils import xpath_get_text, xml_item_update
-from wok.xmlutils.utils import dictize
-from wok.model.tasks import TaskModel
-
-from .. import model
-from .. import vnc
-from ..config import READONLY_POOL_TYPE
-from ..kvmusertests import UserTests
-from ..screenshot import VMScreenshot
-from ..utils import template_name_from_uri
-from ..xmlutils.cpu import get_cpu_xml, get_numa_xml
-from config import CapabilitiesModel
-from templates import TemplateModel
-from utils import get_vm_name
-from utils import get_metadata_node
-from utils import set_metadata_node
-
-
-DOM_STATE_MAP = {0: 'nostate',
- 1: 'running',
- 2: 'blocked',
- 3: 'paused',
- 4: 'shutdown',
- 5: 'shutoff',
- 6: 'crashed',
- 7: 'pmsuspended'}
-
-VM_STATIC_UPDATE_PARAMS = {'name': './name',
- 'cpus': './vcpu'}
-VM_LIVE_UPDATE_PARAMS = {}
-
-XPATH_DOMAIN_DISK = "/domain/devices/disk[@device='disk']/source/@file"
-XPATH_DOMAIN_DISK_BY_FILE = "./devices/disk[@device='disk']/source[@file='%s']"
-XPATH_DOMAIN_NAME = '/domain/name'
-XPATH_DOMAIN_MAC = "/domain/devices/interface[@type='network']/mac/@address"
-XPATH_DOMAIN_MAC_BY_ADDRESS = "./devices/interface[@type='network']/"\
- "mac[@address='%s']"
-XPATH_DOMAIN_MEMORY = '/domain/memory'
-XPATH_DOMAIN_MEMORY_UNIT = '/domain/memory/@unit'
-XPATH_DOMAIN_UUID = '/domain/uuid'
-
-XPATH_NUMA_CELL = './cpu/numa/cell'
-
-
-class VMsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
- self.task = TaskModel(**kargs)
-
- def create(self, params):
- t_name = template_name_from_uri(params['template'])
- vm_list = self.get_list()
- name = get_vm_name(params.get('name'), t_name, vm_list)
- # incoming text, from js json, is unicode, do not need decode
- if name in vm_list:
- raise InvalidOperation("KCHVM0001E", {'name': name})
-
- vm_overrides = dict()
- pool_uri = params.get('storagepool')
- if pool_uri:
- vm_overrides['storagepool'] = pool_uri
- vm_overrides['fc_host_support'] = self.caps.fc_host_support
- t = TemplateModel.get_template(t_name, self.objstore, self.conn,
- vm_overrides)
-
- if not self.caps.qemu_stream and t.info.get('iso_stream', False):
- raise InvalidOperation("KCHVM0005E")
-
- t.validate()
- data = {'name': name, 'template': t,
- 'graphics': params.get('graphics', {})}
- taskid = add_task(u'/plugins/kimchi/vms/%s' % name, self._create_task,
- self.objstore, data)
-
- return self.task.lookup(taskid)
-
- def _create_task(self, cb, params):
- """
- params: A dict with the following values:
- - vm_uuid: The UUID of the VM being created
- - template: The template being used to create the VM
- - name: The name for the new VM
- """
- vm_uuid = str(uuid.uuid4())
- t = params['template']
- name = params['name']
- conn = self.conn.get()
-
- cb('Storing VM icon')
- # Store the icon for displaying later
- icon = t.info.get('icon')
- if icon:
- try:
- with self.objstore as session:
- session.store('vm', vm_uuid, {'icon': icon})
- except Exception as e:
- # It is possible to continue Kimchi executions without store
- # vm icon info
- wok_log.error('Error trying to update database with guest '
- 'icon information due error: %s', e.message)
-
- # If storagepool is SCSI, volumes will be LUNs and must be passed by
- # the user from UI or manually.
- cb('Provisioning storage for new VM')
- vol_list = []
- if t._get_storage_type() not in ["iscsi", "scsi"]:
- vol_list = t.fork_vm_storage(vm_uuid)
-
- graphics = params.get('graphics', {})
- stream_protocols = self.caps.libvirt_stream_protocols
- xml = t.to_vm_xml(name, vm_uuid,
- libvirt_stream_protocols=stream_protocols,
- graphics=graphics,
- volumes=vol_list)
-
- cb('Defining new VM')
- try:
- conn.defineXML(xml.encode('utf-8'))
- except libvirt.libvirtError as e:
- if t._get_storage_type() not in READONLY_POOL_TYPE:
- for v in vol_list:
- vol = conn.storageVolLookupByPath(v['path'])
- vol.delete(0)
- raise OperationFailed("KCHVM0007E", {'name': name,
- 'err': e.get_error_message()})
-
- cb('Updating VM metadata')
- VMModel.vm_update_os_metadata(VMModel.get_vm(name, self.conn), t.info,
- self.caps.metadata_support)
- cb('OK', True)
-
- def get_list(self):
- return VMsModel.get_vms(self.conn)
-
- @staticmethod
- def get_vms(conn):
- conn_ = conn.get()
- names = [dom.name().decode('utf-8') for dom in conn_.listAllDomains(0)]
- names = sorted(names, key=unicode.lower)
- return names
-
-
-class VMModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
- self.vmscreenshot = VMScreenshotModel(**kargs)
- self.users = import_class(
- 'plugins.kimchi.model.users.UsersModel'
- )(**kargs)
- self.groups = import_class(
- 'plugins.kimchi.model.groups.GroupsModel'
- )(**kargs)
- self.vms = VMsModel(**kargs)
- self.task = TaskModel(**kargs)
- self.storagepool = model.storagepools.StoragePoolModel(**kargs)
- self.storagevolume = model.storagevolumes.StorageVolumeModel(**kargs)
- self.storagevolumes = model.storagevolumes.StorageVolumesModel(**kargs)
- cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotModel')
- self.vmsnapshot = cls(**kargs)
- cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotsModel')
- self.vmsnapshots = cls(**kargs)
- self.stats = {}
-
- def update(self, name, params):
- dom = self.get_vm(name, self.conn)
- dom = self._static_vm_update(dom, params)
- self._live_vm_update(dom, params)
- return dom.name().decode('utf-8')
-
- def clone(self, name):
- """Clone a virtual machine based on an existing one.
-
- The new virtual machine will have the exact same configuration as the
- original VM, except for the name, UUID, MAC addresses and disks. The
- name will have the form "<name>-clone-<number>", with <number> starting
- at 1; the UUID will be generated randomly; the MAC addresses will be
- generated randomly with no conflicts within the original and the new
- VM; and the disks will be new volumes [mostly] on the same storage
- pool, with the same content as the original disks. The storage pool
- 'default' will always be used when cloning SCSI and iSCSI disks and
- when the original storage pool cannot hold the new volume.
-
- An exception will be raised if the virtual machine <name> is not
- shutoff, if there is no available space to copy a new volume to the
- storage pool 'default' (when there was also no space to copy it to the
- original storage pool) and if one of the virtual machine's disks belong
- to a storage pool not supported by Kimchi.
-
- Parameters:
- name -- The name of the existing virtual machine to be cloned.
-
- Return:
- A Task running the clone operation.
- """
- name = name.decode('utf-8')
-
- # VM must be shutoff in order to clone it
- info = self.lookup(name)
- if info['state'] != u'shutoff':
- raise InvalidParameter('KCHVM0033E', {'name': name})
-
- # the new VM's name will be used as the Task's 'target_uri' so it needs
- # to be defined now.
-
- vms_being_created = []
-
- # lookup names of VMs being created right now
- with self.objstore as session:
- task_names = session.get_list('task')
- for tn in task_names:
- t = session.get('task', tn)
- if t['target_uri'].startswith('/plugins/kimchi/vms/'):
- uri_name = t['target_uri'].lstrip('/plugins/kimchi/vms/')
- vms_being_created.append(uri_name)
-
- current_vm_names = self.vms.get_list() + vms_being_created
- new_name = get_next_clone_name(current_vm_names, name)
-
- # create a task with the actual clone function
- taskid = add_task(u'/plugins/kimchi/vms/%s/clone' % new_name,
- self._clone_task, self.objstore,
- {'name': name, 'new_name': new_name})
-
- return self.task.lookup(taskid)
-
- def _clone_task(self, cb, params):
- """Asynchronous function which performs the clone operation.
-
- Parameters:
- cb -- A callback function to signal the Task's progress.
- params -- A dict with the following values:
- "name": the name of the original VM.
- "new_name": the name of the new VM.
- """
- name = params['name']
- new_name = params['new_name']
- vir_conn = self.conn.get()
-
- # fetch base XML
- cb('reading source VM XML')
- try:
- vir_dom = vir_conn.lookupByName(name)
- flags = libvirt.VIR_DOMAIN_XML_SECURE
- xml = vir_dom.XMLDesc(flags).decode('utf-8')
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0035E', {'name': name,
- 'err': e.message})
-
- # update UUID
- cb('updating VM UUID')
- old_uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
- new_uuid = unicode(uuid.uuid4())
- xml = xml_item_update(xml, './uuid', new_uuid)
-
- # update MAC addresses
- cb('updating VM MAC addresses')
- xml = self._clone_update_mac_addresses(xml)
-
- with RollbackContext() as rollback:
- # copy disks
- cb('copying VM disks')
- xml = self._clone_update_disks(xml, rollback)
-
- # update objstore entry
- cb('updating object store')
- self._clone_update_objstore(old_uuid, new_uuid, rollback)
-
- # update name
- cb('updating VM name')
- xml = xml_item_update(xml, './name', new_name)
-
- # create new guest
- cb('defining new VM')
- try:
- vir_conn.defineXML(xml)
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0035E', {'name': name,
- 'err': e.message})
-
- rollback.commitAll()
-
- cb('OK', True)
-
- @staticmethod
- def _clone_update_mac_addresses(xml):
- """Update the MAC addresses with new values in the XML descriptor of a
- cloning domain.
-
- The new MAC addresses will be generated randomly, and their values are
- guaranteed to be distinct from the ones in the original VM.
-
- Arguments:
- xml -- The XML descriptor of the original domain.
-
- Return:
- The XML descriptor <xml> with the new MAC addresses instead of the
- old ones.
- """
- old_macs = xpath_get_text(xml, XPATH_DOMAIN_MAC)
- new_macs = []
-
- for mac in old_macs:
- while True:
- new_mac = model.vmifaces.VMIfacesModel.random_mac()
- # make sure the new MAC doesn't conflict with the original VM
- # and with the new values on the new VM.
- if new_mac not in (old_macs + new_macs):
- new_macs.append(new_mac)
- break
-
- xml = xml_item_update(xml, XPATH_DOMAIN_MAC_BY_ADDRESS % mac,
- new_mac, 'address')
-
- return xml
-
- def _clone_update_disks(self, xml, rollback):
- """Clone disks from a virtual machine. The disks are copied as new
- volumes and the new VM's XML is updated accordingly.
-
- Arguments:
- xml -- The XML descriptor of the original VM + new value for
- "/domain/uuid".
- rollback -- A rollback context so the new volumes can be removed if an
- error occurs during the cloning operation.
-
- Return:
- The XML descriptor <xml> with the new disk paths instead of the
- old ones.
- """
- # the UUID will be used to create the disk paths
- uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
- all_paths = xpath_get_text(xml, XPATH_DOMAIN_DISK)
-
- vir_conn = self.conn.get()
-
- def _delete_disk_from_objstore(path):
- with self.objstore as session:
- session.delete('storagevolume', path)
-
- domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
-
- for i, path in enumerate(all_paths):
- try:
- vir_orig_vol = vir_conn.storageVolLookupByPath(path)
- vir_pool = vir_orig_vol.storagePoolLookupByVolume()
-
- orig_pool_name = vir_pool.name().decode('utf-8')
- orig_vol_name = vir_orig_vol.name().decode('utf-8')
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0035E', {'name': domain_name,
- 'err': e.message})
-
- orig_pool = self.storagepool.lookup(orig_pool_name)
- orig_vol = self.storagevolume.lookup(orig_pool_name, orig_vol_name)
-
- new_pool_name = orig_pool_name
- new_pool = orig_pool
-
- if orig_pool['type'] in ['dir', 'netfs', 'logical']:
- # if a volume in a pool 'dir', 'netfs' or 'logical' cannot hold
- # a new volume with the same size, the pool 'default' should
- # be used
- if orig_vol['capacity'] > orig_pool['available']:
- wok_log.warning('storage pool \'%s\' doesn\'t have '
- 'enough free space to store image '
- '\'%s\'; falling back to \'default\'',
- orig_pool_name, path)
- new_pool_name = u'default'
- new_pool = self.storagepool.lookup(u'default')
-
- # ...and if even the pool 'default' cannot hold a new
- # volume, raise an exception
- if orig_vol['capacity'] > new_pool['available']:
- domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
- raise InvalidOperation('KCHVM0034E',
- {'name': domain_name})
-
- elif orig_pool['type'] in ['scsi', 'iscsi']:
- # SCSI and iSCSI always fall back to the storage pool 'default'
- wok_log.warning('cannot create new volume for clone in '
- 'storage pool \'%s\'; falling back to '
- '\'default\'', orig_pool_name)
- new_pool_name = u'default'
- new_pool = self.storagepool.lookup(u'default')
-
- # if the pool 'default' cannot hold a new volume, raise
- # an exception
- if orig_vol['capacity'] > new_pool['available']:
- domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
- raise InvalidOperation('KCHVM0034E', {'name': domain_name})
-
- else:
- # unexpected storage pool type
- raise InvalidOperation('KCHPOOL0014E',
- {'type': orig_pool['type']})
-
- # new volume name: <UUID>-<loop-index>.<original extension>
- # e.g. 1234-5678-9012-3456-0.img
- ext = os.path.splitext(path)[1]
- new_vol_name = u'%s-%d%s' % (uuid, i, ext)
- task = self.storagevolume.clone(orig_pool_name, orig_vol_name,
- new_name=new_vol_name)
- self.task.wait(task['id'], 3600) # 1 h
-
- # get the new volume path and update the XML descriptor
- new_vol = self.storagevolume.lookup(new_pool_name, new_vol_name)
- xml = xml_item_update(xml, XPATH_DOMAIN_DISK_BY_FILE % path,
- new_vol['path'], 'file')
-
- # set the new disk's used_by
- with self.objstore as session:
- session.store('storagevolume', new_vol['path'],
- {'used_by': [domain_name]})
- rollback.prependDefer(_delete_disk_from_objstore, new_vol['path'])
-
- # remove the new volume should an error occur later
- rollback.prependDefer(self.storagevolume.delete, new_pool_name,
- new_vol_name)
-
- return xml
-
- def _clone_update_objstore(self, old_uuid, new_uuid, rollback):
- """Update Kimchi's object store with the cloning VM.
-
- Arguments:
- old_uuid -- The UUID of the original VM.
- new_uuid -- The UUID of the new, clonning VM.
- rollback -- A rollback context so the object store entry can be removed
- if an error occurs during the cloning operation.
- """
- with self.objstore as session:
- try:
- vm = session.get('vm', old_uuid)
- icon = vm['icon']
- session.store('vm', new_uuid, {'icon': icon})
- except NotFoundError:
- # if we cannot find an object store entry for the original VM,
- # don't store one with an empty value.
- pass
- else:
- # we need to define a custom function to prepend to the
- # rollback context because the object store session needs to be
- # opened and closed correctly (i.e. "prependDefer" only
- # accepts one command at a time but we need more than one to
- # handle an object store).
- def _rollback_objstore():
- with self.objstore as session_rb:
- session_rb.delete('vm', new_uuid, ignore_missing=True)
-
- # remove the new object store entry should an error occur later
- rollback.prependDefer(_rollback_objstore)
-
- def _build_access_elem(self, dom, users, groups):
- auth = config.get("authentication", "method")
- access_xml = get_metadata_node(dom, "access",
- self.caps.metadata_support)
-
- auth_elem = None
-
- if not access_xml:
- # there is no metadata element 'access'
- access_elem = E.access()
- else:
- access_elem = ET.fromstring(access_xml)
-
- same_auth = access_elem.xpath('./auth[@type="%s"]' % auth)
- if len(same_auth) > 0:
- # there is already a sub-element 'auth' with the same type;
- # update it.
- auth_elem = same_auth[0]
-
- if users is not None:
- for u in auth_elem.findall('user'):
- auth_elem.remove(u)
-
- if groups is not None:
- for g in auth_elem.findall('group'):
- auth_elem.remove(g)
-
- if auth_elem is None:
- # there is no sub-element 'auth' with the same type
- # (or no 'auth' at all); create it.
- auth_elem = E.auth(type=auth)
- access_elem.append(auth_elem)
-
- if users is not None:
- for u in users:
- auth_elem.append(E.user(u))
-
- if groups is not None:
- for g in groups:
- auth_elem.append(E.group(g))
-
- return access_elem
-
- def _vm_update_access_metadata(self, dom, params):
- users = groups = None
- if "users" in params:
- users = params["users"]
- for user in users:
- if not self.users.validate(user):
- raise InvalidParameter("KCHVM0027E",
- {'users': user})
- if "groups" in params:
- groups = params["groups"]
- for group in groups:
- if not self.groups.validate(group):
- raise InvalidParameter("KCHVM0028E",
- {'groups': group})
-
- if users is None and groups is None:
- return
-
- node = self._build_access_elem(dom, users, groups)
- set_metadata_node(dom, node, self.caps.metadata_support)
-
- def _get_access_info(self, dom):
- users = groups = list()
- access_xml = (get_metadata_node(dom, "access",
- self.caps.metadata_support) or
- """<access></access>""")
- access_info = dictize(access_xml)
- auth = config.get("authentication", "method")
- if ('auth' in access_info['access'] and
- ('type' in access_info['access']['auth'] or
- len(access_info['access']['auth']) > 1)):
- users = xpath_get_text(access_xml,
- "/access/auth[@type='%s']/user" % auth)
- groups = xpath_get_text(access_xml,
- "/access/auth[@type='%s']/group" % auth)
- elif auth == 'pam':
- # Compatible to old permission tagging
- users = xpath_get_text(access_xml, "/access/user")
- groups = xpath_get_text(access_xml, "/access/group")
- return users, groups
-
- @staticmethod
- def vm_get_os_metadata(dom, metadata_support):
- os_xml = (get_metadata_node(dom, "os", metadata_support) or
- """<os></os>""")
- os_elem = ET.fromstring(os_xml)
- return (os_elem.attrib.get("version"), os_elem.attrib.get("distro"))
-
- @staticmethod
- def vm_update_os_metadata(dom, params, metadata_support):
- distro = params.get("os_distro")
- version = params.get("os_version")
- if distro is None:
- return
- os_elem = E.os({"distro": distro, "version": version})
- set_metadata_node(dom, os_elem, metadata_support)
-
- def _update_graphics(self, dom, xml, params):
- root = objectify.fromstring(xml)
- graphics = root.devices.find("graphics")
- if graphics is None:
- return xml
-
- password = params['graphics'].get("passwd")
- if password is not None and len(password.strip()) == 0:
- password = "".join(random.sample(string.ascii_letters +
- string.digits, 8))
-
- if password is not None:
- graphics.attrib['passwd'] = password
-
- expire = params['graphics'].get("passwdValidTo")
- to = graphics.attrib.get('passwdValidTo')
- if to is not None:
- if (time.mktime(time.strptime(to, '%Y-%m-%dT%H:%M:%S')) -
- time.time() <= 0):
- expire = expire if expire is not None else 30
-
- if expire is not None:
- expire_time = time.gmtime(time.time() + float(expire))
- valid_to = time.strftime('%Y-%m-%dT%H:%M:%S', expire_time)
- graphics.attrib['passwdValidTo'] = valid_to
-
- if not dom.isActive():
- return ET.tostring(root, encoding="utf-8")
-
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
- dom.updateDeviceFlags(etree.tostring(graphics),
- libvirt.VIR_DOMAIN_AFFECT_LIVE)
- return xml
-
- def _backup_snapshots(self, snap, all_info):
- """ Append "snap" and the children of "snap" to the list "all_info".
-
- The list *must* always contain the parent snapshots before their
- children so the function "_redefine_snapshots" can work correctly.
-
- Arguments:
- snap -- a native domain snapshot.
- all_info -- a list of dict keys:
- "{'xml': <snap XML>, 'current': <is snap current?>'}"
- """
- all_info.append({'xml': snap.getXMLDesc(0),
- 'current': snap.isCurrent(0)})
-
- for child in snap.listAllChildren(0):
- self._backup_snapshots(child, all_info)
-
- def _redefine_snapshots(self, dom, all_info):
- """ Restore the snapshots stored in "all_info" to the domain "dom".
-
- Arguments:
- dom -- the domain which will have its snapshots restored.
- all_info -- a list of dict keys, as described in "_backup_snapshots",
- containing the original snapshot information.
- """
- for info in all_info:
- flags = libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
-
- if info['current']:
- flags |= libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
-
- dom.snapshotCreateXML(info['xml'], flags)
-
- def _static_vm_update(self, dom, params):
- old_xml = new_xml = dom.XMLDesc(0)
-
- for key, val in params.items():
- if key in VM_STATIC_UPDATE_PARAMS:
- if type(val) == int:
- val = str(val)
- xpath = VM_STATIC_UPDATE_PARAMS[key]
- new_xml = xml_item_update(new_xml, xpath, val)
-
- # Updating memory and NUMA if necessary, if vm is offline
- if not dom.isActive():
- if 'memory' in params:
- new_xml = self._update_memory_config(new_xml, params)
- elif 'cpus' in params and \
- (xpath_get_text(new_xml, XPATH_NUMA_CELL + '/@memory') != []):
- vcpus = params['cpus']
- new_xml = xml_item_update(
- new_xml,
- XPATH_NUMA_CELL,
- value='0-' + str(vcpus - 1) if vcpus > 1 else '0',
- attr='cpus')
-
- if 'graphics' in params:
- new_xml = self._update_graphics(dom, new_xml, params)
-
- snapshots_info = []
- vm_name = dom.name()
- conn = self.conn.get()
- try:
- if 'name' in params:
- state = DOM_STATE_MAP[dom.info()[0]]
- if state != 'shutoff':
- msg_args = {'name': vm_name, 'new_name': params['name']}
- raise InvalidParameter("KCHVM0003E", msg_args)
-
- lflags = libvirt.VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
- dflags = (libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
- libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)
-
- for virt_snap in dom.listAllSnapshots(lflags):
- snapshots_info.append({'xml': virt_snap.getXMLDesc(0),
- 'current': virt_snap.isCurrent(0)})
- self._backup_snapshots(virt_snap, snapshots_info)
-
- virt_snap.delete(dflags)
-
- # Undefine old vm, only if name is going to change
- dom.undefine()
-
- dom = conn.defineXML(new_xml)
- if 'name' in params:
- self._redefine_snapshots(dom, snapshots_info)
- except libvirt.libvirtError as e:
- dom = conn.defineXML(old_xml)
- if 'name' in params:
- self._redefine_snapshots(dom, snapshots_info)
-
- raise OperationFailed("KCHVM0008E", {'name': vm_name,
- 'err': e.get_error_message()})
- return dom
-
- def _update_memory_config(self, xml, params):
- # Checks if NUMA memory is already configured, if not, checks if CPU
- # element is already configured (topology). Then add NUMA element as
- # apropriated
- root = ET.fromstring(xml)
- numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
- vcpus = params.get('cpus')
- if numa_mem == []:
- if vcpus is None:
- vcpus = int(xpath_get_text(xml,
- VM_STATIC_UPDATE_PARAMS['cpus'])[0])
- cpu = root.find('./cpu')
- if cpu is None:
- cpu = get_cpu_xml(vcpus, params['memory'] << 10)
- root.insert(0, ET.fromstring(cpu))
- else:
- numa_element = get_numa_xml(vcpus, params['memory'] << 10)
- cpu.insert(0, ET.fromstring(numa_element))
- else:
- if vcpus is not None:
- xml = xml_item_update(
- xml,
- XPATH_NUMA_CELL,
- value='0-' + str(vcpus - 1) if vcpus > 1 else '0',
- attr='cpus')
- root = ET.fromstring(xml_item_update(xml, XPATH_NUMA_CELL,
- str(params['memory'] << 10),
- attr='memory'))
-
- # Remove currentMemory, automatically set later by libvirt
- currentMem = root.find('.currentMemory')
- if currentMem is not None:
- root.remove(currentMem)
-
- memory = root.find('.memory')
- # Update/Adds maxMemory accordingly
- if not self.caps.mem_hotplug_support:
- if memory is not None:
- memory.text = str(params['memory'] << 10)
- else:
- if memory is not None:
- root.remove(memory)
- maxMem = root.find('.maxMemory')
- host_mem = self.conn.get().getInfo()[1]
- slots = (host_mem - params['memory']) >> 10
- # Libvirt does not accepts slots <= 1
- if slots < 0:
- raise OperationFailed("KCHVM0041E")
- elif slots == 0:
- slots = 1
- if maxMem is None:
- max_mem_xml = E.maxMemory(
- str(host_mem * 1024),
- unit='Kib',
- slots=str(slots))
- root.insert(0, max_mem_xml)
- new_xml = ET.tostring(root, encoding="utf-8")
- else:
- # Update slots only
- new_xml = xml_item_update(ET.tostring(root, encoding="utf-8"),
- './maxMemory',
- str(slots),
- attr='slots')
- return new_xml
- return ET.tostring(root, encoding="utf-8")
-
- def _live_vm_update(self, dom, params):
- self._vm_update_access_metadata(dom, params)
- if 'memory' in params and dom.isActive():
- self._update_memory_live(dom, params)
-
- def _update_memory_live(self, dom, params):
- # Check if host supports memory device
- if not self.caps.mem_hotplug_support:
- raise InvalidOperation("KCHVM0046E")
-
- # Check if the vm xml supports memory hotplug, if not, static update
- # must be done firstly, then Kimchi is going to update the xml
- xml = dom.XMLDesc(0)
- numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
- max_mem = xpath_get_text(xml, './maxMemory')
- if numa_mem == [] or max_mem == []:
- raise OperationFailed('KCHVM0042E', {'name': dom.name()})
-
- # Memory live update must be done in chunks of 1024 Mib or 1Gib
- new_mem = params['memory']
- old_mem = int(xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]) >> 10
- if new_mem < old_mem:
- raise OperationFailed('KCHVM0043E')
- if (new_mem - old_mem) % 1024 != 0:
- raise OperationFailed('KCHVM0044E')
-
- # Check slot spaces:
- total_slots = int(xpath_get_text(xml, './maxMemory/@slots')[0])
- needed_slots = (new_mem - old_mem) / 1024
- used_slots = len(xpath_get_text(xml, './devices/memory'))
- if needed_slots > (total_slots - used_slots):
- raise OperationFailed('KCHVM0045E')
- elif needed_slots == 0:
- # New memory value is same that current memory set
- return
-
- # Finally, we are ok to hot add the memory devices
- try:
- self._hot_add_memory_devices(dom, needed_slots)
- except Exception as e:
- raise OperationFailed("KCHVM0047E", {'error': e.message})
-
- def _hot_add_memory_devices(self, dom, amount):
- # Hot add given number of memory devices in the guest
- flags = libvirt.VIR_DOMAIN_MEM_CONFIG | libvirt.VIR_DOMAIN_MEM_LIVE
- # Create memory device xml
- mem_dev_xml = etree.tostring(
- E.memory(
- E.target(
- E.size('1', unit='GiB'),
- E.node('0')),
- model='dimm'))
- # Add chunks of 1G of memory
- for i in range(amount):
- dom.attachDeviceFlags(mem_dev_xml, flags)
-
- def _has_video(self, dom):
- dom = ElementTree.fromstring(dom.XMLDesc(0))
- return dom.find('devices/video') is not None
-
- def _update_guest_stats(self, name):
- try:
- dom = VMModel.get_vm(name, self.conn)
-
- vm_uuid = dom.UUIDString()
- info = dom.info()
- state = DOM_STATE_MAP[info[0]]
-
- if state != 'running':
- self.stats[vm_uuid] = {}
- return
-
- if self.stats.get(vm_uuid, None) is None:
- self.stats[vm_uuid] = {}
-
- timestamp = time.time()
- prevStats = self.stats.get(vm_uuid, {})
- seconds = timestamp - prevStats.get('timestamp', 0)
- self.stats[vm_uuid].update({'timestamp': timestamp})
-
- self._get_percentage_cpu_usage(vm_uuid, info, seconds)
- self._get_network_io_rate(vm_uuid, dom, seconds)
- self._get_disk_io_rate(vm_uuid, dom, seconds)
- except Exception as e:
- # VM might be deleted just after we get the list.
- # This is OK, just skip.
- wok_log.debug('Error processing VM stats: %s', e.message)
-
- def _get_percentage_cpu_usage(self, vm_uuid, info, seconds):
- prevCpuTime = self.stats[vm_uuid].get('cputime', 0)
-
- cpus = info[3]
- cpuTime = info[4] - prevCpuTime
-
- base = (((cpuTime) * 100.0) / (seconds * 1000.0 * 1000.0 * 1000.0))
- percentage = max(0.0, min(100.0, base / cpus))
-
- self.stats[vm_uuid].update({'cputime': info[4], 'cpu': percentage})
-
- def _get_network_io_rate(self, vm_uuid, dom, seconds):
- prevNetRxKB = self.stats[vm_uuid].get('netRxKB', 0)
- prevNetTxKB = self.stats[vm_uuid].get('netTxKB', 0)
- currentMaxNetRate = self.stats[vm_uuid].get('max_net_io', 100)
-
- rx_bytes = 0
- tx_bytes = 0
-
- tree = ElementTree.fromstring(dom.XMLDesc(0))
- for target in tree.findall('devices/interface/target'):
- dev = target.get('dev')
- io = dom.interfaceStats(dev)
- rx_bytes += io[0]
- tx_bytes += io[4]
-
- netRxKB = float(rx_bytes) / 1000
- netTxKB = float(tx_bytes) / 1000
-
- rx_stats = (netRxKB - prevNetRxKB) / seconds
- tx_stats = (netTxKB - prevNetTxKB) / seconds
-
- rate = rx_stats + tx_stats
- max_net_io = round(max(currentMaxNetRate, int(rate)), 1)
-
- self.stats[vm_uuid].update({'net_io': rate, 'max_net_io': max_net_io,
- 'netRxKB': netRxKB, 'netTxKB': netTxKB})
-
- def _get_disk_io_rate(self, vm_uuid, dom, seconds):
- prevDiskRdKB = self.stats[vm_uuid].get('diskRdKB', 0)
- prevDiskWrKB = self.stats[vm_uuid].get('diskWrKB', 0)
- currentMaxDiskRate = self.stats[vm_uuid].get('max_disk_io', 100)
-
- rd_bytes = 0
- wr_bytes = 0
-
- tree = ElementTree.fromstring(dom.XMLDesc(0))
- for target in tree.findall("devices/disk/target"):
- dev = target.get("dev")
- io = dom.blockStats(dev)
- rd_bytes += io[1]
- wr_bytes += io[3]
-
- diskRdKB = float(rd_bytes) / 1024
- diskWrKB = float(wr_bytes) / 1024
-
- rd_stats = (diskRdKB - prevDiskRdKB) / seconds
- wr_stats = (diskWrKB - prevDiskWrKB) / seconds
-
- rate = rd_stats + wr_stats
- max_disk_io = round(max(currentMaxDiskRate, int(rate)), 1)
-
- self.stats[vm_uuid].update({'disk_io': rate,
- 'max_disk_io': max_disk_io,
- 'diskRdKB': diskRdKB,
- 'diskWrKB': diskWrKB})
-
- def lookup(self, name):
- dom = self.get_vm(name, self.conn)
- info = dom.info()
- state = DOM_STATE_MAP[info[0]]
- screenshot = None
- # (type, listen, port, passwd, passwdValidTo)
- graphics = self._vm_get_graphics(name)
- graphics_port = graphics[2]
- graphics_port = graphics_port if state == 'running' else None
- try:
- if state == 'running' and self._has_video(dom):
- screenshot = self.vmscreenshot.lookup(name)
- elif state == 'shutoff':
- # reset vm stats when it is powered off to avoid sending
- # incorrect (old) data
- self.stats[dom.UUIDString()] = {}
- except NotFoundError:
- pass
-
- with self.objstore as session:
- try:
- extra_info = session.get('vm', dom.UUIDString())
- except NotFoundError:
- extra_info = {}
- icon = extra_info.get('icon')
-
- self._update_guest_stats(name)
- vm_stats = self.stats.get(dom.UUIDString(), {})
- res = {}
- res['cpu_utilization'] = vm_stats.get('cpu', 0)
- res['net_throughput'] = vm_stats.get('net_io', 0)
- res['net_throughput_peak'] = vm_stats.get('max_net_io', 100)
- res['io_throughput'] = vm_stats.get('disk_io', 0)
- res['io_throughput_peak'] = vm_stats.get('max_disk_io', 100)
- users, groups = self._get_access_info(dom)
-
- if state == 'shutoff':
- xml = dom.XMLDesc(0)
- val = xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]
- unit_list = xpath_get_text(xml, XPATH_DOMAIN_MEMORY_UNIT)
- if len(unit_list) > 0:
- unit = unit_list[0]
- else:
- unit = 'KiB'
- memory = convert_data_size(val, unit, 'MiB')
- else:
- memory = info[2] >> 10
-
- return {'name': name,
- 'state': state,
- 'stats': res,
- 'uuid': dom.UUIDString(),
- 'memory': memory,
- 'cpus': info[3],
- 'screenshot': screenshot,
- 'icon': icon,
- # (type, listen, port, passwd, passwdValidTo)
- 'graphics': {"type": graphics[0],
- "listen": graphics[1],
- "port": graphics_port,
- "passwd": graphics[3],
- "passwdValidTo": graphics[4]},
- 'users': users,
- 'groups': groups,
- 'access': 'full',
- 'persistent': True if dom.isPersistent() else False
- }
-
- def _vm_get_disk_paths(self, dom):
- xml = dom.XMLDesc(0)
- xpath = "/domain/devices/disk[@device='disk']/source/@file"
- return xpath_get_text(xml, xpath)
-
- @staticmethod
- def get_vm(name, conn):
- conn = conn.get()
- try:
- # outgoing text to libvirt, encode('utf-8')
- return conn.lookupByName(name.encode("utf-8"))
- except libvirt.libvirtError as e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
- raise NotFoundError("KCHVM0002E", {'name': name})
- else:
- raise OperationFailed("KCHVM0009E", {'name': name,
- 'err': e.message})
-
- def delete(self, name):
- conn = self.conn.get()
- dom = self.get_vm(name, self.conn)
- if not dom.isPersistent():
- raise InvalidOperation("KCHVM0036E", {'name': name})
-
- self._vmscreenshot_delete(dom.UUIDString())
- paths = self._vm_get_disk_paths(dom)
- info = self.lookup(name)
-
- if info['state'] != 'shutoff':
- self.poweroff(name)
-
- # delete existing snapshots before deleting VM
-
- # libvirt's Test driver does not support the function
- # "virDomainListAllSnapshots", so "VMSnapshots.get_list" will raise
- # "OperationFailed" in that case.
- try:
- snapshot_names = self.vmsnapshots.get_list(name)
- except OperationFailed, e:
- wok_log.error('cannot list snapshots: %s; '
- 'skipping snapshot deleting...' % e.message)
- else:
- for s in snapshot_names:
- self.vmsnapshot.delete(name, s)
-
- try:
- dom.undefine()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0021E",
- {'name': name, 'err': e.get_error_message()})
-
- for path in paths:
- try:
- vol = conn.storageVolLookupByPath(path)
- pool = vol.storagePoolLookupByVolume()
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type not in READONLY_POOL_TYPE:
- vol.delete(0)
- # Update objstore to remove the volume
- with self.objstore as session:
- session.delete('storagevolume', path,
- ignore_missing=True)
- except libvirt.libvirtError as e:
- wok_log.error('Unable to get storage volume by path: %s' %
- e.message)
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
-
- try:
- with self.objstore as session:
- if path in session.get_list('storagevolume'):
- used_by = session.get('storagevolume', path)['used_by']
- used_by.remove(name)
- session.store('storagevolume', path,
- {'used_by': used_by})
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
-
- try:
- with self.objstore as session:
- session.delete('vm', dom.UUIDString(), ignore_missing=True)
- except Exception as e:
- # It is possible to delete vm without delete its database info
- wok_log.error('Error deleting vm information from database: '
- '%s', e.message)
-
- vnc.remove_proxy_token(name)
-
- def start(self, name):
- # make sure the ISO file has read permission
- dom = self.get_vm(name, self.conn)
- xml = dom.XMLDesc(0)
- xpath = "/domain/devices/disk[@device='cdrom']/source/@file"
- isofiles = xpath_get_text(xml, xpath)
-
- user = UserTests.probe_user()
- for iso in isofiles:
- run_setfacl_set_attr(iso, user=user)
-
- dom = self.get_vm(name, self.conn)
- try:
- dom.create()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0019E",
- {'name': name, 'err': e.get_error_message()})
-
- def poweroff(self, name):
- dom = self.get_vm(name, self.conn)
- try:
- dom.destroy()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0020E",
- {'name': name, 'err': e.get_error_message()})
-
- def shutdown(self, name):
- dom = self.get_vm(name, self.conn)
- try:
- dom.shutdown()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0029E",
- {'name': name, 'err': e.get_error_message()})
-
- def reset(self, name):
- dom = self.get_vm(name, self.conn)
- try:
- dom.reset(flags=0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0022E",
- {'name': name, 'err': e.get_error_message()})
-
- def _vm_get_graphics(self, name):
- dom = self.get_vm(name, self.conn)
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
-
- expr = "/domain/devices/graphics/@type"
- res = xpath_get_text(xml, expr)
- graphics_type = res[0] if res else None
-
- expr = "/domain/devices/graphics/@listen"
- res = xpath_get_text(xml, expr)
- graphics_listen = res[0] if res else None
-
- graphics_port = graphics_passwd = graphics_passwdValidTo = None
- if graphics_type:
- expr = "/domain/devices/graphics[@type='%s']/@port"
- res = xpath_get_text(xml, expr % graphics_type)
- graphics_port = int(res[0]) if res else None
-
- expr = "/domain/devices/graphics[@type='%s']/@passwd"
- res = xpath_get_text(xml, expr % graphics_type)
- graphics_passwd = res[0] if res else None
-
- expr = "/domain/devices/graphics[@type='%s']/@passwdValidTo"
- res = xpath_get_text(xml, expr % graphics_type)
- if res:
- to = time.mktime(time.strptime(res[0], '%Y-%m-%dT%H:%M:%S'))
- graphics_passwdValidTo = to - time.mktime(time.gmtime())
-
- return (graphics_type, graphics_listen, graphics_port,
- graphics_passwd, graphics_passwdValidTo)
-
- def connect(self, name):
- # (type, listen, port, passwd, passwdValidTo)
- graphics_port = self._vm_get_graphics(name)[2]
- if graphics_port is not None:
- vnc.add_proxy_token(name, graphics_port)
- else:
- raise OperationFailed("KCHVM0010E", {'name': name})
-
- def _vmscreenshot_delete(self, vm_uuid):
- screenshot = VMScreenshotModel.get_screenshot(vm_uuid, self.objstore,
- self.conn)
- screenshot.delete()
- try:
- with self.objstore as session:
- session.delete('screenshot', vm_uuid)
- except Exception as e:
- # It is possible to continue Kimchi executions without delete
- # screenshots
- wok_log.error('Error trying to delete vm screenshot from '
- 'database due error: %s', e.message)
-
- def suspend(self, name):
- """Suspend the virtual machine's execution and puts it in the
- state 'paused'. Use the function "resume" to restore its state.
- If the VM is not running, an exception will be raised.
-
- Parameters:
- name -- the name of the VM to be suspended.
- """
- vm = self.lookup(name)
- if vm['state'] != 'running':
- raise InvalidOperation('KCHVM0037E', {'name': name})
-
- vir_dom = self.get_vm(name, self.conn)
-
- try:
- vir_dom.suspend()
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0038E', {'name': name,
- 'err': e.message})
-
- def resume(self, name):
- """Resume the virtual machine's execution and puts it in the
- state 'running'. The VM should have been suspended previously by the
- function "suspend" and be in the state 'paused', otherwise an exception
- will be raised.
-
- Parameters:
- name -- the name of the VM to be resumed.
- """
- vm = self.lookup(name)
- if vm['state'] != 'paused':
- raise InvalidOperation('KCHVM0039E', {'name': name})
-
- vir_dom = self.get_vm(name, self.conn)
-
- try:
- vir_dom.resume()
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0040E', {'name': name,
- 'err': e.message})
-
-
-class VMScreenshotModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.conn = kargs['conn']
-
- def lookup(self, name):
- dom = VMModel.get_vm(name, self.conn)
- d_info = dom.info()
- vm_uuid = dom.UUIDString()
- if DOM_STATE_MAP[d_info[0]] != 'running':
- raise NotFoundError("KCHVM0004E", {'name': name})
-
- screenshot = self.get_screenshot(vm_uuid, self.objstore, self.conn)
- img_path = screenshot.lookup()
- # screenshot info changed after scratch generation
- try:
- with self.objstore as session:
- session.store('screenshot', vm_uuid, screenshot.info)
- except Exception as e:
- # It is possible to continue Kimchi executions without store
- # screenshots
- wok_log.error('Error trying to update database with guest '
- 'screenshot information due error: %s', e.message)
- return img_path
-
- @staticmethod
- def get_screenshot(vm_uuid, objstore, conn):
- try:
- with objstore as session:
- try:
- params = session.get('screenshot', vm_uuid)
- except NotFoundError:
- params = {'uuid': vm_uuid}
- session.store('screenshot', vm_uuid, params)
- except Exception as e:
- # The 'except' outside of 'with' is necessary to catch possible
- # exception from '__exit__' when calling 'session.store'
- # It is possible to continue Kimchi vm executions without
- # screenshots
- wok_log.error('Error trying to update database with guest '
- 'screenshot information due error: %s', e.message)
- return LibvirtVMScreenshot(params, conn)
-
-
-class LibvirtVMScreenshot(VMScreenshot):
- def __init__(self, vm_uuid, conn):
- VMScreenshot.__init__(self, vm_uuid)
- self.conn = conn
-
- def _generate_scratch(self, thumbnail):
- def handler(stream, buf, opaque):
- fd = opaque
- os.write(fd, buf)
-
- fd = os.open(thumbnail, os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0644)
- try:
- conn = self.conn.get()
- dom = conn.lookupByUUIDString(self.vm_uuid)
- vm_name = dom.name()
- stream = conn.newStream(0)
- dom.screenshot(stream, 0, 0)
- stream.recvAll(handler, fd)
- except libvirt.libvirtError:
- try:
- stream.abort()
- except:
- pass
- raise NotFoundError("KCHVM0006E", {'name': vm_name})
- else:
- stream.finish()
- finally:
- os.close(fd)
diff --git a/plugins/kimchi/model/vmsnapshots.py b/plugins/kimchi/model/vmsnapshots.py
deleted file mode 100644
index fff1908..0000000
--- a/plugins/kimchi/model/vmsnapshots.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import time
-from lxml import objectify
-from lxml.builder import E
-
-from wok.exception import InvalidOperation, NotFoundError, OperationFailed
-from wok.utils import add_task
-from wok.xmlutils.utils import xpath_get_text
-from wok.model.tasks import TaskModel
-
-from vms import DOM_STATE_MAP, VMModel
-from vmstorages import VMStorageModel, VMStoragesModel
-
-
-class VMSnapshotsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
- self.vmstorages = VMStoragesModel(**kargs)
- self.vmstorage = VMStorageModel(**kargs)
-
- def create(self, vm_name, params={}):
- """Create a snapshot with the current domain state.
-
- The VM must be stopped and contain only disks with format 'qcow2';
- otherwise an exception will be raised.
-
- Parameters:
- vm_name -- the name of the VM where the snapshot will be created.
- params -- a dict with the following values:
- "name": The snapshot name (optional). If omitted, a default value
- based on the current time will be used.
-
- Return:
- A Task running the operation.
- """
- vir_dom = VMModel.get_vm(vm_name, self.conn)
- if DOM_STATE_MAP[vir_dom.info()[0]] != u'shutoff':
- raise InvalidOperation('KCHSNAP0001E', {'vm': vm_name})
-
- # if the VM has a non-CDROM disk with type 'raw', abort.
- for storage_name in self.vmstorages.get_list(vm_name):
- storage = self.vmstorage.lookup(vm_name, storage_name)
- type = storage['type']
- format = storage['format']
-
- if type != u'cdrom' and format != u'qcow2':
- raise InvalidOperation('KCHSNAP0010E', {'vm': vm_name,
- 'format': format})
-
- name = params.get('name', unicode(int(time.time())))
-
- task_params = {'vm_name': vm_name, 'name': name}
- taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' % (vm_name,
- name), self._create_task, self.objstore, task_params)
- return self.task.lookup(taskid)
-
- def _create_task(self, cb, params):
- """Asynchronous function which actually creates the snapshot.
-
- Parameters:
- cb -- a callback function to signal the Task's progress.
- params -- a dict with the following values:
- "vm_name": the name of the VM where the snapshot will be created.
- "name": the snapshot name.
- """
- vm_name = params['vm_name']
- name = params['name']
-
- cb('building snapshot XML')
- root_elem = E.domainsnapshot()
- root_elem.append(E.name(name))
- xml = ET.tostring(root_elem, encoding='utf-8')
-
- try:
- cb('fetching snapshot domain')
- vir_dom = VMModel.get_vm(vm_name, self.conn)
- cb('creating snapshot')
- vir_dom.snapshotCreateXML(xml, 0)
- except (NotFoundError, OperationFailed, libvirt.libvirtError), e:
- raise OperationFailed('KCHSNAP0002E',
- {'name': name, 'vm': vm_name,
- 'err': e.message})
-
- cb('OK', True)
-
- def get_list(self, vm_name):
- vir_dom = VMModel.get_vm(vm_name, self.conn)
-
- try:
- vir_snaps = vir_dom.listAllSnapshots(0)
- return sorted([s.getName().decode('utf-8') for s in vir_snaps],
- key=unicode.lower)
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0005E',
- {'vm': vm_name, 'err': e.message})
-
-
-class VMSnapshotModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def lookup(self, vm_name, name):
- vir_snap = self.get_vmsnapshot(vm_name, name)
-
- try:
- snap_xml_str = vir_snap.getXMLDesc(0).decode('utf-8')
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0004E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
- snap_xml = objectify.fromstring(snap_xml_str)
-
- try:
- parent = unicode(snap_xml.parent.name)
- except AttributeError:
- parent = u''
-
- return {'created': unicode(snap_xml.creationTime),
- 'name': unicode(snap_xml.name),
- 'parent': parent,
- 'state': unicode(snap_xml.state)}
-
- def delete(self, vm_name, name):
- try:
- vir_snap = self.get_vmsnapshot(vm_name, name)
- vir_snap.delete(0)
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0006E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
- def revert(self, vm_name, name):
- try:
- vir_dom = VMModel.get_vm(vm_name, self.conn)
- vir_snap = self.get_vmsnapshot(vm_name, name)
- vir_dom.revertToSnapshot(vir_snap, 0)
-
- # get vm name recorded in the snapshot and return new uri params
- vm_new_name = xpath_get_text(vir_snap.getXMLDesc(0),
- 'domain/name')[0]
- return [vm_new_name, name]
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0009E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
- def get_vmsnapshot(self, vm_name, name):
- vir_dom = VMModel.get_vm(vm_name, self.conn)
-
- try:
- return vir_dom.snapshotLookupByName(name, 0)
- except libvirt.libvirtError, e:
- code = e.get_error_code()
- if code == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
- raise NotFoundError('KCHSNAP0003E', {'name': name,
- 'vm': vm_name})
- else:
- raise OperationFailed('KCHSNAP0004E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
-
-class CurrentVMSnapshotModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.vmsnapshot = VMSnapshotModel(**kargs)
-
- def lookup(self, vm_name):
- vir_dom = VMModel.get_vm(vm_name, self.conn)
-
- try:
- vir_snap = vir_dom.snapshotCurrent(0)
- snap_name = vir_snap.getName().decode('utf-8')
- except libvirt.libvirtError, e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
- return {}
-
- raise OperationFailed('KCHSNAP0008E',
- {'vm': vm_name, 'err': e.message})
-
- return self.vmsnapshot.lookup(vm_name, snap_name)
diff --git a/plugins/kimchi/model/vmstorages.py b/plugins/kimchi/model/vmstorages.py
deleted file mode 100644
index bec16c6..0000000
--- a/plugins/kimchi/model/vmstorages.py
+++ /dev/null
@@ -1,252 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import string
-from lxml import etree
-
-from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
-from wok.exception import OperationFailed
-from wok.utils import wok_log
-
-from ..osinfo import lookup
-from ..xmlutils.disk import get_device_node, get_disk_xml
-from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
-from config import CapabilitiesModel
-from diskutils import get_disk_used_by, set_disk_used_by
-from storagevolumes import StorageVolumeModel
-from utils import get_vm_config_flag
-from vms import DOM_STATE_MAP, VMModel
-
-
-HOTPLUG_TYPE = ['scsi', 'virtio']
-
-
-def _get_device_bus(dev_type, dom, metadata_support):
- try:
- version, distro = VMModel.vm_get_os_metadata(dom, metadata_support)
- except:
- version, distro = ('unknown', 'unknown')
- return lookup(distro, version)[dev_type+'_bus']
-
-
-class VMStoragesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
-
- def _get_available_bus_address(self, bus_type, vm_name):
- if bus_type not in ['ide']:
- return dict()
- # libvirt limitation of just 1 ide controller
- # each controller have at most 2 buses and each bus 2 units.
- dom = VMModel.get_vm(vm_name, self.conn)
- disks = self.get_list(vm_name)
- valid_id = [('0', '0'), ('0', '1'), ('1', '0'), ('1', '1')]
- controller_id = '0'
- for dev_name in disks:
- disk = get_device_node(dom, dev_name)
- if disk.target.attrib['bus'] == 'ide':
- controller_id = disk.address.attrib['controller']
- bus_id = disk.address.attrib['bus']
- unit_id = disk.address.attrib['unit']
- if (bus_id, unit_id) in valid_id:
- valid_id.remove((bus_id, unit_id))
- continue
- if not valid_id:
- raise OperationFailed('KCHVMSTOR0014E',
- {'type': 'ide', 'limit': 4})
- else:
- address = {'controller': controller_id,
- 'bus': valid_id[0][0], 'unit': valid_id[0][1]}
- return dict(address=address)
-
- def create(self, vm_name, params):
- vol_model = None
- # Path will never be blank due to API.json verification.
- # There is no need to cover this case here.
- if not ('vol' in params) ^ ('path' in params):
- raise InvalidParameter("KCHVMSTOR0017E")
-
- dom = VMModel.get_vm(vm_name, self.conn)
- params['bus'] = _get_device_bus(params['type'], dom,
- self.caps.metadata_support)
- params['format'] = 'raw'
-
- dev_list = [dev for dev, bus in get_vm_disks(dom).iteritems()
- if bus == params['bus']]
- dev_list.sort()
- if len(dev_list) == 0:
- params['index'] = 0
- else:
- char = dev_list.pop()[2]
- params['index'] = string.ascii_lowercase.index(char) + 1
-
- if (params['bus'] not in HOTPLUG_TYPE and
- DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
- raise InvalidOperation('KCHVMSTOR0011E')
-
- if params.get('vol'):
- try:
- pool = params['pool']
- vol_model = StorageVolumeModel(conn=self.conn,
- objstore=self.objstore)
- vol_info = vol_model.lookup(pool, params['vol'])
- except KeyError:
- raise InvalidParameter("KCHVMSTOR0012E")
- except Exception as e:
- raise InvalidParameter("KCHVMSTOR0015E", {'error': e})
- if len(vol_info['used_by']) != 0:
- raise InvalidParameter("KCHVMSTOR0016E")
-
- valid_format = {
- "disk": ["raw", "bochs", "qcow", "qcow2", "qed", "vmdk"],
- "cdrom": "iso"}
-
- if vol_info['type'] == 'file':
- if (params['type'] == 'disk' and
- vol_info['format'] in valid_format[params['type']]):
- params['format'] = vol_info['format']
- else:
- raise InvalidParameter("KCHVMSTOR0018E",
- {"format": vol_info['format'],
- "type": params['type']})
-
- params['path'] = vol_info['path']
- params['disk'] = vol_info['type']
-
- params.update(self._get_available_bus_address(params['bus'], vm_name))
-
- # Add device to VM
- dev, xml = get_disk_xml(params)
- try:
- conn = self.conn.get()
- dom = conn.lookupByName(vm_name)
- dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
- except Exception as e:
- raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
-
- # Don't put a try-block here. Let the exception be raised. If we
- # allow disks used_by to be out of sync, data corruption could
- # occour if a disk is added to two guests unknowingly.
- if params.get('vol'):
- used_by = vol_info['used_by']
- used_by.append(vm_name)
- set_disk_used_by(self.objstore, params['path'], used_by)
-
- return dev
-
- def get_list(self, vm_name):
- dom = VMModel.get_vm(vm_name, self.conn)
- return get_vm_disks(dom).keys()
-
-
-class VMStorageModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
-
- def lookup(self, vm_name, dev_name):
- # Retrieve disk xml and format return dict
- dom = VMModel.get_vm(vm_name, self.conn)
- return get_vm_disk_info(dom, dev_name)
-
- def delete(self, vm_name, dev_name):
- conn = self.conn.get()
-
- try:
- bus_type = self.lookup(vm_name, dev_name)['bus']
- dom = conn.lookupByName(vm_name)
- except NotFoundError:
- raise
-
- if (bus_type not in HOTPLUG_TYPE and
- DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
- raise InvalidOperation('KCHVMSTOR0011E')
-
- try:
- disk = get_device_node(dom, dev_name)
- path = get_vm_disk_info(dom, dev_name)['path']
- if path is None or len(path) < 1:
- path = self.lookup(vm_name, dev_name)['path']
- # This has to be done before it's detached. If it wasn't
- # in the obj store, its ref count would have been updated
- # by get_disk_used_by()
- if path is not None:
- used_by = get_disk_used_by(self.objstore, self.conn, path)
- else:
- wok_log.error("Unable to decrement volume used_by on"
- " delete because no path could be found.")
- dom.detachDeviceFlags(etree.tostring(disk),
- get_vm_config_flag(dom, 'all'))
- except Exception as e:
- raise OperationFailed("KCHVMSTOR0010E", {'error': e.message})
-
- if used_by is not None and vm_name in used_by:
- used_by.remove(vm_name)
- set_disk_used_by(self.objstore, path, used_by)
- else:
- wok_log.error("Unable to update %s:%s used_by on delete."
- % (vm_name, dev_name))
-
- def update(self, vm_name, dev_name, params):
- old_disk_used_by = None
- new_disk_used_by = None
-
- dom = VMModel.get_vm(vm_name, self.conn)
-
- dev_info = self.lookup(vm_name, dev_name)
- if dev_info['type'] != 'cdrom':
- raise InvalidOperation("KCHVMSTOR0006E")
-
- params['path'] = params.get('path', '')
- old_disk_path = dev_info['path']
- new_disk_path = params['path']
- if new_disk_path != old_disk_path:
- # An empty path means a CD-ROM was empty or ejected:
- if old_disk_path is not '':
- old_disk_used_by = get_disk_used_by(
- self.objstore, self.conn, old_disk_path)
- if new_disk_path is not '':
- new_disk_used_by = get_disk_used_by(
- self.objstore, self.conn, new_disk_path)
-
- dev_info.update(params)
- dev, xml = get_disk_xml(dev_info)
-
- try:
- dom.updateDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
- except Exception as e:
- raise OperationFailed("KCHVMSTOR0009E", {'error': e.message})
-
- try:
- if old_disk_used_by is not None and \
- vm_name in old_disk_used_by:
- old_disk_used_by.remove(vm_name)
- set_disk_used_by(self.objstore, old_disk_path,
- old_disk_used_by)
- if new_disk_used_by is not None:
- new_disk_used_by.append(vm_name)
- set_disk_used_by(self.objstore, new_disk_path,
- new_disk_used_by)
- except Exception as e:
- wok_log.error("Unable to update dev used_by on update due to"
- " %s:" % e.message)
- return dev
diff --git a/plugins/kimchi/netinfo.py b/plugins/kimchi/netinfo.py
deleted file mode 100644
index c5746d7..0000000
--- a/plugins/kimchi/netinfo.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import ethtool
-import glob
-import os
-
-
-NET_PATH = '/sys/class/net'
-NIC_PATH = '/sys/class/net/*/device'
-BRIDGE_PATH = '/sys/class/net/*/bridge'
-BONDING_PATH = '/sys/class/net/*/bonding'
-WLAN_PATH = '/sys/class/net/*/wireless'
-NET_BRPORT = '/sys/class/net/%s/brport'
-NET_MASTER = '/sys/class/net/%s/master'
-NET_STATE = '/sys/class/net/%s/carrier'
-PROC_NET_VLAN = '/proc/net/vlan/'
-BONDING_SLAVES = '/sys/class/net/%s/bonding/slaves'
-BRIDGE_PORTS = '/sys/class/net/%s/brif'
-
-
-def wlans():
- return [b.split('/')[-2] for b in glob.glob(WLAN_PATH)]
-
-
-def is_wlan(iface):
- return iface in wlans()
-
-
-# FIXME if we do not want to list usb nic
-def nics():
- return list(set([b.split('/')[-2] for b in glob.glob(NIC_PATH)]) -
- set(wlans()))
-
-
-def is_nic(iface):
- return iface in nics()
-
-
-def bondings():
- return [b.split('/')[-2] for b in glob.glob(BONDING_PATH)]
-
-
-def is_bonding(iface):
- return iface in bondings()
-
-
-def vlans():
- return list(set([b.split('/')[-1]
- for b in glob.glob(NET_PATH + '/*')]) &
- set([b.split('/')[-1]
- for b in glob.glob(PROC_NET_VLAN + '*')]))
-
-
-def is_vlan(iface):
- return iface in vlans()
-
-
-def bridges():
- return [b.split('/')[-2] for b in glob.glob(BRIDGE_PATH)]
-
-
-def is_bridge(iface):
- return iface in bridges()
-
-
-def all_interfaces():
- return [d.rsplit("/", 1)[-1] for d in glob.glob(NET_PATH + '/*')]
-
-
-def slaves(bonding):
- with open(BONDING_SLAVES % bonding) as bonding_file:
- res = bonding_file.readline().split()
- return res
-
-
-def ports(bridge):
- return os.listdir(BRIDGE_PORTS % bridge)
-
-
-def is_brport(nic):
- return os.path.exists(NET_BRPORT % nic)
-
-
-def is_bondlave(nic):
- return os.path.exists(NET_MASTER % nic)
-
-
-def operstate(dev):
- link_status = link_detected(dev)
- return "down" if link_status == "n/a" else "up"
-
-
-def link_detected(dev):
- # try to read interface carrier (link) status
- try:
- with open(NET_STATE % dev) as dev_file:
- carrier = dev_file.readline().strip()
- # when IOError is raised, interface is down
- except IOError:
- return "n/a"
-
- # if value is 1, interface up with cable connected
- # 0 corresponds to interface up with cable disconnected
- return "yes" if carrier == '1' else "no"
-
-
-def get_vlan_device(vlan):
- """ Return the device of the given VLAN. """
- dev = None
-
- if os.path.exists(PROC_NET_VLAN + vlan):
- with open(PROC_NET_VLAN + vlan) as vlan_file:
- for line in vlan_file:
- if "Device:" in line:
- dummy, dev = line.split()
- break
- return dev
-
-
-def get_bridge_port_device(bridge):
- """Return the nics list that belongs to bridge."""
- # br --- v --- bond --- nic1
- if bridge not in bridges():
- raise ValueError('unknown bridge %s' % bridge)
- nics = []
- for port in ports(bridge):
- if port in vlans():
- device = get_vlan_device(port)
- if device in bondings():
- nics.extend(slaves(device))
- else:
- nics.append(device)
- if port in bondings():
- nics.extend(slaves(port))
- else:
- nics.append(port)
- return nics
-
-
-def aggregated_bridges():
- return [bridge for bridge in bridges() if
- (set(get_bridge_port_device(bridge)) & set(nics()))]
-
-
-def bare_nics():
- "The nic is not a port of a bridge or a slave of bond."
- return [nic for nic in nics() if not (is_brport(nic) or is_bondlave(nic))]
-
-
-def is_bare_nic(iface):
- return iface in bare_nics()
-
-
-# The nic will not be exposed when it is a port of a bridge or
-# a slave of bond.
-# The bridge will not be exposed when all it's port are tap.
-def all_favored_interfaces():
- return aggregated_bridges() + bare_nics() + bondings()
-
-
-def get_interface_type(iface):
- # FIXME if we want to get more device type
- # just support nic, bridge, bondings and vlan, for we just
- # want to expose this 4 kinds of interface
- try:
- if is_nic(iface):
- return "nic"
- if is_bonding(iface):
- return "bonding"
- if is_bridge(iface):
- return "bridge"
- if is_vlan(iface):
- return "vlan"
- return 'unknown'
- except IOError:
- return 'unknown'
-
-
-def get_interface_info(iface):
- if iface not in ethtool.get_devices():
- raise ValueError('unknown interface: %s' % iface)
-
- ipaddr = ''
- netmask = ''
- try:
- ipaddr = ethtool.get_ipaddr(iface)
- netmask = ethtool.get_netmask(iface)
- except IOError:
- pass
-
- iface_link_detected = link_detected(iface)
- iface_status = 'active' if iface_link_detected != "n/a" else "inactive"
-
- return {'name': iface,
- 'type': get_interface_type(iface),
- 'status': iface_status,
- 'link_detected': iface_link_detected,
- 'ipaddr': ipaddr,
- 'netmask': netmask}
diff --git a/plugins/kimchi/network.py b/plugins/kimchi/network.py
deleted file mode 100644
index 1433b8a..0000000
--- a/plugins/kimchi/network.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import ethtool
-import ipaddr
-
-
-APrivateNets = ipaddr.IPNetwork("10.0.0.0/8")
-BPrivateNets = ipaddr.IPNetwork("172.16.0.0/12")
-CPrivateNets = ipaddr.IPNetwork('192.168.0.0/16')
-PrivateNets = [CPrivateNets, BPrivateNets, APrivateNets]
-DefaultNetsPool = [ipaddr.IPNetwork('192.168.122.0/23'),
- ipaddr.IPNetwork('192.168.124.0/22'),
- ipaddr.IPNetwork('192.168.128.0/17')]
-
-
-def get_dev_netaddr(dev):
- info = ethtool.get_interfaces_info(dev)[0]
- return (info.ipv4_address and
- "%s/%s" % (info.ipv4_address, info.ipv4_netmask) or '')
-
-
-def get_dev_netaddrs():
- nets = []
- for dev in ethtool.get_devices():
- devnet = get_dev_netaddr(dev)
- devnet and nets.append(ipaddr.IPNetwork(devnet))
- return nets
-
-
-# used_nets should include all the subnet allocated in libvirt network
-# will get host network by get_dev_netaddrs
-def get_one_free_network(used_nets, nets_pool=PrivateNets):
- def _get_free_network(nets, used_nets):
- for net in nets.subnet(new_prefix=24):
- if not any(net.overlaps(used) for used in used_nets):
- return str(net)
- return None
-
- used_nets = used_nets + get_dev_netaddrs()
- for nets in nets_pool:
- net = _get_free_network(nets, used_nets)
- if net:
- return net
- return None
diff --git a/plugins/kimchi/osinfo.py b/plugins/kimchi/osinfo.py
deleted file mode 100644
index 5b1277c..0000000
--- a/plugins/kimchi/osinfo.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import copy
-import glob
-import os
-import psutil
-from collections import defaultdict
-from configobj import ConfigObj
-from distutils.version import LooseVersion
-
-from wok.config import PluginPaths
-
-
-SUPPORTED_ARCHS = {'x86': ('i386', 'i686', 'x86_64'),
- 'power': ('ppc', 'ppc64'),
- 'ppc64le': ('ppc64le')}
-
-
-template_specs = {'x86': {'old': dict(disk_bus='ide',
- nic_model='e1000', sound_model='ich6'),
- 'modern': dict(disk_bus='virtio',
- nic_model='virtio',
- sound_model='ich6')},
- 'power': {'old': dict(disk_bus='scsi',
- nic_model='spapr-vlan',
- cdrom_bus='scsi',
- kbd_type="kbd",
- kbd_bus='usb', mouse_bus='usb',
- tablet_bus='usb', memory=1280),
- 'modern': dict(disk_bus='virtio',
- nic_model='virtio',
- cdrom_bus='scsi',
- kbd_bus='usb',
- kbd_type="kbd",
- mouse_bus='usb', tablet_bus='usb',
- memory=1280)},
- 'ppc64le': {'old': dict(disk_bus='virtio',
- nic_model='virtio',
- cdrom_bus='scsi',
- kbd_bus='usb',
- kbd_type="keyboard",
- mouse_bus='usb', tablet_bus='usb',
- memory=1280),
- 'modern': dict(disk_bus='virtio',
- nic_model='virtio',
- cdrom_bus='scsi',
- kbd_bus='usb',
- kbd_type="keyboard",
- mouse_bus='usb', tablet_bus='usb',
- memory=1280)}}
-
-
-custom_specs = {'fedora': {'22': dict(video_model='qxl')}}
-
-
-modern_version_bases = {'x86': {'debian': '6.0', 'ubuntu': '7.10',
- 'opensuse': '10.3', 'centos': '5.3',
- 'rhel': '6.0', 'fedora': '16', 'gentoo': '0',
- 'sles': '11', 'arch': '0'},
- 'power': {'rhel': '6.5', 'fedora': '19',
- 'ubuntu': '14.04',
- 'opensuse': '13.1',
- 'sles': '11sp3'},
- 'ppc64le': {'rhel': '6.5', 'fedora': '19',
- 'ubuntu': '14.04',
- 'opensuse': '13.1',
- 'sles': '11sp3'}}
-
-
-icon_available_distros = [icon[5:-4] for icon in glob.glob1('%s/images/'
- % PluginPaths('kimchi').ui_dir, 'icon-*.png')]
-
-
-def _get_tmpl_defaults():
- """
- ConfigObj returns a dict like below when no changes were made in the
- template configuration file (template.conf)
-
- {'main': {}, 'storage': {'disk.0': {}}, 'processor': {}, 'graphics': {}}
-
- The default values should be like below:
-
- {'main': {'networks': ['default'], 'memory': '1024'},
- 'storage': {'pool': 'default',
- 'disk.0': {'format': 'qcow2', 'size': '10'}},
- 'processor': {'cpus': '1'},
- 'graphics': {'type': 'spice', 'listen': '127.0.0.1'}}
- """
- # Create dict with default values
- tmpl_defaults = defaultdict(dict)
- tmpl_defaults['main']['networks'] = ['default']
- tmpl_defaults['main']['memory'] = 1024
- tmpl_defaults['storage']['pool'] = 'default'
- tmpl_defaults['storage']['disk.0'] = {'size': 10, 'format': 'qcow2'}
- tmpl_defaults['processor']['cpus'] = 1
- tmpl_defaults['graphics'] = {'type': 'vnc', 'listen': '127.0.0.1'}
-
- default_config = ConfigObj(tmpl_defaults)
-
- # Load template configuration file
- config_file = os.path.join(PluginPaths('kimchi').conf_dir, 'template.conf')
- config = ConfigObj(config_file)
-
- # Merge default configuration with file configuration
- default_config.merge(config)
-
- # Create a dict with default values according to data structure
- # expected by VMTemplate
- defaults = {'domain': 'kvm', 'arch': os.uname()[4],
- 'cdrom_bus': 'ide', 'cdrom_index': 2, 'mouse_bus': 'ps2'}
-
- # Parse main section to get networks and memory values
- main_section = default_config.pop('main')
- defaults.update(main_section)
-
- # Parse storage section to get storage pool and disks values
- storage_section = default_config.pop('storage')
- defaults['storagepool'] = '/plugins/kimchi/storagepools/' + \
- storage_section.pop('pool')
- defaults['disks'] = []
- for disk in storage_section.keys():
- data = storage_section[disk]
- data['index'] = int(disk.split('.')[1])
- defaults['disks'].append(data)
-
- # Parse processor section to get cpus and cpu_topology values
- processor_section = default_config.pop('processor')
- defaults['cpus'] = processor_section.pop('cpus')
- defaults['cpu_info'] = {}
- if len(processor_section.keys()) > 0:
- defaults['cpu_info']['topology'] = processor_section
-
- # Update defaults values with graphics values
- defaults['graphics'] = default_config.pop('graphics')
-
- return defaults
-
-
-# Set defaults values according to template.conf file
-defaults = _get_tmpl_defaults()
-
-
-def _get_arch():
- for arch, sub_archs in SUPPORTED_ARCHS.iteritems():
- if os.uname()[4] in sub_archs:
- return arch
-
-
-def get_template_default(template_type, field):
- host_arch = _get_arch()
- # Assuming 'power' = 'ppc64le' because lookup() does the same,
- # claiming libvirt compatibility.
- host_arch = 'power' if host_arch == 'ppc64le' else host_arch
- tmpl_defaults = copy.deepcopy(defaults)
- tmpl_defaults.update(template_specs[host_arch][template_type])
- return tmpl_defaults[field]
-
-
-def lookup(distro, version):
- """
- Lookup all parameters needed to run a VM of a known or unknown operating
- system type and version. The data is constructed by starting with the
- 'defaults' and merging the parameters given for the identified OS. If
- known, a link to a remote install CD is added.
- """
- params = copy.deepcopy(defaults)
- params['os_distro'] = distro
- params['os_version'] = version
- arch = _get_arch()
-
- # Setting maxMemory of the VM, which will be equal total Host memory in Kib
- params['max_memory'] = psutil.TOTAL_PHYMEM >> 10
-
- # set up arch to ppc64 instead of ppc64le due to libvirt compatibility
- if params["arch"] == "ppc64le":
- params["arch"] = "ppc64"
-
- if distro in modern_version_bases[arch]:
- if LooseVersion(version) >= LooseVersion(
- modern_version_bases[arch][distro]):
- params.update(template_specs[arch]['modern'])
- else:
- params.update(template_specs[arch]['old'])
- else:
- params['os_distro'] = params['os_version'] = "unknown"
- params.update(template_specs[arch]['old'])
-
- # Get custom specifications
- params.update(custom_specs.get(distro, {}).get(version, {}))
-
- if distro in icon_available_distros:
- params['icon'] = 'plugins/kimchi/images/icon-%s.png' % distro
- else:
- params['icon'] = 'plugins/kimchi/images/icon-vm.png'
-
- return params
diff --git a/plugins/kimchi/po/LINGUAS b/plugins/kimchi/po/LINGUAS
deleted file mode 100644
index 3fcb18f..0000000
--- a/plugins/kimchi/po/LINGUAS
+++ /dev/null
@@ -1,11 +0,0 @@
-en_US
-pt_BR
-zh_CN
-de_DE
-es_ES
-fr_FR
-it_IT
-ja_JP
-ko_KR
-ru_RU
-zh_TW
diff --git a/plugins/kimchi/po/Makefile.in.in b/plugins/kimchi/po/Makefile.in.in
deleted file mode 100644
index d01fb31..0000000
--- a/plugins/kimchi/po/Makefile.in.in
+++ /dev/null
@@ -1,398 +0,0 @@
-# Makefile for PO directory in any package using GNU gettext.
-# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper at gnu.ai.mit.edu>
-#
-# This file can be copied and used freely without restrictions. It can
-# be used in projects which are not available under the GNU General Public
-# License but which still want to provide support for the GNU gettext
-# functionality.
-# Please note that the actual code of GNU gettext is covered by the GNU
-# General Public License and is *not* in the public domain.
-#
-# Origin: gettext-0.18
-GETTEXT_MACRO_VERSION = 0.18
-
-PACKAGE = @PACKAGE@
-VERSION = @VERSION@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-
-SHELL = /bin/sh
- at SET_MAKE@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-datarootdir = @datarootdir@
-datadir = @datadir@
-localedir = @prefix@/share/locale
-gettextsrcdir = $(datadir)/gettext/po
-
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-
-# We use $(MKDIR_P).
-# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
-# on invoking install-sh with the -d option, so your package should contain
-# install-sh as described under AC_PROG_INSTALL.
-mkinstalldirs = $(SHELL) @install_sh@ -d
-install_sh = $(SHELL) @install_sh@
-MKDIR_P = @MKDIR_P@
-MKDIR_P = @MKDIR_P@
-
-GMSGFMT_ = @GMSGFMT@
-GMSGFMT_no = @GMSGFMT@
-GMSGFMT_yes = @GMSGFMT_015@
-GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
-MSGFMT_ = @MSGFMT@
-MSGFMT_no = @MSGFMT@
-MSGFMT_yes = @MSGFMT_015@
-MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
-XGETTEXT_ = @XGETTEXT@
-XGETTEXT_no = @XGETTEXT@
-XGETTEXT_yes = @XGETTEXT_015@
-XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-MSGMERGE = msgmerge
-MSGMERGE_UPDATE = @MSGMERGE@ --update
-MSGINIT = msginit
-MSGCONV = msgconv
-MSGFILTER = msgfilter
-
-POFILES = @POFILES@
-GMOFILES = @GMOFILES@
-UPDATEPOFILES = @UPDATEPOFILES@
-DUMMYPOFILES = @DUMMYPOFILES@
-DISTFILES.common = Makefile.in.in \
-$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
-DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot.in \
-$(POFILES) $(GMOFILES) \
-$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
-
-POTFILES = \
-
-CATALOGS = @CATALOGS@
-
-# Makevars gets inserted here. (Don't remove this line!)
-
-.SUFFIXES:
-.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
-
-.po.mo:
- @echo "$(MSGFMT) -c -o $@ $<"; \
- $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
-
-.po.gmo:
- @lang=`echo $* | sed -e 's,.*/,,'`; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
- cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
-
-.sin.sed:
- sed -e '/^#/d' $< > t-$@
- mv t-$@ $@
-
-
-all: check-macro-version update-gmo all- at USE_NLS@
-
-all-yes: stamp-po
-all-no:
-
-# Ensure that the gettext macros and this Makefile.in.in are in sync.
-check-macro-version:
- @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
- || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
- exit 1; \
- }
-
-# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
-# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
-# we don't want to bother translators with empty POT files). We assume that
-# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
-# In this case, stamp-po is a nop (i.e. a phony target).
-
-# stamp-po is a timestamp denoting the last time at which the CATALOGS have
-# been loosely updated. Its purpose is that when a developer or translator
-# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
-# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
-# invocations of "make" will do nothing. This timestamp would not be necessary
-# if updating the $(CATALOGS) would always touch them; however, the rule for
-# $(POFILES) has been designed to not touch files that don't need to be
-# changed.
-stamp-po: $(srcdir)/$(DOMAIN).pot
- test ! -f $(srcdir)/$(DOMAIN).pot || \
- test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
- @test ! -f $(srcdir)/$(DOMAIN).pot || { \
- echo "touch stamp-po" && \
- echo timestamp > stamp-poT && \
- mv stamp-poT stamp-po; \
- }
-
-# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
-# otherwise packages like GCC can not be built if only parts of the source
-# have been downloaded.
-
-$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
- $(srcdir)/gen-pot $(POTFILES)
-
-# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
-# every "make" invocation, only create it when it is missing.
-# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
-$(srcdir)/$(DOMAIN).pot:
- $(MAKE) $(DOMAIN).pot-update
-
-# This target rebuilds a PO file if $(DOMAIN).pot has changed.
-# Note that a PO file is not touched if it doesn't need to be changed.
-$(POFILES): $(srcdir)/$(DOMAIN).pot
- @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
- if test -f "$(srcdir)/$${lang}.po"; then \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
- cd $(srcdir) \
- && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
- *) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
- esac; \
- }; \
- else \
- $(MAKE) $${lang}.po-create; \
- fi
-
-
-install: install-exec install-data
-install-exec:
-install-data: install-data- at USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- for file in $(DISTFILES.common) Makevars.template; do \
- $(INSTALL_DATA) $(srcdir)/$$file \
- $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- for file in Makevars; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-install-data-no: all
-install-data-yes: all
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
- $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
- echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
- ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
- cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
- fi; \
- done; \
- done
-
-install-strip: install
-
-installdirs: installdirs-exec installdirs-data
-installdirs-exec:
-installdirs-data: installdirs-data- at USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- else \
- : ; \
- fi
-installdirs-data-no:
-installdirs-data-yes:
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- fi; \
- done; \
- done
-
-# Define this as empty until I found a useful application.
-installcheck:
-
-uninstall: uninstall-exec uninstall-data
-uninstall-exec:
-uninstall-data: uninstall-data- at USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- for file in $(DISTFILES.common) Makevars.template; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-uninstall-data-no:
-uninstall-data-yes:
- catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- done; \
- done
-
-check: all
-
-info dvi ps pdf html tags TAGS ctags CTAGS ID:
-
-mostlyclean:
- rm -f remove-potcdate.sed
- rm -f stamp-poT
- rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
- rm -fr *.o
-
-clean: mostlyclean
-
-distclean: clean
- rm -f Makefile Makefile.in POTFILES *.mo
-
-maintainer-clean: distclean
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
- rm -f stamp-po $(GMOFILES)
-
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-dist distdir:
- $(MAKE) update-po
- @$(MAKE) dist2
-# This is a separate target because 'update-po' must be executed before.
-dist2: stamp-po $(DISTFILES)
- dists="$(DISTFILES)"; \
- if test "$(PACKAGE)" = "gettext-tools"; then \
- dists="$$dists Makevars.template"; \
- fi; \
- if test -f $(srcdir)/$(DOMAIN).pot; then \
- dists="$$dists $(DOMAIN).pot stamp-po"; \
- fi; \
- if test -f $(srcdir)/ChangeLog; then \
- dists="$$dists ChangeLog"; \
- fi; \
- for i in 0 1 2 3 4 5 6 7 8 9; do \
- if test -f $(srcdir)/ChangeLog.$$i; then \
- dists="$$dists ChangeLog.$$i"; \
- fi; \
- done; \
- if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
- for file in $$dists; do \
- if test -f $$file; then \
- cp -p $$file $(distdir) || exit 1; \
- else \
- cp -p $(srcdir)/$$file $(distdir) || exit 1; \
- fi; \
- done
-
-update-po: Makefile
- $(MAKE) $(DOMAIN).pot-update
- test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
- $(MAKE) update-gmo
-
-# General rule for creating PO files.
-
-.nop.po-create:
- @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
- echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
- exit 1
-
-# General rule for updating PO files.
-
-.nop.po-update:
- @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
- if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
- tmpdir=`pwd`; \
- echo "$$lang:"; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
- cd $(srcdir); \
- if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
- *) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
- esac; \
- }; then \
- if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
- rm -f $$tmpdir/$$lang.new.po; \
- else \
- if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
- :; \
- else \
- echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
- exit 1; \
- fi; \
- fi; \
- else \
- echo "msgmerge for $$lang.po failed!" 1>&2; \
- rm -f $$tmpdir/$$lang.new.po; \
- fi
-
-$(DUMMYPOFILES):
-
-update-gmo: Makefile $(GMOFILES)
- @:
-
-# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
-# because execution permission bits may not work on the current file system.
-# Use @SHELL@, which is the shell determined by autoconf for the use by its
-# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
-Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
- cd $(top_builddir) \
- && @SHELL@ ./config.status $(subdir)/$@.in po-directories
-
-force:
-
-# Tell versions [3.59,3.63) of GNU make not to export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/plugins/kimchi/po/Makevars b/plugins/kimchi/po/Makevars
deleted file mode 100644
index c29a807..0000000
--- a/plugins/kimchi/po/Makevars
+++ /dev/null
@@ -1,41 +0,0 @@
-# Makefile variables for PO directory in any package using GNU gettext.
-
-# Usually the message domain is the same as the package name.
-DOMAIN = kimchi
-
-# These two variables depend on the location of this directory.
-subdir = po
-top_builddir = ..
-
-# These options get passed to xgettext.
-XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
-
-# This is the copyright holder that gets inserted into the header of the
-# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
-# package. (Note that the msgstr strings, extracted from the package's
-# sources, belong to the copyright holder of the package.) Translators are
-# expected to transfer the copyright for their translations to this person
-# or entity, or to disclaim their copyright. The empty string stands for
-# the public domain; in this case the translators are expected to disclaim
-# their copyright.
-COPYRIGHT_HOLDER =
-
-# This is the email address or URL to which the translators shall report
-# bugs in the untranslated strings:
-# - Strings which are not entire sentences, see the maintainer guidelines
-# in the GNU gettext documentation, section 'Preparing Strings'.
-# - Strings which use unclear terms or require additional context to be
-# understood.
-# - Strings which make invalid assumptions about notation of date, time or
-# money.
-# - Pluralisation problems.
-# - Incorrect English spelling.
-# - Incorrect formatting.
-# It can be your email address, or a mailing list address where translators
-# can write to without being subscribed, or the URL of a web page through
-# which the translators can contact you.
-MSGID_BUGS_ADDRESS = project-kimchi at googlegroups.com
-
-# This is the list of locale categories, beyond LC_MESSAGES, for which the
-# message catalogs shall be used. It is usually empty.
-EXTRA_LOCALE_CATEGORIES =
diff --git a/plugins/kimchi/po/POTFILES.in b/plugins/kimchi/po/POTFILES.in
deleted file mode 100644
index 92eef1e..0000000
--- a/plugins/kimchi/po/POTFILES.in
+++ /dev/null
@@ -1,3 +0,0 @@
-# List of source files which contain translatable strings.
-i18n.py
-ui/pages/*.tmpl
diff --git a/plugins/kimchi/po/de_DE.po b/plugins/kimchi/po/de_DE.po
deleted file mode 100644
index d3f3cc3..0000000
--- a/plugins/kimchi/po/de_DE.po
+++ /dev/null
@@ -1,2288 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: de_DE\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "Fehler beim Abrufen von Blockeinheiten. Details: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "Fehler beim Abrufen von Blockeinheitinformationen für %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Distro-Datei konnte nicht gefunden werden: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"Distro-Datei konnte nicht analysiert werden: %(filename)s. Stellen Sie "
-"sicher, dass es sich um eine JSON-Datei handelt."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "Fehler beim Anmelden bei iSCSI-Hostziel %(portal)s. Details: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Anmeldung bei iSCSI-Host %(host)s Ziel %(target)s nicht möglich"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "Die ISO-Datei %(filename)s ist nicht bootfähig"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "Die ISO-Datei %(filename)s hat keinen gültigen El Torito-Bootsatz"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Ungültiger El Torito-Prüfeintrag in ISO-Datei %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Ungültiger El Torito-Boot-Indikator in ISO-Datei %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Unerwarteter Datenträgertyp für Primärdatenträger in ISO-Datei %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Ungültiges Format beim Lesen des Datenträgerdeskriptors in ISO-Datei %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"Der Hypervisor hat nicht die Berechtigung, die ISO-Datei %(filename)s zu "
-"verwenden. Verschieben Sie sie entweder nach /var/lib/libvirt oder setzen "
-"Sie, sofern möglich, die Suchberechtigung auf Dateizugriffssteuerungslisten "
-"für den Benutzer '%(user)s' oder fügen Sie '%(user)s' der ISO-Pfadgruppe "
-"hinzu oder (nicht empfohlen) 'chmod -R o+x 'path_to_iso'. Details: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "Virtuelle Maschine %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "Virtuelle Maschine %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Screenshot für gestoppte virtuelle Maschine %(name)s konnte nicht abgerufen "
-"werden"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "Fernes ISO-Image wird von diesem Server nicht unterstützt."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht abgerufen werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-"Verbindung zur abgeschalteten Maschine %(name)s konnte nicht hergestellt "
-"werden."
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "Zu überwachende Grafikadresse muss IPv4 oder IPv6 sein"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Vorlage angeben, aus der eine virtuelle Maschine erstellt werden soll"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gelöscht werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht umbenannt werden. Details: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "Netzname muss eine Zeichenfolge sein"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "Netzname muss eine Zeichenfolge sein"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "Benutzer '%(users)s' ist nicht vorhanden."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "Benutzer '%(groups)s' ist nicht vorhanden."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr ""
-"Schnittstelle %(iface)s ist in virtueller Maschine %(name)s nicht vorhanden"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"Das für die virtuelle Maschine %(name)s angegebene Netz %(network)s ist "
-"nicht vorhanden"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "Unterstützter Schnittstellentyp einer virtuellen Maschine ist nur Netz"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"Netzname für Schnittstelle einer virtuellen Maschine muss eine Zeichenfolge "
-"sein"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Ungültige Netzmodellkarte für Schnittstelle einer virtuellen Maschine "
-"angegeben"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Geben Sie Typ und Netz an, um eine neue Schnittstelle für eine virtuelle "
-"Maschine hinzuzufügen"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Vorlage %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr ""
-"Das für Vorlage %(template)s angegebene Netz '%(network)s' ist nicht "
-"vorhanden"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Der für Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht "
-"vorhanden"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-"Der für Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht "
-"aktiv"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Ungültiger Parameter '%(param)s' für CD-ROM angegeben."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"Das für Vorlage %(template)s angegebene Netz %(network)s ist nicht aktiv"
-
-msgid "Template name must be a string"
-msgstr "Vorlagenname muss eine Zeichenfolge sein"
-
-msgid "Template icon must be a path to the image"
-msgstr "Vorlagensymbol muss ein Pfad zum Image sein"
-
-msgid "Template distribution must be a string"
-msgstr "Vorlagenverteilung muss eine Zeichenfolge sein"
-
-msgid "Template distribution version must be a string"
-msgstr "Vorlagenverteilungsversion muss eine Zeichenfolge sein"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "Die Anzahl der CPUs muss eine Ganzzahl sein"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "Speicherkapazität (MB) muss eine Ganzzahl gröÃer als 512 sein"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "Ungültiger Speicherpool-URI %(value)s für Vorlage angegeben"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "Geben Sie ein ISO-Image als CD-ROM an, um eine Vorlage zu erstellen"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Alle Netze für die Vorlage müssen in einer Liste angegeben werden."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr ""
-"Vorlage kann aufgrund des folgenden Fehlers nicht erstellt werden: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr ""
-"Vorlage kann aufgrund des folgenden Fehlers nicht gelöscht werden: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Speicherpool %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Speicherpool %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Geben Sie %(item)s an, um den Speicherpool %(name)s zu erstellen"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Aktiver Speicherpool %(name)s konnte nicht gelöscht werden"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Speicherpools konnten nicht aufgelistet werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Speicherpool %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Anzahl der Speicherdatenträger im Speicherpool %(name)s konnte nicht "
-"abgerufen werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Speicherpool %(name)s konnte nicht aktiviert werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"Speicherpool %(name)s konnte nicht inaktiviert werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "Speicherpool %(name)s konnte nicht gelöscht werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"NFS-Pool konnte nicht erstellt werden, weil Exportpfad %(path)s beim Mounten "
-"blockieren kann"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"NFS-Pool konnte nicht erstellt werden, weil das Mounten des Exportpfads%"
-"(path)s fehlgeschlagen ist"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Nicht unterstützter Speicherpooltyp: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "Speicherpoolhost muss eine IP oder ein Hostname sein"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Einheitenparameter des Speicherpools muss eine Liste sein"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "Ziel-IQN eines iSCSI-Pools muss eine Zeichenfolge sein"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"Port eines fernen Speicherservers muss eine Ganzzahl zwischen 1 und 65535 "
-"sein"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Geben Sie Name und Typ an, um einen Speicherpool zu erstellen"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s ist keine gültige Platte/Partition. Sie konnte nicht hinzugefügt "
-"werden zum Pool %(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Die Parameterplatten können nur für den logischen Speicherpool aktualisiert "
-"werden."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "Der Name des SCSI-Hostadapters muss eine Zeichenfolge sein."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "Der Speicherpool kimchi_isos ist für die interne Verwendung reserviert"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Der NFS-Speicherpool %(name)s konnte nicht aktiviert werden. NFS-Server %"
-"(server)s ist nicht erreichbar."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Der NFS-Speicherpool %(name)s konnte nicht inaktiviert werden. NFS-Server %"
-"(server)s ist nicht erreichbar."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Pool %(name)s konnte nicht inaktiviert werden, weil er einigen Vorlagen "
-"zugeordnet ist"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"Pool %(name)s konnte nicht gelöscht werden, weil er einigen Vorlagen "
-"zugeordnet ist"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"Eine Datenträgergruppe mit dem Namen '%(name)s' ist bereits vorhanden. "
-"Wählen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"Datenbank mit Tiefenscaninformationen kann aufgrund des folgenden Fehlers "
-"nicht aktualisiert werden: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Speicherdatenträger %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"Speicherdatenträger %(name)s ist nicht im Speicherpool %(pool)s vorhanden"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Geben Sie %(item)s an, um Speicherdatenträger %(volume)s zu erstellen"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"Speicherdatenträger konnten nicht aufgelistet werden, weil Speicherpool %"
-"(pool)s nicht aktiv ist"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"Speicherdatenträger %(name)s konnte nicht in Speicherpool %(pool)s erstellt "
-"werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Speicherdatenträger konnten nicht in Speicherpool %(pool)s aufgelistet "
-"werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-"Speicherdatenträger %(name)s konnten nicht bereinigt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Speicherdatenträger %(name)s konnte nicht gelöscht werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"GröÃe des Speicherdatenträgers %(name)s konnte nicht geändert werden. "
-"Details: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"Speichertyp %(type)s unterstützt nicht das Erstellen und Löschen von "
-"Datenträgern"
-
-msgid "Storage volume name must be a string"
-msgstr "Name des Speicherdatenträgers muss eine Zeichenfolge sein"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "Zuordnung des Speicherdatenträgers muss eine Ganzzahl sein"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "Speicherdatenträger erfordert einen Datenträgernamen"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Datenbank mit Datenträgerinformationen kann aufgrund des folgenden Fehlers "
-"nicht aktualisiert werden: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "Schnittstelle %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Netz %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "Netz %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"Das für das Netz %(network)s angegebene Teilnetz %(subnet)s ist nicht gültig."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"Geben Sie eine Netzschnittstelle an, um überbrücktes Netz %(name)s zu "
-"erstellen"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Aktives Netz %(name)s konnte nicht gelöscht werden"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-"Die für das Netz %(network)s angegebene Schnittstelle %(iface)s wird bereits "
-"verwendet"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "Schnittstelle sollte bloÃes NIC, Bonding oder Brückeneinheit sein."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Netz %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Es konnte keine freie IP-Adresse für Netz '%(name)s' gefunden werden"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Unterstützte Netztypen sind Isoliert, NAT und Brücke"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"Teilnetz des Netzes muss eine Zeichenfolge mit IP-Adresse und Präfix oder "
-"Netzmaske sein"
-
-msgid "Network interface must be a string"
-msgstr "Netzschnittstelle muss eine Zeichenfolge sein"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "Netz-VLAN-ID muss eine Ganzzahl zwischen 1 und 4094 sein"
-
-msgid "Specify name and type to create a Network"
-msgstr "Geben Sie Name und Typ an, um ein Netz zu erstellen"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
-"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verknüpft."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
-"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verknüpft."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "Brückeneinheit %(name)s kann nicht die Trunkeinheit eines VLAN sein."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "Schnittstelle %(iface)s konnte nicht aktiviert werden: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"Schnittstelle %(iface)s konnte nicht aktiviert werden. Bitte überprüfen Sie "
-"den Status der physischen Verbindung."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Debugbericht %(name)s ist nicht vorhanden"
-
-msgid "Debug report tool not found in system"
-msgstr "Debugberichtstool nicht im System gefunden"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "Debugbericht %(name)s konnte nicht erstellt werden. Details: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "Debugbericht %(name)s konnte nicht generiert werden. Details: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"Eine Datenträgergruppe mit dem Namen '%(name)s' ist bereits vorhanden. "
-"Wählen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Speicherserver %(server)s wurde nicht von Kimchi verwendet"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' ist nicht vorhanden"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "Partition %(name)s ist nicht im Host vorhanden"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Hostmaschine konnte nicht heruntergefahren werden, weil virtuelle Maschinen "
-"ausgeführt werden"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"Hostmaschine konnte nicht neu gestartet werden, weil virtuelle Maschinen "
-"ausgeführt werden"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "Knoteneinheit '%(name)s' nicht gefunden"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "Keine Pakete für Aktualisierung markiert"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Paket %(name)s ist nicht für Aktualisierung markiert."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Fehler beim Abrufen von Paketen, die für die Aktualsierung markiert sind. "
-"Details: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "Es gibt keinen kompatiblen Paketmanager für dieses System."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "Ungültiger URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Ungültiger Speichertyp. Unterstützte Typen: 'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "Fehler beim Erstellen einer neuen Speichereinheit: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Fehler beim Aktualisieren einer Speichereinheit: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Fehler beim Entfernen einer Speichereinheit: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Geben Sie Typ und Pfad an, um einen neuen Datenträger für eine virtuelle "
-"Maschine hinzuzfügen"
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-"Geben Sie einen Pfad an, um die Platte der virtuellen Maschine zu "
-"aktualisieren"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Geben Sie Typ und Pfad an, um einen neuen Datenträger für eine virtuelle "
-"Maschine hinzuzfügen"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-"YUM-Repository-ID darf nur ein aus einer Zeichenfolge bestehendes Wort sein."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "Repository-URL muss ein http://-, ftp://- oder file://-URL sein."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"Repository-Konfiguration ist ein Wörterbuch mit bestimmten Werten "
-"hinsichtlich Repository-Typ."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "Verteilung an DEB-Repository muss eine Zeichenfolge sein"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "Komponenten für DEB-Repository müssen in einem Array aufgelistet sein"
-
-msgid "Components to DEB repository must be a string"
-msgstr "Komponenten für DEB-Repository müssen eine Zeichenfolge sein"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Name des YUM-Repositorys muss eine Zeichenfolge sein."
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG-Prüfung muss ein boolescher Wert sein."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG-Schlüssel muss ein URL sein, der auf die ASCII-Armor-Datei zeigt."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht aktualisiert werden."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Repository %(repo_id)s ist nicht vorhanden."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "Repository-Verwaltungstool wurde für Ihr System nicht erkannt."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Repository %(repo_id)s ist bereits aktiviert."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Repository %(repo_id)s ist bereits inaktiviert."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht entfernt werden."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"Repository-Konfigurationsdatei %(repo_file)s konnte nicht geschrieben werden"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Geben Sie die Repository-Verteilung an, um ein DEB-Repository zu erstellen."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht aktiviert werden."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht inaktiviert werden."
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM-Repository-ID ist bereits vorhanden"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM-Repository-Name muss eine Zeichenfolge sein"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Repositorys konnten nicht aufgelistet werden. Details: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-"Repository-Informationen konnten nicht abgerufen werden. Details: '%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Repository konnte nicht hinzugefügt werden. Details: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Repository konnte nicht entfernt werden. Details: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "FEHLERCODE"
-
-msgid "REASON"
-msgstr "GRUND"
-
-msgid "STACK"
-msgstr "STACK"
-
-msgid "Go to Homepage"
-msgstr "Gehe zu Homepage"
-
-msgid "Create a New Virtual Machine"
-msgstr "Neue virtuelle Maschine erstellen"
-
-msgid "Virtual Machine Name"
-msgstr "Name der virtuellen Maschine"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"Der für die Kennzeichnung der virtuellen Maschine verwendete Name. Falls er "
-"ausgelassen wird, wird ein Name anhand der verwendeten Vorlage ausgewählt."
-
-msgid "Template"
-msgstr "Vorlage"
-
-msgid "Please create a template first."
-msgstr "Erstellen Sie zunächst eine Vorlage."
-
-msgid "Create a Template"
-msgstr "Vorlage erstellen"
-
-msgid "Please choose a template."
-msgstr "Wählen Sie eine Vorlage aus."
-
-msgid "OS"
-msgstr "BS"
-
-msgid "OS Version"
-msgstr "BS-Version"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Speicher"
-
-msgid "Create"
-msgstr "Erstellen"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "Abbrechen"
-
-msgid "Edit Guest"
-msgstr "Gast bearbeiten"
-
-msgid "General"
-msgstr "Allgemein"
-
-msgid "Storage"
-msgstr "Speicher"
-
-msgid "Interface"
-msgstr "Schnittstelle"
-
-msgid "Permission"
-msgstr "Version"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Name"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "Speicher"
-
-msgid "Icon"
-msgstr "Symbol"
-
-msgid "Device"
-msgstr "Einheitenname"
-
-msgid "Path"
-msgstr "NFS-Pfad"
-
-msgid "Network"
-msgstr "Netz"
-
-msgid "Type"
-msgstr "Typ"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Alle"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "Anbieter"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Speichern"
-
-msgid "Replace"
-msgstr "Ersetzen"
-
-msgid "Detach"
-msgstr "Abhängen"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "Starten"
-
-msgid "Reset"
-msgstr "Zurücksetzen"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "Aktionen"
-
-msgid "Connect"
-msgstr "Verbinden"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "Bearbeiten"
-
-msgid "Shut Down"
-msgstr "Herunterfahren"
-
-msgid "Delete"
-msgstr "Löschen"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "Platten-E/A"
-
-msgid "Network I/O"
-msgstr "Netz-E/A"
-
-msgid "Livetile"
-msgstr "Live Tile"
-
-msgid "No guests found."
-msgstr "Keine Gäste gefunden."
-
-msgid "Add a Storage Device to VM"
-msgstr "Speichereinheit zur virtuellen Maschine hinzufügen"
-
-msgid "Device Type"
-msgstr "Einheitentyp"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "Der Einheitentyp. Derzeit wird nur \"cdrom\" unterstützt."
-
-msgid "Storage Pool"
-msgstr "Speicherpool"
-
-msgid "Storage pool which volume located in"
-msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
-
-msgid "Storage Volume"
-msgstr "Speicherpoolname"
-
-msgid "Storage volume to be attached"
-msgstr "Name des Speicherdatenträgers muss eine Zeichenfolge sein"
-
-msgid "File Path"
-msgstr "Dateipfad"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "Der ISO-Dateipfad auf dem Server für die CD-ROM."
-
-msgid "Attach"
-msgstr "Anhängen"
-
-msgid "Shut down"
-msgstr "Herunterfahren"
-
-msgid "Restart"
-msgstr "Erneut starten"
-
-msgid "Basic Information"
-msgstr "Basisinformationen"
-
-msgid "OS Distro"
-msgstr "BS-Distro"
-
-msgid "OS Code Name"
-msgstr "BS-Codename"
-
-msgid "Processor"
-msgstr "Prozessor"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "Systemstatistik"
-
-msgid "Software Updates"
-msgstr "Software-Updates"
-
-msgid "Update Progress"
-msgstr "Aktualisierungsfortschritt"
-
-msgid "Repositories"
-msgstr "Repositorys"
-
-msgid "Debug Reports"
-msgstr "Debugberichte"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"Der Benutzername oder das Kennwort, den bzw. das Sie eingegeben haben, ist "
-"falsch. Versuchen Sie es bitte erneut."
-
-msgid "This field is required."
-msgstr "Dieses Feld ist erforderlich."
-
-msgid "Log in"
-msgstr "Anmelden"
-
-msgid "Logging in..."
-msgstr "Wird angemeldet..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "Gäste"
-
-msgid "Templates"
-msgstr "Vorlagen"
-
-msgid "Failed to get application configuration"
-msgstr "Anwendungskonfiguration konnte nicht abgerufen werden"
-
-msgid "This is not a valid Linux path"
-msgstr "Dies ist kein gültiger Linux-Pfad"
-
-msgid "This is not a valid URL."
-msgstr "Dies ist kein gültiger URL."
-
-msgid "No such data available."
-msgstr "Keine solchen Daten verfügbar."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"Hostsystem kann nicht kontaktiert werden. Prüfen Sie, ob das Hostsystem "
-"aktiv ist und obNetzkonnektivität besteht. HTTP-Anforderungsantwort %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Löschbestätigung"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Bestätigen"
-
-msgid "Warning"
-msgstr "Warnung"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Wird geladen..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Wiederholen"
-
-msgid "Detailed message:"
-msgstr "Detaillierte Meldung:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "Dies ist keine gültige ISO-Datei."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Dies wird einige Zeit dauern. Möchten Sie fortfahren?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "Hiermit wird die Vorlage dauerhaft gelöscht. Möchten Sie fortfahren?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"System konnte nicht heruntergefahren werden, weil einige virtuellen "
-"Maschinen ausgeführt werden!"
-
-msgid "Max:"
-msgstr "Max:"
-
-msgid "Utilization"
-msgstr "Auslastung"
-
-msgid "Available"
-msgstr "Verfügbar"
-
-msgid "Read Rate"
-msgstr "Leserate"
-
-msgid "Write Rate"
-msgstr "Schreibrate"
-
-msgid "Received"
-msgstr "Empfangen"
-
-msgid "Sent"
-msgstr "Gesendet"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"Durch das Herunterfahren oder Neustarten des Hosts können ungesicherte "
-"Arbeiten verloren gehen. Möchten Sie mit dem Herunterfahren/Neustarten "
-"fortfahren?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Repository wird dauerhaft entfernt und kann nicht wiederhergestellt werden. "
-"Möchten Sie fortfahren?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "Basis-URL"
-
-msgid "Is Mirror"
-msgstr "Ist Spiegel"
-
-msgid "URL Args"
-msgstr "URL-Args"
-
-msgid "Enabled"
-msgstr "Aktiviert"
-
-msgid "GPG Check"
-msgstr "GPG-Prüfung"
-
-msgid "GPG Key"
-msgstr "GPG-Schlüssel"
-
-msgid "Add"
-msgstr "Hinzufügen"
-
-msgid "Remove"
-msgstr "Entfernen"
-
-msgid "Enable"
-msgstr "Aktivieren"
-
-msgid "Disable"
-msgstr "Inaktivieren"
-
-msgid "Package Name"
-msgstr "Paketname"
-
-msgid "Version"
-msgstr "Version"
-
-msgid "Architecture"
-msgstr "Architektur"
-
-msgid "Repository"
-msgstr "Repository"
-
-msgid "Update All"
-msgstr "Alle aktualisieren"
-
-msgid "Updating..."
-msgstr "Wird aktualisiert..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "Pakete konnten nicht aktualisiert werden."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Debugbericht wird dauerhaft entfernt und kann nicht wiederhergestellt "
-"werden. Möchten Sie fortfahren?"
-
-msgid "Generated Time"
-msgstr "Generierte Zeit"
-
-msgid "Generate"
-msgstr "Generieren"
-
-msgid "Generating..."
-msgstr "Wird generiert..."
-
-msgid "Rename"
-msgstr "Umbenennen"
-
-msgid "Download"
-msgstr "Herunterladen"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr ""
-"Berichtsname darf nur Buchstaben, Zahlen und/oder Bindestriche ('-') "
-"enthalten."
-
-msgid "Pending..."
-msgstr "Wird geladen..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"Hiermit werden die virtuelle Maschine und deren virtuellen Platten gelöscht. "
-"Diese Operation kann nicht rückgängig gemacht werden. Möchten Sie fortfahren?"
-
-msgid "Power off Confirmation"
-msgstr "Löschbestätigung"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "Löschbestätigung"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "Löschbestätigung"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "Hiermit wird die Vorlage dauerhaft gelöscht. Möchten Sie fortfahren?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Diese CD-ROM wird dauerhaft abgehängt und Sie können sie neu anhängen. "
-"Möchten Sie mit dem Abhängen fortfahren?"
-
-msgid "Attaching..."
-msgstr "Wird angehängt..."
-
-msgid "Replacing..."
-msgstr "Wird ersetzt..."
-
-msgid "Successfully attached!"
-msgstr "Erfolgreich angehängt!"
-
-msgid "Successfully replaced!"
-msgstr "Erfolgreich ersetzt!"
-
-msgid "Successfully detached!"
-msgstr "Erfolgreich abgehängt!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "Die VLAN-ID muss zwischen 1 und 4094 liegen."
-
-msgid "unavailable"
-msgstr "nicht verfügbar"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"Diese Aktion unterbricht die Netzkonnektivität für jede virtuelle Maschine, "
-"die von diesem Netz abhängt."
-
-msgid "Create a network"
-msgstr "Netz erstellen"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
-"inaktiviert, sondern permanent gelöscht. Möchten Sie fortfahren?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-"Hiermit wird der Speicherpool dauerhaft gelöscht. Möchten Sie fortfahren?"
-
-msgid "This storage pool is empty."
-msgstr "Dieser Speicherpool ist leer."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Hiermit wird Ihre Platte formatiert und Sie verlieren sämtliche Daten "
-"darauf. Sind Sie sicher, dass Sie fortfahren möchten? "
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI-Fibre Channel"
-
-msgid "No SCSI adapters found."
-msgstr "Keine SCSI-Adapter gefunden."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "Der Speicherpoolname darf nicht leer sein."
-
-msgid "The storage pool path can not be blank."
-msgstr "Der Speicherpoolpfad darf nicht leer sein."
-
-msgid "NFS server mount path can not be blank."
-msgstr "Der Mountpfad des NFS-Servers darf nicht leer sein."
-
-msgid "Invalid NFS mount path."
-msgstr "Ungültiger NFS-Mountpfad."
-
-msgid "No logical device selected."
-msgstr "Keine logische Einheit ausgewählt."
-
-msgid "The iSCSI target can not be blank."
-msgstr "Das iSCSI-Ziel darf nicht leer sein."
-
-msgid "Server name can not be blank."
-msgstr "Servername darf nicht leer sein."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "Es wird nach verfügbaren Partitionen gesucht..."
-
-msgid "No available partitions found."
-msgstr "Keine gültigen Partitionen gefunden."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
-"inaktiviert, sondern permanent gelöscht. Möchten Sie fortfahren?"
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-"Repository-Informationen konnten nicht abgerufen werden. Details: '%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Der Speicherpoolname darf nicht leer sein."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "Netzname"
-
-msgid "State"
-msgstr "Status"
-
-msgid "Network Type"
-msgstr "Netztyp"
-
-msgid "Address Space"
-msgstr "Adressraum"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "Ungültiger Speicherpoolname. Er darf nicht '/' enthalten."
-
-msgid "Isolated: no external network connection"
-msgstr "Isolatiert: keine physisische Netzverbindung"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: nur ausgehende physische Netzverbindung"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Ãberbrückt: Virtuelle Maschinen sind direkt mit physischem Netz verbunden"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "Ziel:"
-
-msgid "Enable VLAN"
-msgstr "Virtuelles LAN (VLAN) aktivieren:"
-
-msgid "VLAN ID"
-msgstr "VLAN-ID:"
-
-msgid "Stop"
-msgstr "Stoppen"
-
-msgid "Generate a New Debug Report"
-msgstr "Neuen Debugbericht erstellen"
-
-msgid "Report Name"
-msgstr "Berichtsname"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
-"wird, wird ein Name basierend auf der aktuellen Zeit ausgewählt. Der Name "
-"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
-
-msgid "Rename a Debug Report"
-msgstr "Neuen Debugbericht erstellen"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
-"wird, wird ein Name basierend auf der aktuellen Zeit ausgewählt. Der Name "
-"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "Repository hinzufügen"
-
-msgid "Identifier"
-msgstr "Kennung"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Einzelnes Wort, eindeutige Kennung für das Repository."
-
-msgid "Textual name for the repository."
-msgstr "Textname für das Repository."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Erforderliches Feld"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL zum Repository. Unterstützte Protokolle sind http, ftp und file."
-
-msgid "Repository is a mirror"
-msgstr "Repository ist ein Spiegel."
-
-msgid "Distribution"
-msgstr "Verteilung"
-
-msgid "Distribution of the DEB repository."
-msgstr "Verteilung des DEB-Repositorys."
-
-msgid "Components"
-msgstr "Komponenten"
-
-msgid "List of components in DEB repository."
-msgstr "Liste der Komponenten im DEB-Repository."
-
-msgid "Edit Repository"
-msgstr "Repository bearbeiten"
-
-msgid "Mirror List URL"
-msgstr "Spiegellisten-URL"
-
-msgid "Yes"
-msgstr "Ja"
-
-msgid "No"
-msgstr "Nein"
-
-msgid "Capacity"
-msgstr "Kapazität"
-
-msgid "Allocated"
-msgstr "Zugeordnet"
-
-msgid "Location"
-msgstr "Position"
-
-msgid "Device path"
-msgstr "Einheitenpfad"
-
-msgid "active"
-msgstr "aktiv"
-
-msgid "inactive"
-msgstr "inaktiv"
-
-msgid "Deactivate"
-msgstr "Inaktivieren"
-
-msgid "Activate"
-msgstr "Aktivieren"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "Definition aufheben"
-
-msgid "Format"
-msgstr "Format:"
-
-msgid "Allocation"
-msgstr "Zuordnung:"
-
-msgid "Define a New Storage Pool"
-msgstr "Neuen Speicherpool definieren"
-
-msgid "Storage Pool Name"
-msgstr "Speicherpoolname"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"Der Name, mit dem die Speicherpools gekennzeichnet werden. Er darf nicht "
-"leer sein."
-
-msgid "Storage Pool Type"
-msgstr "Speicherpooltyp"
-
-msgid "Storage Path"
-msgstr "Speicherpfad"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"Der Pfad des Speicherpools. Jeder Speicherpool muss einen eindeutigen Pfad "
-"haben."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"Kimchi versucht, das Verzeichnis zu erstellen, wenn es noch nicht in Ihrem "
-"System vorhanden ist."
-
-msgid "NFS Server IP"
-msgstr "NFS-Server-IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP oder Hostname des NFS-Servers. Diese(r) kann eingegeben oder aus dem "
-"Verlauf ausgewählt werden."
-
-msgid "NFS Path"
-msgstr "NFS-Pfad"
-
-msgid "The NFS exported path on NFS server."
-msgstr "Der NFS-Exportpfad auf dem NFS-Server."
-
-msgid "iSCSI Server"
-msgstr "iSCSI-Server"
-
-msgid "Server"
-msgstr "Server"
-
-msgid "Port"
-msgstr "Port"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP oder Hostname des iSCSI-Servers. Diese(r) darf nicht leer sein."
-
-msgid "Target"
-msgstr "Ziel"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "Das iSCSI-Ziel auf dem iSCSI-Server"
-
-msgid "Add iSCSI Authentication"
-msgstr "iSCSI-Authentifizierung hinzufügen"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI-Authentifizierung"
-
-msgid "User Name"
-msgstr "Benutzername"
-
-msgid "Password"
-msgstr "Kennwort"
-
-msgid "SCSI Adapter"
-msgstr "SCSI-Adapter"
-
-msgid "Please, wait..."
-msgstr "Bitte warten..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "Vorlage hinzufügen"
-
-msgid "Where is the source media for this template? "
-msgstr "Wo ist der Quellendatenträger für diese Vorlage?"
-
-msgid "Local ISO Image"
-msgstr "Lokales ISO-Image"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "Fernes ISO-Image"
-
-msgid "Search ISOs"
-msgstr "ISOs suchen"
-
-msgid "The following ISOs are available:"
-msgstr "Die folgenden ISOs sind verfügbar:"
-
-msgid "OS: "
-msgstr "BS: "
-
-msgid "Version: "
-msgstr "Version: "
-
-msgid "Size: "
-msgstr "GröÃe: "
-
-msgid "Search more ISOs"
-msgstr "Weitere ISOs suchen"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Vorlagen aus ausgewähltem ISO erstellen"
-
-msgid "I want to use a specific ISO file"
-msgstr "Ich möchte eine bestimmte ISO-Datei verwenden"
-
-msgid "Loading default remote ISOs ..."
-msgstr "StandardmäÃige ferne ISOs werden geladen ..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Ich möchte einen benutzerdefinierten URL verwenden"
-
-msgid "Edit Template"
-msgstr "Vorlage bearbeiten"
-
-msgid "CDROM"
-msgstr "CD-ROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "Grafik"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU-Anzahl"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "Keine Vorlagen gefunden."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "Löschen ist nicht zulässig für %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s implementiert keine Aktualisierungsmethode"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Erstellen ist nicht zulässig für %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "JSON-Anfrage konnte nicht analysiert werden"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Diese API unterstützt nur JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Datenspeicher wird nicht im Modellobjekt initialisiert."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr ""
-#~ "Task kann aufgrund des folgenden Fehlers nicht gestartet werden: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr ""
-#~ "Authentifizierung für Benutzer '%(username)s' fehlgeschlagen. "
-#~ "[Fehlercode: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Sie sind nicht berechtigt, auf Kimchi zuzugreifen"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Geben Sie %(item)s an, um sich bei Kimchi anzumelden"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "%(item)s konnten nicht im Datenspeicher gefunden werden"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr ""
-#~ "Zeitlimitüberschreitung beim Ausführen des Befehls '%(cmd)s' nach %"
-#~ "(seconds)s Sekunden"
-
-#~ msgid "Help"
-#~ msgstr "Hilfe"
-
-#~ msgid "About"
-#~ msgstr "Informationen"
-
-#~ msgid "Log out"
-#~ msgstr "Abmelden"
-
-#~ msgid "Version:"
-#~ msgstr "Version:"
diff --git a/plugins/kimchi/po/en_US.po b/plugins/kimchi/po/en_US.po
deleted file mode 100644
index a5d0d44..0000000
--- a/plugins/kimchi/po/en_US.po
+++ /dev/null
@@ -1,2075 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-# Adam Litke <agl at us.ibm.com>, 2013.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: en_US\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-
-msgid "Remote ISO image is not supported by this server."
-msgstr ""
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-
-msgid "Specify a template to create a virtual machine from"
-msgstr ""
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr ""
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr ""
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr ""
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-
-msgid "Template name must be a string"
-msgstr ""
-
-msgid "Template icon must be a path to the image"
-msgstr ""
-
-msgid "Template distribution must be a string"
-msgstr ""
-
-msgid "Template distribution version must be a string"
-msgstr ""
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr ""
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr ""
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-
-msgid "All networks for the template must be specified in a list."
-msgstr ""
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr ""
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr ""
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr ""
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr ""
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr ""
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr ""
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr ""
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr ""
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-
-msgid "The SCSI host adapter name must be a string."
-msgstr ""
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-
-msgid "Storage volume name must be a string"
-msgstr ""
-
-msgid "Storage volume allocation must be an integer number"
-msgstr ""
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr ""
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-
-msgid "Network interface must be a string"
-msgstr ""
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr ""
-
-msgid "Specify name and type to create a Network"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr ""
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr ""
-
-msgid "Debug report tool not found in system"
-msgstr ""
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr ""
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr ""
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr ""
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr ""
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr ""
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr ""
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-
-msgid "There is no compatible package manager for this system."
-msgstr ""
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr ""
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr ""
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr ""
-
-msgid "Components to DEB repository must be a string"
-msgstr ""
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr ""
-
-msgid "GPG check must be a boolean value."
-msgstr ""
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr ""
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr ""
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr ""
-
-msgid "YUM Repository ID already exists"
-msgstr ""
-
-msgid "YUM Repository name must be a string"
-msgstr ""
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr ""
-
-msgid "REASON"
-msgstr ""
-
-msgid "STACK"
-msgstr ""
-
-msgid "Go to Homepage"
-msgstr ""
-
-msgid "Create a New Virtual Machine"
-msgstr ""
-
-msgid "Virtual Machine Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-
-msgid "Template"
-msgstr ""
-
-msgid "Please create a template first."
-msgstr ""
-
-msgid "Create a Template"
-msgstr ""
-
-msgid "Please choose a template."
-msgstr ""
-
-msgid "OS"
-msgstr ""
-
-msgid "OS Version"
-msgstr ""
-
-msgid "CPUS"
-msgstr ""
-
-msgid "Memory"
-msgstr ""
-
-msgid "Create"
-msgstr ""
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr ""
-
-msgid "Edit Guest"
-msgstr ""
-
-msgid "General"
-msgstr ""
-
-msgid "Storage"
-msgstr ""
-
-msgid "Interface"
-msgstr ""
-
-msgid "Permission"
-msgstr ""
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr ""
-
-msgid "CPUs"
-msgstr ""
-
-msgid "Memory (MB)"
-msgstr ""
-
-msgid "Icon"
-msgstr ""
-
-msgid "Device"
-msgstr ""
-
-msgid "Path"
-msgstr ""
-
-msgid "Network"
-msgstr ""
-
-msgid "Type"
-msgstr ""
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr ""
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr ""
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr ""
-
-msgid "Replace"
-msgstr ""
-
-msgid "Detach"
-msgstr ""
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr ""
-
-msgid "Reset"
-msgstr ""
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr ""
-
-msgid "Connect"
-msgstr ""
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr ""
-
-msgid "Shut Down"
-msgstr ""
-
-msgid "Delete"
-msgstr ""
-
-msgid "CPU"
-msgstr ""
-
-msgid "Disk I/O"
-msgstr ""
-
-msgid "Network I/O"
-msgstr ""
-
-msgid "Livetile"
-msgstr ""
-
-msgid "No guests found."
-msgstr ""
-
-msgid "Add a Storage Device to VM"
-msgstr ""
-
-msgid "Device Type"
-msgstr ""
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr ""
-
-msgid "Storage Pool"
-msgstr ""
-
-msgid "Storage pool which volume located in"
-msgstr ""
-
-msgid "Storage Volume"
-msgstr ""
-
-msgid "Storage volume to be attached"
-msgstr ""
-
-msgid "File Path"
-msgstr ""
-
-msgid "The ISO file path in the server for CDROM."
-msgstr ""
-
-msgid "Attach"
-msgstr ""
-
-msgid "Shut down"
-msgstr ""
-
-msgid "Restart"
-msgstr ""
-
-msgid "Basic Information"
-msgstr ""
-
-msgid "OS Distro"
-msgstr ""
-
-msgid "OS Code Name"
-msgstr ""
-
-msgid "Processor"
-msgstr ""
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr ""
-
-msgid "Software Updates"
-msgstr ""
-
-msgid "Update Progress"
-msgstr ""
-
-msgid "Repositories"
-msgstr ""
-
-msgid "Debug Reports"
-msgstr ""
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-
-msgid "This field is required."
-msgstr ""
-
-msgid "Log in"
-msgstr ""
-
-msgid "Logging in..."
-msgstr ""
-
-msgid "Host"
-msgstr ""
-
-msgid "Guests"
-msgstr ""
-
-msgid "Templates"
-msgstr ""
-
-msgid "Failed to get application configuration"
-msgstr ""
-
-msgid "This is not a valid Linux path"
-msgstr ""
-
-msgid "This is not a valid URL."
-msgstr ""
-
-msgid "No such data available."
-msgstr ""
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr ""
-
-msgid "OK"
-msgstr ""
-
-msgid "Confirm"
-msgstr ""
-
-msgid "Warning"
-msgstr ""
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr ""
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr ""
-
-msgid "Detailed message:"
-msgstr ""
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr ""
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr ""
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-
-msgid "Max:"
-msgstr ""
-
-msgid "Utilization"
-msgstr ""
-
-msgid "Available"
-msgstr ""
-
-msgid "Read Rate"
-msgstr ""
-
-msgid "Write Rate"
-msgstr ""
-
-msgid "Received"
-msgstr ""
-
-msgid "Sent"
-msgstr ""
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-
-msgid "ID"
-msgstr ""
-
-msgid "Base URL"
-msgstr ""
-
-msgid "Is Mirror"
-msgstr ""
-
-msgid "URL Args"
-msgstr ""
-
-msgid "Enabled"
-msgstr ""
-
-msgid "GPG Check"
-msgstr ""
-
-msgid "GPG Key"
-msgstr ""
-
-msgid "Add"
-msgstr ""
-
-msgid "Remove"
-msgstr ""
-
-msgid "Enable"
-msgstr ""
-
-msgid "Disable"
-msgstr ""
-
-msgid "Package Name"
-msgstr ""
-
-msgid "Version"
-msgstr ""
-
-msgid "Architecture"
-msgstr ""
-
-msgid "Repository"
-msgstr ""
-
-msgid "Update All"
-msgstr ""
-
-msgid "Updating..."
-msgstr ""
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr ""
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-
-msgid "Generated Time"
-msgstr ""
-
-msgid "Generate"
-msgstr ""
-
-msgid "Generating..."
-msgstr ""
-
-msgid "Rename"
-msgstr ""
-
-msgid "Download"
-msgstr ""
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr ""
-
-msgid "Pending..."
-msgstr ""
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-
-msgid "Power off Confirmation"
-msgstr ""
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr ""
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr ""
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-
-msgid "Attaching..."
-msgstr ""
-
-msgid "Replacing..."
-msgstr ""
-
-msgid "Successfully attached!"
-msgstr ""
-
-msgid "Successfully replaced!"
-msgstr ""
-
-msgid "Successfully detached!"
-msgstr ""
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr ""
-
-msgid "unavailable"
-msgstr ""
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-
-msgid "Create a network"
-msgstr ""
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-
-msgid "This storage pool is empty."
-msgstr ""
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-
-msgid "SCSI Fibre Channel"
-msgstr ""
-
-msgid "No SCSI adapters found."
-msgstr ""
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr ""
-
-msgid "The storage pool path can not be blank."
-msgstr ""
-
-msgid "NFS server mount path can not be blank."
-msgstr ""
-
-msgid "Invalid NFS mount path."
-msgstr ""
-
-msgid "No logical device selected."
-msgstr ""
-
-msgid "The iSCSI target can not be blank."
-msgstr ""
-
-msgid "Server name can not be blank."
-msgstr ""
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr ""
-
-msgid "No available partitions found."
-msgstr ""
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr ""
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr ""
-
-msgid "State"
-msgstr ""
-
-msgid "Network Type"
-msgstr ""
-
-msgid "Address Space"
-msgstr ""
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-
-msgid "Isolated: no external network connection"
-msgstr ""
-
-msgid "NAT: outbound physical network connection only"
-msgstr ""
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr ""
-
-msgid "Enable VLAN"
-msgstr ""
-
-msgid "VLAN ID"
-msgstr ""
-
-msgid "Stop"
-msgstr ""
-
-msgid "Generate a New Debug Report"
-msgstr ""
-
-msgid "Report Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-
-msgid "Rename a Debug Report"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr ""
-
-msgid "Identifier"
-msgstr ""
-
-msgid "Single word, unique identifier for the repository."
-msgstr ""
-
-msgid "Textual name for the repository."
-msgstr ""
-
-msgid "URL"
-msgstr ""
-
-msgid "Required Field"
-msgstr ""
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr ""
-
-msgid "Repository is a mirror"
-msgstr ""
-
-msgid "Distribution"
-msgstr ""
-
-msgid "Distribution of the DEB repository."
-msgstr ""
-
-msgid "Components"
-msgstr ""
-
-msgid "List of components in DEB repository."
-msgstr ""
-
-msgid "Edit Repository"
-msgstr ""
-
-msgid "Mirror List URL"
-msgstr ""
-
-msgid "Yes"
-msgstr ""
-
-msgid "No"
-msgstr ""
-
-msgid "Capacity"
-msgstr ""
-
-msgid "Allocated"
-msgstr ""
-
-msgid "Location"
-msgstr ""
-
-msgid "Device path"
-msgstr ""
-
-msgid "active"
-msgstr ""
-
-msgid "inactive"
-msgstr ""
-
-msgid "Deactivate"
-msgstr ""
-
-msgid "Activate"
-msgstr ""
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr ""
-
-msgid "Format"
-msgstr ""
-
-msgid "Allocation"
-msgstr ""
-
-msgid "Define a New Storage Pool"
-msgstr ""
-
-msgid "Storage Pool Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-
-msgid "Storage Pool Type"
-msgstr ""
-
-msgid "Storage Path"
-msgstr ""
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-
-msgid "NFS Server IP"
-msgstr ""
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-
-msgid "NFS Path"
-msgstr ""
-
-msgid "The NFS exported path on NFS server."
-msgstr ""
-
-msgid "iSCSI Server"
-msgstr ""
-
-msgid "Server"
-msgstr ""
-
-msgid "Port"
-msgstr ""
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr ""
-
-msgid "Target"
-msgstr ""
-
-msgid "The iSCSI target on iSCSI server"
-msgstr ""
-
-msgid "Add iSCSI Authentication"
-msgstr ""
-
-msgid "iSCSI Authentication"
-msgstr ""
-
-msgid "User Name"
-msgstr ""
-
-msgid "Password"
-msgstr ""
-
-msgid "SCSI Adapter"
-msgstr ""
-
-msgid "Please, wait..."
-msgstr ""
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr ""
-
-msgid "Where is the source media for this template? "
-msgstr ""
-
-msgid "Local ISO Image"
-msgstr ""
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr ""
-
-msgid "Search ISOs"
-msgstr ""
-
-msgid "The following ISOs are available:"
-msgstr ""
-
-msgid "OS: "
-msgstr ""
-
-msgid "Version: "
-msgstr ""
-
-msgid "Size: "
-msgstr ""
-
-msgid "Search more ISOs"
-msgstr ""
-
-msgid "Create Templates from Selected ISO"
-msgstr ""
-
-msgid "I want to use a specific ISO file"
-msgstr ""
-
-msgid "Loading default remote ISOs ..."
-msgstr ""
-
-msgid "Arch: "
-msgstr ""
-
-msgid "I want to use a custom URL"
-msgstr ""
-
-msgid "Edit Template"
-msgstr ""
-
-msgid "CDROM"
-msgstr ""
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr ""
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr ""
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr ""
diff --git a/plugins/kimchi/po/es_ES.po b/plugins/kimchi/po/es_ES.po
deleted file mode 100644
index d71e621..0000000
--- a/plugins/kimchi/po/es_ES.po
+++ /dev/null
@@ -1,2305 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: es_ES\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-"Se ha producido un error al obtener dispositivos de bloque. Detalles: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"Se ha producido un error al obtener información de dispositivo de bloque "
-"para %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "No se puede encontrar el archivo distro: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"No se puede analizar el archivo distro: %(filename)s. Asegúrese de que es un "
-"archivo JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"No se puede iniciar la sesión en %(portal)s del destino de host iSCSI. "
-"Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr ""
-"No se puede iniciar la sesión en el destino %(target)s del %(host)s host de "
-"iSCSI"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "El archivo ISO %(filename)s no es arrancable"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"El archivo ISO %(filename)s no tiene un registro de arranque de El Torito "
-"válido"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Entrada de validación de El Torito no válida en ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicador de arranque de El Torito no válido en ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Tipo de volumen inesperado para el volumen primario en ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Formato incorrecto mientras se leÃa el descriptor de volumen en ISO %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"El hipervisor no tiene permiso para utilizar este ISO %(filename)s. "
-"Considere moverlo a /var/lib/libvirt, o establezca el permiso de búsqueda en "
-"listas de control de accesos de archivo para el usuario '%(user)s' si es "
-"posible, o añada el '%(user)s' al grupo de vÃas de acceso ISO, o (no "
-"recomendado) 'chmod -R o+x 'path_to_iso'.Detalles: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "La máquina virtual %(name)s ya existe"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "La máquina virtual %(name)s no existe"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"No se puede recuperar la captura de pantalla para la máquina virtual "
-"detenida %(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "La imagen ISO remota no está soportada por este servidor."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede crear la máquina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede crear la máquina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede recuperar la máquina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"La dirección de gráficos en que hay que estar a la escucha debe ser IPv4 o "
-"IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr ""
-"Especifique una plantilla a partir de la que se creará una máquina virtual"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede iniciar la máquina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede detener la máquina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede suprimir la máquina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede redenominar la máquina virtual %(name)s. Detalles: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "El nombre de red debe ser una serie"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "El nombre de red debe ser una serie"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "El usuario '%(users)s' no existe."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "El usuario '%(groups)s' no existe."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede detener la máquina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede iniciar la máquina virtual %(name)s. Detalles: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "La interfaz %(iface)s no existe en la máquina virtual %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"La red %(network)s especificada para la máquina virtual %(name)s no existe"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "El tipo de interfaces de máquina virtual soportado es de red solamente"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"El nombre de red para la interfaz de máquina virtual debe ser una serie"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Especificada tarjeta de modelo de red no válida para la interfaz de máquina "
-"virtual"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Especifique el tipo y la red para añadir una interfaz de máquina virtual "
-"nueva"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "La plantilla %(name)s ya existe"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr ""
-"La red '%(network)s' especificada para la plantilla %(template)s no existe"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"La agrupación de almacenamiento %(pool)s especificada para la plantilla %"
-"(template)s no existe"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-"La agrupación de almacenamiento %(pool)s especificada para la plantilla %"
-"(template)s no está activa"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Parámetro no válido '%(param)s' especificado para CDROM."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"La red %(network)s especificada para la plantilla %(template)s no está activa"
-
-msgid "Template name must be a string"
-msgstr "El nombre de plantilla debe ser una serie"
-
-msgid "Template icon must be a path to the image"
-msgstr "El icono de plantilla debe ser una vÃa de acceso a la imagen"
-
-msgid "Template distribution must be a string"
-msgstr "La distribución de plantilla debe ser una serie"
-
-msgid "Template distribution version must be a string"
-msgstr "La versión de distribución de plantilla debe ser una serie"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "El número de CPUs debe ser un entero"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "La cantidad de memoria (MB) debe ser un entero mayor que 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-"URI de agrupación de almacenamiento no válido %(value)s especificado para la "
-"plantilla"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "Especifique una imagen de ISO como CDROM para crear una plantilla"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Todas las redes para la plantilla deben especificarse en una lista."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "No se puede crear la plantilla debido a un error: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "No se puede suprimir la plantilla debido a un error: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "La agrupación de almacenamiento %(name)s ya existe"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "La agrupación de almacenamiento %(name)s no existe"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-"Especifique %(item)s para poder crear la agrupación de almacenamiento %(name)"
-"s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "No se puede suprimir la agrupación de almacenamiento activa %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "No se pueden listar agrupaciones de almacenamiento. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede crear la agrupación de almacenamiento %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"No se puede obtener el número de volúmenes de almacenamiento en la "
-"agrupación de almacenamiento %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede activar la agrupación de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede desactivar la agrupación de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede suprimir la agrupación de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"No se puede crear la agrupación de NFS ya que la vÃa de acceso de "
-"exportación %(path)s podrÃa bloquearse durante el montaje"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"No se puede crear la agrupación de NFS ya que el montaje de la vÃa de acceso "
-"de exportación %(path)s ha fallado"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Tipo de agrupación de almacenamiento no soportado: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "La vÃa de acceso de la agrupación de almacenamiento debe ser una serie"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr ""
-"El host de la agrupación de almacenamiento debe ser un IP o nombre de host"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr ""
-"El parámetro de los dispositivos de agrupación de almacenamiento debe ser "
-"una lista"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "El IQN destino de una agrupación de iSCSI debe ser una serie"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"El puerto de un servidor de almacenamiento remoto debe ser un entero entre 1 "
-"y 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr ""
-"Especifique el nombre y el tipo para crear una agrupación de almacenamiento"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s no es un disco/partición. No se ha podido añadir a la agrupación %"
-"(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Los discos de parámetro sólo pueden actualizarse para la agrupación de "
-"almacenamiento lógico."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "El nombre del adaptador de host SCSI debe ser una serie."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr ""
-"La agrupación de almacenamiento kimchi_isos está reservada para uso interno"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"No se puede activar la agrupación de almacenamiento NFS %(name)s. El "
-"servidor NFS %(server)s está fuera de alcance."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"No se puede desactivar la agrupación de almacenamiento NFS %(name)s. El "
-"servidor NFS %(server)s está fuera de alcance."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"No se puede desactivar la agrupación %(name)s ya que está asociada con "
-"algunas plantillas"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"No se puede suprimir la agrupación %(name)s ya que está asociada con algunas "
-"plantillas"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"Un grupo de volúmenes denominado '%(name)s' ya existe. Elija otro nombre "
-"para crear la agrupación lógica."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"No se puede actualizar la base de datos con la información de exploración "
-"profunda debido a un error: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "El volumen de almacenamiento %(name)s ya existe"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"El volumen de almacenamiento %(name)s no existe en la agrupación de "
-"almacenamiento %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-"Especifique %(item)s para poder crear el volumen de almacenamiento %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"No se pueden listar los volúmenes de almacenamiento porque la agrupación de "
-"almacenamiento %(pool)s no está activa"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"No se puede crear el volumen de almacenamiento %(name)s en la agrupación de "
-"almacenamiento %(pool)s. Detalles: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"No se pueden listar volúmenes de almacenamiento en la agrupación de "
-"almacenamiento %(pool)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-"No se pueden borrar los volúmenes de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede suprimir el volumen de almacenamiento %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede redimensionar el volumen de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"El tipo de almacenamiento %(type)s no da soporte a crear y suprimir volúmenes"
-
-msgid "Storage volume name must be a string"
-msgstr "El nombre de volumen de almacenamiento debe ser una serie"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "La asignación de volumen de almacenamiento debe ser un número entero"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "El volumen de almacenamiento requiere un nombre de volumen"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"No se puede actualizar la base de datos con la información de volumen de "
-"almacenamiento debido a un error: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "La interfaz %(name)s no existe"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "La red %(name)s ya existe"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "La red %(name)s no existe"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"La subred %(subnet)s especificada para la red %(network)s no es válida."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "Especifique una interfaz de red para crear una red puenteada %(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "No se puede suprimir la red activa %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-"La interfaz %(iface)s especificada para la red %(network)s ya está en uso"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "La interfaz debe ser dispositivo de puente, enlazado o NIC simple."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "No se puede crear la red %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "No se puede encontrar una dirección IP libre para la red '%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "La interfaz %(iface)s ya existe"
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Los tipos de red soportados son aislada, NAT y puente"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"La subred de red debe ser una serie con dirección IP y prefijo o máscara de "
-"red"
-
-msgid "Network interface must be a string"
-msgstr "La interfaz de red debe ser una serie"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "El ID de VLAN de red debe ser un entero entre 1 y 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Especifique el nombre y el tipo para crear una red"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"No se puede suprimir la red %(name)s. Hay algunas máquinas virtuales %(vms)s "
-"y/o plantillas enlazadas a esta red."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"No se puede desactivar la red %(name)s. Hay algunas máquinas virtuales %(vms)"
-"s y/o plantillas enlazadas a esta red."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"El dispositivo de puente %(name)s no puede ser el dispositivo de conexión "
-"troncal de una VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "No se puede activar la interfaz %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"No se puede activar la interfaz %(iface)s. Compruebe el estado del enlace "
-"fÃsico."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "El informe de depuración %(name)s no existe"
-
-msgid "Debug report tool not found in system"
-msgstr "Herramienta de informes de depuración no encontrada en el sistema"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-"No se puede crear el informe de depuración %(name)s. Detalles: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede generar el informe de depuración %(name)s. Detalles: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"Un grupo de volúmenes denominado '%(name)s' ya existe. Elija otro nombre "
-"para crear la agrupación lógica."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Kimchi no utilizaba el servidor de almacenamiento %(server)s"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' no existe"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "La partición %(name)s no existe en el host"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"No se puede concluir la máquina host ya que hay máquinas virtuales en "
-"ejecución"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"No se puede rearrancar la máquina host ya que hay máquinas virtuales en "
-"ejecución"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "No se ha encontrado el dispositivo de nodo '%(name)s'"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "No hay paquetes marcados para su actualización"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "El paquete %(name)s no está marcado para su actualización."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Se ha producido un error al obtener paquetes marcados para su actualización. "
-"Detalles: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "No hay ningún gestor de paquetes compatible para este sistema."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s no válido"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Tipo de almacenamiento no válido. Tipos soportados: 'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"Se ha producido un error al crear el nuevo dispositivo de almacenamiento: %"
-"(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-"Se ha producido un error al actualizar el dispositivo de almacenamiento: %"
-"(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-"Se ha producido un error al eliminar el dispositivo de almacenamiento: %"
-"(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Especifique el tipo y la vÃa de acceso para añadir un disco de máquina "
-"virtual nuevo"
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-"Especifique la vÃa de acceso para actualizar el disco de máquina virtual"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Especifique el tipo y la vÃa de acceso para añadir un disco de máquina "
-"virtual nuevo"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "El ID de repositorio YUM debe ser una serie de una sola palabra."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "El URL de repositorio debe ser http://, ftp:// o archivo:// URL."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"La configuración de repositorio es un diccionario con valores especÃficos "
-"según el tipo de repositorio."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "El repositorio de Distribución a DEB debe ser una serie"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "El repositorio de Componentes a DEB debe estar listado en una matriz"
-
-msgid "Components to DEB repository must be a string"
-msgstr "El repositorio de Componentes a DEB debe ser una serie"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "El nombre del repositorio YUM debe ser una serie."
-
-msgid "GPG check must be a boolean value."
-msgstr "La comprobación de GPG debe ser un valor booleano."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "La clave GPG debe ser un URL que apunta al archivo blindado por ASCII."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "No se ha podido actualizar el repositorio %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "El repositorio %(repo_id)s no existe."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-"La herramienta de gestión de repositorio no se ha reconocido para su sistema."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "El repositorio %(repo_id)s ya está habilitado."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "El repositorio %(repo_id)s ya está inhabilitado."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "No se ha podido eliminar el repositorio %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"No se ha podido grabar el archivo de configuración del repositorio %"
-"(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Especifique la distribución del repositorio para crear un repositorio de DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "No se ha podido habilitar el repositorio %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "No se ha podido inhabilitar el repositorio %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "El ID de repositorio de YUM ya existe"
-
-msgid "YUM Repository name must be a string"
-msgstr "El nombre del repositorio de YUM debe ser una serie"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "No se pueden listar repositorios. Detalles: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "No se puede recuperar información del repositorio. Detalles: '%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "No se puede añadir el repositorio. Detalles: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "No se puede eliminar el repositorio. Detalles: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "CÃDIGO DE ERROR"
-
-msgid "REASON"
-msgstr "RAZÃN"
-
-msgid "STACK"
-msgstr "PILA"
-
-msgid "Go to Homepage"
-msgstr "Ir a la página inicial"
-
-msgid "Create a New Virtual Machine"
-msgstr "Crear una nueva máquina virtual"
-
-msgid "Virtual Machine Name"
-msgstr "Nombre de máquina virtual"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"El nombre que se utiliza para identificar la máquina virtual. Si se omite, "
-"se elegirá un nombre basándose en la plantilla utilizada."
-
-msgid "Template"
-msgstr "Plantilla"
-
-msgid "Please create a template first."
-msgstr "Cree una plantilla primero."
-
-msgid "Create a Template"
-msgstr "Crear una plantilla"
-
-msgid "Please choose a template."
-msgstr "Elija una plantilla."
-
-msgid "OS"
-msgstr "SO"
-
-msgid "OS Version"
-msgstr "Versión del SO"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Memoria"
-
-msgid "Create"
-msgstr "Crear"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "Cancelar"
-
-msgid "Edit Guest"
-msgstr "Editar invitado"
-
-msgid "General"
-msgstr "General"
-
-msgid "Storage"
-msgstr "Almacenamiento"
-
-msgid "Interface"
-msgstr "Interfaz"
-
-msgid "Permission"
-msgstr "Versión"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Nombre"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "Memoria"
-
-msgid "Icon"
-msgstr "Icono"
-
-msgid "Device"
-msgstr "Nombre de dispositivo"
-
-msgid "Path"
-msgstr "VÃa de acceso NFS"
-
-msgid "Network"
-msgstr "Red"
-
-msgid "Type"
-msgstr "Tipo"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Todo"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "Proveedor"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Guardar"
-
-msgid "Replace"
-msgstr "Sustituir"
-
-msgid "Detach"
-msgstr "Desconectar"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "Iniciar"
-
-msgid "Reset"
-msgstr "Restablecer"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "Acciones"
-
-msgid "Connect"
-msgstr "Conectar"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "Editar"
-
-msgid "Shut Down"
-msgstr "Concluir"
-
-msgid "Delete"
-msgstr "Suprimir"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "E/S de disco"
-
-msgid "Network I/O"
-msgstr "E/S de red"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "No se ha encontrado invitados."
-
-msgid "Add a Storage Device to VM"
-msgstr "Añadir un dispositivo de almacenamiento a VM"
-
-msgid "Device Type"
-msgstr "Tipo de dispositivo"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "El tipo de dispositivo. Actualmente sólo está soportado \"cdrom\"."
-
-msgid "Storage Pool"
-msgstr "Agrupación de almacenamiento"
-
-msgid "Storage pool which volume located in"
-msgstr "La vÃa de acceso de la agrupación de almacenamiento debe ser una serie"
-
-msgid "Storage Volume"
-msgstr "Nombre de agrupación de almacenamiento"
-
-msgid "Storage volume to be attached"
-msgstr "El nombre de volumen de almacenamiento debe ser una serie"
-
-msgid "File Path"
-msgstr "VÃa de acceso de archivo"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "La vÃa de acceso del archivo ISO en el servidor para el CDROM."
-
-msgid "Attach"
-msgstr "Conectar"
-
-msgid "Shut down"
-msgstr "Concluir"
-
-msgid "Restart"
-msgstr "Reiniciar"
-
-msgid "Basic Information"
-msgstr "Información básica"
-
-msgid "OS Distro"
-msgstr "Distro de SO"
-
-msgid "OS Code Name"
-msgstr "Nombre de código de SO"
-
-msgid "Processor"
-msgstr "Procesador"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "EstadÃsticas del sistema"
-
-msgid "Software Updates"
-msgstr "Actualizaciones de software"
-
-msgid "Update Progress"
-msgstr "Actualizar progreso"
-
-msgid "Repositories"
-msgstr "Repositorios"
-
-msgid "Debug Reports"
-msgstr "Informes de depuración"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"El nombre de usuario o contraseña que ha especificado es incorrecto. Por "
-"favor, vuelva a intentarlo."
-
-msgid "This field is required."
-msgstr "Este campo es obligatorio."
-
-msgid "Log in"
-msgstr "Iniciar sesión"
-
-msgid "Logging in..."
-msgstr "Iniciando sesión..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "Invitados"
-
-msgid "Templates"
-msgstr "Plantillas"
-
-msgid "Failed to get application configuration"
-msgstr "No se ha podido obtener la configuración de la aplicación"
-
-msgid "This is not a valid Linux path"
-msgstr "No es una vÃa de acceso de Linux válida"
-
-msgid "This is not a valid URL."
-msgstr "No es un URL válido."
-
-msgid "No such data available."
-msgstr "No hay datos de ese tipo disponibles."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"No se puede contactar con el sistema host, Verifique que el sistema host "
-"está activo y que tiene conectividad de red con él. Respuesta de solicitud "
-"HTTP %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Confirmación de supresión"
-
-msgid "OK"
-msgstr "Aceptar"
-
-msgid "Confirm"
-msgstr "Confirmar"
-
-msgid "Warning"
-msgstr "Aviso"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Cargando..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Reintentar"
-
-msgid "Detailed message:"
-msgstr "Mensaje detallado:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "No es un archivo ISO válido."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Tardará mucho tiempo. ¿Desea continuar?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "Esto suprimirá permanentemente la plantilla. ¿Desea continuar?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"No se puede concluir el sistema ya que hay algunas máquinas virtuales en "
-"ejecución."
-
-msgid "Max:"
-msgstr "Máx.:"
-
-msgid "Utilization"
-msgstr "Utilización"
-
-msgid "Available"
-msgstr "Disponible"
-
-msgid "Read Rate"
-msgstr "Velocidad de lectura"
-
-msgid "Write Rate"
-msgstr "Velocidad de escritura"
-
-msgid "Received"
-msgstr "Recibido"
-
-msgid "Sent"
-msgstr "Enviado"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"Concluir o reiniciar el host hará que se pierda el trabajo no guardado. "
-"¿Desea continuar para concluir/reiniciar?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"El repositorio se eliminará de forma permanente y no se puede recuperar. "
-"¿Desea continuar?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL base"
-
-msgid "Is Mirror"
-msgstr "Es duplicado"
-
-msgid "URL Args"
-msgstr "Args de URL"
-
-msgid "Enabled"
-msgstr "Habilitado"
-
-msgid "GPG Check"
-msgstr "Comprobación GPG"
-
-msgid "GPG Key"
-msgstr "Clave GPG"
-
-msgid "Add"
-msgstr "Añadir"
-
-msgid "Remove"
-msgstr "Eliminar"
-
-msgid "Enable"
-msgstr "Habilitar"
-
-msgid "Disable"
-msgstr "Inhabilitar"
-
-msgid "Package Name"
-msgstr "Nombre de paquete"
-
-msgid "Version"
-msgstr "Versión"
-
-msgid "Architecture"
-msgstr "Arquitectura"
-
-msgid "Repository"
-msgstr "Repositorio"
-
-msgid "Update All"
-msgstr "Actualizar todo"
-
-msgid "Updating..."
-msgstr "Actualizando..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "No se han podido actualizar paquetes."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"El informe de depuración se eliminará permanentemente y no se puede "
-"recuperar. ¿Desea continuar?"
-
-msgid "Generated Time"
-msgstr "Tiempo generado"
-
-msgid "Generate"
-msgstr "Generar"
-
-msgid "Generating..."
-msgstr "Generando..."
-
-msgid "Rename"
-msgstr "Redenominar"
-
-msgid "Download"
-msgstr "Descargar"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr ""
-"El nombre de informe debe contener sólo letras, dÃgitos y/o guión ('-')."
-
-msgid "Pending..."
-msgstr "Cargando..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"Esto suprimirá la máquina virtual y sus discos virtuales. Esta operación no "
-"puede deshacerse. ¿Desea continuar?"
-
-msgid "Power off Confirmation"
-msgstr "Confirmación de supresión"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "Confirmación de supresión"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "Confirmación de supresión"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "Esto suprimirá permanentemente la plantilla. ¿Desea continuar?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Este CDROM se desconectará de forma permanente pero puede volver a "
-"conectarlo. ¿Desea continuar para desconectarlo?"
-
-msgid "Attaching..."
-msgstr "Conectando..."
-
-msgid "Replacing..."
-msgstr "Sustituyendo..."
-
-msgid "Successfully attached!"
-msgstr "¡Conectado correctamente!"
-
-msgid "Successfully replaced!"
-msgstr "¡Sustituido correctamente!"
-
-msgid "Successfully detached!"
-msgstr "¡Desconectado correctamente!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "El ID de VLAN debe estar entre 1 y 4094."
-
-msgid "unavailable"
-msgstr "no disponible"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"Esta acción interrumpirá la conectividad de red para cualquier máquina "
-"virtual que dependa de esta red."
-
-msgid "Create a network"
-msgstr "Crear una red"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Esta agrupación de almacenamiento no es persistente. En lugar de desactivar, "
-"esta acción la suprimirá permanentemente. ¿Desea continuar?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-"Esto suprimirá permanentemente la agrupación de almacenamiento. ¿Desea "
-"continuar?"
-
-msgid "This storage pool is empty."
-msgstr "Esta agrupación de almacenamiento está vacÃa."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Dará formato al disco y se perderán los datos que tenga en él. ¿Está seguro "
-"de que desea continuar? "
-
-msgid "SCSI Fibre Channel"
-msgstr "Canal de fibra de SCSI"
-
-msgid "No SCSI adapters found."
-msgstr "No se han encontrado adaptadores SCSI."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "El nombre de la agrupación de almacenamiento no puede estar en blanco."
-
-msgid "The storage pool path can not be blank."
-msgstr ""
-"La vÃa de acceso de la agrupación de almacenamiento no puede estar en blanco."
-
-msgid "NFS server mount path can not be blank."
-msgstr "La vÃa de acceso de montaje del servidor NFS no puede estar en blanco."
-
-msgid "Invalid NFS mount path."
-msgstr "VÃa de acceso de montaje de NFS no válida."
-
-msgid "No logical device selected."
-msgstr "No se ha seleccionado ningún dispositivo lógico."
-
-msgid "The iSCSI target can not be blank."
-msgstr "El destino iSCSI no puede estar en blanco."
-
-msgid "Server name can not be blank."
-msgstr "El nombre de servidor no puede estar en blanco."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "Buscando particiones disponibles..."
-
-msgid "No available partitions found."
-msgstr "No se han encontrado particiones disponibles."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Esta agrupación de almacenamiento no es persistente. En lugar de desactivar, "
-"esta acción la suprimirá permanentemente. ¿Desea continuar?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "No se puede recuperar información del repositorio. Detalles: '%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "El nombre de la agrupación de almacenamiento no puede estar en blanco."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "Nombre de red"
-
-msgid "State"
-msgstr "Estado"
-
-msgid "Network Type"
-msgstr "Tipo de red"
-
-msgid "Address Space"
-msgstr "Espacio de direcciones"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-"Nombre de agrupación de almacenamiento no válido. No debe contener '/'."
-
-msgid "Isolated: no external network connection"
-msgstr "Aislado: no hay conexión de red fÃsica"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: conexión de red fÃsica saliente solamente"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Puenteado: Las máquinas virtuales están conectadas a la red fÃsica "
-"directamente"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "Destino:"
-
-msgid "Enable VLAN"
-msgstr "Habilitar VLAN:"
-
-msgid "VLAN ID"
-msgstr "ID de VLAN:"
-
-msgid "Stop"
-msgstr "Detener"
-
-msgid "Generate a New Debug Report"
-msgstr "Generar un Informe de depuración nuevo"
-
-msgid "Report Name"
-msgstr "Nombre de informe"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"El nombre que se utiliza para identificar el informe. Si se omite, se "
-"elegirá un nombre basándose en la hora actual. El nombre puede contener: "
-"letras, dÃgitos y guión (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "Generar un Informe de depuración nuevo"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"El nombre que se utiliza para identificar el informe. Si se omite, se "
-"elegirá un nombre basándose en la hora actual. El nombre puede contener: "
-"letras, dÃgitos y guión (\"-\")."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "Añadir un repositorio"
-
-msgid "Identifier"
-msgstr "Identificador"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Identificador exclusivo de una sola palabra para el repositorio."
-
-msgid "Textual name for the repository."
-msgstr "Nombre textual para el repositorio."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Campo obligatorio"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL al repositorio. Los protocolos soportados son http, ftp y archivo."
-
-msgid "Repository is a mirror"
-msgstr "El repositorio es un duplicado."
-
-msgid "Distribution"
-msgstr "Distribución"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribución del repositorio DEB."
-
-msgid "Components"
-msgstr "Componentes"
-
-msgid "List of components in DEB repository."
-msgstr "Lista de componentes en el repositorio DEB."
-
-msgid "Edit Repository"
-msgstr "Editar repositorio"
-
-msgid "Mirror List URL"
-msgstr "URL de lista duplicada"
-
-msgid "Yes"
-msgstr "SÃ"
-
-msgid "No"
-msgstr "No"
-
-msgid "Capacity"
-msgstr "Capacidad"
-
-msgid "Allocated"
-msgstr "Asignado"
-
-msgid "Location"
-msgstr "Ubicación"
-
-msgid "Device path"
-msgstr "VÃa de acceso del dispositivo"
-
-msgid "active"
-msgstr "activo"
-
-msgid "inactive"
-msgstr "inactivo"
-
-msgid "Deactivate"
-msgstr "Desactivar"
-
-msgid "Activate"
-msgstr "Activar"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "No definir"
-
-msgid "Format"
-msgstr "Formato:"
-
-msgid "Allocation"
-msgstr "Asignado:"
-
-msgid "Define a New Storage Pool"
-msgstr "Definir una agrupación de almacenamiento nueva"
-
-msgid "Storage Pool Name"
-msgstr "Nombre de agrupación de almacenamiento"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"El nombre que se utiliza para identificar las agrupaciones de almacenamiento "
-"y no debe estar vacÃo."
-
-msgid "Storage Pool Type"
-msgstr "Tipo de agrupación de almacenamiento"
-
-msgid "Storage Path"
-msgstr "VÃa de acceso de almacenamiento"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"La vÃa de acceso de la agrupación de almacenamiento. Cada agrupación de "
-"almacenamiento debe tener una vÃa de acceso exclusiva."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr "Kimchi intentará crear el directorio cuando no existe en el sistema."
-
-msgid "NFS Server IP"
-msgstr "IP de Servidor NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP o nombre de host de servidor NFS. Puede especificarse o elegirse del "
-"historial."
-
-msgid "NFS Path"
-msgstr "VÃa de acceso NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "La vÃa de acceso exportada de NFS en el servidor NFS."
-
-msgid "iSCSI Server"
-msgstr "Servidor iSCSI"
-
-msgid "Server"
-msgstr "Servidor"
-
-msgid "Port"
-msgstr "Puerto"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP o nombre de host de servidor iSCSI. No debe estar vacÃo."
-
-msgid "Target"
-msgstr "Destino"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "El destino iSCSI en el servidor iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "Añadir Autenticación iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Autenticación iSCSI"
-
-msgid "User Name"
-msgstr "Nombre de usuario"
-
-msgid "Password"
-msgstr "Contraseña"
-
-msgid "SCSI Adapter"
-msgstr "Adaptador SCSI"
-
-msgid "Please, wait..."
-msgstr "Por favor, espere..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "Añadir plantilla"
-
-msgid "Where is the source media for this template? "
-msgstr "¿Dónde está el soporte de origen para esta plantilla?"
-
-msgid "Local ISO Image"
-msgstr "Imagen ISO local"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "Imagen ISO remota"
-
-msgid "Search ISOs"
-msgstr "Buscar ISOs"
-
-msgid "The following ISOs are available:"
-msgstr "Las siguientes ISO están disponibles:"
-
-msgid "OS: "
-msgstr "SO: "
-
-msgid "Version: "
-msgstr "Versión: "
-
-msgid "Size: "
-msgstr "Tamaño: "
-
-msgid "Search more ISOs"
-msgstr "Buscar más ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Crear plantillas a partir de ISO seleccionadas"
-
-msgid "I want to use a specific ISO file"
-msgstr "Deseo utilizar un archivo ISO especÃfico"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Cargando ISO remotas predeterminadas ..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Deseo utilizar un URL personalizado"
-
-msgid "Edit Template"
-msgstr "Editar plantilla"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "Gráficos"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "Número de CPU"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "No se han encontrado plantillas."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "Suprimir no está permitido para %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s no implementa método de actualización"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Crear no está permitido para %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "No se puede analizar la solicitud JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Esta API sólo da soporte a JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "El almacén de datos no se ha iniciado en el objeto de modelo."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "No se puede iniciar la tarea debido a un error: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr ""
-#~ "La autenticación ha fallado para el usuario '%(username)s'. [Código de "
-#~ "error: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "No tiene autorización para acceder a Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Especifique %(item)s para iniciar la sesión en Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "No se puede encontrar %(item)s en el almacén de datos"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr ""
-#~ "Tiempo de espera excedido al ejecutar el mandato '%(cmd)s' después de %"
-#~ "(seconds)s segundos"
-
-#~ msgid "Help"
-#~ msgstr "Ayuda"
-
-#~ msgid "About"
-#~ msgstr "Acerca de"
-
-#~ msgid "Log out"
-#~ msgstr "Finalizar sesión"
-
-#~ msgid "Version:"
-#~ msgstr "Versión:"
diff --git a/plugins/kimchi/po/fr_FR.po b/plugins/kimchi/po/fr_FR.po
deleted file mode 100644
index b996e8a..0000000
--- a/plugins/kimchi/po/fr_FR.po
+++ /dev/null
@@ -1,2338 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2014-08-27 21:30+0000\n"
-"Last-Translator: BobSynfig\n"
-"Language-Team: French (http://www.transifex.com/projects/p/kimchi/language/"
-"fr/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fr_FR\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr "Paramètre inconnu %(value)s"
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr "\"_cap\" spécifiée inconnue"
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr "\"_passthrough\" doit être \"true\" ou \"false\""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr "\"_passthrough_affected_by\" doit être un nom de périphérique"
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "Erreur durant l'accès aux périphériques de bloc. Détails: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"Erreur durant l'obtention de l'information sur le périphérique de bloc %"
-"(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Impossible de trouver le fichier de distro: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"Impossible de parser le fichier de distro: %(filename)s. Veuillez vous "
-"assurer qu'il s'agit d'un fichier JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"Impossible de se connecter à l'hôte cible iSCSI %(portal)s. Détails: %(err)s "
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Impossible de se connecter à l'hôte iSCSI %(host)s cible %(target)s"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr "Impossible de trouver le fichier ISO %(filename)s"
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "Le fichier ISO %(filename)s n'est pas bootable"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"Le fichier ISO %(filename)s n'a pas d'enregistrement de boot El Torito valide"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Entrée de validation El Torito invalide dans l'ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicateur de boot El Torito invalide dans l'ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Type de volume inattendu pour le volume primaire dans l'ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Mauvais format durant la lecture du descripteur de volume dans l'ISO %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"L'hyperviseur n'a pas la permission d'utiliser cet ISO %(filename)s. "
-"Veuillez considérer de le déplacer sous /var/lib/libvirt,, ou de définir la "
-"permission de recherche sur les listes de contrpole d'accès fichier pour "
-"l'utilisateur '%(user)s' si possible, ou ajouter le '%(user)s' au groupe de "
-"chemins d'ISO, ou (non recommandé) 'chmod -R o+x 'chemin_vers_iso'.Détails: "
-"%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-"Une erreur est survenue lors de la détection de l'information d'OS de "
-"l'image."
-
-msgid "No OS information found in given image."
-msgstr "Aucune information d'OS trouvée sur l'image donnée."
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr "Impossible de lire le fichier image %(filename)s"
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-"Le fichier image doit être un fichier existant sur le système. %(filename)s "
-"n'est pas une donnée valide."
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "La machine virtuelle %(name)s existe déjà "
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "La machine virtuelle %(name)s n'existe pas"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-"Impossible de renommer la machine virtuelle %(name)s. Le nom %(new_name)s "
-"est déja utilisé ou la machine virtuelle n'est pas éteinte."
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Impossible de récupérer une capture d'écran pour la machine virtuelle "
-"stoppée %(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "L'image ISO distante n'est pas supportée par le serveur."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr "Copie d'écran non supportée par la machine virtuelle %(name)s"
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossible de créer la machine virtuelle %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de mettre à jour la machine virtuelle %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de récupérer la machine virtuelle %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr "Impossible de se connecter à la machine virtuelle éteinte %(name)s."
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "L'adresse d'écoute du graphics doit être IPv4 ou IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Spécifier un modèle à partir duquel créer une machine virtuelle"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossible de démarrer la machine virtuelle %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de mettre hors tension la machine virtuelle %(name)s. Détails: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de supprimer la machine virtuelle %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de réinitrialiser la machine virtuelle %(name)s. Détails: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "Le nom d'utilisateur doit être une chaîne de caractères"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "Le nom de groupe doit être une chaîne de caractères"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "Le(s) utilisateur(s) '%(users)s' n'existe(nt) pas"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "Le(s) groupe(s) '%(groups)s' n'existe(nt) pas"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossible d'éteindre la machine virtuelle %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible d'accéder aux metadata de la machine virtuelle %(name)s. Détails: "
-"%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr "Le mot de passe de console invitée doit être une chaîne de caractères."
-
-msgid "The life time for the guest console password must be a number."
-msgstr "La durée de vie du mot de passe de console invitée doit être un nombre"
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-"La machine virtuelle %(vmid)s ne peut pas contenir le périphérique hôte "
-"directement assigné %(dev_name)s."
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-"The périphérique hôte %(dev_name)s ne peut être directement assigné à la "
-"machine virtuelle"
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr "\"name\" doit être un nom de périphérique"
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "L'interface %(iface)s n'existe pas dans la machine virtuelle %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"Le réseau %(network)s spécifié pour la machine virtuelle %(name)s n'existe "
-"pas"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-"Le type d'interface de machine virtuelle supporté est réseau uniquement"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"Le nom de réseau pour l'interface de la machine virtuelle doit être une "
-"chaîne de caractères"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Modèle de carte réseau spécifié invalide pour l'interface de machine "
-"virtuelle"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Spécifier le type et le réseau à ajouter à la nouvelle interface de la "
-"machine virtuelle"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Le modèle %(name)s existe déjà "
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr ""
-"Le réseau '%(network)s' spécifié pour le modèle %(template)s n'existe pas"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Le pool de stockage spécifié %(pool)s pour le modèle %(template)s n'existe "
-"pas"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-"Le pool de stockage spécifié %(pool)s pour le modèle %(template)s n'est pas "
-"actif"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Paramètres '%(param)s' spécifié invalide pour le CDROM"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"Le réseau %(network)s spécifié pour le modèle %(template)s n'est pas actif"
-
-msgid "Template name must be a string"
-msgstr "Le modèle de nom doit être une chaîne de caractères"
-
-msgid "Template icon must be a path to the image"
-msgstr "Le modèle d'icone doit être un chemin vers l'image"
-
-msgid "Template distribution must be a string"
-msgstr "Le modèle de distribution doit être une chaîne de caractères"
-
-msgid "Template distribution version must be a string"
-msgstr ""
-"Le modèle de version de distribution doit être une chaîne de caractères"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "Le nombre de CPU doit être un nombre entier supérieur à 0"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "La quantité de mémoire (Mo) doit être un nombre entier supérieur à 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Le CDROM modèle doit être un fichier ISO local ou distant"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "URI %(value)s du pool de stockage spécifiée invalide pour le modèle"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-"Spécifiez une image ISO comme CDROM ou une image de base pour créer un modèle"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Tous les réseaux pour le modèle doivent être spécifiés dans une liste"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr "Le volume %(volume)s n'est pas dans le pool de stockage %(pool)s"
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "Impossible de créer le modèle à cause de l'erreur: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "Impossilbe de supprimer le modèle à cause de l'erreur: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr "La taille de disque doit être un entier supérieur à 1Go."
-
-msgid "Template base image must be a valid local image file"
-msgstr "L'image de base de modèle doit petre un fichier image local valide"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr "Ne peut identifier le format de l'image de base %(path)s"
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-"Dans la topologie de CPU, chaque élément doit être un entier strictement "
-"positif."
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Le pool de stockage %(name)s existe déjà "
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Le pool de stockage %(name)s n'existe pas"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Spécifier %(item)s afin de créer le pool de stockage %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Impossible de supprimer le pool de stockage actif %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Impossible de lister les pools de stockage. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Impossilble de créer le pool de stockage %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Impossible d'obtenir le nombre de volumes de stockage dans le pool de "
-"stockage%(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Impossible d'activer le pool de stockage %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de désactiver le pool de stockage %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de supprimer le pool de stockage %(name)s. Détails: %(err)s "
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"Impossible de créer le Pool NFS du fait que le chemin d'export %(path)s "
-"pourrait se bloquer durant le montage"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"Impossible de créer le pool NFS du fait que le montage du chemin d'export %"
-"(path)s a échoué"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Type de pool de stockage non supporté: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-"Les types de pool de stockage supportés sont: dir, netfs, logical, iscsi, "
-"isci et kimchi-iso"
-
-msgid "Storage pool path must be a string"
-msgstr "Le chemin du pool de stockage doit être une chaîne de caractères"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "L'hôte du pool de stockage doit être une IP ou un nom d'hôte"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Le paramètre de périphérique de pool de stockage doit être une list"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "La cible IQN d'un pool iSCSI doit être une chaîne de caractères"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"Le port d'un serveur de stockage distant doit être un nombre entier entre 1 "
-"et 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-"Le nom d'utilisateur de la cible iSCSI doit être une chaîne de caractères"
-
-msgid "iSCSI target password must be a string"
-msgstr "Le mot de passe de la cible iSCSI doit être une chaîne de caractères"
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Spécifier un nom et un type pour créer un pool de stockage"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s n'est pas un(e) disque/partition valide. N'a pu l'ajouter au pool %"
-"(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr "Impossible d'agrandir le pool logique %(pool)s. Détails: %(err)s"
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Les disques en paramètre peuvent seulement être mis à jour pour un pool de "
-"stockage logique."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "Le nom d'adaptateur de l'hôte SCSI doit être une chapine de caractères"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "Le pool de stockage kimchi_isos est réservé à un usage interne"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossible d'activer le pool de stockage NFS%(name)s. Le serveur NFS %"
-"(server)s n'est pas joignable."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossible de désactiver le pool de stockage NFS%(name)s. Le serveur NFS %"
-"(server)s n'est pas joignable."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossible de désactiver le pool %(name)s du fait qu'il est associé à des "
-"modèles"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossible de supprimer le pool %(name)s du fait qu'il est associé à des "
-"modèles"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"Un groupe de volume appelé '%(name)s' existe déjà . Veuillez choisir un autre "
-"nom pour créer le pool logique."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"Impossible de mettre à jour la base de données avec les informations de scan "
-"profond à cause de l'erreur: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Le volume de stockage %(name)s existe déjà "
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"Le volume de stockage %(name)s n'existe pas dans le pool de stockage %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-"Impossible de créer le volume de stockage %(volume)s car le pool de stockage "
-"%(pool)s n'est pas actif"
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Spécifier %(item)s afin de créer le volume de stockage %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"Impossible de lister les volumes de stockage car le pool de stockage %(pool)"
-"s n'est pas actif"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"Impossible de créer le volume de stockage %(name)s dans le pool de stockage %"
-"(pool)s. Détails: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Impossible de lister les volumes de stockage dans le pool de stockage %(pool)"
-"s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "Impossible de wiper les volumes de stockage %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de supprimer le volume de stockage %(name)s. Détails: %(err)s "
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de redimensionner le volume de stockage %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"Le type de stockage %(type)s ne supporte pas ni la création ni la "
-"suppression de volume"
-
-msgid "Storage volume name must be a string"
-msgstr "Le nom de volume de stockage doit être une chaîne de caractères"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "L'allocation de volume de stockage doit être une nombre entier"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "Le volume de stockage requiert un nom de volume"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Impossible de mettre à jour la base de données avec les informations du "
-"volume de stockage à cause de l'erreur: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr "Seulement un seul des paramêtre %(param)s peut être spécifié"
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr "La création de volume avec %(param)s n'est pas supportée"
-
-msgid "Storage volume capacity must be an integer number."
-msgstr "La capacité du volume de stockage doit être un nombre entier."
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-"L'URL du volume de stockage doit être http://, https://, ftp:// ou ftps://."
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr "Impossible d'accéder au fichier %(url)s. Veuillez le vérifier."
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "L'interface %(name)s n'existe pas"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Le réseau %(name)s existe déjà "
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "Le réseau %(name)s n'existe pas"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"Le sous-réseau %(subnet)s spécifié pour le réseau %(network)s n'est pas "
-"valide"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "Spécifier une interface réseau pour créer le réseau bridge %(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Impossible de supprimer le réseau actif %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-"L'interface %(iface)s spécifiée pour le réseau %(network)s est déjà utilisée"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "L'interface doit être un périphérique NIC vide, bonding ou bridgé."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Impossible de créer le réseau %(name)s. Détails: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Impossible de trouver une adresse IP libre pour le réseau '%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "L'interface %(iface)s existe déjà "
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Les types de réseaux supportés sont isolated, NAT et bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"Le sous-réseau doit être une chaine de caractères avec une adresse IP et un "
-"préfixe ou un masque de réseau"
-
-msgid "Network interface must be a string"
-msgstr "L'interface de réseau doit être une chaîne de caractères"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "L'ID de VLAN du réseau doit être un nombre entier entre 1 et 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Spécifiez un nom et un type pour créer un réseau"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"Impossible de supprimer le réseau %(name)s. Il y a des machines virtuelles %"
-"(vms)s et/ou des modèles liés à ce réseau. "
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"Impossible de désactiver réseau %(name)s. Il y a des machines virtuelles%"
-"(vms)s et/ou des modèles liés à ce réseau. "
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"Le périphérique bridge %(name)s ne peut être le périphérique tronc d'un VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "Ãchec durant l'activation de l'interface %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"Ãchec durant l'activation de l'interface %(iface)s. Veuillez vérifier le "
-"statut du lien physique."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Le rapport de déboggage %(name)s n'existe pas"
-
-msgid "Debug report tool not found in system"
-msgstr "L'outil de rapport de déboggage n'a pas été trouvé dans le système"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-"Impossible de créer le rapport de déboggage %(name)s. Détails: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-"Impossible de trouver un rapport de déboggage avec le nom fourni %(name)s"
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de générer le rapport de déboggage %(name)s. Détails: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr "Vous devriez donner un nom au fichier de rapport de déboggage."
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-"Le nom du rapport de déboggage doit être une chaîne de caractères. Seulement "
-"les lettres, chiffres, blanc souligné ('_') et tirets ('-') sont acceptés."
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"Le rapport de déboggage avec le nom spécifié \"%(name)s\" existe déjà . "
-"Veuillez en utiliser un autre."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Le server de stockage %(server)s n'était pas utilisé par Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "La distro '%(name)s' n'existe pas"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "La partition %(name)s n'existe pas sur cet hôte"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Impossible d'éteindre la machine hôte car des machines virtuelles en sont "
-"cours d'exécution"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"Impossible de redémarrer la machine hôte car des machines virtuelles en sont "
-"cours d'exécution"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "Périphérique de noeud '%(name)s' non trouvé"
-
-msgid "Conflicting flag filters specified."
-msgstr "Filtres incompatibles spécifiés."
-
-msgid "No packages marked for update"
-msgstr "Aucun paquet marqué pour mise à jour"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Le paquet %(name)s n'est pas marqué pour mise à jour"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Erreur durant la récupération des paquets marqués pour la miseà jour. "
-"Détails: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "Il n'y a pas de gestionnaire de paquets compatible avec ce système."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s invalide"
-
-msgid "Unable to choose a virtual machine name"
-msgstr "Impossible de sélectionner un nom de machine virtuelle"
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Type de stockage invalide. Les Types supportés sont: 'cdrom', 'disk'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr "Seulement le chemin d'un CDROM peut être modifié."
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-"Le périphérique de stockage %(dev_name)s n'existe pas dans la machine "
-"virtuelle %(vm_name)s"
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"Erreur durant la création du nouveau périphérique de stockage: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Erreur durant la mise à jour du périphérique de stockage: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Erreur durant le retrait du périphérique de stockage: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr "Ne pas supporter le branchement à chaud de périphérique IDE"
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Spécifier le type et le chemin ou le type et le pool/volume pour ajouter un "
-"nouveau disque de machine virtuelle."
-
-msgid "Specify path to update virtual machine disk"
-msgstr "Spécifier un chemin pour mettre à jour le disque de machine virtuelle"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-"La limitation de %(limit)s périphériques a été atteinte pour le contrôleur "
-"de type %(type)s "
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Seul un chemin ou pool/volume peut être spécifié pour ajouter un nouveau "
-"disque de machine virtuelle"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-"Le volume de format %(format)s sélectionné ne correspond pas au type de "
-"stockage %(type)s"
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-"L'ID du dépôt YUM doit être une chaîne de caractères ne comportant qu'un "
-"seul mot"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "L'URL du dépôt doit être une URL en http://, ftp:// ou file://."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"La configuration du dépôt est un dictionaire avec des valeurs spécifiques en "
-"accord avec le type de dépôt."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-"La distribution dans le nom de dépôt DEB doit être une chaîne de caractères"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "Les composants dans le dépôt DEB doivent être listés dans un tableau"
-
-msgid "Components to DEB repository must be a string"
-msgstr "Les composants dans le dépôt DEB doivent être une chaîne de caractères"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Le nom du dépôt YUM doit être une chaîne de caractères"
-
-msgid "GPG check must be a boolean value."
-msgstr "La vérification GPG doit être une valeur booléenne."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "La clé GPG doit être une URL pointant vers un fichier ASCII non armé."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Ne peut mettre à jour le dépôt %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Le dépôt %(repo_id)s n'existe pas."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "L'outil de gestion de dépôt n'a pas été reconnu pour votre système."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Le dépôt %(repo_id)s est déjà activé."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Le dépôt %(repo_id)s est déjà désactivé."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Ne peut supprimer le dépôt %(repo_id)s. "
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "Ne peut écrire le fichier de configuration du dépôt %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "Spécifier la distribution du dépôt afin de créer un dépôt DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Ne peut activer le dépôt %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Ne peut désactiver le dépôt %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "L'ID du dépôt YUM existe déjà "
-
-msgid "YUM Repository name must be a string"
-msgstr "Le nom du dépôt YUM doit être une chaîne de caractères"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Impossible de lister les dépôts. Détails: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "Impossible de récupérer les informations du dépôt. Détails: '%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Impossible d'ajouter un dépôt. Détails: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Impossible de supprimer un dépôt. Détails: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-"Ãléments de configurations: %(items)s ne sont pas supportés par le "
-"gestionnaire de dépôt"
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "ERROR CODE"
-
-msgid "REASON"
-msgstr "REASON"
-
-msgid "STACK"
-msgstr "STACK"
-
-msgid "Go to Homepage"
-msgstr "Aller à la page d'accueil"
-
-msgid "Create a New Virtual Machine"
-msgstr "Créer une nouvelle Machine Virtuelle"
-
-msgid "Virtual Machine Name"
-msgstr "Nom de Machine Virtuelle"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"Le nm est utilisé pour identifier une machine virtuelle. Si omis, un nom "
-"sera choisi en se basant sur le modèle utilisé."
-
-msgid "Template"
-msgstr "Modèle"
-
-msgid "Please create a template first."
-msgstr "Veuillez d'abord créer un modèle."
-
-msgid "Create a Template"
-msgstr "Créer un modèle"
-
-msgid "Please choose a template."
-msgstr "Veuillez choisir un modèle"
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "Version de l'OS"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Mémoire"
-
-msgid "Create"
-msgstr "Créer"
-
-msgid "Creating..."
-msgstr "Création en cours..."
-
-msgid "Cancel"
-msgstr "Annuler"
-
-msgid "Edit Guest"
-msgstr "Ãditer l'Invité"
-
-msgid "General"
-msgstr "Général"
-
-msgid "Storage"
-msgstr "Stockage"
-
-msgid "Interface"
-msgstr "Interface"
-
-msgid "Permission"
-msgstr "Permission"
-
-msgid "Host PCI Device"
-msgstr "Périphérique PCI Hôte"
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Nom"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "Mémoire (Mo)"
-
-msgid "Icon"
-msgstr "Icone"
-
-msgid "Device"
-msgstr "Périphérique"
-
-msgid "Path"
-msgstr "Chemin"
-
-msgid "Network"
-msgstr "Réseau"
-
-msgid "Type"
-msgstr "Type"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr "Utilisateurs et groupes systèmes disponibles"
-
-msgid "Selected system users and groups"
-msgstr "Utilisateurs et groupes systèmes sélectionnés"
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Tous"
-
-msgid "To Add"
-msgstr "Ã Ajouter"
-
-msgid "Added"
-msgstr "Ajouter"
-
-msgid "filter"
-msgstr "Filtre"
-
-msgid "Product"
-msgstr "Produit"
-
-msgid "Vendor"
-msgstr "Vendeur"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Enregistrer"
-
-msgid "Replace"
-msgstr "Remplacer"
-
-msgid "Detach"
-msgstr "Détacher"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "Démarrer"
-
-msgid "Reset"
-msgstr "Réinitialiser"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "Mettre hors tension"
-
-msgid "Actions"
-msgstr "Actions"
-
-msgid "Connect"
-msgstr "Connecter"
-
-msgid "Clone"
-msgstr "Cloner"
-
-msgid "Edit"
-msgstr "Ãditer"
-
-msgid "Shut Down"
-msgstr "Ãteindre"
-
-msgid "Delete"
-msgstr "Supprimer"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "E/S Disque"
-
-msgid "Network I/O"
-msgstr "E/S Réseau"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "Aucun invité trouvé."
-
-msgid "Add a Storage Device to VM"
-msgstr "Ajouter un Périphérique de Stockage à la VM"
-
-msgid "Device Type"
-msgstr "Type de Périphérique"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr ""
-"Le type de périphérique. Actuellement, \"cdrom\" et \"disk\" sont supportés."
-
-msgid "Storage Pool"
-msgstr "Pool de Stockage"
-
-msgid "Storage pool which volume located in"
-msgstr "Pool de Stockage dans lequel le volume est situé"
-
-msgid "Storage Volume"
-msgstr "Volume de Stockage"
-
-msgid "Storage volume to be attached"
-msgstr "Le volume de stockage à attacher"
-
-msgid "File Path"
-msgstr "Chemin de Fichier"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "Le chemin de fichier ISO sur le serveur comme CDROM."
-
-msgid "Attach"
-msgstr "Attacher"
-
-msgid "Shut down"
-msgstr "Ãteindre"
-
-msgid "Restart"
-msgstr "Redémarrer"
-
-msgid "Basic Information"
-msgstr "Informations de Base"
-
-msgid "OS Distro"
-msgstr "Distro de l'OS"
-
-msgid "OS Code Name"
-msgstr "Nom de code de l'OS"
-
-msgid "Processor"
-msgstr "Processeur"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "Statistiques Système"
-
-msgid "Software Updates"
-msgstr "Mises à jour Logiciel"
-
-msgid "Update Progress"
-msgstr "Progrès de la Mise à Jour"
-
-msgid "Repositories"
-msgstr "Dépôts"
-
-msgid "Debug Reports"
-msgstr "Rapports de Déboggage"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"Le nom d'utilisateur ou le mot de passe que vous avez entré est incorrect. "
-"Veuillez essayer à nouveau."
-
-msgid "This field is required."
-msgstr "Ce champ est requis."
-
-msgid "Log in"
-msgstr "Se connecter"
-
-msgid "Logging in..."
-msgstr "En cours de connexion..."
-
-msgid "Host"
-msgstr "Hôte"
-
-msgid "Guests"
-msgstr "Invités"
-
-msgid "Templates"
-msgstr "Modèles"
-
-msgid "Failed to get application configuration"
-msgstr "Ãchec lors de l'obtention de la configuration de l'application"
-
-msgid "This is not a valid Linux path"
-msgstr "Ce n'est pas un chemin Linux valide"
-
-msgid "This is not a valid URL."
-msgstr "Ce n'est pas une URL valide."
-
-msgid "No such data available."
-msgstr "De telles données ne sont pas disponibles."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"Ne peut contacter le système hôte. Vérifiez que le système hôte est allumé "
-"et que vous avez une connectivité réseau avec lui. Réponse de requête HTTP %"
-"1."
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Confirmation de Suppression"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Confirmer"
-
-msgid "Warning"
-msgstr "Avertissement"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Chargement en cours..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Essayer à nouveau"
-
-msgid "Detailed message:"
-msgstr "Message détaillé:"
-
-msgid "No ISO found"
-msgstr "Aucune ISO détectée"
-
-msgid "This is not a valid ISO file."
-msgstr "Ce n'est pas un fichier ISO valide."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Cela va prendre un long moment. Voulez-vous continuer ?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr ""
-"Cela va supprimer de manière permanent le modèle. Souhaites-vous continuer ?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"Impossible d'éteindre le système du fait que certaines machines virtuelles "
-"sont lancées !"
-
-msgid "Max:"
-msgstr "Max:"
-
-msgid "Utilization"
-msgstr "Utilisation"
-
-msgid "Available"
-msgstr "Disponible"
-
-msgid "Read Rate"
-msgstr "Taux en Lecture"
-
-msgid "Write Rate"
-msgstr "Taux en Ãcriture"
-
-msgid "Received"
-msgstr "Reçu"
-
-msgid "Sent"
-msgstr "Envoyé"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"Ãteindre ou redémarrer l'hôte causera la perte de tout travail non "
-"enregistré. Continuer à éteindre/redémarrer ?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Le dépôt sera retiré de façon permanente et ne pourra être rétabli. Voulez-"
-"vous continuer ?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL de base"
-
-msgid "Is Mirror"
-msgstr "Est un miroir"
-
-msgid "URL Args"
-msgstr "Arguments d'URL"
-
-msgid "Enabled"
-msgstr "Activé"
-
-msgid "GPG Check"
-msgstr "Vérification GPG"
-
-msgid "GPG Key"
-msgstr "Clé GPG"
-
-msgid "Add"
-msgstr "Ajouter"
-
-msgid "Remove"
-msgstr "Retirer"
-
-msgid "Enable"
-msgstr "Activer"
-
-msgid "Disable"
-msgstr "Désactiver"
-
-msgid "Package Name"
-msgstr "Nom de paquet"
-
-msgid "Version"
-msgstr "Version"
-
-msgid "Architecture"
-msgstr "Architecture"
-
-msgid "Repository"
-msgstr "Dépôt"
-
-msgid "Update All"
-msgstr "Tout mettre à jour"
-
-msgid "Updating..."
-msgstr "En cours de mise à jour..."
-
-msgid "Failed to retrieve packages update information."
-msgstr "Ãchec de récupération des informations de mise-à -jour des paquets."
-
-msgid "Failed to update package(s)."
-msgstr "Ãchec durant la mise à jour du/des paquet(s)"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Le rapport de déboggage sera enlevé de façon permanente et ne pourra être "
-"rétabli. Voulez-vous continuer ?"
-
-msgid "Generated Time"
-msgstr "Horodatage de génération"
-
-msgid "Generate"
-msgstr "Générer"
-
-msgid "Generating..."
-msgstr "En cours de génération..."
-
-msgid "Rename"
-msgstr "Renommer"
-
-msgid "Download"
-msgstr "Télécharger"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr ""
-"Le nom de rapport devrait contenir uniquement des lettres, nombres, "
-"soulignement ('_') et/ou tiret ('-')."
-
-msgid "Pending..."
-msgstr "En attente..."
-
-msgid "Report name is the same as the original one."
-msgstr "Le nom du rapport est le même que celui d'origine."
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"Cela va supprimer la machine virtuelle et tous ses disques virtuels. Cette "
-"opération est irréversible. Voulez-vous continuer ?"
-
-msgid "Power off Confirmation"
-msgstr "Confirmation de mise hors tension"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-"Cette action pourrait produire des résultats indésirables, par exemple un "
-"cache disque non flushé dans l'invité. Voulez-vous continuer ?"
-
-msgid "Reset Confirmation"
-msgstr "Confirmation de Réinitialisation"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-"Il y a un risque de perte de données causées par une réinitialisation sans "
-"extinction de l'OS invité. Voulez-vous continuer ?"
-
-msgid "Shut Down Confirmation"
-msgstr "Confirmation d'Extinction"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-"Noter que l'OS invité pourrait ignorer cette requête. Voulez-vous continuer ?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr "Confirmation de suppression de Machine Virtuelle"
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Ce CDROM sera détaché de façon permanente et vous pourrez le ré-attacher. "
-"Continuer le détachement ?"
-
-msgid "Attaching..."
-msgstr "En cours d'attachement..."
-
-msgid "Replacing..."
-msgstr "En cours de Remplacement..."
-
-msgid "Successfully attached!"
-msgstr "Attaché avec succès !"
-
-msgid "Successfully replaced!"
-msgstr "Remplacé avec succès !"
-
-msgid "Successfully detached!"
-msgstr "Détaché avec Succès !"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-"Ce disque sera définitivement détaché et peut être ré-attaché. Continuer à "
-"le détacher ?"
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "L'id du VLAN doit être entre 1 et 4094."
-
-msgid "unavailable"
-msgstr "non disponible"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"Cette action va interrompre la connectivité réseau pour tout machine "
-"virtuelle qui dépend de ce réseau."
-
-msgid "Create a network"
-msgstr "Créer un réseau"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Ce réseau n'est pas persistant. Au lieu de s'arrêter, cette actionva le "
-"suppromer de manière permanente. Voulez-vous continuer ?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-"Cela va effacer de manière permanente le pool de stockage. Voulez-vous "
-"continuer ?"
-
-msgid "This storage pool is empty."
-msgstr "Ce pool de stockage est vide."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Cela va formater votre disque et vous allez perdre toutes les données qui "
-"s'y trouvent, êtes-vous sûr de continuer ?"
-
-msgid "SCSI Fibre Channel"
-msgstr "Canal Fibre SCSI"
-
-msgid "No SCSI adapters found."
-msgstr "Aucun adaptateur SCSI trouvé."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "Le nom de pool de stockage ne peut être vierge."
-
-msgid "The storage pool path can not be blank."
-msgstr "Le chemin de pool de stockage ne peut être vierge."
-
-msgid "NFS server mount path can not be blank."
-msgstr "Le chemin de montage du serveur NFS ne peut être vierge."
-
-msgid "Invalid NFS mount path."
-msgstr "Chemin de montage NFS invalide."
-
-msgid "No logical device selected."
-msgstr "Aucun périphérique logique sélectionné."
-
-msgid "The iSCSI target can not be blank."
-msgstr "La cible iSCSI ne peut être vierge."
-
-msgid "Server name can not be blank."
-msgstr "Le nom de serveur ne peut être vierge."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "En cours de recherche de partitions disponibles..."
-
-msgid "No available partitions found."
-msgstr "Aucune partition disponible trouvée."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Le pool de stockage n'est pas persistent. Au lieu de le désactiver, cette "
-"action va le supprimer de manière permanente. Voulez-vous continuer ?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "Impossible de récupérer les informations des partitions."
-
-msgid "In progress..."
-msgstr "En cours..."
-
-msgid "Failed!"
-msgstr "Ãchec!"
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-"Le chemin de CDROM doit être un chemin local/distant valide et ne peut être "
-"virge."
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Le pool de disque ou le volume ne peut être vierge."
-
-#, fuzzy
-msgid "Filter"
-msgstr "Filtre"
-
-msgid "Network Name"
-msgstr "Nom de Réseau"
-
-msgid "State"
-msgstr "Ãtat"
-
-msgid "Network Type"
-msgstr "Type de Réseau"
-
-msgid "Address Space"
-msgstr "Espace d'adressage"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "Le nom ne devrait pas contenir '/' et '\"'."
-
-msgid "Isolated: no external network connection"
-msgstr "Isolé: pas de connexion à un réseau externe"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: connexion physique au réseau sortant uniquement"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Bridgé: Les macines virtuelles sont connectées directement au réseau physique"
-
-msgid "(No interfaces found)"
-msgstr "(Aucune interface trouvée)"
-
-msgid "Destination"
-msgstr "Destination"
-
-msgid "Enable VLAN"
-msgstr "Activer le VLAN"
-
-msgid "VLAN ID"
-msgstr "ID de VLAN"
-
-msgid "Stop"
-msgstr "Arrêter"
-
-msgid "Generate a New Debug Report"
-msgstr "Générer un Nouveau Rapport de Déboggage"
-
-msgid "Report Name"
-msgstr "Nom du Rapport"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"Le nom utilisé pour identifier le rapport. Si omis, un nom sera choisi basé "
-"sur l'heure courante. Le nom peut contenir des lettres, des nombres, le "
-"soulignement (\"_\") et le tiret (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "Renommer un Rapport de Déboggage"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"Le nom utilisé pour identifer le rapport. Le nom peut contenir des lettres, "
-"nombres et tirets (\"-\")."
-
-msgid "Submit"
-msgstr "Soumettre"
-
-msgid "Add a Repository"
-msgstr "Ajouter un Dépôt"
-
-msgid "Identifier"
-msgstr "Identificateur"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Mot unique, identifiant unique pour le dépôt."
-
-msgid "Textual name for the repository."
-msgstr "Nom textuel pour le dépôt."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Champ requis"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL du dépôt. Les protocoles supportés sont http, ftp et ficheir."
-
-msgid "Repository is a mirror"
-msgstr "Le dépôt est un miroir"
-
-msgid "Distribution"
-msgstr "Distribution"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribution du dépôt DEB."
-
-msgid "Components"
-msgstr "Composants"
-
-msgid "List of components in DEB repository."
-msgstr "Liste des composants dans le dépôt DEB."
-
-msgid "Edit Repository"
-msgstr "Editer le Dépôt"
-
-msgid "Mirror List URL"
-msgstr "URL de Liste de Miroir"
-
-msgid "Yes"
-msgstr "Oui"
-
-msgid "No"
-msgstr "Non"
-
-msgid "Capacity"
-msgstr "Capacité"
-
-msgid "Allocated"
-msgstr "Alloué"
-
-msgid "Location"
-msgstr "Emplacement"
-
-msgid "Device path"
-msgstr "Chemin du Périphérique"
-
-msgid "active"
-msgstr "actif"
-
-msgid "inactive"
-msgstr "inactif"
-
-msgid "Deactivate"
-msgstr "Désactiver"
-
-msgid "Activate"
-msgstr "Activer"
-
-msgid "Add Volume"
-msgstr "Ajouter un Volume"
-
-msgid "Extend"
-msgstr "Ãtendre"
-
-msgid "Undefine"
-msgstr "Supprimer"
-
-msgid "Format"
-msgstr "Format"
-
-msgid "Allocation"
-msgstr "Allocation"
-
-msgid "Define a New Storage Pool"
-msgstr "Définir un Nouveau Pool de Stockage"
-
-msgid "Storage Pool Name"
-msgstr "Nom de Pool de Stockage"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"Le nom utilisé pour identifier les pools de stockage, et il ne doit pas être "
-"vide."
-
-msgid "Storage Pool Type"
-msgstr "Type de Pool de Stockage"
-
-msgid "Storage Path"
-msgstr "Chemin de Stockage"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"Le chemin du Pool de Stockage. Chaque Pool de Stockage doit avoir un chemin "
-"unique."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"Kimchi va essayer de créer un répertoire quand il n'existe pas déjà dans "
-"votre système."
-
-msgid "NFS Server IP"
-msgstr "IP du Serveur NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP du Serveur NFS ou nom d'hôte. Il peut être saisi ou entré à partir de "
-"l'historique."
-
-msgid "NFS Path"
-msgstr "Chemin NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "Le chemin NFS exporté sur le serveur NFS."
-
-msgid "iSCSI Server"
-msgstr "Serveur iSCSI"
-
-msgid "Server"
-msgstr "Serveur"
-
-msgid "Port"
-msgstr "Port"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP du Serveur iSCSI ou nom d'hôte. Il ne devrait pas être vide."
-
-msgid "Target"
-msgstr "Cible"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "La cible iSCSI sur le serveur iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "Ajouter l'Authentification iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Authentification iSCSI"
-
-msgid "User Name"
-msgstr "Nom d'Utilisateur"
-
-msgid "Password"
-msgstr "Mot de Passe"
-
-msgid "SCSI Adapter"
-msgstr "Adaptateur SCSI"
-
-msgid "Please, wait..."
-msgstr "Veuillez patienter..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr "iAjouter un Volume au Pool de Stockage"
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr "Saisir une URL distante ici"
-
-msgid "Upload a file"
-msgstr "Charger un fichier"
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "Ajouter un Modèle"
-
-msgid "Where is the source media for this template? "
-msgstr "Où se trouve le media source pour le modèle ?"
-
-msgid "Local ISO Image"
-msgstr "Image ISO Locale"
-
-msgid "Local Image File"
-msgstr "Fichier Image Local"
-
-msgid "Remote ISO Image"
-msgstr "Image ISO Distante"
-
-msgid "Search ISOs"
-msgstr "Rechercher des ISOs"
-
-msgid "The following ISOs are available:"
-msgstr "Les ISOs suivants sont disponibles:"
-
-msgid "OS: "
-msgstr "OS: "
-
-msgid "Version: "
-msgstr "Version: "
-
-msgid "Size: "
-msgstr "Taille: "
-
-msgid "Search more ISOs"
-msgstr "Chercher plus d'ISOs"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Créer des modèles depuis l'ISO sélectionné"
-
-msgid "I want to use a specific ISO file"
-msgstr "Je veux utiliser un fichier ISO spécifique"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Chargement des ISOs distants par défaut en cours..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Je veux utiliser une URL personnalisée"
-
-msgid "Edit Template"
-msgstr "Ãditer un Modèle"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr "Fichier Image"
-
-msgid "Graphics"
-msgstr "Graphiques"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "Nombre de CPU"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "Aucun modèle trouvé."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "La suppression n'est pas autorisée pour %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s n'implémente pas de méthode de mise à jour"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "La création n'est pas autorisée pour %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "Impossible de parser la requête JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Cette API supporte uniquement le JSON"
-
-#~ msgid "Parameters does not match requirement in schema: %(err)s"
-#~ msgstr ""
-#~ "Les paramètres ne correspondent pas à ce qui est requis dans le schéma: %"
-#~ "(err)s"
-
-#~ msgid "You don't have permission to perform this operation."
-#~ msgstr "Vous n'avez pas la permission d'effectuer cette opération."
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Le magasin de données n'est pas initié dans l'objet modèle."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "Impossible de démarrer la tâche à cause de l'erreur: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr ""
-#~ "L'authentification a échoué pour l'utilisateur '%(username)s'. [Code "
-#~ "d'Erreur: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Vous n'êtes pas autorisé à accéder à Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Spécifiez %(item)s pour vous logguer dans Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "Impossible de trouver %(item)s dans le magasin de données"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr ""
-#~ "Timeout durant l'exécution de la commande '%(cmd)s' après %(seconds)s "
-#~ "secondes"
-
-#~ msgid "Help"
-#~ msgstr "Aide"
-
-#~ msgid "About"
-#~ msgstr "A propos..."
-
-#~ msgid "Log out"
-#~ msgstr "Se déconnecter"
-
-#~ msgid "Version:"
-#~ msgstr "Version:"
-
-#~ msgid "Session timeout, please re-login."
-#~ msgstr "Session expirée, veuillez vous reconnecter."
diff --git a/plugins/kimchi/po/gen-pot.in b/plugins/kimchi/po/gen-pot.in
deleted file mode 100644
index 0e3cd10..0000000
--- a/plugins/kimchi/po/gen-pot.in
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-for src in $@; do
- if [ ${src: -3} == ".py" ]; then
- cat $src
- else
- cat $src | @CHEETAH@ compile -
- fi
-done | xgettext --no-location -o kimchi.pot -L Python -
diff --git a/plugins/kimchi/po/it_IT.po b/plugins/kimchi/po/it_IT.po
deleted file mode 100644
index 257c306..0000000
--- a/plugins/kimchi/po/it_IT.po
+++ /dev/null
@@ -1,2274 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: it_IT\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-"Errore durante il richiamo dei dispositivi del blocco. Dettagli: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"Errore durante il richiamo delle informazioni sul dispositivo del blocco per "
-"%(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Impossibile trovare il file distro: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"Impossibile analizzare il file distro: %(filename)s. Verificare che sia un "
-"file JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"Impossibile accedere a %(portal)s di destinazione host iSCSI. Dettagli: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Impossibile accedere alla destinazione %(target)s host %(host)s iSCSI"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "Il file ISO %(filename)s non è avviabile"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "Il file ISO %(filename)s non ha un record di avvio El Torito valido"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Voce di convalida El Torito non valida in ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicatore di avvio El Torito non valido in ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "Tipo di volume imprevisto per il volume primario in ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Formato non corretto durante la lettura del descrittore volume in ISO %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"L'hypervisor non dispone dell'autorizzazione per utilizzare questo ISO %"
-"(filename)s. Spostarlo in /var/lib/libvirt o impostare l'autorizzazione di "
-"ricerca per gli elenchi di controllo accesso ai file per l'utente '%(user)"
-"s', se possibile, o aggiungere '%(user)s' al gruppo percorso ISO o (non "
-"consigliato) 'chmod -R o+x 'path_to_iso'. Dettagli: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "Macchina virtuale %(name)s già esistente"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "La macchina virtuale %(name)s non esiste"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Impossibile richiamare l'immagine per la macchina virtuale arrestata %(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "L'immagine ISO remota non è supportata da questo server."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossibile richiamare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"L'indirizzo dei grafici su cui rimanere in ascolto deve essere IPv4 o IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Specificare un modello da cui creare una macchina virtuale"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile eliminare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossibile ridenominare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "Il nome della rete deve essere una stringa"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "Il nome della rete deve essere una stringa"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "L'utente '%(users)s' non esiste."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "L'utente '%(groups)s' non esiste."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "L'interfaccia %(iface)s non esiste nella macchina virtuale %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"La rete %(network)s specificata per la macchina virtuale %(name)s non esiste"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-"Il tipo supportato per le interfacce della macchina virtuale è solo rete"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"Il nome di rete per l'interfaccia della macchina virtuale deve essere una "
-"stringa"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Scheda modello di rete non valida per l'interfaccia della macchina virtuale"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Specificare il tipo e la rete per aggiungere una nuova interfaccia della "
-"macchina virtuale"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Modello %(name)s già esistente"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr ""
-"La rete '%(network)s' specificata per il modello %(template)s non esiste"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Il pool di memoria %(pool)s specificato per il modello %(template)s non "
-"esiste"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-"Il pool di memoria %(pool)s specificato per il modello %(template)s non è "
-"attivo"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Parametro non valido %(param)s' specificato per CDROM."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"La rete %(network)s specificata per il modello %(template)s non è attiva"
-
-msgid "Template name must be a string"
-msgstr "Il nome del modello deve essere una stringa"
-
-msgid "Template icon must be a path to the image"
-msgstr "L'icona del modello deve essere un percorso all'immagine"
-
-msgid "Template distribution must be a string"
-msgstr "La distribuzione del modello deve essere una stringa"
-
-msgid "Template distribution version must be a string"
-msgstr "La versione della distribuzione del modello deve essere una stringa"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "Il numero di CPU deve essere un numero intero"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr ""
-"La quantità di memoria (MB) deve essere un numero intero maggiore di 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "URI pool di memoria non valido: %(value)s specificato per il modello"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "Specificare un'immagine ISO come CDROM per creare un modello"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Tutte le reti per il modello devono essere specificate in un elenco."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "Impossibile creare il modello a causa dell'errore: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "Impossibile eliminare il modello a causa dell'errore: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Pool di memoria %(name)s già esistente"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Il pool di memoria %(name)s non esiste"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Specificare %(item)s per poter creare il pool di memoria %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Impossibile eliminare il pool di memoria attivo %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Impossibile elencare i pool di memoria. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile creare il pool di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Impossibile ottenere il numero di volumi di memoria nel pool di memoria %"
-"(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile attivare il pool di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile disattivare il pool di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile eliminare il pool di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"Impossibile creare il pool NFS poiché il percorso di esportazione %(path)s "
-"potrebbe bloccarsi durante il montaggio"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"Impossibile creare il pool NFS poiché il montaggio del percorso di "
-"esportazione %(path)s ha avuto esito negativo"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Tipo di pool di memoria non supportato: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "Il percorso del pool di memoria deve essere una stringa"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "L'host del pool di memoria deve essere un nome host o IP"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Il parametro dispositivi pool di memoria deve essere un elenco"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "L'IQN di destinazione di un pool iSCSI deve essere una stringa"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"La porta di un server di memoria remoto deve essere un numero intero tra 1 e "
-"65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Specificare nome e tipo per creare un pool di memoria"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s non è un disco/partizione valido. Impossibile aggiungerlo al pool %"
-"(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Solo il parametro dischi può essere aggiornato per il pool di memoria logico."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "Il nome adattatore host SCSI deve essere una stringa."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "Il pool di memoria kimchi_isos è riservato per uso interno"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossibile attivare il pool di memoria NFS %(name)s. Il server NFS %(server)"
-"s è irraggiungibile."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossibile disattivare il pool di memoria NFS %(name)s. Il server NFS %"
-"(server)s è irraggiungibile."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossibile disattivare il pool %(name)s poiché è associato ad alcuni modelli"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossibile eliminare il pool %(name)s poiché è associato ad alcuni modelli"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"Un gruppo di volumi denominato '%(name)s' esiste già . Scegliere un altro "
-"nome per creare il pool logico."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"Impossibile aggiornare il database con informazioni approfondite sulla "
-"scansione a causa dell'errore: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Volume di memoria %(name)s già esistente"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "Il volume di memoria %(name)s non esiste nel pool di memoria %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Specificare %(item)s per poter creare il volume di memoria %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"Impossibile elencare i volumi di memoria poiché il pool di memoria %(pool)s "
-"non è attivo"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"Impossibile creare il volume di memoria %(name)s nel pool di memoria %(pool)"
-"s. Dettagli: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Impossibile elencare i volumi di memoria nel pool di memoria %(pool)s. "
-"Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "Impossibile ripulire i volumi di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "Impossibile eliminare il volume di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Impossibile ridimensionare il volume di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"Il tipo di memoria %(type)s non supporta la creazione ed eliminazione del "
-"volume"
-
-msgid "Storage volume name must be a string"
-msgstr "Il nome del volume di memoria deve essere una stringa"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "L'assegnazione del volume di memoria deve essere un numero intero"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "Il volume di memoria richiede un nome volume"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Impossibile aggiornare il database con informazioni sul volume di memoria a "
-"causa dell'errore: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "L'interfaccia %(name)s non esiste"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Rete %(name)s già esistente"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "La rete %(name)s non esiste"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"La sottorete %(subnet)s specificata per la rete %(network)s non è valida ."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"Specificare un'interfaccia di rete per creare la rete con bridge %(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Impossibile eliminare la rete attiva %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-"L'interfaccia %(iface)s specificata per la rete %(network)s è già in uso"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-"L'interfaccia deve essere un dispositivo bridge o di collegamento NIC bare-"
-"metal."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Impossibile creare la rete %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Impossibile trovare un indirizzo IP libero per la rete '%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "L'interfaccia %(iface)s già esistente."
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "I tipi di rete supportati sono isolata, NAT e bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"La sottorete della rete deve essere una stringa con indirizzo IP e prefisso "
-"o maschera di rete"
-
-msgid "Network interface must be a string"
-msgstr "L'interfaccia di rete deve essere una stringa"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "L'ID VLAN di rete deve essere un numero intero tra 1 e 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Specificare nome e tipo per creare una rete"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"Impossibile eliminare la rete %(name)s. Ci sono alcune macchine virtuali %"
-"(vms)s e/o modelli collegati a tale rete."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"Impossibile disattivare la rete %(name)s. Ci sono alcune macchine virtualie %"
-"(vms)s e/o modelli collegati a tale rete."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"Il dispositivo bridge %(name)s non può essere il dispositivo trunk di una "
-"VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "Impossibile attivare l'interfaccia %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"Impossibile attivare l'interfaccia %(iface)s. Controllare lo stato del link "
-"fisico."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Il report di debug %(name)s non esiste"
-
-msgid "Debug report tool not found in system"
-msgstr "Strumento report di debug non trovato nel sistema"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "Impossibile creare il report di debug %(name)s. Dettagli: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "Impossibile generare il report di debug %(name)s. Dettagli: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"Un gruppo di volumi denominato '%(name)s' esiste già . Scegliere un altro "
-"nome per creare il pool logico."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Il server di memoria %(server)s non è stato utilizzato da Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' non esistente"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "La partizione %(name)s non esiste nell'host"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Impossibile arrestare la macchina host poiché sono presenti macchine "
-"virtuali in esecuzione"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"Impossibile riavviare la macchina host poiché sono presenti macchine "
-"virtuali in esecuzione"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "Dispositivo nodo '%(name)s' non trovato"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "Nessun pacchetto contrassegnato per l'aggiornamento"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Il pacchetto %(name)s non è contrassegnato per l'aggiornamento."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Errore durante il richiamo dei pacchetti contrassegnati per l'aggiornamento. "
-"Dettagli: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "Non è presente un gestore pacchetti compatibile per questo sistema."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s non valido"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Tipo di memoria non valido. I tipi supportati sono: 'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"Errore durante la creazione del nuovo dispositivo di memoria: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Errore durante l'aggiornamento del dispositivo di memoria: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Errore durante la rimozione del dispositivo di memoria: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
-"virtuale"
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-"Specificare il percorso per aggiornare il disco della macchina virtuale"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
-"virtuale"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "L'ID repository YUM deve essere una stringa di una sola parola."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "L'URL del repository deve essere http://, ftp:// o file:// URL."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"La configurazione del repository è un dizionario con valori specifici in "
-"base al tipo di repository."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "La distribuzione al repository DEB deve essere una stringa"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "I componenti per il repository DEB devono essere elencati in un array"
-
-msgid "Components to DEB repository must be a string"
-msgstr "I componenti per il repository DEB devono essere una stringa"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Il nome del repository YUM deve essere una stringa."
-
-msgid "GPG check must be a boolean value."
-msgstr "Il controllo GPG deve essere un valore booleano."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "La chiave GPG deve essere un URL che punta al file blindato ASCII."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Impossibile aggiornare il repository %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Il repository %(repo_id)s non esiste."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-"Lo strumento di gestione del repository non è stato riconosciuto per il "
-"sistema."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Il repository %(repo_id)s è già abilitato."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Il repository %(repo_id)s è già disabilitato."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Impossibile rimuovere il repository %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"Impossibile scrivere il file di configurazione del repository %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Specificare la distribuzione del repository per poter creare un repository "
-"DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Impossibile abilitare il repository %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Impossibile disabilitare il repository %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "ID repository YUM già esistente"
-
-msgid "YUM Repository name must be a string"
-msgstr "Il nome del repository YUM deve essere una stringa"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Impossibile elencare i repository. Dettagli: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-"Impossibile richiamare le informazioni sul repository. Dettagli: '%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Impossibile aggiungere il repository. Dettagli: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Impossibile rimuovere il repository. Dettagli: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "CODICE DI ERRORE"
-
-msgid "REASON"
-msgstr "CAUSA"
-
-msgid "STACK"
-msgstr "STACK"
-
-msgid "Go to Homepage"
-msgstr "Vai alla home page"
-
-msgid "Create a New Virtual Machine"
-msgstr "Crea una nuova macchina virtuale"
-
-msgid "Virtual Machine Name"
-msgstr "Nome macchina virtuale"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"Il nome utilizzato per identificare la macchina virtuale. Se il nome viene "
-"omesso ne verrà scelto uno in base al modello utilizzato."
-
-msgid "Template"
-msgstr "Modello"
-
-msgid "Please create a template first."
-msgstr "Creare prima un modello."
-
-msgid "Create a Template"
-msgstr "Crea un modello"
-
-msgid "Please choose a template."
-msgstr "Scegliere un modello."
-
-msgid "OS"
-msgstr "SO"
-
-msgid "OS Version"
-msgstr "Versione SO"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Memoria"
-
-msgid "Create"
-msgstr "Crea"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "Annulla"
-
-msgid "Edit Guest"
-msgstr "Modifica guest"
-
-msgid "General"
-msgstr "Generale"
-
-msgid "Storage"
-msgstr "Memoria"
-
-msgid "Interface"
-msgstr "Interfaccia"
-
-msgid "Permission"
-msgstr "Versione"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Nome"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "Memoria"
-
-msgid "Icon"
-msgstr "Icona"
-
-msgid "Device"
-msgstr "Nome dispositivo"
-
-msgid "Path"
-msgstr "Percorso NFS"
-
-msgid "Network"
-msgstr "Rete"
-
-msgid "Type"
-msgstr "Tipo"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Tutti"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "Fornitore"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Salva"
-
-msgid "Replace"
-msgstr "Sostituisci"
-
-msgid "Detach"
-msgstr "Scollega"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "Avvia"
-
-msgid "Reset"
-msgstr "Reimposta"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "Azioni"
-
-msgid "Connect"
-msgstr "Connetti"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "Modifica"
-
-msgid "Shut Down"
-msgstr "Arresta"
-
-msgid "Delete"
-msgstr "Elimina"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "I/O disco"
-
-msgid "Network I/O"
-msgstr "I/O di rete"
-
-msgid "Livetile"
-msgstr "Riquadro animato"
-
-msgid "No guests found."
-msgstr "Nessuna macchina guest trovata."
-
-msgid "Add a Storage Device to VM"
-msgstr "Aggiungi un dispositivo di memoria alla VM"
-
-msgid "Device Type"
-msgstr "Tipo dispositivo"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "Il tipo di dispositivo. Attualmente, è supportato solo \"cdrom\"."
-
-msgid "Storage Pool"
-msgstr "Pool di memoria"
-
-msgid "Storage pool which volume located in"
-msgstr "Il percorso del pool di memoria deve essere una stringa"
-
-msgid "Storage Volume"
-msgstr "Nome pool di memoria"
-
-msgid "Storage volume to be attached"
-msgstr "Il nome del volume di memoria deve essere una stringa"
-
-msgid "File Path"
-msgstr "Percorso file"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "Il percorso file ISO nel server per CDROM."
-
-msgid "Attach"
-msgstr "Allega"
-
-msgid "Shut down"
-msgstr "Arresta"
-
-msgid "Restart"
-msgstr "Riavvia"
-
-msgid "Basic Information"
-msgstr "Informazioni di base"
-
-msgid "OS Distro"
-msgstr "Distro SO"
-
-msgid "OS Code Name"
-msgstr "Nome codice SO"
-
-msgid "Processor"
-msgstr "Processore"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "Statistiche di sistema"
-
-msgid "Software Updates"
-msgstr "Aggiornamenti del software"
-
-msgid "Update Progress"
-msgstr "Avanzamento aggiornamento"
-
-msgid "Repositories"
-msgstr "Repository"
-
-msgid "Debug Reports"
-msgstr "Report di debug"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"Il nome utente o la password immessi non sono corretti. Ripetere "
-"l'operazione."
-
-msgid "This field is required."
-msgstr "Questo campo è obbligatorio."
-
-msgid "Log in"
-msgstr "Accedi"
-
-msgid "Logging in..."
-msgstr "Accesso in corso..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "Guest"
-
-msgid "Templates"
-msgstr "Modelli"
-
-msgid "Failed to get application configuration"
-msgstr "Richiamo della configurazione dell'applicazione non riuscito"
-
-msgid "This is not a valid Linux path"
-msgstr "Non è un percorso Linux valido"
-
-msgid "This is not a valid URL."
-msgstr "Non è un URL valido."
-
-msgid "No such data available."
-msgstr "Dati indicati non disponibili."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"Impossibile contattare il sistema host. Verificare che il sistema host sia "
-"attivo e che si disponga della connettività di rete per tale sistema. "
-"Risposta alla richiesta HTTP %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Conferma"
-
-msgid "Warning"
-msgstr "Avvertenza"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Caricamento in corso..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Riprova"
-
-msgid "Detailed message:"
-msgstr "Messaggio dettagliato:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "Non è un file ISO valido."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Richiederà molto tempo. Continuare?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "L'azione eliminerà permanentemente il modello. Continuare?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"Impossibile arrestare il sistema poiché sono in esecuzione alcune macchine "
-"virtuali."
-
-msgid "Max:"
-msgstr "Massimo:"
-
-msgid "Utilization"
-msgstr "Utilizzo"
-
-msgid "Available"
-msgstr "Disponibile"
-
-msgid "Read Rate"
-msgstr "Velocità di lettura"
-
-msgid "Write Rate"
-msgstr "Velocità di scrittura"
-
-msgid "Received"
-msgstr "Ricevuti"
-
-msgid "Sent"
-msgstr "Inviati"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"L'arresto o il riavvio dell'host provocherà la perdita del lavoro non "
-"salvato. Continuare con l'arresto o il riavvio?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Il repository verrà rimosso permanentemente e non potrà essere ripristinato. "
-"Si desidera continuare?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL di base"
-
-msgid "Is Mirror"
-msgstr "Ã speculare"
-
-msgid "URL Args"
-msgstr "Argomenti URL"
-
-msgid "Enabled"
-msgstr "Abilitato"
-
-msgid "GPG Check"
-msgstr "Controllo GPG"
-
-msgid "GPG Key"
-msgstr "Chiave GPG"
-
-msgid "Add"
-msgstr "Aggiungi"
-
-msgid "Remove"
-msgstr "Rimuovi"
-
-msgid "Enable"
-msgstr "Abilita"
-
-msgid "Disable"
-msgstr "Disabilita"
-
-msgid "Package Name"
-msgstr "Nome pacchetto"
-
-msgid "Version"
-msgstr "Versione"
-
-msgid "Architecture"
-msgstr "Architettura"
-
-msgid "Repository"
-msgstr "Repository"
-
-msgid "Update All"
-msgstr "Aggiorna tutto"
-
-msgid "Updating..."
-msgstr "Aggiornamento in corso..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "Aggiornamento dei pacchetti non riuscito."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Il report del debug verrà rimosso permanentemente e non potrà essere "
-"ripristinato. Si desidera continuare?"
-
-msgid "Generated Time"
-msgstr "Ora di creazione"
-
-msgid "Generate"
-msgstr "Crea"
-
-msgid "Generating..."
-msgstr "Creazione in corso..."
-
-msgid "Rename"
-msgstr "Ridenomina"
-
-msgid "Download"
-msgstr "Scarica"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr ""
-"Il nome del report può contenere solo lettere, cifre e/o trattini ('-')."
-
-msgid "Pending..."
-msgstr "Caricamento in corso..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"L'operazione eliminerà la macchina virtuale e i relativi dischi virtuali e "
-"non è reversibile. Continuare?"
-
-msgid "Power off Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "L'azione eliminerà permanentemente il modello. Continuare?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Il CDROM verrà scollegato permanentemente e non sarà possibile ricollegarlo. "
-"Continuare con lo scollegamento?"
-
-msgid "Attaching..."
-msgstr "Collegamento in corso..."
-
-msgid "Replacing..."
-msgstr "Sostituzione in corso..."
-
-msgid "Successfully attached!"
-msgstr "Collegamento riuscito."
-
-msgid "Successfully replaced!"
-msgstr "Sostituzione riuscita."
-
-msgid "Successfully detached!"
-msgstr "Scollegamento riuscito."
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "L'ID VLAN deve essere compreso tra 1 e 4094."
-
-msgid "unavailable"
-msgstr "non disponibile"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"L'azione interromperà la connettività di rete per qualsiasi macchina "
-"virtuale che dipende da questa rete."
-
-msgid "Create a network"
-msgstr "Crea una rete"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Il pool di memoria non è permanente. Invece di disattivarlo, l'azione lo "
-"eliminerà permanentemente. Continuare?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "L'azione eliminerà permanentemente il pool di memoria. Continuare?"
-
-msgid "This storage pool is empty."
-msgstr "Il pool di memoria è vuoto."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Il disco verrà formattato e tutti i dati su di esso andranno persi, sicuri "
-"di voler continuare? "
-
-msgid "SCSI Fibre Channel"
-msgstr "Canale a fibre ottiche SCSI"
-
-msgid "No SCSI adapters found."
-msgstr "Nessun adattatore SCSI trovato."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "Il campo per il nome del pool di memoria non può essere vuoto."
-
-msgid "The storage pool path can not be blank."
-msgstr "Il campo per il percorso del pool di memoria non può essere vuoto."
-
-msgid "NFS server mount path can not be blank."
-msgstr ""
-"Il campo per il percorso di montaggio del server NFS non può essere vuoto."
-
-msgid "Invalid NFS mount path."
-msgstr "Percorso di montaggio NFS non valido."
-
-msgid "No logical device selected."
-msgstr "Nessun dispositivo logico selezionato."
-
-msgid "The iSCSI target can not be blank."
-msgstr "Il campo per la destinazione iSCSI non può essere vuoto."
-
-msgid "Server name can not be blank."
-msgstr "Il campo per il nome del server non può essere vuoto."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "Ricerca di partizioni disponibili in corso..."
-
-msgid "No available partitions found."
-msgstr "Nessuna partizione disponibile trovata."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Il pool di memoria non è permanente. Invece di disattivarlo, l'azione lo "
-"eliminerà permanentemente. Continuare?"
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-"Impossibile richiamare le informazioni sul repository. Dettagli: '%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Il campo per il nome del pool di memoria non può essere vuoto."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "Nome rete"
-
-msgid "State"
-msgstr "Stato"
-
-msgid "Network Type"
-msgstr "Tipo di Rete"
-
-msgid "Address Space"
-msgstr "Spazio indirizzo"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "Nome pool di memoria non valido. Non deve contenere '/'."
-
-msgid "Isolated: no external network connection"
-msgstr "Isolata: nessuna connessione di rete fisica"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: solo connessione di rete fisica in uscita"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Con bridge: le macchine virtuali sono connesse direttamente alla rete fisica"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "Destinazione:"
-
-msgid "Enable VLAN"
-msgstr "Abilita VLAN:"
-
-msgid "VLAN ID"
-msgstr "ID VLAN:"
-
-msgid "Stop"
-msgstr "Arresta"
-
-msgid "Generate a New Debug Report"
-msgstr "Crea un nuovo report di debug"
-
-msgid "Report Name"
-msgstr "Nome report"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
-"viene scelto uno in base all'ora corrente. Il nome può contenere lettere, "
-"cifre e trattini (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "Crea un nuovo report di debug"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
-"viene scelto uno in base all'ora corrente. Il nome può contenere lettere, "
-"cifre e trattini (\"-\")."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "Aggiungi un repository"
-
-msgid "Identifier"
-msgstr "Identificativo"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Identificativo univoco di una sola parola per il repository."
-
-msgid "Textual name for the repository."
-msgstr "Nome in formato testo per il repository."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Campo obbligatorio"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL al repository. I protocolli supportati sono http, ftp e file."
-
-msgid "Repository is a mirror"
-msgstr "Il repository è un elemento speculare."
-
-msgid "Distribution"
-msgstr "Distribuzione"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribuzione del repository DEB."
-
-msgid "Components"
-msgstr "Componenti"
-
-msgid "List of components in DEB repository."
-msgstr "Elenco di componenti nel repository DEB."
-
-msgid "Edit Repository"
-msgstr "Modifica repository"
-
-msgid "Mirror List URL"
-msgstr "URL elenco elementi speculari"
-
-msgid "Yes"
-msgstr "Sì"
-
-msgid "No"
-msgstr "No"
-
-msgid "Capacity"
-msgstr "Capacità "
-
-msgid "Allocated"
-msgstr "Assegnato"
-
-msgid "Location"
-msgstr "Ubicazione"
-
-msgid "Device path"
-msgstr "Percorso dispositivo"
-
-msgid "active"
-msgstr "attivo"
-
-msgid "inactive"
-msgstr "non attivo"
-
-msgid "Deactivate"
-msgstr "Disattiva"
-
-msgid "Activate"
-msgstr "Attiva"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "Rimuovi definizione"
-
-msgid "Format"
-msgstr "Formato:"
-
-msgid "Allocation"
-msgstr "Allocazione:"
-
-msgid "Define a New Storage Pool"
-msgstr "Definisci un nuovo pool di memoria"
-
-msgid "Storage Pool Name"
-msgstr "Nome pool di memoria"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"Il nome utilizzato per identificare i pool di memoria; il campo non deve "
-"essere vuoto."
-
-msgid "Storage Pool Type"
-msgstr "Tipo di pool di memoria"
-
-msgid "Storage Path"
-msgstr "Percorso di memoria"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"Il percorso del pool di memoria. Ogni pool di memoria deve avere un percorso "
-"univoco."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"Kimchi tenterà di creare la directory nel caso non esista ancora sul sistema."
-
-msgid "NFS Server IP"
-msgstr "IP server NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"Il nome host o l'indirizzo IP del server NFS. Ã possibile immetterlo o "
-"sceglierlo dalla cronologia."
-
-msgid "NFS Path"
-msgstr "Percorso NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "Il percorso esportato NFS sul server NFS."
-
-msgid "iSCSI Server"
-msgstr "Server iSCSI"
-
-msgid "Server"
-msgstr "Server"
-
-msgid "Port"
-msgstr "Porta"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr ""
-"Il nome host o l'indirizzo IP del server iSCSI. Il campo non deve essere "
-"vuoto."
-
-msgid "Target"
-msgstr "Destinazione"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "La destinazione iSCSI sul server iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "Aggiungi autenticazione iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Autenticazione iSCSI"
-
-msgid "User Name"
-msgstr "Nome utente"
-
-msgid "Password"
-msgstr "Password"
-
-msgid "SCSI Adapter"
-msgstr "Adattatore SCSI"
-
-msgid "Please, wait..."
-msgstr "Attendere..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "Aggiungi modello"
-
-msgid "Where is the source media for this template? "
-msgstr "Dov'è il supporto di origine per questo modello?"
-
-msgid "Local ISO Image"
-msgstr "Immagine ISO locale"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "Immagine ISO remota"
-
-msgid "Search ISOs"
-msgstr "Ricerca ISO"
-
-msgid "The following ISOs are available:"
-msgstr "Sono disponibili i seguenti file ISO:"
-
-msgid "OS: "
-msgstr "SO: "
-
-msgid "Version: "
-msgstr "Versione: "
-
-msgid "Size: "
-msgstr "Dimensione: "
-
-msgid "Search more ISOs"
-msgstr "Ricerca più ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Crea modelli da ISO selezionato"
-
-msgid "I want to use a specific ISO file"
-msgstr "Utilizzare un file ISO specifico"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Caricamento di ISO remoti predefiniti in corso..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Utilizzare un URL personalizzato"
-
-msgid "Edit Template"
-msgstr "Modifica modello"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "Grafici"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "Numero CPU"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "Nessun modello trovato."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "Eliminazione non consentita per %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s non implementa il metodo di aggiornamento"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Creazione non consentita per %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "Impossibile analizzare la richiesta JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "L'API supporta solo JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Archivio dati non inizializzato nell'oggetto modello."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "Impossibile avviare l'attività a causa dell'errore: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr ""
-#~ "Autenticazione non riuscita per l'utente '%(username)s'. [Codice di "
-#~ "errore: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Non si dispone dell'autorizzazione ad accedere a Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Specificare %(item)s per accedere a Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "Impossibile trovare %(item)s nell'archivio dati"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr ""
-#~ "Ã stato raggiunto il timeout durante l'esecuzione del comando '%(cmd)s' "
-#~ "dopo %(seconds)s secondi"
-
-#~ msgid "Help"
-#~ msgstr "Guida"
-
-#~ msgid "About"
-#~ msgstr "Info su"
-
-#~ msgid "Log out"
-#~ msgstr "Disconnetti"
-
-#~ msgid "Version:"
-#~ msgstr "Versione:"
diff --git a/plugins/kimchi/po/ja_JP.po b/plugins/kimchi/po/ja_JP.po
deleted file mode 100644
index a3d3be3..0000000
--- a/plugins/kimchi/po/ja_JP.po
+++ /dev/null
@@ -1,2269 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ja_JP\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-"ãããã¯ã»ããã¤ã¹ãåå¾ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"%(device)s ã®ãããã¯ã»ããã¤ã¹æ
å ±ãåå¾ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ããã"
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã»ãã¡ã¤ã« %(filename)s ãè¦ã¤ããã¾ãã"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã»ãã¡ã¤ã« %(filename)s ãè§£æã§ãã¾ãããJSON ãã¡ã¤ã«"
-"ã§ãããã¨ã確èªãã¦ãã ããã"
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"iSCSI ãã¹ãã»ã¿ã¼ã²ãã %(portal)s ã«ãã°ã¤ã³ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "iSCSI ãã¹ã %(host)s ã¿ã¼ã²ãã %(target)s ã«ãã°ã¤ã³ã§ãã¾ãã"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISO ãã¡ã¤ã« %(filename)s ã¯ããã¼ãå¯è½ã§ã¯ããã¾ãã"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"ISO ãã¡ã¤ã« %(filename)s ã«ã¯ãæå¹ãª El Torito ãã¼ãã»ã¬ã³ã¼ããããã¾ãã"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "ç¡å¹ãª El Torito æ¤è¨¼ã¨ã³ããªã¼ã ISO %(filename)s ã«ããã¾ã"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ç¡å¹ãª El Torito ãã¼ãã»ã¤ã³ã¸ã±ã¼ã¿ã¼ã ISO %(filename)s ã«ããã¾ã"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"1 次ããªã¥ã¼ã ã®äºæããªãããªã¥ã¼ã ã»ã¿ã¤ãã ISO %(filename)s ã«ããã¾ã"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"ããªã¥ã¼ã ã»ãã£ã¹ã¯ãªãã¿ã¼ã ISO %(filename)s ããèªã¿åã£ã¦ãã¾ãããã"
-"ãã©ã¼ãããã䏿£ã§ãã"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"ãã¤ãã¼ãã¤ã¶ã¼ã«ãã® ISO %(filename)s ã使ç¨ããæ¨©éãããã¾ããã/var/lib/"
-"libvirt ã®ä¸ã«ç§»åããããå¯è½ã§ããã°æ¤ç´¢è¨±å¯ãã%(user)sãã¦ã¼ã¶ã¼ã®ãã¡ã¤"
-"ã«ã»ã¢ã¯ã»ã¹å¶å¾¡ãªã¹ãã«è¨å®ããããã%(user)sããISO ãã¹ã»ã°ã«ã¼ãã«è¿½å ã"
-"ãããã¾ãã¯ãchmod -R o+x path_to_isoããå®è¡ (æ¨å¥¨ããã¾ãã) ãã¦ãã ã"
-"ãã詳細: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "ä»®æ³ãã·ã³ %(name)s ã¯æ¢ã«åå¨ãã¾ã"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "ä»®æ³ãã·ã³ %(name)s ã¯åå¨ãã¾ãã"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "忢ãã¦ããä»®æ³ãã·ã³ %(name)s ã®ã¹ã¯ãªã¼ã³ã»ã·ã§ãããåå¾ã§ãã¾ãã"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "ãªã¢ã¼ã ISO ã¤ã¡ã¼ã¸ã¯ããã®ãµã¼ãã¼ã§ã¯ãµãã¼ãããã¦ãã¾ããã"
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ãåå¾ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"listen ãè¡ãã°ã©ãã£ãã¯ã¹ã»ã¢ãã¬ã¹ã¯ãIPv4 ã¾ã㯠IPv6 ã§ãªããã°ãªãã¾ã"
-"ã"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "ä»®æ³ãã·ã³ã®ä½æå
ã¨ãªããã³ãã¬ã¼ããæå®ãã¦ãã ãã"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ãå§åã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ã忢ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ãåé¤ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ãåå夿´ã§ãã¾ããã詳細: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "ãããã¯ã¼ã¯åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "ãããã¯ã¼ã¯åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "ã¦ã¼ã¶ã¼ã%(users)sãã¯åå¨ãã¾ããã"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "ã¦ã¼ã¶ã¼ã%(groups)sãã¯åå¨ãã¾ããã"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ã忢ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "ä»®æ³ãã·ã³ %(name)s ãå§åã§ãã¾ããã詳細: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã¯ä»®æ³ãã·ã³ %(name)s ã«ã¯åå¨ãã¾ãã"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"ä»®æ³ãã·ã³ %(name)s ç¨ã«æå®ããã¦ãããããã¯ã¼ã¯ %(network)s ã¯åå¨ãã¾ãã"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-"ãµãã¼ãããã¦ããä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã»ã¿ã¤ãã¯ããããã¯ã¼ã¯ã ãã§"
-"ã"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"ä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã®ãããã¯ã¼ã¯åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"ç¡å¹ãªãããã¯ã¼ã¯ã»ã¢ãã«ã»ã«ã¼ããä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã«æå®ããã¦"
-"ãã¾ã"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"æ°ããä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã«è¿½å ããã¿ã¤ãããã³ãããã¯ã¼ã¯ãæå®ã"
-"ã¾ã"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "ãã³ãã¬ã¼ã %(name)s ã¯æ¢ã«åå¨ãã¾ã"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr ""
-"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ãããããã¯ã¼ã¯ã%(network)sãã¯åå¨"
-"ãã¾ãã"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ããã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã¯å"
-"å¨ãã¾ãã"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ããã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã¯ã¢"
-"ã¯ãã£ãã§ã¯ããã¾ãã"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "CDROM ã«æå®ããã¦ãããã©ã¡ã¼ã¿ã¼ã%(param)sãã¯ç¡å¹ã§ãã"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ãããããã¯ã¼ã¯ %(network)s ã¯ã¢ã¯"
-"ãã£ãã§ã¯ããã¾ãã"
-
-msgid "Template name must be a string"
-msgstr "ãã³ãã¬ã¼ãåã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Template icon must be a path to the image"
-msgstr "ãã³ãã¬ã¼ãã»ã¢ã¤ã³ã³ã¯ã¤ã¡ã¼ã¸ã®ãã¹ã§ãªããã°ãªãã¾ãã"
-
-msgid "Template distribution must be a string"
-msgstr "ãã³ãã¬ã¼ãã»ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Template distribution version must be a string"
-msgstr ""
-"ãã³ãã¬ã¼ãã»ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã»ãã¼ã¸ã§ã³ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾"
-"ãã"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPU æ°ã¯æ´æ°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "ã¡ã¢ãªã¼ã®é (MB åä½) ã¯ã512 ãã大ããæ´æ°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr ""
-"ãã³ãã¬ã¼ã CDROM ã¯ããã¼ã«ã«ã¾ãã¯ãªã¢ã¼ã ISO ãã¡ã¤ã«ã§ãªããã°ãªãã¾ã"
-"ã"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-"ç¡å¹ãªã¹ãã¬ã¼ã¸ã»ãã¼ã« URI %(value)s ããã³ãã¬ã¼ãã«æå®ããã¦ãã¾ã"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-"CDROM ã¨ãã¦ããã³ãã¬ã¼ãã使ããããã® ISO ã¤ã¡ã¼ã¸ãæå®ãã¦ãã ãã"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "ãã³ãã¬ã¼ãç¨ã®ãããã¯ã¼ã¯ããã¹ã¦ãªã¹ãã«æå®ããå¿
è¦ãããã¾ãã"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "次ã®ã¨ã©ã¼ã®ããããã³ãã¬ã¼ãã使ã§ãã¾ãã: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "次ã®ã¨ã©ã¼ã®ããããã³ãã¬ã¼ããåé¤ã§ãã¾ãã: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr ""
-"ãã³ãã¬ã¼ã CDROM ã¯ããã¼ã«ã«ã¾ãã¯ãªã¢ã¼ã ISO ãã¡ã¤ã«ã§ãªããã°ãªãã¾ã"
-"ã"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã¯æ¢ã«åå¨ãã¾ã"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã¯åå¨ãã¾ãã"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã使ããããã«ã¯ã%(item)s ãæå®ãã¦ãã ãã"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "ã¢ã¯ãã£ãã»ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã¯åé¤ã§ãã¾ãã"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ããªã¹ãã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã®ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ã®æ°ãåå¾ã§ãã¾ããã詳"
-"ç´°:%(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãã¢ã¯ãã£ãã«ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãéã¢ã¯ãã£ãã«ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãåé¤ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"ãã¦ã³ãä¸ã«ã¨ã¯ã¹ãã¼ãã»ãã¹ %(path)s ããããã¯ããã¦ããå¯è½æ§ãããã"
-"ããNFS ãã¼ã«ã使ã§ãã¾ãã"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"ã¨ã¯ã¹ãã¼ãã»ãã¹ %(path)s ã®ãã¦ã³ãã«å¤±æãããããNFS ãã¼ã«ã使ã§ãã¾"
-"ãã"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "ãµãã¼ãããã¦ããªãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ã¿ã¤ã: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ãã¯ãIP ã¾ãã¯ãã¹ãåã§ãªããã°ãªãã¾ãã"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ããã¤ã¹ã»ãã©ã¡ã¼ã¿ã¼ã¯ãªã¹ãã§ãªããã°ãªãã¾ãã"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSI ãã¼ã«ã®ã¿ã¼ã²ãã IQN ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"ãªã¢ã¼ãã»ã¹ãã¬ã¼ã¸ã»ãµã¼ãã¼ã®ãã¼ãã¯ã1 ãã 65535 ã¾ã§ã®æ´æ°ã§ãªããã°ãª"
-"ãã¾ãã"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã使ããã«ã¯ãååã¨ã¿ã¤ããæå®ãã¦ãã ãã"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s ã¯ãæå¹ãªãã£ã¹ã¯/ãã¼ãã£ã·ã§ã³ã§ã¯ãªãããããã¼ã« %(pool)s ã«è¿½"
-"å ã§ãã¾ããã§ããã"
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"è«çã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå¯¾è±¡ã«æ´æ°ã§ããã®ã¯ããã©ã¡ã¼ã¿ã¼ã»ãã£ã¹ã¯ã ãã§"
-"ãã"
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI ãã¹ãã»ã¢ããã¿ã¼åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ããã"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« kimchi_isos ã¯ãå
é¨ä½¿ç¨ã®ããã«äºç´ããã¦ãã¾ã"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãã¢ã¯ãã£ãã«ã§ãã¾ãããNFS ãµã¼ãã¼ %"
-"(server)s ã«å°éã§ãã¾ããã"
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãéã¢ã¯ãã£ãã«ã§ãã¾ãããNFS ãµã¼ãã¼ %"
-"(server)s ã«å°éã§ãã¾ããã"
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"ãã¼ã« %(name)s ã¯ããã¤ãã®ãã³ãã¬ã¼ãã«é¢é£ä»ãããã¦ãããããéã¢ã¯ãã£"
-"ãã«ã§ãã¾ãã"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"ãã¼ã« %(name)s ã¯ããã¤ãã®ãã³ãã¬ã¼ãã«é¢é£ä»ãããã¦ãããããåé¤ã§ãã¾"
-"ãã"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"ååã%(name)sãã®ããªã¥ã¼ã ã»ã°ã«ã¼ãã¯æ¢ã«åå¨ãã¾ããè«çãã¼ã«ã使ãã"
-"ã«ã¯ãå¥ã®ååã鏿ãã¦ãã ããã"
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"次ã®ã¨ã©ã¼ã®ããããã¼ã¿ãã¼ã¹ããã£ã¼ãã»ã¹ãã£ã³æ
å ±ã§æ´æ°ã§ãã¾ãã: %"
-"(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ã¯æ¢ã«åå¨ãã¾ã"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ã¯ãã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã«åå¨ãã¾ã"
-"ã"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(volume)s ã使ããããã«ã¯ã%(item)s ãæå®ãã¦ãã "
-"ãã"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ãã¢ã¯ãã£ãã§ã¯ãªããããã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã "
-"ããªã¹ãã§ãã¾ãã"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ãã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã«ä½æã§ãã¾ã"
-"ãã詳細: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã®ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ããªã¹ãã§ãã¾ããã詳"
-"ç´°: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãã¯ã¤ãã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ãåé¤ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ããµã¤ãºå¤æ´ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ã¿ã¤ã %(type)s ã§ã¯ãããªã¥ã¼ã 使ããã³åé¤ã¯ãµãã¼ãããã¦ã"
-"ã¾ãã"
-
-msgid "Storage volume name must be a string"
-msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã å²ãæ¯ãã¯æ´æ°ã§ãªããã°ãªãã¾ãã"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ã«ã¯ããªã¥ã¼ã åãå¿
è¦ã§ã"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"次ã®ã¨ã©ã¼ã®ããããã¼ã¿ãã¼ã¹ãã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã æ
å ±ã§æ´æ°ã§ãã¾ãã: %"
-"(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(name)s ã¯åå¨ãã¾ãã"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "ãããã¯ã¼ã¯ %(name)s ã¯æ¢ã«åå¨ãã¾ã"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "ãããã¯ã¼ã¯ %(name)s ã¯åå¨ãã¾ãã"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"ãããã¯ã¼ã¯ %(network)s ç¨ã«æå®ããã¦ãããµãããã %(subnet)s ã¯ç¡å¹ã§ãã"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"ããªãã¸æ¥ç¶ãããã¯ã¼ã¯ %(name)s ã使ããã«ã¯ããããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼"
-"ãã§ã¼ã¹ãæå®ãã¦ãã ãã"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "ã¢ã¯ãã£ãã»ãããã¯ã¼ã¯ %(name)s ã¯åé¤ã§ãã¾ãã"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-"ãããã¯ã¼ã¯ %(network)s ç¨ã«æå®ããã¦ããã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã¯ãæ¢"
-"ã«ä½¿ç¨ããã¦ãã¾ã"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-"ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¯ã㢠NICãçµåãã¾ãã¯ããªãã¸ã»ããã¤ã¹ã§ãªããã°ãªãã¾ã"
-"ãã"
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "ãããã¯ã¼ã¯ %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "ãããã¯ã¼ã¯ã%(name)sãã®ããªã¼ IP ã¢ãã¬ã¹ãè¦ã¤ããã¾ããã"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "ãµãã¼ãããã¦ãããããã¯ã¼ã¯ã»ã¿ã¤ãã¯éé¢ãNATãããã³ããªãã¸ã§ã"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"ãããã¯ã¼ã¯ã»ãµããããã¯ãIP ã¢ãã¬ã¹ã¨ãã¬ãã£ãã¯ã¹ã¾ãã¯ããããã¹ã¯ã"
-"å
¥ã£ãã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Network interface must be a string"
-msgstr "ãããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "ãããã¯ã¼ã¯ VLAN ID ã¯ã1 ãã 4094 ã¾ã§ã®æ´æ°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Specify name and type to create a Network"
-msgstr "ãããã¯ã¼ã¯ã使ããã«ã¯ãååã¨ã¿ã¤ããæå®ãã¦ãã ãã"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"ããªãã¸ã»ããã¤ã¹ %(name)s ããVLAN ã®ãã©ã³ã¯ã»ããã¤ã¹ã«ãããã¨ã¯ã§ãã¾ã"
-"ãã"
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã®æ´»ååã«å¤±æãã¾ãã: %(err)sã"
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã®æ´»ååã«å¤±æãã¾ãããç©çãªã³ã¯ç¶æ³ã確èªãã¦ã"
-"ã ããã"
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "ãããã°ã»ã¬ãã¼ã %(name)s ã¯åå¨ãã¾ããã"
-
-msgid "Debug report tool not found in system"
-msgstr "ãããã°ã»ã¬ãã¼ãã»ãã¼ã«ãã·ã¹ãã ã«è¦ã¤ããã¾ãã"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "ãããã°ã»ã¬ãã¼ã %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "ãããã°ã»ã¬ãã¼ã %(name)s ãçæã§ãã¾ããã詳細: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"ååã%(name)sãã®ããªã¥ã¼ã ã»ã°ã«ã¼ãã¯æ¢ã«åå¨ãã¾ããè«çãã¼ã«ã使ãã"
-"ã«ã¯ãå¥ã®ååã鏿ãã¦ãã ããã"
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ãµã¼ãã¼ %(server)s ã¯ãKimchi ã«ãã£ã¦ä½¿ç¨ããã¦ãã¾ããã§ãã"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã%(name)sãã¯åå¨ãã¾ãã"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "ãã¼ãã£ã·ã§ã³ %(name)s ã¯ããã¹ãã«åå¨ãã¾ãã"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr "稼åä¸ã®ä»®æ³ãã·ã³ãããããããã¹ãã»ãã·ã³ãã·ã£ãããã¦ã³ã§ãã¾ãã"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "稼åä¸ã®ä»®æ³ãã·ã³ãããããããã¹ãã»ãã·ã³ããªãã¼ãã§ãã¾ãã"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "ãã¼ãã»ããã¤ã¹ã%(name)sããè¦ã¤ããã¾ãã"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "æ´æ°ã®å¯¾è±¡ã¨ãã¦ãã¼ã¯ããã¦ããããã±ã¼ã¸ã¯ããã¾ãã"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "ããã±ã¼ã¸ %(name)s ã¯ãæ´æ°ã®å¯¾è±¡ã¨ãã¦ãã¼ã¯ããã¦ãã¾ããã"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"æ´æ°ã®å¯¾è±¡ã¨ãã¦ãã¼ã¯ãããããã±ã¼ã¸ãåå¾ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ã"
-"ãã詳細: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "ãã®ã·ã¹ãã ç¨ã®äºæããã±ã¼ã¸ã»ããã¼ã¸ã£ã¼ãããã¾ããã"
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "ç¡å¹ãª URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ã¿ã¤ããç¡å¹ã§ãããµãã¼ãããã¦ããã¿ã¤ãã¯ãcdromãã§ãã"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"æ°ããã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã使ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ãã: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãæ´æ°ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ãã: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãåé¤ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ãã: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "æ°ããä»®æ³ãã·ã³ã»ãã£ã¹ã¯ã«è¿½å ããã¿ã¤ãããã³ãã¹ãæå®ãã¾ã"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "ä»®æ³ãã·ã³ã»ãã£ã¹ã¯ãæ´æ°ããã«ã¯ããã¹ãæå®ãã¦ãã ãã"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "æ°ããä»®æ³ãã·ã³ã»ãã£ã¹ã¯ã«è¿½å ããã¿ã¤ãããã³ãã¹ãæå®ãã¾ã"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM ãªãã¸ããªã¼ ID ã¯ã1 ã¯ã¼ãã®ã¿ã®ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr ""
-"ãªãã¸ããªã¼ URL 㯠http://ãftp://ãã¾ã㯠file:// URL ã§ãªããã°ãªãã¾ã"
-"ãã"
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"ãªãã¸ããªã¼æ§æã¨ã¯ããªãã¸ããªã¼ã»ã¿ã¤ãã«å¿ãã¦ç¹å®ã®å¤ãå
¥ã£ããã£ã¯ã·ã§"
-"ããªã¼ã§ãã"
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-"DEB ãªãã¸ããªã¼ã¸ã®ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã¯ãã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr ""
-"DEB ãªãã¸ããªã¼ã¸ã®ã³ã³ãã¼ãã³ãã¯ãé
åã¨ãã¦ãªã¹ãããã¦ããªããã°ãªãã¾"
-"ãã"
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEB ãªãã¸ããªã¼ã¸ã®ã³ã³ãã¼ãã³ãã¯ãã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUM ãªãã¸ããªã¼åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ããã"
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG ãã§ãã¯ã¯ãã¼ã«å¤ã§ãªããã°ãªãã¾ããã"
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG éµã¯ãASCII ã§ä¿åããããã¡ã¤ã«ãæã URL ã§ãªããã°ãªãã¾ããã"
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "ãªãã¸ããªã¼ %(repo_id)s ãæ´æ°ã§ãã¾ããã§ããã"
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "ãªãã¸ããªã¼ %(repo_id)s ã¯åå¨ãã¾ããã"
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "ã·ã¹ãã ç¨ã®ãªãã¸ããªã¼ç®¡çãã¼ã«ãèªèããã¾ããã§ããã"
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "ãªãã¸ããªã¼ %(repo_id)s ã¯æ¢ã«æå¹ã«ãªã£ã¦ãã¾ãã"
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "ãªãã¸ããªã¼ %(repo_id)s ã¯æ¢ã«ç¡å¹ã«ãªã£ã¦ãã¾ãã"
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "ãªãã¸ããªã¼ %(repo_id)s ãåé¤ã§ãã¾ããã§ããã"
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"ãªãã¸ããªã¼æ§æãã¡ã¤ã« %(repo_file)s ãæ¸ãè¾¼ããã¨ãã§ãã¾ããã§ãã"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"DEB ãªãã¸ããªã¼ã使ããããã«ã¯ããªãã¸ããªã¼ã»ãã£ã¹ããªãã¥ã¼ã·ã§ã³ãæ"
-"å®ãã¦ãã ããã"
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "ãªãã¸ããªã¼ %(repo_id)s ãæå¹ã«ã§ãã¾ããã§ããã"
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "ãªãã¸ããªã¼ %(repo_id)s ãç¡å¹ã«ã§ãã¾ããã§ããã"
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM ãªãã¸ããªã¼ ID ã¯æ¢ã«åå¨ãã¾ã"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM ãªãã¸ããªã¼åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "ãªãã¸ããªã¼ããªã¹ãã§ãã¾ããã詳細: ã%(err)sã"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "ãªãã¸ããªã¼æ
å ±ãåå¾ã§ãã¾ããã詳細: ã%(err)sã"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "ãªãã¸ããªã¼ã追å ã§ãã¾ããã詳細: ã%(err)sã"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "ãªãã¸ããªã¼ãåé¤ã§ãã¾ããã詳細: ã%(err)sã"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "ã¨ã©ã¼ã»ã³ã¼ã"
-
-msgid "REASON"
-msgstr "çç±"
-
-msgid "STACK"
-msgstr "ã¹ã¿ãã¯"
-
-msgid "Go to Homepage"
-msgstr "ãã¼ã ã»ãã¼ã¸ã«ç§»åãã"
-
-msgid "Create a New Virtual Machine"
-msgstr "æ°è¦ä»®æ³ãã·ã³ã®ä½æ"
-
-msgid "Virtual Machine Name"
-msgstr "ä»®æ³ãã·ã³å"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"ååã¯ä»®æ³ãã·ã³ãèå¥ããããã«ä½¿ç¨ããã¾ããçç¥ããã¨ã使ç¨ããã¦ãããã³"
-"ãã¬ã¼ãã«åºã¥ãã¦é¸æããã¾ãã"
-
-msgid "Template"
-msgstr "ãã³ãã¬ã¼ã"
-
-msgid "Please create a template first."
-msgstr "ã¾ããã³ãã¬ã¼ãã使ãã¦ãã ããã"
-
-msgid "Create a Template"
-msgstr "ãã³ãã¬ã¼ãã®ä½æ"
-
-msgid "Please choose a template."
-msgstr "ãã³ãã¬ã¼ãã鏿ãã¦ãã ããã"
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "OS ãã¼ã¸ã§ã³"
-
-msgid "CPUS"
-msgstr "CPU"
-
-msgid "Memory"
-msgstr "ã¡ã¢ãªã¼"
-
-msgid "Create"
-msgstr "使"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "åæ¶"
-
-msgid "Edit Guest"
-msgstr "ã²ã¹ãã®ç·¨é"
-
-msgid "General"
-msgstr "ä¸è¬"
-
-msgid "Storage"
-msgstr "ã¹ãã¬ã¼ã¸"
-
-msgid "Interface"
-msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹"
-
-msgid "Permission"
-msgstr "ãã¼ã¸ã§ã³"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "åå"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "ã¡ã¢ãªã¼"
-
-msgid "Icon"
-msgstr "ã¢ã¤ã³ã³"
-
-msgid "Device"
-msgstr "ããã¤ã¹å"
-
-msgid "Path"
-msgstr "NFS ãã¹"
-
-msgid "Network"
-msgstr " ãããã¯ã¼ã¯"
-
-msgid "Type"
-msgstr "ã¿ã¤ã"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "ãã¹ã¦"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "ãã³ãã¼"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "ä¿å"
-
-msgid "Replace"
-msgstr "交æ"
-
-msgid "Detach"
-msgstr "åãé¢ã"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "éå§"
-
-msgid "Reset"
-msgstr "ãªã»ãã"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "ã¢ã¯ã·ã§ã³"
-
-msgid "Connect"
-msgstr "æ¥ç¶"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "ç·¨é"
-
-msgid "Shut Down"
-msgstr "ã·ã£ãããã¦ã³"
-
-msgid "Delete"
-msgstr "åé¤"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "ãã£ã¹ã¯å
¥åºå"
-
-msgid "Network I/O"
-msgstr "ãããã¯ã¼ã¯å
¥åºå"
-
-msgid "Livetile"
-msgstr "ã©ã¤ãã¿ã¤ã«"
-
-msgid "No guests found."
-msgstr "ã²ã¹ããè¦ã¤ããã¾ããã"
-
-msgid "Add a Storage Device to VM"
-msgstr "VM ã«ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã追å "
-
-msgid "Device Type"
-msgstr "ããã¤ã¹ã»ã¿ã¤ã"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "ããã¤ã¹ã»ã¿ã¤ããç¾å¨ãµãã¼ãããã¦ããã®ã¯ \"cdrom\" ã®ã¿ã§ãã"
-
-msgid "Storage Pool"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«"
-
-msgid "Storage pool which volume located in"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "Storage Volume"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«å"
-
-msgid "Storage volume to be attached"
-msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
-
-msgid "File Path"
-msgstr "ãã¡ã¤ã«ã»ãã¹"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "ãµã¼ãã¼å
ã§ã® CDROM ã® ISO ãã¡ã¤ã«ã»ãã¹ã"
-
-msgid "Attach"
-msgstr "æ¥ç¶"
-
-msgid "Shut down"
-msgstr "ã·ã£ãããã¦ã³"
-
-msgid "Restart"
-msgstr "åå§å"
-
-msgid "Basic Information"
-msgstr "åºæ¬æ
å ±"
-
-msgid "OS Distro"
-msgstr "OS ãã£ã¹ããªãã¥ã¼ã·ã§ã³"
-
-msgid "OS Code Name"
-msgstr "OS ã³ã¼ãå"
-
-msgid "Processor"
-msgstr "ããã»ããµã¼"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "ã·ã¹ãã çµ±è¨æ
å ±"
-
-msgid "Software Updates"
-msgstr "ã½ããã¦ã§ã¢æ´æ°"
-
-msgid "Update Progress"
-msgstr "æ´æ°ã®é²è¡ç¶æ³"
-
-msgid "Repositories"
-msgstr "ãªãã¸ããªã¼"
-
-msgid "Debug Reports"
-msgstr "ãããã°ã»ã¬ãã¼ã"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr "å
¥åããã¦ã¼ã¶ã¼åã¾ãã¯ãã¹ã¯ã¼ãã誤ã£ã¦ãã¾ããããç´ãã¦ãã ããã"
-
-msgid "This field is required."
-msgstr "ãã®ãã£ã¼ã«ãã¯å¿
é ã§ãã"
-
-msgid "Log in"
-msgstr "ãã°ã¤ã³"
-
-msgid "Logging in..."
-msgstr "ãã°ã¤ã³ãã¦ãã¾ã..."
-
-msgid "Host"
-msgstr "ãã¹ã"
-
-msgid "Guests"
-msgstr "ã²ã¹ã"
-
-msgid "Templates"
-msgstr "ãã³ãã¬ã¼ã"
-
-msgid "Failed to get application configuration"
-msgstr "ã¢ããªã±ã¼ã·ã§ã³æ§æãåå¾ã§ãã¾ããã§ãã"
-
-msgid "This is not a valid Linux path"
-msgstr "æå¹ãª Linux ãã¹ã§ã¯ããã¾ãã"
-
-msgid "This is not a valid URL."
-msgstr "æå¹ãª URL ã§ã¯ããã¾ããã"
-
-msgid "No such data available."
-msgstr "ãã®ãããªãã¼ã¿ã¯ããã¾ããã"
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"ãã¹ãã»ã·ã¹ãã ã«æ¥ç¶ã§ãã¾ããããã¹ãã»ã·ã¹ãã ã稼åãã¦ãã¦ããããã¯ã¼"
-"ã¯æ¥ç¶ãè¡ããã¦ãããã¨ã確èªãã¦ãã ãããHTTP è¦æ±å¿ç %1"
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "åé¤ã®ç¢ºèª"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "確èª"
-
-msgid "Warning"
-msgstr "è¦å"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "ãã¼ããã¦ãã¾ã..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "å試è¡"
-
-msgid "Detailed message:"
-msgstr "詳細ã¡ãã»ã¼ã¸:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "æå¹ãª ISO ãã¡ã¤ã«ã§ã¯ããã¾ããã"
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "ãã°ããæéãããããã¨ãããã¾ããç¶è¡ãã¾ãã?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "ãã³ãã¬ã¼ãã¯å®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"ããã¤ãã®ä»®æ³ãã·ã³ã稼åãã¦ããããã«ãã·ã¹ãã ãã·ã£ãããã¦ã³ã§ãã¾ãã!"
-
-msgid "Max:"
-msgstr "æå¤§:"
-
-msgid "Utilization"
-msgstr "使ç¨ç"
-
-msgid "Available"
-msgstr "使ç¨å¯è½"
-
-msgid "Read Rate"
-msgstr "èªã¿åãé度"
-
-msgid "Write Rate"
-msgstr "æ¸ãè¾¼ã¿é度"
-
-msgid "Received"
-msgstr "åä¿¡æ¸ã¿"
-
-msgid "Sent"
-msgstr "éä¿¡æ¸ã¿"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"ãã¹ããã·ã£ãããã¦ã³ã¾ãã¯åå§åããã¨ãä¿åããã¦ããªã使¥ã¯å¤±ããã¾ãã"
-"ã·ã£ãããã¦ã³/åå§åãç¶è¡ãã¾ãã?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"ãªãã¸ããªã¼ã¯å®å
¨ã«åé¤ããããªã«ããªã¼ã§ããªããªãã¾ããç¶è¡ãã¾ãã?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "ãã¼ã¹ URL"
-
-msgid "Is Mirror"
-msgstr "ãã©ã¼"
-
-msgid "URL Args"
-msgstr "URL 弿°"
-
-msgid "Enabled"
-msgstr "使ç¨å¯è½"
-
-msgid "GPG Check"
-msgstr "GPG ãã§ãã¯"
-
-msgid "GPG Key"
-msgstr "GPG éµ"
-
-msgid "Add"
-msgstr "追å "
-
-msgid "Remove"
-msgstr "é¤å»"
-
-msgid "Enable"
-msgstr "使ç¨å¯è½"
-
-msgid "Disable"
-msgstr "使ç¨ä¸å¯"
-
-msgid "Package Name"
-msgstr "ããã±ã¼ã¸å"
-
-msgid "Version"
-msgstr "ãã¼ã¸ã§ã³"
-
-msgid "Architecture"
-msgstr "ã¢ã¼ããã¯ãã£ã¼"
-
-msgid "Repository"
-msgstr "ãªãã¸ããªã¼"
-
-msgid "Update All"
-msgstr "ãã¹ã¦æ´æ°"
-
-msgid "Updating..."
-msgstr "æ´æ°ãã¦ãã¾ã..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "ããã±ã¼ã¸ãæ´æ°ã§ãã¾ããã§ããã"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"ãããã°ã»ã¬ãã¼ãã¯å®å
¨ã«åé¤ããããªã«ããªã¼ã§ããªããªãã¾ããç¶è¡ãã¾ãã?"
-
-msgid "Generated Time"
-msgstr "çææå»"
-
-msgid "Generate"
-msgstr "çæ"
-
-msgid "Generating..."
-msgstr "çæãã¦ãã¾ã..."
-
-msgid "Rename"
-msgstr "åå夿´"
-
-msgid "Download"
-msgstr "ãã¦ã³ãã¼ã"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr "ã¬ãã¼ãåã«ä½¿ç¨ã§ããã®ã¯ãè±åãæ°åãããã³ãã¤ãã³ (-) ã®ã¿ã§ãã"
-
-msgid "Pending..."
-msgstr "ãã¼ããã¦ãã¾ã..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"ä»®æ³ãã·ã³ã¨ãã®ä»®æ³ãã£ã¹ã¯ãåé¤ããã¾ãããã®æä½ã¯å
ã«æ»ããã¨ãã§ãã¾ã"
-"ããç¶è¡ãã¾ãã?"
-
-msgid "Power off Confirmation"
-msgstr "åé¤ã®ç¢ºèª"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "åé¤ã®ç¢ºèª"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "åé¤ã®ç¢ºèª"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "ãã³ãã¬ã¼ãã¯å®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"ãã® CDROM ã¯å®å
¨ã«åãé¢ããã¾ããã忥ç¶ã§ãã¾ããåãé¢ããç¶è¡ãã¾ãã?"
-
-msgid "Attaching..."
-msgstr "æ¥ç¶ãã¦ãã¾ã..."
-
-msgid "Replacing..."
-msgstr "交æãã¦ãã¾ã..."
-
-msgid "Successfully attached!"
-msgstr "æ£å¸¸ã«æ¥ç¶ãã¾ãã!"
-
-msgid "Successfully replaced!"
-msgstr "æ£å¸¸ã«äº¤æãã¾ãã!"
-
-msgid "Successfully detached!"
-msgstr "æ£å¸¸ã«åãé¢ãã¾ãã!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN ID ã¯ã1 ãã 4094 ã¾ã§ã§ãªããã°ãªãã¾ããã"
-
-msgid "unavailable"
-msgstr "使ç¨ä¸å¯"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"ãã®ã¢ã¯ã·ã§ã³ã¯ããã®ãããã¯ã¼ã¯ã«ä¾åãã¦ããä»®æ³ãã·ã³ã®ãããã¯ã¼ã¯æ¥ç¶"
-"ã妨ãã¾ãã"
-
-msgid "Create a network"
-msgstr "ãããã¯ã¼ã¯ã®ä½æ"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯æ°¸ç¶çãªãã®ã§ã¯ããã¾ããããã®ã¢ã¯ã·ã§ã³ã§ãéã¢ã¯"
-"ãã£ãã«ãªãã®ã§ã¯ãªãå®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯å®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
-
-msgid "This storage pool is empty."
-msgstr "ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯ç©ºã§ãã"
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"ãã£ã¹ã¯ã¯ãã©ã¼ãããããããã®ä¸ã®ãã¼ã¿ã¯ãã¹ã¦å¤±ããã¾ããç¶è¡ãã¾ãã?"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI ãã¡ã¤ãã¼ã»ãã£ãã«"
-
-msgid "No SCSI adapters found."
-msgstr "SCSI ã¢ããã¿ã¼ãè¦ã¤ããã¾ããã"
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«åããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
-
-msgid "The storage pool path can not be blank."
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFS ãµã¼ãã¼ã»ãã¦ã³ãã»ãã¹ããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
-
-msgid "Invalid NFS mount path."
-msgstr "NFS ãã¦ã³ãã»ãã¹ãç¡å¹ã§ãã"
-
-msgid "No logical device selected."
-msgstr "è«çããã¤ã¹ã鏿ããã¦ãã¾ããã"
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSI ã¿ã¼ã²ããããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
-
-msgid "Server name can not be blank."
-msgstr "ãµã¼ãã¼åããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "æç¨å¯è½ãªãã¼ãã£ã·ã§ã³ãæ¢ãã¦ãã¾ã..."
-
-msgid "No available partitions found."
-msgstr "使ç¨å¯è½ãªãã¼ãã£ã·ã§ã³ãè¦ã¤ããã¾ããã"
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯æ°¸ç¶çãªãã®ã§ã¯ããã¾ããããã®ã¢ã¯ã·ã§ã³ã§ãéã¢ã¯"
-"ãã£ãã«ãªãã®ã§ã¯ãªãå®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "ãªãã¸ããªã¼æ
å ±ãåå¾ã§ãã¾ããã詳細: ã%(err)sã"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«åããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "ãããã¯ã¼ã¯å"
-
-msgid "State"
-msgstr "ç¶æ
"
-
-msgid "Network Type"
-msgstr "ãããã¯ã¼ã¯ã»ã¿ã¤ã"
-
-msgid "Address Space"
-msgstr "ã¢ãã¬ã¹ã»ã¹ãã¼ã¹"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-
-msgid "Isolated: no external network connection"
-msgstr "éé¢: ç©çãããã¯ã¼ã¯æ¥ç¶ãªã"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: ã¢ã¦ããã¦ã³ãç©çãããã¯ã¼ã¯æ¥ç¶ã®ã¿"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "ããªãã¸: ä»®æ³ãã·ã³ãç´æ¥ç©çãããã¯ã¼ã¯ã«æ¥ç¶ããã"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "å®å
:"
-
-msgid "Enable VLAN"
-msgstr "VLAN ã使ç¨å¯è½ã«ãã:"
-
-msgid "VLAN ID"
-msgstr "VLAN ID:"
-
-msgid "Stop"
-msgstr "忢"
-
-msgid "Generate a New Debug Report"
-msgstr "æ°è¦ãããã°ã»ã¬ãã¼ãã®çæ"
-
-msgid "Report Name"
-msgstr "ã¬ãã¼ãå"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"ååã¯ã¬ãã¼ããèå¥ããããã«ä½¿ç¨ããã¾ããçç¥ããã¨ãç¾å¨æå»ã«åºã¥ãã¦é¸"
-"æããã¾ããååã«ã¯è±åãæ°åãããã³ãã¤ãã³ (-) ã使ç¨ã§ãã¾ãã"
-
-msgid "Rename a Debug Report"
-msgstr "æ°è¦ãããã°ã»ã¬ãã¼ãã®çæ"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"ååã¯ã¬ãã¼ããèå¥ããããã«ä½¿ç¨ããã¾ããçç¥ããã¨ãç¾å¨æå»ã«åºã¥ãã¦é¸"
-"æããã¾ããååã«ã¯è±åãæ°åãããã³ãã¤ãã³ (-) ã使ç¨ã§ãã¾ãã"
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "ãªãã¸ããªã¼ã®è¿½å "
-
-msgid "Identifier"
-msgstr "ID"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "ãªãã¸ããªã¼ã®åºæ ID ã示ãåä¸ã®ã¯ã¼ãã"
-
-msgid "Textual name for the repository."
-msgstr "ãªãã¸ããªã¼ã®ããã¹ãåã"
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "å¿
é ãã£ã¼ã«ã"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr ""
-"ãªãã¸ããªã¼ã® URL ã§ããµãã¼ãããã¦ãããããã³ã«ã¯ httpãftpãããã³ file "
-"ã§ãã"
-
-msgid "Repository is a mirror"
-msgstr "ãªãã¸ããªã¼ã¯ãã©ã¼ã§ãã"
-
-msgid "Distribution"
-msgstr "ãã£ã¹ããªãã¥ã¼ã·ã§ã³"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEB ãªãã¸ããªã¼ã®ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã"
-
-msgid "Components"
-msgstr "ã³ã³ãã¼ãã³ã"
-
-msgid "List of components in DEB repository."
-msgstr "DEB ãªãã¸ããªã¼å
ã®ã³ã³ãã¼ãã³ãã®ãªã¹ãã"
-
-msgid "Edit Repository"
-msgstr "ãªãã¸ããªã¼ã®ç·¨é"
-
-msgid "Mirror List URL"
-msgstr "ãã©ã¼ã»ãªã¹ã URL"
-
-msgid "Yes"
-msgstr " ã¯ã"
-
-msgid "No"
-msgstr " ããã"
-
-msgid "Capacity"
-msgstr "容é"
-
-msgid "Allocated"
-msgstr "å²ãå½ã¦æ¸ã¿"
-
-msgid "Location"
-msgstr "ãã±ã¼ã·ã§ã³"
-
-msgid "Device path"
-msgstr "ããã¤ã¹ã»ãã¹"
-
-msgid "active"
-msgstr "ã¢ã¯ãã£ã"
-
-msgid "inactive"
-msgstr "éã¢ã¯ãã£ã"
-
-msgid "Deactivate"
-msgstr "éã¢ã¯ãã£ãã«ãã"
-
-msgid "Activate"
-msgstr "ã¢ã¯ãã£ãã«ãã"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "å®ç¾©ãè§£é¤ãã"
-
-msgid "Format"
-msgstr "ãã©ã¼ããã:"
-
-msgid "Allocation"
-msgstr "å²ãæ¯ã:"
-
-msgid "Define a New Storage Pool"
-msgstr "æ°è¦ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®å®ç¾©"
-
-msgid "Storage Pool Name"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«å"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"ååã¯ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãèå¥ããããã«ä½¿ç¨ããã¾ãã空ã«ãããã¨ã¯ã§ãã¾ã"
-"ãã"
-
-msgid "Storage Pool Type"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ã¿ã¤ã"
-
-msgid "Storage Path"
-msgstr "ã¹ãã¬ã¼ã¸ã»ãã¹"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ãã¹ãããããã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«åºæã®ãã¹ãå¿
è¦ã§"
-"ãã"
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"ãã£ã¬ã¯ããªã¼ãã·ã¹ãã ã«åå¨ããªãå ´åãKimchi ããã®ä½æã試ã¿ã¾ãã"
-
-msgid "NFS Server IP"
-msgstr "NFS ãµã¼ãã¼ IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"NFS ãµã¼ãã¼ IP ã¾ãã¯ãã¹ãåãå
¥åãããã¨ãããã¹ããªã¼ãã鏿ãããã¨ã"
-"ã§ãã¾ãã"
-
-msgid "NFS Path"
-msgstr "NFS ãã¹"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFS ããã¹ã NFS ãµã¼ãã¼ã«ã¨ã¯ã¹ãã¼ããã¾ããã"
-
-msgid "iSCSI Server"
-msgstr "iSCSI ãµã¼ãã¼"
-
-msgid "Server"
-msgstr "ãµã¼ãã¼"
-
-msgid "Port"
-msgstr "ãã¼ã"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSI ãµã¼ãã¼ IP ã¾ãã¯ãã¹ãåã空ã«ãããã¨ã¯ã§ãã¾ããã"
-
-msgid "Target"
-msgstr "ã¿ã¼ã²ãã"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSI ãµã¼ãã¼ä¸ã® iSCSI ã¿ã¼ã²ãã"
-
-msgid "Add iSCSI Authentication"
-msgstr "iSCSI èªè¨¼ã®è¿½å "
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI èªè¨¼"
-
-msgid "User Name"
-msgstr "ã¦ã¼ã¶ã¼å"
-
-msgid "Password"
-msgstr "ãã¹ã¯ã¼ã"
-
-msgid "SCSI Adapter"
-msgstr "SCSI ã¢ããã¿ã¼"
-
-msgid "Please, wait..."
-msgstr "ãå¾
ã¡ãã ãã..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "ãã³ãã¬ã¼ãã®è¿½å "
-
-msgid "Where is the source media for this template? "
-msgstr "ãã®ãã³ãã¬ã¼ãã®ã½ã¼ã¹ã»ã¡ãã£ã¢ã¯ã©ãã«ããã¾ãã?"
-
-msgid "Local ISO Image"
-msgstr "ãã¼ã«ã« ISO ã¤ã¡ã¼ã¸"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "ãªã¢ã¼ã ISO ã¤ã¡ã¼ã¸"
-
-msgid "Search ISOs"
-msgstr "ISO ã®æ¤ç´¢"
-
-msgid "The following ISOs are available:"
-msgstr "次㮠ISO ã使ç¨å¯è½ã§ã:"
-
-msgid "OS: "
-msgstr "OS: "
-
-msgid "Version: "
-msgstr "ãã¼ã¸ã§ã³: "
-
-msgid "Size: "
-msgstr "ãµã¤ãº: "
-
-msgid "Search more ISOs"
-msgstr "ISO ãããã«æ¤ç´¢"
-
-msgid "Create Templates from Selected ISO"
-msgstr "鏿ãã ISO ãããã³ãã¬ã¼ãã使"
-
-msgid "I want to use a specific ISO file"
-msgstr "ç¹å®ã® ISO ãã¡ã¤ã«ã使ç¨ãã"
-
-msgid "Loading default remote ISOs ..."
-msgstr "ããã©ã«ãã®ãªã¢ã¼ã ISO ããã¼ããã¦ãã¾ã..."
-
-msgid "Arch: "
-msgstr "ã¢ã¼ããã¯ãã£ã¼: "
-
-msgid "I want to use a custom URL"
-msgstr "ã«ã¹ã¿ã URL ã使ç¨ãã"
-
-msgid "Edit Template"
-msgstr "ãã³ãã¬ã¼ãã®ç·¨é"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "ã°ã©ãã£ãã¯ã¹"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU æ°"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "ãã³ãã¬ã¼ããè¦ã¤ããã¾ããã"
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "%(resource)s ã®åé¤ã¯è¨±å¯ããã¾ãã"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s ã¯æ´æ°ã¡ã½ãããå®è£
ãã¦ãã¾ãã"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "%(resource)s ã®ä½æã¯è¨±å¯ããã¾ãã"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "JSON è¦æ±ãè§£æã§ãã¾ãã"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "ãã® API 㯠JSON ã®ã¿ãµãã¼ããã¾ã"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "ãã¼ã¿ã»ã¹ãã¢ã¯ãã¢ãã«ã»ãªãã¸ã§ã¯ãã§éå§ããã¦ãã¾ããã"
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "次ã®ã¨ã©ã¼ã®ãããã¿ã¹ã¯ãéå§ã§ãã¾ãã: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr ""
-#~ "ã¦ã¼ã¶ã¼ã%(username)sãã®èªè¨¼ã«å¤±æãã¾ããã[ã¨ã©ã¼ã»ã³ã¼ã: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Kimchi ã¸ã®ã¢ã¯ã»ã¹ã許å¯ããã¦ãã¾ãã"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Kimchi ã«ãã°ã¤ã³ããã«ã¯ã%(item)s ãæå®ãã¾ã"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "%(item)s ã¯ãã¼ã¿ã»ã¹ãã¢ã«è¦ã¤ããã¾ãã"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr ""
-#~ "ã³ãã³ãã%(cmd)sããå®è¡ãã¦ãã¾ãããã%(seconds)s ç§ãçµéãã¦ã¿ã¤ã ã¢"
-#~ "ã¦ãã«ãªãã¾ãã"
-
-#~ msgid "Help"
-#~ msgstr "ãã«ã"
-
-#~ msgid "About"
-#~ msgstr "製åæ
å ±"
-
-#~ msgid "Log out"
-#~ msgstr "ãã°ã¢ã¦ã"
-
-#~ msgid "Version:"
-#~ msgstr "ãã¼ã¸ã§ã³: "
diff --git a/plugins/kimchi/po/kimchi.pot b/plugins/kimchi/po/kimchi.pot
deleted file mode 100755
index d4605c7..0000000
--- a/plugins/kimchi/po/kimchi.pot
+++ /dev/null
@@ -1,2074 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-
-msgid "Remote ISO image is not supported by this server."
-msgstr ""
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-
-msgid "Specify a template to create a virtual machine from"
-msgstr ""
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr ""
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr ""
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr ""
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-
-msgid "Template name must be a string"
-msgstr ""
-
-msgid "Template icon must be a path to the image"
-msgstr ""
-
-msgid "Template distribution must be a string"
-msgstr ""
-
-msgid "Template distribution version must be a string"
-msgstr ""
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr ""
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr ""
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-
-msgid "All networks for the template must be specified in a list."
-msgstr ""
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr ""
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr ""
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr ""
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr ""
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr ""
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr ""
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr ""
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr ""
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-
-msgid "The SCSI host adapter name must be a string."
-msgstr ""
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-
-msgid "Storage volume name must be a string"
-msgstr ""
-
-msgid "Storage volume allocation must be an integer number"
-msgstr ""
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr ""
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-
-msgid "Network interface must be a string"
-msgstr ""
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr ""
-
-msgid "Specify name and type to create a Network"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr ""
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr ""
-
-msgid "Debug report tool not found in system"
-msgstr ""
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr ""
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr ""
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr ""
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr ""
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr ""
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr ""
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-
-msgid "There is no compatible package manager for this system."
-msgstr ""
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr ""
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr ""
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr ""
-
-msgid "Components to DEB repository must be a string"
-msgstr ""
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr ""
-
-msgid "GPG check must be a boolean value."
-msgstr ""
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr ""
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr ""
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr ""
-
-msgid "YUM Repository ID already exists"
-msgstr ""
-
-msgid "YUM Repository name must be a string"
-msgstr ""
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr ""
-
-msgid "REASON"
-msgstr ""
-
-msgid "STACK"
-msgstr ""
-
-msgid "Go to Homepage"
-msgstr ""
-
-msgid "Create a New Virtual Machine"
-msgstr ""
-
-msgid "Virtual Machine Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-
-msgid "Template"
-msgstr ""
-
-msgid "Please create a template first."
-msgstr ""
-
-msgid "Create a Template"
-msgstr ""
-
-msgid "Please choose a template."
-msgstr ""
-
-msgid "OS"
-msgstr ""
-
-msgid "OS Version"
-msgstr ""
-
-msgid "CPUS"
-msgstr ""
-
-msgid "Memory"
-msgstr ""
-
-msgid "Create"
-msgstr ""
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr ""
-
-msgid "Edit Guest"
-msgstr ""
-
-msgid "General"
-msgstr ""
-
-msgid "Storage"
-msgstr ""
-
-msgid "Interface"
-msgstr ""
-
-msgid "Permission"
-msgstr ""
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr ""
-
-msgid "CPUs"
-msgstr ""
-
-msgid "Memory (MB)"
-msgstr ""
-
-msgid "Icon"
-msgstr ""
-
-msgid "Device"
-msgstr ""
-
-msgid "Path"
-msgstr ""
-
-msgid "Network"
-msgstr ""
-
-msgid "Type"
-msgstr ""
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr ""
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr ""
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr ""
-
-msgid "Replace"
-msgstr ""
-
-msgid "Detach"
-msgstr ""
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr ""
-
-msgid "Reset"
-msgstr ""
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr ""
-
-msgid "Connect"
-msgstr ""
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr ""
-
-msgid "Shut Down"
-msgstr ""
-
-msgid "Delete"
-msgstr ""
-
-msgid "CPU"
-msgstr ""
-
-msgid "Disk I/O"
-msgstr ""
-
-msgid "Network I/O"
-msgstr ""
-
-msgid "Livetile"
-msgstr ""
-
-msgid "No guests found."
-msgstr ""
-
-msgid "Add a Storage Device to VM"
-msgstr ""
-
-msgid "Device Type"
-msgstr ""
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr ""
-
-msgid "Storage Pool"
-msgstr ""
-
-msgid "Storage pool which volume located in"
-msgstr ""
-
-msgid "Storage Volume"
-msgstr ""
-
-msgid "Storage volume to be attached"
-msgstr ""
-
-msgid "File Path"
-msgstr ""
-
-msgid "The ISO file path in the server for CDROM."
-msgstr ""
-
-msgid "Attach"
-msgstr ""
-
-msgid "Shut down"
-msgstr ""
-
-msgid "Restart"
-msgstr ""
-
-msgid "Basic Information"
-msgstr ""
-
-msgid "OS Distro"
-msgstr ""
-
-msgid "OS Code Name"
-msgstr ""
-
-msgid "Processor"
-msgstr ""
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr ""
-
-msgid "Software Updates"
-msgstr ""
-
-msgid "Update Progress"
-msgstr ""
-
-msgid "Repositories"
-msgstr ""
-
-msgid "Debug Reports"
-msgstr ""
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-
-msgid "This field is required."
-msgstr ""
-
-msgid "Log in"
-msgstr ""
-
-msgid "Logging in..."
-msgstr ""
-
-msgid "Host"
-msgstr ""
-
-msgid "Guests"
-msgstr ""
-
-msgid "Templates"
-msgstr ""
-
-msgid "Failed to get application configuration"
-msgstr ""
-
-msgid "This is not a valid Linux path"
-msgstr ""
-
-msgid "This is not a valid URL."
-msgstr ""
-
-msgid "No such data available."
-msgstr ""
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr ""
-
-msgid "OK"
-msgstr ""
-
-msgid "Confirm"
-msgstr ""
-
-msgid "Warning"
-msgstr ""
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr ""
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr ""
-
-msgid "Detailed message:"
-msgstr ""
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr ""
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr ""
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-
-msgid "Max:"
-msgstr ""
-
-msgid "Utilization"
-msgstr ""
-
-msgid "Available"
-msgstr ""
-
-msgid "Read Rate"
-msgstr ""
-
-msgid "Write Rate"
-msgstr ""
-
-msgid "Received"
-msgstr ""
-
-msgid "Sent"
-msgstr ""
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-
-msgid "ID"
-msgstr ""
-
-msgid "Base URL"
-msgstr ""
-
-msgid "Is Mirror"
-msgstr ""
-
-msgid "URL Args"
-msgstr ""
-
-msgid "Enabled"
-msgstr ""
-
-msgid "GPG Check"
-msgstr ""
-
-msgid "GPG Key"
-msgstr ""
-
-msgid "Add"
-msgstr ""
-
-msgid "Remove"
-msgstr ""
-
-msgid "Enable"
-msgstr ""
-
-msgid "Disable"
-msgstr ""
-
-msgid "Package Name"
-msgstr ""
-
-msgid "Version"
-msgstr ""
-
-msgid "Architecture"
-msgstr ""
-
-msgid "Repository"
-msgstr ""
-
-msgid "Update All"
-msgstr ""
-
-msgid "Updating..."
-msgstr ""
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr ""
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-
-msgid "Generated Time"
-msgstr ""
-
-msgid "Generate"
-msgstr ""
-
-msgid "Generating..."
-msgstr ""
-
-msgid "Rename"
-msgstr ""
-
-msgid "Download"
-msgstr ""
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr ""
-
-msgid "Pending..."
-msgstr ""
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-
-msgid "Power off Confirmation"
-msgstr ""
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr ""
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr ""
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-
-msgid "Attaching..."
-msgstr ""
-
-msgid "Replacing..."
-msgstr ""
-
-msgid "Successfully attached!"
-msgstr ""
-
-msgid "Successfully replaced!"
-msgstr ""
-
-msgid "Successfully detached!"
-msgstr ""
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr ""
-
-msgid "unavailable"
-msgstr ""
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-
-msgid "Create a network"
-msgstr ""
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-
-msgid "This storage pool is empty."
-msgstr ""
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-
-msgid "SCSI Fibre Channel"
-msgstr ""
-
-msgid "No SCSI adapters found."
-msgstr ""
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr ""
-
-msgid "The storage pool path can not be blank."
-msgstr ""
-
-msgid "NFS server mount path can not be blank."
-msgstr ""
-
-msgid "Invalid NFS mount path."
-msgstr ""
-
-msgid "No logical device selected."
-msgstr ""
-
-msgid "The iSCSI target can not be blank."
-msgstr ""
-
-msgid "Server name can not be blank."
-msgstr ""
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr ""
-
-msgid "No available partitions found."
-msgstr ""
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr ""
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr ""
-
-msgid "State"
-msgstr ""
-
-msgid "Network Type"
-msgstr ""
-
-msgid "Address Space"
-msgstr ""
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-
-msgid "Isolated: no external network connection"
-msgstr ""
-
-msgid "NAT: outbound physical network connection only"
-msgstr ""
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr ""
-
-msgid "Enable VLAN"
-msgstr ""
-
-msgid "VLAN ID"
-msgstr ""
-
-msgid "Stop"
-msgstr ""
-
-msgid "Generate a New Debug Report"
-msgstr ""
-
-msgid "Report Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-
-msgid "Rename a Debug Report"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr ""
-
-msgid "Identifier"
-msgstr ""
-
-msgid "Single word, unique identifier for the repository."
-msgstr ""
-
-msgid "Textual name for the repository."
-msgstr ""
-
-msgid "URL"
-msgstr ""
-
-msgid "Required Field"
-msgstr ""
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr ""
-
-msgid "Repository is a mirror"
-msgstr ""
-
-msgid "Distribution"
-msgstr ""
-
-msgid "Distribution of the DEB repository."
-msgstr ""
-
-msgid "Components"
-msgstr ""
-
-msgid "List of components in DEB repository."
-msgstr ""
-
-msgid "Edit Repository"
-msgstr ""
-
-msgid "Mirror List URL"
-msgstr ""
-
-msgid "Yes"
-msgstr ""
-
-msgid "No"
-msgstr ""
-
-msgid "Capacity"
-msgstr ""
-
-msgid "Allocated"
-msgstr ""
-
-msgid "Location"
-msgstr ""
-
-msgid "Device path"
-msgstr ""
-
-msgid "active"
-msgstr ""
-
-msgid "inactive"
-msgstr ""
-
-msgid "Deactivate"
-msgstr ""
-
-msgid "Activate"
-msgstr ""
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr ""
-
-msgid "Format"
-msgstr ""
-
-msgid "Allocation"
-msgstr ""
-
-msgid "Define a New Storage Pool"
-msgstr ""
-
-msgid "Storage Pool Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-
-msgid "Storage Pool Type"
-msgstr ""
-
-msgid "Storage Path"
-msgstr ""
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-
-msgid "NFS Server IP"
-msgstr ""
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-
-msgid "NFS Path"
-msgstr ""
-
-msgid "The NFS exported path on NFS server."
-msgstr ""
-
-msgid "iSCSI Server"
-msgstr ""
-
-msgid "Server"
-msgstr ""
-
-msgid "Port"
-msgstr ""
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr ""
-
-msgid "Target"
-msgstr ""
-
-msgid "The iSCSI target on iSCSI server"
-msgstr ""
-
-msgid "Add iSCSI Authentication"
-msgstr ""
-
-msgid "iSCSI Authentication"
-msgstr ""
-
-msgid "User Name"
-msgstr ""
-
-msgid "Password"
-msgstr ""
-
-msgid "SCSI Adapter"
-msgstr ""
-
-msgid "Please, wait..."
-msgstr ""
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr ""
-
-msgid "Where is the source media for this template? "
-msgstr ""
-
-msgid "Local ISO Image"
-msgstr ""
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr ""
-
-msgid "Search ISOs"
-msgstr ""
-
-msgid "The following ISOs are available:"
-msgstr ""
-
-msgid "OS: "
-msgstr ""
-
-msgid "Version: "
-msgstr ""
-
-msgid "Size: "
-msgstr ""
-
-msgid "Search more ISOs"
-msgstr ""
-
-msgid "Create Templates from Selected ISO"
-msgstr ""
-
-msgid "I want to use a specific ISO file"
-msgstr ""
-
-msgid "Loading default remote ISOs ..."
-msgstr ""
-
-msgid "Arch: "
-msgstr ""
-
-msgid "I want to use a custom URL"
-msgstr ""
-
-msgid "Edit Template"
-msgstr ""
-
-msgid "CDROM"
-msgstr ""
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr ""
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr ""
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr ""
diff --git a/plugins/kimchi/po/ko_KR.po b/plugins/kimchi/po/ko_KR.po
deleted file mode 100644
index 08bf222..0000000
--- a/plugins/kimchi/po/ko_KR.po
+++ /dev/null
@@ -1,2197 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ko_KR\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "ë¸ë¡ ì¥ì¹ë¥¼ ê°ì ¸ì¤ë ì¤ì ì¤ë¥ê° ë°ìíìµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "%(device)sì ëí ë¸ë¡ ì¥ì¹ ì 보를 ê°ì ¸ì¤ë ì¤ì ì¤ë¥ê° ë°ìíìµëë¤."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "distro íì¼ì ì°¾ì ì ìì: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"distro íì¼(%(filename)s)ì 구문 ë¶ìí ì ììµëë¤. JSON íì¼ì¸ì§ íì¸íìì"
-"ì¤."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "iSCSI í¸ì¤í¸ ëì %(portal)sì ë¡ê·¸ì¸í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "iSCSI host %(host)s ëì %(target)sì ë¡ê·¸ì¸í ì ììµëë¤."
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISO íì¼ %(filename)sì(ë) ë¶í¸ ê°ë¥íì§ ììµëë¤."
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "ISO íì¼ %(filename)sì ì í¨í El Torito ë¶í¸ ë ì½ëê° ììµëë¤."
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr ""
-"ISO %(filename)sì ì¬ë°ë¥´ì§ ìì El Torito ì í¨ì± ê²ì¦ íëª©ì´ ììµëë¤."
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ISO %(filename)sì ì¬ë°ë¥´ì§ ìì El Torito ë¶í¸ íìê¸°ê° ììµëë¤."
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "ISO %(filename)sìì 기본 ë³¼ë¥¨ì´ ììì¹ ìì 볼륨 ì íì
ëë¤."
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"ISO %(filename)sìì 볼륨 ëì¤í¬ë¦½í°ë¥¼ ì½ë ì¤ì ì못ë íìì´ ë°ê²¬ëììµë"
-"ë¤."
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"íì´í¼ë°ì´ì ê° ì´ ISO %(filename)sì(를) ì¬ì©í ê¶íì´ ììµëë¤. ì´ë¥¼ /var/"
-"lib/libvirt ìëë¡ ì´ëìí¤ê±°ë, (ê°ë¥í ê²½ì°) ê²ì ê¶íì '%(user)s' ì¬ì©ì"
-"ì íì¼ ì¡ì¸ì¤ ì ì´ ëª©ë¡ì ì¤ì íê±°ë, '%(user)s'ì(를) ISO ê²½ë¡ ê·¸ë£¹ì ì¶ê°"
-"íê±°ë, 'chmod -R o+x 'path_to_iso'(ê¶ì¥ëì§ ìì)ì ì¶ê°íììì¤. ì¸ë¶ì¬í: "
-"%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "ê°ì 머ì %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "ê°ì 머ì %(name)sì´(ê°) ììµëë¤."
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "ì¤ì§ë ê°ì 머ì %(name)sì ëí ì¤í¬ë¦°ì·ì ê²ìí ì ììµëë¤."
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "ì격 ISO ì´ë¯¸ì§ë ì´ ìë²ìì ì§ìíì§ ììµëë¤."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ê²ìí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "ì²ì·¨ ëì ê·¸ëí½ ì£¼ìë IPv4 ëë IPv6ì¬ì¼ í©ëë¤."
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "ê°ì 머ì ì ìì±í기 ìí í
í리í¸ë¥¼ ì§ì íììì¤."
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ììí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ì¤ì§í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì ì´ë¦ì ë°ê¿ ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "ë¤í¸ìí¬ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "ë¤í¸ìí¬ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "'%(users)s' ì¬ì©ìê° ììµëë¤."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "'%(groups)s' ì¬ì©ìê° ììµëë¤."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ì¤ì§í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "ê°ì 머ì %(name)sì(를) ììí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "ê°ì 머ì %(name)sì %(iface)s ì¸í°íì´ì¤ê° ììµëë¤."
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr "ê°ì 머ì %(name)sì ëí´ ì§ì ë %(network)s ë¤í¸ìí¬ê° ììµëë¤."
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "ì§ìëë ê°ì 머ì ì¸í°íì´ì¤ ì íì ë¤í¸ìí¬ë¿ì
ëë¤."
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "ê°ì 머ì ì¸í°íì´ì¤ì ë¤í¸ìí¬ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"ê°ì 머ì ì¸í°íì´ì¤ì ëí´ ì¬ë°ë¥´ì§ ìì ë¤í¸ìí¬ ëª¨ë¸ ì¹´ëê° ì§ì ëììµë"
-"ë¤."
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "ì ê°ì 머ì ì¸í°íì´ì¤ë¥¼ ì¶ê°í ì í ë° ë¤í¸ìí¬ë¥¼ ì§ì íììì¤."
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "í
íë¦¬í¸ %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr "í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë '%(network)s' ë¤í¸ìí¬ê° ììµëë¤."
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë ì¤í ë¦¬ì§ í %(pool)sì´(ê°) ììµëë¤."
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-"í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë ì¤í ë¦¬ì§ í %(pool)sì´(ê°) íì±ì´ ìëë"
-"ë¤."
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "CDROMì ëí´ ì¬ë°ë¥´ì§ ìì 매ê°ë³ì '%(param)s'ì´(ê°) ì§ì ëììµëë¤."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë %(network)s ë¤í¸ìí¬ê° íì±ì´ ìëëë¤."
-
-msgid "Template name must be a string"
-msgstr "í
íë¦¬í¸ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Template icon must be a path to the image"
-msgstr "í
íë¦¬í¸ ìì´ì½ì ì´ë¯¸ì§ì ê²½ë¡ì¬ì¼ í©ëë¤."
-
-msgid "Template distribution must be a string"
-msgstr "í
íë¦¬í¸ ë°°í¬ë 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Template distribution version must be a string"
-msgstr "í
íë¦¬í¸ ë°°í¬ ë²ì ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPU ìë ì ìì¬ì¼ í©ëë¤."
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "ë©ëª¨ë¦¬ ì©ë(MB)ì 512ë³´ë¤ í° ì ìì¬ì¼ í©ëë¤."
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "í
íë¦¬í¸ CDROMì ë¡ì»¬ ëë ì격 ISO íì¼ì´ì´ì¼ í©ëë¤."
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-"í
í리í¸ì ëí´ ì¬ë°ë¥´ì§ ìì ì¤í ë¦¬ì§ í URI %(value)sì´(ê°) ì§ì ëììµëë¤."
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "í
í리í¸ë¥¼ ìì±íë ¤ë©´ ISO ì´ë¯¸ì§ë¥¼ CDROMì¼ë¡ ì§ì íììì¤."
-
-msgid "All networks for the template must be specified in a list."
-msgstr "í
í리í¸ì 모ë ë¤í¸ìí¬ê° 목ë¡ì ì§ì ëì´ì¼ í©ëë¤."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "ì¤ë¥ ë문ì í
í리í¸ë¥¼ ìì±í ì ìì: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "ì¤ë¥ ë문ì í
í리í¸ë¥¼ ìì í ì ìì: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "í
íë¦¬í¸ CDROMì ë¡ì»¬ ëë ì격 ISO íì¼ì´ì´ì¼ í©ëë¤."
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì´(ê°) ììµëë¤."
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì±íë ¤ë©´ %(item)sì(를) ì§ì íììì¤."
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "íì± ì¤í ë¦¬ì§ í %(name)sì(를) ìì í ì ììµëë¤."
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ íì ëì´í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"ì¤í ë¦¬ì§ í %(name)sì ìë ì¤í ë¦¬ì§ ë³¼ë¥¨ì ì를 ê°ì ¸ì¬ ì ììµëë¤. ì¸ë¶ì¬"
-"í: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) íì±íí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ë¹íì±íí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"ë´ë³´ë´ê¸° ê²½ë¡ %(path)sì´(ê°) ë§ì´í¸ ì¤ì ì°¨ë¨ë ì ìì¼ë¯ë¡ NFS íì ìì±í "
-"ì ììµëë¤."
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"ë´ë³´ë´ê¸° ê²½ë¡ %(path)s ë§ì´í¸ê° ì¤í¨íì¼ë¯ë¡ NFS íì ìì±í ì ììµëë¤."
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "ì§ìëì§ ìë ì¤í ë¦¬ì§ í ì í: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "ì¤í ë¦¬ì§ í ê²½ë¡ë 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "ì¤í ë¦¬ì§ í í¸ì¤í¸ë IP ëë í¸ì¤í¸ ì´ë¦ì´ì´ì¼ í©ëë¤."
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "ì¤í ë¦¬ì§ í ì¥ì¹ë 목ë¡ì´ì´ì¼ í©ëë¤."
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSI íì ëì IQNì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "ì격 ì¤í ë¦¬ì§ ìë²ì í¬í¸ë 1ê³¼ 65535 ì¬ì´ì ì ìì¬ì¼ í©ëë¤."
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "ì¤í ë¦¬ì§ íì ìì±íë ¤ë©´ ì´ë¦ ë° ì íì ì§ì íììì¤."
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)sì(ë) ì í¨í ëì¤í¬/íí°ì
ì´ ìëëë¤. ì´ë¥¼ %(pool)s íì ì¶ê°í ì "
-"ììµëë¤."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "ë
¼ë¦¬ ì¤í ë¦¬ì§ íì 매ê°ë³ì ëì¤í¬ë§ ì
ë°ì´í¸í ì ììµëë¤."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI í¸ì¤í¸ ì´ëí° ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "ì¤í ë¦¬ì§ í kimchi_isosë ë´ë¶ ì©ëë¡ ìì½ëììµëë¤."
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ì¤í ë¦¬ì§ í %(name)sì(를) íì±íí ì ììµëë¤. NFS ìë² %(server)sì ì°"
-"ê²°í ì ììµëë¤."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ì¤í ë¦¬ì§ í %(name)sì(를) ë¹íì±íí ì ììµëë¤. NFS ìë² %(server)sì "
-"ì°ê²°í ì ììµëë¤."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"ì¼ë¶ í
í리í¸ì ì°ê´ëì´ ìì¼ë¯ë¡ %(name)s íì ë¹íì±íí ì ììµëë¤."
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "ì¼ë¶ í
í리í¸ì ì°ê´ëì´ ìì¼ë¯ë¡ %(name)s íì ìì í ì ììµëë¤."
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"ì´ë¦ì´ '%(name)s'ì¸ ë³¼ë¥¨ ê·¸ë£¹ì´ ì´ë¯¸ ì¡´ì¬í©ëë¤. ë
¼ë¦¬ íì ìì±íë ¤ë©´ ë¤ë¥¸ ì´"
-"ë¦ì ì ííììì¤."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"ì¤ë¥ ë문ì ìì¸í ì¤ìº ì ë³´ë¡ ë°ì´í°ë² ì´ì¤ë¥¼ ì
ë°ì´í¸í ì ìì: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì´(ê°) ì¤í ë¦¬ì§ í %(pool)sì ììµëë¤."
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(volume)sì(를) ìì±íë ¤ë©´ %(item)sì(를) ì§ì íììì¤."
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"ì¤í ë¦¬ì§ í %(pool)sì´(ê°) íì±ì´ ìëë¯ë¡ ì¤í ë¦¬ì§ ë³¼ë¥¨ì ëì´í ì ììµë"
-"ë¤."
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì(를) ì¤í ë¦¬ì§ í %(pool)sì ìì±í ì ììµëë¤. ì¸ë¶"
-"ì¬í: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"ì¤í ë¦¬ì§ í %(pool)sì ì¤í ë¦¬ì§ ë³¼ë¥¨ì ëì´í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì í¬ê¸°ë¥¼ ì¡°ì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "ì¤í ë¦¬ì§ ì í %(type)sì(ë) 볼륨 ìì± ë° ìì 를 ì§ìíì§ ììµëë¤."
-
-msgid "Storage volume name must be a string"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ í ë¹ì ì ìì¬ì¼ í©ëë¤."
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ì 볼륨 ì´ë¦ì´ íìí©ëë¤."
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"ì¤ë¥ ë문ì ì¤í ë¦¬ì§ ë³¼ë¥¨ ì ë³´ë¡ ë°ì´í°ë² ì´ì¤ë¥¼ ì
ë°ì´í¸í ì ìì: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "ì¸í°íì´ì¤ %(name)sì´(ê°) ììµëë¤."
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "ë¤í¸ìí¬ %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "ë¤í¸ìí¬ %(name)sì´(ê°) ììµëë¤."
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"ë¤í¸ìí¬ %(network)sì ëí´ ì§ì ë ìë¸ë· %(subnet)sì´(ê°) ì í¨íì§ ììµëë¤."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"ë¸ë¦¿ì§ë ë¤í¸ìí¬ %(name)sì(를) ìì±í ë¤í¸ìí¬ ì¸í°íì´ì¤ë¥¼ ì§ì íììì¤."
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "íì± ë¤í¸ìí¬ %(name)sì(를) ìì í ì ììµëë¤."
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-"ë¤í¸ìí¬ %(network)sì ëí´ ì§ì ë ì¸í°íì´ì¤ %(iface)sì´(ê°) ì´ë¯¸ ì¬ì© ì¤ì
"
-"ëë¤."
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "ì¸í°íì´ì¤ë ìì NIC, ë³¸ë© ëë ë¸ë¦¿ì§ ì¥ì¹ì¬ì¼ í©ëë¤."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "ë¤í¸ìí¬ %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "ë¤í¸ìí¬ '%(name)s'ì ëí ì¬ì IP 주ì를 ì°¾ì ì ììµëë¤."
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "ì§ìëë ë¤í¸ìí¬ ì íì 격리, NAT ë° ë¸ë¦¿ì§ì
ëë¤."
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"ë¤í¸ìí¬ ìë¸ë·ì IP 주ì ë° ì ëë¶ ëë ë·ë§ì¤í¬ê° ìë 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Network interface must be a string"
-msgstr "ë¤í¸ìí¬ ì¸í°íì´ì¤ë 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "ë¤í¸ìí¬ VLAN IDë 1ê³¼ 4094 ì¬ì´ì ì ìì¬ì¼ í©ëë¤."
-
-msgid "Specify name and type to create a Network"
-msgstr "ë¤í¸ìí¬ë¥¼ ìì±íë ¤ë©´ ì´ë¦ ë° ì íì ì§ì íììì¤."
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "ë¸ë¦¿ì§ ì¥ì¹ %(name)sì(ë) VLANì í¸ë í¬ ì¥ì¹ê° ë ì ììµëë¤."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "%(iface)s ì¸í°íì´ì¤ë¥¼ íì±ííì§ ëª»í¨: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"%(iface)s ì¸í°íì´ì¤ë¥¼ íì±ííì§ ëª»íìµëë¤. 물리ì ë§í¬ ìí를 íì¸íìì"
-"ì¤."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "ëë²ê·¸ ë³´ê³ ì %(name)sì´(ê°) ììµëë¤."
-
-msgid "Debug report tool not found in system"
-msgstr "ëë²ê·¸ ë³´ê³ ì ëêµ¬ê° ìì¤í
ì ììµëë¤."
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "ëë²ê·¸ ë³´ê³ ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "ëë²ê·¸ ë³´ê³ ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"ì´ë¦ì´ '%(name)s'ì¸ ë³¼ë¥¨ ê·¸ë£¹ì´ ì´ë¯¸ ì¡´ì¬í©ëë¤. ë
¼ë¦¬ íì ìì±íë ¤ë©´ ë¤ë¥¸ ì´"
-"ë¦ì ì ííììì¤."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "ì¤í ë¦¬ì§ ìë² %(server)sì(ë) Kimchiìì ì¬ì©ëì§ ìììµëë¤."
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s'ì´(ê°) ììµëë¤."
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "íí°ì
%(name)sì´(ê°) í¸ì¤í¸ì ììµëë¤."
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr "ê°ì 머ì ì ì¤í ì¤ì¸ í¸ì¤í¸ 머ì ì ì¢
ë£í ì ììµëë¤."
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "ê°ì 머ì ì ì¤í ì¤ì¸ í¸ì¤í¸ 머ì ì ë¤ì ë¶í
í ì ììµëë¤."
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "ë
¸ë ì¥ì¹ '%(name)s'ì´(ê°) ììµëë¤."
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "ì
ë°ì´í¸ íìë í¨í¤ì§ê° ììµëë¤."
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "í¨í¤ì§ %(name)sì(ë) ì
ë°ì´í¸ëëë¡ íìëì§ ìììµëë¤."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"ì
ë°ì´í¸ëëë¡ íìë í¨í¤ì§ë¥¼ ê°ì ¸ì¤ë ì¤ì ì¤ë¥ê° ë°ìíìµëë¤. ì¸ë¶ì¬í: %"
-"(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "ì´ ìì¤í
ì ëí´ í¸í ê°ë¥í í¨í¤ì§ ê´ë¦¬ìê° ììµëë¤."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "ì¬ë°ë¥´ì§ ìì URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "ì¬ë°ë¥´ì§ ìì ì¤í ë¦¬ì§ ì íì
ëë¤. ì§ìëë ì í: 'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "ì ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ìì±íë ì¤ì ì¤ë¥ ë°ì: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì
ë°ì´í¸íë ì¤ì ì¤ë¥ ë°ì: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì ê±°íë ì¤ì ì¤ë¥ ë°ì: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "ì ê°ì 머ì ëì¤í¬ë¥¼ ì¶ê°í ì í ë° ê²½ë¡ë¥¼ ì§ì íììì¤."
-
-msgid "Specify path to update virtual machine disk"
-msgstr "ê°ì 머ì ëì¤í¬ë¥¼ ì
ë°ì´í¸í ê²½ë¡ë¥¼ ì§ì íììì¤."
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "ì ê°ì 머ì ëì¤í¬ë¥¼ ì¶ê°í ì í ë° ê²½ë¡ë¥¼ ì§ì íììì¤."
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM ì ì¥ì IDë ë¨ì¼ ë¨ì´ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "ì ì¥ì URLì http://, ftp:// ëë file:// URLì´ì´ì¼ í©ëë¤."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr "ì ì¥ì 구ì±ì ì ì¥ì ì íì ë°ë¥¸ í¹ì ê°ì´ ìë ì¬ì ì
ëë¤."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "DEB ì ì¥ìì ëí ë°°í¬ë 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "DEB ì ì¥ìì ëí 구ì±ììë ë°°ì´ì ëì´ëì´ì¼ í©ëë¤."
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEB ì ì¥ìì ëí 구ì±ììë 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUM ì ì¥ì ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG ê²ì¬ë ë¶ì¸ ê°ì´ì´ì¼ í©ëë¤."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG í¤ë ASCII ë³´í¸ íì¼ì ê°ë¦¬í¤ë URLì´ì´ì¼ í©ëë¤."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "%(repo_id)s ì ì¥ì를 ì
ë°ì´í¸í ì ììµëë¤."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "%(repo_id)s ì ì¥ìê° ììµëë¤."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "í´ë¹ ìì¤í
ì ëí ì ì¥ì ê´ë¦¬ ëêµ¬ê° ì¸ìëì§ ìììµëë¤."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "%(repo_id)s ì ì¥ìê° ì´ë¯¸ ì¬ì©ì¼ë¡ ì¤ì ëì´ ììµëë¤."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "%(repo_id)s ì ì¥ìê° ì´ë¯¸ ì¬ì© ìí¨ì¼ë¡ ì¤ì ëì´ ììµëë¤."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "%(repo_id)s ì ì¥ì를 ì ê±°í ì ììµëë¤."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "ì ì¥ì êµ¬ì± íì¼ %(repo_file)sì(를) ìì±í ì ììµëë¤."
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "DEB ì ì¥ì를 ìì±íë ¤ë©´ ì ì¥ì ë°°í¬ë¥¼ ì§ì íììì¤."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "%(repo_id)s ì ì¥ì를 ì¬ì©ì¼ë¡ ì¤ì í ì ììµëë¤."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "%(repo_id)s ì ì¥ì를 ì¬ì© ìí¨ì¼ë¡ ì¤ì í ì ììµëë¤."
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM ì ì¥ì IDê° ì´ë¯¸ ì¡´ì¬í©ëë¤."
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM ì ì¥ì ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "ì ì¥ì를 ëì´í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "ì ì¥ì ì 보를 ëì´í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "ì ì¥ì를 ì¶ê°í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "ì ì¥ì를 ì ê±°í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "ì¤ë¥ ì½ë"
-
-msgid "REASON"
-msgstr "ì´ì "
-
-msgid "STACK"
-msgstr "ì¤í"
-
-msgid "Go to Homepage"
-msgstr "í íì´ì§ë¡ ì´ë"
-
-msgid "Create a New Virtual Machine"
-msgstr "ì ê°ì 머ì ìì±"
-
-msgid "Virtual Machine Name"
-msgstr "ê°ì 머ì ì´ë¦"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"ê°ì 머ì ì ìë³íë ë° ì¬ì©ëë ì´ë¦ì
ëë¤. ìëµëë©´ ì´ë¦ì ì¬ì©ë í
í리í¸"
-"를 기ë°ì¼ë¡ ì íë©ëë¤."
-
-msgid "Template"
-msgstr "í
í리í¸"
-
-msgid "Please create a template first."
-msgstr "í
í리í¸ë¥¼ 먼ì ìì±íììì¤."
-
-msgid "Create a Template"
-msgstr "í
íë¦¬í¸ ìì±"
-
-msgid "Please choose a template."
-msgstr "í
í리í¸ë¥¼ ì ííììì¤."
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "OS ë²ì "
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "ë©ëª¨ë¦¬"
-
-msgid "Create"
-msgstr "ìì±"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "ì·¨ì"
-
-msgid "Edit Guest"
-msgstr "ê²ì¤í¸ í¸ì§"
-
-msgid "General"
-msgstr "ì¼ë°"
-
-msgid "Storage"
-msgstr "ì¤í 리ì§"
-
-msgid "Interface"
-msgstr "ì¸í°íì´ì¤"
-
-msgid "Permission"
-msgstr "ë²ì "
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "ì´ë¦"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "ë©ëª¨ë¦¬"
-
-msgid "Icon"
-msgstr "ìì´ì½"
-
-msgid "Device"
-msgstr "ì¥ì¹ ì´ë¦"
-
-msgid "Path"
-msgstr "NFS ê²½ë¡"
-
-msgid "Network"
-msgstr "ë¤í¸ìí¬"
-
-msgid "Type"
-msgstr "ì í"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "모ë"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "ê³µê¸ì
ì²´"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "ì ì¥"
-
-msgid "Replace"
-msgstr "êµì²´"
-
-msgid "Detach"
-msgstr "ë¶ë¦¬"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "ìì"
-
-msgid "Reset"
-msgstr "ë¤ì ì¤ì "
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "ì¡°ì¹"
-
-msgid "Connect"
-msgstr "ì°ê²°"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "í¸ì§"
-
-msgid "Shut Down"
-msgstr "ìì¤í
ì¢
ë£"
-
-msgid "Delete"
-msgstr "ìì "
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "ëì¤í¬ I/O"
-
-msgid "Network I/O"
-msgstr "ë¤í¸ìí¬ I/O"
-
-msgid "Livetile"
-msgstr "ë¼ì´ë¸íì¼"
-
-msgid "No guests found."
-msgstr "ê²ì¤í¸ê° ììµëë¤."
-
-msgid "Add a Storage Device to VM"
-msgstr "ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ VMì ì¶ê°"
-
-msgid "Device Type"
-msgstr "ì¥ì¹ ì í"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "ì¥ì¹ ì íì
ëë¤. íì¬ \"cdrom\"ë§ ì§ìë©ëë¤."
-
-msgid "Storage Pool"
-msgstr "ì¤í ë¦¬ì§ í"
-
-msgid "Storage pool which volume located in"
-msgstr "ì¤í ë¦¬ì§ í ê²½ë¡ë 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "Storage Volume"
-msgstr "ì¤í ë¦¬ì§ í ì´ë¦"
-
-msgid "Storage volume to be attached"
-msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
-
-msgid "File Path"
-msgstr "íì¼ ê²½ë¡"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "CDROMì ìí ìë²ì ISO íì¼ ê²½ë¡ì
ëë¤."
-
-msgid "Attach"
-msgstr "ì°ê²°"
-
-msgid "Shut down"
-msgstr "ìì¤í
ì¢
ë£"
-
-msgid "Restart"
-msgstr "ë¤ì ìì"
-
-msgid "Basic Information"
-msgstr "기본 ì ë³´"
-
-msgid "OS Distro"
-msgstr "OS Distro"
-
-msgid "OS Code Name"
-msgstr "OS ì½ë ì´ë¦"
-
-msgid "Processor"
-msgstr "íë¡ì¸ì"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "ìì¤í
íµê³"
-
-msgid "Software Updates"
-msgstr "ìíí¸ì¨ì´ ì
ë°ì´í¸"
-
-msgid "Update Progress"
-msgstr "ì§íìí ì
ë°ì´í¸"
-
-msgid "Repositories"
-msgstr "ì ì¥ì"
-
-msgid "Debug Reports"
-msgstr "ëë²ê·¸ ë³´ê³ ì"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"ì
ë ¥í ì¬ì©ì ì´ë¦ ëë ë¹ë°ë²í¸ê° ì¬ë°ë¥´ì§ ììµëë¤. ë¤ì ìëíììì¤."
-
-msgid "This field is required."
-msgstr "ì´ íëë íìì
ëë¤."
-
-msgid "Log in"
-msgstr "ë¡ê·¸ì¸"
-
-msgid "Logging in..."
-msgstr "ë¡ê·¸ì¸ ì¤..."
-
-msgid "Host"
-msgstr "í¸ì¤í¸"
-
-msgid "Guests"
-msgstr "ê²ì¤í¸"
-
-msgid "Templates"
-msgstr "í
í리í¸"
-
-msgid "Failed to get application configuration"
-msgstr "ì í리ì¼ì´ì
구ì±ì ê°ì ¸ì¤ì§ 못íìµëë¤."
-
-msgid "This is not a valid Linux path"
-msgstr "ì¬ë°ë¥¸ Linux ê²½ë¡ê° ìëëë¤."
-
-msgid "This is not a valid URL."
-msgstr "ì¬ë°ë¥¸ URLì´ ìëëë¤."
-
-msgid "No such data available."
-msgstr "í´ë¹ ë°ì´í°ê° ììµëë¤."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"í¸ì¤í¸ ìì¤í
ì ì ìí ì ììµëë¤. í¸ì¤í¸ ìì¤í
ì´ ê°ëëìê³ ì´ì ëí ë¤í¸"
-"ìí¬ ì°ê²°ì´ ìëì§ íì¸íììì¤. HTTP ìì² ìëµ %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "ìì íì¸"
-
-msgid "OK"
-msgstr "íì¸"
-
-msgid "Confirm"
-msgstr "íì¸"
-
-msgid "Warning"
-msgstr "ê²½ê³ "
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "ë¡ë ì¤..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "ì¬ìë"
-
-msgid "Detailed message:"
-msgstr "ì¸ë¶ ë©ìì§:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "ì¬ë°ë¥¸ ISO íì¼ì´ ìëëë¤."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "ìê°ì´ ì¤ë 걸립ëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "í
í리í¸ê° ì구ì ì¼ë¡ ìì ë©ëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr "ì¼ë¶ ê°ì 머ì ì´ ì¤í ì¤ì´ë¯ë¡ ìì¤í
ì ì¢
ë£í ì ììµëë¤."
-
-msgid "Max:"
-msgstr "ìµë:"
-
-msgid "Utilization"
-msgstr "ì´ì©ë¥ "
-
-msgid "Available"
-msgstr "ì¬ì© ê°ë¥"
-
-msgid "Read Rate"
-msgstr "ì½ê¸° ìë"
-
-msgid "Write Rate"
-msgstr "ì°ê¸° ìë"
-
-msgid "Received"
-msgstr "ë°ì"
-
-msgid "Sent"
-msgstr "ë³´ë"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"í¸ì¤í¸ë¥¼ ì¢
ë£íê±°ë ë¤ì ììíë©´ ì ì¥ëì§ ìì ìì
ì´ ìì¤ë©ëë¤. ìì¤í
ì¢
"
-"ë£/ë¤ì ììì ê³ìíìê² ìµëê¹?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr "ì ì¥ìê° ì구ì ì¼ë¡ ì ê±°ëì´ ë³µêµ¬í ì ììµëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "기본 URL"
-
-msgid "Is Mirror"
-msgstr "미ë¬ì"
-
-msgid "URL Args"
-msgstr "URL ì¸ì"
-
-msgid "Enabled"
-msgstr "ì¬ì©í¨"
-
-msgid "GPG Check"
-msgstr "GPG ê²ì¬"
-
-msgid "GPG Key"
-msgstr "GPG í¤"
-
-msgid "Add"
-msgstr "ì¶ê°"
-
-msgid "Remove"
-msgstr "ì ê±°"
-
-msgid "Enable"
-msgstr "ì¬ì©"
-
-msgid "Disable"
-msgstr "ì¬ì© ìí¨"
-
-msgid "Package Name"
-msgstr "í¨í¤ì§ ì´ë¦"
-
-msgid "Version"
-msgstr "ë²ì "
-
-msgid "Architecture"
-msgstr "ìí¤í
ì²"
-
-msgid "Repository"
-msgstr "ì ì¥ì"
-
-msgid "Update All"
-msgstr "모ë ì
ë°ì´í¸"
-
-msgid "Updating..."
-msgstr "ì
ë°ì´í¸ ì¤..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "í¨í¤ì§ë¥¼ ì
ë°ì´í¸íì§ ëª»íìµëë¤."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"ëë²ê·¸ ë³´ê³ ìê° ì구ì ì¼ë¡ ì ê±°ëì´ ë³µêµ¬í ì ììµëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "Generated Time"
-msgstr "ìì± ìê°"
-
-msgid "Generate"
-msgstr "ìì±"
-
-msgid "Generating..."
-msgstr "ìì± ì¤..."
-
-msgid "Rename"
-msgstr "ì´ë¦ ë°ê¾¸ê¸°"
-
-msgid "Download"
-msgstr "ë¤ì´ë¡ë"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr "ë³´ê³ ì ì´ë¦ìë 문ì, ì«ì ë°/ëë íì´í('-')ë§ í¬í¨ëì´ì¼ í©ëë¤."
-
-msgid "Pending..."
-msgstr "ë¡ë ì¤..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"ê°ì 머ì ë° í´ë¹ ê°ì ëì¤í¬ê° ìì ë©ëë¤. ì´ ì¡°ìì ì¤í ì·¨ìí ì ììµë"
-"ë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "Power off Confirmation"
-msgstr "ìì íì¸"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "ìì íì¸"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "ìì íì¸"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "í
í리í¸ê° ì구ì ì¼ë¡ ìì ë©ëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"ì´ CDROMì ì구ì ì¼ë¡ ë¶ë¦¬ëë©° ë¤ì ì°ê²°í ì ììµëë¤. ë¶ë¦¬ë¥¼ ê³ìíìê² ìµë"
-"ê¹?"
-
-msgid "Attaching..."
-msgstr "ì°ê²° ì¤..."
-
-msgid "Replacing..."
-msgstr "êµì²´ ì¤..."
-
-msgid "Successfully attached!"
-msgstr "ì°ê²°ëììµëë¤."
-
-msgid "Successfully replaced!"
-msgstr "êµì²´ëììµëë¤."
-
-msgid "Successfully detached!"
-msgstr "ë¶ë¦¬ëììµëë¤."
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN IDë 1ê³¼ 4094 ì¬ì´ì¬ì¼ í©ëë¤."
-
-msgid "unavailable"
-msgstr "ì¬ì© ë¶ê°ë¥"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"ì´ ì¡°ì¹ë ì´ ë¤í¸ìí¬ì ìì¡´íë ê°ì 머ì ì ë¤í¸ìí¬ ì°ê²°ì ì¸í°ë½í¸í©ëë¤."
-
-msgid "Create a network"
-msgstr "ë¤í¸ìí¬ ìì±"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"ì´ ì¤í ë¦¬ì§ íì ì§ìì ì´ì§ ììµëë¤. ì´ ì¡°ì¹ë íì ë¹íì±ííì§ ìê³ ì구ì "
-"ì¼ë¡ ìì í©ëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "ì¤í ë¦¬ì§ íì´ ì구ì ì¼ë¡ ìì ë©ëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "This storage pool is empty."
-msgstr "ì´ ì¤í ë¦¬ì§ íì ë¹ì´ ììµëë¤."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr "ëì¤í¬ê° í¬ë§·ëê³ ë°ì´í°ê° ìì¤ë©ëë¤. ê³ìíìê² ìµëê¹? "
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI íì´ë² ì±ë"
-
-msgid "No SCSI adapters found."
-msgstr "SCSI ì´ëí°ê° ììµëë¤."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "ì¤í ë¦¬ì§ í ì´ë¦ì ë¹ìë ì ììµëë¤."
-
-msgid "The storage pool path can not be blank."
-msgstr "ì¤í ë¦¬ì§ í ê²½ë¡ë ë¹ìë ì ììµëë¤."
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFS ìë² ë§ì´í¸ ê²½ë¡ë ë¹ìë ì ììµëë¤."
-
-msgid "Invalid NFS mount path."
-msgstr "ì¬ë°ë¥´ì§ ìì NFS ë§ì´í¸ ê²½ë¡ì
ëë¤."
-
-msgid "No logical device selected."
-msgstr "ë
¼ë¦¬ ì¥ì¹ê° ì íëì§ ìììµëë¤."
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSI ëìì ë¹ìë ì ììµëë¤."
-
-msgid "Server name can not be blank."
-msgstr "ìë² ì´ë¦ì ë¹ìë ì ììµëë¤."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "ì¬ì© ê°ë¥í íí°ì
ì ì°¾ë ì¤..."
-
-msgid "No available partitions found."
-msgstr "ì¬ì© ê°ë¥í íí°ì
ì´ ììµëë¤."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"ì´ ì¤í ë¦¬ì§ íì ì§ìì ì´ì§ ììµëë¤. ì´ ì¡°ì¹ë íì ë¹íì±ííì§ ìê³ ì구ì "
-"ì¼ë¡ ìì í©ëë¤. ê³ìíìê² ìµëê¹?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "ì ì¥ì ì 보를 ëì´í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "ì¤í ë¦¬ì§ í ì´ë¦ì ë¹ìë ì ììµëë¤."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "ë¤í¸ìí¬ ì´ë¦"
-
-msgid "State"
-msgstr "ìí"
-
-msgid "Network Type"
-msgstr "ë¤í¸ìí¬ ì í"
-
-msgid "Address Space"
-msgstr "주ì ê³µê°"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "ì¬ë°ë¥´ì§ ìì ì¤í ë¦¬ì§ í ì´ë¦ì
ëë¤. '/'를 í¬í¨íì§ ììì¼ í©ëë¤."
-
-msgid "Isolated: no external network connection"
-msgstr "격리ë¨: 물리ì ë¤í¸ìí¬ ì°ê²° ìì"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: ììë°ì´ë 물리ì ë¤í¸ìí¬ ì°ê²°ë§"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "ë¸ë¦¿ì§ë¨: ê°ì 머ì ì´ ë¬¼ë¦¬ì ë¤í¸ìí¬ì ì§ì ì°ê²°ë¨"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "ëì:"
-
-msgid "Enable VLAN"
-msgstr "VLAN ì¬ì©:"
-
-msgid "VLAN ID"
-msgstr "VLAN ID:"
-
-msgid "Stop"
-msgstr "ì¤ì§"
-
-msgid "Generate a New Debug Report"
-msgstr "ì ëë²ê·¸ ë³´ê³ ì ìì±"
-
-msgid "Report Name"
-msgstr "ë³´ê³ ì ì´ë¦"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"ë³´ê³ ì를 ìë³íë ë° ì¬ì©ëë ì´ë¦ì
ëë¤. ìëµëë©´ ì´ë¦ì íì¬ ìê°ì 기ë°ì¼"
-"ë¡ ì íë©ëë¤. ì´ë¦ì 문ì, ì«ì ë° íì´í(\"-\")ì í¬í¨í ì ììµëë¤."
-
-msgid "Rename a Debug Report"
-msgstr "ì ëë²ê·¸ ë³´ê³ ì ìì±"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"ë³´ê³ ì를 ìë³íë ë° ì¬ì©ëë ì´ë¦ì
ëë¤. ìëµëë©´ ì´ë¦ì íì¬ ìê°ì 기ë°ì¼"
-"ë¡ ì íë©ëë¤. ì´ë¦ì 문ì, ì«ì ë° íì´í(\"-\")ì í¬í¨í ì ììµëë¤."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "ì ì¥ì ì¶ê°"
-
-msgid "Identifier"
-msgstr "ID"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "ì ì¥ìì ëí ë¨ì¼ ë¨ì´ì ê³ ì IDì
ëë¤."
-
-msgid "Textual name for the repository."
-msgstr "ì ì¥ìì ëí í
ì¤í¸ ì´ë¦ì
ëë¤."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "íì íë"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "ì ì¥ìì ëí URLì
ëë¤. ì§ìëë íë¡í ì½ì http, ftp ë° fileì
ëë¤."
-
-msgid "Repository is a mirror"
-msgstr "ì ì¥ìê° ë¯¸ë¬ì
ëë¤."
-
-msgid "Distribution"
-msgstr "ë°°í¬"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEB ì ì¥ìì ë°°í¬ì
ëë¤."
-
-msgid "Components"
-msgstr "구ì±ìì"
-
-msgid "List of components in DEB repository."
-msgstr "DEB ì ì¥ìì 구ì±ìì 목ë¡ì
ëë¤."
-
-msgid "Edit Repository"
-msgstr "ì ì¥ì í¸ì§"
-
-msgid "Mirror List URL"
-msgstr "ë¯¸ë¬ ëª©ë¡ URL"
-
-msgid "Yes"
-msgstr "ì"
-
-msgid "No"
-msgstr "ìëì¤"
-
-msgid "Capacity"
-msgstr "ì©ë"
-
-msgid "Allocated"
-msgstr "í ë¹ë¨"
-
-msgid "Location"
-msgstr "ìì¹"
-
-msgid "Device path"
-msgstr "ì¥ì¹ ê²½ë¡"
-
-msgid "active"
-msgstr "íì±"
-
-msgid "inactive"
-msgstr "ë¹íì±"
-
-msgid "Deactivate"
-msgstr "ë¹íì±í"
-
-msgid "Activate"
-msgstr "íì±í"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "ì ì ì·¨ì"
-
-msgid "Format"
-msgstr "í¬ë§·:"
-
-msgid "Allocation"
-msgstr "í ë¹:"
-
-msgid "Define a New Storage Pool"
-msgstr "ì ì¤í ë¦¬ì§ í ì ì"
-
-msgid "Storage Pool Name"
-msgstr "ì¤í ë¦¬ì§ í ì´ë¦"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "ì¤í ë¦¬ì§ íì ìë³íë ë° ì¬ì©ëë ì´ë¦ì´ë©° ë¹ì´ ìì§ ììì¼ í©ëë¤."
-
-msgid "Storage Pool Type"
-msgstr "ì¤í ë¦¬ì§ í ì í"
-
-msgid "Storage Path"
-msgstr "ì¤í ë¦¬ì§ ê²½ë¡"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr "ì¤í ë¦¬ì§ íì ê²½ë¡ì
ëë¤. ê° ì¤í ë¦¬ì§ íì ê³ ì ê²½ë¡ë¥¼ ê°ì ¸ì¼ í©ëë¤."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"ëë í ë¦¬ê° ìì¤í
ì ì´ë¯¸ ì¡´ì¬íì§ ìì¼ë©´ Kimchiê° ëë í 리 ìì±ì ìëí©ëë¤."
-
-msgid "NFS Server IP"
-msgstr "NFS ìë² IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"NFS ìë² IP ëë í¸ì¤í¸ ì´ë¦ì
ëë¤. ì´ê²ì ì
ë ¥íê±°ë íì¤í 리ìì ì íí ì "
-"ììµëë¤."
-
-msgid "NFS Path"
-msgstr "NFS ê²½ë¡"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFS ìë²ìì NFSì ë´ë³´ë¸ ê²½ë¡ì
ëë¤."
-
-msgid "iSCSI Server"
-msgstr "iSCSI ìë²"
-
-msgid "Server"
-msgstr "ìë²"
-
-msgid "Port"
-msgstr "í¬í¸"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSI ìë² IP ëë í¸ì¤í¸ ì´ë¦ì
ëë¤. ë¹ì´ ìì§ ììì¼ í©ëë¤."
-
-msgid "Target"
-msgstr "ëì"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSI ìë²ì iSCSI ëì"
-
-msgid "Add iSCSI Authentication"
-msgstr "iSCSI ì¸ì¦ ì¶ê°"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI ì¸ì¦"
-
-msgid "User Name"
-msgstr "ì¬ì©ì ì´ë¦"
-
-msgid "Password"
-msgstr "ë¹ë°ë²í¸"
-
-msgid "SCSI Adapter"
-msgstr "SCSI ì´ëí°"
-
-msgid "Please, wait..."
-msgstr "ì ì 기ë¤ë ¤ 주ììì¤."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "í
íë¦¬í¸ ì¶ê°"
-
-msgid "Where is the source media for this template? "
-msgstr "ì´ í
í리í¸ì ìì¤ ë§¤ì²´ë ì´ëì ììµëê¹?"
-
-msgid "Local ISO Image"
-msgstr "ë¡ì»¬ ISO ì´ë¯¸ì§"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "ì격 ISO ì´ë¯¸ì§"
-
-msgid "Search ISOs"
-msgstr "ISO ê²ì"
-
-msgid "The following ISOs are available:"
-msgstr "ë¤ì ISOê° ì¬ì© ê°ë¥í©ëë¤."
-
-msgid "OS: "
-msgstr "OS: "
-
-msgid "Version: "
-msgstr "ë²ì : "
-
-msgid "Size: "
-msgstr "í¬ê¸°: "
-
-msgid "Search more ISOs"
-msgstr "ì¶ê° ISO ê²ì"
-
-msgid "Create Templates from Selected ISO"
-msgstr "ì íí ISOë¡ë¶í° í
íë¦¬í¸ ìì±"
-
-msgid "I want to use a specific ISO file"
-msgstr "í¹ì ISO íì¼ì ì¬ì©íë ¤ê³ í©ëë¤."
-
-msgid "Loading default remote ISOs ..."
-msgstr "기본 ì격 ISO ë¡ë ì¤..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "ì¬ì©ì ì ì URLì ì¬ì©íë ¤ê³ í©ëë¤."
-
-msgid "Edit Template"
-msgstr "í
íë¦¬í¸ í¸ì§"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "ê·¸ëí½"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU ë²í¸"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "í
í리í¸ê° ììµëë¤."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "%(resource)sì ìì ë íì©ëì§ ìì"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)sììë ì
ë°ì´í¸ ë©ìë를 구ííì§ ìì"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "%(resource)sì ìì±ì íì©ëì§ ìì"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "JSON ìì²ì 구문 ë¶ìí ì ììµëë¤."
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "ì´ APIë JSONë§ ì§ìí©ëë¤."
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "ë°ì´í° ì ì¥ìê° ëª¨ë¸ ì¤ë¸ì í¸ìì ììëì§ ìììµëë¤."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "ì¤ë¥ ë문ì ìì
ì ììí ì ìì: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr "ì¬ì©ì '%(username)s'ì ì¸ì¦ì´ ì¤í¨íìµëë¤. [ì¤ë¥ ì½ë: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Kimchiì ì¡ì¸ì¤í ê¶íì´ ììµëë¤."
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Kimchiì ë¡ê·¸ì¸íë ¤ë©´ %(item)sì(를) ì§ì íììì¤."
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "ë°ì´í° ì ì¥ììì %(item)sì(를) ì°¾ì ì ììµëë¤."
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr ""
-#~ "%(seconds)sì´ íì '%(cmd)s' ëª
ë ¹ ì¤í ì¤ ì íìê°ì´ ì´ê³¼ëììµëë¤."
-
-#~ msgid "Help"
-#~ msgstr "ëìë§"
-
-#~ msgid "About"
-#~ msgstr "ì ë³´"
-
-#~ msgid "Log out"
-#~ msgstr "ë¡ê·¸ìì"
-
-#~ msgid "Version:"
-#~ msgstr "ë²ì : "
diff --git a/plugins/kimchi/po/pt_BR.po b/plugins/kimchi/po/pt_BR.po
deleted file mode 100644
index c2cb4e9..0000000
--- a/plugins/kimchi/po/pt_BR.po
+++ /dev/null
@@ -1,2369 +0,0 @@
-# i18n portable object for kimchi.
-# Copyright (C) IBM, Corp. 2013-2014
-# ShaoHe Feng <shaohef at linux.vnet.ibm.com>, 2013-04-18.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2015-03-23 12:57+0000\n"
-"Last-Translator: CrÃstian Deives dos Santos Viana <cristiandeives at gmail."
-"com>\n"
-"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/"
-"kimchi/language/pt_BR/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt_BR\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr "Parâmetro desconhecido: %(value)s"
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-"Limite de tempo de %(seconds)s segundos expirado ao executar a tarefa '%"
-"(task)s'."
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr "Usuário %(user_id)s não encontrado com as configurações LDAP dadas."
-
-msgid "Unknown \"_cap\" specified"
-msgstr "\"_cap\" desconhecido especificado"
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr "\"_passthrough\" deve ser \"true\" ou \"false\""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr "\"_passthrough_affected_by\" deve ser um texto do nome do dispositivo"
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "Erro ao consultar block devices. Detalhes %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "Erro ao consultar informações de block devices para %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Não foi possÃvel encontrar o arquivo da distribuição: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"Não foi possÃvel ler o arquivo da distribuição: %(filename)s. Confirme se é "
-"um arquivo JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel logar na máquina alvo do iSCSI %(portal)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Não foi possÃvel logar na máquina %(host)s alvo %(target)s do iSCSI"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr "Não foi possÃvel encontrar a ISO %(filename)s"
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "A ISO %(filename)s não é bootável"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "A ISO %(filename)s não possui uma gravação válida de boot El Torito"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Validação El Torito inválida na ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicador de boot El Torito inválido na ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Tipo de volume não esperado para um volume primário na ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "Formato errado na leitura do descritor de volume na ISO %(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"O servidor não tem permissão para acessar a ISO %(filename)s. Considere mudá-"
-"la para o diretório /var/lib/libvirt, ou mude as permissões para que o "
-"usuário '%(user)s' tenha acesso, ou, adicione o usuário '%(user)s' no grupo "
-"do caminho da ISO, ou (não recomendado) 'chmod -R o+x 'caminho_para_iso'. "
-"Detalhes: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr "Ocorreu um erro ao identificar o sistema operacional da imagem."
-
-msgid "No OS information found in given image."
-msgstr ""
-"Nenhuma informação de sistema operacional encontrada na imagem fornecida."
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr "Não foi possÃvel ler o arquivo de imagem %(filename)s."
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-"Arquivo de imagem deve ser um arquivo existente no sistema. %(filename)s não "
-"é uma entrada válida."
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "Máquina virtual %(name)s já existe"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "Máquina virtual %(name)s não existe"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-"Não foi possÃvel renomear a máquina virtual %(name)s. O nome %(new_name)s já "
-"está em uso ou a máquina virtual não está ligada."
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Não foi possÃvel tirar uma foto da tela para a máquina virtual %(name)s que "
-"está desligada"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "Imagem de ISO remota não é suportada por esse servidor."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr "Foto da tela não é suportado na máquina virtual %(name)s"
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel criar a máquina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel atualizar a máquina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel encontrar a máquina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr "Não foi possÃvel conectar à máquina virtual desligada %(name)s."
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr "URI do Modelo inválida %(value)s especificada para máquina virtual"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-"URI do Storage pool URI inválida %(value)s especificada para máquina virtual"
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr "Gráficos suportados para a máquina virtual são Spice ou VNC"
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "Endereço para receber eventos gráficos deve ser IPv4 ou IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Especifique um modelo para ser base da criação da máquina virtual"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel iniciar a máquina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel forçar o desligamento da máquina virtual %(name)s. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel remover a máquina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel reiniciar a máquina virtual %(name)s. Detalhes: %(err)s"
-
-msgid "User name list must be an array"
-msgstr "Lista de nomes de usuário deve ser um array"
-
-msgid "User name must be a string"
-msgstr "Nome de usuário deve ser um texto"
-
-msgid "Group name list must be an array"
-msgstr "Lista de nomes de grupo deve ser um array"
-
-msgid "Group name must be a string"
-msgstr "Nome de grupo deve ser um texto"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "Usuário(s) '%(users)s' não existe(m)"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "Grupo(s) '%(groups)s' não existe(m)"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel desligar a máquina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel acessar os metadados da máquina virtual %(name)s. Detalhes: "
-"%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr "A senha para o console do guest deve ser um texto."
-
-msgid "The life time for the guest console password must be a number."
-msgstr "O tempo de vida da senha do console do guest deve ser um número."
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr "A máquina virtual '%(name)s' deve estar parada antes de cloná-la."
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr "Espaço em disco insuficiente para clonar a máquina virtual '%(name)s'"
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr "Não foi possÃvel clonar a VM '%(name)s'. Detalhes: %(err)s"
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr "Operação inválida para máquina virtual não-persistente %(name)s"
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-"A VM %(vmid)s não contém o dispositivo de host atribuÃdo diretamente %"
-"(dev_name)s."
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-"Não é permitido atribuir diretamente o dispositivo de host %(dev_name)s."
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-"Nenhum grupo IOMMU encontrado. Passthrough de host PCI necessita do grupo "
-"IOMMU para funcionar corretamente. Por favor, habilite o suporte ao Intel VT-"
-"d ou AMD IOMMU. Para uma CPU Intel, adicione \"intel_iommu=on\" nos seus "
-"parâmetros de kernel em \"/boot/grub2/grub.conf\". Para uma CPU AMD, "
-"adicione \"iommu=pt iommu=1\"."
-
-msgid "\"name\" should be a device name string"
-msgstr "\"nome\" deve ser um texto do nome do dispositivo."
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "Interface %(iface)s não existe na máquina virtual %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"Rede %(network)s especificada para a máquina virtual %(name)s não existe"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "Tipo de interface suportado das máquinas virtuais é somente rede"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "Nome da rede para a interface da máquina virtual deve ser texto"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr "Modelo de placa de rede inválido para a interface da máquina virtual"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Especifique o tipo e a rede para adicionar uma nova interface da máquina "
-"virtual"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Modelo %(name)s já existe"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr "Rede '%(network)s' especificada para o modelo %(template)s não existe"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Storage pool %(pool)s especificado para o modelo %(template)s não existe"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr ""
-"Storage pool %(pool)s especificado para o modelo %(template)s não está ativo"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Parâmetro inválido '%(param)s' especificado para CDROM"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "Rede %(network)s especificada para modelo %(template)s não está ativa"
-
-msgid "Template name must be a string"
-msgstr "Nome do modelo deve ser um texto"
-
-msgid "Template icon must be a path to the image"
-msgstr "Ãcone do modelo deve ser um caminho para uma imagem"
-
-msgid "Template distribution must be a string"
-msgstr "Distribuição do modelo deve ser um texto"
-
-msgid "Template distribution version must be a string"
-msgstr "Versão da distribuição do modelo deve ser um texto"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "O número de CPUs deve ser um inteiro maior do que 0"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "Quantidade de memória (MB) deve ser um inteiro maior que 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Modelo do CDROM deve ser um arquivo ISO local ou remoto"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "URI de storage pool inválido %(value)s especificado para modelo"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-"Especifique uma imagem ISO como CD-ROM ou uma imagem base para criar um "
-"modelo"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Todas redes para o modelo devem ser especificadas em uma lista"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-"Especifique um volume para o template quando o storage pool for iSCSI or SCSI"
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr "O volume %(volume)s não está no storage pool %(pool)s"
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "Não foi possÃvel criar o modelo devido a um erro: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "Não foi possÃvel remover o modelo devido a um erro: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr "O tamanho do disco deve ser um número inteiro maior que 1GB."
-
-msgid "Template base image must be a valid local image file"
-msgstr "Imagem base do modelo deve ser um arquivo de imagem local válido"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr "Não foi possÃvel identificar o formato da imagem base %(path)s"
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-"Ao especificar a topologia de CPU, VCPUs deve ser um produto de sockets, "
-"cores e threads."
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-"Ao especificar a topologia de CPU, cada elemento deve ser um número inteiro "
-"maior do que zero."
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"Formato de imagem de disco inválido. Formatos válidos: bochs, cloop, cow, "
-"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Storage pool %(name)s já existe"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Storage pool %(name)s não existe"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Especifique %(item)s para criar o storage pool %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Não foi possÃvel remover o storage pool ativo %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Não foi possÃvel listar os storage pools. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel criar o storage pool %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Não foi possÃvel saber o número de volumes no storage pool %(name)s. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Não foi possivel ativar o storage pool %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "Não foi possivel desativar o storage pool %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "Não foi possivel remover o storage pool %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"Não foi possÃvel criar Pool NFS uma vez que o caminho de exportação %(path)s "
-"pode bloquear durante a montagem"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"Não foi possÃvel criar NFS Pool uma vez que a montagem do caminho de "
-"exportação %(path)s falhou"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Tipo de storage pool não suportado: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr "Erro durante a leitura do XML do storage pool %(pool)s"
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-"Tipos de storage pool supportados são dir, netfs, logical, iscsi, scsi e "
-"kimchi-iso"
-
-msgid "Storage pool path must be a string"
-msgstr "Caminho para storage pool deve ser um texto"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "Host do storage pool deve ser um IP ou um hostname"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-"Dispositivo do storage pool deve ser o caminho absoluto para o block device"
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Parâmetro dos dispositivos do storage pool devem ser uma lista"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "Alvo IQN de um pool iSCSI deve ser um texto"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"Porta de um servidor remoto de storage deve ser um inteiro entre 1 e 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr "Usuário do iSCSI target deve ser um texto"
-
-msgid "iSCSI target password must be a string"
-msgstr "Senha do iSCSI target deve ser um texto"
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Especifique o nome e o tipo para criar um storage pool"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s não é um disco/partição válido. Não foi possÃvel adicioná-lo ao "
-"pool %(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr "Não foi possÃvel extender o pool lógico %(pool)s. Detalhes: %(err)s"
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"O parâmetro discos somente pode ser atualizado para storage pool lógicos."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "O nome do adaptador SCSI host deve ser um texto"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "O storage pool kimchi_isos é reservado para uso interno"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Não foi possÃvel ativar o storage pool NFS %(name)s. Servidor NFS %(server)s "
-"está inacessÃvel."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Não foi possÃvel desativar o storage pool NFS %(name)s. Servidor NFS %"
-"(server)s está inacessÃvel."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Não foi possÃvel desativar o pool %(name)s uma vez que ele está associado "
-"com algum dos modelos"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"Não foi possÃvel remover o pool %(name)s uma vez que ele está associado com "
-"algum dos modelos"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"Um grupo de volume chamado '%(name)s' já existe. Por favor, escolha outro "
-"nome para criar o pool lógico."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"Não foi possÃvel atualizar a base de dados com informações de mais ISOs "
-"devido a um erro: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Volume de storage %(name)s já existe"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "Volume de storage %(name)s não existe no storage pool %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-"Não foi possÃvel criar o storaget volume %(volume)s pois o storage pool %"
-"(pool)s não está ativo"
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Especifique %(item)s para poder criar o volume %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"Não foi possÃvel listar volumes pois o storage pool %(pool)s não está ativo"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"Não foi possÃvel criar o volume %(name)s no storage pool %(pool)s. Detalhes: "
-"%(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel listar os volumes do storage pool %(pool)s. Detalhes: %(err)"
-"s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel limpar o volume %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel remover o volume %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel redimensionar o volume %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "Storage do tipo %(type)s não suporta criação ou remoção de volume"
-
-msgid "Storage volume name must be a string"
-msgstr "Nome do volume deve ser um texto"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "Alocação do volume de storage deve ser um número inteiro"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"Formato de volume de storage inválido. Formatos válidos: bochs, cloop, cow, "
-"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
-
-msgid "Storage volume requires a volume name"
-msgstr "Volume de storage requer um nome"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Não foi possÃvel atualizar a base de dados com informações de volume de "
-"storage devido a um erro: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr "Somente um parâmetro %(param)s pode ser especificado"
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr "Criar um volume a partir de %(param)s não é suportado"
-
-msgid "Storage volume capacity must be an integer number."
-msgstr "A capacidade do storage volume deve ser um número inteiro."
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-"URL para o storage volume deve ser http://, https://, ftp:// ou ftps://."
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr "Erro ao acessar arquivo %(url)s. Por favor, verifique isso."
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-"Não foi possÃvel clonar o volume de storage '%(name)s' no pool '%(pool)s'. "
-"Detalhes: %(err)s"
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "Interface %(name)s não existe"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Rede %(name)s já existe"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "Rede %(name)s não existe"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"A subrede %(subnet)s especificada para a rede %(network)s não é válida."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "Especifique uma interface de rede para criar a rede de bridge %(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Não foi possÃvel remover a rede ativa %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr ""
-"A interface %(iface)s especificada para a rede %(network)s já está em uso"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "Interface deve ser 'bare NIC', 'bonding' ou 'dispositivo de bridge'."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel criar a rede %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Não foi possÃvel encontrar um endereço IP livre para a rede '%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "A interface %(iface)s já existe"
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Tipos de rede suportados são isolada, NAT e bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"Subrede deve ser um texto com endereço IP e prefixo, ou máscara de rede"
-
-msgid "Network interface must be a string"
-msgstr "Interface de rede deve ser um texto"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "ID da rede VLAN deve ser um inteiro entre 1 e 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Especifique o nome e o tipo para criar uma rede"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"Não foi possÃvel desativar a rede %(name)s. Há alguma máquina virtual %(vms)"
-"s e/ou modelo associados a esta rede."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"Não foi possÃvel desativar a rede %(name)s. Há alguma máquina virtual %(vms)"
-"s e/ou modelo associados a esta rede."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"Dispositivo da bridge %(name)s não pode ser um dispositivo vinculado a uma "
-"VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "Não foi possÃvel ativar a interface %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"Não foi possÃvel ativar a interface %(iface)s. Por favor, verifique o status "
-"da conexão fÃsica."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr "Não foi possÃvel iniciar a rede %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Relatório de debug %(name)s não existe"
-
-msgid "Debug report tool not found in system"
-msgstr "Ferramenta de relatório de debug não encontrada no sistema"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-"Não foi possÃvel criar o relatório de debug %(name)s. Detalhes: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr "Não foi possÃvel encontrar nenhum relatório com o nome %(name)s"
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel gerar o relatório de debug %(name)s. Detalhes: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr "Você deve dar um nome para o arquivo do relatório de debug."
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-"Nome do relatório deve ser um texto. Somente letras, digitos, underscore "
-"('_') e hÃfem ('-') são permitidos."
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"O relatório de debug com o nome especificado \"%(name)s\" já existe. Por "
-"favor, use outro nome."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Servidor de storage %(server)s não foi usado pelo Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distribuição '%(name)s' não existe"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "Partição %(name)s não existe no host"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Não foi possÃvel desligar o host uma vez que há máquinas virtuais ligadas"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"Não foi possÃvel resetar o host uma vez que há máquinas virtuais ligadas"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "Dispositivo de nó '%(name)s' não encontrado"
-
-msgid "Conflicting flag filters specified."
-msgstr "Foram especificados filtros de flag com conflito."
-
-msgid "No packages marked for update"
-msgstr "Nenhum pacote marcado para atualização"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Pacote %(name)s não está marcado para atualização."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr "Erro ao buscar pacotes marcados para atualização. Detalhes: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "Não há gerenciador de pacotes compatÃvel para este sistema."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s inválida"
-
-msgid "Unable to choose a virtual machine name"
-msgstr "Não foi possÃvel escolher um nome para a máquina virtual"
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Tipo de storage inválido. Tipos suportados: 'cdrom', 'disco'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-"O caminho '%(value)s' não é um caminho local/remoto válido para este "
-"dispositivo"
-
-msgid "Only CDROM path can be update."
-msgstr "Apenas o caminho do CD-ROM pode ser atualizado."
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr "O disco %(dev_name)s não existe na máquina virtual %(vm_name)s"
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "Erro ao criar novo dispositivo de storage: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Erro ao atualizar dispositivo de storage: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Erro ao remover dispositivo de storage: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr "Dispositivo IDE hot plug não é suportado"
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Especifique o tipo e o caminho, ou o tipo e o pool/volume, para adicionar um "
-"novo disco da máquina virtual"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "Especifique o caminho para atualizar o disco da máquina virtual"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-"Limitação do tipo do controlador %(type)s de %(limit)s dispositivos foi "
-"alcançada"
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-"Não foi possÃvel buscar informações do caminho do disco para o pool/volume "
-"dado: %(error)s"
-
-msgid "Volume already in use by other virtual machine."
-msgstr "Volume já em uso por outra máquina virtual."
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Somente um caminho ou pool/volume pode ser especificado para adicionar um "
-"novo disco da máquina virtual."
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-"Volume escolhido com formato %(format)s não se enquadra no tipo de storage %"
-"(type)s"
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "ID do repositório YUM deve ser apenas uma palavra."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "URL do repositório deve ser uma URL http://, ftp:// ou file://."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"Configuração do repositório é um dicionário com valores especÃficos de "
-"acordo com o tipo do repositório."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "Distribuição para o repositório DEB deve ser um texto"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "Componentes para o repositório DEB deve ser um array"
-
-msgid "Components to DEB repository must be a string"
-msgstr "Componentes para o repositório DEB deve ser um texto"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Nome do repositório YUM deve ser um texto."
-
-msgid "GPG check must be a boolean value."
-msgstr "Verificação de GPG deve ser um valor booleano."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-"Chave GPG deve ser uma URL apontando para o arquivo no formato ASCII-armor."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Não foi possÃvel atualizar o repositório %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Repositório %(repo_id)s não existe."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-"Ferramenta de gerenciamento de repositório não foi reconhecida no seu "
-"sistema."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Repositório %(repo_id)s já está habilitado."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Repositório %(repo_id)s já está desabilitado."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Não foi possÃvel remover o repositório %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"Não foi possÃvel gravar o arquivo de configuração do repositório %(repo_file)"
-"s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Especificar o repositório de distribuição para poder criar o repositório DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Não foi possÃvel habilitar o repositório %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Não foi possÃvel desabilitar o repositório %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "ID do repositório YUM já existe"
-
-msgid "YUM Repository name must be a string"
-msgstr "Nome do repositório YUM deve ser um texto"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Não é possÃvel listar os repositórios. Detalhes: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-"Não foi possÃvel carregar as informações do repositório. Detalhes: '%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Não foi possÃvel adicionar o repositório. Detalhes: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Não foi possÃvel remover o repositório. Detalhes: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-"Itens de configuração '%(items)s' não são suportados pelo gerenciador de "
-"repositórios."
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-"A máquina virtual '%(vm)s' deve estar parada antes de criar um snapshot dela"
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-"Não foi possÃvel criar o snapshot '%(name)s' na máquina virtual '%(vm)s'. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr "O snapshot '%(name)s' não existe na máquina virtual '%(vm)s'."
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-"Não foi possÃvel recuperar o snapshot '%(name)s' da máquina virtual '%(vm)"
-"s'. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-"Não foi possÃvel listar os snapshots da máquina virtual '%(vm)s'. Detalhes: %"
-"(err)s"
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-"Não foi possÃvel remover o snapshot '%(name)s' da máquina virtual '%(vm)s'. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-"Não foi possÃvel recuperar o snapshot atual da máquina virtual '%(vm)s'. "
-"Detalhes: %(err)s."
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-"Não foi possÃvel reverter a máquina virtual '%(vm)s' para o snapshot '%(name)"
-"s'. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-"Não foi possÃvel criar o snapshot para a máquina virtual '%(vm)s' porque ela "
-"contém discos no formato '%(format)s'; somente 'qcow2' é suportado."
-
-msgid "The number of vCPUs is too large for this system."
-msgstr "O número de VCPUs é grande demais para esse sistema."
-
-msgid "Invalid vCPU/topology combination."
-msgstr "Combinação inválida de VCPU/topologia."
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr "Este host (ou configuração atual) não permite topologia de CPU."
-
-msgid "ERROR CODE"
-msgstr "CÃDIGO DE ERRO"
-
-msgid "REASON"
-msgstr "MOTIVO"
-
-msgid "STACK"
-msgstr "PILHA"
-
-msgid "Go to Homepage"
-msgstr "Ir para a Página Inicial"
-
-msgid "Create a New Virtual Machine"
-msgstr "Criar nova Máquina Virtual"
-
-msgid "Virtual Machine Name"
-msgstr "Nome da Máquina Virtual"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"O nome usado para identificar a máquina virtual. Se ele for omitido, a "
-"escolha será baseada no modelo selecionado."
-
-msgid "Template"
-msgstr "Modelo"
-
-msgid "Please create a template first."
-msgstr "Por favor, crie um modelo primeiro."
-
-msgid "Create a Template"
-msgstr "Criar um Modelo"
-
-msgid "Please choose a template."
-msgstr "Por favor, escolha um modelo."
-
-msgid "OS"
-msgstr "Sistema Operacional"
-
-msgid "OS Version"
-msgstr "Versão do Sistema Speracional"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Memória"
-
-msgid "Create"
-msgstr "Criar"
-
-msgid "Creating..."
-msgstr "Criando..."
-
-msgid "Cancel"
-msgstr "Cancelar"
-
-msgid "Edit Guest"
-msgstr "Editar Guest"
-
-msgid "General"
-msgstr "Geral"
-
-msgid "Storage"
-msgstr "Storage"
-
-msgid "Interface"
-msgstr "Interface"
-
-msgid "Permission"
-msgstr "Permissão"
-
-msgid "Host PCI Device"
-msgstr "Dispositivo de host PCI"
-
-msgid "Snapshot"
-msgstr "Snapshot"
-
-msgid "Name"
-msgstr "Nome"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "Memória (MB)"
-
-msgid "Icon"
-msgstr "Ãcone"
-
-msgid "Device"
-msgstr "Dispositivo"
-
-msgid "Path"
-msgstr "Caminho"
-
-msgid "Network"
-msgstr "Rede"
-
-msgid "Type"
-msgstr "Tipo"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr "Usuários e grupos de sistema disponÃveis"
-
-msgid "Selected system users and groups"
-msgstr "Usuários e grupos de sistema selecionados"
-
-msgid "User"
-msgstr "Usuário"
-
-msgid "All"
-msgstr "Todos"
-
-msgid "To Add"
-msgstr "Para adicionar"
-
-msgid "Added"
-msgstr "Adicionado"
-
-msgid "filter"
-msgstr "filtro"
-
-msgid "Product"
-msgstr "Produto"
-
-msgid "Vendor"
-msgstr "Vendor"
-
-msgid "Created"
-msgstr "Criado"
-
-msgid "Save"
-msgstr "Salvar"
-
-msgid "Replace"
-msgstr "Substituir"
-
-msgid "Detach"
-msgstr "Remover"
-
-msgid "revert"
-msgstr "Reverter"
-
-msgid "Start"
-msgstr "Iniciar"
-
-msgid "Reset"
-msgstr "Reiniciar"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "Forçar desligamento"
-
-msgid "Actions"
-msgstr "Ações"
-
-msgid "Connect"
-msgstr "Conectar"
-
-msgid "Clone"
-msgstr "Clonar"
-
-msgid "Edit"
-msgstr "Editar"
-
-msgid "Shut Down"
-msgstr "Desligar"
-
-msgid "Delete"
-msgstr "Remover"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "Disco E/S"
-
-msgid "Network I/O"
-msgstr "Rede E/S"
-
-msgid "Livetile"
-msgstr "Tela ao vivo"
-
-msgid "No guests found."
-msgstr "Nenhum guest encontrado."
-
-msgid "Add a Storage Device to VM"
-msgstr "Adicionar um dispositivo de storage à VM"
-
-msgid "Device Type"
-msgstr "Tipo do Dispositivo"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr ""
-"O tipo do dispositivo. Atualmente, \"cdrom\" e \"disco\" são suportados."
-
-msgid "Storage Pool"
-msgstr "Storage Pool"
-
-msgid "Storage pool which volume located in"
-msgstr "Storage pool no qual o volume está localizado"
-
-msgid "Storage Volume"
-msgstr "Volume de storage"
-
-msgid "Storage volume to be attached"
-msgstr "Volume de storage a ser adicionado"
-
-msgid "File Path"
-msgstr "Caminho do Arquivo"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "O caminho do arquivo ISO para o CDROM no servidor."
-
-msgid "Attach"
-msgstr "Adicionar"
-
-msgid "Shut down"
-msgstr "Desligar"
-
-msgid "Restart"
-msgstr "Reiniciar"
-
-msgid "Basic Information"
-msgstr "Informações básicas"
-
-msgid "OS Distro"
-msgstr "Distribuição"
-
-msgid "OS Code Name"
-msgstr "Nome-código do sistema operacional"
-
-msgid "Processor"
-msgstr "Processador"
-
-msgid "CPU(s)"
-msgstr "CPU(s)"
-
-msgid "System Statistics"
-msgstr "EstatÃsticas do sistema"
-
-msgid "Software Updates"
-msgstr "Atualizações de software"
-
-msgid "Update Progress"
-msgstr "Progresso da atualização"
-
-msgid "Repositories"
-msgstr "Repositórios"
-
-msgid "Debug Reports"
-msgstr "Relatórios de Debug"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"O usuário ou senha inseridos estão incorretos. Por favor, tente novamente."
-
-msgid "This field is required."
-msgstr "Esse campo é obrigatório."
-
-msgid "Log in"
-msgstr "Entrar"
-
-msgid "Logging in..."
-msgstr "Entrando..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "Guests"
-
-msgid "Templates"
-msgstr "Modelos"
-
-msgid "Failed to get application configuration"
-msgstr "Não foi possÃvel carregar as configurações da aplicação"
-
-msgid "This is not a valid Linux path"
-msgstr "Este não é um caminho válido no Linux"
-
-msgid "This is not a valid URL."
-msgstr "Essa não é uma URL válida."
-
-msgid "No such data available."
-msgstr "Não há dados disponÃveis."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"Não foi possÃvel contactar o sistema host. Verique se o sistema do host está "
-"ligado e se você possui conectividade de rede com ele. Resposta da "
-"requisição HTTP %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Confirmação de remoção"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Confirmar"
-
-msgid "Warning"
-msgstr "Aviso"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Carregando..."
-
-msgid "An error occurred while retrieving system information."
-msgstr "Ocorreu um erro ao recuperar informações do sistema."
-
-msgid "Retry"
-msgstr "Tentar novamente"
-
-msgid "Detailed message:"
-msgstr "Mensagem detalhada:"
-
-msgid "No ISO found"
-msgstr "Nenhuma ISO encontrada"
-
-msgid "This is not a valid ISO file."
-msgstr "Esse não é um arquivo ISO válido."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Isso vai levar um longo tempo. Deseja continuar?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "O modelo vai ser permanentemente removido. Deseja continuar?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"Não foi possÃvel desligar o sistema porque algumas máquinas virtuais estão "
-"ligadas!"
-
-msgid "Max:"
-msgstr "Máximo:"
-
-msgid "Utilization"
-msgstr "Utilização"
-
-msgid "Available"
-msgstr "DisponÃvel"
-
-msgid "Read Rate"
-msgstr "Taxa de leitura"
-
-msgid "Write Rate"
-msgstr "Taxa de escrita"
-
-msgid "Received"
-msgstr "Recebido"
-
-msgid "Sent"
-msgstr "Enviado"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"Desligar ou reiniciar o host causará perda de trabalho que não foi salvo. "
-"Continuar o processo de desligar/reiniciar?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Repositório será removido permanentemente e não poderá ser recuperado. "
-"Deseja continuar?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL Base"
-
-msgid "Is Mirror"
-msgstr "Ã mirror"
-
-msgid "URL Args"
-msgstr "Argumentos da URL"
-
-msgid "Enabled"
-msgstr "Ativado"
-
-msgid "GPG Check"
-msgstr "Verificação GPG"
-
-msgid "GPG Key"
-msgstr "Chave GPG"
-
-msgid "Add"
-msgstr "Adicionar"
-
-msgid "Remove"
-msgstr "Remover"
-
-msgid "Enable"
-msgstr "Ativar"
-
-msgid "Disable"
-msgstr "Desativar"
-
-msgid "Package Name"
-msgstr "Nome do pacote"
-
-msgid "Version"
-msgstr "Versão"
-
-msgid "Architecture"
-msgstr "Arquitetura"
-
-msgid "Repository"
-msgstr "Repositório"
-
-msgid "Update All"
-msgstr "Atualizar todos"
-
-msgid "Updating..."
-msgstr "Atualizando..."
-
-msgid "Failed to retrieve packages update information."
-msgstr "Não foi possÃvel recuperar as informações de atualização de pacoates."
-
-msgid "Failed to update package(s)."
-msgstr "Erro ao atualizar pacote(s)."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"Relatório de debug será permanentemente removido e não poderá ser "
-"recuperado. Deseja continuar?"
-
-msgid "Generated Time"
-msgstr "Tempo gerado"
-
-msgid "Generate"
-msgstr "Gerar"
-
-msgid "Generating..."
-msgstr "Gerando..."
-
-msgid "Rename"
-msgstr "Renomear"
-
-msgid "Download"
-msgstr "Baixar"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr ""
-"Nome do relatório deve apenas conter letras, números, underscore ('_') e/ou "
-"hÃfen ('-')."
-
-msgid "Pending..."
-msgstr "Pendente..."
-
-msgid "Report name is the same as the original one."
-msgstr "Nome do relatório é o mesmo que o original."
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"A máquina virtual vai ser removida com todos seus discos. Essa operação é "
-"irreversÃvel. Deseja continuar?"
-
-msgid "Power off Confirmation"
-msgstr "Confirmação de desligamento forçado"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-"Essa ação pode produzir resultados não desejáveis, como por exemplo cache de "
-"disco não-atualizado no guest. Deseja continuar?"
-
-msgid "Reset Confirmation"
-msgstr "Confirmação de reinicialização"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-"Existe um risco de perda de dados causado pela reinicialização sem o "
-"desligamento do sistema operacional do guest. Deseja continuar?"
-
-msgid "Shut Down Confirmation"
-msgstr "Confirmação de desligamento"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-"O sistema operacional do guest pode ignorar essa requisição. Deseja "
-"continuar?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr "Confirmação de Remoção da Máquina Virtual"
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-"Essa máquina virtual não é persistente. O desligamento irá removê-la. Deseja "
-"continuar?"
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-"Quando o guest de destino tiver volumes SCSI ou iSCSI, eles serão clonados "
-"no storage pool padrão. O mesmo vai acontecer quando o pool de destino não "
-"tiver espaço suficiente para clonar os volumes. Você deseja continuar?"
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Esse CDROM será desconectado permanentemente e você pode reconectá-lo. "
-"Deseja continuar a remoção? "
-
-msgid "Attaching..."
-msgstr "Adicionando..."
-
-msgid "Replacing..."
-msgstr "Substituindo..."
-
-msgid "Successfully attached!"
-msgstr "Adicionado com sucesso!"
-
-msgid "Successfully replaced!"
-msgstr "SubstituÃdo com sucesso!"
-
-msgid "Successfully detached!"
-msgstr "Removido com sucesso!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-"Esse disco será desconectado permanentemente e você pode reconectá-lo. "
-"Deseja continuar a remoção? "
-
-msgid "interface:"
-msgstr "interface:"
-
-msgid "address:"
-msgstr "endereço:"
-
-msgid "link_type:"
-msgstr "tipo do link:"
-
-msgid "block:"
-msgstr "bloco:"
-
-msgid "drive_type:"
-msgstr "tipo do drive:"
-
-msgid "model:"
-msgstr "modelo:"
-
-msgid "Affected devices:"
-msgstr "Dispositivos afetados:"
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "ID da VLAN deve ser um número entre 1 e 4094."
-
-msgid "unavailable"
-msgstr "indisponÃvel"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"Esta ação irá interromper a conectividade da rede para qualquer máquina "
-"virtual que depende dessa rede."
-
-msgid "Create a network"
-msgstr "Criar uma rede"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Essa rede não é persistente. Ao invés de parar, essa ação irá removê-la "
-"permantemente. Deseja continuar?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "O storage pool vai ser permanentemente removido. Deseja continuar?"
-
-msgid "This storage pool is empty."
-msgstr "Esse storage pool está vazio."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Isso formatará seu disco e você perderá toda informação, você tem certeza "
-"que quer continuar?"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI Fibre Channel"
-
-msgid "No SCSI adapters found."
-msgstr "Nenhum adaptador SCSI encontrado."
-
-msgid "Loading iSCSI targets..."
-msgstr "Carregando iSCSI targets..."
-
-msgid "No iSCSI found. Please input one."
-msgstr "Nenhum iSCSI encontrado. Por favor, forneça um."
-
-msgid "Failed to load iSCSI targets."
-msgstr "Erro ao carregar iSCSI targets."
-
-msgid "The storage pool name can not be blank."
-msgstr "O nome do storage pool não pode ser vazio."
-
-msgid "The storage pool path can not be blank."
-msgstr "O caminho do storage pool não pode ser vazio."
-
-msgid "NFS server mount path can not be blank."
-msgstr "Caminho de montagem do servidor de NFS não pode ser vazio."
-
-msgid "Invalid NFS mount path."
-msgstr "Caminho de montagem do NFS inválido."
-
-msgid "No logical device selected."
-msgstr "Nenhum dispositivo lógico selecionado."
-
-msgid "The iSCSI target can not be blank."
-msgstr "O alvo iSCSI não pode ser vazio."
-
-msgid "Server name can not be blank."
-msgstr "Nome do servidor não pode ser vazio."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr "Este não é um nome ou IP de servidor válido. Por favor, modifique-o."
-
-msgid "Looking for available partitions ..."
-msgstr "Procurando por partições disponÃveis ..."
-
-msgid "No available partitions found."
-msgstr "Nenhuma partição disponÃvel encontrada."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"O storage pool não é persistente. Ao invés de desativar, essa ação vai "
-"removê-lo permanentemente. Deseja continuar?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "Não foi possÃvel recuperar as informações das partições."
-
-msgid "In progress..."
-msgstr "Em progresso..."
-
-msgid "Failed!"
-msgstr "Falhou!"
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-"Caminho do CDROM precisa ser um caminho local válido e não pode ser vazio."
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Pool ou volume do disco não pode ser vazio."
-
-#, fuzzy
-msgid "Filter"
-msgstr "filtro"
-
-msgid "Network Name"
-msgstr "Nome da rede"
-
-msgid "State"
-msgstr "Estado"
-
-msgid "Network Type"
-msgstr "Tipo da rede"
-
-msgid "Address Space"
-msgstr "Espaço de endereço"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "O nome não deve conter '/' and '\"'."
-
-msgid "Isolated: no external network connection"
-msgstr "Isolada: nenhuma conexão externa"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: somente conexão de rede fÃsica de saÃda"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Bridged: Máquinas virtuais estão conectadas diretamente com a rede fÃsica"
-
-msgid "(No interfaces found)"
-msgstr "(Nenhuma interface encontrada)"
-
-msgid "Destination"
-msgstr "Destino"
-
-msgid "Enable VLAN"
-msgstr "Habilitar VLAN"
-
-msgid "VLAN ID"
-msgstr "ID da VLAN"
-
-msgid "Stop"
-msgstr "Parar"
-
-msgid "Generate a New Debug Report"
-msgstr "Gerar um novo Relatório de Debug"
-
-msgid "Report Name"
-msgstr "Nome do Relatório"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"O nome usado para identificar o relatório. Se omitido, um nome será "
-"escolhido baseado no horário atual. O nome pode conter: letras, números, "
-"underscore ('_') e hÃfen ('-')."
-
-msgid "Rename a Debug Report"
-msgstr "Renomear um Relatório de Debug"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"O nome usado para identificar o relatório. O nome pode conter: letras, "
-"dÃgitos e hÃfen (\"-\")."
-
-msgid "Submit"
-msgstr "Enviar"
-
-msgid "Add a Repository"
-msgstr "Adicionar um Repositório"
-
-msgid "Identifier"
-msgstr "Identificador"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Uma única palavra, identificador único para o repositório."
-
-msgid "Textual name for the repository."
-msgstr "Nome textual para o repositório."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Campo Obrigatório"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL para o repositório. Protocolos suportados são http, ftp e file."
-
-msgid "Repository is a mirror"
-msgstr "Repositório é um mirror"
-
-msgid "Distribution"
-msgstr "Distribuição"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribuição para o repositório DEB."
-
-msgid "Components"
-msgstr "Componentes"
-
-msgid "List of components in DEB repository."
-msgstr "Lista de componentes para o repositório DEB."
-
-msgid "Edit Repository"
-msgstr "Editar Repositório"
-
-msgid "Mirror List URL"
-msgstr "URL para a lista de mirror"
-
-msgid "Yes"
-msgstr "Sim"
-
-msgid "No"
-msgstr "Não"
-
-msgid "Capacity"
-msgstr "Capacidade"
-
-msgid "Allocated"
-msgstr "Alocado"
-
-msgid "Location"
-msgstr "Localização"
-
-msgid "Device path"
-msgstr "Caminho do dispositivo"
-
-msgid "active"
-msgstr "ativo"
-
-msgid "inactive"
-msgstr "inativo"
-
-msgid "Deactivate"
-msgstr "Desativar"
-
-msgid "Activate"
-msgstr "Ativar"
-
-msgid "Add Volume"
-msgstr "Adicionar volume"
-
-msgid "Extend"
-msgstr "Aumentar"
-
-msgid "Undefine"
-msgstr "Indefinir"
-
-msgid "Format"
-msgstr "Formato"
-
-msgid "Allocation"
-msgstr "Alocação"
-
-msgid "Define a New Storage Pool"
-msgstr "Definir novo Storage Pool"
-
-msgid "Storage Pool Name"
-msgstr "Nome do Storage Pool"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "O nome usado para identificar o storage pool e não deve ser vazio."
-
-msgid "Storage Pool Type"
-msgstr "Tipo do Storage Pool"
-
-msgid "Storage Path"
-msgstr "Caminho do storage"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"O caminho do Storage Pool. Cada Storage Pool deve ter um caminho único."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"O Kimchi vai tentar criar o diretório se ainda não existir no seu sistema."
-
-msgid "NFS Server IP"
-msgstr "IP do servidor NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP ou hostname do servidor NFS. Pode ser inserido ou escolhido do histórico."
-
-msgid "NFS Path"
-msgstr "Caminho do NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "O caminho exportado do servidor NFS."
-
-msgid "iSCSI Server"
-msgstr "Servidor iSCSI"
-
-msgid "Server"
-msgstr "Servidor"
-
-msgid "Port"
-msgstr "Porta"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP ou hostname do servidor iSCSI. Não deve ser vazio."
-
-msgid "Target"
-msgstr "Alvo"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "O alvo iSCSI no servidor iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "Adicionar as credenciais do iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Credenciais do iSCSI"
-
-msgid "User Name"
-msgstr "Usuário"
-
-msgid "Password"
-msgstr "Senha"
-
-msgid "SCSI Adapter"
-msgstr "Adaptador SCSI"
-
-msgid "Please, wait..."
-msgstr "Por favor, aguarde..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr "Adicionar um volume ao Storage Pool"
-
-msgid "Fetch from remote URL"
-msgstr "Fazer download de uma URL remota"
-
-msgid "Enter the remote URL here."
-msgstr "Digite a URL remota aqui."
-
-msgid "Upload a file"
-msgstr "Fazer upload de um arquivo"
-
-msgid "Choose the file you want to upload."
-msgstr "Escolha o arquivo que você quer fazer upload."
-
-msgid "Add Template"
-msgstr "Adicionar Modelo"
-
-msgid "Where is the source media for this template? "
-msgstr "Onde está a mÃdia de origem desse modelo? "
-
-msgid "Local ISO Image"
-msgstr "Imagem ISO Local"
-
-msgid "Local Image File"
-msgstr "Arquivo de Imagem Local"
-
-msgid "Remote ISO Image"
-msgstr "Imagem ISO Remota"
-
-msgid "Search ISOs"
-msgstr "Procurar ISOs"
-
-msgid "The following ISOs are available:"
-msgstr "As seguintes ISOs estão disponÃveis:"
-
-msgid "OS: "
-msgstr "Sistema Operacional: "
-
-msgid "Version: "
-msgstr "Versão: "
-
-msgid "Size: "
-msgstr "Tamanho: "
-
-msgid "Search more ISOs"
-msgstr "Procurar por mais ISOs"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Criar Modelos a partir das ISOs selecionadas"
-
-msgid "I want to use a specific ISO file"
-msgstr "Eu quero usar um arquivo ISO especÃfico"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Carregando ISOs remotas ..."
-
-msgid "Arch: "
-msgstr "Arquitetura: "
-
-msgid "I want to use a custom URL"
-msgstr "Eu quero usar uma URL personalizada"
-
-msgid "Edit Template"
-msgstr "Editar Modelo"
-
-msgid "CDROM"
-msgstr "CD-ROM"
-
-msgid "Image File"
-msgstr "Arquivo de imagem"
-
-msgid "Graphics"
-msgstr "Gráficos"
-
-msgid "Disk(GB)"
-msgstr "Disco (GB)"
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "Quantidade de CPUs"
-
-msgid "Manually set CPU topology"
-msgstr "Configurar manualmente a topologia de CPU"
-
-msgid "Cores"
-msgstr "Cores"
-
-msgid "Threads"
-msgstr "Threads"
-
-msgid "No templates found."
-msgstr "Nenhum modelo encontrado."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "Método de remoção não é permitido em %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s não implementa método de atualização"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Método de criação não é permitido em %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "Não é possÃvel realizar a leitura da requisição do JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Essa API suporta apenas JSON"
-
-#~ msgid "Parameters does not match requirement in schema: %(err)s"
-#~ msgstr "Parâmetros não correspondem à especificação do esquema: %(err)s"
-
-#~ msgid "You don't have permission to perform this operation."
-#~ msgstr "Você não tem permissão para executar esta operação."
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Datastore não está inicializado no objeto modelo."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "Não foi possÃvel iniciar a tarefa devido a um erro: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr ""
-#~ "Autenticação falhou para o usuário '%(username)s'. [Código de erro: %"
-#~ "(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Você não está autorizado para acessar o Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Especifique %(item)s para autenticar no Kimchi"
-
-#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
-#~ msgstr "Configurações LDAP inválidas: %(item)s : %(value)s"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "Não foi possÃvel encontrar %(item)s no datastore"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr ""
-#~ "Fim do limite de tempo ao rodar comando '%(cmd)s' após %(seconds)s "
-#~ "segundos"
-
-#~ msgid "Invalid data value '%(value)s'"
-#~ msgstr "Valor inválido '%(value)s'"
-
-#~ msgid "Invalid data unit '%(unit)s'"
-#~ msgstr "Unidade inválida '%(unit)s'"
-
-#~ msgid "Peers"
-#~ msgstr "Peers"
-
-#~ msgid "Searching"
-#~ msgstr "Procurando"
-
-#~ msgid "No peers found."
-#~ msgstr "Nenhum peer encontrado."
-
-#~ msgid "Help"
-#~ msgstr "Ajuda"
-
-#~ msgid "About"
-#~ msgstr "Sobre"
-
-#~ msgid "Log out"
-#~ msgstr "Sair"
-
-#~ msgid "Version:"
-#~ msgstr "Versão:"
-
-#~ msgid "Session timeout, please re-login."
-#~ msgstr ""
-#~ "Fim do limite do tempo da sessão, por favor se autentique novamente."
diff --git a/plugins/kimchi/po/ru_RU.po b/plugins/kimchi/po/ru_RU.po
deleted file mode 100644
index a5dec2e..0000000
--- a/plugins/kimchi/po/ru_RU.po
+++ /dev/null
@@ -1,2198 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2014-08-28 17:32+0000\n"
-"Last-Translator: Aline Manera <aline.manera at gmail.com>\n"
-"Language-Team: Russian (http://www.transifex.com/projects/p/kimchi/language/"
-"ru/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ru_RU\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "ÐÑибка полÑÑÐµÐ½Ð¸Ñ Ð±Ð»Ð¾ÑнÑÑ
ÑÑÑÑойÑÑв. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "ÐÑибка полÑÑÐµÐ½Ð¸Ñ Ð¸Ð½ÑоÑмаÑии о блоÑнÑÑ
ÑÑÑÑойÑÑваÑ
Ð´Ð»Ñ %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Ðе найден Ñайл ваÑианÑа ÐС: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"ÐÑибка анализа Ñайла ваÑианÑа ÐС %(filename)s. УбедиÑеÑÑ, ÑÑо ÑÑо Ñайл JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð²Ð¾Ð¹Ñи в Ñелевой %(portal)s Ñ
оÑÑа iSCSI. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Ðе ÑдалоÑÑ Ð²Ð¾Ð¹Ñи в Ñелевой %(target)s Ñ
оÑÑа iSCSI %(host)s"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "Файл ISO %(filename)s не загÑÑзоÑнÑй"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"Файл ISO %(filename)s не ÑодеÑÐ¶Ð¸Ñ Ð¿ÑавилÑнÑÑ Ð·Ð°Ð³ÑÑзоÑнÑÑ Ð·Ð°Ð¿Ð¸ÑÑ El Torito"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "ÐедопÑÑÑÐ¸Ð¼Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð¿ÑовеÑки El Torito в обÑазе ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ÐедопÑÑÑимÑй индикаÑÐ¾Ñ Ð·Ð°Ð³ÑÑзки El Torito в обÑазе ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "ÐеожиданнÑй Ñип Ñома Ð´Ð»Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ Ñома в обÑазе ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "ÐевеÑнÑй ÑоÑÐ¼Ð°Ñ Ð´ÐµÑкÑипÑоÑа Ñома в обÑазе ISO %(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"У гипеÑвизоÑа Ð½ÐµÑ Ð¿Ñав доÑÑÑпа Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑого обÑаза ISO %(filename)"
-"s. ÐеÑемеÑÑиÑе его в каÑалог /var/lib/libvirt, добавÑÑе ÑазÑеÑение на поиÑк "
-"в ÑпиÑки конÑÑÐ¾Ð»Ñ Ð´Ð¾ÑÑÑпа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ %(user)s, еÑли ÑÑо возможно, "
-"добавÑÑе %(user)s в гÑÑÐ¿Ð¿Ñ Ð¿ÑÑи к обÑÐ°Ð·Ñ ISO или (не ÑекомендÑеÑÑÑ) "
-"вÑполниÑе ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ 'chmod -R o+x 'path_to_iso'. СведениÑ: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "ÐиÑÑÑалÑÐ½Ð°Ñ Ð¼Ð°Ñина %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "ÐиÑÑÑалÑÐ½Ð°Ñ Ð¼Ð°Ñина %(name)s не ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ñнимок ÑкÑана Ð´Ð»Ñ Ð¾ÑÑановленной виÑÑÑалÑной маÑÐ¸Ð½Ñ %"
-"(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "УдаленнÑй обÑаз ISO не поддеÑживаеÑÑÑ ÑÑим ÑеÑвеÑом."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"ÐдÑÐµÑ Ð¿Ñиема запÑоÑов Ð´Ð»Ñ Ð³ÑаÑиÑеÑкой подÑиÑÑÐµÐ¼Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ IPv4 или IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "УкажиÑе Ñаблон Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿ÑÑÑиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð¾ÑÑановиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð¿ÐµÑеименоваÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "ÐÐ¼Ñ ÑеÑи должно бÑÑÑ ÑÑÑокой"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "ÐÐ¼Ñ ÑеÑи должно бÑÑÑ ÑÑÑокой"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "ÐолÑзоваÑÐµÐ»Ñ %(users)s не ÑÑÑеÑÑвÑеÑ."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "ÐолÑзоваÑÐµÐ»Ñ %(groups)s не ÑÑÑеÑÑвÑеÑ."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð¾ÑÑановиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿ÑÑÑиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "ÐнÑеÑÑÐµÐ¹Ñ %(iface)s не ÑÑÑеÑÑвÑÐµÑ Ð² виÑÑÑалÑной маÑине %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"СеÑÑ %(network)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ Ð²Ð¸ÑÑÑалÑной маÑÐ¸Ð½Ñ %(name)s, не ÑÑÑеÑÑвÑеÑ"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "ÐоддеÑживаеÑÑÑ ÑолÑко один Ñип инÑеÑÑейÑов виÑÑÑалÑной маÑÐ¸Ð½Ñ - ÑеÑÑ"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "ÐÐ¼Ñ ÑеÑи Ð´Ð»Ñ Ð¸Ð½ÑеÑÑейÑа виÑÑÑалÑной маÑÐ¸Ð½Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ бÑÑÑ ÑÑÑокой"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Указана недопÑÑÑÐ¸Ð¼Ð°Ñ ÐºÐ°ÑÑа модели ÑеÑи Ð´Ð»Ñ Ð¸Ð½ÑеÑÑейÑа виÑÑÑалÑной маÑинÑ"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "УкажиÑе Ñип и ÑеÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ инÑеÑÑейÑа виÑÑÑалÑной маÑинÑ"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Шаблон %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr "СеÑÑ %(network)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ Ñаблона %(template)s, не ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr "ÐÑл памÑÑи %(pool)s, ÑказаннÑй Ð´Ð»Ñ Ñаблона %(template)s, не ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr "ÐÑл памÑÑи %(pool)s, ÑказаннÑй Ð´Ð»Ñ Ñаблона %(template)s, не акÑивен"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Указан недопÑÑÑимÑй паÑамеÑÑ %(param)s Ð´Ð»Ñ CDROM."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "СеÑÑ %(network)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ Ñаблона %(template)s, не акÑивна"
-
-msgid "Template name must be a string"
-msgstr "ÐÐ¼Ñ Ñаблона должно бÑÑÑ ÑÑÑокой"
-
-msgid "Template icon must be a path to the image"
-msgstr "ÐнаÑок Ñаблона должен бÑÑÑ Ð¿ÑÑем к обÑазÑ"
-
-msgid "Template distribution must be a string"
-msgstr "ÐаÑÐ¸Ð°Ð½Ñ Ñаблона должен бÑÑÑ ÑÑÑокой"
-
-msgid "Template distribution version must be a string"
-msgstr "ÐеÑÑÐ¸Ñ Ð²Ð°ÑианÑа Ñаблона должна бÑÑÑ ÑÑÑокой"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "ЧиÑло пÑоÑеÑÑоÑов должно бÑÑÑ ÑелÑм ÑиÑлом"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "ÐбÑем памÑÑи (ÐÐ) должен бÑÑÑ ÑелÑм ÑиÑлом болÑÑе 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "CDROM Ñаблона должен бÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑм или ÑдаленнÑм Ñайлом ISO"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "ÐÐ»Ñ Ñаблона Ñказан недопÑÑÑимÑй URI пÑла памÑÑи %(value)s"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "УкажиÑе обÑаз ISO в каÑеÑÑве CDROM Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñаблона"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "ÐÑе ÑеÑи Ð´Ð»Ñ Ñаблона Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÐºÐ°Ð·Ð°Ð½Ñ Ð² ÑпиÑке."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ñаблон из-за оÑибки %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñаблон из-за оÑибки %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "CDROM Ñаблона должен бÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑм или ÑдаленнÑм Ñайлом ISO"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "ÐÑл памÑÑи %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "ÐÑл памÑÑи %(name)s не ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "УкажиÑе %(item)s Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñла памÑÑи %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð°ÐºÑивнÑй пÑл памÑÑи %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок пÑлов памÑÑи. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÑиÑло Ñомов в пÑле памÑÑи %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð´ÐµÐ°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¿Ñл NFS: ÑкÑпоÑÑиÑованнÑй пÑÑÑ %(path)s мог бÑÑÑ "
-"заблокиÑован во вÑÐµÐ¼Ñ Ð¼Ð¾Ð½ÑиÑованиÑ"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¿Ñл NFS: не ÑдалоÑÑ ÑмонÑиÑоваÑÑ ÑкÑпоÑÑиÑованнÑй пÑÑÑ %"
-"(path)s"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "ÐеподдеÑживаемÑй Ñип пÑла памÑÑи: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи должен бÑÑÑ ÑÑÑокой"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "ХоÑÑ Ð¿Ñла памÑÑи должен бÑÑÑ IP-адÑеÑом или именем Ñ
оÑÑа"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "ÐаÑамеÑÑ ÑÑÑÑойÑÑв пÑла памÑÑи должен бÑÑÑ ÑпиÑком"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "Целевой IQN пÑла iSCSI должен бÑÑÑ ÑÑÑокой"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "ÐоÑÑ Ñдаленного ÑеÑвеÑа памÑÑи должен бÑÑÑ ÑелÑм ÑиÑлом Ð¾Ñ 1 до 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "УкажиÑе Ð¸Ð¼Ñ Ð¸ Ñип Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñла памÑÑи"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s не ÑвлÑеÑÑÑ Ð´Ð¾Ð¿ÑÑÑимÑм диÑком/Ñазделом. Ðе ÑдалоÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ ÐµÐ³Ð¾ в "
-"пÑл %(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "ÐиÑки паÑамеÑÑов можно обновлÑÑÑ ÑолÑко Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸ÑеÑкого пÑла памÑÑи."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "ÐÐ¼Ñ Ð°Ð´Ð°Ð¿ÑеÑа Ñ
оÑÑа SCSI должно бÑÑÑ ÑÑÑокой."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "kimchi_isos пÑла памÑÑи заÑезеÑвиÑован Ð´Ð»Ñ Ð²Ð½ÑÑÑеннего иÑполÑзованиÑ"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Ðе ÑдалоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи NFS %(name)s. СеÑÐ²ÐµÑ NFS %(server)s "
-"недоÑÑÑпен."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Ðе ÑдалоÑÑ Ð´ÐµÐ°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи NFS %(name)s. СеÑÐ²ÐµÑ NFS %(server)s "
-"недоÑÑÑпен."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð´ÐµÐ°ÐºÑивиÑоваÑÑ Ð¿Ñл %(name)s: пÑл ÑвÑзан Ñ Ð½ÐµÐºÐ¾ÑоÑÑми Ñаблонами"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð¿Ñл %(name)s: пÑл ÑвÑзан Ñ Ð½ÐµÐºÐ¾ÑоÑÑми Ñаблонами"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr ""
-"ÐÑÑппа Ñомов Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ %(name)s Ñже ÑÑÑеÑÑвÑеÑ. ÐÑбеÑиÑе дÑÑгое Ð¸Ð¼Ñ Ð´Ð»Ñ "
-"ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð»Ð¾Ð³Ð¸ÑеÑкого пÑла."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
Ñ Ð¸Ð½ÑоÑмаÑией глÑбокого ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·-за "
-"оÑибки %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Том %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "Том %(name)s не ÑÑÑеÑÑвÑÐµÑ Ð² пÑле памÑÑи %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "УкажиÑе %(item)s Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñома %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr "Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок Ñомов: пÑл памÑÑи %(pool)s не акÑивен"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr ""
-"Ðе ÑдалоÑÑ ÑоздаÑÑ Ñом %(name)s в пÑле памÑÑи %(pool)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок Ñомов в пÑле памÑÑи %(pool)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑÑеÑеÑÑ Ñома %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñом %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ñома %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "Тип памÑÑи %(type)s не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ñоздание и Ñдаление Ñомов"
-
-msgid "Storage volume name must be a string"
-msgstr "ÐÐ¼Ñ Ñома должно бÑÑÑ ÑÑÑокой"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "ÐÑделение Ñома должно бÑÑÑ ÑелÑм ÑиÑлом"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "Ð¢Ð¾Ð¼Ñ ÑÑебÑеÑÑÑ Ð¸Ð¼Ñ"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
Ñ Ð¸Ð½ÑоÑмаÑией о ÑомаÑ
из-за оÑибки %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "ÐнÑеÑÑÐµÐ¹Ñ %(name)s не ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "СеÑÑ %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "СеÑÑ %(name)s не ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr "ÐодÑеÑÑ %(subnet)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ ÑеÑи %(network)s, недопÑÑÑима."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"УкажиÑе ÑеÑевой инÑеÑÑÐµÐ¹Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑеÑи %(name)s Ñ Ð´Ð¾ÑÑÑпом ÑеÑез моÑÑ"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð°ÐºÑивнÑÑ ÑеÑÑ %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr "ÐнÑеÑÑÐµÐ¹Ñ %(iface)s, ÑказаннÑй Ð´Ð»Ñ ÑеÑи %(network)s, Ñже иÑполÑзÑеÑÑÑ"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-"ÐнÑеÑÑÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ ÑеÑевой каÑÑой, ÑÑÑÑойÑÑвом моÑÑа или ÑвÑзÑÑÑим "
-"ÑÑÑÑойÑÑвом."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ ÑеÑÑ %(name)s. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Ðе найден ÑвободнÑй IP-адÑÐµÑ Ð´Ð»Ñ ÑеÑи %(name)s"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "ÐоддеÑживаемÑе ÑÐ¸Ð¿Ñ ÑеÑей: isolated, NAT и bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"ÐодÑеÑÑ ÑеÑи должна бÑÑÑ ÑÑÑокой, ÑодеÑжаÑей IP-адÑеÑ, пÑеÑÐ¸ÐºÑ Ð¸Ð»Ð¸ маÑÐºÑ ÑеÑи"
-
-msgid "Network interface must be a string"
-msgstr "СеÑевой инÑеÑÑÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ ÑÑÑокой"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "СеÑевой ÐÐ VLAN должен бÑÑÑ ÑелÑм ÑиÑлом Ð¾Ñ 1 до 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "УкажиÑе Ð¸Ð¼Ñ Ð¸ Ñип Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑеÑи"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"УÑÑÑойÑÑво моÑÑа %(name)s не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¼Ð°Ð³Ð¸ÑÑÑалÑнÑм ÑÑÑÑойÑÑвом VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "Ðе ÑдалоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"Ðе далоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ %(iface)s. ÐÑовеÑÑÑе ÑоÑÑоÑние ÑизиÑеÑкой "
-"линии ÑвÑзи. "
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "ÐÑладоÑнÑй оÑÑÐµÑ %(name)s не ÑÑÑеÑÑвÑеÑ"
-
-msgid "Debug report tool not found in system"
-msgstr "ÐнÑÑÑÑÐ¼ÐµÐ½Ñ Ð¾ÑладоÑного оÑÑеÑа не найден в ÑиÑÑеме"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¾ÑладоÑнÑй оÑÑÐµÑ %(name)s. СведениÑ: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¾ÑладоÑнÑй оÑÑÐµÑ %(name)s. СведениÑ: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr ""
-"ÐÑÑппа Ñомов Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ %(name)s Ñже ÑÑÑеÑÑвÑеÑ. ÐÑбеÑиÑе дÑÑгое Ð¸Ð¼Ñ Ð´Ð»Ñ "
-"ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð»Ð¾Ð³Ð¸ÑеÑкого пÑла."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "СеÑÐ²ÐµÑ Ð¿Ð°Ð¼ÑÑи %(server)s не иÑполÑзовалÑÑ Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "ÐаÑÐ¸Ð°Ð½Ñ ÐС %(name)s не ÑÑÑеÑÑвÑеÑ"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "Раздел %(name)s не ÑÑÑеÑÑвÑÐµÑ Ð½Ð° Ñ
оÑÑе"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Ðе ÑдалоÑÑ Ð·Ð°Ð²ÐµÑÑиÑÑ ÑабоÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа: вÑполнÑÑÑÑÑ Ð²Ð¸ÑÑÑалÑнÑе маÑинÑ"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "Ðе ÑдалоÑÑ Ð¿ÐµÑезагÑÑзиÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа: вÑполнÑÑÑÑÑ Ð²Ð¸ÑÑÑалÑнÑе маÑинÑ"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "УÑÑÑойÑÑво %(name)s Ñзла не найдено"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "ÐÐµÑ Ð¿Ð°ÐºÐµÑов, помеÑеннÑÑ
Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "ÐÐ°ÐºÐµÑ %(name)s не помеÑен Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr "ÐÑибка полÑÑÐµÐ½Ð¸Ñ Ð¿Ð°ÐºÐµÑов, помеÑеннÑÑ
Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ. СведениÑ: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "ÐÐµÑ ÑовмеÑÑимого админиÑÑÑаÑоÑа пакеÑов Ð´Ð»Ñ ÑÑой ÑиÑÑемÑ."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "ÐедопÑÑÑимÑй URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "ÐедопÑÑÑимÑй Ñип памÑÑи. ÐоддеÑживаемÑе ÑипÑ: cdrom"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "ÐÑибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑанениÑ: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "ÐÑибка Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑанениÑ: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "ÐÑибка ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑанениÑ: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "УкажиÑе Ñип и пÑÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ диÑка виÑÑÑалÑной маÑинÑ"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "УкажиÑе пÑÑÑ Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¸Ñка виÑÑÑалÑной маÑинÑ"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "УкажиÑе Ñип и пÑÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ диÑка виÑÑÑалÑной маÑинÑ"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-"ÐÐ Ñ
ÑанилиÑа YUM должен бÑÑÑ ÑÑÑокой, ÑоÑÑоÑÑей ÑолÑко из одного Ñлова."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "URL Ñ
ÑанилиÑа должен бÑÑÑ http://, ftp:// или file:// ."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"ÐонÑигÑÑаÑÐ¸Ñ Ñ
ÑанилиÑа пÑедÑÑавлÑÐµÑ Ñобой ÑловаÑÑ Ð·Ð½Ð°Ñений, опÑеделÑемÑÑ
"
-"Ñипом Ñ
ÑанилиÑа."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "ÐаÑÐ¸Ð°Ð½Ñ Ð´Ð»Ñ Ñ
ÑанилиÑа DEB должен бÑÑÑ ÑÑÑокой"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "ÐомпоненÑÑ Ð´Ð»Ñ Ñ
ÑанилиÑа DEB Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÐµÑеÑиÑÐ»ÐµÐ½Ñ Ð² маÑÑиве"
-
-msgid "Components to DEB repository must be a string"
-msgstr "ÐомпоненÑÑ Ð´Ð»Ñ Ñ
ÑанилиÑа DEB Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÑÑокой"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "ÐÐ¼Ñ Ñ
ÑанилиÑа YUM должно бÑÑÑ ÑÑÑокой."
-
-msgid "GPG check must be a boolean value."
-msgstr "ÐÑовеÑка GPG должна бÑÑÑ Ð±ÑлевÑким знаÑением."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-"ÐлÑÑ GPG должен бÑÑÑ URL, ÑказÑваÑÑим на заÑиÑеннÑй Ñайл Ñ ÐºÐ¾Ð´Ð¸Ñованием "
-"ASCII."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ñ
ÑанилиÑе %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Ð¥ÑанилиÑе %(repo_id)s не ÑÑÑеÑÑвÑеÑ."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "Ðе ÑаÑпознан инÑÑÑÑÐ¼ÐµÐ½Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ
ÑанилиÑем Ð´Ð»Ñ ÑиÑÑемÑ."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Ð¥ÑанилиÑе %(repo_id)s Ñже вклÑÑено."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Ð¥ÑанилиÑе %(repo_id)s Ñже вÑклÑÑено."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñ
ÑанилиÑе %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿Ð¸ÑаÑÑ Ð² Ñайл конÑигÑÑаÑии Ñ
ÑанилиÑа %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "УкажиÑе ваÑÐ¸Ð°Ð½Ñ Ñ
ÑанилиÑа Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ
ÑанилиÑа DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Ðе ÑдалоÑÑ Ð²ÐºÐ»ÑÑиÑÑ Ñ
ÑанилиÑе %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Ðе ÑдалоÑÑ Ð²ÑклÑÑиÑÑ Ñ
ÑанилиÑе %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "ÐÐ Ñ
ÑанилиÑа YUM Ñже ÑÑÑеÑÑвÑеÑ"
-
-msgid "YUM Repository name must be a string"
-msgstr "ÐÐ¼Ñ Ñ
ÑанилиÑа YUM должно бÑÑÑ ÑÑÑокой"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок Ñ
ÑанилиÑ. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Ðе ÑдалоÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "Ðод оÑибки"
-
-msgid "REASON"
-msgstr "ÐÐ ÐЧÐÐÐ"
-
-msgid "STACK"
-msgstr "СÑек"
-
-msgid "Go to Homepage"
-msgstr "ÐеÑейÑи на главнÑÑ ÑÑÑаниÑÑ"
-
-msgid "Create a New Virtual Machine"
-msgstr "СоздаÑÑ Ð½Ð¾Ð²ÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑинÑ"
-
-msgid "Virtual Machine Name"
-msgstr "ÐÐ¼Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии виÑÑÑалÑной маÑинÑ. ÐÑли не Ñказано, Ð¸Ð¼Ñ Ð±ÑÐ´ÐµÑ Ð²ÑбÑано "
-"в завиÑимоÑÑи Ð¾Ñ Ð¸ÑполÑзÑемого Ñаблона."
-
-msgid "Template"
-msgstr "Шаблон"
-
-msgid "Please create a template first."
-msgstr "ÐожалÑйÑÑа, ÑоздайÑе Ñаблон в пеÑвÑÑ Ð¾ÑеÑедÑ."
-
-msgid "Create a Template"
-msgstr "СоздаÑÑ Ñаблон"
-
-msgid "Please choose a template."
-msgstr "ÐожалÑйÑÑа, вÑбеÑиÑе Ñаблон."
-
-msgid "OS"
-msgstr "ÐС"
-
-msgid "OS Version"
-msgstr "ÐеÑÑÐ¸Ñ ÐС"
-
-msgid "CPUS"
-msgstr "ÐÑоÑеÑÑоÑÑ"
-
-msgid "Memory"
-msgstr "ÐамÑÑÑ"
-
-msgid "Create"
-msgstr "СоздаÑÑ"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "ÐÑмена"
-
-msgid "Edit Guest"
-msgstr "ÐзмениÑÑ Ð³Ð¾ÑÑевÑÑ ÑиÑÑемÑ"
-
-msgid "General"
-msgstr "ÐбÑее"
-
-msgid "Storage"
-msgstr "Ð¥ÑанилиÑе"
-
-msgid "Interface"
-msgstr "ÐнÑеÑÑейÑ"
-
-msgid "Permission"
-msgstr "ÐеÑÑиÑ"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "ÐмÑ"
-
-msgid "CPUs"
-msgstr "ÐÑоÑеÑÑоÑÑ"
-
-msgid "Memory (MB)"
-msgstr "ÐамÑÑÑ (Ðб)"
-
-msgid "Icon"
-msgstr "ÐнаÑок"
-
-msgid "Device"
-msgstr "ÐÐ¼Ñ ÑÑÑÑойÑÑва"
-
-msgid "Path"
-msgstr "ÐÑÑÑ NFS"
-
-msgid "Network"
-msgstr "СеÑÑ"
-
-msgid "Type"
-msgstr "Тип"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "ÐÑе"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "ÐендоÑ"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "СоÑ
ÑаниÑÑ"
-
-msgid "Replace"
-msgstr "ÐамениÑÑ"
-
-msgid "Detach"
-msgstr "ÐÑклÑÑиÑÑ"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "ÐапÑÑÑиÑÑ"
-
-msgid "Reset"
-msgstr "СбÑоÑиÑÑ"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "ÐÑклÑÑиÑÑ"
-
-msgid "Actions"
-msgstr "ÐейÑÑвиÑ"
-
-msgid "Connect"
-msgstr "ÐодклÑÑиÑÑ"
-
-msgid "Clone"
-msgstr "ÐлониÑоваÑÑ"
-
-msgid "Edit"
-msgstr "РедакÑиÑоваÑÑ"
-
-msgid "Shut Down"
-msgstr "ÐавеÑÑиÑÑ ÑабоÑÑ"
-
-msgid "Delete"
-msgstr "УдалиÑÑ"
-
-msgid "CPU"
-msgstr "ÐÑоÑеÑÑоÑ"
-
-msgid "Disk I/O"
-msgstr "ÐиÑковÑй ввод-вÑвод"
-
-msgid "Network I/O"
-msgstr "СеÑевой ввод-вÑвод"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð³Ð¾ÑÑевÑе ÑиÑÑемÑ."
-
-msgid "Add a Storage Device to VM"
-msgstr "ÐобавиÑÑ ÑÑÑÑойÑÑво Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð² VM"
-
-msgid "Device Type"
-msgstr "Тип ÑÑÑÑойÑÑва"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "Тип ÑÑÑÑойÑÑва. РданнÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¿Ð¾Ð´Ð´ÐµÑживаеÑÑÑ ÑолÑко \"cdrom\"."
-
-msgid "Storage Pool"
-msgstr "ÐÑл памÑÑи"
-
-msgid "Storage pool which volume located in"
-msgstr "ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи должен бÑÑÑ ÑÑÑокой"
-
-msgid "Storage Volume"
-msgstr "ÐÐ¼Ñ Ð¿Ñла памÑÑи"
-
-msgid "Storage volume to be attached"
-msgstr "ÐÐ¼Ñ Ñома должно бÑÑÑ ÑÑÑокой"
-
-msgid "File Path"
-msgstr "ÐÑÑÑ Ðº ÑайлÑ"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "ÐÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO Ð´Ð»Ñ CDROM на ÑеÑвеÑе."
-
-msgid "Attach"
-msgstr "ÐодклÑÑиÑÑ"
-
-msgid "Shut down"
-msgstr "ÐÑклÑÑен"
-
-msgid "Restart"
-msgstr "ÐеÑезапÑÑк"
-
-msgid "Basic Information"
-msgstr "ÐÐ°Ð·Ð¾Ð²Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ"
-
-msgid "OS Distro"
-msgstr "ÐаÑÐ¸Ð°Ð½Ñ ÐС"
-
-msgid "OS Code Name"
-msgstr "Ðодовое Ð¸Ð¼Ñ ÐС"
-
-msgid "Processor"
-msgstr "ÐÑоÑеÑÑоÑ"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "СиÑÑÐµÐ¼Ð½Ð°Ñ ÑÑаÑиÑÑика"
-
-msgid "Software Updates"
-msgstr "ÐÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑогÑаммного обеÑпеÑениÑ"
-
-msgid "Update Progress"
-msgstr "Ход обновлениÑ"
-
-msgid "Repositories"
-msgstr "Ð¥ÑанилиÑа"
-
-msgid "Debug Reports"
-msgstr "ÐÑладоÑнÑе оÑÑеÑÑ"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr "Указано невеÑное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¸Ð»Ð¸ паÑолÑ. ÐведиÑе еÑе Ñаз."
-
-msgid "This field is required."
-msgstr "ÐÑо обÑзаÑелÑное поле."
-
-msgid "Log in"
-msgstr "ÐойÑи"
-
-msgid "Logging in..."
-msgstr "ÐÑ
од..."
-
-msgid "Host"
-msgstr "ХоÑÑ"
-
-msgid "Guests"
-msgstr "ÐоÑÑевÑе ÑиÑÑемÑ"
-
-msgid "Templates"
-msgstr "ШаблонÑ"
-
-msgid "Failed to get application configuration"
-msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÐºÐ¾Ð½ÑигÑÑаÑÐ¸Ñ Ð¿ÑиложениÑ"
-
-msgid "This is not a valid Linux path"
-msgstr "ÐÑÐ¾Ñ Ð½ÐµÐ´Ð¾Ð¿ÑÑÑимÑй пÑÑÑ Ð² Linux"
-
-msgid "This is not a valid URL."
-msgstr "ÐÑо недопÑÑÑимÑй URL."
-
-msgid "No such data available."
-msgstr "ÐÐµÑ ÑакиÑ
даннÑÑ
."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"ÐÐµÑ ÑвÑзи Ñ ÑиÑÑемой Ñ
оÑÑа. УбедиÑеÑÑ, ÑÑо ÑиÑÑема Ñ
оÑÑа ÑабоÑÐ°ÐµÑ Ð¸ доÑÑÑпна "
-"Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑениÑ. ÐÑÐ²ÐµÑ Ð½Ð° запÑÐ¾Ñ HTTP: %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "ÐодÑвеÑждение ÑдалениÑ"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "ÐодÑвеÑдиÑÑ"
-
-msgid "Warning"
-msgstr "ÐÑедÑпÑеждение"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "ÐагÑÑжаеÑÑÑ..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "ÐовÑоÑиÑÑ"
-
-msgid "Detailed message:"
-msgstr "ÐодÑобное ÑообÑение:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "ÐÑÐ¾Ñ Ñайл не ÑвлÑеÑÑÑ Ð´Ð¾Ð¿ÑÑÑимÑм обÑазом ISO."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "ÐÑо Ð·Ð°Ð¹Ð¼ÐµÑ Ð¼Ð½Ð¾Ð³Ð¾ вÑемени. ÐÑодолжиÑÑ?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "Шаблон бÑÐ´ÐµÑ Ð±ÐµÐ·Ð²Ð¾Ð·Ð²ÑаÑно Ñдален. ÐÑодолжиÑÑ?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"Ðевозможно завеÑÑиÑÑ ÑабоÑÑ ÑиÑÑемÑ, поÑколÑÐºÑ Ð² ней ÑабоÑаÑÑ Ð²Ð¸ÑÑÑалÑнÑе "
-"маÑинÑ!"
-
-msgid "Max:"
-msgstr "ÐакÑ.:"
-
-msgid "Utilization"
-msgstr "ÐÑполÑзование"
-
-msgid "Available"
-msgstr "ÐоÑÑÑпно"
-
-msgid "Read Rate"
-msgstr "СкоÑоÑÑÑ ÑÑениÑ"
-
-msgid "Write Rate"
-msgstr "СкоÑоÑÑÑ Ð·Ð°Ð¿Ð¸Ñи"
-
-msgid "Received"
-msgstr "ÐолÑÑено"
-
-msgid "Sent"
-msgstr "ÐÑпÑавлено"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"ÐавеÑÑение ÑабоÑÑ Ð¸ пеÑезапÑÑк Ñ
оÑÑа пÑиведÑÑ Ðº поÑеÑе неÑоÑ
Ñаненной ÑабоÑÑ. "
-"ÐÑодолжиÑÑ Ð·Ð°Ð²ÐµÑÑение ÑабоÑÑ/пеÑезапÑÑк?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr "Ð¥ÑанилиÑе бÑÐ´ÐµÑ Ñдалено без возможноÑÑи воÑÑÑановлениÑ. ÐÑодолжиÑÑ?"
-
-msgid "ID"
-msgstr "ÐÐ"
-
-msgid "Base URL"
-msgstr "ÐазовÑй URL"
-
-msgid "Is Mirror"
-msgstr "ÐеÑкалÑÐ½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ"
-
-msgid "URL Args"
-msgstr "ÐÑгÑменÑÑ URL"
-
-msgid "Enabled"
-msgstr "ÐклÑÑено"
-
-msgid "GPG Check"
-msgstr "ÐÑовеÑка GPG"
-
-msgid "GPG Key"
-msgstr "ÐлÑÑ GPG"
-
-msgid "Add"
-msgstr "ÐобавиÑÑ"
-
-msgid "Remove"
-msgstr "УдалиÑÑ"
-
-msgid "Enable"
-msgstr "ÐклÑÑиÑÑ"
-
-msgid "Disable"
-msgstr "ÐÑклÑÑиÑÑ"
-
-msgid "Package Name"
-msgstr "ÐÐ¼Ñ Ð¿Ð°ÐºÐµÑа"
-
-msgid "Version"
-msgstr "ÐеÑÑиÑ"
-
-msgid "Architecture"
-msgstr "ÐÑÑ
иÑекÑÑÑа"
-
-msgid "Repository"
-msgstr "Ð¥ÑанилиÑе"
-
-msgid "Update All"
-msgstr "ÐбновиÑÑ Ð²ÑÑ"
-
-msgid "Updating..."
-msgstr "Ðбновление..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð¿Ð°ÐºÐµÑÑ."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr ""
-"ÐÑладоÑнÑй оÑÑÐµÑ Ð±ÑÐ´ÐµÑ Ñдален без возможноÑÑи воÑÑÑановлениÑ. ÐÑодолжиÑÑ?"
-
-msgid "Generated Time"
-msgstr "ÐÑÐµÐ¼Ñ ÑозданиÑ"
-
-msgid "Generate"
-msgstr "СоздаÑÑ"
-
-msgid "Generating..."
-msgstr "Создание..."
-
-msgid "Rename"
-msgstr "ÐеÑеименоваÑÑ"
-
-msgid "Download"
-msgstr "ÐагÑÑзиÑÑ"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr "ÐÐ¼Ñ Ð¾ÑÑеÑа должно ÑодеÑжаÑÑ ÑолÑко бÑквÑ, ÑиÑÑÑ Ð¸ деÑиÑÑ ('-')."
-
-msgid "Pending..."
-msgstr "ÐагÑÑжаеÑÑÑ..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"ÐÑÐ´ÐµÑ Ñдалена виÑÑÑалÑÐ½Ð°Ñ Ð¼Ð°Ñина вмеÑÑе Ñо Ñвоими виÑÑÑалÑнÑми диÑками. ÐÑо "
-"необÑаÑÐ¸Ð¼Ð°Ñ Ð¾Ð¿ÐµÑаÑиÑ. ÐÑодолжиÑÑ?"
-
-msgid "Power off Confirmation"
-msgstr "ÐодÑвеÑждение ÑдалениÑ"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "ÐодÑвеÑждение ÑдалениÑ"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "ÐодÑвеÑждение ÑдалениÑ"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "Шаблон бÑÐ´ÐµÑ Ð±ÐµÐ·Ð²Ð¾Ð·Ð²ÑаÑно Ñдален. ÐÑодолжиÑÑ?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"ÐÑÐ¾Ñ CDROM бÑÐ´ÐµÑ Ð¾ÑклÑÑен. Ðго можно бÑÐ´ÐµÑ Ñнова подклÑÑиÑÑ. ÐÑклÑÑиÑÑ?"
-
-msgid "Attaching..."
-msgstr "ÐодклÑÑение..."
-
-msgid "Replacing..."
-msgstr "Ðамена..."
-
-msgid "Successfully attached!"
-msgstr "УÑпеÑно подклÑÑен!"
-
-msgid "Successfully replaced!"
-msgstr "УÑпеÑно заменен!"
-
-msgid "Successfully detached!"
-msgstr "УÑпеÑно оÑклÑÑен!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "ÐÐ VLAN должен бÑÑÑ Ð¾Ñ 1 до 4094."
-
-msgid "unavailable"
-msgstr "недоÑÑÑпно"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr ""
-"ÐÑо дейÑÑвие наÑÑÑÐ¸Ñ ÑеÑевÑе ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð²ÑеÑ
виÑÑÑалÑнÑÑ
маÑин, коÑоÑÑе "
-"завиÑÑÑ Ð¾Ñ ÑÑой ÑеÑи."
-
-msgid "Create a network"
-msgstr "СоздаÑÑ ÑеÑÑ"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"ÐÑÐ¾Ñ Ð¿Ñл памÑÑи не поÑÑоÑннÑй. ÐмеÑÑо деакÑиваÑии, ÑÑо дейÑÑвие безвозвÑаÑно "
-"его ÑдалиÑ. ÐÑодолжиÑÑ?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "ÐÑл памÑÑи бÑÐ´ÐµÑ Ð±ÐµÐ·Ð²Ð¾Ð·Ð²ÑаÑно Ñдален. ÐÑодолжиÑÑ?"
-
-msgid "This storage pool is empty."
-msgstr "ÐÑÐ¾Ñ Ð¿Ñл памÑÑи пÑÑÑой."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"ÐиÑк бÑÐ´ÐµÑ Ð¾ÑÑоÑмаÑиÑован, и вÑе даннÑе на нем бÑдÑÑ Ð¿Ð¾ÑеÑÑнÑ. ÐÑ "
-"дейÑÑвиÑелÑно Ñ
оÑиÑе пÑодолжиÑÑ? "
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI Fibre Channel"
-
-msgid "No SCSI adapters found."
-msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð°Ð´Ð°Ð¿ÑеÑÑ SCSI."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "Ðе Ñказано Ð¸Ð¼Ñ Ð¿Ñла памÑÑи."
-
-msgid "The storage pool path can not be blank."
-msgstr "Ðе Ñказан пÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи."
-
-msgid "NFS server mount path can not be blank."
-msgstr "Ðе Ñказан пÑÑÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑеÑвеÑа NFS."
-
-msgid "Invalid NFS mount path."
-msgstr "ÐедопÑÑÑимÑй пÑÑÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ NFS."
-
-msgid "No logical device selected."
-msgstr "Ðе вÑбÑано логиÑеÑкое ÑÑÑÑойÑÑво."
-
-msgid "The iSCSI target can not be blank."
-msgstr "Ðе Ñказан Ñелевой обÑÐµÐºÑ iSCSI."
-
-msgid "Server name can not be blank."
-msgstr "Ðе Ñказано Ð¸Ð¼Ñ ÑеÑвеÑа."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "ÐоиÑк доÑÑÑпнÑÑ
Ñазделов..."
-
-msgid "No available partitions found."
-msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð´Ð¾ÑÑÑпнÑе ÑазделÑ."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"ÐÑÐ¾Ñ Ð¿Ñл памÑÑи не поÑÑоÑннÑй. ÐмеÑÑо деакÑиваÑии, ÑÑо дейÑÑвие безвозвÑаÑно "
-"его ÑдалиÑ. ÐÑодолжиÑÑ?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Ðе Ñказано Ð¸Ð¼Ñ Ð¿Ñла памÑÑи."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "ÐÐ¼Ñ ÑеÑи"
-
-msgid "State"
-msgstr "СоÑÑоÑние"
-
-msgid "Network Type"
-msgstr "Тип ÑеÑи"
-
-msgid "Address Space"
-msgstr "ÐдÑеÑное пÑоÑÑÑанÑÑво"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "ÐедопÑÑÑимое Ð¸Ð¼Ñ Ð¿Ñла памÑÑи. Римени не должно бÑÑÑ Ñимволов '/'."
-
-msgid "Isolated: no external network connection"
-msgstr "ÐзолиÑованнÑй (без ÑизиÑеÑкиÑ
ÑеÑевÑÑ
Ñоединений)"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT (ÑолÑко иÑÑ
одÑÑее ÑизиÑеÑкое ÑеÑевое Ñоединение)"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "ЧеÑез моÑÑ (пÑÑмое подклÑÑение виÑÑÑалÑнÑÑ
маÑин к ÑизиÑеÑкой ÑеÑи)"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "Целевое ÑаÑположение:"
-
-msgid "Enable VLAN"
-msgstr "ÐклÑÑиÑÑ VLAN:"
-
-msgid "VLAN ID"
-msgstr ""
-
-msgid "Stop"
-msgstr "ÐавеÑÑиÑÑ"
-
-msgid "Generate a New Debug Report"
-msgstr "СоздаÑÑ Ð½Ð¾Ð²Ñй оÑладоÑнÑй оÑÑеÑ"
-
-msgid "Report Name"
-msgstr "ÐÐ¼Ñ Ð¾ÑÑеÑа"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии оÑÑеÑа. ÐÑли не Ñказано, Ð¸Ð¼Ñ Ð±ÑÐ´ÐµÑ ÑÑоÑмиÑовано на "
-"оÑнове ÑекÑÑего вÑемени. ÐÐ¼Ñ Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ: бÑквÑ, ÑиÑÑÑ Ð¸ деÑиÑÑ (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "СоздаÑÑ Ð½Ð¾Ð²Ñй оÑладоÑнÑй оÑÑеÑ"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии оÑÑеÑа. ÐÑли не Ñказано, Ð¸Ð¼Ñ Ð±ÑÐ´ÐµÑ ÑÑоÑмиÑовано на "
-"оÑнове ÑекÑÑего вÑемени. ÐÐ¼Ñ Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ: бÑквÑ, ÑиÑÑÑ Ð¸ деÑиÑÑ (\"-\")."
-
-msgid "Submit"
-msgstr "ÐодÑвеÑдиÑÑ"
-
-msgid "Add a Repository"
-msgstr "ÐобавиÑÑ Ñ
ÑанилиÑе"
-
-msgid "Identifier"
-msgstr "ÐденÑиÑикаÑоÑ"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "ÐдиноÑное Ñлово - ÑникалÑнÑй иденÑиÑикаÑÐ¾Ñ Ñ
ÑанилиÑа."
-
-msgid "Textual name for the repository."
-msgstr "ТекÑÑовое Ð¸Ð¼Ñ Ñ
ÑанилиÑа."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "ÐбÑзаÑелÑное поле"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL Ñ
ÑанилиÑа. ÐоддеÑживаемÑе пÑоÑоколÑ: http, ftp, file."
-
-msgid "Repository is a mirror"
-msgstr "Ð¥ÑанилиÑе ÑвлÑеÑÑÑ Ð·ÐµÑкалÑной копией."
-
-msgid "Distribution"
-msgstr "ÐаÑианÑ"
-
-msgid "Distribution of the DEB repository."
-msgstr "ÐаÑÐ¸Ð°Ð½Ñ Ñ
ÑанилиÑа DEB."
-
-msgid "Components"
-msgstr "ÐомпоненÑÑ"
-
-msgid "List of components in DEB repository."
-msgstr "СпиÑок компоненÑов в Ñ
ÑанилиÑе DEB."
-
-msgid "Edit Repository"
-msgstr "ÐзмениÑÑ Ñ
ÑанилиÑе"
-
-msgid "Mirror List URL"
-msgstr "URL ÑпиÑка зеÑкалÑнÑÑ
копий"
-
-msgid "Yes"
-msgstr "Ðа"
-
-msgid "No"
-msgstr "ÐеÑ"
-
-msgid "Capacity"
-msgstr "ÐмкоÑÑÑ"
-
-msgid "Allocated"
-msgstr "ÐÑделено"
-
-msgid "Location"
-msgstr "РаÑположение"
-
-msgid "Device path"
-msgstr "ÐÑÑÑ Ðº ÑÑÑÑойÑÑвÑ"
-
-msgid "active"
-msgstr "акÑивен"
-
-msgid "inactive"
-msgstr "неакÑивен"
-
-msgid "Deactivate"
-msgstr "ÐÑклÑÑиÑÑ"
-
-msgid "Activate"
-msgstr "ÐкÑивиÑоваÑÑ"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "УдалиÑÑ"
-
-msgid "Format"
-msgstr "ФоÑмаÑ:"
-
-msgid "Allocation"
-msgstr "ÐÑделение ÑеÑÑÑÑов:"
-
-msgid "Define a New Storage Pool"
-msgstr "СоздаÑÑ Ð¿Ñл памÑÑи"
-
-msgid "Storage Pool Name"
-msgstr "ÐÐ¼Ñ Ð¿Ñла памÑÑи"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии пÑлов памÑÑи. Ðе Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑÑм."
-
-msgid "Storage Pool Type"
-msgstr "Тип пÑла памÑÑи"
-
-msgid "Storage Path"
-msgstr "ÐÑÑÑ Ðº диÑкÑ"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr "ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи. ÐаждÑй пÑл памÑÑи должен имеÑÑ ÑникалÑнÑй пÑÑÑ."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr "Kimchi попÑÑаеÑÑÑ ÑоздаÑÑ ÐºÐ°Ñалог, еÑли он не ÑÑÑеÑÑвÑÐµÑ Ð² ÑиÑÑеме."
-
-msgid "NFS Server IP"
-msgstr "IP-адÑÐµÑ ÑеÑвеÑа NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP-адÑÐµÑ Ð¸Ð»Ð¸ Ð¸Ð¼Ñ Ñ
оÑÑа ÑеÑвеÑа NFS. Ðго можно ввеÑÑи или вÑбÑаÑÑ Ð² "
-"Ñ
Ñонологии."
-
-msgid "NFS Path"
-msgstr "ÐÑÑÑ NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "ÐкÑпоÑÑиÑованнÑй пÑÑÑ NFS на ÑеÑвеÑе NFS."
-
-msgid "iSCSI Server"
-msgstr "СеÑÐ²ÐµÑ iSCSI"
-
-msgid "Server"
-msgstr "СеÑвеÑ"
-
-msgid "Port"
-msgstr "ÐоÑÑ"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP-адÑÐµÑ Ð¸Ð»Ð¸ Ð¸Ð¼Ñ Ñ
оÑÑа ÑеÑвеÑа iSCSI. Ðе Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑÑм."
-
-msgid "Target"
-msgstr "Целевой обÑекÑ"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "Целевой обÑÐµÐºÑ iSCSI на ÑеÑвеÑе iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "ÐобавиÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¸Ñ iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "ÐденÑиÑикаÑÐ¸Ñ iSCSI"
-
-msgid "User Name"
-msgstr "ÐÐ¼Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ"
-
-msgid "Password"
-msgstr "ÐаÑолÑ"
-
-msgid "SCSI Adapter"
-msgstr "ÐдапÑÐµÑ SCSI"
-
-msgid "Please, wait..."
-msgstr "ÐодождиÑе..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "ÐобавиÑÑ Ñаблон"
-
-msgid "Where is the source media for this template? "
-msgstr "Ðде наÑ
одиÑÑÑ Ð¸ÑÑ
однÑй ноÑиÑÐµÐ»Ñ Ð´Ð»Ñ ÑÑого Ñаблона?"
-
-msgid "Local ISO Image"
-msgstr "ÐокалÑнÑй обÑаз ISO"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "УдаленнÑй обÑаз ISO"
-
-msgid "Search ISOs"
-msgstr "ÐоиÑк обÑазов ISO"
-
-msgid "The following ISOs are available:"
-msgstr "ÐоÑÑÑпнÑе обÑÐ°Ð·Ñ ISO:"
-
-msgid "OS: "
-msgstr "ÐС: "
-
-msgid "Version: "
-msgstr "ÐеÑÑиÑ: "
-
-msgid "Size: "
-msgstr "РазмеÑ: "
-
-msgid "Search more ISOs"
-msgstr "ÐоиÑк дополниÑелÑнÑÑ
обÑазов ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "СоздаÑÑ ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð¸Ð· вÑбÑаннÑÑ
обÑазов ISO"
-
-msgid "I want to use a specific ISO file"
-msgstr "ÐÑполÑзоваÑÑ ÐºÐ¾Ð½ÐºÑеÑнÑй Ñайл ISO"
-
-msgid "Loading default remote ISOs ..."
-msgstr "ÐагÑÑзка ÑдаленнÑÑ
ISO по ÑмолÑаниÑ..."
-
-msgid "Arch: "
-msgstr "ÐÑÑ
иÑекÑÑÑа: "
-
-msgid "I want to use a custom URL"
-msgstr "ÐÑполÑзоваÑÑ Ð´ÑÑгой URL"
-
-msgid "Edit Template"
-msgstr "ÐзмениÑÑ Ñаблон"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "ÐÑаÑика"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "ÐолиÑеÑÑво пÑоÑеÑÑоÑов"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ ÑаблонÑ."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "Удаление запÑеÑено Ð´Ð»Ñ %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s не ÑеализÑÑÑ Ð¼ÐµÑод обновлениÑ"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Создание запÑеÑено Ð´Ð»Ñ %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "ÐÑибка анализа запÑоÑа JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "ÐÑа ÑÑнкÑÐ¸Ñ API поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑолÑко JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Ð¥ÑанилиÑе даннÑÑ
в обÑекÑе модели не иниÑиализиÑовано."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿ÑÑÑиÑÑ Ð·Ð°Ð´Ð°ÑÑ Ð¸Ð·-за оÑибки %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr ""
-#~ "Сбой иденÑиÑикаÑии полÑзоваÑÐµÐ»Ñ %(username)s. [Ðод оÑибки: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "ÐÐµÑ Ð¿Ñав доÑÑÑпа к Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "УкажиÑе %(item)s Ð´Ð»Ñ Ð²Ñ
ода в Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "Ðе найден %(item)s в Ñ
ÑанилиÑе даннÑÑ
"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr "ÐÑÑек Ñайм-аÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ %(cmd)s (%(seconds)s Ñ)"
-
-#~ msgid "Help"
-#~ msgstr "ÐомоÑÑ"
-
-#~ msgid "About"
-#~ msgstr "РпÑогÑамме"
-
-#~ msgid "Log out"
-#~ msgstr "ÐÑйÑи"
-
-#~ msgid "Version:"
-#~ msgstr "ÐеÑÑиÑ:"
diff --git a/plugins/kimchi/po/zh_CN.po b/plugins/kimchi/po/zh_CN.po
deleted file mode 100644
index fc6dd84..0000000
--- a/plugins/kimchi/po/zh_CN.po
+++ /dev/null
@@ -1,2186 +0,0 @@
-# i18n portable object for kimchi.
-# Copyright (C) IBM, Corp. 2013-2014
-# ShaoHe Feng <shaohef at linux.vnet.ibm.com>, 2013-04-18.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-06-27 10:48+0000\n"
-"Last-Translator: ShaoHe Feng <shaohef at linux.vnet.ibm.com>\n"
-"Language-Team: ShaoHe Feng <shaohef at linux.vnet.ibm.com>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_CN\n"
-"Generated-By: pygettext.py 1.5\n"
-"X-Poedit-Country: CHINA\n"
-"X-Poedit-Language: Chinese\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr "æªç¥åé %(value)s"
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr "ä»»å¡'%(task)sè¶
æ¶%(seconds)sç§ã"
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr "ä½¿ç¨æå®çLDAPé
ç½®æªæ¾å°%(user_id)sç¨æ·"
-
-msgid "Unknown \"_cap\" specified"
-msgstr "æªè¯å«ç\"_cap\""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr "\"_passthrough\"å¼åºä¸º\"true\"æè
\"false\""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr "\"_passthrough_affected_by\"åºä¸ºä¸ä¸ªå符串å设å¤å"
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "è·ååè®¾å¤æ¶åºéã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "è·ååè®¾å¤ %(device)s ä¿¡æ¯æ¶åºéã"
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "æ¾ä¸å°åè¡çæä»¶ï¼%(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr "ä¸è½è§£æåè¡çæä»¶ï¼%(filename)sã请确ä¿å®æ¯ä¸ä¸ªJSONæ ¼å¼çæä»¶ã"
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "æ æ³éè¿ %(portal)s ç»å½iSCSI主æºåç®æ ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "æ æ³ç»å½iSCSI主æº%(host)sä¸çç®æ %(target)sã"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr "æªè½æ¾å°ISOæä»¶ %(filename)s"
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISOæä»¶%(filename)sä¸å¯å¼å¯¼ã"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "ISOæä»¶%(filename)sæ²¡æææçEl Toritoå¼å¯¼è®°å½ã"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "å¨ISOæä»¶%(filename)sä¸åç°æ æçEl Toritoæ ¡éªæ¡ç®ãã"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ISOæä»¶%(filename)sçEl Toritoå¼å¯¼æ å¿æ¯æ æç"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "æªè½è¯å«ISOæä»¶%(filename)sç主å·ç±»å"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "ISOæä»¶%(filename)sçå·æè¿°ç¬¦æ ¼å¼é误"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"hypervisor没æè®¿é®ISOæä»¶%(filename)sçæéãå¯ä»¥å°ISOç§»å°/var/lib/libvirtç®"
-"å½ä¸ï¼æä¸º'%(user)s'ç¨æ·è®¾ç½®è®¿é®æéï¼æå°'%(user)s'ç¨æ·å¢å å°ISOè·¯å¾çå±ç»ï¼"
-"æè
为ææçç¨æ·å¢å è®¿é®æé 'chmod -R o+x 'ï¼ä¸æ¨èï¼ã详æ
ï¼%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr "æç´¢éåæä½ç³»ç»ä¿¡æ¯æ¶åçé误ã"
-
-msgid "No OS information found in given image."
-msgstr "卿å®çéåæä»¶ä¸æªåç°æä½ç³»ç»ä¿¡æ¯ã"
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr "æªè½è¯»åéåæä»¶ %(filename)s"
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr "ç£çæä»¶å¿
须已åå¨ç³»ç»ä¸ï¼%(filename)s䏿¯åæ³æä»¶å"
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "èææº%(name)så·²ç»åå¨"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "èææº%(name)sä¸åå¨"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-"æªè½å®ç°èææº %(name)s éå½åï¼åç§° %(new_name)s å·²è¢«ä½¿ç¨æè
è¯¥èææºæªå
³"
-"æºã"
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "ä¸è½è·ååæ¢ç¶æçèææº%(name)sçæªå±"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "该æå¡å¨ä¸æ¯æè¿ç¨ISOéåã"
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr "èææº %(name)s 䏿¯æå¿«ç
§"
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "ä¸è½åå»ºèææº%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "ä¸è½æ´æ°èææº%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "ä¸è½è·åèææº%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr "èææº%(name)så·²å
³æºï¼è¿æ¥å¤±è´¥ã"
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr "æ æçèææºæ¨¡æ¿URI %(value)s"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr "æ æçèææºå卿± URI %(value)s"
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr "èææºå¾å½¢çé¢ä»
æ¯æSpice以åVNC"
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "è¿ç¨å¾å½¢è®¿é®ççå¬å°åå¿
é¡»æ¯IPv4æIPv6å°åã"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "æå®ç¨äºåå»ºèææºç模æ¿"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "ä¸è½å¯å¨èææº %(name)s. 详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "ä¸è½å
³éèææº%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "ä¸è½å é¤èææº %(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "æªè½éç½®èææº%(name)sã详æ
ï¼%(err)s"
-
-msgid "User name list must be an array"
-msgstr "ç¨æ·åå表å¿
须为ä¸ä¸ªæ°ç»"
-
-msgid "User name must be a string"
-msgstr "ç¨æ·åå¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "Group name list must be an array"
-msgstr "ç»åç§°å表å¿
须为ä¸ä¸ªæ°ç»"
-
-msgid "Group name must be a string"
-msgstr "ç¨æ·ç»åç§°å¿
é¡»æ¯ä¸ä¸ªå符串"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "ç¨æ·'%(users)s'ä¸åå¨"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "ç¨æ·ç»'%(groups)s'ä¸åå¨"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "æªè½å
³éèææº%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "æ æ³è·å¾èææº %(name)sçå
æ°æ®ï¼è¯¦æ
ï¼%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr "å®¢æ·æºæ§å¶å°å¯ç å¿
须为ä¸ä¸ªå符串ã"
-
-msgid "The life time for the guest console password must be a number."
-msgstr "å®¢æ·æºå½ä»¤è¡å¯ç æææ¶é´å¿
é¡»æ¯ä¸ä¸ªæ°åã"
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr "èææº'%(name)s'å¨å¶ä½å¯æ¬åå¿
é¡»å
³æºã"
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr "å¶ä½èææº'%(name)s'坿¬æéçç£ç空é´ä¸è¶³"
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr "æªè½æåå¶ä½èææº'%(name)s'坿¬ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr "èææº%(vmid)sæªææè¢«åé
ç主æºè®¾å¤%(dev_name)sã"
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr "主æºè®¾å¤%(dev_name)sä¸å
è®¸ç´æ¥åé
ç»èææºã"
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-"æªæ¾å°IOMMU groupsã主æºPCI pass throughéè¦IOMMU groupæå¯ä»¥æ£ç¡®å·¥ä½ã请å¨"
-"BIOS设置éå°Intel VT-d æè
AMD IOMMU 设为使è½ï¼èå确认å
æ ¸æ¯æIOMMUã对äº"
-"Intel CPUï¼å¨è·¯å¾/boot/grub2/grub.conf䏿·»å å
æ ¸åéintel_iommu=onã对äºAMD "
-"CPUï¼åæ·»å iommu=pt iommu=1ã"
-
-msgid "\"name\" should be a device name string"
-msgstr "\"name\"åºè¯¥ä¸ºä¸ä¸ªå符串åç设å¤å"
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "èææº %(name)s 䏿²¡ææ¥å£ %(iface)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr "ä¸ºèææº%(name)sæå®çç½ç»%(network)sä¸åå¨"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "åªæ¯æç½ç»ç±»åçèææºæ¥å£"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "èææºæ¥å£çç½ç»ååå¿
é¡»æ¯å符串"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr "èææºæ¥å£æå®çç½ç»æ¨¡å塿 æ"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "为æ°çèææºæ¥å£æå®ç±»ååç½ç»"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "æ¨¡æ¿ %(name)s å·²ç»åå¨"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çç½ç» '%(network)s' ä¸åå¨"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çå卿± '%(pool)s' ä¸åå¨"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çå卿± '%(pool)s' æ²¡ææ¿æ´»"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "为CDROMæå®çåæ° '%(param)s' æ æ"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çç½ç» '%(network)s' æ²¡ææ¿æ´»"
-
-msgid "Template name must be a string"
-msgstr "模æ¿çååå¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "Template icon must be a path to the image"
-msgstr "模æ¿ç徿 å¿
é¡»æ¯ä¸ä¸ªæåéåçè·¯å¾"
-
-msgid "Template distribution must be a string"
-msgstr "模æ¿çåè¡çå¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "Template distribution version must be a string"
-msgstr "模æ¿çåè¡ççæ¬å·å¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPUæ°éå¿
须为ä¸ä¸ªå¤§äº0çæ´æ°"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "æ»å
åæ°ï¼MB为åä½ï¼å¿
é¡»æ¯ä¸ä¸ªå¤§äº512çæ´æ°"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "模æ¿çCDROMå¿
é¡»æ¯ä¸ä¸ªæ¬å°æè
è¿ç¨çISOæä»¶"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "ç»æ¨¡æ¿æå®äºæ æçå卿± URI %(value)s"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "æå®ä¸ä¸ªISOéåä½ä¸ºå建模æ¿çCDROMæè
åºç¡éå"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "ä¸ºæ¨¡æ¿æå®çç½ç»å¿
é¡»å¨ä¸ä¸ªå表ä¸"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr "å½å卿± ç±»å为iSCSIæè
SCSIçæ¶åé¡»ä¸ºæ¨¡æ¿æå®ä¸ä¸ªå·"
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr "å·%(volume)sä¸å¨å卿± %(pool)sä¸"
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "å建模æ¿å¤±è´¥ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "ç±äºé误ï¼%(err)sï¼æªè½å 餿¨¡æ¿"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr "ç£ç大å°å¿
须大äº1GBã"
-
-msgid "Template base image must be a valid local image file"
-msgstr "模æ¿åºç¡éåå¿
须为ä¸ä¸ªææçæ¬å°éåæä»¶"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr "æªè½è¯å«åºç¡éå%(path)sæ ¼å¼"
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr "CPUææä¸ï¼VCPUså¿
é¡»å
æ¬sockets, cores 以åthreadsã"
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr "CPUææä¸ï¼æ¯ä¸ä¸ªåæ°å¿
须为大äºé¶çæ´æ°ã"
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"æ æçç£çéåæ ¼å¼ãææçæ ¼å¼ä¸ºï¼bochs, cloop, cow, dmg, qcow, qcow2, qed, "
-"raw, vmdk, vpcã"
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "å卿± %(name)så·²ç»åå¨"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "å卿± %(name)sä¸åå¨"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "为æ°å卿± %(name)sæå®%(item)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "ä¸è½å 餿¿æ´»çå卿± %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "ä¸è½å举å卿± ã 详æ
ï¼ %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "ä¸è½å建å卿± %(name)sã详æ
ï¼ %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr "ä¸è½è·åå¨åæ± %(name)sä¸å·çæ°ç®ã详æ
ï¼ %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "ä¸è½æ¿æ´»å¨åæ± %(name)sã详æ
ï¼ %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "ä¸è½åç¨å¨åæ± %(name)sã详æ
ï¼ %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "ä¸è½å é¤å¨åæ± %(name)sã详æ
ï¼ %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr "ä¸è½å建NFSå卿± ï¼å¯è½å¯¼åºè·¯å¾%(path)så¨æè½½æ¶è¢«é»å¡äº"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr "ä¸è½å建NFSå卿± ï¼æè½½å¯¼åºè·¯å¾%(path)s失败"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "䏿¯æçå卿± ç±»åï¼%(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr "æ¥è¯¢å卿± XMLå°%(pool)sæ¶åºç°é误"
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr "å卿± ç±»åä»
æ¯ædirï¼netfsï¼logicalï¼iscsiï¼isci以åkimchi-iso"
-
-msgid "Storage pool path must be a string"
-msgstr "å卿± è·¯å¾å¿
é¡»æ¯å符串"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "å卿± 主æºå¿
é¡»æ¯ä¸ä¸ªIPåè
主æºå"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr "å卿± 设å¤å¿
须为å设å¤çä¸ä¸ªç»å¯¹è·¯å¾"
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "å卿± 设å¤åæ°å¿
é¡»æ¯ä¸ä¸ªå表"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSIå卿± çç®æ IQNå¿
é¡»æ¯å符串"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "è¿ç¨å卿å¡å¨ç端å£å¿
é¡»æ¯1å°65535ä¹é´çæ´æ°"
-
-msgid "iSCSI target username must be a string"
-msgstr "iSCSIç®æ ç¨æ·åå¿
须为ä¸ä¸ªå符串"
-
-msgid "iSCSI target password must be a string"
-msgstr "iSCSIç®æ å¯ç å¿
须为ä¸ä¸ªå符串"
-
-msgid "Specify name and type to create a storage pool"
-msgstr "为æ°å卿± æå®åååç±»å"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr "%(disk)s 䏿¯ææçç£ç/ååºãä¸è½è¢«æ·»å å°å卿± %(pool)sä¸"
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr "æªè½å®ç°é»è¾æ± %(pool)sçæ©å±ï¼è¯¦æ
ï¼%(err)s"
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "åªæé»è¾å卿± æ¯ææ´æ°ç£çåæ°ã"
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI主æºéé
å¨åå¿
é¡»æ¯ä¸ªå符串"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "å卿± kimchi_isosçä½å
é¨ä½¿ç¨"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr "ä¸è½æ¿æ´»NFSå卿± %(name)sãNFSæå¡å¨%(server)sä¸å¯å°è¾¾ã"
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr "ä¸è½åç¨NFSå卿± %(name)sãNFSæå¡å¨%(server)sä¸å¯å°è¾¾ã"
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr "ä¸è½åç¨å卿± %(name)sï¼è¯¥å卿± ä¸ä¸äºæ¨¡æ¿å
³è"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "ä¸è½å é¤å卿± %(name)sï¼è¯¥å卿± ä¸ä¸äºæ¨¡æ¿å
³è"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr "å·ç»'%(name)s'å·²ç»åå¨ï¼è¯·éæ©å
¶å®çå忥å建é»è¾å卿± ã"
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr "å
¨çæ«æä¿¡æ¯æ´æ°å¤±è´¥ã详æ
ï¼%(err)sã"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "åå¨å·%(name)så·²ç»åå¨"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "å卿± %(pool)s䏿²¡æåå¨å·%(name)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr "æªè½å建åå¨å·%(volume)sï¼å 为å卿± %(pool)s æªè¢«æ¿æ´»"
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "为æ°åå¨å·%(volume)sæå®æå®%(item)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr "ä¸è½ååºåå¨å·ï¼å 为å卿± %(pool)sæ²¡ææ¿æ´»"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr "ä¸è½å¨å卿± %(pool)sä¸å建åå¨å·%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr "ä¸è½å¨å卿± %(pool)sä¸ååºåå¨å·ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "ä¸è½æ¦é¤åå¨å·%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "ä¸è½å é¤åå¨å·%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "ä¸è½æ¹ååå¨å·%(name)sç大å°ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "åå¨ç±»å%(type)s䏿¯æå·çå建åå é¤"
-
-msgid "Storage volume name must be a string"
-msgstr "åå¨å·çååå¿
é¡»æ¯å符串"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "åå¨å·åé
é¢å¿
é¡»æ¯æ´æ°"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"䏿¯æè¯¥åå¨å·æ ¼å¼ï¼æ¯æçæ ¼å¼ï¼bochs, cloop, cow, dmg, qcow, qcow2, qed, "
-"raw, vmdk, vpcã"
-
-msgid "Storage volume requires a volume name"
-msgstr "åå¨å·éè¦åå"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr "åå¨å·ä¿¡æ¯æ´æ°å¤±è´¥ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr "åªè½å¯¹åæ°%(param)sä¸çä¸ä¸ªè¿è¡æå®"
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr "䏿¯æä»%(param)såå»ºèææº"
-
-msgid "Storage volume capacity must be an integer number."
-msgstr "åå¨å·å®¹éå¿
须为ä¸ä¸ªæ´æ°"
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr "åå¨å·URLå¿
须为http://ï¼https://ï¼ftp://æftps://"
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr "ä¸è½è®¿é®æä»¶%(url)sï¼è¯·æ£æ¥è¯¥æä»¶æ¯å¦åå¨ã"
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr "æªè½äºå卿± '%(pool)s'å¶ä½åå¨å·'%(name)s'ç坿¬ï¼è¯¦æ
ï¼%(err)s"
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "æ¥å£%(name)sä¸åå¨"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "ç½ç»%(name)så·²ç»åå¨"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "ç½ç»%(name)sä¸åå¨"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr "ç»ç½ç»%(network)sæå®çåç½%(subnet)sæ æ"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "æå®ä¸ä¸ªç½ç»æ¥å£æ¥å建桥æ¥ç±»åçç½ç»%(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "ä¸è½å 餿¿æ´»çç½ç»%(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr "ç»ç½ç»%(network)sæå®çæ¥å£%(iface)s已被使ç¨"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "æ¥å£åºè¯¥æ¯ä¸ä¸ªè£¸çç½ç»æ¥å£å¡ãbondingæè
æ¡¥æ¥è®¾å¤ã"
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "ä¸è½å建ç½ç»%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "ä¸è½ä¸ºç½ç»'%(name)s'æ¾å°ä¸ä¸ªæªä½¿ç¨çIPç½ç»å°åã"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "æ¯æçç½ç»ç±»åæé离ãNATåæ¡¥æ¥"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr "ç½ç»åç½å¿
é¡»æ¯ä¸ä¸ªIPå°åå ç½ç»åç¼æåç½æ©ç çå符串"
-
-msgid "Network interface must be a string"
-msgstr "ç½ç»æ¥å£å¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "ç½ç»VLANå·å¿
é¡»æ¯1å°4094ä¹é´çæ´æ°"
-
-msgid "Specify name and type to create a Network"
-msgstr "为æ°ç½ç»æå®åååç±»å"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "ä¸è½ä»¥æ¡¥è®¾å¤%(name)sä½ä¸ºVLANçtrunk设å¤ã"
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "ç½ç»æ¥å£å¯å¨å¤±è´¥ %(iface)sï¼%(err)sã"
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr "ç½ç»æ¥å£%(iface)så¯å¨å¤±è´¥ï¼è¯·æ£æ¥ç½ç»è¿æ¥æ
åµã"
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr "å¯å¨ç½ç»%(name)s失败ï¼è¯¦æ
ï¼%(err)s"
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "è¯ææ¥å%(name)sä¸åå¨"
-
-msgid "Debug report tool not found in system"
-msgstr "ç³»ç»ä¸æ²¡æè¯ææ¥åå·¥å
·"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "ä¸è½åå»ºè¯ææ¥å%(name)sã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr "æªè½æ¾å°æå®åç§°%(name)sçè°è¯æ¥å"
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "ä¸è½çæè¯ææ¥å%(name)sã详æ
ï¼%(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr "ä¸è½çæè¯ææ¥å%(name)sã详æ
ï¼%(err)s"
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-"è°è¯æ¥ååç§°å¿
须为ä¸ä¸ªå符串ãåªæè±æåç¬¦ï¼æ°åï¼ä¸å线('_')以åè¿å符('-')"
-"ä¸ºåæ³å符ã"
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr "åå为\"'%(name)s\"çè°è¯æ¥åå·²ç»åå¨ï¼è¯·éæ©å
¶å®çååã"
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "å卿å¡å¨%(server)sæªè¢«Kimchi使ç¨"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "åè¡çæ¬'%(name)s'ä¸åå¨"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "主æºä¸ä¸æ²¡æååº%(name)s"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr "æèææºå¨è¿è¡ï¼ä¸è½å
³é主æº"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "æèææºå¨è¿è¡ï¼ä¸è½é起主æº"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "æ²¡ææ¾å°èç¹è®¾å¤'%(name)s'"
-
-msgid "Conflicting flag filters specified."
-msgstr "flag filterså²çªã"
-
-msgid "No packages marked for update"
-msgstr "没æè½¯ä»¶å
æ è¯è¦å级"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "软件å
%(name)sæ²¡ææ è¯ä¸ºè¦å级"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr "è·åæ è¯ä¸ºè¦å级ç软件å
æ¶åºéã详æ
ï¼%(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "ç³»ç»ä¸æ²¡æå
¼å®¹ç软件å
管çå¨"
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "æ æçURI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr "æªè½éæ©ä¸ä¸ªèææºåç§°"
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "æ æçåå¨ç±»åãæ¯æç±»å为ï¼'cdrom'ï¼'disk'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr "è·¯å¾'%(value)s'䏿¯è®¾å¤çæææ¬å°/è¿ç¨è·¯å¾"
-
-msgid "Only CDROM path can be update."
-msgstr "ä»
æ¯æCDROMè·¯å¾æ´æ°ã"
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr "åå¨è®¾å¤%(dev_name)så¨èææº%(vm_name)sä¸ä¸åå¨"
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "å建æ°çåå¨è®¾å¤æ¶åºéï¼%(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "æ´æ°åå¨è®¾å¤æ¶åºéï¼%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "ç§»é¤åå¨è®¾å¤æ¶åºéï¼%(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr "䏿¯æIDE设å¤ççææ"
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "ä¸ºæ·»å æ°å»ºèææºç£çæå®ç±»ååè·¯å¾æè
ç±»ååå卿± /åå¨å·"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "æå®æ´æ°èææºç£ççè·¯å¾"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr "æ§å¶å¨ç±»å为%(type)sç设å¤è¾¾å°ä¸é%(limit)s"
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr "æªè½ä¸ºç»åºçå卿± /åå¨å·æ¾å°å¯¹åºç£çè·¯å¾ä¿¡æ¯ï¼%(error)s"
-
-msgid "Volume already in use by other virtual machine."
-msgstr "该å·å·²ç»è¢«å
¶ä»èææºä½¿ç¨ã"
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "å¢å èææºç£çæ¶ï¼ä»
è½æå®è·¯å¾æå卿± /åå¨å·ä¸çä¸ä¸ª"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr "æ ¼å¼ä¸º%(format)sçå·ä¸ç¬¦ååå¨ç±»å%(type)s"
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM软件ä»åºIDå¿
é¡»æ¯åªå
å«ä¸ä¸ªåè¯çå符串"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "软件ä»åºURLå¿
é¡»æ¯http://ã ftp:// æ file://"
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr "软件ä»åºé
ç½®æ¯ä¸ä¸ªä¸ä»åºé®åç¹å®å¼å¯¹åºçåå
¸"
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "DEBä»åºçåè¡çæ¬å¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "DEBä»åºçç»ä»¶å¿
须以æ°ç»å½¢å¼ååº"
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEBä»åºçç»ä»¶å¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUMä»åºçååå¿
é¡»æ¯ä¸ä¸ªå符串"
-
-msgid "GPG check must be a boolean value."
-msgstr "GPGæ ¡éªå¿
é¡»æ¯ä¸ä¸ªå¸å°å¼"
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPGé®å¿
é¡»æ¯ä¸ä¸ªæåASCIIè½¬ä¹æä»¶ï¼.ascæä»¶ï¼çURL"
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "ä¸è½æ´æ°è½¯ä»¶ä»åº%(repo_id)s"
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "软件ä»åº%(repo_id)sä¸åå¨ã"
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "æ¨çç³»ç»æ æ³è¯å«è½¯ä»¶ç®¡çå·¥å
·"
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "软件ä»åº%(repo_id)så·²ç»å¯ç¨ã"
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "软件ä»åº%(repo_id)så·²ç»ç¦ç¨ã"
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "ä¸è½ç§»é¤è½¯ä»¶ä»åº%(repo_id)s"
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "æ æ³å软件ä»åºçé
ç½®æä»¶%(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "æå®è½¯ä»¶ä»åºåè¡çæ¬æ¥å建ä¸ä¸ªDEBä»åºã"
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "ä¸è½å¯ç¨è½¯ä»¶ä»åº%(repo_id)s"
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "ä¸è½ç¦ç¨è½¯ä»¶ä»åº%(repo_id)s"
-
-msgid "YUM Repository ID already exists"
-msgstr "YUMä»åºIDå·²ç»åå¨"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUMä»åºååå¿
é¡»æ¯ä¸ä¸ªå符串"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "ä¸è½å举软件ä»åºã详æ
ï¼'%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "ä¸è½è·å软件ä»åºçä¿¡æ¯ã详æ
ï¼'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "ä¸è½å¢å 软件ä»åºã详æ
ï¼'%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "ä¸è½ç§»é¤è½¯ä»¶ä»åºã详æ
ï¼'%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr "软件ä»åºä¸æ¯æé
置类å: %(items)s"
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr "èææº'%(vm)s'å¨å¶ä½å¿«ç
§åå¿
é¡»å
³æºã"
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr "æªè½ä¸ºèææº'%(vm)s'å¶ä½å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr "å¿«ç
§'%(name)s'ä¸åå¨èææº'%(vm)s'ä¸ã"
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr "æªè½å¨èææº'%(vm)s'æ¾å°å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr "æªè½ååºèææº'%(vm)s'çå¿«ç
§ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr "æªè½å é¤èææº'%(vm)s'å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr "æªè½æ¾å°èææº'%(vm)s'å½åå¿«ç
§ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr "æªè½æ¢å¤èææº'%(vm)s'å°å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-"æªè½ä¸ºèææº'%(vm)s'å建快ç
§å 为å
¶ä½¿ç¨äºæ ¼å¼ä¸º'%(format)s'çç£çï¼å½åä»
æ¯"
-"æ'qcow2'æ ¼å¼ã"
-
-msgid "The number of vCPUs is too large for this system."
-msgstr "vCPUsçæ°é对该系ç»èè¨å¤ªå¤§ã"
-
-msgid "Invalid vCPU/topology combination."
-msgstr "æ æçvCPU/topologyç»åã"
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr "å½å主æºï¼æå½åé
ç½®ï¼ä¸å
许CPUææã"
-
-msgid "ERROR CODE"
-msgstr "é误ç "
-
-msgid "REASON"
-msgstr "åå "
-
-msgid "STACK"
-msgstr "è°ç¨æ "
-
-msgid "Go to Homepage"
-msgstr "è¿å主页"
-
-msgid "Create a New Virtual Machine"
-msgstr "å建ä¸ä¸ªæ°çèææº"
-
-msgid "Virtual Machine Name"
-msgstr "èææºåç§°"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr "ååæ¯èææºçæ è¯ã妿çç¥ï¼å°ä¼åºäºä½¿ç¨ç模æ¿éæ©ä¸ä¸ªååã"
-
-msgid "Template"
-msgstr "模æ¿"
-
-msgid "Please create a template first."
-msgstr "请å
éæ©ä¸ä¸ªæ¨¡æ¿"
-
-msgid "Create a Template"
-msgstr "å建ä¸ä¸ªæ¨¡æ¿"
-
-msgid "Please choose a template."
-msgstr "è¯·éæ©æ¨¡æ¿ã"
-
-msgid "OS"
-msgstr "æä½ç³»ç»"
-
-msgid "OS Version"
-msgstr "æä½ç³»ç»çæ¬"
-
-msgid "CPUS"
-msgstr "ä¸å¤®å¤çå¨"
-
-msgid "Memory"
-msgstr "å
å"
-
-msgid "Create"
-msgstr "å建"
-
-msgid "Creating..."
-msgstr "æ£å¨å建..."
-
-msgid "Cancel"
-msgstr "åæ¶"
-
-msgid "Edit Guest"
-msgstr "ä¿®æ¹å®¢æ·æº"
-
-msgid "General"
-msgstr "常è§"
-
-msgid "Storage"
-msgstr "åå¨"
-
-msgid "Interface"
-msgstr "ç½ç»æ¥å£"
-
-msgid "Permission"
-msgstr "æé"
-
-msgid "Host PCI Device"
-msgstr "主æºPCI设å¤"
-
-msgid "Snapshot"
-msgstr "å¿«ç
§"
-
-msgid "Name"
-msgstr "åç§°"
-
-msgid "CPUs"
-msgstr "ä¸å¤®å¤çå¨"
-
-msgid "Memory (MB)"
-msgstr "å
å(MB)"
-
-msgid "Icon"
-msgstr "徿 "
-
-msgid "Device"
-msgstr "设å¤åç§°"
-
-msgid "Path"
-msgstr "è·¯å¾"
-
-msgid "Network"
-msgstr "ç½ç»"
-
-msgid "Type"
-msgstr "ç±»å"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr "å¯éçç³»ç»ç¨æ·åç¨æ·ç»"
-
-msgid "Selected system users and groups"
-msgstr "å·²éçç³»ç»ç¨æ·åç¨æ·ç»"
-
-msgid "User"
-msgstr "ç¨æ·"
-
-msgid "All"
-msgstr "ææ"
-
-msgid "To Add"
-msgstr "å¾
æ·»å "
-
-msgid "Added"
-msgstr "已添å "
-
-msgid "filter"
-msgstr "è¿æ»¤å¨"
-
-msgid "Product"
-msgstr "产å"
-
-msgid "Vendor"
-msgstr "åå"
-
-msgid "Created"
-msgstr "å建äº"
-
-msgid "Save"
-msgstr "ä¿å"
-
-msgid "Replace"
-msgstr "æ¿æ¢"
-
-msgid "Detach"
-msgstr "å¸è½½"
-
-msgid "revert"
-msgstr "æ¢å¤"
-
-msgid "Start"
-msgstr "å¯ç¨"
-
-msgid "Reset"
-msgstr "éç½®"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "å
³éçµæº"
-
-msgid "Actions"
-msgstr "æä½"
-
-msgid "Connect"
-msgstr "è¿æ¥å°"
-
-msgid "Clone"
-msgstr "å¶ä½å¯æ¬"
-
-msgid "Edit"
-msgstr "ç¼è¾"
-
-msgid "Shut Down"
-msgstr "å
³æº"
-
-msgid "Delete"
-msgstr "å é¤"
-
-msgid "CPU"
-msgstr "å¤çå¨"
-
-msgid "Disk I/O"
-msgstr "ç£çI/O"
-
-msgid "Network I/O"
-msgstr "ç½ç»I/O"
-
-msgid "Livetile"
-msgstr "å±å¹"
-
-msgid "No guests found."
-msgstr "没æåç°å®¢æ·æº"
-
-msgid "Add a Storage Device to VM"
-msgstr "ä¸ºèææºæ·»å ä¸ä¸ªåå¨è®¾å¤"
-
-msgid "Device Type"
-msgstr "设å¤ç±»å"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "设å¤ç±»åãç®åæ¯æè®¾å¤ç±»åï¼\"cdrom\"å\"disk\"ã "
-
-msgid "Storage Pool"
-msgstr "å卿± "
-
-msgid "Storage pool which volume located in"
-msgstr "åå¨å·æå¨çå卿± "
-
-msgid "Storage Volume"
-msgstr "åå¨å·"
-
-msgid "Storage volume to be attached"
-msgstr "被添å çåå¨å·"
-
-msgid "File Path"
-msgstr "æä»¶è·¯å¾"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "æå¡å¨ç«¯CDROMæä½¿ç¨çISOæä»¶è·¯å¾"
-
-msgid "Attach"
-msgstr "è£
è½½"
-
-msgid "Shut down"
-msgstr "å
³æº"
-
-msgid "Restart"
-msgstr "éå¯"
-
-msgid "Basic Information"
-msgstr "åºæ¬ä¿¡æ¯"
-
-msgid "OS Distro"
-msgstr "æä½ç³»ç»åè¡ç"
-
-msgid "OS Code Name"
-msgstr "æä½ç³»ç»ä»£å·"
-
-msgid "Processor"
-msgstr "å¤çå¨"
-
-msgid "CPU(s)"
-msgstr "CPU(s)"
-
-msgid "System Statistics"
-msgstr "ç³»ç»ç»è®¡ä¿¡æ¯"
-
-msgid "Software Updates"
-msgstr "è½¯ä»¶æ´æ°"
-
-msgid "Update Progress"
-msgstr "æ´æ°è¿åº¦"
-
-msgid "Repositories"
-msgstr "软件ä»åº"
-
-msgid "Debug Reports"
-msgstr "主æºè¯ææ¥å"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr "ç¨æ·åæå¯ç é误ï¼è¯·éæ°è¾å
¥ã"
-
-msgid "This field is required."
-msgstr "éè¦å¡«åæ¤å¤"
-
-msgid "Log in"
-msgstr "ç»å½"
-
-msgid "Logging in..."
-msgstr "ç»å½ä¸..."
-
-msgid "Host"
-msgstr "主æº"
-
-msgid "Guests"
-msgstr "å®¢æ·æº"
-
-msgid "Templates"
-msgstr "模æ¿"
-
-msgid "Failed to get application configuration"
-msgstr "è·ååºç¨é
置失败"
-
-msgid "This is not a valid Linux path"
-msgstr "è¿ä¸æ¯ä¸ä¸ªææçLinuxè·¯å¾"
-
-msgid "This is not a valid URL."
-msgstr "è¿ä¸æ¯ä¸ä¸ªææçURL"
-
-msgid "No such data available."
-msgstr "没æå¯ç¨çæ°æ®"
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"è¿æ¥ä¸ä¸ä¸»æºã请确ä¿ä¸»æºç³»ç»å·²å¯å¨ï¼å¹¶ä¸è½éè¿ç½ç»è¿æ¥ä¸»æºãHTTP请æ±ååºï¼%1"
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "å é¤ç¡®è®¤"
-
-msgid "OK"
-msgstr "ç¡®å®"
-
-msgid "Confirm"
-msgstr "确认"
-
-msgid "Warning"
-msgstr "è¦å"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "æ£å¨å è½½..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "éè¯"
-
-msgid "Detailed message:"
-msgstr "è¯¦ç»æ¶æ¯ï¼"
-
-msgid "No ISO found"
-msgstr "没æåç°ISOæä»¶"
-
-msgid "This is not a valid ISO file."
-msgstr "è¿ä¸æ¯ä¸ä¸ªææçISOæä»¶"
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "è¿éè¦ä¸æ®µæ¶é´ãæ¯å¦ç»§ç»ï¼"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "è¿å°æ°¸ä¹
å 餿¨¡æ¿ãæ¯å¦ç»§ç»ï¼"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr "æèææºå¨è¿è¡ï¼ä¸è½å
³é主æºã"
-
-msgid "Max:"
-msgstr "æå¤§ï¼"
-
-msgid "Utilization"
-msgstr "å©ç¨ç"
-
-msgid "Available"
-msgstr "å¯å©ç¨ç"
-
-msgid "Read Rate"
-msgstr "读éç"
-
-msgid "Write Rate"
-msgstr "åéç"
-
-msgid "Received"
-msgstr "æ¥æ¶"
-
-msgid "Sent"
-msgstr "åé"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr "å
³éæè
éå¯ä¸»æºä¼å¯¼è´æ²¡æä¿åçå·¥ä½ä¸¢å¤±ãç»§ç»å
³æº/éå¯ï¼"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr "软件ä»åºå°è¢«æ°¸ä¹
å é¤ï¼ä¸è½æ¢å¤ãæ¯å¦ç»§ç»ï¼"
-
-msgid "ID"
-msgstr "æ è¯ç¬¦"
-
-msgid "Base URL"
-msgstr "åºæ¬URL"
-
-msgid "Is Mirror"
-msgstr "æ¯å¦ä¸ºéå"
-
-msgid "URL Args"
-msgstr "URLåæ°"
-
-msgid "Enabled"
-msgstr "å·²å¯ç¨"
-
-msgid "GPG Check"
-msgstr "GPGæ ¡éª"
-
-msgid "GPG Key"
-msgstr "GPGé®"
-
-msgid "Add"
-msgstr "å¢å "
-
-msgid "Remove"
-msgstr "å é¤"
-
-msgid "Enable"
-msgstr "使è½"
-
-msgid "Disable"
-msgstr "ç¦ç¨"
-
-msgid "Package Name"
-msgstr "软件å
åç§°"
-
-msgid "Version"
-msgstr "çæ¬"
-
-msgid "Architecture"
-msgstr "ä½ç³»ç»æ"
-
-msgid "Repository"
-msgstr "软件ä»åº"
-
-msgid "Update All"
-msgstr "æ´æ°ææ"
-
-msgid "Updating..."
-msgstr "æ£å¨æ´æ°..."
-
-msgid "Failed to retrieve packages update information."
-msgstr "æ¥æ¾è½¯ä»¶å
æ´æ°ä¿¡æ¯å¤±è´¥ã"
-
-msgid "Failed to update package(s)."
-msgstr "æ´æ°è½¯ä»¶å
失败"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr "è¯ææ¥åå°è¢«æ°¸ä¹
å é¤ï¼å¹¶ä¸ä¸è½æ¢å¤ãæ¯å¦ç»§ç»ï¼"
-
-msgid "Generated Time"
-msgstr "çææ¶é´"
-
-msgid "Generate"
-msgstr "çæ"
-
-msgid "Generating..."
-msgstr "æ£å¨çæ..."
-
-msgid "Rename"
-msgstr "éå½å"
-
-msgid "Download"
-msgstr "ä¸è½½"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr "æ¥åååä¸åªè½å
å«åæ¯ãæ°åãä¸å线('_')åè¿å符('-')"
-
-msgid "Pending..."
-msgstr "æ£å¨å è½½..."
-
-msgid "Report name is the same as the original one."
-msgstr "æ¥ååç§°ä¸åå§åç§°éå¤ã"
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr "è¿å°å é¤èææºåå®çèæç£çã该æä½ä¸è½æ¤éï¼ç»§ç»åï¼"
-
-msgid "Power off Confirmation"
-msgstr "å
³éçµæºç¡®è®¤"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr "è¿æ ·åå¯è½å¯¼è´ä¸è¯åæï¼æ¯å¦å®¢æ·æºç£çç¼åæªå·æ°ï¼ç¡®è®¤è¦ç»§ç»åï¼"
-
-msgid "Reset Confirmation"
-msgstr "é置确认"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr "å¨å®¢æ·æºæä½ç³»ç»æªå
³éçæ
åµä¸éç½®æé£é©å¯¼è´æ°æ®ä¸¢å¤±ï¼ç¡®è®¤è¦ç»§ç»åï¼"
-
-msgid "Shut Down Confirmation"
-msgstr "å
³æºç¡®è®¤"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "注æï¼å®¢æ·æºæä½ç³»ç»å¯è½ä¼å¿½ç¥è¿ä¸ªè¯·æ±ï¼ç¡®è®¤è¦ç»§ç»åï¼"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr "èææºå é¤ç¡®è®¤"
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr "è¯¥èææºä¸æ¯ä¸ä¸ªç¨³å®çèææºï¼å
³æºå°ä¼å é¤å®ï¼æ¯å¦ç»§ç»ï¼"
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-"å½ç®æ å®¢æ·æºä½¿ç¨SCSIæè
iSCSIåå¨å·æ¶ï¼è¿äºåå¨å·ç坿¬å°è¢«æ¾ç½®äºé»è®¤å卿± "
-"ä¸ãå¨ç®æ å卿± 没æè¶³å¤ç©ºé´æ¾ç½®å
¶ä»åå¨å·çæ¶åä¹ä¼å¦æ¤ã确认继ç»ï¼"
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr "CDROMå°è¢«æ°¸ä¹
å¸è½½ï¼ä½ å¯ä»¥éæ°è£
è½½å®ãç»§ç»å¸è½½ï¼"
-
-msgid "Attaching..."
-msgstr "æ£å¨è£
è½½"
-
-msgid "Replacing..."
-msgstr "æ£å¨æ¿æ¢..."
-
-msgid "Successfully attached!"
-msgstr "æåè£
è½½"
-
-msgid "Successfully replaced!"
-msgstr "æåæ¿æ¢"
-
-msgid "Successfully detached!"
-msgstr "æåå¸è½½"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr "该ç£çå°ä¼è¢«æ°¸ä¹
å¸è½½ï¼ä½ å¯ä»¥éæ°æ·»å å®ï¼ç»§ç»æ§è¡å¸è½½æä½å?"
-
-msgid "interface:"
-msgstr "æ¥å£ï¼"
-
-msgid "address:"
-msgstr "å°åï¼"
-
-msgid "link_type:"
-msgstr "è¿æ¥ç±»åï¼"
-
-msgid "block:"
-msgstr "åï¼"
-
-msgid "drive_type:"
-msgstr "设å¤ç±»åï¼"
-
-msgid "model:"
-msgstr "模åï¼"
-
-msgid "Affected devices:"
-msgstr "被影åç设å¤ï¼"
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN æ è¯ç¬¦å¿
é¡»å¨1è³4094ä¹é´"
-
-msgid "unavailable"
-msgstr "æ æ³è·å"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr "ï»¿æ¤æä½å°ä¸æä¾èµæ¤ç½ç»çèææºçç½ç»è¿æ¥ã"
-
-msgid "Create a network"
-msgstr "å建ä¸ä¸ªç½ç»"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"è¿æ¯ä¸ä¸ªä¸´æ¶çç½ç»é
ç½®ï¼è¯¥æä½ä¼æ°¸ä¹
å°å é¤è¿ä¸ªç½ç»è䏿¯åæ¢å
¶è¿è¡ï¼ç¡®å®è¦ç»§"
-"ç»åï¼"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "è¿å°æ°¸ä¹
å é¤å卿± ãæ¯å¦ç»§ç»ï¼"
-
-msgid "This storage pool is empty."
-msgstr "è¿ä¸ªå卿± 为空"
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr "ä½ çç£çå°ä¼æ ¼å¼åï¼ç£çä¸çæ°æ®ä¼ä¸¢å¤±ï¼ä½ ç¡®å®è¦ç»§ç»åï¼"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSIå
纤éé"
-
-msgid "No SCSI adapters found."
-msgstr "没æåç°SCSIéé
å¨"
-
-msgid "Loading iSCSI targets..."
-msgstr "读åiSCSIç®æ ..."
-
-msgid "No iSCSI found. Please input one."
-msgstr "æªè½æ¾å°iSCSI,请è¾å
¥ä¸ä¸ªã"
-
-msgid "Failed to load iSCSI targets."
-msgstr "读åiSCSIç®æ 失败ã"
-
-msgid "The storage pool name can not be blank."
-msgstr "å卿± çåç§°ä¸è½ä¸ºç©ºã"
-
-msgid "The storage pool path can not be blank."
-msgstr "å卿± çè·¯å¾ä¸è½ä¸ºç©ºã"
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFSæå¡å¨æè½½è·¯å¾ä¸è½ä¸ºç©ºã"
-
-msgid "Invalid NFS mount path."
-msgstr "æ æçNFSæè½½è·¯å¾ã"
-
-msgid "No logical device selected."
-msgstr "没æéæ©é»è¾è®¾å¤ã"
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSIç®æ ä¸è½ä¸ºç©ºã"
-
-msgid "Server name can not be blank."
-msgstr "æå¡å¨ä¸è½ä¸ºç©ºã"
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr "è¿ä¸æ¯ä½ 个ææçæå¡å¨åç§°æIPå°åï¼è¯·å¯¹å
¶è¿è¡ä¿®æ¹ã"
-
-msgid "Looking for available partitions ..."
-msgstr "æ¥æ¾ææçååº ..."
-
-msgid "No available partitions found."
-msgstr "没æåç°æ¨¡æ¿ã"
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr "对äºéæä¹
å卿± ï¼è¿ä¸ªæä½å°ä¼æ°¸ä¹
å é¤å卿± è䏿¯åç¨ãæ¯å¦ç»§ç»ï¼"
-
-msgid "Unable to retrieve partitions information."
-msgstr "æªè½æ¾å°ååºä¿¡æ¯ã"
-
-msgid "In progress..."
-msgstr "æ£å¨è¿è¡..."
-
-msgid "Failed!"
-msgstr "失败ï¼"
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr "CDROMè·¯å¾éè¦ä¸ä¸ªææçæ¬å°/è¿ç¨è·¯å¾ä¸ä¸è½ä¸ºç©ºã"
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "å卿± æå·ä¸è½ä¸ºç©º"
-
-#, fuzzy
-msgid "Filter"
-msgstr "è¿æ»¤å¨"
-
-msgid "Network Name"
-msgstr "ç½ç»åç§°"
-
-msgid "State"
-msgstr "ç¶æ"
-
-msgid "Network Type"
-msgstr "ç½ç»ç±»å"
-
-msgid "Address Space"
-msgstr "å°å空é´"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "ååä¸ä¸è½å
å«â/âå'\"'ã"
-
-msgid "Isolated: no external network connection"
-msgstr "é离: åç©çç½ç»ä¸è¿é"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: ä»èææºå°ç©çç½ç»ååè¿æ¥"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "æ¡¥æ¥ï¼èææºå¯ä»¥ç´æ¥è¿æ¥å°ç©çç½ç»ä¸ã"
-
-msgid "(No interfaces found)"
-msgstr "(没æåç°ç½ç»æ¥å£)"
-
-msgid "Destination"
-msgstr "ç®æ 设å¤"
-
-msgid "Enable VLAN"
-msgstr "å¯ç¨VLAN"
-
-msgid "VLAN ID"
-msgstr "VLANå·"
-
-msgid "Stop"
-msgstr "忢"
-
-msgid "Generate a New Debug Report"
-msgstr "产çä¸ä¸ªæ°çè¯ææ¥å"
-
-msgid "Report Name"
-msgstr "è¯ææ¥åå"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"ååç¨æ¥æ è¯è¯ææ¥åã妿çç¥ï¼å°ä¼åºäºå½åæ¶é´çæä¸ä¸ªæ°ååãååä¸å¯ä»¥å
"
-"å«åæ¯ãæ°åãä¸å线 ('_') åè¿å符ï¼'-'ï¼"
-
-msgid "Rename a Debug Report"
-msgstr "éå½åä¸ä¸ªè°è¯æ¥å"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr "æ¥åçå¯ä¸è¡¨ç¤ºåç§°ï¼åç§°å¯ä»¥å
å«ï¼è±æåç¬¦ï¼æ°ååè¿å符(\"-\")ã"
-
-msgid "Submit"
-msgstr "æäº¤"
-
-msgid "Add a Repository"
-msgstr "å¢å ä¸ä¸ªè½¯ä»¶ä»åº"
-
-msgid "Identifier"
-msgstr "æ è¯ç¬¦"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "ä¸ä¸ªåè¯ï¼å¯ä¸æ è¯è½¯ä»¶ä»åº"
-
-msgid "Textual name for the repository."
-msgstr "软件ä»åºçåé¢åå"
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "å¿
éçåæ®µ"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "软件ä»åºçURLï¼æ¯æçåè®®æhttpãftpãåfile"
-
-msgid "Repository is a mirror"
-msgstr "软件ä»åºæ¯ä¸ä¸ªéå"
-
-msgid "Distribution"
-msgstr "åè¡ç"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEBä»åºçåè¡ç"
-
-msgid "Components"
-msgstr "ç»ä»¶"
-
-msgid "List of components in DEB repository."
-msgstr "DEBä»åºä¸çç»ä»¶å表"
-
-msgid "Edit Repository"
-msgstr "ä¿®æ¹è½¯ä»¶ä»åº"
-
-msgid "Mirror List URL"
-msgstr "éåå表URL"
-
-msgid "Yes"
-msgstr "æ¯"
-
-msgid "No"
-msgstr "å¦"
-
-msgid "Capacity"
-msgstr "容é"
-
-msgid "Allocated"
-msgstr "å·²åé
"
-
-msgid "Location"
-msgstr "è·¯å¾"
-
-msgid "Device path"
-msgstr "设å¤è·¯å¾"
-
-msgid "active"
-msgstr "å·²æ¿æ´»"
-
-msgid "inactive"
-msgstr "æªæ¿æ´»"
-
-msgid "Deactivate"
-msgstr "åç¨"
-
-msgid "Activate"
-msgstr "æ¿æ´»"
-
-msgid "Add Volume"
-msgstr "æ·»å å·"
-
-msgid "Extend"
-msgstr "æ©å±"
-
-msgid "Undefine"
-msgstr "åæ¶å®ä¹"
-
-msgid "Format"
-msgstr "æ ¼å¼"
-
-msgid "Allocation"
-msgstr "åé
"
-
-msgid "Define a New Storage Pool"
-msgstr "å®ä¹ä¸ä¸ªæ°çå卿± "
-
-msgid "Storage Pool Name"
-msgstr "å卿± åç§°"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "该åç§°ç¨æ¥å¯ä¸æ è¯å卿± ï¼è¯¥åç§°ä¸è½ä¸ºç©ºã"
-
-msgid "Storage Pool Type"
-msgstr "å卿± ç±»å"
-
-msgid "Storage Path"
-msgstr "åå¨è·¯å¾"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr "å卿± çè·¯å¾.æ¯ä¸ªå卿± çè·¯å¾æ¯å¯ä¸çã"
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr "妿ç®å½ä¸åå¨ï¼KIMCHIä¼èªå¨å¨ç³»ç»ä¸å建ä¸ä¸ªæ°çç®å½"
-
-msgid "NFS Server IP"
-msgstr "NFSæå¡å¨IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr "NFSæå¡å¨IPæè
主æºåï¼å¯ä»¥ç´æ¥è¾å
¥æè
ä»åå²è®°å½ä¸éåã"
-
-msgid "NFS Path"
-msgstr "NFS è·¯å¾"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFSæå¡å¨ä¸å¯¼åºçNFSè·¯å¾"
-
-msgid "iSCSI Server"
-msgstr "iSCSIæå¡å¨"
-
-msgid "Server"
-msgstr "æå¡å¨"
-
-msgid "Port"
-msgstr "端å£"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSIæå¡å¨IPæè
主æºåï¼ ä¸è½ä¸ºç©ºã"
-
-msgid "Target"
-msgstr "ç®æ "
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSIç®æ "
-
-msgid "Add iSCSI Authentication"
-msgstr "æ·»å ISCSI认è¯"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI认è¯"
-
-msgid "User Name"
-msgstr "ç¨æ·å"
-
-msgid "Password"
-msgstr "å¯ç "
-
-msgid "SCSI Adapter"
-msgstr "SCSIéé
å¨"
-
-msgid "Please, wait..."
-msgstr "请çå¾
..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr "为å卿± æ·»å ä¸ä¸ªå·"
-
-msgid "Fetch from remote URL"
-msgstr "ä»è¿ç¨URLè·å"
-
-msgid "Enter the remote URL here."
-msgstr "å¨è¿éè¾å
¥è¿ç¨URLã"
-
-msgid "Upload a file"
-msgstr "ä¸ä¼ ä¸ä¸ªæä»¶"
-
-msgid "Choose the file you want to upload."
-msgstr "éæ©éè¦ä¸ä¼ çæä»¶ã"
-
-msgid "Add Template"
-msgstr "å建模æ¿"
-
-msgid "Where is the source media for this template? "
-msgstr "模æ¿çæºä»è´¨å¨åªéï¼"
-
-msgid "Local ISO Image"
-msgstr "æ¬å°ISOéå"
-
-msgid "Local Image File"
-msgstr "æ¬å°éåæä»¶"
-
-msgid "Remote ISO Image"
-msgstr "è¿ç¨ISOéå"
-
-msgid "Search ISOs"
-msgstr "æç´¢ISO"
-
-msgid "The following ISOs are available:"
-msgstr "å¯ç¨ISOæä»¶å¦ä¸"
-
-msgid "OS: "
-msgstr "æä½ç³»ç»ï¼ "
-
-msgid "Version: "
-msgstr "çæ¬ï¼ "
-
-msgid "Size: "
-msgstr "大å°ï¼"
-
-msgid "Search more ISOs"
-msgstr "æç´¢æ´å¤ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "ä»éä¸çISOä¸å建模æ¿"
-
-msgid "I want to use a specific ISO file"
-msgstr "æå®ä¸ä¸ªISOæä»¶"
-
-msgid "Loading default remote ISOs ..."
-msgstr "å è½½é»è®¤çè¿ç¨ISOs ..."
-
-msgid "Arch: "
-msgstr "ä½ç³»ç»æï¼"
-
-msgid "I want to use a custom URL"
-msgstr "ææ³ç¨ä¸ä¸ªèªå®ä¹çURL"
-
-msgid "Edit Template"
-msgstr "ç¼è¾æ¨¡æ¿"
-
-msgid "CDROM"
-msgstr "å
驱"
-
-msgid "Image File"
-msgstr "éåæä»¶"
-
-msgid "Graphics"
-msgstr "å¾å½¢"
-
-msgid "Disk(GB)"
-msgstr "ç£ç(GB)"
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU个æ°"
-
-msgid "Manually set CPU topology"
-msgstr "æå¨é
ç½®CPUææ"
-
-msgid "Cores"
-msgstr "å
æ ¸æ°"
-
-msgid "Threads"
-msgstr "线ç¨"
-
-msgid "No templates found."
-msgstr "没æåç°æ¨¡æ¿"
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "ä¸å
许å é¤%(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "䏿¯ææ´æ°%(resource)s"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "ä¸å
许å建%(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "æ æ³è§£æJSON请æ±"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "è¿ä¸ªAPIä»
æ¯æJSON"
-
-#~ msgid "Parameters does not match requirement in schema: %(err)s"
-#~ msgstr "åæ°ä¸ç¬¦åè¦æ±çæ ¼å¼ï¼%(err)s"
-
-#~ msgid "You don't have permission to perform this operation."
-#~ msgstr "æ¨æ²¡ææéæ§è¡è¿é¡¹æä½ã"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "å°æªä¸ºmodel对象åå§åæ°æ®åå¨ã"
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "ç±äºé误%(err)sä»»å¡å¯å¨å¤±è´¥"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr "ç¨æ·'%(username)s'身份éªè¯å¤±è´¥.[é误代ç ï¼%(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "æ¨æ²¡æè¢«ææè®¿é®Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "æå®ç»å½Kimchiç%(item)s"
-
-#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
-#~ msgstr "æ æçLDAPé
ç½®ï¼%(item)s : %(value)s"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "卿°æ®åå¨ä¸æ¾ä¸å°%(item)s"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr "å½ä»¤'%(cmd)s'è¿è¡%(seconds)sç§åè¶
æ¶ã"
-
-#~ msgid "Peers"
-#~ msgstr "å¯¹çæº"
-
-#~ msgid "Searching"
-#~ msgstr "æ£å¨æ¥è¯¢"
-
-#~ msgid "No peers found."
-#~ msgstr "没æåç°å¯¹çæºã"
-
-#~ msgid "Help"
-#~ msgstr "帮å©"
-
-#~ msgid "About"
-#~ msgstr "å
³äº"
-
-#~ msgid "Log out"
-#~ msgstr "ç»åº"
-
-#~ msgid "Version:"
-#~ msgstr "çæ¬ï¼"
-
-#~ msgid "Session timeout, please re-login."
-#~ msgstr "ç»å½è¶
æ¶ï¼è¯·éæ°ç»å½ã"
diff --git a/plugins/kimchi/po/zh_TW.po b/plugins/kimchi/po/zh_TW.po
deleted file mode 100644
index 90045b5..0000000
--- a/plugins/kimchi/po/zh_TW.po
+++ /dev/null
@@ -1,2138 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_TW\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or \"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "åå¾åå¡è£ç½®æç¼çé¯èª¤ãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "åå¾ %(device)s çåå¡è£ç½®è³è¨æç¼çé¯èª¤ã"
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "æ¾ä¸å° distro æªæ¡ï¼%(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr "ç¡æ³åæ distro æªæ¡ï¼%(filename)sãè«ç¢ºä¿å®æ¯ JSON æªæ¡ã"
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "ç¡æ³ç»å
¥ iSCSI 主æ©ç®æ¨ %(portal)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "ç¡æ³ç»å
¥ iSCSI ä¸»æ© %(host)s ç®æ¨ %(target)s"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISO æªæ¡ %(filename)s ä¸å¯éæ©"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "ISO æªæ¡ %(filename)s æ²æææç El Torito éæ©è¨é"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "ISO %(filename)s ä¸æç¡æç El Torito é©èé
ç®"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ISO %(filename)s ä¸æç¡æç El Torito ååæç¤ºå¨"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "ISO %(filename)s 䏿䏻è¦ç£ç¢åçéé æç£åé¡å"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "è®å ISO %(filename)s ä¸çç£åæè¿°åæéå°ä¸ç¶çæ ¼å¼"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the '%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"Hypervisor æ²æä½¿ç¨æ¤ ISO %(filename)s çè¨±å¯æ¬ãè«èéå°å
¶ç§»åè³ /var/lib/"
-"libvirt ä¸ãå°æå°è¨±å¯æ¬è¨çº'%(user)s' 使ç¨è
çæªæ¡ååæ§å¶æ¸
å®ï¼è¥æå¯è½ï¼ã"
-"å° '%(user)s' æ°å¢è³ ISO è·¯å¾ç¾¤çµæï¼å»ºè°ä¸è¦å·è¡æ¤åä½ï¼å·è¡ 'chmod -R o+x "
-"'path_to_iso'ãè©³ç´°è³æï¼%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "èæ¬æ©å¨ %(name)s å·²åå¨"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "èæ¬æ©å¨ %(name)s ä¸åå¨"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "ç¡æ³æ·åå·²åæ¢èæ¬æ©å¨ %(name)s çç«é¢"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "æ¤ä¼ºæå¨ä¸æ¯æ´é 端 ISO æ åæªã"
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³å»ºç«èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³å»ºç«èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³æ·åèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "è¦æ¥è½çåå½¢å¡ä½åå¿
é æ¯ IPv4 æ IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "æå®ç¨æ¼å»ºç«èæ¬æ©å¨çç¯æ¬"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³ååèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³åæ¢èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³åªé¤èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³éæ°å½åèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "網路å稱å¿
é æ¯å串"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "網路å稱å¿
é æ¯å串"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "使ç¨è
'%(users)s' ä¸åå¨ã"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "使ç¨è
'%(groups)s' ä¸åå¨ã"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³åæ¢èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "ç¡æ³ååèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with "
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus "
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >= "
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "ä»é¢ %(iface)s ä¸å卿¼èæ¬æ©å¨ %(name)s ä¸"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr "çºèæ¬æ©å¨ %(name)s æå®ç網路 %(network)s ä¸åå¨"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "å¯ä¸åæ¯æ´çèæ¬æ©å¨ä»é¢é¡åæ¯ç¶²è·¯"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "èæ¬æ©å¨ä»é¢ç網路å稱å¿
é æ¯å串"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr "çºèæ¬æ©å¨ä»é¢æå®ç網路模åå¡ç¡æ"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "æå®é¡åå網路以æ°å¢èæ¬æ©å¨ä»é¢"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "ç¯æ¬ %(name)s å·²åå¨"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not exist"
-msgstr "çºç¯æ¬ %(template)s æå®ç網路 '%(network)s' ä¸åå¨"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr "çºç¯æ¬ %(template)s æå®çå²åå '%(pool)s' ä¸åå¨"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not active"
-msgstr "çºç¯æ¬ %(template)s æå®çå²åå '%(pool)s' æªèæ¼ä½ç¨ä¸çæ
"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "çº CDROM æå®ç忏 '%(param)s' ç¡æã"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "çºç¯æ¬ %(template)s æå®ç網路 %(network)s æªèæ¼ä½ç¨ä¸çæ
"
-
-msgid "Template name must be a string"
-msgstr "ç¯æ¬å稱å¿
é æ¯å串"
-
-msgid "Template icon must be a path to the image"
-msgstr "ç¯æ¬å示å¿
é æ¯å½±åçè·¯å¾"
-
-msgid "Template distribution must be a string"
-msgstr "ç¯æ¬ç¼è¡å¥ä»¶å¿
é æ¯å串"
-
-msgid "Template distribution version must be a string"
-msgstr "ç¯æ¬ç¼è¡çæ¬å¿
é æ¯å串"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPU æ¸ç®å¿
é æ¯æ´æ¸"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "è¨æ¶é«æ¸é (MB) å¿
é æ¯å¤§æ¼ 512 çæ´æ¸"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "ç¯æ¬ CDROM å¿
é æ¯æ¬ç«¯æé 端 ISO æªæ¡"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "çºç¯æ¬æå®çå²åå URI %(value)s ç¡æ"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "æå® ISO æ åæªä½çº CDROM 以建ç«ç¯æ¬"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "ç¯æ¬çææç¶²è·¯é½å¿
é 卿¸
å®ä¸æå®ã"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³å»ºç«ç¯æ¬ï¼%(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³åªé¤ç¯æ¬ï¼%(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "ç¯æ¬ CDROM å¿
é æ¯æ¬ç«¯æé 端 ISO æªæ¡"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "å²åå %(name)s å·²åå¨"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "å²åå %(name)s ä¸åå¨"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "æå® %(item)s 以建ç«å²åå %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "ç¡æ³åªé¤ä½ç¨ä¸çå²åå %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "ç¡æ³ååºå²ååãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "ç¡æ³å»ºç«å²åå %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr "ç¡æ³åå¾å²åå %(name)s ä¸å²åç£åçæ¸ç®ãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "ç¡æ³ååå²åå %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "ç¡æ³åæ¶ååå²åå %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "ç¡æ³åªé¤å²åå %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr "ç¡æ³å»ºç« NFS å²ååï¼å çºå¨è£è¼æéï¼å¯åºè·¯å¾ %(path)s å¯è½æå°é"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr "ç¡æ³å»ºç« NFS å²ååï¼å çºå¯åºè·¯å¾ %(path)s è£è¼å¤±æ"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "ä¸åæ¯æ´çå²ååé¡åï¼%(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "å²ååè·¯å¾å¿
é æ¯å串"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "å²åå主æ©å¿
é æ¯ IP æä¸»æ©å稱"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "å²ååè£ç½®åæ¸å¿
é æ¯æ¸
å®"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSI å²ååçç®æ¨ IQN å¿
é æ¯å串"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "é 端å²åé«ä¼ºæå¨çå å¿
é æ¯ä»æ¼ 1 å 65535 ä¹éçæ´æ¸"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "æå®å稱åé¡å以建ç«å²åå"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr "%(disk)s 䏿¯ææçç£ç¢/åå²åãç¡æ³å°å®æ°å¢è³å²åå%(pool)sã"
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "åªè½éå°é輯å²ååæ´æ°ãå
éç£ç¢ã忏ã"
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI 主æ©é
æ¥å¡å稱å¿
é æ¯å串ã"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "å²åå kimchi_isos ä¿çä¾å
§é¨ä½¿ç¨"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr "ç¡æ³åå NFS å²åå %(name)sãNFS 伺æå¨ %(server)sç¡æ³é£ç·ã"
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr "ç¡æ³åæ¶åå NFS å²åå %(name)sãNFS 伺æå¨ %(server)sç¡æ³é£ç·ã"
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr "ç¡æ³åæ¶ååå²åå %(name)sï¼å çºå®èé¨åç¯æ¬ç¸éè¯"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "ç¡æ³åªé¤å²åå %(name)sï¼å çºå®èé¨åç¯æ¬ç¸éè¯"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name "
-"to create the logical pool."
-msgstr "åçº '%(name)s' çç£å群çµå·²åå¨ãè«é¸æå¦ä¸åå稱以建ç«é輯å²ååã"
-
-#, python-format
-msgid "Unable to update database with deep scan information due error: %(err)s"
-msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³ä½¿ç¨æ·±å±¤ææè³è¨ä¾æ´æ°è³æåº«ï¼%(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "å²åç£å %(name)s å·²åå¨"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "å²åç£å %(name)s ä¸å卿¼å²åå %(pool)s ä¸"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "æå® %(item)s 以建ç«å²åç£å %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr "ç¡æ³ååºå²åç£åï¼å çºå²åå %(pool)s æªèæ¼ä½ç¨ä¸çæ
"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
-"(err)s"
-msgstr "ç¡æ³å¨å²åå %(pool)s ä¸å»ºç«å²åç£å %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr "ç¡æ³ååºå²åå %(pool)s ä¸çå²åç£åãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "ç¡æ³æ¸
é¤å²åç£å %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "ç¡æ³åªé¤å²åç£å %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "ç¡æ³èª¿æ´å²åç£å %(name)s ç大å°ãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "å²åé«é¡å %(type)s 䏿¯æ´ç£å建ç«ååªé¤"
-
-msgid "Storage volume name must be a string"
-msgstr "å²åç£åå稱å¿
é æ¯å串"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "å²åç£åé
ç½®å¿
é æ¯æ´æ¸"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "å²åç£åéè¦ç£åå稱"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³ä½¿ç¨å²åç£åè³è¨ä¾æ´æ°è³æåº«ï¼%(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload' parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "ä»é¢ %(name)s ä¸åå¨"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "網路 %(name)s å·²åå¨"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "網路 %(name)s ä¸åå¨"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr "çºç¶²è·¯ %(network)s æå®çå網路 %(subnet)s ç¡æã"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "æå®ç¶²è·¯ä»é¢ä»¥å»ºç«æ©æ¥ç網路 %(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "ç¡æ³åªé¤ä½ç¨ä¸ç網路 %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in use"
-msgstr "çºç¶²è·¯ %(network)s æå®çä»é¢ %(iface)s å·²å¨ä½¿ç¨ä¸"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "ä»é¢æè©²æ¯è£¸é² NICãæ¥åè£ç½®ææ©æ¥å¨è£ç½®ã"
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "ç¡æ³å»ºç«ç¶²è·¯ %(name)sãè©³ç´°è³æï¼%(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "æ¾ä¸å°ç¶²è·¯ '%(name)s' çå¯ç¨ IP ä½å"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "忝æ´ç網路é¡åæ¯éé¢å¼ãNAT åæ©æ¥å¨"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr "網路çå網路å¿
é æ¯å«æ IP ä½åãåé¦æç¶²è·¯é®ç½©çå串"
-
-msgid "Network interface must be a string"
-msgstr "網路ä»é¢å¿
é æ¯å串"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "網路 VLAN ID å¿
é æ¯ä»æ¼ 1 å 4094 ä¹éçæ´æ¸"
-
-msgid "Specify name and type to create a Network"
-msgstr "æå®å稱åé¡å以建ç«ç¶²è·¯"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "æ©æ¥å¨è£ç½® %(name)s ä¸è½æ¯ VLAN çå¹¹ç·è£ç½®ã"
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "ç¡æ³ååä»é¢ %(iface)sï¼%(err)sã"
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr "ç¡æ³ååä»é¢ %(iface)sãè«æª¢æ¥å¯¦ééçµçæ
ã"
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "é¤é¯å ±å %(name)s ä¸åå¨"
-
-msgid "Debug report tool not found in system"
-msgstr "å¨ç³»çµ±ä¸æ¾ä¸å°é¤é¯å ±åå·¥å
·"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "ç¡æ³å»ºç«é¤é¯å ±å %(name)sãè©³ç´°è³æï¼%(err)sã"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "ç¡æ³ç¢çé¤é¯å ±å %(name)sãè©³ç´°è³æï¼%(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_') "
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please use "
-"another one."
-msgstr "åçº '%(name)s' çç£å群çµå·²åå¨ãè«é¸æå¦ä¸åå稱以建ç«é輯å²ååã"
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Kimchi æªä½¿ç¨å²åé«ä¼ºæå¨ %(server)s"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' ä¸åå¨"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "åå²å %(name)s ä¸å卿¼ä¸»æ©ä¸"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr "ç¡æ³éé主æ©ï¼å çºæä¸äºèæ¬æ©å¨æ£å¨å·è¡ä¸"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "ç¡æ³å°ä¸»æ©éæ°éæ©ï¼å çºæä¸äºèæ¬æ©å¨æ£å¨å·è¡ä¸"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "æ¾ä¸å°ç¯é»è£ç½® '%(name)s'"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "æ²æå¥ä»¶æ¨ç¤ºçºè¦é²è¡æ´æ°"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "å¥ä»¶ %(name)s æªæ¨ç¤ºçºè¦é²è¡æ´æ°ã"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr "å徿¨ç¤ºçºè¦é²è¡æ´æ°çå¥ä»¶æç¼çé¯èª¤ãè©³ç´°è³æï¼%(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "æ²ææ¤ç³»çµ±çç¸å®¹å¥ä»¶ç®¡çç¨å¼ã"
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s ç¡æ"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "å²åé«é¡åç¡æã忝æ´çé¡åï¼'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "å»ºç«æ°çå²åè£ç½®æç¼çé¯èª¤ï¼%(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "æ´æ°å²åè£ç½®æç¼çé¯èª¤ï¼%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "ç§»é¤å²åè£ç½®æç¼çé¯èª¤ï¼%(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "æå®é¡ååè·¯å¾ä»¥æ°å¢èæ¬æ©å¨ç£ç¢"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "æå®è·¯å¾ä»¥æ´æ°èæ¬æ©å¨ç£ç¢"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "æå®é¡ååè·¯å¾ä»¥æ°å¢èæ¬æ©å¨ç£ç¢"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type %(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM å²å庫 ID å¿
é æ¯å
éä¸åå®åçå串ã"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "å²å庫 URL å¿
é æ¯ http://ãftp:// æ file:// URLã"
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr "å²å庫é
ç½®æ¯åå
¸ï¼å
¶ä¸å
嫿¼å²å庫é¡åå°æçç¹å®å¼ã"
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "DEB å²å庫çç¼è¡å¥ä»¶å¿
é æ¯å串"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "DEB å²å庫çå
ä»¶å¿
é 以é£åçå½¢å¼ååº"
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEB å²å庫çå
ä»¶å¿
é æ¯å串"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUM å²å庫å稱å¿
é æ¯å串ã"
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG 檢æ¥å¿
é æ¯å¸æå¼ã"
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG éé°å¿
é æ¯æå ASCII è£ç²æªæ¡ç URLã"
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "ç¡æ³æ´æ°å²å庫 %(repo_id)sã"
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "å²å庫 %(repo_id)s ä¸åå¨ã"
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "æªè½è¾¨è系統çå²å庫管çå·¥å
·ã"
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "å·²åç¨å²å庫 %(repo_id)sã"
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "å·²åç¨å²å庫 %(repo_id)sã"
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "ç¡æ³ç§»é¤å²å庫 %(repo_id)sã"
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "ç¡æ³å¯«å
¥å²å庫é
ç½®æª %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "æå®å²å庫ç¼è¡å¥ä»¶ä»¥å»ºç« DEB å²å庫ã"
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "ç¡æ³åç¨å²å庫 %(repo_id)sã"
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "ç¡æ³åç¨å²å庫 %(repo_id)sã"
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM å²å庫 ID å·²åå¨"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM å²å庫å稱å¿
é æ¯å串"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "ç¡æ³ååºå²å庫ãè©³ç´°è³æï¼'%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "ç¡æ³æ·åå²å庫è³è¨ãè©³ç´°è³æï¼'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "ç¡æ³æ°å¢å²å庫ãè©³ç´°è³æï¼'%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "ç¡æ³ç§»é¤å²å庫ãè©³ç´°è³æï¼'%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "é¯èª¤ç¢¼"
-
-msgid "REASON"
-msgstr "åå "
-
-msgid "STACK"
-msgstr "å ç"
-
-msgid "Go to Homepage"
-msgstr "è·³è³é¦é "
-
-msgid "Create a New Virtual Machine"
-msgstr "å»ºç«æ°çèæ¬æ©å¨"
-
-msgid "Virtual Machine Name"
-msgstr "èæ¬æ©å¨å稱"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr "ç¨ä¾èå¥èæ¬æ©å¨çå稱ã妿çç¥ï¼åææ ¹ææç¨çç¯æ¬é¸æå稱ã"
-
-msgid "Template"
-msgstr "ç¯æ¬"
-
-msgid "Please create a template first."
-msgstr "è«å
建ç«ç¯æ¬ã"
-
-msgid "Create a Template"
-msgstr "建ç«ç¯æ¬"
-
-msgid "Please choose a template."
-msgstr "è«é¸æç¯æ¬ã"
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "OS çæ¬"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "è¨æ¶é«"
-
-msgid "Create"
-msgstr "建ç«"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "åæ¶ "
-
-msgid "Edit Guest"
-msgstr "編輯客é«"
-
-msgid "General"
-msgstr "ä¸è¬"
-
-msgid "Storage"
-msgstr "å²åé«"
-
-msgid "Interface"
-msgstr "ä»é¢"
-
-msgid "Permission"
-msgstr "çæ¬"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "å稱"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "è¨æ¶é«"
-
-msgid "Icon"
-msgstr "å示"
-
-msgid "Device"
-msgstr "è£ç½®å稱"
-
-msgid "Path"
-msgstr "NFS è·¯å¾"
-
-msgid "Network"
-msgstr "網路"
-
-msgid "Type"
-msgstr "é¡å"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "å
¨é¨"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "便å"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "å²å"
-
-msgid "Replace"
-msgstr "å代"
-
-msgid "Detach"
-msgstr "åé¢"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "éå§"
-
-msgid "Reset"
-msgstr "éè¨"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "åä½"
-
-msgid "Connect"
-msgstr "飿¥"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "編輯"
-
-msgid "Shut Down"
-msgstr "éé"
-
-msgid "Delete"
-msgstr "åªé¤"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "ç£ç¢ I/O"
-
-msgid "Network I/O"
-msgstr "網路 I/O"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "æ¾ä¸å°å®¢é«ã"
-
-msgid "Add a Storage Device to VM"
-msgstr "å°å²åè£ç½®æ°å¢è³ VM"
-
-msgid "Device Type"
-msgstr "è£ç½®é¡å"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
-msgstr "è£ç½®é¡åãç®åå
æ¯æ´ \"cdrom\"ã"
-
-msgid "Storage Pool"
-msgstr "å²åå"
-
-msgid "Storage pool which volume located in"
-msgstr "å²ååè·¯å¾å¿
é æ¯å串"
-
-msgid "Storage Volume"
-msgstr "å²ååå稱"
-
-msgid "Storage volume to be attached"
-msgstr "å²åç£åå稱å¿
é æ¯å串"
-
-msgid "File Path"
-msgstr "æªæ¡è·¯å¾"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "CDROM ç ISO æªæ¡è·¯å¾å¨ä¼ºæå¨ä¸ã"
-
-msgid "Attach"
-msgstr "飿¥"
-
-msgid "Shut down"
-msgstr "éé"
-
-msgid "Restart"
-msgstr "éæ°åå"
-
-msgid "Basic Information"
-msgstr "åºæ¬è³è¨"
-
-msgid "OS Distro"
-msgstr "OS Distro"
-
-msgid "OS Code Name"
-msgstr "OS ç¨å¼ç¢¼å稱"
-
-msgid "Processor"
-msgstr "èçå¨"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "系統統è¨è³æ"
-
-msgid "Software Updates"
-msgstr "è»é«æ´æ°"
-
-msgid "Update Progress"
-msgstr "æ´æ°é²åº¦"
-
-msgid "Repositories"
-msgstr "å²å庫"
-
-msgid "Debug Reports"
-msgstr "é¤é¯å ±å"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr "æ¨è¼¸å
¥ç使ç¨è
å稱æå¯ç¢¼ä¸æ£ç¢ºãè«é試ã"
-
-msgid "This field is required."
-msgstr "æ¤æ¬ä½æ¯å¿
è¦çã"
-
-msgid "Log in"
-msgstr "ç»å
¥"
-
-msgid "Logging in..."
-msgstr "æ£å¨ç»å
¥..."
-
-msgid "Host"
-msgstr "主æ©"
-
-msgid "Guests"
-msgstr "客é«"
-
-msgid "Templates"
-msgstr "ç¯æ¬"
-
-msgid "Failed to get application configuration"
-msgstr "ç¡æ³å徿ç¨ç¨å¼é
ç½®"
-
-msgid "This is not a valid Linux path"
-msgstr "éæ¯ç¡æç Linux è·¯å¾"
-
-msgid "This is not a valid URL."
-msgstr "éæ¯ç¡æç URLã"
-
-msgid "No such data available."
-msgstr "æ²ææ¤é¡å¯ç¨è³æã"
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"ç¡æ³é£æ¥è³ä¸»æ©ç³»çµ±ãè«é©è主æ©ç³»çµ±æ¯å¦å·²ååï¼ä»¥åæ¨æ¯å¦å
·æèå®çé£ç·ãHTTP "
-"è¦æ±åæçº %1ã"
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "åªé¤ç¢ºèª"
-
-msgid "OK"
-msgstr "確å®"
-
-msgid "Confirm"
-msgstr "確èª"
-
-msgid "Warning"
-msgstr "è¦å"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "æ£å¨è¼å
¥..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "é試"
-
-msgid "Detailed message:"
-msgstr "詳細çè¨æ¯ï¼"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "éæ¯ç¡æç ISO æªæ¡ã"
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "å®å°éè¦å¾é·æéãè¦ç¹¼çºåï¼"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "æ¤åä½å°æ°¸ä¹
å°åªé¤ç¯æ¬ãè¦ç¹¼çºåï¼"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr "ç¡æ³éé系統ï¼å çºæå¹¾åèæ¬æ©å¨æ£å¨å·è¡ä¸ï¼"
-
-msgid "Max:"
-msgstr "ä¸éï¼"
-
-msgid "Utilization"
-msgstr "使ç¨ç"
-
-msgid "Available"
-msgstr "å¯ç¨"
-
-msgid "Read Rate"
-msgstr "è®åéç"
-
-msgid "Write Rate"
-msgstr "寫å
¥éç"
-
-msgid "Received"
-msgstr "å·²æ¥æ¶"
-
-msgid "Sent"
-msgstr "å·²å³é"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr "ééæéæ°åå主æ©å°å°è´æªå²åçå·¥ä½éºå¤±ãè¦ç¹¼çºéé/éæ°åååï¼"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr "å°ææ°¸ä¹
å°ç§»é¤å²å庫並ä¸ç¡æ³å復ãè¦ç¹¼çºåï¼"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "åºæ¬ URL"
-
-msgid "Is Mirror"
-msgstr "æ¯é¡æ "
-
-msgid "URL Args"
-msgstr "URL 弿¸"
-
-msgid "Enabled"
-msgstr "å·²åç¨"
-
-msgid "GPG Check"
-msgstr "GPG 檢æ¥"
-
-msgid "GPG Key"
-msgstr "GPG éé°"
-
-msgid "Add"
-msgstr "æ°å¢"
-
-msgid "Remove"
-msgstr "ç§»é¤"
-
-msgid "Enable"
-msgstr "åç¨"
-
-msgid "Disable"
-msgstr "åç¨"
-
-msgid "Package Name"
-msgstr "å¥ä»¶å稱"
-
-msgid "Version"
-msgstr "çæ¬"
-
-msgid "Architecture"
-msgstr "æ¶æ§"
-
-msgid "Repository"
-msgstr "å²å庫"
-
-msgid "Update All"
-msgstr "å
¨é¨æ´æ°"
-
-msgid "Updating..."
-msgstr "æ£å¨æ´æ°..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "ç¡æ³æ´æ°å¥ä»¶ã"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want "
-"to continue?"
-msgstr "å°ææ°¸ä¹
å°ç§»é¤é¤é¯å ±å並ä¸ç¡æ³å復ãè¦ç¹¼çºåï¼"
-
-msgid "Generated Time"
-msgstr "ç¢çæé"
-
-msgid "Generate"
-msgstr "ç¢ç"
-
-msgid "Generating..."
-msgstr "æ£å¨ç¢ç..."
-
-msgid "Rename"
-msgstr "éæ°å½å"
-
-msgid "Download"
-msgstr "ä¸è¼"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or "
-"hyphen ('-')."
-msgstr "å ±ååç¨±åªæè©²å
å«åæ¯ãæ¸åå/æé£åè ('-')ã"
-
-msgid "Pending..."
-msgstr "æ£å¨è¼å
¥..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr "æ¤åä½å°æåªé¤èæ¬æ©å¨åå
¶èæ¬ç£ç¢ãæ¤ä½æ¥ç¡æ³å¾©åãè¦ç¹¼çºåï¼"
-
-msgid "Power off Confirmation"
-msgstr "åªé¤ç¢ºèª"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "åªé¤ç¢ºèª"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "åªé¤ç¢ºèª"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "æ¤åä½å°æ°¸ä¹
å°åªé¤ç¯æ¬ãè¦ç¹¼çºåï¼"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"å°ææ°¸ä¹
å°å颿¤ CDROMï¼ä½æ¯æ¨å¯ä»¥å°å
¶éæ°é£æ¥ãè¦ç¹¼çºå颿¤ CDROM åï¼"
-
-msgid "Attaching..."
-msgstr "æ£å¨é£æ¥..."
-
-msgid "Replacing..."
-msgstr "æ£å¨å代..."
-
-msgid "Successfully attached!"
-msgstr "å·²é å©é£æ¥ï¼"
-
-msgid "Successfully replaced!"
-msgstr "å·²é å©å代ï¼"
-
-msgid "Successfully detached!"
-msgstr "å·²é å©åé¢ï¼"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to "
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN ID å¿
é 仿¼ 1 å 4094 ä¹éã"
-
-msgid "unavailable"
-msgstr "ç¡æ³ä½¿ç¨"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that "
-"depend on this network."
-msgstr "æ¤åä½å°æå²æ·ä¾è³´æ¼æ¤ç¶²è·¯ä¹ææèæ¬æ©å¨ç網路é£ç·åè½ã"
-
-msgid "Create a network"
-msgstr "建ç«ç¶²è·¯"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"æ¤å²åå䏿¯æçºæ§çãæ¤åä½ä¸æ¯æå°å
¶åæ¶ååï¼èæ¯æå°å
¶æ°¸ä¹
å°åªé¤ãè¦ç¹¼çº"
-"åï¼"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "æ¤åä½å°æ°¸ä¹
å°åªé¤å²ååãè¦ç¹¼çºåï¼"
-
-msgid "This storage pool is empty."
-msgstr "æ¤å²ååæ¯ç©ºçã"
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr "æ¤åä½ææ ¼å¼åæ¨çç£ç¢ï¼èæ¨å°æéºå¤±ç£ç¢ä¸çææè³æã確å®è¦ç¹¼çºåï¼"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI å
çºéé"
-
-msgid "No SCSI adapters found."
-msgstr "æ¾ä¸å° SCSI é
æ¥å¡ã"
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "å²ååå稱ä¸è½ç©ºç½ã"
-
-msgid "The storage pool path can not be blank."
-msgstr "å²ååè·¯å¾ä¸è½ç©ºç½ã"
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFS 伺æå¨è£è¼è·¯å¾ä¸è½ç©ºç½ã"
-
-msgid "Invalid NFS mount path."
-msgstr "NFS è£è¼è·¯å¾ç¡æã"
-
-msgid "No logical device selected."
-msgstr "æªé¸åé輯è£ç½®ã"
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSI ç®æ¨ä¸è½ç©ºç½ã"
-
-msgid "Server name can not be blank."
-msgstr "伺æå¨å稱ä¸è½ç©ºç½ã"
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "æ£å¨å°æ¾å¯ç¨çåå²å ..."
-
-msgid "No available partitions found."
-msgstr "æ¾ä¸å°å¯ç¨çåå²åã"
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"æ¤å²åå䏿¯æçºæ§çãæ¤åä½ä¸æ¯æå°å
¶åæ¶ååï¼èæ¯æå°å
¶æ°¸ä¹
å°åªé¤ãè¦ç¹¼çº"
-"åï¼"
-
-msgid "Unable to retrieve partitions information."
-msgstr "ç¡æ³æ·åå²å庫è³è¨ãè©³ç´°è³æï¼'%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "å²ååå稱ä¸è½ç©ºç½ã"
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "網路å稱"
-
-msgid "State"
-msgstr "çæ
"
-
-msgid "Network Type"
-msgstr "網路é¡å"
-
-msgid "Address Space"
-msgstr "ä½å空é"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "å²åååç¨±ç¡æãå®ä¸æè©²å
å« '/'ã"
-
-msgid "Isolated: no external network connection"
-msgstr "å·²éé¢ï¼æ²æå¯¦é«ç¶²è·¯é£ç·"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NATï¼å
éåºå 實é«ç¶²è·¯é£ç·"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "å·²æ©æ¥ï¼èæ¬æ©å¨ç´æ¥å·²é£æ¥è³å¯¦é«ç¶²è·¯"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "ç®çå°ï¼"
-
-msgid "Enable VLAN"
-msgstr "åç¨ VLANï¼"
-
-msgid "VLAN ID"
-msgstr "VLAN IDï¼"
-
-msgid "Stop"
-msgstr "忢"
-
-msgid "Generate a New Debug Report"
-msgstr "ç¢çæ°çé¤é¯å ±å"
-
-msgid "Report Name"
-msgstr "å ±åå稱"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore (\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"ç¨ä¾èå¥å ±åçå稱ã妿çç¥ï¼åææ ¹æç¾è¡æé鏿å稱ãå稱å¯ä»¥å
å«ï¼åæ¯ã"
-"æ¸ååé£åè (\"-\")ã"
-
-msgid "Rename a Debug Report"
-msgstr "ç¢çæ°çé¤é¯å ±å"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"ç¨ä¾èå¥å ±åçå稱ã妿çç¥ï¼åææ ¹æç¾è¡æé鏿å稱ãå稱å¯ä»¥å
å«ï¼åæ¯ã"
-"æ¸ååé£åè (\"-\")ã"
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "æ°å¢å²å庫"
-
-msgid "Identifier"
-msgstr "ID"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "å®åï¼å²å庫çå¯ä¸ IDã"
-
-msgid "Textual name for the repository."
-msgstr "å²å庫çæåå稱ã"
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "å¿
è¦æ¬ä½"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "å²å庫ç URLã忝æ´çéè¨åå®å
æ¬ httpãftp å fileã"
-
-msgid "Repository is a mirror"
-msgstr "å²å庫æ¯é¡æ ã"
-
-msgid "Distribution"
-msgstr "ç¼è¡å¥ä»¶"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEB å²å庫çç¼è¡å¥ä»¶ã"
-
-msgid "Components"
-msgstr "å
ä»¶"
-
-msgid "List of components in DEB repository."
-msgstr "DEB å²å庫ä¸çå
ä»¶æ¸
å®ã"
-
-msgid "Edit Repository"
-msgstr "編輯å²å庫"
-
-msgid "Mirror List URL"
-msgstr "顿 æ¸
å® URL"
-
-msgid "Yes"
-msgstr "æ¯"
-
-msgid "No"
-msgstr "å¦"
-
-msgid "Capacity"
-msgstr "容é"
-
-msgid "Allocated"
-msgstr "å·²é
ç½®"
-
-msgid "Location"
-msgstr "ä½ç½®"
-
-msgid "Device path"
-msgstr "è£ç½®è·¯å¾"
-
-msgid "active"
-msgstr "ä½ç¨ä¸"
-
-msgid "inactive"
-msgstr "éä½ç¨ä¸"
-
-msgid "Deactivate"
-msgstr "åæ¶åå"
-
-msgid "Activate"
-msgstr "åå"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "åæ¶å®ç¾©"
-
-msgid "Format"
-msgstr "æ ¼å¼ï¼"
-
-msgid "Allocation"
-msgstr "é
ç½®ï¼"
-
-msgid "Define a New Storage Pool"
-msgstr "å®ç¾©æ°çå²åå"
-
-msgid "Storage Pool Name"
-msgstr "å²ååå稱"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "ç¨ä¾èå¥å²ååçå稱ï¼ä¸æè©²æ¯ç©ºçã"
-
-msgid "Storage Pool Type"
-msgstr "å²ååé¡å"
-
-msgid "Storage Path"
-msgstr "å²åé«è·¯å¾"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr "å²ååçè·¯å¾ãæ¯ä¸åå²ååé½å¿
é æä¸åå¯ä¸çè·¯å¾ã"
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr "Kimchi å°å試建ç«è©²ç®éï¼ç¶è©²ç®éå°ä¸å卿¼ç³»çµ±ä¸æï¼ã"
-
-msgid "NFS Server IP"
-msgstr "NFS 伺æå¨ IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr "NFS 伺æå¨ IP æä¸»æ©å稱ãå¯ä»¥ç´æ¥è¼¸å
¥ï¼ä¹å¯ä»¥å¾æ·ç¨ä¸é¸æã"
-
-msgid "NFS Path"
-msgstr "NFS è·¯å¾"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFS 伺æå¨ä¸ NFS å¯åºçè·¯å¾ã"
-
-msgid "iSCSI Server"
-msgstr "iSCSI 伺æå¨"
-
-msgid "Server"
-msgstr "伺æå¨"
-
-msgid "Port"
-msgstr "å "
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSI 伺æå¨ IP æä¸»æ©å稱ãå®ä¸æè©²æ¯ç©ºçã"
-
-msgid "Target"
-msgstr "ç®æ¨"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSI 伺æå¨ä¸ç iSCSI ç®æ¨"
-
-msgid "Add iSCSI Authentication"
-msgstr "æ°å¢ iSCSI éå¥"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI éå¥"
-
-msgid "User Name"
-msgstr "使ç¨è
å稱"
-
-msgid "Password"
-msgstr "å¯ç¢¼"
-
-msgid "SCSI Adapter"
-msgstr "SCSI é
æ¥å¡"
-
-msgid "Please, wait..."
-msgstr "è«ç¨å..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "æ°å¢ç¯æ¬"
-
-msgid "Where is the source media for this template? "
-msgstr "æ¤ç¯æ¬ç便ºåªé«ä½æ¼ä½èï¼"
-
-msgid "Local ISO Image"
-msgstr "æ¬ç«¯ ISO æ åæª"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "é 端 ISO æ åæª"
-
-msgid "Search ISOs"
-msgstr "æå° ISO"
-
-msgid "The following ISOs are available:"
-msgstr "ä¸å ISO å¯ç¨ï¼"
-
-msgid "OS: "
-msgstr "OSï¼"
-
-msgid "Version: "
-msgstr "çæ¬ï¼"
-
-msgid "Size: "
-msgstr "大å°ï¼"
-
-msgid "Search more ISOs"
-msgstr "æå°æ´å¤ ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "å¾æé¸ ISO 建ç«ç¯æ¬"
-
-msgid "I want to use a specific ISO file"
-msgstr "ææ³ä½¿ç¨ç¹å®ç ISO æªæ¡"
-
-msgid "Loading default remote ISOs ..."
-msgstr "æ£å¨è¼å
¥é è¨é 端 ISO ..."
-
-msgid "Arch: "
-msgstr "æ¶æ§ï¼"
-
-msgid "I want to use a custom URL"
-msgstr "ææ³ä½¿ç¨èªè¨ URL"
-
-msgid "Edit Template"
-msgstr "ç·¨è¼¯ç¯æ¬"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "åå½¢å¡"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU æ¸ç®"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "æ¾ä¸å°ç¯æ¬ã"
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "ä¸å®¹è¨±éå° %(resource)s å·è¡åªé¤"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s æªå¯¦ä½æ´æ°æ¹æ³"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "ä¸å®¹è¨±éå° %(resource)s å·è¡å»ºç«"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "ç¡æ³åæ JSON è¦æ±"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "æ¤ API å
æ¯æ´ JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "æªå¨æ¨¡åç©ä»¶ä¸èµ·å§è³æå²å庫ã"
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³éå§å·¥ä½ï¼%(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
-#~ msgstr "使ç¨è
'%(username)s' çéå¥å¤±æã[é¯èª¤ç¢¼ï¼%(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "æ¨æªç²ææ¬ä¾åå Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "æå® %(item)s 以ç»å
¥ Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "å¨è³æå²ååº«ä¸æ¾ä¸å° %(item)s"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
-#~ msgstr "å·è¡æä»¤ '%(cmd)s' %(seconds)s ç§ä¹å¾é¾æ"
-
-#~ msgid "Help"
-#~ msgstr "說æ"
-
-#~ msgid "About"
-#~ msgstr "ç¸é"
-
-#~ msgid "Log out"
-#~ msgstr "ç»åº"
-
-#~ msgid "Version:"
-#~ msgstr "çæ¬ï¼"
diff --git a/plugins/kimchi/repositories.py b/plugins/kimchi/repositories.py
deleted file mode 100644
index 9caabc4..0000000
--- a/plugins/kimchi/repositories.py
+++ /dev/null
@@ -1,529 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import copy
-import os
-import time
-import urlparse
-from ConfigParser import ConfigParser
-
-from wok.basemodel import Singleton
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import OperationFailed, NotFoundError, MissingParameter
-from wok.utils import validate_repo_url
-
-from config import kimchiLock
-from yumparser import get_yum_repositories, write_repo_to_file
-
-
-class Repositories(object):
- __metaclass__ = Singleton
-
- """
- Class to represent and operate with repositories information.
- """
- def __init__(self):
- try:
- __import__('yum')
- self._pkg_mnger = YumRepo()
- except ImportError:
- try:
- __import__('apt_pkg')
- self._pkg_mnger = AptRepo()
- except ImportError:
- raise InvalidOperation('KCHREPOS0014E')
-
- def addRepository(self, params):
- """
- Add and enable a new repository
- """
- config = params.get('config', {})
- extra_keys = list(
- set(config.keys()).difference(set(self._pkg_mnger.CONFIG_ENTRY)))
- if len(extra_keys) > 0:
- raise InvalidParameter("KCHREPOS0028E",
- {'items': ",".join(extra_keys)})
-
- return self._pkg_mnger.addRepo(params)
-
- def getRepositories(self):
- """
- Return a dictionary with all Kimchi's repositories. Each element uses
- the format {<repo_id>: {repo}}, where repo is a dictionary in the
- repositories.Repositories() format.
- """
- return self._pkg_mnger.getRepositoriesList()
-
- def getRepository(self, repo_id):
- """
- Return a dictionary with all info from a given repository ID.
- """
- info = self._pkg_mnger.getRepo(repo_id)
- info['repo_id'] = repo_id
- return info
-
- def enableRepository(self, repo_id):
- """
- Enable a repository.
- """
- return self._pkg_mnger.toggleRepo(repo_id, True)
-
- def disableRepository(self, repo_id):
- """
- Disable a given repository.
- """
- return self._pkg_mnger.toggleRepo(repo_id, False)
-
- def updateRepository(self, repo_id, params):
- """
- Update the information of a given repository.
- The input is the repo_id of the repository to be updated and a dict
- with the information to be updated.
- """
- return self._pkg_mnger.updateRepo(repo_id, params)
-
- def removeRepository(self, repo_id):
- """
- Remove a given repository
- """
- return self._pkg_mnger.removeRepo(repo_id)
-
-
-class YumRepo(object):
- """
- Class to represent and operate with YUM repositories.
- It's loaded only on those systems listed at YUM_DISTROS and loads necessary
- modules in runtime.
- """
- TYPE = 'yum'
- DEFAULT_CONF_DIR = "/etc/yum.repos.d"
- CONFIG_ENTRY = ('repo_name', 'mirrorlist', 'metalink')
-
- def __init__(self):
- self._confdir = self.DEFAULT_CONF_DIR
-
- def _get_repos(self, errcode):
- try:
- kimchiLock.acquire()
- repos = get_yum_repositories()
- except Exception, e:
- kimchiLock.release()
- raise OperationFailed(errcode, {'err': str(e)})
- finally:
- kimchiLock.release()
-
- return repos
-
- def getRepositoriesList(self):
- """
- Return a list of repositories IDs
- """
- repos = self._get_repos('KCHREPOS0024E')
- return repos.keys()
-
- def getRepo(self, repo_id):
- """
- Return a dictionary in the repositories.Repositories() of the given
- repository ID format with the information of a YumRepository object.
- """
- repos = self._get_repos('KCHREPOS0025E')
-
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
-
- info = {}
- info['enabled'] = entry.enabled
- info['baseurl'] = entry.baseurl or ''
- info['config'] = {}
- info['config']['repo_name'] = entry.name or ''
- info['config']['gpgcheck'] = entry.gpgcheck
- info['config']['gpgkey'] = entry.gpgkey or ''
- info['config']['mirrorlist'] = entry.mirrorlist or ''
- info['config']['metalink'] = entry.metalink or ''
- return info
-
- def addRepo(self, params):
- """
- Add a given repository to YumBase
- """
- # At least one base url, or one mirror, must be given.
- baseurl = params.get('baseurl', '')
-
- config = params.get('config', {})
- mirrorlist = config.get('mirrorlist', '')
- metalink = config.get('metalink', '')
- if not baseurl and not mirrorlist and not metalink:
- raise MissingParameter("KCHREPOS0013E")
-
- if baseurl:
- validate_repo_url(baseurl)
-
- if mirrorlist:
- validate_repo_url(mirrorlist)
-
- if metalink:
- validate_repo_url(metalink)
-
- if mirrorlist and metalink:
- raise InvalidOperation('KCHREPOS0030E')
-
- repo_id = params.get('repo_id', None)
- if repo_id is None:
- repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
-
- repos = self._get_repos('KCHREPOS0026E')
- if repo_id in repos.keys():
- raise InvalidOperation("KCHREPOS0022E", {'repo_id': repo_id})
-
- repo_name = config.get('repo_name', repo_id)
- repo = {'baseurl': baseurl, 'mirrorlist': mirrorlist,
- 'name': repo_name, 'gpgcheck': 1,
- 'gpgkey': [], 'enabled': 1, 'metalink': metalink}
-
- # write a repo file in the system with repo{} information.
- parser = ConfigParser()
- parser.add_section(repo_id)
-
- for key, value in repo.iteritems():
- if value:
- parser.set(repo_id, key, value)
-
- repofile = os.path.join(self._confdir, repo_id + '.repo')
- try:
- with open(repofile, 'w') as fd:
- parser.write(fd)
- except:
- raise OperationFailed("KCHREPOS0018E",
- {'repo_file': repofile})
-
- return repo_id
-
- def toggleRepo(self, repo_id, enable):
- repos = self._get_repos('KCHREPOS0011E')
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
- if enable and entry.enabled:
- raise InvalidOperation("KCHREPOS0015E", {'repo_id': repo_id})
-
- if not enable and not entry.enabled:
- raise InvalidOperation("KCHREPOS0016E", {'repo_id': repo_id})
-
- kimchiLock.acquire()
- try:
- if enable:
- entry.enable()
- else:
- entry.disable()
-
- write_repo_to_file(entry)
- except:
- if enable:
- raise OperationFailed("KCHREPOS0020E", {'repo_id': repo_id})
-
- raise OperationFailed("KCHREPOS0021E", {'repo_id': repo_id})
- finally:
- kimchiLock.release()
-
- return repo_id
-
- def updateRepo(self, repo_id, params):
- """
- Update a given repository in repositories.Repositories() format
- """
- repos = self._get_repos('KCHREPOS0011E')
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
-
- baseurl = params.get('baseurl', None)
- config = params.get('config', {})
- mirrorlist = config.get('mirrorlist', None)
- metalink = config.get('metalink', None)
-
- if baseurl is not None and len(baseurl.strip()) == 0:
- baseurl = None
-
- if mirrorlist is not None and len(mirrorlist.strip()) == 0:
- mirrorlist = None
-
- if metalink is not None and len(metalink.strip()) == 0:
- metalink = None
-
- if baseurl is None and mirrorlist is None and metalink is None:
- raise MissingParameter("KCHREPOS0013E")
-
- if baseurl is not None:
- validate_repo_url(baseurl)
- entry.baseurl = baseurl
-
- if mirrorlist is not None:
- validate_repo_url(mirrorlist)
- entry.mirrorlist = mirrorlist
-
- if metalink is not None:
- validate_repo_url(metalink)
- entry.metalink = metalink
-
- if mirrorlist and metalink:
- raise InvalidOperation('KCHREPOS0030E')
-
- entry.id = params.get('repo_id', repo_id)
- entry.name = config.get('repo_name', entry.name)
- entry.gpgcheck = config.get('gpgcheck', entry.gpgcheck)
- entry.gpgkey = config.get('gpgkey', entry.gpgkey)
- kimchiLock.acquire()
- write_repo_to_file(entry)
- kimchiLock.release()
- return repo_id
-
- def removeRepo(self, repo_id):
- """
- Remove a given repository
- """
- repos = self._get_repos('KCHREPOS0027E')
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
- parser = ConfigParser()
- with open(entry.repofile) as fd:
- parser.readfp(fd)
-
- if len(parser.sections()) == 1:
- os.remove(entry.repofile)
- return
-
- parser.remove_section(repo_id)
- with open(entry.repofile, "w") as fd:
- parser.write(fd)
-
-
-class AptRepo(object):
- """
- Class to represent and operate with YUM repositories.
- It's loaded only on those systems listed at YUM_DISTROS and loads necessary
- modules in runtime.
- """
- TYPE = 'deb'
- KIMCHI_LIST = "kimchi-source.list"
- CONFIG_ENTRY = ('dist', 'comps')
-
- def __init__(self):
- getattr(__import__('apt_pkg'), 'init_config')()
- getattr(__import__('apt_pkg'), 'init_system')()
- config = getattr(__import__('apt_pkg'), 'config')
- self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
- module = __import__('aptsources.sourceslist', globals(), locals(),
- ['SourcesList'], -1)
-
- self._sourceparts_path = '/%s%s' % (
- config.get('Dir::Etc'), config.get('Dir::Etc::sourceparts'))
- self._sourceslist = getattr(module, 'SourcesList')
- self.filename = os.path.join(self._sourceparts_path, self.KIMCHI_LIST)
- if not os.path.exists(self.filename):
- with open(self.filename, 'w') as fd:
- fd.write("# This file is managed by Kimchi and it must not "
- "be modified manually\n")
-
- def _get_repos(self):
- try:
- with self.pkg_lock():
- repos = self._sourceslist()
- repos.refresh()
- except Exception, e:
- kimchiLock.release()
- raise OperationFailed('KCHREPOS0025E', {'err': e.message})
-
- return repos
-
- def _get_repo_id(self, repo):
- data = urlparse.urlparse(repo.uri)
- name = data.hostname or data.path
- return '%s-%s-%s' % (name, repo.dist, "-".join(repo.comps))
-
- def _get_source_entry(self, repo_id):
- kimchiLock.acquire()
- repos = self._get_repos()
- kimchiLock.release()
-
- for r in repos:
- # Ignore deb-src repositories
- if r.type != 'deb':
- continue
-
- if self._get_repo_id(r) != repo_id:
- continue
-
- return r
-
- return None
-
- def getRepositoriesList(self):
- """
- Return a list of repositories IDs
-
- APT repositories there aren't the concept about repository ID, so for
- internal control, the repository ID will be built as described in
- _get_repo_id()
- """
- kimchiLock.acquire()
- repos = self._get_repos()
- kimchiLock.release()
-
- res = []
- for r in repos:
- # Ignore deb-src repositories
- if r.type != 'deb':
- continue
-
- res.append(self._get_repo_id(r))
-
- return res
-
- def getRepo(self, repo_id):
- """
- Return a dictionary in the repositories.Repositories() format of the
- given repository ID with the information of a SourceEntry object.
- """
- r = self._get_source_entry(repo_id)
- if r is None:
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- info = {'enabled': not r.disabled,
- 'baseurl': r.uri,
- 'config': {'dist': r.dist,
- 'comps': r.comps}}
- return info
-
- def addRepo(self, params):
- """
- Add a new APT repository based on <params>
- """
- # To create a APT repository the dist is a required parameter
- # (in addition to baseurl, verified on controller through API.json)
- config = params.get('config', None)
- if config is None:
- raise MissingParameter("KCHREPOS0019E")
-
- if 'dist' not in config.keys():
- raise MissingParameter("KCHREPOS0019E")
-
- uri = params['baseurl']
- dist = config['dist']
- comps = config.get('comps', [])
-
- validate_repo_url(uri)
-
- kimchiLock.acquire()
- try:
- repos = self._get_repos()
- source_entry = repos.add('deb', uri, dist, comps,
- file=self.filename)
- with self.pkg_lock():
- repos.save()
- except Exception as e:
- kimchiLock.release()
- raise OperationFailed("KCHREPOS0026E", {'err': e.message})
- kimchiLock.release()
- return self._get_repo_id(source_entry)
-
- def toggleRepo(self, repo_id, enable):
- """
- Enable a given repository
- """
- r = self._get_source_entry(repo_id)
- if r is None:
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- if enable and not r.disabled:
- raise InvalidOperation("KCHREPOS0015E", {'repo_id': repo_id})
-
- if not enable and r.disabled:
- raise InvalidOperation("KCHREPOS0016E", {'repo_id': repo_id})
-
- if enable:
- line = 'deb'
- else:
- line = '#deb'
-
- kimchiLock.acquire()
- try:
- repos = self._get_repos()
- with self.pkg_lock():
- repos.remove(r)
- repos.add(line, r.uri, r.dist, r.comps, file=self.filename)
- repos.save()
- except:
- kimchiLock.release()
- if enable:
- raise OperationFailed("KCHREPOS0020E", {'repo_id': repo_id})
-
- raise OperationFailed("KCHREPOS0021E", {'repo_id': repo_id})
- finally:
- kimchiLock.release()
-
- return repo_id
-
- def updateRepo(self, repo_id, params):
- """
- Update a given repository in repositories.Repositories() format
- """
- old_info = self.getRepo(repo_id)
- updated_info = copy.deepcopy(old_info)
- updated_info['baseurl'] = params.get(
- 'baseurl', updated_info['baseurl'])
-
- if 'config' in params.keys():
- config = params['config']
- updated_info['config']['dist'] = config.get(
- 'dist', old_info['config']['dist'])
- updated_info['config']['comps'] = config.get(
- 'comps', old_info['config']['comps'])
-
- self.removeRepo(repo_id)
- try:
- return self.addRepo(updated_info)
- except:
- self.addRepo(old_info)
- raise
-
- def removeRepo(self, repo_id):
- """
- Remove a given repository
- """
- r = self._get_source_entry(repo_id)
- if r is None:
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- kimchiLock.acquire()
- try:
- repos = self._get_repos()
- with self.pkg_lock():
- repos.remove(r)
- repos.save()
- except:
- kimchiLock.release()
- raise OperationFailed("KCHREPOS0017E", {'repo_id': repo_id})
- finally:
- kimchiLock.release()
diff --git a/plugins/kimchi/root.py b/plugins/kimchi/root.py
deleted file mode 100644
index 1e2bfc7..0000000
--- a/plugins/kimchi/root.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import cherrypy
-
-from wok.i18n import messages
-from wok.root import WokRoot
-
-import config
-import mockmodel
-import vnc
-from control import sub_nodes
-from model import model as kimchiModel
-
-
-class KimchiRoot(WokRoot):
- def __init__(self, wok_options):
- if hasattr(wok_options, "model"):
- self.model = wok_options.model
- elif wok_options.test:
- self.model = mockmodel.MockModel()
- else:
- self.model = kimchiModel.Model()
-
- dev_env = wok_options.environment != 'production'
- super(KimchiRoot, self).__init__(self.model, dev_env)
-
- for ident, node in sub_nodes.items():
- setattr(self, ident, node(self.model))
-
- if isinstance(self.model, kimchiModel.Model):
- vnc_ws_proxy = vnc.new_ws_proxy()
- cherrypy.engine.subscribe('exit', vnc_ws_proxy.terminate)
-
- self.api_schema = json.load(open(os.path.join(os.path.dirname(
- os.path.abspath(__file__)), 'API.json')))
- self.paths = config.kimchiPaths
- self.domain = 'kimchi'
- self.messages = messages
-
- make_dirs = [
- os.path.abspath(config.get_distros_store()),
- os.path.abspath(config.get_debugreports_path()),
- os.path.abspath(config.get_screenshot_path())
- ]
- for directory in make_dirs:
- if not os.path.isdir(directory):
- os.makedirs(directory)
-
- def get_custom_conf(self):
- return config.KimchiConfig()
diff --git a/plugins/kimchi/scan.py b/plugins/kimchi/scan.py
deleted file mode 100644
index b475c46..0000000
--- a/plugins/kimchi/scan.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import glob
-import hashlib
-import os.path
-import shutil
-import tempfile
-import time
-
-from wok.utils import wok_log
-
-from isoinfo import IsoImage, probe_iso
-
-
-SCAN_IGNORE = ['/tmp/kimchi-scan-*']
-
-
-class Scanner(object):
- SCAN_TTL = 300
-
- def __init__(self, record_clean_cb):
- self.clean_cb = record_clean_cb
-
- def delete(self):
- self.clean_stale(-1)
-
- def clean_stale(self, window=SCAN_TTL):
- """
- Clear scan pools generated before time window,
- Clear all scan pools if window is -1.
- """
- try:
- now = time.time()
- clean_list = glob.glob("/tmp/kimchi-scan-*")
- for d in clean_list:
- transient_pool = \
- os.path.basename(d).replace('kimchi-scan-', '')[0: -6]
- if now - os.path.getmtime(d) > window:
- shutil.rmtree(d)
- self.clean_cb(transient_pool)
- except OSError as e:
- msg = "Exception %s occured when cleaning stale pool, ignore"
- wok_log.debug(msg % e.message)
-
- def scan_dir_prepare(self, name):
- # clean stale scan storage pools
- self.clean_stale()
- return tempfile.mkdtemp(prefix='kimchi-scan-' + name, dir='/tmp')
-
- def start_scan(self, cb, params):
- def updater(iso_info):
- iso_name = os.path.basename(iso_info['path'])[:-3]
-
- duplicates = "%s/%s*" % (params['pool_path'], iso_name)
- for f in glob.glob(duplicates):
- iso_img = IsoImage(f)
- if (iso_info['distro'], iso_info['version']) == \
- iso_img.probe():
- return
-
- iso_path = iso_name + hashlib.md5(iso_info['path']).hexdigest() + \
- '.iso'
- link_name = os.path.join(params['pool_path'],
- os.path.basename(iso_path))
- os.symlink(iso_info['path'], link_name)
-
- ignore_paths = params.get('ignore_list', [])
- scan_params = dict(path=params['scan_path'], updater=updater,
- ignore_list=ignore_paths + SCAN_IGNORE)
- probe_iso(None, scan_params)
- cb('', True)
diff --git a/plugins/kimchi/screenshot.py b/plugins/kimchi/screenshot.py
deleted file mode 100644
index ffe5a1a..0000000
--- a/plugins/kimchi/screenshot.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import glob
-import os
-import signal
-import tempfile
-import time
-import uuid
-
-try:
- from PIL import Image
-except ImportError:
- import Image
-
-
-from wok.utils import wok_log
-
-import config
-
-
-(fd, pipe) = tempfile.mkstemp()
-stream_test_result = None
-
-
-class VMScreenshot(object):
- OUTDATED_SECS = 5
- THUMBNAIL_SIZE = (256, 256)
- LIVE_WINDOW = 60
- MAX_STREAM_ATTEMPTS = 10
-
- def __init__(self, args):
- self.vm_uuid = args['uuid']
- args.setdefault('thumbnail',
- os.path.join(config.get_screenshot_path(),
- '%s-%s.png' %
- (self.vm_uuid, str(uuid.uuid4()))))
- self.info = args
-
- @staticmethod
- def get_stream_test_result():
- return stream_test_result
-
- def lookup(self):
- now = time.time()
- try:
- last_update = os.path.getmtime(self.info['thumbnail'])
- except OSError:
- last_update = 0
-
- if now - last_update > self.OUTDATED_SECS:
- self._clean_extra(self.LIVE_WINDOW)
- self._generate_thumbnail()
- return 'plugins/kimchi/data/screenshots/%s' %\
- os.path.basename(self.info['thumbnail'])
-
- def _clean_extra(self, window=-1):
- """
- Clear screenshots before time specified by window,
- Clear all screenshots if window is -1.
- """
- try:
- now = time.time()
- clear_list = glob.glob("%s/%s-*.png" %
- (config.get_screenshot_path(),
- self.vm_uuid))
- for f in clear_list:
- if now - os.path.getmtime(f) > window:
- os.unlink(f)
- except OSError:
- pass
-
- def delete(self):
- return self._clean_extra()
-
- def _generate_scratch(self, thumbnail):
- """
- Generate screenshot of given vm.
- Override me in child class.
- """
- pass
-
- def _create_black_image(self, thumbnail):
- image = Image.new("RGB", self.THUMBNAIL_SIZE, 'black')
- image.save(thumbnail)
-
- def _watch_stream_creation(self, thumbnail):
- """
- This is a verification test for libvirt stream functionality.
-
- It is necessary to avoid the server hangs while creating the screenshot
- image using libvirt stream API.
-
- This problem was found in libvirt 0.9.6 for SLES11 SP2.
-
- This test consists in running the screeshot creation with a timeout.
- If timeout occurs, the libvirt is taking too much time to create the
- screenshot image and the stream must be disabled it if happens
- successively (to avoid blocking server requests).
- """
- pid = os.fork()
- if pid == 0:
- try:
- self._generate_scratch(thumbnail)
- os._exit(0)
- except:
- os._exit(1)
- else:
- counter = 0
- ret = os.waitpid(pid, os.WNOHANG)
- while ret == (0, 0) and counter < 3:
- counter += 1
- time.sleep(1)
- ret = os.waitpid(pid, os.WNOHANG)
-
- fd = open(pipe, "a")
- if ret != (pid, 0):
- fd.write("-")
- if ret[0] != pid:
- os.kill(int(pid), signal.SIGKILL)
- os.waitpid(pid, 0)
- else:
- fd.write("+")
- fd.close()
-
- def _get_test_result(self):
- if not os.path.exists(pipe):
- return
-
- fd = open(pipe, "r")
- data = fd.read()
- fd.close()
-
- if len(data) >= self.MAX_STREAM_ATTEMPTS or bool('+' in data):
- global stream_test_result
- stream_test_result = bool('+' in data)
- os.remove(pipe)
-
- def _generate_thumbnail(self):
- thumbnail = os.path.join(config.get_screenshot_path(), '%s-%s.png' %
- (self.vm_uuid, str(uuid.uuid4())))
-
- self._get_test_result()
- if stream_test_result is None:
- self._watch_stream_creation(thumbnail)
- elif stream_test_result:
- try:
- self._generate_scratch(thumbnail)
- except:
- wok_log.error("screenshot_creation: Unable to create "
- "screenshot image %s." % thumbnail)
- else:
- self._create_black_image(thumbnail)
-
- if os.path.getsize(thumbnail) == 0:
- self._create_black_image(thumbnail)
- else:
- im = Image.open(thumbnail)
- try:
- # Prevent Image lib from lazy load,
- # work around pic truncate validation in thumbnail generation
- im.thumbnail(self.THUMBNAIL_SIZE)
- except Exception as e:
- wok_log.warning("Image load with warning: %s." % e)
- im.save(thumbnail, "PNG")
-
- self.info['thumbnail'] = thumbnail
diff --git a/plugins/kimchi/swupdate.py b/plugins/kimchi/swupdate.py
deleted file mode 100644
index 84b927f..0000000
--- a/plugins/kimchi/swupdate.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import subprocess
-import time
-
-from wok.basemodel import Singleton
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import run_command, wok_log
-
-from config import kimchiLock
-from yumparser import get_yum_packages_list_update
-
-
-class SoftwareUpdate(object):
- __metaclass__ = Singleton
-
- """
- Class to represent and operate with OS software update.
- """
- def __init__(self):
- # This stores all packages to be updated for Kimchi perspective. It's a
- # dictionary of dictionaries, in the format {'package_name': package},
- # where:
- # package = {'package_name': <string>, 'version': <string>,
- # 'arch': <string>, 'repository': <string>
- # }
- self._packages = {}
-
- # This stores the number of packages to update
- self._num2update = 0
-
- # Get the distro of host machine and creates an object related to
- # correct package management system
- try:
- __import__('yum')
- wok_log.info("Loading YumUpdate features.")
- self._pkg_mnger = YumUpdate()
- except ImportError:
- try:
- __import__('apt')
- wok_log.info("Loading AptUpdate features.")
- self._pkg_mnger = AptUpdate()
- except ImportError:
- zypper_help = ["zypper", "--help"]
- (stdout, stderr, returncode) = run_command(zypper_help)
- if returncode == 0:
- wok_log.info("Loading ZypperUpdate features.")
- self._pkg_mnger = ZypperUpdate()
- else:
- raise Exception("There is no compatible package manager "
- "for this system.")
-
- def _scanUpdates(self):
- """
- Update self._packages with packages to be updated.
- """
- self._packages = {}
- self._num2update = 0
-
- # Call system pkg_mnger to get the packages as list of dictionaries.
- for pkg in self._pkg_mnger.getPackagesList():
-
- # Check if already exist a package in self._packages
- pkg_id = pkg.get('package_name')
- if pkg_id in self._packages.keys():
- # package already listed to update. do nothing
- continue
-
- # Update the self._packages and self._num2update
- self._packages[pkg_id] = pkg
- self._num2update = self._num2update + 1
-
- def getUpdates(self):
- """
- Return the self._packages.
- """
- self._scanUpdates()
- return self._packages
-
- def getUpdate(self, name):
- """
- Return a dictionary with all info from a given package name.
- """
- if name not in self._packages.keys():
- raise NotFoundError('KCHPKGUPD0002E', {'name': name})
-
- return self._packages[name]
-
- def getNumOfUpdates(self):
- """
- Return the number of packages to be updated.
- """
- self._scanUpdates()
- return self._num2update
-
- def doUpdate(self, cb, params):
- """
- Execute the update
- """
- # reset messages
- cb('')
-
- cmd = self._pkg_mnger.update_cmd
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- msgs = []
- while proc.poll() is None:
- msgs.append(proc.stdout.readline())
- cb(''.join(msgs))
- time.sleep(0.5)
-
- # read the final output lines
- msgs.extend(proc.stdout.readlines())
-
- retcode = proc.poll()
- if retcode == 0:
- return cb(''.join(msgs), True)
-
- msgs.extend(proc.stderr.readlines())
- return cb(''.join(msgs), False)
-
-
-class YumUpdate(object):
- """
- Class to represent and operate with YUM software update system.
- It's loaded only on those systems listed at YUM_DISTROS and loads necessary
- modules in runtime.
- """
- def __init__(self):
- self._pkgs = {}
- self.update_cmd = ["yum", "-y", "update"]
-
- def _refreshUpdateList(self):
- """
- Update the list of packages to be updated in the system.
- """
- try:
- kimchiLock.acquire()
- self._pkgs = get_yum_packages_list_update()
- except Exception, e:
- raise OperationFailed('KCHPKGUPD0003E', {'err': str(e)})
- finally:
- kimchiLock.release()
-
- def getPackagesList(self):
- """
- Return a list of package's dictionaries. Each dictionary contains the
- information about a package, in the format:
- package = {'package_name': <string>, 'version': <string>,
- 'arch': <string>, 'repository': <string>}
- """
- self._refreshUpdateList()
- pkg_list = []
- for pkg in self._pkgs:
- package = {'package_name': pkg.name, 'version': pkg.version,
- 'arch': pkg.arch, 'repository': pkg.ui_from_repo}
- pkg_list.append(package)
- return pkg_list
-
-
-class AptUpdate(object):
- """
- Class to represent and operate with APT software update system.
- It's loaded only on those systems listed at APT_DISTROS and loads necessary
- modules in runtime.
- """
- def __init__(self):
- self._pkgs = {}
- self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
- self.update_cmd = ['apt-get', 'upgrade', '-y']
-
- def _refreshUpdateList(self):
- """
- Update the list of packages to be updated in the system.
- """
- apt_cache = getattr(__import__('apt'), 'Cache')()
- try:
- with self.pkg_lock():
- apt_cache.update()
- apt_cache.upgrade()
- self._pkgs = apt_cache.get_changes()
- except Exception, e:
- kimchiLock.release()
- raise OperationFailed('KCHPKGUPD0003E', {'err': e.message})
-
- def getPackagesList(self):
- """
- Return a list of package's dictionaries. Each dictionary contains the
- information about a package, in the format
- package = {'package_name': <string>, 'version': <string>,
- 'arch': <string>, 'repository': <string>}
- """
- kimchiLock.acquire()
- self._refreshUpdateList()
- kimchiLock.release()
- pkg_list = []
- for pkg in self._pkgs:
- package = {'package_name': pkg.shortname,
- 'version': pkg.candidate.version,
- 'arch': pkg._pkg.architecture,
- 'repository': pkg.candidate.origins[0].label}
- pkg_list.append(package)
-
- return pkg_list
-
-
-class ZypperUpdate(object):
- """
- Class to represent and operate with Zypper software update system.
- It's loaded only on those systems listed at ZYPPER_DISTROS and loads
- necessary modules in runtime.
- """
- def __init__(self):
- self._pkgs = {}
- self.update_cmd = ["zypper", "--non-interactive", "update",
- "--auto-agree-with-licenses"]
-
- def _refreshUpdateList(self):
- """
- Update the list of packages to be updated in the system.
- """
- self._pkgs = []
- cmd = ["zypper", "list-updates"]
- (stdout, stderr, returncode) = run_command(cmd)
-
- if len(stderr) > 0:
- raise OperationFailed('KCHPKGUPD0003E', {'err': stderr})
-
- for line in stdout.split('\n'):
- if line.find('v |') >= 0:
- info = line.split(' | ')
- package = {'package_name': info[2], 'version': info[4],
- 'arch': info[5], 'repository': info[1]}
- self._pkgs.append(package)
-
- def getPackagesList(self):
- """
- Return a list of package's dictionaries. Each dictionary contains the
- information about a package, in the format
- package = {'package_name': <string>, 'version': <string>,
- 'arch': <string>, 'repository': <string>}
- """
- kimchiLock.acquire()
- self._refreshUpdateList()
- kimchiLock.release()
- return self._pkgs
diff --git a/plugins/kimchi/template.conf b/plugins/kimchi/template.conf
deleted file mode 100644
index f3615e6..0000000
--- a/plugins/kimchi/template.conf
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Configuration file for Kimchi Templates
-#
-
-[main]
-# Memory in MB
-#memory = 1024
-
-# List of networks separated by comma
-# Represents the virtual network interfaces to be assigned to guest
-#networks = default,
-
-[storage]
-# Storage pool used to handle the guest disk
-#pool = default
-
-# Specify multiple [[disk.X]] sub-sections to add multiples disks to guest
-# All the disk files will be created in the same storage pool as set above
-[[disk.0]]
-# Disk size in GB
-#size = 10
-
-# Disk format
-#format = qcow2
-
-[graphics]
-# Graphics type
-# Valid options: vnc | spice
-#type = vnc
-
-# The network which the vnc/spice server listens on
-#listen = 127.0.0.1
-
-[processor]
-# Number of vcpus
-# When specifying CPU topology, make sure cpus value is equal to the product
-# of sockets, cores, and threads.
-#cpus = 1
-
-# Number of sockets (not set by default)
-#sockets =
-
-# Number of cores per socket (not set by default)
-#cores =
-
-# Number of threads per core (not set by default)
-#threads =
diff --git a/plugins/kimchi/tests/Makefile.am b/plugins/kimchi/tests/Makefile.am
deleted file mode 100644
index c1f6784..0000000
--- a/plugins/kimchi/tests/Makefile.am
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = \
- Makefile.am \
- run_tests.sh.in \
- test_config.py.in \
- $(filter-out test_config.py, $(wildcard *.py)) \
- $(NULL)
-
-noinst_SCRIPTS = run_tests.sh
-
-do_substitution = \
- sed -e 's,[@]HAVE_PYMOD_UNITTEST[@],$(HAVE_PYMOD_UNITTEST),g' \
- -e 's,[@]prefix[@],$(prefix),g' \
- -e 's,[@]datadir[@],$(datadir),g' \
- -e 's,[@]PYTHON_VERSION[@],$(PYTHON_VERSION),g' \
- -e 's,[@]wokdir[@],$(pythondir)/wok,g' \
- -e 's,[@]pkgdatadir[@],$(pkgdatadir),g'
-
-
-run_tests.sh: run_tests.sh.in Makefile
- $(do_substitution) < $(srcdir)/run_tests.sh.in > run_tests.sh
- chmod +x run_tests.sh
-
-test_config.py: test_config.py.in Makefile
- $(do_substitution) < $(srcdir)/test_config.py.in > test_config.py
-
-check-local:
- $(MKDIR_P) $(top_srcdir)/data/screenshots
- ./run_tests.sh
-
-BUILT_SOURCES = test_config.py
-CLEANFILES = run_tests.sh test_config.py
diff --git a/plugins/kimchi/tests/iso_gen.py b/plugins/kimchi/tests/iso_gen.py
deleted file mode 100644
index 736c660..0000000
--- a/plugins/kimchi/tests/iso_gen.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import platform
-import struct
-
-from wok.plugins.kimchi.isoinfo import IsoImage
-
-
-iso_des = [
- ('openbsd', lambda v: True,
- lambda v: 'OpenBSD/i386 %s Install CD' % v),
- ('centos', lambda v: True, lambda v: 'CentOS_%s_Final' % v),
- ('windows', '2000', 'W2AFPP'),
- ('windows', 'xp', 'WXPFPP'),
- ('windows', '2003', 'ARMECHK'),
- ('windows', '2003r2', 'CRMEFPP'),
- ('windows', '2008', 'KRTMSVOL'),
- ('windows', '2008r2', 'GRMSXVOL'),
- ('windows', 'vista', 'FB1EVOL'),
- ('windows', '7', 'GRMCULFRER'),
- ('windows', '8', 'HB1_CCPA_X86FRE'),
- ('sles', '10', 'SLES10'),
- ('sles', '11', 'SUSE_SLES-11-0-0'),
- ('opensuse', '11.1', 'SU1110.001'),
- ('opensuse', '11.3', 'openSUSE-DVD-x86_64.0702..001'),
- ('opensuse', '11.4', 'openSUSE-DVD-x86_640024'),
- ('opensuse', '12.1', 'openSUSE-DVD-x86_640039'),
- ('opensuse', '12.2', 'openSUSE-DVD-x86_640167'),
- ('opensuse', lambda v: True, lambda v: 'openSUSE-%s' % v),
- ('rhel', '4.8', 'RHEL/4-U8'),
- ('rhel', lambda v: v.startswith('6.'), lambda v: 'RHEL_%s' % v),
- ('debian', lambda v: True, lambda v: 'Debian %s' % v),
- ('ubuntu',
- lambda v: v in ('7.10', '8.04', '8.10', '9.04', '9.10', '10.04', '10.10',
- '11.04', '11.10', '12.04', '12.10', '13.04', '13.10',
- '14.04'),
- lambda v: 'Ubuntu %s' % v),
- ('fedora',
- lambda v: v in ('16', '17', '18', '19'),
- lambda v: 'Fedora %s' % v)
-]
-
-
-class FakeIsoImage(object):
- def _build_iso(self, fd, iso_volid, bootable):
- if platform.machine().startswith('ppc'):
- self._build_powerpc_bootable_iso(fd, iso_volid)
- return
- self._build_intel_iso(fd, iso_volid, bootable)
-
- def _build_powerpc_bootable_iso(self, fd, iso_volid):
- self._build_prim_vol(fd, iso_volid)
- self._build_bootable_ppc_path_table(fd)
-
- def _build_intel_iso(self, fd, iso_volid, bootable):
- # Do not change the order of the method calls
- self._build_el_boot(fd, bootable)
- self._build_prim_vol(fd, iso_volid)
- self._build_el_torito(fd)
-
- def _build_prim_vol(self, fd, iso_volid):
- fd.seek(16 * IsoImage.SECTOR_SIZE)
- fmt = IsoImage.VOL_DESC
- vd_type = 1
- vd_ident = 'CD001'
- vd_ver = 1
- pad0 = 1
- sys_id = 'fake os'
- vol_id = iso_volid
- data = (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id)
- s = fmt.pack(*data)
- fd.write(s)
- self._add_sector_padding(fd, s)
-
- def _add_sector_padding(self, fd, s):
- padding_len = IsoImage.SECTOR_SIZE - len(s)
- fmt = struct.Struct('=%ss' % padding_len)
- s = fmt.pack('a' * padding_len)
- fd.write(s)
-
- def _build_el_torito(self, fd):
- fmt = IsoImage.EL_TORITO_BOOT_RECORD
- vd_type = 0
- vd_ident = 'CD001'
- vd_ver = 1
- et_ident = "EL TORITO SPECIFICATION:"
- pad0 = 'a' * 32
- boot_cat = 0
- data = (vd_type, vd_ident, vd_ver, et_ident, pad0, boot_cat)
- s = fmt.pack(*data)
- fd.write(s)
- self._add_sector_padding(fd, s)
-
- def _build_el_boot(self, fd, bootable):
- fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
- hdr_id = 0
- platform_id = 0
- pad0 = 1
- ident = 'c' * 24
- csum = 1
- key55 = 0x55
- keyAA = 0xaa
- data = (hdr_id, platform_id, pad0, ident, csum, key55, keyAA)
- s = fmt.pack(*data)
- fd.write(s)
-
- fmt = IsoImage.EL_TORITO_BOOT_ENTRY
- if bootable:
- boot = 0x88
- else:
- boot = 0
- media_type = 1
- load_seg = 1
- sys_type = 1
- pad0 = 1
- sectors = 1
- load_rba = 1
- data = (boot, media_type, load_seg, sys_type, pad0, sectors, load_rba)
- s = fmt.pack(*data)
- fd.write(s)
-
- s = 'a' * IsoImage.SECTOR_SIZE
- fd.write(s)
-
- def _build_bootable_ppc_path_table(self, fd):
- # write path table locator
- PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
- PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
- path_table_size = 64
- path_table_loc = 18
- fd.seek(PATH_TABLE_LOC_OFFSET)
- fmt = PATH_TABLE_SIZE_LOC
- data = (path_table_size, 4*'0', path_table_loc)
- s = fmt.pack(*data)
- fd.write(s)
- # write path table entry
- fd.seek(path_table_loc * IsoImage.SECTOR_SIZE)
- DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H 3s")
- dir_namelen = 3
- dir_loc = 19
- dir_parent = 1
- dir_name = 'ppc'
- data = (dir_namelen, 0, dir_loc, dir_parent, dir_name)
- fmt = DIR_NAMELEN_LOCATION_PARENT
- s = fmt.pack(*data)
- fd.write(s)
- # write 'ppc' dir record
- ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
- fd.seek(ppc_dir_offset)
- STATIC_DIR_RECORD_FMT = struct.Struct("<B 9s I 11s B 6s B 12s")
- dir_rec_len = 1
- unused1 = 9 * '0'
- dir_size = 100
- unused2 = 11 * '0'
- file_flags = 0
- unused3 = 6 * '0'
- file_name_len = 12
- boot_file_name = "bootinfo.txt"
- data = (dir_rec_len, unused1, dir_size, unused2, file_flags,
- unused3, file_name_len, boot_file_name)
- fmt = STATIC_DIR_RECORD_FMT
- s = fmt.pack(*data)
- fd.write(s)
-
-
-def construct_fake_iso(path, bootable, version, distro):
- iso = FakeIsoImage()
-
- for d, v, gen_id in iso_des:
- if d != distro:
- continue
- if hasattr(v, '__call__'):
- supported = v(version)
- else:
- supported = version == v
-
- if not supported:
- continue
-
- if hasattr(gen_id, '__call__'):
- vol_id = gen_id(version)
- else:
- vol_id = gen_id
- with open(path, 'w') as fd:
- return iso._build_iso(fd, vol_id, bootable)
-
- raise Exception("%s: %s not supported generation" % (distro, version))
-
-
-if __name__ == '__main__':
- construct_fake_iso('centos.iso', True, '6.1', 'centos')
- construct_fake_iso('ubuntu12.04.iso', True, '12.04', 'ubuntu')
- construct_fake_iso('fedora17.iso', True, '17', 'fedora')
- construct_fake_iso('sles10.iso', True, '10', 'sles')
- construct_fake_iso('openbsd.iso', True, '5.0', 'openbsd')
diff --git a/plugins/kimchi/tests/run_tests.sh.in b/plugins/kimchi/tests/run_tests.sh.in
deleted file mode 100644
index beef75e..0000000
--- a/plugins/kimchi/tests/run_tests.sh.in
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-HAVE_UNITTEST=@HAVE_PYMOD_UNITTEST@
-PYTHON_VER=@PYTHON_VERSION@
-
-if [ "$1" = "-v" ]; then
- OPTS="-v"
- shift
-else
- OPTS=""
-fi
-
-if [ $# -ne 0 ]; then
- ARGS="$@"
-else
- ARGS=`find -name "test_*.py" | xargs -I @ basename @ .py`
-fi
-
-if [ "$HAVE_UNITTEST" != "yes" -o "$PYTHON_VER" == "2.6" ]; then
- CMD="unit2"
-else
- CMD="python -m unittest"
-fi
-
-LIST=($ARGS)
-MODEL_LIST=()
-MOCK_LIST=()
-for ((i=0;i<${#LIST[@]};i++)); do
-
- if [[ ${LIST[$i]} == test_model* ]]; then
- MODEL_LIST+=(${LIST[$i]})
- else
- MOCK_LIST+=(${LIST[$i]})
- fi
-done
-
-PYTHONPATH=../plugins:../src:../ $CMD $OPTS ${MODEL_LIST[@]} ${MOCK_LIST[@]}
diff --git a/plugins/kimchi/tests/test_authorization.py b/plugins/kimchi/tests/test_authorization.py
deleted file mode 100644
index 87d68ab..0000000
--- a/plugins/kimchi/tests/test_authorization.py
+++ /dev/null
@@ -1,178 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi import mockmodel
-
-from iso_gen import construct_fake_iso
-from utils import get_free_port, patch_auth, request
-from utils import run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-fake_iso = '/tmp/fake.iso'
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port
-
- patch_auth(sudo=False)
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- test_server = run_server(host, port, ssl_port, test_mode=True, model=model)
-
- # Create fake ISO to do the tests
- construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
- os.unlink(fake_iso)
-
-
-class AuthorizationTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def test_nonroot_access(self):
- # Non-root users can access static host information
- resp = self.request('/plugins/kimchi/host', '{}', 'GET')
- self.assertEquals(403, resp.status)
-
- # Non-root users can access host stats
- resp = self.request('/plugins/kimchi/host/stats', '{}', 'GET')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not reboot/shutdown host system
- resp = self.request('/plugins/kimchi/host/reboot', '{}', 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/host/shutdown', '{}', 'POST')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not get or debug reports
- resp = self.request('/plugins/kimchi/debugreports', '{}', 'GET')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/debugreports', '{}', 'POST')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not create or delete network (only get)
- resp = self.request('/plugins/kimchi/networks', '{}', 'GET')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/networks', '{}', 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/networks/default/activate', '{}',
- 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/networks/default', '{}', 'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not create or delete storage pool (only get)
- resp = self.request('/plugins/kimchi/storagepools', '{}', 'GET')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/storagepools', '{}', 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/default/activate',
- '{}', 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/default', '{}',
- 'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not update or delete a template
- # but he can get and create a new one
- resp = self.request('/plugins/kimchi/templates', '{}', 'GET')
- self.assertEquals(403, resp.status)
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/templates/test', '{}', 'PUT')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can only get vms authorized to them
- model.templates_create({'name': u'test', 'cdrom': fake_iso})
-
- task_info = model.vms_create({
- 'name': u'test-me',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
-
- model.vm_update(u'test-me',
- {'users': [mockmodel.fake_user.keys()[0]],
- 'groups': []})
-
- task_info = model.vms_create({
- 'name': u'test-usera',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
-
- non_root = list(set(model.users_get_list()) - set(['root']))[0]
- model.vm_update(u'test-usera', {'users': [non_root], 'groups': []})
-
- task_info = model.vms_create({
- 'name': u'test-groupa',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
- a_group = model.groups_get_list()[0]
- model.vm_update(u'test-groupa', {'groups': [a_group]})
-
- resp = self.request('/plugins/kimchi/vms', '{}', 'GET')
- self.assertEquals(200, resp.status)
- vms_data = json.loads(resp.read())
- self.assertEquals([u'test-groupa', u'test-me'],
- sorted([v['name'] for v in vms_data]))
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(403, resp.status)
-
- # Create a vm using mockmodel directly to test Resource access
- task_info = model.vms_create({
- 'name': 'kimchi-test',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
- resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}', 'PUT')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}', 'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can only update VMs authorized by them
- resp = self.request('/plugins/kimchi/vms/test-me/start', '{}', 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-usera/start', '{}',
- 'POST')
- self.assertEquals(403, resp.status)
-
- model.template_delete('test')
- model.vm_delete('test-me')
diff --git a/plugins/kimchi/tests/test_config.py.in b/plugins/kimchi/tests/test_config.py.in
deleted file mode 100644
index 4604eb1..0000000
--- a/plugins/kimchi/tests/test_config.py.in
+++ /dev/null
@@ -1,267 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-from cherrypy.lib.reprconf import Parser
-
-from wok.config import Paths, PluginPaths, WokConfig
-
-from wok.plugins.kimchi.config import get_debugreports_path
-from wok.plugins.kimchi.config import get_screenshot_path
-from wok.plugins.kimchi.config import KimchiConfig, KimchiPaths
-
-
-get_prefix = None
-
-
-def setUpModule():
- global get_prefix
- get_prefix = Paths.get_prefix
-
-
-def tearDownModule():
- Paths.get_prefix = KimchiPaths.get_prefix = get_prefix
-
-
-class ConfigTests(unittest.TestCase):
- def assertInstalledPath(self, actual, expected):
- if '@pkgdatadir@' != '/usr/share/kimchi':
- usr_local = '/usr/local'
- if not expected.startswith('/usr'):
- expected = usr_local + expected
- self.assertEquals(actual, expected)
-
- def test_installed_paths(self):
- Paths.get_prefix = lambda self: '@datadir@/wok'
- paths = Paths()
- self.assertInstalledPath(paths.state_dir, '/var/lib/wok')
- self.assertInstalledPath(paths.log_dir, '/var/log/wok')
- self.assertInstalledPath(paths.conf_dir, '/etc/wok')
- self.assertInstalledPath(paths.src_dir, '@wokdir@')
- self.assertInstalledPath(paths.plugins_dir, '@wokdir@/plugins')
- self.assertInstalledPath(paths.ui_dir, '@datadir@/wok/ui')
- self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
-
- def test_uninstalled_paths(self):
- Paths.get_prefix = lambda self: '/home/user/wok'
- paths = Paths()
- self.assertEquals(paths.state_dir, '/home/user/wok/data')
- self.assertEquals(paths.log_dir, '/home/user/wok/log')
- self.assertEquals(paths.conf_dir, '/home/user/wok/src')
- self.assertEquals(paths.src_dir, '/home/user/wok/src/wok')
- self.assertEquals(paths.plugins_dir, '/home/user/wok/plugins')
- self.assertEquals(paths.ui_dir, '/home/user/wok/ui')
- self.assertEquals(paths.mo_dir, '/home/user/wok/mo')
-
- def test_installed_plugin_paths(self):
- KimchiPaths.get_prefix = lambda self: '@datadir@/wok'
- paths = KimchiPaths()
- self.assertInstalledPath(paths.conf_dir, '/etc/wok/plugins.d')
- self.assertInstalledPath(paths.conf_file,
- '/etc/wok/plugins.d/kimchi.conf')
- self.assertInstalledPath(paths.src_dir, '@wokdir@/plugins/kimchi')
- self.assertInstalledPath(paths.ui_dir,
- '@datadir@/wok/plugins/kimchi/ui')
- self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
-
- def test_uninstalled_plugin_paths(self):
- KimchiPaths.get_prefix = lambda self: '/home/user/wok'
- paths = KimchiPaths()
- self.assertEquals(paths.conf_dir, '/home/user/wok/plugins/kimchi')
- self.assertEquals(
- paths.conf_file, '/home/user/wok/plugins/kimchi/kimchi.conf')
- self.assertEquals(paths.src_dir, '/home/user/wok/plugins/kimchi')
- self.assertEquals(paths.ui_dir, '/home/user/wok/plugins/kimchi/ui')
- self.assertEquals(paths.mo_dir, '/home/user/wok/plugins/kimchi/mo')
-
- def test_wok_config(self):
- Paths.get_prefix = PluginPaths.get_prefix = get_prefix
- paths = Paths()
- CACHEEXPIRES = 31536000
- SESSIONSTIMEOUT = 10
- configObj = {
- '/': {
- 'tools.trailing_slash.on': False,
- 'request.methods_with_bodies': ('POST', 'PUT'),
- 'tools.nocache.on': True,
- 'tools.proxy.on': True,
- 'tools.sessions.on': True,
- 'tools.sessions.name': 'wok',
- 'tools.sessions.secure': True,
- 'tools.sessions.httponly': True,
- 'tools.sessions.locking': 'explicit',
- 'tools.sessions.storage_type': 'ram',
- 'tools.sessions.timeout': SESSIONSTIMEOUT,
- 'tools.wokauth.on': False
- },
- '/wok-ui.html': {
- 'tools.wokauth.on': True
- },
- '/css': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/css' % paths.prefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/js': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/js' % paths.prefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/libs': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/libs' % paths.prefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/images': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/images' % paths.prefix,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/favicon.ico': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename':
- '%s/images/logo.ico' % paths.ui_dir
- },
- '/robots.txt': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': '%s/robots.txt' % paths.ui_dir
- },
- }
-
- wok_config = WokConfig()
- self.assertEquals(wok_config, configObj)
-
-
- def test_kimchi_config(self):
- KimchiPaths.get_prefix = PluginPaths.get_prefix = get_prefix
- paths = KimchiPaths()
- pluginPrefix = paths.add_prefix(paths.plugin_dir)
- CACHEEXPIRES = 31536000
- SESSIONSTIMEOUT = 10
- configObj = {
- 'wok': {
- 'enable': True,
- 'plugin_class': "KimchiRoot",
- 'uri': '/%s' % paths.plugin_dir,
- 'extra_auth_api_class': "control.sub_nodes"
- },
- '/': {
- 'tools.trailing_slash.on': False,
- 'request.methods_with_bodies': ('POST', 'PUT'),
- 'tools.nocache.on': True,
- 'tools.proxy.on': True,
- 'tools.sessions.on': True,
- 'tools.sessions.name': 'wok',
- 'tools.sessions.secure': True,
- 'tools.sessions.httponly': True,
- 'tools.sessions.locking': 'explicit',
- 'tools.sessions.storage_type': 'ram',
- 'tools.sessions.timeout': SESSIONSTIMEOUT,
- 'tools.wokauth.on': True
- },
- '/novnc': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': paths.novnc_dir,
- 'tools.nocache.on': True,
- 'tools.wokauth.on': True
- },
- '/spice_auto.html': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': paths.spice_file,
- 'tools.nocache.on': True,
- 'tools.wokauth.on': True
- },
- '/spice-html5': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': paths.spice_dir,
- 'tools.nocache.on': True
- },
- '/spice-html5/spice.css': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': paths.spice_css_file,
- 'tools.nocache.on': True,
- },
- '/ui/config/tab-ext.xml': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': '%s/ui/config/tab-ext.xml' %
- pluginPrefix,
- 'tools.nocache.on': True
- },
- '/css': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/css' % pluginPrefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/js': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/js' % pluginPrefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/libs': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/libs' % pluginPrefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False,
- },
- '/images': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/images' % pluginPrefix,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/data/screenshots': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': get_screenshot_path(),
- 'tools.nocache.on': False
- },
- '/data/debugreports': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': get_debugreports_path(),
- 'tools.nocache.on': False,
- 'tools.wokauth.on': True,
- 'tools.staticdir.content_types': {'xz': 'application/x-xz'}
- },
- '/help': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/pages/help' % pluginPrefix,
- 'tools.nocache.on': True
- }
- }
-
- kimchi_config = Parser().dict_from_file(KimchiPaths().conf_file)
- kimchi_config.update(KimchiConfig())
- self.assertEquals(kimchi_config, configObj)
diff --git a/plugins/kimchi/tests/test_exception.py b/plugins/kimchi/tests/test_exception.py
deleted file mode 100644
index 4459aa6..0000000
--- a/plugins/kimchi/tests/test_exception.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-
-from wok.plugins.kimchi import mockmodel
-
-from utils import get_free_port, patch_auth, request, run_server
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-
-
-def setup_server(environment='development'):
- global test_server, model, host, port, ssl_port
-
- patch_auth()
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- test_server = run_server(host, port, ssl_port, test_mode=True, model=model,
- environment=environment)
-
-
-class ExceptionTests(unittest.TestCase):
- def tearDown(self):
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
- def test_production_env(self):
- """
- Test reasons sanitized in production env
- """
- setup_server('production')
- # test 404
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
- )
- self.assertEquals('404 Not Found', resp.get('code'))
-
- # test 405 wrong method
- resp = json.loads(request(host, ssl_port, '/', None, 'DELETE').read())
- msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
- self.assertEquals('405 Method Not Allowed', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
-
- # test 400 parse error
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', '{', 'POST').read()
- )
- msg = u'WOKAPI0006E: Unable to parse JSON request'
- self.assertEquals('400 Bad Request', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
- self.assertNotIn('call_stack', resp)
-
- # test 400 missing required parameter
- req = json.dumps({})
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', req, 'POST').read()
- )
- self.assertEquals('400 Bad Request', resp.get('code'))
- m = u"KCHVM0016E: Specify a template to create a virtual machine from"
- self.assertEquals(m, resp.get('reason'))
- self.assertNotIn('call_stack', resp)
-
- def test_development_env(self):
- """
- Test traceback thrown in development env
- """
- setup_server()
- # test 404
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
- )
- self.assertEquals('404 Not Found', resp.get('code'))
-
- # test 405 wrong method
- resp = json.loads(request(host, ssl_port, '/', None, 'DELETE').read())
- msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
- self.assertEquals('405 Method Not Allowed', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
-
- # test 400 parse error
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', '{', 'POST').read()
- )
- msg = u'WOKAPI0006E: Unable to parse JSON request'
- self.assertEquals('400 Bad Request', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
- self.assertIn('call_stack', resp)
-
- # test 400 missing required parameter
- req = json.dumps({})
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', req, 'POST').read()
- )
- m = u"KCHVM0016E: Specify a template to create a virtual machine from"
- self.assertEquals('400 Bad Request', resp.get('code'))
- self.assertEquals(m, resp.get('reason'))
- self.assertIn('call_stack', resp)
diff --git a/plugins/kimchi/tests/test_host.py b/plugins/kimchi/tests/test_host.py
deleted file mode 100644
index 6cd0833..0000000
--- a/plugins/kimchi/tests/test_host.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import platform
-import psutil
-import tempfile
-import time
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from utils import get_free_port, patch_auth, request, run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-ssl_port = None
-tmpfile = None
-
-
-def setUpModule():
- global test_server, model, host, ssl_port, tmpfile
-
- patch_auth()
- tmpfile = tempfile.mktemp()
- model = MockModel(tmpfile)
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink(tmpfile)
-
-
-class HostTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_hostinfo(self):
- resp = self.request('/plugins/kimchi/host').read()
- info = json.loads(resp)
- keys = ['os_distro', 'os_version', 'os_codename', 'cpu_model',
- 'memory', 'cpus']
- self.assertEquals(sorted(keys), sorted(info.keys()))
-
- distro, version, codename = platform.linux_distribution()
- self.assertEquals(distro, info['os_distro'])
- self.assertEquals(version, info['os_version'])
- self.assertEquals(unicode(codename, "utf-8"), info['os_codename'])
- self.assertEquals(psutil.TOTAL_PHYMEM, info['memory'])
-
- def test_hoststats(self):
- time.sleep(1)
- stats_keys = ['cpu_utilization', 'memory', 'disk_read_rate',
- 'disk_write_rate', 'net_recv_rate', 'net_sent_rate']
- resp = self.request('/plugins/kimchi/host/stats').read()
- stats = json.loads(resp)
- self.assertEquals(sorted(stats_keys), sorted(stats.keys()))
-
- cpu_utilization = stats['cpu_utilization']
- self.assertIsInstance(cpu_utilization, float)
- self.assertGreaterEqual(cpu_utilization, 0.0)
- self.assertTrue(cpu_utilization <= 100.0)
-
- memory_stats = stats['memory']
- self.assertIn('total', memory_stats)
- self.assertIn('free', memory_stats)
- self.assertIn('cached', memory_stats)
- self.assertIn('buffers', memory_stats)
- self.assertIn('avail', memory_stats)
-
- resp = self.request('/plugins/kimchi/host/stats/history').read()
- history = json.loads(resp)
- self.assertEquals(sorted(stats_keys), sorted(history.keys()))
-
- def test_host_actions(self):
- def _task_lookup(taskid):
- return json.loads(
- self.request('/plugins/kimchi/tasks/%s' % taskid).read()
- )
-
- resp = self.request('/plugins/kimchi/host/shutdown', '{}', 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/host/reboot', '{}', 'POST')
- self.assertEquals(200, resp.status)
-
- # Test system update
- resp = self.request('/plugins/kimchi/host/packagesupdate', None, 'GET')
- pkgs = json.loads(resp.read())
- self.assertEquals(3, len(pkgs))
-
- pkg_keys = ['package_name', 'repository', 'arch', 'version']
- for p in pkgs:
- name = p['package_name']
- resp = self.request('/plugins/kimchi/host/packagesupdate/' + name,
- None, 'GET')
- info = json.loads(resp.read())
- self.assertEquals(sorted(pkg_keys), sorted(info.keys()))
-
- resp = self.request('/plugins/kimchi/host/swupdate', '{}', 'POST')
- task = json.loads(resp.read())
- task_params = [u'id', u'message', u'status', u'target_uri']
- self.assertEquals(sorted(task_params), sorted(task.keys()))
-
- resp = self.request('/tasks/' + task[u'id'], None,
- 'GET')
- task_info = json.loads(resp.read())
- self.assertEquals(task_info['status'], 'running')
- wait_task(_task_lookup, task_info['id'])
- resp = self.request('/tasks/' + task[u'id'], None,
- 'GET')
- task_info = json.loads(resp.read())
- self.assertEquals(task_info['status'], 'finished')
- self.assertIn(u'All packages updated', task_info['message'])
- pkgs = model.packagesupdate_get_list()
- self.assertEquals(0, len(pkgs))
-
- def test_host_partitions(self):
- resp = self.request('/plugins/kimchi/host/partitions')
- self.assertEquals(200, resp.status)
- partitions = json.loads(resp.read())
-
- keys = ['name', 'path', 'type', 'fstype', 'size', 'mountpoint',
- 'available']
- for item in partitions:
- resp = self.request('/plugins/kimchi/host/partitions/%s' %
- item['name'])
- info = json.loads(resp.read())
- self.assertEquals(sorted(info.keys()), sorted(keys))
-
- def test_host_devices(self):
- def asset_devices_type(devices, dev_type):
- for dev in devices:
- self.assertEquals(dev['device_type'], dev_type)
-
- resp = self.request('/plugins/kimchi/host/devices?_cap=scsi_host')
- nodedevs = json.loads(resp.read())
- # Mockmodel brings 3 preconfigured scsi fc_host
- self.assertEquals(3, len(nodedevs))
-
- nodedev = json.loads(
- self.request('/plugins/kimchi/host/devices/scsi_host2').read()
- )
- # Mockmodel generates random wwpn and wwnn
- self.assertEquals('scsi_host2', nodedev['name'])
- self.assertEquals('fc_host', nodedev['adapter']['type'])
- self.assertEquals(16, len(nodedev['adapter']['wwpn']))
- self.assertEquals(16, len(nodedev['adapter']['wwnn']))
-
- devs = json.loads(self.request('/plugins/kimchi/host/devices').read())
- dev_names = [dev['name'] for dev in devs]
- for dev_type in ('pci', 'usb_device', 'scsi'):
- resp = self.request('/plugins/kimchi/host/devices?_cap=%s' %
- dev_type)
- devsByType = json.loads(resp.read())
- names = [dev['name'] for dev in devsByType]
- self.assertTrue(set(names) <= set(dev_names))
- asset_devices_type(devsByType, dev_type)
-
- resp = self.request('/plugins/kimchi/host/devices?_passthrough=true')
- passthru_devs = [dev['name'] for dev in json.loads(resp.read())]
- self.assertTrue(set(passthru_devs) <= set(dev_names))
-
- for dev_type in ('pci', 'usb_device', 'scsi'):
- resp = self.request(
- '/plugins/kimchi/host/devices?_cap=%s&_passthrough=true' %
- dev_type
- )
- filteredDevs = json.loads(resp.read())
- filteredNames = [dev['name'] for dev in filteredDevs]
- self.assertTrue(set(filteredNames) <= set(dev_names))
- asset_devices_type(filteredDevs, dev_type)
-
- for dev in passthru_devs:
- resp = self.request(
- '/plugins/kimchi/host/devices?_passthrough_affected_by=%s' %
- dev
- )
- affected_devs = [dev['name'] for dev in json.loads(resp.read())]
- self.assertTrue(set(affected_devs) <= set(dev_names))
diff --git a/plugins/kimchi/tests/test_mock_network.py b/plugins/kimchi/tests/test_mock_network.py
deleted file mode 100644
index 4e2a939..0000000
--- a/plugins/kimchi/tests/test_mock_network.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from test_model_network import _do_network_test
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class MockNetworkTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def test_vlan_tag_bridge(self):
- # Verify the current system has at least one interface to create a
- # bridged network
- interfaces = json.loads(
- self.request('/plugins/kimchi/interfaces?type=nic').read()
- )
- if len(interfaces) > 0:
- iface = interfaces[0]['name']
- _do_network_test(self, model, {'name': u'bridge-network',
- 'connection': 'bridge',
- 'interface': iface, 'vlan_id': 987})
diff --git a/plugins/kimchi/tests/test_mock_storagepool.py b/plugins/kimchi/tests/test_mock_storagepool.py
deleted file mode 100644
index 5cf5b3e..0000000
--- a/plugins/kimchi/tests/test_mock_storagepool.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class MockStoragepoolTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def _task_lookup(self, taskid):
- return json.loads(
- self.request('/tasks/%s' % taskid).read()
- )
-
- def test_storagepool(self):
- # MockModel always returns 2 partitions (vdx, vdz)
- partitions = json.loads(
- self.request('/plugins/kimchi/host/partitions').read()
- )
- devs = [dev['path'] for dev in partitions]
-
- # MockModel always returns 3 FC devices
- fc_devs = json.loads(
- self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
- )
- fc_devs = [dev['name'] for dev in fc_devs]
-
- poolDefs = [
- {'type': 'dir', 'name': u'kīмÑhÄ«UnitTestDirPool',
- 'path': '/tmp/kimchi-images'},
- {'type': 'netfs', 'name': u'kīмÑhÄ«UnitTestNSFPool',
- 'source': {'host': 'localhost',
- 'path': '/var/lib/kimchi/nfs-pool'}},
- {'type': 'scsi', 'name': u'kīмÑhÄ«UnitTestSCSIFCPool',
- 'source': {'adapter_name': fc_devs[0]}},
- {'type': 'iscsi', 'name': u'kīмÑhÄ«UnitTestISCSIPool',
- 'source': {'host': '127.0.0.1',
- 'target': 'iqn.2015-01.localhost.kimchiUnitTest'}},
- {'type': 'logical', 'name': u'kīмÑhÄ«UnitTestLogicalPool',
- 'source': {'devices': [devs[0]]}}]
-
- def _do_test(params):
- name = params['name']
- uri = '/plugins/kimchi/storagepools/%s' % name.encode('utf-8')
-
- req = json.dumps(params)
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # activate the storage pool
- resp = self.request(uri + '/activate', '{}', 'POST')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals('active', storagepool['state'])
-
- # Set autostart flag of an active storage pool
- for autostart in [True, False]:
- t = {'autostart': autostart}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals(autostart, storagepool['autostart'])
-
- # Extend an active logical pool
- if params['type'] == 'logical':
- t = {'disks': [devs[1]]}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- self.assertEquals(200, resp.status)
-
- # Deactivate the storage pool
- resp = self.request(uri + '/deactivate', '{}', 'POST')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals('inactive', storagepool['state'])
-
- # Set autostart flag of an inactive storage pool
- for autostart in [True, False]:
- t = {'autostart': autostart}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals(autostart, storagepool['autostart'])
-
- # Extend an inactive logical pool
- if params['type'] == 'logical':
- t = {'disks': [devs[1]]}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- self.assertEquals(200, resp.status)
-
- # Delete the storage pool
- resp = self.request(uri, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- for pool in poolDefs:
- _do_test(pool)
diff --git a/plugins/kimchi/tests/test_mock_storagevolume.py b/plugins/kimchi/tests/test_mock_storagevolume.py
deleted file mode 100644
index 9d0a5ad..0000000
--- a/plugins/kimchi/tests/test_mock_storagevolume.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from test_model_storagevolume import _do_volume_test
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class MockStorageVolumeTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_storagevolume(self):
- # MockModel always returns 2 partitions (vdx, vdz)
- partitions = json.loads(
- self.request('/plugins/kimchi/host/partitions').read()
- )
- devs = [dev['path'] for dev in partitions]
-
- # MockModel always returns 3 FC devices
- fc_devs = json.loads(
- self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
- )
- fc_devs = [dev['name'] for dev in fc_devs]
-
- poolDefs = [
- {'type': 'dir', 'name': u'kīмÑhÄ«UnitTestDirPool',
- 'path': '/tmp/kimchi-images'},
- {'type': 'netfs', 'name': u'kīмÑhÄ«UnitTestNSFPool',
- 'source': {'host': 'localhost',
- 'path': '/var/lib/kimchi/nfs-pool'}},
- {'type': 'scsi', 'name': u'kīмÑhÄ«UnitTestSCSIFCPool',
- 'source': {'adapter_name': fc_devs[0]}},
- {'type': 'iscsi', 'name': u'kīмÑhÄ«UnitTestISCSIPool',
- 'source': {'host': '127.0.0.1',
- 'target': 'iqn.2015-01.localhost.kimchiUnitTest'}},
- {'type': 'logical', 'name': u'kīмÑhÄ«UnitTestLogicalPool',
- 'source': {'devices': [devs[0]]}}]
-
- for pool in poolDefs:
- pool_name = pool['name']
- uri = '/plugins/kimchi/storagepools/%s' % pool_name.encode('utf-8')
- req = json.dumps(pool)
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
- # activate the storage pool
- resp = self.request(uri + '/activate', '{}', 'POST')
- self.assertEquals(200, resp.status)
- _do_volume_test(self, model, host, ssl_port, pool_name)
diff --git a/plugins/kimchi/tests/test_mockmodel.py b/plugins/kimchi/tests/test_mockmodel.py
deleted file mode 100644
index ffbf8d5..0000000
--- a/plugins/kimchi/tests/test_mockmodel.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import json
-import os
-import time
-import unittest
-
-from wok.plugins.kimchi import mockmodel
-from wok.plugins.kimchi.osinfo import get_template_default
-
-from utils import get_free_port, patch_auth, request, run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-fake_iso = None
-
-
-def setUpModule():
- global host, port, ssl_port, model, test_server, fake_iso
- cherrypy.request.headers = {'Accept': 'application/json'}
- model = mockmodel.MockModel('/tmp/obj-store-test')
- patch_auth()
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- host = '127.0.0.1'
- test_server = run_server(host, port, ssl_port, test_mode=True,
- model=model)
- fake_iso = '/tmp/fake.iso'
- open(fake_iso, 'w').close()
-
-
-def tearDown():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
- os.unlink(fake_iso)
-
-
-class MockModelTests(unittest.TestCase):
- def setUp(self):
- model.reset()
-
- def test_screenshot_refresh(self):
- # Create a VM
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- request(host, ssl_port, '/plugins/kimchi/templates', req, 'POST')
- req = json.dumps({'name': 'test-vm', 'template': '/templates/test'})
- resp = request(host, ssl_port, '/plugins/kimchi/vms', req, 'POST')
- task = json.loads(resp.read())
- wait_task(model.task_lookup, task['id'])
-
- # Test screenshot refresh for running vm
- request(host, ssl_port, '/plugins/kimchi/vms/test-vm/start', '{}',
- 'POST')
- resp = request(host, ssl_port,
- '/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(200, resp.status)
- self.assertEquals('image/png', resp.getheader('content-type'))
- resp1 = request(host, ssl_port, '/plugins/kimchi/vms/test-vm')
- rspBody = resp1.read()
- testvm_Data = json.loads(rspBody)
- screenshotURL = testvm_Data['screenshot']
- time.sleep(5)
- resp2 = request(host, ssl_port, screenshotURL)
- self.assertEquals(200, resp2.status)
- self.assertEquals(resp2.getheader('content-type'),
- resp.getheader('content-type'))
- self.assertEquals(resp2.getheader('content-length'),
- resp.getheader('content-length'))
- self.assertEquals(resp2.getheader('last-modified'),
- resp.getheader('last-modified'))
-
- def test_vm_list_sorted(self):
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- request(host, ssl_port, '/plugins/kimchi/templates', req, 'POST')
-
- def add_vm(name):
- # Create a VM
- req = json.dumps({'name': name,
- 'template': '/plugins/kimchi/templates/test'})
- task = json.loads(request(host, ssl_port, '/plugins/kimchi/vms',
- req, 'POST').read())
- wait_task(model.task_lookup, task['id'])
-
- vms = [u'abc', u'bca', u'cab', u'xba']
- for vm in vms:
- add_vm(vm)
-
- vms.append(u'test')
- self.assertEqual(model.vms_get_list(), sorted(vms))
-
- def test_vm_info(self):
- model.templates_create({'name': u'test',
- 'cdrom': fake_iso})
- task = model.vms_create({'name': u'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- wait_task(model.task_lookup, task['id'])
- vms = model.vms_get_list()
- self.assertEquals(2, len(vms))
- self.assertIn(u'test-vm', vms)
-
- keys = set(('name', 'state', 'stats', 'uuid', 'memory', 'cpus',
- 'screenshot', 'icon', 'graphics', 'users', 'groups',
- 'access', 'persistent'))
-
- stats_keys = set(('cpu_utilization',
- 'net_throughput', 'net_throughput_peak',
- 'io_throughput', 'io_throughput_peak'))
-
- info = model.vm_lookup(u'test-vm')
- self.assertEquals(keys, set(info.keys()))
- self.assertEquals('shutoff', info['state'])
- self.assertEquals('test-vm', info['name'])
- self.assertEquals(get_template_default('old', 'memory'),
- info['memory'])
- self.assertEquals(1, info['cpus'])
- self.assertEquals('images/icon-vm.png', info['icon'])
- self.assertEquals(stats_keys, set(info['stats'].keys()))
- self.assertEquals('vnc', info['graphics']['type'])
- self.assertEquals('127.0.0.1', info['graphics']['listen'])
diff --git a/plugins/kimchi/tests/test_model.py b/plugins/kimchi/tests/test_model.py
deleted file mode 100644
index 7c89048..0000000
--- a/plugins/kimchi/tests/test_model.py
+++ /dev/null
@@ -1,1248 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import grp
-import os
-import pwd
-import re
-import shutil
-import time
-import unittest
-import uuid
-
-import wok.objectstore
-from wok.basemodel import Singleton
-from wok.config import config
-from wok.exception import InvalidOperation
-from wok.exception import InvalidParameter, NotFoundError, OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task
-
-from wok.plugins.kimchi import netinfo
-from wok.plugins.kimchi.osinfo import get_template_default
-from wok.plugins.kimchi.model import model
-from wok.plugins.kimchi.model.libvirtconnection import LibvirtConnection
-
-import iso_gen
-import utils
-
-
-invalid_repository_urls = ['www.fedora.org', # missing protocol
- '://www.fedora.org', # missing protocol
- 'http://www.fedora', # invalid domain name
- 'file:///home/foobar'] # invalid path
-
-TMP_DIR = '/var/lib/kimchi/tests/'
-UBUNTU_ISO = TMP_DIR + 'ubuntu14.04.iso'
-
-
-def setUpModule():
- if not os.path.exists(TMP_DIR):
- os.makedirs(TMP_DIR)
-
- iso_gen.construct_fake_iso(UBUNTU_ISO, True, '14.04', 'ubuntu')
-
- # Some FeatureTests functions depend on server to validate their result.
- # As CapabilitiesModel is a Singleton class it will get the first result
- # from FeatureTests which may be wrong when using the Model instance
- # directly - the case of this test_model.py
- # So clean Singleton instances to make sure to get the right result when
- # running the following tests.
- Singleton._instances = {}
-
-
-def tearDownModule():
- shutil.rmtree(TMP_DIR)
-
-
-class ModelTests(unittest.TestCase):
- def setUp(self):
- self.tmp_store = '/tmp/kimchi-store-test'
-
- def tearDown(self):
- # FIXME: Tests using 'test:///default' URI should be moved to
- # test_rest or test_mockmodel to avoid overriding problems
- LibvirtConnection._connections['test:///default'] = {}
-
- os.unlink(self.tmp_store)
-
- def test_vm_info(self):
- inst = model.Model('test:///default', self.tmp_store)
- vms = inst.vms_get_list()
- self.assertEquals(1, len(vms))
- self.assertEquals('test', vms[0])
-
- keys = set(('name', 'state', 'stats', 'uuid', 'memory', 'cpus',
- 'screenshot', 'icon', 'graphics', 'users', 'groups',
- 'access', 'persistent'))
-
- stats_keys = set(('cpu_utilization',
- 'net_throughput', 'net_throughput_peak',
- 'io_throughput', 'io_throughput_peak'))
- info = inst.vm_lookup('test')
- self.assertEquals(keys, set(info.keys()))
- self.assertEquals('running', info['state'])
- self.assertEquals('test', info['name'])
- self.assertEquals(2048, info['memory'])
- self.assertEquals(2, info['cpus'])
- self.assertEquals(None, info['icon'])
- self.assertEquals(stats_keys, set(info['stats'].keys()))
- self.assertRaises(NotFoundError, inst.vm_lookup, 'nosuchvm')
- self.assertEquals([], info['users'])
- self.assertEquals([], info['groups'])
- self.assertTrue(info['persistent'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_lifecycle(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- vol_params = {'name': u'test-vol', 'capacity': 1024}
- task = inst.storagevolumes_create(u'default', vol_params)
- rollback.prependDefer(inst.storagevolume_delete, u'default',
- vol_params['name'])
- inst.task_wait(task['id'])
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
- vol = inst.storagevolume_lookup(u'default', vol_params['name'])
-
- params = {'name': 'test', 'disks': [{'base': vol['path'],
- 'size': 1}],
- 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
- inst.task_wait(task['id'], 10)
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
-
- vms = inst.vms_get_list()
- self.assertTrue('kimchi-vm' in vms)
-
- inst.vm_start('kimchi-vm')
-
- info = inst.vm_lookup('kimchi-vm')
- self.assertEquals('running', info['state'])
-
- self.assertRaises(InvalidOperation, inst.vmsnapshots_create,
- u'kimchi-vm')
-
- inst.vm_poweroff(u'kimchi-vm')
- vm = inst.vm_lookup(u'kimchi-vm')
-
- empty_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals({}, empty_snap)
-
- # this snapshot should be deleted when its VM is deleted
- params = {'name': u'mysnap'}
- task = inst.vmsnapshots_create(u'kimchi-vm', params)
- inst.task_wait(task['id'])
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
-
- self.assertRaises(NotFoundError, inst.vmsnapshot_lookup,
- u'kimchi-vm', u'foobar')
-
- snap = inst.vmsnapshot_lookup(u'kimchi-vm', params['name'])
- self.assertTrue(int(time.time()) >= int(snap['created']))
- self.assertEquals(vm['state'], snap['state'])
- self.assertEquals(params['name'], snap['name'])
- self.assertEquals(u'', snap['parent'])
-
- snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
- self.assertEquals([params['name']], snaps)
-
- current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals(snap, current_snap)
-
- task = inst.vmsnapshots_create(u'kimchi-vm')
- snap_name = task['target_uri'].split('/')[-1]
- rollback.prependDefer(inst.vmsnapshot_delete,
- u'kimchi-vm', snap_name)
- inst.task_wait(task['id'])
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
-
- snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
- self.assertEquals(sorted([params['name'], snap_name],
- key=unicode.lower), snaps)
-
- snap = inst.vmsnapshot_lookup(u'kimchi-vm', snap_name)
- current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals(snap, current_snap)
-
- # update vm name
- inst.vm_update('kimchi-vm', {'name': u'kimchi-vm-new'})
-
- # Look up the first created snapshot from the renamed vm
- snap = inst.vmsnapshot_lookup(u'kimchi-vm-new', params['name'])
-
- # snapshot revert to the first created vm
- result = inst.vmsnapshot_revert(u'kimchi-vm-new', params['name'])
- self.assertEquals(result, [u'kimchi-vm', snap['name']])
-
- vm = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(vm['state'], snap['state'])
-
- current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals(params['name'], current_snap['name'])
-
- self.assertRaises(NotFoundError, inst.vmsnapshot_delete,
- u'kimchi-vm', u'foobar')
-
- # suspend and resume the VM
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'shutoff')
- self.assertRaises(InvalidOperation, inst.vm_suspend, u'kimchi-vm')
- inst.vm_start(u'kimchi-vm')
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'running')
- inst.vm_suspend(u'kimchi-vm')
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'paused')
- self.assertRaises(InvalidParameter, inst.vm_update, u'kimchi-vm',
- {'name': 'foo'})
- inst.vm_resume(u'kimchi-vm')
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'running')
- self.assertRaises(InvalidOperation, inst.vm_resume, u'kimchi-vm')
- # leave the VM suspended to make sure a paused VM can be
- # deleted correctly
- inst.vm_suspend(u'kimchi-vm')
-
- vms = inst.vms_get_list()
- self.assertFalse('kimchi-vm' in vms)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_image_based_template(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- vol = 'base-vol.img'
- params = {'name': vol,
- 'capacity': 1073741824, # 1 GiB
- 'allocation': 1048576, # 1 MiB
- 'format': 'qcow2'}
- task_id = inst.storagevolumes_create('default', params)['id']
- rollback.prependDefer(inst.storagevolume_delete, 'default', vol)
- inst.task_wait(task_id)
- self.assertEquals('finished', inst.task_lookup(task_id)['status'])
- vol_path = inst.storagevolume_lookup('default', vol)['path']
-
- params = {'name': 'test', 'disks': [{'base': vol_path}]}
- self.assertRaises(OperationFailed, inst.templates_create, params)
-
- # Hack the model objstore to add a new template
- # It is needed as the image file must be a bootable image when
- # using model
- # As it is difficult to create one on test runtime, inject a
- # template with an empty image file to the objstore to test the
- # feature
- tmpl_name = "img-tmpl"
- tmpl_info = {"cpus": 1, "cdrom": "",
- "graphics": {"type": "vnc", "listen": "127.0.0.1"},
- "networks": ["default"], "memory": 1024, "folder": [],
- "icon": "images/icon-vm.png",
- "os_distro": "unknown", "os_version": "unknown",
- "disks": [{"base": vol_path, "size": 10}],
- "storagepool": "/plugins/kimchi/storagepools/default"}
-
- with inst.objstore as session:
- session.store('template', tmpl_name, tmpl_info)
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/img-tmpl'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
-
- vms = inst.vms_get_list()
- self.assertTrue('kimchi-vm' in vms)
-
- inst.vm_start('kimchi-vm')
- rollback.prependDefer(inst.vm_poweroff, 'kimchi-vm')
-
- info = inst.vm_lookup('kimchi-vm')
- self.assertEquals('running', info['state'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_graphics(self):
- inst = model.Model(objstore_loc=self.tmp_store)
- params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- with RollbackContext() as rollback:
- params = {'name': 'kimchi-vnc',
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params)
- inst.task_wait(task1['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vnc')
-
- info = inst.vm_lookup('kimchi-vnc')
- self.assertEquals('vnc', info['graphics']['type'])
- self.assertEquals('127.0.0.1', info['graphics']['listen'])
-
- graphics = {'type': 'spice', 'listen': '127.0.0.1'}
- params = {'name': 'kimchi-spice',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics}
- task2 = inst.vms_create(params)
- inst.task_wait(task2['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-spice')
-
- info = inst.vm_lookup('kimchi-spice')
- self.assertEquals('spice', info['graphics']['type'])
- self.assertEquals('127.0.0.1', info['graphics']['listen'])
-
- inst.template_delete('test')
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_ifaces(self):
- inst = model.Model(objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- # Create a network
- net_name = 'test-network'
- net_args = {'name': net_name,
- 'connection': 'nat',
- 'subnet': '127.0.100.0/24'}
- inst.networks_create(net_args)
- rollback.prependDefer(inst.network_delete, net_name)
- inst.network_activate(net_name)
- rollback.prependDefer(inst.network_deactivate, net_name)
-
- for vm_name in ['kimchi-ifaces', 'kimchi-ifaces-running']:
- params = {'name': vm_name,
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- ifaces = inst.vmifaces_get_list(vm_name)
- self.assertEquals(1, len(ifaces))
-
- iface = inst.vmiface_lookup(vm_name, ifaces[0])
- self.assertEquals(17, len(iface['mac']))
- self.assertEquals("default", iface['network'])
- self.assertIn("model", iface)
-
- # attach network interface to vm
- iface_args = {"type": "network",
- "network": "test-network",
- "model": "virtio"}
- mac = inst.vmifaces_create(vm_name, iface_args)
- # detach network interface from vm
- rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
- self.assertEquals(17, len(mac))
-
- iface = inst.vmiface_lookup(vm_name, mac)
- self.assertEquals("network", iface["type"])
- self.assertEquals("test-network", iface['network'])
- self.assertEquals("virtio", iface["model"])
-
- # attach network interface to vm without providing model
- iface_args = {"type": "network",
- "network": "test-network"}
- mac = inst.vmifaces_create(vm_name, iface_args)
- rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
-
- iface = inst.vmiface_lookup(vm_name, mac)
- self.assertEquals("network", iface["type"])
- self.assertEquals("test-network", iface['network'])
-
- # update vm interface
- newMacAddr = '54:50:e3:44:8a:af'
- iface_args = {"mac": newMacAddr}
- inst.vmiface_update(vm_name, mac, iface_args)
- iface = inst.vmiface_lookup(vm_name, newMacAddr)
- self.assertEquals(newMacAddr, iface['mac'])
-
- # undo mac address change
- iface_args = {"mac": mac}
- inst.vmiface_update(vm_name, newMacAddr, iface_args)
- iface = inst.vmiface_lookup(vm_name, mac)
- self.assertEquals(mac, iface['mac'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_disk(self):
- disk_path = os.path.join(TMP_DIR, 'existent2.iso')
- open(disk_path, 'w').close()
- modern_disk_bus = get_template_default('modern', 'disk_bus')
-
- def _attach_disk(expect_bus=modern_disk_bus):
- disk_args = {"type": "disk",
- "pool": pool,
- "vol": vol}
- disk = inst.vmstorages_create(vm_name, disk_args)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count + 1, len(storage_list))
-
- # Check the bus type to be 'virtio'
- disk_info = inst.vmstorage_lookup(vm_name, disk)
- self.assertEquals(u'disk', disk_info['type'])
- self.assertEquals(vol_path, disk_info['path'])
- self.assertEquals(expect_bus, disk_info['bus'])
- return disk
-
- inst = model.Model(objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- path = os.path.join(TMP_DIR, 'kimchi-images')
- pool = 'test-pool'
- vol = 'test-volume.img'
- vol_path = "%s/%s" % (path, vol)
- if not os.path.exists(path):
- os.mkdir(path)
- rollback.prependDefer(shutil.rmtree, path)
-
- args = {'name': pool,
- 'path': path,
- 'type': 'dir'}
- inst.storagepools_create(args)
- rollback.prependDefer(inst.storagepool_delete, pool)
-
- # Activate the pool before adding any volume
- inst.storagepool_activate(pool)
- rollback.prependDefer(inst.storagepool_deactivate, pool)
-
- params = {'name': vol,
- 'capacity': 1073741824, # 1 GiB
- 'allocation': 536870912, # 512 MiB
- 'format': 'qcow2'}
- task_id = inst.storagevolumes_create(pool, params)['id']
- rollback.prependDefer(inst.storagevolume_delete, pool, vol)
- inst.task_wait(task_id)
-
- vm_name = 'kimchi-cdrom'
- params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
- params = {'name': vm_name,
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params)
- inst.task_wait(task1['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- prev_count = len(inst.vmstorages_get_list(vm_name))
- self.assertEquals(1, prev_count)
-
- # Volume format with mismatched type raise error
- cdrom_args = {"type": "cdrom", "pool": pool, "vol": vol}
- self.assertRaises(InvalidParameter, inst.vmstorages_create,
- vm_name, cdrom_args)
-
- # Cold plug and unplug a disk
- disk = _attach_disk()
- inst.vmstorage_delete(vm_name, disk)
-
- # Hot plug a disk
- inst.vm_start(vm_name)
- disk = _attach_disk()
-
- # VM disk still there after powered off
- inst.vm_poweroff(vm_name)
- disk_info = inst.vmstorage_lookup(vm_name, disk)
- self.assertEquals(u'disk', disk_info['type'])
- inst.vmstorage_delete(vm_name, disk)
-
- # Specifying pool and path at same time will fail
- disk_args = {"type": "disk",
- "pool": pool,
- "vol": vol,
- "path": disk_path}
- self.assertRaises(
- InvalidParameter, inst.vmstorages_create, vm_name, disk_args)
-
- old_distro_iso = TMP_DIR + 'rhel4_8.iso'
- iso_gen.construct_fake_iso(old_distro_iso, True, '4.8', 'rhel')
-
- vm_name = 'kimchi-ide-bus-vm'
- params = {'name': 'old_distro_template', 'disks': [],
- 'cdrom': old_distro_iso}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'old_distro_template')
- params = {
- 'name': vm_name,
- 'template': '/plugins/kimchi/templates/old_distro_template'
- }
- task2 = inst.vms_create(params)
- inst.task_wait(task2['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- # Need to check the right disk_bus for old distro
- disk = _attach_disk(get_template_default('old', 'disk_bus'))
- inst.vmstorage_delete('kimchi-ide-bus-vm', disk)
-
- # Hot plug IDE bus disk does not work
- inst.vm_start(vm_name)
- self.assertRaises(InvalidOperation, _attach_disk)
- inst.vm_poweroff(vm_name)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_cdrom(self):
- inst = model.Model(objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- vm_name = 'kimchi-cdrom'
- params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
- params = {'name': vm_name,
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- prev_count = len(inst.vmstorages_get_list(vm_name))
- self.assertEquals(1, prev_count)
-
- # dummy .iso files
- iso_path = os.path.join(TMP_DIR, 'existent.iso')
- iso_path2 = os.path.join(TMP_DIR, 'existent2.iso')
- open(iso_path, 'w').close()
- rollback.prependDefer(os.remove, iso_path)
- open(iso_path2, 'w').close()
- rollback.prependDefer(os.remove, iso_path2)
- wrong_iso_path = '/nonexistent.iso'
-
- # Create a cdrom
- cdrom_args = {"type": "cdrom",
- "path": iso_path}
- cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count + 1, len(storage_list))
-
- # Get cdrom info
- cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(u'cdrom', cd_info['type'])
- self.assertEquals(iso_path, cd_info['path'])
-
- # update path of existing cd with
- # non existent iso
- self.assertRaises(InvalidParameter, inst.vmstorage_update,
- vm_name, cdrom_dev, {'path': wrong_iso_path})
-
- # Make sure CD ROM still exists after failure
- cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(u'cdrom', cd_info['type'])
- self.assertEquals(iso_path, cd_info['path'])
-
- # update path of existing cd with existent iso of shutoff vm
- inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path2})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(iso_path2, cdrom_info['path'])
-
- # update path of existing cd with existent iso of running vm
- inst.vm_start(vm_name)
- inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(iso_path, cdrom_info['path'])
-
- # eject cdrom
- cdrom_dev = inst.vmstorage_update(vm_name, cdrom_dev, {'path': ''})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals('', cdrom_info['path'])
- inst.vm_poweroff(vm_name)
-
- # removing non existent cdrom
- self.assertRaises(NotFoundError, inst.vmstorage_delete, vm_name,
- "fakedev")
-
- # removing valid cdrom
- inst.vmstorage_delete(vm_name, cdrom_dev)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count, len(storage_list))
-
- # Create a new cdrom using a remote iso
- valid_remote_iso_path = utils.get_remote_iso_path()
- cdrom_args = {"type": "cdrom",
- "path": valid_remote_iso_path}
- cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count + 1, len(storage_list))
-
- # Update remote-backed cdrom with the same ISO
- inst.vmstorage_update(vm_name, cdrom_dev,
- {'path': valid_remote_iso_path})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- cur_cdrom_path = re.sub(":80/", '/', cdrom_info['path'])
- self.assertEquals(valid_remote_iso_path, cur_cdrom_path)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_storage_provisioning(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {'name': 'test', 'disks': [{'size': 1}],
- 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'test-vm-1',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'test-vm-1')
-
- vm_info = inst.vm_lookup(params['name'])
- disk_path = '%s/%s-0.img' % (
- inst.storagepool_lookup('default')['path'], vm_info['uuid'])
- self.assertTrue(os.access(disk_path, os.F_OK))
- self.assertFalse(os.access(disk_path, os.F_OK))
-
- def test_vm_memory_hotplug(self):
- config.set("authentication", "method", "pam")
- inst = model.Model(None, objstore_loc=self.tmp_store)
- orig_params = {'name': 'test', 'memory': 1024, 'cdrom': UBUNTU_ISO}
- inst.templates_create(orig_params)
-
- with RollbackContext() as rollback:
- params = {'name': 'kimchi-vm1',
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params)
- inst.task_wait(task1['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm1')
- # Start vm
- inst.vm_start('kimchi-vm1')
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
- 'kimchi-vm1')
-
- # Hotplug memory, only available in Libvirt >= 1.2.14
- params = {'memory': 2048}
- if inst.capabilities_lookup()['mem_hotplug_support']:
- inst.vm_update('kimchi-vm1', params)
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm1')
- self.assertEquals(params['memory'],
- inst.vm_lookup('kimchi-vm1')['memory'])
- else:
- self.assertRaises(InvalidOperation, inst.vm_update,
- 'kimchi-vm1', params)
-
- def test_vm_edit(self):
- config.set("authentication", "method", "pam")
- inst = model.Model(None,
- objstore_loc=self.tmp_store)
-
- orig_params = {'name': 'test', 'memory': 1024, 'cpus': 1,
- 'cdrom': UBUNTU_ISO}
- inst.templates_create(orig_params)
-
- with RollbackContext() as rollback:
- params_1 = {'name': 'kimchi-vm1',
- 'template': '/plugins/kimchi/templates/test'}
- params_2 = {'name': 'kimchi-vm2',
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params_1)
- inst.task_wait(task1['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm1')
- task2 = inst.vms_create(params_2)
- inst.task_wait(task2['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm2')
-
- vms = inst.vms_get_list()
- self.assertTrue('kimchi-vm1' in vms)
-
- # make sure "vm_update" works when the domain has a snapshot
- inst.vmsnapshots_create(u'kimchi-vm1')
-
- # update vm graphics when vm is not running
- inst.vm_update(u'kimchi-vm1',
- {"graphics": {"passwd": "123456"}})
-
- inst.vm_start('kimchi-vm1')
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
- 'kimchi-vm1')
-
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals('123456', vm_info['graphics']["passwd"])
- self.assertEquals(None, vm_info['graphics']["passwdValidTo"])
-
- # update vm graphics when vm is running
- inst.vm_update(u'kimchi-vm1',
- {"graphics": {"passwd": "abcdef",
- "passwdValidTo": 20}})
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals('abcdef', vm_info['graphics']["passwd"])
- self.assertGreaterEqual(20, vm_info['graphics']['passwdValidTo'])
-
- info = inst.vm_lookup('kimchi-vm1')
- self.assertEquals('running', info['state'])
-
- params = {'name': 'new-vm'}
- self.assertRaises(InvalidParameter, inst.vm_update,
- 'kimchi-vm1', params)
-
- # change VM users and groups, when wm is running.
- inst.vm_update(u'kimchi-vm1',
- {'users': ['root'], 'groups': ['root']})
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals(['root'], vm_info['users'])
- self.assertEquals(['root'], vm_info['groups'])
- # change VM users and groups by removing all elements,
- # when wm is running.
- inst.vm_update(u'kimchi-vm1', {'users': [], 'groups': []})
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals([], vm_info['users'])
- self.assertEquals([], vm_info['groups'])
-
- inst.vm_poweroff('kimchi-vm1')
- self.assertRaises(OperationFailed, inst.vm_update,
- 'kimchi-vm1', {'name': 'kimchi-vm2'})
-
- params = {'name': u'пeÏ-â¨Ð¼', 'cpus': 4, 'memory': 2048}
- inst.vm_update('kimchi-vm1', params)
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- u'пeÏ-â¨Ð¼')
- self.assertEquals(info['uuid'], inst.vm_lookup(u'пeÏ-â¨Ð¼')['uuid'])
- info = inst.vm_lookup(u'пeÏ-â¨Ð¼')
- for key in params.keys():
- self.assertEquals(params[key], info[key])
-
- # change only VM users - groups are not changed (default is empty)
- users = inst.users_get_list()[:3]
- inst.vm_update(u'пeÏ-â¨Ð¼', {'users': users})
- self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
- self.assertEquals([], inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
-
- # change only VM groups - users are not changed (default is empty)
- groups = inst.groups_get_list()[:2]
- inst.vm_update(u'пeÏ-â¨Ð¼', {'groups': groups})
- self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
- self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
-
- # change VM users and groups by adding a new element to each one
- users.append(pwd.getpwuid(os.getuid()).pw_name)
- groups.append(grp.getgrgid(os.getgid()).gr_name)
- inst.vm_update(u'пeÏ-â¨Ð¼', {'users': users, 'groups': groups})
- self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
- self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
-
- # change VM users (wrong value) and groups
- # when an error occurs, everything fails and nothing is changed
- self.assertRaises(InvalidParameter, inst.vm_update, u'пeÏ-â¨Ð¼',
- {'users': ['userdoesnotexist'], 'groups': []})
- self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
- self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
-
- # change VM users and groups (wrong value)
- # when an error occurs, everything fails and nothing is changed
- self.assertRaises(InvalidParameter, inst.vm_update, u'пeÏ-â¨Ð¼',
- {'users': [], 'groups': ['groupdoesnotexist']})
- self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
- self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
-
- # change VM users and groups by removing all elements
- inst.vm_update(u'пeÏ-â¨Ð¼', {'users': [], 'groups': []})
- self.assertEquals([], inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
- self.assertEquals([], inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
-
- def test_get_interfaces(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
- expected_ifaces = netinfo.all_favored_interfaces()
- ifaces = inst.interfaces_get_list()
- self.assertEquals(len(expected_ifaces), len(ifaces))
- for name in expected_ifaces:
- iface = inst.interface_lookup(name)
- self.assertEquals(iface['name'], name)
- self.assertIn('type', iface)
- self.assertIn('status', iface)
- self.assertIn('ipaddr', iface)
- self.assertIn('netmask', iface)
-
- def test_async_tasks(self):
- class task_except(Exception):
- pass
-
- def quick_op(cb, message):
- cb(message, True)
-
- def long_op(cb, params):
- time.sleep(params.get('delay', 3))
- cb(params.get('message', ''), params.get('result', False))
-
- def abnormal_op(cb, params):
- try:
- raise task_except
- except:
- cb("Exception raised", False)
-
- def continuous_ops(cb, params):
- cb("step 1 OK")
- time.sleep(2)
- cb("step 2 OK")
- time.sleep(2)
- cb("step 3 OK", params.get('result', True))
-
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
- taskid = add_task('', quick_op, inst.objstore, 'Hello')
- inst.task_wait(taskid)
- self.assertEquals(1, taskid)
- self.assertEquals('finished', inst.task_lookup(taskid)['status'])
- self.assertEquals('Hello', inst.task_lookup(taskid)['message'])
-
- taskid = add_task('', long_op, inst.objstore,
- {'delay': 3, 'result': False,
- 'message': 'It was not meant to be'})
- self.assertEquals(2, taskid)
- self.assertEquals('running', inst.task_lookup(taskid)['status'])
- self.assertEquals('OK', inst.task_lookup(taskid)['message'])
- inst.task_wait(taskid)
- self.assertEquals('failed', inst.task_lookup(taskid)['status'])
- self.assertEquals('It was not meant to be',
- inst.task_lookup(taskid)['message'])
- taskid = add_task('', abnormal_op, inst.objstore, {})
- inst.task_wait(taskid)
- self.assertEquals('Exception raised',
- inst.task_lookup(taskid)['message'])
- self.assertEquals('failed', inst.task_lookup(taskid)['status'])
-
- taskid = add_task('', continuous_ops, inst.objstore,
- {'result': True})
- self.assertEquals('running', inst.task_lookup(taskid)['status'])
- inst.task_wait(taskid, timeout=10)
- self.assertEquals('finished', inst.task_lookup(taskid)['status'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_delete_running_vm(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {'name': u'test', 'disks': [], 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': u'kīмÑhÄ«-â¨Ð¼',
- 'template': u'/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- u'kīмÑhÄ«-â¨Ð¼')
-
- inst.vm_start(u'kīмÑhÄ«-â¨Ð¼')
- self.assertEquals(inst.vm_lookup(u'kīмÑhÄ«-â¨Ð¼')['state'], 'running')
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
- u'kīмÑhÄ«-â¨Ð¼')
-
- inst.vm_delete(u'kīмÑhÄ«-â¨Ð¼')
-
- vms = inst.vms_get_list()
- self.assertFalse(u'kīмÑhÄ«-â¨Ð¼' in vms)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_list_sorted(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
-
- vms = inst.vms_get_list()
-
- self.assertEquals(vms, sorted(vms, key=unicode.lower))
-
- def test_vm_clone(self):
- inst = model.Model('test:///default', objstore_loc=self.tmp_store)
-
- all_vm_names = inst.vms_get_list()
- name = all_vm_names[0]
-
- original_vm = inst.vm_lookup(name)
- if original_vm['state'] == u'shutoff':
- inst.vm_start(name)
-
- # the VM 'test' should be running by now, so we can't clone it yet
- self.assertRaises(InvalidParameter, inst.vm_clone, name)
-
- with RollbackContext() as rollback:
- inst.vm_poweroff(name)
- rollback.prependDefer(inst.vm_start, name)
-
- # create two simultaneous clones of the same VM
- # and make sure both of them complete successfully
- task1 = inst.vm_clone(name)
- task2 = inst.vm_clone(name)
- clone1_name = task1['target_uri'].split('/')[-2]
- rollback.prependDefer(inst.vm_delete, clone1_name)
- clone2_name = task2['target_uri'].split('/')[-2]
- rollback.prependDefer(inst.vm_delete, clone2_name)
- inst.task_wait(task1['id'])
- task1 = inst.task_lookup(task1['id'])
- self.assertEquals('finished', task1['status'])
- inst.task_wait(task2['id'])
- task2 = inst.task_lookup(task2['id'])
- self.assertEquals('finished', task2['status'])
-
- # update the original VM info because its state has changed
- original_vm = inst.vm_lookup(name)
- clone_vm = inst.vm_lookup(clone1_name)
-
- self.assertNotEqual(original_vm['name'], clone_vm['name'])
- self.assertTrue(re.match(u'%s-clone-\d+' % original_vm['name'],
- clone_vm['name']))
- del original_vm['name']
- del clone_vm['name']
-
- self.assertNotEqual(original_vm['uuid'], clone_vm['uuid'])
- del original_vm['uuid']
- del clone_vm['uuid']
-
- # compare all VM settings except the ones already compared
- # (and removed) above (i.e. 'name' and 'uuid')
- self.assertEquals(original_vm, clone_vm)
-
- def test_use_test_host(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {
- 'name': 'test',
- 'disks': [],
- 'cdrom': UBUNTU_ISO,
- 'storagepool': '/plugins/kimchi/storagepools/default-pool',
- 'domain': 'test',
- 'arch': 'i686'
- }
-
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
-
- vms = inst.vms_get_list()
-
- self.assertTrue('kimchi-vm' in vms)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_debug_reports(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- if not inst.capabilities_lookup()['system_report_tool']:
- raise unittest.SkipTest("Without debug report tool")
-
- try:
- timeout = int(os.environ['TEST_REPORT_TIMEOUT'])
- except (ValueError, KeyError):
- timeout = 120
-
- namePrefix = 'unitTestReport'
- # sosreport always deletes unsual letters like '-' and '_' in the
- # generated report file name.
- uuidstr = str(uuid.uuid4()).translate(None, "-_")
- reportName = namePrefix + uuidstr
- try:
- inst.debugreport_delete(namePrefix + '*')
- except NotFoundError:
- pass
- with RollbackContext() as rollback:
- report_list = inst.debugreports_get_list()
- self.assertFalse(reportName in report_list)
- try:
- tmp_name = reportName + "_1"
- task = inst.debugreports_create({'name': reportName})
- rollback.prependDefer(inst.debugreport_delete, tmp_name)
- taskid = task['id']
- inst.task_wait(taskid, timeout)
- self.assertEquals('finished',
- inst.task_lookup(taskid)['status'],
- "It is not necessary an error. "
- "You may need to increase the "
- "timeout number by "
- "TEST_REPORT_TIMEOUT=200 "
- "./run_tests.sh test_model")
- report_list = inst.debugreports_get_list()
- self.assertTrue(reportName in report_list)
- name = inst.debugreport_update(reportName, {'name': tmp_name})
- self.assertEquals(name, tmp_name)
- report_list = inst.debugreports_get_list()
- self.assertTrue(tmp_name in report_list)
- except OperationFailed, e:
- if 'debugreport tool not found' not in e.message:
- raise e
-
- def test_get_distros(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
- distros = inst.distros_get_list()
- for d in distros:
- distro = inst.distro_lookup(d)
- self.assertIn('name', distro)
- self.assertIn('os_distro', distro)
- self.assertIn('os_version', distro)
- self.assertIn('os_arch', distro)
- self.assertIn('path', distro)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_deep_scan(self):
- inst = model.Model(None,
- objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- deep_path = os.path.join(TMP_DIR, 'deep-scan')
- subdir_path = os.path.join(deep_path, 'isos')
- if not os.path.exists(subdir_path):
- os.makedirs(subdir_path)
- ubuntu_iso = os.path.join(deep_path, 'ubuntu12.04.iso')
- sles_iso = os.path.join(subdir_path, 'sles10.iso')
- iso_gen.construct_fake_iso(ubuntu_iso, True, '12.04', 'ubuntu')
- iso_gen.construct_fake_iso(sles_iso, True, '10', 'sles')
-
- args = {'name': 'kimchi-scanning-pool',
- 'path': deep_path,
- 'type': 'kimchi-iso'}
- inst.storagepools_create(args)
- rollback.prependDefer(shutil.rmtree, deep_path)
- rollback.prependDefer(shutil.rmtree, args['path'])
- rollback.prependDefer(inst.storagepool_deactivate, args['name'])
-
- time.sleep(1)
- volumes = inst.storagevolumes_get_list(args['name'])
- self.assertEquals(len(volumes), 2)
-
- def test_repository_create(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- yum_repos = [{'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'},
- {'repo_id': 'fedora-updates-fake',
- 'config':
- {'mirrorlist': 'http://www.fedoraproject.org'}}]
-
- deb_repos = [{'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal'}},
- {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal', 'comps': ['main']}}]
-
- yum_invalid_repos = []
- deb_invalid_repos = []
-
- for url in invalid_repository_urls:
- wrong_baseurl = {'repo_id': 'wrong-id', 'baseurl': url}
- wrong_mirrorlist = {'repo_id': 'wrong-id',
- 'baseurl': 'www.example.com',
- 'config': {'mirrorlist': url}}
- wrong_config_item = {
- 'repo_id': 'wrong-id',
- 'baseurl': 'www.example.com',
- 'config': {
- 'gpgkey': 'file:///tmp/KEY-fedora-updates-fake-19'}}
-
- yum_invalid_repos.append(wrong_baseurl)
- yum_invalid_repos.append(wrong_mirrorlist)
- yum_invalid_repos.append(wrong_config_item)
-
- wrong_baseurl['config'] = {'dist': 'tasty'}
- wrong_config = {'baseurl': deb_repos[0]['baseurl'],
- 'config': {
- 'unsupported_item': "a_unsupported_item"}}
- deb_invalid_repos.append(wrong_baseurl)
- deb_invalid_repos.append(wrong_config)
-
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- if repo_type == 'yum':
- test_repos = yum_repos
- invalid_repos = yum_invalid_repos
- elif repo_type == 'deb':
- test_repos = deb_repos
- invalid_repos = deb_invalid_repos
- else:
- # repository management tool was not recognized by Kimchi
- # skip test case
- return
-
- # create repositories with invalid data
- for repo in invalid_repos:
- self.assertRaises(InvalidParameter, inst.repositories_create, repo)
-
- for repo in test_repos:
- system_host_repos = len(inst.repositories_get_list())
- repo_id = inst.repositories_create(repo)
- host_repos = inst.repositories_get_list()
- self.assertEquals(system_host_repos + 1, len(host_repos))
-
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(repo_id, repo_info['repo_id'])
- self.assertEquals(True, repo_info.get('enabled'))
- self.assertEquals(repo.get('baseurl', ''),
- repo_info.get('baseurl'))
-
- original_config = repo.get('config', {})
- config_info = repo_info.get('config', {})
-
- if repo_type == 'yum':
- self.assertEquals(original_config.get('mirrorlist', ''),
- config_info.get('mirrorlist', ''))
- self.assertEquals(True, config_info['gpgcheck'])
- else:
- self.assertEquals(original_config['dist'], config_info['dist'])
- self.assertEquals(original_config.get('comps', []),
- config_info.get('comps', []))
-
- inst.repository_delete(repo_id)
- self.assertRaises(NotFoundError, inst.repository_lookup, repo_id)
-
- self.assertRaises(NotFoundError, inst.repository_lookup, 'google')
-
- def test_repository_update(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- yum_repo = {'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'}
- yum_new_repo = {'baseurl': 'http://www.fedoraproject.org'}
-
- deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal'}}
- deb_new_repo = {'baseurl': 'http://br.archive.canonical.com/ubuntu/',
- 'config': {'dist': 'utopic'}}
-
- yum_invalid_repos = []
- deb_invalid_repos = []
-
- for url in invalid_repository_urls:
- wrong_baseurl = {'baseurl': url}
- wrong_mirrorlist = {'baseurl': 'www.example.com',
- 'config': {'mirrorlist': url}}
-
- yum_invalid_repos.append(wrong_baseurl)
- yum_invalid_repos.append(wrong_mirrorlist)
-
- wrong_baseurl['config'] = {'dist': 'tasty'}
- deb_invalid_repos.append(wrong_baseurl)
-
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- if repo_type == 'yum':
- repo = yum_repo
- new_repo = yum_new_repo
- invalid_repos = yum_invalid_repos
- elif repo_type == 'deb':
- repo = deb_repo
- new_repo = deb_new_repo
- invalid_repos = deb_invalid_repos
- else:
- # repository management tool was not recognized by Kimchi
- # skip test case
- return
-
- system_host_repos = len(inst.repositories_get_list())
-
- with RollbackContext() as rollback:
- repo_id = inst.repositories_create(repo)
- rollback.prependDefer(inst.repository_delete, repo_id)
-
- host_repos = inst.repositories_get_list()
- self.assertEquals(system_host_repos + 1, len(host_repos))
-
- # update repositories with invalid data
- for tmp_repo in invalid_repos:
- self.assertRaises(InvalidParameter, inst.repository_update,
- repo_id, tmp_repo)
-
- new_repo_id = inst.repository_update(repo_id, new_repo)
- repo_info = inst.repository_lookup(new_repo_id)
-
- self.assertEquals(new_repo_id, repo_info['repo_id'])
- self.assertEquals(new_repo['baseurl'], repo_info['baseurl'])
- self.assertEquals(True, repo_info['enabled'])
- inst.repository_update(new_repo_id, repo)
-
- def test_repository_disable_enable(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- yum_repo = {'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'}
- deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal'}}
-
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- if repo_type == 'yum':
- repo = yum_repo
- elif repo_type == 'deb':
- repo = deb_repo
- else:
- # repository management tool was not recognized by Kimchi
- # skip test case
- return
-
- system_host_repos = len(inst.repositories_get_list())
-
- repo_id = inst.repositories_create(repo)
-
- host_repos = inst.repositories_get_list()
- self.assertEquals(system_host_repos + 1, len(host_repos))
-
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(True, repo_info['enabled'])
-
- inst.repository_disable(repo_id)
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(False, repo_info['enabled'])
-
- inst.repository_enable(repo_id)
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(True, repo_info['enabled'])
-
- # remove files creates
- inst.repository_delete(repo_id)
-
-
-class BaseModelTests(unittest.TestCase):
- class FoosModel(object):
- def __init__(self):
- self.data = {}
-
- def create(self, params):
- self.data.update(params)
-
- def get_list(self):
- return list(self.data)
-
- class TestModel(wok.basemodel.BaseModel):
- def __init__(self):
- foo = BaseModelTests.FoosModel()
- super(BaseModelTests.TestModel, self).__init__([foo])
-
- def test_root_model(self):
- t = BaseModelTests.TestModel()
- t.foos_create({'item1': 10})
- self.assertEquals(t.foos_get_list(), ['item1'])
diff --git a/plugins/kimchi/tests/test_model_network.py b/plugins/kimchi/tests/test_model_network.py
deleted file mode 100644
index e4cf5ef..0000000
--- a/plugins/kimchi/tests/test_model_network.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.model.model import Model
-
-from utils import get_free_port, patch_auth, request, rollback_wrapper
-from utils import run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = Model(None, '/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-def _do_network_test(self, model, params):
- with RollbackContext() as rollback:
- net_name = params['name']
- uri = '/plugins/kimchi/networks/%s' % net_name.encode('utf-8')
-
- # Create a network
- req = json.dumps(params)
- resp = self.request('/plugins/kimchi/networks', req, 'POST')
- rollback.prependDefer(rollback_wrapper, model.network_delete,
- net_name)
- self.assertEquals(201, resp.status)
-
- # Verify the network
- resp = self.request(uri)
- network = json.loads(resp.read())
- self.assertEquals('inactive', network['state'])
- self.assertTrue(network['persistent'])
-
- # activate the network
- resp = self.request(uri + '/activate', '{}', 'POST')
- rollback.prependDefer(rollback_wrapper,
- model.network_deactivate, net_name)
- self.assertEquals(200, resp.status)
- resp = self.request(uri)
- network = json.loads(resp.read())
- self.assertEquals('active', network['state'])
-
- # Deactivate the network
- resp = self.request(uri + '/deactivate', '{}', 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request(uri)
- network = json.loads(resp.read())
- self.assertEquals('inactive', network['state'])
-
- # Delete the network
- resp = self.request(uri, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
-
-class NetworkTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_get_networks(self):
- networks = json.loads(self.request('/plugins/kimchi/networks').read())
- self.assertIn('default', [net['name'] for net in networks])
-
- with RollbackContext() as rollback:
- # Now add a couple of Networks to the mock model
- for i in xrange(5):
- name = 'network-%i' % i
- req = json.dumps({'name': name,
- 'connection': 'nat',
- 'subnet': '127.0.10%i.0/24' % i})
-
- resp = self.request('/plugins/kimchi/networks', req, 'POST')
- rollback.prependDefer(model.network_delete, name)
- self.assertEquals(201, resp.status)
- network = json.loads(resp.read())
- self.assertEquals([], network["vms"])
-
- nets = json.loads(self.request('/plugins/kimchi/networks').read())
- self.assertEquals(len(networks) + 5, len(nets))
-
- network = json.loads(
- self.request('/plugins/kimchi/networks/network-1').read()
- )
- keys = [u'name', u'connection', u'interface', u'subnet', u'dhcp',
- u'vms', u'in_use', u'autostart', u'state', u'persistent']
- self.assertEquals(sorted(keys), sorted(network.keys()))
-
- def test_network_lifecycle(self):
- # Verify all the supported network type
- networks = [{'name': u'kīмÑhÄ«-пet', 'connection': 'isolated'},
- {'name': u'nat-network', 'connection': 'nat'},
- {'name': u'subnet-network', 'connection': 'nat',
- 'subnet': '127.0.100.0/24'}]
-
- # Verify the current system has at least one interface to create a
- # bridged network
- interfaces = json.loads(
- self.request('/plugins/kimchi/interfaces?type=nic').read()
- )
- if len(interfaces) > 0:
- iface = interfaces[0]['name']
- networks.append({'name': u'bridge-network', 'connection': 'bridge',
- 'interface': iface})
-
- for net in networks:
- _do_network_test(self, model, net)
diff --git a/plugins/kimchi/tests/test_model_storagepool.py b/plugins/kimchi/tests/test_model_storagepool.py
deleted file mode 100644
index 5f9b966..0000000
--- a/plugins/kimchi/tests/test_model_storagepool.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import tempfile
-import unittest
-from functools import partial
-
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.model.model import Model
-
-from utils import get_free_port, patch_auth, request
-from utils import run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = Model(None, '/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class StoragepoolTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_get_storagepools(self):
- storagepools = json.loads(
- self.request('/plugins/kimchi/storagepools').read()
- )
- self.assertIn('default', [pool['name'] for pool in storagepools])
-
- with RollbackContext() as rollback:
- # Now add a couple of storage pools
- for i in xrange(3):
- name = u'kīмÑhÄ«-storagepool-%i' % i
- req = json.dumps({'name': name, 'type': 'dir',
- 'path': '/var/lib/libvirt/images/%i' % i})
- resp = self.request('/plugins/kimchi/storagepools', req,
- 'POST')
- rollback.prependDefer(model.storagepool_delete, name)
-
- self.assertEquals(201, resp.status)
-
- # Pool name must be unique
- req = json.dumps({'name': name, 'type': 'dir',
- 'path': '/var/lib/libvirt/images/%i' % i})
- resp = self.request('/plugins/kimchi/storagepools', req,
- 'POST')
- self.assertEquals(400, resp.status)
-
- # Verify pool information
- resp = self.request('/plugins/kimchi/storagepools/%s' %
- name.encode("utf-8"))
- p = json.loads(resp.read())
- keys = [u'name', u'state', u'capacity', u'allocated',
- u'available', u'path', u'source', u'type',
- u'nr_volumes', u'autostart', u'persistent']
- self.assertEquals(sorted(keys), sorted(p.keys()))
- self.assertEquals(name, p['name'])
- self.assertEquals('inactive', p['state'])
- self.assertEquals(True, p['persistent'])
- self.assertEquals(True, p['autostart'])
- self.assertEquals(0, p['nr_volumes'])
-
- pools = json.loads(
- self.request('/plugins/kimchi/storagepools').read()
- )
- self.assertEquals(len(storagepools) + 3, len(pools))
-
- # Create a pool with an existing path
- tmp_path = tempfile.mkdtemp(dir='/var/lib/kimchi')
- rollback.prependDefer(os.rmdir, tmp_path)
- req = json.dumps({'name': 'existing_path', 'type': 'dir',
- 'path': tmp_path})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- rollback.prependDefer(model.storagepool_delete, 'existing_path')
- self.assertEquals(201, resp.status)
-
- # Reserved pool return 400
- req = json.dumps({'name': 'kimchi_isos', 'type': 'dir',
- 'path': '/var/lib/libvirt/images/%i' % i})
- resp = request(host, ssl_port, '/plugins/kimchi/storagepools', req,
- 'POST')
- self.assertEquals(400, resp.status)
diff --git a/plugins/kimchi/tests/test_model_storagevolume.py b/plugins/kimchi/tests/test_model_storagevolume.py
deleted file mode 100644
index 46c07bd..0000000
--- a/plugins/kimchi/tests/test_model_storagevolume.py
+++ /dev/null
@@ -1,280 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import requests
-import unittest
-from functools import partial
-
-from wok.config import paths
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.config import READONLY_POOL_TYPE
-from wok.plugins.kimchi.mockmodel import MockModel
-from wok.plugins.kimchi.model.model import Model
-
-from utils import fake_auth_header, get_free_port, patch_auth, request
-from utils import rollback_wrapper, run_server, wait_task
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = Model(None, '/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-def _do_volume_test(self, model, host, ssl_port, pool_name):
- def _task_lookup(taskid):
- return json.loads(
- self.request('/tasks/%s' % taskid).read()
- )
-
- uri = '/plugins/kimchi/storagepools/%s/storagevolumes' \
- % pool_name.encode('utf-8')
- resp = self.request(uri)
- self.assertEquals(200, resp.status)
-
- resp = self.request('/plugins/kimchi/storagepools/%s' %
- pool_name.encode('utf-8'))
- pool_info = json.loads(resp.read())
- with RollbackContext() as rollback:
- # Create storage volume with 'capacity'
- vol = 'test-volume'
- vol_uri = uri + '/' + vol
- req = json.dumps({'name': vol, 'format': 'raw',
- 'capacity': 1073741824}) # 1 GiB
- resp = self.request(uri, req, 'POST')
- if pool_info['type'] in READONLY_POOL_TYPE:
- self.assertEquals(400, resp.status)
- else:
- rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
- pool_name, vol)
- self.assertEquals(202, resp.status)
- task_id = json.loads(resp.read())['id']
- wait_task(_task_lookup, task_id)
- status = json.loads(
- self.request('/tasks/%s' % task_id).read()
- )
- self.assertEquals('finished', status['status'])
- vol_info = json.loads(self.request(vol_uri).read())
- vol_info['name'] = vol
- vol_info['format'] = 'raw'
- vol_info['capacity'] = 1073741824
-
- # Resize the storage volume: increase its capacity to 2 GiB
- req = json.dumps({'size': 2147483648}) # 2 GiB
- resp = self.request(vol_uri + '/resize', req, 'POST')
- self.assertEquals(200, resp.status)
- storagevolume = json.loads(self.request(vol_uri).read())
- self.assertEquals(2147483648, storagevolume['capacity'])
-
- # Resize the storage volume: decrease its capacity to 512 MiB
- # FIXME: Due a libvirt bug it is not possible to decrease the
- # volume capacity
- # For reference:
- # - https://bugzilla.redhat.com/show_bug.cgi?id=1021802
- req = json.dumps({'size': 536870912}) # 512 MiB
- resp = self.request(vol_uri + '/resize', req, 'POST')
- # It is only possible when using MockModel
- if isinstance(model, MockModel):
- self.assertEquals(200, resp.status)
- storagevolume = json.loads(self.request(vol_uri).read())
- self.assertEquals(536870912, storagevolume['capacity'])
- else:
- self.assertEquals(500, resp.status)
-
- # Wipe the storage volume
- resp = self.request(vol_uri + '/wipe', '{}', 'POST')
- self.assertEquals(200, resp.status)
- storagevolume = json.loads(self.request(vol_uri).read())
- self.assertEquals(0, storagevolume['allocation'])
-
- # Clone the storage volume
- vol_info = json.loads(self.request(vol_uri).read())
- resp = self.request(vol_uri + '/clone', '{}', 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- cloned_vol_name = task['target_uri'].split('/')[-1]
- rollback.prependDefer(model.storagevolume_delete, pool_name,
- cloned_vol_name)
- wait_task(_task_lookup, task['id'])
- task = json.loads(
- self.request('/tasks/%s' % task['id']).read()
- )
- self.assertEquals('finished', task['status'])
- resp = self.request(uri + '/' + cloned_vol_name.encode('utf-8'))
-
- self.assertEquals(200, resp.status)
- cloned_vol = json.loads(resp.read())
-
- self.assertNotEquals(vol_info['name'], cloned_vol['name'])
- self.assertNotEquals(vol_info['path'], cloned_vol['path'])
- for key in ['name', 'path', 'allocation']:
- del vol_info[key]
- del cloned_vol[key]
-
- self.assertEquals(vol_info, cloned_vol)
-
- # Delete the storage volume
- resp = self.request(vol_uri, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
- resp = self.request(vol_uri)
- self.assertEquals(404, resp.status)
-
- # Storage volume upload
- # It is done through a sequence of POST and several PUT requests
- filename = 'COPYING.LGPL'
- filepath = os.path.join(paths.get_prefix(), filename)
- filesize = os.stat(filepath).st_size
-
- # Create storage volume for upload
- req = json.dumps({'name': filename, 'format': 'raw',
- 'capacity': filesize, 'upload': True})
- resp = self.request(uri, req, 'POST')
- if pool_info['type'] in READONLY_POOL_TYPE:
- self.assertEquals(400, resp.status)
- else:
- rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
- pool_name, filename)
- self.assertEquals(202, resp.status)
- task_id = json.loads(resp.read())['id']
- wait_task(_task_lookup, task_id)
- status = json.loads(self.request('/tasks/%s' %
- task_id).read())
- self.assertEquals('ready for upload', status['message'])
-
- # Upload volume content
- url = 'https://%s:%s' % (host, ssl_port) + uri + '/' + filename
-
- # Create a file with 5M to upload
- # Max body size is set to 4M so the upload will fail with 413
- newfile = '/tmp/5m-file'
- with open(newfile, 'wb') as fd:
- fd.seek(5*1024*1024-1)
- fd.write("\0")
- rollback.prependDefer(os.remove, newfile)
-
- with open(newfile, 'rb') as fd:
- with open(newfile + '.tmp', 'wb') as tmp_fd:
- data = fd.read()
- tmp_fd.write(data)
-
- with open(newfile + '.tmp', 'rb') as tmp_fd:
- r = requests.put(url, data={'chunk_size': len(data)},
- files={'chunk': tmp_fd},
- verify=False,
- headers=fake_auth_header())
- self.assertEquals(r.status_code, 413)
-
- # Do upload
- index = 0
- chunk_size = 2 * 1024
- content = ''
-
- with open(filepath, 'rb') as fd:
- while True:
- with open(filepath + '.tmp', 'wb') as tmp_fd:
- fd.seek(index*chunk_size)
- data = fd.read(chunk_size)
- tmp_fd.write(data)
-
- with open(filepath + '.tmp', 'rb') as tmp_fd:
- r = requests.put(url, data={'chunk_size': len(data)},
- files={'chunk': tmp_fd},
- verify=False,
- headers=fake_auth_header())
- self.assertEquals(r.status_code, 200)
- content += data
- index = index + 1
-
- if len(data) < chunk_size:
- break
-
- rollback.prependDefer(os.remove, filepath + '.tmp')
- resp = self.request(uri + '/' + filename)
- self.assertEquals(200, resp.status)
- uploaded_path = json.loads(resp.read())['path']
- with open(uploaded_path) as fd:
- uploaded_content = fd.read()
-
- self.assertEquals(content, uploaded_content)
-
- # Create storage volume with 'url'
- url = 'https://github.com/kimchi-project/kimchi/raw/master/COPYING'
- req = json.dumps({'url': url})
- resp = self.request(uri, req, 'POST')
-
- if pool_info['type'] in READONLY_POOL_TYPE:
- self.assertEquals(400, resp.status)
- else:
- rollback.prependDefer(model.storagevolume_delete, pool_name,
- 'COPYING')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(_task_lookup, task['id'])
- resp = self.request(uri + '/COPYING')
- self.assertEquals(200, resp.status)
-
-
-class StorageVolumeTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_get_storagevolume(self):
- uri = '/plugins/kimchi/storagepools/default/storagevolumes'
- resp = self.request(uri)
- self.assertEquals(200, resp.status)
-
- keys = [u'name', u'type', u'capacity', u'allocation', u'path',
- u'used_by', u'format']
- for vol in json.loads(resp.read()):
- resp = self.request(uri + '/' + vol['name'])
- self.assertEquals(200, resp.status)
-
- all_keys = keys[:]
- vol_info = json.loads(resp.read())
- if vol_info['format'] == 'iso':
- all_keys.extend([u'os_distro', u'os_version', u'bootable'])
-
- self.assertEquals(sorted(all_keys), sorted(vol_info.keys()))
-
- def test_storagevolume_action(self):
- _do_volume_test(self, model, host, ssl_port, 'default')
diff --git a/plugins/kimchi/tests/test_networkxml.py b/plugins/kimchi/tests/test_networkxml.py
deleted file mode 100644
index a64b6c2..0000000
--- a/plugins/kimchi/tests/test_networkxml.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ipaddr
-import lxml.etree as ET
-import unittest
-
-from wok.xmlutils.utils import xpath_get_text
-
-from wok.plugins.kimchi.xmlutils import network as nxml
-
-import utils
-
-
-class NetworkXmlTests(unittest.TestCase):
- def test_dhcp_xml(self):
- """
- Test network dhcp xml
- """
- dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"}
- host1 = {"mac": "00:16:3e:77:e2:ed",
- "name": "foo.example.com",
- "ip": "192.168.122.10"}
- host2 = {"mac": "00:16:3e:3e:a9:1a",
- "name": "bar.example.com",
- "ip": "192.168.122.11"}
- params = {}
-
- dhcp = nxml._get_dhcp_elem(**params)
- self.assertEquals(None, dhcp)
-
- params["range"] = dhcp_range
- xml = ET.tostring(nxml._get_dhcp_elem(**params))
- start = xpath_get_text(xml, "/dhcp/range/@start")
- end = xpath_get_text(xml, "/dhcp/range/@end")
- self.assertEquals(dhcp_range['start'], start[0])
- self.assertEquals(dhcp_range['end'], end[0])
-
- params["hosts"] = [host1, host2]
- xml = ET.tostring(nxml._get_dhcp_elem(**params))
- ip = xpath_get_text(xml, "/dhcp/host/@ip")
- self.assertEquals(ip, [host1['ip'], host2['ip']])
-
- def test_ip_xml(self):
- """
- Test network ip xml
- """
- dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"}
- params = {}
-
- dhcp = nxml._get_dhcp_elem(**params)
- self.assertEquals(None, dhcp)
-
- params["net"] = "192.168.122.0/255.255.255.0"
- params["dhcp"] = {'range': dhcp_range}
- xml = ET.tostring(nxml._get_ip_elem(**params))
- start = xpath_get_text(xml, "/ip/dhcp/range/@start")[0]
- end = xpath_get_text(xml, "/ip/dhcp/range/@end")[0]
- self.assertEquals(dhcp_range['start'], start)
- self.assertEquals(dhcp_range['end'], end)
-
- address = xpath_get_text(xml, "/ip/@address")[0]
- netmask = xpath_get_text(xml, "/ip/@netmask")[0]
- self.assertEquals(address, params["net"].split("/")[0])
- self.assertEquals(netmask, params["net"].split("/")[1])
-
- # test _get_ip_xml can accepts strings: '192.168.122.0/24',
- # which is same as "192.168.122.0/255.255.255.0"
- params["net"] = "192.168.122.0/24"
- xml = ET.tostring(nxml._get_ip_elem(**params))
- netmask = xpath_get_text(xml, "/ip/@netmask")[0]
- self.assertEquals(netmask,
- str(ipaddr.IPNetwork(params["net"]).netmask))
-
- def test_forward_xml(self):
- """
- Test network forward xml
- """
- params = {"mode": None}
-
- forward = nxml._get_forward_elem(**params)
- self.assertEquals(None, forward)
-
- params["mode"] = 'nat'
- params["dev"] = 'eth0'
- xml = ET.tostring(nxml._get_forward_elem(**params))
- mode = xpath_get_text(xml, "/forward/@mode")[0]
- dev = xpath_get_text(xml, "/forward/@dev")[0]
- self.assertEquals(params['mode'], mode)
- self.assertEquals(params['dev'], dev)
-
- def test_network_xml(self):
- """
- Test network xml
- """
- params = {"name": "test",
- "forward": {"mode": "nat", "dev": ""},
- "net": "192.168.0.0/255.255.255.0"}
- xml = nxml.to_network_xml(**params)
- name = xpath_get_text(xml, "/network/name")[0]
- self.assertEquals(name, params['name'])
-
- forward_mode = xpath_get_text(xml, "/network/forward/@mode")[0]
- self.assertEquals(forward_mode, params['forward']['mode'])
- forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
- self.assertEquals(forward_dev, '')
-
- address = xpath_get_text(xml, "/network/ip/@address")[0]
- self.assertEquals(address, params["net"].split("/")[0])
- netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
- self.assertEquals(netmask, params["net"].split("/")[1])
-
- dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
- self.assertEquals(dhcp_start, [])
- dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
- self.assertEquals(dhcp_end, [])
-
- # test optional params
- params['forward']['dev'] = "eth0"
- params['dhcp'] = {"range": {'start': '192.168.0.1',
- 'end': '192.168.0.254'}}
- xml = nxml.to_network_xml(**params)
- forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
- self.assertEquals(forward_dev, params['forward']['dev'])
-
- dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")[0]
- self.assertEquals(dhcp_start, params['dhcp']['range']['start'])
- dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")[0]
- self.assertEquals(dhcp_end, params['dhcp']['range']['end'])
-
- # test _get_ip_xml can accepts strings: '192.168.122.0/24',
- # which is same as "192.168.122.0/255.255.255.0"
- params["net"] = "192.168.0.0/24"
- xml = nxml.to_network_xml(**params)
- netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
- self.assertEquals(netmask,
- str(ipaddr.IPNetwork(params["net"]).netmask))
-
-
-class InterfaceXmlTests(unittest.TestCase):
-
- def test_vlan_tagged_bridge_no_ip(self):
- expected_xml = """
- <interface type='bridge' name='br10'>
- <start mode='onboot'/>
- <bridge>
- <interface type='vlan' name='em1.10'>
- <vlan tag='10'>
- <interface name='em1'/>
- </vlan>
- </interface>
- </bridge>
- </interface>
- """
- actual_xml = nxml.create_vlan_tagged_bridge_xml('br10', 'em1', '10')
- self.assertEquals(actual_xml, utils.normalize_xml(expected_xml))
diff --git a/plugins/kimchi/tests/test_objectstore.py b/plugins/kimchi/tests/test_objectstore.py
deleted file mode 100644
index 632786f..0000000
--- a/plugins/kimchi/tests/test_objectstore.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import tempfile
-import threading
-import unittest
-
-from wok import objectstore
-from wok.exception import NotFoundError
-
-
-tmpfile = None
-
-
-def setUpModule():
- global tmpfile
- tmpfile = tempfile.mktemp()
-
-
-def tearDownModule():
- os.unlink(tmpfile)
-
-
-class ObjectStoreTests(unittest.TestCase):
- def test_objectstore(self):
- store = objectstore.ObjectStore(tmpfile)
-
- with store as session:
- # Test create
- session.store('fÇÇ', 'tÄst1', {'α': 1})
- session.store('fÇÇ', 'tÄst2', {'β': 2})
-
- # Test list
- items = session.get_list('fÇÇ')
- self.assertTrue(u'tÄst1' in items)
- self.assertTrue(u'tÄst2' in items)
-
- # Test get
- item = session.get('fÇÇ', 'tÄst1')
- self.assertEquals(1, item[u'α'])
-
- # Test delete
- session.delete('fÇÇ', 'tÄst2')
- self.assertEquals(1, len(session.get_list('fÇÇ')))
-
- # Test get non-existent item
-
- self.assertRaises(NotFoundError, session.get,
- 'α', 'β')
-
- # Test delete non-existent item
- self.assertRaises(NotFoundError, session.delete,
- 'fÇÇ', 'tÄst2')
-
- # Test refresh existing item
- session.store('fÇÇ', 'tÄst1', {'α': 2})
- item = session.get('fÇÇ', 'tÄst1')
- self.assertEquals(2, item[u'α'])
-
- def test_object_store_threaded(self):
- def worker(ident):
- with store as session:
- session.store('foo', ident, {})
-
- store = objectstore.ObjectStore(tmpfile)
-
- threads = []
- for i in xrange(50):
- t = threading.Thread(target=worker, args=(i,))
- t.setDaemon(True)
- t.start()
- threads.append(t)
-
- for t in threads:
- t.join()
-
- with store as session:
- self.assertEquals(50, len(session.get_list('foo')))
- self.assertEquals(10, len(store._connections.keys()))
diff --git a/plugins/kimchi/tests/test_osinfo.py b/plugins/kimchi/tests/test_osinfo.py
deleted file mode 100644
index bd2af58..0000000
--- a/plugins/kimchi/tests/test_osinfo.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-
-from wok.plugins.kimchi.osinfo import _get_arch, get_template_default, lookup
-from wok.plugins.kimchi.osinfo import modern_version_bases
-
-
-class OSInfoTests(unittest.TestCase):
- def test_default_lookup(self):
- entry = lookup(None, None)
- self.assertEquals('unknown', entry['os_distro'])
- self.assertEquals('unknown', entry['os_version'])
- self.assertEquals(['default'], entry['networks'])
-
- def test_old_distros(self):
- old_versions = {'debian': '5.0', 'ubuntu': '7.04', 'opensuse': '10.1',
- 'centos': '5.1', 'rhel': '5.1', 'fedora': '15'}
- for distro, version in old_versions.iteritems():
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('old', 'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('old', 'nic_model'))
-
- def test_modern_bases(self):
- for distro, version in modern_version_bases[_get_arch()].iteritems():
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('modern', 'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('modern', 'nic_model'))
-
- def test_modern_distros(self):
- # versions based on ppc64 modern distros
- modern_versions = {'ubuntu': '14.04', 'opensuse': '13.1',
- 'rhel': '6.5', 'fedora': '19', 'sles': '11sp3'}
- for distro, version in modern_versions.iteritems():
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('modern', 'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('modern', 'nic_model'))
-
- def test_lookup_unknown_distro_version_returns_old_distro(self):
- distro = 'unknown_distro'
- version = 'unknown_version'
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('old', 'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('old', 'nic_model'))
diff --git a/plugins/kimchi/tests/test_plugin.py b/plugins/kimchi/tests/test_plugin.py
deleted file mode 100644
index fc8e277..0000000
--- a/plugins/kimchi/tests/test_plugin.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.utils import get_enabled_plugins
-
-from wok.plugins.kimchi import mockmodel
-
-import utils
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port
-
- utils.patch_auth()
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = utils.get_free_port('http')
- ssl_port = utils.get_free_port('https')
- test_server = utils.run_server(host, port, ssl_port, test_mode=True,
- model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
- at unittest.skipUnless(
- 'sample' in [plugin for plugin, _config in get_enabled_plugins()],
- 'sample plugin is not enabled, skip this test!')
-class PluginTests(unittest.TestCase):
-
- def setUp(self):
- self.request = partial(utils.request, host, ssl_port)
-
- def _create_rectangle(self, name, length, width):
- req = json.dumps({'name': name, 'length': length, 'width': width})
- resp = self.request('/plugins/sample/rectangles', req, 'POST')
- return resp
-
- def _get_rectangle(self, name):
- resp = self.request('/plugins/sample/rectangles/%s' % name)
- return json.loads(resp.read())
-
- def _create_rectangle_and_assert(self, name, length, width):
- resp = self._create_rectangle(name, length, width)
- self.assertEquals(201, resp.status)
-
- rectangle = self._get_rectangle(name)
- self.assertEquals(rectangle['name'], name)
- self.assertEquals(rectangle['length'], length)
- self.assertEquals(rectangle['width'], width)
-
- def _get_rectangles_list(self):
- resp = self.request('/plugins/sample/rectangles')
- rectangles = json.loads(resp.read())
- name_list = [rectangle['name'] for rectangle in rectangles]
- return name_list
-
- def test_rectangles(self):
- # Create two new rectangles
- self._create_rectangle_and_assert('small', 10, 8)
- self._create_rectangle_and_assert('big', 20, 16)
-
- # Verify they're in the list
- name_list = self._get_rectangles_list()
- self.assertIn('small', name_list)
- self.assertIn('big', name_list)
-
- # Update the big rectangle.
- req = json.dumps({'length': 40, 'width': 30})
- resp = self.request('/plugins/sample/rectangles/big', req, 'PUT')
- self.assertEquals(200, resp.status)
- big = self._get_rectangle('big')
- self.assertEquals(big['length'], 40)
- self.assertEquals(big['width'], 30)
-
- # Delete two rectangles
- resp = self.request('/plugins/sample/rectangles/big', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
- resp = self.request('/plugins/sample/rectangles/small', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
- name_list = self._get_rectangles_list()
- self.assertEquals([], name_list)
-
- def test_bad_params(self):
- # Bad name
- resp = self._create_rectangle(1.0, 30, 40)
- self.assertEquals(400, resp.status)
-
- # Bad length value
- resp = self._create_rectangle('test', -10.0, 40)
- self.assertEquals(400, resp.status)
-
- # Missing param for width
- req = json.dumps({'name': 'nowidth', 'length': 40})
- resp = self.request('/plugins/sample/rectangles', req, 'POST')
- self.assertEquals(400, resp.status)
diff --git a/plugins/kimchi/tests/test_rest.py b/plugins/kimchi/tests/test_rest.py
deleted file mode 100644
index 243074e..0000000
--- a/plugins/kimchi/tests/test_rest.py
+++ /dev/null
@@ -1,1327 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import re
-import time
-import unittest
-import urllib2
-import urlparse
-from functools import partial
-
-from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task
-
-from wok.plugins.kimchi import mockmodel
-from wok.plugins.kimchi.osinfo import get_template_default
-
-import iso_gen
-from utils import get_free_port, patch_auth, request
-from utils import run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-fake_iso = '/tmp/fake.iso'
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
- # Create fake ISO to do the tests
- iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
- iso_gen.construct_fake_iso("/var/lib/libvirt/images/fedora.iso", True,
- "17", "fedora")
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
- os.unlink(fake_iso)
- os.unlink("/var/lib/libvirt/images/fedora.iso")
-
-
-class RestTests(unittest.TestCase):
- def _async_op(self, cb, opaque):
- time.sleep(1)
- cb('success', True)
-
- def _except_op(self, cb, opaque):
- time.sleep(1)
- raise Exception("Oops, this is an exception handle test."
- " You can ignore it safely")
- cb('success', True)
-
- def _intermid_op(self, cb, opaque):
- time.sleep(1)
- cb('in progress')
-
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def assertHTTPStatus(self, code, *args):
- resp = self.request(*args)
- self.assertEquals(code, resp.status)
-
- def test_get_vms(self):
- vms = json.loads(self.request('/plugins/kimchi/vms').read())
- # test_rest.py uses MockModel() which connects to libvirt URI
- # test:///default. By default this driver already has one VM created
- self.assertEquals(1, len(vms))
-
- # Create a template as a base for our VMs
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- test_users = ['root']
- test_groups = ['wheel']
- # Now add a couple of VMs to the mock model
- for i in xrange(10):
- name = 'vm-%i' % i
- req = json.dumps({'name': name,
- 'template': '/plugins/kimchi/templates/test',
- 'users': test_users, 'groups': test_groups})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- vms = json.loads(self.request('/plugins/kimchi/vms').read())
- self.assertEquals(11, len(vms))
-
- vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
- self.assertEquals('vm-1', vm['name'])
- self.assertEquals('shutoff', vm['state'])
- self.assertEquals([], vm['users'])
- self.assertEquals([], vm['groups'])
-
- def test_edit_vm(self):
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- req = json.dumps({'name': 'vm-1',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
- self.assertEquals('vm-1', vm['name'])
-
- resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}', 'POST')
- self.assertEquals(200, resp.status)
-
- req = json.dumps({'unsupported-attr': 'attr'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'name': 'new-vm'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'cpus': 3})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(200, resp.status)
-
- # Check if there is support to memory hotplug, once vm is running
- resp = self.request('/plugins/kimchi/config/capabilities').read()
- conf = json.loads(resp)
- req = json.dumps({'memory': 2048})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- if conf['mem_hotplug_support']:
- self.assertEquals(200, resp.status)
- else:
- self.assertEquals(400, resp.status)
-
- req = json.dumps({"graphics": {'passwd': "abcdef"}})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- info = json.loads(resp.read())
- self.assertEquals('abcdef', info["graphics"]["passwd"])
- self.assertEquals(None, info["graphics"]["passwdValidTo"])
-
- resp = self.request('/plugins/kimchi/vms/vm-1/poweroff', '{}', 'POST')
- self.assertEquals(200, resp.status)
-
- req = json.dumps({"graphics": {'passwd': "123456",
- 'passwdValidTo': 20}})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- info = json.loads(resp.read())
- self.assertEquals('123456', info["graphics"]["passwd"])
- self.assertGreaterEqual(20, info["graphics"]["passwdValidTo"])
-
- req = json.dumps({'name': 12})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'name': ''})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'cpus': -2})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'cpus': 'four'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'memory': 100})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'memory': 'ten gigas'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'name': 'new-name', 'cpus': 5, 'UUID': 'notallowed'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- params = {'name': u'â¨Ð¼-ÑÑdαtеd', 'cpus': 5, 'memory': 3072}
- req = json.dumps(params)
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(303, resp.status)
- vm = json.loads(
- self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req).read()
- )
- for key in params.keys():
- self.assertEquals(params[key], vm[key])
-
- # change only VM users - groups are not changed (default is empty)
- resp = self.request('/plugins/kimchi/users', '{}', 'GET')
- users = json.loads(resp.read())
- req = json.dumps({'users': users})
- resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
- self.assertEquals(200, resp.status)
- info = json.loads(
- self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', '{}').read()
- )
- self.assertEquals(users, info['users'])
-
- # change only VM groups - users are not changed (default is empty)
- resp = self.request('/plugins/kimchi/groups', '{}', 'GET')
- groups = json.loads(resp.read())
- req = json.dumps({'groups': groups})
- resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
- self.assertEquals(200, resp.status)
- info = json.loads(
- self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', '{}').read()
- )
- self.assertEquals(groups, info['groups'])
-
- # change VM users (wrong value) and groups
- # when an error occurs, everything fails and nothing is changed
- req = json.dumps({'users': ['userdoesnotexist'], 'groups': []})
- resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- # change VM users and groups (wrong value)
- # when an error occurs, everything fails and nothing is changed
- req = json.dumps({'users': [], 'groups': ['groupdoesnotexist']})
- resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- def test_vm_lifecycle(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'disks': [{'size': 1}],
- 'icon': 'images/icon-debian.png',
- 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create a VM
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- self.assertEquals(202, resp.status)
-
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('shutoff', vm['state'])
- self.assertEquals('images/icon-debian.png', vm['icon'])
-
- # Verify the volume was created
- vol_uri = '/plugins/kimchi/storagepools/default-pool/storagevolumes/' \
- + '%s-0.img'
- resp = self.request(vol_uri % vm['uuid'])
- vol = json.loads(resp.read())
- self.assertEquals(1 << 30, vol['capacity'])
- self.assertEquals(['test-vm'], vol['used_by'])
-
- # Start the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('running', vm['state'])
-
- # Test screenshot
- resp = self.request(vm['screenshot'], method='HEAD')
- self.assertEquals(200, resp.status)
- self.assertTrue(resp.getheader('Content-type').startswith('image'))
-
- # Clone a running VM
- resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}', 'POST')
- self.assertEquals(400, resp.status)
-
- # Force poweroff the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}',
- 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('shutoff', vm['state'])
-
- # Test create VM with same name fails with 400
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Clone a VM
- resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}', 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- task = json.loads(
- self.request('/tasks/%s' % task['id'], '{}').read()
- )
- self.assertEquals('finished', task['status'])
- clone_vm_name = task['target_uri'].split('/')[-2]
- self.assertTrue(re.match(u'test-vm-clone-\d+', clone_vm_name))
-
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}')
- original_vm_info = json.loads(resp.read())
- resp = self.request('/plugins/kimchi/vms/%s' % clone_vm_name, '{}')
- self.assertEquals(200, resp.status)
- clone_vm_info = json.loads(resp.read())
-
- self.assertNotEqual(original_vm_info['name'], clone_vm_info['name'])
- del original_vm_info['name']
- del clone_vm_info['name']
-
- self.assertNotEqual(original_vm_info['uuid'], clone_vm_info['uuid'])
- del original_vm_info['uuid']
- del clone_vm_info['uuid']
-
- self.assertEquals(original_vm_info, clone_vm_info)
-
- # Create a snapshot on a stopped VM
- params = {'name': 'test-snap'}
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
- json.dumps(params),
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- task = json.loads(
- self.request('/tasks/%s' % task['id']).read()
- )
- self.assertEquals('finished', task['status'])
-
- # Look up a non-existing snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/snap404',
- '{}', 'GET')
- self.assertEquals(404, resp.status)
-
- # Look up a snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
- params['name'], '{}', 'GET')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- self.assertTrue(int(time.time()) >= int(snap['created']))
- self.assertEquals(params['name'], snap['name'])
- self.assertEquals(u'', snap['parent'])
- self.assertEquals(u'shutoff', snap['state'])
-
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots', '{}',
- 'GET')
- self.assertEquals(200, resp.status)
- snaps = json.loads(resp.read())
- self.assertEquals(1, len(snaps))
-
- # Look up current snapshot (the one created above)
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
- '{}', 'GET')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- self.assertEquals(params['name'], snap['name'])
-
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots', '{}',
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- snap_name = task['target_uri'].split('/')[-1]
- wait_task(self._task_lookup, task['id'])
- resp = self.request('/tasks/%s' % task['id'], '{}',
- 'GET')
- task = json.loads(resp.read())
- self.assertEquals('finished', task['status'])
-
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots', '{}',
- 'GET')
- self.assertEquals(200, resp.status)
- snaps = json.loads(resp.read())
- self.assertEquals(2, len(snaps))
-
- # Look up current snapshot (the one created above)
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
- '{}', 'GET')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- self.assertEquals(snap_name, snap['name'])
-
- # Revert to snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s/revert' %
- params['name'], '{}', 'POST')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], snap['state'])
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
- '{}', 'GET')
- self.assertEquals(200, resp.status)
- current_snap = json.loads(resp.read())
- self.assertEquals(snap, current_snap)
-
- # Delete a snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
- params['name'], '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Suspend the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'shutoff')
- resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
- 'POST')
- self.assertEquals(400, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'running')
- resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
- 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'paused')
-
- # Resume the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/resume', '{}', 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'running')
-
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Delete the Template
- resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Verify the volume was deleted
- self.assertHTTPStatus(404, vol_uri % vm['uuid'])
-
- def test_vm_graphics(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create a VM with default args
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('127.0.0.1', vm['graphics']['listen'])
- self.assertEquals('vnc', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a VM with specified graphics type and listen
- graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('127.0.0.1', vm['graphics']['listen'])
- self.assertEquals('vnc', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a VM with listen as ipv6 address
- graphics = {'type': 'spice', 'listen': 'fe00::0'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('fe00::0', vm['graphics']['listen'])
- self.assertEquals('spice', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a VM with specified graphics type and default listen
- graphics = {'type': 'spice'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('127.0.0.1', vm['graphics']['listen'])
- self.assertEquals('spice', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Try to create a VM with invalid graphics type
- graphics = {'type': 'invalid'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Try to create a VM with invalid graphics listen
- graphics = {'type': 'spice', 'listen': 'invalid'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Delete the Template
- resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_vm_storage_devices(self):
-
- with RollbackContext() as rollback:
- # Create a template as a base for our VMs
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- # Delete the template
- rollback.prependDefer(self.request,
- '/plugins/kimchi/templates/test', '{}',
- 'DELETE')
-
- # Create a VM with default args
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Delete the VM
- rollback.prependDefer(self.request, '/plugins/kimchi/vms/test-vm',
- '{}', 'DELETE')
-
- # Check storage devices
- resp = self.request('/plugins/kimchi/vms/test-vm/storages', '{}',
- 'GET')
- devices = json.loads(resp.read())
- self.assertEquals(2, len(devices))
- dev_types = []
- for d in devices:
- self.assertIn(u'type', d.keys())
- self.assertIn(u'dev', d.keys())
- self.assertIn(u'path', d.keys())
- dev_types.append(d['type'])
-
- self.assertEquals(['cdrom', 'disk'], sorted(dev_types))
-
- # Attach cdrom with nonexistent iso
- req = json.dumps({'dev': 'hdx',
- 'type': 'cdrom',
- 'path': '/tmp/nonexistent.iso'})
- resp = self.request('/plugins/kimchi/vms/test-vm/storages', req,
- 'POST')
- self.assertEquals(400, resp.status)
-
- # Create temp storage pool
- req = json.dumps({'name': 'tmp',
- 'capacity': 1024,
- 'allocated': 512,
- 'path': '/tmp',
- 'type': 'dir'})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/tmp/activate',
- req, 'POST')
- self.assertEquals(200, resp.status)
-
- # 'name' is required for this type of volume
- req = json.dumps({'capacity': 1024,
- 'allocation': 512,
- 'type': 'disk',
- 'format': 'raw'})
- resp = self.request(
- '/plugins/kimchi/storagepools/tmp/storagevolumes', req, 'POST'
- )
- self.assertEquals(400, resp.status)
- req = json.dumps({'name': "attach-volume",
- 'capacity': 1024,
- 'allocation': 512,
- 'type': 'disk',
- 'format': 'raw'})
- resp = self.request(
- '/plugins/kimchi/storagepools/tmp/storagevolumes', req, 'POST'
- )
- self.assertEquals(202, resp.status)
- time.sleep(1)
-
- # Attach cdrom with both path and volume specified
- open('/tmp/existent.iso', 'w').close()
- req = json.dumps({'dev': 'hdx',
- 'type': 'cdrom',
- 'pool': 'tmp',
- 'vol': 'attach-volume',
- 'path': '/tmp/existent.iso'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(400, resp.status)
-
- # Attach disk with both path and volume specified
- req = json.dumps({'dev': 'hdx',
- 'type': 'disk',
- 'pool': 'tmp',
- 'vol': 'attach-volume',
- 'path': '/tmp/existent.iso'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(400, resp.status)
-
- # Attach disk with only pool specified
- req = json.dumps({'dev': 'hdx',
- 'type': 'cdrom',
- 'pool': 'tmp'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(400, resp.status)
-
- # Attach disk with pool and vol specified
- req = json.dumps({'type': 'disk',
- 'pool': 'tmp',
- 'vol': 'attach-volume'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(201, resp.status)
- cd_info = json.loads(resp.read())
- self.assertEquals('disk', cd_info['type'])
-
- # Attach a cdrom with existent dev name
- req = json.dumps({'type': 'cdrom',
- 'path': '/tmp/existent.iso'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(201, resp.status)
- cd_info = json.loads(resp.read())
- cd_dev = cd_info['dev']
- self.assertEquals('cdrom', cd_info['type'])
- self.assertEquals('/tmp/existent.iso', cd_info['path'])
- # Delete the file and cdrom
- rollback.prependDefer(self.request,
- '/plugins/kimchi/vms/test-vm/storages/hdx',
- '{}', 'DELETE')
- os.remove('/tmp/existent.iso')
-
- # Change path of storage cdrom
- cdrom = u'http://fedora.mirrors.tds.net/pub/fedora/releases/20/'\
- 'Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso'
- req = json.dumps({'path': cdrom})
- resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
- cd_dev, req, 'PUT')
- self.assertEquals(200, resp.status)
- cd_info = json.loads(resp.read())
- self.assertEquals(urlparse.urlparse(cdrom).path,
- urlparse.urlparse(cd_info['path']).path)
-
- # Test GET
- devs = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/storages').read()
- )
- self.assertEquals(4, len(devs))
-
- # Detach storage cdrom
- resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
- cd_dev, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Test GET
- devs = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/storages').read()
- )
- self.assertEquals(3, len(devs))
- resp = self.request('/plugins/kimchi/storagepools/tmp/deactivate',
- {}, 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/tmp', {},
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_vm_iface(self):
-
- with RollbackContext() as rollback:
- # Create a template as a base for our VMs
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- # Delete the template
- rollback.prependDefer(self.request,
- '/plugins/kimchi/templates/test', '{}',
- 'DELETE')
-
- # Create a VM with default args
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Delete the VM
- rollback.prependDefer(self.request,
- '/plugins/kimchi/vms/test-vm', '{}',
- 'DELETE')
-
- # Create a network
- req = json.dumps({'name': 'test-network',
- 'connection': 'nat',
- 'net': '127.0.1.0/24'})
- resp = self.request('/plugins/kimchi/networks', req, 'POST')
- self.assertEquals(201, resp.status)
- # Delete the network
- rollback.prependDefer(self.request,
- '/plugins/kimchi/networks/test-network',
- '{}', 'DELETE')
-
- ifaces = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/ifaces').read()
- )
- self.assertEquals(1, len(ifaces))
-
- for iface in ifaces:
- res = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- iface['mac']).read()
- )
- self.assertEquals('default', res['network'])
- self.assertEquals(17, len(res['mac']))
- self.assertEquals(get_template_default('old', 'nic_model'),
- res['model'])
-
- # try to attach an interface without specifying 'model'
- req = json.dumps({'type': 'network'})
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
- 'POST')
- self.assertEquals(400, resp.status)
-
- # attach network interface to vm
- req = json.dumps({"type": "network",
- "network": "test-network",
- "model": "virtio"})
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
- 'POST')
- self.assertEquals(201, resp.status)
- iface = json.loads(resp.read())
-
- self.assertEquals('test-network', iface['network'])
- self.assertEquals(17, len(iface['mac']))
- self.assertEquals('virtio', iface['model'])
- self.assertEquals('network', iface['type'])
-
- # update vm interface
- newMacAddr = '54:50:e3:44:8a:af'
- req = json.dumps({"network": "default", "model": "virtio",
- "type": "network", "mac": newMacAddr})
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- iface['mac'], req, 'PUT')
- self.assertEquals(303, resp.status)
- iface = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- newMacAddr).read()
- )
- self.assertEquals(newMacAddr, iface['mac'])
-
- # detach network interface from vm
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- iface['mac'], '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_vm_customise_storage(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'cdrom': fake_iso,
- 'disks': [{'size': 1}]})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create alternate storage
- req = json.dumps({'name': 'alt',
- 'capacity': 1024,
- 'allocated': 512,
- 'path': '/tmp',
- 'type': 'dir'})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/alt/activate', req,
- 'POST')
- self.assertEquals(200, resp.status)
-
- # Create a VM
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'storagepool': '/plugins/kimchi/storagepools/alt'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- resp = self.request('/plugins/kimchi/vms/test-vm', {}, 'GET')
- vm_info = json.loads(resp.read())
-
- # Test template not changed after vm customise its pool
- t = json.loads(self.request('/plugins/kimchi/templates/test').read())
- self.assertEquals(t['storagepool'],
- '/plugins/kimchi/storagepools/default-pool')
-
- # Verify the volume was created
- vol_uri = '/plugins/kimchi/storagepools/alt/storagevolumes/%s-0.img' \
- % vm_info['uuid']
- resp = self.request(vol_uri)
- vol = json.loads(resp.read())
- self.assertEquals(1 << 30, vol['capacity'])
-
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Verify the volume was deleted
- self.assertHTTPStatus(404, vol_uri)
-
- def test_scsi_fc_storage(self):
- # Create scsi fc pool
- req = json.dumps({'name': 'scsi_fc_pool',
- 'type': 'scsi',
- 'source': {'adapter_name': 'scsi_host2'}})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Test create vms using lun of this pool
- # activate the storage pool
- resp = self.request(
- '/plugins/kimchi/storagepools/scsi_fc_pool/activate', '{}', 'POST'
- )
-
- # Create template fails because SCSI volume is missing
- tmpl_params = {
- 'name': 'test_fc_pool', 'cdrom': fake_iso,
- 'storagepool': '/plugins/kimchi/storagepools/scsi_fc_pool'
- }
- req = json.dumps(tmpl_params)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Choose SCSI volume to create template
- resp = self.request(
- '/plugins/kimchi/storagepools/scsi_fc_pool/storagevolumes'
- )
- lun_name = json.loads(resp.read())[0]['name']
-
- tmpl_params['disks'] = [{'index': 0, 'volume': lun_name}]
- req = json.dumps(tmpl_params)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create vm in scsi pool
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test_fc_pool'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- # Start the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('running', vm['state'])
-
- # Force poweroff the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}',
- 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('shutoff', vm['state'])
-
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_unnamed_vms(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create 5 unnamed vms from this template
- for i in xrange(1, 6):
- req = json.dumps({'template': '/plugins/kimchi/templates/test'})
- task = json.loads(self.request('/plugins/kimchi/vms',
- req, 'POST').read())
- wait_task(self._task_lookup, task['id'])
- resp = self.request('/plugins/kimchi/vms/test-vm-%i' % i, {},
- 'GET')
- self.assertEquals(resp.status, 200)
- count = len(json.loads(self.request('/plugins/kimchi/vms').read()))
- self.assertEquals(6, count)
-
- def test_create_vm_without_template(self):
- req = json.dumps({'name': 'vm-without-template'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
- resp = json.loads(resp.read())
- self.assertIn(u"KCHVM0016E:", resp['reason'])
-
- def test_create_vm_with_bad_template_uri(self):
- req = json.dumps({'name': 'vm-bad-template',
- 'template': '/mytemplate'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
- resp = json.loads(resp.read())
- self.assertIn(u"KCHVM0012E", resp['reason'])
-
- def test_create_vm_with_img_based_template(self):
- resp = json.loads(
- self.request(
- '/plugins/kimchi/storagepools/default-pool/storagevolumes'
- ).read()
- )
- self.assertEquals(0, len(resp))
-
- # Create a Template
- mock_base = '/tmp/mock.img'
- open(mock_base, 'w').close()
- req = json.dumps({'name': 'test', 'disks': [{'base': mock_base}]})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- req = json.dumps({'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- # Test storage volume created with backing store of base file
- resp = json.loads(
- self.request(
- '/plugins/kimchi/storagepools/default-pool/storagevolumes'
- ).read()
- )
- self.assertEquals(1, len(resp))
-
- def _create_pool(self, name):
- req = json.dumps({'name': name,
- 'capacity': 10240,
- 'allocated': 5120,
- 'path': '/var/lib/libvirt/images/',
- 'type': 'dir'})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the storage pool
- storagepool = json.loads(self.request('/plugins/kimchi/storagepools/%s'
- % name).read())
- self.assertEquals('inactive', storagepool['state'])
- return name
-
- def _delete_pool(self, name):
- # Delete the storage pool
- resp = self.request('/plugins/kimchi/storagepools/%s' % name, '{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_iso_scan_shallow(self):
- # fake environment preparation
- self._create_pool('pool-3')
- self.request('/plugins/kimchi/storagepools/pool-3/activate', '{}',
- 'POST')
- params = {'name': 'fedora.iso',
- 'capacity': 1073741824, # 1 GiB
- 'type': 'file',
- 'format': 'iso'}
- task_info = model.storagevolumes_create('pool-3', params)
- wait_task(self._task_lookup, task_info['id'])
-
- storagevolume = json.loads(
- self.request(
- '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes/'
- ).read()
- )[0]
- self.assertEquals('fedora.iso', storagevolume['name'])
- self.assertEquals('iso', storagevolume['format'])
- self.assertEquals('/var/lib/libvirt/images/fedora.iso',
- storagevolume['path'])
- self.assertEquals(1073741824, storagevolume['capacity']) # 1 GiB
- self.assertEquals(0, storagevolume['allocation'])
- self.assertEquals('17', storagevolume['os_version'])
- self.assertEquals('fedora', storagevolume['os_distro'])
- self.assertEquals(True, storagevolume['bootable'])
-
- # Create a template
- # In real model os distro/version can be omitted
- # as we will scan the iso
- req = json.dumps({'name': 'test',
- 'cdrom': storagevolume['path'],
- 'os_distro': storagevolume['os_distro'],
- 'os_version': storagevolume['os_version']})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the template
- t = json.loads(self.request('/plugins/kimchi/templates/test').read())
- self.assertEquals('test', t['name'])
- self.assertEquals('fedora', t['os_distro'])
- self.assertEquals('17', t['os_version'])
- self.assertEquals(get_template_default('old', 'memory'), t['memory'])
-
- # Deactivate or destroy scan pool return 405
- resp = self.request(
- '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes'
- '/deactivate', '{}', 'POST'
- )
- self.assertEquals(405, resp.status)
-
- resp = self.request(
- '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
- '{}', 'DELETE'
- )
- self.assertEquals(405, resp.status)
-
- # Delete the template
- resp = self.request('/plugins/kimchi/templates/%s' % t['name'], '{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- resp = self.request('/plugins/kimchi/storagepools/pool-3/deactivate',
- '{}', 'POST')
- self.assertEquals(200, resp.status)
- self._delete_pool('pool-3')
-
- def test_screenshot_refresh(self):
- # Create a VM
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- # Test screenshot for shut-off state vm
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(404, resp.status)
-
- # Test screenshot for running vm
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
-
- resp = self.request(vm['screenshot'], method='HEAD')
- self.assertEquals(200, resp.status)
- self.assertTrue(resp.getheader('Content-type').startswith('image'))
-
- # Test screenshot sub-resource redirect
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(200, resp.status)
- self.assertEquals('image/png', resp.getheader('content-type'))
- lastMod1 = resp.getheader('last-modified')
-
- # Take another screenshot instantly and compare the last Modified date
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- lastMod2 = resp.getheader('last-modified')
- self.assertEquals(lastMod2, lastMod1)
-
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot', '{}',
- 'DELETE')
- self.assertEquals(405, resp.status)
-
- # No screenshot after stopped the VM
- self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}', 'POST')
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(404, resp.status)
-
- # Picture link not available after VM deleted
- self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- img_lnk = vm['screenshot']
- self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
- resp = self.request(img_lnk)
- self.assertEquals(404, resp.status)
-
- def test_interfaces(self):
- resp = self.request('/plugins/kimchi/interfaces').read()
- self.assertIn('name', resp)
- interfaces = json.loads(resp)
- keys = ['name', 'type', 'ipaddr', 'netmask', 'status']
- for interface in interfaces:
- self.assertEquals(sorted(keys), sorted(interface.keys()))
-
- def _task_lookup(self, taskid):
- return json.loads(
- self.request('/tasks/%s' % taskid).read()
- )
-
- def test_tasks(self):
- id1 = add_task('/tasks/1', self._async_op,
- model.objstore)
- id2 = add_task('/tasks/2', self._except_op,
- model.objstore)
- id3 = add_task('/tasks/3', self._intermid_op,
- model.objstore)
-
- target_uri = urllib2.quote('^/tasks/*', safe="")
- filter_data = 'status=running&target_uri=%s' % target_uri
- tasks = json.loads(
- self.request('/tasks?%s' % filter_data).read()
- )
- self.assertEquals(3, len(tasks))
-
- tasks = json.loads(self.request('/tasks').read())
- tasks_ids = [int(t['id']) for t in tasks]
- self.assertEquals(set([id1, id2, id3]) - set(tasks_ids), set([]))
- wait_task(self._task_lookup, id2)
- foo2 = json.loads(
- self.request('/tasks/%s' % id2).read()
- )
- keys = ['id', 'status', 'message', 'target_uri']
- self.assertEquals(sorted(keys), sorted(foo2.keys()))
- self.assertEquals('failed', foo2['status'])
- wait_task(self._task_lookup, id3)
- foo3 = json.loads(
- self.request('/tasks/%s' % id3).read()
- )
- self.assertEquals('in progress', foo3['message'])
- self.assertEquals('running', foo3['status'])
-
- def test_config(self):
- resp = self.request('/plugins/kimchi/config').read()
- conf = json.loads(resp)
- keys = ["display_proxy_port", "version"]
- self.assertEquals(keys, sorted(conf.keys()))
-
- def test_capabilities(self):
- resp = self.request('/plugins/kimchi/config/capabilities').read()
- conf = json.loads(resp)
-
- keys = [u'libvirt_stream_protocols', u'qemu_stream', u'qemu_spice',
- u'screenshot', u'system_report_tool', u'update_tool',
- u'repo_mngt_tool', u'federation', u'kernel_vfio', u'auth',
- u'nm_running', u'mem_hotplug_support']
- self.assertEquals(sorted(keys), sorted(conf.keys()))
-
- def test_peers(self):
- resp = self.request('/plugins/kimchi/peers').read()
- self.assertEquals([], json.loads(resp))
-
- def test_distros(self):
- resp = self.request('/plugins/kimchi/config/distros').read()
- distros = json.loads(resp)
- for distro in distros:
- self.assertIn('name', distro)
- self.assertIn('os_distro', distro)
- self.assertIn('os_version', distro)
- self.assertIn('path', distro)
-
- # Test in X86
- ident = "Fedora 20"
- resp = self.request('/plugins/kimchi/config/distros/%s' %
- urllib2.quote(ident)).read()
- distro = json.loads(resp)
- if os.uname()[4] in ['x86_64', 'amd64']:
- self.assertEquals(distro['name'], ident)
- self.assertEquals(distro['os_distro'], "fedora")
- self.assertEquals(distro['os_version'], "20")
- self.assertEquals(distro['os_arch'], "x86_64")
- self.assertIn('path', distro)
- else:
- # Distro not found error
- self.assertIn('KCHDISTRO0001E', distro.get('reason'))
-
- # Test in PPC
- ident = "Fedora 20 (PPC64)"
- resp = self.request('/plugins/kimchi/config/distros/%s' %
- urllib2.quote(ident)).read()
- distro = json.loads(resp)
- if os.uname()[4] == 'ppc64':
- self.assertEquals(distro['name'], ident)
- self.assertEquals(distro['os_distro'], "fedora")
- self.assertEquals(distro['os_version'], "20")
- self.assertEquals(distro['os_arch'], "ppc64")
- self.assertIn('path', distro)
- else:
- # Distro not found error
- self.assertIn('KCHDISTRO0001E', distro.get('reason'))
-
- def test_debugreports(self):
- resp = request(host, ssl_port, '/plugins/kimchi/debugreports')
- self.assertEquals(200, resp.status)
-
- def _report_delete(self, name):
- request(host, ssl_port, '/plugins/kimchi/debugreports/%s' % name, '{}',
- 'DELETE')
-
- def test_create_debugreport(self):
- req = json.dumps({'name': 'report1'})
- with RollbackContext() as rollback:
- resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- # make sure the debugreport doesn't exist until the
- # the task is finished
- wait_task(self._task_lookup, task['id'])
- rollback.prependDefer(self._report_delete, 'report2')
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1')
- debugreport = json.loads(resp.read())
- self.assertEquals("report1", debugreport['name'])
- self.assertEquals(200, resp.status)
- req = json.dumps({'name': 'report2'})
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1', req, 'PUT')
- self.assertEquals(303, resp.status)
-
- def test_debugreport_download(self):
- req = json.dumps({'name': 'report1'})
- with RollbackContext() as rollback:
- resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- # make sure the debugreport doesn't exist until the
- # the task is finished
- wait_task(self._task_lookup, task['id'], 20)
- rollback.prependDefer(self._report_delete, 'report1')
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1')
- debugreport = json.loads(resp.read())
- self.assertEquals("report1", debugreport['name'])
- self.assertEquals(200, resp.status)
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1/content')
- self.assertEquals(200, resp.status)
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1')
- debugre = json.loads(resp.read())
- resp = request(host, ssl_port, debugre['uri'])
- self.assertEquals(200, resp.status)
-
- def test_repositories(self):
- def verify_repo(t, res):
- for field in ('repo_id', 'enabled', 'baseurl', 'config'):
- if field in t.keys():
- self.assertEquals(t[field], res[field])
-
- base_uri = '/plugins/kimchi/host/repositories'
- resp = self.request(base_uri)
- self.assertEquals(200, resp.status)
- # Already have one repo in Kimchi's system
- self.assertEquals(1, len(json.loads(resp.read())))
-
- # Create a repository
- repo = {'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'}
- req = json.dumps(repo)
- resp = self.request(base_uri, req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the repository
- res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
- verify_repo(repo, res)
-
- # Update the repository
- params = {}
- params['baseurl'] = repo['baseurl'] = 'http://www.fedoraproject.org'
- resp = self.request('%s/fedora-fake' % base_uri, json.dumps(params),
- 'PUT')
-
- # Verify the repository
- res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
- verify_repo(repo, res)
-
- # Delete the repository
- resp = self.request('%s/fedora-fake' % base_uri, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
-
-class HttpsRestTests(RestTests):
- """
- Run all of the same tests as above, but use https instead
- """
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
diff --git a/plugins/kimchi/tests/test_rollbackcontext.py b/plugins/kimchi/tests/test_rollbackcontext.py
deleted file mode 100644
index 6eac6d0..0000000
--- a/plugins/kimchi/tests/test_rollbackcontext.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-
-from wok.rollbackcontext import RollbackContext
-
-
-class FirstError(Exception):
- '''A hypothetical exception to be raise in the test firstly.'''
- pass
-
-
-class SecondError(Exception):
- '''A hypothetical exception to be raise in the test secondly.'''
- pass
-
-
-class RollbackContextTests(unittest.TestCase):
-
- def setUp(self):
- self._counter = 0
-
- def _inc_counter(self):
- self._counter += 1
-
- def _raise(self, exception=FirstError):
- raise exception()
-
- def test_rollback(self):
- with RollbackContext() as rollback:
- rollback.prependDefer(self._inc_counter)
- rollback.prependDefer(self._inc_counter)
- self.assertEquals(self._counter, 2)
-
- def test_raise(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._inc_counter)
- rollback.prependDefer(self._inc_counter)
- raise FirstError()
- rollback.prependDefer(self._inc_counter)
- except FirstError:
- # All undo before the FirstError should be run
- self.assertEquals(self._counter, 2)
- else:
- self.fail('Should have raised FirstError')
-
- def test_raise_undo(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._inc_counter)
- rollback.prependDefer(self._raise)
- rollback.prependDefer(self._inc_counter)
- except FirstError:
- # All undo should be run
- self.assertEquals(self._counter, 2)
- else:
- self.fail('Should have raised FirstError')
-
- def test_raise_prefer_original(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._raise, SecondError)
- raise FirstError()
- except FirstError:
- pass
- except SecondError:
- self.fail('Should have preferred FirstError to SecondError')
- else:
- self.fail('Should have raised FirstError')
-
- def test_raise_prefer_first_undo(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._raise, SecondError)
- rollback.prependDefer(self._raise, FirstError)
- except FirstError:
- pass
- except SecondError:
- self.fail('Should have preferred FirstError to SecondError')
- else:
- self.fail('Should have raised FirstError')
diff --git a/plugins/kimchi/tests/test_server.py b/plugins/kimchi/tests/test_server.py
deleted file mode 100644
index d5ef565..0000000
--- a/plugins/kimchi/tests/test_server.py
+++ /dev/null
@@ -1,289 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import base64
-import cherrypy
-import json
-import os
-import tempfile
-import threading
-import unittest
-from functools import partial
-
-from wok.control.base import Collection, Resource
-
-from wok.plugins.kimchi import mockmodel
-
-import utils
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-tmpfile = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port, tmpfile
-
- utils.patch_auth()
- tmpfile = tempfile.mktemp()
- model = mockmodel.MockModel(tmpfile)
- host = '127.0.0.1'
- port = utils.get_free_port('http')
- ssl_port = utils.get_free_port('https')
- cherrypy_port = utils.get_free_port('cherrypy_port')
- test_server = utils.run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink(tmpfile)
-
-
-class ServerTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(utils.request, host, ssl_port)
- model.reset()
-
- def assertValidJSON(self, txt):
- try:
- json.loads(txt)
- except ValueError:
- self.fail("Invalid JSON: %s" % txt)
-
- def test_server_start(self):
- """
- Test that we can start a server and receive HTTP:200.
- """
- resp = self.request('/')
- self.assertEquals(200, resp.status)
-
- def test_multithreaded_connection(self):
- def worker():
- for i in xrange(100):
- ret = model.vms_get_list()
- self.assertEquals('test', ret[0])
-
- threads = []
- for i in xrange(100):
- t = threading.Thread(target=worker)
- t.setDaemon(True)
- t.start()
- threads.append(t)
- for t in threads:
- t.join()
-
- def test_collection(self):
- c = Collection(model)
-
- # The base Collection is always empty
- cherrypy.request.method = 'GET'
- cherrypy.request.headers['Accept'] = 'application/json'
- self.assertEquals('[]', c.index())
-
- # POST and DELETE raise HTTP:405 by default
- for method in ('POST', 'DELETE'):
- cherrypy.request.method = method
- try:
- c.index()
- except cherrypy.HTTPError, e:
- self.assertEquals(405, e.code)
- else:
- self.fail("Expected exception not raised")
-
- def test_resource(self):
- r = Resource(model)
-
- # Test the base Resource representation
- cherrypy.request.method = 'GET'
- cherrypy.request.headers['Accept'] = 'application/json'
- self.assertEquals('{}', r.index())
-
- # POST and DELETE raise HTTP:405 by default
- for method in ('POST', 'DELETE'):
- cherrypy.request.method = method
- try:
- r.index()
- except cherrypy.HTTPError, e:
- self.assertEquals(405, e.code)
- else:
- self.fail("Expected exception not raised")
-
- def test_404(self):
- """
- A non-existent path should return HTTP:404
- """
- url_list = ['/plugins/kimchi/doesnotexist', '/plugins/kimchi/vms/blah']
- for url in url_list:
- resp = self.request(url)
- self.assertEquals(404, resp.status)
-
- # Verify it works for DELETE too
- resp = self.request('/plugins/kimchi/templates/blah', '', 'DELETE')
- self.assertEquals(404, resp.status)
-
- def test_accepts(self):
- """
- Verify the following expectations regarding the client Accept header:
- If omitted, default to html
- If 'application/json', serve the rest api
- If 'text/html', serve the UI
- If both of the above (in any order), serve the rest api
- If neither of the above, HTTP:406
- """
- resp = self.request("/", headers={})
- location = resp.getheader('location')
- self.assertTrue(location.endswith("login.html"))
- resp = self.request("/login.html", headers={})
- self.assertTrue('<!doctype html>' in resp.read().lower())
-
- resp = self.request("/", headers={'Accept': 'application/json'})
- self.assertValidJSON(resp.read())
-
- resp = self.request("/", headers={'Accept': 'text/html'})
- location = resp.getheader('location')
- self.assertTrue(location.endswith("login.html"))
-
- resp = self.request("/", headers={'Accept':
- 'application/json, text/html'})
- self.assertValidJSON(resp.read())
-
- resp = self.request("/", headers={'Accept':
- 'text/html, application/json'})
- self.assertValidJSON(resp.read())
-
- h = {'Accept': 'text/plain'}
- resp = self.request('/', None, 'GET', h)
- self.assertEquals(406, resp.status)
-
- def test_auth_unprotected(self):
- hdrs = {'AUTHORIZATION': ''}
- uris = ['/plugins/kimchi/js/kimchi.min.js',
- '/plugins/kimchi/css/theme-default.min.css',
- '/plugins/kimchi/images/icon-vm.png',
- '/libs/jquery-1.10.0.min.js',
- '/login.html',
- '/logout']
-
- for uri in uris:
- resp = self.request(uri, None, 'HEAD', hdrs)
- self.assertEquals(200, resp.status)
-
- def test_auth_protected(self):
- hdrs = {'AUTHORIZATION': ''}
- uris = ['/plugins/kimchi/vms',
- '/plugins/kimchi/vms/doesnotexist',
- '/tasks']
-
- for uri in uris:
- resp = self.request(uri, None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- def test_auth_bad_creds(self):
- # Test HTTPBA
- hdrs = {'AUTHORIZATION': "Basic " + base64.b64encode("nouser:badpass")}
- resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- # Test REST API
- hdrs = {'AUTHORIZATION': ''}
- req = json.dumps({'username': 'nouser', 'password': 'badpass'})
- resp = self.request('/login', req, 'POST', hdrs)
- self.assertEquals(401, resp.status)
-
- def test_auth_browser_no_httpba(self):
- # Kimchi detects REST requests from the browser by looking for a
- # specific header
- hdrs = {"X-Requested-With": "XMLHttpRequest"}
-
- # Try our request (Note that request() will add a valid HTTPBA header)
- resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
- self.assertEquals(None, resp.getheader('WWW-Authenticate'))
-
- def test_auth_session(self):
- hdrs = {'AUTHORIZATION': '',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'}
-
- # Test we are logged out
- resp = self.request('/tasks', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- # Execute a login call
- user, pw = mockmodel.fake_user.items()[0]
- req = json.dumps({'username': user, 'password': pw})
- resp = self.request('/login', req, 'POST', hdrs)
- self.assertEquals(200, resp.status)
-
- user_info = json.loads(resp.read())
- self.assertEquals(sorted(user_info.keys()),
- ['groups', 'roles', 'username'])
- roles = user_info['roles']
- for tab, role in roles.iteritems():
- self.assertEquals(role, u'admin')
-
- cookie = resp.getheader('set-cookie')
- hdrs['Cookie'] = cookie
-
- # Test we are logged in with the cookie
- resp = self.request('/tasks', None, 'GET', hdrs)
- self.assertEquals(200, resp.status)
-
- # Execute a logout call
- resp = self.request('/logout', '{}', 'POST', hdrs)
- self.assertEquals(200, resp.status)
- del hdrs['Cookie']
-
- # Test we are logged out
- resp = self.request('/tasks', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- def test_get_param(self):
- # Create a mock ISO file
- mockiso = '/tmp/mock.iso'
- open('/tmp/mock.iso', 'w').close()
-
- # Create 2 different templates
- req = json.dumps({'name': 'test-tmpl1', 'cdrom': mockiso})
- self.request('/plugins/kimchi/templates', req, 'POST')
-
- req = json.dumps({'name': 'test-tmpl2', 'cdrom': mockiso})
- self.request('/plugins/kimchi/templates', req, 'POST')
-
- # Remove mock iso
- os.unlink(mockiso)
-
- # Get the templates
- resp = self.request('/plugins/kimchi/templates')
- self.assertEquals(200, resp.status)
- res = json.loads(resp.read())
- self.assertEquals(2, len(res))
-
- # Get a specific template
- resp = self.request('/plugins/kimchi/templates?name=test-tmpl1')
- self.assertEquals(200, resp.status)
- res = json.loads(resp.read())
- self.assertEquals(1, len(res))
- self.assertEquals('test-tmpl1', res[0]['name'])
diff --git a/plugins/kimchi/tests/test_storagepoolxml.py b/plugins/kimchi/tests/test_storagepoolxml.py
deleted file mode 100644
index 7e45cca..0000000
--- a/plugins/kimchi/tests/test_storagepoolxml.py
+++ /dev/null
@@ -1,171 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-import unittest
-
-from wok.plugins.kimchi.model.libvirtstoragepool import StoragePoolDef
-
-
-class StoragepoolXMLTests(unittest.TestCase):
- def test_get_storagepool_xml(self):
- poolDefs = [
- {'def':
- {'type': 'dir',
- 'name': 'unitTestDirPool',
- 'path': '/var/temp/images'},
- 'xml':
- """
- <pool type='dir'>
- <name>unitTestDirPool</name>
- <target>
- <path>/var/temp/images</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'netfs',
- 'name': 'unitTestNFSPool',
- 'source': {'host': '127.0.0.1',
- 'path': '/var/export'}},
- 'xml':
- """
- <pool type='netfs'>
- <name>unitTestNFSPool</name>
- <source>
- <host name='127.0.0.1'/>
- <dir path='/var/export'/>
- </source>
- <target>
- <path>/var/lib/kimchi/nfs_mount/unitTestNFSPool</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'logical',
- 'name': 'unitTestLogicalPool',
- 'source': {'devices': ['/dev/hda', '/dev/hdb']}},
- 'xml':
- """
- <pool type='logical'>
- <name>unitTestLogicalPool</name>
- <source>
- <device path="/dev/hda" />
- <device path="/dev/hdb" />
- </source>
- <target>
- <path>/dev/unitTestLogicalPool</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'iscsi',
- 'name': 'unitTestISCSIPool',
- 'source': {
- 'host': '127.0.0.1',
- 'target': 'iqn.2003-01.org.linux-iscsi.localhost'}},
- 'xml':
- """
- <pool type='iscsi'>
- <name>unitTestISCSIPool</name>
- <source>
- <host name='127.0.0.1' />
- <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
- </source>
- <target>
- <path>/dev/disk/by-id</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'iscsi',
- 'name': 'unitTestISCSIPoolPort',
- 'source': {
- 'host': '127.0.0.1',
- 'port': 3266,
- 'target': 'iqn.2003-01.org.linux-iscsi.localhost'}},
- 'xml':
- """
- <pool type='iscsi'>
- <name>unitTestISCSIPoolPort</name>
- <source>
- <host name='127.0.0.1' port='3266' />
- <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
- </source>
- <target>
- <path>/dev/disk/by-id</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'iscsi',
- 'name': 'unitTestISCSIPoolAuth',
- 'source': {
- 'host': '127.0.0.1',
- 'target': 'iqn.2003-01.org.linux-iscsi.localhost',
- 'auth': {'username': 'testUser',
- 'password': 'ActuallyNotUsedInPoolXML'}}},
- 'xml':
- """
- <pool type='iscsi'>
- <name>unitTestISCSIPoolAuth</name>
- <source>
- <host name='127.0.0.1' />
- <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
- <auth type='chap' username='testUser'>
- <secret type='iscsi' usage='unitTestISCSIPoolAuth'/>
- </auth>
- </source>
- <target>
- <path>/dev/disk/by-id</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'scsi',
- 'name': 'unitTestSCSIFCPool',
- 'path': '/dev/disk/by-path',
- 'source': {
- 'name': 'scsi_host3',
- 'adapter': {
- 'type': 'fc_host',
- 'wwpn': '0123456789abcdef',
- 'wwnn': 'abcdef0123456789'}}},
- 'xml':
- """
- <pool type='scsi'>
- <name>unitTestSCSIFCPool</name>
- <source>
- <adapter type='fc_host' name='scsi_host3'
- wwnn='abcdef0123456789' wwpn='0123456789abcdef'></adapter>
- </source>
- <target>
- <path>/dev/disk/by-path</path>
- </target>
- </pool>
- """}]
-
- for poolDef in poolDefs:
- defObj = StoragePoolDef.create(poolDef['def'])
- xmlStr = defObj.xml
-
- parser = ET.XMLParser(remove_blank_text=True)
- t1 = ET.fromstring(xmlStr, parser)
- t2 = ET.fromstring(poolDef['xml'], parser)
- self.assertEquals(ET.tostring(t1), ET.tostring(t2))
diff --git a/plugins/kimchi/tests/test_template.py b/plugins/kimchi/tests/test_template.py
deleted file mode 100644
index c7de182..0000000
--- a/plugins/kimchi/tests/test_template.py
+++ /dev/null
@@ -1,387 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.config import READONLY_POOL_TYPE
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class TemplateTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def test_tmpl_lifecycle(self):
- resp = self.request('/plugins/kimchi/templates')
- self.assertEquals(200, resp.status)
- self.assertEquals(0, len(json.loads(resp.read())))
-
- # Create a template without cdrom and disk specified fails with 400
- t = {'name': 'test', 'os_distro': 'ImagineOS',
- 'os_version': '1.0', 'memory': 1024, 'cpus': 1,
- 'storagepool': '/plugins/kimchi/storagepools/alt'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the template
- keys = ['name', 'icon', 'invalid', 'os_distro', 'os_version', 'cpus',
- 'memory', 'cdrom', 'disks', 'storagepool', 'networks',
- 'folder', 'graphics', 'cpu_info']
- tmpl = json.loads(
- self.request('/plugins/kimchi/templates/test').read()
- )
- self.assertEquals(sorted(tmpl.keys()), sorted(keys))
-
- # Verify if default disk format was configured
- self.assertEquals(tmpl['disks'][0]['format'], 'qcow2')
-
- # Clone a template
- resp = self.request('/plugins/kimchi/templates/test/clone', '{}',
- 'POST')
- self.assertEquals(303, resp.status)
-
- # Verify the cloned template
- tmpl_cloned = json.loads(
- self.request('/plugins/kimchi/templates/test-clone1').read()
- )
- del tmpl['name']
- del tmpl_cloned['name']
- self.assertEquals(tmpl, tmpl_cloned)
-
- # Delete the cloned template
- resp = self.request('/plugins/kimchi/templates/test-clone1', '{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a template with same name fails with 400
- req = json.dumps({'name': 'test', 'cdrom': '/tmp/mock.iso'})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Create an image based template
- open('/tmp/mock.img', 'w').close()
- t = {'name': 'test_img_template',
- 'disks': [{'base': '/tmp/mock.img'}]}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- os.remove('/tmp/mock.img')
-
- # Test disk format
- t = {'name': 'test-format', 'cdrom': '/tmp/mock.iso',
- 'disks': [{'index': 0, 'size': 10, 'format': 'vmdk'}]}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- tmpl = json.loads(
- self.request('/plugins/kimchi/templates/test-format').read()
- )
- self.assertEquals(tmpl['disks'][0]['format'], 'vmdk')
-
- def test_customized_tmpl(self):
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- tmpl = json.loads(
- self.request('/plugins/kimchi/templates/test').read()
- )
-
- # Update name
- new_name = u'kīмÑhÄ«Tmpl'
- new_tmpl_uri = '/plugins/kimchi/templates/%s' \
- % new_name.encode('utf-8')
- req = json.dumps({'name': new_name})
- resp = self.request('/plugins/kimchi/templates/test', req, 'PUT')
- self.assertEquals(303, resp.status)
- resp = self.request(new_tmpl_uri)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(new_name, update_tmpl['name'])
- del tmpl['name']
- del update_tmpl['name']
- self.assertEquals(tmpl, update_tmpl)
-
- # Update icon
- req = json.dumps({'icon': 'kimchi/images/icon-fedora.png'})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('kimchi/images/icon-fedora.png', update_tmpl['icon'])
-
- # Update os_distro and os_version
- req = json.dumps({'os_distro': 'fedora', 'os_version': '21'})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('fedora', update_tmpl['os_distro'])
- self.assertEquals('21', update_tmpl['os_version'])
-
- # Update cpus
- req = json.dumps({'cpus': 2})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(2, update_tmpl['cpus'])
-
- # Update memory
- req = json.dumps({'memory': 2048})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(2048, update_tmpl['memory'])
-
- # Update cpu_info
- resp = self.request(new_tmpl_uri)
- cpu_info = json.loads(resp.read())['cpu_info']
- self.assertEquals(cpu_info, {})
- self.assertEquals(cpu_info.get('topology'), None)
-
- cpu_info_data = {'cpu_info': {'topology': {'sockets': 1,
- 'cores': 2,
- 'threads': 1}}}
- resp = self.request(new_tmpl_uri, json.dumps(cpu_info_data), 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(update_tmpl['cpu_info'], cpu_info_data['cpu_info'])
-
- # Update cdrom
- cdrom_data = {'cdrom': '/tmp/mock2.iso'}
- resp = self.request(new_tmpl_uri, json.dumps(cdrom_data), 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(update_tmpl['cdrom'], cdrom_data['cdrom'])
-
- # Update disks
- disk_data = {'disks': [{'index': 0, 'size': 10},
- {'index': 1, 'size': 20}]}
- resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
- self.assertEquals(200, resp.status)
- resp = self.request(new_tmpl_uri)
- self.assertEquals(200, resp.status)
- updated_tmpl = json.loads(resp.read())
- self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
-
- # For all supported types, edit the template and check if
- # the change was made.
- disk_types = ['bochs', 'cloop', 'cow', 'dmg', 'qcow', 'qcow2',
- 'qed', 'raw', 'vmdk', 'vpc']
- for disk_type in disk_types:
- disk_data = {'disks': [{'index': 0, 'format': disk_type,
- 'size': 10}]}
- resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
- self.assertEquals(200, resp.status)
-
- resp = self.request(new_tmpl_uri)
- self.assertEquals(200, resp.status)
- updated_tmpl = json.loads(resp.read())
- self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
-
- # Update folder
- folder_data = {'folder': ['mock', 'isos']}
- resp = self.request(new_tmpl_uri, json.dumps(folder_data), 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(update_tmpl['folder'], folder_data['folder'])
-
- # Update graphics
- req = json.dumps({'graphics': {'type': 'spice'}})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('spice', update_tmpl['graphics']['type'])
-
- req = json.dumps({'graphics': {'type': 'vnc', 'listen': 'fe00::0'}})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('vnc', update_tmpl['graphics']['type'])
- self.assertEquals('fe00::0', update_tmpl['graphics']['listen'])
-
- def test_customized_network(self):
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create networks to be used for testing
- networks = [{'name': u'kīмÑhÄ«-пet', 'connection': 'isolated'},
- {'name': u'nat-network', 'connection': 'nat'},
- {'name': u'subnet-network', 'connection': 'nat',
- 'subnet': '127.0.100.0/24'}]
-
- # Verify the current system has at least one interface to create a
- # bridged network
- interfaces = json.loads(
- self.request('/plugins/kimchi/interfaces?type=nic').read()
- )
- if len(interfaces) > 0:
- iface = interfaces[0]['name']
- networks.append({'name': u'bridge-network', 'connection': 'bridge',
- 'interface': iface})
- networks.append({'name': u'bridge-network', 'connection': 'bridge',
- 'interface': iface, 'vlan_id': 987})
-
- tmpl_nets = []
- for net in networks:
- self.request('/plugins/kimchi/networks', json.dumps(net), 'POST')
- tmpl_nets.append(net['name'])
- req = json.dumps({'networks': tmpl_nets})
- resp = self.request('/plugins/kimchi/templates/test', req, 'PUT')
- self.assertEquals(200, resp.status)
-
- def test_customized_storagepool(self):
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # MockModel always returns 2 partitions (vdx, vdz)
- partitions = json.loads(
- self.request('/plugins/kimchi/host/partitions').read()
- )
- devs = [dev['path'] for dev in partitions]
-
- # MockModel always returns 3 FC devices
- fc_devs = json.loads(
- self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
- )
- fc_devs = [dev['name'] for dev in fc_devs]
-
- poolDefs = [
- {'type': 'dir', 'name': u'kīмÑhÄ«UnitTestDirPool',
- 'path': '/tmp/kimchi-images'},
- {'type': 'netfs', 'name': u'kīмÑhÄ«UnitTestNSFPool',
- 'source': {'host': 'localhost',
- 'path': '/var/lib/kimchi/nfs-pool'}},
- {'type': 'scsi', 'name': u'kīмÑhÄ«UnitTestSCSIFCPool',
- 'source': {'adapter_name': fc_devs[0]}},
- {'type': 'iscsi', 'name': u'kīмÑhÄ«UnitTestISCSIPool',
- 'source': {'host': '127.0.0.1',
- 'target': 'iqn.2015-01.localhost.kimchiUnitTest'}},
- {'type': 'logical', 'name': u'kīмÑhÄ«UnitTestLogicalPool',
- 'source': {'devices': [devs[0]]}}]
-
- for pool in poolDefs:
- self.request('/plugins/kimchi/storagepools', json.dumps(pool),
- 'POST')
- pool_uri = '/plugins/kimchi/storagepools/%s' \
- % pool['name'].encode('utf-8')
- self.request(pool_uri + '/activate', '{}', 'POST')
-
- req = None
- if pool['type'] in READONLY_POOL_TYPE:
- resp = self.request(pool_uri + '/storagevolumes')
- vols = json.loads(resp.read())
- if len(vols) > 0:
- vol = vols[0]['name']
- req = json.dumps({'storagepool': pool_uri,
- 'disks': [{'volume': vol}]})
- else:
- req = json.dumps({'storagepool': pool_uri})
-
- if req is not None:
- resp = self.request('/plugins/kimchi/templates/test', req,
- 'PUT')
- self.assertEquals(200, resp.status)
-
- def test_tmpl_integrity(self):
- # Create a network and a pool for testing template integrity
- net = {'name': u'nat-network', 'connection': 'nat'}
- self.request('/plugins/kimchi/networks', json.dumps(net), 'POST')
-
- pool = {'type': 'dir', 'name': 'dir-pool', 'path': '/tmp/dir-pool'}
- self.request('/plugins/kimchi/storagepools', json.dumps(pool), 'POST')
- pool_uri = '/plugins/kimchi/storagepools/%s' \
- % pool['name'].encode('utf-8')
- self.request(pool_uri + '/activate', '{}', 'POST')
-
- # Create a template using the custom network and pool
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso',
- 'networks': ['nat-network'],
- 'storagepool': '/plugins/kimchi/storagepools/dir-pool'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Try to delete network
- # It should fail as it is associated to a template
- resp = self.request('/plugins/kimchi/networks/nat-network', '{}',
- 'DELETE')
- self.assertIn("KCHNET0017E", json.loads(resp.read())["reason"])
-
- # Update template to release network and then delete it
- params = {'networks': []}
- req = json.dumps(params)
- self.request('/plugins/kimchi/templates/test', req, 'PUT')
- resp = self.request('/plugins/kimchi/networks/nat-network', '{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Try to delete the storagepool
- # It should fail as it is associated to a template
- resp = self.request('/plugins/kimchi/storagepools/dir-pool', '{}',
- 'DELETE')
- self.assertEquals(400, resp.status)
-
- # Verify the template
- res = json.loads(self.request('/plugins/kimchi/templates/test').read())
- self.assertEquals(res['invalid']['cdrom'], ['/tmp/mock.iso'])
diff --git a/plugins/kimchi/tests/test_utils.py b/plugins/kimchi/tests/test_utils.py
deleted file mode 100644
index bcb14e2..0000000
--- a/plugins/kimchi/tests/test_utils.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-
-from wok.exception import InvalidParameter
-from wok.utils import convert_data_size
-
-
-class UtilsTests(unittest.TestCase):
- def test_convert_data_size(self):
- failure_data = [{'val': None, 'from': 'MiB'},
- {'val': self, 'from': 'MiB'},
- {'val': 1, 'from': None},
- {'val': 1, 'from': ''},
- {'val': 1, 'from': 'foo'},
- {'val': 1, 'from': 'kib'},
- {'val': 1, 'from': 'MiB', 'to': None},
- {'val': 1, 'from': 'MiB', 'to': ''},
- {'val': 1, 'from': 'MiB', 'to': 'foo'},
- {'val': 1, 'from': 'MiB', 'to': 'kib'}]
-
- for d in failure_data:
- if 'to' in d:
- self.assertRaises(InvalidParameter, convert_data_size,
- d['val'], d['from'], d['to'])
- else:
- self.assertRaises(InvalidParameter, convert_data_size,
- d['val'], d['from'])
-
- success_data = [{'got': convert_data_size(5, 'MiB', 'MiB'),
- 'want': 5},
- {'got': convert_data_size(5, 'MiB', 'KiB'),
- 'want': 5120},
- {'got': convert_data_size(5, 'MiB', 'M'),
- 'want': 5.24288},
- {'got': convert_data_size(5, 'MiB', 'GiB'),
- 'want': 0.0048828125},
- {'got': convert_data_size(5, 'MiB', 'Tb'),
- 'want': 4.194304e-05},
- {'got': convert_data_size(5, 'KiB', 'MiB'),
- 'want': 0.0048828125},
- {'got': convert_data_size(5, 'M', 'MiB'),
- 'want': 4.76837158203125},
- {'got': convert_data_size(5, 'GiB', 'MiB'),
- 'want': 5120},
- {'got': convert_data_size(5, 'Tb', 'MiB'),
- 'want': 596046.4477539062},
- {'got': convert_data_size(5, 'MiB'),
- 'want': convert_data_size(5, 'MiB', 'B')}]
-
- for d in success_data:
- self.assertEquals(d['got'], d['want'])
diff --git a/plugins/kimchi/tests/test_vmtemplate.py b/plugins/kimchi/tests/test_vmtemplate.py
deleted file mode 100644
index 0bca215..0000000
--- a/plugins/kimchi/tests/test_vmtemplate.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import unittest
-import uuid
-
-from wok.xmlutils.utils import xpath_get_text
-
-from wok.plugins.kimchi.osinfo import get_template_default
-from wok.plugins.kimchi.vmtemplate import VMTemplate
-
-
-class VMTemplateTests(unittest.TestCase):
- def setUp(self):
- self.iso = '/tmp/mock.iso'
- open(self.iso, 'w').close()
-
- def tearDown(self):
- os.unlink(self.iso)
-
- def test_minimal_construct(self):
- disk_bus = get_template_default('old', 'disk_bus')
- memory = get_template_default('old', 'memory')
- nic_model = get_template_default('old', 'nic_model')
- fields = (('name', 'test'), ('os_distro', 'unknown'),
- ('os_version', 'unknown'), ('cpus', 1),
- ('memory', memory), ('networks', ['default']),
- ('disk_bus', disk_bus), ('nic_model', nic_model),
- ('graphics', {'type': 'vnc', 'listen': '127.0.0.1'}),
- ('cdrom', self.iso))
-
- args = {'name': 'test', 'cdrom': self.iso}
- t = VMTemplate(args)
- for name, val in fields:
- self.assertEquals(val, t.info.get(name))
-
- def test_construct_overrides(self):
- graphics = {'type': 'spice', 'listen': '127.0.0.1'}
- args = {'name': 'test', 'disks': [{'size': 10}, {'size': 20}],
- 'graphics': graphics, "cdrom": self.iso}
- t = VMTemplate(args)
- self.assertEquals(2, len(t.info['disks']))
- self.assertEquals(graphics, t.info['graphics'])
-
- def test_specified_graphics(self):
- # Test specified listen
- graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
- args = {'name': 'test', 'disks': [{'size': 10}, {'size': 20}],
- 'graphics': graphics, 'cdrom': self.iso}
- t = VMTemplate(args)
- self.assertEquals(graphics, t.info['graphics'])
-
- # Test specified type
- graphics = {'type': 'spice', 'listen': '127.0.0.1'}
- args['graphics'] = graphics
- t = VMTemplate(args)
- self.assertEquals(graphics, t.info['graphics'])
-
- # If no listen specified, test the default listen
- graphics = {'type': 'vnc'}
- args['graphics'] = graphics
- t = VMTemplate(args)
- self.assertEquals(graphics['type'], t.info['graphics']['type'])
- self.assertEquals('127.0.0.1', t.info['graphics']['listen'])
-
- def test_to_xml(self):
- graphics = {'type': 'spice', 'listen': '127.0.0.1'}
- vm_uuid = str(uuid.uuid4()).replace('-', '')
- if os.uname()[4] in ['ppc', 'ppc64', 'ppc64le']:
- maxmem = 3328
- else:
- maxmem = 3072
- t = VMTemplate({'name': 'test-template', 'cdrom': self.iso,
- 'max_memory': maxmem << 10})
- xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics)
- self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0])
- self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0])
- expr = "/domain/devices/graphics/@type"
- self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0])
- expr = "/domain/devices/graphics/@listen"
- self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0])
- expr = "/domain/maxMemory/@slots"
- self.assertEquals('2', xpath_get_text(xml, expr)[0])
-
- def test_arg_merging(self):
- """
- Make sure that default parameters from osinfo do not override user-
- provided parameters.
- """
- graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
- args = {'name': 'test', 'os_distro': 'opensuse', 'os_version': '12.3',
- 'cpus': 2, 'memory': 2048, 'networks': ['foo'],
- 'cdrom': self.iso, 'graphics': graphics}
- t = VMTemplate(args)
- self.assertEquals(2, t.info.get('cpus'))
- self.assertEquals(2048, t.info.get('memory'))
- self.assertEquals(['foo'], t.info.get('networks'))
- self.assertEquals(self.iso, t.info.get('cdrom'))
- self.assertEquals(graphics, t.info.get('graphics'))
diff --git a/plugins/kimchi/tests/test_yumparser.py b/plugins/kimchi/tests/test_yumparser.py
deleted file mode 100644
index be5e95c..0000000
--- a/plugins/kimchi/tests/test_yumparser.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import tempfile
-import unittest
-
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.model import model
-from wok.plugins.kimchi.yumparser import delete_repo_from_file, get_repo_files
-from wok.plugins.kimchi.yumparser import get_yum_packages_list_update
-from wok.plugins.kimchi.yumparser import get_yum_repositories
-from wok.plugins.kimchi.yumparser import write_repo_to_file, YumRepoObject
-
-
-TEMP_REPO_FILE = ''
-
-
-def _is_yum_distro():
- inst = model.Model('test:///default')
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- return repo_type == 'yum'
-
-
-def _create_fake_repos(repo_file_name):
- repo1 = YumRepoObject('fake-repo-1', repo_file_name)
- repo2 = YumRepoObject('fake-repo-2', repo_file_name)
- repo3 = YumRepoObject('fake-repo-3', repo_file_name)
- repo4 = YumRepoObject('fake-repo-4', repo_file_name)
- repos = [repo1, repo2, repo3, repo4]
- return repos
-
-
-def _create_empty_repo_file():
- data = """
-#
-# This is a repository file with no repositories at all
-# No repositories must be added after reading this file.
-#
- """
- _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
- dir='/etc/yum.repos.d')
- with open(tmp_file_name, 'w') as f:
- f.writelines(data)
-
- return tmp_file_name
-
-
-def _create_fake_repos_file():
- _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
- dir='/etc/yum.repos.d')
-
- fake_repos = _create_fake_repos(tmp_file_name)
- file_data = ''
- for repo in fake_repos:
- file_data += str(repo) + '\n'
-
- with open(tmp_file_name, 'w') as f:
- f.writelines(file_data)
-
- return tmp_file_name
-
-
-def _generate_yumcheckupdate_output():
- output = """
-Repository 'REPOSITORY1' is missing name in configuration, using id
-Repository 'REPOSITORY1-OPTIONAL' is missing name in configuration, using id
-
-PACKAGE1.noarch 20150611.-gg-FAKE1 REPOSITORY1
-PACKAGE2.x86_64 20150611.-no-FAKE2 REPOSITORY2
-PACKAGE3.dot.dot.i386 20150611.-re-FAKE3 REPOSITORY3
-
-Obsoleting Packages
-OBSOLETE4.dot.dot.i386 20150611.FAKE4 REPOSITORY4
-OBSOLETE5.dot.dot.fakearch 20150611.FAKE5 REPOSITORY5
- """
- return output
-
-
- at unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
-def setUpModule():
- global TEMP_REPO_FILE
- TEMP_REPO_FILE = _create_fake_repos_file()
-
-
- at unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
-def tearDownModule():
- os.remove(TEMP_REPO_FILE)
-
-
- at unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
-class YumParserTests(unittest.TestCase):
-
- def test_get_yum_repositories(self):
- repo_files = get_repo_files()
- repo_objects = get_yum_repositories()
- self.assertGreaterEqual(len(repo_objects), len(repo_files))
-
- def test_empty_repo_file(self):
- with RollbackContext() as rollback:
- repos = get_yum_repositories()
- tmp_file_name = _create_empty_repo_file()
- rollback.prependDefer(os.remove, tmp_file_name)
- repos_after = get_yum_repositories()
- self.assertEqual(len(repos_after), len(repos))
-
- def test_update_repo_attributes(self):
- repos = get_yum_repositories()
- fake_repo_2 = repos['fake-repo-2']
- fake_repo_2.disable()
- fake_repo_2.name = 'This is a fake repo'
- fake_repo_2.baseurl = 'http://a.fake.repo.url'
- fake_repo_2.gpgkey = 'file://a/fake/gpg/key.fake'
- fake_repo_2.gpgcheck = False
- fake_repo_2.metalink = 'this is not a true metalink'
- fake_repo_2.mirrorlist = 'fake mirrorlist'
- write_repo_to_file(fake_repo_2)
-
- repos = get_yum_repositories()
- fake_repo_2 = repos['fake-repo-2']
- self.assertEqual(False, fake_repo_2.enabled)
- self.assertEqual(False, fake_repo_2.gpgcheck)
- self.assertEqual('This is a fake repo', fake_repo_2.name)
- self.assertEqual('http://a.fake.repo.url', fake_repo_2.baseurl)
- self.assertEqual('file://a/fake/gpg/key.fake', fake_repo_2.gpgkey)
- self.assertEqual('this is not a true metalink', fake_repo_2.metalink)
- self.assertEqual('fake mirrorlist', fake_repo_2.mirrorlist)
-
- def test_delete_repo_from_file(self):
- repos = get_yum_repositories()
- fake_repo_3 = repos['fake-repo-3']
- delete_repo_from_file(fake_repo_3)
-
- repos = get_yum_repositories()
- repos_id = repos.keys()
- self.assertNotIn('fake-repo-3', repos_id)
-
- def test_yum_checkupdate_parsing(self):
- output = _generate_yumcheckupdate_output()
- packages = get_yum_packages_list_update(output)
- self.assertEqual(len(packages), 3)
- self.assertEqual(packages[0].ui_from_repo, 'REPOSITORY1')
- self.assertEqual(packages[1].version, '20150611.-no-FAKE2')
- self.assertEqual(packages[2].name, 'PACKAGE3.dot.dot')
- self.assertEqual(packages[2].arch, 'i386')
diff --git a/plugins/kimchi/tests/utils.py b/plugins/kimchi/tests/utils.py
deleted file mode 100644
index ecaa87f..0000000
--- a/plugins/kimchi/tests/utils.py
+++ /dev/null
@@ -1,260 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import base64
-import cherrypy
-import grp
-import httplib
-import inspect
-import json
-import os
-import socket
-import ssl
-import sys
-import threading
-import time
-import unittest
-from contextlib import closing
-from lxml import etree
-
-import wok.server
-from wok.config import config, PluginPaths
-from wok.auth import User, USER_NAME, USER_GROUPS, USER_ROLES, tabs
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import wok_log
-
-from wok.plugins.kimchi import mockmodel
-
-
-_ports = {}
-
-# provide missing unittest decorators and API for python 2.6; these decorators
-# do not actually work, just avoid the syntax failure
-if sys.version_info[:2] == (2, 6):
- def skipUnless(condition, reason):
- if not condition:
- sys.stderr.write('[expected failure] ')
- raise Exception(reason)
- return lambda obj: obj
-
- unittest.skipUnless = skipUnless
- unittest.expectedFailure = lambda obj: obj
-
- def assertGreater(self, a, b, msg=None):
- if not a > b:
- self.fail('%s not greater than %s' % (repr(a), repr(b)))
-
- def assertGreaterEqual(self, a, b, msg=None):
- if not a >= b:
- self.fail('%s not greater than or equal to %s'
- % (repr(a), repr(b)))
-
- def assertIsInstance(self, obj, cls, msg=None):
- if not isinstance(obj, cls):
- self.fail('%s is not an instance of %r' % (repr(obj), cls))
-
- def assertIn(self, a, b, msg=None):
- if a not in b:
- self.fail("%s is not in %b" % (repr(a), repr(b)))
-
- def assertNotIn(self, a, b, msg=None):
- if a in b:
- self.fail("%s is in %b" % (repr(a), repr(b)))
-
- unittest.TestCase.assertGreaterEqual = assertGreaterEqual
- unittest.TestCase.assertGreater = assertGreater
- unittest.TestCase.assertIsInstance = assertIsInstance
- unittest.TestCase.assertIn = assertIn
- unittest.TestCase.assertNotIn = assertNotIn
-
-
-def get_free_port(name='http'):
- global _ports
- if _ports.get(name) is not None:
- return _ports[name]
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- with closing(sock):
- try:
- sock.bind(("0.0.0.0", 0))
- except:
- raise Exception("Could not find a free port")
- _ports[name] = sock.getsockname()[1]
- return _ports[name]
-
-
-def run_server(host, port, ssl_port, test_mode, cherrypy_port=None,
- model=None, environment='development'):
-
- if cherrypy_port is None:
- cherrypy_port = get_free_port('cherrypy_port')
-
- if ssl_port is None:
- ssl_port = get_free_port('https')
-
- args = type('_', (object,),
- {'host': host, 'port': port, 'ssl_port': ssl_port,
- 'cherrypy_port': cherrypy_port, 'max_body_size': '4*1024',
- 'ssl_cert': '', 'ssl_key': '',
- 'test': test_mode, 'access_log': '/dev/null',
- 'error_log': '/dev/null', 'environment': environment,
- 'log_level': 'debug'})()
- if model is not None:
- setattr(args, 'model', model)
-
- s = wok.server.Server(args)
- t = threading.Thread(target=s.start)
- t.setDaemon(True)
- t.start()
- cherrypy.engine.wait(cherrypy.engine.states.STARTED)
- return s
-
-
-def silence_server():
- """
- Silence server status messages on stdout
- """
- cherrypy.config.update({"environment": "embedded"})
-
-
-def running_as_root():
- return os.geteuid() == 0
-
-
-def _request(conn, path, data, method, headers):
- if headers is None:
- headers = {'Content-Type': 'application/json',
- 'Accept': 'application/json'}
- if 'AUTHORIZATION' not in headers.keys():
- user, pw = mockmodel.fake_user.items()[0]
- hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
- headers['AUTHORIZATION'] = hdr
- conn.request(method, path, data, headers)
- return conn.getresponse()
-
-
-def request(host, port, path, data=None, method='GET', headers=None):
- # verify if HTTPSConnection has context parameter
- if "context" in inspect.getargspec(httplib.HTTPSConnection.__init__).args:
- context = ssl._create_unverified_context()
- conn = httplib.HTTPSConnection(host, port, context=context)
- else:
- conn = httplib.HTTPSConnection(host, port)
-
- return _request(conn, path, data, method, headers)
-
-
-def get_remote_iso_path():
- """
- Get a remote iso with the right arch from the distro files shipped
- with kimchi.
- """
- host_arch = os.uname()[4]
- remote_path = ''
- with open(os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d',
- 'fedora.json')) as fedora_isos:
- # Get a list of dicts
- json_isos_list = json.load(fedora_isos)
- for iso in json_isos_list:
- if (iso.get('os_arch')) == host_arch:
- remote_path = iso.get('path')
- break
-
- return remote_path
-
-
-class FakeUser(User):
- auth_type = "fake"
- sudo = True
-
- def __init__(self, username):
- self.user = {}
- self.user[USER_NAME] = username
- self.user[USER_GROUPS] = None
- self.user[USER_ROLES] = dict.fromkeys(tabs, 'user')
-
- def get_groups(self):
- return sorted([group.gr_name for group in grp.getgrall()])[0:3]
-
- def get_roles(self):
- if self.sudo:
- self.user[USER_ROLES] = dict.fromkeys(tabs, 'admin')
- return self.user[USER_ROLES]
-
- def get_user(self):
- return self.user
-
- @staticmethod
- def authenticate(username, password, service="passwd"):
- try:
- return mockmodel.fake_user[username] == password
- except KeyError, e:
- raise OperationFailed("WOKAUTH0001E", {'username': 'username',
- 'code': e.message})
-
-
-def patch_auth(sudo=True):
- """
- Override the authenticate function with a simple test against an
- internal dict of users and passwords.
- """
- config.set("authentication", "method", "fake")
- FakeUser.sudo = sudo
-
-
-def normalize_xml(xml_str):
- return etree.tostring(etree.fromstring(xml_str,
- etree.XMLParser(remove_blank_text=True)))
-
-
-def wait_task(task_lookup, taskid, timeout=10):
- for i in range(0, timeout):
- task_info = task_lookup(taskid)
- if task_info['status'] == "running":
- wok_log.info("Waiting task %s, message: %s",
- taskid, task_info['message'])
- time.sleep(1)
- else:
- return
- wok_log.error("Timeout while process long-run task, "
- "try to increase timeout value.")
-
-
-# The action functions in model backend raise NotFoundError exception if the
-# element is not found. But in some tests, these functions are called after
-# the element has been deleted if test finishes correctly, then NofFoundError
-# exception is raised and rollback breaks. To avoid it, this wrapper ignores
-# the NotFoundError.
-def rollback_wrapper(func, resource, *args):
- try:
- func(resource, *args)
- except NotFoundError:
- # VM has been deleted already
- return
-
-
-# This function is used to test storage volume upload.
-# If we use self.request, we may encode multipart formdata by ourselves
-# requests lib take care of encode part, so use this lib instead
-def fake_auth_header():
- headers = {'Accept': 'application/json'}
- user, pw = mockmodel.fake_user.items()[0]
- hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
- headers['AUTHORIZATION'] = hdr
- return headers
diff --git a/plugins/kimchi/ui/Makefile.am b/plugins/kimchi/ui/Makefile.am
deleted file mode 100644
index 21fe703..0000000
--- a/plugins/kimchi/ui/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-SUBDIRS = config css images js pages spice-html5
-
-uidir = $(datadir)/wok/plugins/kimchi/ui
diff --git a/plugins/kimchi/ui/config/Makefile.am b/plugins/kimchi/ui/config/Makefile.am
deleted file mode 100644
index e3b3d19..0000000
--- a/plugins/kimchi/ui/config/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-xmldir = $(datadir)/wok/plugins/kimchi/ui/config
-
-dist_xml_DATA = \
- tab-ext.xml \
- $(NULL)
diff --git a/plugins/kimchi/ui/config/tab-ext.xml b/plugins/kimchi/ui/config/tab-ext.xml
deleted file mode 100644
index ee88c88..0000000
--- a/plugins/kimchi/ui/config/tab-ext.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<tabs-ext>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>Host</title>
- <path>plugins/kimchi/host.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="byInstance"/>
-
- <title>Guests</title>
- <path>plugins/kimchi/guests.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>Templates</title>
- <path>plugins/kimchi/templates.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="read-only"/>
-
- <title>Storage</title>
- <path>plugins/kimchi/storage.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="read-only"/>
-
- <title>Network</title>
- <path>plugins/kimchi/network.html</path>
- </tab>
-</tabs-ext>
diff --git a/plugins/kimchi/ui/css/Makefile.am b/plugins/kimchi/ui/css/Makefile.am
deleted file mode 100644
index 5071d29..0000000
--- a/plugins/kimchi/ui/css/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-EXTRA_DIST = theme-default
-
-cssdir = $(datadir)/wok/plugins/kimchi/ui/css
-dist_css_DATA = theme-default.min.css
-
-theme-default.min.css: theme-default/*.css
- cat $^ > $@
-
-CLEANFILES = theme-default.min.css
diff --git a/plugins/kimchi/ui/css/theme-default/guest-edit.css b/plugins/kimchi/ui/css/theme-default/guest-edit.css
deleted file mode 100644
index b661159..0000000
--- a/plugins/kimchi/ui/css/theme-default/guest-edit.css
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-#guest-edit-window {
- font-size: 13px;
- height: 420px;
- width: 820px;
-}
-
-#guest-edit-window #action-button-container {
- padding-right: 0;
-}
-
-#guest-edit-window #guest-edit-button-cancel {
- margin-left: 10px;
-}
-
-#guest-edit-tabs {
- background: transparent;
- border: none;
- height: 100%;
- padding: 0;
-}
-
-#form-guest-edit-general {
- padding: 1em;
-}
-
-#form-guest-edit-general .edit-general-inline {
- display: inline-block;
-}
-
-#form-guest-edit-storage input[readonly] {
- background: none;
- border-color: transparent;
- text-overflow: ellipsis;
-}
-
-.guest-edit-fieldset {
- padding-right: 0;
-}
-
-.guest-edit-wrapper-label {
- height: 30px;
- line-height: 30px;
- margin-top: 10px;
- vertical-align: top;
- min-width: 100px;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
-
-#form-guest-edit-storage .guest-edit-wrapper-label {
- width: 60px;
-}
-
-.guest-edit-wrapper-controls {
- width: 470px;
- margin-top: 5px;Ã
-}
-
-#form-guest-edit-storage .guest-edit-wrapper-controls {
- width: 486px;
-}
-
-.guest-edit-wrapper-controls input[type="text"] {
- font-size: 16px;
- height: 30px;
- width: 450px;
- border: 1px solid #CCCCCC;
-}
-
-.guest-edit-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
- border: 1px solid #CCCCCC;
-}
-
-.guest-edit-cdrom-row-container {
- max-height: 180px;
- overflow: auto;
-}
-
-.guest-edit-cdrom-row-container input[type="text"] {
- width: 400px;
-}
-
-#form-guest-edit-storage .header,
-.guest-edit-snapshot .header,
-.guest-edit-interface .header,
-#form-guest-edit-permission .ldap .header {
- margin-bottom: 8px;
- padding-bottom: 2px;
- font-weight: bold;
- border-bottom: 1px solid #999999;
- overflow: hidden;
-}
-
-#form-guest-edit-storage .body .item,
-.guest-edit-snapshot .body .item,
-.guest-edit-snapshot .task .item,
-.guest-edit-interface .body .item {
- margin: 5px 0;
-}
-
-#form-guest-edit-storage .cell,
-.guest-edit-interface .cell {
- display: inline-block;
- width: 200px;
-}
-
-.guest-edit-snapshot .cell {
- display: inline-block;
-}
-
-.guest-edit-snapshot .sel {
- width: 25px;
- vertical-align: top;
-}
-
-.guest-edit-snapshot .icon {
- background: url('../images/theme-default/kimchi-loading15x15.gif') no-repeat;
- display: block;
- width: 16px;
- height: 16px;
- vertical-align: middle;
- margin-left: 2px;
-}
-
-.guest-edit-snapshot .name {
- width: 400px;
-}
-
-.guest-edit-snapshot .created {
- width: 270px;
-}
-
-#form-guest-edit-storage .cell.dev {
- width: 60px;
-}
-
-#form-guest-edit-storage .cell.path {
- width: 440px;
-}
-
-#form-guest-edit-storage .cell.dev input,
-#form-guest-edit-storage .cell.path input {
- box-sizing: border-box;
- width: 100%;
-}
-
-.guest-edit-interface .body select {
- width: 180px;
- padding: 0px;
-}
-
-#form-guest-edit-storage .action-area,
-.guest-edit-snapshot .action-area,
-.guest-edit-interface .action-area {
- float: right;
-}
-
-#form-guest-edit-storage .action-area {
- line-height: 24px;
-}
-
-#form-guest-edit-storage button,
-.guest-edit-snapshot button,
-.guest-edit-interface button {
- width: 20px;
- height: 20px;
-}
-
-#form-guest-edit-storage .body button:not(:last-child),
-.guest-edit-interface .body button:not(:last-child) {
- margin-right: 2px;
-}
-
-.guest-edit-snapshot .hide,
-.guest-edit-interface .hide {
- display: none!important;
-}
-
-.guest-edit-permission .pam {
- height: 220px;
- padding: 5px 10px!important;
-}
-
-.guest-edit-permission .hide {
- display: none;
-}
-
-.guest-edit-permission .pam .column {
- display: inline-block;
- vertical-align: top;
-}
-
-.guest-edit-permission .pam .title {
- margin-bottom: 3px;
-}
-
-.guest-edit-permission .pam input[type="text"] {
- margin-bottom: 3px;
- font-size: 12px;
- width: 97%;
-}
-
-.guest-edit-permission .pam .body {
- border: 1px solid #999999;
- font-size: 12px;
- padding: 1px;
- height: 192px;
- overflow: auto;
-}
-
-.guest-edit-permission .pam .body .head {
- margin-bottom: 3px;
- font-weight: bold;
- background: linear-gradient(to bottom, #E5E5E5 0%, #C4C4C4 100%) repeat scroll 0 0 transparent;
-}
-
-.guest-edit-permission .pam .body .item {
- padding: 2px 3px;
- margin-bottom: 1px;
- cursor: pointer;
-}
-
-.guest-edit-permission .pam .body .item:hover {
- background-color: #AAAAAA;
-}
-
-.guest-edit-permission .pam .body .item-picked {
- background-color: #BBBBBB;
-}
-
-.guest-edit-permission .pam .body .item .icon {
- display: inline-block;
- height: 15px;
- width: 15px;
- vertical-align: bottom;
-}
-
-.guest-edit-permission .pam .body .item .user-icon {
- background: url('../images/theme-default/user.png') no-repeat scroll;
- background-size: 15px 15px;
-}
-
-.guest-edit-permission .pam .body .item .group-icon {
- background: url('../images/theme-default/group.png') no-repeat scroll;
- background-size: 15px 15px;
-}
-
-.guest-edit-permission .pam .body .column-user {
- width: 48%;
-}
-.guest-edit-permission .pam .body .column-group {
- width: 50%;
-}
-
-.guest-edit-permission .pam .control {
- width: 5%;
-}
-
-.guest-edit-permission .pam .control button {
- width: 26px;
- margin-left: 7px;
-}
-
-.guest-edit-permission .pam .control button:first-child {
- margin-top: 110px;
- margin-bottom: 2px;
-}
-
-.guest-edit-permission .pam .control .ui-button-text-only .ui-button-text {
- padding: 2px 8px;
-}
-
-.guest-edit-permission .pam .avail {
- width: 46%;
-}
-
-.guest-edit-permission .pam .selected {
- width: 46%;
- float: right;
-}
-
-#form-guest-edit-permission .ldap .body .item {
- margin: 8px 0;
-}
-
-#form-guest-edit-permission .ldap .cell {
- width: 250px;
-}
-
-#form-guest-edit-permission .ldap .action-area {
- float: right;
- line-height: 24px;
-}
-
-#form-guest-edit-permission .ldap button {
- width: 20px;
- height: 20px;
-}
-
-#form-guest-edit-permission input[type="text"] {
- width: 300px;
-}
-
-#form-guest-edit-permission .ldap .header button {
- margin-bottom: 1px;
-}
-
-#form-guest-edit-permission .ldap .checked {
- border-color: red;
- border-style: solid;
- border-width: 1px;
-}
-
-#form-guest-edit-permission .ldap .checked.hide {
- display: none;
-}
-
-.guest-edit-pci {
- height: 79%;
- overflow: auto;
- font-size: 12px;
-}
-
-.guest-edit-pci .guest-scroll-indent {
- width: 783px;
-}
-
-.guest-edit-pci .filter {
- height: 35px;
- margin-right: 5px;
- overflow: hidden;
-}
-
-.guest-edit-pci .group {
- float: right;
-}
-
-.guest-edit-pci .filter .control {
- border: 1px solid #AAAAAA;
- font-size: 12px;
- background-color: white;
-}
-
-.guest-edit-pci .filter select {
- border-right: 0px!important;
- border-radius: 7px 0px 0px 7px;
- padding: 2px 2px 2px 7px;
- width: 100px;
- height: 24px;
-}
-
-.guest-edit-pci .filter select option {
- padding-left: 7px;
-}
-
-.guest-edit-pci .filter input {
- border-radius: 0px 7px 7px 0px;
- padding: 3px 3px 3px 10px;
- width: 200px;
- height: 16px;
- font-style: italic;
-}
-
-.guest-edit-pci .header {
- margin-bottom: 8px;
- padding-bottom: 2px;
- font-weight: bold;
- border-bottom: 1px solid #999999;
-}
-
-.guest-edit-pci .item {
- margin-bottom: 4px;
- overflow: hidden;
-}
-
-.guest-edit-pci .cell {
- display: inline-block;
- vertical-align: middle;
- margin-right: 10px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.guest-edit-pci .item button {
- width: 20px;
- height: 20px;
- float: right;
-}
-
-.guest-edit-pci .name {
- width: 18%;
- max-width: 18%;
-}
-
-.guest-edit-pci .product {
- width: 45%;
- max-width: 45%;
-}
-
-.guest-edit-pci .vendor {
- width: 25%;
- max-width: 25%;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/guest-storage-add.css b/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
deleted file mode 100644
index 9cc41e8..0000000
--- a/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-#guest-storage-add-window {
- font-size: 13px;
- height: 600px;
- width: 700px;
-}
-
-.guest-storage-add-fieldset {
- padding: 1em;
-}
-
-#guest-storage-add-window .btn {
- width: 587px;
-}
-
-#form-guest-storage-add .form-section .field {
- overflow: visible;
-}
-
-#guest-storage-add-window input[type="text"] {
- font-size: 16px;
- height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding-left: 10px;
- width: 600px;
-}
-
-#guest-storage-add-window input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-.guest-storage-add-wrapper-label, .guest-storage-add-wrapper-controls {
- display: inline-block;
-}
-
-.guest-storage-add-wrapper-label {
- height: 38px;
- line-height: 38px;
- margin-top: 5px;
- vertical-align: top;
- width: 80px;
-}
-
-.guest-storage-add-wrapper-controls {
- width: 470px;
-}
-
-#vm-storage-button-add[disabled] {
- background: #c0c0c0;
- color: #ddd;
- padding-left: 26px;
-}
-
-#vm-storage-button-add.loading[disabled] {
- background: url("../../images/theme-default/loading.gif") 7px center no-repeat #c0c0c0;
- color: #ddd;
- padding-left: 26px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/host.css b/plugins/kimchi/ui/css/theme-default/host.css
deleted file mode 100644
index a0cccb1..0000000
--- a/plugins/kimchi/ui/css/theme-default/host.css
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-.host-panel {
- font-size: 12px;
- margin-bottom: 100px;
-}
-
-.host-panel .logo-container, .host-panel .info-container,
-.host-panel .section-label, .host-panel .section-value {
- display: inline-block;
- vertical-align: top;
-}
-
-.host-panel .section-label {
- display: inline-block;
- margin-right: 1em;
- vertical-align: top;
-}
-
-.host-panel .logo {
- background: url("plugins/kimchi/images/icon-vm.png") no-repeat left top;
- height: 128px;
- width: 128px;
-}
-
-.host-panel .hostname {
- text-decoration: underline;
-}
-
-.host-panel .action-panel {
- margin-top: 2em;
- padding-left: 10px;
-}
-
-.host-panel .button-icon {
- background: url("../images/theme-default/host-icon-sprite.png") no-repeat
- left top;
- display: inline-block;
- height: 12px;
- width: 12px;
-}
-
-.host-panel .action-icon-stop {
- background-position: -14px 0;
-}
-
-.host-panel .action-icon-restart {
- background-position: -28px 0;
-}
-
-.host-panel .action-icon-download {
- background-position: -42px 0;
-}
-
-.host-panel .action-icon-connect {
- background-position: -56px 0;
-}
-
-.host-panel .action-icon-add {
- background-position: -70px 0;
-}
-
-.host-panel .action-icon-edit {
- background-position: -84px 0;
-}
-
-.host-panel .action-icon-remove {
- background-position: -98px 0;
-}
-
-.host-panel button:disabled .action-icon-start {
- background-position: 0 -14px;
-}
-
-.host-panel button:disabled .action-icon-stop {
- background-position: -14px -14px;
-}
-
-.host-panel button:disabled .action-icon-restart {
- background-position: -28px -14px;
-}
-
-.host-panel button:disabled .action-icon-download {
- background-position: -42px -14px;
-}
-
-.host-panel button:disabled .action-icon-connect {
- background-position: -56px -14px;
-}
-
-.host-panel button:disabled .action-icon-add {
- background-position: -70px -14px;
-}
-
-.host-panel button:disabled .action-icon-edit {
- background-position: -84px -14px;
-}
-
-.host-panel button:disabled .action-icon-remove {
- background-position: -98px -14px;
-}
-
-.host-panel .info-container {
- padding-top: 16px;
- width: 890px;
-}
-
-.host-panel .section-header {
- background: #EEE;
- border-radius: 5px;
- cursor: pointer;
- line-height: 2em;
- margin: 1em 0 1em;
- padding-left: 6px;
-}
-
-.host-panel .section-header:hover {
- background: #06f;
- color: white;
-}
-
-.host-panel .section-content {
- padding-left: 1em;
-}
-
-.host-panel .section-header .arrow {
- border-color: transparent;
- border-style: solid;
- display: inline-block;
- margin-right: 6px;
- width: 0;
-}
-
-.host-panel .section-header[aria-expanded="true"] .arrow {
- border-top-color: black;
- border-width: 8px 4px 0;
- border-bottom: none;
-}
-
-.host-panel .section-header[aria-expanded="true"]:hover .arrow {
- border-top-color: white;
-}
-
-.host-panel .section-header[aria-expanded="false"] .arrow {
- border-left-color: black;
- border-right: none;
- border-width: 4px 0 4px 8px;
-}
-
-.host-panel .section-header[aria-expanded="false"]:hover .arrow {
- border-left-color: white;
-}
-
-.host-panel .section-row {
- line-height: 1.6em;
- margin-bottom: 1em;
-}
-
-.host-panel .section-label {
- width: 100px;
-}
-
-#frequency-textbox {
- width: 20px;
-}
-
-#container-chart-cpu,
-#container-chart-memory,
-#container-chart-disk-io,
-#container-chart-network-io {
- border: 1px solid white;
- box-shadow: 2px 2px 2px gray, 2px -2px 2px gray, -2px -2px 2px gray, -2px
- 2px 2px gray;
- height: 100px;
- width: 500px;
-}
-
-#container-chart-disk-io .disk-write,
-#container-chart-network-io .network-sent {
- stroke: #f80;
-}
-
-/* Debug Report */
-.cell-text-wrapper {
- margin-left: 10px;
-}
-
-.host-panel #available-reports-grid {
- border-color: #ddd;
- height: 400px;
- width: 850px;
-}
-
-.host-panel select#available-reports-list {
- width: 300px;
-}
-
-.host-panel select#available-reports-list option {
- margin: .2em 1em;
-}
-
-.debug-report-name,
-.debug-report-time {
- width: 424px;
-}
-
-#id-debug-img {
- background: url(../images/theme-default/kimchi-loading15x15.gif) 12px
- center no-repeat;
- padding-left: 23px;
-}
-
-/* End of Debug Report */
-
-/* Software Updates */
-.host-panel #software-updates-grid {
- border-color: #ddd;
- height: 300px;
- width: 850px;
-}
-
-.software-update-name,
-.software-update-repos {
- width: 224px;
-}
-
-.software-update-version,
-.software-update-arch {
- width: 200px;
-}
-
-.host-panel #software-updates-progress-textarea {
- border: 1px solid #ddd;
- box-sizing: border-box;
- height: 100px;
- padding: .2em .5em;
- resize: vertical;
- width: 852px;
-}
-/* End of Software Updates */
-
-/* Repository */
-.host-panel #repositories-grid {
- border-color: #ddd;
- height: 200px;
- width: 850px;
-}
-
-.host-panel #repositories-grid .repository-id {
- width: 120px;
-}
-
-.host-panel #repositories-grid .repository-name {
- width: 640px;
-}
-
-.host-panel #repositories-grid .repository-enabled {
- width: 88px;
-}
-
-.host-panel #repositories-grid .repository-baseurl.deb {
- width: 400px;
-}
-
-.host-panel #repositories-grid .repository-enabled.deb {
- width: 100px;
-}
-
-.host-panel #repositories-grid .repository-gpgcheck.deb {
- width: 150px;
-}
-/* End of Repository */
diff --git a/plugins/kimchi/ui/css/theme-default/icon.css b/plugins/kimchi/ui/css/theme-default/icon.css
deleted file mode 100644
index f82d45d..0000000
--- a/plugins/kimchi/ui/css/theme-default/icon.css
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
- /* Generated at http://colorzilla.com/gradient-editor/ */
-
-.btn.loading {
- box-shadow: none;
- cursor: default;
-}
-
-.btn.loading .icon {
- background: url(../images/theme-default/icon-load.png) center
- center no-repeat;
-}
-
-.btn.pause-gray .icon {
- background: url(../images/theme-default/ac22_pause_grey.png) center
- center no-repeat;
-}
-
-.btn.resume-gray .icon {
- background: url(../images/theme-default/ac24_resume_grey.png) center
- center no-repeat;
-}
-
-.icon.reset {
- background: url(../images/theme-default/icon-reset.png) center
- center no-repeat;
-}
-
-.icon.power-up {
- background: url(../images/theme-default/icon-power-up.png) center
- center no-repeat;
-}
-
-.icon.power-down {
- background: url(../images/theme-default/icon-power-down.png) center
- center no-repeat;
-}
-
-.icon.pause {
- background: url(../images/theme-default/ac22_pause.png) center
- center no-repeat;
-}
-
-.icon.resume {
- background: url(../images/theme-default/ac24_resume.png) center
- center no-repeat;
-}
-
-.icon.search {
- background: url(../images/theme-default/icon-search.png) no-repeat
- center center;
-}
-
-.icon.sort {
- background: url(../images/theme-default/icon-sort.png) no-repeat
- center center;
-}
-
-.icon.design {
- background: url(../images/theme-default/icon-design.png) no-repeat
- center center;
-}
-
-.icon.list {
- background: url(../images/theme-default/icon-list.png) no-repeat
- center center;
-}
-
-.icon.detail {
- background: url(../images/theme-default/icon-detail.png) no-repeat
- center center;
-}
-
-.icon.add {
- line-height: 32px;
- text-align: center;
- text-shadow: -1px -1px 1px #aaa, 1px 1px 1px #eee;
- font-size: 38px;
- font-weight: bold;
- color: #7cae0a;
-}
-
-.icon.tree {
- width: 42px;
- background: url(../images/theme-default/icon-tree.png) no-repeat
- center center;
-}
-
-
diff --git a/plugins/kimchi/ui/css/theme-default/list.css b/plugins/kimchi/ui/css/theme-default/list.css
deleted file mode 100644
index 8c78623..0000000
--- a/plugins/kimchi/ui/css/theme-default/list.css
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-.list-vm {
- margin: 10px;
-}
-
-/* Generated at http://colorzilla.com/gradient-editor/ */
-.list-vm>li {
- margin-bottom: 10px;
- background: #ffffff;
- background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -webkit-gradient(linear, left top, left bottom,
- color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
- background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
- endColorstr='#e5e5e5', GradientType=0);
- border: 1px solid #ccc;
- color: #333;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
-}
-
-.list-vm li>* {
- height: 130px;
- display: table-cell;
- vertical-align: top;
- position: relative;
- border-left: 1px solid #ccc;
- border-right: 1px solid #fff;
-}
-
-.list-vm li>*:FIRST-CHILD {
- border-left: none;
-}
-
-.list-vm li>*:LAST-CHILD {
- border-right: none;
-}
-
-.list-vm li>.guest-tile{
- text-align: center;
- vertical-align: middle;
-}
-
-.list-vm .handle {
- display: block;
- width: 50px;
- height: 130px;
- box-sizing: border-box;
- box-shadow: inset 4px 4px 4px #0289e2, inset -4px -4px 4px #04385d;
- background: #0b6bad url(../images/theme-default/arrow_out.png) center
- center no-repeat;
- border-top-right: 1px solid #CCC;
- -webkit-border-top-right-radius: 8px;
- -moz-border-top-right-radius: 8px;
- border-top-right-radius: 8px;
- border-bottom-right: 1px solid #CCC;
- -webkit-border-bottom-right-radius: 8px;
- -moz-border-bottom-right-radius: 8px;
- border-bottom-right-radius: 8px;
-}
-
-.list-vm .subtitle {
- color: #666;
- font-size: 13px;
- text-align: center;
- line-height: 10px;
- font-weight: bold;
-}
-
-.list-vm .tile .imgload {
- display: none;
-}
-
-.list-vm .tile.shutoff .imgactive {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- display:inline;
- border: none;
- position: relative;
-}
-
-.list-vm .tile.paused .imgactive {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- display:inline;
- border: none;
- position: relative;
-}
-
-.list-vm .tile.running .imgactive{
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- display:inline;
- border: none;
- cursor: crosshair;
- cursor: -moz-zoom-in;
- cursor: -webkit-zoom-in;
-}
-
-.list-vm .tile .overlay {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- position:absolute;
- bottom:0;
- right:0;
- display:none;
-}
-
-.guest-type {
- width: 257px;
-}
-
-.guest-cpu {
- width: 91px;
-}
-
-.guest-network {
- width: 91px;
-}
-
-.guest-storage {
- width: 91px;
-}
-
-.guest-tile {
- width: 190px;
-}
-
-.guest-users {
- width: 93px;
-}
-
-.guest-actions {
- width: 125px;
- min-width: 125px;
-}
-
-.guest-handle {
- width: 50px;
-}
-
-.guest-general {
- padding: 10px;
- border-bottom: 1px solid #ccc;
- width: 237px;
-}
-
-.guest-ip {
- padding: 0 10px;
- border-top: 1px solid #fff;
-}
-
-.guest-general .title {
- color: #666;
- font-size: 16px;
- font-weight: normal;
- height: 25px;
- line-height: 25px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- max-width: 237px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.guest-general .text {
- font-weight: bold;
- color: #999;
- font-size: 11px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
-}
-
-.guest-users .top {
- border-bottom: 1px solid #ccc;
- padding: 3px 10px;
-}
-
-.guest-users .bottom {
- border-top: 1px solid #fff;
- padding: 3px 10px;
-}
-
-.guest-users .users {
- height: 45px;
- line-height: 45px;
- background: url(../images/theme-default/icon-user.png) left
- center no-repeat;
- padding-left: 50px;
- font-size: 36px;
- font-weight: bold;
-}
-
-.guest-users .snapshots {
- height: 40px;
- line-height: 40px;
- background: url(../images/theme-default/icon-camera.png) left
- center no-repeat;
- padding-left: 50px;
- font-size: 36px;
- font-weight: bold;
-}
-
-.guest-users .mini-text {
- font-size: 11px;
- font-weight: normal;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
-}
-
-.guest-actions .top {
- padding: 7px 10px;
- width: 200px;
-}
-
-.guest-actions .top button {
- display: inline-block;
- width: 42px;
- height: 42px;
-}
-
- at -moz-document url-prefix() {
- .guest-actions .top button span {
- margin-left: -3px;
- margin-top: -1px;
- }
-}
-
-.guest-actions .bottom {
- padding: 0 10px;
-}
-
-.list-vm .tile {
- max-width: 170px;
- max-height: 110px;
- width: auto;
- height: auto;
- margin: 10px;
-}
-
-.list-vm .tile:not(.shutoff) && .tile:not(.paused) img {
- box-shadow: -1px -1px 2px rgb(0, 0, 0, .25), 3px 3px 3px #fff;
-}
-
-.list-vm .shutoff {
- position: relative;
- box-shadow: none !important;
-}
-
-.list-vm .shutoff img {
- opacity: 0.4;
-}
-
-.list-vm .paused {
- position: relative;
- box-shadow: none !important;
-}
-
-.list-vm .paused img {
- opacity: 0.6;
-}
-
-.list-title {
- color: #666;
- font-weight: bold;
- font-size: 12px;
- overflow: hidden;
- margin: 10px;
-}
-
-.list-title li {
- display: table-cell;
- padding: 0 1px;
-}
-
-.list-no-result {
- font-size: 16px;
- height: 48px;
- line-height: 48px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- padding-left: 10px;
-}
-
-.guest-pending {
- margin: 10px;
-}
-
-.guest-pending .icon {
- background: url('../images/theme-default/kimchi-loading15x15.gif') no-repeat;
- display: inline-block;
- width: 20px;
- height: 20px;
- vertical-align: middle;
-}
-
-.guest-pending .text {
- color: #666666;
- margin-left: 5px;
- text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/network.css b/plugins/kimchi/ui/css/theme-default/network.css
deleted file mode 100644
index fc8a24f..0000000
--- a/plugins/kimchi/ui/css/theme-default/network.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-.network {
- margin: 5px;
-}
-
-.network .grid-control {
- height: 40px;
- padding: 5px 0;
-}
-
-.network .grid-control .filter {
- width: 300px;
- padding: 5px;
- float: right;
-}
-
-.network .list .column-name {
- width: 20%;
- max-width: 20%;
- text-overflow: ellipsis;
-}
-
-.network .list .column-state {
- width: 10%;
-}
-
-.network .list .column-type {
- width: 15%;
-}
-
-.network .list .column-interface {
- width: 15%;
-}
-
-.network .list .column-space {
- width: 25%;
-}
-
-.network .list .column-action {
- display: inline-block;
- float: right;
- height: 40px;
-}
-
-.network .list .hide-action-item {
- display: none;
-}
-
-.network .list .menu-container {
- display: none;
- top: 58px;
-}
-
-.network .list .action-button {
- float: right;
- margin-top: 2px;
- margin-left: 5px;
-}
-
-.network .list .action-button-icon {
- background: url("../images/theme-default/arrow-down-black.png") no-repeat
- scroll center center transparent;
-}
-
-.network .list .ui-state-disabled {
- margin: 0px;
-}
-
-.network .list .network-state {
- display: inline-block;
- height: 16px;
- width: 16px;
- border-radius: 8px;
- margin-left: 10px;
-}
-
-.network .list .nw-loading {
- background: #c0c0c0 url(../images/theme-default/loading.gif)
- center no-repeat;
-}
-
-.network .list .up {
- background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
- #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
-}
-
-.network .list .down {
- background: linear-gradient(to bottom, #AFAFAF 0%, #AFAFAF 50%,
- #AFAFAF 51%, #AFAFAF 100%) repeat scroll 0 0 transparent;
-}
-
-.network-config {
- font-family: Arial;
- font-size: 12px;
- margin-bottom: 40px;
- display: none;
-}
-
-.network-config .section-container {
- margin-top: 20px;
-}
-
-.network-config .section-container:first-child {
- margin-top: 10px;
-}
-
-.network-config .section-container:last-child {
- height: 200px;
-}
-
-.network-config .section-container .bridged-inline {
- display: inline-block;
- vertical-align: top;
- max-width: 520px;
-}
-
-.network-config .section-header {
- font-size: 14px;
- font-weight: lighter;
-}
-
-.network-config .section-content {
- margin-top: 10px;
-}
-
-.network-config input[type="text"] {
- border: 1px solid #CCCCCC;
- font-size: 16px;
- height: 30px;
- width: 300px;
- line-height: 30px;
- padding: 0 5px;
-}
-
-.network-config input.invalid-field[type="text"] {
- border-color: #FF4444;
-}
-
-.network-config input.invalid-field[type="text"][disabled] {
- border-color: #666666;
-}
-
-.network-config input[type="radio"] {
- margin-right: 5px;
- margin-top: 0px;
-}
-
-.network-config select {
- color: #666666;
- border: solid 1px;
- background-color: white;
- padding: 3px 4px 3px 0;
-}
-
-.network-config .input-container {
- height: 20px;
-}
-
-.network-config label {
- vertical-align: top;
-}
-
-.network-type-wrapper-controls input[type="text"] {
- height: 38px;
- line-height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding: 0 10px;
- margin-top: 5px;
- width: 50px;
-}
-
-.network-type-wrapper-controls > .dropdown {
- margin: 5px 0 0 1px;
- width: 180px;
-}
-
-.network-type-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-.network-type-wrapper-controls span[type="text"] {
- padding: 0 10px;
-}
-
-.bridge-option-column {
- display: inline-block;
- vertical-align: middle;
-}
-
-.bridge-option-column label {
- margin-left: 42px;
-}
-
-.network-type-wrapper-controls {
- width: 80px;
- display: inline-block;
- vertical-align: top;
- padding: 5px 5px 5px 22px;
-}
-
-#enableVlan {
- margin-left: 42px;
- vertical-align: middle;
-}
-
-#labelEnableVlan {
- vertical-align: middle;
-}
-
-#labelNetworkVlanID {
- margin-left: 42px;
- vertical-align: middle;
- display: none;
-}
-
-#networkVlanID {
- width: 80px;
- vertical-align: middle;
- display: none;
-}
-
-.network-config .input-hint-icon {
- margin: -1px 1px 0 0;
- display: inline-block;
-}
-
-.network-config .input-hint {
- margin-top: 3px;
-}
-
-.network-config .input-hint-text {
- color: #999999;
- font-weight: lighter;
- font-size: 12px;
-}
-
-.ui-state-default a {
- color: #212121;
-}
-
-#networkConfig {
- padding-left: 30px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/report-add.css b/plugins/kimchi/ui/css/theme-default/report-add.css
deleted file mode 100644
index 8020182..0000000
--- a/plugins/kimchi/ui/css/theme-default/report-add.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-#report-add-window {
- height: 300px;
- width: 400px;
-}
-
-#report-add-window .field {
- font-size: 12px;
-}
-
-#report-name-textbox {
- margin: 0;
- width: 100%;
-}
-
-.info-add-debug-report {
- font-size: 12px;
- color: #999999;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
\ No newline at end of file
diff --git a/plugins/kimchi/ui/css/theme-default/report-rename.css b/plugins/kimchi/ui/css/theme-default/report-rename.css
deleted file mode 100644
index 2fb2698..0000000
--- a/plugins/kimchi/ui/css/theme-default/report-rename.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-#report-rename-window {
- height: 300px;
- width: 400px;
-}
-
-#report-rename-window .field {
- font-size: 12px;
-}
-
-#report-name-textbox {
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- margin: 0;
- width: 100%;
-}
-
-.info-debug-report-rename {
- font-size: 12px;
- color: #999999;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/repository-add.css b/plugins/kimchi/ui/css/theme-default/repository-add.css
deleted file mode 100644
index 4344569..0000000
--- a/plugins/kimchi/ui/css/theme-default/repository-add.css
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-#repository-add-window {
- height: 500px;
- width: 1000px;
-}
-
-#repository-add-window span.required {
- color: red;
- padding-left: 5px;
- vertical-align: top;
-}
-
-#repository-add-window .textbox-wrapper input[type="text"] {
- box-sizing: border-box;
- width: 100%;
-}
-
-#repository-add-window .textbox-wrapper label {
- vertical-align: middle;
-}
-
-#isMirrorLabel {
- font-size: 14px;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
\ No newline at end of file
diff --git a/plugins/kimchi/ui/css/theme-default/repository-edit.css b/plugins/kimchi/ui/css/theme-default/repository-edit.css
deleted file mode 100644
index 383a7fe..0000000
--- a/plugins/kimchi/ui/css/theme-default/repository-edit.css
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-.yum div#repository-edit-window {
- height: 680px;
- width: 1000px;
-}
-
-.deb div#repository-edit-window {
- height: 480px;
- width: 1000px;
-}
-
-
-.repository-edit-fieldset {
- float: left;
- padding: 0 30px;
- width: 95%;
-}
-
-.repository-edit-wrapper-label, .repository-edit-wrapper-controls {
- display: inline-block;
- height: 30px;
- line-height: 30px;
- font-size: 14px;
- vertical-align: top;
-}
-
-.repository-edit-wrapper-label {
- margin-top: 10px;
- width: 150px;
-}
-
-.repository-edit-wrapper-controls label {
- vertical-align: middle;
-}
-
-.repository-edit-wrapper-controls {
- width: 100%;
-}
-
-.repository-edit-wrapper-controls input[type="text"] {
- font-size: 16px;
- height: 30px;
- line-height: 30px;
- padding: 0 10px;
- width: 100%;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- border: 1px solid #CCCCCC;
-}
-
-
-.repository-edit-wrapper-controls input[type="text"][readonly] {
- color: #bbb;
- background-color: #fafafa;
-}
-
-
-.repository-edit-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-
-.deb .yum{
- display: none;
-}
-
-
-.yum .deb{
- display: none;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/storage.css b/plugins/kimchi/ui/css/theme-default/storage.css
deleted file mode 100644
index 88447b5..0000000
--- a/plugins/kimchi/ui/css/theme-default/storage.css
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-/* STORAGE */
-.storage {
- margin: 5px;
-}
-
-
-.storage .grid-control {
- height: 40px;
- padding: 5px 0;
-}
-
-.storage .grid-control .filter {
- width: 300px;
- padding: 5px;
- float: right;
-}
-
-.storage-allocate-padding-user {
- padding-right: 108px;
-}
-
-.usage {
- float: right;
- margin-right: 30px;
-}
-
-.list-storage .storage-li>.guest-tile {
- text-align: center;
- vertical-align: middle;
-}
-
-.list-storage .subtitle {
- color: #666;
- font-size: 13px;
- text-align: center;
- line-height: 10px;
- font-weight: bold;
-}
-
-.list-storage .tile .imgload {
- display: none;
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
-}
-
-.list-storage .tile .imgactive {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
-}
-
-.storage-volum {
- height: 40px;
- width: 186px;
- display: table-cell;
- vertical-align: top;
- position: relative;
- border-left: 1px solid #ccc;
- border-right: 1px solid #fff;
-}
-
-.storage-name {
- width: 15%;
-}
-
-.storage-state {
- width: 10%;
-}
-
-.storage-type {
- width: 10%;
-}
-
-.storage-capacity {
- width: 10%;
-}
-
-.storage-allocate {
- width: 10%;
-}
-
-.storage-location {
- width: 30%;
-}
-
-.storage-button {
- width: 9%;
-}
-
-.handle {
- width: 2%;
-}
-
-.status-dot {
- background: #72AA00;
- background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
- #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
- border: 1px solid #72AA00;
- border-radius: 13px;
- box-shadow: 3px 3px 3px #FFFFFF, -3px -3px 3px #DDDDDD;
- height: 13px;
- width: 13px;
- margin-left: 10px;
-}
-
-.toolable {
- position: relative;
-}
-
-.toolable .tooltip {
- display: none;
- border: 2px solid #0B6BAD;
- background: #fff;
- padding: 6px;
- position: absolute;
- color: #666666;
- font-weight: bold;
- font-size: 11px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-radius: 5px;
- z-index: 100;
- top: -300%;
- left: -140%;
- white-space: nowrap;
-}
-
-.toolable:hover .tooltip {
- display: block;
-}
-
-.toolable .tooltip:after {
- -moz-border-bottom-colors: none;
- -moz-border-left-colors: none;
- -moz-border-right-colors: none;
- -moz-border-top-colors: none;
- border-color: #fff transparent transparent;
- border-image: none;
- border-style: solid;
- border-width: 7px;
- content: "";
- display: block;
- left: 15px;
- position: absolute;
- bottom: -14px;
-}
-
-.toolable .tooltip:before {
- -moz-border-bottom-colors: none;
- -moz-border-left-colors: none;
- -moz-border-right-colors: none;
- -moz-border-top-colors: none;
- border-color: #0B6BAD transparent transparent;
- border-image: none;
- border-style: solid;
- border-width: 8px;
- content: "";
- display: block;
- left: 14px;
- position: absolute;
- bottom: -18px;
-}
-
-.inactive {
- background: #E80501;
- background: linear-gradient(to bottom, #E88692 0%, #E84845 50%,
- #E80501 51%, #E84845 100%) repeat scroll 0 0 transparent;
- border: 1px solid #FF340C;
-}
-
-.storage-volumes {
- width: 90px;
-}
-
-.storage-actions {
- width: 125px;
-}
-
-.storage-action {
- width: 70px;
-}
-
-.detail-view-icon {
- background: url(../images/large_details_icon.png) no-repeat center
- center;
- height: 30px;
- width: 42px;
-}
-
-.volumes {
- background: #73716F;
- width: 1004px;
- display: none;
- margin-top: 10px;
- border: 1px solid rgb(204, 204, 204);
-}
-
-.volumeslist {
- padding: 7px;
- max-height: 272px;
- min-height: 136px;
- overflow: auto;
- color: #ffffff;
-}
-
-.volumes>.footer {
- height: 48px;
- z-index: 100;
- box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.15);
-}
-
-.volume-title {
- float: left;
- padding: 4px;
- margin-bottom: 5px;
- width: 130px;
-}
-
-.pool-empty {
- text-align:center;
- line-height:136px;
-}
-.volume-title>.volume-name {
- font-size: 14px;
- font-weight: normal;
- padding-bottom: 5px;
- max-width: 120px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.volume-box {
- border-radius: 8px;
- background: white;
- color: #666666;
- float: left;
- height: 100px;
- margin: 7px;
- padding: 10px;
- width: 205px;
- border: 1px solid rgb(204, 204, 204);
-}
-
-.volume-box .volume-state {
- font-size: 75%;
-}
-
-.volume-box .label {
- color: white;
- font-weight: bold;
- padding: 1px 5px;
- text-shadow: none;
-}
-
-.volume-box .used {
- background-color: #FF7121;
- border-radius: 5px 5px 5px 5px;
-}
-
-.volume-box .free {
- background: none repeat scroll 0 0 #72AA00;
- border-radius: 5px 5px 5px 5px;
-}
-
-.volume-setting {
- float: right;
- padding: 5px;
-}
-
-.volume-setting>* {
- height: 16px;
- width: 16px;
- border: none;
- float: left;
- padding: 2px;
- cursor: pointer;
-}
-
-.field>select {
- height: 30px;
- width: 160px;
- font-size: 14px;
- padding-left: 8px;
-}
-
-.clear {
- clear: both;
-}
-
-.volume-text {
- color: #999999;
- float: left;
- font-size: 10px;
- font-weight: bold;
- height: 18px;
- line-height: 18px;
- width: 142px;
- max-width: 85px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.volume-textquota {
- color: #999999;
- float: left;
- font-size: 10px;
- font-weight: bold;
- height: 18px;
- line-height: 18px;
- width: 142px;
- max-width: 95px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.volume-type-position {
- display: inline;
- padding-right: 5px;
- clear: both;
- width: 90px;
- border-right: 1px solid #999;
- float: left;
- white-space: nowrap;
-}
-
-.volume-quota-position {
- display: inline;
- width: 90px;
- padding-left: 5px;
- float: left;
- border-left: 1px solid #eee;
- white-space: nowrap;
-}
-
-.list-storage .storage-li[data-stat="active"]>.handle>.arrow-down {
- background: url(../images/theme-default/arrow-down.png) no-repeat center
- center;
- height: 18px;
- width: 18px;
-}
-
-.list-storage .storage-li[data-stat="inactive"]>.handle>.arrow-down {
- background: url(../images/theme-default/arrow-down-disable.png) no-repeat
- center center;
- height: 18px;
- width: 18px;
-}
-
-.arrow-up {
- background: url(../images/theme-default/arrow-up.png) no-repeat center
- center;
- height: 18px;
- width: 18px;
-}
-
-.storage-icon {
- border: 1px solid #CCCCCC;
- border-radius: 8px 8px 8px 8px;
- height: 40px;
- width: 40px;
- margin: 0 10px 10px 0;
- float: left;
- display: inline;
-}
-
-.volume-default {
- background: url(../images/theme-default/icon-volume-default.png)
- no-repeat center center;
-}
-
-.icon-raw {
- background: url(../images/theme-default/icon-raw.png) no-repeat center
- center;
-}
-
-.icon-qcow2 {
- background: url(../images/theme-default/icon-qcow2.png) no-repeat center
- center;
-}
-
-.icon-iso {
- background: url(../images/theme-default/icon-iso.png) no-repeat center
- center;
-}
-
-.host-partition {
- padding-left:13px;
-}
-
-.host-partition>div {
- font-size: 13px;
- height: 18px;
- padding: 10px;
- color: #666;
- float: left;
- max-width: 200px;
- overflow: hidden;
- text-overflow: ellipsis;
- font-weight: bold;
- line-height: 18px;
- white-space: nowrap;
-}
-
-.storage-type-wrapper-controls {
- width: 300px;
- display: inline-block;
- vertical-align: top;
- padding: 5px 5px 5px 22px;
-}
-
-.storage-type-wrapper-controls input[type="text"] {
- height: 38px;
- line-height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding: 0 10px;
- margin-top: 5px;
- width: 250px;
-}
-
-.storage-type-wrapper-controls > .dropdown {
- margin: 5px 0 0 1px;
- width: 200px;
-}
-
-.storage-type-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-.storage-add-input-width {
- width: 285px;
-}
-
-.form-section .storage-field {
- overflow: visible;
-}
-
-.storage-base-input-width {
- width: 300px;
-}
-
-.storage-window {
- width: 600px;
- height: 700px;
-}
-
-.storage-port-width {
- width:40px;
-}
-
-.storage-auth-width {
- width: 150px;
-}
-
-.storage-window .form-section .field {
- overflow: visible;
-}
-
-#pool-loading {
- margin: 10px 15px;
- background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
- center no-repeat;
- padding: 0 20px 0 26px;
-}
-
-.storage-admin .filter-select {
- display: inline-block;
- position: relative;
-}
-
-#iscsiportId, .storage-admin .filter-select input {
- border: 1px solid #CCCCCC;
- border-radius: 1px;
- font-size: 14px;
- padding: 3px 3px 3px 10px;
- height: 30px;
-}
-
-.storage-admin .filter-select input::-ms-clear {
- display: none;
-}
-
-#iSCSIServer input {
- width: 410px;
-}
-
-#iscsiportId {
- width: 60px;
-}
-
-#iSCSITarget input {
- width: 493px;
-}
-
-/* Progress bar */
-.volume-progress {
- clear: both;
- width: 140px;
-}
-
-.volume-progress .progress-bar-outer {
- background: #ccc;
- height: 4px;
- overflow: hidden;
- width: 100%;
-}
-
-.volume-progress .progress-bar-inner {
- background: #090;
- height: 100%;
- width: 0%;
-}
-
-.volume-progress .progress-label {
- color: #999;
- font-size: 10px;
- line-height: 16px;
-}
-
-.volume-progress .progress-transferred {
- float: right;
-}
-/* End of Progress bar */
diff --git a/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css b/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
deleted file mode 100644
index 6e8a551..0000000
--- a/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-#sp-add-volume-window {
- height: 400px;
- width: 500px;
-}
-
-#sp-add-volume-window .textbox-wrapper input[type="text"] {
- box-sizing: border-box;
- width: 100%;
-}
-
-#sp-add-volume-window .textbox-wrapper label {
- vertical-align: middle;
-}
-
-#sp-add-volume-window input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template-edit.css b/plugins/kimchi/ui/css/theme-default/template-edit.css
deleted file mode 100644
index 7c93117..0000000
--- a/plugins/kimchi/ui/css/theme-default/template-edit.css
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-#template-edit-window {
- font-size: 13px;
- height: 500px;
- width: 800px;
-}
-
-#edit-template-tabs {
- background: none repeat scroll 0 0 transparent;
- border: medium none;
- height: 100%;
- padding: 0;
-}
-
-#edit-template-tabs .form-template-inline-wrapper {
- display: inline-block;
- vertical-align: top;
-}
-
-.template-edit-wrapper-label {
- vertical-align: top;
- min-width: 100px;
- height: 35px;
- line-height: 35px;
- margin: 7px 0 8px;
-}
-
-.template-edit-wrapper-controls {
- vertical-align: top;
- width: 400px;
-}
-
-.template-edit-wrapper-controls input[type="text"] {
- height: 38px;
- line-height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding: 0 10px;
- margin-top: 5px;
- width: 100%;
-}
-
-.template-edit-wrapper-controls > .dropdown {
- margin: 5px 0 0 1px;
- width: 372px;
-}
-
-.template-edit-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-#edit-template-tabs .template-tab-header {
- margin-bottom: 8px;
- padding-bottom: 2px;
- font-weight: bold;
- border-bottom: 1px solid #999999;
- overflow: hidden;
-}
-
-#edit-template-tabs .template-tab-header .action-area {
- float: right;
- height: 20px;
- width: 20px;
-}
-
-#edit-template-tabs .template-interface-cell {
- display: inline-block;
- width: 250px;
-}
-
-#edit-template-tabs .template-storage-cell{
- display: inline-block;
- width: 180px;
-}
-
-#edit-template-tabs .template-storage-cell label {
- height: 25px;
- padding: 2px;
- border: 1px;
-}
-
-#form-template-storage .template-tab-body select {
- width: 140px;
-}
-
-#form-template-storage .template-tab-body input {
- width: 56px;
- height: 17px;
-}
-
-#form-template-storage .template-tab-body .template-storage-name {
- width: 170px;
-}
-
-#form-template-storage .template-tab-body .template-storage-disk-format {
- width: 160px;
-}
-
-#edit-template-tabs .template-tab-body input[readonly] {
- background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
- border-color: transparent;
- text-overflow: ellipsis;
-}
-
-#edit-template-tabs .template-tab-body .item {
- height: 25px;
-}
-
-#form-template-interface .template-tab-body select {
- width: 180px;
-}
-
-#edit-template-tabs .template-tab-body .action-area {
- float: right;
-}
-
-#edit-template-tabs .template-tab-body .action-area button {
- width: 20px;
- height: 20px;
-}
-
-#edit-template-tabs .hide {
- display: none;
-}
-
-#form-template-processor select,
-#form-template-processor input[type="text"] {
- margin-left: 10px;
-}
-
-#form-template-processor input[type="checkbox"] {
- margin-right: 5px;
-}
-
-#form-template-processor .manual {
- margin-top: 10px;
- margin-left: -3px;
-}
-
-#form-template-processor .topology {
- margin: 10px 30px;
-}
-
-#form-template-processor .topology div {
- margin-bottom: 10px;
-}
-
-#form-template-processor .topology select {
- width: 80px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template.css b/plugins/kimchi/ui/css/theme-default/template.css
deleted file mode 100644
index 27fe404..0000000
--- a/plugins/kimchi/ui/css/theme-default/template.css
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-.tile-template>li>label:hover .summary {
- opacity: 0.1;
-}
-
-.tile-template>li>label:hover .list-info {
- top: 0;
-}
-
-.tile-template .summary {
- -webkit-transition: opacity 0.25s;
- -moz-transition: opacity 0.25s;
- transition: opacity 0.25s;
-}
-
-.tile-template .list-info {
- -webkit-transition: top 0.25s;
- -moz-transition: top 0.25s;
- transition: top 0.25s;
- position: absolute;
- top: 100%;
- width: 100%;
-}
-
-.tile-template .list-info>li {
- border-bottom: 1px dotted #ccc;
- padding: 5px;
- font-size: 12px;
- line-height: 20px;
- overflow: hidden;
- width: 96%;
-}
-
-.tile-template .list-info>li>label {
- display: inline-block;
- color: #111;
- width: auto;
- text-align: left;
- cursor: pointer;
-}
-
-.tile-template .list-info>li>span {
- float: right;
- color: #444693;
- width: auto;
- text-align: right;
-}
-
-.os-icon {
- text-align: center;
-}
-
-.os-icon .title {
- display: block;
- font-size: 14px;
- margin-bottom: 5px;
- overflow: hidden;
- width: 260px;
- word-break: break-all;
- word-wrap: break-word;
- height: 50px;
- line-height: 25px;
-}
-
-.os-icon img {
- margin-top: 7px;
- width: 64px;
- height: 64px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template_add.css b/plugins/kimchi/ui/css/theme-default/template_add.css
deleted file mode 100644
index f1e28c5..0000000
--- a/plugins/kimchi/ui/css/theme-default/template_add.css
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-.page-list {
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- overflow: hidden;
-}
-
-.page {
- position: absolute;
- left: 100%;
- width: 100%;
- height: 100%;
- overflow: auto;
-}
-
-.page>header {
- position: relative;
- overflow: hidden;
-}
-
-.button-group {
- margin-left: 5px;
-}
-
-.back {
- float: left; display : block;
- width: 50px;
- height: 52px;
- background: url(../images/theme-default/icon-back.png) center
- center no-repeat;
- cursor: pointer;
- display: block;
-}
-
-.step-title {
- color: #333;
- font-size: 18px;
- font-weight: normal;
- padding: 15px 10px;
-}
-
-.step-choose>li>a {
- display: block;
- margin: 0 10px 10px;
- padding: 20px 10px 20px 65px;
- border: 2px solid #ccc;
- background: url(../images/theme-default/icon-local.png) 15px
- center no-repeat;
- cursor: pointer;
-}
-
-.step-choose>li>a.local {
- background-image: url(../images/theme-default/icon-local.png);
-}
-
-.step-choose>li>a.remote {
- background-image: url(../images/theme-default/icon-remote.png);
-}
-
-.step-choose>li>a:HOVER {
- border: 2px solid #06C;
-}
-
-.step-subtitle {
- font-size: 16px;
- height: 48px;
- line-height: 48px;
- color: #06C;
- margin: 0 10px;
- font-weight: bold;
- text-shadow: -1px -1px 1px #eaeaea, 1px 1px 1px #fff;
-}
-
-.custom-iso-field {
- position: relative;
- padding: 0 10px 10px;
-}
-
-.custom-iso-field>.input-wrapper {
- margin-right: 110px;
-}
-
-.custom-iso-field>.input-wrapper>input.text {
- padding: 10px;
- color: #333;
- font-size: 13px;
- background: #fff;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- width: 100%;
-}
-
-.custom-iso-field>button {
- position: absolute;
- top: -6px;
- right: 8px;
-}
-
-.iso-field .button-field {
- padding: 0 20px;
- text-align: right;
-}
-
-.check-all {
- display: inline-block;
- position: relative;
- height: 38px;
- line-height: 38px;
- margin: 5px;
- font-size: 13px;
-}
-
-.check-all input {
- margin: 0 5px 0 0;
-}
-
-.box {
- background: #ffffff;
- background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -webkit-gradient(linear, left top, left bottom,
- color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
- background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
- endColorstr='#e5e5e5', GradientType=0);
- border: 1px solid #ccc;
- color: #333;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
-}
-
-.box:HOVER {
- border: 1px solid #aaa;
- -webkit-box-shadow: #bbb 0px 0px 5px;
- box-shadow: #bbb 0px 0px 5px;
-}
-
-.box-iso {
- padding: 10px;
- margin: 5px;
- overflow: hidden;
-}
-
-.iso-icon {
- float: left;
- width: 58px;
- height: 58px;
- margin: 0 5px 0 0;
- border: 1px solid #CCCCCC;
- border-radius: 8px;
- background: url(../images/icon-vm.png) center center no-repeat;
- background-size: 58px;
-}
-
-.iso-icon.centos {
- background-image: url(../images/icon-centos.png);
-}
-
-.iso-icon.debian {
- background-image: url(../images/icon-debian.png);
-}
-
-.iso-icon.fedora {
- background-image: url(../images/icon-fedora.png);
-}
-
-.iso-icon.opensuse {
- background-image: url(../images/icon-opensuse.png);
-}
-
-.iso-icon.ubuntu {
- background-image: url(../images/icon-ubuntu.png);
-}
-
-.iso-icon.gentoo {
- background-image: url(../images/icon-gentoo.png);
-}
-
-.list-iso {
- overflow: hidden;
- margin: 5px;
-}
-
-.list-iso li {
- float: left;
- width: 320px;
-}
-
-.list-iso>li>label {
- display: block;
- cursor: pointer;
-}
-
-.list-iso>li>label>input[type="checkbox"] {
- display: none;
-}
-
-.list-iso>li>label>input[type="checkbox"]:CHECKED+.box-iso {
- border: 1px solid rgb(11, 107, 173);
- -webkit-box-shadow: rgb(11, 107, 173) 0px 0px 4px;
- box-shadow: rgb(11, 107, 173) 0px 0px 4px;
-}
-
-.iso-title {
- margin: 0;
- display: block;
- position: relative;
- height: 23px;
- line-height: 23px;
- font-size: 14px;
- font-weight: normal;
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.iso-title>label>input {
- display: block;
- position: absolute;
- top: 0;
- right: 2px;
-}
-
-.iso-info {
- margin-top: 5px;
- overflow: hidden;
-}
-
-.iso-info-col {
- float: left;
- width: 50%;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- padding: 0 0 0 5px;
-}
-
-.iso-info-col:FIRST-CHILD {
- padding: 0 5px 0 0;
- border-right: 1px solid #999;
-}
-
-.iso-info-item {
- font-weight: bold;
- color: #999;
- font-size: 11px;
- line-height: 18px;
- max-width: 106px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-#iso-search {
- margin: 10px 15px;
-}
-
-#iso-search-loading {
- margin: 10px 15px;
- background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
- center no-repeat;
- padding: 0 20px 0 26px;
-}
-
-#iso-more-loading {
- background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
- center no-repeat;
- padding: 0 20px 0 26px;
-}
-
-#vm-image-local-box .body {
- margin: 30px 0 0 26px;
-}
-
-#vm-image-local-box .body input {
- background: none repeat scroll 0 0 #FFFFFF;
- border-left: 1px solid #BBBBBB;
- border-radius: 5px 5px 5px 5px;
- border-top: 1px solid #BBBBBB;
- box-shadow: 2px 2px 2px #EEEEEE inset;
- color: #333333;
- font-size: 13px;
- padding: 10px;
- margin-left: 10px;
- width: 600px;
-}
-
-#vm-image-local-box .body button {
- margin-left: 10px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template_list.css b/plugins/kimchi/ui/css/theme-default/template_list.css
deleted file mode 100644
index 3161a33..0000000
--- a/plugins/kimchi/ui/css/theme-default/template_list.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-* Project Kimchi
-*
-* Copyright IBM, Corp. 2013-2014
-*
-* 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.
-*/
-.list-template.framework {
- float: left;
- clear: both;
-}
-
-.template-box {
- border-radius: 8px 8px 8px 8px;
- box-shadow: none;
- color: #666666;
- float: left;
- height: auto;
- margin: 10px 11px 10px 0;
- padding: 10px;
- width: 308px;
-}
-
-.template-title {
- font-size: 16px;
- height: 25px;
- line-height: 25px;
-}
-
-.template-icon {
- border: 1px solid #CCCCCC;
- border-radius: 8px 8px 8px 8px;
- height: 58px;
- margin: 0 10px 10px 0;
- width: 48px;
-}
-
-.template-icon img {
- width: 58px;
-}
-
-.template-text {
- color: #999999;
- float: left;
- font-size: 11px;
- font-weight: bold;
- height: 18px;
- line-height: 18px;
- width: 142px;
- display: table;
-}
-
-.white-box {
- background: #ffffff;
- background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -webkit-gradient(linear, left top, left bottom,
- color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
- background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
- endColorstr='#e5e5e5', GradientType=0);
- border: 1px solid #CCCCCC;
- color: #333333;
- text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
-}
-
-.row-select {
- -moz-border-bottom-colors: none;
- -moz-border-left-colors: none;
- -moz-border-right-colors: none;
- -moz-border-top-colors: none;
- background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
- scroll 0 0 transparent;
- border-color: #999999 #AAAAAA #AAAAAA #999999;
- border-image: none;
- border-radius: 5px 5px 5px 5px;
- border-right: 1px solid #AAAAAA;
- border-style: solid;
- border-width: 1px;
- float: left;
- font-size: 13px;
- height: 42px;
- line-height: 42px;
- margin: 5px 0 0 10px;
- padding-left: 10px;
- text-align: left;
- text-shadow: -1px -1px 1px #AAAAAA, 1px 1px 1px #FFFFFF;
- width: 100px;
-}
-
-.bevel3 {
- box-shadow: -2px -2px 2px #EAEAEA, 2px 2px 2px #FFFFFF, 3px 3px 3px white
- inset, -3px -3px 3px rgba(0, 0, 0, 0.25) inset;
- color: #333333;
-}
-
-.row-drop {
- left: 10px;
- position: relative;
- top: 50px;
-}
-
-.template-action-hidden {
- visibility: hidden;
-}
-
-.template-action-show {
- visibility: visible;
- display: block;
-}
-
-template-hidden {
- display: none;
-}
-
-.select-drop {
- background: none repeat scroll 0 0 #EEEEEE;
- border: 2px solid #096AAD;
- border-radius: 5px 5px 5px 5px;
- box-shadow: 6px 6px 6px;
- height: 147px;
- left: 0;
- position: absolute;
- top: 8px;
- width: 250px;
- z-index: 2147483647;
-}
-
-.button-drop {
- background: linear-gradient(to bottom, #EEEEEE 0%, #CCCCCC 10px, #CCCCCC
- 96%, #A5A5A5 100%) repeat scroll 0 0 transparent;
-}
-
-.action-bevel {
- box-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #EEEEEE;
-}
-
-.template-border {
- border: 1px solid rgb(204, 204, 204);
-}
-
-.template-button-position {
- position: relative;
- left: 250px;
- top: 55px;
- z-index: 5555;
-}
-
-.tempate-action-position {
- float: right;
- width: 83px;
- margin: 0;
-}
-
-.template-actiontext-position {
- width: 250px;
- height: 160px;
-}
-
-.template-line {
- left: 200px;
-}
-
-.template-os-position {
- padding-right: 10px;
- clear: both;
- width: 142px;
- border-right: 1px solid #999;
- float: left;
-}
-
-.template-cpu-position {
- border-left: 1px solid #eee;
- padding-left: 10px;
- float: left;
- width: 132px;
-}
-
-.template-icon-position {
- float: left;
- height: 58px;
- width: 58px;
-}
-
-.template-icon img.template-type-icon-position {
- width: 20px;
- height: 20px;
- position: relative;
- top: -15px;
- left: 49px;
-}
-
-.template-title-position {
- float: left;
- width: 120px;
-}
-
-.template-results {
- background: linear-gradient(to bottom, #FFFFFF 35px, rgba(255, 255, 255, 0)
- 100%) repeat scroll 0 0 transparent;
- float: left;
- height: 60px;
- margin-bottom: -22px;
- padding-left: 10px;
- width: 1014px;
-}
-
-.select-row-action {
- background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
- scroll 0 0 transparent;
- border: 1px solid #CCCCCC;
- border-radius: 5px 5px 5px 5px;
- float: left;
- font-size: 13px;
- height: 38px;
- line-height: 38px;
- margin: 10px 10px 0;
- text-align: center;
- text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
- width: 230px;
-}
-
-.select-row-delete {
- background: linear-gradient(to bottom, #FF3019 0%, #CF0404 100%) repeat
- scroll 0 0 transparent;
- border: 1px solid #B10F14;
- border-radius: 5px 5px 5px 5px;
- color: #FFFFFF;
- float: left;
- font-size: 13px;
- font-weight: bold;
- height: 38px;
- line-height: 38px;
- margin: 10px 10px 0;
- text-align: center;
- text-shadow: -1px -1px 1px #9E0505, 1px 1px 1px #FC5D4C;
- width: 230px;
-}
-
-.template-general .title {
- color: black;
- font-size: 16px;
- font-weight: normal;
- height: 25px;
- line-height: 25px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- max-width: 130px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.processing {
- cursor: wait;
-}
diff --git a/plugins/kimchi/ui/images/Makefile.am b/plugins/kimchi/ui/images/Makefile.am
deleted file mode 100644
index ca3ee6e..0000000
--- a/plugins/kimchi/ui/images/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-SUBDIRS = theme-default
-
-imagedir = $(datadir)/wok/plugins/kimchi/ui/images
-
-dist_image_DATA = *.png
diff --git a/plugins/kimchi/ui/images/icon-centos.png b/plugins/kimchi/ui/images/icon-centos.png
deleted file mode 100644
index 5afb7b4b63462412d825f63542beb1f7e26b3d7f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4734
zcmV-^5`pcBP)<h;3K|Lk000e1NJLTq002J#002A)1^@s6(aU0S00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3h)2`3h)6!tTdPa000McNliru)C(I02nLeE_`m=F03CEi
zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9 at 01@IzL_t(|+U1*hcvRKh
z$3N%ZnaMIFAqh#y3V{%o5Fj9gC1DY;#iC$^YO7C+h_9~|#0>=mSt5p|A_ceVTdio-
zqR<x*go4NpAwWpj5yBGoB?%-mlg!M$zxR&>N`OGZ=G*o>&-rKWnS0Lnw=d_yT^=H$
ziAcJLOcs&){HF{N(M6=2h?y;hr&L5{h)9 at -{6~OK6Omlw`~fN3`>B}j3l0(alZe#$
zcjtJTm}b8BY>r%5e7_WZnIO(B6U20%_ln5-A`)@8B|y6yz=58?d)~8K8#*_S!#KYW
z0QdemxN at iI;wkwZFcFBlo8Z+Q1`d!8GSe(M+{Ur?S&Z|0t8S|_e49UoPm5>Dl*RrT
z at B-jaO8x7CujF_)kiQzIH`jM=8ii4MsG2PmwnhW+Ydu1gPw?l!D5cb~e at U?y5esl1
zV$SfM&aUs=nt at Sr@Z!_US5{0haUc3$%JQZwabFk+GG0WY at 3ak2H2`9*)Ww<-N`ThD
zRMT-R(YgKw3`fCb8!E(8f*3B8H4t>)Dg^OuIv87%$IF$)ZyqoKaMuD)8E{%DW!x_C
zO at IZ087yMnSd^3n5W6X69Sj%ZDY-;9r7Cci<xazWa322cCt;25jcJ-ygi+aoP`X8w
zrp}5frkLgpVJKaplv)iuqm(*V6Y!RrvC<4VdVWp#@sg}+sU<*UKzm|?x^b#Bhl2Af
z5izP9(9ar1v(WyaSwIAIADksVZ2NdEB9{w*;9J*UB|nxLW*R1Y=5EDtrleY4={AkV
zeOeNp6dh0-J7%e&5_6(7o4ivWqbcngk4+*2I?^PxKWCl0SaWzZ7s?B+S{LHil!UrJ
ztMXn~VJSKPvz9BltCYfdx`cb4?T&wV09kJ@!{hQ?6PnfEMo2;g;YrbV#^5Ow74GNi
z85P)>o{iqd<vGLm2cD}0e&sr?TBazi0_^1zAn&scteLck*e;FfHT_rEBLXiGrpj8S
zZpv?Iw`MIh;(~h6Id%+Z9C>U!IvI!O<Zbn!2fo|M+DVIvYS)0YQGKWr8T9|d)!8fo
zB!xdtpieA$r#_*mZ2xT!9ZavmzWLiYo_&b;Ud?HIUlL-<PX}Hpjk><^cnk-dj{bqO
z&Rukj9Z7_}EyC^f&AQD(+o!t`*R=`T|C+_FIh(Qi+pq=t{uJO9v4P#`*=Q!s!+uRs
z*?!g at 8Ha{W$JkMX+go$Hf)m|lq4l87q&$_*jxRQ``Q4QmZZGYJ-Anh0{VP=97WS$Y
zcoCBZLEY&P^AbLK5N+x|P4jw>Q0zLu+9R){P^34=AlNVAmL)(;q0N(Nqzp;tz;`>y
znz0<i<0WNC8p)4$B)(@ex=-wfPmuo=QR5u}uZRokL3+bU6ua_Su;*7CC|pRJ$Y*F9
z^(-e#b69m~6kfwg&qgzdu&3Pgp)5WY?s>L5?VjnzuCF(<=8Z)lkorPz?iqS7*|S!#
zV&pu+lA`$8A0MGkWZj#RHcL$x#s+nxX}yOzc3~ZxkN=TU&k44kco$O)nuZR*ZIrU-
z%p6u99z)lLljt1#8d*oDa-uZ5b_epa()OvYBtM=??kDTW`DhJFQ>4Doo5nv+BKPBU
z<bApx(=hS6+;p4Rk8ZE`MYmb*2<Js9T_WnF;P9McL%}3UD*d?IC?)6Q2kbBUmX!L>
zRN8<aS$`x0l%h-AIO_T~uDJvVq&$^Q^5dx-ShADsSu60Cc}W?PPRn1nXV2WNY<_Pg
zhQ~lmA^-c`tjk<XXtPKn+cn at CnbXaK7ZD$z2T0J7;+3q(e~~h8aTRywF-qBVbQ-(Q
zenrcO-;x^r3Wct{{E+`LPS0t2H-3kxfKCYJbwOMGZFGG3K2ip!kvDq-t0pYK;%lYL
z$e+`CP-oUpTgvA5e!y^ht3-kO7UuE&t8*zmb%DwREM7#^ErG8D{wTtD5!3gyV;e3{
z_4&fK6Cbem>|7G-Jw$TE6O?*Ru<pnN+(ro<Vnz at Z(6QS8TJ1L4{#RF$9%)a`pVzYO
z<8>%as}S`*E!p<TI(B}s3Dav{BRW(Z&pyb>oFf29z$75)Mm9i1lvdpX;4#x<ym313
zXq4MgUcsL0(9>f&$vycId(O-uIbtv^!v}G}eT>zIU&Cv<=-MEIaC at t(f*?)TXg~B`
zT0WM_?zvmo^4>}SIt;s)rv2Km{qrnxK3aomnAb}^Fuf*)g{697p`$18ZVe>Bs$B!P
z4fu^|m@|J|yglaoQFHOSJT=lGujyp- at tN#C^Cig<zoSF+ixj%{vFgxhO5DdujTwoL
zrEZn~1UCw!<*z%C_m}l#y|oP8$3mA;eP}(XGaIKbBj>}_RYd)IBR98zv18}yM~@bD
z1wN}z0xF48N4w%jU*Jj8FsJVRdW(Ji<nJgy at 2ahbCimn=>^%KBjf4BrE^;X4-Xc~X
z8qGQ9E|k(xKEWuTAT+;vm|l}jGgpxF=e6iQ7ShN3g1D}UY?`@(U4P5IF2}EqJQZ0R
z4={SvHykY}>LemFf%es?K!A2dvGGwc%&`S)evDd|xwyiJ+(aSKYr5Ee>J#>yokMcO
z6SNHfEv4?`Y(4P~ZqtQN!ejWgn}{CPo(o5d$eX<$5uyFCdrA03E4F{Wk=(zmuNCl1
zxqvBb+_;~NjQQG`GbLStS=XovE5P4U3EUqTVz|ATyXI{6-!N?{?$UBprG6@<2=#A4
zLdXNCTEs=?%MVfH+DEI1CkgP0rMT<>N@=EMk14j<V>F=5>gTTC<bl>S?9q%y_qE{2
zs(rZ5IcU;1xyCt?ZnF>=8^VbT&P(TAv0^tR!@tnSPw1bTm{@<FhztidDW#+myhVwK
z9eBd<7_aY{yESa%^kultmR39#s1q4TzuAMa2H6nt)=~ikO<B;D6^q at 1W>cbTwqj84
z00)7dVoHCb+-r9mCa!W1hTDr6wT#vj=vJMq?1PLQGY^NO{1OpbwTj{G8NV?iBkQiy
zH1z_I1L#0AB_c12VZM^TY<JkQ5ntnVR;?FmR-KT9aFniYHd;k#iiSO#)Bg9}O{Hr~
zfuWV)I|5TnF1XS at _+TX)HtfHpe4w<njDmtf%*#?<(-gXNX~MYi{ml6Iu+6}4fqWoA
z1CF6osb7d4pE^F*j*)LMOVe}>|4=(rR8>y{-b&H40U>UWL2<EzJ5j1u3eKG?!Qm)Z
zKo}5Qxp%p$bZvdblxas+|JZ1C#zKk at o~<Yk3Dk)SqTi>3(d{<8-r5-;5wO{GELI)O
z*9y8aZ8l4xQfdlNQd!%-UyO2JXBm{08(@@!n6*c!S=pF%n6YE#UJ`qNxVTVe%=nEo
zYaY2v*R>JAKPtgTT9i_55m~4-rQ*6a`7mwN{UNJfpMNo2tcV5zd|8#9&krkhqcl}h
zg-6#lh7RjRUAv91zRIGw*r^S9s#|bCfbZ{thziGW(zk5KJNU#uguPx{-1&>~p2 at CV
zMyT1aH5!23?q8)<*05nc#*cr9q?Xb7z$jp;Qp&9CCK;AW!{7ntiijh=XY*MBF~JGn
z4*8Ul<HeU)xNGMz=FiVTs{wcs2o1F};*~!5``gIOT*TkL%A#$%h75WlO)v8n#TT4k
zMO;vKtfm)F!FPC%Eyu6jIIJ<f at t)p*`|zR~6F^z~v4p1rO)mj&-XfYQQwB=2W|8}W
zfk0lRrN20gEB)5 at C`Q$5T7O at UH~JHj5MFB|CjucMc7{KHA8BccOn++$3+Cq#9BgOs
z;B at K)*w}OSE7lcE;6!OQnmrod<mV9)Tsd#zE!>W8%VF5!?!UQupi(qWh#({5A!*Vi
zA{Q8b4d8MW_(}=*JBnu;bZdI1`^0_(#0J;c5Q%`Vua#F{y`NsalKAMum3;YS7IwRh
zF=HR3SFa>AO}J2g6p!J=ZIpuP#nxy5zO7zBJPur0BQY)<!tb8(SR=dEy84sQIGoJP
z0kmoryI0q>=Yb_x0KW*{qg^9JG=SwOo`~uYzo+*f24bt at TVqk5FtI;f(h`|AbuqJN
zuO}+1E)ysIlC-oYeDMAXii(_7_-T~nQ<nP{)|lS-wa-AjrMNbY#&diXejVP#*06s?
zVZR0=p-BXjrwlY(w~pNjJPxe62JnmEy;^lKGO$!>>ZQP#;C&W9E4oF$F7SHw>hRLb
zeMn17<PXypvtU6EAt81qX8e+-%_5ncxrpV<cUJMi7b6sR{v678%)}Dj0l$>dfZ*Di
zfpKmdzRAy55a32CpfqA)Ld^L1upFh-?}4pKsq487w|1Q*!CUDTMroQ>+BH3q`1pEP
zx%>)uW?|ImzNDuo^8R}(Sg;_6y1{lvjqXdURx!N$&T<wm+*ZB$Fg=tX_=d6_v#`eX
z#W#64m>yhPCt?)s!mstqSfhJfn*d^>1;k^i+Z?6HSBjCq+G;p{Idi?*4YDLJuw5w}
zDQz3@!Jh`vpke4G0*F9(cmPwT4x~eeMogWunAx+}5g8fG)TzIsQ>O%8dhsjf&(Eol
zG`UWEDqh_Czr?jQ155P1_;;F)c$_%1Ud3~K75=Hyu*E-IRRzRE54#8d&TpdyB>?;g
z<lKPc7qLl=l*uqmwep8OxSVb#O?sH5q$os$h=@Q&ymCKn+cqTg&2L${bUXFy2QhAZ
zKVoA;$b9qL+J&r2!+m%@Wjkh}2Pff|G7_cxQkFXv at 2U0pCjB?IMguMpKo4z&fBT8x
zabOhf;<CozZ7f|2Y}s;%(WAd1E-sXD<NK4+wgIob_5d9_He%MS<t$v7L*2Umj2qvd
z7A>Nf{?-x}Ey}%#{*-|`{~OA3r(uo#Iliq&AY$Om9*a at 96TddEVvXsI9@+-~4w+zj
zE9^t%C8s;nrB$$V=P`y3{R~~#_~erzB)5toW8wn7`Fa!a at nK|U4kS4_hF4yh!;&T2
zZ>3{_`_SKUZJvlFA{GDCX at KC|JQnw%1^9Q!q)yil!6?VEb|^;i?wg7UwA#fFioDzc
zGBOshbH_0zPhP~b<vXcgKZr?h4j?)vm<i+Ovwq!vZuvHq(s3VINLk)n=)ukKYxjDE
z3T&H-=jd{b;ypOC$6%Hg+;nra)|LK?1Q<U2a|#QcL`Mbl+L#B3jR|Jbq=l?lv5VVw
zi%d-1hrb0e at M}9B)w&`IbmdG!S^P1bC%Bc(ZmLTwBAh$tz-rZbZg_9HcW=gf at 2_C_
z@?Ez*C9P0_1-K7<i6y2tJ}sU`%8M$1|CIfCkH^awf89u4ZUK)zl1jUF4R1eqG%OLF
zu*UYmIJ*UR{x>y_`0glp5!klvFk{EeBQVg9F=HR3MT_X$c6k61EMe{Nzb6B;{2Z>W
zZ(tPfy^Un8nWsafLfo&M0DJeH;OVFTLP<#(v)*}(HYssetv5}nK0y+bOBWI^yO?N=
z>4kslWK7pdoNJ!NIKTg&_t~zRcgWyrnxcJ&cns65){2V=$Bz|}k`l)oZ#>N6#d(yK
zd#com!@~pd^Rt5UG6U)pg00z;a78aqX+GEz9!1%LFi)+=+VH_ at jhoVJ=oJy(Z3k~^
znmX65TQf;dPrPv%S=UHxTHm*ELU^EIdQ`db&&H-w3Z*$Q#EU{<m}Qh(HE1!Y$~$~4
zL1 at YfN-qTQ*y0D&$Te1$#%e4EHNAcsT}x*g3uKlX7dovu{F*xL$g8rU+bG3rmSNKa
zuxLJ)PAg&(AABEeBZnEjmbz<!=PCi!bll$Sr#I;eHJ}~H<RaJp9$CkxsG}FwU$&XL
z%$i*MMI$CCowT^|hMzU;JB9Wtu={%1*)3Og at 6?Mcn}IEXFN$3Ilhz#>uTDC)T(jdN
z2(f|bbdDQKfGy?+V3<;BCwF+<@f-aj(j54s%X6;h%0nZx<0V;F0dErWARS^x7=D(}
zWxycd)ZO^l;EsQ00_*`s`dLF)c8Yz?j1KH_nE}*k5Y&VA(Jy-aETKz)my}X>1^8VX
zBBDejQN+wDE<0#0-uI+ at xH(alA9zk2?vo-S--<}nnqDXQS0zGI5&4J1ecH%7`LQ_N
zXFMXZSVSWDcOR7!kR)O*G)zyKh&e|@8vRFnR9IC7WQK?&{*-6=Kk6Dayw&uIx&QzG
M07*qoM6N<$f~4IfuK)l5
diff --git a/plugins/kimchi/ui/images/icon-debian.png b/plugins/kimchi/ui/images/icon-debian.png
deleted file mode 100644
index ff49a39696fdfa5f232b0e79de04d90af6557111..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4239
zcmWldc{o(>8^+K0B4eq^STcyLC8fm@!jx?!k~OkNF}Cb}Swoa9yKG_XYqDi0W6jcx
zC0mvdLx$`|mf!0-*E#39&L4B$=e+mxx$kG*X=$o5(WB at g2x3yhC~1Rx!0Aax3$A#1
zi(YV}wNzJCf=*74%%=P}@C5!6W9SM&49uq|Y;el&5Ij8Nrlz5MW{R4FiCvo15Ud74
z2rf0Hd%9i|WRph^IbX1yXgpi!Ht!PpLl;+a!^1gV-yve$#8&Jx@#3Ynv<Eq*mI5Bt
z{erdHuKa90*RGB%#FiQfAgi at Wa9r?Ynf+eHVA)}QX-$j<ZNvj6dNq6dAahv%Me`?<
zWAh5P=Q+-8HOwKld|TF=X1r&-*Z;HXj&^=^uUj3mKTsU at lL-%UV|(yS7&2E#@1R(O
zE{v*P`mJ!C{oP}T at WVTKY&*1|)Q0QC#1QXj$;2-A%;rziL#UO*fm8R#Mb~i6N`a>k
zd^Ta7qk6*&mW;meARE^3uKMJ*X>rK3M8NH(iA- at +rnraYRaDpRUU)b4{Tu(*=8XM$
zVjkhhHeBo~pOCj;N)hS51*&guadEz9r<ZJGj#v3_Tk1?^g;BY$Qt(uJR)UtHcP61|
z!$Y3#jXqN(o_2~LK}z%Jc at mx{+?uDL<Z#!twX<(4<hZ3&pTW=F6?!#_)`@#<vlwZX
zen_8;e)4x6=gD;6-!-$<y_@<D4W}7nBtAs_qXIYb5~%acG8gnVkt?`y<FGb#svWgE
zG)}c)Yw{79-hhyU?P_xjg?WeBSG`~A)id6VfI$Nup3JvkBD4L*0Y<1MvzM_c++ at vv
z&fCt!+d{R<2yU21V%+ffn&w>YpNoQTbj;}KOHu!pMdMZQ?;7!iLanAE&t4Jz!$o&9
zw7UeqU+|NoyqMEP@`9CY{F0Rrbgq?&6tR0Wo+0(X4a+6 at WbvZ-PeFv`_#ykz7cbcz
zP@<dSXw*=f8+~o!;Rz_8EEKDHW&TDD&e^m%zemd1N7Y$`t~H-v=Q%<A?ap)6(a7v&
zuHLQJ2<=BL_(=+HKHGBG$zwc*_cF|s^6~Kk$#=ltDZ7K!_uS{>zfU#a{=_gNv?mTd
z^117?>;k8Ll5=n6?GzfixVzNbV$c|it*tj{<DLe81=O!IXD6zxSN?!U^1_HEsh`AA
zgte;qzB<W*61K}#SmN(V<a~yXola%Rn_sLa{L{Fgkn3Y$#Ye*@@IN%moAs%Si;)a%
zUu4O(cTWs(h4AvEZy#_|cmd9s98adXspJL?&!8UV54{Ezq;!>QZ3n}m#r;wd?=yR4
z9aWIH(!E>G9Vc}3rS)qwpJk+djpxVQsJ(8pXG&faD`!^p5im`Oq*lKh+}D_ at BbjGr
zE1o&OOJ`Kdb~%!kXq;6c#|XYR&Y7lBjP(7ZSfSCp<s1FT at Q*j$>YXqZ%u>s~_e*P=
z+ at Ipl@tL`LT=4RQRi_;57t`=4H7Bkv{)f*0M|*FSW;pD~jm=mf<&NO#zKXC at jkq-A
zgSF#HQo$?_eFZ=GAfM+FwPvzX{uc#QE{LLP4_%K|@NUi-OY^IA!d+2pd_}|!i6;Ac
z{`peE#oF75?^ym$-9}(dt}+%-(eqAn+||I;Y=yv=4*t>M_c6W}J9wv#djXNjG!?yn
z<YPXS=`W=H=+6i0dtN3b?sJ>noJ{*fDwHj}TFMo+vNQjtXs!Fvzr~?4-eq6yjaIk+
zO+f)c{O1cQcFj|Re$wTKo2mDSIr&{`>%64$_0an;y!)hN&}KF#IAZ8V`Gni2Mv5 at e
zIn|H>(4uScIQ9kOBvJXLvtsuZSkdF7SEHGY6v0vJfX56a3TeuH6b>5bw5fMOq8sZ1
zuw`-*XE~?O`CR(epP!wG-~DU#^*h*rg0fxoJZWBn+eAZ*+Ck2L*GFwR&ErQ0Uzkd|
z-^7c1dv9zceP2kcl`5olboNpCtsd2`E^Xq+c}o0qWE}n5dn2GJLUq`NTq$z9>>hZr
z^^yM%GF9xfFiSeDL}*d!-`aiA$QbX!h-J`&tjivj4%nJJ?*jlbpmwE(&>n;47ip&7
zKk|4W67IK=*V$oQyKF8*#jFBPnE&e0h4eK}b?9$>+p>Yp2u6-6Y;L$EnL&%V_A543
zbMKrDm#?5V?P-_mi$~eti1 at N~FFJc~gQv^v@^wxb at w1%I=+gbKmDNl}Z?#{Rbj-X?
zWv|NK1EhoD5)Qhc(2_B5- at RJ(Z@>R<Z~aY?#I*^z$tgA71Ew2>2Q%#d{9nnaRe68t
zQ?^WFaVjd?jTa2KU)<?vNv>_lnzDT{6{nTNpoL=6nsn$AE{cWg*^C5UJ<;aVTSqCa
zZ{D3wuX_qqS$8ad+CIV7YcTzvrkWxi;!*OQL7=HFK7Cy|mEI2Pl at G3`Lsy=I02GS(
zI*%|fD>GUsfK=<06aBr;B)+zPuf^VuzGwHkGAUAnurCU`gM7W+mMijsH<uU?wQ>F{
zmIBbI<9CJC#Hm$P at 3ZrYP9S-)phPahF5wkQbbk${%2QnY%X92w$%Dm{*cT7Ac3S2>
z$_!`@O6>Y{Zrb~M0`tgm9=o78cu1NDj^L~^`J62nO6Y4Dv_TB-EeY$h7)d;AhGQ(6
zdE^EpGsN2vnSqr2rC)Tv_qO6hA{`qRk;e6(>fzDh?HBr62>A*pud1hPlZI!PTm-$C
z1kt%eW==$YgM0-Ab(NW1b(&=K2bMJG;f4rA3JK;%H%k&5Xj98FGDon5HdChcYw)Km
zMpul_58hpTDxBqt*qH?&>&#de`jN?5FH}NPkaPD99|kM`1hEUhatL;xCFxkk%*;90
z*2|9ZJm1d=b?b)|4dlZOH+}?9a}b$i*?*kUykQsIJog4N&J(dSswMFyiyf2xg*{iy
zT|gxrgt1fI=%1QLc5t^Rw6o0Ak~r`j4yoc>5Jfr6^4>=O2g1t9VR=x2YS0bV(U;^O
zUZ0^9A&DkSG~n(xRv%yvB&V})`OgnC&KA9{_$(u2s=r{nDhaG{>z<6Ni!#+m at c?C(
z at bQSDPO%76;SYIP1R|@!I9g2^ChTLYRXeJ at LY~Y{bx{A+N30**in3<sy-#r1+)2dd
zE(TfEjhQ*KJhq~`G{9`!hzPjqQQ<BZ>1Xy<en)K`Su|*(CLM40Pd?3K+Rz-Xqz+}Z
zebO!qT}L&w^`|O#?Z1`gWE`!gbsPU*;eYNH+cIBOIZ|_s(S<bFcvg at pF6VwmD(w0_
zG%d+SJRjl_k(Co|DHj43Xe?AKkPiz(3Vt%|6D~>c0TyKQDcfuvB#a%M6Jc|iBT6uv
zvXEBE<$*XS<$0!FqthntEPP})&6U^upt*NNKox4TYc=kr3javZY>=KgbWNw%|GSav
zdfwv*YhTW7BCu2THBf-i+2;z7rYo0s8<5_?zlF})pv!`>xgsjat!DNLs^+rermoFM
zd7oVC%7OvS=n9a}7UiA$Qz%dCy`Pu?-KtP5VTS9@`SZiF$vW$(8^vY2yhz4p?k=cg
zG#&f0{Qam++74<`?a}#xoxSsvXA7WRkUYO6iWTNE_PO;2oZvfWrymO=3hO6aEpd6#
zGsP_5n1c5;R at Q~<Bh7#@`{){O;b29}><j#ilZKkw*JS!*Cme&mVWl6RE0>YJ7G}5F
zq}$2j>Zk94!W3eQe6I1LsN#Dm;IpLll@|lO(=CwXpwR3;9!NV-$DIxCdAuhog-fKG
zB6i>ulRHuWv^23|@5m=%>@y#v^ZOk8ygGJkBxo$^y5$fL4&YR`VJPYp7py1Qf#1pb
zm0m=Dbp-PQ-_4b->GwU_8}d_M3R<KIg!Oh2`a69ZNdr|tf4qcRg#~+0;h1gttZt&W
z*Y^`CfX7p7H*!Payd)uwz*qc1MpAM}I>jsp#kv>I!Y+nj3sfwuVI%@Zl;k$U3p~QU
z?{4VvB4oNf!{-`vA=h=H|M^TiT>UQ)!DWesl&g)Ka at hcFRzVig)~2et!Z{2hRo at 0_
z;=il$*wZ8FQ+$w%kzEX`u70BX)-I?&I+ZyCwo?8G%0aNulk~LCb3YWcjl&fuR;;Lg
zRXj6hoaYaGgn6-(u`ViHi1|`kg08y$J^78f2WT}@1=9dPx6?SMJky^Fei(#A!?lFX
zK*M{YxR{ZiPZz|pNc!$K#Y-xVsZM?zXW1u}Kbc!gD)Sx&+y(g{vF;2Y_Tv6u?uws6
z#Ezs9#*mzzM0oJ$i~-yrNiq^I6gH|M&5s85sW;H>i=Y^Z%TYj=tt9o>uJYtM%T7tX
z#hUKk^}$ZR#0^RVl}UXL!M at nJ5=jf}9A~E^T>E6q#a17`Pq$LXJwGHtSTvh2&+7f7
zB7`WD)i5S^nr%kB^N_#wwF8&PSy=?K^yIdJ(oX0)h<0W|`DzCXL&A+C*smZR-brpQ
z)KgrlQuKF4Z$J9!vibXiTfh at l{1V?yYzJA6&5o=o3#fcbnCDcN?EPEb0#}_Rc7!#(
zqB!24C)uTVMoRNTL-BTHGj;PQN|8yHUUsjnsS9Fzz-6<&G at a#Q<-$U*!7C=6EImbQ
z@@vQL>l1s>a?h_SPQo2~0+)#hD65C at 1E6NYPqcH%wcVv(q-_Vu3!VDnrrPWvSK4q%
zy8XOpD-!pe6IS%URrG3oW~^6EsGRs#$d(F}XOlU+d|pKTayBB3HMnZWwCsR86>I|M
zZHAo2LuNim%NJhRX<_Hp6c9m+KrdAp?9k_R`h7U()OqZi3^CdeZ4--<d%u7z4BTvS
z=<kF5LOzIlQ7;?jmz<U;5x at d}S<?_#5JC-tEsjgveWEoSUbf3*kxPW0&K0iG=2*e7
zM5>*$kE1WSP(kRfeN4w&UL at V?_lEVil+Xce>CX#$We4_?fr?JmZOx2{hFX7hS3V&3
zfzhcVD8@=$8W!;Flly9=&%RbjH~e%CD~RVab$--igf60n0?ZyAC!3?}t1<>GZMU1j
z8y`Tkf5#>B3TDYZ2xEn=>xxR$r*oQa7`^^aoxmE$Ug}v65X)}oy?bx`y5tP%ZAiYw
zG7SC@`FW at 89!O(vYXWqIpfdsmZUzKw^(+Xlw_rI7R5n#4adm^k_ZO5c_|M$^MvZ_R
znv&o;L_$a$j&OB7S{Dv+Md?f2jyAuFQnfsE9jC`6KyFs8N`cjd;~|f@;*>L?%NG{}
z81Oolu%c?}D)rfw5ql24N=SUVkES5^7P5MCi`sHsEFRuURfmZXk<t;H;Rce9T^Wjl
zM~7l>g+S)X-n{j7vK6$m5CGs{DADOO1&@CxWSdxF2voy31`xPJUC%8zKD%NV;FAX2
z;Ky%i*SdqYhrAIsdpFdU82muK?2!s%u7ElyfvkJFhIXJxv~{()R7^WaIaUt55>y1L
zoBqS8T-QI|q9Tj|*cQhPMSKeG6^On8D-sM8Wfs&7 at ZkeV6Xel0cqEucPp3Tt4z*;c
zBkS49vL~kh3_~~iz4OSJcX0~sbtIb4s+$(yP2DCuy_6gJq{ir)mI?XwH*CzRR=19N
zfF&XK`BUPZvth;^U!R|CcqdUnmK-<fj=rQgx6k9!#KIbd#ejbfAV^JFQ>pB}dEoy6
D^V29c
diff --git a/plugins/kimchi/ui/images/icon-fedora.png b/plugins/kimchi/ui/images/icon-fedora.png
deleted file mode 100644
index 7b9dd06d1f766a3285cd0fb587c0be4114bfac47..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4449
zcmaJ_c{J2t*#FKj_9goWk+p>ETQP%#7_w#Gml9b*CXBIV-zj9vQiQRDDBCEzWGAvU
zmPupzp|OPVj`RNep7-4I+~?lso^#K=_dK8H`8+rNzM&2y-DNre02uXj at 0gHv_=V6=
zk^8UePD5lx<*cuB2ROfIZ`#W<$rf5)T`PY8pl7=f5b!!5N;Xml=pnSJ7bv+InZ>uS
z*nKCP_&m%k1GIdeJaO|5AWs26>#3VlfSap8kVn8H0UbTWeOD<rY5=&@qjyKc3^}(|
z at I1g~s-O>MlqYGG5wxjnsL9DnNqZHp3obSjF;FgZ@?dg`!8B6HOH&x|y`n8p!H#~N
z7I?)J3(r+q%QCs96+s2QTIQ_RuQ?9L7%SeoYL8p^AUR;Yln1LGkM2GQ8P7ajZQD^%
zRaFl&I&42VTU<I at 2tgkPX~Z(|sRsNWE!O%!2c>LZ9-(BiTi@~KygD^NgjoPg*syLT
zIPm)xu9f2lYPAnfJPHIo%JZf0z2d9ACug-L_>96w43>woPc5T&T-6()-~=qdi4mC}
z%mV1^E+gqJclLt?KLa0hg0KGf)%8Z_Dvg}F2 at T+x>5QDg69Wj~euiBLoY6Pv!}+ve
zB$f?(uV`kXoF2}HLtqiuGq_vI?<Phh4RR4r><$2x8Io9+f0c0+C00;`fliI93`^e_
z<8D%3p;%AK&=`ESY+p3fV9$je?M{UhQgbGcZ^SoYCDm*3X;R at X12Clxy;P at wQjV5!
zJke|X%U7tpCMgixCk7l#OY>|5e)9BI{v`>2da%v1Txjbo4I9z4dQNM%&>kIG91!-$
z&+)|wfyGD})H1JNxXdAWco-=ly`SV^`?uXHU(t<Wtp}3D_4ArUU1$ix!Y8`-0AR$Z
z$@6YIpNTnqAQ04aoi)8>sv<l??TwbBS;B|x<W!DvQj)Cb#WpJmYhNa={6JZ^7sm-Z
zOZByxv0?i%)C6YM-R6E4Ey=nccp@(^5$yZPb6u|PjY)|DuH2|-aA8Qw<-lX3Rj|Dn
z8dN)XZ;SLm6GI($#2h8RY6cH6p|rV+0Wu`fRnz^om6eXiPhhx==cbp;s?*=4TvAd$
zp#AkI@{Y1 at g&S<F<NL2WzTS$G5i*IZx59~7q+~j}>-gb*XX?3JxskZV%TS<v*uei`
z94fgTYQVXdAT9$%bVo+jaB%?igJR!L?E1P8W5#j}2Eiw_K)FZ!Y0;uD_lVk&k+RqN
zxAv2xl2V;ZZY#cpx7oTLU2YTu+v`owR^(D6b0S1+5m*5z at -NAzh0sec1C{+rFWT*L
zf@)}w{xX1fY_z0qed6~NnSXL|{Tj&jl*y1o{i&){tFQHg!MT|q{-+&EBQY+xT$)}D
z%!t}-j)bgh&gm>R(OU5QkH|T;Df|1kdsYi5WA%ku)fNi(dK?s1a5X=b%Xa(qbCv4=
z+20c)KAnYP(qJJ64BIx({2mP6i(^ggJm664Dn_X^wC6<1MAbaQgM2>EE3EjBfp1fr
zdAtbC8&1G?pu4 at y@GphxDRF-P4x_KtyP(BjXH(@~&=Mm58uV344^D!AbBO~>ucE-5
zmcMyyrvL8zz|F#sF#hTK0*{eyXh&5pv1rSg at QfcLS@0JErlAu0u1PK8_BQK5l1Bf{
zvSJ}kiQ>@5Fc#WhOU-T-10|5$II;dLKoR8Mq#35?!NT9x2DT~G`@}Z0j9=nML5ga<
zj|SzT_2!16osFt*@eGPvSLdhXe{?oeG)$$C-zNN2#9EMl*}><tiOeyrF|G&p#AN`H
z+AqitXJw<zI~=#^q>!1bJyOANu(2>ieIG7hl$dIS=u-KHCC4})@jko7LkfVoXNF>e
zh}tb%Fne58L5NAMWfV&Y at x3M8jmbuEV7UG;+_Xs&JN!r at eB$iPpFN%Vzh$|q3Bhxp
zX at Sv}yl72*>1a6`iq?X#cLP$`wVHalOP?{<Z39RF+B3Bz*PDdtDmIKrJS~{96*yk_
zIBOs62>sCdZ)Ejz!ny?3Zs2O7yQ5;BiqE?8>`e2s7e{M at OI80EcJDKv@iE@}$0YH6
zytqdBy4B3w1<*_xBxbA$MIqbV?5jgTq$?;A>L2(I_4?oDNuk~^doKvr__j0F22^K~
zAeP<zJ7c$~R;t!^I2dDAs?V><)k8CcSvNc~QSD>SJlh#yGizH at eZb<4Mpm|pn?vhH
z6&0=?*;^<wHz8HT-XP)`SojghuxaFaYyybvLF&%)J|?N_3-V?eCFs2ZILR(_Y+VO%
zd5oPh)4)kCO at Xe8pg7^)H61$onBrIQshd<%(~*F at 2MLt0xyPg14BI!JrPJ(TN$Rbh
zL|I>8fRd`jLY`K`xY6jH(heOoX-{jUtfe{)+p`gq^41fyo^dPWK!=?wllzl#xrtzk
z at SwG^1od}*J&<jU=?#A`pKO>H*Ghs3lU*^r0JZct-t#eVoOVO6#^A-~3E`%Jk7HwH
zMq*~IL{I)9J4^m*W at f6eG<bso_S{s_2amZT1v)EB+qdq~=PI&-eK%H_m_28e4L)i@
z&d^!N3MDbhH#Xr;2sCJVP%mLS{@_`etT4g~5VZri_x{l*)Tf%d{{xkfrp*#~SU_gK
z<@w9|jD)1+Ie%Yyyz=|Lu8Ov|s$Doro+apCBW-08k-q$!p^CWj<OkSP37?P?h}Y_|
z2{{5WxYI{Emi0Ti;aX&qWEGL at mTN}s_Nal}zp<sE#x}6kz;@Kxq(VTNZXAuM991U7
zrGqcA!C+f_(T`=fS)7mbejJK;{Q-ysHMBz$8yFfem!hsScge$X%<jp**7*%fKUWI~
zsrvu;HXk;8+ at EWe+|3$#5XfWHzN=u at z9B}J&FZHq8JKj(WilF4r+jbVMostTwOih{
zr+ZcJ{CiGmA3>hG3vJ8w`F@|2-9FkG-t_r{h(g78Xf-8h_D*^wZ5#m}56z`#^OeO4
zUaYL<l97|5PlCvaD`=B~FukamZ{0a}QzDjsp}N6#LI+Gj8P~=gFJf2JMO2i!c6o1(
z|7L!P2Yxr}v6#Q@`{C}GTX{4=ij}+2h<ujtS$oZ~tXWIC*jo990qm-{n02hDW;!n9
z-%lo1uf@`7p|VZ2*B`8mkKI<TSL92C*v)$@ILSUfH%Jt04c$RI_NAphO0ATM10~bL
zvGyqO=RJdaJAsGV9y_$A_Bpj4ph<-x&+zz1un4WD4TeLrX25C#?DaB}J at Z`2Yks!U
zW6#Ae{YmSsn6|q~I<$&AU7bPxqW!TEZ1)<khqsl`Rj<7d*{xcfMT8hxHh_<c4iCnE
zu<*Ku@(WE`r=mwhzZ4+8y3rx1L*%amnNu2FKmI;Qjym%TBW-d%LzQCuc}iu{&8vd;
zV~IK=yb1Nvzf!1z2|=T4KjG+~8roynSx)$RD4>B=-wvSE3cj4l>i4J9<JUU}Mc>6F
zal<0Z-T at c7*nB#vI_n$-qOi6K5XASp>?<tv&*7pY<x&Kb;+9v*t}mDK?MP^%V6TvH
z$ytJ8c+z9gDpzV(&O`n5ztCSb?j>ql-6!YjLm%IHQ+v9SdXqLxpKoy=+ialsE3=yj
zis_}JuK>y at 7SEottnK83z)N29$xx%4=G))r+Bbdv%Dw#@XPlx+W;`|5L95xxrfssK
z at qUrRCvgG%54KbU>nX*6MZ+PZq3#@qjo=n&;;3n}+5#k<jl<`yf5V?rAanSA3z7PD
zsOs_iV!j_0*FpWcE3iR>AO$u8Vf?)TW7UM3?>!Xg+8l^Y6p8FKT%pNDPeI5jHFhup
z%|LcvU1!^J83oFSz}KwdU4rPbyBXcC3~edw_0xD_bdv~RTDa-CqJdU?ryICmWDd$%
z3ptP1)h(9}qzn&g6ayff at FeYk%cgy7>b2!I{$P05msDXlQj2Y(73n?lm#@4<zYoQO
z%DcI*jot~@N3eRPix1MRrRrMGJ$0ADbxz)XXlV}8r8CKce#_;67xrkT+l6sUN^X6E
zlful@)$h8|3pfDxp01ZgKHqmARHv2aMT}0c^+Q1O<?B|UKlB1MW%PB9AKau?L%JY)
zsWG01hj{R at 4a$Cm at c6u<5*!yBmEe9*Er$4}i$LT^ztYDK!J2VZ?XmtEz at aNnXNnJ^
zD_CD_)TchDAC#40QN2CzG*aNd{}KrO&HenK(4!4QOy+sb2;tcB1Pt^{v_i~HrE{hd
zPtFI3iMa~qVI9%B5?x|EA3bwVzgC1A7{owEY3X{8BD<p7tqZ*5GDVZ|2cGyFpC9T!
zkvltkovckmVR6(}_>K%v;a(0Ka_phRmsurnW_Bd%-^?8uGLjTB>RM&S7R@}FcuMG;
zCG*r_R}gnREkn~Zb2o%$@9T$QNDq5~Z0!9ZQUros*4WIf|LoAV at 5`sbsQY9Wb{#(9
zX}m{TA#>g}1Fj4fkg(v at FAKw~*-7T>SnectGsIWi?Re71sBTS?M$iO1r>bR(qg1oQ
zIqF`)d#e;Nd!$8!A%C4955&#O0gfhs$V at L*m3ANc1LH2G-kLCAE(bOJoaTs5Dl7!l
zP*;P4qb&C&v$B<Qq(4T>y~`?pnd7u#k?b|M_m*?u5HwT9^G5*(zO-Vji6OElsc26V
zmu{72tm&7V;`&c7Ye at 6r(;qI53Le{GoyjoB!+_;JtKFU-3m^C+Q2Xe&5Jc2M<@s{2
zRVCk+dYQCHJjactvJO%j=RoH?o;c~&Fq$-jtn)iG{@I!mdn-Ht6~`W^Fyx6GKgq3u
zbC~o=y;h8H#iQ5LF5}L>j#-u8n(1Q#(r2r<>b6blJi_yX7v~d~k3GXb&3Yd{4gk@@
zU&Sib?LXv6p_P-iO0@?nuYD9(pI6~H-Cnqf{I(y0Nk6Cb9Z6?ef&{g-K42|VLHlUL
z35FWMgW>WA4xJkVZ<lIphdW(}6d8^`T6Q<I33oLCb@;)+H)jb=p9P2O73#!mMQ`4=
z7Wv8-KiamZEs;s5E<&X$ou6_^vhYK~*7t+MLXxyMo9qnJVKAxJu$RK#i7rRua}Sey
z3%W#NqKR6L9N1HvC2r*!i>%W!mMevZ6DPM{ZVQaoC6Y76(p}2LlJ4HQZ)FiGlXHEH
zLG2X^dq080-G1t$-_6_q=@{8<P_t$j|Ngm0(C-X<LwTf>MhOf^NNT<C!faTEKfxNA
z at bTR_!&u%B&2X^osa=}y;k8hCR%P|_^7bZU!yjfIBr%y;w_AZDxP!B$2Tv at MrHmJ#
z;oIM_ZRj`KM8Ot0Y-8wnv<zk&fu#a58pSQ{OIkg`q_vF^<m&pY*~>W-5&|vorD_M&
zm3R{)%06zE*7v_<n|c91%ca6B;rF6r-2FP2o<-D&E$lN*uwWe`FxXEUx8Z`UB|G;e
ze_jsq58UFiZ92Lg_BU#xLMl6({quV at tWMF)?k_Qi|BmrZaTygNI6}Asfd2bj&EsKQ
zr597j)a~AntQtr&)@U0 at yta@#h+KtzS*tmgsiV*h(Qsg02~gyBp4yMKBu0WB`pK+R
z-GEw{8wQ$Rce#<EC(POycrd;=re&j}gg`vuRsIo2HAZ!t@^;Z(28a6ziB93_i9${y
zztLyJxAFTsNIYn{CfVqwwbJ?bASqcI6KS=o3{i5m(HibhOhKjSr4FjTIGG4#zW>Q(
zd^*!|I(p>f_(UYHu&s=+Y4hNxXyBoaJsRcVEDUkfRaK%lygyDcaEMNf7{zSc1|!W`
zcgZyJ?y~o?2KFg9Z4q2;n9)J5kXJX=mCWU2TIUty!n4DzO4I%>FbKN_^ZcleF;)6Q
znZ_Q$okNii$uBs4cGZ6lNqNadVD_oQc>W;>qxYrr?5OPu?Em>4xL8V;J3`mux>fJu
S9$oyI0D9VncWN{pBmW0TFKp8Q
diff --git a/plugins/kimchi/ui/images/icon-gentoo.png b/plugins/kimchi/ui/images/icon-gentoo.png
deleted file mode 100644
index 50d928fbfa30560fe873cf3de438a8f0c10a8f96..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 15307
zcmV;+J2b?JP)<h;3K|Lk000e1NJLTq004jh004jp1^@s6!#-il00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY4#NNd4#NS*Z>VGd000McNliru-3uHIHU<90ip~H4AOJ~3
zK~#9!?Y(!HWLJ6T|2gNz%ALEXyQgPHqfrJ4fh3R+AhPZC+K<Do?Z^IMOmYC5j7{*8
z!5F+?ytYXO2X?VY0)d1C5?}*X0%eUfGa60qo}P}CZanAw{;2An>guYV9!V1bo#(lI
zL*1&by6^YA`F)Qt#t5DmKexmFss9BA5Fmsw>$?33z^@qMr|^LoAq2)4zJKHPV!fvG
z8io+^QmuKC)@(Ie3;-p8Fh+=~6ymUuJS?TSUnzZyZCgitUsRs=;;ogRcToJ)0ATh=
znfvZK<iv@(FsP?*ier8=iX}=}Xd^K+HV|M0AVIA7r3gR at gC)VX44!AOEIy-2KGfe=
zc;w2fHl$!Z0f5uy%Qe~h_1E0_`dUrDGYqXvYHV9+8`C7Zv}~kwK!^tM5eRW~FN8!|
z&HF3~fQlpHC_w8JDZsWgj%5<xH#3%_|M-`Gb=x(@7+49RCjf9V3IFYH-tnUHg85hw
z*;|v;v6ZngSYRZ=vXRopvTTH~5W+%Q65qFQ9f4&D3<9kUNur4&O&lwX(M_cRgk|A4
zHqy38qlhT1Auu?W!L?P8$#9>W(XV*%FK)g2XIVs?P5>}M2)_BHTmQ0Bldp^uXDrbU
z#yB8sq~%~)F4A%-7F-6097;tC#}QbzKnl>hZ8Kn+$4Wtx8sgXx)KeB06RNcsgFy<g
zYzJvc(j+2{L!{8Sj=^{Jo=jH!!!P{urVsrr>I<g at 0E7_c+ArSn)_P#QEr^_~G9KU{
zEC<W-a2%iEVV{u=4!u1R*M(GpRx63E^-+Rr4a%%MU)qdmY$}CnEu~UPD3?RDHb_fi
zSr*1<(j)|}aBNM+H<6#=V<QvJJD+;dhTvxf2&WVP4Z{D|Z-$}xw_4!33Lk`vB|U7{
zr&P)@G2yXkv&69>O*<1)H3_d;uj`}Nbr%pUAJf<`EW}hQ3H5pm7%baHU`W#ljKY?R
zY}SzR#e4floWH*8(vfnKXkpvp2>`5j#8HChyXLyD{BT<sitDO1=gd_57~x~t9<G;T
zpg+gi=Xh+~2uX63Sgk}`p5+>hI?4f-LD0NrRD%<A1VJ13(7N#*!%#Cj7ZTKCwAM(=
zLI_Z41V-anid at FvXT@uWHu#@->Qe_orL>SzJOO}Xji20pk38^5<=yqV{njw?(PWU8
zhv(-hl?puNVwVjYFc`!Vt8OR!(yVV40j;yW{WWclo~tfgpj~&Mxu2d62!aHqQiPNU
z2`Y(^LStK+Le7xM$zR*NIe+c8vkU480IV^-`lXu+Ci3 at H1FxiX1|u`LUY0_k#05{v
zuyre at i?>g#B3A3HS1Yfpc7nIu+YW?oAZX<}#=!J+NDxFQt+0duDNt#I6b8 at M6be)d
zz0O6KUq0~2Pm at SE;Q-KDV_BB@`qkfkU9IN*O%(fRkwMxSa`_%MY$$Ts(}l6u<CJa!
zVFkhUN)RlGge4HHxURc!4%0=UY*j3q|95saAPgI#LCA(j5}jaK2G3EHO5)xZ|I+A_
ze_E8p6AFOYBMS at +^_pw`-}in{t9e(%I*S$=JU35I?*LD`#9?>@bKD<n5bcCt0Rq)R
zaMeL1w7;*Lve+hmOjBWuW6kVrog`Hltq{^e>jWuGLs9f~+|z5l<GC*w`B1f*id at e6
z`2)bdM-GX5?zyiRSN*$dfj^O&EXWMGd at rM;Jv{9aX?*`NIu3LL2<;$f1wyMBP`ZO?
z=%7e;wHTUar7?};AV`^?570(8olIa%iY*MTqbTIrIWXk@;$_bm*mb&cgcBAGy!Xf3
z&y7O=mRgX_DUm^1If^|4oOM>7^DlT5v%V90CB|xcewAu9FOQxJv5I?ibnq%b>Z32W
zZkXn=ZiE<&24NtRvGLpji{*%VJwh9e5Dv;H!dQ|n>TOXJ at BGg7Q|}W(y#2KFx;~y?
z${2$X!hGXP-?=0V+}rA57A3OSPJzC at A<lo2$L7tC5AnO{2CZ8=S6Jo*s<ZCUNm=a1
z1(xokDJG&=vrrCDu|gTu2vHk_B at M2vDHhpZ>~*es<}>>rKAlX)#|;3+7^IZuYgd2!
z;y84FT#s at nlfm&y3=R(Rl#5-4hED+T+eE?&J)n)~t=CL*uT&S)vCY at 8%>MOiAS_u5
z7+5Gr1VN0^8bd=gSORRR$YnK!qV=-py>RHCYPD2kv)0cJ0E7_c>sNp0$x-0k9mF|O
zGPrJ$p^*_Txzwho=fo1flU|@y!`-Xe6-3otKWNnlRydWGh)<g%$sAP<k6H_c`T06Z
zYqU}rG*TF(G<a4 at Z?C*#cr0`Ilb>8je`Wx1-B)kAAgnp})WR%^EVf%<c*6!RyVRyw
zIyuBYYI`D<h~5f-t{`Z$9+pKxo29Vq7w8ahY6Za3d8HB&h6&nev{ncVmNeLwqL4GD
zXTW*NGoRUa,}e5 at Z(DOb7fYv0`%2i86H$VZdKvU3a%k8sH)r-1m4Uu7%_mets#
z1(pQaVH54wMDw~h`g+svgA|S9<xRGow{Ac_ at 6l7rB89}VY(SD~L85FHE0&l(l-%{*
zn`S;IgfK~>fBHCpQX1Q~%-6nf^FpPTDJfF`nPF&ToJ%itO<(^h=5Gd(rfoC6Im?%>
z>ki^!`C11TvT2JQn6?OGyKX>Jl$0w0X`+_7fs|kgjb|&0MIIhI%Q=5TZ$9oHaDI9?
zfNfjm+N*EAvsQCU+GIg^^bd at 1;f1FG at c{&8i3==kOEZ3%JIIwYe#Pu>;Q}i-0G&Ak
zOQvJXebD%fQZYj|>mh{1k~Ufkl$L~v&HSR+y7z&2=DvFuE?aMM>uCXi>%V&QKL&OC
zB4x4|;ZrE}bLO at z8%9qfJGUtgWDDV2iM{65B&6ghAi5H}g9vB`LdJI}6|zX#%sD`!
zj3iEN7AsbMao+sbcWylV>XQkAM+E>Ogt_sX-+ywwDqa<<42BGzUu5G%FK3@~3S|DV
zzOU8f1T7%ws1JzMx<RX~Z`U1`a!^GlPSASZvbP;cPbrIS*+|()XVXTIYMV;kVsSxy
z{Ko4KfA(a7;J9^wG*$fQ`?qB(b78Gq&5)Wr(k?JIKE`Fwu*qajKL9N01FbrMN*h^4
zY1-XVXx9tY+B!LkTCIcD(6*tmuht at xIBA5RjY0^pq{g*VN<HQg$4}3{>N%qUConnn
zxH*91*e0k&pQ;BA+IR at zQR?Yu+qTn__`2a25ZZvWFpi7yGniZfQ|iI=4`52Y;JQaS
zL#qz3N*@sG-=thA3YL7!ONaTaM<(kdg+NFfV;Xuvl-SJA%Pn!;t>5tN14D4)p6hXO
z0HrkFz3~T^))v$)^)QbjkLUHW?VJ%Vy7=@Vev%++HAoY%ZE(HDj0*yY!p5=VKqd>>
zEZFwZ at 17)x>BA7m>+=tEOffS at Q_Wg~N3EOyjvlAVP^s3NRzt(TETzGg38ex^KY8+V
zpEG=)<H%FX0c_hcX{f#!B`z8dAwBx~``CKs=|OmvA`Tx$OihCCL;nD#rx%mWVsbf*
z$U`Whs$r%M`={WcU9fW}V)`&bD}>`<#>O!dn=qc&BKwzgfi8+4on$^O=d9KfmRNyh
z35reSP>6<tp|v2 at 4vQ5*T66BX`Fm5paY{Kr9L0R^+dq0)P%)pXM|m`P{OkZ1TrkMl
z=bif5A4iD&2f%Y-Y#h at X1-#>K#E<Vh%#rCC3VDZO-owviDHc5jhYPqFflwd~^b}yj
z2-t4pHw6Lg-E%Y}Nv($qw0H|wae)^9z$(2!L$w~FlxifJ7=x6$kz<h2Wb^7RFL>d|
zhqTs02yt=&AcQd2efg%TTGbtnbrB=;jE-*PvS&DCbEg&n#=t`lA+&;X&u7ICx_dj~
z>aW~KrBcSVHJOadV!2Eqo1q>Al!`^hh6fni*vHUF54HoAg5d!eY9^~_4SOCzgyAtj
zU{(i<+8soll))8%0BW^}G)<ciRX5Ao6ggj$DX4e9 at P)(wD~^?TJVe5}@&RhqI^VqJ
z+b>t47}j`zjqCah4V`-80~|Vtn4N*GTUV;f`zPT){&PRo>H_(!<h*UeNU5k+Ep%#O
z$Z+sTg`eDWKfCw!ko6qSJZlpZTLw`_Y|3TC<})z14QFh{?Ae2;R+^$fbr1!nQI@!D
z`-`IhU2)FQJcDHri=)?aIgfe(Nun at DqKyF!wGe>6yy07irR!Snh at w=uu65#dfP5im
zY+=16O>K;^K{^x*J&cW?7Fs at 2hoM@7$-_reyS0W-er~5wNu4vsi)`E6gI0CosEj2O
zq^KZ>I6QTTfdP*&nnw^ZH8sf>ufB=<cOGQ14i9ce#8KljH*dydvmIgrZ4Mw>0nlmz
zw21!ptdkY at 1KEs+>)6Y6j at n3+wyB2}Va<B`4c|Ka0nf9IQu at RL;M0Hq&v}({rZx^n
zG)lBeJy{B+Q$PE)Zpi5{gaiBG2R}gU+mDzn8zDtNJ}>b-O&l$vk_t(*ND?ie)FQT3
z;o|dq at kE*Px0OhAh4TCYy*a at hw>-cj`;QPN at Zf`um;%6-Eg05e0<z>PX0>Oq)f8;S
zhF~S9$Yxwz$7w2u0%HWJu^J$#+kbxJ4Tt}?ZCmDq17O334WBexg0MkYIF3tCPs6iz
zn%MfJsUnUw^Yd{3eelqIf-|;kK&2sZP(>#}qY7BY=(LPcRnlkyla?u!B)fO)VB>HG
zDa*_)Ea1BVKlt7c33Wmc!mb at n+DJI#jE0ig&GWZJ>=jl(3$<k at 4$#3*V1R7K!LjXS
z>%bUEsx9iFB&^x5z2Sz#fBRVc1ji)d?LWF*danD6##jj9AT1l$^C=cNEsCd?%rs*R
zN@<cr6UUl*4bIv;NEpQk5faqqsMjW`*QPLP4wEjBMl+=G3=Rtv3W_6Bd)Uw~fEuo?
zIcwVxxBcKJ2nS|o6OJ5i{Nil(XiR})iGnt<Aev8o6$cQj#lsQ^G8qS_MI0E8f*`8f
zuld#ulkYw;05A|G%0kGzv>j~Q!j`h(xjIeK8!fBh=n+DYDov^sNur3Nl(43`{PL$_
z+bKe%O(%=Os05=UAVv}sh4bY6gs?tO5|=q^OP0gaQ#`z54}16TWBc}pFr at 5#L}40z
zCfKyO$pu&g2&}$N8^>q`$qJyf>ITg~l5JTHPJn1~0-GR|sL+4Mb>BMpKORl|Kprcc
zTA!cWBrL~rTo2o|acqgvDYe>(bWk4O7#Rk~wJ^q at wI)q9ahwtcF(xsDp~i6}X`&Fc
zsM{D2reS7 at 1dD(l-?I~)ED{C_<T9F}fdX5$odG7LyjW*`wke<6l|fds^iE2l=%ygH
zDTAv30c5i-mL-=#pp78WHuX>-)9e?%dHsRo4kycF*#1;&)hkjY!m;pt2iLVQMlm;M
zh@#V at gU0wcrch|;BuXjLrYHzPMQt%6NhOx!5Jhq0iMRS=G0kh5dYp2>)*^?eXUX`A
zAXsE_axa(&twNHd&g>D>8fsoG`#Z?}_Rw%^h`5s|Xcq&m;vtuHu`IEI6C}!_T9-H`
zd&~7V9^AGtZyrA#AgtGOcieIhF*Z)t!_7Llj$vWG!v4KYu6l}xl(2Cea(NFh7-LAa
zA&L!)i!tY&dl3r at bsWb*iUu1MLeS_V(g3>B3eOj$N}$3TLWkH^%s|Ouadr}w1gJEj
zTuD|deWEiEIuUS{;@8FvR@~pgL<GoXJY*9D#s~}+sghJ`5?g2PxbcS%WR||?V|D}u
zLHOY0)I8Rm_jB15S0S7f&yqwz!h!t}8Q&A56DwV>r(&FWCT4CP5k(&LdWbQm5dew|
zLS)&p<wEYi at 8)WyJom8Ym<7+by<EoWvn)Ao+cGPKz;i6-=NCwYjYZ1h;v!D$kn>WK
zI;5#X9IF)yXeaY;iI~!WZaRn%O$U%^QSoUx7A==di^E8?IgXmoIpetmVchgWHbR|g
z3bh)=f#T?Yl#1 at t*5l>1*LJZQ at wrcY_J@L$1N-+7-t=vxo#O>Bd_I<?h=PEJAC_q2
zi17)GIK^h+MHfO8+DuM)1VMn-rtyFRjqi@}yyw5--e+8yd7kfxp!I#f^V at ISIy{j5
zaDT6VRk=D_3bl*SHobYxS?6uQBoR at d2$RN)Tk`I~Y9oHxgj;G<rdx>E^b{^joi>Gg
zX{NUld<g_Bc^R8~+ZOnqO&FzU-T1Gm0g*sZ=c(VhdFFFMh~GaJ2#y&GxcXneVBLHF
zBa70?WUKW8sjxX?%NbnujLR^wA_^47IE;^ZY}tA=h;ph%5WpRGAf~5ND%EO3RvLvA
z;MkgcR*)~*e^M+tpSt+sOxhmrc*P(5#UIzB=<kF<^cQ at 7`B#65@|;JIWI*J&@S+LM
zf3h%91dr@)B$>2#Cs`37VrAm!T8Sd9A!5 at 4fK~gJ;~+{&6Wyp*7GMd5V=D?dO={IH
z{KXfI-TRn>L2rHIyT4xx^p%d?!$L(eIzB*}W_i&szZl<kN$N34Vki|eY(4|}22L#q
z(iHBz6EQVqm|v(Y^I5GEEWmLzzDJtNTR+lL{ppKeICOXWXZ-GOzvlK!o_fX8#x`6)
zJ+jcoqo;R>=RQA2p at 7-BqfvX%UQE(4Lb#qRp?1QrgZN9w<yxbSO5;9-V<|jGQ!Ei>
zOR9Lu#XU*4QnYme;BVglk+DNl)%{88GB7wyoLG!*9OHrQlbnCy#cbO)LEg_1)nbIO
z7#VSx*aY4w%n&jL4je%2*a7nk3H5r===mcc2?GoYOM+t?EU9DLGG*H)5a={X5-&}3
zU!3A6X~P4W&-e1wOY&^l0+WZJR_l-`(y0ZF>9B8Fpt=J9mc>gO2$pwk#D~V`RBLhb
zGa4ae$5LcGO`+F(_u0?td2Tm4uL}S|2=gbe`t$vspBt~#HNM}=hT&nN1S&O&kv?0u
zO>p_spG;Uzi6f2gIgE`7Mn=JQP8|^97<TVQ?B5TSYDy5q2q~}}8>19S9HNpKV-z&H
z3pO8W<4Ie#$KX&eXP at OTz7ZDY8^mudM(vs_*ji5BDKm(+<4z!G;{vTfXbmU^p(ak!
z<ri(Ka2-uPr}6UY;w!J{z3VaM1HAS1fB6qnGxb-+8idG`q&B&Ho=m1dF5g2GSqR7D
z>Cd>3GdGVCRTU~RWV06I<AQ-9u<TO at geZckDa3&TP%dkNK#?fjGz1$@+h~JI8|>7v
zE%F7I;bE5z8z7T`FgV(&tUY<OQ?m)v-fg5qjzGu6kWL_2OAIv6D>a2u4Io>>VA~4c
zH57Zz{Ii}_?CV79bpznfU;n{Oy}nRes79Q7&IE-*fx|P3!$%@4D?_nRL<-4#EoF3U
zf at eJAB6^EC;+i5&p^%e|jS2b(FqXq99n~sgZVt+2s8kzyf@#{2p|%YfUr;DOq0k__
zU?t((%gj}W-bJRpccJN=8PqXDs6`K0#roT3ek%~-*bqjI>LW>`1+HsraygBgO<wt|
zEBijxPVeK&2ztY-|KjsAbG6^uG%-RpE6HWEI9{HGs>{Kt8o6vgy`?<$Bn9CyGCayz
z=WU^w$q)w`l|Vix86AcGL5zKhfzbN%lBAIyu64u1x71#yy|k<o at s~=?+u8rBV$xP6
zusuVlP5En|{jHA6b{(MABCXamsctk(kWyjWnv8467Si&wpIs`o(|g^PyVhD{yq-VF
zXFX=-YD`a8IdE`}IIL65M4W$SmXRUN)a(={Rd_;E4;Ogoz8&0g$NeZL#V<;N#IR$R
z=B_&thxQ|q__S~*8^^);ej`0xwr29Q*!ipC`g9KXESHZR<Mp+ohil%uMh=4ON-Vk5
zFk6C=Xe~iG#T#y(e8r;{0ZR|+ZEt+{uT4#tzdSNHfJ&<Dn~r$e#iRIM5h+~|4o0}_
zJ`j at 277*IT&u8c@^#eBNJZUQ#&qYOsG%`4jWMl+JHh|}!;_y<lm{jYdEPqvTX%{hI
z%xW%R*61%p7Zb3X^4Codpe-h+6$Bwozd*wxaBV}z*Vvipj%Q!lb4e at Bj|%`xT|oZ$
z<!^b1u>E)Ed<$V>GWiViwV2Ht25{^gwwFN&7o`Q0vnkTfVhIN+Yzp}zem2LJGdI%P
zmq!JVMg~g?`UhZa6taa=1cYYwkW!7RA=L(guDt}-vI5p=26CJZAl3ju7`7^s4FLGQ
z!po*S^NO5!)BtG42FPYJ<`uvHroTbhuX9{YZy`%hDMK}gNVP#~hiooSZ~q9=a!3+b
ztZ8Nz6Z(7lK?|gCDD{;XpBQCq;{a&@Ndyu at Z;xPf42nG`83-)^=(@Fb7i&3Rv*D!a
zP#{7VMeuk5&;bN#dQ^NV1-1pgr}1-!#qxodz32s-KKrNv&<cWAzU(cponNf}?}33L
zLp?cqOF1f)8c~v<jbw45PH$fy{evUq^L?Zm7Ai5*a}kAnFTUfE#L&}MWOU;Owrm|m
z#}J1gwV_xNjEzE1Z*wt_Qw)H0bAWd3->kL-+HL=10ic`x-wpzROs-KMk;}v6!G<ry
z_rcFW7#z9z%4ZHdf5|iWm>NU~A<QdY`sQC)tku6UJk&4y3NE><N4*xHQ$;qPVScg3
z!hDrtsh7TiVS0N9u^o>ib9Ls*DVF7t_X}t($>g$ZI%AxPO`}L5Na~Gr=u#61rQSwb
z+=&LjvJS8$3Oe-^I*vw at -O9r{)&{f#z^wFcE(L^E0isDo--A*K`UhZW5VLo0qtwkv
zuxv=<#a)*_qqJ>VKYgq{f({=k^YM at TUC-Wwv)}ey`>B0JmqIo}oWvxFCZF at k<$Mkw
zS)f{tv2B<Bff0K82gzh|lxr!64p(vP3|YT`C2btnXUmxrjE)cC*fvS6 at ymOAV0;1!
z#S;Vqv$D(B3fsRG2xfKT$rXhntsTX>5q`Zffc1!gmiLa0!{8wF^)+sroJ1U)1YFRm
zAt=ure9p6n#+T^+xHO46bnq}^<0Iw|Ui#+OXrunB;LD6HG=)+gZ6Hkr#hgn%pJ8sH
z#==4!gH1kPWO!sFekMnv1iSXklF63H`Z+9NlgSm>Fh0WA#z9=^5Z4U?!Pc!XyrDBE
zJkbC+o>sFRBY|xSAnkF0E*`*k=TC=2dVArFGoa9-L{HBm4jl$<L2aha%;e64zxJCK
zJ-z^F7Yi?Y>07>+&x&VN7G}iI&>-1D2CW74dO}a$BVWi6Mw*$~GEoGcmtk~#Gnq^d
zBWxbpeS}hR2-~)?Etj62e)7c}ThH2vNG<AR#WSw3 at ck1DfQ~vqn-ZuytT|wgLjgP<
z?SC!VFC|>`6v*dS-m-rhF*64<(=loF2$lH*2mj~qK7APgk9(`w<_BN(rq{l^=;a3Q
zs0H;igRsuvU_XVTO%Nw6P6p&M4jV^%NHrXpsj_?L{dj(c(Xq{(b4DKq#jd?`6pQ^#
zA2~=67pa%4_;!Yko5t~d>y(&^t8)H3<n}F<hne;y53 at 1@NF0lWwaR<3GFxbw_RatG
zl&3(htxQiFDA%AiZ<w1|U~zUDPn6ALaReRL*!kci{N2Ytw^^z5mSRp1S(YH1%MztY
zvonXrvnBogy(ndvnX9t65R%L18Q*vYo}VL1G``b|@0Ktk%iz!`&wo*NeeLBRgB8$G
z_P6- at mFnIfU|q$bU0lCwg?&wzu=jcA9hLd5V{!qp>wd-lLkrw{?_E^ON4WIK#r^-^
z%YJEMiS8%VxY~Bk7C!cW-nHldeB%AXmB4*crDp9>sm3;fjBDX}g47r$r)Qa)Utq95
z%a$$u7#;G!eRrbM8e;=vWV{|U8F~kXdEN_75b=*G+E%83wb%Qtn6+)LUDn~wmF;~8
zTbfjf)_#U9Jqt0gX;Ww7M=4_WgNj|d5ApCL2biCq!*vqswQ$9~C*@H#(RRNOV#}*u
z{<cdCdHbWiMf({U$3j_}R4bBHbNI*tj%_hCnB%Oo&Ze*DOlqNvHa`7>!#w{51>?9U
zFQKHX3}_Pv%Q=4?DumlBgS)YL(}nG~R}n9X6Jua>6gF<`tQOq=0PNa*gq at E}GIMx8
zmIxW>vso-xLeui&PU>7T#)!Rp58l3c^Z4a2`Moz?JUU!>S1x1!x18^gq$!C~#A!-4
zKSFQMIn+W2WqgK)hI#Jui^lU$JkgC=hfEfoaj_!Nca3{n3AL;e98F7T#BfZLJ)4FN
zzar{qU|;~YoY7f@*s%+7$L;&L^WOXLT#NJ09$?3g9ptmUR2PDql+wa#7IvO=X1Zz9
z7{(ZJ<jCBeLqq+){5!w-+Og5G(%<!!ykE_ at HWTCLQpj(k-X#9W=m=L`l{c<;QeDCw
zxj>8lwjvvN1qWzX_*fmXUGaG>C=g<0*6<20(DL3=sgVZX>8n4o4{`I&ySe-R2PqbO
zCN{V{v~w3i*Gba?N}11EEmggz&BBrAZF`>e`q%yG;bLK9f0%d}<1w~z1JAzdB*}b(
zXkB8atGTC-y~vbqi~8wq?%qdX?qzdu?zx?bf8Y?}x^L~}CwD(UU$4)m4OtFNPxHvG
z?VPc31Hujtyz^bJ+Sp2So6}$z6N&4ux%ak8S at wsCj}ac5w~TY;v)z+gaALa5)b-kj
z%cftG3rMqi2AfWz;~3`N(v6u6oYRH)lhcTA-+X{O?|p!gp)7+v4m);DGCjSA4gE!I
z&m|1Y|NN*kf==Y@|K^wPm?>B6{zSPTGn{qy1eZQtp4 at 7qHYZRgkKgeoe$ohK9MkF3
z&CAz1as at cE%d&b?(}?T7wU0aQdVnn(dr5;ucI`Pttv<_!{tP2S15C|KS3dgD*A(07
zeJVMC`Pwx<=>Pf`@7TXsb~1 at _v79^?J!O>hpCrx6=R(KO{yPYB(Wb$-%l}Tgz$)#3
zN#?g{`K_a;2PP&u6aVlu;+n7T=H3T(aKTx_?A at PH^~nGL8%#+=K~%GsAPK3}ry1$b
zGT4`6c5ab0uK(_1N(z0vXZ>|wyY;zoXn&_xcSNFHT(8J8E+1j at 7IE@Dd~NFyu37EV
zVL|FOJArkP`R!oq=HwX~g5fSp?Hrs$eC2BovupQm&OLLG2OoSGFAG`+q~Rh1J$dT2
z8gXi_{_x+t`hRw!wLH1A%ruFA+Z&>~eN(mOibQ#2bNxK`c^gg*@!L$mV{rn}%|XQa
za`$9=E7`Vo^s=S5(AXHJ8}aw-M_m2oUF_Sxk8PX#xc`Bj6nkwZHuhqhkWJ&m#9^I8
z8HW13mrfo!(s82OCzJS6N^{*cw|}Nywf-Os9a21c`-gbWb4n*a`=^y|ZS4YDO|w?n
z-OczHq75|d9l at 50JY`#az_ciPEgr_Dux_c;`3pa|(}*u$^8j&NX2Vd9?GHW7=va=S
zfgDE;A7bO!0CUqvh at yy0#y;y!Z+&^an_hd;M8FrW`Kl<1jki|I*3-ho#R#9_kzt<m
z+&rFl3X?&X)+JWm3p`h``Y!7WubcI+q3j6(;~OEH?O+KSxa*!&eCexqQtEL at qbgI=
zhZx(CqrW#pr96vcL1kf)xw$fyE8hIU554xU*D`8O1^~=;-?+6`r1pVw*~-SLi;+H?
zHjnbGXZxqTuR!ZEw5=d8W_<uyI$t7??xgK^5i9K!ma@@{u#?{-Rq&%*Lh<!)+`*aK
zMmVr<KXJUk&_I at +qDvIalO!?qN`=Z|Kq}L(eE1`8`1ND8l|9iSz+8XrZJS8!Jqs0!
zRQU+Y=bUrLx#Uv&)OQ$aI)7Ho*ki>4Sjnna9k=`NMcaE?DBnsJ+lI|sI`f4nMttX{
zGB<tyE-t+A3?6u32N^G9sJ}?YH$?RrqA((gB7$l}V$}CP@{u?E`eSYo at mR<8*WUJQ
z6<Ob_RBaONW7!!le(E^qo-a?2_EM&Ec5ZvE{(3>M%E{j$P|ztbl*z(|4V{U<P)2<1
z>yzB~;BL-6XPgHg+(|wYFf>rW5)rk^G;y4O5`@)&Sfx8Z^3m5nXT6;LgaAMYVQ%=w
zZLf~%*2n9CL#jO-FVE$dkFx0$YWnT7pDwa{6)BDZf+etY<FulSeUE{G!A66tZf4%q
zU*5stnHhR}JoX<vKwnAG*Hc93h}oF~s5D06Q>#^pm0B3tlsPX9<8=$x#}xotYb?t$
zH+=K9zpgFHH#S1K9+_;3XFh9~4Wp;eq7vQGvX@=Lrn_Ihb>=TSbvl8d&G#$Xh(9vc
zSd*aB*!~dWi(k2$`NhNJvssJ at 819o~Gae=hIC6MDQC!EdvIJ2LrB&=?%=qj6>{aS`
zp2On?fG~*2WPS6kYj6L@>VkY#5H*&R$rbx})|CSc4xdKL$uyficFM^=mUE_){lB7@
zPX|ALdpzH^V0fglkku+>FNGi8S{K(|cNbwaM<HLNr`MvC6G%dIROiU_LBhC(#3zXp
zluoNy@!-4P^Tz0SAI0MWfNCY6P|TWdef_piR~N<0!q`C>k7CaNS6<mi|KRCGe4{&8
z=XR3)W*y&Lh?VADtFk9sroI9E3=DR89+fKM`WvVD-hbYMlp)1pp0N?1tPgRxK$6s%
zn>kFXLeMTCNOg4N;rRm_KL3diJ*tL%_Tw at 03&pIt{%g1WOLbBHUJ$z&e0qBOdFGXU
zr at UWKH+O!gx;)xgKkFp^GVAZA{57wYicl<e59MBS?Ze!^{b6h;C7<&+W1 at sDBdV1d
zOd7H{H-{#{wX>+ykg90^dp`JQ6Z3P6kJ^}iOaRbYH`)GeU#c#MUk?)pgHN${fM;IW
zd- at SyH=I7J8a2>a6dWTt=%_bObf*2Xejs3IxHHRF3hsSCi?3dL7t_--*tTL~yqErx
zi_ul8<#}`xQeIrd2t^@ZA`TS^)&1}Kz at JVWIWi}DdW)PA09ck~Zv5tL*Ouq`Z;d1l
zpF*jRD=t5MiLbj<<#tWb=r-$H+5H-Mf40+|<<|rF(XEmA#<y-qsSvHJJmtc3uuPpO
zEE7i+(x^_YT1QAI6?;g+lrXODc;|axb9PV<g`atBsZx*06ZoC$Z~szdo?oj+9tNLm
zzL%#zeUQ<Or!Vo_OSM;I?C8!FJDqCxkEJ6R1H}?1m+Soc{zHgw-FSdI at 7{@!DSf>b
zTQ?7(lL}hJ)a&!a)e2#h0E%KMi%wy&JoCffc*%di^89UE9v_qa(EvaQVQ#$s*8f$T
z=biP)LmLl2)5}vX9_EZQPkqPGc0WJ5nV8X`PJh*=yO at Y{-**}V0~o85OIIWAx=ZoZ
zYwu)!p+XSO^R%aICFdKGxPm1V)ygajb92oVO=Eg{vsl7reqrX5 at BYB+U-fvp?~fY*
zLI`u?b+=p<R=K%WcS*I6;}$vZ{87$5Pn_~jq3y))R-B>N=+(DM7g#6ZjcJr&m%2nY
z=NAz-+&IY(ZrzDeF|L<z;dvV|X$?byG%=O(4AWCHC<Sp`rLQ-K=Xq4B<=4LF18?})
z;~l#>E*+p!4!G%t|2i|Ob8`?lDD5Jx44XC$vw8DrLj0zOZ<&?rmb9#6wP<Pg0hnWZ
z|5`_>r_pC<l>{>I at FR#XedS*E95{kj0h>4VFflqp999rQg9 at 3MndHdy0vJK9Hb-x7
z79j=Y%Hn^2?+4#_?THB7ts4Mg5b?uXe`JX$cWbR8NwovAk+Z*PvrVCR8qNA9;g>8r
z)1f-I{d|Ro(5%l2Tmph^H;6Agh`wqKam#HruD$-p)aoI=uejhz8}Xf#II18>&`FKS
zLkF2(2(YA}TAQI*@Nr!ys at JPeegB8va{q~n+OAt#XR^Mr;_R1#3Vn%oFu3INJ&bS6
z(AU>Yg4E3x{N^Nf{#yEfx+SdJVG+mn(rn$0)wlZq%u0f{|FCQhdiz!rUz<jb{ujS|
zkbl4Chg7Ny3=cb8`jiP=E5N7-qv|Bl9FIJ*m-)pA&$Wr81&Re9-}m;_YxUCm{_4#S
zoXC*<x;enL*L?T4lZao5m4h)Zj+0 at -Xdi=vAgx9mU6`Y3Pl(3qEKOVZaWCU;b-|ir
zHC|k+CCjn;@pf<k2pX~bzP`>-uSbZx at 78?#yZ5kX-z1Kea>->|@kBxzSHZ+2X_X|Z
zv1jirMjP^3mnd8yoAt0AdB?lo|N2WRmD&lPNb3TC5W?K>^&ftsT9qi{f^;eM^wHZZ
z$YdMcv|0-r&FTe}1zqgquHfj#Mb>Dq-ifelDt5=ynso&?TwRL2^!`2j5qI6S$ajBq
z7nQ|DHjeeMb;|%rR6$#y(h8W6YPrn5{bd{*iUpTAu3=jeZPLGe?+4!eXD2IDYh6~r
zb=Q9XS`)gzRF6DTmBsN2Ol%rs>zS~$!gjaB$BxyqodPOdT(%s;1Y65aH(j!G*42-%
z!?~0VcHilHR|CX-_Zt4=hxf2+?_qQjaLLmevtE;;bx0aju<e8c2j-cXsglh)WPHFR
zD3uTf_2+*0qi_4JG3Iew9QrW<K&6TsZ at N|5v54wb%L>yB8lRrt5hf-IjE%RIHnYaE
z>TLixp5M2M=<P)7)@5U@>ua(7HYIS$snaQRYe4LL81B1&jyvw&#i2t}Y}-1-*l+=r
z)Dc3FBsI_hQp7y4eTtwSQ7m~_BEfMi;;0^{X|nkvAA9 at c$xhQ>697U8^OdW=bxp>~
z|4Kc~kf;ononvr#jI+<SaNVP<U#@fQyjDN at v4GIcEL$=Ap>t#9E;)I}(|OaF28YWR
zI&1hd^N1ZgQht2bZtj0 at ACiP8UoeUzQiM>AS)bIgWX$4Xne7iwVo5>P7g$z`@419g
z__ch&|Mhph=XIxK`K_)xK$<GP at XufAEfq_@QZEZIR%6*%*T?rQtft~8m;B+f%Nn`e
zW`A2sb$ebNqC=~+#_Dc}hLwkCmR>DKV)W7Tc0#wa{8gapVB!@^7`H<|f+$7o+-cac
zbAj7`vYo at zb8Oo>z}Rq}I1WIhq-h<aB5WD6W9NSM?wh5M^KdNH{CtO6z4p3~{oOl0
zTCWGEEH$<(0363QSAYKNmzxxfmKb3pu&^DMY_>^!K*^&kWOZcyodD1lDO)kk#Txp+
z(#qh?KSp#>;PlZ%jP<r!Z~aGpc6GC*rS~10LOk?f%>57U=AQd at QY`vhaoJ`}8W2TQ
z1QA-r2on)TW$yUNLsTm<eWg6E8)G{HgPgC|t1teCPrmoIQ(c?6rWN3M&WE%~5yC?V
zi4-=Lw8`b0?NM7-#p==xdrdB2IyhF$+M=MNOSThh*Xx+=Z6anZht6UR@!)pNp1rf&
ze#gDk!hk1Tu#rMm5JeSS+n~}AL<*+P<m4p(b;|?fvv~#w3OIISmCYoPcl`Z7UU126
zw{DSt|B3gU`qKPv2z<{Q-j;d#^Iud$Wr#zMIQ22YCztQ%yeH)vHh(+YmtEG(T|)sp
zUS-#GAY9j4JF~`nR<nED4zBD-A$ILFJn~45oe%G4 at 7{g%_2<~Uv6ou4jOR&I8X$$i
zsDL!7@{@ZW;=ukR3=RyC&)Y~5k*2BETE6*{pMLL0>h(ZmGCrrn=*j`kKL4C^69ulY
z8mnxIqvfzmuGJ;S53+e|)}a7)QUqb$1^H_MU_CRv{WM?bT!o_y?4LwD{9wX?>3OCn
zr-_pqPq}b2Nn9n4>eyBS8Z1&&S|tdp+;;nR(nPa);|5&cpjAMU$g1aMMnC$uZ?Ash
zQ|~!Vmfc<h0CAiUM9F3mrg%Aluq0B0MxwP|u8NVOLt~^)BA^QgXea!!fY2>KW4aO9
ztmWEncGMKB&AO>M*tK18U}}+>>3JO2P{@Jn_{32eDHDXz7*f)>4yMlBLXDlf_L9qF
z$PZ?)tdum3sRiOoPkq|Czx9WI^jn(KaM+z?ziZy}_7879Z)6*mZDFMXtp!>cRGN~e
zUF7~cW&bL|i|&Dz^%B)|Jz1$cxGwZ`@ZB3=wu*T8A$WNA5e^-i!E+75#E8@&Ed at ej
zTPZ4y3BwAG)zJ3m7V1n*P1E07YOJnKLZuQDN6A&6{-^hR?{7aI2u{<{RRn0Qhwr=V
zL7w%TXJR`NtprLNj8>G(ibBC!a~YIlIe^yV3lO3Uk&iR7U;w9~;Nf(T^K$`W*A94S
z`y_kzPGT9=SRP&pEXUw at AcZ1LV#1(;(IKv#5CjqBYMpYqLQkoHM4)xT{6g(UrPXhK
z at -y!#pAJ2k9u)wLFlv6TjBq?GW3aVE8Bkg?KU*iCFDxfSwmO1zOF+o9hzL#d8VzMp
zo1^FLzJXOhkSur6FfG7YPs+9>8`-#-+-fE<y@=SgD`w~RX?E at 2k4Y6hMGMCfc&^0r
z!IGLJj;IGUqOgMRX{3w^f|yDzBnSdL$H%0aauBdsslNPk|NQ>X96mfNKJm$SpVq`*
z69ASa7K5P9p4|u7vSkyN0$YJj3}Kj{RKqvEWV>szl8Cwk7g!R4LN(4+TWx(;9Y7x+
z2Qa4b-Eui76j!b>pn-jd5ZfON*uQ6reFqMaB#OaO79$Lft;iQ_90!s(q`FWcs4rq!
zid;^RBz2NRQ>z68VS<Vq*McOz-Lb;wfA(|lul&<z-zUUrPx>_gP%c-*M?U!Rot`VX
z^+&fbv1Kc^Coo2%j7BNNfqiAhCyJ~5|I6&&bg%|Guzj%(CGdD3X2x%rbxup)fz%*&
z><Re6_veY~Rc7X9m|rY2v0)G?3~^GYShC1vUE(lgZm~>ItDw_>QprWim?(^i6Gg2S
zQm-k3T7njYQBr^1KYjN7|5&Xy!nZ#y#9z}7 at V2+S|DrHRf07u7@$s|RFus{HCdLWt
zhA0B99Y#irWV6n?W&fiAz?u)Ur3_n}#xg0zQX@$N(U1^9g4neu;M!{*#1;~zQw~i}
zv1NP^DJ>QjD+~{1$z=se6tcK5Pf)L+Rfy{-N+p*#uA?=CK}@xpP_4v7u_7_?j;EbB
za^5Rm_lMfHBtMO#D*z7d`hobshi_E9y#+Fbab{-gT=A at DGSoXjSXV@mKx at g^cn_X$
zt=9fK5dL at pAjBF(r`gacZIoN(@{rGg<3g;U62kT!Rla%6UG$W4_?ZmVT8*BfL#4b(
zwQd+0$xz7BnDMhS&1GX#lDNV^zmGN%N-5IBP_Ly_$`O at D{e5a%@pC@$>G%DJpYqWa
z073}!C$D_#jgI5IAP93vKhLI(V?6tL&n2lvM0HIRgE1B(8%p>YtGfx<Wxu9Rpo=Il
zrm at tkv>NN<WU`G0iqeKe!)zIT_ at ha7Y~M>?PYy5R02Z#3aAbOh=_8A5+1yX5U=!Bs
zEY8mXAW;NCnS5U2dzv&&NK-`=X%^=LDwUXetdLgxuNyZFzwDjw{L_ at 5fw5*d_~kEs
z%SC;~+)r#T%i(E5Z-0r=(Jeglsw+t9ny?lV#Rj7#`Fw_fA- at r=6I}?uPE)Y`eyt%0
zno5h^VD)~cQFUWvBT#wo{T1%N?=aO`jjSgzIws?LC^WOvlPoM&nV9IOuO~yLyhy!L
z!?FaHG{j*QAwmiT8*NgOxIz3{C1!4}PPv+3EOo$fdH!cU^Ztj*<*FzYa{SB#-~;dZ
zn7#Ai192%^B9|{RznHS^?5)f!7 at qZ<D=6l2MD>IyXe<ydq)oAup;UBMu<B!SfhAL~
z2?VVmiXlmw;a}Ns;J9vs#Y-EoAOUW_{UEz{%@RccM#uCNGc1-D at w^;Tq-Y(`Q_7Ib
z*euM=6GsuYC6Q8-CUsO=Czlgg7Nki+lEkDbEG~vjO_vGd6x$Uq`PYB_;J=*iHvQuc
z03n2V<;&jm8<y>U(Xu at Hdxps6^UN<ML}`|Zty{S4l8ew$LL4gMNHrEvGLlTj#q%sY
z&%(9^mL-r at ORT?TrLERgIg+$-k7YMzyW=$WmfP5rfXS&EJ9kX+$ivfsMhJ!L7;3dT
z3ky~H`$`NCdE{~qLMv+3T9fc#bV8B at U?MU;xSl|zszG?ANfVfvtulFJ5o64!FS~5;
zk6-utHz#STg!NOZ=sjuxBuUD*Z~VUa@)vKYDx))%s$qO=9N*7@%ux#r1A{|ce#NEq
z_Vkd1F)CIhu|g at +QiLH92n@2RAj)Q=#OB_TSW+UbCb65F?SgcmT8lU`TV?O=BkbEd
zO+5(E7^F1x_hr%Auy6k~eWffLhO+eadBkBtwNgQ=6e$f#g{UM160%u~j4#nfktQjr
zQfSjye*M6qd1mIzKQ0yA|MBV1d|>y_;;dgc0G7rdzw#~b2*c!EqoX6tEhLmH38m5i
zBSQmt`63dJTsF`77hizqW)MhpYS5`drHwQlt&et75(tD8SW<!|ux){~8?4<J(^xn{
zB^;hw<o<geA*{z}t*FHjT3f_P6-R0`hB!^>FSwkwbqLE6)GBp?dL6A|j7fkLbOI(J
zla*w%4j9wW?$e~%6w+d at 9I|Wo)IllqZ+-srfBl20sTnam+|SSYSQh|<5at!X|Hg&Q
zn+Hl+-{ATMs)5J;$&kL at er(HQelcNaXn<lq!^HR~nS7p1wt(%qARF03rY-$P8%?S-
z(^Io7&PU81S)^R9P_0+-{VY-#G_Y8%vRJ8+q$!p#IF4Y;ra>k~i>NfBUJHoA0G*~F
z6k0_X-7x8lPVijF7yO2Pp&O1YV+;mCq72)29S$nx>K|SG?;rW+AP9x;d;GkNbr*-e
z<`3WcsxVIfp^*33GSP=+c_3Vj at Ti6s`zC8t%L$oG4%_!}q=Qn1f&M;*hx at Q4gkemY
zN at _twrBZ7Y^fXg<)6`(wHbGR!aU5#(ki}}1Ovb0TkfFC^G0>OCmXIV7^;!+fk{F#J
z1Xz|p7==<1Vc00KwxlAL%djN7jWNp`LUP}ZL(I)rU-89%|H!9*)>-{y27nO4y!@qa
zx=9<JTP$SQG+HE0B?t#US43J4J07X9?@+*#&mW_Z^@&4GkV>Xz7Kmew=lWzaS%O*>
zV+^kEA*6*cid^2Mkk1oE31JYB^=*24d|XFjv|3I(H%4JhiV(V?Hwc4P32{;<3Tnhr
z4JpC%Y%Hsh%+l&$Fu?r}O;M at VUzW?~|Lv2X_{%s+QeoQ`PXJ(zF*`fYXa4?QiaT~6
zTu{a^F`OriQfl=&xoiR3^Krc_`9d$Y?c=*H2%AJ{gn&#YkB~NC5JE1ml98sGG)<SI
zI2w&(Tgc_cN*as;6vk+ at N}Gj<4IrpABu(Om2+%1~N*vp6<S|&*GU=5uJoNB1<x22-
zzHfi&Q=fWYcsiwKo%R4&;sSs4ia)<NOw5ndB;w3Xee{%a2n(ciNtM8HJcP7SN}{#E
zc6=<$LRvOLN{-foiH0 at M?5}1xn$~MjU<}6S<qfSds0Pa?0j){Xm^h9boidxia$N`4
zaj<L)jG-Px>^rn@@bFCKEmu5k%m4e+H@;f`yt4bp41gsN{K4<P`AW~v{6`^YGuZ23
zHBC7otY-gv7qBqG0xYC-uxz_A^P7&>qpZ1+Zz$x^YEsLRU^J<UQE7tKG3W$iR0AMd
zH<p=8QdHV-95}Xv=XqGRL;!OOHD>2)|GDSD{9k?bD<Au2bFI852>)0Cu&fWf<SoAx
zDfP9p&KR}|8Pm)N7Np96&{)Dj8H12EmUPevY}>(gJZ#57V1W@$7H`nHQC at 6NO+S3t
zXy~`h6-3i~Ylw_gDYVj9mWAs&IF5r-nsOzm9-LadcK>AM_22x)$ETi{?I!>LOXDBk
z_hEU{kN57r_ at d1d#jI}3`sLLQk1AbD8hGoB2Me>*&SOO^pyj^S`tqjsu9RwQ+F)B2
z(y~yg(T8U$d-fe%eA~ZY{Wo8DVz!?o04((e{@ves!@Hh*-sszNnN(t&Mgos$N#hZs
zF~f~%h>2xtw<gNA)`+!g?#=fCN-gOG074y^tyT_B)js%d|M#!|3LuUX;W+jaR6SV$
zSen^F2tN3s&x`2;+dsBxEca^1 at tb{lbX&8`l_uHIbTG4m;DSc(VVbICr;U`7AXH2q
zsqU>*<F{RL*^|C7apoE37k}YO^8^`BApn-Sfl^quZC?4xcjS8u@`7UC`=>(QJy%)=
zV?;~!&e0 at 5(>nW`38zY>D5cTb5JZY{HQ8Pdl25y?^X1ucJoAOmf2h`oQzXK+pP22Z
z4FK91gAjt3yyP#6TPKPer8MViZLYE{xlKyWGKO)}6zZumsnTYz*5;8kH4iIoZWBU0
zRIaJ%eN)lFZ(j3PNs~)FA=7_~0I)pLG{te8<6_fFDIukNf;vA70C-}Y-s6dB_5=W)
d7(dVB{|A}{iGK_`5CH%H002ovPDHLkV1nH%iLU?v
diff --git a/plugins/kimchi/ui/images/icon-opensuse.png b/plugins/kimchi/ui/images/icon-opensuse.png
deleted file mode 100644
index 83fe4d5df0f59b52dd609b3bd16838f4d2570ab8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3046
zcmc&$i8s{i8~@HQh9R;H+2W=}wp4SGHNs%*jK<hz5C+v)$1<3yWFNYOrZjd!4B4kN
z_OeFZ5HcYtdl9Z~{ibt%|HFOHdEU=?pYuMSb3V`eocDZE>}`>UU@|ZO01jDNm^yNi
z@;mtXxO=xDevk{iVJ4Q&{M<$6_f6)W1&9`|Vch!@zXN2Vd_Rhtlnyt;ggagL3n$@2
zuK*+xNrP}LD9i^>yrOYE)c^jvz6<~e`dFG8J4ZcOD~QdK=#}p`3e%S;Ndc#V%ghT$
zp(kOYHqsIbHl`V6$|_^dh?MK%3Wy^%WlY3rh0i5oHgAfP%>`|a_nhlHrIeClN;cg}
zykmHFk4 at o&i<*6i{E8gydVh}9!aC22MebGv241g-ZBHQmTkvq*>sO3Maxs4<s}V5`
z*oAF at iE?Lv{{IL*&j$0zP+`3;Y#dIiP%0}elXinK0a9&5Y-kUT_#F;DU6<liG%20M
z*2GzKo;`8|W9G0zAyGa;7}t5ufYKTf)m2P_EXSS`tv;Mk%`C!iV?dSm+hAevNdU=n
z05ayOis!-b>Psou1rgq>;ukbIO?xX=oc%qFL_%{AAvB_;Rmi{!P?69BA at Q<gedeVw
zb+BR=?8Aq>C`Z&2(8WY=JI>sdS`S&TgNfg%Z_#nXYt}7N6quP2hsEBdjv<yb?79PS
zhMWA~w?Y!&6Y*gEqh3Z{sBiAymm<oiVT$qPUcdvWP(Z_l;dwO2j}xgr{3XWu)f#W1
z$r#L?k1RV`^>Qg(>MfWA)+P`<Uo>#8DFN_Q5IcNTexql*QE1<_e}!$qxrkfQS&Qc&
z)Q6F-&Tqnh3x#O##>0Z=oPFq{N$ij8p{^<8)&6|inzS25ih8LbN)3VLY7?if)Q6EK
zTo0v>k3Tj1I3@~(I1n{7)sA7rOvh$po(iCqX?#C#z&mZQbir|#cM at D`A at H^Ckq-vB
zPK}7LH%~?L4)fBzwc{k*tNYKixhKv~Om>C{>nN^S7kvQR7wPa#@9AkZ&ad0Ba?Py;
zd*d%e@#*n>N#<yqjtLqcwgzlrH<p>oFiB7~Q)6ukOW!Dc)QV3tR*`V4wx3Cs at 7e3y
z7y?t|It6-oIQ;8D*-ORETWc-NFTZC~uZVUo?zKHfbX;@PkE*?QJG~jLYz|HUz7tI2
z46=UpFuX<>{G7^1na!U0E6W%%VUQ at WYD+ViUyQtnt9a=TTy1i3Cvg>}LyiK?)g%vt
z{Acr{mjy?5(u$Y+3d;(!g)wr!5Kk57Oda_PYkdGXOkhSZ*r~-TMmR`0PW&lfvU?ql
zh(d0|HhXXBuaqe2Y9`-kp>*|D$Z1-jzCFjLS4|(em^iPqn$xS at aRsC)jmgc at lG6$5
z`+&-YI)v*+T47%JAAT?w>3eXj=6PwB<mx=e=1m!t+c!vl#_lp)4D^_NpPflz0A4B<
z2?{GSu0Ix#No(zfU*g1=q{C)|*c&ufT^?$h`%b;@oqK;cpu$4c&97*1r{pHJe=~#8
za|laME6iRwa4)ob at bk1Ld_};W@!TTO+l`}ALyS3*b8tJ?Zx<^x;QV{ky>H6j_H|j#
z?M1Q;vGkU2r<|2}iSk6Uafcn{6s3h?P`?5y>k}b?UN<5JgU%|S=XS3V$8*g0B;;Bf
znHHxXs6O0>6NRUaO|~XEJsPt6sz$t%yTl-*zjOp%Q&rEO9y)Yv_1lksy3C!6mNPOU
zb$MlhY>^1Jn>)Y=be%^skPy1HfUnG5LI)~}bIHl_dILN7rKT;R$Y%+*Wt}A|5|=0n
z;7`C+ES>SUV~7h+QxI3>ZJv3b+pu0Aw!tK(Gp`8|gj?AA5){&LcGB~hQ53oIZK~5Q
zS056Lhv)r}KNx%_si4aI!%Gizsb2Ngg2mCbcJo^qCc>0itHo%0RG9T+xbGN`^Sd2=
ze)qDn=&CgG)%tgKfGxDI{A_KKIKaxYh!ts-X+4345Mn6jXelN?ArI=xqRabqM}T-s
z|B94Ba{A7{Eguy`2o?u39i?g82|!X_5E-7 at fPasr&*3kND%8GfS5Jbo<tLAZXsZw3
zbwwDKE`#PV9e)SIT-5vow0b^g7q9#Sn(O|j&aK{KCJCd^*7>tIGk~CV-a65Q$0_h!
zYe+bdMipU_f)a54xWgWGY2mnvm<_x~Uqbg!b<di-dO{!IqddEJfirZgk0CU}UW(n}
z>*)_zz41~Eo+^!{-!t1U_lBlclrr^3WrCFson%eDB6GaehX*ZFwmdtjkpAZ2z)cc$
zSN0iN%|?U>+59H<@_ZBGlf*}(qxq<al7l($rvQR3Y+wqOpA?bfd`UPTGQ+Djh<sCJ
zzuo!WM2Xo&A1eQh{*x>u^isv0<xnch?q+MFj%S`GuUFg4(F!1M8pamlgV~FH?@bfE
zp{q*+9;#{!AvM$C4wt3T%D27ywfucHURkx7p~5`j`z#27k6PTbUnX#~V=Cv`5A-Cf
zLZaVWDOIbuY#(6#<sx7QB)N?5g-l%!B9sFM-u-9qe)WY%vknn>?Z2!qZzI!4FV-D%
z{N;&~%xAfNif;uF0xKZ5(WUgX-NO>0&`m2Tty<`am5hC4Vy>SwQIpB+Ld7hW=OVz$
zP5NyO%LlEu^rZp`ejgd#Sh`&kBCH8<%G;mc(p|nzN6ag`n-87iQ<Ph-dMD?2ymXH!
zo1yw*{Q;nrqvJ(xk<ZWakAGy+gm_{p96BS*!Z&JeJj1kvo<4de+eMU1M-{KH&-l13
zyrEJ_M}RTd`5&9b8+E4^rC*y(<>48#y~leyhSi;HW2JVSP4xxuSw|bkDW$c`*ckA>
z!Y<CD0$<!mE0<T=TRRrDx+Kn9!BZXfd-g=)gSsM=#77LWh#GdtdyQ4E#%p+JJYt{r
z*a7g=I$yL`iG>oyarCV*8xNUdbn)p+jw`%k%dO5D%10gdTo`$xShV_92UnbxM{)dP
z?4B;V5uxDi<?zifMa|#O)k}$6ZFJZ2!1yOreYhW^5P4Z?iyBT#bGx5aaprAU%bloO
zztEh^lZ68&=R~4uJ{z>I4&$2q*J$OAtcZf0Qa?}t;bBGi8O_tQkik!J{Q2hl8W*7Y
z9-DE_CJ%*iPm-n8hxNGsSiM^{;(m`)o<VYm+8mKX*3Asz6HDrS)Q^Q$ML+JZj(#kz
zQ83ruzf=}3GG5C!q7u at fO+>CXLoT99>Tf=;5dV4xVyhmiSWu9)k<mr`?A?e^Z9+KJ
z*Uko2F1%5D*#15}BDr9oeCkE7iiFa1-#xUkpq at D>wrR1L-qj>y{4R>pF?qLc{!YTf
zSZ3XM*URCvBa?}YQA!?{C~ch7do5p0GN5WXFGd`RwBh*&lw_*@%pBkiUVfYzP&cLE
zVAsGea3HB=)g&QEO~KOP at Z1ULo<Zcg$Iw|U9a`PeP+w`kDxx+q{&YInt^HVaC1;vB
zor9{EY!%%zYa?w{*{=!?0W at n1&%&~h3;H!0z9%S#lW5kKhwm(9_Ch1T`Z=qxV!V<$
zYm>A1=g at f<R5s$z?NY_Tj6bIFO7Xj+rR<TRzsIesF13whyQ(F~m1s%I_S`u^0#{sd
zFF#f8Io)js_WLWIx`^eZVspa`?mDz+-|BJD^Y`%rUuYZ{WI+4^2<rngns%qY{G_)|
zl8i+4F3Kf(ys}JfbED0EA+vJ*LQL8#gb at n{)VTWVeE-Vn8Mq79T>WljOT1hDTy^rb
k`wyDue`PEG?`HRnhNAAT>MrGXaXmR;X=ZC$Yl6G+KaKu$s{jB1
diff --git a/plugins/kimchi/ui/images/icon-ubuntu.png b/plugins/kimchi/ui/images/icon-ubuntu.png
deleted file mode 100644
index d92c00f357b6b0e1542413f6aaf0de8ef4b8d130..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4818
zcmb7Ig;!Kv_a1VFPU&ut7*J4<Zs`<6YUl>(W>CbDj+c1pW*7<S96}_eTUzNFy6YQ%
z at dtc&t$oir=j^l3UF+`W+3`h3ON9uZ4j%vj5WQAa)I*QZzXHNVzq_R&KhXoWm;7r3
z5c&xQ*}%|qJP*~kUTFQ<zk(splj)CMr1e%Z_SSc|^Y(*y+5-Ii`~)4{oV~0e9=3w+
zp7xn2Njd<4T>G`6oPmGVL3V(@!Sqs}Os#FrXATWaMN$=b)07FBLtU{UzX%&9N-x^P
zuR8vzp=_|DfH9SBZi_*klK;~tgHLRPM~JBk1O6sS7z>z<6>lIR!lq`#cSQ!pX_q;a
z-MlrTk$x>XDoLH>HF`ZPzLFI*D&BGW3ioxAYGNDBnyYNoRT8;uQu2Qx)^Uv(fxkWH
zPM~CiTLv2 at gzJD`jFo^`XlZvn{v1(og{j{{HtNQBp7|+Z-%rnPKOxTmh2aB(ThF_c
z_AzJpa$S8(Z=2vv(gJ|AZaW-7KnWlj8ZOM<(H!$5^g?wd5+yXY?{e3n2JefH at s@
zXCxhd*m~?g4suaM(axZ4x4c}SAPZ6cyASjSG%@!_)r#jkU@`$y=d#_j+hTPUz7uqA
ze0vLBfHuqOW)17AiyrYDwJq&j^em(=s~ThQ2>BRcoQ5Z_xoFkx12+LxoV)7Q^7!a8
zu~<}?>}#&kEDcyB^VulBHCI(5ay9f#uApy(O+3pD+dsHg-?UDKfR`f~*df at fo^xv9
zjS1Y&arOvknQv*3a~n}O_P_YP;x3cn0t}C_Bqx501;JZQ6thfd^R(f8(3PHH*i{WE
z-PW(=<FN>f8>WZ2%dbwpb=o!?J4Wy@%KJrc;ZYL^txcr#@W=i~n+GGfsF*$AUA;{;
zMY at e&3kj at RRZ5r|`V&I`aq+4lor<4S-<&l--<{k3?s<&(HO&xJ8}M at M?6=IZi+OBE
z3x9^oQa{_3;<sibxjqI@*!9A8cWkcsu6)$i9nnY8!oC$Com1J(y-ywL=6S~cQs=hu
z1-38+^kis7jTv=O(LG`__Q!{2;#rU;cfh-{EUzaOuL|jQ4zSg%&$URCA$cba9Z}MY
zR{*8jN4kb%xlnGNw(GD0flWfo6g~SEimw6CzU?*l+Zp|lUJ(xm>>ZV)_cL=2(U}pZ
z_AQ02fPe7frDaA&CETrkTo&a9#-*}_QAZE3nc?JV912d>#u!6X_pXbpUc at xxm_(bE
zOy#?6Z&D)o_uFuc&-oOHaFc2GV2SC`pDhLXx)wXIy~gp<T~DSh8%U3)$j%rzx68VX
zPzA1sTXi9)w98l)?AIF`ca{pS>z{z4+DC808%>E99FSBAXJ`24$_!f<6{T647dS>q
z_orp)C-^~{&Vme}Pc^R~HzcE+_TPN~*iOV=N0GIOchYSusHnNfO>HqHH-EpV#68as
zu%VWMpJ1K0qhTuky$~=7jr_>9QGyhTkDt>jSQW9kqB^PK{;{inbxY=l$Q2NQBA7Bf
zU8)KNC4F;zAUHqbCVe2z^FQII%&ww4;aX9CID7k at j+tdPzwPsDIj6Kyqv^b)6_xX(
zRz)%CPWfWDPX&GItA;-YllvTY&sJIt)j?ukmO2uT*DNe)y~zQZ?_TKCuX1s?3z at HW
z0aS9@(oz}UMa+krmKuE-F at OUofg{&!r-Yx%^3vthXA*@^?k;k1q<p3-%=sEvK89n&
zw?{QQfB~A!NX;IswAFyE6fLV{%uvZpBYoe!X8+|7!*ZgPXBK7F5KssZ?Z$o>VN|IQ
zP&xYuq;oM1{DgAt>B?ySLLb{T5<tW6NNC>h<P^#(|MQHwEYI`e$<^RR!{d;pR=4Dl
z;)hrjJh3TOoIClSgkA0jT9=arA`~-NJfXK<N*mNsS$G|GV}I(?@z*gTi`Q*V1X~O5
zFOx>q4^C7*r8%QyU~<v3i2)-o3AqA}IIfXs%j9scKEyG`CZCT0Hbe>ymRqSKSi+F}
z*x_yvPZLC|F;~4}_ at 5=cs7F<$+flU~4=cueM=n8*uHM4uVK;)qkH1tG+J(R*FUiyg
z28`9TdW|lKi1sWdiWiCRx=`LK$hk2xR!p4+=al at lxa{)kWZuwi9Prs4+u~Ih9fG;F
z`2KOHG}dZtjb4HqANOdMp*O7PLuaDeTW}Yk<c{rHUq at p;ff*{N(8u%IK%nVMN&Jjb
zu8MyKw2Q4F|4Rla0~QzSE at jK1bSXnobBs~br`1&p!4a?s#+Kcy)ONgaVEnh3*reks
zq4#oj?Cg*Tn?C-+B$c-+VaQ96!|P0FfX0WlHwM&^+9f+aWM2lCR$O?ItK?f1Sd*}K
zcWCmAd>X5b*fd|fkO at ppRI*++oPKjok~tIPL9*fZP;ejMvOCMn at kKU7)4(><lc2xV
z3O68anS26+gEG9uY4ETa6n35uAAHj#v#)iTV)AU9A7C4OL3TD*><rd9`Jr51npJU=
znnBH!|1i82kpUTO)b;4 at UXRJ88V_*|k}17IMJsB97z at d^t9+bWV7i?++jUB>whAni
zrmm72i5?-x&RpRVFHqd5lEC9^RaXJTVJ)#tw5hF`9Iz&F&zyn{8>}SDv;?->_-hz3
z38atL6TkJ$ctDzycmW)O4}As?nV1v%PpWcbg`a8*B|o1<a$)dzO}6;oP-=wn?DH)P
z-%Wq!>2PPOu-G}&*}Hdpky0zft+VweW%(Z?)d!!J>u!yS7U{ftAWbYW<n2Ucjv9*d
z1w!p<y_mlEo=C9m3QUZhqkRyIA#|PYgTU^cm>2iG@;RSX1finaNBB4&bb#*gFp;6}
z%#A=QA0F_YsXfa599(ELe-ZK}=r|iOL8oEo$-SJH#+xzE@*CR{{O`cSwSl4Iy9W1s
z$i3${7reyrYjR2a%9|9ipnb~eg1Ce$knERkZV5_yTJ}++^L-Mr>9x>5ZsR>F8pB?-
zcw(PPfHs4TX#B&G5kYIuiv<eg)k(ne-ALAfcG;yx<?hIoD`&oQFe}@gXv);1!qOkp
zxWPjz9Nk7GdAv?bk!10}Hbh;{@K;4 at W>KO{BRMdsn3>&956#2``j8;zOVJ5>eokM{
zUJLa{T7n%JYgX~KsvbQn_eUh<k=NNYclYLG%c;y2 at j-N*{}O15q2zk<2o=~H!#@$J
zZ0hO+lh7B4mO~iYe=E}UxOWLyYTr}Kq%1<a2;8h1FtD|;{Z-qF at q)c3H1Ku*on)qY
z+`I$w=x)VHq%YzS$^Y^5UbQM^8k20w&&IB#-n?S16T#f^Q<1M-s>>VCXzHfEbS2?J
zgLcf2aeJ8!5{0$KDkgre`YD135x)Z|nd@(nR2c9RHQuIBu^EVcq^3QiFBi`2C@#y~
zgktxC6v^QS&GYY!GD at WIuW#yi9cT-p0R<PN6Kv3L1hT2*LEL^79_wblDz~rX;2k_+
zh6Y{KRv#`Gs=k-JrY}dUn#W9 at 5R<;~*(r_xGSu2@$#H)sd~(4*YouB+ywqTQiy-Iv
zVgADDK?JBDnz$cNdgRxPn}8Y0k!uuRP>8~)1F at 9vmUoXvz0}`3sy%WsC+Y%J1T`cd
z7v}ohgveh4Rt_Q$eftWx;X%*{7)3f;sKX8hUAXzBOyj}5<R6WNL*Wcnnc`bqcCX`A
z*lElYNA5VCa}Z1fX5g;KsHGeYkc=Rc-80JVN9j1NU=>;3X0%U-2FCw3=I^n35ezFj
zy10fEez+QJ&)=UpRitJ-|AlSBgaI+!dg`aNo@?~D>2)<|1}Ms%ITi6ke-3vxlUQtH
z_Xu0K;u4kv8I*5&y3$w{O`6>$&I^~E^-rn#m2GW4d4q)QHg<Nbo`|Ap&+uz{`^Od#
zi=dQjN`@kuz<WZ7cUSyN><^83RqyFXb>8O|hQMrE4|mL^9BR}U$KRH-=LeQo`jhOi
z0SsNoDNL3zd<!RN<xT?1(10QuNh!*eE(!6UYq<0>>9{FEE&u~=jokMDEI|Z8%K at B$
zKYduX(q<8ATa#O4q~~+`(SY{2GhB;i0*hvKrmah8mrcpa^ku{__kB#Rr8va+dpRfr
zADAHSWIE^FmCDryWUCYtRm?6+Re>JSlJKsU1}xYaI<hYn<#RW$m6my4IxV-zIqU4`
zC at xXqaRL%T4yO}>j=ja3^s|Jii8&6VS`CWN;dgGjq(K-w_B+Z<5>E*Q78>CuhR^Ia
zAg!0Yf3f?UkpOHLnHxni)$Dk^k0qrsSG-|rU7_FQEV{fxgue9nzR{p~m?l8FnPU2Y
zdF*4k9`Nnf`NQ|Xm|l_ at xF>xyrlxCx2PWX?r4gdC{CnnBJ at 9=LC)&rYGOx=Kb$Xpu
z_G7Rnd`tQhxk343rYnge1yv)$oqq{~_cf8e%V#j#RUO>B-%ny_cd35U&D?8NWvi$3
zyON4#VCQ8;mZ|f^%%_CuA*)tQy)ik}XMa8bC6ayrfN%x<vGm(po(W-|i%#8#B${uQ
zPX at A;!8TS!F;BLYzm?_8r#-+WkixCZSk!HDGtG%A=Wo=}$(7#8)FzBAVY<RNuaqEj
zvxS-!dO7xuW}H4pQ)sfm{`2lx<nymbM;<JPyVXm#luFNXV|nyc7nVmI=iuT|>O6FR
zBR~dDo+5k>E}F}f$bq0*)L7jnGaNvoGv99)pDrFVZ_bU7J#E|?%{Y{Ic7h72?(zPA
zcy)|4r<vWSo=Si^l`F>OWK9#`_1l!}{T61uzXN849mY)v9g!+IRRI_ITE{mxqsElC
zEV}*nxQsb|**VAIvST3rCtQL9-9L&km6W at VDS7nP!^za43*l_x0lt6G>_rZ*%72WJ
zfq+ZvAKTo{C$wU7rF^3VW0~PqT}T^Tfn4Ouj_%smtJGA+M{;v>5F&BU1oXY_!+};K
zkd(Qoksv4bQN3qq0Ncry8Dw$&pyg(dt4 at dWB8uegzKot+&(Q1VkC#gqy)V)yzY#LU
z at vh7;$-KmsL`>C_D!#jy^dMnD{fK08Sh%+!zV~J5ArUG?ZS))@e#h_>LcYDy88bQ-
zNU0Tczuc at xN7F@hcebxn<ER`ioV(}kw-PEAK{d%Aqb)DkXRE;x%(QEsbCtMOYn9f|
zeN3K#H`kxpT$fsf;BtPc$?U7^V;#KN;iMeCQ{N_g4Mwx>QeZZ%N9 at uLRYo-vy@EMb
z!(M{BUkg9YhIWu_Q at 6uU`^TI1V|Aet{|k#C<~TadvyLr1kr8Pb?~LuaIMYUXGC_c?
z+l}1#H6lOs;B=}Yn9$-n6cQlz(rEAzOvBssJ`TZJ(B+c99bQ^b#NB$DHxuxfGj?#~
zkk;Km)})#?WJo$t{XT!&-^KLJP7kF_4O_wOQ|2uBpJ~i0hQ8Edzp~xT;$kOHr_bN4
z7Y{aNG0rvE16_lBby{626F#y}YDG!1m~3iu!ANDFc$)2gaKrreY6)mYykKBS at Lp2N
z0RL*^z>coFU)hJyMQDp2UPP3Rm at UiCJ4IQxP9mQ$PSdM%RNe6W?t|?%{Tf+B{4G at 4
zr4~`%RoLFAFxV4KW)-GSZ9efOmO9b at v`nTL_W;vBY2_$X7r2fR2d4np)T(|T_51Yu
zl)MrqgD&k5V@^V|t9i7A5Y&qiQ}YaB+3T*wn>_*JRJ9c8B~$;Re(=k~mUi3}rQgY#
z<=tZ!xvr$0j8`MG=*S)5#hx>^b*Px#@dI2gUY{ov-kCtqr~j!Kd&*7`8nPMzpVl>z
z*;&Vv=>KXBes{#Qs4)5Y at kecdPaT<ToM`()skt}HCME!#)+;0`c_<GN%wi~*w9H6_
zy-K8igwjM$QKYfx4pIvg$9K>$DOj&nVX3W+Uy=6lKnA_s at cX(*b+MwMyw$;*ew>2w
z(8?x;hMi84KQFCmtmhNB1H75HKC`o81OB&whE2}P5thm4EKmDHY75{|@aUB#jCYp!
zFBGt6LdU;MTqVd#$*Q0WwU?HxV^VrHD>koA0z<F#IjuClp8*(k`J5;{h-#QkEo@~@
z{Af~Ou_So&Sl&PWuLrQb?J1b<WJ9vEg+`gsa_^b)cY;-#|L-0!`ms0`;rTNdvrYKC
z)4quT#O1pvWWpE<JuoG*O_?xa`!lU)G53^QW}`UKO$o;L;x2F2*{4cbgr4{CxfpYv
z5H8cLN|CjCuPNnH$*TOLU#G%;NtjF)hS(8Y?>MRN6qAzlUh8_#4z1+rD~r>SF6EoG
zT3<7)d1Wex>Xl-wH0-awY=2YPS|4GhZWH$oqew?Zegvxs#>k7oA^zXUBZ(xz at KQls
T?|XFr3GiA;OR-Yk^22`sn~zF<
diff --git a/plugins/kimchi/ui/images/icon-vm.png b/plugins/kimchi/ui/images/icon-vm.png
deleted file mode 100644
index 50dac50c5a0ee59f4e79170434f53bb3b94390e3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2976
zcmbVOi8~YiAK$c?G*_1+SxjOnw_GDMmIx6-d=n-&8()kq<W|T%lAFvDQI1%-m1|)L
zlcVJ*<Q&6~-=FY(p3m`op6C63eO~YP`}I8UcZ`X#KIDYZ2><{9K^f?o9o~ea4Q4+)
zTM++z0RXsMP<l7a{~h~n$Ah+ at iE!)YqjU0|_6;wf3Y?G$eFEW)8b<MQ?WJ#f1svn~
zW8Di*&&S4-g#A+Fkt*GZrm-n<u_IM6(We`*ZXNYMVhw0Dd}H$USYdKOOU2Xs4X*T1
zd#1>T!sWRfzrMOa{5InHIB|B;uUC_y-b`P{ZH>Rk5(<NY|J%wp^O<gq>H9ra<F+|6
zGQ!&1-MW^RqUJqCnc(2Lz?#m}jmj$EY!((2tTXIgoMjoShCU#_*{IO9w4|NvVsN9l
zBBP?x^W$-I;(4CFM&ZL);KH-rwYl&`?~o>3KJ!OrlIR$KnP)UzTQn=j#XOI|ZF6-7
zU@(}#JeQbSsf9S at p&gpBFwo>5OsTn;Ou_&>RUmbpVE)U-m*ub6rNo1(x2IOJ#${-4
zhM$#gEU}KG!6 at slT|=`?%Q+m*mwCU0Lqa5J4I$NhCc#||5}_CV#ixK3qD}qi`<o`o
zP>|}IG5eWO7^>=Z*LQ-CVQs=AqFqs%TRRud9FtFOFIu`bQ at 6@ObG(bXh at GaiNOJ|C
zZa(i~qELOe>cw0ingv-<*OFiMN9q>Y^sgX5dL^#m6Ow_5OC4OkjoBqE%h~!|!ysE>
ze*jF6d8 at E(EE?L`;;SLkL7(ele1qYGjSfPQZ?wX8lb*YA5C{SrP*Jr93kM>oJ6%k}
z%Oxfvu#Z>fNw#a6su$WQW^v}~9w5rE<@xzQho4_FX>*pU#KDn~ZT2f{YTRdG<WY0K
zoF`7M9v&f|YFUB`&f}fV)%4a<r9+=o#mmijs<P+{=bkLA-}2-~Ei?XiAMOKrtvRSG
z{r&x0j2_}vlbgsrvTe*Kr4uv)t2hCG)+<}5Ei5h`xZ8}5R=dzA-+R&f25sNBmQ~Ix
z*5M71e`g>N$S}zE9eSYV)2B~f4y~D1AP9#Ts;RF*8IjD(cs)4R097IpWXgPU`0Kcw
zLl%cC(q~ed{eO?q1|{BgV0C?DwAEQDR!=z7Pk2o>GPB0FbX&R6082O^mlMyaCBsN(
z^yawPZ5A65_Y0lXx!4E<XcdbUt<gdBQG=%5ntKG*;4o{5*Gaq+{!#p|h6^z(%d<@i
zzqhloT*mch)2F-_ArN{RVR2!f`uQnW1$=ybJX^Q%)r~<ra;Txckti-mU%!K+cCI&5
zK~i#<W3}@-xUgD)7kW%*b8~ZF!I%Sz_4jXrGxxP$mT;KXLCW|x+(vnLPM&O>)0st&
zRsPdrB()|9Hb`Q;GdhMnArG6+#HfXQul>xgFk9<I- at ioSK<37c%KsFdO)_q*#4&v>
zr*p!a^(YaII(*t|O$0$uadaDrz at 97R(fo}X`hGgij-L%6t77)cS&C&Umx~V|twZXT
zPdoEPhj~m8<PN~FfaS@(`Y)wPNc<fau8HD29X>$epT)&sVKV4Xk(K_d--8?RUw$3v
zjt|(Iu~9H?py1~0gRwS9DV-(pvuY*0)|1k~GF%DZynoy_T`(^X{AyrZGDAo#KPpvP
zQNkR~z8LuYd~OP3yT4>SnNPdG>TBL|(z;^|Qp;aZPThZLTM??O=Q+cU`-%?^-j&I?
zpE3SxT>%DEZ2$LoL69_!9Udu|n7k^H{^agGkZkcu5iqbtDKRM)51Q7_c<Xb_r$?)E
zm`*?7E`EGz=Q(?I9 at xQF7+E77Yba?06lawZu<|duY<Wza=fMue^59UI9Y!#f><J|^
zX}%9AibhJTu|n`Gr#<A*z}ZCQzNL9jjcT{xR0$vjeLHv>6CWqMB6o1tI;$Vl at 33Z%
zWJIUAM2LcV6TKz8_idv8-ns>F%(}?cvK8aH at 5ulETwwOo9xvsZb|*s#e37!<d at v&6
zRGL10DnYx${=KIiSsKin`R!SEOOD}Z$iG?mQq0!RQ#psmF{-lN7uSSpzO@?mYr!7W
zFDPul;cOY)pIKuy7d^%S;9_wOpZ4mjpv9#noM_>|t3`zqcKo1du&&F+HR;urCdAWp
z<6k6<+8*7+DfKuISNP+hC#5lf!gWee)obKgHje7m6eM{AP~iW01B$<`iJhSM&^F7!
zY}*Dcck6%!N`&*!n2ZBq1l8*@8_Bx59T~ixOO_EBD3c$)p<(*<>Cn*7kD5RyK8n83
z%WjB34PP8WHq}p1m03tP0VOv2wJqc?%$%_T+Fg_NEXeR2t&(6||02b6g#UCLU~qi3
z9Xn=jumiaXz?dl$YeE=4#`d(AQuiW<8{|2s#32m7W9=2_DNOrZg7w9D6&P at HY4ipB
z?DMI*2m-#XN>R1Rj^tQ0saj^}#DB=)S(A}MITrK7Rl!{8Tn|qA$OE>V-D5jxYZEV9
zy49Pb4krQ-)Jl!c4lCX=I4)gi=%id*t;cur)5K8SQ`%x7-yPmvw*HDeV+0U&{kQ5F
zd65-0$fA=`QxY#Efu3C<DskAeNM-UhXNW{)qYU!~vdQ!<XeBkWhbk>$(!P=EDtGkh
z?1c{`PEK~M6EIQ7wsj|>RUYXmoR*W_np#5^Emo2TRwvi&O?DvHArYycuFQmCM#_Pc
z^NzLNd<%KA0Y&*o*2J4<KJWnZ&i6HB96Y3YX|v&8iRMoc3DpQHIncRhv5<GFEmo57
zT#=Np3n!gV3zl?Wu1N|##y>?@>uD`PKd(0!yleGwrru=pVcV(0^bDi7>k9)Uy7ys)
z>%tj;l6CdZyAj at unJa&yn^XsDB03(D0xoME6-S_p`eb;`{oGM3Q;#v-YOmgQYfXdj
ze at V^#XLPo8exZkW4*`)WGLR%cxdUaYmjN5aMSPgzF5atP+^c^s_ClG^5s)lHSuC!6
zT{sI+sVt3ye7L%LkJ?1Czg at DS@OI$!#Y6J(?bbDqExhMdfL#4W<+$&*>E%DLaw&Hj
z7Xhx=V+jjlhc?*}>qHQ69iGcR0hoDbRZmO{8(OR%)k8L$Kd{AuR+1uLB!<3#5=N!<
zRWb#Z|NLn(U)nzdzh_IcZjBDywN5>%kgj1fCqHG$O8&CQwn0e9p8DO1W}lgM#(Iwa
z at D-to`$u&1is*%4-nW?O<B at zkr4~V^?>jRIy*y5LOJ4VL2i?f(tXf at w9TGZ!f5#{m
zkknXdV=c4`qBJ_D=qm>c(Y%h!!n+q-X4i~z%Cio2=4~*qf?_Kbd^6<aKEnOxYW)Op
z^mQ)@OK6CFooaC;u at BLap_4avjFJIB(xZ(d4U?t*LN0vu80U}#O6v(-EzF;1Pn7X_
zuP=V|BxgQU;m+M-M-li at Ez$8akJ)}!!><TDF<cEqTNPdZ-rBV^bFE&*;nLvGcxfq~
zTS2eO%DRHQQyvko=d!Eh8W^e#9kz5)OSUUEwM)8P9OY3R`MLHT6?d`|#MIT)LgS<^
z6yx%0U4|_BHF=ZG%2GDU=aSt|&%+^$G(?AOZJ?6t#==lDO%vZ>TSUi+S!7o{{604J
zvOS*tTce4vA~B~W0$^`l^{C5&BjEa;P20|6Hf~`}BIc$_0isO&jc5U#c7UAbC-&sO
zotzTHYC7JUE;{TGL<fi6j8H3>-8pOYu|HJLvm)9;wPOpK^_ptrPX<rvG|jc;bq`#}
z at 9EWsf*>QL(>N1x7G0$tb~D_exI8=(L)?q%_H5YJhE?vk at SqODLErHLrnkGe6b+?I
mVQE8J@&9#74TC1P9{|tL%c2?+(}WHuZvg71u^w5+A?$zXeWqvt
diff --git a/plugins/kimchi/ui/images/theme-default/Makefile.am b/plugins/kimchi/ui/images/theme-default/Makefile.am
deleted file mode 100644
index 7e11d75..0000000
--- a/plugins/kimchi/ui/images/theme-default/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-imagedir = $(datadir)/wok/plugins/kimchi/ui/images/theme-default
-
-dist_image_DATA = *.png *.gif
diff --git a/plugins/kimchi/ui/images/theme-default/ac22_pause.png b/plugins/kimchi/ui/images/theme-default/ac22_pause.png
deleted file mode 100644
index 9258aee87f0e2f430cf1fb12a4588f763f3c0a62..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1219
zcmbVMO>Em#9CtTbM!QYZ3R7EwV!5LOiP*7Yo5gCV96yIfTDmTcw6Ieh`=v3h{fzyx
zq`hSAssY^&+X3-;7(IbDF^V*#0ostNNpJ&chiPJ(*f=3gfS^*?io$c-6b{vpux!5%
z|9-#!$NT^N=IF at FyE^+iDT>;a83s8r_K~M&M+bTTG<W|x8G5l^z+<R{tA-CL)j~x`
zXB=Y!=AdCszxFL0q^RvBJ72(s>><TO4r_!Mw&r+*O;LkGHP0|7A*PFP!giC)FJE3`
zXxmCMN2P2m>uIoT56}2;Y-S{H&P<vKiy3-}9;_)uz=7DHYtED#D77TBrmK*7xXm&2
z8U#-!nRTZM*-=_UKBOf!9yMb;Ps=jPi;^t!FVI4a7q}R?<tQ&IlB at _X(i;~;toc?+
z$$|8SEwV~7WsE(A<EqsvTaB~GpWygJA`xl`LX;q)!L*BwTGS2tTM7UMrf+-LMlKyH
z8bwsWNrrg39)ja#vzx+hu#qT|GOlKL9M8r$#|h(FLkBnq|8ZkWbdaC+AeVyys`w^3
zk5Ye&Omg>VLm`lOqa5~aawx_WKxV~(F3x}?L%y(<Z7H#MN&~u_5<ptiMV?RbaS4!>
zrVD8v at O(>SE3PK#KozA#S`-LU7gZ6cs;KfBkmKouAhfs{H^7E#!j at f|*xleBd?Z)V
zd}v_g=MkD}RlsN&VHA{+M{8p;{oGO8wNN#9K0KcFXaV%?<Iqa`$f4KrtJquEkBR>k
z_d3`5KRM%wGhA34|0<T&7OB8+x>@>UvDrM(B^~3F);Mrp0;H{e&j2-FyH#9mHixz+
zsjfH1Eo=U_E3<{C2X?pDPc)w0Q`h${U)cTry;r_#-0i-(^1+#R+i$(o+oLyy)rrPR
zGqQa6RQ*y<Z%_B&waD#}Gs^kZ<Eed1jiuqwm$peKfB56{kCElaPu<xWX*Tygy#8yQ
z9UWc(m4ngZo|4tA&$sX2aW%f${zc=`{>0DYC!VN3CJ3Lly+xgTeKuD)G at tA0Klky%
zS!JL at nLTnk9qqeZzOi_&{C$L3`Rl_Qi*JAZ>Yq=2M&<4|=XMg!2b~wc+G{MR(t(fO
w>*#y%<Tu#??U}`^+b$Q*9#iveH;<`QTL-02da<sDMK=7cWb_g6NosuVZ*kO>5C8xG
diff --git a/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png b/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
deleted file mode 100644
index 7cde85bcb26ca808b9b02d5336872f10556585a0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1175
zcmbVMUue{J98c{SYPo?ZqV0n};)|2JOMXc%y~}#Gy(HIO+0}Br&chc?lV97|CciBC
z)w`CVuHZZen`;>q!NH~v?x9Y7Dzb+TRHmS);FB+cii#l4hoNGz{?hikJroBENq)cY
zFW=AS`#;Bfx;rB48`m=o6UlXI1-drUXUp1;>HE>d^Q&~(O7s%x#RH^l_=st at a6bY$
z#~4HfWLRTgUPmnqQ$JuAOQe+lTrsf|H$t6w#qlVbVOm-%o?#9n0{YRQ?WWlmzt6G2
zw$kjLM4r!kDjKpo$9>d0-d!}uhs~75w(bHg6@?Nwh!~*ajJSbPNwbT*3f+gt919jz
z$Z(ona;lW?0V?(pNW{gM$wLTaIS!?SEW;=ecqni at z2z8`l!UAZ&0zUrsWsmkPzqXh
z*%p=3><}TI!g1wtIbIgy*dOFzDwPU31R+K>V!@b8j7rQ6w$~Um6qvs45gWT8WHkEm
zC`q%_)1?p`FP~o_c7x?a(Ufr&!{cC_=Nu=DYf(EO1 at w;_t7-?uF%NMC6yQ<cr1cos
zUIWwIeb`W_NWD>Z`!+3#F`{8})Il!EX=#>ziCea%@M1>QbU7nvSxJ{5%s?@rQAyQ>
zEYu*Zajb?-3eBR(C#7sshY;#gQphxC+ck+-)ufnJ#Tqu}2E=epRI_VSyUSSdgIGoN
zkwLIu#CW9E0X;*Q;9v-QK<$;mjy<+(;d1b4Se~V5HRRg|k(Kqa0~YhE*sIv*rT>b1
z32XhIoN?3{E^Ll}HB0S?c3`+&X?-fJ3=eYY#Q1bH&XxYUOvmcaoYr2f-0PoTSZJ+J
zGaKuFVj6^FlarIb%*@=_c<offl__vP^D+Rfmu6?npH+9yD5o}m%``PNmBebKF#qJ%
zwr}PRFLb?o`wG|fbgrw;O`ZPatR9U<r+E2BU)xQvuUdEVLEBd+HjQdmH|(hH-!gr<
z+Sf6Ag+FlTSN+W9 at AgUu?sylUrsSi4bUlxpeCF-_aZPc)@rz)Bzwqs$H?Lnl-1+nE
zZNlC5ogI&|9~C0kBj>)K9Pawz at pRkY`;PY=8`;oyq>edy=*0QyXoDR7Dsp<a_FHEE
F#Cyajgunm*
diff --git a/plugins/kimchi/ui/images/theme-default/ac24_resume.png b/plugins/kimchi/ui/images/theme-default/ac24_resume.png
deleted file mode 100644
index 6f1f16f52f2c000a7413e22a0105c5d0b09c7a2b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1341
zcmeAS at N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}- at RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb at l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+ at n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn18<-kc7?=Qc8Ua<hnpheen>)I>
zSh!jkI9dYZ2Bz0Duec;JFF6%vZzj-Qs9rO?daay`QWHz^i$e1Ab6_bTAS1sdzc?em
zK*2fKOhF?&GcP5-yjT+yJrLizq!wkCrKY$Q<>xAZ!`CVki~T0%g!~QBn?g>Q=>r|3
z4 at w+Ji3KJEOo1RKJm~{D at XV8%2h1@=z^w7aYe at nF17ohIi(^Q|tu52`dL3~PIG%1+
z{qdYj)BS{nN)a4Uzgfz at U5|{==-~Rr(X?J+hS&Y0>>I9~a|+n7!)e0 at qjPDSCqysa
zelqu;f#OV^&$nmJ^%d*n=n)W<QMqBXLNn7=f3xbe`~%;@s_sSHJo4k~OgVK%Rrc$T
zR+%%`o}PbiUixvh#eaiq9=uWhwou#SM&C=8Uq&o5x)^q~e*7C)>7$^?RXt(u(xzEy
zOPU;}B=89}ep{<6u&4Nh>w+5DRCa}Vt_$zQ-(mgo)$`M{6pJ-XGfMySzIu_fqb8xM
zIo&>rjjbj2?e)nA^GjETTIn!NmEN#PGO#~*Y439ez4xkDnXXRN&Pke}eTMr4>oZ;x
zKDC3Jd3;tjEd1V+bK{)Y%G$QIDJfg_xop at z_u<1l?(CE;R_hhlnjVf9c&{M6XkYI=
z$N!Fd8jm^dX^2q>UEnA^L2H7Q^pY(86$;1V><mnqe;9lYxu>o-;m`U at 4@9nbC@(Pk
bs(gUqpHO<9rrQcmP=V&@>gTe~DWM4fDsR{!
diff --git a/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png b/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
deleted file mode 100644
index 1714ba2d00294e99222f833b8cf5e33da31448f9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1282
zcmeAS at N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}- at RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb at l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+ at n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn1xSBb;n7f#|S-2V*8oHV|I=Y#<
zS~!~;n_HL~7+4y?^m^tMmn7yTr^4*b1lkMLYl2s=m2**QVo82cNPd0}ECmE)<d at _Z
zXXF<sI0u_4XoP3xrR0|vYl5N&;#-&0qRg_?6t|-MTm^9WT4iFf-^84dzae^4$O$uj
zpkwqwi32IIz=VJ)5X6KheIN&(c~bL$Ii?7hH7ag6?Pg$LH1c$D45_%aXWGTy76pMe
z#*54EzIj}xurI?=?19(<x7iySHaBM<W7^hSeW!Y#j`idYMV)ys4*D7$JRonE*5IhM
zRONpX$ECYRU+uDc`!t~V)3Qvv1uJ>(TJRk9Wv+EDZnJyEl{9T%m!aDtjZ3lzucwwy
zndkU9=XRJJn_^3`-z1gDJsMmxyH<Q*>Nrw(reMu$E6&J{ZI{m9FXEiM!sA2qLEql4
zs%w7|zTdl|J2^M+!yb)}zAv@<{Ec(`CoA{--l4?RW_EbR_l}&24;eYxZZ#R+pPI&d
z%xQ`#>*>!j(GTAm-0<OWJhe&0QQ7NqNc)}Uh8%(S3rsu0FXRj4E66fk{VliT+D?am
zJVmW*?k+Ywy~(S-d0FN!6W0ZWZ4v(^pOtgWf7`vVwxRwd<J#Omaudp{ISm*X#7kc9
TIKK2Js8sTF^>bP0l+XkKJo~{m
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-down-black.png b/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
deleted file mode 100644
index 2c05f00498232213a081497051c94d16537daab8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2942
zcmV-^3xV{BP)<h;3K|Lk000e1NJLTq000gE000RH1^@s60!<xh00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0001~Nkl<Zc-oxNJxW7S5QgD*4hlCvSlFuR0 at Ge_ZDuQRGcH1qgN=nD*+C*$<h40h
zG at uEY>MQ2qgPBk{XD$FDVh-E^lOy|E;2qe6N<`dd=IYe8TI+0p1?Vz!djeVjuLVFI
zt6i=2>Iiylaa~&20iVF-U$~(+;0bss?Ku1Y at F9wb4}QKwE$URgR{P9UU8)c2y*e6p
ohvWRhz!<mz`j(%+o7#L0056AMLI?@#xBvhE07*qoM6N<$f;a(mxBvhE
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png b/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
deleted file mode 100644
index 2d04c841780fa57153d4a73f3bee69824f6efb57..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 472
zcmV;}0Vn>6P)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0004xNkl<ZIE~%Wzi-W99L4e1`D&V|3LS(5xxKfOSt3TG2s0reX(TMQ_!VNZ
zh#xUYy4w5!VnqmI7D4*Gx9xXeu`;OkG58Xc5{txVd6FmRyg%nW5C821>bed}RaJVu
z-XEK1W at bjQKFOP^uIrRiwwF?NFD@>w`cp_<*TXo4o7h=lGtOZe`|G;?Ev(<~594T(
zsU*8_bqJG5_F)J&FwyV#r}1`TV&Z3z5gcomk6{7tsw5ARJWBF0$yk!pxP+}gLS|=Y
zD@@`{k_|}~lH5)*RpB8{;0~6s7Kd?pFc^G=4F-d%l(IL;xg?vCXak&2 at +z$eMsNj(
zunvoOf(uEWmQoJlV*92Gcz`2#-Rt!}fB!epM{yie-&A{vTWzIrd}!03$IEWF3*UoU
z*c$A?b!=&`-(z*FzuPW)(d~B27vC}v%+1XOJ8-Q%hub=j+dA{(<Ky3XehPy5`T1ZQ
zPT~OW;VhnaI-O<uUxJ`%8l{wtE$BX;bvm7;l{_m>(==7nG=J^?H}eT{w|+~olSG{W
O0000<MNUMnLSTa0 at YLi0
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-down.png b/plugins/kimchi/ui/images/theme-default/arrow-down.png
deleted file mode 100644
index 3f5239bbb93ad8660f47d3def443e42b8f57c6e6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 537
zcmV+!0_OdRP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005dNkl<ZIE~$sze^Nw7>A$d6~#>G7g3=>Q#G^&cL#z*Q$%}FLnMWF=;0ky
z&|yo<#f2xjw6^sJL}L+>rbk<lQf`6m4I+8ox1kd>!=xqXGrqjf!~62S at ZUy&d_HeP
zq|VMxrlzL$3=a<v_W}piuaVE^O(~t<*x0zVwzk%>S4p8z=mPEn&wyM2ed+_?sd}|g
zDEv`2GBVPo-j0Z3L|jmxbYwD_l6og14yzZ{&P*orF`Lb<HX4l`lF`x89-yE;RF9}l
zbve`-b+%nN6cP8-Dsb{wNx57Obtoe4t4Gy!^@UpO$Y!%&)b|n5ubx)BBjTLem&@fE
z3kwV107|7&q?E1zkJS?@?IFtQCjrLB#sGR!N;UNca6sJv-T~w4LQ3g6 at CfJw)`1z|
zW~<d&nVz2hdHyY<_X2sKxVf6T1Uv_ZQc9<Q at 4!o-0xV5VP6BKfwPpJw;xbSN`rGAI
zU|+lcHBd|`E!OMxw8`x__5A$&`oO at zVnocUXCvZxM07_)Q+=!60+uHxCbn_E{h7JB
zIR*y at SJZj6S3RS?Qp*wXxmK&~V0NswHRI#sG at H$1z%}5F`k`8_wsvE7O{G$aN~QAG
b{J+T$+X03p_V~Q~00000NkvXXu0mjf`lS0g
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-up.png b/plugins/kimchi/ui/images/theme-default/arrow-up.png
deleted file mode 100644
index 40ce708941a35d8e1578e3cafb13d330fcf37c10..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 510
zcmV<a0RjGrP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005CNkl<ZIE~$rJ!?~O6vlt&78gOQf)-b$iZ2KSmn<r{=pcRoKR^>nFL|-K
z<P!wcpd?CfHn&cG04E2BSc>ALR0_q4C<tzXLwz0xuM%P+9mQw+bI$X7&N+YhZxw$l
zw%cuhqd)?D=yW<$dy{E}EXzXDIorAIN0Jt at ESnlU6=eH_?XILNk}lfr+Foe2S`+*K
zNN6^jGZAqXSOrdwgb8>L+_1gY?RIxYeKVtvMx(I at xN7?WaJqnO0H1(4;DGH5z`IhZ
zv^5+KzfWAv_T^%QGm=8mhNNXlHA$}}Vf&cvySA^_>-FFM07%nxFK`XWfmt9TVjW16
zBv}KHbRM`}OccO3AO%)?z24WTR;&AgMW7iGM~Z-T;AX$ye=$07nx?00KLjoTVfzbk
z2gnoK%eGs#=OiKNne7_za{MEDz1|z!4M|TW+4iBrpCyv!CC%!mp4eWr{k-4rdmL2U
z at s;he?Z=XKB<+(lALVlSxb1s at BVsAf^X*B1aaAgn!;<a;2P2}E09!x<ShBq<2*Aq9
z%4gsfPy;rTJkJGe0^5VZV7HuK`Ut!&82^}l07Tsjb=)@&!~g&Q07*qoM6N<$f&;VO
AtpET3
diff --git a/plugins/kimchi/ui/images/theme-default/arrow_out.png b/plugins/kimchi/ui/images/theme-default/arrow_out.png
deleted file mode 100644
index f5b4b8ed7de68dc79673472aab7c9672233bc8a7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3048
zcmV<E3m5c>P)<h;3K|Lk000e1NJLTq000jF003YJ1^@s6!gMIb00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003KNkl<Zc-rjPy=ucS6o%nfjYQFsL4y`Up|{ngV{Xx_Z@^RUpit=64z(dod%7qP
zJC1#vLWgn$#=`RR`A^nxoQQC3yWtnjA3M&uSh@$`3;3RcA~LvgsO!1|0<h8C)!+p0
zJx$Ym6ucO4Iw&zla?Z4E+iL;_10e)bN>o*)3OGCHy;lcJCTasNK943~_H9lCNZE8V
zY!vV*B6lJZ2Qy3)kaK<jD&P(1)pOf>zXLkp73kOe7`uX=fM at 62UW+H82493{b9)UO
z<HH&_{#1K_l+q*cz61f>$r`o=?#upV35v)7-vY;_sGEaR_-|KF!-fqTHf-3iVZ(+E
q|3_?f604I~oy6)SRwucp{R{vP7|{U{#BK5b0000<MNUMnLSTa7ET*pj
diff --git a/plugins/kimchi/ui/images/theme-default/group.png b/plugins/kimchi/ui/images/theme-default/group.png
deleted file mode 100644
index 1160bd97178375f202c3c20fef689ddf4a6dcfae..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1703
zcmV;Y23YxtP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU&Nl8RORCwCNS9?s8R}{bBqot*VmO`u2
z73hYPhb at ot@PRUQFz|tzm>K_=)0sIn{<XyibGT({Vw{pJTQnrgqMI>U7Ux{1;*3V8
zWNO4Ij{2AksU%LE7{a^H{mv%^EG?Kp;%!du*ZbY?o^yWpch0$&^ZWhmWi~M(Az^%0
z;+Vj5yq)KHJN_wse%}?p&tC at zdxEE4tFIe0z|Z_+)C<jmkS~+VzLm at 67Eu(Xaj(bA
z+#dIXzP`RSc&-VjM;xniQ6}2eYV~iCk&zK-3<xle<Cxd$WiFS?)ZNv6ytA{j)a`bk
z4rPQm765pGXR*52!}17ugi@&_BnIBeWHL!G#si&0PyT&k at _0P1VQY-ReTIdt9M7dF
z6bi|6BJ at z9F+xQYM1w}FDWh+O89=c7pC7?*x7!zD-zCU{l at B!nhBBMYwg4n$!P~$~
z|HBDQ;Q1mzxeuOP2GZwbqHHe~vXIi^H;V=GkXkqcNN8 at HKGr~e at Ro-~0FwoHSFKj5
z&uKK8burqQd~J-jC|VQ!fl95q4z_Ptw7C4l+V$_dh;SnrKr+Q at bq3ZR6#;@*p;T0Y
z-D{wbMMXuiNL3_LsZ`Q4M4^mSemO0Fx^DKI*{dd}OqN*h^ZAAejnn($k~e<vd3`U2
z0KBt+)gO~Wf|%G%dr3lZu2d)`V<3m87tHv6>a>De;ZUIO*R5ZB73<ZKL8Br-L`kuv
ztiXo?g;A*eB{mcJU{D<TyzHFpswvitVe`zdn%T}>J37!W&$i`cNy>u|5QA$05oJ>R
zr2O{w_CbYV8X=RHpZB`SWZJ)d=k~W+TU(1A4GxBQXXzQ~EIvN|3Z|{f&Ccrqc^z1L
zi^uJ$8Z{Fd40_ at At=nw0LPcCjO|{6gtvT&LqonS})dYjVP>5G@$VGcr?mfURXtml?
z at LcBcdiHjAckA)4Vvqwtu%U>s!kLBFLJ=xhKvY&Xzw8pe$w#VPVoT5b$Ci<K7;*s5
z_uy?lw(%_V%%x1Jic~SA>@D`p+}&YGNDI#>obgTByfW!ITv!q5R=>Bp2QXhSy<*x5
z1wTe8BKiPzJ&1Z0+-QNa%TPK?%9Kdks2gMeLj-LEYNa7bNJ_J;*^YNsuJ}4FEj6Ta
znlldu&R;NZeNLubS@~(D&oIHjqNAgUc&W%6c8D=5I!Z!mXpNAf2x#bHb=A@~>J9qm
z!-C^=*v~EXjvJrh?=L?cJyukEv6eO7Ym}HzF<riBA(8JZFuMXCZLhs_ at nFNB4Hqi6
zZd1csPg`4?NMx2WUx-EyfD5dnqhltg*XxH?w`45vD?T-YFq<&+`5*PyHlSY$p at Rk;
zE{NHrybf?5118gO at c6Fg^vUXn4<FX-*}XU7(W6JQaLNM>=L81S4smgDaZ+3hypV;x
zIfwYy5M(r=x3~8=tlf{r&cZ0^WCMjpbZ>)P6_^`Mkb-~=ggbNO*pVGi+u9Cn{BTp^
zXvLI5Rj1QAB?I8O5n1gf7L1|HMb^^<SD%Zy+%D-k5Ry`LLxQ4t)YE?=B#fnbKVPZ4
zyt8Ug)uodsYPgY5pluLD!OhboU5xGvxlA4tD6N4cLj(%se<B!(R2RVH{!BP9S4!Eu
zP>v8wUbcMMK|*Gv;zX^hvrERqdmV-rQ_UV)*8^FR79wQ<=|ANROVNS4uhnUH8I8tG
zvx;VUM+#$Ft6*vY6DJrZyxZH?D+FK}OCuxTl?eo$xb2h5GpA0TDxvtNW;UByVp0N2
zNK9lI85t}qJF^GQoEO2wr7bNj10Id(kjhCXWS0C|^2#}L=j=;MPb--?X(B@^rq?$i
zj(+(aavtImVX-9u{kU8Yu$C-BHWz2W3P>)7oYpkk<3O6H{?=W`U}6IN>hbV?r~zGF
zU5V+I3>WSLb)ib|bJY;>D~$K`45+FkPWeaY6u))bM?IxwrA$glV{9nJY+?BVwz*<+
z*NfgaxW`Xhm!L0)6gM|JjrW_HSYzYg?19tCoX!UWX|wr$v&8b`$;ktRrMf_O%OrCW
zSe`@&5GP*MkXVvak4k625bdv~yMqQG9X`8G at f>s9X|P}{9b$!8`h}XZf7}bXK4dL=
xz7t?K_Pq&p;n{h??+d&4&l&Ktujl^>FaVgriY_I-t at r={002ovPDHLkV1m5fG0*@2
diff --git a/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png b/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
deleted file mode 100644
index da1cd3f2562a5905a526446bcc8fc18bea06c734..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1034
zcmV+l1oiugP)<h;3K|Lk000e1NJLTq003?P000^Y1^@s6R_JLg00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-3t>283nlSO%wnC03B&m
zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E at cM*00VAGL_t(&-tAexPZU8E
z{`PW&1_K4^OH?eZvAftnL5(5A#KOeLoryLc6xvbn7idfrLqY*-qLqe%L|Ypgg$i36
z(dbjkBSwPpvl)`j+}`fa-u^(2muzw~^LF01^X{8 at Zysm_jzUN2Fh`A~Pjc5hKFL~I
z+Z}W#NVXC{Y>}KuY7;pNNspw5tO0f7IFeP8D-r4|QCJ)u*CII!fKd<0S(2@?9Y=DD
z<R_9!@=PZG-V7bLl9r_ at 9LG4P1)Rq+9Y?Z{<af)|`7qr|9MBxV)c`acbbCfT&pQC{
z%j$mX<hUFic+YA-2XN6mak_;`9K$+|XK?mUTkTPj&CIsEF5cU<hDHKoBi7iJvbM^i
z*Tus8!czN9a>$8s1<N-8RRC8_`$GnE?vb2Jz_2+0dq-p)ngI3#?S24 at sTh|bQ+;d5
zH%uEL`5>TIAzA4bYua?6Ovagcnjz|Ai5Da5sM6$aQ8E^l$E3xZb^24#IlFC{{Sv!X
zdPZ`HoHhZhMyRZj95%WP!xe at 3m<5`5?4yL_;89M%??>JmIN;83>nfaa#_lVU`y{Vr
z67H9I<>i9?7&xxqKI>29L{6meTNYI%0Emdw!G8E&QVE-1Rcq#UWYToK0q{&jHq+Sd
zU}FNnI)H(=d=J2sh`dW;({;UEMO8gxC-hsZHn6+_8Cz8V%OQ7`GXQ2(brnD(BP{Cx
z=6&CP5~WnH*XNDysWO?Qs#^et%pdJCfS-x(Dpi%PY)T=^F&E8^3~dd>ISl}e&Opgd
z>jQ8Oz$E}@0sK%^x9UJ%4m8_i!$G%aL_`u-2dYWWvJAJ-u<F2q`TaRWw_eh}pDyEv
z>yyFRKMi0z&>mIQrid&iVqA_4oV3~tBC;bQJ7_QMEcIHnC?X#LytKL>s%r052kP~D
zY<0ls{5RDBFDZ*`N~hftRMj`pW7t-CT|^!ky^4A7udB@<*0kwB7vI-)nq=l_0(fe5
zkBi7gBF9Bcoc6<NF-#g4k&RAyOj^9%=3_<YamMC0fYCtLR}r}oxmAjYmj^hLTt`+1
zRCTyh@)?Dxh{Y^e+NuMpIv5&N7WDCVBl5M=0B!+z9Oa;-3`iRt9+5!hy{f(jFa_X-
zh^)1x14RNBkv{-#tLjpkD=*u5$B=13xe4GPc-8~JKL<=Y@!??g0{{R307*qoM6N<$
Ef;%S0RsaA1
diff --git a/plugins/kimchi/ui/images/theme-default/icon-back.png b/plugins/kimchi/ui/images/theme-default/icon-back.png
deleted file mode 100644
index eca9948ca7f0c4eaa3c36d20e4fb2d72ac79b2d8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 244
zcmeAS at N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ-JULvArbCxuSRn<C<w3y#71eK
zT)K72v}tTjuGj8VdL~>5 at BMC(b=2TTSM%q?EFRVyo~rsxN}a;s^<!54Nr^X)q~g at x
z^JN^q%lN$@{6O#y=>_6_at*5DZ*m1wnKN6b$4D%Y<YV4)Sh2y?LNY=0pS;7ws8U8N
zRxu8ago~UK3wje6O$2ieNH=}5eE-k*!lQ-zA6s=>GtE7+RQk>%v4gUYTRgh7os8Nz
s0?gB1y)!t(JaL}EzvtS*278#<8D&)ztBkXBf!<*7boFyt=akR{0KU{)8UO$Q
diff --git a/plugins/kimchi/ui/images/theme-default/icon-camera.png b/plugins/kimchi/ui/images/theme-default/icon-camera.png
deleted file mode 100644
index f181545ed44db658aa6373c28ca33724f84a3d05..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4860
zcmV<Y5(DjtP)<h;3K|Lk000e1NJLTq001oj001Be1^@s6hJ^7%00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000OlNkl<Zc-quhU2GM{75>hdnVq|LuT8-}*kHi?*lw|mkwt_|3oTMnkQzm$YEVU^
z76l|K+A2mWlEo8M+b4Kv6jjPYr55D{TBSmLX{AVQ`cOg=g{F}bYQmo)XhX4$@x|Bs
zGdt6V%wAo<fRRz!9%&zT_v|^}oH_HIbC#TQ_<s`#07P`}a{|Bsl-F?pjK8eE7XX?7
zbOLDedKSPGfZJYY5rEHmT?1eozzqP?{vO^(1wh%`$N|&<%m7He&HF*mAq*e{umnKl
zKfLX))B_3tED=Ji)ms0Qhz9+)*PL^|1~B8C>tyC{0O<1XJ}}07D at l?&4S{I_(5aLf
zB%(5al!(T&EPKmZJLP at 3xj>VTMgTzjt63>EAf@~!5s`E5N|t56GR905iz1?qAPAmk
z=0PbXm>JAGon_g{+1c5Ih*m45zAS|3VrBs7&-46%we}}jmK6(Mq_zHvlya1a0w17E
z2=V<|t at alm`Ltn|>!6k2#x?+ph^PWUF!MTQUMGY|0cdM&kF|CNK<J!vLWp)|ZVH0n
zkL7Z?*4*42#Bn^GB+2)rltG^7QYm$*R4QGGqDZ7^nx|>HBu&$ed7h_!Hw6)OF!N=l
zRF#=?0HrL;mJ1<z@;tBkl$!#O0LaNX2O??*uu>^Cq?CFNz#4B1N+}xzLC(x%j6s^F
zWQ-wy7KD`2hGCdQQDmi*aL&mr%fi{&SvJNvA;fGLh9(FCM?^5j=vu8twOY+(Sw;Ye
znW42#OQn*LQUU-QV^kc+NRs5bG3M1cj(=aIXA$YeK at e<}QobmJSS5r25rLTz1Ob8|
z05iiF17=2^=kSY#loCM at 008nlujido3PK1lGl&S*+PmJBN+tM3-sMLK@#&#rhG(|5
zQpz4FW$DhHJFhtB>gl1Sl+Q{jS7@!FwT6_k4!m$IrG!!n&bc~hB0{mqI`w$nyXdIl
zJu}w<H$E%;6#9M#V2tTZ({yjOTKz46xUlS)xm#<^Q4~RIeV2hoQA*99Po>PmFieCH
z);VXbwG_v(%Cf99Upvk at SZh(KRF(l)4d8kK+6p1i80CeC*4nIJzkYnvrcM9exN+mZ
zT3cHu0nAQJOxSbh&P8X=oawrB>CzXHBx!w=ts>$|DfaZMWW&q6psj_-(xpqQd-m+P
zyl>yWzXSLXz}o;Wc<SodwryM2$jC_f`0?YbPoF;h%+%D>m*!*F<01f5fKHfMJfJ$x
zTb3_hK6Uiy(RYW3hu;M7G7*IU+QTsXA^=X)^kSap?*jP5IX5sgH1wy#hYuf)<M_Ep
z`Sl#$3_uj1?*OP0k at 2V3H58pkinUg@w6x5OjEuZDJUsjdB6<bDK&4W78o*WnD*(ta
z3~yR%&!%bmOCq}HoC|mF-hJfc$&+1anhyKipDV992m<o8gbUCz%d#Kmd2V}qdn at H~
zSy^kH-xhiRP^Xj<-QC at t?d|RTy}iA>ef#!zi0BspHdQK>LjZOVQIim&pt3dA+NXpN
zLur~GBBJ-5bF-&To%&8oOUu?3D^@6Groy*B%-r7I-qzXKDFIvqFjEwl{^sW9mztWI
zI!mQeLPTyJr<#b!5s_+ZYrAsn*s<5PY}xWVB3ctg(IF!Gu9T9r)^+|RBIJ3FEXxqb
z@$0o(?fE20CYX6~M at Pqx!Z7?g5zWk%(nNIm!i5Wm0Mv>|3nJ<_#&o1<`q+7$B*|n?
zPtV6hB!eLMJP|#kl%jIETrVQU0e8+J&vPiHb};kKBuQR%&hgC53;^^!h`E?~nePTo
zp^*bfgb?+j@)+VaY}jzEt*wm#l!OpNLWrg?3{ftZp_IDMUQtN2)-Q~YkH0}gx3Vnz
zhqX3gW<3{!X{{ZA_Qv7 at B0>-Z&{{thXlBlvnwoC<{ue~lp_EdMRdp`z6+$2k!)0+C
zuLLk|t(_sFNu^ZhT+!BAlW*+!F3<&$KMrUjqKS!#qG?Z<xhkc!Qc8Xp=Mxdi<+4&r
zwfeTWWUVbVaPnL{{b}`H=;-5|6IZWZZS$aK0K6rHF!L!=eSLkO2q8*-YFX}_TWqbx
zqej35g9d=f$;sX$M~)ch9A{bfx^wP>M>*D7rw0xkI1k`55w$XN?|h5f69H|l-FV`}
zi48=Q1VM1a81o_#{qteK_wL>M{^re_&lAy at 5Mm88Z!1#sQNW)FXl7odl=?vwMXRdS
zs<?6E#z(t$?HXOSY}r|6HjTR7-QBlGM at P>cJb3WW0FDFb3xeQTDdpPv_CE4Sfc6v4
zjwp&o<2e2q5#4moof#V&%g>)b|J2ynSU(Xp_x1H9gM))Ny1TpIB%+rAY$}(_JDK_0
zMX&yuf|gQ>FbrR4Zf*{yr>9>cqMHC-bIzRw(39u+A|b>CfH#O}1rcp6m&;!zq8~~r
zL#_2^3%Z~rt+k4xXfJ^EaUB09P1E;;5Yx`N>j173QN+wU!!TSag!meOr-cwQ3`2xr
zIPX5bKDp3BdeVjwD-1&du$h at RODQkrdHy#5w}>bQP$8l|0Go)2rIaX at N)N1 at bGd2k
zr{jBnh%6wt>lH6al66^@tt$rMdnOSCL2zGh@(|n7_a60r`j&I<Z2+sDP=41ZY-0?J
zF(`@#GeZagrBq#SKAYUq(lQI61Hgv`=&6B$fuF~5ytZ1c4lOWK>X9xQuwr^|%>ViD
zaUoq at UDNyb@Bhe``-Hr)CIHI;Yy{Bn|KTb8_k|jMY<>*juK?aDKo|Ma=G(u>uj+q6
iasaacZWe!B|1$t|HV7wlk?hg{0000<MNUMnLSTY1+a*>2
diff --git a/plugins/kimchi/ui/images/theme-default/icon-design.png b/plugins/kimchi/ui/images/theme-default/icon-design.png
deleted file mode 100644
index c8931dae58e4d3d95d7a1ebba04ed0481f4b74ff..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4562
zcmV;@5iRbCP)<h;3K|Lk000e1NJLTq001Na000*V1^@s6WA5#n00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000L4Nkl<Zc-o{^TWnQX8UFrt+1GPz5zood4q!Tg&>;h+8I2`E6iK+GFHO{#8jzq5
zVoHpd5QCQ&HBrDABFUu22jYW~KtMxa3_^sqv;#C515}+-N()SZw&%2`=eG7<%ZJ&g
zITRQsx{{Ubo&B%<f9wCh?^}!T^1%Sah-f(xB>-5)7(qk~00B_On8(JLNdPqfJ`rVz
zXgL4 at zyQ$3m=Hh(K!J1qIFrc~jWGZK&N-&1r?IfGu$WZ50+5qPB)-o%|2%*MfFu!l
z04xATDK)fW#fq<4mNhXvJZ$;C{|zbS52NoIK-m~G4<H`|!9+Hj{n^OK$hF2Kd-v`|
zZ*T9%0%QOv#@HLSZNJGm2N5k!tu<=3ns at T#$y94=>!jy-CB|6MvMg6h2_oVEq%kI8
zjLB)OUthCk&2IoWQAPEmM~`sl&YkC~@KJyQ&iT8Z=b2P0h5Ae+5{Sp+PY)b8aHOTB
z<pTin;K76Ca=H8m*LDAxOeT>|r;$u17uPIXw(Nt>&dx~y9DuoZ?;g6ky3p6x_pt%h
z$CMDlSeAwQBqFR at wdzD?XXkm_w&xEWI;3W2XHl(Ir}O#z?-^qcIp>g4!m=z#DG`gs
z@>{oVEdbDW at 7^_CU0vw!?|&}Y(w6at>HvTV!?3KiHd<?N&S8v!5CU^^bH#o8_RVn4
zaq;3st6Hr}09LtNj#VlZ?Rg#;V`w07KAX+fCMPF@?c2Ark&zLq6Mre7x at sH%UIeNJ
zpbUT+W2#{oF8&w*7-J|D3f~$Y9=<m}KmT_ChKMZ7vRYi%{cgEj{#3o1i#z3f;o-xF
zs-vTWjgOC~qr8<UkE#O`0Bit^h?cvq`vocGW&lsi<?^Xot#;2CqhHiVBFbelncsSz
zH&m at w$0LjQEa!Y>T>uTSC=?2{b?equW at ctq#A2~82_fDx#{8>PD*Z_*HRk(15fMb>
zAHwsz?XK(ol!%%cW3X*|Td7n!%ouya7(>sn-55kMek>N-ETu#kh9DwXmIc>!!8w0s
z17R4h48!n?O-)T-2k=$Sxy=}Z5aRVP41X{%Fz_^+&4P$%6=N)wN~L}$rF_eA99WhG
ztu-o@%3K(R(sf-o9*;wa=UpNQ0w|@RwMLWxLWpN71OQrVy|A!QC>D!p0I+QvLI_Mv
zP2tR$Ghf-XY17~8EfWCZLWnm#&x7y#kWxZx4a>3;N+}2-z}SlgSqD((*is;kik4EQ
zecy)=0+wZgbB<D}1R+GS9wPvh02HN^bB^PDqE1B4Ic(crl=;g5HS*+D-x*`@eIJam
z#rViX>+I*u81pm?!}s&~{HeyiN1V86+x8G+%;5hVoby5|m3qe*Q*LM at 7-LTuV|f4)
z0Ap9LUabrc4i*j{KK!fM+1XP{sX!@JOQ+N4dV70&nwpy4R!W79vTr1J7=~dG1l1r2
zYA=eZ$N9eh?;}T!9BON8`*E#S8&^s}DK**M-TjNUwzgY!52U(+lu~STbTl_GFtFD5
zeS61_9b?_y-TxdK8rqdeB;K}dn>V&iYmH<wd9A&@{m-jcuO55w-~qpK<;uqC>FIA0
zQEDlmcszdT!i5XnK at ik#-MY1+udna5j*gD$4I4I$an5G|EC4XnuqzfBp+!UjKy~ff
zwfz45``^oCGC%iypVd_sh9NA=8a#IF*pJ%V+eacJtzN!-S?}Jx``b-TO~0lFQW<05
zIL^Cg&z{}h+}u2GK1^ywAwjf0TzZyi009w|0L*RMwoTo>ecO>z#<bQ;Jq5X3?yt?w
z%{KtdjE;`ZT)K3rxOwyD;^W7UuPUYfv$TCmsbqhDzXT8xQI&}10nA5E9lr1^o0you
zjT<+R$z<^4$rA>E6VbBhXjvRmN{o$-CC{HfzmUu2)UI8-D4)+u0G=_XrBo^<W3kwx
zZxIoKAn>nUyXNiOx$`3hvIuBqW(GYyJve>(^fN7FjICmf(bA*97_)o-{{8>hxN+lO
zlu`g-Nhw#muKS%@t at g>KRW-)M$H&J%4PYFvxD^5b1_uWl!PHyGf*|;e)*6k|7z1NW
zb1Iek$?@aIR~|ij)NszZ<2YLwV_&Y5Uu%sp455 at lrBaC%i^cZnHc79n(E9c3apJ at Y
zIF17Vuq-P$ckW!_`t|F-6heH?7}F92K~orpZsZxJwYBwq$8p>}d-kxNo}Qvo>OI at G
zhoqEgBGN=ulTsEFiNsVko1NIQWy^cfT57oBJZqpY^9}$sH#bMKv$M9=x>;+T(ptO5
z7(1%0v2A-Mm&;9Y&I>nh-c&*eUkLFU=RD0m>~kGd+4H=)bUIxWLX-eh{}(`rc0zSN
wHM~<pTXiH|G{o?RXWeiSGm)ZRn)JT|00_?=SoP}gcmMzZ07*qoM6N<$g1D)Tga7~l
diff --git a/plugins/kimchi/ui/images/theme-default/icon-detail.png b/plugins/kimchi/ui/images/theme-default/icon-detail.png
deleted file mode 100644
index 978df03ca7480d0f9ebb3b4f1a1f73226fcbe246..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3079
zcmV+i4EXbjP)<h;3K|Lk000e1NJLTq000~S000{Z1^@s6ZwT)!00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003pNkl<Zc-rjNKTg9i6oB#Xy(D%}o3>nnl_4EC2vUxQI+vN_AT9x__!AOR{8;RY
z1Gt^yB}1fqdbWR3#LT$lDgi`f18jgRKr?<n06p*yd;-TZzG$3t_o~{RVW?ncyKx-%
zfTdtr6h$W at TUA9wvKGy37>3~ys8aA(L~fjOR8 at tl<__KhYv3ydCsloR&fR(Mvrkyp
z^$Sn~LkjjHa#U5$v8B$r67Z*63Vbw8^WeR&7K=rxs#%H>SKGEvfB-?v3=t7CtAJ}@
z1r(WvlgR7`H~@zfTmws>O6Q!>;deAR{%5iB-gm0no#6~a2w~Uv{T`T34pp at ik*$bi
zzci{knAz-bb~rnn9nKDOI*c5e=x~|QVX`;?ufSUhYK;2$%(<rln4-f;F8$~IHvo#L
Voc;M?!D;{i002ovPDHLkV1gS<wu1lw
diff --git a/plugins/kimchi/ui/images/theme-default/icon-iso.png b/plugins/kimchi/ui/images/theme-default/icon-iso.png
deleted file mode 100644
index d76290427e75fd1c6ad914acde114e065760b30d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4188
zcmV-i5ToyjP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T700009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000GtNkl<Zc-rikT}+c_6vuxp)*{H47Ga2dNXU$JiP1HacmXp;vuWH%;>DJzOqc9t
zORRUh(aj6JYZu1NGEnqlTc(le<YJ3sC6S<16qOPXEmm7BQf+BV;Vtd^?1Hvhq)><s
zmU)t1^nK6!JpXgf^FJStLI}Y^79|T at 7R}i*qq!W|47?4j14 at Cs$m>C%ALs(E0j)sa
zRO`rk-L(5CW*cIq(Od<5T%Mi!)#jB;*_fBky5&nK%~F$>rkX$(7^i<&qU*^h9fKpZ
zI{fr`#=Zy6$$Fh>Hv1(FP-!%;20pJU%=r4F@*H-p&Y?JSaZ=yfyg at El-8A;OG1+~`
zfjU{QvnKVi5Msuk!qC2>tp27rc6C5J@(0CS<&i%qj$IuPW%W0O!qC1WnZ1(%w}0!|
z9&yp?7B5RKTHRvn*&d-VwC|sB|7eJnMsqIk7x30R6Soc6ChK+n$!X at x1pp490@yQE
zn#oP{#roVdvehYgq%fUB0RT!e)s##@lFp$39w{9ApRG<|eQsKu&V6r?`(9}}kVUh~
zgNCXistPkO*?nv|(?dz7n!}q4sMcy;&^^@hfCh^Tj}#_bokF!%gQ2o0PN%`*;^>uu
znLy6HlI&Z%JO)l_G@~?{*>a|5!kEgUn8%+7x8+O^N~0NoYORLDn+hn&RR4RW&Lf2}
z*?pMoK0H#G^|@(r;7oR3%%CX9eQTG$no?);O`M^UOf^R~6##Im`$^1;09Az<^H+--
zEG_`{uGO$ltDz)QO>w3gn^)pg_miZ~)+=uo8Z0gvEH0|G8uqT$uzp1v)mjb3nQD$+
z8JJ&yRfQQ;Mnd at Ql>r(oE~*MMXx_bsYORLT-LCoV2P+FRI8w2aBNZzX>fHARV at JVI
zRTRsG&AZnCV6yvYi4f<dd$1+K)~MH_2{{`2Xd;e=x>~E@#P(7=QaF}RkG45t%uW`d
zKatYuZWk>Nz1V!gnDw+dXqm*+^LO2GB#DBwJx7|Bhu)Zh)5y>Z{h-oleiP_k0AoNH
zD3tX&=VTA|0&PERE!n(bMcRz3{M_>t!*%CRfMEvJLx(oxfBMOqWizgM{c(UVF5Pbf
zoKrTe3PXEsZRcQ8J>3JZBtATUM<@*Kd#33n_q^ZOD{NjVsWodm2Zh4WUi<tSlSy)|
zV{jz7SwR6Gl;t1`aaw6KZvg%PIwG$(0^8p!$vU{JEQisMi~tlftQpz++H@>#ZFTsu
zd4mb(4FOm^63)Ol<vFQ*Q&GsftFjLMX&XKmHEv^GI@^k~cqcy{8E}n;P%uV$PHIAs
zHgAwtho8s<n0O{p7}{%UZaAk5K}eQ`#T5{j9X at f{;S&zu^z+GBNEWRT-OCQ2xZ at rb
zasu6&8&07xwAW0=GZkacHTJo2j*Q1W42A`_hDLEmn$e<+#S|=6O&c<Gih^aS&w}(g
z5aO<9>;*mN$T*FCZh&($RuWmSGnwqZ<0mc8%2gmFbITPV5Rw5XNLR5cBe{|Djr4dU
zCP2nF6DKV$Om^S#sb=OxIj^q1Ylx<P5ALxLw}t{p;fZ{ipQfTTOPzF5%TlM1u8QAg
zFfbki+0^f$zH11eF6mk<>vdM^u(Z?AF-YS*HxX>)E?GobwtCi?cd{3wAb+=d`0n~3
z)?sO9qCq}k)sXeNroSJ05B$>ml%A)fEKglTc~0t_N<;1v6)I&sfBT0ee!TsdzaDrG
z$a-DVT$_axmuz0eSV*qROINXG+1vms6_A&v!tS4_<u at LW@Y_8P%@g2G%(<J1+&tAQ
zjb`V7|G~xEL!*4A)sUaAnp2o>y8<*n^l{;y8|$#N6KGmcmq)+$KBaZQe>_46>;LQe
m?LTvY`TCCfHNclF{|o>aAZz-p)g%r80000<MNUMnLSTa4!QO}f
diff --git a/plugins/kimchi/ui/images/theme-default/icon-list.png b/plugins/kimchi/ui/images/theme-default/icon-list.png
deleted file mode 100644
index 7b3b595ffce5fab49dbd2588cebd113922b9dcbd..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2983
zcmV;Y3t04tP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0002eNkl<Zc-rjNF-`+95QX8-*%cTPAqu2GfrJD!-2V);oPd%7I;1GO5R##>F96Fn
z_%&nC6rS<>i%Ah-PA$x=9#TqoSm7NToa17mh7NecE4F<}b~)!K7{@W=Ea&_<<z&M!
zbm-~?FSQU6_jvw;-+aKbFOTeTi%awovBnLqa54cWQDce-DWzlVBVtiJJ)py`c<^II
zM2Dkt{j45dW0g{x9GcR6g(ey_4Vnf`gQh{#plQ(j8)%BDrzP(2QO?V{yZ(k7d|``C
dntRp%9so28)jylt{44+f002ovPDHLkV1h$EiK_qr
diff --git a/plugins/kimchi/ui/images/theme-default/icon-load.png b/plugins/kimchi/ui/images/theme-default/icon-load.png
deleted file mode 100644
index 2ad195ca84691697a63e720003fe48b1573590f9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3678
zcmV-k4x#ahP)<h;3K|Lk000e1NJLTq000;O000^Y1^@s6t-qY}000V4X+uL$P-t&-
zZ*ypGa3D!TLm+T+Z)Rz1WdHzp+MQEpR8#2|J@?-9LQ9B%luK_?6$l_wLW_VDktQl3
z2 at pz%A)(n7QNa;KMFbnjpojyGj)066Q7jCK3fKqaA)=0hqlk*i`{8?|Yu3E?=FR at K
z*FNX0^PRKL2fzpnmPj*EHGmAMLLL#|gU7_i;p8qrfeIvW01ybXWFd3?BLM*Temp!Y
zBESc}00DT at 3kU$fO`E_l9Ebl8>Oz at Z0f2-7z;ux~O9+4z06=<<LZ$#fMgf4Gm?l#I
zpacM5%VT2W08lLeU?+d((*S^-_?deF09%wH6#<};03Z`(h(rKrI{>WDR*FRcSTFz-
zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8
z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc-
z5#WRK{dmp}uFlRjj<yb8E$Y7p{~}^y<NoE(t8hR70O53g(f%wivl at Uq27qn;q9yJG
zXkH7Tb at z*AvJXJD0HEpGSMzZAemp!yp^&-R+2!Qq*h<7gTVcvqeg0>{U%*%WZ25jX
z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq
zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S
z1Au6Q;m>#f??3%Vpd|o+W=WE9003S at Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG
z3;bX<ghC|5!a@*23S at vBa$qT}f<h>U&9EIRU at z1_9W=mEXoiz;4lcq~xDGvV5BgyU
zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi at a{RY)E3
zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q
zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF
zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv at SV$}*
z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C
z$c5yc<iq4M<QwE6@>>d>VnA`E_*3F2Qp##d8RZb=H01_mm at +|Cqnc9PsG(F5HIG_C
zt)aG3uTh7n6Et<2In9F>NlT at zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c
z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWw<V8OKyGH!<s&=a~<gZ&g?-wkmuTk;)2{N|h#+
z8!9hUsj8-`-l_{#^Hs}KkEvc$eXd4TGgITK3DlOWRjQp(>r)$3XQ?}=hpK0&Z&W{|
zep&sA23f;Q!%st`QJ}G3<GjWo3u76xcq}1n4XcKAfi=V?vCY|hb}GA={T;iDJ*ugp
zIYTo_Ggq at x^OR;k2jiG=_?&c33Fj!Mm-Bv#-W2aC;wc-ZG)%cMWn62jmY0 at Tt4OO+
zt4Hg-Hm>cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP
zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By
zLtVo_L#1JrVVB{Ak-5=4qt!- at Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>=<rYWX7
zOgl`+&CJcB&DNPUn>{htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2
zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd
zlf9FDx_yoPJqHbk*$%56S{;6Kv~m<WRyy9A&YbQ)eZ};a=`Uwk&k)bpGvl at s%PGWZ
zol~3BM`ssjxpRZ_h>M9!g3B(KJ}#RZ#@)!h<Vtk)ab4kh()FF2vzx;0sN1jZHtuQe
zhuojcG at mJ+Su=Cc!^lJ6QRUG;3!jxRYu~JXPeV_EXSL at eFJmu}SFP8ux21Qg_hIiB
zKK4FxpW{B`JU8Al-dSJFH^8^Zx64n%Z=PR;-$Q>R|78Dq|Iq-afF%KE1Brn_fm;Im
z_<DRHzm7jT+hz8$+3i7$pt(U6L63s1g5|-jA!x|#kgXy2=a|ls&S?&XP=4sv&<A1W
zVT;3l3 at 3$$g;$0 at j&O)r8qqPAHFwe6Lv!Cm`b3sQ-kWDJPdTqGN;N7zsxE3g+Bdp1
zx<AG)W?9VDSe;l&Y)c$DE-J1zZfw5a{O$9H;+^6P<9ipFFUVbRd7;k2^o6GusV)*M
zI+j38h)y_^@IeqNs1}SR@)LI at jtY6g9l~cKFVQy9h}c71DjrVqNGeTwlI)SZHF+e(
zGo>u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x
zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote
z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE at iwJh+OsDs9zItL;~pu715HdQEGA
zUct(O!L<Qv>kCy1<%NCg+}G`0PgpNm-?d at -hMgNe6^V+j6x$b<6 at S<$+<4_1hi}Ti
zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B
zJh;4Nr^(LEJ3myURP<E(R5tF?-L+xY_- at he8+*L=H0;&eTfF!EKFPk at RRL8^)n?UY
z`$_w=_dl+Qs_FQa`)ysVPHl1R#{<#>{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o
z4K at u`jhx2fBXC4{<mvYb-}fF3I@)%Od#vFH(;s#nXB{tULYnfLMw?Tb`&(jLx=+kL
z(bnqTdi+P*9}k=~JXv{4^Hj-c+UbJRlV|eJjGdL8eSR+a++f?HwtMGe&fjVeZ|}Mg
zbm7uP|BL54ygSZZ^0;*JvfJeoSGZT2uR33C>U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0
z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ?
z-G|jbTmIbG at 7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd
z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P`
z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000SaNLh0L01FcU
z01FcV0GgZ_00007bV*G`2i*o42M;+N_sXUK00W{)L_t(Y$DP(|h*eb-2k_rL_s*zU
z<1`WqI@*IQERZY+ih*P-NXniRVSb59`_jWlR- at j1HLZ{kt;nbkQ_ at rDL0M#Jf)+&y
zQ6lB5am>+7%O=4XXXf-}-#Q)dkhtKmIcM$lU;D20|F3-u{>MTH1(Yxb<59$q_#uRl
z{$G5-NmvMB1fIuD at zV}m+uPT-tFf`sGb>lxvu97u*u=@%*_f1hKOeW0ip7T6vu0^-
zZXPf&8K5M2E5<TqZ45?MDwV?K&6`gyK?tFQQV5|bgwU9A^~Wb4n^xmO2uZC2CK>P~
zp7eIC!}<`yZH<LGHNfFGenBJd#)~0@=@@iEf(-brcovspB33+DZo2 at -Y9#1cwQPAe
z?u!Jt3ooNB`zw;ndKsR?unfpZToc)rr)2-kxeqnqsvIjH#k7AC#M2MO!x)_d`4gwr
zXfT|PCTy=khy@{p<{?ePBq4<UNWs?J#=r0-HVvScA{y`nKF|5aVcNd6n<OEGI$Vu2
za+|)vT6{f#DEnfPgP0i`p0z0}KYn{`f)SXIb9UhqZ1~{Qb;nT`!Ll~A+M5u<R=k??
zPr$?^)^SYE`8~cv$E4O)*pK`ys7EQ4_Qv-OHT+EphTzPcb4LU`ws`&m*ozgh41L&%
zT{xKG)*&3uV5CS&1E}-}ensD)Qk}@6^>Muz`=S{49XfnC+w^=HmCzl*8ZzITaOAqF
z*Qcvit<u)k*0W^ElD&8XgQM`eTU%TET3TAF<KdjB>Z~S8rO1NaI4|RDLEX)F-l22b
zcAcG_mM&e|gWq7ynl;+n+il#qQ3#<JlTN8IN`@3hB}3e^aNc6f&uw at lgzyy9*Vh|9
ze7H1CB}t;YyW7#DN2?<SZoulutg7wA^5nuBC&Rlnc-$63m_A6Nr>Dn^88Zq84jj<c
z)n(3{IaU1>aAh1ZLv!&R=qiK|3O{e#o{k<rZUyeoZTbVx;iX8`G}F6b at rIj=vAMXz
zcm?eV3Qxbe8XnK6wra!h7&hVs%)@Lf!-rT|1H2#KVheT`(lk}6REi7B<-SFg%H?<s
z=Q=g(j{<!Qub0c^j%t(o7gZ|t*op_ at dMe;s at jl+GD!-7X|4Ok^sSJu`nSgsSImhi<
zmg4sa{t at 26_HwzLo{%6WDMg`;!WEc`OX4^wW<YzR;(v;h_cMG^E|>TJ=YLT?K_<~)
woP~?xZ8tVjF^Nz0PTqpA&`~azd-FJd12*I@(BIHxlK=n!07*qoM6N<$g48GX-v9sr
diff --git a/plugins/kimchi/ui/images/theme-default/icon-local.png b/plugins/kimchi/ui/images/theme-default/icon-local.png
deleted file mode 100644
index 092026fbc9301b311d5e9bb8556450cd6fa93ff9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 425
zcmV;a0apHrP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80004SNkl<ZSV!%a
z3vt3g5QaekH~<v14oDTWC}^snNB{>oAXQKt6bFEU4h~uc at P9LR3`t0`$1CkjcIF>Q
z*t`919|`SN&DO3teyag!GGNU>tY)1DHtd`Hld3fqfJmEsRc%!8`;+c3%hpx_Ji6dr
zeNLr`5o9L6cj-q0VqLVZ41l1V9EcBzGKAPd&d)A55WwWD41m-PrH%9=eL5Hm1ScLz
zKs-q71%w$Ok>{)QEA=H(%5{jb2W11MBXLb*rtDM(VtLT<1drSXA%U~LlyK#4<|ZQx
zKtSK|rZF;-`9tBJnv7$BY{yeSU}(lm%ufOkxykSV*^VE}`TGjNJva~pDUni>;Q^NV
z!FN1mI5{$xq`|G_pu{>%1^`eUcl at n_d;Y$@93}&R-4#xD_7?vNfKufiBn3yO<4teR
z&<t20%)x;V1vtCbMGG5%Kal|*JiIRJuq_#g+|#gkXM(Nb#Z~_aZ_d;J)SiJoPBKc^
Ts5X1J00000NkvXXu0mjf;iIrQ
diff --git a/plugins/kimchi/ui/images/theme-default/icon-power-down.png b/plugins/kimchi/ui/images/theme-default/icon-power-down.png
deleted file mode 100644
index 2c653bc6af72f628cea721d618849d912c1aa186..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4372
zcmV+v5$o=WP)<h;3K|Lk000e1NJLTq000;O000^Y1^@s6t-qY}00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000I*Nkl<Zc-owneQcH09mhYvbI$YJ=l0&)dwcr=SST;uV4zrVux5 at eLPZ9PLl(gq
z;uskcT}Gl)F_>X8MUX{IU at UHbY-?tw1~Qm245J%0p);bqxY9X6-df(;Vx_c~+xGT8
z=j at N(ON!2D_Di0Bo|E72`+NI-&k?@ZL?dRrDyd0erdgZ at j-9YqKkO%TU+DZL0GOak
zM*TLJ`NC+4EGb0%=%w)7!pLLyoJ^%s{Ce9q+S=OqzipN-t3MKJxZE1Q-JOXqa3}o+
zcVWRJYh6Apb<Qzo&YaKnHJ?+}b)`p9IuK>j;uA$-0VY=0pw;N7H*Dx at Zf<s87Qg^f
zr;-VU*dw;5XBbhehgehSs2~K<sOsqIbh~%&F8bNRcU^)b0aQYaUhPd>+F+_40_13T
zW%H)ou^oei_A{9&J at n4OgPo@jA5J|LnRZX5__H%E|JDmbr*@vQ*?~_3C_vxuO}u-V
zH+H*$WPqktN4I8c)BoDlezbpNaHSL%J34X?E_<x^myx<B=9uzl6re;_PSvH8A00UQ
z<cGG;6$1mPySy>8eqe5R)`%o4RD at 9~Lg}C#z3SmLca$XJ;+(rywsVeXs?=`y>BFTr
z4tlp45z^vQA->GisdYd1zp|VWnX5 at E7F*%ftc{5tTOmG4JpAksiD|Wc!EG~265^Q=
z at p0A>jmP45-McIuD~TPivK~qCNMMMe^#U_${SS5ZxM(_w0_;3pId_7 at 8xj~wF-R^C
zHB|#8zkBE%^R=4&elGkBU&2hkE}uEIbl{1lo6cps{^=vQ!h{oICO;n5EI+?zKWelD
z-aJz|-xEp1m4|WyMiY7D?t}8pX?vdEwE4ZB-YbZRj9g at AZ3yT+`HrsFxcGpD&f>9l
zP#%db3XC^irNkRGL1J|QiU<N>h?+X?g8!3+Zvy-FzW(}9mVQq}^fiFIMIv4dkSN+c
z#l_a+HuL9^WQaOlr=8rQ6q1gKt_jd+1o9zjM(t4ozXdomx1oV7_F{N7(?;GxE)PcV
zzjLz>7zKHN{bBdM+%N?ZK#TYyq?Hn)5m9Acu>;N_<ElOa+JOG2f3cpefBnnZ)T7I{
z+NxxyR9A$N_4l3d7uBBxx{8!K9A5r-z=hq#Dn!Hyq6}aS%BteViV$At?g1_VVZ?ZR
zck!LZEz1AHtzB-!ag&rK&STUY!1<56yNA1m(}Or|ao2Vqz&Pl2xJwF3hyNG`-)>FE
zq36(%!|uHU at 3Lyus+{r6S*b|A0t7%m(A(VH9R6neb^w{85)(sgY6MvXFvjA#hOnm`
zt`-E*3Ul_-x0`;n&inD9U9^92oc8v1Hg4RQ13m%RxpOCtjg4fpSpe;!g6TT3=$igp
zhm-_EcqVFkUH<Yp+kc=+2lI;)@<OI}y!hJcc8+fb*s^5{jg5^s=TJ(~+uKVflPMC_
zt?_H`7(;Zik3u83fkE`_$(?F!#en|Cl7(Do`JnfEksB5}hyz$0ll)ZuSXFXvU;a`{
zF3gk3WF(Wx(AU>TE|*io%@kJp6TY?7tKL>B-k36F at a(Xb`fHXP_U6slr~lp3DtnK;
ze<6RQb==fQd3|xwtPq*3;`6?$<B1{M=@a&9KcEW&8M#>{(?9cT at 4M5Cc`hcVHZ4AJ
zF-SItnmwgE`pn8VB_3 at O=bY-r+G8u8tgQOe-}jWoD`!(!*&LRBXF2cs+uLmRtql2-
z){zfHjja^_*0lK34N8 at XA*p=KU<mQRmb|#G$t;}xN8nW{h?sT|c0TxAz54wdF9n`I
z39X9j$5leIF3$j#&{+^r2mzW>F+|bmTpo!AHuC%fE&j>{JAjvgGerOaJZG(!*|uwL
z{#QFTsji-z#5Z8fHJ}`J_#Gh*gWx+s7uYS;<u=%Sf2()zyjOu&fd2qaM#?Y{0g}0v
zQ+0#SzP#Esy?;BOWKt+$xFRXshYs?EX(eM$H{5bL^7yh=U01so*bN*nUYnl=DBf~u
zXKi)vZ|~kZ^oPCQw?|IRq^GZp&<+cpR!+(id0juH$6vAFw3+|)gJ{(RybWBu?gjBb
z0E!j>mG(;JM%URhi|pWdoQnYp5hbx;NJghSB at sOY901Nx5WbQ2-vIzgSaovf<_KQ^
O0000<MNUMnLSTY^CsYvt
diff --git a/plugins/kimchi/ui/images/theme-default/icon-power-up.png b/plugins/kimchi/ui/images/theme-default/icon-power-up.png
deleted file mode 100644
index a4575f90120e56d21d42dc4fbefcfc571a30ef71..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4367
zcmV+q5%BJbP)<h;3K|Lk000e1NJLTq000;O000^Y1^@s6t-qY}00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000I$Nkl<Zc-oYfZE#i96^5U+_qpfX at 7#NnkS_uxfs7)QV4(;|h49fT6_rx@!PuF$
zfUQ3|wm(|Rw6s$#YAdZ~=+tq>l9^7ag>fR&I at oG~DNzJ9B7#yN5<(yb0)~7i_nf`^
zBe at b7I@<mB%v$ey-?i4ej_}D(l*UOH%LFgVRBO>#{?plJk7tLlpBVfp07#ce(dv!r
z56KMojbyYZn_hD6oIi0xb1I!jU0oe#&YZbntn+CA;wdI2GAvRd!3%>Q1XI4gZr+!_
zefy at TmFVt<hKBzOK;T;HP8jXD;zX0+h9MikxKz~yCA#?Ghac%_Y;63WQmGpNI;B%2
zGyWz?jX^Zp!6 at e{awHm29UT|!3okU};?#{~AIm^_QS{uE>MPZ=<RJuUZ?=!Wvd!%9
zvzY5E(~im>di|}AcaAruzW9LpY9hnzp+5G#`n=hB=^TUC11Lb>cCT7hvqZLPO`hXH
zewlqLY$m<)+CSO`5c_d)N<sVi_TlfZTh+bddun54jr>X}K=G}jN?pC{Nweufi?w4V
zQq%8Hvp!QRk7-BpVkse>7M!Rpe(- at GE{nyIVy*pHXKNuIOPdXw9!wTgn1$LAqDdi^
zCsI}|KUw$<Su?f=D!+`_?7QVhUWD<n6olhowNF|8l%C4`+Gsd}W5=}7T8Kpx at l`9o
zmWjsHiD=5;#lee$7e(JRSN&|}Qpyvt3<@xlXUU>W35&g`5RQVyClxLk{L;<aUN4B>
zyr0mJT)$F-*&ba{`q|{{f}cOyao)V at gsy(`VpK2qCTre4 at i$Z=pHTH|wNyKj at S-5f
zA}DSv|M8n;iTN-7X3Jx5T<PjVlw7-%)&zh)w%=Yjwx91BL&w$Cw<Oct<%UBORU{!r
znNntiJaAkvHlQFj_594z^)CZ^UfR7o+uuh>5It5Rt-Kf at ZW#OTdX9Fs^5>k40yrUN
zh_bgTrO3EpCO9sLfU!^<zx7>5MUDV1wTl+x579o5_0L%A6Br*6n3P%Q0uF)?@WElT
zC-BG2yv7wFqeO^=TuJNE`Ye#}CY%J$00Y1H<xlz3GYw}KRX_Ap#3|}XdZob~6`M{~
z7u?+pT*xJCd*62YLtM(SPzoy|$^ndMjOY<=0`v@??*c9YLCAGje&@YTV3z-@*5BwL
zc3RlUoKxcb6F7INvlD>8p#3b`HH;Ax91GpRMG=w!T0!gO{TZOEsp)Nd=+Hsdu3bCq
zIH9vqx9~Y23=9C>jg5`L*57XhkZ}{G!UUx3)jkPW$FYVBfzJoVQl$Vv)8n@;sN1n7
zRJY+U&8Od^wY8Pan>P;wmjQO}+(~_XJ^lUt09reQORD59WTcN4Lr8mBC2qtS?6V(r
zb=ZUPv at 9JN0YPbhdgJl!>zhyWIKY-ITd1$E$6AY0itg at idV70wi)wFQt(N5#aF5m_
zHj*`#@?=d%GCY1z*UnqXsh0P;r+r at CgC#yfPbex^b5i4^?c^KwNH!bL+uJL>y}k7G
z^e{X;tN=%8n6pC7uURa0UW}4xLQsyuV)<P851J~{OZMoa$BxK>eaFwA?K)asR;lLX
zrodRd!U<AaSWd$DobGI60MMfb>6J{8%!1YG{#zEv6K;g6Xj1TE;M;)G#LP>JtA72m
ztK)mcTC0ZpF at M~%rtsA8_80T>)odB{K;H*{5UyObt(V)`H`GtFwfK(9_;`wW(LAPW
z2Ng*OkvLfKah;gCZ|Yz7PR?Jx4cH~4CaJLm&o`}|^X{c*x4WKHDn at 242w->svV)fF
z5LlD50|<HGMFlquMtnjlYL-oY@<>hTx*fn at fR-G903l;d=)mdUEjn;^^P>a7<!M at h
z8eI?*K#(1=32Q-V&>@SJ0AnHU7MP_~zdbsw`2JnMbHMw66>G1tNe{^Tu>0_g#+FCc
zw_JH;$xv`5C4h*GxrP=q8W(nwwj#akqxlmz9xaN`+zm7UCvtcFdVt)O%NT3QPG0=`
zyu<C!toX36Y387RIc=@cBa<vP63X|>5_7w1O22cuGV_Hu1-%z|4QRjS58?&@xfccs
z2eVzb^bL2+%9_53U}Jz1M1^!b8*__0JSX`Ua1dw#{OgnacL3h*X|FQPz?=X8002ov
JPDHLkV1k37QX&8V
diff --git a/plugins/kimchi/ui/images/theme-default/icon-qcow2.png b/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
deleted file mode 100644
index a5220093e8143db08887f31decf8af059d654ba7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4684
zcmV-S60_}zP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000U_X+uL$Nkc;*
zP;zf(X>4Tx0C?J+Q)g6D=@vcr-t<CCh=7z!Z&DQqAW}k$fE1A?Dj^9FN{At$*%eX2
z5k*A=8_1xD1CEY>j1^HV42lZa2jn55j)S9!ipu-pd!uXCy!YnK{<YUW=dAOcv(E>>
z2n?1;Gf_2w45>mM5#WQz#Kz&|E<k|_Bya!_2(x4%bNwR$0Qi19JS!r=2fhFSc+(3A
z0KiR~z%U$#{}1XynOp&YgaN>GkvK~TfD`~gdX7S-06<0ofSs5oQvjd at 0AR~wV&ec%
zEdXFAf9BHwfSvf6djSAjlpz%XppgI|6J>}*0BAb^tj|`8MF3bZ02F3R#5n-iEdVe{
zS7t~6u(trf&JYW-00;~KFj0twDF6g}0AR=?BX|IWnE(_<@>e|ZE3OddDgXd at nX){&
zBsoQaTL>+22Uk}v9w^R97b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&JM25
z&Nhy=4qq+mzXtyzVq)X|<<F~dKmY*YbbitPEHASffI9|&ZT_Mq?gVIF3!ruPi)OM9
zK(zp%>DpKGaQJ>aJVl|9x!Kv}<mA{nwP%2$2<XTo2=SN&}Hemwm5_29nZB!Mzr
zfky=R;KI!GOr;#pk_m)j+~$u*{I?7L{2kLG#7SbgSSl3bQ4(>EM4F8AGNmGkLXs)P
zCDQ+7;@>R$13uq10I+I40eg`xs9j?N_Dd%aSaiVR_W%I$yKlkNC<p_9XoKO;cmMA{
z{YRiB0Dxvml5qe4UPL4=RLZkI#|QubM4*8xut6L2!5A#S1{}c!+`$X{U^aw8B*el(
z5JC!MfE;pQDXfA*D2C0j9V%ci)Ic3Hz)@(1lW-0$!d18qJ#Y{DVF;eVD7=9Q1VP9M
z6Ja6Rhyh}XSR;-I7nz0lA;Cxl5{o1t$%qtDB1 at 4qNHJ21R3KGI9r8VL0y&3VM!JzZ
z$N(~e{D!<oF_eL_Q9aZQwL`h6HyVUSq6^SubTOKb7NDEZa<m#fj5eX?(5q+<+K)a%
z$1uR?7zZ=NY%ngy!$Pq*ED4ii%dsM?46DW(uvV-CyNUH<&#`v|5`jg)2{r_GLLgxt
zK}c9kSWehTs3069G!fbfHwgoTQNkx8lc-CyCb|*%#28{SF^5=4EF;zuj}tEtdx%5C
zHzX2?Loz41kOE1uq*T%p(niv5QX}asshc!N8Y7d*+GK082RW21AS=j)<elWh<TK<O
z<RS7~3Y}s=aisWD;wVzeYDyX95al%G24$EsK~<xgQr)PbR1r0gT0*U%wo<QAho}=Y
zb(%TNgBD3krLCfs(;8?OX!mKa=ybXf-IX3rm(W+z%jrkxm*@lZcMJ`N6@$l!XDAt)
z7zY?<8Fv`3m`tV_(~B9$R4_L&>zL=651DUOSSq$Ed=-((3YAKgCY2j1FI1_jrmEhm
z3sv(~%T$l4UQ>OpMpZLY<EaVMmaA2&olxsj8&hYgJE(`MXQ*#fKcs$H{fP!y!%V|Z
zL!?olv0vl7#vlu08MAmSA!`k*hIN58#3r%L*?e{?yO{kQyNf-lsi8STGfFd8vr_Yv
zW<Lkxm~r@=bWRE9D5sb6eu~}{?<wLb8>Tc&xiMv2YpRx)mRPGut5K^*>%BIv?Wdil
zy+ylO`+*KY$4Vz$Cr4+G&IO(4Q`uA9rwXSQO+7mGt}d!;r5mBUM0dY#r|y`ZzFvTy
zOmC;&dA;ZQ9DOhSRQ+xGr}ak+SO&8UBnI0I&KNw!HF0k|9WTe*@liuv!$3o&VU=N*
z;e?U7(LAHoMvX=fjA_PP<0Rv4#%;!<CI%)UCQD7~P41dfO}VBiraMeKOvla4&7#fL
znKhd|G1oHZo9CO?o8Px!T6kJ4wy3taWl6H+TBcd<w!ChIS~*#zSXEkGvqr6*ttHmG
zt-GfYr at 2m(POF~QXTz}Zw#l}sw;8bI*aq9Kwr#e3VP|3&XSc<!!|s#4lYP2<jr~0b
z4Tsqds~uV$esi>P6gpNq-kQ#w?mvCS^p@!_XIRe=&)75LwiC-K#A%&Vo6|>U7iYP1
zgY$@siA#dZE|)$on;XX6$i3uBboFsv;d;{botv|p!tJQrukJSPY3_&IpUgC$DV|v~
zbI`-cL*P;6(LW2Hl`w1HtbR{JPl0E(=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$
z-ZI`<U(7eax5&54Ps4AXUxnX8e<S~7|9bz?0H=T at 0cQh=fkA;=0{i%Sd?CM%KRVlG
z_OjXSL5!feK@~xdf~|t(!L1=^$n21<A@}E)&XLY(4uw#D=+ at 8&Vdi0r!+s1Wg@=V#
zhChyQh*%oYF_$%W(cD9G-$eREmPFp0XE9GXuPsV7Dn6<%YCPIEx-_~!#x7=A%+*+(
zSV?S4962s3t~PFLzTf=q^M~S{;tS(@7nm=|U2u7!&cgJCrxvL$5-d8FKum~EIF#@~
z5Gtq^j3x3DcO{MrdBPpSXCg1rHqnUKLtH8zPVz`9O?r~-k-Rl|B*inOEaka`C#jIU
zObtxkn>wBrnsy*<GCexIF at utkka0q)Ax)FEXX<C>W_HW0Wrec-#cqqYFCLW#$!oKa
ztOZ#u3bsO~=u}!L*D43HXJuDrzs-rtIhL!QE6wf9v&!3$H=OUE|LqdO65*1zrG`sa
zEge|qy{u|EvOIBl+X~|q1uKSD2CO`|inc0k)laMKSC_7Sy(W51Yk^+D%7VeQ0c-0E
zRSM;Wee2xU?Ojh;FInHUVfu!h8$K0 at imnvf7nc=(*eKk1<r{}@%D<W1l(ea<#JOb8
zX3}Qq=H4xyTMm}0m*$raZVlPmv<=@@wC(lwMcXfz%_!TugSJDtqrW`3yk)1!&dobN
zRHRh&RQgml?$X`0Vb}O>(e4|2y!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu8FGY
z_?G)^U9C=SaqY(g(gXbmBM!FLxzyDi(mhmCkJc;eM-ImyzW$x>cP$Mz4ONYt#^NJz
zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{
zoHRUHc}nwC$!Xf at g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR
z&Rp`ibn>#><r7!9SDLRnUv27i>OB6F(@)2{oV%K?xm;_x?s~noduI3P8=g1L-SoYA
z at fQEq)t)&$-M#aAZ}-Lb_1_lVesU-M&da;mcPH+xyidGe^g!)F*+boj)jwPQ+}Q8j
ze`>&Yp!3n(NB0JWgU|kv^^Xrj1&^7J%Z3ex>z+71IXU7#a{cN2r$f(V&nBK1{-XZN
zt``<Be)!ev*Ur(H(V>^}my^G3e5L*B!0Q>W+s4Ai9=^$VGcjKDR{QP2cieX!@1x%j
zPvm?ce<=TG`LXp=(5L&88IzO$1Ou4!{1CdwXaE2J24YJ`L;(K){{a7>y{D4^000Sa
zNLh0L01FcU01FcV0GgZ_00007bV*G`2i*w^2nIR7DLxkf00)RkL_t(o!|j-Ra8y?v
z$3N%ZeQ%zd4M_-TNKzAE1C){kLBXjMQ0#~>tzbr|NU61z4rSW<8pl!VAIb<b)>16*
z>EI}eMW at q31C)YOX;KJz(hw4pAdfsY at 9g{D;~%>TDcMXC4DCNXGyBJ$d+xoT^ZR{&
zk8|O(@&64Gb#g~(8n6Y(1Z;p4umXKRXp$K`KrOIaZYydY6Hx3Z6+ks`svyPI5 at S^T
zPOG6S-lY0EeOgRNm&#<C#~ad(CtG at RfYm^*+*TxqFEK>9Z7SdhZ7m4ulI;T_op_Tv
z$wre%1ib+byFo!!#4GB~G7B&bxHf#{kTq5xsZbw2R5~NZD6)Z84K^=5T1Wb;7kT|k
z*Q6`!z(;P<UoB_F-|Em{g#>qwO%yIad@(61V7*VZc3SKW{XrQ3e7=yRqRqpAN8|MM
z{z(`Ah1LNEd?CtPJ at f=MDL^)OWaCZUq(yac^@jX at 0K?8wLr5Zx0?OCBxY*(4Yxl(x
z(DX?K+`cHChce<QOtumugcyv6s`dHZqXtRZuCk}ye)&>Bm+>ZpqKHo at l}L#U>bkV6
ze2^JqSXZ-Ye#;2J*q6(e^apuQN}ceAKG`8<ICxB|@<w25;hGT|><eH6$)~^;wv-6}
z0#aC`YETG3hHa_}`1!(gHoBZxRE1*=T|9TDh5n#^??EFNBP=-F;aldVu+in at nbXZY
z_U2U{oML19l8i|O`Bt8Tn@>J~`}^~Fu^@HSb%s0gCkWV_pUe->UE`k(;edMbWE1bN
zoynGWTljpMo&C$RNU<4tt*V_D&R%1V)5 at M@)5&+*sP6Evxul884lfn!UA$iFru5bT
zXTCXuFZ}s3E3 at KRoF2<ehlO9Bzd>!Mms5|<U|)3yZeMT&U{niEk2h26_6<#c)ak>h
zDonK-dF9KQ{PjvFOO9M-RZaq*OE9x{Sr)Z!A2SbDQS0{c+Op{Yywlvv!l^M7rP}HB
zYZRv1S&(YyL~{=-k6mG3bvr>_(ihO^3u;j<7`3i8_4t|TumG?&*TGYBrXZ!H%@ZUy
z!NNZpx~XXQl6#<v`ffiir<MIR?X>g-I8f8UY^M!?lI9*3rp2%z&CdRsc8XH%6sFpF
zr at 4m<tsYk8Byw<h7AyW<M?jO~0F12JQ{B#Q7H9BCb^;61>}+3>!HMQxe43=O$It5f
z6PcTArS|cBvg6Ivba?r$E1COZO>A^Isp{|maPE3PiDs3h8FB2YXyfbI350aG*y`cg
zc`5wvOBrk`Y2xNU5W^^0*AUIcFPFEHWHGRNX(sVzmE%o4<R+LgtAb}vH?wbf7EjNe
z!XGZR(%9qYiIV at YcUcyfzcZWa4i8V1Gy&iZ>72XXN3zYx)owrCevN<K=tBa}&rfA)
zjEQ$2n*qSggH_aZc}MRD#g4MCAm!T#8MRGJG^=#^wR at eeL8!;&a|K@=;bJKflF_sD
zy@!in$Wb&HXTqx}a;W5d8nsS>Fe|z at ss>j~QLE2)YMa`8eA};6 at K8pKO+gHGssUZ%
z_JuI20x2P=>Gb$D`hz;z31;GqD#l?#9|-BxclmI8f}n`o6+)LR&WOV_xK at B)(>?Fs
z7|?7gM`p(>2hNYy&8+-WS;~7Iq<cbgUubJVju0Yt_=3#c<y`9xfI$HvaafFeus)w3
zoND5DT_=w}n2Il;@o-i=n`Sr=LU7{0eXM<>o}OU%D3fe6(e~5>cPg)5-B~t}ZR5x3
z3HFk+>s(sYH1k$*VXG%3^%3k5VXSdEkwyg>)L5D2;7su>Rv)e7czq|rsBozK7JsQ}
zXY*SP{QARNVb4s9rRjTf`RT%R&?IZ}93Ok;@X_eu)^NDd&LkhNdqbTBY at Fp}*M(M|
zU7SI2o`d=OD+vHX4ewJJZtwSJXIcnI_(f3~2_}`77N)bom5fP*BVoKPoidT|nv-PZ
z{Q7+23<?E at stJTcKYDX#Q25o^7S_GpFm!)zoQdhNrU~_%;|3H$Af;qpl7&lc9`ukt
ztVbK!+zBZWs=|>PH;=yAaMy?F37v5VA&)+i!wX-WhAJg8GAHj4$KZcefjp-bgAjL>
zybKfk=r9EN+ePUV=Q`Ma;TFfPbmHj`+}6E-m{=35avl6=ek%D%*09^}qFo<fkVJt*
z!rUYahgW3bUp}3y-2p1y9)y574lDO3m@!2*Gd$2H5pe9 at To48|3xO-qj4RPRvb2sL
zECd)Qs6iRMK#r}1F|XZzrW|~Y7qCnKP!I at 7$~t}bto)X_y?8@%a3cZ0G;Tnzu9La1
zlA=Fe;>Ca8oOHOKoWDWQo(gjJR?-{NiMTg79zX at qRUw4aYCxD3Qf!7Xg)my0ks}*+
z032om!mQ%78ZatC0QQKR#|)A#Ala;llcmM8zR~U1m})mh1=AzD5qAKHQO>!;=bxXK
zLUEo0hgn6DvL09jG>-QJW~EUPA8yEZ22$-tzmzZ#)J%R&8iv1gG%$GwoQPt<!RrBC
z%EPrC!WWWxa$C{j at qPkM1~vc%k<Y(_QFbpPMn)|6d%3OXCZCN-9{&S%4huE#v8l}f
O0000<MNUMnLSTX?tJj49
diff --git a/plugins/kimchi/ui/images/theme-default/icon-raw.png b/plugins/kimchi/ui/images/theme-default/icon-raw.png
deleted file mode 100644
index b5def8f3dddd81a3a570f3acbd3b206684275cbf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4679
zcmV-N61eS&P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000U_X+uL$Nkc;*
zP;zf(X>4Tx0C?J+Q)g6D=@vcr-t<CCh=7z!Z&DQqAW}k$fE1A?Dj^9FN{At$*%eX2
z5k*A=8_1xD1CEY>j1^HV42lZa2jn55j)S9!ipu-pd!uXCy!YnK{<YUW=dAOcv(E>>
z2n?1;Gf_2w45>mM5#WQz#Kz&|E<k|_Bya!_2(x4%bNwR$0Qi19JS!r=2fhFSc+(3A
z0KiR~z%U$#{}1XynOp&YgaN>GkvK~TfD`~gdX7S-06<0ofSs5oQvjd at 0AR~wV&ec%
zEdXFAf9BHwfSvf6djSAjlpz%XppgI|6J>}*0BAb^tj|`8MF3bZ02F3R#5n-iEdVe{
zS7t~6u(trf&JYW-00;~KFj0twDF6g}0AR=?BX|IWnE(_<@>e|ZE3OddDgXd at nX){&
zBsoQaTL>+22Uk}v9w^R97b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&JM25
z&Nhy=4qq+mzXtyzVq)X|<<F~dKmY*YbbitPEHASffI9|&ZT_Mq?gVIF3!ruPi)OM9
zK(zp%>DpKGaQJ>aJVl|9x!Kv}<mA{nwP%2$2<XTo2=SN&}Hemwm5_29nZB!Mzr
zfky=R;KI!GOr;#pk_m)j+~$u*{I?7L{2kLG#7SbgSSl3bQ4(>EM4F8AGNmGkLXs)P
zCDQ+7;@>R$13uq10I+I40eg`xs9j?N_Dd%aSaiVR_W%I$yKlkNC<p_9XoKO;cmMA{
z{YRiB0Dxvml5qe4UPL4=RLZkI#|QubM4*8xut6L2!5A#S1{}c!+`$X{U^aw8B*el(
z5JC!MfE;pQDXfA*D2C0j9V%ci)Ic3Hz)@(1lW-0$!d18qJ#Y{DVF;eVD7=9Q1VP9M
z6Ja6Rhyh}XSR;-I7nz0lA;Cxl5{o1t$%qtDB1 at 4qNHJ21R3KGI9r8VL0y&3VM!JzZ
z$N(~e{D!<oF_eL_Q9aZQwL`h6HyVUSq6^SubTOKb7NDEZa<m#fj5eX?(5q+<+K)a%
z$1uR?7zZ=NY%ngy!$Pq*ED4ii%dsM?46DW(uvV-CyNUH<&#`v|5`jg)2{r_GLLgxt
zK}c9kSWehTs3069G!fbfHwgoTQNkx8lc-CyCb|*%#28{SF^5=4EF;zuj}tEtdx%5C
zHzX2?Loz41kOE1uq*T%p(niv5QX}asshc!N8Y7d*+GK082RW21AS=j)<elWh<TK<O
z<RS7~3Y}s=aisWD;wVzeYDyX95al%G24$EsK~<xgQr)PbR1r0gT0*U%wo<QAho}=Y
zb(%TNgBD3krLCfs(;8?OX!mKa=ybXf-IX3rm(W+z%jrkxm*@lZcMJ`N6@$l!XDAt)
z7zY?<8Fv`3m`tV_(~B9$R4_L&>zL=651DUOSSq$Ed=-((3YAKgCY2j1FI1_jrmEhm
z3sv(~%T$l4UQ>OpMpZLY<EaVMmaA2&olxsj8&hYgJE(`MXQ*#fKcs$H{fP!y!%V|Z
zL!?olv0vl7#vlu08MAmSA!`k*hIN58#3r%L*?e{?yO{kQyNf-lsi8STGfFd8vr_Yv
zW<Lkxm~r@=bWRE9D5sb6eu~}{?<wLb8>Tc&xiMv2YpRx)mRPGut5K^*>%BIv?Wdil
zy+ylO`+*KY$4Vz$Cr4+G&IO(4Q`uA9rwXSQO+7mGt}d!;r5mBUM0dY#r|y`ZzFvTy
zOmC;&dA;ZQ9DOhSRQ+xGr}ak+SO&8UBnI0I&KNw!HF0k|9WTe*@liuv!$3o&VU=N*
z;e?U7(LAHoMvX=fjA_PP<0Rv4#%;!<CI%)UCQD7~P41dfO}VBiraMeKOvla4&7#fL
znKhd|G1oHZo9CO?o8Px!T6kJ4wy3taWl6H+TBcd<w!ChIS~*#zSXEkGvqr6*ttHmG
zt-GfYr at 2m(POF~QXTz}Zw#l}sw;8bI*aq9Kwr#e3VP|3&XSc<!!|s#4lYP2<jr~0b
z4Tsqds~uV$esi>P6gpNq-kQ#w?mvCS^p@!_XIRe=&)75LwiC-K#A%&Vo6|>U7iYP1
zgY$@siA#dZE|)$on;XX6$i3uBboFsv;d;{botv|p!tJQrukJSPY3_&IpUgC$DV|v~
zbI`-cL*P;6(LW2Hl`w1HtbR{JPl0E(=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$
z-ZI`<U(7eax5&54Ps4AXUxnX8e<S~7|9bz?0H=T at 0cQh=fkA;=0{i%Sd?CM%KRVlG
z_OjXSL5!feK@~xdf~|t(!L1=^$n21<A@}E)&XLY(4uw#D=+ at 8&Vdi0r!+s1Wg@=V#
zhChyQh*%oYF_$%W(cD9G-$eREmPFp0XE9GXuPsV7Dn6<%YCPIEx-_~!#x7=A%+*+(
zSV?S4962s3t~PFLzTf=q^M~S{;tS(@7nm=|U2u7!&cgJCrxvL$5-d8FKum~EIF#@~
z5Gtq^j3x3DcO{MrdBPpSXCg1rHqnUKLtH8zPVz`9O?r~-k-Rl|B*inOEaka`C#jIU
zObtxkn>wBrnsy*<GCexIF at utkka0q)Ax)FEXX<C>W_HW0Wrec-#cqqYFCLW#$!oKa
ztOZ#u3bsO~=u}!L*D43HXJuDrzs-rtIhL!QE6wf9v&!3$H=OUE|LqdO65*1zrG`sa
zEge|qy{u|EvOIBl+X~|q1uKSD2CO`|inc0k)laMKSC_7Sy(W51Yk^+D%7VeQ0c-0E
zRSM;Wee2xU?Ojh;FInHUVfu!h8$K0 at imnvf7nc=(*eKk1<r{}@%D<W1l(ea<#JOb8
zX3}Qq=H4xyTMm}0m*$raZVlPmv<=@@wC(lwMcXfz%_!TugSJDtqrW`3yk)1!&dobN
zRHRh&RQgml?$X`0Vb}O>(e4|2y!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu8FGY
z_?G)^U9C=SaqY(g(gXbmBM!FLxzyDi(mhmCkJc;eM-ImyzW$x>cP$Mz4ONYt#^NJz
zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{
zoHRUHc}nwC$!Xf at g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR
z&Rp`ibn>#><r7!9SDLRnUv27i>OB6F(@)2{oV%K?xm;_x?s~noduI3P8=g1L-SoYA
z at fQEq)t)&$-M#aAZ}-Lb_1_lVesU-M&da;mcPH+xyidGe^g!)F*+boj)jwPQ+}Q8j
ze`>&Yp!3n(NB0JWgU|kv^^Xrj1&^7J%Z3ex>z+71IXU7#a{cN2r$f(V&nBK1{-XZN
zt``<Be)!ev*Ur(H(V>^}my^G3e5L*B!0Q>W+s4Ai9=^$VGcjKDR{QP2cieX!@1x%j
zPvm?ce<=TG`LXp=(5L&88IzO$1Ou4!{1CdwXaE2J24YJ`L;(K){{a7>y{D4^000Sa
zNLh0L01FcU01FcV0GgZ_00007bV*G`2i*w^2n8EKWGpZM00)CfL_t(o!|j-9Y*g13
z$A9;|nKz!r+jzWyaSRyjfDMLtX+fn)lqiU_RRT#9WCgmQC~cKiK=(%dfJjuSD4}YV
zgsMpcqEsphO{6B26sTC##@K*^mlVesfel`W$IIBW&wIBYW;`A*gKcWkFF9YH=Ds`k
z{m=QI|GDR0_}u<C6H^YpQa2CyK2QkQ02g2dhJnZ&WAFhV1N-F8>g&@26tC0?pcyz>
znQQBCnAM=mY8pt_)IfhgcSH=S%w>4|5yO0<!&3xo1d8R(YMD62G{xWM1J20y%CI5X
z<Bb at kYw8>aO(GF^LOOPnf~tsD)xGs8zyhE%ab`Rk8xLPnA3jibufr at B1HC#t`_PeA
z@?XEm!A}O}JhR at q>?Z&92G+mbiVo`~xQlF}>XAbiv!(>t7ErDIDfae}unYl#Ktyus
zmJhE_=btx6<~;c?^m_3IA~f{+7z*oBfNb~4tKEjCPf2m}*0K=*)80B$L?X=s8n%>j
zvCq#}?nx!28*>V9&)R$*EJ&j&+loU7F{+2AEoFmAMKbTT`tP}e^2LxL(>0T#h|j2$
zNQn#^hP11kD|DDPw`{BEm;^BOclBQ$33FOXgQ!EFtw|XbkESZ`gtk|0nndw%2%8X+
zQEbMJs!5A9_4#<}y>?m$0^`OTo++g~+s04NcCzPuPkj9S$Ct8UQ3i!?T%vP0#CKQb
z at ajW_{Hm^t7yfk<O%;qhU%`L+{gfYU0U#uWbxM&40m$)y-2Mo=KD^29+AdCYdRXDI
zv1?8KxH-j{DU at g10C;j~=D2q!Iy?YW<V4@!mm7Un<=O!#&9Y)r1ShV0k``vu?aFqa
zKg_P$E&y_ECc2+n&BAnT+?=P1qo6ML`>D!vP?)B1-4g=fc<jR!xpv-dAEYA3PJPb^
zl`(*;Vve2c^dzNTnNUBI+Gv#iaee$^PZwv==MS?x=ExIE#-iBl_S54HQ;};&Qw3!%
zEBhKhB_qW|QM!fIIW{7O<jjrX83LRT!4jtxV at DOnjw+6AD&bV8hnLQE#osT_N}<$c
z<^8Ke9KAM#Zb-gf?3_UJ5EVH#R=A>c{`JZLZhwTTJUgqhZJg^KVI*wK5a0y6HWXyp
z{w9_mXyS*bJ9wZVjlK8ZlR$42%-^mKG8EJ~dvlmC%yUqXI+g~<uY1V0nR%=zlPiM(
zhJrfhd%aZW*(uMq#q%_onI=)35XGQw#1-2%5a8we at 8OH{90~MB0lxjUCF7QPVreG7
zx!5~SDBmu1arS1E%JaQmzFF!bRa0-9f74Q&XnHI^EoyYqN|%)qr<DUOeJtDG#IpTO
zlpky+7%|4Fx!W72rO(fNhsK3o9{}~eUh*9p-muQOZtpAr%IOR0==L&7 at 1HKaX&ngA
zIuM|#&(Dbt4{PVAlJ78&(cCc<-G6UI!JO}jKF{13CTz$VHmon#Zvc)8Vcb5HcX>aN
zs2{Mia>JwurfK*UMaH+B|Hob at L0A;SKcz_4=cvuK{ra|B0iFpOR6bbXuqlXmry4RO
z?mz^yDv%Pwy1`ITXC!Q}IKx7kS;d^tUU(x0Z36+^zAz|)_(o+&))l0ojm{Mi)D7Ri
zyS%zh<?xDh<*nLevUv2*^|`0}$oEC$o0096MM8+w#0iD_8tC+dz@&hXI8)4=+fv5!
zC$Dj=wV!X?mq#F^^YEf{w%zMQ2*C$8hI#s(Hip8{qfE9<<JNapO-%hZb#J|Qv5lYS
zXV{OQ*<7kmDUzc#RlUB5G$vt>^3JAG7t*XC!#a;Ha&oF>IUA3(a;&W%VOBWM(8FI^
zKIPe??YtCg8rCmJ<=S)Qys#!8bjhX?=eRW!?W&KSL~zN at B$JC`ti}1(au=^%=;a6N
z3aBY at Qt`(|LV!@CehSl=zrQ at yK}f=`>Um^nDle|dXKQITnutnarY)T^8-1<JvQoRH
zj5L!%<$-2GQX*uM=FX(B`%DL$|K1+|e{q_|!c=Wm{pO4T3L%hEvN|h;k8b%eBF5A`
zS}fv1N`$I#xW&zr at 3r6YVR}|)+)<E6zFNeOzq9~VN at Q$IPDqZ?->L#7E-NM>?x=W~
zW_jrl2l?x@`P39U*>j<XcR%UJHxe4ldjXDAjmL_e{H!96vMg(q_B%LA%uFOxfJ8!h
zRtksKFCzHJLaq#kXmtA!0#-V$EXlB-#hghL+8hF${@Owi1!@t3(o74bnU+aD&O#6o
zz&y(wlyL>lG83kKH at 2o6{fr+-nFT;WC?cuv58Sowx8Ci?ACaSugaB>E0R4tR;hT+A
z|NbL>@?rO!gZo8o7uA2bMDZJqcp?Tddc!jTr~rm4gm76+2#Z3l%`|NyBr7vANxSK^
zm=G2fm(_$>5dyHsXr5Li13<P#5hv<umOnli)R}KLPYKM3c_StO5EIgHs_`GK&ZVZr
ziPNH at NZAIg1+LEY0<+Pqi1S;^T%kO>IVdG~!@3sKr77{F$$-fT;6##!T}0bBdFbOl
z5s1hVxwCrROs{~mfvrGg?D}_9Wp_g{G8Vbt%AM8Sd~S1W{{`>T2W#;P>wo|N002ov
JPDHLkV1mo3<ud>P
diff --git a/plugins/kimchi/ui/images/theme-default/icon-remote.png b/plugins/kimchi/ui/images/theme-default/icon-remote.png
deleted file mode 100644
index e316dc0701db28b51db92b5e6e6985f3b82b25e9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1005
zcmV<J0}}j+P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000BDNkl<ZSVxuC
zkM$Ep5C?FmK&Zf at 0<Z$l3WN#>6^IoWD-bF$Rv=bjr~s(IPytwh&gb4t+~2yJgn4gX
z_U7i#cjw>b{=F}wr=k9R at DltW_(__-kKfP1r{Fiif86T!{tb$P{S+*?ptle(fc%)i
zrZ(3A?8EYhCh&)Jd`!n~j${J3HGw`(IUuisf1V+j0pRS<bj<d*U|>$STt9S{)PJ7(
zfPR;t at 3<HNa2vsa_?S1Uo8B1ztR^Fe;IA_{5O;j_00jLjgG=|zJXe!R>6en;`8EBp
zf7E881<<Gcl#w3B?=iuYtOrr at rFr4}E(5pvF7r(ZS^)bH>h_+b4FIL_UPB3ZDI06N
zck32V>z5Dl?iGL;S~`Lqg3Y!YA<v@`lSO6YT=$!x5uHm>0646Uo!D$ySQCgdn?4Im
z$nfq4e<o{J066+8SmV_U&w!lMH&FmUBby)@;aB#YzYTtyzhXWFK$rfW!ELWmA5^Rj
z^$c0a*I*;8$pi$3zF<Ik|19l2KLg+pEd6Q<z%kg|_T)wy at lx{%x=(xhHO7FD`;M?b
zrLWfj2q-nx?Q4Pp;_qN%!+_pl0IU at W_)8;jA;gw{09twrfB@<)ZO(`zEbyALC7(MV
z=SS~Hb6*Nod(Xfq)q4Q`NsWFh?nACLY9_UndZ0#Spns`<*jZ|t@=TWiP*U?<@G-d3
z+1j_~YXIo#3qa_~z_y601klYI%%l_`y<r-FY6;j{R5OtL8{<Rpr{E8xCY%|sg*p{v
zq(-W200l(JoJZ62I^=9+U~58X)cV?jDZLipi?kns7Nqa`+9NeB+ZaM>5h=y_D>d*q
z0zmB)EVaFD`E6ZQnXByEB0?PK&PVBRbfYDNw%3TP+Uk>fzs6x}w1$8biyu4YK>;|#
zgECxOwWGB1-;Xfa2!Q$D2U~nwtTNOzr(jvAjX1n&2y1WDdkaRep7_-1MVjvztlVzD
z1b=RkLuQev4-m7FYyn99?t*UB8VKJS{|^K{H+-MEGJq6_p4JdlUERVnn;8M;pOMcz
z;6~Kh??yd<wiKgGltZ>|^y)%zuWBE-xuECN&j659JO=BBQ?Ob0jP}9GWC3Z&YqW-f
zuVV%Gd?#b0?&TD6LF?bqA<nfz^+rE(J&+}V?(&7S3;w^pngJ+>Zft9{UogPPIW30(
z11kt{RbwevCi+9V27nRgoN#>SQ#x}Ra)Ffy_}MgV=C=T7;{bt|1Xd-gY^d)sgI~b+
b->ZKC*A4Oh7Gf$=00000NkvXXu0mjfz>VSq
diff --git a/plugins/kimchi/ui/images/theme-default/icon-reset.png b/plugins/kimchi/ui/images/theme-default/icon-reset.png
deleted file mode 100644
index eae8449a556d68a44c28144727f7bb3c5d2fc13c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4576
zcmV<65g+b}P)<h;3K|Lk000e1NJLTq0012T000^Y1^@s6OO{u+00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000LINkl<Zc-ov+X>3&275?sh%e<MfXYuofZN|oUVX*_0eGw^OnTA9$p(zqZgfvB>
zs6wq8QKTXyn_onrN|D>NN|n$Cktj`xL4mL&ZNQB%0z`?cK)~2wmV%dA8PD>Td-}s;
zXKV$Ea-^&GboJi(biVVQh2iOq17HATSyA1La|ZwrkzreAoP<a}tt0s<zheLt05a#2
z)01C3Nmf)p7~{gW<H>mR{%|BX1b_h8ndcLo{Xdfc<fxj<Us63|kteUHG1p%(N0OC1
z0E~#z>BR8OXz;;5hVJ$r4?eil1Hj1mrtb;Lq>8$EtBNYBcRO4;3mD_-h${jZ1Hixl
zFvejSslHJE-9PvI``p{9M11gZz|s?FcL1;eki%OzV{+AuU)q-KU|;}a5E*Zbv5^A+
zT=KcS`pUvU)lAb!Ux-JBLXV?vqF5XNa`e*jy0V&CuLY)5-d@|V^g>7H1<7AjvVw@<
zb~*19<oUaNo}6yRcr<O8xwa50=NyaylB`zilP1qI(#g~D at L=q5^l|_aW6Yi7%dZT~
znA7AdEZr<AT6vz={aX9m`wo13{Iq`T?4>uC&a3ZzVdb(5nnMWzEN$C1zjCcxKXl~O
zx@$eRH>$GY;+z2tFj9&4yUrZj^e8k)*)%f%8UUV~S6EeCS-YkvQ2mM|Dbs1B9H8sI
z_uBvT#!msL06YMk0O9}=07S-z6i+1OLq|?E{Qblif3Pg82mmBmF$em(H~r^dpME%A
zC8`#vsGGaFux#o&)#;v1whhJ^7~=qA;GEt3?Y7MeRxO(!$zn!)N2*i+#&a9DHKl~~
z0b_6yfOOh8{lcQ@>vWH6cuX*p%cnT2XDxg+6bx4q32<2&0nAuDk(_+)a##JTW%E0}
zONqf?aP-yCbsaY at bsR04zVIW>o%0GK0TN<)dCkoFjZKZ`$Aok1#?_v-me*HrSoi!d
zIG3(u17f5U9K(s!GRv~Y-Jdyg20M1_Kz at Gy*lBHTMJ)ILx4JqH%Zi)^0Egz#j-EQR
z*fcGcT^e++=lb19Z`WI9D&bXK?%AM`d<r6{vV^YdJ&Ug1ysbPlt;!tzv8kyEu~;ly
z8*)oaivVC3y7g|$FzzzOsu&Rr%bF<p1k at PbQQ0$L;Ou);)WCmTAr;A_yVicDo)_
zlubG=%W~@BU~obIP-sqeq&}Z-T;$$@;_9k7OMk?<RA{6U5i^~NeVYqb2*3q^S(XJ^
z*L9et2`)+CoacZ5+ZJ#-)c)3AZE3mDd*_`KXV0(odvl93%vb;riA1t7Npt5G1*Xq=
zH*Zq;m3VmIux*)|0w)N7B1>?niX0Ay+3MA+At#eb0AO5_ED*&3K$0X3426`w`wwG{
z%NKs$xP0N4nOYu8_^w^Muyg0mF;pX&ykZ*ZUYEz$=yc~c638SW03rbR`i;GNLnlt2
zpo<qTjyWMBN(o{00RZO=@!@1)G#2+nBcVsFt*t`<1~QEt`}glhXJ_X)dSk)<aAe at W
zmn2yN;~ZR)6vh}h=Lp9hmF(X8yVA2~J5&ICT*I%PyZq&{Y0rEFK at bFJs{EVFr#{>_
z*#8i^uA{B34coVG&n}a3Rx|(E=E=3Q4hq{IR{}x^A#7_f8VMh^276oOty{N_&|{?0
ze(dDM!1USI1?*bR0K>4iG0po4 at bH^pFvyylo1Zu*6VdQR+cLw9aXtIq7J^&0D411W
zH}B1s1C@;ETR*a*qJH`Fd-6-lciZ+zU6Qc>`SrQawhZ3w>B}?+nlLc<=-`%BO<nNZ
z`cED1+?6B<mTdzJC@(2Kzv0Ekql;$G?9lz*TT)9)%V<(DV_FRk9{S*#!&|UM)3kz&
z!lvkx0!xVKej*-?fryBRgE5D!sD78%Ut2b9*5c^EgPXQxnx5i{az%5k5JHHu;=-%V
zFE+mQ>z{3Sr at nS-hs&wm0T3A%DFAlxy}#0zU)_B6O7Fw=9GB)NB7g{jMAAqMe-R4}
zTuwZS3`vUO$noV@<aqKLWQSHU(AT~GYUgK1w!FT3VKgazzjDbB&i-Ug!*Sj3xd&hn
zz at rQ!m<T#L=0w|H{`TX8M^66H>Cg%!&Ot;V2r$L~%5W?MD6>IWmbg})=XmKr+rGYg
z1Hr)5K&b^F3Lpl+oCq+{1ORFKtLqQ{y!oX~ZkKj0Wf){w76=TKX^|ir*}@1&n>Hj_
zs`+6<V}nD}Ff~xx4WJJ|a3bL2A|36e41jvSf3WENqo-f~rl)Uh at 16UVX~XmjAymc~
zDT<uP^Lj!vYb(1Nmdrc0V)5Mb0D1uoKXL1N3}`kJDgb#X94+|jYIogmDpf9Qk;@pM
zX^vQFQNgXcn#x<5oJF#R`}YPNH$^ffqGX;dYtJ<RJoU2uzX1S0-5^Y~P;dqS0000<
KMNUMnLSTYcw5GuT
diff --git a/plugins/kimchi/ui/images/theme-default/icon-search.png b/plugins/kimchi/ui/images/theme-default/icon-search.png
deleted file mode 100644
index b38cf6cba2ae18095f990c7dd3736365d9965fe1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4197
zcmV-r5Ss6aP)<h;3K|Lk000e1NJLTq000~S001Be1^@s60ks%H00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000G$Nkl<Zc-p*|ONd+79mc<N?zs=?>gsBS8P7<#)?_?m*OpR4pn}QMi_+9?LP#JO
z;w-Xh at od}}ZvqK;lU*Q`LcH>1*DgZB5R-u0O<O25UX((}*ltpft;xe<tQn8S(%h%+
z*F}z8#ZGL+4mlunb+0(T^M8EbUlJtoV=e^%LWurnq3`7YlmHa<wV|IU0JZ?M0o(u(
z0O$c2>eM8^1`fb14ccZH#)M^AzmQTsDumdf!5xzS&9dxt5Ck7+a7Q0xD5xOWkI)1#
z3ZP=!_9IHEm!*_D4a0zx5>m>WrzD9qP5%}}(W_AuE$OJ!yFp3b1WEutfbEXs{L(bd
z*QJz>Wm)ij|Hkz6^cT5YZnM>D6|Y^pHXX;Y9mg at EC|cgy+Il_+g7W|(0NJo9wE+00
zY0jFa`I=J7aU2H+4jedp{P^*Y_U_&LC4db8?S+Mf;;B=o4sUF1?2n>oS}FC1Ua$A-
zIF4go7T&dxx;bk3eEz*ssl-a9!lOrz{)OZ#Bwr-?Fv-0n_mKSQxpU{n>-GBkwOWlk
zckbl2ZQBkH+cbUPm{RKTVzIb3F)_ipxw(r;lFXBQisTNGHc3I!Aejds%jI&dR;z8)
z>vitlz55JFpQLj)pw!ofQfkUDj8VsNP^;Dcu9Rv5I1k_}Aw(pEpb(-5AOv7sxpJko
zwY7B?08G<- at XVPr72U~qTzz0Br7S6>U|AMi*ZmKGuK=tGA<}QOwGf%srQPXtzD$w?
zQc8byb+rn>B`JpiCID_IrC=BaE?v6R18`MGbDNZOljYMi^^+ul5F)Kst2qG9z at B#m
zMkGHILWELEEH5wrObBsR2oc}1fdF6wC`l<tNj{Wi8C=(0Ycv|^FkN~x!YGO^ko=bx
z_H&bylaFg{y87e}01v<ffC<~SpOaEf2_dj+*RCbkb%oAIHViP$vTQR=)3>rLgAl^a
z<#KO(p7$t#NdVgc>;UipfU at H_zfwxgE2WUn=R5QB^Z(So+7&|ZuI8-^oeCk|@jP$8
zX_~*aZTkVw^Zq1+_#lqsf0NvlQkJEZPe>`BFijJV<KWPtLyL_@;{t$-05*pbqt=*7
zGPk(6IM!%1{#dWqIXgScN~OZl(NX%o&tkF2QmMqTu`yPw)#TW*V{eh%uG8&mKNiDy
zDM<Dkq5!}@a^%PhOG`_KTdmfvFbqYKBp?aPvf|m<*$W2`9{l~ulP52d{7t9RN!so9
zLJ$O>0O)?#$od9Q-{?bq0FyxwlouBlAG&<`@=O#(Ub$S3_U+rZGB-DOdS+&3Tq*T#
z5Cm2jhDeg+Vh{w+gkiY+T}FNzZ~&?R<n_23)9-oRWS<Km&R46|(^;17CkZJfNFofw
z#a65J63I}HtL#n#xbGwckdWNe!}W@;k<uG%0Pwrr?hV_vk<aI0Syn&Y&yxIWtJPZ2
z-{q~Ty)D8am+AZd&r7A!pFPhjDE0NZ(=<i5+g)E at Uw^XQZhxX3toLo^J at nEY&33ze
zmgH-L&kVzW<2a**Lg7uzvI^RB<+lkR_X1v7SveWU at rPNK^~(X%G~v4LV<RIYztb`?
z2Bq at 7fx5>1G$osxn at 7_$z1sh|DW!yM+i+d?_{hk}!?#9xPZ9Q^B-QHb>g8^?`*N?>
z`+wS`gyT3l&-30a6bd5)#((cA)lia@&1Uo6Fbv<mHMO~1u3jt_=e3I&_XX?^Ze7pb
z_3PJPNs{E#erkmfuq+GX<Ks^Qn9&Y)f53ry8f$B7t!}q_Bu&$7uxt11*|QGdCtAz*
z9pPYV&1SRtQMp`xLkJNFAviTP)jV<H#6Ps_#P=io+a#j9(bLiF22jxftpNBKKodax
vg8&Dhrmoef9#;u~>-rS|p!l)>uKjNSf7rQAZ2gwc00000NkvXXu0mjfr62uF
diff --git a/plugins/kimchi/ui/images/theme-default/icon-sort.png b/plugins/kimchi/ui/images/theme-default/icon-sort.png
deleted file mode 100644
index 78e8b3930368c9ee163ea6f28a0c5a1d631241a9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3421
zcmV-j4WjaiP)<h;3K|Lk000e1NJLTq000{R000;W1^@s63qXeZ00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0007rNkl<Zc-p*{&2G~`5XXPxIO&G8ZrU7BQOjo~M8ydSgt+#`i$pv_r5^ewRj<57
z%LQ=-iAtchK&1)<O+UO2PCOi#R<22c6C~zh%R9UO+4=3vT2z()Ws-ZZ0kc2^RDl%e
z0H=W3_XwCO%qyA#eIT*9=Rm5e8s?lFu(+|Yu?kSBR8nAfZEbDG7QeB+zP=iUVdZZ-
zNYgai+uQrPwYBvII0Slt<|CX3R-AL&`H4xA1h$*yMx*h%-|yGQNuBq;1_VGiER6N8
z<X9wD)g_=KBKujEeGY<PNkoD&i2D706?h8l0!Kx$enAYNVfp_a$MIv}J}_s|4zkdY
zOaU2Cu_s~4Y at 7hMMP%MYevCLAr@$vwod&Mi0qKk*)&uITR_kTA+np7WOjT8E>z7Jq
zB60vc0zwf<ZLG9d1RTV1+)&l1g#SG71o!}a%jdU at Re-ZNj&A`EjM*Sob>o#;-D=UH
zjCFu}#th?9v~yrzRcpWua8~pihnaKE?Ue8hffEtw76*coVol&<N#AGYKQIbPMtkPH
zZvrdULx-`ttgA`Ij)A+zOfKqX1gp-!i1mQFbMDn7tn$o4tD}~+rhJiRz at hcRgGpKC
zqp1Pcft%LP@?xP0HGy;Qeam{|>^Q9QmuIcrZZB_cZoVDmm?X&puw=nyLs%V)$j^aI
zQx#FwKtvRna?bf7chYka*>=vI4j2oq2X;pVtE#{2OjVt#R=xMr0~Tuo72`J%t4n6q
z!MoPSs^0sBD2m>tX*%b<e*qlX<>$Qj4}p8Yv at y~$tp51nQPseBG=V$7qH%c-d@<k1
z4oB65E`ExJvbw^o at Zmym#!gyNW}z~ss{9%N0 at n^A`j6H=00000NkvXXu0mjfD-&z2
diff --git a/plugins/kimchi/ui/images/theme-default/icon-tree.png b/plugins/kimchi/ui/images/theme-default/icon-tree.png
deleted file mode 100644
index 5f7ed5312dac8d3bfb26010ea6555682f5a43f3d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3526
zcmV;%4LS0OP)<h;3K|Lk000e1NJLTq000^Q001Ef1^@s6$M?IS00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0008<Nkl<Zc-qXCJ!@1!6o#KOb3byEtRluJMoA%Pv=dvqEsQ at vOxn~|b}7W)VPP*(
z5Ns4dL at -!Jv at jtUER1n6ux7K#HG6Y&Y|i4cNp5o24;&cwvdqjobIyC78BtaKMGF8#
zqz at Pb27m~Vu5k*qfDP+gz)oo)V8A(dUPLBEWV~Sf6IH#J=lN2vLa~TUI_GYA at A2O6
zH~w~>=bL$+-%-^_L|SEq#5s2 at iXxIEA&z52WY=I-MOAMuFE2j;R)Jbsp&jo%Ns>^h
zR0zXx-wAOX$G}<3Q%^z~$1!0T;+!iI^1u-wER&=5iY-9*3RicFq9_7RbZoMe&?fNk
zFcYfP>MC#?$V<CURrBfT=|_u;ix+COTGcs6mSwGay?$zBWMo6ERjbv;#KgpB;2W at 3
zMo5edgTNW!vh`J9c5H0y_5A$&D=XMFU>$f1yaYaoNLtnmDX<Lu0G5C`5eY^|M**Ih
zzyk0c_#`5AGsD0h6v4u}ZNEF62+D1-b>I__07<ji#7^)<MBdq=F>tIbt_q#gYV9g~
z-z%<yk`VU2;;Klf9g-I!;(((Tsy^r3cv)Np2kagZi7X$n{pY>+S{7GDLJBZEJlssv
zlr;V2WbZv?aaAOg1Jr7@`&MUPtpsL<hK8O7L2&UPWOd at o9dsh#BQOWd0`Gv0IF4ru
zOt2 at e4r7M7b{(mz0Dfv}>hZ$D!ljj!m1-14-ANMfz3;}AsOny>Nr3)JrLx*+G_H3E
z3D6Im1Fit0W|VddZT=Q854-^uOVyEWC^VaY1D<z<x&56P*0u~q+DpL>I_EAp=O%+7
z7~d~fs`@0$vU^#UEdkp-lR-po9dP>F-uulg%l;2C?6mPNB7xOW-`^lZ1~iQfn}3ZA
zs_N{{xdB|Y)BN}yG6V%wXxXirTHOFNI>>PMx5;2PZr%F(j+6dzGEflG{;r42X>()e
z6E4{GkSQZ%V&24#11BxnL08zf?bTGX7ghRm0P43^ani4pQUCw|07*qoM6N<$f?lhO
A0ssI2
diff --git a/plugins/kimchi/ui/images/theme-default/icon-user.png b/plugins/kimchi/ui/images/theme-default/icon-user.png
deleted file mode 100644
index f4258d420b98a019332bc742e15d53497e1012cf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 5366
zcmV<S6bb8zP)<h;3K|Lk000e1NJLTq001Na001Zm1^@s6mcm%$00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000UhNkl<Zc-pL3ON<=Xbv^gKS6y8_Gu at owkRlz*6o*5 at V}q6 at Bo3fJiC|=rI9ddO
zkYp1Z77W9mMGzp{AfJ_C!wC=wK{n1Niy&EfWynGtuSggHY%uaiwBXR<NJ9?iLr(vy
ztKNI}-YlxRO(l%j3Q|C!yQ*Jxox1njbI&dM`d|MImf461ckbT7y}SE3bLI?;Y}-5k
zscznVHqY~ObqF$<O!j88*>~!?{`O=tIXQps9Ijm1#{1d)`&mo?)a*it at pJwD+8+)E
zgAWb*1M=QOR56`Qad3F>M~8=p-&NJWGT8U<J~wY>OD$w(IOndUl>VNXKe at Kn$J*)|
zeC9z!AS2{?2d4&uZdsPUeROoRL!d7b(W}ee0|0zc6icNm#<;P!clYnQ-R>ugqJW5C
zR##9H5EyEPx~@@&fXsXJdcCLi?;X5y at u`b1X5Qai77%yy9FN;qdOh5|d-tW|<KySE
zEJFwZbzLLW0aX=H*8!of5kf#p2{9$)d5+<5c=^_?pMRN%VTPr4KN^i5i#p3P93CA0
zYMys;RYgjI7$fSchN{9b!(fOpBE|#}g@~ft&9S??`+HlLE`3!*-d-wYufF!$QlT`p
zU+VYQAR<U9BE|@2hM6^=Fr=7}QiO^Cs&MR3*LCms{{73Ux*VY4$;sovn4u_oYzCy%
zMkpl!3{eA96K;`&7!#5R)D&h0Q^PxZd$ugGy{aw+2rv;5s5a?xbrT&i0Reyk(*Bkt
zK~#|>!DU%EfByV|EpZ<J at SB^POI2ANf`l01U0db^h$_6xz)S#ul+q%d&38es*WK+E
z#T$~+a)7okUw-@|@1MT;(>FgH>Kfj8fC(T#)S%wLOfWMfk*3OGgro#(#Pamv!O^b~
z(Y2)jy><KcGNSn0bTYZ*Gmn%ah?+F2C``2_w>JEeCPE=bs2T1bA7APgZ@<XQ%K?fp
zE(7SeuImznRp;Wv<btY#m|zCzLlK&%udZsTs%n^bax6n^|I9NVf9#@8r}Lfb*S~k`
z at bKtkgF&Opb3Jm70VXg25rIg8iXx?i at o0?xss70eFTC(?CnqN$qQ?U|bLPx4!gze?
z(o?UP*&mNaqmOpcg^GYVftf)d7yvVELA4d;-GgU7{><05wl4kqwQJYW>2#K9u8%KA
z(S)KXzOlW%{pO7uH at -D1XT8jOuyZXSz+kQX8)67BGi-lo`!6?6Z~kqJX{qP{fWNc1
zzf{@7pxr!w{q)AhkAD8v?N6+(tN<cl<~gBSju0l(DbAifbNk#APyA~PmHqVQO?0yC
zk)Y=1=KS*ItX$fl5mA|U^B<|nC&UEMhBp9#7%){dY925+HTc2i>CJbT8LEnvm6b;d
zu84q$;GBE6Qa^n1JwVm{{^0vXw|Lo9(L5Xhrcgn9Y{>H*y`uNyI)w3i$Ui!Hj-%uI
zSX*7i2S4~EQcCcbx3(H3t}2`ihXB!{2R$lEZs2}+;lhOn$HzzO(w4aqfedi$K#sAt
zHVCIqt-m>)mipgYlbQnBJcsusB&CI}nHl`f&JMiyI6OSW^o^S!0%Az$^l|`-#>>15
z-0gGco_Ir5o-1cF#I~Kxn<+D+zqWQPl6Ggaa&hgv0{i^|ie3Q_P}NoAiytO+2mvBZ
zQ=F4hM35w5ZFLpn at dSC^0WrfGk$iCW?AgN*0`BeaV^)?(F+wDPiP0Yn!0h6|!C}3q
z(j?f}SVw=*ha`b^6a at MoVBXW@ONwA7s0u=iSYKa<iondw5oy2Q$E++d9#1fui~%#O
z^i}{6n29$}pQZ&-y+ at vR;WLjEBVc$Wn8!>VO*?2vYhWT6F#tUqW88M^;Ij-xuW0Os
zG(Alu0l-GDC_YfEtY9=8qSML13 at l@Hc<B*{$f at d;YF7QlbTYYGmL;lL1xeBrfN4Wm
z03n3l?mN4GUY66(6X^WhFaN*IWz2kaR+cZ#s`~eb!{LX^$pj~(5r(57s(J=#Qi&83
z>Z*qK9$A)MJwCqwO0QRZhMB+Vv+TP>^g4j>e*#1VIL8-M_2m%4%hT!f;%qj<WHQBg
zJi=%+Mp>4Kp at yn8gl|>Xd50|PAcT;0vh2A);W<>e<Jf)EXa1j<`MTlJJ<I<u^m#TV
z`Qp*h at vo;8w^Y?vRfXxa#CSBqWI91Ln<3OS8vD}ZLy18I)O7{tJeUbt=E07E8XsWh
zFNGLhDyQY^8yg${2;iRq)Q<$z_LR-KuKr{?oqoYNx6v3cpss7oW;4vn60>TCx~dUk
zY*VF+qA>_kB5+6uKA at WUM*R)QyE(F~12Q_RBENa(?w#N07TrH!;y)vzAIy82_rAG^
zna}R;?|&nN`o-1NHHa!=Y|K{O4u(}#HA7(vNGT#|S|}_)Z6!9ID8vBA4Cfj*Agbte
z1l~D#@8H;FlhOE7!_oNJet+;;QGJz};SUZDu(Gm3Kl{&He|mI${Nm}2^~Mux(-u;Q
zh$$h2fDi+cG?7tNKn?S0!pxx56fUtY#5KeKVuG4NQiO9JS?1xq2eX4?KKJ(9yI(0f
z`OS-$F23b<c0PjPaQO6%8~^cDW?IX<M+gxy#fBr2kXjeG0AdY+nW_0x=it0+pWeg!
z44HR}n>O~P>5rz0qzY33%-|ej|K7cGz15Zdi%&jz%`-bXI5_;R>12F<ePaWu9al^Z
zOii<Njv?N+irZPt at N<CHk{SlEV=(^$nD@;wfg0~k08}BufHjV at +wEd+@6M;++THz@
z4<S6czrX)GKFb;|IR^s33>dVXE(iogWQB>r(0FQTqc*QHP~#kl8ogx#m>AwU5HlRN
z{+kF)3?c?Iq3GrqPbOQpZrys`i^|n<R_<ipF9>R_`%6jMJtC#p at Td+5?Nl*0^o<G|
zh-m&EsS(FchRkQkIvsSftchCY!QKNzjT``NTA3d_IJxMny84wm)EnwrlDVd<t16^@
zwKDfTF$AR4P8KOaRhyJ80%XlZ(mqs^dO+2XQe#sVAhQhW91MgQ17O-wl_z{%)h8*Y
zo1v;d5 at JM_Weel303<ap4`d##HY#e?TGoft1&}rTQ&9*Bh?<D08iW*-WHEMw8Vj6)
z43nhqCy{Huljr~7oO><Q_4A_oyD_F;_Kw%h%taAMN>CA~86+uG1u%uE!BpDur$It(
zza~<s(!w(*NpQ^YnTKnm1JhE~Zi~pb$?z(OZWwUS!)yfLCm{R;z`qb-$3Pz~dd1bQ
z>C+*Et?9HpUyjEv#ekF)+8TTVK-`Arp)si8MdQ&sSqH^R4 at FUox<zr at G2axC8zA@N
zB;ki<*khoc8>DyjG6Nm}xXw)1vn<PsqF7sBKeg at H?TE;g$z-%OnUtH8>7+L+XT1<Y
zM^v1dF at eC&r7ZKQn-_Iabf>GUtHb`Fe}{;F7Gr#~uItw)lgWXZ)xXe+cW?hS0K=Ts
U)&>o#U;qFB07*qoM6N<$f|wvR(EtDd
diff --git a/plugins/kimchi/ui/images/theme-default/icon-volume-default.png b/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
deleted file mode 100644
index ac906c7723e9c26900c347cf5e47e3192a5b2f88..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4265
zcmV;a5LWMrP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000U_X+uL$Nkc;*
zP;zf(X>4Tx0C?J+Q)g6D=@vcr-t<CCh=7z!Z&DQqAW}k$fE1A?Dj^9FN{At$*%eX2
z5k*A=8_1xD1CEY>j1^HV42lZa2jn55j)S9!ipu-pd!uXCy!YnK{<YUW=dAOcv(E>>
z2n?1;Gf_2w45>mM5#WQz#Kz&|E<k|_Bya!_2(x4%bNwR$0Qi19JS!r=2fhFSc+(3A
z0KiR~z%U$#{}1XynOp&YgaN>GkvK~TfD`~gdX7S-06<0ofSs5oQvjd at 0AR~wV&ec%
zEdXFAf9BHwfSvf6djSAjlpz%XppgI|6J>}*0BAb^tj|`8MF3bZ02F3R#5n-iEdVe{
zS7t~6u(trf&JYW-00;~KFj0twDF6g}0AR=?BX|IWnE(_<@>e|ZE3OddDgXd at nX){&
zBsoQaTL>+22Uk}v9w^R97b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&JM25
z&Nhy=4qq+mzXtyzVq)X|<<F~dKmY*YbbitPEHASffI9|&ZT_Mq?gVIF3!ruPi)OM9
zK(zp%>DpKGaQJ>aJVl|9x!Kv}<mA{nwP%2$2<XTo2=SN&}Hemwm5_29nZB!Mzr
zfky=R;KI!GOr;#pk_m)j+~$u*{I?7L{2kLG#7SbgSSl3bQ4(>EM4F8AGNmGkLXs)P
zCDQ+7;@>R$13uq10I+I40eg`xs9j?N_Dd%aSaiVR_W%I$yKlkNC<p_9XoKO;cmMA{
z{YRiB0Dxvml5qe4UPL4=RLZkI#|QubM4*8xut6L2!5A#S1{}c!+`$X{U^aw8B*el(
z5JC!MfE;pQDXfA*D2C0j9V%ci)Ic3Hz)@(1lW-0$!d18qJ#Y{DVF;eVD7=9Q1VP9M
z6Ja6Rhyh}XSR;-I7nz0lA;Cxl5{o1t$%qtDB1 at 4qNHJ21R3KGI9r8VL0y&3VM!JzZ
z$N(~e{D!<oF_eL_Q9aZQwL`h6HyVUSq6^SubTOKb7NDEZa<m#fj5eX?(5q+<+K)a%
z$1uR?7zZ=NY%ngy!$Pq*ED4ii%dsM?46DW(uvV-CyNUH<&#`v|5`jg)2{r_GLLgxt
zK}c9kSWehTs3069G!fbfHwgoTQNkx8lc-CyCb|*%#28{SF^5=4EF;zuj}tEtdx%5C
zHzX2?Loz41kOE1uq*T%p(niv5QX}asshc!N8Y7d*+GK082RW21AS=j)<elWh<TK<O
z<RS7~3Y}s=aisWD;wVzeYDyX95al%G24$EsK~<xgQr)PbR1r0gT0*U%wo<QAho}=Y
zb(%TNgBD3krLCfs(;8?OX!mKa=ybXf-IX3rm(W+z%jrkxm*@lZcMJ`N6@$l!XDAt)
z7zY?<8Fv`3m`tV_(~B9$R4_L&>zL=651DUOSSq$Ed=-((3YAKgCY2j1FI1_jrmEhm
z3sv(~%T$l4UQ>OpMpZLY<EaVMmaA2&olxsj8&hYgJE(`MXQ*#fKcs$H{fP!y!%V|Z
zL!?olv0vl7#vlu08MAmSA!`k*hIN58#3r%L*?e{?yO{kQyNf-lsi8STGfFd8vr_Yv
zW<Lkxm~r@=bWRE9D5sb6eu~}{?<wLb8>Tc&xiMv2YpRx)mRPGut5K^*>%BIv?Wdil
zy+ylO`+*KY$4Vz$Cr4+G&IO(4Q`uA9rwXSQO+7mGt}d!;r5mBUM0dY#r|y`ZzFvTy
zOmC;&dA;ZQ9DOhSRQ+xGr}ak+SO&8UBnI0I&KNw!HF0k|9WTe*@liuv!$3o&VU=N*
z;e?U7(LAHoMvX=fjA_PP<0Rv4#%;!<CI%)UCQD7~P41dfO}VBiraMeKOvla4&7#fL
znKhd|G1oHZo9CO?o8Px!T6kJ4wy3taWl6H+TBcd<w!ChIS~*#zSXEkGvqr6*ttHmG
zt-GfYr at 2m(POF~QXTz}Zw#l}sw;8bI*aq9Kwr#e3VP|3&XSc<!!|s#4lYP2<jr~0b
z4Tsqds~uV$esi>P6gpNq-kQ#w?mvCS^p@!_XIRe=&)75LwiC-K#A%&Vo6|>U7iYP1
zgY$@siA#dZE|)$on;XX6$i3uBboFsv;d;{botv|p!tJQrukJSPY3_&IpUgC$DV|v~
zbI`-cL*P;6(LW2Hl`w1HtbR{JPl0E(=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$
z-ZI`<U(7eax5&54Ps4AXUxnX8e<S~7|9bz?0H=T at 0cQh=fkA;=0{i%Sd?CM%KRVlG
z_OjXSL5!feK@~xdf~|t(!L1=^$n21<A@}E)&XLY(4uw#D=+ at 8&Vdi0r!+s1Wg@=V#
zhChyQh*%oYF_$%W(cD9G-$eREmPFp0XE9GXuPsV7Dn6<%YCPIEx-_~!#x7=A%+*+(
zSV?S4962s3t~PFLzTf=q^M~S{;tS(@7nm=|U2u7!&cgJCrxvL$5-d8FKum~EIF#@~
z5Gtq^j3x3DcO{MrdBPpSXCg1rHqnUKLtH8zPVz`9O?r~-k-Rl|B*inOEaka`C#jIU
zObtxkn>wBrnsy*<GCexIF at utkka0q)Ax)FEXX<C>W_HW0Wrec-#cqqYFCLW#$!oKa
ztOZ#u3bsO~=u}!L*D43HXJuDrzs-rtIhL!QE6wf9v&!3$H=OUE|LqdO65*1zrG`sa
zEge|qy{u|EvOIBl+X~|q1uKSD2CO`|inc0k)laMKSC_7Sy(W51Yk^+D%7VeQ0c-0E
zRSM;Wee2xU?Ojh;FInHUVfu!h8$K0 at imnvf7nc=(*eKk1<r{}@%D<W1l(ea<#JOb8
zX3}Qq=H4xyTMm}0m*$raZVlPmv<=@@wC(lwMcXfz%_!TugSJDtqrW`3yk)1!&dobN
zRHRh&RQgml?$X`0Vb}O>(e4|2y!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu8FGY
z_?G)^U9C=SaqY(g(gXbmBM!FLxzyDi(mhmCkJc;eM-ImyzW$x>cP$Mz4ONYt#^NJz
zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{
zoHRUHc}nwC$!Xf at g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR
z&Rp`ibn>#><r7!9SDLRnUv27i>OB6F(@)2{oV%K?xm;_x?s~noduI3P8=g1L-SoYA
z at fQEq)t)&$-M#aAZ}-Lb_1_lVesU-M&da;mcPH+xyidGe^g!)F*+boj)jwPQ+}Q8j
ze`>&Yp!3n(NB0JWgU|kv^^Xrj1&^7J%Z3ex>z+71IXU7#a{cN2r$f(V&nBK1{-XZN
zt``<Be)!ev*Ur(H(V>^}my^G3e5L*B!0Q>W+s4Ai9=^$VGcjKDR{QP2cieX!@1x%j
zPvm?ce<=TG`LXp=(5L&88IzO$1Ou4!{1CdwXaE2J24YJ`L;(K){{a7>y{D4^000Sa
zNLh0L01FcU01FcV0GgZ_00007bV*G`2i*w^2m>lc;ERj^00reqL_t(o!|j-DY*XhI
z$A8bg*VnP*B;X`KYO)m4CLKx3IzlSYsKi>8s;kt3T7jZMHKA&4wN(u5ecFd<-IpO1
zX;WXOt*h8dtFcB*Rn>PYXr%%Pkdgvxng-FZm4spkg6-JX_ujJ)wu774#SRYJhn{bK
z{9HZ%bI$*N&UqgA%C5{*-o+<+8h{@FO at JS$1AM?mz%Da}IB)`ZMz(f-dRc(#i5>+U
z1NL;x_YVg=da}-EjMbQWB9d?dwkujW!!u#Kp0|g`n}M}Ji)`(b+$~0)&#nQ2_Lh#6
zD{PC|E;XiJ=Aa3JV%&15G&FQgJ*jW+tpFARr*n5sMq}-+qx$VTdTt1K)M8-NfroDE
z9w7Ae5&rh^SlOBN+(%(TPxrCrr2!mRBM@%(tL1m>JW`t%;9x at cMJg(XqA9U}M8X!1
zo{bZWJG}FsXxYhscr->VVbeDn=R(R61u_(ulV at Dh$(!P1o7$rQ#`Ye=7Q~~VZ(|!r
z&Q0*0uT^0=Zdn0tTNz??V>Qd`eFT(JSv`EXvHg5Oku*Hj`)D{Rk6W(Pn1-gQt5ixv
zkd*66rOv^ofU)8D=4Hdv09O5>_tt2NeIhPthpw)Pq{U<E+HPyh@^#Zve9^+MlrR%)
z^*)0qzum;@#%fZou=|rSe)`^NqN(C(kv-QE<;%-Kr2r{Zy1(3BzUO*wX$a6g7@@Js
z<dLQGs4x_p-#j&=&LR0!T)3}%xy|z%+|m%><)Ja|e`Sc({}>=@Io#Vkw=AhQrqs`p
zL5?RKR=jwEk$5Uy<tsgyy5jUjYZd^`Ac6@;I5-jmpt;7&d+WcB?Fx_W9i9b%S7?8|
zb20TkgIjlf#QrnU|Bn>sTK8at=l>Nh8 at RHFB-ehpYys<AgJrFcWsP7cU=p>Q*#Rhm
z0)_fQ6)G_u+k3CPp-6!gSDQ>|noPEw|3$A8P+rZQ$Q!{m^Ymi}BF^Ts2_8tgbgXU+
z_%+nzq-wcBIAP<_6(W#wTrMOXqA8cfbG%f0bUZoZMa*^?97_<6r$AGeI)p2%YOKc0
z?p2U<-1z&S#T>uRt{ZE#=MEH-#a%D-&fj;AP~4Vh?JXV6N~x;c4NcGVaeCYWLjxrQ
zD?A+B*v|L&oZ|I?2oHX90SU|D_C+;pz9EQGiZ}j!k at dR=xsXa<W$OJVXCMB?RO%1v
z+k0b+{ro&Mr}C|LH?%o<Rs3q#^3k|0?lkNfVytVcLp&Oia=2?zkiA_?Sld0o>w^)L
zM`K6d2!B8RIS;)$#BUFcq%*Uyic{ZP$}d-hz!BDERW8$MbTZCJF1X7S>KsXDMvd<-
zspF}`qdc~%k*?Mt%l^`j1t>l3r!p at 2`>VafSOUN9Y+#P5^Z1Goo7(CzRayzfj&xcn
z^17+k$AOLQR2v!{JC0$AprpWXXK4K9-C;JoHZ=KtOSQ?hRc1-^X3+qZQiupQ*H-Ys
z**LE4=FDi*hdU*L(lvG+4|CruLo>cimvqO?g6zJ#nIC^^A-V{XS(7Q`$o|$fXsz>M
zsF_t*qr^vtNszx=8KSEt$hN~H{PW`o at u+o)_X+}4Cik=i`Ps4swAcF5X`jKkUYtns
zfJ9(vZ3R2mEFyWwwS02kqCXr*DYz-<<GMLs%#1T%nCY+DxRq&)2zZsEZLXKLx!!3$
zmLLcl at RZ0w$=@K0oq$v^O;@tVOaK)n0907E&>Kn2TKnw{PcUIi))5OZiv~F1x->o8
zPv;*$;3xaflpWkJ4tz%EpN`V<=YGa*mrQz7#Q at X*S652a`3#g-W4_<GED;Ko8JR|y
zv<1Be%Bxf7Gw^6i0hO6FUsfbzK)qK}Z})U9x%Yh1;hIWMUSMv<8#M)hDsa!uUH{R|
z^XY0067=e5B7?w6;AF86nEf729op1hXDz7oBt;;Wa?GS7M(&}7fXNhaDo+Hn|68ue
z&J*WU!j at Lq+PSLOC*XQu6VQ=){>`dvHWVY7$o*cncAnuYE3^F<>K#$%^M|uQ00000
LNkvXXu0mjfnm8lp
diff --git a/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif b/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
deleted file mode 100644
index aaa4f85a0560dcb59d4bb70154a9144417aae926..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1653
zcmZ?wbhEHb6krfwcz&0`fx$V3fzy*s(30KRoyj+pP0*a%B9B4Xkl)0X$H9|dJd8D}
zo<ZDBSSFF7*jZT0OhTc9Q7nTgk3rREDud*7MxI>8&Ju=(ISf+93MQOdag7Y~1hic{
z8T#{u6)cohTNtM^7+W$J#50+i$>`cj=^O84k`pyFn#{1$Ur8%a&i6QjtgEuCfQhw>
zh77A6gQ$gokA at _-E$2dp^>Sv?oMy2Rvbjr`S1FsTIOwZtnQE_R*m$2oUC1KhF at wT7
z#vS5TPBXdYi#jqhIC*|#&}Xr)`pY25?86wZk@$x}Azj<#4}*rAu{Vcnu(UhJUj}_&
zGsWW!mvn9Irz#jqI|d0m<_4Kq$D4?%x#%8bJFV#KwS(tqvz9fdTmMyIV-~+CKU<>^
zTODbStQ;$e9OEp8kfaJrQB(IojUXN?PfLA&1ruKlE$<Ybz{O>Dnh|c+IZj3l84L_z
z+ZiGkGQ_8gg)Ec{ZB|VbVu;;p8Ir+}TJcZ8St};J)7e)ugI_wAy~kUSA^Gq;v#nzB
zo6<uZ9TN=&l6EuXHCx41&a>X&p6tkweNrgxtWY&KLrITauKX0wDL;*ZSPITdWuHCl
z7S2#|o1wN-skGcGd-j}YNrw7v?ff;HUH7htly%83WoVk=SR=P3TA8QnVNZtdt|Td^
z4tBRT;l<gOCKJSuq^f)gOk<w3o@>%d>z1S5joVY2V;E+x4Cszxn7#dGQiZ}|@k{wq
ze5<)H#@>~ixp+mvx~nC^*GqKvReGJxyd=J8Z|Hp0)LG8{Q?7j|(|J;(^S(;?X-VtX
z{Ej0{$vo>WNUb at RHtpd12Emt&YTJ7ve>HRaY*WxWB$BmO<7<oVrMfE&d+u577yI7H
zdv${AuTG6`J!)PD74G*(XRN&WpI$)mKewN2NU*bGfUA+70W%{51B2pE7EU3C{|q`n
zHZYS2Ffee)GW_S1 at z}87U^9oXR?LYF3lFyoD0|KE*tqCuBO at a=9coY=j!k!j<aB0i
zc<9u4hfS*nq@!EHIP1=djf>s;v1`@Ep>^V-!(BqkNq@`*laF`Fn|H~0Zd!7(0h{Hf
zM42F;^~FLc<zy?bzucZ38xtI`nPf?{Nk)rZI#dI#a%KcAJ>AR3%!JJ}Tb!mjcL>V+
z&Dl|qe5_B>QtnB`#6;Il`9QBD85<TlO;@&EX5(p~fXzf_h=~b~c^s at tPtrczcWUF8
zl$)Y)G4W`lxU|rj6$Xj!z4E$EBA!9O at K)2-%Q<1V)NzW4rQ4Q{qQ at s^Df6<iU^CYa
zVJ@$f%ZvcUgKd2BZZRt+Jap&~-N|`mN5EtIK6cxtnin4*pO_@<TefG1V5)aFPwc)q
zGcP6L3rdhvk&Uz{R5;QluAbJjV`8#<o~Uk<jm4+?Cwh5=mxY`NNH{%#3wux+Vs{|2
sX~(-16pJpOC{Q`pufUDnn>s|9;tWh`McC5^G?`;~3OSj#0+YEl0GD)I?EnA(
diff --git a/plugins/kimchi/ui/images/theme-default/loading.gif b/plugins/kimchi/ui/images/theme-default/loading.gif
deleted file mode 100644
index 60d46d2683817f81a678c5e3eef14ef35089d119..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2190
zcmb7_`)^a%9l+0hKYVRpUtc?ZTqoD at wG*cy3TcL*WhlA#65q>!8Yk0A87qcR5=z^Y
zJ}6yLW8%anCg23f7(z>6v~*HCLD#C)V8TgAFyR#lkMIsJ2?Pk}#t-{tn<Fg<w4ZkV
zfO9_jobTtHkX|!=MwA6Cc<KdxeSQ7?{R0C7hYuef92^`P8ai_1NH&{2di3b<@bIx?
z$BrLAe&WQ5lP6D}I(2GfWMp)7^z7NQ=g*%X8ymZL@#5vnm#<v8a`o!f>({T}ym|BX
z?b~<m+_`)A?)dol>C>k#UApw};lrm-pWeH7 at A2cuH*VZGbLPysbLXBsd2->xh5PsK
z- at 0|{(W6J#u3dZZ;6Wyn0ssH<{@XBrc3rJf9iClLR*pcq9lZaVGA~-cTwJ<V{Ke|%
z2aWGEu8xZHm#<vbu>9kwSiEM<nzB{zMe7^iee1olcb9({1m1t57!ACjbmI64F96?~
zNjEu4wk5OaB at yzSY2Ieh>Dp5^|8B3&GwnsKbC7a$H`o>bJ6m5!w>ATZM9Td{e3$tc
zjWsG1+oB*VWX5JIAat18f--iyEv<EJRR~i;Cf-a2+&r9sn5K5WWP~^dMM?AWd`gCE
z4IaD(EhZaO$j*A%VPl~Ei22Rqa||PO<e*;tUr^ukpc^xtP18S}nbda0%ZKZ0T8G8p
z_-8v_JHB!bzj0=-y7w>S?6jprX^u%;*E})&m at X<btU+0Z`K?TbG#Drbp10yUgr|`W
zsSa&(r-C#3M;hzlG(efi#Oyo+#L@^tFaR at dgJjB%nal{gP3J>3K01G|X8g?nL><w6
z1aWE-(DOXthRmj>vG=DZwWyk1N)@fI550V^^3~sM{VqGB(zZ9UqMYs4nAn|Im0Hn~
z{i;yVrft2O-bY1gl?bVTGbl921)4R0peU3hjHkO4jMfoIh0S)hN5$!GBTqrAU<9K!
zQ>fBI7Nbm~>HA2)=sDmanMH~IArHQ2N4Gjj=YF1UW2U3&$7p$uu5sV~x at o8$(JFq{
zQ?RMoL9TM`Q0{C2YvY$s-1?Rb3kd}E6 at MR4w9p)(etw>YhcpYVkSyy*b-Kjm@=y4q
zJG&H=)FGf5t!5p;=gNiv2^a!~zXVWjG;kK7D2V<_1Nn&qZj7o02i=E3cdd+`d<G~z
z516XzYSP{)O=^*G at 1AhHbI(t(cZP25_-<_K+yL2$T<n!#uC4F!K60k8Aw2Tu!l}LH
z*y~}*ODTleyiBJ&PN%sg9!a*(l at US%Tu6av3j<Wx?R8)>m5&1ogCH1zEIykIdN33G
zHozeXK{SSx-ahn21eb>-c#)EcObQg9=WDOp)RbLNoD-;II<@#0d(uBO%<_AJMbY5)
zxrDK0fG^8H$=%_mFuG}8{n+-Iuo|0PS<SJ!nNTpM4bjQcl&LkbAysNpU`)4!RMJGL
z0Cg7S<wg+&I069YM*LHF4WS_vF?c_y*Qjn36&x=m^}Rwyz-)tWK%YFz<AshB6CKN9
zQoA9Ou{gfDs-k{ne8;a+ACiDy5RV)kS;$%Qk at 1+wI=ZS_>NuRY)O3A2)tE#G-K3&a
z0 at ewe-OjWn+Y4;APe1-#V{>pAjcbTQEI{Qp1fVeei4!&poCd9QmC!{W)ncE!-QK)l
zt#^a>kZc_~ytH;w-3#faCenRHNM<df#qsleU$yT~|0v!$LbSe8QH7gBeO>Id108Vl
z`woUrXKup3EEFgZITI5xOlNQf!4oS~+{*KYwxpiwFem`l&7{_bY*+1tR;3w&+#E%*
z4%p<fXcn)*<Dta-1v_7I_?%8(fzYEOwwP1$q1>;P*XkzuUMM#?QErgWJuTJQC1jo+
z*gg87a_(tUpSOVvk7m+o2jE&`;0Y-ecSNiAOSssb$js78Hpvi*zNKRUj-%JdK~9}w
z;B*tAVh*nxRbk%Et at GG?7Q|^GSJ at X!ei>QkFQQ9J3Bj~5nCJPyV|6Wnt#Za=S*Vx}
zJiFKz!tIy{*UKg~FSJjWrp3^ge_veLL!aVjgjFk&go4E=Xp2=fEdlJ8gH7rAvjRp*
zOshhx-?g6BQ9sL)F;_`kYfF*}ZPA%!YF?2O(KrvQSf}`52TKqp9x~*aWmwJ^sRA3}
zS_^%qz(RrBW_Jf9UFJdqxv|Wu43nMI_d>a?6Xm*?oW81t^71YH{rh#fJY5sXfCgH?
zI3Rw#u`re!ykhCEe^7brrP2hbQ7vMbq!S_8>~wlo>*f at ZD?>AF%zY_39aYc*(V??;
z^BPXbhj-0mIEdnnorR>;ihB%U$z_#zUSjjs=@$8K@%|qTKRk2yzs*u;Qajlj8D~iW
zRL*!kx^qN^gKUkQ>Jxh%V(^<YOMDQ(@!&xD!JQSO(f(LfNuiD{mQAH?>okN(VXcX}
z6f;jI%sRPNwieo3WXNnaDi*g1=1mwzvk(z5D2o}_z5r%lqzfKS;0~GjgMwe~6W~7%
L$~1kj8oc at +?)_VM
diff --git a/plugins/kimchi/ui/images/theme-default/user.png b/plugins/kimchi/ui/images/theme-default/user.png
deleted file mode 100644
index c57a81a92757ef31c424a4e6c741f71db62a1092..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1322
zcmV+_1=aeAP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%t=H+RCwCFS6xgTRTRGSvwt(QEW2!%
zZEC<RY*%PmU|~TT(9l}brY~)zO*HkzHZ`VcV>GER{yyo84?Y{zXpHs6S4l9Y#$eJ`
zmI9TeNz<hS;wC6n(*0#;*YAuwlVv;L6r^`@m^(Xj at A=NT=X~eDmCI%J$6w2=dc>kV
zY@@+(9ODK4xF85;1zu=k91CHOq^hbvsYP|PR4&aWrYD(|;jiDtI5Pm<(b&U^nWnhO
zZnuB!bUFte4hIuOQ3F&emDt+a8q4K!YCf0$1oO+2)4!@#0EkwQl5$ualok1!EXhHq
z%gJmu8{>K206<bG6ogDB^F}6}*^Ol{S=pO6{k6PaIG$r3kLNqL+Z|Ng3M1<QNK>wD
z0wClKm&?WQ4U=X0#ew+2^IHe7-h8rlfP at r~VhtmXu2yJ}XCzr-e!u_2cz2($B>?5B
zi|2UO+S2;E!|Bj0HB)Q`0>S806y at n{9{~c7$%@p!ndP-YM`IIhEY=e{_Fn+RjXY4D
zb{x;w(OtLDQsClyUxV+7?FS)7Fxa?e#qxE6tFbYV-gXdDdWFN`J9K{(0F)I&&kRj$
zI|#vW?8M0vpCb(|D<`nShlY!hry^t9K7x{3LJ-PdzWUnvKdl1r at A9)#r$@fP4l7&p
zK#etB9o>b2g9B$ST)a at CRMeTzOi1}V at 4bC5&=`2jO0Zg at ViXxFP-BUi$(LJN_Ksfp
z=3D3WYuB~o(FYyT;UkCH$jA$KK}644v0lp-vto3ht%C^2h1~xbJa874jpHaz!TRjf
zY@!{XyqnEtPcAMl+BGYX^P$j_DNIKpA3+{;9_VVv`tOm%b^yJ6^VZZ?maAd3z0;0@
z^8+}4h*+&yEHYHNtJz%k6}(OoDNW5J6wD))C57Iu_-s)vYB2+#M<hwQVt3em#0U9&
zo&oSVtQoZgARg=c6uf^<=YBd{Y`}8a9F^U1Jl{ry%u<!a_#1N%?h2Ge at cpwW*%8Sl
zF#ymAiApspWGS6aAB88zHwA!z8&qWFXDTRUy%7gEZ}J3fMsuAPv~1!2Wj+Ec3L+D2
zqQ(OhuzFCF7qC8cf8~C7W^Vd{X+O}>78M%&4WH3QB-PYQo53<|<J#h5P&Rc-l^#J?
ztdGi32J7nTKEUIfrfCS5pT-%6Ny$cqM^~a*D~g8DbG5~0>&O6nb1AyN(`O36>+`;^
zE8i^Fw<;AciT(!v#fQ?cbAMMCx}7NsJl&F=7!*g?e<hVl1yaAKR6|o}Z|D*QkY09o
zN@#y%ln=dSY#kHg^-=2m9;N1QW$4+`+|+aik2gd;`n?U_M)dhR4nPNiKf{Ix&_Fij
z3wd5}JSG6RifhF^Mi%tOdm`1jyVF9%1!9s64=8STpq4mxa*!S{s%Us%UnHDGZax<4
zb!iSYtJOTviuu)rdkcFeCVpX4i3FROnWX~qzgZm!1kk2;v%da**4x{|>b>>js0Gj0
z79%RJ$03IxgUidyp5)ymo1dR&^T~O(w6w(16;L1%wz|4%C<yKjGVr{ij5;GUFVxVY
zR|qke<XXV1A0cCv`|^h6xNTp%_8-x2w{KCTwpR&x%A<1^#8<T}S=9xRvL(nY<R)Z}
gniR8!<R1YB09_*wa#VgYhyVZp07*qoM6N<$f^kM~^#A|>
diff --git a/plugins/kimchi/ui/js/Makefile.am b/plugins/kimchi/ui/js/Makefile.am
deleted file mode 100644
index c9d1218..0000000
--- a/plugins/kimchi/ui/js/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-EXTRA_DIST = src
-
-jsdir = $(datadir)/wok/plugins/kimchi/ui/js
-
-dist_js_DATA = kimchi.min.js $(filter-out kimchi.min.js, $(wildcard *.js))
-
-kimchi.min.js: src/*.js
- cat $(sort $^) > $@
-
-CLEANFILES = kimchi.min.js
diff --git a/plugins/kimchi/ui/js/src/kimchi.api.js b/plugins/kimchi/ui/js/src/kimchi.api.js
deleted file mode 100644
index fde803a..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.api.js
+++ /dev/null
@@ -1,1355 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-var kimchi = {
-
- widget: {},
-
- trackingTasks: [],
-
- /**
- *
- * Get host capabilities
- * suc: callback if succeed err: callback if failed
- */
- getCapabilities : function(suc, err, done) {
- done = typeof done !== 'undefined' ? done: function(){};
- wok.requestJSON({
- url : "plugins/kimchi/config/capabilities",
- type : "GET",
- contentType : "application/json",
- dataType : "json",
- success: suc,
- error: err,
- complete: done
- });
- },
-
- /**
- * Get the i18 strings.
- */
- getI18n: function(suc, err, url, sync) {
- wok.requestJSON({
- url : url ? url : 'plugins/kimchi/i18n.json',
- type : 'GET',
- resend: true,
- dataType : 'json',
- async : !sync,
- success : suc,
- error: err
- });
- },
-
- /**
- * Get the host static information.
- */
- getHost: function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host',
- type : 'GET',
- resend: true,
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error: err
- });
- },
-
- /**
- * Get the dynamic host stats (usually used for monitoring).
- */
- getHostStats : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/stats',
- type : 'GET',
- contentType : 'application/json',
- headers: {'Wok-Robot': 'wok-robot'},
- dataType : 'json',
- success : suc,
- error: err
- });
- },
-
- /**
- * Get the historic host stats.
- */
- getHostStatsHistory : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/stats/history',
- type : 'GET',
- resend: true,
- contentType : 'application/json',
- headers: {'Wok-Robot': 'wok-robot'},
- dataType : 'json',
- success : suc,
- error: err
- });
- },
-
- /**
- *
- * Create a new Virtual Machine. Usage: kimchi.createVM({ name: 'MyUbuntu',
- * template: '/templates/ubuntu_base' }, creationSuc, creationErr);
- *
- * settings: name *(optional)*: The name of the VM. Used to identify the VM
- * in this API. If omitted, a name will be chosen based on the template
- * used. template: The URI of a Template to use when building the VM
- * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
- * suc: callback if succeed err: callback if failed
- */
- createVM : function(settings, suc, err) {
- wok.requestJSON({
- url : "plugins/kimchi/vms",
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json"
- }).done(suc).fail(err);
- },
-
- /**
- *
- * Create a new Template. settings name: The name of the Template. Used to
- * identify the Template in this API suc: callback if succeed err: callback
- * if failed
- */
- createTemplate : function(settings, suc, err) {
- wok.requestJSON({
- url : "plugins/kimchi/templates",
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success: suc,
- error: err
- });
- },
-
- deleteTemplate : function(tem, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates/' + encodeURIComponent(tem),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- cloneTemplate : function(tem, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates/' + encodeURIComponent(tem) + "/clone",
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listTemplates : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- /**
- * Retrieve the information of a template by the given name.
- */
- retrieveTemplate : function(templateName, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates/' + encodeURIComponent(templateName),
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json'
- }).done(suc);
- },
-
- /**
- * Update a template with new information. TODO: Update me when the RESTful
- * API is available. Now work it around by remove the template and then
- * recreate it with new information.
- */
- updateTemplate : function(name, settings, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/templates/' + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json'
- }).done(suc).fail(err);
- },
-
- /**
- * Create a new Storage Pool. settings name: The name of the Storage Pool
- * path: The path of the defined Storage Pool type: The type of the defined
- * Storage Pool capacity: The total space which can be used to store volumes
- * The unit is MBytes suc: callback if succeed err: callback if failed
- */
- createStoragePool : function(settings, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools',
- type : 'POST',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json'
- }).done(suc).fail(err);
- },
-
- updateStoragePool : function(name, content, suc, err) {
- $.ajax({
- url : "plugins/kimchi/storagepools/" + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(content)
- }).done(suc).fail(err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- });
- },
-
- startVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/start',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- poweroffVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/poweroff',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- shutdownVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/shutdown',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- resetVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/reset',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- suspendVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/suspend',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- resumeVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/resume',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- /**
- * Retrieve the information of a given VM by its name.
- *
- * @param vm VM name
- * @param suc callback for success
- * @param err callback for error
- */
- retrieveVM : function(vm, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- /**
- * Update a VM with new information.
- */
- updateVM : function(name, settings, suc, err) {
- $.ajax({
- url : "plugins/kimchi/vms/" + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- deleteVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- vncToVM : function(vm) {
- wok.requestJSON({
- url : 'plugins/kimchi/config',
- type : 'GET',
- dataType : 'json'
- }).done(function(data, textStatus, xhr) {
- proxy_port = data['display_proxy_port'];
- wok.requestJSON({
- url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
- type : "POST",
- dataType : "json"
- }).done(function() {
- url = 'https://' + location.hostname + ':' + proxy_port;
- url += "/console.html?url=";
- url += encodeURIComponent("plugins/kimchi/novnc/vnc_auto.html");
- url += "&port=" + proxy_port;
- /*
- * From python documentation base64.urlsafe_b64encode(s)
- * substitutes - instead of + and _ instead of / in the
- * standard Base64 alphabet, BUT the result can still
- * contain = which is not safe in a URL query component.
- * So remove it when needed as base64 can work well without it.
- * */
- url += "&path=?token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
- url += "&wok=" + location.port;
- url += '&encrypt=1';
- window.open(url);
- });
- }).error(function() {
- wok.message.error.code('KCHAPI6002E');
- });
- },
-
- spiceToVM : function(vm) {
- wok.requestJSON({
- url : 'plugins/kimchi/config',
- type : 'GET',
- dataType : 'json'
- }).done(function(data, textStatus, xhr) {
- proxy_port = data['display_proxy_port'];
- wok.requestJSON({
- url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
- type : "POST",
- dataType : "json"
- }).done(function(data, textStatus, xhr) {
- url = 'https://' + location.hostname + ':' + proxy_port;
- url += "/console.html?url=plugins/kimchi/spice_auto.html";
- url += "&port=" + proxy_port + "&listen=" + location.hostname;
- /*
- * From python documentation base64.urlsafe_b64encode(s)
- * substitutes - instead of + and _ instead of / in the
- * standard Base64 alphabet, BUT the result can still
- * contain = which is not safe in a URL query component.
- * So remove it when needed as base64 can work well without it.
- * */
- url += "&token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
- url += "&wok=" + location.port;
- url += '&encrypt=1';
- window.open(url);
- });
- }).error(function() {
- wok.message.error.code('KCHAPI6002E');
- });
- },
-
- listVMs : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms',
- type : 'GET',
- contentType : 'application/json',
- headers: {'Wok-Robot': 'wok-robot'},
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- listTemplates : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- listStoragePools : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- listStorageVolumes : function(poolName, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listIsos : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listDistros : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/config/distros',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- stepListDeepScanIsos : function(suc, err) {
- var deepScanHandler = {
- stop : false
- };
- var isoPool = 'iso' + new Date().getTime();
- kimchi.createStoragePool({
- name : isoPool,
- type : 'kimchi-iso',
- path : '/'
- }, function(result) {
- var taskId = result.task_id;
- function monitorTask() {
- if (deepScanHandler.stop) {
- return;
- }
- kimchi.getTask(taskId, function(result) {
- var status = result.status;
- if (status === "finished") {
- if (deepScanHandler.stop) {
- return;
- }
- kimchi.listStorageVolumes(isoPool, function(isos) {
- if (deepScanHandler.stop) {
- return;
- }
- suc(isos, true);
- }, err);
- } else if (status === "running") {
- if (deepScanHandler.stop) {
- return;
- }
- kimchi.listStorageVolumes(isoPool, function(isos) {
- if (deepScanHandler.stop) {
- return;
- }
- suc(isos, false);
- setTimeout(monitorTask, 2000);
- }, err);
- } else if (status === "failed") {
- if (deepScanHandler.stop) {
- return;
- }
- err(result.message);
- }
- }, err);
- }
- setTimeout(monitorTask, 2000);
- }, err);
- return deepScanHandler;
- },
-
- getTask : function(taskId, suc, err) {
- wok.requestJSON({
- url : 'tasks/' + encodeURIComponent(taskId),
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getTasksByFilter : function(filter, suc, err, sync) {
- wok.requestJSON({
- url : 'tasks?' + filter,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- async : !sync,
- success : suc,
- error : err
- });
- },
-
- deleteStoragePool : function(poolName, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- changePoolState : function(poolName, state, suc, err) {
- if (state === 'activate' || state === 'deactivate')
- $.ajax({
- url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/' + state,
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listNetworks : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/networks',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- toggleNetwork : function(name, on, suc, err) {
- var action = on ? "activate" : "deactivate";
- wok.requestJSON({
- url : 'plugins/kimchi/networks/' + encodeURIComponent(name) + '/' + action,
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- createNetwork : function(network, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/networks',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(network),
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getInterfaces : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/interfaces',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- deleteNetwork : function(name, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/networks/' + encodeURIComponent(name),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- listReports : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/debugreports',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- trackTask : function(taskID, suc, err, progress) {
- var onTaskResponse = function(result) {
- var taskStatus = result['status'];
- switch(taskStatus) {
- case 'running':
- progress && progress(result);
- setTimeout(function() {
- kimchi.trackTask(taskID, suc, err, progress);
- }, 2000);
- break;
- case 'finished':
- suc && suc(result);
- break;
- case 'failed':
- err && err(result);
- break;
- default:
- break;
- }
- };
-
- kimchi.getTask(taskID, onTaskResponse, err);
- if(kimchi.trackingTasks.indexOf(taskID) < 0)
- kimchi.trackingTasks.push(taskID);
- },
-
- createReport: function(settings, suc, err, progress) {
- var onResponse = function(data) {
- taskID = data['id'];
- kimchi.trackTask(taskID, suc, err, progress);
- };
-
- wok.requestJSON({
- url : 'plugins/kimchi/debugreports',
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success : onResponse,
- error : err
- });
- },
-
- renameReport : function(name, settings, suc, err) {
- $.ajax({
- url : "plugins/kimchi/debugreports/" + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- deleteReport: function(settings, suc, err) {
- var reportName = encodeURIComponent(settings['name']);
- wok.requestJSON({
- url : 'plugins/kimchi/debugreports/' + reportName,
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- downloadReport: function(settings, suc, err) {
- window.open(settings['file']);
- },
-
- shutdown: function(settings, suc, err) {
- var reboot = settings && settings['reboot'] === true;
- var url = 'plugins/kimchi/host/' + (reboot ? 'reboot' : 'shutdown');
- wok.requestJSON({
- url : url,
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listHostPartitions : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/partitions',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getStorageServers: function(type, suc, err) {
- var url = 'plugins/kimchi/storageservers?_target_type=' + type;
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getStorageTargets: function(server,type, suc, err) {
- var url = 'plugins/kimchi/storageservers/' + server + '/storagetargets?_target_type=' + type;
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- timeout: 2000,
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getStoragePool: function(poolName, suc, err) {
- var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName);
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- timeout: 2000,
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getStoragePoolVolume: function(poolName, volumeName, suc, err) {
- var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName);
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- timeout: 2000,
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- addVMStorage : function(settings, suc, err) {
- var vm = encodeURIComponent(settings['vm']);
- delete settings['vm'];
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + vm + '/storages',
- type : 'POST',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- retrieveVMStorage : function(settings, suc, err) {
- var vm = encodeURIComponent(settings['vm']);
- var dev = encodeURIComponent(settings['dev']);
- wok.requestJSON({
- url : "plugins/kimchi/vms/" + vm + '/storages/' + dev,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- replaceVMStorage : function(settings, suc, err) {
- var vm = encodeURIComponent(settings['vm']);
- var dev = encodeURIComponent(settings['dev']);
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + vm + '/storages/' + dev,
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify({
- path: settings['path']
- }),
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- deleteVMStorage : function(settings, suc, err) {
- var vm = settings['vm'];
- var dev = settings['dev'];
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
- '/storages/' + encodeURIComponent(dev),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listVMStorages : function(params, suc, err) {
- var vm = encodeURIComponent(params['vm']);
- var type = params['storageType'];
- var url = 'plugins/kimchi/vms/' + vm + '/storages';
- if(type) {
- url += '?type=' + type;
- }
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listSoftwareUpdates : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/packagesupdate',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- updateSoftware : function(suc, err, progress) {
- var taskID = -1;
- var onResponse = function(data) {
- taskID = data['id'];
- trackTask();
- };
-
- var trackTask = function() {
- kimchi.getTask(taskID, onTaskResponse, err);
- };
-
- var onTaskResponse = function(result) {
- var taskStatus = result['status'];
- switch(taskStatus) {
- case 'running':
- progress && progress(result);
- setTimeout(function() {
- trackTask();
- }, 200);
- break;
- case 'finished':
- case 'failed':
- suc(result);
- break;
- default:
- break;
- }
- };
-
- wok.requestJSON({
- url : 'plugins/kimchi/host/swupdate',
- type : "POST",
- contentType : "application/json",
- dataType : "json",
- success : onResponse,
- error : err
- });
- },
-
- createRepository : function(settings, suc, err) {
- wok.requestJSON({
- url : "plugins/kimchi/host/repositories",
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success: suc,
- error: err
- });
- },
-
- retrieveRepository : function(repository, suc, err) {
- var reposID = encodeURIComponent(repository);
- wok.requestJSON({
- url : "plugins/kimchi/host/repositories/" + reposID,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- updateRepository : function(name, settings, suc, err) {
- var reposID = encodeURIComponent(name);
- $.ajax({
- url : "plugins/kimchi/host/repositories/" + reposID,
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- enableRepository : function(name, enable, suc, err) {
- var reposID = encodeURIComponent(name);
- $.ajax({
- url : "plugins/kimchi/host/repositories/" + reposID +
- '/' + (enable === true ? 'enable' : 'disable'),
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- deleteRepository : function(repository, suc, err) {
- var reposID = encodeURIComponent(repository);
- wok.requestJSON({
- url : 'plugins/kimchi/host/repositories/' + reposID,
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listRepositories : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/repositories',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- getHostFCDevices: function(suc, err) {
- var url = 'plugins/kimchi/host/devices?_cap=fc_host';
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getGuestInterfaces: function(name, suc, err) {
- var url = 'plugins/kimchi/vms/' + encodeURIComponent(name) + '/ifaces';
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err || function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- createGuestInterface : function(name, interface, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(name) + '/ifaces',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(interface),
- success : suc,
- error : err || function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- deleteGuestInterface : function(vm, mac, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/ifaces/' + encodeURIComponent(mac),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- updateGuestInterface : function(vm, mac, interface, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/ifaces/' + encodeURIComponent(mac),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(interface),
- dataType : 'json',
- success: suc,
- error: err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getUserById : function(data, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/users?_user_id=' + data.user_id,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- async : false,
- success : suc && suc(data),
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getUsers : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/users',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getGroups : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/groups',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getHostPCIDevices : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/devices?_passthrough=true&_cap=pci',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getPCIDeviceCompanions : function(pcidev, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/devices?_passthrough_affected_by=' + pcidev,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getISCSITargets : function(server, port, suc, err) {
- server = encodeURIComponent(server);
- port = port ? '&_server_port='+encodeURIComponent(port) : '';
- wok.requestJSON({
- url : 'plugins/kimchi/storageservers/' + server + '/storagetargets?_target_type=iscsi' + port,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getPeers : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/peers',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getVMPCIDevices : function(id, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(id) + '/hostdevs',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- addVMPCIDevice : function(vm, device, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm) +'/hostdevs',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(device),
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- removeVMPCIDevice : function(vm, device, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm) +'/hostdevs/' + encodeURIComponent(device),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- /**
- * Create a new volume with capacity
- */
- createVolumeWithCapacity: function(poolName, settings, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes',
- type : 'POST',
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success : suc,
- error : err
- });
- },
-
- /**
- * Upload volume content
- */
- uploadVolumeToSP: function(poolName, volumeName, settings, suc, err) {
- var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName);
- var fd = settings['formData'];
- wok.requestJSON({
- url : url,
- type : 'PUT',
- data : fd,
- processData : false,
- contentType : false,
- dataType: 'json',
- success : suc,
- error : err
- });
- },
-
- /**
- * Add a volume to a given storage pool by URL.
- */
- downloadVolumeToSP: function(settings, suc, err) {
- var sp = encodeURIComponent(settings['sp']);
- delete settings['sp'];
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools/' + sp + '/storagevolumes',
- type : 'POST',
- data : JSON.stringify(settings),
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- cloneGuest: function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + "/clone",
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- listSnapshots : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getCurrentSnapshot : function(vm, suc, err, sync) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots/current',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- async : !sync,
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- revertSnapshot : function(vm, snapshot, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots/' + encodeURIComponent(snapshot) + '/revert',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- createSnapshot : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- deleteSnapshot : function(vm, snapshot, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots/' + encodeURIComponent(snapshot),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getCPUInfo : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/cpuinfo',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- }
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js b/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
deleted file mode 100644
index 6be6f9a..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.guest_add_main = function() {
- var showTemplates = function() {
- wok.topic('templateCreated').unsubscribe(showTemplates);
- kimchi.listTemplates(function(result) {
- if (result && result.length) {
- $('#prompt-create-template').addClass('hidden');
- $('#prompt-choose-template').removeClass('hidden');
- var html = '';
- var tmpl = $('#tmpl-template').html();
- $.each(result, function(index, value) {
- html += wok.substitute(tmpl, value);
- });
- $('#templateTile').html(html);
- return;
- }
-
- $('#btn-create-template').on('click', function(event) {
- wok.topic('templateCreated').subscribe(showTemplates);
-
- wok.window.open('plugins/kimchi/template-add.html');
-
- event.preventDefault();
- });
-
- $('#prompt-choose-template').addClass('hidden');
- $('#prompt-create-template').removeClass('hidden');
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- };
-
- function validateForm() {
- if (!$('input[name=template]:checked', '#templateTile').val()) {
- return false;
- }
- return true;
- }
-
- $('#form-vm-add').change(function() {
- if (validateForm()) {
- $('#vm-doAdd').attr('disabled', false);
- }
- });
-
- var addGuest = function(event) {
- $('#vm-doAdd').attr('disabled', true);
- $('#vm-doAdd').attr('style', 'display:none');
- $('#vm-doAdding').attr('style', 'display');
- var formData = $('#form-vm-add').serializeObject();
- kimchi.createVM(formData, function() {
- kimchi.listVmsAuto();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- $('#vm-doAdd').attr('style', 'display');
- $('#vm-doAdding').attr('style', 'display:none');
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
-
- return false;
- };
-
- $('#form-vm-add').on('submit', addGuest);
- $('#vm-doAdd').on('click', addGuest);
-
- showTemplates();
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js b/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
deleted file mode 100644
index 7105c88..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.guest_edit_main = function() {
- var buttonContainer = $('#action-button-container');
- $('#guest-edit-tabs').tabs({
- beforeActivate: function(event, ui) {
- var display_list = null;
- if(kimchi.thisVMState === "running") {
- display_list = ['form-guest-edit-permission'];
- } else {
- display_list = ['form-guest-edit-general', 'form-guest-edit-permission'];
- }
- $(buttonContainer).addClass('hidden');
- var deactivated = ui['newPanel'];
- if(display_list.indexOf($(deactivated).attr('id')) >= 0) {
- $(buttonContainer).removeClass('hidden');
- }
- }
- });
-
- var guestEditForm = $('#form-guest-edit-general');
- var saveButton = $('#guest-edit-button-save');
- var authType;
-
- var refreshCDROMs = function() {
- kimchi.listVMStorages({
- vm: kimchi.selectedGuest
- }, function(storages) {
- var container = $('#form-guest-edit-storage .body');
- $(container).empty();
- $.each(storages, function(index, storage) {
- storage['vm'] = kimchi.selectedGuest;
- rowHTML = $('#' + storage['type'] + '-row-tmpl').html();
- var templated = wok.substitute(rowHTML, storage);
- container.append(templated);
- });
-
- $('.replace', container).button({
- icons: {
- primary: 'ui-icon-pencil'
- },
- text: false
- });
-
- $('.detach', container).button({
- icons: {
- primary: 'ui-icon-trash'
- },
- text: false
- });
- if (kimchi.thisVMState === 'running') {
- $('.detach[data-type="cdrom"]', container).remove();
- }
-
- $('.save', container).button({
- icons: {
- primary: 'ui-icon-disk'
- },
- text: false
- });
-
- $('.cancel', container).button({
- icons: {
- primary: 'ui-icon-arrowreturnthick-1-w'
- },
- text: false
- });
- });
- };
-
- var initStorageListeners = function() {
- var container = $('#form-guest-edit-storage .body');
- var toggleCDROM = function(rowNode, toEdit) {
- $('button.replace,button.detach', rowNode)
- [(toEdit ? 'add' : 'remove') + 'Class']('hidden');
- $('button.save,button.cancel', rowNode)
- [(toEdit ? 'remove' : 'add') + 'Class']('hidden');
- var pathBox = $('.path input', rowNode)
- .prop('readonly', !toEdit);
- toEdit && pathBox.select();
- pathBox.val(pathBox.attr('value'));
- };
-
- var replaceCDROM = function(event) {
- event.preventDefault();
- kimchi.selectedGuestStorage = $(this).data('dev');
- $('.item', container).each(function(i, n) {
- toggleCDROM(n);
- });
- var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
- toggleCDROM(rowNode, true);
- };
-
- $(container).on('click', 'button.replace', replaceCDROM);
-
- $(container).on('click', 'button.detach', function(e) {
- e.preventDefault();
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHVMCD6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- if ($(this).data('type') == "disk")
- settings['content'] = i18n['KCHVMCD6009M'];
-
- var dev = $(this).data('dev');
- wok.confirm(settings, function() {
- kimchi.deleteVMStorage({
- vm: kimchi.selectedGuest,
- dev: dev
- }, function() {
- wok.topic('kimchi/vmCDROMDetached').publish();
- });
- });
- });
-
- $(container).on('click', 'button.save', function(event) {
- event.preventDefault();
- var path = $('#cdrom-path-' + kimchi.selectedGuestStorage).val();
- var settings = {
- vm: kimchi.selectedGuest,
- dev: kimchi.selectedGuestStorage,
- path: path
- };
-
- kimchi.replaceVMStorage(settings, function(result) {
- wok.topic('kimchi/vmCDROMReplaced').publish({
- result: result
- });
- }, function(result) {
- var errText = result['reason'] ||
- result['responseJSON']['reason'];
- wok.message.error(errText);
- });
- });
-
- $(container).on('click', 'button.cancel', function(event) {
- event.preventDefault();
- var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
- toggleCDROM(rowNode);
- });
- };
-
- var setupInterface = function() {
- $(".add", "#form-guest-edit-interface").button({
- icons: { primary: "ui-icon-plusthick" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- addItem({
- id: -1,
- mac: "",
- network: "",
- type: "network",
- viewMode: "hide",
- editMode: ""
- });
- });
- var toggleEdit = function(item, on, itemId){
- $("#label-mac-" + itemId, item).toggleClass("hide", on);
- $("#edit-mac-" + itemId, item).toggleClass("hide", !on);
- $("#label-network-" + itemId, item).toggleClass("hide", false);
- $("select", item).toggleClass("hide", true);
- $(".action-area", item).toggleClass("hide");
- };
- var addItem = function(data) {
- if (data.id == -1) {
- data.id = $('#form-guest-edit-interface > .body').children().size()
- }
- var itemNode = $.parseHTML(wok.substitute($('#interface-tmpl').html(),data));
- $(".body", "#form-guest-edit-interface").append(itemNode);
- $("select", itemNode).append(networkOptions);
- if(data.network!==""){
- $("select", itemNode).val(data.network);
- }
- $(".edit", itemNode).button({
- disabled: kimchi.thisVMState === "running",
- icons: { primary: "ui-icon-pencil" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- toggleEdit($(this).closest('div'), true, data.id);
- });
- $(".delete", itemNode).button({
- icons: { primary: "ui-icon-trash" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- kimchi.deleteGuestInterface(kimchi.selectedGuest, item.prop("id"), function(){
- item.remove();
- });
- });
- $(".save", itemNode).button({
- icons: { primary: "ui-icon-disk" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- var interface = {
- network: $("select", item).val(),
- type: "network",
- mac: $(":text", item).val()
- };
- var postUpdate = function(mac){
- $("#label-network-" + data.id, item).text(interface.network);
- $("#label-mac-" + data.id, item).text(mac);
- $("#edit-mac-" + data.id, item).val(mac);
- toggleEdit(item, false, data.id);
- };
- if(item.prop("id")==""){
- kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data){
- item.prop("id", data.mac);
- postUpdate(data.mac);
- });
- }else{
- if (item.prop('id') == interface.mac) {
- toggleEdit(item, false, data.id);
- } else {
- kimchi.updateGuestInterface(kimchi.selectedGuest, item.prop('id'),
- interface, function(data){
- item.prop("id", data.mac);
- postUpdate(data.mac);
- });
- }
- }
- });
- $(".cancel", itemNode).button({
- icons: { primary: "ui-icon-arrowreturnthick-1-w" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- $("label", item).text()==="" ? item.remove() : toggleEdit(item, false, data.id);
- });
- };
- var networkOptions = "";
- kimchi.listNetworks(function(data){
- for(var i=0;i<data.length;i++){
- var isSlected = i==0 ? " selected" : "";
- networkOptions += "<option"+isSlected+">"+data[i].name+"</option>";
- }
- kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data){
- for(var i=0;i<data.length;i++){
- data[i].viewMode = "";
- data[i].editMode = "hide";
- data[i].id = i;
- addItem(data[i]);
- }
- });
- });
- };
-
- var setupPermission = function() {
- //set up for LDAP
- $(".add", "#form-guest-edit-permission").button({
- icons: { primary: "ui-icon-plusthick" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- addItem({
- user: "",
- freeze: false,
- viewMode: "hide",
- editMode: "",
- checked: true
- });
- });
- var addItem = function(data) {
- var itemNode = $.parseHTML(wok.substitute($('#ldap-user-tmpl').html(),data));
- $(".body", "#form-guest-edit-permission .ldap").append(itemNode);
- $(".delete", itemNode).button({
- icons: { primary: "ui-icon-trash" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- item.remove();
- });
- $("input").focusout(function() {
- var item = $(this).parent().parent();
- var user= $(this).val();
- item.prop("id", user);
- $("label", item).text(user);
- });
- $("input").focusin(function() {
- $(this).removeClass("checked");
- });
-
- if (data.checked == true) {
- $(".checked", itemNode).addClass("hide");
- }
- };
- var toggleEdit = function(item, on){
- $("label", item).toggleClass("hide", on);
- $("input", item).toggleClass("hide", !on);
- $(".action-area", item).toggleClass("hide");
- };
- //set up for PAM
- var userNodes = {}, groupNodes = {};
- authType = kimchi.capabilities['auth']
- if (authType == 'pam') {
- $("#form-guest-edit-permission .ldap").hide();
- kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
- kimchi.getUsers(function(users){
- kimchi.getGroups(function(groups){
- var subArray = function(a1, a2){ //a1-a2
- for(var i=0; i<a2.length; i++){
- for(var j=0; j<a1.length; j++){
- if(a2[i] == a1[j]){
- a1.splice(j, 1);
- break;
- }
- }
- }
- };
- subArray(users, vm.users); subArray(groups, vm.groups);
- init(users, groups, vm.users, vm.groups);
- });
- });
- });
- } else if (authType == 'ldap') {
- $("#form-guest-edit-permission .pam").hide();
- kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
- for (var i=0; i<vm.users.length; i++) {
- addItem({
- user: vm.users[i],
- viewMode: "",
- freeze: true,
- editMode: "hide",
- checked: true});
- }
- });
- }
- var sortNodes = function(container, isUser){
- nodes = container.children();
- var keys = [];
- nodes.each(function(){
- keys.push($("label", this).text());
- });
- keys.sort();
- container.empty();
- for(var i=0; i<keys.length; i++){
- var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]];
- $(itemNode).click(function(){
- $(this).toggleClass("item-picked");
- });
- container.append(itemNode);
- }
- };
- var init = function(availUsers, availGroups, selUsers, selGroups){
- var initNode = function(key, isUserNode){
- var nodeGroups = isUserNode ? userNodes : groupNodes;
- nodeGroups[key] = $.parseHTML(wok.substitute($('#permission-item-pam').html(), {
- val: key,
- class: isUserNode? "user-icon" : "group-icon"
- }));
- };
- for(var i=0; i<availUsers.length; i++){
- initNode(availUsers[i], true);
- $("#permission-avail-users").append(userNodes[availUsers[i]]);
- sortNodes($("#permission-avail-users"), true);
- }
- for(var i=0; i<selUsers.length; i++){
- initNode(selUsers[i], true);
- $("#permission-sel-users").append(userNodes[selUsers[i]]);
- sortNodes($("#permission-sel-users"), true);
- }
- for(var i=0; i<availGroups.length; i++){
- initNode(availGroups[i], false);
- $("#permission-avail-groups").append(groupNodes[availGroups[i]]);
- sortNodes($("#permission-avail-groups"), false);
- }
- for(var i=0; i<selGroups.length; i++){
- initNode(selGroups[i], false);
- $("#permission-sel-groups").append(groupNodes[selGroups[i]]);
- sortNodes($("#permission-sel-groups"), false);
- }
- };
- var filterNodes = function(key, container){
- container.children().each(function(){
- $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : "");
- });
- }
- $("#permission-avail-searchBox").on("keyup", function() {
- var key = $(this).val();
- filterNodes(key, $("#permission-avail-users"));
- filterNodes(key, $("#permission-avail-groups"));
- });
- $("#permission-sel-searchBox").on("keyup", function() {
- var key = $(this).val();
- filterNodes(key, $("#permission-sel-users"));
- filterNodes(key, $("#permission-sel-groups"));
- });
- $('#permissionGo').button().click(function(evt) {
- evt.preventDefault();
- $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked");
- sortNodes($("#permission-sel-users"), true);
- $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked");
- sortNodes($("#permission-sel-groups"), false);
- $("#permission-sel-searchBox").val("");
- filterNodes("", $("#permission-sel-users"));
- filterNodes("", $("#permission-sel-groups"));
- });
- $('#permissionBack').button().click(function(evt) {
- evt.preventDefault();
- $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked");
- sortNodes($("#permission-avail-users"), true);
- $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked");
- sortNodes($("#permission-avail-groups"), false);
- $("#permission-avail-searchBox").val("");
- filterNodes("", $("#permission-avail-users"));
- filterNodes("", $("#permission-avail-groups"));
- });
- }
- var setupPCIDevice = function(){
- kimchi.getHostPCIDevices(function(hostPCIs){
- kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){
- var pciEnabled = kimchi.capabilities.kernel_vfio;
- for(var i=0; i<hostPCIs.length; i++){
- var itemNode = $.parseHTML(wok.substitute($('#pci-tmpl').html(),{
- name: hostPCIs[i].name,
- product: hostPCIs[i].product.description,
- vendor: hostPCIs[i].vendor.description
- }));
- $(".body", "#form-guest-edit-pci").append(itemNode);
- var iconClass = "ui-icon-plus";
- for(var j=0; j<vmPCIs.length; j++){
- if(hostPCIs[i].name==vmPCIs[j].name){
- iconClass = "ui-icon-minus";
- break;
- }
- }
- pciEnabled || $("button", itemNode).remove();
- $("button", itemNode).button({
- icons: { primary: iconClass },
- text: false
- }).click(function(){
- var obj = $(this);
- if(obj.button("option", "icons").primary == "ui-icon-minus"){
- kimchi.removeVMPCIDevice(kimchi.selectedGuest, obj.parent().prop("id"), function(){
- kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs1){
- for(var k=0; k<hostPCIs.length; k++) {
- $("button", "#" + hostPCIs[k].name).button("option", "icons", {primary: "ui-icon-plus"});
- }
- for(var k=0; k<vmPCIs1.length; k++) {
- $("button", "#" + vmPCIs1[k].name).button("option", "icons", {primary: "ui-icon-minus"});
- }
- });
- filterNodes($("select", "#form-guest-edit-pci").val(), $("input", "#form-guest-edit-pci").val());
- });
- } else {
- kimchi.addVMPCIDevice(kimchi.selectedGuest, { name: obj.parent().prop("id") }, function(){
- kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs1){
- for(var k=0; k<vmPCIs1.length; k++) {
- $("button", "#" + vmPCIs1[k].name).button("option", "icons", {primary: "ui-icon-minus"});
- }
- });
- filterNodes($("select", "#form-guest-edit-pci").val(), $("input", "#form-guest-edit-pci").val());
- });
- }
- });
- kimchi.getPCIDeviceCompanions(hostPCIs[i].name, function(infoData) {
- var pciTitle = i18n["KCHVMED6007M"] + "\n";
- var haveCompanions = false;
- for(var p=0; p<infoData.length; p++) {
- if(infoData[p].device_type === "net") {
- haveCompanions = true;
- pciTitle += " " + infoData[p].name + "\n";
- pciTitle += " " + i18n["KCHVMED6001M"] + " " + infoData[p].interface;
- pciTitle += ", " + i18n["KCHVMED6002M"] + " " + infoData[p].address;
- pciTitle += ", " + i18n["KCHVMED6003M"] + " " + infoData[p].link_type + "\n";
- } else if(infoData[p].device_type === "storage") {
- haveCompanions = true;
- pciTitle += " " + infoData[p].name + "\n";
- pciTitle += " " + i18n["KCHVMED6004M"] + " " + infoData[p].block;
- pciTitle += ", " + i18n["KCHVMED6005M"] + " " + infoData[p].drive_type;
- pciTitle += ", " + i18n["KCHVMED6006M"] + " " + infoData[p].model + "\n";
- }
- }
- for(var q=0; q<infoData.length; q++) {
- haveCompanions && $(".name", "#" + infoData[q].parent).attr("title", pciTitle);
- haveCompanions && $(".product", "#" + infoData[q].parent).attr("title", pciTitle);
- haveCompanions && $(".vendor", "#" + infoData[q].parent).attr("title", pciTitle);
- }
- });
- }
- });
- });
- var filterNodes = function(group, text){
- text = text.toLowerCase();
- $(".body", "#form-guest-edit-pci").children().each(function(){
- var textFilter = $(".name", this).text().toLowerCase().indexOf(text)!=-1;
- textFilter = textFilter || $(".product", this).text().toLowerCase().indexOf(text)!=-1;
- textFilter = textFilter || $(".vendor", this).text().toLowerCase().indexOf(text)!=-1;
- var display = "none";
- var itemGroup = $("button", this).button("option", "icons").primary;
- if(textFilter){
- if(group == "all"){
- display = "";
- }else if(group=="toAdd" && itemGroup=="ui-icon-plus"){
- display = ""
- }else if(group == "added" && itemGroup=="ui-icon-minus"){
- display = ""
- }
- }
- $(this).css("display", display);
- });
- };
- $("select", "#form-guest-edit-pci").change(function(){
- filterNodes($(this).val(), $("input", "#form-guest-edit-pci").val());
- });
- $("input", "#form-guest-edit-pci").on("keyup", function() {
- filterNodes($("select", "#form-guest-edit-pci").val(), $(this).val());
- });
- };
-
- var setupSnapshot = function() {
- var currentSnapshot;
- var setCurrentSnapshot = function(aSnapshot){
- if(!aSnapshot)
- kimchi.getCurrentSnapshot(kimchi.selectedGuest, function(snapshot){
- if(snapshot&&snapshot.name) aSnapshot = snapshot.name;
- }, null, true);
- if(aSnapshot){
- if(currentSnapshot) $(".ui-icon-check", "#"+currentSnapshot).addClass("hide");
- $(".ui-icon-check", "#"+aSnapshot).removeClass("hide");
- currentSnapshot = aSnapshot;
- }
- };
- var addItem = function(data, container) {
- var itemNode = $.parseHTML(wok.substitute($('#snapshot-tmpl').html(),data));
- $("."+container, "#form-guest-edit-snapshot").append(itemNode);
- $(".delete", itemNode).button({
- icons: { primary: "ui-icon-trash" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- $("button", "#form-guest-edit-snapshot").button("disable");
- kimchi.deleteSnapshot(kimchi.selectedGuest, item.prop("id"), function(){
- item.remove();
- setCurrentSnapshot();
- $("button", "#form-guest-edit-snapshot").button("enable");
- }, function(data){
- wok.message.error(data.responseJSON.reason);
- $("button", "#form-guest-edit-snapshot").button("enable");
- });
- });
- $(".revert", itemNode).button({
- icons: { primary: "ui-icon-arrowthick-1-ne" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- $(".ui-icon-check", item).addClass("hide");
- $(".icon", item).removeClass("hide");
- $("button", "#form-guest-edit-snapshot").button("disable");
- kimchi.revertSnapshot(kimchi.selectedGuest, item.prop("id"), function(){
- $(".icon", item).addClass("hide");
- $("button", "#form-guest-edit-snapshot").button("enable");
- setCurrentSnapshot(item.prop("id"));
- kimchi.listVmsAuto();
- wok.window.close();
- }, function(data){
- wok.message.error(data.responseJSON.reason);
- $(".icon", item).addClass("hide");
- $("button", "#form-guest-edit-snapshot").button("enable");
- });
- });
- };
- var addOngoingItem = function(task){
- var uri = task.target_uri;
- addItem({
- name: uri.substring(uri.lastIndexOf('/')+1, uri.length),
- created: "",
- listMode: "hide",
- createMode: ""
- }, 'task');
- if(kimchi.trackingTasks.indexOf(task.id)==-1)
- kimchi.trackTask(task.id, function(task){
- listGeneratingSnapshots();
- $("button", "#form-guest-edit-snapshot").button("enable");
- }, function(err){
- wok.message.error(err.message);
- listGeneratingSnapshots();
- $("button", "#form-guest-edit-snapshot").button("enable");
- });
- };
- var listGeneratingSnapshots = function(){
- kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/snapshots/*'), function(tasks) {
- $(".task", "#form-guest-edit-snapshot").empty();
- for(var i=0;i<tasks.length;i++){
- addOngoingItem(tasks[i]);
- }
- if(tasks.length==0) listSnapshots();
- });
- };
- var listSnapshots = function(){
- kimchi.listSnapshots(kimchi.selectedGuest, function(data){
- $(".body", "#form-guest-edit-snapshot").empty();
- for(var i=0;i<data.length;i++){
- data[i].created = new Date(data[i].created*1000).toLocaleString();
- data[i].createMode = "hide";
- data[i].listMode = "";
- addItem(data[i], 'body');
- }
- setCurrentSnapshot();
- });
- };
- listGeneratingSnapshots();
- $(".add", "#form-guest-edit-snapshot").button({
- icons: { primary: "ui-icon-plusthick" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- kimchi.createSnapshot(kimchi.selectedGuest, function(task){
- $("button", "#form-guest-edit-snapshot").button("disable");
- addOngoingItem(task);
- });
- });
- if(kimchi.thisVMState=="running") $("button", "#form-guest-edit-snapshot").remove();
- };
-
- var initContent = function(guest) {
- guest['icon'] = guest['icon'] || 'plugins/kimchi/images/icon-vm.png';
- $('#form-guest-edit-general').fillWithObject(guest);
- kimchi.thisVMState = guest['state'];
- refreshCDROMs();
- $('#guest-edit-attach-cdrom-button').button({
- icons: {
- primary: "ui-icon-plusthick"
- },
- text: false
- }).click(function(event) {
- event.preventDefault();
- wok.window.open("plugins/kimchi/guest-storage-add.html");
- });
- if(kimchi.thisVMState === "running") {
- $("#form-guest-edit-general input").prop("disabled", true);
- } else {
- $("#action-button-container").removeClass("hidden");
- }
-
- var onAttached = function(params) {
- refreshCDROMs();
- };
- var onReplaced = function(params) {
- refreshCDROMs();
- };
- var onDetached = function(params) {
- refreshCDROMs();
- };
-
- initStorageListeners();
- setupInterface();
- setupPermission();
- setupPCIDevice();
- setupSnapshot();
-
- wok.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
- wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
- wok.topic('kimchi/vmCDROMDetached').subscribe(onDetached);
-
- kimchi.clearGuestEdit = function() {
- wok.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached);
- wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
- wok.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached);
- };
- };
-
- kimchi.retrieveVM(kimchi.selectedGuest, initContent);
-
- var generalSubmit = function(event) {
- $(saveButton).prop('disabled', true);
- var data=$('#form-guest-edit-general').serializeObject();
- if(data['memory']!=undefined) {
- data['memory'] = Number(data['memory']);
- }
- if(data['cpus']!=undefined) {
- data['cpus'] = Number(data['cpus']);
- }
-
- kimchi.updateVM(kimchi.selectedGuest, data, function() {
- kimchi.listVmsAuto();
- wok.window.close();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $(saveButton).prop('disabled', false);
- });
- }
-
- var permissionSubmit = function(event) {
- var content = { users: [], groups: [] };
- authType = kimchi.capabilities['auth']
- if (authType == 'pam') {
- $("#permission-sel-users").children().each(function(){
- content.users.push($("label", this).text());
- });
- $("#permission-sel-groups").children().each(function(){
- content.groups.push($("label", this).text());
- });
- kimchi.updateVM(kimchi.selectedGuest, content, function(){
- wok.window.close();
- });
- } else if (authType == 'ldap') {
- $(saveButton).prop('disabled', true);
- var errors = 0;
-
- $(".body", "#form-guest-edit-permission .ldap").children().each(function () {
- var elem = $(this);
- content.users.push(elem.attr("id"));
-
- if (!$('input', elem).hasClass('hide')) {
- var user = {'user_id': $(this).attr("id")};
- kimchi.getUserById(user, null, function (data) {
- errors += 1;
- $("input", elem).addClass("checked");
- });
- }
- });
- if (errors == 0) {
- kimchi.updateVM(kimchi.selectedGuest, content, function(){
- wok.window.close();
- });
- } else {
- $(saveButton).prop('disabled', false);
- }
- }
- }
-
- // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "password": 4
- var submit_map = {0: generalSubmit, 3:permissionSubmit};
- var submitForm = function(event) {
- var current = $('#guest-edit-tabs').tabs( "option", "active" );
- var submitFun = submit_map[current];
- submitFun && submitFun(event);
- event.preventDefault();
- };
-
- $(guestEditForm).on('submit', submitForm);
- $(saveButton).on('click', submitForm);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_main.js b/plugins/kimchi/ui/js/src/kimchi.guest_main.js
deleted file mode 100644
index 7dd5d84..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_main.js
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-kimchi.sampleGuestObject = {
- "name": "",
- "uuid": "",
- "state": "shutoff",
- "persistent": true,
- "icon": null,
- "cpus": 0,
- "memory": 0,
- "stats": {
- "net_throughput": 0,
- "io_throughput_peak": 100,
- "cpu_utilization": 0,
- "io_throughput": 0,
- "net_throughput_peak": 100
- },
- "screenshot": null,
- "graphics": {
- "passwd": null,
- "passwdValidTo": null,
- "type": "vnc",
- "port": null,
- "listen": "127.0.0.1"
- },
- "users": [],
- "groups": [],
- "access": "full"
-};
-
-kimchi.vmstart = function(event) {
- var button=$(this);
- if (!button.hasClass('loading')) {
- button.addClass('loading');
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.startVM(vm_id, function(result) {
- button.removeClass('loading');
- kimchi.listVmsAuto();
- }, function(err) {
- button.removeClass('loading');
- wok.message.error(err.responseJSON.reason);
- }
- );
- } else {
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-};
-
-kimchi.vmsuspend = function(event) {
- var button=$(this);
- if (!button.hasClass('pause-gray')) {
- button.addClass('pause-gray');
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.suspendVM(vm_id, function(result) {
- button.removeClass('pause-gray');
- kimchi.listVmsAuto();
- }, function(err) {
- button.removeClass('pause-gray');
- wok.message.error(err.responseJSON.reason);
- }
- );
- } else {
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-};
-
-kimchi.vmresume = function(event) {
- var button=$(this);
- if (!button.hasClass('resume-gray')) {
- button.addClass('resume-gray');
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.resumeVM(vm_id, function(result) {
- button.removeClass('resume-gray');
- kimchi.listVmsAuto();
- }, function(err) {
- button.removeClass('resume-gray');
- wok.message.error(err.responseJSON.reason);
- }
- );
- } else {
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-};
-
-kimchi.vmpoweroff = function(event) {
- var button=$(this);
- if (!button.hasClass('loading')) {
- button.addClass('loading');
- var vm=button.closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var vmObject=vm.data();
- var vm_persistent=vmObject.persistent == true;
- var content_msg = vm_persistent ? i18n['KCHVM6003M'] :
- i18n['KCHVM6009M'];
- var settings = {
- title : i18n['KCHVM6002M'],
- content : content_msg,
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.poweroffVM(vm_id, function(result) {
- button.removeClass('loading');
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- });
- } else {
- event.preventDefault();
- event.stopPropagation();
- }
-};
-
-kimchi.vmshutdown = function(event){
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var settings = {
- title : i18n['KCHVM6006M'],
- content : i18n['KCHVM6007M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.shutdownVM(vm_id, function(result) {
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- }
- );
- }, function() {
- });
-};
-
-kimchi.vmreset = function(event){
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var settings = {
- title : i18n['KCHVM6004M'],
- content : i18n['KCHVM6005M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.resetVM(vm_id, function(result) {
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- }
- );
- }, function() {
- });
-};
-
-kimchi.vmdelete = function(event) {
- var vm = $(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var settings = {
- title : i18n['KCHVM6008M'],
- content : i18n['KCHVM6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.deleteVM(vm_id, function(result) {
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- });
-};
-
-kimchi.vmedit = function(event) {
- var vm = $(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.selectedGuest = vm_id;
- wok.window.open({
- url: 'plugins/kimchi/guest-edit.html',
- close: function() {
- kimchi.clearGuestEdit();
- }
- });
-};
-
-kimchi.openVmConsole = function(event) {
- var vm=$(this).closest('li[name=guest]');
- var vmObject=vm.data();
- if (vmObject.graphics['type'] == 'vnc') {
- kimchi.vncToVM(vm.attr('id'));
- }
- else if (vmObject.graphics['type'] == 'spice') {
- kimchi.spiceToVM(vm.attr('id'));
- }
-
-};
-
-kimchi.getVmsCurrentConsoleImgs = function() {
- var res = new Object();
- $('#guestList').children().each(function() {
- res[$(this).attr('id')] = $(this).find('img.imgactive').attr('src');
- })
- return res;
-};
-
-kimchi.getOpenMenuVmId = function() {
- var result;
- var openMenu = $('#guestList div[name="actionmenu"] .popover:visible');
- if(openMenu) {
- var li_element=openMenu.closest('li');
- result=li_element.attr('id');
- }
- return result;
-};
-
-kimchi.listVmsAuto = function() {
- if (kimchi.vmTimeout) {
- clearTimeout(kimchi.vmTimeout);
- }
- var getCreatingGuests = function(){
- var guests = [];
- kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/[^/]+$'), function(tasks) {
- for(var i=0;i<tasks.length;i++){
- var guestUri = tasks[i].target_uri;
- var guestName = guestUri.split('/')[2]
- guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName, isCreating: true}));
- if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
- kimchi.trackTask(tasks[i].id, null, function(err){
- wok.message.error(err.message);
- }, null);
- }
- }, null, true);
- return guests;
- };
- var getCloningGuests = function(){
- var guests = [];
- kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/.+/clone'), function(tasks) {
- for(var i=0;i<tasks.length;i++){
- var guestUri = tasks[i].target_uri;
- var guestName = guestUri.split('/')[2]
- guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName, isCloning: true}));
- if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
- kimchi.trackTask(tasks[i].id, null, function(err){
- wok.message.error(err.message);
- }, null);
- }
- }, null, true);
- return guests;
- };
- kimchi.listVMs(function(result, textStatus, jqXHR) {
- if (result && textStatus=="success") {
- result = getCloningGuests().concat(result);
- result = getCreatingGuests().concat(result);
- if(result.length) {
- var listHtml = '';
- var guestTemplate = kimchi.guestTemplate;
- var currentConsoleImages = kimchi.getVmsCurrentConsoleImgs();
- var openMenuGuest = kimchi.getOpenMenuVmId();
- $('#guestList').empty();
- $('#guestListField').show();
- $('#noGuests').hide();
-
- $.each(result, function(index, vm) {
- var guestLI = kimchi.createGuestLi(vm, currentConsoleImages[vm.name], vm.name==openMenuGuest);
- $('#guestList').append(guestLI);
- });
- } else {
- $('#guestListField').hide();
- $('#noGuests').show();
- }
- }
-
- kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
- }, function(errorResponse, textStatus, errorThrown) {
- if(errorResponse.responseJSON && errorResponse.responseJSON.reason) {
- wok.message.error(errorResponse.responseJSON.reason);
- }
- kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
- });
-};
-
-kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
- var result=kimchi.guestElem.clone();
-
- //Setup the VM list entry
- var vmRunningBool=(vmObject.state=="running");
- var vmSuspendedBool = (vmObject.state=="paused");
- var vmPoweredOffBool = (vmObject.state=="shutoff");
- var vmPersistent = (vmObject.persistent == true);
- result.attr('id',vmObject.name);
- result.data(vmObject);
-
- //Add the Name
- var guestTitle=result.find('.title').attr('title',vmObject.name);
- guestTitle.html(vmObject.name);
-
- //Setup the VM console thumbnail display
- var curImg = vmObject.icon;
- if (vmObject.screenshot) {
- curImg = vmObject.screenshot.replace(/^\//,'');
- }
- var load_src = curImg || 'plugins/kimchi/images/icon-vm.png';
- var tile_src = prevScreenImage || vmObject['load-src'];
- var liveTile=result.find('div[name=guest-tile] > .tile');
- liveTile.addClass(vmObject.state);
- liveTile.find('.imgactive').attr('src',tile_src);
- var imgLoad=liveTile.find('.imgload');
- imgLoad.on('load', function() {
- var oldImg=$(this).parent().find('.imgactive');
- oldImg.removeClass("imgactive").addClass("imgload");
- oldImg.attr("src","");
- $(this).addClass("imgactive").removeClass("imgload");
- $(this).off('load');
- });
- imgLoad.attr('src',load_src);
-
- //Link the stopped tile to the start action, the running tile to open the console, and the paused tile to resume
- if(!(vmObject.isCloning || vmObject.isCreating)){
- if (vmPoweredOffBool) {
- liveTile.off("click", kimchi.openVmConsole);
- liveTile.off("click", kimchi.vmresume);
- liveTile.on("click", kimchi.vmstart);
- liveTile.hover(function(event){$(this).find('.overlay').show()}, function(event){$(this).find('.overlay').hide()});
- } else if (vmSuspendedBool) {
- liveTile.off("click", kimchi.vmstart);
- liveTile.off("click", kimchi.openVmConsole);
- liveTile.on("click", kimchi.vmresume);
- if(vmObject.state="paused") {
- liveTile.find('.overlay').attr('src',"plugins/kimchi/images/theme-default/ac24_resume.png");
- liveTile.find('.overlay').attr('alt',"Resume");
- }
- liveTile.hover(function(event){$(this).find('.overlay').show()}, function(event){$(this).find('.overlay').hide()});
- } else {
- liveTile.off("click", kimchi.vmstart);
- liveTile.off("click", kimchi.vmresume);
- liveTile.on("click", kimchi.openVmConsole);
- }
- }
-
- //Setup the gauges
- var stats=vmObject.stats;
- var gaugeValue=0;
- gaugeValue=parseInt(stats.net_throughput);
- kimchi.circleGaugeInit(result, "net_throughput",gaugeValue,(gaugeValue*100/stats.net_throughput_peak));
- gaugeValue=parseInt(stats.io_throughput);
- kimchi.circleGaugeInit(result, "io_throughput",gaugeValue,(gaugeValue*100/stats.io_throughput_peak));
- gaugeValue=parseInt(stats.cpu_utilization);
- kimchi.circleGaugeInit(result, "cpu_utilization",gaugeValue+"%",gaugeValue);
-
- //Setup the VM Actions
- var guestActions=result.find("div[name=guest-actions]");
- guestActions.find(".shutoff-disabled").prop("disabled", !vmRunningBool);
- guestActions.find(".running-disabled").prop("disabled", vmRunningBool);
- guestActions.find(".non-persistent-disabled").prop("disabled", !vmPersistent);
- guestActions.find(".reset-disabled").prop("disabled", vmPoweredOffBool || !vmPersistent);
- guestActions.find(".pause-disabled").prop("disabled", vmPoweredOffBool || !vmPersistent);
-
- if (vmSuspendedBool) { //VM is paused
- //Hide Start
- guestActions.find(".running-hidden").hide();
- //Hide Pause button and menu
- guestActions.find(".pause-disabled").hide();
- guestActions.find(".pause-hidden").hide();
- }
-
- if (vmRunningBool) { //VM IS running
- //Hide Start
- guestActions.find(".running-hidden").hide();
- //Hide Resume
- guestActions.find(".resume-hidden").hide();
- }
-
- if (vmPoweredOffBool) { //VM is powered off
- //Hide PowerOff
- guestActions.find(".shutoff-hidden").hide();
- //Hide Pause
- guestActions.find(".pause-hidden").hide();
- //Hide Resume
- guestActions.find(".resume-hidden").hide();
- }
-
- var consoleActions=guestActions.find("[name=vm-console]");
-
- if ((vmObject.graphics['type'] == 'vnc') || (vmObject.graphics['type'] == 'spice')) {
- consoleActions.on("click", kimchi.openVmConsole);
- consoleActions.show();
- } else { //we don't recognize the VMs supported graphics, so hide the menu choice
- consoleActions.hide();
- consoleActions.off("click",kimchi.openVmConsole);
- }
-
- //Setup action event handlers
- if(!(vmObject.isCloning || vmObject.isCreating)){
- guestActions.find("[name=vm-start]").on({click : kimchi.vmstart});
- guestActions.find("[name=vm-poweroff]").on({click : kimchi.vmpoweroff});
- if ((vmRunningBool) || (vmSuspendedBool)) {
- //If the guest is not running, do not enable reset; otherwise, reset is enabled (when running or paused)
- guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset});
-
- //If the guest is not running, do not enable shutdown;otherwise, shutdown is enabled (when running or paused)
- guestActions.find("[name=vm-shutdown]").on({click : kimchi.vmshutdown});
- }
-
- if (vmSuspendedBool) {
- guestActions.find("[name=vm-resume]").on({click : kimchi.vmresume});
- }
-
- if (vmRunningBool) {
- guestActions.find("[name=vm-pause]").on({click : kimchi.vmsuspend});
- }
-
- guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit});
- guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
- guestActions.find("[name=vm-clone]").click(function(){
- var guest = $(this).closest('li[name=guest]').attr("id");
- wok.confirm({
- title : i18n['KCHAPI6006M'],
- content : i18n['KCHVM6010M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- }, function() {
- kimchi.cloneGuest(guest, function(data){
- kimchi.listVmsAuto();
- });
- }, null);
- });
-
- //Maintain menu open state
- var actionMenu=guestActions.find("div[name=actionmenu]");
- if (openMenu) {
- $('.popover', actionMenu).toggle();
- }
-
- }else{
- guestActions.find('.btn').attr('disabled', true);
- $('.popover', guestActions.find("div[name=actionmenu]")).remove();
-
- result.find('.guest-pending').removeClass('hide-content');
- pendingText = result.find('.guest-pending .text')
- if(vmObject.isCloning)
- pendingText.text(i18n['KCHAPI6009M']);
- else
- pendingText.text(i18n['KCHAPI6008M']);
- }
-
- return result;
-};
-
-kimchi.circleGaugeInit = function(topElement, divName, display, percentage){
- var gauge=topElement.find('div[name="' + divName + '"] .circleGauge');
- if(gauge) {
- var data=Object();
- data.percentage = percentage;
- data.display = display;
- gauge.data(data);
- }
- gauge.circleGauge();
- return(gauge);
-};
-
-kimchi.guestSetRequestHeader = function(xhr) {
- xhr.setRequestHeader('Accept', 'text/html');
-};
-
-kimchi.guest_main = function() {
- if(wok.tabMode['guests'] === 'admin') {
- $('.tools').attr('style','display');
- $("#vm-add").on("click", function(event) {
- wok.window.open('plugins/kimchi/guest-add.html');
- });
- }
- kimchi.guestTemplate = $('#guest-tmpl').html();
- kimchi.guestElem=$('<div/>').html(kimchi.guestTemplate).find('li');
- $('#guests-root-container').on('remove', function() {
- kimchi.vmTimeout && clearTimeout(kimchi.vmTimeout);
- });
- kimchi.listVmsAuto()
-};
-
-kimchi.editTemplate = function(guestTemplate, oldPopStat) {
- if (oldPopStat) {
- return guestTemplate.replace("vm-action", "vm-action open");
- }
- return guestTemplate;
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js b/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
deleted file mode 100644
index b920527..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.guest_media_main = function() {
-
- var refreshCDROMs = function() {
- kimchi.listVMStorages({
- vm: kimchi.selectedGuest,
- storageType: 'cdrom'
- }, function(storages) {
- var rowHTML = $('#cdrom-row-tmpl').html();
- var container = $('#guest-edit-cdrom-row-container');
- $(container).empty();
-
- $.each(storages, function(index, storage) {
- storage['vm'] = kimchi.selectedGuest;
- var templated = wok.substitute(rowHTML, storage);
- container.append(templated);
- });
-
- var replaceCDROM = function(event) {
- event.preventDefault();
- kimchi.selectedGuestStorage = $(this).data('dev');
- wok.window.open("plugins/kimchi/guest-cdrom-edit.html");
- };
-
- $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM);
- $('.replace', container).on('click', replaceCDROM);
- });
- };
-
- refreshCDROMs();
-
- var onReplaced = function(params) {
- refreshCDROMs();
- };
- wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
-
- kimchi.clearGuestMedia = function() {
- wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
- };
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js b/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
deleted file mode 100644
index bc162e8..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-kimchi.guest_storage_add_main = function() {
- var types = [{
- label: 'cdrom',
- value: 'cdrom',
- },
- {
- label: 'disk',
- value: 'disk',
- }];
- var typesRunning = [{
- label: 'disk',
- value: 'disk'
- }];
-
- var storageAddForm = $('#form-guest-storage-add');
- var submitButton = $('#guest-storage-button-add');
- var typeTextbox = $('input[name="type"]', storageAddForm);
- var pathTextbox = $('input[name="path"]', storageAddForm);
- var poolTextbox = $('input[name="pool"]', storageAddForm);
- var volTextbox = $('input[name="vol"]', storageAddForm);
-
- typeTextbox.change(function() {
- var pathObject = {'cdrom': ".path-section", 'disk': '.volume-section'}
- selectType = $(this).val();
- $.each(pathObject, function(type, value) {
- if(selectType == type){
- $(value).removeClass('hidden');
- } else {
- $(value).addClass('hidden');
- }
- });
-
- if ($(".path-section").hasClass('hidden')) {
- $(poolTextbox).val('default');
- $(poolTextbox).change();
- $(pathTextbox).val("");
- }
- else {
- $(poolTextbox).val("");
- $(volTextbox).val("");
- }
- });
-
- kimchi.listStoragePools(function(result) {
- var options = [];
- if (result && result.length) {
- $.each(result, function(index, storagePool) {
- if ((storagePool.state=="active") && (storagePool.type !== 'kimchi-iso')) {
- options.push({
- label: storagePool.name,
- value: storagePool.name
- });
- }
- });
- wok.select('guest-add-storage-pool-list', options);
- }
- });
-
- poolTextbox.change(function() {
- var options = [];
- kimchi.listStorageVolumes($(this).val(), function(result) {
- var validVolType = { cdrom: /iso/, disk: /^(raw|qcow|qcow2|bochs|qed|vmdk)$/};
- $('#guest-disk').selectMenu();
- if (result.length) {
- $.each(result, function(index, value) {
- // Only unused volume can be attached
- if (value.used_by.length == 0 && (value.type != 'file' || validVolType[selectType].test(value.format))) {
- options.push({
- label: value.name,
- value: value.name
- });
- }
- });
- if (options.length) {
- $(volTextbox).val(options[0].value);
- $(volTextbox).change();
- }
- }
- $('#guest-disk').selectMenu("setData", options);
- });
- });
-
-
- typeTextbox.change(function() {
- var pathObject = {'cdrom': ".path-section", 'disk': '.volume-section'}
- var selectType = $(this).val();
- $.each(pathObject, function(type, value) {
- if(selectType == type){
- $(value).removeClass('hidden');
- } else {
- $(value).addClass('hidden');
- }
- });
- });
-
- if (kimchi.thisVMState === 'running') {
- types =typesRunning;
- $(typeTextbox).val('disk');
- typeTextbox.change();
- poolTextbox.change();
- }
- var selectType = $(typeTextbox).val();
- wok.select('guest-storage-type-list', types);
-
- var validateCDROM = function(settings) {
- if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path']))
- return true;
- else {
- wok.message.error.code('KCHVMSTOR0001E');
- return false;
- }
- }
-
- var validateDisk = function(settings) {
- if (settings['pool'] && settings['vol'])
- return true;
- else {
- wok.message.error.code('KCHVMSTOR0002E');
- return false;
- }
- }
-
- validator = {cdrom: validateCDROM, disk: validateDisk};
- var submitForm = function(event) {
- if (submitButton.prop('disabled')) {
- return false;
- }
-
- var formData = storageAddForm.serializeObject();
- var settings = {
- vm: kimchi.selectedGuest,
- type: typeTextbox.val(),
- };
-
- $(submitButton).prop('disabled', true);
- $.each([pathTextbox, poolTextbox, volTextbox], function(i, c) {
- $(c).prop('disabled', true);
- val = $(c).val()
- if (val && val != '') {
- settings[$(c).attr('name')] = $(c).val();
- }
- });
- // Validate form for cdrom and disk
- validateSpecifiedForm = validator[settings['type']];
- if (!validateSpecifiedForm(settings)) {
- $(submitButton).prop('disabled', false);
- $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c) {
- $(c).prop('disabled', false);
- });
- return false;
- }
- $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']);
-
- kimchi.addVMStorage(settings, function(result) {
- wok.window.close();
- wok.topic('kimchi/vmCDROMAttached').publish({
- result: result
- });
- }, function(result) {
- var errText = result['reason'] ||
- result['responseJSON']['reason'];
- wok.message.error(errText);
-
- $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c) {
- $(c).prop('disabled', false);
- });
- $(submitButton).removeClass('loading').text(i18n['KCHVMCD6002M']);
- });
-
- event.preventDefault();
- };
-
- storageAddForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
- pathTextbox.on('change input propertychange', function(event) {
- $(submitButton).prop('disabled', $(this).val() === '');
- });
- volTextbox.on('change propertychange', function (event) {
- $(submitButton).prop('disabled', $(this).val() === '');
- });
-
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.host.js b/plugins/kimchi/ui/js/src/kimchi.host.js
deleted file mode 100644
index e2d2511..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.host.js
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.host={};
-
-kimchi.host_main = function() {
- var expand = function(header, toExpand) {
- var controlledNode = $(header).attr('aria-controls');
- $('#' + controlledNode)[toExpand ? 'removeClass' : 'addClass']('hidden');
- $(header).attr('aria-expanded', toExpand ? 'true' : 'false');
- };
-
- var repositoriesGrid = null;
- var initRepositoriesGrid = function(repo_type) {
- var gridFields=[];
- if (repo_type == "yum") {
- gridFields=[{
- name: 'repo_id',
- label: i18n['KCHREPO6004M'],
- 'class': 'repository-id'
- }, {
- name: 'config[repo_name]',
- label: i18n['KCHREPO6005M'],
- 'class': 'repository-name'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled'
- }];
- }
- else if (repo_type == "deb") {
- gridFields=[{
- name: 'baseurl',
- label: i18n['KCHREPO6006M'],
- makeTitle: true,
- 'class': 'repository-baseurl deb'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled deb'
- }, {
- name: 'config[dist]',
- label: "dist",
- 'class': 'repository-gpgcheck deb'
- }, {
- name: 'config[comps]',
- label: "comps",
- 'class': 'repository-gpgcheck deb'
- }];
- }
- else {
- gridFields=[{
- name: 'repo_id',
- label: i18n['KCHREPO6004M'],
- 'class': 'repository-id'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled'
- }, {
- name: 'baseurl',
- label: i18n['KCHREPO6006M'],
- makeTitle: true,
- 'class': 'repository-baseurl'
- }];
- }
- repositoriesGrid = new wok.widget.Grid({
- container: 'repositories-grid-container',
- id: 'repositories-grid',
- title: i18n['KCHREPO6003M'],
- toolbarButtons: [{
- id: 'repositories-grid-add-button',
- label: i18n['KCHREPO6012M'],
- onClick: function(event) {
- wok.window.open({url:'plugins/kimchi/repository-add.html',
- class: repo_type});
- }
- }, {
- id: 'repositories-grid-enable-button',
- label: i18n['KCHREPO6016M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- var name = repository['repo_id'];
- var enable = !repository['enabled'];
- $(this).prop('disabled', true);
- kimchi.enableRepository(name, enable, function() {
- wok.topic('kimchi/repositoryUpdated').publish();
- });
- }
- }, {
- id: 'repositories-grid-edit-button',
- label: i18n['KCHREPO6013M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- kimchi.selectedRepository = repository['repo_id'];
- wok.window.open({url:'plugins/kimchi/repository-edit.html',
- class: repo_type});
- }
- }, {
- id: 'repositories-grid-remove-button',
- label: i18n['KCHREPO6014M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
-
- var settings = {
- title : i18n['KCHREPO6001M'],
- content : i18n['KCHREPO6002M'],
- confirm : i18n['KCHAPI6004M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.deleteRepository(
- repository['repo_id'],
- function(result) {
- wok.topic('kimchi/repositoryDeleted').publish(result);
- }, function(error) {
- }
- );
- });
- }
- }],
- onRowSelected: function(row) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- $('#repositories-grid-remove-button').prop('disabled', false);
- $('#repositories-grid-edit-button').prop('disabled', false);
- var enabled = repository['enabled'];
- $('#repositories-grid-enable-button')
- .text(i18n[enabled ? 'KCHREPO6017M' : 'KCHREPO6016M'])
- .prop('disabled', false);
- },
- frozenFields: [],
- fields: gridFields,
- data: listRepositories
- });
- };
-
- var listRepositories = function(gridCallback) {
- kimchi.listRepositories(function(repositories) {
- if($.isFunction(gridCallback)) {
- gridCallback(repositories);
- }
- else {
- if(repositoriesGrid) {
- repositoriesGrid.setData(repositories);
- }
- else {
- initRepositoriesGrid();
- repositoriesGrid.setData(repositories);
- }
- }
- },
- function(error) {
- var message = error && error['responseJSON'] && error['responseJSON']['reason'];
-
- if($.isFunction(gridCallback)) {
- gridCallback([]);
- }
- repositoriesGrid &&
- repositoriesGrid.showMessage(message || i18n['KCHUPD6008M']);
- });
-
- $('#repositories-grid-remove-button').prop('disabled', true);
- $('#repositories-grid-edit-button').prop('disabled', true);
- $('#repositories-grid-enable-button').prop('disabled', true);
- };
-
- var softwareUpdatesGridID = 'software-updates-grid';
- var softwareUpdatesGrid = null;
- var progressAreaID = 'software-updates-progress-textarea';
- var reloadProgressArea = function(result) {
- var progressArea = $('#' + progressAreaID)[0];
- $(progressArea).text(result['message']);
- var scrollTop = $(progressArea).prop('scrollHeight');
- $(progressArea).prop('scrollTop', scrollTop);
- };
-
- var initSoftwareUpdatesGrid = function(softwareUpdates) {
- softwareUpdatesGrid = new wok.widget.Grid({
- container: 'software-updates-grid-container',
- id: softwareUpdatesGridID,
- title: i18n['KCHUPD6001M'],
- rowSelection: 'disabled',
- toolbarButtons: [{
- id: softwareUpdatesGridID + '-update-button',
- label: i18n['KCHUPD6006M'],
- disabled: true,
- onClick: function(event) {
- var updateButton = $(this);
- var progressArea = $('#' + progressAreaID)[0];
- $('#software-updates-progress-container').removeClass('hidden');
- $(progressArea).text('');
- !wok.isElementInViewport(progressArea) &&
- progressArea.scrollIntoView();
- $(updateButton).text(i18n['KCHUPD6007M']).prop('disabled', true);
-
- kimchi.updateSoftware(function(result) {
- reloadProgressArea(result);
- $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
- wok.topic('kimchi/softwareUpdated').publish({
- result: result
- });
- }, function(error) {
- var message = error && error['responseJSON'] && error['responseJSON']['reason'];
- wok.message.error(message || i18n['KCHUPD6009M']);
- $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
- }, reloadProgressArea);
- }
- }],
- frozenFields: [],
- fields: [{
- name: 'package_name',
- label: i18n['KCHUPD6002M'],
- 'class': 'software-update-name'
- }, {
- name: 'version',
- label: i18n['KCHUPD6003M'],
- 'class': 'software-update-version'
- }, {
- name: 'arch',
- label: i18n['KCHUPD6004M'],
- 'class': 'software-update-arch'
- }, {
- name: 'repository',
- label: i18n['KCHUPD6005M'],
- 'class': 'software-update-repos'
- }],
- data: listSoftwareUpdates
- });
- };
-
- var listSoftwareUpdates = function(gridCallback) {
- kimchi.listSoftwareUpdates(function(softwareUpdates) {
- if($.isFunction(gridCallback)) {
- gridCallback(softwareUpdates);
- }
- else {
- if(softwareUpdatesGrid) {
- softwareUpdatesGrid.setData(softwareUpdates);
- }
- else {
- initSoftwareUpdatesGrid(softwareUpdates);
- }
- }
-
- var updateButton = $('#' + softwareUpdatesGridID + '-update-button');
- $(updateButton).prop('disabled', softwareUpdates.length === 0);
- }, function(error) {
- var message = error && error['responseJSON'] && error['responseJSON']['reason'];
- if($.isFunction(gridCallback)) {
- gridCallback([]);
- }
- softwareUpdatesGrid &&
- softwareUpdatesGrid.showMessage(message || i18n['KCHUPD6008M']);
- });
- };
-
- var reportGridID = 'available-reports-grid';
- var reportGrid = null;
- var enableReportButtons = function(toEnable) {
- var buttonID = '#{grid}-{btn}-button';
- $.each(['rename', 'remove', 'download'], function(i, n) {
- $(wok.substitute(buttonID, {
- grid: reportGridID,
- btn: n
- })).prop('disabled', !toEnable);
- });
- };
- var initReportGrid = function(reports) {
- reportGrid = new wok.widget.Grid({
- container: 'available-reports-grid-container',
- id: reportGridID,
- title: i18n['KCHDR6002M'],
- toolbarButtons: [{
- id: reportGridID + '-generate-button',
- label: i18n['KCHDR6006M'],
- onClick: function(event) {
- wok.window.open('plugins/kimchi/report-add.html');
- }
- }, {
- id: reportGridID + '-rename-button',
- label: i18n['KCHDR6008M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- kimchi.selectedReport = report['name'];
- wok.window.open('plugins/kimchi/report-rename.html');
- }
- }, {
- id: reportGridID + '-remove-button',
- label: i18n['KCHDR6009M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHDR6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.deleteReport({
- name: report['name']
- }, function(result) {
- listDebugReports();
- }, function(error) {
- wok.message.error(error.responseJSON.reason);
- });
- });
- }
- }, {
- id: reportGridID + '-download-button',
- label: i18n['KCHDR6010M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- kimchi.downloadReport({
- file: report['uri']
- });
- }
- }],
- onRowSelected: function(row) {
- var report = reportGrid.getSelected();
- // Only enable report buttons if the selected line is not a
- // pending report
- if (report['time'] == i18n['KCHDR6007M']) {
- var gridElement = $('#'+ reportGridID);
- var row = $('tr:contains(' + report['name'] + ')', gridElement);
- enableReportButtons(false);
- row.attr('class', '');
- }
- else {
- enableReportButtons(true);
- }
- },
- frozenFields: [],
- fields: [{
- name: 'name',
- label: i18n['KCHDR6003M'],
- 'class': 'debug-report-name'
- }, {
- name: 'time',
- label: i18n['KCHDR6005M'],
- 'class': 'debug-report-time'
- }],
- data: reports
- });
- };
-
- var getPendingReports = function() {
- var reports = []
- var filter = 'status=running&target_uri=' + encodeURIComponent('^/plugins/kimchi/debugreports/*')
-
- kimchi.getTasksByFilter(filter, function(tasks) {
- for(var i = 0; i < tasks.length; i++) {
- reportName = tasks[i].target_uri.replace(/^\/plugins\/kimchi\/debugreports\//, '') || i18n['KCHDR6012M'];
- reports.push({'name': reportName, 'time': i18n['KCHDR6007M']})
-
- if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
- continue;
- }
-
- kimchi.trackTask(tasks[i].id, function(result) {
- wok.topic('kimchi/debugReportAdded').publish();
- }, function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
- wok.topic('kimchi/debugReportAdded').publish();
- }, null);
- }
- }, null, true);
-
- return reports;
- };
-
- var listDebugReports = function() {
- kimchi.listReports(function(reports) {
- pendingReports = getPendingReports();
- allReports = pendingReports.concat(reports);
- $('#debug-report-section').removeClass('hidden');
-
- // Row selection will be cleared so disable buttons here
- enableReportButtons(false);
-
- if(reportGrid) {
- reportGrid.setData(allReports);
- }
- else {
- initReportGrid(allReports);
- }
-
- // Set id-debug-img to pending reports
- // It will display a loading icon
- var gridElement = $('#' + reportGridID);
- $.each($('td:contains(' + i18n['KCHDR6007M'] + ')', gridElement), function(index, row) {
- $(row).parent().addClass('no-hover');
- $(row).attr('id', 'id-debug-img');
- });
- }, function(error) {
- if(error['status'] == 403) {
- $('#debug-report-section').addClass('hidden');
- return;
- }
- $('#debug-report-section').removeClass('hidden');
- });
- };
-
- var shutdownButtonID = '#host-button-shutdown';
- var restartButtonID = '#host-button-restart';
- var shutdownHost = function(params) {
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHHOST6008M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.shutdown(params);
- $(shutdownButtonID).prop('disabled', true);
- $(restartButtonID).prop('disabled', true);
- // Check if there is any VM is running.
- kimchi.listVMs(function(vms) {
- for(var i = 0; i < vms.length; i++) {
- if(vms[i]['state'] === 'running') {
- wok.message.error.code('KCHHOST6001E');
- $(shutdownButtonID).prop('disabled', false);
- $(restartButtonID).prop('disabled', false);
- return;
- }
- }
-
- });
- }, function() {
- });
- };
-
- var initPage = function() {
- $('#host-info-container .section-header').each(function(i, header) {
- $('<span class="arrow"></span>').prependTo(header);
- var toExpand = $(header).attr('aria-expanded') !== 'false';
- expand(header, toExpand);
- });
-
- $('#host-info-container').on('click', '.section-header', function(event) {
- var toExpand = $(this).attr('aria-expanded') === 'false';
- expand(this, toExpand);
- });
-
- $('#host-button-shutdown').on('click', function(event) {
- shutdownHost(null);
- });
-
- $('#host-button-restart').on('click', function(event) {
- shutdownHost({
- reboot: true
- });
- });
-
- var setupUI = function() {
- if (kimchi.capabilities == undefined) {
- setTimeout(setupUI, 2000);
- return;
- }
-
- if((kimchi.capabilities['repo_mngt_tool']) && (kimchi.capabilities['repo_mngt_tool']!="None")) {
- initRepositoriesGrid(kimchi.capabilities['repo_mngt_tool']);
- $('#repositories-section').switchClass('hidden', kimchi.capabilities['repo_mngt_tool']);
- wok.topic('kimchi/repositoryAdded')
- .subscribe(listRepositories);
- wok.topic('kimchi/repositoryUpdated')
- .subscribe(listRepositories);
- wok.topic('kimchi/repositoryDeleted')
- .subscribe(listRepositories);
- }
-
- if(kimchi.capabilities['update_tool']) {
- $('#software-update-section').removeClass('hidden');
- initSoftwareUpdatesGrid();
- wok.topic('kimchi/softwareUpdated')
- .subscribe(listSoftwareUpdates);
- $('#software-updates-progress-container').accordion({
- collapsible: true
- });
- }
-
- if(kimchi.capabilities['system_report_tool']) {
- listDebugReports();
- wok.topic('kimchi/debugReportAdded')
- .subscribe(listDebugReports);
- wok.topic('kimchi/debugReportRenamed')
- .subscribe(listDebugReports);
- }
- };
- setupUI();
- };
-
- kimchi.getHost(function(data) {
- var htmlTmpl = $('#host-tmpl').html();
- data['logo'] = data['logo'] || '';
- data['memory'] = wok.formatMeasurement(data['memory'], {
- fixed: 2
- });
- var templated = wok.substitute(htmlTmpl, data);
- $('#host-content-container').html(templated);
-
- initPage();
- initTracker();
- });
-
- var StatsMgr = function() {
- var statsArray = {
- cpu: {
- u: {
- type: 'percent',
- legend: i18n['KCHHOST6002M'],
- points: []
- }
- },
- memory: {
- u: {
- type: 'value',
- base: 2,
- fixed: 2,
- legend: i18n['KCHHOST6003M'],
- points: []
- }
- },
- diskIO: {
- r: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6004M'],
- points: []
- },
- w: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6005M'],
- 'class': 'disk-write',
- points: []
- }
- },
- networkIO: {
- r: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6006M'],
- points: []
- },
- s: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6007M'],
- 'class': 'network-sent',
- points: []
- }
- }
- };
- var SIZE = 20;
- var cursor = SIZE;
-
- var add = function(stats) {
- for(var key in stats) {
- var item = stats[key];
- for(var metrics in item) {
- var value = item[metrics]['v'];
- var max = item[metrics]['max'];
- var unifiedMetrics = statsArray[key][metrics];
- var ps = unifiedMetrics['points'];
- if(!Array.isArray(value)){
- ps.push(value);
- if(ps.length > SIZE + 1) {
- ps.shift();
- }
- }
- else{
- ps=ps.concat(value);
- ps.splice(0, ps.length-SIZE-1);
- unifiedMetrics['points']=ps;
- }
- if(max !== undefined) {
- unifiedMetrics['max'] = max;
- }
- else {
- if(unifiedMetrics['type'] !== 'value') {
- continue;
- }
- max = -Infinity;
- $.each(ps, function(i, value) {
- if(value > max) {
- max = value;
- }
- });
- if(max === 0) {
- ++max;
- }
- max *= 1.1;
- unifiedMetrics['max'] = max;
- }
- }
- }
- cursor++;
- };
-
- var get = function(which) {
- var stats = statsArray[which];
- var lines = [];
- for(var k in stats) {
- var obj = stats[k];
- var line = {
- type: obj['type'],
- base: obj['base'],
- unit: obj['unit'],
- fixed: obj['fixed'],
- legend: obj['legend']
- };
- if(obj['max']) {
- line['max'] = obj['max'];
- }
- if(obj['class']) {
- line['class'] = obj['class'];
- }
- var ps = obj['points'];
- var numStats = ps.length;
- var unifiedPoints = [];
- $.each(ps, function(i, value) {
- unifiedPoints.push({
- x: cursor - numStats + i,
- y: value
- });
- });
- line['points'] = unifiedPoints;
- lines.push(line);
- }
- return lines;
- };
-
- return {
- add: add,
- get: get
- };
- };
-
- var Tracker = function(charts) {
- var charts = charts;
- var timer = null;
- var statsPool = new StatsMgr();
- var setCharts = function(newCharts) {
- charts = newCharts;
- for(var key in charts) {
- var chart = charts[key];
- chart.updateUI(statsPool.get(key));
- }
- };
-
- var self = this;
-
- var UnifyStats = function(stats) {
- var result= {
- cpu: {
- u: {
- v: stats['cpu_utilization']
- }
- },
- memory: {
- u: {
- }
- },
- diskIO: {
- r: {
- v: stats['disk_read_rate']
- },
- w: {
- v: stats['disk_write_rate']
- }
- },
- networkIO: {
- r: {
- v: stats['net_recv_rate']
- },
- s: {
- v: stats['net_sent_rate']
- }
- }
- };
- if(Array.isArray(stats['memory'])){
- result.memory.u['v']=[];
- result.memory.u['max']=-Infinity;
- for(var i=0;i<stats['memory'].length;i++){
- result.memory.u['v'].push(stats['memory'][i]['avail']);
- result.memory.u['max']=Math.max(result.memory.u['max'],stats['memory'][i]['total']);
- }
- }
- else {
- result.memory.u['v']=stats['memory']['avail'],
- result.memory.u['max']=stats['memory']['total']
- }
- return(result);
- };
-
-
- var statsCallback = function(stats) {
- var unifiedStats = UnifyStats(stats);
- statsPool.add(unifiedStats);
- for(var key in charts) {
- var chart = charts[key];
- chart.updateUI(statsPool.get(key));
- }
- timer = setTimeout(function() {
- continueTrack();
- }, 1000);
- };
-
- var track = function() {
- kimchi.getHostStatsHistory(statsCallback,
- function() {
- continueTrack();
- });
- };
-
- var continueTrack = function() {
- kimchi.getHostStats(statsCallback,
- function() {
- continueTrack();
- });
- };
-
- var destroy = function() {
- timer && clearTimeout(timer);
- timer = null;
- };
-
- return {
- setCharts: setCharts,
- start: track,
- stop: destroy
- };
- };
-
- var initTracker = function() {
- // TODO: Extend tabs with onUnload event to unregister timers.
- if(kimchi.hostTimer) {
- kimchi.hostTimer.stop();
- delete kimchi.hostTimer;
- }
-
- var trackedCharts = {
- cpu: new wok.widget.LineChart({
- id: 'chart-cpu',
- node: 'container-chart-cpu',
- type: 'percent'
- }),
- memory: new wok.widget.LineChart({
- id: 'chart-memory',
- node: 'container-chart-memory',
- type: 'value'
- }),
- diskIO: new wok.widget.LineChart({
- id: 'chart-disk-io',
- node: 'container-chart-disk-io',
- type: 'value'
- }),
- networkIO: new wok.widget.LineChart({
- id: 'chart-network-io',
- node: 'container-chart-network-io',
- type: 'value'
- })
- };
-
- if(kimchi.hostTimer) {
- kimchi.hostTimer.setCharts(trackedCharts);
- }
- else {
- kimchi.hostTimer = new Tracker(trackedCharts);
- kimchi.hostTimer.start();
- }
- };
-
- $('#host-root-container').on('remove', function() {
- if(kimchi.hostTimer) {
- kimchi.hostTimer.stop();
- delete kimchi.hostTimer;
- }
-
- repositoriesGrid && repositoriesGrid.destroy();
- wok.topic('kimchi/repositoryAdded')
- .unsubscribe(listRepositories);
- wok.topic('kimchi/repositoryUpdated')
- .unsubscribe(listRepositories);
- wok.topic('kimchi/repositoryDeleted')
- .unsubscribe(listRepositories);
-
- softwareUpdatesGrid && softwareUpdatesGrid.destroy();
- wok.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates);
-
- reportGrid && reportGrid.destroy();
- wok.topic('kimchi/debugReportAdded').unsubscribe(listDebugReports);
- wok.topic('kimchi/debugReportRenamed').unsubscribe(listDebugReports);
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.main.js b/plugins/kimchi/ui/js/src/kimchi.main.js
deleted file mode 100644
index 2fdeb85..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.main.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.capabilities = undefined;
-kimchi.getCapabilities(function(result) {
- kimchi.capabilities = result;
-
- if(kimchi.capabilities.federation=="on")
- $('#peers').removeClass('hide-content');
-}, function() {
- kimchi.capabilities = {};
-});
diff --git a/plugins/kimchi/ui/js/src/kimchi.network.js b/plugins/kimchi/ui/js/src/kimchi.network.js
deleted file mode 100644
index c43b59a..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.network.js
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-kimchi.NETWORK_TYPE_BRIDGE = "bridged";
-
-kimchi.initNetwork = function() {
- if(wok.tabMode['network'] === 'admin') {
- $('.tools').attr('style','display');
- $('#network-content .header span:last-child').attr('style','display');
- kimchi.initNetworkCreation();
- }
- kimchi.initNetworkListView();
- kimchi.initNetworkDialog();
- kimchi.initNetworkCleanup();
-};
-
-kimchi.initNetworkListView = function() {
- kimchi.listNetworks(function(data) {
- for (var i = 0; i < data.length; i++) {
- var network = {
- name : data[i].name,
- in_use : data[i].in_use,
- state : data[i].state === "active" ? "up" : "down"
- };
- if (data[i].connection === "bridge") {
- network.type = kimchi.NETWORK_TYPE_BRIDGE;
- } else {
- network.type = data[i].connection;
- }
- network.interface = data[i].interface ? data[i].interface : null;
- network.addrSpace = data[i].subnet ? data[i].subnet : null;
- network.persistent = data[i].persistent;
- kimchi.addNetworkItem(network);
- }
- $('#networkGrid').grid({enableSorting: false});
- $('input', $('.grid-control', '#network-content')).on('keyup', function(){
- $('#networkGrid').grid('filter', $(this).val());
- });
- });
-};
-
-kimchi.addNetworkItem = function(network) {
- var itemNode = $.parseHTML(kimchi.getNetworkItemHtml(network));
- $("#networkBody").append(itemNode);
- if(wok.tabMode["network"] === "admin") {
- $(".column-action").attr("style","display");
- } else {
- $(".column-space").addClass('column-space-no-border-right');
- }
- kimchi.addNetworkActions(network);
- return itemNode;
-};
-
-kimchi.getNetworkItemHtml = function(network) {
- if(!network.interface) {
- network.interface = i18n["KCHNET6001M"];
- }
- if(!network.addrSpace) {
- network.addrSpace = i18n["KCHNET6001M"];
- }
- if(i18n["network_type_" + network.type]) {
- network.type = i18n["network_type_" + network.type];
- }
-
- var disable_in_use = network.in_use ? "ui-state-disabled" : "";
- var networkItem = wok.substitute($('#networkItem').html(), {
- name : network.name,
- state : network.state,
- type : network.type,
- interface: network.interface,
- addrSpace : network.addrSpace,
- startClass : network.state === "up" ? "hide-action-item" : "",
- stopClass : network.state === "down" ? "hide-action-item" : disable_in_use,
- stopDisabled : network.in_use ? "disabled" : "",
- deleteClass : network.state === "up" || network.in_use ? "ui-state-disabled" : "",
- deleteDisabled: network.state === "up" || network.in_use ? "disabled" : ""
- });
- return networkItem;
-};
-
-kimchi.stopNetwork = function(network,menu) {
- $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("up", "nw-loading");
- $("[nwAct='stop']", menu).addClass("ui-state-disabled");
- kimchi.toggleNetwork(network.name, false, function() {
- $("[nwAct='start']", menu).removeClass("hide-action-item");
- $("[nwAct='stop']", menu).addClass("hide-action-item");
- $("[nwAct='stop']", menu).removeClass("ui-state-disabled");
- if (!network.in_use) {
- $("[nwAct='delete']", menu).removeClass("ui-state-disabled");
- $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
- }
- $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "down");
- }, function(err) {
- $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "up");
- if (!network.in_use) {
- $("[nwAct='stop']", menu).removeClass("ui-state-disabled");
- }
- wok.message.error(err.responseJSON.reason);
- });
-}
-
-kimchi.addNetworkActions = function(network) {
- $(".menu-container", "#" + wok.escapeStr(network.name)).menu();
-
- $('#' + wok.escapeStr(network.name)).on('click', '.menu-container li', function(evt) {
- var menu = $(evt.currentTarget).parent();
- if ($(evt.currentTarget).attr("nwAct") === "start") {
- $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("down", "nw-loading");
- $("[nwAct='start']", menu).addClass("ui-state-disabled");
- $("[nwAct='delete']", menu).addClass("ui-state-disabled");
- $(":first-child", $("[nwAct='delete']", menu)).attr("disabled", true);
- kimchi.toggleNetwork(network.name, true, function() {
- $("[nwAct='start']", menu).addClass("hide-action-item");
- $("[nwAct='start']", menu).removeClass("ui-state-disabled");
- $("[nwAct='stop']", menu).removeClass("hide-action-item");
- network.state = "up";
- if (network.in_use) {
- $("[nwAct='stop']", menu).addClass("ui-state-disabled");
- }
- $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "up");
- }, function(err) {
- $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading","down");
- $("[nwAct='start']", menu).removeClass("ui-state-disabled");
- if (!network.in_use) {
- $("[nwAct='delete']", menu).removeClass("ui-state-disabled");
- }
- $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
- wok.message.error(err.responseJSON.reason);
- });
- } else if ($(evt.currentTarget).attr("nwAct") === "stop") {
- if (network.in_use) {
- return false;
- }
- if (!network.persistent) {
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHNET6004M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.stopNetwork(network, menu);
- $('#networkGrid').grid('deleteRow', $(evt.currentTarget).parents(".row"));
- }, null);
- }
- else {
- kimchi.stopNetwork(network, menu);
- network.state = "down";
- }
- } else if ($(evt.currentTarget).attr("nwAct") === "delete") {
- if (network.state === "up" || network.in_use) {
- return false;
- }
- wok.confirm({
- title : i18n['KCHAPI6006M'],
- content : i18n['KCHNET6002M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- }, function() {
- kimchi.deleteNetwork(network.name, function() {
- $('#networkGrid').grid('deleteRow', $(evt.currentTarget).parents(".row"));
- });
- }, null);
- }
- });
-
- $("#networkBody .column-action .popable").button({
- icons : {
- secondary : "action-button-icon"
- }
- });
-
-};
-
-kimchi.initNetworkCreation = function() {
- $("#networkAdd").on("click", function() {
- kimchi.openNetworkDialog(function() {
- var errorCallback = function(){
- $("#networkFormOk").button("enable");
- $("#networkName").removeAttr("readonly");
- $("#networkFormOk span").text(i18n.KCHAPI6005M);
- };
- var network = kimchi.getNetworkDialogValues();
- var data = {
- name : network.name,
- connection: network.type
- };
- if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
- data.connection = "bridge";
- data.interface = network.interface;
- if ($("#enableVlan").prop("checked")) {
- data.vlan_id = network.vlan_id;
- if (!(data.vlan_id >=1 && data.vlan_id <= 4094)) {
- wok.message.error.code('KCHNET6001E');
- errorCallback();
- return;
- }
- }
- }
- kimchi.createNetwork(data, function(result) {
- network.state = result.state === "active" ? "up" : "down";
- network.interface = result.interface ? result.interface : i18n["KCHNET6001M"];
- network.addrSpace = result.subnet ? result.subnet : i18n["KCHNET6001M"];
- network.persistent = result.persistent;
- $('#networkGrid').grid('addRow', kimchi.addNetworkItem(network));
- $("#networkConfig").dialog("close");
- }, function(data) {
- wok.message.error(data.responseJSON.reason);
- errorCallback();
- });
- });
- });
-};
-
-kimchi.initNetworkDialog = function() {
- buttonsObj= {};
- buttonsObj['id'] = "networkFormOk";
- buttonsObj['text'] = i18n.KCHAPI6005M;
- buttonsObj['class'] = "btn-normal";
- buttonsObj['disabled'] = true;
- buttonsObj['click'] = function() { };
- buttonsObjCancel= {};
- buttonsObjCancel['id'] = "networkFormCancel";
- buttonsObjCancel['text'] = i18n.KCHAPI6003M;
- buttonsObjCancel['class'] = "btn-normal";
- buttonsObjCancel['disabled'] = false;
- buttonsObjCancel['click'] = function() {
- $(this).dialog("close");
- };
- $("#networkConfig").dialog({
- autoOpen : false,
- modal : true,
- width : 600,
- draggable : false,
- resizable : false,
- closeText: "X",
- dialogClass : "network-ui-dialog remove-when-logged-off",
- open : function(){
- $(".ui-dialog-titlebar-close", $("#networkConfig").parent()).removeAttr("title");
- $(".ui-widget-overlay").css({
- "background": "#FFFFFF",
- "opacity": "0.5"
- });
- },
- beforeClose : function() {
- kimchi.cleanNetworkDialog();
- },
- buttons : [buttonsObj, buttonsObjCancel]
- });
- $("#networkConfig").parent().css({
- "background": "#FFFFFF",
- "border-radius": 0,
- "border": "2px solid #999999"
- });
- $(".ui-dialog-titlebar button", $("#networkConfig").parent()).remove();
- $(".ui-dialog-titlebar span", $("#networkConfig").parent()).css({
- "font-weight": "lighter",
- "height": "48px",
- "line-height": "48px",
- "margin": "0 30px",
- "color": "#444444",
- "font-size": "22px"
- });
- $(".ui-dialog-titlebar", $("#networkConfig").parent()).css({
- "box-shadow": "none",
- "padding": "0",
- });
- $(".ui-dialog-buttonpane", $("#networkConfig").parent()).css({
- "background": "#008ABF"
- });
- $(".ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset").css({
- "padding": "0 10px",
- "float": "left"
- });
- $(".ui-dialog-buttonpane .ui-dialog-buttonset button").removeClass("ui-corner-all");
- $(".ui-dialog-buttonpane .ui-dialog-buttonset button").css({
- "background": "#FFFFFF",
- "color": "#444444",
- "font-size": "13px",
- "border-radius": "0",
- "opacity": "1"
- });
- kimchi.setupNetworkFormEvent();
-};
-
-kimchi.openNetworkDialog = function(okCallback) {
- kimchi.getInterfaces(function(result) {
- var options = [];
- $('#networkDestinationID').selectMenu();
- var nics = {};
- for (var i = 0; i < result.length; i++) {
- options.push({label:result[i].name,value:result[i].name});
- nics[result[i].name] = result[i];
- }
- result.length>0 && $("#networkDestinationID").selectMenu("setData", options);
- onChange = function() {
- $("#networkDestinationLabel").text($("#networkDestinationID li:first-child").text());
- $("#networkDestinationID li:first-child").addClass("active");
- if (result.length>0 && nics[$("#networkDestinationLabel").text()].type === "bridge") {
- $("#enableVlan").prop("checked", false);
- $("#enableVlan").prop("disabled", true);
- $("#networkVlanID").val("");
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- } else {
- $("#enableVlan").prop("disabled",false);
- }
- };
- $("#networkDestinationLabel").on("change", onChange);
- kimchi.setDefaultNetworkType(result.length!==0);
- onChange();
- });
- $("#networkConfig").dialog({
- title : i18n.KCHNET6003M
- });
- $("#networkFormOk").on("click", function() {
- $("#networkFormOk").button("disable");
- $("#networkName").prop("readonly", "readonly");
- $("#networkFormOk span").text(i18n.KCHAPI6008M);
- okCallback();
- });
- $("#enableVlan").on("click", function() {
- $("#networkVlanID").prop("disabled", !this.checked);
- if (!this.checked) {
- $("#networkVlanID").slideUp(100);
- $("#labelNetworkVlanID").slideUp(100);
- $("#networkVlanID").val("");
- }
- else {
- $("#networkVlanID").slideDown(100);
- $("#labelNetworkVlanID").slideDown(100);
- }
- });
- $("#networkConfig").dialog("open");
-};
-
-kimchi.enableBridgeOptions = function(enable) {
- if (!enable) {
- $("#enableVlan").prop("checked", false);
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- $("#networkVlanID").val("");
- $("#networkDestinationLabel").text("");
- $("#bridgeOptions").slideUp(100);
- } else if (!$("#networkDestinationLabel").text()){
- $("#networkDestinationLabel").text($("#networkDestinationID li:first-child").text());
- $("#bridgeOptions").slideDown(100);
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- }
-};
-
-
-kimchi.setDefaultNetworkType = function(isInterfaceAvail) {
- $("#networkTypeBri").prop("checked", isInterfaceAvail);
- $("#networkTypeBri").prop("disabled", !isInterfaceAvail);
- $("#networkTypeNat").prop("checked", !isInterfaceAvail);
- if (!isInterfaceAvail) {
- kimchi.enableBridgeOptions(false);
- $("#networkBriDisabledLabel").show();
- } else {
- if (kimchi.capabilities && kimchi.capabilities.nm_running) {
- wok.message.warn(i18n['KCHNET6001W']);
- }
- $("#bridgeOptions").slideDown(100);
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- $("#networkBriDisabledLabel").hide();
- }
-};
-
-kimchi.getNetworkDialogValues = function() {
- var network = {
- name : $("#networkName").val(),
- type : $("input:radio[name=networkType]:checked").val()
- };
- if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
- network.interface = $("#networkDestinationLabel").text();
- network.vlan_id = parseInt($("#networkVlanID").val());
- }
- return network;
-};
-
-kimchi.cleanNetworkDialog = function() {
- $("input:text", "#networkConfig").val(null).removeClass("invalid-field");
- $("#networkTypeIso").prop("checked", false);
- $("#networkTypeNat").prop("checked", false);
- $("#networkTypeBri").prop("checked", false);
- $("#networkDestinationLabel").text($("#networkDestinationID li:first-child").text());
- $("#networkFormOk").off("click");
- $("#networkFormOk").button("disable");
- $("#networkFormOk span").text(i18n.KCHAPI6005M);
- $("#networkName").removeAttr("readonly");
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- $("#enableVlan").prop("checked", false);
-
-};
-kimchi.setupNetworkFormEvent = function() {
- $("#networkName").on("keyup", function(event) {
- $("#networkName").toggleClass("invalid-field", !$("#networkName").val().match(/^[^\"\/]+$/));
- kimchi.updateNetworkFormButton();
- });
- $("#networkTypeIso").on("click", function(event) {
- kimchi.enableBridgeOptions(false);
- });
- $("#networkTypeNat").on("click", function(event) {
- kimchi.enableBridgeOptions(false);
- });
- $("#networkTypeBri").on("click", function(event) {
- kimchi.enableBridgeOptions(true);
- });
-};
-
-kimchi.updateNetworkFormButton = function() {
- if($("#networkName").hasClass("invalid-field")){
- $("#networkFormOk").button("disable");
- }else{
- $("#networkFormOk").button("enable");
- }
-};
-
-kimchi.initNetworkCleanup = function() {
- $("#network-content").on("remove", function() {
- $("#networkConfig").dialog("destroy");
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.report_add_main.js b/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
deleted file mode 100644
index 5f098d3..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.report_add_main = function() {
- var reportGridID = 'available-reports-grid';
- var addReportForm = $('#form-report-add');
- var submitButton = $('#button-report-add');
- var nameTextbox = $('input[name="name"]', addReportForm);
- nameTextbox.select();
-
- var submitForm = function(event) {
- if(submitButton.prop('disabled')) {
- return false;
- }
- var reportName = nameTextbox.val();
- var validator = RegExp("^[_A-Za-z0-9-]*$");
- if (!validator.test(reportName)) {
- wok.message.error.code('KCHDR6011M');
- return false;
- }
- var formData = addReportForm.serializeObject();
- var taskAccepted = false;
- var onTaskAccepted = function() {
- if(taskAccepted) {
- return;
- }
- taskAccepted = true;
- wok.window.close();
- wok.topic('kimchi/debugReportAdded').publish();
- };
-
- kimchi.createReport(formData, function(result) {
- onTaskAccepted();
- wok.topic('kimchi/debugReportAdded').publish();
- }, function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
-
- taskAccepted &&
- $('.grid-body-view table tr:first-child',
- '#' + reportGridID).remove();
- submitButton.prop('disabled', false);
- nameTextbox.select();
- }, onTaskAccepted);
-
- event.preventDefault();
- };
-
- addReportForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js b/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
deleted file mode 100644
index 1bdb8d9..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.report_rename_main = function() {
- var renameReportForm = $('#form-report-rename');
- var submitButton = $('#button-report-rename');
- var nameTextbox = $('input[name="name"]', renameReportForm);
- var submitForm = function(event) {
- if(submitButton.prop('disabled')) {
- return false;
- }
- var reportName = nameTextbox.val();
-
- // if the user hasn't changed the report's name,
- // nothing should be done.
- if (reportName == kimchi.selectedReport) {
- wok.message.error.code('KCHDR6013M');
- return false;
- }
-
- var validator = RegExp("^[A-Za-z0-9-]*$");
- if (!validator.test(reportName)) {
- wok.message.error.code('KCHDR6011M');
- return false;
- }
- var formData = renameReportForm.serializeObject();
- submitButton.prop('disabled', true);
- nameTextbox.prop('disabled', true);
- kimchi.renameReport(kimchi.selectedReport, formData, function(result) {
- submitButton.prop('disabled', false);
- nameTextbox.prop('disabled', false);
- wok.window.close();
- wok.topic('kimchi/debugReportRenamed').publish({
- result: result
- });
- }, function(result) {
- var errText = result &&
- result['responseJSON'] &&
- result['responseJSON']['reason'];
- wok.message.error(errText);
- submitButton.prop('disabled', false);
- nameTextbox.prop('disabled', false).focus();
- });
-
- event.preventDefault();
- };
-
- renameReportForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
-
- nameTextbox.val(kimchi.selectedReport).select();
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js b/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
deleted file mode 100644
index 656306b..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.repository_add_main = function() {
-
- var addForm = $('#form-repository-add');
- var addButton = $('#button-repository-add');
-
- var validateField = function(event) {
- var valid=($(this).val()!=='');
- $(addButton).prop('disabled', !valid);
- return(valid);
- };
-
- var validateForm = function(event) {
- var valid=false;
- addForm.find('input.required').each( function() {
- valid=($(this).val()!=='');
- return(!valid);
- });
- return(valid);
- }
-
- addForm.find('input.required').on('input propertychange', validateField);
-
- var weedObject = function(obj) {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- if((typeof(obj[key])==="object") && !Array.isArray(obj[key])) {
- weedObject(obj[key]);
- }
- else if(obj[key] == '') {
- delete obj[key];
- }
- }
- }
- }
-
- var addRepository = function(event) {
- var valid = validateForm();
- if(!valid) {
- return false;
- }
-
- var formData = $(addForm).serializeObject();
-
- if (formData && formData.isMirror!=undefined) {
- formData.isMirror=(String(formData.isMirror).toLowerCase() === 'true');
- }
- if(formData.isMirror) {
- if(formData.config==undefined) {
- formData.config=new Object();
- }
- formData.config.mirrorlist=formData.baseurl;
- delete formData.baseurl;
- delete formData.isMirror;
- }
- weedObject(formData);
- if(formData.config && formData.config.comps) {
- formData.config.comps=formData.config.comps.split(/[,\s]/);
- for(var i=0; i>formData.config.comps.length; i++) {
- formData.config.comps[i]=formData.config.comps[i].trim();
- }
- for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
- formData.config.comps.splice(j, 1);
- }
- }
-
- kimchi.createRepository(formData, function() {
- wok.topic('kimchi/repositoryAdded').publish();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
- return false;
- };
-
- $(addForm).on('submit', addRepository);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js b/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
deleted file mode 100644
index 5bfc51e..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.repository_edit_main = function() {
-
- var editForm = $('#form-repository-edit');
-
- var saveButton = $('#repository-edit-button-save');
-
- if(kimchi.capabilities['repo_mngt_tool']=="yum") {
- editForm.find('input.deb').prop('disabled', true);
- }
- else if(kimchi.capabilities['repo_mngt_tool']=="deb") {
- editForm.find('input.yum').prop('disabled', true);
- }
-
- kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) {
- editForm.fillWithObject(repository);
-
- $('input', editForm).on('input propertychange', function(event) {
- if($(this).val() !== '') {
- $(saveButton).prop('disabled', false);
- }
- });
- });
-
-
- var editRepository = function(event) {
- var formData = $(editForm).serializeObject();
-
- if (formData && formData.config) {
- formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() === 'true');
- }
-
- if(formData.config && formData.config.comps) {
- formData.config.comps=formData.config.comps.split(/[,\s]/);
- for(var i=0; i>formData.config.comps.length; i++) {
- formData.config.comps[i]=formData.config.comps[i].trim();
- }
- for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
- formData.config.comps.splice(j, 1);
- }
- }
-
- kimchi.updateRepository(kimchi.selectedRepository, formData, function() {
- wok.topic('kimchi/repositoryUpdated').publish();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
-
- return false;
- };
-
- $(editForm).on('submit', editRepository);
- $(saveButton).on('click', editRepository);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.storage_main.js b/plugins/kimchi/ui/js/src/kimchi.storage_main.js
deleted file mode 100644
index 40a43f6..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.storage_main.js
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.doListStoragePools = function() {
- kimchi.listStoragePools(function(result) {
- var storageHtml = $('#storageTmpl').html();
- if (result && result.length) {
- var listHtml = '';
- $.each(result, function(index, value) {
- value.usage = Math.round(value.allocated / value.capacity * 100) || 0;
- value.capacity = wok.changetoProperUnit(value.capacity,1);
- value.allocated = wok.changetoProperUnit(value.allocated,1);
- value.enableExt = value.type==="logical" ? "" : "hide-content";
- if ('kimchi-iso' !== value.type) {
- listHtml += wok.substitute(storageHtml, value);
- }
- });
- if($('#storageGrid').hasClass('grid'))
- $('#storageGrid').grid('destroy');
- $('#storagepoolsList').html(listHtml);
- if(wok.tabMode['storage'] === 'admin') {
- $('.storage-button').attr('style','display');
- } else {
- $('.storage-allocate').addClass('storage-allocate-padding-user');
- }
- $('#storageGrid').grid({enableSorting: false});
- $('input', $('.grid-control', '.storage')).on('keyup', function(){
- $('#storageGrid').grid('filter', $(this).val());
- });
- kimchi.storageBindClick();
- } else {
- $('#storagepoolsList').html('');
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
-}
-
-kimchi.storageBindClick = function() {
-
- $('.inactive').each(function(index) {
- if ('active' === $(this).data('state')) {
- $(this).hide();
- } else {
- $(this).show();
- }
- });
-
- $('.list-storage .storage-state .active').each(function(index) {
- if ('active' === $(this).data('state')) {
- $(this).show();
- } else {
- $(this).hide();
- }
- });
-
- $('.pool-activate').each(function(index) {
- if ('active' === $(this).data('stat')) {
- $(this).hide();
- } else {
- $(this).show();
- }
- });
-
- $('.pool-deactivate').each(function(index) {
- if ('active' === $(this).data('stat')) {
- $(this).show();
- } else {
- $(this).hide();
- }
- });
-
- $('.pool-add-volume').each(function(index) {
- var canAddVolume =
- $(this).data('stat') === 'active' &&
- $(this).data('type') !== 'iscsi' &&
- $(this).data('type') !== 'scsi';
- if(canAddVolume) {
- $(this).show();
- }
- else {
- $(this).hide();
- }
- });
-
- if(wok.tabMode['storage'] === 'admin') {
- $('.pool-delete').on('click', function(event) {
- var $pool = $(this);
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- var poolName = $pool.data('name');
- kimchi.deleteStoragePool(poolName, function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
- });
-
- $('.pool-activate').on('click', function(event) {
- var poolName = $(this).data('name');
- kimchi.changePoolState(poolName, 'activate', function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-
- $('.pool-deactivate').on('click', function(event) {
- var poolName = $(this).data('name');
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6012M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- if (!$(this).data('persistent')) {
- wok.confirm(settings, function() {
- kimchi.changePoolState(poolName, 'deactivate', function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- return false;
- });
- }
- else {
- kimchi.changePoolState(poolName, 'deactivate', function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }
- });
-
- $('.pool-add-volume').on('click', function(event) {
- var poolName = $(this).data('name');
- kimchi.selectedSP = poolName;
- wok.window.open('plugins/kimchi/storagepool-add-volume.html');
- });
-
- $('.storage-action').on('click', function() {
- var storage_action = $(this);
- var deleteButton = storage_action.find('.pool-delete');
- if ('active' === deleteButton.data('stat')) {
- deleteButton.attr('disabled', 'disabled');
- } else {
- deleteButton.removeAttr('disabled');
- }
- });
-
- $('.pool-extend').on('click', function() {
- $("#logicalPoolExtend").dialog("option", "poolName", $(this).data('name'));
- $("#logicalPoolExtend").dialog("open");
- });
- }
-
- $('.row').on('click', function(event) {
- if (!$(event.target).parents().hasClass('bottom')) {
- if ($(this).data('stat') === 'active') {
- var that = $(this);
- var volumeDiv = $('#volume' + that.data('name'));
- var slide = $('.volumes', this);
- if (that.hasClass('in')) {
- that.css('height','auto');
- kimchi.doListVolumes(that);
- } else {
- slide.slideUp('slow', function(){
- that.css('height','');
- });
- that.addClass('in');
- kimchi.changeArrow($('.arrow-up', this));
- }
- }
- }
- });
-}
-
-kimchi._generateVolumeHTML = function(volume) {
- if(volume['type'] === 'kimchi-iso') {
- return '';
- }
- var volumeHtml = $('#volumeTmpl').html();
- volume.capacity = wok.changetoProperUnit(volume.capacity,1);
- volume.allocation = wok.changetoProperUnit(volume.allocation,1);
- return wok.substitute(volumeHtml, volume);
-};
-
-kimchi.doListVolumes = function(poolObj) {
- var poolName = poolObj.data('name')
-
- var getOngoingVolumes = function() {
- var result = {}
- var filter = 'status=running&target_uri=' + encodeURIComponent('^/plugins/kimchi/storagepools/' + poolName + '/*')
- kimchi.getTasksByFilter(filter, function(tasks) {
- for(var i = 0; i < tasks.length; i++) {
- var volumeName = tasks[i].target_uri.split('/').pop();
- result[volumeName] = tasks[i];
-
- if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
- continue;
- }
-
- kimchi.trackTask(tasks[i].id, function(result) {
- wok.topic('kimchi/volumeTransferFinished').publish(result);
- }, function(result) {
- wok.topic('kimchi/volumeTransferError').publish(result);
- }, function(result) {
- wok.topic('kimchi/volumeTransferProgress').publish(result);
- });
- }
- }, null, true);
- return result;
- };
-
- var volumeDiv = $('#volume' + poolName);
- $(volumeDiv).empty();
- var slide = $('.volumes', poolObj);
- var handleArrow = $('.arrow-down', poolObj);
-
- kimchi.listStorageVolumes(poolName, function(result) {
- var listHtml = '';
- var ongoingVolumes = [];
- var ongoingVolumesMap = getOngoingVolumes();
- $.each(ongoingVolumesMap, function(volumeName, task) {
- ongoingVolumes.push(volumeName)
- var volume = {
- poolName: poolName,
- used_by: [],
- capacity: 0,
- name: volumeName,
- format: '',
- bootable: null,
- os_distro: '',
- allocation: 0,
- os_version: '',
- path: '',
- type: 'file'
- };
- listHtml += kimchi._generateVolumeHTML(volume);
- });
-
- $.each(result, function(index, value) {
- if (ongoingVolumes.indexOf(value.name) == -1) {
- value.poolname = poolName;
- listHtml += kimchi._generateVolumeHTML(value);
- }
- });
-
- if (listHtml.length > 0) {
- volumeDiv.html(listHtml);
- } else {
- volumeDiv.html("<div class='pool-empty'>" + i18n['KCHPOOL6002M'] + "</div>");
- }
-
- $.each(ongoingVolumesMap, function(volumeName, task) {
- wok.topic('kimchi/volumeTransferProgress').publish(task);
- });
-
- poolObj.removeClass('in');
- kimchi.changeArrow(handleArrow);
- slide.slideDown('slow');
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
-}
-
-kimchi.initLogicalPoolExtend = function() {
- $("#logicalPoolExtend").dialog({
- autoOpen : false,
- modal : true,
- width : 600,
- resizable : false,
- closeText: "X",
- open : function(){
- $('#loading-info', '#logicalPoolExtend').removeClass('hidden');
- $(".ui-dialog-titlebar-close", $("#logicalPoolExtend").parent()).removeAttr("title");
- kimchi.listHostPartitions(function(data) {
- $('#loading-info', '#logicalPoolExtend').addClass('hidden');
- if (data.length > 0) {
- for(var i=0;i<data.length;i++){
- if (data[i].type === 'part' || data[i].type === 'disk') {
- $('.host-partition', '#logicalPoolExtend').append(wok.substitute($('#logicalPoolExtendTmpl').html(), data[i]));
- }
- }
- } else {
- $('.host-partition').html(i18n['KCHPOOL6011M']);
- $('.host-partition').addClass('text-help');
- }
- }, function(err) {
- $('#loading-info', '#logicalPoolExtend').addClass('hidden');
- $('.host-partition').html(i18n['KCHPOOL6013M'] + '<br/>(' + err.responseJSON.reason + ')');
- $('.host-partition').addClass('text-help');
- });
- },
- beforeClose : function() { $('.host-partition', '#logicalPoolExtend').empty(); },
- buttons : [{
- class: "ui-button-primary",
- text: i18n.KCHAPI6007M,
- click: function(){
- var devicePaths = [];
- $("input[type='checkbox']:checked", "#logicalPoolExtend").each(function(){
- devicePaths.push($(this).prop('value'));
- })
- kimchi.updateStoragePool($("#logicalPoolExtend").dialog("option", "poolName"),{disks: devicePaths},function(data){
- var item = $("#"+$("#logicalPoolExtend").dialog("option", "poolName"));
- $(".usage", $(".storage-name", item)).text((Math.round(data.allocated/data.capacity*100)||0)+"%");
- $(".storage-text", $(".storage-capacity", item)).text(wok.changetoProperUnit(data.capacity,1));
- $(".storage-text", $(".storage-allocate", item)).text(wok.changetoProperUnit(data.allocated,1));
- });
- $(this).dialog("close");
- }
- }]
- });
-}
-
-kimchi.storage_main = function() {
- if(wok.tabMode['storage'] === 'admin') {
- $('.tools').attr('style','display');
- $('#storage-pool-add').on('click', function() {
- wok.window.open('plugins/kimchi/storagepool-add.html');
- });
- $('.list-title .title-actions').attr('style','display');
- }
- kimchi.doListStoragePools();
- kimchi.initLogicalPoolExtend();
-
- wok.topic('kimchi/storageVolumeAdded').subscribe(function() {
- pool = kimchi.selectedSP;
- var poolNode = $('.storage-li[data-name="' + pool + '"]');
- kimchi.doListVolumes(poolNode);
- });
-
- wok.topic('kimchi/volumeTransferProgress').subscribe(function(result) {
- var extractProgressData = function(data) {
- var sizeArray = /(\d+)\/(\d+)/g.exec(data) || [0, 0, 0];
- var downloaded = sizeArray[1];
- var percent = 0;
- if(downloaded) {
- var total = sizeArray[2];
- if(!isNaN(total)) {
- percent = downloaded / total * 100;
- }
- }
- var formatted = wok.formatMeasurement(downloaded);
- var size = (1.0 * formatted['v']).toFixed(1) + formatted['s'];
- return {
- size: size,
- percent: percent
- };
- };
-
- var uriElements = result.target_uri.split('/');
- var poolName = uriElements[2];
- var volumeName = uriElements.pop();
- var progress = extractProgressData(result['message']);
- var size = progress['size'];
- var percent = progress['percent'];
-
- volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
- $('.progress-bar-inner', volumeBox).css({
- width: percent + '%'
- });
- $('.progress-transferred', volumeBox).text(size);
- $('.volume-progress', volumeBox).removeClass('hidden');
- $('.progress-status', volumeBox).text(i18n['KCHPOOL6014M']);
- });
-
- wok.topic('kimchi/volumeTransferFinished').subscribe(function(result) {
- var uriElements = result.target_uri.split('/');
- var poolName = uriElements[2];
- var volumeName = uriElements.pop();
- var volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
- $('.volume-progress', volumeBox).addClass('hidden');
- kimchi.getStoragePoolVolume(poolName, volumeName, function(volume) {
- var html = kimchi._generateVolumeHTML(volume);
- $(volumeBox).replaceWith(html);
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-
- wok.topic('kimchi/volumeTransferError').subscribe(function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
-
- var uriElements = result.target_uri.split('/');
- var poolName = uriElements[2];
- var volumeName = uriElements.pop();
- volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
- $('.progress-status', volumeBox).text(i18n['KCHPOOL6015M']);
- });
-};
-
-kimchi.changeArrow = function(obj) {
- if ($(obj).hasClass('arrow-down')) {
- $(obj).removeClass('arrow-down').addClass('arrow-up');
- } else {
- $(obj).removeClass('arrow-up').addClass('arrow-down');
- }
-}
diff --git a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js b/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
deleted file mode 100644
index 8c27539..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-kimchi.storagepool_add_main = function() {
- kimchi.initStorageAddPage();
- $('#form-pool-add').on('submit', kimchi.addPool);
- $('#pool-doAdd').on('click', kimchi.addPool);
- // 'pool-doAdd' button starts as disabled.
- $("#pool-doAdd").attr("disabled", true);
- // Make any change in the form fields enables the
- // 'pool-doAdd' button if all the visible form
- // fields are filled, disables it otherwise.
- $('#form-pool-add').on('input change propertychange', function() {
- if (!kimchi.inputsNotBlank())
- $("#pool-doAdd").attr("disabled", true);
- else
- $("#pool-doAdd").attr("disabled", false);
- });
-};
-
-kimchi.storageFilterSelect = function(id, isUpdate) {
- var input = $('input', '#'+id);
- var options = $(".option", '#'+id);
- var filter = function(container, key){
- container.children().each(function(){
- $(this).css("display", $(this).text().indexOf(key)==-1 ? "none" : "");
- });
- };
- if(!isUpdate){
- input.on("keyup", function(){
- filter(options, input.val());
- });
- }
- options.children().each(function(){
- $(this).click(function(){
- options.children().removeClass("active");
- input.val($(this).text());
- input.trigger("change");
- $(this).addClass("active");
- filter(options, "");
- });
- });
-};
-
-kimchi.setupISCSI = function(){
- var loadTargets = function(server, port, callback){
- var isUpdate = $(".option", "#iSCSITarget").children().length > 0;
- $(".option", "#iSCSITarget").empty();
- $('input', "#iSCSITarget").attr("placeholder", i18n['KCHPOOL6006M']);
- kimchi.getISCSITargets(server, port, function(data){
- if(data.length==0){
- $('input', "#iSCSITarget").attr("placeholder", i18n['KCHPOOL6007M']);
- }else{
- for(var i=0; i<data.length; i++){
- var itemNode = $.parseHTML("<li>"+data[i].target+"</li>");
- $(".option", "#iSCSITarget").append(itemNode);
- }
- $('input', "#iSCSITarget").attr("placeholder", "");
- $(".popover", "#iSCSITarget").css("display", "block");
- }
- kimchi.storageFilterSelect('iSCSITarget', isUpdate);
- $('input', "#iSCSITarget").trigger("focus");
- callback();
- }, function(data){
- $('input', "#iSCSITarget").attr("placeholder", i18n['KCHPOOL6008M']);
- callback();
- wok.message.error(data.responseJSON.reason);
- });
- };
- var triggerLoadTarget = function(){
- $('input', "#iSCSITarget").val("");
- var server = $("#iscsiserverId").val().trim();
- var port = $("#iscsiportId").val().trim();
- if(server!="" && !$("#iscsiserverId").hasClass("invalid-field") && !$("#iscsiportId").hasClass("invalid-field")){
- $("#iscsiserverId").attr("disabled", true);
- $("#iscsiportId").attr("disabled", true);
- loadTargets(server, port, function(){
- $("#iscsiserverId").attr("disabled", false);
- $("#iscsiportId").attr("disabled", false);
- });
- }
- };
- $("#iscsiserverId").change(function(){
- $('input', "#iSCSITarget").off('focus', triggerLoadTarget);
- $('input', "#iSCSITarget").one('focus', triggerLoadTarget);
- });
- $("#iscsiportId").change(function(){
- $('input', "#iSCSITarget").off('focus', triggerLoadTarget);
- $('input', "#iSCSITarget").one('focus', triggerLoadTarget);
- });
- var initISCSIServers = function(){
- kimchi.getStorageServers("iscsi", function(data){
- for(var i=0;i<data.length;i++){
- var itemNode = $.parseHTML("<li>"+data[i].host+"</li>");
- $(".option", "#iSCSIServer").append(itemNode);
- $(itemNode).click(function(){
- $("#iscsiportId").val($(this).prop("port"));
- $("#iscsiserverId").val($(this).text());
- triggerLoadTarget();
- }).prop("port", data[i].port);
- }
- kimchi.storageFilterSelect('iSCSIServer', false);
- });
- };
- initISCSIServers();
-};
-
-kimchi.initStorageAddPage = function() {
- kimchi.listHostPartitions(function(data) {
- if (data.length > 0) {
- var deviceHtml = $('#partitionTmpl').html();
- var listHtml = '';
- valid_types = ['part', 'disk', 'mpath'];
- $.each(data, function(index, value) {
- if (valid_types.indexOf(value.type) != -1) {
- listHtml += wok.substitute(deviceHtml, value);
- }
- });
- $('.host-partition', '#form-pool-add').html(listHtml);
- } else {
- $('.host-partition').html(i18n['KCHPOOL6011M']);
- $('.host-partition').addClass('text-help');
- }
- }, function(err) {
- $('.host-partition').html(i18n['KCHPOOL6013M'] + '<br/>(' + err.responseJSON.reason + ')');
- $('.host-partition').addClass('text-help');
- });
-
- kimchi.getHostFCDevices(function(data){
- if(data.length>0){
- for(var i=0;i<data.length;i++){
- data[i].label = data[i].name;
- data[i].value = data[i].name;
- }
- $('#scsiAdapter').selectMenu();
- $("input", "#scsiAdapter").val(data[0].name);
- $('#scsiAdapter').selectMenu("setData", data);
- } else {
- $('#scsiAdapter').html(i18n['KCHPOOL6005M']);
- $('#scsiAdapter').addClass('text-help');
- }
- });
-
- $('#poolTypeId').selectMenu();
- $('#serverComboboxId').combobox();
- $('#targetFilterSelectId').filterselect();
- var options = [ {
- label : "DIR",
- value : "dir"
- }, {
- label : "NFS",
- value : "netfs"
- }, {
- label : "iSCSI",
- value : "iscsi"
- }, {
- label : "LOGICAL",
- value : "logical"
- }, {
- label : i18n.KCHPOOL6004M,
- value : "scsi"
- } ];
- $('#poolTypeId').selectMenu("setData", options);
-
- kimchi.getStorageServers('netfs', function(data) {
- var serverContent = [];
- if (data.length > 0) {
- $.each(data, function(index, value) {
- serverContent.push({
- label : value.host,
- value : value.host
- });
- });
- }
- $('#serverComboboxId').combobox("setData", serverContent);
- $('input[name=nfsServerType]').change(function() {
- if ($(this).val() === 'input') {
- $('#nfsServerInputDiv').removeClass('tmpl-html');
- $('#nfsServerChooseDiv').addClass('tmpl-html');
- } else {
- $('#nfsServerInputDiv').addClass('tmpl-html');
- $('#nfsServerChooseDiv').removeClass('tmpl-html');
- }
- });
- $('#nfsserverId').on("change keyup",function() {
- if ($(this).val() !== '' && wok.isServer($(this).val())) {
- $('#nfspathId').prop('disabled',false);
- $(this).removeClass("invalid-field");
- } else {
- $(this).addClass("invalid-field");
- $('#nfspathId').prop( "disabled",true);
- }
- $('#targetFilterSelectId').filterselect('clear');
- });
- $('#nfspathId').focus(function() {
- var targetContent = [];
- kimchi.getStorageTargets($('#nfsserverId').val(), 'netfs', function(data) {
- if (data.length > 0) {
- $.each(data, function(index, value) {
- targetContent.push({
- label : value.target,
- value : value.target
- });
- });
- }
- $('#targetFilterSelectId').filterselect("setData", targetContent);
- });
- });
- });
-
- $('#poolTypeInputId').change(function() {
- var poolObject = {'dir': ".path-section", 'netfs': '.nfs-section',
- 'iscsi': '.iscsi-section', 'scsi': '.scsi-section',
- 'logical': '.logical-section'}
- var selectType = $(this).val();
- $.each(poolObject, function(type, value) {
- if(selectType == type){
- $(value).removeClass('tmpl-html');
- } else {
- $(value).addClass('tmpl-html');
- }
- });
- });
- $('#authId').click(function() {
- if ($(this).prop("checked")) {
- $('.authenticationfield').removeClass('tmpl-html');
- } else {
- $('.authenticationfield').addClass('tmpl-html');
- }
- });
- $('#iscsiportId').keyup(function(event) {
- $(this).toggleClass("invalid-field",!/^[0-9]*$/.test($(this).val()));
- });
- $('#iscsiserverId').keyup(function(event) {
- $(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
- }).change(function(event) {
- $(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
- });
- kimchi.setupISCSI();
-};
-
-/* Returns 'true' if all form fields were filled, 'false' if
- * any field is left blank. The function takes into account
- * the current poolType selected.
- *
- * Any 'field is blank' verification that were done in other
- * validate functions were deleted, since we're doing it here
- * already.
- */
-kimchi.inputsNotBlank = function() {
- if (!$('#poolId').val()) return false;
- var poolType = $("#poolTypeInputId").val();
- if (poolType === "dir") {
- if (!$('#pathId').val()) return false;
- } else if (poolType === "netfs") {
- if (!$('#nfspathId').val()) return false;
- if (!$('#nfsserverId').val()) return false;
- } else if (poolType === "iscsi") {
- if (!$('#iscsiserverId').val()) return false;
- if (!$('#iscsiTargetId').val()) return false;
- } else if (poolType === "logical") {
- if ($("input[name=devices]:checked").length === 0)
- return false;
- }
- return true;
-};
-
-kimchi.validateForm = function() {
- var poolType = $("#poolTypeInputId").val();
- if (poolType === "dir") {
- return kimchi.validateDirForm();
- } else if (poolType === "netfs") {
- return kimchi.validateNfsForm();
- } else if (poolType === "iscsi") {
- return kimchi.validateIscsiForm();
- } else if (poolType === "logical") {
- return kimchi.validateLogicalForm();
- } else {
- return true;
- }
-};
-
-kimchi.validateDirForm = function () {
- var path = $('#pathId').val();
- if (!/(^\/.*)$/.test(path)) {
- wok.message.error.code('KCHAPI6003E');
- return false;
- }
- return true;
-};
-
-kimchi.validateNfsForm = function () {
- var nfspath = $('#nfspathId').val();
- var nfsserver = $('#nfsserverId').val();
- if (!kimchi.validateServer(nfsserver)) {
- return false;
- }
- if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
- wok.message.error.code('KCHPOOL6005E');
- return false;
- }
- $('#nfs-mount-loading').removeClass('hidden');
- return true;
-};
-
-kimchi.validateIscsiForm = function() {
- var iscsiServer = $('#iscsiserverId').val();
- var iscsiTarget = $('#iscsiTargetId').val();
- if (!kimchi.validateServer(iscsiServer)) {
- return false;
- }
- return true;
-};
-
-kimchi.validateServer = function(serverField) {
- if(!wok.isServer(serverField)) {
- wok.message.error.code('KCHPOOL6009E');
- return false;
- }
- return true;
-};
-
-kimchi.validateLogicalForm = function () {
- if ($("input[name=devices]:checked").length === 0) {
- wok.message.error.code('KCHPOOL6006E');
- return false;
- } else {
- return true;
- }
-};
-
-kimchi.addPool = function(event) {
- if (kimchi.validateForm()) {
- var formData = $('#form-pool-add').serializeObject();
- delete formData.authname;
- var poolType = $('#poolTypeId').selectMenu('value');
- if (poolType === 'dir') {
- formData.path = $('#pathId').val();
- } else if (poolType === 'logical') {
- var source = {};
- if (!$.isArray(formData.devices)) {
- var deviceObj = [];
- deviceObj[0] = formData.devices;
- source.devices = deviceObj;
- } else {
- source.devices = formData.devices;
- }
- delete formData.devices;
- formData.source = source;
- } else if (poolType === 'netfs'){
- var source = {};
- source.path = $('#nfspathId').val();
- source.host = $('#nfsserverId').val();
- formData.source = source;
- } else if (poolType === 'iscsi') {
- var source = {};
- source.target = $('#iscsiTargetId').val();
- source.host = $('#iscsiserverId').val();
- $('#iscsiportId').val() !== '' ? source.port = parseInt($('#iscsiportId').val()): null;
- if ($('#authId').prop("checked")) {
- source.auth = {
- "username" : $('#usernameId').val(),
- "password" : $('#passwordId').val()
- };
- }
- formData.source = source;
- } else if (poolType === 'scsi'){
- formData.source = { adapter_name: $('#scsiAdapter').selectMenu('value') };
- }
- var storagePoolAddingFunc = function() {
- $('input', '#form-pool-add').attr('disabled','disabled');
- $('#pool-doAdd').hide();
- $('#pool-loading').show();
- kimchi.createStoragePool(formData, function() {
- kimchi.doListStoragePools();
- wok.window.close();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $('input', '#form-pool-add').removeAttr('disabled');
- $('#pool-loading').hide();
- $('#pool-doAdd').show();
- });
- };
- if (poolType === 'logical') {
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6003M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- storagePoolAddingFunc();
- }, function() {
- });
- } else {
- storagePoolAddingFunc();
- }
- }
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js b/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
deleted file mode 100644
index 8479ab2..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-kimchi.sp_add_volume_main = function() {
- // download from remote server or upload from local file
- var type = 'download';
-
- var addButton = $('#sp-add-volume-button');
- var remoteURLBox = $('#volume-remote-url');
- var localFileBox = $('#volume-input-file');
- var typeRadios = $('input.volume-type');
-
- var isValidURL = function() {
- var url = $(remoteURLBox).val();
- return kimchi.template_check_url(url);
- };
-
- var isValidFile = function() {
- var fileName = $(localFileBox).val();
- return fileName.length > 0;
- };
-
- $(typeRadios).change(function(event) {
- $('.volume-input').prop('disabled', true);
- $('.volume-input.' + this.value).prop('disabled', false);
- type = this.value;
- if(type == 'download') {
- $(addButton).prop('disabled', !isValidURL());
- }
- else {
- $(addButton).prop('disabled', !isValidFile());
- }
- });
-
- $(remoteURLBox).on('input propertychange', function(event) {
- $(addButton).prop('disabled', !isValidURL());
- });
-
- $(localFileBox).on('change', function(event) {
- $(addButton).prop('disabled', !isValidFile());
- });
-
- var onError = function(result) {
- $(this).prop('disabled', false);
- $(typeRadios).prop('disabled', false);
- if(!result) {
- return;
- }
- var msg = result['message'] || (
- result['responseJSON'] && result['responseJSON']['reason']
- );
- wok.message.error(msg);
- };
-
- var fetchRemoteFile = function() {
- var volumeURL = remoteURLBox.val();
- var volumeName = volumeURL.split(/(\\|\/)/g).pop();
- kimchi.downloadVolumeToSP({
- sp: kimchi.selectedSP,
- url: volumeURL
- }, function(result) {
- wok.window.close();
- wok.topic('kimchi/storageVolumeAdded').publish();
- }, onError);
- };
-
- var uploadFile = function() {
- var chunkSize = 8 * 1024 * 1024; // 8MB
- var uploaded = 0;
-
- var blobFile = $(localFileBox)[0].files[0];
-
- var createUploadVol = function() {
- kimchi.createVolumeWithCapacity(kimchi.selectedSP, {
- name: blobFile.name,
- format: '',
- capacity: blobFile.size,
- upload: true
- }, function(result) {
- wok.window.close();
- trackVolCreation(result.id);
- }, onError);
- };
-
- var uploadRequest = function(blob) {
- var fd = new FormData();
- fd.append('chunk', blob);
- fd.append('chunk_size', blob.size);
-
- kimchi.uploadVolumeToSP(kimchi.selectedSP, blobFile.name, {
- formData: fd
- }, function(result) {
- if (uploaded < blobFile.size)
- setTimeout(doUpload, 500);
- }, onError);
-
- uploaded += blob.size
- };
-
- // Check file exists and has read permission
- try {
- var blob = blobFile.slice(0, 20);
- var reader = new FileReader();
- reader.onloadend = function(e) {
- if (e.loaded == 0)
- wok.message.error.code('KCHAPI6008E');
- else
- createUploadVol();
- };
-
- reader.readAsBinaryString(blob);
- } catch (err) {
- wok.message.error.code('KCHAPI6008E');
- return;
- }
-
- var doUpload = function() {
- try {
- var blob = blobFile.slice(uploaded, uploaded + chunkSize);
- var reader = new FileReader();
- reader.onloadend = function(e) {
- if (e.loaded == 0)
- wok.message.error.code('KCHAPI6009E');
- else
- uploadRequest(blob);
- };
-
- reader.readAsBinaryString(blob);
- } catch (err) {
- wok.message.error.code('KCHAPI6009E');
- return;
- }
- }
-
- var trackVolCreation = function(taskid) {
- var onTaskResponse = function(result) {
- var taskStatus = result['status'];
- var taskMsg = result['message'];
- if (taskStatus == 'running') {
- if (taskMsg != 'ready for upload') {
- setTimeout(function() {
- trackVolCreation(taskid);
- }, 2000);
- } else {
- wok.topic('kimchi/storageVolumeAdded').publish();
- doUpload();
- }
- }
- };
- kimchi.getTask(taskid, onTaskResponse, onError);
- };
- };
-
- $(addButton).on('click', function(event) {
- $(this).prop('disabled', true);
- $(typeRadios).prop('disabled', true);
- if(type === 'download') {
- fetchRemoteFile();
- }
- else {
- uploadFile();
- }
- event.preventDefault();
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.template_add_main.js b/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
deleted file mode 100644
index 01a47c2..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.switchPage = function(fromPageId, toPageId, direction) {
- direction = direction || 'left';
- var toLeftBegin;
- var fromLeftEnd;
- if('left' === direction) {
- toLeftBegin = '100%';
- fromLeftEnd = '-100%';
- } else if('right' === direction) {
- toLeftBegin = '-100%';
- fromLeftEnd = '100%';
- }
- var formPage = $('#'+fromPageId);
- var toPage = $('#'+toPageId);
- toPage.css({
- left: toLeftBegin
- });
- formPage.animate({
- left: fromLeftEnd,
- opacity: 0.1
- }, 400);
- toPage.animate({
- left: '0',
- opacity: 1
- }, 400);
-};
-
-kimchi.template_add_main = function() {
- kimchi.deepScanHandler = null;
- // 1-1 local iso
- $('#iso-local').click(function() {
- kimchi.switchPage('iso-type-box', 'iso-local-box');
- initLocalIsoField();
- initIsoFileField();
- kimchi.listIsos(function(isos) {
- if (isos && isos.length) {
- showLocalIsoField(isos);
- $('#iso-more').show();
- } else {
- $('#iso-search').show();
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-
- $('#iso-local-box-back').click(function() {
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- kimchi.switchPage('iso-local-box', 'iso-type-box', 'right');
- });
-
- $('#iso-search').click(function() {
- var settings = {
- content : i18n['KCHTMPL6002M']
- };
- wok.confirm(settings, function() {
- $('#iso-search').hide();
- $('#iso-search-loading').show();
- deepScan('#iso-search');
- });
- });
-
- $('#iso-more').click(function() {
- var settings = {
- content : i18n['KCHTMPL6002M']
- };
- wok.confirm(settings, function() {
- $('#iso-more').hide();
- $('#iso-more-loading').show();
- deepScan('#iso-more');
- });
- });
-
- $('#iso-search-loading').click(function() {
- $('#iso-search-loading').hide();
- $('#iso-search').show();
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- });
-
- $('#iso-more-loading').click(function() {
- $('#iso-more-loading').hide();
- $('#iso-more').show();
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- });
-
- var deepScan = function(button) {
- kimchi.deepScanHandler = kimchi.stepListDeepScanIsos(function(isos, isFinished) {
- if (isos && isos.length) {
- if(button === '#iso-search') {
- $(button + '-loading').hide();
- button = '#iso-more';
- $(button + '-loading').show();
- }
- showLocalIsoField(isos);
- } else {
- if (isFinished) {
- wok.message.warn(i18n['KCHTMPL6001W']);
- }
- }
- if (isFinished) {
- $(button + '-loading').hide();
- $(button).show();
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $(button + '-loading').hide();
- $(button).show();
- });
- };
-
- //1-1-1 local iso list
- var initLocalIsoField = function() {
- kimchi.isoInfo = {};
- $('#local-iso-field').hide();
- $('#select-all-local-iso').prop('checked', false);
- $('#btn-template-local-iso-create').attr('disabled', 'disabled');
- $('#iso-search').hide();
- $('#iso-more').hide();
- $('#iso-search-loading').hide();
- $('#iso-more-loading').hide();
- $('#list-local-iso').empty();
- };
-
- var showLocalIsoField = function(isos) {
- var html = '';
- var template = $('#tmpl-list-local-iso').html();
- $.each(isos, function(index, volume) {
- var isoId = volume.os_distro + '*' + volume.name + '*' + volume.os_version;
- if (!kimchi.isoInfo[isoId]) {
- volume.isoId = isoId;
- volume.capacity = wok.changetoProperUnit(volume.capacity, 1);
- kimchi.isoInfo[isoId] = volume;
- html += wok.substitute(template, volume);
- }
- });
- $('#list-local-iso').append(html);
- $('#local-iso-field').show();
- };
-
- $('#select-all-local-iso').click(function() {
- $('#list-local-iso [type="checkbox"]').prop('checked', $(this).prop('checked'));
- if ($(this).prop('checked')) {
- $('#btn-template-local-iso-create').removeAttr('disabled');
- } else {
- $('#btn-template-local-iso-create').attr('disabled', 'disabled');
- }
- });
-
- $('#list-local-iso').on('click', '[type="checkbox"]', function() {
- var checkedLength = $('#list-local-iso [type="checkbox"]:checked').length;
- if (checkedLength) {
- $('#btn-template-local-iso-create').removeAttr('disabled');
- var length = $('#list-local-iso [type="checkbox"]').length;
- $('#select-all-local-iso').prop('checked', length == checkedLength);
- } else {
- $('#select-all-local-iso').prop('checked', false);
- $('#btn-template-local-iso-create').attr('disabled', 'disabled');
- }
- });
-
- $('#btn-template-local-iso-create').click(function() {
- submitIso('form-local-iso');
- });
-
- //1-1-2 local iso file
- var initIsoFileField = function() {
- $('#iso-file-check').prop('checked', false);
- $('#iso-file-box').hide();
- $('#iso-file').val('');
- $('#btn-template-file-create').attr('disabled', 'disabled');
- };
-
- $('#iso-file-check').click(function() {
- if ($(this).prop('checked')) {
- $('#iso-file-box').slideDown();
- } else {
- $('#iso-file-box').slideUp();
- }
- });
-
- $('#iso-file').on('input propertychange', function() {
- if ($('#iso-file').val()) {
- $('#btn-template-file-create').removeAttr('disabled');
- } else {
- $('#btn-template-file-create').attr('disabled', 'disabled');
- }
- });
-
- $('#btn-template-file-create').click(function() {
- var isoFile = $('#iso-file').val();
- if (!kimchi.template_check_path(isoFile)) {
- wok.message.error.code('KCHAPI6003E');
- return;
- }
- var data = {
- "cdrom" : isoFile
- };
- addTemplate(data);
- });
-
- //1-2 remote iso
- $('#iso-remote').css('opacity', 0.3).css('cursor', 'not-allowed');
-
- var enabledRemoteIso = function() {
- if (kimchi.capabilities == undefined) {
- setTimeout(enabledRemoteIso, 2000);
- return;
- }
-
- if (kimchi.capabilities.qemu_stream != true) {
- return;
- }
-
- $('#iso-remote').css('opacity', 1).css('cursor', 'pointer');
- $('#iso-remote').click(function() {
- kimchi.switchPage('iso-type-box', 'iso-remote-box');
- initRemoteIsoField();
- initIsoUrlField();
- kimchi.listDistros(function(isos) {
- showRemoteIsoField(isos);
- }, function() {
- });
- });
- };
- enabledRemoteIso();
-
- $('#iso-remote-box-back').click(function() {
- kimchi.switchPage('iso-remote-box', 'iso-type-box', 'right');
- });
-
- //1-2-1 remote iso list
- var initRemoteIsoField = function() {
- $('#load-remote-iso').show();
- $('#remote-iso-field').hide();
- $('#iso-url-field').hide();
- $('#select-all-remote-iso').prop('checked', false);
- $('#btn-template-remote-iso-create').attr('disabled', 'disabled');
- };
-
- var showRemoteIsoField = function(isos) {
- if (isos && isos.length) {
- kimchi.isoInfo = {};
- var html = '';
- var template = $('#tmpl-list-remote-iso').html();
- $.each(isos, function(index, volume) {
- var isoId = volume.os_distro + '*' + volume.name + '*' + volume.os_version;
- if (!kimchi.isoInfo[isoId]) {
- volume.isoId = isoId;
- kimchi.isoInfo[isoId] = volume;
- html += wok.substitute(template, volume);
- }
- });
- $('#list-remote-iso').html(html);
- $('#load-remote-iso').hide()
- $('#remote-iso-field').show();
- $('#iso-url-field').show();
- } else {
- $('#load-remote-iso').hide()
- $('#iso-url-field').show();
- wok.message.warn(i18n['KCHTMPL6001W']);
- }
- };
-
- $('#select-all-remote-iso').click(function() {
- $('#list-remote-iso [type="checkbox"]').prop('checked', $(this).prop('checked'));
- if ($(this).prop('checked')) {
- $('#btn-template-remote-iso-create').removeAttr('disabled');
- } else {
- $('#btn-template-remote-iso-create').attr('disabled', 'disabled');
- }
- });
-
- $('#list-remote-iso').on('click', '[type="checkbox"]', function() {
- var checkedLength = $('#list-remote-iso [type="checkbox"]:checked').length;
- if (checkedLength) {
- $('#btn-template-remote-iso-create').removeAttr('disabled');
- var length = $('#list-remote-iso [type="checkbox"]').length;
- $('#select-all-remote-iso').prop('checked', length == checkedLength);
- } else {
- $('#select-all-remote-iso').prop('checked', false);
- $('#btn-template-remote-iso-create').attr('disabled', 'disabled');
- }
- });
-
- $('#btn-template-remote-iso-create').click(function() {
- submitIso('form-remote-iso');
- });
-
- //1-2-2 remote iso url
- var initIsoUrlField = function() {
- $('#iso-url-check').prop('checked', false);
- $('#iso-url-box').hide();
- $('#iso-url').val('');
- $('#btn-template-url-create').attr('disabled', 'disabled');
- }
-
- $('#iso-url-check').click(function() {
- if ($(this).prop('checked')) {
- $('#iso-url-box').slideDown();
- } else {
- $('#iso-url-box').slideUp();
- }
- });
-
- $('#iso-url').on('input propertychange', function() {
- if ($('#iso-url').val()) {
- $('#btn-template-url-create').removeAttr('disabled');
- } else {
- $('#btn-template-url-create').attr('disabled', 'disabled');
- }
- });
-
- $('#vm-image-local').click(function(){
- kimchi.switchPage('iso-type-box', 'vm-image-local-box');
- });
- $('#vm-image-local-box-back').click(function(){
- kimchi.switchPage('vm-image-local-box', 'iso-type-box', 'right');
- });
- $('input', '#vm-image-local-box').on('keyup cut paste', function(){
- setTimeout(function(){
- var isValid = kimchi.template_check_path($('input', '#vm-image-local-box').val());
- $('input', '#vm-image-local-box').toggleClass('invalid-field', !isValid);
- $('button', $('.body', '#vm-image-local-box')).button(isValid ? "enable" : "disable");
- }, 0);
- });
- $('button', $('.body', '#vm-image-local-box')).button({
- disabled: true
- }).click(function(){
- $('input', '#vm-image-local-box').prop('disabled', true);
- $(this).button('option', {
- label: i18n['KCHAPI6008M'],
- disabled: true
- });
- addTemplate({disks:[{base:$('input', '#vm-image-local-box').val()}]}, function(){
- $('input', '#vm-image-local-box').prop('disabled', false);
- $('button', $('.body', '#vm-image-local-box')).button('option', {
- label: i18n['KCHAPI6005M'],
- disabled: false
- });
- });
- });
-
- $('#btn-template-url-create').click(function() {
- var isoUrl = $('#iso-url').val();
- if (!kimchi.template_check_url(isoUrl)) {
- wok.message.error.code('KCHAPI6004E');
- return;
- }
- var data = {
- "cdrom" : isoUrl
- };
- addTemplate(data);
- });
-
- //do create
- var addTemplate = function(data, callback) {
- kimchi.createTemplate(data, function() {
- if(callback) callback();
- kimchi.doListTemplates();
- wok.window.close();
- wok.topic('templateCreated').publish();
- }, function(err) {
- if(callback) callback();
- wok.message.error(err.responseJSON.reason);
- });
- };
-
- var submitIso = function(formId) {
- var formData = $('#' + formId).serializeObject();
- if (formData.iso) {
- var length = 0;
- var successNum = 0;
- var addTemplate = function(isoInfo) {
- var data = {
- "os_distro" : isoInfo.os_distro,
- "os_version" : isoInfo.os_version,
- "cdrom" : isoInfo.path
- };
- kimchi.createTemplate(data, function() {
- successNum++;
- $('input[value="' + isoInfo.isoId + '"]').prop('checked', false);
- $('.check-all>input').prop('checked', false);
- kimchi.doListTemplates();
- wok.topic('templateCreated').publish(data);
- if (successNum === length) {
- wok.window.close();
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- };
- if (formData.iso instanceof Array) {
- length = formData.iso.length;
- $.each(formData.iso, function(index, value) {
- addTemplate(kimchi.isoInfo[value]);
- });
- } else {
- length = 1;
- addTemplate(kimchi.isoInfo[formData.iso]);
- }
- }
- };
-};
-
-kimchi.template_check_url = function(url) {
- var reg = /(https|http|ftp|ftps|tftp):\/\//;
- if (url.constructor === String) {
- return reg.test(url);
- }
- return false;
-};
-
-kimchi.template_check_path = function(filePath) {
- var reg = /((\/([0-9a-zA-Z-_ \.]+))+)$/;
- if (filePath.constructor === String) {
- return reg.test(filePath);
- }
- return false;
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js b/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
deleted file mode 100644
index d40b6c7..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.template_edit_main = function() {
- var templateEditMain = $('#edit-template-tabs');
- var origDisks;
- var origPool;
- var origNetworks;
- var templateDiskSize;
- $('#template-name', templateEditMain).val(kimchi.selectedTemplate);
- templateEditMain.tabs();
-
- var initTemplate = function(template) {
- origDisks = template.disks;
- origPool = template.storagepool;
- origNetworks = template.networks;
- for(var i=0;i<template.disks.length;i++){
- if(template.disks[i].base){
- template["vm-image"] = template.disks[i].base;
- $('.templ-edit-cdrom').addClass('hide');
- $('.templ-edit-vm-image').removeClass('hide');
- break;
- }
- }
- for ( var prop in template) {
- var value = template[prop];
- if (prop == 'graphics') {
- value = value["type"];
- }
- $('input[name="' + prop + '"]', templateEditMain).val(value);
- }
-
- var vncOpt = [{label: 'VNC', value: 'vnc'}];
- $('#template-edit-graphics').append('<option selected>VNC</option>');
- $('#template-edit-graphics').append('<option>Spice</option>');
- wok.select('template-edit-graphics-list', vncOpt);
- var enableSpice = function() {
- if (kimchi.capabilities == undefined) {
- setTimeout(enableSpice, 2000);
- return;
- }
- if (kimchi.capabilities.qemu_spice == true) {
- spiceOpt = [{label: 'Spice', value: 'spice'}]
- wok.select('template-edit-graphics-list', spiceOpt);
- }
- };
- enableSpice();
- var initStorage = function(result) {
- var scsipools = {};
- var addStorageItem = function(storageData) {
- var thisName = storageData.storageName;
- var nodeStorage = $.parseHTML(wok.substitute($('#template-storage-pool-tmpl').html(), storageData));
- $('.template-tab-body', '#form-template-storage').append(nodeStorage);
- var storageOptions = '';
- var scsiOptions = '';
- $('#selectStorageName').find('option').remove();
- $.each(result, function(index, storageEntities) {
- if((storageEntities.state === 'active') && (storageEntities.type != 'kimchi-iso')) {
- if(storageEntities.type === 'iscsi' || storageEntities.type === 'scsi') {
- kimchi.listStorageVolumes(storageEntities.name, function(currentVolume) {
- $.each(currentVolume, function(indexSCSI, scsiEntities) {
- var tmpPath = storageEntities.name + '/' + scsiEntities.name;
- var isSlected = tmpPath === thisName ? ' selected' : '';
- scsiOptions += '<option' + isSlected + '>' + tmpPath + '</option>';
- });
- $('#selectStorageName').append(scsiOptions);
- }, function() {});
- } else {
- var isSlected = storageEntities.name === thisName ? ' selected' : '';
- storageOptions += '<option' + isSlected + '>' + storageEntities.name + '</option>';
- }
- }
- });
- $('#selectStorageName').append(storageOptions);
-
- // Set disk format
- $('#diskFormat').val(storageData.storageDiskFormat);
- $('#diskFormat').on('change', function() {
- $('.template-storage-disk-format').val($(this).val());
- });
-
- $('#selectStorageName').change(function() {
- var selectedItem = $(this).parent().parent();
- var tempStorageNameFull = $(this).val();
- var tempName = tempStorageNameFull.split('/');
- var tempStorageName = tempName[0];
- $('.template-storage-name').val(tempStorageNameFull);
- kimchi.getStoragePool(tempStorageName, function(info) {
- tempType = info.type;
- selectedItem.find('.template-storage-type').val(tempType);
- if (tempType === 'iscsi' || tempType === 'scsi') {
- kimchi.getStoragePoolVolume(tempStorageName, tempName[tempName.length-1], function(info) {
- volSize = info.capacity / Math.pow(1024, 3);
- $('.template-storage-disk', selectedItem).attr('readonly', true).val(volSize);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled', true).change();
- });
- } else if (tempType === 'logical') {
- $('.template-storage-disk', selectedItem).attr('readonly', false);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled', true).change();
- } else {
- $('.template-storage-disk', selectedItem).attr('readonly', false);
- if ($('#diskFormat').prop('disabled') == true) {
- $('#diskFormat').val('qcow2');
- $('#diskFormat').prop('disabled', false).change();
- }
- }
- });
- });
- };
-
- if ((origDisks && origDisks.length) && (origPool && origPool.length)) {
- splitPool = origPool.split('/');
- var defaultPool = splitPool[splitPool.length-1];
- var defaultType;
-
- kimchi.getStoragePool(defaultPool, function(info) {
- defaultType = info.type;
- $.each(origDisks, function(index, diskEntities) {
- var storageNodeData = {
- viewMode : '',
- editMode : 'hide',
- storageName : defaultPool,
- storageType : defaultType,
- storageDisk : diskEntities.size,
- storageDiskFormat : diskEntities.format ? diskEntities.format : 'qcow2'
- }
-
- if (diskEntities.volume) {
- kimchi.getStoragePoolVolume(defaultPool, diskEntities.volume, function(info) {
- var volSize = info.capacity / Math.pow(1024, 3);
- var nodeData = storageNodeData
- nodeData.storageName = defaultPool + '/' + diskEntities.volume;
- nodeData.storageDisk = volSize;
- addStorageItem(nodeData);
- $('.template-storage-disk').attr('readonly', true);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled', true).change();
- });
- } else if (defaultType === 'logical') {
- addStorageItem(storageNodeData);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled', true).change();
- } else {
- addStorageItem(storageNodeData);
- }
- });
- });
- }
-
- $('#template-edit-storage-add-button').button({
- icons: {
- primary: "ui-icon-plusthick"
- },
- text: false,
- disabled: true
- }).click(function(event) {
- event.preventDefault();
- var storageNodeData = {
- viewMode : 'hide',
- editMode : '',
- storageName : 'null',
- storageType : 'dir',
- storageDisk : '10'
- }
- addStorageItem(storageNodeData);
- });
- };
- var initInterface = function(result) {
- var networkItemNum = 0;
- var addInterfaceItem = function(networkData) {
- var networkName = networkData.networkV;
- var nodeInterface = $.parseHTML(wok.substitute($('#template-interface-tmpl').html(), networkData));
- $('.template-tab-body', '#form-template-interface').append(nodeInterface);
- $('.delete', '#form-template-interface').button({
- icons : {primary : 'ui-icon-trash'},
- text : false
- }).click(function(evt) {
- evt.preventDefault();
- $(this).parent().parent().remove();
- });
- var networkOptions = '';
- for(var i=0;i<result.length;i++){
- if(result[i].state === "active") {
- var isSlected = networkName===result[i].name ? ' selected' : '';
- networkOptions += '<option' + isSlected + '>' + result[i].name + '</option>';
- }
- }
- $('select', '#form-template-interface #networkID' + networkItemNum).append(networkOptions);
- networkItemNum += 1;
- };
- if(result && result.length > 0) {
- for(var i=0;i<origNetworks.length;i++) {
- addInterfaceItem({
- networkID : 'networkID' + networkItemNum,
- networkV : origNetworks[i],
- type : 'network'
- });
- }
- }
- $('#template-edit-interface-add-button').button({
- icons: {
- primary: 'ui-icon-plusthick'
- },
- text: false
- }).click(function(evt) {
- evt.preventDefault();
- addInterfaceItem({
- networkID : 'networkID' + networkItemNum,
- networkV : 'default',
- type : 'network'
- });
- });
- };
- var initProcessor = function(){
- var setCPUValue = function(){
- if(!$('#cores').hasClass("invalid-field")&&$('#cores').val()!=""){
- $("#cpus").val(parseInt($("#cores").val())*parseInt($("#threads").val()));
- }else{
- $("#cpus").val('');
- }
- };
- $("input:text", "#form-template-processor").on('keyup', function(){
- $(this).toggleClass("invalid-field", !$(this).val().match('^[0-9]*$'));
- if($(this).prop('id')=='cores') setCPUValue();
- });
- $("input:checkbox", "#form-template-processor").click(function(){
- $(".topology", "#form-template-processor").toggleClass("hide", !$(this).prop("checked"));
- $("#cpus").attr("disabled", $(this).prop("checked"));
- setCPUValue();
- });
- $('select', '#form-template-processor').change(function(){
- setCPUValue();
- });
- kimchi.getCPUInfo(function(data){
- var options = "";
- for(var i=0;Math.pow(2,i)<=data.threads_per_core;i++){
- var lastOne = Math.pow(2,i+1)>data.threads_per_core?" selected":"";
- options += "<option"+lastOne+">"+Math.pow(2,i)+"</option>";
- }
- $('select', '#form-template-processor').append(options);
- if(template.cpus) $("#cpus").val(template.cpus);
- var topo = template.cpu_info.topology;
- if(topo&&topo.cores) $("#cores").val(topo.cores);
- if(topo&&topo.threads){
- $('select', '#form-template-processor').val(topo.threads);
- $("input:checkbox", "#form-template-processor").trigger('click');
- }
- });
- };
- kimchi.listNetworks(initInterface);
- kimchi.listStoragePools(initStorage);
- initProcessor();
- };
- kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
-
-
- $('#tmpl-edit-button-save').on('click', function() {
- var editableFields = [ 'name', 'memory', 'disks', 'graphics'];
- var data = {};
- //Fix me: Only support one storage pool now
- var storages = $('.template-tab-body .item', '#form-template-storage');
- var tempName = $('.template-storage-name', storages).val();
- var tmpItem = $('#form-template-storage .item');
- tempName = tempName.split('/');
- var tempNameHead = tempName[0];
- var tempNameTail = tempNameHead;
- if($('.template-storage-type', tmpItem).val() === 'iscsi' || $('.template-storage-type', tmpItem).val() == 'scsi') {
- tempNameTail = tempName[tempName.length-1];
- }
- tempName = '/plugins/kimchi/storagepools/' + tempNameHead;
- data['storagepool'] = tempName;
- $.each(editableFields, function(i, field) {
- /* Support only 1 disk at this moment */
- if (field == 'disks') {
- if($('.template-storage-type', tmpItem).val() === 'iscsi' || $('.template-storage-type', tmpItem).val() == 'scsi') {
- origDisks[0]['size'] && delete origDisks[0]['size'];
- origDisks[0]['volume'] = tempNameTail;
- } else {
- origDisks[0]['volume'] && delete origDisks[0]['volume'];
- origDisks[0].size = Number($('.template-storage-disk', tmpItem).val());
- }
- origDisks[0].format = $('.template-storage-disk-format', tmpItem).val();
- data[field] = origDisks;
- }
- else if (field == 'graphics') {
- var type = $('#form-template-general [name="' + field + '"]').val();
- data[field] = {'type': type};
- }
- else {
- data[field] = $('#form-template-general [name="' + field + '"]').val();
- }
- });
- data['memory'] = Number(data['memory']);
- data['cpus'] = parseInt($('#cpus').val());
- if($("input:checkbox", "#form-template-processor").prop("checked")){
- data['cpu_info'] = {
- topology: {
- sockets: 1,
- cores: parseInt($("#cores").val()),
- threads: parseInt($("#threads").val())
- }
- };
- }else{
- data['cpu_info'] = {};
- }
- var networks = $('.template-tab-body .item', '#form-template-interface');
- var networkForUpdate = new Array();
- $.each(networks, function(index, networkEntities) {
- var thisValue = $('select', networkEntities).val();
- networkForUpdate.push(thisValue);
- });
- if (networkForUpdate instanceof Array) {
- data.networks = networkForUpdate;
- } else if (networkForUpdate != null) {
- data.networks = [networkForUpdate];
- } else {
- data.networks = [];
- }
-
- kimchi.updateTemplate($('#template-name').val(), data, function() {
- kimchi.doListTemplates();
- wok.window.close();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.template_main.js b/plugins/kimchi/ui/js/src/kimchi.template_main.js
deleted file mode 100644
index b09fe12..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.template_main.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.doListTemplates = function() {
- kimchi.listTemplates(function(result) {
- if (result && result.length) {
- $('#noTemplates').hide();
- var listHtml = '';
- var templateHtml = $('#templateTmpl').html();
- $.each(result, function(index, value) {
- var isLocal;
- if(value.cdrom){
- isLocal = /^\//.test(value['cdrom']);
- }else{
- for(var i=0;i<value.disks.length;i++){
- if(value.disks[i].base){
- isLocal = /^\//.test(value.disks[i].base);
- break;
- }
- }
- }
- if(isLocal){
- value.location = "plugins/kimchi/images/theme-default/icon-local.png";
- }else{
- value.location = "plugins/kimchi/images/theme-default/icon-remote.png";
- }
- listHtml += wok.substitute(templateHtml, value);
- });
- $('#templateList').html(listHtml);
- kimchi.templateBindClick();
- } else {
- $('#templateList').html('');
- $('#noTemplates').show();
- }
- $('html').removeClass('processing');
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $('html').removeClass('processing');
- });
-};
-
-kimchi.templateBindClick = function() {
- $('.template-edit').on('click', function(event) {
- var templateName = $(this).data('template');
- kimchi.selectedTemplate = templateName;
- wok.window.open("plugins/kimchi/template-edit.html");
- });
- $('.template-clone').on('click', function(event) {
- kimchi.selectedTemplate = $(this).data('template');
- $('html').addClass('processing');
- kimchi.cloneTemplate(kimchi.selectedTemplate, function() {
- kimchi.doListTemplates();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- kimchi.doListTemplates();
- });
- });
- $('.template-delete').on('click', function(event) {
- var $template = $(this);
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHTMPL6003M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- var templateName = $template.data('template');
- kimchi.deleteTemplate(templateName, function() {
- kimchi.doListTemplates();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- });
- });
-}
-kimchi.hideTitle = function() {
- $('#tempTitle').hide();
-};
-
-kimchi.template_main = function() {
- if(wok.tabMode['templates'] === 'admin') {
- $('.tools').attr('style','display');
- $("#template-add").on("click", function(event) {
- wok.window.open({
- url: 'plugins/kimchi/template-add.html',
- close: function() {
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- }
- });
- });
- }
-
- kimchi.doListTemplates();
-};
diff --git a/plugins/kimchi/ui/pages/Makefile.am b/plugins/kimchi/ui/pages/Makefile.am
deleted file mode 100644
index 56288e3..0000000
--- a/plugins/kimchi/ui/pages/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-SUBDIRS = help
-
-htmldir = $(datadir)/wok/plugins/kimchi/ui/pages
-
-dist_html_DATA = $(wildcard *.tmpl) $(NULL)
diff --git a/plugins/kimchi/ui/pages/guest-add.html.tmpl b/plugins/kimchi/ui/pages/guest-add.html.tmpl
deleted file mode 100644
index 3770d96..0000000
--- a/plugins/kimchi/ui/pages/guest-add.html.tmpl
+++ /dev/null
@@ -1,98 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<body>
-<div class="window" style="width: 900px;height: 580px;">
- <header>
- <h1 class="title h1 grey">$_("Create a New Virtual Machine")</h1>
- </header>
- <div class="content">
- <form id="form-vm-add">
- <section class="form-section">
- <h2>1. $_("Virtual Machine Name")</h2>
- <div class="field">
- <input type="text" class="text" style="width: 300px" name="name"><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("The name used to identify the virtual machine. If omitted, a name will be chosen based on the template used.")
- </p>
- </div>
- </section>
- <section class="form-section">
- <h2>2. $_("Template")</h2>
- <div class="field">
- <div class="text-help">
- <div id="prompt-create-template" class="hidden">
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <div class="text-help help-inline">$_("Please create a template first.")</div>
- <a id="btn-create-template" class="btn-normal" href="templates.html">
- <span class="text">$_("Create a Template")</span>
- </a>
- </div>
- <div id="prompt-choose-template" class="hidden">
- <span class="icon-info-circled light-grey c1"></span>
- <span class="text-help">$_("Please choose a template.")</span>
- </div>
- </div>
- <ul id="templateTile" class="tile-check tile-template">
- </ul>
- <script type="html/text" id="tmpl-template" class="tmpl-html">
- <li>
- <label>
- <input type="radio" name="template" value="/plugins/kimchi/templates/{name}">
- <div class="info">
- <div class="summary os-icon">
- <img src="{icon}">
- <span class="title">{name}</span>
- </div>
- <ul class="list-info">
- <li><label>$_("OS")</label><span>{os_distro}</span></li>
- <li><label>$_("OS Version")</label><span>{os_version}</span></li>
- <li><label>$_("CPUS")</label><span>{cpus}</span></li>
- <li><label>$_("Memory")</label><span>{memory}M</span></li>
- </ul>
- </div>
- </label>
- </li>
- </script>
- </div>
- </section>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="vm-doAdd" class="btn-normal" disabled="disabled" href="javascript:void(0);"><span class="text">$_("Create")</span></button>
- <button id="vm-doAdding" class="btn-normal" disabled="disabled" style="display:none" href="javascript:void(0);"><span class="text">$_("Creating...")</span></button>
- <button id="vm-add=cancel" class="btn-normal close" type="button">
- <span class="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.guest_add_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/guest-edit.html.tmpl b/plugins/kimchi/ui/pages/guest-edit.html.tmpl
deleted file mode 100644
index c5acf04..0000000
--- a/plugins/kimchi/ui/pages/guest-edit.html.tmpl
+++ /dev/null
@@ -1,311 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-<div id="guest-edit-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Edit Guest")</h1>
- </header>
- <div class="content">
- <div id="guest-edit-tabs">
- <ul>
- <li>
- <a href="#form-guest-edit-general">$_("General")</a>
- </li>
- <li>
- <a href="#form-guest-edit-storage">$_("Storage")</a>
- </li>
- <li>
- <a href="#form-guest-edit-interface">$_("Interface")</a>
- </li>
- <li>
- <a href="#form-guest-edit-permission">$_("Permission")</a>
- </li>
- <li>
- <a href="#form-guest-edit-pci">$_("Host PCI Device")</a>
- </li>
- <li>
- <a href="#form-guest-edit-snapshot">$_("Snapshot")</a>
- </li>
- </ul>
- <form id="form-guest-edit-general">
- <fieldset class="guest-edit-fieldset">
- <div class="edit-general-inline">
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-id-textbox">
- $_("Name")
- </label>
- </div>
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-cores-textbox">
- $_("CPUs")
- </label>
- </div>
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-memory-textbox">
- $_("Memory (MB)")
- </label>
- </div>
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-icon-textbox">
- $_("Icon")
- </label>
- </div>
- </div>
- <div class="edit-general-inline">
- <div class="guest-edit-wrapper-controls">
- <input id="guest-edit-id-textbox"
- name="name" type="text" />
- </div>
- <div class="guest-edit-wrapper-controls">
- <input
- id="guest-edit-cores-textbox"
- name="cpus"
- type="text" />
- </div>
- <div class="guest-edit-wrapper-controls">
- <input id="guest-edit-memory-textbox"
- name="memory"
- type="text" />
- </div>
- <div class="guest-edit-wrapper-controls">
- <input
- id="guest-edit-icon-textbox"
- name="icon"
- type="text"
- disabled="disabled" />
- </div>
- </div>
- </fieldset>
- </form>
- <form id="form-guest-edit-storage">
- <div class="header">
- <span class="cell">$_("Device")</span>
- <span class="cell">$_("Path")</span>
- <button type="button" id="guest-edit-attach-cdrom-button" class="action-area attach"></button>
- </div>
- <div class="body"></div>
- </form>
- <form id="form-guest-edit-interface" class="guest-edit-interface">
- <div class="header">
- <span class="cell">$_("Network")</span>
- <span class="cell">$_("Type")</span>
- <span class="cell">$_("MAC Address")</span>
- <button class="add action-area"></button>
- </div>
- <div class="body"></div>
- </form>
- <form id="form-guest-edit-permission" class="guest-edit-permission">
- <div class="pam">
- <div class="column avail">
- <div class="title">$_("Available system users and groups")</div>
- <input type="text" id="permission-avail-searchBox">
- <div class="body">
- <div class="head">
- <div class="column column-user"><div class="item">Users</div></div>
- <div class="column column-group"><div class="item">Groups</div></div>
- </div>
- <div id="permission-avail-users" class="column column-user"></div>
- <div id="permission-avail-groups" class="column column-group"></div>
- </div>
- </div>
- <div class="column control">
- <button id="permissionGo"> > </button>
- <button id="permissionBack"> < </button>
- </div>
- <div class="column selected">
- <div class="title">$_("Selected system users and groups")</div>
- <input type="text" id="permission-sel-searchBox">
- <div class="body">
- <div class="head">
- <div class="column column-user"><div class="item">Users</div></div>
- <div class="column column-group"><div class="item">Groups</div></div>
- </div>
- <div id="permission-sel-users" class="column column-user"></div>
- <div id="permission-sel-groups" class="column column-group"></div>
- </div>
- </div>
- </div>
- <div class="ldap">
- <div class="header">
- <span class="cell">$_("User")</span>
- <button type="button" id="guest-edit-add-user-button" class="action-area add"></button>
- </div>
- <div class="body"></div>
- </div>
- </form>
- <form id="form-guest-edit-pci" class="guest-edit-pci">
- <div class="guest-scroll-indent">
- <div class="filter">
- <span class="group">
- <select class="control">
- <option value="all">$_("All")</option>
- <option value="toAdd">$_("To Add")</option>
- <option value="added">$_("Added")</option>
- </select><input type="text" class="control" placeholder="$_("filter")">
- </span>
- </div>
- <div class="header">
- <span class="cell name">$_("Name")</span>
- <span class="cell product">$_("Product")</span>
- <span class="cell vendor">$_("Vendor")</span>
- </div>
- <div class="body"></div>
- </div>
- </form>
- <form id="form-guest-edit-snapshot" class="guest-edit-snapshot">
- <div class="header">
- <span class="cell sel"></span>
- <span class="cell name">$_("Name")</span>
- <span class="cell created">$_("Created")</span>
- <button class="add action-area"></button>
- </div>
- <div class="task"></div>
- <div class="body"></div>
- </form>
- </div>
- </div>
- <footer>
- <div id="action-button-container" class="btn-group hidden">
- <button id="guest-edit-button-save" class="btn-normal">
- <span class="text">$_("Save")</span>
- </button>
- </div>
- <button id="guest-edit-button-cancel" class="btn-normal close">
- <span class="text">$_("Cancel")</span>
- </button>
- </footer>
-</div>
-<script id="cdrom-row-tmpl" type="text/html">
- <div class="item view" id="cdrom-{dev}">
- <span class="cell dev">
- <input type="text" readonly="readonly"
- id="cdrom-dev-{dev}" name="cdrom-dev-{dev}" value="{dev}" />
- </span>
- <span class="cell path">
- <input id="cdrom-path-{dev}" name="cdrom" type="text"
- data-vm="{vm}" data-dev="{dev}"
- value="{path}" readonly="readonly" />
- </span>
- <span class="action-area">
- <button type="button" class="guest-edit-cdrom-button replace"
- data-vm="{vm}" data-dev="{dev}"
- title='$_("Replace")'>
- </button>
- <button type="button" class="guest-edit-cdrom-button detach"
- data-vm="{vm}" data-dev="{dev}" data-type="{type}"
- title='$_("Detach")'>
- </button>
- <button type="button" class="guest-edit-cdrom-button save hidden"
- data-vm="{vm}" data-dev="{dev}"
- title='$_("Save")'>
- </button>
- <button type="button" class="guest-edit-cdrom-button cancel hidden"
- data-vm="{vm}" data-dev="{dev}"
- title='$_("Cancel")'>
- </button>
- </span>
- </div>
-</script>
-<script id="interface-tmpl" type="text/html">
- <div class="item" id="{mac}">
- <span class="cell">
- <label id="label-network-{id}" class="{viewMode}">{network}</label>
- <select class="{editMode}"></select>
- </span>
- <span class="cell">
- <span>{type}</span>
- </span>
- <span class="cell">
- <label id="label-mac-{id}" class="{viewMode}">{mac}</label>
- <input class="{editMode}" type="text"
- id="edit-mac-{id}" name="{mac}" value="{mac}" />
- </span>
- <span class="action-area {editMode}">
- <button class="save"></button><button class="cancel"></button>
- </span>
- <span class="action-area {viewMode}">
- <button class="edit"></button><button class="delete"></button>
- </span>
- <div>
-</script>
-<script id="ldap-user-tmpl" type="text/html">
- <div class="item" id="{user}">
- <span class="cell">
- <label class="{viewMode}">{user}</label>
- <input type="text" placeholder="LDAP User ID,e.g.foo at foo.com" class="{editMode}"/>
- </span>
- <span class="action-area">
- <button class="delete"></button>
- </span>
- <div>
-</script>
-<script id="disk-row-tmpl" type="text/html">
- <div class="item" id="cdrom-{dev}">
- <span class="cell dev">
- <input type="text" readonly="readonly"
- id="disk-dev-{dev}" name="disk-dev-{dev}" value="{dev}" />
- </span>
- <span class="cell path">
- <input id="disk-path-{dev}" name="path-{dev}" type="text"
- data-vm="{vm}" data-dev="{dev}"
- value="{path}" readonly="readonly" />
- </span>
- <span class="action-area">
- <button type="button" class="guest-edit-cdrom-button detach"
- data-vm="{vm}" data-dev="{dev}" data-type="{type}"
- title="$_("Detach")">
- </button>
- </span>
- </div>
-</script>
-<script id="permission-item-pam" type="text/html">
-<div class="item">
- <span class="icon {class}"></span>
- <label>{val}</label>
-</div>
-</script>
-<script id="pci-tmpl" type="text/html">
-<div class="item" id="{name}">
- <span class="cell name" title="{name}">{name}</span>
- <span class="cell product" title="{product}">{product}</span>
- <span class="cell vendor" title="{vendor}">{vendor}</span>
- <button></button>
-</div>
-</script>
-<script id="snapshot-tmpl" type="text/html">
- <div class="item" id="{name}">
- <span class="cell sel">
- <span class="icon {createMode}"></span>
- <span class="ui-icon ui-icon-check hide"></span>
- </span>
- <span class="cell name">{name}</span>
- <span class="cell created">{created}</span>
- <span class="action-area">
- <button class="revert {listMode}" title="$_("revert")"></button>
- <button class="delete {listMode}"></button>
- </span>
- <div>
-</script>
-<script type="text/javascript">
- kimchi.guest_edit_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl b/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
deleted file mode 100644
index a26e0f9..0000000
--- a/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
+++ /dev/null
@@ -1,103 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<div id="guest-storage-add-window" class="window">
- <header>
- <h1 class="title">$_("Add a Storage Device to VM")</h1>
- <div class="close">X</div>
- </header>
- <div class="content">
- <form id="form-guest-storage-add">
- <section class="form-section">
- <h2>1. $_("Device Type")</h2>
- <div class="field">
- <p class="text-help">
- $_("The device type. Currently, \"cdrom\" and \"disk\" are supported.")
- </p>
- <div class="btn dropdown popable">
- <input id="guest-storage-type" name="type" value="cdrom" type="hidden" />
- <span class="text" id="guest-storage-type-label"></span>
- <span class="arrow"></span>
- <div class="popover">
- <ul class="select-list" id="guest-storage-type-list" data-target="guest-storage-type" data-label="guest-storage-type-label"></ul>
- </div>
- </div>
- </div>
- </section>
- <div class="volume-section hidden">
- <section class="form-section">
- <h2>2. $_("Storage Pool")</h2>
- <div class="field storage-field">
- <p class="text-help">
- $_("Storage pool which volume located in")
- </p>
- <div class="btn dropdown popable">
- <input value="default" id="guest-disk-pool" name="pool" type="hidden"/>
- <span class="text" id="guest-disk-pool-label">default</span><span class="arrow"></span>
- <div class="popover" style="width: 100%">
- <ul class="select-list" id="guest-add-storage-pool-list" data-target="guest-disk-pool" data-label="guest-disk-pool-label"></ul>
- </div>
- </div>
- </div>
- </section>
- <section class="form-section">
- <h2>3. $_("Storage Volume")</h2>
- <div class="field storage-field">
- <p class="text-help">
- $_("Storage volume to be attached")
- </p>
- <div class="btn dropdown popable" id="guest-disk">
- <input id="guest-disk-vol" name="vol" type="hidden">
- <span class="text" id="guest-disk-vol-label"></span><span class="arrow"></span>
- <div class="popover" style="width: 100%">
- <ul class="select-list" id="guest-add-storage-pool-list" data-target="guest-disk-vol" data-label="guest-disk-vol-label"></ul>
- </div>
- </div>
- </div>
- </section>
- </div>
- <div class="path-section">
- <section class="form-section">
- <h2>2. $_("File Path")</h2>
- <div class="field">
- <p class="text-help">
- $_("The ISO file path in the server for CDROM.")
- </p>
- <input type="text" class="text" name="path" />
- </div>
- </section>
- </div>
- </fieldset>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="guest-storage-button-add" class="btn-normal" disabled="disabled">
- <span class="text">$_("Attach")</span>
- </button>
- </div>
- </footer>
-</div>
-<script type="text/javascript">
- kimchi.guest_storage_add_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/guest.html.tmpl b/plugins/kimchi/ui/pages/guest.html.tmpl
deleted file mode 100644
index 78e9161..0000000
--- a/plugins/kimchi/ui/pages/guest.html.tmpl
+++ /dev/null
@@ -1,77 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
- <li name="guest" class="guest">
- <div class="sortable guest-type">
- <div class="guest-general">
- <h2 class="title" title="{name}">{name}</h2>
- </div>
- <div class="guest-pending hide-content">
- <span class="icon"></span><span class="text"></span>
- </div>
- </div>
- <div name="cpu_utilization" class="sortable">
- <div class="circleGauge"></div>
- </div>
- <div name="io_throughput" class="sortable">
- <div class="circleGauge"></div>
- <div class="subtitle">KB/s</div>
- </div>
- <div name="net_throughput" class="sortable">
- <div class="circleGauge"></div>
- <div class="subtitle">KB/s</div>
- </div>
- <div name="guest-tile" class="sortable guest-tile">
- <div class="tile ">
- <img class="imgactive" alt="" src="">
- <img class="imgload" alt="" src="">
- <img class="overlay shutoff-hidden" alt="$_("Start")" src="plugins/kimchi/images/theme-default/icon-power-down.png" >
- </div>
- </div>
- <div class="sortable guest-actions" name="guest-actions">
- <div class="top">
- <button class="btn reset-disabled" name="vm-reset" href="javascript:void(0);" title="$_("Reset")"><span class="icon reset"></span></button>
- <button class="btn pause-disabled" name="vm-pause" href="javascript:void(0);" title="$_("Pause")"><span class="icon pause"></span></button>
- <button class="btn resume-hidden" name="vm-resume" href="javascript:void(0);" title="$_("Resume")"><span class="icon resume"></span></button>
- <button class="btn running-hidden" name="vm-start" href="javascript:void(0);" title="$_("Start")"><span class="icon power-down"></span></button>
- <button class="btn shutoff-hidden" name="vm-poweroff" href="javascript:void(0);" title="$_("Power Off")"><span class="icon power-up"></span></button>
- </div>
- <div class="bottom">
- <div name="actionmenu" class="btn dropdown popable vm-action" style="width: 126px">
- <span class="text">$_("Actions")</span><span class="arrow"></span>
- <div class="popover actionsheet right-side" style="width: 250px">
- <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Connect")</span></button>
- <button class="button-big running-disabled" name="vm-clone"><span class="text">$_("Clone")</span></button>
- <button class="button-big" name="vm-edit"><span class="text">$_("Edit")</span></button>
- <button class="button-big shutoff-hidden non-persistent-disabled" name="vm-reset"><span class="text">$_("Reset")</span></button>
- <button class="button-big pause-hidden non-persistent-disabled" name="vm-pause"><span class="text">$_("Pause")</span></button>
- <button class="button-big resume-hidden" name="vm-resume"><span class="text">$_("Resume")</span></button>
- <button class="button-big shutoff-hidden" name="vm-shutdown"><span class="text">$_("Shut Down")</span></button>
- <button class="button-big running-hidden" name="vm-start"><span class="text">$_("Start")</span></button>
- <button class="button-big shutoff-hidden" name="vm-poweroff"><span class="text">$_("Power Off")</span></button>
- <button class="button-big red non-persistent-disabled" name="vm-delete">$_("Delete")</button>
- </div>
- </div>
- </div>
- </div>
- </li>
diff --git a/plugins/kimchi/ui/pages/guests.html.tmpl b/plugins/kimchi/ui/pages/guests.html.tmpl
deleted file mode 100644
index b8a1259..0000000
--- a/plugins/kimchi/ui/pages/guests.html.tmpl
+++ /dev/null
@@ -1,65 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#from Cheetah.Template import Template
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-#silent ht = Template
-
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div id="guests-root-container">
- <div class="toolbar">
- <div class="tools" style="display:none">
- <a id="vm-add" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
- </div>
- </div>
- <div id="guestListField" style="display: none">
- <ul class="list-title">
- <li class="guest-type">$_("Name")</li>
- <li class="guest-cpu">$_("CPU")</li>
- <li class="guest-storage">$_("Disk I/O")</li>
- <li class="guest-network">$_("Network I/O")</li>
- <li class="guest-tile">$_("Livetile")</li>
- <li class="guest-actions">$_("Actions")</li>
- </ul>
- <ul id="guestList" class="list-vm empty-when-logged-off">
- </ul>
- </div>
- <div id="noGuests" class="list-no-result" style="display: none;">
- $_("No guests found.")
- </div>
- <script id="guest-tmpl" type="kimchi/template">
- $ht(file=$data.ui_dir + "/pages/guest.html.tmpl", searchList=[self, {'lang':$lang}])
- </script>
- <script type="text/javascript">
- kimchi.guest_main();
- </script>
-</div>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/help/Makefile.am b/plugins/kimchi/ui/pages/help/Makefile.am
deleted file mode 100644
index a4ee361..0000000
--- a/plugins/kimchi/ui/pages/help/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = zh_CN it_IT en_US zh_TW pt_BR ja_JP ru_RU ko_KR fr_FR de_DE es_ES
-
-DITA_HTML_FILES = $(patsubst %.dita,%.html,$(wildcard */*.dita))
-HTML_FILES = $(if $(DITA_HTML_FILES), $(DITA_HTML_FILES), $(wildcard */*.html))
-DITA_XSL_FILE = dita-help.xsl
-
-EXTRA_DIST = $(DITA_XSL_FILE)
-
-helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help
-
-dist_help_DATA = kimchi.css
-
-all: $(HTML_FILES) $(wildcard */*.dita)
-
-%.html: %.dita $(DITA_XSL_FILE)
- xsltproc -o $@ $(DITA_XSL_FILE) $<
-
-CLEANFILES = $(HTML_FILES)
diff --git a/plugins/kimchi/ui/pages/help/de_DE/Makefile.am b/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
deleted file mode 100644
index 3d99aae..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-de_DE_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/de_DE
-
-dist_de_DE_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/de_DE/guests.dita b/plugins/kimchi/ui/pages/help/de_DE/guests.dita
deleted file mode 100644
index 1d64469..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/guests.dita
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="de-de">
-<title>Gäste</title>
-<shortdesc>Auf der Seite <wintitle>Gäste</wintitle> sind die definierten virtuellen
-Maschinen von KVM aufgelistet.</shortdesc>
-<csbody>
-<p>Für jeden Gast werden die folgenden Informationen angezeigt:<dl><dlentry>
-<dt>Name</dt>
-<dd>Name der virtuellen Maschine.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Prozentsatz der Prozessorauslastung in der virtuellen Maschine.</dd>
-</dlentry><dlentry>
-<dt>Netz-E/A</dt>
-<dd>Netz-E/A-Ãbertragungsrate in KB pro Sekunde.</dd>
-</dlentry><dlentry>
-<dt>Platten-E/A</dt>
-<dd>Platten-E/A-Ãbertragungsrate in KB pro Sekunde.</dd>
-</dlentry><dlentry>
-<dt>Live Tile</dt>
-<dd>Status der Konsole für das Gastbetriebssystem oder ein Symbol, das die
-<tm tmtype="tm" trademark="Linux">Linux</tm>-Verteilung darstellt, wenn
-der Gast nicht aktiv ist.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionssymbole werden für jeden Gast angezeigt:<dl>
-<dlentry>
-<dt>Zurücksetzen</dt>
-<dd>Klicken Sie hier, um den Gast zurückzusetzen. </dd>
-</dlentry><dlentry>
-<dt>Power (Starten oder Stoppen)</dt>
-<dd>Klicken Sie hier, um den Gast ein- bzw. auszuschalten. Wenn das Symbol rot ist,
-ist er ausgeschaltet. Wenn das Symbol grün ist, ist er eingeschaltet.</dd>
-</dlentry></dl> </p>
-<p>Die folgenden Aktionen können für jeden Gast ausgewählt werden:<ul>
-<li>Wählen Sie <uicontrol>Verbinden</uicontrol> aus, um eine Verbindung zur fernen Konsole
-für das Gastbetriebssystem herzustellen.</li>
-<li>Wählen Sie <uicontrol>Medien verwalten</uicontrol> aus, um den Pfad zu den
-Installationsmedien zu ändern.</li>
-<li>Wählen Sie <uicontrol>Zurücksetzen</uicontrol> aus, um den Gast zurückzusetzen.</li>
-<li>Wählen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die Eigenschaften eines
-bestehenden Gastes zu bearbeiten. Gäste können nur bearbeitet werden, wenn sie gestoppt sind.</li>
-<li>Wählen Sie <uicontrol>Löschen</uicontrol> aus, um den Gast zu löschen.</li>
-</ul>Um einen Gast bzw. eine virtuelle Maschine zu erstellen, klicken Sie auf das <uicontrol>Plus (+)</uicontrol>-Symbol oben rechts auf der Seite.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="de-de">
-<title>Virtuelle Maschine erstellen</title>
-<shortdesc>Erstellen Sie eine virtuelle Maschine mithilfe einer bestehenden Vorlage.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Geben Sie den Namen ein, mit dem die virtuelle Maschine gekennzeichnet wird.</li>
-<li rev="rev1">Wählen Sie eine Vorlage aus. <ul>
-<li>Wenn Vorlagen vorhanden sind, wählen Sie eine aus den angezeigten Vorlagen aus.</li>
-<li>Wenn keine Vorlagen vorhanden sind, klicken Sie auf <uicontrol>Vorlage erstellen</uicontrol>, um eine Vorlage zu erstellen.</li>
-</ul></li>
-<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="de-de">
-<title>Gast bearbeiten</title>
-<shortdesc>Bearbeiten Sie die Eigenschaften einer bestehenden virtuellen Maschine. Einige Eigenschaften können nur bearbeitet werden, solange der Gast gestoppt ist. Andere Eigenschaften treten beim nächsten Booten in Kraft. </shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Für jeden Gast werden die folgenden Informationen auf der Registerkarte <wintitle>Allgemein</wintitle> angezeigt:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name der virtuellen Maschine. (Kann nur bearbeitet werden, solange der Gast gestoppt ist.)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Anzahl der Prozessoren. (Wenn der Gast aktiv ist, tritt die neue Menge beim nächsten Booten in Kraft.)
-</dd>
-</dlentry><dlentry>
-<dt>Speicher</dt>
-<dd>Speicherkapazität in MB. (Wenn der Gast aktiv ist, tritt die neue Menge beim nächsten Booten in Kraft.)
-</dd>
-</dlentry><dlentry>
-<dt>Symbol</dt>
-<dd>Grafikbild, das die Linux-Verteilung darstellt und anstelle des aktuellen Status (Live Tile) angezeigt werden soll, wenn der Gast nicht aktiv ist.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Informationen werden auf der Registerkarte <wintitle>Speicher</wintitle> angezeigt.</p>
-<dl><dlentry>
-<dt>Speicher</dt>
-<dd>Zeigt die Position der ISO-Datei an, die für die Installation verwendet wird.</dd>
-</dlentry></dl>
-<p> Felder, die nicht inaktiviert sind, können bearbeitet werden. Nachdem Sie ein Feld bearbeitet haben, klicken Sie auf <uicontrol>Speichern</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="de-de">
-<title>Speichereinheit hinzufügen, ersetzen oder abhängen</title>
-<shortdesc rev="rev1">Sie können eine Speichereinheit zu Ihrer virtuellen Maschine hinzufügen oder diese ersetzen oder abhängen. Die einzige unterstützte Einheit ist CD-ROM. Führen Sie die folgenden Schritte aus, um Ihre Speichereinheiten zu bearbeiten:</shortdesc>
-<csbody>
-<ol>
-<li>Wählen Sie im Fenster <wintitle>Gast bearbeiten</wintitle> die Option <wintitle>Speicher</wintitle> aus.</li>
-<li>Um eine Speichereinheit zu ersetzen, klicken Sie auf das erste Symbol mit dem <uicontrol>orangefarbenen Schrägstrich (/)</uicontrol>. Geben Sie den ISO-Dateipfad ein und klicken Sie auf <uicontrol>Ersetzen</uicontrol>.</li>
-<li>Um eine Speichereinheit abzuhängen, klicken Sie auf das zweite Symbol mit dem <uicontrol>roten Gedankenstrich (-)</uicontrol>. Bestätigen Sie den Löschvorgang und klicken Sie auf <uicontrol>OK</uicontrol>.</li>
-<li>Um eine Speichereinheit hinzuzufügen, klicken Sie auf das dritte Symbol mit dem grünen <uicontrol>Pluszeichen (+)</uicontrol>. Geben Sie einen Einheitennamen und einen ISO-Dateipfad ein und klicken Sie auf <uicontrol>Anhängen</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="de-de">
-<title>CD-ROM für VM ersetzen</title>
-<shortdesc rev="rev1">Sie können den Inhalt der CD-ROM für eine virtuelle Maschine nach Abschluss der Installation ersetzen.</shortdesc>
-<csbody>
-<ol>
-<li>Stellen Sie sicher, dass die virtuelle Maschine gestartet ist.</li>
-<li>Wählen Sie aus dem Aktionsmenü die Option <uicontrol>Medien verwalten</uicontrol> aus.</li>
-<li>Um das zu ändern, was aktuell in der CD-ROM geladen ist, klicken Sie auf das Symbol mit dem <uicontrol>orangefarbenen Schrägstrich (/)</uicontrol> neben dem hdc-Feld.</li>
-<li>Geben Sie auf der Seite <wintitle>CD-ROM für VM ersetzen</wintitle> den ISO-Dateipfad ein. Die anderen beiden Felder sind schreibgeschützt.</li>
-<li>Klicken Sie auf <uicontrol>Ersetzen</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/host.dita b/plugins/kimchi/ui/pages/help/de_DE/host.dita
deleted file mode 100644
index 33a40e3..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/host.dita
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="de-de">
-<title>Host</title>
-<shortdesc>Die Seite <wintitle>Host</wintitle> zeigt Informationen zum Hostsystem an und ermöglicht Ihnen, den Host herunterzufahren, erneut zu starten und eine Verbindung zu ihm herzustellen.</shortdesc>
-<csbody>
-<p>Sie können die folgenden Aktionen am Host durchführen:<ul>
-<li>Wählen Sie <uicontrol>Herunterfahren</uicontrol> aus, um das Hostsystem herunterzufahren.</li>
-<li>Wählen Sie <uicontrol>Erneut starten</uicontrol> aus, um das Hostsystem erneut zu starten.</li>
-<li>Wählen Sie <uicontrol>Verbinden</uicontrol> aus, um eine VNC-Verbindung zum Hostsystem herzustellen, wenn noch keine Verbindung besteht.</li>
-</ul></p>
-<p>Klicken Sie auf die folgenden Abschnitte, um Informationen zum Host anzuzeigen:<dl>
-<dlentry>
-<dt>Basisinformationen</dt>
-<dd>Dieser Abschnitt zeigt die Verteilung, die Version und den Codenamen des Hostbetriebssystems sowie den Prozessortyp und die Speicherkapazität in GB an.</dd>
-</dlentry><dlentry>
-<dt>Systemstatistik</dt>
-<dd>Dieser Abschnitt zeigt mithilfe von Grafiken Statistiken für CPU, Speicher, Platten-E/A und Netz-E/A für den Host an. Wählen Sie <uicontrol>Daten werden nach dem Verlassen dieser Seite gesammelt</uicontrol> aus, um mit der Sammlung von Daten fortzufahren, wenn die Host-Registerkarte nicht angezeigt wird.</dd>
-</dlentry><dlentry>
-<dt>Software-Updates</dt>
-<dd>Dieser Abschnitt zeigt Informationen für alle Pakete an, bei denen Aktualisierungen verfügbar sind, einschlieÃlich Paketname, Version, Architektur und Repository. Sie können alle aufgelisteten Pakete aktualisieren, indem Sie <uicontrol>Alle aktualisieren</uicontrol> auswählen. Sie können nicht einzelne Pakete zur Aktualisierung auswählen.</dd>
-</dlentry><dlentry>
-<dt>Repositorys</dt>
-<dd>Dieser Abschnitt zeigt Repositorys an, die dem Hostsystem zugeordnet sind. Sie können Repositorys hinzufügen, aktivieren, bearbeiten oder entfernen. Beim Hinzufügen wird ein Repository dem Hostsystem zugeordnet. Das Aktivieren eines Repositorys dagegen ermöglicht dem Host den Zugriff auf das Repository. Wenn Ihr System Red Hat Enterprise
-Linux oder Fedora ist, können Sie <filepath>yum</filepath>-Repositorys hinzufügen.
-Wenn Ihr System Ubuntu oder Debian ist, fügen Sie <filepath>deb</filepath>-Repositorys hinzu.<p>Wenn Sie mit yum-Repositorys arbeiten, können Sie eine GPG-Prüfung hinzufügen, um sicherzustellen, dass ein Paket aus diesem Repository nicht beschädigt wurde.
-Wählen Sie ein Repository und dann <uicontrol>Bearbeiten</uicontrol> aus. Wählen Sie <uicontrol>Ja</uicontrol> aus, um die GPG-Prüfung zu aktivieren, und geben Sie dann ein URL zur GPG-Schlüsseldatei für das Repository ein.</p></dd>
-</dlentry><dlentry>
-<dt>Debugberichte</dt>
-<dd>Dieser Abschnitt zeigt Debugberichte, einschlieÃlich Name und Dateipfad, an.
-Sie haben die Möglichkeit, einen neuen Bericht zu erstellen oder einen bestehenden Bericht umzubenennen, zu entfernen oder herunterzuladen.<p>Der Debugbericht wird während des Befehls <cmdname>sosreport</cmdname> generiert. Er ist verfügbar für Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>-, Fedora-
-und Ubuntu-Verteilungen. Der Befehl generiert eine .tar-Datei, die Konfigurations- und Diagnoseinformationen enthält, wie zum Beispiel Kernelversion, geladene Module sowie System- und Servicekonfigurationdateien.
-Der Befehl führt zudem externe Programme aus, um weitere Informationen zu sammeln, und speichert diese Ausgabe im resultierenden Archiv.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/network.dita b/plugins/kimchi/ui/pages/help/de_DE/network.dita
deleted file mode 100644
index 49a2935..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/network.dita
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="de-de">
-<title>Netz</title>
-<shortdesc>Die Seite <wintitle>Netz</wintitle> zeigt Informationen zur Netzverbindung an.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Netzname</dt>
-<dd>Name des Netzes oder <uicontrol>Standard</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Status</dt>
-<dd>Status des Netzes, aktiv (grün) oder inaktiv (rot). </dd>
-</dlentry><dlentry>
-<dt>Netztyp</dt>
-<dd>Netztyp, zum Beispiel <uicontrol>NAT</uicontrol> (Network
-Address Translation, Netzadressumsetzung).</dd>
-</dlentry><dlentry>
-<dt>Schnittstelle</dt>
-<dd>Netzschnittstelle, zum Beispiel <uicontrol>virbr0</uicontrol> (Standard).</dd>
-</dlentry><dlentry>
-<dt>Adressraum</dt>
-<dd>IP-Adresse.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionen können ausgewählt werden:<ul>
-<li rev="rev1">Wählen Sie <uicontrol>Starten</uicontrol> aus, um die Netzverbindung herzustellen.</li>
-<li>Wählen Sie <uicontrol>Stoppen</uicontrol> aus, um die Netzverbindung zu beenden.</li>
-<li>Wählen Sie <uicontrol>Löschen</uicontrol> aus, um die Verbindungsinformationen zu löschen.</li>
-</ul>Um ein Netz zu erstellen, klicken Sie auf das Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="de-de">
-<title>Netz erstellen</title>
-<shortdesc>Erstellen Sie ein Netz.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Geben Sie den Namen des Netzes ein.</li>
-<li>Klicken Sie hier, um den Netztyp auszuwählen. <dl rev="rev1"><dlentry>
-<dt><uicontrol>Isoliert</uicontrol></dt>
-<dd>Isolierter Modus. Gäste können keine Kommunikation an externe Systeme senden oder von ihnen empfangen.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Network Address Translation-Modus. Bei der Kommunikation von Gästen mit externen Systemen wird die Host-IP-Adresse verwendet. Externe Systeme können keine Kommunikation mit Gästen initiieren.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Ãberbrückt</uicontrol></dt>
-<dd>Ãberbrückt-Modus. Gäste können mit externen Systemen kommunizieren und von externen Systemen kontaktiert werden, als ob sie physische Systeme im Netz wären. Für den Ãberbrückt-Modus müssen Sie zusätzliche Ziel- und VLAN-Informationen angeben.</dd>
-</dlentry></dl></li>
-<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/storage.dita b/plugins/kimchi/ui/pages/help/de_DE/storage.dita
deleted file mode 100644
index 7f89603..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/storage.dita
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="de-de">
-<title>Speicher</title>
-<shortdesc>Auf der Seite <wintitle>Speicher</wintitle> werden die verfügbaren Speicherpools aufgelistet, einschlieÃlich der sofort einsatzfähigen Speicherpools 'default' und 'ISO'. Wenn Sie ein eigenes ISO-Image verwenden möchten, fügen Sie es zum Speicherpoolpfad 'ISO' hinzu.</shortdesc>
-<csbody>
-<p>Für jeden Speicherpool werden die folgenden Informationen angezeigt:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name des Speicherpools und genutzter Prozentsatz.</dd>
-</dlentry><dlentry>
-<dt>Status</dt>
-<dd>Status des Speicherpools, aktiv (grün) oder inaktiv (rot). </dd>
-</dlentry><dlentry>
-<dt>Position</dt>
-<dd>Dateipfad zur Position des Speicherpools.</dd>
-</dlentry><dlentry>
-<dt>Typ</dt>
-<dd>Typ des Speicherpools, zum Beispiel <uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Kapazität</dt>
-<dd>Speicherkapazität im Speicherpool.</dd>
-</dlentry><dlentry>
-<dt>Zugeordnet</dt>
-<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionen können für jeden Speicherpool ausgewählt werden:<ul>
-<li>Wählen Sie <uicontrol>Aktivieren</uicontrol> aus, um den Speicherpool zu aktivieren, damit er genutzt werden kann.</li>
-<li>Wählen Sie <uicontrol>Inaktivieren</uicontrol> aus, um einen aktiven Speicherpool zu inaktivieren.</li>
-<li>Wählen Sie <uicontrol>Definition aufheben</uicontrol>, um einen inaktiven Speicherpool zu entfernen.</li>
-</ul></p>
-<p>Um Details zum Speicherdatenträger anzuzeigen, klicken Sie auf den Pfeil auf der rechten Seite der Speicherpoolzeile. Zu den Details gehören folgende Informationen:<dl><dlentry>
-<dt>Typ</dt>
-<dd>Typ des Datenträgers, zum Beispiel <uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Format</dt>
-<dd>Das Format, variiert abhängig vom Typ.</dd>
-</dlentry><dlentry>
-<dt>Kapazität</dt>
-<dd>GröÃe des Speicherdatenträgers.</dd>
-</dlentry><dlentry>
-<dt>Zuordnung</dt>
-<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
-</dlentry></dl>Um einen Speicherpool zu definieren, klicken Sie auf das Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="de-de">
-<title>Speicherpool definieren</title>
-<shortdesc> Definieren Sie einen Speicherpool.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Geben Sie im Feld <uicontrol>Speicherpoolname</uicontrol> den Namen ein, mit dem der Speicherpool gekennzeichnet werden soll.</li>
-<li>Wählen Sie aus der Liste <uicontrol>Speicherpooltyp</uicontrol> den Typ aus: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Gibt einen Verzeichnispool an. Wenn Sie <uicontrol>DIR</uicontrol> auswählen, geben Sie den <uicontrol>Speicherpfad</uicontrol> ein (Dateipfad zum Speicherpool).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Gibt einen Netzdateisystempool an. Wenn Sie <uicontrol>NFS</uicontrol> auswählen,
-geben Sie <uicontrol>NFS-Server-IP</uicontrol> und <uicontrol>NFS-Pfad</uicontrol> an (Pfad des exportierten Verzeichnisses).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Gibt einen Pool an, der auf einem Ziel basiert, der auf einem iSCSI-Server zugeordnet ist.
-Wenn Sie <uicontrol>iSCSI</uicontrol> auswählen, geben Sie die IP-Adresse vom <uicontrol>iSCSI-Server</uicontrol> und das <uicontrol>Ziel</uicontrol> auf dem iSCSI-Server an. Sie können optional iSCSI-Authentifizierung hinzufügen.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logisch</uicontrol></dt>
-<dd>Gibt einen Speicherpool aus logischen Datenträgern an. Wählen Sie die Position zur Einheit im <uicontrol>Einheitenpfad</uicontrol> aus.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI-Fibre Channel</uicontrol></dt>
-<dd>Gibt einen Pool an, der auf einem SCSI-Fibre Channel basiert. Wählen Sie aus, welcher Adapter verwendet werden soll.</dd>
-</dlentry></dl></li>
-<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/templates.dita b/plugins/kimchi/ui/pages/help/de_DE/templates.dita
deleted file mode 100644
index 5063930..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/templates.dita
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="de-de">
-<title>Vorlagen</title>
-<shortdesc>Die Seite <wintitle>Vorlagen</wintitle> zeigt die definierten Vorlagen der virtuellen Maschine an, die zum Erstellen von KVM-Gästen verwendet werden können.</shortdesc>
-<csbody>
-<p>Für jede Vorlage werden die folgenden Informationen angezeigt:<dl>
-<dlentry>
-<dt>BS</dt>
-<dd>Name des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Anzahl der Prozessoren, die für die Vorlage definiert sind.</dd>
-</dlentry><dlentry>
-<dt>Speicher</dt>
-<dd>GröÃe des zuzuordnenden Arbeitsspeichers in MB.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionen können für jede Vorlage ausgewählt werden:<ul>
-<li>Wählen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die Vorlage zu bearbeiten.</li>
-<li>Wählen Sie <uicontrol>Löschen</uicontrol> aus, um die Vorlage zu löschen.</li>
-</ul>Um eine Vorlage hinzuzufügen, klicken Sie auf das Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="de-de">
-<title>Vorlage bearbeiten</title>
-<shortdesc>Bearbeiten Sie eine bestehende Vorlage.</shortdesc>
-<csbody>
-<p>Für jede Vorlage werden die folgenden Informationen angezeigt: <dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name der Vorlage.</dd>
-</dlentry><dlentry>
-<dt>Anbieter</dt>
-<dd>Der Name des Unternehmens, das das Betriebssystem oder die Verteilung erstellt hat, für die die Vorlage konfiguriert ist.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Die Version des Betriebssystems oder der Verteilung, für die die Vorlage konfiguriert ist.</dd>
-</dlentry><dlentry>
-<dt>CPU-Anzahl</dt>
-<dd>Anzahl der Prozessoren, die für die Vorlage definiert sind.</dd>
-</dlentry><dlentry>
-<dt>Speicher</dt>
-<dd>Speicherkapazität in MB, die der virtuellen Maschine zugeordnet werden soll.</dd>
-</dlentry><dlentry>
-<dt>Platte</dt>
-<dd>PlattengröÃe in GB.</dd>
-</dlentry><dlentry>
-<dt>CD-ROM</dt>
-<dd>Dateipfad zur Position der ISO-Datei an, die für die Installation des KVM-Gastes verwendet wird.</dd>
-</dlentry><dlentry>
-<dt>Speicherpool</dt>
-<dd>Bestimmter Speicherpool oder der Standardspeicherpool.</dd>
-</dlentry><dlentry>
-<dt>Netz</dt>
-<dd>Standardnetzschnittstelle, die für den KVM-Gast verfügbar ist. Sie können mehrere Netze auswählen.</dd>
-</dlentry></dl> Felder, die nicht inaktiviert sind, können bearbeitet werden. Nachdem Sie ein Feld bearbeitet haben, klicken Sie auf <uicontrol>Speichern</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Vorlage hinzufügen</title>
-<shortdesc>Fügen Sie eine Vorlage vom Quellendatenträger hinzu. Sie können für eine nachfolgende Erkennung Ihr eigenes ISO-Image zum Speicherpool 'ISO' hinzufügen.</shortdesc>
-<csbody>
-<p>Wählen Sie die Position des Quellendatenträgers aus den folgenden Optionen aus:<dl>
-<dlentry>
-<dt>Lokales ISO-Image</dt>
-<dd>Wählen Sie diese Option aus, um Speicherpools nach Installations-ISO-Images zu durchsuchen, die im System verfügbar sind.</dd>
-</dlentry><dlentry>
-<dt>Fernes ISO-Image</dt>
-<dd>Wählen Sie diese Option aus, um eine ferne Position für ein Installations-ISO-Image anzugeben.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Vorlage hinzufügen - lokales ISO-Image</title>
-<shortdesc>Fügen Sie eine Vorlage aus einem lokalen ISO-Image hinzu.</shortdesc>
-<csbody>
-<p>Die im System verfügbaren ISO-Images werden angezeigt.<dl><dlentry>
-<dt>BS</dt>
-<dd>Name des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>GröÃe</dt>
-<dd>GröÃe des ISO-Image.</dd>
-</dlentry></dl></p>
-<p>Um eine Vorlage aus einem ISO-Image zu erstellen, wählen Sie aus den folgenden
-Optionen aus:<ul>
-<li>Wählen Sie ein ISO-Image aus, aus dem Sie eine Vorlage erstellen möchten, und klicken Sie dann auf <uicontrol>Vorlagen aus ausgewähltem ISO erstellen</uicontrol>.</li>
-<li>Wählen Sie <uicontrol>Alle</uicontrol> aus, um eine Vorlage aus jedem aufgelisteten ISO-Image zu erstellen, und klicken Sie dann auf <uicontrol>Vorlagen aus ausgewähltem ISO erstellen</uicontrol>.</li>
-<li>Wenn das ISO-Image, das Sie verwenden möchten, nicht in den Suchergebnissen angezeigt wird, können Sie aus den folgenden Optionen auswählen:<ul>
-<li>Wählen Sie <uicontrol>Ich möchte eine bestimmte ISO-Datei verwenden</uicontrol> aus, um einen Pfad zum ISO-Image anzugeben.</li>
-<li>Klicken Sie auf <uicontrol>Weitere ISOs suchen</uicontrol>, um weitere ISO-Images zu suchen.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/dita-help.xsl b/plugins/kimchi/ui/pages/help/dita-help.xsl
deleted file mode 100644
index 45f0a3b..0000000
--- a/plugins/kimchi/ui/pages/help/dita-help.xsl
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns="http://www.w3.org/1999/xhtml">
- <xsl:output method="xml" indent="yes" encoding="UTF-8" />
-
- <xsl:template match="/">
- <html>
- <head>
- <title><xsl:value-of select="/cshelp/title" /></title>
- <meta charset="UTF-8" />
- <link rel="shortcut icon" href="images/logo.ico" />
- <link rel="stylesheet" type="text/css" href="../kimchi.css" />
- </head>
- <body>
- <xsl:apply-templates select="//cshelp" />
- </body>
- </html>
- </xsl:template>
-
- <xsl:template match="cshelp">
- <h1><xsl:value-of select="title" /></h1>
- <p class="shortdesc"><xsl:value-of select="shortdesc" /></p>
- <p class="csbody"><xsl:copy-of select="csbody/node()" /></p>
- </xsl:template>
-</xsl:stylesheet>
diff --git a/plugins/kimchi/ui/pages/help/en_US/Makefile.am b/plugins/kimchi/ui/pages/help/en_US/Makefile.am
deleted file mode 100644
index d37f03a..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-en_US_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/en_US
-
-dist_en_US_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/en_US/guests.dita b/plugins/kimchi/ui/pages/help/en_US/guests.dita
deleted file mode 100644
index 1bb437a..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/guests.dita
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="en-us">
-<title>Guests</title>
-<shortdesc>The <wintitle>Guests</wintitle> page lists the defined
-KVM virtual machines.</shortdesc>
-<csbody>
-<p>For each guest, the following information is displayed:<dl><dlentry>
-<dt>Name</dt>
-<dd>Name of the virtual machine.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Percentage of processor utilization in the virtual machine.</dd>
-</dlentry><dlentry>
-<dt>Network I/O</dt>
-<dd>Network input/output transmission rate in KB per seconds.</dd>
-</dlentry><dlentry>
-<dt>Disk I/O</dt>
-<dd>Disk input/output transmission rate in KB per seconds.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>State of guest operating system console, or an icon that represents
-the <tm tmtype="tm" trademark="Linux">Linux</tm> distribution if the
-guest is not active.</dd>
-</dlentry></dl></p>
-<p>The following actions icons are displayed for each guest:<dl>
-<dlentry>
-<dt>Reset</dt>
-<dd>Click to reset the guest. </dd>
-</dlentry><dlentry>
-<dt>Power (Start or Stop)</dt>
-<dd>Click to power on or power off the guest. If the icon is red,
-the power is off; if the icon is green, the power is on.</dd>
-</dlentry></dl> </p>
-<p>The following actions can be selected for each guest:<ul>
-<li>Select <uicontrol>Connect</uicontrol> to connect to the remote
-console for the guest operating system.</li>
-<li>Select <uicontrol>Manage media</uicontrol> to change the path
-to the installation media.</li>
-<li>Select <uicontrol>Reset</uicontrol> to reset the guest.</li>
-<li>Select <uicontrol>Edit</uicontrol> to edit the properties of an
-existing guest. Guests can be edited only while stopped.</li>
-<li>Select <uicontrol>Delete</uicontrol> to delete the guest.</li>
-</ul>To create a guest, or virtual machine, click the <uicontrol>plus
-(+)</uicontrol> icon in the upper right of the page.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="en-us">
-<title>Create virtual machine</title>
-<shortdesc>Create a virtual machine by using an existing template.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Type the name to be used to identify the virtual machine.</li>
-<li rev="rev1">Select a template. <ul>
-<li>If templates exist, select from displayed templates.</li>
-<li>If no templates exist, click <uicontrol>Create a template</uicontrol> to
-create a template.</li>
-</ul></li>
-<li>Click <uicontrol>Create</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="en-us">
-<title>Edit guest</title>
-<shortdesc>Edit the properties of an existing virtual machine. Some properties
-can be edited only while guest is stopped. Others will take effect in next boot.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>For each guest, the following information is displayed on the <wintitle>General</wintitle> tab:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name of the virtual machine. (can only be edited while guest is stopped)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Number of processors. (if guest is running, new amount will take effect
-in next boot)</dd>
-</dlentry><dlentry>
-<dt>Memory</dt>
-<dd>Amount of memory in MB. (if guest is running, new amount will take effect
-in next boot)</dd>
-</dlentry><dlentry>
-<dt>Icon</dt>
-<dd>Graphic image representing the Linux distribution to be displayed
-in place of current status (Livetile) when the guest is not active.</dd>
-</dlentry></dl></p>
-<p>The following information is displayed on the <wintitle>Storage</wintitle> tab.</p>
-<dl><dlentry>
-<dt>Storage</dt>
-<dd>Displays the location of the ISO file used for installation.</dd>
-</dlentry></dl><?Pub Caret -2?>
-<p> Fields that are not disabled can be edited. After you edit a field,
-click <uicontrol>Save</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="en-us">
-<title>Add, replace, or detach a storage device</title>
-<shortdesc rev="rev1">You can add, replace, or detach a storage device
-to your virtual machine. The only supported device is CDROM. To edit
-your storage devices, follow these steps:</shortdesc>
-<csbody>
-<ol>
-<li>On the <wintitle>Edit Guest</wintitle> window, select <wintitle>Storage</wintitle>.</li>
-<li>To replace a storage device, click the first icon with the <uicontrol>orange
-slash (/)</uicontrol>. Enter the ISO file path and click <uicontrol>Replace</uicontrol>.</li>
-<li>To detach a storage device, click the second icon with the <uicontrol>red
-dash (-)</uicontrol>. Confirm the deletion and click <uicontrol>OK</uicontrol>.</li>
-<li>To add a storage device, click the third icon with the green <uicontrol>plus
-sign (+)</uicontrol>. Enter a device name and ISO file path and click <uicontrol>Attach</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="en-us">
-<title>Replace a CDROM of VM</title>
-<shortdesc rev="rev1">You can replace the contents of the CDROM for
-a virtual machine after the installation is complete.</shortdesc>
-<csbody>
-<ol>
-<li>Ensure that the virtual machine is started.</li>
-<li>From the Actions menu, select <uicontrol>Manage Media</uicontrol>.</li>
-<li>To change what is currently loaded in the CDROM, click the <uicontrol>orange
-slash (/)</uicontrol> icon next to the hdc field.</li>
-<li>On the <wintitle>Replace a CDROM of VM</wintitle> page, enter
-the ISO file path. The other two fields are read-only.</li>
-<li>Click <uicontrol>Replace</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-<?Pub *0000005541?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/host.dita b/plugins/kimchi/ui/pages/help/en_US/host.dita
deleted file mode 100644
index 0dcb670..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/host.dita
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="en-us">
-<title>Host</title>
-<shortdesc>The <wintitle>Host</wintitle> page shows information about
-the host system, and allows you to shut down, restart, and connect
-to the host.</shortdesc>
-<csbody>
-<p>You can perform the following actions on the host:<ul>
-<li>Select <uicontrol>Shut down</uicontrol> to shut down the host
-system.</li>
-<li>Select <uicontrol>Restart</uicontrol> to restart the host system.</li>
-<li>Select <uicontrol>Connect</uicontrol> to open a VNC connection
-to the host system, if it is not already connected.</li>
-</ul></p>
-<p>Click the following sections to display information about the host:<dl>
-<dlentry>
-<dt>Basic information</dt>
-<dd>This section displays the host operating system distribution,
-version, and code name, as well as the processor type, the number of
-online CPUs and amount of memory in GB.</dd>
-</dlentry><dlentry>
-<dt>System statistics</dt>
-<dd>This section displays graphs to show statistics for CPU, memory,
-disk I/O, and network I/O for the host. Select <uicontrol>Collecting
-data after leaving this page</uicontrol> to continue collecting data
-when the host tab is out of view.</dd>
-</dlentry><dlentry>
-<dt>Software Updates</dt>
-<dd>This section displays information for all of the packages that
-have updates available, including package name, version, architecture,
-and repository. You can update all of the packages listed by selecting <uicontrol>Update
-All</uicontrol>. You cannot select individual packages for updates.</dd>
-</dlentry><dlentry>
-<dt>Repositories</dt>
-<dd>This section displays repositories that are associated with the
-host system. You can add, enable, edit, or remove repositories. Adding
-a repository associates it with the host system while enabling a repository
-allows the host to access it. If your system is Red Hat Enterprise
-Linux or Fedora, you can add <filepath>yum</filepath> repositories.
-If your system is Ubuntu or Debian, then add <filepath>deb</filepath> repositories.<p>If
-you are working with yum repositories, you can add a GPG check to
-verify that a package from this repository have not been corrupted.
-Select a repository and then <uicontrol>Edit</uicontrol>. Select <uicontrol>Yes</uicontrol> to
-enable GPG Check and then enter a URL to the GPG key file for the
-repository.</p><?Pub Caret 156?></dd>
-</dlentry><dlentry>
-<dt>Debug reports</dt>
-<dd>This section displays debug reports, including name and file path.
-You can select from options to generate a new report, or rename, remove,
-or download an existing report.<p>The debug report is generated using
-the <cmdname>sosreport</cmdname> command. It is available for Red
-Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora,
-and Ubuntu distributions. The command generates a .tar file that contains
-configuration and diagnostic information, such as the running kernel
-version, loaded modules, and system and service configuration files.
-The command also runs external programs to collect further information
-and stores this output in the resulting archive.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-<?Pub *0000003492?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/network.dita b/plugins/kimchi/ui/pages/help/en_US/network.dita
deleted file mode 100644
index 25c05ff..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/network.dita
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="en-us">
-<title>Network</title>
-<shortdesc>The <wintitle>Network</wintitle> page displays information
-about the network connection.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Network Name</dt>
-<dd>Name of the network, or <uicontrol>default</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>State</dt>
-<dd>State of the network, active (green) or inactive (red). </dd>
-</dlentry><dlentry>
-<dt>Network type</dt>
-<dd>Network type, for example, <uicontrol>NAT</uicontrol> (network
-address translation).</dd>
-</dlentry><dlentry>
-<dt>Interface</dt>
-<dd>Network interface, for example, <uicontrol>virbr0</uicontrol> (default).</dd>
-</dlentry><dlentry>
-<dt>Address space</dt>
-<dd>IP address.</dd>
-</dlentry></dl></p>
-<p>The following actions can be selected:<ul>
-<li rev="rev1">Select <uicontrol>Start</uicontrol> to begin the network
-connection.</li>
-<li>Select <uicontrol>Stop</uicontrol> to end the network connection.</li>
-<li>Select <uicontrol>Delete</uicontrol> to delete the connection
-information.</li>
-</ul>To create a network, click the <uicontrol>plus (+)</uicontrol> icon
-in the upper right of the display.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="en-us">
-<title>Create a network</title>
-<shortdesc>Create a network.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Type the name of the network.</li>
-<li>Click to select the network type. <dl rev="rev1"><dlentry>
-<dt><uicontrol>Isolated</uicontrol></dt>
-<dd>Isolated mode. Guests cannot send or receive communication to
-or from external systems.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Network Address Translation mode. Communication from guests to
-external systems uses the host IP address. External systems cannot
-initiate communication to guests.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Bridged</uicontrol></dt>
-<dd>Bridged mode. Guests can communicate with external systems and
-be contacted by external systems as if they were physical systems
-on the network. For bridged mode, you must specify additional destination
-and VLAN information.</dd>
-</dlentry></dl><?Pub Caret 224?></li>
-<li>Click <uicontrol>Create</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-<?Pub *0000002571?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/storage.dita b/plugins/kimchi/ui/pages/help/en_US/storage.dita
deleted file mode 100644
index d9a32f9..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/storage.dita
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="en-us">
-<title>Storage</title>
-<shortdesc>The <wintitle>Storage</wintitle> page lists the available
-storage pools, including the out of box 'default' and 'ISO' storage pool.
-If you want to use your own ISO, please add it to 'ISO' storage pool path.</shortdesc>
-<csbody>
-<p>For each storage pool, the following information is displayed:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name of the storage pool and percentage used.</dd>
-</dlentry><dlentry>
-<dt>State</dt>
-<dd>State of the storage pool, active (green) or inactive (red). </dd>
-</dlentry><dlentry>
-<dt>Location</dt>
-<dd>File path to the location of the storage pool.</dd>
-</dlentry><dlentry>
-<dt>Type</dt>
-<dd>Type of storage pool, for example, <uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacity</dt>
-<dd>Amount of space in the storage pool.</dd>
-</dlentry><dlentry>
-<dt>Allocated</dt>
-<dd>Amount of space that is already allocated in the storage pool.</dd>
-</dlentry></dl></p>
-<p>The following actions can be selected for each storage pool:<ul>
-<li>Select <uicontrol>Activate</uicontrol> to activate the storage
-pool so that it can be used.</li>
-<li>Select <uicontrol>Deactivate</uicontrol> to deactivate an active
-storage pool.</li>
-<li>Select <uicontrol>Undefine</uicontrol> to remove an inactive storage
-pool.</li>
-</ul></p>
-<p>To display storage volume details for a storage pool, click the
-arrow on the right side of the storage pool row. Details include
-the following:<dl><dlentry>
-<dt>Type</dt>
-<dd>The type of volume, for example, <uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Format</dt>
-<dd>The format, varying dependent on the type.</dd>
-</dlentry><dlentry>
-<dt>Capacity</dt>
-<dd>Size of the storage volume.</dd>
-</dlentry><dlentry>
-<dt>Allocation</dt>
-<dd>Amount of space that is already allocated in the storage pool.</dd>
-</dlentry></dl>To define a storage pool, click the <uicontrol>plus
-(+)</uicontrol> icon in the upper right of the display.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="en-us">
-<title>Define a storage pool</title>
-<shortdesc> Define a storage pool.</shortdesc>
-<csbody>
-<p> <ol>
-<li>In the <uicontrol>Storage pool name</uicontrol> field, type the
-name to be used to identify the storage pool.</li>
-<li>In the <uicontrol>Storage pool type</uicontrol> list, select the
-type: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Specifies a directory pool. When selecting <uicontrol>DIR</uicontrol>,
-type the <uicontrol>Storage path</uicontrol> (file path to the storage
-pool).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Specifies a network filesystem pool. When selecting <uicontrol>NFS</uicontrol>,
-type the <uicontrol>NFS server IP</uicontrol> address and <uicontrol>NFS
-path</uicontrol> (path of the exported directory).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Specifies a pool based on a target allocated on an iSCSI server.
-When selecting <uicontrol>iSCSI</uicontrol>, type the <uicontrol>iSCSI
-server</uicontrol> IP address and <uicontrol>Target</uicontrol> on
-the iSCSI server. You can optionally select to add iSCSI authentication.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logical</uicontrol></dt>
-<dd>Specifies a logical volume storage pool. Select the location to
-the device in <uicontrol>Device path</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
-<dd>Specifies a pool based on an SCSI Fibre Channel. Select which
-SCSI adapter to use.</dd>
-</dlentry></dl><?Pub Caret 0?></li>
-<li>Click <uicontrol>Create</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-<?Pub *0000003914?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/templates.dita b/plugins/kimchi/ui/pages/help/en_US/templates.dita
deleted file mode 100644
index 57ee9b5..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/templates.dita
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="en-us">
-<title>Templates</title>
-<shortdesc>The <wintitle>Templates</wintitle> page shows the defined
-virtual machine templates that can be used to create KVM guests.</shortdesc>
-<csbody>
-<p>For each template, the following information is displayed:<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>Name of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Number of processors that are defined for the template.</dd>
-</dlentry><dlentry>
-<dt>Memory</dt>
-<dd>Amount of random access memory to be allocated, in MB.</dd>
-</dlentry></dl></p>
-<p>The following actions can be selected for each template:<ul>
-<li>Select <uicontrol>Edit</uicontrol> to edit the template.</li>
-<li>Select <uicontrol>Delete</uicontrol> to delete the template.</li>
-</ul>To add a template, click the <uicontrol>plus (+)</uicontrol> icon
-in the upper right of the display.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="en-us">
-<title>Edit template</title>
-<shortdesc>Edit an existing template.</shortdesc>
-<csbody>
-<p>For each template, the following information is displayed: <dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name of the template.</dd>
-</dlentry><dlentry>
-<dt>Vendor</dt>
-<dd>The name of the company that created the operating system or distribution
-that the template is configured to use.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>The version of the operating system or distribution that the template
-is configured to use.</dd>
-</dlentry><dlentry>
-<dt>CPU number</dt>
-<dd>Number of processors that are defined for the template.</dd>
-</dlentry><dlentry>
-<dt>Memory</dt>
-<dd>Amount of memory in MB to be allocated to the virtual machine.</dd>
-</dlentry><dlentry>
-<dt>Disk</dt>
-<dd>Disk size in GB.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>File path to the location of the ISO file used to install the
-KVM guest.</dd>
-</dlentry><dlentry>
-<dt>Storage pool</dt>
-<dd>Specific storage pool or the default storage pool.</dd>
-</dlentry><dlentry>
-<dt>Network</dt>
-<dd>Default network interfaces available to the KVM guest. You can
-select multiple networks.</dd>
-</dlentry></dl> Fields that are not disabled can be edited. After
-you edit a field, click <uicontrol>Save</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Add template</title>
-<shortdesc>Add a template from source media.
-You can add your own ISO image to 'ISO' storage pool for following discovery.</shortdesc>
-<csbody>
-<p>Select the location of the source media from the following options:<dl>
-<dlentry>
-<dt>Local ISO image</dt>
-<dd>Select to scan storage pools for installation ISO images available
-on the system.</dd>
-</dlentry><dlentry>
-<dt>Remote ISO image</dt>
-<dd>Select to specify a remote location for an installation ISO image.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Add template - local ISO image</title>
-<shortdesc>Add a template from a local ISO image.</shortdesc>
-<csbody>
-<p>The ISO images available on the system are displayed.<dl><dlentry>
-<dt>OS</dt>
-<dd>Name of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>Size</dt>
-<dd>Size of the ISO image.</dd>
-</dlentry></dl></p>
-<p>To create a template from an ISO image, choose from the following
-options:<ul>
-<li>Select an ISO image from which to create a template, then click <uicontrol>Create
-Templates from Selected ISO</uicontrol>.</li>
-<li>Select <uicontrol>All</uicontrol> to create a template from each
- listed ISO image, then click <uicontrol>Create Templates from Selected
-ISO</uicontrol>.</li>
-<li>If the ISO image that you want to use does not appear in the scan
-results, you can select from the following options:<ul>
-<li>Select <uicontrol>I want to use a specific ISO file</uicontrol> to
-specify a path to the ISO image.</li>
-<li>Click <uicontrol>Search more ISOs</uicontrol> to search for more
-ISO images.</li>
-</ul></li><?Pub Caret 0?>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-<?Pub *0000004433?>
diff --git a/plugins/kimchi/ui/pages/help/es_ES/Makefile.am b/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
deleted file mode 100644
index 29c596f..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-es_ES_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/es_ES
-
-dist_es_ES_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/es_ES/guests.dita b/plugins/kimchi/ui/pages/help/es_ES/guests.dita
deleted file mode 100644
index 88e77e0..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/guests.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="es-es">
-<title>Invitados</title>
-<shortdesc>La página <wintitle>Invitados</wintitle> lista las máquinas virtuales KVM definidas.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente información para cada invitado:<dl><dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la máquina virtual.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Porcentaje de utilización de procesador en la máquina virtual.</dd>
-</dlentry><dlentry>
-<dt>E/S de red</dt>
-<dd>Velocidad de transmisión de entrada/salida de red en KB por segundos.</dd>
-</dlentry><dlentry>
-<dt>E/S de disco</dt>
-<dd>Velocidad de transmisión de entrada/salida de disco en KB por segundos.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>Estado de la consola del sistema operativo invitado, o un icono que representa la distribución de <tm tmtype="tm" trademark="Linux">Linux</tm> si el invitado no está activo.</dd>
-</dlentry></dl></p>
-<p>Se visualizan los siguientes iconos de acciones para cada invitado:<dl>
-<dlentry>
-<dt>Restablecer</dt>
-<dd>Pulse aquà para restablecer el invitado. </dd>
-</dlentry><dlentry>
-<dt>Alimentación (Iniciar o Detener)</dt>
-<dd>Pulse aquà para encender o apagar el invitado. Si el icono es de color rojo, la alimentación está apagada; si el icono es de color verde, la alimentación está encendida.</dd>
-</dlentry></dl> </p>
-<p>Se pueden seleccionar las siguientes acciones para cada invitado:<ul>
-<li>Seleccione <uicontrol>Conectar</uicontrol> para conectarse a la consola remota para el sistema operativo invitado.</li>
-<li>Seleccione <uicontrol>Gestionar soporte</uicontrol> para cambiar la vÃa de acceso al soporte de instalación.</li>
-<li>Seleccione <uicontrol>Restablecer</uicontrol> para restablecer el invitado.</li>
-<li>Seleccione <uicontrol>Editar</uicontrol> para editar las propiedades de un invitado existente. Los invitados sólo pueden editarse mientras están detenidos.</li>
-<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir el invitado.</li>
-</ul>Para crear un invitado o máquina virtual, pulse el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la página.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="es-es">
-<title>Crear máquina virtual</title>
-<shortdesc>Crear una máquina virtual utilizando una plantilla existente.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Escriba el nombre a utilizar para identificar la máquina virtual.</li>
-<li rev="rev1">Seleccione una plantilla. <ul>
-<li>Si existen plantillas, seleccione entre las plantillas mostradas.</li>
-<li>Si no existen plantillas, pulse <uicontrol>Crear una plantilla</uicontrol> para crear una plantilla.</li>
-</ul></li>
-<li>Pulse <uicontrol>Crear</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="es-es">
-<title>Editar invitado</title>
-<shortdesc>Editar las propiedades de una máquina virtual existente. Algunas propiedades pueden editarse sólo cuando el invitado se ha detenido. Otras surtirán efecto en el arranque siguiente.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Se visualiza la siguiente información para cada invitado en la pestaña <wintitle>General</wintitle>:<dl>
-<dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la máquina virtual.(sólo puede editarse cuando el invitado se ha detenido)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Número de procesadores.(si el invitado está en ejecución, la nueva cantidad surtirá efecto en el siguiente arranque)
-</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>Cantidad de memoria en MB.(si el invitado está en ejecución, la nueva cantidad surtirá efecto en el siguiente arranque)
-</dd>
-</dlentry><dlentry>
-<dt>Icono</dt>
-<dd>Imagen gráfica que representa la distribución de Linux a visualizar en lugar del estado actual (Livetile) cuando el invitado no está activo.</dd>
-</dlentry></dl></p>
-<p>Se visualiza la siguiente información en la pestaña <wintitle>Almacenamiento</wintitle>.</p>
-<dl><dlentry>
-<dt>Almacenamiento</dt>
-<dd>Muestra la ubicación del archivo ISO utilizado para la instalación.</dd>
-</dlentry></dl>
-<p> Los campos que no están inhabilitados pueden editarse. Después de editar un campo, pulse <uicontrol>Guardar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="es-es">
-<title>Añadir, sustituir o desconectar un dispositivo de almacenamiento</title>
-<shortdesc rev="rev1">Puede añadir, sustituir o desconectar un dispositivo de almacenamiento a la máquina virtual. El único dispositivo soportado es CDROM. Para editar los dispositivos de almacenamiento, siga estos pasos:</shortdesc>
-<csbody>
-<ol>
-<li>En la ventana <wintitle>Editar invitado</wintitle>, seleccione <wintitle>Almacenamiento</wintitle>.</li>
-<li>Para sustituir un dispositivo de almacenamiento, pulse el primer icono con la <uicontrol>barra inclinada naranja (/)</uicontrol>. Especifique la vÃa de acceso del archivo ISO y pulse <uicontrol>Sustituir</uicontrol>.</li>
-<li>Para desconectar un dispositivo de almacenamiento, pulse el segundo icono con el <uicontrol>guión rojo (-)</uicontrol>. Confirme la supresión y pulse <uicontrol>Aceptar</uicontrol>.</li>
-<li>Para añadir un dispositivo de almacenamiento, pulse el tercer icono con el <uicontrol>signo más (+)</uicontrol> verde. Especifique un nombre de dispositivo y la vÃa de acceso del archivo ISO y pulse <uicontrol>Conectar</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="es-es">
-<title>Sustituir un CDROM de máquina virtual</title>
-<shortdesc rev="rev1">Puede sustituir el contenido del CDROM para una máquina virtual después de completarse la instalación.</shortdesc>
-<csbody>
-<ol>
-<li>Asegúrese de que la máquina virtual se ha iniciado.</li>
-<li>En el menú Acciones, seleccione <uicontrol>Gestionar soporte</uicontrol>.</li>
-<li>Para cambiar lo que está cargado actualmente en el CDROM, pulse el icono <uicontrol>barra inclinada naranja (/)</uicontrol> junto al campo hdc.</li>
-<li>En la página <wintitle>Sustituir un CDROM de máquina virtual</wintitle>, especifique la vÃa de acceso del archivo ISO. Los otros dos campos son de sólo lectura.</li>
-<li>Pulse <uicontrol>Sustituir</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/host.dita b/plugins/kimchi/ui/pages/help/es_ES/host.dita
deleted file mode 100644
index 7734244..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/host.dita
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="es-es">
-<title>Host</title>
-<shortdesc>La página <wintitle>Host</wintitle> muestra información sobre el sistema host y le permite concluir, reiniciar y conectar con el sistema principal.</shortdesc>
-<csbody>
-<p>Puede realizar las acciones siguientes en el host:<ul>
-<li>Seleccione <uicontrol>Concluir</uicontrol> para concluir el sistema host.</li>
-<li>Seleccione <uicontrol>Reiniciar</uicontrol> para reiniciar el sistema host.</li>
-<li>Seleccione <uicontrol>Conectar</uicontrol> para abrir una conexión VNC al sistema host, si no está conectado aún.</li>
-</ul></p>
-<p>Pulse en las secciones siguientes para visualizar información acerca del host:<dl>
-<dlentry>
-<dt>Información básica</dt>
-<dd>Esta sección muestra la distribución del sistema operativo de host, la versión y el nombre de código, asà como el tipo de procesador y la cantidad de memoria en GB.</dd>
-</dlentry><dlentry>
-<dt>EstadÃsticas del sistema</dt>
-<dd>Esta sección muestra gráficos para mostrar estadÃsticas para CPU, memoria, E/S de disco y E/S de red para el host. Seleccione <uicontrol>Recoger datos después de salir de esta página</uicontrol> para continuar la recogida de datos cuando la pestaña principal ya no está a la vista.</dd>
-</dlentry><dlentry>
-<dt>Actualizaciones de software</dt>
-<dd>En esta sección se muestra información para todos los paquetes que tienen actualizaciones disponibles, incluido el nombre de paquete, versión, arquitectura y repositorio. Puede actualizar todos los paquetes listados seleccionando <uicontrol>Actualizar todo</uicontrol>. No puede seleccionar paquetes individuales para las actualizaciones.</dd>
-</dlentry><dlentry>
-<dt>Repositorios</dt>
-<dd>En esta sección se muestran los repositorios que están asociados con el sistema host. Puede añadir, habilitar, editar o eliminar repositorios. Añadir un repositorio lo asocia con el sistema host mientras que habilitar un repositorio permite que el host acceda a él. Si el sistema es Red Hat Enterprise
-Linux o Fedora, puede añadir repositorios <filepath>yum</filepath>.
-Si el sistema es Ubuntu o Debian, añada repositorios <filepath>deb</filepath>.<p>Si está trabajando con repositorios yum, puede añadir una comprobación GPG para verificar que un paquete de este repositorio no ha resultado dañado.
-Seleccione un repositorio y, a continuación, <uicontrol>Editar</uicontrol>. Seleccione <uicontrol>SÃ</uicontrol> para habilitar la comprobación GPG y, a continuación, especifique un URL al archivo de claves GPG para el repositorio.</p></dd>
-</dlentry><dlentry>
-<dt>Informes de depuración</dt>
-<dd>En esta sección se muestran informes de depuración, incluido el nombre y la ruta de archivo.
-Puede seleccionar entre opciones para generar un informe nuevo, o bien redenominar, eliminar o descargar un informe existente.<p>El informe de depuración se genera utilizando el mandato <cmdname>sosreport</cmdname>. Está disponible para distribuciones de Red
-Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora y Ubuntu. El mandato genera un archivo .tar que contiene la información de configuración y de diagnóstico, como la versión de kernel en ejecución, los módulos de carga y los archivos de configuración del sistema y servicio.
-El mandato también ejecuta programas externos para recopilar información adicional y almacena esta salida en el archivo resultante.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/network.dita b/plugins/kimchi/ui/pages/help/es_ES/network.dita
deleted file mode 100644
index 3654531..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="es-es">
-<title>Red</title>
-<shortdesc>La página <wintitle>Red</wintitle> muestra información sobre la conexión de red.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nombre de red</dt>
-<dd>Nombre de la red, o <uicontrol>predeterminado</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado de la red, activa (verde) o inactiva (rojo). </dd>
-</dlentry><dlentry>
-<dt>Tipo de red</dt>
-<dd>Tipo de red, por ejemplo, <uicontrol>NAT</uicontrol> (conversión de direcciones de red).</dd>
-</dlentry><dlentry>
-<dt>Interfaz</dt>
-<dd>La interfaz de red, por ejemplo, <uicontrol>virbr0</uicontrol> (predeterminada).</dd>
-</dlentry><dlentry>
-<dt>Espacio de direcciones</dt>
-<dd>Dirección IP.</dd>
-</dlentry></dl></p>
-<p>Se pueden seleccionar las siguientes acciones:<ul>
-<li rev="rev1">Seleccione <uicontrol>Iniciar</uicontrol> para iniciar la conexión de red.</li>
-<li>Seleccione <uicontrol>Detener</uicontrol> para finalizar la conexión de red.</li>
-<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la información de conexión.</li>
-</ul>Para crear una red, pulse en el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="es-es">
-<title>Crear una red</title>
-<shortdesc>Crear una red.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Escriba el nombre de la red.</li>
-<li>Pulse para seleccionar el tipo de red. <dl rev="rev1"><dlentry>
-<dt><uicontrol>Aislada</uicontrol></dt>
-<dd>Modalidad aislada. Los invitados no pueden enviar ni recibir comunicación a sistemas externos o desde ellos.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Modalidad de Conversión de direcciones de red. La comunicación de invitados a sistemas externos utiliza la dirección IP del host. Los sistemas externos no pueden iniciar la comunicación con los invitados.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Puenteada</uicontrol></dt>
-<dd>Modalidad puenteada. Los invitados pueden comunicarse con sistemas externos y ser contactados por sistemas externos como si fueran sistemas fÃsicos en la red. Para la modalidad puenteada, debe especificar información de destino y VLAN adicional.</dd>
-</dlentry></dl></li>
-<li>Pulse <uicontrol>Crear</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/storage.dita b/plugins/kimchi/ui/pages/help/es_ES/storage.dita
deleted file mode 100644
index 0c68951..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/storage.dita
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="es-es">
-<title>Almacenamiento</title>
-<shortdesc>La página <wintitle>Almacenamiento</wintitle> lista las agrupaciones de almacenamiento disponibles, incluyendo la agrupación de almacenamiento predefinida 'default' e 'ISO'.
-Si desea utilizar su propia ISO, añádala a la vÃa de acceso de la agrupación de almacenamiento 'ISO'.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente información para cada agrupación de almacenamiento:<dl>
-<dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la agrupación de almacenamiento y el porcentaje utilizado.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado de la agrupación de almacenamiento, activa (verde) o inactiva (rojo). </dd>
-</dlentry><dlentry>
-<dt>Ubicación</dt>
-<dd>VÃa de acceso de archivo a la ubicación de la agrupación de almacenamiento.</dd>
-</dlentry><dlentry>
-<dt>Tipo</dt>
-<dd>Tipo de agrupación de almacenamiento, por ejemplo, <uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacidad</dt>
-<dd>Cantidad de espacio en la agrupación de almacenamiento.</dd>
-</dlentry><dlentry>
-<dt>Asignado</dt>
-<dd>Cantidad de espacio que ya está asignado en la agrupación de almacenamiento.</dd>
-</dlentry></dl></p>
-<p>Se pueden seleccionar las siguientes acciones para cada agrupación de almacenamiento:<ul>
-<li>Seleccione <uicontrol>Activar</uicontrol> para activar la agrupación de almacenamiento para que pueda utilizarse.</li>
-<li>Seleccione <uicontrol>Desactivar</uicontrol> para desactivar una agrupación de almacenamiento activa.</li>
-<li>Seleccione <uicontrol>No definir</uicontrol> para eliminar una agrupación de almacenamiento inactiva.</li>
-</ul></p>
-<p>Para visualizar detalles de volumen de almacenamiento para una agrupación de almacenamiento, pulse la flecha situada en el lado derecho de la fila de agrupación de almacenamiento. Los detalles incluyen lo siguiente:<dl><dlentry>
-<dt>Tipo</dt>
-<dd>El tipo de volumen, por ejemplo, <uicontrol>archivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Formato</dt>
-<dd>El formato, variable dependiendo del tipo.</dd>
-</dlentry><dlentry>
-<dt>Capacidad</dt>
-<dd>Tamaño del volumen de almacenamiento.</dd>
-</dlentry><dlentry>
-<dt>Asignación</dt>
-<dd>Cantidad de espacio que ya está asignado en la agrupación de almacenamiento.</dd>
-</dlentry></dl>Para definir una agrupación de almacenamiento, pulse en el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="es-es">
-<title>Definir una agrupación de almacenamiento</title>
-<shortdesc> Definir una agrupación de almacenamiento.</shortdesc>
-<csbody>
-<p> <ol>
-<li>En el campo <uicontrol>Nombre de agrupación de almacenamiento</uicontrol>, escriba el nombre que se utilizará para identificar la agrupación de almacenamiento.</li>
-<li>En la lista <uicontrol>Tipo de agrupación almacenamiento</uicontrol>, seleccione el tipo: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Especifica una agrupación de directorio. Al seleccionar <uicontrol>DIR</uicontrol>, escriba la <uicontrol>VÃa de acceso de almacenamiento</uicontrol> (vÃa de acceso de archivo a la agrupación de almacenamiento).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Especifica una agrupación de sistema de archivos de red. Al seleccionar <uicontrol>NFS</uicontrol>, escriba la dirección <uicontrol>IP de servidor NFS</uicontrol> y <uicontrol>vÃa de acceso de NFS</uicontrol> (vÃa de acceso del directorio exportado).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Especifica una agrupación basada en un destino asignado en un servidor iSCSI.
-Al seleccionar <uicontrol>iSCSI</uicontrol>, escriba la dirección IP del <uicontrol>Servidor iSCSI</uicontrol> y el <uicontrol>Destino</uicontrol> en el servidor iSCSI. Opcionalmente puede seleccionar añadir autenticación iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Lógico</uicontrol></dt>
-<dd>Especifica una agrupación de almacenamiento de volumen lógico. Seleccione la ubicación al dispositivo en <uicontrol>VÃa de acceso de dispositivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Canal de fibra de SCSI</uicontrol></dt>
-<dd>Especifica una agrupación basada en un Canal de fibra SCSI. Seleccione qué adaptador SCSI se utilizará.</dd>
-</dlentry></dl></li>
-<li>Pulse <uicontrol>Crear</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/templates.dita b/plugins/kimchi/ui/pages/help/es_ES/templates.dita
deleted file mode 100644
index 8cceee7..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="es-es">
-<title>Plantillas</title>
-<shortdesc>La página <wintitle>Plantillas</wintitle> muestra las plantillas de máquina virtual definidas que se pueden utilizar para crear invitados KVM.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente información para cada plantilla:<dl>
-<dlentry>
-<dt>SO</dt>
-<dd>Nombre del sistema operativo o distribución.</dd>
-</dlentry><dlentry>
-<dt>Versión</dt>
-<dd>Versión del sistema operativo o distribución.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Número de procesadores que están definidos para la plantilla.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>Cantidad de memoria de acceso aleatorio a asignar, en MB.</dd>
-</dlentry></dl></p>
-<p>Se pueden seleccionar las siguientes acciones para cada plantilla:<ul>
-<li>Seleccione <uicontrol>Editar</uicontrol> para editar la plantilla.</li>
-<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la plantilla.</li>
-</ul>Para añadir una plantilla, pulse en el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="es-es">
-<title>Editar plantilla</title>
-<shortdesc>Editar una plantilla existente.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente información para cada plantilla: <dl>
-<dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la plantilla.</dd>
-</dlentry><dlentry>
-<dt>Proveedor</dt>
-<dd>El nombre de la empresa que creó el sistema operativo o distribución que la plantilla está configurada para utilizar.</dd>
-</dlentry><dlentry>
-<dt>Versión</dt>
-<dd>La versión del sistema operativo o distribución que la plantilla está configurada para utilizar.</dd>
-</dlentry><dlentry>
-<dt>Número de CPU</dt>
-<dd>Número de procesadores que están definidos para la plantilla.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>Cantidad de memoria en MB a asignar a la máquina virtual.</dd>
-</dlentry><dlentry>
-<dt>Disco</dt>
-<dd>Tamaño de disco en GB.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>VÃa de acceso de archivo a la ubicación del archivo ISO utilizado para instalar el invitado KVM.</dd>
-</dlentry><dlentry>
-<dt>Agrupación de almacenamiento</dt>
-<dd>Agrupación de almacenamiento especÃfica o la agrupación de almacenamiento predeterminada.</dd>
-</dlentry><dlentry>
-<dt>Red</dt>
-<dd>Interfaces de red predeterminadas disponibles para el invitado KVM. Puede seleccionar varias redes.</dd>
-</dlentry></dl> Los campos que no están inhabilitados pueden editarse. Después de editar un campo, pulse <uicontrol>Guardar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Añadir plantilla</title>
-<shortdesc>Añadir una plantilla desde el soporte de origen. Puede añadir su propia imagen ISO a la agrupación de almacenamiento 'ISO' para el siguiente descubrimiento.</shortdesc>
-<csbody>
-<p>Seleccione la ubicación del soporte de origen entre una de las opciones siguientes:<dl>
-<dlentry>
-<dt>Imagen ISO local</dt>
-<dd>Seleccione esta opción para explorar las agrupaciones de almacenamiento en busca de imágenes ISO de instalación disponibles en el sistema.</dd>
-</dlentry><dlentry>
-<dt>Imagen ISO remota</dt>
-<dd>Seleccione esta opción para especificar una ubicación remota para una imagen ISO de instalación.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Añadir plantilla â imagen ISO local</title>
-<shortdesc>Añadir una plantilla desde una imagen ISO local.</shortdesc>
-<csbody>
-<p>Se visualizan las imágenes ISO disponibles en el sistema.<dl><dlentry>
-<dt>SO</dt>
-<dd>Nombre del sistema operativo o distribución.</dd>
-</dlentry><dlentry>
-<dt>Versión</dt>
-<dd>Versión del sistema operativo o distribución.</dd>
-</dlentry><dlentry>
-<dt>Tamaño</dt>
-<dd>Tamaño de la imagen ISO.</dd>
-</dlentry></dl></p>
-<p>Para crear una plantilla a partir de una imagen ISO, elija entre las opciones siguientes:<ul>
-<li>Seleccione una imagen ISO desde la que desea crear una plantilla y, a continuación, pulse <uicontrol>Crear plantillas desde ISO seleccionada</uicontrol>.</li>
-<li>Seleccione <uicontrol>Todo</uicontrol> para crear una plantilla desde cada imagen ISO en la lista y, a continuación, pulse <uicontrol>Crear plantillas desde ISO seleccionada</uicontrol>.</li>
-<li>Si la imagen ISO que desea utilizar no aparece en los resultados de la exploración, puede seleccionar entre las opciones siguientes:<ul>
-<li>Seleccione <uicontrol>Deseo utilizar un archivo ISO especÃfico</uicontrol> para especificar una vÃa de acceso a la imagen ISO.</li>
-<li>Pulse <uicontrol>Buscar más ISO</uicontrol> para buscar más imágenes ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am b/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
deleted file mode 100644
index 11ce394..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-fr_FR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/fr_FR
-
-dist_fr_FR_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/guests.dita b/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
deleted file mode 100644
index ad5b4e4..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="fr-fr">
-<title>Invités</title>
-<shortdesc>La page <wintitle>Invités</wintitle> répertorie les machines virtuelles KVM définies.</shortdesc>
-<csbody>
-<p>Pour chaque invité, les informations suivantes sont affichées :<dl><dlentry>
-<dt>Nom</dt>
-<dd>Nom de la machine virtuelle.</dd>
-</dlentry><dlentry>
-<dt>UC</dt>
-<dd>Pourcentage d'utilisation du processeur sur la machine virtuelle.</dd>
-</dlentry><dlentry>
-<dt>E-S réseau</dt>
-<dd>Vitesse de transmission d'entrée-sortie du réseau, exprimée en ko par seconde.</dd>
-</dlentry><dlentry>
-<dt>E-S disque</dt>
-<dd>Vitesse de transmission d'entrée-sortie du disque, exprimée en ko par seconde.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>Etat de la console du système d'exploitation de l'hôte, ou
-icône représentant la distribution <tm tmtype="tm" trademark="Linux">Linux</tm>
-si l'invité n'est pas actif.</dd>
-</dlentry></dl></p>
-<p>Les icônes d'action suivantes sont affichées pour chaque invité :<dl>
-<dlentry>
-<dt>Réinitialiser</dt>
-<dd>Cliquez pour réinitialiser l'invité. </dd>
-</dlentry><dlentry>
-<dt>Alimentation (Démarrer ou Arrêter)</dt>
-<dd>Cliquez pour mettre sous ou hors tension l'invité. Si l'icône est rouge,
-l'alimentation est démarrée ; si l'icône est verte, l'alimentation est arrêtée.</dd>
-</dlentry></dl> </p>
-<p>Les actions suivantes peuvent être sélectionnées pour chaque invité :<ul>
-<li>Sélectionnez <uicontrol>Connexion</uicontrol> pour vous connecter à la console
-distante du système d'exploitation invité.</li>
-<li>Sélectionnez <uicontrol>Gérer le support</uicontrol> pour modifier le chemin
-d'accès au support d'installation.</li>
-<li>Sélectionnez <uicontrol>Réinitialiser</uicontrol> pour réinitialiser l'invité.</li>
-<li>Sélectionnez <uicontrol>Editer</uicontrol> pour éditer les propriétés d'un invité existant. Les invités peuvent être édités uniquement lorsqu'ils sont à l'arrêt.</li>
-<li>Sélectionnez <uicontrol>Supprimer</uicontrol> pour supprimer l'invité.</li>
-</ul>Pour créer un invité, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
-dans le coin supérieur droit de la page.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="fr-fr">
-<title>Créer une machine virtuelle</title>
-<shortdesc>Créez une machine virtuelle en utilisant un modèle existant.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Entrez le nom à utiliser pour identifier la machine virtuelle.</li>
-<li rev="rev1">Sélectionnez un modèle. <ul>
-<li>Si des modèles existent, faites un choix parmi les modèles affichés.</li>
-<li>Si aucun modèle n'existe, cliquez sur <uicontrol>Créer un modèle</uicontrol> pour créer un modèle.</li>
-</ul></li>
-<li>Cliquez sur <uicontrol>Créer</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="fr-fr">
-<title>Editer l'invité</title>
-<shortdesc>Editez les propriétés d'une machine virtuelle existante. Certaines propriétés
-peuvent être éditées uniquement lorsque l'invité est arrêté. D'autres seront appliquées à l'amorçage suivant.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Pour chaque invité, les informations suivantes sont affichées dans l'onglet <wintitle>Général</wintitle> :<dl>
-<dlentry>
-<dt>Nom</dt>
-<dd>Nom de la machine virtuelle. (Ne peut être édité que lorsque l'invité est arrêté)</dd>
-</dlentry><dlentry>
-<dt>UC</dt>
-<dd>Nombre de processeurs. (Si l'invité est en cours d'exécution, la nouvelle quantité sera appliquée à l'amorçage suivant)</dd>
-</dlentry><dlentry>
-<dt>Mémoire</dt>
-<dd>Quantité de mémoire en Mo. (Si l'invité est en cours d'exécution, la nouvelle quantité sera appliquée à l'amorçage suivant)</dd>
-</dlentry><dlentry>
-<dt>Icône</dt>
-<dd>Image graphique représentant la distribution Linux à afficher à la place
-du statut en cours (Livetile) lorsque l'invité n'est pas actif.</dd>
-</dlentry></dl></p>
-<p>Les informations suivantes sont affichées dans l'onglet <wintitle>Stockage</wintitle>.</p>
-<dl><dlentry>
-<dt>Stockage</dt>
-<dd>Affiche l'emplacement du fichier ISO utilisé pour l'installation.</dd>
-</dlentry></dl>
-<p> Les zones qui ne sont pas désactivées peuvent être éditées. Après que vous avez édité une zone, cliquez sur <uicontrol>Sauvegarder</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="fr-fr">
-<title>Ajoutez, remplacez ou détachez une unité de stockage</title>
-<shortdesc rev="rev1">Vous pouvez ajouter, remplacer ou détacher une unité de stockage
-pour votre machine virtuelle. Seule une unité CD-ROM est prise en charge. Pour éditer vos unités de stockage, procédez comme suit :</shortdesc>
-<csbody>
-<ol>
-<li>Dans la fenêtre <wintitle>Editer l'invité</wintitle>, sélectionnez <wintitle>Stockage</wintitle>.</li>
-<li>Pour remplacer une unité de stockage, cliquez sur la première icône avec la <uicontrol>barre oblique (/) orange</uicontrol>. Entrez le chemin d'accès au fichier ISO et cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
-<li>Pour détacher une unité de stockage, cliquez sur la deuxième icône avec le <uicontrol>tiret (-) rouge</uicontrol>. Confirmer la suppression et cliquez sur <uicontrol>OK</uicontrol>.</li>
-<li>Pour ajouter une unité de stockage, cliquez sur la troisième icône avec le <uicontrol>signe plus (+) vert</uicontrol>. Entrez un nom d'unité et un chemin d'accès au fichier ISO puis cliquez sur <uicontrol>Attacher</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="fr-fr">
-<title>Remplacer l'unité CD-ROM d'une machine virtuelle</title>
-<shortdesc rev="rev1">Vous pouvez remplacer le contenu du CD-ROM pour
-une machine virtuelle une fois l'installation terminée.</shortdesc>
-<csbody>
-<ol>
-<li>Vérifiez que la machine virtuelle est démarrée.</li>
-<li>Dans le menu Actions, sélectionnez <uicontrol>Gérer le support</uicontrol>.</li>
-<li>Pour modifier les données actuellement chargées dans l'unité de CD-ROM, cliquez sur l'icône
-<uicontrol>barre oblique (/) orange</uicontrol> en regard de la zone hdc.</li>
-<li>Sur la page <wintitle>Remplacer une unité CD-ROM d'une machine virtuelle</wintitle>,
-entrez le chemin d'accès au fichier ISO. Les deux autres zones sont en lecture seule.</li>
-<li>Cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/host.dita b/plugins/kimchi/ui/pages/help/fr_FR/host.dita
deleted file mode 100644
index f4c330b..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/host.dita
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="fr-fr">
-<title>Hôte</title>
-<shortdesc>La page <wintitle>Hôte</wintitle> affiche des informations
-sur le système hôte et vous permet d'arrêter, de redémarrer et de vous
-connecter à l'hôte.</shortdesc>
-<csbody>
-<p>Vous pouvez effectuer les actions suivantes sur l'hôte :<ul>
-<li>Sélectionnez <uicontrol>Arrêter</uicontrol> pour arrêter le système hôte.</li>
-<li>Sélectionnez <uicontrol>Redémarrer</uicontrol> pour redémarrer le système hôte.</li>
-<li>Sélectionnez <uicontrol>Connexion</uicontrol> pour ouvrir une connexion VNC
-au système hôte, si celui-ci n'est pas déjà connecté.</li>
-</ul></p>
-<p>Cliquez sur les sections suivantes pour afficher des informations sur l'hôte :<dl>
-<dlentry>
-<dt>Informations de base</dt>
-<dd>Cette section affiche la distribution, la version et le nom de code
-du système d'exploitation hôte, ainsi que le type de processeur et la quantité
-de mémoire en Go.</dd>
-</dlentry><dlentry>
-<dt>Statistiques système</dt>
-<dd>Cette section affiche les graphiques des statistiques pour l'UC, mémoire, ainsi que
-les E-S disque et E-S réseau pour l'hôte. Sélectionnez <uicontrol>Collecte des données une fois la page quittée</uicontrol>
-pour continuer la collecte de données lorsque l'onglet hôte n'est plus visible.</dd>
-</dlentry><dlentry>
-<dt>Mises à jour logicielles</dt>
-<dd>Cette section affiche des informations pour tous les modules qui
-disposent de mises à jour disponibles, y compris le nom de module, la version, l'architecture
-et le référentiel. Vous pouvez mettre à jour toutes les modules répertoriés en sélectionnant <uicontrol>Tout
-mettre à jour</uicontrol>. Vous ne pouvez pas sélectionner des modules individuels pour les mises à jour.</dd>
-</dlentry><dlentry>
-<dt>Référentiels</dt>
-<dd>Cette section affiche les référentiels associés au système hôte. Vous pouvez ajouter, activer, éditer ou retirer des référentiels. L'ajout d'un référentiel associe celui-ci au système hôte,
-tandis que l'activation d'un référentiel permet à l'hôte d'y accéder. Si votre système est Red Hat Enterprise Linux ou Fedora,
-vous pouvez ajouter des référentiels <filepath>yum</filepath>.
-Si votre système est de type Ubuntu ou Debian, ajoutez des référentiels
-<filepath>deb</filepath>.<p>Si vous travaillez avec des référentiels yum, vous pouvez ajouter un contrôle GPG
-afin de vérifier qu'un module provenant de ce référentiel n'a pas été endommagé.
-Sélectionnez un référentiel puis cliquez sur <uicontrol>Editer</uicontrol>. Sélectionnez <uicontrol>Oui</uicontrol> pour activer le contrôle GPG,
-puis entrez une URL pour le fichier de clés GPG du référentiel.</p></dd>
-</dlentry><dlentry>
-<dt>Rapports de débogage</dt>
-<dd>Cette section affiche les rapports de débogage, y compris le nom et le chemin du fichier.
-Vous pouvez faire un choix parmi les options afin de générer un nouveau rapport, ou renommer, supprimer,
-ou télécharger un rapport existant.<p>Le rapport de débogage est généré Ã
-l'aide de la commande <cmdname>sosreport</cmdname>. Cette option est disponible pour les distributions
-Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora et Ubuntu. La commande génère un fichier .tar contenant la configuration et des informations de diagnostic,
-telles que la version du noyau d'exécution, les modules chargés, ainsi que les fichiers de configuration
-du système et de la maintenance.
-La commande exécute également des programmes externes pour collecter des informations
-supplémentaires et stocke cette sortie dans l'archive résultante.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/network.dita b/plugins/kimchi/ui/pages/help/fr_FR/network.dita
deleted file mode 100644
index 5c2e9dd..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/network.dita
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="fr-fr">
-<title>Réseau</title>
-<shortdesc>La page <wintitle>Réseau</wintitle> affiche des informations sur la connexion réseau.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nom du réseau</dt>
-<dd>Nom du réseau, ou <uicontrol>par défaut</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Etat</dt>
-<dd>Etat du réseau, actif (vert) ou inactif (rouge). </dd>
-</dlentry><dlentry>
-<dt>Type de réseau</dt>
-<dd>Type du réseau, par exemple <uicontrol>NAT</uicontrol> (conversion d'adresses réseau).</dd>
-</dlentry><dlentry>
-<dt>Interface</dt>
-<dd>Interface réseau, par exemple <uicontrol>virbr0</uicontrol> (par défaut).</dd>
-</dlentry><dlentry>
-<dt>Espace adresse</dt>
-<dd>Adresse IP.</dd>
-</dlentry></dl></p>
-<p>Les actions suivantes peuvent être sélectionnées :<ul>
-<li rev="rev1">Sélectionnez <uicontrol>Démarrer</uicontrol> pour démarrer la connexion au réseau.</li>
-<li>Sélectionnez <uicontrol>Arrêter</uicontrol> pour mettre fin à la connexion au réseau.</li>
-<li>Sélectionnez <uicontrol>Supprimer</uicontrol> pour supprimer les informations de connexion.</li>
-</ul>Pour créer un réseau, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
-dans le coin supérieur droit de l'écran.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="fr-fr">
-<title>Créer un réseau</title>
-<shortdesc>Créez un réseau.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Entrez le nom du réseau.</li>
-<li>Cliquez pour sélectionner le type de réseau. <dl rev="rev1"><dlentry>
-<dt><uicontrol>Isolé</uicontrol></dt>
-<dd>Mode isolé. Les invités ne peuvent pas envoyer ni recevoir de communication avec des systèmes externes.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Mode de conversion d'adresses réseau. La communication à partir d'invités
-vers des systèmes externes utilise l'adresse IP hôte. Les systèmes externes ne
-peuvent pas initier de communication vers les invités.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Routé</uicontrol></dt>
-<dd>Mode routé. Les invités peuvent communiquer avec des systèmes externes et
-être contactés par des systèmes externes comme s'il s'agissait de systèmes physiques
-sur le réseau. Pour le mode routé, vous devez spécifier des informations supplémentaires
-sur la destination et le réseau local virtuel.</dd>
-</dlentry></dl></li>
-<li>Cliquez sur <uicontrol>Créer</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/storage.dita b/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
deleted file mode 100644
index eebf2bb..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="fr-fr">
-<title>Stockage</title>
-<shortdesc>La page <wintitle>Stockage</wintitle> répertorie les pools de stockage disponibles,
-y compris les pools de stockage 'default' et 'ISO' prêts à l'emploi.
-Si vous souhaitez utiliser votre propre pool de stockage ISO, ajoutez-le dans le chemin du pool de stockage 'ISO'.</shortdesc>
-<csbody>
-<p>Pour chaque pool de stockage, les informations suivantes sont affichées :<dl>
-<dlentry>
-<dt>Nom</dt>
-<dd>Nom du pool de stockage et pourcentage d'utilisation.</dd>
-</dlentry><dlentry>
-<dt>Etat</dt>
-<dd>Etat du pool de stockage, actif (vert) ou inactif (rouge). </dd>
-</dlentry><dlentry>
-<dt>Emplacement</dt>
-<dd>chemin d'accès au fichier pour l'emplacement du pool de stockage.</dd>
-</dlentry><dlentry>
-<dt>Type</dt>
-<dd>Type de pool de stockage, par exemple <uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacité</dt>
-<dd>Quantité d'espace dans le pool de stockage.</dd>
-</dlentry><dlentry>
-<dt>Alloué</dt>
-<dd>Quantité d'espace déjà allouée dans le pool de stockage.</dd>
-</dlentry></dl></p>
-<p>Les actions suivantes peuvent être sélectionnées pour chaque pool de stockage :<ul>
-<li>Sélectionnez <uicontrol>Activer</uicontrol> pour activer le pool de stockage pour utilisation.</li>
-<li>Sélectionnez <uicontrol>Désactiver</uicontrol> pour désactiver un pool de stockage actif.</li>
-<li>Sélectionnez <uicontrol>Annuler définition</uicontrol> pour retirer un pool de stockage inactif.</li>
-</ul></p>
-<p>Pour afficher les détails de volume de stockage pour un pool de stockage, cliquez sur la
-flèche située à droite de la ligne du pool de stockage. Détails inclus :<dl><dlentry>
-<dt>Type</dt>
-<dd>Type de volume, par exemple <uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Format</dt>
-<dd>Format, variable selon le type.</dd>
-</dlentry><dlentry>
-<dt>Capacité</dt>
-<dd>Taille du volume de stockage.</dd>
-</dlentry><dlentry>
-<dt>Allocation</dt>
-<dd>Quantité d'espace déjà allouée dans le pool de stockage.</dd>
-</dlentry></dl>Pour définir un pool de stockage, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
-dans le coin supérieur droit de l'écran.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="fr-fr">
-<title>Définir un pool de stockage</title>
-<shortdesc> Définissez un pool de stockage.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Dans la zone <uicontrol>Nom du pool de stockage</uicontrol>, entrez le nom à utiliser pour identifier le pool de stockage.</li>
-<li>Dans la zone <uicontrol>Type de pool de stockage</uicontrol>, sélectionnez le type : <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Indique un pool de répertoires. Lorsque vous sélectionnez <uicontrol>DIR</uicontrol>,
-indiquez le <uicontrol>Chemin de stockage</uicontrol> (chemin d'accès au fichier
-du pool de stockage).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>indique un pool de systèmes de fichiers réseau. Lorsque vous sélectionnez <uicontrol>NFS</uicontrol>,
-indiquez l'adresse <uicontrol>IP du serveur NFS</uicontrol> et le <uicontrol>Chemin NFS</uicontrol> (chemin d'accès au répertoire d'exportation).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Indique un pool basé sur une cible allouée sur un serveur iSCSI.
-Lorsque vous sélectionnez <uicontrol>iSCSI</uicontrol>, indiquez l'adresse IP du <uicontrol>Serveur iSCSI</uicontrol>
-et la <uicontrol>Cible</uicontrol> sur le serveur iSCSI. Vous avez la possibilité d'ajouter l'authentification iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logique</uicontrol></dt>
-<dd>Indique un pool de stockage de volumes logiques. Sélectionnez l'emplacement de l'unité dans <uicontrol>Chemin d'unité</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
-<dd>Indique un pool basée sur une connexion Fibre Channel SCSI. Sélectionnez l'adaptateur SCSI à utiliser.</dd>
-</dlentry></dl></li>
-<li>Cliquez sur <uicontrol>Créer</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/templates.dita b/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
deleted file mode 100644
index a517e33..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="fr-fr">
-<title>Modèles</title>
-<shortdesc>La page <wintitle>Modèles</wintitle> affiche les modèles de machine virtuelle définis
-pouvant être utilisés pour créer des hôtes KVM.</shortdesc>
-<csbody>
-<p>Pour chaque modèle, les informations suivantes sont affichées :<dl>
-<dlentry>
-<dt>SE</dt>
-<dd>Nom du système d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version du système d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>UC</dt>
-<dd>Nombre de processeurs définis pour le modèle.</dd>
-</dlentry><dlentry>
-<dt>Mémoire</dt>
-<dd>Quantité de mémoire vive à allouer, en Mo.</dd>
-</dlentry></dl></p>
-<p>Les actions suivantes peuvent être sélectionnées pour chaque modèle :<ul>
-<li>Sélectionnez <uicontrol>Editer</uicontrol> pour éditer le modèle.</li>
-<li>Sélectionnez <uicontrol>Supprimer</uicontrol> pour supprimer le modèle.</li>
-</ul>Pour ajouter un modèle, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
-dans le coin supérieur droit de l'écran.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="fr-fr">
-<title>Editer un modèle</title>
-<shortdesc>Editez un modèle existant.</shortdesc>
-<csbody>
-<p>Pour chaque modèle, les informations suivantes sont affichées : <dl>
-<dlentry>
-<dt>Nom</dt>
-<dd>Nom du modèle.</dd>
-</dlentry><dlentry>
-<dt>Fournisseur</dt>
-<dd>Nom de la société qui a créé le système d'exploitation ou la distribution
-pour lequel/laquelle le modèle est configuré.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version du système d'exploitation ou de la distribution
-pour lequel/laquelle le modèle est configuré.</dd>
-</dlentry><dlentry>
-<dt>Nombre d'UC</dt>
-<dd>Nombre de processeurs définis pour le modèle.</dd>
-</dlentry><dlentry>
-<dt>Mémoire</dt>
-<dd>Quantité de mémoire en Mo à allouer à la machine virtuelle.</dd>
-</dlentry><dlentry>
-<dt>Disque</dt>
-<dd>Taille du disque en Go.</dd>
-</dlentry><dlentry>
-<dt>CD-ROM</dt>
-<dd>chemin d'accès au fichier pour l'emplacement du fichier ISO utilisé pour l'installation de l'invité KVM.</dd>
-</dlentry><dlentry>
-<dt>Pool de stockage</dt>
-<dd>Pool de stockage spécifique ou pool de stockage par défaut.</dd>
-</dlentry><dlentry>
-<dt>Réseau</dt>
-<dd>Interfaces réseau par défaut disponibles pour l'invité KVM. Vous pouvez
-sélectionner plusieurs réseaux.</dd>
-</dlentry></dl> Les zones qui ne sont pas désactivées peuvent être éditées. Après que vous avez édité une zone, cliquez sur <uicontrol>Sauvegarder</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Ajouter un modèle</title>
-<shortdesc>Ajoutez un modèle à partir du support source.
-Vous pouvez ajouter votre propre image ISO au pool de stockage 'ISO' pour la reconnaissance suivante.</shortdesc>
-<csbody>
-<p>Sélectionnez l'emplacement du support source à partir des options suivantes :<dl>
-<dlentry>
-<dt>Image ISO locale</dt>
-<dd>Sélectionnez cette option pour rechercher dans les pools de stockage l'image d'installation ISO disponible sur le système.</dd>
-</dlentry><dlentry>
-<dt>Image ISO distante</dt>
-<dd>Sélectionnez cette option pour indiquer un emplacement distant pour une image d'installation ISO.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Ajouter un modèle - Image ISO locale</title>
-<shortdesc>Ajoutez un modèle à partir d'une image ISO locale.</shortdesc>
-<csbody>
-<p>Les images ISO disponibles sur le système sont affichées.<dl><dlentry>
-<dt>SE</dt>
-<dd>Nom du système d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version du système d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>Taille</dt>
-<dd>Taille de l'image ISO.</dd>
-</dlentry></dl></p>
-<p>Pour créer un modèle à partir d'une image ISO, choisissez parmi les options suivantes :<ul>
-<li>Sélectionnez une image ISO à partir de laquelle créer un modèle, puis cliquez sur <uicontrol>Créer des modèles à partir de l'ISO sélectionné </uicontrol>.</li>
-<li>Sélectionnez <uicontrol>Tout</uicontrol> pour créer un modèle à partir de chaque
-image ISO répertoriée, puis cliquez sur <uicontrol>Créer des modèles à partir de l'ISO sélectionné</uicontrol>.</li>
-<li>Si l'image ISO que vous souhaitez utiliser ne figure pas dans les résultats
-d'analyse, vous pouvez faire un choix parmi les options suivantes :<ul>
-<li>Sélectionnez <uicontrol>Je souhaite utiliser un fichier ISO spécifique</uicontrol> pour
-spécifier un chemin d'accès à l'image ISO.</li>
-<li>Cliquez sur <uicontrol>Rechercher d'autres images ISO</uicontrol> pour rechercher des images ISO supplémentaires.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/Makefile.am b/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
deleted file mode 100644
index 62e2f29..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-it_IT_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/it_IT
-
-dist_it_IT_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/it_IT/guests.dita b/plugins/kimchi/ui/pages/help/it_IT/guests.dita
deleted file mode 100644
index e05db7e..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/guests.dita
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="it-it">
-<title>Guest</title>
-<shortdesc>La pagina <wintitle>Guest</wintitle> elenca le macchine virtuali
-KVM definite.</shortdesc>
-<csbody>
-<p>Per ciascuna macchina guest vengono visualizzate le seguenti informazioni:<dl><dlentry>
-<dt>Nome</dt>
-<dd>Il nome della macchina virtuale.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>La percentuale di utilizzo del processore nella macchina virtuale.</dd>
-</dlentry><dlentry>
-<dt>I/O di rete</dt>
-<dd>La velocità di trasmissione dell'input/output di rete in KB al secondo.</dd>
-</dlentry><dlentry>
-<dt>I/O disco</dt>
-<dd>La velocità di trasmissione dell'input/output disco in KB al secondo.</dd>
-</dlentry><dlentry>
-<dt>Riquadro animato</dt>
-<dd>Lo stato della console del sistema operativo della macchina guest o un'icona che rappresenta la distribuzione <tm tmtype="tm" trademark="Linux">Linux</tm> se la macchina guest non è attiva.</dd>
-</dlentry></dl></p>
-<p>Per ciascuna macchina guest vengono visualizzate le icone di azioni indicate di seguito:<dl>
-<dlentry>
-<dt>Reimposta</dt>
-<dd>Fare clic qui per reimpostare la macchina guest. </dd>
-</dlentry><dlentry>
-<dt>Alimentazione (Avvia o Arresta)</dt>
-<dd>Fare clic qui per accendere o spegnere la macchina guest. Se l'icona è rossa, la macchina è spenta, se è verde è accesa.</dd>
-</dlentry></dl> </p>
-<p>Per ciascuna macchina guest è possibile selezionare le azioni indicate di seguito:<ul>
-<li>Selezionare <uicontrol>Connetti</uicontrol> per effettuare la connessione alla console remota per il sistema operativo della macchina guest.</li>
-<li>Selezionare <uicontrol>Gestisci supporti</uicontrol> per modificare il percorso al supporto di installazione.</li>
-<li>Selezionare <uicontrol>Reimposta</uicontrol> per reimpostare la macchina guest.</li>
-<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare le proprietà  di una macchina guest esistente. à possibile modificare le macchine guest solo se sono arrestate.</li>
-<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare la macchina guest.</li>
-</ul>Per creare una macchina guest, o macchina virtuale, fare clic sull'icona <uicontrol>più
-(+)</uicontrol> nella parte in alto a destra della pagina.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="it-it">
-<title>Creare una macchina virtuale</title>
-<shortdesc>Creare una macchina virtuale utilizzando un modello esistente.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Immettere il nome da utilizzare per identificare la macchina virtuale.</li>
-<li rev="rev1">Selezionare un modello. <ul>
-<li>Se il modello esiste, selezionarlo dai modelli visualizzati.</li>
-<li>Se non esiste alcun modello, fare clic su <uicontrol>Crea un modello</uicontrol> per crearne uno.</li>
-</ul></li>
-<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="it-it">
-<title>Modifica macchina guest</title>
-<shortdesc>Modificare le proprietà di una macchina virtuale esistente. Alcune proprietà possono essere
-modificate solo mentre la macchina guest è arrestata. Altre diventeranno effettive al prossimo avvio.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Per ciascuna macchina guest vengono visualizzate le seguenti informazioni sulla scheda <wintitle>Generale</wintitle>:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Il nome della macchina virtuale. (Può essere modificato solo mentre la macchina guest è arrestata)</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Il numero di processori. (Se la macchina guest è in esecuzione, la nuova quantità diventerà effettiva
-al prossimo avvio)</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>La quantità di memoria in MB. (Se la macchina guest è in esecuzione, la nuova quantità diventerà effettiva
-al prossimo avvio)</dd>
-</dlentry><dlentry>
-<dt>Icona</dt>
-<dd>L'immagine grafica che rappresenta la distribuzione Linux da visualizzare al posto dello stato corrente (Riquadro animato) quando la macchina guest non è attiva.</dd>
-</dlentry></dl></p>
-<p>Sulla scheda <wintitle>Memoria</wintitle> vengono visualizzate le seguenti informazioni.</p>
-<dl><dlentry>
-<dt>Memoria</dt>
-<dd>Visualizza l'ubicazione del file ISO utilizzato per l'installazione.</dd>
-</dlentry></dl>
-<p> I campi non disabilitati possono essere modificati. Dopo aver modificato un campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="it-it">
-<title>Aggiungere, sostituire o scollegare un dispositivo di memoria.</title>
-<shortdesc rev="rev1">à possibile aggiungere, sostituire o scollegare un dispositivo di memoria per la macchina virtuale. L'unico dispositivo supportato è CDROM. Per modificare i dispositivi di memoria, attenersi alla seguente procedura:</shortdesc>
-<csbody>
-<ol>
-<li>Nella finestra <wintitle>Modifica macchina guest</wintitle>, selezionare <wintitle>Memoria</wintitle>.</li>
-<li>Per sostituire un dispositivo di memoria, fare clic sulla prima icona con la <uicontrol>barra (/) arancione</uicontrol>. Immettere il percorso del file ISO e fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
-<li>Per scollegare un dispositivo di memoria, fare clic sulla seconda icona con il <uicontrol>trattino (-) rosso</uicontrol>. Confermare l'eliminazione facendo clic su <uicontrol>OK</uicontrol>.</li>
-<li>Per aggiungere un dispositivo di memoria, fare clic sulla terza icona con il <uicontrol>segno più (+)</uicontrol> verde. Immettere un nome dispositivo e percorso file ISO e fare clic su <uicontrol>Collega</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="it-it">
-<title>Sostituisci un CDROM della macchina virtuale</title>
-<shortdesc rev="rev1">Ã possibile sostituire il contenuto del CDROM per una macchina virtuale dopo il completamento dell'installazione.</shortdesc>
-<csbody>
-<ol>
-<li>Assicurarsi che la macchina virtuale sia avviata.</li>
-<li>Dal menu Azioni, selezionare <uicontrol>Gestisci supporti</uicontrol>.</li>
-<li>Per modificare il contenuto correntemente caricato sul CDROM, fare clic sull'icona della <uicontrol>barra (/) arancione</uicontrol> accanto al campo hdc.</li>
-<li>Sulla pagina <wintitle>Sostituisci un CDROM della macchina virtuale</wintitle>, immettere il percorso del file ISO. Gli altri due campi sono di sola lettura.</li>
-<li>Fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/host.dita b/plugins/kimchi/ui/pages/help/it_IT/host.dita
deleted file mode 100644
index 63d3367..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/host.dita
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="it-it">
-<title>Host</title>
-<shortdesc>La pagina <wintitle>Host</wintitle> visualizza le informazioni sul sistema host e consente di arrestarlo, riavviarlo e connettersi ad esso.</shortdesc>
-<csbody>
-<p>Ã possibile effettuare le seguenti operazioni sull'host:<ul>
-<li>Selezionare <uicontrol>Arresta</uicontrol> per arrestare il sistema host.</li>
-<li>Selezionare <uicontrol>Riavvia</uicontrol> per riavviare il sistema host.</li>
-<li>Selezionare <uicontrol>Connetti</uicontrol> per aprire una connessione VNC al sistema host, se non è già connesso.</li>
-</ul></p>
-<p>Fare clic sulle seguenti sezioni per visualizzare le informazioni sull'host:<dl>
-<dlentry>
-<dt>Informazioni di base</dt>
-<dd>Questa sezione visualizza il nome codice, la versione e la distribuzione del sistema operativo, come pure il tipo di processore e la quantità di memoria in GB.</dd>
-</dlentry><dlentry>
-<dt>Statistiche di sistema</dt>
-<dd>Questa sezione visualizza i grafici che mostrano le statistiche per la CPU, la memoria, l'I/O disco e di rete per l'host. Selezionare <uicontrol>Raccolta dati all'uscita dalla pagina</uicontrol> per continuare la raccolta dei dati quando la scheda host non è più visibile.</dd>
-</dlentry><dlentry>
-<dt>Aggiornamenti del software</dt>
-<dd>Questa sezione visualizza le informazioni per tutti i pacchetti per cui sono disponibili gli aggiornamenti, incluso il nome, la versione, l'architettura e il repository del pacchetto. à possibile aggiornare tutti i pacchetti elencati, selezionando <uicontrol>Aggiorna tutto</uicontrol>. Non è possibile selezionare singoli pacchetti per gli aggiornamenti.</dd>
-</dlentry><dlentry>
-<dt>Repository</dt>
-<dd>Questa sezione visualizza i repository associati al sistema host. Ã possibile aggiungere, abilitare, modificare o rimuovere i repository. L'aggiunta di un repository lo associa al sistema host, mentre l'abilitazione di un repository
-consente all'host di accedervi. Se il sistema è Red Hat Enterprise
-Linux o Fedora, è possibile aggiungere i repository <filepath>yum</filepath>.
-Se il sistema è Ubuntu o Debian, aggiungere i repository <filepath>deb</filepath>.<p>Se si stanno utilizzando i repository yum, è possibile aggiungere un controllo GPG per verificare che un pacchetto da questo repository non sia stato corrotto.
-Selezionare un repository, quindi <uicontrol>Modifica</uicontrol>. Selezionare <uicontrol>Sì</uicontrol> per abilitare il controllo GPG, quindi immettere un URL al file di chiavi GPG per il
-repository.</p></dd>
-</dlentry><dlentry>
-<dt>Report di debug</dt>
-<dd>Questa sezione visualizza i report di debug, incluso il nome e il percorso file.
-Le opzioni disponibili consentono di generare un nuovo report oppure ridenominare, rimuovere o scaricare un report esistente.<p>Il report di debug viene generato utilizzando il comando <cmdname>sosreport</cmdname>. Ã disponibile per le distribuzioni Red
-Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora e Ubuntu. Il comando genera un file .tar che contiene informazioni di diagnostica e configurazione, come la versione del kernel in esecuzione, i moduli caricati e i file di configurazione del servizio e del sistema.
-Il comando esegue anche programmi esterni per raccogliere ulteriori informazioni e memorizza l'output nell'archivio risultante.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/network.dita b/plugins/kimchi/ui/pages/help/it_IT/network.dita
deleted file mode 100644
index a396d58..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/network.dita
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="it-it">
-<title>Rete</title>
-<shortdesc>La pagina <wintitle>Rete</wintitle> visualizza le informazioni sulla connessione di rete.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nome rete</dt>
-<dd>Il nome della rete o il <uicontrol>valore predefinito</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Stato</dt>
-<dd>Lo stato della rete, attivo (verde) o non attivo (rosso). </dd>
-</dlentry><dlentry>
-<dt>Tipo di rete</dt>
-<dd>I tipo di rete, ad esempio, <uicontrol>NAT</uicontrol> (network
-address translation).</dd>
-</dlentry><dlentry>
-<dt>Interfaccia</dt>
-<dd>L'interfaccia di rete, ad esempio, <uicontrol>virbr0</uicontrol> (valore predefinito).</dd>
-</dlentry><dlentry>
-<dt>Spazio indirizzo</dt>
-<dd>L'indirizzo IP.</dd>
-</dlentry></dl></p>
-<p>Ã possibile selezionare le seguenti azioni:<ul>
-<li rev="rev1">Selezionare <uicontrol>Avvia</uicontrol> per iniziare la connessione di rete.</li>
-<li>Selezionare <uicontrol>Arresta</uicontrol> per terminare la connessione di rete.</li>
-<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare le informazioni di connessione.</li>
-</ul>Per creare una rete fare clic sull'icona <uicontrol>più
-(+)</uicontrol> nella parte in alto a destra del pannello.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="it-it">
-<title>Crea una rete</title>
-<shortdesc>Creare una rete.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Immettere il nome della rete.</li>
-<li>Fare clic per selezionare il tipo di rete. <dl rev="rev1"><dlentry>
-<dt><uicontrol>Isolata</uicontrol></dt>
-<dd>La modalità isolata. Le macchine guest non possono inviare o ricevere comunicazioni verso o da i sistemi esterni.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>La modalità NAT (Network Address Translation). La comunicazione dalle macchine guest ai sistemi esterni utilizza l'indirizzo IP host. I sistemi esterni non possono iniziare la comunicazione con le macchine guest.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Con bridge</uicontrol></dt>
-<dd>La modalità con bridge. Le macchine guest possono comunicare con i sistemi esterni ed essere contattate dai sistemi esterni come se fossero sistemi fisici sulla rete. Per la modalità con bridge, è necessario specificare informazioni aggiuntive su destinazione e VLAN.</dd>
-</dlentry></dl></li>
-<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/storage.dita b/plugins/kimchi/ui/pages/help/it_IT/storage.dita
deleted file mode 100644
index 5a9bc25..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/storage.dita
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="it-it">
-<title>Memoria</title>
-<shortdesc>La pagina <wintitle>Memoria</wintitle> elenca i pool di memoria
-disponibili, compresi i pool di memoria pronti per l'uso 'default' e 'ISO'.
-Se si desidera utilizzare un proprio ISO, aggiungerlo al percorso del pool di memoria 'ISO'.</shortdesc>
-<csbody>
-<p>Per ciascun pool di memoria vengono visualizzate le seguenti informazioni:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Il nome del pool di memoria e la percentuale utilizzata.</dd>
-</dlentry><dlentry>
-<dt>Stato</dt>
-<dd>Lo stato del pool di memoria, attivo (verde) o non attivo (rosso). </dd>
-</dlentry><dlentry>
-<dt>Ubicazione</dt>
-<dd>Il percorso file all'ubicazione del pool di memoria.</dd>
-</dlentry><dlentry>
-<dt>Tipo</dt>
-<dd>Il tipo di pool di memoria, ad esempio, <uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacità </dt>
-<dd>La quantità di spazio nel pool di memoria.</dd>
-</dlentry><dlentry>
-<dt>Assegnato</dt>
-<dd>La quantità di spazio già assegnato nel pool di memoria.</dd>
-</dlentry></dl></p>
-<p>Per ciascun pool di memoria è possibile selezionare le azioni indicate di seguito:<ul>
-<li>Selezionare <uicontrol>Attiva</uicontrol> per attivare il pool di memoria in modo da poterlo utilizzare.</li>
-<li>Selezionare <uicontrol>Disattiva</uicontrol> per disattivare un pool di memoria attivo.</li>
-<li>Selezionare <uicontrol>Rimuovi definizione</uicontrol> per rimuovere un pool di memoria non attivo.</li>
-</ul></p>
-<p>Per visualizzare i dettagli del volume di memoria per un pool di memoria, fare clic sulla freccia sul lato destro della riga del pool di memoria. I dettagli includono:<dl><dlentry>
-<dt>Tipo</dt>
-<dd>Il tipo di volume, ad esempio, <uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Formato</dt>
-<dd>Il formato, che varia in base al tipo.</dd>
-</dlentry><dlentry>
-<dt>Capacità </dt>
-<dd>La dimensione del volume di memoria.</dd>
-</dlentry><dlentry>
-<dt>Assegnazione</dt>
-<dd>La quantità di spazio già assegnato nel pool di memoria.</dd>
-</dlentry></dl>Per definire un pool di memoria fare clic sull'icona <uicontrol>più
-(+)</uicontrol> nella parte in alto a destra del pannello.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="it-it">
-<title>Definire un pool di memoria</title>
-<shortdesc> Definire un pool di memoria.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Nel campo <uicontrol>Nome pool di memoria</uicontrol>, immettere i l nome da utilizzare per definire il pool di memoria.</li>
-<li>Nell'elenco <uicontrol>Tipo pool di memoria</uicontrol>, selezionare il tipo: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Specifica un pool directory. Quando si seleziona <uicontrol>DIR</uicontrol>,
-immettere il <uicontrol>Percorso di memoria</uicontrol> (percorso file al pool di memoria).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Specifica un pool NFS (Network File System). Quando si seleziona <uicontrol>NFS</uicontrol>,
-immettere l'indirizzo <uicontrol>IP del server NFS</uicontrol> e il <uicontrol>Percorso NFS</uicontrol> (percorso alla directory esportata).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Specifica un pool basato su una destinazione assegnata su un server iSCSI.
-Quando si seleziona <uicontrol>iSCSI</uicontrol>, immettere l'indirizzo IP del <uicontrol>Server iSCSI</uicontrol> e la <uicontrol>Destinazione</uicontrol> sul server iSCSI. Ã possibile, facoltativamente, selezionare di aggiungere l'autenticazione iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logico</uicontrol></dt>
-<dd>Specifica un pool di memoria di tipo volume logico. Selezionare l'ubicazione del dispositivo in <uicontrol>Percorso dispositivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Canale a fibre ottiche SCSI</uicontrol></dt>
-<dd>Specifica un pool basato su un canale a fibre ottiche SCSI. Selezionare quale adattatore
-SCSI utilizzare.</dd>
-</dlentry></dl></li>
-<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/templates.dita b/plugins/kimchi/ui/pages/help/it_IT/templates.dita
deleted file mode 100644
index 9b84b16..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/templates.dita
+++ /dev/null
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="it-it">
-<title>Modelli</title>
-<shortdesc>La pagina <wintitle>Modelli</wintitle> visualizza i modelli di macchina virtuale definiti che è possibile utilizzare per creare macchine guest KVM.</shortdesc>
-<csbody>
-<p>Per ciascun modello vengono visualizzate le seguenti informazioni:<dl>
-<dlentry>
-<dt>SO</dt>
-<dd>Il nome del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>Versione</dt>
-<dd>La versione del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Il numero di processori definiti per il modello.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>La quantità di memoria ad accesso casuale da assegnare, in MB.</dd>
-</dlentry></dl></p>
-<p>Per ciascun modello è possibile selezionare le azioni indicate di seguito:<ul>
-<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare il modello.</li>
-<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare il modello.</li>
-</ul>Per aggiungere un modello fare clic sull'icona <uicontrol>più
-(+)</uicontrol> nella parte in alto a destra del pannello.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="it-it">
-<title>Modifica modello</title>
-<shortdesc>Modificare un modello esistente.</shortdesc>
-<csbody>
-<p>Per ciascun modello vengono visualizzate le seguenti informazioni: <dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Il nome del modello.</dd>
-</dlentry><dlentry>
-<dt>Fornitore</dt>
-<dd>Il nome della società che ha creato il sistema operativo o la distribuzione per il cui utilizzo è configurato il modello.</dd>
-</dlentry><dlentry>
-<dt>Versione</dt>
-<dd>La versione del sistema operativo o della distribuzione per il cui utilizzo è configurato il modello.</dd>
-</dlentry><dlentry>
-<dt>Numero CPU</dt>
-<dd>Il numero di processori definiti per il modello.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>La quantità di memoria in MB da assegnare alla macchina virtuale.</dd>
-</dlentry><dlentry>
-<dt>Disco</dt>
-<dd>La dimensione del disco in GB.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>Il percorso file all'ubicazione del file ISO utilizzato per installare la macchina guest
-KVM.</dd>
-</dlentry><dlentry>
-<dt>Pool di memoria</dt>
-<dd>Un pool di memoria specifico o quello predefinito.</dd>
-</dlentry><dlentry>
-<dt>Rete</dt>
-<dd>Le interfacce di rete predefinite disponibili per la macchina guest KVM. à possibile selezionare più reti.</dd>
-</dlentry></dl> I campi non disabilitati possono essere modificati. Dopo aver modificato un campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Aggiungi modello</title>
-<shortdesc>Aggiungere un modello dal supporto di origine.
-Ã possibile aggiungere una propria immagine ISO al pool di memoria 'ISO' per la seguente individuazione.</shortdesc>
-<csbody>
-<p>Selezionare l'ubicazione del supporto di origine dalle seguenti opzioni:<dl>
-<dlentry>
-<dt>Immagine ISO locale</dt>
-<dd>Selezionare questa opzione per eseguire la scansione dei pool di memoria alla ricerca di immagini ISO di installazione disponibili sul sistema.</dd>
-</dlentry><dlentry>
-<dt>Immagine ISO remota</dt>
-<dd>Selezionare questa opzione per specificare un'ubicazione remota per un'immagine ISO di installazione.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Aggiungi modello - Immagine ISO locale</title>
-<shortdesc>Aggiungere un modello da un'immagine ISO locale.</shortdesc>
-<csbody>
-<p>Vengono visualizzate le immagini ISO disponibili sul sistema.<dl><dlentry>
-<dt>SO</dt>
-<dd>Il nome del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>Versione</dt>
-<dd>La versione del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>Dimensione</dt>
-<dd>La dimensione dell'immagine ISO.</dd>
-</dlentry></dl></p>
-<p>Per creare un modello da un'immagine ISO scegliere tra le seguenti opzioni:<ul>
-<li>Selezionare un'immagine ISO da cui creare un modello, quindi fare clic su <uicontrol>Crea modelli da ISO selezionato</uicontrol>.</li>
-<li>Selezionare <uicontrol>Tutti</uicontrol> per creare un modello da ciascuna immagine ISO elencata, quindi fare clic su <uicontrol>Crea modelli da ISO selezionato</uicontrol>.</li>
-<li>Se nei risultati della scansione non viene visualizzata l'immagine ISO che si desidera utilizzare, è possibile selezionare dalle seguenti opzioni:<ul>
-<li>Selezionare <uicontrol>Utilizzare un file ISO specifico</uicontrol> per specificare un percorso all'immagine ISO.</li>
-<li>Fare clic su <uicontrol>Ricerca più ISO</uicontrol> per ricercare più immagini
-ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am b/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
deleted file mode 100644
index f9c2f33..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-ja_JP_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ja_JP
-
-dist_ja_JP_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/guests.dita b/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
deleted file mode 100644
index 5dade49..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
+++ /dev/null
@@ -1,172 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="ja-jp">
-<title>ã²ã¹ã</title>
-<shortdesc><wintitle>ãã²ã¹ãã</wintitle>ãã¼ã¸ã«ã¯ãå®ç¾©æ¸ã¿ KVM ä»®æ³ãã·ã³ããªã¹ãããã¾ãã
-</shortdesc>
-<csbody>
-<p>ã²ã¹ããã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
-<dl><dlentry>
-<dt>åå</dt>
-<dd>ä»®æ³ãã·ã³ã®ååã
-</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>ä»®æ³ãã·ã³ã«ãããããã»ããµã¼ä½¿ç¨çã
-</dd>
-</dlentry><dlentry>
-<dt>ãããã¯ã¼ã¯å
¥åºå</dt>
-<dd>ãããã¯ã¼ã¯å
¥åºåã®é度 (KB/ç§)ã
-</dd>
-</dlentry><dlentry>
-<dt>ãã£ã¹ã¯å
¥åºå</dt>
-<dd>ãã£ã¹ã¯å
¥åºåã®é度 (KB/ç§)ã
-</dd>
-</dlentry><dlentry>
-<dt>ã©ã¤ãã¿ã¤ã«</dt>
-<dd>ã²ã¹ãã»ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã»ã³ã³ã½ã¼ã«ã®ç¶æ
ãã¾ãã¯ã²ã¹ããã¢ã¯ãã£ãã§ã¯ãªãå ´åã<tm tmtype="tm" trademark="Linux">Linux</tm>
-ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã表ãã¢ã¤ã³ã³ã
-</dd>
-</dlentry></dl></p>
-<p>ã²ã¹ããã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã»ã¢ã¤ã³ã³ã表示ããã¾ãã
-<dl>
-<dlentry>
-<dt>ãªã»ãã</dt>
-<dd>ã¯ãªãã¯ãã¦ã²ã¹ãããªã»ãããã¾ãã
-</dd>
-</dlentry><dlentry>
-<dt>黿º (éå§ã¾ãã¯åæ¢)</dt>
-<dd>ã¯ãªãã¯ãã¦ã²ã¹ãã®é»æºããªã³ã¾ãã¯ãªãã«ãã¾ãã
-ãã®ã¢ã¤ã³ã³ã赤ã§ããã°é»æºã¯ãªãã«ãªã£ã¦ãã¾ããç·ã§ããã°ãªã³ã«ãªã£ã¦ãã¾ãã
-</dd>
-</dlentry></dl> </p>
-<p>ã²ã¹ããã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
-<ul>
-<li>ã²ã¹ãã»ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã®ãªã¢ã¼ãã»ã³ã³ã½ã¼ã«ã«æ¥ç¶ããã«ã¯ã<uicontrol>ãæ¥ç¶ã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ã¤ã³ã¹ãã¼ã«ã»ã¡ãã£ã¢ã®ãã¹ã夿´ããã«ã¯ã<uicontrol>ãã¡ãã£ã¢ã®ç®¡çã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ã²ã¹ãããªã»ããããã«ã¯<uicontrol>ããªã»ããã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>æ¢åã®ã²ã¹ãã®ããããã£ã¼ãç·¨éããã«ã¯ã<uicontrol>ãç·¨éã</uicontrol>ã鏿ãã¾ãã
-ã²ã¹ãã¯ã忢ãã¦ããéã®ã¿ç·¨éã§ãã¾ãã
-</li>
-<li>ã²ã¹ããåé¤ããã«ã¯<uicontrol>ãåé¤ã</uicontrol>ã鏿ãã¾ãã
-</li>
-</ul>ã²ã¹ã (ä»®æ³ãã·ã³) ã使ããã«ã¯ããã¼ã¸ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
-</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="ja-jp">
-<title>ä»®æ³ãã·ã³ã®ä½æ</title>
-<shortdesc>æ¢åã®ãã³ãã¬ã¼ããç·¨éãããã¨ã«ãã£ã¦ãä»®æ³ãã·ã³ã使ãã¾ãã
-</shortdesc>
-<csbody>
-<p> <ol>
-<li>ä»®æ³ãã·ã³ãèå¥ããããã®ååãå
¥åãã¾ãã
-</li>
-<li rev="rev1">ãã³ãã¬ã¼ãã鏿ãã¾ãã
-<ul>
-<li>ãã³ãã¬ã¼ããåå¨ããå ´åã表示ããããã³ãã¬ã¼ããã鏿ãã¦ãã ããã
-</li>
-<li>ãã³ãã¬ã¼ããåå¨ããªãå ´åã¯ã<uicontrol>ããã³ãã¬ã¼ãã®ä½æã</uicontrol>ãã¯ãªãã¯ãã¦ãã³ãã¬ã¼ãã使ãã¾ãã
-</li>
-</ul></li>
-<li><uicontrol>ã使ã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
-</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="ja-jp">
-<title>ã²ã¹ãã®ç·¨é</title>
-<shortdesc>æ¢åã®ä»®æ³ãã·ã³ã®ããããã£ã¼ãç·¨éãã¾ãã
-ä¸é¨ã®ããããã£ã¼ã¯ãã²ã¹ãã忢ãã¦ããéã«éãç·¨éå¯è½ã§ãã
-ããã¨ã¯å¥ã«ã次ã®ãã¼ãã§æå¹ã«ãªãããããã£ã¼ãããã¾ãã</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>ã²ã¹ããã¨ã«ã以ä¸ã®æ
å ±ã<wintitle>ãä¸è¬ã</wintitle>ã¿ãã«è¡¨ç¤ºããã¾ãã
-<dl>
-<dlentry>
-<dt>åå</dt>
-<dd>ä»®æ³ãã·ã³ã®ååã
-(ã²ã¹ãã忢ãã¦ããéã«éãç·¨éå¯è½)</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>ããã»ããµã¼ã®æ°ã
-(ã²ã¹ãã稼åãã¦ããå ´åãæ°è¦ã®æ°ã¯æ¬¡ã®ãã¼ãã§æå¹ã«ãªã)</dd>
-</dlentry><dlentry>
-<dt>ã¡ã¢ãªã¼</dt>
-<dd>ã¡ã¢ãªã¼ã®é (MB åä½)ã
-(ã²ã¹ãã稼åãã¦ããå ´åãæ°è¦ã®éã¯æ¬¡ã®ãã¼ãã§æå¹ã«ãªã)</dd>
-</dlentry><dlentry>
-<dt>ã¢ã¤ã³ã³</dt>
-<dd>ã²ã¹ããã¢ã¯ãã£ãã§ã¯ãªãå ´åã«ç¾å¨ã®ç¶æ³ (ã©ã¤ãã¿ã¤ã«) ã¨ãã¦è¡¨ç¤ºããããLinux ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã表ãã°ã©ãã£ãã¯ã»ã¤ã¡ã¼ã¸ã
-</dd>
-</dlentry></dl></p>
-<p>æ¬¡ã®æ
å ±ã<wintitle>ãã¹ãã¬ã¼ã¸ã</wintitle>ã¿ãã«è¡¨ç¤ºããã¾ãã
-</p>
-<dl><dlentry>
-<dt>ã¹ãã¬ã¼ã¸</dt>
-<dd>ã¤ã³ã¹ãã¼ã«ã«ä½¿ç¨ããã ISO ãã¡ã¤ã«ã®ãã±ã¼ã·ã§ã³ã表示ãã¾ãã
-</dd>
-</dlentry></dl>
-<p> 使ç¨ä¸å¯ã«ãªã£ã¦ããªããã£ã¼ã«ããç·¨éã§ãã¾ãã
-ãã£ã¼ã«ããç·¨éããå¾ã<uicontrol>ãä¿åã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
-</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="ja-jp">
-<title>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã®è¿½å ã交æãã¾ãã¯åãé¢ã</title>
-<shortdesc rev="rev1">ä»®æ³ãã·ã³ã«ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã追å ãããã¤ã¹ã交æãã¾ãã¯ä»®æ³ãã·ã³ããåãé¢ããã¨ãã§ãã¾ãã
-ãµãã¼ãããã¦ããããã¤ã¹ã¯ CDROM ã ãã§ãã
-ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãç·¨éããã«ã¯ã以ä¸ã®æé ã«å¾ã£ã¦ãã ããã
-</shortdesc>
-<csbody>
-<ol>
-<li><wintitle>ãã²ã¹ãã®ç·¨éã</wintitle>ã¦ã£ã³ãã¦ã§<wintitle>ãã¹ãã¬ã¼ã¸ã</wintitle>ã鏿ãã¾ãã
-</li>
-<li>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã交æããã«ã¯ã<uicontrol>ãªã¬ã³ã¸ã®ã¹ã©ãã·ã¥ (/)</uicontrol> ãä»ããæåã®ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
-ISO ãã¡ã¤ã«ã»ãã¹ãå
¥åãã<uicontrol>ã交æã</uicontrol>ãã¯ãªãã¯ãã¾ãã
-</li>
-<li>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãåãé¢ãã«ã¯ã<uicontrol>赤ãããã·ã¥ (-)</uicontrol> ãä»ãã 2 çªç®ã®ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
-åé¤ã確èªãã¦<uicontrol>ãOKã</uicontrol>ãã¯ãªãã¯ãã¾ãã
-</li>
-<li>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã追å ããã«ã¯ã<uicontrol>ç·ã®æ£ç¬¦å· (+)</uicontrol> ãä»ãã 3 çªç®ã®ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
-ããã¤ã¹å㨠ISO ãã¡ã¤ã«ã»ãã¹ãå
¥åãã<uicontrol>ãæ¥ç¶ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
-</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="ja-jp">
-<title>VM ã® CDROM ã交æ</title>
-<shortdesc rev="rev1">ã¤ã³ã¹ãã¼ã«ãå®äºããå¾ã§ãä»®æ³ãã·ã³ã® CDROM ã®å
容ã交æãããã¨ãã§ãã¾ãã
-</shortdesc>
-<csbody>
-<ol>
-<li>ä»®æ³ãã·ã³ãå§åãã¦ãããã¨ã確èªãã¾ãã
-</li>
-<li>ãã¢ã¯ã·ã§ã³ãã¡ãã¥ã¼ãã<uicontrol>ãã¡ãã£ã¢ã®ç®¡çã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>CDROM ã«ãã¼ãããã¦ããå
容ã夿´ããã«ã¯ãhdc ãã£ã¼ã«ãã®æ¨ªã«ãã<uicontrol>ãªã¬ã³ã¸ã®ã¹ã©ãã·ã¥ (/)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¾ãã
-</li>
-<li><wintitle>ãVM ã® CDROM ã交æã</wintitle>ãã¼ã¸ã§ãISO ãã¡ã¤ã«ã»ãã¹ãå
¥åãã¾ãã
-ãã以å¤ã® 2 ã¤ã®ãã£ã¼ã«ãã¯èªã¿åãå°ç¨ã§ãã
-</li>
-<li><uicontrol>ã交æã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
-</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/host.dita b/plugins/kimchi/ui/pages/help/ja_JP/host.dita
deleted file mode 100644
index 3a0141c..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/host.dita
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="ja-jp">
-<title>ãã¹ã</title>
-<shortdesc><wintitle>ããã¹ãã</wintitle>ãã¼ã¸ã«ã¯ããã¹ãã»ã·ã¹ãã ã«é¢ããæ
å ±ã表示ããã¾ããããã§ããã¹ããã·ã£ãããã¦ã³ãåå§åãã¾ããã¹ãã«æ¥ç¶ãããã¨ãã§ãã¾ãã
-</shortdesc>
-<csbody>
-<p>以ä¸ã®ã¢ã¯ã·ã§ã³ããã¹ãã«å¯¾ãã¦å®è¡ã§ãã¾ãã
-<ul>
-<li>ãã¹ãã»ã·ã¹ãã ãã·ã£ãããã¦ã³ããã«ã¯<uicontrol>ãã·ã£ãããã¦ã³ã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ãã¹ãã»ã·ã¹ãã ãåå§åããã«ã¯<uicontrol>ãåå§åã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ãã¹ãã»ã·ã¹ãã ã¸ã® VNC æ¥ç¶ã (ã¾ã æ¥ç¶ããã¦ããªãå ´åã«) ãªã¼ãã³ããã«ã¯ã<uicontrol>ãæ¥ç¶ã</uicontrol>ã鏿ãã¾ãã
-</li>
-</ul></p>
-<p>ãã¹ãã«é¢ããæ
å ±ã表示ããã«ã¯ã以ä¸ã®é¸æé
ç®ãã¯ãªãã¯ãã¦ãã ããã
-<dl>
-<dlentry>
-<dt>åºæ¬æ
å ±</dt>
-<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããã¹ãã»ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã®ãã£ã¹ããªãã¥ã¼ã·ã§ã³ããã¼ã¸ã§ã³ãããã³ã³ã¼ãåãããã«ããã»ããµã¼ã»ã¿ã¤ãã¨ã¡ã¢ãªã¼ã®é (GB åä½) ã表示ããã¾ãã
-</dd>
-</dlentry><dlentry>
-<dt>ã·ã¹ãã çµ±è¨æ
å ±</dt>
-<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããã¹ãã® CPUãã¡ã¢ãªã¼ããã£ã¹ã¯å
¥åºåãããã³ãããã¯ã¼ã¯å
¥åºåã®çµ±è¨æ
å ±ã表ãã°ã©ãã表示ããã¾ãã
-ãã¹ãã»ã¿ããéããã¨ãã«ãã¼ã¿ã®åéãç¶è¡ããã«ã¯ã<uicontrol>ããã®ãã¼ã¸ãéããå¾ããã¼ã¿ãåéããã</uicontrol>ã鏿ãã¦ãã ããã
-</dd>
-</dlentry><dlentry>
-<dt>ã½ããã¦ã§ã¢æ´æ°</dt>
-<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ãæ´æ°ãç¨æããã¦ããããã±ã¼ã¸ãã¹ã¦ã®æ
å ±
-(ããã±ã¼ã¸åããã¼ã¸ã§ã³ãã¢ã¼ããã¯ãã£ã¼ããªãã¸ããªã¼ãªã©) ã表示ããã¾ãã
-<uicontrol>ããã¹ã¦æ´æ°ã</uicontrol>ã鏿ããã¨ããªã¹ãããã¦ããããã±ã¼ã¸ãã¹ã¦ãæ´æ°ã§ãã¾ãã
-æ´æ°ãã対象ã¨ãã¦åå¥ã®ããã±ã¼ã¸ã鏿ãããã¨ã¯ã§ãã¾ããã
-</dd>
-</dlentry><dlentry>
-<dt>ãªãã¸ããªã¼</dt>
-<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããã¹ãã»ã·ã¹ãã ã«é¢é£ä»ãããã¦ãããªãã¸ããªã¼ã表示ããã¾ãã
-ãªãã¸ããªã¼ã追å ãããæå¹ã«ãããç·¨éãããã¾ãã¯åé¤ãããã¨ãã§ãã¾ãã
-ãªãã¸ããªã¼ã追å ããã¨ããã®ãªãã¸ããªã¼ããã¹ãã»ã·ã¹ãã ã«é¢é£ä»ãããããªãã¸ããªã¼ãæå¹ã«ããã¨ããã®ãªãã¸ããªã¼ã«ãã¹ããã¢ã¯ã»ã¹ã§ããããã«ãªãã¾ãã
-ã·ã¹ãã ã Red Hat Enterprise Linux ã¾ã㯠Fedora ã§ããã°ã<filepath>yum</filepath> ãªãã¸ããªã¼ã追å ã§ãã¾ãã
-ã·ã¹ãã ã Ubuntu ã¾ã㯠Debian ã§ããã°ã<filepath>deb</filepath> ãªãã¸ããªã¼ã追å ãã¦ãã ããã
-<p>yum ãªãã¸ããªã¼ãæä½ãã¦ããå ´åããã®ãªãã¸ããªã¼ã«å
¥ã£ã¦ããããã±ã¼ã¸ãå£ãã¦ããªããã¨ã確èªãããããGPG ãã§ãã¯ã追å ã§ãã¾ãã
-ãªãã¸ããªã¼ã鏿ãã<uicontrol>ãç·¨éã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
-<uicontrol>ãã¯ãã</uicontrol>ã鏿ã㦠GPG ãã§ãã¯ãæå¹ã«ãã¦ããããã®ãªãã¸ããªã¼ã® GPG éµãã¡ã¤ã«ã® URL ãå
¥åãã¦ãã ããã
-</p></dd>
-</dlentry><dlentry>
-<dt>ãããã°ã»ã¬ãã¼ã</dt>
-<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããããã°ã»ã¬ãã¼ã (ååããã¡ã¤ã«ã»ãã¹ãªã©) ã表示ããã¾ãã
-æ°ããã¬ãã¼ããçæãæ¢åã®ã¬ãã¼ããåå夿´ãåé¤ãã¾ãã¯ãã¦ã³ãã¼ãããããã®ãªãã·ã§ã³ã鏿ã§ãã¾ãã
-<p>ãããã°ã»ã¬ãã¼ãã¯ã<cmdname>sosreport</cmdname> ã³ãã³ãã§çæããã¾ãã
-ããã¯ãRed Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>ãFedoraãããã³ Ubuntu ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã«ç¨æããã¦ãã¾ãã
-ãã®ã³ãã³ãã¯ãæ§æããã³è¨ºææ
å ± (稼åä¸ã®ã«ã¼ãã«ã®ãã¼ã¸ã§ã³ããã¼ãããã¦ããã¢ã¸ã¥ã¼ã«ãã·ã¹ãã ããã³ãµã¼ãã¹æ§æãã¡ã¤ã«ãªã©) ãå
¥ã£ã .tar ãã¡ã¤ã«ãçæãã¾ãã
-ãã®ã³ãã³ãã¯ã¾ããå¤é¨ããã°ã©ã ãå®è¡ãã¦æ
å ±ãããã«åéãããã®åºåãçµæã®ã¢ã¼ã«ã¤ãã«ä¿ç®¡ãã¾ãã
-</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 227 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/network.dita b/plugins/kimchi/ui/pages/help/ja_JP/network.dita
deleted file mode 100644
index 5d9ce05..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/network.dita
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="ja-jp">
-<title> ãããã¯ã¼ã¯</title>
-<shortdesc><wintitle>ããããã¯ã¼ã¯ã</wintitle>ãã¼ã¸ã«ã¯ããããã¯ã¼ã¯æ¥ç¶ã«é¢ããæ
å ±ã表示ããã¾ãã
-</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>ãããã¯ã¼ã¯å</dt>
-<dd>ãããã¯ã¼ã¯ã®åå (ã¾ã㯠<uicontrol>default</uicontrol>) ã§ãã
-</dd>
-</dlentry><dlentry>
-<dt>ç¶æ
</dt>
-<dd>ãããã¯ã¼ã¯ã®ç¶æ
ã§ãã¢ã¯ãã£ã (ç·) ã¾ãã¯éã¢ã¯ãã£ã (赤) ã§ãã
-</dd>
-</dlentry><dlentry>
-<dt>ãããã¯ã¼ã¯ã»ã¿ã¤ã</dt>
-<dd>ãããã¯ã¼ã¯ã»ã¿ã¤ãã§ãä¾ãã° <uicontrol>NAT</uicontrol> (ãããã¯ã¼ã¯ã»ã¢ãã¬ã¹å¤æ) ã§ãã
-</dd>
-</dlentry><dlentry>
-<dt>ã¤ã³ã¿ã¼ãã§ã¼ã¹</dt>
-<dd>ãããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã§ãä¾ãã° <uicontrol>virbr0</uicontrol> (ããã©ã«ã) ã§ãã
-</dd>
-</dlentry><dlentry>
-<dt>ã¢ãã¬ã¹ã»ã¹ãã¼ã¹</dt>
-<dd>IP ã¢ãã¬ã¹ã</dd>
-</dlentry></dl></p>
-<p>以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
-<ul>
-<li rev="rev1">ãããã¯ã¼ã¯æ¥ç¶ãéå§ããã«ã¯<uicontrol>ãéå§ã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ãããã¯ã¼ã¯æ¥ç¶ãçµäºããã«ã¯<uicontrol>ã忢ã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>æ¥ç¶æ
å ±ãåé¤ããã«ã¯<uicontrol>ãåé¤ã</uicontrol>ã鏿ãã¾ãã
-</li>
-</ul>ãããã¯ã¼ã¯ã使ããã«ã¯ã表示ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
-</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="ja-jp">
-<title>ãããã¯ã¼ã¯ã®ä½æ</title>
-<shortdesc>ãããã¯ã¼ã¯ã使ãã¾ãã
-</shortdesc>
-<csbody>
-<p> <ol>
-<li>ãããã¯ã¼ã¯ã®ååãå
¥åãã¾ãã
-</li>
-<li>ã¯ãªãã¯ãã¦ãããã¯ã¼ã¯ã»ã¿ã¤ãã鏿ãã¾ãã
-<dl rev="rev1"><dlentry>
-<dt><uicontrol>éé¢</uicontrol></dt>
-<dd>éé¢ã¢ã¼ãã
-ã²ã¹ãã¯ãå¤é¨ã·ã¹ãã ã¨ã®éã®éä¿¡ãè¡ããã¨ãã§ãã¾ããã
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>ãããã¯ã¼ã¯ã»ã¢ãã¬ã¹å¤æã¢ã¼ãã
-ã²ã¹ãããå¤é¨ã·ã¹ãã ã¸ã®éä¿¡ã«ããã¹ã IP ã¢ãã¬ã¹ã使ç¨ããã¾ãã
-å¤é¨ã·ã¹ãã ã¯ãã²ã¹ãã¸ã®éä¿¡ãéå§ã§ãã¾ããã
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>ããªãã¸</uicontrol></dt>
-<dd>ããªãã¸ã»ã¢ã¼ãã
-ã²ã¹ãã¯å¤é¨ã·ã¹ãã ã¨ã®éä¿¡ãè¡ããã¨ãã§ãããããã¯ã¼ã¯ä¸ã®ç©çã·ã¹ãã ã§ãããã®ããã«å¤é¨ã·ã¹ãã ããæ¥ç¶ã§ãã¾ãã
-ããªãã¸ã»ã¢ã¼ãã§ã¯ãå®å
ããã³ VLAN æ
å ±ãããã«æå®ããå¿
è¦ãããã¾ãã
-</dd>
-</dlentry></dl></li>
-<li><uicontrol>ã使ã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
-</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/storage.dita b/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
deleted file mode 100644
index f975e7a..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="ja-jp">
-<title>ã¹ãã¬ã¼ã¸</title>
-<shortdesc><wintitle>ãã¹ãã¬ã¼ã¸ã</wintitle>ãã¼ã¸ã«ã¯ã使ç¨å¯è½ãª
-ã¹ãã¬ã¼ã¸ã»ãã¼ã« (å³æä½¿ç¨å¯è½ãªãdefaultãã¹ãã¬ã¼ã¸ã»ãã¼ã«ããISOãã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå«ã) ããªã¹ãããã¾ãã
-ç¬èªã® ISO ã使ç¨ããå ´åã¯ãããããISOãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ã«è¿½å ãã¦ãã ããã</shortdesc>
-<csbody>
-<p>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
-<dl>
-<dlentry>
-<dt>åå</dt>
-<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ååããã³ä½¿ç¨çã
-</dd>
-</dlentry><dlentry>
-<dt>ç¶æ
</dt>
-<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ç¶æ
ã§ãã¢ã¯ãã£ã (ç·) ã¾ãã¯éã¢ã¯ãã£ã (赤) ã§ãã
-</dd>
-</dlentry><dlentry>
-<dt>ãã±ã¼ã·ã§ã³</dt>
-<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ãã±ã¼ã·ã§ã³ã®ãã¡ã¤ã«ã»ãã¹ã
-</dd>
-</dlentry><dlentry>
-<dt>ã¿ã¤ã</dt>
-<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ã¿ã¤ãã§ãä¾ãã° <uicontrol>dir</uicontrol> ã§ãã
-</dd>
-</dlentry><dlentry>
-<dt>容é</dt>
-<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«ãããã¹ãã¼ã¹ã®éã
-</dd>
-</dlentry><dlentry>
-<dt>å²ãå½ã¦æ¸ã¿</dt>
-<dd>æ¢ã«ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«å²ãå½ã¦ããã¦ããã¹ãã¼ã¹ã®éã
-</dd>
-</dlentry></dl></p>
-<p>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
-<ul>
-<li>使ç¨ã§ããããã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¢ã¯ãã£ãã«ããã«ã¯ã<uicontrol>ãã¢ã¯ãã£ãã«ããã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ã¢ã¯ãã£ãã»ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãéã¢ã¯ãã£ãã«ããã«ã¯ã<uicontrol>ãéã¢ã¯ãã£ãã«ããã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>éã¢ã¯ãã£ãã»ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãåé¤ããã«ã¯ã<uicontrol>ãå®ç¾©ãè§£é¤ããã</uicontrol>ã鏿ãã¾ãã
-</li>
-</ul></p>
-<p>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã 詳細ã表示ããã«ã¯ãã¹ãã¬ã¼ã¸ã»ãã¼ã«è¡ã®å³å´ã«ããç¢å°ãã¯ãªãã¯ãã¦ãã ããã
-詳細ã¯ä»¥ä¸ã®ã¨ããã§ãã
-<dl><dlentry>
-<dt>ã¿ã¤ã</dt>
-<dd>ããªã¥ã¼ã ã®ã¿ã¤ãã§ãä¾ãã° <uicontrol>file</uicontrol> ã§ãã
-</dd>
-</dlentry><dlentry>
-<dt>ãã©ã¼ããã</dt>
-<dd>ã¿ã¤ãã«ãã£ã¦ç°ãªããã©ã¼ãããã
-</dd>
-</dlentry><dlentry>
-<dt>容é</dt>
-<dd>ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ã®ãµã¤ãºã
-</dd>
-</dlentry><dlentry>
-<dt>å²ãæ¯ã</dt>
-<dd>æ¢ã«ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«å²ãå½ã¦ããã¦ããã¹ãã¼ã¹ã®éã
-</dd>
-</dlentry></dl>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå®ç¾©ããã«ã¯ã表示ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
-</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="ja-jp">
-<title>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®å®ç¾©</title>
-<shortdesc> ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå®ç¾©ãã¾ãã
-</shortdesc>
-<csbody>
-<p> <ol>
-<li><uicontrol>ãã¹ãã¬ã¼ã¸ã»ãã¼ã«åã</uicontrol>ãã£ã¼ã«ãã«ãã¹ãã¬ã¼ã¸ã»ãã¼ã«ãèå¥ããããã®ååãå
¥åãã¾ãã
-</li>
-<li><uicontrol>ãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ã¿ã¤ãã</uicontrol>ãªã¹ãããã以ä¸ã®ã¿ã¤ãã鏿ãã¾ãã
-<dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>ãã£ã¬ã¯ããªã¼ã»ãã¼ã«ãæå®ãã¾ãã
-<uicontrol>DIR</uicontrol> ã鏿ããå ´åã<uicontrol>ã¹ãã¬ã¼ã¸ã»ãã¹</uicontrol> (ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ãã¡ã¤ã«ã»ãã¹) ãå
¥åãã¦ãã ããã
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>ãããã¯ã¼ã¯ã»ãã¡ã¤ã«ã·ã¹ãã ã»ãã¼ã«ãæå®ãã¾ãã
-<uicontrol>NFS</uicontrol> ã鏿ããå ´åã<uicontrol>NFS ãµã¼ãã¼ IP</uicontrol> ã¢ãã¬ã¹ããã³ <uicontrol>NFS ãã¹</uicontrol>
-(ã¨ã¯ã¹ãã¼ãããããã£ã¬ã¯ããªã¼ã®ãã¹) ãå
¥åãã¦ãã ããã
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>iSCSI ãµã¼ãã¼ã«å²ãå½ã¦ããã¦ããã¿ã¼ã²ããã«åºã¥ãã¦ããã¼ã«ãæå®ãã¾ãã
-<uicontrol>iSCSI</uicontrol> ã鏿ããå ´åã<uicontrol>iSCSI ãµã¼ãã¼</uicontrol> IP ã¢ãã¬ã¹ã¨ããã® iSCSI ãµã¼ãã¼ä¸ã®<uicontrol>ã¿ã¼ã²ãã</uicontrol>ãå
¥åãã¦ãã ããã
-å¿
è¦ã«å¿ãã¦ãiSCSI èªè¨¼ã追å ãããã鏿ã§ãã¾ãã
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>è«ç</uicontrol></dt>
-<dd>è«çããªã¥ã¼ã ã»ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãæå®ãã¾ãã
-ããã¤ã¹ã®ãã±ã¼ã·ã§ã³ã<uicontrol>ãããã¤ã¹ã»ãã¹ã</uicontrol>ã§é¸æãã¦ãã ããã
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI ãã¡ã¤ãã¼ã»ãã£ãã«</uicontrol></dt>
-<dd>SCSI ãã¡ã¤ãã¼ã»ãã£ãã«ã«åºã¥ãã¦ãã¼ã«ã鏿ãã¾ãã
-使ç¨ãã SCSI ã¢ããã¿ã¼ã鏿ãã¦ãã ããã
-</dd>
-</dlentry></dl></li>
-<li><uicontrol>ã使ã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
-</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/templates.dita b/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
deleted file mode 100644
index 24dc2ab..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
+++ /dev/null
@@ -1,150 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="ja-jp">
-<title>ãã³ãã¬ã¼ã</title>
-<shortdesc><wintitle>ããã³ãã¬ã¼ãã</wintitle>ãã¼ã¸ã«ã¯ãKVM ã²ã¹ãã使ããããã«ä½¿ç¨ã§ãããå®ç¾©æ¸ã¿ä»®æ³ãã·ã³ã»ãã³ãã¬ã¼ãã表示ããã¾ãã
-</shortdesc>
-<csbody>
-<p>ãã³ãã¬ã¼ããã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
-<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ååã
-</dd>
-</dlentry><dlentry>
-<dt>ãã¼ã¸ã§ã³</dt>
-<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ã
-</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>ãã³ãã¬ã¼ãã«å®ç¾©ããã¦ããããã»ããµã¼ã®æ°ã
-</dd>
-</dlentry><dlentry>
-<dt>ã¡ã¢ãªã¼</dt>
-<dd>å²ãå½ã¦ãããã©ã³ãã ã»ã¢ã¯ã»ã¹ã»ã¡ã¢ãªã¼ã®é (MB åä½)ã
-</dd>
-</dlentry></dl></p>
-<p>ãã³ãã¬ã¼ããã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
-<ul>
-<li>ãã³ãã¬ã¼ããç·¨éããã«ã¯<uicontrol>ãç·¨éã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ãã³ãã¬ã¼ããåé¤ããã«ã¯<uicontrol>ãåé¤ã</uicontrol>ã鏿ãã¾ãã
-</li>
-</ul>ãã³ãã¬ã¼ãã追å ããã«ã¯ã表示ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
-</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="ja-jp">
-<title>ãã³ãã¬ã¼ãã®ç·¨é</title>
-<shortdesc>æ¢åã®ãã³ãã¬ã¼ããç·¨éãã¾ãã
-</shortdesc>
-<csbody>
-<p>ãã³ãã¬ã¼ããã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
-<dl>
-<dlentry>
-<dt>åå</dt>
-<dd>ãã³ãã¬ã¼ãã®ååã
-</dd>
-</dlentry><dlentry>
-<dt>ãã³ãã¼</dt>
-<dd>ãã³ãã¬ã¼ãã使ç¨ããããæ§æããã¦ãããªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã使ããä¼ç¤¾ã®ååã
-</dd>
-</dlentry><dlentry>
-<dt>ãã¼ã¸ã§ã³</dt>
-<dd>ãã³ãã¬ã¼ãã使ç¨ããããæ§æããã¦ãããªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ã
-</dd>
-</dlentry><dlentry>
-<dt>CPU æ°</dt>
-<dd>ãã³ãã¬ã¼ãã«å®ç¾©ããã¦ããããã»ããµã¼ã®æ°ã
-</dd>
-</dlentry><dlentry>
-<dt>ã¡ã¢ãªã¼</dt>
-<dd>ä»®æ³ãã·ã³ã«å²ãå½ã¦ãããã¡ã¢ãªã¼ã®é (MB åä½)ã
-</dd>
-</dlentry><dlentry>
-<dt>ãã£ã¹ã¯</dt>
-<dd>ãã£ã¹ã¯ã»ãµã¤ãº (GB åä½)ã
-</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>KVM ã²ã¹ããã¤ã³ã¹ãã¼ã«ããããã«ä½¿ç¨ããã ISO ãã¡ã¤ã«ã®ãã±ã¼ã·ã§ã³ã®ãã¡ã¤ã«ã»ãã¹ã
-</dd>
-</dlentry><dlentry>
-<dt>ã¹ãã¬ã¼ã¸ã»ãã¼ã«</dt>
-<dd>ç¹å®ã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¾ãã¯ããã©ã«ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã
-</dd>
-</dlentry><dlentry>
-<dt> ãããã¯ã¼ã¯</dt>
-<dd>KVM ã²ã¹ãã使ç¨ã§ããããã©ã«ãã®ãããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã
-è¤æ°ã®ãããã¯ã¼ã¯ã鏿ãããã¨ãã§ãã¾ãã
-</dd>
-</dlentry></dl> 使ç¨ä¸å¯ã«ãªã£ã¦ããªããã£ã¼ã«ããç·¨éã§ãã¾ãã
-ãã£ã¼ã«ããç·¨éããå¾ã<uicontrol>ãä¿åã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
-</p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>ãã³ãã¬ã¼ãã®è¿½å </title>
-<shortdesc>ãã³ãã¬ã¼ããã½ã¼ã¹ã»ã¡ãã£ã¢ãã追å ãã¾ãã
-ä»å¾ã®ãã£ã¹ã«ããªã¼ã®ããã«ãç¬èªã® ISO ã¤ã¡ã¼ã¸ããISOãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«è¿½å ã§ãã¾ãã</shortdesc>
-<csbody>
-<p>ã½ã¼ã¹ã»ã¡ãã£ã¢ã®ãã±ã¼ã·ã§ã³ã以ä¸ã®ãªãã·ã§ã³ãã鏿ãã¦ãã ããã
-<dl>
-<dlentry>
-<dt>ãã¼ã«ã« ISO ã¤ã¡ã¼ã¸</dt>
-<dd>ããã鏿ãã¦ãã·ã¹ãã ã§ä½¿ç¨å¯è½ãªã¤ã³ã¹ãã¼ã« ISO ã¤ã¡ã¼ã¸ããã¹ãã¬ã¼ã¸ã»ãã¼ã«ã§ã¹ãã£ã³ãã¾ãã
-</dd>
-</dlentry><dlentry>
-<dt>ãªã¢ã¼ã ISO ã¤ã¡ã¼ã¸</dt>
-<dd>ããã鏿ãã¦ãã¤ã³ã¹ãã¼ã« ISO ã¤ã¡ã¼ã¸ã®ãªã¢ã¼ãã»ãã±ã¼ã·ã§ã³ãæå®ãã¾ãã
-</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>ãã³ãã¬ã¼ãã®è¿½å - ãã¼ã«ã« ISO ã¤ã¡ã¼ã¸</title>
-<shortdesc>ãã³ãã¬ã¼ãããã¼ã«ã« ISO ã¤ã¡ã¼ã¸ãã追å ãã¾ãã
-</shortdesc>
-<csbody>
-<p>ã·ã¹ãã ã§ä½¿ç¨å¯è½ãª ISO ã¤ã¡ã¼ã¸ã表示ããã¾ãã
-<dl><dlentry>
-<dt>OS</dt>
-<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ååã
-</dd>
-</dlentry><dlentry>
-<dt>ãã¼ã¸ã§ã³</dt>
-<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ã
-</dd>
-</dlentry><dlentry>
-<dt>ãµã¤ãº</dt>
-<dd>ISO ã¤ã¡ã¼ã¸ã®ãµã¤ãºã
-</dd>
-</dlentry></dl></p>
-<p>ãã³ãã¬ã¼ãã ISO ã¤ã¡ã¼ã¸ãã使ããã«ã¯ã以ä¸ã®ãªãã·ã§ã³ã鏿ãã¦ãã ããã
-<ul>
-<li>ãã³ãã¬ã¼ãã使ããå
ã«ãªã ISO ã¤ã¡ã¼ã¸ã鏿ãã¦ã<uicontrol>ã鏿ãã ISO ãããã³ãã¬ã¼ãã使ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
-</li>
-<li>ãªã¹ãããã¦ãã ISO ã¤ã¡ã¼ã¸ãããããããã³ãã¬ã¼ãã使ããã«ã¯ã<uicontrol>ããã¹ã¦ã</uicontrol>ã鏿ãã¦ãã<uicontrol>ã鏿ãã ISO ãããã³ãã¬ã¼ãã使ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
-</li>
-<li>使ç¨ããã ISO ã¤ã¡ã¼ã¸ãã¹ãã£ã³çµæã«è¦ã¤ãããªãå ´åã以ä¸ã®ãªãã·ã§ã³ã鏿ã§ãã¾ãã
-<ul>
-<li>ISO ã¤ã¡ã¼ã¸ã®ãã¹ãæå®ããã«ã¯ã<uicontrol>ãç¹å®ã® ISO ãã¡ã¤ã«ã使ç¨ããã</uicontrol>ã鏿ãã¾ãã
-</li>
-<li>ãã以ä¸ã® ISO ã¤ã¡ã¼ã¸ãæ¤ç´¢ããã«ã¯ã<uicontrol>ãISO ãããã«æ¤ç´¢ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
-</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/kimchi.css b/plugins/kimchi/ui/pages/help/kimchi.css
deleted file mode 100644
index 32fae4a..0000000
--- a/plugins/kimchi/ui/pages/help/kimchi.css
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-BODY {
- background: #FFFFFF;
- margin-bottom: 1em;
- margin-left: .5em;
-}
-
-bold {
- font-weight: bold;
-}
-
-boldItalic {
- font-weight: bold;
- font-style: italic;
-}
-
-italic {
- font-style: italic;
-}
-
-underlined {
- text-decoration: underline;
-}
-
-uicontrol {
- font-weight: bold;
-}
-
-filepath {
- font-family: monospace, monospace;
-}.option {
- font-family: monospace, monospace;
-}
-
-cmdname {
- font-weight: bold;
- font-family: monospace, monospace;
-}
-
-.defparmname {
- font-weight: bold;
- text-decoration: underline;
- font-family: monospace, monospace;
-}
-
-.kwd {
- font-weight: bold;
-}
-
-.defkwd {
- font-weight: bold;
- text-decoration: underline;
-}
-
-var {
- font-style : italic;
-}
-
-strongwintitle {
- font-weight : bold;
-}
-
-parmname {
- font-weight: bold;
- font-family: monospace, monospace;
- white-space: nowrap;
-}
-
-code {
- font-family: monospace, monospace;
-}
-
-pre {
- font-family: monospace, monospace;
-}
-
-CITE {
- font-style: italic;
-}
-
-EM {
- font-style: italic;
-}
-
-STRONG {
- font-weight: bold;
-}
-
-VAR {
- font-style: italic;
-}
-
-dt {
- font-weight: bold;
-}
-
-/***********************************************************
- * Basic fonts
- ***********************************************************/
-body,
-td,
-th,
-caption {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
-}
-
-pre, code {
- font-family: MS Courier New, Courier, monospace;
-}
-
-h1, h2, h3 {
- font-size: 12pt;
- font-weight: bold;
- color: #336699;
-}
-
-h4 {
- font-size: 10pt;
- font-weight: bold;
- color: #336699;
-}
-
-/***********************************************************
- * Basic indents, padding, and margin
- ***********************************************************/
-body {
- color: black;
- background-color: white;
- margin: 0;
- padding-top: 0.2em;
- padding-left: 0.6em;
- padding-right: 0.2em;
- padding-bottom: 1em;
-}
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- padding: 0;
- margin-top: 1em;
- margin-bottom: 0.75em;
- margin-left: 0;
- margin-right: 0;
-}
-
-address,
-dl,
-li,
-p {
- padding: 0;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
- margin-left: 0;
- margin-right: 0;
- line-height: 125%;
-}
-
-td dl {
- margin-left: 2em;
-}
-
-pre {
- padding: 0;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
- margin-left: 2em;
- margin-right: 0;
-}
-
-ol,
-ul {
- padding: 0;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
- margin-left: 2.00em;
- margin-right: 0;
-}
-
-dd {
- margin-left: 3.00em;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
-}
-
-dt {
- margin-left: 1.00em;
- margin-top: 0.75em;
-}
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am b/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
deleted file mode 100644
index e441955..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-ko_KR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ko_KR
-
-dist_ko_KR_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/guests.dita b/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
deleted file mode 100644
index 2d9f32b..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="ko-kr">
-<title>ê²ì¤í¸</title>
-<shortdesc><wintitle>ê²ì¤í¸</wintitle> íì´ì§ìë ì ìë KVM ê°ì 머ì ì´ ëì´ë©ëë¤.</shortdesc>
-<csbody>
-<p>ê° ê²ì¤í¸ì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤.<dl><dlentry>
-<dt>ì´ë¦</dt>
-<dd>ê°ì 머ì ì ì´ë¦ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>ê°ì 머ì ì íë¡ì¸ì ì´ì©ë¥ ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë¤í¸ìí¬ I/O</dt>
-<dd>ì´ë¹ ë¤í¸ìí¬ ì
/ì¶ë ¥(I/O) ì ì¡ ìë(KB)ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ëì¤í¬ I/O</dt>
-<dd>ì´ë¹ ëì¤í¬ ì
/ì¶ë ¥(I/O) ì ì¡ ìë(KB)ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë¼ì´ë¸íì¼</dt>
-<dd>ê²ì¤í¸ ì´ì ì²´ì ì ìíì´ê±°ë, ê²ì¤í¸ê° íì±ì´ ìë ê²½ì° <tm tmtype="tm" trademark="Linux">Linux</tm> ë°°í¬ë¥¼ ëíë´ë ìì´ì½ì
ëë¤.</dd>
-</dlentry></dl></p>
-<p>ë¤ì ì¡°ì¹ ìì´ì½ì´ ê° ê²ì¤í¸ë§ë¤ íìë©ëë¤.<dl>
-<dlentry>
-<dt>ë¤ì ì¤ì </dt>
-<dd>ê²ì¤í¸ë¥¼ ë¤ì ì¤ì íë ¤ë©´ í´ë¦í©ëë¤. </dd>
-</dlentry><dlentry>
-<dt>ì ì(ìì ëë ì¤ì§)</dt>
-<dd>ê²ì¤í¸ì ì ìì ì¼ê±°ë ëë ¤ë©´ í´ë¦í©ëë¤. ìì´ì½ì´ 빨ê°ìì´ë©´ ì ìì´ êº¼ì§ ê²ì´ê³ ìì´ì½ì´ ë
¹ìì´ë©´ ì ìì´ ì¼ì§ ê²ì
ëë¤.</dd>
-</dlentry></dl> </p>
-<p>ê° ê²ì¤í¸ë§ë¤ ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
-<li>ê²ì¤í¸ ì´ì ì²´ì ì ì격 ì½ìì ì°ê²°íë ¤ë©´ <uicontrol>ì°ê²°</uicontrol>ì ì íí©ëë¤.</li>
-<li>ê²½ë¡ë¥¼ ì¤ì¹ ë§¤ì²´ë¡ ë³ê²½íë ¤ë©´ <uicontrol>매체 ê´ë¦¬</uicontrol>를 ì íí©ëë¤.</li>
-<li>ê²ì¤í¸ë¥¼ ë¤ì ì¤ì íë ¤ë©´ <uicontrol>ë¤ì ì¤ì </uicontrol>ì ì íí©ëë¤.</li>
-<li>기존 ê²ì¤í¸ì í¹ì±ì í¸ì§íë ¤ë©´ <uicontrol>í¸ì§</uicontrol>ì ì íí©ëë¤. ê²ì¤í¸ë ì¤ì§ ìíì¼ ëë§ í¸ì§í ì ììµëë¤.</li>
-<li>ê²ì¤í¸ë¥¼ ìì íë ¤ë©´ <uicontrol>ìì </uicontrol>를 ì íí©ëë¤.</li>
-</ul>ê²ì¤í¸ ëë ê°ì 머ì ì ìì±íë ¤ë©´ íì´ì§ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="ko-kr">
-<title>ê°ì 머ì ìì±</title>
-<shortdesc>기존 í
í리í¸ë¥¼ ì¬ì©íì¬ ê°ì 머ì ì ìì±í©ëë¤.</shortdesc>
-<csbody>
-<p> <ol>
-<li>ê°ì 머ì ì ìë³íë ë° ì¬ì©ë ì´ë¦ì ì
ë ¥íììì¤.</li>
-<li rev="rev1">í
í리í¸ë¥¼ ì ííììì¤. <ul>
-<li>í
í리í¸ê° ì¡´ì¬íë ê²½ì°, íìë í
íë¦¬í¸ ì¤ìì ì ííììì¤.</li>
-<li>í
í리í¸ê° ìë ê²½ì°, <uicontrol>í
íë¦¬í¸ ìì±</uicontrol>ì í´ë¦íì¬ í
í리í¸ë¥¼ ìì±íììì¤.</li>
-</ul></li>
-<li><uicontrol>ìì±</uicontrol>ì í´ë¦íììì¤.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="ko-kr">
-<title>ê²ì¤í¸ í¸ì§</title>
-<shortdesc>기존 ê°ì 머ì ì í¹ì±ì í¸ì§í©ëë¤. ì¼ë¶ í¹ì±ì ê²ì¤í¸ê° ì¤ì§ë ëììë§ í¸ì§í ì ììµëë¤.
-ë¤ë¥¸ í¹ì±ì ë¤ì ë¶í¸ìì ì ì©ë©ëë¤. </shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>ê° ê²ì¤í¸ì ëí´ ë¤ì ì ë³´ê° <wintitle>ì¼ë°</wintitle> íì íìë©ëë¤.<dl>
-<dlentry>
-<dt>ì´ë¦</dt>
-<dd>ê°ì 머ì ì ì´ë¦ì
ëë¤(ê²ì¤í¸ê° ì¤ì§ë ëììë§ í¸ì§í ì ìì).</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>íë¡ì¸ì ìì
ëë¤(ê²ì¤í¸ê° ì¤í ì¤ì¸ ê²½ì° ì í¬ê¸°ë ë¤ì ë¶í¸ìì ì ì©ë¨).</dd>
-</dlentry><dlentry>
-<dt>ë©ëª¨ë¦¬</dt>
-<dd>ë©ëª¨ë¦¬ ì©ë(MB)ì
ëë¤(ê²ì¤í¸ê° ì¤í ì¤ì¸ ê²½ì° ì ì©ëì ë¤ì ë¶í¸ìì ì ì©ë¨).</dd>
-</dlentry><dlentry>
-<dt>ìì´ì½</dt>
-<dd>ê²ì¤í¸ê° íì±ì´ ìë ë íì¬ ìí(ë¼ì´ë¸íì¼) ëì ì íìë Linux ë°°í¬ë¥¼ ëíë´ë ê·¸ëí½ ì´ë¯¸ì§ì
ëë¤.</dd>
-</dlentry></dl></p>
-<p>ë¤ì ì ë³´ê° <wintitle>ì¤í 리ì§</wintitle> íì íìë©ëë¤.</p>
-<dl><dlentry>
-<dt>ì¤í 리ì§</dt>
-<dd>ì¤ì¹ì ì¬ì©ë ISO íì¼ì ìì¹ë¥¼ íìí©ëë¤.</dd>
-</dlentry></dl>
-<p> ì¬ì© ìí¨ì¼ë¡ ì¤ì ëì§ ìì íë를 í¸ì§í ì ììµëë¤. íë를 í¸ì§í íì <uicontrol>ì ì¥</uicontrol>ì í´ë¦í©ëë¤. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="ko-kr">
-<title>ì¤í ë¦¬ì§ ì¥ì¹ ì¶ê°, êµì²´ ëë ë¶ë¦¬</title>
-<shortdesc rev="rev1">ê°ì 머ì ì ëí´ ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì¶ê°, êµì²´ ëë ë¶ë¦¬í ì ììµëë¤. ì§ìëë ì¥ì¹ë CDROMë¿ì
ëë¤. ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ í¸ì§íë ¤ë©´ ë¤ì ë¨ê³ë¥¼ ìííììì¤.</shortdesc>
-<csbody>
-<ol>
-<li><wintitle>ê²ì¤í¸ í¸ì§</wintitle> ì°½ìì <wintitle>ì¤í 리ì§</wintitle>를 ì ííììì¤.</li>
-<li>ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ êµì²´íë ¤ë©´ <uicontrol>주í©ì ì¬ëì(/)</uicontrol>ê° ìë 첫 ë²ì§¸ ìì´ì½ì í´ë¦íììì¤. ISO íì¼ ê²½ë¡ë¥¼ ì
ë ¥íê³ <uicontrol>êµì²´</uicontrol>를 í´ë¦íììì¤.</li>
-<li>ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ë¶ë¦¬íë ¤ë©´ <uicontrol>빨ê°ì ëì(-)</uicontrol>ê° ìë ë ë²ì§¸ ìì´ì½ì í´ë¦íììì¤. ìì ì¬ë¶ë¥¼ íì¸íê³ <uicontrol>íì¸</uicontrol>ì í´ë¦íììì¤.</li>
-<li>ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì¶ê°íë ¤ë©´ ë
¹ì <uicontrol>ëí기 ë¶í¸(+)</uicontrol>ê° ìë ì¸ ë²ì§¸ ìì´ì½ì í´ë¦íììì¤. ì¥ì¹ ì´ë¦ ë° ISO íì¼ ê²½ë¡ë¥¼ ì
ë ¥íê³ <uicontrol>ë¶ë¦¬</uicontrol>를 í´ë¦íììì¤.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="ko-kr">
-<title>VMì CDROM êµì²´</title>
-<shortdesc rev="rev1">ì¤ì¹ê° ìë£ë íì ê°ì 머ì ì ëí CDROMì 컨í
ì¸ ë¥¼ ë°ê¿ ì ììµëë¤.</shortdesc>
-<csbody>
-<ol>
-<li>ê°ì 머ì ì´ ììëìëì§ íì¸íììì¤.</li>
-<li>ì¡°ì¹ ë©ë´ìì <uicontrol>매체 ê´ë¦¬</uicontrol>를 ì ííììì¤.</li>
-<li>CDROMì íì¬ ë¡ëë í목ì ë³ê²½í기 ìí´ hdc íë ìì ìë <uicontrol>주í©ì ì¬ëì(/)</uicontrol> ìì´ì½ì í´ë¦íììì¤.</li>
-<li><wintitle>VMì CDROM êµì²´</wintitle> íì´ì§ìì ISO íì¼ ê²½ë¡ë¥¼ ì
ë ¥íììì¤. ë¤ë¥¸ ë íëë ì½ê¸° ì ì©ì
ëë¤.</li>
-<li><uicontrol>êµì²´</uicontrol>를 í´ë¦íììì¤.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/host.dita b/plugins/kimchi/ui/pages/help/ko_KR/host.dita
deleted file mode 100644
index ee4a9c3..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/host.dita
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="ko-kr">
-<title>í¸ì¤í¸</title>
-<shortdesc><wintitle>í¸ì¤í¸</wintitle> íì´ì§ìë í¸ì¤í¸ ìì¤í
ì ëí ì ë³´ê° íìëë©° ì´ íì´ì§ë¥¼ ì¬ì©íì¬ í¸ì¤í¸ë¥¼ ì¢
ë£ ë° ë¤ì ììíê±°ë í¸ì¤í¸ì ì°ê²°í ì ììµëë¤.</shortdesc>
-<csbody>
-<p>í¸ì¤í¸ì ëí´ ë¤ì ì¡°ì¹ë¥¼ ìíí ì ììµëë¤.<ul>
-<li>í¸ì¤í¸ ìì¤í
ì ì¢
ë£íë ¤ë©´ <uicontrol>ìì¤í
ì¢
ë£</uicontrol>를 ì íí©ëë¤.</li>
-<li>í¸ì¤í¸ ìì¤í
ì ë¤ì ììíë ¤ë©´ <uicontrol>ë¤ì ìì</uicontrol>ì ì íí©ëë¤.</li>
-<li>ì´ë¯¸ ì°ê²°ëì´ ìì§ ìì ê²½ì°, í¸ì¤í¸ ìì¤í
ì ëí VNC ì°ê²°ì ììíë ¤ë©´ <uicontrol>ì°ê²°</uicontrol>ì ì íí©ëë¤.</li>
-</ul></p>
-<p>í¸ì¤í¸ì ëí ì 보를 íìíë ¤ë©´ ë¤ì ì¹ì
ì í´ë¦íììì¤.<dl>
-<dlentry>
-<dt>기본 ì ë³´</dt>
-<dd>ì´ ì¹ì
ìë í¸ì¤í¸ ì´ì ì²´ì ë°°í¬, ë²ì , ì½ë ì´ë¦, íë¡ì¸ì ì í, ë©ëª¨ë¦¬ ì©ë(GB) ë±ì´ íìë©ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ìì¤í
íµê³</dt>
-<dd>ì´ ì¹ì
ìë í¸ì¤í¸ì CPU, ë©ëª¨ë¦¬, ëì¤í¬ I/O, ë¤í¸ìí¬ I/Oì ëí íµê³ë¥¼ íìíë ê·¸ëíê° íìë©ëë¤. í¸ì¤í¸ íì ë ë¬ì ë ë°ì´í° ìì§ì ê³ìíë ¤ë©´ <uicontrol>ì´ íì´ì§ë¥¼ ë ë íì ë°ì´í° ìì§</uicontrol>ì ì íí©ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ìíí¸ì¨ì´ ì
ë°ì´í¸</dt>
-<dd>ì´ ì¹ì
ìë í¨í¤ì§ ì´ë¦, ë²ì , ìí¤í
ì², ì ì¥ì를 ë¹ë¡¯íì¬ ì¬ì© ê°ë¥í ì
ë°ì´í¸ê° ìë 모ë í¨í¤ì§ì ëí ì ë³´ê° íìë©ëë¤. <uicontrol>모ë ì
ë°ì´í¸</uicontrol>를 ì ííì¬ ëì´ë 모ë í¨í¤ì§ë¥¼ ì
ë°ì´í¸í ì ììµëë¤. ì
ë°ì´í¸ì ëí´ ê°ë³ í¨í¤ì§ë¥¼ ì íí ìë ììµëë¤.</dd>
-</dlentry><dlentry>
-<dt>ì ì¥ì</dt>
-<dd>ì´ ì¹ì
ìë í¸ì¤í¸ ìì¤í
ê³¼ ì°ê´ë ì ì¥ìê° íìë©ëë¤. ì ì¥ì를 ì¶ê°íê±°ë, ì¬ì©ì¼ë¡ ì¤ì íê±°ë, í¸ì§íê±°ë, ì ê±°í ì ììµëë¤. ì ì¥ì를 ì¶ê°íë©´ ì ì¥ìê° í¸ì¤í¸ ìì¤í
ê³¼ ì°ê´ëë©°, ì ì¥ì를 ì¬ì©ì¼ë¡ ì¤ì íë©´ í¸ì¤í¸ê° ì ì¥ìì ì¡ì¸ì¤í ì ììµëë¤. í´ë¹ ìì¤í
ì´ Red Hat Enterprise Linux ëë Fedoraì¸ ê²½ì°, <filepath>yum</filepath> ì ì¥ì를 ì¶ê°í ì ììµëë¤.
-í´ë¹ ìì¤í
ì´ Ubuntu ëë Debianì¸ ê²½ì°, <filepath>deb</filepath> ì ì¥ì를 ì¶ê°íììì¤.<p>yum ì ì¥ìë¡ ìì
íë ê²½ì°, GPG ê²ì¬ë¥¼ ì¶ê°íì¬ ì´ ì ì¥ìì í¨í¤ì§ê° ììëì§ ììëì§ íì¸í ì ììµëë¤.
-ì ì¥ì를 ì íí í <uicontrol>í¸ì§</uicontrol>ì ì ííììì¤. <uicontrol>ì</uicontrol>를 ì ííì¬ GPG ê²ì¬ë¥¼ ì¬ì©ì¼ë¡ ì¤ì í í ì ì¥ìì ëí GPG í¤ íì¼ì URLì ì
ë ¥íììì¤.</p></dd>
-</dlentry><dlentry>
-<dt>ëë²ê·¸ ë³´ê³ ì</dt>
-<dd>ì´ ì¹ì
ìë ì´ë¦ ë° íì¼ ê²½ë¡ë¥¼ í¬í¨í ëë²ê·¸ ë³´ê³ ìê° íìë©ëë¤.
-ì ë³´ê³ ì ìì±, 기존 ë³´ê³ ì ì´ë¦ ë°ê¾¸ê¸°, ì ê±°, ë¤ì´ë¡ë ë±ì ìµì
ì¤ìì ì íí ì ììµëë¤.<p>ëë²ê·¸ ë³´ê³ ìë <cmdname>sosreport</cmdname> ëª
ë ¹ì ì¬ì©íì¬ ìì±ë©ëë¤. ì´ë Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora ë° Ubuntu ë°°í¬ìì ì¬ì© ê°ë¥í©ëë¤. ì´ ëª
ë ¹ì êµ¬ì± ë° ì§ë¨ ì ë³´(ì: ì¤í ì¤ì¸ 커ë ë²ì , ë¡ëë 모ë, ìì¤í
ë° ìë¹ì¤ êµ¬ì± íì¼)를 í¬í¨íë .tar íì¼ì ìì±í©ëë¤.
-ëí ì´ ëª
ë ¹ì ì¸ë¶ íë¡ê·¸ë¨ì ì¤ííì¬ ì¶ê° ì 보를 ìì§íê³ ê²°ê³¼ ìì¹´ì´ë¸ì ì´ ì¶ë ¥ì ì ì¥í©ëë¤.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/network.dita b/plugins/kimchi/ui/pages/help/ko_KR/network.dita
deleted file mode 100644
index 451510f..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="ko-kr">
-<title>ë¤í¸ìí¬</title>
-<shortdesc><wintitle>ë¤í¸ìí¬</wintitle> íì´ì§ìë ë¤í¸ìí¬ ì°ê²°ì ëí ì ë³´ê° íìë©ëë¤.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>ë¤í¸ìí¬ ì´ë¦</dt>
-<dd>ë¤í¸ìí¬ì ì´ë¦ ëë <uicontrol>기본ê°</uicontrol>ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ìí</dt>
-<dd>ë¤í¸ìí¬ì ìí(íì±ì ê²½ì° ë
¹ì, ë¹íì±ì ê²½ì° ë¹¨ê°ì)ì
ëë¤. </dd>
-</dlentry><dlentry>
-<dt>ë¤í¸ìí¬ ì í</dt>
-<dd>ë¤í¸ìí¬ ì íì
ëë¤. ì: <uicontrol>NAT</uicontrol>(Network Address Translation)</dd>
-</dlentry><dlentry>
-<dt>ì¸í°íì´ì¤</dt>
-<dd>ë¤í¸ìí¬ ì¸í°íì´ì¤ì
ëë¤. ì: <uicontrol>virbr0</uicontrol>(기본ê°)</dd>
-</dlentry><dlentry>
-<dt>주ì ê³µê°</dt>
-<dd>IP 주ìì
ëë¤.</dd>
-</dlentry></dl></p>
-<p>ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
-<li rev="rev1">ë¤í¸ìí¬ ì°ê²°ì ììíë ¤ë©´ <uicontrol>ìì</uicontrol>ì ì íí©ëë¤.</li>
-<li>ë¤í¸ìí¬ ì°ê²°ì ì¢
ë£íë ¤ë©´ <uicontrol>ì¤ì§</uicontrol>를 ì íí©ëë¤.</li>
-<li>ì°ê²° ì 보를 ìì íë ¤ë©´ <uicontrol>ìì </uicontrol>를 ì íí©ëë¤.</li>
-</ul>ë¤í¸ìí¬ë¥¼ ìì±íë ¤ë©´ íë©´ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="ko-kr">
-<title>ë¤í¸ìí¬ ìì±</title>
-<shortdesc>ë¤í¸ìí¬ë¥¼ ìì±í©ëë¤.</shortdesc>
-<csbody>
-<p> <ol>
-<li>ë¤í¸ìí¬ì ì´ë¦ì ì
ë ¥íììì¤.</li>
-<li>ë¤í¸ìí¬ ì íì ì ííë ¤ë©´ í´ë¦íììì¤. <dl rev="rev1"><dlentry>
-<dt><uicontrol>격리ë¨</uicontrol></dt>
-<dd>격리 모ëì
ëë¤. ê²ì¤í¸ë ì¸ë¶ ìì¤í
ì ëí´ íµì ì ë³´ë´ê±°ë ë°ì ì ììµëë¤.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Network Address Translation 모ëì
ëë¤. ê²ì¤í¸ê° ì¸ë¶ ìì¤í
ì¼ë¡ ë³´ë´ë íµì ìì í¸ì¤í¸ IP 주ì를 ì¬ì©í©ëë¤. ì¸ë¶ ìì¤í
ì ê²ì¤í¸ë¡ì íµì ì ììí ì ììµëë¤.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>ë¸ë¦¿ì§ë¨</uicontrol></dt>
-<dd>ë¸ë¦¿ì§ 모ëì
ëë¤. ê²ì¤í¸ë ì¸ë¶ ìì¤í
ê³¼ íµì í ì ìê³ ì¸ë¶ ìì¤í
ì ë¤í¸ìí¬ìì 물리ì ìì¤í
ì²ë¼ ê²ì¤í¸ì ì ìí ì ììµëë¤. ë¸ë¦¿ì§ 모ëì ê²½ì°, ì¶ê° 목ì ì§ ë° VLAN ì 보를 ì§ì í´ì¼ í©ëë¤.</dd>
-</dlentry></dl></li>
-<li><uicontrol>ìì±</uicontrol>ì í´ë¦íììì¤.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/storage.dita b/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
deleted file mode 100644
index 2e6f5e8..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="ko-kr">
-<title>ì¤í 리ì§</title>
-<shortdesc><wintitle>ì¤í 리ì§</wintitle> íì´ì§ìë ë°ë¡ ì¬ì©í ì ìë '기본' ë° 'ISO' ì¤í ë¦¬ì§ íì í¬í¨íì¬ ì¬ì© ê°ë¥í ì¤í ë¦¬ì§ íì´ ëì´ë©ëë¤.
-ì¬ì©ì ì ì© ISO를 ì¬ì©íë ¤ë©´ ì´ë¥¼ 'ISO' ì¤í ë¦¬ì§ í ê²½ë¡ì ì¶ê°íììì¤.</shortdesc>
-<csbody>
-<p>ê° ì¤í ë¦¬ì§ íì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤.<dl>
-<dlentry>
-<dt>ì´ë¦</dt>
-<dd>ì¤í ë¦¬ì§ íì ì´ë¦ ë° ì¬ì©ë¥ ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ìí</dt>
-<dd>ì¤í ë¦¬ì§ íì ìí(íì±ì ê²½ì° ë
¹ì, ë¹íì±ì ê²½ì° ë¹¨ê°ì)ì
ëë¤. </dd>
-</dlentry><dlentry>
-<dt>ìì¹</dt>
-<dd>ì¤í ë¦¬ì§ íì ìì¹ì ëí íì¼ ê²½ë¡ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ì í</dt>
-<dd>ì¤í ë¦¬ì§ íì ì íì
ëë¤. ì: <uicontrol>dir</uicontrol></dd>
-</dlentry><dlentry>
-<dt>ì©ë</dt>
-<dd>ì¤í ë¦¬ì§ íìì ê³µê°ì ìì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>í ë¹ë¨</dt>
-<dd>ì¤í ë¦¬ì§ íì ì´ë¯¸ í ë¹ë ê³µê°ì ìì
ëë¤.</dd>
-</dlentry></dl></p>
-<p>ê° ì¤í ë¦¬ì§ íë§ë¤ ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
-<li>ì¬ì© ê°ë¥íëë¡ ì¤í ë¦¬ì§ íì íì±ííë ¤ë©´ <uicontrol>íì±í</uicontrol>를 ì íí©ëë¤.</li>
-<li>ì¤í ë¦¬ì§ íì ë¹íì±ííë ¤ë©´ <uicontrol>ë¹íì±í</uicontrol>를 ì íí©ëë¤.</li>
-<li>ë¹íì± ì¤í ë¦¬ì§ íì ì ê±°íë ¤ë©´ <uicontrol>ì ì ì·¨ì</uicontrol>를 ì íí©ëë¤.</li>
-</ul></p>
-<p>ì¤í ë¦¬ì§ íì ëí ì¤í ë¦¬ì§ ë³¼ë¥¨ ì¸ë¶ì¬íì íìíë ¤ë©´ ì¤í ë¦¬ì§ í íì ì¤ë¥¸ìª½ì ìë íì´í를 í´ë¦íììì¤. ì¸ë¶ì¬íìë ë¤ìì´ í¬í¨ë©ëë¤.<dl><dlentry>
-<dt>ì í</dt>
-<dd>볼륨ì ì íì
ëë¤. ì: <uicontrol>íì¼</uicontrol></dd>
-</dlentry><dlentry>
-<dt>íì</dt>
-<dd>íìì ì íì ë°ë¼ ë¬ë¼ì§ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ì©ë</dt>
-<dd>ì¤í ë¦¬ì§ ë³¼ë¥¨ì í¬ê¸°ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>í ë¹</dt>
-<dd>ì¤í ë¦¬ì§ íì ì´ë¯¸ í ë¹ë ê³µê°ì ìì
ëë¤.</dd>
-</dlentry></dl>ì¤í ë¦¬ì§ íì ì ìíë ¤ë©´ íë©´ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="ko-kr">
-<title>ì¤í ë¦¬ì§ í ì ì</title>
-<shortdesc> ì¤í ë¦¬ì§ íì ì ìí©ëë¤.</shortdesc>
-<csbody>
-<p> <ol>
-<li><uicontrol>ì¤í ë¦¬ì§ í ì´ë¦</uicontrol> íëìì, ì¤í ë¦¬ì§ íì ìë³íë ë° ì¬ì©ë ì´ë¦ì ì
ë ¥íììì¤.</li>
-<li><uicontrol>ì¤í ë¦¬ì§ í ì í</uicontrol> 목ë¡ìì ë¤ì ì íì ì ííììì¤. <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>ëë í 리 íì ì§ì í©ëë¤. <uicontrol>DIR</uicontrol> ì íì ì íí ê²½ì°, <uicontrol>ì¤í ë¦¬ì§ ê²½ë¡</uicontrol>(ì¤í ë¦¬ì§ íì íì¼ ê²½ë¡)를 ì
ë ¥í©ëë¤.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>ë¤í¸ìí¬ íì¼ ìì¤í
íì ì§ì í©ëë¤. <uicontrol>NFS</uicontrol>를 ì íí ê²½ì°, <uicontrol>NFS ìë² IP 주ì</uicontrol> ë° <uicontrol>NFS ê²½ë¡</uicontrol>(ìì ëë í 리ì ê²½ë¡)를 ì
ë ¥í©ëë¤.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>iSCSI ìë²ì í ë¹ë ëìì 기ë°ì¼ë¡ íì ì§ì í©ëë¤.
-<uicontrol>iSCSI</uicontrol>를 ì íí ê²½ì°, iSCSI ìë²ì ëí <uicontrol>iSCSI ìë² IP 주ì</uicontrol> ë° <uicontrol>ëì</uicontrol>ì ì
ë ¥í©ëë¤. ì íì ì¼ë¡, iSCSI ì¸ì¦ì ì¶ê°íëë¡ ì íí ì ììµëë¤.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>ë
¼ë¦¬ì </uicontrol></dt>
-<dd>ë
¼ë¦¬ì 볼륨 ì¤í ë¦¬ì§ íì ì§ì í©ëë¤. <uicontrol>ì¥ì¹ ê²½ë¡</uicontrol>ìì ì¥ì¹ì ëí ìì¹ë¥¼ ì íí©ëë¤.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI íì´ë² ì±ë</uicontrol></dt>
-<dd>SCSI íì´ë² ì±ëì 기ë°ì¼ë¡ íì ì§ì í©ëë¤. ì¬ì©í SCSI ì´ëí°ë¥¼ ì íí©ëë¤.</dd>
-</dlentry></dl></li>
-<li><uicontrol>ìì±</uicontrol>ì í´ë¦íììì¤.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/templates.dita b/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
deleted file mode 100644
index de16d6e..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="ko-kr">
-<title>í
í리í¸</title>
-<shortdesc><wintitle>í
í리í¸</wintitle> íì´ì§ìë KVM ê²ì¤í¸ë¥¼ ìì±íë ë° ì¬ì©ë ì ìë ì ìë ê°ì 머ì í
í리í¸ê° íìë©ëë¤.</shortdesc>
-<csbody>
-<p>ê° í
í리í¸ì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤.<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>ì´ì ì²´ì ëë ë°°í¬ì ì´ë¦ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë²ì </dt>
-<dd>ì´ì ì²´ì ëë ë°°í¬ì ë²ì ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>í
í리í¸ì ëí´ ì ìë íë¡ì¸ìì ìì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë©ëª¨ë¦¬</dt>
-<dd>í ë¹ë RAM(Random Access Memory)ì ì(MB)ì
ëë¤.</dd>
-</dlentry></dl></p>
-<p>ê° í
í리í¸ë§ë¤ ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
-<li>í
í리í¸ë¥¼ í¸ì§íë ¤ë©´ <uicontrol>í¸ì§</uicontrol>ì ì íí©ëë¤.</li>
-<li>í
í리í¸ë¥¼ ìì íë ¤ë©´ <uicontrol>ìì </uicontrol>를 ì íí©ëë¤.</li>
-</ul>í
í리í¸ë¥¼ ì¶ê°íë ¤ë©´ íë©´ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="ko-kr">
-<title>í
íë¦¬í¸ í¸ì§</title>
-<shortdesc>기존 í
í리í¸ë¥¼ í¸ì§í©ëë¤.</shortdesc>
-<csbody>
-<p>ê° í
í리í¸ì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤. <dl>
-<dlentry>
-<dt>ì´ë¦</dt>
-<dd>í
í리í¸ì ì´ë¦ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ê³µê¸ì
ì²´</dt>
-<dd>í
í리í¸ê° ì¬ì©íëë¡ êµ¬ì±ë ì´ì ì²´ì ëë ë°°í¬ë¥¼ ìì±í íì¬ì ì´ë¦ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë²ì </dt>
-<dd>í
í리í¸ê° ì¬ì©íëë¡ êµ¬ì±ë ì´ì ì²´ì ëë ë°°í¬ì ë²ì ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>CPU ì</dt>
-<dd>í
í리í¸ì ëí´ ì ìë íë¡ì¸ìì ìì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë©ëª¨ë¦¬</dt>
-<dd>ê°ì 머ì ì í ë¹ë ë©ëª¨ë¦¬ ì©ë(MB)ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ëì¤í¬</dt>
-<dd>ëì¤í¬ í¬ê¸°(GB)ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>KVM ê²ì¤í¸ë¥¼ ì¤ì¹íë ë° ì¬ì©ë ISO íì¼ì ìì¹ì ëí íì¼ ê²½ë¡ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ì¤í ë¦¬ì§ í</dt>
-<dd>í¹ì ì¤í ë¦¬ì§ í ëë 기본 ì¤í ë¦¬ì§ íì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë¤í¸ìí¬</dt>
-<dd>KVM ê²ì¤í¸ì ì¬ì© ê°ë¥í 기본 ë¤í¸ìí¬ ì¸í°íì´ì¤ì
ëë¤. ì¬ë¬ ë¤í¸ìí¬ë¥¼ ì íí ì ììµëë¤.</dd>
-</dlentry></dl> ì¬ì© ìí¨ì¼ë¡ ì¤ì ëì§ ìì íë를 í¸ì§í ì ììµëë¤. íë를 í¸ì§í íì <uicontrol>ì ì¥</uicontrol>ì í´ë¦í©ëë¤. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>í
íë¦¬í¸ ì¶ê°</title>
-<shortdesc>ìì¤ ë§¤ì²´ë¡ë¶í° í
í리í¸ë¥¼ ì¶ê°í©ëë¤. ë¤ì ê²ìì ëí´ 'ISO' ì¤í ë¦¬ì§ íì ì¬ì©ì ì ì© ISO ì´ë¯¸ì§ë¥¼ ì¶ê°í ì ììµëë¤. </shortdesc>
-<csbody>
-<p>ë¤ì ìµì
ì¤ìì ìì¤ ë§¤ì²´ì ìì¹ë¥¼ ì ííììì¤.<dl>
-<dlentry>
-<dt>ë¡ì»¬ ISO ì´ë¯¸ì§</dt>
-<dd>ìì¤í
ìì ì¬ì© ê°ë¥í ì¤ì¹ ISO ì´ë¯¸ì§ì ì¤í ë¦¬ì§ íì ì¤ìºíë ¤ë©´ ì íí©ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ì격 ISO ì´ë¯¸ì§</dt>
-<dd>ì¤ì¹ ISO ì´ë¯¸ì§ì ì격 ìì¹ë¥¼ ì§ì íë ¤ë©´ ì íí©ëë¤.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>í
íë¦¬í¸ ì¶ê° - ë¡ì»¬ ISO ì´ë¯¸ì§</title>
-<shortdesc>ë¡ì»¬ ISO ì´ë¯¸ì§ë¡ë¶í° í
í리í¸ë¥¼ ì¶ê°í©ëë¤.</shortdesc>
-<csbody>
-<p>ìì¤í
ìì ì¬ì© ê°ë¥í ISO ì´ë¯¸ì§ê° íìë©ëë¤.<dl><dlentry>
-<dt>OS</dt>
-<dd>ì´ì ì²´ì ëë ë°°í¬ì ì´ë¦ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>ë²ì </dt>
-<dd>ì´ì ì²´ì ëë ë°°í¬ì ë²ì ì
ëë¤.</dd>
-</dlentry><dlentry>
-<dt>í¬ê¸°</dt>
-<dd>ISO ì´ë¯¸ì§ì í¬ê¸°ì
ëë¤.</dd>
-</dlentry></dl></p>
-<p>ISO ì´ë¯¸ì§ë¡ë¶í° í
í리í¸ë¥¼ ìì±íë ¤ë©´ ë¤ì ìµì
ì¤ìì ì ííììì¤.<ul>
-<li>í
í리í¸ë¥¼ ìì±í기 ìí ISO ì´ë¯¸ì§ë¥¼ ì íí í <uicontrol>ì íí ISOë¡ë¶í° í
íë¦¬í¸ ìì±</uicontrol>ì í´ë¦í©ëë¤.</li>
-<li>ëì´ë ê° ISO ì´ë¯¸ì§ë¡ë¶í° í
í리í¸ë¥¼ ìì±íë ¤ë©´ <uicontrol>모ë</uicontrol>를 ì íí í <uicontrol>ì íí ISOë¡ë¶í° í
íë¦¬í¸ ìì±</uicontrol>ì í´ë¦í©ëë¤.</li>
-<li>ì¬ì©íë ¤ë ISO ì´ë¯¸ì§ê° ì¤ìº ê²°ê³¼ì íìëì§ ìë ê²½ì°, ë¤ì ìµì
ì¤ìì ì íí ì ììµëë¤.<ul>
-<li>ISO ì´ë¯¸ì§ì ê²½ë¡ë¥¼ ì§ì íë ¤ë©´ <uicontrol>í¹ì ISO íì¼ì ì¬ì©íë ¤ê³ í©ëë¤.</uicontrol>를 ì íí©ëë¤.</li>
-<li>ì¶ê° ISO ì´ë¯¸ì§ë¥¼ ê²ìíë ¤ë©´ <uicontrol>ì¶ê° ISO ê²ì</uicontrol>ì í´ë¦í©ëë¤.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am b/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
deleted file mode 100644
index 7fc2cb0..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-pt_BR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/pt_BR
-
-dist_pt_BR_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/guests.dita b/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
deleted file mode 100644
index ac58d5c..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="pt-br">
-<title>Máquinas Virtuais</title>
-<shortdesc>A página <wintitle>Máquinas Virtuais</wintitle> lista as máquinas virtuais
-KVM definidas.</shortdesc>
-<csbody>
-<p>Para cada convidado, as informações a seguir são exibidas:<dl><dlentry>
-<dt>Nome</dt>
-<dd>Nome da máquina virtual.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Porcentagem de utilização do processador na máquina virtual.</dd>
-</dlentry><dlentry>
-<dt>E/S de rede</dt>
-<dd>Taxa de transmissão de entrada/saÃda de rede em KB por segundo.</dd>
-</dlentry><dlentry>
-<dt>E/S de disco</dt>
-<dd>Taxa de transmissão de entrada/saÃda de disco em KB por segundo.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>Estado do console do sistema operacional guest ou um Ãcone que representa
-a distribuição <tm tmtype="tm" trademark="Linux">Linux</tm> se o
-convidado não estiver ativo.</dd>
-</dlentry></dl></p>
-<p>Os Ãcones de ações a seguir são exibidos para cada convidado:<dl>
-<dlentry>
-<dt>Reiniciar</dt>
-<dd>Clique para Reiniciar o convidado. </dd>
-</dlentry><dlentry>
-<dt>Energia (iniciar ou parar)</dt>
-<dd>Clique para ligar ou desligar o convidado. Se o Ãcone estiver vermelho,
-a energia está desligada; se o Ãcone estiver verde, a energia está ligada.</dd>
-</dlentry></dl> </p>
-<p>As ações a seguir podem ser selecionadas para cada convidado:<ul>
-<li>Selecione <uicontrol>Conectar</uicontrol> para conectar-se ao console
-remoto para o sistema operacional guest.</li>
-<li>Selecione <uicontrol>Gerenciar mÃdia</uicontrol> para alterar o caminho
-para a mÃdia de instalação.</li>
-<li>Selecione <uicontrol>Reiniciar</uicontrol> para Reiniciar o convidado.</li>
-<li>Selecione <uicontrol>Editar</uicontrol> para editar as propriedades de um
-convidado existente. Os Máquinas Virtuais podem ser editados somente quando interrompidos.</li>
-<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o convidado.</li>
-</ul>Para criar um convidado, ou máquina virtual, clique no Ãcone <uicontrol>mais
-(+)</uicontrol> na parte superior direita da página.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="en-us">
-<title>Criar máquina virtual</title>
-<shortdesc>Crie uma máquina virtual usando um modelo existente.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Digite o nome a ser usado para identificar a máquina virtual.</li>
-<li rev="rev1">Selecione um modelo. <ul>
-<li>Se existirem modelos, selecione a partir dos modelos exibidos.</li>
-<li>Se não existir nenhum modelo, clique em <uicontrol>Criar um modelo</uicontrol> para
-criar um modelo.</li>
-</ul></li>
-<li>Clique em <uicontrol>Criar</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="en-us">
-<title>Editar convidado</title>
-<shortdesc>Edite as propriedades de uma máquina virtual existente. Algumas propriedades podem ser editadas enquanto o convidado está interrompido. Outras entrarão em vigor na próxima inicialização.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Para cada convidado, as informações a seguir são exibidas na guia <wintitle>Geral</wintitle>:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Nome da máquina virtual. (somente pode ser editado enquanto o convidado está interrompido)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Número de processadores. (se o convidado estiver em execução, uma nova quantia entrará em vigor na próxima inicialização)</dd>
-</dlentry><dlentry>
-<dt>Memória</dt>
-<dd>Quantia de memória em MB. (se o convidado estiver em execução, uma nova quantia entrará em vigor na próxima inicialização)</dd>
-</dlentry><dlentry>
-<dt>Ãcone</dt>
-<dd>Imagem gráfica representando a distribuição Linux a ser exibida
-no lugar do status atual (Livetile) quando o convidado não está ativo.</dd>
-</dlentry></dl></p>
-<p>As informações a seguir são exibidas na guia <wintitle>Armazenamento</wintitle>.</p>
-<dl><dlentry>
-<dt>Armazenamento</dt>
-<dd>Exibe o local do arquivo ISO usado para instalação.</dd>
-</dlentry></dl>
-<p> Os campos que não estão desativados podem ser editados. Depois de editar um campo,
-clique em <uicontrol>Salvar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="en-us">
-<title>Incluir, substituir ou remover um dispositivo de armazenamento</title>
-<shortdesc rev="rev1">Ã possÃvel incluir, substituir ou remover um dispositivo de armazenamento
-para sua máquina virtual. O único dispositivo suportado é CD-ROM. Para editar
-seus dispositivos de armazenamento, siga estas etapas:</shortdesc>
-<csbody>
-<ol>
-<li>Na janela <wintitle>Editar convidado</wintitle>, selecione <wintitle>Armazenamento</wintitle>.</li>
-<li>Para substituir um dispositivo de armazenamento, clique no primeiro Ãcone com a <uicontrol>barra
-laranja (/)</uicontrol>. Insira o caminho do arquivo ISO e clique em <uicontrol>Substituir</uicontrol>.</li>
-<li>Para remover um dispositivo de armazenamento, clique no segundo Ãcone com o <uicontrol>traço
-vermelho (-)</uicontrol>. Confirme a exclusão e clique em <uicontrol>OK</uicontrol>.</li>
-<li>Para incluir um dispositivo de armazenamento, clique no terceiro Ãcone com o <uicontrol>sinal de
-mais (+)</uicontrol> verde. Insira um nome de dispositivo e um caminho de arquivo ISO e clique em <uicontrol>Conectar</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="en-us">
-<title>Substituir um CD-ROM da VM</title>
-<shortdesc rev="rev1">à possÃvel substituir o conteúdo do CD-ROM para
-uma máquina virtual após a instalação ser concluÃda.</shortdesc>
-<csbody>
-<ol>
-<li>Assegure-se de que a máquina virtual esteja iniciada.</li>
-<li>No menu Ações, selecione <uicontrol>Gerenciar mÃdia</uicontrol>.</li>
-<li>Para alterar o que está atualmente carregado no CD-ROM, clique no Ãcone <uicontrol>barra
-laranja (/)</uicontrol> próximo ao campo hdc.</li>
-<li>Na página <wintitle>Substituir um CD-ROM da VM</wintitle>, insira
-o caminho do arquivo ISO. Os outros dois campos são somente leitura.</li>
-<li>Clique em <uicontrol>Substituir</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/host.dita b/plugins/kimchi/ui/pages/help/pt_BR/host.dita
deleted file mode 100644
index 88f7eb2..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/host.dita
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="pt-br">
-<title>Host</title>
-<shortdesc>A página <wintitle>Host</wintitle> mostra informações sobre
-o sistema host e permite encerrar, reiniciar e conectar
-ao host.</shortdesc>
-<csbody>
-<p>à possÃvel executar as ações a segur no host:<ul>
-<li>Selecione <uicontrol>Encerrar</uicontrol> para encerrar o sistema
-host.</li>
-<li>Selecione <uicontrol>Reiniciar</uicontrol> para reiniciar o sistema host.</li>
-<li>Selecione <uicontrol>Conectar</uicontrol> para abrir uma conexão VNC
-para o sistema host, se ele já não estiver conectado.</li>
-</ul></p>
-<p>Clique nas seções a seguir para exibir informações sobre o host:<dl>
-<dlentry>
-<dt>Informações básicas</dt>
-<dd>Esta seção exibe a distribuição do sistema operacional do host,
-a versão e o nome do código, bem como o tipo de processador e quantia de
-memória em GB.</dd>
-</dlentry><dlentry>
-<dt>EstatÃsticas do sistema</dt>
-<dd>Esta seção exibe gráficos para mostrar estatÃsticas para CPU, memória,
-E/S de disco e E/S de rede para o host. Selecione <uicontrol>Coletando
-dados depois de sair desta página</uicontrol> para continuar a coletar dados
-quando a guia do host estiver fora de visualização.</dd>
-</dlentry><dlentry>
-<dt>Atualizações de software</dt>
-<dd>Esta seção exibe informações de todos os pacotes que
-possuem atualizações disponÃveis, incluindo nome do pacote, versão, arquitetura
-e repositório. à possÃvel atualizar todos os pacotes listados selecionando <uicontrol>Atualizar
-todos</uicontrol>. Não é possÃvel selecionar pacotes individuais para atualizações.</dd>
-</dlentry><dlentry>
-<dt>Repositórios</dt>
-<dd>Esta seção exibe repositórios que estão associados ao
-sistema host. à possÃvel incluir, ativar, editar ou remover repositórios. Incluir
-um repositório o associa com o sistema host enquanto ativar um repositório
-permite que o host o acesse. Se o seu sistema for Red Hat Enterprise
-Linux ou Fedora, será possÃvel incluir repositórios <filepath>yum</filepath>.
-Se o seu sistema for Ubuntu ou Debian, inclua repositórios <filepath>deb</filepath>.<p>Se
-você estiver trabalhando com repositórios yum, será possÃvel incluir uma verificação de GPG para
-verificar se um pacote desse repositório não foi corrompido.
-Selecione um repositório e, em seguida, <uicontrol>Editar</uicontrol>. Selecione <uicontrol>Sim</uicontrol> para
-ativar a Verificação de GPG e, em seguida, insira uma URL no arquivo-chave de GPG para o
-repositório.</p></dd>
-</dlentry><dlentry>
-<dt>Relatórios de depuração</dt>
-<dd>Esta seção exibe relatórios de depuração, incluindo nome e caminho do arquivo.
-à possÃvel selecionar a partir das opções para gerar um novo relatório ou renomear, remover
-ou fazer o download de um relatório existente.<p>O relatório de depuração é gerado usando
-o comando <cmdname>sosreport</cmdname>. Ele está disponÃvel para distribuições
-Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora
-e Ubuntu. O comando gera um arquivo .tar que contém
-informações de configuração e de diagnóstico, como versão do kernel
-em execução, módulos carregados e arquivos de configuração de sistema e de serviço.
-O comando também executa programas externos para coletar informações adicionais
-e armazena essa saÃda no archive resultante.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/network.dita b/plugins/kimchi/ui/pages/help/pt_BR/network.dita
deleted file mode 100644
index 1585298..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/network.dita
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="pt-br">
-<title>Rede</title>
-<shortdesc>A página <wintitle>Rede</wintitle> exibe informações
-sobre a conexão de rede.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nome da rede</dt>
-<dd>Nome da rede ou <uicontrol>padrão</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado da rede, ativo (verde) ou inativo (vermelho). </dd>
-</dlentry><dlentry>
-<dt>Tipo de rede</dt>
-<dd>Tipo de rede, por exemplo, <uicontrol>NAT</uicontrol> (conversão
-de endereço de rede).</dd>
-</dlentry><dlentry>
-<dt>Interface</dt>
-<dd>Interface de rede, por exemplo, <uicontrol>virbr0</uicontrol> (padrão).</dd>
-</dlentry><dlentry>
-<dt>Espaço de endereço</dt>
-<dd>Endereço IP.</dd>
-</dlentry></dl></p>
-<p>As ações a seguir podem ser selecionadas:<ul>
-<li rev="rev1">Selecione <uicontrol>Iniciar</uicontrol> para iniciar a conexão
-de rede.</li>
-<li>Selecione <uicontrol>Parar</uicontrol> para terminar a conexão de rede.</li>
-<li>Selecione <uicontrol>Excluir</uicontrol> para excluir as informações
-de conexão.</li>
-</ul>Para criar uma rede, clique no Ãcone <uicontrol>mais (+)</uicontrol> na
-parte superior direita da exibição.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="en-us">
-<title>Criar uma rede</title>
-<shortdesc>Crie uma rede.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Digite o nome da rede.</li>
-<li>Clique para selecionar o tipo de rede. <dl rev="rev1"><dlentry>
-<dt><uicontrol>Isolado</uicontrol></dt>
-<dd>Modo isolado. Os Máquinas Virtuais não podem enviar ou receber comunicação para
-ou de sistemas externos.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Modo de Conversão de Endereço de Rede. A comunicação de Máquinas Virtuais com
-sistemas externos usa o endereço IP do host. Os sistemas externos não podem
-iniciar a comunicação com os Máquinas Virtuais.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>bridged</uicontrol></dt>
-<dd>Modo bridged. Os Máquinas Virtuais podem se comunicar com os sistemas externos e
-ser contatados por sistemas externos como se fossem sistemas fÃsicos
-na rede. Para o modo bridged, devem-se especificar informações adicionais
-de destino e de VLAN.</dd>
-</dlentry></dl></li>
-<li>Clique em <uicontrol>Criar</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/storage.dita b/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
deleted file mode 100644
index 03c8cab..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="pt-br">
-<title>Armazenamento</title>
-<shortdesc>A página <wintitle>Armazenamento</wintitle> lista os conjuntos de armazenamentos disponÃveis, inclusive o conjunto de armazenamentos 'padrão' e 'ISO' integrado.
-Se desejar usar seu próprio ISO, inclua-o em seu caminho do conjunto de armazenamentos 'ISO'.</shortdesc>
-<csbody>
-<p>Para cada storage pool, as informações a seguir são exibidas:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Nome do storage pool e porcentagem usada.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado do storage pool, ativo (verde) ou inativo (vermelho). </dd>
-</dlentry><dlentry>
-<dt>Local</dt>
-<dd>Caminho do arquivo para o local do storage pool.</dd>
-</dlentry><dlentry>
-<dt>Tipo</dt>
-<dd>Tipo de storage pool, por exemplo, <uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacidade</dt>
-<dd>Quantia de espaço no storage pool.</dd>
-</dlentry><dlentry>
-<dt>Alocado</dt>
-<dd>Quantia de espaço já alocado no storage pool.</dd>
-</dlentry></dl></p>
-<p>As ações a seguir podem ser selecionadas para cada storage pool:<ul>
-<li>Selecione <uicontrol>Ativar</uicontrol> para ativar o storage pool
-para que ele possa ser usado.</li>
-<li>Selecione <uicontrol>Desativar</uicontrol> para desativar um storage pool
-ativo.</li>
-<li>Selecione <uicontrol>Indefinir</uicontrol> para remover um storage pool
-inativo.</li>
-</ul></p>
-<p>Para exibir detalhes do volume de armazenamento para um storage pool, clique na
-seta no lado direito da linha do storage pool. Os detalhes incluem
-os seguintes:<dl><dlentry>
-<dt>Tipo</dt>
-<dd>O tipo de volume, por exemplo, <uicontrol>arquivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Formato</dt>
-<dd>O formato, que varia dependendo do tipo.</dd>
-</dlentry><dlentry>
-<dt>Capacidade</dt>
-<dd>Tamanho do volume de armazenamento.</dd>
-</dlentry><dlentry>
-<dt>Alocação</dt>
-<dd>Quantia de espaço já alocado no storage pool.</dd>
-</dlentry></dl>Para definir um storage pool, clique no Ãcone <uicontrol>mais
-(+)</uicontrol> na parte superior direita da exibição.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="en-us">
-<title>Definir um storage pool</title>
-<shortdesc> Defina um storage pool.</shortdesc>
-<csbody>
-<p> <ol>
-<li>No campo <uicontrol>Nome do storage pool</uicontrol>, digite o
-nome a ser usado para identificar o storage pool.</li>
-<li>Na lista <uicontrol>Tipo de storage pool</uicontrol>, selecione o
-tipo: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Especifica um conjunto de diretórios. Ao selecionar <uicontrol>DIR</uicontrol>,
-digite o <uicontrol>Caminho do armazenamento</uicontrol> (caminho do arquivo para o
-storage pool).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Especifica um conjunto de sistema de arquivos de rede. Ao selecionar <uicontrol>NFS</uicontrol>,
-digite o endereço <uicontrol>IP do servidor NFS</uicontrol> e o <uicontrol>Caminho
-do NFS</uicontrol> (caminho do diretório exportado).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Especifica um conjunto com base em um destino alocado em um servidor iSCSI.
-Ao selecionar <uicontrol>iSCSI</uicontrol>, digite o endereço IP do <uicontrol>Servidor
-iSCSI</uicontrol> e o <uicontrol>Destino</uicontrol> no
-servidor iSCSI. Opcionalmente, é possÃvel selecionar para incluir a autenticação iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Lógico</uicontrol></dt>
-<dd>Especifica um storage pool do volume lógico. Selecione o local para
-o dispositivo em <uicontrol>Caminho do dispositivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
-<dd>Especifica um conjunto com base em um Fibre Channel SCSI. Selecione qual
-adaptador SCSI deve ser usado.</dd>
-</dlentry></dl></li>
-<li>Clique em <uicontrol>Criar</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/templates.dita b/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
deleted file mode 100644
index f3c6515..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="pt-br">
-<title>Modelos</title>
-<shortdesc>A página <wintitle>Modelos</wintitle> mostra os modelos de
-máquina virtual definidos que podem ser usados para criar Máquinas Virtuais do KVM.</shortdesc>
-<csbody>
-<p>Para cada modelo, as informações a seguir são exibidas:<dl>
-<dlentry>
-<dt>S.O.</dt>
-<dd>Nome do sistema operacional ou distribuição.</dd>
-</dlentry><dlentry>
-<dt>Versão</dt>
-<dd>Versão do sistema operacional ou distribuição.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Número de processadores que estão definidos para o modelo.</dd>
-</dlentry><dlentry>
-<dt>Memória</dt>
-<dd>Quantia de memória de acesso aleatório a ser alocada, em MB.</dd>
-</dlentry></dl></p>
-<p>As ações a seguir podem ser selecionadas para cada modelo:<ul>
-<li>Selecione <uicontrol>Editar</uicontrol> para editar o modelo.</li>
-<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o modelo.</li>
-</ul>Para incluir um modelo, clique no Ãcone <uicontrol>mais (+)</uicontrol> na
-parte superior direita da exibição.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="en-us">
-<title>Editar modelo</title>
-<shortdesc>Edite um modelo existente.</shortdesc>
-<csbody>
-<p>Para cada modelo, as informações a seguir são exibidas: <dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Nome do modelo.</dd>
-</dlentry><dlentry>
-<dt>Fornecedor</dt>
-<dd>O nome da empresa que criou o sistema operacional ou a distribuição
-que o modelo está configurado para usar.</dd>
-</dlentry><dlentry>
-<dt>Versão</dt>
-<dd>A versão do sistema operacional ou distribuição que o modelo
-está configurado para usar.</dd>
-</dlentry><dlentry>
-<dt>Número de CPU</dt>
-<dd>Número de processadores que estão definidos para o modelo.</dd>
-</dlentry><dlentry>
-<dt>Memória</dt>
-<dd>Quantia de memória em MB a ser alocada para a máquina virtual.</dd>
-</dlentry><dlentry>
-<dt>Disco</dt>
-<dd>O tamanho do disco em GB.</dd>
-</dlentry><dlentry>
-<dt>CD-ROM</dt>
-<dd>O caminho do arquivo para o local do arquivo ISO usado para instalar o
-convidado do KVM.</dd>
-</dlentry><dlentry>
-<dt>storage pool</dt>
-<dd>storage pool especÃfico ou storage pool padrão.</dd>
-</dlentry><dlentry>
-<dt>Rede</dt>
-<dd>As interfaces de rede padrão disponÃveis para o convidado do KVM. à possÃvel
-selecionar diversas redes.</dd>
-</dlentry></dl> Os campos que não estão desativados podem ser editados. Depois
-de editar um campo, clique em <uicontrol>Salvar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Incluir modelo</title>
-<shortdesc>Inclua um modelo a partir da mÃdia de origem.
-à possÃvel incluir sua própria imagem ISO em seu conjunto de armazenamentos 'ISO' para a descoberta a seguir.</shortdesc>
-<csbody>
-<p>Selecione o local da mÃdia de origem a partir das opções a seguir:<dl>
-<dlentry>
-<dt>Imagem ISO local</dt>
-<dd>Selecione para varrer conjuntos de armazenamentos para imagens ISO de instalação disponÃveis
-no sistema.</dd>
-</dlentry><dlentry>
-<dt>Imagem ISO remota</dt>
-<dd>Selecione para especificar um local remoto para uma imagem ISO de instalação.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Incluir modelo - imagem ISO local</title>
-<shortdesc>Inclua um modelo a partir de uma imagem ISO local.</shortdesc>
-<csbody>
-<p>As imagens ISO disponÃveis no sistema são exibidas.<dl><dlentry>
-<dt>S.O.</dt>
-<dd>Nome do sistema operacional ou distribuição.</dd>
-</dlentry><dlentry>
-<dt>Versão</dt>
-<dd>Versão do sistema operacional ou distribuição.</dd>
-</dlentry><dlentry>
-<dt>Tamanho</dt>
-<dd>Tamanho da imagem ISO.</dd>
-</dlentry></dl></p>
-<p>Para criar um modelo a partir de uma imagem ISO, escolha a partir das opções
-a seguir:<ul>
-<li>Selecione uma imagem ISO para criar um modelo a partir dela, em seguida, clique em <uicontrol>Criar
-modelos a partir do ISO selecionado</uicontrol>.</li>
-<li>Selecione <uicontrol>Todos</uicontrol> para criar um modelo a partir de cada
-imagem ISO listada, em seguida, clique em <uicontrol>Criar modelos a partir do
-ISO selecionado</uicontrol>.</li>
-<li>Se a imagem ISO que você deseja usar não aparecer nos resultados de
-varredura, será possÃvel selecionar a partir das opções a seguir:<ul>
-<li>Selecione <uicontrol>Eu desejo usar um arquivo ISO especÃfico</uicontrol> para
-especificar um caminho para a imagem ISO.</li>
-<li>Clique em <uicontrol>Procurar mais ISOs</uicontrol> para procurar mais
-imagens ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am b/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
deleted file mode 100644
index 85ca27a..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-ru_RU_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ru_RU
-
-dist_ru_RU_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/guests.dita b/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
deleted file mode 100644
index 701dd7e..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="ru-ru">
-<title>ÐоÑÑевÑе ÑиÑÑемÑ</title>
-<shortdesc>Ðа ÑÑÑаниÑе <wintitle>ÐоÑÑевÑе ÑиÑÑемÑ</wintitle> показÑваеÑÑÑ ÑпиÑок ÑозданнÑÑ
виÑÑÑалÑнÑÑ
маÑин KVM.</shortdesc>
-<csbody>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ:<dl><dlentry>
-<dt>ÐмÑ</dt>
-<dd>ÐÐ¼Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ.</dd>
-</dlentry><dlentry>
-<dt>ÐÑоÑеÑÑоÑ</dt>
-<dd>ÐÑоÑÐµÐ½Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑоÑеÑÑоÑа в виÑÑÑалÑной маÑине.</dd>
-</dlentry><dlentry>
-<dt>СеÑевой ввод-вÑвод</dt>
-<dd>СкоÑоÑÑÑ ÑеÑевого ввода-вÑвода в ÐÐ/Ñ.</dd>
-</dlentry><dlentry>
-<dt>ÐиÑковÑй ввод-вÑвод</dt>
-<dd>СкоÑоÑÑÑ Ð´Ð¸Ñкового ввода-вÑвода в ÐÐ/Ñ.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>СоÑÑоÑние конÑоли гоÑÑевой опеÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ знаÑок, пÑедÑÑавлÑÑÑий ваÑÐ¸Ð°Ð½Ñ ÐС <tm tmtype="tm" trademark="Linux">Linux</tm>, еÑли гоÑÑÐµÐ²Ð°Ñ ÑиÑÑема не акÑивна.</dd>
-</dlentry></dl></p>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваÑÑÑÑ ÑледÑÑÑие знаÑки дейÑÑвий:<dl>
-<dlentry>
-<dt>СбÑоÑ</dt>
-<dd>СбÑÐ¾Ñ Ð³Ð¾ÑÑевой ÑиÑÑемÑ. </dd>
-</dlentry><dlentry>
-<dt>ÐиÑание (запÑÑк/оÑÑановка)</dt>
-<dd>ÐклÑÑение/вÑклÑÑение пиÑÐ°Ð½Ð¸Ñ Ð³Ð¾ÑÑевой ÑиÑÑемÑ. ÐÑли знаÑок кÑаÑнÑй, пиÑание вÑклÑÑено. ÐÑли знаÑок зеленÑй, пиÑание вклÑÑено.</dd>
-</dlentry></dl> </p>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ ÑледÑÑÑие дейÑÑвиÑ:<ul>
-<li><uicontrol>ÐодклÑÑиÑÑÑÑ</uicontrol> - подклÑÑиÑÑÑÑ Ðº Ñдаленной конÑоли гоÑÑевой опеÑаÑионной ÑиÑÑемÑ.</li>
-<li><uicontrol>УпÑавление ноÑиÑелÑми</uicontrol> - изменение пÑÑи к ÑÑÑановоÑÐ½Ð¾Ð¼Ñ Ð½Ð¾ÑиÑелÑ.</li>
-<li><uicontrol>СбÑоÑ</uicontrol> - ÑбÑÐ¾Ñ Ð³Ð¾ÑÑевой ÑиÑÑемÑ.</li>
-<li><uicontrol>ÐзмениÑÑ</uicontrol> - наÑÑÑойка ÑвойÑÑв гоÑÑевой ÑиÑÑемÑ. СвойÑÑва гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð¶Ð½Ð¾ изменÑÑÑ, ÑолÑко когда ÑиÑÑема оÑÑановлена.</li>
-<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ð³Ð¾ÑÑевÑÑ ÑиÑÑемÑ.</li>
-</ul>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð³Ð¾ÑÑевой ÑиÑÑÐµÐ¼Ñ (виÑÑÑалÑной маÑинÑ) ÑелкниÑе на знаÑке <uicontrol>плÑÑ
-(+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="ru-ru">
-<title>Создание виÑÑÑалÑной маÑинÑ</title>
-<shortdesc>Создание виÑÑÑалÑной маÑÐ¸Ð½Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñаблона.</shortdesc>
-<csbody>
-<p> <ol>
-<li>ÐведиÑе Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии виÑÑÑалÑной маÑинÑ.</li>
-<li rev="rev1">ÐÑбеÑиÑе Ñаблон. <ul>
-<li>ÐÑли еÑÑÑ ÑаблонÑ, вÑбеÑиÑе Ñаблон в ÑпиÑке.</li>
-<li>ÐÑли Ñаблонов неÑ, ÑелкниÑе на <uicontrol>СоздаÑÑ Ñаблон</uicontrol>, ÑÑÐ¾Ð±Ñ ÑоздаÑÑ Ñаблон.</li>
-</ul></li>
-<li>ЩелкниÑе на <uicontrol>СоздаÑÑ</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="ru-ru">
-<title>Ðзменение гоÑÑевой ÑиÑÑемÑ</title>
-<shortdesc>Ðзменение ÑвойÑÑв ÑÑÑеÑÑвÑÑÑей виÑÑÑалÑной маÑинÑ. ÐекоÑоÑÑе ÑвойÑÑва можно изменÑÑÑ ÑолÑко пока оÑÑановлена гоÑÑÐµÐ²Ð°Ñ ÑÑеда. ÐÑÑгие вÑÑÑпаÑÑ Ð² ÑÐ¸Ð»Ñ Ð¿Ð¾Ñле ÑледÑÑÑей пеÑезагÑÑзки.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð½Ð° вкладке <wintitle>ÐбÑие</wintitle>:<dl>
-<dlentry>
-<dt>ÐмÑ</dt>
-<dd>ÐÐ¼Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ. (можно ÑедакÑиÑоваÑÑ Ð¿Ð¾ÐºÐ° оÑÑановлена гоÑÑÐµÐ²Ð°Ñ ÑÑеда)</dd>
-</dlentry><dlentry>
-<dt>ÐÑоÑеÑÑоÑÑ</dt>
-<dd>ЧиÑло пÑоÑеÑÑоÑов. (еÑли гоÑÑÐµÐ²Ð°Ñ ÑÑеда ÑабоÑаеÑ, новое ÑиÑло вÑÑÑÐ¿Ð¸Ñ Ð² ÑÐ¸Ð»Ñ Ð¿Ð¾Ñле пеÑезагÑÑзки)</dd>
-</dlentry><dlentry>
-<dt>ÐамÑÑÑ</dt>
-<dd>ÐбÑем памÑÑи в ÐÐ. (еÑли гоÑÑÐµÐ²Ð°Ñ ÑÑеда ÑабоÑаеÑ, новое ÑиÑло вÑÑÑÐ¿Ð¸Ñ Ð² ÑÐ¸Ð»Ñ Ð¿Ð¾Ñле пеÑезагÑÑзки)</dd>
-</dlentry><dlentry>
-<dt>ÐнаÑок</dt>
-<dd>ÐÑаÑиÑеÑкое изобÑажение, пÑедÑÑавлÑÑÑее ваÑÐ¸Ð°Ð½Ñ ÐС Linux. Ðно показÑваеÑÑÑ Ð²Ð¼ÐµÑÑо ÑекÑÑего ÑоÑÑоÑниÑ
-(Livetile), когда гоÑÑÐµÐ²Ð°Ñ ÑиÑÑема не акÑивна.</dd>
-</dlentry></dl></p>
-<p>Ðа вкладке <wintitle>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</wintitle> показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ.</p>
-<dl><dlentry>
-<dt>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</dt>
-<dd>ÐоказÑÐ²Ð°ÐµÑ ÑаÑположение Ñайла ISO Ð´Ð»Ñ ÑÑÑановки.</dd>
-</dlentry></dl>
-<p> ÐкÑивнÑе Ð¿Ð¾Ð»Ñ Ð¼Ð¾Ð¶Ð½Ð¾ изменÑÑÑ. ÐоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ñ ÑелкниÑе на <uicontrol>СоÑ
ÑаниÑÑ</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="ru-ru">
-<title>Ðобавление, замена и оÑклÑÑение ÑÑÑÑойÑÑв Ñ
ÑанениÑ</title>
-<shortdesc rev="rev1">РвиÑÑÑалÑной маÑине можно добавлÑÑÑ, заменÑÑÑ Ð¸ оÑклÑÑаÑÑ ÑÑÑÑойÑÑва Ñ
ÑанениÑ. ÐдинÑÑвенное поддеÑживаемое ÑÑÑÑойÑÑво - CDROM. ÐÐ»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑв Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð²ÑполниÑе ÑледÑÑÑие дейÑÑвиÑ:</shortdesc>
-<csbody>
-<ol>
-<li>Рокне <wintitle>ÐзмениÑÑ Ð³Ð¾ÑÑевÑÑ ÑиÑÑемÑ</wintitle> вÑбеÑиÑе <wintitle>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</wintitle>.</li>
-<li>ÐÐ»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ ÑÑÑÑойÑÑва Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑелкниÑе на пеÑвом знаÑке Ñ <uicontrol>оÑанжевой коÑой ÑеÑÑой (/)</uicontrol>. ÐведиÑе пÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO и ÑелкниÑе на <uicontrol>ÐамениÑÑ</uicontrol>.</li>
-<li>ÐÐ»Ñ Ð¾ÑклÑÑÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑелкниÑе на вÑоÑом знаÑке Ñ <uicontrol>кÑаÑной гоÑизонÑалÑной ÑеÑÑой (-)</uicontrol>. ÐодÑвеÑдиÑе Ñдаление и нажмиÑе ÐºÐ½Ð¾Ð¿ÐºÑ <uicontrol>OK</uicontrol>.</li>
-<li>ÐÐ»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑелкниÑе на ÑÑеÑÑем знаÑке Ñ <uicontrol>зеленÑм плÑÑом
-(+)</uicontrol>. ÐведиÑе Ð¸Ð¼Ñ ÑÑÑÑойÑÑва и пÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO и ÑелкниÑе на <uicontrol>ÐодклÑÑиÑÑ</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="ru-ru">
-<title>Ðамена CDROM виÑÑÑалÑной маÑинÑ</title>
-<shortdesc rev="rev1">Ðо оконÑании ÑÑÑановки можно замениÑÑ ÑодеÑжимое CDROM Ð´Ð»Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ.</shortdesc>
-<csbody>
-<ol>
-<li>ÐапÑÑÑиÑе виÑÑÑалÑнÑÑ Ð¼Ð°ÑинÑ.</li>
-<li>Ð Ð¼ÐµÐ½Ñ ÐейÑÑÐ²Ð¸Ñ Ð²ÑбеÑиÑе <uicontrol>УпÑавление ноÑиÑелÑми</uicontrol>.</li>
-<li>ÐÐ»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ Ð½Ð¾ÑиÑелÑ, вÑÑавленного в CDROM, ÑелкниÑе на знаÑке Ñ <uicontrol>оÑанжевой коÑой ÑеÑÑой
-(/)</uicontrol> ÑÑдом Ñ Ð¿Ð¾Ð»ÐµÐ¼ hdc.</li>
-<li>Ðа ÑÑÑаниÑе <wintitle>Ðамена CDROM виÑÑÑалÑной маÑинÑ</wintitle> введиÑе пÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO. Ðва дÑÑгиÑ
Ð¿Ð¾Ð»Ñ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ ÑолÑко Ð´Ð»Ñ ÑÑениÑ.</li>
-<li>ÐÑбеÑиÑе опÑÐ¸Ñ <uicontrol>ÐамениÑÑ</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/host.dita b/plugins/kimchi/ui/pages/help/ru_RU/host.dita
deleted file mode 100644
index fb72c21..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/host.dita
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="ru-ru">
-<title>ХоÑÑ</title>
-<shortdesc>СÑÑаниÑа <wintitle>ХоÑÑ</wintitle> показÑÐ²Ð°ÐµÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑиÑÑеме Ñ
оÑÑа и позволÑÐµÑ Ð¾ÑÑанавливаÑÑ Ñ
оÑÑ, пеÑезапÑÑкаÑÑ Ñ
оÑÑ Ð¸ подклÑÑаÑÑÑÑ Ðº немÑ.</shortdesc>
-<csbody>
-<p>Ðа Ñ
оÑÑе можно вÑполнÑÑÑ ÑледÑÑÑие дейÑÑвиÑ:<ul>
-<li><uicontrol>ÐавеÑÑиÑÑ ÑабоÑÑ</uicontrol> - оÑÑановиÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа.</li>
-<li><uicontrol>ÐеÑезапÑÑÑиÑÑ</uicontrol> - пеÑезапÑÑÑиÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа.</li>
-<li><uicontrol>ÐодклÑÑиÑÑÑÑ</uicontrol> - оÑкÑÑÑÑ Ñоединение VNC Ñ ÑиÑÑемой Ñ
оÑÑа, еÑли оно еÑе не ÑÑÑановлено.</li>
-</ul></p>
-<p>ЩелкниÑе на ÑледÑÑÑиÑ
ÑазделаÑ
Ð´Ð»Ñ Ð¿ÑоÑмоÑÑа инÑоÑмаÑии о Ñ
оÑÑе:<dl>
-<dlentry>
-<dt>ÐÐ°Ð·Ð¾Ð²Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ</dt>
-<dd>Ð ÑÑом Ñазделе показÑваеÑÑÑ Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑемÑ, его веÑÑÐ¸Ñ Ð¸ кодовое имÑ, а Ñакже Ñип пÑоÑеÑÑоÑа и обÑем памÑÑи в ÐÐ.</dd>
-</dlentry><dlentry>
-<dt>СиÑÑÐµÐ¼Ð½Ð°Ñ ÑÑаÑиÑÑика</dt>
-<dd>Ð ÑÑом Ñазделе показÑваÑÑÑÑ Ð³ÑаÑики, оÑÑажаÑÑие ÑÑаÑиÑÑиÑеÑкÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ пÑоÑеÑÑоÑе, памÑÑи, диÑковом вводе-вÑводе и ÑеÑевом вводе-вÑводе Ð´Ð»Ñ Ñ
оÑÑа. ÐÑбеÑиÑе <uicontrol>Ð¡Ð±Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ
поÑле закÑÑÑÐ¸Ñ ÑÑой ÑÑÑаниÑÑ</uicontrol>, ÑÑÐ¾Ð±Ñ ÑÐ±Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ
пÑодолжалÑÑ Ð¿Ð¾Ñле закÑÑÑÐ¸Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ¸ ХоÑÑ.</dd>
-</dlentry><dlentry>
-<dt>ÐÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑогÑаммного обеÑпеÑениÑ</dt>
-<dd>Ð ÑÑом Ñазделе показÑваеÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð±Ð¾ вÑеÑ
пакеÑаÑ
, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
доÑÑÑÐ¿Ð½Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ, вклÑÑÐ°Ñ Ð¸Ð¼Ñ Ð¿Ð°ÐºÐµÑа, веÑÑиÑ, аÑÑ
иÑекÑÑÑÑ Ð¸ Ñ
ÑанилиÑе. Ðожно обновиÑÑ Ð²Ñе пакеÑÑ Ð² ÑпиÑке ÑелÑком на <uicontrol>ÐбновиÑÑ Ð²Ñе</uicontrol>. ÐÑделÑнÑе пакеÑÑ Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²ÑбÑаÑÑ Ð½ÐµÐ»ÑзÑ.</dd>
-</dlentry><dlentry>
-<dt>Ð¥ÑанилиÑа</dt>
-<dd>Ð ÑÑом Ñазделе показÑваÑÑÑÑ Ñ
ÑанилиÑа, ÑвÑзаннÑе Ñ ÑиÑÑемой Ñ
оÑÑа. Ð¥ÑанилиÑа можно добавлÑÑÑ, акÑивиÑоваÑÑ, изменÑÑÑ Ð¸ ÑдалÑÑÑ. ÐÑи добавлении Ñ
ÑанилиÑе ÑвÑзÑваеÑÑÑ Ñ ÑиÑÑемой Ñ
оÑÑа, пÑи акÑиваÑии Ñ
ÑанилиÑе ÑÑановиÑÑÑ Ð´Ð¾ÑÑÑпнÑм Ð´Ð»Ñ Ñ
оÑÑа. ÐÑли ÑиÑÑема - Red Hat Enterprise Linux или Fedora, можно добавиÑÑ Ñ
ÑанилиÑа <filepath>yum</filepath>.
-ÐÑли ÑиÑÑема - Ubuntu или Debian, добавÑÑе Ñ
ÑанилиÑа <filepath>deb</filepath>.<p>ÐÑи ÑабоÑе Ñ Ñ
ÑанилиÑами yum можно добавиÑÑ Ð¿ÑовеÑÐºÑ GPG Ð´Ð»Ñ Ð¿ÑовеÑки ÑелоÑÑноÑÑи пакеÑов из данного Ñ
ÑанилиÑа.
-ÐÑбеÑиÑе Ñ
ÑанилиÑе и ÑелкниÑе на <uicontrol>ÐзмениÑÑ</uicontrol>. ÐÑбеÑиÑе <uicontrol>Ðа</uicontrol>, ÑÑÐ¾Ð±Ñ Ð²ÐºÐ»ÑÑиÑÑ Ð¿ÑовеÑÐºÑ GPG, и введиÑе URL Ñайла клÑÑей GPG Ð´Ð»Ñ Ñ
ÑанилиÑа.</p></dd>
-</dlentry><dlentry>
-<dt>ÐÑладоÑнÑе оÑÑеÑÑ</dt>
-<dd>Ð ÑÑом Ñазделе показÑваÑÑÑÑ Ð¾ÑладоÑнÑе оÑÑеÑÑ, вклÑÑÐ°Ñ Ð¸Ð¼Ñ Ð¸ пÑÑÑ.
-ÐоÑÑÑÐ¿Ð½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð´Ð»Ñ ÑозданиÑ, пеÑеименованиÑ, ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¸ загÑÑзки оÑÑеÑов.<p>ÐÑладоÑнÑй оÑÑÐµÑ ÑоздаеÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ <cmdname>sosreport</cmdname>. Ðн доÑÑÑпен Ð´Ð»Ñ Red
-Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora и Ubuntu. Ðоманда ÑÐ¾Ð·Ð´Ð°ÐµÑ Ñайл .tar Ñ ÐºÐ¾Ð½ÑигÑÑаÑионной и диагноÑÑиÑеÑкой инÑоÑмаÑией, Ñакой как веÑÑÐ¸Ñ ÑдÑа, загÑÑженнÑе модÑли и ÑÐ°Ð¹Ð»Ñ ÐºÐ¾Ð½ÑигÑÑаÑии ÑиÑÑÐµÐ¼Ñ Ð¸ ÑлÑжб.
-Ðоманда Ñакже вÑполнÑÐµÑ Ð²Ð½ÐµÑние пÑогÑÐ°Ð¼Ð¼Ñ Ð´Ð»Ñ ÑбоÑа дополниÑелÑной инÑоÑмаÑии и ÑоÑ
ÑанÑÐµÑ Ð¸Ñ
вÑвод в ÑезÑлÑÑиÑÑÑÑем аÑÑ
иве.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/network.dita b/plugins/kimchi/ui/pages/help/ru_RU/network.dita
deleted file mode 100644
index 9cdcdd1..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="ru-ru">
-<title>СеÑÑ</title>
-<shortdesc>Ðа ÑÑÑаниÑе <wintitle>СеÑÑ</wintitle> показÑваеÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑеÑевом Ñоединении.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>ÐÐ¼Ñ ÑеÑи</dt>
-<dd>ÐÐ¼Ñ ÑеÑи или <uicontrol>по ÑмолÑаниÑ</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>СоÑÑоÑние</dt>
-<dd>СоÑÑоÑние ÑеÑи - акÑÐ¸Ð²Ð½Ð°Ñ (зеленÑй) или неакÑÐ¸Ð²Ð½Ð°Ñ (кÑаÑнÑй). </dd>
-</dlentry><dlentry>
-<dt>Тип ÑеÑи</dt>
-<dd>Тип ÑеÑи, напÑÐ¸Ð¼ÐµÑ <uicontrol>NAT</uicontrol> (пÑеобÑазование ÑеÑевÑÑ
адÑеÑов).</dd>
-</dlentry><dlentry>
-<dt>ÐнÑеÑÑейÑ</dt>
-<dd>СеÑевой инÑеÑÑейÑ, напÑÐ¸Ð¼ÐµÑ <uicontrol>virbr0</uicontrol> (по ÑмолÑаниÑ).</dd>
-</dlentry><dlentry>
-<dt>ÐдÑеÑное пÑоÑÑÑанÑÑво</dt>
-<dd>IP-адÑеÑ.</dd>
-</dlentry></dl></p>
-<p>ÐоÑÑÑÐ¿Ð½Ñ ÑледÑÑÑие дейÑÑвиÑ:<ul>
-<li rev="rev1"><uicontrol>ÐапÑÑÑиÑÑ</uicontrol> - оÑкÑÑÑÑ ÑеÑевое Ñоединение.</li>
-<li><uicontrol>ÐÑÑановиÑÑ</uicontrol> - закÑÑÑÑ ÑеÑевое Ñоединение.</li>
-<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñоединении.</li>
-</ul>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑеÑи ÑелкниÑе на знаÑке <uicontrol>плÑÑа (+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="ru-ru">
-<title>Создание ÑеÑи</title>
-<shortdesc>Создание ÑеÑи.</shortdesc>
-<csbody>
-<p> <ol>
-<li>ÐведиÑе Ð¸Ð¼Ñ ÑеÑи.</li>
-<li>ÐÑбеÑиÑе Ñип ÑеÑи. <dl rev="rev1"><dlentry>
-<dt><uicontrol>ÐзолиÑованнÑй</uicontrol></dt>
-<dd>ÐзолиÑованнÑй Ñежим. ÐоÑÑевÑе ÑиÑÑÐµÐ¼Ñ Ð½Ðµ могÑÑ Ð¾Ð±Ð¼ÐµÐ½Ð¸Ð²Ð°ÑÑÑÑ Ð´Ð°Ð½Ð½Ñми Ñ Ð²Ð½ÐµÑними ÑиÑÑемами.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Режим пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑеÑевÑÑ
адÑеÑов. Ðбмен даннÑми Ð¼ÐµÐ¶Ð´Ñ Ð³Ð¾ÑÑевÑми и внеÑними ÑиÑÑемами оÑÑÑеÑÑвлÑеÑÑÑ ÑеÑез IP-адÑÐµÑ Ñ
оÑÑа. ÐнеÑние ÑиÑÑÐµÐ¼Ñ Ð½Ðµ могÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑаÑÑÑÑ Ðº гоÑÑевÑм.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>ЧеÑез моÑÑ</uicontrol></dt>
-<dd>Режим ÑабоÑÑ ÑеÑез моÑÑ. ÐоÑÑевÑе ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð³ÑÑ Ð¾Ð±Ð¼ÐµÐ½Ð¸Ð²Ð°ÑÑÑÑ Ð´Ð°Ð½Ð½Ñми Ñ Ð²Ð½ÐµÑними ÑиÑÑемами, и внеÑние ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð³ÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑаÑÑÑÑ Ðº гоÑÑевÑм, как еÑли Ð±Ñ Ñе бÑли ÑизиÑеÑкими ÑиÑÑемами в ÑеÑи. Ð Ñежиме ÑабоÑÑ ÑеÑез моÑÑ Ð½ÐµÐ¾Ð±Ñ
одимо ÑказаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñелевом ÑаÑположении и VLAN.</dd>
-</dlentry></dl></li>
-<li>ЩелкниÑе на <uicontrol>СоздаÑÑ</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/storage.dita b/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
deleted file mode 100644
index fa37edc..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="ru-ru">
-<title>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</title>
-<shortdesc>Ðа ÑÑÑаниÑе <wintitle>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</wintitle> показÑваеÑÑÑ ÑпиÑок доÑÑÑпнÑÑ
пÑлов памÑÑи, вклÑÑÐ°Ñ Ð¿ÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи 'по ÑмолÑаниÑ' и 'ISO'.
-ÐÑли Ð²Ñ Ñ
оÑиÑе иÑполÑзоваÑÑ ÑобÑÑвеннÑй ISO, добавÑÑе его в пÑÑÑ Ð´Ð¸Ñковой памÑÑи 'ISO'.</shortdesc>
-<csbody>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑла памÑÑи показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ:<dl>
-<dlentry>
-<dt>ÐмÑ</dt>
-<dd>ÐÐ¼Ñ Ð¿Ñла памÑÑи и пÑоÑÐµÐ½Ñ Ð¸ÑполÑзованиÑ.</dd>
-</dlentry><dlentry>
-<dt>СоÑÑоÑние</dt>
-<dd>СоÑÑоÑние пÑла памÑÑи - акÑивнÑй (зеленÑй) или неакÑивнÑй (кÑаÑнÑй). </dd>
-</dlentry><dlentry>
-<dt>РаÑположение</dt>
-<dd>ÐÑÑÑ Ðº ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñла памÑÑи.</dd>
-</dlentry><dlentry>
-<dt>Тип</dt>
-<dd>Тип пÑла памÑÑи, напÑÐ¸Ð¼ÐµÑ <uicontrol>каÑалог</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>ÐмкоÑÑÑ</dt>
-<dd>ÐбÑем пÑла памÑÑи.</dd>
-</dlentry><dlentry>
-<dt>ÐÑделено</dt>
-<dd>ÐбÑем вÑделенной памÑÑи в пÑле.</dd>
-</dlentry></dl></p>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑла памÑÑи можно вÑбиÑаÑÑ ÑледÑÑÑие дейÑÑвиÑ:<ul>
-<li><uicontrol>ÐкÑивиÑоваÑÑ</uicontrol> - акÑивиÑоваÑÑ Ð¿Ñл памÑÑи, ÑÑÐ¾Ð±Ñ ÐµÐ³Ð¾ можно бÑло иÑполÑзоваÑÑ.</li>
-<li><uicontrol>ÐеакÑивиÑоваÑÑ</uicontrol> - деакÑивиÑоваÑÑ Ð°ÐºÑивнÑй пÑл памÑÑи.</li>
-<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ð½ÐµÐ°ÐºÑивнÑй пÑл памÑÑи.</li>
-</ul></p>
-<p>ÐÐ»Ñ Ð¿ÑоÑмоÑÑа Ñведений о ÑомаÑ
пÑла памÑÑи ÑелкниÑе на ÑÑÑелке в пÑавой ÑаÑÑи ÑÑÑоки пÑла памÑÑи. Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð²ÐºÐ»ÑÑаÑÑ:<dl><dlentry>
-<dt>Тип</dt>
-<dd>Тип Ñома, напÑÐ¸Ð¼ÐµÑ <uicontrol>Ñайл</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>ФоÑмаÑ</dt>
-<dd>ФоÑÐ¼Ð°Ñ (завиÑÐ¸Ñ Ð¾Ñ Ñипа).</dd>
-</dlentry><dlentry>
-<dt>ÐмкоÑÑÑ</dt>
-<dd>Ð Ð°Ð·Ð¼ÐµÑ Ñома.</dd>
-</dlentry><dlentry>
-<dt>ÐÑделение</dt>
-<dd>ÐбÑем вÑделенной памÑÑи в пÑле.</dd>
-</dlentry></dl>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñла памÑÑи ÑелкниÑе на знаÑке <uicontrol>плÑÑа (+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="ru-ru">
-<title>Создание пÑла памÑÑи</title>
-<shortdesc> Создание пÑла памÑÑи.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Рполе <uicontrol>ÐÐ¼Ñ Ð¿Ñла памÑÑи</uicontrol> введиÑе Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии пÑла памÑÑи.</li>
-<li>Ð ÑпиÑке <uicontrol>Тип пÑла памÑÑи</uicontrol> вÑбеÑиÑе Ñип: <dl><dlentry>
-<dt><uicontrol>ÐаÑалог</uicontrol></dt>
-<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл-каÑалог. ÐÑи вÑбоÑе Ñипа <uicontrol>ÐаÑалог</uicontrol> заполниÑе поле
-<uicontrol>ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи</uicontrol> (пÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи в Ñайловой ÑиÑÑеме).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл на оÑнове ÑеÑевой Ñайловой ÑиÑÑемÑ. ÐÑи вÑбоÑе <uicontrol>NFS</uicontrol> ÑкажиÑе адÑÐµÑ Ð²
-поле <uicontrol>IP-адÑÐµÑ ÑеÑвеÑа NFS</uicontrol> и пÑÑÑ Ðº ÑкÑпоÑÑиÑÐ¾Ð²Ð°Ð½Ð½Ð¾Ð¼Ñ ÐºÐ°ÑÐ°Ð»Ð¾Ð³Ñ Ð² поле <uicontrol>ÐÑÑÑ NFS</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл на оÑнове Ñелевого обÑекÑа, вÑделенного на ÑеÑвеÑе iSCSI.
-ÐÑи вÑбоÑе Ñипа <uicontrol>iSCSI</uicontrol> ÑкажиÑе IP-адÑÐµÑ Ð² поле <uicontrol>СеÑÐ²ÐµÑ iSCSI</uicontrol> и Ñелевой обÑÐµÐºÑ Ð½Ð° ÑеÑвеÑе iSCSI в поле <uicontrol>Целевой обÑекÑ</uicontrol>. Ðожно Ñакже добавиÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¸Ñ iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>ÐогиÑеÑкий</uicontrol></dt>
-<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл памÑÑи на оÑнове логиÑеÑкого Ñома. ÐÑбеÑиÑе ÑаÑположение ÑÑÑÑойÑÑва в поле <uicontrol>ÐÑÑÑ Ðº ÑÑÑÑойÑÑвÑ</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
-<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл на оÑнове SCSI Fibre Channel. ÐÑбеÑиÑе адапÑÐµÑ SCSI.</dd>
-</dlentry></dl></li>
-<li>ЩелкниÑе на <uicontrol>СоздаÑÑ</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/templates.dita b/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
deleted file mode 100644
index 27ce4ae..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="ru-ru">
-<title>ШаблонÑ</title>
-<shortdesc>Ðа ÑÑÑаниÑе <wintitle>ШаблонÑ</wintitle> показÑваÑÑÑÑ ÑозданнÑе ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð²Ð¸ÑÑÑалÑнÑÑ
маÑин, коÑоÑÑе можно иÑполÑзоваÑÑ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð³Ð¾ÑÑевÑÑ
ÑиÑÑем KVM.</shortdesc>
-<csbody>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñаблона показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ:<dl>
-<dlentry>
-<dt>ÐС</dt>
-<dd>ÐÐ¼Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
-</dlentry><dlentry>
-<dt>ÐеÑÑиÑ</dt>
-<dd>ÐеÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
-</dlentry><dlentry>
-<dt>ÐÑоÑеÑÑоÑÑ</dt>
-<dd>ÐолиÑеÑÑво пÑоÑеÑÑоÑов Ð´Ð»Ñ Ñаблона.</dd>
-</dlentry><dlentry>
-<dt>ÐамÑÑÑ</dt>
-<dd>ÐÑделÑемÑй обÑем опеÑаÑивной памÑÑи в ÐÐ.</dd>
-</dlentry></dl></p>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñаблона можно вÑбиÑаÑÑ ÑледÑÑÑие дейÑÑвиÑ:<ul>
-<li><uicontrol>ÐзмениÑÑ</uicontrol> - измениÑÑ Ñаблон.</li>
-<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ñаблон.</li>
-</ul>ÐÐ»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñаблона ÑелкниÑе на знаÑке <uicontrol>плÑÑа (+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="ru-ru">
-<title>ÐзмениÑÑ Ñаблон</title>
-<shortdesc>ÐзмениÑÑ ÑÑÑеÑÑвÑÑÑий Ñаблон.</shortdesc>
-<csbody>
-<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñаблона показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ: <dl>
-<dlentry>
-<dt>ÐмÑ</dt>
-<dd>ÐÐ¼Ñ Ñаблона.</dd>
-</dlentry><dlentry>
-<dt>ÐендоÑ</dt>
-<dd>ÐÐ¼Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸, ÑоздавÑей опеÑаÑионнÑÑ ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑÐ¸Ð°Ð½Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑемÑ, Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾ÑоÑÑÑ
наÑÑÑаиваеÑÑÑ Ñаблон.</dd>
-</dlentry><dlentry>
-<dt>ÐеÑÑиÑ</dt>
-<dd>ÐеÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ, Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾ÑоÑÑÑ
наÑÑÑаиваеÑÑÑ Ñаблон.</dd>
-</dlentry><dlentry>
-<dt>ÐолиÑеÑÑво пÑоÑеÑÑоÑов</dt>
-<dd>ÐолиÑеÑÑво пÑоÑеÑÑоÑов Ð´Ð»Ñ Ñаблона.</dd>
-</dlentry><dlentry>
-<dt>ÐамÑÑÑ</dt>
-<dd>ÐбÑем памÑÑи в ÐÐ, вÑделÑемÑй виÑÑÑалÑной маÑине.</dd>
-</dlentry><dlentry>
-<dt>ÐиÑк</dt>
-<dd>Ð Ð°Ð·Ð¼ÐµÑ Ð´Ð¸Ñка в ÐÐ.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>ÐÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO Ð´Ð»Ñ ÑÑÑановки гоÑÑевой ÑиÑÑÐµÐ¼Ñ KVM.</dd>
-</dlentry><dlentry>
-<dt>ÐÑл памÑÑи</dt>
-<dd>ÐпÑеделеннÑй пÑл памÑÑи или пÑл памÑÑи по ÑмолÑаниÑ.</dd>
-</dlentry><dlentry>
-<dt>СеÑÑ</dt>
-<dd>СеÑевÑе инÑеÑÑейÑÑ Ð¿Ð¾ ÑмолÑаниÑ, доÑÑÑпнÑе Ð´Ð»Ñ Ð³Ð¾ÑÑевой ÑиÑÑÐµÐ¼Ñ KVM. Ðожно вÑбÑаÑÑ Ð½ÐµÑколÑко ÑеÑей.</dd>
-</dlentry></dl> ÐкÑивнÑе Ð¿Ð¾Ð»Ñ Ð¼Ð¾Ð¶Ð½Ð¾ изменÑÑÑ. ÐоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ñ ÑелкниÑе на <uicontrol>СоÑ
ÑаниÑÑ</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Ðобавление Ñаблона</title>
-<shortdesc>Ðобавление Ñаблона Ñ Ð¸ÑÑ
одного ноÑиÑелÑ. ÐобавÑÑе ÑобÑÑвеннÑй обÑаз ISO в диÑковÑÑ Ð¿Ð°Ð¼ÑÑÑ ISO Ð´Ð»Ñ Ð´Ð°Ð»ÑнейÑего поиÑка.</shortdesc>
-<csbody>
-<p>ÐÑбеÑиÑе один из ÑледÑÑÑиÑ
ваÑианÑов ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ÑÑ
одного ноÑиÑелÑ:<dl>
-<dlentry>
-<dt>ÐокалÑнÑй обÑаз ISO</dt>
-<dd>ÐÑбеÑиÑе ÑÑÐ¾Ñ Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка ÑÑÑановоÑнÑÑ
обÑазов ISO в локалÑнÑÑ
пÑлаÑ
памÑÑи ÑиÑÑемÑ.</dd>
-</dlentry><dlentry>
-<dt>УдаленнÑй обÑаз ISO</dt>
-<dd>ÐÑбеÑиÑе ÑÑÐ¾Ñ Ð²Ð°ÑианÑ, ÑÑÐ¾Ð±Ñ ÑказаÑÑ Ñдаленное ÑаÑположение ÑÑÑановоÑного обÑаза ISO.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Ðобавление Ñаблона (локалÑнÑй обÑаз ISO)</title>
-<shortdesc>Ðобавление Ñаблона из локалÑного обÑаза ISO.</shortdesc>
-<csbody>
-<p>ÐÑдÑÑ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ Ð¾Ð±ÑÐ°Ð·Ñ ISO, доÑÑÑпнÑе в ÑиÑÑеме.<dl><dlentry>
-<dt>ÐС</dt>
-<dd>ÐÐ¼Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
-</dlentry><dlentry>
-<dt>ÐеÑÑиÑ</dt>
-<dd>ÐеÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
-</dlentry><dlentry>
-<dt>РазмеÑ</dt>
-<dd>Ð Ð°Ð·Ð¼ÐµÑ Ð¾Ð±Ñаза ISO.</dd>
-</dlentry></dl></p>
-<p>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñаблона из обÑаза ISO вÑбеÑиÑе один из ÑледÑÑÑиÑ
ваÑианÑов:<ul>
-<li>ÐÑбеÑиÑе обÑаз ISO, из коÑоÑого нÑжно ÑоздаÑÑ Ñаблон, заÑем ÑелкниÑе на <uicontrol>СоздаÑÑ ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð¸Ð· вÑбÑаннÑÑ
обÑазов ISO</uicontrol>.</li>
-<li>ÐÑбеÑиÑе <uicontrol>ÐÑе</uicontrol>, ÑÑÐ¾Ð±Ñ ÑоздаÑÑ Ñаблон из каждого обÑаза ISO в ÑпиÑке, заÑем ÑелкниÑе на <uicontrol>СоздаÑÑ ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð¸Ð· вÑбÑаннÑÑ
обÑазов ISO</uicontrol>.</li>
-<li>ÐÑли ÑÑебÑемÑй обÑаз ISO оÑÑÑÑÑÑвÑÐµÑ Ð² ÑезÑлÑÑаÑаÑ
поиÑка, вÑбеÑиÑе один из ÑледÑÑÑиÑ
ваÑианÑов:<ul>
-<li>ÐÑбеÑиÑе <uicontrol>ÐÑполÑзоваÑÑ ÐºÐ¾Ð½ÐºÑеÑнÑй Ñайл ISO</uicontrol>, ÑÑÐ¾Ð±Ñ ÑказаÑÑ Ð¿ÑÑÑ Ðº обÑÐ°Ð·Ñ ISO.</li>
-<li>ЩелкниÑе на <uicontrol>ÐоиÑк дополниÑелÑнÑÑ
обÑазов ISO</uicontrol> Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка дополниÑелÑнÑÑ
обÑазов ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am b/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
deleted file mode 100644
index e785048..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-zh_CN_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_CN
-
-dist_zh_CN_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/guests.dita b/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
deleted file mode 100644
index d684af2..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="zh-cn">
-<title>访客</title>
-<shortdesc>â<wintitle>访客</wintitle>â页é¢å示已å®ä¹ç KVM èææºã</shortdesc>
-<csbody>
-<p>å¯¹äºæ¯ä¸ªè®¿å®¢ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl><dlentry>
-<dt>åç§°</dt>
-<dd>èææºçåç§°ã</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>èææºä¸å¤çå¨ä½¿ç¨ç¾åæ¯ã</dd>
-</dlentry><dlentry>
-<dt>ç½ç» I/O</dt>
-<dd>ç½ç»è¾å
¥/è¾åºä¼ è¾éåº¦ï¼æ KB/ç§è®¡ï¼ã</dd>
-</dlentry><dlentry>
-<dt>ç£ç I/O</dt>
-<dd>ç£çè¾å
¥/è¾åºä¼ è¾éåº¦ï¼æ KB/ç§è®¡ï¼ã</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>访客å¤äºéæ´»å¨ç¶ææ¶ï¼è®¿å®¢æä½ç³»ç»æ§å¶å°çç¶æï¼æè
表示 <tm tmtype="tm" trademark="Linux">Linux</tm> ååçç徿 ã</dd>
-</dlentry></dl></p>
-<p>å¯ä¸ºæ¯ä¸ªè®¿å®¢æ¾ç¤ºä»¥ä¸æä½å¾æ ï¼<dl>
-<dlentry>
-<dt>éç½®</dt>
-<dd>å廿¤é¡¹ä»¥é置访客ã</dd>
-</dlentry><dlentry>
-<dt>çµæºï¼å¯å¨æåæ¢ï¼</dt>
-<dd>å廿¤é¡¹ä»¥å¼å¯æå
³é访客ççµæºãå¦æè¯¥å¾æ 为红è²ï¼é£ä¹çµæºå·²å
³éï¼å¦æè¯¥å¾æ 为绿è²ï¼é£ä¹çµæºå·²å¼å¯ã</dd>
-</dlentry></dl> </p>
-<p>å¯ä¸ºæ¯ä¸ªè®¿å®¢éæ©ä»¥ä¸æä½ï¼<ul>
-<li>éæ©<uicontrol>è¿æ¥</uicontrol>ä»¥è¿æ¥å°è®¿å®¢æä½ç³»ç»çè¿ç¨æ§å¶å°ã</li>
-<li>éæ©<uicontrol>管çä»è´¨</uicontrol>ä»¥æ´æ¹å®è£
ä»è´¨çè·¯å¾ã</li>
-<li>éæ©<uicontrol>éç½®</uicontrol>以é置访客ã</li>
-<li>éæ©<uicontrol>ç¼è¾</uicontrol>以ç¼è¾ç°æè®¿å®¢ç屿§ãä»
å½åæ¢æ¶æå¯ç¼è¾è®¿å®¢ã</li>
-<li>éæ©<uicontrol>å é¤</uicontrol>以å é¤è®¿å®¢ã</li>
-</ul>è¦å建访客æèææºï¼è¯·åå»é¡µé¢å³ä¸æ¹ç<uicontrol>å å·é® (+) </uicontrol> 徿 ã</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="zh-cn">
-<title>åå»ºèææº</title>
-<shortdesc>éè¿ä½¿ç¨ç°ææ¨¡æ¿åå»ºèææºã</shortdesc>
-<csbody>
-<p> <ol>
-<li>è¾å
¥ç¨äºæ è¯èææºçåç§°ã</li>
-<li rev="rev1">éæ©æ¨¡æ¿ã<ul>
-<li>å¦ææ¨¡æ¿å·²åå¨ï¼è¯·ä»ææ¾ç¤ºççæ¨¡æ¿ä¸éæ©ã</li>
-<li>妿ä¸åå¨ä»»ä½æ¨¡æ¿ï¼è¯·åå»<uicontrol>å建模æ¿</uicontrol>以å建模æ¿ã</li>
-</ul></li>
-<li>åå»<uicontrol>å建</uicontrol>ã</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="zh-cn">
-<title>ç¼è¾è®¿å®¢</title>
-<shortdesc>ç¼è¾ç°æèææºç屿§ãä¸äºå±æ§åªè½å¨è®¿å®¢å·²åæ¢çæ
åµä¸ç¼è¾ãå
¶ä»å±æ§å°å¨ä¸ä¸æ¬¡å¼å¯¼æ¶çæã</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>å¯¹äºæ¯ä¸ªè®¿å®¢ï¼ä¼å¨â<wintitle>常è§</wintitle>âé项å¡ä¸æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
-<dlentry>
-<dt>åç§°</dt>
-<dd>èææºçåç§°ãï¼åªè½å¨è®¿å®¢å·²åæ¢çæ
åµä¸ç¼è¾ï¼</dd>
-</dlentry><dlentry>
-<dt>CPU æ°</dt>
-<dd>å¤çå¨çæ°ç®ãï¼å¦æè®¿å®¢æ£å¨è¿è¡ï¼æ°æ°éå°å¨ä¸ä¸æ¬¡å¼å¯¼æ¶çæï¼</dd>
-</dlentry><dlentry>
-<dt>å
å</dt>
-<dd>å
åéï¼ä»¥ MB 计ï¼ãï¼å¦æè®¿å®¢æ£å¨è¿è¡ï¼æ°æ°éå°å¨ä¸ä¸æ¬¡å¼å¯¼æ¶çæï¼</dd>
-</dlentry><dlentry>
-<dt>徿 </dt>
-<dd>访客å¤äºéæ´»å¨ç¶ææ¶ï¼è¡¨ç¤ºè¦æ¾ç¤ºç Linux ååçè䏿¯å½åç¶æ (Livetile) çå¾å½¢å¾åã</dd>
-</dlentry></dl></p>
-<p>ä¼å¨â<wintitle>åå¨å¨</wintitle>âé项å¡ä¸æ¾ç¤ºä»¥ä¸ä¿¡æ¯ã</p>
-<dl><dlentry>
-<dt>åå¨å¨</dt>
-<dd>æ¾ç¤ºç¨äºå®è£
ç ISO æä»¶æå¨çä½ç½®ã</dd>
-</dlentry></dl>
-<p> å¯å¯¹æªç¦ç¨çåæ®µè¿è¡ç¼è¾ãç¼è¾å段ä¹åï¼è¯·åå»<uicontrol>ä¿å</uicontrol>ã</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="zh-cn">
-<title>æ·»å ãæ¿æ¢ææç¦»åå¨è®¾å¤</title>
-<shortdesc rev="rev1">æ¨å¯ä»¥å¯¹èææºæ·»å ãæ¿æ¢ææç¦»åå¨è®¾å¤ãå¯ä¸åæ¯æç设å¤ä¸º CDROMãè¦ç¼è¾åå¨è®¾å¤ï¼è¯·éµå¾ªä»¥ä¸æ¥éª¤ï¼</shortdesc>
-<csbody>
-<ol>
-<li>å¨â<wintitle>ç¼è¾è®¿å®¢</wintitle>âçªå£ä¸ï¼éæ©â<wintitle>åå¨å¨</wintitle>âã</li>
-<li>è¦æ¿æ¢åå¨è®¾å¤ï¼è¯·åå»ç¬¬ä¸ä¸ªå¾æ ï¼å¸¦æ<uicontrol>æ©è²ææ (/)</uicontrol>ãè¾å
¥ ISO æä»¶è·¯å¾å¹¶åå»<uicontrol>æ¿æ¢</uicontrol>ã</li>
-<li>è¦æç¦»åå¨è®¾å¤ï¼è¯·åå»ç¬¬äºä¸ªå¾æ ï¼å¸¦æ<uicontrol>红è²çå线 (-)</uicontrol>ã确认å 餿ä½ï¼ç¶ååå»<uicontrol>ç¡®å®</uicontrol>ã</li>
-<li>è¦æ·»å åå¨è®¾å¤ï¼è¯·åå»ç¬¬ä¸ä¸ªå¾æ ï¼å¸¦æ<uicontrol>绿è²å å·é® (+)</uicontrol>ãè¾å
¥è®¾å¤åå ISO æä»¶è·¯å¾å¹¶åå»<uicontrol>æç¦»</uicontrol>ã</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="zh-cn">
-<title>æ¿æ¢ VM ç CDROM</title>
-<shortdesc rev="rev1">å®è£
宿ä¹åï¼æ¨å¯ä»¥æ¿æ¢èææºç CDROM çå
容ã</shortdesc>
-<csbody>
-<ol>
-<li>请确ä¿å·²å¯å¨èææºã</li>
-<li>ä»âæä½âèåä¸ï¼éæ©<uicontrol>管çä»è´¨</uicontrol>ã</li>
-<li>è¦æ´æ¹å½åè£
å
¥å° CDROM ä¸çå
容ï¼è¯·åå» hdc åæ®µæè¾¹ç<uicontrol>æ©è²ææ (/)</uicontrol> 徿 ã</li>
-<li>å¨â<wintitle>æ¿æ¢ VM ç CDROM</wintitle>â页é¢ä¸ï¼è¾å
¥ ISO æä»¶è·¯å¾ãå¦å¤ä¸¤ä¸ªå段为åªè¯»ã</li>
-<li>åå»<uicontrol>æ¿æ¢</uicontrol>ã</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/host.dita b/plugins/kimchi/ui/pages/help/zh_CN/host.dita
deleted file mode 100644
index 78a89c3..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/host.dita
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="zh-cn">
-<title>主æº</title>
-<shortdesc>â<wintitle>主æº</wintitle>â页颿¾ç¤ºæå
³ä¸»æºç³»ç»çä¿¡æ¯ï¼å¹¶ä¸å
许æ¨å¯¹ä¸»æºè¿è¡å
³éãå¯å¨åè¿æ¥ã</shortdesc>
-<csbody>
-<p>å¯å¯¹ä¸»æºæ§è¡ä»¥ä¸æä½ï¼<ul>
-<li>éæ©<uicontrol>å
³é</uicontrol>以å
³é主æºç³»ç»ã</li>
-<li>éæ©<uicontrol>éæ°å¯å¨</uicontrol>以鿰å¯å¨ä¸»æºç³»ç»ã</li>
-<li>éæ©<uicontrol>è¿æ¥</uicontrol>以æå¼ä¸ä¸»æºç³»ç»ç VNC è¿æ¥ï¼å¦æå°æªè¿æ¥ï¼ã</li>
-</ul></p>
-<p>åå»ä»¥ä¸é¨å以æ¾ç¤ºæå
³ä¸»æºçä¿¡æ¯ï¼<dl>
-<dlentry>
-<dt>åºæ¬ä¿¡æ¯</dt>
-<dd>æ¬é¨åæ¾ç¤ºä¸»æºæä½ç³»ç»ååçãçæ¬å代ç å称以åå¤çå¨ç±»ååå
åéï¼ä»¥ GB 计ï¼ã</dd>
-</dlentry><dlentry>
-<dt>ç³»ç»ç»è®¡ä¿¡æ¯</dt>
-<dd>æ¬é¨åæ¾ç¤ºå¾å½¢ï¼ä»¥æ¾ç¤ºä¸»æºæå
³ CPUãå
åãç£ç I/O åç½ç» I/O çç»è®¡ä¿¡æ¯ãéæ©<uicontrol>ç¦»å¼æ¤é¡µé¢ä¹åæ¶éæ°æ®</uicontrol>以继ç»å¨ä¸»æºé项å¡ä¸å¨è§å¾ä¸æ¶æ¶éæ°æ®ã</dd>
-</dlentry><dlentry>
-<dt>è½¯ä»¶æ´æ°</dt>
-<dd>æ¬é¨åæ¾ç¤ºææ´æ°å¯ç¨çææè½¯ä»¶å
çä¿¡æ¯ï¼å
¶ä¸å
æ¬è½¯ä»¶å
åç§°ãçæ¬ãä½ç³»ç»æååå¨åºãå¯éè¿éæ©<uicontrol>å
¨é¨æ´æ°</uicontrol>æ¥æ´æ°æåç¤ºçææè½¯ä»¶å
ãä¸è½éå¯¹æ´æ°éæ©å个软件å
ã</dd>
-</dlentry><dlentry>
-<dt>åå¨åº</dt>
-<dd>æ¬é¨åæ¾ç¤ºä¸ä¸»æºç³»ç»å
³èçåå¨åºãæ¨å¯ä»¥æ·»å ãå¯ç¨ãç¼è¾æé¤å»åå¨åºãå½å¯ç¨åå¨åºä¼å
许主æºå¯¹å
¶è¿è¡è®¿é®æ¶ï¼æ·»å åå¨åºä¼å°å
¶ä¸ä¸»æºç³»ç»å
³èã妿æ¨çç³»ç»ä¸º Red Hat Enterprise Linux æ Fedoraï¼é£ä¹å¯æ·»å <filepath>yum</filepath> åå¨åºã妿æ¨çç³»ç»ä¸º Ubuntu æ Debianï¼é£ä¹è¯·æ·»å <filepath>deb</filepath> åå¨åºã<p>妿è¦å¤ç Yum åå¨åºï¼æ¨å¯ä»¥æ·»å GPG æ£æ¥ä»¥éªè¯æ¤åå¨åºä¸ç软件å
æ¯å¦å·²æåãéæ©ä¸ä¸ªåå¨åºï¼ç¶åéæ©<uicontrol>ç¼è¾</uicontrol>ãéæ©<uicontrol>æ¯</uicontrol>以å¯ç¨ GPG æ£æ¥ï¼ç¶åè¾å
¥åå¨åºä¸ GPG å¯é¥æä»¶ç URLã</p></dd>
-</dlentry><dlentry>
-<dt>è°è¯æ¥å</dt>
-<dd>æ¬é¨åæ¾ç¤ºè°è¯æ¥åï¼å
¶ä¸å
æ¬åç§°åæä»¶è·¯å¾ãæ¨å¯ä»¥ä»é项ä¸è¿è¡éæ©ä»¥çææ°æ¥åï¼æè
å¯¹ç°ææ¥åè¿è¡éå½åãé¤å»æä¸è½½ã<p>è°è¯æ¥åå°ä½¿ç¨
-<cmdname>sosreport</cmdname> å½ä»¤çæã该æ¥åå¯ç¨äº Red
-Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>ãFedora å Ubuntu ååçã该å½ä»¤å°çæå
å«é
ç½®åè¯æä¿¡æ¯ç .tar æä»¶ï¼ä¾å¦ï¼æ£å¨è¿è¡çå
æ ¸çæ¬ãå·²è£
å
¥ç模å以åç³»ç»åæå¡é
ç½®æä»¶ã该å½ä»¤è¿ä¼è¿è¡å¤é¨ç¨åºä»¥æ¶éæ´å¤ä¿¡æ¯å¹¶å°æ¤è¾åºåå¨å¨çæç彿¡£ä¸ã</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/network.dita b/plugins/kimchi/ui/pages/help/zh_CN/network.dita
deleted file mode 100644
index f6aa532..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="zh-cn">
-<title>ç½ç»</title>
-<shortdesc>â<wintitle>ç½ç»</wintitle>â页颿¾ç¤ºæå
³ç½ç»è¿æ¥çä¿¡æ¯ã</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>ç½ç»å</dt>
-<dd>ç½ç»çåç§°æ<uicontrol>缺çå¼</uicontrol>ã</dd>
-</dlentry><dlentry>
-<dt>ç¶æ</dt>
-<dd>ç½ç»çç¶æï¼æ´»å¨ï¼ç»¿è²ï¼æéæ´»å¨ï¼çº¢è²ï¼ã</dd>
-</dlentry><dlentry>
-<dt>ç½ç»ç±»å</dt>
-<dd>ç½ç»ç±»åï¼ä¾å¦ï¼<uicontrol>NAT</uicontrol>ï¼ç½ç»å°å转æ¢ï¼ã</dd>
-</dlentry><dlentry>
-<dt>æ¥å£</dt>
-<dd>ç½ç»æ¥å£ï¼ä¾å¦ï¼<uicontrol>virbr0</uicontrol>ï¼ç¼ºçå¼ï¼ã</dd>
-</dlentry><dlentry>
-<dt>å°å空é´</dt>
-<dd>IP å°åã</dd>
-</dlentry></dl></p>
-<p>å¯ä»¥éæ©ä»¥ä¸æä½ï¼<ul>
-<li rev="rev1">éæ©<uicontrol>å¼å§</uicontrol>以å¼å§ç½ç»è¿æ¥ã</li>
-<li>éæ©<uicontrol>忢</uicontrol>ä»¥ç»æç½ç»è¿æ¥ã</li>
-<li>éæ©<uicontrol>å é¤</uicontrol>以å é¤è¿æ¥ä¿¡æ¯ã</li>
-</ul>è¦å建ç½ç»ï¼è¯·å廿¾ç¤ºå±å³ä¸æ¹ç<uicontrol>å å·é® (+)</uicontrol> 徿 ã</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="zh-cn">
-<title>å建ç½ç»</title>
-<shortdesc>å建ç½ç»ã</shortdesc>
-<csbody>
-<p> <ol>
-<li>è¾å
¥ç½ç»çåç§°ã</li>
-<li>å廿¤é¡¹ä»¥éæ©ç½ç»ç±»åã<dl rev="rev1"><dlentry>
-<dt><uicontrol>é离</uicontrol></dt>
-<dd>é离æ¹å¼ãè®¿å®¢æ æ³åå¤é¨ç³»ç»åééä¿¡æä»å
¶æ¥æ¶éä¿¡ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>ç½ç»å°åè½¬æ¢æ¹å¼ãä»è®¿å®¢å°å¤é¨ç³»ç»çéä¿¡å°ä½¿ç¨ä¸»æº IP å°åãå¤é¨ç³»ç»æ æ³å¯å¨ä¸è®¿å®¢çéä¿¡ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>æ¡¥æ¥</uicontrol></dt>
-<dd>æ¡¥æ¥æ¹å¼ã访客å¯ä¸å¤é¨ç³»ç»è¿è¡éä¿¡å¹¶ä¸ç±ä½ä¸ºç½ç»ä¸çç©çç³»ç»çå¤é¨ç³»ç»èç³»ãå¯¹äºæ¡¥æ¥æ¹å¼ï¼å¿
é¡»æå®éå ç®æ å VLAN ä¿¡æ¯ã</dd>
-</dlentry></dl></li>
-<li>åå»<uicontrol>å建</uicontrol>ã</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/storage.dita b/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
deleted file mode 100644
index cfb09f5..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="zh-cn">
-<title>åå¨å¨</title>
-<shortdesc>â<wintitle>åå¨å¨</wintitle>页é¢å示å¯ç¨å卿± ï¼å
¶ä¸å
æ¬ç°æçâ缺çâåâISOâå卿± ã妿æ¨è¦ä½¿ç¨æ¨èªå·±ç ISOï¼è¯·å°å®æ·»å è³âISOâå卿± è·¯å¾ã</shortdesc>
-<csbody>
-<p>å¯¹äºæ¯ä¸ªå卿± ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
-<dlentry>
-<dt>åç§°</dt>
-<dd>å卿± çå称以å使ç¨ç¾åæ¯ã</dd>
-</dlentry><dlentry>
-<dt>ç¶æ</dt>
-<dd>å卿± çç¶æï¼æ´»å¨ï¼ç»¿è²ï¼æéæ´»å¨ï¼çº¢è²ï¼ã</dd>
-</dlentry><dlentry>
-<dt>ä½ç½® </dt>
-<dd>å卿± æå¨ä½ç½®çæä»¶è·¯å¾ã</dd>
-</dlentry><dlentry>
-<dt>ç±»å</dt>
-<dd>å卿± çç±»åï¼ä¾å¦ï¼<uicontrol>dir</uicontrol>ã</dd>
-</dlentry><dlentry>
-<dt>容é</dt>
-<dd>å卿± ä¸ç空é´éã</dd>
-</dlentry><dlentry>
-<dt>å·²åé
</dt>
-<dd>å卿± ä¸å·²åé
ç空é´éã</dd>
-</dlentry></dl></p>
-<p>å¯ä¸ºæ¯ä¸ªå卿± 鿩以䏿ä½ï¼<ul>
-<li>éæ©<uicontrol>æ¿æ´»</uicontrol>ä»¥æ¿æ´»å卿± 以使å
¶å¯ä½¿ç¨ã</li>
-<li>éæ©<uicontrol>åæ¶æ¿æ´»</uicontrol>ä»¥åæ¶æ¿æ´»æ´»å¨å卿± ã</li>
-<li>éæ©<uicontrol>åæ¶å®ä¹</uicontrol>以é¤å»éæ´»å¨å卿± ã</li>
-</ul></p>
-<p>è¦æ¾ç¤ºå卿± çåå¨å·è¯¦ç»ä¿¡æ¯ï¼è¯·åå»å卿± è¡å³ç«¯çç®å¤´ã详ç»ä¿¡æ¯å
æ¬ä»¥ä¸å
容ï¼<dl><dlentry>
-<dt>ç±»å</dt>
-<dd>å·çç±»åï¼ä¾å¦ï¼<uicontrol>æä»¶</uicontrol>ã</dd>
-</dlentry><dlentry>
-<dt>æ ¼å¼</dt>
-<dd>æ ¼å¼å ç±»åèææä¸åã</dd>
-</dlentry><dlentry>
-<dt>容é</dt>
-<dd>åå¨å·ç大å°ã</dd>
-</dlentry><dlentry>
-<dt>åé
</dt>
-<dd>å卿± ä¸å·²åé
ç空é´éã</dd>
-</dlentry></dl>è¦å®ä¹å卿± ï¼è¯·å廿¾ç¤ºå±å³ä¸æ¹ç<uicontrol>å å·é® (+)</uicontrol> 徿 ã</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="zh-cn">
-<title>å®ä¹å卿± </title>
-<shortdesc> å®ä¹å卿± ã</shortdesc>
-<csbody>
-<p> <ol>
-<li>å¨<uicontrol>å卿± åç§°</uicontrol>åæ®µä¸ï¼è¾å
¥ç¨äºæ è¯å卿± çåç§°ã</li>
-<li>å¨<uicontrol>å卿± ç±»å</uicontrol>å表ä¸ï¼éæ©ç±»åï¼<dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>æå®ç®å½æ± ãå½éæ© <uicontrol>DIR</uicontrol> æ¶ï¼è¾å
¥<uicontrol>åå¨è·¯å¾</uicontrol>ï¼å卿± çæä»¶è·¯å¾ï¼ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>æå®ç½ç»æä»¶ç³»ç»æ± ãå½éæ© <uicontrol>NFS</uicontrol> æ¶ï¼è¾å
¥ <uicontrol>NFS æå¡å¨ IP å°å</uicontrol>å <uicontrol>NFS è·¯å¾</uicontrol>ï¼å·²å¯¼åºç®å½çè·¯å¾ï¼ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>æ ¹æ® iSCSI æå¡å¨ä¸åé
çç®æ æå®æ± ãå½éæ© <uicontrol>iSCSI</uicontrol> æ¶ï¼å¨ iSCSI æå¡å¨ä¸è¾å
¥ <uicontrol>iSCSI æå¡å¨ IP å°å</uicontrol>å<uicontrol>ç®æ </uicontrol>ãæ¨å¯ä»¥éæ©æ§å°éæ©æ·»å iSCSI 认è¯ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>é»è¾</uicontrol></dt>
-<dd>æå®é»è¾å·å卿± ãå¨<uicontrol>设å¤è·¯å¾</uicontrol>ä¸éæ©è®¾å¤çä½ç½®ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI å
纤éé</uicontrol></dt>
-<dd>æ ¹æ® SCSI å
纤ééæå®æ± ãéæ©è¦ä½¿ç¨ç SCSI éé
å¨ã</dd>
-</dlentry></dl></li>
-<li>åå»<uicontrol>å建</uicontrol>ã</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/templates.dita b/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
deleted file mode 100644
index ca50119..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="zh-cn">
-<title>模æ¿</title>
-<shortdesc>â<wintitle>模æ¿</wintitle>â页颿¾ç¤ºå¯ç¨äºå建 KVM 访客çå·²å®ä¹èææºæ¨¡æ¿ã</shortdesc>
-<csbody>
-<p>å¯¹äºæ¯ä¸ªæ¨¡æ¿ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
-<dlentry>
-<dt>æä½ç³»ç»</dt>
-<dd>æä½ç³»ç»æååççåç§°ã</dd>
-</dlentry><dlentry>
-<dt>çæ¬</dt>
-<dd>æä½ç³»ç»æååçççæ¬ã</dd>
-</dlentry><dlentry>
-<dt>CPU æ°</dt>
-<dd>为模æ¿å®ä¹çå¤ç卿°ã</dd>
-</dlentry><dlentry>
-<dt>å
å</dt>
-<dd>è¦åé
çéæºåååå¨éï¼ä»¥ MB 计ï¼ã</dd>
-</dlentry></dl></p>
-<p>å¯ä¸ºæ¯ä¸ªæ¨¡æ¿éæ©ä»¥ä¸æä½ï¼<ul>
-<li>éæ©<uicontrol>ç¼è¾</uicontrol>以ç¼è¾æ¨¡æ¿ã</li>
-<li>éæ©<uicontrol>å é¤</uicontrol>以å 餿¨¡æ¿ã</li>
-</ul>è¦æ·»å 模æ¿ï¼è¯·å廿¾ç¤ºå±å³ä¸æ¹ç<uicontrol>å å·é® (+)</uicontrol> 徿 ã</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="zh-cn">
-<title>ç¼è¾æ¨¡æ¿</title>
-<shortdesc>ç¼è¾ç°ææ¨¡æ¿ã</shortdesc>
-<csbody>
-<p>å¯¹äºæ¯ä¸ªæ¨¡æ¿ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
-<dlentry>
-<dt>åç§°</dt>
-<dd>模æ¿çåç§°ã</dd>
-</dlentry><dlentry>
-<dt>ä¾åºå</dt>
-<dd>å
¬å¸åç§°ï¼è¯¥å
¬å¸åå»ºäºæ¨¡æ¿å·²é
置使ç¨çæä½ç³»ç»æååçã</dd>
-</dlentry><dlentry>
-<dt>çæ¬</dt>
-<dd>模æ¿å·²é
置使ç¨çæä½ç³»ç»æååçççæ¬ã</dd>
-</dlentry><dlentry>
-<dt>CPU æ°é</dt>
-<dd>为模æ¿å®ä¹çå¤ç卿°ã</dd>
-</dlentry><dlentry>
-<dt>å
å</dt>
-<dd>è¦åé
ç»èææºçå
åéï¼ä»¥ MB 计ï¼ã</dd>
-</dlentry><dlentry>
-<dt>ç£ç</dt>
-<dd>ç£ç大å°ï¼ä»¥ GB 计ï¼ã</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>ç¨äºå®è£
KVM 访客ç ISO æä»¶æå¨ä½ç½®çæä»¶è·¯å¾ã</dd>
-</dlentry><dlentry>
-<dt>å卿± </dt>
-<dd>ç¹å®å卿± æç¼ºçå卿± ã</dd>
-</dlentry><dlentry>
-<dt>ç½ç»</dt>
-<dd>å¯ä¾ KVM 访客使ç¨ç缺çç½ç»æ¥å£ãæ¨å¯ä»¥éæ©å¤ä¸ªç½ç»ã</dd>
-</dlentry></dl> å¯å¯¹æªç¦ç¨çåæ®µè¿è¡ç¼è¾ãç¼è¾å段ä¹åï¼è¯·åå»<uicontrol>ä¿å</uicontrol>ã</p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>æ·»å æ¨¡æ¿</title>
-<shortdesc>仿ºä»è´¨ä¸æ·»å 模æ¿ãæ¨å¯ä»¥å°æ¨èªå·±ç ISO æ åæ·»å è³âISOâå卿± 以ç¨äºåç»åç°ã</shortdesc>
-<csbody>
-<p>ä»ä»¥ä¸é项鿩æºä»è´¨æå¨çä½ç½®ï¼<dl>
-<dlentry>
-<dt>æ¬å° ISO æ å</dt>
-<dd>éæ©æ¤é¡¹ä»¥å¯¹ç³»ç»ä¸å¯ç¨çå®è£
ISO æ åçå卿± è¿è¡æ«æã</dd>
-</dlentry><dlentry>
-<dt>è¿ç¨ ISO æ å</dt>
-<dd>éæ©æ¤é¡¹ä»¥æå®å®è£
ISO æ åçè¿ç¨ä½ç½®ã</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>æ·»å æ¨¡æ¿ - æ¬å° ISO æ å</title>
-<shortdesc>仿¬å° ISO æ åæ·»å 模æ¿ã</shortdesc>
-<csbody>
-<p>伿¾ç¤ºç³»ç»ä¸å¯ç¨ç ISO æ åã<dl><dlentry>
-<dt>æä½ç³»ç»</dt>
-<dd>æä½ç³»ç»æååççåç§°ã</dd>
-</dlentry><dlentry>
-<dt>çæ¬</dt>
-<dd>æä½ç³»ç»æååçççæ¬ã</dd>
-</dlentry><dlentry>
-<dt>大å°</dt>
-<dd>ISO æ åç大å°ã</dd>
-</dlentry></dl></p>
-<p>è¦ä» ISO æ åå建模æ¿ï¼è¯·ä»ä»¥ä¸é项ä¸éæ©ï¼<ul>
-<li>éæ©è¦ä»å
¶å建模æ¿ç ISO æ åï¼ç¶ååå»<uicontrol>仿é ISO å建模æ¿</uicontrol>ã</li>
-<li>éæ©<uicontrol>å
¨é¨</uicontrol>以仿¯ä¸ªæå示ç ISO æ åå建模æ¿ï¼ç¶ååå»<uicontrol>仿é ISO å建模æ¿</uicontrol>ã</li>
-<li>妿æ¨è¦ä½¿ç¨ç ISO æ åæªåºç°å¨æ«æç»æä¸ï¼é£ä¹å¯ä»ä»¥ä¸é项ä¸éæ©ï¼<ul>
-<li>éæ©<uicontrol>æè¦ä½¿ç¨ç¹å® ISO æä»¶</uicontrol>以æå® ISO æ åçè·¯å¾ã</li>
-<li>åå»<uicontrol>æç´¢æ´å¤ ISO</uicontrol> 以æç´¢æ´å¤ ISO æ åã</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am b/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
deleted file mode 100644
index 9c8ac26..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-zh_TW_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_TW
-
-dist_zh_TW_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/guests.dita b/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
deleted file mode 100644
index cf73785..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="zh-tw">
-<title>客é«</title>
-<shortdesc>ã<wintitle>客é«</wintitle>ãé 颿ååºå·²å®ç¾©ç KVM èæ¬æ©å¨ã</shortdesc>
-<csbody>
-<p>å°æ¼æ¯ä¸å客é«ï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl><dlentry>
-<dt>å稱</dt>
-<dd>èæ¬æ©å¨çå稱ã</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>èæ¬æ©å¨ä¸èçå¨ä½¿ç¨ççç¾åæ¯ã</dd>
-</dlentry><dlentry>
-<dt>網路 I/O</dt>
-<dd>網路輸å
¥/輸åºå³è¼¸éç (KB/s)ã</dd>
-</dlentry><dlentry>
-<dt>ç£ç¢ I/O</dt>
-<dd>ç£ç¢è¼¸å
¥/輸åºå³è¼¸éç (KB/s)ã</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>客é«ä½æ¥ç³»çµ±ä¸»æ§å°ççæ
ï¼ææ¯è¡¨ç¤º <tm tmtype="tm" trademark="Linux">Linux</tm> ç¼è¡å¥ä»¶çå示ï¼å¦æå®¢é«æªèæ¼ä½ç¨ä¸çæ
ï¼ã</dd>
-</dlentry></dl></p>
-<p>å°æ¼æ¯ä¸å客é«ï¼å°æé¡¯ç¤ºä¸ååä½å示ï¼<dl>
-<dlentry>
-<dt>éè¨</dt>
-<dd>æä¸ä¸å¯éè¨å®¢é«ã</dd>
-</dlentry><dlentry>
-<dt>黿ºï¼ååæåæ¢ï¼</dt>
-<dd>æä¸ä¸å¯éåæéé客é«ç黿ºãå¦æè©²å示çºç´
è²ï¼åè¡¨ç¤ºé»æºééï¼å¦æè©²å示çºç¶ è²ï¼åè¡¨ç¤ºé»æºéåã</dd>
-</dlentry></dl> </p>
-<p>å¯éå°æ¯ä¸å客é«é¸åä¸ååä½ï¼<ul>
-<li>é¸å<uicontrol>飿¥</uicontrol>å¯é£æ¥è³å®¢é«ä½æ¥ç³»çµ±çé 端主æ§å°ã</li>
-<li>é¸å<uicontrol>管çåªé«</uicontrol>å¯è®æ´å®è£åªé«çè·¯å¾ã</li>
-<li>é¸å<uicontrol>éè¨</uicontrol>å¯éè¨å®¢é«ã</li>
-<li>é¸å<uicontrol>編輯</uicontrol>å¯ç·¨è¼¯ç¾æå®¢é«çå
§å®¹ãå
å¨åæ¢æï¼æè½ç·¨è¼¯å®¢é«ã</li>
-<li>é¸å<uicontrol>åªé¤</uicontrol>å¯åªé¤å®¢é«ã</li>
-</ul>è¥è¦å»ºç«å®¢é«æèæ¬æ©å¨ï¼è«æä¸ä¸é¡¯ç¤ºé é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="zh-tw">
-<title>建ç«èæ¬æ©å¨</title>
-<shortdesc>使ç¨ç¾æç¯æ¬å»ºç«èæ¬æ©å¨ã</shortdesc>
-<csbody>
-<p> <ol>
-<li>輸å
¥ç¨ä¾èå¥èæ¬æ©å¨çå稱ã</li>
-<li rev="rev1">é¸åç¯æ¬ã<ul>
-<li>å¦æç¯æ¬åå¨ï¼è«å¾é¡¯ç¤ºçç¯æ¬ä¸é¸åã</li>
-<li>å¦ææ²æç¯æ¬ï¼è«æä¸ä¸<uicontrol>建ç«ç¯æ¬</uicontrol>ä¾å»ºç«ç¯æ¬ã</li>
-</ul></li>
-<li>æä¸ä¸<uicontrol>建ç«</uicontrol>ã</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="zh-tw">
-<title>編輯客é«</title>
-<shortdesc>ç·¨è¼¯ç¾æèæ¬æ©å¨çå
§å®¹ãé¨åå
§å®¹åªè½å¨å®¢é«åæ¢æé²è¡ç·¨è¼¯ãå
¶ä»å
§å®¹å°å¨ä¸ä¸æ¬¡ååæçæã</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>å°æ¼æ¯ä¸å客é«ï¼å°æå¨ã<wintitle>ä¸è¬</wintitle>ãæ¨ç±¤ä¸é¡¯ç¤ºä¸åè³è¨ï¼<dl>
-<dlentry>
-<dt>å稱</dt>
-<dd>èæ¬æ©å¨çå稱ãï¼åªè½å¨å®¢é«åæ¢æé²è¡ç·¨è¼¯ï¼</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>èç卿¸ç®ãï¼å¦æå®¢é«å¨å·è¡ä¸ï¼åæ°æ¸éå°å¨ä¸ä¸æ¬¡ååæçæï¼</dd>
-</dlentry><dlentry>
-<dt>è¨æ¶é«</dt>
-<dd>è¨æ¶é«æ¸é (MB)ãï¼å¦æå®¢é«å¨å·è¡ä¸ï¼åæ°æ¸éå°å¨ä¸ä¸æ¬¡ååæçæï¼</dd>
-</dlentry><dlentry>
-<dt>å示</dt>
-<dd>ç¶å®¢é«ä¸èæ¼ä½ç¨ä¸çæ
æï¼è¦å代ç¾è¡çæ
(Livetile) 顯示ç代表 Linux ç¼è¡å¥ä»¶çå形影åã</dd>
-</dlentry></dl></p>
-<p>ä¸åè³è¨æé¡¯ç¤ºå¨ã<wintitle>å²å</wintitle>ãæ¨ç±¤ä¸ã</p>
-<dl><dlentry>
-<dt>å²åé«</dt>
-<dd>é¡¯ç¤ºç¨æ¼å®è£ç ISO æªæ¡çä½ç½®ã</dd>
-</dlentry></dl>
-<p> å¯ä»¥ç·¨è¼¯æªåç¨çæ¬ä½ã編輯æ¬ä½ä¹å¾ï¼æä¸ä¸<uicontrol>å²å</uicontrol>ã</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="zh-tw">
-<title>æ°å¢ãå代æåé¢å²åè£ç½®</title>
-<shortdesc rev="rev1">æ¨å¯ä»¥æ°å¢ãå代æåé¢èæ¬æ©å¨çå²åè£ç½®ãå¯ä¸åæ¯æ´çè£ç½®æ¯ CDROMãè¥è¦ç·¨è¼¯å²åè£ç½®ï¼è«éµå¾ªä¸åæ¥é©ï¼</shortdesc>
-<csbody>
-<ol>
-<li>å¨ã<wintitle>編輯客é«</wintitle>ãè¦çªä¸ï¼é¸åã<wintitle>å²åé«</wintitle>ãã</li>
-<li>è¥è¦å代å²åè£ç½®ï¼è«æä¸ä¸å«æ<uicontrol>æ©è²æç· (/)</uicontrol> ç第ä¸åå示ã輸å
¥
-ISO æªæ¡è·¯å¾ï¼ç¶å¾æä¸ä¸<uicontrol>å代</uicontrol>ã</li>
-<li>è¥è¦åé¢å²åè£ç½®ï¼è«æä¸ä¸å«æ<uicontrol>ç´
è²æç· (/)</uicontrol> ç第äºåå示ã確èªåªé¤ï¼ç¶å¾æä¸ä¸<uicontrol>確å®</uicontrol>ã</li>
-<li>è¥è¦æ°å¢å²åè£ç½®ï¼è«æä¸ä¸å«æç¶ è²<uicontrol>å è (+)</uicontrol> ç第ä¸åå示ã輸å
¥è£ç½®å稱å
-ISO æªæ¡è·¯å¾ï¼ç¶å¾æä¸ä¸<uicontrol>飿¥</uicontrol>ã</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="zh-tw">
-<title>åä»£èæ¬æ©å¨ç CDROM</title>
-<shortdesc rev="rev1">å®è£å®æä¹å¾ï¼æ¨å¯ä»¥åä»£èæ¬æ©å¨ç CDROM çå
§å®¹ã</shortdesc>
-<csbody>
-<ol>
-<li>確å®èæ¬æ©å¨å·²ååã</li>
-<li>å¾ãåä½ãåè½è¡¨ä¸ï¼é¸å<uicontrol>管çåªé«</uicontrol>ã</li>
-<li>è¥è¦è®æ´ç®åå¨ CDROM ä¸å è¼çå
§å®¹ï¼è«æä¸ä¸ hdc æ¬ä½æéç<uicontrol>æ©è²æç· (/)</uicontrol> å示ã</li>
-<li>å¨ã<wintitle>åä»£èæ¬æ©å¨ç CDROM</wintitle>ãé é¢ä¸ï¼è¼¸å
¥ ISO æªæ¡è·¯å¾ãå¦å¤å
©åæ¬ä½æ¯å¯è®çã</li>
-<li>æä¸ä¸<uicontrol>å代</uicontrol>ã</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/host.dita b/plugins/kimchi/ui/pages/help/zh_TW/host.dita
deleted file mode 100644
index a55aae4..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/host.dita
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="zh-tw">
-<title>主æ©</title>
-<shortdesc>ã<wintitle>主æ©</wintitle>ãé é¢æé¡¯ç¤ºä¸»æ©ç³»çµ±çç¸éè³è¨ï¼ä¸¦å®¹è¨±æ¨ééãéæ°åå以å飿¥å°ä¸»æ©ã</shortdesc>
-<csbody>
-<p>æ¨å¯ä»¥éå°ä¸»æ©å·è¡ä¸ååä½ï¼<ul>
-<li>é¸å<uicontrol>éé</uicontrol>以éé主æ©ç³»çµ±ã</li>
-<li>é¸å<uicontrol>éæ°åå</uicontrol>以鿰åå主æ©ç³»çµ±ã</li>
-<li>é¸å<uicontrol>飿¥</uicontrol>以éåè主æ©ç³»çµ±ç VNC é£ç·ï¼å¦æå°æªé£ç·å°ä¸»æ©ç³»çµ±ï¼ã</li>
-</ul></p>
-<p>æä¸ä¸ä¸ååæ®µä»¥é¡¯ç¤ºä¸»æ©çç¸éè³è¨ï¼<dl>
-<dlentry>
-<dt>åºæ¬è³è¨</dt>
-<dd>æ¤å段æé¡¯ç¤ºä¸»æ©ä½æ¥ç³»çµ±ç¼è¡å¥ä»¶ãçæ¬ãç¨å¼ç¢¼å稱ãèçå¨é¡å以åè¨æ¶é«æ¸é (GB)ã</dd>
-</dlentry><dlentry>
-<dt>系統統è¨è³æ</dt>
-<dd>æ¤å段æé¡¯ç¤ºä¸äºåå½¢ï¼ä»¥é¡¯ç¤ºä¸»æ©ç CPUãè¨æ¶é«ãç£ç¢ I/O å網路 I/O ççµ±è¨è³æãé¸å<uicontrol>é¢éæ¤é é¢ä¹å¾æ¶éè³æ</uicontrol>以å¨ä¸»æ©æ¨ç±¤å¾è¦ç·ä¸æ¶å¤±ä¹å¾ç¹¼çºæ¶éè³æã</dd>
-</dlentry><dlentry>
-<dt>è»é«æ´æ°</dt>
-<dd>æ¤å段æé¡¯ç¤ºå
·æå¯ç¨æ´æ°çææå¥ä»¶çç¸éè³è¨ï¼å
æ¬å¥ä»¶å稱ãçæ¬ãæ¶æ§åå²ååº«ãæ¨å¯ä»¥ééé¸å<uicontrol>å
¨é¨æ´æ°</uicontrol>便´æ°ææååºçå¥ä»¶ãä¸è½é¸ååå¥å¥ä»¶ä»¥é²è¡æ´æ°ã</dd>
-</dlentry><dlentry>
-<dt>å²å庫</dt>
-<dd>æ¤å段æé¡¯ç¤ºè主æ©ç³»çµ±ç¸éè¯çå²ååº«ãæ¨å¯ä»¥æ°å¢ãåç¨ã編輯æç§»é¤å²ååº«ãæ°å¢å²å庫å¯ä½¿å®è主æ©ç³»çµ±ç¸éè¯ï¼èåç¨å²å庫å容許主æ©ååå²å庫ã妿æ¨ç系統æ¯
-Red Hat Enterprise Linux æ Fedoraï¼åå¯ä»¥æ°å¢ <filepath>yum</filepath> å²å庫ã妿æ¨ç系統æ¯
-Ubuntu æ Debianï¼åå¯ä»¥æ°å¢ <filepath>deb</filepath> å²å庫ã<p>å¦ææ¨æ£å¨ä½¿ç¨
-yum å²å庫ï¼åå¯ä»¥æ°å¢ GPG 檢æ¥ä»¥é©èæ¤å²å庫ä¸çæåå¥ä»¶æ¯å¦æªæ¯æãé¸åå²å庫ï¼ç¶å¾é¸å<uicontrol>編輯</uicontrol>ãé¸å<uicontrol>æ¯</uicontrol>以åç¨
-GPG 檢æ¥ï¼ç¶å¾è¼¸å
¥å²å庫ç GPG éé°æªç URLã</p></dd>
-</dlentry><dlentry>
-<dt>é¤é¯å ±å</dt>
-<dd>æ¤å段顯示é¤é¯å ±åï¼å
æ¬åç¨±åæªæ¡è·¯å¾ãæ¨å¯ä»¥é¸åé¸é
以ç¢çæ°å ±åãææ¯éæ°å½åãç§»é¤æä¸è¼ç¾æå ±åã<p>é¤é¯å ±åæ¯ä½¿ç¨
-<cmdname>sosreport</cmdname> æä»¤ç¢ççã該æä»¤å¯ç¨æ¼ Red
-Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>ãFedora
-å Ubuntu ç¼è¡å¥ä»¶ã該æä»¤æç¢ç .tar æªæ¡ï¼å
¶å
å«é
ç½®è診æ·è³è¨ï¼ä¾å¦å·è¡ä¸çæ ¸å¿çæ¬ãå·²è¼å
¥æ¨¡çµä»¥å系統åæåé
ç½®æªæ¡ã該æä»¤éæå·è¡å¤é¨ç¨å¼ä¾æ¶éæ´å¤è³è¨ä¸¦å°æ¤è¼¸åºå²åå¨ç¢ççä¿åæªä¸ã</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/network.dita b/plugins/kimchi/ui/pages/help/zh_TW/network.dita
deleted file mode 100644
index f392060..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="zh-tw">
-<title>網路</title>
-<shortdesc>ã<wintitle>網路</wintitle>ãé é¢æé¡¯ç¤ºç¶²è·¯é£ç·çç¸éè³è¨ã</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>網路å稱</dt>
-<dd>網路çåç¨±ï¼ææ¯<uicontrol>é è¨å¼</uicontrol>ã</dd>
-</dlentry><dlentry>
-<dt>çæ
</dt>
-<dd>網路ççæ
ï¼ä½ç¨ä¸ï¼ç¶ è²ï¼æéä½ç¨ä¸ï¼ç´
è²ï¼ã</dd>
-</dlentry><dlentry>
-<dt>網路é¡å</dt>
-<dd>網路é¡åï¼ä¾å¦ï¼<uicontrol>NAT</uicontrol>ï¼ç¶²åè½æï¼ã</dd>
-</dlentry><dlentry>
-<dt>ä»é¢</dt>
-<dd>網路ä»é¢ï¼ä¾å¦ï¼<uicontrol>virbr0</uicontrol>ï¼é è¨å¼ï¼ã</dd>
-</dlentry><dlentry>
-<dt>ä½å空é</dt>
-<dd>IP ä½åã</dd>
-</dlentry></dl></p>
-<p>å¯é¸åä¸ååä½ï¼<ul>
-<li rev="rev1">é¸å<uicontrol>éå§</uicontrol>以éå§ç¶²è·¯é£ç·ã</li>
-<li>é¸å<uicontrol>忢</uicontrol>ä»¥çµæç¶²è·¯é£ç·ã</li>
-<li>é¸å<uicontrol>åªé¤</uicontrol>以åªé¤é£ç·è³è¨ã</li>
-</ul>è¥è¦å»ºç«ç¶²è·¯ï¼è«æä¸ä¸é¡¯ç¤ºç«é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="zh-tw">
-<title>建ç«ç¶²è·¯</title>
-<shortdesc>建ç«ç¶²è·¯</shortdesc>
-<csbody>
-<p> <ol>
-<li>輸å
¥ç¶²è·¯çå稱ã</li>
-<li>æä¸ä¸ä»¥é¸å網路é¡åã<dl rev="rev1"><dlentry>
-<dt><uicontrol>å·²éé¢</uicontrol></dt>
-<dd>å·²é颿¨¡å¼ã客é«ç¡æ³å°éè¨å³éè³å¤é¨ç³»çµ±ï¼ä¹æ¥æ¶ä¸å°ä¾èªå¤é¨ç³»çµ±çéè¨ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>ç¶²åè½ææ¨¡å¼ãå¾å®¢é«å°å¤é¨ç³»çµ±çéè¨ä½¿ç¨ä¸»æ© IP ä½åãå¤é¨ç³»çµ±ç¡æ³èµ·å§å³éè³å®¢é«çéè¨ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>å·²æ©æ¥</uicontrol></dt>
-<dd>å·²æ©æ¥æ¨¡å¼ã客é«å¯ä»¥èå¤é¨ç³»çµ±éè¨ï¼ä¸¦ä¸å¤é¨ç³»çµ±å¯ä»¥é£æ¥è³å®¢é«ï¼å°±å¦å®¢é«æ¯ç¶²è·¯ä¸ç實é«ç³»çµ±ä¸æ¨£ãå°æ¼å·²æ©æ¥æ¨¡å¼ï¼æ¨å¿
é æå®å
¶ä»ç®çå°å VLAN è³è¨ã</dd>
-</dlentry></dl></li>
-<li>æä¸ä¸<uicontrol>建ç«</uicontrol>ã</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/storage.dita b/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
deleted file mode 100644
index 971619c..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="zh-tw">
-<title>å²åé«</title>
-<shortdesc>ã<wintitle>å²åé«</wintitle>ãé 颿ååºå¯ç¨çå²ååï¼å
æ¬ç¾æå¯ç¨çãé è¨ãå²ååå 'ISO' å²ååã妿è¦ä½¿ç¨æ¨èªå·±ç ISOï¼è«å°å
¶æ°å¢è³ 'ISO' å²ååè·¯å¾ã</shortdesc>
-<csbody>
-<p>å°æ¼æ¯ä¸åå²ååï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl>
-<dlentry>
-<dt>å稱</dt>
-<dd>å²ååçå稱å已使ç¨ç¾åæ¯ã</dd>
-</dlentry><dlentry>
-<dt>çæ
</dt>
-<dd>å²ååççæ
ï¼ä½ç¨ä¸ï¼ç¶ è²ï¼æéä½ç¨ä¸ï¼ç´
è²ï¼ã</dd>
-</dlentry><dlentry>
-<dt>ä½ç½®</dt>
-<dd>å²ååä½ç½®çæªæ¡è·¯å¾ã</dd>
-</dlentry><dlentry>
-<dt>é¡å</dt>
-<dd>å²ååçé¡åï¼ä¾å¦ï¼<uicontrol>dir</uicontrol>ã</dd>
-</dlentry><dlentry>
-<dt>容é</dt>
-<dd>å²ååä¸ç©ºéçæ¸éã</dd>
-</dlentry><dlentry>
-<dt>å·²é
ç½®</dt>
-<dd>å²ååä¸å·²é
ç½®çç©ºéæ¸éã</dd>
-</dlentry></dl></p>
-<p>å¯éå°æ¯ä¸åå²ååé¸åä¸ååä½ï¼<ul>
-<li>é¸å<uicontrol>åå</uicontrol>å¯ååå²ååï¼ä½¿ä¹å¯ä¾ä½¿ç¨ã</li>
-<li>é¸å<uicontrol>åæ¶åå</uicontrol>å¯åæ¶ååä½ç¨ä¸çå²ååã</li>
-<li>é¸å<uicontrol>åæ¶å®ç¾©</uicontrol>å¯ç§»é¤é使ç¨ä¸çå²ååã</li>
-</ul></p>
-<p>è¥è¦é¡¯ç¤ºå²ååçå²åç£åè©³ç´°è³æï¼è«æä¸ä¸å²åååå³å´çç®é ãè©³ç´°è³æå
æ¬ä¸ååé
ï¼<dl><dlentry>
-<dt>é¡å</dt>
-<dd>ç£åçé¡åï¼ä¾å¦ï¼<uicontrol>æªæ¡</uicontrol>ã</dd>
-</dlentry><dlentry>
-<dt>æ ¼å¼</dt>
-<dd>æ ¼å¼ï¼å é¡åèç°ã</dd>
-</dlentry><dlentry>
-<dt>容é</dt>
-<dd>å²åç£åç大å°ã</dd>
-</dlentry><dlentry>
-<dt>é
ç½®</dt>
-<dd>å²ååä¸å·²é
ç½®çç©ºéæ¸éã</dd>
-</dlentry></dl>è¥è¦å®ç¾©å²ååï¼è«æä¸ä¸é¡¯ç¤ºç«é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="zh-tw">
-<title>å®ç¾©å²åå</title>
-<shortdesc> å®ç¾©å²ååã</shortdesc>
-<csbody>
-<p> <ol>
-<li>å¨<uicontrol>å²ååå稱</uicontrol>æ¬ä½ä¸ï¼è¼¸å
¥ç¨ä¾èå¥å²ååçå稱ã</li>
-<li>å¨<uicontrol>å²ååé¡å</uicontrol>æ¸
å®ä¸ï¼é¸åé¡åï¼<dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>æå®ç®éå²ååãç¶é¸å <uicontrol>DIR</uicontrol> æï¼è«è¼¸å
¥<uicontrol>å²åé«è·¯å¾</uicontrol>ï¼å²ååçè·¯å¾ï¼ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>æå®ç¶²è·¯æªæ¡ç³»çµ±å²ååãç¶é¸å <uicontrol>NFS</uicontrol> æï¼è«è¼¸å
¥
-<uicontrol>NFS 伺æå¨ IP</uicontrol> ä½åå <uicontrol>NFS
-è·¯å¾</uicontrol>ï¼å¯åºçç®éçè·¯å¾ï¼ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>æ ¹æå iSCSI 伺æå¨ä¸é
ç½®çç®æ¨ï¼æå®å²ååãç¶é¸å
-<uicontrol>iSCSI</uicontrol> æï¼è«è¼¸å
¥ <uicontrol>iSCSI
-伺æå¨</uicontrol> IP ä½åå iSCSI 伺æå¨ä¸ç<uicontrol>ç®æ¨</uicontrol>ãæ¨å¯ä»¥é¸ææ§å°é¸åæ°å¢ iSCSI éå¥ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>é輯</uicontrol></dt>
-<dd>æå®é輯ç£åå²ååãå¨<uicontrol>è£ç½®è·¯å¾</uicontrol>ä¸é¸æè£ç½®çä½ç½®ã</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI å
çºéé</uicontrol></dt>
-<dd>æ ¹æ SCSI å
çºééæå®å²ååãé¸åè¦ä½¿ç¨ç SCSI é
æ¥å¡ã</dd>
-</dlentry></dl></li>
-<li>æä¸ä¸<uicontrol>建ç«</uicontrol>ã</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/templates.dita b/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
deleted file mode 100644
index 4b3a6a6..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="zh-tw">
-<title>ç¯æ¬</title>
-<shortdesc>ã<wintitle>ç¯æ¬</wintitle>ãé é¢æé¡¯ç¤ºå¯ç¨ä¾å»ºç«
-KVM 客é«çå·²å®ç¾©èæ¬æ©å¨ç¯æ¬ã</shortdesc>
-<csbody>
-<p>å°æ¼æ¯ä¸åç¯æ¬ï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>使¥ç³»çµ±çå稱æç¼è¡å¥ä»¶çå稱ã</dd>
-</dlentry><dlentry>
-<dt>çæ¬</dt>
-<dd>使¥ç³»çµ±ççæ¬æç¼è¡å¥ä»¶ççæ¬ã</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>çºç¯æ¬å®ç¾©çèç卿¸ç®ã</dd>
-</dlentry><dlentry>
-<dt>è¨æ¶é«</dt>
-<dd>è¦é
ç½®ç鍿©ååè¨æ¶é«æ¸é (MB)ã</dd>
-</dlentry></dl></p>
-<p>å¯éå°æ¯ä¸åç¯æ¬é¸åä¸ååä½ï¼<ul>
-<li>é¸å<uicontrol>編輯</uicontrol>å¯ç·¨è¼¯ç¯æ¬ã</li>
-<li>é¸å<uicontrol>åªé¤</uicontrol>å¯åªé¤ç¯æ¬ã</li>
-</ul>è¥è¦å»ºç«ç¯æ¬ï¼è«æä¸ä¸é¡¯ç¤ºç«é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="zh-tw">
-<title>ç·¨è¼¯ç¯æ¬</title>
-<shortdesc>ç·¨è¼¯ç¾æç¯æ¬ã</shortdesc>
-<csbody>
-<p>å°æ¼æ¯ä¸åç¯æ¬ï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl>
-<dlentry>
-<dt>å稱</dt>
-<dd>ç¯æ¬çå稱ã</dd>
-</dlentry><dlentry>
-<dt>便å</dt>
-<dd>建ç«é
ç½®çµ¦ç¯æ¬ä½¿ç¨ä¹ä½æ¥ç³»çµ±æç¼è¡å¥ä»¶çå
¬å¸çå稱ã</dd>
-</dlentry><dlentry>
-<dt>çæ¬</dt>
-<dd>é
ç½®çµ¦ç¯æ¬ä½¿ç¨ä¹ä½æ¥ç³»çµ±æç¼è¡å¥ä»¶ççæ¬ã</dd>
-</dlentry><dlentry>
-<dt>CPU æ¸ç®</dt>
-<dd>çºç¯æ¬å®ç¾©çèç卿¸ç®ã</dd>
-</dlentry><dlentry>
-<dt>è¨æ¶é«</dt>
-<dd>è¦é
ç½®çµ¦èæ¬æ©å¨çè¨æ¶é«æ¸é (MB)ã</dd>
-</dlentry><dlentry>
-<dt>ç£ç¢</dt>
-<dd>ç£ç¢å¤§å° (GB)ã</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>ç¨ä¾å®è£ KVM 客é«ä¹ ISO æªæ¡ä½ç½®çæªæ¡è·¯å¾ã</dd>
-</dlentry><dlentry>
-<dt>å²åå</dt>
-<dd>ç¹å®å²ååæé è¨å²ååã</dd>
-</dlentry><dlentry>
-<dt>網路</dt>
-<dd>KVM 客é«å¯ä½¿ç¨çé è¨ç¶²è·¯ä»é¢ãæ¨å¯ä»¥é¸åå¤å網路ã</dd>
-</dlentry></dl> å¯ä»¥ç·¨è¼¯æªåç¨çæ¬ä½ã編輯æ¬ä½ä¹å¾ï¼æä¸ä¸<uicontrol>å²å</uicontrol>ã</p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>æ°å¢ç¯æ¬</title>
-<shortdesc>å¾ä¾æºåªé«ä¸æ°å¢ç¯æ¬ãæ¨å¯ä»¥å°èªå·±ç ISO æ åæªæ°å¢è³ 'ISO' å²ååï¼ä»¥é²è¡ä¸åæ¢ç´¢ã</shortdesc>
-<csbody>
-<p>å¾ä¸åé¸é
ä¸é¸å便ºåªé«çä½ç½®ï¼<dl>
-<dlentry>
-<dt>æ¬ç«¯ ISO æ åæª</dt>
-<dd>é¸åæ¤é
坿æå²åå以åå¾ç³»çµ±ä¸å¯ç¨çå®è£ ISO æ åæªã</dd>
-</dlentry><dlentry>
-<dt>é 端 ISO æ åæª</dt>
-<dd>é¸åæ¤é
坿å®å®è£ ISO æ åæªçé 端ä½ç½®ã</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>æ°å¢ç¯æ¬ - æ¬ç«¯ ISO æ åæª</title>
-<shortdesc>徿¬ç«¯ ISO æ åæªæ°å¢ç¯æ¬ã</shortdesc>
-<csbody>
-<p>å°æé¡¯ç¤ºç³»çµ±ä¸å¯ç¨ç ISO æ åæªã<dl><dlentry>
-<dt>OS</dt>
-<dd>使¥ç³»çµ±çå稱æç¼è¡å¥ä»¶çå稱ã</dd>
-</dlentry><dlentry>
-<dt>çæ¬</dt>
-<dd>使¥ç³»çµ±ççæ¬æç¼è¡å¥ä»¶ççæ¬ã</dd>
-</dlentry><dlentry>
-<dt>大å°</dt>
-<dd>ISO æ åæªç大å°ã</dd>
-</dlentry></dl></p>
-<p>è¥è¦å¾ ISO æ åæªå»ºç«ç¯æ¬ï¼è«å¾ä¸åé¸é
ä¸é¸æï¼<ul>
-<li>é¸åè¦ç¨ä¾å»ºç«ç¯æ¬ç ISO æ åæªï¼ç¶å¾æä¸ä¸<uicontrol>å¾æé¸ ISO 建ç«ç¯æ¬</uicontrol>ã</li>
-<li>é¸å<uicontrol>å
¨é¨</uicontrol>以徿¯ä¸åååºç ISO æ åæªå»ºç«ç¯æ¬ï¼ç¶å¾æä¸ä¸<uicontrol>å¾æé¸ ISO 建ç«ç¯æ¬</uicontrol>ã</li>
-<li>å¦è¦è¦ä½¿ç¨ç ISO æ åæªæªåºç¾å¨ææçµæä¸ï¼åå¯ä»¥å¾ä¸åé¸é
ä¸é¸æï¼<ul>
-<li>é¸å<uicontrol>ææ³ä½¿ç¨ç¹å®ç ISO æªæ¡</uicontrol>以æå® ISO æ åæªçè·¯å¾ã</li>
-<li>æä¸ä¸<uicontrol>æå°æ´å¤ ISO</uicontrol> 以æå°æ´å¤ ISO æ åæªã</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/host.html.tmpl b/plugins/kimchi/ui/pages/host.html.tmpl
deleted file mode 100644
index d87debc..0000000
--- a/plugins/kimchi/ui/pages/host.html.tmpl
+++ /dev/null
@@ -1,177 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div id="host-root-container">
- <div class="toolbar">
- <div class="tools">
- </div>
- </div>
- <div id="host-content-container" class="empty-when-logged-off"></div>
-</div>
-
-<script id="host-tmpl" type="kimchi/template">
- <div class="host-panel">
- <div class="logo-container">
- <div class="logo" style="background-image: url({logo});"></div>
- </div>
- <div id="host-info-container" class="info-container">
- <h2 class="hostname">{hostname}</h2>
- <div class="action-panel">
- <button id="host-button-shutdown" class="btn-normal-1 stop">
- <div class="button-icon action-icon-stop"></div>
- $_("Shut down")
- </button>
- <button id="host-button-restart" class="btn-normal-1 restart">
- <div class="button-icon action-icon-restart"></div>
- $_("Restart")
- </button>
- <button class="btn-normal-1 connect" disabled="disabled">
- <div class="button-icon action-icon-connect"></div>
- $_("Connect")
- </button>
- </div>
- <div class="host-section">
- <h3 class="section-header"
- aria-expanded="false"
- aria-controls="content-sys-info">
- $_("Basic Information")
- </h3>
- <div id="content-sys-info" class="section-content">
- <div class="section-row">
- <div class="section-label">$_("OS Distro")</div>
- <div class="section-value">{os_distro}</div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("OS Version")</div>
- <div class="section-value">{os_version}</div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("OS Code Name")</div>
- <div class="section-value">{os_codename}</div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("Processor")</div>
- <div class="section-value">{cpu_model}</div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("CPU(s)")</div>
- <div class="section-value">{cpus}</div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("Memory")</div>
- <div class="section-value">{memory}</div>
- </div>
- </div>
- </div>
- <div class="host-section">
- <h3 class="section-header"
- aria-controls="content-sys-statistics">
- $_("System Statistics")
- </h3>
- <div id="content-sys-statistics" class="section-content">
- <div class="section-row">
- <div class="section-label">$_("CPU")</div>
- <div class="section-value">
- <div id="container-chart-cpu" class="inline-block"></div>
- </div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("Memory")</div>
- <div class="section-value">
- <div id="container-chart-memory" class="inline-block"></div>
- </div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("Disk I/O")</div>
- <div class="section-value">
- <div id="container-chart-disk-io" class="inline-block"></div>
- </div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("Network I/O")</div>
- <div class="section-value">
- <div id="container-chart-network-io" class="inline-block"></div>
- </div>
- </div>
- </div>
- </div>
- <div id="software-update-section" class="host-section hidden">
- <h3 class="section-header"
- aria-controls="content-software-update">
- $_("Software Updates")
- </h3>
- <div id="content-software-update" class="section-content">
- <div class="section-row">
- <div class="section-value">
- <div id="software-updates-grid-container"></div>
- <div id="software-updates-progress-container" class="hidden">
- <label for="software-updates-progress-textarea">$_("Update Progress")</label>
- <textarea id="software-updates-progress-textarea" readonly></textarea>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div id="repositories-section" class="host-section hidden">
- <h3 class="section-header"
- aria-controls="content-repositories">
- $_("Repositories")
- </h3>
- <div id="content-repositories" class="section-content">
- <div class="section-row">
- <div class="section-value">
- <div id="repositories-grid-container"></div>
- </div>
- </div>
- </div>
- </div>
- <div id="debug-report-section" class="host-section hidden">
- <h3 class="section-header"
- aria-controls="content-sys-reports">
- $_("Debug Reports")
- </h3>
- <div id="content-sys-reports" class="section-content">
- <div class="section-row">
- <div class="section-value">
- <div id="available-reports-grid-container"></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-</script>
-
-<script type="text/javascript">
- kimchi.host_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/i18n.json.tmpl b/plugins/kimchi/ui/pages/i18n.json.tmpl
deleted file mode 100644
index cd320e0..0000000
--- a/plugins/kimchi/ui/pages/i18n.json.tmpl
+++ /dev/null
@@ -1,187 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-{
- "KCHAUTH6001E": "$_("The username or password you entered is incorrect. Please try again.")",
- "KCHAUTH6002E": "$_("This field is required.")",
-
- "KCHAUTH6001M": "$_("Log in")",
- "KCHAUTH6002M": "$_("Logging in...")",
-
- "Host": "$_("Host")",
- "Guests": "$_("Guests")",
- "Templates": "$_("Templates")",
- "Storage": "$_("Storage")",
- "Network": "$_("Network")",
-
- "KCHAPI6002E": "$_("Failed to get application configuration")",
- "KCHAPI6003E": "$_("This is not a valid Linux path")",
- "KCHAPI6004E": "$_("This is not a valid URL.")",
- "KCHAPI6005E": "$_("No such data available.")",
- "KCHAPI6007E": "$_("Can not contact the host system. Verify the host system is up and that you have network connectivity to it. HTTP request response %1. ")",
- "KCHAPI6008E": "$_("Unable to read file.")",
- "KCHAPI6009E": "$_("Error while uploading file.")",
-
- "KCHAPI6001M": "$_("Delete Confirmation")",
- "KCHAPI6002M": "$_("OK")",
- "KCHAPI6003M": "$_("Cancel")",
- "KCHAPI6004M": "$_("Confirm")",
- "KCHAPI6005M": "$_("Create")",
- "KCHAPI6006M": "$_("Warning")",
- "KCHAPI6007M": "$_("Save")",
- "KCHAPI6008M": "$_("Creating...")",
- "KCHAPI6009M": "$_("Cloning...")",
-
- "KCHGRD6001M": "$_("Loading...")",
- "KCHGRD6002M": "$_("An error occurred while retrieving system information.")",
- "KCHGRD6003M": "$_("Retry")",
- "KCHGRD6004M": "$_("Detailed message:")",
-
- "KCHTMPL6001W": "$_("No ISO found")",
-
- "KCHTMPL6002E": "$_("This is not a valid ISO file.")",
-
- "KCHTMPL6002M": "$_("This may take a long time. Do you want to continue?")",
- "KCHTMPL6003M": "$_("This will permanently delete the template. Would you like to continue?")",
-
- "KCHHOST6001E": "$_("Unable to shut down system as there are some virtual machines running!")",
-
- "KCHHOST6001M": "$_("Max:")",
- "KCHHOST6002M": "$_("Utilization")",
- "KCHHOST6003M": "$_("Available")",
- "KCHHOST6004M": "$_("Read Rate")",
- "KCHHOST6005M": "$_("Write Rate")",
- "KCHHOST6006M": "$_("Received")",
- "KCHHOST6007M": "$_("Sent")",
- "KCHHOST6008M": "$_("Shutting down or restarting host will cause unsaved work lost. Continue to shut down/restarting?")",
-
-
- "KCHREPO6001M": "$_("Confirm")",
- "KCHREPO6002M": "$_("Repository will be removed permanently and can't be recovered. Do you want to continue?")",
- "KCHREPO6003M": "$_("Repositories")",
- "KCHREPO6004M": "$_("ID")",
- "KCHREPO6005M": "$_("Name")",
- "KCHREPO6006M": "$_("Base URL")",
- "KCHREPO6007M": "$_("Is Mirror")",
- "KCHREPO6008M": "$_("URL Args")",
- "KCHREPO6009M": "$_("Enabled")",
- "KCHREPO6010M": "$_("GPG Check")",
- "KCHREPO6011M": "$_("GPG Key")",
- "KCHREPO6012M": "$_("Add")",
- "KCHREPO6013M": "$_("Edit")",
- "KCHREPO6014M": "$_("Remove")",
- "KCHREPO6016M": "$_("Enable")",
- "KCHREPO6017M": "$_("Disable")",
-
-
- "KCHUPD6001M": "$_("Software Updates")",
- "KCHUPD6002M": "$_("Package Name")",
- "KCHUPD6003M": "$_("Version")",
- "KCHUPD6004M": "$_("Architecture")",
- "KCHUPD6005M": "$_("Repository")",
- "KCHUPD6006M": "$_("Update All")",
- "KCHUPD6007M": "$_("Updating...")",
- "KCHUPD6008M": "$_("Failed to retrieve packages update information.")",
- "KCHUPD6009M": "$_("Failed to update package(s).")",
-
-
- "KCHDR6001M": "$_("Debug report will be removed permanently and can't be recovered. Do you want to continue?")",
- "KCHDR6002M": "$_("Debug Reports")",
- "KCHDR6003M": "$_("Name")",
- "KCHDR6005M": "$_("Generated Time")",
- "KCHDR6006M": "$_("Generate")",
- "KCHDR6007M": "$_("Generating...")",
- "KCHDR6008M": "$_("Rename")",
- "KCHDR6009M": "$_("Remove")",
- "KCHDR6010M": "$_("Download")",
- "KCHDR6011M": "$_("Report name should contain only letters, digits, underscore ('_') and/or hyphen ('-').")",
- "KCHDR6012M": "$_("Pending...")",
- "KCHDR6013M": "$_("Report name is the same as the original one.")",
-
- "KCHVM6001M": "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")",
- "KCHVM6002M": "$_("Power off Confirmation")",
- "KCHVM6003M": "$_("This action may produce undesirable results, "
- "for example unflushed disk cache in the guest. "
- "Would you like to continue?")",
- "KCHVM6004M": "$_("Reset Confirmation")",
- "KCHVM6005M": "$_("There is a risk of data loss caused by reset without"
- " the guest OS shutdown. Would you like to continue?")",
- "KCHVM6006M": "$_("Shut Down Confirmation")",
- "KCHVM6007M": "$_("Note the guest OS may ignore this request. Would you like to continue?")",
- "KCHVM6008M": "$_("Virtual Machine delete Confirmation")",
- "KCHVM6009M": "$_("This virtual machine is not persistent. Power Off will delete it. Continue?")",
- "KCHVM6010M": "$_("When the target guest has SCSI or iSCSI volumes, they will be cloned on default storage pool. The same will happen when the target pool does not have enough space to clone the volumes. Do you want to continue?")",
-
- "KCHVMCD6001M": "$_("This CDROM will be detached permanently and you can re-attach it. Continue to detach it?")",
- "KCHVMCD6002M": "$_("Attach")",
- "KCHVMCD6003M": "$_("Attaching...")",
- "KCHVMCD6004M": "$_("Replace")",
- "KCHVMCD6005M": "$_("Replacing...")",
- "KCHVMCD6006M": "$_("Successfully attached!")",
- "KCHVMCD6007M": "$_("Successfully replaced!")",
- "KCHVMCD6008M": "$_("Successfully detached!")",
- "KCHVMCD6009M": "$_("This disk will be detached permanently and you can re-attach it. Continue to detach it?")",
-
- "KCHVMED6001M": "$_("interface:")",
- "KCHVMED6002M": "$_("address:")",
- "KCHVMED6003M": "$_("link_type:")",
- "KCHVMED6004M": "$_("block:")",
- "KCHVMED6005M": "$_("drive_type:")",
- "KCHVMED6006M": "$_("model:")",
- "KCHVMED6007M": "$_("Affected devices:")",
-
- "KCHNET6001E": "$_("The VLAN id must be between 1 and 4094.")",
-
- "KCHNET6001M": "$_("unavailable")",
- "KCHNET6002M": "$_("This action will interrupt network connectivity for any virtual machine that depend on this network.")",
- "KCHNET6003M": "$_("Create a network")",
- "KCHNET6004M": "$_("This network is not persistent. Instead of stop, this action will permanently delete it. Would you like to continue?")",
- "KCHNET6001W": "$_("The bridged VLAN tag may not work well with NetworkManager enabled. You should consider disabling it.")",
-
- "KCHPOOL6001M": "$_("This will permanently delete the storage pool. Would you like to continue?")",
- "KCHPOOL6002M": "$_("This storage pool is empty.")",
- "KCHPOOL6003M": "$_("It will format your disk and you will loose any data in there, are you sure to continue? ")",
- "KCHPOOL6004M": "$_("SCSI Fibre Channel")",
- "KCHPOOL6005M": "$_("No SCSI adapters found.")",
- "KCHPOOL6006M": "$_("Loading iSCSI targets...")",
- "KCHPOOL6007M": "$_("No iSCSI found. Please input one.")",
- "KCHPOOL6008M": "$_("Failed to load iSCSI targets.")",
-
- "KCHPOOL6001E": "$_("The storage pool name can not be blank.")",
- "KCHPOOL6002E": "$_("The storage pool path can not be blank.")",
- "KCHPOOL6003E": "$_("NFS server mount path can not be blank.")",
- "KCHPOOL6005E": "$_("Invalid NFS mount path.")",
- "KCHPOOL6006E": "$_("No logical device selected.")",
- "KCHPOOL6007E": "$_("The iSCSI target can not be blank.")",
- "KCHPOOL6008E": "$_("Server name can not be blank.")",
- "KCHPOOL6009E": "$_("This is not a valid Server Name or IP. Please, modify it.")",
- "KCHPOOL6010M": "$_("Looking for available partitions ...")",
- "KCHPOOL6011M": "$_("No available partitions found.")",
- "KCHPOOL6012M": "$_("This storage pool is not persistent. Instead of deactivate, this action will permanently delete it. Would you like to continue?")",
- "KCHPOOL6013M": "$_("Unable to retrieve partitions information.")",
- "KCHPOOL6014M": "$_("In progress...")",
- "KCHPOOL6015M": "$_("Failed!")",
-
- "KCHVMSTOR0001E": "$_("CDROM path needs to be a valid local/remote path and cannot be blank.")",
- "KCHVMSTOR0002E": "$_("Disk pool or volume cannot be blank.")"
-}
diff --git a/plugins/kimchi/ui/pages/network.html.tmpl b/plugins/kimchi/ui/pages/network.html.tmpl
deleted file mode 100644
index 915feac..0000000
--- a/plugins/kimchi/ui/pages/network.html.tmpl
+++ /dev/null
@@ -1,133 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div class="toolbar">
- <div class="tools" style="display:none">
- <a id="networkAdd" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
- </div>
-</div>
-<div id="network-content" class="network">
- <div class="grid-control"><input type="text" class="filter" placeholder="$_("Filter")"></div>
- <div id="networkGrid" class="list">
- <div>
- <span class="column-name">$_("Network Name")</span><!--
- --><span class="column-state">$_("State")</span><!--
- --><span class="column-type">$_("Network Type")</span><!--
- --><span class="column-interface">$_("Interface")</span><!--
- --><span class="column-space">$_("Address Space")</span><!--
- --><span style="display:none">$_("Actions")</span>
- </div>
- <div id="networkBody" class="empty-when-logged-off"></div>
- </div>
- <div id="networkConfig" class="network-config">
- <div class="section-container">
- <div class="section-header">1. $_("Network Name")</div>
- <div class="section-content">
- <input type="text" id="networkName" />
- <div class="input-hint">
- <span class="icon-info-circled light-grey c1 help-inline"></span>
- <span class="input-hint-text help-inline">$_("Name should not contain '/' and '\"'.")</span>
- </div>
- </div>
- </div>
- <div class="section-container">
- <div class="section-header">2. $_("Network Type")</div>
- <div class="section-content">
- <div class="input-container">
- <input type="radio" id="networkTypeIso" name="networkType" value="isolated" />
- <label for="networkTypeIso">$_("Isolated: no external network connection")</label>
- </div>
- <div class="input-container">
- <input type="radio" id="networkTypeNat" name="networkType" value="nat" />
- <label for="networkTypeNat">$_("NAT: outbound physical network connection only")</label>
- </div>
- <div class="input-container">
- <div class="bridged-inline">
- <input type="radio" id="networkTypeBri" name="networkType" value="bridged" />
- </div>
- <div class="bridged-inline">
- <label for="networkTypeBri">$_("Bridged: Virtual machines are connected to physical network directly")</label><br />
- <label id="networkBriDisabledLabel" style="display:none">$_("(No interfaces found)")</label>
- </div>
- </div>
- <div id="bridgeOptions">
- <div>
- <div class="bridge-option-column">
- <label for="networkInterface">$_("Destination"): </label>
- </div>
- <div class="bridge-option-column">
- <div class="network-type-wrapper-controls">
- <div id ="networkDestinationID">
- <input id="networkDestinationInputId" name="type" type="hidden"/>
- <span id="networkDestinationLabel" type="text"></span><span class="arrow"></span>
- <div>
- <ul id="networkInterface"></ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div>
- <input id="enableVlan" type="checkbox" value="" />
- <label for="enableVlan" id="labelEnableVlan">$_("Enable VLAN") </label>
- </div>
- <label for="networkVlanID" id="labelNetworkVlanID">$_("VLAN ID"): </label>
- <input type="text" id="networkVlanID" class="network-label"/>
- </div>
- </div>
- </div>
- </div>
- </div>
-</div>
-<script id="networkItem" type="text/html">
- <div id='{name}' class='remove-when-logged-off'>
- <span class='column-name' title="{name}" val="{name}">{name}</span><!--
- --><span class='column-state' val="{state}"><span class='network-state {state}'></span></span><!--
- --><span class='column-type' val="{type}">{type}</span><!--
- --><span class='column-interface' val="{interface}">{interface}</span><!--
- --><span class='column-space' val="{addrSpace}">{addrSpace}</span><!--
- --><span class='column-action' style="display:none">
- <span class="ui-button-secondary dropdown popable action-button">
- $_("Actions")
- <ul class='popover actionsheet right-side menu-container'>
- <li nwAct="start" class='{startClass}'><a class='button-big'>$_("Start")</a></li>
- <li nwAct="stop" class='{stopClass}'><a {stopDisabled} class='button-big'>$_("Stop")</a></li>
- <li nwAct="delete" class='{deleteClass}'><a {deleteDisabled} class='red'>$_("Delete")</a></li>
- </ul>
- </span>
- </span>
- </div>
-</script>
-<script>
- kimchi.initNetwork();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/report-add.html.tmpl b/plugins/kimchi/ui/pages/report-add.html.tmpl
deleted file mode 100644
index 25bf0a9..0000000
--- a/plugins/kimchi/ui/pages/report-add.html.tmpl
+++ /dev/null
@@ -1,56 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<div id="report-add-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Generate a New Debug Report")</h1>
- </header>
- <div class="content">
- <form id="form-report-add">
- <section class="form-section">
- <h2>
- <label for="report-name-textbox">$_("Report Name")</label>
- </h2>
- <div class="field">
- <input type="text" class="text" id="report-name-textbox" name="name" />
- <span class="icon-info-circled light-grey c1"></span>
- <span class="info-add-debug-report">
- $_("The name used to identify the report. If omitted, a name will be chosen based on current time. Name can contain: letters, digits, underscore (\"_\") and hyphen (\"-\").")
- </span>
- </div>
- </section>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="button-report-add" class="btn-normal"><span class="text">$_("Generate")</span></button>
- <button id="button-report-cancel" class="btn-normal close" type="button">
- <span calss="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.report_add_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/report-rename.html.tmpl b/plugins/kimchi/ui/pages/report-rename.html.tmpl
deleted file mode 100644
index 90a0a80..0000000
--- a/plugins/kimchi/ui/pages/report-rename.html.tmpl
+++ /dev/null
@@ -1,56 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<div id="report-rename-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Rename a Debug Report")</h1>
- </header>
- <div class="content">
- <form id="form-report-rename">
- <section class="form-section">
- <h2>
- <label for="report-name-textbox">$_("Report Name")</label>
- </h2>
- <div class="field">
- <input type="text" class="text" id="report-name-textbox" name="name" />
- <span class="icon-info-circled light-grey c1"></span>
- <span class="info-debug-report-rename">
- $_("The name used to identify the report. Name can contain: letters, digits and hyphen (\"-\").")
- </span>
- </div>
- </section>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="button-report-rename" class="btn-normal"><span class="text">$_("Submit")</span></button>
- <button id-"button-report-rename-cancel" class="btn-normal close" type="button">
- <span class="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.report_rename_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/repository-add.html.tmpl b/plugins/kimchi/ui/pages/repository-add.html.tmpl
deleted file mode 100644
index 950252a..0000000
--- a/plugins/kimchi/ui/pages/repository-add.html.tmpl
+++ /dev/null
@@ -1,113 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<div id="repository-add-window" class="window">
- <form id="form-repository-add">
- <header class="window-header">
- <h1 class="title h1 grey">$_("Add a Repository")</h1>
- </header>
- <section>
- <div class="content">
- <div class="form-section yum">
- <h2>$_("Identifier")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text" name="repo_id" />
- </div>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("Single word, unique identifier for the repository.")
- </p>
- </div>
- </div>
- <section class="form-section yum">
- <h2>$_("Name")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text" name="config[repo_name]" />
- </div>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("Textual name for the repository.")
- </p>
- </div>
- </section>
- <section class="form-section">
- <h2>$_("URL")<span class="required" role="presentation" title='$_("Required Field")'>*</span></h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text required" name="baseurl" />
- </div>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("URL to the repository. Supported protocols are http, ftp, and file.")
- </p>
- </div>
- <div class="field yum">
- <p class="yum">
- <input type="checkbox" name="isMirror" value="true" id="isMirror" />
- <label id="isMirrorLabel" for="isMirror">$_("Repository is a mirror")</label>
- </p>
- </div>
- </section>
- <section class="form-section repository-dist deb">
- <h2>$_("Distribution")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text" name="config[dist]" />
- </div>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("Distribution of the DEB repository.")
- </p>
- </div>
- </section>
- <section class="form-section repository-comps deb">
- <h2>$_("Components")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text" name="config[comps]" />
- </div>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("List of components in DEB repository.")
- </p>
- </div>
- </section>
- </div>
- </section>
- <footer>
- <div class="btn-group">
- <button type="submit" id="button-repository-add" class="btn-normal" disabled="disabled">
- <span class="text">$_("Add")</span>
- </button>
- <button type="button" id="button-repository-close" class="btn-normal close">
- <span class="text">$("Cancel")</span>
- </button>
- </div>
- </footer>
- </form>
-</div>
-<script>
- kimchi.repository_add_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/repository-edit.html.tmpl b/plugins/kimchi/ui/pages/repository-edit.html.tmpl
deleted file mode 100644
index e5a3cfb..0000000
--- a/plugins/kimchi/ui/pages/repository-edit.html.tmpl
+++ /dev/null
@@ -1,117 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-<div id="repository-edit-window" class="window">
- <form id="form-repository-edit">
- <header>
- <h1 class="title h1 grey">$_("Edit Repository")</h1>
- </header>
- <div class="content">
- <section id="form-repository-edit">
- <fieldset class="repository-edit-fieldset">
- <div class="repository-id yum">
- <div class="repository-edit-wrapper-label">
- <label for="repository-edit-id-textbox">$_("ID")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-id-textbox" name="repo_id" type="text" disabled="disabled" readonly="readonly"/>
- </div>
- </div>
- <div class="repository-name yum">
- <div class="repository-edit-wrapper-label">
- <label for="repository-edit-name-textbox">$_("Name")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-name-textbox" class="yum" name="config[repo_name]" type="text" />
- </div>
- </div>
- <div class="repository-url">
- <div class="repository-edit-wrapper-label">
- <label for="repository-edit-baseurl-textbox">$_("URL")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-baseurl-textbox" name="baseurl" type="text" />
- </div>
- </div>
- <div class="repository-dist deb">
- <div class="repository-edit-wrapper-label">
- <label for="repository-edit-urlargs-textbox">$_("Distribution")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-urlargs-textbox" class="deb" name="config[dist]" type="text" />
- </div>
- </div>
- <div class="repository-mirrorlist yum">
- <div class="repository-edit-wrapper-label">
- <label for="repository-edit-urlargs-textbox">$_("Mirror List URL")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-urlargs-textbox" class="yum" name="config[mirrorlist]" type="text" />
- </div>
- </div>
- <div class="repository-comps deb">
- <div class="repository-edit-wrapper-label">
- <label for="repository-edit-urlargs-textbox">$_("Components")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-urlargs-textbox" class="deb" name="config[comps]" type="text" />
- </div>
- </div>
- <div class="repository-gpgkey yum">
- <div class="repository-edit-wrapper-label">
- <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-gpgkey-textbox" class="yum" name="config[gpgkey]" type="text" />
- </div>
- </div>
- <div class="repository-gpgcheck yum">
- <div class="repository-edit-wrapper-label">
- <label>$_("GPG Check")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-gpgcheck-radio-true" class="yum" name="config[gpgcheck]" type="radio" value="true" />
- <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label>
- <input id="repository-edit-gpgcheck-radio-false" class="yum" name="config[gpgcheck]" type="radio" value="false" />
- <label for="repository-edit-gpgcheck-radio-false">$_("No")</label>
- </div>
- </div>
- </fieldset>
- </section>
- </div>
- <footer>
- <div class="btn-group">
- <button type="submit" id="repository-edit-button-save" class="btn-normal">
- <span class="text">$_("Save")</span>
- </button>
- <button type="button" id="repository-edit-button-cancel" class="close btn-normal">
- <span class="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
- </form>
-</div>
-<script type="text/javascript">
- kimchi.repository_edit_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/storage.html.tmpl b/plugins/kimchi/ui/pages/storage.html.tmpl
deleted file mode 100644
index 7b51a8b..0000000
--- a/plugins/kimchi/ui/pages/storage.html.tmpl
+++ /dev/null
@@ -1,143 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div class="toolbar">
- <div class="tools" style="display:none">
- <a id="storage-pool-add" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
- </div>
-</div>
-<div class='storage'>
-<div class="grid-control"><input type="text" class="filter" placeholder="$_("Filter")"></div>
-<div id='storageGrid'>
- <div>
- <span class="storage-name">$_("Name")</span>
- <span class="storage-state" >$_("State")</span>
- <span class="storage-type">$_("Type")</span>
- <span class="storage-capacity">$_("Capacity")</span>
- <span class="storage-allocate">$_("Allocated")</span>
- <span class="storage-location">$_("Location")</span>
- </div>
- <div id="storagepoolsList" class="list-storage empty-when-logged-off"></div>
-</div>
-</div>
-<div id="logicalPoolExtend" title="$_("Device path")">
- <p id="loading-info" class="text-help">
- <img src = "plugins/kimchi/images/theme-default/loading.gif" />
- $_("Looking for available partitions ...")
- </p>
- <div class="host-partition">
- </div>
-</div>
-<script id="storageTmpl" type="html/text">
- <div id="{name}" class="storage-li in" data-name="{name}" data-stat="{state}">
- <span class="storage-name" val="{name}{usage}%">
- <span title="{name}">{name}</span>
- <span class="usage">{usage}%</span>
- </span>
- <span class="storage-state">
- <div class="status-dot toolable active" data-state="{state}">
- <label class="tooltip">$_("active")</label>
- </div>
- <div class="status-dot toolable inactive" data-state="{state}">
- <label class="tooltip">$_("inactive")</label>
- </div>
- </span>
- <span class="storage-type" val="{type}">
- <div>{type}</div>
- </span>
- <span class="storage-capacity" val="{capacity}">
- <div data-type="{type}">{capacity}</div>
- </span>
- <span class="storage-allocate" val="{allocated}">
- <div data-type="{type}">{allocated}</div>
- </span>
- <span class="storage-location" val="{path}">
- <div>{path}</div>
- </span>
- <span class="bottom storage-button" style="display:none">
- <div class="btn dropdown popable storage-action" data-state="{state}" data-type="{type}" data-name="{name}">
- <span class="text">$_("Actions")</span><span class="arrow"></span>
- <div class="popover actionsheet right-side" style="width: 250px">
- <button class="button-big pool-deactivate" data-stat="{state}" data-name="{name}" data-persistent="{persistent}"><span class="text">$_("Deactivate")</span></button>
- <button class="button-big pool-activate" data-stat="{state}" data-name="{name}"><span class="text">$_("Activate")</span></button>
- <button class="button-big pool-add-volume" data-stat="{state}" data-name="{name}" data-type="{type}"><span class="text">$_("Add Volume")</span></button>
- <button class="button-big pool-extend {enableExt}" data-stat="{state}" data-name="{name}"><span class="text">$_("Extend")</span></button>
- <button class="button-big red pool-delete" data-stat="{state}" data-name="{name}"><span class="text">$_("Undefine")</span></button>
- </div>
- </div>
- </span>
- <span class="handle">
- <div class="arrow-down"></div>
- </span>
- <div class="volumes">
- <div id="volume{name}" class="volumeslist" data-name="{name}" ></div>
- <div class="clear"></div>
- </div>
- </div>
-</script>
-<script id="volumeTmpl" type="html/text">
- <div class="volume-box white-box" data-volume-name="{name}">
- <div class="storage-icon volume-default icon-{format} ">
- </div>
- <div class="volume-title">
- <div class="volume-name" title="{name}">{name}</div>
- <div class="volume-progress hidden">
- <div class="progress-bar-outer">
- <div class="progress-bar-inner"></div>
- </div>
- <div class="progress-label">
- <span class="progress-status"></span>
- <span class="progress-transferred"></span>
- </div>
- </div>
- </div>
- <div class="volume-setting">
- </div>
- <div class="volume-type-position">
- <div title="{type}" class="volume-text">$_("Type"): {type}</div>
- <div title="{format}" class="volume-text">$_("Format"): {format}</div>
- </div>
- <div class="volume-quota-position">
- <div title="{capacity}" class="volume-textquota">$_("Capacity"): {capacity}</div>
- <div title="{allocation}"class="volume-textquota">$_("Allocation"): {allocation}</div>
- </div>
- </div>
-</script>
-<script id="logicalPoolExtendTmpl" type="html/text">
- <div>
- <input type="checkbox" value="{path}" name="devices">
- <label for="{name}">{path}</label>
- </div>
-</script>
-<script>
- kimchi.storage_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl b/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
deleted file mode 100644
index ab10939..0000000
--- a/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
+++ /dev/null
@@ -1,79 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<div id="sp-add-volume-window" class="window">
- <form id="form-sp-add-volume">
- <header class="window-header">
- <h1 class="title h1 grey">$_("Add a Volume to Storage Pool")</h1>
- </header>
- <section>
- <div class="content">
- <div class="form-section">
- <h2>
- <input type="radio" id="volume-type-download" class="volume-type" name="volumeType" value="download" checked="checked" />
- <label for="volume-type-download">
- $_("Fetch from remote URL")
- </label>
- </h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" id="volume-remote-url" class="text volume-input download" name="volumeRemoteURL" />
- </div><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("Enter the remote URL here.")
- </p>
- </div>
- </div>
- <div class="form-section">
- <h2>
- <input type="radio" id="volume-type-upload" class="volume-type" name="volumeType" value="upload"/>
- <label for="volume-type-upload">
- $_("Upload a file")
- </label>
- </h2>
- <div class="field">
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("Choose the file you want to upload.")
- </p>
- <div class="textbox-wrapper">
- <input type="file" class="volume-input upload" id="volume-input-file" name="volumeLocalFile" disabled="disabled" />
- </div>
- </div>
- </div>
- </div>
- </section>
- <footer>
- <div class="btn-group">
- <button type="submit" id="sp-add-volume-button" class="btn-normal" disabled="disabled">
- <span class="text">$_("Add")</span>
- </button>
- <button type="button" class="btn-normal close"><span class="text">$_("Cancel")</span></button>
- </div>
- </footer>
- </form>
-</div>
-<script type="text/javascript">
- kimchi.sp_add_volume_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/storagepool-add.html.tmpl b/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
deleted file mode 100644
index a697af5..0000000
--- a/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
+++ /dev/null
@@ -1,186 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<body>
- <div class="window storage-window storage-admin">
- <header>
- <h1 class="title h1 grey">$_("Define a New Storage Pool")</h1>
- </header>
- <div class="content">
- <form id="form-pool-add">
- <section class="form-section">
- <h2>1. $_("Storage Pool Name")</h2>
- <div class="field">
- <input id="poolId" required="required" type="text" class="text storage-base-input-width" name="name"><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("The name used to identify the storage pools, and it should not be empty.")
- </p>
- </div>
- </section>
- <section class="form-section">
- <h2>2. $_("Storage Pool Type")</h2>
- <div class="storage-type-wrapper-controls">
- <div id="poolTypeId">
- <input id="poolTypeInputId" name="type" type="hidden" value="dir"/>
- <span id="pool-type-label" class="text"></span><span class="arrow"></span>
- <div>
- <ul id="storagePool-list">
- </ul>
- </div>
- </div>
- </div>
- </section>
- <div class="path-section">
- <section class="form-section">
- <h2>3. $_("Storage Path")</h2>
- <div class="field">
- <input id="pathId" type="text" class="text storage-base-input-width"><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("The path of the Storage Pool. Each Storage Pool must have a unique path.")</p><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("Kimchi will try to create the directory when it does not already exist in your system.")</p>
- </div>
- <div class="clear"></div>
- </section>
- </div>
- <div class="nfs-section tmpl-html">
- <section class="form-section">
- <h2>3. $_("NFS Server IP")</h2>
- <div class="field storage-field">
- <div id="serverComboboxId" class="storage-add-input-width">
- <input id="nfsserverId"/>
- <div>
- <ul id="nfs-server-used">
- </ul>
- </div>
- </div><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("NFS server IP or hostname. It can be input or chosen from history.")</p>
- </div>
- </section>
- <section class="form-section">
- <h2>4. $_("NFS Path")</h2>
- <div class="field storage-field">
- <div id="targetFilterSelectId" class="storage-add-input-width">
- <input id="nfspathId" class="input" disabled/>
- <div>
- <ul id="nfs-server-target">
- </ul>
- </div>
- </div><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">$_("The NFS exported path on NFS server.")</p>
- </div>
- </section>
- </div>
- <div class="logical-section tmpl-html">
- <section class="form-section storageType">
- <h2>3. $_("Device path")</h2>
- <div class="host-partition">
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("Looking for available partitions ...")
- <img src = "plugins/kimchi/images/theme-default/loading.gif" />
- </p>
- </div>
- </section>
- </div>
- <div class="iscsi-section tmpl-html">
- <section class="form-section">
- <h2>3. $_("iSCSI Server")</h2>
- <div class="field">
- <span class="filter-select popable" id="iSCSIServer">
- <input id="iscsiserverId" type="text" placeholder="$_("Server")">
- <div class="popover"><ul class="option select-list"></ul></div>
- </span>
- <input id="iscsiportId" placeholder="$_("Port")" type="text" class="text storage-port-width" maxlength="4"><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">
- $_("iSCSI server IP or hostname. It should not be empty.")</p>
- </div>
- </section>
- <section class="form-section">
- <h2>4. $_("Target")</h2>
- <div class="field">
- <span class="filter-select popable" id="iSCSITarget">
- <input id="iscsiTargetId" type="text">
- <div class="popover"><ul class="option select-list"></ul></div>
- </span><br>
- <div class="icon-info-circled light-grey c1 help-inline"></div>
- <p class="text-help help-inline">$_("The iSCSI target on iSCSI server")</p>
- </div>
- </section>
- <section class="form-section">
- <div class="field">
- <input type="checkbox" id="authId" name="authname">
- <label for="authId">$_("Add iSCSI Authentication")</label>
- </div>
- </section>
- <section class="authenticationfield form-section tmpl-html">
- <h2>5. $_("iSCSI Authentication")</h2>
- <div class="field">
- <input id="usernameId" placeholder="$_("User Name")" type="text" class="text storage-auth-width">
- <input id="passwordId" placeholder="$_("Password")" type="password" class="text storage-auth-width">
- </div>
- </section>
- </div>
- <div class="scsi-section tmpl-html">
- <section class="form-section">
- <h2>3. $_("SCSI Adapter")</h2>
- <div class="storage-type-wrapper-controls">
- <div id="scsiAdapter">
- <input type="hidden"/>
- <span class="text"></span><span class="arrow"></span>
- <div><ul></ul></div>
- </div>
- </div>
- </section>
- </div>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="pool-doAdd" class="btn-normal">
- <span class="text">$_("Create")</span>
- </button>
- <button class="btn-normal" id="pool-loading" style="display: none"><span class="text">$_("Please, wait...")</span></button>
- <button class="btn-normal close" type="button"><span class="text">$_("Cancel")</span></button>
- </div>
- </footer>
- </div>
- <script>
- kimchi.storagepool_add_main();
- </script>
- <script id="partitionTmpl" type="html/text">
- <div>
- <input type="checkbox" id="{name}" value="{path}" name="devices">
- <label for="{name}">{path}</label>
- </div>
- </script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/template-add.html.tmpl b/plugins/kimchi/ui/pages/template-add.html.tmpl
deleted file mode 100644
index b44db79..0000000
--- a/plugins/kimchi/ui/pages/template-add.html.tmpl
+++ /dev/null
@@ -1,233 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<body>
-<div class="window" style="width: 992px;height: 660px;">
- <header>
- <h1 class="title h1 grey">$_("Add Template")</h1>
- </header>
- <div class="content" style="margin-bottom: 0">
- <div class="page-list">
- <!-- 1 -->
- <div class="page" id="iso-type-box" style="left:0">
- <h2 class="step-title">$_("Where is the source media for this template? ")</h2>
- <ul class="step-choose">
- <li>
- <a id="iso-local" class="local">$_("Local ISO Image")</a>
- </li>
- <li>
- <a id="vm-image-local" class="local">$_("Local Image File")</a>
- </li>
- <li>
- <a id="iso-remote" class="remote">$_("Remote ISO Image")</a>
- </li>
- </ul>
- </div>
-
- <!-- 1-1 -->
- <div class="page" id="iso-local-box">
- <header>
- <a class="back" id="iso-local-box-back"></a>
- <h2 class="step-title">$_("Local ISO Image")</h2>
- </header>
-
- <button class="btn-normal" id="iso-search" style="display: none"><span class="text">$_("Search ISOs")</span></button>
- <button class="btn-normal" id="iso-search-loading" style="display: none"><span class="text">$_("Please, wait...")</span></button>
- <!-- 1-1-1 -->
- <div id="local-iso-field" class="iso-field" style="display: none;">
- <h3 class="step-subtitle">
- $_("The following ISOs are available:")
- </h3>
- <div class="toolbar">
- <label class="check-all">
- <input type="checkbox" id="select-all-local-iso">$_("All")
- </label>
- </div>
- <div>
- <form id="form-local-iso">
- <ul id="list-local-iso" class="list-iso">
- </ul>
- </form>
- <script id="tmpl-list-local-iso" type="text/html">
- <li>
- <label>
- <input type="checkbox" name="iso" value="{isoId}">
- <div class="box box-iso">
- <div class="iso-icon {os_distro}">
- </div>
- <h3 class="iso-title" title="{name}">
- {name}
- </h3>
- <div class="iso-info">
- <div class="iso-info-col">
- <div class="iso-info-item" title="{os_distro}">
- $_("OS: "){os_distro}
- </div>
- <div class="iso-info-item" title="{os_version}">
- $_("Version: "){os_version}
- </div>
- </div>
- <div class="iso-info-col">
- <div class="iso-info-item" title="{capacity}">
- $_("Size: "){capacity}
- </div>
- </div>
- </div>
- </div>
- </label>
- </li>
- </script>
- </div>
- <div class="button-field">
- <button class="btn-normal" id="iso-more" style="display: none"><span class="text">$_("Search more ISOs")</span></button>
- <button class="btn-normal" id="iso-more-loading" style="display: none"><span class="text">$_("Please, wait...")</span></button>
- <button class="btn-normal" id="btn-template-local-iso-create" disabled="disabled"><span class="text">$_("Create Templates from Selected ISO")</span></button>
- </div>
- </div>
-
- <!-- 1-1-2 -->
- <div id="iso-file-field">
- <h3 class="step-subtitle">
- <label>
- <input type="checkbox" id="iso-file-check">
- $_("I want to use a specific ISO file")
- </label>
- </h3>
- <div id="iso-file-box" class="custom-iso-field">
- <div class="input-wrapper"><input type="text" class="text" id="iso-file" name="iso-file"></div>
- <button class="btn-normal" id="btn-template-file-create" disabled="disabled"><span class="text">$_("Create")</span></button>
- </div>
- </div>
-
- </div>
-
- <div class="page" id="vm-image-local-box">
- <header>
- <a class="back" id="vm-image-local-box-back"></a>
- <h2 class="step-title">$_("Local Image File")</h2>
- </header>
- <div class="body">
- <label for="vm-image-local-text">File Path:</label>
- <input type="text" id="vm-image-local-text" />
- <button class="ui-button-primary">$_("Create")</button>
- </div>
- </div>
-
- <!-- 1-2 -->
- <div class="page" id="iso-remote-box">
- <header>
- <a class="back" id="iso-remote-box-back"></a>
- <h2 class="step-title">$_("Remote ISO Image")</h2>
- </header>
-
- <!-- 1-2-0 -->
- <div id="load-remote-iso">
- <h3 class="step-subtitle">
- <label>
- <img src = "plugins/kimchi/images/theme-default/loading.gif" />
- $_("Loading default remote ISOs ...")
- </label>
- </h3>
- </div>
-
- <!-- 1-2-1 -->
- <div id="remote-iso-field" class="iso-field" style="display: none;">
- <h3 class="step-subtitle">
- $_("The following ISOs are available:")
- </h3>
- <div class="toolbar">
- <label class="check-all">
- <input type="checkbox" id="select-all-remote-iso">$_("All")
- </label>
- </div>
- <div>
- <form id="form-remote-iso">
- <ul id="list-remote-iso" class="list-iso">
- </ul>
- </form>
- <script id="tmpl-list-remote-iso" type="text/html">
- <li>
- <label>
- <input type="checkbox" name="iso" value="{isoId}">
- <div class="box box-iso">
- <div class="iso-icon {os_distro}">
- </div>
- <h3 class="iso-title" title="{name}">
- {name}
- </h3>
- <div class="iso-info">
- <div class="iso-info-col">
- <div class="iso-info-item" title="{os_distro}">
- $_("OS: "){os_distro}
- </div>
- <div class="iso-info-item" title="{os_version}">
- $_("Version: "){os_version}
- </div>
-
- </div>
- <div class="iso-info-col">
- <div class="iso-info-item" title="{os_arch}">
- $_("Arch: "){os_arch}
- </div>
- </div>
- </div>
- </div>
- </label>
- </li>
- </script>
- </div>
- <div class="button-field">
- <button class="btn-normal" id="btn-template-remote-iso-create" disabled="disabled"><span class="text">$_("Create Templates from Selected ISO")</span></button>
- </div>
- </div>
-
- <!-- 1-2-2 -->
- <div id="iso-url-field" style="display: none;">
- <h3 class="step-subtitle">
- <label>
- <input type="checkbox" id="iso-url-check">
- $_("I want to use a custom URL")
- </label>
- </h3>
- <div id="iso-url-box" class="custom-iso-field">
- <div class="input-wrapper"><input type="text" class="text" id="iso-url" name="iso-url"></div>
- <button class="btn-normal" id="btn-template-url-create" disabled="disabled"><span class="text">$_("Create")</span></button>
- </div>
- </div>
-
- </div>
- </div>
- </div>
- <footer>
- <div class="button-group">
- <button class="btn-normal close" type="button"><span type="text">$_("Cancel")</span></button>
- </div>
- </footer>
-</div>
-<script>
-kimchi.template_add_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/template-edit.html.tmpl b/plugins/kimchi/ui/pages/template-edit.html.tmpl
deleted file mode 100644
index 0588294..0000000
--- a/plugins/kimchi/ui/pages/template-edit.html.tmpl
+++ /dev/null
@@ -1,193 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-<div id="template-edit-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Edit Template")</h1>
- </header>
- <div class="content">
- <div id="edit-template-tabs">
- <input type="hidden" id="template-name" name="templateName" />
- <ul>
- <li>
- <a href="#form-template-general">$_("General")</a>
- </li>
- <li>
- <a href="#form-template-storage">$_("Storage")</a>
- </li>
- <li>
- <a href="#form-template-interface">$_("Interface")</a>
- </li>
- <li>
- <a href="#form-template-processor">$_("Processor")</a>
- </li>
- </ul>
- <form id="form-template-general">
- <div class="form-template-inline-wrapper">
- <div class="template-edit-wrapper-label">
- <label for="template-edit-id-textbox">$_("Name")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label for="template-edit-vendor-textbox">$_("Vendor")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label for="template-edit-version-textbox">$_("Version")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label for="template-edit-memory-textbox">$_("Memory (MB)")</label>
- </div>
- <div class="template-edit-wrapper-label templ-edit-cdrom">
- <label for="template-edit-cdrom-textbox">$_("CDROM")</label>
- </div>
- <div class="template-edit-wrapper-label templ-edit-vm-image hide">
- <label for="template-edit-vmimage-textbox">$_("Image File")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label>$_("Graphics")</label>
- </div>
- </div>
- <div class="form-template-inline-wrapper">
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-id-textbox" name="name" type="text" />
- </div>
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-vendor-textbox" name="os_distro" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-version-textbox" name="os_version" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-memory-textbox" name="memory" type="text" />
- </div>
- <div class="template-edit-wrapper-controls templ-edit-cdrom">
- <input id="template-edit-cdrom-textbox" name="cdrom" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls templ-edit-vm-image hide">
- <input id="template-edit-vmimage-textbox" name="vm-image" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls">
- <div class="btn dropdown popable">
- <input id="template-edit-graphics" name="graphics" type="hidden" />
- <span class="text" id="template-edit-graphics-label"></span><span class="arrow"></span>
- <div class="popover" style="width: 100%">
- <ul class="select-list" id="template-edit-graphics-list" data-target="template-edit-graphics" data-label="template-edit-graphics-label">
- </ul>
- </div>
- </div>
- </div>
- </div>
- </form>
- <form id="form-template-storage">
- <div class="template-tab-header">
- <span class="template-storage-cell">$_("Storage Pool")</span>
- <span class="template-storage-cell">$_("Type")</span>
- <span class="template-storage-cell">$_("Disk(GB)")</span>
- <span class="template-storage-cell">$_("Disk Format")</span>
- <button type="button" id="template-edit-storage-add-button" class="action-area"></button>
- </div>
- <div class="template-tab-body">
- </div>
- </form>
- <form id="form-template-interface">
- <div class="template-tab-header">
- <span class="template-interface-cell">$_("Network")</span>
- <span class="template-interface-cell">$_("Type")</span>
- <button type="button" id="template-edit-interface-add-button" class="action-area"></button>
- </div>
- <div class="template-tab-body"></div>
- </form>
- <form id="form-template-processor">
- <div>
- <label for="cpus">$_("CPU Number"):</label>
- <input type="text" value="1" id="cpus" />
- </div>
- <div class="manual">
- <input type="checkbox" id="cpus-check" />
- <label for="cpus-check">$_("Manually set CPU topology")</label>
- </div>
- <div class="topology hide">
- <div>
- <label for="cores">$_("Cores"):</label>
- <input type="text" value="1" id="cores" />
- </div>
- <div>
- <label for="threads">$_("Threads"):</label>
- <select id="threads"></select>
- </div>
- </div>
- </form>
- </div>
- </div>
- <footer>
- <div class="btn-group">
- <a id="tmpl-edit-button-save" class="btn-normal" href="javascript:void(0);"><span class="text">$_("Save")</span></a>
- <button class="btn-normal close" type="button"><span class="text">$_("Cancel")</span></button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.template_edit_main();
-</script>
-<script id="template-storage-pool-tmpl" type="text/html">
- <div class='item'>
- <span class="template-storage-cell">
- <input class="template-storage-name" value={storageName} type="text" style="display:none" />
- <select id="selectStorageName"></select>
- </span>
- <span class="template-storage-cell">
- <input class="template-storage-type" value={storageType} readonly=true type="text" />
- </span>
- <span class="template-storage-cell">
- <input class="template-storage-disk" value={storageDisk} type="text" />
- </span>
- <span class="template-storage-cell">
- <input class="template-storage-disk-format" value={storageDiskFormat} type="text" style="display:none" />
- <select id="diskFormat">
- <option value="qcow2">qcow2</option>
- <option value="raw">raw</option>
- <option value="bochs">bochs</option>
- <option value="cloop">cloop</option>
- <option value="cow">cow</option>
- <option value="dmg">dmg</option>
- <option value="qcow">qcow</option>
- <option value="qed">qed</option>
- <option value="vmdk">vmdk</option>
- <option value="vpc">vpc</option>
- </select>
- </span>
- </div>
-</script>
-<script id="template-interface-tmpl" type="text/html">
- <div class="item" id={networkID}>
- <span class="template-interface-cell">
- <select></select>
- </span>
- <span class="template-interface-cell">
- <input value={type} readonly=true type="text" />
- </span>
- <span class="action-area">
- <button class="delete"></button>
- </span>
- </div>
-</script>
diff --git a/plugins/kimchi/ui/pages/templates.html.tmpl b/plugins/kimchi/ui/pages/templates.html.tmpl
deleted file mode 100644
index af1cf3f..0000000
--- a/plugins/kimchi/ui/pages/templates.html.tmpl
+++ /dev/null
@@ -1,77 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div class="toolbar">
- <div class="tools" style="display:none">
- <a id="template-add" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
- </div>
-</div>
-<div>
- <div id="noTemplates" class="list-no-result" style="display: none;">
- $_("No templates found.")
- </div>
-
- <ul id="templateList" class="empty-when-logged-off"></ul>
-
- <script id="templateTmpl" type="html/text">
-
- <div class="template-box white-box template-border">
- <div class="btn dropdown popable" style="width: 70px">
- <span class="text">$_("Actions")</span><span class="arrow"></span>
- <div class="popover actionsheet right-side" style="width: 250px">
- <a class="button-big template-edit" data-template='{name}'>$_("Edit")</a>
- <a class="button-big template-clone" data-template='{name}'>$_("Clone")</a>
- <a class="button-big red template-delete" data-template='{name}'>$_("Delete")</a>
- </div>
- </div>
-
- <div class="template-icon template-icon-position">
- <img alt="" src="{icon}">
- <img alt="" src="{location}" class="template-type-icon-position">
- </div>
- <div class="template-general template-title template-title-position">
- <h2 class="title" title="{name}">{name}</h2>
- </div>
- <div class="template-os-position">
- <div class="template-text">$_("OS"): {os_distro}</div>
- <div class="template-text">$_("Version"): {os_version}</div>
- </div>
- <div class="template-cpu-position">
- <div class="template-text">$_("CPUs"): {cpus}</div>
- <div class="template-text">$_("Memory"): {memory}M</div>
- </div>
- </div>
- </script>
-</div>
-<script>
- kimchi.template_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/robots.txt b/plugins/kimchi/ui/robots.txt
deleted file mode 100644
index 1f53798..0000000
--- a/plugins/kimchi/ui/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow: /
diff --git a/plugins/kimchi/ui/spice-html5/Makefile.am b/plugins/kimchi/ui/spice-html5/Makefile.am
deleted file mode 100644
index c43f1ef..0000000
--- a/plugins/kimchi/ui/spice-html5/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-SUBDIRS = pages
-
-if WITH_SPICE
-SUBDIRS += css thirdparty
-
-spicehtml5dir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
-dist_spicehtml5_DATA = $(wildcard *.js) $(NULL)
-endif
diff --git a/plugins/kimchi/ui/spice-html5/atKeynames.js b/plugins/kimchi/ui/spice-html5/atKeynames.js
deleted file mode 100644
index e1e27fd..0000000
--- a/plugins/kimchi/ui/spice-html5/atKeynames.js
+++ /dev/null
@@ -1,183 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Aric Stewart <aric at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-/*
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three)
- * sets of scancodes. Set3 can only be generated by a MF keyboard.
- * Set2 sends a makecode for keypress, and the same code prefixed by a
- * F0 for keyrelease. This is a little bit ugly to handle. Thus we use
- * here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes.
- * Bit 7 ist set if the key is released. The code E0 switches to a
- * different meaning to add the new MF cursorkeys, while not breaking old
- * applications. E1 is another special prefix. Since I assume that there
- * will be further versions of PC/XT scancode compatible keyboards, we
- * may be in trouble one day.
- *
- * IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3.
- * 2) Use the keyboards native set and translate it to common keysyms.
- */
-
-/*
- * definition of the AT84/MF101/MF102 Keyboard:
- * ============================================================
- * Defined Key Cap Glyphs Pressed value
- * Key Name Main Also (hex) (dec)
- * ---------------- ---------- ------- ------ ------
- */
-
-var KEY_Escape =/* Escape 0x01 */ 1
-var KEY_1 =/* 1 ! 0x02 */ 2
-var KEY_2 =/* 2 @ 0x03 */ 3
-var KEY_3 =/* 3 # 0x04 */ 4
-var KEY_4 =/* 4 $ 0x05 */ 5
-var KEY_5 =/* 5 % 0x06 */ 6
-var KEY_6 =/* 6 ^ 0x07 */ 7
-var KEY_7 =/* 7 & 0x08 */ 8
-var KEY_8 =/* 8 * 0x09 */ 9
-var KEY_9 =/* 9 ( 0x0a */ 10
-var KEY_0 =/* 0 ) 0x0b */ 11
-var KEY_Minus =/* - (Minus) _ (Under) 0x0c */ 12
-var KEY_Equal =/* = (Equal) + 0x0d */ 13
-var KEY_BackSpace =/* Back Space 0x0e */ 14
-var KEY_Tab =/* Tab 0x0f */ 15
-var KEY_Q =/* Q 0x10 */ 16
-var KEY_W =/* W 0x11 */ 17
-var KEY_E =/* E 0x12 */ 18
-var KEY_R =/* R 0x13 */ 19
-var KEY_T =/* T 0x14 */ 20
-var KEY_Y =/* Y 0x15 */ 21
-var KEY_U =/* U 0x16 */ 22
-var KEY_I =/* I 0x17 */ 23
-var KEY_O =/* O 0x18 */ 24
-var KEY_P =/* P 0x19 */ 25
-var KEY_LBrace =/* [ { 0x1a */ 26
-var KEY_RBrace =/* ] } 0x1b */ 27
-var KEY_Enter =/* Enter 0x1c */ 28
-var KEY_LCtrl =/* Ctrl(left) 0x1d */ 29
-var KEY_A =/* A 0x1e */ 30
-var KEY_S =/* S 0x1f */ 31
-var KEY_D =/* D 0x20 */ 32
-var KEY_F =/* F 0x21 */ 33
-var KEY_G =/* G 0x22 */ 34
-var KEY_H =/* H 0x23 */ 35
-var KEY_J =/* J 0x24 */ 36
-var KEY_K =/* K 0x25 */ 37
-var KEY_L =/* L 0x26 */ 38
-var KEY_SemiColon =/* ;(SemiColon) :(Colon) 0x27 */ 39
-var KEY_Quote =/* ' (Apostr) " (Quote) 0x28 */ 40
-var KEY_Tilde =/* ` (Accent) ~ (Tilde) 0x29 */ 41
-var KEY_ShiftL =/* Shift(left) 0x2a */ 42
-var KEY_BSlash =/* \(BckSlash) |(VertBar)0x2b */ 43
-var KEY_Z =/* Z 0x2c */ 44
-var KEY_X =/* X 0x2d */ 45
-var KEY_C =/* C 0x2e */ 46
-var KEY_V =/* V 0x2f */ 47
-var KEY_B =/* B 0x30 */ 48
-var KEY_N =/* N 0x31 */ 49
-var KEY_M =/* M 0x32 */ 50
-var KEY_Comma =/* , (Comma) < (Less) 0x33 */ 51
-var KEY_Period =/* . (Period) >(Greater)0x34 */ 52
-var KEY_Slash =/* / (Slash) ? 0x35 */ 53
-var KEY_ShiftR =/* Shift(right) 0x36 */ 54
-var KEY_KP_Multiply =/* * 0x37 */ 55
-var KEY_Alt =/* Alt(left) 0x38 */ 56
-var KEY_Space =/* (SpaceBar) 0x39 */ 57
-var KEY_CapsLock =/* CapsLock 0x3a */ 58
-var KEY_F1 =/* F1 0x3b */ 59
-var KEY_F2 =/* F2 0x3c */ 60
-var KEY_F3 =/* F3 0x3d */ 61
-var KEY_F4 =/* F4 0x3e */ 62
-var KEY_F5 =/* F5 0x3f */ 63
-var KEY_F6 =/* F6 0x40 */ 64
-var KEY_F7 =/* F7 0x41 */ 65
-var KEY_F8 =/* F8 0x42 */ 66
-var KEY_F9 =/* F9 0x43 */ 67
-var KEY_F10 =/* F10 0x44 */ 68
-var KEY_NumLock =/* NumLock 0x45 */ 69
-var KEY_ScrollLock =/* ScrollLock 0x46 */ 70
-var KEY_KP_7 =/* 7 Home 0x47 */ 71
-var KEY_KP_8 =/* 8 Up 0x48 */ 72
-var KEY_KP_9 =/* 9 PgUp 0x49 */ 73
-var KEY_KP_Minus =/* - (Minus) 0x4a */ 74
-var KEY_KP_4 =/* 4 Left 0x4b */ 75
-var KEY_KP_5 =/* 5 0x4c */ 76
-var KEY_KP_6 =/* 6 Right 0x4d */ 77
-var KEY_KP_Plus =/* + (Plus) 0x4e */ 78
-var KEY_KP_1 =/* 1 End 0x4f */ 79
-var KEY_KP_2 =/* 2 Down 0x50 */ 80
-var KEY_KP_3 =/* 3 PgDown 0x51 */ 81
-var KEY_KP_0 =/* 0 Insert 0x52 */ 82
-var KEY_KP_Decimal =/* . (Decimal) Delete 0x53 */ 83
-var KEY_SysReqest =/* SysReqest 0x54 */ 84
- /* NOTUSED 0x55 */
-var KEY_Less =/* < (Less) >(Greater) 0x56 */ 86
-var KEY_F11 =/* F11 0x57 */ 87
-var KEY_F12 =/* F12 0x58 */ 88
-
-var KEY_Prefix0 =/* special 0x60 */ 96
-var KEY_Prefix1 =/* specail 0x61 */ 97
diff --git a/plugins/kimchi/ui/spice-html5/bitmap.js b/plugins/kimchi/ui/spice-html5/bitmap.js
deleted file mode 100644
index 03f5127..0000000
--- a/plugins/kimchi/ui/spice-html5/bitmap.js
+++ /dev/null
@@ -1,51 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** bitmap.js
-** Handle SPICE_IMAGE_TYPE_BITMAP
-**--------------------------------------------------------------------------*/
-function convert_spice_bitmap_to_web(context, spice_bitmap)
-{
- var ret;
- var offset, x;
- var u8 = new Uint8Array(spice_bitmap.data);
- if (spice_bitmap.format != SPICE_BITMAP_FMT_32BIT &&
- spice_bitmap.format != SPICE_BITMAP_FMT_RGBA)
- return undefined;
-
- ret = context.createImageData(spice_bitmap.x, spice_bitmap.y);
- for (offset = 0; offset < (spice_bitmap.y * spice_bitmap.stride); )
- for (x = 0; x < spice_bitmap.x; x++, offset += 4)
- {
- ret.data[offset + 0 ] = u8[offset + 2];
- ret.data[offset + 1 ] = u8[offset + 1];
- ret.data[offset + 2 ] = u8[offset + 0];
-
- // FIXME - We effectively treat all images as having SPICE_IMAGE_FLAGS_HIGH_BITS_SET
- if (spice_bitmap.format == SPICE_BITMAP_FMT_32BIT)
- ret.data[offset + 3] = 255;
- else
- ret.data[offset + 3] = u8[offset];
- }
-
- return ret;
-}
diff --git a/plugins/kimchi/ui/spice-html5/css/Makefile.am b/plugins/kimchi/ui/spice-html5/css/Makefile.am
deleted file mode 100644
index ed51972..0000000
--- a/plugins/kimchi/ui/spice-html5/css/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-spicecssdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
-
-dist_spicecss_DATA = $(wildcard *.css) $(NULL)
diff --git a/plugins/kimchi/ui/spice-html5/css/spice.css b/plugins/kimchi/ui/spice-html5/css/spice.css
deleted file mode 100644
index 5d092ba..0000000
--- a/plugins/kimchi/ui/spice-html5/css/spice.css
+++ /dev/null
@@ -1,118 +0,0 @@
-body
-{
- background-color: #999999;
- color: #000000; margin: 0; padding: 0;
- font-family: "Lucida Grande", "Lucida Sans Unicode", "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;
- font-size: 12pt;
- line-height: 1.5em;
-}
-
-* { margin: 0; }
-
-#login
-{
- width: 95%;
- margin-left: auto;
- margin-right: auto;
- border: 1px solid #999999;
- background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#24414e));
- background: -moz-linear-gradient(top, #fff, #24414e);
- background-color: #24414e;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- border-radius: 10px;
-}
-#login span.logo
-{
- display: inline-block;
- margin-right: 5px;
- padding: 2px 10px 2px 20px;
- border-right: 1px solid #999999;
- font-size: 20px;
- font-weight: bolder;
- text-shadow: #efefef 1px 1px 0px;
-}
-#login label { color: #ffffff; text-shadow: 1px 1px 0px rgba(175, 210, 220, 0.8); }
-#login input
-{
- padding: 5px;
- background-color: #fAfAfA;
- border: 1px inset #999999;
- outline: none;
- -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
-}
-#login input#host { width: 200px; }
-#login input#port { width: 75px; }
-#login input#password { width: 100px; }
-#login button
-{
- padding: 5px 10px 5px 10px;
- margin-left: 5px;
- text-shadow: #efefef 1px 1px 0px;
- border: 1px outset #999999;
- cursor: pointer;
- -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
-}
-#login button:hover
-{
- background-color: #666666;
- color: #ffffff;
-}
-
-#spice-area
-{
- height: 100%;
- width: 95%;
- padding: 0;
- margin-left: auto;
- margin-right: auto;
- border: solid #222222 1px;
- -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- border-radius: 10px;
-}
-.spice-screen
-{
- min-height: 600px;
- height: 100%;
- margin: 10px;
- padding: 0;
- background-color: #333333;
-}
-.spice-message {
- width: 700px;
- height: 50px;
- overflow: auto;
- margin-top: 5px;
- margin-left: auto;
- margin-right: auto;
- padding: 10px;
- background-color: #efefef;
- border: solid #c3c3c3 2px;
- font-size: 8pt;
- line-height: 1.1em;
- font-family: 'Andale Mono', monospace;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- border-radius: 10px;
- -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
-}
-.spice-message p {
- margin-bottom: 0em;
- margin-top: 0em;
-}
-.spice-message-warning {
- color: orange;
-}
-.spice-message-error {
- color: red;
-}
-
diff --git a/plugins/kimchi/ui/spice-html5/cursor.js b/plugins/kimchi/ui/spice-html5/cursor.js
deleted file mode 100644
index 71e941d..0000000
--- a/plugins/kimchi/ui/spice-html5/cursor.js
+++ /dev/null
@@ -1,110 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** SpiceCursorConn
-** Drive the Spice Cursor Channel
-**--------------------------------------------------------------------------*/
-function SpiceCursorConn()
-{
- SpiceConn.apply(this, arguments);
-}
-
-SpiceCursorConn.prototype = Object.create(SpiceConn.prototype);
-SpiceCursorConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_CURSOR_INIT)
- {
- var cursor_init = new SpiceMsgCursorInit(msg.data);
- DEBUG > 1 && console.log("SpiceMsgCursorInit");
- if (this.parent && this.parent.inputs &&
- this.parent.inputs.mouse_mode == SPICE_MOUSE_MODE_SERVER)
- {
- // FIXME - this imagines that the server actually
- // provides the current cursor position,
- // instead of 0,0. As of May 11, 2012,
- // that assumption was false :-(.
- this.parent.inputs.mousex = cursor_init.position.x;
- this.parent.inputs.mousey = cursor_init.position.y;
- }
- // FIXME - We don't handle most of the parameters here...
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_SET)
- {
- var cursor_set = new SpiceMsgCursorSet(msg.data);
- DEBUG > 1 && console.log("SpiceMsgCursorSet");
- if (cursor_set.flags & SPICE_CURSOR_FLAGS_NONE)
- {
- document.getElementById(this.parent.screen_id).style.cursor = "none";
- return true;
- }
-
- if (cursor_set.flags > 0)
- this.log_warn("FIXME: No support for cursor flags " + cursor_set.flags);
-
- if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA)
- {
- this.log_warn("FIXME: No support for cursor type " + cursor_set.cursor.header.type);
- return false;
- }
-
- this.set_cursor(cursor_set.cursor);
-
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_HIDE)
- {
- DEBUG > 1 && console.log("SpiceMsgCursorHide");
- document.getElementById(this.parent.screen_id).style.cursor = "none";
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_RESET)
- {
- DEBUG > 1 && console.log("SpiceMsgCursorReset");
- document.getElementById(this.parent.screen_id).style.cursor = "auto";
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_INVAL_ALL)
- {
- DEBUG > 1 && console.log("SpiceMsgCursorInvalAll");
- // FIXME - There may be something useful to do here...
- return true;
- }
-
- return false;
-}
-
-SpiceCursorConn.prototype.set_cursor = function(cursor)
-{
- var pngstr = create_rgba_png(cursor.header.height, cursor.header.width, cursor.data);
- var curstr = 'url(data:image/png,' + pngstr + ') ' +
- cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default";
- var screen = document.getElementById(this.parent.screen_id);
- screen.style.cursor = 'auto';
- screen.style.cursor = curstr;
- if (window.getComputedStyle(screen, null).cursor == 'auto')
- SpiceSimulateCursor.simulate_cursor(this, cursor, screen, pngstr);
-}
diff --git a/plugins/kimchi/ui/spice-html5/display.js b/plugins/kimchi/ui/spice-html5/display.js
deleted file mode 100644
index 2aa5985..0000000
--- a/plugins/kimchi/ui/spice-html5/display.js
+++ /dev/null
@@ -1,823 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** FIXME: putImageData does not support Alpha blending
-** or compositing. So if we have data in an ImageData
-** format, we have to draw it onto a context,
-** and then use drawImage to put it onto the target,
-** as drawImage does alpha.
-**--------------------------------------------------------------------------*/
-function putImageDataWithAlpha(context, d, x, y)
-{
- var c = document.createElement("canvas");
- var t = c.getContext("2d");
- c.setAttribute('width', d.width);
- c.setAttribute('height', d.height);
- t.putImageData(d, 0, 0);
- context.drawImage(c, x, y, d.width, d.height);
-}
-
-/*----------------------------------------------------------------------------
-** FIXME: Spice will send an image with '0' alpha when it is intended to
-** go on a surface w/no alpha. So in that case, we have to strip
-** out the alpha. The test case for this was flux box; in a Xspice
-** server, right click on the desktop to get the menu; the top bar
-** doesn't paint/highlight correctly w/out this change.
-**--------------------------------------------------------------------------*/
-function stripAlpha(d)
-{
- var i;
- for (i = 0; i < (d.width * d.height * 4); i += 4)
- d.data[i + 3] = 255;
-}
-
-/*----------------------------------------------------------------------------
-** SpiceDisplayConn
-** Drive the Spice Display Channel
-**--------------------------------------------------------------------------*/
-function SpiceDisplayConn()
-{
- SpiceConn.apply(this, arguments);
-}
-
-SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype);
-SpiceDisplayConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_DISPLAY_MARK)
- {
- // FIXME - DISPLAY_MARK not implemented (may be hard or impossible)
- this.known_unimplemented(msg.type, "Display Mark");
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_RESET)
- {
- DEBUG > 2 && console.log("Display reset");
- this.surfaces[this.primary_surface].canvas.context.restore();
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_DRAW_COPY)
- {
- var draw_copy = new SpiceMsgDisplayDrawCopy(msg.data);
-
- DEBUG > 1 && this.log_draw("DrawCopy", draw_copy);
-
- if (! draw_copy.base.box.is_same_size(draw_copy.data.src_area))
- this.log_warn("FIXME: DrawCopy src_area is a different size than base.box; we do not handle that yet.");
- if (draw_copy.base.clip.type != SPICE_CLIP_TYPE_NONE)
- this.log_warn("FIXME: DrawCopy we don't handle clipping yet");
- if (draw_copy.data.rop_descriptor != SPICE_ROPD_OP_PUT)
- this.log_warn("FIXME: DrawCopy we don't handle ropd type: " + draw_copy.data.rop_descriptor);
- if (draw_copy.data.mask.flags)
- this.log_warn("FIXME: DrawCopy we don't handle mask flag: " + draw_copy.data.mask.flags);
- if (draw_copy.data.mask.bitmap)
- this.log_warn("FIXME: DrawCopy we don't handle mask");
-
- if (draw_copy.data && draw_copy.data.src_bitmap)
- {
- if (draw_copy.data.src_bitmap.descriptor.flags &&
- draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_CACHE_ME &&
- draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_HIGH_BITS_SET)
- {
- this.log_warn("FIXME: DrawCopy unhandled image flags: " + draw_copy.data.src_bitmap.descriptor.flags);
- DEBUG <= 1 && this.log_draw("DrawCopy", draw_copy);
- }
-
- if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
- {
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- if (! draw_copy.data.src_bitmap.quic)
- {
- this.log_warn("FIXME: DrawCopy could not handle this QUIC file.");
- return false;
- }
- var source_img = convert_spice_quic_to_web(canvas.context,
- draw_copy.data.src_bitmap.quic);
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: source_img,
- tag: "copyquic." + draw_copy.data.src_bitmap.quic.type,
- has_alpha: (draw_copy.data.src_bitmap.quic.type == QUIC_IMAGE_TYPE_RGBA ? true : false) ,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
- }
- else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE ||
- draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS)
- {
- if (! this.cache || ! this.cache[draw_copy.data.src_bitmap.descriptor.id])
- {
- this.log_warn("FIXME: DrawCopy did not find image id " + draw_copy.data.src_bitmap.descriptor.id + " in cache.");
- return false;
- }
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: this.cache[draw_copy.data.src_bitmap.descriptor.id],
- tag: "copycache." + draw_copy.data.src_bitmap.descriptor.id,
- has_alpha: true, /* FIXME - may want this to be false... */
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
-
- /* FIXME - LOSSLESS CACHE ramifications not understood or handled */
- }
- else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
- {
- var source_context = this.surfaces[draw_copy.data.src_bitmap.surface_id].canvas.context;
- var target_context = this.surfaces[draw_copy.base.surface_id].canvas.context;
-
- var source_img = source_context.getImageData(
- draw_copy.data.src_area.left, draw_copy.data.src_area.top,
- draw_copy.data.src_area.right - draw_copy.data.src_area.left,
- draw_copy.data.src_area.bottom - draw_copy.data.src_area.top);
- var computed_src_area = new SpiceRect;
- computed_src_area.top = computed_src_area.left = 0;
- computed_src_area.right = source_img.width;
- computed_src_area.bottom = source_img.height;
-
- /* FIXME - there is a potential optimization here.
- That is, if the surface is from 0,0, and
- both surfaces are alpha surfaces, you should
- be able to just do a drawImage, which should
- save time. */
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: computed_src_area,
- image_data: source_img,
- tag: "copysurf." + draw_copy.data.src_bitmap.surface_id,
- has_alpha: this.surfaces[draw_copy.data.src_bitmap.surface_id].format == SPICE_SURFACE_FMT_32_xRGB ? false : true,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
-
- return true;
- }
- else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
- {
- if (! draw_copy.data.src_bitmap.jpeg)
- {
- this.log_warn("FIXME: DrawCopy could not handle this JPEG file.");
- return false;
- }
-
- // FIXME - how lame is this. Be have it in binary format, and we have
- // to put it into string to get it back into jpeg. Blech.
- var tmpstr = "data:image/jpeg,";
- var img = new Image;
- var i;
- var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg.data);
- for (i = 0; i < qdv.length; i++)
- {
- tmpstr += '%';
- if (qdv[i] < 16)
- tmpstr += '0';
- tmpstr += qdv[i].toString(16);
- }
-
- img.o =
- { base: draw_copy.base,
- tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
- descriptor : draw_copy.data.src_bitmap.descriptor,
- sc : this,
- };
- img.onload = handle_draw_jpeg_onload;
- img.src = tmpstr;
-
- return true;
- }
- else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
- {
- if (! draw_copy.data.src_bitmap.jpeg_alpha)
- {
- this.log_warn("FIXME: DrawCopy could not handle this JPEG ALPHA file.");
- return false;
- }
-
- // FIXME - how lame is this. Be have it in binary format, and we have
- // to put it into string to get it back into jpeg. Blech.
- var tmpstr = "data:image/jpeg,";
- var img = new Image;
- var i;
- var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg_alpha.data);
- for (i = 0; i < qdv.length; i++)
- {
- tmpstr += '%';
- if (qdv[i] < 16)
- tmpstr += '0';
- tmpstr += qdv[i].toString(16);
- }
-
- img.o =
- { base: draw_copy.base,
- tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
- descriptor : draw_copy.data.src_bitmap.descriptor,
- sc : this,
- };
-
- if (this.surfaces[draw_copy.base.surface_id].format == SPICE_SURFACE_FMT_32_ARGB)
- {
-
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- img.alpha_img = convert_spice_lz_to_web(canvas.context,
- draw_copy.data.src_bitmap.jpeg_alpha.alpha);
- }
- img.onload = handle_draw_jpeg_onload;
- img.src = tmpstr;
-
- return true;
- }
- else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
- {
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- if (! draw_copy.data.src_bitmap.bitmap)
- {
- this.log_err("null bitmap");
- return false;
- }
-
- var source_img = convert_spice_bitmap_to_web(canvas.context,
- draw_copy.data.src_bitmap.bitmap);
- if (! source_img)
- {
- this.log_warn("FIXME: Unable to interpret bitmap of format: " +
- draw_copy.data.src_bitmap.bitmap.format);
- return false;
- }
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: source_img,
- tag: "bitmap." + draw_copy.data.src_bitmap.bitmap.format,
- has_alpha: draw_copy.data.src_bitmap.bitmap == SPICE_BITMAP_FMT_32BIT ? false : true,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
- }
- else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
- {
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- if (! draw_copy.data.src_bitmap.lz_rgb)
- {
- this.log_err("null lz_rgb ");
- return false;
- }
-
- if (draw_copy.data.src_bitmap.lz_rgb.top_down != 1)
- this.log_warn("FIXME: Implement non top down support for lz_rgb");
-
- var source_img = convert_spice_lz_to_web(canvas.context,
- draw_copy.data.src_bitmap.lz_rgb);
- if (! source_img)
- {
- this.log_warn("FIXME: Unable to interpret bitmap of type: " +
- draw_copy.data.src_bitmap.lz_rgb.type);
- return false;
- }
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: source_img,
- tag: "lz_rgb." + draw_copy.data.src_bitmap.lz_rgb.type,
- has_alpha: draw_copy.data.src_bitmap.lz_rgb.type == LZ_IMAGE_TYPE_RGBA ? true : false ,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
- }
- else
- {
- this.log_warn("FIXME: DrawCopy unhandled image type: " + draw_copy.data.src_bitmap.descriptor.type);
- this.log_draw("DrawCopy", draw_copy);
- return false;
- }
- }
-
- this.log_warn("FIXME: DrawCopy no src_bitmap.");
- return false;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_DRAW_FILL)
- {
- var draw_fill = new SpiceMsgDisplayDrawFill(msg.data);
-
- DEBUG > 1 && this.log_draw("DrawFill", draw_fill);
-
- if (draw_fill.data.rop_descriptor != SPICE_ROPD_OP_PUT)
- this.log_warn("FIXME: DrawFill we don't handle ropd type: " + draw_fill.data.rop_descriptor);
- if (draw_fill.data.mask.flags)
- this.log_warn("FIXME: DrawFill we don't handle mask flag: " + draw_fill.data.mask.flags);
- if (draw_fill.data.mask.bitmap)
- this.log_warn("FIXME: DrawFill we don't handle mask");
-
- if (draw_fill.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
- {
- // FIXME - do brushes ever have alpha?
- var color = draw_fill.data.brush.color & 0xffffff;
- var color_str = "rgb(" + (color >> 16) + ", " + ((color >> 8) & 0xff) + ", " + (color & 0xff) + ")";
- this.surfaces[draw_fill.base.surface_id].canvas.context.fillStyle = color_str;
-
- this.surfaces[draw_fill.base.surface_id].canvas.context.fillRect(
- draw_fill.base.box.left, draw_fill.base.box.top,
- draw_fill.base.box.right - draw_fill.base.box.left,
- draw_fill.base.box.bottom - draw_fill.base.box.top);
-
- if (DUMP_DRAWS && this.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('width', this.surfaces[draw_fill.base.surface_id].canvas.width);
- debug_canvas.setAttribute('height', this.surfaces[draw_fill.base.surface_id].canvas.height);
- debug_canvas.setAttribute('id', "fillbrush." + draw_fill.base.surface_id + "." + this.surfaces[draw_fill.base.surface_id].draw_count);
- debug_canvas.getContext("2d").fillStyle = color_str;
- debug_canvas.getContext("2d").fillRect(
- draw_fill.base.box.left, draw_fill.base.box.top,
- draw_fill.base.box.right - draw_fill.base.box.left,
- draw_fill.base.box.bottom - draw_fill.base.box.top);
- document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
- }
-
- this.surfaces[draw_fill.base.surface_id].draw_count++;
-
- }
- else
- {
- this.log_warn("FIXME: DrawFill can't handle brush type: " + draw_fill.data.brush.type);
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_COPY_BITS)
- {
- var copy_bits = new SpiceMsgDisplayCopyBits(msg.data);
-
- DEBUG > 1 && this.log_draw("CopyBits", copy_bits);
-
- var source_canvas = this.surfaces[copy_bits.base.surface_id].canvas;
- var source_context = source_canvas.context;
-
- var width = source_canvas.width - copy_bits.src_pos.x;
- var height = source_canvas.height - copy_bits.src_pos.y;
- if (width > (copy_bits.base.box.right - copy_bits.base.box.left))
- width = copy_bits.base.box.right - copy_bits.base.box.left;
- if (height > (copy_bits.base.box.bottom - copy_bits.base.box.top))
- height = copy_bits.base.box.bottom - copy_bits.base.box.top;
-
- var source_img = source_context.getImageData(
- copy_bits.src_pos.x, copy_bits.src_pos.y, width, height);
- //source_context.putImageData(source_img, copy_bits.base.box.left, copy_bits.base.box.top);
- putImageDataWithAlpha(source_context, source_img, copy_bits.base.box.left, copy_bits.base.box.top);
-
- if (DUMP_DRAWS && this.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('width', width);
- debug_canvas.setAttribute('height', height);
- debug_canvas.setAttribute('id', "copybits" + copy_bits.base.surface_id + "." + this.surfaces[copy_bits.base.surface_id].draw_count);
- debug_canvas.getContext("2d").putImageData(source_img, 0, 0);
- document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
- }
-
-
- this.surfaces[copy_bits.base.surface_id].draw_count++;
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES)
- {
- this.known_unimplemented(msg.type, "Inval All Palettes");
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_SURFACE_CREATE)
- {
- if (! ("surfaces" in this))
- this.surfaces = [];
-
- var m = new SpiceMsgSurfaceCreate(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id " + m.surface.surface_id
- + "; " + m.surface.width + "x" + m.surface.height
- + "; format " + m.surface.format
- + "; flags " + m.surface.flags);
- if (m.surface.format != SPICE_SURFACE_FMT_32_xRGB &&
- m.surface.format != SPICE_SURFACE_FMT_32_ARGB)
- {
- this.log_warn("FIXME: cannot handle surface format " + m.surface.format + " yet.");
- return false;
- }
-
- var canvas = document.createElement("canvas");
- canvas.setAttribute('width', m.surface.width);
- canvas.setAttribute('height', m.surface.height);
- canvas.setAttribute('id', "spice_surface_" + m.surface.surface_id);
- canvas.setAttribute('tabindex', m.surface.surface_id);
- canvas.context = canvas.getContext("2d");
-
- if (DUMP_CANVASES && this.parent.dump_id)
- document.getElementById(this.parent.dump_id).appendChild(canvas);
-
- m.surface.canvas = canvas;
- m.surface.draw_count = 0;
- this.surfaces[m.surface.surface_id] = m.surface;
-
- if (m.surface.flags & SPICE_SURFACE_FLAGS_PRIMARY)
- {
- this.primary_surface = m.surface.surface_id;
-
- /* This .save() is done entirely to enable SPICE_MSG_DISPLAY_RESET */
- canvas.context.save();
- document.getElementById(this.parent.screen_id).appendChild(canvas);
-
- /* We're going to leave width dynamic, but correctly set the height */
- document.getElementById(this.parent.screen_id).style.height = m.surface.height + "px";
- this.hook_events();
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_SURFACE_DESTROY)
- {
- var m = new SpiceMsgSurfaceDestroy(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id " + m.surface_id);
- this.delete_surface(m.surface_id);
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_CREATE)
- {
- var m = new SpiceMsgDisplayStreamCreate(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgStreamCreate id" + m.id);
- if (!this.streams)
- this.streams = new Array();
- if (this.streams[m.id])
- console.log("Stream already exists");
- else
- this.streams[m.id] = m;
- if (m.codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG)
- console.log("Unhandled stream codec: "+m.codec_type);
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA)
- {
- var m = new SpiceMsgDisplayStreamData(msg.data);
- if (!this.streams[m.base.id])
- {
- console.log("no stream for data");
- return false;
- }
- if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
- {
- var tmpstr = "data:image/jpeg,";
- var img = new Image;
- var i;
- for (i = 0; i < m.data.length; i++)
- {
- tmpstr += '%';
- if (m.data[i] < 16)
- tmpstr += '0';
- tmpstr += m.data[i].toString(16);
- }
- var strm_base = new SpiceMsgDisplayBase();
- strm_base.surface_id = this.streams[m.base.id].surface_id;
- strm_base.box = this.streams[m.base.id].dest;
- strm_base.clip = this.streams[m.base.id].clip;
- img.o =
- { base: strm_base,
- tag: "mjpeg." + m.base.id,
- descriptor: null,
- sc : this,
- };
- img.onload = handle_draw_jpeg_onload;
- img.src = tmpstr;
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
- {
- var m = new SpiceMsgDisplayStreamClip(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id);
- this.streams[m.id].clip = m.clip;
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY)
- {
- var m = new SpiceMsgDisplayStreamDestroy(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgStreamDestroy id" + m.id);
- this.streams[m.id] = undefined;
- return true;
- }
- if (msg.type == SPICE_MSG_DISPLAY_INVAL_LIST)
- {
- var m = new SpiceMsgDisplayInvalList(msg.data);
- var i;
- DEBUG > 1 && console.log(this.type + ": MsgInvalList " + m.count + " items");
- for (i = 0; i < m.count; i++)
- if (this.cache[m.resources[i].id] != undefined)
- delete this.cache[m.resources[i].id];
- return true;
- }
-
- return false;
-}
-
-SpiceDisplayConn.prototype.delete_surface = function(surface_id)
-{
- var canvas = document.getElementById("spice_surface_" + surface_id);
- if (DUMP_CANVASES && this.parent.dump_id)
- document.getElementById(this.parent.dump_id).removeChild(canvas);
- if (this.primary_surface == surface_id)
- {
- this.unhook_events();
- this.primary_surface = undefined;
- document.getElementById(this.parent.screen_id).removeChild(canvas);
- }
-
- delete this.surfaces[surface_id];
-}
-
-
-SpiceDisplayConn.prototype.draw_copy_helper = function(o)
-{
-
- var canvas = this.surfaces[o.base.surface_id].canvas;
- if (o.has_alpha)
- {
- /* FIXME - This is based on trial + error, not a serious thoughtful
- analysis of what Spice requires. See display.js for more. */
- if (this.surfaces[o.base.surface_id].format == SPICE_SURFACE_FMT_32_xRGB)
- {
- stripAlpha(o.image_data);
- canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
- }
- else
- putImageDataWithAlpha(canvas.context, o.image_data,
- o.base.box.left, o.base.box.top);
- }
- else
- canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
-
- if (o.src_area.left > 0 || o.src_area.top > 0)
- {
- this.log_warn("FIXME: DrawCopy not shifting draw copies just yet...");
- }
-
- if (o.descriptor && (o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
- {
- if (! ("cache" in this))
- this.cache = {};
- this.cache[o.descriptor.id] = o.image_data;
- }
-
- if (DUMP_DRAWS && this.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('width', o.image_data.width);
- debug_canvas.setAttribute('height', o.image_data.height);
- debug_canvas.setAttribute('id', o.tag + "." +
- this.surfaces[o.base.surface_id].draw_count + "." +
- o.base.surface_id + "@" + o.base.box.left + "x" + o.base.box.top);
- debug_canvas.getContext("2d").putImageData(o.image_data, 0, 0);
- document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
- }
-
- this.surfaces[o.base.surface_id].draw_count++;
-
- return true;
-}
-
-
-SpiceDisplayConn.prototype.log_draw = function(prefix, draw)
-{
- var str = prefix + "." + draw.base.surface_id + "." + this.surfaces[draw.base.surface_id].draw_count + ": ";
- str += "base.box " + draw.base.box.left + ", " + draw.base.box.top + " to " +
- draw.base.box.right + ", " + draw.base.box.bottom;
- str += "; clip.type " + draw.base.clip.type;
-
- if (draw.data)
- {
- if (draw.data.src_area)
- str += "; src_area " + draw.data.src_area.left + ", " + draw.data.src_area.top + " to "
- + draw.data.src_area.right + ", " + draw.data.src_area.bottom;
-
- if (draw.data.src_bitmap && draw.data.src_bitmap != null)
- {
- str += "; src_bitmap id: " + draw.data.src_bitmap.descriptor.id;
- str += "; src_bitmap width " + draw.data.src_bitmap.descriptor.width + ", height " + draw.data.src_bitmap.descriptor.height;
- str += "; src_bitmap type " + draw.data.src_bitmap.descriptor.type + ", flags " + draw.data.src_bitmap.descriptor.flags;
- if (draw.data.src_bitmap.surface_id !== undefined)
- str += "; src_bitmap surface_id " + draw.data.src_bitmap.surface_id;
- if (draw.data.src_bitmap.quic)
- str += "; QUIC type " + draw.data.src_bitmap.quic.type +
- "; width " + draw.data.src_bitmap.quic.width +
- "; height " + draw.data.src_bitmap.quic.height ;
- if (draw.data.src_bitmap.lz_rgb)
- str += "; LZ_RGB length " + draw.data.src_bitmap.lz_rgb.length +
- "; magic " + draw.data.src_bitmap.lz_rgb.magic +
- "; version 0x" + draw.data.src_bitmap.lz_rgb.version.toString(16) +
- "; type " + draw.data.src_bitmap.lz_rgb.type +
- "; width " + draw.data.src_bitmap.lz_rgb.width +
- "; height " + draw.data.src_bitmap.lz_rgb.height +
- "; stride " + draw.data.src_bitmap.lz_rgb.stride +
- "; top down " + draw.data.src_bitmap.lz_rgb.top_down;
- }
- else
- str += "; src_bitmap is null";
-
- if (draw.data.brush)
- {
- if (draw.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
- str += "; brush.color 0x" + draw.data.brush.color.toString(16);
- if (draw.data.brush.type == SPICE_BRUSH_TYPE_PATTERN)
- {
- str += "; brush.pat ";
- if (draw.data.brush.pattern.pat != null)
- str += "[SpiceImage]";
- else
- str += "[null]";
- str += " at " + draw.data.brush.pattern.pos.x + ", " + draw.data.brush.pattern.pos.y;
- }
- }
-
- str += "; rop_descriptor " + draw.data.rop_descriptor;
- if (draw.data.scale_mode !== undefined)
- str += "; scale_mode " + draw.data.scale_mode;
- str += "; mask.flags " + draw.data.mask.flags;
- str += "; mask.pos " + draw.data.mask.pos.x + ", " + draw.data.mask.pos.y;
- if (draw.data.mask.bitmap != null)
- {
- str += "; mask.bitmap width " + draw.data.mask.bitmap.descriptor.width + ", height " + draw.data.mask.bitmap.descriptor.height;
- str += "; mask.bitmap type " + draw.data.mask.bitmap.descriptor.type + ", flags " + draw.data.mask.bitmap.descriptor.flags;
- }
- else
- str += "; mask.bitmap is null";
- }
-
- console.log(str);
-}
-
-SpiceDisplayConn.prototype.hook_events = function()
-{
- if (this.primary_surface !== undefined)
- {
- var canvas = this.surfaces[this.primary_surface].canvas;
- canvas.sc = this.parent;
- canvas.addEventListener('mousemove', handle_mousemove);
- canvas.addEventListener('mousedown', handle_mousedown);
- canvas.addEventListener('contextmenu', handle_contextmenu);
- canvas.addEventListener('mouseup', handle_mouseup);
- canvas.addEventListener('keydown', handle_keydown);
- canvas.addEventListener('keyup', handle_keyup);
- canvas.addEventListener('mouseout', handle_mouseout);
- canvas.addEventListener('mouseover', handle_mouseover);
- canvas.addEventListener('mousewheel', handle_mousewheel);
- canvas.focus();
- }
-}
-
-SpiceDisplayConn.prototype.unhook_events = function()
-{
- if (this.primary_surface !== undefined)
- {
- var canvas = this.surfaces[this.primary_surface].canvas;
- canvas.removeEventListener('mousemove', handle_mousemove);
- canvas.removeEventListener('mousedown', handle_mousedown);
- canvas.removeEventListener('contextmenu', handle_contextmenu);
- canvas.removeEventListener('mouseup', handle_mouseup);
- canvas.removeEventListener('keydown', handle_keydown);
- canvas.removeEventListener('keyup', handle_keyup);
- canvas.removeEventListener('mouseout', handle_mouseout);
- canvas.removeEventListener('mouseover', handle_mouseover);
- canvas.removeEventListener('mousewheel', handle_mousewheel);
- }
-}
-
-
-SpiceDisplayConn.prototype.destroy_surfaces = function()
-{
- for (var s in this.surfaces)
- {
- this.delete_surface(this.surfaces[s].surface_id);
- }
-
- this.surfaces = undefined;
-}
-
-
-function handle_mouseover(e)
-{
- this.focus();
-}
-
-function handle_mouseout(e)
-{
- if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor)
- this.sc.cursor.spice_simulated_cursor.style.display = 'none';
- this.blur();
-}
-
-function handle_draw_jpeg_onload()
-{
- var temp_canvas = null;
- var context;
-
- /*------------------------------------------------------------
- ** FIXME:
- ** The helper should be extended to be able to handle actual HtmlImageElements
- ** ...and the cache should be modified to do so as well
- **----------------------------------------------------------*/
- if (this.o.sc.surfaces[this.o.base.surface_id] === undefined)
- {
- // This can happen; if the jpeg image loads after our surface
- // has been destroyed (e.g. open a menu, close it quickly),
- // we'll find we have no surface.
- DEBUG > 2 && this.o.sc.log_info("Discarding jpeg; presumed lost surface " + this.o.base.surface_id);
- temp_canvas = document.createElement("canvas");
- temp_canvas.setAttribute('width', this.o.base.box.right);
- temp_canvas.setAttribute('height', this.o.base.box.bottom);
- context = temp_canvas.getContext("2d");
- }
- else
- context = this.o.sc.surfaces[this.o.base.surface_id].canvas.context;
-
- if (this.alpha_img)
- {
- var c = document.createElement("canvas");
- var t = c.getContext("2d");
- c.setAttribute('width', this.alpha_img.width);
- c.setAttribute('height', this.alpha_img.height);
- t.putImageData(this.alpha_img, 0, 0);
- t.globalCompositeOperation = 'source-in';
- t.drawImage(this, 0, 0);
-
- context.drawImage(c, this.o.base.box.left, this.o.base.box.top);
-
- if (this.o.descriptor &&
- (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
- {
- if (! ("cache" in this.o.sc))
- this.o.sc.cache = {};
-
- this.o.sc.cache[this.o.descriptor.id] =
- t.getImageData(0, 0,
- this.alpha_img.width,
- this.alpha_img.height);
- }
- }
- else
- {
- context.drawImage(this, this.o.base.box.left, this.o.base.box.top);
-
- // Give the Garbage collector a clue to recycle this; avoids
- // fairly massive memory leaks during video playback
- this.src = null;
-
- if (this.o.descriptor &&
- (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
- {
- if (! ("cache" in this.o.sc))
- this.o.sc.cache = {};
-
- this.o.sc.cache[this.o.descriptor.id] =
- context.getImageData(this.o.base.box.left, this.o.base.box.top,
- this.o.base.box.right - this.o.base.box.left,
- this.o.base.box.bottom - this.o.base.box.top);
- }
- }
-
- if (temp_canvas == null)
- {
- if (DUMP_DRAWS && this.o.sc.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('id', this.o.tag + "." +
- this.o.sc.surfaces[this.o.base.surface_id].draw_count + "." +
- this.o.base.surface_id + "@" + this.o.base.box.left + "x" + this.o.base.box.top);
- debug_canvas.getContext("2d").drawImage(this, 0, 0);
- document.getElementById(this.o.sc.parent.dump_id).appendChild(debug_canvas);
- }
-
- this.o.sc.surfaces[this.o.base.surface_id].draw_count++;
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/enums.js b/plugins/kimchi/ui/spice-html5/enums.js
deleted file mode 100644
index d99b38e..0000000
--- a/plugins/kimchi/ui/spice-html5/enums.js
+++ /dev/null
@@ -1,324 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** enums.js
-** 'constants' for Spice
-**--------------------------------------------------------------------------*/
-var SPICE_MAGIC = "REDQ";
-var SPICE_VERSION_MAJOR = 2;
-var SPICE_VERSION_MINOR = 2;
-
-var SPICE_CONNECT_TIMEOUT = (30 * 1000);
-
-var SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION = 0;
-var SPICE_COMMON_CAP_AUTH_SPICE = 1;
-var SPICE_COMMON_CAP_AUTH_SASL = 2;
-var SPICE_COMMON_CAP_MINI_HEADER = 3;
-
-var SPICE_TICKET_KEY_PAIR_LENGTH = 1024;
-var SPICE_TICKET_PUBKEY_BYTES = (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34);
-
-var SPICE_LINK_ERR_OK = 0,
- SPICE_LINK_ERR_ERROR = 1,
- SPICE_LINK_ERR_INVALID_MAGIC = 2,
- SPICE_LINK_ERR_INVALID_DATA = 3,
- SPICE_LINK_ERR_VERSION_MISMATCH = 4,
- SPICE_LINK_ERR_NEED_SECURED = 5,
- SPICE_LINK_ERR_NEED_UNSECURED = 6,
- SPICE_LINK_ERR_PERMISSION_DENIED = 7,
- SPICE_LINK_ERR_BAD_CONNECTION_ID = 8,
- SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE = 9;
-
-var SPICE_MSG_MIGRATE = 1;
-var SPICE_MSG_MIGRATE_DATA = 2;
-var SPICE_MSG_SET_ACK = 3;
-var SPICE_MSG_PING = 4;
-var SPICE_MSG_WAIT_FOR_CHANNELS = 5;
-var SPICE_MSG_DISCONNECTING = 6;
-var SPICE_MSG_NOTIFY = 7;
-var SPICE_MSG_LIST = 8;
-
-var SPICE_MSG_MAIN_MIGRATE_BEGIN = 101;
-var SPICE_MSG_MAIN_MIGRATE_CANCEL = 102;
-var SPICE_MSG_MAIN_INIT = 103;
-var SPICE_MSG_MAIN_CHANNELS_LIST = 104;
-var SPICE_MSG_MAIN_MOUSE_MODE = 105;
-var SPICE_MSG_MAIN_MULTI_MEDIA_TIME = 106;
-var SPICE_MSG_MAIN_AGENT_CONNECTED = 107;
-var SPICE_MSG_MAIN_AGENT_DISCONNECTED = 108;
-var SPICE_MSG_MAIN_AGENT_DATA = 109;
-var SPICE_MSG_MAIN_AGENT_TOKEN = 110;
-var SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST = 111;
-var SPICE_MSG_MAIN_MIGRATE_END = 112;
-var SPICE_MSG_MAIN_NAME = 113;
-var SPICE_MSG_MAIN_UUID = 114;
-var SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS = 115;
-var SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS = 116;
-var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK = 117;
-var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK = 118;
-var SPICE_MSG_END_MAIN = 119;
-
-
-
-var SPICE_MSGC_ACK_SYNC = 1;
-var SPICE_MSGC_ACK = 2;
-var SPICE_MSGC_PONG = 3;
-var SPICE_MSGC_MIGRATE_FLUSH_MARK = 4;
-var SPICE_MSGC_MIGRATE_DATA = 5;
-var SPICE_MSGC_DISCONNECTING = 6;
-
-
-var SPICE_MSGC_MAIN_CLIENT_INFO = 101;
-var SPICE_MSGC_MAIN_MIGRATE_CONNECTED = 102;
-var SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR = 103;
-var SPICE_MSGC_MAIN_ATTACH_CHANNELS = 104;
-var SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST = 105;
-var SPICE_MSGC_MAIN_AGENT_START = 106;
-var SPICE_MSGC_MAIN_AGENT_DATA = 107;
-var SPICE_MSGC_MAIN_AGENT_TOKEN = 108;
-var SPICE_MSGC_MAIN_MIGRATE_END = 109;
-var SPICE_MSGC_END_MAIN = 110;
-
-var SPICE_MSG_DISPLAY_MODE = 101;
-var SPICE_MSG_DISPLAY_MARK = 102;
-var SPICE_MSG_DISPLAY_RESET = 103;
-var SPICE_MSG_DISPLAY_COPY_BITS = 104;
-var SPICE_MSG_DISPLAY_INVAL_LIST = 105;
-var SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS = 106;
-var SPICE_MSG_DISPLAY_INVAL_PALETTE = 107;
-var SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES= 108;
-
-var SPICE_MSG_DISPLAY_STREAM_CREATE = 122;
-var SPICE_MSG_DISPLAY_STREAM_DATA = 123;
-var SPICE_MSG_DISPLAY_STREAM_CLIP = 124;
-var SPICE_MSG_DISPLAY_STREAM_DESTROY = 125;
-var SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL= 126;
-
-var SPICE_MSG_DISPLAY_DRAW_FILL = 302;
-var SPICE_MSG_DISPLAY_DRAW_OPAQUE = 303;
-var SPICE_MSG_DISPLAY_DRAW_COPY = 304;
-var SPICE_MSG_DISPLAY_DRAW_BLEND = 305;
-var SPICE_MSG_DISPLAY_DRAW_BLACKNESS = 306;
-var SPICE_MSG_DISPLAY_DRAW_WHITENESS = 307;
-var SPICE_MSG_DISPLAY_DRAW_INVERS = 308;
-var SPICE_MSG_DISPLAY_DRAW_ROP3 = 309;
-var SPICE_MSG_DISPLAY_DRAW_STROKE = 310;
-var SPICE_MSG_DISPLAY_DRAW_TEXT = 311;
-var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT = 312;
-var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND = 313;
-var SPICE_MSG_DISPLAY_SURFACE_CREATE = 314;
-var SPICE_MSG_DISPLAY_SURFACE_DESTROY = 315;
-
-var SPICE_MSGC_DISPLAY_INIT = 101;
-
-var SPICE_MSG_INPUTS_INIT = 101;
-var SPICE_MSG_INPUTS_KEY_MODIFIERS = 102;
-
-var SPICE_MSG_INPUTS_MOUSE_MOTION_ACK = 111;
-
-var SPICE_MSGC_INPUTS_KEY_DOWN = 101;
-var SPICE_MSGC_INPUTS_KEY_UP = 102;
-var SPICE_MSGC_INPUTS_KEY_MODIFIERS = 103;
-
-var SPICE_MSGC_INPUTS_MOUSE_MOTION = 111;
-var SPICE_MSGC_INPUTS_MOUSE_POSITION = 112;
-var SPICE_MSGC_INPUTS_MOUSE_PRESS = 113;
-var SPICE_MSGC_INPUTS_MOUSE_RELEASE = 114;
-
-var SPICE_MSG_CURSOR_INIT = 101;
-var SPICE_MSG_CURSOR_RESET = 102;
-var SPICE_MSG_CURSOR_SET = 103;
-var SPICE_MSG_CURSOR_MOVE = 104;
-var SPICE_MSG_CURSOR_HIDE = 105;
-var SPICE_MSG_CURSOR_TRAIL = 106;
-var SPICE_MSG_CURSOR_INVAL_ONE = 107;
-var SPICE_MSG_CURSOR_INVAL_ALL = 108;
-
-var SPICE_MSG_PLAYBACK_DATA = 101;
-var SPICE_MSG_PLAYBACK_MODE = 102;
-var SPICE_MSG_PLAYBACK_START = 103;
-var SPICE_MSG_PLAYBACK_STOP = 104;
-var SPICE_MSG_PLAYBACK_VOLUME = 105;
-var SPICE_MSG_PLAYBACK_MUTE = 106;
-var SPICE_MSG_PLAYBACK_LATENCY = 107;
-
-var SPICE_PLAYBACK_CAP_CELT_0_5_1 = 0;
-var SPICE_PLAYBACK_CAP_VOLUME = 1;
-var SPICE_PLAYBACK_CAP_LATENCY = 2;
-var SPICE_PLAYBACK_CAP_OPUS = 3;
-
-var SPICE_AUDIO_DATA_MODE_INVALID = 0;
-var SPICE_AUDIO_DATA_MODE_RAW = 1;
-var SPICE_AUDIO_DATA_MODE_CELT_0_5_1 = 2;
-var SPICE_AUDIO_DATA_MODE_OPUS = 3;
-
-var SPICE_AUDIO_FMT_INVALID = 0;
-var SPICE_AUDIO_FMT_S16 = 1;
-
-var SPICE_CHANNEL_MAIN = 1;
-var SPICE_CHANNEL_DISPLAY = 2;
-var SPICE_CHANNEL_INPUTS = 3;
-var SPICE_CHANNEL_CURSOR = 4;
-var SPICE_CHANNEL_PLAYBACK = 5;
-var SPICE_CHANNEL_RECORD = 6;
-var SPICE_CHANNEL_TUNNEL = 7;
-var SPICE_CHANNEL_SMARTCARD = 8;
-var SPICE_CHANNEL_USBREDIR = 9;
-
-var SPICE_SURFACE_FLAGS_PRIMARY = (1 << 0);
-
-var SPICE_NOTIFY_SEVERITY_INFO = 0;
-var SPICE_NOTIFY_SEVERITY_WARN = 1;
-var SPICE_NOTIFY_SEVERITY_ERROR = 2;
-
-var SPICE_MOUSE_MODE_SERVER = (1 << 0),
- SPICE_MOUSE_MODE_CLIENT = (1 << 1),
- SPICE_MOUSE_MODE_MASK = 0x3;
-
-var SPICE_CLIP_TYPE_NONE = 0;
-var SPICE_CLIP_TYPE_RECTS = 1;
-
-var SPICE_IMAGE_TYPE_BITMAP = 0;
-var SPICE_IMAGE_TYPE_QUIC = 1;
-var SPICE_IMAGE_TYPE_RESERVED = 2;
-var SPICE_IMAGE_TYPE_LZ_PLT = 100;
-var SPICE_IMAGE_TYPE_LZ_RGB = 101;
-var SPICE_IMAGE_TYPE_GLZ_RGB = 102;
-var SPICE_IMAGE_TYPE_FROM_CACHE = 103;
-var SPICE_IMAGE_TYPE_SURFACE = 104;
-var SPICE_IMAGE_TYPE_JPEG = 105;
-var SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS = 106;
-var SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB = 107;
-var SPICE_IMAGE_TYPE_JPEG_ALPHA = 108;
-
-var SPICE_IMAGE_FLAGS_CACHE_ME = (1 << 0),
- SPICE_IMAGE_FLAGS_HIGH_BITS_SET = (1 << 1),
- SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME = (1 << 2);
-
-var SPICE_BITMAP_FLAGS_PAL_CACHE_ME = (1 << 0),
- SPICE_BITMAP_FLAGS_PAL_FROM_CACHE = (1 << 1),
- SPICE_BITMAP_FLAGS_TOP_DOWN = (1 << 2),
- SPICE_BITMAP_FLAGS_MASK = 0x7;
-
-var SPICE_BITMAP_FMT_INVALID = 0,
- SPICE_BITMAP_FMT_1BIT_LE = 1,
- SPICE_BITMAP_FMT_1BIT_BE = 2,
- SPICE_BITMAP_FMT_4BIT_LE = 3,
- SPICE_BITMAP_FMT_4BIT_BE = 4,
- SPICE_BITMAP_FMT_8BIT = 5,
- SPICE_BITMAP_FMT_16BIT = 6,
- SPICE_BITMAP_FMT_24BIT = 7,
- SPICE_BITMAP_FMT_32BIT = 8,
- SPICE_BITMAP_FMT_RGBA = 9;
-
-
-var SPICE_CURSOR_FLAGS_NONE = (1 << 0),
- SPICE_CURSOR_FLAGS_CACHE_ME = (1 << 1),
- SPICE_CURSOR_FLAGS_FROM_CACHE = (1 << 2),
- SPICE_CURSOR_FLAGS_MASK = 0x7;
-
-var SPICE_MOUSE_BUTTON_MASK_LEFT = (1 << 0),
- SPICE_MOUSE_BUTTON_MASK_MIDDLE = (1 << 1),
- SPICE_MOUSE_BUTTON_MASK_RIGHT = (1 << 2),
- SPICE_MOUSE_BUTTON_MASK_MASK = 0x7;
-
-var SPICE_MOUSE_BUTTON_INVALID = 0;
-var SPICE_MOUSE_BUTTON_LEFT = 1;
-var SPICE_MOUSE_BUTTON_MIDDLE = 2;
-var SPICE_MOUSE_BUTTON_RIGHT = 3;
-var SPICE_MOUSE_BUTTON_UP = 4;
-var SPICE_MOUSE_BUTTON_DOWN = 5;
-
-var SPICE_BRUSH_TYPE_NONE = 0,
- SPICE_BRUSH_TYPE_SOLID = 1,
- SPICE_BRUSH_TYPE_PATTERN = 2;
-
-var SPICE_SURFACE_FMT_INVALID = 0,
- SPICE_SURFACE_FMT_1_A = 1,
- SPICE_SURFACE_FMT_8_A = 8,
- SPICE_SURFACE_FMT_16_555 = 16,
- SPICE_SURFACE_FMT_32_xRGB = 32,
- SPICE_SURFACE_FMT_16_565 = 80,
- SPICE_SURFACE_FMT_32_ARGB = 96;
-
-var SPICE_ROPD_INVERS_SRC = (1 << 0),
- SPICE_ROPD_INVERS_BRUSH = (1 << 1),
- SPICE_ROPD_INVERS_DEST = (1 << 2),
- SPICE_ROPD_OP_PUT = (1 << 3),
- SPICE_ROPD_OP_OR = (1 << 4),
- SPICE_ROPD_OP_AND = (1 << 5),
- SPICE_ROPD_OP_XOR = (1 << 6),
- SPICE_ROPD_OP_BLACKNESS = (1 << 7),
- SPICE_ROPD_OP_WHITENESS = (1 << 8),
- SPICE_ROPD_OP_INVERS = (1 << 9),
- SPICE_ROPD_INVERS_RES = (1 << 10),
- SPICE_ROPD_MASK = 0x7ff;
-
-var LZ_IMAGE_TYPE_INVALID = 0,
- LZ_IMAGE_TYPE_PLT1_LE = 1,
- LZ_IMAGE_TYPE_PLT1_BE = 2, // PLT stands for palette
- LZ_IMAGE_TYPE_PLT4_LE = 3,
- LZ_IMAGE_TYPE_PLT4_BE = 4,
- LZ_IMAGE_TYPE_PLT8 = 5,
- LZ_IMAGE_TYPE_RGB16 = 6,
- LZ_IMAGE_TYPE_RGB24 = 7,
- LZ_IMAGE_TYPE_RGB32 = 8,
- LZ_IMAGE_TYPE_RGBA = 9,
- LZ_IMAGE_TYPE_XXXA = 10;
-
-
-var QUIC_IMAGE_TYPE_INVALID = 0,
- QUIC_IMAGE_TYPE_GRAY = 1,
- QUIC_IMAGE_TYPE_RGB16 = 2,
- QUIC_IMAGE_TYPE_RGB24 = 3,
- QUIC_IMAGE_TYPE_RGB32 = 4,
- QUIC_IMAGE_TYPE_RGBA = 5;
-
-var SPICE_INPUT_MOTION_ACK_BUNCH = 4;
-
-
-var SPICE_CURSOR_TYPE_ALPHA = 0,
- SPICE_CURSOR_TYPE_MONO = 1,
- SPICE_CURSOR_TYPE_COLOR4 = 2,
- SPICE_CURSOR_TYPE_COLOR8 = 3,
- SPICE_CURSOR_TYPE_COLOR16 = 4,
- SPICE_CURSOR_TYPE_COLOR24 = 5,
- SPICE_CURSOR_TYPE_COLOR32 = 6;
-
-var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1;
-
-var VD_AGENT_PROTOCOL = 1;
-
-var VD_AGENT_MOUSE_STATE = 1,
- VD_AGENT_MONITORS_CONFIG = 2,
- VD_AGENT_REPLY = 3,
- VD_AGENT_CLIPBOARD = 4,
- VD_AGENT_DISPLAY_CONFIG = 5,
- VD_AGENT_ANNOUNCE_CAPABILITIES = 6,
- VD_AGENT_CLIPBOARD_GRAB = 7,
- VD_AGENT_CLIPBOARD_REQUEST = 8,
- VD_AGENT_CLIPBOARD_RELEASE = 9,
- VD_AGENT_FILE_XFER_START =10,
- VD_AGENT_FILE_XFER_STATUS =11,
- VD_AGENT_FILE_XFER_DATA =12,
- VD_AGENT_CLIENT_DISCONNECTED =13,
- VD_AGENT_MAX_CLIPBOARD =14;
diff --git a/plugins/kimchi/ui/spice-html5/inputs.js b/plugins/kimchi/ui/spice-html5/inputs.js
deleted file mode 100644
index c904eda..0000000
--- a/plugins/kimchi/ui/spice-html5/inputs.js
+++ /dev/null
@@ -1,280 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
- ** Modifier Keystates
- ** These need to be tracked because focus in and out can get the keyboard
- ** out of sync.
- **------------------------------------------------------------------------*/
-var Shift_state = -1;
-var Ctrl_state = -1;
-var Alt_state = -1;
-var Meta_state = -1;
-
-/*----------------------------------------------------------------------------
-** SpiceInputsConn
-** Drive the Spice Inputs channel (e.g. mouse + keyboard)
-**--------------------------------------------------------------------------*/
-function SpiceInputsConn()
-{
- SpiceConn.apply(this, arguments);
-
- this.mousex = undefined;
- this.mousey = undefined;
- this.button_state = 0;
- this.waiting_for_ack = 0;
-}
-
-SpiceInputsConn.prototype = Object.create(SpiceConn.prototype);
-SpiceInputsConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_INPUTS_INIT)
- {
- var inputs_init = new SpiceMsgInputsInit(msg.data);
- this.keyboard_modifiers = inputs_init.keyboard_modifiers;
- DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers);
- // FIXME - We don't do anything with the keyboard modifiers...
- return true;
- }
- if (msg.type == SPICE_MSG_INPUTS_KEY_MODIFIERS)
- {
- var key = new SpiceMsgInputsKeyModifiers(msg.data);
- this.keyboard_modifiers = key.keyboard_modifiers;
- DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers);
- // FIXME - We don't do anything with the keyboard modifiers...
- return true;
- }
- if (msg.type == SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
- {
- DEBUG > 1 && console.log("mouse motion ack");
- this.waiting_for_ack -= SPICE_INPUT_MOTION_ACK_BUNCH;
- return true;
- }
- return false;
-}
-
-
-
-function handle_mousemove(e)
-{
- var msg = new SpiceMiniData();
- var move;
- if (this.sc.mouse_mode == SPICE_MOUSE_MODE_CLIENT)
- {
- move = new SpiceMsgcMousePosition(this.sc, e)
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
- }
- else
- {
- move = new SpiceMsgcMouseMotion(this.sc, e)
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
- }
- if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
- {
- if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH))
- {
- this.sc.inputs.send_msg(msg);
- this.sc.inputs.waiting_for_ack++;
- }
- else
- {
- DEBUG > 0 && this.sc.log_info("Discarding mouse motion");
- }
- }
-
- if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor)
- {
- this.sc.cursor.spice_simulated_cursor.style.display = 'block';
- this.sc.cursor.spice_simulated_cursor.style.left = e.pageX - this.sc.cursor.spice_simulated_cursor.spice_hot_x + 'px';
- this.sc.cursor.spice_simulated_cursor.style.top = e.pageY - this.sc.cursor.spice_simulated_cursor.spice_hot_y + 'px';
- e.preventDefault();
- }
-
-}
-
-function handle_mousedown(e)
-{
- var press = new SpiceMsgcMousePress(this.sc, e)
- var msg = new SpiceMiniData();
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
- if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_contextmenu(e)
-{
- e.preventDefault();
- return false;
-}
-
-function handle_mouseup(e)
-{
- var release = new SpiceMsgcMouseRelease(this.sc, e)
- var msg = new SpiceMiniData();
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
- if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_mousewheel(e)
-{
- var press = new SpiceMsgcMousePress;
- var release = new SpiceMsgcMouseRelease;
- if (e.wheelDelta > 0)
- press.button = release.button = SPICE_MOUSE_BUTTON_UP;
- else
- press.button = release.button = SPICE_MOUSE_BUTTON_DOWN;
- press.buttons_state = 0;
- release.buttons_state = 0;
-
- var msg = new SpiceMiniData();
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
- if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
- this.sc.inputs.send_msg(msg);
-
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
- if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_keydown(e)
-{
- var key = new SpiceMsgcKeyDown(e)
- var msg = new SpiceMiniData();
- check_and_update_modifiers(e, key.code, this.sc);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
- if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_keyup(e)
-{
- var key = new SpiceMsgcKeyUp(e)
- var msg = new SpiceMiniData();
- check_and_update_modifiers(e, key.code, this.sc);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
- if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function sendCtrlAltDel()
-{
- if (sc && sc.inputs && sc.inputs.state === "ready"){
- var key = new SpiceMsgcKeyDown();
- var msg = new SpiceMiniData();
-
- update_modifier(true, KEY_LCtrl, sc);
- update_modifier(true, KEY_Alt, sc);
-
- key.code = KEY_KP_Decimal;
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
- sc.inputs.send_msg(msg);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
- sc.inputs.send_msg(msg);
-
- if(Ctrl_state == false) update_modifier(false, KEY_LCtrl, sc);
- if(Alt_state == false) update_modifier(false, KEY_Alt, sc);
- }
-}
-
-function update_modifier(state, code, sc)
-{
- var msg = new SpiceMiniData();
- if (!state)
- {
- var key = new SpiceMsgcKeyUp()
- key.code =(0x80|code);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
- }
- else
- {
- var key = new SpiceMsgcKeyDown()
- key.code = code;
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
- }
-
- sc.inputs.send_msg(msg);
-}
-
-function check_and_update_modifiers(e, code, sc)
-{
- if (Shift_state === -1)
- {
- Shift_state = e.shiftKey;
- Ctrl_state = e.ctrlKey;
- Alt_state = e.altKey;
- Meta_state = e.metaKey;
- }
-
- if (code === KEY_ShiftL)
- Shift_state = true;
- else if (code === KEY_Alt)
- Alt_state = true;
- else if (code === KEY_LCtrl)
- Ctrl_state = true;
- else if (code === 0xE0B5)
- Meta_state = true;
- else if (code === (0x80|KEY_ShiftL))
- Shift_state = false;
- else if (code === (0x80|KEY_Alt))
- Alt_state = false;
- else if (code === (0x80|KEY_LCtrl))
- Ctrl_state = false;
- else if (code === (0x80|0xE0B5))
- Meta_state = false;
-
- if (sc && sc.inputs && sc.inputs.state === "ready")
- {
- if (Shift_state != e.shiftKey)
- {
- console.log("Shift state out of sync");
- update_modifier(e.shiftKey, KEY_ShiftL, sc);
- Shift_state = e.shiftKey;
- }
- if (Alt_state != e.altKey)
- {
- console.log("Alt state out of sync");
- update_modifier(e.altKey, KEY_Alt, sc);
- Alt_state = e.altKey;
- }
- if (Ctrl_state != e.ctrlKey)
- {
- console.log("Ctrl state out of sync");
- update_modifier(e.ctrlKey, KEY_LCtrl, sc);
- Ctrl_state = e.ctrlKey;
- }
- if (Meta_state != e.metaKey)
- {
- console.log("Meta state out of sync");
- update_modifier(e.metaKey, 0xE0B5, sc);
- Meta_state = e.metaKey;
- }
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/lz.js b/plugins/kimchi/ui/spice-html5/lz.js
deleted file mode 100644
index 4292eac..0000000
--- a/plugins/kimchi/ui/spice-html5/lz.js
+++ /dev/null
@@ -1,166 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** lz.js
-** Functions for handling SPICE_IMAGE_TYPE_LZ_RGB
-** Adapted from lz.c .
-**--------------------------------------------------------------------------*/
-function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
-{
- var encoder = at;
- var op = 0;
- var ctrl;
- var ctr = 0;
-
- for (ctrl = in_buf[encoder++]; (op * 4) < out_buf.length; ctrl = in_buf[encoder++])
- {
- var ref = op;
- var len = ctrl >> 5;
- var ofs = (ctrl & 31) << 8;
-
-//if (type == LZ_IMAGE_TYPE_RGBA)
-//console.log(ctr++ + ": from " + (encoder + 28) + ", ctrl " + ctrl + ", len " + len + ", ofs " + ofs + ", op " + op);
- if (ctrl >= 32) {
-
- var code;
- len--;
-
- if (len == 7 - 1) {
- do {
- code = in_buf[encoder++];
- len += code;
- } while (code == 255);
- }
- code = in_buf[encoder++];
- ofs += code;
-
-
- if (code == 255) {
- if ((ofs - code) == (31 << 8)) {
- ofs = in_buf[encoder++] << 8;
- ofs += in_buf[encoder++];
- ofs += 8191;
- }
- }
- len += 1;
- if (type == LZ_IMAGE_TYPE_RGBA)
- len += 2;
-
- ofs += 1;
-
- ref -= ofs;
- if (ref == (op - 1)) {
- var b = ref;
-//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha " + out_buf[(b*4)+3] + " dupped into pixel " + op + " through pixel " + (op + len));
- for (; len; --len) {
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
- out_buf[(op*4) + 3] = out_buf[(b*4)+3];
- }
- else
- {
- for (i = 0; i < 4; i++)
- out_buf[(op*4) + i] = out_buf[(b*4)+i];
- }
- op++;
- }
- } else {
-//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op + " through " + (op + len) + " from " + ref);
- for (; len; --len) {
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
- out_buf[(op*4) + 3] = out_buf[(ref*4)+3];
- }
- else
- {
- for (i = 0; i < 4; i++)
- out_buf[(op*4) + i] = out_buf[(ref*4)+i];
- }
- op++; ref++;
- }
- }
- } else {
- ctrl++;
-
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
-//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
- out_buf[(op*4) + 3] = in_buf[encoder++];
- }
- else
- {
- out_buf[(op*4) + 0] = in_buf[encoder + 2];
- out_buf[(op*4) + 1] = in_buf[encoder + 1];
- out_buf[(op*4) + 2] = in_buf[encoder + 0];
- if (default_alpha)
- out_buf[(op*4) + 3] = 255;
- encoder += 3;
- }
- op++;
-
-
- for (--ctrl; ctrl; ctrl--) {
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
-//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
- out_buf[(op*4) + 3] = in_buf[encoder++];
- }
- else
- {
- out_buf[(op*4) + 0] = in_buf[encoder + 2];
- out_buf[(op*4) + 1] = in_buf[encoder + 1];
- out_buf[(op*4) + 2] = in_buf[encoder + 0];
- if (default_alpha)
- out_buf[(op*4) + 3] = 255;
- encoder += 3;
- }
- op++;
- }
- }
-
- }
- return encoder - 1;
-}
-
-function convert_spice_lz_to_web(context, lz_image)
-{
- var at;
- if (lz_image.type === LZ_IMAGE_TYPE_RGB32 || lz_image.type === LZ_IMAGE_TYPE_RGBA)
- {
- var u8 = new Uint8Array(lz_image.data);
- var ret = context.createImageData(lz_image.width, lz_image.height);
-
- at = lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGB32, lz_image.type != LZ_IMAGE_TYPE_RGBA);
- if (lz_image.type == LZ_IMAGE_TYPE_RGBA)
- lz_rgb32_decompress(u8, at, ret.data, LZ_IMAGE_TYPE_RGBA, false);
- }
- else if (lz_image.type === LZ_IMAGE_TYPE_XXXA)
- {
- var u8 = new Uint8Array(lz_image.data);
- var ret = context.createImageData(lz_image.width, lz_image.height);
- lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGBA, false);
- }
- else
- return undefined;
-
- return ret;
-}
diff --git a/plugins/kimchi/ui/spice-html5/main.js b/plugins/kimchi/ui/spice-html5/main.js
deleted file mode 100644
index 91f1963..0000000
--- a/plugins/kimchi/ui/spice-html5/main.js
+++ /dev/null
@@ -1,231 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceMainConn
-** This is the master Javascript class for establishing and
-** managing a connection to a Spice Server.
-**
-** Invocation: You must pass an object with properties as follows:
-** uri (required) Uri of a WebSocket listener that is
-** connected to a spice server.
-** password (required) Password to send to the spice server
-** message_id (optional) Identifier of an element in the DOM
-** where SpiceConn will write messages.
-** It will use classes spice-messages-x,
-** where x is one of info, warning, or error.
-** screen_id (optional) Identifier of an element in the DOM
-** where SpiceConn will create any new
-** client screens. This is the main UI.
-** dump_id (optional) If given, an element to use for
-** dumping every single image + canvas drawn.
-** Sometimes useful for debugging.
-** onerror (optional) If given, a function to receive async
-** errors. Note that you should also catch
-** errors for ones that occur inline
-** onagent (optional) If given, a function to be called when
-** a VD agent is connected; a good opportunity
-** to request a resize
-**
-** Throws error if there are troubles. Requires a modern (by 2012 standards)
-** browser, including WebSocket and WebSocket.binaryType == arraybuffer
-**
-**--------------------------------------------------------------------------*/
-function SpiceMainConn()
-{
- if (typeof WebSocket === "undefined")
- throw new Error("WebSocket unavailable. You need to use a different browser.");
-
- SpiceConn.apply(this, arguments);
-
-}
-
-SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
-SpiceMainConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_MAIN_INIT)
- {
- this.log_info("Connected to " + this.ws.url);
- this.report_success("Connected")
- this.main_init = new SpiceMsgMainInit(msg.data);
- this.connection_id = this.main_init.session_id;
-
- if (DEBUG > 0)
- {
- // FIXME - there is a lot here we don't handle; mouse modes, agent,
- // ram_hint, multi_media_time
- this.log_info("session id " + this.main_init.session_id +
- " ; display_channels_hint " + this.main_init.display_channels_hint +
- " ; supported_mouse_modes " + this.main_init.supported_mouse_modes +
- " ; current_mouse_mode " + this.main_init.current_mouse_mode +
- " ; agent_connected " + this.main_init.agent_connected +
- " ; agent_tokens " + this.main_init.agent_tokens +
- " ; multi_media_time " + this.main_init.multi_media_time +
- " ; ram_hint " + this.main_init.ram_hint);
- }
-
- this.handle_mouse_mode(this.main_init.current_mouse_mode,
- this.main_init.supported_mouse_modes);
-
- if (this.main_init.agent_connected)
- this.connect_agent();
-
- var attach = new SpiceMiniData;
- attach.type = SPICE_MSGC_MAIN_ATTACH_CHANNELS;
- attach.size = attach.buffer_size();
- this.send_msg(attach);
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_MOUSE_MODE)
- {
- var mode = new SpiceMsgMainMouseMode(msg.data);
- DEBUG > 0 && this.log_info("Mouse supported modes " + mode.supported_modes + "; current " + mode.current_mode);
- this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_CHANNELS_LIST)
- {
- var i;
- var chans;
- DEBUG > 0 && console.log("channels");
- chans = new SpiceMsgChannels(msg.data);
- for (i = 0; i < chans.channels.length; i++)
- {
- var conn = {
- uri: this.ws.url,
- parent: this,
- connection_id : this.connection_id,
- type : chans.channels[i].type,
- chan_id : chans.channels[i].id
- };
- if (chans.channels[i].type == SPICE_CHANNEL_DISPLAY)
- this.display = new SpiceDisplayConn(conn);
- else if (chans.channels[i].type == SPICE_CHANNEL_INPUTS)
- {
- this.inputs = new SpiceInputsConn(conn);
- this.inputs.mouse_mode = this.mouse_mode;
- }
- else if (chans.channels[i].type == SPICE_CHANNEL_CURSOR)
- this.cursor = new SpiceCursorConn(conn);
- else if (chans.channels[i].type == SPICE_CHANNEL_PLAYBACK)
- this.cursor = new SpicePlaybackConn(conn);
- else
- {
- this.log_err("Channel type " + chans.channels[i].type + " unknown.");
- if (! ("extra_channels" in this))
- this.extra_channels = [];
- this.extra_channels[i] = new SpiceConn(conn);
- }
-
- }
-
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED ||
- msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS)
- {
- this.connect_agent();
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_AGENT_DISCONNECTED)
- {
- this.agent_connected = false;
- return true;
- }
-
- return false;
-}
-
-SpiceMainConn.prototype.stop = function(msg)
-{
- this.state = "closing";
-
- if (this.inputs)
- {
- this.inputs.cleanup();
- this.inputs = undefined;
- }
-
- if (this.cursor)
- {
- this.cursor.cleanup();
- this.cursor = undefined;
- }
-
- if (this.display)
- {
- this.display.cleanup();
- this.display.destroy_surfaces();
- this.display = undefined;
- }
-
- this.cleanup();
-
- if ("extra_channels" in this)
- for (var e in this.extra_channels)
- this.extra_channels[e].cleanup();
- this.extra_channels = undefined;
-}
-
-SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y)
-{
- if (this.agent_connected > 0)
- {
- var monitors_config = new VDAgentMonitorsConfig(flags, width, height, depth, x, y);
- var agent_data = new SpiceMsgcMainAgentData(VD_AGENT_MONITORS_CONFIG, monitors_config);
- var mr = new SpiceMiniData();
- mr.build_msg(SPICE_MSGC_MAIN_AGENT_DATA, agent_data);
- this.send_msg(mr);
- }
-}
-
-SpiceMainConn.prototype.connect_agent = function()
-{
- this.agent_connected = true;
-
- var agent_start = new SpiceMsgcMainAgentStart(0);
- var mr = new SpiceMiniData();
- mr.build_msg(SPICE_MSGC_MAIN_AGENT_START, agent_start);
- this.send_msg(mr);
-
- if (this.onagent !== undefined)
- this.onagent(this);
-
-}
-
-SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
-{
- this.mouse_mode = current;
- if (current != SPICE_MOUSE_MODE_CLIENT && (supported & SPICE_MOUSE_MODE_CLIENT))
- {
- var mode_request = new SpiceMsgcMainMouseModeRequest(SPICE_MOUSE_MODE_CLIENT);
- var mr = new SpiceMiniData();
- mr.build_msg(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
- this.send_msg(mr);
- }
-
- if (this.inputs)
- this.inputs.mouse_mode = current;
-}
-
diff --git a/plugins/kimchi/ui/spice-html5/pages/Makefile.am b/plugins/kimchi/ui/spice-html5/pages/Makefile.am
deleted file mode 100644
index 431ec6c..0000000
--- a/plugins/kimchi/ui/spice-html5/pages/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-spicepagesdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/pages
-
-dist_spicepages_DATA = $(wildcard *.html) $(NULL)
diff --git a/plugins/kimchi/ui/spice-html5/pages/spice_auto.html b/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
deleted file mode 100644
index c87f5c2..0000000
--- a/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!--
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-
- --------------------------------------------------
- Spice Javascript client template.
- Refer to main.js for more detailed information
- --------------------------------------------------
-
--->
-
-<!doctype html>
-<html>
- <head>
-
- <!--
- The below sources were updated according to Kimchi configuration
- to get the Javascript and CSS files from the installed spice-html5
- package.
- Kimchi is not using the default spice_auto.html because Kimchi uses
- wss:// for all connections and it is only supported by recent
- versions of spice-html5.
- In addition to it, Kimchi points user to the right token on URL
- (check line 146 of this file).
- -->
- <title>Spice Javascript client</title>
- <script src="spice-html5/spicearraybuffer.js"></script>
- <script src="spice-html5/enums.js"></script>
- <script src="spice-html5/atKeynames.js"></script>
- <script src="spice-html5/utils.js"></script>
- <script src="spice-html5/png.js"></script>
- <script src="spice-html5/lz.js"></script>
- <script src="spice-html5/quic.js"></script>
- <script src="spice-html5/bitmap.js"></script>
- <script src="spice-html5/spicedataview.js"></script>
- <script src="spice-html5/spicetype.js"></script>
- <script src="spice-html5/spicemsg.js"></script>
- <script src="spice-html5/wire.js"></script>
- <script src="spice-html5/spiceconn.js"></script>
- <script src="spice-html5/display.js"></script>
- <script src="spice-html5/main.js"></script>
- <script src="spice-html5/inputs.js"></script>
- <script src="spice-html5/webm.js"></script>
- <script src="spice-html5/playback.js"></script>
- <script src="spice-html5/simulatecursor.js"></script>
- <script src="spice-html5/cursor.js"></script>
- <script src="spice-html5/thirdparty/jsbn.js"></script>
- <script src="spice-html5/thirdparty/rsa.js"></script>
- <script src="spice-html5/thirdparty/prng4.js"></script>
- <script src="spice-html5/thirdparty/rng.js"></script>
- <script src="spice-html5/thirdparty/sha1.js"></script>
- <script src="spice-html5/ticket.js"></script>
- <script src="spice-html5/resize.js"></script>
- <link rel="stylesheet" type="text/css" href="spice-html5/spice.css" />
-
- <script>
- var host = null, port = null;
- var sc;
-
- function spice_set_cookie(name, value, days) {
- var date, expires;
- date = new Date();
- date.setTime(date.getTime() + (days*24*60*60*1000));
- expires = "; expires=" + date.toGMTString();
- document.cookie = name + "=" + value + expires + "; path=/";
- };
-
- function spice_query_var(name, defvalue) {
- var match = RegExp('[?&]' + name + '=([^&]*)')
- .exec(window.location.search);
- return match ?
- decodeURIComponent(match[1].replace(/\+/g, ' '))
- : defvalue;
- }
-
- function spice_error(e)
- {
- disconnect();
- }
-
- function connect()
- {
- var host, port, password, scheme = "ws://", uri;
-
- // By default, use the host and port of server that served this file
- host = spice_query_var('host', window.location.hostname);
-
- // Note that using the web server port only makes sense
- // if your web server has a reverse proxy to relay the WebSocket
- // traffic to the correct destination port.
- var default_port = window.location.port;
- if (!default_port) {
- if (window.location.protocol == 'http:') {
- default_port = 80;
- }
- else if (window.location.protocol == 'https:') {
- default_port = 443;
- }
- }
- port = spice_query_var('port', default_port);
- if (window.location.protocol == 'https:') {
- scheme = "wss://";
- }
-
- // If a token variable is passed in, set the parameter in a cookie.
- // This is used by nova-spiceproxy.
- token = spice_query_var('token', null);
- if (token) {
- spice_set_cookie('token', token, 1)
- }
-
- password = spice_query_var('password', '');
- path = spice_query_var('path', 'websockify');
-
- if ((!host) || (!port)) {
- console.log("must specify host and port in URL");
- return;
- }
-
- if (sc) {
- sc.stop();
- }
-
- /*
- * The following line was modified from the original one:
- *
- * 'uri = scheme + host + ":" + port;'
- *
- * to point wok.user to a specific console represented by
- * token value.
- */
- uri = scheme + host + ":" + port + "/?token=" + token;
-
- try
- {
- sc = new SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
- message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
- }
- catch (e)
- {
- alert(e.toString());
- disconnect();
- }
-
- }
-
- function disconnect()
- {
- console.log(">> disconnect");
- if (sc) {
- sc.stop();
- }
- console.log("<< disconnect");
- }
-
- function agent_connected(sc)
- {
- window.addEventListener('resize', handle_resize);
- window.spice_connection = this;
-
- resize_helper(this);
- }
-
- connect();
- </script>
-
- </head>
-
- <body>
-
- <div id="login">
- <span class="logo">SPICE</span>
- </div>
-
- <div id="spice-area">
- <div id="spice-screen" class="spice-screen"></div>
- </div>
-
- <div id="message-div" class="spice-message"></div>
-
- <div id="debug-div">
- <!-- If DUMPXXX is turned on, dumped images will go here -->
- </div>
-
- </body>
-</html>
diff --git a/plugins/kimchi/ui/spice-html5/playback.js b/plugins/kimchi/ui/spice-html5/playback.js
deleted file mode 100644
index 7209fbe..0000000
--- a/plugins/kimchi/ui/spice-html5/playback.js
+++ /dev/null
@@ -1,278 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2014 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpicePlaybackConn
-** Drive the Spice Playback channel (sound out)
-**--------------------------------------------------------------------------*/
-function SpicePlaybackConn()
-{
- SpiceConn.apply(this, arguments);
-
- this.queue = new Array();
- this.append_okay = false;
- this.start_time = 0;
- this.skip_until = 0;
- this.gap_time = 0;
-}
-
-SpicePlaybackConn.prototype = Object.create(SpiceConn.prototype);
-SpicePlaybackConn.prototype.process_channel_message = function(msg)
-{
- if (!!!window.MediaSource)
- {
- this.log_err('MediaSource API is not available');
- return false;
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_START)
- {
- var start = new SpiceMsgPlaybackStart(msg.data);
-
- DEBUG > 0 && console.log("PlaybackStart; frequency " + start.frequency);
-
- if (start.frequency != OPUS_FREQUENCY)
- {
- this.log_err('This player cannot handle frequency ' + start.frequency);
- return false;
- }
-
- if (start.channels != OPUS_CHANNELS)
- {
- this.log_err('This player cannot handle ' + start.channels + ' channels');
- return false;
- }
-
- if (start.format != SPICE_AUDIO_FMT_S16)
- {
- this.log_err('This player cannot format ' + start.format);
- return false;
- }
-
- if (! this.source_buffer)
- {
- this.media_source = new MediaSource();
- this.media_source.spiceconn = this;
-
- this.audio = document.createElement("audio");
- this.audio.setAttribute('autoplay', true);
- this.audio.src = window.URL.createObjectURL(this.media_source);
- document.getElementById(this.parent.screen_id).appendChild(this.audio);
-
- this.media_source.addEventListener('sourceopen', handle_source_open, false);
- this.media_source.addEventListener('sourceended', handle_source_ended, false);
- this.media_source.addEventListener('sourceclosed', handle_source_closed, false);
-
- this.bytes_written = 0;
-
- return true;
- }
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_DATA)
- {
- var data = new SpiceMsgPlaybackData(msg.data);
-
- // If this packet has the same time as the last, just bump up by one.
- if (this.last_data_time && data.time <= this.last_data_time)
- {
- // FIXME - this is arguably wrong. But delaying the transmission was worse,
- // in initial testing. Could use more research.
- DEBUG > 1 && console.log("Hacking time of " + data.time + " to " + this.last_data_time + 1);
- data.time = this.last_data_time + 1;
- }
-
- /* Gap detection: If there has been a delay since our last packet, then audio must
- have paused. Handling that gets tricky. In Chrome, you can seek forward,
- but you cannot in Firefox. And seeking forward in Chrome is nice, as it keeps
- Chrome from being overly cautious in it's buffer strategy.
-
- So we do two things. First, we seek forward. Second, we compute how much of a gap
- there would have been, and essentially eliminate it.
- */
- if (this.last_data_time && data.time >= (this.last_data_time + GAP_DETECTION_THRESHOLD))
- {
- this.skip_until = data.time;
- this.gap_time = (data.time - this.start_time) -
- (this.source_buffer.buffered.end(this.source_buffer.buffered.end.length - 1) * 1000.0).toFixed(0);
- }
-
- this.last_data_time = data.time;
-
-
- DEBUG > 1 && console.log("PlaybackData; time " + data.time + "; length " + data.data.byteLength);
-
- if (! this.source_buffer)
- return true;
-
- if (this.start_time == 0)
- this.start_playback(data);
-
- else if (data.time - this.cluster_time >= MAX_CLUSTER_TIME || this.skip_until > 0)
- this.new_cluster(data);
-
- else
- this.simple_block(data, false);
-
- if (this.skip_until > 0)
- {
- this.audio.currentTime = (this.skip_until - this.start_time - this.gap_time) / 1000.0;
- this.skip_until = 0;
- }
-
- if (this.audio.paused)
- this.audio.play();
-
- return true;
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_MODE)
- {
- var mode = new SpiceMsgPlaybackMode(msg.data);
- if (mode.mode != SPICE_AUDIO_DATA_MODE_OPUS)
- {
- this.log_err('This player cannot handle mode ' + mode.mode);
- delete this.source_buffer;
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_STOP)
- {
- return true;
- }
-
- return false;
-}
-
-SpicePlaybackConn.prototype.start_playback = function(data)
-{
- this.start_time = data.time;
-
- var h = new webm_Header();
-
- var mb = new ArrayBuffer(h.buffer_size())
-
- this.bytes_written = h.to_buffer(mb);
-
- this.source_buffer.addEventListener('error', handle_sourcebuffer_error, false);
- this.source_buffer.addEventListener('updateend', handle_append_buffer_done, false);
- playback_append_buffer(this, mb);
-
- this.new_cluster(data);
-}
-
-SpicePlaybackConn.prototype.new_cluster = function(data)
-{
- this.cluster_time = data.time;
-
- var c = new webm_Cluster(data.time - this.start_time - this.gap_time);
-
- var mb = new ArrayBuffer(c.buffer_size());
- this.bytes_written += c.to_buffer(mb);
-
- if (this.append_okay)
- playback_append_buffer(this, mb);
- else
- this.queue.push(mb);
-
- this.simple_block(data, true);
-}
-
-SpicePlaybackConn.prototype.simple_block = function(data, keyframe)
-{
- var sb = new webm_SimpleBlock(data.time - this.cluster_time, data.data, keyframe);
- var mb = new ArrayBuffer(sb.buffer_size());
-
- this.bytes_written += sb.to_buffer(mb);
-
- if (this.append_okay)
- playback_append_buffer(this, mb);
- else
- this.queue.push(mb);
-}
-
-function handle_source_open(e)
-{
- var p = this.spiceconn;
-
- if (p.source_buffer)
- return;
-
- p.source_buffer = this.addSourceBuffer(SPICE_PLAYBACK_CODEC);
- if (! p.source_buffer)
- {
- p.log_err('Codec ' + SPICE_PLAYBACK_CODEC + ' not available.');
- return;
- }
- p.source_buffer.spiceconn = p;
- p.source_buffer.mode = "segments";
-
- // FIXME - Experimentation with segments and sequences was unsatisfying.
- // Switching to sequence did not solve our gap problem,
- // but the browsers didn't fully support the time seek capability
- // we would expect to gain from 'segments'.
- // Segments worked at the time of this patch, so segments it is for now.
-
-}
-
-function handle_source_ended(e)
-{
- var p = this.spiceconn;
- p.log_err('Audio source unexpectedly ended.');
-}
-
-function handle_source_closed(e)
-{
- var p = this.spiceconn;
- p.log_err('Audio source unexpectedly closed.');
-}
-
-function handle_append_buffer_done(b)
-{
- var p = this.spiceconn;
- if (p.queue.length > 0)
- {
- var mb = p.queue.shift();
- playback_append_buffer(p, mb);
- }
- else
- p.append_okay = true;
-
-}
-
-function handle_sourcebuffer_error(e)
-{
- var p = this.spiceconn;
- p.log_err('source_buffer error ' + e.message);
-}
-
-function playback_append_buffer(p, b)
-{
- try
- {
- p.source_buffer.appendBuffer(b);
- p.append_okay = false;
- }
- catch (e)
- {
- p.log_err("Error invoking appendBuffer: " + e.message);
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/png.js b/plugins/kimchi/ui/spice-html5/png.js
deleted file mode 100644
index 6a26151..0000000
--- a/plugins/kimchi/ui/spice-html5/png.js
+++ /dev/null
@@ -1,256 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** crc logic from rfc2083 ported to Javascript
-**--------------------------------------------------------------------------*/
-
-var rfc2083_crc_table = Array(256);
-var rfc2083_crc_table_computed = 0;
-/* Make the table for a fast CRC. */
-function rfc2083_make_crc_table()
-{
- var c;
- var n, k;
- for (n = 0; n < 256; n++)
- {
- c = n;
- for (k = 0; k < 8; k++)
- {
- if (c & 1)
- c = ((0xedb88320 ^ (c >>> 1)) >>> 0) & 0xffffffff;
- else
- c = c >>> 1;
- }
- rfc2083_crc_table[n] = c;
- }
-
- rfc2083_crc_table_computed = 1;
-}
-
-/* Update a running CRC with the bytes buf[0..len-1]--the CRC
- should be initialized to all 1's, and the transmitted value
- is the 1's complement of the final running CRC (see the
- crc() routine below)). */
-
-function rfc2083_update_crc(crc, u8buf, at, len)
-{
- var c = crc;
- var n;
-
- if (!rfc2083_crc_table_computed)
- rfc2083_make_crc_table();
-
- for (n = 0; n < len; n++)
- {
- c = rfc2083_crc_table[(c ^ u8buf[at + n]) & 0xff] ^ (c >>> 8);
- }
-
- return c;
-}
-
-function rfc2083_crc(u8buf, at, len)
-{
- return rfc2083_update_crc(0xffffffff, u8buf, at, len) ^ 0xffffffff;
-}
-
-function crc32(mb, at, len)
-{
- var u8 = new Uint8Array(mb);
- return rfc2083_crc(u8, at, len);
-}
-
-function PngIHDR(width, height)
-{
- this.width = width;
- this.height = height;
- this.depth = 8;
- this.type = 6;
- this.compression = 0;
- this.filter = 0;
- this.interlace = 0;
-}
-
-PngIHDR.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig = at;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.buffer_size() - 12); at += 4;
- dv.setUint8(at, 'I'.charCodeAt(0)); at++;
- dv.setUint8(at, 'H'.charCodeAt(0)); at++;
- dv.setUint8(at, 'D'.charCodeAt(0)); at++;
- dv.setUint8(at, 'R'.charCodeAt(0)); at++;
- dv.setUint32(at, this.width); at += 4;
- dv.setUint32(at, this.height); at += 4;
- dv.setUint8(at, this.depth); at++;
- dv.setUint8(at, this.type); at++;
- dv.setUint8(at, this.compression); at++;
- dv.setUint8(at, this.filter); at++;
- dv.setUint8(at, this.interlace); at++;
- dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 12 + 13;
- }
-}
-
-
-function adler()
-{
- this.s1 = 1;
- this.s2 = 0;
-}
-
-adler.prototype.update = function(b)
-{
- this.s1 += b;
- this.s1 %= 65521;
- this.s2 += this.s1;
- this.s2 %= 65521;
-}
-
-function PngIDAT(width, height, bytes)
-{
- if (bytes.byteLength > 65535)
- {
- throw new Error("Cannot handle more than 64K");
- }
- this.data = bytes;
- this.width = width;
- this.height = height;
-}
-
-PngIDAT.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig = at;
- var x, y, i, j;
- var dv = new SpiceDataView(a);
- var zsum = new adler();
- dv.setUint32(at, this.buffer_size() - 12); at += 4;
- dv.setUint8(at, 'I'.charCodeAt(0)); at++;
- dv.setUint8(at, 'D'.charCodeAt(0)); at++;
- dv.setUint8(at, 'A'.charCodeAt(0)); at++;
- dv.setUint8(at, 'T'.charCodeAt(0)); at++;
-
- /* zlib header. */
- dv.setUint8(at, 0x78); at++;
- dv.setUint8(at, 0x01); at++;
-
- /* Deflate header. Specifies uncompressed, final bit */
- dv.setUint8(at, 0x80); at++;
- dv.setUint16(at, this.data.byteLength + this.height); at += 2;
- dv.setUint16(at, ~(this.data.byteLength + this.height)); at += 2;
- var u8 = new Uint8Array(this.data);
- for (i = 0, y = 0; y < this.height; y++)
- {
- /* Filter type 0 - uncompressed */
- dv.setUint8(at, 0); at++;
- zsum.update(0);
- for (x = 0; x < this.width && i < this.data.byteLength; x++)
- {
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- }
- }
-
- /* zlib checksum. */
- dv.setUint16(at, zsum.s2); at+=2;
- dv.setUint16(at, zsum.s1); at+=2;
-
- /* FIXME - something is not quite right with the zlib code;
- you get an error from libpng if you open the image in
- gimp. But it works, so it's good enough for now... */
-
- dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 12 + this.data.byteLength + this.height + 4 + 2 + 1 + 2 + 2;
- }
-}
-
-
-function PngIEND()
-{
-}
-
-PngIEND.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig = at;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.buffer_size() - 12); at += 4;
- dv.setUint8(at, 'I'.charCodeAt(0)); at++;
- dv.setUint8(at, 'E'.charCodeAt(0)); at++;
- dv.setUint8(at, 'N'.charCodeAt(0)); at++;
- dv.setUint8(at, 'D'.charCodeAt(0)); at++;
- dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 12;
- }
-}
-
-
-function create_rgba_png(width, height, bytes)
-{
- var i;
- var ihdr = new PngIHDR(width, height);
- var idat = new PngIDAT(width, height, bytes);
- var iend = new PngIEND;
-
- var mb = new ArrayBuffer(ihdr.buffer_size() + idat.buffer_size() + iend.buffer_size());
- var at = ihdr.to_buffer(mb);
- at = idat.to_buffer(mb, at);
- at = iend.to_buffer(mb, at);
-
- var u8 = new Uint8Array(mb);
- var str = "";
- for (i = 0; i < at; i++)
- {
- str += "%";
- if (u8[i] < 16)
- str += "0";
- str += u8[i].toString(16);
- }
-
-
- return "%89PNG%0D%0A%1A%0A" + str;
-}
diff --git a/plugins/kimchi/ui/spice-html5/quic.js b/plugins/kimchi/ui/spice-html5/quic.js
deleted file mode 100644
index 9bb9f47..0000000
--- a/plugins/kimchi/ui/spice-html5/quic.js
+++ /dev/null
@@ -1,1335 +0,0 @@
-/*"use strict";*/
-/* use strict is commented out because it results in a 5x slowdone in chrome */
-/*
- * Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
- * Copyright (C) 2012 by Aric Stewart <aric at codeweavers.com>
- *
- * This file is part of spice-html5.
- *
- * spice-html5 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * spice-html5 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
- */
-
-var encoder;
-
-var QUIC_IMAGE_TYPE_INVALID = 0;
-var QUIC_IMAGE_TYPE_GRAY = 1;
-var QUIC_IMAGE_TYPE_RGB16 = 2;
-var QUIC_IMAGE_TYPE_RGB24 = 3;
-var QUIC_IMAGE_TYPE_RGB32 = 4;
-var QUIC_IMAGE_TYPE_RGBA = 5;
-var DEFevol = 3;
-var DEFwmimax = 6;
-var DEFwminext = 2048;
-var need_init = true;
-var DEFmaxclen = 26;
-var evol = DEFevol;
-var wmimax = DEFwmimax;
-var wminext = DEFwminext;
-var family_5bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
- notGRcwlen:[0,0,0,0,0,0,0,0],
- notGRprefixmask:[0,0,0,0,0,0,0,0],
- notGRsuffixlen:[0,0,0,0,0,0,0,0],
- xlatU2L:[0,0,0,0,0,0,0,0],
- xlatL2U:[0,0,0,0,0,0,0,0]
- };
-var family_8bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
- notGRcwlen:[0,0,0,0,0,0,0,0],
- notGRprefixmask:[0,0,0,0,0,0,0,0],
- notGRsuffixlen:[0,0,0,0,0,0,0,0],
- xlatU2L:[0,0,0,0,0,0,0,0],
- xlatL2U:[0,0,0,0,0,0,0,0]
- };
-var bppmask = [ 0x00000000,
- 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
- 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
- 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
- 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
- 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
- 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
- 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
- 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff];
-
-var zeroLUT = [];
-
-var besttrigtab = [
- [ 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160],
- [ 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140],
- [ 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160]];
-
-var J = [ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 9, 10, 11, 12, 13, 14, 15];
-
-var lzeroes = [
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0];
-
-var tabrand_chaos = [
- 0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052,
- 0x57329b28, 0x2993868e, 0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac,
- 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b, 0x9e3dce44, 0xdaabee13,
- 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
- 0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e,
- 0xedd58794, 0xc5076689, 0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9,
- 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45, 0x600bde29, 0xf3971ace,
- 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
- 0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136,
- 0xf1840e7e, 0x6a6048c1, 0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d,
- 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0, 0x8f9d8604, 0x4f86e73b,
- 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
- 0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee,
- 0x92826ddf, 0x284bec73, 0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b,
- 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76, 0xfc6fac0a, 0xce927e9b,
- 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
- 0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0,
- 0xb7e8d590, 0xbe807feb, 0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c,
- 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be, 0xb4805c77, 0x00c880fa,
- 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
- 0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf,
- 0x29f8c9fb, 0x53dd6880, 0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119,
- 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4, 0xc2b8a563, 0x94f2f741,
- 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
- 0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b,
- 0xd161043e, 0x5d2fa2e2, 0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34,
- 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d, 0xccb01948, 0x8d168df7,
- 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
- 0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098,
- 0xce81675a, 0x4b372f7d, 0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6,
- 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef, 0x80020447, 0x67976491,
- 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
- 0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d,
- 0x624a78b4, 0x30dbee1b, 0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff,
- 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4, 0x49e54438, 0x2f2577e6,
- 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
- 0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65,
- 0xe0893818, 0x9e00a16a, 0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e,
- 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97, 0x923a9559, 0x37a7a1f6,
- 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
- 0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649,
- 0xdc0a36c0, 0x61cf2bba, 0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d,
- 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5 ];
-
-var rgb32_pixel_pad = 3;
-var rgb32_pixel_r = 2;
-var rgb32_pixel_g = 1;
-var rgb32_pixel_b = 0;
-var rgb32_pixel_size = 4;
-
-/* Helper Functions */
-
-function ceil_log_2(val)
-{
- if (val === 1)
- return 0;
-
- var result = 1;
- val -= 1;
- while (val = val >>> 1)
- result++;
-
- return result;
-}
-
-function family_init(family, bpc, limit)
-{
- var l;
- for (l = 0; l < bpc; l++)
- {
- var altprefixlen, altcodewords;
- altprefixlen = limit - bpc;
- if (altprefixlen > bppmask[bpc - l])
- altprefixlen = bppmask[bpc - l];
-
- altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
- family.nGRcodewords[l] = (altprefixlen << l);
- family.notGRcwlen[l] = altprefixlen + ceil_log_2(altcodewords);
- family.notGRprefixmask[l] = bppmask[32 - altprefixlen]>>>0;
- family.notGRsuffixlen[l] = ceil_log_2(altcodewords);
- }
-
- /* decorelate_init */
- var pixelbitmask = bppmask[bpc];
- var pixelbitmaskshr = pixelbitmask >>> 1;
- var s;
- for (s = 0; s <= pixelbitmask; s++) {
- if (s <= pixelbitmaskshr) {
- family.xlatU2L[s] = s << 1;
- } else {
- family.xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
- }
- }
-
- /* corelate_init */
- for (s = 0; s <= pixelbitmask; s++) {
- if (s & 0x01) {
- family.xlatL2U[s] = pixelbitmask - (s >>> 1);
- } else {
- family.xlatL2U[s] = (s >>> 1);
- }
- }
-}
-
-function quic_image_bpc(type)
-{
- switch (type) {
- case QUIC_IMAGE_TYPE_GRAY:
- return 8;
- case QUIC_IMAGE_TYPE_RGB16:
- return 5;
- case QUIC_IMAGE_TYPE_RGB24:
- return 8;
- case QUIC_IMAGE_TYPE_RGB32:
- return 8;
- case QUIC_IMAGE_TYPE_RGBA:
- return 8;
- case QUIC_IMAGE_TYPE_INVALID:
- default:
- console.log("quic: bad image type\n");
- return 0;
- }
-}
-
-function cnt_l_zeroes(bits)
-{
- if (bits & 0xff800000) {
- return lzeroes[bits >>> 24];
- } else if (bits & 0xffff8000) {
- return 8 + lzeroes[(bits >>> 16) & 0x000000ff];
- } else if (bits & 0xffffff80) {
- return 16 + lzeroes[(bits >>> 8) & 0x000000ff];
- } else {
- return 24 + lzeroes[bits & 0x000000ff];
- }
-}
-
-function golomb_decoding_8bpc(l, bits)
-{
- var rc;
- var cwlen;
-
- if (bits < 0 || bits > family_8bpc.notGRprefixmask[l])
- {
- var zeroprefix = cnt_l_zeroes(bits);
- cwlen = zeroprefix + 1 + l;
- rc = (zeroprefix << l) | (bits >> (32-cwlen)) & bppmask[l];
- }
- else
- {
- cwlen = family_8bpc.notGRcwlen[l];
- rc = family_8bpc.nGRcodewords[l] + ((bits >> (32-cwlen)) & bppmask[family_8bpc.notGRsuffixlen[l]]);
- }
- return {'codewordlen':cwlen, 'rc':rc};
-}
-
-function golomb_code_len_8bpc(n, l)
-{
- if (n < family_8bpc.nGRcodewords[l]) {
- return (n >>> l) + 1 + l;
- } else {
- return family_8bpc.notGRcwlen[l];
- }
-}
-
-function QuicModel(bpc)
-{
- var bstart;
- var bend = 0;
-
- this.levels = 0x1 << bpc;
- this.n_buckets_ptrs = 0;
-
- switch (evol) {
- case 1:
- this.repfirst = 3;
- this.firstsize = 1;
- this.repnext = 2;
- this.mulsize = 2;
- break;
- case 3:
- this.repfirst = 1;
- this.firstsize = 1;
- this.repnext = 1;
- this.mulsize = 2;
- break;
- case 5:
- this.repfirst = 1;
- this.firstsize = 1;
- this.repnext = 1;
- this.mulsize = 4;
- break;
- case 0:
- case 2:
- case 4:
- console.log("quic: findmodelparams(): evol value obsolete!!!\n");
- default:
- console.log("quic: findmodelparams(): evol out of range!!!\n");
- }
-
- this.n_buckets = 0;
- var repcntr = this.repfirst + 1;
- var bsize = this.firstsize;
-
- do {
- if (this.n_buckets) {
- bstart = bend + 1;
- } else {
- bstart = 0;
- }
-
- if (!--repcntr) {
- repcntr = this.repnext;
- bsize *= this.mulsize;
- }
-
- bend = bstart + bsize - 1;
- if (bend + bsize >= this.levels) {
- bend = this.levels - 1;
- }
-
- if (!this.n_buckets_ptrs) {
- this.n_buckets_ptrs = this.levels;
- }
-
- (this.n_buckets)++;
- } while (bend < this.levels - 1);
-}
-
-QuicModel.prototype = {
- n_buckets : 0,
- n_buckets_ptrs : 0,
- repfirst : 0,
- firstsize : 0,
- repnext : 0,
- mulsize : 0,
- levels :0
-}
-
-function QuicBucket()
-{
- this.counters = [0,0,0,0,0,0,0,0];
-}
-
-QuicBucket.prototype = {
- bestcode: 0,
-
- reste : function (bpp)
- {
- this.bestcode = bpp;
- this.counters = [0,0,0,0,0,0,0,0];
- },
-
- update_model_8bpc : function (state, curval, bpp)
- {
- var i;
-
- var bestcode = bpp - 1;
- var bestcodelen = (this.counters[bestcode] += golomb_code_len_8bpc(curval, bestcode));
-
- for (i = bpp - 2; i >= 0; i--) {
- var ithcodelen = (this.counters[i] += golomb_code_len_8bpc(curval, i));
-
- if (ithcodelen < bestcodelen) {
- bestcode = i;
- bestcodelen = ithcodelen;
- }
- }
-
- this.bestcode = bestcode;
-
- if (bestcodelen > state.wm_trigger) {
- for (i = 0; i < bpp; i++) {
- this.counters[i] = this.counters[i] >>> 1;
- }
- }
- }
-}
-
-function QuicFamilyStat()
-{
- this.buckets_ptrs = [];
- this.buckets_buf = [];
-}
-
-QuicFamilyStat.prototype = {
-
- fill_model_structures : function(model)
- {
- var bstart;
- var bend = 0;
- var bnumber = 0;
-
- var repcntr = model.repfirst + 1;
- var bsize = model.firstsize;
-
- do {
- if (bnumber) {
- bstart = bend + 1;
- } else {
- bstart = 0;
- }
-
- if (!--repcntr) {
- repcntr = model.repnext;
- bsize *= model.mulsize;
- }
-
- bend = bstart + bsize - 1;
- if (bend + bsize >= model.levels) {
- bend = model.levels - 1;
- }
-
- this.buckets_buf[bnumber] = new QuicBucket;
-
- var i;
- for (i = bstart; i <= bend; i++) {
- this.buckets_ptrs[i] = this.buckets_buf[bnumber];
- }
-
- bnumber++;
- } while (bend < model.levels - 1);
- return true;
- }
-}
-
-function QuicChannel(model_8bpc, model_5bpc)
-{
- this.state = new CommonState;
- this.family_stat_8bpc = new QuicFamilyStat;
- this.family_stat_5bpc = new QuicFamilyStat;
- this.correlate_row = { zero: 0 , row:[] };
- this.model_8bpc = model_8bpc;
- this.model_5bpc = model_5bpc;
- this.buckets_ptrs = [];
-
- if (!this.family_stat_8bpc.fill_model_structures(this.model_8bpc))
- return undefined;
-
- if (!this.family_stat_5bpc.fill_model_structures(this.model_5bpc))
- return undefined;
-}
-
-QuicChannel.prototype = {
-
- reste : function (bpc)
- {
- var j;
- this.correlate_row = { zero: 0 , row: []};
-
- if (bpc == 8) {
- for (j = 0; j < this.model_8bpc.n_buckets; j++)
- this.family_stat_8bpc.buckets_buf[j].reste(7);
- this.buckets_ptrs = this.family_stat_8bpc.buckets_ptrs;
- } else if (bpc == 5) {
- for (j = 0; j < this.model_5bpc.n_buckets; j++)
- this.family_stat_8bpc.buckets_buf[j].reste(4);
- this.buckets_ptrs = this.family_stat_5bpc.buckets_ptrs;
- } else {
- console.log("quic: %s: bad bpc %d\n", __FUNCTION__, bpc);
- return false;
- }
-
- this.state.reste();
- return true;
- }
-}
-
-function CommonState()
-{
-}
-
-CommonState.prototype = {
- waitcnt: 0,
- tabrand_seed: 0xff,
- wm_trigger: 0,
- wmidx: 0,
- wmileft: wminext,
- melcstate: 0,
- melclen: 0,
- melcorder: 0,
-
- set_wm_trigger : function()
- {
- var wm = this.wmidx;
- if (wm > 10) {
- wm = 10;
- }
-
- this.wm_trigger = besttrigtab[Math.floor(evol / 2)][wm];
- },
-
- reste : function()
- {
- this.waitcnt = 0;
- this.tabrand_seed = 0x0ff;
- this.wmidx = 0;
- this.wmileft = wminext;
-
- this.set_wm_trigger();
-
- this.melcstate = 0;
- this.melclen = J[0];
- this.melcorder = 1 << this.melclen;
- },
-
- tabrand : function()
- {
- this.tabrand_seed++;
- return tabrand_chaos[this.tabrand_seed & 0x0ff];
- }
-}
-
-
-function QuicEncoder()
-{
- this.rgb_state = new CommonState;
- this.model_8bpc = new QuicModel(8);
- this.model_5bpc = new QuicModel(5);
- this.channels = [];
-
- var i;
- for (i = 0; i < 4; i++) {
- this.channels[i] = new QuicChannel(this.model_8bpc, this.model_5bpc);
- if (!this.channels[i])
- {
- console.log("quic: failed to create channel");
- return undefined;
- }
- }
-}
-
-QuicEncoder.prototype = {
- type: 0,
- width: 0,
- height: 0,
- io_idx: 0,
- io_available_bits: 0,
- io_word: 0,
- io_next_word: 0,
- io_now: 0,
- io_end: 0,
- rows_completed: 0,
- };
-
-QuicEncoder.prototype.reste = function(io_ptr)
-{
- this.rgb_state.reste();
-
- this.io_now = io_ptr;
- this.io_end = this.io_now.length;
- this.io_idx = 0;
- this.rows_completed = 0;
- return true;
-}
-
-QuicEncoder.prototype.read_io_word = function()
-{
- if (this.io_idx >= this.io_end)
- throw("quic: out of data");
- this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8 | this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
-}
-
-QuicEncoder.prototype.decode_eatbits = function (len)
-{
- this.io_word = this.io_word << len;
-
- var delta = (this.io_available_bits - len);
- if (delta >= 0)
- {
- this.io_available_bits = delta;
- this.io_word |= this.io_next_word >>> this.io_available_bits;
- }
- else
- {
- delta = -1 * delta;
- this.io_word |= this.io_next_word << delta;
- this.read_io_word();
- this.io_available_bits = 32 - delta;
- this.io_word |= this.io_next_word >>> this.io_available_bits;
- }
-}
-
-QuicEncoder.prototype.decode_eat32bits = function()
-{
- this.decode_eatbits(16);
- this.decode_eatbits(16);
-}
-
-QuicEncoder.prototype.reste_channels = function(bpc)
-{
- var i;
-
- for (i = 0; i < 4; i++)
- if (!this.channels[i].reste(bpc))
- return false;
- return true;
-}
-
-QuicEncoder.prototype.quic_decode_begin = function(io_ptr)
-{
- if (!this.reste(io_ptr)) {
- return false;
- }
-
- this.io_idx = 0;
- this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8 | this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
- this.io_word = this.io_next_word;
- this.io_available_bits = 0;
-
- var magic = this.io_word;
- this.decode_eat32bits();
- if (magic != 0x43495551) /*QUIC*/ {
- console.log("quic: bad magic "+magic.toString(16));
- return false;
- }
-
- var version = this.io_word;
- this.decode_eat32bits();
- if (version != ((0 << 16) | (0 & 0xffff))) {
- console.log("quic: bad version "+version.toString(16));
- return false;
- }
-
- this.type = this.io_word;
- this.decode_eat32bits();
-
- this.width = this.io_word;
- this.decode_eat32bits();
-
- this.height = this.io_word;
- this.decode_eat32bits();
-
- var bpc = quic_image_bpc(this.type);
-
- if (!this.reste_channels(bpc))
- return false;
-
- return true;
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row0_seg = function (i, cur_row, end,
- waitmask, bpc, bpc_mask)
-{
- var stopidx;
- var n_channels = 3;
- var c;
- var a;
-
- if (!i) {
- cur_row[rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode, this.io_word);
- this.channels[c].correlate_row.row[0] = a.rc;
- cur_row[2-c] = (family_8bpc.xlatL2U[a.rc]&0xFF);
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
-
- if (this.rgb_state.waitcnt) {
- --this.rgb_state.waitcnt;
- } else {
- this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
- c = 0;
- do
- {
- this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[0], bpc);
- } while (++c < n_channels);
- }
- stopidx = ++i + this.rgb_state.waitcnt;
- } else {
- stopidx = i + this.rgb_state.waitcnt;
- }
-
- while (stopidx < end) {
- for (; i <= stopidx; i++) {
- cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i - 1]].bestcode, this.io_word);
- this.channels[c].correlate_row.row[i] = a.rc;
- cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
- c = 0;
- do
- {
- this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx - 1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx], bpc);
- } while (++c < n_channels);
- stopidx = i + (this.rgb_state.tabrand() & waitmask);
- }
-
- for (; i < end; i++) {
- cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i - 1]].bestcode, this.io_word);
- this.channels[c].correlate_row.row[i] = a.rc;
- cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
- this.rgb_state.waitcnt = stopidx - end;
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row0 = function (cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <= width)) {
- if (this.rgb_state.wmileft) {
- this.quic_rgb32_uncompress_row0_seg(pos, cur_row,
- pos + this.rgb_state.wmileft,
- bppmask[this.rgb_state.wmidx],
- bpc, bpc_mask);
- pos += this.rgb_state.wmileft;
- width -= this.rgb_state.wmileft;
- }
-
- this.rgb_state.wmidx++;
- this.rgb_state.set_wm_trigger();
- this.rgb_state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_rgb32_uncompress_row0_seg(pos, cur_row, pos + width,
- bppmask[this.rgb_state.wmidx], bpc, bpc_mask);
- if (wmimax > this.rgb_state.wmidx) {
- this.rgb_state.wmileft -= width;
- }
- }
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row_seg = function( prev_row, cur_row, i, end, bpc, bpc_mask)
-{
- var n_channels = 3;
- var waitmask = bppmask[this.rgb_state.wmidx];
-
- var a;
- var run_index = 0;
- var stopidx = 0;
- var run_end = 0;
- var c;
-
- if (!i)
- {
- cur_row[rgb32_pixel_pad] = 0;
-
- c = 0;
- do {
- a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode, this.io_word);
- this.channels[c].correlate_row.row[0] = a.rc;
- cur_row[2-c] = (family_8bpc.xlatL2U[this.channels[c].correlate_row.row[0]] + prev_row[2-c]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
-
- if (this.rgb_state.waitcnt) {
- --this.rgb_state.waitcnt;
- } else {
- this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
- c = 0;
- do {
- this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[0], bpc);
- } while (++c < n_channels);
- }
- stopidx = ++i + this.rgb_state.waitcnt;
- } else {
- stopidx = i + this.rgb_state.waitcnt;
- }
- for (;;) {
- var rc = 0;
- while (stopidx < end && !rc) {
- for (; i <= stopidx && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
-
- if ( prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r] && prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] && prev_row[pixelm1 + rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
- {
- if (run_index != i && i > 2 && (cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] && cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] && cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
- {
- /* do run */
- this.rgb_state.waitcnt = stopidx - i;
- run_index = i;
- run_end = i + this.decode_run(this.rgb_state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] = 0;
- cur_row[pixel+rgb32_pixel_r] = cur_row[pixelm1+rgb32_pixel_r];
- cur_row[pixel+rgb32_pixel_g] = cur_row[pixelm1+rgb32_pixel_g];
- cur_row[pixel+rgb32_pixel_b] = cur_row[pixelm1+rgb32_pixel_b];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + this.rgb_state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- c = 0;
- cur_row[pixel+rgb32_pixel_pad] = 0;
- do {
- var cc = this.channels[c];
- var cr = cc.correlate_row;
-
- a = golomb_decoding_8bpc(cc.buckets_ptrs[cr.row[i-1]].bestcode, this.io_word);
- cr.row[i] = a.rc;
- cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
- if (rc)
- break;
-
- c = 0;
- do {
- this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx - 1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx], bpc);
- } while (++c < n_channels);
-
- stopidx = i + (this.rgb_state.tabrand() & waitmask);
- }
-
- for (; i < end && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
-
- if (prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r] && prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] && prev_row[pixelm1+rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
- {
- if (run_index != i && i > 2 && (cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] && cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] && cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
- {
- /* do run */
- this.rgb_state.waitcnt = stopidx - i;
- run_index = i;
- run_end = i + this.decode_run(this.rgb_state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] = 0;
- cur_row[pixel+rgb32_pixel_r] = cur_row[pixelm1+rgb32_pixel_r];
- cur_row[pixel+rgb32_pixel_g] = cur_row[pixelm1+rgb32_pixel_g];
- cur_row[pixel+rgb32_pixel_b] = cur_row[pixelm1+rgb32_pixel_b];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + this.rgb_state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- cur_row[pixel+rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i-1]].bestcode, this.io_word);
- this.channels[c].correlate_row.row[i] = a.rc;
- cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
-
- if (!rc)
- {
- this.rgb_state.waitcnt = stopidx - end;
- return;
- }
- }
-}
-
-QuicEncoder.prototype.decode_run = function(state)
-{
- var runlen = 0;
-
- do {
- var hits;
- var x = (~(this.io_word >>> 24)>>>0)&0xff;
- var temp = zeroLUT[x];
-
- for (hits = 1; hits <= temp; hits++) {
- runlen += state.melcorder;
-
- if (state.melcstate < 32) {
- state.melclen = J[++state.melcstate];
- state.melcorder = (1 << state.melclen);
- }
- }
- if (temp != 8) {
- this.decode_eatbits(temp + 1);
-
- break;
- }
- this.decode_eatbits(8);
- } while (true);
-
- if (state.melclen) {
- runlen += this.io_word >>> (32 - state.melclen);
- this.decode_eatbits(state.melclen);
- }
-
- if (state.melcstate) {
- state.melclen = J[--state.melcstate];
- state.melcorder = (1 << state.melclen);
- }
-
- return runlen;
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row = function (prev_row, cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <= width)) {
- if (this.rgb_state.wmileft) {
- this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
- pos + this.rgb_state.wmileft, bpc, bpc_mask);
- pos += this.rgb_state.wmileft;
- width -= this.rgb_state.wmileft;
- }
-
- this.rgb_state.wmidx++;
- this.rgb_state.set_wm_trigger();
- this.rgb_state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
- pos + width, bpc, bpc_mask);
- if (wmimax > this.rgb_state.wmidx) {
- this.rgb_state.wmileft -= width;
- }
- }
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row0_seg = function (channel, i,
- correlate_row, cur_row, end, waitmask,
- bpc, bpc_mask)
-{
- var stopidx;
- var a;
-
- if (i == 0) {
- a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode, this.io_word);
- correlate_row.row[0] = a.rc;
- cur_row[rgb32_pixel_pad] = family_8bpc.xlatL2U[a.rc];
- this.decode_eatbits(a.codewordlen);
-
- if (channel.state.waitcnt) {
- --channel.state.waitcnt;
- } else {
- channel.state.waitcnt = (channel.state.tabrand() & waitmask);
- channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state, correlate_row.row[0], bpc);
- }
- stopidx = ++i + channel.state.waitcnt;
- } else {
- stopidx = i + channel.state.waitcnt;
- }
-
- while (stopidx < end) {
- var pbucket;
-
- for (; i <= stopidx; i++) {
- pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
-
- a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
- correlate_row.row[i] = a.rc;
- cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
-
- pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
-
- stopidx = i + (channel.state.tabrand() & waitmask);
- }
-
- for (; i < end; i++) {
- a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode, this.io_word);
-
- correlate_row.row[i] = a.rc;
- cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
- channel.state.waitcnt = stopidx - end;
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row0 = function(channel, cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var correlate_row = channel.correlate_row;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <= width)) {
- if (channel.state.wmileft) {
- this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row,
- pos + channel.state.wmileft, bppmask[channel.state.wmidx],
- bpc, bpc_mask);
- pos += channel.state.wmileft;
- width -= channel.state.wmileft;
- }
-
- channel.state.wmidx++;
- channel.state.set_wm_trigger();
- channel.state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row, pos + width,
- bppmask[channel.state.wmidx], bpc, bpc_mask);
- if (wmimax > channel.state.wmidx) {
- channel.state.wmileft -= width;
- }
- }
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row_seg = function (channel,
- correlate_row, prev_row, cur_row, i,
- end, bpc, bpc_mask)
-{
- var waitmask = bppmask[channel.state.wmidx];
- var stopidx;
-
- var run_index = 0;
- var run_end;
-
- var a;
-
- if (i == 0) {
- a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode, this.io_word);
-
- correlate_row.row[0] = a.rc
- cur_row[rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + prev_row[rgb32_pixel_pad]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
-
- if (channel.state.waitcnt) {
- --channel.state.waitcnt;
- } else {
- channel.state.waitcnt = (channel.state.tabrand() & waitmask);
- channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state, correlate_row.row[0], bpc);
- }
- stopidx = ++i + channel.state.waitcnt;
- } else {
- stopidx = i + channel.state.waitcnt;
- }
- for (;;) {
- var rc = 0;
- while (stopidx < end && !rc) {
- var pbucket;
- for (; i <= stopidx && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
-
- if (prev_row[pixelm1+rgb32_pixel_pad] == prev_row[pixel+rgb32_pixel_pad])
- {
- if (run_index != i && i > 2 && cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
- {
- /* do run */
- channel.state.waitcnt = stopidx - i;
- run_index = i;
-
- run_end = i + this.decode_run(channel.state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] = cur_row[pixelm1+rgb32_pixel_pad];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + channel.state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
- a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
- correlate_row.row[i] = a.rc
- cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
- if (rc)
- break;
-
- pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
-
- stopidx = i + (channel.state.tabrand() & waitmask);
- }
-
- for (; i < end && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
- if (prev_row[pixelm1+rgb32_pixel_pad] == prev_row[pixel+rgb32_pixel_pad])
- {
- if (run_index != i && i > 2 && cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
- {
- /* do run */
- channel.state.waitcnt = stopidx - i;
- run_index = i;
-
- run_end = i + this.decode_run(channel.state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] = cur_row[pixelm1+rgb32_pixel_pad];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + channel.state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode, this.io_word);
- correlate_row.row[i] = a.rc;
- cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
-
- if (!rc)
- {
- channel.state.waitcnt = stopidx - end;
- return;
- }
- }
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row = function(channel, prev_row,
- cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var correlate_row = channel.correlate_row;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <= width)) {
- if (channel.state.wmileft) {
- this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row, pos,
- pos + channel.state.wmileft, bpc, bpc_mask);
- pos += channel.state.wmileft;
- width -= channel.state.wmileft;
- }
-
- channel.state.wmidx++;
- channel.state.set_wm_trigger();
- channel.state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row, pos,
- pos + width, bpc, bpc_mask);
- if (wmimax > channel.state.wmidx) {
- channel.state.wmileft -= width;
- }
- }
-}
-
-/* We need to be generating rgb32 or rgba */
-QuicEncoder.prototype.quic_decode = function(buf, stride)
-{
- var row;
-
- switch (this.type)
- {
- case QUIC_IMAGE_TYPE_RGB32:
- case QUIC_IMAGE_TYPE_RGB24:
- this.channels[0].correlate_row.zero = 0;
- this.channels[1].correlate_row.zero = 0;
- this.channels[2].correlate_row.zero = 0;
- this.quic_rgb32_uncompress_row0(buf);
-
- this.rows_completed++;
- for (row = 1; row < this.height; row++)
- {
- var prev = buf;
- buf = prev.subarray(stride);
- this.channels[0].correlate_row.zero = this.channels[0].correlate_row.row[0];
- this.channels[1].correlate_row.zero = this.channels[1].correlate_row.row[0];
- this.channels[2].correlate_row.zero = this.channels[2].correlate_row.row[0];
- this.quic_rgb32_uncompress_row(prev, buf);
- this.rows_completed++;
- };
- break;
- case QUIC_IMAGE_TYPE_RGB16:
- console.log("quic: unsupported output format\n");
- return false;
- break;
- case QUIC_IMAGE_TYPE_RGBA:
- this.channels[0].correlate_row.zero = 0;
- this.channels[1].correlate_row.zero = 0;
- this.channels[2].correlate_row.zero = 0;
- this.quic_rgb32_uncompress_row0(buf);
-
- this.channels[3].correlate_row.zero = 0;
- this.quic_four_uncompress_row0(this.channels[3], buf);
-
- this.rows_completed++;
- for (row = 1; row < this.height; row++) {
- var prev = buf;
- buf = prev.subarray(stride);
-
- this.channels[0].correlate_row.zero = this.channels[0].correlate_row.row[0];
- this.channels[1].correlate_row.zero = this.channels[1].correlate_row.row[0];
- this.channels[2].correlate_row.zero = this.channels[2].correlate_row.row[0];
- this.quic_rgb32_uncompress_row(prev, buf);
-
- this.channels[3].correlate_row.zero = this.channels[3].correlate_row.row[0];
- this.quic_four_uncompress_row(encoder.channels[3], prev, buf);
- this.rows_completed++;
- }
- break;
-
- case QUIC_IMAGE_TYPE_GRAY:
- console.log("quic: unsupported output format\n");
- return false;
- break;
-
- case QUIC_IMAGE_TYPE_INVALID:
- default:
- console.log("quic: bad image type\n");
- return false;
- }
- return true;
-}
-
-QuicEncoder.prototype.simple_quic_decode = function(buf)
-{
- var stride = 4; /* FIXME - proper stride calc please */
- if (!this.quic_decode_begin(buf))
- return undefined;
- if (this.type != QUIC_IMAGE_TYPE_RGB32 && this.type != QUIC_IMAGE_TYPE_RGB24
- && this.type != QUIC_IMAGE_TYPE_RGBA)
- return undefined;
- var out = new Uint8Array(this.width*this.height*4);
- out[0] = 69;
- if (this.quic_decode( out, (this.width * stride)))
- return out;
- return undefined;
-}
-
-function SpiceQuic()
-{
-}
-
-SpiceQuic.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- if (!encoder)
- throw("quic: no quic encoder");
- this.data_size = dv.getUint32(at, true);
- at += 4;
- var buf = new Uint8Array(mb.slice(at));
- this.outptr = encoder.simple_quic_decode(buf);
- if (this.outptr)
- {
- this.type = encoder.type;
- this.width = encoder.width;
- this.height = encoder.height;
- }
- at += buf.length;
- return at;
- },
-}
-
-function convert_spice_quic_to_web(context, spice_quic)
-{
- var ret = context.createImageData(spice_quic.width, spice_quic.height);
- var i;
- for (i = 0; i < (ret.width * ret.height * 4); i+=4)
- {
- ret.data[i + 0] = spice_quic.outptr[i + 2];
- ret.data[i + 1] = spice_quic.outptr[i + 1];
- ret.data[i + 2] = spice_quic.outptr[i + 0];
- if (spice_quic.type !== QUIC_IMAGE_TYPE_RGBA)
- ret.data[i + 3] = 255;
- else
- ret.data[i + 3] = 255 - spice_quic.outptr[i + 3];
- }
- return ret;
-}
-
-/* Module initialization */
-if (need_init)
-{
- need_init = false;
-
- family_init(family_8bpc, 8, DEFmaxclen);
- family_init(family_5bpc, 5, DEFmaxclen);
- /* init_zeroLUT */
- var i, j, k, l;
-
- j = k = 1;
- l = 8;
- for (i = 0; i < 256; ++i) {
- zeroLUT[i] = l;
- --k;
- if (k == 0) {
- k = j;
- --l;
- j *= 2;
- }
- }
-
- encoder = new QuicEncoder;
-
- if (!encoder)
- throw("quic: failed to create encoder");
-}
diff --git a/plugins/kimchi/ui/spice-html5/resize.js b/plugins/kimchi/ui/spice-html5/resize.js
deleted file mode 100644
index f5410d3..0000000
--- a/plugins/kimchi/ui/spice-html5/resize.js
+++ /dev/null
@@ -1,70 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2014 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** resize.js
-** This bit of Javascript is a set of logic to help with window
-** resizing, using the agent channel to request screen resizes.
-**
-** It's a bit tricky, as we want to wait for resizing to settle down
-** before sending a size. Further, while horizontal resizing to use the whole
-** browser width is fairly easy to arrange with css, resizing an element to use
-** the whole vertical space (or to force a middle div to consume the bulk of the browser
-** window size) is tricky, and the consensus seems to be that Javascript is
-** the only right way to do it.
-**--------------------------------------------------------------------------*/
-function resize_helper(sc)
-{
- var w = document.getElementById(sc.screen_id).clientWidth;
- var h = document.getElementById(sc.screen_id).clientHeight;
-
- var m = document.getElementById(sc.message_id);
-
- /* Resize vertically; basically we leave a 20 pixel margin
- at the bottom, and use the position of the message window
- to figure out how to resize */
- var hd = window.innerHeight - m.offsetHeight - m.offsetTop - 20;
-
- /* Xorg requires height be a multiple of 8; round up */
- h = h + hd;
- if (h % 8 > 0)
- h += (8 - (h % 8));
-
- /* Xorg requires width be a multiple of 8; round up */
- if (w % 8 > 0)
- w += (8 - (w % 8));
-
-
- sc.resize_window(0, w, h, 32, 0, 0);
- sc.spice_resize_timer = undefined;
-}
-
-function handle_resize(e)
-{
- var sc = window.spice_connection;
-
- if (sc && sc.spice_resize_timer)
- {
- window.clearTimeout(sc.spice_resize_timer);
- sc.spice_resize_timer = undefined;
- }
-
- sc.spice_resize_timer = window.setTimeout(resize_helper, 200, sc);
-}
diff --git a/plugins/kimchi/ui/spice-html5/simulatecursor.js b/plugins/kimchi/ui/spice-html5/simulatecursor.js
deleted file mode 100644
index b1fce06..0000000
--- a/plugins/kimchi/ui/spice-html5/simulatecursor.js
+++ /dev/null
@@ -1,202 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2013 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceSimulateCursor
-** Internet Explorer 10 does not support data uri's in cursor assignment.
-** This file provides a number of gimmicks to compensate. First, if there
-** is a preloaded cursor available, we will use that. Failing that, we will
-** simulate a cursor using an image that is moved around the screen.
-**--------------------------------------------------------------------------*/
-var SpiceSimulateCursor = {
-
-cursors : new Array(),
-unknown_cursors : new Array(),
-warned: false,
-
-add_cursor: function(sha1, value)
-{
- SpiceSimulateCursor.cursors[sha1] = value;
-},
-
-unknown_cursor: function(sha1, curdata)
-{
- if (! SpiceSimulateCursor.warned)
- {
- SpiceSimulateCursor.warned = true;
- alert("Internet Explorer does not support dynamic cursors. " +
- "This page will now simulate cursors with images, " +
- "which will be imperfect. We recommend using Chrome or Firefox instead. " +
- "\n\nIf you need to use Internet Explorer, you can create a static cursor " +
- "file for each cursor your application uses. " +
- "View the console log for more information on creating static cursors for your environment.");
- }
-
- if (! SpiceSimulateCursor.unknown_cursors[sha1])
- {
- SpiceSimulateCursor.unknown_cursors[sha1] = curdata;
- console.log('Unknown cursor. Simulation required. To avoid simulation for this cursor, create and include a custom javascript file, and add the following line:');
- console.log('SpiceCursorSimulator.add_cursor("' + sha1 + '"), "<your filename here>.cur");');
- console.log('And then run following command, redirecting output into <your filename here>.cur:');
- console.log('php -r "echo urldecode(\'' + curdata + '\');"');
- }
-},
-
-simulate_cursor: function (spicecursor, cursor, screen, pngstr)
-{
- var cursor_sha = hex_sha1(pngstr + ' ' + cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y);
- if (typeof SpiceSimulateCursor.cursors != 'undefined')
- if (typeof SpiceSimulateCursor.cursors[cursor_sha] != 'undefined')
- {
- var curstr = 'url(' + SpiceSimulateCursor.cursors[cursor_sha] + '), default';
- screen.style.cursor = curstr;
- }
-
- if (window.getComputedStyle(screen, null).cursor == 'auto')
- {
- SpiceSimulateCursor.unknown_cursor(cursor_sha,
- SpiceSimulateCursor.create_icondir(cursor.header.width, cursor.header.height,
- cursor.data.byteLength, cursor.header.hot_spot_x, cursor.header.hot_spot_y) + pngstr);
-
- document.getElementById(spicecursor.parent.screen_id).style.cursor = 'none';
- if (! spicecursor.spice_simulated_cursor)
- {
- spicecursor.spice_simulated_cursor = document.createElement('img');
-
- spicecursor.spice_simulated_cursor.style.position = 'absolute';
- spicecursor.spice_simulated_cursor.style.display = 'none';
- spicecursor.spice_simulated_cursor.style.overflow = 'hidden';
-
- spicecursor.spice_simulated_cursor.spice_screen = document.getElementById(spicecursor.parent.screen_id);
-
- spicecursor.spice_simulated_cursor.addEventListener('mousemove', SpiceSimulateCursor.handle_sim_mousemove);
-
- spicecursor.spice_simulated_cursor.spice_screen.appendChild(spicecursor.spice_simulated_cursor);
- }
-
- spicecursor.spice_simulated_cursor.src = 'data:image/png,' + pngstr;
-
- spicecursor.spice_simulated_cursor.spice_hot_x = cursor.header.hot_spot_x;
- spicecursor.spice_simulated_cursor.spice_hot_y = cursor.header.hot_spot_y;
-
- spicecursor.spice_simulated_cursor.style.pointerEvents = "none";
- }
- else
- {
- if (spicecursor.spice_simulated_cursor)
- {
- spicecursor.spice_simulated_cursor.spice_screen.removeChild(spicecursor.spice_simulated_cursor);
- delete spicecursor.spice_simulated_cursor;
- }
- }
-},
-
-handle_sim_mousemove: function(e)
-{
- var retval;
- var f = SpiceSimulateCursor.duplicate_mouse_event(e, this.spice_screen);
- return this.spice_screen.dispatchEvent(f);
-},
-
-duplicate_mouse_event: function(e, target)
-{
- var evt = document.createEvent("mouseevent");
- evt.initMouseEvent(e.type, true, true, e.view, e.detail,
- e.screenX, e.screenY, e.clientX, e.clientY,
- e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
- return evt;
-},
-
-ICONDIR: function ()
-{
-},
-
-ICONDIRENTRY: function(width, height, bytes, hot_x, hot_y)
-{
- this.width = width;
- this.height = height;
- this.bytes = bytes;
- this.hot_x = hot_x;
- this.hot_y = hot_y;
-},
-
-
-create_icondir: function (width, height, bytes, hot_x, hot_y)
-{
- var i;
- var header = new SpiceSimulateCursor.ICONDIR();
- var entry = new SpiceSimulateCursor.ICONDIRENTRY(width, height, bytes, hot_x, hot_y);
-
- var mb = new ArrayBuffer(header.buffer_size() + entry.buffer_size());
- var at = header.to_buffer(mb);
- at = entry.to_buffer(mb, at);
-
- var u8 = new Uint8Array(mb);
- var str = "";
- for (i = 0; i < at; i++)
- {
- str += "%";
- if (u8[i] < 16)
- str += "0";
- str += u8[i].toString(16);
- }
- return str;
-},
-
-};
-
-SpiceSimulateCursor.ICONDIR.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint16(at, 0, true); at += 2;
- dv.setUint16(at, 2, true); at += 2;
- dv.setUint16(at, 1, true); at += 2;
- return at;
- },
- buffer_size: function()
- {
- return 6;
- }
-};
-
-SpiceSimulateCursor.ICONDIRENTRY.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint8(at, this.width); at++;
- dv.setUint8(at, this.height); at++;
- dv.setUint8(at, 0); at++; /* color palette count, unused */
- dv.setUint8(at, 0); at++; /* reserved */
- dv.setUint16(at, this.hot_x, true); at += 2;
- dv.setUint16(at, this.hot_y, true); at += 2;
- dv.setUint32(at, this.bytes, true); at += 4;
- dv.setUint32(at, at + 4, true); at += 4; /* Offset to bytes */
- return at;
- },
- buffer_size: function()
- {
- return 16;
- }
-};
diff --git a/plugins/kimchi/ui/spice-html5/spicearraybuffer.js b/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
deleted file mode 100644
index 228bce6..0000000
--- a/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
+++ /dev/null
@@ -1,58 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceArrayBufferSlice
-** This function is a work around for IE 10, which has no slice()
-** method in it's subclass.
-**--------------------------------------------------------------------------*/
-function SpiceArrayBufferSlice(start, end)
-{
- start = start || 0;
- end = end || this.byteLength;
- if (end < 0)
- end = this.byteLength + end;
- if (start < 0)
- start = this.byteLength + start;
- if (start < 0)
- start = 0;
- if (end < 0)
- end = 0;
- if (end > this.byteLength)
- end = this.byteLength;
- if (start > end)
- start = end;
-
- var ret = new ArrayBuffer(end - start);
- var in1 = new Uint8Array(this, start, end - start);
- var out = new Uint8Array(ret);
- var i;
-
- for (i = 0; i < end - start; i++)
- out[i] = in1[i];
-
- return ret;
-}
-
-if (! ArrayBuffer.prototype.slice)
-{
- ArrayBuffer.prototype.slice = SpiceArrayBufferSlice;
- console.log("WARNING: ArrayBuffer.slice() is missing; we are extending ArrayBuffer to compensate");
-}
diff --git a/plugins/kimchi/ui/spice-html5/spiceconn.js b/plugins/kimchi/ui/spice-html5/spiceconn.js
deleted file mode 100644
index e33227e..0000000
--- a/plugins/kimchi/ui/spice-html5/spiceconn.js
+++ /dev/null
@@ -1,460 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceConn
-** This is the base Javascript class for establishing and
-** managing a connection to a Spice Server.
-** It is used to provide core functionality to the Spice main,
-** display, inputs, and cursor channels. See main.js for
-** usage.
-**--------------------------------------------------------------------------*/
-function SpiceConn(o)
-{
- if (o === undefined || o.uri === undefined || ! o.uri)
- throw new Error("You must specify a uri");
-
- this.ws = new WebSocket(o.uri, 'binary');
-
- if (! this.ws.binaryType)
- throw new Error("WebSocket doesn't support binaryType. Try a different browser.");
-
- this.connection_id = o.connection_id !== undefined ? o.connection_id : 0;
- this.type = o.type !== undefined ? o.type : SPICE_CHANNEL_MAIN;
- this.chan_id = o.chan_id !== undefined ? o.chan_id : 0;
- if (o.parent !== undefined)
- {
- this.parent = o.parent;
- this.message_id = o.parent.message_id;
- this.password = o.parent.password;
- }
- if (o.screen_id !== undefined)
- this.screen_id = o.screen_id;
- if (o.dump_id !== undefined)
- this.dump_id = o.dump_id;
- if (o.message_id !== undefined)
- this.message_id = o.message_id;
- if (o.password !== undefined)
- this.password = o.password;
- if (o.onerror !== undefined)
- this.onerror = o.onerror;
- if (o.onsuccess !== undefined)
- this.onsuccess = o.onsuccess;
- if (o.onagent !== undefined)
- this.onagent = o.onagent;
-
- this.state = "connecting";
- this.ws.parent = this;
- this.wire_reader = new SpiceWireReader(this, this.process_inbound);
- this.messages_sent = 0;
- this.warnings = [];
-
- this.ws.addEventListener('open', function(e) {
- DEBUG > 0 && console.log(">> WebSockets.onopen");
- DEBUG > 0 && console.log("id " + this.parent.connection_id +"; type " + this.parent.type);
-
- /***********************************************************************
- ** WHERE IT ALL REALLY BEGINS
- ***********************************************************************/
- this.parent.send_hdr();
- this.parent.wire_reader.request(SpiceLinkHeader.prototype.buffer_size());
- this.parent.state = "start";
- });
- this.ws.addEventListener('error', function(e) {
- this.parent.log_err(">> WebSockets.onerror" + e.toString());
- this.parent.report_error(e);
- });
- this.ws.addEventListener('close', function(e) {
- DEBUG > 0 && console.log(">> WebSockets.onclose");
- DEBUG > 0 && console.log("id " + this.parent.connection_id +"; type " + this.parent.type);
- DEBUG > 0 && console.log(e);
- if (this.parent.state != "closing" && this.parent.state != "error" && this.parent.onerror !== undefined)
- {
- var e;
- if (this.parent.state == "connecting")
- e = new Error("Connection refused.");
- else if (this.parent.state == "start" || this.parent.state == "link")
- e = new Error("Unexpected protocol mismatch.");
- else if (this.parent.state == "ticket")
- e = new Error("Bad password.");
- else
- e = new Error("Unexpected close while " + this.parent.state);
-
- this.parent.onerror(e);
- this.parent.log_err(e.toString());
- }
- });
-
- if (this.ws.readyState == 2 || this.ws.readyState == 3)
- throw new Error("Unable to connect to " + o.uri);
-
- this.timeout = window.setTimeout(spiceconn_timeout, SPICE_CONNECT_TIMEOUT, this);
-}
-
-SpiceConn.prototype =
-{
- send_hdr : function ()
- {
- var hdr = new SpiceLinkHeader;
- var msg = new SpiceLinkMess;
-
- msg.connection_id = this.connection_id;
- msg.channel_type = this.type;
- // FIXME - we're not setting a channel_id...
- msg.common_caps.push(
- (1 << SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION) |
- (1 << SPICE_COMMON_CAP_MINI_HEADER)
- );
-
- if (msg.channel_type == SPICE_CHANNEL_PLAYBACK)
- msg.channel_caps.push(
- (1 << SPICE_PLAYBACK_CAP_OPUS)
- );
-
- hdr.size = msg.buffer_size();
-
- var mb = new ArrayBuffer(hdr.buffer_size() + msg.buffer_size());
- hdr.to_buffer(mb);
- msg.to_buffer(mb, hdr.buffer_size());
-
- DEBUG > 1 && console.log("Sending header:");
- DEBUG > 2 && hexdump_buffer(mb);
- this.ws.send(mb);
- },
-
- send_ticket: function(ticket)
- {
- var hdr = new SpiceLinkAuthTicket();
- hdr.auth_mechanism = SPICE_COMMON_CAP_AUTH_SPICE;
- // FIXME - we need to implement RSA to make this work right
- hdr.encrypted_data = ticket;
- var mb = new ArrayBuffer(hdr.buffer_size());
-
- hdr.to_buffer(mb);
- DEBUG > 1 && console.log("Sending ticket:");
- DEBUG > 2 && hexdump_buffer(mb);
- this.ws.send(mb);
- },
-
- send_msg: function(msg)
- {
- var mb = new ArrayBuffer(msg.buffer_size());
- msg.to_buffer(mb);
- this.messages_sent++;
- DEBUG > 0 && console.log(">> hdr " + this.channel_type() + " type " + msg.type + " size " + mb.byteLength);
- DEBUG > 2 && hexdump_buffer(mb);
- this.ws.send(mb);
- },
-
- process_inbound: function(mb, saved_header)
- {
- DEBUG > 2 && console.log(this.type + ": processing message of size " + mb.byteLength + "; state is " + this.state);
- if (this.state == "ready")
- {
- if (saved_header == undefined)
- {
- var msg = new SpiceMiniData(mb);
-
- if (msg.type > 500)
- {
- alert("Something has gone very wrong; we think we have message of type " + msg.type);
- debugger;
- }
-
- if (msg.size == 0)
- {
- this.process_message(msg);
- this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
- }
- else
- {
- this.wire_reader.request(msg.size);
- this.wire_reader.save_header(msg);
- }
- }
- else
- {
- saved_header.data = mb;
- this.process_message(saved_header);
- this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
- this.wire_reader.save_header(undefined);
- }
- }
-
- else if (this.state == "start")
- {
- this.reply_hdr = new SpiceLinkHeader(mb);
- if (this.reply_hdr.magic != SPICE_MAGIC)
- {
- this.state = "error";
- var e = new Error('Error: magic mismatch: ' + this.reply_hdr.magic);
- this.report_error(e);
- }
- else
- {
- // FIXME - Determine major/minor version requirements
- this.wire_reader.request(this.reply_hdr.size);
- this.state = "link";
- }
- }
-
- else if (this.state == "link")
- {
- this.reply_link = new SpiceLinkReply(mb);
- // FIXME - Screen the caps - require minihdr at least, right?
- if (this.reply_link.error)
- {
- this.state = "error";
- var e = new Error('Error: reply link error ' + this.reply_link.error);
- this.report_error(e);
- }
- else
- {
- this.send_ticket(rsa_encrypt(this.reply_link.pub_key, this.password + String.fromCharCode(0)));
- this.state = "ticket";
- this.wire_reader.request(SpiceLinkAuthReply.prototype.buffer_size());
- }
- }
-
- else if (this.state == "ticket")
- {
- this.auth_reply = new SpiceLinkAuthReply(mb);
- if (this.auth_reply.auth_code == SPICE_LINK_ERR_OK)
- {
- DEBUG > 0 && console.log(this.type + ': Connected');
-
- if (this.type == SPICE_CHANNEL_DISPLAY)
- {
- // FIXME - pixmap and glz dictionary config info?
- var dinit = new SpiceMsgcDisplayInit();
- var reply = new SpiceMiniData();
- reply.build_msg(SPICE_MSGC_DISPLAY_INIT, dinit);
- DEBUG > 0 && console.log("Request display init");
- this.send_msg(reply);
- }
- this.state = "ready";
- this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
- if (this.timeout)
- {
- window.clearTimeout(this.timeout);
- delete this.timeout;
- }
- }
- else
- {
- this.state = "error";
- if (this.auth_reply.auth_code == SPICE_LINK_ERR_PERMISSION_DENIED)
- {
- var e = new Error("Permission denied.");
- }
- else
- {
- var e = new Error("Unexpected link error " + this.auth_reply.auth_code);
- }
- this.report_error(e);
- }
- }
- },
-
- process_common_messages : function(msg)
- {
- if (msg.type == SPICE_MSG_SET_ACK)
- {
- var ack = new SpiceMsgSetAck(msg.data);
- // FIXME - what to do with generation?
- this.ack_window = ack.window;
- DEBUG > 1 && console.log(this.type + ": set ack to " + ack.window);
- this.msgs_until_ack = this.ack_window;
- var ackack = new SpiceMsgcAckSync(ack);
- var reply = new SpiceMiniData();
- reply.build_msg(SPICE_MSGC_ACK_SYNC, ackack);
- this.send_msg(reply);
- return true;
- }
-
- if (msg.type == SPICE_MSG_PING)
- {
- DEBUG > 1 && console.log("ping!");
- var pong = new SpiceMiniData;
- pong.type = SPICE_MSGC_PONG;
- if (msg.data)
- {
- pong.data = msg.data.slice(0, 12);
- }
- pong.size = pong.buffer_size();
- this.send_msg(pong);
- return true;
- }
-
- if (msg.type == SPICE_MSG_NOTIFY)
- {
- // FIXME - Visibility + what
- var notify = new SpiceMsgNotify(msg.data);
- if (notify.severity == SPICE_NOTIFY_SEVERITY_ERROR)
- this.log_err(notify.message);
- else if (notify.severity == SPICE_NOTIFY_SEVERITY_WARN )
- this.log_warn(notify.message);
- else
- this.log_info(notify.message);
- return true;
- }
-
- return false;
-
- },
-
- process_message: function(msg)
- {
- var rc;
- DEBUG > 0 && console.log("<< hdr " + this.channel_type() + " type " + msg.type + " size " + (msg.data && msg.data.byteLength));
- rc = this.process_common_messages(msg);
- if (! rc)
- {
- if (this.process_channel_message)
- {
- rc = this.process_channel_message(msg);
- if (! rc)
- this.log_warn(this.type + ": Unknown message type " + msg.type + "!");
- }
- else
- this.log_err(this.type + ": No message handlers for this channel; message " + msg.type);
- }
-
- if (this.msgs_until_ack !== undefined && this.ack_window)
- {
- this.msgs_until_ack--;
- if (this.msgs_until_ack <= 0)
- {
- this.msgs_until_ack = this.ack_window;
- var ack = new SpiceMiniData();
- ack.type = SPICE_MSGC_ACK;
- this.send_msg(ack);
- DEBUG > 1 && console.log(this.type + ": sent ack");
- }
- }
-
- return rc;
- },
-
- channel_type: function()
- {
- if (this.type == SPICE_CHANNEL_MAIN)
- return "main";
- else if (this.type == SPICE_CHANNEL_DISPLAY)
- return "display";
- else if (this.type == SPICE_CHANNEL_INPUTS)
- return "inputs";
- else if (this.type == SPICE_CHANNEL_CURSOR)
- return "cursor";
- return "unknown-" + this.type;
-
- },
-
- log_info: function()
- {
- var msg = Array.prototype.join.call(arguments, " ");
- console.log(msg);
- if (this.message_id)
- {
- var p = document.createElement("p");
- p.appendChild(document.createTextNode(msg));
- p.className += "spice-message-info";
- document.getElementById(this.message_id).appendChild(p);
- }
- },
-
- log_warn: function()
- {
- var msg = Array.prototype.join.call(arguments, " ");
- console.log("WARNING: " + msg);
- if (this.message_id)
- {
- var p = document.createElement("p");
- p.appendChild(document.createTextNode(msg));
- p.className += "spice-message-warning";
- document.getElementById(this.message_id).appendChild(p);
- }
- },
-
- log_err: function()
- {
- var msg = Array.prototype.join.call(arguments, " ");
- console.log("ERROR: " + msg);
- if (this.message_id)
- {
- var p = document.createElement("p");
- p.appendChild(document.createTextNode(msg));
- p.className += "spice-message-error";
- document.getElementById(this.message_id).appendChild(p);
- }
- },
-
- known_unimplemented: function(type, msg)
- {
- if ( (!this.warnings[type]) || DEBUG > 1)
- {
- var str = "";
- if (DEBUG <= 1)
- str = " [ further notices suppressed ]";
- this.log_warn("Unimplemented function " + type + "(" + msg + ")" + str);
- this.warnings[type] = true;
- }
- },
-
- report_error: function(e)
- {
- this.log_err(e.toString());
- if (this.onerror != undefined)
- this.onerror(e);
- else
- throw(e);
- },
-
- report_success: function(m)
- {
- if (this.onsuccess != undefined)
- this.onsuccess(m);
- },
-
- cleanup: function()
- {
- if (this.timeout)
- {
- window.clearTimeout(this.timeout);
- delete this.timeout;
- }
- if (this.ws)
- {
- this.ws.close();
- this.ws = undefined;
- }
- },
-
- handle_timeout: function()
- {
- var e = new Error("Connection timed out.");
- this.report_error(e);
- },
-}
-
-function spiceconn_timeout(sc)
-{
- SpiceConn.prototype.handle_timeout.call(sc);
-}
diff --git a/plugins/kimchi/ui/spice-html5/spicedataview.js b/plugins/kimchi/ui/spice-html5/spicedataview.js
deleted file mode 100644
index 800df03..0000000
--- a/plugins/kimchi/ui/spice-html5/spicedataview.js
+++ /dev/null
@@ -1,120 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceDataView
-** FIXME FIXME
-** This is used because Firefox does not have DataView yet.
-** We should use DataView if we have it, because it *has* to
-** be faster than this code
-**--------------------------------------------------------------------------*/
-function SpiceDataView(buffer, byteOffset, byteLength)
-{
- if (byteOffset !== undefined)
- {
- if (byteLength !== undefined)
- this.u8 = new Uint8Array(buffer, byteOffset, byteLength);
- else
- this.u8 = new Uint8Array(buffer, byteOffset);
- }
- else
- this.u8 = new Uint8Array(buffer);
-};
-
-SpiceDataView.prototype = {
- getUint8: function(byteOffset)
- {
- return this.u8[byteOffset];
- },
- getUint16: function(byteOffset, littleEndian)
- {
- var low = 1, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 1;
- }
-
- return (this.u8[byteOffset + high] << 8) | this.u8[byteOffset + low];
- },
- getUint32: function(byteOffset, littleEndian)
- {
- var low = 2, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 2;
- }
-
- return (this.getUint16(byteOffset + high, littleEndian) << 16) |
- this.getUint16(byteOffset + low, littleEndian);
- },
- getUint64: function (byteOffset, littleEndian)
- {
- var low = 4, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 4;
- }
-
- return (this.getUint32(byteOffset + high, littleEndian) << 32) |
- this.getUint32(byteOffset + low, littleEndian);
- },
- setUint8: function(byteOffset, b)
- {
- this.u8[byteOffset] = (b & 0xff);
- },
- setUint16: function(byteOffset, i, littleEndian)
- {
- var low = 1, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 1;
- }
- this.u8[byteOffset + high] = (i & 0xffff) >> 8;
- this.u8[byteOffset + low] = (i & 0x00ff);
- },
- setUint32: function(byteOffset, w, littleEndian)
- {
- var low = 2, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 2;
- }
-
- this.setUint16(byteOffset + high, (w & 0xffffffff) >> 16, littleEndian);
- this.setUint16(byteOffset + low, (w & 0x0000ffff), littleEndian);
- },
- setUint64: function(byteOffset, w, littleEndian)
- {
- var low = 4, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 4;
- }
-
- this.setUint32(byteOffset + high, (w & 0xffffffffffffffff) >> 32, littleEndian);
- this.setUint32(byteOffset + low, (w & 0x00000000ffffffff), littleEndian);
- },
-}
diff --git a/plugins/kimchi/ui/spice-html5/spicemsg.js b/plugins/kimchi/ui/spice-html5/spicemsg.js
deleted file mode 100644
index c64f5a3..0000000
--- a/plugins/kimchi/ui/spice-html5/spicemsg.js
+++ /dev/null
@@ -1,1047 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** Spice messages
-** This file contains classes for passing messages to and from
-** a spice server. This file should arguably be generated from
-** spice.proto, but it was instead put together by hand.
-**--------------------------------------------------------------------------*/
-function SpiceLinkHeader(a, at)
-{
- this.magic = SPICE_MAGIC;
- this.major_version = SPICE_VERSION_MAJOR;
- this.minor_version = SPICE_VERSION_MINOR;
- this.size = 0;
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkHeader.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.magic = "";
- for (var i = 0; i < 4; i++)
- this.magic += String.fromCharCode(dv.getUint8(at + i));
- at += 4;
-
- this.major_version = dv.getUint32(at, true); at += 4;
- this.minor_version = dv.getUint32(at, true); at += 4;
- this.size = dv.getUint32(at, true); at += 4;
- },
-
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- for (var i = 0; i < 4; i++)
- dv.setUint8(at + i, this.magic.charCodeAt(i));
- at += 4;
-
- dv.setUint32(at, this.major_version, true); at += 4;
- dv.setUint32(at, this.minor_version, true); at += 4;
- dv.setUint32(at, this.size, true); at += 4;
- },
- buffer_size: function()
- {
- return 16;
- },
-}
-
-function SpiceLinkMess(a, at)
-{
- this.connection_id = 0;
- this.channel_type = 0;
- this.channel_id = 0;
- this.common_caps = [];
- this.channel_caps = [];
-
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkMess.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var orig_at = at;
- var dv = new SpiceDataView(a);
- this.connection_id = dv.getUint32(at, true); at += 4;
- this.channel_type = dv.getUint8(at, true); at++;
- this.channel_id = dv.getUint8(at, true); at++;
- var num_common_caps = dv.getUint32(at, true); at += 4;
- var num_channel_caps = dv.getUint32(at, true); at += 4;
- var caps_offset = dv.getUint32(at, true); at += 4;
-
- at = orig_at + caps_offset;
- this.common_caps = [];
- for (i = 0; i < num_common_caps; i++)
- {
- this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
-
- this.channel_caps = [];
- for (i = 0; i < num_channel_caps; i++)
- {
- this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
- },
-
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig_at = at;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.connection_id, true); at += 4;
- dv.setUint8(at, this.channel_type, true); at++;
- dv.setUint8(at, this.channel_id, true); at++;
- dv.setUint32(at, this.common_caps.length, true); at += 4;
- dv.setUint32(at, this.channel_caps.length, true); at += 4;
- dv.setUint32(at, (at - orig_at) + 4, true); at += 4;
-
- for (i = 0; i < this.common_caps.length; i++)
- {
- dv.setUint32(at, this.common_caps[i], true); at += 4;
- }
-
- for (i = 0; i < this.channel_caps.length; i++)
- {
- dv.setUint32(at, this.channel_caps[i], true); at += 4;
- }
- },
- buffer_size: function()
- {
- return 18 + (4 * this.common_caps.length) + (4 * this.channel_caps.length);
- }
-}
-
-function SpiceLinkReply(a, at)
-{
- this.error = 0;
- this.pub_key = undefined;
- this.common_caps = [];
- this.channel_caps = [];
-
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkReply.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var orig_at = at;
- var dv = new SpiceDataView(a);
- this.error = dv.getUint32(at, true); at += 4;
-
- this.pub_key = create_rsa_from_mb(a, at);
- at += SPICE_TICKET_PUBKEY_BYTES;
-
- var num_common_caps = dv.getUint32(at, true); at += 4;
- var num_channel_caps = dv.getUint32(at, true); at += 4;
- var caps_offset = dv.getUint32(at, true); at += 4;
-
- at = orig_at + caps_offset;
- this.common_caps = [];
- for (i = 0; i < num_common_caps; i++)
- {
- this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
-
- this.channel_caps = [];
- for (i = 0; i < num_channel_caps; i++)
- {
- this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
- },
-}
-
-function SpiceLinkAuthTicket(a, at)
-{
- this.auth_mechanism = 0;
- this.encrypted_data = undefined;
-}
-
-SpiceLinkAuthTicket.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.auth_mechanism, true); at += 4;
- for (i = 0; i < SPICE_TICKET_KEY_PAIR_LENGTH / 8; i++)
- {
- if (this.encrypted_data && i < this.encrypted_data.length)
- dv.setUint8(at, this.encrypted_data[i], true);
- else
- dv.setUint8(at, 0, true);
- at++;
- }
- },
- buffer_size: function()
- {
- return 4 + (SPICE_TICKET_KEY_PAIR_LENGTH / 8);
- }
-}
-
-function SpiceLinkAuthReply(a, at)
-{
- this.auth_code = 0;
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkAuthReply.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.auth_code = dv.getUint32(at, true); at += 4;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMiniData(a, at)
-{
- this.type = 0;
- this.size = 0;
- this.data = undefined;
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceMiniData.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- this.type = dv.getUint16(at, true); at += 2;
- this.size = dv.getUint32(at, true); at += 4;
- if (a.byteLength > at)
- {
- this.data = a.slice(at);
- at += this.data.byteLength;
- }
- },
- to_buffer : function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint16(at, this.type, true); at += 2;
- dv.setUint32(at, this.data ? this.data.byteLength : 0, true); at += 4;
- if (this.data && this.data.byteLength > 0)
- {
- var u8arr = new Uint8Array(this.data);
- for (i = 0; i < u8arr.length; i++, at++)
- dv.setUint8(at, u8arr[i], true);
- }
- },
- build_msg : function(in_type, extra)
- {
- this.type = in_type;
- this.size = extra.buffer_size();
- this.data = new ArrayBuffer(this.size);
- extra.to_buffer(this.data);
- },
- buffer_size: function()
- {
- if (this.data)
- return 6 + this.data.byteLength;
- else
- return 6;
- },
-}
-
-function SpiceMsgChannels(a, at)
-{
- this.num_of_channels = 0;
- this.channels = [];
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceMsgChannels.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- this.num_of_channels = dv.getUint32(at, true); at += 4;
- for (i = 0; i < this.num_of_channels; i++)
- {
- var chan = new SpiceChannelId();
- at = chan.from_dv(dv, at, a);
- this.channels.push(chan);
- }
- },
-}
-
-function SpiceMsgMainInit(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgMainInit.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.session_id = dv.getUint32(at, true); at += 4;
- this.display_channels_hint = dv.getUint32(at, true); at += 4;
- this.supported_mouse_modes = dv.getUint32(at, true); at += 4;
- this.current_mouse_mode = dv.getUint32(at, true); at += 4;
- this.agent_connected = dv.getUint32(at, true); at += 4;
- this.agent_tokens = dv.getUint32(at, true); at += 4;
- this.multi_media_time = dv.getUint32(at, true); at += 4;
- this.ram_hint = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgMainMouseMode(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgMainMouseMode.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.supported_modes = dv.getUint16(at, true); at += 2;
- this.current_mode = dv.getUint16(at, true); at += 2;
- },
-}
-
-function SpiceMsgSetAck(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgSetAck.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.generation = dv.getUint32(at, true); at += 4;
- this.window = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgcAckSync(ack)
-{
- this.generation = ack.generation;
-}
-
-SpiceMsgcAckSync.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.generation, true); at += 4;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMsgcMainMouseModeRequest(mode)
-{
- this.mode = mode;
-}
-
-SpiceMsgcMainMouseModeRequest.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint16(at, this.mode, true); at += 2;
- },
- buffer_size: function()
- {
- return 2;
- }
-}
-
-function SpiceMsgcMainAgentStart(num_tokens)
-{
- this.num_tokens = num_tokens;
-}
-
-SpiceMsgcMainAgentStart.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.num_tokens, true); at += 4;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMsgcMainAgentData(type, data)
-{
- this.protocol = VD_AGENT_PROTOCOL;
- this.type = type;
- this.opaque = 0;
- this.size = data.buffer_size();
- this.data = data;
-}
-
-SpiceMsgcMainAgentData.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.protocol, true); at += 4;
- dv.setUint32(at, this.type, true); at += 4;
- dv.setUint64(at, this.opaque, true); at += 8;
- dv.setUint32(at, this.size, true); at += 4;
- this.data.to_buffer(a, at);
- },
- buffer_size: function()
- {
- return 4 + 4 + 8 + 4 + this.data.buffer_size();
- }
-}
-
-function VDAgentMonitorsConfig(flags, width, height, depth, x, y)
-{
- this.num_mon = 1;
- this.flags = flags;
- this.width = width;
- this.height = height;
- this.depth = depth;
- this.x = x;
- this.y = y;
-}
-
-VDAgentMonitorsConfig.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.num_mon, true); at += 4;
- dv.setUint32(at, this.flags, true); at += 4;
- dv.setUint32(at, this.height, true); at += 4;
- dv.setUint32(at, this.width, true); at += 4;
- dv.setUint32(at, this.depth, true); at += 4;
- dv.setUint32(at, this.x, true); at += 4;
- dv.setUint32(at, this.y, true); at += 4;
- },
- buffer_size: function()
- {
- return 28;
- }
-}
-
-function SpiceMsgNotify(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgNotify.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- this.time_stamp = dv.getUint64(at, true); at += 8;
- this.severity = dv.getUint32(at, true); at += 4;
- this.visibility = dv.getUint32(at, true); at += 4;
- this.what = dv.getUint32(at, true); at += 4;
- this.message_len = dv.getUint32(at, true); at += 4;
- this.message = "";
- for (i = 0; i < this.message_len; i++)
- {
- var c = dv.getUint8(at, true); at++;
- this.message += String.fromCharCode(c);
- }
- },
-}
-
-function SpiceMsgcDisplayInit()
-{
- this.pixmap_cache_id = 1;
- this.glz_dictionary_id = 0;
- this.pixmap_cache_size = 10 * 1024 * 1024;
- this.glz_dictionary_window_size = 0;
-}
-
-SpiceMsgcDisplayInit.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint8(at, this.pixmap_cache_id, true); at++;
- dv.setUint64(at, this.pixmap_cache_size, true); at += 8;
- dv.setUint8(at, this.glz_dictionary_id, true); at++;
- dv.setUint32(at, this.glz_dictionary_window_size, true); at += 4;
- },
- buffer_size: function()
- {
- return 14;
- }
-}
-
-function SpiceMsgDisplayBase()
-{
-}
-
-SpiceMsgDisplayBase.prototype =
-{
- from_dv : function(dv, at, mb)
- {
- this.surface_id = dv.getUint32(at, true); at += 4;
- this.box = new SpiceRect;
- at = this.box.from_dv(dv, at, mb);
- this.clip = new SpiceClip;
- return this.clip.from_dv(dv, at, mb);
- },
-}
-
-function SpiceMsgDisplayDrawCopy(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayDrawCopy.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceMsgDisplayBase;
- at = this.base.from_dv(dv, at, a);
- this.data = new SpiceCopy;
- return this.data.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgDisplayDrawFill(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayDrawFill.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceMsgDisplayBase;
- at = this.base.from_dv(dv, at, a);
- this.data = new SpiceFill;
- return this.data.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgDisplayCopyBits(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayCopyBits.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceMsgDisplayBase;
- at = this.base.from_dv(dv, at, a);
- this.src_pos = new SpicePoint;
- return this.src_pos.from_dv(dv, at, a);
- },
-}
-
-
-function SpiceMsgSurfaceCreate(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgSurfaceCreate.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.surface = new SpiceSurface;
- return this.surface.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgSurfaceDestroy(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgSurfaceDestroy.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.surface_id = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgInputsInit(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgInputsInit.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpiceMsgInputsKeyModifiers(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgInputsKeyModifiers.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpiceMsgCursorInit(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgCursorInit.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.position = new SpicePoint16;
- at = this.position.from_dv(dv, at, mb);
- this.trail_length = dv.getUint16(at, true); at += 2;
- this.trail_frequency = dv.getUint16(at, true); at += 2;
- this.visible = dv.getUint8(at, true); at ++;
- this.cursor = new SpiceCursor;
- return this.cursor.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgPlaybackData(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgPlaybackData.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.time = dv.getUint32(at, true); at += 4;
- if (a.byteLength > at)
- {
- this.data = a.slice(at);
- at += this.data.byteLength;
- }
- return at;
- },
-}
-
-function SpiceMsgPlaybackMode(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgPlaybackMode.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.time = dv.getUint32(at, true); at += 4;
- this.mode = dv.getUint16(at, true); at += 2;
- if (a.byteLength > at)
- {
- this.data = a.slice(at);
- at += this.data.byteLength;
- }
- return at;
- },
-}
-
-function SpiceMsgPlaybackStart(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgPlaybackStart.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.channels = dv.getUint32(at, true); at += 4;
- this.format = dv.getUint16(at, true); at += 2;
- this.frequency = dv.getUint32(at, true); at += 4;
- this.time = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-
-
-function SpiceMsgCursorSet(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgCursorSet.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.position = new SpicePoint16;
- at = this.position.from_dv(dv, at, mb);
- this.visible = dv.getUint8(at, true); at ++;
- this.cursor = new SpiceCursor;
- return this.cursor.from_dv(dv, at, a);
- },
-}
-
-
-function SpiceMsgcMousePosition(sc, e)
-{
- // FIXME - figure out how to correctly compute display_id
- this.display_id = 0;
- this.buttons_state = sc.buttons_state;
- if (e)
- {
- var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
- var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
-
- this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft + scrollLeft;
- this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop + scrollTop;
- sc.mousex = this.x;
- sc.mousey = this.y;
- }
- else
- {
- this.x = this.y = this.buttons_state = 0;
- }
-}
-
-SpiceMsgcMousePosition.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.x, true); at += 4;
- dv.setUint32(at, this.y, true); at += 4;
- dv.setUint16(at, this.buttons_state, true); at += 2;
- dv.setUint8(at, this.display_id, true); at += 1;
- return at;
- },
- buffer_size: function()
- {
- return 11;
- }
-}
-
-function SpiceMsgcMouseMotion(sc, e)
-{
- // FIXME - figure out how to correctly compute display_id
- this.display_id = 0;
- this.buttons_state = sc.buttons_state;
- if (e)
- {
- this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
- this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
-
- if (sc.mousex !== undefined)
- {
- this.x -= sc.mousex;
- this.y -= sc.mousey;
- }
- sc.mousex = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
- sc.mousey = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
- }
- else
- {
- this.x = this.y = this.buttons_state = 0;
- }
-}
-
-/* Use the same functions as for MousePosition */
-SpiceMsgcMouseMotion.prototype.to_buffer = SpiceMsgcMousePosition.prototype.to_buffer;
-SpiceMsgcMouseMotion.prototype.buffer_size = SpiceMsgcMousePosition.prototype.buffer_size;
-
-function SpiceMsgcMousePress(sc, e)
-{
- if (e)
- {
- this.button = e.button + 1;
- this.buttons_state = 1 << e.button;
- sc.buttons_state = this.buttons_state;
- }
- else
- {
- this.button = SPICE_MOUSE_BUTTON_LEFT;
- this.buttons_state = SPICE_MOUSE_BUTTON_MASK_LEFT;
- }
-}
-
-SpiceMsgcMousePress.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint8(at, this.button, true); at ++;
- dv.setUint16(at, this.buttons_state, true); at += 2;
- return at;
- },
- buffer_size: function()
- {
- return 3;
- }
-}
-
-function SpiceMsgcMouseRelease(sc, e)
-{
- if (e)
- {
- this.button = e.button + 1;
- this.buttons_state = 0;
- sc.buttons_state = this.buttons_state;
- }
- else
- {
- this.button = SPICE_MOUSE_BUTTON_LEFT;
- this.buttons_state = 0;
- }
-}
-
-/* Use the same functions as for MousePress */
-SpiceMsgcMouseRelease.prototype.to_buffer = SpiceMsgcMousePress.prototype.to_buffer;
-SpiceMsgcMouseRelease.prototype.buffer_size = SpiceMsgcMousePress.prototype.buffer_size;
-
-
-function SpiceMsgcKeyDown(e)
-{
- if (e)
- {
- this.code = keycode_to_start_scan(e.keyCode);
- }
- else
- {
- this.code = 0;
- }
-}
-
-SpiceMsgcKeyDown.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.code, true); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMsgcKeyUp(e)
-{
- if (e)
- {
- this.code = keycode_to_end_scan(e.keyCode);
- }
- else
- {
- this.code = 0;
- }
-}
-
-/* Use the same functions as for KeyDown */
-SpiceMsgcKeyUp.prototype.to_buffer = SpiceMsgcKeyDown.prototype.to_buffer;
-SpiceMsgcKeyUp.prototype.buffer_size = SpiceMsgcKeyDown.prototype.buffer_size;
-
-function SpiceMsgDisplayStreamCreate(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamCreate.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.surface_id = dv.getUint32(at, true); at += 4;
- this.id = dv.getUint32(at, true); at += 4;
- this.flags = dv.getUint8(at, true); at += 1;
- this.codec_type = dv.getUint8(at, true); at += 1;
- this.stamp = dv.getUint64(at, true); at += 8;
- this.stream_width = dv.getUint32(at, true); at += 4;
- this.stream_height = dv.getUint32(at, true); at += 4;
- this.src_width = dv.getUint32(at, true); at += 4;
- this.src_height = dv.getUint32(at, true); at += 4;
-
- this.dest = new SpiceRect;
- at = this.dest.from_dv(dv, at, a);
- this.clip = new SpiceClip;
- this.clip.from_dv(dv, at, a);
- },
-}
-
-function SpiceStreamDataHeader(a, at)
-{
-}
-
-SpiceStreamDataHeader.prototype =
-{
- from_dv : function(dv, at, mb)
- {
- this.id = dv.getUint32(at, true); at += 4;
- this.multi_media_time = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-function SpiceMsgDisplayStreamData(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamData.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceStreamDataHeader;
- at = this.base.from_dv(dv, at, a);
- this.data_size = dv.getUint32(at, true); at += 4;
- this.data = dv.u8.subarray(at, at + this.data_size);
- },
-}
-
-function SpiceMsgDisplayStreamClip(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamClip.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.id = dv.getUint32(at, true); at += 4;
- this.clip = new SpiceClip;
- this.clip.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgDisplayStreamDestroy(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamDestroy.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.id = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgDisplayInvalList(a, at)
-{
- this.count = 0;
- this.resources = [];
- this.from_buffer(a,at);
-}
-
-SpiceMsgDisplayInvalList.prototype =
-{
- from_buffer: function (a, at)
- {
- var i;
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.count = dv.getUint16(at, true); at += 2;
- for (i = 0; i < this.count; i++)
- {
- this.resources[i] = {};
- this.resources[i].type = dv.getUint8(at, true); at++;
- this.resources[i].id = dv.getUint64(at, true); at += 8;
- }
- },
-}
diff --git a/plugins/kimchi/ui/spice-html5/spicetype.js b/plugins/kimchi/ui/spice-html5/spicetype.js
deleted file mode 100644
index 951b277..0000000
--- a/plugins/kimchi/ui/spice-html5/spicetype.js
+++ /dev/null
@@ -1,473 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** Spice types
-** This file contains classes for common spice types.
-** Generally, they are used as helpers in reading and writing messages
-** to and from the server.
-**--------------------------------------------------------------------------*/
-
-function SpiceChannelId()
-{
-}
-SpiceChannelId.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.type = dv.getUint8(at, true); at ++;
- this.id = dv.getUint8(at, true); at ++;
- return at;
- },
-}
-
-function SpiceRect()
-{
-}
-
-SpiceRect.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.top = dv.getUint32(at, true); at += 4;
- this.left = dv.getUint32(at, true); at += 4;
- this.bottom = dv.getUint32(at, true); at += 4;
- this.right = dv.getUint32(at, true); at += 4;
- return at;
- },
- is_same_size : function(r)
- {
- if ((this.bottom - this.top) == (r.bottom - r.top) &&
- (this.right - this.left) == (r.right - r.left) )
- return true;
-
- return false;
- },
-}
-
-function SpiceClipRects()
-{
-}
-
-SpiceClipRects.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var i;
- this.num_rects = dv.getUint32(at, true); at += 4;
- if (this.num_rects > 0)
- this.rects = [];
- for (i = 0; i < this.num_rects; i++)
- {
- this.rects[i] = new SpiceRect();
- at = this.rects[i].from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-function SpiceClip()
-{
-}
-
-SpiceClip.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.type = dv.getUint8(at, true); at ++;
- if (this.type == SPICE_CLIP_TYPE_RECTS)
- {
- this.rects = new SpiceClipRects();
- at = this.rects.from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-function SpiceImageDescriptor()
-{
-}
-
-SpiceImageDescriptor.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.id = dv.getUint64(at, true); at += 8;
- this.type = dv.getUint8(at, true); at ++;
- this.flags = dv.getUint8(at, true); at ++;
- this.width = dv.getUint32(at, true); at += 4;
- this.height= dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-function SpicePalette()
-{
-}
-
-SpicePalette.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var i;
- this.unique = dv.getUint64(at, true); at += 8;
- this.num_ents = dv.getUint16(at, true); at += 2;
- this.ents = [];
- for (i = 0; i < this.num_ents; i++)
- {
- this.ents[i] = dv.getUint32(at, true); at += 4;
- }
- return at;
- },
-}
-
-function SpiceBitmap()
-{
-}
-
-SpiceBitmap.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.format = dv.getUint8(at, true); at++;
- this.flags = dv.getUint8(at, true); at++;
- this.x = dv.getUint32(at, true); at += 4;
- this.y = dv.getUint32(at, true); at += 4;
- this.stride = dv.getUint32(at, true); at += 4;
- if (this.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)
- {
- this.palette_id = dv.getUint64(at, true); at += 8;
- }
- else
- {
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- this.palette = null;
- else
- {
- this.palette = new SpicePalette;
- this.palette.from_dv(dv, offset, mb);
- }
- }
- // FIXME - should probably constrain this to the offset
- // of palette, if non zero
- this.data = mb.slice(at);
- at += this.data.byteLength;
- return at;
- },
-}
-
-function SpiceImage()
-{
-}
-
-SpiceImage.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.descriptor = new SpiceImageDescriptor;
- at = this.descriptor.from_dv(dv, at, mb);
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
- {
- this.lz_rgb = new Object();
- this.lz_rgb.length = dv.getUint32(at, true); at += 4;
- var initial_at = at;
- this.lz_rgb.magic = "";
- for (var i = 3; i >= 0; i--)
- this.lz_rgb.magic += String.fromCharCode(dv.getUint8(at + i));
- at += 4;
-
- // NOTE: The endian change is *correct*
- this.lz_rgb.version = dv.getUint32(at); at += 4;
- this.lz_rgb.type = dv.getUint32(at); at += 4;
- this.lz_rgb.width = dv.getUint32(at); at += 4;
- this.lz_rgb.height = dv.getUint32(at); at += 4;
- this.lz_rgb.stride = dv.getUint32(at); at += 4;
- this.lz_rgb.top_down = dv.getUint32(at); at += 4;
-
- var header_size = at - initial_at;
-
- this.lz_rgb.data = mb.slice(at, this.lz_rgb.length + at - header_size);
- at += this.lz_rgb.data.byteLength;
-
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
- {
- this.bitmap = new SpiceBitmap;
- at = this.bitmap.from_dv(dv, at, mb);
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
- {
- this.surface_id = dv.getUint32(at, true); at += 4;
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
- {
- this.jpeg = new Object;
- this.jpeg.data_size = dv.getUint32(at, true); at += 4;
- this.jpeg.data = mb.slice(at);
- at += this.jpeg.data.byteLength;
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
- {
- this.jpeg_alpha = new Object;
- this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1;
- this.jpeg_alpha.jpeg_size = dv.getUint32(at, true); at += 4;
- this.jpeg_alpha.data_size = dv.getUint32(at, true); at += 4;
- this.jpeg_alpha.data = mb.slice(at, this.jpeg_alpha.jpeg_size + at);
- at += this.jpeg_alpha.data.byteLength;
- // Alpha channel is an LZ image
- this.jpeg_alpha.alpha = new Object();
- this.jpeg_alpha.alpha.length = this.jpeg_alpha.data_size - this.jpeg_alpha.jpeg_size;
- var initial_at = at;
- this.jpeg_alpha.alpha.magic = "";
- for (var i = 3; i >= 0; i--)
- this.jpeg_alpha.alpha.magic += String.fromCharCode(dv.getUint8(at + i));
- at += 4;
-
- // NOTE: The endian change is *correct*
- this.jpeg_alpha.alpha.version = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.type = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.width = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.height = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.stride = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.top_down = dv.getUint32(at); at += 4;
-
- var header_size = at - initial_at;
-
- this.jpeg_alpha.alpha.data = mb.slice(at, this.jpeg_alpha.alpha.length + at - header_size);
- at += this.jpeg_alpha.alpha.data.byteLength;
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
- {
- this.quic = new SpiceQuic;
- at = this.quic.from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-
-function SpiceQMask()
-{
-}
-
-SpiceQMask.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.flags = dv.getUint8(at, true); at++;
- this.pos = new SpicePoint;
- at = this.pos.from_dv(dv, at, mb);
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- {
- this.bitmap = null;
- return at;
- }
-
- this.bitmap = new SpiceImage;
- return this.bitmap.from_dv(dv, offset, mb);
- },
-}
-
-
-function SpicePattern()
-{
-}
-
-SpicePattern.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- {
- this.pat = null;
- }
- else
- {
- this.pat = new SpiceImage;
- this.pat.from_dv(dv, offset, mb);
- }
-
- this.pos = new SpicePoint;
- return this.pos.from_dv(dv, at, mb);
- }
-}
-
-function SpiceBrush()
-{
-}
-
-SpiceBrush.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.type = dv.getUint8(at, true); at ++;
- if (this.type == SPICE_BRUSH_TYPE_SOLID)
- {
- this.color = dv.getUint32(at, true); at += 4;
- }
- else if (this.type == SPICE_BRUSH_TYPE_PATTERN)
- {
- this.pattern = new SpicePattern;
- at = this.pattern.from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-function SpiceFill()
-{
-}
-
-SpiceFill.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.brush = new SpiceBrush;
- at = this.brush.from_dv(dv, at, mb);
- this.rop_descriptor = dv.getUint16(at, true); at += 2;
- this.mask = new SpiceQMask;
- return this.mask.from_dv(dv, at, mb);
- },
-}
-
-
-function SpiceCopy()
-{
-}
-
-SpiceCopy.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- {
- this.src_bitmap = null;
- }
- else
- {
- this.src_bitmap = new SpiceImage;
- this.src_bitmap.from_dv(dv, offset, mb);
- }
- this.src_area = new SpiceRect;
- at = this.src_area.from_dv(dv, at, mb);
- this.rop_descriptor = dv.getUint16(at, true); at += 2;
- this.scale_mode = dv.getUint8(at, true); at ++;
- this.mask = new SpiceQMask;
- return this.mask.from_dv(dv, at, mb);
- },
-}
-
-function SpicePoint16()
-{
-}
-
-SpicePoint16.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.x = dv.getUint16(at, true); at += 2;
- this.y = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpicePoint()
-{
-}
-
-SpicePoint.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.x = dv.getUint32(at, true); at += 4;
- this.y = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-function SpiceCursorHeader()
-{
-}
-
-SpiceCursorHeader.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.unique = dv.getUint64(at, true); at += 8;
- this.type = dv.getUint8(at, true); at ++;
- this.width = dv.getUint16(at, true); at += 2;
- this.height = dv.getUint16(at, true); at += 2;
- this.hot_spot_x = dv.getUint16(at, true); at += 2;
- this.hot_spot_y = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpiceCursor()
-{
-}
-
-SpiceCursor.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.flags = dv.getUint16(at, true); at += 2;
- if (this.flags & SPICE_CURSOR_FLAGS_NONE)
- this.header = null;
- else
- {
- this.header = new SpiceCursorHeader;
- at = this.header.from_dv(dv, at, mb);
- this.data = mb.slice(at);
- at += this.data.byteLength;
- }
- return at;
- },
-}
-
-function SpiceSurface()
-{
-}
-
-SpiceSurface.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.surface_id = dv.getUint32(at, true); at += 4;
- this.width = dv.getUint32(at, true); at += 4;
- this.height = dv.getUint32(at, true); at += 4;
- this.format = dv.getUint32(at, true); at += 4;
- this.flags = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-/* FIXME - SpiceImage types lz_plt, jpeg, zlib_glz, and jpeg_alpha are
- completely unimplemented */
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am b/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
deleted file mode 100644
index 474478d..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-thirdpartydir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/thirdparty
-
-dist_thirdparty_DATA = $(wildcard *.js) $(NULL)
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js b/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
deleted file mode 100644
index 9b9476e..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
+++ /dev/null
@@ -1,589 +0,0 @@
-// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// Basic JavaScript BN library - subset useful for RSA encryption.
-
-// Bits per digit
-var dbits;
-
-// JavaScript engine analysis
-var canary = 0xdeadbeefcafe;
-var j_lm = ((canary&0xffffff)==0xefcafe);
-
-// (public) Constructor
-function BigInteger(a,b,c) {
- if(a != null)
- if("number" == typeof a) this.fromNumber(a,b,c);
- else if(b == null && "string" != typeof a) this.fromString(a,256);
- else this.fromString(a,b);
-}
-
-// return new, unset BigInteger
-function nbi() { return new BigInteger(null); }
-
-// am: Compute w_j += (x*this_i), propagate carries,
-// c is initial carry, returns final carry.
-// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
-// We need to select the fastest one that works in this environment.
-
-// am1: use a single mult and divide to get the high bits,
-// max digit bits should be 26 because
-// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
-function am1(i,x,w,j,c,n) {
- while(--n >= 0) {
- var v = x*this[i++]+w[j]+c;
- c = Math.floor(v/0x4000000);
- w[j++] = v&0x3ffffff;
- }
- return c;
-}
-// am2 avoids a big mult-and-extract completely.
-// Max digit bits should be <= 30 because we do bitwise ops
-// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
-function am2(i,x,w,j,c,n) {
- var xl = x&0x7fff, xh = x>>15;
- while(--n >= 0) {
- var l = this[i]&0x7fff;
- var h = this[i++]>>15;
- var m = xh*l+h*xl;
- l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
- c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
- w[j++] = l&0x3fffffff;
- }
- return c;
-}
-// Alternately, set max digit bits to 28 since some
-// browsers slow down when dealing with 32-bit numbers.
-function am3(i,x,w,j,c,n) {
- var xl = x&0x3fff, xh = x>>14;
- while(--n >= 0) {
- var l = this[i]&0x3fff;
- var h = this[i++]>>14;
- var m = xh*l+h*xl;
- l = xl*l+((m&0x3fff)<<14)+w[j]+c;
- c = (l>>28)+(m>>14)+xh*h;
- w[j++] = l&0xfffffff;
- }
- return c;
-}
-if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
- BigInteger.prototype.am = am2;
- dbits = 30;
-}
-else if(j_lm && (navigator.appName != "Netscape")) {
- BigInteger.prototype.am = am1;
- dbits = 26;
-}
-else { // Mozilla/Netscape seems to prefer am3
- BigInteger.prototype.am = am3;
- dbits = 28;
-}
-
-BigInteger.prototype.DB = dbits;
-BigInteger.prototype.DM = ((1<<dbits)-1);
-BigInteger.prototype.DV = (1<<dbits);
-
-var BI_FP = 52;
-BigInteger.prototype.FV = Math.pow(2,BI_FP);
-BigInteger.prototype.F1 = BI_FP-dbits;
-BigInteger.prototype.F2 = 2*dbits-BI_FP;
-
-// Digit conversions
-var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
-var BI_RC = new Array();
-var rr,vv;
-rr = "0".charCodeAt(0);
-for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
-rr = "a".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-rr = "A".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-
-function int2char(n) { return BI_RM.charAt(n); }
-function intAt(s,i) {
- var c = BI_RC[s.charCodeAt(i)];
- return (c==null)?-1:c;
-}
-
-// (protected) copy this to r
-function bnpCopyTo(r) {
- for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
- r.t = this.t;
- r.s = this.s;
-}
-
-// (protected) set from integer value x, -DV <= x < DV
-function bnpFromInt(x) {
- this.t = 1;
- this.s = (x<0)?-1:0;
- if(x > 0) this[0] = x;
- else if(x < -1) this[0] = x+DV;
- else this.t = 0;
-}
-
-// return bigint initialized to value
-function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
-
-// (protected) set from string and radix
-function bnpFromString(s,b) {
- var k;
- if(b == 16) k = 4;
- else if(b == 8) k = 3;
- else if(b == 256) k = 8; // byte array
- else if(b == 2) k = 1;
- else if(b == 32) k = 5;
- else if(b == 4) k = 2;
- else { this.fromRadix(s,b); return; }
- this.t = 0;
- this.s = 0;
- var i = s.length, mi = false, sh = 0;
- while(--i >= 0) {
- var x = (k==8)?s[i]&0xff:intAt(s,i);
- if(x < 0) {
- if(s.charAt(i) == "-") mi = true;
- continue;
- }
- mi = false;
- if(sh == 0)
- this[this.t++] = x;
- else if(sh+k > this.DB) {
- this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
- this[this.t++] = (x>>(this.DB-sh));
- }
- else
- this[this.t-1] |= x<<sh;
- sh += k;
- if(sh >= this.DB) sh -= this.DB;
- }
- if(k == 8 && (s[0]&0x80) != 0) {
- this.s = -1;
- if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
- }
- this.clamp();
- if(mi) BigInteger.ZERO.subTo(this,this);
-}
-
-// (protected) clamp off excess high words
-function bnpClamp() {
- var c = this.s&this.DM;
- while(this.t > 0 && this[this.t-1] == c) --this.t;
-}
-
-// (public) return string representation in given radix
-function bnToString(b) {
- if(this.s < 0) return "-"+this.negate().toString(b);
- var k;
- if(b == 16) k = 4;
- else if(b == 8) k = 3;
- else if(b == 2) k = 1;
- else if(b == 32) k = 5;
- else if(b == 4) k = 2;
- else return this.toRadix(b);
- var km = (1<<k)-1, d, m = false, r = "", i = this.t;
- var p = this.DB-(i*this.DB)%k;
- if(i-- > 0) {
- if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
- while(i >= 0) {
- if(p < k) {
- d = (this[i]&((1<<p)-1))<<(k-p);
- d |= this[--i]>>(p+=this.DB-k);
- }
- else {
- d = (this[i]>>(p-=k))&km;
- if(p <= 0) { p += this.DB; --i; }
- }
- if(d > 0) m = true;
- if(m) r += int2char(d);
- }
- }
- return m?r:"0";
-}
-
-// (public) -this
-function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
-
-// (public) |this|
-function bnAbs() { return (this.s<0)?this.negate():this; }
-
-// (public) return + if this > a, - if this < a, 0 if equal
-function bnCompareTo(a) {
- var r = this.s-a.s;
- if(r != 0) return r;
- var i = this.t;
- r = i-a.t;
- if(r != 0) return r;
- while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
- return 0;
-}
-
-// returns bit length of the integer x
-function nbits(x) {
- var r = 1, t;
- if((t=x>>>16) != 0) { x = t; r += 16; }
- if((t=x>>8) != 0) { x = t; r += 8; }
- if((t=x>>4) != 0) { x = t; r += 4; }
- if((t=x>>2) != 0) { x = t; r += 2; }
- if((t=x>>1) != 0) { x = t; r += 1; }
- return r;
-}
-
-// (public) return the number of bits in "this"
-function bnBitLength() {
- if(this.t <= 0) return 0;
- return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
-}
-
-// (protected) r = this << n*DB
-function bnpDLShiftTo(n,r) {
- var i;
- for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
- for(i = n-1; i >= 0; --i) r[i] = 0;
- r.t = this.t+n;
- r.s = this.s;
-}
-
-// (protected) r = this >> n*DB
-function bnpDRShiftTo(n,r) {
- for(var i = n; i < this.t; ++i) r[i-n] = this[i];
- r.t = Math.max(this.t-n,0);
- r.s = this.s;
-}
-
-// (protected) r = this << n
-function bnpLShiftTo(n,r) {
- var bs = n%this.DB;
- var cbs = this.DB-bs;
- var bm = (1<<cbs)-1;
- var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
- for(i = this.t-1; i >= 0; --i) {
- r[i+ds+1] = (this[i]>>cbs)|c;
- c = (this[i]&bm)<<bs;
- }
- for(i = ds-1; i >= 0; --i) r[i] = 0;
- r[ds] = c;
- r.t = this.t+ds+1;
- r.s = this.s;
- r.clamp();
-}
-
-// (protected) r = this >> n
-function bnpRShiftTo(n,r) {
- r.s = this.s;
- var ds = Math.floor(n/this.DB);
- if(ds >= this.t) { r.t = 0; return; }
- var bs = n%this.DB;
- var cbs = this.DB-bs;
- var bm = (1<<bs)-1;
- r[0] = this[ds]>>bs;
- for(var i = ds+1; i < this.t; ++i) {
- r[i-ds-1] |= (this[i]&bm)<<cbs;
- r[i-ds] = this[i]>>bs;
- }
- if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
- r.t = this.t-ds;
- r.clamp();
-}
-
-// (protected) r = this - a
-function bnpSubTo(a,r) {
- var i = 0, c = 0, m = Math.min(a.t,this.t);
- while(i < m) {
- c += this[i]-a[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- if(a.t < this.t) {
- c -= a.s;
- while(i < this.t) {
- c += this[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c += this.s;
- }
- else {
- c += this.s;
- while(i < a.t) {
- c -= a[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c -= a.s;
- }
- r.s = (c<0)?-1:0;
- if(c < -1) r[i++] = this.DV+c;
- else if(c > 0) r[i++] = c;
- r.t = i;
- r.clamp();
-}
-
-// (protected) r = this * a, r != this,a (HAC 14.12)
-// "this" should be the larger one if appropriate.
-function bnpMultiplyTo(a,r) {
- var x = this.abs(), y = a.abs();
- var i = x.t;
- r.t = i+y.t;
- while(--i >= 0) r[i] = 0;
- for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
- r.s = 0;
- r.clamp();
- if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
-}
-
-// (protected) r = this^2, r != this (HAC 14.16)
-function bnpSquareTo(r) {
- var x = this.abs();
- var i = r.t = 2*x.t;
- while(--i >= 0) r[i] = 0;
- for(i = 0; i < x.t-1; ++i) {
- var c = x.am(i,x[i],r,2*i,0,1);
- if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
- r[i+x.t] -= x.DV;
- r[i+x.t+1] = 1;
- }
- }
- if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
- r.s = 0;
- r.clamp();
-}
-
-// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
-// r != q, this != m. q or r may be null.
-function bnpDivRemTo(m,q,r) {
- var pm = m.abs();
- if(pm.t <= 0) return;
- var pt = this.abs();
- if(pt.t < pm.t) {
- if(q != null) q.fromInt(0);
- if(r != null) this.copyTo(r);
- return;
- }
- if(r == null) r = nbi();
- var y = nbi(), ts = this.s, ms = m.s;
- var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
- if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
- else { pm.copyTo(y); pt.copyTo(r); }
- var ys = y.t;
- var y0 = y[ys-1];
- if(y0 == 0) return;
- var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
- var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
- var i = r.t, j = i-ys, t = (q==null)?nbi():q;
- y.dlShiftTo(j,t);
- if(r.compareTo(t) >= 0) {
- r[r.t++] = 1;
- r.subTo(t,r);
- }
- BigInteger.ONE.dlShiftTo(ys,t);
- t.subTo(y,y); // "negative" y so we can replace sub with am later
- while(y.t < ys) y[y.t++] = 0;
- while(--j >= 0) {
- // Estimate quotient digit
- var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
- if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
- y.dlShiftTo(j,t);
- r.subTo(t,r);
- while(r[i] < --qd) r.subTo(t,r);
- }
- }
- if(q != null) {
- r.drShiftTo(ys,q);
- if(ts != ms) BigInteger.ZERO.subTo(q,q);
- }
- r.t = ys;
- r.clamp();
- if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
- if(ts < 0) BigInteger.ZERO.subTo(r,r);
-}
-
-// (public) this mod a
-function bnMod(a) {
- var r = nbi();
- this.abs().divRemTo(a,null,r);
- if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
- return r;
-}
-
-// Modular reduction using "classic" algorithm
-function Classic(m) { this.m = m; }
-function cConvert(x) {
- if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
- else return x;
-}
-function cRevert(x) { return x; }
-function cReduce(x) { x.divRemTo(this.m,null,x); }
-function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-Classic.prototype.convert = cConvert;
-Classic.prototype.revert = cRevert;
-Classic.prototype.reduce = cReduce;
-Classic.prototype.mulTo = cMulTo;
-Classic.prototype.sqrTo = cSqrTo;
-
-// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
-// justification:
-// xy == 1 (mod m)
-// xy = 1+km
-// xy(2-xy) = (1+km)(1-km)
-// x[y(2-xy)] = 1-k^2m^2
-// x[y(2-xy)] == 1 (mod m^2)
-// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
-// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
-// JS multiply "overflows" differently from C/C++, so care is needed here.
-function bnpInvDigit() {
- if(this.t < 1) return 0;
- var x = this[0];
- if((x&1) == 0) return 0;
- var y = x&3; // y == 1/x mod 2^2
- y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
- y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
- y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
- // last step - calculate inverse mod DV directly;
- // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
- y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
- // we really want the negative inverse, and -DV < y < DV
- return (y>0)?this.DV-y:-y;
-}
-
-// Montgomery reduction
-function Montgomery(m) {
- this.m = m;
- this.mp = m.invDigit();
- this.mpl = this.mp&0x7fff;
- this.mph = this.mp>>15;
- this.um = (1<<(m.DB-15))-1;
- this.mt2 = 2*m.t;
-}
-
-// xR mod m
-function montConvert(x) {
- var r = nbi();
- x.abs().dlShiftTo(this.m.t,r);
- r.divRemTo(this.m,null,r);
- if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
- return r;
-}
-
-// x/R mod m
-function montRevert(x) {
- var r = nbi();
- x.copyTo(r);
- this.reduce(r);
- return r;
-}
-
-// x = x/R mod m (HAC 14.32)
-function montReduce(x) {
- while(x.t <= this.mt2) // pad x so am has enough room later
- x[x.t++] = 0;
- for(var i = 0; i < this.m.t; ++i) {
- // faster way of calculating u0 = x[i]*mp mod DV
- var j = x[i]&0x7fff;
- var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
- // use am to combine the multiply-shift-add into one call
- j = i+this.m.t;
- x[j] += this.m.am(0,u0,x,i,0,this.m.t);
- // propagate carry
- while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
- }
- x.clamp();
- x.drShiftTo(this.m.t,x);
- if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
-}
-
-// r = "x^2/R mod m"; x != r
-function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-// r = "xy/R mod m"; x,y != r
-function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-
-Montgomery.prototype.convert = montConvert;
-Montgomery.prototype.revert = montRevert;
-Montgomery.prototype.reduce = montReduce;
-Montgomery.prototype.mulTo = montMulTo;
-Montgomery.prototype.sqrTo = montSqrTo;
-
-// (protected) true iff this is even
-function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
-
-// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
-function bnpExp(e,z) {
- if(e > 0xffffffff || e < 1) return BigInteger.ONE;
- var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
- g.copyTo(r);
- while(--i >= 0) {
- z.sqrTo(r,r2);
- if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
- else { var t = r; r = r2; r2 = t; }
- }
- return z.revert(r);
-}
-
-// (public) this^e % m, 0 <= e < 2^32
-function bnModPowInt(e,m) {
- var z;
- if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
- return this.exp(e,z);
-}
-
-// protected
-BigInteger.prototype.copyTo = bnpCopyTo;
-BigInteger.prototype.fromInt = bnpFromInt;
-BigInteger.prototype.fromString = bnpFromString;
-BigInteger.prototype.clamp = bnpClamp;
-BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
-BigInteger.prototype.drShiftTo = bnpDRShiftTo;
-BigInteger.prototype.lShiftTo = bnpLShiftTo;
-BigInteger.prototype.rShiftTo = bnpRShiftTo;
-BigInteger.prototype.subTo = bnpSubTo;
-BigInteger.prototype.multiplyTo = bnpMultiplyTo;
-BigInteger.prototype.squareTo = bnpSquareTo;
-BigInteger.prototype.divRemTo = bnpDivRemTo;
-BigInteger.prototype.invDigit = bnpInvDigit;
-BigInteger.prototype.isEven = bnpIsEven;
-BigInteger.prototype.exp = bnpExp;
-
-// public
-BigInteger.prototype.toString = bnToString;
-BigInteger.prototype.negate = bnNegate;
-BigInteger.prototype.abs = bnAbs;
-BigInteger.prototype.compareTo = bnCompareTo;
-BigInteger.prototype.bitLength = bnBitLength;
-BigInteger.prototype.mod = bnMod;
-BigInteger.prototype.modPowInt = bnModPowInt;
-
-// "constants"
-BigInteger.ZERO = nbv(0);
-BigInteger.ONE = nbv(1);
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js b/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
deleted file mode 100644
index 4715372..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// prng4.js - uses Arcfour as a PRNG
-
-function Arcfour() {
- this.i = 0;
- this.j = 0;
- this.S = new Array();
-}
-
-// Initialize arcfour context from key, an array of ints, each from [0..255]
-function ARC4init(key) {
- var i, j, t;
- for(i = 0; i < 256; ++i)
- this.S[i] = i;
- j = 0;
- for(i = 0; i < 256; ++i) {
- j = (j + this.S[i] + key[i % key.length]) & 255;
- t = this.S[i];
- this.S[i] = this.S[j];
- this.S[j] = t;
- }
- this.i = 0;
- this.j = 0;
-}
-
-function ARC4next() {
- var t;
- this.i = (this.i + 1) & 255;
- this.j = (this.j + this.S[this.i]) & 255;
- t = this.S[this.i];
- this.S[this.i] = this.S[this.j];
- this.S[this.j] = t;
- return this.S[(t + this.S[this.i]) & 255];
-}
-
-Arcfour.prototype.init = ARC4init;
-Arcfour.prototype.next = ARC4next;
-
-// Plug in your RNG constructor here
-function prng_newstate() {
- return new Arcfour();
-}
-
-// Pool size must be a multiple of 4 and greater than 32.
-// An array of bytes the size of the pool will be passed to init()
-var rng_psize = 256;
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/rng.js b/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
deleted file mode 100644
index 829a23c..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
+++ /dev/null
@@ -1,102 +0,0 @@
-// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// Random number generator - requires a PRNG backend, e.g. prng4.js
-
-// For best results, put code like
-// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
-// in your main HTML document.
-
-var rng_state;
-var rng_pool;
-var rng_pptr;
-
-// Mix in a 32-bit integer into the pool
-function rng_seed_int(x) {
- rng_pool[rng_pptr++] ^= x & 255;
- rng_pool[rng_pptr++] ^= (x >> 8) & 255;
- rng_pool[rng_pptr++] ^= (x >> 16) & 255;
- rng_pool[rng_pptr++] ^= (x >> 24) & 255;
- if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
-}
-
-// Mix in the current time (w/milliseconds) into the pool
-function rng_seed_time() {
- rng_seed_int(new Date().getTime());
-}
-
-// Initialize the pool with junk if needed.
-if(rng_pool == null) {
- rng_pool = new Array();
- rng_pptr = 0;
- var t;
- if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
- // Extract entropy (256 bits) from NS4 RNG if available
- var z = window.crypto.random(32);
- for(t = 0; t < z.length; ++t)
- rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
- }
- while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
- t = Math.floor(65536 * Math.random());
- rng_pool[rng_pptr++] = t >>> 8;
- rng_pool[rng_pptr++] = t & 255;
- }
- rng_pptr = 0;
- rng_seed_time();
- //rng_seed_int(window.screenX);
- //rng_seed_int(window.screenY);
-}
-
-function rng_get_byte() {
- if(rng_state == null) {
- rng_seed_time();
- rng_state = prng_newstate();
- rng_state.init(rng_pool);
- for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
- rng_pool[rng_pptr] = 0;
- rng_pptr = 0;
- //rng_pool = null;
- }
- // TODO: allow reseeding after first request
- return rng_state.next();
-}
-
-function rng_get_bytes(ba) {
- var i;
- for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
-}
-
-function SecureRandom() {}
-
-SecureRandom.prototype.nextBytes = rng_get_bytes;
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js b/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
deleted file mode 100644
index 1bbf249..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
+++ /dev/null
@@ -1,146 +0,0 @@
-// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// Depends on jsbn.js and rng.js
-
-// Version 1.1: support utf-8 encoding in pkcs1pad2
-
-// convert a (hex) string to a bignum object
-function parseBigInt(str,r) {
- return new BigInteger(str,r);
-}
-
-function linebrk(s,n) {
- var ret = "";
- var i = 0;
- while(i + n < s.length) {
- ret += s.substring(i,i+n) + "\n";
- i += n;
- }
- return ret + s.substring(i,s.length);
-}
-
-function byte2Hex(b) {
- if(b < 0x10)
- return "0" + b.toString(16);
- else
- return b.toString(16);
-}
-
-// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
-function pkcs1pad2(s,n) {
- if(n < s.length + 11) { // TODO: fix for utf-8
- alert("Message too long for RSA");
- return null;
- }
- var ba = new Array();
- var i = s.length - 1;
- while(i >= 0 && n > 0) {
- var c = s.charCodeAt(i--);
- if(c < 128) { // encode using utf-8
- ba[--n] = c;
- }
- else if((c > 127) && (c < 2048)) {
- ba[--n] = (c & 63) | 128;
- ba[--n] = (c >> 6) | 192;
- }
- else {
- ba[--n] = (c & 63) | 128;
- ba[--n] = ((c >> 6) & 63) | 128;
- ba[--n] = (c >> 12) | 224;
- }
- }
- ba[--n] = 0;
- var rng = new SecureRandom();
- var x = new Array();
- while(n > 2) { // random non-zero pad
- x[0] = 0;
- while(x[0] == 0) rng.nextBytes(x);
- ba[--n] = x[0];
- }
- ba[--n] = 2;
- ba[--n] = 0;
- return new BigInteger(ba);
-}
-
-// "empty" RSA key constructor
-function RSAKey() {
- this.n = null;
- this.e = 0;
- this.d = null;
- this.p = null;
- this.q = null;
- this.dmp1 = null;
- this.dmq1 = null;
- this.coeff = null;
-}
-
-// Set the public key fields N and e from hex strings
-function RSASetPublic(N,E) {
- if(N != null && E != null && N.length > 0 && E.length > 0) {
- this.n = parseBigInt(N,16);
- this.e = parseInt(E,16);
- }
- else
- alert("Invalid RSA public key");
-}
-
-// Perform raw public operation on "x": return x^e (mod n)
-function RSADoPublic(x) {
- return x.modPowInt(this.e, this.n);
-}
-
-// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
-function RSAEncrypt(text) {
- var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
- if(m == null) return null;
- var c = this.doPublic(m);
- if(c == null) return null;
- var h = c.toString(16);
- if((h.length & 1) == 0) return h; else return "0" + h;
-}
-
-// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
-//function RSAEncryptB64(text) {
-// var h = this.encrypt(text);
-// if(h) return hex2b64(h); else return null;
-//}
-
-// protected
-RSAKey.prototype.doPublic = RSADoPublic;
-
-// public
-RSAKey.prototype.setPublic = RSASetPublic;
-RSAKey.prototype.encrypt = RSAEncrypt;
-//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js b/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
deleted file mode 100644
index 8118cb4..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS 180-1
- * Version 2.2 Copyright Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
- /* Downloaded 6/1/2012 from the above address by Jeremy White.
- License reproduce here for completeness:
-
-Copyright (c) 1998 - 2009, Paul Johnston & Contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
-
-Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
-var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
-function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
-function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
-function hex_hmac_sha1(k, d)
- { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha1(k, d)
- { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha1(k, d, e)
- { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha1_vm_test()
-{
- return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
-}
-
-/*
- * Calculate the SHA1 of a raw string
- */
-function rstr_sha1(s)
-{
- return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-SHA1 of a key and some data (raw strings)
- */
-function rstr_hmac_sha1(key, data)
-{
- var bkey = rstr2binb(key);
- if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
-
- var ipad = Array(16), opad = Array(16);
- for(var i = 0; i < 16; i++)
- {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
- return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
- try { hexcase } catch(e) { hexcase=0; }
- var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var output = "";
- var x;
- for(var i = 0; i < input.length; i++)
- {
- x = input.charCodeAt(i);
- output += hex_tab.charAt((x >>> 4) & 0x0F)
- + hex_tab.charAt( x & 0x0F);
- }
- return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
- try { b64pad } catch(e) { b64pad=''; }
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var output = "";
- var len = input.length;
- for(var i = 0; i < len; i += 3)
- {
- var triplet = (input.charCodeAt(i) << 16)
- | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
- | (i + 2 < len ? input.charCodeAt(i+2) : 0);
- for(var j = 0; j < 4; j++)
- {
- if(i * 8 + j * 6 > input.length * 8) output += b64pad;
- else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
- }
- }
- return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
- var divisor = encoding.length;
- var remainders = Array();
- var i, q, x, quotient;
-
- /* Convert to an array of 16-bit big-endian values, forming the dividend */
- var dividend = Array(Math.ceil(input.length / 2));
- for(i = 0; i < dividend.length; i++)
- {
- dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
- }
-
- /*
- * Repeatedly perform a long division. The binary array forms the dividend,
- * the length of the encoding is the divisor. Once computed, the quotient
- * forms the dividend for the next step. We stop when the dividend is zero.
- * All remainders are stored for later use.
- */
- while(dividend.length > 0)
- {
- quotient = Array();
- x = 0;
- for(i = 0; i < dividend.length; i++)
- {
- x = (x << 16) + dividend[i];
- q = Math.floor(x / divisor);
- x -= q * divisor;
- if(quotient.length > 0 || q > 0)
- quotient[quotient.length] = q;
- }
- remainders[remainders.length] = x;
- dividend = quotient;
- }
-
- /* Convert the remainders to the output string */
- var output = "";
- for(i = remainders.length - 1; i >= 0; i--)
- output += encoding.charAt(remainders[i]);
-
- /* Append leading zero equivalents */
- var full_length = Math.ceil(input.length * 8 /
- (Math.log(encoding.length) / Math.log(2)))
- for(i = output.length; i < full_length; i++)
- output = encoding[0] + output;
-
- return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
- var output = "";
- var i = -1;
- var x, y;
-
- while(++i < input.length)
- {
- /* Decode utf-16 surrogate pairs */
- x = input.charCodeAt(i);
- y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
- if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
- {
- x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
- i++;
- }
-
- /* Encode output as utf-8 */
- if(x <= 0x7F)
- output += String.fromCharCode(x);
- else if(x <= 0x7FF)
- output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
- 0x80 | ( x & 0x3F));
- else if(x <= 0xFFFF)
- output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
- 0x80 | ((x >>> 6 ) & 0x3F),
- 0x80 | ( x & 0x3F));
- else if(x <= 0x1FFFFF)
- output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
- 0x80 | ((x >>> 12) & 0x3F),
- 0x80 | ((x >>> 6 ) & 0x3F),
- 0x80 | ( x & 0x3F));
- }
- return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
- var output = "";
- for(var i = 0; i < input.length; i++)
- output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
- (input.charCodeAt(i) >>> 8) & 0xFF);
- return output;
-}
-
-function str2rstr_utf16be(input)
-{
- var output = "";
- for(var i = 0; i < input.length; i++)
- output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
- input.charCodeAt(i) & 0xFF);
- return output;
-}
-
-/*
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
- var output = Array(input.length >> 2);
- for(var i = 0; i < output.length; i++)
- output[i] = 0;
- for(var i = 0; i < input.length * 8; i += 8)
- output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
- return output;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
- var output = "";
- for(var i = 0; i < input.length * 32; i += 8)
- output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
- return output;
-}
-
-/*
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
-function binb_sha1(x, len)
-{
- /* append padding */
- x[len >> 5] |= 0x80 << (24 - len % 32);
- x[((len + 64 >> 9) << 4) + 15] = len;
-
- var w = Array(80);
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
- var e = -1009589776;
-
- for(var i = 0; i < x.length; i += 16)
- {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
- var olde = e;
-
- for(var j = 0; j < 80; j++)
- {
- if(j < 16) w[j] = x[i + j];
- else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
- var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
- safe_add(safe_add(e, w[j]), sha1_kt(j)));
- e = d;
- d = c;
- c = bit_rol(b, 30);
- b = a;
- a = t;
- }
-
- a = safe_add(a, olda);
- b = safe_add(b, oldb);
- c = safe_add(c, oldc);
- d = safe_add(d, oldd);
- e = safe_add(e, olde);
- }
- return Array(a, b, c, d, e);
-
-}
-
-/*
- * Perform the appropriate triplet combination function for the current
- * iteration
- */
-function sha1_ft(t, b, c, d)
-{
- if(t < 20) return (b & c) | ((~b) & d);
- if(t < 40) return b ^ c ^ d;
- if(t < 60) return (b & c) | (b & d) | (c & d);
- return b ^ c ^ d;
-}
-
-/*
- * Determine the appropriate additive constant for the current iteration
- */
-function sha1_kt(t)
-{
- return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
- (t < 60) ? -1894007588 : -899497514;
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
- return (num << cnt) | (num >>> (32 - cnt));
-}
diff --git a/plugins/kimchi/ui/spice-html5/ticket.js b/plugins/kimchi/ui/spice-html5/ticket.js
deleted file mode 100644
index 96577a3..0000000
--- a/plugins/kimchi/ui/spice-html5/ticket.js
+++ /dev/null
@@ -1,250 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-var SHA_DIGEST_LENGTH = 20;
-
-/*----------------------------------------------------------------------------
-** General ticket RSA encryption functions - just good enough to
-** support what we need to send back an encrypted ticket.
-**--------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-** OAEP padding functions. Inspired by the OpenSSL implementation.
-**--------------------------------------------------------------------------*/
-function MGF1(mask, seed)
-{
- var i, j, outlen;
- for (i = 0, outlen = 0; outlen < mask.length; i++)
- {
- var combo_buf = new String;
-
- for (j = 0; j < seed.length; j++)
- combo_buf += String.fromCharCode(seed[j]);
- combo_buf += String.fromCharCode((i >> 24) & 255);
- combo_buf += String.fromCharCode((i >> 16) & 255);
- combo_buf += String.fromCharCode((i >> 8) & 255);
- combo_buf += String.fromCharCode((i) & 255);
-
- var combo_hash = rstr_sha1(combo_buf);
- for (j = 0; j < combo_hash.length && outlen < mask.length; j++, outlen++)
- {
- mask[outlen] = combo_hash.charCodeAt(j);
- }
- }
-}
-
-
-function RSA_padding_add_PKCS1_OAEP(tolen, from, param)
-{
- var seed = new Array(SHA_DIGEST_LENGTH);
- var rand = new SecureRandom();
- rand.nextBytes(seed);
-
- var dblen = tolen - 1 - seed.length;
- var db = new Array(dblen);
- var padlen = dblen - from.length - 1;
- var i;
-
- if (param === undefined)
- param = "";
-
- if (padlen < SHA_DIGEST_LENGTH)
- {
- console.log("Error - data too large for key size.");
- return null;
- }
-
- for (i = 0; i < padlen; i++)
- db[i] = 0;
-
- var param_hash = rstr_sha1(param);
- for (i = 0; i < param_hash.length; i++)
- db[i] = param_hash.charCodeAt(i);
-
- db[padlen] = 1;
- for (i = 0; i < from.length; i++)
- db[i + padlen + 1] = from.charCodeAt(i);
-
- var dbmask = new Array(dblen);
- if (MGF1(dbmask, seed) < 0)
- return null;
-
- for (i = 0; i < dbmask.length; i++)
- db[i] ^= dbmask[i];
-
-
- var seedmask = Array(SHA_DIGEST_LENGTH);
- if (MGF1(seedmask, db) < 0)
- return null;
-
- for (i = 0; i < seedmask.length; i++)
- seed[i] ^= seedmask[i];
-
- var ret = new String;
- ret += String.fromCharCode(0);
- for (i = 0; i < seed.length; i++)
- ret += String.fromCharCode(seed[i]);
- for (i = 0; i < db.length; i++)
- ret += String.fromCharCode(db[i]);
- return ret;
-}
-
-
-function asn_get_length(u8, at)
-{
- var len = u8[at++];
- if (len > 0x80)
- {
- if (len != 0x81)
- {
- console.log("Error: we lazily don't support keys bigger than 255 bytes. It'd be easy to fix.");
- return null;
- }
- len = u8[at++];
- }
-
- return [ at, len];
-}
-
-function find_sequence(u8, at)
-{
- var lenblock;
- at = at || 0;
- if (u8[at++] != 0x30)
- {
- console.log("Error: public key should start with a sequence flag.");
- return null;
- }
-
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
- return lenblock;
-}
-
-/*----------------------------------------------------------------------------
-** Extract an RSA key from a memory buffer
-**--------------------------------------------------------------------------*/
-function create_rsa_from_mb(mb, at)
-{
- var u8 = new Uint8Array(mb);
- var lenblock;
- var seq;
- var ba;
- var i;
- var ret;
-
- /* We have a sequence which contains a sequence followed by a bit string */
- seq = find_sequence(u8, at);
- if (! seq)
- return null;
-
- at = seq[0];
- seq = find_sequence(u8, at);
- if (! seq)
- return null;
-
- /* Skip over the contained sequence */
- at = seq[0] + seq[1];
- if (u8[at++] != 0x3)
- {
- console.log("Error: expecting bit string next.");
- return null;
- }
-
- /* Get the bit string, which is *itself* a sequence. Having fun yet? */
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
-
- at = lenblock[0];
- if (u8[at] != 0 && u8[at + 1] != 0x30)
- {
- console.log("Error: unexpected values in bit string.");
- return null;
- }
-
- /* Okay, now we have a sequence of two binary values, we hope. */
- seq = find_sequence(u8, at + 1);
- if (! seq)
- return null;
-
- at = seq[0];
- if (u8[at++] != 0x02)
- {
- console.log("Error: expecting integer n next.");
- return null;
- }
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
- at = lenblock[0];
-
- ba = new Array(lenblock[1]);
- for (i = 0; i < lenblock[1]; i++)
- ba[i] = u8[at + i];
-
- ret = new RSAKey();
- ret.n = new BigInteger(ba);
-
- at += lenblock[1];
-
- if (u8[at++] != 0x02)
- {
- console.log("Error: expecting integer e next.");
- return null;
- }
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
- at = lenblock[0];
-
- ret.e = u8[at++];
- for (i = 1; i < lenblock[1]; i++)
- {
- ret.e <<= 8;
- ret.e |= u8[at++];
- }
-
- return ret;
-}
-
-function rsa_encrypt(rsa, str)
-{
- var i;
- var ret = [];
- var oaep = RSA_padding_add_PKCS1_OAEP((rsa.n.bitLength()+7)>>3, str);
- if (! oaep)
- return null;
-
- var ba = new Array(oaep.length);
-
- for (i = 0; i < oaep.length; i++)
- ba[i] = oaep.charCodeAt(i);
- var bigint = new BigInteger(ba);
- var enc = rsa.doPublic(bigint);
- var h = enc.toString(16);
- if ((h.length & 1) != 0)
- h = "0" + h;
- for (i = 0; i < h.length; i += 2)
- ret[i / 2] = parseInt(h.substring(i, i + 2), 16);
- return ret;
-}
diff --git a/plugins/kimchi/ui/spice-html5/utils.js b/plugins/kimchi/ui/spice-html5/utils.js
deleted file mode 100644
index 9eb42ff..0000000
--- a/plugins/kimchi/ui/spice-html5/utils.js
+++ /dev/null
@@ -1,265 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** Utility settings and functions for Spice
-**--------------------------------------------------------------------------*/
-var DEBUG = 0;
-var DUMP_DRAWS = false;
-var DUMP_CANVASES = false;
-
-
-/*----------------------------------------------------------------------------
-** combine_array_buffers
-** Combine two array buffers.
-** FIXME - this can't be optimal. See wire.js about eliminating the need.
-**--------------------------------------------------------------------------*/
-function combine_array_buffers(a1, a2)
-{
- var in1 = new Uint8Array(a1);
- var in2 = new Uint8Array(a2);
- var ret = new ArrayBuffer(a1.byteLength + a2.byteLength);
- var out = new Uint8Array(ret);
- var o = 0;
- var i;
- for (i = 0; i < in1.length; i++)
- out[o++] = in1[i];
- for (i = 0; i < in2.length; i++)
- out[o++] = in2[i];
-
- return ret;
-}
-
-/*----------------------------------------------------------------------------
-** hexdump_buffer
-**--------------------------------------------------------------------------*/
-function hexdump_buffer(a)
-{
- var mg = new Uint8Array(a);
- var hex = "";
- var str = "";
- var last_zeros = 0;
- for (var i = 0; i < mg.length; i++)
- {
- var h = Number(mg[i]).toString(16);
- if (h.length == 1)
- hex += "0";
- hex += h + " ";
-
- if (mg[i] == 10 || mg[i] == 13 || mg[i] == 8)
- str += ".";
- else
- str += String.fromCharCode(mg[i]);
-
- if ((i % 16 == 15) || (i == (mg.length - 1)))
- {
- while (i % 16 != 15)
- {
- hex += " ";
- i++;
- }
-
- if (last_zeros == 0)
- console.log(hex + " | " + str);
-
- if (hex == "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ")
- {
- if (last_zeros == 1)
- {
- console.log(".");
- last_zeros++;
- }
- else if (last_zeros == 0)
- last_zeros++;
- }
- else
- last_zeros = 0;
-
- hex = str = "";
- }
- }
-}
-
-/*----------------------------------------------------------------------------
-** Converting keycodes to AT scancodes is very hard.
-** luckly there are some resources on the web and in the Xorg driver that help
-** us figure out what browser depenend keycodes match to what scancodes.
-**
-** This will most likely not work for non US keyboard and browsers other than
-** modern Chrome and FireFox.
-**--------------------------------------------------------------------------*/
-var common_scanmap = [];
-common_scanmap['Q'.charCodeAt(0)] = KEY_Q;
-common_scanmap['W'.charCodeAt(0)] = KEY_W;
-common_scanmap['E'.charCodeAt(0)] = KEY_E;
-common_scanmap['R'.charCodeAt(0)] = KEY_R;
-common_scanmap['T'.charCodeAt(0)] = KEY_T;
-common_scanmap['Y'.charCodeAt(0)] = KEY_Y;
-common_scanmap['U'.charCodeAt(0)] = KEY_U;
-common_scanmap['I'.charCodeAt(0)] = KEY_I;
-common_scanmap['O'.charCodeAt(0)] = KEY_O;
-common_scanmap['P'.charCodeAt(0)] = KEY_P;
-common_scanmap['A'.charCodeAt(0)] = KEY_A;
-common_scanmap['S'.charCodeAt(0)] = KEY_S;
-common_scanmap['D'.charCodeAt(0)] = KEY_D;
-common_scanmap['F'.charCodeAt(0)] = KEY_F;
-common_scanmap['G'.charCodeAt(0)] = KEY_G;
-common_scanmap['H'.charCodeAt(0)] = KEY_H;
-common_scanmap['J'.charCodeAt(0)] = KEY_J;
-common_scanmap['K'.charCodeAt(0)] = KEY_K;
-common_scanmap['L'.charCodeAt(0)] = KEY_L;
-common_scanmap['Z'.charCodeAt(0)] = KEY_Z;
-common_scanmap['X'.charCodeAt(0)] = KEY_X;
-common_scanmap['C'.charCodeAt(0)] = KEY_C;
-common_scanmap['V'.charCodeAt(0)] = KEY_V;
-common_scanmap['B'.charCodeAt(0)] = KEY_B;
-common_scanmap['N'.charCodeAt(0)] = KEY_N;
-common_scanmap['M'.charCodeAt(0)] = KEY_M;
-common_scanmap[' '.charCodeAt(0)] = KEY_Space;
-common_scanmap[13] = KEY_Enter;
-common_scanmap[27] = KEY_Escape;
-common_scanmap[8] = KEY_BackSpace;
-common_scanmap[9] = KEY_Tab;
-common_scanmap[16] = KEY_ShiftL;
-common_scanmap[17] = KEY_LCtrl;
-common_scanmap[18] = KEY_Alt;
-common_scanmap[20] = KEY_CapsLock;
-common_scanmap[144] = KEY_NumLock;
-common_scanmap[112] = KEY_F1;
-common_scanmap[113] = KEY_F2;
-common_scanmap[114] = KEY_F3;
-common_scanmap[115] = KEY_F4;
-common_scanmap[116] = KEY_F5;
-common_scanmap[117] = KEY_F6;
-common_scanmap[118] = KEY_F7;
-common_scanmap[119] = KEY_F8;
-common_scanmap[120] = KEY_F9;
-common_scanmap[121] = KEY_F10;
-common_scanmap[122] = KEY_F11;
-common_scanmap[123] = KEY_F12;
-
-/* These externded scancodes do not line up with values from atKeynames */
-common_scanmap[42] = 99;
-common_scanmap[19] = 101; // Break
-common_scanmap[111] = 0xE035; // KP_Divide
-common_scanmap[106] = 0xE037; // KP_Multiply
-common_scanmap[36] = 0xE047; // Home
-common_scanmap[38] = 0xE048; // Up
-common_scanmap[33] = 0xE049; // PgUp
-common_scanmap[37] = 0xE04B; // Left
-common_scanmap[39] = 0xE04D; // Right
-common_scanmap[35] = 0xE04F; // End
-common_scanmap[40] = 0xE050; // Down
-common_scanmap[34] = 0xE051; // PgDown
-common_scanmap[45] = 0xE052; // Insert
-common_scanmap[46] = 0xE053; // Delete
-common_scanmap[44] = 0x2A37; // Print
-
-/* These are not common between ALL browsers but are between Firefox and DOM3 */
-common_scanmap['1'.charCodeAt(0)] = KEY_1;
-common_scanmap['2'.charCodeAt(0)] = KEY_2;
-common_scanmap['3'.charCodeAt(0)] = KEY_3;
-common_scanmap['4'.charCodeAt(0)] = KEY_4;
-common_scanmap['5'.charCodeAt(0)] = KEY_5;
-common_scanmap['6'.charCodeAt(0)] = KEY_6;
-common_scanmap['7'.charCodeAt(0)] = KEY_7;
-common_scanmap['8'.charCodeAt(0)] = KEY_8;
-common_scanmap['9'.charCodeAt(0)] = KEY_9;
-common_scanmap['0'.charCodeAt(0)] = KEY_0;
-common_scanmap[145] = KEY_ScrollLock;
-common_scanmap[103] = KEY_KP_7;
-common_scanmap[104] = KEY_KP_8;
-common_scanmap[105] = KEY_KP_9;
-common_scanmap[100] = KEY_KP_4;
-common_scanmap[101] = KEY_KP_5;
-common_scanmap[102] = KEY_KP_6;
-common_scanmap[107] = KEY_KP_Plus;
-common_scanmap[97] = KEY_KP_1;
-common_scanmap[98] = KEY_KP_2;
-common_scanmap[99] = KEY_KP_3;
-common_scanmap[96] = KEY_KP_0;
-common_scanmap[110] = KEY_KP_Decimal;
-common_scanmap[191] = KEY_Slash;
-common_scanmap[190] = KEY_Period;
-common_scanmap[188] = KEY_Comma;
-common_scanmap[220] = KEY_BSlash;
-common_scanmap[192] = KEY_Tilde;
-common_scanmap[222] = KEY_Quote;
-common_scanmap[219] = KEY_LBrace;
-common_scanmap[221] = KEY_RBrace;
-
-common_scanmap[91] = 0xE05B; //KEY_LMeta
-common_scanmap[92] = 0xE05C; //KEY_RMeta
-common_scanmap[93] = 0xE05D; //KEY_Menu
-
-/* Firefox/Mozilla codes */
-var firefox_scanmap = [];
-firefox_scanmap[173] = KEY_Minus;
-firefox_scanmap[109] = KEY_Minus;
-firefox_scanmap[61] = KEY_Equal;
-firefox_scanmap[59] = KEY_SemiColon;
-
-/* DOM3 codes */
-var DOM_scanmap = [];
-DOM_scanmap[189] = KEY_Minus;
-DOM_scanmap[187] = KEY_Equal;
-DOM_scanmap[186] = KEY_SemiColon;
-
-function get_scancode(code)
-{
- if (common_scanmap[code] === undefined)
- {
- if (navigator.userAgent.indexOf("Firefox") != -1)
- return firefox_scanmap[code];
- else
- return DOM_scanmap[code];
- }
- else
- return common_scanmap[code];
-}
-
-function keycode_to_start_scan(code)
-{
- var scancode = get_scancode(code);
- if (scancode === undefined)
- {
- alert('no map for ' + code);
- return 0;
- }
-
- if (scancode < 0x100) {
- return scancode;
- } else {
- return 0xe0 | ((scancode - 0x100) << 8);
- }
-}
-
-function keycode_to_end_scan(code)
-{
- var scancode = get_scancode(code);
- if (scancode === undefined)
- return 0;
-
- if (scancode < 0x100) {
- return scancode | 0x80;
- } else {
- return 0x80e0 | ((scancode - 0x100) << 8);
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/webm.js b/plugins/kimchi/ui/spice-html5/webm.js
deleted file mode 100644
index 35cbc07..0000000
--- a/plugins/kimchi/ui/spice-html5/webm.js
+++ /dev/null
@@ -1,553 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2014 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** EBML identifiers
-**--------------------------------------------------------------------------*/
-var EBML_HEADER = [ 0x1a, 0x45, 0xdf, 0xa3 ];
-var EBML_HEADER_VERSION = [ 0x42, 0x86 ];
-var EBML_HEADER_READ_VERSION = [ 0x42, 0xf7 ];
-var EBML_HEADER_MAX_ID_LENGTH = [ 0x42, 0xf2 ];
-var EBML_HEADER_MAX_SIZE_LENGTH = [ 0x42, 0xf3 ];
-var EBML_HEADER_DOC_TYPE = [ 0x42, 0x82 ];
-var EBML_HEADER_DOC_TYPE_VERSION = [ 0x42, 0x87 ];
-var EBML_HEADER_DOC_TYPE_READ_VERSION = [ 0x42, 0x85 ];
-
-var WEBM_SEGMENT_HEADER = [ 0x18, 0x53, 0x80, 0x67 ];
-var WEBM_SEGMENT_INFORMATION = [ 0x15, 0x49, 0xA9, 0x66 ];
-
-var WEBM_TIMECODE_SCALE = [ 0x2A, 0xD7, 0xB1 ];
-var WEBM_MUXING_APP = [ 0x4D, 0x80 ];
-var WEBM_WRITING_APP = [ 0x57, 0x41 ];
-
-var WEBM_SEEK_HEAD = [ 0x11, 0x4D, 0x9B, 0x74 ];
-var WEBM_SEEK = [ 0x4D, 0xBB ];
-var WEBM_SEEK_ID = [ 0x53, 0xAB ];
-var WEBM_SEEK_POSITION = [ 0x53, 0xAC ];
-
-var WEBM_TRACKS = [ 0x16, 0x54, 0xAE, 0x6B ];
-var WEBM_TRACK_ENTRY = [ 0xAE ];
-var WEBM_TRACK_NUMBER = [ 0xD7 ];
-var WEBM_TRACK_UID = [ 0x73, 0xC5 ];
-var WEBM_TRACK_TYPE = [ 0x83 ];
-var WEBM_FLAG_ENABLED = [ 0xB9 ];
-var WEBM_FLAG_DEFAULT = [ 0x88 ];
-var WEBM_FLAG_FORCED = [ 0x55, 0xAA ];
-var WEBM_FLAG_LACING = [ 0x9C ];
-var WEBM_MIN_CACHE = [ 0x6D, 0xE7 ];
-
-var WEBM_MAX_BLOCK_ADDITION_ID = [ 0x55, 0xEE ];
-var WEBM_CODEC_DECODE_ALL = [ 0xAA ];
-var WEBM_SEEK_PRE_ROLL = [ 0x56, 0xBB ];
-var WEBM_CODEC_DELAY = [ 0x56, 0xAA ];
-var WEBM_CODEC_PRIVATE = [ 0x63, 0xA2 ];
-var WEBM_CODEC_ID = [ 0x86 ];
-
-var WEBM_AUDIO = [ 0xE1 ] ;
-var WEBM_SAMPLING_FREQUENCY = [ 0xB5 ] ;
-var WEBM_CHANNELS = [ 0x9F ] ;
-
-var WEBM_CLUSTER = [ 0x1F, 0x43, 0xB6, 0x75 ];
-var WEBM_TIME_CODE = [ 0xE7 ] ;
-var WEBM_SIMPLE_BLOCK = [ 0xA3 ] ;
-
-/*----------------------------------------------------------------------------
-** Various OPUS / Webm constants
-**--------------------------------------------------------------------------*/
-var CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME = 1 << 7;
-
-var OPUS_FREQUENCY = 48000;
-var OPUS_CHANNELS = 2;
-
-var SPICE_PLAYBACK_CODEC = 'audio/webm; codecs="opus"';
-var MAX_CLUSTER_TIME = 1000;
-
-var GAP_DETECTION_THRESHOLD = 50;
-
-/*----------------------------------------------------------------------------
-** EBML utility functions
-** These classes can create the binary representation of a webm file
-**--------------------------------------------------------------------------*/
-function EBML_write_u1_data_len(len, dv, at)
-{
- var b = 0x80 | len;
- dv.setUint8(at, b);
- return at + 1;
-}
-
-function EBML_write_u8_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(1, dv, at);
- dv.setUint8(at, val);
- return at + 1;
-}
-
-function EBML_write_u32_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(4, dv, at);
- dv.setUint32(at, val);
- return at + 4;
-}
-
-function EBML_write_u16_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(2, dv, at);
- dv.setUint16(at, val);
- return at + 2;
-}
-
-function EBML_write_float_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(4, dv, at);
- dv.setFloat32(at, val);
- return at + 4;
-}
-
-
-
-function EBML_write_u64_data_len(len, dv, at)
-{
- /* Javascript doesn't do 64 bit ints, so this cheats and
- just has a max of 32 bits. Fine for our purposes */
- dv.setUint8(at++, 0x01);
- dv.setUint8(at++, 0x00);
- dv.setUint8(at++, 0x00);
- dv.setUint8(at++, 0x00);
- var val = len & 0xFFFFFFFF;
- for (var shift = 24; shift >= 0; shift -= 8)
- dv.setUint8(at++, val >> shift);
- return at;
-}
-
-function EBML_write_array(arr, dv, at)
-{
- for (var i = 0; i < arr.length; i++)
- dv.setUint8(at + i, arr[i]);
- return at + arr.length;
-}
-
-function EBML_write_string(str, dv, at)
-{
- for (var i = 0; i < str.length; i++)
- dv.setUint8(at + i, str.charCodeAt(i));
- return at + str.length;
-}
-
-function EBML_write_data(id, data, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- if (data.length < 127)
- at = EBML_write_u1_data_len(data.length, dv, at);
- else
- at = EBML_write_u64_data_len(data.length, dv, at);
- if ((typeof data) == "string")
- at = EBML_write_string(data, dv, at);
- else
- at = EBML_write_array(data, dv, at);
- return at;
-}
-
-/*----------------------------------------------------------------------------
-** Webm objects
-** These classes can create the binary representation of a webm file
-**--------------------------------------------------------------------------*/
-function EBMLHeader()
-{
- this.id = EBML_HEADER;
- this.Version = 1;
- this.ReadVersion = 1;
- this.MaxIDLength = 4;
- this.MaxSizeLength = 8;
- this.DocType = "webm";
- this.DocTypeVersion = 2; /* Not well specified by the WebM guys, but functionally required for Firefox */
- this.DocTypeReadVersion = 2;
-}
-
-EBMLHeader.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
-
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(0x1f, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_VERSION, this.Version, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_READ_VERSION, this.ReadVersion, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_MAX_ID_LENGTH, this.MaxIDLength, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_MAX_SIZE_LENGTH, this.MaxSizeLength, dv, at);
- at = EBML_write_data(EBML_HEADER_DOC_TYPE, this.DocType, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_VERSION, this.DocTypeVersion, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_READ_VERSION, this.DocTypeReadVersion, dv, at);
-
- return at;
- },
- buffer_size: function()
- {
- return 0x1f + 8 + this.id.length;
- },
-}
-
-function webm_Segment()
-{
- this.id = WEBM_SEGMENT_HEADER;
-}
-
-webm_Segment.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
-
- at = EBML_write_array(this.id, dv, at);
- dv.setUint8(at++, 0xff);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 1;
- },
-}
-
-function webm_SegmentInformation()
-{
- this.id = WEBM_SEGMENT_INFORMATION;
- this.timecode_scale = 1000000; /* 1 ms */
- this.muxing_app = "spice";
- this.writing_app = "spice-html5";
-
-}
-
-webm_SegmentInformation.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
-
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = EBML_write_u32_value(WEBM_TIMECODE_SCALE, this.timecode_scale, dv, at);
- at = EBML_write_data(WEBM_MUXING_APP, this.muxing_app, dv, at);
- at = EBML_write_data(WEBM_WRITING_APP, this.writing_app, dv, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- WEBM_TIMECODE_SCALE.length + 1 + 4 +
- WEBM_MUXING_APP.length + 1 + this.muxing_app.length +
- WEBM_WRITING_APP.length + 1 + this.writing_app.length;
- },
-}
-
-function webm_Audio(frequency)
-{
- this.id = WEBM_AUDIO;
- this.sampling_frequency = frequency;
- this.channels = OPUS_CHANNELS;
-}
-
-webm_Audio.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = EBML_write_u8_value(WEBM_CHANNELS, this.channels, dv, at);
- at = EBML_write_float_value(WEBM_SAMPLING_FREQUENCY, this.sampling_frequency, dv, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- WEBM_SAMPLING_FREQUENCY.length + 1 + 4 +
- WEBM_CHANNELS.length + 1 + 1;
- },
-}
-
-
-/* ---------------------------
- SeekHead not currently used. Hopefully not needed.
-*/
-function webm_Seek(seekid, pos)
-{
- this.id = WEBM_SEEK;
- this.pos = pos;
- this.seekid = seekid;
-}
-
-webm_Seek.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u1_data_len(this.buffer_size() - 1 - this.id.length, dv, at);
-
- at = EBML_write_data(WEBM_SEEK_ID, this.seekid, dv, at)
- at = EBML_write_u16_value(WEBM_SEEK_POSITION, this.pos, dv, at)
-
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 1 +
- WEBM_SEEK_ID.length + 1 + this.seekid.length +
- WEBM_SEEK_POSITION.length + 1 + 2;
- },
-}
-function webm_SeekHead(info_pos, track_pos)
-{
- this.id = WEBM_SEEK_HEAD;
- this.info = new webm_Seek(WEBM_SEGMENT_INFORMATION, info_pos);
- this.track = new webm_Seek(WEBM_TRACKS, track_pos);
-}
-
-webm_SeekHead.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
-
- at = this.info.to_buffer(a, at);
- at = this.track.to_buffer(a, at);
-
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- this.info.buffer_size() +
- this.track.buffer_size();
- },
-}
-
-/* -------------------------------
- End of Seek Head
-*/
-
-function webm_TrackEntry()
-{
- this.id = WEBM_TRACK_ENTRY;
- this.number = 1;
- this.uid = 1;
- this.type = 2; // Audio
- this.flag_enabled = 1;
- this.flag_default = 1;
- this.flag_forced = 1;
- this.flag_lacing = 0;
- this.min_cache = 0; // fixme - check
- this.max_block_addition_id = 0;
- this.codec_decode_all = 0; // fixme - check
- this.seek_pre_roll = 0; // 80000000; // fixme - check
- this.codec_delay = 80000000; // Must match codec_private.preskip
- this.codec_id = "A_OPUS";
- this.audio = new webm_Audio(OPUS_FREQUENCY);
-
- // See: http://tools.ietf.org/html/draft-terriberry-oggopus-01
- this.codec_private = [ 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, // OpusHead
- 0x01, // Version
- OPUS_CHANNELS,
- 0x00, 0x0F, // Preskip - 3840 samples - should be 8ms at 48kHz
- 0x80, 0xbb, 0x00, 0x00, // 48000
- 0x00, 0x00, // Output gain
- 0x00 // Channel mapping family
- ];
-}
-
-webm_TrackEntry.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = EBML_write_u8_value(WEBM_TRACK_NUMBER, this.number, dv, at);
- at = EBML_write_u8_value(WEBM_TRACK_UID, this.uid, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_ENABLED, this.flag_enabled, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_DEFAULT, this.flag_default, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_FORCED, this.flag_forced, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_LACING, this.flag_lacing, dv, at);
- at = EBML_write_data(WEBM_CODEC_ID, this.codec_id, dv, at);
- at = EBML_write_u8_value(WEBM_MIN_CACHE, this.min_cache, dv, at);
- at = EBML_write_u8_value(WEBM_MAX_BLOCK_ADDITION_ID, this.max_block_addition_id, dv, at);
- at = EBML_write_u8_value(WEBM_CODEC_DECODE_ALL, this.codec_decode_all, dv, at);
- at = EBML_write_u32_value(WEBM_CODEC_DELAY, this.codec_delay, dv, at);
- at = EBML_write_u32_value(WEBM_SEEK_PRE_ROLL, this.seek_pre_roll, dv, at);
- at = EBML_write_u8_value(WEBM_TRACK_TYPE, this.type, dv, at);
- at = EBML_write_data(WEBM_CODEC_PRIVATE, this.codec_private, dv, at);
-
- at = this.audio.to_buffer(a, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- WEBM_TRACK_NUMBER.length + 1 + 1 +
- WEBM_TRACK_UID.length + 1 + 1 +
- WEBM_TRACK_TYPE.length + 1 + 1 +
- WEBM_FLAG_ENABLED.length + 1 + 1 +
- WEBM_FLAG_DEFAULT.length + 1 + 1 +
- WEBM_FLAG_FORCED.length + 1 + 1 +
- WEBM_FLAG_LACING.length + 1 + 1 +
- WEBM_MIN_CACHE.length + 1 + 1 +
- WEBM_MAX_BLOCK_ADDITION_ID.length + 1 + 1 +
- WEBM_CODEC_DECODE_ALL.length + 1 + 1 +
- WEBM_SEEK_PRE_ROLL.length + 1 + 4 +
- WEBM_CODEC_DELAY.length + 1 + 4 +
- WEBM_CODEC_ID.length + this.codec_id.length + 1 +
- WEBM_CODEC_PRIVATE.length + 1 + this.codec_private.length +
- this.audio.buffer_size();
- },
-}
-function webm_Tracks(entry)
-{
- this.id = WEBM_TRACKS;
- this.track_entry = entry;
-}
-
-webm_Tracks.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = this.track_entry.to_buffer(a, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- this.track_entry.buffer_size();
- },
-}
-
-function webm_Cluster(timecode, data)
-{
- this.id = WEBM_CLUSTER;
- this.timecode = timecode;
- this.data = data;
-}
-
-webm_Cluster.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- dv.setUint8(at++, 0xff);
- at = EBML_write_u32_value(WEBM_TIME_CODE, this.timecode, dv, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 1 +
- WEBM_TIME_CODE.length + 1 + 4;
- },
-}
-
-function webm_SimpleBlock(timecode, data, keyframe)
-{
- this.id = WEBM_SIMPLE_BLOCK;
- this.timecode = timecode;
- this.data = data;
- this.keyframe = keyframe;
-}
-
-webm_SimpleBlock.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.data.byteLength + 4, dv, at);
- at = EBML_write_u1_data_len(1, dv, at); // Track #
- dv.setUint16(at, this.timecode); at += 2; // timecode - relative to cluster
- dv.setUint8(at, this.keyframe ? CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 0); at += 1; // flags
-
- // FIXME - There should be a better way to copy
- var u8 = new Uint8Array(this.data);
- for (var i = 0; i < this.data.byteLength; i++)
- dv.setUint8(at++, u8[i]);
-
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- 1 + 2 + 1 +
- this.data.byteLength;
- },
-}
-
-function webm_Header()
-{
- this.ebml = new EBMLHeader;
- this.segment = new webm_Segment;
- this.seek_head = new webm_SeekHead(0, 0);
-
- this.seek_head.info.pos = this.segment.buffer_size() + this.seek_head.buffer_size();
-
- this.info = new webm_SegmentInformation;
-
- this.seek_head.track.pos = this.seek_head.info.pos + this.info.buffer_size();
-
- this.track_entry = new webm_TrackEntry;
- this.tracks = new webm_Tracks(this.track_entry);
-}
-
-webm_Header.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- at = this.ebml.to_buffer(a, at);
- at = this.segment.to_buffer(a, at);
- at = this.info.to_buffer(a, at);
- at = this.tracks.to_buffer(a, at);
-
- return at;
- },
- buffer_size: function()
- {
- return this.ebml.buffer_size() +
- this.segment.buffer_size() +
- this.info.buffer_size() +
- this.tracks.buffer_size();
- },
-}
diff --git a/plugins/kimchi/ui/spice-html5/wire.js b/plugins/kimchi/ui/spice-html5/wire.js
deleted file mode 100644
index 7407ce7..0000000
--- a/plugins/kimchi/ui/spice-html5/wire.js
+++ /dev/null
@@ -1,123 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*--------------------------------------------------------------------------------------
-** SpiceWireReader
-** This class will receive messages from a WebSocket and relay it to a given
-** callback. It will optionally save and pass along a header, useful in processing
-** the mini message format.
-**--------------------------------------------------------------------------------------*/
-function SpiceWireReader(sc, callback)
-{
- this.sc = sc;
- this.callback = callback;
- this.needed = 0;
-
- this.buffers = [];
-
- this.sc.ws.wire_reader = this;
- this.sc.ws.binaryType = "arraybuffer";
- this.sc.ws.addEventListener('message', wire_blob_catcher);
-}
-
-SpiceWireReader.prototype =
-{
-
- /*------------------------------------------------------------------------
- ** Process messages coming in from our WebSocket
- **----------------------------------------------------------------------*/
- inbound: function (mb)
- {
- var at;
-
- /* Just buffer if we don't need anything yet */
- if (this.needed == 0)
- {
- this.buffers.push(mb);
- return;
- }
-
- /* Optimization - if we have just one inbound block, and it's
- suitable for our needs, just use it. */
- if (this.buffers.length == 0 && mb.byteLength >= this.needed)
- {
- if (mb.byteLength > this.needed)
- {
- this.buffers.push(mb.slice(this.needed));
- mb = mb.slice(0, this.needed);
- }
- this.callback.call(this.sc, mb,
- this.saved_msg_header || undefined);
- }
- else
- {
- this.buffers.push(mb);
- }
-
-
- /* If we have fragments that add up to what we need, combine them */
- /* FIXME - it would be faster to revise the processing code to handle
- ** multiple fragments directly. Essentially, we should be
- ** able to do this without any slice() or combine_array_buffers() calls */
- while (this.buffers.length > 1 && this.buffers[0].byteLength < this.needed)
- {
- var mb1 = this.buffers.shift();
- var mb2 = this.buffers.shift();
-
- this.buffers.unshift(combine_array_buffers(mb1, mb2));
- }
-
-
- while (this.buffers.length > 0 && this.buffers[0].byteLength >= this.needed)
- {
- mb = this.buffers.shift();
- if (mb.byteLength > this.needed)
- {
- this.buffers.unshift(mb.slice(this.needed));
- mb = mb.slice(0, this.needed);
- }
- this.callback.call(this.sc, mb,
- this.saved_msg_header || undefined);
- }
-
- },
-
- request: function(n)
- {
- this.needed = n;
- },
-
- save_header: function(h)
- {
- this.saved_msg_header = h;
- },
-
- clear_header: function()
- {
- this.saved_msg_header = undefined;
- },
-}
-
-function wire_blob_catcher(e)
-{
- DEBUG > 1 && console.log(">> WebSockets.onmessage");
- DEBUG > 1 && console.log("id " + this.wire_reader.sc.connection_id +"; type " + this.wire_reader.sc.type);
- SpiceWireReader.prototype.inbound.call(this.wire_reader, e.data);
-}
diff --git a/plugins/kimchi/utils.py b/plugins/kimchi/utils.py
deleted file mode 100644
index 2480362..0000000
--- a/plugins/kimchi/utils.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import re
-
-from wok.exception import InvalidParameter
-
-
-def _uri_to_name(collection, uri):
- expr = '/plugins/kimchi/%s/(.*?)$' % collection
- m = re.match(expr, uri)
- if not m:
- raise InvalidParameter("WOKUTILS0001E", {'uri': uri})
- return m.group(1)
-
-
-def template_name_from_uri(uri):
- return _uri_to_name('templates', uri)
-
-
-def pool_name_from_uri(uri):
- return _uri_to_name('storagepools', uri)
diff --git a/plugins/kimchi/vmtemplate.py b/plugins/kimchi/vmtemplate.py
deleted file mode 100644
index 07e70ba..0000000
--- a/plugins/kimchi/vmtemplate.py
+++ /dev/null
@@ -1,431 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import stat
-import time
-import urlparse
-import uuid
-from lxml import etree
-from lxml.builder import E
-
-from wok.exception import InvalidParameter, ImageFormatError, IsoFormatError
-from wok.exception import MissingParameter, OperationFailed
-from wok.utils import check_url_path
-
-import imageinfo
-import osinfo
-from isoinfo import IsoImage
-from utils import pool_name_from_uri
-from xmlutils.cpu import get_cpu_xml
-from xmlutils.disk import get_disk_xml
-from xmlutils.graphics import get_graphics_xml
-from xmlutils.interface import get_iface_xml
-from xmlutils.qemucmdline import get_qemucmdline_xml
-
-
-class VMTemplate(object):
- def __init__(self, args, scan=False):
- """
- Construct a VM Template from a widely variable amount of information.
- The only required parameter is a name for the VMTemplate. If present,
- the os_distro and os_version fields are used to lookup recommended
- settings. Any parameters provided by the caller will override the
- defaults. If scan is True and a cdrom or a base img is present, the
- operating system will be detected by probing the installation media.
- """
- self.info = {}
- self.fc_host_support = args.get('fc_host_support')
-
- # Fetch defaults based on the os distro and version
- try:
- distro, version = self._get_os_info(args, scan)
- except ImageFormatError as e:
- raise OperationFailed('KCHTMPL0020E', {'err': e.message})
- os_distro = args.get('os_distro', distro)
- os_version = args.get('os_version', version)
- entry = osinfo.lookup(os_distro, os_version)
- self.info.update(entry)
-
- # Auto-generate a template name and no one is passed
- if 'name' not in args or args['name'] == '':
- args['name'] = self._gen_name(distro, version)
- self.name = args['name']
-
- # Override with the passed in parameters
- graph_args = args.get('graphics')
- if graph_args:
- graphics = dict(self.info['graphics'])
- graphics.update(graph_args)
- args['graphics'] = graphics
- self.info.update(args)
-
- # Assign right disk format to logical and [i]scsi storagepools
- if self._get_storage_type() in ['logical', 'iscsi', 'scsi']:
- for i, disk in enumerate(self.info['disks']):
- self.info['disks'][i]['format'] = 'raw'
-
- def _get_os_info(self, args, scan):
- distro = version = 'unknown'
-
- # Identify the cdrom if present
- iso = args.get('cdrom', '')
- if len(iso) > 0:
- if not iso.startswith('/'):
- self.info.update({'iso_stream': True})
-
- if scan:
- distro, version = self.get_iso_info(iso)
-
- return distro, version
-
- # CDROM is not presented: check for base image
- base_imgs = []
- for d in args.get('disks', []):
- if 'base' in d.keys():
- base_imgs.append(d)
- if scan:
- distro, version = imageinfo.probe_image(d['base'])
-
- if 'size' not in d.keys():
- d_info = imageinfo.probe_img_info(d['base'])
- d['size'] = d_info['virtual-size']
-
- if len(base_imgs) == 0:
- raise MissingParameter("KCHTMPL0016E")
-
- return distro, version
-
- def _gen_name(self, distro, version):
- if distro == 'unknown':
- name = str(uuid.uuid4())
- else:
- name = distro + version + '.' + str(int(time.time() * 1000))
- return name
-
- def get_iso_info(self, iso):
- iso_prefixes = ['/', 'http', 'https', 'ftp', 'ftps', 'tftp']
- if len(filter(iso.startswith, iso_prefixes)) == 0:
- raise InvalidParameter("KCHTMPL0006E", {'param': iso})
- try:
- iso_img = IsoImage(iso)
- return iso_img.probe()
- except IsoFormatError:
- raise InvalidParameter("KCHISO0001E", {'filename': iso})
-
- def _get_cdrom_xml(self, libvirt_stream_protocols):
- if 'cdrom' not in self.info:
- return ''
-
- params = {}
- params['type'] = 'cdrom'
- params['format'] = 'raw'
- params['bus'] = self.info['cdrom_bus']
- params['index'] = self.info['cdrom_index']
- params['path'] = self.info['cdrom']
-
- if self.info.get('iso_stream', False):
- protocol = urlparse.urlparse(params['path']).scheme
- if protocol not in libvirt_stream_protocols:
- driveOpt = 'file=%(path)s,if=none,id=drive-%(bus)s0-1-0,'
- driveOpt += 'readonly=on,format=%(format)s'
-
- deviceOpt = '%(bus)s-cd,bus=%(bus)s.1,unit=0,'
- deviceOpt += 'drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'
-
- args = {}
- args['-drive'] = driveOpt % params
- args['-device'] = deviceOpt % params
- # return qemucmdline XML
- return get_qemucmdline_xml(args)
-
- dev, xml = get_disk_xml(params)
- return xml
-
- def _get_disks_xml(self, vm_uuid):
- # Current implementation just allows to create disk in one single
- # storage pool, so we cannot mix the types (scsi volumes vs img file)
- storage_type = self._get_storage_type()
- storage_path = self._get_storage_path()
-
- base_disk_params = {'type': 'disk', 'disk': 'file',
- 'bus': self.info['disk_bus'], 'format': 'qcow2'}
- logical_disk_params = {'format': 'raw'}
- iscsi_disk_params = {'disk': 'block', 'format': 'raw'}
-
- scsi_disk = 'volume' if self.fc_host_support else 'block'
- scsi_disk_params = {'disk': scsi_disk, 'type': 'lun',
- 'format': 'raw', 'bus': 'scsi'}
-
- disks_xml = ''
- pool_name = pool_name_from_uri(self.info['storagepool'])
- for index, disk in enumerate(self.info['disks']):
- params = dict(base_disk_params)
- params['format'] = disk.get('format', params['format'])
- params.update(locals().get('%s_disk_params' % storage_type, {}))
- params['index'] = index
-
- volume = disk.get('volume')
- if volume is not None:
- params['path'] = self._get_volume_path(pool_name, volume)
- else:
- volume = "%s-%s.img" % (vm_uuid, params['index'])
- params['path'] = os.path.join(storage_path, volume)
-
- disks_xml += get_disk_xml(params)[1]
-
- return unicode(disks_xml, 'utf-8')
-
- def to_volume_list(self, vm_uuid):
- storage_path = self._get_storage_path()
- fmt = 'raw' if self._get_storage_type() in ['logical'] else 'qcow2'
- ret = []
- for i, d in enumerate(self.info['disks']):
- index = d.get('index', i)
- volume = "%s-%s.img" % (vm_uuid, index)
-
- info = {'name': volume,
- 'capacity': d['size'],
- 'format': fmt,
- 'path': '%s/%s' % (storage_path, volume)}
-
- if 'logical' == self._get_storage_type() or \
- fmt not in ['qcow2', 'raw']:
- info['allocation'] = info['capacity']
- else:
- info['allocation'] = 0
-
- if 'base' in d:
- info['base'] = dict()
- base_fmt = imageinfo.probe_img_info(d['base'])['format']
- if base_fmt is None:
- raise InvalidParameter("KCHTMPL0024E", {'path': d['base']})
- info['base']['path'] = d['base']
- info['base']['format'] = base_fmt
-
- v_tree = E.volume(E.name(info['name']))
- v_tree.append(E.allocation(str(info['allocation']), unit='G'))
- v_tree.append(E.capacity(str(info['capacity']), unit='G'))
- target = E.target(
- E.format(type=info['format']), E.path(info['path']))
- if 'base' in d:
- v_tree.append(E.backingStore(
- E.path(info['base']['path']),
- E.format(type=info['base']['format'])))
- v_tree.append(target)
- info['xml'] = etree.tostring(v_tree)
- ret.append(info)
- return ret
-
- def _get_networks_xml(self):
- networks = ""
- params = {'type': 'network',
- 'model': self.info['nic_model']}
- for nw in self.info['networks']:
- params['network'] = nw
- networks += get_iface_xml(params, self.info['arch'],
- self.info['os_distro'],
- self.info['os_version'])
- return unicode(networks, 'utf-8')
-
- def _get_input_output_xml(self):
- sound = """
- <sound model='%(sound_model)s' />
- """
- mouse = """
- <input type='mouse' bus='%(mouse_bus)s'/>
- """
-
- keyboard = """
- <input type='%(kbd_type)s' bus='%(kbd_bus)s'> </input>
- """
-
- tablet = """
- <input type='tablet' bus='%(kbd_bus)s'> </input>
- """
-
- video = """
- <video>
- <model type='%(video_model)s'/>
- </video>
- """
-
- input_output = ""
- if 'mouse_bus' in self.info.keys():
- input_output += mouse % self.info
- if 'kbd_bus' in self.info.keys():
- input_output += keyboard % self.info
- if 'tablet_bus' in self.info.keys():
- input_output += tablet % self.info
- if 'sound_model' in self.info.keys():
- input_output += sound % self.info
- if 'video_model' in self.info.keys():
- input_output += video % self.info
- return input_output
-
- def _get_cpu_xml(self):
- # Include CPU topology, if provided
- cpu_info = self.info.get('cpu_info')
- if cpu_info is not None:
- cpu_topo = cpu_info.get('topology')
- return get_cpu_xml(self.info.get('cpus'),
- self.info.get('memory') << 10,
- cpu_topo)
-
- def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
- params = dict(self.info)
- params['name'] = vm_name
- params['uuid'] = vm_uuid
- params['networks'] = self._get_networks_xml()
- params['input_output'] = self._get_input_output_xml()
- params['qemu-namespace'] = ''
- params['cdroms'] = ''
- params['qemu-stream-cmdline'] = ''
- params['cpu_info'] = self._get_cpu_xml()
- params['disks'] = self._get_disks_xml(vm_uuid)
-
- graphics = dict(self.info['graphics'])
- graphics.update(kwargs.get('graphics', {}))
- params['graphics'] = get_graphics_xml(graphics)
-
- libvirt_stream_protocols = kwargs.get('libvirt_stream_protocols', [])
- cdrom_xml = self._get_cdrom_xml(libvirt_stream_protocols)
-
- if not urlparse.urlparse(self.info.get('cdrom', "")).scheme in \
- libvirt_stream_protocols and \
- params.get('iso_stream', False):
- params['qemu-stream-cmdline'] = cdrom_xml
- else:
- params['cdroms'] = cdrom_xml
-
- # Setting maximum number of slots to avoid errors when hotplug memory
- # Number of slots are the numbers of chunks of 1GB that fit inside
- # the max_memory of the host minus memory assigned to the VM
- params['slots'] = ((params['max_memory'] >> 10) -
- params['memory']) >> 10
- if params['slots'] < 0:
- raise OperationFailed("KCHVM0041E")
- elif params['slots'] == 0:
- params['slots'] = 1
-
- xml = """
- <domain type='%(domain)s'>
- %(qemu-stream-cmdline)s
- <name>%(name)s</name>
- <uuid>%(uuid)s</uuid>
- <maxMemory slots='%(slots)s' unit='KiB'>%(max_memory)s</maxMemory>
- <memory unit='MiB'>%(memory)s</memory>
- <vcpu>%(cpus)s</vcpu>
- %(cpu_info)s
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- <boot dev='cdrom'/>
- </os>
- <features>
- <acpi/>
- <apic/>
- <pae/>
- </features>
- <clock offset='utc'/>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>restart</on_crash>
- <devices>
- %(disks)s
- %(cdroms)s
- %(networks)s
- %(graphics)s
- %(input_output)s
- <memballoon model='virtio' />
- </devices>
- </domain>
- """ % params
-
- # Adding PPC console configuration
- if params['arch'] in ['ppc', 'ppc64']:
- ppc_console = """<memballoon model='virtio' />
- <console type='pty'>
- <target type='serial' port='1'/>
- <address type='spapr-vio' reg='0x30001000'/>
- </console>"""
- xml = xml.replace("<memballoon model='virtio' />", ppc_console)
-
- return xml
-
- def validate(self):
- self._storage_validate()
- self._network_validate()
- self._iso_validate()
-
- def _iso_validate(self):
- pass
-
- def _network_validate(self):
- pass
-
- def _storage_validate(self):
- pass
-
- def fork_vm_storage(self, vm_uuid):
- pass
-
- def _get_storage_path(self):
- return ''
-
- def _get_storage_type(self):
- return ''
-
- def _get_volume_path(self):
- return ''
-
- def _get_all_networks_name(self):
- return []
-
- def _get_all_storagepools_name(self):
- return []
-
- def validate_integrity(self):
- invalid = {}
- # validate networks integrity
- invalid_networks = list(set(self.info['networks']) -
- set(self._get_all_networks_name()))
- if invalid_networks:
- invalid['networks'] = invalid_networks
-
- # validate storagepools integrity
- pool_uri = self.info['storagepool']
- pool_name = pool_name_from_uri(pool_uri)
- if pool_name not in self._get_all_storagepools_name():
- invalid['storagepools'] = [pool_name]
-
- # validate iso integrity
- # FIXME when we support multiples cdrom devices
- iso = self.info.get('cdrom')
- if iso:
- if os.path.exists(iso):
- st_mode = os.stat(iso).st_mode
- if not (stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode)):
- invalid['cdrom'] = [iso]
- elif not check_url_path(iso):
- invalid['cdrom'] = [iso]
-
- self.info['invalid'] = invalid
-
- return self.info
diff --git a/plugins/kimchi/vnc.py b/plugins/kimchi/vnc.py
deleted file mode 100644
index 2532449..0000000
--- a/plugins/kimchi/vnc.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python2
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import base64
-import errno
-import os
-from multiprocessing import Process
-from websockify import WebSocketProxy
-
-from wok.config import config, paths
-
-
-WS_TOKENS_DIR = '/var/lib/wok/vnc-tokens'
-
-
-def new_ws_proxy():
- try:
- os.makedirs(WS_TOKENS_DIR, mode=0755)
- except OSError as e:
- if e.errno == errno.EEXIST:
- pass
-
- cert = config.get('server', 'ssl_cert')
- key = config.get('server', 'ssl_key')
- if not (cert and key):
- cert = '%s/wok-cert.pem' % paths.conf_dir
- key = '%s/wok-key.pem' % paths.conf_dir
-
- params = {'web': os.path.join(paths.ui_dir, 'pages/websockify'),
- 'listen_port': config.get('display', 'display_proxy_port'),
- 'target_cfg': WS_TOKENS_DIR,
- 'key': key, 'cert': cert, 'ssl_only': True}
-
- def start_proxy():
- server = WebSocketProxy(**params)
- server.start_server()
-
- proc = Process(target=start_proxy)
- proc.start()
- return proc
-
-
-def add_proxy_token(name, port):
- with open(os.path.join(WS_TOKENS_DIR, name), 'w') as f:
- """
- From python documentation base64.urlsafe_b64encode(s)
- substitutes - instead of + and _ instead of / in the
- standard Base64 alphabet, BUT the result can still
- contain = which is not safe in a URL query component.
- So remove it when needed as base64 can work well without it.
- """
- name = base64.urlsafe_b64encode(name).rstrip('=')
- f.write('%s: localhost:%s' % (name.encode('utf-8'), port))
-
-
-def remove_proxy_token(name):
- try:
- os.unlink(os.path.join(WS_TOKENS_DIR, name))
- except OSError:
- pass
diff --git a/plugins/kimchi/xmlutils/Makefile.am b/plugins/kimchi/xmlutils/Makefile.am
deleted file mode 100644
index 207ad7f..0000000
--- a/plugins/kimchi/xmlutils/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-xmlutils_PYTHON = *.py
-
-xmlutilsdir = $(pythondir)/wok/plugins/kimchi/xmlutils
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(xmlutilsdir)
diff --git a/plugins/kimchi/xmlutils/__init__.py b/plugins/kimchi/xmlutils/__init__.py
deleted file mode 100644
index ca7ede4..0000000
--- a/plugins/kimchi/xmlutils/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/plugins/kimchi/xmlutils/cpu.py b/plugins/kimchi/xmlutils/cpu.py
deleted file mode 100644
index 32c01a4..0000000
--- a/plugins/kimchi/xmlutils/cpu.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from lxml.builder import E
-
-
-def get_numa_xml(cpus, memory):
- # Returns the NUMA xml to be add into CPU element
- # Currently, supports only one node/cell
- # <numa>
- # <cell id='0' cpus='0-3' memory='512000' unit='KiB'/>
- # </numa>
- xml = E.numa(E.cell(
- id='0',
- cpus='0-' + str(cpus - 1) if cpus > 1 else '0',
- memory=str(memory),
- unit='KiB'))
- return ET.tostring(xml)
-
-
-def get_topology_xml(cpu_topo):
- # Return the cpu TOPOLOGY element
- # <topology sockets='1' cores='2' threads='1'/>
- xml = E.topology(
- sockets=str(cpu_topo['sockets']),
- cores=str(cpu_topo['cores']),
- threads=str(cpu_topo['threads']))
- return ET.tostring(xml)
-
-
-def get_cpu_xml(cpus, memory, cpu_topo=None):
- # Returns the libvirt CPU element based on given numa and topology
- # CPU element will always have numa element
- # <cpu>
- # <numa>
- # <cell id='0' cpus='0-3' memory='512000' unit='KiB'/>
- # </numa>
- # <topology sockets='1' cores='2' threads='1'/>
- # </cpu>
- xml = E.cpu(ET.fromstring(get_numa_xml(cpus, memory)))
- if cpu_topo is not None:
- xml.insert(0, ET.fromstring(get_topology_xml(cpu_topo)))
- return ET.tostring(xml)
diff --git a/plugins/kimchi/xmlutils/disk.py b/plugins/kimchi/xmlutils/disk.py
deleted file mode 100644
index 126ce77..0000000
--- a/plugins/kimchi/xmlutils/disk.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-import os
-import socket
-import stat
-import string
-import urlparse
-from lxml import objectify
-from lxml.builder import E
-
-from wok.exception import InvalidParameter, NotFoundError
-from wok.utils import check_url_path
-
-
-BUS_TO_DEV_MAP = {'ide': 'hd', 'virtio': 'vd', 'scsi': 'sd'}
-DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', 'block': 'dev'}
-
-
-def get_disk_xml(params):
- """
- <disk type='file' device='cdrom'>
- <driver name='qemu' type='raw'/>
-
- [source XML according to src_type]
-
- <target dev='%(dev)s' bus='%(bus)s'/>
- <readonly/>
- </disk>
- """
- path = params['path']
- disk_type = params.get('disk', None)
- if disk_type is None:
- disk_type = _get_disk_type(path) if len(path) > 0 else 'file'
- disk = E.disk(type=disk_type, device=params['type'])
- driver = E.driver(name='qemu', type=params['format'])
- if params['type'] != 'cdrom':
- driver.set('cache', 'none')
-
- disk.append(driver)
-
- # Get device name according to bus and index values
- dev = params.get('dev', (BUS_TO_DEV_MAP[params['bus']] +
- string.lowercase[params.get('index', 0)]))
- disk.append(E.target(dev=dev, bus=params['bus']))
-
- if params.get('address'):
- # ide disk target id is always '0'
- disk.append(E.address(
- type='drive', controller=params['address']['controller'],
- bus=params['address']['bus'], target='0',
- unit=params['address']['unit']))
-
- if len(params['path']) == 0:
- return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
-
- if disk_type == 'network':
- """
- <source protocol='%(protocol)s' name='%(url_path)s'>
- <host name='%(hostname)s' port='%(port)s'/>
- </source>
- """
- output = urlparse.urlparse(params['path'])
- port = str(output.port or socket.getservbyname(output.scheme))
-
- source = E.source(protocol=output.scheme, name=output.path)
- source.append(E.host(name=output.hostname, port=port))
- else:
- """
- <source file='%(src)s' />
- """
- source = E.source()
- source.set(DEV_TYPE_SRC_ATTR_MAP[disk_type], params['path'])
-
- disk.append(source)
- return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
-
-
-def _get_disk_type(path):
- if check_url_path(path):
- return 'network'
-
- if not os.path.exists(path):
- raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
-
- # Check if path is a valid local path
- if os.path.isfile(path):
- return 'file'
-
- r_path = os.path.realpath(path)
- if stat.S_ISBLK(os.stat(r_path).st_mode):
- return 'block'
-
- raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
-
-
-def get_device_node(dom, dev_name):
- xml = dom.XMLDesc(0)
- devices = objectify.fromstring(xml).devices
- disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name)
-
- if not disk:
- raise NotFoundError("KCHVMSTOR0007E",
- {'dev_name': dev_name,
- 'vm_name': dom.name()})
-
- return disk[0]
-
-
-def get_vm_disk_info(dom, dev_name):
- # Retrieve disk xml and format return dict
- disk = get_device_node(dom, dev_name)
- if disk is None:
- return None
-
- try:
- source = disk.source
- if source is not None:
- src_type = disk.attrib['type']
- if src_type == 'network':
- host = source.host
- path = (source.attrib['protocol'] + '://' +
- host.attrib['name'] + ':' +
- host.attrib['port'] + source.attrib['name'])
- else:
- path = source.attrib[DEV_TYPE_SRC_ATTR_MAP[src_type]]
- except:
- path = ""
-
- return {'dev': dev_name,
- 'path': path,
- 'type': disk.attrib['device'],
- 'format': disk.driver.attrib['type'],
- 'bus': disk.target.attrib['bus']}
-
-
-def get_vm_disks(dom):
- xml = dom.XMLDesc(0)
- devices = objectify.fromstring(xml).devices
-
- storages = {}
- all_disks = devices.xpath("./disk[@device='disk']")
- all_disks.extend(devices.xpath("./disk[@device='cdrom']"))
- for disk in all_disks:
- storages[disk.target.attrib['dev']] = disk.target.attrib['bus']
-
- return storages
diff --git a/plugins/kimchi/xmlutils/graphics.py b/plugins/kimchi/xmlutils/graphics.py
deleted file mode 100644
index 2b4346a..0000000
--- a/plugins/kimchi/xmlutils/graphics.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from lxml.builder import E
-
-
-def get_graphics_xml(params):
- """
- <graphics type='%(type)s' autoport='yes' listen='%(listen)s'/>
-
- - For spice graphics:
-
- <channel type='spicevmc'>
- <target type='virtio' name='com.redhat.spice.0'/>
- </channel>
- """
- graphics = E.graphics(type=params['type'], autoport='yes',
- listen=params['listen'])
- graphics_xml = ET.tostring(graphics, encoding='utf-8', pretty_print=True)
-
- if params['type'] == 'vnc':
- return graphics_xml
-
- # For spice graphics, a channel also must be configured
- channel = E.channel(type='spicevmc')
- channel.append(E.target(type='virtio', name='com.redhat.spice.0'))
- channel_xml = ET.tostring(channel, encoding='utf-8', pretty_print=True)
- return graphics_xml + channel_xml
diff --git a/plugins/kimchi/xmlutils/interface.py b/plugins/kimchi/xmlutils/interface.py
deleted file mode 100644
index 0f3e848..0000000
--- a/plugins/kimchi/xmlutils/interface.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from distutils.version import LooseVersion
-from lxml.builder import E
-
-from .. import osinfo
-
-
-def get_iface_xml(params, arch=None, os_distro=None, os_version=None):
- """
- <interface type='network'>
- <source network='default'/>
- <model type='virtio'/>
- </interface>
- """
- interface = E.interface(type=params['type'])
- interface.append(E.source(network=params['network']))
-
- model = params.get('model')
-
- # no model specified; let's try querying osinfo
- if model is None:
- # if os_distro and os_version are invalid, nic_model will also be None
- model = osinfo.lookup(os_distro, os_version).get('nic_model')
-
- # only append 'model' to the XML if it's been specified as a parameter or
- # returned by osinfo.lookup; otherwise let libvirt use its default value
- if model is not None:
- interface.append(E.model(type=model))
-
- mac = params.get('mac', None)
- if mac is not None:
- interface.append(E.mac(address=mac))
-
- # Hack to disable vhost feature in Ubuntu LE and SLES LE (PPC)
- if arch == 'ppc64' and \
- ((os_distro == 'ubuntu' and
- LooseVersion(os_version) >= LooseVersion('14.04')) or
- (os_distro == 'sles' and
- LooseVersion(os_version) >= LooseVersion('12'))):
- interface.append(E.driver(name='qemu'))
-
- return ET.tostring(interface, encoding='utf-8', pretty_print=True)
diff --git a/plugins/kimchi/xmlutils/network.py b/plugins/kimchi/xmlutils/network.py
deleted file mode 100644
index c73aad9..0000000
--- a/plugins/kimchi/xmlutils/network.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ipaddr
-import lxml.etree as ET
-from lxml.builder import E
-
-
-# FIXME, do not support ipv6
-def _get_dhcp_elem(**kwargs):
- """
- <dhcp>
- <range start="192.168.122.100" end="192.168.122.254" />
- <host mac="00:16:3e:77:e2:ed" name="foo.test.com" ip="192.168.122.10" />
- <host mac="00:16:3e:3e:a9:1a" name="bar.test.com" ip="192.168.122.11" />
- </dhcp>
- """
- dhcp = E.dhcp()
- if 'range' in kwargs.keys():
- dhcp_range = E.range(start=kwargs['range']['start'],
- end=kwargs['range']['end'])
- dhcp.append(dhcp_range)
-
- if 'hosts' in kwargs.keys():
- for host in kwargs['hosts']:
- dhcp.append(E.host(mac=host['mac'],
- name=host['name'],
- ip=host['ip']))
-
- return dhcp if len(dhcp) > 0 else None
-
-
-def _get_ip_elem(**kwargs):
- """
- <ip address="192.168.152.1" netmask="255.255.255.0">
- <dhcp>
- <range start="192.168.152.2" end="192.168.152.254" />
- </dhcp>
- </ip>
- """
- if 'net' not in kwargs.keys():
- return None
-
- net = ipaddr.IPNetwork(kwargs['net'])
- ip = E.ip(address=str(net.ip), netmask=str(net.netmask))
-
- dhcp_params = kwargs.get('dhcp', {})
- dhcp = _get_dhcp_elem(**dhcp_params)
- if dhcp is not None:
- ip.append(dhcp)
-
- return ip
-
-
-def _get_forward_elem(**kwargs):
- """
- <forward mode='hostdev' dev='eth0' managed='yes'>
- </forward>
- """
- if "mode" in kwargs.keys() and kwargs['mode'] is None:
- return None
-
- forward = E.forward()
- if 'mode' in kwargs.keys():
- forward.set('mode', kwargs['mode'])
-
- if 'dev' in kwargs.keys():
- forward.set('dev', kwargs['dev'])
-
- if 'managed' in kwargs.keys():
- forward.set('managed', kwargs['managed'])
-
- return forward
-
-
-def to_network_xml(**kwargs):
- network = E.network(E.name(kwargs['name']))
- bridge = kwargs.get('bridge')
- if bridge:
- network.append(E.bridge(name=bridge))
-
- # None means is Isolated network, {} means default mode nat
- params = kwargs.get('forward', {"mode": None})
- forward = _get_forward_elem(**params)
- if forward is not None:
- network.append(forward)
-
- if 'net' in kwargs:
- network.append(_get_ip_elem(**kwargs))
-
- return ET.tostring(network)
-
-
-def create_vlan_tagged_bridge_xml(bridge, interface, vlan_id):
- vlan = E.vlan(E.interface(name=interface))
- vlan.set('tag', vlan_id)
- m = E.interface(
- E.start(mode='onboot'),
- E.bridge(
- E.interface(
- vlan,
- type='vlan',
- name='.'.join([interface, vlan_id]))),
- type='bridge',
- name=bridge)
- return ET.tostring(m)
diff --git a/plugins/kimchi/xmlutils/qemucmdline.py b/plugins/kimchi/xmlutils/qemucmdline.py
deleted file mode 100644
index 66238a7..0000000
--- a/plugins/kimchi/xmlutils/qemucmdline.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from lxml.builder import ElementMaker
-
-QEMU_NAMESPACE = "http://libvirt.org/schemas/domain/qemu/1.0"
-
-
-def get_qemucmdline_xml(args):
- """
- <qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
- <qemu:arg value='-drive'/>
- <qemu:arg value='file=%(path)s,if=none,id=drive-%(bus)s0-1-0,
- readonly=on,format=%(format)s'/>
- <qemu:arg value='-device'/>
- <qemu:arg value='%(bus)s-cd,bus=%(bus)s.1,unit=0,
- drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'/>
- </qemu:commandline>
- """
- EM = ElementMaker(namespace=QEMU_NAMESPACE,
- nsmap={'qemu': QEMU_NAMESPACE})
-
- root = EM.commandline()
- for opt, value in args.iteritems():
- root.append(EM.arg(value=opt))
- root.append(EM.arg(value=value))
-
- return ET.tostring(root, encoding='utf-8', pretty_print=True)
diff --git a/plugins/kimchi/yumparser.py b/plugins/kimchi/yumparser.py
deleted file mode 100644
index 74f9fa0..0000000
--- a/plugins/kimchi/yumparser.py
+++ /dev/null
@@ -1,283 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import subprocess
-from os import listdir
-from os.path import isfile, splitext
-
-
-class YumRepoObject(object):
-
- def __init__(self, repo_id, repofile):
- self.repo_id = repo_id
- self.name = None
- self.baseurl = None
- self.enabled = True
- self.gpgcheck = True
- self.gpgkey = None
- self.metalink = None
- self.mirrorlist = None
- self.repofile = repofile
- self.string_attrs = ['baseurl', 'gpgkey', 'name',
- 'metalink', 'mirrorlist']
- self.boolean_attrs = ['enabled', 'gpgcheck']
-
- def set_attribute(self, key, strvalue):
- if key in self.string_attrs:
- setattr(self, key, strvalue)
- elif key in self.boolean_attrs:
- setattr(self, key, (strvalue == '1'))
-
- def get_attribute_str(self, key):
- if key not in self.get_attributes():
- return None
-
- if key in self.boolean_attrs:
- str_value = '1' if getattr(self, key) is True else '0'
- else:
- str_value = getattr(self, key)
-
- if str_value is None:
- return None
-
- return key + '=' + str_value
-
- def get_attributes(self):
- return self.string_attrs + self.boolean_attrs
-
- def enable(self):
- self.enabled = True
-
- def disable(self):
- self.enabled = False
-
- def __str__(self):
- str_obj = '[' + self.repo_id + ']' + '\n'
- for key in self.get_attributes():
- if self.get_attribute_str(key) is not None:
- str_obj += self.get_attribute_str(key) + '\n'
- return str_obj
-
-
-def get_repo_files():
- def _is_repository_file(f):
- _, f_extension = splitext(f)
- return isfile(f) and (f_extension == '.repo')
-
- YUM_REPO_DIR = '/etc/yum.repos.d'
- return [YUM_REPO_DIR+'/'+f for f in listdir(YUM_REPO_DIR)
- if _is_repository_file(YUM_REPO_DIR+'/'+f)]
-
-
-def _ignore_line_repo_file(line):
- return line.startswith("#") or '=' not in line
-
-
-def _get_repos_from_file(repo_file):
- repos_from_file = {}
- current_repo = None
- current_repo_id = None
- with open(repo_file) as f:
- for line in f.readlines():
- line = line.strip()
- if line.startswith("["):
- if current_repo is not None:
- repos_from_file[current_repo_id] = current_repo
- current_repo_id = line.strip('[]')
- current_repo = YumRepoObject(current_repo_id, repo_file)
- continue
- if _ignore_line_repo_file(line):
- continue
- key, value = line.split('=', 1)
- key = key.strip()
- value = value.strip()
- current_repo.set_attribute(key, value)
-
- # add the last repo from file.
- if current_repo is not None:
- repos_from_file[current_repo_id] = current_repo
-
- return repos_from_file
-
-
-def get_yum_repositories():
- repo_files = get_repo_files()
- repos = {}
- for yum_repo in repo_files:
- repos.update(_get_repos_from_file(yum_repo))
-
- return repos
-
-
-def _retrieve_repo_line_index(data, repo):
- repo_entry = '[' + repo.repo_id + ']\n'
- try:
- repo_index = data.index(repo_entry)
- except:
- return None
- return repo_index
-
-
-def _update_repo_file_data(data, repo, repo_index):
- remaining_repo_attrs = repo.get_attributes()
-
- for i in range(repo_index + 1, len(data)):
- line = data[i].strip()
- if line.startswith('['):
- break
- if _ignore_line_repo_file(line):
- continue
- key, _ = line.split('=', 1)
- key = key.strip()
- attr_str = repo.get_attribute_str(key)
- if attr_str is None:
- continue
- remaining_repo_attrs.remove(key)
- data[i] = attr_str + '\n'
-
- for attr in remaining_repo_attrs:
- attr_str = repo.get_attribute_str(attr)
- if attr_str is None:
- continue
- data.insert(repo_index+1, attr_str + '\n')
-
- return data
-
-
-def write_repo_to_file(repo):
- with open(repo.repofile) as f:
- data = f.readlines()
-
- repo_index = _retrieve_repo_line_index(data, repo)
- if repo_index is None:
- return
-
- data = _update_repo_file_data(data, repo, repo_index)
-
- with open(repo.repofile, 'w') as f:
- f.writelines(data)
-
-
-def _get_last_line_repo(data, repo_index):
- stop_delete_index = None
- for i in range(repo_index+1, len(data)):
- line = data[i].strip()
- if line.startswith('['):
- stop_delete_index = i - 1
- break
- if stop_delete_index is None:
- stop_delete_index = len(data) - 1
-
- return stop_delete_index
-
-
-def _remove_repo_file_data(data, repo_index):
- last_line_repo = _get_last_line_repo(data, repo_index)
- for i in range(last_line_repo, repo_index - 1, -1):
- data.pop(i)
- return data
-
-
-def delete_repo_from_file(repo):
- with open(repo.repofile) as f:
- data = f.readlines()
-
- repo_index = _retrieve_repo_line_index(data, repo)
- if repo_index is None:
- return
-
- data = _remove_repo_file_data(data, repo_index)
-
- with open(repo.repofile, 'w') as f:
- f.writelines(data)
-
-
-class YumUpdatePackageObject(object):
-
- def __init__(self, name, arch, version, repo):
- self.name = name
- self.arch = arch
- self.version = version
- self.ui_from_repo = repo
-
-
-def _include_line_checkupdate_output(line):
- tokens = line.split()
-
- if len(tokens) != 3:
- return False
-
- if '.' not in tokens[0]:
- return False
-
- return True
-
-
-def _ignore_obsoleting_packages_in(output):
- out = ''
- for l in output.split('\n'):
- if 'Obsoleting ' in l:
- break
- out += l + '\n'
- return out
-
-
-def _filter_lines_checkupdate_output(output):
- if output is None:
- return []
-
- output = _ignore_obsoleting_packages_in(output)
-
- out = [l for l in output.split('\n')
- if _include_line_checkupdate_output(l)]
- return out
-
-
-def _get_yum_checkupdate_output():
- cmd = ['yum', 'check-update', '-d0']
- yum_update_cmd = subprocess.Popen(cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- out, error = yum_update_cmd.communicate()
- return_code = yum_update_cmd.returncode
- if return_code == 1:
- return None
-
- return out
-
-
-def get_yum_packages_list_update(checkupdate_output=None):
- if checkupdate_output is None:
- checkupdate_output = _get_yum_checkupdate_output()
-
- filtered_output = _filter_lines_checkupdate_output(checkupdate_output)
-
- packages = []
- for line in filtered_output:
- line = line.split()
- index = 0
- name_arch = line[index]
- index += 1
- version = line[index]
- index += 1
- repo = line[index]
- name, arch = name_arch.rsplit('.', 1)
- packages.append(YumUpdatePackageObject(name, arch, version, repo))
-
- return packages
diff --git a/plugins/sample/API.json b/plugins/sample/API.json
deleted file mode 100644
index 6ee7d91..0000000
--- a/plugins/sample/API.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-03/schema#",
- "title": "Plugin Sample API",
- "description": "Json schema for Wok's Sample Plugin API",
- "type": "object",
- "error": "SPAPI0001E",
- "properties": {
- "rectangles_create": {
- "type": "object",
- "error": "SPRET0003E",
- "properties": {
- "name": {
- "description": "The name of the new rectangle instance",
- "type": "string",
- "required": true,
- "error": "SPRET0004E"
- },
- "length": {
- "$ref": "#/definitions/positiveNumber",
- "required": true,
- "error": "SPRET0005E"
- },
- "width": {
- "$ref": "#/definitions/positiveNumber",
- "required": true,
- "error": "SPRET0006E"
- }
- }
- },
- "circles_create": {
- "type": "object",
- "error": "SPCIRC0003E",
- "properties": {
- "name": {
- "description": "The name of the new circle instance",
- "type": "string",
- "required": true,
- "error": "SPCIRC0004E"
- },
- "radius": {
- "$ref": "#/definitions/positiveNumber",
- "required": true,
- "error": "SPCIRC0005E"
- }
- }
- }
- },
- "definitions": {
- "positiveNumber": {
- "error": "SPAPI0002E",
- "type": "number",
- "minimum": 0,
- "exclusiveMinimum": true
- }
- }
-}
diff --git a/plugins/sample/Makefile.am b/plugins/sample/Makefile.am
deleted file mode 100644
index 876ab54..0000000
--- a/plugins/sample/Makefile.am
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = ui po
-
-EXTRA_DIST = API.json sample.conf.in $(wildcard *.py) config.status
-
-all-local:
- while read L && test -n "$$L"; do \
- dir=mo/$$L/LC_MESSAGES ; \
- $(MKDIR_P) $$dir ; \
- ln -sf ../../../po/$$L.gmo $$dir/sample.mo ; \
- done < po/LINGUAS
diff --git a/plugins/sample/__init__.py b/plugins/sample/__init__.py
deleted file mode 100644
index a3a8f05..0000000
--- a/plugins/sample/__init__.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-from cherrypy import expose
-
-
-from wok.config import PluginPaths
-from wok.control.base import Collection, Resource
-from wok.root import WokRoot
-
-
-from plugins.sample.i18n import messages
-from plugins.sample.model import Model
-
-
-model = Model()
-
-
-class Drawings(WokRoot):
- def __init__(self, wok_options):
- Resource.__init__(self, model)
- self.description = Description(model)
- self.rectangles = Rectangles(model)
- self.circles = Circles(model)
- self.paths = PluginPaths('sample')
- self.domain = 'sample'
- self.messages = messages
- self.api_schema = json.load(open(os.path.join(os.path.dirname(
- os.path.abspath(__file__)), 'API.json')))
-
- @expose
- def index(self):
- return 'This is a sample plugin for Wok'
-
-
-class Description(Resource):
- def __init__(self, model):
- super(Description, self).__init__(model)
-
- @property
- def data(self):
- return {'name': 'sample', 'version': '0.1'}
-
-
-class Circles(Collection):
- def __init__(self, model):
- super(Circles, self).__init__(model)
- self.resource = Circle
- self.admin_methods = ['POST', 'PUT']
-
-
-class Rectangles(Collection):
- def __init__(self, model):
- super(Rectangles, self).__init__(model)
- self.resource = Rectangle
- self.admin_methods = ['POST', 'PUT']
-
-
-class Circle(Resource):
- def __init__(self, model, ident):
- super(Circle, self).__init__(model, ident)
- self.update_params = ['radius']
-
- @property
- def data(self):
- ret = {'name': self.ident}
- ret.update(self.info)
- return ret
-
-
-class Rectangle(Resource):
- def __init__(self, model, ident):
- super(Rectangle, self).__init__(model, ident)
- self.update_params = ['length', 'width']
-
- @property
- def data(self):
- self.info.update({'name': self.ident})
- return self.info
diff --git a/plugins/sample/config.status b/plugins/sample/config.status
deleted file mode 120000
index 6cd6b4f..0000000
--- a/plugins/sample/config.status
+++ /dev/null
@@ -1 +0,0 @@
-../../config.status
\ No newline at end of file
diff --git a/plugins/sample/i18n.py b/plugins/sample/i18n.py
deleted file mode 100644
index 763970f..0000000
--- a/plugins/sample/i18n.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gettext
-
-_ = gettext.gettext
-
-
-messages = {
- "SPAPI0001E": _("Unkown parameter specified %(value)s"),
- "SPAPI0002E": _("The specified value %(value)s is not a positive number"),
-
- "SPCIRC0002E": _("Circle %(name)s does not exist"),
- "SPCIRC0003E": _("Specify name and radius to create a Circle"),
- "SPCIRC0004E": _("Circle name must be a string"),
- "SPCIRC0005E": _("Circle radius must be a positive number"),
-
- "SPRET0001E": _("Rectangle %(name)s already exists"),
- "SPRET0002E": _("Rectangle %(name)s does not exist"),
- "SPRET0003E": _("Specify name, length and width to create a Rectangle"),
- "SPRET0004E": _("Rectangle name must be a string"),
- "SPRET0005E": _("Rectangle length must be a positive number"),
- "SPRET0006E": _("Rectangle width must be a positive number"),
-}
diff --git a/plugins/sample/model.py b/plugins/sample/model.py
deleted file mode 100644
index 4ada648..0000000
--- a/plugins/sample/model.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.basemodel import BaseModel
-from wok.exception import InvalidOperation, NotFoundError
-
-
-class CirclesModel(object):
- def __init__(self):
- self._circles = {}
-
- def create(self, params):
- name = params['name']
- if name in self._circles:
- raise InvalidOperation("SPCIRCLE0001E", {'name': name})
- self._circles[name] = Circle(params['radius'])
- return name
-
- def get_list(self):
- return sorted(self._circles)
-
-
-class CircleModel(object):
- def __init__(self, parent_model):
- # Circel and Circles models are friends, it's OK to share _circles.
- self._circles = parent_model._circles
-
- def lookup(self, name):
- try:
- circle = self._circles[name]
- except KeyError:
- raise NotFoundError("SPCIRC0002E", {'name': name})
- return {'radius': circle.radius}
-
- def update(self, name, params):
- if name not in self._circles:
- raise NotFoundError("SPCIRC0002E", {'name': name})
- self._circles[name].radius = params['radius']
- return name
-
- def delete(self, name):
- try:
- del self._circles[name]
- except KeyError:
- pass
-
-
-class RectanglesModel(object):
- def __init__(self):
- self._rectangles = {}
-
- def create(self, params):
- name = params['name']
- if name in self._rectangles:
- raise InvalidOperation("SPRET0001E", {'name': name})
- self._rectangles[name] = Rectangle(params['length'], params['width'])
- return name
-
- def get_list(self):
- return sorted(self._rectangles)
-
-
-class RectangleModel(object):
- def __init__(self, parent_model):
- self._rectangles = parent_model._rectangles
-
- def lookup(self, name):
- try:
- rectangle = self._rectangles[name]
- except KeyError:
- raise NotFoundError("SPRET0002E", {'name': name})
- return {'length': rectangle.length, 'width': rectangle.width}
-
- def update(self, name, params):
- if name not in self._rectangles:
- raise NotFoundError("SPRET0002E", {'name': name})
- try:
- self._rectangles[name].length = params['length']
- except KeyError:
- pass
-
- try:
- self._rectangles[name].width = params['width']
- except KeyError:
- pass
- return name
-
- def delete(self, name):
- try:
- del self._rectangles[name]
- except KeyError:
- pass
-
-
-class Model(BaseModel):
- def __init__(self):
- circles = CirclesModel()
- circle = CircleModel(circles)
-
- rectangles = RectanglesModel()
- rectangle = RectangleModel(rectangles)
-
- return super(Model, self).__init__(
- [circle, circles, rectangle, rectangles])
-
-
-class Rectangle(object):
- def __init__(self, length, width):
- self.length = length
- self.width = width
-
-
-class Circle(object):
- def __init__(self, radius):
- self.radius = radius
diff --git a/plugins/sample/po/LINGUAS b/plugins/sample/po/LINGUAS
deleted file mode 100644
index 469998e..0000000
--- a/plugins/sample/po/LINGUAS
+++ /dev/null
@@ -1,3 +0,0 @@
-en_US
-pt_BR
-zh_CN
diff --git a/plugins/sample/po/Makefile.in.in b/plugins/sample/po/Makefile.in.in
deleted file mode 100644
index 52ab81c..0000000
--- a/plugins/sample/po/Makefile.in.in
+++ /dev/null
@@ -1,400 +0,0 @@
-# Makefile for PO directory in any package using GNU gettext.
-# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper at gnu.ai.mit.edu>
-#
-# This file can be copied and used freely without restrictions. It can
-# be used in projects which are not available under the GNU General Public
-# License but which still want to provide support for the GNU gettext
-# functionality.
-# Please note that the actual code of GNU gettext is covered by the GNU
-# General Public License and is *not* in the public domain.
-#
-# Origin: gettext-0.18
-GETTEXT_MACRO_VERSION = 0.18
-
-PACKAGE = @PACKAGE@
-VERSION = @VERSION@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-
-SHELL = /bin/sh
- at SET_MAKE@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-datarootdir = @datarootdir@
-datadir = @datadir@
-localedir = @prefix@/share/locale
-gettextsrcdir = $(datadir)/gettext/po
-
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-
-# We use $(MKDIR_P).
-# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
-# on invoking install-sh with the -d option, so your package should contain
-# install-sh as described under AC_PROG_INSTALL.
-mkinstalldirs = $(SHELL) @install_sh@ -d
-install_sh = $(SHELL) @install_sh@
-MKDIR_P = @MKDIR_P@
-MKDIR_P = @MKDIR_P@
-
-GMSGFMT_ = @GMSGFMT@
-GMSGFMT_no = @GMSGFMT@
-GMSGFMT_yes = @GMSGFMT_015@
-GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
-MSGFMT_ = @MSGFMT@
-MSGFMT_no = @MSGFMT@
-MSGFMT_yes = @MSGFMT_015@
-MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
-XGETTEXT_ = @XGETTEXT@
-XGETTEXT_no = @XGETTEXT@
-XGETTEXT_yes = @XGETTEXT_015@
-XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-MSGMERGE = msgmerge
-MSGMERGE_UPDATE = @MSGMERGE@ --update
-MSGINIT = msginit
-MSGCONV = msgconv
-MSGFILTER = msgfilter
-
-POFILES = @POFILES@
-GMOFILES = @GMOFILES@
-UPDATEPOFILES = @UPDATEPOFILES@
-DUMMYPOFILES = @DUMMYPOFILES@
-DISTFILES.common = Makefile.in.in \
-$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
-DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot \
-$(POFILES) $(GMOFILES) \
-$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
-
-POTFILES = \
-
-CATALOGS = @CATALOGS@
-
-# Makevars gets inserted here. (Don't remove this line!)
-
-.SUFFIXES:
-.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
-
-.po.mo:
- @echo "$(MSGFMT) -c -o $@ $<"; \
- $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
-
-.po.gmo:
- @lang=`echo $* | sed -e 's,.*/,,'`; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
- cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
-
-.sin.sed:
- sed -e '/^#/d' $< > t-$@
- mv t-$@ $@
-
-
-all: check-macro-version update-gmo all- at USE_NLS@
-
-all-yes: stamp-po
-all-no:
-
-# Ensure that the gettext macros and this Makefile.in.in are in sync.
-check-macro-version:
- @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
- || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
- exit 1; \
- }
-
-# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
-# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
-# we don't want to bother translators with empty POT files). We assume that
-# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
-# In this case, stamp-po is a nop (i.e. a phony target).
-
-# stamp-po is a timestamp denoting the last time at which the CATALOGS have
-# been loosely updated. Its purpose is that when a developer or translator
-# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
-# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
-# invocations of "make" will do nothing. This timestamp would not be necessary
-# if updating the $(CATALOGS) would always touch them; however, the rule for
-# $(POFILES) has been designed to not touch files that don't need to be
-# changed.
-stamp-po: $(srcdir)/$(DOMAIN).pot
- test ! -f $(srcdir)/$(DOMAIN).pot || \
- test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
- @test ! -f $(srcdir)/$(DOMAIN).pot || { \
- echo "touch stamp-po" && \
- echo timestamp > stamp-poT && \
- mv stamp-poT stamp-po; \
- }
-
-# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
-# otherwise packages like GCC can not be built if only parts of the source
-# have been downloaded.
-
-$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
- $(srcdir)/gen-pot $(POTFILES)
-
-# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
-# every "make" invocation, only create it when it is missing.
-# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
-$(srcdir)/$(DOMAIN).pot:
- $(MAKE) $(DOMAIN).pot-update
-
-# This target rebuilds a PO file if $(DOMAIN).pot has changed.
-# Note that a PO file is not touched if it doesn't need to be changed.
-$(POFILES): $(srcdir)/$(DOMAIN).pot
- @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
- if test -f "$(srcdir)/$${lang}.po"; then \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
- cd $(srcdir) \
- && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
- *) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
- esac; \
- }; \
- else \
- $(MAKE) $${lang}.po-create; \
- fi
-
-
-install:
-
-install-exec:
-install-data: install-data- at USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- for file in $(DISTFILES.common) Makevars.template; do \
- $(INSTALL_DATA) $(srcdir)/$$file \
- $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- for file in Makevars; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-install-data-no: all
-install-data-yes: all
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
- $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
- echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
- ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
- cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
- fi; \
- done; \
- done
-
-install-strip: install
-
-installdirs: installdirs-exec installdirs-data
-installdirs-exec:
-installdirs-data: installdirs-data- at USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- else \
- : ; \
- fi
-installdirs-data-no:
-installdirs-data-yes:
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- fi; \
- done; \
- done
-
-# Define this as empty until I found a useful application.
-installcheck:
-
-uninstall:
-
-uninstall-exec:
-uninstall-data: uninstall-data- at USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- for file in $(DISTFILES.common) Makevars.template; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-uninstall-data-no:
-uninstall-data-yes:
- catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- done; \
- done
-
-check: all
-
-info dvi ps pdf html tags TAGS ctags CTAGS ID:
-
-mostlyclean:
- rm -f remove-potcdate.sed
- rm -f stamp-poT
- rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
- rm -fr *.o
-
-clean: mostlyclean
-
-distclean: clean
- rm -f Makefile Makefile.in POTFILES *.mo
-
-maintainer-clean: distclean
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
- rm -f stamp-po $(GMOFILES)
-
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-dist distdir:
- $(MAKE) update-po
- @$(MAKE) dist2
-# This is a separate target because 'update-po' must be executed before.
-dist2: stamp-po $(DISTFILES)
- dists="$(DISTFILES)"; \
- if test "$(PACKAGE)" = "gettext-tools"; then \
- dists="$$dists Makevars.template"; \
- fi; \
- if test -f $(srcdir)/$(DOMAIN).pot; then \
- dists="$$dists $(DOMAIN).pot stamp-po"; \
- fi; \
- if test -f $(srcdir)/ChangeLog; then \
- dists="$$dists ChangeLog"; \
- fi; \
- for i in 0 1 2 3 4 5 6 7 8 9; do \
- if test -f $(srcdir)/ChangeLog.$$i; then \
- dists="$$dists ChangeLog.$$i"; \
- fi; \
- done; \
- if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
- for file in $$dists; do \
- if test -f $$file; then \
- cp -p $$file $(distdir) || exit 1; \
- else \
- cp -p $(srcdir)/$$file $(distdir) || exit 1; \
- fi; \
- done
-
-update-po: Makefile
- $(MAKE) $(DOMAIN).pot-update
- test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
- $(MAKE) update-gmo
-
-# General rule for creating PO files.
-
-.nop.po-create:
- @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
- echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
- exit 1
-
-# General rule for updating PO files.
-
-.nop.po-update:
- @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
- if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
- tmpdir=`pwd`; \
- echo "$$lang:"; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
- cd $(srcdir); \
- if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
- *) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
- esac; \
- }; then \
- if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
- rm -f $$tmpdir/$$lang.new.po; \
- else \
- if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
- :; \
- else \
- echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
- exit 1; \
- fi; \
- fi; \
- else \
- echo "msgmerge for $$lang.po failed!" 1>&2; \
- rm -f $$tmpdir/$$lang.new.po; \
- fi
-
-$(DUMMYPOFILES):
-
-update-gmo: Makefile $(GMOFILES)
- @:
-
-# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
-# because execution permission bits may not work on the current file system.
-# Use @SHELL@, which is the shell determined by autoconf for the use by its
-# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
-Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
- cd $(top_builddir) \
- && @SHELL@ ./config.status $(subdir)/$@.in po-directories
-
-force:
-
-# Tell versions [3.59,3.63) of GNU make not to export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/plugins/sample/po/Makevars b/plugins/sample/po/Makevars
deleted file mode 100644
index 60de3f1..0000000
--- a/plugins/sample/po/Makevars
+++ /dev/null
@@ -1,41 +0,0 @@
-# Makefile variables for PO directory in any package using GNU gettext.
-
-# Usually the message domain is the same as the package name.
-DOMAIN = sample
-
-# These two variables depend on the location of this directory.
-subdir = po
-top_builddir = ..
-
-# These options get passed to xgettext.
-XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
-
-# This is the copyright holder that gets inserted into the header of the
-# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
-# package. (Note that the msgstr strings, extracted from the package's
-# sources, belong to the copyright holder of the package.) Translators are
-# expected to transfer the copyright for their translations to this person
-# or entity, or to disclaim their copyright. The empty string stands for
-# the public domain; in this case the translators are expected to disclaim
-# their copyright.
-COPYRIGHT_HOLDER =
-
-# This is the email address or URL to which the translators shall report
-# bugs in the untranslated strings:
-# - Strings which are not entire sentences, see the maintainer guidelines
-# in the GNU gettext documentation, section 'Preparing Strings'.
-# - Strings which use unclear terms or require additional context to be
-# understood.
-# - Strings which make invalid assumptions about notation of date, time or
-# money.
-# - Pluralisation problems.
-# - Incorrect English spelling.
-# - Incorrect formatting.
-# It can be your email address, or a mailing list address where translators
-# can write to without being subscribed, or the URL of a web page through
-# which the translators can contact you.
-MSGID_BUGS_ADDRESS = kimchi-devel at ovirt.org
-
-# This is the list of locale categories, beyond LC_MESSAGES, for which the
-# message catalogs shall be used. It is usually empty.
-EXTRA_LOCALE_CATEGORIES =
diff --git a/plugins/sample/po/POTFILES.in b/plugins/sample/po/POTFILES.in
deleted file mode 100644
index 7dbfb6c..0000000
--- a/plugins/sample/po/POTFILES.in
+++ /dev/null
@@ -1,2 +0,0 @@
-# List of source files which contain translatable strings.
-plugins/sample/ui/pages/*.tmpl
diff --git a/plugins/sample/po/en_US.po b/plugins/sample/po/en_US.po
deleted file mode 100644
index 207d3c3..0000000
--- a/plugins/sample/po/en_US.po
+++ /dev/null
@@ -1,21 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the kimchi package.
-# shhfeng <shaohef at linux.vnet.ibm.com>, 2014.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.2.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: 2014-05-17 02:08+0800\n"
-"Last-Translator: shhfeng <shaohef at linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"Language: en_US\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ASCII\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: pygettext.py 1.5\n"
-
-msgid "SampleTab"
-msgstr "SampleTab"
diff --git a/plugins/sample/po/gen-pot b/plugins/sample/po/gen-pot
deleted file mode 100755
index c1cfb8f..0000000
--- a/plugins/sample/po/gen-pot
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-for src in $@; do
- if [ ${src: -3} == ".py" ]; then
- cat $src
- else
- cat $src | cheetah compile -
- fi
-done | xgettext --no-location -o sample.pot -L Python -
diff --git a/plugins/sample/po/pt_BR.po b/plugins/sample/po/pt_BR.po
deleted file mode 100644
index 8519d74..0000000
--- a/plugins/sample/po/pt_BR.po
+++ /dev/null
@@ -1,24 +0,0 @@
-# Portuguese translations for kimchi package
-# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the kimchi package.
-# shhfeng <shaohef at linux.vnet.ibm.com>, 2014.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.2.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: 2014-05-17 02:09+0800\n"
-"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
-"Language-Team: Aline Manera <alinefm at br.ibm.com>\n"
-"Language: pt_BR\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: pygettext.py 1.5\n"
-"X-Poedit-Country: Brazil\n"
-"X-Poedit-Language: Portuguese\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-msgid "SampleTab"
-msgstr "Tab de exemplo"
diff --git a/plugins/sample/po/sample.pot b/plugins/sample/po/sample.pot
deleted file mode 100644
index 458ffe9..0000000
--- a/plugins/sample/po/sample.pot
+++ /dev/null
@@ -1,21 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
-"Language-Team: LANGUAGE <LL at li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-msgid "SampleTab"
-msgstr ""
diff --git a/plugins/sample/po/zh_CN.po b/plugins/sample/po/zh_CN.po
deleted file mode 100644
index 04b2501..0000000
--- a/plugins/sample/po/zh_CN.po
+++ /dev/null
@@ -1,24 +0,0 @@
-# Chinese translations for kimchi package
-# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the kimchi package.
-# shhfeng <shaohef at linux.vnet.ibm.com>, 2014.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.2.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: 2014-05-17 02:10+0800\n"
-"Last-Translator: shhfeng <shaohef at linux.vnet.ibm.com>\n"
-"Language-Team: Chinese (simplified)\n"
-"Language: zh_CN\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: pygettext.py 1.5\n"
-"X-Poedit-Country: CHINA\n"
-"X-Poedit-Language: Chinese\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-msgid "SampleTab"
-msgstr "ç¤ºä¾æ ç¾"
diff --git a/plugins/sample/sample.conf.in b/plugins/sample/sample.conf.in
deleted file mode 100644
index 9da33e1..0000000
--- a/plugins/sample/sample.conf.in
+++ /dev/null
@@ -1,27 +0,0 @@
-[wok]
-enable = @ENABLE_SAMPLE@
-plugin_class = "Drawings"
-uri = "/plugins/sample"
-
-[/]
-tools.nocache.on = True
-tools.trailing_slash.on = False
-tools.sessions.on = True
-tools.sessions.name = 'wok'
-tools.sessions.httponly = True
-tools.sessions.locking = 'explicit'
-tools.sessions.storage_type = 'ram'
-
-[/description]
-tools.wokauth.on = True
-
-[/rectangles]
-tools.wokauth.on = True
-
-[/circles]
-tools.wokauth.on = True
-
-[/help]
-tools.staticdir.on = True
-tools.nocache.on = True
-tools.staticdir.dir = wok.config.PluginPaths('sample').ui_dir + '/pages/help'
diff --git a/plugins/sample/ui/Makefile.am b/plugins/sample/ui/Makefile.am
deleted file mode 100644
index 37fec98..0000000
--- a/plugins/sample/ui/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = config js pages
-
-
diff --git a/plugins/sample/ui/config/Makefile.am b/plugins/sample/ui/config/Makefile.am
deleted file mode 100644
index cf9e09e..0000000
--- a/plugins/sample/ui/config/Makefile.am
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = tab-ext.xml
-
diff --git a/plugins/sample/ui/config/tab-ext.xml b/plugins/sample/ui/config/tab-ext.xml
deleted file mode 100644
index aff0d14..0000000
--- a/plugins/sample/ui/config/tab-ext.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<tabs-ext>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>SampleTab 1</title>
- <path>plugins/sample/sample-tab1.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>SampleTab 2</title>
- <path>plugins/sample/sample-tab2.html</path>
- </tab>
-</tabs-ext>
diff --git a/plugins/sample/ui/css/.gitignore b/plugins/sample/ui/css/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/images/.gitignore b/plugins/sample/ui/images/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/js/.gitignore b/plugins/sample/ui/js/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/js/Makefile.am b/plugins/sample/ui/js/Makefile.am
deleted file mode 100644
index 4d536ae..0000000
--- a/plugins/sample/ui/js/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = util.js
diff --git a/plugins/sample/ui/js/util.js b/plugins/sample/ui/js/util.js
deleted file mode 100644
index 7689a81..0000000
--- a/plugins/sample/ui/js/util.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-
-sample = {};
-
-sample.description = function(suc, err){
- wok.requestJSON({
- url : 'plugins/sample/description',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err || function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
-};
diff --git a/plugins/sample/ui/libs/.gitignore b/plugins/sample/ui/libs/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/pages/Makefile.am b/plugins/sample/ui/pages/Makefile.am
deleted file mode 100644
index 3da95a2..0000000
--- a/plugins/sample/ui/pages/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = i18n.json.tmpl sample-tab1.html.tmpl sample-tab2.html.tmpl
diff --git a/plugins/sample/ui/pages/help/en_US/sample-tab1.html b/plugins/sample/ui/pages/help/en_US/sample-tab1.html
deleted file mode 100644
index 7122124..0000000
--- a/plugins/sample/ui/pages/help/en_US/sample-tab1.html
+++ /dev/null
@@ -1 +0,0 @@
-Help page for TAB 1 of Wok's Sample plugin.
diff --git a/plugins/sample/ui/pages/help/en_US/sample-tab2.html b/plugins/sample/ui/pages/help/en_US/sample-tab2.html
deleted file mode 100644
index 1bfe448..0000000
--- a/plugins/sample/ui/pages/help/en_US/sample-tab2.html
+++ /dev/null
@@ -1 +0,0 @@
-Help page for TAB 2 of Wok's Sample plugin.
diff --git a/plugins/sample/ui/pages/i18n.json.tmpl b/plugins/sample/ui/pages/i18n.json.tmpl
deleted file mode 100644
index 737bb39..0000000
--- a/plugins/sample/ui/pages/i18n.json.tmpl
+++ /dev/null
@@ -1,26 +0,0 @@
-#*
- * Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang)
-#silent _ = t.gettext
-#silent _t = t.gettext
-{
- "SampleTab": "$_("SampleTab")"
-}
diff --git a/plugins/sample/ui/pages/sample-tab1.html.tmpl b/plugins/sample/ui/pages/sample-tab1.html.tmpl
deleted file mode 100644
index 4354d81..0000000
--- a/plugins/sample/ui/pages/sample-tab1.html.tmpl
+++ /dev/null
@@ -1,30 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-<!DOCTYPE html>
-<html>
-<script type="text/javascript" src="plugins/sample/js/util.js"></script>
-<body>
- <div id="samplebody"/>
-</body>
-<script>
- sample.description(function(r){
- \$("#samplebody").html("name: " + r.name + " version: " + r.version);
- });
-</script>
-</html>
diff --git a/plugins/sample/ui/pages/sample-tab2.html.tmpl b/plugins/sample/ui/pages/sample-tab2.html.tmpl
deleted file mode 100644
index 4354d81..0000000
--- a/plugins/sample/ui/pages/sample-tab2.html.tmpl
+++ /dev/null
@@ -1,30 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-<!DOCTYPE html>
-<html>
-<script type="text/javascript" src="plugins/sample/js/util.js"></script>
-<body>
- <div id="samplebody"/>
-</body>
-<script>
- sample.description(function(r){
- \$("#samplebody").html("name: " + r.name + " version: " + r.version);
- });
-</script>
-</html>
diff --git a/src/wok/plugins/Makefile.am b/src/wok/plugins/Makefile.am
new file mode 100644
index 0000000..21a6ece
--- /dev/null
+++ b/src/wok/plugins/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = sample
+
+plugins_PYTHON = \
+ __init__.py
+
+pluginsdir = $(pythondir)/wok/plugins
diff --git a/src/wok/plugins/__init__.py b/src/wok/plugins/__init__.py
new file mode 100644
index 0000000..0539a76
--- /dev/null
+++ b/src/wok/plugins/__init__.py
@@ -0,0 +1,18 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/src/wok/plugins/kimchi/.gitignore b/src/wok/plugins/kimchi/.gitignore
new file mode 100644
index 0000000..1dae610
--- /dev/null
+++ b/src/wok/plugins/kimchi/.gitignore
@@ -0,0 +1,37 @@
+*.pyc
+*~
+i18n/mo/*
+log
+data
+mo
+autom4te.cache
+Makefile
+Makefile.in
+aclocal.m4
+build-aux/compile
+build-aux/config.guess
+build-aux/config.sub
+build-aux/install-sh
+build-aux/missing
+build-aux/py-compile
+configure
+config.log
+config.py
+config.status
+contrib/DEBIAN/control
+contrib/kimchi.spec.fedora
+contrib/kimchi.spec.suse
+contrib/make-deb.sh
+*.min.css
+*.min.js
+*.gmo
+stamp-po
+kimchi-*.tar.gz
+tests/run_tests.sh
+tests/test_config.py
+po/POTFILES
+po/gen-pot
+*.orig
+*.rej
+*.pem
+ui/pages/help/*/*.html
diff --git a/src/wok/plugins/kimchi/API.json b/src/wok/plugins/kimchi/API.json
new file mode 100644
index 0000000..f1f58ff
--- /dev/null
+++ b/src/wok/plugins/kimchi/API.json
@@ -0,0 +1,836 @@
+{
+ "$schema": "http://json-schema.org/draft-03/schema#",
+ "title": "Kimchi API",
+ "description": "Json schema for Kimchi API",
+ "type": "object",
+ "kimchitype": {
+ "graphics": {
+ "description": "Configure graphics parameters for the new VM",
+ "type": "object",
+ "properties": {
+ "type": {
+ "enum": ["spice", "vnc"],
+ "error": "KCHVM0014E"
+ },
+ "listen": {
+ "error": "KCHVM0015E",
+ "type": [
+ {
+ "type": "string",
+ "format": "ip-address"
+ },
+ {
+ "type": "string",
+ "format": "ipv6"
+ }
+ ]
+ }
+ }
+ },
+ "cpu_info": {
+ "description": "Configure CPU specifics for a VM.",
+ "type": "object",
+ "properties": {
+ "topology": {
+ "description": "Configure the guest CPU topology.",
+ "type": "object",
+ "properties": {
+ "sockets": {
+ "type": "integer",
+ "required": true,
+ "minimum": 1,
+ "error": "KCHTMPL0026E"
+ },
+ "cores": {
+ "type": "integer",
+ "required": true,
+ "minimum": 1,
+ "error": "KCHTMPL0026E"
+ },
+ "threads": {
+ "type": "integer",
+ "required": true,
+ "minimum": 1,
+ "error": "KCHTMPL0026E"
+ }
+ }
+ }
+ }
+ }
+ },
+ "properties": {
+ "debugreports_create": {
+ "type": "object",
+ "error": "KCHDR0006E",
+ "properties": {
+ "name": {
+ "description": "The name for the debug report file.",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]*$",
+ "error": "KCHDR0007E"
+ }
+ }
+ },
+ "debugreport_update": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "New name of debug report",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]*$",
+ "error": "KCHDR0007E"
+ }
+ },
+ "additionalProperties": false
+ },
+ "storagepools_create": {
+ "type": "object",
+ "error": "KCHPOOL0026E",
+ "properties": {
+ "name": {
+ "description": "The name of the Storage Pool",
+ "type": "string",
+ "minLength": 1,
+ "pattern": "^[^/]*$",
+ "required": true,
+ "error": "KCHPOOL0016E"
+ },
+ "type": {
+ "description": "The type of the defined Storage Pool",
+ "type": "string",
+ "pattern": "^dir|netfs|logical|kimchi-iso|iscsi|scsi$",
+ "required": true,
+ "error": "KCHPOOL0017E"
+ },
+ "path": {
+ "description": "The path of the defined Storage Pool",
+ "type": "string",
+ "error": "KCHPOOL0018E"
+ },
+ "source": {
+ "description": "Dictionary containing source information of the pool",
+ "type": "object",
+ "properties": {
+ "host": {
+ "description": "IP or hostname of server for a pool backed from a remote host",
+ "type": "string",
+ "error": "KCHPOOL0019E"
+ },
+ "path": {
+ "description": "Export path on NFS server for NFS pool",
+ "type": "string",
+ "error": "KCHPOOL0018E"
+ },
+ "devices": {
+ "description": "Array of devices to be used in the Storage Pool",
+ "type": "array",
+ "minItems": 1,
+ "uniqueItems": true,
+ "error": "KCHPOOL0021E",
+ "items": {
+ "description": "Full path of the block device node",
+ "type": "string",
+ "error": "KCHPOOL0020E"
+ }
+ },
+ "target": {
+ "description": "Target IQN of an iSCSI pool",
+ "type": "string",
+ "error": "KCHPOOL0022E"
+ },
+ "port": {
+ "description": "Listening port of a remote storage server",
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 65535,
+ "error": "KCHPOOL0023E"
+ },
+ "adapter_name": {
+ "description": "SCSI host name",
+ "type": "string",
+ "error": "KCHPOOL0030E"
+ },
+ "auth": {
+ "description": "Storage back-end authentication information",
+ "type": "object",
+ "properties": {
+ "username": {
+ "description": "Login username of the iSCSI target",
+ "type": "string",
+ "error": "KCHPOOL0024E"
+ },
+ "password": {
+ "description": "Login password of the iSCSI target",
+ "type": "string",
+ "error": "KCHPOOL0025E"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "storagepool_update": {
+ "type": "object",
+ "properties": {
+ "autostart": {
+ "description": "Set autostart value of the pool",
+ "type": "boolean"
+ },
+ "disks": {
+ "description": "List of disks/partitions to be added",
+ "type": "array",
+ "items": { "type": "string" },
+ "minItems": 1,
+ "uniqueItems": true
+ }
+ },
+ "additionalProperties": false
+ },
+ "storagevolumes_create": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the Storage Volume",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHVOL0013E"
+ },
+ "capacity": {
+ "description": "The total size (MiB) of the storage volume",
+ "type": "number",
+ "minimum": 1,
+ "error": "KCHVOL0020E"
+ },
+ "upload": {
+ "description": "When the storage volume will be uploaded",
+ "type": "boolean",
+ "error": "KCHVOL0025E"
+ },
+ "allocation": {
+ "description": "The size(MiB) of allocation when create the storage volume",
+ "type": "number",
+ "minimum": 1,
+ "error": "KCHVOL0014E"
+ },
+ "format": {
+ "description": "The format of the volume",
+ "type": "string",
+ "pattern": "^(|bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
+ "error": "KCHVOL0015E"
+ },
+ "url": {
+ "description": "The remote URL of the storage volume",
+ "type": "string",
+ "pattern": "^(http|ftp)[s]?://",
+ "error": "KCHVOL0021E"
+ }
+ }
+ },
+ "storagevolume_update": {
+ "type": "object",
+ "properties": {
+ "chunk": {
+ "description": "Upload storage volume chunk",
+ "error": "KCHVOL0024E",
+ "required": true
+ },
+ "chunk_size": {
+ "description": "Chunk size of uploaded storage volume",
+ "type": "string",
+ "error": "KCHVOL0024E",
+ "required": true
+ }
+ },
+ "additionalProperties": false
+ },
+ "vms_create": {
+ "type": "object",
+ "error": "KCHVM0016E",
+ "properties": {
+ "name": {
+ "description": "The name of the new VM",
+ "type": "string",
+ "pattern": "^[^/]*$",
+ "error": "KCHVM0011E"
+ },
+ "template": {
+ "description": "The URI of a template to use when building a VM",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/templates/(.*?)/?$",
+ "required": true,
+ "error": "KCHVM0012E"
+ },
+ "storagepool": {
+ "description": "Assign a specefic Storage Pool to the new VM",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHVM0013E"
+ },
+ "graphics": { "$ref": "#/kimchitype/graphics" }
+ }
+ },
+ "vm_update": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "New name of VM",
+ "type": "string",
+ "pattern": "^[^/]*$",
+ "minLength": 1,
+ "error": "KCHVM0011E"
+ },
+ "users": {
+ "description": "Array of users who have permission to the VM",
+ "type": "array",
+ "uniqueItems": true,
+ "error": "KCHVM0023E",
+ "items": {
+ "description": "User name",
+ "type": "string",
+ "error": "KCHVM0024E"
+ }
+ },
+ "groups": {
+ "description": "Array of groups who have permission to the VM",
+ "type": "array",
+ "uniqueItems": true,
+ "error": "KCHVM0025E",
+ "items": {
+ "description": "Group name",
+ "type": "string",
+ "error": "KCHVM0026E"
+ }
+ },
+ "graphics": {
+ "description": "Graphics information from guest",
+ "type": "object",
+ "properties": {
+ "passwd": {
+ "description": "New graphics password.",
+ "type": "string",
+ "error": "KCHVM0031E"
+ },
+ "passwdValidTo": {
+ "description": "Life time for the graphics password.",
+ "type": "number",
+ "error": "KCHVM0032E"
+ }
+ }
+ },
+ "cpus": {
+ "description": "The new number of virtual CPUs for the VM",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0012E"
+ },
+ "memory": {
+ "description": "The new amount (MB) of memory for the VM",
+ "type": "integer",
+ "minimum": 512,
+ "error": "KCHTMPL0013E"
+ }
+ },
+ "additionalProperties": false
+ },
+ "networks_create": {
+ "type": "object",
+ "error": "KCHNET0016E",
+ "properties": {
+ "name": {
+ "description": "The name of the new network",
+ "type": "string",
+ "minLength": 1,
+ "pattern": "^[^/\"]*$",
+ "required": true,
+ "error": "KCHNET0011E"
+ },
+ "connection": {
+ "description": "Specifies how this network should be connected to the other networks",
+ "type": "string",
+ "pattern": "^isolated|nat|bridge$",
+ "required": true,
+ "error": "KCHNET0012E"
+ },
+ "subnet": {
+ "description": "Network segment in slash-separated format with ip address and prefix or netmask",
+ "type": "string",
+ "error": "KCHNET0013E"
+ },
+ "interface": {
+ "description": "The name of a network interface on the host",
+ "type": "string",
+ "error": "KCHNET0014E"
+ },
+ "vlan_id": {
+ "description": "Network's VLAN ID",
+ "type": "integer",
+ "maximum": 4094,
+ "minimum": 1,
+ "error": "KCHNET0015E"
+ }
+ }
+ },
+ "vmifaces_create": {
+ "type": "object",
+ "error": "KCHVMIF0007E",
+ "properties": {
+ "type": {
+ "description": "The type of VM network interface that libvirt supports",
+ "type": "string",
+ "pattern": "^network$",
+ "required": true,
+ "error": "KCHVMIF0004E"
+ },
+ "network": {
+ "description": "the name of one available network",
+ "minLength": 1,
+ "type": "string",
+ "error": "KCHVMIF0005E"
+ },
+ "model": {
+ "description": "model of emulated network interface card",
+ "type": "string",
+ "pattern": "^ne2k_pci|i82551|i82557b|i82559er|rtl8139|e1000|pcnet|virtio$",
+ "error": "KCHVMIF0006E"
+ },
+ "mac": {
+ "description": "Network Interface Card MAC address",
+ "type": "string",
+ "pattern": "(^$)|^(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$)",
+ "error": "KCHVMIF0010E"
+ }
+ }
+ },
+ "vmiface_update": {
+ "type": "object",
+ "error": "KCHVMIF0008E",
+ "properties": {
+ "mac": {
+ "description": "Network Interface Card MAC address",
+ "type": "string",
+ "pattern": "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$",
+ "error": "KCHVMIF0010E"
+ }
+ }
+ },
+ "templates_create": {
+ "type": "object",
+ "error": "KCHTMPL0016E",
+ "properties": {
+ "name": {
+ "description": "The name of the template",
+ "type": "string",
+ "pattern": "^[^ ]+( +[^ ]+)*$",
+ "minLength": 1,
+ "error": "KCHTMPL0008E"
+ },
+ "icon": {
+ "description": "The template icon path",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/images/",
+ "error": "KCHTMPL0009E"
+ },
+ "os_distro": {
+ "description": "Distribution name of the Operating System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0010E"
+ },
+ "os_version": {
+ "description": "Version of the Operating System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0011E"
+ },
+ "cpus": {
+ "description": "Number of CPUs for the template",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0012E"
+ },
+ "memory": {
+ "description": "Memory (MB) for the template",
+ "type": "integer",
+ "minimum": 512,
+ "error": "KCHTMPL0013E"
+ },
+ "cdrom": {
+ "description": "Path for cdrom",
+ "type": "string",
+ "pattern": "^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "error": "KCHTMPL0014E"
+ },
+ "disks": {
+ "description": "List of disks",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "index": {
+ "description": "Index of the disk",
+ "type": "integer",
+ "minimum": 0
+ },
+ "size": {
+ "description": "Size (GB) of the disk",
+ "type": "number",
+ "minimum": 1,
+ "error": "KCHTMPL0022E"
+ },
+ "base": {
+ "description": "Base image of the disk",
+ "type": "string",
+ "pattern": "^/.+$",
+ "error": "KCHTMPL0023E"
+ }
+
+ }
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "storagepool": {
+ "description": "Location of the storage pool",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHTMPL0015E"
+ },
+ "networks": {
+ "description": "list of which networks will be assigned to the new VM.",
+ "type": "array",
+ "items": { "type": "string" },
+ "error": "KCHTMPL0017E"
+ },
+ "folder": {
+ "description": "Folder",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "graphics": { "$ref": "#/kimchitype/graphics" },
+ "cpu_info": { "$ref": "#/kimchitype/cpu_info" }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "storageservers_get_list": {
+ "type": "object",
+ "properties": {
+ "_target_type": {
+ "description": "List storage servers of given type",
+ "type": "string",
+ "pattern": "^netfs|iscsi$"
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "storagetargets_get_list": {
+ "type": "object",
+ "properties": {
+ "_target_type": {
+ "description": "List storage servers of given type",
+ "type": "string",
+ "pattern": "^netfs|iscsi$"
+ },
+ "_server_port": {
+ "description": "the port of iscsi storage servers",
+ "type": "string",
+ "pattern": "^[0-9]{1,5}$"
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "vmstorages_create": {
+ "type": "object",
+ "error": "KCHVMSTOR0012E",
+ "properties": {
+ "type": {
+ "description": "The storage type",
+ "type": "string",
+ "pattern": "^cdrom|disk$",
+ "required": true,
+ "error": "KCHVMSTOR0002E"
+ },
+ "pool": {
+ "description": "Storage pool name disk image locate in",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHVMSTOR0012E"
+ },
+ "vol": {
+ "description": "Storage volume name of disk image",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHVMSTOR0012E"
+ },
+ "path": {
+ "description": "Path of iso image file or disk mount point",
+ "type": "string",
+ "pattern": "^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "error": "KCHVMSTOR0003E"
+ }
+ }
+ },
+ "vmstorage_update": {
+ "type": "object",
+ "error": "KCHVMSTOR0013E",
+ "properties": {
+ "path": {
+ "description": "Path of iso image file or disk mount point",
+ "type": "string",
+ "pattern": "^(|(/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "required": true,
+ "error": "KCHVMSTOR0003E"
+ }
+ },
+ "additionalProperties": false
+ },
+ "template_update": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the template",
+ "type": "string",
+ "pattern": "^[^ ]+( +[^ ]+)*$",
+ "minLength": 1,
+ "error": "KCHTMPL0008E"
+ },
+ "icon": {
+ "description": "The template icon path",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/images/",
+ "error": "KCHTMPL0009E"
+ },
+ "os_distro": {
+ "description": "Distribution name of the Operating System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0010E"
+ },
+ "os_version": {
+ "description": "Version of the Operating System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0011E"
+ },
+ "cpus": {
+ "description": "Number of CPUs for the template",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0012E"
+ },
+ "memory": {
+ "description": "Memory (MB) for the template",
+ "type": "integer",
+ "minimum": 512,
+ "error": "KCHTMPL0013E"
+ },
+ "cdrom": {
+ "description": "Path for cdrom",
+ "type": "string",
+ "pattern": "^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "error": "KCHTMPL0014E"
+ },
+ "disks": {
+ "description": "List of disks",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "index": {
+ "description": "Index of the disk",
+ "type": "integer",
+ "minimum": 0
+ },
+ "size": {
+ "description": "Size (GB) of the disk",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0022E"
+ },
+ "format": {
+ "description": "Type of the image of the disk",
+ "type": "string",
+ "pattern": "^(bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
+ "error": "KCHTMPL0027E"
+ }
+ }
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "storagepool": {
+ "description": "Location of the storage pool",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHTMPL0015E"
+ },
+ "networks": {
+ "description": "list of which networks will be assigned to the new VM.",
+ "type": "array",
+ "items": { "type": "string" },
+ "error": "KCHTMPL0017E"
+ },
+ "folder": {
+ "description": "Folder",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "graphics": { "$ref": "#/kimchitype/graphics" },
+ "cpu_info": { "$ref": "#/kimchitype/cpu_info" }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "repositories_create": {
+ "type": "object",
+ "properties": {
+ "repo_id": {
+ "description": "Repository ID used for YUM repository.",
+ "type": "string",
+ "error": "KCHREPOS0001E"
+ },
+ "baseurl": {
+ "description": "URL to the directory where the repodata directory of a repository is located. Can be an http://, ftp:// or file:// URL.",
+ "type": "string",
+ "error": "KCHREPOS0002E"
+ },
+ "config": {
+ "description": "Dictionary containing repository configuration",
+ "type": "object",
+ "error": "KCHREPOS0003E",
+ "properties": {
+ "dist": {
+ "description": "Distribution to DEB repository",
+ "type": "string",
+ "error": "KCHREPOS0004E"
+ },
+ "comps": {
+ "description": "List of components to DEB repository",
+ "type": "array",
+ "error": "KCHREPOS0005E",
+ "uniqueItems": true,
+ "items": {
+ "description": "Component name",
+ "type": "string",
+ "error": "KCHREPOS0006E"
+ }
+ },
+ "repo_name": {
+ "description": "YUM repository name",
+ "type": "string",
+ "error": "KCHREPOS0023E"
+ },
+ "mirrorlist": {
+ "description": "URL to a file containing a list of baseurls",
+ "type": "string",
+ "error": "KCHREPOS0007E"
+ },
+ "metalink": {
+ "description": "URL to a metalink file for the repomd.xml",
+ "type": "string",
+ "error": "KCHREPOS0029E"
+ }
+ }
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "repository_update": {
+ "type": "object",
+ "properties": {
+ "baseurl": {
+ "description": "URL to the directory where the repodata directory of a repository is located. Can be an http://, ftp:// or file:// URL.",
+ "type": "string",
+ "error": "KCHREPOS0002E"
+ },
+ "config": {
+ "description": "Dictionary containing repository configuration",
+ "type": "object",
+ "error": "KCHREPOS0003E",
+ "properties": {
+ "dist": {
+ "description": "Distribution to DEB repository",
+ "type": "string",
+ "error": "KCHREPOS0004E"
+ },
+ "comps": {
+ "description": "List of components to DEB repository",
+ "type": "array",
+ "error": "KCHREPOS0005E",
+ "uniqueItems": true,
+ "items": {
+ "description": "Component name",
+ "type": "string",
+ "error": "KCHREPOS0006E"
+ }
+ },
+ "repo_name": {
+ "description": "Human-readable string describing the YUM repository.",
+ "type": "string",
+ "error": "KCHREPOS0008E"
+ },
+ "mirrorlist": {
+ "description": "URL to a file containing a list of baseurls for YUM repository",
+ "type": "string",
+ "error": "KCHREPOS0007E"
+ },
+ "gpgcheck": {
+ "description": "Indicates if a GPG signature check on the packages gotten from repository should be performed.",
+ "type": "boolean",
+ "error": "KCHREPOS0009E"
+ },
+ "gpgkey": {
+ "description": "URL pointing to the ASCII-armored GPG key file for the repository.",
+ "type": "string",
+ "error": "KCHREPOS0010E"
+ }
+ }
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "devices_get_list": {
+ "type": "object",
+ "properties": {
+ "_cap": {
+ "description": "List specific type of device",
+ "type": "string",
+ "pattern": "^fc_host|net|pci|scsi|scsi_host|storage|system|usb|usb_device$",
+ "error": "KCHDEVS0001E"
+ },
+ "_passthrough": {
+ "description": "List only devices eligible to be assigned to guest",
+ "type": "string",
+ "pattern": "^true|false$",
+ "error": "KCHDEVS0002E"
+ },
+ "_passthrough_affected_by": {
+ "description": "List the affected devices in the same group of a certain device to be assigned to guest",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]+$",
+ "error": "KCHDEVS0003E"
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "vmhostdevs_create": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Then name of the device to assign to VM",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]+$",
+ "required": true,
+ "error": "KCHVMHDEV0004E"
+ }
+ },
+ "error": "KCHAPI0001E"
+ }
+ }
+}
diff --git a/src/wok/plugins/kimchi/INSTALL b/src/wok/plugins/kimchi/INSTALL
new file mode 100644
index 0000000..63bf076
--- /dev/null
+++ b/src/wok/plugins/kimchi/INSTALL
@@ -0,0 +1,369 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
+Inc.
+
+ Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package. Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below. The lack of an optional feature in a given package is not
+necessarily a bug. More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+ The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package, generally using the just-built uninstalled binaries.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation. When installing into a prefix owned by root, it is
+ recommended that the package be configured and built as a regular
+ user, and only the `make install' phase executed with root
+ privileges.
+
+ 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ this time using the binaries in their final installed location.
+ This target does not install anything. Running this target as a
+ regular user, particularly if the prior `make install' required
+ root privileges, verifies that the installation completed
+ correctly.
+
+ 6. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 7. Often, you can also type `make uninstall' to remove the installed
+ files again. In practice, not all packages have tested that
+ uninstallation works correctly, even though it is required by the
+ GNU Coding Standards.
+
+ 8. Some packages, particularly those that use Automake, provide `make
+ distcheck', which can by used by developers to test that all other
+ targets like `make install' and `make uninstall' work correctly.
+ This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'. This
+is known as a "VPATH" build.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them. In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+ The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+ The first method involves providing an override variable for each
+affected directory. For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'. Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated. The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the `DESTDIR' variable. For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names. The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters. On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+ Some packages offer the ability to configure how verbose the
+execution of `make' will be. For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved. Use GNU `make'
+instead.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+ On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+ On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS
+ KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
diff --git a/src/wok/plugins/kimchi/Makefile.am b/src/wok/plugins/kimchi/Makefile.am
new file mode 100644
index 0000000..49c835e
--- /dev/null
+++ b/src/wok/plugins/kimchi/Makefile.am
@@ -0,0 +1,161 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = contrib control distros.d docs model po tests ui xmlutils
+
+kimchi_PYTHON = $(filter-out config.py, $(wildcard *.py))
+
+nodist_kimchi_PYTHON = config.py
+
+if WITH_SPICE
+WITH_SPICE=yes
+else
+WITH_SPICE=no
+endif
+
+wokdir = $(pythondir)/wok
+kimchidir = $(pythondir)/wok/plugins/kimchi
+
+confdir = $(sysconfdir)/wok/plugins.d
+dist_conf_DATA = kimchi.conf template.conf
+
+AUTOMAKE_OPTIONS = foreign
+
+ACLOCAL_AMFLAGS = --install -I m4
+
+EXTRA_DIST = \
+ config.rpath \
+ API.json \
+ autogen.sh \
+ COPYING.ASL2 \
+ COPYING.LGPL \
+ CONTRIBUTE.md \
+ VERSION \
+ build-aux/pkg-version \
+ config.py.in \
+ $(NULL)
+
+
+PEP8_BLACKLIST = *config.py,*i18n.py,*tests/test_config.py
+
+I18N_FILES = ./i18n.py \
+ $(NULL)
+
+check-local:
+ contrib/check_i18n.py $(I18N_FILES)
+ find . -path './.git' -prune -type f -o \
+ -name '*.py' -o -name '*.py.in' | xargs $(PYFLAKES) | \
+ while read LINE; do echo "$$LINE"; false; done
+
+ $(PEP8) --version
+ $(PEP8) --filename '*.py,*.py.in' --exclude="$(PEP8_BLACKLIST)" .
+
+
+# Link built mo files in the source tree to enable use of translations from
+# within the source tree
+all-local:
+ while read L && test -n "$$L"; do \
+ dir=mo/$$L/LC_MESSAGES ; \
+ $(MKDIR_P) $$dir ; \
+ ln -sf ../../../po/$$L.gmo $$dir/kimchi.mo ; \
+ done < po/LINGUAS
+
+do_substitution = \
+ sed -e 's,[@]prefix[@],$(prefix),g' \
+ -e 's,[@]datadir[@],$(datadir),g' \
+ -e 's,[@]sysconfdir[@],$(sysconfdir),g' \
+ -e 's,[@]localstatedir[@],$(localstatedir),g' \
+ -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \
+ -e 's,[@]wokdir[@],$(wokdir),g' \
+ -e 's,[@]kimchidir[@],$(kimchidir),g' \
+ -e 's,[@]kimchiversion[@],$(PACKAGE_VERSION),g' \
+ -e 's,[@]kimchirelease[@],$(PACKAGE_RELEASE),g' \
+ -e 's,[@]withspice[@],$(WITH_SPICE),g'
+
+config.py: config.py.in Makefile
+ $(do_substitution) < $(srcdir)/config.py.in > config.py
+
+
+#
+# Packaging helpers
+#
+
+install-deb: install
+ cp -R $(top_srcdir)/contrib/DEBIAN $(DESTDIR)/
+ mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
+ mkdir -p $(DESTDIR)/var/lib/kimchi/debugreports
+ mkdir -p $(DESTDIR)/var/lib/kimchi/screenshots
+ mkdir -p $(DESTDIR)/var/lib/kimchi/isos
+
+
+deb: contrib/make-deb.sh
+ $(top_srcdir)/contrib/make-deb.sh
+
+kimchi.spec: contrib/kimchi.spec.fedora contrib/kimchi.spec.suse
+ @if test -e /etc/redhat-release; then \
+ ln -sf contrib/kimchi.spec.fedora $@ ; \
+ elif test -e /etc/SuSE-release; then \
+ ln -sf contrib/kimchi.spec.suse $@ ; \
+ else \
+ echo "Unable to select a spec file for RPM build" ; \
+ /bin/false ; \
+ fi
+
+rpm: dist kimchi.spec
+ $(MKDIR_P) rpm/BUILD rpm/RPMS rpm/SOURCES rpm/SPECS rpm/SRPMS
+ cp $(top_srcdir)/kimchi.spec rpm/SPECS/kimchi.spec
+ cp $(DIST_ARCHIVES) rpm/SOURCES
+ rpmbuild -ba --define "_topdir `pwd`/rpm" rpm/SPECS/kimchi.spec
+
+fedora-rpm: contrib/kimchi.spec.fedora
+ ln -sf contrib/kimchi.spec.fedora kimchi.spec
+ $(MAKE) rpm
+
+suse-rpm: contrib/kimchi.spec.suse
+ ln -sf contrib/kimchi.spec.suse kimchi.spec
+ $(MAKE) rpm
+
+ChangeLog:
+ @if test -d .git; then \
+ $(top_srcdir)/build-aux/genChangelog --release > $@; \
+ fi
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(kimchidir)
+ $(INSTALL_DATA) API.json $(DESTDIR)$(kimchidir)/API.json
+ mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
+ mkdir -p $(DESTDIR)/var/lib/kimchi/{debugreports,isos,screenshots}
+
+uninstall-local:
+ $(RM) $(DESTDIR)$(kimchidir)/API.json
+ $(RM) -rf $(DESTDIR)/var/lib/kimchi
+
+VERSION:
+ @if test -d .git; then \
+ git describe --abbrev=0 > $@; \
+ fi
+
+.PHONY: deb install-deb rpm fedora-rpm suse-rpm ChangeLog VERSION
+
+
+clean-local:
+ rm -rf mo rpm
+
+BUILT_SOURCES = config.py
+CLEANFILES = config.py kimchi.spec `find "$(top_srcdir)" -type f -name "*.pyc" -print`
diff --git a/src/wok/plugins/kimchi/README.md b/src/wok/plugins/kimchi/README.md
new file mode 120000
index 0000000..0e01b43
--- /dev/null
+++ b/src/wok/plugins/kimchi/README.md
@@ -0,0 +1 @@
+docs/README.md
\ No newline at end of file
diff --git a/src/wok/plugins/kimchi/VERSION b/src/wok/plugins/kimchi/VERSION
new file mode 100644
index 0000000..bc80560
--- /dev/null
+++ b/src/wok/plugins/kimchi/VERSION
@@ -0,0 +1 @@
+1.5.0
diff --git a/src/wok/plugins/kimchi/__init__.py b/src/wok/plugins/kimchi/__init__.py
new file mode 100644
index 0000000..9330044
--- /dev/null
+++ b/src/wok/plugins/kimchi/__init__.py
@@ -0,0 +1,21 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from root import KimchiRoot
+__all__ = [KimchiRoot]
diff --git a/src/wok/plugins/kimchi/autogen.sh b/src/wok/plugins/kimchi/autogen.sh
new file mode 100755
index 0000000..0f22dba
--- /dev/null
+++ b/src/wok/plugins/kimchi/autogen.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+aclocal
+automake --add-missing
+autoreconf
+
+if [ ! -f "configure" ]; then
+ echo "Failed to generate configure script. Check to make sure autoconf, "
+ echo "automake, and other build dependencies are properly installed."
+ exit 1
+fi
+
+if [ "x$1" == "x--system" ]; then
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
+else
+ if [ $# -gt 0 ]; then
+ ./configure $@
+ else
+ ./configure --prefix=/usr/local
+ fi
+fi
diff --git a/src/wok/plugins/kimchi/build-aux/config.rpath b/src/wok/plugins/kimchi/build-aux/config.rpath
new file mode 100644
index 0000000..17298f2
--- /dev/null
+++ b/src/wok/plugins/kimchi/build-aux/config.rpath
@@ -0,0 +1,672 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2010 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ darwin*)
+ case $cc_basename in
+ xlc*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ newsos6)
+ ;;
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ pgcc | pgf77 | pgf90)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ wl='-Wl,'
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we cannot use
+ # them.
+ ld_shlibs=no
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | k*bsd*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if test "$GCC" = yes ; then
+ :
+ else
+ case $cc_basename in
+ xlc*)
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ library_names_spec='$libname.a'
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd1*)
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ nto-qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/src/wok/plugins/kimchi/build-aux/genChangelog b/src/wok/plugins/kimchi/build-aux/genChangelog
new file mode 100755
index 0000000..803f24e
--- /dev/null
+++ b/src/wok/plugins/kimchi/build-aux/genChangelog
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# This script is based on code from the Kandan project:
+# https://github.com/kandanapp/kandan/blob/master/gen-changelog.sh
+
+echo "CHANGELOG"
+echo "========="
+echo
+git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags | tac |grep -v '^$' | while read TAG ; do
+ if [ $NEXT ]; then
+ echo "#### [$NEXT] ####"
+ elif [ "$1" != "--release" ]; then
+ echo "#### [Current] ####"
+ else
+ NEXT=$TAG
+ continue
+ fi
+ GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)" $TAG..$NEXT
+ NEXT=$TAG
+ echo; echo
+done
+FIRST=$(git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags | head -1)
+
+echo "#### [$FIRST] ####"
+GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)" $FIRST
diff --git a/src/wok/plugins/kimchi/build-aux/pkg-version b/src/wok/plugins/kimchi/build-aux/pkg-version
new file mode 100755
index 0000000..749cf6c
--- /dev/null
+++ b/src/wok/plugins/kimchi/build-aux/pkg-version
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# Copyright 2008-2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# tags and output versions:
+# - 4.9.0 => 4.9.0 (upstream clean)
+# - 4.9.0-1 => 4.9.0 (downstream clean)
+# - 4.9.0-2-g34e62f => 4.9.0 (upstream dirty)
+# - 4.9.0-1-2-g34e62f => 4.9.0 (downstream dirty)
+AWK_VERSION='
+ BEGIN { FS="-" }
+ /^[0-9]/ {
+ print $1
+ }'
+
+# tags and output releases:
+# - 4.9.0 => 0 (upstream clean)
+# - 4.9.0-1 => 1 (downstream clean)
+# - 4.9.0-2-g34e62f1 => 2.git34e62f1 (upstream dirty)
+# - 4.9.0-1-2-g34e62f1 => 1.2.git34e62f1 (downstream dirty)
+AWK_RELEASE='
+ BEGIN { FS="-"; OFS="." }
+ /^[0-9]/ {
+ if (NF == 1) print 0
+ else if (NF == 2) print $2
+ else if (NF == 3) print $2, "git" substr($3, 2)
+ else if (NF == 4) print $2, $3, "git" substr($4, 2)
+ }'
+
+if [ ! -d .git ]; then
+ PKG_VERSION=`cat VERSION`
+else
+ PKG_VERSION=`git describe --tags --match "[0-9]*" || cat VERSION`
+fi
+
+if test "x$1" = "x--full"; then
+ echo $PKG_VERSION | tr -d '[:space:]'
+elif test "x$1" = "x--version"; then
+ echo $PKG_VERSION | awk "$AWK_VERSION" | tr -cd '[:alnum:].'
+elif test "x$1" = "x--release"; then
+ echo $PKG_VERSION | awk "$AWK_RELEASE" | tr -cd '[:alnum:].'
+else
+ echo "usage: $0 [--full|--version|--release]"
+ exit 1
+fi
diff --git a/src/wok/plugins/kimchi/config.py.in b/src/wok/plugins/kimchi/config.py.in
new file mode 100644
index 0000000..6ae0ccd
--- /dev/null
+++ b/src/wok/plugins/kimchi/config.py.in
@@ -0,0 +1,144 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import libvirt
+import os
+import platform
+import threading
+
+from wok.config import CACHEEXPIRES, PluginConfig, PluginPaths
+from wok.xmlutils.utils import xpath_get_text
+
+kimchiLock = threading.Lock()
+
+__with_spice__ = "@withspice@"
+
+# Storage pool constant for read-only pool types
+READONLY_POOL_TYPE = ['iscsi', 'scsi', 'mpath']
+
+
+def get_distros_store():
+ return os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d')
+
+
+def get_debugreports_path():
+ return os.path.join(PluginPaths('kimchi').state_dir, 'debugreports')
+
+
+def get_screenshot_path():
+ return os.path.join(PluginPaths('kimchi').state_dir, 'screenshots')
+
+
+def find_qemu_binary(find_emulator=False):
+ try:
+ connect = libvirt.open(None)
+ except Exception, e:
+ raise Exception("Unable to get qemu binary location: %s" % e)
+ try:
+ xml = connect.getCapabilities()
+
+ # On Little Endian system, the qemu binary is
+ # qemu-system-ppc64, not qemu-system-ppc64le as expected
+ arch = platform.machine()
+ if arch == "ppc64le":
+ arch = "ppc64"
+
+ if find_emulator:
+ expr = "/capabilities/guest/arch[@name='%s']\
+ /emulator" % arch
+ else:
+ expr = "/capabilities/guest/arch[@name='%s']\
+ /domain[@type='kvm']/emulator" % arch
+ res = xpath_get_text(xml, expr)
+ location = res[0]
+ except Exception, e:
+ raise Exception("Unable to get qemu binary location: %s" % e)
+ finally:
+ connect.close()
+ return location
+
+
+class KimchiPaths(PluginPaths):
+
+ def __init__(self):
+ super(KimchiPaths, self).__init__('kimchi')
+ self.spice_file = os.path.join(self.ui_dir,
+ 'spice-html5/pages/spice_auto.html')
+
+ if __with_spice__ == 'yes':
+ self.spice_dir = self.add_prefix('ui/spice-html5')
+ elif os.path.exists('@datadir@/spice-html5'):
+ self.spice_dir = '@datadir@/spice-html5'
+ else:
+ self.spice_dir = '/usr/share/spice-html5'
+
+ if os.path.exists('@datadir@/novnc'):
+ self.novnc_dir = '@datadir@/novnc'
+ else:
+ self.novnc_dir = '/usr/share/novnc'
+
+ if self.installed:
+ self.spice_css_file = os.path.join(self.spice_dir, 'spice.css')
+ else:
+ self.spice_css_file = os.path.join(self.spice_dir, 'css/spice.css')
+
+
+kimchiPaths = KimchiPaths()
+
+
+class KimchiConfig(PluginConfig):
+ def __init__(self):
+ super(KimchiConfig, self).__init__('kimchi')
+
+ static_config = {
+ '/novnc': {'type': 'dir',
+ 'path': kimchiPaths.novnc_dir},
+ '/spice-html5': {'type': 'dir',
+ 'path': kimchiPaths.spice_dir},
+ '/spice_auto.html': {'type': 'file',
+ 'path': kimchiPaths.spice_file},
+ '/spice-html5/spice.css': {'type': 'file',
+ 'path': kimchiPaths.spice_css_file}}
+
+ custom_config = {}
+ for uri, data in static_config.iteritems():
+ custom_config[uri] = {'tools.nocache.on': True,
+ 'tools.wokauth.on': True}
+ path = data['path']
+ if data['type'] == 'dir':
+ custom_config[uri].update({'tools.staticdir.on': True,
+ 'tools.staticdir.dir': path})
+ elif data['type'] == 'file':
+ custom_config[uri].update({'tools.staticfile.on': True,
+ 'tools.staticfile.filename': path})
+
+ for dirname in ('css', 'js', 'images'):
+ custom_config['/' + dirname] = {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': os.path.join(kimchiPaths.ui_dir,
+ dirname),
+ 'tools.wokauth.on': False,
+ 'tools.nocache.on': False}
+ if dirname != 'images':
+ custom_config['/' + dirname].update({
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES})
+
+ self.update(custom_config)
diff --git a/src/wok/plugins/kimchi/config.rpath b/src/wok/plugins/kimchi/config.rpath
new file mode 100644
index 0000000..17298f2
--- /dev/null
+++ b/src/wok/plugins/kimchi/config.rpath
@@ -0,0 +1,672 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2010 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ darwin*)
+ case $cc_basename in
+ xlc*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ newsos6)
+ ;;
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ pgcc | pgf77 | pgf90)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ wl='-Wl,'
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # Samuel A. Falvo II <kc5tja at dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we cannot use
+ # them.
+ ld_shlibs=no
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | k*bsd*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if test "$GCC" = yes ; then
+ :
+ else
+ case $cc_basename in
+ xlc*)
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ library_names_spec='$libname.a'
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd1*)
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ nto-qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/src/wok/plugins/kimchi/configure.ac b/src/wok/plugins/kimchi/configure.ac
new file mode 100644
index 0000000..adab45b
--- /dev/null
+++ b/src/wok/plugins/kimchi/configure.ac
@@ -0,0 +1,119 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+AC_INIT([kimchi], [m4_esyscmd([./build-aux/pkg-version --version])])
+
+AC_SUBST([PACKAGE_VERSION],
+ [m4_esyscmd([./build-aux/pkg-version --version])])
+
+AC_SUBST([PACKAGE_RELEASE],
+ [m4_esyscmd([./build-aux/pkg-version --release])])
+
+# Testing for version and release
+AS_IF([test "x$PACKAGE_VERSION" = x],
+ AC_MSG_ERROR([package version not defined]))
+AS_IF([test "x$PACKAGE_RELEASE" = x],
+ AC_MSG_ERROR([package release not defined]))
+
+AC_CONFIG_AUX_DIR([build-aux])
+AM_INIT_AUTOMAKE([-Wno-portability])
+AM_PATH_PYTHON([2.6])
+AC_PATH_PROG([PEP8], [pep8], [/usr/bin/pep8])
+AC_PYTHON_MODULE([unittest])
+AC_SUBST([HAVE_PYMOD_UNITTEST])
+AC_SUBST([PYTHON_VERSION])
+AM_GNU_GETTEXT([external])
+AM_GNU_GETTEXT_VERSION([0.10])
+AC_PATH_PROG([CHEETAH], [cheetah], [/usr/bin/cheetah])
+
+# Checking for pyflakes
+AC_PATH_PROG([PYFLAKES], [pyflakes])
+if test "x$PYFLAKES" = "x"; then
+ AC_MSG_WARN([pyflakes not found])
+fi
+
+AC_ARG_ENABLE(
+ [sample],
+ [AS_HELP_STRING(
+ [--enable-sample],
+ [enable sample plugin @<:@default=no@:>@]
+ )],
+ ,
+ [enable_sample="no"]
+)
+
+if test "${enable_sample}" = "yes"; then
+AC_SUBST([ENABLE_SAMPLE], [True])
+else
+AC_SUBST([ENABLE_SAMPLE], [False])
+fi
+
+AC_ARG_WITH(
+ [spice-html5],
+ [AS_HELP_STRING([--with-spice-html5],
+ [Build Kimchi with spice-html5 @<:@default=no@:>@])],
+ ,
+ [with_spice_html5="no"]
+)
+AM_CONDITIONAL([WITH_SPICE], [test "x$with_spice_html5" = xyes])
+
+AC_CONFIG_FILES([
+ po/Makefile.in
+ po/gen-pot
+ Makefile
+ docs/Makefile
+ distros.d/Makefile
+ control/Makefile
+ control/vm/Makefile
+ model/Makefile
+ ui/Makefile
+ ui/config/Makefile
+ ui/css/Makefile
+ ui/images/Makefile
+ ui/images/theme-default/Makefile
+ ui/js/Makefile
+ ui/spice-html5/Makefile
+ ui/spice-html5/css/Makefile
+ ui/spice-html5/pages/Makefile
+ ui/spice-html5/thirdparty/Makefile
+ ui/pages/Makefile
+ ui/pages/help/Makefile
+ ui/pages/help/en_US/Makefile
+ ui/pages/help/de_DE/Makefile
+ ui/pages/help/es_ES/Makefile
+ ui/pages/help/fr_FR/Makefile
+ ui/pages/help/it_IT/Makefile
+ ui/pages/help/ja_JP/Makefile
+ ui/pages/help/ko_KR/Makefile
+ ui/pages/help/pt_BR/Makefile
+ ui/pages/help/ru_RU/Makefile
+ ui/pages/help/zh_CN/Makefile
+ ui/pages/help/zh_TW/Makefile
+ contrib/Makefile
+ contrib/DEBIAN/Makefile
+ contrib/DEBIAN/control
+ contrib/kimchi.spec.fedora
+ contrib/kimchi.spec.suse
+ tests/Makefile
+ xmlutils/Makefile
+],[
+ chmod +x po/gen-pot
+])
+
+AC_OUTPUT
diff --git a/src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am b/src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am
new file mode 100644
index 0000000..ca89552
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am
@@ -0,0 +1,17 @@
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+CLEANFILES = control
diff --git a/src/wok/plugins/kimchi/contrib/DEBIAN/control.in b/src/wok/plugins/kimchi/contrib/DEBIAN/control.in
new file mode 100644
index 0000000..dc153d8
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/DEBIAN/control.in
@@ -0,0 +1,30 @@
+Package: @PACKAGE_NAME@
+Version: @PACKAGE_VERSION@
+Section: base
+Priority: optional
+Architecture: all
+Depends: wok,
+ python-imaging,
+ python-configobj,
+ websockify,
+ novnc,
+ python-jsonschema (>= 1.3.0),
+ python-libvirt,
+ gettext,
+ libvirt-bin,
+ nfs-common,
+ qemu-kvm,
+ python-parted,
+ python-psutil (>= 0.6.0),
+ python-ethtool,
+ sosreport,
+ python-ipaddr,
+ python-lxml,
+ open-iscsi,
+ python-guestfs,
+ libguestfs-tools,
+ spice-html5
+Build-Depends: libxslt,
+ python-lxml
+Maintainer: Aline Manera <alinefm at br.ibm.com>
+Description: Kimchi web application
diff --git a/src/wok/plugins/kimchi/contrib/Makefile.am b/src/wok/plugins/kimchi/contrib/Makefile.am
new file mode 100644
index 0000000..5001191
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/Makefile.am
@@ -0,0 +1,34 @@
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = DEBIAN
+
+EXTRA_DIST = \
+ check_i18n.py \
+ kimchi.spec.fedora.in \
+ make-deb.sh.in \
+ $(NULL)
+
+make-deb.sh: make-deb.sh.in $(top_builddir)/config.status
+ $(AM_V_GEN)sed \
+ -e 's|[@]PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
+ -e 's|[@]PACKAGE_RELEASE[@]|$(PACKAGE_RELEASE)|g' \
+ < $< > $@-t && \
+ chmod a+x $@-t && \
+ mv $@-t $@
+BUILT_SOURCES = make-deb.sh
+
+CLEANFILES = kimchi.spec.fedora kimchi.spec.suse kimchi.spec make-deb.sh
diff --git a/src/wok/plugins/kimchi/contrib/check_i18n.py b/src/wok/plugins/kimchi/contrib/check_i18n.py
new file mode 100755
index 0000000..6a2603c
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/check_i18n.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python2
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import imp
+import os
+import re
+import sys
+
+
+# Match all conversion specifier with mapping key
+PATTERN = re.compile(r'''%\([^)]+\) # Mapping key
+ [#0\-+]? # Conversion flags (optional)
+ (\d+|\*)? # Minimum field width (optional)
+ (\.(\d+|\*))? # Precision (optional)
+ [lLh]? # Length modifier (optional)
+ [cdeEfFgGioursxX%] # Conversion type''',
+ re.VERBOSE)
+BAD_PATTERN = re.compile(r"%\([^)]*?\)")
+
+
+def load_i18n_module(i18nfile):
+ path = os.path.dirname(i18nfile)
+ mname = i18nfile.replace("/", "_").rstrip(".py")
+ mobj = imp.find_module("i18n", [path])
+ return imp.load_module(mname, *mobj)
+
+
+def check_string_formatting(messages):
+ for k, v in messages.iteritems():
+ if BAD_PATTERN.findall(PATTERN.sub(" ", v)):
+ print "bad i18n string formatting:"
+ print " %s: %s" % (k, v)
+ exit(1)
+
+
+def check_obsolete_messages(path, messages):
+ def find_message_key(path, k):
+ for root, dirs, files in os.walk(path):
+ for f in files:
+ fname = os.path.join(root, f)
+ if (not fname.endswith("i18n.py") and fname.endswith(".py") or
+ fname.endswith(".json")):
+ with open(fname) as f:
+ string = "".join(f.readlines())
+ if k in string:
+ return True
+ return False
+
+ for k in messages.iterkeys():
+ if not find_message_key(path, k):
+ print " %s is obsolete, it is no longer in use" % k
+ exit(1)
+
+
+def main():
+ print "Checking for invalid i18n string..."
+ for f in sys.argv[1:]:
+ messages = load_i18n_module(f).messages
+ check_string_formatting(messages)
+ check_obsolete_messages(os.path.dirname(f), messages)
+ print "Checking for invalid i18n string successfully"
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in b/src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in
new file mode 100644
index 0000000..0db3d7e
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in
@@ -0,0 +1,119 @@
+Name: kimchi
+Version: @PACKAGE_VERSION@
+Release: @PACKAGE_RELEASE@%{?dist}
+Summary: Kimchi server application
+BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
+BuildArch: noarch
+Group: System Environment/Base
+License: LGPL/ASL2
+Source0: %{name}-%{version}.tar.gz
+Requires: wok
+Requires: qemu-kvm
+Requires: gettext
+Requires: libvirt
+Requires: libvirt-python
+Requires: libvirt-daemon-config-network
+Requires: python-websockify
+Requires: python-configobj
+Requires: novnc
+Requires: python-imaging
+Requires: pyparted
+Requires: python-psutil >= 0.6.0
+Requires: python-jsonschema >= 1.3.0
+Requires: python-ethtool
+Requires: sos
+Requires: python-ipaddr
+Requires: python-lxml
+Requires: nfs-utils
+Requires: iscsi-initiator-utils
+Requires: python-libguestfs
+Requires: libguestfs-tools
+BuildRequires: libxslt
+BuildRequires: python-lxml
+
+%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
+Requires: spice-html5
+%endif
+
+%if 0%{?fedora} >= 15 || 0%{?rhel} >= 7
+%global with_systemd 1
+%endif
+
+%if 0%{?rhel} == 6
+Requires: python-ordereddict
+Requires: python-imaging
+BuildRequires: python-unittest2
+%endif
+
+%description
+Web application to manage KVM/Qemu virtual machines
+
+
+%prep
+%setup
+
+
+%build
+%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
+%configure
+%else
+%configure --with-spice-html5
+%endif
+make
+
+
+%install
+rm -rf %{buildroot}
+make DESTDIR=%{buildroot} install
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%attr(-,root,root)
+%{python_sitelib}/wok/plugins/kimchi/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
+%{python_sitelib}/wok/plugins/kimchi/model/*.py*
+%{python_sitelib}/wok/plugins/kimchi/API.json
+%{python_sitelib}/wok/plugins/kimchi/
+%{_datadir}/kimchi/doc/API.md
+%{_datadir}/kimchi/doc/README.md
+%{_datadir}/kimchi/doc/README-federation.md
+%{_datadir}/kimchi/doc/kimchi-guest.png
+%{_datadir}/kimchi/doc/kimchi-templates.png
+%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
+%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
+%{_datadir}/wok/plugins/kimchi/ui/
+%{_datadir}/wok/plugins/kimchi
+%{_sysconfdir}/wok/plugins.d/kimchi.conf
+%{_sysconfdir}/wok/plugins.d/template.conf
+%{_sysconfdir}/kimchi/distros.d/debian.json
+%{_sysconfdir}/kimchi/distros.d/fedora.json
+%{_sysconfdir}/kimchi/distros.d/opensuse.json
+%{_sysconfdir}/kimchi/distros.d/ubuntu.json
+%{_sysconfdir}/kimchi/distros.d/gentoo.json
+%{_sysconfdir}/kimchi/
+%{_sharedstatedir}/kimchi/debugreports/
+%{_sharedstatedir}/kimchi/isos/
+%{_sharedstatedir}/kimchi/screenshots/
+%{_sharedstatedir}/kimchi/vnc-tokens/
+%{_sharedstatedir}/kimchi/
+
+
+%changelog
+* Thu Jun 18 2015 Lucio Correia <luciojhc at linux.vnet.ibm.com> 1.6
+- Run kimchi as a plugin
+
+* Thu Feb 26 2015 Frédéric Bonnard <frediz at linux.vnet.ibm.com> 1.4.0
+- Add man page for kimchid
+
+* Tue Feb 11 2014 CrÃstian Viana <vianac at linux.vnet.ibm.com> 1.1.0
+- Add help pages and XSLT dependency
+
+* Tue Jul 16 2013 Adam Litke <agl at us.ibm.com> 0.1.0-1
+- Adapted for autotools build
+
+* Thu Apr 04 2013 Aline Manera <alinefm at br.ibm.com> 0.0-1
+- First build
diff --git a/src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in b/src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in
new file mode 100644
index 0000000..e466961
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in
@@ -0,0 +1,107 @@
+Name: kimchi
+Version: @PACKAGE_VERSION@
+Release: @PACKAGE_RELEASE@%{?dist}
+Summary: Kimchi server application
+BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
+BuildArch: noarch
+Group: System Environment/Base
+License: LGPL/ASL2
+Source0: %{name}-%{version}.tar.gz
+Requires: wok
+Requires: kvm
+Requires: gettext-tools
+Requires: libvirt
+Requires: libvirt-python
+Requires: libvirt-daemon-config-network
+Requires: python-websockify
+Requires: python-configobj
+Requires: novnc
+Requires: python-imaging
+Requires: python-parted
+Requires: python-psutil >= 0.6.0
+Requires: python-jsonschema >= 1.3.0
+Requires: python-ethtool
+Requires: python-ipaddr
+Requires: python-lxml
+Requires: python-xml
+Requires: nfs-client
+Requires: open-iscsi
+Requires: python-libguestfs
+Requires: guestfs-tools
+BuildRequires: libxslt-tools
+BuildRequires: python-lxml
+
+%if 0%{?suse_version} == 1100
+Requires: python-ordereddict
+%endif
+
+%if 0%{?suse_version} > 1140
+%global with_systemd 1
+%endif
+
+%description
+Web application to manage KVM/Qemu virtual machines
+
+%prep
+%setup
+
+%build
+%configure --with-spice-html5
+make
+
+%install
+rm -rf %{buildroot}
+make DESTDIR=%{buildroot} install
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%attr(-,root,root)
+%{python_sitelib}/wok/plugins/kimchi/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
+%{python_sitelib}/wok/plugins/kimchi/model/*.py*
+%{python_sitelib}/wok/plugins/kimchi/API.json
+%{python_sitelib}/wok/plugins/kimchi/
+%{_datadir}/kimchi/doc/API.md
+%{_datadir}/kimchi/doc/README.md
+%{_datadir}/kimchi/doc/README-federation.md
+%{_datadir}/kimchi/doc/kimchi-guest.png
+%{_datadir}/kimchi/doc/kimchi-templates.png
+%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
+%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
+%{_datadir}/wok/plugins/kimchi/ui/
+%{_datadir}/wok/plugins/kimchi
+%{_sysconfdir}/wok/plugins.d/kimchi.conf
+%{_sysconfdir}/wok/plugins.d/template.conf
+%{_sysconfdir}/kimchi/distros.d/debian.json
+%{_sysconfdir}/kimchi/distros.d/fedora.json
+%{_sysconfdir}/kimchi/distros.d/opensuse.json
+%{_sysconfdir}/kimchi/distros.d/ubuntu.json
+%{_sysconfdir}/kimchi/distros.d/gentoo.json
+%{_sysconfdir}/kimchi/
+%{_var}/lib/kimchi/debugreports/
+%{_var}/lib/kimchi/isos/
+%{_var}/lib/kimchi/screenshots/
+%{_var}/lib/kimchi/vnc-tokens/
+%{_var}/lib/kimchi/
+
+
+%changelog
+* Thu Jun 18 2015 Lucio Correia <luciojhc at linux.vnet.ibm.com> 1.6
+- Run kimchi as a plugin
+
+* Thu Feb 26 2015 Frédéric Bonnard <frediz at linux.vnet.ibm.com> 1.4.0
+- Add man page for kimchid
+
+* Tue Feb 11 2014 CrÃstian Viana <vianac at linux.vnet.ibm.com> 1.1.0
+- Add help pages and XSLT dependency
+
+* Thu Jul 18 2013 Adam Litke <agl at us.ibm.com> 0.1.0-1
+- Adapted for autotools build
+- Split Suse and Fedora spec files
+
+* Thu Apr 04 2013 Aline Manera <alinefm at br.ibm.com> 0.0-1
+- First build
diff --git a/src/wok/plugins/kimchi/contrib/make-deb.sh.in b/src/wok/plugins/kimchi/contrib/make-deb.sh.in
new file mode 100644
index 0000000..5a6e56a
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/make-deb.sh.in
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+VERSION="@PACKAGE_VERSION@"
+RELEASE="@PACKAGE_RELEASE@"
+
+if [ ! -f configure ]; then
+ echo "Please run this script from the top of the package tree"
+ exit 1
+fi
+
+TMPDIR=`mktemp -d`
+
+make DESTDIR=$TMPDIR install-deb
+dpkg-deb -b $TMPDIR kimchi-${VERSION}-${RELEASE}.noarch.deb
+rm -rf $TMPDIR
diff --git a/src/wok/plugins/kimchi/control/Makefile.am b/src/wok/plugins/kimchi/control/Makefile.am
new file mode 100644
index 0000000..33118ca
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = vm
+
+control_PYTHON = *.py
+
+controldir = $(pythondir)/wok/plugins/kimchi/control
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(controldir)
diff --git a/src/wok/plugins/kimchi/control/__init__.py b/src/wok/plugins/kimchi/control/__init__.py
new file mode 100644
index 0000000..4ad9459
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/__init__.py
@@ -0,0 +1,26 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+
+
+from wok.control.utils import load_url_sub_node
+
+
+sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/src/wok/plugins/kimchi/control/config.py b/src/wok/plugins/kimchi/control/config.py
new file mode 100644
index 0000000..15df68f
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/config.py
@@ -0,0 +1,57 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode("config")
+class Config(Resource):
+ def __init__(self, model, id=None):
+ super(Config, self).__init__(model, id)
+ self.capabilities = Capabilities(self.model)
+ self.distros = Distros(model)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class Capabilities(Resource):
+ def __init__(self, model, id=None):
+ super(Capabilities, self).__init__(model, id)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class Distros(Collection):
+ def __init__(self, model):
+ super(Distros, self).__init__(model)
+ self.resource = Distro
+
+
+class Distro(Resource):
+ def __init__(self, model, ident):
+ super(Distro, self).__init__(model, ident)
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/cpuinfo.py b/src/wok/plugins/kimchi/control/cpuinfo.py
new file mode 100644
index 0000000..31f316c
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/cpuinfo.py
@@ -0,0 +1,37 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+from wok.control.base import Resource
+
+
+class CPUInfo(Resource):
+ def __init__(self, model):
+ super(CPUInfo, self).__init__(model)
+ self.admin_methods = ['GET']
+ self.role_key = 'host'
+ self.uri_fmt = "/host/cpuinfo"
+
+ @property
+ def data(self):
+ return {'threading_enabled': self.info['guest_threads_enabled'],
+ 'sockets': self.info['sockets'],
+ 'cores': self.info['cores_available'],
+ 'threads_per_core': self.info['threads_per_core']
+ }
diff --git a/src/wok/plugins/kimchi/control/debugreports.py b/src/wok/plugins/kimchi/control/debugreports.py
new file mode 100644
index 0000000..b5a3072
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/debugreports.py
@@ -0,0 +1,61 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import AsyncCollection, Resource
+from wok.control.utils import internal_redirect
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode('debugreports', True)
+class DebugReports(AsyncCollection):
+ def __init__(self, model):
+ super(DebugReports, self).__init__(model)
+ self.resource = DebugReport
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'POST']
+
+ def _get_resources(self, filter_params):
+ res_list = super(DebugReports, self)._get_resources(filter_params)
+ return sorted(res_list, key=lambda x: x.data['time'], reverse=True)
+
+
+class DebugReport(Resource):
+ def __init__(self, model, ident):
+ super(DebugReport, self).__init__(model, ident)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'PUT', 'POST']
+ self.uri_fmt = '/debugreports/%s'
+ self.content = DebugReportContent(model, ident)
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'uri': self.info['uri'],
+ 'time': self.info['ctime']}
+
+
+class DebugReportContent(Resource):
+ def __init__(self, model, ident):
+ super(DebugReportContent, self).__init__(model, ident)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+
+ def get(self):
+ self.lookup()
+ raise internal_redirect(self.info['uri'])
diff --git a/src/wok/plugins/kimchi/control/groups.py b/src/wok/plugins/kimchi/control/groups.py
new file mode 100644
index 0000000..649ff09
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/groups.py
@@ -0,0 +1,28 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import SimpleCollection
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode('groups', True)
+class Groups(SimpleCollection):
+ def __init__(self, model):
+ super(Groups, self).__init__(model)
+ self.role_key = 'guests'
diff --git a/src/wok/plugins/kimchi/control/host.py b/src/wok/plugins/kimchi/control/host.py
new file mode 100644
index 0000000..0a40f1b
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/host.py
@@ -0,0 +1,157 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource, SimpleCollection
+from wok.control.utils import UrlSubNode
+from wok.exception import NotFoundError
+
+from cpuinfo import CPUInfo
+
+
+ at UrlSubNode('host', True)
+class Host(Resource):
+ def __init__(self, model, id=None):
+ super(Host, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'POST']
+ self.uri_fmt = '/host/%s'
+ self.reboot = self.generate_action_handler('reboot')
+ self.shutdown = self.generate_action_handler('shutdown')
+ self.stats = HostStats(self.model)
+ self.partitions = Partitions(self.model)
+ self.devices = Devices(self.model)
+ self.packagesupdate = PackagesUpdate(self.model)
+ self.repositories = Repositories(self.model)
+ self.swupdate = self.generate_action_handler_task('swupdate')
+ self.cpuinfo = CPUInfo(self.model)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class HostStats(Resource):
+ def __init__(self, model, id=None):
+ super(HostStats, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+ self.history = HostStatsHistory(self.model)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class HostStatsHistory(Resource):
+ @property
+ def data(self):
+ return self.info
+
+
+class Partitions(Collection):
+ def __init__(self, model):
+ super(Partitions, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.resource = Partition
+
+ # Defining get_resources in order to return list of partitions in UI
+ # sorted by their path
+ def _get_resources(self, flag_filter):
+ res_list = super(Partitions, self)._get_resources(flag_filter)
+ res_list = filter(lambda x: x.info['available'], res_list)
+ res_list.sort(key=lambda x: x.info['path'])
+ return res_list
+
+
+class Partition(Resource):
+ def __init__(self, model, id):
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ super(Partition, self).__init__(model, id)
+
+ @property
+ def data(self):
+ if not self.info['available']:
+ raise NotFoundError("KCHPART0001E", {'name': self.info['name']})
+
+ return self.info
+
+
+class Devices(Collection):
+ def __init__(self, model):
+ super(Devices, self).__init__(model)
+ self.resource = Device
+
+
+class VMHolders(SimpleCollection):
+ def __init__(self, model, device_id):
+ super(VMHolders, self).__init__(model)
+ self.model_args = (device_id, )
+
+
+class Device(Resource):
+ def __init__(self, model, id):
+ super(Device, self).__init__(model, id)
+ self.vm_holders = VMHolders(self.model, id)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class PackagesUpdate(Collection):
+ def __init__(self, model):
+ super(PackagesUpdate, self).__init__(model)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+ self.resource = PackageUpdate
+
+
+class PackageUpdate(Resource):
+ def __init__(self, model, id=None):
+ super(PackageUpdate, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+
+ @property
+ def data(self):
+ return self.info
+
+
+class Repositories(Collection):
+ def __init__(self, model):
+ super(Repositories, self).__init__(model)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'POST']
+ self.resource = Repository
+
+
+class Repository(Resource):
+ def __init__(self, model, id):
+ super(Repository, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'PUT', 'POST', 'DELETE']
+ self.uri_fmt = "/host/repositories/%s"
+ self.enable = self.generate_action_handler('enable')
+ self.disable = self.generate_action_handler('disable')
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/interfaces.py b/src/wok/plugins/kimchi/control/interfaces.py
new file mode 100644
index 0000000..d698b7a
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/interfaces.py
@@ -0,0 +1,46 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode('interfaces', True)
+class Interfaces(Collection):
+ def __init__(self, model):
+ super(Interfaces, self).__init__(model)
+ self.role_key = 'network'
+ self.admin_methods = ['GET']
+ self.resource = Interface
+
+
+class Interface(Resource):
+ def __init__(self, model, ident):
+ super(Interface, self).__init__(model, ident)
+ self.role_key = 'network'
+ self.admin_methods = ['GET']
+ self.uri_fmt = "/interfaces/%s"
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'type': self.info['type'],
+ 'ipaddr': self.info['ipaddr'],
+ 'netmask': self.info['netmask'],
+ 'status': self.info['status']}
diff --git a/src/wok/plugins/kimchi/control/networks.py b/src/wok/plugins/kimchi/control/networks.py
new file mode 100644
index 0000000..fd92111
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/networks.py
@@ -0,0 +1,54 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode('networks', True)
+class Networks(Collection):
+ def __init__(self, model):
+ super(Networks, self).__init__(model)
+ self.role_key = 'network'
+ self.admin_methods = ['POST']
+ self.resource = Network
+
+
+class Network(Resource):
+ def __init__(self, model, ident):
+ super(Network, self).__init__(model, ident)
+ self.role_key = 'network'
+ self.admin_methods = ['PUT', 'POST', 'DELETE']
+ self.uri_fmt = "/networks/%s"
+ self.activate = self.generate_action_handler('activate')
+ self.deactivate = self.generate_action_handler('deactivate',
+ destructive=True)
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'vms': self.info['vms'],
+ 'in_use': self.info['in_use'],
+ 'autostart': self.info['autostart'],
+ 'connection': self.info['connection'],
+ 'interface': self.info['interface'],
+ 'subnet': self.info['subnet'],
+ 'dhcp': self.info['dhcp'],
+ 'state': self.info['state'],
+ 'persistent': self.info['persistent']}
diff --git a/src/wok/plugins/kimchi/control/peers.py b/src/wok/plugins/kimchi/control/peers.py
new file mode 100644
index 0000000..21e9f13
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/peers.py
@@ -0,0 +1,29 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import SimpleCollection
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode("peers", True)
+class Peers(SimpleCollection):
+ def __init__(self, model):
+ super(Peers, self).__init__(model)
+ self.role_key = 'peers'
+ self.admin_methods = ['GET']
diff --git a/src/wok/plugins/kimchi/control/storagepools.py b/src/wok/plugins/kimchi/control/storagepools.py
new file mode 100644
index 0000000..e5f264e
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/storagepools.py
@@ -0,0 +1,116 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import get_class_name, model_fn
+from wok.control.utils import validate_params
+from wok.control.utils import UrlSubNode
+
+from ..model.storagepools import ISO_POOL_NAME
+from storagevolumes import IsoVolumes, StorageVolumes
+
+
+ at UrlSubNode('storagepools', True)
+class StoragePools(Collection):
+ def __init__(self, model):
+ super(StoragePools, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['POST']
+ self.resource = StoragePool
+ isos = IsoPool(model)
+ setattr(self, ISO_POOL_NAME, isos)
+
+ def create(self, params, *args):
+ try:
+ create = getattr(self.model, model_fn(self, 'create'))
+ except AttributeError:
+ error = 'Create is not allowed for %s' % get_class_name(self)
+ raise cherrypy.HTTPError(405, error)
+
+ validate_params(params, self, 'create')
+ args = self.model_args + [params]
+ name = create(*args)
+ args = self.resource_args + [name]
+ res = self.resource(self.model, *args)
+ resp = res.get()
+
+ if 'task_id' in res.data:
+ cherrypy.response.status = 202
+ else:
+ cherrypy.response.status = 201
+
+ return resp
+
+ def _get_resources(self, filter_params):
+ try:
+ res_list = super(StoragePools, self)._get_resources(filter_params)
+ # Append reserved pools
+ isos = getattr(self, ISO_POOL_NAME)
+ isos.lookup()
+ res_list.append(isos)
+ except AttributeError:
+ pass
+
+ return res_list
+
+
+class StoragePool(Resource):
+ def __init__(self, model, ident):
+ super(StoragePool, self).__init__(model, ident)
+ self.role_key = 'storage'
+ self.admin_methods = ['PUT', 'POST', 'DELETE']
+ self.uri_fmt = "/storagepools/%s"
+ self.activate = self.generate_action_handler('activate')
+ self.deactivate = self.generate_action_handler('deactivate',
+ destructive=True)
+ self.storagevolumes = StorageVolumes(self.model, ident)
+
+ @property
+ def data(self):
+ res = {'name': self.ident,
+ 'state': self.info['state'],
+ 'capacity': self.info['capacity'],
+ 'allocated': self.info['allocated'],
+ 'available': self.info['available'],
+ 'path': self.info['path'],
+ 'source': self.info['source'],
+ 'type': self.info['type'],
+ 'nr_volumes': self.info['nr_volumes'],
+ 'autostart': self.info['autostart'],
+ 'persistent': self.info['persistent']}
+
+ val = self.info.get('task_id')
+ if val:
+ res['task_id'] = val
+
+ return res
+
+
+class IsoPool(Resource):
+ def __init__(self, model):
+ super(IsoPool, self).__init__(model, ISO_POOL_NAME)
+ self.storagevolumes = IsoVolumes(self.model, ISO_POOL_NAME)
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'state': self.info['state'],
+ 'type': self.info['type']}
diff --git a/src/wok/plugins/kimchi/control/storageservers.py b/src/wok/plugins/kimchi/control/storageservers.py
new file mode 100644
index 0000000..654ab47
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/storageservers.py
@@ -0,0 +1,60 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok import template
+from wok.control.base import Collection, Resource
+from wok.control.utils import get_class_name, model_fn, UrlSubNode
+
+
+ at UrlSubNode('storageservers', True)
+class StorageServers(Collection):
+ def __init__(self, model):
+ super(StorageServers, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.resource = StorageServer
+
+
+class StorageServer(Resource):
+ def __init__(self, model, ident):
+ super(StorageServer, self).__init__(model, ident)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.storagetargets = StorageTargets(self.model,
+ self.ident.decode("utf-8"))
+
+ @property
+ def data(self):
+ return self.info
+
+
+class StorageTargets(Collection):
+ def __init__(self, model, server):
+ super(StorageTargets, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.server = server
+ self.resource_args = [self.server, ]
+ self.model_args = [self.server, ]
+
+ def get(self, filter_params):
+ res_list = []
+ get_list = getattr(self.model, model_fn(self, 'get_list'))
+ res_list = get_list(*self.model_args, **filter_params)
+ return template.render(get_class_name(self), res_list)
diff --git a/src/wok/plugins/kimchi/control/storagevolumes.py b/src/wok/plugins/kimchi/control/storagevolumes.py
new file mode 100644
index 0000000..bbe6627
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/storagevolumes.py
@@ -0,0 +1,83 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok import template
+from wok.control.base import AsyncCollection, Collection, Resource
+from wok.control.utils import get_class_name, model_fn
+
+
+class StorageVolumes(AsyncCollection):
+ def __init__(self, model, pool):
+ super(StorageVolumes, self).__init__(model)
+ self.resource = StorageVolume
+ self.pool = pool
+ self.resource_args = [self.pool, ]
+ self.model_args = [self.pool, ]
+
+ def filter_data(self, resources, fields_filter):
+ # filter directory from storage volumes
+ fields_filter.update({'type': ['file', 'block', 'network']})
+ return super(StorageVolumes, self).filter_data(resources,
+ fields_filter)
+
+
+class StorageVolume(Resource):
+ def __init__(self, model, pool, ident):
+ super(StorageVolume, self).__init__(model, ident)
+ self.pool = pool
+ self.ident = ident
+ self.info = {}
+ self.model_args = [self.pool, self.ident]
+ self.uri_fmt = '/storagepools/%s/storagevolumes/%s'
+ self.resize = self.generate_action_handler('resize', ['size'])
+ self.wipe = self.generate_action_handler('wipe')
+ self.clone = self.generate_action_handler_task('clone')
+
+ @property
+ def data(self):
+ res = {'name': self.ident,
+ 'type': self.info['type'],
+ 'capacity': self.info['capacity'],
+ 'allocation': self.info['allocation'],
+ 'path': self.info['path'],
+ 'used_by': self.info['used_by'],
+ 'format': self.info['format']}
+
+ for key in ('os_version', 'os_distro', 'bootable', 'base'):
+ val = self.info.get(key)
+ if val:
+ res[key] = val
+
+ return res
+
+
+class IsoVolumes(Collection):
+ def __init__(self, model, pool):
+ super(IsoVolumes, self).__init__(model)
+ self.pool = pool
+
+ def get(self, filter_params):
+ res_list = []
+ try:
+ get_list = getattr(self.model, model_fn(self, 'get_list'))
+ res_list = get_list(*self.model_args)
+ except AttributeError:
+ pass
+
+ return template.render(get_class_name(self), res_list)
diff --git a/src/wok/plugins/kimchi/control/templates.py b/src/wok/plugins/kimchi/control/templates.py
new file mode 100644
index 0000000..fc58815
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/templates.py
@@ -0,0 +1,58 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode('templates', True)
+class Templates(Collection):
+ def __init__(self, model):
+ super(Templates, self).__init__(model)
+ self.role_key = 'templates'
+ self.admin_methods = ['GET', 'POST']
+ self.resource = Template
+
+
+class Template(Resource):
+ def __init__(self, model, ident):
+ super(Template, self).__init__(model, ident)
+ self.role_key = 'templates'
+ self.admin_methods = ['PUT', 'POST', 'DELETE']
+ self.uri_fmt = "/templates/%s"
+ self.clone = self.generate_action_handler('clone')
+
+ @property
+ def data(self):
+ return {
+ 'name': self.ident,
+ 'icon': self.info['icon'],
+ 'invalid': self.info['invalid'],
+ 'os_distro': self.info['os_distro'],
+ 'os_version': self.info['os_version'],
+ 'cpus': self.info['cpus'],
+ 'memory': self.info['memory'],
+ 'cdrom': self.info.get('cdrom', None),
+ 'disks': self.info['disks'],
+ 'storagepool': self.info['storagepool'],
+ 'networks': self.info['networks'],
+ 'folder': self.info.get('folder', []),
+ 'graphics': self.info['graphics'],
+ 'cpu_info': self.info.get('cpu_info')
+ }
diff --git a/src/wok/plugins/kimchi/control/users.py b/src/wok/plugins/kimchi/control/users.py
new file mode 100644
index 0000000..756a2f7
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/users.py
@@ -0,0 +1,35 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import SimpleCollection
+from wok.control.utils import get_class_name, model_fn, UrlSubNode
+from wok.template import render
+
+
+ at UrlSubNode('users', True)
+class Users(SimpleCollection):
+ def __init__(self, model):
+ super(Users, self).__init__(model)
+ self.role_key = 'guests'
+
+ def get(self, filter_params):
+ res_list = []
+ get_list = getattr(self.model, model_fn(self, 'get_list'))
+ res_list = get_list(*self.model_args, **filter_params)
+ return render(get_class_name(self), res_list)
diff --git a/src/wok/plugins/kimchi/control/vm/Makefile.am b/src/wok/plugins/kimchi/control/vm/Makefile.am
new file mode 100644
index 0000000..b17c68a
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+vm_PYTHON = *.py
+
+vmdir = $(pythondir)/wok/plugins/kimchi/control/vm
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(vmdir)
diff --git a/src/wok/plugins/kimchi/control/vm/__init__.py b/src/wok/plugins/kimchi/control/vm/__init__.py
new file mode 100644
index 0000000..a311045
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/__init__.py
@@ -0,0 +1,26 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+
+
+from wok.control.utils import load_url_sub_node
+
+
+sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/src/wok/plugins/kimchi/control/vm/hostdevs.py b/src/wok/plugins/kimchi/control/vm/hostdevs.py
new file mode 100644
index 0000000..a43b9d8
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/hostdevs.py
@@ -0,0 +1,43 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode("hostdevs")
+class VMHostDevs(Collection):
+ def __init__(self, model, vmid):
+ super(VMHostDevs, self).__init__(model)
+ self.resource = VMHostDev
+ self.vmid = vmid
+ self.resource_args = [self.vmid, ]
+ self.model_args = [self.vmid, ]
+
+
+class VMHostDev(Resource):
+ def __init__(self, model, vmid, ident):
+ super(VMHostDev, self).__init__(model, ident)
+ self.vmid = vmid
+ self.ident = ident
+ self.model_args = [self.vmid, self.ident]
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vm/ifaces.py b/src/wok/plugins/kimchi/control/vm/ifaces.py
new file mode 100644
index 0000000..ac957fd
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/ifaces.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode("ifaces")
+class VMIfaces(Collection):
+ def __init__(self, model, vm):
+ super(VMIfaces, self).__init__(model)
+ self.resource = VMIface
+ self.vm = vm
+ self.resource_args = [self.vm, ]
+ self.model_args = [self.vm, ]
+
+
+class VMIface(Resource):
+ def __init__(self, model, vm, ident):
+ super(VMIface, self).__init__(model, ident)
+ self.vm = vm
+ self.ident = ident
+ self.info = {}
+ self.model_args = [self.vm, self.ident]
+ self.uri_fmt = '/vms/%s/ifaces/%s'
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vm/snapshots.py b/src/wok/plugins/kimchi/control/vm/snapshots.py
new file mode 100644
index 0000000..dd17b85
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/snapshots.py
@@ -0,0 +1,58 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import AsyncCollection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode('snapshots')
+class VMSnapshots(AsyncCollection):
+ def __init__(self, model, vm):
+ super(VMSnapshots, self).__init__(model)
+ self.resource = VMSnapshot
+ self.vm = vm
+ self.resource_args = [self.vm, ]
+ self.model_args = [self.vm, ]
+ self.current = CurrentVMSnapshot(model, vm)
+
+
+class VMSnapshot(Resource):
+ def __init__(self, model, vm, ident):
+ super(VMSnapshot, self).__init__(model, ident)
+ self.vm = vm
+ self.ident = ident
+ self.model_args = [self.vm, self.ident]
+ self.uri_fmt = '/vms/%s/snapshots/%s'
+ self.revert = self.generate_action_handler('revert')
+
+ @property
+ def data(self):
+ return self.info
+
+
+class CurrentVMSnapshot(Resource):
+ def __init__(self, model, vm):
+ super(CurrentVMSnapshot, self).__init__(model)
+ self.vm = vm
+ self.model_args = [self.vm]
+ self.uri_fmt = '/vms/%s/snapshots/current'
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vm/storages.py b/src/wok/plugins/kimchi/control/vm/storages.py
new file mode 100644
index 0000000..f502caa
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/storages.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+ at UrlSubNode("storages")
+class VMStorages(Collection):
+ def __init__(self, model, vm):
+ super(VMStorages, self).__init__(model)
+ self.resource = VMStorage
+ self.vm = vm
+ self.resource_args = [self.vm, ]
+ self.model_args = [self.vm, ]
+
+
+class VMStorage(Resource):
+ def __init__(self, model, vm, ident):
+ super(VMStorage, self).__init__(model, ident)
+ self.vm = vm
+ self.ident = ident
+ self.info = {}
+ self.model_args = [self.vm, self.ident]
+ self.uri_fmt = '/vms/%s/storages/%s'
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vms.py b/src/wok/plugins/kimchi/control/vms.py
new file mode 100644
index 0000000..858b23c
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vms.py
@@ -0,0 +1,67 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import AsyncCollection, Resource
+from wok.control.utils import internal_redirect, UrlSubNode
+
+from vm import sub_nodes
+
+
+ at UrlSubNode('vms', True)
+class VMs(AsyncCollection):
+ def __init__(self, model):
+ super(VMs, self).__init__(model)
+ self.resource = VM
+ self.role_key = 'guests'
+ self.admin_methods = ['POST']
+
+
+class VM(Resource):
+ def __init__(self, model, ident):
+ super(VM, self).__init__(model, ident)
+ self.role_key = 'guests'
+ self.screenshot = VMScreenShot(model, ident)
+ self.uri_fmt = '/vms/%s'
+ for ident, node in sub_nodes.items():
+ setattr(self, ident, node(model, self.ident))
+ self.start = self.generate_action_handler('start')
+ self.poweroff = self.generate_action_handler('poweroff',
+ destructive=True)
+ self.shutdown = self.generate_action_handler('shutdown',
+ destructive=True)
+ self.reset = self.generate_action_handler('reset',
+ destructive=True)
+ self.connect = self.generate_action_handler('connect')
+ self.clone = self.generate_action_handler_task('clone')
+ self.suspend = self.generate_action_handler('suspend')
+ self.resume = self.generate_action_handler('resume')
+
+ @property
+ def data(self):
+ return self.info
+
+
+class VMScreenShot(Resource):
+ def __init__(self, model, ident):
+ super(VMScreenShot, self).__init__(model, ident)
+ self.role_key = 'guests'
+
+ def get(self):
+ self.lookup()
+ raise internal_redirect(self.info)
diff --git a/src/wok/plugins/kimchi/disks.py b/src/wok/plugins/kimchi/disks.py
new file mode 100644
index 0000000..eb40e3a
--- /dev/null
+++ b/src/wok/plugins/kimchi/disks.py
@@ -0,0 +1,196 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os.path
+import re
+import subprocess
+from parted import Device as PDevice
+from parted import Disk as PDisk
+
+from wok.exception import OperationFailed
+from wok.utils import wok_log
+
+
+def _get_dev_node_path(maj_min):
+ """ Returns device node path given the device number 'major:min' """
+
+ dm_name = "/sys/dev/block/%s/dm/name" % maj_min
+ if os.path.exists(dm_name):
+ with open(dm_name) as dm_f:
+ content = dm_f.read().rstrip('\n')
+ return "/dev/mapper/" + content
+
+ uevent = "/sys/dev/block/%s/uevent" % maj_min
+ with open(uevent) as ueventf:
+ content = ueventf.read()
+
+ data = dict(re.findall(r'(\S+)=(".*?"|\S+)', content.replace("\n", " ")))
+
+ return "/dev/%s" % data["DEVNAME"]
+
+
+def _get_lsblk_devs(keys, devs=[]):
+ lsblk = subprocess.Popen(
+ ["lsblk", "-Pbo"] + [','.join(keys)] + devs,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = lsblk.communicate()
+ if lsblk.returncode != 0:
+ raise OperationFailed("KCHDISKS0001E", {'err': err})
+
+ return _parse_lsblk_output(out, keys)
+
+
+def _get_dev_major_min(name):
+ maj_min = None
+
+ keys = ["NAME", "MAJ:MIN"]
+ dev_list = _get_lsblk_devs(keys)
+
+ for dev in dev_list:
+ if dev['name'].split()[0] == name:
+ maj_min = dev['maj:min']
+ break
+ else:
+ raise OperationFailed("KCHDISKS0002E", {'device': name})
+
+ return maj_min
+
+
+def _is_dev_leaf(devNodePath):
+ try:
+ # By default, lsblk prints a device information followed by children
+ # device information
+ childrenCount = len(
+ _get_lsblk_devs(["NAME"], [devNodePath])) - 1
+ except OperationFailed as e:
+ # lsblk is known to fail on multipath devices
+ # Assume these devices contain children
+ wok_log.error(
+ "Error getting device info for %s: %s", devNodePath, e)
+ return False
+
+ return childrenCount == 0
+
+
+def _is_dev_extended_partition(devType, devNodePath):
+ if devType != 'part':
+ return False
+ diskPath = devNodePath.rstrip('0123456789')
+ device = PDevice(diskPath)
+ try:
+ extended_part = PDisk(device).getExtendedPartition()
+ except NotImplementedError as e:
+ wok_log.warning(
+ "Error getting extended partition info for dev %s type %s: %s",
+ devNodePath, devType, e.message)
+ # Treate disk with unsupported partiton table as if it does not
+ # contain extended partitions.
+ return False
+ if extended_part and extended_part.path == devNodePath:
+ return True
+ return False
+
+
+def _parse_lsblk_output(output, keys):
+ # output is on format key="value",
+ # where key can be NAME, TYPE, FSTYPE, SIZE, MOUNTPOINT, etc
+ lines = output.rstrip("\n").split("\n")
+ r = []
+ for line in lines:
+ d = {}
+ for key in keys:
+ expression = r"%s=\".*?\"" % key
+ match = re.search(expression, line)
+ field = match.group()
+ k, v = field.split('=', 1)
+ d[k.lower()] = v[1:-1]
+ r.append(d)
+ return r
+
+
+def _get_vgname(devNodePath):
+ """ Return volume group name of a physical volume. If the device node path
+ is not a physical volume, return empty string. """
+ pvs = subprocess.Popen(
+ ["pvs", "--unbuffered", "--nameprefixes", "--noheadings",
+ "-o", "vg_name", devNodePath],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = pvs.communicate()
+ if pvs.returncode != 0:
+ return ""
+
+ return re.findall(r"LVM2_VG_NAME='([^\']*)'", out)[0]
+
+
+def _is_available(name, devtype, fstype, mountpoint, majmin):
+ devNodePath = _get_dev_node_path(majmin)
+ # Only list unmounted and unformated and leaf and (partition or disk)
+ # leaf means a partition, a disk has no partition, or a disk not held
+ # by any multipath device. Physical volume belongs to no volume group
+ # is also listed. Extended partitions should not be listed.
+ if (devtype in ['part', 'disk', 'mpath'] and
+ fstype in ['', 'LVM2_member'] and
+ mountpoint == "" and
+ _get_vgname(devNodePath) == "" and
+ _is_dev_leaf(devNodePath) and
+ not _is_dev_extended_partition(devtype, devNodePath)):
+ return True
+ return False
+
+
+def get_partitions_names(check=False):
+ names = set()
+ keys = ["NAME", "TYPE", "FSTYPE", "MOUNTPOINT", "MAJ:MIN"]
+ # output is on format key="value",
+ # where key can be NAME, TYPE, FSTYPE, MOUNTPOINT
+ for dev in _get_lsblk_devs(keys):
+ # split()[0] to avoid the second part of the name, after the
+ # whiteline
+ name = dev['name'].split()[0]
+ if check and not _is_available(name, dev['type'], dev['fstype'],
+ dev['mountpoint'], dev['maj:min']):
+ continue
+ names.add(name)
+
+ return list(names)
+
+
+def get_partition_details(name):
+ majmin = _get_dev_major_min(name)
+ dev_path = _get_dev_node_path(majmin)
+
+ keys = ["TYPE", "FSTYPE", "SIZE", "MOUNTPOINT"]
+ try:
+ dev = _get_lsblk_devs(keys, [dev_path])[0]
+ except OperationFailed as e:
+ wok_log.error(
+ "Error getting partition info for %s: %s", name, e)
+ return {}
+
+ dev['available'] = _is_available(name, dev['type'], dev['fstype'],
+ dev['mountpoint'], majmin)
+ if dev['mountpoint']:
+ # Sometimes the mountpoint comes with [SWAP] or other
+ # info which is not an actual mount point. Filtering it
+ regexp = re.compile(r"\[.*\]")
+ if regexp.search(dev['mountpoint']) is not None:
+ dev['mountpoint'] = ''
+ dev['path'] = dev_path
+ dev['name'] = name
+ return dev
diff --git a/src/wok/plugins/kimchi/distroloader.py b/src/wok/plugins/kimchi/distroloader.py
new file mode 100644
index 0000000..0032737
--- /dev/null
+++ b/src/wok/plugins/kimchi/distroloader.py
@@ -0,0 +1,67 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import glob
+import json
+import os
+
+
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import wok_log
+
+import config
+
+
+ARCHS = {'x86_64': ['x86_64', 'amd64', 'i686', 'x86', 'i386'],
+ 'amd64': ['x86_64', 'amd64', 'i686', 'x86', 'i386'],
+ 'ppc64': ['ppc', 'ppc64'],
+ 'ppc64le': ['ppc64', 'ppc64le']}
+
+
+class DistroLoader(object):
+
+ def __init__(self, location=None):
+ self.location = location or config.get_distros_store()
+
+ def _get_json_info(self, fname):
+ msg_args = {'filename': fname}
+ if not os.path.isfile(fname):
+ msg = "DistroLoader: failed to find distro file: %s" % fname
+ wok_log.error(msg)
+ raise NotFoundError("KCHDL0001E", msg_args)
+ try:
+ with open(fname) as f:
+ data = json.load(f)
+ return data
+ except ValueError:
+ msg = "DistroLoader: failed to parse distro file: %s" % fname
+ wok_log.error(msg)
+ raise OperationFailed("KCHDL0002E", msg_args)
+
+ def get(self):
+ arch_list = ARCHS.get(os.uname()[4])
+ all_json_files = glob.glob("%s/%s" % (self.location, "*.json"))
+ distros = []
+ for f in all_json_files:
+ distros.extend(self._get_json_info(f))
+
+ # Return all remote ISOs arch not found
+ return dict([(distro['name'], distro) for distro in distros if
+ (arch_list is None or distro['os_arch'] in arch_list)])
diff --git a/src/wok/plugins/kimchi/distros.d/Makefile.am b/src/wok/plugins/kimchi/distros.d/Makefile.am
new file mode 100644
index 0000000..684fe60
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+distrosdir = $(sysconfdir)/kimchi/distros.d
+
+dist_distros_DATA = *.json
diff --git a/src/wok/plugins/kimchi/distros.d/debian.json b/src/wok/plugins/kimchi/distros.d/debian.json
new file mode 100644
index 0000000..5d6a313
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/debian.json
@@ -0,0 +1,9 @@
+[
+ {
+ "name": "debian-Wheezy",
+ "os_distro": "debian",
+ "os_arch": "x86_64",
+ "os_version": "7.7.0",
+ "path": "http://caesar.acc.umu.se/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/fedora.json b/src/wok/plugins/kimchi/distros.d/fedora.json
new file mode 100644
index 0000000..bce72d6
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/fedora.json
@@ -0,0 +1,30 @@
+[
+ {
+ "name": "Fedora 20",
+ "os_distro": "fedora",
+ "os_arch": "x86_64",
+ "os_version": "20",
+ "path": "http://fedora.mirrors.tds.net/pub/fedora/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso"
+ },
+ {
+ "name": "Fedora 18 (PPC64)",
+ "os_distro": "fedora",
+ "os_arch": "ppc64",
+ "os_version": "18",
+ "path": "http://mirrors.kernel.org/fedora-secondary/releases/18/Fedora/ppc64/iso/Fedora-18-ppc64-DVD.iso"
+ },
+ {
+ "name": "Fedora 19 (PPC64)",
+ "os_distro": "fedora",
+ "os_arch": "ppc64",
+ "os_version": "19",
+ "path": "http://mirrors.kernel.org/fedora-secondary/releases/19/Fedora/ppc64/iso/Fedora-19-ppc64-DVD.iso"
+ },
+ {
+ "name": "Fedora 20 (PPC64)",
+ "os_distro": "fedora",
+ "os_arch": "ppc64",
+ "os_version": "20",
+ "path": "http://mirrors.kernel.org/fedora-secondary/releases/20/Fedora/ppc64/iso/Fedora-20-ppc64-DVD.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/gentoo.json b/src/wok/plugins/kimchi/distros.d/gentoo.json
new file mode 100644
index 0000000..2c0f012
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/gentoo.json
@@ -0,0 +1,9 @@
+[
+ {
+ "name": "gentoo-20141204",
+ "os_distro": "gentoo",
+ "os_arch": "x86_64",
+ "os_version": "20141204",
+ "path": "http://distfiles.gentoo.org/releases/amd64/autobuilds/current-iso/install-amd64-minimal-20141204.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/opensuse.json b/src/wok/plugins/kimchi/distros.d/opensuse.json
new file mode 100644
index 0000000..f51de97
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/opensuse.json
@@ -0,0 +1,23 @@
+[
+ {
+ "name": "opensuse-12.3",
+ "os_distro": "opensuse",
+ "os_arch": "x86_64",
+ "os_version": "12.3",
+ "path": "http://suse.mirrors.tds.net/pub/opensuse/distribution/12.3/iso/openSUSE-12.3-DVD-x86_64.iso"
+ },
+ {
+ "name": "opensuse-13.1",
+ "os_distro": "opensuse",
+ "os_arch": "x86_64",
+ "os_version": "13.1",
+ "path": "http://suse.mirrors.tds.net/pub/opensuse/distribution/13.1/iso/openSUSE-13.1-DVD-x86_64.iso"
+ },
+ {
+ "name": "opensuse-13.2",
+ "os_distro": "opensuse",
+ "os_arch": "x86_64",
+ "os_version": "13.2",
+ "path": "http://suse.mirrors.tds.net/pub/opensuse/distribution/13.2/iso/openSUSE-13.2-DVD-x86_64.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/ubuntu.json b/src/wok/plugins/kimchi/distros.d/ubuntu.json
new file mode 100644
index 0000000..161fbc8
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/ubuntu.json
@@ -0,0 +1,37 @@
+[
+ {
+ "name": "Ubuntu 13.04 (Raring Ringtail)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "13.04",
+ "path": "http://ubuntu-releases.cs.umn.edu/13.04/ubuntu-13.04-desktop-amd64.iso"
+ },
+ {
+ "name": "Ubuntu 13.10 (Saucy Salamander)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "13.10",
+ "path": "http://ubuntu-releases.cs.umn.edu/13.10/ubuntu-13.10-desktop-amd64.iso"
+ },
+ {
+ "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
+ "os_distro": "ubuntu",
+ "os_arch": "ppc64",
+ "os_version": "14.04",
+ "path": "http://cdimages.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-ppc64el.iso"
+ },
+ {
+ "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "14.04",
+ "path": "http://releases.ubuntu.com/14.04/ubuntu-14.04-desktop-amd64.iso"
+ },
+ {
+ "name": "Ubuntu Server 14.10 (Utopic Unicorn)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "14.10",
+ "path": "http://releases.ubuntu.com/14.10/ubuntu-14.10-desktop-amd64.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/docs/API.md b/src/wok/plugins/kimchi/docs/API.md
new file mode 100644
index 0000000..fca424c
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/API.md
@@ -0,0 +1,1116 @@
+## Project Kimchi REST API Specification
+
+The Kimchi API provides all functionality to the application and may be used
+directly by external tools. In the following sections you will find the
+specification of all Collections and Resource types that are supported and the
+URIs where they can be accessed. In order to use the API effectively, please
+the following general conventions:
+
+* The **Content Type** of the API is JSON. When making HTTP requests to this
+ API you should specify the following headers:
+ * Accept: application/json
+ * Content-type: application/json
+* A **Collection** is a group of Resources of a given type.
+ * A **GET** request retrieves a list of summarized Resource representations
+ This summary *may* include all or some of the Resource properties but
+ *must* include a link to the full Resource representation.
+ * A **POST** request will create a new Resource in the Collection. The set
+ of Resource properties *must* be specified as a JSON object in the request
+ body.
+ * No other HTTP methods are supported for Collections
+* A **Resource** is a representation of a singular object in the API (eg.
+ Virtual Machine).
+ * A **GET** request retrieves the full Resource representation.
+ * A **DELETE** request will delete the Resource. This request *may* contain
+ a JSON object which specifies optional parameters.
+ * A **PUT** request is used to modify the properties of a Resource (eg.
+ Change the name of a Virtual Machine). This kind of request *must not*
+ alter the live state of the Resource. Only *actions* may alter live state.
+ * A **POST** request commits an *action* upon a Resource (eg. Start a
+ Virtual Machine). This request is made to a URI relative to the Resource
+ URI. Available *actions* are described within the *actions* property of a
+ Resource representation. The request body *must* contain a JSON object
+ which specifies parameters.
+* URIs begin with '/plugins/kimchi' to indicate the root of Kimchi plugin.
+ * Variable segments in the URI begin with a ':' and should replaced with the
+ appropriate resource identifier.
+
+### Collection: Virtual Machines
+
+**URI:** /plugins/kimchi/vms
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Virtual Machines
+* **POST**: Create a new Virtual Machine
+ * name *(optional)*: The name of the VM. Used to identify the VM in this
+ API. If omitted, a name will be chosen based on the template used.
+ * persistent: If 'true', vm will persist after a Power Off or host reboot.
+ All virtual machines created by Kimchi are persistent.
+ * template: The URI of a Template to use when building the VM
+ * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
+ * graphics *(optional)*: Specify the graphics paramenter for this vm
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+
+
+### Resource: Virtual Machine
+
+**URI:** /plugins/kimchi/vms/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Virtual Machine
+ * name: The name of the VM. Used to identify the VM in this API
+ * state: Indicates the current state in the VM lifecycle
+ * running: The VM is powered on
+ * paused: The VMs virtual CPUs are paused
+ * shutoff: The VM is powered off
+ * stats: Virtual machine statistics:
+ * cpu_utilization: A number between 0 and 100 which indicates the
+ percentage of CPU utilization.
+ * net_throughput: Expresses total network throughput for reads and
+ writes across all virtual interfaces (kb/s).
+ * net_throughput_peak: The highest recent value of 'net_throughput'.
+ * io_throughput: Expresses the total IO throughput for reads and
+ writes across all virtual disks (kb/s).
+ * io_throughput_peak: The highest recent value of 'io_throughput'.
+ * uuid: UUID of the VM.
+ * memory: The amount of memory assigned to the VM (in MB)
+ * cpus: The number of CPUs assigned to the VM
+ * screenshot: A link to a recent capture of the screen in PNG format
+ * icon: A link to an icon that represents the VM
+ * graphics: A dict to show detail of VM graphics.
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+ * port: The real port number of the graphics, vnc or spice. Users
+ can use this port to connect to the vm with general vnc/spice
+ clients.
+ * passwd: console password
+ * passwdValidTo: lifetime for the console password.
+ * users: A list of system users who have permission to access the VM.
+ Default is: empty (i.e. only root-users may access).
+ * groups: A list of system groups whose users have permission to access
+ the VM. Default is: empty (i.e. no groups given access).
+* **DELETE**: Remove the Virtual Machine
+* **PUT**: update the parameters of existed VM
+ * name: New name for this VM (only applied for shutoff VM)
+ * users: New list of system users.
+ * groups: New list of system groups.
+ * cpus: New number of virtual cpus for this VM (if VM is running, new value
+ will take effect in next reboot)
+ * memory: New amount of memory (MB) for this VM (if VM is running, new
+ value will take effect in next reboot)
+ * graphics: A dict to show detail of VM graphics.
+ * passwd *(optional)*: console password. When omitted a random password
+ willbe generated.
+ * passwdValidTo *(optional)*: lifetime for the console password. When
+ omitted the password will be valid just
+ for 30 seconds.
+
+* **POST**: *See Virtual Machine Actions*
+
+**Actions (POST):**
+
+* start: Power on a VM
+* poweroff: Power off a VM forcefully. Note this action may produce undesirable
+ results, for example unflushed disk cache in the guest.
+* shutdown: Shut down a VM graceful. This action issue shutdown request to guest.
+ And the guest will react this request. Note the guest OS may ignore
+ the request.
+* reset: Reset a VM immediately without the guest OS shutdown.
+ It emulates the power reset button on a machine. Note that there is a
+ risk of data loss caused by reset without the guest OS shutdown.
+* connect: Prepare the connection for spice or vnc
+
+* clone: Create a new VM identical to this VM. The new VM's name, UUID and
+ network MAC addresses will be generated automatically. Each existing
+ disks will be copied to a new volume in the same storage pool. If
+ there is no available space on that storage pool to hold the new
+ volume, it will be created on the pool 'default'. This action returns
+ a Task.
+
+* suspend: Suspend an active domain. The process is frozen without further
+ access to CPU resources and I/O but the memory used by the domain at
+ the hypervisor level will stay allocated.
+
+* resume: Resume a suspended domain. The process is restarted from the state
+ where it was frozen by calling "suspend".
+
+### Sub-resource: Virtual Machine Screenshot
+
+**URI:** /plugins/kimchi/vms/*:name*/screenshot
+
+Represents a snapshot of the Virtual Machine's primary monitor.
+
+**Methods:**
+
+* **GET**: Redirect to the latest screenshot of a Virtual Machine in PNG format
+
+
+### Sub-collection: Virtual Machine storages
+**URI:** /plugins/kimchi/vms/*:name*/storages
+* **GET**: Retrieve a summarized list of all storages of specified guest
+* **POST**: Attach a new storage or virtual drive to specified virtual machine.
+ * type: The type of the storage (currently support 'cdrom' and 'disk').
+ * path: Path of cdrom iso.
+ * pool: Storage pool which disk image file locate in.
+ * vol: Storage volume name of disk image.
+
+### Sub-resource: storage
+**URI:** /plugins/kimchi/vms/*:name*/storages/*:dev*
+* **GET**: Retrieve storage information
+ * dev: The name of the storage in the vm.
+ * type: The type of the storage (currently support 'cdrom' and 'disk').
+ * path: Path of cdrom iso or disk image file.
+ * bus: Bus type of disk attached.
+* **PUT**: Update storage information
+ * path: Path of cdrom iso. Can not be blank. Now just support cdrom type.
+* **DELETE**: Remove the storage.
+
+**Actions (POST):**
+
+
+### Sub-collection: Virtual Machine Passthrough Devices
+**URI:** /plugins/kimchi/vms/*:name*/hostdevs
+* **GET**: Retrieve a summarized list of all directly assigned host device of
+ specified guest.
+* **POST**: Directly assign a host device to guest.
+ * name: The name of the host device to be assigned to vm.
+
+### Sub-resource: Device
+**URI:** /plugins/kimchi/vms/*:name*/hostdevs/*:dev*
+* **GET**: Retrieve assigned device information
+ * name: The name of the assigned device.
+ * type: The type of the assigned device.
+* **DELETE**: Detach the host device from VM.
+
+### Sub-collection: Virtual Machine Snapshots
+**URI:** /plugins/kimchi/vms/*:name*/snapshots
+* **POST**: Create a new snapshot on a VM.
+ * name: The snapshot name (optional, defaults to a value based on the
+ current time).
+* **GET**: Retrieve a list of snapshots on a VM.
+
+### Sub-resource: Snapshot
+**URI:** /plugins/kimchi/vms/*:name*/snapshots/*:snapshot*
+* **GET**: Retrieve snapshot information.
+ * created: The time when the snapshot was created
+ (in seconds, since the epoch).
+ * name: The snapshot name.
+ * parent: The name of the parent snapshot, or an empty string if there is
+ no parent.
+ * state: The corresponding domain's state when the snapshot was created.
+* **DELETE**: Delete snapshot. If the snapshot has any children, they will be
+ merged automatically with the snapshot's parent.
+* **POST**: See "Snapshot actions (POST)"
+
+**Snapshot Actions (POST):**
+
+* revert: Revert the domain to the given snapshot.
+
+### Sub-resource: Current snapshot
+**URI:** /plugins/kimchi/vms/*:name*/snapshots/current
+* **GET**: Retrieve current snapshot information for the virtual machine.
+
+### Collection: Templates
+
+**URI:** /plugins/kimchi/templates
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Templates
+* **POST**: Create a new Template
+ * name: The name of the Template. Used to identify the Template in this API
+ * os_distro *(optional)*: The operating system distribution
+ * os_version *(optional)*: The version of the operating system distribution
+ * cpus *(optional)*: The number of CPUs assigned to the VM.
+ Default is 1, unlees specifying a cpu topology. In that case, cpus
+ will default to a product of the topology values (see cpu_info).
+ * memory *(optional)*: The amount of memory assigned to the VM.
+ Default is 1024M.
+ * cdrom *(optional)*: A volume name or URI to an ISO image.
+ * storagepool *(optional)*: URI of the storagepool.
+ Default is '/storagepools/default'
+ * networks *(optional)*: list of networks will be assigned to the new VM.
+ Default is '[default]'
+ * disks *(optional)*: An array of requested disks with the following optional fields
+ (either *size* or *volume* must be specified):
+ * index: The device index
+ * size: The device size in GB
+ * base: Base image of this disk
+
+ * graphics *(optional)*: The graphics paramenters of this template
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+ * cpu_info *(optional)*: CPU-specific information.
+ * topology: Specify sockets, threads, and cores to run the virtual CPU
+ threads on.
+ All three are required in order to specify cpu topology.
+ * sockets - The number of sockets to use.
+ * cores - The number of cores per socket.
+ * threads - The number of threads per core.
+ If specifying both cpus and CPU topology, make sure cpus is
+ equal to the product of sockets, cores, and threads.
+
+### Sub-Collection: Virtual Machine Network Interfaces
+
+**URI:** /plugins/kimchi/vms/*:name*/ifaces
+
+Represents all network interfaces attached to a Virtual Machine.
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all network interfaces attached to a Virtual Machine.
+
+* **POST**: attach a network interface to VM
+ * model *(optional)*: model of emulated network interface card. It can be one of these models:
+ ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
+ When model is missing, libvirt will set 'rtl8139' as default value.
+ * network *(optional)*: the name of resource network, it is required when the
+ interface type is network.
+ * type: The type of VM network interface that libvirt supports.
+ Now kimchi just supports 'network' type.
+
+### Sub-Resource: Virtual Machine Network Interface
+
+**URI:** /plugins/kimchi/vms/*:name*/ifaces/*:mac*
+
+A interface represents available network interface on VM.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of the VM network interface
+ * bridge *(optional)*: the name of resource bridge, only be available when the
+ interface type is bridge.
+ * mac: Media Access Control Address of the VM interface.
+ * model *(optional)*: model of emulated network interface card. It will be one of these models:
+ ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
+ * network *(optional)*: the name of resource network, only be available when the
+ interface type is network.
+ * type: The type of VM network interface that libvirt supports.
+ It will be one of these types: 'network', 'bridge', 'user','ethernet',
+ 'direct', 'hostdev', 'mcast', 'server' and 'client'.
+
+* **DELETE**: detach the network interface from VM
+
+* **PUT**: update the parameters of existing VM interface.
+ * model *(optional)*: model of emulated network interface card. It will be one of these models:
+ ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
+ This change is only on the persisted VM configuration.
+ * network *(optional)*: the name of resource network, only be available when the
+ interface type is network.
+ This change is on the active VM instance and persisted VM configuration.
+
+**Actions (POST):**
+
+*No actions defined*
+
+
+### Resource: Template
+
+**URI:** /plugins/kimchi/templates/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Template
+ * name: A name for this template
+ * folder: A virtual path which can be used to organize Templates in a user
+ interface. The format is an array of path components.
+ * icon: A URI to a PNG image representing this template
+ * os_distro: The operating system distribution
+ * os_version: The version of the operating system distribution
+ * cpus: The number of CPUs assigned to the VM
+ * memory: The amount of memory assigned to the VM in the unit of MB
+ * cdrom: A volume name or URI to an ISO image
+ * storagepool: URI of the storagepool where template allocates vm storage.
+ * networks *(optional)*: list of networks will be assigned to the new VM.
+ * disks: An array of requested disks with the following optional fields
+ (either *size* or *volume* must be specified):
+ * index: The device index
+ * size: The device size in GB
+ * volume: A volume name that contains the initial disk contents
+ * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc.
+ * graphics: A dict of graphics paramenters of this template
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+ * invalid: A dict indicates which paramenters of this template are invalid.
+ * networks *(optional)*: An array of invalid network names.
+ * cdrom *(optional)*: An array of invalid cdrom names.
+ * disks *(optional)*: An array of invalid volume names.
+ * storagepools *(optional)*: An array of invalid storagepool names.
+
+* **DELETE**: Remove the Template
+* **POST**: *See Template Actions*
+* **PUT**: update the parameters of existed template
+ * name: A name for this template
+ * folder: A virtual path which can be used to organize Templates in the user
+ interface. The format is an array of path components.
+ * icon: A URI to a PNG image representing this template
+ * os_distro: The operating system distribution
+ * os_version: The version of the operating system distribution
+ * cpus: The number of CPUs assigned to the VM
+ * memory: The amount of memory assigned to the VM
+ * cdrom: A volume name or URI to an ISO image
+ * storagepool: URI of the storagepool where template allocates vm storage.
+ * networks *(optional)*: list of networks will be assigned to the new VM.
+ * disks: An array of requested disks with the following optional fields
+ (either *size* or *volume* must be specified):
+ * index: The device index
+ * size: The device size in GB
+ * volume: A volume name that contains the initial disk contents
+ * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc.
+ * graphics *(optional)*: A dict of graphics paramenters of this template
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+
+**Actions (POST):**
+
+* clone: clone a template from an existing template with different name.
+ It will provide a reasonable default name with "-cloneN" as suffix
+ for the new clone template. The "N" means the number of clone times.
+
+### Collection: Storage Pools
+
+**URI:** /plugins/kimchi/storagepools
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Storage Pools
+* **POST**: Create a new Storage Pool
+ * name: The name of the Storage Pool.
+ * type: The type of the defined Storage Pool.
+ Supported types: 'dir', 'kimchi-iso', 'netfs', 'logical', 'iscsi', 'scsi'
+ * path: The path of the defined Storage Pool.
+ For 'kimchi-iso' pool refers to targeted deep scan path.
+ Pool types: 'dir', 'kimchi-iso'.
+ * source: Dictionary containing source information of the pool.
+ * host: IP or hostname of server for a pool backed from a remote host.
+ Pool types: 'netfs', 'iscsi'.
+ * path: Export path on NFS server for NFS pool.
+ Pool types: 'netfs'.
+ * devices: Array of devices to be used in the Storage Pool
+ Pool types: 'logical'.
+ * target: Target IQN of an iSCSI pool.
+ Pool types: 'iscsi'.
+ * port *(optional)*: Listening port of a remote storage server.
+ Pool types: 'iscsi'.
+ * auth *(optional)*: Storage back-end authentication information.
+ Pool types: 'iscsi'.
+ * username: Login username of the iSCSI target.
+ * password: Login password of the iSCSI target.
+ * adapter_name: SCSI host name.
+
+### Resource: Storage Pool
+
+**URI:** /plugins/kimchi/storagepools/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Storage Pool
+ * name: The name of the Storage Pool
+ Used to identify the Storage Pool in this API
+ 'kimchi_isos' is a reserved storage pool
+ which aggregates all ISO images
+ across all active storage pools into a single view.
+ * state: Indicates the current state of the Storage Pool
+ * active: The Storage Pool is ready for use
+ * inactive: The Storage Pool is not available
+ * path: The path of the defined Storage Pool
+ * type: The type of the Storage Pool
+ * capacity: The total space which can be used to store volumes
+ The unit is Bytes
+ * allocated: The amount of space which is being used to store volumes
+ The unit is Bytes
+ * available: Free space available for creating new volumes in the pool
+ * nr_volumes: The number of storage volumes for active pools, 0 for inactive pools
+ * autostart: Whether the storage pool will be enabled
+ automatically when the system boots
+ * persistent: True, when pool persist after a system reboot or be stopped.
+ All storage pools created by Kimchi are persistent.
+ * source: Source of the storage pool,
+ * addr: mount address of this storage pool(for 'netfs' pool)
+ * path: export path of this storage pool(for 'netfs' pool)
+
+* **PUT**: Set whether the Storage Pool should be enabled automatically when the
+ system boots
+ * autostart: Toggle the autostart flag of the VM. This flag sets whether
+ the Storage Pool should be enabled automatically when the
+ system boots
+ * disks: Adds one or more disks to the pool (for 'logical' pool only)
+* **DELETE**: Remove the Storage Pool
+* **POST**: *See Storage Pool Actions*
+
+**Actions (POST):**
+
+* activate: Activate an inactive Storage Pool
+* deactivate: Deactivate an active Storage Pool
+
+### Collection: Storage Volumes
+
+**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Storage Volumes
+ in the defined Storage Pool
+* **POST**: Create a new Storage Volume in the Storage Pool
+ The return resource is a task resource * See Resource: Task *
+ Only one of 'capacity', 'url' can be specified.
+ * name: The name of the Storage Volume
+ * capacity: The total space which can be used to store volumes
+ The unit is bytes
+ * format: The format of the defined Storage Volume. Only used when creating
+ a storage volume with 'capacity'.
+ * upload: True to start an upload process. False, otherwise.
+ Only used when creating a storage volume 'capacity' parameter.
+ * file: File to be uploaded, passed through form data
+
+### Resource: Storage Volume
+
+**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Storage Volume
+ * name: The name of the Storage Volume
+ Used to identify the Storage Volume in this API
+ * type: The type of the Storage Volume
+ * capacity: The total space which can be used to store data
+ The unit is Bytes
+ * allocation: The amount of space which is being used to store data
+ The unit is Bytes
+ * format: The format of the file or volume
+ * path: Full path of the volume on the host filesystem.
+ * os_distro *(optional)*: os distribution of the volume, for iso volume only.
+ * os_version *(optional)*: os version of the volume, for iso volume only.
+ * bootable *(optional)*: True if iso image is bootable and not corrupted.
+ * used_by: Name of vms which use this volume.
+
+* **DELETE**: Remove the Storage Volume
+* **POST**: *See Storage Volume Actions*
+* **PUT**: Upload storage volume chunk
+ * chunk_size: Chunk size of the slice in Bytes.
+ * chunk: Actual data of uploaded file
+
+**Actions (POST):**
+
+* resize: Resize a Storage Volume
+ * size: resize the total space which can be used to store data
+ The unit is bytes
+* wipe: Wipe a Storage Volume
+* clone: Clone a Storage Volume.
+ * pool: The name of the destination pool (optional).
+ * name: The new storage volume name (optional).
+
+
+### Collection: Interfaces
+
+**URI:** /plugins/kimchi/interfaces
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of current Interfaces
+
+### Resource: Interface
+
+**URI:** /plugins/kimchi/interfaces/*:name*
+
+A interface represents available interface on host.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of the Interface
+ * name: The name of the interface.
+ * status: The current status of the Interface.
+ * active: The interface is active.
+ * inactive: The interface is inactive.
+ * ipaddr: The ip address assigned to this interface in subnet.
+ * netmask: Is used to divide an IP address into subnets and specify the
+ networks available hosts
+ * type: The net device type of the interface.
+ * nic: Network interface controller that connects a computer to a
+ computer network
+ * vlan: A logical interface that represents a VLAN in all Layer 3
+ activities the unit may participate in
+ * bonding: The combination of network interfaces on one host for redundancy
+ and/or increased throughput.
+ * bridge: A network device that connects multiple network segments.
+
+* **POST**: *See Interface Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Collection: Networks
+
+**URI:** /plugins/kimchi/networks
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Networks
+* **POST**: Create a new Network
+ * name: The name of the Network
+ * connection: Specifies how this network should be connected to the other
+ networks visible to this host.
+ * isolated: Create a private, isolated virtual network.
+ * nat: Outgoing traffic will be routed through the host.
+ * bridge: All traffic on this network will be bridged through the indicated
+ interface.
+ * subnet *(optional)*: Network segment in slash-separated format with ip address and
+ prefix or netmask used to create nat network.
+ * interface *(optional)*: The name of a network interface on the host.
+ For bridge network, the interface can be a bridge or nic/bonding
+ device.
+ * vlan_id *(optional)*: VLAN tagging ID for the bridge network.
+
+### Resource: Network
+
+**URI:** /plugins/kimchi/networks/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Network
+ * name: The name of the Network
+ Used to identify the Network in this API
+ * state: Indicates the current state of the Network
+ * active: The Network is ready for use
+ * inactive: The Network is not available
+ * autostart: Network autostart onboot
+ * in_use: Indicates ('true') if some guest is attached to this network and 'false' otherwise.
+ * vms: all vms attached to this network
+ * subnet: Network segment in slash-separated format with ip address and prefix
+ * dhcp: DHCP services on the virtual network is enabled.
+ * start: start boundary of a pool of addresses to be provided to DHCP clients.
+ * end: end boundary of a pool of addresses to be provided to DHCP clients.
+ * connection: Specifies how this network should be connected to the other networks
+ visible to this host.
+ * isolated: A private, isolated virtual network.
+ The VMs attached to it can not be reached by the systems
+ outside of this network and vice versa.
+ * nat: Outgoing traffic will be routed through the host.
+ The VM attached to it will have internet access via the host but
+ other computers will not be able to connect to the VM.
+ * bridge: Aggregated Public Network.
+ The VM that joines this network is seen as a peer on this network
+ and it may offer network services such as HTTP or SSH.
+ * interface: The name of a bridge network interface on the host. All traffic
+ on this network will be bridged through the indicated interface.
+ The interface is a bridge or ethernet/bonding device.
+ * persistent: If 'true', network will persist after a system reboot or be stopped.
+ All networks created by Kimchi are persistent.
+
+* **DELETE**: Remove the Network
+* **POST**: *See Network Actions*
+
+**Actions (POST):**
+
+* activate: Activate an inactive Network
+* deactivate: Deactivate an active Network
+
+
+### Resource: Configuration
+
+**URI:** /plugins/kimchi/config
+
+Contains information about the application environment and configuration.
+
+**Methods:**
+
+* **GET**: Retrieve configuration information
+ * display_proxy_port: Port for vnc and spice's websocket proxy to listen on
+ * version: The version of the kimchi service
+* **POST**: *See Configuration Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Resource: Capabilities
+
+**URI:** /plugins/kimchi/config/capabilities
+
+Contains information about the host capabilities: iso streaming, screenshot
+creation.
+
+**Methods:**
+
+* **GET**: Retrieve capabilities information
+ * libvirt_stream_protocols: list of which network protocols are accepted
+ for iso streaming by libvirt
+ * qemu_spice: True, if QEMU supports Spice; False, otherwise
+ * qemu_stream: True, if QEMU supports ISO streaming; False, otherwise
+ * screenshot: True, if libvirt stream functionality can create screenshot
+ file without problems; False, otherwise or None if the functionality was
+ not tested yet
+ * system_report_tool: True if the is some debug report tool installed on
+ the system; False, otherwise.
+ * update_tool: True if there is a compatible package manager for the
+ system; False, otherwise
+ * repo_mngt_tool: 'deb', 'yum' or None - when the repository management
+ tool is not identified
+ * federation: 'on' if federation feature is enabled, 'off' otherwise.
+ * auth: authentication type, 'pam' and 'ldap' are supported.
+* **POST**: *See Configuration Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Collection: Storage Servers
+
+**URI:** /plugins/kimchi/storageservers
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of used storage servers.
+ * Parameters:
+ * _target_type: Filter server list with given type, currently support
+ 'netfs' and 'iscsi'.
+
+### Resource: Storage Server
+
+**URI:** /plugins/kimchi/storageservers/*:host*
+
+**Methods:**
+
+* **GET**: Retrieve description of a Storage Server
+ * host: IP or host name of storage server
+ * port: port of storage server, only for "iscsi"
+
+### Collection: Storage Targets
+
+**URI:** /plugins/kimchi/storageservers/*:name*/storagetargets
+
+**Methods:**
+
+* **GET**: Retrieve a list of available storage targets.
+ * Parameters:
+ * _target_type: Filter target list with given type, currently support
+ 'netfs' and 'iscsi'.
+ * _server_port: Filter target list with given server port,
+ currently support 'iscsi'.
+ * Response: A list with storage targets information.
+ * host: IP or host name of storage server of this target.
+ * target_type: Type of storage target, supported: 'nfs'.
+ * target: Storage target path.
+
+### Collection: Distros
+
+**URI:** /plugins/kimchi/config/distros
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all Distros
+
+### Resource: Distro
+
+**URI:** /plugins/kimchi/config/distros/*:name*
+
+Contains information about the OS distribution.
+
+**Methods:**
+
+* **GET**: Retrieve a OS distribution information.
+ * name: The name of the Distro.
+ * os_distro: The operating system distribution.
+ * os_version: The version of the operating system distribution.
+ * path: A URI to an ISO image.
+
+**Actions (POST):**
+
+*No actions defined*
+
+#### Collection: Debug Reports
+
+**URI:** /plugins/kimchi/debugreports
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all available Debug Reports
+* **POST**: Create a new Debug Report. This POST method is different
+ from the other ones. The return resource is a task resource which
+ is identified by the url below
+ * task resource. * See Resource: Task *
+
+### Resource: Debug Report
+
+**URI:** /plugins/kimchi/debugreports/*:name*
+
+A Debug Report is an archive of logs and other information about the host that
+is used to diagnose and debug problems. The exact format and contents are
+specific to the low level collection tool being used.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of Debug Report
+ * name: The debug report name used to identify the report
+ * uri: The URI path to download a debug report
+ * time: The time when the debug report is created
+
+* **PUT**: rename an existed debug report
+ * name: The new name for this debug report
+
+* **DELETE**: Remove the Debug Report
+ * name: The debug report name used to identify the report
+
+* **POST**: *See Debug Report Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Sub-resource: Debug Report content
+
+**URI:** /plugins/kimchi/debugreports/*:name*/content
+
+It is the sub-resource of Debug Report and the client use it to get the real content
+of the Debug Report file from the server
+
+* **GET**: Retrieve the content of a Debug Report file
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Resource: Host
+
+**URI:** /plugins/kimchi/host
+Contains information of host.
+
+**Methods:**
+
+* **GET**: Retrieve host static information
+ * memory: Total size of host physical memory
+ The unit is Bytes
+ * cpu_model: The model name of host CPU
+ * cpus: The number of online CPUs available on host
+ * os_distro: The OS distribution that runs on host
+ * os_version: The version of OS distribution
+ * os_codename: The code name of OS distribution
+
+* **POST**: *See Host Actions*
+
+**Actions (POST):**
+
+* reboot: Restart the host machine.
+ Only allowed if there is not vm running.
+* shutdown: Power off the host machine.
+ Only allowed if there is not vm running.
+* swupdate: Start the update of packages in background and return a Task resource
+ * task resource. * See Resource: Task *
+
+### Resource: Users
+
+**URI:** /plugins/kimchi/users
+List of available users.
+
+**Methods:**
+
+* **GET**: Retrieve list of available users.
+ * Parameters:
+ * _user_id: Validate whether user exists.
+ Essential for 'ldap' authentication.
+
+### Resource: Groups
+
+**URI:** /plugins/kimchi/groups
+List of available groups.
+
+**Methods:**
+
+* **GET**: Retrieve list of available groups, only support 'pam' authentication.
+
+### Resource: HostStats
+
+**URI:** /plugins/kimchi/host/stats
+
+Contains the host sample data.
+
+**Methods:**
+
+* **GET**: Retrieve host sample data
+ * cpu_utilization: A number between 0 and 100 which indicates the
+ percentage of CPU utilization.
+ * memory: memory statistics of host
+ * total: Total amount of memory. The unit is Bytes.
+ * free: The amount of memory left unused by the system. The unit is Bytes.
+ * buffers: The amount of memory used for file buffers. The unit is Bytes.
+ * cached: The amount of memory used as cache memory. The unit is Bytes.
+ * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
+ * disk_read_rate: Expresses the total IO throughput for reads across
+ all disks (B/s).
+ * disk_write_rate: Expresses the total IO throughput for writes across
+ all disks (B/s).
+ * net_sent_rate: Expresses the total network throughput for writes across
+ all interfaces (B/s).
+ * net_recv_rate: Expresses the total network throughput for reads across
+ all interfaces (B/s).
+
+* **POST**: *See HostStats Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Resource: HostStats
+
+**URI:** /plugins/kimchi/host/cpuinfo
+
+The cores and sockets of a hosts's CPU. Useful when sizing VMs to take
+advantages of the perforamance benefits of SMT (Power) or Hyper-Threading (Intel).
+
+**Methods:**
+
+* **GET**: Retreives the sockets, cores, and threads values.
+ * threading_enabled: Whether CPU topology is supported on this system.
+ * sockets: The number of total sockets on a system.
+ * cores: The total number of cores per socket.
+ * threads_per_core: The threads per core.
+
+**Actions (PUT):**
+
+*No actions defined*
+
+**Actions (POST):**
+
+*No actions defined*
+
+
+### Resource: HostStatsHistory
+
+**URI:** /plugins/kimchi/host/stats/history
+
+It is the sub-resource of Host Stats and the client uses it to get the host
+stats history
+
+**Methods:**
+
+* **GET**: Retrieve host sample data history
+ * cpu_utilization: CPU utilization history
+ * memory: Memory statistics history
+ * total: Total amount of memory. The unit is Bytes.
+ * free: The amount of memory left unused by the system. The unit is Bytes.
+ * buffers: The amount of memory used for file buffers. The unit is Bytes.
+ * cached: The amount of memory used as cache memory. The unit is Bytes.
+ * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
+ * disk_read_rate: IO throughput for reads history
+ * disk_write_rate: IO throughput for writes history
+ * net_sent_rate: Network throughput for writes history
+ * net_recv_rate: Network throughput for reads history
+
+* **POST**: *See HostStatsHistory Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Collection: Partitions
+
+**URI:** /plugins/kimchi/host/partitions
+
+**Methods:**
+
+* **GET**: Retrieves a detailed list of all partitions of the host.
+
+### Resource: Partition
+
+**URI:** /plugins/kimchi/host/partitions/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the description of a single Partition:
+ * name: The name of the partition. Used to identify it in this API
+ * path: The device path of this partition.
+ * type: The type of the partition:
+ * part: a standard partition
+ * lvm: a partition that belongs to a lvm
+ * fstype: The file system type of the partition
+ * size: The total size of the partition, in bytes
+ * mountpoint: If the partition is mounted, represents the mountpoint.
+ Otherwise blank.
+ * available: false, if the partition is in use by system; true, otherwise.
+
+### Collection: Devices
+
+**URI:** /plugins/kimchi/host/devices
+
+**Methods:**
+
+* **GET**: Retrieves list of host devices (Node Devices).
+ * Parameters:
+ * _cap: Filter node device list with given node device capability.
+ To list Fibre Channel SCSI Host devices, use "_cap=fc_host".
+ Other available values are "fc_host", "net", "pci", "scsi",
+ "storage", "system", "usb" and "usb_device".
+ * _passthrough: Filter devices eligible to be assigned to guest
+ directly. Possible values are "ture" and "false".
+ * _passthrough_affected_by: Filter the affected devices in the same
+ group of a certain directly assigned device.
+ The value should be the name of a device.
+
+### Resource: Device
+
+**URI:** /plugins/kimchi/host/devices/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve information of a single host device.
+ * device_type: Type of the device, supported types are "net", "pci", "scsi",
+ "storage", "system", "usb" and "usb_device".
+ * name: The name of the device.
+ * path: Path of device in sysfs.
+ * parent: The name of the parent parent device.
+ * adapter: Host adapter information of a "scsi_host" or "fc_host" device.
+ * type: The capability type of the scsi_host device (fc_host, vport_ops).
+ * wwnn: The HBA Word Wide Node Name. Empty if pci device is not fc_host.
+ * wwpn: The HBA Word Wide Port Name. Empty if pci device is not fc_host.
+ * domain: Domain number of a "pci" device.
+ * bus: Bus number of a "pci" device.
+ * slot: Slot number of a "pci" device.
+ * function: Function number of a "pci" device.
+ * vendor: Vendor information of a "pci" device.
+ * id: Vendor id of a "pci" device.
+ * description: Vendor description of a "pci" device.
+ * product: Product information of a "pci" device.
+ * id: Product id of a "pci" device.
+ * description: Product description of a "pci" device.
+ * iommuGroup: IOMMU group number of a "pci" device. Would be None/null if
+ host does not enable IOMMU support.
+
+
+### Sub-collection: VMs with the device assigned.
+**URI:** /plugins/kimchi/host/devices/*:name*/vmholders
+* **GET**: Retrieve a summarized list of all VMs holding the device.
+
+### Sub-resource: VM holder
+**URI:** /plugins/kimchi/host/devices/*:name*/vmholders/*:vm*
+* **GET**: Retrieve information of the VM which is holding the device
+ * name: The name of the VM.
+ * state: The power state of the VM. Could be "running" and "shutdown".
+
+
+### Collection: Host Packages Update
+
+**URI:** /plugins/kimchi/host/packagesupdate
+
+Contains the information and action of packages update in the host.
+
+**Methods:**
+
+* **GET**: Retrieves a list of all packages to be updated in the host:
+
+### Resource: Host Package Update
+
+**URI:** /plugins/kimchi/host/packagesupdate/*:name*
+
+Contains the information for a specific package to be updated.
+
+**Methods:**
+
+* **GET**: Retrieves a full description of a package:
+ * package_name: The name of the package to be updated
+ * arch: The architecture of the package
+ * version: The new version of the package
+ * repository: The repository name from where package will be downloaded
+
+### Collection: Host Repositories
+
+**URI:** /plugins/kimchi/host/repositories
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all repositories available
+* **POST**: Add a new repository
+ * baseurl: URL to the repodata directory when "is_mirror" is false.
+Otherwise, it can be URL to the mirror system for YUM. Can be an
+http://, ftp:// or file:// URL.
+ * repo_id *(optional)*: Unique YUM repository ID
+ * config: A dictionary that contains specific data according to repository
+ type.
+ * repo_name *(optional)*: YUM Repository name
+ * mirrorlist *(optional)*: Specifies a URL to a file containing a
+ list of baseurls for YUM repository
+ * dist: Distribution to DEB repository
+ * comps *(optional)*: List of components to DEB repository
+
+### Resource: Repository
+
+**URI:** /plugins/kimchi/host/repositories/*:repo-id*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Repository
+ * repo_id: Unique repository name for each repository, one word.
+ * baseurl: URL to the repodata directory when "is_mirror" is false.
+Otherwise, it can be URL to the mirror system for YUM. Can be an
+http://, ftp:// or file:// URL.
+ * enabled: True, when repository is enabled; False, otherwise
+ * config: A dictionary that contains specific data according to repository
+ type.
+ * repo_name: Human-readable string describing the YUM repository.
+ * mirrorlist: Specifies a URL to a file containing a list of baseurls
+ for YUM repository
+ * gpgcheck: True, to enable GPG signature verification; False, otherwise.
+ * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
+ repository.
+ * dist: Distribution to DEB repository
+ * comps: List of components to DEB repository
+
+* **DELETE**: Remove the Repository
+* **POST**: *See Repository Actions*
+* **PUT**: update the parameters of existing Repository
+ * repo_id: Unique repository name for each repository, one word.
+ * baseurl: URL to the repodata directory when "is_mirror" is false.
+Otherwise, it can be URL to the mirror system for YUM. Can be an
+http://, ftp:// or file:// URL.
+ * config: A dictionary that contains specific data according to repository
+ type.
+ * repo_name: Human-readable string describing the YUM repository.
+ * mirrorlist: Specifies a URL to a file containing a list of baseurls
+ for YUM repository
+ * gpgcheck: True, to enable GPG signature verification; False, otherwise.
+ * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
+ repository.
+ * dist: Distribution to DEB repository
+ * comps: List of components to DEB repository
+
+**Actions (POST):**
+
+* enable: Enable the Repository as package source
+* disable: Disable the Repository as package source
+
+### Collection: Peers
+
+**URI:** /plugins/kimchi/peers
+
+**Methods:**
+
+* **GET**: Return the list of Kimchi peers in the same network
+ (It uses openSLP for discovering)
diff --git a/src/wok/plugins/kimchi/docs/Makefile.am b/src/wok/plugins/kimchi/docs/Makefile.am
new file mode 100644
index 0000000..679aa18
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/Makefile.am
@@ -0,0 +1,28 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+docdir = $(datadir)/kimchi/doc
+
+dist_doc_DATA = \
+ API.md \
+ README.md \
+ README-federation.md \
+ kimchi-guest.png \
+ kimchi-templates.png \
+ $(NULL)
diff --git a/src/wok/plugins/kimchi/docs/README-federation.md b/src/wok/plugins/kimchi/docs/README-federation.md
new file mode 100644
index 0000000..c184f4f
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/README-federation.md
@@ -0,0 +1,60 @@
+Kimchi Project - Federation Feature
+===================================
+
+Federation feature is a Kimchi mechanism to discover Wok peers in the same
+network. It uses openSLP tool (http://www.openslp.org/) to register and find Wok
+servers.
+
+By default this feature is disabled on Wok as it is not critical for KVM
+virtualization and requires additional software installation.
+
+To enable it, do the following:
+
+1. Install openslp and openslp-server rpm packages,
+ or install slpd and slptool deb packages.
+
+2. openSLP uses port 427 (UDP) and port 427 (TCP) so make sure to open those
+ ports in your firewall configuration
+
+ For system using firewalld, do:
+ sudo firewall-cmd --permanent --add-port=427/udp
+ sudo firewall-cmd --permanent --add-port=427/tcp
+ sudo firewall-cmd --reload
+
+ For openSUSE systems, do:
+ sudo /sbin/SuSEfirewall2 open EXT TCP 427
+ sudo /sbin/SuSEfirewall2 open EXT UDP 427
+
+ For system using iptables, do:
+ sudo iptables -A INPUT -p tcp --dport 427 -j ACCEPT
+ sudo iptables -A INPUT -p udp --dport 427 -j ACCEPT
+
+3. In addition to the openSLP ports, you also need to allow multicast in the
+ firewall configuration
+
+ For system using firewalld, do:
+ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s <subnet> -j ACCEPT
+
+ For openSUSE systems, do:
+ Add the subnet to the trusted networks listed on FW_TRUSTED_NETS in
+ /etc/sysconfig/SuSEfirewall2 file.
+ Make sure to restart /sbin/SuSEfirewall2 after modifying /etc/sysconfig/SuSEfirewall2
+
+ For system using iptables, do:
+ sudo iptables -A INPUT -s <subnet> -j ACCEPT
+
+4. Start slpd service and make sure it is up while running Wok
+ sudo service slpd start
+
+5. Enable federation on Wok by editing the /etc/wok/wok.conf file:
+
+ federation = on
+
+6. Then start Wok service
+ sudo service wokd start
+
+The Wok server will be registered on openSLP on server starting up and will
+be found by other Wok peers (with federation feature enabled) in the same
+network.
+
+Enjoy!
diff --git a/src/wok/plugins/kimchi/docs/README.md b/src/wok/plugins/kimchi/docs/README.md
new file mode 100644
index 0000000..f400333
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/README.md
@@ -0,0 +1,247 @@
+Kimchi Project
+==============
+
+Kimchi is an HTML5 based management tool for KVM. It is designed to make it as
+easy as possible to get started with KVM and create your first guest.
+
+Kimchi runs as a Wok plugin. Wok runs as a daemon on the hypervisor host.
+
+Kimchi manages KVM guests through libvirt. The management interface is accessed
+over the web using a browser that supports HTML5.
+
+Browser Support
+===============
+Desktop Browser Support:
+-----------------------
+* **Internet Explorer:** IE9+
+* **Chrome:** Current-1 version
+* **Firefox:** Current-1 version Firefox 24ESR
+* **Safari:** Current-1 version
+* **Opera:** Current-1 version
+
+Mobile Browser Support:
+-----------------------
+* **Safari iOS:** Current-1 version
+* **Android Browser** Current-1 version
+
+Current-1 version denotes that we support the current stable version of the
+browser and the version that preceded it. For example, if the current version of
+a browser is 24.x, we support the 24.x and 23.x versions.This does not mean that
+kimchi cannot be used in other browsers, however, functionality and appearance
+may be diminished and we may not be able to provide support for any problems you
+find.
+
+Hypervisor Distro Support
+=========================
+
+Kimchi and Wok might run on any GNU/Linux distribution that meets the conditions
+described on the 'Getting Started' section below.
+
+The Kimchi community makes an effort to test it with the latest versions of
+Fedora, RHEL, OpenSuSe, and Ubuntu.
+
+Getting Started
+===============
+
+Install Dependencies
+--------------------
+
+**For fedora and RHEL:**
+
+ $ sudo yum install gcc make autoconf automake gettext-devel git \
+ python-cherrypy python-cheetah libvirt-python \
+ libvirt libvirt-daemon-config-network python-imaging \
+ PyPAM m2crypto python-jsonschema rpm-build \
+ qemu-kvm python-psutil python-ethtool sos \
+ python-ipaddr python-ldap python-lxml nfs-utils \
+ iscsi-initiator-utils libxslt pyparted nginx \
+ python-libguestfs libguestfs-tools python-websockify \
+ novnc spice-html5 python-configobj
+
+ # If using RHEL, install the following additional packages:
+ $ sudo yum install python-unittest2 python-ordereddict
+
+ # Restart libvirt to allow configuration changes to take effect
+ $ sudo service libvirtd restart
+
+ Packages version requirement:
+ python-psutil >= 0.6.0
+
+ # These dependencies are only required if you want to run the tests:
+ $ sudo yum install pyflakes python-pep8 python-requests
+
+*Note for RHEL users*: Some of the above packages are located in the Red Hat
+EPEL repositories. See
+[this FAQ](http://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_packages.3F)
+for more information on how to configure your system to access this repository.
+
+And for RHEL7 systems, you also need to subscribe to the "RHEL Server Optional"
+channel at RHN Classic or Red Hat Satellite.
+
+**For debian:**
+
+ $ sudo apt-get install gcc make autoconf automake gettext git \
+ python-cherrypy3 python-cheetah python-libvirt \
+ libvirt-bin python-imaging python-configobj \
+ python-pam python-m2crypto python-jsonschema \
+ qemu-kvm libtool python-psutil python-ethtool \
+ sosreport python-ipaddr python-ldap \
+ python-lxml nfs-common open-iscsi lvm2 xsltproc \
+ python-parted nginx python-guestfs libguestfs-tools \
+ websockify novnc spice-html5
+
+ Packages version requirement:
+ python-jsonschema >= 1.3.0
+ python-psutil >= 0.6.0
+
+ # These dependencies are only required if you want to run the tests:
+ $ sudo apt-get install pep8 pyflakes python-requests
+
+**For openSUSE:**
+
+ $ sudo zypper install gcc make autoconf automake gettext-tools git \
+ python-CherryPy python-Cheetah libvirt-python \
+ libvirt libvirt-daemon-config-network python-pam \
+ python-imaging python-M2Crypto python-jsonschema \
+ rpm-build kvm python-psutil python-ethtool \
+ python-ipaddr python-ldap python-lxml nfs-client \
+ open-iscsi libxslt-tools python-xml python-parted \
+ nginx python-libguestfs python-configobj \
+ guestfs-tools python-websockify novnc
+
+ Packages version requirement:
+ python-psutil >= 0.6.0
+
+ # These dependencies are only required if you want to run the tests:
+ $ sudo zypper install python-pyflakes python-pep8 python-requests
+
+*Note for openSUSE users*: Some of the above packages are located in different
+openSUSE repositories. See
+[this FAQ](http://download.opensuse.org/repositories/home:GRNET:synnefo/) for
+python-parted; and
+[this FAQ](http://download.opensuse.org/repositories/systemsmanagement:/spacewalk/)
+for python-ethtool to get the correct repository based on your openSUSE version. And
+[this FAQ](http://en.opensuse.org/SDB:Add_package_repositories) for more
+information on how configure your system to access this repository.
+
+Build and Install
+-----------------
+
+ Wok:
+ $ ./autogen.sh --system
+
+ $ make
+ $ sudo make install # Optional if running from the source tree
+
+
+ Kimchi:
+ $ cd plugins/kimchi
+
+ For openSUSE 13.1:
+ $ ./autogen.sh --with-spice-html5
+
+ Otherwise:
+ $ ./autogen.sh --system
+
+ $ make
+ $ sudo make install # Optional if running from the source tree
+
+Run
+---
+
+ $ sudo wokd --host=0.0.0.0
+
+If you cannot access Wok, take a look at these 2 points:
+
+1. Firewall
+Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
+
+ For system using firewalld, do:
+ sudo firewall-cmd --add-port=8000/tcp --permanent
+ sudo firewall-cmd --add-port=8001/tcp --permanent
+ sudo firewall-cmd --add-port=64667/tcp --permanent
+ sudo firewall-cmd --reload
+
+ For openSUSE systems, do:
+ sudo /sbin/SuSEfirewall2 open EXT TCP 8000
+ sudo /sbin/SuSEfirewall2 open EXT TCP 8001
+ sudo /sbin/SuSEfirewall2 open EXT TCP 64667
+
+ For system using iptables, do:
+ sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
+ sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
+ sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
+
+ Don't forget to correctly save the rules.
+
+
+2. SELinux
+Allow httpd_t context for Wok web server:
+
+ semanage permissive -a httpd_t
+
+
+Test
+----
+
+ $ cd plugins/kimchi
+ $ make check-local # check for i18n and formatting errors
+ $ sudo make check
+
+After all tests are executed, a summary will be displayed containing any
+errors/failures which might have occurred.
+
+Usage
+-----
+
+Connect your browser to https://localhost:8001. You should see a screen like:
+
+
+
+Wok uses PAM to authenticate users so you can log in with the same username
+and password that you would use to log in to the machine itself. Once logged in
+you will see a screen like:
+
+
+
+This shows you the list of running guests including a live screenshot of
+the guest session. You can use the action buttons to shutdown the guests
+or connect to the display in a new window.
+
+To create a new guest, click on the "+" button in the upper right corner.
+In Kimchi, all guest creation is done through templates.
+
+You can view or modify templates by clicking on the Templates link in the
+top navigation bar.
+
+The template screen looks like:
+
+
+
+From this view, you can change the parameters of a template or create a
+new template using the "+" button in the upper right corner.
+
+To create a template, you need an ISO on your host or using remote one.
+If you are willing to use your own ISO, please copy it to out of box storage
+pool (default path is: /var/lib/kimchi/isos).
+
+Known Issues
+------------
+
+1. When you are using NFS as storage pool, check the nfs export path permission
+is configured as:
+ (1) export path need to be squashed as kvm gid and libvirt uid:
+ /my_export_path *(all_squash,anongid=<kvm-gid>, anonuid=<libvirt-uid>,rw,sync)
+ So that root user can create volume with right user/group.
+ (2) Chown of export path as libvirt user, group as kvm group,
+ In order to make sure all mapped user can get into the mount point.
+
+Participating
+-------------
+
+All patches are sent through our mailing list hosted by oVirt. More
+information can be found at:
+
+https://github.com/kimchi-project/kimchi/wiki/Communications
+
+Patches should be sent using git-send-email to kimchi-devel at ovirt.org.
diff --git a/src/wok/plugins/kimchi/docs/kimchi-guest.png b/src/wok/plugins/kimchi/docs/kimchi-guest.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ec8fea930b71c0e03a40700d79c4bbb63bf54e6
GIT binary patch
literal 192281
zcmX_H1ymftwj_bz?yd>$?gV#t3&Gvpli=>|PJ+7ym&M%|cXwapFM03%;c$Rucc!QN
zcHLWbYr>QiB$43p;UOR(kff!=R3IQA*&rZ3mcc at UU+F)bp$GqfHj<STgLr%Y%55)6
z0KWp~Af at dL0fB(={`~<WJrfuFB8-c)yg1A%93~nE6l}>L_!S5|7jZ2YQF~ikQ#%(3
zQ72PF7gG~bcS{!wQb}ofCC#76I1mt|5Yl48Y97lctL~X<bE|;Mi5Ao0aqOe%I7)c(
zd{WM8x&i#K)IRhAX`k}27-_kyLW^`tt9Ys~mj2IAVn*x(iwJI*g=M8bq|WI_?pD)U
zPBZsomhjwCJ|zcHZ=Jt*ePQLhUvu6cKN){qo0+}Z9f{iaWar>eR#yIb4uTT?F^^9c
zh$;e07Why~Q&er6k)KZ<KlFLXBwmX?I6<LAx?~3Y?l_quZqP~Ht`*#W-h3xL!GDb?
zLz7P}GM38H>yZsutTCoxVEBS48p-06^q&)=f->bOd&{-!AgXC;X<>i;FkzKOg+e#^
z-+#-+$bYJYr>Em*GD|r>9VQH!OfNPvXiCCf4&`Ddt9)noVp{7}P7Y#)ULB9h%Mxg^
z*F%q3`7)LI{5XAA({0ha=JUyR<Zwq>DOu#hN$-LdELq<gi{<p^*UK3Hjlj51xb!3O
z8hB)VuL<h(1PiV;a#HgsAA+`97n46Nn;*Ag(Z7C2I*YxGBuEuGcg$B#txguNThH$R
zDh&{^|43cU&zGl&Fvw9<|HBj#g)8AGcj^b%C_3s05fJ9{JjwpXFR?QA!hph`W6|`M
zOh-RrKKJWW`87RsG=DsqK4kJ(+5~jg_rbwlJf)-S?s89?S{ZJO9Sbk))3ryw8mMS1
zqF<5Gq514|`|U%#>t>UKHHg%82cw#Cnr(6SDV6!%DAI{UU53Wc+rwg<BCs{<(>lhH
z-5;0-q+-!TPBhaw88(ATifdS02 at Rf}wNzT;coYRkfMr}51TN%~uDWA0Z$7{BuO*rN
zl)|Z(dpm#1<OS&L30~t`BMZie2H*BJsBQAdF0g at WU_49CFA;J16BFCoLbz=7`4cSJ
z)+lXlo}xQrospR+SUHhoi8s$uIDaWPK8xcp|FQPD*U7+KY at FD_$^NbrHBvGRVEr31
z0jd%N9Q$dGAG&h~w3=w&OtX!;K`Ze)U<yQ>Ap6-<+W?H$*5CRv at eu%4$gC1m)`K47
zg3h=R+5VaP#~7KbAP4AVZD7M6>i%&^g~_hxl((UJPhF|o!;#!PQ$k+KrUailIPhwY
zS*F<pq8j<5dCJ>pcLsClOJG>$h|iGhE-kF}3vH;bxZG_fN`yEa*X$dUqpZi={rzgp
z3~dAGZdAXP&wqACBWr)0W;zo_Lkm=<dfmhSRjk8VVIbMwXvxmD<aEGuQ-7R#zd|^#
zu7g{Z=z at Fd$Hi=X@%OX2 at 4nl(axgU_oJfEv-(q8wh%us;!kOb)!%=ioF0Q<4KkvMT
zR&x-uao#X8<#7o&sLkD>l2y#`D{h0W{1lWR_ahO|yXu8~?wBj?%!{9E)qz-FJ(L7W
zsx1;#<fQXzWRTm5CJ+_GP*fcWI9ht!+bmh9;Jjk*@Oz|5gtpWe_e%y5dqwZ?2yJ*L
zcwL-1zipjQjOJTBr`_oDWd*5=6S|ILA`gvkZCWB+4hK7*nWi||ypfYvMc<osbX`|<
z4i!s8>CWcRXzGt|>dRHi*&|fFY;%q3HUIQj7kwBNSLH5uC%X5$HvbE}=dNr!`3Rk;
zmF2Hp^Z8btq}s+enAMEApod)fBo-VkT at U5@+*#(?-cfU|g2SiXn^f7|cmNUwpBK^R
z3od77IGiGidgU8jH$=^EuDo^rer!zht(k89?%d`cKx$JReNEsv>vmP=?$T})E(WU7
z=*4A;!&za$A)2+2T#$m|IH<?pu_rWML at Df-3~}cv@;57~i{Eq|V`(s)R~IPu+pe8~
zXuZ(2m#d!^F*=9t#}9|M7IO9vQ}$I4 at r?RkQa$ENcn&AgzdfxI{rzSjS0j*+<KxWh
zJK!5;Ewq~TX+mHqqHe8#x0>dRB{E^0Cj_o{#ACmu^P;Ohitsjx;PIx5_w_QQ&6A4%
zm-QRS8Bu{2PFMtX>Vq=oC2;*USvrA|#c5}7wL^LzB*<nyZZerGjEKh?2u8f)s?PC?
z&0aiq3#E`4s?|~Ol72CU*xi^P+c!`&r53nRV{E-Jk!etb)ryv_Ee*|24Vs4rMyaZ)
z$eBIjKN0z}uKh}*_u2E)K;}(XRS<~wWHY}!xjuK^NkK6l`-S7VRn(%@tFV>t2nkzu
ze1JX?b*nU-Z}<q0ACuFy)ZTWv6(Q?!+MX17qOCx#E~ZQ#U9@;+Us+4I;zL58 at 1_%x
z9uSTkij+3^^SJo38^(UK%0MjkU;?c`V9kRkKsc__BSMnIGduXFB-?KJ<}6dzc)ewe
zk^6afNeBr5rxN$4I0IWw#&~)#y>Bp)NZ6+ulla1YbZa|pD`lr+zi$J%6yoQiihFec
zS1RFTr0eY67Eh)Nor#~B?s5id5tp=&`V6aGZT9@~b0EjAe4oL%NTJUX^l63Ea;SB}
z1mgT at pOeEZ;KO-Ndm^Oos7<%G79Q_suBnCmSXCulO&?FpQ|~T150~%Zqq(hF33B|x
zQGTJxy^d}s-k%J_A1Ypt638BK-sz1K{Ym9|QP1|=AnCJzz{gPF$>Fd*H-4RoF(iuJ
zdl`io at 7yAUraJ8Npa3U74+lb+A~nAClwf8=J|Du7TBnLTnW=VfcW^Rnv^~Fb>|y?l
zC~7vAE>4+{S6ds;pxZcEWzgB<dHU?VCY6dN;)8BSRCGxn5<du8Fe$;MIia5S$4<^!
z0~WHC$eYtVJ9gvp_Pn++Kf7i>a|rGXRIYVHsm`HZ_(D&>S(!g|-u<|rHLfh6M_v)e
zE{4ZU*+b;QZJx>fQ>~HjT+TnF^@)D7QP8}iE%(E)lXR6wqL4r%Jb(jgsP}O?MWJw3
zj6nzPit4v=jUb`t^Vc(9JACVWcKw))9^o*5wq6Js<<31 at PLmPt&C<(AffI=7U9^bx
z^x^oT3?BEJ%}CyIs&hsE%;8|(aO9Ry1O+?=xrOtM=g~&%*(=XoBbbcT#}m2qU!jB6
zJvEqVM=~F0aGKO{S;q`1$HLv$H(rziu#BN#*j{6aE1Im=<gr{0M=#ACMt{<{r0!<z
zua^k(R6n>9>zZwv9#ylt(rYD{u8_efXZ!r>cjJMH!WU077 at Eo8+z@Z)z8u}g)7|PF
zm at 8jzO$~}@bXuW#;W<7DqwhTbvgWmJx>J+07y8;C$ZGfl)kp}L6<paAwYGY-?YFuf
z55!3lFXfTuCmP)z&6Vr7VHaTvc-?%T`=efN&`At%<i1-p<|DKKuP9ZP3%dQ^OX!hg
zhTcY71^!F1r at K>G%+pp-Qy{ot at RKL#5);#p*(uGxPrdH8d406uVtkp^3fHfz049=g
zy%x0eWK&0AK;z45e?=>T6Wy?MVvEPC=fq`~;8~<3hb855|3RxZu>G6+AXI99AQV@$
zO!(BcH<AUK$a8jKVZSGGsN%6m7wJ3Kfvv0Wa0np)0wkzm0&;%s`zB_8Ac7Fif?t5y
z$Py?lRoY#PDM3(=ywvOgt=P#NQv7OunH7OTm5da+GS9$NAv53NOtUhfifq=)e&%b$
zShE(ub2+L?tq;QV_pfO6q?bQFPkhGBo}}4-X8JZH9g?`aRzMm+GT-De)2L51QWHi+
z^s5VC0ck;g%Dk~5imOG~`+ZVa%<>%9Z!(aQYs?KdFi?5c=ath96CFyKtiviH<0CI{
zHZ-J1WZRVBk|L^L$6E=uCdZG;D#{kfJ$^?aM?bP$ae2+qL`Orjbk?#eprEXbmL>;1
zGJLBLnqRt#U6>V&M;5sFwnN*Mr#_CSsjqld<-awj9mA%s?Q^Co`ThLhym0)~TBkwE
z2Gm=g3Dxe6QoNW37 at 09s^}2!RS=I at MCK6kJX#CN4hS(kBqXJ_vFk!duhAw{_b&&PU
zqUd_uYY2$!o|9xH&-1KO(p at M-#+4_zcU=3{94g%Zp+R=PW?Yu#X=5$*kGtoU!9?v8
zQO_e4vdKv8u2vZ9(_K_kix(e{|0m(r59?YtN1UOMpp at FHF~mQfca4ppbZi_hpqip@
zfYocBIQ_g6ooE{$ZG_!Ru<9@(Yt6Sv+&PqAl=DpbvJ0#!^QujFYJXD&1wiOc>*i0#
z=kfT(p60h+>2f%f(FYQ0b-zkV+QV>;CpKX?S^T@@unE}%w?kZ$mL|Yyqlg)i=josT
z;b)%hq@|6`iPDcr9X6XqW{GG*xGuV?zdeI-6o+$VI1snDw?w=OubJ3P-{eF^A$x<7
z3V#0%`y!hRF<GLRvr52L(7-qfOA0<EBvG)*jC|oL;!<v80^{GrgFKMuVMEAc=Q0DK
zD}=`(yT<jXk at 7);G*=uFhlI5clPvEkh6H|vXzddFAvI}_;X!Ibs at nPW@JY$TO9njE
zS_Z<aHLR}@+PBuQ`h5(`0L~Twp3ql}&5{|DTH?5Qi`A!?_VIb;l-0Awna1buKaqWF
z57|3#^0Lqevb<O%%VOmyMNv(pxIRHCOVt9j#`#LZOALInIvM at 2PFN+fJg^fa?ur~=
zg*?kt5@>aL6YgK(MD0HQ7^&h;Bh4Voa=a*5A!;Q}pgaY@)eq!evRSgaC6mHBKod{=
zrkKC#;hVVL|HFZJj2&lb)pMPpn{>5KBV&jsA1j}rU=G)_r#&ghXoK%knHkw_Z+Cme
zW;v})saZKLKc^>n!aXin5w~9=)W!5IVl!Xr7Ps46B1XInR%k|S8DVl6RU1x%$QM2;
zO0Y`djiA$W>C2oeDaM3QjBzU`%YGPDS`+U^-&^aCI+)qG)eF9CzXzJ(DiA*mj;>g|
z1$Zg)f`fyz1lOl7VuwryO;~Y_rHWJ at Iu!NwSM5k7t>ww%zV8gi-JGowOk6vpn~$AH
z$tu5kOT4_C`*ZE*_zQNNkF?PTF8Wg^>5^guL_4ikmOsl}<0jU2TQH|f5hR)#(j*<H
z7iTo7=N6RqcK}JOfh2RVqRwdpsFv-ggpri2^@2GH?Vk}wRDzuCZZl1dcPDVF=`-fJ
z08YEpfAxV(%oQBTw)>Sa(UZYM{G4M3tnecmE#vNE6(Zq!DeZUIq^oZ9?W?@3e6*U!
z7P{H0 at FT-X3r8GS<3;_Tg!OOQ6;(fnqHI-?dsO~B>UB5XpZKDQgev}tk4LXvT9L0D
zcOWd8EX_~saU{&AK2oBPrN`c$k|gOLy0=YWVG{{`31@*CgM?MT{u80>EG|SvuNIH>
zy(hNxVi7gC;vNY|TxKfH_vU<M`bY1}a=qWmkq_@}yoghXQoTSR9ArK=AUePLcKvp5
zK^n6jc$J$-KI)IhVV~ijDP(pG2&P_~&!fLjxSL?mv{8b^v&~ua<N>ZtNHw)@r!bA6
zLfckWu!z;)6aPe(FSEvi^1kZ;(@QFK at aho1oZ8_1iezb<YmT2_V*T&~bqgcbdQ?F)
zW@%`<5p;H-RpD>9Oi$hN^5adwN1RWudivxcEUS?h*ZA%LKNUF>SUFx$u;69BU}z3H
zIeNGfpbkX!e&o9orPk~LQvom+N8K{U%cpO_{P(*^XiS0P=<Mj at hsq@z?Dc!TdfXUP
z5XMNYgMNw_xw6(L?r?ISb-?xC6_0oUi at Y(Em56?$zU at o5690cEh-ID$BgGI$!@|N+
zQ&(43QJFr=7Zy30=wapxvS&>zH0bo>juy4GWjLO%po7X3fFo7LL=#8L-e+;x_}c1n
zNDlcY=zUa%X7;6(m1e80u7s|$%8ALzoQiF<SPYj#c at 2~aL(Jymgf_rp at B1@)gO1F#
zcJCQ*@ni#Bqx<<ATrQc8B(s=};u--p#QrxXya8NJyOlw3r3 at AhlEg*&sWiYLKU=Ci
zn#G5+;5wy~AX7AGR_9$22 at V*rfB at bi=w|QQK}}UKUeM`cDsy2$%~x$VJI7k;&$A?J
zCzb=a(}(Qf;aPKNP{MxXv|kg`*2Y6ZLV^<hnj`32`ulet7!=7wgKMqkXop8eXc!rj
z6(b%NBl1Hl_1mUrXT^B480!a4tjZ&8cjvDsgWYh%Y;L{3X|++rA~1rl9O_FpO1)wd
zA82bhSRqouX6?CUKf(6>N}MngamkgF#YSH+0Fa#>!1hXB$=!&fe6tCKZ;U96im8G3
zDHO2%d~ERc89RavJP-3#29n0c6sD&7TAh9Z8C>>eleyi0L1%o0Gx9!rY^uD>;}V;c
z=!<!hoF_gbF|~x~jxbCaw$Azt=;ClLoKZ|jviS*Hm)wT9=)r~|zYx1listC`v_}>p
z+noAh8Qb)}v=@}!!@r9)&mp~$<k%xuD;4XTRrVEt2zJAPt@;dmv-<7HDP=0&()}XI
zY*L;xgiHsA6#cbT+p3S)P{L*K@!Q;s$x-{>Z7V{szch{y7aPaG#AaaC{Vk3Z7MJ at 1
zB2mSn0*~u#ut!c2M~^uOX#a+1h}(#(nj2aYuCzp1i$={Sq1+=5!yyN{C8FoOV(s8<
zq!KpQ$w?HSDdu^8B8h0(SROgp77NM&WQ{%Vh38D~C%2`ouyrlea>gF`G%x7j_))oG
zTVP(qEO4>x?!>Ktdb}fvbQ)&}(2`B1!8JE{M|Pl_eWj6KZRNP>I3hk1BokNtu7sN}
zirnQS@=>Tu3!X at vdSt-WriYYt8rqbnxl;asLrLEpm&b>?UDg<vXcLBP04z-O*I+5*
zey4{4sNfQzTLo<|LUjPn{oV)^gly4!gOMd^f>?r6zIn!dk;T4jIJWP*b|bd9ni=1t
zvyF<1dOp(ZT-w$8X~Q|P&~djO6i%Ymw>|g#bfWtE`RsaycieE~S?Ds&zH>C_4Fp3;
z?2c|K5Dwc=tXj8%FN#_GyS$uolHn|!KpwT2`)FogSq~G{<?cbGCz2)5P%E|aF9mDI
z00PAy{Ac9VuEjeL`THKYL<>pd=fkEVj=|9WdLg*p`G6hWc0XbBG8FZ9))W`=g<g~@
zyEjZ=;i3)n&B&Tl3;=STLNXwKebDFcH2LCe-x=^!Wiaxi#ee6%$_AoH8ab`6sgpO%
z)c=j=?TYfM?k&CRSLa(|$u!_{l_^JN+6~vGi}ah%;ipJtL?YHi9%u6!k4x`J!JBI2
z3cMLNq$oAo{@oP+pWf%~IWDc1A)x+kN4vJu5<TDBhR^6>K7V`N^z`VA=E~jxO>ciw
znVw$-1^si4PHS0*(UJ2sM~1O7U<(kjI0SuzV~VR9(%jb!Vpd<iM&r)Kq(aMb)LgZT
zm#?LF)13Aih7iO4C}Jzu{`({8R{jQ;JzNy|;1>(0zE=`P({2FWog8kkMMV?BW6(N|
ztycRNd0S(~ztrp*O`ND+#LjE$GPstlNdtH*ZMbD)<v$*OPyPe9*O`-{1gdqXi*A_n
z!mB)o%-DV={@xJ;oH~o~GJY;=ieBW?eh?GG_pUVatqHH>q+X`ol=Wx+ZP2{a{um0&
z)c~;NG(Ccck~1eq(6sqzU?Nt(Hqp7`o^HH4dkfg9H$LaS+V5}RfT>FYE>K&|omS0}
zO>aBj22 at 8<uGV1seRiKB4icEDO{Y57AsX#gd-D6wmDTn8VMzW?9EbuOPFOJ9JYm34
zpUj{;APhsKc0gO)Q0)KqdULYmTmm96K3J-wT5Y?xAYLqY$fUm}e#JQt6hy$W+3l(F
zPpAv&gL6qv at xPbNW+3i$9P0Pkw{};VYY<YH(>rTB|H5frms{q!S#__<v!zP7O0u^K
zVmtFNr4tyoq2=P5zVGVB^gMpJUoVMcJPiXr2)_9_ at UF)21VPHuJ&bAE<sZ#P;OU~H
z4Mo{crSaiL_pY=!zZa%UHpzCYt+w}kN^={Ror;x4&H+Z^;>jNb!nIYWzD_X0VOJ^E
zdFZF(>{sjtPPK=&R4f!L%hY&Yo4w;R4NcsCaJQYr$R?vmHpQ*pbl^L={A10&)8!`I
zba7(#kj-XGC}x4gy{KueN!daTXI*rVP-{5VhrcrOl;OXxk;%i^{ZM1qF0eTSV)i!d
zf+G+61C3j+XM5xy5&(|<rWB8}nk1W%x+J@?jL=n{B8A{M#!DFAssWG~-X5tFx=cz%
z<NM2nEQAlmq*?whK!Bp18+W7Ks-Vi=-XicD=p*ZYh#RQEa-)|RRrw*G(oMm0{7gfr
zqap8ghs93xY%A#R#IrqJ<$OFs(Cp>#snfssC)4YzcjoL^4+?oTVfqp2oIS3&e0C3+
zKEKTTw=vxaEAHP-K^amTw6TN~cVd2{awCpx43B<dyaX!hIeBDRpf89N^5kb*yqt}v
z)qd6#hPZ~2b*o4ahh~)TNeV?Yq%94vg62>tGmau$3I-dQPFJlIOT)QZ`4T-m!MOR!
z- at mIypOBmgEg0=v at 4yP?xQ=nk9hGutx|M-4_DHRtDWpDh(x#cl6;OzNquM#f^fBPR
z#^`1a(LqGc`4bIs%yrsO&Ta!<mBUsaMqYq$@$TXepHFny5tsgN?o95hx8Bo-Hwvoj
z&JzN?U`z<};Lk>IlL&C+-aTTfJBnMs8r?W|+zTbfMZ|<w6Qxy`p at r7zKU7KYI!o^n
z3pbIDtnQ((Dlg>ai4`v5RL0%?rs%i6#j4^MG|xF?l)_AqpAl1~n at A>RzSH(A$go)-
zNA5>_VgCoyVDU1p{6w-e+O6t17*^*yk at 7(bcn+$_1L+lYV8c-(VFJZFcGf5crcI7)
zg^am7vizXD;AcmD68uT2Id$fQo04+{@BiGt>f>NxkZA+?Z9Pnnd7kn{Ab$`*>?N2(
z?8N5Z4DuUDwl!J~7HxS>C;scTPDGE-8)V>XOJ4Q5=l{^@-_aeFL!daltRY=%8!@9O
zVBEA&ZK1mf-y0i-5km#rlXX_oV0LrRyR1*t4iHXw81AyNdsv!~UVk8B6lkrtO>zW<
zSOFo+fT+P<idRR|UL8Ij?$aC%fi*jKZL(QPC#H`qY<%#9;&377-&pa1wMy{gFKZ(=
zN7 at qd`srL}ydk8sfpKKVL8pHF?i`}&@1<K`2&Ngh5HarISl^B9aQr*@V at m91tH<6a
zs?srI)8HBYTPOEVmV+*%n@<ZDQT^vNPO=y-$KpAL`Zf9)b&PMUMW*RW?&enuZy|=~
z^aYgMKM4FCaA8s`lA{D-&Jl5=F|_2GAE1Z19<@$qLwM_O4ZPiRGSbtX>WWTx9Atj)
zrA_NJisIEqA+bL(Z!||V_clJ9Dca>el?mk<Y{VfU4Fnd>XkVcX+gtTnXLHMd<k`(W
z{+c!PIW5Czd2wIgLl_u1^}~I8iDH_R-M^b_>4B}4H_0%M9pU8MBH-o!(um3j@?D&o
z9Ub_}OMvYMgE`qC3kNUmo1j>o;F{=Wp3MGU3xx{g6)R*}jq{!J`>e0q8x)>{_-`gf
z^_+&j^ck^0fQ2EUhgbKOtKqW4)e^3O)ShM5WYfGvaa?F9;jWzXM+!}!L%JZ}Zg3(Q
zkdGw*mBaCq7z3*1LmTz=iY_6e2%MF_?s(%;MH~MN<M%m5cdzK_FuZ1;uSty%pY>Yr
z64hnVBltKW*}ugdZze|d1s%?={Z=EI_lVlc$_kgqX@^l)`OL?GjEQNntFQptVLPZG
z>}Gr+EltQ at P?FFQ3K9l6 at xO@32;OZE+cD>Bv!f)Mr>it~{4pa{59t1{BP2YxvoqSw
z7q*Rd6+6?iOxq0$#dRh_MjdZ2x(}Bz_M4e?6aB8M$#|$#*%sQqy$t-(amTS{7!kI|
z>1Kc};9cW3L$T)g>2V`(8z-pM at hWD;Lr<{XXyWWUd&pguJjCSuo1PQ5(8HEikJ9$1
zDMtVGWotOBcdD`o6l5_hK261|;COku-479Zh7(3*HtZ2gtQ|CC({o$eU2GIpRi$uW
zd!+MOKUZ7eB)e08WS*Jo+613RR1Ub#^S(^5aBSYcx8}d$hUJ$sCuooC*Dcv>uFK2I
zU(uj}cF)B|CLaB_pnpOA>s&sUXoElqYBI{Is-pbF=NGN4U}{r8kBH0sBZ`1aMMvj}
zgr=arzTT78`CkaU5mFg!uK)GCR#?z|<Sr{OHyKT3nI0yGYWeVlL8V}Fce2!6IZ`a2
zad$@qB_ktKT2b*OVQBCZ4)_MeLR{(*d}x!524l&9J(1hoe{c6P%Ju8asx+;Z6<SSy
z5LMna7l<?8SGUP at h?~t5*bkP7!5UZ7BLEyrfB$(x!KTn3d%r=51=mYok|Gn{<*ZL>
z0g{oq)=hS8D~-EPF$x{EZ?Dru^m@$>6ScC=T0@#fE|^#vWfP`YLAKgssw8Env;vQ(
zI(9KCL9UES at MWGtzsdh~WkY=h2f2}}I-Y3Fvs|$o8XEXIJm28J-3bbb=tBGTj<yv}
z><FwYk-UthXy_q#O7-2h1*a#?py5>{HzFJ0_$SOF_%UgQk}z8u5}$HTGO75AcjyRw
z;4ZBw6D0^Bfl>)sl}-&?Hu>peEGfuU53sb~7C>VCM-~k+jYLG%FgDdK60Mba>tWkw
z?c6~kbPAY1p-t%$x4$oOx?MXzD%F+j)4tz7I8?YyYqjUgwPoeyk-(JAc%$pXXN)lY
zkTikA?Q9gvcVa_E$sB0SahXo;71Ul$BSPi-yk$jBXVXwI at SVf7<`}=4RWOYDBY;xw
zGi-PQ)T)eQx*`{eRiRMFe=d;Hpx3N#&A_$oo@?4J7*4KHsVD9#kCbd$Q&bxdrZA2d
z!W9D}_3&)oIvyQmS{+IKV$jL7tsIGLiJLcOsMykf7C5ROyWC4n^bK{D`jV at P3R|PI
z<HTFSrXVAlr`flZP1S4i*oAj5ek#RV&CSVujQV$BRFGmS+^<|z6H=~|!s143Ay}z1
z>d_PFGC99>5qB2E at pRl>q;|YrLWy$+(s1smz{KC&Ln(A=|MLPEYV+vg&+jRWqeyq$
z3ciSpS;%lFa=)l$8qpJC5(o1V)z%b;HDOnp%(E0+7;$PukW&1Vc-IU>PL7jYe%GDx
zDt@)gXR2^5;~;OCKOJ{ip&fN;JS<a>Wx+37%hwbq8K8>Z`(Z)-A=s<d0#RSlNy|Vl
z#HzYlBxlE477xoxLE&yIR*PjdNq!iGH0zU5t{x&|uX?;_EmmO<Hxo7xsK`tz at Akfk
zs753+jTve5TOG%fO?;W{j=9hDCIh&L!PDWa68(~FJv>k%85Ofiyo_PI&B1d;vcFer
zu>iGU6~IBMZHJq{ZOfz8gp_a$t>k?30>Gd=5 at Gd*fZ8%-5^1y%1X)PZ{jO_Ubl0`>
z>QbTWe{XR=$*qO44VKNjAS12&dkFRm>kDoge;}hF&YvD$86gtmsjen%gNA4q{dDF?
zhk{VM2JJ2L%$@`q9IE1}!l}4{KJpb|76k&9FvYi1o~<PrQt~5#&?e|xv5GRL`aU0Y
z>^<u?%9#H|{)5`|{eYM*x*0F38SjjK*=fdhAfxYrYzq*fjRt!E;qMek{itz%(~~$&
zE|@tyw-F6=(5szYU+p5c(U4ZGZC%VcUw4vTms)K_r;wW_R4Zg({t6*<y!l8hjOy|f
z0RG^i3;u$uG-X0i8d^Se&ozJT5`FYGSQAy20sm9S8a)gudfUfhb=haVq_Hu%!xyv#
z5*$c9HFLCh{Pxfha}EMaH~hpY#d80^Ehg554cIO>b;vxkq&7=CitA8;D^Q;OxqzJ2
zm-Vmf2EUb+^@Tu=3vZS#Dpj~cYqF9qA;6?AsGm(2I_;S>M{~_HVJQp>KInej%%Vo#
zd?8&~Mp;{Xs3_%I_&MnB<p9B0-5+7Fa-m~AE(o%bk(GT<O(Q8xC8edIstP<oJkEPy
zHB&GV#mJ9k<^v at 3#Yx at 7Rf*6`7z~MzL&&)@ZZJDLyTh!qB>3*iG^>(p#Qwz*$u&HP
zYIoU1qNFXYfv{}a$pA~WFq2%ZJ%2Beq1;+Wo- at Jv5G)2kjnU=c14Yd1f{el37?wR~
z+X^x{pA4}kiF{Znhe`IgNa<phOq)u0aWN%0-<{W)j$kL#Ym2C>V}VyFI2gL)X|Bp?
z)pdczevN<4V;iZ5d8atTZfnJPV)qqvzCYprdM$Y+Jgc+Kt&k`F=hXV+!CE`t{faXR
zc(8j%WmS|JW5Z1U_IaP6igb$Ck|3&?4$^}?o=GCP+=GYPS6oX at WF5(ubZBy+1y{Ot
zbvhD}9%dWYzdmewoBTc~WxtbC*F&vEcbZL%#UB(b?c(G|80*JR6lA44!W6CLaf25d
z<x!z#=jK at ao;@nt&UnGf*TYndpBSciVq)S2IG?|(a at dS|p~tOI!WVg+HGBkAiJizb
zT9GN=yxt{$%*wFm>3?|O!+s~hRd;t305VQp+O{(z;`u7*vZJef1=30mGS&82HkZvA
z6H5}*O{cxAC8lJB5>{FiT(2m%ZL!_o)Ub=xn&`MuA`VzZT<xL7 at 1gw@U^Sm!sg|xn
zj^yUdyp+Y&bV^&m!NGxvgL6G%@EQ+x@^n0o*`tdq=gBUCZ9g8T4GYvXG~JE1KI>Eo
zL%9u<*bxo*W$`ja at C?-8cF_8L%|E*ldYD)liera5ZNd;{PqwM{XLPvm at Nk{>8Xaq}
zo(E23fre82#8hc=Tdj7R>GQL*7q?aZS<}-hdJ7Ct;_q<}dpV^x&8KR(prfjxG0=}=
zFe;9tulDd*<^N)x?S00BkB@&>cFE;kVQOanGuJkDN at oU>$Ac_!fXtLY&O(dV1r5L`
zKn!pW%}2$sT~D7`8)~xgRFc_+UXx6}rG;JvG5bwANWestMt|?0*V$7yO-&*Cfg{G<
z*slA#VYd;i0f9>fgV!q at ubYGJ7{8kWk)}H8aH*1+LKT|IjwdVdat&tkID-Qikwh>v
z41>yPLEoLlYL=Q(F7?NJI)K<aax8<ZAknBN5H6B{3wh!?mBknu9CDO#Qs04YWSMGe
zYRpbMQsB3LoyZno833ykB-JKE=vLO&2>XYg#D=&|<2?J!CWEN&>cGw6%q4$}7`ZTR
z at I%K0SH~ri*=TBazIeplF%;ALbk%f1=ZcYcH+9 at HL<_w>XiWH?S{oSO985iLzz7}O
zJY2r;j-DKSePk{u2wkQg`Xh%En)1DbA{cOdXjt-FMw8|KhU=iE66Z5!90~RvaOn~l
zoSwW2nAfz~ML9(G^VsPoG{a^q)l@`YZcXYS;JUEbRU&6<f1%Ceo4k@=(7}NE(D~5M
zge&01?!NBJ1 at 7U3ODxRR_#i{6s&DPh&sQU!J8_b!eC~`o)&r4vy<qr(?@H4ACM_=h
z30wp3gws`S<VP at WJsnq>uQWTFu;L+eZ$L11K0DcUJeuu|XCWxTvI>E1U|_R=kSthL
z2KRY`lGDK9a18Fg;#A5yI<hDVKAPkm>ypQ9th%r7mKnTQ8IFQYacC)ePH-LPbuNd~
zJrn<wp}vqRTduljd=4v2aD8ZV-?AOe7yXWPmNUht4#~i`L2EeQdMAgI_I2|51v9o|
z>L5deb}2++*}p!xmP{t{r%q3;_FGmto at UtFPlV#iw&6PZbpR%r4-Ip3&vyac&o&Of
zvcrCCzO*Wx*cA`UUk~fx$fhaCn>ZX6r8r#;QL%a7*${hdd@!ofGUQhTDt!XSM4ql@
z3Zs7W-LiGdUb?kbqYYjHmEzu?vdS%ce-Ht<R$g(Lk+)f{4}(PEk2QFETF~=8ZJ^hx
z{=tk0794k|gdX8E^&CGTVAF4a=}=*1CGwB_{QMphI8SgKr?l*6dwU$@g~0a4X4rS6
zVJPy)(Wn+PyB?`UvIJe%(<1;Ib=#5uZM~XvwgJp!7)wQZY~zcKZi@<`zs$z;64|#{
z&<k?=k340ecX8NxtKZBiJF{4z%L++qx-po)wAa){^@Yni;A<M=bAp=<b#!LAq5;v3
zQB{Wr&6&x<`LQNZhL^Qia_3VC*GAS3L at 6BtBixd<M$$9Xf2 at uWfNq6BaJh;(f|=fD
zEnxfM!Bhbrw*x7O&&7utEqbnForo|v9q968Kqu&|O}oJgOBs^|JbK2~1M=bF;pXdc
zKJ6wuA{}dNdaW*s82+9hoNrPKmHOIXHJ(Bu^80WiO}SRhFI~HqB4!}LS5;MvuVu_v
zJqSz};0#e$eKvO5v_39PmDR at rAnXl55e(h;JRN7HGXB?}AQNo;KHW&X6zA(U7hYF)
ziyajW`wJFW6WRk?V57Itt&&^tgLxMBt2SqJ0?6|^`+)g#sFSI^_gd~ttT2`Ss5D*5
z<!D*NMLBLwbMIO>d)BFRJ#cljQNX?$gGS0ta*1((T4m_-7v;z&UU0iLt>?-bP>(2_
z<@<90H<Z1O6H1PLI*|%#*bz@<ez3X{ZO#?>pnB4(wxCw0v6ef!x2&pTIR1<5!<l>M
z2ol#ymps?%tQA9A<3iDC&AJ~5jMji_evJwpb=<aEu;HaA_jO=E0$i#?c7>u*Xo2UF
zD%0WPmoHzyNmF2Ue%>gOMovBp#ff1=r`5&MP<etnT&w!~2Z-Nl;b85r2E0q$dLv!f
zF#d4~3zx=>C9nzgeWG7L_v>dZF1%x-X>3gyYIG9}BttkQk;Z$@BRqT0Y`D9XTND1C
zKkm6Wr*9|gT6SgtQ%$qguN9gP3!Px!qs)dDJcjrU$s3-a`v97YEOdG5Eny5lM?i&k
z23byfS_FzC4W0u{6Eb&3wI8MX^NztRZ%sS81#bo#@9L&Jjri!iSSdCWsaQyhI7<L2
zDPnI=YSg$|sjdRIQfa1fX{mL7EsY2PB(;j8Xbw3F(2;j`cAhoUX6<j<J781g_{5jw
z_@!TN1DuyFOHMT|hC><~8FX!RC3O_UD-!en{w4e|SElKHfZu?`Wn1#i4)}+%g7sgy
z0}5WPNT|?liUtR7$?E=D`~9~y-}_afaWk`&o4rA{%FX-E)=-DF0y$qNXslaHbmNZU
z*>(R2$bh21oYovL25tnMPfO}Is)Cd^)HxTnXKgRCi5eYakz8~<d)99wimxD_)|TK3
z=bZ0*UO7>+Ya4MP#2Yy=6D32--VAJ6yE}B<Z36R9;y7htx5}Xb!ZcDK<YWS>jIn&6
zW!Taxmm{#14c}NtZu10G=o`iP9WvTfm2e`;G|Xi&Zzn at Y15=!xlha5WyJ_8z4-ASs
z??4O&YBdcFqo%Yk746vNL=C at A%F8rIPz<D{r466<?s`_vk{jxB{zFw`DEnMoXwZxi
z-~BmzqiJ&4{Ana_4}f>pK0GY*j^doQ%VM6MJmB;XT=2{|9(DWp?Q#76VVhtMa|wFl
zxMyy?GxGZxO3P)k<lq42#CZA66ri(*MpCfHz#ztX>Me7kmdb8p at 69)9Qh8J_ac^@y
z3veK5uz8DhUh`+!d}9ymZ^L)NjwAw6g@}a|sn1fB38(V{*S(*?+9mSw3&}Dsn+#24
z?SU2T?@7TpPA!=!Tx}b;HdJvkVO-n$k8bx-O!cE$Xv5UZ at Jie=1(DF05;Td(HMTIo
z+E5Gs)%2_(_ka--*5{iNq1}C<Hy)wqO%$-QL<dCj;zK|_Z4bU{bR`VwkHEnQCIgW8
z^T!Cia#tQV!n51X+>Q54jgKq;rx)BOiDSm=<!nGB?&~X%qVI;c{xshN at s40T+mUS5
z^bw at 6%{%e3sl2YV5dI+GdNVjZfsF(eBVRXz={#*+gPRM$UZ&rMa)huWuk2Y~R0`9|
zO1Jn-HmzZ=FJ8t;H(RM^f_3Kfq}G7YrSO|#ywMS#=$`_uUE%P|e8^TZG?WUNgE9Wk
z+e955 at 2P?R`J&g`6*jQ0ZuntbEBO-=0UjZPp|S%a90KdIAyL2q0aFjkk*=%%@~UUG
zu0|ij2)SI5BY`aQz~m0*Hf3$!FIqL+t^RGB8kmm+d}?76If}sAL>0Ll!7MOTyxX_m
z^Y~c@=uG2-u_gm4A3V41+i5G~_5Or8SSZN!dpgu}Uv*vaI<6?3v5aI%OiG$6kc`P9
zHkOQtIy;H}@gM5u&?_f-3_Ns62V-~;0 at L5>>ecr`D4Kf<mJrZ=@2eniJ1f$Di(v5Z
z5fU141029$3R5c1^A!`7Lx_3cd;O4U+};4DF$AQ{&%AbC8)r957F~xCUKek!`5ezZ
zJg{Kbd|cV4V_TKDrMv!w&D8O*g&Y!i(%@>wD?=lW`H-l|Kau<)Kr4rV60c56c_C=p
zE(A?>f;6(ReX;R_k$X>MSguWMz#9CwpnO3GkMT&VC2>_kgjD7AoTdev?t at TfM0cKp
z_EUDZWYY%xoa>a%=O8!?N{4<dO=jOG7ci?)SrjB0q#v>3Kyq4(js`k;?LW_sgJ}-9
z006#Yv!3gm`g?k$*RF*EIO6iUP;;$$P=LuA6CvB%`m?pQw*rIze60-}+kZgGFZI$l
z$2dm7t?g-bh$`o=z5xGuAcjKMy>I-`&Yh`M04H=%kConVS=q)fX)5KX^N>O6AmBN_
z!nuAwq%|k{obBc<1B-+_e|+B!4xCcqlbnf<50av~8duC4r`E89B--+F$9|Hj_Gmgs
zL<D1NC=9VjZtRE3zgIHgG^|vbb5?$~e#l(M7goBPpNy1|?5y+HE2o$}5v=oR2z_mt
zH`TBxDUqYR59%A^WrIc9QWni&{X8|M9s2M<*Pf<6;>AEMEw-%!T1?Aqi6+Jq*dc>M
zNwhe(l?hHoNCccp>gsbxA9a%Z!97aA%l-Pq&QL<j!&XGgX(JH);KTCra?eA$7QF;2
zlu6x^Mjly`47eT?CXcgF&wl4xUqwYlH=pT8jKF at vO!qa<chxx4V=F9 at SRnoA$O^0&
zf<M_ at Da)Tt5Ry1#qNCplrYPV>o{k4tbBdFr95SmboH<m83PS%k-EV2kb!9AU3=4=S
zr9NLRfMcVzHn}b05;S^E at tyu}F><dn{?|a at u&1AAq%^p(nyz`a71WZ%&AIZ{3*&il
z_qI9jfO_3{x3NN3d@)YZbaD5GH?l?>v<Hv;c*CPtEvR663ttRQBju(|=}=#3`rlLj
z7Eb5jJ5PD%X{`RQ&skvB-*AY?0WOWMTPA#?!5#i=Fokz%rqk*$CFi=YH=5jlEIo9?
zJkDQJ12J+Wl{r{rPkm{NR!Jhm_N3+&Or{_~1wRC$9bVfj8k~u$e7*8>R+Ak)qTk6r
z{$qiwA at 2?;EWGh|H#Zw#<3CQKY|&`VBddiePF>`nk5i;(=+^k0Tl{=ts$;G4Ta8R=
zH-;bvfbfCxt$U1wElm!493!2I(ZX-Mwp^ov`_a|>7b$6y44SyIp$7X%EqoPO=htGE
zU{Y9WT3Qh<1DyYoLGWs}IPYIQPWX4I+vnVw)M>x7FtC-SR at d;b5oiaTXEp9R<jF)3
zV$0_7_m4G2GBhN at Bl2(&FhR%3c4cpuMI>1F%>t+Sv at zw63m=KZZwTCx6BO}87Xl~#
zcrsn~)i2Gab2qYb{}#;T-K`^J$)%f}*lThZ6wbo1u2GObzNTelWGv5WrUQ3C&wcj!
z2p#*-Olr0F#xr8JZLHnldSfrQ2jb-@!vNbiM{^P2E7{yHqzzG3Cjabq)t|4_m$Xs+
z1Q{`Mpny)8;!;b-<?HkvK8!A>)h(&x3TRcKoZQ1 at S?(d$xvBqqRcl?(5d}Ukf7hSy
ziWjURIcAD*FHSWlJpU4VL at C(!46?n-qY$DK72M&D4w!G9w3 at kU-EB)bE&c1$Ww}J6
zOcS)t9VE`8E4XmSK at ENes10?zQ2n3YwpB1wTV$#!N(T0t_&@ZLxV1%!kxv~p`}G^0
zfyTTS?d*<BvZ|1m8RsGlHY(jq3=yeEdK`@wE$X2Yjb2s&54$Il&fAt?zTl|5V}^Ej
z%yrR6V!!Wb{1q&+BS_fu`4PNZ7wxDYmD<vF>BejWL at 5)B{<M0PY_l&T<6AXIgsTM2
zXZUclEN@`)hz&^?g`v0JMHzB5iM;DS1hyqKXM@%Uqt0#1m28012azIgjsM8M4-O6b
z?9Q62qdJWeF2#|AV8c*L_nR%326nV at 1AYB1XR`cA2~g0!iCf6nZIz?Ez;$NajSX07
zYUVzzDmYn>$f0w*f)M>>GCE at 08}+GzQ3SYClt}KPpUA>(D3xfR6vnPGT3ploD|=UZ
z>kFfXZRM`;ajE+8e>LE(1k<+UwDGkira*Y(QpH3i0;VrA*k}u6?f7NY8AmK*!T|P?
zzdrZBd4Xi7&4`GiwG28Y4p_J1y3}U`N`m!#HGu<R;mV~N`*eo?RX!u!N-~zHmO=zM
zoV}^OM^ZXr*qqK2m at iTry+9{~iD;BR{_wM22UM(t!t>J`ce%k5hA=??u?@N0ZMW2G
zp<lq?UM|d{#NSfKybbZ&ZjC!S-k{XOZ_?T!h`CywDzr}empB)3c6((<c6r4>3zjhh
zqbHWJAC!j4BdMx`V<<T;5nUFtOKpN}I)%#*RifLU1ytrT9G(${3oYxhic3Q`VTh!_
z53(sG2gzucYtXTn60bsIPr19`>7ytZeGx at J+_d?o8d971S at +*YB@^7tYz!-9v#dc4
zjLZ`g-u}=V`h?i`aT2;sSJ9{-rt5qy;VIm8QVGcrJ6x4;v5ilX-e7pz2AXQGmbN2v
z;|G1aWYVOuLwIdAixIfQ5U$QA;n1DODkdDC*!aTmpR{IVFzc3;wyH0=m*A1bi)FSv
z&Nz=ZTuVALIH+!4W4a<X&+SNF;Ji9v1V??2px^p6^-JEzXh-&!6nc}F0VM8dS>8d^
zn=6_$B{3_DUt-h3G(nP(kk(YSjtbbFo{po>PYlz%|N6>gf{aNnEpTrnh-}`NCg}@G
z-L*p<0vUqpScGnSm}}=8iBXN at 6<uz*pOe4CG8<WcnRDJ#(KpD^C6SQiUM^~Or$O4)
zJ^Y3Vm?5()!p#!M2;P_dz0wRnaed+2*?T<nPt${~VN#neI%~Z?t_K{Co*d?WE^;!~
z?x7~Hb7UYmf58&<N_O^mgOs9D`5Z~PTl8D2Egi{F3N_dxTM}&2lfNXCAZ&efpuLqK
zY>N{#G#IcE47#1LDg5K~Da|GsY{liw06)WLne^_h3PdHzV5V3d<#l_Xw|6P=nI6gz
zch3(s;=P6P=ZKaNIOHnI2AxQbDC)D$R9}y4T&)*z(&~lmcZ&M!r=^#tuU3l*hbxD=
zi9n1TuRLeQYGZEke;5Cf<xipP%dHTaS>i9!_byNo91PQJ;Ib0ByTyeFp)8s^J$^0O
z at 8$rOV3%APd2W+mu(pW(jv>J|QY#H%e8`8BlSS0X$>J9D!{K_Y!i+yY6N<YUW5Xax
zsHWV}NOM~h44O at Iv(*K%5n37PhPH(N2}W#$yR6kdVk4$mAm0uVYi-eE>T6&yYRnfT
zP$6`m9Ei0P1k{s!hz(zwH5c8g3^Jwxj{rO at A=U>&JD>zpUoECISCeg=bzWlr5CV-f
zuZQrl_4aajYWwMOJw4a9qy=I>3zcT2@#bQSlPo&2p~;1ayyf(VM?Hl1ct7z^asfhj
zMb{qKKqj9Kid&xZnzE%*pO~b=)v^=26CIyDvgNdT3*y8ak2s39Id$i(ZxzuEFuThW
z-H$DGIWI(Rw}#-TraL at rruA~4R(kpz*OT2a$X+DDtnC(+0WL3eGdy<#Xo+8j(R^Mz
zf(YlU0_kE1x(e6F_PKB(NeL`EKszv_?PpSck5{xB>ZZ-- at uEB+6a;R27asG-gCS3U
zuY}(zL<8~R5`Oo~I(y&vqV4&g1mT-sW?&qb^{<;>10lIf`TL9fy+hL8IFikAG_Q8r
zbUm*A)abdr at gbfn_aRXsZQZo(UA8%gY%gPTy?Vp3RSLuljcWng2nZfPI4IlT$7OaB
z16r at sSlW4x@2}ImF7wK(hMYhVbe`9(m(LrArtDs1oms5$(w!LqEWnNVN*AjjXramT
zb|mEbDIEWm#h+qAk1hJ`2|zw9YvkiTt)$RqP29<EOueeYxWHeZs#%2xcyZ=pwpM3&
zdz#*qdpy=9<S0c*i8=>7 at U7*_#zjE6zOP5<%LJLub at s6m`w?#oE+1Hb;;07MotL~@
z1Q^p<)2?5cL#S{xVncxsdBWDBtY!(96!fxa&Y0RvJ+8K0s8H!*D+34|17D{bh91Zo
zv#f6~o<p at pDW`*}r#~CFXb at Vg%_BJKA;{AB2$2)l!PN^(0*BSH`-sZKTTr2t+jeyt
zgMj&Z6-b7q(gVQ6;}Gt~AX8g9E*s})nFjiWk7{`<S^61TqY?z7i$ASZshg(Ed(SCn
z&VvC`*!?>R^zTY8nV=)<&%OJ7lCH1-St;|n(JU?!z|wp;RxsH%AnHq+9C{4k-G~(<
zaHll_2Z8y!Fr)0IsZ_ND9mpyDr3pzZoTtS>8M98u<{10+l->S#`SC44?eA_)qwO)L
z{qf?Dwlb#*<fI6s%e!IulhT#DaYv97pOftt(O=GJq;Jxh2K;Xy+*Z14O~keSVfy8e
zv3B_QY at jJ`P)w>ZjagNBPtERs8p)_4J);1rd4#u|_VehJI_mqkaoxLBr)g32cv7-J
zbQuUy81b*+p=#p0Yt}8{-`bB9TawGZRh2Fv=NsV^1q7{mqqI{de*Gv-TDYLv_}6sr
z9*}K*y*iYg;H*G9<nx$`LgnpdzMti}mv*kYhsXbLOQBr$*^Zg;|Bt7id){Uc&0;0;
z5!58#-$>S?N>N*XnIZr00DfkN)>vtxVckYdlaFC%d+16$MKeG9s08!hBg7U1vO!cY
zeaTEB+3exI*Zr4tCd>B5{~wWQO=#hdsNOlwRN?)TNWlUBJ9 at uH;kjFG7fZGzZ_P8c
zBbaJJbanstFeK>zIu_f-X_6^i_dD<6saD}D4cFcO#)Leceh9<AHH)0_;c*h+Z@>om
zsJ8*#`@au&8-5*#>@^c^NdG>MvL0f^;})>_|HIh;j|b&fW=tKUFTCFlIotoA6B&}z
zOzz(Qs_muqg==O at 2voNsq1bs}bgGflU|@Z_rjet+-l%)qQe_LQqM>%_x1<=eC$+uj
z9Pq_Ej#_e4WSvf7Swjb|>D8{P0ts{)7fMdo1ncq^#*#^ay4S6a-aUIjj3-uNJ4J`u
z_LjTAF$SQW;v(m~yg%BF>krUXQ-_}$sV$1j&#H5CE(zeX4m#BXz#Lh4v)sQc(FxMd
z+jz`42gnIs!wKtyvK9>f`wlpCCy{U}KXsQ(OQ9<Yd`U8Bvg6FM>14Qrq5>*3a>d)U
z2^b#hb3s->RGaQ_;&q`wMp_}n-D6=Qw*G<BNL2kyP}-Bi(iNNMxig|puh5w31*0t3
zSGnGT)Pm$O5&5%ckPIyt>b5I`6IzCb8p1LC`{ohU60~2mFoonsOi6SvQ)T+kl2)(m
zfNs$%YK<~2T>Ao^=<JwN=v`)NHRk1971`=SHu1{DUgj(#Vf8j0!v9UTJ%RCnMX7M_
zWyAe>;O|F7x<7b{B|n;jt%);2`1Ti+!Z`kB#$^8K?8GMsj6>-s=`j4C7l7nzyvbnw
zhun=IK_}wxk-`j9tFFaZY8%~s#DY(UqK-RA?%Ron(8Apz!>pgRn;LdJLq+TpFotx}
zH#=k2iQYW>X9&vkwT(U!)~tIFa?pz4?p|c;LvIFY(^Z$6Re!%!dA^BmQc{P%;1A3T
zf%wWWo-6Rlq*XAPhomDi<|=l?^8&);w}eVl?0lqdE`+gCv}>=F%nai1$cl3ccuXsf
zpcx at YW`(wEK|)YuaLzrN*KG^yGK5Swif<r1cuJDpCh}A+AW1fXD^Jp_C;-9+m=2zy
z-jz8TME=wx8J}Yk`|nNniUW#3^X=TW<)4`$e^L6vg6+Nlf1iEhgBLE1En3}PU^tGe
zYE4P5tb(L2{n~AEkS#e=Yx}<~X+C;05iiU!ws~!S5`|Lkg;k>828Cdaf8iU6hc4Vt
zV^#da{u#uW>b!m3Y{s$C6g5Ed<_hcQ+fV1g0(aR_K)GE8LKarD1AOA at 2)9lyrcRW3
zc&=&NxFNb?cEoyXcBiz19oRDd5)em4{DTkqv`^9A2MGb7*ryn?h-~Z=@TqE|x5Qp2
z61gF)fOB~xH%kIyDY(sqvIJev_niKD6{3Gr)NwP7Z>x!`Bh-?P6*B~}_w5<f&27{M
zac$NfX21SK`Ayd8;X<-_BX=nRjhOiZOzGT1XXjX-Zrkb4Yh;pW^}79yIxdDj8IM%2
zgU^}2t+X0?9ZvLBJT_Z+9xks>=j**ZCgKt<8)yPpMn{-WhqNE=AnBOhh7}%~y5Y|~
z)?b at na#{WS_ia`lurKVX<Oj6du;b_rg3k at u5Kvrb5D7Rw3i0|;5%SW1Z7}8-Z+qcb
zX+N;_sVSWr%tw3JQx<g`VIt|9SYw5~{?KTB9T!C$&gMq^i|GHTdh58T+BIAlq>&Ek
z?(UNA2I-KLl1_n<p}V_b07<1&8mXa66d1Ze>2CPe{?6I&e$V_fxn`~3^W67!-MwD>
zt<Ra_i=92PgHP&7H6#NJ!0xru)0GBW%Vc(2HH0h?iR1}WN0NAq7<GHzAhnJYLfxBH
zB&z(RNQ27t20ydG(pr5uD&~0daP$1PxDVT`w at V0P^;_Ghfvw(xX6hcoJFP2#|AO3m
zU>IIte#7cw`W3f5De3>9YX8z)7EkU*pPE%rFWuSKd<@RFJ~X>};&PCXNnUmnt%z5J
z at sasM*b1;(6wI{D{xk{|RJ`z;yiTeBQ3sZUmld@%A25o`%YuvV(<9N0pbZnb;rlq9
zzz$S<-5*%a$gY!t2$_^!2v}VQB;ea{4C1#~Q+a~ql5bylOy;xuySHRY7A~!Dc3zQR
z&-&r+^kd$ysIVZSqlzIRA!)LNwc&N&oOLCMKZ>nBfRTpsxe0qj1^Pz}*as_S`cF6N
z_3|#uncV&aKdjHa_;9;`_6hUubMJ1CiLU!ku1zAa#WRceD=_US=OVD5tlxI;VM5I%
z+Q=k2Zb6UD=!KMp!4Wd0{z#MEZj8H#vhKY^*MoOQv!}4~y{(2~?*TMyiO5u2>v!3a
ze3JgelgByXTY+t;bY;ikOOoH&uq1u3Bs_j4C_w^|6esrkPHB*~o4=0jFL{4uDf}6&
zs2_2={ooB9yW!}gdp&B{Vl10WFh6M=F5bSoUV`!#uKKh)^`?JHfuo;?s55TUEY<C5
zh;gH7ZG7OII?@V at BD|6-0Qp6*Jf@`=>G0vF3HUU_n_wuhKb%Pu`koCk=*)(GJHm7=
zbyUN21|dN<fBYpa+~&;kjKkLXLWi=x+z0Nw2_Y)-&JF93>|)z}K4j=b#I7lW{NIhY
z?S%tD=704uKJ!4~+TcR<LgZ~Q_X&vk;IY9+ at 5b*}{Z2c45~XT-Pe0uxe#PIFA(Qy-
z7&KO1E!AX-Cc6aW93wWWC<rpVf4w8+As9O0CBRoDy~xzFEIdH4Zs*7-iJ5;ZM&7db
zvD424Yb-NEOAy%sKT*1xbPIMu9%|gy;@;g)EJY$!&KyUQX!V-H_oI8n$kJZ@>CX3{
znPTp?ijBJ;_%{=MvqxwUZ~%$^&WFddRR+VAW>TUFmAacrB<k5yg!Sggz0Kza<VAyx
z+6!K=hYBU*Y&@OmD7|mMt_ouRQk}tj!g+CnewPmHS6=$HHkKGkHr%o;{qszvt^4)A
zi3M5^pP({gA|L%8$0{&ft5kqOOC at qicbteyMAf&O$Ne8%=c%aA$8P69v#0&vJ#Lqk
z{kCRYDHF&vNMeulBF4SOnrDX3<@4%OBMa7U0TALH_jQq=oR&SST>>dt)Hz*iFJJ4E
zKtDFsa#}%Ch(%r2B6!*nfQGp&ZZRpBOJQ<+_952-d&Laz^$@bX;uRD%d*<#=Hn*96
zHtvsJWaz4yTgl7JU<dLf8`r(FPm;$&PpwopTLH^cOV4(2b86EB3^P}c_X5!Pza1<{
zHvZ76Go{+!`aS`Y7<KIwTnEa&^M=?4Q@^HNyCUcU?nx6QJOcA at nWY?wy$W`w(X;hY
zb)U%PEx?DT2^+$UTEi@%Mw*lTY;1g;r}s{II%M%%-lWlV*HmGD$vn at RMGbz@i5oq2
zO4m4|Nd#EN at Lf{|<71JBB1EK}HLIHU^3~`2l^cuMX-=)p^Avff_hC+TA>BGmh@`=P
zU)dC}B1O(4LS&Z5y)NK?W!jBR9DhIwN&KF2zxU0?R0xcb#K<$cQlOU|jLza at qbANV
z`Kz1(wf(^bqmZwnj~jeL*HP#^qSC3Sp+)*f)__3F>aX}OQf|^yvF*4>Q^o|T^*dC{
z({<CvGcU!E$m5*oQos1VjSlBTY*(U<vmv_;O|DP0M|zC!hqJZg8+8sKikG!VX4V~g
z7Rbolzcow(#=J}dQiDm~lFozuSi7IjX-yzG?a~Vz2s9Y&+sm1g?`EY|D--?54~}_s
zv+8CI!CTWCh7DD5H5dz@>LNkV9~WZ2Z>tMH=kTc|QR=#qOr_##S={79AE`uaP7h^k
zw+6j`$oj`u_c*zRe40JE`}@aLd}2##QBa at CFQsSV_jQ?x5W*6E%VEoRYuNDtq^`Lp
zccP1_bH%1Z(it$##*&Y!-88335$bJoKpivmRNwB_*oDz2?hMb(N|{M5KD9))g#P6P
zAMB>L9+=+ at U1X{a?KHkk-icjsR-?SzLGG^E98AFROL!d&5+HYbG>kJK%$oe&YHJzu
z!m8(Xy|(+o=FNw4<$jAr0cav|Sb~V_=8z_I;VLTB9TwcreVM>un0-$yq6SYPKyRh6
zE<VU<0$!rE=s5E|%<ZsDJhc%s(z%k>dLmBMuN at m;b0|Jr%yCEeU$4cUP}pbtVeRkQ
zVQ=y~=VU_!r@#22Yv=pw57{06>1XJBVIKt|?usyR#htphBkeZLOT+u!FACXjEo;8#
z|DN)vM;4{%=F<RgyDyuN#Y`PThB)Rwy)t{hB0Rx+8>+b8IwO#G_V6bw8xtzj!-Ez8
zld at saFQaTBJBH6kD<s<b$<VQ><SNkZaY0KT5H`|*G59wpvP&_-_d0vt{e}*m>Uo+*
z*xm^@(ElsN*CKZ(Qo3wD)#oMw6oeFKK5AIYyn6~+$ctEKl>HPt)RPSlgG#G!QY19<
zEuL4|kJAkaH4)@Zjph1<euG4ka7QkGgm7`j^{#MEu&sTJTg9J*fZuzzn+qGv9HwC}
zZO at olMOJP{&sOX3QAAzg<(?-4*&PwL8?mHRfor05`DW-%Ttj-X1QJI3eVH#JRHnn0
znWhn6=CXTT+g>geTZE?D?OB#=onZ>EjSTIUeo5Z>RDPOOdGpz6>FviMXGe8^{t2sa
ziKZ0?lX-{twSHpLv+aMRTZD$&XAXK?jN=Kvb8Nj`Z<#1dKaw~^L&!XmI7WL)Ig+T#
z4IaG?0vrr$zt?N{a|}xdD=qfo&t%pst>Tum$7r at oFnqvISsPZvzjHV{rL9^tl(8 at l
zT+M1mf;uc=6PWqmDwB6P5It`8M{bt)zp7}B at q^@qQfa&o8J}_+Tr=-0E$}6>B{zWj
zPt^=mHjB}6LDMrOqnE!vtpD*Wx2RC&KDZJ(%T_h$C6mM=D)>wdRYYfd!vXzXn-f21
z7Li+15dR{4z^t2K9?bXBf>Tb;hh`8LyUw7u>^5|9tB8WbB8y*sFUS}q!1MTcnS+{R
zMh8}AfW}G+BeW%&M^q3ryY!T|7~z!k{A%eGn)r)m+}@7<;tylHy;H;*`Z*O=;qA5l
z&ChN#a4(~X&s2z at ozBZWqZ-u2E?ad_`_SEck;p#uAbDkG(k<?`Cq8?&HSai#$wo7R
z5vQ$`F+Rv;mLKEzd}CN;*o^mm>R7JrW6}lR^5-qb+hrrgLa-B4x7W<9 at QqNSRG^pS
z_|xy;;Xwhhi_L at EOG!~~(21$r3Xy_Emh0(#<;7{Z<D23y2MlF?8O at Z?VT;D$mX(%h
zN2SP<xY(W+B1Qr+uV$b1Z#|m*H+v=AN3NSNO^x1B^Sjoo?()<6O30x1O9PkL!_}&i
zLCwI6sQ`jznt%e9DPI9MvSueYQ90PlRqQN2+He^bT<Y1L#2ij-6zyupPnH?5$qZ)L
zACUK%8akjmkJ62keBR-yz&;MmoD5`IY(V6i$cb&_d=GC$G<KZmlp9c!i%GL2{)Zzu
zS>O5Q^2xE;*?3HStVMmwW41rXiGvOy>FBv><!@J4{76Qf%jfi-c-Zyl;p at -GXyV^j
zo?usILQl!gm+V3a$w%=mE?x%$4Gbq}x#}%PH{N6Y$mT*To}1T*-<dGvS{~3o-R)%N
z@=1D;N}T3Ky5Eecegx~r)+JFa9;kkt2?#uxvbB$B5|x2trar|9lK|UTG%1)Iw9LIi
zDv^4Jiu0q8w7jCx4Gt1XjUL1<Pa5m<BQyrQEvCn`(~J=m5(CZ>eoseGlvrUSQm+4`
z!1Z#>QZo11<mdRhX-7O%ww7IC-LDHw^cgMm+T(p?O*zAz2vso3N9Uwp4FY{6zY03^
zm4i)!z&>FW#yqGoS3DY91T0|0?!;n^&rIF*=Y-_`^D*}ZDDWO4wJvajqyYrf?~t2~
zjU_ir2-Zn{+(yx2E7(O<UIFQI>T?VS_c_xEb@=W`?(-xliP~Z{hB%VsIWDsk|J_nn
z!$d*lAW70+fm}t-eNN|Ut;({i`Tjx)re+t|b^F>L+sEo;dSuJV&~jaW=K)yGbsBsK
zTrxIdaAM7G8)~gAx66&z>!2Os=MW=9Lf at z@FLfmGHAS4e(|MMqGHk2)*;|Xyv1_O+
zSy!j#6%E4&(<7(27NG(sS4c~J0?%RPDzNje%i at +7!`_;nGnp;<PObs4W6dQp?Uoft
zox8Q4qq&gym^a7dX$SUk2%QgQh(~h_69kMdUB`HwQpSR{9LS0u{t8I50X1jtPgnDv
z)(W*E<}+KF2XC+)=6HtBJM6l?-|=;$+-glfe)cIKAowzDKHKElKJ^n$YuyraOkl;1
zhu{%Bz3f_DsQZ*Ms<1{kb)J&_2LH=vU&`MH7ncH&Mh6(FEo>XlnGMH7AAfsSjtK3K
zWs at LLkAg5YgXf7=KNkqb&u at 39FegHZAA(V+q;l-TiV~%ZP~;?N6J>I_uTK6z8ksNW
zGjysCJhN}+FZEW*JOcSW;z4>GRiAA}3Z7n`oyNuEciOExYMn3Ic~;K<3VdJl*I;xQ
z4!p?=qx_qBkQIU9$Nj0e!%vI=<4a!894TLR at 8rW#{K+BymlP1O_`v$j{6sG=Qka6z
z_X#ul6-AifzIi}^`MmmzO~;<P{nNbqNyCiF^W0TumotQ{()l<LK>8)08-o_1ONd3!
z<jIlhlE3MR|8Im`AUJf}5Kno(nEROhJ=@7OLA>Y$9C;H4>G8AzloTKggt3+-e8Gu!
zqf95)GV$K3lWY>JDwF0_<XRgH3yNBsr;kgQjn1=)f(@9{-hn-hdp9}8F$Lg{tel-&
z4230gXX5)-<`ZxbyA@{?%F}5M%?;gD+Hy5)dmOTFYh{TSjWkPuU|=^nH{#B#&uwFa
z{GqD1i%wMCuN;~Y$Hwee0(f#2T2NN6%QBBX1qN7+UhkR++2YscUS%F(_Aog`J=uCz
zkva7q*s3NucdA=2Ic*$3kI>%lL8c3MR>KaURhj~Pr516)B<sCok->E14-0pdFH(l6
zt8cc<t97-Gw(vX`I- at G}*elxI-Tu$RmrTme at MSn|?!bIzqR3pyf#vzW&C2bb>sXGH
zsvZ8nKXY5S=Kis?Rn5n@*tR4TN|-Z+^vO~8!A0z!xMz#B6(d=av=s?oHrcRxoXKQA
zNlzz5+py2p$$w*ob<Q82X2-pJ==345_HP%}2mS}&yyxFP_*Y!pVkF7NU{E&sYeGM_
zbWM&195{58-&jsKx-&pKd-B4MB=4BEw;|c9-&U at Qj{@|j4^)?IgHDcI&F`1IU7cM<
zTjs-`hi4Sbgbp~C4!%is)U*hNJGl<GJg_a1IjlHEH*|%cpuN9r|5N+uobYMuKalAZ
zC2pyj<_x^J^XrSKwY62Z)qF9Vf4J9)>V3X>i_T!Z*pJglx+dz*dmI4baRF5$PhAKq
zEgi5kTCU9eZXh+)Jn|H1hr6A*(wrOHR<SOt4d)pD9A^_4lXKbZeA#%^P0%-O=wpAr
zx at fW%a8vGlsWT at u+YX~{Sb4wn4cplj9VVEo)lyG5cKxQ4>9XVKdGxw$0bfmW*Iso6
z|DN_g at yzy{Fb=K%pvKM#+Gp94?B<wpr=sD)X?@eM%I5=wg}@t%vu at e;y8Fk<v-O{1
zubQK=o-aSW^1G|T4rMYoh0{DUrNTm>G>GI-XjuWjg{|)HT3FSPF)g{QI92<FgpyS<
zT9v&}z3+hgv1DBnxzA|=x{hA(EU&Nlg|}TyUh{O!<hDE?7+T&D;ruq#)<3?%0~7lN
z0K>dX{6dbCHx2(pp9MdTSNr4``B*DBk0g^ISP?`Zp-n#Q!)LWWApY7cIh(I>h+7K0
zE)agoi#<K1MVeYWuM9;3Q9b1O<37rqw(u}g{3A?)>=Wj-ui(BdWx*OoywJmGV62b#
zRwun at k;jpfDi`rVD)8yXA+M*Nak@{J$lT_aiMtmYW_N$m589(>^kF}@payWdg&h7P
zct<qvr}+4w#917z{BFqM(q}4<7r9h at tD=eKV at Z|-7of)t)$$GV=aUa=?;(m6Ef#bf
z%BRuA<?AS!tFQ6f$yEQjv=(U$ZrQJv<6)E*4H#OSQe^^7f~fvf${D>n=-qoX8rq0O
z*u>Q8eA^!IKlwx9agZfa_`}P^d?7L^)~K>ni^SH(bbBaDpH>Xf!9A-PC(<mRYXzqj
z=q?fHjgU(TUiCb8(S;xe-kqaxgZd2V?N1ak1(Bt3)-wwH;fJ1kE>6|#$iT#i!B<`O
zH#fG|H?M;C=rnW?yRj>d_b?HxjcyjgBvR- at _dX@6=g?mI6T{i-2fF6iaF<C4x~KHr
zi1~KQ;MJ0lrQh(}UG&HrqRx?n9rW<9=T7#w{HDhqgyfdG(oYXGm;6EIm4fr%o$o08
zKX!0AUo{^=c2T;-`0j;k5S%+|FJMc)P7Zf|qD?DQu+=0WY%fXXxl*P2+>-XGk;S@$
z%hAd4z0lGkq>ceVu|@nAZ`f+ab(s2y&#gc{)^H&jTwyWkR>VnObg|@v__Eh(ru%Qx
z#LbyMjcyx0l8IA~>o*I5=W^h~u>P~)#;N{0yMpKh4?@Y-)3?j_m5uJlJKsO_{!G6e
zG?0u=47dR21#H6$Z|0|-ZMd2SsZQPTmrVuW2exeln0T%loE^QckxP4h)>9x(!4!D6
zcl%Q at VJPfKakGlbEb1WOS$_F)ny>ZXjHGoN#k`Lw;L+|-!jk=YtEt%ikSH*Yt>>!t
zG&U5M$-aQ9rnoYOEa1GL)p1eB7o^1$a5>25z8LsKZkO*tf4vAo0YBzRu2V at qiyiy@
zWiau1No_qJGVe8*>_XjA#O#OJL4xqRA3ec0v*m at lQEu0FnOkKSJz=UY0XS2gyhMSI
z1us9!C+|40*6f7x+{dMb?|K4)*T7F}bzU~20iXY<x87x%4{CC@!?V3 at KW*d+#IOTD
ziRFPFi-dh^m2dZ79^V)|uQ&Q`4$iv`0-?IZf+wO?(C$1>N%ek}$A9D5k<M7n!h@%I
ze{Q~#{Qov%s-^@<rNQ^&H0&9puQWu+Kt{wgomAxx_3K<zDuHu2YPvCo6b)7Q{x at CR
za2heqB9nM6Ryn1g81 at -OX^HP at pr>NkTEvBo+VV7`@Nlfn#Lk0a4(_k2F=Ot?+gSy|
zf)lAvXY{@nWhE9iD^x%Db$mk`hpQ4OCFuJRS+4u!_Zsvog~0gW{zl&s6-;Hh<>xsK
z1olgq32Aj5(cnU5(%$n4LLzG%FiT~^_<`3u#u%C`a&0)KJFH)r!^;0!&FT-+Y0N?w
zy!5OPyCY5BQRViQzKV0ddi_7e6$i?WKKypjb>w0F%?j~7XF=@Ex!AVP+5GWT{^cDr
zbqp;~Wk))19{7~Q&o`yBU-b(P&OL=z<8OS1qkA##ov6jM-dFf{6`vGUbcO7{uT?g-
zyBDX)G<Te5X at 7gTm^g`_#c($cbS>Svxu$|<DewamU26U=uH}}Hq(E=9KQ-z5t7#8(
ziF0B6RKa|Q-rRb!wxm__mc{%3GO^o&ZG1LAnMF=^QUDRje?N3{Tlh=^4)i<^C?!bK
zbN4NLLKBpu`)}3<cz!RqDGVJ=XRCLD at ea6SbVb+NXsH0jrv$O`apWR+p(xl9nl~~z
zS6mZ^aU}m00F=mTG!>R#4g%x3LfDOVQ&3<&M*=XlNXoHGKg`;yk65QxpBzzXmf+~<
zh*->*TWpHVP4eGa$T~t<$9SNy*y{fBkMP+5K5hgJcr9`d1UG&AQpRoDG&kIU;Z9y`
zT>Yi1i$XRMi^45!*i_^nOJKc at kWLwIyg-sFlJYb27iI@JMev$yo;i#_8ncw3f!&dq
z-`EkjJYPs8`xvsz_%MRg-*>71rJB&teyDtg%|}<)A)to|4zBw|h?dVkew5hiUG?0%
zYI<%cHHK_cGvPXDe}08K#i6WOq1jkIg&wsZ$N1n%l&|0Xzr+AM*L{)-d1LGtX1T!q
z;of0bNzUf?Xn0oRzF?Kg+vF)C?$4L-3pV4HQAt;@!sKEOW5*Kv7>~B)C>%`0<MFtE
zE~#JNWqbjuTsiOe0M4+f_?__~V7{RK2Rn)bC35a8kL|CHWSu`jaU^&4df#9q|H_hL
zIl4avFAFq6^|`sZ-&MR|!L?H<Bop(Vi{99TmSl?v|MPI_QkamM9KEr2BGwUdxt~RT
zQ6g-->gG=+^Zb{zy!{b*;7s?0Yrk#LNL*sJp#MR8P)(v=E9Z*W_8)#FCvVYMfT{)R
zj5p0qLj{8{;sm*kZz{iJI}cZ3FK7QtPMm)v84;bFaC}HDWAQ3G!j`gQ`RR1 at 3eKaV
zKnFILZrfsJXKRv^{l9gXL(;%?w2?b~U`<EYuh|dLAUs^MiWA)bt7bW#<1uMp9U<?^
zE?Zv1-?gMeiHzyczg~nJXP>aR5c%@(-l$s93i?mlx!3YQMiVznze2a2+Xse}MX?s4
z7QTKC2Sg)DN%UolTn=?NJI;nTho(&we!#tZH at 3)a|3I~obc7A()jsF5WM?C&1P_;K
zyZg^}*IkkDx6DlcJtnc at Z~7w>XEUtUdhD$w at AR$uCF3^^9YUHz%q#oq+!#1(qq$$@
z&#OXP|BuovXW3tMJVB^Y-$jY-8;6WbAQi(QA^j$(pBZNU`|}qh#xiaG{NX(z%>uQ(
z?PS(J)-#~Q7MXg-)dUSENW|ig?+!_jxTSwx3RMe??(7&YUcrq<!NXY!<EBRRkb%;h
zqb>=!%beL8_ at z_m<L4XMWmD*tW}D6$CESw#wKdfQ-t=;x%Ke+SpGNzqe`*nnTpA)u
zPp6%ym$7892f$CI7szCOmF|_5kR;S$0#k*~PG*#5H|r~HE*jh0cIokvx&3S7Li^{O
z7n<%@8a^g5lG@|FkBC-C`ADq7tMhJ}<Xtsmm%e;UPbSyIav>62)7(=_#J^?9iLR_C
z)B5~@Atw}aTsFeH|0b~UC`SKgr7DqT)_S~ZN#$P>>MKgh=SV{R)M~E1>I(O8PeQB{
z__day at Q9z!AP4rp%`Y;Cjw3ty7hlc(TU{oz>>pR(3p9Rev252F8ea at NQ1t`vuO$p$
zGHL(%nUxIvf26m1zK|q}2SDk19NI&6x*A<LxcZu2sjEtH!4IFSz6s)3mHplk_&1sY
z7rf+nAd^Ow_~hM6fI{Gb8UhCqLX_55Xr at w#rpW*E2X6wN?BDwPzJRB(I|2cRT6YV#
z1RlKAPaG<I at YgdYiwD_0hgKO6kR<Mpb4+~WD}4W};;2iP#fZ2P`WOVj+oedgz)ybD
zu|msG#~*-Fsy6*w>F*Tcc#tiL`-nr?$8d&te)6xB7#W?fG#g|7b|7>or&CU8{yBl{
zH2x1v2n#!zazlZN`v1T`@Ed4W1W!E+0*UcK1P$R3k3%zQ1G_AN{6V07nV}N^VXs#`
z+5TG#@NYFPB>+Z%Mgv3jEP+WB6}qg<nPW<`Ua6#dDYlF(w#q3M=i4K|$4V)P-6z=N
zS;<^((0{?<TqIZ`Q8-}+27 at WxeA8vkrGGp7jocIHJqGRN^SCSvSDCco0Sxhu8DlwX
zgUjPz2==)!O@=t)6qsG1jaIA>zv$%81EtO!D>7vNPg(qdjc(iUzfPo&wQ;BYn;k<|
zP74um&)P77qjSpk_xC>%^B$N^jQ>xdEDscO$_%?cU)i1v-7j-BX7J3yV9|P&`qehQ
z&QV;jU;1{M{sE#AQxW8`&VTOaud0 at E*qt0N4y+d^R$7>6UCZl_zSh1cJ6V|9SvbRD
zVtNXmBfSFyjj`8jSu at 5~Kw~Yi7;Pq4Mj1c>CpBu44T;zk0vx^atEr2eztVmXlv0AG
zIlxkq#^G1#0zo3VF>r@?;C at _mLict&wK+MJQzF8lnfGo~o5Dbu|GWRNc!~WY^97?w
z(0|Cf8Tyc>9Utr8$1MloK?+bNDJVfDuT`8A3RbuWS{{lyTbj6v>Zwslty0VEi#4^Q
zr5BT at 9IA66nyXCCXB-vh<3A(f>gU?eL;^Tn6wMO9pt_Uy-#kGtfd9T9K!N}E+hGfK
z*I}I?N7*zNf0hQ?bil`hr1gw-D*M^z2u_4=D?3z^U06(Y?12D&2c$c5OaNj4k++t%
zR^C;)PZ`@GonrN*f65TFdA5<byR+%ENpNg7-l`)VGt96V-n&prDN)uhReug}NoD)2
zluNq>469~#V0VG|kkFCX9p_%ELNy`L4~!m+&ZB(g_A$&c#@(9t<LHs;4dVsFZNs6a
zLXbTfv&`!q5r%RD>+l}MOSD=eE4A6247)vvv5V+KJEOTI_yFv&pvNBLYC&tYMO!2M
zwlurfA%!#8f2eMx=e|6?-&HruwA-z>7TIn~J4xD$-fC4o8D4fn2YQ*OjfE~7s^tH~
zb{!klDoOB-HC at hMbe3IBJw%LG4ttRg#XrZI;gD#n2tZ9BZSR=*M<V0W<G9M17XIKh
zl-K7iT}+_p$ggf^Z}Xjt{fu1oYC0_VViiLDai21oCYdF>(u8w9$p%y_RxVcX$mtK9
zx=7O6#pvWL0P4qefCdvaR8;<|J0~h8_}Fn7+(U=@N|!ZV;o&FIowzdI_Qjn7L$Q9R
z?EPwt&+sz$Nz$m&xTxG4Bh8V$&zlrK744UHDH@(1Mn&bY3>8PZ>v=$tmw|<yp^{u%
zgAX}kl}&Vh6{lGCLpT1qmA|12^A63;zL6ZWRe{!6#%EZ`@-ymWAwE$q1f~q0aD_ZW
zf+tCzVE89VXB&4!T|bFdd$*|l$x%;|+FC#;YZt(7&u!LJ`$nFEXG8!K3|idNDeF~m
z*$k}voNZ4Wi4_I_ATVO)KZy7ee+u_NQD0Dj?|6!2I4|zNv(_qhVIR*FQl|EDCAeg0
zkKV)%mSGy-)6<u0f8`J3M-72m^TBMj at etwPii-01o~|=COl(8ao0w7FqYV!Ls{-8~
z85o5!jT&_KUx=lR?UcP;Y!D7_idk>iw6l_jsv}B6R0UtzH|nwqK-tuFFet at ZXEGg{
zV{qvd_><8Xy=gyoDo4X*sFXr)+|9#$8#Ys>Vp6uW{dfa;^_^~8Xd~3n<?eVkw(2cI
zRRpsElg}3dY at Riu=Znq74km{(UYbfNa*<64GxW=N^LR148i<p|7FdUGQQH?FK%>e+
zeYIWvfsy@~*>6Iozv&j?T&a|X07f=H!Pg}12M>1G@=-k at D19&U6a5ywr+&3Q8859T
zGrE=_I_C-V!TU7w at BL(02K<&=5liXKBXUMise8`1N*I2tt%k}fWGXBKv4atKd-L-8
zC7AZLCY(a|EEnu0YSyOrmZ^9%44pKuX*PS%aPj?VE=C$A5tY1R_CJD<LHVEB_uXcy
z&kvmn<+OfHJInl#r<70FNeE(&$q{6m$>v45w$zxJJzwTElR36I0ov5|r;FmxGS95r
zzEjAl<=8mcK;+6`7M5G4+v?i|BT1KQH%|)YzBM*eA9y)mh>EqK^23dXl?~T&Lp%!~
z--u+~)T=d$ZF{sK*C&B&?oytkoUDx^fb~o=H;PmfwC*k~XweDE$M|VZq6y)f8I(zr
z!yazsOC}N@?UZHtJ)J9f0u1z)F0@&d%Zv&jG^0k;o6EhVORxg|MW$%_Hg7@{K&vM?
zsNQw=s;{Dffq|8n+{^WVXjU3ln9s1-&48%f)D=|Jkg1mI1PA3WFbwwnIo90#t6U%M
z0*h4|4~BE5Cp;^q>kj?SP|UUNQ>?r1<M^U$)`!+FxJH>R;pPjS{TYF~6oVh?EfE_U
zdx>YcKLF|y!0C>PcEU`6j#>N at P`kBA%LTd<oPc?QRT^Yn*G}2%w=*-m8nHxN$KQFj
z3cMHX_YQ%!Ak1DII)$ii)cVfJ*kH8MBi!}LGdX#!UkhP!7B-frvW<fyh*EDL%tDlE
zj9XR0VL?Rb;ZUhjD0 at k`5W7)W6=Jqnv{b!;CNw&|keU9Cmk}|qAT9ZqLf8_uik6 at n
zV{4}f-&xwVwWkd)jm+5EP at vT&O9sCptwXc1RZTIo!z1SfM=m9sBuL>}WlSs<BTAc4
z1UHdFl5C1?&(8xfNJ#sxYB;*dwDLFU8iOZCL}^_5<3z&ZDPtcbk~xNyELkkIX^>3R
zuiMCIGz%z at Sx_^&&JN?rR!u<+mnouo{lRSk3c;~v{M-o|LGITg0lk?);#D}5P7{DC
zlvVj%(~m7&lu?gnNm}{MfiCJt#9k(G5wAn)rAJhBpH08&=ETvtL%BuLZt8*uAQs8k
z+2$mEFm^et_wtTek1a9aQ@@f#UWj(PHpXisE1AhsSGDVGu!_0ie01loM_YthQ}G&Y
z<+&I+N0LBaX5EMar(*;rXM)tojgn-x(&>gSNP%(WXIUpy%ZAb?Ss5l|9hVh1OdNe!
zPn1`nwXM9%1W;O>sbGr at xo_w8CldVQ+I=P(yf3O at 1gO%MiF}GRV>=$QZw9#6c>r(H
z)YLTo%vyU)ivm_F%sOJ7 at riOOSd44zb*;1+(;>U{D$Ri2DxC(MUt*@a%b;kM7!1H}
zhg37ziTn%ja$BHas&<DR at UPaLPyrhukN!Nab7&#KB4M|#x0i%lY>pfWm-7dG7ZV_*
zoX+}{zma=w=o$!5lDbSTv*I#O(HYO3S}!93$ZlvP_r<nz8JziWN4dJ>wA%adM)4>+
zapa(?7$hERqWaJ$WMgKXxGOPc7_C-6TS$0<lfBVpY at JK@+;xUEnZ^1hR$Z*7wo{h;
z)t8%vg+_{d_R#akO<${3njtgmC!meF*Z5q-<!}M&)6(2*3A9r?#*x6@$&*AEHVVBb
z5W=?xS(uGiKTmDXY8a(PZY6bNVEFm^ZV_R3GTUF%^7L+=GW*f^&f3{<ji%}FZM&*D
zfOwYdu^VteVn at GF7}u+!VEBVyLA2xze^egMC5+(C#Xih5;-E_>ufb-aT3op$3uYvg
z2wE1KxE4n16B_rlCB_7TTyTPQzMb+kOQVWnc!%MsC+Y9%FS9WTmvW&IahJhpDHOc6
z;p`A`Eirb*^SnorY*kTADJ6ctgK(S$i0gG>gILs%LRumYt^PKxk08vZlrC3vjCzc!
z9MWK*wJROP;yNJ4^%F}JFHDJ7%i6Rg&B2#JL{EO#gqEKC$@0UGgQQ}HJdF?dVl?GW
z{7bmXTF`UXGl`{vpjms7QI7lc_`qy35=lWR!y6CuoVeG1hfc0sii9vxXIB$)2BHvW
zd`*ozYa>fjj)I*g6z_A?Kk0ThPXl2w6gZs{BF#{5TDO=iXQeU9J_T~cm|KzsBL;t)
zt at x|Z@$$H~B-8*G`^b1sv#pkXDOSvAAM@?t;y|&4PUw!0#=)CA0+KB|98*rup$CNW
zS=gWOlsB}<p~UA-AKl6FTA=oP<Dw-TGm!wtpMC!%$F at pyZe5PTcT#slm+P~@qA7lc
z#TY`1f5^QR^)(;L_1R=w)j9)&Qr=!K8{cT2<ugor6z{WeVhOSZvN^%Cq#|T8sH`{2
z*MiUa6vn{8qQ*bTPAm|9X^^D4<7RKCbpqf at L9j`lHZ|%e?7_U%d;c|EEtX~uA2{Q*
zKFed3=K{CY5EYqZ=Zo8Cci?g)|6_g7 at V3$TqD-Yvhz>~4{Qmvh)e5 at Rh$zNgwJegx
zL1PNTIK+|U!Vqm57*z^0PRpqFI==&_GG&Xm0fq)k7~>jCDD!C6QtFg at NocW{Q~hWk
zerQlve^nGH6 at Q0l$bA-sr9UmB54y0CAA~3>tKub!`W1m>x9az%YuTmr9X?dl*E3Nf
z924!C#Yl~HHsV$2SE}O*<{s8>u*M`1qV26WFsVFq6l6w`j)mlV&|NV9dDY2nleh3=
zr>Pl0OEZ&I{)O8*A}W09>&=GDcuZfd#k at XRYsEO)vxw1%p@{G#L=8>chGBd0&XM!Q
z)RR<qfazDMHKvj!E;zdKj;ZC;yu!x`{T4ucxLn#r?>;t-B;)^yt at 4~Bk#P|55Ah7L
zVYjy0Y92X?^+*R1oTTJKp~+Ha2i^|k<#G#_zFGs|gb<;7{jXH#7}sqW&s9>FRHCVd
zl2Mj+ie83^^+dB8={WheeiI`3 at 4RZoiuYe9&#ILE6!z;~wOsNWg2*Od*;kV#^N<*L
zi;aZ4R$r6ByhJ>pldOyvY8fK(s=Mj)b#cLRWehpy0AaL`XcW{><wPwvB<wZ`%ymGC
zy*_;s_ at nb+5{eT6*iKQehVQqUnCH-1z_AItX}sPaqA||1-001=)#nr|n;a!-={%<V
z8w=ihWyF0y#qzG=23d)GBoyDefZLQ?_tM;;czjzv4*=(G90(;*nr*N66ibjEM#9K)
zIbQBWr?;CZlC!TPI9y8AQmi${st5^-jdt053cFHaqu{vDoXvFVayjV*s{!bj#FGxP
z)8_h9`6Uu&Il{}aMbn-oqOaK*8c&cQ5yign)s7dr;W^u<j%O5^wSWU})zXd!upz8X
z&)33+>JZE>%ktA_ at J|4jM*ShE%HLaw_asT;YCzQ28P*v(<<MZI;k6+(9W{=s)r@`W
z!HVSiD{qbIB-O;p4^Lz;wo3<G7UJo5bcsW=4<=6ULP)t8n`2YdUD)a+3l1ZMT}(s@
z?D$NcY at 2v$>3c`Td%B27)&b520jZxS{gw3MZWG~1xb?X$8TXfx*Woh#etoMhxXdH*
zyHR+4=Dy=LoYqyP=3qhPU3rg*_d9hB<4WJc#3U7s2Ba+M6j9N}Nc<qI=_*z_^<B^}
zX?LPoYVHHkHu?k!?BigGHDRv)0XfGNCA8G|oGu*R8}Re6VA4X+E`f|jCf-lm$gV-h
zNriM~B|&Cu9Sg-!Ik-dF&MG;Pd6TFLr+qa7n>gn_X0l}8U7LI~5j()#i*<_mvi(ax
z!J*DdW{$qRre2G6ZO|Sr&x~0vTKpLgw#~1vQEG8c1Dfb0X}pQ2W2<5cI~`e$GQ$zK
zEC+^(q;xkHht2aJAmxsGmYC)dJFSoTHtuPN-O0opswdA=D9VOqjU50~te(rE_$|wD
z*re`wC+)RF?SMR!^`VG*$Q75Loz2BAYT~{l&5jJg!r1U18s45S#dnX`e&ZtP#>21u
z^1~NARB+1QkCKmG at MhQ3$vDX=-KQO*o#$^-Z}D>_3nW;NZTM%{bCUkBmv8A018(k?
z0Ol%a!|bnPsm>kwI!u}<Ni}Cq1h6WujDsklQ?a{gr|jxbiMB6Ftztq#jE0T&s8#Qi
zlg;uuNFO92+BbzuuMxhd3;9sLz;=?<Jkcq8DKW-Fw2$*d3kcyW?_J&#i^R at ++bNAJ
z06803<P?<<y9rO$H|YSrRu<Uy0`7AsjFbn8tg at NBwpg`PEP&PbYP{=+!t{K-L2(G@
zFetj<{zI&PmnKhrI>yJXo%{kzv|(gsZ`Bt?@g~d1jemNVf;SV0?_=)y^vsS6hYkEe
z6C0^!B|O_q3ykG$ywEq&a@*l!-0((1z3%f&;EsHqeL0HgZYDy-xr at W(R|wM?oguwm
ztrrR!3hUx)c-Q(DsT{}s7Iyu3vGMK!1G{{r>6_Xn$c&E2SSiF8`>qpSvHMo!jvOgc
zDBR+#$m!ZE8YPr%9PmWTkj6oKc?T?7OiMWRl}KkkOLtf2Ro9Fk{kUPO{T}v_<)w*V
zf=V4w$%v|DhQV1n1oVo+u(6R<vJCs@{DSo2>@UpO%+V=H^#ma<_&SW)-rwN;AR=9%
zo*f_w;in2cbnH~JWcy^<WMz#j3)ohm>bJ})=Y+CT8he_}Jc+ at naTdPA>^**9l$|PN
z?RdEFA*cp+)|-sN(<JOXcm3^xajHGzD%xKm4%0ypQ5esnTn~o)t%}S2d4bp2Kw`7e
ziv7Y{u2&=3f~%Pa88Cy3 at I{=ZhYOR^^^>hRS$kI{A?6Qo?MEcGc0t3@`{>@hZpjFY
zEDb}aB4iSoP)hd%(mKd@@#6EUD)X$<sL&aSa;O!xAEsXcEGQkc)x<#)O at 7pfMnYx0
z``6$5im#)OMv?LGLWW##cORwP?##^b0xLsSLUhotx7{~#xRbaBAmEzmLA#)ZI>5+V
z<$9nI<vslCeHd)JYFR$i{5EpLs?P|U{k69Wj%dyyUzGm_g*Sb{&D(@$_tJN{KEr(1
z;XYAVN6|h}%K+Mv+f~zgjf)PP4NsczbQ&r)Lad&8BR&9Nc||0;Xh>Bz&IeeeK~u;c
zlJC#3?l_gZ8ri7M-CyOZUYvl<qVnAYPwJ-ht}=a^Hh+%W1K#|D^SJM!-d9~#b$tj&
zQ;SS;Pkm%?wW^=ao8ZQayX~a%B!LdvWYdhSF7CV#XslvbxRC7iePbzWE&*^SOz{ov
zY?GY{tZ-GTBUTKPi7?q9r?!iT$vxIXk1lUi$kIB3<zY4uFaMf_P$0BE5i){Zpt{lD
z(OF+_m!p%29xgN6x_Eb;cfnB-(=(+ZYt`2m6Ro3j%MIx)*RK??&LLt=CDLckyBL9x
zB>Zw~#$g<~-es42hm}6YcLsx7Wo~V!DDYc9Pc*@rfpF>n-L$cFB?+XGOa(*Oh(`H5
zMp<0n${Zj4(q%M0H}RIn<iv!18>q}TV;D%KV{fRDj}ZQ1!=@k at 0V>`_sB at C?gehw@
zZ_B(^gD%{r&hKR39imRrC{~EbFp(jrYA2AZI+Qyt=4p?vDy?4H9NyJ^%_klDYW$(3
zfphypv#QwHY9vE-?sZC_3%;3#^u|SqSOBf)`SMRjgCpGh(LGDwwe?Zwyn?9*ys6lH
z=m#REx>$r$_)n|8ZNwM{Aa9N6xU)OjngpoiGF1X`^tii9qw~VWns9s@;n$Ra=#9aF
zq$x5Uqs=yal-E?K-)Bd5F1{3lR$;>5FCMdfhCe4yjkS72d%%i6Z&950M;>PnDVf_)
zxNl%;INGgR5~*0?P1*k$|0)+5%?|h}-0;nyNdMi*jG^vxtOQ1-+^RL<t{f1GDCJQb
z at Xav4XxHsH>B&izpF9^&pySTR?N at KSOLe?U7WUrAf3J=88E{_)I9A;~hd&TfneWcZ
zULNm0^Cp=m;c|>z*#S~g$CC-fraTdIE0;P$Z<M{afn(fC^5P|SDaNZ0J!PLX__jig
zoYEIJSZWpr|LB5=;P<2(4CJ3DQ0fowFRS15Q1EO_m-s$pDS3=WsiVVu*ZDcF_uY=X
z64>jQOsizfDjvny3Ba5Y)%qI!7V_f^*zZ at 2tTeqVe>PMJ?-&jK-HT6|TB+Oku~Q at x
z4o&cip05SMS%|Y(6dpBIroADvoC^<ADg!k=Qz-57Z;aZ8A4hB_Hk|YgJKN48Ccesg
zROAZjF+Q7kWQe=9DCY0XNmPuMHXad3aVCx<#wkONNYeUS51Z?i8y?pZu-w0;R}m&q
z*Io2$xF@%*4`Uo)Yj8AIk~N>Zz<i|YHn*9vGgqB<dYeyL>#=hhboy&Jp(68Q^BBtS
zQzYs_Y&CP3!4DExTAL<@K{`o>-PyhiTDlsEHsZ7w{YT1^Z~ee+!?9xJPFdi&J_&lK
z13R+^kK<`U69(}pW#)1T*bSNTqIu<&O+jv5F{byRyr_9DU80Gp<{Vn0NICE5?Wy4@
z2$@FkP~NV;Hv!qRls$n{sbosRv;QDup7g{>EhlU}T5Fte{jgE#kbH|BO%Pd_A$$*_
z({cz(3Q!@<>vTEzm;hJDGr}+nm|}MMI`uHOl)Y^NR#Ex!Zpo2d3bjW$>;;x at -tIyA
z@)p+B^_Ig(o`%S`Z9p{CJM33Y#2~|Wzb%StVfcd5rr7`3XIVd9pIA_gX*hdV00hf~
zMb>&qK(N}I;Mg&oXett$Z=IJ9u;nS}93b6%WN=_gb>h)z1^}lb*aNtU`knopkA2D5
zWY-eC54Z-SI~~EkRO=rNfM}1l;!%?o;5nJ(6bGGmUteDb8}MzNic)>F?G4w^s{Up1
z2-mGWt&Egz$XZyq at u%+M$f#%!2v`hFV#V{-CnJqT_Aca37RhOGg3$<N1vzUxtg$KI
zr+OQXOH at Fc??v*)Vv}S&QglZD7=aUl#2vuhLs&hk-y;0yQ8KeKkl4}-4#A&0 at X*U&
zpOp=*Vvz79=#PXDrdanFOe&3h*l1#qxcH$ZKogOoK}$wO#8Jm3X at yNfMM@-3_w)yt
zEW}E0;mS#_WpVP=sjx~3h!YW0;+dv|j^-H{2lgm5FNd?w4mU}s*zY$1$?u<CBqc%T
zaH+KMRs$qSV at T8Pghv#n!`P&V)-3$a#D~twuZItRF-`K=k?ioJY0PiE<`c0|`}P^;
zV>#Tu8yeuP5?W;=dK5Eu at dh2_<=sT5%<F3j9Q*Azr!}kG*H&Bnw8sbPQ>{w<^+?=J
z<L0l^$Tv&fLP4*iPN7*gq;2mkcSgPC!fE3sb2{hYaD1gw9DsM=sn8S9{^6lq8D`wb
zdT*h2by1~>bk-Q1YHG7~?m*)x$~b7&BHK1ae_oyC6%{Z?Wu}6EtgsWVSy+LmK(<<2
z9-XQ?k}-5jN2*y{K|qgrJNJ_Z4q}uC{Ahl at Qgb9TdU7d=m$v)|8M&g!R()wZMW&xX
zX4YZ*3%P}<*Ql8x<IZ7LT`@w7j`AD<Q7X=pgE at 5cPvxQ0?BWj{<YosX({w~F0vUKz
zvCxDBjS6ZRVqf)1BF=!`ucRt0`|R?ia}@ciA4=RY>#r?-qK~E{E)pY3H^L8o%~AW+
zM$dYJCguVrA}F^R&3F7j&|rc_vfG$@EgdL9G=K{vq)GQMZJb0tjO`H~eq=LGVL4Er
zYjsxhxMFyK5K{VyQpD<P8<XIh=*6;;obQAkl5c$T1*H1<m=Y8@`L0qg*&g9m!YiXj
zZ~4``pqbM&Yz_ll=6HHO)DUuuOXEL5fYJGIO!U6|;&USi#qSc}`6XuiK~Z{%ei
zIK{?oFpFr)T}6oh*XF~bYR={6G2PdR7OR85Yqz`dBG_jTyO(vz-;!S?U9nE$CD30E
zh~AFViQZZtov)~X1?0>@k^793YJcN>>U84s!@x$hM_DagN7mxh4gC?Uq9lMmgL|ym
zR(o-oB at hOESRJZoW@dQYtRj$tqBZEmdwrEMm*Z;#cKupi^~hE~{jg>a-1ocPEHEE{
zJRBv?gnA6`(GeG0dLd8USgz9$-E%9 at pn`o>;DMOt;Whj1N?Thu_Sy~3yu)xi$Geu>
zoi*}%Jb7C($rR+?@8dDAGWuQ4Nz3tJlnQ5)o|Jr%WH8d*3mzw+b;bR-95oR&Hc4Kh
z#5vQp$(7qy6N!ypLwZYnv<7PsUDstkBYarM^#X)Q>Bxvr`%YXwS*}$c?aWWac^Zpv
zi3W7d-`Ka;gl$%#=5hCu2N|N#m5>@T6GV$uEfAp{w6uXO-^qv-W9W~AaSR at JG+WOj
zI!=Ee+-$ZHp8Tk}Q#{SDeL=<+yAr1Cd{Ph-6B;z@*mEBd*;^mATRL5}^6o!>9}w$W
z at S^D(*-53NAcqMeAhGS&+>XVbQY|>dYsf2hDL`9~!Y*)4x|9 at DvdOyzzj1|X`$4++
z!7X3ikyT24pC at BapH5z|_#%%Jt$eWE`>A?@CA)avD4qzQ-&Mf<pgt7`svEOrvjV0t
zTaW)>ppe(m$pH5vmS*CKLoZZAcMkeckBWqefW7!j$XgTMK82bOUF(<W?$YZbB9p{g
z at D|=a1 at _=7J~G|tPN79o8A%AY%n;f4^)d7N*I!K6qJ83`lByuFY at BUaR@b7$6jLiv
zu`iEACjLt+t$Q_*XU2X}(H%!|A<FABpX<asX?yY%n9O8F8tb6VZ>SH!1TX$`BCVjs
z;?@_4sM}3yEgg9q9V3Qmg6iZ8;jvK*{;IeQ;wvsGoZI0B0?QV-z^4(Pvpu4gA(qG^
zxE+ at 5VpIx>{HQOl9xp#VUccX4KQBiY{=09Ad&g4tvLSlw=fRCd*$(&J^cv-H=dbA5
zY3R*|#f#TGANE#wXxG3xf{IMAHoCpsRyCH)wajHucX1S5iZ>1Z2-04fp+w;ch%&^9
zhV$<1=4=mzVAXG#lGzu&^P0)+Iq^9LRQkm8=>wSse+s=U=P2FiCq>y%at}+mYQC^w
z>{8xw at U89gt#62b`EitBBi?uOGd~j^D`G5S5326-rw(rSzcj?6?AXNuuhweEm<Y2r
zP=yNQH$q<yH<~_C8F&($G at 3e?%n7aWPtm6poAL%!*Pu1u{BrqkEx<b2h<w39DHyii
zPz)hgZ{nKW1_z2d2G7RJtqrfz6Hc|BVirhRTWNC6HeEcya6X*0<_A;DnffB9DrZcw
zj|CBOZ9P&wV?W=2e^^%+hd&`Fq#oh_0)}rhK`jk3$&%FuVH!OBQ5c}}ftJ+E*8gqJ
zJuNn0i=62=3B at fH(EB2WWNj=9g7+v&Ec819N(j}+e1j9g1T+{3zUbV at 95-6IKBpoK
z64*NIZ^$}BW5obaIgDyGW%- at ZvN(eZag``%2g2>n7g*l>p89YXSlyu2ZdWCxHXN6P
z6oCB8QAITYKUk$YA7-g&ChRaegHjVWv>Y<!yqG>(G6l}CHth`E38s6=^I(TcDDJjS
zCx8oduPgN{<J<83*|9#~VP&Hv!{_?A?Y^;-S?HAY?U$nEQ at _JAc@3%T;8$`=l3iNI
zdn5TkO_}pzc6cEFk?l=VKkxFx&HJ;To1DJkmRX+<qqExmabwN9P<+&;xF^kHghu7n
zV1elRJ(tY83|nWxiR6*VrmmKY{yrOjMA*2U_Cnp3XHcxXaMg?SS-v}DiV?`F4pZ!j
ztG33TI9v2?U+^^4pE9_&WM+nESIW7e=XVuFeUBRBZD_Fh$*z#eF6O7 at uF+yzZ2t4>
z?K{RuY@@bVyM=276=UsEZF?1aOU=A|GFGxCaAe$fREhHYVFlLQ1ZL)E&NG)0M{@D4
zJd12q!FR%9Q#Yt?DsRdg>xCjcBkuUBIR&h_UPZ3O4$>|zE#=1T3y-{0Gap>zd|)z*
z$Lh7~4!}^@*E3w?!LWae-&+`cJ8dTsPvJQ0wpvTsKdYli$DZ~shJe=h)B}_jBY$fY
z!mfd9S5{=w`ZnKGI9SL+f4YUnVJ&zdlF<2tf{Yd{LQVFZCpn42$S_!_cL@|*2rJ|4
zo)e4lCyIQ3#@D3uedA#XKgcYF<C}Fe5Z`(b4U1ax9_UyNq=i<0M!#9+!)$cqJ9|j5
ztD8#uYIuFlm*smt#A6AgXbn)nrF#59Am+9)xS!=qu95ZSY~A!`Go3*oZt;qm{NnhD
zr{aL+ at v3&Jh~JhVg9EtpMLqnY3Ihf!Jl7gX<hWpGOPorCq62$Gnv8mcU{OUL5hA at F
zX;^=#w@=ey(Q!#)a(W|Le@?-)9{U2q`BjyBcEDEK`-u+7fNU{JW$!i`kq4*WeMn^X
zgA+MYvm at ab+eV51!Kny|zM&9CoHDyWSw5X|<ldFkkSj8j;W at AW{OsBKG-q#UtVP_?
zFCo11)In{|`~}Eq_)J2th}I%n`Zarjx-w}pOk(Ud8Ti2ul-%fTi(+c;xsit+{m5)3
ze0f~JJbgX>&o7qRE)2)r_jo40ce1w|upx_zlU~D}YnzGlY<UgMb*1tuD^AM(8H-%R
zXq1!_V0=Y5zdCLhO((UKF7ucDPkW0 at Bwo8k?^ye)vZ5<r9?`wuZg?H?_4VTeu|Xjy
zWwZ|VD&d&za&RuyXOiE2!sOsb6mFxgkcVS14&NfmmS(=DRc*h9RJWlVj}G^6kuE#+
zaCpU}KjQrIJ#j`hjqe^0(^labh*{F`K;NxnxniG$#wu at aJh#*Tp~X}qb7 at 2M!_m+A
z&551AzSrVPV79kw^qdbpNgp(Bb}-<*&)sxqy2Fwhsc#?2 at ofO?xKn%ZFn)NZ>JE^;
z*Q(a%`8ZAO<?Ssff)OU{&fm97p}yyo)=TDTKIkEUo2tm!cllsGfZ~&jzK=mstKMII
zBN_Sqtt>fs^x<9G)rqh5y-a7j0}n*>wD|Tm4Nqn8)g!l*^D2Jp at pE}SJ&R?cPkzwN
zp#<J*yVd9=2&dJMHj3H%WXqdSjUO`)n0*&Mt1*%0W?}5aAy0`SSUONF8L6=J;;U+3
z6obDiDJ47-VpDxo!d)f-3;P)&8I9NtFAI6m(Hv_+3|3PHs>1<&Hh%!COrv*av<Nsx
zF=hd`uQdFjU-bWD>aC;NXrt|69E!V3aV_rdw76SwcP&=j-8HzoTY&;ia1Sk3+^xka
z1PYYjy!Tu8u8%*mkW9!-&YWkT^X#+tnN!1kFFSC$y$ZfaKvm53(gn at B_CyIl8Dwr`
z-hwQR86My0QM)`$+ at hfpHq+zLaQ>hR-iu&7yXuB+U9TPeF%VnIq1v6PdcsJ}X55an
z47?xa4*QN`WXXR|MzE6-Dw)DhgE011lQjY_(__an)&g~A+%~j_OhqShuFCuBfXZ(t
zyB_kR=5p9J_l3$k_ucRxrIyic8h;F^l!r)j(dq6LJ&xje8 at uNnl?E-=(Acio;0x&X
z`7s1 at l0EAeQ@`Ux)D^t&9L4eH*Lwx4v!b0sW8nIsmKbj$%>{Is4D}jv2oCKvp{1A#
zM0zV%O~sPR+|1lZd*1Y$M9T^aND|J#5`osbBaU`#Ay>Lp#8fQjxyc{nrWm04`aoTG
zKlC_9>AI^hyM;c--d&;H4u5URATDIWT*4j}f5%lvT9`TO#e|BwN-$exb`D_RXz{+I
z*^!MoOoEgLxO;LT1bRgcaF#^39PO25DejSM-W*Zw11%xIo95PxE8F!E6L at CXuEb=h
z$#KU%o*wV1N1H}=zc_O}6uqIWI-vApQm4}idN24t6gNSlM2mo<<lN)2TX7r57>4+C
zH@~;oth11JU*=G5XtU5YgI`3S|4u1!`=>^>4o at k0e&^zZ{OJDvGvol*zxTX#C5!c^
zV-_SrL}TyY>bc>+p_d-NwP{1)OA+zs5pP57rk$<dT%%nYpRC5?hp+a!NcPtpxoDd?
z#*&z+$M+ZPEk_<a<FX>O$-QZMsYy&<2xF)|Gx$<rj(kX9P}|KkKr0^lVNfi$9yNeB
z_{e+2EXhRuz<G9^a-H|-3NMe8oFmYONmN@$<3okqn#lo#b95?Jd$rW<1ipp(loN|8
z`daKfd0#^m&1saE!{3 at Ghtnu3dRpx2heYT&yImmVC-4 at jo9MjObZJ+Fd(M6}Mo2u_
zXVkO1l-*<p|NN=yvfV)Ru7HI$i$5|y=~v<dTIOU!pmH8N&0<zhZ at yZ#NZf~k?kI_?
zs1cMmGm|GI?dcBm#36+(P`%?Q(l%8UfcbBJUa%s9zTT6iK>>zChs%nUE>ATgA%15V
z#fH#mcF*tj+3t-KmAA)haEBHPrh at CmoiL2cZ@AzSw{N}LIODNtlF&^Bx7!T2|1Qf}
z at 8w`#Pf_a9G_m#Wjn{BubB@|@@3%e#ckE3Zo$*DF{g%*FdohWqt$h28WbqQHkRGd*
z)f{8nDrgK at QP?Mv3SWy*Ks#0BU6mn6v(Gmqf>?c`^bwso>#4CEQ&!y{pu@{Tlu?oE
z?uyza3G05GwG|{Z+RQ9kTHm14#*=gXB{D|jb<Q^DB$+y0C%Pg!=!{st8;??q2p_dl
z=WC$no>;8)QX}e>abw!$XUuQUciH|y#gI8M?D3m>q<!CYy!0u{Cn^}Ym;j~XM;j$Z
zPNy7KD8jeL;q9xDa(qP;cHj&+!2=l66QWz-1;6dsRnim)M#)H%-$sf-wNw<ldl2C$
zYwUjM=J?y>hW870Taa{25RLk`y;>unUPF%e#{oDtfjwuLz<I9iihX%dEhoJBuXIcp
zn^Q1D4Ju9uKqa|%0N4>o(`H6&+2o-Fk4Go)HMX#5KMxxDt+R3z!CZhmF(P9DAUP|5
zv!ttU`oLU*YPAI++WN@@R={xq5m%&A!IyXZ9TpQd&7-0O65upf&EPfYM>rwe)!DSG
zaO3olF{eRka*QIL&UPSLOur|eTToYw$xfMZo#o>+Y^Q#@863<tr{sES(s+M6 at hC0o
zWgc{u6bj)HbI2M~9YdA!Wb>T?ge3kJ7;@WFvtblN^m0v;jU3+;buF<l`^XU9uutXU
z7%P|joSs{<=|M-#bwBuJU%nyy$u6)*1X-TAlLgC+v`}M$k!1BFgow4$i;_S=Oe0(6
z`Z at r!_bfFTcd`aB+)JKSE8cF#n1jy5q>y@<xTSeFf9>lde at VMMi2P*oPfrjTTWs1}
zWgFP`v(8M1#%1gyW(3J~`=1Hh%%Vq0fK1{Ovw7Kdu{+jLPby{cX at 2D(&!NZQnB44M
z8aJV6EKO#g7AFGKT>cNg9pC&_Gr69A9e!LHj48U8fYX5i^Gk?eo2y+JXJkZVTg<GR
z{EIic6Ip*E8<OL~M^U~cQ7JVYc>m}o1?`o!<79RW*`;R8e3_uCdE*sL$Qi%>i8&gT
z;WI<Z%ax2n=uJu9;3D`IpCkC5wXwc)zwKi)Boad+%PX;Mh9>enHn()$7jW98Nh)GW
z8jmWYzZxUpyZTGPqlklQR`QR5xB=hy=avQJOsI7~zGi0;R+3_Uk6H~iN}6HGYmJh?
z5ksUAJ+(-hW6ita75}?4{PW)*=<dvmB82n<7u?W%Y`9E*CHJXz|Gg~oK8zH#$d{)2
z&)14Uk#Fj?!8poG^rKcM?e>~UmiKGkMDq7Zf(HbONED#uD?nx+7iqItmrK_3>v`+V
zlKmB!fQy#;8XFUXzn@$7yqDbrns6<AILvJEq+JAOXG|aGb+>2^sQM%rlo-W%qMjw;
z!!;4AX23Zm!+yY_d5hG#k>Se@%V*MS2AM_qz)A6K>y3ye+v=b-3O5UHCb0{XTbIIv
z8$E>&hA#M<yS0AW?=j4T9w5(vB(U7E*53r42 at +421fxth*ouc9FZKATCuzIEZ#80%
zKJW~e-R^tL1FLTCIf4VCv`<aP1GpZ<W%;4d^1F`EZj6$7EJ^bSy9xoRjyb?<UoE4D
zY5 at gPuBBIggBtc@Qkm%;RPyZI+}Gyj<}t(fhhoi(BP4&<h~UrBO&^0onlc*8Nk#*w
z at k|F}69yW6ZIvbcz%UKZUsXw_y(VUfnH~__!G;fPot~`b>tP3c`Cids;uVD&?Ey+f
zE{}0vw?;6az7{Tdw1wQ%M#n)j{%ut3=Kk;)_2jW3zc7UFvUEIum=W+irUh%w(=w at w
zAjMuv;u~ei1dvag=Z8m|zNs#L{P6s{?h=w$hH>?9#+Edfmb`&@DRsd>8TvrlcwrcB
z>?W*;iNU>pv3 at mEV4H=mK$sZag$?UK%y0PAw!d^lWpWh(<>tKv2<&PKbT*eqDx=ZT
zD$1+|*85I2suPUm!?zHCoI(s_ja))IW}e*5V=Ekdg$xOGUQ7R$qZ3Q_{z#l106H!F
z2D;E%4E>QSaAGb%ORCUp>bO>(*k<;9A2rG0?g^X0+WxJTNojbpF#xp`bPSKZefT9y
zm{&Q at I_)+&3+E+QrdXYV6)bX_Ga(rs8|0Ursme|kpHPw{knAZR2tz_HgD^LJ#QUnZ
z<JYUX#&%z?zvbO5-#y%7siZUT$X4tg6DBQd7R&A&<3?{Txeei?k5YPx(S&mqdUDT9
zDV%`c`gb)~%UKmFgNGP!ILdei at wOyqMsjVvK$c(SYgq)1Na;THPyV!LGla`y at p{lA
zjsOM<trR(%9Jb%iP%DFI#5jzFgr~7^M80tb0~7(QNY%OXD?iUJoK+T^bbxSLJ*(u!
z#Hh=aVBQ~bKR{r at T4%ypasJu?JF?7KT3S8%I?lILSJ%*R93K<o)+f`4hf72WhefI@
zuNmi{nv_2>a`}|O{OIO&sdh0C0#Ysio;F#_Gopbn5LZq`35SeCe&QB`(iiUb`J%b^
zmulc(sBY8d<>OLay-rO`vt`S1U2OH!qGaIfy}SR4@#SX&9i8k?v`VjwEZ8uy^k_yc
zBuNJl`j{?TfaGqmcdTa at 4XXQ%Q&u(co#tWL*do$w*q|MT;6Z3qFir?YYEuAe4jH2G
z@^*L^8CLNiy3orMm*x7eDu<72DFCJPPy{P5&<u<bE4Y7<zEJBh-AYFSxqYs$B at rVi
zBtEv1td8^ilp*rPiP^!7;6?(UY7f)8*CYjpYiq}lR#i|lyL-H7qk<(OB|YmCDP70o
zrvLhy>BHEqEyqW9`pqr$ci9jz$s6aN%O=t*llaR%q(6zA=GjbzHy2Wu&WnEb4^qKi
zU6_4+8ixzGPQjTt;#l<FBAmtr!>66e|0<ZT*2?Ixscz@{L{JxM;qp^dy{Wb0c4b4@
zWAB`Eb`DVo6H%d$EX`Ya<C<kio2^P0nvs^(Wp|fjX2%H6zqG-ELe@=pe3TETur~Wg
zqIvUwv}X5VE2bWJH;PEZt^31S&f7LA-kP#tcy^r8%kSKZ7qno_OV9qk7M!n_!IWC-
z0ft}ukhv7_N*#q^cS3vjNBhFPmr6ay+yAhAk1xT}aMp*6h9qa>h&bnCB0?rfOtW&N
zirnRR<c3J{*_`4FnPb0OoWkvDS}*$5JT3z<QwLk|j`KHvKAlM#7Pw0*X)0Py#8%hJ
zd*KPt#O$GUn6#Y9aOgtFoVF^+I;RaiBkd<KNn@~Q=i${NkN)h<H?+Jxq%h3CE_0L)
zqwF?o$7{lQA>95q7^`>OPcfYzrmRHqX&^}`bVtbZ5S>N|$9KQbme?!-Zu4}!Zb4$=
zK)@lc^ppuxPL2 at ablJ|qEDTHNAGuqoDX|g`CFF;9e(5PKW<7xoIc*DLwT$;Bnvlkk
z&t!1$0ZcgYt+T;0{epgv5in_Hftm7Pa&RIkR0wq3^#-y|O}wblznB$jR0n&4RU?86
z9rvik>krzD*{9UopQ#fsJuEUS_D$>=E^7=q^x++|@!!D7R9fzUBmG&YtRBP1J-2Bw
zrWc4PSHIyva(qw1Q!Ak7qdXO4>Q1csM$~|}a45|2Pqvsvz9_C^>rDWuWth&B`4A+9
zfRvQKm9u3S9h0;>o&{6Wm)=1Osk1P(U at Mdzn?@`_LTZ4-obB+6*{`2WWW8}nj55mh
zj#C6x<Tu#9N%^`F)z9OlJwdFeIk8QaGdEGD1<7<tx^kldNx)Wp+J1b9YOgajTCB$>
zb_aW|@~U{|3ADkrkKKH(<%udLZoP{Q=?nsTW$%rWvkSntlHe%|wu`ho78vWLsnf2%
zyWYo~i9&ovfnu(+)`{R+Lz$}T4iCah`y??^4IV{@5zu#$O=zZaPq(T$f_PRUW7f22
zcmHoilQ3FL!l{WuKUU6*`PSd-=8)8TO1U!KaJzN14fKRV+!)&mZH{t7j<P*nP1bD9
zYoD{8BMC$AU-l2{&`|7GkCg%ce-F3_H)%%Sqhv%>Y=OB0Ed>peotfwwr+gJA0iieh
zkzt9Gy3$aBWGW&~FKvtl5%lo{MiY)PE!Wjb5vRJT+d2Urr<i2=&-F>Ai;@$2_Eq$g
zQFWgm`&*IDrUoVk+WeY-tiX*FP~3WeLZ{TDDP8JsaM&p)5e{N(@v*YE?W=fFI6WW*
z^<`Wb=5U!wH7<pF8&hKjY}s at CW4Dz4r`|y0Z!0B{@9BC8`a<^a2E!bpVa^Jd9xFSk
zH0a8j(|Kg^z=^;C>H4xAciZ^#@D=*Zda-)Ell)~P>Q;vuAs^?=zwMc&p`ZIuTTjIj
z%=)|NRHObAJ(QhzNV7tX<4dEcZvBXTc76(qLwc-LUDVqN%O|lGxxgx#Xe(ru?JJds
zQ8n^^ze}VNp_`9H8?XnND1B-Y7h~jxC;NwjZ-2!@e09hF&Q9-QQI1MG at o}2kT9$sJ
z+3j;R-1-s!Wnf>lvgEI*<kMp)xY&ZdIrN3;q%2XpEh>RxWZT@!$7SG1u-|@EE9mgH
zWccMNvDKBJ+ZE!;&O)qwg<Jj<KaOkSAtEY3qBYI<aA+PVwTvy1 at a^@iWETV0pX7S^
z*LLGiH4%6DFKQk-`l-<yj>$$rJzKKnUFcIS=A9KR@|D8;VK4VO>kHYJ-~->n74mXj
zj&faJkB8Hu2WX(*-uGY$hi!jkPQ&^#T~g`ZJFlRJd%yBm=FnKKmn%kpEwq)pQi?Dg
z&a#6C=`xxDeX%*$*;3s%o{;Rz(LgiQ4ew*~-463-HnT2HNUZxHX78 at NdUiWKBJD-M
z+gN;9&z_X`azS0}27iX$VV>el*4nOwveHT56&q&)b7+E?)RR%rJ at j%U5>?~BP~Ag$
z at 7_oFu^{GZNDI}OYc<7Whdy+2*8g&J*8iayy4&)4uhMhb7U^+ExZGrvQvHK-<1sfh
znug{LZh&nT8>j5HOq*s@@3rg0jzEFugP1wE<aLR}6NUq`0$*E at e%50u4xIF0Fa at L7
ze|y}><jH_e_R_&4&E at m@sGgfc{@}ygAS at f%YepJ+c`aVRvfWqQpjzI*icm6X at h
zzSo#UnA{Q|_bat);oJJwyQQ>@z2Yz>02Cn4m`<rAdaQS<oAOAe6ySyJK*Hr;DpzIZ
zudYF729gN{Ei-$Q%zkCglX^Wb`L~`YTi-_Q|DCBnKV+MMjl)-5J+5~)&B0QVUI=mG
zgo%uK$AeT~27~#4J*?Y at +m?T5YGPZdFgHh;Ds7oIT at -%Aa0A7*y`kU1Z??a|#C|@4
zq1VQ3Sh>aD&~tc<(M?^kz($<e0T6%rcg-!RepfvWJ(1hJ#=l2bc}_!zyS^of^%!xY
z7Lcs~g8xeox>S?~(j!e+4zVjDJ!l^7BZ<(*Hn!n(R3a3jRv&*Ggc3;pfp*5N9#r
z!wXVflGMcTyUMqtM7M?7_4QlqTXt!7)ZeGDRyfI7ballbxfrI^5ntdQE1$#H)$6J+
zcYeL-WA6jpZ1)|$$j8{gxBjU(?w#kq?o&b!{Dc^Oi5OSvh@$HKlR(9u_sRrykOsTq
z_k$$nG<mw<C(FF$I4?}x7(9N{SX<+?ii`rqI!cY=4ed@&jO>DvI at 3iEdNqRm2ObqC
zJ+lnTT5*ukXB})feaU at YQIcnj&_XK26`%C!Lro6i1}8q?-JdPBkCedqrF460arnWA
zHA*TT0jHtsqfF at Wz8}Y_eebw&QK0P);zR|0At3{W82|6wn(2Wgqx|ud at ALC|4=Ley
z%-*mOMMlFJ`l$W22ZnhbOg(MVoFn~Z&|7k;egL*QO9DlK?^@+%UOpRs`&K^@5=9Qo
zXj$gbPbu}mFLdG}h4`3b4NJG_%8C||d6q)wQKBp6vgGyCt+Mft3a2|fxmbO*1Bxb0
z at cYVVJVlTgt(b0Oa6-D=<4p{Bu_;fp*Wye#W5KZ99%_zt@^t<sJbApKw_(kWak$Az
zN at x}jmxx+A2s<J~q}9>fNomuzI{}iI3$nesy7JO44&*z+M0wT7V%ZU8zge;qJWO#O
zkL-G~c_X+ZY;km2V^&JA!C|gAdj+q at CA5FLq#$ZV*s`1QxDUfHb|)LHsIbMdMKiVf
z+ZpFrNM-*qU)V_4@!u=N_(IePn;(E;1s>ccw<Y;7?_7Shj1Xo|3Zm%>+-#UFIZLhz
zw<-mw(*_L_DFjXm&EwZ<iN$d`rQ}U<172_Tu8ShB^n&7YO0^7yCkrX}d+8|Xn-niz
zpQIuJc$&fwI~E_Bu)jC<4I6!cXCLIUP^2OHkW>oc{{-m0Y?9{8bSWOWv)QKd_cfIE
z_98bQr_`=K&if$BkPh);=~Ci!+rC8`N>7Tznr`2R_7-C#2|wl7S~@t?Di7-3`%ZGU
zvb{y^O&GP(Q_Swr!AG`-dka=t&XuI2;)K(>m)1Mah-USd;JeDYgA%^)+LDQ2Mi^Wy
z*0>3=kxG}yUs|(qn}F%<V{>h3JZ!BR9bDWxVdXqil|(K%PdBcOiv*7K&|gVN^H~@(
z6)GdgG`?GpVD@>N77>J4e2i@`t;U|?hf}fpw{tg;LQzbumm^`+vJR#yn#_V}u~vr%
zdf)@8sIBZ0y!(j$TW<pb)veP_n?6*$L#vM#i;7`<sw&*vAW(;Mf44!a-m$?2vjKj8
z;BqC-CE2lRne&u>+oZ_?T$SEm&j23TmxNFi24`{b*v~APN!|p_z*%lUqMstf7=F{=
zz8{MxqdpUE6&^M0ky}pfclVX;?PdBxp>=wreMtwMR43oZ#<NQE$(yv<1LVs$%I;0H
zJ!5Bx9{E<TYI`C(;#XaWQvhl4uN1(*@}V-a#@Xlgdg3iuu!-+!N*-?yAk6WfRhoSz
z$mp*=%11huJ^1`;y-_{v;o5q`e0n(9+4(!Zes at i+VxAlAVQ#wBiCVUER?1LL**&$q
zihsbm9eAbsW-pG~n^+`bCVG<>Z}t2BBoxnuGeoZ<%cOHEI)QTb=nQ9tp?0%cAwc$g
zg5wW$ueqBI3ju4vtiHkzn;+A{b&KrPac^3*wuE%>4XZO*gM&&vv*K{9%}Sj*MD+yZ
zlMy-=Sn7PLRch7fM~yP=@wrE}3;TIetD4K~6c!z7H=tMW%mpAk5(ezlZ!|TfBHq5$
zN-0`P?BQK6qrE#EWGh)bUFm$yg-h1pSuN2nQtd)(l<LN_@@4C`k!tw>vLNp434XPn
zVpO%^Rt8?zGy7Vmx`(Uya!V!p=G}O at O6}A1?Xs~hdekyyD%~f=H_{nCLjCrq!zsF|
zRlI;BB7f7H_2ype0zS at -_mPsk_QG$=7y9ZLN#-^z=UBX2qgKL_m}y*wpC&<=rlLhL
zDn;E!W%dt#k^UhCM<9fa-Oj};SXZMYje$uIHCm))srxEiCmS+#bNJ4S0bFdDQ+6{8
zbOf8cgb(3NZ<MPGMZFv*USkvhy$v$VF+GGUS}jp3PoRgUmq{88XS>Qek`o7!=76c-
zFX<wz^RL9EsvX<-5ae4w^qCXp8_ty^Mv7Q4Un<^<5gY9W4AG(KIr&xgjQmczY|)o_
zH%*^N560g$xvkW$=uI<B2H^3m(WigvAt*WVho5ypDnZp#8%GjRFk_!oeflX(GZFvV
zJ#2k$B1VZwo3hxFKn8z$5Uw^|cK%0G8sZAH$!kh#48Q?yDCzgRKYT_VhC at P0h$>DL
zh+SlKe5k^5Tu)dlW84>MZMdQ&sAr^pXwtd8Qq&h|!Ql!~q<*yzNp%L+Oa03CF-4We
zJ#tm}?d`es<p*Egh5wfeP$Ou4L{51T$!oL$37#1nqAH}- at kGTqNs1O*{A{bwdN`Ai
zq$OC;l>d|@miL_jIt_gnN}ObfbCG7>5-n!9s%FbL2{H%TPM3Vc;^OyS0qGtL=^}}$
zj at n;)yb=tTn(PO;g%-7iG*}mN2#HC;>Vr{#E at Y83B%of&+qmcO;WctY3O{n19Pt;e
z37DSiHVFpU2oRgSZxoq}PBK|2{k&YLt{ade9xlu)p#RHIJa~}iVzFLvcL}Xn^i-Ir
zp}N_5QU-k|)6<F at tczaEUP!x_)wOn#AVVi+Y;sFqK<3;t4hO<U&_B<BjT8vb6xNrg
z30LOW>fPB}UNtz)VQ^<Vq^$i({+(n~aePLOsI>K9xck1 at fc@)8y2sYcVIPO!TZ%k5
zoMHo$Kddm?ShCx~)oXiHP|<q<zFKX#1GC<3I3Z;lTrlK~p7t#!98Fn_LRj6zNc%$B
zMF}wRR+&gKGu2VQqms;-_z=}+e$%&$Slj_>_tgt<z;-wxk3nW8bYl7DJ*c!*!zjzX
zJ<Km(-OKBNo5r-Fe`<dQH-WR@;D5OzGWkd20t<4Cyb{;CFg(DoD?L6yqHCYUcQ?aq
ze~m#@TQ>mlr?HNeeph(toe<8{@HrVd$XQ_NK%@~tqL|C+dhkriX<x2+TZclu9xu=+
zlVg5}kf3W!bujh!pFHelHn2c~*g-L4JIC7;y;j|t!n*Xvq-qp_2US~57HGvDwt)Ba
zZNv)Oir;enLdF}tZJHLoob6+dpN2h=Q17{)Z3t(;cYJ=0;4$lwCiX?2Vc at 4v`@7h7
zBS0iY at qmG+RkeA<qPeOf`+0=+eD**UqO;wA1QypnGl9h4#B{LPyxV}B<$=Idl$}-^
zT5Q=&=QAf~cONWE{IxO!?M{tAxO<b+HapcyXNI*}I63DW*~&b~iC_DsE|rnA`aiR>
zWX)>+7#H6u-+HTy#F=B)>sZ}4L1$;iWp88yRw!0aR=)QB at JG7&-8OweQRTtIAzw>g
zL7JyK8MS>g{hpeNPfyRSAdORoXm)gkGWD&1u=nU?8iaMhiZqRTKm!<lQ}5D`q at S<1
zVWz3xh|(I<;H4hgC#J6BAPpdPn;Mf=s|`NGY}cuCtK4&G+c&7wwdx`Y$h{E>SW)f8
zPk-afB+SNe8N(WICSDg?^!(lx#eUUry%<N*XrDK9={g5X?g+`Rm1KTmju`5wFRJym
zj1TS5&dO;PdxgeBKD|Wc$Lm>G+w#CXLk|Y;Lcv2vkfBFw6h<<rehM7<xO9fbQ<Xrk
zP076@@(#w_WwiHvvtiXN at M<K%Z&(xud51`ia;&<I1TeNpOE5UxhMeW;GG&!;4><*7
zCl$)d??;W0s;fL~^q1q;R1%-$d4!4}1T<+ks)b8APsg5VfyV(O$yv5IX%75ih)%;A
zUBnrzY#W6cE0yyf^IXA%j=rjfi;)%3v!sd3DajG_+O_15$Q6zF^@>_X5eCTa{eIID
zw!EO8oKYWBV7lHv^q`A15TE^(=R7W)WP0*O)NTV}gkJUmXgeI_%ZlatHSb~jwjR7p
z6q^C5CZDlc#rC);aT*xW)#HwZ;Z_ at aJ)sC7wiK_N)wYXLFZ>aH&j4 at RrLK<keD!RR
zH1y+J{eHRNk=>}Ana1<iBr##q+IwrOjk0EUU$+NU3JkxA?T$z$veZwa5}X%lU3v}f
zI4fzMID*Z+T14+xWxObBez{l(raw3DcpFJYhzUOorKH;|+n8G%s}MN?03*wf$nWYO
zEdnBsPGW>8<$Qk9D2S{qav~~+zgJaoc`64nEZ`a;L*!<RAOb#`(u{Ic=W8u5*mizm
zvx5<zWs8XhsgUy^dO9PRqhjVXB)}}4`k=POg>r9TI at miWa=@}nr&;(TX53FP+YqJ|
z5j4$Rhw}Oxx`GVXb)LJ(!;~e&bb8kIusj at d_K4}x5{`24W#ZQ{?@pynxTQTEPMh3`
zB2A3LKw;j>h$`hOd>y2NznEi;YMihs>8xmYC!%Ivp)4xx>dwiYhRvDYeSVz;L!V>_
zvJ$P$FiA8?_26}Q4Ke1_5!*iJidD9#ewQURm(m_7W-S74qy8u|Xk#JVv0y0q*nzL6
zX$g&;M!eUAbIZf%yXNeSmsYLIQG4i>A~d*4_cQUdu2(YU0#i?esL*rf4*JUKwc%|D
z<9?Z-zuqHc$okl!;LNDdN2}vx<85k{rmfTgTK9}nHu~EirIfVC0Zr818(iTqX3wJ@
zPjdSi!<X2S$d0NTY|sTe<PG)=+R34 at c(pY5jsbn2XGtwy0$)R*m*$7%>@$&H`N!8<
z;W-<DIyyQ;hC5x2g1v`UCe at cq8IHC!X0^JMWykL&zI_zIFw#54JX~t5SF*LwfC at FU
z>vdpIGUi at qd&@4zEQ0HcrkE4OMr?wwpLOfh3R(4j8wJdI;(oY-hx(D(kMUC)S{w?A
zZ0l~&?$2DBG^y-$WWvIYdm^3henF^ig1nYJe5GgcYmHQ=+xPn3g)p<F*^ZmJrb8g+
z0?v$qjcdcHp0S!+55>CaOn2hCp0P;shrx9b+CipcRQQb<0Zg|#PFi{K;2ybmtp=w>
z?O!Ipa>rk=z}RJwn~4r)IKL=sdZL!R1RZ(G1?agr(rrMn%Pjmw5c8O3WPC*Y)D}j-
zVCj8+zDKXE)`QC)2%Yy`p5o}}RpZETV(fs$YM!m!&P-Un6F4)MijKAaSb?b^HJ{fW
zntDpEO0XYCK=Y}w8S-sf0Io1y8#3TQ3mO_Lz-&mZb<~_|Z~fFEOmMb2C7=18WLqlm
zJFjPtBLj>t?G2|wKBepaQ_hEput-}6kYLT{>q7W+sP}Gded~}>I$syuE(>^AS-{I;
zQgL$j?W$4s37S1*aSQDX?719SM7YXPIha5{8{}F&)7C8^7KS;e2SKQ|yB-@>>ouIx
zr!%~PZLCC<<l<x-JNggWS2Nct3kLafXDh%lwNO+KaGx9xL>92tchW6a8x(wgqq%=%
z+b?zf*ILA;x_wG~*CJuc(QZ7NiUNhz%h01TW2Lsw!0V67Y`@1r$+i$Ieoq>$#nQLD
zca?F4oBKt2Irr?T{fO*@o7-}JE|v|-ldTOtMn_}>X7oyjo>)R-7$Zc)AQta^1pQmI
zU<!IRa;Cq3U>footD5geg7`{IG{&Le6}!*x#9U0Ebg&s+iB-ABq#bFR1zFtyW6m)9
z@$9eO>$(eL0y_QXt&xqA1S^QVn at JVl`+a-1Nmop7MD(~WG at bRyJSHD&h{L?k;lv=S
za{5##V^pd-dvI_isdqcr*!QZ$erWI7bDlkbMU>6L3%f1h#Ksd9mTU!P`<>`Kth)h$
zSlc<ba%0(V_?z$kJ-_ydT_k9rV>nA|z_I{}FnGi<s-P5ayl45INEn5YpZFK2??+Jr
zv~yqk+^_r6FLgX)ZITUJ!y<9d=GzxcF#Kve1qW&7IO+r%z1#t9spN&3N||&H(fBiO
zODZnWEwpI!`kO|O%49nG#pzHMN`Q<k>(1EwLbY8qw!m304O!%!VTGk1$FmuC&w9PK
z>hOGE8{iGd@@_^2tn_Q<l}z%(U!+zbBp93crTm at nZ{r)8%k{rFi)-JgGgf6OKvBZU
zvl?@v!=JQ#J8B_K943!$v>Qu8y4}LBnmK_AeFr+2As}i6ucDXvcrI}Dwix68Y?Lf#
z>+%px5;E_q5YUMiuHstBu+K&O7=en(5>Py8l6!)xWN)kX#x<N`!fUO#2t8-Bk;o{!
zw at wuGCa}Ju3I+M6(XPnEZEg`p3QK*-vA`^a5X^qhZ%kKX3D4H!?Gusn+BE!dNv;e2
z0 at LHmL{MhA+LDZRqH6D((prr+wq*2wdP)jaB5lUmY}JrYLKmDZKdKi+#_tsO9<D5>
z22}FMCoK}_T~((K8WZPzNv~?L(ONv`;P}A0&V&BX0q$0)N=?017g9>ehrNbx5 at 9xT
z-0fGWh(b&8I{|fet_(kiq6dP;Y9;c8Nk=0P5atYdixA(+`W$l9h$qgl!b9*S4k!B7
zJTzE7-fTK0C!yEsPP(ohj}KGzw=6}9`ELZg<G#>DlmUSL4 at T&O5%n0K*Sj&QvxBQ3
zeJb6qu~ZnMo^Zq}``sS)R;=zu8L?Tztjm%p`kcN7vfqS>%?4zZYm7=<N`!CRx!^a3
z-UjVAG2)9IY37FCZ&D6A28e+dABdQ(+)_S?1(2c9x)T}PH+Ma-VpaE)e|?v;b`BUi
zw<tl4Dp_IM%-0c%n3_3C)m3ZHvB}|`d2Bw+&!@gWsn#x}pUBBTk at 8v7146%mZu5QG
zu3CGv$D5nR$!VWoJ<v<5(3pdTK$^H<3h!7hAu-c-7vo*LvtfN!V%#Nbrk-gj=CX)S
zlcKAx47?<qaQVbeM!-V-CnlOTCmzy<DDE1AFk;xQrCX<}3#YD5g;OK{xR$X%1e6d?
z{gF31uA;U6GpW+K(^6;a9;J}mUZ)6+qSwRXk9~u?Rof6il_b%8Oogc0f_pBOTnwpy
z(i<slJh39J-U(MltHW%dZ?YCkYRTnoXbinTS33_|XkLf9D$!ooD4Pu1Xe=c5Osakl
z^Af)Qdq+7f6m=_Ul{P(qYc5&2#?}ejUPmOOZcrmzgX^`re)0OV{_oAjmn0Z=4wY@%
z`P0AJzgR?_wE`i4Eva)v5rNtC^S{OSoc49XeGP)q`?VZ8(NV->uUy{7P44?^h(0uX
z&h=PApoFO%m3M-~N-9mxdvU%^wfv!G$tP3KA`5C}EmMSbWcC4HOkfZ~k!I5ayB}=a
zIc;g4yP{$siXbW!R+Gw^RSb|uyP#2;^ifs*sr?(b>R(qzY?pe=1H$@FFHu2?MBqHm
z4T!hdD5k2Ze%0yfcPnzErhLriyMq7*Z|Reo8DC9DYsyvtkzGA<!GU02KIR6jhSsx=
zzER9WR8F5tA}P+&yq3*Jsgn4BmAJ<ssgZe={qYH?ZRrqIF$_FWFKfCyP)lq%9Ln~v
zt6Az1sGhfa%ld7$fM>|UB_-<C6gxU3i7mDx<RBdLrF+Kq)7z18-$sU-zZ=-;kY7HS
zpVxfe`ZYU~=Oj}rUa85?Ff^QCPPuwmV5t-tj;7R^*UY$rt6s*oJ~l@*4X#5z7q at 7{
zYjN{$pPWMA#iU<Gu?M{eiEqdl5T_Fce&|qN4SEnWyy?}S(qPJw$27uIMDHa%@wSU}
zX7V at b@hGX_&Q`9f|Cxp(RQF*Qt at ybJ-6`srV at I}-0>y)}%wXxGuA?gJFTF%S=jT{f
z3Z4`J<?vtSmEpP8aGfcq1<|9adRardY1eKp`Ac2)1yK5_f1ieVAE;zo*~H50d1lDP
z2??dpwVlyNQu~UFG)(-CPn2eKq908JsiFXl;fh}hc{g>-h?7A!WOk2cDcU^Twu9nI
zPa;DNf;<GVYDWT*(vKZ~V7OPacVs^rK1jc5F#m8QcaOvAaWq^+Z!TV}ty!l$?p@<l
z*J8mbAf%g#RRpOr?w_0e#}F}Rx_bC^(GM!%{6jO1Z^tB#(>bxCigIZmHW%ADwV==E
zO(~(*VTXBU`-(A)tEQ%=r;f6~Z=0&krwmeM3Zc0vW_TLo9mCXLl=Z4k_joIBh`C3|
z^VY6QoU_y(WZ3*QjZaTkNQ7ee*fBIzs(sakqk=scVpDPq8@?0Tpoq+td|VBHYKgq`
zf0^vheE-Fypla{XB`yD>-l9zQm&5nX{eB?S=U^vAP-IY{2o10a&@FpmFTMfk0`?|#
zqs4puh&42qFh%~Fv1MDqV|L*Q?_-<A@^-Ub>~NlMphq~H3xDRiRH9Tfi;ch|JppPJ
z-CsoCq(BQ90k(FD8 at XAiXiFMfV*A*0pC_o91A(J^4T#OGHXxuT029KCFR&r|wHk*1
z3ERy#n!C9Adn_tEM#W3bcA=T=?!1dF&;aa9Oc*txYy)i=Cq&Oj%Oix>ul;_j*0!kx
z at T9BW0azaM2BTDT!!tdRE0%H~vXron<LN0%%nKs~?QC(o<{o305ejB5ag<AOQZG&J
z8ol%NA+Rpfpa-oHV-iLaSs@>)9{R)*`J0sbo3he-a!Uoalu9odI`6sw?bf7*=WoK<
zUM#KFbkb(Y)!gO=#H^t?kChx$tf!h?nz<N}0pdR~44xW2kcuDco$OsgBy&m*FP2T5
zhr~aYk$D~|U4ZKRZvs*@J-OiYL{zHuxCNr9sCVBq6zcaf+2=kOd+pr9L+iXzOuSql
z{ZdM~H`7;GlzfbgvrhRieIJaBMB*58KtI5BzRM*B3yb14wl5QTd{sL4WW5GNEVp^w
zSnA7M_5wZMn}YOh!j_5|F at t*C5?@nflE~w2ub at tHCi1gbF3w9nR~y7t%zAH<rJ%~j
z?fN}qvW1LY at 3Ubj)vfWvW1nO|C1?Cse>E}gm(*{A?BcF(F$UBnTNG24yrT-H<8{CT
zvrgafK;*+da;nK%9o6kP?ZQ|qS{{T2RCstVxTWQGIR2?x<4JleBOfe2*PZ3Ax^%P2
z(eH!Xcb at IHzSyYMfi!)8h`>!6 at r3BZ52>cxA`4)<O@(MW4@?`jF??;LKv`{Hxp@&v
z5EGW0!NxCfox#V&Z2+=YI3G6=a~L4 at 9^hN4ON)MbSha^uY*7pB#B;?Pe;m3kCB8t5
zC`I?X+8T$P0SJ!mX}U))#HM5~iCC-@;eLsnlbFHsN`h<yvdBc_H&HweG+ktX_IOwB
z9h3E>J at d+2Pq>022JCh(- at N0_1Tj*sj)^6pGj5Bs2n1X(i+zjUp&Dn+&YDD5a4bL%
zFwflJ+sD=qv~6T?_HuA=_#wcj2O<;bs`72M$NAFGfH7+2NjRXSR+4Hk(WG8#+^;ei
zQ(q3*kv|9G>+NH)ZoEYo3BoG{B1M-JdSLx?zmp}+0^wqy)}@9-8tCK1PTs;q*I2*4
z9E&=EcVGTvn^Qu at cyR}Y(-*gFK`^qJNnEqrXVul+OKnz7wxY08nqPd}<2p^lS|tVF
zYKZR~#dRuHO*$LRI`m;?A(G9*yPXYxVfA!)FlCFhN!Ylzw(HH5F6lq95TUM%k5xOh
z&TY$ub_s+e)b;4{*0Ue7l|KIdx70PNp58}u{cVL@$!GKSvVNt$t7Y-8pO1R|tx1!m
zHVo_HxZ;8U(_*pQPmj&qRrjN_L at lhcS?%tn{+H>qh>v;$R-|+IbN$6{LRy-{;t4X@
zF5<8i^(Ie)QOjSe6(G)vdhxpN8h0)_jw3-YzqS;YykozaH`O%ypm^oTG=*y(M=OW#
zi!>EyIwhwmt7(^Lod*oVr?=gEOSU)<u!qbUKP}pL#EJ?57(S(cjjMKf_2chgpo at 0Z
zv63jJi|X6n6UiDzu#4Sg*MhfE_OE#@@dMVFs?dezw=V$V3Z%IHYMa030<=?(Ko??E
zJ#wRE$w0*rGzlu1KAc}$Gw$My!U9Y5GFda>pzFx>_{Pw8XDcHsrBKR9mW%`P<NFiR
zP1wWnY9+IONTEx9!ZgP@)s83U=L&=hhV3?!Jus=Q+jpHlRg$Teq(3|CaX5PqGGc^U
zABAI?yrp6+cScFfN5+yVl#o5~<%krn|C}xe9~XKvAtCbJaoT$q&sK>H%tJ#L_}lEE
z)Fz+4D|Co{!QV)qIgS2vwx>yys8A>#fFCUj|9hn+wc`R<Cjh57uVv7$@@$};{FQI?
z_-C87;TJd4nMYNQwh_gG{6l4zXEdFP<aXj=QqN5zD{HY}$}-?@pq~qwz1fCVIv?el
znwlJ3T}R^ym|H_%LmEGR!G^PPVzv)p@^O7cWUoo8N({N$k!dvUV)L}YR{>u3{~r3(
zf|7~Y^+(i`=aChJE7QTIdL?A64*1abPF5V#vKksVydX?Ks%me7A;-`vp7DPlutWq@
zayhB0evO~AFj at 1=s_JS~&i?=g0XkM6R00D7+w5lZwG>o<1AaQ_B%%;d1SVy8*1J<P
zTJvA;<|XM^dE1ucp9csNp>M1j^1ZR;;(?nu^a4bBCv152%HLv%@om7x-3>>NGqt--
z%B26_zt&%8bs$VrTN2SE>R}>)%bR_2JuoBqn8!3guHe-BeXa8+D1DR}0q({ebj2Z+
z`+vvfkk)(Pzs_{?RS4EnLl3B<_bQZ$po^q!jZ&`+-NI@|5&R at YUUp1q2>b#9WtuD_
zTj{Feb8G*<llDca#DJNT at 6XvS%Tx(81ecC^^#^UIIukBduXpg+iTi$tvAfRC`r;9o
z7gIzw-Oep69H+_@`4(+2Wd;yM_AHD_Ei|;kqV|Yi3T<V~nW?Ia=<StM4@&LI|IIl9
zD;M-AbO&b_V5QutkEUP$C%wA^SSkqzJ#d?>6m`Lz@|gfVk~Z6EVnAD!M~XQmX~P)+
z4cL^zVX|f1&SZ>g3-gPMQECN(mgj3-lT6)lP{CD_5s;(9#WamLG}3h)NVWCr?T-0a
zfy)2;IsPPL6Iuv-xFoL6ob057;NNUVYx6-a1rq4aw!hJwe)`X2Ab7(gNRR^!q5o!z
z{pVLdu5S136hOlBVj#vcPNznF7l{9!v-auv<z>N!{pF>l=-{XOGVQvZ=Ub?TV7!7$
zwld=ubIrj_+&&%ht2Pba>fFY!u|)^@Jr^H~CZ%2mt$OAE2}qZA=@r0qu^4q5*6<4%
zX at d)Jk1kfC6oTMupEw)o>vb$VK8J`nd!PN}snlk5*&Ym at 5_V`$NjeTN>~bP9SsDHJ
z^3-NMo}#s*c_Dx)mo;ts2L{_uU~iUY%g(=kIuzM`lJx4O>~>v`IW7sMMnpseZW%R?
zB|83Vp<hj~{CN=GMWrRFUbJz!i(vXB(`=C10>5ScQKcJa0$oot#xS>C7hexYD>vqT
z;PK_Lt{0)gbqw%{{ukn_$XVWZg9kGnl&HW*-Od5TkRH_<M)qUrk5iKsg*x4YB`w$W
z6h4yM0W^~nUZqs(QGpc`9dAs#o3FMh+0(WFmtjBKzzkBAYi7LgA?LLPxDk$T+vxcg
zU~DT`5pd1F%S||kJt->}90}2pJG;9%g=-|+{;EcZ79R^_71jOXBS3=Zm`;%Joo=tE
z1jXy3{QdixM|eJ!TQpO0&bGtB?NVA$kLF~B9}CEZFTn%cP5f)QoiZg=$%6nb_FD_d
zsMVYN=CXlcR^#=LWvLuPfB<Y6L?%mF;Xwv%UA?SnfJ&{`MRr)F at o22bWol9wxRGzi
z1hBkq3mNEl``l*y9o*cC_13<d_;WpP19AUJG})^+Nwy3QdYh(R(_mwCyiVSD*!m&O
zyZeY<jBnJ6=ija2oTR<|;?OH-(EQO1daKEq3v82U0vio*1!q2qmoAx&O$<8ZZEWyx
zlgcN3DY|S#Vhp^KW4Cz%YLN!Q$uuD^7(d14V{9M)c<4 at Dd(1VJjE#5u4Pgw`C#5Q%
zW+c7GMLH3CARK(ALA{~~{ln_w(1wfOVyGt9Ml!x~tiXdOC6qwt5I29f_wuleV?MNF
zfup=8`h0Kx%EPIS%o0eAg8Jm?^h)rsi>Oh)A_NDOTOXVDd}>;;RFEv1nfm{-Xgwv_
zxM$j|-9FP|{C*v6!R%1C>z}*3GF>*>%t=hd43Ud@{=Mg!n9R4gv$x{HDFiDtwR8V$
zD7!&3b8&pbtDq6$7EpD(E?cyA-6HpTopSyvzuM1ktQDWK-=9_Q>V*y~9LZJbBNN^F
z5&g~#F^tgjiy)c+Lv0_z&7T(&{%I=4ku;8<N(Q%7lY<V8zLEn&W(P9wW5dgOl8>?t
z(_+cNRSYXb%(11*RF+x5>M4%ZuEX4%59f}sBcG_!0W5(=69CDGGI(w^L{Ju%nh@@i
zhXcQwoM<K_AEOz}#eW(0IyLYBW7g*Ofm`E7ZutoiV9%aez1;h;XhQaxveXBoUZ4MN
zKKvanxcVyOqDad0J?ek1&8Q2)GQN_X72LwsR?5YN8xXp{osq09@$tQPIrVWV at p)_U
z_MvK`ut27dBGbCGPQ)<&2NIdY&nu`abAUfU+HLmFA?_8Q-2gK=TUNcfq-sYGQxYI8
zRcW(wPIb77aq2cY^T5T)O0UH9x__UDIn-4?p*T^3{)_e8PAwj(i%4ZWHcR;^<xe2^
zu1%ALkbB;n5-Q=(6>>A9RcedKIp9zANluRRfs~T1Vm^>Cka{gXwpb(qJYl{5(H;EM
zGJwhYPWE*Y@!{gz<w$`0MvMVXFcOqx&2w5Q6!D`DbpI>tAJP+ck^JPBHm7Nd>oT0}
zIDnunqwDPX%i&`$8A-RkN4r>bE!z!VnYM6>+#ykq^|=10Zrk}5S8%s??tXz(F!_Lx
zNt__k`y6wtUyv*ypS+_c2s;wSR$Y*1%KQ+vN?QF}6!`MEIrsobNB6+_m;Ir#+%aq6
z1M(T*ya#xh*ycL`@=5FWJu7LzthgO7tai(N;5Nv^0gX!nCN91*icI1vr=)~h{wBnH
zK;!Yl-1Mk(j3pquU%7Bv_kE_ECBe}y#};zi4`8Loto?UWEaad{a&G@;fwOgkD7TYV
zzNU#oKGL5siJ-%+{hpg6oc&;SI`Nmtuh&bV at mKNY17vodxGj=5SZCs$gftIb+cIuD
zWI?Y|Az}1mz7K<`WmZDPe_Pyl%C@{c)|t0(8k}(ky<w&gUv&8{{BOs0lc51vu#N2`
zoY0%ly^3j<sLv>K4Z+;Y07Jds2l>yGqqxuOm+M}x>MNyhu*3;}>;tX55PfzwT5(BJ
zR9V1AuuS{ACZ_?eBTDDRS4Bs)|K$SYdJe(o7>1Ql8po^glIJGr at TwEQC)*?)jhkdl
z^y~`*h6#YG++<(_{mH`GTEfM}MV_6V(Q at JRT#^AF-;y7Px at w)Sth>2X3bj-`z&-uM
z7TwigV71z=Zu5inq>tw?u%!9%M2S{C^!#b!b=RQmt0em6H}c2OXNjMzUw4C3R<x`V
z?V-#3SarJSK;G>&adQHZ0SR%^ru4TcQ16 at M9rw8vQQ*TlaL=OEnE9jQP;1bl%Ly-w
zngnhto(+a_37R~8^oQvk53`Fn^qxkZyd1k*zV1?+%m-0wNC-rI34U1U`Bh%ULTCV{
z5sj}93r3PbYw<^d(#&7~+y3{qS^Nvx=pJv+!1#3wj(BpJP%(xaA_7-(!(|VZ``XWN
zz#fEyc=uhf#MVxKl!2L8SOh_t>&xezQ|2oZ*xgU3oZY|FVd>=~x=tI73AP{y^FC_!
zrjniGuduS0_GFKzl-+Fl@!ijYY?7s`(i!<5{#(gE_M>)OK6#i5NoEn)+gYhpX}5A<
zr0nZ{5QH8(3 at ERXb3Fl>zU{a-_~CH at y0@BZrU12g6M`$dBG7r%-gDLO<3CNbe*JgF
zHQKhOzIoIrWzr at B=)(zTqi;xX(YJhbn5)Da_=K)_i92-YI$xUn`$|LJQDu2{55pl2
zO}a{(OhK%19TZ>AQk?}qTxXu1x#&Z6`l+v3O#u=2FS($pA4bSyyU*}k5)NjOKj}8>
z35(RV+VdzM`4EdN;olQU$*?&u<n#dYfzQ~vT<*x_xZ#&{3!Rj%r}S{2qN+GCZP&kV
zWyp}CT=m1vzN4DR#x5I2%*UhUH*OVme|r`DAQPrtm86sUA~txv^QQ6JnOCEWI^<f1
zn+_FODN<`Ind at aiLsLF#etO at u<blYfyB_&FX`<$ePv<)+9HET|l%Tthe*1H#v-5H^
zYQE^cOo=ASa_#s31KEjN=;@<pwFqg8)S1H?)d{|rm6g#x4C1VJlWc6%9x?zoTeS(c
zTr|Sq>pa23<3;fNCn`%)2o54?ANC4{$LAGq|Gm{0|0jy>eFL`vyj2sotShYn^$CAi
zji^990Y14Xg8YQBpeBOquympwEg}_nlO--Gd at JTjO!&MHUi9~<6f>*DbpW4o{qwGX
zPXd-^Pp24Gz0duVJ<VcuA8HDSwY!tK6G|y)H&n45H^FOP`f-F@=7w*F at zi`VW>rMB
zBz<u0NWnfP4}-|#p1YqpBXGGfsXntI&iZJwW$o~<vKUNVnWC0~6qIS|mg?B at 5dXB2
zNQFKiSGN2$4SF7M_ULoQMMV92bz4FcUgkLQZZih9(T-$><Y0`>o^yl;j}~F6AY>F8
zPD9Ht3rEhsIrMks8_6r|ck^(Yb&Zyw3#P=Q=?0Mt*ogw|#m0*1zk=qSuf5{uN=A#O
z5Fl7dNlC+w1JEMg&dtpnKXU7%&|%66r$hqCau=fHw;L(69cLc&o8oHb--;$ncH3kB
zonc2mfy7IszuT)!PjO<x at qQqVL^#Ci&FjAP7f82Gg+pz!=$rb^fOl&Ko*uYdFQ*20
z5;x*&A(w)Uy}R|6S8v|R@@xM_B2-qOe8>&lEx8!3PTh>kA)02Q%(W?EfF#x3Z}0|0
zc*4|7SAe7+w5`OJosf7l)(naVe at N!jo|dkD2|5!NiXJ!fC##yxr7xjw77KTyv;D=L
zQ<!?Yb~&t~Ar<TDdJK7YzrUEC`(4j5-1XyxPjPD3Sfu~2x&epvK at _cCoR<F2xN9N?
z)<()oH2e-Tmp}L`&nyGJ%u~p_Z@*<5b?fi at O@>K6c4dDq=(6 at hv2G1FJ0UXspCl#`
zJBxmhyk*?K<^@uh544%nr6z3UUurPS9Kfv{qyw>6BP!!<`!OHWa1b9R%T*i4s)GgT
z!>y at Iye(bk?uBRXc=CUHJ2nFrER at Wa{6GmA1(P!3w#skwkGOooY9ODzCvWuI@~oKJ
zXV%zjV=jT<P>0};_o1`~Kl%1QPEB7q3XKF%=v(ji>7hm7_EndKwuXg1-s4=opwdKM
zKKa|gBwa#wwECac8ltz&SN^RzyqFRy)Cyyp{hi7E{s)-H>T>y6(nEk4_yzJ_1w}2A
zCZ_d=pxI-A``f2+KS)IQg%XVZ?oLY9?t}B at wuljY<OrZ at fuB$I^k1Qhj|^06ea!~0
z40r1Ps$Iy9cffDzpV2F|UHuo%{YsB7p04h=F6B7wWfI|<0uZ+X7rwSu`yg-q-E#JX
z`GtnL|2b3GO3=K(ws3@}Q<Iy{!15n|Y98C%UXKqA<VpRcDZ6TzvM%Yx${T|%lqq}A
zd!_V)wGZWIuU^m5-|6eFr+-xDzeP}I`w|nj;y*p2iJ!p5{PwIz6_DRf-+b7btI^`1
zlnY=PnhSkV67M|F4!X(Rj>)3l=^Bt4iTwK2!VpiK#_+xmwwI%#53q1Y(m%N9%WN4Y
z&oli(9W4?2NHt;q^t2dR2<wi&&=^>WuI=N~kG=XlcH#o9>gA6?7$cYq-4Bdtl_#Eh
zXw!u?pyF7r at Nw;YuPGTX+c!mnujD|~kc81S_Z-Ofza)#{qR;}u2NQh=KUgWg{Xe3<
zIxMO$>Y5TzT9EDr5s)E<PC*)^TO@{*?(UF~5S*bwQo0*ykrpYD?gr_8kH7bOpYKoS
zk-2m4-RGRO*IIk;tDLk-Z#|6r``wE!Jd{5dORJ50D_B)_+llJ9gPMKiQ+)Iq{evEU
zBu!j*`1`ZWwapSpgyq&b_ at R;EO)tmXsB+MGsh~m3&m#(4(XYEJvUl<B2^1gh18ARV
z37F6v`X`;$G=k)Hs~LB${vV7SDIG|X(>nX<CYmDu74~lZx6W!C%>!z-m!1|?YdC&W
zzJb$j|5Q$c17;kJ6okV(O at HindN6UAZq>TJuiZM+7MD<D46i=I#nWV5(qJJp2$Q1T
zBwjVc<q^69Znoa{x)+iL8suQWpx0H?<ygQCFAvo)rrg2Am{MuWU(4I`t9eq6o3T>L
z6jyU@*E?EgD$~8oO1+fWx=oXC1EG4Pg2zUvx!i#jo8#tWW5dLT*Yy{xe-sBX>2WNZ
zA1kKRc24De=~sFOdzL<Zt&WFw6=1xZ=wu<-6NVytH5)=3Nr5yiEc*?9D)7KTG^^_t
z(}*fSLZG at fbYz(L(%^gCqKw2xEeXP}i>^i$i91G^BYK~ZB=DCo at D95gJnpgKcH}A6
zU1Q;!0|$N>YVPUkVJF?}Rdj}2U0m&V%ASAWB*$9|Bu6{Tt5EOimLKq9lETT|A*8_f
zq|n>HlDYvtH2Q87WkI;g(;pvxALfatBKt-g-q2z9_eYCglX}z4#Qq6H=SuBNeE1Xg
z(}!AaCtQHexed{oD3c=i*!*<>qnIMOyCuh9iO|ujmwCoGj>-*VznggOsU~AIsWYA<
zKJ^m*;9{7biYjow&Mcq|ObE*-v$8pq(YS#J;D!)%qCmpVEe46+K1D`^ZNxpZ%JCU3
z9YVqE(;R!f{<{*<u{M-J9~|zgA*{XT#qnRHPjwa+`F-y+QEk}P?|d=~MGHKZ<uSn{
z)y8}G)>v`7P+LaL&1NPip^9MBfzI)|pS-ZDuPC$W3-#*{!^QG;J8$)eb4LVLmn4W@
zRcf&LUgtHel2rITzh4`vSnk<A_{=mVp!RM1K#XJ8iYDoYB`NxX_x2;tzhSBBe?>*E
z_OKe)x=w7ST6lkRYuvd6Vy;KHcZ=}_T0$O`ZFOBgh{YWJ-p9PYk;_#7K=6hXtx~(T
z`~L4CUE>)SNZ+2x9vygLFSjh9#Sr=`+8rbG&1Sy)MrM#ryP0LOt8xxjgUnk_`LC?N
ziMLnpcy$KG0{f?YH2#<tknY>+xd+~ZA684()`L$Xq5qGZV}C1E~@I;5L|PR^6;
zON|D-S<mPIGJ#vnq|;Zvb_kye<YlVOFaw`Uzu6bdLeJ7G^1W|Glv{B00$7WsYz9k|
zvj45kBiP1Ye=#!oRc>s at gWt~@ttNyh#hjk#4a)E*^?h5y&-B^`Y|Xe>NsBaTI4L<f
zDA?=n!`U5Am(O`qzBE&OAiqp>M!icm_pS-e>_T!)3a6MGg`YFRe{k|h6t6jlK??H)
zcF^kx;?OZ{sz~};ljdil4zn@!G-6n!LVKHW5_k-ugiEXoK7<B_oiyFtZxNPSm6dd`
zzWV)=$BY>Gipu}a{IfY%q=u?yra?gRI+>uO$E{9EV7^{g&LhUxfDoP_V@{H at co|=j
z*~a{GdQ-z~!z}ID&W>YWE<Ek~AYxo#tsR at 7hTl)Ykg15>{_F7FliyOKKN(>bJpOgx
zno2{0f{-aid at 0pQO|5+>#Lkw}j%E)094SfsWADk^4_EIas9%jrAnO>mlIatnkgGZU
zQI||Dh6e5EfmA;|I^;-~<R^D_7(wodHl39M1Ge-`eQf at r-}BrE<M1gyw7UWUDO-nd
zV)P at oZ0GwYXyV?)%t)vbMBxnfg0ir{b^j!Nc&~NbYEN9u;f=;ucml5_K3Y|uFltcf
z#An at iHMXte7?SuNB&nqm%t^&f{1k%Nq{$`f?z0#h^tw7}KaWYHe)*QYUx|$)fR)ae
zzNrw`(faJ^J3}{OS(8T at D=YaZ{?X{X{+WCfQ~gIOgnr^sfoT`{Y{Q3qo)M##CkFiQ
zi?+YN=FYFHd**TIONuAfPV#J2nn+f+zE-sSQK^=+;G`3n=tV$J>W at j-t@rsm4}lHC
zuQy0d4R#U7CIKiDIQV78Pq at gPG?AbwxF$5n at Mf`er;>zc3Rad;v-LRrPDt4~;c%@H
zC498k`EQ));&xuLfOlHsK|6>(suE+!m7&sIT}syCFk)VL!aFTtRrc~JOJ8-Vr+6CM
z>R#A)1%*?$a>u)Vms3D<@Tb|c=8MCddI$tSgWLR<3P_&sYN}KRZYwqTQ(oAIoc}dV
zht7xONRd(P^J5!P)QH*dM_X9^C>Wm*N3-f4W>>v9UG7EYGMnGgs<ij{ZKHO1p*#^<
zS4!3Fjz7j5%HmCcLlmfKdwca(@41w+G%5NwOk5m8l9A3;%v&UGH(G3hF!?s6cXh)T
zckIox$vhAcUE{cGho9rKlv;b9rg;T+(;E5bvIbitv_!KkyFVxPj&~FXj}^;qd at i6h
zV^q-*%AnS|5tv~1VG^Hnjnl|8V~oR&C*U^3Vk5hpC1()(0 at Z*};l}Et`PEDAN~y0Q
zlvlmsO_2iR`w)l%ozk?^efZ?%IN at k#eNaWfMa1Q=i1*~F*T2UXqT|lBPjQLm&M9zI
z#XD$P&JVg at bU5<)Uu}5A>S00PVvrr!#5Oj&!4!S-1>3hV({@iZzj*P8jSIstE13bi
zUl+(*URT_;Ssh5-yhzg#_1<hUL)P>#=1%wrJO+7*;re~Vul452CnjSTcb`Klc7;GC
z|EHuRfXRn%O$U}V-joBjXWR9<)G at m0y(Q-!YF&C8H at 2yswo;og#YM4 at Kg^|7_be{p
zA6=CZM+L8WDZ68+Zv|6y)@J6{=9W6Yn6{sfnN*y6i$M3k?lJa#V2MXkhemIZy&}Li
zl2de{-qmrJq8M1fCjOxNdm-AS?M&9tW0E5KxzB=Y5&V at p8X@_guMPB{25}~OZjr8O
z0;u}47BC>GWa}|qykip+v6&ASU%yk)gcff{8e;Ul(4qTT=S0;7IK3#^c-|rVEpi*p
z9w$nWq5)!-_k_^j<=?I4u<WX_3L*g>;9becY^{EY6>K8Gv=GGYD737Up#RVg%Dead
zyJ6yQQm6BcpN0z2{)7gRH&>ps at p0$;tye$oCD1^c+0uSNc)Qzh&|RFwvfSKFTB^yu
zvYu+vmluB+Y at s((>(3`L9YKTExNkJQ;u3Ia;Q7GS`p8z>wGYX$d0KtzM%QT|%=13n
zCBYdbG(2u^0C`RPT2RDi+C$Ctxnnod`=z|S7SHtr7N=|J2dr&5V;KW>)I7By_gUgC
z0pp;t<388Srv`tRrObX(7bLi}Mq8rOzSn2?;{X_rVM{_7b5)P!GSb?LT~zL9KDuvR
z54xqTL(%#Xa-_9|%YdhnrORQd76XG%lll3^4k^>{$y0z(V%hzV?{^o&Q{&Tn{(%s7
z9Y^4{I6e{Odb?VJYyO7#i3JH4rAT;A^#|W}GM&9f%tH}Z%ER`9VJPfO0a`9xk~-}9
zt4#Kgk6jpgsQMt>oO#WQFxd;TCjXvJ-W9!g32SxVyui0##MEWJMU_kNwiB;54#kCp
z#o%Q#VeF19hJM8nz$tU9h>}jyC3^MUvIcOD_4WdcDEJIW$I+j2O%cqlM)6$fj%0+2
zc7G#u+p<<s?48Uvyni*1-`IY!l<j-Xg9B3ZPYS(fFR`qB3xrZX>oeDBpCI${dIz}V
zlxyTaW#T_`N_XIc)M*m-dlPqaA4POHVTe6&Jp at H$`Qolee~@NrKK?!MUdEL7&)YW?
zBY%8P?jw$GvTm7fry>?3xMS4VQ~U2Sk9X8|yyDa!%B^1q?Bgx_t$g6733!}hpVO;E
zcXn${bU__P5<aFx#WpBqEbunfckB7wTi;`WWd}X13eERhKsck^HS)z-ya4Rsuj?Ts
z*yRvPNl&9AFQ9SK{EzyQ*_0<X&@61~k$pttuqOt465zXssX^y<fn`;caC2%Pef)9y
z6_U`lED*5m*LYp6c=XMzrD_*WGB!Dfw}|)FfLZ9bfzuTe$;$8N9^bgJp>ZFqf_LNd
zBl+QVd^<JjXntB4wE_1Ik?pmFmp at fV?_RC(u$k}u`7S55WkDl^vUS*seNE$wbYFkw
zsJM<e6N#Eg{5+&Q?FJgd6f*uXb553!c%~RT(nklBm=Civ3CP@=MHXjvvXC~_q7fya
z{HS~FY`1&VUHniQWh!<PF$lYlMX;W|2!#|996^ncW4u{?cJ7qdTMAe8u?S#F$rgzn
zbM at A!^_dOSs9_#&E7d>>3W#z0VJ}_*i-_rS=&v;WSV*CFN6909Bzt-4>xb57efAEo
zPMdtP=O1`agG|HtzSvti%%Gf12p~JOVa9ECR%qH-8r$$qDcd;-^QKtz$|tc+4mnQi
z42--^R?Y4CL{10+51gWndsi=J$C6W-dNYY3FSrsuL(|xq_Z>PyA{U-z%FI-!hpW5s
z)Az?gu?s8*X5EL{^e5Y$=O%KfCh9z|%I4Xn%UR at o(YL0lx(%C}dAPF*h1O2uXzhlJ
zmF at fBaMP&O0X5?OJi)22uKeR|eQp`MLZ<%5(>cOorvwU=t~lQdmSyQ$otsL^<l1a$
zJ5xVU2moCI%-H#u3m>3J`ZdU1`Q+b(*;1+T>FHFZdJrPtT#e*xZEcM(Fi389o2kEI
zjx<Oc^Ry(f at oM4KMp25rj})Zoe=RX at PG49W$v<xRu5grhxQ1C>l**-e+-l#j7*6K!
zf_uh10exU8YQmOOc26_r(UZwc{#KPQCLtxI{jpVoq;x?_NXH)2PfCk+)%WojrV~Xa
z%QaL#T5|Ghrhg|Wl6&vT!{-o-&U48 at _F;-|%5Qoug8ANPF=F*5FdQO|q{e}=s%Goe
zUgYA~>Z5G8jQBP5x-I4uVLby!Mgq0RDuv5XTp)5&_6J$$RT=({e)c?39-s*~8B%cX
zUpnJmoigK at M`o19LZK)eVZkR(Dv?Pq=k+-FT3Al2uUd5mMf4-<5KntNxARjS!309}
zlg at g3L$CEu+}I2wzovx#koADEz3)adMS;AnrNWH_S~tF%tG7oAEHCHWo2`KjahNhE
zbxxHTjQ{-kbX1G)D+4_xkSBrI>TsK}<13&{Xi#q_34_6gZIv-TX5k&`p>z>iuowIl
z&D`vCGiofS!1|)Z-$?HgHHR`3dex5C at 3hp+DKh$X$Lw<v8K(;2E#O-d2F%HuW%q_&
z=P4b36ajGT)yq0N&XNy|DKm!X6=x`8K&U<w$ih2-H!{a3m|JYrJd)(zcZKlz at R>Zh
z?-!ogFw?f?anaALDlCK%9i95o00TpRwZ&jbbzPnLcsF<GZZp*DFJm0FsL+nSDe1fJ
za2#;IW4t)M?+92_GbuHo-Q3u<4Gj!nU*vr?aKJ5bA%gc$3C)p?=+mU;Q6{vVDwPD$
zr1g*=);tZ#kLxdfQ~ZsIY#shtwf!&;$dqr2d*UW^cOw)ZuPx+{Myx^|DPgkY`6psv
zLI=1-AVdC47OjFhLZ0c{eB!OKp97P5!%b;1QOs-fpm9mimr+dou}CKC{17IycJT_z
z#EJDKM^|H>o)f>AU(G$+NSN%(*6qR&9$7ba;|*Fqi`=@y8!-d|0S;=Q9+hm=0Y^wj
zfH)#8ZS`UxQ14L{AoW>P(j!0NU$s=va{Rp#0Z~-G3x1Xq?4~D*5X|<CY;mr^|A=%7
z#86ZW+!*0$Ah$3aN%^E>tHJSzAd`~d3Dw)1IXdDOSa&&55`B0DiqXji+`s!K4#liO
zohrUX^@y+Cd1sPfR1U85DCEDP9LkKUN<K_%%0WMQTG|Ay`l;!MQ!^z=za+_w at KlP@
z0PslzgRjm?5-Vp(uNwDk%CiW=xvVWR=-Tjr1)^6eHtU2a5(wR!LwUP#168(+v5D=U
z)!$8GtL0ZFeDUH1NXp314)5;nfGH*n6zJ5w(dr at We`jTdIX^$2*Up74&0$cFow?bI
z{KH$Q_u~9Kx1xe8MGSUbWVpK28S?MXJr<*Li=q`64{MG4eK|)~k2AIGz(nN#=O3U}
z94W!=axIxEcI9`nnJ(3X*cfVUK2I808q1MpCH~;#4g(j9TUC<RvuX9Q5K0^B2Nm at N
z1qIF1s_(F{7 at WQps247pb7e5e09C!ki8Hjw3BW2XIav9H0=!fjLZyQ774ibjdsbJ%
zk3KC1F)8)^M-lFWZ;DMOYa&;2c at m3ioX|JXQEA|B`ThI%+qrXAK9P~3f3mF_YmE0r
zy*)$PaNnYi15V;9bnD<i*1*7EZ|wE34n7*|Ck4;_y6GK68i!-$M at e?r5Wn3_AV~N`
z?k`t$o186_9+_j93hl1{5|yA_vY)Gu#lq%OmIg^KupU*}PIHzTw~-?Xdih?IvhvMe
z494a>|MUc`{fMb4?aTHov|*BBcmWygS>Z2OxF~&8k&;%8$iKtk;i!0$&$}Jft)NHA
z;&7=-|Fzi{c12}5RZPw;qt`C-DAri=C3=)(>Y_v?@ay+CH#h2F(S!Vda at f(eCB=-6
zs78sIP@|QZ!NVI^D1aB}$v^Lrhk{Y>_C(?CQ|R*BP$5;4>h0z at Dq;5}U_ydAE=ec{
zg~EBdxhtK432C;P>0s_9L53Ufmsr`_cDMW8SZY;iPrCs-#@<X7D)0l96~9lJS>b-{
z3B+5+EYTzZ-Kf0*SvCr*L^zO!wjb3fW#~szOlZ>Y*bsT-Ji{F<FdB7HmK|}+8D?@n
z at BhF(`szqS)i2CK?{(n>xCX`g5RycWngmecG&Bf<X#-73tGI*H$HDHnwY^Qo7Z1)K
zv8?#C!RSA3Z6n(GZ#s)L3O|l+n!T!{#ax2oHa9n0YVO-`woMOMCeLge*I454zyIT@
zea at Map-l9V7=GX at 7BA4Ytqgm#E005_ILK0enNF6Hn)SvKbXNlMXo<=i&$#Yav10_l
zdd_d{IOJple at hu?&`XL?V}35O49BY<IIo0rr8QV1oS45-vrR?`S#$NsCME5Uy42fR
zGNXFG>Vyp>GC`eIdWweR!7l_AOiCRD%_P(1m9;LDo$nD^BSSKAH9{V)M*ZMTR5`Ez
zXvBSvEe*u-)AMtclFn^&@6w at O1bpDsL_I5iA-h*;zx%9Y?8)afW9b^vzQ=@C#|X8T
zy%^R#O0zLCIMVakzKbRw1D{v*jMOK&)Z at m@&U`k<gX7Y+;P+cKvkKVcb%jAyu#TH#
z<P~I)fF<Vo=H_cAu*`rFc&1l>*PYf7SjW9pMHV3S8Xg|5v==UjiWP_}Y0fOL{>Rst
zn3x!P0J{nJvzJh)uG<Ui&C0QtUFIQ={_1I2ysy9bJa8ZfTNPzi8Cv1*=Kg1m$X4!#
zld)BP3I?_~5SC^m>r(9P${bZqu27YRXLn+urjNr580>kw$I|eTSuaH~yXozQW&8Fd
zzK~(&B3X1$C~rKKfWX$S$VDk9zaPfX6kw|Vy}=KEMv4fE8AmZ1rSBS|sw_!9)2x83
zo;)L0=%l at M#PlYjvsimeVUG#(jM>P`<0lwa!gb6+ywIyg^Yio58ZEXa_xAQKDYD!f
z0#>2vWPKpi0w*1y6siJ8Wo*@UNE(Sj7^DliJyA^Ih_beiz@;j2=3c*G)`+k9Y}f8q
ztC}9&Gt!qn;YL-y3v54^?c#M}5G5aO<r)P^3wrx&;DWGwN1I1&H}O~khxGF5n~I3{
z<-}M9!%-KegT6CEx&8@>=S%0~{ky|X%ddn+#v}*2Hyzn^hVg|M0l_-)_XO|fPG4M3
zIa^I!-X=vA#rG>_;oyIj>>l-gAdIKEqB6flhUP at rrubvd>D-AQmBo>zF=((k>PYr0
z2}97a_qaL&G2(7LT=7Igc>`T)NLGw?@5#OI+0ha(?9uy*sM+S4rc4Tqk)CTpfML<~
zUkl3Lwt2YDPOSO{249o?Df=ZI91dAo=%eWY2L)!uG-?-QA{dk>z*{wAvv8ulxxOBo
zo{sPpqnX}xGy<muSh!#ZH;d~vUn|-C?W6o97_6L)*hfg at qJt%9NI$n-OT*slX{S at K
zTgnaut8lzj!hF*wj9r*UST5PErr8(JdQD(x at 4jT8)*eBVn$^n?5kRvK+Dx^!A+v2h
z`%}G6;CnvC@{-$8-1*A(_<Pmp((3a7yr3q^$N~Y3ob%+*m_@%za^N_$Ig-*rtyh8n
z=LK*Wi$A2i)%x?f4RcQ5p2;2e9#dTGnyeO9|4w<61^=BTCHrIA*oKC<-suXy083{F
zcfO at ehK>)XORC4kZdv_U=L#aeM><FQAvFC|1{ZJfg}714$O&?bNw7!55OD9si1e}o
zYx<;t?3x-v0Bg$h1rP-}pwk9GHBnmrUEDJNtOO1Y!?JL&sK8Uw61CBN+BjwSRDN+|
z!_w8mBg^Zs`~xA2io`^1qgVvhkRAUAFc5s>M8$nnLmZ+*HTf@^$U`g`ke?1#F99uM
zdQ7nE4QJ|V0Ki#J+RXBFEGaXmLc$YzSZ}S+jad)7odfWjPMKZT79$7e#3Km_xYfL=
zryE)cd-rya3R_b1>W(nA-Tj|Fc%I at Nqx(D(`u#q<06xa+C!1L_4qI!-fxt6f@)F)C
zjAlcQ#t|(<`%U|erFW=MYGjowL8~0$yd^6kR!xYgEIDubsS5ojbx?tU?vy`-)9&gK
zQ7r%I^}NK at D~So1Ya2%og4W$q22(=o%LFgZx-%I-7r-HKp!0^6NOrOulhw-FI*N*n
zc=U7RwdEW?08$`OCSe%p=#D$T*odBll^oV^JSQgmtR(&=4F3xv<|OG>1|~Z8apsS}
z2(7C8Fh?}KIS&~?PasS+*@3bQARF;3Clde*&O4z-OG+Ve!Qx0*NW6pu*k4Y0MUYH&
zWsD)m0rvB;&bm at l-&a`tE~F3Junb18gv2gZ4BmRmIa%M^H@@39$t%)B$`u6Ux3`}a
z>E9bu<Vao$f?ChL+-xMA&Qj4$&GQ*J6$_4vS~zhmT3rk;$8czcb+-!>WhlD6am<9_
z9}Jnv(&FOBpgx3 at lCty~u$KSa#&Z4K>o39XBIZY4zN at X?zJ^UAXpsY-teK94n31A8
zHyJ*wGelT9+v at -lV)F#>5Fc_qhRjj19vch!bf)%fY^HzYXdN at 80MGRmZPGwbiRH@o
z$XYXCNaSzJwiDt%!$;OGm|70P<nH3Zw%R(rNx;A-e-U}gk^UAl+;T~6otD~j-|SL+
z>VdHRPXJfBf`iOSctBUis9kUG at U(<O2bt-b@*HHuLeA22PpVYK;aeWv+egx`t@*ug
z#n$L)tAz-xAuRqpMqq1ylGSt^J!VsvS4vii{EbGUQ;Ciw>?jYZQky}Fm*GH3ln;W{
z2~VhLXlf$+SG9x2?d{_O%zi7l`w at 6F<zCERiE6wzNnnuxjd6os<j<JgK*_pLb9r7~
z9%`{>37y_?Q!R$lO=jY2Y}HE at 5}SIys^Vd+?Ls~#nCzRM<-2{o#ene6MUqEwSM at OC
z^=Q6t{>^13G^K(62s$l>VS2I-<vvC7zy0m78uj-*$8?YjVj)Iilr9>jF(IBN<5I)7
zXrEbT_%M+Fh=EiciN*1)ZD3B}(&!j at MWL)^X;s>QC`+WTor1ko@?x-2+oFWLL!WAd
zf6Q4*(7LjN45sbIj+>3EeT4`1tQUOSDH=aV+CjScO31VDphvXAAI)#$P3VEC;esy?
zy$>pWGo<8Jn~Ph_07g`?JFpM}eF_Xh0C|H1YK_&VVYeAz&Tv!Gt(_h6PoI#(*(`J4
z_4PiS4dE$Iyn_|w=Rblg6_g|tvMY?u&PFLQqt4YA#)g+qO%L(4zFfHb?oCw6$QL4y
z?`a1MUvyge#qmBJEuGDc;J6AnldU6}C^V~dOaCVSbChg at Djuo?a`Xf-f7q(P at nOXs
zI`wW7)(ctk>9Tw5DUKVW9}K72Itr at Y9AZ&!o3{?0NDEU}PQE9T!r6y&K?cI&ahiiI
zOG-)Xle+Yn8jo%v$iI|_dkXpeu@?RJr;n|s#oxkbqdm&+P=3$74<>vB5u#zPS^iqx
zRs*j)V!)s=xg)v66ODkWK2TLV9*@M~El2YOgmiun;}3}&^3C1{lo^WqtAeJoG92LH
z`H}GPq^Y5S1oSZ~RLLNJl$d`c4jh+Yq8+q&1RizpYReipy1)U%m-XRLgWP817iGGl
zga<uLEuHjA5O}HMC<POXI;Xhj>H*MFNcTBt!nt at RZ@2t;50<F>zGt(@1^_Md6>+R3
zkZDzQ>HS+xezfk*css4*!K#@TS!29Z>S&$`AKvIjWh4zZ4OY4hYB+|V1mfFHY_483
zh+$X-l3bHwD^AEhL&TBe$1M!=W^dQ(tTu37zRb3cr2mFP1x<k1p1dttEiLIEj#=GY
zt)I*aYCj*1nBV07rly<jBxhM-#!Hh<n}b+)76e{jka=1CO6MZ}0OBEf+mfC1W6Tqc
zp&cq=Wc(GRGQ*~)AiXZN`SK!Va2 at oWS~-Nv2W4M9t<r(WW8hLs2xau0O`C`-{GzK`
z7Ahq%_Cy{Py`bc5zg&Tad|n#rwSEIZ#h%8DV__06hjfp>i=xLQaj$251CDJvu3uI6
z0YcLnp_tDCiuxAu(rCPnx`QqcL%z$w at 3X{(jgZVaq7_AXYmV;&nqNo+R*OS-RrYm%
z4xWvCnmzclkH%Dlz=T|tv44ki at zxA1e1H-*mz(uQKZAOoZWS$_iQoYs=A?>V58SUH
zy at Ni_tJnCLRW;%YmzMG(WS?E`j*y%D0nE`1Ndqyt)v<M!yIQp+OoJjO-oxM9cADe5
zBk&k9RDd^!O6#G0rdX3lRuZ2UTiWh-?c-6g8xCA*kw`4gMp|413#rTTFc#Zw1IO28
z<}ock2+shc5Cgkqy}gc;10h%l*8+#f_kMIF{Hi2}espmfM6aA+=iYr*tuOJ*@1 at o@
zzt)kT1uiw=SAO2R0~@p+F#ygf9D2bMg{tv8lf1+hY^j4<>O;Q*rP?m&$>@=En_ahy
z_LN>k&ze&PMNK)sh_Ec57`ileGwMHH?LR(m=<xg1A at ByHa*P988rZfTvf3`<>Q9Rf
z9tCKb2yJhS$lJJm&DXZ6%T|}AWkg1if8F)=aVSooNcV}SWu`s#s3|oxaGD~%AL2=d
zUfIb}D)&@3 at KrJs9RXtwrBxX2PPzm1SW)Ywzv*T|Y;v=}#ld4y&8N)RZ{n(}+{ov_
zz0|ucPBt$nUomwB4$JKH+RT8(Bk5(!tZstx4FlZ7Oy{K!0ZD*z$R`h{3#P49woBm{
zu9Qqa%!d#y at 1NcgD-gM`j|@qDV#+lAJbEa9sDL~CcYTnh4TII-DVij|v7W;0c#n)2
zW_Cvh4ag0LWo11;g7Nk(t&64Ak7E0U_v<D^ui$ww3>K=2nncEd5rvZJ-N;pFlAa<~
zs^Ro-br%&LQZ~+OlGQYB`KQ7H^NIOnyzU#CHCO29&~Mu^4z;$fS at 9x?Z&aRxL3`#=
zs5wz<7UdmZH@)=S3%-8+YJUi(P;LSUCcJC9{i`#Z7R>@yJ2lhjWajS3FKWV>I*5|N
za{Fycu(f{w2QG<_x+QZoJuf+qjCyj}%fqDF+Db}8Hl|$GAMDsd)Wb^o=1!D(pivv(
zq}+^n$zxMC_$W*(&5LV>g^2Mp;%}nlbo!!|RDMCay?AMYkS5VJXu8c8oOnb&tNPMM
z#P95}Fksc>!@|uwl6FC(S}<h%d<gD-s2HL1SDI(;EF)&}!#jV~NixuSWRNJ|`gdX-
zouS0YrTO`#`SknxvmqtR0A<TV{k_nXyMzL^6=>##_t4L^GrvSes#JI#C4wzqhO+;~
zIMt64-Q{X?>y4N!FT}ZTbdgVH>UPY)c}NWGa>L9$Je|y+v)8kgZ1+z2NFd8oCL4h?
zY97uwRNyB at 1q;Wm5b-=(3Y~4~{XhaEqY{hrDn;tly;y&+swT5A+tN>NN_b;Q7}1v`
z=sz4qiKt4?YT`zCwT`;(%#6tKpc-!cVjnCFi%oic;U<EBb0&hujuq2 at U;WAZN-Rr`
zvVRr{38YfPhD5<cH@>Lbl%69!WRR0sIT1D9BoRaf?xNI=FfA+yw_<4B*(?Rz)7au-
zJfKO at BtP=q$1|adOjw{ic79v*E5<zeL6i$4cl0>(xBFk14;_bIH7}VksN_;?((50=
zws?D~NlE^RBs}Nr^9wy8WQxxZ;xv)*u34p0h^;%=^~Z4yWi+8;SDWh1K-V7~P0a$n
zi=)hToJ2R>g$Oqgr|UmHLEZOeoP4uI|D6;7f)2sSzAmJve|c9G2`Z+{r}Gxi&d=+i
zGKS^91sOy%R&T^oUKoVS<|Pd9mYG!P+W7=-YPzi%GEO|!QFyUs`gk=KqoKAk3Pa{Q
z-u4VUhuoti%wC{(=t(w{qK3}G>Rl$qep7n`_!$yHLHSWX3YiC4qESZOs2|hmD-1E)
z&cJfBEIIenq;kf(^4wuxYf;-kI9WE&@{gY2qaja~8-1`COtDbDM2j4V0`^5=Ru_?o
zpmg~Cy+7Cv+0y7A(c12et~>V&%B+6MALk39{noUZ`9Z%d<(1a<rbdQ0KgDQW+R(3W
z#hE!ZAMICkZ$A&Wy-86iRr+Y0HiAT$`n-h}^CRQqL`Li4i2Yi+{zN84Le%UlsrEw}
zjGu+?mY7#2eV52y6+iwwqB+&M_Z%@OLZ2;`AT2V7bf~nACe)b79Ntt8CORyxj2%1k
zE^tk7evs0mWJg}dF#G8x=Nela__zz5H~jM&Vr}fCb?>SG0bd^JEFQ8{>aRlVndV^O
zG{y-qcK@|9eOjTtbt+Oo3<E0`jM>QjmHfs`CB4#o;O7wQWs|YLL|_=|7 at Swha{k^h
zA6zh at yWyibTh=J-kVj{5sNkk`4O<Ph9p1Ux_M)}lg1$c_9e44<;76vX*@Na<1SLbJ
z6C>G|O++a}%~&AE=A_K+@@{#ZY}*1-s07_6YS%fV9%4>rwb}aUdo2${e;51XX9Xrq
z6d&#sCPkLO%l6!*PD9 at aL(bGssLGm8d8w#}Cx=3&$N>>970GepM}NhuV-YnXw3;7{
zrOx8W5~6yVHnc#h%6}>7oMBiv55o)`>f!76>Ch<4Dy+Gf6I`3LdB*Tb=-OLh>&H!G
z9jXLPYS@%Mpu;5;G46UP- at W+w#jW)=&%vyJwqa#{^MYQ*t^d%2M{&un{>M*U?=0?~
zTHImA(MYrpxIex`Vu at pPKFI<>r|~E0&LBE^gbAszPPSO{M_)6cT9!h`m?k#ctE5c?
zb*^(7uX4?sh2qm6N}!F8t5vz6-x?9>_e<Vq-R|tjZ(3aPEdT2Lw)j&pVe<1pKf at 5#
zx~p=A*q1mk6ogrFU^sD*y`CVFUVq~LaGG^ob!gw~Msvd<<|v75`tueTFu`8$LKGnv
zw{rZ?ndpBXakM#I8ob%`(K^_hoi<<MPb7Xg9g_LFpQe^HnF{;j7pG0jfC<gH$IJ*#
zSSB8y-o0LW6Svb-Dy)g^Q}a|TW at Lh=Hcxx5#yo8Ye%dXL-JZ at hRW8;}>4k8;`dP at 6
z^Of*OMg*Y<#}Eqq2rE}H-zLJ~av8`O*gSdRZdDD3&rU&Hasw};Sm#9GZ#y(TLUepA
zhiJJUd`ZJ2Z7`0vP)FagQuo9kw2~Yy_+rWE_K%I>qhnwsFh9Pf1uUgZoqp%|T}xHl
z1OAV7<6q=2iH(3(Z!3 at 7y-toxBNl3t{{)9Nb<p&9r57pi?&bnjUpg)Y$>ZWQyX7ku
zNQy|w$b#@uBtLe4`-T+V+m*a<7{!wLZK2I4Uif)9Wz(w<#LGjFQ5h4HMJHPu7K9$p
z#gn^TqKDdKxVj6wm;A<%7uZ at eNLOw?c&l2r<X-sET=|NjZYK@%51|pLW$oj};-i31
zo^!3jza}|3*p#I26QM~CB9Z&3)#P6(=-X<RX#MgK4L70Ii^99Bm|k7HKR38s&!ngn
zH0fXNzNx$;S?m<WYYRm@#k`(gj&*1!RXr36^}A^gjTaXWjCE*4?mc|qyT98RU2>UT
zdwKbz;wYoVKaeC|7PA|TqWoUjcPr&NcjLuN-{prk!n-u%h|3vjN=l-}duf{9-4x0m
zRFhi~>OUl%1mvCYhUJI*LxJp%jGy<)zfRg*)`;Ige%aKm(r+uUp-Bb`AGX%?!mG@!
zOGPD_`k1K^)e!0MP?Jb<r at hDZ;4!o+D;GaRsoaZwT7%+(LFykECalYLHIaoZs98fq
z(x?!iGHu#TRX1zMGw!8D6 at VMT8a0z_oJ3FHlx~UhX=Oo=6<yL&C)&it&BCjdz|k+_
zOVr`N#};`~-lg|^wA*X2JuYkh0d2&0V!MdOmvr&!*!a(VfFFT_k%`pZjF=roDP4o<
zBb$l`Mlp|F^1b;RdVg03+*hjfHrOkvi+9v<=@-biCvxSzo&5)WCb#PyD}@G}-+-t*
zY7i<ge=OJN3h&EXyu|wBx7h7DFD&)P?E!z`A#8MMe)F8RT*mQJFrury<@WEO(`JUp
zN}TY4)p#e7#1(M6$DNFd(|l4`hu-u-cvCozml-m4?uXzxTN!WI({j6T=pX00*>LC~
zJ`24#Ubc9axoN>STBCdn+Sn;M92vul$*)w-p4^FYMP=C20!xX7Uj4SYg^+R!p^5eB
zf!&b%m>^raoQ5dxzRX#%>kkK8mQ5BK;Yp1G->F?UY?|2!maMt>7Y*g%N=E5!$B!CM
z#v>f}{zCAne2HUUZJM5J1BJ_iQH8+kWhkqbS}gg`qBz;l61GTE5{!I%<Zl}PRzv7)
zEf{+(X1KGDZgbE%cam5+4WidSC=^ZOc5Uln!?o3QFH~*^B8)pz?{_?oKNV3-w?E(=
zceLJ#D6OC6vUY*;?Bk at YTQrdE(4nKFBOw9iw(Fn3Ix!JqQzx`xoME;9;spo&4RoKU
z1{$Z%N`(JP-O_w((<NuEH!=Upe5lwxSz^mB>Mc01Kv at vSphVnIv8ULNF*O_SdMNK3
z1u$Tw9(+Xm<DGiARsGiA{|ad!)OrSH)~!n;#mx^&LNIH at JI^mMzpGL!&2FegZnwp|
z at j?UNybPZdYUR=GE(y|ljqYK(TR#sKRl`J~krH|xCSxcTp5QE=tbmM+NvF<wmMy??
zw4&HjS at B%fZw>QD&bR7J!;N&-{OnJ`=-EkVlg`mN4mYB=@f3mGqxTf|r-T6^H5Hfa
z<%h}y1xeHE>O?@!db>MS*0`1XA-k^ce1C4)i<&&P&&fRqW^UIT&(z-kC3*I!Dz5Ue
zz&F=rXk1RRR3amsptjgWF-1j8jRhk(JwihsK++GnY2bFb6<k$OcE4b&T9_}KhyaD+
zHQSt}xypGB0qK{Yy|YV{8Z-o-_>(w>Cm|LpjQGZp*_LAM(_bF~X+J`5ztZGhPCbOT
zJe+2*exdsj;^Q>E=#TAjcl+#izhyCO`eBW*@#Ms$FKqWF!9}FB?b_0A#*@7LzQ)JV
z<HAeVWn=c}RrG5tSDex=w`rr8j+=8Gr|C|Y1RCGRHzY>U7a47&BMT^+l#;RNc+Jt&
zE1I-|x2)~AhaIwuE7Yz`5n~PahNbLYV_O_9dr;i=t6>KzwnvK>HS*SG$6W__ip<As
zmJ>U0b%mU9D|3?ATvo`p%uPL5Ut+$-TeJb%F-P1dyy>NPuVcNgeA_K*9Sf5NRT$%~
zPFV%<Su|iyfw<YdQG%1cD=IYNp~vPl;iYvW;j(I~p9P!jI8iD6#Uhyo727YY9u(Qe
zrsrZ^%I~@P%UhnjqN0=6SZhgHDge%P72)3zZ$`=g9Gi#-!7 at E@<#yRx57wb=9g+72
z;xXca`__9E!mLCXj>irU1lpY2(z%A|F8e;mQGBXqyXBHwb+F~(3cnZH7nfGh&DFL;
zlhBDL<X&r)=eN5 at _xaQ+CI;UoQ!yzy<pO<#?zh6HmxB$1Ws8J3W5sq$YiL8iJFe+Y
z!;4=orEH8Evrr7o=?l4Ag4%JAQN=O at kuHdv*^<4`Lm(2f4*cmp_K%`wC#EM!hDj|$
z167b*g_b6G|4u9uav5dsh3qzCb{~cAK7Vo!wiOQ4pXIf7%$L0Ln_o6H6f7c=)yH<s
zNlU>TCt^99f@*CDn<AuYv0sRB{O8)0fPpv5kW!b-<`<<6hcL{_gG2!-%pg`@z7Tc8
zCIX%ElrbmlhDPiPue-mNs at YSowPJpm#9&pl5|hY3mXI!MMpHzVaYD%#Ert4EX=m-m
zoKv!Xkw;<K>h?+_L5 at r)AP>8*o2e~|+T=Gm at 3Z@!r2Qn8dk1Q!_)Iiu{%ew6fFc%b
zaWpi3+}WyN6$+Tw7jZ)ah;L>CiTPCm!Wg}^0$%5?1wkyzpI307dAzeU=x%$=$eJb-
zw-~iVpzI34>rO9&ql at W9o%-RUjp at TI=pa|EyyQZugLJ8blC~Mg5rc^tR^|iAWD}3G
zxKzmT-qhU)x057yIT5}{l8L3bwDFivv9*c~onJNIb()xM at L7C1M!6=<ABn4SFaux4
z(Cl@>{+E|lZw~2J^D0KlRTh7Vrg*uaDL8wl5TMASoRlXsyn9O{K4Vk=l;%d>EXqqQ
zoU*F;FQ!#Wl at qmkN>IAO$#o4Ml6i2{G45G9N7j~669+;3Rt(ih*3}eEcV}b%HU{Iy
zobarj^bKFVNL8{RL#cqLz9{6>l&42?V$Un{8B{UFl1z6qABOf at P>pHKDzjDzWBCc)
zQuF&M=}v}R1-4Mr8Ryt0*LM($YN+n!;Q$L(or_o`NxIyx8X1w5S?nY^7rNh8!5sd~
zv726S%Fhqbtk-dkNpd19=b^&fhGLrx1mbo*O)m3&s6{6Og0;{c&v~<q07aQrjuyhZ
zZ3IPZZmjvO7eiSrCwK~O`F^=E^g%K__h{^F>?3JbSJSuf*VeVD<t#s=1j%3_YM~M6
z%=iJAtiaX6M(wn!IPtTw+mjwIP<T8E4Ciu0pv#HaY;OJCP#R%r5APwo7f;P=VpY`e
zBBn$8PrIo;cYY#6HZmJ3V7Vf~kp>rBFr`w2=^MXLN|&kc#SV8{8yb7n%{>%D6hEc+
zF9CNKQbZ%QrsQTrMakUnqjHY;&dbw^w<#06l{CPxkUpB%e!J^_cFmmSb#5UROP22@
zkkR4pYr~?LPGXs2Ll^rlpQptgW~WP at W%ah-6=~QG-8N+`muBxHwqn8Ea!_qt2B<q<
zx)Iws^VVKff^@?SYATo%Q{n_th>%&-_=qnl at k&Q^R_8cF-u{KrQ^T{eDtuQ)OoYkE
zKd54b$(a$5nF1SK#q_upZ*`DR3Uf*eNChoYHl?!;?0%4r at UvKQetKab<VDo~5;UMN
zhU*~;NU5o1RaI3LR|E3KzsuI>gS$Kkbk9AO=q%;|q^{=S>`2}$vs{X5l8aT*sExTf
z+LiADd%nCHD7Mo6I_oO2kj0;RfiM2{(mWH7-yj1HjU#xaJ{UBZ!cm8n>$W#E)`aSc
zE=d~BO7ui;6x$)a4rFw{B$lND!rjA%HO*7xY96jE8L}(~1tDvD;AjS?F6bG+nL0i>
zX|cb7CL-*4^j7=v3Us72p`kb(GBJ`6wMrT*i|Rzlwe^IAT`)Em6a34R)bcLEGCsK%
zj-|?P<!zIrwl%Zt0JoH-CZO^M&HItQWkSGm2M?1&8RfGg8vz<Jz!V7#a at 7(!`R5WF
zN6X#+o<u-Ez{ZfP_mfLIT2N&V>_<>s5GiHa(rv~KBiMsOA43GDr+ at z(8o*EvVl??;
z1`Ag;%{h7gJz+U10k9S3|E{o~L55)dJh+bE{}Pu<C=`%!^jV{G)#M={VTh5A!2Ks6
zhDp)6SZ>fS(Bjv>>wO|}_Df@?)eDl#Dg|bZlxYtJ_h8M!Uk)B1E!9q_)ZBDE1;k_`
zV^DH+-kSUeh&1d+k5f7hDzL3+kNxje^W~BBovn)OS`0bOHb*ja>+Q&{udj)3iC9*~
zf%ikLO#5FK2KG;YR1g_Ws~LVko6#vZj9Okc75V#}LATx4OWXJr%wv3!lNT0#KdleL
zV03qLTTXWwv37cI_iU_-!5NS*!*LmKUS$wmNJt>*ph(gN7A^Kq`e at _eu9GyD+&f|%
z{;2R~X(DLl-+Vh>YI!=wmJ1C-UuvcfRrtt?V}&F7r1r~dmm6b%ZjTd6{|Rkx@$y8}
zCx%#PboSD>3nNUcFY+;rlON+SrjZk&;Xld9!|-uMMv-B1<Z`dWFczPkyh$lQnX<;0
z07PF2HGn=5;0~~{vCUzWFOs7%^phCnL92;Mhea_Y2^}3B1363n^GIdcdaJTg at dsZ@
zs3VfF``&lQPi60|=NbNa-NJDwvXg({D%GwcNSKN7rD&Bk8q4RL>n-F)urro8LO}`8
zm_7rb0TjN1(Ai*=mouG<?}+BQUove>d%zOA3euXn{?@Uq=yCV-09Y(28Wv+N7Xtcp
z{OhnBPgp(KN}?hrHw}Z+-g`ZtB1X<<%3Urzz8by9Fn+klTMd3D2z_HoYy1^WUMMxT
zLPCEr46NrQ&)OSr- at kbRUE;Tt?Pqlr%f;PZhSzb6eQB!V;avCo4-xw%SVpgC<TWD%
zDv_t#Pcj-;PN}V4EVW2qPA&RAo#VP<y+3NsA5#b%3ZHsn{nM3}BxW!699eCEUr?Y<
zAE(9RaOB4r$d7)MY&?(5vx(=%1}_!xK*6*URk|{O)x$?~X>Ki at zhRaSULQ;~1MVOf
zp*dH2Hf0S)`Cvx*YUIaL33{L7UK|$goEi?M at IY+7(Md8`C`IV~TLeGTQ9fnH`{p3^
zD;|MV=Uc|2-xJY_Hspr+BlPs~ilgUT5}<8Uu5!a_!$NYupNBtH{Chu4JTVu+DWe6f
zGOA<~Z?xmYSg4;D0Rz_qinx!BF#0arA47uYBkfOhGN&>43aQAWXid;=)c5|+3m{RP
zEVtf!;{=3|<xf_R-d|<RInG}DYvN(kefK)LUI=_R&BRh)xW{b2E2CMx!E3`!&2U2g
z;{I{Zk9>4WXLUc7L)zC4kJ at jIU=L~-MoitTW7qS^U__QpS2wo(PYxX{e9xLR9PD{|
zc%8n(D}Sqn>CiygE(o)YZ<p<hJkeh5Nd71=g<`LZ_mE+ho%||2c$i{xY>xcL2_fDj
zz|tsTzalJ|ED`+&KiS9~6>EOvN&4+hJ8sszB(`rNJ8WBa+rk;+;G)RixrZGOM!ac-
zYKE+q^$1dUXFsF0AR85}#zH0e6B_h;_41}-J|xeZjdP}z{5UA}Xpn_}>4!4vH^WR#
zMx at sy3*#nBChc(g1jVDcivT18?e**^xvrqngRa$hCf37+Xj9R^4<iOoig`l`%{C{v
z7!3U$^Ap>6{>AWE6~4eTTg~4D7UJ;K%z($6Ssoj~E|!hb4EaMPG=RyB6Q#w6#j$6p
z#$kI{8BW_ at _2Yd{ckoWa2rq+7WbQ#N6&W!Am|m5)d@&O9=1JyeolI1b`UiSN?In<(
zwi49bSop46kk^uRMEtZe)|M!IDb+!<X=nH$mnAznT+OETR6hIVB~NCN{Ff+{XeOvS
zT9`;r73}D%^dm$6&L@#pEKf5~jFC|lr{500N?qx@=lo*o+;!zjzyA8GWe2`%G`E7<
z at 5V<II%wZm19*998PhM3GW~W~v)?uLinKCHmLPM9gco{Xzniz%B>>bXuPnW&>)EN<
z{Ew64>raa6PyP^|<JN4a!;gb0h;j-yHjh=LvUa^g7T~C!&W4xbxPM{0WU?9Q5NVlb
zoKp$#8C+fcMjqPyp=yW|rE0}c3~ovEDk(_7qxmsW((Y at _i&3TDZ)<X)Sq~B&tSIYN
zWcG`iv=N?p{E6PJPe)e$NSIr>QoYz8&|=SIe7Ui>d>C*_?|<DL;dCBRE_rn<$NeXO
zV1!C7^32xpW|+?Z{LlM6&s+aLH?c;JQ--new+m;aV~>9sZX{`|g-uj?SwB)0yR*Md
z(&%?saD9}rE{Dgh#2_=c82zxC=OEF1A at 6$y=AMNt-qO_ at o(k)Fo71>!H9HL>P~L1W
z-zvVB>h{8JF}dP9 at H>r|(KzUD5kEC(bo8>8+(pCvL)9;c%Q|}D!J;2|$3QF&=y`s5
zHb{RK4Pq_<97{uMCtg-%1mSeiz4Tq&Lqz|u3&*f1V*<Ty{iDNnZ-%2 at hm}H)2UTp`
zg_yYofBrRA1kLQR%k5Dnz5AUvzW(z_!^c5l!9H2g;PupY3_mG4DsQs*R>S^iH<+2d
zD`vMGp4n(zD)(mv4(Gt8`Q>tajOR|n!X_aQ>PzB-<_C<+RPV^e=GC&TXMriWYe!g(
zhy5>C%qreKL<axxpbPBE at oT~7G>&-YMIsbi>9aZb`pKZvNWp~TRv5va?-nMm4mm!n
zX^ugHJK2Y;_XhTk{|NC_A^LJG(8;J`y2iN%oPey+z>Nq%R*hvZG|oVT8Qh~DLc>4i
zJ%4JnW=`Wf!h=hyAg;UB>7yY(ldzuxE2WwY%Foa}L?Q#`igRReZAUtY1=?2mKKf91
zLDu~ZJBsnx)$z+etR1;rE;B at oy+&@RCDLiz<S#v05uE2iEz9{yWQ~yU@|(HcxR8jh
zSee7SN6Wgu;aNB-ccJ5@{V}?Fv*<%jj?&vpveb6y3n4DXkKg+f{tVXoNKgk!U!o_(
zbLIZVkwY`^)aiWEp)-Z=u5y_h>l~Qo%m==(Mpt)-7aCd0`n{CG1f#V|t(Dor0M8v8
zS4&2&n8Mr at -n>7Z(zh`lwWNW-EN$6nyZqX4Py8|5>KA?X1?BAli`XL!2}IB9USh-J
zOr6dz-?nCX+4~k!&n3%egK-|kGHQ+8Z#Q0fJm4QDKb7Lm5{zPCj1nroMJzv;-k4gt
z%ev+eD<b6WA|>~-Yd;oWc58s*3rP~?LmxD<!cp%^q;uuutf%lyALwXyISp}(`G^cl
zTP`y$x1Jr2l-z2PGsI00E<jx9Ed~-NHMHwF^n_meDA~q>dDGcmBkQ#V at M9q1GD!PD
z+<9yM9pd!Gj8Y7ynbF#jvUpV#lfJK4SH)Sf)kIEs{<yny-P)-IN>PSIZqlUU^X-(y
zy``)>V&d~xHB5X at P|<eJe9HNv-Mfxg_H&>1<$u`gXAkk~;=Oc5a%(ZI#M^gZ;pf5G
z7?R*+)-g&o01)Ok$&f!a`jBF3VS+ at _PnM?G#rC$h#DcXkg#rW)fZIDVFlDEJJTn+`
z>L6&cW<LDzpEF(>6Pe9|zkc=~W+g_`oc=AuleC^>5%O<M=^^OHJF7uGlJdm1Dnvse
z2lTl-^QLM)WQa2Zekn$Ilzbwv2H8J70hS#50XR@~0$X%CE9alD9)JI9{TICVABjxQ
z4Z!MTQAk9KTcwqM3XIBH5z3#chm`(do^Bx4*d8#QU0i^#3^lbXtoYYQ@!xOx-`_kE
zkz6!s1FEP%*TeF;p)yzRa*K_jvF#pxTOfo2qi!=N0IXBwajS0ucmOoGB+;v>oT~r-
z6$3w$Dd7nT1VEfE)vH05#5a$NNp|+mgNNbImTvMY8?-VgRBW7hahSAIV&GASZhC=U
zf^forUr;MUY^T>XBQx<-u!Ey6m1!k4|JWjGFquga!esF4x!qY4lj1}JOg=GNzpTs6
zsMM&1UwD)!b<pAtGC at A9L^A#l(J{&=QW-OZ2JSYG>6?w`z5?E3$tJ at Qk>|#%eH{fn
zeAk&2mI`c6k8<kXdp*7uG>Q;Y9UVB7U!0h}y}ot$zPlQrdZ9GId()QuRH4`o3587Y
z8u5^+8pzQ95%iqZu at S>N&RY0H#M(hKAL7}0*xga+k#l%e<GkQZJ=O+oTx)%u_{G8=
zdbsU#LY*#fJ6|lDxVX4RGM{=9R6#QTm5N4bG}H5A!M4-k?*sT2d4b3Y-|DF1s00&S
zfh{H`MglX)xhdUfdM{vUy5QlehD9D_+6~ggyZE8PRQRb>?I-K|%njJw at pSUG`vtEB
zLQKwgb63fv<ERVkpZ6VfEm}st%goI1SK;}7Atiie-Ec0SSZkQ&*?obX`ba}HhGn8)
zFU==!9`TVH;^ojj`u#g5FplQGvAz=i`PHyMx$S#a)L`uu-*IGss`I;@ckSVZVvQ<m
zf8QQ3=xa2$4}3i~Pn^R~QU!1myxZHAYSZ$^)5vDqRwrbaHED6oM*YbQoE^7!mwd0$
zt at nQ)r=5HnB;B+S&JakUwkq@(@>rkdJu7FcD4=wjGyRSEes{>WsXUDeqw}J?iR*F`
zbRYi0Vu|7b9tACCu${zD&&Cj)M%Q5BOP{A5f*rq?asB6umvH?Z;=~I=goo-t^X|{h
zT|HE;;_p+Hz1IJ7Pc(*z4=OF=CdLzn2 at fIdxH?5dHGrwI`+KIse<Xc=UikfMt at -?g
zEiZY|^zM-eo+&9v<2-onN-eSrcALRxdR}C0jLH!3AK*EMAbRl8j{F{=ZzZ@$`d<Q^
z#P3NdFiIV{N_yo>?L-L+1{voHG<>&tc9T`QN8qWz${$js at 1H^ciothBuLbA(HFe)8
zfW-hrX=421WKf|-M*39BJcecAqZ)!DGZZwoQqrB^eZ`q7oya&V49xf_mq at hO-6>6T
z8;c2n<84<yV?JJ)sq;xwsh7&5vbP1Jb*Nsy<X#156tIDQg}|1PWJ at l@ITN>9+bRum
z%&DwPyZ468%%6DCC6VaR$YW*u3Z-%ap>Z`AYoliD|HIT<g|*d1?V@;~IJ9VRFYXrH
zT?>UGEl$w@#U;4AyGx-!DHPY@?oiyVxI3Kn{r^7u**D2m@~q5E8FRem0^EOrGj6Zw
z5I6Te1Gm}=dm_V$c=K at BJSp(Y;s||XK{UAxF2HE4H<s at U>-a)cpw3t~z%xkOfo+(}
z3}<g(g-2DHzUQ&vV`XPGj$6$b at Mk{jauyOBfk5fvvxzK%pIm{bw!h~h&OS&S8z8HZ
zB!Yh)*w>$U<ftzFm~!=Ip0#LxpE!)r;C5my5#lHpC5-EWxyVn;d?j|kxQTq;G-(Cc
zok?pTF`3tc1RMe=tvI)rt){r+|1gM190Jjj@&Do4gEvUW*jW0F{snt<>6D at qy!)5H
zpJAhHBYz=3zu~nM^|jPGqfNLHXl^cWL-lAy<SzQW_zy(0*n6-SL(M3^gS2h34;-iA
zH`b#At*hkr)A#p!0%Z#)f9+YX;hrkktB6jV-v1t8OEAoDOQuBw21MtRs at GzY^~;f2
zZCEu@`G`27VdN3Q0m1m?FAIYc7JQU-E|rILGj3qF=k$!h7Xb~D9;4yMwNwGPeTe4w
zq+<pBPiwchAz#o5 at -5e4_JD8uxYZ`suU^v)EPdw1C2*S4PbH_rX8XwHIE=GLWfZr#
zlbuI##q>&kAA9O$iB^YD;kvnnTZ7R0ZnBxA(QA}`vO2fM!Xb|yDCn8yhwNj9 at Ax;C
zell9_qJ{(KWr<9dlRObip-^zggl|drHfgl%O~bJx$j1)F%{teKMW!CMM4T|_+8B6B
zcLISD(`ApI!!00J9qyl^CT27S-dveEf}XRMY^S&l{3cep&NUKffv|gku23sc^hxOZ
zjgx)TPD*U<w>iCqO<=T%rP~FY-0ZnBgQ5sR`H;{gGfG%}_yAUqPQ`EO0r{VTRz=af
z0;(kwBdBr2*XwVnF}kCgz**DzkY%M(H)=<TThwkG;OvW_23%7KV7<A?NRgz}Ifi+b
z+W{(1-{%jBjjhiG%NTIP1Bv$^Xg}Av7Bwo=WW-?cPbGN_BYn{hQ`o=T%^RO2iPNB=
z+C_<Dey1r^6xV1%A8c4XAA5OW%__fvFpx#0Z#>P26KhSA=JYn?%T1P9-M%Qe(b-&r
zR4}5z))`NrK;%y$A9!S1v|tcsAZvxGOv$0clbZxg4lDSHtFfyiu==G0ITFr3`L*Y>
zK%Vl at Uuc#x`GJwas=UPc0G?oYQJj^bz{GA}Fo^#SUJq=0VGH!h7KA5rw&6ln(@DQJ
z%MpbTkB?62H8ZS4-kHf(g^geR085_ at ycIzt;~MFr0g3fUVTE{TC&}H6%5!4NPUHaU
zxM*1#=b^=8FHiCWYlO%4Q_I$k(|!rcL7wx_TTQ%<gIfrqg{(kRI|D~Iwi!L~Hn125
z%`=bCp4n8iW)81yjh$(fz2eN0R)ceLF@&*o;>l?pB~Evn*~(|X(toNmZY-4BlCgG3
ze~darJF&$b*!!h)(PKv{){}Af$DjBVN|$GTf?riDAivd|`Vx|p?5iqWA9zKJ9TA7M
zPIqX4<*^=v==jk3eXTKvySkV24ZJkIo1=(+#jO5nuFKno3b5ORC?_|?art|Bx0q02
zf%Pq-fF=9{tr+1y9JXi$=Pamh@{K>vluZK3-YR>w>r{|6RI8jRdwro^1{O`pk^-B`
zlej<p;wP{hjt&Qz5x!fTXz8=%Ce|DGgcWjhw~6Kpxc6(MGu>TK5H??CW1#4;T~xU6
zKnT>UGZBUU1fVc<XTBYvH0b(9bDngWcG=rQR`h9<g>&r|_(qi77`$WlO@=|N%E|xE
z9NTy;^9MM9)R~yy_IN{<ifi0tBGXr@`8}xeQ$zc|5gcwb4s|gMG%hBeF$40^y@(l>
z(M=7CoPt7|vnyg^lq$&nDbu2~1{b%v0%_b^);1Q<{MA#B`hyQq2*3>;B8bOeUP)aG
zl!KvV#hFyjAF>WbGfN at __SkT}MUr(#N(`i{f}yTE??{mb at NqDSkaw+r4xS6gfY)U)
zlP8Hr0eqe#3kRmBuj~QDuZ7*18&7cv;%F{D>7D at Z>8j~;RfS}7Ah?uV<4CEXfq>N+
zrUn3^Z-SNY;{u8-0e)&a*r{n3SIb_$k$O`DZIi*+3qjl4wA4C+67`o?{V*d`N+Be`
z5=oG8(<||Wte+FW<>@1fvfO79a$*DD=p$A!T4N3pZ^yHEVm}C<&^j;hM5_Wss_<pp
zHTm%KE5T#VW_}S;5n(3xF^Va8gZ7a&Wv{RofYX#dMGt3VVY9E-c(U0S;X78Vko4`l
zP6aCnZ`$k3N_0LLV%l}8a5y-hEjP*(FmTI<jWXH(b&nPrDEq4$llWNB{;yT#<-Iq$
z{GM#0aMx8-k&PhxKpE6BNQ}D@{ye}IfjyMcV|{%Un#CeHtkfxA;;{f)3AKEKN;~O!
z9tCKrKC)OG+E^sXi|)U=jv-eHJ{P*}6xTzhRBXCy+s)SY+vFS0m9x|RseC#;{$#(y
z+DAp7$e2C6W*Js|{5$gV{4?3Hl+*43IsM7{e14m}-#psMy3=sQdsNDd#_kbG=jAS%
zHSis<0nY=WSctN;gkZO`h=dwP&>rR>C35JfFX9-YFC!Ib at U6j)Q};E_x%dChaACm{
zN)g%S;GB4~h(n?nVRy&G)K(`E6|Z;@`as{Lehgs7Z<r?{{|K9l942+k at qmTgFjtNO
z*@u>x3ad<rf1n_C9~zM_7SSVkEHT1&i<ePcz-gdM>kK5`ILRyc%Ih#%{l^m3E7$`(
zU5Yio_o_mPd7z;2Ih+(gm!gMbJ~S4Uj>V%yD-gCFpcpVr!}f%{-wg5TiGF+gZzKns
z`&(~eSJrvm`ZDAB4^%r^t~zjBq9as&MC%lyXgXJMnX3^L`O1wc7z>y16S#A-{F9Va
zuzWtVVl at nvOKqg0v5fvjZ-9np{QW6#F62(aPcCyBnq_NeW!U|n=4QxuTuJY)(Y{%X
z_%nI%I)s;u0$AL%Q~()FHnx<(T18ndYCBoZ+2c(%hCpSoUc20>l-L$rny^+KXVagJ
zi@{qwwaW|7&#GW)Cvl1S!Z2=jhJ4;_A4(Ti@@MMwUGvaZ+W>LaV^e)>&HcK)Q6V5R
zX}O6?E{XK*3l?Nr;zDtfx*hOj9QnOP#{dq4c6QO2El*5c3s7=+$y>3<7b<xrMNzRc
z^E`UE8}h`a;Steq^&aMgmugG?>7q_WBd^@X^}_nN|6F#GCfDZC7k3q%&bf&aTQyiK
zWub=xim>?po__ at C1eM4M&Pw*6=|{Y30dFDic72d=V{4E9S}GzMmPM0Y;Vob7$uj50
zj=R~mN1O0 at 3fKIyYg#dQS)<skSme)ezk5$=JAHqApiKgM)i7hDTyFlU;9a4J443@)
zU^Zu!TVoF0`X4gumsZ;8R-OdQ*G5~d-*D`a+qkByr+<_RJ*+wU$;|qJQrp`hLp*+|
z6quUl5myQ6qja6Jt|`J%Z-cm?pwtc5#_prvg(F?S1WT=et|$pbUomW88R_)g15no2
z-};f2cA>(H*HaVCmrfszocfepn+!{ioPo}1B#qpK1f<AExv~4l2oaEVvalCZy(IuZ
zMXaoZ7JB>#6841*K<bk at qFWA{RKoKn{0#663l^(vok|*lY(SyoewJ_<+<`x?nEA2U
z5ZkyENCqR6(Fg)yFJxw6CkuhN^>_txx?&Km`G^FLNLEw$2r7ZDMP1G4TRuN1m%G7z
zgU#p7Tdv_P_w6ZVk&A~9SdhW3ZN*Tz_je^baKS*dfm$tmf-oOA&q-YAmKL5NG(>KV
ziOa$B27+gH)98pe@(zD|=FExrA(vSnt3Hfjd1;Rhz6i3!>xvte$GdxAjb-cJ6E at F%
zX(eW7;AE at de?j5|l-89xwetAvr5l+eQ8$jgf1*WF?Q#s)I}=}U2a495P5b6!OS1(z
z*1w&YA-P9$^G_ at jT}<KR at KVG2lG#C=7DEdL__Zgw!fW1Q7h&YO4-ly#L?$HZ5n0C^
zL#|A*QD2-KD$Y=o3GTGf)K;D#VTPyEM$SERO^cM67pPBPARf5KY4t)BS)YG#&0v?&
zL<J=*N|5*+!cTC~rM$Z^nO#bz<HVqnqdSWKki#fTtRP$`3-2Z$EcGjN_40yiwL at W^
zD(|!G>L8`FVLvzjaYl>>6B~#Y!flr_pRNiT&x^0z&?B}7mhzsDh{Y at 7X&aS~*^T++
z+F63kwCu%u<Y@)E&aWv!&YvZT{fxMJy$DA<{c^r>(R9q9o1t)`xuuQnLMlvec%y*=
z;G>=HNxz3U*QnRO65xWzJvol%=Ex8aigKSz1Yx1=12w4J7!bTPLZxOPH!b3EmQQxF
zE|h5bsjr(XE7p5l6~%2LXSXr%h;*%^HNb*pd9q6R7ug9%=G-V8{i)^7JU26myLk2)
z%}OLna$GizWgH0aZt)yLus_TKB|(>2IY at Y9J@S4G?B=-AeNB7Xw)5!Cvi#+S$_aRp
zeM1F6PC{-L14}!<1HrB5S3<Fr36|r-L?Z+Ex<bpH(C$vH0~ZzYoe~wvzC=<#O_wVX
z2b>)&jOxOoeL9&SmD2D6B!e>#L9FX{IG2KOC03$t+V0wk=mfC at xN7d!1U_ at O&qp4N
zDnEY90te>?-D&!Io`0Ytw~cuW?+#|F#Z{UdgL1FkT<isjtMd>TL<i|zvoFBOO_MWs
z0Sv?q*eo%#E&R~fS-I{zAA?ZeI(3UrV%vXqpC%ti$#^Df#STf$IzLhsE=|f}H|kd+
z{vYnKL<&4$h=O}MxPH!paE$3GYmYPf at F`*j8YgpG%v%^DyZTejD`j=%$MfD8?JEW*
zPX1nAo8n`46bUr0Pf54YX*YV#!1cT3pDZ at h8&HOZe$|yiu6li(7~%N{7=dF>n`KJs
z3S8HB?J4q at D+f2q#OG}#-g00Fx%@NC(}Y{pCPU}ot#$!q?N-t+6pM7iGY`gE?^~@f
z4l5Ev-kWYiwsWZrRXrz1rp_!WpZl({$8j$3-mOB^xW+&|aWA`_i&35#@8AIRp_Q=G
zSu}S%OU{UI$ivJcZUoKYN(_|OIu08a24U0tHHvJ~d9)e~V-%f#p*t=aJzwR~Cp97%
z1 at WGV<Bt!VC1_)nyZ0=NggBSRSVrvMLI#G`BIh6Q|88?xSA~ZQk4&jO<d`MjB<pQ{
z-NagKDKZAa>gxRDW6y2y#~JU20!u9D`hc86_L{B6z*V5As5cY7%R|CX%Xo;;wK?0{
zPA71NAq=ATlX<f?jq!WQj{YE`pzel-3L;0}UgDkPi8Es2t-~7_x%Mw{3!DI#N1+T*
z8n7u}aqF|kjE|DnpF4sa=+*<h+}Cq$@!3sxC2Z~GJPv+`3paM#32hqmpDU7Y_74om
z?~P%s0Br=@a=2WsZV~C}={=NOIbT$79Qn<W^}gWS+_MlmZqFgoqOb+X8>Ll22Sr{n
z2LuWHw1h8vOvde9qvtgcr$026yPpxTl7M~PmBMJKdw6Xmhf=ZYlHSN!D8<9!#1{Hf
zN;XqYV-!#D{qTlj;E4)XCynNn^J;DP;q9otk+UsD?8C(c#bT!!i$LDS;ZWfztsA7+
zey;4&ZENx^_u_c+o7{Do2!A<-(eFY}`Vg<K$5D4ae?Fg<uy?s678dtb&y7(RT%=X<
z?$&Q(5ukDjmZk2r at z@{pY~p?uDoA*TA?wz+9>w4OJcof&Kh)ZWiy;~_7)59^zSW1L
zU<c6&uIqi$CoR9`&-T>(Y3ANo`)58%?$N_#Jj&=2#Rq|`6{+_KN|Qav9amIsMTE at H
z<t=h=IiiV%g{p8f%Jufdz>%!yn%UuISHrIs5`H&I=4R9<3F5gd6JgKZ_?##g=t0>9
z#$2 at D=H63i(ZtWG1nx}>B1~bO at bL>u@?1myaBF){*?s>MzVer($z6HG`R7E>#Rf9{
z+5)eia|v=g+o*oF)m<F8Wm%iwPCM&+1k?cublWyvO8obom{XIGz%dEtR0n4>kp&si
zi2z-lw8lW;(yJrLzfms%_n9;`oo!--_O-jygUjQ-q01LD(fvLaV_vze%q>R`*qpc6
z6xEf-(3`j|(@iX+0)8O<u-@{=7KOkGM?Z!0{T94zjPQuRDE;`T@?YR$pK6V at tg_r?
zhd7vU`k3CD@%+=<FB2Y+x}+MKQZIkWiSIoYs>UkNbjEi}qv=y=;;uC=i3V!LN~-ht
zqulhSjV=gKVscQ%j4P+_HYVxHVPIpcdBDMj3uhp|hoW(b&2th8QOL+E_d*g%HJWO>
zh8ss1vjj`VA)ictOm<j=gV*AoZg;8cGf&6*N7FUbxR1v~)M}UeY`ON(H=5Z1vi8!L
zi~~Pm7PE>on8N>SyXvks9y$CjE-}`CVA&3xfw#!0CU})cNz!(#Xm3m2V|z5qa4a)%
zbm~nld9ttrI4#{$Fm3IUcROAJYpMyl?ae(7-n<ye7O4_n%%1-|=0b6ZL4ePbUM#n}
zyUSa;OvP6izx;(G8<{+cBN}&27;KiVCpW#o&kYZG(>JWwl)u&KKi`-6IbAMeQ=ku6
zcf-Ptp_8_od%s2>ZQYSFQ<c&%<97w+EeLuc!vVKC>G<>R#CV|h$2X{{q&b+obb1CI
zli%*l1Yedd>Z8_DZ<Xq|zO<~ex9b8U=oKQI4N0^{!5N`KSZ3lHKeT43ZbeE${9ILd
zFS>5Cd;&qU&mH02aQga>#d%wBezKJ(BQ^Shm-AbiHTu#u5Y=IBfv!>-n>vzCS#0PS
zdO5dT>aE<Whoy8eO6KTX at U|b_Tf2 at 4WFZ^A#MF*WA1J)2Vr%EdHv!1 at N`Z6Gc2#*D
zE2n06r+m3-bBup)$Gx$;=MB)AYR}Q?CG%$N1+rOFXEJsifGGx7KaC4qX}%^MY+}_W
zWew9C&xbpP3dR*1su9f7SagdS6FT?&I^b~x1)Fkd5vI-W&7vJ6$Q(O{>b-Z^#B$nH
zDxQKC{<$|g3DVCZcGkoxrt|Ow(mjqAf1@`UU;)N8{j<M6{i>S?r$*P$&s+Pyz5q6W
z$;P5qVLv4kUA_HEL^LVCtBd at c<i>wgn4g~4|6){Sj2Pd_-~zrzfHRcN-)9SJ*+D4S
zcBT29c9#hN*^Gt7Ff24UPym|s6gERo17qiwiz6mMZf($@l31C2rrf^k at nZ0QilHqe
z07Y|w at RCH^LaK^uvPF%)ntvCG1-KP`hx#PlaZPNpva-LRYXH(xms5b-0>CH#vVgQ}
z;5}fa#m#iS%J5^G=eJ=b-r6IdUrBoXK>rn*(CQbW8Lr55wAw}rsO)6i+!_pV{}*}r
zKNO~nx;fxuyZ|i-AQde;5pkRj9uA~$ghrgBxa8>#8?mKQ6$7e*+-TMR7q<CM6KVly
zpa2$Uqcc?KoYUY1(_wR?@Culw|1qIF%?|%#ABv`9)&h86{Lb|D_P~Xe$(F$MuNj5o
z`eLn?ms%OM?4xHPLp_o7ahuy at x&olj0o2-LjHCEWWP;p0cCayxJi!&0642;y1Iq0G
z;6<aB;=^*+`Wd9sS_MLOlsVR+5849UyH~Y?kkjvPlFrb~QwZ4NtG|%<t<-Q!asRl_
zcjB3giPfx|hWszU=1o`p7U*RBH;{>Cb~p~MiT}gl{13<YuKf=cW3&i=*&h5n=!kLm
zcP%^%=~7QEMawkD$sq^d+<F6<%AGO*>-iY428$a#+P!SP$FTlCD3+)ez<&dSdjKL4
zbbo>hz!Lsat};>kRt<cFrG~uwPlij%XFE{xnym~Q8K)_9E)=pe%L%vK0Hk&fceQwB
zko0jY at -r*4jNnS=18*u{Mkjzb#AGA%H-f at dDzt5(*-j~?#D1McWfbnyuU{_j?*Zan
zNJz*}AVtjkERez$-V<CjCUe${J>g<V_=Tt*3>G9Exb*>Yj<%fyd!SMC9WU4J8^MH*
zSNoGG-2#G)bNXG-3 at u%2p(*8n%kVR7UbcQ{mifhhOsH&OH;Yiq+#lD50QqZ7a1Z=n
zrqpW;m^dN;fWBJqHY3xwe7Vd%q51>byDXoZ1;E&-c-BG3(h~Hn%FHblI_I7f3V^0e
zbdd4kr0jP*|1(HDq}KFZgvkaJ!mbzq%`Vlzi8IH~mw8j*&*SQ?C|J;m2<URb2<zKn
z8u*Yot;u)&cY at C+W`ZbpO-j3aLr~Jdm|2%rKJm}x_B8Xn5kDDy(rsqGZ{S1T6
zHD3K1KFe8h=m&|O!NYX|tMP0~iM>FlVq+07_qSndMs-_z&Yt{S(aGH6y3y*)*6EK3
z`ssdd0th;h&DH2B3lmu3{?^-({^98PJ#Pd6kE)B#z`y~$x6Si at ihe-7x44=qR-yUk
zKUXp!C+erir3Emnwu>(8USFQwchfC#WN-nUoegvsVQ#JJP_+W at hdCT<OCYR(5#N;x
z2{K;Gbc5drbN+UzdUfP{zXE)??xzA%Fi*JuCLW~883+24h<f5~H`X_tF`TLxvF1uy
zJW-fB<FjE@${1y^qasWPkQ52QXBbN;g7i^v^d%07;@IjEaN6PO5Z=P|!%rbeHcw2!
zYa=j<3n1w8vNpv1^6;a}h!H1|=(a5*7|o4-P+!8sthq5cQh9enE`L6ZIQ}P*t>-~0
zV?I)gau5D{K!gb at 6}+6Jl{h+bJc7OzrD}|ux-88PYG-BbOTXezuR8pK61lj2-%fl?
z7<`+qPhrKDh;Sz_2U=ytA~?fi-OuAkeNy9OQbeVWhS-ARa=#sg$i0d~3^-u<Qn=vz
zuWEgRKP4<W2D<`5xH7m^jhhjPC(6av5!Z+FTfu}zol5L&L4YKCUErxNmmfn43~|TN
zHT?F at scBikOQ(`Iffg{FVXwDc2q?|*d=p8)DygfR+KY)EHxRCnP_*USkn$hq476P@
zcc*zq|IO3m-$!gU7Q;uQvwM8vUP+UiFR}Qg>Z=C29_g{_9yDTBNErFDtp%o6N at 69g
zPPvoDDZXcFb6Cy2Q-LrzEd96XsM3mOc$gC+RyScn^RZze0X<<luq|;Lcy~51Q|3p*
z0eat5ya~=Cez*-*<OB&TDoQet{)fCE*a&Ngsy8ZoKuqX{KxCeiXx)#lc#nOKkOZtC
zWvVs^-hp@!Q;;@}e~`Shd^S$Oy2MwI<PNTGtfaVv4LlW@)ucB)Q^q(0xcWfA9m^#{
zvJvZN5mFSbdJG~vj=BcMymMTU!t^s!X`BouKQ2yq=l~j3aR>>E6fK%dmbgISScHy>
zrQKTr^kjth{wdW$+y&O+c^}>+_u&*`WzIAopoZ_B!uxyTNj2k9M{Brx!Am=85ef;0
zd}I&ZVxo=4O~REFq7x^WIP;1l_aK&(!6|T2G*ed$*ERA$2L6&+=r0dyiRL*HC>U^{
zo&lsi7#Qn=47oieDw&Hy--15;yB2D0Y2lXJHN#|;Pe201CPvjX5!3*u04UoED=LOj
zBnhp~2EMIWCkxbHjR0y9RH|R-=u`kX<`a?+go>1$JY?^2pDj59mly>mCo4-yMkr!f
z*^$WxG-aHcFxGA-KM1`nLcykHMNyJev67;G1_i<~rZb0_+fMKZYq>fp*;UEoptH7`
z>UT1 at z?P5G%X!fR_VjFqXQlUXsN@~m;o9Ws6?fpLR2$n);Zf13(pImSiz|QID+%w@
z*49~8TaYCATVLk4P9S-u9^2asMuLbqJFo)!FBTP9fW!dF2y<8KcDbKH*nfhXK%)es
ze$P*WInvUazfD3wqBQ3=rPh8U at Qicf1m_js$2*Wm_=YV{5hr*uN~R85ku8Mg5$6$B
z8k+xs+?q)8hLDmPbLO21dq5N-DzVf(j0SFJW+M+t`@Om^zqXxN-t|7WqBs+(;6I4f
z%1Biik>Z<yqJy)6b_mB?Nny6D8mc^P=|u|hBZ>f`0mM*JN1a_tohzCJ9}JT+4BXT>
zZEUHMK`U2z$%D7lb{4s`Z-b^LBqa(DmQmq6uRQWxxbf+bg5JhSN}!8JTQ~$M<_E(C
zS@>1M at nRfgqmbE!IzCW+3*t$R^Ch=_Pw9dbPOWVKAN2SYx`u&xSz|T~?q9azp^r|t
z5Go at Lp(>w!53JO}Nup`2N#|ng3}g?r6dEZ#S|^MD?s|>|v)|CC>n9hr)HdrpEe4o3
zHC)Ptv!fi*sMG~p$=2 at v%-7uCiiYr4Qdnh|=abw`?!6G4n|Fk|8GBf8lbCw1F3XpM
zmh|5#?@SEe{Ubd2)BAdF+W6JZ_|P&KCi(z=*=6?&BNcmDJ8u at nW@=H+q9t0qCn9$@
zL2~dNkN)`Yt6BIdl#4Zs;i`o(270t(yzXy_*ZLgOU>dJnYXdE<F{<ABo3nRLvG(ZJ
z>dq3h=7aWfXxv8ltnl<z);H@`S5b=UPonW1QhU`}B>U6BJN3fQteD$Y{PUI-kxy0d
z at C?h5kEbu9IZHL9AS`Xi4KF_miuN1HMuakc62 at 3?cMgMJ!0GFiAh?p*-LT>;Wy!vu
zcdr^Yf$os_A8Q^<s{nr7Uy}q6FXr+qy=<%yI?Psx3yx9|)`CP$7Bb<{IV=%rfupjG
z2L~Tlf)fKu*NNXH?3%{aUIrb{Qbk}%uW7FDQ!(-f%R{W*@os%6#&hvw?-_21OOceH
zMKlydU_}BS<mnyJ=LN$8;3y|qd~E)?e1}8rG}I1I)f8x>lYWem+;$#~nsmfyDkCi*
zrygwS<V0qbg)z$fBUlf at 6i|4BiB_p44=4YPd${o0%42zdoH8%i*1|l<_Qfdn#b0Nl
zT<>d1vXy9#ICo)@T&=LABpl8ke^orj--LgR(Z8G0Uau6Ur&0&0#|g=hkonIb#2L*6
zxRld8l{ouQ=LRbRxnq(<AyzyjWGkm;5cb?6f)J|z8o*mX9fm77qsRo*BnK+oiJBJX
zCfYi(bTT}nwwwEDLAk?S$#{yzWjcpvfpCIql0u?me$&G1mHGjmzforEaKkp=R?*-h
ziB8c<(5O=7;ogZlwa;sZSy_mXd~qJ~r^#%C+;@_GaL1Ei6E~<X)V$u1_xEOlC9&o4
zX61ZvUvgLu<5nc^jez6f#*F5WG<ByS_cCMP>(~-vIliGnR(A-plI9Gu;u1O&agRZy
zqupebY{QMYQ0csdxK{;oMB$KoA!Ca{f|OQ0SP2Np<f*v!!VCCjWrJvh$-9_?(a$^l
zwvRt9B!<3`N;<?WT6k<ig<!{F@$hUi%2wh^zJVYA2JGVf<5aOFI6+^+WQlllb@}cO
zn%H<UK=~oih%5%2UJ~DRsy#&>lVFY*s=5#y@%6_u2!F++J%giRF*QN;LRh4l7 at -&W
zGknli3`w*_k@@}t#kz4vExxYz*)4P at 1Foa})#h&3vI91i`^r>ha6+v?u>J{{m{sc2
zM)FK~dB&K3G&+VVIJvDf0?u?0JW&-tP-Y{n-ym9vH#52X<CBt%K~RU?v`{7B3?-}E
z6SFB!MB_Yk+5<wX at 95&1p>b&16POy|c{ZVN9dPrLVW3+HcXIH`h_86F$~3)Pi&+r)
z at ty{b$~>Zz9>27nL<@rTM;jsb*|$PJ;PojL5CqzTT=0va2zrxoLxK3k;;VAh5uNJD
zQ&7q&q_|%TuLW|2|Gw7A$)lofChJUSnzivDEc?R;sf!COdKJMlN#8`zA!s&Fl*9Kt
z#y2ZbW%*heBD-Kxzr#_*in+*pLW!fVW*Y)y*`^mSB|^pTB&v58<P)JsLW8z^43C01
zaGJdL5*kk)iL`=M2TLg#fK)X7+DFW$Yab9`<p7)ofa8<1N5+rtP2I+h6xV|r5+aN9
z0c%st*OA{y&zsf0$py{G<Ah1zge0jIlJmOS@!1WEpHfEVez)Mm_~UOFf5)}{6@}N^
zwU-xmN9k`H-yE8V9Xv*b_IbMGn<5%pL255Y5|D?(wy+fh)s{1oWv3N-E4ViZ&CO)D
zPs38~yW&CSq}82d4XxxJ-!;e}L8X4z7!Q1gLGa^t3mgXnqL8a;Ib5j?=GQ&ruH==*
zBfAEZ=|!U=P;Ot_?F)i1*1WnwJFY|9HGx6nNdKhMyN!uR_p{L3t$8oGyjE(RTpy;@
zMsv8^=O;l_c<%!(KX at un=rh at A_YNt6<vsC%!qL--*gEMrFr=YpO&wk+h^anE6s_f;
z*}|5y?Q!x>nvT^_p83$x`Bp at JdqFa20f*-Ig8D~=r|s3ypFXG`J-T`YL}p=#(n5Xm
z#Swk04A4`*Cj at p1`#hV4^v099%o=kUTxf>Le4yKA%O@|#<6d&#hpkWzLBOP{|5Oy;
zE4PIL`{~H~h@!lUiKUBf-Y~X;T_4nNeDO7GQ{TY(nFK7 at NO~*wN(0_C$!B)oNY9p^
z?|66G?1HGBC2rusJLa+Ne0LwnzB#o9=~x(OR{tEAo#`+*1zzhZobF3P0P`d6BaF(r
zQz22l<?*D<dMDnDsgEH(U}PmHS at yoJloAg_O(<@SoK5R^DcEx at v@YMNK=nIlj#pkI
zAVwB0308;Tj~WKAM;^j*Bh`Yn*$6M99T=w)Dsh=ZmW|-aqecD80JBcrk>DGR$Q+y#
zg6coYXgIkL^>)NCNESyxfUG{YKc$su%YFdXI~RQ!&qkC6OSp1faqJi#pO8uA2rx2j
z4AJjCO-U*7QXx`{yt<I2Lh`(~g$t=JGr#tC<KUxi#^Hb)g#4s;>|0osM5$N)&cDgk
zjPAGsY{gjd0cz<fI5TnvciN?-Y$9LSuGx#I0v<r=_<{7}Ba5nlP^K{T_Jqr()p<hh
zpm&vy&F9CPV}PJ$S+xYqX`c$p-Ggjs&HiXJ_`5BjN)O5&kPOi)Wc+GDDVzCvZ|l;0
z7L at rb-A%62K$f-oY}>6PO75!oF7R+HlzcI;3(*V4O``r at T%Zvo=I4%+x$4MU<#m|u
zeiZ7qwPd{TCR-R&xAlNtddWA$tNn at fhsg77O?{pQ#j<~{_jASF2OqLkkKyBwQQhtj
z_qa1I+!0&Drgs~<r at b=s9heTnZeqR{Z4T?Tk*fU^Mr|nX%RjH3w3X4m(YI#QAx}9q
z4v%DC4YE94ja<76jQw0$sG$bC>O{PIvOJMFn96j#%p~}-gy^=B`;t4p{_OVz`dA#Z
z-tPCpm7{khyZq9w;&=#5;lnRI&xBh;^EttLr^H=$uRGlzX?UE9*~IxznSx+@?jPM&
zfDFX5YImN+sM|GnL2v%fvyJ1%Q&P9hjR()x!?`7 at Td|myjwkH0cduan>fwCox`Ow$
z-)eCF at A<722cvLfu`@)-&o&H?6!Ajxg7!zkyFY}d{-U?Xjo19C>+ at nS1fs9=xgigS
zu^YB(RF#-t#_LM~R-uafc<3vtOnfLa(!ZTAEP{JZt*#1aa&C|iuhXYDZwxzPhv#n_
zSnsEs7nXC2tcO2pR`P<sYsB)JF=6{#2pXmd40v@;J};?v-7{K82je-^{O(9m<9;{!
z8zSWKYsLw4_6Skq4NUl<V+-zmFbsVMPSZ_77$$!!6-ix35`Z(D_YD!xP#h0Y74eq?
zCJx<1Hz at Bb+OjvfwGhU!n*@s}=HE*$p7IG#I4;pQ`y_A;3vvaTJ<(qTgs?5$i571&
ziLt5VYNZdX!c%O8FeKr>@;t-CCtt41pt;~lR2ssIOu+;o82twU<^Aey<Ss~ILzH#+
z;vu{PIpC`^4wo9#s34dwECydd0$#xl0cuOMXx*$NpZU#|dLD%PAumCw8<UB4)Jv;C
z5bpDg5geX+q2;0iT9H}qx9JUygEBED$|RWTKiDeTL1oBS+KB>;FndN3R8&wHv!33H
za_(0#qwx{t<-m;1irM!!$6~Orl_3Uk-Tyu?13sv!A4Zk8<CL$CxO=gSVRFU~y2}m6
zh4L<8DwD^J_XXpfmn$*XS-;WHbse;1Eq*0`HWlLj&(0!FrJz6-{P}{R`=3Vd2eD={
zY_U5E_o0 at zuS=&ZQ8HYA{PQ)`Awoh^xCoK_h9ScCUg)j*WQGqMqPN9_XG?w_!u2fU
z8w39!MjrRMXFV@(=CXD-CT{l5j^cOjw$yxx4&RLKE!H7h%^dz^K+-OPj(Ld&tTnqM
zzn}dw at Vs<ZY}^Wa$W$%tN|N6q+EEO1znb{zEsEWLuFkkkRTS$l6Uj+w0v4(##rC-s
zof&IIqwrb#?O4wHL;pph==JW_{c6%sU at HN~D^&AGlLfa9JF)opLkwF_JD6fqRNFmV
z96Soab)j)DqwXP5l{5 at 4AWzV&^YEXX+gR|a%a`*6y0FmL&7I@%jr2goyR+QokZWZB
zhvpqr6t^vOw`Z`!!`8g%t at HSoST|(R`&<X<YLu~$o9pX2<6lar)SE+6$$c^UAJza%
zfB{TKtIsPD5EQX%Ywy!F<IaUseRN$b)FvW+?|ptp9SNFn{HUbij~=U}>OxMa-Lp8w
z#iWiWLo4nskG{5omFUr)h>E<0QvWg4x1xLs0&q~@JPVk9U?=z9By{(lC;qrmQg-A8
z&yEe>RE$aM`lkVCAnd+XD4K|?vZ5C*f)RMu!5ej>dFB_|%kPM{NWm^BS9)R7EcjZ@
z2>r()1PFuix|BhPj35#$?Jdf6S1D~8tD~<%_%dk3<l^Nfs2hCnZRBJxStS#{QIZa$
z2s+RNGEgYsBpWBV>{Rs;DP at P_;o*sGdU(ZC5I*<g!XZ>?iIbGzNJ?m%G_Dkvthmt?
zvHPpjpcyn;W2~%U&m78E(BN3(QqN<GQ2Lt&PMGj4XzmBZNC_1C=6SzW&<xyabi{*G
zpNI)k#YdI<qcJ+gUy0WV4{n^W=KAL~sKHQjFvD0(MFwB2X|?eOYEpCn-#IEZfEV`w
zo5p6<>|`3x=o!)Wv>=JbSu*xO?(qDl2YK4Q6mYDIVpQ3X5APMBvu#>uY2BEbH(6Pn
z?#~_)A_Li%W2qHRc8<|t!}}r{B7asFiShJAtuhj|ZvR-?n=mJo>8XSdU%E3gLA1hw
zk=e<E8k1?u$BEXc`YzV{_OJ}26_?`muJYr_d!9dA$U5C!1v$L~Xq3t(@};oV9VN~<
zXWU-2Bu5-1tf6Zp%|;?}Aq;4r;KyC2qQQ!EtcXp<QVL7<K`Irzo^V;ty{_mX)bFB%
zDyA;BOFnleh}GgKSO^Z7t52&9X3+<V){ObEKHOFaBiu7}`?;EMe9`D0MHSsy%u(Qy
z8(Nj$(&5=L#Vfw(^Q94sVLJ+;fzvxSgSFHHjbfO#by<96<D)QkVa8YaB*%kj{?Fg?
z)3Yb^sZ=tVHsUvcWY9O{cYV5NaaO8)T7msIC!XYTQ_P$KJV8@}srjFnd!P}2KLyo3
zh}eQC6NGNC=O!8sAaCKMp+V|wT^<$Q-hQX9+E<=%Z%}o%>Jaj#-bQou3`~51_^owp
z=sqG7up1)D^$WQC2+-%1F6Y5&2a>O!E=3#>Kuyc~%UAxS6V)bB$(=XL)O>9_C<d<U
zN_SIY-teS4JB~+I??fU+dQ{<b5#*0||I=YFQ^Lc`@m~M#u>y&}Q5m8(pqJS^y&koB
z{4`(quzUN-CfE7oZa1s;SI7?!b(Qj|C|Vp=T7R4YSQ=7U`Vowe{%7VH#qrN>*M=om
zVaFw`kP<t6mqHZ&&%8YH1$652FbfS$h4%_{AHKh at ec#W&wvknPYxJ_U?0mRek#%YQ
z!D7x37tlR=pXNB9w0nJ=zV)FMi6YQv!(B$piw;WKhg7BGdQ<GRgk6VkmW4IPM8VEU
z2ad38n_^u_<oy!&eR^Mr5Xwj!3 at 5+l&&dp_NKPWEgawr&&>*Z9PKGJW>g#-nr9_F<
zr_Er{C$y6}i;0slp~-8KqYEB|pBhv at tugX<#m~|$z!vC;sasO7`$-+ at 4aY{M_t)Q8
z)ZfO183QZgv{KS0r^rECtg|56G5v#5hWt0a_wckjv&_6KSCqRS-u0REI?B!-Sekbh
z$j#yg=GUv%!4_CZ0LEWOIjlFCP&M$18ZlS_ood4V_us#Nw{Ks&L+}4uwg;8t$+3Pc
zS9DN6>#6nYHum|4-nu1h+%LTLKvtx;<#GHa6-YNa)MLhr3bK++VX{CpD5$ffvXQJ!
zkE&r))zT&t-M0MEtc;lceYQr94)#eQ2_v*yseh!0Xz(&CJv|*d$gQF^^b5RpbtD=7
znX6yQp)qv)b$0J=y2Blo`%op!?Ag0_%<<vA#r}g(rOriJ8=s1nK>{9%)I|ZUirI``
zMHFWUFYg|cZcR8ki9$+^^P1iAYbQbiV*z>{(ojVAuSFMps$mjZi;-1#{_0i-|3A9N
z-!6u9Ya1Wo!gWvX#wd2h{CZIsV#sz+MPJ}w*4^4i7RR68yICi5*W$+2a5toSowUVD
z at C2bKajT#PYKac;C at CZcx%gt=irwK<YFA)uk#Bx;$TV#rQENu>RtSrCx?1SLO<Sd7
z`Um!%py^4VW at n59qvI-MSczc$>+8lVh<AVtGIVgQ3;XU8dYm;A3^U|x)Ka)-sDWsP
zxo!;Hgm1-u77oqODe?G!v_T<GL({o!(b*tA*gSsf1Rkwg%rmHaSZeW-*!Z<=ZIiUc
zz8IZ7oS at eF^mL}gHQEd_T-rqD{t(aPY*sLJ3{Ocy2v{*DzJWxc0_hC;5+iSDJvWaG
zIUoq#yk~YZ7^WWDLvWGE^-zQZmOqYd<=SNxn~6Oige`c?tZ~Vb;%+93BI%jT+jV}Y
z2cuf+XA8flIqmq07K1x;5JpHT*)E~H8$RaP9(%F`U*6NrfHsyNOjF+9jMZY!?s<pw
zvMrQ9DKiwtOO_yK>-;X`GRPO(FpK5}ed<JXD4Aj62O>fEf_Jb7vAt+N$1a{S#=9=b
z at J3>mY^f)-p5JmKc32S+@|5L>%s8_VJ)IcgvW^jj*d(0uy?h=1C3XR>RcTrlHj(>t
zu&z`(xmdCt{M=^*2d~S9%ZJdDz3EudF<FOBR{kT)wJNe7KkUwC8FKnqezi{SwY|P{
zXMNP$6MH^?Et+Bz8WmxqmrpC=TO(PX5yM77eA(oFWf- at 8!mMsN)@{5Dna?-<K~Sb`
zhSTl8hj0Ak^Uw=5@;Z&>6z2Au`)olnql}q1f5^$rEmb=G#oT;nGccWq##}F<gvleP
zu)Or at XEt`+=*UmF7K$ec-~0O40kKEISM1lS`)Tj-ZvLouVQS&p^k)R7K4}_*%d&8?
zFj_mum2V*H=UIlk?X6qr>lk0i<kxSG;iR1Pwu3AjP$@6AzyFTf6X#Fbou3#zG$xd|
zXF{?J^el||>9X5m9vy7YUl>#;e3pD%<V4!6Q>Luy7YsgGa4<TC7q<P(oo_!rh3@<L
zva3-HHZ`PEK|2R`-nsrxs;h}i?eIKhYAj4n?gGx(65_|ImhfFUF{!MTL4UI2_sldC
zCnK8%+Yg5~TzC7a9v3~wBML<yJu>=ZQun`29I-eJ`;$Fgmx_%Mt~Q1i at 7KJ{-)$%M
z#hkWh5=VoxiBJpimXr-C`}6VkZ}|?Yv$yxBfsnO;a<1AvHlv2qCT!M_1f%Nl-9D7e
zHuBY|f{wwy2cc|Nba+1gIbsawsS|3 at Vu;@+qPO?AlvBTH5!y+uRwTYkX81kFo1#Di
z=+?L5=xLXzs#VTKoe>P&cXUxfWK;!0vB7W81GszZ&}!7q5T%9FD)abarGG}3Qt~UN
ze)$y;0-nUE{n!hpZd^yR8K)kj$`B8mRV5S2C>eM{$UmL5N9PK)v!~<=ME6&}VV0Zm
z5@#M{H~vQT at t-;pD`E=mJ3$!glyLYGZ)BxE_!9#k7%Gx5$`B+GTZT49d|nZX+D5f_
zMBOdgg``p&@i*^x;>Rk*3j)vo-xr`u8U0X>C;HAC(c%WrYq+Ni&A=2(!6F<Q_EB}F
zoYWu3Up`^%vk-Q7DQZ5tCiMc#F8_OlU|gf`CEo~YHEao~Pzk8_QK(S{*?#aas&U+(
zcf_To*IG{~zZj&@F*8?qKb*FAK8js5K+Z?F8rGm72cPMNns~31)_atb)*Td+A0H1?
ztE$cqUw32g_ZeQXaJK^eF7 at mM-9;Q;>U9lgng!<5vQE<5Zl4wyUid}bE+`UtH>B1c
zSiJVgsZ_Xadk*kh8RF?FUXH3SYb;->#=5w3?>WTI?K<Q#c-XD7*y*{&epk#JzaLJp
zs2%L<Ls_xEEtorEni)|@h^pWySIj8cGn-8F&U3Bsm&PU%K7E$(-C#)aJAZA*PNvw1
zb{kFH98|G#6XNO7iqVfrpe>$NMibQz_Qus8#rO?t_;(9B at j!O)J?6ikUh`o$7IY`O
zv>v-S6Y at P{Sd(m+6_+f#9+sbuaz!YPZKTa#QLN#Z@?Q9*o+aeE?1;{P{D9<l^Y}`!
zw%8FUOzz2A{c`Sh+2imc+VOlC+5~+ClPF#+I}h9V2F;VZC-_}2QAoR<TI45c<ah^c
zJ)Z2yQT**48x?N+a(?+V`1q36e|x<CGT)k#={B0hr5Y_On?htR7K0F(ba>*4?BE4F
zW#ZcNy!Xq4$OuoTLynoxx!n`tX?y6B(Y;;kzna^N)!S#{>SkvK($J2<&ReFyO)IC@
z%(XwdSg+)-|M>k<g&oq&uLt{y$)B)%Pgv(So?tpANyW2Z%%X79FXJnapO0JKM^Y4K
zmvdx4$b6$1_(||X{c$BBI}5#Y_eY^(JzAuhV8JQV+SmD~$#C}Ct(%66n|TUKkq7hD
zM+ebhmkin+5;Zb*kNr@;@Y7{<^ZTiR_SOm2)rDWymY(&M8JhE+yw*-E|89Ltq<n0U
zo5?d%C3}y(_okFAqOt<s;9+(JE`9hw2$?v-eGGZPRL0L5`7($iiM~mnF#7o!&zf-z
z`zJ>yEpdZdeng)D!X(2x;dGrKz6h!@i3%B1_!=Z3OcsSW35fxaRYhP>tJAJrR!&IF
zN15V~W&Gsw9p(3!B<S#hHU4a)c)I8qH0dg540B=T{x+kZeUPuM7HQwoS at ZXzNd4fT
zRlq$itVD4~CJb*1u-%j-wPwR}N#1|7l6PDo>+vRL1trVI224<u)N(AtS#YYZPqj%?
zzz|&Ul{q8JghmkPBZMRhwSPELhq<NQ;9y(W$=5PFsiYIjXgFT|<!rx8uD(poy#vRJ
z`j#b_;A~tPzmTwZ?78}`vpP@)$?J*sKM0B~?R4CO#ClJU9-UWj8D8Tdx2>=2qGQi)
z%R at 26!PE2;Y<xrlcAqVV)<l5><Blh_{Sm<oL#ZEfQ$L|@sM?jO7DMM3T6Mw`Cnexo
z?6bYxR|k*Bz*qD#vD2ZEq>TGw^WOuuDdvPeF<E#cVW?wGH6(|@<m#8g)q5?g*K8JU
z<9S5<txv~Kn@<us`~2zYpEf@@ylOnfw7Gn;JMkTESx8<9LWftucU^O*IDN<uJo+lE
zoiA7$$?ts{t9hbFNn&Lh&fj_|vh4l31r};ohzkO_uJu$|1RS-;H at uu-b9Pi1BBNUa
zdisv^T+s<LS>y#bhSR5W!K%YX&cp at hNE8y`)6M?XOK$Jy at 1_`%iVf*;tjoh{FH`p9
zuZxLU%PgJdBPV}{qvyw`6;F0Ued`9}cQ8ZDdseO~9a^s0s&X-tvL8Lh$6ef?CKOO=
zB$$=d^wOv$YZo?wR7#1K9~@E$@_hX^Yv+l}E~oq+4}aemGewUfJUT$aLgcx;;waq5
z{rXIepHYUT{$4Hu#epuQr=gKJtSHj$d`s*#();*O?bkB88Fst>r<3-;Y!XI;KdYe~
zslbmh=_{vEleQW^+NeCe_h^6l?NF0L+G6zl-1 at Kt$}+Q*N%6?QELq9fS+{fhxlV%(
zxqH(?O@;ESm`yc!?8M9C(alYuJ>FCyk)NV5Ss06Dz2R(C&F-;6EHQcd^83gPLdEq%
z#~eatCH#ol9D5MA4fPCVk0(q0OUqo=&EUOriSo(9?$lgOQ^~F->PL*QrU?6mJtXvX
ziwTa<K{#~4KRn5vc#;h-$%;wGUg!OFFA82{JfQ<>&6Fh?F8+JZ9S$Z&YpV>CQLK+4
zn-z1_g~N at qibO<<UvVQb(+=_G`8q+g3LMm7-I8=)tqb8w3LIl*L?mj?25NXeW=Ir%
z879S%oP9}l$kQXOi{6o{L;uo`fI&JCZ{CBR at ZosM2%*`J at aDQSZUlEYjI*aG at E?8B
zVWG4Mei#maTpvUde;D+cl+n5IirxfFxl3i2zes-*BUQH-r%0otF6myyYKVaj&w#uS
z2})uv9<}}TZFmHA^-_-Ffzj`&D|TxtiA6=;@C~*1Ze;BF$*I>cafPsq_0zy at YdE|2
z4wU@<AOHPgVyJ-2wt!OPWoq$zJ!82K9=i+O-v1W-lxq=>7b12aD;r+8GY%k7$*)~u
zM1pJ3TlUMA+*ceuuRvO%c8wQ;SPBoIf$v8~l~QWglv!`lQO6o2UO1Vzc52)_rpy|b
zZoZI4!m6SriCVfpn#CJFyYDpYb4x>mf=Byhyb}ATZaG at ZX$+|Eb8hh`<1s8;lQJ&Z
z=o7Y+Hiz4?DBCa_=$0Y2&OBE|``5_lhSlM34cYG*&Gk}0o#r;OPb_;eW1m+1QlHb`
zHfLWuU$(eweaA9#)Dj$evnI6h<X%)0xOB4Qq3D*Cj$7H){^`Wxl?i=<(Wgf_P1sQw
z+xQjyhOuuCgnapUYVn1ZPmfsvL~<nPPUz(zdfoi(o3v0%<755`e#cTj8)ZteDgCkG
z at _py_sYozIbbmXLvg_OBEm+kWhB~_7vwR!zTnbrxsTJU$w>xpaOD<jU9s$W)2)d64
zE<?^Attp*7z~h5+<CS)KrKG2_T-<Zcj9WPI9C#wr(2GrdM`?!sb>%IW`iSoByE#)$
z;lu0O#ICVf(bTUh5!2DL2mJ&2n;eSoP2Q1mvt-+|86L+d%3#fPs%s;5=}e}59uY79
zNOgCFw8 at p$g!M39;DK;}S0jM(B}_r{gL(k2Veqpf>Z*88pHQzw2rX8+UT1Z6qFI2;
zuENl_5vCo=0ye6@^i%TCrq3&U&^BE(U40c)oex$nLCBa~n^$!j{4mAY=5My?WkLlK
z<iGjS at Io^Oe#U-E3!eJf6&IIkMNCD82TF$fZG#T+YAr{(Mp6>dM2SPm7~Swe<COay
zzCb_qSL63_Fu2rwwm=SqUV$V2gBI)YvvAxlHT0Qyq$!@Ul<LcjVIHj7W$vv+f{40p
zK(YZ72HdAaL_M0V(~iSOk83G*VEZ1UaC9>FSvK-B at yNy>u3%vu$>z)h%qC8~dsiS2
zqos_Gbh(dH^X>~|{9^1@&1reNQFc}(5Z^1Bt78Qr?ikqKhezM^7Pr>W+1b(Z9fv5K
zGI{zNw&h{Bl`GPx>xbA6kqk_Ci~k-Q?bZ&*KPIOu->4oJTaGnx%D$TLhW2$SV_vaG
zm?$Ufs2%-c$#v_ at hHBX2+Hj%ojbw-tsxRnOf2(KNxO|yAdb|0<IYQp<{!u7SpnEG<
z%AtQuVewo2k25`^-i5V3Jzu{*OQCsQ_ABCa6t+ at 9%6jgwh4%t{9;makvw(>Dx28Ml
z_LCaLc$&?~2G5oq|EmqwNPGMgcE643)R$bBb#}MeZKtc>x%OH0D6G6>X2)Ukr*1YA
zS`425&ew!gQ!jDa!FLsx=}OmL<$LkY_D}8Dm3~pCZR}?kZLct#=gXOX24<eb%l%+S
z?RsWmk(c*q5#5_8oGxK3R0#$2ca1TNkd%+_P?P9>cq0~k)(g0f-6EOC-4P%NO|zzZ
zYaJhk)3YI4*B2%w7cOeejuR?nFon?Je=WY78rJrq2W$i?s)C<CrW5rjLpWw1r5Yw3
zD4TMaM8v}H^_EU7r=}^Qp&y;}0wZ&pT26J2Y#B(N(fw*xv~`=1I>b?uM9lIx7yJhl
zh7#We at wB{2pb9_02FB}`1z!ib!+OySrr^J&QAk3w)?K$;up%p at ZSoW-YLOZq&4UVK
zsmvoX7oyj|8{sC`-cadi)~_FUm9WJB_PD(B)@gfX^}lodk$pLtF8JsZq(ifne7o9J
zancre>$mM-)rj%Iymo$TI96=%&=^YbiCqJqJDs>;%?aQ6n7)@|@6$Ng2g}BreDAC`
zN})q+-RhOQXcRU~ee8mLdwj1a`BOukgsMgZ-S3*570A>)qi??$AQiOt3y;`xe<7yK
znN~|%wk*AwI!|o9Ep?GLz_TbpC at 9@REHe_PmP|394)ge`)gr!B#mk*8Uq*KL at VL03
zoL~m-v0cHCPLl9NU{LSDjNqaskz?`Cn!L{)sW(12d{r)=O6&@Cwuh)DR=So7e?IJ}
zu9Z!^O#{CQ!It%Bn-c;Lr=vA|;*?`1)3FF at VG)7hw+68XI>;A7jUM at d8Fsb%-?{YB
z?kwYIDVs?n59Pt)lL)EQizpr8*5U@}7rg%;05d_%zK}K{KMvUvq9=$&AD3iA1UDkM
zu^N*oV5*1;as33+-Gex-s5XNquCF3#3T7mIflv~@@hz|vYY4j9LmM5!a1D`>4owVH
zgasAjnMH%dQx%9JDix)(g;-&Of?*0`La?%;kS<ElUPVQn36!4TBO)1=<#?|!beIU*
zH0UniR#w3Rp|GlL%&%bxp&a5&Q3PX_>Smi2{-&HmwFL|by%k)@uvCfpDvn(v5zrN)
zM$C`M03<<e4`u~1mJl42;fi9++*(OjRaRD4c>Kwyh|$=&G|#)g at 4NWO-+q>(Cznsb
zsMhAa=ffZSTZ%Gp&+P|sRMn9FU^wnJ*;-M(6rGvL*AIt7)`w4$Gz`O7Y~D>K^Mnw{
zvXtAe`%YGl|2e_dI57VjTImuo06t+(U&b;2msRy_6y%=iIVbnsX)^Ss>nqhk&BfR_
zm??^aX0tgK&8!#T`L>u%ZE91ye9mVb#MF+Ws?umQ#?^(hWxE7nP at WuRZ51KXPIgu;
zjuXAnlg?{>zcT^7uQX?2YjvRhIZe~?9ya;x7qekbR=u_cHk0jDSIZbp2CZ3^of5#D
zZH#=(EAhuO+-GtwZ4D}~x;Dlz5)P1vNCS&2sB=WO2gL&=#8oU=z$C?43$qe&yRq_d
zG~10>iDYw_Cd6X1YDcpQV}R-?yB-nIYPD*D4NhR~1zfX39Ij*KCc+%jXd_ZqS~Q7a
zc*45J)R0(`&MZ)Du2K~(97MwywQcAqfXAwDM^&8qt7-My8go*~9|#nlKuOYU5|fND
z%n{ZQn<pj$so_!~t`*QSoCsb)vVis1M(u8u$e6_e;@U{oK at zQkvO-9bRV2<pY+#!w
zh-m`}>xi30Bq8_>G at S)oL!=rvaeJ^l66FLc3dt^@;7Sqz*cw=j^)yC(g+)>F>ih5J
zH4ogwAkR;`=A2Vd$M5}z53~5OPqW^uw0m|e&YjZAw)M=o)V-p5UL(p7O{%$(Y6r|!
z?aB)GU;j?_?Yw~~J@#~72~jJu1_SXeEVwF|*^)fkuIHWFwPPWKaYxw2oDKTif^n2(
zc}nK4uE<<Uv^2G;P3__imD=en%M$NB-up37uH9~vW!ZTq8kD|2@!Yk6X1Y{4Q)h76
zlO!2q=O(K`+qDmDha)=~=xrS%Ri)eQ(rh+Qsl;q&CdoNhRkubOUFSnz|6&C)F~;%u
zlw~;%_}c9@?RNWul2#%PC+YbeFr%treMn8V>|GUSN;0DTAL)jfLGa6n9R=HsaRQSR
z37e=(F&z?p#So_H^$>+vE)#~4%+2GHE;3>;GmIGgSdJiCB!<!aQGwnG%t~T1ho)^}
z7-Icnm`hLxaRB0)XwpJ`50#8q3T|;18i7~=`iT|ZgcvKpw#Dk6F^t;4jcBnFsx-g?
z5=Ye0qu;sN4zZOHRgq>&bREP3QUnx7%m;+oCUR^AUj!f^8!MxrC{~&`RVj*Cu47?<
z_c>Msq`O4u?g#B-!J}>t!YUSLAST4}8>2v|z?iRs#pEWeI7xH?VuG*)5<u3u(o{3I
zRy?w-!LFq_RF%U=PS76=aZc&9ny1B*h$sgS?5Ewzc=p69Wr#SZZ1nmZdgkzWEpL}@
z%j7kZB%#~fiE5Rk=@rkAmm3p*1G`!evA6X`2u*zOqdmD~rS~*Gjw-Y<j*@3gHD;!E
zTC4q?x)b6ew(80z53 at R`2_fLUr_pGfHp?)zsZH(tvvL>uy4nG)Gux_4tJNA;1}@~<
zgYv|4?bQa&WNGA7+Bu!kt&Zn*u+Lm7W at f9CK8e?8Hk)H at tQTUxsso$JO4fEU^jr#N
zX7aUl#l3cXk|d$gXk1)d$4JM^Vg)8YU#rJx>$7dgIBf+%Z`-;J6=)x=FefUmdjH`V
znkp6!B66Ha3-Lpc60;QZE6|$9g%)NxAr8rV;M!eqh7~!uifUM*Rm@|AQFR9J6%HY;
zAHv%EiAe`34x?@s?H{LT&mb`pdOebvMND at QeXnY@vL<nU9@$tUgmP4U(dRN5u_B#u
zTHzZ^1&y();z&ghA|e&;#z5vegdUi9tXbmH84?^}aJ;Gz#aT$ZxZxT}w}l_%gte3C
zNTgX}Eh1gDDp~1qojF7uHrzzi16 at KHDyFxhhtNVqv9JN|08*X=-HF;dmK-DwpRHQw
z^l4Q05o3nMV^F5swhy20b<Q>KPR9^-^Y#1q$Y;KUOB{dr!N20~|G;;jo}6g(`W=gN
zEG^8lx>0G=B at RCI$YXr&i;wY+H@${;zw at nUrBy#)otdqF+iW)3(Y=#rHvfbK<>c^D
z4zE1Q%{#w+B!>R{`^9J+Up~a)jlab$DUm=YT^wPx;yHtvsh|1M^ONdxyFN=VsWMXo
z%)IyG1y_H6IWn75o7&V)zp!h^d at _*9vW#}SJ=RCLFh@`6m&d7_Oq at WbUCy^1V-m={
zoq*a)bt>vHs-1M_9IaOCytT0|M?kZkPW5&KL6a4kx_!9WY>p3(i?Kjazv&A<a3<!_
zl`xmi9f2um)ox{@>IS03;E3TQ;*LPtsTj4ifz028OH#xs;`<;a(e13p%AFwkK9Y8E
zqDTy*V4^0U&@pu~P9Pe%3>h537(#OgCXq62phbzOM^q^`S0Qy+)<y7GERZt7+#*hE
zh4!ifBa8wTt*S1#s>RJPqSQjwhNvN8ShtCglFT)cW{Mjo;5P}9W1S^5YZ5~rDK<d5
z<h?!&)+*q?L_|mXhpW`#O$0Zy4+|Mq4v;Lv*4L1YCsAn=Ee976nT5EH#Wf&>WDhER
z%r&9h#5LOBGMw&3T^G?KRr?v?irv>I*W`mQyNkU`3uI}+pMUgIeC(5-L*@Au>$-(?
zVQ!A=_v{?6o&GRqw%g|0UiknozwaKhG<#lx=whF5^0i4K>}|b)X4(J~0z*Ff&40wR
z$DbhEB7|8vrH<Zaj}JfkPZ`J)q=`}lxP8YDA!yZJISo{%c9w)-d6De5T3;xHz+f<-
zEXz}vkZP*5sZDKaFH9h_71PjawZ>vn7i)v^#3+<8n(6ErTg=Y3*=)swycmblWYuc2
z+R$h;Xf~TKI==5p7^g|6sUDxn%3j^_b at A5^C>O8iF-Zte|9r(dI3Z%eh#^)LjTng0
zqZTXHvT}pyH_#-5a#)E#T8YJy7?couK#8M+vo5Ma%m;YQkk%3sL!|)|?K!=f7?BVw
zj9ZL|3ATQuVgXCrXz=J#7hBwgrI6sUjiRFZYIIRw5_`+A(L?5DiP1)s{56?@VbNFr
zf+za2Y8k8B%ZNmuBWa7o+9)Nl+eEreEaZft5c>h~IWCz+e7~wjtsMs%1eal<#DZZy
zRJaSPs-~{7lb8#>{}kkXtSq6?z=kvUyudWU{D6?JU{Sz!U?wOlm?`FskR%lYvlC(f
zE7yr$K~kW3#q8y0t2*r2y^~kncLx at YyeRnXKl}jy{)2zT>dG=P1Tdq>ha5WeG+%i1
zOEel8x81m(qAVHa1#f=c!~FNZ{4 at OWdwz)f at 4SU#BzC^ttdKsG+<M)sXs*2laUQXR
ze)=dM_~uXWsV{y2p9>b07zAIy<4-)wAAb7hd1CXA>C7Z}JiFRAbH~!V at Szx2a?iI?
zG_{w8)r4bp0p(&WsV7sj*&Js9>cgcz^ri#=Q=8fg at 1z6cYRn}$*uWrE1OS-PN)|53
zS$}>uPF}Dv+Ulg&dsmvKSIlR*bv$0ks`lwx%j)*GOR2_eol)a<sBIdj`pmiFIsnoH
z74R6YDl=4-6Rj!@B8u61g)2!HEB3P3B1T0Up{iOCiOG(tx<ZMQ1Wk6r at F=dmK*-lH
zQ3N*@x{MZ4({VeWCJu%xSZau*(9025B0@#+oOsj^N!@O|4iV{Kso{H at XzFmy4t}G;
zlPFp-o2eiby}_6iAdXtl48_U~R9XZ};p7SoOR$P54c){BZLHD9wQs-=o`Gfu3Xe3q
zhy^Hz<MuM5p)-4l{eamDn(aYiAJZ1nQ#1)!*o3kGW<U>vT~C at iigJ}0=8*Ixq;t6D
zZN!yNA;F>A#M^O_q=__dB={A;uE at Q8(qUH-e&l=q9$)_EA)Yw&EUW9A{L4T35Fh>Y
z7r5>EU9_7S8~vOwe*Gy{`#JyPFLim%%kSf}U->3K at YXkS=fN8ZF^ns(+l50p{p(A9
z at D;ztzx=yTBF(38ny~4<%wHb=5kC3U!|dt4ibNY6+xRli4n9I~8+4b1v=s@!TW<a>
zlomx8KJOk^MRj&+m)+{PV^R|4qJkNya59ZXW87+1Uw9JyKaHTLHnj^s7|!=^>$a)-
zHLX at _Te8+g=<{7S{U&d^@&6$AE0nQMh{d)!?iY&-y3lcYl6Nz?R2X)C+j<8vu<
zX=_DBL};~I+vYUfvhaPCcF{J^p-UO7NviE_#mxAU*h<hE8y^E`-A)*)(7-C}N7+ar
z&Y<L^jV5Jd7U$bl#YT^hgee8d=J123aoHTvm(b|KU=yp^%*?73gcynuMMfk9f~~J2
z^E<G90UC(0fhJ{zUkE8>IEu|I;s)!4=s_HAW)boYBx at jLiG_gZNLaJR>x{tM^=IG!
z%ux=HkTiEgKN3eeBCcUbXb^o5Kgf_|1<9IdVOS at Deu*?@2xds$!^A;*i8v^cumQd#
z(F{x5;QQc)L`o#-VCKL!LG~jK%3^>@mq;He9U6PY!RL^eVqOXI1ZldPP!!N#27i)T
z$o0(5`Sz~C$$M-~Je at 7TXf_-C(|`E${MY~MZ}IrI4&!~~D^DKgD^DJ-f=#okMG*M6
zfBsQ^<)`1pKl;U=#0-kEIO~0$k7J4F^yAL-dc#PQChxlE5BSq>{xF;2Ns>g7uBWFT
z<4e7d5kfV+vstCv7F@%VxHfOO at z>bXehq_R at 4TON>Sw+*eWkji;bJ?%bn9VI6venN
zzh=FuGoVwO+SD#jz%%K5*42jX%Tfzv9AFk{xOuwS{;P7FCTV_a8pkWCB6F at y`h^^$
zdOp<^neDV_CBceqeeNsPf`N|^0*n~HBm{!@m<gtW#R!tYaD+>93lIYhoy90By%<yQ
z5s?`}KSwOX@@0a}5Te61XA!CvuX;2r#?iGaZIx=T5d7Nl3R~hE2tyJTWPT^4DItR9
zYgjSB(IiRc at h6`p<Pk|TEX^twvrxUKIJ$?#s>RJlElx(oLWT)(Z~}={?o(XEl8msl
z100ZsN&?0gh~}`cR0T9X$7~MCc0qeL6g?={iI$?tE<#ceiar*HNai4ILOEhGGDWN;
z`b|VUQF}-V;y_H1C?jahiHf1EI0_i}XSrYn=ofe|IAv;uD$($df8}TS*>`;p_uh3g
zt!9I~C>iECK15pW77yNgC$GH!ZbX!#cuv at S>vhkzjxKfoi56LG-Ok%@`M2CU|AUwb
zQ9P{~VScA$akpcBm(ZM#NF%VP`w(xt<^SgP#UEvu_b&<0Gqr2q>ek~t&o8<Y<&@@W
z at BNr5$vH<+6k}GPDFMLLrgr(A&^nO0JguD-o6vT5VbsZw%Y8^qVu{i;y<{BG3;Fq;
zkABN`-D?sfQ!|!bO^4bQ<?yIf*>M>OvtW=qbR<@YL{Jb4G at V7WtisCJ3^F)`n#W{_
zg$|PLhGGR|6HRuZ&0SD#U}}WeAZa_Szk;Ad3~@4UGpqGz)F7IoWe>78vDv_jM_k27
zCP|Y}Y at n`%x;ACGfsj<pWHOJkhIG2bL7(WY(t4?p3{sJWFrsL#xBx0LfS8{oG at H0)
z7ws2_U%|=*%d`>-Et>?}L{A<8i&$(x7!bR&NNx~PEFMR7FVYg?a1*BsnA^mX1~jij
zdSAsz5Z8pbin>K&Ttyq#S0oFYj}wY!MPk4qB(+M%#0<hR>UI*ivZ$HQRfVV%4sU+l
z!@Tb0_j2UKGArwwc<)Kmgr&JzcJExI)yPI?#OZ^At%AXq+GcjT?6?mlbJ?wY`+;BM
zo*h5M=a2n!p4#{@-bO at G3VYfw<H5bZz`=#L<3g9gVE8=NvoneIPVJ>@ldPl{i<>zm
zn8~t?as(txl4N`+)_rW#NjJ5rou5N?J`UvR1TnAlwyD#-hs*7RP9Au*lYX at XGL!G2
z4*D(!;C-uuQ0ZA at R~6oIGHG_jkOEYNimFPYhL}Q8qRt_SVm?&W0nN~4A7O9;iz%W@
z__TpYfk*?@c|vgntN`s)0Ytuu(L+KPDTnxwp-C4jdWci3tSUcJaoSdGWuizhBx?|f
z*sz7mfWuEgYoTHQ^MW-x`2Gr7ZbG&b(ufut#H4}6fNM6;!4Seo;7}_HYBP_dZmdmX
zWgxl=BjpBt%p2t}W?TROAOJ~3K~$1<h^s?<6Wm}ONf$AV#IjB3Zy>%wv>{0=!HRW|
zS=2Iu+lw|j#C#cC6T%Q1&Jn{JtUrcWiin57F(Q!|hqydLv?PXS at k2l(=AS?`K?2xB
z%V~&5APipAVCGEiTjz5QG#e>5UAKpWwUQ}S>t7x8Tu9(_v8_7ide#^NA{o0|ui|Y7
zUqz6L;G$ZyN~UuV6N<dR$NYi<y{S!ordr$Xk}xwhR;FeK3L%hX8F`+MZ}#MqPfkaD
zYEwIhIp^53XU{nghpi5%h>&I3RmUDUneey}jL_Bt?Ofwjx4ULpcGVqzlaBg at VyU)L
z8J}y6YL)S;DJY(NACn at a7xVh<!pxW%;wp+_oPsnFiV;A5B&2DErCro5Vm`-2F<nEF
z7A|#^h2dl;W`}_RqWh3EC5jP!4^1GtCNe)yvT~Rp4qOwnyu!)gs)~sUCZHJ7XcMzV
z;$WF93xs?I>p1WmB))|-x`cccY>1?bL at klviGY@1Q3*-2Y7xr^Ag&77MzqE<)}InY
zYkGi6Xp>?SPlTCSTz`#dO{7>w+zd$yq3j^ykpyCM9?<|B%Y<wZ)f^vAqGU*(V_5=L
zpfU%Xgv?-Y0#ijyz*e9=kIzpaF-6lB=AU6CNB^8Cs962Mfx0t(mX{i!oC|BRb^p6q
zT;Qc9GPbUrGlA{T#3*(?dkw^@qtBX5GRXBQf#R&myvgL<)@Qw{1a+sjtqFh{w|}v1
z*~z2>R%Z_DQcwMV^@O|m=9{OJY-&?Gk1Rv4*E{b+s9sYw0ms$&eru<@-Y>RuquZ)T
zeX$C`FZLMKLEm;C*w0rCm#Z at 1o3zPu=S4keV<d)%y4 at I?5ZVZRNT^!K=z`5xn3ix9
z8VkUV${7zm9CIMcm?aQekU7i(He5xM9f%oX17y$y=a9TvfkV<3p*V>~!<kY>t3)T8
zbBNAhgFYHPVX%U>I)tK+h(j!)>>a{lB*_+tsi850P$E{KyA~*-;+BsS(*{;VBn-d_
zVv&eccp4Q10ShC>HUp_Bq#15N5pa#&P#gtGkl4r5KwQAAK!c*C5JCmqH%?&YQP&}q
z8`$h#5)&*xjFt&TmpJ at ZMSdWH#fm1{!ZMQXK%B?&Bh-la3QHuFXlLaHj~E*4MPKKq
z3o_~!n#*NnSz&2vob&mto7!pITG6SAXfBt95Gaa*qA14WvbDlLwU?G9NkW!oV=U}N
z2Qwl<p658{Xf~T;HnTj>Pw7pcwwX<BYUg*Loog{p9w7AszM3h}>uSJcaI;-b`eX+0
zN(cO(&p2&&3)R-l?A3;oIn!La5?akfBhKvvh6pL*a>P}Fj*@h-xQpP2n6Ba6EJBwk
zMvx({Y=bPL%oD|9+6Kumzk#L+I1jOblt4H^@C~pbt~E!@kD+b>v2~(KrE8ORK{}8d
zs%w~bk;WokhiD84ZSru8L}x34fXtyq)f(ioHo*+v+aPVU2#KLZifbuB64=}X71X2x
z^pEsyYMh;6$cSMJQ8e@@@@Hwz>>=iB#NkOaT_jotQlO25xVeH;p^SaRgtW0lSuUg2
zMg}>aWgJ2 at 2mWcqM#&HiQ9;C2c#HCA#q?%XOB@!ficzQn8c~QNHmw(fmU*%@a&p~;
z5Gc!%;c!S<mY2nUs`tqHKJ~rM7SL>^M6a(?mL++fljr$mBYmpRyZTw{fM)7fzO-%f
zjGxpXyWn7^1|1Iu0~(FSDQyb%p)$3pP3^)r?sGYybte64tTvqPJ#BYJy}njmmATsY
zqPjY>UE{R1DpQLcU+wd#elIU>KfPgoiI_M{N>uw;T*5SB%#nm9k!38dA+n2L9h`xM
zHE>Fl9x{6ue&b0*71I>_8m>_iWCpSZR`dzM;Ytu~Vww|&Cy*o~mcCNF4?Q%Q0XL77
zB_S at 8q;r^biEQG6CwK>CAJ<wUlq-nqV5LCmag8BnEhIE?c}^VUNSPpMK>$MO&_;_e
z=z&Dk1O-AY!33qEhORyb8*AYtzK7pD0_hUw4E23fBPK1Z7-CWqM5-Xj?ZOX_Vi81#
z#Qp%6DZ~Wx&mtqzflB`dh!Ba at w<e>Ci-3X!fe?^rXspN!o(p_moc&=^2sTaAab<ou
z9MbRi84ib+B|w;L(J6{z9L&_uaVD$Rma5{t$9qp%mJ9}iv3UCBsw8>uDT-noI8E+}
z=Q=m1c5PZ+t!ua23<iUXntRFQA=_%T#?Dn)mUKFuaoKV5keS-lrgrfG&DOGheGp#l
zYb%5>K9J7E7k{pP@~zA_bue=+>_7Eqe!fBP+4kP8)vMZpxfbS99lTx$-e9{hGj%Wn
zDZ&~R;A9C=hec4G!K{ZwkCO(NhiF8<g6IqyV^#4ea-24S6nu%f0?Q+`+i2Q^{u+`9
zF)E at 38XY0@&=_%AQ9K82gD${ul}JJA=7})_m!m~V6cBaD&N<?-Wn5<#D<YIR;&OCm
zC&A~iIe?-Gp}<@LD83)j)FIj+X+=VR1GHi^t#B)GM1veFQi3oFz*VsT7S=1~vvdwA
zBGE5{HL;{w;cQAnbqOh#3FSKKy4CZ#E;h`8XVD2=9kW=CHHM6EJc3}MY9}*4!t{*v
zR}jO+5wjel=bhMpUI?9;t?O;io;^JJ=%d_y_uUjl!RF>B{eJ(lR3Nre`<G=oh6wE4
zyZ4OGUi*2iR*R>edWv4JHx6btHa5mV#^pE<>$bZ(fCA`rI<(vEDTVV(*hdl(LI at XK
zKuNY9vT2%*zt%y_wU9NQ+SIPJ1za!U8a#ikWLRn@#7nWQ&d9Y;m6_aU>rCXi#_2*>
z at l^Gi*{dg+>t4Jhnt-fSfe7uYEv)n-fc`obS{0bz7ZoM5UqNVtY!YLFQzZ_Mg0zU`
z5Yr=QoWasII#?$5K+-1WSHLYIUWpt*-2!Hgm{dS~bql~M(F}=!&}f47ut9*Vi at K6P
ziH3k?5siWm9-0mUge1Ydhgc92L46N(En*pPb6uo8i=8-xW^E*CLOcesB0zSo($R5^
z4$%UXJrKpBjR*=9@#_@}T5BKLD~OUqEFgN+?ZJv=jCC~GN7Mq<2C?rUEfFt7i)dAr
zfoRxRBy?1{R%$+iDnJ at hFrXk&Mq-|k7jt`<Y}dNwmRtDjXFtm$k37PT9Xp6IlIJ-^
zQCt?h+}8C{?=3HT*~`vY4XRt>I-L$nOG`ZR$Rq6CyO$W_xWZH8X12Q}w%!AQG0D{4
zy?a?$SQtO=G>~~|S*?dw2Q(LB$>hb#vV7hlQe$YQlWS^I+up;c{&y`U3nr@$mx6iN
z+CFtHjnO1S*>;Z63nk9^LXXp>&ZSEVW{OBmXHY4z!obZSY at +%yf<A@$oJgD4-z00!
z6WkDV2hMF0f<a+eI>78Gc!wo at q!6sJ2rd#rg*Cy0*)aqKO(D$@Um(&U_D_;@7O`|4
z at pDAK38ml~is_J;XNV3ftrhE1mP4dCj!PDZq{L^BA_7rC%RWIGNZ+BYh!iE|;3x?V
z;-+9WfH()T1_rS#(dG=e8K8t at 07XQ!iZDcCMJ85kQ07mgop~rr2stj at M<`EX<#CXm
zh$|}+gM5fI1~>zsEFi@(#3><<I91HzxZTV`MZn+^M=U%d&$Z^74~zjbb%1jPxG71J
z at bJSA^YqhC^Z4VB)9?3Ru(_M2Df{>D=bn4+q19 at gQ^!R_xcTOrSy))$vBw@`Wo6}(
z6Hyo9z|POlbKiaUv48*mQ$(Y$7;5&Zy<l^puF7nSXlAF=!Fx}m(O_d^<CM0uDQ;$J
zQ`<f#ZL;EUt=ZN#s*4Ty>hCWW5O^h9-I8}cL=opZUe{U$eX`<oHV5l+IX#9!;t(~=
z1d|MW9~vEk41tWq8H7HP%@X}8BD=BX3}N#amUY1jB(7Fqc2}_oN7m5-q}e11vy}Nd
zjvU+)Mib{eR&GK%gGm9q4&Yax!MP^UhD7g3G9jAb(hg`r7_>2k=sgmiMYKs6tdevV
z at FbW-q%2TPkf2y%NZG0w*9=r<pgka#iWT5w7R#5Btb@~8LVpv%A<f;ycoYkvLZ?Kq
zk<O;-fH*8sm*AQQC^x=>rn8XjK{N#|h`B>u4{>dxrr1Ug*SZb{hY%-(7*G|=A~K?e
z*7^pusHa2-BLN^PK~b~O{D}Ut&58462&?Dp!Gj06{r1~m6bxG(7 at VupQCGm1mX>(q
z8{hb%>>;%*$ac2{PVMU3?=Pjh;FQYDWDnz{3i*ZhE>CT0Q#&`#VG`tgtvTv71 at YO&
z;B4cxmEGiWI;}7E7 at Z4Wbfz(y#1mbMb7`{TbiNMdcI(Vw3L&qQ*IlTnfy*3`$3dGI
zS%sak0;7q9HEiu9NCznk%#IV)Rn?0CQ4LWghD~%>V3woWs#>#rfuu&v6Oaxz>=Bz8
zlpak4?}t at ICi7VENOwOTaQOz}Am&Ad?~zIv6BWw!lektFvjmAX)$}G3Gt31f%;986
z&~=<OkoE!+mx)2Z&7p~-EY at LhCpH+On<vq1k?7Z}R<|fsWyHXIghVjc!uP+9(IJ+7
zB<TP>Vvz$079w6tT)G>TwW_e9O(@sF8<855Q-S==D!fij4IS%13ai at E>XtOovF6N$
z=vbX^5Obl|sRN1{6ZvASowM!1r+d~q!SX^TkG2YZUTr#SQ at ixfza|~4<Bv-UX3UJ?
za7db_V at 8}>M6=m!PJ@`KO>LVN?&R02oq6hXRv$)}dLUlQV{|%4{Zi~&t)5SI2D}(&
zP<8K!(+1Hkp|TF<F(MWNp5urFEEH&xW4a5~Ht2xhmr)ss$&RWD)#n}&O)8wph+3G?
zfUJoGK@&fUp&Tw6Vf{Fw5uu581uc7cOOf^Cs3b_*g}92u3eTb%iA2C5D#UyfNm`gL
zVg4jgVA8GVmTeQWK4^k3N~GH$79O$|sz%HMnmOq8h~|;z3=}Dv&JhX$RuFAqWe*yQ
zsGA|!5a-%x7+}@~-N1Z;Iwg98&_&ZtWb-RX(j}HFnD3+Fzyc^liKsEE&{)M at W+RGd
zWkd=9;uHxH8xaUpgL(Pp!i9+4ZWYRXG4_`Wecl(N6X#5#qf>k7SWR40%fMU`0l;Kb
zKFNuGEjkiYo7$BS&|K?lYrCA#YqiC7I~<3}s?2nZF2 at 6uU=46BG(A8p9wAY|hX(3a
zsY()xB(7qS(vzsn;BBSCzJ#i(APB*ih^yodEJSdM#T<zONs9OclL4j*u8qrjm{%O@
zNL;{WKpr4<B(WgU#$`>4{!t|4mDr|vOe$6{K`=2SDi#Katf0vbLg=IM2r<l~Nej~k
zsu79;d-hw1G at w|)+%BB- at OeOVP_=)RZ7l6U3^<)7D&UV{=>pnVK>Eu#&9J1>uW at OB
zplHa^R<{ZQZ4J$52}uhnjzJt$^EU)Y1Q9BV>rq9<{D>ex1Y*QY5F#ccCs at I}RV-*%
zm@{1OeJ>OaWjh0lsZH&LvPn_dN%Dz{3TEow{Sd;KS)l&8D2nL>pW4*6>0rAYYR3`B
z|Nhmt;Ci2=2stwXuig1GyyC$Bz_((~?|$taESArZNsAvl_}f_b)qHXDZ}`j;zrfGl
z{(j2rz_uwgY|TnuXh1W0puR9ptnlc@$N7tI{Q@%h2ARNH_WqaLzW2YP)b?d{8YZc%
zFLsPBM_{ay^6w7)cN{+c8+gBhM7U at 6mAvi7-ypW`=7T5S$CnQMDzP|1jBtJHdfs{C
z|Am`*6GqtfHFLIkaJkMV0W6NFw8APj_#6^EA(^Q}8>NATJ`qFx=<g{B;W!#HqIeJ^
zloidexawNbhl&Sm)KaBM4u!`W8Day>9Y8vZ=<%--vji(=A*;apF-fp~f@`EGIia_P
zh9QguCM8B9enhJrhzQQgswy;G9kHD)A+ktftN5aUq=tFHG$O9~|Fie*QMP4QdEal&
zwfA{e)vf#N_d{w4q?Tk5LK0wM2_z)q2t&jp=3xX5*nmwuFtM>ShVU3bVh^xJ;*kUq
z#|{JqgFp!m7DfV**q|7J9w<mHtVg%{ecx5L>ePAdz1E!hW1W3;ZuPz0_fd6UedZW7
zx^ACS=j^l2+H1{k&G~&_zJ{uV`f04Z6O|pjszFw8*+S(29t`3pfi<E!p=@D0XOM$;
zqN4#`RkUbjubL{53W3(0sGY&$0Ix at AYLU_wLJ28i;sjC5fHWIWvs{e<EZL0kAMqfN
zz^z7$0<$dPOtd|nA4{p=Wh~>`<VKxNhwbfcTCLXARc7kCp0}4Z9GU5KItMyS&df5F
zv3Hx{UUD1+ArZN^bw95@^4FN^8t;AT9sJ?xf5DyIm-C0(rW}5Pzx@@*`MEFrFy}Vj
z!%F`({NYpogzviJ$4KSf;J&9qK)YKkF6JY1p~o-OBC&r7tFV)H_~nPclQ)EQzWjmz
zjo;h;Aiw?eKV_wLFSi}}KK84FyAfNt*cj~wz!w^i{Tic$aX@>#?2dm(r~N|y=-hAd
z(KEly%A-HTn_l`y+}(Zw_uu`G=@z%~shtn=;irF^qmTX_{?otk8MZC%88F`6KYuA>
zv{#%N5C{<^U=lEogm4fF!{R2+Dykh+HnS5wj+<q&KZb??$c)hLSvq*;Qt!#3EN7l6
zlKoWDStt)6!_)X=J6qfM6g+^pv7qR|`(g88+!VJ}+{QV-_ZgU)dCt&Y!Nyyt3nqpb
zpam9pkiu|1h7<6(0n;h8j({o2rUXi`LDmPeb4alUHpX-ZF|d%J?8EddR!#_$1ElFT
z+HQjhCK1&RsRGdwFA_l<A3T~XQr5*~it{)@+nMvCo?qJ&DhUs*te{q%&FyYYrKSL)
z%+$`ZG_-pb({LQZ{sEC?{<Dl_?9*|g2vt=PLbzfZhB=sNwOZ$C`Zt7}y>|3o#xj=i
z#T$4}fCEkdzU99EjzYWiLziDX{m(fveFXE0H>`gf at 9O+4|HCI=Mjz$&7r&QZIQ~vv
zf^qlJA7m;8(QA at T_Ov>4H7aC_KxjX!GeH6mjX%lybd!5-|5jdb at NIl;_sjU7PrjSM
z at Z;Qm_`5(_`v!FPqJ?T-#>gXYxa~(Mw1Y~)XVW&1oc&eQv(Lv%`>*D++T-~42iX{X
zg2PhqRd at UZBd_<=gMD#~F7_GsZ+<w`0V`vsa!4E3DP9eba1?BWQ-iF5ZbNE-OG2c;
z>WBtIy}*1%PIm#7YyfF99!NEl6;6&YK=cq6CxlY)l(49od!u9GnTIJPf%gy};j)gW
zO;kp>6%Z6 at A4Y2>m4=MZ;@W~>cwJ|J61P#Uk=C84J5CQt6WnSfZDZx(>~)hORA(T9
z=qi$?m^iY%gZMT{yAX$H2x#hH(-CSXp)RmALW(JFf=t?Ys|7xRiY%DGSs>(!isrVl
z+$L7xv=BXvS0hA^;PGjgJuWfxXPU1E8slLQ%VW5o>-FVUPnU5m at 7HDA%yS~8M61=h
zViAC1 at szOfa}bfadFFIFos)Bxv5aNxZIZTUivb`~Vs8A#iT{y1cRs|u{a11SvA at B9
zz&l>?=Zw=f{jkc%Mh|i7#Lx2GFZxa1`I&DZj6ccOAO1dGcGpia;>POj-tUc1P&VsR
zbOlU17*0R*nF5~9As+V)%v?>PbS=h7rNlh(<m7WabmE_KhZKDMi++V|8`IGiA07Mw
zn@|2ENrV;cP=uANM0Ep?)8!r#(76i at 1Coz%0Tk5wcz6NgUqI3Zi8ku1xNPGTv%fS{
z0~Gh*@dP4HQc$xQ$EE-`qC*iBkD1(VaflWL8hUt2xGNe~2pX}vg|?@Vjsn|wQ6piB
zS3Rf`S~ybPMI4TB8KdpP#Ezr&2I>Wl;z1!s+=pm7i4^ydsxKgA7n`0#rNrwqNc$+E
zRIEOL_!iVP);WU44JZ;$iNr0``njF06m;CjeVi5A%7}&oq$qgUK&$n9<RYW2U{(o~
zxsoE5fLxslVFhFrt2fbNjZ_cN@?NZZ48btByxIwwALD7(4k(D^f8Pk}`Vz=o<HMI_
z-1K0k+wC%$Os<#%dY+nDQ4|zKL0#8WRW;|)EPZB{v5Y-V6lYb?JyWwn7}}8EJMm7A
zpZWz}fA~B3>iho%+g>AHlf0r6dYnz${2z~e7yt0ypW{8-zsu{2L-bz!Z+Q1ZU&BwY
zd=;|(R^02oxu!kvn%VDl$1#qz?&2d3!A2Ak*iHkw0L5Wk_Rj}suPQTpJ(n7AoDe>_
z^#Ok8vA at M@TletRmw$qt*8N~(YODDE+kXtd^T+t`x!>mlpZ`w&mxsTb|LRpkwwXD&
z at 6i}ti+OOddy48L$qh$A5+s3gOt8<97-O^$o#F_|`V{2^bED7>9u8q~2QQDJ at g!0w
zJQTSa6C<b)Wai7HGoWTlN;`y*ThLs9xQWRDOloA>hp<U#8?n3%t2YTc#EKOp1f)6(
zodQ|?QqtMa5!!u-cVT`8 at hP5kR>go+4+*WOKmuu;4Le=3%yOEXK-#w>+Jji)oPqHc
z6nBG-^8nc at Fu>{rwgy^&7l_ngj<pXWAwfKcmFMv3AcHRpxH#GvU#cQzhzXVo&;cR`
zu;K-1{48!Ya17CNK$R<6A>dTtD`+UO`V2N>EnV+eltW$un`a(GG*Z>eoN^gWG~E1#
z=5i(XOtE{SH6}}qan0_Vad~4dV;Ps1h&>lyWG|8~6XAb-<og+&`yC$aJ&3j+;NKnp
zCp^%5HHTNfhUiAb_`r#G^0t*%(>eThMvwk&db&n893}#_O|m%CH87leE}xl8d2BBt
z5_w7IL4Lh^7yt3xzoFfE3BSMnLGDpF)PMENM`WM)I=eRWOYu<I4TPR;o?R6{k{18=
z<U4uj>7U}5lpI`n4S%@tUe<Jlmmc|k{-4wDVkK?TZQaAu<4+-Ji#y7r<P&z^H&v<U
znh$%$naMy`fC<n?Yy=_T(!tG0b`F<-hGJHY2?VK-xP~euQ-mQB)}h)#!fgaSM at l=m
zmU&-AP!mvqoXm at R1{HOU`3lG;!V0jBcpsN at s3=yI1fS%VtJFhEhdKi!F~!e4frb_`
zDj-z2^l&0UBB?fL_XxU<TL9gHXk=lqtQzJfFgk&^)^X`W9g%PVNdiTI+ZK}6AoOt=
zL46j{!$|04|CuDP{ZzglQM?}DHiD#C%35apA|Ry-u>#c&ZWSH_x##Q)vrMN#NO<bc
zTJ<V0%b&X_ at H9d60G`feEF<U7g}qusF6DK01DWMP at P)z5^^&Y!#*LXLHQ;tU9<#c-
zdPT2OG?T2ZYeERLTCF+hay%YW6vbR!U^(%Yv5dV-;`cIYoQF1khnEUGJo+>bkKTa*
z<!wL0vDMcRF+Ml^Q^x0hi&wnx*Qnfi{m~!bUqAYN$fw at T+YWy_E9>9H_C8c)ZnXBP
z-QPz?+x*Q3-pg-2`a?YN_}^zWwD?c%`5BHK{0=Jiw+H`nu5<DEi|g at zjFE}(nXM1d
ziWS>Z at dqb<9s>>)tGx2)-())t_{fQWMqxt)c-89bc=NsgjDg2JtIAye`_{obBpsvT
zh*pS|gwP^Z5pM}-1iPP57R2}{=9<;HJmS&=eIZ&rilr&$y;=Lj5Ii8}n0uBVcEK$o
zp}++!Z4*KZ3Abam1Gb4tK&3;nvxH(DADu(H?X2iEsnG5n)b&}4D7e&!9l*j4Fr7`B
z!z4S7wtB!pEDaG#L=NCBLE^a?`_9pjy)dQTBy<wiK8#o&(;cV>sH|eeCL%4=4`jtL
zJA>P8P#%V~iCaR;gpIclpCUyo^NAb^bf&aiA=*Prg$U?DupO`|;t7ut)7&xQ^$0kC
zv{E)Pl@>@uIDq*k8jg^vC%%Yg_IWM87}#k5&GF;MdF-*r=0Zx#_+qqLE$+ViZeIAp
z7v7S_(aX5J2qEC^lx2CvGUi2d6E>hFr8GCpTv=Jc-RFFoWh`SES0Ac6cU*2NpjWlY
z;*{?E%h#r7C~qaNnR?z#U(){y9(>s+i8cnD7x!Mt-+TFIaFpaVTRz>hM077WAd3o$
z`weRD at 4k$``?8O~ESZa5QSA}1doD0 at wd2$zP<tuQ>^9{mzV!DwPabME+qP`TTkrS>
z{FOU at a-KLEk=my0b(>E!53Y|ZxPWaD{7$elxOY*HSXH1QVcx|jTSz!Tf~-sy+IZSQ
zq=hhn`XSr|rzWV*+Ne5+PY}^OddZMzSjf7Bs1Zc*coLO>(!)&&z5~)m^%!w-iqP&s
zU8A*-WI~!eNg->PMbuaDVu*XBSa}g?`UK(?$?nSFC~XrC-iwDd{Pdrq?L!cIm^_iw
zf(3O$n~cHMp*sLK=-x%#IZja?!QyEo6i962*1_!wsJdup9b=4*M!79b18NCNS!y{O
zhXT?eNFYt>?8j4|M#^=JEr=}?153Ex1Dr+J#NrA{jmI$(?t}6mOa~~5WQT!kKUa3U
z*gx{fBUDwzo8I)Mxy{8gz8Is?h(G(YKjYJ%{xq+6#VfAkJ-&<^C1Q+}WqHMw)cNjL
z6va#xByS!~g{JYCS%R5mEMxCBzQtsAuVQLD)VqGnzj!KWZbTc+6HdpdY&3tKT<7uF
zofurxYrv^(JR7&+p7DmB?K3X|zGrK*yB>21SQwARpInJaUQ^p}{{NFr*blzKZcBh?
zlV;wZlZS}d2C9bu#e4`dB6*3VDH_&rAAnEu$G6kCv~e-4cHAnUMinH26ri#S-o;3m
z=eBMSS>a5~@s#pdiel*mmIj#iaSgbig=#=3SMe%lev2w16-o<B4xz+-3#Ue6q_z<r
z4fC2%D5QQqP#K)Yho42tRj5m(5VW{Ii-{CU&>7D at tYLB%>IuYg<~&G=rOn(LR-eUn
z)_&%aD@!s!(l#Ok9L4ZCkO8uanH at x>o7+svgLoQ|Mc*PKE4WuA?Lis=Bi!<M<pz)B
z+;#u}AOJ~3K~z1#wZQ!>Ry~4vfmwuNrWm(J^W#$1qQ$u>BAhyPimIx3-RoYr1Tq&G
z%NQf7%9nrnmlI>;i6@@8VmaPr+!|5W^&HGzX=~=3Gt->x6-7Z+Rg`5p*L_~xc$c7N
z8Ozw4jqp~zpBAesi#_De1z;`}?A$7IV^IqKYUj#cS7vU+Xg0fx&7HmWnQ?arg3A<>
zEu6!sr<sD*Hh2at>g}xPl_C-nlD4pLFjraJaZ1!S at zz)3@)Vv1h?EG$tQ{<o$THyw
zs5>zw)Dlv*@N^2K23f^rrU({Wm~COHO;H{OKZ3;pq60{W5M2QuVA4f4A4kg;BqOB>
zqU|i>oOXZ?#C|rzRK-(4;BH7y=6g3BMq-TyAx$9!#daP+Wd)zL(g{7xwh&o^a1hlA
zR_|cd5Di7HSb64AWi!tyYDYm2;IfSnuzG;#F-SW&8;Grdcaby!R`BX^#Cx;qOHJ|)
zQX3w25Y5VPB9b{Z7nvLTwVp4&hpO_}V~_Fr*S~&WuHja=hwHj#GMO-)PPylvdwA%f
zhxn2&`4Un}bI$fMo?m%V2!UR&M~v}`tzhQ6UrLE~yUlPooNtPaAiz?Zc^S*tyBqgb
zCqFi7HCOuio-fj!jcUtYjMJ?;mzp-r>y{8&Ktv&p5IGIu04`3p6-|(eEDa`r_GVR;
zfcOqVIrEYkgO{ZGQKZ^NX=Q~jpCBeP0AnDAiOmc!4R^sT;RM9aAvVa;&Y^=<8<0SJ
zLW)m=MN|*sW>_3zwvEvR-$u$+Qmk+a)K4REh)ape3Q`5&3{tLP?K=R&8IsaHP#!|e
z2%U8#tRo>}smMYEzC(~hFx>(d#KCNvB2;)BK|RUlp`K6-6(#qT)rj8(6cDzvnpst$
zp at Zr+&_cYA`3R8-NP+1X(Jsg~76L+r*cMW>zywK(YQUugeE_bbynJIe-tBhx6ky*<
z`(KQa$z;OL&dwavG?pOCcz#BVaee at L)ux$cS+c#oO}E=UPbSUX=dEVTSjIB0ezV(M
z>Ackz at kQCqD_J*oliP2_F=_x`jPa_+=~kahi;2*+&%R;?6DaOeT+SeJ7-1U?UGRYU
z6tk4gELq2N3^vSC#oERhBE<?}I>194k#SDkJxdffVgo+&TR}AQY1DCZR1GsQHt?{9
zR9l3io!hx+4jxZ~-iB}+$Oc|*Abt;09Kqt_sN9LAQy>X(BP7LwK`{XD;$9&tc$#8`
z6G8<hcn#j~gHF(@h07E*B^3uqqitLVxh>6mNGniJPl9Q#z-X?-I6z&`%&^vQZQ+a&
z)}eC at -}x+F?4Z^H8RFhSwZLo(w;rKzhy%=eVB28hELz|Rl|F=x%wKAZNpGOU{kd8s
zpKoDi#2Bfnit%_%RaNsftJyb}<MjNC=Flp}c*Q*8Ihd*Ins&QAFZDI8A|Zq&YF@@N
z_6gM7YSEmm>~1mJooHW*JoRo)$*r;mHL5Mm?-wJ!UXE1rt$L3%2Wr=i9Go2)bHznV
z at G)*@kZ=f+VlqTckR*8FphJ}QOqqI|Wrejvsz<1-fK5sD21r0Gx70`onGhd}nXt8?
z4sKZ-8Vg7OT+q0U6G(N;eHB5;-E0Pa8quROx0Q9=+b9v$72HlEdKj$2ZHr_hRF6VD
z2r|grp792*0rlH5 at Ua@S4Lc|BFvYD!pq;OInlR21=!5lft?}t`#0$VsOSovhu4I|#
zqG8tlW_YR~jvzix@`{ikMWdia(or4{>)}>m(GeR%8lrj#HwB&MF%rXBBj|+W6-+)u
z9;|1AiYr+^_Uay6Cg{(U%1$X=vD^DHZoRoN9*?goFDiDUqv>=?S(cP#IY-dDC*v}f
zv5c$R#CG at j-%5uCjlANeo=iSlFZ!)$JlB93Gn)gx=K?g(HAc5$!lbH%5UA_=JaGJM
z_t>8AQKCpF$WD{s5hRo-6HFb|+aPpMdjw16>}eCwK5pBfvkIg4F*Xp!h-;Q84h7ik
z-WMfHLC+AB&-fn#o+3hlsNx3ViEK}!*_ at J;Tj6{PegX-{py*;+<7tOfRcN~l>1ia~
zhfw1(#(k8v>U5ptr;xIXatP{Ei0pu^AUeYR020A05CzmC&L*Mg;l6@|2-VZsWYlKK
zsWwv60Z$cD^ni6dZf3t4DTr~C5EN}Go?0M*7&j0(2)2QXpz2^lTuam=&S^xB0d?jM
z6$MuBKyd&KQ><8-dmQba3s*8PF2 at h+V*me2IRLjZplQ~=rZRn@^==u at pE=Q}m^GF7
zt7<cYT%Bo7!y3e_s&k*2Wh`SEdz2&HqOCzq#o=Pa|H~btX0f}K#wdjF4D$b8jM1$&
zPK%tP>z3TOAj$9q9wMSWTsm1bOeQ3InjisBiil?!VFJPcbPduNQJb|-4S at iXjWKb@
zEi$vJ%;u8rh&sdu+)93)Cx~@^t{GYuGr at t7Te&QO2dGDo1h;Ke6Rdm*8a813G!hQu
z at eAND#4R9xmgGY;-7^CPtC*igtTC}Wi>DXjoX*nBGC^zrGA4vWND_<^OJ6{fW>7WL
zD-)NQp=U(HL9ioOJV|K31h-A3+C+mQmS$~fC1y_|x=OO+lzx=t8 at P?}XdqQK-~?iP
ziXz+&bn$u{p~g}xx2eU=3_SO6onFTNAMPz<IWL;St40LiiouMkVrFxR=E-D2S(X$<
zu^j1TEMuPl&8 at Uyx;yQ5`#Gx(mzyx$YA)Ih!ErB7Y;VP+tFZ^Tu7JjCOp9D)uyxP^
zl_6*kv`=9Z+y#O`0`(5Y0H=jBL8K&;-UnccW4XdYn%SYui1FqiKJ%b5P(elKQpTig
zZSS5CAsbS<;O6-`4&pUhtdV4hh=Ce1-N31`qM8pe=_B?SqDR04!XYf3MfJr<dJ1(g
zw()e3#GQzqB+!Cl1YY6EaR-$V&QaVxlfjfH#63$Z=RUXmS*44m4x$yRZQQpoi->`1
zMY0|$UCcH?Rxlf(dW7gB#K)Ne6LQtcEFmEfLW#?1L~g at O5c*&x76d|PUYWTO*25)d
z=9%NM7YAL-xV7 at 2#unykR5^>q4YuLRG-aO)sS+(G;4+qRX^G{tZDPBhb1Sq`m1Q|6
zwKr{Mm%<0RR9WI%!6{lq<`sv=IQ3FN&9iZfZZ*TXcDp_QT$eINyDL<Ck#qr>#4n!P
zm}G^NHgUZlm7OdjECIt1X``(YODDmyWHS=*G{}B01XO2ac(L4)h0W%)A?{=!8<3#6
z%ghW@%|?~Zto2MVcT at z!5os!Nj)cQlazbH56!j9blZY9v0kaM&H7+G?TcGQx51_mc
ztB!*QM0N-q2JIs03}RqqM7>6=kC%eP0;7edhcj?!aCDF?!)#y at GkD=3$`JEy&{ZUD
zA}NuyCU_4dV15c at jCdcFqqq$aKa09z;#mpJ!9uQJ5o89S&Y*gG21mics|*U+d%5ms
zy9XDm?3de0`+Nj67uy at 3tEF}sw`Q)?bQF|j$#^`zVsEB7m}%TM%d(`dYeEQ2CKEyk
z7uEM)#xj=i+==?-B&IiWES{t{3Fwt32p3CMZ+6fZLZB#$c`5yJfXv0JFN?gQTS2N>
zMCKJfGkZ?&iGBU7DWSH4p)-l#f>a+zLP3y3tPG^Y)kzExZ-FH!){wM?#}QrxaL1+z
zS|#cQo`g`$5`VG>i>e|S8bLB_Mw at ZZwvzy6Gv%`ckXyNwh|5u|ifDO&R2)GkCxC?2
zhROsjkKpxL2nkOG1c7=3ZQn<#9>+c5aR&*<&;VX<1B!$i^avjAz_vezgd<ssx_)wY
ze+wd()z=)%9k&{n9zl;`wvGE%7Db3-kPe=92-*Q6l6G*WI4#uL7-tYhxQCgjf#Z at e
z&qkRlj!OoGR!=EfliarF32ncalpf#nwfwnwdzZ?K+{<}-v)<>sMF1|xZ)_R2Zmtw#
zoMVv1`F%N|%^x-noWtR8zJat_t at DVy%UH%T_80uztkJZjE>;}&@^jrPYf!J(I}hw#
z>Swyt#r<X<BX_6M>0DM-W?!S|;JOY(ydHuDilWLA#srFP2PsNKN13l8U8FdG>Lz$a
zQM6DOf(Tj!6hqP)!a6a5WhjHFViqxrneZQUUS&XLqH3P26hhO-WgrQ&BcK8jAv!_2
zXaKP(MNxwEAk~=m!G{DXfrE&TvG_Sex~OSxoeOO+gW!0WAgp55S$y&kLAr<xz at A1h
z8r=d>$rU0o#1kStRPQ3zTWE+NeJr%|YuOf|TtQOAWei~lmsVCy(<#ajG0$8Yk(p_!
zpeh8-zxzxyArwbYDbQd at 5fDEKzQY$wMYrbK-Y7qfMx&d$BD>5fm$7)rmr|M^_Fb_6
zKqIHx7-Ys6=ZVR!?kc^EWnAxA)Y-ooH>c(#eZPRr;=*<_pGbDQT|{KwhPT(>^<wqv
zW^Fwyiej#Y*Zf?^Zw<A6CY3YEid=P_!GTXP0jmvUg1SSoh8ZZ^xJ_{nAYZ)xTxB_s
zN&hm=#Q3;L2!@$wb+aZFPYH8FX2Jq##*4`;8p(je42lC3g#(+o9KhoS47V_Eq0+*#
zaslQW*;taJ;45f4iFu7zRp#o17J;Kk8e`_TM1+7dLZu6S7S}br+61W(QPjXB<thmd
zmN_!$VJw|NWkRYAVGU^EoJB-PaSK6n`<n%VcOZ>$-OOSDDw*_;<H=w)pVO>DA~+%|
z7!}cKR6AH*5&d))L12H at o~u2G*<G<8kH-v0V^;b-`kgi=deOfhjYc at aTCa_vOr}Fl
ze(K|F-}lwL_MR1z`Ax9~K38RC8PDGws4Pn+lga$R?~1 at oQ<>@YdV~<>fTk?Vxq0T|
zWL(BFmT~DD;HCJ5xcf8Q&Tp0^y;(Qvx;~FDb2+U+m-?A+Rx)i_mUADkMKE)zUNV>S
zc^65PH`6$Y$h=>=8K=u_SKLd^jJso at Mit!qS)r?FG<|hcTVJp>R-{;PcXxL$UaZg}
zp%izgxNC8T0zr#Y+}&M*Qz#bPU4s=~e((F<%34|Xk8l&toik_8o|!#X3HX at HDnqOW
zY?s<$xF$%da5ABxR_d`dk(CJHhomJOurisk_hUk^!CHSSNelT5G0laZgTSo9W4OOy
z1B+0C2`(Ez7v*O3w>&sXIM^IYK$*#6<decJYD=SD2PA#)N~uC5Q#RVZ0Bv}>r{&SX
z0}}njg_#xLcfDe~m|)>e<a_lG);slBM;OPzDSbbS5>bD_P&%i=xjqp at L)y6sR;O+r
zA)KMnKruvyDSN%_7s-0b9cUvBIlNdrK75n(#~qQ>Wo)eBy-J&oHvX7|ERus}6!FKT
zjor7WLZ*imDnFEsTj>bay at NmQ5(nHBtY5!cJ>Ecj(iOXJS07Glx^g^9&2RFh_6N4K
zJI at 15^#8cNTPa}P|DYbTHpFNGrp2>?#Le&erTaRsm+?xjdYwArbfsQ>-3LwA=-Kbs
zr>55EO;)m;ExAjea9JwA at Ow&qvD_ByL3xuw_SnZK`vdtH^5cAfDMdnA2YWh}oCj at _
z#Otcs?ApciN7*Cr%hQX$_nVv;`@$@-Z6D-fwo!dW0y*&vWk@%NaFB-NsTEKKGByqO
zb(k+?nfnyVn)__C-^XSrehsP(SJ8Rk#ToQ{yqilc&>JxK9S+o_-l_&M(QZ;UNT-XH
z!#5&hZ7m{9ZB>)NJ(4nh=ErXfUMm$ou%x!+KrFqbqG`5-h?oape~8ADo8I)mM?-uM
zi?p_NjJLf+LqAP-I@${ovOJG%BH3-Z1)YIix7bZbr2Dq9IMwqJ>cfFVY8vni`?71{
zNG$ck!6IeTUsgyJz33v1<>atGaDZCO&~$rgx8dho4{R-U=>i%@1t48Ss->SxcKH0Z
zLj!vidz`a(damED)AC*wDoGn8h at H>Z1Pea2tmZG- at a3Lf-j+&^NA#0Dbk~T3t-1HR
zd#({X_eV*;4xm|0Wt;F;F^A5bdFUB^EsT!(T&n&#^_}Pr35DL*{B_%gy0#%_ at e*x9
zH!%vV>Y9-BbnW at 4+fu2?;o)KVic-aR@~tVc3v+k(yAYIjDl_%5L(f~bEF1 at DaQtIq
z1t=krpS1scpW`qiSz^w7ohAF1%N891tLoI4$r9MrH}FJ!a&(iP|3XIk?`5J&(BRBh
z$n{7eL8n3<7UI@)ojwJ&V7U{W2=__&wtcd)^1-0lM>3?_j-uyCB~919R0HFElpYrl
z*A{-~7=9=+IAuZ$tec?Q&v|Jv+|dsr%@tQ+VCr?StOxD{04iht0?go6m}=EcliPT3
zHQ&oI^~xmY(K*8%Pg7TgdL5d&D51(4Ah{^YDc_-DGS#^O<_=trOl&e&5BU+<#amKD
zKqK3A;RV<}sK2MTv^HH3w)BwMPJiidrzyFAh`}6e#yP?Lo!A(c<{-|n*1##FBWouu
zQf5skJ41)ck?gp63kX;G=Uwz?phUo;?SlXXL at 5;%gHW{PJh*$LahYF=ePi^J9vBt)
zeACmXsL=&N83_B#l;FCZkA0nM^d>>MoITfbz~;3YcrW00=&EsbSQ;39 at z^U`^SIyQ
z`b^cGvhmpd7G>mRmT-oLebs05CIET6V){Mq4tcrn8G?2nO$h({OLa5x_9Aq+4uvbF
zd=p<?8-Tub<!$!;`RsSAyD?PbcX$(<^8Hd<3e5F-+A<e&l?*?bq9Hk!@Oqel`=QlX
z=tFFhXV3F`=dpH8dpHVUqLrj at YmDD_Q9Bs4{*qC0AX?0yKK7r3tqY8 at a-|Y1ep^2u
z71AnW{TC2usHtzywR+)V3uyq}I+{z*AGuk#tR6INo<Z*fU4PpMb<D!60n;igE5Qev
zh!2ioVT$8~AK|}HM~4yO>fj*!WsyVpRIpGaDx)Xsj*=c~eBgXx)n at KsrcW&@|1AlZ
z{0F`=S_mV3qa_ at p)eURg(8mxuE%W%;O4 at n^A1oJCc`CiW0;{>6W*3JYm&lWk$XEeP
zQ@}>y%zxjBaiR&<5Uf8d<H)J}`rt-Z7 at _}xI6r^bHZk!hsvIBOHGYyQLrcW+Z_wN_
z97lU3p<+3DAK93}=#E(Eff8zYbnMjf7k|O+Z at Uc}!_EEYNd}ZdA0~AFQ4)FY}QA
zR}_FBqhJl~E&0WxqPHR4TiiyJHLyiY7kY+C`TCbBqx;ak^Lof=xbWm+M;2D=xdv at t
zCCPdG9Pm$qYL6^%U+AI2C?In7H`gV|!Rm|vN)ve0bCAB_AvBT at 7?1rDk*p3VNl}x$
z4(yIdpnBDTJYV$0 at de)2Jk-2p8Es2--j;g(vd2;6c- at 9}hdO!5j8SzxQ(b<&cm{Ai
zmQcLzJqtc2z5Nq<yyrTq^|n>&xC(3=oW4(M>HOi at b@J`yA>r+TkCKls;PoId_rFP&
zutNApz0-S8+aLP9beFxl)>0!FifPD~uAX7{p<&OZ<(vqCfxcpf6y1+soCG`fDecQC
zgtWo{dO+Y<(b~jrkin_>`N!ekZE0jKpYd^gx+r0-ypob?1p#e&cOUo4vhLcMqsf|A
zmTa32?|g1-!9T&p=>Gd%O49Jzs5)CZ1)^D2&G3}2^0Xok8D+V_ag>8|I)c8bKi6yt
zS(70NdYD%%xbF(WTSI~g at z_I35Ynah*O0OeFu&`5NLpP16KIsq@><|cc at g`e7f|QR
zM$0zd(XQnMwf;DKe<}R8&u@~3`so9E0KE8CUBWXkr1^5$ux5|=3e6HhCkYkkMNJBl
zP8AVR3VwJ`*kVPVJ&z<3`zTW8Ia3?WhwROw at 09#v6NalH3r1<%#^qD`K7GA_*&-`$
zQlgjr;Y4r&@%PGTxmD~Z2{=cuN|(>Zv5y(2E8edLtvcBt6;J}^Rp1HOMe_bP)5Ca6
z01AVI;i~}lHALzaQPA+8E=cm9rbm2NxKQUdU|=h8L8L!8hY2(&mx)p5({HV1MVS<|
zAm(@eWzy(1S9hN5qIV1Bq27#uD$ob4g2ikHg^VD2R`IQfD0`n8MwcSro(G~!Jv2)l
zw7gv<Tz{>i>%0<sL*BS+Vq4C-!!0alg}m$w-Kg~3s&w8}Iqe<J7Q$tVdnZGC-eBU6
ze`+kbi48m|AiUFlukr&Vj+G|W8GH?1(Mw;fGR at 1`C-!#rVI(D7qQT^bP$~Z8q<`UB
zAPv&u;^O|&-!J6V`}F^8Upb5Ubxk`p%du%c^laoA>BhRKA9hjBmVG9a=V3zIK-ElR
zfcXyyymPUu&Bi%q#Ecg6Vp4kuEe(t15c`>VL3;uY8ohh;r%(wjtxcd01{%B&lQRNB
zYg5uEy5mo5Njx9X(U4dA<{1+Sz!_Bb=GAelSor?$HMQOuR&I&X76l<WR{-qHuBHKq
zjnu_E!V##98M<Zny^4`VYpg`*^yGuf{oi;&8-AACN3K!Uv-XQDShQ#?SUdWOrt&kA
zX{^5n{Skk<t4?hTGAKno544qAR5UD!rL;*cBjP8Kw5Z4wPGZOq(9;f47{9}9&R1=H
zx29`pP<-mNV-bv3w-9VvpKfaDYf2oD`zws(>*^|o5Y_%o;Hx*~+l$nuXK3<vMpf;=
z=fJbC!ks>mKF|0GlHMU5MFoG(f3Ys0+PKB{ZO-^{;Gntrvfb)m?&6JzbnEbuW}D%f
zbm>}3i`y;p at vV`^2<)^DlR;k1IxYG4k2Jax@}5C&X{#GIF at 6K^W|^GdoXz-2uQo%m
zubBd`nL6*AYTj+`P`wGaYy^mf_HB|VAI(`=k`To(P6G#NbdfAcFXyrm1XFsprrB4)
zFh<Z0Ju)-ymnKms<WGc7g}dRkca;b=5lj(cbE(nUVA^`+f)mNSdL;i-g9lg04q5)n
z(vjOf0mzbaUFpoi`?K4e+mAUWy%RzDoN&Eu+eox(yb!{o6;yn=yxrY3%vl7j-oJA0
z?@ZNV!&4b#@S_w=qswJ%r+3qYaCpEu_IV)hbG;lkT4pVYxCsiq46O$w<wR4=xexTZ
zb|IdT&F at svzN0RY#=zGFO$a{N)KW73S{XBzfn{ZQei~@com%XS at s9QMZT+4aPRG3x
z9)E91D5C?Q*m4OQivBg?yxv>%qm;!uAvVT?nmpu*AJ=~PPab>*>pm2Bh=V4;xWw86
z3yK?sWkIF3X%lISrc-E1&!Sn9QBzlHZJBW1C(n%+QvdI0qttI_V^3(~N}_TlwW=ZE
zszM5i1%bZhY%*;;oW1<m at I!e!)(yyVdWjZeuAo^*=}Ggw5E<Vek?hawS_4YdeqfXS
zpeOMi+vy=Q{d&sCm&-G7<m4#t0Z+0N`x at GF%bbJP#U8v)PI;@J!8Tti1@@KnOG7dA
zB1363-|MB(5#=!czKnuK+Yg%o?mg`bk^LC8>eQ2S<mS^SVFJ~I(UEG}ma|6t(Z!&w
z`40I)F!E*@tGp(=q94gb>u_D`UoIafg9-B*pf&0F$d8ra>VuNTR+ezUzQebrolH_(
zUpn`mEETt|<lFUMHNc%3flF7<@%p0qBQRTh%*|0a0<Skp7`OZf6q>#0n0?kCK8!0J
zlrmpA!uZPEEs at h3j>8=b3N}9{-_O?PQV<TG($Fo>Xe}tY&`G7?xKy7K^YM*?`f0GV
zLUL%8gxJcw<tzxIJDh#-m*6cc!uW at p^3>?<=&WHvcAa4h<FxQvfL&rvCKr?|?GXD=
z6=ddIDRj<X$#LvWF<- at WtNI;UbCA_g;qxVKLX^F{-oK!7kC`GNtqHmOMlHx753UUz
z!iff#OJ(-OzW;!dFYOnd1YiN2(MXP0dHgWNb?(C6!!P16=m4CMedlo6Z?fII%$G!Q
z^rdimo7e!)Hh<C$4jnl^SnWA at _TDJ$A5TiZq?5W!cvy%2+wi+h$Sd$%O}|d7F+AAY
z_$TYP(enyN_0lD^`O^qGDgLnEVgjw%p4%7LxR-s|t%KfNNM4l|y-K|Nm3kti6koAo
z>Wr-MHJhAmo}Z_Lc0RCqr{J&oLgCL at rAA7n?u8+eqtMq|v4 at z7sIkEs>pWZ>!{?Qy
zf^t>HlpCZXkAyzMFCA$vCwro5Vz&iqLj=Jf7#S!<@%8l4=nJ!ca~2G=rzawCWOEvv
z{i{C=fvlZQ`ulJc%pc9bwk-rHru0y^f$=o0raRL`U;OB+eO!)u=@Pv%tZU9Nj;F!9
zW5F~epozoFw-3=q?px;PS^$E!_L<nF9i(I9V&1lC|9O0S+VL_#;KrEC-!f6|I_xi@
zI-Ex2g7C)~EX&o_;0ohpX4x2g3iB{;PlatRz*I1P2D;2g<HWCj29=uQKJJf#IpHw*
z(9EZ6I9U1Vqc9vxBHzX0qKSF=;QEDpMDdH%3<)g`q5kTn6^4M#P%c}G5c9dnZH+*K
z<&EQ{HAkUQn%yFhoWXZ8V?R~Kwowm70yTTgkdLoAI+a5ls~#m5BZ&l#f4H@>Ky=Wa
zmrdkumO2vKio>yCDUp(pTtlD$zErL;fp2m{CaIU;iZp4&B`e6|dj%yy%y&!Qrf!3A
zpYDf;p;%tNUq?6E8+QXpxG7iWk{8%L+i@?OY(GR5+7%7QTmJR3F-He=XzCKw-N9|Z
z^f$1a(4&i$t}phBb2C)!z_6O%lQ&nx$FvZ8KK$RunfJ#Memg=va4ng{IiXNL1}Fbu
zQ{;{7d!o<yCa*7JMeW-<e`Bgz(&rVLZ$aL#ut at sg%BaSiGFKO5qf`(_+)JBaxop`C
zW0)ZOE$KBDmN&kQ>?*MOXM-$%se&y&e(I9)a;q<9jzyTI%W!6~H at 4qvmgt6+w6&kF
zbJbLUz_gnSE1bbK>#*mc_n6!@tpZV_0YRAxneD4*Qyac at xD7<dj?bdQmd0k{q?`_N
zC0 at s7^=QArW1=`hvQ at JE!8C+sI)o{NgRZTNm+ucvVx^br#|m at CegZJehc#?otm{?i
zi$E)SpMT3-nzvb~F4YzpuS&xqTkD}v$&iM6N_Q9wq?MFGdANA8K7|EoNJV)ETSWrR
z{;w7woN(VN(T5^EwAI0UGZnXwA3f}6d<hPr7%C!IeWw7`K}lB2-s<Kf)}~Du(g?1X
zTcc8|uJN}Sv?)PSnSN2r&)M&<;1>J*V{4;#=wqx8x9^ZpzOb>ATBEzdmoPI}%N3f>
zFbFN`zp5JVEX<>I*eS6r#_l}6K`2t(u4F6QGqrT5k?`kj^!+pm- at GxWd~@B|)3QMp
z(wrr*o#$Qcs%>kjhAusCwBBh9OY3IBo&@{O6GH)JkhS_!)_?UkBx)))h^eGgBc^OK
z1>*~G?MLi}MySC61Q-N*6{$uJ<2c at IS^ckMom~2ivXHFC;`pVl(JQB16za7cW2 at x~
zw`ki0)3<Sz?tDH_pe*DHIKqkMq?dII8Idelo|$3Cr3Zs4I?B|8Sr|F^-85O0B&9!m
zz%W3ZLQ0}6=c&l$vD->USmU*l|IU`hf2NCNh{R5kY=56&S{-=~&>MhtNI$Ti at 0`NZ
zNsND&OBP&sS0JVo>Gd7PKaslHWv4}|!cw>a(Z8UUARCfjG}5T}s6bxh5d5J^)A?}%
z5)S8!!hA-dfjtl5n>E3bd?boJ9lqYClt(UjQ&HKO!pQ8&W1D2>BdywZ_3DYzjmq7I
zRH2j~V(8k6r|@hk3~W;oQs6<KT+P<)CaTlW6GrYFHDPsccxvv3a{D<1x)_#U+^ZQc
zhrXBPTK#JKZ*_;4iOD|A!zB)3n)2iub_QmJbt;c%u`28+&Nb3%Yr7lv`xY`C5`A1G
z8Yv?w9pYK}_xxkH42YPuWIb$;BPUo>_mC?zVW5u`RQ|DJJ@>5#J?`^OOU#a2K99aV
ziFJ{nCt_EYsfKbJj0yl8rBIv)ABLG?w$SvSLT<uh=mZhT>@6QR#cj)YZZt`fRFjtV
zERD_Eer?91z-X!ct7da+^R!wNFzetu0vYzixi)*+-x8?~sL&*>IOnvC6<F5sDe at NJ
z8S9$37$jZ)Am2-<5lY!xfho6SMeu9Vuj~j&fQ}~@{>z{JCxHA47t_=1s3EeXlDEV`
z9Fu142T}YGyo?xq0+N&2;*dRhW3N3P+KDk8fWa$nzTf at hHI^w3HV%}~aW%3Obey?g
zC%~{w+?d@|v)&3_yJ;KP``}<c5uaxP=gO8*!ggA|0M1lyZr##gOljK&pDVZix5E8(
z>Dizdhxe0FJ|B<7jpu?=hSauAdoBVd<t^&h#~uv><JY@(pLx{PuCuj7xwZ^nE`D^k
z3|%-uy*PBZ2=Q+JiTbazO at SNYG!YF+jq6dr6FsI7WvUR779wK^?bL5jTh<)RdDm#7
zQodh6<Q at dk4v}sHAIDJ3NXy|{1nAGeou8UNxq#oLFY86^k4J;;&$V${R2!$aO+Z51
z(jS9 at EY)S3Q%@}$rnnXCW2ae3Rz&%IC50(2;mdOjczEl9OrL*6 at JV;ZoFJinlZ$Sv
ztZ#M<<?omM at oXvBa=I2ilmd$7S{{CflZ``zq>4?)%UI0x2?zHbE211eCc~7n5 at 4J&
z0}tu)y>_rOKy5YBqqn4$5UJ+Z;kH0)EP%?qL6ymOBMd8;=6Bi)2}AH=r0%9ftt2o$
z&dR~6{n*>(2g;{u=!*?h-#h<GFMj^!Cb1bu#1;#^h8WCW>ZoQE02`OX3j%8hrlb16
zfY{5fZI4hm<8K311tN`!tPxM9;trvd_0r4du1CWP9{m?`On}W|!_ZaxUt*5#VaJ1G
z`9#kKr|!uYAW~q*!TfgA^3eX=(C|?SMWNnKeoQGmW60r0o!5`Du%<d at rCC5l!$A}!
zoEX|5hBJ2v^B87~fK0t;M%(mYI)y_}{2n2P2C|Z4;hgxCvTiSKChvuU9M7`C3tTRK
z3kwqB2`%qCs!-;A0>==Q4}L+Tq$P;&on)frI8Y0`%IoMi8Oo_MmF(%<v9T3<r!3WD
zU=p3^QIUT|z`D*<$y&i_beE(Jm}}U(h(s>@?-hPz6l6y3hiwAdBavXa{d6F`iD<Y^
z at Js|hwYR)=unkI_0GcxgHyO<rfKTKtuMl(2#Ic=k<Kig+s{Sw^_73NQWixrj!9{ji
zd9-7Tm{eJpDfhhnrTe#OApvcMVc~SLZ~x^3c0!np+-3}wz*!qaLecvh=>^@c74YDp
z*EMv8g9)B(aqrgym_cSmv<wmhsUMI^r?kc?FTd<KmQBJby0G7f{8eB#%~j+6JpRh!
z*wE~ds(OZ^IfgrwX1vI0DYqsQT0pAAlWfO(lIX#F3(&bwd}3jD`?MH at tBv9~LR`QL
z?~t_ZH8q5jwZAA313(_d at B=Jro)3Ew&$1-zD=9U+A0hrjfiyEys{W1si?I<HlNa7n
zw4vz8YzWYD75lc+nlqp$%i_Ws?Myr_P#F*l$Y?tMIrv1r;=@B);w6eEPo^a|5oSl#
z;_AhEvl>O0`w26WtR(y)LoSP2Hjz{4z0JP<mpms0fGeLfSGvntA#6+&NEOy?ue(t0
z53BN*eaVp$J}K at 2`s}6G#U6<L0>1ofTbZb~(hBIpQq1M(Yn>go7D;yuV#d>Iyt;)o
zl0mLK3`TMepxIbZNO~e4d?FJ3KKUSZbTaceuCj8oxr+W+numDWe5~hL)6#RDXICDm
zZt)&m-6eMamvSsw)nYb{fL$M`Q-t6;B?BiD7IE7 at x$ZypI@^+YmkEW(hQo`jo<^a9
zyI5cKZ*N!sQ`7$&fo$Q%qYt?=<{Iq|$^3|3#`qfXQ5vA&MYipaen9~tt*jHixE#jS
z<FoF_#x4T;A*x`wahHTLjRs4)KuZ3KA at F@b{!8840cR$jAv!GAYL1L2M17LfjzmV<
zYwDM)eIpaX)W5Q(%;Wezgs0PP3p}rvg^6r(e*+Y)j<|w{{JFjn2ZmrCw-p*^63_V|
zV_9;88xr_ff`5SD{opfkKy3^{UQ`e+x#FCR at I@9-6^zl4keTUiK)Ik84%4%{R-XZl
zAQ{^u9y}ReFN;G^HhqZ6OdVo91u9igoJ&SrSEf!y;4bElF1;jAIpMGAm7^E$xSAXj
z2)ewACb|=D?SXoP!XmA|5A+Vzm49Apf0^wMeu`-`G9354E5>aS*STGe>6$W=Ny|ME
z;WMT_OMWNF#ib%@9P*MKUbCfktIF6P=Ka<9#040Ag)_XwT^)4;4<cI#$$F9Qf#$+p
zdZhM-ncJY_#U{1LI&K$=a*pMo`5|zQTP>M8T+%R(T0w-Lyi8RCzZ&Wve^Ao;m1bpX
zkGDj{6nQOsEi*G>fn|-0gxAYH{Ntf96p9lr84e)x%0^et>H7=khq=Q at lhMnK$VoR~
z;wO1Jx9LnmY=a*}0-oS$t&H-d`|FH9fDb`xeTA>ZlBG&l3p&|X!&41%XIVTLknciw
z8OHlGAcii3ZGdSv?6Qmj5xC~G#mc^r+0Xk7B2EK+V^$U#b!_>{-zRK%m2z1Pi$Y+5
z%w^FF=)DzX;KBtIl#@f at qkdDHLjr33jqNZllU+VoSrBa)0N1vyDNjK0MTsW1mT`dZ
z-Ib}|Twf- at tfZH{e-$m;$?Tej+sih?nMHCv9F4X%rndV>i;U(!^U%&tu;Na}LNckM
z-dDv;Ra|*G;e#t61sQ{|U9BMUP93LILvo9xI$Y=-+8~c4`V}(oJOek+1Cj>H4kI-<
zi<NA3AS;Nv*;^-)G1v&HITX#5)|ZxZ75gZlv&O`pC<f6qb~OquZPO1gMBcchmX~>6
z4>qRY!kjpj!AE5Npf6nd9Ce$FSn8c{EE;$4NQNL#5I(r?Npf(4dzm=A^d=rLfV*-Y
zimHlfRpM;P^A|bTX?qe$W^JGjfhZP%%W+T&Ll!1L4e at PX=REVsf-N4>j|4^WVllG&
zXaDx~^K6hY0mX)%^wbfR+Qe%uyS<iTH8!G3M`JW=d09a;t0?Cvu`>zeYbVOZSG{B5
zbW<?%@LeAn#?`M=*1l)X)-G=$E;|=c-(Ss2yZx&8D=(A>m&yuEtRY2X6ozlr=s-+6
znj0*;G(?K*)f6kmQ3~XQcT(>{PZOI8y_RVB-Lvy1)2C5~zlKoLxT>)e<`sL1SqrJ5
zQ^lIDqate at TXA>i3Gwz~W`=N3@?#PA@%*rO2Z6c-r1rYGNcIUQ{6t1(G|KS|J$%|U
zNJ5hx)t4r6A|FN$HRX=s$qfQ#JMDI>%=JB|&M<m?aOQ!Oczqt39pFy7fh at W#^fldV
z6<Lxdlk|2gZ6~K|Rp~cHKc9Cb at J$Ja2J~oD{3-Zjn^bb-k_Sp+WS?7<jHcD8G5q$f
zCEgV`j}BvijuKh2Gz*lA36q)DsgPj8%VhiC6)Qi~bF+>nT#$t4jV1d5b3}}sIYZ%Q
z!o4C10yMdT!(R<n;LV(YVQ326K(@Cos-dq56YatWXdj%9KJOwjVGb*pgH2V#l$mZS
z6~z&{g+?=wyoBPQm?6KArxGomYh^HZvf5nbL+W at Q7$H#P1FO-c9CKp|K?AG+{EI9=
z?9MX^_aY|ipq8_HEU0gOXuh|W{9rX~&}-+aJD7*ks$M)s;E?AmdxSWFL5j)T&oE%W
zbL`QIy;VHr$IHAZh66WdrCkbqyf9U@&GX}o=EY?n^OXB#5%ESpcZes?6#tDXF_$B-
z#x)+3Owbu7Y~eC30j;%P=B;Ok9XJGM<9iJwS$u`w_(<?mBDPJWRyppA*~ty#bt11y
ze%K_<eqSsshlydyf;fdx$Cio1LuQy=>Q^b?%m29qN3-g4zj_B8fIG8eS8pbn%n%Xm
zdaa5;C}wD(;@?l|F`OJAoVqoW7Ut?TBY-f%JPYBs?aQObpLDW-a6R6+g)JVK at 6Uwi
zdik}wX8_Yda>R0Ll!?6aUR^hXDgCT>U$w=U at EEJ*&Z3GEiy?d9tMFR;+VhxT5UT2s
zsTN>!S7QqHw~;<1&IGmO!l5&Qtx5r#IRoJ|QzWW016l*c-*~?=H42EUbvhW=W2CF$
zD7eqjqg+7FMtnm{6K>oqC%OAjAuWBkW7$lN at WLAV<brTJidO*`C%MB}0A3a2699Ny
zEo_XpHdGeM at 7x^k@=X=6o3oA#la}5g7D8vFBDEcj2+~i%Zgg{;L0Bgy$1>w+3kya=
zadlReBpohh2`5}s-|QlZ-5wk5*YsOt=uMd&{tLiU-Hm&%bSab2%f)C$7;^Oih3W{H
zUYNuIZ+?*NiY4ZGz6;YNVf#46>JtuoCQLbQxG;4dRv7?(yx|}F;|F?BIxI^=OhO`3
zV23}YN*pdP)W95l2z^G9k%pD{SeEGPewkIlEYrQ+PQoNl2slewyKMT3I{oYbd7EIW
zySdML$kOmjH^1_MT<1bRJ at +X-4mxNAW1>~jH5J;oZ`wkh_I2xdzY9AlTT*T#20jyT
z`cFGKLss;E_l55K4OkDaZ1_p``k>L~{-O_g>saDj^p57*@Iu at OY@7fsy|Fq;HH={f
zzQX5%6 at Cv9rh5--2&W76{8P*BGDS+DiO%%fn}$qxS-lDN1pd>nUpT=G7E=K2&f{-8
zJ6l6SJQGU*#Jmb<v3;$A at u&vaWbxYuA!vx%d`OlUb6CT}#GgkjC^d-sExh=mw`?%b
zSd2s9cEss9V&C~;+EGum6I1Q at Wl>`|E2|zK1BxDLyj=KlMp_v`z_25C*U~XE1hY{C
z$*_4ZY|bEO7GOOUQJk!391jVk={i4`P+X$(B-Ck_!C9G#$h_^woHWB2Q_>$JFW99?
zoNrsLn<#sLER+g7$}^Sn$Zk~Z>is)=k`Fj6)+uDp=|sQDr?Fky%SD>H;w{d`<A_bt
z at BlWA9cb<R<Gx>lM$DuP4gD?a5k%CH1<H;A_5?^|2|00w^!-`hY0D|EXJ^Z#|FS+A
z?*sz$6pFV#MP`He)ne*-L0oj9d~EO)Fc%-M9Kje{wseA&WOm~4*01RFA~`#jeu?hn
z%SM#F*>*R=bLSJsP--|mZAj{Jliody*b*33<0KpbH4u&WOxxFR%I~u0BU_A}gWLhI
z#oJPJrcHK4Cl>R at NXUkxfwUvc>5(Ux3JSKjo{#~e*S(mvX5Z9`z$1SH&sY6Su?xC*
zy8bKO%k!4(zEcgSgA=135Lu5qp;gy&WoMBs)PGH+A$iH5JKo-d3tQ?1wWFj%dUUk@
zF1zj#iFB3+b-!}5&(qrZp);8^mb+Smn3TKlp_?v}eQK`_k<2SrNKP}3-W{+|+l`q&
zR7|tD(5q%<&la&RBW=uXZahGlA)n}uIw0f0KpfhasCFQVbfp#RVs3+{dR{4f0h55@
z3l9<;#3SbQv%Hk-Tj|?!U4`QdHwmZySl1nnoqn+Apot9XTfsPxjm5rhUKlpcp(%_P
zAVDJGTn!b#$%P9+nm}4CX{}5Vvq1LSug(9lfP;)|g*lA5e`;L2xEm^p at -}sFhCxoV
zVmwldWh^!rUTKBa52zfl0zy9Z#_sri1T0=7qjGvF2l4%Wyl at k}ef~#xK6Cq>X>2&s
z?6b+_&QgAo)&QMaHdus@?ks~rJClA)I&U?4l|Z{ux;%DK1v62>jp_|I&&yisDy_o%
zV7e<DGlpF`nUH6#(KTpnoqJsaZAT#6tsfOaQh9bcszGTrR#E{3iH}A|-2ekb#rjJ)
zDwOUW_7pWZx4~~$7=BV>;qM5!;b(8x{q~2ko>z7{x4vEMmCvVbAy+x_AkPs#-=AAp
zzTx|KgmEx&j7`hxjokZEl{7u!PJs@;zqRxXN(GpS*-ftv>hVtAKYKLTp4qDF`C$kq
z^8`3sOL2udQ;zPgDMp`Yn1mqbCI(?#&}G{M<-t=OM4UCC+6^nuOPccmIEO3%tq^KD
zoSi5C%CoJwp(msPV$PhYRgz~LUMYC~AY|am0B at F+Y3!I-w70B6^caF_Z7RFNKGqM<
zO$0x<2f#FHt4(K12J^5959j163pB-VSS2&vp9F6wS&}h!bPnH6{4d-EUaYdql=0CH
zd&a_+J)&y(gwJ2<(TVG1`$Q0;*?>41VrT=u%=sdQ<N;!q5Cu15-hnKir_LN_hM!~n
z9dK4~)k=`+qwP*`1Ci{auQI&5i#=-=w^Zbx&ho>DVbwXgow96_qYHK`v!Vs|_#Ik#
z{T%qRvVtFMhqgWBnTpd)dDkcV*6Z%~d;~R{D-&GilX}vbA_yspQGMJEXAx_Sn3p7$
zSB!*94wO~7-idkk2_kP*WVL5hwZ0{?+#bB8xvn^5OWi;Ab_D7TpF&3GZoIJ*`sf=@
zRd|P|z3|fW+7Pme9v9sG&QBXD_sNXBi94C9xGa~wFfYUfbGFY%?(1F&mUxoyL7-*D
zEFM97(KrsKO0&uG;=%hz-|z#oDKMXoATe0I&MO7wvGeEs043Ek`I;5Yl(0R2^ce1?
zrld7q1U8C=jxsu)dXNncG9G<*LKD3Cw^|8Qg)z1UT5+|=VP{z6rGjctl`!NRI+ at u@
zJxGcY+*b;OEM~y<Gd$ErxMOa at Jru((l+6(Al)g#51qvc?!j8R*&y{1`Tg(eWGS|$B
z>BY-M$TC!9oJ=(R^c`rZSD*-Lh6#*(Pjiz<9+qKMW3U^fe8m?v)XFQ<J0!@jwd}^b
zL0C$71NR^ft#gus)DAIr%-In+#KKq$RrJAlQks$JijbYART46sVa-sa%vlGKVscf9
zx10j!BVX%$`Dw0Ol$`{dyO~S}VbekXNg2;#Wl{9gP at Vu5wAI=0Q1lH(RboOfr}JJ>
z9KF8>Vr9k>YmK1QJbimTu6cuva4p9)N1@#OD)cYRk-Y9Lm#V?@#eT{V?PxB>YvhE}
z80a9h(Q~Bm+5>&Vd3)TEDzcD`_b=OaiPO%mwa1x<zT#0mzf`G~hO%710rMa$LN`o-
zuWy%Bfd}i^g6&yO0mp2o*J<W&Sk3A}t+%^8ysMj)F#+K!>Qz at W*ga#VQnzo{RBtyC
z-p)=38QbAaf>g?z*Ef>GiB=c}$eb6KAQ2SG&Xa9_vJ?^nAGjT>I>Fvd48_ceJalTk
zBr&uSnY6Rv2drVnP!Jah1UkkWI#J?+M4WD-8i}2@{Tnk}<GwF8c=|F_i_ at ytY?Qd~
znUeEtCmGmj6m~-*Ims;}w~be+jJn303zrAHT<?R*)>p=;G at J0|NqM$JKqWdu!NuOI
zJh<d6kj6fdN`WGX>8V1k_dLRZ!kB8dqF&AbgN-I(+EY{~o_;{Llm`6cO8|0;&<E6O
z5#gylStXYgucZ- at gbB;hWEO+8V3qH=IHm?v8-b+tNH at 5Z^d$QR+JUT!B?ZCWBoCA}
znUpR<d=+#kFi1p_!9EfFrYjrwUkGGIR9d<qWH{*yxl<5aKJz=r%iFGKaT at t?B at Iui
zFLrT|mbW%lnDR&><Aj-?x83~Jvu?XUw{}g`z?G;YB*kl;ta|Th$!H3VZ6u at pLePWJ
z1E49D=AD`pZ@)!x;Vo7pX(o~ocyZ%*tRl4)gpG>f{rK6A%oE}v<|*~?+44E`+|cX(
z)GK;1S<Rj}?h at GVCT21rU$eh*QoVQWx;V4Z6j$|}H4-~uRaHD|U2FTN{DlND=8E#9
zPcKG*FkQqxK#Ni~2#tKovoFkxYSTZQ&m{NkQpCAMa44g*xPi&jqf-N|A5NCS&a9t$
z at +<G>0V`z)2j at C+WAC7MRGPqpv7htQI$j3qj$$1or6qof+mhd@$DS8~YUf)BO>Y({
zRw$+|l1l*A$Yv0=l<T}y(DW1W1$T1}Hc}Jej#aHA_97B7ZmrDgnqEk+>5GTb>R;;N
zFsvQASc);Rtaru(qL5f)38VmWsY9 at R5lb)%f-GRSQ-HYkG4YeCv~fF<Ai_KoDsCla
zpF52mE^NfI03CMw at E?OtSZrFttoAwERnIQLi(Iu#qEMkw(=9#GmG^r<$;T9(FPicr
zq;359t4Fx^d}$8dAx1t<qnK1LOx<_OJ*CSpK*4*w_I1jR^PZ>#Nu(}z<MrR^SHmZq
zj4S?Po at Z1C+C<es3uZ@`^Q%2$OCA)|E|f$Z+XXEz<V+(h=NS^bX1!uhIap_9vV!fw
zuo>e-zen=+OS0agdRFSvJ-Z*x>*;B7I)9Q$d7}W+aJVEvLT~*iz&+o!x;q}7oEQCL
zne#R9xldw^-wAvs5b|O-z-Bo4?j+5*a?m7{+IY4=-X79PlDRS5hGQUDraqcr2NynA
zG!0ha!D!FE3qtnpsA6^^$X3T3&O-{7NpHj3jYV0aX%OIcH?Trh%`oCq>RtNI6i)r7
zo+guF6;m6}j(JTugY10vg6&?*lOcJFY&TZYR~=zbC=9p7{6GluG`2G)k`YCd93^Xh
zl$;VmsVbwe5rXG~UzAxH&znese!+Tr{MR)dc)mIf&UWDzMnW{f0FwDhTS~O*Lq0C=
zLPwwFJNi7qYvJa(;^>5Kz3~T~;F6nvaqtaPA)*gBO6`MmbZ#Bm0?IHZhEK<uo7B?W
zJd9s0p)(7_6V9&&lWcO$CRTnvB;nJxtu2VgQs29wCZK>Ff+%_Q3$;g?o;R;cZ?s;D
zH7Qy~zBoOPBk35I=>x8U>95$+`s5H{kF^)1oS#I_i%9gq=o*LZv!1ICYl)L@;VOJ<
z=%Y0U87hCDkY6YB{DX`b^C%Ei+F+j;`gt*$15-i#`g&XQ5%lxr0O*Om+FX+T!e at te
zDNNgJ at QM}i_S1D$SL`4U%EveTlbytjn2d}LLzePsjVgpkPE!eA0cq=3(dDn<MXELL
zY^YfH0M%1jkJ)}(;3Ho^@DjznswMoi at Tur4w^tv6ml(8Tk<`{DZdfVQQOI9?8Z5ry
zQw~Gnp6td|7H)2-{Ay?emy!2CW}=h<AznL}Ov`=}_5o~YJdBVz{QD(!D(R<;SK1`}
z&GIMd6I3CC!Bq`?<@GUVr3BaIi6oV2bISd#tm*nK<AvdD|H&-9HWR=2n`DXs`{Wy5
z6JpaU2GkH!tdOSW<MYSlv|X$5-3lxqfwr4{qPgX^uw*+pR+ytnzp6|-rl73MBn1oc
zrzs4MM8~6l+T~Eu5C-je@#-FRJ^m_;BdmLDWDrij`p%2ZOC(384b$L;J4%0o+zp*3
zAAf_LfGT;}uEb{1BI$}Be(;%9F<=as{!J0)EBI at XX!*1F_y4==ZDpmp`~Z0-yYJ(7
z<@B#qarsq;KLV|^ZTw(HLKd$|KH{p-PyUk+Padbsu;$Qs@#Jp*#oo^^8`gU~I4D<4
z4qFw#@E5W_(fbFQL#00^wB)(s*~eyNqsVpKUQV+<YQTQUjfzbsAwy?@UBUx6)=RNT
zKTf?=78c{4>HqKO+XlBIElS^09 at 02uO?>UFb{OpibNoBV<hp`2|6L!p(U_ at jIVlmr
zLgMHWvj~+Tp+P!Q5)u|$^#N}7j}x$f`ed=n%*W>`68rEA%<sU?|Ns9s!UVK~saG|w
zI_OjzL_sOdz}a=&5i0VQj2N=9JZ>H9+rJ7`cU0$7eY&Ow2a$$}Jx>41ROuAXTH|m0
z7o6or36I*B*gAoy>Hb|rYuwz}{583a&UGN4_^z!fKV4j1Ze9U<I`P at A^vbXq(S!OE
zPj at F#JFSPr%SUdJI}eB9mZJZudGnKEhEV_dV>|iV#7;0vPE)RMc5~sghQ&s=KX_^i
zrl@?drYG3xrGJz3V(6o)A{1(p$7a-0sdw8oUJQrwZ1_ld!%|1r*8SS^s{WX{cQH0S
zz5!&W;)hE<AwSLmw}d|iNNwDVL-#vIYV}92J+bcB(18bj-}B#`Vp(>p{Qmu at c9C4>
ztf^afq`Kw18Qbggss{vMuWFz#^PxX3bAt>=eOV_Cc6aGr$QzuFe**un7Qh#JE;|nN
ze*M!28LDkM@$3e4@!AJYF*zyH&fgsUxbDu$&K}hNIy&2D?)NtnyJR)|%JHu!VSNjB
zNd;kljfr6XOIzsJE$qfJ0B#Wx at 4vkMwVqzE?~7cYzZSE{9(AR7&(4)v8c|V5L^~g`
z{pSPZ-_}afwIuO9G~fQt^@rH~>2fGf_<DyY70!8v(*^l^Px8|SMVL~}TQ0UI7 at CdV
zM}acWHzIaU+<brV-jh9SgNy!r28t09q)^xwj!6a!t#5rKf(j5+lj#(bb6CPHVa%(7
zqT)f3Pf>?-={!q&))*q^xAs(vi8LG}nXOCVgXn1spaK9%-Y7ssoQ2Qf>7S$wAhCo6
zX16e4GVt?Sx}NYc9@=e<SH<^XrEFAS*K;mkZABGbb}tid-LXY4=6stG$RhFe7mSa4
zDgR at OB*R^5VMRV7FN6%Vs##)N<bqDu+fS{yeYGEpj_R-aV|)AT9}Dwka>?}5J_=V}
z7VGttIMpx$$fINEVo>vE?u!fn3~cD6^47^%t^T?zeSVhB=EW?v)R|SoueqyWE`QFj
zewR7PXhKYw>zi5Py2yGVhKc~=m&ql^<$znhJsVttsxU^?u!iVl?&MF_oQPtVVd?4_
zVV0`rE#5Lw?r2BaipEh8{e at Ak<~@>hGX0Q%d~T!PA?L?o;t*<Phz3wIGWgt0biuZX
zwqxZ28YAmr5%kBgC1#qRG|p;FoqS|yjb+)hUj>*|DPumOuR=cZgVSYdGAWKZ8dgXF
z`;dru(m~?Mm}_+Q5n at Qa<zvpJ`hEPR;zZhLt)GVCy?nELyhUF0Hm9ds>NFSydCxvS
zKzBO>_I=xY{j&eo*(V}*TCIC&d0DQRPd+9WJ at km@ji#KsR27Ep=8Qk%=h`jf`Tuon
z`Mq at Vqf-T~-h+EDw|)smz~uI@&%@kLXBrd{?490E1T at Ml`N3{O!Qk6kiRaU0=;B|;
zRnOU0(#&xE%sVX?h~{KLndPVMrU3hwIw(j;Kn+fN5);oU5-cx^CwbE at X-(0cXn|op
zuzN0Xcz#Rq%%UG7f2LVVhW_^E2Imuy{mN5=#EqWR+S|3!M0?PhH|LxRB*9wNWLj1^
za%FdwcUxn{<nGM_DKR{)mx0XZGwpU6c&t5C;bL-Wa?SFAsA&KYJ|zX`IRFv^nQxWd
zwUu0>xlqlOH<CS#s8rs;;+Vglk}DlEB<f(gk-dGLd-{B%>Q>y;4A&mfPf^d5faDq3
zz0 at ij@)!{#CP(?s6V+%BG`Jr%m2CBu`5a&v)fpu at S|1BbeEFujL<~QyXeM5ay7R}2
z5uY>b=2&;pg9w(F3S4)e`ghnT-mlG`+`+cc&_zOHvCrjVOZS~rw$JfzSHp5>u6~t{
zy}?<LbuHcd=E at g2r7#+VFga at 2n$leM`#pBqQ at ZdLFlXKbweNmFyrNfDN)G$)FHCV}
z99vYn47pOf1-Dm(CqxIS4?zg})^03Ge(D;W1T;8XiE+ijY2b at lzho)eHBJ0UoDc95
z`dhYrsdh&K6Z%6YWQ;}ihQJ159L=<XHFLy?=Xq*f!Nf~#-}7tAMwj$J^jbXb5`u;R
zWN!rtsb63#&5(6RPpreACxWDLA99;Mvz@{1t*rc>$y>URmgJgdmYN at yF_%Fc^XO13
zoQ2E4qn`;k5|g0axOPo)b@{aCy$87_!5o)oi8+muSyJ%LK>WRtAM}S84xb6QD-WsY
zq~mcDy`~kf{9{Y6tmUSTznuPj2)U_eY7|E`{)4RN#buYW5%UrQwq}wy*FX^(G>$x<
zS5Mf_Kg9hPThKDc&v9RUo?jDJacOklbg1M|2}|+D#u!BAa(XT&AE+mrV>yM(7w!4h
zTiyPX_e{r(yOb9rp at q`U`}9O&xlIvFbt5lse_A at Z`yg4g27KjuS=>~+jXxwl6SwsS
z0P^FiAy)N9NM6cB8kotuhS$0B3GV?K$whxd`&It=(GnGCjKlZT<D~nS^u-*q)}hhT
zSwKelq6$}G+uZ$dGcJBA`s`1TJa!(wVYI3p*>4ITZ_Xr}s;}dIi&#PXpi|i at 6}R3S
z<5t=G=D$3cD}#<lp~C~t5uLvO#9;<`=hKz=FLVnFK7rKpu#5eKc?WBfjlyjvJ~7C$
zOL7uhLZ~)YER1WV`p}=glO0ii*2zcdH}ZNt<D_EM^Zo$EfGFy{j|6NZdsVqaoEGw)
z&vY)dD at nHuQ<x^mX}~P_QfcwqzAK4mWUNYWb*vaYaSLFL#!FGM#zOlv{x$wm{x*9P
zi^BO2JVV?~7}Yh&R`F;Ak|WGYO-2p|C<<iVdsR?~!<JmgiJnJ at Wh?%$o-WOcd4SQT
zgb(yuJRI`bV2xV;X|d$m!2Ob7 at +Lt@Hs47nsGmw4MaPv{A}fPo1qB%^<*+CO!rlB`
z(e1rsHAaLYg4#}LoGDmHgbE6xHi at -It{QavqH}z2UPUVnGsgJ*G~ZEloKLLKS at ECl
z at Ize|J5jZYnqR~_P<z&lUTfx^zhirAAe`<3<-8~M*$^o)U-!O6C#smMAQ>Q%@CaML
z<^Sxo_rX!R0^bS9w+{6IhCatfr>lhVOB0yUepJtXS4BLYWCMFCca1gjG4kfnE1P^7
znu)})Az8v9tHNMFr<pZP;)*JG|0e$`mvnggYijf;vaWN38uh&y*EIdo&#ns04q_}|
zMCUXtJJhgj?&j9m8V>j6p8>5HZ3OO*x$#EB8a#Q;{OsFYya5jB&joz6RM+YgKq7C;
zGo at qep7;;w*n3b>KHB;cx?KGunCa|rNq7FSCGg`wWQG4<yAXKvUyfQ at N*`u}Rla&D
zw3T*t)Hjqg)X}2Qvei at V`bXByIzaDoITh!cUXH-OJ-h^r7oiIz+4U|9c8SwR7{3nj
zUE<9(qSbJcBa1zd8rTcxkMPxF4(qrvKp>Ebxp~oFJOqCCU&@fEAiw1-+MT(r&$k*d
zOl$x1Mcuqzrvf&q`F(d31jidchwehJU}jILBfe<7VO(qmCr~0wCd69?0ISuF4z&A6
z at 6iCe_xDowywOHD{8<wO^$D!F#j|V3@!b=-Kb>#mx}%hehK)bng^pC-Fh##v&NtQ_
zEdRhN>|4=@Ei7PqkWgFt)RgsFKASKS-eGKzpHA;J_ZrR9w~xvbt%d83MBf*z`S+3H
z##?23(7mM)q=`brZgW%UP?B?I;7#k$X%j?G=)N0zxQ%NQ`*5YXL at cTm=*k~_tW}b#
z at DPMK)?hWaeMMdCg_ApxX6anDX?^w`EQ&JNK6f^RgH<{<kmGXL(aw{ipFG>3e6rG?
z09C at QbJTEodA3!yo?kSm=*(Z_q0GH;v~jfCLrLH~@pK*b`=%M5b(~W-vHE_5yes->
z)(yTiv9KKcbsPzjOMJ(ESmxSBF7NA8py&2chs~TNXO6PeKm{X7Cxet3{b43cMzFF{
zrgWa4dPzOT9`Nmh7U$#4xT=^h>E_9Eba3)p`iWvw;`lH at FMA%r5EGdak^z!Z0gC85
z3YcBBx*vbi`l;`du7YAd*}mQ^p2cjmRW}-nd~PB8B|hlTM+tLuH`n5wE@#cmk^kAJ
zqsC4+On8|mxNc5&oL8G#)`&^DlBS!ALW=9aoHN{aoEMs<%NFa`_M$!|(D<qM)`+D&
zOwrOPn1i2={TVuEi-}D2+ at FBe70|?~{xRPq39X7h`)i6f-xQ(aQ_X3f-jr?4%n#r1
z)$SpOhlk`lzv+BnDOAH6U1ARhVYji!G?FCEe`|{?9}bR`vf@|LC+ywKjZVb9g|zmW
zdzO;izp*k=%P4N${i8oFny_<g%kj8w)SMkiXnHyHtSW4xoo`pwgyaYp?kVL#din$5
z<t#2sWJ)gO(i2nd#@v at n;z>`~%RRK*_hr*DkEui9#B$J5y7ZfIlE-F>S@*Q`G07)*
zYeEC}=6KL>57~cRe!FeCtjh)xJ{P%{V|k!nYzuQ%7sJO~wvcZvSWvZhe%=MH4t at 7-
z8Ergu>S}R2sub_>plqZh$Z7_xX?ldnb0T?;l1?yG)N9D6+pOiQH0=JfU8Bh;Aiw?7
zu7G0fUh*+?66V*d1{x>X6pvvxY#{k<n1Z&Dw!va8zk-kd93Ya^MSY=!!mx+YG}^V_
zwAoS5$AjUSy5~ZCJ_Ahuv5B>u at ZBF6dMLngL+WY0sy|He<kPRaeBwiOyxDvS{D`=x
z4 at 38v8a_SN&kVdAFEB7<=3EDpPtAumHy77K$7NI<R^63hsi4yf-gD+vqcdaMwXJM3
z50B<r2J}fV{#2|7y<4NIBL6N7XxI%OWy+c~>KN~dy5)Ran02iR8^2p at 7cckIE31s$
z(}x`ZSt^LQIoop|jlz^LV*J#@K03|Sn-$u9o{0W}SbuGauPEpA{+l6VNHu0{{FkF=
zrK8aJvXe~3NuzJj@`-7;R7J%*H}4+-jE~s?38dho1?xuuDE`ag0a+RX0f>zXz?Kd<
zdir`sY$MMAWiNG;e?0MIfBz}A23dNAJC&e_6MN=YOC at _#5|s{L4fKNuZ{?m*X>gP3
ziA2$!%tih+2t`eQ>*Q2b<mA`SD!Cs>K}uiLdW_)F+Bt!{pC*znOV%ByU1l123HBKM
z<}ZLf=oF|k3`i at HCr@7A@@l-lNY<2MHXjNnaZ!xUJ{yTK>s#57%mBsxIX~=b+!!iu
zhvkWCmADs5ex(kV+cmVZZVaCDBLK~a7P2eu-JtIs%#+BC4Ig4e`IQ(X7)^a2>t>;%
z<w%$QnPYjDXuDpO!}2Y##zG#EPi;?2)nV7dC at Ma!@`vE-cL`turxYnNed7+z2 at 48G
z<7BF5eyCEW)Cy<`PV2lh=gq{*tTEI8%k+3ohhqeW8AJzYpAC(SR;l1C3qDU27sJp*
z^N2p at gs3abas;bl#RhZjO08hmR-3yAD<H~nv2jdXHxId;U|zt24B%|nnyfreInRa7
zN+f&>Ypma<v)G~IFS82(=3MhEW at QAviTVk*?ie35HDb=(yAz)iFKTK{G#+Z6{e?;1
z4<lrbJb5?0{$Ut^K^E%YQ-ro_`DdOao~fa$7HgWr+9(4QK1Q%W^blHnmxy(G7;dJh
zZCQdnf at U_sfO8$FSt}Y-AR*EvBj375+Ade<=LJmH{n=-;+?zhFeHfXm-f{Hw4YQz0
zE0Ksk_77zj^JfYc{JpP|MEP%vpq%Sq7EB-8CVd+Er^Le7T%FTvZwiW;{*uD*r^^OO
zw)_du_>_8Es;Uz=#oZj7M(OkfZ1L*;kV%h|?^2A5aCrB$cgm+HA5E4Mbf*#?+Q)MG
z&ciun at M%ub-#`Bo+0$q*(j=FsIAb9bu1a)QYrp(VH8p?t at FcpYR9UV36Rgk{6B%D?
zL#H4AFe(x8Gdi;V=Ut>J>&1x4vZTZ41W=9QY60ticzVmAxVm6#7y<zjoZ#*d+}%C6
z26uONcZcBa?(P<x;O<VaAcGIid!Bp0`^}H3si~P=XIuB`?$zDt0h+p)B|8co-D2Y`
z&B_=!33;c3O}I>_Xk at y|s?(Vk0+xd{!ucGZ3hP`(egsiB3e*&t^x#rkqtwdCxa^8a
zOHJSuH4akvtWcnJy6NK)MAm-IYq^|-#JC`ikY7xYreAoD$>NxO-adpu<dLcAuS7z!
zJfJ<BE8#dC1Q&+8+^InE61?G?&9-bMPS(PBcdiA+$)2%bMfO?|m&qg_YMMr5>*(J#
zEYEfJ2ad&!rP^KP6DSjCEUYYg%LKdl($kkUD%=+sX@)0DoZ1Amw(xXOVnB6v1SO9~
zB3Nukze<G(c`&q#dQ{mqtFl^bXfSMKA-h|Q`T&OxQQ{5^sPr7o at 9s$7^u~SJP8J at T
zH)VwYb&EfD?8NRz?VgtyP<&z$%R4?DP%Xakvmy*TjQ8#xJ!96Kja`26aI-VHI)=Ad
z06&b^h1&x-Sf*MBNMDjqsyjvqIybKr0XfG)-~;@pxv2=8WWYo)1|0E_89?xvYVigE
z*aC4uIQT}hKy)w8a0_;#U34N!z`M${Q^%@u=8DiUBZK3zb0TJ&{27v*zhvPtQF>tu
z)5S#+N>i7nq=@C2_0SFt7hOh6D{T>hmr3{XrkM3R4?S&5)_i0sf|yH1$hOZ-qBu!J
z(46%`c$VqG1V}v6x}<mp;s?2ww2{fG;#0{P$kMc&)#%xw2wNR-k-V`m at K-miu6hl!
zmt|<#3JG{+IvWPFb5bVH^OyBWa0?5`Ps)+;dzUo4HMZy3ia4ZGJEOy<Pg;b{pXQ_d
zG>(KN+3yX18*T}^RD{OWTK?V!dW-?4_n?BVSqYi=VR;i005xKh&7{J_%!$U=zCt!N
zN)TAmrWyVd-M`Va{q<SrbTZIQ1TdhHvZju*Mf=tx=aHgoiBhT4&*uP`a{}QhU`y?S
zDfG})e8Qej?@qAj#9tlOi9ZC`w$2a<ItnY3fc;cRE+;ABI<9+3!NOEMDVAnoiJ}3c
zt=ve<qc#7bl{-GiVe1iYn*4XYle|{Pi*|+vRE59BIN`!QTSNf+UEy0tvUM7(VCSL)
zJ{J8#=Z|PYgqot}b<`D{cthCA7UQ2)OXW*e!%qadXrv&?H20MI-V?2kHi5RXiI+Rx
zSzWe!!>7iJ1%js#AXlK0b(#n2dt+suW*Vm#=)cuiKoJ9JB03!Nj#f00dJ$-qwq*aO
zm#x^bdC at Otae77fkO;0Y_=tH<09)+C2Ky4A9)G@^rFaC+4FSGp-YV7HR%eW4UKy$`
zHIJx6_;k=2apkJ_T-7|bgo_e)dy!-Kw9P+f#X^v4Mb5M`;GckNrE%9=WZ?jmHWV(Y
z%0Sx<x6zt=<H~1e#6f~is0yUke>e8Ayv+mv)ZAK9Jcx4|T?7=dd+5S*MGUWt#LojH
z-NqUy`$LE_HyYQ9l4a)3xs+X`FXt!x6*(fYykhU-%ScqL#sb%o3Xhz9PgCMswPIm+
zkUTvJrp!}j&how;aFI6BTmNeLRzzzVQE77CX;$3M8ozFhw4a~;DVT2zV!-1>G-(N(
z%M!0sTFJA9l?#r#38WxUTim{{=cw%r5#serv|Dc3^O{<xwhqlN8d%5vH;q0ZlOwP=
z$I!FZ91ta(1eaM$wNygUDbT)|P at IiJyAqK4M8(JG{n6Pilg5@@gznXJW`=M>fXH=t
zeCR#qneDVJb}NyqzcP{bR6SAQ($iEMj&)E(V095-y|y4B?!G&xH0-plm-c+>UR<Zm
z at MS(6g*_nCo-p#ND*J6wNXA4y?f#^P6t>3|S~-m)RlDk+uRyg}F;EX*RW`ZQ1e48S
z@%IlX6#D3OPwKQ~i`=xV#FMk+3B$YX#S67#THVEG<q6X#{s|K0y at Dgnj&3PfQnq$_
z^Y)2Dj(slRCfL>Hvwp*cNSR1+k!#yFHq9yWRP*aQ<Q8AYOqoeYzAyF*H`OhIayy(>
zH=;EKS>;n?d?uKj%h30g_>q=;5)eP_mol>ghn-Z4`f1X&BU?}5DaO?EC=@0mGwm==
zM(e|>V*wJP$9)_}u;F{>tBpp5-BWh{mD2B3rp*FY&~vxQS_5s~_XXQ>SGAzAC^rN4
zu<r**HG<<cA?%mbZRB~#?k855Z at oyc?k8xRz64*;tTPr&FVXPl4{%+AVJ;A?Hni;C
zi=XOTH$@!683Y%+>wKoj`Uwsb;Ngb});X;7kbv`tuD0=+V0E_BNMN%7s-u&luht4M
zWr#Y{i1TZuXV+?+$gq6rr)YEd|GOSewEg=xe1x7Ox?OH_c5SCFU7Jp4w$3yb^K6HS
z(G10N7K&9%8ZA~B`ap^3BOca5RTs}FnBc^>)fQ{@0--y(|6&r^<O at t396y<j30X$!
zUC(~X^IZ>-{iF5ozOp!;&Z*YvxQT#?Bw$P?|FW>KP_5ChA2ESWQ)z*%X}#9zN{h!~
zQ~p2Uf*^9PHM=$(JUrvW at f7DE=6yB=dHJIpOyt3gFZZy3?q^mJl00h$ciC=m{H)gK
z9~v6MxBo9JVkD0~%RPE?I6-TMAJS^Sqj!CR((M1?2mFZnc=Lz2^N)4SI*o=xBMI at D
z=-mH}O>Ac**xUde>sDKB at u+e=_Os^~okq<1(`DXC4%wa+>)lkdozFKrl1gOK8eM?=
z^b-32c(msB>p;{);Sk+f93wu?tWV9SvV1)lL+x&UN5K%g(eXec*XQO3B^8xsgVAu)
zv@!w1)TtR|4wZ|b#dV>{i9*Uq9S}bGZ_WPqEiR-RY_r*(0GQ?6!7lO5^Vaei8HDoC
zlc!&LjYpA|t2I@`vuG<VAQQrAGTWF0)cCZp<7s-jm<}}lD2u1$0s|R`kBp9<f?w$L
zx;^Aar^(#R?i@(??_~TKY@@5Dbd<#5q11r>zU75j_8=hW6ipG#C~;M=$$aVXFcCc$
zAnuM`eezhs6$g~E62EOY{yQ0yiwEiaqAhbaUwNkZ{|Alcbmni%^`ycj+VJ$slN57%
zZbUvq-5FT%#{)5`Bo`T9`XtHo$&-GbUtrXgw?DLo|HX;^ccQqLV`C&{TSBLy1M*(A
zD+Nqh0TR9^&!Ku%ueyelQN{GPb0%kB%_S%Y{y_>UTa_-9s^Rt(Mq!qgSG_rTj8_*1
z-<IvqO-QDO<$yf7dv{o<JxL&Mo!{_bH-Zzlq!ya7skyni|Fqg}M1Az3pofuE{j4#X
zNTr9RUqKy}fkA82q6aqki<!CkF~W;auO|;PbN~0U?14(Ps>;f|0}cI&-&Q!&o~ju*
z8QU49mdrJ(rRhHh*MW!sbOgj8>7Y^c{vla*Ae>6Yf*bDiT)rf~zG%4G9C^1To<ghw
zC-}d1d-F1kzWp#%-k?*rF22{R!A-xH3mu>9;bDk7!#MR+Q?BFm%*_2jfLOEXJYzbQ
z$?lvf#GhyFI^6*5^JVv~{50RK>~fvHJ~!Javl-yY=c at BxoSqyTlPb`#Zo%DtF}jrf
zzs+#@D<6}5FJ-B~z5e0kWOXz#enMTX8h}3`FW2F8_&X5le4{PCs;>9>v%V+_bhh8~
z>83ZRhwtfcQnuT=<;;M+S51#z{C|Bgt7<!==H})+ceb2+em;2v_bw(r-uXDkz0u?k
znuLS|O{gP&B6BHMn}0ESYADd+M^_SO^g4*46c1*y%`^Ax`?3*v*p at p<-%8e*1!p~n
znA+QM{|`w@*JAk(JpmPgRjwUg%o2LMA}?5AC11G^7?)flzX5#;e=NA at 34J)Z{T+%t
z1HXtL7jnf#9;6e)Ayw|gQ#3B$0No6o*G$t84+n2QLzfKIY+THr-D~uCv4c0Ak<0S@
zp1Tw5K>PqjTRa*QLw*Q;ZhI43<vbh+peB+7Q($FhA3iy;P+N1z-WTSccPj3Wt*2WR
zMnM^MEbsuLqtI6dc=OnUcXtT)2{6X at xEXm}vl$thg<d)0WT}h%?pdTi&@yW<0Y}E%
zyl-GXXag7%P3yLLr_55iZN<D;iL4${vMDx^ykJEEo1nswtJAt?Gf=W>sdV9DUk5-|
z=6{Bur at gzoo6MrwChA8FY6_I<l&Y4PIIsu60#iTJ=q6N>m$Cod<Hl+s+FS(*>a(Zq
z9zsdzTjkdmK7lu7Y^P(OHK0v!jREp=#)8GMhX<ojAT4gJL_ac4vU=SL{PAVU`67W8
zvNTf-;3O+CWgO~F at h-NMu3IVkFF)Y>g`2nD8%^K<5Uc3zQ+$zp2<2i0I#T)d=_jA4
zJ?uWZm?5>*Ja$h5p==<)*0e?*MVjqA<ftPSk14{M6n{I1CotjJcjMjdwb0m+MQ?k(
z^zlGNp4Jnu-)?m4{OR8G+swIFNc`rNIK$KZ&cXP%G`=(E)4%+$r!RfO_x^W%&U=M$
z>P|vPHa*dGf~)&Wf-hdFpWh?YQ^~)-5cP%D3H<9gvaK^_);yd=z|e^Y5$)!Je1r2g
z?}-&IGELu1?e}+jz+RY|l9?sVZh`~Iy|?_Aevdzp?huM5IIm0H`;ye{H4!Nc!O$jM
z_6MvVce;c-E#Y=X*qW^gRsQc=I^OR*dM9a$hyWPPh>Ek<MEjje{smY9t~eYbBEie1
z;dyp;1kru2BjCb_Yj$z*k7gFR*Ox*ts^Sz(zq|4fc=c?fZpqYvpR}sDlzt?lPph|W
z)FiJsRyWnONN!E at E#_})X=i68NJZjXX^$Zy7zCpj(`|FF=P($eqlH5nsvZnE>j!E!
zrR$Xi-^R`2CXx?oiPFb8ZqI=LhOQ&NQZyM;htWi1j9#5WX345>X0Ki}b3i{zNUC0$
zOw-zcmS_(q^0HCH=uf9TjI{bn!XqJ%D>}{8xeKr*$TJb-cUETOw?(VTf at v5O;3rtH
zqj2L21L=s53iAZMwUK88QwDNH!3_rJ^(lCR$zIPm%ec-E)$7X*nT4e?T&KB#WCzPk
z$Xx32yruO3wh1S3Xl&%^7w#FAE2CfBO(Q7cB#!8YHcS!IcV9lqq;?p+-D|}(2s?tv
z<(Q!kl<HQPgu1ej=_|!ibG!N76U|~ctUM5U^z!@?4aP$2env+QMA#TKzq~<TL5X4@
zX78Hg*;~^a#|HSBX}Ye{YOs5;b}?ZaLrT)eUA=&rFlr7E`yM4yS2{PrTa34neUA{=
zd9QihR-qKGGfeDJWFxq)%Q;|NJ<oj}BhCpZ&JTF~_pA@;J4ycmJcSq_jgd(mpf at na
zIHp1YH=@nS<jB$L-#t$>7Ngn6`<uAQ&kyeHoby3$xEcZ~N2_sD5PZjS0vF4^4-aUM
zX{BoB7r|+hy32VI8_`6AzmM1oT(~Vv1~VY4z6?6-iN?xa(wbNfOrFzi9qAFi3K2ZT
z{~s6N8ob(ar>y5XLi+p`vs%Ko(ZqNCmX(gbHIV4S3l``NpHs`~IFFLS=5-+Y at Veca
zWE$yE?~R*~=Y<5Zn3-wcWp#P{t>tb1`17N&y#JY%;kYtdp&x1*PsbW>=jGVj!$yCg
zatiCZw2G1VF79WUOsbj3aqj2Zg|#1-y=Rcw7uSb)0z=?^$LXFMD|t<R=}wT6-P at ln
zKK><Bm&5Nmo>NOUnz$^i8^ydmDP4Xpcnas1B5VWeNizrCDx>Wexl|3p<7on~!o4^Q
z`{QSI$JvN7QC-q_Lr0U4xqeqa?fgApD=h0zUnkoC?XyO78(Zx#Ty{Q%(+OCTc at z2t
zP?e$m%yl7L(RKcEpd{3^RtVI7I{<G^^T%Hd3<Es`POUwr*6^ejl6wSu!ihF}qv07e
z2Yoqr#^c<^Mx6DB at 6~f9>K01ao1#ZSy|LbeTjDz*bXpyev~?Yc9$viQ_rG==Jx5v`
zb@(MapoX_xB8QF3l-EsH^My<xOO)#J=%FhwKSRWL4wu3A!kXLhN9 at r#o65%JVQLql
zX{o)2>-dw7?-B)_H6JgmIRaB-+}ZY%eFjf`ytjZmyn?w_z36i9zSjF&)r~yemfk>S
zq<{jS7t~Idd!~Ai9e2BVuR(WF at 3r){TOrvG<@Fo^YjvL7_G2=>hgF2^=1*gK=)t-G
zt%ksVIwtuQ`#%;|)$cVvpURapI)FXF at BJ`&>h_?MSL542uo23klsNMM)30nzfA8fx
zJ=quRtMGo3STpEofaDG>Np;#}e2fGj?~rfHtUv7$95CSlj8t)ccrDj>e0ct5$SY>L
zOCdt%n(Rbvo?efP<)_fKR=kwEzg_1SR41T$Fwn$dFi)rr>WP(flTGS~fl}BWR_}W>
zz1-G5PNqLwb6!b%dW|L853A!Jdi-PFFnPX5Byi)IoBr>pVxhv;=eQ~F??{$=)8%<I
z_eV4Px##(JGyYwY#)a22L7!0FA}Z&9Bg32E*!b%NBEi^}u;!LDUOyM!q#lGtubP%c
zs?-L{1sIW$j=R{E+c4`|qp3okwQcREM_7TWw~NDU- at OiK1^;;D*Lz7%gOT0&x7VvA
zqJyptk?D at RuMAwq{C}qNfX5%Tq^cRIPoJps{<hM)M<cJp9A{{!dp0?Vps at YSE%1IH
zuF?7A(^?(f{<PpfYVLnU?0ftp38{<l9g^r{a%$+fJ2%h!fYx%${hR+&sP{?fmx~PD
z&6~rSs|=!ZldUx@=W*%BXT*;jMn0c_-$MRwjPcuVu6FI$3_o?<2-I`hqO|+2NCZ4V
zbR+Jb=dk*RM15VcEyvwK6AS{;*Ovlrt*kop`*U3&!xa~Q6w5yra_`A`n{Vh_<c6Rm
z_nRli_jHdzZXLJN&}^oo)fO-W>lCFo(G#Wr$0;bWmMh13nlFJs at R^S2X at 821l~qSi
zM`9i{cSdExkcKx4f|+Mi5S^KvoXy)(U}dG#W#%|`{;Z!w`0{XJ4*qNRAZK^b5Asj5
z^<&4%?L$+2z6pI~r4v$ot9W!_^QnAvuo+8)_yhFANF<k)l|>h>{>P7atX}ie7@%$f
z?ahUUMV=G)S42$DESgx9y_T%l*LvS934PBU0r)IYwM1vLov?l2fS>Xi$ggtqz0^PL
zzD7RPy at fr0LnbQ7qm(?qBCzRM%1djz1j at A}mhdJbjf<N}^wO1>?vDXcezDI;Jzsuz
z#P~ULg8i>4dt2S%`|i8?hQhQ4YI8iLwxzu#prWVSBiujcH!NJVtF73cy6^~(us#;-
zoz^;)9_;j|bIa^^TM6WT+DEM34*71rFQEFJeLUxJJ1gmR-dC;waWlg*=2=j~yZO#&
zU9S}xYtsu()>=PR-wV^$#EKCUw)NP2vRRXYpd9R>nrl#b|9nYwLq7tZ{MzK7(wV>S
zIh)TJbxa+v?5{*1?{D|=;VKGxu^(A|hmvh}$2C}!S0`~uW!>O=9hVVor3=1VA6wa`
zwf$3y1MD+y$6Lzfu8^N)6L&7~V>1-o$3MJzI}Tn14^sp``fjFaIp?kP#>8fi4tBa@
zs~EYySR)iWjJw+Jt-~u6?3`VP0gP+^msR!lm!&Mtn>(Q2jL>+O-*Fn3y?BniJ?lZu
z4}teJqT6*rAN~UNcE2Hvz8e9(E at qRDMbg^dTTB6PO}NJ>j`nJgH}V0N&P3JpmaI;l
z^R;Om<>~$Ed+{U`lk>c72OYGFnfrpaFORy82PG{fZj6o(j%H%LHMnT=Ifba<U9E3m
zqmDPadckliF+yR>171PTRe&lk%P3B%M~`Uz#joAT{XhC$?$&V5PDkw8;mXy6Gj2P{
z#Y;@XkYQ5R`x(*gpjnKJgy&Y>2S*x%TwYVyw;A&v!hn4OC{V)eRSPyG9Hlzyl{5fA
zXJp_2Kq{NTo-w?7Qbf89ppA7=fgQka$X9RLpreW{mAk}b;`(aM)(BcgzAReCuJn|N
zwEkZ#-Gh#`nER at 9e_yuj(w6(Sg?*3N4xm@<cjCABL-l*^>hY_r{8eA{c?e|C4$C_;
zBKHBuUg)P(J2QB7nlR!MhfyrSaT6C3|HsjfR5?V+I`t?Ah}B<9GRrK4B8(Fe`(IM4
zwMR1>cq~(eQCR2U(yb`4KOvp(#PUAr$m25)*O!?qgL5Ytj)U$GOf033=%OXgptqo0
z8iH^4JzoZ(Hb8$z!RM3_P`I%z*&qMlVc>5(j{n4jZxa%(9+un6w!h)&m*nwegNt3$
zb2jCh?|f>z?@W4MpOCNmc{!Z+!(y}DmOE at T*b8H{kValuwL6|9k>_1=sqqhz;Ta0&
zw)>I#Lf|>8Awdq)O(w&Ubk<wbCY;8fch8~AYO;UxhP&rJHy+YOfp2F`#<^L$EW+4Z
zcb-HaLSc^k?^P0Q!40&&WbF8s?U at T{u<dMvs4UF51Jh87`Xf(Ry1#=t-&p-`7jXfT
zb0&3R`frTNvO&6J0N>C(43%9+0Aia at T>MUbmg||qZnBE};UYcNffi61Ht^RW>&DZ2
zn_EIDPAzBX+4<gS1`_SMg2U~_2D76Oz1|;F`}V{V4)0RbV90LaGzc?IiKeB}rOg>*
zPX81lklsMuE2H43Q(gjslHW3}gv82KtKcJRt>x6sEWQ5T1ko#e;m)h*w%4|DW3zJl
ze<>@s_Q^@)Boi$E?!7)QVoE*XOyUA49*FF__;_<8F5y$c0|~v3ld^TAk{_p(y>Ch0
z(J-9b-Z3rbd3KIF2MV`KM4KaB+dhcux^B#YmFYM~#Q1U$cD>dfpzFY4sDu_E%bA~!
zlbH<K;FfiG+gldJ;8V2Bym?Mh1z<Sj9&#hByJ}m<w^tP`eWE0o`pXozDfaQQ3;)R&
z*M`p*{$Q)D;~;MIgcn?mJKlXxBWS=H0reO5Nv`5Ld4}1Jyaq~FI<YjAHL0u+mWV*M
z=6<GK=85uVMu#rODu%s~?>4Y(LGF44bE=^m{1o`i^xFW=Sj8h+3A^!fpYwJ-T7mQq
zk-_)n<?-JCmV;rtG4l^>?_juq4^-R5L&!3ETPufw4LN1K*)NF+2aew`m>>epbt;+L
zMCdeAY~#G|Kk%9vk_X>46L<flh at orP7{FCetzc>Fw_x2&yX#G%CEX68Z;_xAIWZ>2
zV(AXP_+9k8PGTG at +S?vF=e?rncY`35EZ}<qNteh5<X(B0%gA#@yT7g1-8c(6b5~i>
z_r8=UI2<4o2K9Fi&Z23^po<R`O?14*t~igZQ^dq0d0g`6*abB`MW@>2SI>E?Q$LzD
z$#ppgQ1#ww_PW^*WceMYaobx8{d;W+>yTz!^c3|q`XZBBv)4SaGlo%>$>*>kdMA4o
zWDjIv1IcO5X2q&f=Mv)ZD;WUsluZua{OS<eCEV0<p3M-H`=j at v285z9k)h3jDuLSL
zHxOki!+pCbSFPWa$mZ<9r|k|pW)yt?Z1+090x!!>m*qq*FXDM8;n_3I-PuEk?0*-{
zcgO4B|G*2Pig2#BVE)W;y}jW4J>KWwh41myzhKK|UsD6eR(!OL3<@2CPg2CW`QrWU
zMYGZ5#~g%^*$hB45y?l^YCFZ(#B4lO>l<4t^UvseU4 at Mt&_8rFuPyyslt0_zBm%uS
zjd4j`+2A!LF#y`?-%`*W(v&e`u?OJeA6BgQ4C}+Qs~IkCt0E0}8IIndwra3=YiVAw
zOEAj8^CXA)=?Z;I<Toy3*WW8;*4eIW7>kJ^lb(P(p at qxH%?cO9I+9jre7nDt-EGRv
z`JNVk^BV{#h?9)C-dYcb8JLi*=(IIRA at U-t>`^XXu at ib<p~@3zOV(`}nSH37=W#`*
zkTGjc7^ELPz_wkFCt=Nj+$`+;Gb=8?*6uJ(E4L*in7~#k2<EY-uKdX!g at OELTy&Qh
zqIoeprG%bqS104$DaX~B99u?bIQ6^~0xK{w1$fBTtw$q at 2wzGcSXqrvTFuv3+2sVa
zv)UB1ZH<DJmhJdLOK4Z>o0pGokuQilU-3B@<t;gu9p+5Sgfbz+=H_4=@ds9)x}R*1
zvG~Gc+}dQSwt&EX68Bgl;l<DBIWMWY9rM<Xc*(x^AH5Fdd7SSfeaA7wI8$cPTJ)51
zDy8O`F>JVijq1XqtCho0Fty_==$P(;r68xh-#`)4&4rqe#d_mX at 2NN{z1X;~GF(&y
z8N-;$npA3;lEVEds<0eR_4HqK+B0Fc!sQXKdy*+IbW+!4PadPsSvX&#E2n?&CG at u2
z1^c9%iaf6;lzEO93rsM$-W%li{-Ba~-0DqOm{#obfVX4**14qP`RB7JK}IN-a=7#R
z2zU74?d*<!?unpJBG<jiPH+6F{To)0mQF}HYZ~ejDdE$j9CY7{J2u~j|2vZWQ`U~)
ziMI~i4vm*5Y~WBv>oTDuagl at B08_DE-9a`P+$Vs>$GmGr5;oyozG4mS5yWIPSOVHx
zdEvb3SMZIR)AvI at uCD&}IaeSIAmG~YPfrNd{F30GCdeR_{)Vb`VgOf^o;2MNLVMYj
zhbQO&6|d{VLtBWcASdsz)ulHh)g$qnb#0O<s$3EibbHewK|it!d%D3#djMNvDvVP9
z8ggH)b0^yST;gwfRD5W&>cpYmbBxvg!T6rg_x_vw*k1F;uV(IgccLmr57 at fRD>(m`
zoxah1ATOk;TpoPd<zaOWz3sP5^RrdnWNnPV=P<8tsyB9m>oBHCqo at 6PQU+=SGiTDe
zjyDO}|H8Rg<+x$~d at nAKub+139i*Y$bPgF*E)1@<zp{L2vg{u0X#;HWD*qH`tkB{t
z#$9%-?I}T at zsA|_+m>`hfz!P;e5ZAP{k=eIZ2O8Swx0W1vh-Ib+bHdtepe|oS0?7!
zu2pHuXO~CQTl~`>8TWL0_zur&RgY=*e&HoYB9rfu9iRl;y93q+nAV*aMxVDh4m^3i
zQL)**gf7B^5E%y3)BRYT+gj_#jd;J*cml3?xhe at M?H5lgtDv^t1FdCwvCtSP?mQV@
zK1XoPs|$$D+ub!?j_|Nc-<ghkQBfLjIZo95qp_+w<cGi-Zs=fE25UC3mxW?8q_
zsDgz`^eEte)#n at 7<OdpjeYSLX5%dcJ5k+Wp*`T^^7;e0QoBUtd{7z%dQO&;pnb5&W
z#uzLp)O~gym7)BBcN=^yCHbA*J`PqOMR at LGW;<*2ht^N<{*JqURb`b|PVQ;0uc=u&
zjsZ3*j2NUaY7o<|L}BE}Cb>EVXTQ#r(~^SSWlyBzkDFUc%DHw at oh0kc-)C`AK>=SQ
zn3$OGnjU%=A1?a at y`~2%+NwIMs=7L>D)T_cta%xywO(nr*~fh5f=e!YT5;WMNsThw
z;uSGdh+?cPCR(9>d~Xg;EYaq9{)9X4bAykkNi&1 at KGab`qsW8<m$w`THEnwF#4*yH
z2{rmXXhc3UpabK)H?+&QcZFXQ+>i5|{t*OOocT>fzU#d?GT>$_geEDat8=g)!ke!<
z2^0o@<(H2u6cI)dJDST+#6g8taBLVOZGJGk5Iix^i!-lqlC3qvBZBXUzu`-_L~$9=
zn!&z1k~Arm9cB`|4!gf$fer<HhN#zl{4?J;aq;oR?Cn7 at SWO57U)k<#w}Wzv120{9
z8@?xvI-9fG2>SD%&q^M5+G=cUAn`l=I at t)j_q~`!|2>OA?S-4gQ71aDm~Tx}C^Z~)
zuia3)B~o10a2uqnk%q*~!58OaV01CfzuH at i_d^9L-}wHB{zUdfQ4O&a4dT=<yRV1n
z2O?ZDG)HzDj%5#9sEQH<S<_eT7v4RDyy3OEPxC$2^<G;~?RSYa^*N3)F$x1JXeS$P
zs1KKV;SVmbJV^mb6Gkjq;qxs7bsZOO=h`JAmfEqlRqMZqc%qxgkUE#ECGAHTC^}0G
zho84r8>B~1uBh=%>cP(&4i~+#ioVE62ZJ7$*XE9U^lgSoJW&hZP?teHgl+n5c$B0<
zG6uI#T at 4*F!;fQdjq-3+-mDM$y|7j5w%9Z%r?#uzzGR6s`DZXOv%%|4U%J}rB+SP}
z6w}4rSYRcm3_vY)qp at 8-iIowm_4+V$_lS{*c)w6}K&tDxF?)5Y8y>d`6sy?IzVS7#
z;eV|Sa($^Col-v+5sChFxfR#L>$Mk$Y|M8I at e|AKaw~f3O?P&wy%7%EE26-7l!;4I
zsM4Kv`M#CxE^5r$+Ho!p11<`w`XS{+F3jQWYSVC+*k&gz=WN};N+{pm;B0zJBaL}>
zdm%DpfAH2vOzSHiLpNGm_bEqq+Lt|gCs+t^C9x<2(gY3klBBk-zfA?wDlA2ox<TmT
z8Ap)1bfKyXY}wq-FtqBm)f0vzb$?XQxN{zNd}!P{AoZ?05TnJ5_Vx^2TwE3}a#K7a
zEtKNYxO!-==Z)|<zJ2><VQ;UmT#{loL7w!d5-&%pyS)scVCPp_{TP2y76nG;_r~n$
z>0urJp2!Te&**=+*pT at vhc50w0IUCa<NNr?58m%c3Z7N{yxx&%GJ5ZDfx#Gf47-4k
zP~lCp+G9&b=(~>toDCxj7yLAx`foj3Ir{>=pdt;rD0#0n8_X`Z3mR*>S?9xBPiWzQ
z?d@$#@62Tr4;ScfpjYqaJbcMIvq5SPsa~+0LtO_%hc}VfKXs~nQOHi#Sv_}(MT{J#
z-kWbO5- at BFAx|gHV|qRCk-ZqCNn!KM(ZhuvN88(a&24QmgJv0l>%WpnfXq5dN=h;F
zrld0Yl(9f2goe&OeS{rbYwN-OU|9W_N$RLi3v9!`7;&?I_^Th3EU0X)eq`bWQU?%)
z1Q_jg)7lNlQv?x(SoHm)q*e+chHJRI(XLmD+=YcC6&Kc?!R$T?vsDQu97Ktli;J%7
z{bGgw8<~tc0_B8Y)phv3eRsS9D|!Gz7 at Jh~em4rwKK<FBiG7U4ciXSqu8c)3X1f<@
zWvd%iiRu37wCq<@3NOQ8O;=qy=}#15I3401NX9P1+YVej*`*F>$bou9UPfOEH_Lw=
ziT7}ZD8Fw%i6sQR^Q-T>Vp;AV`zapfR))rU*Nvq5-Z7AT+6l%JXL2E+Ar*`C)A1XW
zxoUI<BLyq+`RA9`yY4KlzANh;v$!%k5C7bBnD9In5L9DaXaTW%1b=<>3)q&!+F#NJ
z_nzb+K|${&4-`^%IsU1#8!S1t(iwm=dRzD6*gNF3iJc=uA82#l`s^_^(sMljr}UrS
zYkp9;oZQ}kwcT$4dN&PmNIpTaou{<DRQP5~`Y(mEdAJ;zYjN7!_3%o&gUA7snHL_z
z&$s%j`9oLr^(7nvGlp?Qsn__&PUD|;M%h*ZOF<*>c3Eo^dbOYFKC=8v(PG<KM7K%N
zD(~Ez79wuH;?OU7$Q^96?i1Y9w%tGsS)G1oc28C*&&nY>*$K1UXRqu2>icGW6<X(K
zJ&x*SXP=FO-+y%i&BJ1gf%mz&rR1vet?T-=f|dFR-s5%Gd9}lJu$kJKzPajeyOIkc
z8TbPsGPrEckTTy?x7^+vV-eg9sYJrdPW|otJvV;RHEs7?zZYlR`%>7Xy#AKqwF at NK
z>`p~G!}yZD>5-_B`?Ae86<U!&0$FW|%Qq8jnK^cRJ7&UCsCHXjutOb$)%gm0#gA2(
zz(Dl(Z#ac9LJ at Vq8O%a2USBU!*ww`5y7N}L{Q2OQN02!oDF(Da(C at rbjc|<K;}?=~
z0XU{5r75uaH=?VaQ&1r_4a+Hq#xu8l^l=K2h<G!#dzNK0H0e(8E$LZ4DR-d-F1<{;
z9Sl!u$sPiT=#hlRpD%=WqD80dPIHskqFt_25!R^#4&j6IBc{}Hpz4P-rQp^6c+asX
z#W>H$v=Kf7d_{XQtHHiB4?!jyN_r>z{EJgba_zy3-xoQqoPVBhGm^p;N10-H(<-m5
z*%GgB=2817zFaw&GD at 2NGBch^pXkhoo_ at XWP=CF&VP`!=NN+FP-r0zCee3bq8~W~Z
z_<}qz%LZ*2;!_Y|9)~|zf^|uwEh=(je%v}WM(z(i<LL1CSkV|J%l_h5I&+hE94&5v
zOe8`IagL(++?BuM$m(;L9dp-Hf$m4m#mR(J04f5zt{DCmBouz$JBCyXz27CFR-&fy
zq!sTj5jF6<^cI+z2ft<3su)eq4jEPEFe5+#0;)n)TG=Ndzw#^E#oOZ)*dHZAq&=50
zlC%etBHX*9;!kI7v>+>i>NOnH_tIoLap~{sQfG#Xbj<^rb`FL*6{<6?>qX1)O&G1C
z+Ve at u{VRdVu2C-R&jtM-S1vsJ6f8F$GVjs}IL}$z8*Eci6_(Mq#GIJ}v<*HO?9*6L
zg$6!0_~G$A0n`X{3md^%wQKSAn;$5-f_`5a*LsZC*?o3K;|T%wqM^~?x&ZdER-gRQ
z4bXa{T0#Oss6a!=;|?KFu^<$+kiZ(XI^D?uuQYNpmp<as8*Qv(wzV#BJ|pbw?>3je
z3>x8!qT%@!xNL$#=pm*#a`#-w<eA9t9Z&HsJWSG^8FM5c&s- at +Rs_+ocT8Ofd7M<V
z8{*==16RUk{exR<s~?QS;(5vQ?G1}#-_;y(htGJZrAsWeA{&$@_A02O%7b^65G$F<
zOM2!!BNrlab7J`HelLy7uw60P`8exYsrn^a;Op5^9JG?tR97DJw0?>p-E_G>^tex9
z93C>MEj%#rAPr~Sb|>Pf(Tvn7h at g%VlU^6WWAOoUeFHMx4P+^L$;Qc1|EYLutE=91
zznO{k&=vq$U)zmDxfOCHiI5Hp96q|C5}=szoTXysrfy+&RbiChY*U%FBr!P3X64Z^
z1VUkk`5JW6W=X#^{)*P?G<f+Cs`CFXLIl{=7BkNxI%I at 3`_i4ImQs{Su6W&&s0f6I
zyHhH-H6=FOxR3$18|=v6tHLBU>-R3)JZ<HwzVFRTW%bEguxmM$Y_Z6>xSQoy(#U5M
z3Ki at UXEZkyRuxs}mQ>QT+HXTFJb%gcx#Uun3#}}_3Wg9J6g at e;)SJCD;EO6g<++Qy
zQ_ZRV6f&43)EhA-E9aW0hEd+87bv8(7fvGLUTLZN7uI1KL7`;hY(zD(zr(I&37cif
zMJd^W-Z%_Dt|d2*A^}IbfEc;BvU1F<sgNwGIiG_3$d7tb@<$nv&JUd!G>!b~6*SP>
zjrA%*U9cpZU3>J>?TyDzC5OW3Ug!1QkdLodk?qrwKI>pCeeQdSC9cgzEq5WOz8=jA
zrFXCOES$61zC2vyKc!l`sthYLnrq$cV>LOTbrh}R$4p*OVR<|FJ#RObvlmS-R4b4=
zs=ly_V2j`)eG&r_A`FS|ZdK*+uwS(OeO%^h1h1|py^%eQo7FLRtd-7VW10B*ff2Z`
z&x_3M;R?ci7Vy4?S}G+>2nhuE5?5pW6?=Zd(9LC~M;~e at m73E}qzyiI<WAMs0pmIa
zPB4F;9>_JMm at V#n9KJ;UWC^f%B#i%6s$4;_7S5-<0LMMe_c;jWTq$Qpxn+nVm{JeF
zZ?RhphI#G_1l@!P0J_j98t at rg{_W9`DE(<)>++`Z;^j5S<mtVeg1uTzQix_KI5d$_
zmxNue{ny_?S#;$?R9aws7)4mE-(@Bo)|{H8ooe^H%Z8V25E at -5kJ{j|&;RRF0&{to
zz}vYp#OUqSfS~V}Kl(W#71j}7KU?&<eJ`D|`1Q+x at A5@JXC?H2i~YKBmq9vX*K@~Y
zcabMSMMR{KLo}=mN;CEIL}RMX>d;`H49U0s;WP9MKw?FT8U4v&h*jLx`~DV}*+qB%
znk2DD at g>p=)GzJ7Tzxs%o0Ekaih48r>3uJ^?jRhQKT3xIJ{zz0!kZ9gI(K-FOww=z
zv$Yl!e)gG~3yER1;j{l^E9b7L{|%Ck at 7l1#v at 3DVQiAgL%x~?4>x_L6Wel27TZp?^
zJU{t8px4~r{5|%L6$X?7g;Y?=zv5F2tQ}A}o<n_nx?R{256=nt=@95zmEZe*2&da;
zLz6xEm at vyGcfx-?!n;&B)XabxEk%x2*rZ9BB;24;{j`sUhUUyGyMHPaDOOnUps%B(
zKiLVJt2Lr>CA(1FVd21R(TwhcuAo9LTADz5ew`t4dq|;KHSc8+%6|C$m&o<J>gN0U
z+0|d?QD!EVumz~W$5mbZ;is$>qm9lKsa48GPuO at tXY`^D()WGczQ_rN?chAV2LwIu
z3ygM)V~+HZWT<u5t<O~%-@(2zOS4Z2yi5;`ytAp%5TcUD at wxqDjDjJ9FPx$s9<=BS
z0pN4T@*VF_BY%|c#CX<85wGyE{lPDAo$Dy*ITf85G`T9vlXQZ{VI%#E|B}&1V$M1N
zQ33#fSyzHo(|%Xoxe`gOSv0g30)(Yq>8zCh;{y1lN}51K$Zd^z*Di~eEoWwU_{JDw
zGa(ciS~e?&-{@GN*O7f9{%4GvAiw#m;{FM@!c5}mm647htHO-3He~orRPU90b}n~B
z^8GyL at eS;ceQ>~yPCyj@`j4CMrs`O%jFlP{U3{1yycO@>{RHto+T{<MSvX*9S#)h)
zt{TpwO<p_?E+P(SDg3s#1qy#D?F&k9H>{xX8o}4l_eNM_6#OLk)xerYR!uV8iWH|p
zF&JeX)*pG!)q4*!$`t-%Vq4)d&lGmWRlG*PRV9~pXqs#WXxmUvCj*Bf?VRxISNRUf
zAC;i;2;JohInIanLiz1%3IEIC7 at c9>-2|o0F~ZBAXI7LXN;wN8LAJP$$9=EHuj{m6
zV>Np$7t!!zSO<PAKkVO3vel>hk!rN+5Q-=;Bsw!$OTwz*a$hg at YZL{+`ly#%pF$vI
zM<vsY3U{Q8Vlzgp*dqn>CACRH)>jZOg6(17ZxN|^;@ITL&G at 0BhDisQs=0%O#LP~1
zn{2(cypOctoyf__&31;ag at aQ~+10F$jWAqppOK>oIVW&$;k5Zrfg(c66Pf*r5#BA@
zhus+${QFyfkMQ`T{rl$cF<GS5FSS_Y%2j*Sqc}n!*u?v_?RyA;o>(k=?&suTBb2+|
z0tlj#_Ucp|_9vrJac<DnqT8|r6CRT7T6t}oO*Bf-hw~ST0{4=Ny<o0F1%KG_8DwEb
z9z_VTOe9koqGnFL&xgyjyY^aNRvb}s7pM*raJGBoZ^oTC&qWJve<`UnF^hi3%RLre
zaZPYboj5H0P7ho!c=uUHdmcG`dk)i at TzbDJNI67lTz*oOO9D*NoJuV{tC17J8rvR=
zMX4}^x(^z2xLLo-Wt2m9_rsW2rzuQn81BXwwT+=d<$ucbE0tn(hbRs3MQ{Z~`BnU}
zX?pd>nap4FjW&*)Ui^F6Sy{IS at AI3fP`4V1o~yvZcvHgnP{g0|D}>Z>{U{+BzoPtw
zXUFqIn}BCq%{2MwKAO}>4b@?Q9c0?&LbBPA;K;%donez3R8ioks9+#rh6g@(x}H_?
z;CnO&J{UHAcQgr^YLTG!E1z<Cdz_v1!jZo(Rnoc6ibiF_W4uPPudIw>x8%?(<e7Ss
zXV#}V9<o7gcald~|L9)8LrloJFo at SL+iZEXscfH{K#aG#Bmhxk$HPn>YO&7MD_NOU
z*02|}l#7q3u~1gN$y4}cMl#ak6fKS6Lcq}>4)@BQr$J=z$5 at YeQrh{bMe+S;X0WIs
z7!9nfWI{0Z8<9nUmMT$p(8cPk9lYfuM~h74yU*cum!?emRsM;ukUNW6)VmS~5l30i
zgJwy at YkfZok^5(6f`l-N(8~R1!TO2s{!`;J(Ws}^A?^r45au(v!&g^VY=cuw2sZ1@
zKd^tZWtmeJ6)IBi4n=+=rO1vkP*Y2gFKh6+w}KGj$Qq9PMpcS~XcCZK8u|Y2N1pWK
zq?5snY8Z6-;`fLD33Q^>SzA<BhnyiR(LE|FElpePn*H<o;pBdwY6raMnR}wAK~I0+
z+~6T+)Pn*I3Fs!k6o7He_CuS1ZC0S>QHiFbJ~cDTH2VWBpNTF9Tb#{FMxwL at 3G_X&
z!=T84C-Zs_z1$t<_mJTyGbK4ujYp at sOkkI5sz~{?U-I<#owJcd6lUz|iplSxDKCXh
zD1XPC1;@qBZJJu<gs1jwe=>vB<8OlGF7UL+!Nk9}d%OWQ^jC=Av$H6Kevf;N71ezI
zI@~U_8qzvYMZkA_$W#isL!!w1s!Cr<k~OV_=HOV<|5^SX+F?Wx^~i-Cb+o#iRizj7
z%ncVQ2rz1(jtQ|kYdO)hv?w_1be+3z=VQc-rpAm0_Nx~p)8mvu7FC$2nbsn7yiJT&
z*;xx;61dJPBPB(5esnmlMLX$KcrqzMQ^1E9h|p^$@YvqwTW~UDSzKwgaEs=jW=4;c
zOD{JH_658VgRQpc(ZiNsk635;g5epv>xa^*)nCw{A at N81PZ!F{a9Dn;Hn)|P!4B`M
z{)_jvYd4}eTn77Q3;5#d>gt+?XC($*b}}Fl at Tj&DFoz#-IpCL_=CChevx&j#uIzEe
zX=M2bFuv;}LqP^GWsV7 at pUM`PAKqlf>;v- at DS(){{rB at j3QPk`ZQ7M5S`vaH70ctF
zM@`EU#U&2Sd;ARbZg|Q60L0Q{wP$Vxc&pGO-0PD`S;Ew{qsbu^B5In2ufv7Tf1>jy
zY$BKtLcdk6d47lcl)%fM<`pbao>5`eGgdxj!U8C^1 at w;oeqn&-8hrwzp4y>&;z{V#
zfe!-<Teb!4!rlFSBs#g><fQ5hD;rx#LjyB*m{Q`=$U=sE4o_%*e?Lx9jLGAbOW_)+
z96bB0Bl975Sy>_V$?0kTf`VWyy>{zwSKYr(+<$MMI>m at RisMOXlc%NU+MQ<P<E%GY
z9dCg8AGe;UTN&BeA;6wSlPCE7=tdPsRjxosixg91H%F@}qxviiG0`|Q7V6n%w(LsK
z3mR;_NPM06|75)&c2<SACc8)^@_G%13Bq-`Y}FWXVhdl1J0*{*s5?!zeF`;?f0>y}
z;ndGtQAAuGUS4J{E-u@?_S$G*;>8P=>80Fq5-7fanYOx$4RGqquA^$t0H<5t5q3J_
zlMkV&s3>6m1DX(9#Yc6pKs3B^U+!bmVblY?Q3tlo3`QSRqusVYCrR`fqFDL6M=n(%
z3Vcm at +F6vOx7kcCKSoiXiE3+03rULf-fn*|urz_77YBUUP?3V-O at o3N{(Vuog<VfV
zAZa0RdRqRJO}}*adxj66tlS8K+|K0jZJ{{pmC*#-moJf_ygu!-b|r7a(VNFAcxd41
z)~J3-P%DaU=7HX1JGd7EiAxJ?X0xPo>S>vyswS?kjs=KhfxNtj%c7zpYV at xI`McIK
zVKJZ=kG)W=kiAh*jx43&Ml1E-x}U-kg>Yr^IU at S{d5;1(ti2#(4-ag>`>0lD$euw^
zQ{27Y8teP=u=jX<z~yp+a`W_BxQM56*9nLtUbk~0b#--3(L}%-X|vIa_ at CUHE0Sd9
z;GiUxy3Y+Sq5jIl!&46s-mCTd2muN2J;5zL0lzpLV-xS`%1S0Kri70E^>YLB(K<*E
z0MB0H%@_oq;n(C-oGi5E-s#9=+tZpbz*6j})n=b?fP%Ng2~znzJ-(UDP!LH;Nx;M`
ztgUG`E~pShfnfkot63(hjGp^MqqG^9>WdHX6Kq0432p7Hh*o99vERQTUNw($>C}Ir
z*==wDX(Mq!4h(%|Qec^>lc-r~i#qz}x3 at QqF1MP90LHNH!x^5m;}i>i>@X61&K4d{
zX;RkztWvoGlZwi(qmHE|K2lOrs&z3bDgqtM3s&AylICWW1nH6T*M$#SpLL1`z`k>?
zHl@#n8CFdDqBmN$<;?c?+Hv+rjmMa0o==^V&{m5EnUtMfU5-F)C(E7h=wH**(}ldf
zyCSBCtjXgD`L&jrme~+bT{?%-Gpd9=p6 at L09v-6hHv#i%;*g1tkB<s>MfrA7>QsUi
zkt=8F&#vcoBA4+Ik66;bf_>E9VIMustRA0x@|jy{D^q|mk+L}XYqoHot}#)orKB)q
zNSTJOc(EDxakf{YU7qZ=U!+I7YTQDgtvCZcdu=($$_!x;cpTouKjc7yOIeE=A+VVC
z_I2q`5<uZX7APnvQ;_L~+mERUo3F0j96!|500NqUjSWJin8>EHk<q7vgM$+3p^j4F
zn%aQrP}mL<Le4R)h4hLC&!_XM5^PnP*z`lhC_Uxat!`4*?%l+7YCv`mGKCB?kdQPu
zM4baZgs<q>m59{1q!4~5q%k_w5VGu$)VKrGK}47kA&Lbe>fan at -uehXS&<~q4l_NX
zmmgb{<rd`xQ{Q09Ddp9n)oVyJ6lf?eR>WEQ{Uw8oR>aMgh_yPg$b=bW`Xya5yS5ey
zyb{5x=%0b<tkxR_OMwfe>`<VAusp5h*<@dud|84NxtL_*+HY27xZGny0|SVhoE*}r
z3*bIn`RZTcA+FP*e^suZsTVxFm6lRX4OfjH9mSl~R6q$&HjKy?x0;arRE6QZOhKMH
z9#JvcZ2b8v%x2PKSMbVyonPgyzo5<T*dH)iBwWYX at D86Z;`>qA*Go^IZ+8QA5D>7p
z at dw87_Mw-2@#RP$E$f~wW&H9{c-ZR%{T_7xH<iyHcT!)=W?l(oLtKx;pJvOmgLDLq
z6#~C`J>E44{?>n29hM|izPc({A;FP_aAh-p)UzyQEms~_&2D3t3$8uW=x{RC3|_qD
zLqJ6A2N>#C3iKY55)xuXx$TDY3kzfj8CJ?1<s)H&!G+Y=xVQsAak!f&KA>z^+0t=(
z>6eXGbDK6DdfQBKzyHy<y at i-}=nc8*P!Kn*ijt6OYN1M^SZP1ILc}g$4Y)tMkUS)P
z`YaI8$L|8Mk#l@~(+l1o4IRB+O7ag)UJit9b}RoT_&ZO>1D%NPfguLL?~|>yU<gsp
zJCokViyQP23~?0ZWPaod&m@~<=_csu!`#}j3#FMhMEv!@8P-9VDUiSF<I_&wD?{(=
zfcKR|4_=OLU0v1>(cFg&gm&rwJedbx<7R5iSCI!GA+ARpoh4t|X<XXtx26xc8KU1U
z$G%wK64bGh!n{u^OXiekGAdf%7+l#FTnQ>vzXBQ_8y`R0Oc4PAA-}Ir9~)5#y+D!L
zz{JEvi$E4#9FRq#EE(t{2%OLpa}f`fmYKjegR86QkKG4cT+T-bKWnr?$t2 at st19Yk
z at ls9IHV>ScwZ^ATEmOH!0l421oXzIrag;qneK`fV3u at 1z3?;~AbyrfdG(-yJC8m7}
zzT at V87l;<SRM$xJ!(ll6Q0cbX+BvX+#?SGANF!(b9nyiO?{RrA_18b{GVbiUrC_FT
zg+FeJ78FoWR!|xFId*!IlRtu2;ooV(3OXVzyh8sp(O_*{mZRfN*Y$V{Q9m;gHsGtK
za5{4Xt%bo&r!3zGefn(vMgqM?B)TB0)ABIb?lh%O#<H>>xoIqP%`G(duT#OSP=(bT
z at oGK8X%0tR=@%fH1Oyn&`sRp78X6iJn@>(o0xUBNuljJq0|2-!_YFX?2zn);n3xy?
z2L}{DK~c<<o$<_{-o+$jc#ZcAOVps6Jy9jHGov+K((A5-zA3 at GFr=6FvFfsA$VQDo
zuuRE{7#XHChgLc(<{SOykBs>gQW+|wG+S%>>odw{<5i2hy{#@n$$laUt%=<Z;%I#V
zFy-r?BgTDD-iND2hoploh_~KyDTi8Y`Ub5~(Q%nSu=&%Y)>pm1MY<FD`4Cs(1!4mE
z>CvQ<$Ii1W>H at UsccTX4ke?uC7o=!lzD7kch<|=%Rjl_^vRIJ5r7AyBTX99j_)(%f
zcIZTrcgu%NMn-n>?;n~3U;{AWk7jUaQzl3eC;drgH#76b<T+NUQ2mi0$d0?KM4Y*v
zD_xR06u2<vq&qF8sdXGJcH0m3HS}K8T2`K)qDztfG9k6V2EeFHEgoqpsY$yrx at 5(8
zl)}LiVblP$PQ at aKCt_qgh(+}LbfzV8x+X*h5ufL^EC=%)|6%{Xgag9~@Wz8wR~_bc
zqp*ox1tzt^==75akx!VdQ1^`Qz(5Ncfkx2fhNv_FKEHy$2+ggde%I1{G9V#kh5sXy
zQl31!jzWDL7fp;T$!aLEr^=>qCK6K4U}<(=&S=dR9M(t*s0U#0*o-BV(19(DAbnv%
za6DgaXk;rG at Lym%F2?>vYM4n0-~gcR;dkZNath~H9)5m)(qUPevJyVpB9x{)_(XGZ
zxKvYNC3NOKE4{7BAY!2g4LU<M0R81N0QhGey}^qt;?sG(`>vfchQy7+?$}t`RnhA=
zjS>ig$XisaQ)e2>5c}-6o%ZDuVQ{6p at zof}D6a$QB2pJSKA at Ttf?&LRVTxvnT~&pA
z@}mcvaGLmQJ!=Erhn<;&(+%tiK^L-M?jzFADj^zA64G?U89~=Px;VJ1yA+3u+k7nK
zy^KKrA;Ti%QlMh`GR*I77_t7uxnk5anxh+86RFkK*tj?(1SBMRXJTc at -pWcqdx&ym
z<+w3aRcbL0+i>s<Yl|cQKc2n<DysJT8bPGHySuxF?rxD5q&ua%J0zsL6%<e!q?;jB
z6p)4ikr=v!@9|x~|92Nl!R2u8+<ESE&e?mPeK0Yzd{~n#YkGR9TwPsxHNBtP+rLi?
zVVHiKcNnnQ;?Q0p$9}kzl2_$o&NcVq1cK9ekTX`1pF)OTJ7kar)qI~1W5{A;td!Ni
zeRN8SZZH()a_~Q>4mz3MdL;9s3Z*bWSbXP?@%nQ02~Ym*)W*OYQt}5ux1T4D+ZCv}
zevjh4 at BykXd%5uZOXu0u2Xc*Q>JJFt1a`7&^9ZBzFiQg`3Q_Tvz7mFpEWqHuUL6kz
zK>P5>!w-ypMSLr2iW9k at _3iL8due1!DM>=k{i9`IlwvXT>6P3tOzU3z2fByVt)5xi
z(W^1JC#-5M(Lqji&{~tDN$3j@(E0G)eJNw<Vq;@pE(?PK!Z62gX=y1sLe_lhn)cgI
zLM8G|Rj6*=ujcxCdiGcO%w~(`Z&AJT>`11+B821AKMilOhi-z(nMo~wh)`oeAuLS#
zd!zZX#{uWZ>$}AK?CW037EB&KI|!7Z%<;%Iqd at oH2Ju4toS6ML8U4`buZll9w?^e|
zo)Z%3>)Ta7^s#*;pzwn{rC}#T=$hvlypf<Lx(h at 69ZAaX({uAZobx$BI4a&{rDZDE
zM>xug;>6n|EW)*16>0*tkFfE|7hfc-EuE9Se5D`~hw`aWm+T?*8|lpSvp{L5xk8XJ
zfG;SlrpE|W_MilA{`seMO?N}O>aDKwd<O(Y62wx_*?7?^PPS=SpIvr0CV0M&*ReI4
z_R7bHFxMiG4cwgVGLi~?@OlDmNCYSj0T_`eri4F9AZV|oo0T7Dm*XR#Z)k|QQEru|
zOE~@v0iZ>kvj<htY&vDE<b;ZY=QlLyghO3SbN1huYLxH4n7Y{d+AVS2OL#{$J&&^c
z=&UB1lBKww*RH#==V+Hrxbm}8LN`CR at nG-xm?ubb)RUK=pZ;`0408}ymu!$%?K+}H
zYFeSe|F4#x-&HHLp*~TAIm(9LICDlgH{_Rwd1HM*<25xk71i+A7;0nhtrHm3oaxiD
zb02qX59+;frrejo!IYrTsPEK`Q8<V!WIMNSWW9-n1z6uQPv at cy>by|<Z(~22(0JeH
z{`{mC-KdhC4XtG^LeIi9MTAvO<c-UFLHlZB!rQ<<Re5?M1&*MXG0QDy+$Me8280|b
zE^~nrXl{=ieTEEsHvR}Q(L-)fb>6OchAuJ!&`B)(_5(`?<g+fz!~%47n^2S8DZ$JP
z{nXb2hq{J_p4TT<f7bfKjK^*}iZQk$0K@?Bg#uyM0U$s4Xf+s%FR5=Gu&*lUt-c@#
z7My;T)($!n_)Kqs0=BszFM0^keI*bl(j{6x3HICQ?8YhdyAv&$L`f}Xlc$TKPQ5{c
z#KNX){@vYOL#iBGVx$H$((-5Z<UG+d19f-u!e76Br8G8j&jG9y(*~d`zP{Nj4cS+}
z&DJ#kE0QvREtL4_pMr9L?EviKEhwD9H-zYNS6MH5yMbe?YTcw+*{CFnATI|hqSaRq
zoaE@}p?fe;&-!a(k=Z7}s56n9XW%FDlraoLj-s)JpA+3f`fp9l=@{kZ7Jb1fEA{G{
zKM5>g!@WyN4qWo`lGzsoK}r7lcr^uJFwMgMkuKr3#())=s(!=DGdQ8xpCiD!FzRbg
zh#r%<iwDVP{dj*Jxt(^<DI^9{GZ8S&K?Zp?6c!`nO{uJ8$H at 5G=4&gxk9i5- at Vm?n
z{2J{B>W39a!8HeYjx)Tp6Cw5Oy6<i=+X$uJi=SP=6 at jp4e4GpN^zYw=x!CoO^6dB_
z*8;P?djXNOxK!Gz+O$1Z+;^S$lH}QGB){`2BOmCgYLh|y{As2pN7}p{UH46lKAEf&
zR|tXDu7$H<D2P?0>fcTI_#D{h#qv4Nc?t;$K$d3Jd<Ap~69N@(^_{0RIL`3d7QV(;
z>vd{Xe6mYz+k1c6HFS_)-QUa!AfntNu|d38y1>9d1%;Xw(ipGvyaYR&*;yKXGY8EH
zUr3R9$jeWkgi`bb^rt0e&d==lM at XWIS4!CyxwOf{Cev8Po(Pm+Hx0a{iyA(IyvSkV
ze#bh|dc^uK0jw}1X?XtA^6S#4rP?VMAA0gnnfG)&U*%X`JuRG=#C7Rzy*$f at 59~lN
zeQErBcn@<rrz|qqY1FLIRRGqN=bzaNO(9zaUaDeDTMhWvLIu8>zc*%0W)d4JQxt;J
zbWL|}PUKZZ1SXpmK!)B6YUUrGx!AbrbZg|Bv+1#OY`NNvK7Ffp7{%&U((NS2GHCl)
z$d5Rd&Wnk3cz6h)k+_3S+chxC?fmMBAx~qV`5hUC{S9T_HH`HzV{!Q;t0fQ90cgfZ
z7rrNiYF(MSVb9&XZgcj{R|!<f5^!=V607v?mk;>3?MNrfM5YbcvVQYJ`~1J9HDB3&
zhmI}OI8|xhBe-O{iBw+ea?IaUm$sT9AxJGJ)3^y#kqb`*@kEy^jU?L|gN7Ip^cY0S
z(Fj;Tq){y&4$*c&HCytwS8FNjBxv*Zm=;>3&7JH&gY>5*C?I}z)fRx*m5Y!`e0JTM
z;Am3d&Xxc8g0PO>XWH&4 at Oe^U{=soh3!gr>=JR>S8~9UXT@~u-h5|C2iy`?@M#i1k
ztn}Jrs~=Omnk|eZol9f#LS9vd<cR4}@mc3iHB?Z;OJRv3mu2pas-M5P$YmYP;_prk
z1eQN5-sajGGx at CVJDk^;!KM3{$>z>O>WxZe^B|r2DI2oTktSzj;sIX5s|sxAZx$`O
zu&Jr)M}viJ8 at jcsyqygV-_ZF|<6hK3ov+I?9Q^Vl7*~<H>UKX_%;m~^2YP-={?5|F
ze=2JpTQY1aByu3m@@6~}@yE^7rlX=oVmT^!=ZWQ6q(jr6ch5pB_ at C9<3H8?aFMf3T
ztv4pCs)Qp(-F}vdS=n)dvyXM&-D&}Me!k`CDnwO59`){dz^-Vj3XV&4{3pTZjO=9m
z+b`>c-kZS+qL#Q3am}YqxGcd%%zeS|DfoDhQqEfbJXS*fw`_%-kX<<|e(~kaHZnBk
z`Lqg4qHtEy1gA)z%!mvVa{6S76BZ*s_h$Df^v0=4xr8OE-pr`==lr)EB=#x;vD7HJ
zGSubI=^wac>NKuE+~ZA5hg@}-aVL%U3(Ok1$%S>r*!`q0%&mH378y08sK(d$^X(H_
zh)nM>5J5ZSGjlS7bn%vz%V!q;xqjN~T0aD-N-N_}t?g$Gp$ReV8wX}vr3JwZaYg<d
z>~l3|Djw?M6qa~y#+CwIU0QqcIR|cZZHDe+xweVo27!<HK{MYYTpFR0BvH0>J8}Z!
zm+gE6v2-INEFP!hcknaV=!dK7wIQYu;(K2F3m=G=u&`9*RvILHPP6HY?{b$FixA{t
zC#>J^@-Lf|k2&Jca+Ymw5pKuF*-v9K)pHaEO}vZolp?9Xh4T90J+q-Ux#%R$*SFD~
z?9j=#bk(oTjVhB*A}Ngp80h%?hV8f$U*JC7^l*p`QF6ovAPeihcU^W}jMlb|W3{}t
zE at 6hnh@--(Z&|jllx9a>tft;a(Ye|spJAm!0fy}6o4F<c5@(qn=k*?Ra-$FHLT;v;
z*3bGxBbB{^J{<QL(N0MK2?A-!l-z<Kqbmm5vcgBv1pB@#reJ3m6pNl70=Lz{%Qb(I
z%ci{{h1LGCF;+ at woTEla4Oh0p+yx(mAALbE9972v`EZ}mM{{uO2jgif#`4#U53W9y
z1gP{_-es2?gK+ at 5nwXK*BSZ!;3Mi5QkI%|+4AYNdoHMyA_E%Z-1pqvmz4Nrwl+NBy
zPfCE(0!9FO_A<YE44MV#Na<RJ7Zt~1nhOBGiRR63U<r{LNGl(iE`0|8NX-Q`dZUX_
zH!m$b9wG5|T at 9a1M^^mz)`i0vlO*fKA&AnD`PjDJgXh6lEq+_ at xm+uCgP|{9jFYKD
z5lSAnN#NJ}l>7ykTUc!tiFYNEDHYn?BqD#6QMmgKrL6{`(y7P2e+IAjIPl++ibtb7
z912_yTouQzeI|Bq-}>eMtIE`4_XY(XCUr$b$`R=KXI6mq^I^Zl<F=LyZ`{ebkyL70
z*oAI#Ao=s7N2K6OcQ^U at s|H~QY-&in#Bn!4ok9JdV_+mIbu+HLS;Z4lC#c707hTQ@
z(0Y}c1 at J{mL(}x at EnUnIFQ#ZJgIoq--9Li%*seN6CDDO_qb#vJUfzX!-xkBuvRDnd
zv<!=Uviarm=TfLODgThVLWPougP^87z(aX$h at +J7@snI<XZrwQvpvL``nbub at h*Vu
z($WJ at i+MGQ=I@^Id0!<`#|8^LChR7xeOvo at gr)IC$~b}c)_!-)CB_5NmBmfl^`8hK
z(U4oQ;IkU)0am$>qN$d_`z`Izu4j*z>oC64DDCy0urp7W7mrWQ_t{6ZNj#<{9x=mu
zB@<AjZj`Slazo?&ETj|D{@&59`YyJ4o;^dZv3MJ;I+w}5b~r-eK6HI8Ds|nDqot04
zK8Sl9w08GzZ-43K)g1i{@>hdg1iw-q)L-M{s-DDOU8ZKs2C~^EUU9UEF#$gKIkWRm
zf!4?CsT`%B-Zm<=^@#@TOyyV at x@)|PevDSipXjm(R#i?Dc3p5o+WSQo^UF-ulI%j$
zz3b=vRTnQD=X!1wY;)9P6Kkv{y}dTDB9%gOe*Rt+bqA3%8K-1~LHjN|!}9;M0F?d3
z4epT%g0Iax(XJ%Vk<5bnxjeM)pEC3qtuJ0S0X!Z>{JT|*AEox)6EOUu%t)bkuh+q+
zearte2GQ;Bp!4kEPP%yu%H8wTBoyuKlabcM)M?X?K?`bx-u4-0Ekw6GN*OOg$ShhO
z?XO2h9}v at g-Vf|Fbs#tWx!Qn6d<R6Ft9uZI%koH(-)aJ&6cD}u{6Xq=E^YI2*<D$<
zfUCew#I(V;BP=Jk(I%hSz>p{^6J{tNe at I|xNF?SAr<WaniI4w{%Kxk`B%vI&_c(Wo
z(J{J5Inh(Rh}gRh0xj at U(|IpQ9~BFAbtD8VC16n8<?W;nwAL;{ED5jmB5WB>GOb7f
z>_u>I!NDVBve7qm?>PR*X)BQBg!R=4HWh6ZpOB!st(3O;(^4vlK=~0R)H4 at bL^@JH
z$75Ghq;y*C3rF(SpPyFIR(REpvbqR7dbq?aibZOKPjrNSyhe<DmW++H at kb_H?lrzu
z?H6Gm1q4E5)N*fM2dik_lXY?mc(wF3L$`+)!f5d=^}`KPSkzF>1GSM2V!P}Gc3naO
z8l|WQ0vMAq=xljsg7C$t at 7B=l^-o)nP8Tx2**Y(5(pN7Rx)d)$DTaNc%p)1Wq-xKx
zMdKLf#k}t2Ax8j^KWF2B^4;uNHxtQuWiX<C9X^KD*pv~jS5)kLdk#5xhTqZYV-)Rj
z_^FaH!U*B>dVo{}_i9emx-LMKTr|_-Vkrtz#f~YjfPfx%tnBmicwIm2lGuix<W-dN
zNle-UPw?F=@59TrCocB`cOF+^knqK0OAIcF at Xh*PFMj at t-LRC5ig4~MJ9ws{iA;!`
zSNy5{e&Eyfo_%jJ)p0jo-Bubv=S)^Q-c#&`V-X>gvytU#yhSkBw(!T5_Foz;E^7FA
z(Cy1x#BkzEfSwp%?xE$pD~kPZzJzx0Cc#Mv4d^@v at C8>x`iTBCBV%~oJKja#;SRB;
zv1EYb?UlSu<v`KnRafDB=-1lU2kIDbFLW;n6(bz;nI`NZR1RzsDxOiXyX~CAXF3yv
zlJebJc6D7Y$g;F{33xnQ!Ul#huFKZtk~GM(?6Ju{_p0R2cf+tGe-TsD91dZ%^- at y=
z&7V->>`!rb?|-I%L$$H!Lk1^3V2{B(QdbE)o9<y|GRvJw at EqxObff$4%kU}bVB)Y#
znDiGz_v;XsHE+C`V@;WF`u;cW4|M0}HE{RGlPgsI1Nbt{^((Wlx&4)$#LJ&ul?t9P
zUJ%|cx{U;w`o6RH89@`e&wW4HHj1|->3?zefY|g0Q-}3y at lwFwi^Zg=Vzt<0!E2_8
z!;AK)_r$%pBbWh4wJ!w|=>hSlXKv$chnCPmHFP#z0uwL<8Qq05VWK(ae-OFic7<7G
z*>}N at F{OBPnDTT at 4twPXok`ZLd!4BY^mL~oY!f=pPCqq#@}b`IWwLnWf!~Muo$wQ$
za!#`IU2Y2IyPN#d`#zNw^en*Q`{&q{%9H03618UNh8_82n$Dw5e}5{MDO00&ME(eK
zwuBQ0 at 0paYUprX#(HuXl8}edO>8 at A2VEv+bG)(pAERAU%0~0 at ihyKB#+D at XD`$T2*
zFcReP%e_DcuiuxF&>Sb>=<Gzo?@z>W$4T(Zoq(nRi7N+>9#p^kEA^M8;syxCrV1a|
zXAaB&T_yD1UCfx}YWj5PtkQC7w2Ud44Cq%hnALCZ?s|E8H1P3##qW3POLf()7X+Um
zq;7qs%q%)A1~gutMvkcPZz9JRtmJcjjt*w at 8MvQFFJ8QIik4BrbdSX?VOmg0q=zwq
zLZyC80|^2{nru#2VH{eaSoBqQ5VRcZ#&fo-lzZOQPemi#@l{CRY^P;Ebscrs?DY~1
zQiA{ufIk{9=IxSBYIQO#ayB26oQV;hbvUk#@4P57+oL~tGh<YE`Exi+Hv2MV=oHC)
zPhe5De<2wl9qXNLs&jp=%LucC0z8b2CVxv|8Muaq!)Dlvz9d8KI)uovR`H!;t5q(I
zQJA?VtoSLIg8<)_i?Bc?ha0d-y)Rg(&Csvj%e&zu_p<3|lsLYqiW+O?1eIRr>F}fA
zWMQevs=0NjR>Je_WenR|XboAv9yty?pUhZ<p&#m|=GcS`ibHp1gpF}V+mU8YRY$ah
zXQHGLb#_!=Gv5+AFEzolimtN)jxK0<P^+kP#o5SI%v76ft^ewA9Gp*`hjwd4agcht
zTZxgwpI->R6s0yVy%QRIGL1#9#ZsTNd2BFVpypF9Z9|I3GxtPs<aNuOgVeJWpNDVU
zYn#DLb0!BAxu5Xy>+1)aIXzRSIQX|jQ{N`YkocJc>438CrrEyMX5ti!`K&&LUk3
z``-&v3xDfu1s_EYT^n6a!xk%u%U1qG1hOigV=FM|eYP*hGb-OyBU0p<V1r%MzNz&)
zL?$CTmts5~=dH_%#WxZZE2<4mSg0=UCahTm3;m?!%`QyEKv}vTd3!>mV$Qu0%FyL!
zSgl;u!+tTf<G8K&w4 at oyNf;Cwa%DQW#P~bYZ@`o at x;avGR+4MNd?u!FSfO6!r^4Jf
zP7wbZj?P^<A{(AcJ>HU_^h_-!tQvwE5|Njig3K``%KQ_Gz4>`YVm+IJ^n<w+U+(V~
zmY^ehU;lIqk|5=ai>p?-xSdyYzBiF<0WDY^IT-F!Sq1V8A0ao9<SIZCu^<%9Ctqi?
z;;la1m&H#DE}|WsjYe1z3Ey7*8!L>-d00!M`|VrI&t7<M^Lo`EcTqeV=Hg}c{VNNh
zN(}rC6LZcTtgH|!0Cx{~Qf`oDy)C*rz3DEcS(MKYk>;|^?NQ3=pVl#A{n%crfndJq
zyvi}428U=@=4G_y<|DR7zRXB}f&C1N1Q9M+nwPa$_13&43&n{`&`A-=PPn3arGMU`
z`>V<bruO8FT}$(7s~TwK0kW+HLB$Cdjy)=P>#v<qrQt4XwO2}!{!x)EXKvF|c`4nh
z1_A=6sTI-D3IVq6Y**?G$KL|KPqm__kne~Ulx-lvDyo7l5;=ih$wfHHhCc!9W6)`1
z2Vp_Mr_i%>t(q9VAFSO*&RKk at i2n(Ca$Hng84h)wp6Rg?>TnV()=b^Z8<*b%L}7+G
zi3&G8L&(aJD+&bC1=3g`o^(4y0Z(3lx0(vMDyOvavu{N}${!K&<ef!Nr_FYR0vqTQ
z;uRH*2dMko>YqA}cAv)BG#7?2c}G0~+BE!_+pxlb6qDR#{Soya_bsv0 at uB<TNuqUN
zu}Ghwz)Pnk5k68fq2SZ@=>HA{+gGvl0-s%9d3oUj8hG#UkmzO|pT`>fsGLTvXlhCU
zI1Y^km)d6t-sX3#iL(Hzi$cM%UZ~at5MhTI_Dyi8?5>$m7vI)hFR9I+J1L;PFfz(r
zA<=WonR=V&Cn7Lm`_-4K7}oz^;%;XG(ujY at R4^+j#hi3lSXllkV*auFVp5Y-_4S*7
zezpL*RgOPTfjv9Y*0?;%Nq}6yV5JurP6Dq at 0)%iIel+Nrf_(gQmqtA<S1@;(`qYlT
z%kP+*@4T|H1F{jY+FeMt5NoGL&G1)K@~p#`i;j-3MULTWas|6Ha86Z7<3(pGD{J{)
ztd0RtxXQ?arVZSEW{s4ZRt3~xoMI9gNJjZUGv;+;60O;N!cSl6bt0l_SNSvuAteqT
zA!#hKxe;z4wwYywqp42+??O46#sdaIXq8Nx%U)SjISDsf3b`#bquh=(wl;U%u0=HT
zUKGGqvvYI0-gk3$xk*-}^d-<Opd14jCJ+|?BTqpTNYr2u(}qo$e*Novb at WTr_ctLB
zQ$@>_(NZ7`IoK=<1K2;wb@?-0hDto$^y!pY at qOt*C#jPp&p-MJFXE#s5K*ErjPNEq
zMqL9%XuSlGP^Bu>6K{67hhY1Kz;qpgRwJ$+zY`}*Uzp!t*!LzC&ZQdl?HrClyhM&}
zZqO8TfUscdwM)?ch3Ls|j9KEC_|h*>>Jc!d)Yt61daWP%@B8mXYO?9lv0))=aqzQq
z-)r~dK%u1y&)~DOlA$&lilJMhzuc?ci~Z(dS52b7O+f=*MtPa at mK0_Cg^A153;mHa
z<Do0*Qz=O2%@zEp;C7>H($upeA4lqxwgmc*0|1;TJ-O_!E|Z(!Dl+~UxhJ661^fvD
z=bLd5JHf{MFPgj+lBoUe4;JB%-jFWRc at E!Nk`$9o3 at 3CMB>k%XHi+yK!XwQ3 at was9
zc>|@ogtCT)K+3XIr3x0F;8uTKJ-Y$Z!1}_~)<Vf6apFE!`$LNR;5So4$Z0&Hp<%j3
z7*pdCGURlyWOE&-FTCmfO7hx|+(;Uyv7QrDrKRuI7ZZft;|rpakSB{trF+lxs6zG*
z_~%yW^&;x)W__^wx6y)+SG!K8qv*JMZ>~<NIofFbZgX|AP_67(+`63vm{TQVOCa~I
z!Qws0H2#CwtYwJ~*K82}+1T8bUUF6&K7Ts|0%RPp3N?Jo-4#(VHH}{fD?h{X6>H(d
z7`Da(&m9o>B=MJi#v?Q;M<(O5`SK#ia6Ywzh%i(tDY5gd>Z|Hze0A4++lJkpASHb&
zL+~^K<@$K-H!*!Ce6)-OAbHcP%d+7{OCZPbNKi7yr8>e`8#RwhqhAZba|`;V*<K0_
zKM34p$p03bszs$LA7l4U#yu{ARj;(38(TUU_wZmXIeUWdel6&ze~TsL-HTrd9 at e<S
z-<n2)R-36JC<I%$kYu8Y!>}#;?sOqR&quRS+(sKLoAFTP=4TPOB7B&UDwj(e9N+!c
zLclAn#hZcL2#$1KZf?5KK&7s+?w3Qf`;RQqmZ4UJ2k_mscD#n=6k8S)71^3HkF5Q4
z4d$BZWrwQ#h-+SxhX=4l_SJbCH<0p!<Qsi;=UwlF550-1x&Cj>-s45eI&MdOCCOsI
z#sNsuie|<i0L}s!4jq>D6}po9g1+VmiRfW}c(q7-+BZ6#KX}KWEn<{X;0<^$-H-JL
z!JD*WP>H_$UJ4iDa8aNu6^CxtC=<GLxe1&npq!kK^X*XudF)SGMt<T5O8-o7VonqP
z8>;SW$V!Opw1HU+McG^N<goY at hM}>jh>DCyFZ0bR`4RIf_()elH~x!B#6`n$Su9<a
z1HLvyAiOuX7k|Grd{m33|HE490rzT}YlBgFLkpE^OK4FydC0st+gW8hMJ%0 at -sCs5
z)^a|1dH5cV$V-(u_o1s)iahTCCF-&a?8cwaCkZ=~NPtw#P(h8VCeE75E9>2BbtF=Z
za9y74tSSZJt%V^v(<}xXhS~cN))#xU){C_ql<ChW!a0!7 at rd!TC&N>Gy*YYPhk~;y
zVHre95q5^&E**wj^X{<yy`_AqS#kl7WIT_g7cTgSRe?+JyY_8OFg5vV025KLEjk%D
zkIKR5lr(Jj;CfSJq5Y6(`6U}{mEC9Koa&3^V=l)!We}lX$nM$o<*&7Y)vF#n$yYU=
z{zG4?Oa)Mh2qZwaai939ImCahZz~SyTAf)|Pfgpb^=m%4h^6m3>UaiqkM(?m8U<QX
zzc<lR>-|~+P!GVV&HDE2=9w{N<QcFdL(fVb$(w(2;wMDoD$KY1%TWqHC#P-aSPq){
zNk;LkoP_|lw_hoy?tMgeZEaDN`2w%el~ZrVP$mqv`*{#27^&~}(R|FVmtWM~oU|DK
zShkE=`&C0P?L)fOe%vK`d-7NGbSd{`93HKMT?iBU`X|fyw!V)fYqxDd at V&MN974)3
z(@j6Hh-97;B??4tDW^TD2vDeh<}W6y8=axg!Z-IBjbh<hB(Fl&pFym)KBA0*(YevS
z7 at n{LGKc_g#B>qIhZRHd;@665ZVeorW`5~`AZjZxMU^ZqL6_f_v3;`nF^jc*ZViy%
z-PTuTgr@;}TJb_87IBtom at B@EA=jIIq4*4K-NcfqNdQuQ(|7F`e7}$SrUREl_|M3W
z(V at Kc9vdX^`-r;58V(bJU>E{U at Wp{>hA%?&SeN+czD<*NB1nSn1k}j!a-ug7uRvle
zn2_knF6R8>gJLkuxn%T9ozd2A?$sA>GyfXuFEtN4R!`mVGJ4RBR(!B-*Eh$v;$}bH
zcrp4CscnOCmseY>D5><bSWmU6CA%)IVD+z6)_iQYl;q^(ti>q!s~r;wTLQ4ApCW)-
zC-%Ee1ihkz4OV!xf-gnON*@#ZLM^oqdN4AD#e?|${tim119Rdq>aXRdq2s?dRj3Ry
z->@8DkJzt!ggJGO3^n5%4 at Cd2%O<y4h9`9*K(FwaKCfdv?o*vOeoro!6T#ezNb|tk
z|MbNm(y3|W at c52*wUqS31+H2kS7XRo*NK<3%u}lBx{bEAt3{^c+FJeLl?;jGL8zwn
z!l%EpxO4^@g?={&ANDgz7LE*lg_k+|Hsxj5XGL#wfe&N(6^K}<h+tRtMyRSRATtkN
zLPO-|<OD0QTgMmab7*7I^QQ>x8k2S<v!&UN%~jD-14OW`oPtGKq8J#VH&Lgfth*$8
ze=7lBXWoaONlu^5cZ1O7YJYeQ18d;kzr)8)&p4;kr&#E~!N&n{uWxa{eQJHAGd+U&
zNgg8-0pOv+(?0O_TySgU$_?=p$)CIZjFE~yL1MdN*FmfQ8H2%X5kY%Gmxh7{js%mJ
z#>7AfY_)uOZz7=2<Ksl9+G1BrtGpoiRF?L at 9wZbw$OE+Dh02m$vii;(n*Y7XHgqPI
z4rH!?P(t#7*@C_ZrrZ97;ks-a+^0b21>!c4d+^Hv2>(qW3v9|jlR>rScYvzgY36 at -
z={e%J354**19}3NM%-79lF+CvQEPk-W2N&J&>;^b)N_X#|1ST3hc!2-K#O5?iS$5o
z3|cUFG1W~L7i|Er_JaRI?6V)Un#)T|v&+j#K(g&A|L+3-cO*Dr<yn7>hr>PpX}g<q
zK$oU+OGkO-6NIX_KxhpL-#aNnMOo5V0005Mf at sJ5f7usEWa%@&)y;p%NRM|ln7Dg4
zJosUS*3p2hFs-tX3ukpgf5tVV7R7yzI?K at xP?%sMv43%#i!cTPP*WmlED(AvpFv2K
zT#I;p#SuVbLUmCAmB)-)`JM*I_F}czvj>0=A<!B`g2b at Bkz+~JNbgTQ9>R{4(Y`&S
z4dBv>4#n6*Vnd}Cjt}6)@TlHZpLehSQe05)e0SuANJ>dr0MZ{;<a87I3DTwm2>~Km
z;1 at z-;cq4DA6Ok^bSLHgYvE$E=UQ?zxHbLG_VXijh$h?LP6}d<p{ZRYj;yHbak at Q@
z{HCHMq^;O~PHtkqW8Rz3zY}j}H_t!+vE=M|%N~`t7}Ui0_yy*#QoM^)lO4~V3v56@
zs4&hhF0$B}#9FcLPLam)RY>wRfLP at 0fXG7hw`Rf7N;Lx%hxU0I&w$>ES5sfXyB34o
z_+>C@>haxXmk-zNJCNynf0a#nCv;m3{weT_!IhAcfy`o6Aa!79uj5!t9V<HEI6=Vv
zwFDUNMU24 at +vZWUxJ9d?Q~*VT1#H4}1;70q71UJFWkfI7lk(wGgH_zkb)8^oAFC=c
z|J5=y1W+|2J{l0)1FCm5<DCiU^m?FMLq!;pz;pE%OeL2BxMs3RXKb}2(58QOO)A0D
z-1{3(>_cNc57KUOjal#czc-y8;&Yv|CU~xOe8?fsbqV_=T3@%8?cIX!e9c)C>Gy^u
zc;Qg6^2M(db)N#wo~}0Vl0gUOQpsA4TU+MEl%*)=s$rXZ;}6(*xWFLqkbsA~Kw4HN
zOMdU*V(R77x%eaP?$Ij_m{nr4o>7LsviuUse~ot_XFZxOhymQ*-t-QJ<>R%`zIlAx
zzT~xdMld}&F3(U30G)>K7Fy<(PCqd&{rD`Y**n{brwzXn(A58<Ue3|P#2Bh)X!wqA
z9MeQOkc4|IA#AU6h+t^aNAtFDOSJqBV_bo{s`POgW;Zk|zVJ}iS9d+{Nl6#fF;yd}
z36bsA4xYFvwoGe68u#X|P*s`_oWCh^%ujdij(w9Te{;3~bL>04V18gW$@o(tsdS*q
zAMO9oL&LAao*~f7LO`=+dxb6lPcdWtm5Gt~tM;?>WAB*-PcluYc5C$o(`wmO878`+
zp?bCBS<pfk+`j5lg%I8CyyT{?Y&jAf0nT=4l$n&e6 at OI~V%S((>|f;nPX_4=gW*Wy
zYz3k$at!c-hm|Q1WzJ8yC+ZAYlEggifa<=eeokU<h1qxzs={r5-R0F2b%5>J at j~@@
zy`=1F!<l+fLR33<K?10GGskTbR{M|5If;i?)1Yk0XM&OhxdD}axJ5TNBTW>G5_`sz
z`&7aOX@*+I at yE{dJrny>jA6SKe(8nzs>h`;mVluvlIiewm44|`{ZO7wj7%zc3kP>v
z`_y~zOK|Yr7y9-)#EKlvJBr8mwYp_t3h!sJDMe2r&SoUEd7rpa2C|u8>ZLkvEo=<o
zxS6QnTeli-#>p1WC6va<$?{?vJ>Bm*54nXHZFca3?wa5=lC>QaOfCqSBjer{Rqfs{
zhbJBUDs!ym$}54piW+7*^8*3JM*LlI9P(x#x*ARC%_v9lpb7=4t8Xxzt(9)YBvD+^
z#m^l?@mvjVscQt_NWXGJl at I#!O8mZ5Xp*?Yrb|*VSRT54K%B|tDDWJ7ql}WUYWDKX
zp4I{$V#&JGdyFxhUW4yZ40>V*);CdDVD?%p4`%0*U{9FbdD at q*M at n+q`s}>dC#)O~
z&3e<ZG5o}S^N#buoqFP%FBN!G?@)d*G|HTnc)m)DrhCr?a}0dGNy6Xm7)r$E*m_y1
zk=g&{O2w>WH;(Sm-bB0jK at Flaqpv(dfp*irsd}%`E$>rRGE9YN##RMmme08)KXhNk
zE@@PU_S+)D+&gK;0f>U^J|DtXKU2gV%tLS(Kf320SnU-n7$RLTode-va}4G=4beOx
z$Q_l%%{mc;i;XiK$!sKAKoCa*GOrUkdOeW^L$AGGWi`sfkmrPE7R+|%Bpn{-mf(XW
zGs4TChr2w73ns}o(WJIg9Fz|<oi$2e_98tLk|afIg(&SCviy=qLN!-A!ODxYz4VGn
zVX++C_ZpQ-a_7dk(ndM$3o$;Zfg<HxhX;A**nuP07hr`|R(khDZ4<7s_)zu6+09FA
z#&U^x?MZG1D&J$4eWLG)nxqNL>DZ%cZDZf3I-jZhF>-<3N#dvDjT{UX{)48^=D}nN
z)@`uaap_vd>c|zgpS3}Q-%z%1D6^Nnkx-yAX{-mO{qvrvLP>A%Y}~<VWyE at -DAg3?
z=fPvp{lagv!fPg`eO2}@t7Hcu8vGqY;d|d9S_Brk^V at 1RN(Zw`_QXg)HNvS`w2Rn(
z`hh|AzG2b;{{?+R|MRJFLHN>R63mdvuZj83V_`HITg${>4}U+9G2GXj2W~SbH@^!y
zZW4yR5;~nuoyJtbyeO4XbwX)pM=GZ$yleJhHsPMbX#(gy0+tR(Lh+_^=b^2t{x*>u
z#w+YQC_(`fAf^_h9PK2~@K+M*4 at J@>Gp?xU%+pOc7ds4k@~{ScXvd}Rr<PV>4OAY%
z3GldiG9#(FgQ<T at X{1p1rr3%UG&Id-QedqN4of;PhL2%rt+E{9m1~ZKX+`E_J?-R~
zi~k;R9Sz~Ac0})-&4(kUE1QB-LRE{^Zm}gP(EK)W+;oPp!rS2rk?BFg?YP@>L+vPq
z$437_|HEZ2%df}(I)=?tCj at ahLh*|BCAW%|k2JU9c+iG}r7Y=N6CSswRj-dj)<{NB
z;gGrfNz}%@%&GFLkDTi7GO8VcwoMLg8=Va<No5jjIh=wBJ^Ke3n$wXb-OJGD&xU?<
zH9gUUcnvV*v}*ZaEe)>h)i`GaGa66!#0-g?KLo$vXT#n;p?y%V(%U3+gk~hy*jF5%
z`0eoLW7m02h|LvTC$Gj`a~{ROGNd<kk9rtQ at KW0Q$*-c%{%SQB`mKC)?NTU%;o&#x
zc-@$=5~^LlwJcCh6_xI2G(Bx(gsIGU4afPv;kaWg*nh_yAOj(~`Y`{u!*g;6*XVoj
znleah?y`F)p<LVzsvGMWDw#Dy3$1<~TNyKkCfb?m!A*EH-b@)_gI+U>+xWL80r(Yp
z)j=ocL*K*D*b25}|LP~Xzp~G<XE at -s*ie;?VsEch519E1pGHvR8KK{RPBeF;U%DAA
z1Kna$W(3O;g*u|~`SH3jIs{$*s>~M_h%%0xsFp4(bG4P~-{|L|Ot2^m=Gr=s>@bFa
zSK|H+sK$XZmw&40QG#)aoPgcDwU1+;N`XWir+u{_DpO7(jj<mPz$kbmSmC!Dh?3U5
zkbf4y>uFB`{-^t9DwW&)RHfh7%-_{s+C_~A|3vTTVpo-!n+j at A+A1BM?1v}DneU&0
zlr}>Jh#Bz^w~Hy<I_A7RlJc_T-TpG;CnP2cp=p}P&@&s6 at 7)r1lttwWTXW|UP$ZPo
zwW4*b(~VS?NTljFi>cOn at l;xo4lFww=lDx6oox4P9}f)f`K-?gb)4){PucLZ={Y%U
zrQ1#+6G%$eu;BD8*tg^5sa2^tXd^~qOD&CoMNCa^o4A^^TBE~?N~a#j2Yt`Dp^2`$
z;yorgI1~gyj)&x(OPK|1AtpU&L#A=iHW_aFwnXI|nM`J(9rL6liIDfv{>9jP;9RS5
zi%t8T*g)6ilNEHV`eim~&cve_AsqB{KBZ)%cslZh<o~n)jOo|?DnVJ7$Y^1k61Rgm
z7Wk_xqC1Y%S*c&L?Zv;2CCCOP&ui|HZCQX8Lo@{XiwI>B|Ezcl?qO?P2#TU@`=)H`
z2Uk;8ch9Q)qXx(PA1&vptw#SMbtZUwPkBHxw at vBif$KV{*xw!%y*G+wBz_Kx5TK?}
z4cm!I-~X`XRj3@(o*{Fr6coK0!%?zwHi_fjxJS at 5ADC&a5|n}MD-OBopIETvn#7N_
zyXVX=Eaco!2SH#TmoaLropC4GzZg^EXg{UKFWqI6T5*%AoF}dL>@1Fh3?AuK&HzVE
zBOSuBGeM!2rKhg+V^~e(uwZ-)XpOa at W|O-wtn%i`R?AjMSlDkZB|G%qq`Ad}3+Lvo
z?8`x90#QOrCPhpHW||<@YLKBFc}UUR8RX;f9wk#C?wUtWRLSDbIkx!nW};9?3B|m^
ztK!Q+{T$U^eC=7^=ASMJtFp~>)QXjoa%&9AEFzdU9ZLK;4j`dvFJvTB7Gzpw4)kQm
zIvTvd7LOa7WrU%?>2eoazpt>3F$kE!Xp3SUXkyF8{?JLr)kNWGgP3!jbB<k)!%`Ie
zJ>A~KLzy(K5?sSJmYB_!u76{kr)2K;hRoIe6pnIR(B1<wE{Omq8h4c;DisBk%qRu@
zM!(qy#ykb*p#?cr;)P<`z>$m8e@)8{;MpUawq-`x%a7Gy*2nMHs99igOj?+q(pcae
z*Wab%pYegbQ<UCfqf=mYLjwXvyRWm=$w5fhcDr~aw^Uc*Z at kpwu({~n4 at MTa{R0t<
za<1*K%cgp2yC1 at 9Bxk#Z@^U!DT6rsjJ*uKZl_L`u(t;W~Mq_GHJb1)N*n^dDsq_?R
zmhR6Rv$oWdRiGM(F&s-P?MXEp at Kz-Jc{4PICA_WEsN~R at 1NKd}V93zenNvqxK8271
zNx7t}R5 at D{O?=J5tZY6YUS&rmYqllni+5vf&Az}{@oG at C8xqg(*Sz7axS=xogo#1b
z2{-{WBEOQ(XrXIWgK3Mt=^k7A*o@(ub7&879Nt5gLt!gr{rbZGiFiHISEpx3iDtUh
z_PfBp27S<baG!U#o1n>i>onPh7VT9a&gLr<XFVr>bPBe-75#BrbBJcTvV(sQW>}4X
z5B1*?j(zx;&b at cxar{+4bi6WCKqA-LF{5QbB9*pf(j>LG%+1}biI>#QDXT?Pf6rSp
zvPu;sm}7C{kfT0#Oj4sfl*~vW{`)yu@%(5{>N$7oB|Kl&;%sP#D9!&gi<+NOOgcm4
z?W7$)W=FY7>pI(q!rl91h8vmSiG!HU#dSQUK;q)t at g4R>w9UCuuTP2wETgvgYXW8o
zTUT_qa39_oZ3UxwiFRtdMG4l;k%h<2{ROa}yE%ZhR^xrv$=8T<!uo8VYK0c$?`d*#
zd2+`ySCnG$sx|Ae=1d^ZA$l<DK1!t^t{j{bIQ33b-d3pw9)OvDRsL=5)FJDi)bE3n
z52#l1v~DpZF+`Zb7Jg63Q{#8yBY8y2FkDD6U%2LAnb8vcJI8K8qP;&yg)y2Tyv8s?
zo(ZhUU%8W{ZiUZ5Y9wISKFC#kIe8&H6W6^$+vs<~S^e`o)kT=&`|+dwanB%QNB!AG
zo3&BReles)%&E%!P_4^^5LXs8g7GP$%@a9PjAc>+7k*N*WO&@iCzIi-u_bu;pApE&
zIAv_IbY{BL9K5kx-bffdJiHaFS`d;H_$4XXLU42kIdge?RBzgLBze`%^1CxO*v*E9
zVvhAWr)jJLJ>Hlxx&X!)rhO7*H-(1XjMgicsLlWE`c>%5xkv`vc=u=42j`O1n+oGE
zRys{NiIHTXmh{FZ*OE7~V>rZ(tn;6&KfW;LXKKqjF(W?Gf?2&1<T<DB&>M#dP$td1
zqU0D}_WnNe-oMpR71bcoXxH<z&ovxE8|txezYsC~YU(By6@!l&XEK2s2M?Wt5Arop
z?#h2afXl6zU}*57-J?`Kr%5|>9ey#^!vJZ`#PH^h9$}!j@)}+v(=Oc|cuOO0rOw1Q
zl8sIfO(c72ePUyw^&p0ZnybZffS$$zBMx at EfmP;lG~7$VeFr3s6lQKLU?^xt_1E1V
z7$SJgp&lo^Y=O#*=l-JD;}j+gkkw)i=asIhabmx?xWVTEa^lkGq8nxQu<hb^;pg(u
z at hir(9_Fej(}I9 at Y8n!p(VYpwX$i7I{~0Qt`2l(KYw at iT7Gzqp>u8wMEY8lHhhn7Z
z=fRr<#?kBE_3a`k6O?4rip7j>!#OdC{@QrNmJ3I6>$!BJ!-?|=JZ|f<V}2${BmJ8o
zWoN&9jDIg9Te{8oZjAQWtXxn6hfpEmnIGW{&E|8TO!-PoZ{%px=|M63^O^RKDaVGz
z>Ix+_d~j=0vl;kVHtfn%Y-AB1$A0H7_kapwRj?a3U^VDH(=)lXPX$r%g!DuaeCEBW
zp=oaPHrArPOgP65?Tt<;Siu;AcAVS{avcXZom~vrO0y6!Lj762eo)LXhz`IA`bgfJ
z&r4hvg97xV71g4Y{awL)7Yn`|bZF3O92GxR5dDD4Y7i?er?%41BSiQQ6`A(&dfD51
z&Yjc3;x|E;4vnlNaTI+1FW9voYJ_B<<5;H<D9fJ=0ZfJ$4G<sUcYYp7O#4(Dkk9aQ
zY(-r}ek26=3(V<hN1#pR{C%Xv{>`9TI+ae~{!6?9eMCVj_H#80Opc1eqSyv<58GU`
zkl at IG6$ut~h!2OEYa|EtISU)|O5}hDl{R6er`PLg5j2#vGe#>dH32+cH?$oKYzxOo
z8eT at 3cH49oH2nc1(SXE0h#S{>WD-XdgfrF%pI(IBPb^mbcLq}d2A9^Y1Bl5E9_r7g
z#dwJOvstK(G`6aQWKiU*D49EP*2XrR;rHAoB|u^DBfT;!9iK3 at 1BOCICE7iYV%#SB
z6N_bVPSU at e-mlC10LOANSkrr_fDnvd*<3~Gt?u}MNs_&eA_zsIjmdeVcJ!^(cakd@
zVo`$aPX8KG6W`S{cm?A->wbwC*6V?XU;$4U-8n;dw2DGVD`3H3J`7ue`IOGR2>6uG
z`*DX3p|TPll|UG<l)Fv0%^&fGp8EU1qR)@6sT4Uv_bG3k0mE|9h;1UK0DrEwp^O+Y
zvw);aES4i59`vAXF<djNtum^WSN&L6_p`94DICsbc4r=z#clEyo)0skAFI4s&BCL;
z3qlFD6PZ#n<mftv^Nm6`Z-^oNLK>)pR`S7XvrCL(Uv}88q`a7tg0wgSe(VJbx?2qw
z7}0O?vr?kV--#5~44_fwN_M}+u!LISpy3(JOYHrMzQA_VS?AB{TN^*eZglYui6~hx
z%dM;Qn>E1(o3O+Pmfpt2lq7%fuZ2!Zu(ZZ+1aZJpTq*jnDl3jwbhomuRy?CNY&}pc
zcm!V$L`g}yL}uwz*zH*Dhs7O at CLAdQqR<dXpS9bEqki`X5dnV_BpDyub>AKhX20&e
z6fN7ez*eg(y%Nt@#cLcGlMn3JNO@!a(B1u#q|c3sfmvk4aK6eBE5qzPC<BU*KCJfJ
zGQLOQZ_WsnKVU0?qB!TRstP(K&n<}MWw`a;*gc+3^6<21oZ{EsuMHLYdolCu8`W{r
z at l=f?(>y|Y%z8fz8Zus&4ZWvd*&LD=atPi)L^N}V<`UaDL0FP8Q-M1<1?ze at 5lE8`
ze$yFn$sg#eU3%Jd`h|dPzok;t!^pO(IcXzNtQ$hZf(?<)I+`YUh^O4~>Sz{Kc8l2h
z{_Mf!d}`%ZQH}d59qyq3?nz`cA#XFKmpbjQxOZk7YDO!E<L?cuo<QGYuDnq=n?@5g
z`ms;GVy%8QEj_uY*pA7B<A-T_Fj$O;k8fkRIbr)lZsNVS!qh;F<iJ5LHitN*9dYP=
zWVbkxw4ncurCUJRr=e`|V!?^`la(Lfn^@gXMM*ld>=ko_>ECB{5lI#LD-xSLwyq97
z*Xey6D0A5mwFDPMEun|W$}Lg&iZDfKvYQ!V78%cpbGB2ay76~98^4j)8_LIGaxXd8
zwW+4x4&mha-G3IuZhYEdpH33CzPMGE!N at USt2J14I>@BEUy2!26;R7`WdrA>D|VTZ
zx9*UW^U5%ar2k3kRzLQ>XXC_~8i(3q!Qis^yS`Kj&)L8!yRQ`kDVgaQ#)x`~w>$ZJ
z(<8p!43v$QloGzm^jXqDriu=h%w%L>C!+DO%y0M#d6BH$Go^_su at 5ILqbcU(M?fP1
z55z$A7&T7TOKw7P?EW4VY=rbvS0O*Vr^m5bLb~5czSooz4h at aQ%7^GhrsXP6pQvDf
z3_&vO&C7=X`s{4AhktoY at hAuH{QaDmRPn0pDGTVaiy884a;=&u%sx-`Ku28E_Gb$S
z4UMgEACnolf*hvl)d|*tLXx2V`{<z2AT>EP_h^rxk7Q#7_+<k`ZXHq+S9n+J(^;#!
zY?_e=*+91pdOK~!;r?L%-23xq$hGa)v+S;%_J$&1gbajHPu#RoT~@-`wKW<>Dy{FX
zc^JJwbkq^6B&<Y!Y!Vd}C9wL^g+1k~(~TPg#g688h)!l at X^YGI>F(coNeLqwa`}rL
zmV31Z#2syIB%qH8%ke9dDn5UnhUOYW-q$@Lb9MRVva&KbN9!0rz$L>C*bNQs at 9KmT
z3g1)Bu#i)*@ql~GX?$)od1rDwX-h#fs&G&-?>i7wstYyP$1F*REnHx#aPD}{u$?t4
zvD>)HH)n76W|fab#)c<Pqr9g_l2ri at TcU}`NwiFQ1tEU)BCk53xR at Hi@?eIm=u2Zn
zM8q9ZQqu6_I|o-+qBnd`fD6w*10_B at f>Hx^D=?(f7vm-dc;R at Q@9BQbd0LGOtZA%W
z(NF~uwx`8CH=n9i;pcD~<10|<sL4p$7fra!c;*q#$WIsV)c~6oxIZPZE+8t9L_<ZT
z{XqiRR(#3X{ssR`5Kaj<LyGvguIM~uf{*K^CiC)j<f)`lqgleQF24$Jvw-OV!o+}#
zb1(Pbn9WV}7&&8W%CxSj9k0EkBVq~@ng4&3+FkdiWpfx=dw6_!XF_=_ppP-(WjB!E
z-o0&aX-PxOV?l{27Y#v0O~&~s%}ioromyYQU?r39Upz#KHYF at 3v~a-pN4DN}g at r>~
zL*~zWpePHLN>iZM{f^Md%`b0ARSxD7k7O;L*KmJ=`***qPYVzK@<)Pk2$CRXGUm;=
ztGaG;Bx`XLR89EWqAuH~(_|!&e>|C12!q04?!8{iZvHstH)zd#S}R^{GJQ7I_Kq_0
z)Bhc~xTLGOub3N3;12mtsE9m4Qg13_-;k~<n7y=;(<KCLh`<l5xi```gA75og{r=0
znncu{o0;~1hmMwwe}82jb`_S$V{z?E)E!nGid2t^sXS7SrczU`Cj at Ux*0D4>gg!JS
zOr2n<Vx$mD9H(=rq=bLjj?Bl#e5gSHTMIICF%6%xcMz8$`rnPm;<V%3tC96)&&G?1
zw;GQdSao$z4%XLcQ)#3vzK;iYLMaUm=a!ZdcP4Xlh2Bu6`TzV(B}gjewT%kgd0P8O
zdY=LDa1NJgY)%d_-bG9Jj?jB$Cu9L8{y~XIeH0z*KNtK=Pa<L(HPDa^WM1xKp|;>b
z?pY}l1ucoh8rx5CYj21x6pFFy9|E_>@F*o-V}dSNIS6$L->W##de`O011P&#VDa?y
z3{rdwL^MELP#myJ_Rh2o8z}1wGW_IT{WF4kl_nXhSs+~2(4dZ+kBn((SmtQ*E90eY
zh~3yPl;rk at S~lhmjsJZNPDX;`Ix4QXDtU$b_lbGT{FU0XY4!Dh>r5<vx^2h(hWz0H
zfNRWe`aw6Y=YCc0%pNHOD$j`DKaxW65zL3Cg!tovF~IeESd}!(pFg^<Nfm}Y+&DNn
z<<H%CnUkpJax1E<WBj{t1NImdM*62Ch%vUt5q{Oh#ZI=|Bp|KxV at ET&?Q at F8;@LOb
z_hbA at o|15+PGMheUpl>t8eww$sh-T9p%?l-9OCHFe6tgm84lK<i$1IUL3{kriyY)p
zPeifz2jYO2tFQOAC at b0fL(2oYWo;E>=`&CTH8~iBys4TwU;UG{9e1DE`Gnl|;*5F%
z2O!SLfpW#9lRqs`YcM8wOW6G~ga+78froG0#!Kl6Kc+ofjS2L)R97<t=aH9SuG at e|
zFM_N^UfozfKNOQM2%OoAVbW_h%8vdZgHd(Nra6A(Rs23X<#Eg-Q0;b at QFmI=;(gob
zlp_CVR#)lMtD_)Dtf-;CalO;$M~QMHhc<45*~ysux43w@)kOh|s+n=HVBpI?=20SE
zks&=izY%o7u$pk2%=4*8t>1n^YX-{7N#v#ctrN4p%^s>z*)pBztw5dZj6p%W<QH-y
z6b-Nda2XyUv_;9X`mO7~(3AVXT&;4Ztho*$Y3o$xRqqxyWzEb=er?cG0K5)>Pyjz6
ziwqkkFosldAPydPncu+Y5wKH&no(Ay5p8zD1o`8av}AvQN!dTEkRwxi;C&4wgoD6m
z?Ci$VmNRA2vrs0Xu<oz?)3s*c$%9Oor1;}A)n3si<b}TnB}@7fLZ;^}bP*47h&h?x
z;!$Vm8<fT{OMXOwc`YFKI)3Q at M@-Egbnp8swsQN$qCK6wGa)YRaLDiB2BZCWo%fnI
zN_4)s=A<g at +6W@%!T?dsaeZ|%D{y`2PW`2nL)*~?{QPq5&Gok?8o3c8r_P+i08#i@
z+R2>uN;pF%deun8kK(inzfdfi$2e2o(%M%?hn?K9adCWK{ZMfpH<j+s?4?q)&8~2+
z=dZ$&Ud6zhOxg3sc2G{fXqF73JUno;-`%{c71yh><|fpUwRuXsYqE*<9q0=(8R?3&
zP<mE~mpWk?NEs?mH8nNC%8zu+XNYZ|!+p~s%Cbe|i&}!TqAo%uox1f at fe)}iiUt}6
z{^j#Q`9~i!YZ?vM=}Mp#2JC1XpTcEVO){Tk1wF?w2<58}l?~IoeqP1c?8zwlE>q09
z<0^zuz3NL##Q}MKSMC>ea^7kDU}zLX?X8V5_L1YVuo*O}v2ON4rBpPi7$wQ<E2*dY
z{;k6&?6oM{Y#mm at jLAA%?qJo-Qsp;$7M-M?zF$uV^G))qV^%&=U4J`7`LMUrk{-{I
zZb;O4(BJIR-iV~At8{x<%g!slLC7z220X<yCgm<q7TW*924CD{a)}P7(>1VvsYNzs
zgh1mMH)0SmdQsL|blHtrx7Ei2nZ_o at 1SXpCyI<1hW-SaQ30$WpSSO4*oV+~=3A1tI
zm-OF+iEOM+d6}KExXU-_4b9PE<On<<a^x#+``u&vQKr+eF^Lwp(sCw(IE{G0-d1Ur
zqs9b!$p9iO=R;;=tRzStb9 at J^fiMZ(%@^%^;;Jpm1&ZvMS!flUuKzkowm9FoNDhl!
z`wv>=1&(m=wp{_pUlu&xsG5>@mODvtsK~<?|Bt4#4#)d_-?$pn-8tReIo-`P)7>^q
zcXxM9H=CMn(+m^SIm4ry-~IU>$IpKp4xZ=z+<9H+`8t0#8GhHX+NGpY_;w&Ty6;B6
z3-4;N<UU%aGSG4QRzE#2+C~xQ-VjeV-<x3h5Nj~k_ at 5YWtk*GC?w1w8!)3qUFaO9=
zzw$5Ux8ojXv<zGt?q0k}b at SuzwB|#*MuE)^s?#ptx%&PG0)5vFC*+B;dKv&X!pXV<
z{_tf>F3i}a8U!V`=>_MT4OZt2^~yc;zdt^2yHf|KdLD6ah+S*e+uk_J<KE1?`?uDP
z4l6+1xH!abeypdPtCcjluRcmPv at UikG3|obL?->X&7-?mX?hz(Hkuq2;eV<4Z!U%Z
zdCk4CNkm=7iZkmSiPt{jU8U3AGFk4ZppAhKYqqSs>i!_>zvUN_ru?A2<LQ3A<BrYW
zXq?N!H4~Ws)*JEZIB5uuoE+9VaGA2Hpo9AOy(MYJWj-IAxo&Ks8D4Jn^bYfSUu~*w
z`LM33<!1edNKkZnC>UWo`!}@6XBg?%`Ul~iv08H?J_d%aZUk3Y`h7PzU%ZQ);Ex;u
zATRR&XlBwd``B6UO8uIwFS3#rT29^rnY`m%K8LBQ0!zB%sW=f^k5%WHUR_8~pSV|k
z41f|4RPi3&9+GXHM_;;a1*2SjTQAp|R7(CDNO+EX)M0Esgi8*LBlp2!BDZVNCja7g
zF8K1^Oi!6Uo;imE_!F}l77Qni_{W)$It_Kil^3$uZ7rKTqkldX#q~$DIdPCaoiT4a
zJ1_Bim0gcVo0K-aqbGYkQFT3VBDZ!DL1nPUNDzTAr`P?3_kEw%>~(izQe-~KVAJGt
zeoX!+LGmKve35JQBRW~{v~w4N^KTd07CXVtS?fegLQJY?U2d2=PW_IKS!M<o2ZWnV
za at W;>SFEnePrtuaA^MPaqN0m@!U(v at aF$pj>TOx|5A=x;a=qEtR-1VD&)1h&qdtHJ
zD;&O8TG5kFzfhd~Iv1k<7;kR2A=$dK9^}+{SbAXQD2r7^-4}r}BoZz3a=T<>&_Obl
zB<p$$t4eVhq`H~=?T!7R_u9*Ifmu&Cl7WijKoOmP)FatyT+dyv&`gxNsuD%!&#;mm
zi^hY-yvWb_36h?E_&qE02rOMB^}dt#4WAqzGjHv(X`}C<h5cTiAuWcn_-sGTGWah1
z{URZi`pnv9bwu`vhLM+)5_kv0`jqG$mU<1$$di+k;@EaUKO=|Cz<0|Iyrc7_717Ib
zN_Ix>3;D2YIMM8`+k=QWNYVr{a4{V}FcauDl?ov`*fJkZ_^bYi)t&A9b|xF#?0Lp;
z8VkOp!#A6as0(Hs(>|L$zfyR2hKCnvomi9W#=~`*=W2vMWX92utJR7qQ;W37e)IIe
zyVg-n8gQNDxs{rlfIZ at th>JT{u^_E&A*GWW&a`p!fjW;l{|wIQ>BY(Lehhu5bX at aL
zs12!g?G9G>3wKNme)ZwTEjO9h&;C`hXATEPuFd%Pp(bXM4C-D+iu35!O_6%T5Qj4I
zKQ95>Bc4x~0ZsRoiC;0d4ux0&HK9fwk045_P$s9r!<J8LXqb at ApW%Z%?Ux9ZkB^gL
zBdkZvzW=&(3dcA(zImhiU)ScioSCx??GeK_oZS1 at ++X(eSst4Q7E7pWr7|PW(vT*S
zO at 17|XY13LmY5~MoV)6;&<~+iv{}9~Gdy3>c~|5$ijTza3k9haPB%G!-Kx at NRJqDS
z+)*^?|KoWww9nUKdO+GU*wQcP`>#Z&WRfFkxdW}|b)WCNTF4~ap6xFh at E!gb-D`$C
zCAkReslW4nb7du*J1QD&G+EzUZSqL@?_od{@+Swru;)yKzw0tAIg;uPvD+x=M$kw?
zDWpTE0G{D867us`krHAMb7X99zn-G-#0YzAM{O+fN#4-TIfbW$_5y{lUtPUGU8?Gp
zz-mj<m<43*Qpn|YKy|zK96FU5p^DPn)rZU2|Ax@(eAyZp5K;+c25z$=Nq$KzR^9tn
zYDt{pqf at jviY0f$+|!{;bUa|)<xOh;iFkcmKhYn4+!0ihYUyp4PpGd2wrt?8Vn<0;
zD5WSb=@_CFPgfRxZYFkVXoDwzDo6ilo`OEloUm~PE!Pw+eKJ0amtkr}Ewxi?W31Kx
zGyT`wWsYsRVaqEk7P-XP4Ih;K=w=uFW at z-cj!@)vYvIjHEeTJGi?jLhk}LBGFuSv(
zOo(;I9~-R2Zb*oNtE%Ow1sl93vE)+cw-dCWFBRz^zo4<BQ2!9DU6aHcuo_NF`jkgY
zj-W~SEW<k(uf_`b`@(kj+<N4;*b#nUHVLwjV50h5cU+Wt)K~W>!t^oFl)BODx+-Zy
z5&pyHPw%SaAt8UASPdO{j5`+t?e!oF-03Z&USHbC<EwWP5H96vbc5GU4`!U(U7$Uf
zqqcj4jOag($>pO!{mATFC!Kz$>4q_j`i(_DsDf59DR4Jg^E}<N6H^fvVf at G3sQ+H|
z at 9s;eMbA8><y#rV;yANz^3~IB<l3A%i5RDM=F5<+zD5?WI^_3n$)Ta4gCK+oeii^?
zBvq!MHq;F8vRc2hj}@Fs|C*+Wme3<bmtr}!?eRXH_Bld~XXK#d`;+pag)b(^9NG at v
zJuT-LN5mbg=A}|7E$P0KhtRwytX-sAWnIA(H`LgCq}rV~XQ6yTA{$dM$9<F<RatE@
zC6Lj6mxY~7_;*SXpAt(lmO(ccn^{mE21hSE$xgQadd3IBo_lQsk-R6sl5sPnmM2r+
z_9MrF(o2VmVsQwN641eY(|snP;pdf)?Ce2enIrxoaC76z51p+I+qdEi+{)%V;VwUN
zYGs%PxO$^jP6{C^YQ<n$STbteuIa7wkvNJ1DZAxhuB8^qBn_|YA7X*h2_jK>kLX*c
z1%DzO%vkE4=36Nzjf0DA<m?Fl`Q8v(7@^l;54AhSH0UDu%7+UJ?sKM>+a>xE-5mP)
zy-$Ne=UjUs^?Ev&q%yzolRKZ}w;nR1e?jgtH_MK*zJ11gd{BV+;WAAteLNoK{YDp<
zxfrVj$9_r6Y#?sX8b5GPX*do0l;p`)EqL{Br|tL%C7n=p^QI)BpBEwN_QGpBzTkbl
zNt8~l6IqHi6{O!73+&Kdg}w-6dlYJU6R}d1Kw!||C}i_nWW&wc>uuA4H-NhK7g3Eg
ze!f=l`1}nv8D_O<W-(cYG3$M!mW1jCg at s=Kyife5`>QM0%l6Nu&261rlMkEaSnn!7
zz0e_-a5*B6ocW_nol at EOPsU)H%pppr7rhTge+`q6?vBWJoF16Ym}&epkSUXi9oCD;
zy!K2UGX#8P<Hdb{DY at cz{=2E{0Vqx-ul4Y)FuyU50qYMu{F6sQr>8~F&F2M^&7o=;
ze?hAM*8=EEAZOrw!sC;F-FdXUCxa?Hf?pBBlk9k9_;)CPU(Q|W;)^&Y<-r^T4KVWr
z<V5#fViM_si$<}Yb#BnMp-S!fG3HG$W6f&J`&%*=1eMad^Z#}-U6ELO{tl at rA=jM^
zuop+#a5fDP(ktNDPx*4B*S5N>LoVC)K(1tjXE${HEKYB;8a>`tg=p$8Td(o&$H9;H
zP!C^_O9pB&`2PAp0|z%gk&8^WU}J}NAGsnEWTl!l)Je}pm^>*m$V+SFV+)3GGs#JB
z^*V&N?Zw7iNiXQ6L-*4@*3*6;)$afcf<JE1-5DdBt_UXv*z~x_4a)enM+B5r!B at pB
zUh at k^E|!QbClvF}<_Y!1m5!JzSmBYjwOdd^%OCodRlfaK#If5Y$*b|+-piB^!scxH
za at axU)lzXb=#bqrmil~tA<F125)E=O?w(lJ{BJ|NzAU}-J at 2^Pa&&IP$tsRZQ~cpN
zTxk!|^hidAwsyMi)>Zw(4nCjA(wg+gz1|XkYyG}i6L%~do0!SpT9=Ifb!Db)b0s;{
zNbH5QQ+53<i-E)`9eVHMn029=w4R)cA9{A3*{$kX;N|Qq90|fca6Ir7_^|md5ql~v
zOyu-FEv7`;S5)a6%r+`mgnO=ky|B6Rta9Q#hlirXBt`P2Pok~qIW%fpd<<wi`XMIu
z_j$?8TPmUos*d`dnN%SI72;WMWQ+jTYzR98xCz-aYDtGP$b)ph>S=!B9P&TmXTCc=
zUVCqHW-Bcl9|NOxx{o9XFuRzKl+?AQxCybS>7!#K>%`M#3sf}<D;$cc->?|v$r0Rc
z-Sz~)y{zzhFzZDjZ at dT!pAWqbEIAzx+?TTjn_14f at 3LzUzreBSwP0_&Oi>-Ke<M>g
zD5gIRfI>*csncBwy7A>R`-^?|d`1 at 3)qxw6&L%7PAwQwmmWbPOPzX0xPaR`c3+{T6
z8Zjvn&4}#&M;Z5)rL#W^+4B?ndFd-b|C^i)anH*`u_lD|IlgTkHd{%l6u=Q~Do*t&
zwIEcS`hjFE>>}d-6hgj3W9?Dm{7CwnOb9oi*_4O6C$a=R0QR-53!D7 at SZri&|C86f
zbh&skb!K`<5EX~;<qSveLosqgyAaxv>kw<MbbsJ$SGGphlRNTI${_k>)PAG^!~Gg_
zsCN}_pTL at hb5U*S`F^CEm04q^+(SJk4wLGGOjlHIv*mPXn)~0?*4JL>r~Q0{^9Z`n
z6ei3-mh7<6h;aOYWyGZCIT{m|<%g4w4>E7PNyu@}rC8hTtRun1?s<vHIv8#EB at 9^=
za#nw7U~qfb<bPlP=Dj2T0j*4faH4=SMfD>n7}bP`0g>B|B^+E#Yi}t86J?vRf-d$<
zK2HCY)_tC0+SI!tXrhjcfnra7%pbET1ck97F&KIAXN6JZ9e$Oph_YzMKo57O4>fvW
z9$F!FNBo!DVgm);%wa+SuQ-WzeRFBmvq>t23`tVA7d*Oi%Wz|tMYe+aD?b{(44FwS
zV20zVmNi)H*)cm29r2XVWbFLCeMVjX?8JoT;6rdL(v5F-YxWhD^eCOTMz<M@!F*8R
zqZG<FR{eO*51xH$T3-!>8thIKsI>_F>En#j0|zhM&*Pa)!baC4AkC|1z0C*+7zVBk
zqW1}BeT3)!!uOD8uYXz3kQKg<^OY=e-|7Ywc|G6#II|UYIeYfvZN&iyhVt_&>GvLc
zZ|=sKOwa-j{Mt^eJxxc>ef8Qc^wMX4rS@;*+RrRtA#lV;)|Gs>M_kNrf=g0QP!P_4
zKN9_2x4n&!GjOyxW2a-<AL_t!7xIhhb|>lNN0PICLap^@3OtUP4jbGL_5T1OM1C=Y
zhGM-FMkiob^7mYBU&}~- at B8C>uUC^-+{IR=NSTsD-A*L?3^oa^l%LFT(ai7utVAu?
z>rj$vZnfuQh&Ic47mEQEJD{CSIt_ at mI3g63oN1I)-QTGkwI34R3oCQWrr!1*RHiqT
zUiz^p^U5M?i>gU8V%q5oMN-U at Ol2Gtk*_vEN(x?J3LY*z&*#O2qa-Tfq}2=Uh{%?2
z{vkg)UESY%0<3^feK(1bV=Yvm_2-iTuypOvzVHQ4s0~iIh{kMNcSl%ENtKg`Q(IGg
znxsk8Pl24^$7UxVNVXV#Gj<czr^dCdh?Fg{dHz>>xcVKPfTlWanDHit-D1$Jv5-_r
z<XETUen01VoUKQ=f=uF+Ec&rD?rP0_dh2RlwLooDE*V8x6M8yqFE-T8HX9x>@R%Re
zU6RlGJ{yi^!@m)A at UhrTu6eJC>s1H4M7%83Q3l<Oym~H!--)8V^XJ5mKOUJpuq^&c
zu~Ak8zNtzwP4 at IyJh+SzVua9QVEcrHqa1?u3!8wjgqle$&5e?eQ#5oKnpY*&WZc~}
zLH&iMq640g%;7PtZX~%_T$8#j9=k08*9d(w1xcAyh<4;U*!r`B5WSelzP#*#071(^
zKOt#BP3)KH-_Isqtw`L;ga_Vm{SmsnIiQqlV{4nmJCx!%vDXFPpDrlM${<z4pcC&e
z`<jmkKpS)gzF44)T~)o~%o9yhkYR`R(hw0ejh?VoQ0e8bJm27cpu%j@?W at 0zY{Hec
zUp=Q^wHvneEN+v_m30ZMF=*tXv6kcMdECoV%A5!Y2(yce;Wpfip{8+XE*sr`ASP(c
z0;^Hi;lnQJQAhmAYODD`I4bUSL14{qs{Dxm=uY(k&&ROEsumlcNQJ+flau*w>#beS
z?9iuAd<@_&Pre%#^CuYdswu|z7?dOKL-)UMUxUmGsWal7uiLLjGO_x5H+U+Rg1!|B
z;HZK^n#;f69G!bC&J0|<GhSo#v#YDf^W2U8&kw!)eS3j5mA}0ojS^okHfEie<Zwtw
z>xJ+iZbjpv%R|=_{9*H2MPXpEo<1oSy_{_foHz|P20Zbm``>#u at DREf?uy>&e-(XH
zDYSUwZ3%p~0|Nu#%ry*Hro2vTk>D{*+V5od>RNDS6~=afupmcbU~r*NQ%LdW!-^_w
zZpLo?^Vz`L*2?X2&TRX8!F?I22|+u%a>gqH^StlYhLY*I61EB<zRSmsJ)@7xFMno_
z4Xi9nM^G3f>m2)89=o`b2*S+M60Ef(K6ci}@u5Mb)#G*)kbdEXf{-Fx9mY&$dN*;b
z*A7e at o=@TK3*2>^$3J#<pY?K+HeUYaFC_M^ZD=B-<@%N|#@>gk=#MIxdenf*baHi{
zr6xn{?Q#yA<73`W1}mQ&EKrQqutiB{s``e`hZ?_JsMAjHVInkVSNo!B#u`T&(Vu^-
z_Loh<zEEep6(`(@#Q|Q}ZN~eP!H#659F`qoHgCUT>L>i&reH2rgOJJNrT#|cr)~6v
z_i4Dl0n4s2^bZ1>`FQvz^HYwdbYJizE)}DYvJH{9BTbN}{17VBdtBhrE6B3D2#792
zye}e+><~3e3|yqGSTf>~&|t=ocZ^F{Nrv|P8kuOVcjz^p!|t(!Hdr9|mY(y<ryye2
zJ1FUsa69dT9m|BD>cJZ^YddMeEQT}%aoB30Me!9CTcI(o{BhF^S{1)~yI8go$sPi<
zwL=P`-b)1Ic&+O&`kpk5ShXZ~DnwJi7Hw#HnpREmFO!6cy!&e7stS*|@pr)0dPINw
z65Ci2r&U<J09~GO`gZ4R>y6?!;u<PJu`+X($(9hk+?2Q!<jYcFuIavUD=vQDD}LW;
zS$hK{{9JchfB%tZFRKybT<?_?4tEe2MCRl6U#P%}L5}Q&%{x>6oa#)Uxk#)@=qv`j
ztuuk>%=-7P&;ie!Z7~L0?W|hLvcA%M6wU}r2yQw=8iLS-SZkR<YkEwWt1aYBHSbyU
zAx8DZ;!d5ntPPMGKhXkNX1wZSqM&_A1d(UkY+BGja9r)5qo#04M*pmV(hj5Gla at W9
zyaz>b?30NCX((E*(sEHnYW+8N2gKn&Nn8_fbrx;ot(v!SZ*;@P@{8#$$1<*`uqXL?
z at So*(bq7b0C%zV$^Cqrx*0WRd*C9_|7BL{LyAGA!rNprH_Rg>yPFMf#bDS>Pxw|)N
zH66FDR^wK_gW7I9v~lhn#>|4;l7gs7hW7)9_jAdi_0^#LkzG at G8KN^Vj|IAkg`H<^
z{OY9LmIEnJ%>wYUX+^M!7FpWWxNo4~hX0Zap9d)96E>YDCrj<oFnG$m2OT_g at w&qK
zjj<mXEs=aM!cWl=ei*a1sg_-sOK%PC+hpITTS`$TaY8ST!lw8T--(our|>LzZ|{cr
zWH5T061ArvDj`m5QZ4m4X!Z|z3w+9A-`G!P`u9aj)?E`TnsR6K+!zOmhI^>QCR!HO
z4C}*{ib*Sc&)oo3+wrV*p)I2YRCXCf3ZaZ(TJS+pk!c0>F>qKfrUt^;QYSm`qxV?!
zFUfw{mG6MLcHTgd<8&Aav(~4I;}Jo(dSxeB3ahK2Vt_AVbi_`|tR&Ea+o!EK)a{B-
zX%gis)u?1XDo7=8QpZMCdS7 at 0TSHbF`Lok)kBcY{KKj7pOj>Y4u6MMCXi_UJ)=p4G
z=hAQ8HBb0MN1f!-bvV-jHYV}kk)g9?`hMPp?}Li)m!7r+GJ32FN;NcOUlvEbw?nTj
z0FzAe7S4|9Pcx6RSyOJ-`7qIxv?dNN6W;e7^wpQQ8`rK&0|`49I^8&nHqb#xo-#g)
zNVP{e7t;2>-oD$}qAM84_d_`UdD*ggUGMKb1gTZnsV*}?dzM0hUHmHzIrGJXSjtV4
z2D*PmcXK-$Juo6SZWMl9ayP<>;B+D1;7Fd?xqr_LvvDcoFLCd^<wx1cgY3NFE?`{0
zhN5I)aa8Jp5?xxr+->;&ec?F*EnCSyZ?gX>y))SpOa;?EsaRM^+}Fz7seA9SFYicM
zmGussTMdx7?j`O=`P@{X>??)%JeN^9+p!XJg#I%i$lLPU7}<|2FJeiPkkWA-pFSHt
z?Rp$pYW6LxrHLCNt!2XqpM^9j6@}Ue$N%Qmp5o#rJryW_uc7rG=IVtc-fydCGgV2h
zNlS0PcjV>l6>FC6Mp9GjE(|L*rWK}&^WdhbcOpnOTsdkY(d~WAXj9GRYgvgyRbb$I
zOB(vz`NCsClmY%qbL0#MQ9V<r+)+pagI+pjoD3aHAUn4E;Eum_NJgMe1Sg95Vl7Qk
z+uI2pJ>#R1OW_*B7MvUvJ$Q1ga5p{QlSi?k`DqdKW-SuLjefar6aO{H3;3Z2*c+_w
zDckZRl5I_aWueY{pxSjFUn~l2paKf%JT&I>Uf#_4mQ)W-TuB05#L*{x at fErc<JK-u
zXWelxA+o09fpm%x>fQ?xlxy^l(|pchH+!oyI8hRfB!wcV_f^Q7%TsNo=V2(izc<^{
zt_9VGcPHeMaY7vv!`yj)eZj}bJc}ULnLC=6qvou>F`<#*O6igc#K(GOa8S_J2J=u4
z+j{a~$HMEo0K@(;{Q!ILTKRHIy3Lwq78|BG`zt&7x@{?jpR(rp;!+pV^r=9s5^KUA
zg!pYmz8AKZ8j}znMIp>Mn^9aP;VyTvhi31mKR at dG1g!Jpe~|mZ<L3q7O^MlKuVibM
zJX=mA`KH1rhA2o;5yqK9kk6z}w~sMCeY(R$1^a(&KHY8MD{i^udK*k~Ro}WN&MB#?
z#Bw)zZG0%Le3-?4;q#@*fYAzCy;@E7U}SDq*!Phrclv0o+~ZFvgiTP`l9XnW2t}h=
zm>3mjA1iK}JB2}Qrdj3QVYf)rc}l4*lpCydJO>X?N|r3z3Rej-CCwkiH@|u at YX4IC
zT+?;PHGk)wYcIf+_V!EL2=4Q1 at ziI-*QncVqk;!Y;pqXjmPjG8_4prTNl*pd$1qK?
z2L7&m>-Xv7ko$yJToe(QjoV<_yl)31KXknQEeOl%(I}70%rh`;uHUsb)U}gkf2E*g
zI9!`g*y{46Ku1Rtwt-+?T5u~eZYLwrI7>Va@<28&+;s0HhSs&xPU&u@`&ZABsR85}
zoSiwO&8m3gU9Gg}aW?r?3b`S07UE`baAnS15x6sQ)NUFV<|^UE#^WUC?a9;(6r9aQ
zYSTDgu!{PMQWjQ^BvD*4A1O;ld_xW%ZRF|BO_l<%4xEh9jdY;p8XWM;90xudzW;y`
zC$se+Dr^#5R|V-zDNMK*{iWj&?mG~%`H2S><lwv!6h at 8lBUKbOzmk>x38N($@zClV
zeC4Ur=i$)U`i2&OK|$+E+%>a9gv(;fgM{wTNF5lZRH2}Q2>EN;FXR{6RIE;AS<Dao
zbjl2hwuW(~)vZL5wkmYqFEyu+Dys@`x{LeI>+4snzsh7#*6pvMO<!uA{u#BOl)V?t
zZw2sVf{ys(^=ICHqAobAFKxskey|Os2$)8ao(4=)YYliz86JI~4BK`_6BX9uE8{&U
zgs%PM>V*(4!uKGr2V|Qq5rHDIMLAP)&Lq<C9R?I8-`-rTvWEJ+*fuE8uBpQc)W$@0
za>5|vmufIXqUC5zfz-{Qm<Sw34I(ddo<;~99FfnAYXU3}TQ1XEPp<;jdkm*tdGNC3
z)%W6*%S)1VyjYGpM31|C(iZ2ukS+{q=&_&c=B)o7X>u=L-))R2;vC%8?!Ro=ha&3L
zqC#kiAAR49eNR*DXfSid7v6yNg~BR~#lvZ2{y{s(jmyaea5aA9{<EPyUr}Eo>H;s)
zkqgNP109yBcC>K|s|imp&{9!wS&><)J^a?8I<N at wI`;dak3_GmMc$4owZ-uBXzU=I
z|CfMhW%T|d7Vx2KSAWnhol&zPB*dgl8qLMtj^9b;k*&F&$^GZERaT at GXU{r`jmucr
zvs7%Tl~O-iy_saGIR8zcH9fLM<$L|q7`KX&jPCt`*9(3Ixz>4{&Pa9mVMM+3MtQSv
z4dlZE^B>P*pUZ~d3O;S=_HlfC+*2vaHdT{6h-WAIKh_c|iH=MDDl}~k_oZBCAtwAt
z|7+I0(+j)lQTp+7DWe}0y&!hok_*)a<hRt+L_hSIJz>ny$L#%Iqd;0AE?_0C4k+Vl
zdf at l~GSlLS`H)(eDcBLI<t11%s`a3=6-_m_4ocaJDs|sft2>Pza^fG1e)`k#R++_J
zYAG+~Yi7P>cZOrxEjI{|bKo^tyw*>q25s}3o14OeRWGSPY|43V4t92oE9`Bc>un^M
zJK~0dD?m=cxcCV!Y#xH7IOOlla6ia^m_|!I5K9o at xQbg3QklW;ZJ&D)_GQI#PkdT7
zIU-dqZT99l9&^p*m<+KeJyVKXxRi;;hq&lMi`zsx|6)Rh0Sr4dZe?UVLOp$|B)N~I
zm|;+Ga8*JSRZ%(z=?r$dLK$J00jDw_AlsMRI&SZWVaMiVBGg^%%gb!tlOgBUMTsHz
z3RZ?oLqL55 at LQ@{hSM2_Ziv8-1^IC<!6wJ?59pnqZ#PUnY(@L`07#d^?*?cnm!~_|
zHNV?GJ3onxmKr}De*khnf{wa`qdcj_fDu<0psrdAczxdKrULN;H_O)M%T1Qr<3sIA
zAN!|eC+(EyQRMbLYG^iYO;>q=7)GH~V at A%ascXQJhpr;sQaPti*1kuJu}F)tk9)F1
z at f>M_O)VkoOLbOSnpN2h=R7y;-eAj#fISBuM&=|Es^`J9CFMXt`RqEOsOm2f|GH^x
z9W-L)hfzvV^2Iri#O~z_hxnbs_IAQ>Q#ee_C+77=a|B+;6*#^0kf#R73Z0p$9$q}D
z5d4ViaN--~`I&`<FdzfcOE=Y94E+k|btEERaE?5_pd=NY3&n$MgGQg*Qx0zxQ_E#;
zWdOp|OFxbdD`47<*iY>=m7-Sy?{3(GoBY6HxTz*^Lg|-$-Z~RohxlL&cJUE4SD9 at w
zVAl**uCPl5-6JMbQ5Tf$X3cV=0)`sV3AN%WnbFd?p;$i`6@}WWI9JkzJQDr1PR=+?
z6b at b$hy-0z;#S>)&+0y#9wSMN8dYK$f}+(|Tw{`yvJ$PK0XHBXt#OjPf4Nz9H==s)
za<a2sfCiOA{$V76eB@$pd?fUXE0z+H4Qs{#h~^yD<rbNil$Dj;>?$%w!=5ZZdjyO)
zknqV4#uUn1>VnA8tE;O`kO+p&NcL3~Xu-gX>r77R>RC?Z;#wyAx-r|#!^iiZ^h>wN
z0uiK8{Et6RvcqG)n`y(Mn~p2B{O#K}C3^SD#Gj4kBf#$p9yR#Hf!VDPL1m<ymMzh7
zHE4v9EFs|tpVnhCtb|TI(!NLy_>MKvxk}1-lBq!u72Jo#`$8MUw-X<VxiT14ly8*2
zswpoZ5wdRSF?<fF3wE<6`lFUo(|-vq{NyGY&Nto!G<maYYq8zk-5k at _dUy{H4}fV=
zXuCq-OpK07^uHVb41r=N^SF(Z6Dw8d!oP8#%KTqI=~$tX at QLgN+{y38lB$DUzrXv<
zXnpegE8p$U at BVA@S?S>cxhSEy&DVqM8{`bw_??gA=`7eEkYNL*C_ye*W5BCF0GI%M
zR%l>SxwD`f#lZR_nDRB+rrai86m{Zmb*JoHNOX$SSV7le$*v$Xf;XL&q5(r51^@5Y
zifR1B;;Cv4<-M7l1oy$(wzy0x4J*bl%E?a>k`b$hD15}uot-~*fZ`8m?-WYsGOfu8
z2;N&;(}7huQ<$ET76%XS<|ojsdI^(JUo6cXjNbbFH+%t;9Aq72m%XtVb|v{wY-eLr
zL93x36X93~@(#8qxTXie3c$h5jpJp>pOjmN!3yTV>}=3NwN6QOwY>zT{JYBX{4b3E
z5xt)uZ>fMhjeC*<KJ<v7o?0Fx%<6V{Fnp*tCf#+2q3uA{;iDAbDlN+ro={4rCJ4t&
zeZTO@&zLkB2Bz8aa*8fNQkS0RLjO|vg`3mYs at wanf0}0lhgg3)yX+la42YGCdk5kg
zsd6TZb(ty25<squ4eO|)SvD=GRS8=K$R&pYFI6I at U9{23-G4GOetv?r93;?b49m~Y
zud3HZZO?IFc0c*^B|k!o5mzf9ud*MZQy0#AgemP94J0}O+9DB<RA$doqIUiz4Q%>r
z6+Ft!40bipMcqYMbWgAJHFX^Vg>#VpQ8<62W%r8wmRYMw!?p(kYb6@)a$)rYdk+mv
z#HSx$D<;dmi*uvKkf4=PLol6$`8F1 at M96O$m2Q0Lgsj68d^n}!rxq6%KjiYenoYDJ
zhrxh4S9W&xM*^9w)|4-rr2H<0W+M*L>NCH7;dp(bH>^*$7Wn*+U}beR#1MY^G8p5V
zz7Nep_9Zv*<HRrh-=XX0W9-9;)}`4PV#%bP<TFZB0&z*>zD3ro%z%XgW*Z#YJ~%ji
zD+E%*L}8hGu2g<{yo|v2=D1`Ug8RhuOQux_lxJNW<Oda)MOKEc*$H50sLoctVXeUV
zQDzH1OHf4~J-D>oa3?_k8ub5C&Ky at QcQbyjYGC<;RUScr4X2oQHnSfolv at 73=)9R3
zHH at OI4ptBcl!?)NZzv=5q+;)gq$K5Drii|@;+ss2tP)OAS+-o$`}Brya3P0EZ$AqF
z4Z&)ROA8#M)oRof6f<ohWwVQdh*%ypX!0<=P%Q_&*9wVH1PU;TP}2y^^-y<Y7V<%?
zvg&TgP at UmoCbdYtQo&9uVGI_B3Md45LgU}J9{0bkyEpw+`A!ebWqH4_M{nW1E8HML
z9-k4xJ?UfFjmh%`j}Zne1OVd+VEx0w)~c%L>1-zPV6N!0jBSg8?Hq7d&&mE*@MM<T
zthY+2tRm79DjB>6#3GRU(+lebwl*-gYxt at paL`h)Gjp`trF!s#QlO_e{<6%oxI-&m
zZ;m11py6X;VA#YaPp4(eygRcxuQhTW?h(Zr at g%b!Y1}apH=Ns&!+P;Mz`Z+&pnlq|
zjGLKwh6?l>%Da2eESLO#)9c)z at Dul+e!->1XtwbqefP@~P1{QnfzuZ=MEHjnWK8+I
zn`;c#b|HgBjiCXFImiH2K_5Pu{qPc5)XtG#Koqs_9an?(K2cF64ks>JQIRiLnr0Uk
zc=qoPl}^vj&=pQK=6WpkfH=QG_f$t6=iB%1Z=}kIikZeav7!buv1UQ8khtv at _~N)1
z0Mn8vPDR(LeWe||E#1t*ZAwtUIGvemD$DxCp7J07K7Q9f5{GZ!{wntfXZaL|l9yDt
zZQ|L37}IpSRkPT-HM{-!>27lb at _D(}C>h!w@(MYMo8FE=5Q`4Vcc$pxy=-eeIQG(h
zaBEv}>%Ao^OTEA<+8K+Ba<lT95~s>hj7J#pJYO)<G4npx>#R7Lb}_kOeX at A<aY-YQ
zq<j|in*Umt(r81uENDD6;Zau_jSz;@*NWzkQo3U@#4zTbsJ`mzbA}4}SHkZz={S17
z|IN#$t+Z`LKyca5s_Ogbr34g+6am6TFy75aWx=oj;iVyK+JMl&n8psiXwipn{Q&EH
z5J+my3nE;!vZ>Y&-jO9xrHsKn*6A{DgDnzFlwPogj%X<Zf88Onx^2Regg)c-QI_&U
zIQw6uw at L-^U+EPnRR2bCC${s at fnNKNm&TgU_eD~m=2(%R(khZe`kdplg|-o)nPVKK
zQ-8<HYT(Bd at 6&rZ;JJz8$8ceX<Vp6*CspGoH{7z>U1TCTCK8JJhdj87TRfc#ReQOd
z$Y(O`^61+rQ*v-#DX9zBs;krSg4f<f{noZNpLv1fj?E33TsKecPjxC`w0Y74R&j}X
zp~y7|TOqyR`nSIbUe|xgC1x|W*C+lY*7^m0ReBU9JR>}?drOo=2vqLJg5a?*eX#~g
zWw7jq&{`!_cm2N>Af&|+YzpRJTPcpHYi}1AO{?VfR8F at 92VP)1!AsxwCIh=Lc$9%)
zQ|1&2l-NZX(8c((dJr7p{VvZ3<`SWadBBwf>|DU(s#DO>#E&%I1k=icNd(R`Bt+m5
z4U<I2O}Hl(ZAP|}J7R5)s<%OA>slyadp#c-#`tlMK6w_|kPfDu1jHMEC-xNa#H%xS
zQT9E9SO at l-w-r9KHC9~fr#@*66nx?(_vgeRVLXwpM)|FPt+XNWV<kElPVNR#t{YZv
zCAKyyg=actHtXFFa*mA<WGH<id3i|{jl^V}UO^Oj6W&_)fr0b=7zrs0kXS}xDux$R
zq|2P{2Z+`nDX$p3cm52}M*&yXk*jnNcL_AhxMLGimooW;^2r!La4~5W@=AAx!ZreU
zy2Z2fAQoEL=iY)Qvw*qOi2jVr*%vc2r;xT;lNAb-ltEH0GaeK2ImAz_E$Y8wxA>kF
zG0iW(yU1$g2IyW-ioUSDtQjadH=IN*4<dUgb5v@*5$l2gp7qrS-lxU2kiC7C(LD0O
zfHOY?QCvM}E>}_C4ck$7-tFbGRjPjjvJ%RD at D%rW)OQV?SXxlYBoPTmKLSdGRpSg5
zcP2HYcsDiCk_>`tr3(8ID4^Y7{0Exr at WNq~lF)y-msM6)#!k#w11fr>&1~^U6<{(_
zb5#LvNN+pf``EW+YVmn)n`}HBs?CKkxAwKn+c{wF03L<Zc~`ku3eGfC-s^otqzUJ|
z$Q9f~_0oO!#AZrq^`C!#L>vbogVn^pL7C5RqtA92o<wJdKHG;q(+4L3?S;Sy>!Z|%
z0i9&32n36#vRhh*Yd78QUH9K6UPz9^Uux{X(8NFDJt+E6Nao{Sa%&<b9}DS{{|Uv8
zj#V-x4o6nqIq!RwY=t|Vy at pu&t)SoO^~7(LC>~1~8^CRN&WK%c2^X|uyIK=4d?#dI
zgzn~}a_82YE?)jRv8Z4JJ`l#VDqWG({+|^TAP8P<DDj(zpoo*ee$?=wh*YH(;~@*z
zIu~uqSd%F40><1jqgXZRfW^J2Awx-cS_*EkuAErfzIn at uNl*&x1qHx?=tvp|dRs+~
zw$%|2PR#Yl(<9l3fDamNw*ks|(EnnK>K(DyKr}IAv at hY~*_5KX2WjqxFT<2g06Mct
zI68X7L>|A(_OaLPTs_6{`0s3g*i)e!Rmf$+_TG8(%!&slXFe)7|CV193{(nc_ED;U
zs4q7YgJH{)f!E>8#`e(xn?xVe7Ota?srO~h=EK~#g<~Y9>;+och*xLYR2Xd-R)dQ-
zPg^q)=OCm6)(Gaq at Zwez%@P$GVW4xL*qDzUW3+ool+t(e%_6H^+ at gLV%de}S{%hJ9
zExGQFCUJy<1p2`pSK#vx{1}?@T7BdvNtRbuR^~d+GTubOJ^$-dmznf;naK?Ysw(Wb
zh}2Kf4upUZt*WXzuy5TR*ck{Yga3t&hRPhu1z~<<Od^2J;!x&tQPni7s;UA}#aEzE
zXG0;^XY=*8 at 0v6>qXVbBpanNSCxUV;l3~&%4d-c=j5F^6tMk)!t;+(d9K`j*U#wiL
z4U{o1Or7i`O at o;Ve=f}vnQ3AgmDY^mh=h!mPDF!b{NBrGHR?C6-`||t-2L*XgH>7i
z+Xa6Ol{J+pyyV%y+5sJ-vjH<g8vO5(J(XJPJL)Mno_ygacJ--!hbt#-A=)pZlw4r)
z15G?`loW4{bU;9W-ggfFJP*M*8*Y6W3p+wKo(s6Zp&0y<`g-Sy&d2TqUFQEV0f}W_
z6f39r!eYm(K&ozGc{##=J|$*6><D9<e4umv{O|XF(TU&fmlpHr-m!}nR at q@R={x&(
z>mSXykd)WVH(-2#fr-OCoDciDf>v>&q#hv7ZleL0-9oQ6jVmv$Z$R?2KJX8DDXa2@
zlGB3v`xFPYbqDTxWnEZS#oh3dhM_#Pg5B_<5|2B#L0X~yu(b9hD9n3$@_q5~8R^uV
z=N>s>DX}F2RRX<8JxIK6rWa3<Rdn%xA?Dzg?dRub3D7m|HSg&By78nxcaL9!NX3B&
z^qo0HHrxoKFz*XtbYSK<$aP0MZ9gCbZgUS054eRII6N}LC26n?U)+ at avJT%~sG#Qh
z6S%fn+ at 2Qr{-poM;!M$fV1tfj6MJ)%+r at q}%;4T%FLyQN!#Rn>@r9bw_C;$eVTpNg
z@$(XnH)PfMT%k$nUwTXwj(L@?j$^50b0_s|eAg2-1D-MXk09!}XCf1j2*I%*Wq^J>
z&DNqIYx$Q_v&LCYRH}zwdZYC;S+3{0w|lV5G`E+#)Ob_F=M#Mp0Sg<0&xY2?Wmbn*
zmM_Iwy-xBRIH6YSbMX^H5o_!fJo-Ov$XkKc()8L*{Vp+2zP0I6-qD(RifbjJ<O4z8
z^y|JKJiMj}L37?_mJ<9u^NEi7t0&-g0YpXA1F!2@{aZAi^HfVhF!aHJ9FTPS{DAXK
zUtd4iXY#fp?n^#P!8BE#3LAl>WUa+;i({$+4LJOJ<wy96l7~u1<53{%ux-oCFnC)5
z@@0|Q+Y5`)zY?wvz~&JrK;muo=&SY1QZJl&Tr)ZZ&9kMz*<DHi2}fUjS{O4bOSMa9
zn2PH%?`ggnD+^@*g6jb2fNRs7YC02YARSK at 6n_HGZ2O#FMeNxFSdsYSVL_>cKqiq*
zQshwT?Zcf+CZxmYumi{23KRqybpe*yTp~KGyB+f0O;tU$(#Hz;ugYveZyf}XS1^Cn
zTTD&y25z~Z=$-ez4N2l(R}P4$SA;jf{RC;s_vT}gnF#)pc<l~|0w~Pq+R?_ at xs4h!
z6Yoa(u3N#KKDLMu7bG!xcs6UpJ%d26uCpYokiIlu`9s~Emw01GY6D*o=V!kiu*U(|
z{8=oN??!}ew)xbzj?w>Wva6XdDlp6r@^}~+6|d~MX9&4fRpMbR4_OXqi~y!l#9Pp>
zSAoev`nU77-|Lcl`RrgvpVBhhO at MBkDcdIBN<)1I$)I+FPD1k8m=U}((DAITtu>FF
z at M<SZ*_(iPm%DH&&j&YR79mE!DW~J>D3eV%OlDPDIf5caaiqq*;f!iqdE}u;Gy6Mv
zjl_M8)^*Gm^wpLkdZY{RFz$iAx0!`vrZ<ilZ{>2Yuml4aiM--gEqfY4Ot1UDrmpa$
z&NRxNKQj&$5gl?z9T*c-K&YV09A8Z`Y{tRO$A at 5<JP^lu)UgH-=GkA*<_mTiw%wvl
z%!}=lg)6wr+OJfIq$5Lvjg100g2E6^w`z5aQ<Df42IoEjcz$2YNpCQq55U08yQ}?o
zZ>Pq}nwf8yIf!IBn&(ixM8sieNTh_}50WdN2PJy|yvG$g_9g?TM9i3>V3PFnMd<4|
zDlF0|>Fu6_LF-P8nTB$ZWs7oMmo*-0RmG{EnALdsuGkljaV)yhi+x0kYy9A{PXe5u
z8-Bli`<DBI?G}umD9P2=HZ|ue87+xjRP2KoPN{p&t at y1tUBye&_zEaxo_AKw_k at 4n
zgncFq51P#3D^a5d=3?;DHyg^;zJb;E$~P;LTTMOi^wi1F_k0N4Z5x=GDB@;qaAs{h
zCU|Ja8`b~IKH2O?W|IO<cCh|19>;l3wzuFNKR-Dj2INj!$n4 at ECi()qC5SHGOIeh*
zqVJ4Nex^4JRp3G9WuZ_j*vv<KW5XNh3CUA}uDvcqKbV=o at 7Hl0YPI{~F;V{Af<T5{
zEXCWpUm&l!bXuuvFtw8!jDG&ZN_zA&1W9-~h0%gYcF44*Dgx5U=3s^Xb{{g{3{Mon
z>@|-v@~{k9K_&eUy30Hjyi;9A^t>>VEseMcg~KdlcO#d2lrs};{H&rFjWk4UZBtO#
zW>pT&LVT;VVU>UU7?XPCqVec4F>fexIJ!D%>G*wGBhF2L9EX++Q>|LZidW=T3lUXX
z5`*FGG_1G&=pnzl6H+Z|lb433k_MR<IMqljFdAjZVKKbp9)|E#GvJDB;QY4hL|^#e
zh!QXb21tlN#?7OYW%Zj-G&l;E!e7c(cNy{+nC5mC_tN0l{u5!r at WZdMXr;Ps89uQb
zHg_pw!iTJ>Yi|65DCXw{uiO0}N)%Y{slO&uDv2%BAu7)^?zd?X>wk!vaPceB(Ehe8
z!)*;)2 at PE0AG57C`?77~>3tJKGbXLJe)DQfvdr*&Qkj$%872w3M|J8<rmn1O=J@^Q
zTSH`LB6}%>tML$Yw`6ULx_IzW5xUPLmp<8KgF-J%&@VafzO>8s!@QyfVx&Ab61um9
zRi*f<-`5F$>Se~r&}%II)l+OXRp#!<lq|W>uBH*8d+fNBpMD!5dSMNs&?O}Y_&cnH
zzJwd)emP}o;H(|6EIst*yqcMT`f_^$lkU|2P)A+tN_hJ+PY1cYe0lTg?ag;lrkQRa
zH$>b|hCx}7tK_1wGU_R2to{~Lh86=pPj7dxR`xUv7Yg{8fV1WhTRe`NX`v1{yE30X
z)=6VhQAw0^5zXKG0`NP~3EZPzX)2>BiChjcaZKXsQOjeQH4;FjPO9^qwdcd>)%}_%
z{VsKnyCsla_nq5FD*RRktHSwZU%wzr0YoVM04>25M;wKL-{<3JTjQQ03AJZ!&>LSi
ztoWt>V>@R#kTp?K5zU%PapNcw3g3s+Z)X_1Lbn<=qp6Gy90i=;^8YBoy-$t{Dl*k=
zfmKe!<f4p}E@@yU4jITwB7xfop&qwU7%Uv+4CnO5Q9{O44#JG0NQ>>iw)n-l3d+&I
za*Z2D`@c;O at butNKaBWHr#$!cK5g7u_?FBpGw at A*h0VahHapg|wV<M)P<t+t{}9#w
zQ9Hwu5Lo4v<O at z`pal<Y;`jTDbQn4vI!2V&3tij?mH~4XEI&Wx8rAIJ_KDic%{n_V
zHf{lE!Sq%n=7*<E+rCKsK#15Ybbi;3w62x)?7Tb7@<76NfYSrHgHW=p-L<#Zjy>N_
z_p={=$K|}&xU+%l)ZUWW-lf>!z`?VK=qDANf#*la-L%v2ZNM#a=aqutGavaN4Ke=C
z=xGEbX4M~EU^(>phiAW|DDv40#Ak-#+I-`zJL1)Ib%3Bjn_2L+>uz7H6HR at oHhV_+
zemCWA!df&0oQb2~B?48N$^B0q7tl6Ya!AC~)h+Dy0C#JwD6KSeKGv)xYDD1Z`>$+`
z%mNlmusNHxyn(aY#Mm8cZqAwkwNWo&V>~QwYz4tdZ1mFXNrbOuw&1t=NR(v>)-Bwn
z0tzO-@`G~*&{HfX2ljfDB>&eCwP*&T`B^^K#s_gd;05pM`RUB{4EE7wsEpn%L<lnA
zycV2x_DEFMV}Tp~*?B~T4%Pfw<BqMJjIYO=2910<Y-1w;rpp`OiXp_>=?5ksxd8UY
z!(Na1;pyvOdG{5nN5HwJ+`v##Ir=tD!9DHEgQRlXYdHFjZ0mZAr^&CFdf!)yb at v@r
zNcIrx&Dpf%kd3Zk+BC?o%P<Aag|_oy;t~3S?z5d0`}(0UeB($5UZG)v?=ugwh)O8i
z#HlM9)84o>@3pm)6iS2nmB*Wc?Wn<Fhs*PBmaJw(kOO-sg__}zypQFGD{Z5fscdpz
zAqMQ0ptgL;g-g at 5ex{c7yeufY`=_LFj%0FS_oI5LJVhs2zZi()7=RstjNbgwy`9s<
zIG_LB at Eu!K)CC=$nXpvyc2jqJ9I~%d08?)BuERzIj}VV}I^s+h@()XC9DWvUgJdwp
zhtuowhjD^sRm2s;!KU;{NZajuv<}9S`_y?zF)GvMGMYy9qU6up{zJnAWhTqD%aR<I
z`PcO*Q{}Mz6$oRjXD9iHD<n$Q7iP)O9ToH*5+zfn56%}`yK$F{JW0W|`s<SI?lJ{C
zpSb*Mr>k=<Jrfk at vxE>$Yb}YcG3YXLLkIm${Z>g|WKmkEENYOPBY&@@{e5DUJq^j~
z`X_D&xwnl~%55KeY*T2!YRfTF-geaMbshAGYp~!;^U$j7u at IP@_MOJ)8xG at Hm^RGN
znW*Mje^(f9e_A9F^GA}Zp7nivRc?DRCJpP``JEI%(&g-r%Z=zlg1rnRQ=c)b$|PYn
z??ip81I-%wJ7l3oIVn5P<N~wC3+qi}K&yvR-i2L1PbGcx9-RJz4(=g_#Qtu`qIZ?I
zJF_Q34UhK-kb4ucpoD;Da#yQ~h!bt+#Ge+NcfZO-!+>COtAzZS9%}R9xPIjOl5q?;
z_0Q6CsFM}4!!u7jv&v(k47`oi*Q~OVLFGaQ&n{Gc(R3>h6C=|*Q9CbkU<?mpc#nde
zmBPV$I<zgoKt~K{QinTzQA#4~;gw&s+OT*G+$b293w$gbR`ZiEgvFf(eHWrDPsPbJ
z_BvQemLj|%==6?lFa<9&3pT-FTiwrhv#qbNo~Ok9LVPCiQ?CysPVLVyhJG(t^vmW1
zN_7%~nBp7p&!a*ym^>af(Qxv~Ne%|V__g)}t=*nNync7rk>o4!bdReLP^X)Dph|>D
zB!8kVhUpHS2#SErh~wt8<|c4`fVq7={d^@J!JGy0t1t5eS at DozzHW}hPdY}Qa6xx%
zsB7Xt0%sIsvjZ*7I={&}oVECW#C1S5J-8HSZnnv0pkTj55W)luM40g=m7mb>ErL>2
zRm at aA7xOZ_m1>cr$d5fAZ2~SO%+Z-;EZ!kpgzj{eVJ~{ASuj$9-*$prs0e<hH^Uj2
zNcslaYmdJujD7FRT^B1AH#2!V_Y^-G-cY~nbsO1q9Af!CHJ=UW)c25`y*QCoF0l1I
ziapvILgHI@`lkI!bqu{>jc at Bz&CEUVv&{vs<gksO>k at jOr!vmj0xpf)D$~3kKLtcw
zrk8Tmd at JGk1E&nXEki;|N^0ZuVP=_mYh>ez=;g5*7E(;wc4%JEN5djIVfOs4LC3_8
z=YQdi+QeyaTli2IQlZL2zdtNGj<q;KQ8ljrifRYFMcf#GOR>Yh(7YFYo#ke!xa%7~
zQ#tsptsQ1cApV=-c2sGoV{z04hLSt~03;0^b{Ow-WS<HoTM~k40a_U0MGZ at Kj9cMX
zx0S-O{L_&{ni_QHM_Ro{gdRo_0Puj%LQ?#@;@OQ;KK8I=HuF1Y&RbKFcL~^g5jJ+n
zFIU83LHlWm)3{q-sG?sPbbLu#yBB2ZK9-n2Ti#u;=t!hP^~y37ge-eNcSD}X3*`ds
zGd{|1^p!dxW+kJl9`_Q9KJXZR`Xh%EXP-r%szfcsx1(7Q!0}H5vy8=bdH=Pb>lUr~
zxau at KpnOBnPlgB}g2oxsbJkE<+ctj_ at WrzKzM6qy2+atkrZ$o5rZZXJrSW|)*Gr8N
z64%FDOc3ijf@;vh%!g~xWO>by?Y4S!@Vql6sPB2K@`H;?dHL9Tf7Zt8RN%3u`9{A-
z`xgFbr(Mv2Zt(T-k7A*H$lgqMi0 at dKiMf?fG$kO|?~4fjvaynHcHZ#G=d0U+WBg);
zG7x#3Au=5k6r20XB0qQTY9loumvqgJvZFL9MeOhIk8*vYMmS>;i=Y3tt6!|%R^N9{
zAWc*WKH-o;X`XurbCfcHmUEsxNtja9RWIA7yeu1AQbuuiUP^RH>o6;+rHS_?3Sn2J
z)!j<Q%?;rdtJF|Tq5oh_gRG19L=648&hOVX!h_*W3YNpo53 at RQ8q-%9_0YAzX&542
z_@|4FHYZz+e+yn$T^=@8bm}fKE+cI+T$)kv3089%j;l at G>d9Ys9JFkmHOLJZ(<Ct9
zu=V|Api!dNVj at gct}n%G{DfgmvuO>N@*0dWjTxnbD1N4c>=MIoyxW+lp8%;rVtkt3
zU<lnbpH-MB!9h;2yRV?~MtETuBLQyTes9{QEQC~*%-vWn!UQV=87Wsq&MI6%wnD~O
zTN~W?L8rO$D~)`%M0ipL%J~4iEqVgZR`L5cYOE=o%GlwigPQeTySa7B3RYFb6sLEX
z32${Z7qeiGw!8+tEeT|vq?hW3OO8H%ZD$6JF6-yHBafj+@@i&Rgk+&FlnG at q%nN^K
z<Ptv+7j9ipbBs*1Sh^+1ZC?QKj3FT}t2I2mtR?A4rCf}Lg(G9W_dEGH2kyHkHK}YE
z3C-z>B$Zg-^A|K26mFi-US>9<okC5x7i?%w+WAD+LZ#yaSQYw`{@3t&dANf?CMet~
z41~jl;y7%cC<n at WW94)&_;?sS at D9+%<eI)#*@2h3gZgZkPTPcjs5`!3Bd@*C_Np~^
z7-bQ at YeO6KS)l9qkm9Gy!GzLh@`A6GG}zf?LxRnVSU1tL6BcVgm-!b3Aqy{+x{_Ct
zmvCussr(<5r`q7zkX*Tq)?lnEPoh{-;JNM<KE%2tGU0I06=RBv!#7TNM>|e6#rtm6
zMnRKy`(f7wqk!LJ at T~egl7!&FpI%g%HzB at NQc}3d(O_kq153HD>T~wf`LC^%+H$KB
zWfBEvm6q-lZl0(wD$s*nX*@z)fPg<n9ZV6p!(UNdEeSGp at 3)hw<pp_%({Z4oHAJ^v
z+G-d*b;F~3r>UuaDh5iqh-y*0(8CJP_o5zPW|S0>Y!{Ju&SK`Xw1nINoQ%UN at L#)@
zY0Zr`=`f~kGhZrIz*X`tD+zL{FSu#SH|N+O**5CNj{mX$4DQ`A=#$(iRH8BO$ub$_
z=dL(&;cBD`c|fJ@;nf1RXUA5}7IiHX4dGV;enEUIv-Zya5%tzlQGIXwFg<{Dcb9;|
zhmN78J48TITBK2iknWV0h5<oPY3XjHLrICD1%aWPcl-UVXT59j7i;F6Gw1BH_r33{
zh73|Zm2He1DU<-%nueCvmdTBbEP@%-Ab2(<UlfWAGCBGMQ)}<&W7p@{RndM#lV!n8
z_Qc)Er$;`Ur;RxlkfZ~rE8ErrHq~S$r-=kgrcY-x5>nenUtPJ69C*h at 3|4268<RF^
zv6^+YzEBnLNLRQrh5-QpkQE(8l~;{H%aLwCjyo+TG3sNCpDXWl at 8^y&_nes8E<4uA
zcCY^#5NxS_w{wjav at i9aAjU0m{6)4ubJbszRCFq(xV2*`teVWG`4yQxBny*3I+Pzf
za(6V8)t8i2iToG?K4pOa1 at fdvvPHECCa5DUK)DAYWB|?DaK|in?M1Jj`a&onKhA*T
z`Vyhg%eQ#m|9V%>i%0J};4?2I{;OTAm|%jNB!-B;&dS_t23i>qV3Vc>C at U(8yx_#(
zFCHyty6_u77eQVB`}c3)gO)a(S*}y4(>aza3940qMO)k3HK%`6)D7$JS8Bb#-us8R
zuZw|o8noSNeY@!o(~wZUdo_*}5Mn<Sow=ES_t!7$jY!2voUJj^$Zq9g-7Y6{DvtC2
zolsMx;FF%9#O%KtiH%lQU*B&}rYik-XK$~kP$BXk`aNU=(tz-KKGqjymhlD-C9}`f
z*s4QsgVnxV2G`YUVqF%{1mt}<yfJEd=REqJB-t*(A3)xakbW~eJ7dGXd7Rr3+<8G(
z)u|nP;TNkO<8faHIU<#Dg?hpq9b{JvHZXLA&~c`NLa_6!S!bRYHUFRt?et#rMTK9!
zf6Y&dg*Fh(s5Foxn({;;21MX-fQVnU`beT6D-KHsT>0@}QWV2(G(tzkV8YomqTW3{
zOSa?*dD?o~F<E1p#rx6)R~mIG03(9PAK)8hQ#)@gZWPHM=DY~3+mr$WWkAo7BSlUi
z6SN)OkG#s$1rti_IRG^dI8e<sxLV|-6`r)%d1g{`4%hJ8kJ0hItjCLwkFRoWK@?c4
z){>%6EHloc0B=4p$w9}2vC(##pLTs at Q(f0t@;HneYt+OldmSXoaP{9oz?(;PKN<VC
zMR`Np_Hb_Z{t{X<)w!)j5Edan#m`+L0zd#9e_R1OZ8aip_y{CIb)TX?(^(~7>CRng
zCj7E;hx*mI!H%Xk%wi$7<^Jj=>_1QD`~4!yLb+PxrFKX7ii>nm6Qw`4Xzri&`j>~D
zK<P)Oq$5N+s{U*J&zEs!KY3*g%;sH0*~6v%n?H at z`Ax4F(D-t6YlPm->swDKJ at Ap?
z0 at J}~+S=o~w$BBdFrLJ~8?}M46ljpi>XL!3J6Jt{101fhUGrWU6E+wZRUVsapUZL0
zW+UmHq-k?aP>?t8=#;g at QeaFB@`iiCWz~Y#S$2KF&!LLkqJ?01moRH7uZnX~JetTw
zX=)HzyJ@&1iQMNM^IPF`o5Z0Ik$Nd#Z6y2ppiIm&I`K(%1LA7MpHO#tWwmXO<VXSk
z)7`k0t3hHzLotyrCYdv(6^5*CVYX`VS4RfhM0v4KXt>Rh6SSSRG7nD=d`lQPTY&<4
zP%^zs`cyzIoDM6F6nQQv!C$pa-g>z|j{M#0e|z?w6QvOMQy?VIcY2_lXR*+i;W(V6
zl?kIj_NQiXGR2Isjne0(IJA({Hs?jqg1)=E1B^F%<m%5%G}B!Rvsr7-gdD1Ap~AiE
zx+i>Jutu=e<G12U=GA6o6e3B+w@`6ve<u~<*lo<j-Arh#Tv#7Q`3=>y0%x3RS~pew
z&2R^|mb`&nnWYePqo84#(*V;tUd(aNb-fycMYWs&JG3S<*H^XKvU>Q$a>3<SbG5s+
zHWDtfE%V`#t{wD=?F*sL-qX0n^1o<j47_hA$6j)z(=|Ym4PT at 0E%LtS%<~=XDa%-i
za^f?GJi)b&<kT1)SV+-Udb(#h>y)eV2N#a5^Ar1bWqZiMzC?~NWbUpT{SrBzr}SS^
zFm<zA?H6Prp=q?w+v~5>=o`HgSAt#<FC}slf^!_4?6ZLQ;ydDMSAF&^P^l~L*e5R+
zdpt(loysg5V@>wn9UO6K-S9E@@7MTtQw+C{DEY{qG6Y+AMil{qH_q!yBh3Df3jkyT
zLRjo(fBjThX}?EzxXfoF3Ep%YwvlIa97^PLh+!_`7tktC_|L|ABUb7$+(NLU`@b7i
zi#-ZsHgKiPTRyO!j5O^2^BzsR)tAV3TEf(K(|2TuqmTw4yLG5CJim31 at XuStaET+D
zyxqhJe?*Jh-_26izl+!`|1W@%E`X%r{ze}gN?WlUG5w-m4xg1vje*ZuDk%NzP|jMX
zQ(e-cxBV6C(-y=lURNhsmLxgP*T>gPy>}u%&*>5;NDH=Yg%MfyF=Irv0$x-c;(P|?
z1Ij03Y*OqD6FiPPZ9IRAQ&A<Hl&0&D at pgv)n#Z8!-hBbAEhx2ZGvh~Nz?x%*!tEp2
z-+~&g#HMZr+i8bXe_c1>RdbAD!Lzetsmni8^}jaLgdy`@BG<RQSCcGU`;#wngI708
zt6siLkTG&#($VfBFNH?tzwsre4ZOrnCHm++rg=HnVkq}05fAU9x&NzK(OQ*e;N~S0
za+9~y`O}^+Of55WB2;vn+kZF3zQ<?J=k`+hVs$Ma8V9`EP3k~4qmvo#So2rn!dHl}
zpY~SEJcO&&`43cyJlx4Azt-+(E98}P|8u&a6&Ju*cEsC#gX+0aHE|M~Fs6ZDr&9G4
z%=u^594Tc at -#0%C2)-VS0UG=4Bu!(m)MeF^`Ksi*p)WUVh%dDxsr}cpQKgToovQ5;
z2=p=wU5j?O96qZv<4Ue=5VGpLX}vwARjF*EKEY!&SM8comx<x)n3h|)r@!3f3yc+I
zY$2?)Xr}lQhtlQM&yz&haF6GIzrc2I-Q|j$;d70waP71$eH!BvHUUDa6 at E^uunS at Q
z&K-;ldS at wfO`=`}Uw%f#J;*DDpMP1aue*QPx0f9ln!o&jW-bAfrkMHus$QY_wQ<xu
zikG-pk})n=I-iTNG$-hl{i7DX2#z1l#OWad-hH5O<gs3SH;OO*Z#DNaz5Cc1YQ1<Q
zW!ZN%yQ;L(Y1RS5Te-87sc6|X<Ch|=U$<N-kwnJ-WhS^t{gB&&;WQ2<- at X5Pc_&R@
zYW^L?q(HXXV!*6nIT7`F<frQ$8kDVkf2 at UgqP4nrHuA9g_+;Inses4Qw at 8U4&l_#z
zD*Z~&+JTeXt_k1=_pCfnx!nEYfPF$u?Uwl3e&qbIv~jNe;;l_aUP4_VT2lO9?cec`
zyuFZ2t*-I6%q=_5c%6U9nh at a}u>Y$K*tq#v%RkX*P|{Oh=ZV_rwpH$fcA_KMoX+`3
zT&8kLS1G>^|3jQNf|O?ki~T3o;$-#d*I{Im;+`(9{Ks8hy^N)(@x1MRCmjQP!*YVr
zCvSIrw*u%izIACj)3kOfr-H!Tm8F>ORUyIW4LY+kA#XM`n*{}ZJjmpPw^z%x1Boe}
z-VT12K287Gc&*^+elLsKo-F^~lSb74dVK9!C~<AqW0&~Rc%9$o`wPF~*(pauv6u`r
zzC!n2*X4eUq<p4Bh9CU~oo0`uw%%STc}5 at nCK}&F-CgJJ4Bh`p3i{_T{XF;01Kwt9
zH|@N_DQv1!Li));Y0l65>Z at -b_@7~rYI-itTYO4#fnL|Dt#*&`_DNQnL`h(T7JbB@
z5p5`J|M9*=xQruf>xryB=1SH?o^#9tn|Ni>4+wb};AoVZ#f8Ua6)>R{bZY#x)+#s0
z{a4w7i%3&gZ$4-=dHKpdq8|=WC?;$~G^>G!$aC$@H1LVy=ob|<3opJ6_+uQQmt91x
zk{Em;x6hNIv|80Z)RX*Q-R5N))n9iqlnC|+R#g3hE4#xdtuebi8*?h)1XCKN{71|u
zldO_L?T6|j|NaFQoR=TE%K1U{S6=0wmYLLpXntz&{2RYc#a_3NCIE!N0-p)InjOPN
zRUdw|2|yFs@|F11lZ!!NTEh+w$pYy2#uOUUpmY*u#3U^>{yY+=#Y at mb1d3HK@&T4#
zRD|ASs^wz$zYF}|FHL6qso~{TWkm&&o=P0M`Qx&Fj2IlyPsZ7gpCFpX<%l}pni-{s
zgF+T$F{YK?54tD+yVn2vqhWs>1Jq5Ev$K&~TU&D%Oxq<C<sa>oYV#bSS+>SNqXL?;
zplGeD1K2zxpdhMnqyVh0!u{W~v<wT<#7LF0D_YMe{?ogu@@M`JnIf^5S)#3~A)!i^
z$~?kP=SMo5>UaJBMLmAf!^zt&1U~_=Iol5hY;(R}lQlbt?XGaeaMO4=Ks`M at 1pyTo
zaM=JaZMC^#X%)-?(a<ofD8K_BieuiHC{)1iA at V!lPXcm3p{EkCBPRcqf#o(oc0o2x
zF2LJGv7%C&PiAw>DR!g*=segU0Z0$Q;GdN<lAD#4OU=z!lr%CUgPsaOK>?g0c``)+
zlL9y&2>PRoCd$kEJ>iedFqp>ncm751tRtPgoK3{uW6Gf@>LNOd{8IEc#RxzI9-M1J
z=*bvO66=;2fnJ$GYXC4~GNyozgH-V#u=z_3ADaZpPAtbj-2k18zjvj=0z17T!Bd~C
zR at wZ*y@^_s&1Tsi{#OGaw+8s(z(P!^BFK&Tr4<wC)O;DT1eBdfEhK)&UhXuz_{*$Z
z0O%R7=d%ozE-}w~^fuQ2^m+^(vy&G^xpptmWEVpU|=7S$<9|OnkdsWTSqa4cl
zKU5v%$K)?2Y|BLv&_>`rH8s?n4%=(~Po at kKckpFTf^HysToXQ8wCCG*Q%s`POn_9G
zuKP%7kPNPySK-#u*w=3S1Z+%z7-Yor`SUd~g8%jIj-Y&74Tm>iAp94oT3^H^@h6uf
zMHQH!g5fQeK>Cm;t)2qerPn>pvNu=daHKbN+4VFSR=b6h at k??376d^}?m0#Yjs70X
zlYWKcBoDg*{&Y}n(G#a<x?rjg2GoyAK!ERGnQkf0JS!FiCbw2pz*F^?j8~uudfFVx
z;V#M=Aoh=+aI<Li at +D(7%k0u2P^Bu@#j0;#XJIYY6Gt!u9t^K~o!#r0;tTof1gttD
z3)TM5?#ap at c71kEnkxp_d;AF}DBBcJs#{|u`s at E*9$v0YEHj(Q-lV{k1wJ{_fP3Sk
zl>eNJ{hoJMHd&oUn)Q!^3+Eu#hubOX()^QP5w>a5l?h4aTsgn2bI9yuuf;VBLzIA)
zL>O%FO7kY{G|Y+$(E9;q7|;)P+{E8D#vK;l at piDO&m8`+P2GRmhQ2^+>OFPmFzO%j
zSd*INeOG=k%-PtmwI2vwz}S#tU0 at xPM9?Br-Ow48o(c4<NM^84mDXV)8lofz^I{uA
zJ46wj1N3ziU=VyK&R6cHXA=d at 84trp2L<C((iHBHN{rR(2$;4}D9bAA8bL*@s`So<
zbss&Q_J^;>=yOd8Y<FrmDa)}@k`89Ykt&9;u>5rb09R+(y>ad42edh0>iXP0^79RN
z{&DZc321o^n3jnu9SEZW$8Gg{>Dji61;rAI&Ze4`VkK3S!4;h{eap6Kr8!vji$1^7
zX$;*b8sZod`deu-JW{t;(Q<HTSYb-dBR9#sMw=0qiji&36s&$P)kem0K!+(ubb<I#
zQw%A{PtrNsCu)1MP<IM%axW5|dhd{n at k$JPn=jave*wi`0cp>M{>IqwYtSWX5t~EB
zUcXcE_sM?dDutK`S`iagXM>8?n7&t-GCNYl+A78#Ix6zYvK)9lxK=Dh+Wsd{KCDPn
zD^gcQtMw4IAKJHhWRjv`rs6~$(fPMDZ0N<Zmy*ouV`=n5WKxpIbeQ%<k(0ZvmVZ%x
z%6^RXkT~qq-gP at 8NWs8G@Z3px_YMXnhpf+Tp+wnqx#wIO4>HB5C51AyYe|3l08<GH
z4$#VH^?|P>#UX3-tK$-6 at sK&E5OHLAInYrsV8Vx*R`oS at YFR2B6F=x}VC9DjFDTnA
zsaSaiDGDeZM$+0gGyaYp#-t`9NN!?4+-}z>3yh&tFGZKUSKMQf>YGJn!iwvqT!455
zB09Lf6ni(J%U!HPw>|#&n14-i44fEu9FN*Wg;!H*zuh{F+6eun{je>Y at oOv>z2eY^
zKj=_uYUuWNasr2xtWvg&=r=R3Uzhi5!Gyl~Y^<is;$j>2^~7#P9Xx4j)gvD&))RPk
z9k1zzsAk)W^>@sWQrgGzH~OZOK~zFh4?g?}=d|9pO?PX4$)_SRQ7`d=jxH!L<P at 30
z_E=2N#o1cP%;PpZmb(5zyi=bobzPvp&y(z`d*_l8(L;Ya0_BpwSeFPpac5hSJMKfb
zVG{+<HJGBAa|qvpc7UEGXzOD2FdX8l>gt)vz;mz)VNK?pz9~3!*U`LyJCPDTyB+u|
zk-_KjON>vPF%rBAq0me98bPvyRRTyGWySc_UDO4eYw?5FL4i|rW9W(}*OHtQn-7^g
zWMB$f#e!uH=PGxjh`u0$u78Yy4gV#wDE+M7c+b8sE0RX1;*t?L(!V1C)+S);{mup@
zh^mZ2lrbNDlwA5QpV1dg$8@>tSeX?HvA=}y!8 at 3b-$Mi%iQQZuPUQJwE7U`t`ktIp
zFQDvtHFxt*NpN{|vOepDROrAW!thwX<;I1SI95+?W#@*4$%4>Cq%d~s)G3x;G8+*Y
z5}_*;1B}lZ$MvGM2=3 at Fe)y23hJ}kjah~`bK)bbs6HWtsIO3JxsC at R>2v)w?u}Cfj
zF7nD0S4tZwab$Rk1K4w*LCRD-+EW_{MX1fPtoN}Jvwf+93^p-cu`wK<J@<pKO`j5g
z1tQ#9p|x;_J6PL%c_^O`8x7DyVe6bJL%7tR&OQ{b3yfT8IhCxW)NCh+BZF-Wd1ctC
zi%^0q_WqOIAP(@QV3;Y`VM=V*JB_q49Z5i1;v!QomAi0!w{6%SqYriwB)UzVf%lU4
z!avtWOxyuJo;0>j&Gp}Fjd@|30{P}hi0;lpz4HqjbeKr2B>OGXe`7q8Yir|!XJX${
z&YuRqWN=#(9%bV^{hBIXa5HU!^I?LaNJ=dz=3K&?NwuL^ugqvAiu(Nl)5J2O70i35
zBFOlSBzVawFWb7Q=!ZCf>7|p)@cq at E%Bah~x?dCM6m$UH<d2FS>$-2Is4?KG<5QAs
z#%#H=351aM#Vw%0sA#8&;cAMtJFjZtdB-c^OV$O}Yh~LRSZ|uFaKrGaRule~Z`Sfl
z;iWEm?SmY5sb_xfyp5sK%8j9W22WcyqK at 9MqKYjj(}84KFywQkamhR~D<ULevO$%(
zi;wc$S?@Z}*aqlh;JpH)?vOyp#?f>hhjelZGa{kzS^>=HsePYrK%?&vl>r-c9^I>A
z_mmI#kG)57ji+9iMt%rjU0M^<!ra*|$d*=@$XX{zR&}Y|i9ONxQh^<P-2V{O=E!%<
z1RXF0(|>ay*d$_89I0U@$o1hp9v{^E8Puo at BML6h>n%sg6Gq6ezWjILm<tNuQ#1QA
zsh`Fzy<FGjCZGWF*&hv!RTIM-47s2O>t)FM- at 2nKv1zj9LOs1CQ}Jg9g%5CM#a=l=
zMbtqi$E*l2080s*n2?{*of&+w^muPK-9Bj%;A at 7g$7I0OmgLqMByjLV2~3g44#dGs
z)n38&#c(c(a+_!o#=E><oFWs+BpZ{$XgNz(1 at WW$N4?f+cPa9SRTYC{xYZV|oWU|6
z+hl4OrUtqN4dSCE#<-2=r!pnJnYt-(I-277Phgl{B)JyQE-kWu$ri*YKZj*yvLtNm
z1L at ctF%zp+(h~#@wMDXz9#)B?p%}+2gRD-RafajMC+3D-7o at g_J5oCHSS!Q+56RUV
zHAb2xyJja2EK;2Lue);%77kCfz<4O}!N{wOmR3HNo#c4B?PYN-$&I=m6r7<kd0*6~
zaTs~Z<h_9N*{xH~mY`0ATe%pU1ELO{=p1(5b$v1%Gb{`eFR3-2K6<5EX+`xP$`-q)
z%|6VS<XhV1Kqxu}tWkRMUve+%kWG#J%Jb<PHc#k{meZPTAXI*=i);vm+NS*iMv=ae
ze#kskS;tv66Psaw6h}B7<vx&C17Q>07&+eI8xjsQ97FeAp~E27R;*GRAM9d6Wp0+<
zwLud)^{IFPb7X?Rp(oG3(WM4Xo~d%^ml-I&jdb7~((+VJgmkI6>}JA5IKf at s5wBj(
zv#%;MP2B(Rk$r<YFhO$XBK3}ANv>w>;_(1Iv`Wo4U6K`)^!3gI1o(WOTk{IwBQ&oJ
z at -p5{c`nwQ1!t?&t9qZ{k<U}zo3b3NW;(`vJb9RICsI#nS|7jQ<lEk843+%2RLHMc
z+g-N(7qeo|5W~nvB&sI&ryHb!aOr7mFg9)h>B?vSyvj&>l`FQVF57+SsOInbzR;^I
z!^8zwI9s2kRR9hK&w{)dIDt$vmeiv)0+-mRi{eLpB(}ch-M3zR+!yON$@Xhap(E(O
zHe`;@i1~2CyFUsFRtqZhrb#7!^~<AF4uh$pRBCSINe649{cPQj3QM2eo9f?;(bG+x
z6Wkan6nKP2&xZXfCi_?abj5A>2L!YAXe}|FY?1)nfg at 10wKznQV}p#yfs;v|HZd<7
z1zS6NDgq%ts_)+Gv{2WI7pkleizdZMv7)L*BJKq1v|LPKnYes`Ye`nV8ND**_ww?Z
zw85p}yFS=LNN*LTG+NfY`wd-bJ##2IZwNKR+2;HcmrkFVbjjhmcY0JCDj+5 at 2Hj4P
zGlLfIKOV(`L|SbEs>gmktW>6%CvT_{XO4o<4$BIp2IwCNh+%X)93HFi at s%-OZTN2y
zV0v#1t*sKjG4KDu`T{DU>L(X>PI3q{W(wx_<+K^Z{*1h~s at _k_$e3Co?huEST&T*?
zwVNXZW%6Uuee*mx*Nu27*4yM!QZgKMWJAs$6TUh+Ci-{hZR;L;XgQIxRxVv3*abF(
zbQno8q$&tiGLG~#lbH#mefmpHGD+^9SfHaqDoSxsbbE96B=Y9hn^WVULqe#m?oZ%?
zUFyPIZVG<=LZeic9y;TKrKSmu&IK3!^nM2 at DgH5cBtX@X{uYe}dc&Fi;PLWDsOCo1
z(O1-!m10Qa==vUKr~K`9XIzehuU6jU?JfZZ=&II}`F964$8D-wgnwxdEaSr@#XfJf
ziJB4~7l0BN)<GgAxJF<e&=cxT=RNV=$Mq4!vlTB_((3kvO&!Fa(*6(}fX4QReu577
zx<kfCqJq)>3+nyLx%+~FXqDQJ!Dw at H(}uEqji5cU5f7wozm!F_I&gd5Lk}hDRbSur
z>1EK)lVhbO8m@?{gu*)AA at gj_G6VEWs_b_IpbCM~2_~UyH-<tC#W{-oqB8{-1ZVVn
zFCNcMvm7uj3X&YGHXHAAZjU|29NxJ*d6N_+31~*Tm);s<c#qkR4;*_Yhc!#5k+JZo
z at Eze;{3bRg41bmRs7<CNvB|9>O4X#mWwB=?g`?e==_0r|l9iDgAw7p(fy#VZ7-+50
z8eYETkJT%%o06I3Rte}T8B2su;)iCt at d>Cg2?|tEk88-54|}HTTMZ3)?bj0UAUgh`
zo^o5?S6dU(Bn4i{pblYLNGdAA*dkNW6F;6bKX<`{Nu*yY$HcOTv_e0GKDj?=wC)}@
zP+^{s_{{N<g at UdQdC^z&$HoC>n3Cb|W~*_S!lQEU4Xx_DU=8GZWuft1kFVMyw6sdx
zq7izsLy<Oy#G?olEyi|y at GxGD55_q6vB3A9*%b#uM-Fv!i_zNAR}b+<5wf=kc0DLp
z=fx9<KJ-K9UXYJCRwB&3NX at _a4aGRGp%cnxf<zk6hkMrclaUzgr&n!`u15m=(i@@n
zV_ZMRh9h7lA2M!{dO5EZbQ`6&Y;$gXd@#}vR69Rpa3c4gZcBQLT((_h^>NtgmiR=I
z{La4LoEM47ioIAPwz#Ivd%N~7Cgbx_0H%istWBD4ljuU&)oV)*!@NU#H4);_D at UL6
z at QRP#^#=$2s56BW>tE{%#`5_W9!shXo=b8!j!>`w+Y!Kql4x+fkCIgxKCc_e?&q#H
zhAu*gUq%T?(JXa^va%cy-DLIYIT3pwtx`db=)8|Ko(|B{<&Yi}>>2dX7t4qrFwt at S
z>3*Gn$G5xbp?00HSGMK`ag8oGO9+#UVr27Na$mo;z~fDF*$g(BI(b!}x}ik(r<0z{
zTtIVN!S=8fH&n9J^x+8AY(oXPhSPc)d$?A;N-!1*jxwv at -x&J2=;X@(?--u5go_Xi
zot#>Ofq4x#T3OKNS%^8=e?jH~iRYdrF>UCr35m)&eHwU=74x2x6jkP+LdpB(B*x!;
zU|!ucHQ?^o&%V8YI`!cbRi2UEyym*&6B$1~Wzha~((wtu-;bwP17&5Sj(S({loyJS
z_b>Hk50T4j=UC at r@a>)c;y;!ASr+CMpONOiK1lm;b+i3m)zsbHa!_5nx5U_G#)mCW
z+mm$fa})D6I|tlqv+d>2td1rPPladWqwx)5nQCvaioYM5*xxT>3wh{tb>WGln_ at Mt
zv9J%wp_^rklAc7!dkDeUvNF()@8tFh&pZc0GSZ_v6SWcRtI66`Ynpwngpr2;(M0v;
zzB&~=&_H_V5 at __25H3e)P&1(6F6ojwU5j6?Zzi@*ezc#z<i}hd7`&ksn_C?nH`PAk
zB^n<)*+&hegf8&jC!jxL__^Mu4A=0SM?6P^r^r8S>sRhv(Ant!Qkk*xN5L3JoRC<#
zxb{vxm%fcSw3eO-R~BnJQ5<L2%3t4PLELO*>Q=B`_9~m}4e)U9P^&Qb=zI`0n%?&5
zKp&SlN)|J}R{LZPHR at wsf?f`Ca!kF)K8<FN1>FGu&ml&S`RNWmzhlE(No*C32o+zx
z={!rL5+ZVkFy;tSEOiZ^Ufyg4WmSeA;#40-Ww^!?5NG%$NcQ&oEz2+?2=3p2A&4h5
z)UN`jFCuL1m_`NOJJ5cZ=XclX1YLj^gwZ`d06e$#1Z61048ku}G9Atv)fhU=YcZ{2
zlyxEEkqJINPM3h`9Tkdu*}hFs4tf%<o=b)0um5Idl4?V%Swg#W(MW(2%RSXfjg92L
zxs7FBpc!;De8p<^U5|tTlboFY;<T5z&p(F+(zG;ztYgcM=__ at L(t;=+?o#jiT%~d_
z3~e!GN}4SxuotpzYLAAnP$6RSX=O}8=k$BCiHFcBOQ(+n=oU6!>9dY=A4L(kzFse|
z_!_#I$(^UWezpt69O@!miAwzgHUXgb<$juLU(dx-Sk4W|7m8&#KUGqa*SFv4<fG-A
z%RA~++eg8kvC=;_Q-4q3FMu<|25Da!jK&YRb;TC*3|BK|tDu7AiZOCAm)u>6xk&fL
zzFz2a_->SJ{EaN4w5!QlQwpsv at bjrUo#c<JPM=Ox?!)S$n-9>FeJlti-O{lKZabmk
zgvxlg-~^QYsn#!&?6E#o7<8R2{aw=6X%+Q99mE4KV{}Dg+L8D8(zeNx0boB0FU$Vb
zyEo<&&43J6Ql0ku)P;RIg5lrie(>swFA;tmhXWyM^-o7rTN*^>q5n}Y|E1h{Ms5~~
z!Vlr{=O&(=HcfBjO<q at PC8sS>WFXoh&A#nhBlpKf{cDx%NI>DZ;@<g#w$Vohl~0pc
zFtXQMS~UrsEpKgO(zzNZD?}R_Iz-Qd(3H-vM6rUt8ov-=BpjBDkCNP(S4niMdWr9S
zBp`A?rOO|+PSDQR6v}fR55|bB5air6uPJZq?0zYDTfa%EoBo#iD(d&-DnT_}&IR}6
zN_3;bNW$@IikOM<KINAP$xE(R_W>}+axn%oI;x&fyt>3oCI(_}H~U!a<n>^!JjKd%
zISx}<sjo|qw^A%sBffw^>98(G%56+uDohY5iH)v{BdAHbu0RC4+Hq?Pg~^Z|Fq!L9
zL|c>PNwN48t5Ji4(TxjkfubOr&rta%Vr0jZ`Z$U%zqnH_t;7+qM1X-%B?<-frn613
z`l`v0L|?b)?xxz*uW==IT#$j}Q1q95dH;IhrS#N^2ARc|JOASR_{|H2Z?%R#w1095
z23}r2w7<Vm+MqrhlAsWfF!7<^yQz2{q3m}DJW(__1UH2HS;pZSiQW%CYxp9YwZ4Ck
z-#Q%nJjI`ww7lykAVufOsrOXr3lFE-Jr0-7yxq5P{$+bcRgTv`C%=DnhVO5v_%nVR
z!DA2oZtBN-?g~Gpo7Jxc%W1cFv?K?Ew?_KkJe6FrtnFDLd?3Af`}QreF!NOe%rw$2
zhS;;ZH44Q9uz=uP at _v4PP^EuJW7^E(Vk|!%FnHn3{130~sQZyoo9}m<UjDlGH}8&^
zpCp$<2+t2!5*1 at 9RP9u<+!ktVWB-9gnjb30K*HbdZt%7bNRcWZESUYHzq3S3#;J)^
zXa#2gfqp>d2<&j4CxU*6sx8T|8ymeQVyG{<`~>?mFHf?U5c08+9>5r+0Dv;XW;Q!H
zGZS`w?F*uVNMqmyAZroMTS*b~jkWTGoxlHv0UQ&EKEqjA|9=Ps9Jh%1&)Q4im(twa
zjF9G9Zji9!jBYP%0?I?x_{3+C1oYjlJ|`P5KLBV>NcZg+_y$c|a4MT){f~8+^H{ZM
zWnE%&kO!?g$Ua<3(eBB7T_!(qrMTP4h>XL|n&S_=zm2I51>Z_Wabm&C+L%6qk|>X=
z)A)9%N~=mN`~HCq7Q&R4jP|FIbAtXXImPqpUL|x_jNgA)?~fcAUkgbmPe}>!<R^{-
z)aBn{z at I^MQG#*@8za8-0*)2bVRS%B+pa1&(Q$i4JuCNFWWf{)3eAOStzgf1CewDf
zUEx^D|8W7 at OMM;?Mwb6~AhzAXFk}-AVxDs#WG9FCI-pUH-oxgz@|uyP#chzK$rr$~
z<Vzw=8L|N~`N@?PixxozV`>T6g#26e6?J7La51EEdKoIoH8OtZA=n1?G;W{1V$p|C
zD-wf9HGt$GrZTNJnPz5Zi at tqx9;^{G;h}F<c{o2krTfVvH9z)3AoJPFm$bmDq}V>3
zP4llT2(kmRHRQY?0N&V4TYsf!@ozD-V=x2e)@Y|{@>qQ8Cu{WdQi1$l4+f+Y#{v2>
zrJSweG#Hop2x&5^b?QvOAKU-kLJ1_H3B%`!;r<|hsm<>K-qJ$rG+Xg4E0<Y0q8(Ts
z)w}$TY4Y5LfB$~=@gTgtT^f3^<Z0C4LZ6kLZL59G``x*@qK7}uefKa%K=4N=0Prr`
z2|;TfqWpi)poJ7LI-!;W7k8k-v`hX5h+t{5(H0vU8rxCOzy at 71U_*caB={ck7pCqb
zV-bkVLf|{o3f>Pud}5?{YHB1*I%w;@J(ep5Bq!kY at z+>J|Hk?M at V0N?@cG(KNyfyt
z>8K)@$@_VW0R#7hSC#YE{)kTbWDPGcy873y=YWofI%XBQaM5xv2rM0Py!OO<`**1I
z!p7yitlhkVt?#>`;15=*#LLXgV`%_83$@@2qbhUnMgI>ltohn_ZN>3N(D&W=3Gg2@
z?bf;s3HdCzc?Ar^fdiM at R;E3}bPR=uP1FG3ch9xImjnr$P#YNyGDYx|0RQcO at 2!iL
z2tdhZ-vW#Xg(+p|pFkR<p9;XFAE{0Y0Xgcl5HW_FW;4^ff8=6TMYf5&?dNf7w5o$1
zS5N at dkwgUR5H0DIVf?Q9P>+W}%JrrFu*j$;NySKoN&<~br~FnrSF2k`2t&5-FqA21
z at 2ZLyJqyl479c}mOM-z4m67chDEI|?0yIV3^ZdM|kB6U$b=@pn+__gKVS!}6Sbki~
z9f_KGyi_jvsN=70i|(t<(q!x*<y`z;KvanmWB3z^6N1v0EVWbkrAh<6#0o{t)@B&Q
z{XJ4NDv55^K$H9Y>%5yylUms*d1Ln3kzF}5O1T4s5fWkWYm$OVvcz#L##>!0#?}}}
zgRw(U>YaOllq<IH@{Od&PQr7JqV)HoQ+{xV<IYZ5(+c7A at x)n2HgO&@T<}?-9%4Np
z$2E*47fX4PvM~a_21`!c_94H>==w3Q0B+UbYNM~6124^|z@`Fy37A-<k}laPqc3U4
z<r%9OGArBNMEU*g30KT&D%R14nKxSLQjofqG0JlyqyHA9m)`ekP6oPh2AuD$tQB7@
zh3GHraZ58sFz+k8L>A at CL_U(f*UkAj$wT*K_H3dh5c2Nth1;>uUea at giEqkTe0&vs
zXVBAw`53cYZY`Myp<*IS-or2g{68|SgxV{9j0=2iINKEt;d<-C-|7R#PbONtCEqdN
zxi4ImvVIGr+WS<*6|y%scd@|nX5o}%`OgUR?>aJ3e*^`u&<}Ppmuf;jnKP7t2gK9U
zG=HigrJU1qZ$x>mc91leg(>m&F{W5}DD0{la at 0F~QwTy&x}7Qp7GDUlhS7BFnMz0A
zEsCy9DhEW~BJeMV3BM}rK=eIAe at H`yICm#Tw2a{>@rO5nRR&sy*`xBaXU3xBsWM;6
z%K_*M(zxoKtt~B?T<$-S6qVt<iu~b*x6OZ)oH^usI8zI3{6N;N=`8(uyTacT>&Xs9
zt at dpnaHuQ)_CKqrWruc&0so_y0!NK7E3x*GxNRSBRIpTTtVVfuMUqxccu%}PBJyzY
zAr(&$G$Q=cE%cTvYBhZGbAZrCwd41U0B??ot5ImKc#+zG6q3@>QlGS!Uy-{g3>Aaw
zJS(i&hfzo9iqMtg4$lyUG0Wrq+7e)2ZzRAvZx8c32zYeH`K`M=73;YuVpM4w at TsG6
zC9dheh3jo5?7<&Kw~y8>PK(Y`pBuSw>p<cu1Km%>d-w~u)ZUzWnL!GeaQ#o;G6YTL
zD-?bR2|4bPKZOs)e%ii(5?WCi-saO9m~_CoHig^I&<+;nqPJ3BtYfIl at n1H~u=X7m
zKHB3{Gm^NzaOwYYqfqy<4d&@eNw*o*rA7m$e6)oZxuIuIaOf7QaT0GYMEO75I{Dk&
zK`(hXH+&fAZumu3JZS@}YYAQ~UAn+3p;40e;~feQKQi0`vaw|1eh|0$^O*-Cao+s)
zK~YI7ke9=dEtdj|l_op7rZKjnE?9-unF@<*?n=rOfv*91*GQ&;hxgYS`VA%`E%>@n
zRR14Y?RwU(0i%|Rmq}@5wr$BJqPmXMRu?8*@9aLyM9^h$#Q at Unt4~nwE<F at QR5-tE
zwGNOb#0KX*4SP%Ppn}Gk6UZ*`ZFF!OYogYk)3lbjIlpHum}Khg$wxtN0-c at SygM`O
zGmI at h^N6b__)&18 at K?lrri=vM^zs&C5q2gHE*4?u>CFNk<547M<8xoG^ajzx9kn3o
ze3^+{*g8`tZdbyGy{)N+Noj!7<nlPOqM`?zl~&SX0Zk at F>E!^6kqNe6!K2(<DXu2e
z<hP?nHNbx(nFie3V|23}>6!4>zY3yHgoGMcbFnAqrxUrj5oeSZvX3*nLpFIPa;mw_
zO<WJHHd+Xn7v0eoX!PC8D5WCLSq`a;8e!&Fhj46{3W#LGJC^M*2M5Q2<4=!*I+eAz
zQ8zpYD83pcq!xD7tBbWhXr{)!<30G?vli;-R at D;qt6r#?(5sukpl-w>PVuj%8!r0J
z{sFz|I>lTW#vhY~g6;F3VczcJzHiu2#`o`kQ|;`_^>n8>I9GAEVuCb^Y{wk$J4*M3
z=TFa<9<(nPSkq#rzh)=$tUP4S84rCk!!5dGy!=b*hwKuREC`eHR~^65T{<CQ at cR}t
z+;K_RXjd2!EbP3qauaxz(qhrwlrK)2XZEbnNIu}OcJ9|=*w0vnH&Px7vfR at D1`8^J
zUB-$EURWq6A)ufmlKtcb>*>Wn0v_hFU5ub$`kO*A4a>Sn%j5CM)EX0dc=cD|D0#A2
zc0dp|;KsKm^B9}`kxOH2DB>6WA|U>JVwO3V8d#KO*(q)X)vyVfxOrs@$d~EJR;*eb
zdUkY=i=H9scwBm~uZRP at 2O5a-E+QLkoLS#3JxD?4+K4!Lo#c16s$DPScxBc#sIJV(
zT2bCZE|@aRBgX^&NC>?~J-*AGyPvs(S$c|^NNzEGN}XV&@78QEMMKd^BdNbTXqZb=
zVdgqt{ieWfdekM;P0mBJ>gC+y-Eo3larI*b at l}ZwHI{(-byRzvIffig<oRDY9FF7H
zQWW-*$hq-=_`l(JTi-d{U at I^AGt9y+R$w>=ErgN`%@D!^yedm8TCz&)Mc3}|*__1X
z9`q=AO2|cPxM`~Ft1&pPJx2`7r8%+oZ>00;6yNF{C7&V@#?Im$+C2~nT~2pgGZ883
zkV7Q%e5oMW*#&;$t=}tYzf at fEyNFpcsF}664G=O6oCP8=b7s<?QC-d5^eXv#Ux;7!
zub4-5- at iCYk!0w~A)U3<ddZq|@Out+Sk#Che8ApIk at h9LV8(N%TezUWO^Q~G_Qkje
zr1V~xUHcOF{;B})bgl3(5b}2RR at kMvfL@oW<SQ%81#r+YW-F8J64CI;j;qWl+ntIg
z+GrsybiC4~nA~tN+F~wTv=xQ%U at fw^=VJDGF`XA{d!u5Gj-(=ON4)2e_AJjm3g#q{
zgOwuIL(dt*ksHo)F%EbhK5s;~s^dIH>#$3T3sHlL%lOm*Cv0@|?Ci{4$!uzZApTzr
zXe^Q+1x4Q_`So`xv4t*`BA<lD+aGTyfBwe*M-bxJ8p{l|;g<Ru%Cc<T=+T%oCQkEY
zyoakhm{VkZ)mx;y!OY9_J?g?rAf^yk(bj;@Sl*0x?Lc&4;FDpR7nKH}>Qkli83b{D
zKyE?uDJhI62CGQVoWYOrhWr4g)rFsbjrYr&ZSt+9s8CNxg;Nl`QwZ<#lfRAoQilq)
zdc9w?m!l;EuAvo|`=#!`V<=AlP41WX+Q^Z6b!0-5gs*o;SR{i?kh=7RcuvP>RP6U+
zTG&5zCNMFx@)g{7F)w?DXS<(xt?%ahQ+C{sikQ|M({aUM30leHpr^i}U0xN;D!~z)
z4*BV1xVo0H(#<~W+Nsy4_##lW{&yR3$DwJA_QO^D$D->U at k`u;yGp;K9h}nDV_P%W
z^+ik7YC7L~=w3|}3Pu2i#dH$Xota at lBxu-WDJVP%vUmbQNKjT)t~J0sLSbMQPcN(Z
z)6y8rKvAxkYoZ&9wV*v<FVafytJ9mH92l}Fa!<E6`<_JgdAMWdgaM{(7<SO>k19qB
zmTbzA)J+az+rQ`BUejXvUcix(7JYmHClX^<JJCihuOBl6e1DYDZjVmUqo7^ExcK%F
zj=tnEOJQdf?~a<W2y`GE4YRqBFdr)}!Bk$9^-atA%SJyZLKd0s9Q~(#jOL9fR!lRS
zN~kgQ_<Z7o)a>$PO0vZ)zdtH%oFObbA{DI&DsT5)TAOa|{H>g&7;eol95jwfxIQN1
z8cPTyi`EV&6 at JCj<ViVn+xVv-McBDX*Z4GJP)GO;6z$4ACcJ-)ILmE0x-6kYZr!`2
z(h){fSamJg<#gP$<pdl{7)AGfFphh at O%ZQv5%=Aq{~aCP(iygZ%u1L>vHYGFk=eVa
z at Lv&D&K}<d(`^jx-a&S`(06YFn(%F*=qO~0(d0OqCWVhFUrDV`h#3Z#`_7&3J#<(4
zZmkws+ at p=TOs|Roz(Dt{*N8=M__xO}bZMHbMO_)r-ap}<Np%KuZ{r=x(Fx9*I!(!c
zN1nqc+_A<?XV4TN-8za3I;+i3gRtAD;yksDV>G&-jg7;LzN1cVDR9Xu`sAkyqP&-i
zoSe1 at bJ-cR%TB7$E;42G#-LQz;>=rFPK=n=Qf!-!lpavF8S5+mgjL`1opvj8xav(p
zH0NO(X$PHA;#(dHc-wc(W|B1ZJS;v63{+h7ww(j%I3nOBg!d;qOZn7*6-CY{vi8>#
z<@ZxT+a(j#9+)%?3sIB=&9LlpyxnJ9C`92$-+jdFpVJCG3rgy0Ey2i9fLQT3ag#?D
zT=w!ntfIO*t-Kf{;#71$XxUFnct7PeqhAw8QBb%1-QuFOw|FwwaA&-9vFGPLdrXRq
zZr~%fDcnz;bc(|Ad9h{dGbcMf+|f1uj<0**;k9^c at cW}8Y~9uFcz-Tpq}jhMWkSAH
zNk9*vs_Kuj$D>8zoewrw&=R75JYZ at t!Ft8TovwCy$mrbbnzw{EPFUF6Z`Acm^c>N(
z(h)ZOLMl43<IsfHbi&;rMJO%uXVxSUx|@O-D^1;Z-1!}Nyohixo>17+0u1JEot(##
zHPh at DL;LK16o4efJ-LvBUVcUAJp5t==nNic(f?Y7Y3ZV9o_+AtWTSbRRCTio!B>_P
zK!K|Sm;XVwkpcc=+HY&O9wrdLgzZoHS}!z&$O`6F$Ex?%p-z`5t=gHY$~+M}D at nHM
z;qmQdp0kbyrfwY-<Lxk^y#7a-0<MX*p74m^7lF}-e}5s6gXPN!&p9~?%bgp~Px6)b
z?g*`iA0 at 74-uNaN2Rs#d)5y|Jf#Q%A{HBh!;Wr2(xFc%M?v`}9LeU!JCdc2CBTBC&
z_V4*3f%kpn(d-EkH;sm{?9hwwt20?DgG`l at U0H*BA2NIo!LM|^(7~-Ad%;;JKd2cs
zMU(LB5x*E^!jf?t-(k((4{=tvv*XA}EEL9cuEd6TEu!V{LmcvF32GmR+ApRD+<L-?
zCwCy5)e|vjW}-=|p9(U3Kb)X{#9q63x_^&W&;akF>r5GcqwIk!gY6APf;iaT;G9^M
z`GnFuEkxMc(!!rHB^n`0N|}J0p9^fzVR6TAFon`>L6^WV?or-Qvk)HI#<36H#v_N<
zZ-VTMj&897h?ugqn3JkjeWX3ESm0cpq%X~T4ni9co(-mng4$-0Ze;TX(KW_10dAK+
zbB_p53)V)2Cu$z=lt&yplwvPf8e38+?gTn9l8MT`8-h|bL$URz29HbkHp}yMFLnqw
zM|52A^22NaqxAEn1N>2xJcgCj(^hx%DqB{UyXy;Nuyz2--hyCvf0S7y>#QO*cE+J@
z6SbybaLJZ9cK&>VsNYy$avXsS#?&sxFmF^+IO}Sw=?@HttPr2Qih&0cV+IBM=MWY`
z2swEaT4O@|1O~}l&uV`90>9<H%Ob-3gh6-Wh at iA8OKMQxqCWHG8Ef-E*Wx3eXmceE
zxQzEZIvS!x<ThhH3mwfj!D!nx at JDFRvdH_CXP3}Y?Z{yKMp5gd0}gCz?6iG)0Mo8|
z!y6N1iL!X%g$N<ntWswellr~GXY0Pa#8&4*`r3ijf*Wpdv^M8MHztW)#A+IqfN;Hf
zC at +!Iea>{eCLw|*6;epcpNtjKZoXkkX*H>|L#On at T&{?u+d+~t|IVVcZ`_jOhlgGb
zy;wpl69$|s%&8?xkJw*Ew$MglTKKar#`wirqt7!dY%ZE^e)*>sK~~0tMl{f#?wqT?
zDlLR-yQ0 at e3F0)XXO;sM3?F$adJz$L*JA;+U(v<s4rqh+wshV6pQ#Z*BwDJOcu$~N
z at J&1Y|NaR5Ea{^g{;n~gDqa)e|N2KVm09sn>c-%pw}|h3W(jr1?&P!SvSmTRoRQ}|
zr7RwFv at OeX@sRw5FipO;h)Vx8{mTjb7jQm{?wntCIW at 1v1<Kgo4D`|Z5v*<#N+<lj
zAwcMiqqN_L#$W1*ggzh6V4>RYqtT3>S22bcRuC%^7jVPY3rlq`5e<cm`=K`p(>f1-
z`DBGpS;vgY<YtBU15T+o?vD+hu|x0~TS(OJFFBs=UxvN*FH5IR_On0Vaq_U+iTY at w
zvQ5cmtD!$)I{QuMN6&0HT7-+NBK8w0N_&e7$DQjyM7`@uwD#Q)WCBh*A;c7hHZ4&2
zMY)Ewyu7Qpoo?%sqlphR%jKg{`vKlp-{Zy0#D_-o7pDF+3#X|2OZYi{KNl@&u!Q<i
zG=Ey|ycS<9D(A<iFE^>^dM<=+2=_o2sT1j$%IhpjbPfIvr^f&Gx6!6Y@@VNrU|3*-
zFS1_v at 5B-+-NFrp9#2I#^@;hww+7d)kdznJa{9QRL>mw~slB_gS(65Df*G9qixN99
zoE_1#w(D7~*|EsqWonlhpi_LyjFrsy!7Z(LBWGp>$@96TK3%8d;^KKbY;bh#DuQ_W
z*W;^`*U^3`VVBgdZ_fNHrm1b~fR{KI_vb!!7Ct1`7K>rq<}0xUis9v4o7>^I+zY_?
ztHk7Kpr8T1rt=g2G<)REI-k77udx1lA0w|{5*RD~xP&s^++*1<x;-zJW6j#5Ny#yj
z;9Ye7SSUJh?22vpO=tF;-x2?HOH7nM;bMLuh1M`Mr^+9+5;|gT4g;~~6~VUgCx4YU
zZJxhBrB?IRdk2E|r(4Ut^bY~F`?2joGLkKrPk6Kkn$!a#Z`$vqxDF*AU1w_}CZ*oa
z9hFU6p^06!4!a*)8kT*K30pbe?`K{&ZQcHD&w7j=W+h}R`UlxO;AYQ?6bN6Zzk?bo
z#pd7eFZmcMAgx7gmXvtZ5sg=6OzH!qC`cSlAlOY(87z7D?^t`f?vl+f%R~4l!Q at wV
z2gMp<46s}8Z3j+2tLq&DJ>%^$dF^z!Or7eB-fLOvD-q*?`yd_<|C)&p#qxLbuv?dL
z>8eGCA7@^m53PjXwc9oyV|RW)9r><7d3lkZlYZdOaUR^|xn}zF{9DOCEglY&DcAw`
zfD-it)qsTnGpU at 3|Lxqv8BcM;UxhY1xtm4CwfL)VM%Q`6M2*Y3HwF?<l2r(}qJYTY
zbqy=Gs1_N1VHvgQs!}^FEF!{JNMxpK=K04Vi5&0I0rycH@!JdMMCQ+~&pZ|AlW|Dj
z&huu`{Q01ku6&<W5**R*J7YgJ0m)6!;D`qRM)9bJpe5W<T>7|ad^I;#4fbX|(fvl7
zu}h9U^s6mhQ>9@*4q(goM_|p&ezMw;p!u_>yP^Xr`XTr^CZze(He!osw&-Myam{Jv
zRyq%MM)b$fERpYF6f&`JLMO89BYDt%;SJ;Y82TxeR(H0Q>dO`uY;)4jeZX0!x6=H%
z``PwA!J$bpOYJTF<pg6+SVMp(ZTs~Z<LbQVH6nmup|->ku at URiwMid|41IXWKgyT!
zBj+^rm(t3zmJ`JT?SAIPMylBrFPss2!qrIcmBjX@!(NM}V-Yr#k8e-hfBU(1C-)?-
zuH0W)91YKUnfjmaI+SU5O=t?u%oY|hKYCyFo)ZYS3kw<E&XWnDyybb?`6SQ{_gv~o
z;dW8<9?}um_9)&-WVQCtIFvH*`1$R$s0a&myQk6D7)>I!)vZg=3;&bCOZOEiTI8G)
zb4_|EXJ7!N-E;iWkr4W~zmKXKL4#W}5pll)4cfj4Yg{D_j2<^{q|(KhvDL5Q#g8dR
zFGu_Ry61WRHE)F^H4IVey*?>QI(PJm4*?hFZe<FAe|Fb*0Lo^4Yt}ykWyj)zwPZq3
zNl&EHQ~sRqE^+CRo$>`^N+)=7(2$SOdf31)+GrA^yieH^)N{*f$ZELw0t0l at ckJQ3
z#DVsLV$9N75F+WHQ355Vd3N0=6B&CFjoTR={TUB`JC1rRWTGp2?n1jv(6u{`1iIx~
z)PUEWvgl8HWK(vfqV at YLoukpkcdrhEE0_i8z8`eGp5<v2!MZ>28>HJApnDQ+u&j7z
zYcJ<K#&VoMS6vVm^atVqbrxP=A=NAom*|tdv$#X~eM5+bCS%hPSNz(8li^b0&)s<_
z<1JJ3^`9>Q<_2wg)7f~Z*&TRR$y(YA^R6smr-;K$U12J)I5UG5e3(Z%3JRJ`P>B-?
z3oMWDH-7=jkrbg7ncPpjovaZ4BjPaPn>X0wkBAl5lJ*2~{TZ24yKb<KZjZNK;FC7X
zcf7FL;U>ax`;s7PP>|hEJWjw2<qLxUnGm)baarvlB&UiH({8)XJSO9N_XN?Wo1{su
zM6S$?hlZhxp-_o<hJoszB~!V}Usr@*a(EL(h96-l?LSRRSN1iNqweF%=j+z2u0Rgy
z7hYuJLOnr-eFNWMoQP|vYgMsMxT8bb?28#AbEW16D}o>6mSnEw)YYa>A+v7*oG9cN
z6s`8MJlOfV4dzDkknwt|FZ53WIS~MfvqfF|o8RuemY}p^L#+C9Nk{h^Y!Gkbzt at J~
zFvju%4G3@&g-|>(5qf+WK1|YvUY+?d#MnBC{l3=P77y5H#fCqkWDs?G7D;}7c2)?S
zT8C`(;Hm$$_lPdT&_OOqMFjz1fo`Fna+qj4&(~l&{rXz=+Q}hNC;DE2P%6y3<L0+A
z<}>JQpF+n<Tx9-2oO8>&o|A;s86n}BwU>bpKE=t=%(F>q9BzAmFIFKPzIgAdqs9Zh
z(C=5_o`^Q5MG-74tO+3g0@{6a2*GOG;d|G8D);SRG*W<Ny3s+tyr`_e)|yx;2SKBR
zP=d4cK)Kj2OiqzHW9H$#<M#xSKT&c6&+$jDh6Gh)<?1|8Ph0M>x^6l4A1-BHt>upQ
z2pT-gOYF{Yk-f`s!FnT#_4Uf1;h)6&@K70myIK;vY`mt8RV+blj$6|J8;MKXfmXb~
zIR{BI at t4N`&k*3vQX?^WR3?iXfaB`_!kV#VFazfFYC9uIFUcdu-4o)7Pjgv2JR!<*
z(<_+mv7G}S^5fy35!Y}5;zQa-f`rZ at 6fJ(!Z~hprZc^kZoX{E$;!CjvnGGM7=ap|$
z(eSwQ4tKVxuf0)-t{9dqKd(UCFwCzLLWAx)7HAaK?0dd3My<9G+*+~dAtcK-0*$&9
zXeKqFWmpB5ZDzlQh3Vr?pM{RUHYOLS108(}4F0}5^+5HA(EIex>uS1qiOC3cFOx?1
zjn$l!=#7-&99Sc*_nU+?1;NZsDmb2d6WnjIiSegR^f2oX$^RGa4-)Wq04YOptjFvg
zubvrEUL at 77+ooc+xR#z7{y9z8 at y@rMg?F5L2LAOsKg2^%Z-%C7aD5NOl8s$^_T!|L
zOOGm<CVl04K2Be~96x*H83dk-mv-#J6&Id;)V)Ttp5gWhe@@$Tpgy at 3mKP!g6UbUH
z{{9wtDGOn40KVs;+#H~y+&mj1v>mj3`D4hv at D(IpKLAD7U_SgZ at E6syGSvc0(wUiE
z`=0E_Xb*|4Mirx(`6PiTisDhtwr!936x*TxKiY$x#_~6#HDa~?zLxvd%B#tIp7HRu
zRxmNv_dObAI~_ObL>N)g*z?jJUDsh*Rz=`pEZ65zL;~&<C7BE`I??Zz>nAEB6P-Oi
zF=eb-4!VX|&p#B%pQ<F5l8FutP#%+8?pYkWQ6b)Q*{tR;&Ll at hg0RVR7^cH`=HYCd
zC>KE(qEsxPx3?Ez6rrUdi}h<);@(G|!t<}}z?v0Hj=F~L`*``)t!Qd&L`zE(5?Z+*
zwzq%aDElznAb_#TF;E^E9lf>>X=u>H2+^8F2v^KQ;QKI41IgBUAc%m#gOW)=sY^js
z6lnDs^q#d0*7ki+bq)GJ38)fO8tp-zl4ds1Xm%bDtI3&Bl=68kRBA?}CFx(wvgEi~
zNs^AEapyJE9C(_h8IM)3l?de1^dPzykCaShP{Ey;YR(=xFyx%o$|IV%Bs!J6v}!8r
z$)Ox#$}(|TsufId$Az3fk}00mlJ-Q>RC7otbI*yu-F7^LL5QSf;d39n0XJQJDY_2#
z4S68u=B+#N;8QQ)g7s_RdTy-yC)$w_KkxZIl-?Z4v_KXB01a(PL_t(cDCOfL+8PjA
z2Es6eq3US=;)mepBB=ZOp#48LBg`br(_a<9Y0JXbRhR%2RgEXhPSkoO%^adW%<<S!
zorKu3tavOM85?q9eBYPcmL%yo8A0w`P!F4Fn$UGUE(@C|BF9E7)8d(oi2$M#1!lz(
zDV|v}3?p`8CYnc at ra{xRqnw(ln57X*$#_Oa(=-@{5oh!!5?IhX7)q9AszW0kwej<f
zmnP372d#YMg at O7^3Yw;2|DkRaOE%h?8qn6<fFL-!JW<m$oU(c)?t9{S+;#sGu&nZg
z*=#zALZN_6CS7s%-b6Z+s;WXyCCk%Ml?Y+J1h^hx>4T$LEm+_BW2lOX!1ob2Wk)Lt
zBRKte_(1?u(=oWfQ9G^EaeTg{@!4_T_mN7aY90Vk(KC}sB;xW6-}jNpWQJ5Sk|aqQ
zokLQqF`*4k02IJcrDT&?n@^yVz%P%uPbA2wg-;wDh>f=7#L#*tlSky(R2wRAym=(b
zl2}HVNF?HH)nrFU$?4`LdK1Z`ir&iOc+QMi+9>Vi*!eeAOZG<UnHlMKN6I)2ENpMZ
z6EE(7?YMaM#aD6hx$EH$jxMgoo7ScVG&j`2cFKQaC at P+PaT~h3dvN~xb$G{lXAC>w
zWVC!0`!B781#d|^lt;D!ngVRw1HZEuO4>RCMDxWX=S~dj8Yf?X|H5l at Is{;7h{6bA
zR6ZbF3_=aZFG;h5R8 at _$GvgY~OcN#y!+>R3$Ye6`JTLx|j*KKp$If6<+Lb`4s;Wq*
z)8j5FtA(fud?Lqbj_32Dvqw{SC?I25)-fNAE0$MHl)fA<pZMe=a%6N}M>?GzSJ~Zo
z96xbn?L_XK<GF7o7#qLdn~uE`we+r at vUVjJ>as{!2L9)#58%N5gG1`|D2mY1)PQ-d
zO>8d#`C<v1x9vi%<RUdmlk*a$g<$;(M5+oX3e1Cj*!#6R0OhDf#%onI4R8MJAtZkP
zIt)!mRIs64cru`?{A}|nyO$*$`~9OR3X;hrOw+6x-&CA46Gagm$ARm*C=?3teLpTa
zk-{ZO(y=k<yn&sj3#L-3<63gT`$D+BI9 at bVrr~&waur8hA5R`}r<j+OnWlN%M+S?L
zH)&fW&1C1S+Ie6rmM+HXCG!9%=<Mmi*MImkytQX9JkK564-o?2M?ROsz(5YkWCF_<
zwj)9W&-al^TDanZv+(0 at d<8dOa~T}h9apfaTIME-B1EnS{lb&sFP{S?2;o^e7Txg-
z-u$QkK`EDqj|d at v5P%!_C>Dx%?e6=b{=@Ca8WuD^05VCa at 4E=09}L+;Bz3^-ChFU#
z(&t*JVwzbxordE$&@>IM>%y|isl-}GrAd+`Y4paV8b~)y6Q*fSnRQlkXpZFw=W0Bn
z!6j3r&YJV%cr?6=j*M8MI8}I5ZM6M(2U$p(c_3#dJOiJo2mqF8;)W|O!nQZ|qiEaM
zvTY~+`8z+td8e+%;*L2;m<IAi8?V0hCc69c_~Q at Xh|^D6h5Mh}f-_D&5tp5J29__H
zk01<TJMM%z1mbnVFhp}>6ZU`kMwlD^H;m9kXc?II_4}~zx!0gvu^#%e`GBs$+t-ES
z!_Pze&1N*%A?noxlu{1*KmH-26Bi&X6i4l7$)1_n>-^VReWLS=6^q4q!)3GCxSo-F
zN>aciNvh2-jP$ouHbvi0CGa_!MrSO1;tlNN$WYK_D)MPG=W|VlEQuMJWHLG7!y+bH
zhQ=dHlU2G_>;0vjoETs;9eQT?&#O7;Lp{&RrHk<QfASH0?kit|s;Jm|=rHd3?GvyJ
zeefX6u$*yG6x{XeM{(1;FTp>2{-bDVsE4Mia9p=SFN%{2hg#!E&%t|U0Km5$w4HYv
zysv%&`1F53Pg<~49rK>th2H0OqL|PSAVTE%$P_))D+cPc1oT`9+Q;4v<x^L|DHM-7
z#CWLlgybHYoqOK0thlA6mOj^t!gAmD<NA044KCX-Qn(~Znw*WyL3$7b at wBq3OydEc
zwUj~diDkS;W~z at vK9=hfc@&0W?8r=Y9!+QaBG1V<Hhi6qYaQz6VH9D>g1Pwq|NatA
zSkeL4_u&O03bu<}p at gFCzz-vMeu%xDJqRM8rJ)`G5FG16S)&O0^%p?-+9wej8kE3C
zQq|Dz>FCHsm_HC<fvsYJl0=iQLU%)GAHE#g|Mw9%N;GD0D)-Oq+T(^{!1sMvmK9G5
z9V=C2W(Yiy1H(@Qmn2Ej<ZNUyQbp6aro-CB!2pv95-4*;XE7Y_-jA^m1&EG?Eb)xY
z at fe0Mm1SwRIK5-N-bCJCo+C80ju-jj`ym?ZviO(3{4_Sd`Z}I??j`K+?1ATbuuK#4
z=d|GbGuC0<%B2W`a7Z08QB(AW`@Etkh(2^FaLO`7-~0uX$6kigGk}C2LIn`13Xrv+
zoVgV0hc8ET!+9v#4*bFM3ai~iW?&@InU<=m!uS1(p<^{UGt`tB1VMcE009Tj^Ww%F
zDR`13jl4O>Vmx>>oz9S%F2qMRbH`&c?!(V>nd%vtYR=eXg7u-C;;Ek98x90dcUv>u
z`iD9-o)3>0&;5qG=5S5oW4(X1(k1a4W4%_bx^z0oK(%Kq2OkuivT7MlK5-em!A5yS
z0ZiTazwMpRPUBV-#=jf?K?ni^EV_Uax~V!81|by$&%lP)=<D<uShC>-Sj_BE7f485
zR7}U^-vY%DVmo$l7xcI{j$=EJ5K_M1W;9I34%f%`p6{M>&w;8agke- at PlFH$dA1S9
zG0^m()@s0SzoPQ{pD_OT8x^mWlwZcmcZh%a5#ho#!iOeeEwwD~yQc5QGc)fG%d+6Q
z?z1xq%>Q->B2+4sB*ddPIFp~9o}O~V2`RuZ4Ag41QVxwSWMn6O+$M1mVd?$`{Ww8+
z|1aIKUYhxi(>O^<<bEA>Jq4>DThbd=j+>ZyN%PK8?(}9=Y09$){h8^Xm4Z8Zx$h#|
z%DR@`z*R3Bp5Dbze^xJ{omVbcj{v^pT1AfeTM;B>&dlhMlYZtn{hW%zQ|V;@2&1s{
zcTAr{DYDC6=V%JQYtX`@0 at TI|@M#4d^_E32-!%&DHGQs6|89 at 3okmAS{(d!^%@-B&
zNmf^J5cGq!a(+gPZgq8)YMGD%lu~$jcqqL<>M23vJRwOc)u4Na=wtNUeA>5Q6H-iN
z7-OV62>`|_x|d}~{ffSELe^N{_u>0~QuIT9cf&9+H8lm(G?O*Bmk^L^wOTEBo|iP)
z6=5imUU3q_FofrMT|z{}hGkhvzlUD;7Qq~bA)3u*$35kDkb6%~P9}NqMa}Sf^_dx`
z=uEEy0D4q;81|%BF6?K1$tzfp|DpnMR at 0agJ$Ksec1PbU`jkZGJ(;6kRLv}kA}FO`
znr27ph&0k9g!J!_W$moW0xgHw<-D4_XXBPyp{G&loxF=27kwft+VRvkT_kcmuH&RP
zj_k*ddfAdVH1c=bwv(vLIFC`<*)BUyqjHY)=tH_MQ`Yl3J3GV4$w^mgonaW*+uK96
zT20P8r6U`<(-}n(uCA`|`SWK4LD2EJ$Hzykt*v2ma}#kK!*LuOA0PKjKb)ADz|PJN
z78e&`+jiHz<(WiL1jljk<;$1Ecj$61OcT4iyQtM_9oH#ilX^sHls2r}Ufwg+?Nt9$
zL|?1b8cMW5>`BC|=XnT%0AUy=>x*nM>F-85S_dEz89@*rilU*7XS>~o at B8pP55DiC
z)oLX+q(66_y?P(WGnZ;+W!J~FA7RSHZf|dsRI_xbRCa7GFE2Urg!HjnrdI>ZTLeeF
zXb);qN>4C($gc6l#YJHyAQ`7|jLKw<Q`s?+`S|AMrf^b!&$gtLLKH<KU8BTN0|3``
z(P%VspVh*`0=BlcGNTcm=OvN6GU;A%9AkZbJ at en^=jTzc*8x05?6$YJdtOf*N!N7~
z0i7kHB+9U{v5|W%+qO}!*E0oK79z45jRri=dlPnS7zRw!#MRYRsdG?EOH26n?OR8r
zWS9{MeQundp2p<lWU~G^j+0ydSdJ1nj?+<1v!8eGxdKd at 9Dn%mArUx^<FF{eJ3}JV
zvJoTaJ?G};O0AEHKtDJ*i1+vRaeaM_AP6|Jgb+dqA%u`uC5~gv&CQigySHr{M at L66
z^VCupMgXXg2_b|KLI@$xMZvPnp;Xz-yyD&cJ<iX+qVBp3_Ypz}A%qY at o-bvT!tCrU
zepsntrdl1Yn2DkY=U at MVdw>7G$WJGP5JCtcgp8K^e}g5fAAcHXgr?FhX4+`nH&9^}
z2|@@Vgb+f=08mPy(P#|3VqTY+F-;RQGgUk?y^Ih-2qA<JG63Q at Ms=n- at N+X}x0o?d
zTmByH^EO=fj%Q{FA%qY at 2qDi#DTUdY8Pt}Shc9LTpjxfs=Z_x|MiGmd5kd$dgb+er
zpk at Hee8p;Jz*D-}Fm6Z)A%qY at 2q6O%GnQp>GzcMt5JCtcuTC7ts8lNbiy5U9EX%_D
z{5(gI5JCtcgb*?^K~omnwxN`Q83X|i4-a|JpAbR_A%qYz7AU0<1Ofg5hf=$3<6K|$
P00000NkvXXu0mjf{F7R-
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/docs/kimchi-login.png b/src/wok/plugins/kimchi/docs/kimchi-login.png
new file mode 100644
index 0000000000000000000000000000000000000000..66387fd70adebc3b20b9520974a127ea7faa52ac
GIT binary patch
literal 318041
zcmYhi1y~ee+cvy}bPCcbNGKA5OLs|&2}mO)i{#SXjdU!Hgi3>y^b*n_%I?yzgt&C~
z{=@UW&-;G|HOw(Pb061z)p=g$L_gP6CnsSd0f9i|8qZW-fIxVnAQ0|1A_Cw{-{zD6
z at Q1)sOI-zoz5Oa^FG~T=5Ia9JbOV7%X>NaTK-oDAz)3=P4INd&d16{>;Rli}0?fcE
zMt4;McV#C>N9&L7AZ1r;3wP`H9G>>>b{y&&I?vw*Q_zDz93Tx9#aCW4TkW3BChE{r
zZ0@{nyXxE4f63Mw>5p4ZBbXn6`}>jR3m_azn!C?JKOKZBJUh@*BKrJdYC(ZS<L{q&
z0!Yg+!LVvNj9aVDr)4eG#CAb`EUQw|%~N*6cvCa)SVo2t at vdxZJWICTX4<n-mCbic
zWW808X_Tj*f~_}}uwU3nprF8Ef++Zj^-wDR%Tn#E+XGhq;?$x^h~;Tjy9B0U%EFND
zVH%0RaL6PCybOH0Dl!RGzmIJ{u8hh2e?MpQ*&hvC46DKrg at 9Jm-#J;onsVL at r?)gW
z2X*X*ij?yG-vfXHNPm{&Z1d%g?{fjVLY=tyZhYWi**kCMC*OaU at t>=VY7JCcjC*=}
zCE^@Y$gftU7lPG_aZC{RSb>GMOT~S9W6Dun;4cH`%qHkzu<Px9{_A^Iu!=G%@g4Lc
z{lOwx+>@h2iq-MW0}}-?TwIW7X6=90j7c<s{&{^CtLM+uKj%svCt{afTJ!`kg0#oU
z!)%Hvu|g5{MhqT at ur^I=DbDY{4o4vi_ at NNoIDl=;&<JPSTV1*9N<`*xZ(KyA4tFD`
z89!Z6Vy4^zJ~L3$Sw~e?Z5sVGt+R_{lH4EyCn)%ipmF|p?2qt}FF59VEcA*yEjbEP
z#*lz37l at mffQg%6`uM?K4_D&yJ)_=(r?!@Z1+g3KMv=KQAYEfOCbi-7j!uhv7N5p+
zsETny3W9Yo0TGT>3Dyo{{mGo<^8%`4ND7GGM^PRV_P#>2^9ADo{PQbWqT4<7h-0!M
zi=}@YW?_dPC-OZ>zf>C~Vtt%DzEZ_LAIzE-yWioN6HijPoW#Bm!P~eM at _oxSN51Y(
zlOLLp&#aSa<MB5RBA*;QVw~gty}y-<@L^t)$dtE&AzzaAvekI^_D*l;^#t2!wGzyN
zW3o=S8BZL&K%R40d?xLIp2LL%hjA9AE_ZFYOGm%WJXTQU(l5^r^0JYKtFd5e1%wHt
z8AI5NE{GN%lV$$4-i$n(nysDA4R at f=jkbn^^IA6E$Up=Xp_}{+k1>o0a@=|6njHsh
zoI1q^VX+P(>XCN=Y*j5j5As?LFPq(pq8!%qqf3-$Qp-s=pDiqTrFd-(EOxPCP73PG
zInyf{dcN2;n0|f(zV&u#4{^~_`z{W<H0hTx##^`7qLYAbp>Cd-vdNL-K=()57yBGf
zW$&Cei?2{tNz#ONe>wZDiU_?!VJ!Z4pn{|yG%s9$x%w1kM!IArw{R+s#SH=FvAc_G
zJn=df*_!Jhr+K9wFB>FVW*V#S&w}|Fh(CMs!F-H^Dd3YCK|cdaS(v#0mS}UjFn$N+
zxb1{HUTaloP>6_vs8L|kPMS?(fpE;ljw7=5T`1#68?jG?Dds=!86WPCuZ)Iq?#Z47
zv*;A=8FwuS#a&d+6Hq`Fqx&ng_6gZLDC(mq5r+jUx9<GXV~fdAeUUs|2?*_h3ToVV
zN#wzv=icbMyom4X<Y)6R(@4eYU>(ZEi0XiAkJPGbZaJ4V78&Se)86-Y>`Lct-)fyP
z?FOBlafj9I)V#Bl%P`N1NYMror-0obE|V)yaBW%i<elkvj4wsED)ckg`kMFg#Fs}b
zrZ2Q at DR(aO$CrbTs|#xO-nSj+imx1<qtAwR1DW(5w=r~{FEm*U22Ec(8a~k83S<+4
zI9U>%qHpGzVqW9vMB<Qv+-jlM?ajw0mo?UNcSJUpMuw|<UT5S*_ncIt_2f^93?}gl
zarn40>kpK!{t*V?P-6eEqjyAToSM(Anmy9m(kxkxq4WLM*c0!$6HD?q at 4e@JUk^<q
z#m&5N)(s|M{EG~I(B1Q=#*IE4bLIF8rhZr<`B-0`STFP_d*2`4-+QC-*IE@&!Wy5o
z7h7KcT>fTU$;r8F3qTBfc|V at -TOl#R27gqWS9P4a at 0C$3<p~AQIq-fh|3|qr9*8v+
zkl64)i*Fj~M>k=qJmrtXD7>V;y1iM6aj5QdctgHCIExj!xlCY{z+SU=ze`U*2j1*!
zdHs?n?cA5{j6!RvIELJ2Wr5H;ib3OnH;2s!Lyu~0MziN4-K#Jw!GvsGb=Jc*e&?=Y
zFr5mMA9UZ|RQ3R8o^<BpC=8C=ZvF_P6(|bF?MlQCqpm}icj41^xLw`H0bRzMAfqX9
zWwh49D<Nw&RPZi{S&tR6nk=afKRm-T2*d<hPSug_wIa;opp-IUvpaK9Zh>p=ZC7XW
zXWg=iO7FbyEO?LIJtOQFF}7Rtp(?UC=*xKi<LGI#%?;5`$ED%i=@Cx_V{WWvNt|mf
zDBgT1M at tNk2Vu?`6-D=5{NeA=?^kzoYPKn4uvg>D9|H+YT|~yDM!Q4hKZXPs)Lw3!
z?KJK7uKpr*M#J7%thD&L46rVS%lT3))cvz;+gSfIAsj*Yv6Eg%Z^oeJ;60gL(CdeV
ztC=-3Ne`A&q at kv9!36k+dj5}Z#{25^!{Xmg&qvH6=EE=5GFDni=|hOlA6}I(<@Ua$
zTnM>lCIyL&m;?xpNuxr5yKK>0Y=W%u!(R};5mlJ~wnFX{NU!NeP-_J@^4my<X8LZD
zH}9t!dhIX2a~Tlt3^gQm>Nj+1#gYDaPMvr91|89q7u{0K<#n>~&KVOrZn?T8jvjqP
zG(CU$a_(Xg8`={oABJe#@o8&2{^qrnzN;u*6&yeMp!sIq!Nrf*WR>~0Orj<&A}oTa
z?$(+<IqS$j_ZQP~P~9f(-a^&uKTIpY`0SkS`?GiKq6;J0l<HBv3+=wOw&QF9Mh$#d
zrh^!n|4C@=ObH20&SH3Y!Fa;BLw2*WyoKM!41BAXd>LB)G8y|DQZFvv&^GSmb)gWZ
z at xvqWUYl9@7TE4<yJoN{s+RGoCq-4~4!!dY3k^;Q5g(NpPCstu at L2Ebj81}kzTmvJ
zQ;j%1<Q}E{nA8J1P?Sy4{x8q{@x at s(`1?Ig+ZF%aA1t8)R7Ln#S}&*^aK_r*`8!-M
zS-m9f%%}UrS9(`Go#pWqh<Ho`aI2BZ&0AN8&L^7#g(Biz5&2m9JpYgM3w|?M5^G2L
zkharHq_kwh!QgK1tZ5SoU2fEQz!nwPzLZFzuk?PGBW1zP9ikj5viJgTb0L{VDw_eD
zsPE#U<ZVa4Ly>=9D%967 at h-QeY`EY2I2nHC&0uTnb5BsF5cl7#*TGnPCO1Ki#p90C
z5P~vEib~0Z0kcMzu|ZzTkDG+Zg7LoSvYZf3Poa;fbCMi$Ho?w|7df&^xYCX0mmTB=
z*bzD7tJXfRsizrBebo!0`A%ZB>qSjV6 at 9PIzM2OCy+*=v{77-4Tnru|g?0=0$&(Pb
zaar*xwJ at rX$L|`=G1HYCVdi5wlE^l1(MG353b?TIq$<7j!bGa(17nxIdtQ6pg!?_D
zLJA0|alrYSL9;Vw2#3i{C0O*fhLy%Y0SPDwV~lgm0+<qIu)-ZKvqTHm{q_1!QJg4R
z<ww}!?Hc+>l08|HcstM#gTNCn3e|7-8G)!Lqm5&jFa(X`8GXll_BW3H;hi7?BD+WG
zVIuC_--lt0{S0<X=9ZR4-?J<#^UNB!f^&n}4vs}U&-)CD0`Cc-VqLBu98$?VgA<Wh
z(Z*5zjq5)3JENTt!&PJCI|icVx_PZi{kho{kKdMwZBLynzK!i_2|C3d^CN7-yBFlU
zM&Y+cnAnpYC<B-j$}o4q<+t5|w{4s~_B4EB at 2ub07(3h<^GKKN!?l_zO_e<7m0hHS
zeMExNV9-X3c`8l;QF-tK-rTs7*Q8`*ze$B97DF(96el0nZ~Mw!ao7b0vidB+4?~<U
zH4VSvH<(m+;{+3s3{-WK^N|%zE8f=oVu$-B6HwL&k*9E#sRrZo!<9~E28K-6$GexQ
z!`47fwKLMnrNUQykI(NST726Z59EDkF*k$7ev{jK$9Fv|k1nJ1XUD3FU9B*Whp>t3
z{hD?#R99J<=+%z9zdkO{_S%Xyz;6J~&}L42RV$L3ksB2ruFTB6s?kkp{7TnHNbWjI
z*{n!TA5SN9<PjIC^F_FA*XIpOXwu5&#JjR`7EdO+%*6p3On!IW*T~w9X$#oPZhPKQ
z!dWbBz**&N4cs^ZBV-mME7V3*DG?S<N_w|FY*!CdEkc}OpDA8P#w)<qTbln=apuqL
zD&h%Fl}UbAFSk8bojm=)&7+8)^moa*V&7O$ofg}V!vDRb!!c!@&7X}iROXS=Y7+UR
zbdOYxzNo;dx7{IM$@)QG%Dcwmu?UyJf7JMdW<8HRugDU<GuY-mAFxW44;s)jPSAQg
z_Tta at ZQaq%-o0#I3L)(w4{e+L^5;Vqm at 4%}g>lPWhv^C&(A6rhe0TO!2VtiL8BkYm
zuS)6Z@}fOFf;=-Pr*|mrk$yE|f2)2R7epsu at JYxv;sw(i{O15Tsk7=X--UntJt+*U
zY3DTFKk?)`y9iv#yX=S#WS<Q^OvKAk!!!C(XR!3c4*ajipG1w{ctEXqxrdUE at 7Q9N
zTnv{Ihpa*ZO=2v$yuwR~B{I8V4A##~Y`UIt6{x|Lh?inYhz)x3eEQ<YrcVLU5}3(u
zh5}bp(SGB--nL8J?8}5)ifwkWpbNn*HM}aCASOJCjpN;(JH6`lsIZNvljXj9xa=j8
zw&+%eQ*`<d#L6Q0igqH>d1%e4C(VJb=maUgci2vwb})Rl{Pu>CtP&R_K7VE8<v|l)
ziX(29JK;S_!1NJ^t;D>*8AdJ!WzO5^Ht^v$?euxH<8z>Ug}KS7b>&v5H;qI$7Hj(H
zaN;u+?`;t<ku&ElR)zE%!E^{_E^>H6XA^u{fIBJHAGb8T{_4Fm6zej|{Gs`90o%Vg
zXWNahXg&6!?YN;{Q3KRus1Dy(;8!lV=Q4DsTDfw4rR?;EQ0~-<Ce2XGW$+lW++zrp
zIS6I9oTsDAz|PD%k0!eytNo~({0`MKFJZe~8n4NNXC?vEw#CpeI5^mgF%+j9wV?sN
z<3wIPyw_Y6yT89bx2w#rT5HgIyXk>9ei8|I#U at WhwLV8xi>^ADT{8W+xxg&9R$Zi}
z-FB=DoRtJw<^_sc9wqy_hvpnAgba5WR23MbN)@?2KhP=O4%7lM;rBR{bs!2go`RGw
zMH!V9HVb#V_;4e}cBlS4wx1BY8?ce!kWCREXa>qIEk1OvIBv1SN_*oJrz%Yy)3GxJ
zJ?Xs~orxt2E=@^4t75%(-%jJCi0KoXkC0SJqW0Xz3nrGCacW#02Y=H6+3-cxGyk(r
zUL#(-=^@AaOu=f;E`Q**F3j#0-KK@=H$dJ9a%`e#X%&GB_Y{zD;zw9;5QS(f(hb+`
z&F==#6CfJD<opL at yzFOa^T6e__cS4!NeCFen$X|@W$tnjVQu!V#}F3>zR?L_?Cw&&
zhLNrq=IRIf(jBTLXXK>F(Rt at k7Qe@rFnCe2x at ngtn4Zy_Bdlv9R{wJGp!3|<<7Sk~
zD-z$j5_|W0-iRF&4kJ5vJ=kEmki~nLf3`nvxhEU_*ouhim>K7{Eo+5Lb<?8iE!sD&
z1k1 at SOwI9s3}LWp33=p)Eg}Kk?&j;7YKv$XTl!wp)lBp0zpGvC4}6kOmpccfV;l_z
zSA at 9LSQ)HjMa&sH-p!o;9FmGw{^js%!K^a$7IjQ-JUtQitC|`4f6 at F_`J9S9N%;TE
z86>Fr{z<i2C$4IAghS`GN4<cWmaaV|mRTBYS<B#oLlFY1!t}W0yphwOq&CWHwl$<9
z30Hc5u6~Q){zDXe&)T%)qQS at U*j<RfzC5)uH|MCc{{*D!y7Pc<VNPFO^%SYbnllje
z_xIO0&Ne!SP7M=q6XD`3f(Be_+&5p4QBr;j`|#h}&5RtuDOe<efGd};4#x+Umdt-_
zeRXX}ZTE?L5o1#yt<L6+-&$pLvW4>6 at 1qw1e0d~Kmbta+)EeI4xog_C*F!3SjuSO!
z{TEgKKWqxHOt9!YgB6*y$5z+Z*WZLCB+9eH9{T<PsEuBJptn$G_opqj4|x%zS%N#;
zczMEzhlhu3_Z80`E&c!PXY<b{LP6YJcu{@Y5ohw~jayw;q#mW&u~<I?Q#^s1nwpfW
zwahrY%0ya3Oe}10P{S)P@(wB8(o%P5IRazQ;dck at v=G<gwoznM`E{~rtGtPWNZ4Uo
z;5P;;#uP8il#>3a*r76jEtRv5({jL#?PO<<*7<*}g3?BgP-T|fjcFx_ctihTW-f;P
zY9QCZ6)x at aVo?2JA<SYi_7v^gB!i1?^ITbvUFRgC7>|e$As9dG5iABh=cC=Lbn?eb
zf8E7sn-jb}+f?}Gn}wYn!)%k&K$Xdl8VG9N>)#jNNxR?s(@hJRoZ}H)04a1y0qMN_
zNjXVIOG>~po8J6^FFm%v1FwoifFJXVBplaoF>?1Z3;YDMx93J!6EMXvCTBr6W+az0
z^FY?&)bzhQT4%p7LS>L1KP!JMay2{N1SjUZDvc1o+Gj_L!4;+}X#VLe<vC$NC2k9$
z!@5kmvh(q-T{7bs=TBttpsG!0W8UNAybb8l)FhPE0kIG%<iDA}<js~YC`%DW^<2|s
zOmZV4EpOqZk$FFB+>fbamsIi&ez+!MZxx&ZRP>IIUg!BP$Ie;g_)3=BV(g-vFRiKg
zByUk+$079<91H214M4XWnBy-83NifHYk^^LNpDuQnk{~ZYQ1*iu%36?;V)ShO=>9Q
z1l`zf>&~6cJUtsS(L-<DQ;sI2&My5j8u!2P1Sy5sfRy<9o7&^f+0W?xHtR_KvEkt;
zJ0G}Akg?}sg6;9eh!n(FOAFzrGWe;%b_CilBX_k|x+LJ)uOA5qPT&^f7>^TL;kR1!
zOc3KP;!Tk;FyR!-`DvOnNXa0&={v6^uX>oPdWY_PQy{{zB0IfW{U~#}C3-gD<d2__
z(pI=^ZQC;S=G&h=&%o1`-^Mtzjr)a^*SdetaF|HK at y;S0OcUGLJ8ANz2D<VFZWx`e
z|0eFAbYj(wUH9)XWWS8i<8S at yI?RCE8Qktm*;U;0MY4GBiexNs7+Rh#>owoe`2^@i
z$vSo;*M{m1rb?WzK$pDp+Jp>|dG!Cc+gxo~%cbw`(30H2X978K-TXBP42kVLs79V{
zuy at PCAJzW;Ub~X);Bx+V_-y6vZnxYl;bVb*Y56NT+79fUx$`X^nTxD(%N5T+JT10s
zUcYnRYEW2F!<DArQB!p<soCWtzu^}A{G0EHrTyybI|09&8Q8IDh~m%81|D-y=KRM^
z%;U`a4(@raPDa*Pz^5d(e@}@X$0hmN0kv?>ead$)t@?_WDc)xb1NiXGfe;p#{c6dn
zz(C+&o7Ej2_T>)pYASF*9Sg-<I9#h<VdbTQ_*)PutKxNtM(7A_hp~&*UKYgO`KAk3
za-`3jYi7OJqH&()k2Tj<;DSPYE*K#wM3_i3s4U+H7o<?E)7G}^0?9778moH=cmmv9
zdtk4vh41f&rH7bNzeU0l_aPp6KT|$<x-5CzA0rq&Zj8w#&$2WH8>*QyKtbe*LD&A_
zw~5bRgW70Y|C_l{?yvwjx%kzf25)Zak{=aAL?XH8d<=W_VvsG{IseB%JHj`4Qk2ZQ
z-Yi;G9ZWmQO%_vMJ<(2qSXK$AWrmxJ#Lk4L?B`@R2Z+UR(#nB7dU?yUF7*YHOVoz*
zHt!9^TYLE)b?k|%-yW%1*KXUk-`3@#Je+d$+dj-m_TIaWL-w=D*zx7fjc;C9r*<0B
z7_u-sgEl+jlkM41Td++0HQ@>Rd_#Pt;pKRjDt!mfF}?&5?tgOgelLyk7lsnrSbCxU
zzklskFpO3VtgL-oD7TsDQJ`vD&5L)2^ZL_c*cT(4usgfx?6o^yzxxwA&zhPmeFy{v
z9lHkPju1$B2a&kz#FcMm?Swxd%mswbh|X)?ld1qNK?Aai%b~J;RQ?t`hm+OU^H0rQ
z7+T+>aar2z2VQ))e&+Z1voY*KEQ-E^f|qQke`5hlh{RraE^h^cf~C&hOpg*rSS(Gd
zv-h=mADYjCf!tmygLlcxdUZ`HZiV3P*81TnkoB@}_y at 0ulyPswHaP@2-8GMCT&bH{
z?|vffJ4K~b<A4wx$(5!DDhWyR|L$4^7RF#Q0D#Yor%&KrxG^pC?Toup^-%=Oy>^2X
z)pyF5Qm5#G#T=1 at jTR1W%+pvbdlw~67b>>0?_qx~4K+S()kfj|(72295pIrH&&2z~
zy=+ojv^vJKr+t}a?rPzw7qG+3Z~g!Mknqmzwx?J5`s!ixzajBu-$g9A5rT at N(K8M`
z9RDHgR?Uzn%4IZ75FDm*C4F~kL%x}H_hPTiW$@tPTo90a+=oL-s6kQ at iDseVCV^bK
ztWrV!aPi`RU+Vh_h_OD&`0r=G6V18_6Bpx!7Nw%iZVq^z`=SUCq at Ym+f0l9qqiFGY
zXD(ef58;~Q(6e(<LYF>2a+_MB6wn9u;tG1Sq^RXWoLv=jfyE_KezNy{@iEl}j%uxW
zkC^-4*5K{S4|~_3IL4P0pwyB7)^HCAf%=g+{g~jsZ#6bhMsmH-V4V<Uor3S;;LpNA
zA2!MS_IBl?V<X7%#e#MToq0SPG$me=_&bZl(7bc*dcaTzfh>weFIy`M!(e;ofqpDy
zo#*%4&N|Kdw95Rcw8+>iwmI&R+-W<Gz=mG#V2K4gS6w;KYHB0oOBCtWhG(aNSdxyt
zaG~N!JMNu}kDb?VfMjwBlvX2VX*C?1B`EvVJ;=?;h6`ptzw6Jpji6v03#F&ezmOGK
z;-u0F%NT^oeZ!@rN+l3D`@xF;y<OtDQH*t{6t2A8JY}FGlqd}sr$kEgHBHBMXyal&
zNq(WWp?H6ZdB?6^k~wadf(G10nQR<_!ck(-Onahh=7!7W<t5wDrMUDG;7)1pq-aO~
zi;<N4Z&PM1YAK4A1{-(!$B+^P^|-M-2X$b2itQw4;AQAi#5F$lNZhRFuuL$_La)cr
zi+I7Kkzx at _g)ew?4}pF>jAg){m0){O%F-?akIGg`&GJL at 1CHyxZ2IEQeo&f(<Ol3f
z?(Z&oQL&%*9X|g>A*s<?wM=gs_<Dzpt`5F-DJR&n`ob$O|4d4gUsrnj=;zK~H{G_o
zyJkKh_M0QK!u_Pg<#~FtAwl$S`N2Z at hNLxv<tr+A|BtwxuImsniiGYa&6j3XeoEH<
z;5<>9re!{Qa=)t#-Ows~4t%de-hepoVr2=5g|1MuX1YARWkRw>v^vFj1Bw0r86eVL
z6u#t5XL^WX9~dMhb at n3=jsYF+oh)8b+1zulxL7-d8@>t}U??wJZfLre3UGo?Asfml
z;zr;hY4rs#sRj3`YIEnPp0auu`0fqo8 at Y2_3ZH>xu6!9*Uh?N{&L_|_Wb$ia8S-jx
zM5Ksk8R_F5_J5^}X1_Px+D)BaYiW5&D?R)1BAX%7vc at 5$yrnBSb}@SVACuh8277<-
z;te;QHw7d=ScE-3g1jT#74uYLyGQ?bW%2aU(rev;$biece(SO9eZH9#ZYP^(xr at G(
z>yy(C_89mQ3X0q&arLMq$l!F-fLISD=S4RE8i~UppQX&l!8M=W0}&DN{1a>olhgG6
z`uTsFbf7#RTdsEAU^<adgb5)6nuvnAo6wtKFA)1$okv<V0;Hhl57YJr<u4=xj^D~h
zos+JIiqM^;Pl}O;+3opL=4~vSVb}7V4=)$kJLt^!SP4f2iqbB%mn8)=KPuYFm4EEv
zrma%9FybK!>VkH~;gXS?2jgXA^JN;H8FiZU&(vw#5lNY0Bnz_dyd;zvxKm3a{QIMt
zVa6K)y8SPD{v;dufpQdVGEq+*ra!Cc-&_PD&;yB`A&<t*LK54q#qh;i#z(9YWh3gx
zq)4?g1YdUnK=nW4Qh#v(;$80s%A47*7yl{JjbR<=))DWd#9jnqiK_#zh0L!ncx#*%
zP1`Q#cl-QL=VNX2=Y!-gisifWuTl9+GY$)6Q(}Fx9C1qe?u+ITf$!{yf4Lh>bJ}Nr
zyhqV)Bt*29_OAM=bVu%yQ9bA;!;r6h@>@j{P25ST>=#fFB=Ahjb|t0L5A2uUvmf$%
z<MG40U;mr5rk#BMKx|fX7&ZCn9vj8UUr)(LZg_i*Itb!$GC_VspLU$`013~hJ>qt2
zLNTo-8ndbVurK}MqK4uu3G|;oTCUpa-lD|+fGtOxi`8aTN3{?RqDNWL2*+6pY+$?T
z+hP at z$hmeD+E0pt>UV_N|6UHBFJ;AuKO^ey4kgs*qkVFkreC^c0M_JB7cdNAmG&@q
zc6K(BvvPK>F&Q%c?;{`=BTE!m02B1^-Qnck@^%$~*qrRl$BK^20EEKJ>y;tX<2Tg^
z7nF6z at -6jU_`GXp{zqB*+w^?@+On6w+c=DQw?{{MdwUzy0{<5vT36pC^%ZIK`{ddZ
zhfa{*nXu^>CX=~2L*Fv4Aag%I7Q&NVN>*AE1YGVBekI#I9KCW|vIzSKeaa9IPnVrN
zVS=eTBj(R1>pjr<2~Nwn?z_6q-u&<HUg%WXWNEhwO1)u4Olt1X=YF%SCEEM^zTqp3
z8Ykfa_o-<Al8>oZt{sy$`V*5-0d4T&L&M=22w5RvJUf2D_7w|3S94&~>VLHWVsXmU
zoJs(;$eie!N=8ahL!OPayMgaZONZo2P)Q+i`NHna7_A?5MZ6%9CuD{T7x31IJSJtr
zvRd_zQd{8>{n@^cr23^Vc0XQ+3g5yMv26ZQAPs=N0VikZm(_TW!P}>>gAtrc+c(JH
z?yr=&@$U?OSX*t#*GE9%wl5s&EvO+N1%%k&Z5P!UG|z~)6<LIZ0?j&C^}Hx=j*~V`
z*tohQSlj$%O~u|1Dy1c<vBGp+YBUeRFU2*tVSt=wK`5HMn07(GCqg8mNapRV$0G96
ziC=0Ou$sNgUV`nGi)XcpzH<N4<4f&@U2BpMXB1#+hpWl4ezCY3@|+Ph at i-N%dhKSh
zlNUD%<P1Ey-#}d|MB=TUg(z#lq5cq$Yy56HxfKHoOYhGu6e!4gINhQz=3XRNRK}+k
zig{y~9kG$;OCi*@r}RTbM6u-+iBrf6AHJSRwvoP-!XZ-tIy^VLRBRG>WK3&}*mm}d
z>9hPxdsk@!0*3D_$BCqBmMDws5N+Aiqf3X=h6-Uk_{To&Ye&?$YWxq=GzW11xa8JO
zLzf9F5SYijmDh_yYp!0oB6MoiXO|D^CZV)iB`RP)g}Y;=vK(jTYZM}!_>GS2u2KBt
ztiL{)6i>QBh;SSifBY=fuWq8-1;bQ4>>)E-Kdg&4r8F5)1+tmv%^KEl24GcBV6NvA
zEAw2;xCQB51aXB6c(AThiwz4aL*a1ShiN+XsF{MM-S$_4o-%InYQ^7);~C%DL;fB6
zV9v*dtDaqE4Uee(ydLc7ud7HnUyrKe#6LEAEXoWjCxS4P*bz<I=u9P}7zjvujC1?@
zYquwAC3%pvvCGh`c+N_zFAx at 9<2EbQ9z5C<^*l!N`wR{2GgO=F^V5&_kt$XDc?c=@
zSj#E7qfPUdd|g!Q|Lko=;~o4SGTXCiS&3S+I)IfUn}r}0Wmp<~yLAhz>}5p{9&j?&
z?N#k&kCWh0Pw6Wu_nMU8_$}<ntIn(!F)6xI#E;%ofH?7ihIM(vojb`cn_#w4y5oJx
z3&{qBpD6{a2G2F6-#=)rg0Jv4Y|{kW)DtsJ>=BBRam_U&8|P<&zhh++jrKa3;|XM3
zin%~&d4mCbvr3OEj;HoG<s>N_px+<9Qw+xWnFtbm>W#2t(p+;Dfbqwc?M9N~%OBJ0
zov;pUB2h8Sj0LY7IP56Fa+$p>g=)o<Gbj>B0}G_bcLNfp_?sN&N&#LmC!qTHsjocf
zXX$gk&-K(r_w6C?ZT*ItH7s6Yl5|9a0e^pqA{z7K0dH$iC=B3I*HQD-exQeBcG)P{
zaLKx*efW-c=Sz!Us`=NNH&iMd54lf2&H!E(%?Q<bZ7FIUDo|q)r(@0K=>7}oC0k<;
zhKVM|?~M#XG`&$oWuKlf54cEuwWSNklguK|r at V_II%VrC&49*Hh17|$M?>yYQsRRn
zEZo`H&H at H3N~{f+)oi4YuZsHPmtGwYl_rPk{FX}Zw;5tubOMVw_*FyhBWl|q+}MH9
zP3)?LDB2HB3+^*T5gjIts2!2R<8>(^rDqXSf5l at RWH>*g-Nan>(Pr5%NOY#2SH6Kq
zk(AIL`>=lYS2mihT|$I%WV*J$dI*KQ2WY9xfu;C6<|+6*wNko0ECa;yW(erth{>5V
ze4Olf9^-L58jsQ|!sV1W35|5k5 at fCg(W_?9{U3)K+HI#smFZq49iIEGBN0M*SFO93
z%RI^XcX at IJVWlXM%woE?`-+sTiE)tkWl at y<Tz#b|h(`@S9pJ)pA6K85voH_Wxz<yE
zbM338&Mk!xmQLD at 7=Yu6BA at ImO!dE}W!_(an(TUEH*L72txH~fv6A~|J-3>hSQiK5
z2Kxp7jUbnIPe!>5RQ0XIS<`$^cu<?9_naJ_*`t>5_a`%}H=gX;gvQ_K^l+UfjDb9I
z)o{SannubRm)S)wIkz;RZV-b#YVAKAQp@{xIa*4;ShIMeM+erx7<{gu4|U4yUw6KU
z(1)z*m{$iJE}xK}-vqs28dGO|A_}BpoC13$AO)N`M-{%-wD)?U%74cmbIv+IT+DYR
z6}c**>wseisv(XTHRQ9uhyNXvxmLI-w$!Y9X4q#*U0RA4&vO*i;~*Bq5mbmFawiX8
z=KR~rhPxt9g!St<Tzy`|=6-{>7f(fVfY;lnHOCkO6Qgea86mCX0`Wp-nR%Ktp?wOU
z|83rp(0w#e=HG50&?7dwCzWWkk16r!ReO)V3>Y{T1N-gqf%hTJXwLeif!B24qN&sq
zZ5?{%fNSTvWyHB(N`}syA9sDNz&G at TdrdSfu?QKpbx=oLtp5a7{t0lpRhK{H%;#Cd
zLp+XEa??n$nHL6Q#q?l(H|Skh!_xqsIOct+#h<;k%VQVI=4fxzzs_T{;OnEnRcHlZ
zPBTcW37Rs}2`K~?oy2Bo1k__%S(!zZW!5Ie9?!kDCC}~G2=Y?l!I#r0kmj*@=O+Aq
zB&1)!D<LuTyX;;AowGdA^M at H0U={{la#cHXa%LNaLgi3OdY=}2+oE8b at AxksMo25)
zE&H)vhyVkrW5%T}&E2v)@cI5?+2Fr}q2e=hTIeUg8W+~j&CPw1I&rlLgs<C9xw<2U
z2`;-M^7)QZ$mMai({&g;5-hmXA0#99?%a>o`Auxg!d$hnaoT@;C7Kj3p>YyQF8^g^
zF+(q8YLsUuOUn{&mLI9}atMza1tdIVZ|=${E%=~085Oma00tlUxi_P at H7NSX-FduU
zB|?6!|J!^&H7b>!LGIaFgxuq^X>w>AvEixQpTCHR(RsqW#@v4y;a3b#!zmgWp;{(X
z4ALyQ`%$G=`1#z97TMw7)`hR1IEL;S6B;RpuF(pAh__6CO41{CW(U0|{tWX-7^FI^
zWYLyTv};ADoyy7{-W5cQORi8T5fx-t(+(mWVD>^Cf=n=HiV^}*(F00R+E?#9T6_06
zIt4c<RR>vn*##akcZiZJzmK4%nC6T815_iE`pmt)5|)EOuemCp(%MNeo!U(<W^b3Z
z6k}SLQlao#*h>m&JznO0A9<v+#(i5ZA*%b#Q)1FcmGD(x3ogyaMM#xeOnSVZ?8BJ{
zb<5{*bq!n2b=1}D4v<xvF|Izfjy&#Jtr(9r3%K}`oOpp?T}v)C{*?EghA3 at aT{eC2
zit*?J1s6!sv`CiDFDVahlslUF1c=oh9!FN`WQdAAYI!g4piVORCUL{t4h)+Rt1QNa
z3;<nYT*5s4qG61Y>`h_VC;k?)QhSdpa~V|rbKGzGT~{l(BacV$j&Ue)WDu&)p<NH<
zCO{;m(Ms_CAdFS8p-P|aL^Qz^H-{-`_+gKjkvv~`gwlM3Ed%n+q++*}hlgJ>t+KgB
znU}s#fJ<_+^85RHZIIO(_utUT&6OXnD1J0AlO^s~35}T0*S{;&YpGGJj*w(sVl*=9
zNroxvr*6s>$4QS`ha4+pwJ$CI<a4ctG^0Eda!=z01u9k}-4KOrlnp13)?i7<POQ6)
zQBiM!8fv}GRtv6i_3QUsX1i(e6&t&0Iy1&|q_8%(?;|{$?ve at d5^rZ4b2AB(BX!cD
zThHpL5oZlhZ5uf2bOkS3G*?IHHnG`vSg?VoHnA-BV9`-=2pA?z#x(+?mS3cz8B>wX
z at hjrMy{BjOzARck>gqVV((0p&;5z-fGO4 at 7Z}sOViW?Gpu~4xsBdy^LpK>X-^-&lh
zjEdzq1JR`U1<pEL#l8+ljD>1GY}T%)h)s<|8Cgg}JG(5+<{BsEJuaGQou&1v<)sTk
z08h`AFNH_MaO0=)iOYo{n`vCK^qwz&(>JogLe!=?7v(zeYr(e((mUZ$4OwBChL7 at S
z{^N`+>BC%`r!-Dx2?8M|mV%7py#9##`Go%b=&kNEz3gwcQZTW|r#iT_uScus!S=4B
zS^Yd?`%x(hp2Iw`4FW>2&n;5X<bnQ8n9LD1kJewv&!d0Tvq#-4_NV$vfy_?}gRfzK
zc37B#2kL;7)oC~-cGkhJHo#?VBcl<im)usARcg=5d`~X3FDk)n=KeniMr(%YNMUt$
z)nM8s0-P&JL7s at y;&tsFxAr$t+K9qkR%MHBTu20EJ^=`a?^wSo-6e=BZY(<#Z6*l{
z9A|qj+$H90UJz5Ksuaz_iJy{^l5}B6 at j!Q6C<2+Rn_)e`^-zXkKy9ZM{wVz?@jJhs
z$8 at n4e+WbrQ_VI~7&_U~Cuok&WP-mgLe9)H^cL!Y-qwGpISHEV0yzuKiPXtO=qFlm
z)oWSadX0|yZpd3nW~FBjVSHIyw9JM>E at CxFu{b{=E6HxY)?9B|mrwiY)o%>_ at O&kZ
z+?#c(Eh?QT?$JNhbl^H0*<q>a$IJ_d_bFkfh}v?${?AY460uWGU_-=NK<#ZE9a1wM
zC_;|B!frU%OV0SiO|NWPmh`^7QmQqG%gEYira5+Xjc#vvsf5}WCa1xJ5UIWiS!Z at 8
z#2}>`XmrY=yC{1E3mWX<EUevfce~u$rxU3rYU)Du_!}?TP7=~Zn%byJ(Uy?+AR0SI
zOTLn2&y4SWMSb?yd?kA_lt6R+hqz^4py9=rFn_1Bu~bSb5P&~M{6dC&>A5%0(aEi<
z18^6X)Zw+~^=zIO?*ucH1@&3y)_T$0tnX9DM05zVc&`|~JJ1vQrmDTN;lkL~rys>l
zMU~c4vtOB_xCiZiAypo1oTS7XtBF&>_#9oBm|NVf*ueTTR((9oFbUaCKGxVR43%39
z;t{iceO`u6w%B7*W=TqJ9bE1VvE6W;JZQxtq)r7l1*tM<oIrbP$F`fq5uOk6<HKr#
zvyZFyHLhiB?!p9a^s;3hR?!CJVBG|2H4ey&4<c<I!UQ at je&;E at hY#F2ohpOa_${he
zz9D57gbPc#CmXsWEWMSc#PsWiYGi2W1SIm}+qr(|H(?5J$i<)FluT&TJXKq6bb3e>
z^894I3HE-bG2Uen9xxwNidQ-xw2;6ZJ;}ZBjMt$G&-2K3G&_89Qh#ga`=hIF*>Pnm
ze1LinFSTc2W`-k?3}o=Gn0t?E0<kxHi$_I2bbl$vv_d-eeFgx{_b5ypy;+t|@$Kkm
zHuR<g4u`XHD##i9I=V6h-#6YsI(~dDk5UOYMIT+cD)}|FP*|E8z8Nqttx2->b%9)z
z7`}xhID!q`SP%Z4A4<$lb at TA6^XQQLdJL;*$(tH2&6xWt06AFwc?1KRV~^&8v5Rh=
z#|TlalFoq2{q{NySYlnx;J=ZL(a_wF;Ooq9=+Cy6B0-x!spal=aPAfsW28QOH`?I&
z6sRE**5?`F+U^h#YI$xghxCeyL%_j0H0A)7?m=yI<vCd;>vHV9W4_m6&ly&*j9m8J
zmlM6R@&23U2`dd|&YSk?puC at J5H(+l_A&i=T*u4H>(YIP-W*WT17TbU89g+Tlqt*g
zVB+E70ca(;zpV)=dUA~4-d6VmD!~1vP)d)V2JgXscWF>jh+?I0mR|Z~?5??7R%D73
zF_3Ub*xr3gdEBm+jl5W3oDIcH7n)W_h8q6X=zsld at E4^@`XiM;i}EaxRo{%K1@?$F
z7n(k`Dy7u#8+||<M<N~jbUg)WmrciS`<EA1E+^_r?sMbG#Oy5>V at dPcOg=&9SMx8i
z$B5>C;y`mJJ&pXSKM_z9o%~3pHVGlpA;A_4N&d`Yh*YWEAGixEzv4{NdDWSiHN;aX
zWm_%V*$WjA0`8Sf3`xEyT-$U=TgR?ii_YJc7?%LIPJj4ERG4psTCs9EAt<}~-A21j
zuMg5C8~RZOzu)QkZ#L2R!e#K%9l2~cR6>V$&TyZ-aMG^p^g2Cf<W%{bHq!XpA0uqK
zewV$aLb33+#@`d}qb@~9*Sm^TVfjMowh7tz=v4~i<UZy1fbvF|tirIK01(<n^X7p{
zX#ae;cX_f6 at 9@8@@xMGtxa)OAi01LI)%ohqmB**@hlHLmMW&lq_GjLP#c=v#BoOg3
z<I3NSwkHt%_9^JqxAv?HYhl&p-7>5Yuex`0p-g?HZ at xi|$9vRd9?({^6N6o=Lgx^i
z(K<8DN!6!AJYO?3=lCsYnOg|jf2!?x33!wxO824B55LNFdPz)Bf-SFa1R%Y(g7G at 9
zDD&Pvf;A|SxU_C<TBd;CZdh=cjrZ_;8P}!*A22PF!piYltkTHGp+8#_)~vZUe*VN5
zyy*NS2DZl-FfpUV<BSFptik%kyOG1#Xv}$9hEC4noYP{>JMh&4>p-vt1MA`-mAt}K
zL(MoD*2$9pJ6|O`C5?-H7Jo#SF=5Jk+<FmaolZv0;bwPjvLtGyo~U>MRtM_I=d5gs
ziiBU8RFhDd6^Y%y_?SjiXzrvArBM)nB1_#!`e`Ir)rmGz5M-6!$Z=C3>b~{lj}0Ll
zfF=xoy2^xf{7|ZhBi%Y&9=H0hO*W614(TJIs5ZYvO634cSHX=TWjo^o-VgZaRk at M*
z=ezxjiInTd7z7-^D+?=kWBV3OY`Dxaw6<L0?dFcl6NWUd73xj|KMm)uZ<<gcC_ldi
z>!Tk=>%3B5;|A+zL%r{&9)E8?fksI$%lv};`gb at CY27rLcmykV`6C2&ZQ9K0RZHdS
zT`PeOtK|(J)+`_D18LgZzWu08A{)hh?~0mcK^0uLrMsh-8mTj9%nIFA4*_~i9_d5<
zgD+xW*I&>)s6f2V43kh@^gHxD7#AA5x_O?4z;34L$one;*zbdl-}n=2Q8=qj$M9CU
zW_nTR=hU7C?Y}nEjRWTY at PE54wX!`^4VB#~c%N!sB-+N8 at i!L3#B#%t9l>L5{^m})
zjd|7 at +?Mv~fbvT#q#m*HkV24g3q=u6?(nd#?D4C(xH$9w(b<tH8~f4Jy&t>_2(&8S
zHT4LSkx@`sZvHB{rA7Hl4BEUz+)V}^Rkz^|xB!5ZfPmmutp}(|Zn;}OKN+%iqx5?p
zh;*iUfiY#z{F8C at mC!ipijG~Yo2zq!8gm?$f$p(fX=;2NV+6TpXIXxLlrf_3=K4|^
z96i4t{PSE<|G^1GMx#Wfj76%AEWeB7W5lwZEzO^&5{Wh at sS(H02#Z$K`$4?uM;S9h
z;PzE1mV}(PfVwO}S?uIbwJnDdBtxwmlnEx#lIKlwFv1NsoUZ*i++J3 at 31!6q_MAS;
z8nWRzlh;snyvXA6lR)kv2o;4(no2l7OrK#lq?IW+tJXz36^H8-;&A(ANmZK65ss;1
zln-=5H(JVB<%9KYX?;gz6((lRqnW0fsTe!I0N{y^XF`mekTPMJ17}1M&mc%7E at 32O
z+q)dhgj^xB^n<j)C!di#8rIMQ#Mx))#DSH**joE3o~^kS(cfMNCZeDm_g at +e?Cb*x
ztkUM$Jiv=px-$DJKsWeN at avz4x{_<OGDj222CeS=>4GLP(b2?YWMt-p$q&44&Nl#w
zcb>43^(+`*u_Y=DYH`!83sI0F0|7wOV|jgXT;s?LFfkpwaA7iIzx_T2Ha3cqVBQ>O
zTtJY&L&3UsoAZIKwuC?g;u`wG36orC_&x?%dmKb7<#kZ#`@jEn0sb5hYo4%wg>1=(
z6s_vJKvq-svwrgMSB&WS{z`65StV(&iPj9!wxoFwN{vz(WK7_OC6FZXL+XGScmX-X
zto?gkbo`Jt<<a%pHsKQhi`ecs*Cds&T-(q<g<ZK(t4Rr}l~w@!y2>v%<+qPi^G5cL
z{&9i4Z?Rzmdn3*^ZKk%R($jQaSyyjbPJP3=NuZ8qv63u6m6a5I at PzB8z>?8SvVlo5
zQwNWx0n{!N(#03bB*>FXFmz#>s?ADsArTXPpCmXu^m}OZgOfVDYX++VoW58z9i0G6
z#FuknO&)>D=+G0zI0qgggYwQa`1HzB)vJdV_EK^RZz>FeYimVhPUqap-+W_*h1%3J
z?x>xQy_zFt_ndR_0xH36$-SMdZ{&Ki2?9JbLqzbce#`e{OA#1GgwvZw{rUE`7$~WC
zXn~PS*zG?k$VxXMJDF#b at rQntaDR>0z9pdJC#00w0|9Z?;`(5HJU@{}R{}>*_L!E4
zll50!xzX|y=Gs?~oH<37EBmy^zchV at vY{^K2hVc74(3OjqkTUerm}BE=qwzB+OO$e
z4yw76mBQk$Msx^ae6oRenQK`-7~!=7Np1YqD_zqjNKuiAJ!Carmkq43mT}q5^F<8$
zyLo816p_4sA68yB4{YktAr)dSpnlV{#WPDMH7}5-E;?nBTlG`QkjFq;&u&C~CLs(6
zEOA(y!<BpergeP2J*2lqYRE|!DEy7Sttb}3MPaR$Q-O}cvui+#wEC5;&c=l7-62bs
zQXz=xj6;pOL4s6Jn<`#Ol!Wgen}AKIh<Rc=bJcc_n{>)r-QT*t?w(xl8&*##)zoOx
z(TSx?w)9kEmLv7an)aU^WGn5e_UCUZjqda_L_|i`+D#S-yWTC)pob=35uzF$nNM~X
z7xjm{-Q8*BFHz$)ZX3G5Gyu at SwH^J^YF<s&0>+C<rCR9%!5iKNO&?i_I4yb!?2b*A
zU_2chkeLR4<D5Ld1C87K*d21mYdy;rcpp)k;8}K~ghs~We=PitX at BU<gf?{d at A|nQ
ztjiw#Q{mDWA7?-M9KdOKe5Kz)0r0-RMS0(tYYss_p;Xegchcj}=BLCkfZ;I%xUdSJ
z8z7K0GIDtlh53+Q?g&HV-pih5sJ4vBSkcCKkzwN0;lQZ)RG*q@*+E?rB_%Cv2c>fS
z0*Erniu(Yln$fy>4j^refe at r9`!~;8x6L35;ERe$46pLDx_Cyho9Q~~#^YS0JcHt^
zlD=1fCa-dzc}a)M`{lDKF&d0DJxTbOaMCV(pE$}U=t+cYOGxks;?(cVy5Q^@R_V6x
z8b7zo!?hT`m8x94jo0Hn!ZbK1Px+bTl#5XyJVlgw=1T(2HD&3k@`nm5?a^Hh-;J6X
zCDu}30+yBX`Kw|Nyp>7L{6SY+Tj5r}$+&(;G9k3x_cTI2&)TrCSWHX|f3^{r1m3C+
zA at i+IuM*lcVFnQik?bvayO(kRT at 1`$87P7z-PYaza`Z*%(q+X;AdBzTC4Y!kw@>Wj
z9#Sg&RGyML at H#a at Ow(5&fjJ=Nr*gf9&rMqkg@%4O0PQ<E3<ORps<+d0ays5rttW@;
z7{z<<w^|!ULjYp8I9TV^%D%Q$iic)qndeI;W|92bci@%g;T|4`aZ>$yw(kkYLp)k+
z&zNAJ&-qB1lN^~~&3W`L4t`9qHpwUUJ~yUFm2-J-l*-z~ss-0+)}}4nPxrdPAN{r#
zDYV-_1KiX<{FpWw`Q8wnD8}qkr8}Io$z$upQ?ne6bv140yeZEvRh(+z=Y6f=0}fyU
z1bk|s9tO?6yV{RI<hUU2k;5e&_8*huLnX}cDH5Tsn|&smw@|8h5L5RYC+VdLtGS|J
zCA$?FOxy{WOmvm%z?^%Cd6#a>Oe+-AqiN~4 at pDm2Mt?~@v-~j~JhJVL1Qu&~uGqo6
z(HUy|C}&s2`{t9ucP>rdL2O28sP@!htklnDV?slK79d1RAv}r=cb@{Vl0cNzo5KaN
zqI3Xolm-WFW<CK)<QXm8wVMwRg^TCPQ-eIZ<MJjD0DZOBC9RQpBY&R90sN&?l`;#g
z87go~h2$AWw%vB84=FvQ4iyg8f38|g#pjv5r+NBTeU0c5c=E~O<_Ml-GNg4s&<6LG
zA32KENp)h#;2J5G2O4O;EXGBFDDpBdX!Yk`aej9jNaR?Co<F2jAPU{k|63ZY)=p8~
zo<yzp6 at U{O4^E^Sd_ezb(0hc840uEg1YbjI{HJd^K6A12XkvH~1sgwRZ1er;4%bKF
zIg)O|wqrTZrFb%I+*x?9U|933_F^%Naa})QC<_}cGifwTLJlc24(n0ds^!Xi2C#;@
zlZr9BfW=aws5*)l(*TI6i({7L7RoqEg(iCsQS!vY0_;?LtyA6vJg1OWA1uD;Q;P$u
z)<#>>m&xi{ahWALG(O0aD+^yOgT;GY8(5{hYP at u=OR84aP)$avs6KAx_smYyNw1st
zM*a^;sZsL98r+^<Dwhl?Vmga)gT7*WHX}7XUN`>))&Lctgb82_*ueJIKk93e-0Us}
z*Pm7IN2ZKU-r^-VLZr4NwhF^KsiiaLy}x(gv(%dZ*{d&45m20>ZcFe`I>o%O;tX at V
zKNNS|6CRNYw7!xunXfFX4fsO7(_HeG*nyci9=CFAvq{F?;ZPwBjx~~(j8yym>0fJt
zX34Llt-wY9Q^hGU03O+BM#a at H?+Q8K6ic-ovI~4DhVObVw0SRk(!hdU%i^$ImPkp>
z_4^pxshm;)h>Bqz;D<sSh6C{oa<t;XEBu9j4L(1(yUy>)^jh7Yr#^`*Sf9M4u1+JR
zMFpTZt*yDtHX!eTF==woFLh>S?~q+y7 at vlf5Tsdju~O!rbHaZ{2sT4f(>GOy$e-b~
z2dUEWAB1_O2t;$^kqjbL!A^AEuYM1D$)i?tzx_xeR(~BvlST|6`VS{r8S#H>*c>3g
zrq3$SrSHJ)75m<()qU9Eh5WURs7VKB^?RNKVjcHJv~Fba5v0-4Gp_=Je^^0$2E0OG
zL at s*z^r at YV<W at -!T;*WwWrZSpiQxt!dfIjU%VtmGJ8J5DhKUN?ujvGjoeM<RX at K_w
zHl`}naVilQWU~v``dBXWiNi7^`CmmW1Rx3O*NpZA)dc^m1&}u+-1KGxYFZ*7*<R_T
z(F=2&E&uZYct3_L at TmM{51+r|Z}W6m(k<hADwbPZ at i=|g#3tiSzWmp>n#NViLQntR
zx}$nKJLJ7=AQP+t%|ps;xSsrZBk_Z_ml(jSji}cygMt3+oJWYcg*~c#c&vvfQ8b at B
z at n3|_FXNo>crRd#x3+_!8i?rZcsJTQqBdPoR;z&_bmd0w8Amp^HONpnFah(fe`)bK
z!=D=ZZ4CjI?(^E#acn%x^0s<nZU8XtF*HQ2x~vx?qwfA~yU}BUNp!Zn0~=niS3p)S
zwpfW5g&pM%WQ52PUOh}pkd5UOynmpkwj~M|zwi3%={VjbIi9;KeS|GJI!yyt2 at hXb
ze=0)wg=60bpnP6kt9qvzn`Y^EO&QzW3;N^!yx+N|nW&xwUsbjX$EaINh#jASJoof7
zMVUr6REfxAdnR11ICyP1!)jwJ7un)wYal53H7w6qErAkTOTwsUzH%C{)P?h0v(^Qz
z2Cyosv2 at G-zE$_%>Q at BlM5Lr*0BC77o+q2s>geJ;RM(<e5&{qb;eaClQ~zs5O%lo&
zE43Yh#~5yOf4sq};u!l%Cmte7ZE&ZkpIm76v4cvn=F4FOU<=OEa+-KCu>O+_KJWqY
z#$=CLMMFw2&rsGbFS99&N=_mLJ&fC=k&if25Ufv~@e#FmXXRO4bh3J1Z4wma;u_A?
z$Mb<T)+!@h=a%=bN=N-{p_&?0%S(I at uFLCu3)Hlj7i>qc_~r!F+W(KH^A2b0f8V&G
zsG6l#%$lWDGd67%wX3MwBevMoUZvCswMMeT^a6){8Y#NK;vYW&XUdtJYOTm;E=
zPR at Cr`?>Ge`<-54y>7tk3!;YKA|sE2EWuip4dP&*YnH&apuGRJswC&{or-F-l%o(y
zOKbmyW3r<qa;}KB&TR{#7+<m|2uM(k>*Z&hza(`N0BQQ{rEnX?Y}H$7*KZ+x>Bmzm
z93mEN3}@yvz at S26R<gFRIeRa##jxXw)~mylJlQ37<f at kqY&^LrP6otiNq?W?{HMtN
zTay4NUx48++h#N3?*`UDLZKzg<_n=A+>6n(KP4Pomt7AQUd?#T2mB|-073&{)(%iz
zq~?GLW8NjwA at Htza?!^`X$fJMj%oCAzPJpd7)Td=SZ(lp07*%R#6)mK!s>bx36cIe
z at thK3%4<&?q7x-26-BiYMRRhjHhqBP(n`n;(_jkqpVxziDGR&+336mjOumv`+)0Mj
z1p}59Hgcb(`sIohRkCFo$GrqU+LJ$A_GN>@PB|Ek=b6g7UzgIyP>9HW8|g=Y%A2i-
zU*D1jlBEkExyhsjrWxQCn3sD2FI?jAS=CZbz6F{cHGI=Naq><Xl30aOx<mtiBn>?(
zfhbLh4Lk{<!G4vkwPgyhUg<NjV1BEkOOALFm2c-_ObZNl@{d8|ON`zVMBfE*rnwG&
zhD at Bj$_-W|`g#)TYGXQx7f%~VK(Iw9&`*Mwi|4|HM}aGz`Oq(ier at z1g0pC@+TS_F
zYVr2pe#CY|c7`fRb~CV=98+oa5D4bsdH{0;Hd+8C{{I$a09?(%sgd9He|5(yrHgRZ
z(|88p_7+>$xf#;)&4D&*j{g>L6$fi)KY;*e;Lirxi!qn|=JVH+r|&wHiQ0E-=gHJZ
zC6D}o$tCLaJof})VM-|2)YD2%ZpaM-A^yJ7nKbix6ti{9E4$&JNXPBIc%Duz`52T9
z_~0e?lCcLow$$*#D4ymDWnRNH4yJ8dAh93C^epr8f$9@}_HY#`8v=Rys>U&3E)oHq
zb~FzN at JbC#bP{Vgz^?AqbqC!D%Khh#vXWDn15dRKAo7au9!InRrg$8L{k&d^0n=Fu
z0V4R85Bk`i=J(c;puKOOIuuhJtgYC~50#?SY3{l!OUiDto<SQ<gM0xOvL*YwX(t{o
z6P%uTZL#@%PH?n=j0B<LGr2-LhAkKu?+Q*|-h=s3!JnJoUAQO&SXl96aJ$|MRvH!g
zKjMn0e!xcbHRAoR;2iTmzwevBf8 at 2(1ylR@?4{e<ss@&^5C9yWnozp{OJ*33{72TH
z-tQCW48}d1*-v=47%#o3<j-DF{Cxl0qXJk>sck8AJs-twp7ZP*@@qn7m$HO7yl}7@
zcnp1M2~HY$O65OQM_Jur at ln#==uPrzN_n(fc%k-dedfpO6(|^}-o3QxGR~r-)o^6V
ztM0#HCDuNMCk`$ScDw%z_)<Tb`vvyhYl07Sn8*7Np4YW+3!zH&Oa21$j{-D4VD|Dw
z0D5K2^YBd~3$K+G6=%rcf2e~EknPtu0M0>C!m4><O)QhsfAh*CxX6E0S0-BRAjsF8
z>U6-ff6e70Tw0**#sD$AmDEEr=~1A2PemnjmFXqu)PN2*+6`q@%0ehDAb`VV7uNxc
z%Fh<J{Uf0Eks&0XQY}XFllZws#93hx%TbxJEN4<sMWKqA)~d!T6`?*My&j*m%FsNl
z=HuXtrNyqiM}ENj`@mHH7eslPi+5PlnzoCJSB^)uoLb`9^AEe<um_Q>k+6&deyQUp
zAQN;M{M&WBS)#~)cep4OY-*#)04Tp4kuamzb%sxsXu$rmTZAB4Qve82^<6XXu;K at 1
zXNMNr+E^xa=!yl74<83-DFo0FyNJXOnfjT<qnJ(w+}std%ysprGCzQGq6}EFSt!M_
zobNTLRs*c%VbGF)htqY||J+z+aJK1>HfyfSaMv#RPMnbM`NQ$TR3Gr)_IiF}BEJN-
z_h2LXTmiLgqbqa at w!2EApwqNpk~8 at A{vIcO$?o3>5PjcEk<WiB$dGT%J~I5gcj}u9
z;ZE04<o|7CpTPK9_Q7_Fx<Q$I62FuN;nQtK_T%WhtAEPB=yUsM*UZ_sFOe0>BUa}L
zK-ULy^v-b8{S<YbHwC7?w}pYM%FvaB%;pNpavLjlepW#5tEB#jP*32ODr#wI!pTF#
zujlfBm)ccY-I)?Zwt+E8#$7lWwv(iQP);w7^8~y4ROkco-zBnAx$pQJmZKD+4`kQy
zIwH3b$%z+WyLz%w^#6DnF3pEu3hS?2kXkK^1OL%CcIgv`^Q4q7fy^)a9TBZGf{~Y;
zs&@ogSW!*)$Bk}*fu_*urxEYxVVp5{9MoTG8oid|ha#k8Y;<OAmQwcZEF#FFP-+=!
zLe*eJ^U2w#-1<32(Rja-6t_+<2NNQCa@^=IPI;c20>N+*3!v~x>bpf1q7s#Q8?E(C
zr4q3{R(t?@kTR at Zv?fG_?U~F~5supFtndI%qdIO9N^$20NB9q*v9G>s1e|v{pchC}
zq`@*wlei{hKzgnX+qqxV6N~_NlYMa9wVrGikhgAmXr;=e+<9n at r0aP!5UrQcf+HNt
z2LC9UbW_7Uz|9wON_YUjaTZ6K3XgP;XA7^pSjyk_ReB#!w-)dD?Ye;{Ye`BeOR(+>
zv8^Y?c>O~hb@@^g`Co#uYqv6H_r56N^aZ<B6Q@#$yb>_ at ZDz4Pc((5Fvw_?Z$BdKZ
z7nWwAlAzlWcaXJ>jMRE~GohIK%@3U}QDRlq&oL?uDIq}h?1;D~EdEd&DMTmH^xZ?H
zhp^GxB7Urqb&pyziBF9dRCX8x8CCx%34;M0Rwq=J93*kh>u>}esf!#PLc#b36`xK2
z0GBOc-aKA-Tl|fq-zWj|wM(8%4E}7$NJpVA&oyx at l)EflRmbaU(;BD?t4w0e74iQD
z)WiT;xs-mq>7So~=@~LgY58FH_=%Kn^REhJc=55Uww5FA(tp1gtBcPy_L&g$fyFt<
z&b$DR)}y)=JQ}RnhsN!ex%L^dI=T88vaEh=P24H-3dOI1&bICj<a3>X3>ga~P)gCx
zblu^Ea-UhhKSGamf<`@MjEq)dyM0!Plit4^4erAsh%>zp*~7I(uD#4^#PK86RZEI6
zPwlg1poz)W|30P;1QK}eYi)BuI3zfNq9QSpCs-W%93Hf=7Ng)_k8ReF`>n&jLu0mm
z;&n!ZodmcyFGm|**;ue|Fpi#FFL7{BFr-=uXmMU7sI=!Nvn2hfeD>(4G_(_ at LJfbG
zehSzPtA9O!2-gs+T876Wwj at 0H5LB-yg99inOJ*@UXr=hE5U5 at R2#Wz*4_QG^NB7l=
zO02AbNz9I{cxRv=np4$XnZ!;G+WWXNTymbM&TP{HciUG6$cD5&DJNemb~$%f8Sk96
zttyyC`hb{bnLG_x|K!?r$Y{<r(Tb_RaTrJ at UO4!txF%NpmmHNt?3NWXfSQ(f8E)s`
zFE*r8>)>xPFW^M=eO!$C_+`T(DRRY^3(<>24T;PPL;@t_e at 5yJvy`Q^(O?%{=(70Y
z-MZYzu?Kv2?=9XaUcZ+NZjZ;Bjo*7YdJkpx?_SS>z<0ZL2k<)~B1Xk~@=Em|U)tTt
zj at cG(r8$UKSQ`pNcv2IpeZNmyGaal!_qXtmLltk(p)7CCL>xD9?})G#0ekr0oU;Cc
z{-a1m6R=in#P at P)-QnjNYft*OI@@`+%DQYHPfA!@QRz(?q)2uC7~n=Ms!y!|*%{kq
zAd<4Y00D$=f4GXib}m}82cGA~!{`iXG(RF$Bt}r`I&yI$;2f at IL$HOYbQ<iVGPjeg
z3PhWS+BczIjT?k0 at k*&Tu<oGM>{>ghh-Zr9NONWeTbLMp0Q>x>3B8%WinH`Wm#(ww
zL~lP at jFti*AXiyW$KpxQ2<Bu|Y~atD?J4PTB_PvRUO%{&?IMk1+k3s*XRLgsU*GAH
zH&OoXWp8GfYQUH$p6E0IDXu^cUe}{2yinG#R}gBXXWI<&A#92x_yY at r!(UwbUjpGI
z6igMnTp|}dgzglKJZ%F07cJzdj}a!OWn~oOqn{lvJ1Nq<jVFSm4CI)fY)8U8Wb7-V
z<aGWs8y?sgc><Z05ut=Jv~r~fxF;_=vrPePj}xgpLgUrJ)wihvVW0dNC*`ONq0$YK
zd%EM#f#LXZc9IDDh~|F?uevPM1M9ElmOxkV$4Z1!AwZWk6=8yQ+UjH^LAXjFl at K;0
z<$7-6?Hhe;o-QXm654tB)*85XpTJ8V{nP^xhees+>w4*TRJv%5%W$Ov=bqfWCI3;a
z^t9HmUf<UntWAj3CyFCa%T{FtDl^!=)5$M>Ijsn{?kFV5ExYH`_O3L^JUCm0N70{!
zum<{hx8djR=ns{8+=7i9t&&``jY3fdfi?lchi#v9Up0RSqBjv$*LeBZ3vHoGb{l%=
zJGnIYEyyeIJtsHkq2K-&*vE$%rg6ljQH{0|(mh`J*P at k4@<xogE5vqC at 7F1e1~OCs
zDFwd&Aecv>z@=}UihF2}I!w<bfM{`-05<S9|FNf;j0yWGu#f2o5ZJBvI5!Q3skN8H
zbSAUXlyl3tR~iA{@Wm29H697mb}RbdcpxGZ>c2u)>Lp>Mscwv=08-O{tN<9S!2e32
z0$}hPG5lu;MXD!tOg)Deini#1?T)p|p(EEUX=snDaKOn(4Cr8A6pPkP<>unb2cuW+
zK8}h|y#6DgDdt-Pc#$|<=lg^bE;tIKZSSmby0XnFXe(@S3beX24_zzHybc27NL+Py
zd7l})EDgl5df)z4hI~(h_y;}_uG~zInwpx&?D6Y8<F=rRyaO}l(k%Za3f*+Uasm-e
zmbARN`#{t`{&T30OXY*u51=iQr@@Re1xm|9jk4r`;F{D|zfaH at nzJXPoCwH`)*zsg
zahtm~!{312_VY`8SONQBcv}-74H7S#pp|QqZxE5Zc9{{d89q)s*(l!BDL#-sb8-ZX
zQS>dJx(qNN#J7onkBok#Z2x at -4=jV&L66R^qY~;@tP%_IE<GwYJz;TM5h-hTJ(Ue6
z{vEmKyWVZknz?(`zwnzAIPyyFTENx9;>op%HduHmHiBEUS68m{1t&kN+lI~<?$M8I
zU>K8OX>jO}tsoD(mOGo<F|1sc+`nEL;1+h)%_hcar)2HAmu{<7sb1{ZUz5`4crIV7
zSN<zCaHBSGbbh(D&DnR$M5fGX+MtHRu=we8j+$1+%Xl231fHMaaGy1*VRA~>!B}zE
ze8#=z`xPcVf9iesj#DWSUT^&WO~2&Ak80X*`gkImFcAv&A>A*R*(o!5{lp^aA59B)
zd5idZVNu`3>#CaXee{LhO%qqcd?JQ>0^Dp2?$PuR;nOeJ$xt1X&?nATu8ZOI+IDN@
z_tu8O8ofqq7)%#b75nb)MioJy*qaeen(X#>Gzo&iL}Mhdn4zI|YZ$(5EL!KdSsVCq
zveMNqx&X7WAjx&_N*v+JX;ss8kTGEO6wVoW&uX-$R7>9d0T}ZB8w69gqNQrZ-)iRW
zg=J)CljIU(gb1hJJ(Cfs#5R4cUo-%}FmSR(>cj6g&XpknW~M$7=0q-J2LwKW-?(XF
zLL8p6;CZu$DrT<Q8eSR^g{U`#kl!1gFf;2J+l%t4d|+KUd(Sa6Ke>R_Cna~)v36P|
z0l!I$pB<N{_>sw4`@g^PloM}9 at I`576}kG6W!d>G7hgNxwulMnz at FcWqWBVcKG$FL
zTK5AEUR`G4tGgy1l`+rpfHMwdiYt>l>@lvocK^B&>uiZxuIIPsgx{}AHo3lV8xV=M
zA)kdV;F=vNC7=lwNW*d$`XS5-;$gPq$tL~rv{N=rG at zeO4Ad#o_6h191Yl<NA@?dv
zBXuO at TQN|mdZyJv6e&(#B9tycd>88y`$P=OL1{Ib!=v0$An>LH8=PHY480mMN#fkH
zzYjmzLr~h^Uf%wO=GcJ|UHLqJ#~d(u2W$=NN$Truc^HA}IhVm7P*!{)zTi#>6z3u{
zE^P2=t`;3dSV((*5noc6I<>-ALg?1sr9S4{sjVnHsq$6rL at e?tD>c*nu_PGh??9!N
z!>I-MkOXd-fEI|gvQ@%Tps!wom8X!D8SLE9CJAszs5<B57AJH`Tu}t2NR-#R3H5jR
znvxX)Gl+||lDBAzhDp=u4{|9#3M<AGUS$h{>zS4xfTl at sNP4X$;5Cl%RA3>LX2k<^
zb=|Y%H?|^oT92|HfQ#Ka^ubRtwzm)jC9V(HGB>L>@p6a=lzul*nbse4w0yiaUY~6V
z>GbXk_j$Wy>+1B8QV$>q7w;ci+uS1ObG1gmh8oz at v}{u0W~D5J%T2o1RR>kF;Mun0
zX8s3#Wb|PRM-sG{-K%2VI6=lULL#DM_Xl~v8dy3833tRiOB-`~y64S(0iNfqkiY+~
zTxu1b_G}(4{^h)q)#j$zI&E4lJZ8*fATidW!lzpqtbE$P=R>FP^@$H?^%ehTM`N#{
z<-FD>$8FzeCA=HI!6-0}5m200nfnc93nAt~n9x@@-1oRasD at Ot+TAR9oXbVl`9_8T
zFkA&W+<3&HJ4BzJuc-YF+}xE(7+%Rc{2@%8k)6m7te_QKi*^IUpMS57g<aouBZr43
z5%<#b6||{k-~w-`ySHxos3L2MoFYhvhwQ=Avl<U%CXwbb=8f1hsJK!xB{)+Otu-`_
ztPD{@J%s~TYd_WqUAbxHg9o0dONX%6y-c=BgxW`|Gj>xbRfOOqRHbVA at Zu27#Udpb
zaS$;uincv!@ViIZ>{xvBua=+Hsn0(knCYS_ah!?Z93d<hHwHh3kd#zV0{7UrGAR`j
z8OiFw92&l0&o4C`&>W)d$KBrAS#7A8L%l}f%6l%D7dFd2KxEPSq1G{4@<oQ=oO|bm
zHWnJ$Rl#>xZwKbIa<{l$wiq3(SiG*9ad{StMw*L%TgL;x{wY1f2nP+3a$_(%;m}~W
z|7r-HfJkW5<)8ZOXj0k((-y*Pd)tkyJ?nf&LtSq?qkUoNS(}6JgfI8XDvQ2Qls2r<
zH#G0Kmr6XguXvdJRuEbXGO}^2C17(Ax11fa57;>_*~#1|CtS73&)Pq at X3cuY?;^g_
zKIV5UUGCS+pOJ9yjqG^<iycMo`_@)RgB70%8S>9Ke+X4hZ_^tTwNhqVSrjPWJZCL3
zFqTR!DpZz at gTU3<yizp4FEefA!9L?RE%GU^SRCpxZ?TzOTvD;H^?w-X(%z}#^phbd
z7 at DL`r$7M<E_86?G^GS1+Vh`9znYH-5FE5d3SxT_OGKep>#vEbiTZ|6YZz}?@N_2W
zep%^L5cw}(Su?6|ik9Ga(nSpkwT}QXJNvl>o0kjyDf{mf0sS7a>l6hO>qU{{<`KXN
z6!c>%e>)hz#UR`9;g*!}215t|6l~}q!(fBQrW5>e&|0bsRf`cJjWU{yd<J3XC1b0D
zt0!2Pf_=%S?@z8m!Q2(*n7s|(suWn<Sb>9QsDB#)k0R!cD~Xo-*FNix2608~ch{Xq
zP_kLSRzWb92+kvf)%n$w>}`&L7GUwg at QjjiFq}bGH?|T1 at lW6oPkJtpat8&|fC4(C
zQtk#STvz2DV&3{ZR!U*|Q1O5StnTH2_^dA4&NVx*9)3xRSY*U5z6JB5$gyfG;p;tc
zJ11|oIe!(Wx7dsf(3B4{?T*@t&H0thku^VlkwJ}Rdy*)U0=LOgE9K^iox!hD135$F
z++D81IWl;9Pe)aSe%sMa^sn^LqNjnJsSNF!yKbU<wLh at oi-FuthW#b55lmI!mBjdv
zZ|0=kjWiH~9nZ|>M?llHzy?Edy^6C&^_cGyF<$ZNqP?hzS5s3EIBcEt^m?G(x^Vq`
zc3Fkgf4=n@=%3H;6<uf;({79uI-HdFK{rO=lqJ?Ykt0&NSMD?H#{U5vDD>j7l$m{s
zFoZi2u|8t~o}<TxMUiSllZ0aoQ+F*o6zwhZu^vPF&)|VFBhU+CFn{!7i=s70tk2E|
zOr4}FIVPr45RHmG6l+(Ul+5^J-D_a1yUGLqO(%y!u~bkNAm}3xr#`MGKvDLVDHX2k
z;d6a62SU)n$IDpddUL6GPzuX_Q at wtQm@pazv0q-VOB*(jmU(cW76bKr;j-nW-ux%^
z)BT$0^a+}uQxh>`<kO#?>5m-$8JF)qLw>s4)_!pSw-)~JR=gWE{@0BZG-)PH2uh7>
zC_XOTr9q-X151kcyOUwXdc at V%RgG6==EAxg>lTn92{;VB$Auj at P4gMXsCm``i(4hv
z*D!Tgl1)9(wJR!hL|Qb&9lExJK|oPU-yL%uqy*4ii26)Z78|h09X$joa)-dqe7c1o
zCA^&K!qG~CV$w=;{%W`GqX22aPVVY`ciVs`wq=m-<$ATHvmc8J9u4wnod*qhHU5bI
zSl85<YJi>!#HbP?Z{^`3?+ZZoi4KOo_Dp%Ve{6FFZoWLTf}Ag;L4<8~Z5{5fW9kwv
z1;GtoA-B1+Mum>6>XpD%^m3PQs0)=`!Q79kVQJ!nLg6OU&#l#koRPy<*k90-3=jk&
zwk|~r`gi&L$JSHmj>*$?%Vm2b;AEK;J14?s`BtgHC)E3N;4*P=m-XP8UrB0Tf at NSy
z`D5c^Kv=o%BtY|*zSl$<ccAus1ZkJ$?4cXSPr<53S>mxnDR(iVD#nQ*eyii0)o?Jp
zTJV;C742TX$Own`kghsbl{L<ToP3yX7G8gCS#Zel3JG|x5K{k0Wh(+r2RivzA+uI+
z6=GXDpM)+eUhl%Z$x{7zY8U4~Y1C)Ui>;x;GvL`c!p*YqA_F at lR7!x|KNWbvNUH-q
zM9-zX{`l%)Fab=yH#=4sOl0>Xuyz2G?SknaYo}%jLQrFQ2OYdVZ|8f<2UYAw-c~*)
z=Cn!t3#oB&>Ir`ZR*iG|lZ9EgV54&fbt42b;OH^IRq{dzl$yK)D9;Dm3}Efcq2JJn
zHMueCbKvA$+r*-cOp8UK{Ar*vD<p at Q(dhAZZl>70krU51rh!`pytK5P5qf!)hW<{G
z;~MJZTH6#evfa*!KChbCr_MV0ok_#b;_0ZlF>zI2UYdHw|2;7l_G9U}UAQL|bZ4C(
zoHWY-b{|1#W8eMmuJ at ywQ2>`|OtEl+wQsLk#K0b<nGocg4_<oM660cHS7<EyyR`jI
zxR*L3d}~^udu_%QN(z_Q#7JOfe$lmtp><-iAjePE<@mu><>N0fYLo3IMeC`>cBe|5
zV$`^mU;d0wU>ND)^n((g8kunC3Eu?^I{&m8)!VvKSMSX=O85Mi<kD-FDRtBQv~>Rc
z%}zZ=&6u1&xxNmwVHi4Hf(Klc1^RNyu;=b+7RV1nL5WbKh8@*PiRy_(e#G$d)<^JF
z-j)$`?c`b&i*Yzrub`LeYUBg%BMhRNOdB}Nlk2OA1 at QLEHO#=~<xqS09D^D{AGGY8
zfUZBz5*+WWKgx1P)Wc>DMxYvK(jl}p%wwm<z2kTtP53hGK)QU}ee at Ka`%oNb3|6Jt
zU)f>lx|@_T^s6!7jo=@#qjD+U&Fj=L$pPhHR8^pA9;0eiV5+6?Fa0dYXw7c#5f7Yn
zmaY70nQ<Sg3{N5josc(REnog&vNEmVQy?X_4lJpi?%9XpbeH&o*7*^kY6$(WI2wQp
z`i!7phZW-5-ZjQ*GO=FkK at N)t at ZZ(G8iCaxkby<geb(~pGxgZIt(Q&-z_kWEVbr0R
zpi}+?pkddx%yz}CCw-?bha|8 at LU;Q8Yy2zWFI49IBWGNq(1MrbtPNT94GluFjY at KL
z`~QfpUve_DPfGKn8$>Y#ks+m&x(2e at qIoHS9~|y|DLoxESp+bXuoL3_lj at jkJ44GY
z;=z`{B)I6vqDMO|jRK{=)YD}?%*T+RSoGpYa9c3U24VLcd`nuf33YqXjv5IbL~NS0
zroa-0-+ at EW;T*^9Ak>@xX8~SwTWPnCXKnzC at ZEdQV3paiE^jQ}VCmp56Ox`=K$Ima
zr3qPvOQxY7aX;J<i%J!nW!H|E$)W1a34pkhPwS at xy*w+GOd%b%dWbV{tmwcLX1x6q
z!&p-7n}F_ARC);(17pM=k;7pK=2;;Sd#rJ=y0;=2%LqF4Pa?JQQU=<sW~IK_%<E-L
zFpM3g4Te*KKlWJrX at DK0XV_ZZ96e~dyy5Cv&xV2+p=Tc$r^^ONCoAi1ooo?LO at 7X}
z#G;MSq+b~HloRMaOok7r?H4xuVdCO8NzXr^8SB}ojo0^NjhqsFxE-dAr)i|1v~|9j
z7ipN1X-1OqamO`cBJLsf&GXotJ&ExnS2j3<f;mQ}z(7_uH*^f at j}8}H(GO2KF6(GG
z={S=F`)GMYcGH0bbM?Itf((++t#UoS<wBFlju at esUl<HG83dY6 at QXpu>kDafI{IXM
z2N(PU|82krIH_R=D&5^Ho-}};2B=C1t!3b at DLlJ)1k?m=Xx-Hg0m!dZBOw>N0ZP?{
z=A+bgv!4tRLf<;)Ct}}8bfjVaihGj4e at j^X*Un_hL_mQY at Dn=lgu!!0F<w>7M%dBd
ze*=w<W3rQ{Hwj4Zw&NZ?`(<39^WqmQhuzfaiDWV?z|02ex*EPoS<ja19xE*;1;6h)
zfOPA4HK(>VlhAbeedeIB>5^<c9H)b8HrNN)AKe*Pu9K=~l;OoB at 1?huZu4eHvApfd
zft5}V>ag`P#r7tj<K>vUWYm*4v}0GWO;&7Y^~rm1vFJ7#E$gK6_<Q3srASg|!}|Do
zHn6+zEil|q4uaume2`vN+R|qzzcFEDIyxpZ=s8?<LeeM!7I;Gkhlp%zfLD?<keeEZ
z8h?+o8Ur`Dura+xDfSbZrJi-F(3A$&IZ5~zpqM1!l$t}<<!%$MxuYx<PALD=8gad(
zala{LdBvK3Nq&<6i>2KStfF5SIn`-#GT~BG#8B+yun!%#eNT!l9qyhA9iKp=H(7`D
z2`vaIWWIL;H3Z66utT^my#lxp*qyoj%)1PzQS-a}ldFOWNwv*OM{u|8MCwGy%zd!-
z)N;K+gzCm+w>=Y1t>|*}0IH_c$YIk*13Wo78IAn`hcOvBf>lqh3o7(M-5Tb|nu$d^
znY$5#2)H#eZ^E1xH4Tj&K5l&r-7{d?`B>U9a=or#A)E~2NB9NByLE7)o<pE}Z=8Bo
zxCo%OvKBJ~J$$c1I5ZY~V2AlB2EJSOGxpvTT$j{muZE5s{R&^TaoS`ofId&f48X8G
z!+C10azDId^o8I1t=1bKKZTmvjSO|<E9%okKf4(0LRDF3)UaegAk$Q3kkOw!N4cez
zla-On_?hbt<Ll4h5)P<m{V!0cz`z*vo+KDy4jkCDN^{%10{HA{wxu>H=2`7-W|nqA
zh28YTUt`nH=<hPZ>U}Ad*=K!#$f*7B!U|8o<@O=C-{N``x at OVT8=hU%rwq2zFSGd1
zq_Kg-fmn&ImBH%+K`E7XhGZ~E<gd$LZXIw-$h?XzxO-iW#O}&s9W4e2#m-s?xs+kO
zozl`MaMef68iDy+!ZM3K{8 at jy&%?GrZ8xElP<;>6 at 7IL*VK_$_nM;Bk%2PKbGQ**5
z@(G<3pYeW5zV&G1d`E_o*3peDDk at cYwv(A^6;d>!S3EOv6k>aW!*)?+VoC%B*UY>^
z#*3xjYzkR*^qOfXVNV{0pcT2Ewy=m}sHvc~Bb}7pS4eHJ=lK-}qWqWpnCGZWD%774
z^bv}K+OQ)-X7EA54cy@}PDgt-XodGYV1 at JZ7GP8DmVA1RF*bN5gi1j$=dGNL<qQVE
zIym7IN6H0IArbX$vu;9n6=W{da%mWtQ)xiWJ;Ptxx~%IWx3L1zq{a)o68F0^EFNMH
zVgu5h6fqkT$z(L`5 at 6rKwCJC#(4^#C8?aU`6emQ0grZydd~QIZpj%x;s9+@{cSs$~
zs9gDqj#=1g=TwoKM&W$MC>r=?JAn=*V5UudlYtDiG4&vgh8d}DrxVD*VHzYx%@24$
z4Ic_n8OTYv$hccXCQPFtTtnh)vy#5xDldi#e3P*y_BToW^~rS-tR at Q9TZf<u{Z=Bz
z+*kS9I2AZkrUYm%I{j#4SGA$~r{J7_O(Gg;fK<&<ruV8uXa=3uZAO<FyGK>VFZY?m
zEr|<Zu!8=XXlqNEgds6_>FSK901B3Nhk;5vP`$-&oQ78-x`EdAJLcL(0wmRn=q6=3
zp<uKbE!UF)3A%`aY}kML(WE~pj$M=i3CH%XbHNcae``#cA<G8EyEA`f)(6B_B{0yE
zYa7YfG#{ijUNkI2cnua+fg!>VDaT+w?Q27M9~D at HnM*TtbHEYIKqg3USiD+y7%&tM
zitQ5g(=@N_t;CxuelAVE2T!YUblsnm`E{IlSNQvMc_m6UW}~up*4;<Or=ltl^oX at C
zdBCumtVuzCginCQmC>`j+~FVbvmF}2df~k2nWPDFc7xVXfL}V7Tz?$M3p)1wCIyx}
zQ~}pGTK$#DvPq<e=AC)RzzhkoygxXsyJ469J&F`yi&v$1&61CWp&pgYMd*7yb|hm@
zY$ro7%HzJ^{`Ikg%f$*7^IY1`&~SCxKE+R`yVx-EpO}qNQ at FbS6F4c|acqXRJJc)&
zL<>r<Q1Q`m!l&?A<^PIbSg}G3EIxc{k_9cdLe2yQ1vbYI?MhVtFk4nxQ?LKr8?GV|
z7OMWGp{!xul~KK7F>fM7YBKlGAOeEjQNq-nT(ds-?NT8)X|FArzpi5mgF`T1zd+CU
zusd8BlJ&87LvmdxZ76Cj2_4=idSBvZm;6UMDi*SC>E7%;(=%BBY&S&yEBzHyiF3v8
zZB!H_yDOgqdO-qe5x?7<H1I2xr3Ix*N1<23GaoN^W9p7rWE1ZWKs}_|kQ at 5)c%b>M
zC<507FZsG~JsWU+O>TK!4y8Bg-wrIg;P_o~a<Yj!BV%NRV+4H`o(6ZA7qZDH7)lqM
zPCG at Cy~k<dM?~Z8SeV}KTl+A5RqM+?y*9)BUBYfqdg{LE at S@+^!S>DMcnChmQ4G^{
zuWSh?@&$!pY_WJ7|Jk>UkAy-{Tc6<IxYnEE^2Pp0yJ^RuGuDH{zMEnsLZVs`CF*4P
zo&b_7jIuVsU8xkAXCu3D$~YFn!)ucc7dddL26l|+DaL5qGfiw<8dsCKr=PNcoDVZ9
zAI42?RK}Sj6^G`<NyIg*{!`$};FI%mtK}k_Cd<-L)zlj;3uOL8`}p6Z1gPzjYnmix
z(;%W={1Y*}o=#48yMiMYjnLO7+%EF`*l+Dv+QE6u0!OFQ1*tiC6T at lw#7;D=k@<=j
zj8MA7EbRkxJX3jVlmubeORc_zEkEe5OvkjqPdfdCKOZsAc~dWFYsKWO5`Csnezbg;
z=-_{67n)O|^?}o0^E`lvg0D1-;-%Jy!v04GGTyJV*4`A3>AD$D7WNZ6`(ILdA9tJ|
z2FZ~x{N}6tP}rGcw|Ges<8Pk&_qg1`J#SAkifU%M>*81HlQAopar)~OPT6Poaak_T
z{2r5$5+2h{88nbQ7(Q<brv3Rin0(<Itu34(b3f!a4(^ar|NSrvyutRdpy*NRl7#(V
z!;e_l7JNu3NPyQJz1UiOaGRRtim&#Qmzao6qU{*LKDFFn7jKg$&G6;r8~?vAvKuo;
zzQ)#fl?<13D at Uc8*2k60oW$!gMl|6x)^>^AT}imy5#Mc$(*<383O5kAP+M^6VKwDn
zxX)Y at rQSbY?Vb{Psn$U0D?7rW&~e{CE?XB`htno;4H&7a+lrdl6&n3}-bW^qu^Kk=
z)!hzQ47^R$_m=ZiK6S#_Gy(nF_qMUqx at f}uDQL=JA;b5!UVNfvR~f4DJ3h^wegv8?
zvYl!TIS;A-eZ at AJk^3IQ=^N;mi{!Y|*Ov3xOm70lv6hL&<@Pm&KGFirKo^1&${#QG
zkbj}LMK{BJ*^5Br0kG8k-?qcD{lwhOfcnXAF{><bjCyomLsxOR;{l&}_}zH~A+<>`
zj|N2q=M&AJJcdn&Y0sO^dHtnmzm727-onWbLRqBS|NZH1HvZarilr7554_kDZZak$
z%Aw1;?0h`uPm$dxe7#b at vS5fMaPA~2_rD#z*f$7gx!Iu)j3S-$$AMP7(xtu_WigiL
zaDvxok9By2NpU at eL*zkU?9%!Z{#X#jc54bX9gmW0O){DW99!wg`Fv*iK>1mq>qYA!
zk+ac#@3Z!Z3l#a;#XE2BU2VOKC(>W_m={LPL-$*57 at b8)?hf3^+oPHwNZ?&d{dCWp
zk+slmWs))I at EG@3!f at 5xz0Y_rn%!7T=c?XfXf(6-4q;g<Z&_qI*S*+k8Y3<W&JC{@
zcC(fY{T76?d>^!43H;$FKG>}-KU_}eIQI8nq!N^EtjG0^W@!zAdG+;(Ykllko1y7Y
z-F>k6yzl_hbQwvf8FWH-w^lG|M)LMG`Sat$@gdni9i$y{YPI4!S<9wD`%g`LE{R)j
zRX%^K_1?D&WnngGJ3j2snhlYghWx94PPQ-8zWgulz_8qyje>E%<&JUw+9x*WSuiWg
z*?*6?+&SQSC#`Mm7lrf90sS1>LE8V@!hXP_?B^O(-296Jjoo=(IHIggb!|-Ny>*rj
z8V0g&_18n8pF;B=#Yuoe3EcUx8Pkeh1DV(^)H`Oz_=;GGngAm#23+qx0R%r8(-z*p
zOT}P|5W(A#%Q&>PUCiBmIBgc%aV0#}UQUp<TcZyy6RtBmwi)DJk+xapD$OO6 at kO9a
zBlX1dFO$lq=%awdu^;W8Ia*`S12>sFfDdY`3y&)nCy02dU)z&TV5JMGZ6;sq*O+>h
zvCs~Fi64$`#t+&yiIlr+7tQ=97<k at aj=OKP9BLaa=7oE=HZ+eq{;=@s&$~VMYqh4B
zRA#xZyW{U24=t|Gw%g)b&*|o$<L_}Y|3TA`ru^F<LJZI9$5}!4r*_-b$_aO4yFHDw
z9T~jUXx2HEKmQ~>TuU`Yai41*wBBJwKfRdm*!RCAzUwwMS)RM`yXaGGYyDT;?d{<A
zrS<stbCb)3r?(qYe*Sx>gcnL#rw8TCwFmwz<v~L2EJ4eT*M;~kM_9s(<bR|sdd>?z
zMfx<y-}bW>;rpu>6{H7ZEk_i0&teaPZmK%t%0SSgf(z523u<O*|E*J{i)q)`pgWDw
zPmLXNx4-=AZqKwuA|oQyLxPTfkR0GOxdq`>oY{gMelbpwC2Oo86rlXBf0uI{4W-NI
z=IZtrVb3~;$VH=yx}3beoXhqc{*GFXn at 1m>Tr!`t7%y(eNniJ#Gl$Cf(+BOJGDWcj
zem&<67g at 4R#|^r=S*IB2US}4#?)75HCARRtQ6)b>MQ9$H3bC}_uE{rDT|c-zu%VPa
zN3maTJ?<voqR}H4yC~liyXe at LQEaaNBX`-y$J2U_FXxQEWoUu4)DT3u1O&)P6m0lf
zHj>n9{8_{8e7YQN(mRTSNJ3A^3h_6N3W5zD33OTStju!86>a<eCG{Ps`Nv<8J-eA&
z0n|82T99GiVGhC-bwLky*quAgF#Kc9|J$HLaa~Cpy0do%)Xd&%3G6`WIExkFkxhVp
zXk#+cL7C}dqty*!*ZL_SjV?rE8)^^^fF%C{=9Sc)avRd=r%0k-O$j^OQRd;0<pn3T
zXRl7fBk_#!t6M(MgyAtC$GnJfkKJ*>k!E3|;*sd!Qg83TZ#_=dI~WRFeSCeRc||nN
z#di?U83~Q*#2Isp)?1>HyQ{z_$7`bg=RNquKX6-FYPhDW*pU217fD3Zt1<m{6|pZ*
zh7L+>4-Z~_*4)GGd==Kh(kQ>}H3~g3qp9Jvec|<Y->Syz74;KhyszS2 at M(hi8~s?0
zM}=8db+Ow1x4eoJ1m0J3!q;^x7njTH;#H4tw`NIvrk6swI?s5+$}^tIdY|K6=Rxny
zEph)Nc5eE_V&eQW>{%l!vEcp|Yg@<11!el>+fbr-oH`1O>Ha+d7r8b#x%Bl8#h*C5
zH=bXz*gFd@?pbwEa@>=3mqR&_*Yrf45rHi-)y=p{Jax&r8=SdHnv6}hUskuuIvm38
zuGz06xN-k`p*wVW0PbB!d22Wy7pEVE+mnYw9mUfW`z=}7Dm6VwMmbrWEDe97eRA7k
z0y&=#A))3-<-<kKFX9hex_JHfXB}qdzr4&?P_>KRmpLBJ={lcByVyz`Rd&+uU3&k!
z!ENV4b%?k9D~)^MB%^cc!SwY<61r0PnM_bhTxGndUrJ_>)Yvx2-Cjzz0Duq%fAa^6
zqez{VgDJKhERCSA8z-`}r<NaAlUW!H?Ux;Yx0avGg<$9!cC3v}i^ZcT2{;aURHD(B
z_Dm>yvlJxdD756%HUakW?=fEt0W_ToW4Ugz90ef*Yr77dU%SfO;etQCUsGA*c3^rB
zR|lK0vzHhUsC6C)S0c#CQ5X?VWIDP*5(BbCvfiaxE^AKqU?Sd!N at 6fYp~h|2Rb(qP
zZt|(rpIn{9I}|5`HP+=4p*u~N6`8PsOZu&R#msdSqnM>NPTPH@^gOc?0uLsY#R_Yk
zeJz(*BSYW!Kl at TrYo8zGd^5!3Um%oCcq6<2FQCxa%Xqo%iT~p2^EuyE1rFltVrSXV
z)V%|#tOJ}uN=3>9 at epyMw&Qn`kE5D8Q;gY^UpHm;4c4J$yQjaj-S$RYcoDK>HD)aw
zljAl~yIf<Xszm~*)ILQxJNPe`5 at ZEXEW<Qq{}dat1YJ%J9hh*wqml3)eLYR>nUYyl
z!I5Rb?(KYk+oHqJ4neqPISNF1O&e98%?mX+#JMGVD*c!hwtVB=b3%0{qm2v>IJIJ;
z9(uRL<wGlA^s;GO?_<wi!J1hXW$~v{vUycpE`q;m;k{j=3)#2RGotnhnQ&&Sn|a3J
zN<2?%W}o=ohF;v?{}e`8r#ET)neN#so8{wFk9UvWd5Xx^^wPA`TqK!MG<EsO1+om;
zFLZRc`>XC8e9>cG;wAfQNeCPop+wnW4_8#qUj5kDiP>#+KkL$U=Z47wyQrU|UsY&x
z0%v-tNaK8r^_HZELTb9C<N~6+0{g!0>@DsGo>E;*#|d3){U*LllF8op`<h7lMnAM&
zezu0^m_*H|%uj79+xOMi at _;?!Q`rurJWS-2E%Ra6tFOCUuSWaellet1KdQHGaL)Jl
z4=!18sc=`18TVygyrbc~PQ;9j{Em5;*Qu<89Ii<T{sv--hAm{g?H+Nux3iY?Nx(ca
zLwFXqd_8HZ%~$r3=sF!8gJVP#oL<b8kzHtoY(*uDZx`{29#`IJOp>U6SP(-k0}|k{
zE0X1lSMqebPi~j+DQI8g at b6H)h<d~6TP^~hZZ0C+JZ0%YE)q)aWoQnMBBM6=&0brz
zF)x!CKUin4A_HbrEav9;!!k4(`WGSCt<KWDQkPH-eD=tbM0zXj1lQz at cv9q}51bN4
z?fKs=A%nk1F}BUOm^wD-#Ua$6GjtPMMF#F9&Z=Y+G-+flOVh6H=VG>D$4?M>wGdw|
zITZ2XB1~N?202`BK7<+w;sK at IG4>NYoPhsweMX01P05-y(_UF9g`>ONI~vjkgNle1
z^kLnI%Gdfo`0lhmT;^WJC5uT}_z#6k)=&cA$c_K>nV67A?&k21ZxpzVyBajMxwXID
z_tmU&l2@@|6Xm;Nk~q at y?ilhjlO-+IgXV7B7p=EMrhe2vOI4_KVT98-vcVk06|{oP
zd(tAXml;AF>i2(k4Us)&HtxFUC6u^bo*p`w7$x49mcn6{e@}bS-+GHPKS$_&n#}ab
zWz1~h3E>M~mltjQ=F#0l4%gjY!aFxO<m{SP`n9DylDu`p<Y9v01J+0c#uEExQHXwk
zLIa>Ka1>1=Ft!O3ev$60ul9MZw|5DxT&T^M<<C|GTfA&3YdKp^&*f440&^e~WV
zUKSqbr)2$j2yMuuo#ML=&bRy4Qq{HnK<T^F;Z-j6(3z<CPfS%X%ksl>x;ekrHnF*0
z7qgL%Z2e?~1|j0+FWD(BWdn7Hq=`WO>pu!E?pn^>uQz<Ya3{BobA?Y<U1$c~u-zV|
zwS~gsY6g_B-(|P^G4Dw2GS@%cv1!YvTcxe$wjf0E&g!rv*O#Dn;Pw*p=CsB*z3+7W
zT8zVEA9BMMN{f at Tdc<KAb}>`@^nE+qXPokj`*Zyufvs0B at c;0%2gEOf=5L<1Tqfc=
zZYVcuyEM(dxfs{Owe*4MF%w{Xf^8k7o&1}c9v)0+W-iG!`@veTu<lJ>Jjt}d#c^tg
zZ=~C6F)Solx|-CMMz4^TiHYs_=D8DhjTfJ1w%C{1*l0RRM{EB1FQdA`36y&Cxw2+=
z+7nmlrzV*7z#zBP)?w(%dVGLoAv^}nwfzxu^V+CpR{7C3#-U>PQ-PNBVE+E40#=6x
z{&$N|sGZBOTXC>Ha3&*;R1(}gYp1^SU4wB)@|)W|xJjbyPO=*@JhY38Q!p?bW-Zp6
zPZt9h1iO`HT2P^5;Kvn|(U=NK at L8RKSi#KY&?a=nSEQSZ&IYMlO%bL(ji6tX`{V>{
zu~_UT-$6Wou3^Sb;I3jo@*?h#A3Vq$T45ngvlhOY=H77+#3v>)VWGrWJd}2qCw!?X
zIh<vSne6KgKLxFHux&dHZf2SNELNOHc)XY6!#{%<$R!^#7|5xbO07ZTfwAeXbZXHd
zD=_%(Z2UQ{i*%q{TUM(fj$IfF0I2(~@s%%R$?+U4XYIPqhMT=!=uKn{LipWp{Rets
zzWhM?^5E(1%`uHaRr~z)ANHnC$vDruYXcANWeSC71>LP*47`x}b9dnx+v>e8u@|tU
z>%aL5pM`P1^^PRy=+ at nqDZK)^lrd#-g9QK$G{K)=iPX3Q34G$G*9etoVK4iAybRb^
zwL033wu^O9B($t-!A(4D>5qbLe{^4fvVy+eZSqN7-~?V>NZg(n^ieW6wihIDq5Af8
z7JY->NqH||BRFMm)?O^`?@LSH97x>WL_97#zb_uQ5|>Ko?{G&Hv at TY5P@VIqk-mHM
zy}?fN-Kb1v&?e>W`uyyopR*iFEbxHtVn+31)-;v^N$4FI&=%xfj2iEMv0N*cXtDip
zC4w>Nq%@0N56&A3lOLLY+~G=AsPK29WYi#{^4Tz$)T8@%dva4TSy;@WKKkmkTC#M(
z_L}H!p;i_~m at Pf)f6mRaVA^`aC{1#ROf~%@cLzUj+akVOKQBKt{X=*Gd^7|7%24JK
z;l6CwwEn}j%eSMXnF}}q;TFKKhvm2^Z at p4Z(*4pML1Uiq#O(g<u~+88wy8IL>-hnL
z+_hb#1M?Fi|Lf};yxS+<!9hpxEQP;g7r at 3`hXu~}($I=T!2jl#HIAml!qWFoPV|WC
z at 0sMS>$(55kv~CNE?aEad}(u1Ol`(O8}@<ShkS6DA#W4&Kw{zihV at +-5L4swVK6Mk
zjVPqEl5P(Lqo5$^cVH3$HP4Ap<o@@RiPdCVjZ;pwGN4j at y>c-R?Cap-CF7$0PnBBb
zaYjO^X|AIQrzrjHzcsUdOj+6!by}_S6UOA2opZBHo61c~0slh%$#f4-A at N?oh~8Q!
zmAS*zWs at l<!8om~cn_qoF);XU4WtXF`0iUM`n1|o9&(MT)7p0~nP@)`fRyGd%tCx`
zon{KdJV$EaZ~G;|+P=3pEz!S2>6{I_Bq!h|xK%DQG2 at a%o_wz`whz8pgTk|$7IpW3
zRZc8vO*@^=Wk69V^oRjrK;@=|FxY8q9f2ir>v*=kmS-~=B94N!-0VU8h4qJQD_naz
zlpxpCAhvKQqr1I;6Ut4#FT4{GOFDBIC+PI~r$e5k0lTnp!A3^^(F~m!(z7D;6qTWE
zC>2|eA~lYy#B0*?Q__?yz_ebc-o3w`+rMGH?P|TCz1Z_=jjpjf*gel&j%z)ps-{nv
zH57waHEIa|6Y5!?-p%iqB6-fTGF~k4(eTu0Z$cVXq1E8 at 8|;u2uG=h2VihW*%bxi7
z at m3{{H2DIq76Utsy{fcIkH46>si+;7T+PM%RoKht2`%f{TCl!4U}>-YI at T?%T+iwr
z!BbTP-q%fOHo|?bS-SQy>*XWmebBpm)4R!uu&RZ`2gNmIPE#~Kb8 at MZ(VK4<D?i<A
z(0(>DmipHhK6xB~uSLRU>0VTm@}AP0L>2;ww~Wh!00MGc0FZSO_s?3KQ`Ng at EPr!R
z>ugiFvRim<g0D19EHK|a4!*yR3rk3R>_b3AFmGeF at HOFi9ghEeD7Sdox!=n|;|7+6
zxpA7$wYK7as~9~qLoQ{dxstd7GGKP5MA{=n`hLlIowxOSRzgQ%x>;x68Ab*J1!5OL
z(RmuuYba95dOSjHpVTCgt^F@}Uz63iP5|;TIo)e~7)-KKR|MjB28-(z#B2q#A0Vdl
z7I2BA3HZgyhRWH*<qtL}Z~uwm-(Hjw5ZbC9GpMtzQy&M5lSuU+n=c6tp_pE#J8ATX
zfj2%{(tElCSm_sc6(S#l(Q+|nAgXpmG|vsdKscVGZzaMKcJVvUM$n2<BAa<7t(AoM
zOFXYB6xpFG$xZ8*D=1DqrYTLE4jibL-ZHeupgEm1ta60KhKk^xMWsm^bPa{}1^cAL
zFH2-!nVcH;AmyFU=O)|4C+w>~e1d+5(lms__Wj<D?ux?&7#LNCNvq15AF)FRLTN*!
z3qBRTo`|H|*2<SH_M7Q(tqw*H)VX$D%&AO(KK3$qD~gScZO4Nb-fgRAe5;<aWbam=
zKevAlTC=08PwM-B7NGbVLFYVCdRU_XrYs-<e-koC7B;5(4I(MO{&_o_(*Wd(@J(^9
zL`Nwx=@Te$9F4hd@{<|%27WW&t|NM3WLE4}0h=3j!_6zUj1K9(;pii}@`n>j$JUkc
z`a|I>audGzZyzovb+#|o3A%T**SU6jAHU-TTX at IQZgIuE-5xjC1;jJJnJMC2peI?D
zin9W~iYp)ddJ*uT_3mG5oZLmI+=jC?K%#FmXwf~<%lz9S`)gD|{x!)-wLu?S9iv*4
zsAs~D#?KQ+qN05{Neu7XSD(;ur|dQCG(ePGW5lCKpPNqW%pQAFu at kdz%I*3U>XOEk
z`#N#heHLKVvu(%~qLbESRTl%83{o;5nT<$U91kJd-Bd at 1n}n)H7(E0J5u;v9ISj>B
zO*G-NqfgqCj8y|CC- at ewyXIhfWQ8gZ>h|o}P?(EMk&w3*Zq0=vo0WIpQtF`;ghKiR
z+EW%?TnEj2eX|e}HvFTU;Bp3}Zw#Aqty at RW7_RBc?C-pNRZ<>tLI|_;aIoH&1R at vw
zTNUuCG`yj#aea22ZxX6gYxj+TzP|-XUH5Rz>}P_1<Lbn<)4m^wx4G{x8vDJwVzj}r
zEB~20ClgyNrxELc6$`zLleDJCvLa2Q5cW`PcEM}T|1l|TU9IZD+%n!-5xKg4>Vo=x
zxp(foPp+`{p;0+6W%~2ABJiTry at bjKZ~!1zONchxivLaOu3bQBx^@OgR48-5Khb^g
z-UO|&aB>*Ny+}2EEF;>(;^ky+5sO}U4F<yV(9<f20F28B*ZJW=3BJY$e`yc5jdM<h
zG3Z^cV(HxOk2ISg+k;`(vyRiBc088M>__%#K)KeMrCo}ydtAC2zYLI>y+bNa at G8Y0
z54#jk9{m&qAAM+N8T+AL`IH;;j(z|@$kY4OnX at dYVk(uZ2CVMEWl_1)E2RJBv};FM
zNTilvCi!vJVx4)1t1$eo&Q1Ogm%3&jDWuPuA7$un4 at Q-nvHyZ3p+C<E%${ryf1G=!
zVNOMUw5ILW(FN5pZqC$hI4f!$ro7>De&TGcw1PIG59W;ANmO!%;re=R{F5cazLFs5
zp_<<PG)nrR(17q;KgNWem$mNQ6ojHtTa{2b!|Ao$OGbqsT-9X`I#*F at +m*`0 at nf$h
zj1P8iDprrB`}3GttV=%!@@tm)oEw>zZmmaj1R8BER>V&`c~L<tqG0^t+bwkSsZ4Rd
zla^zkBRX~wnr4YI)64U+w6;>TY_81U0n3gT1Nl832iu<5_jr<jtdaMR!=ad-I*A?f
zAO6~tzfPf;HY?jiCq-<}XMl7cLjLBh$ZyYDRl%j!;b9;fa<7P_!e=v2+*W|ngZu{5
zpyK8oN at c&$eE&KEGf3-_oavh%eyGfL;@6@(Q<yZ{n)taj*Lbqt`T)G-0shm)r9YtP
zFyU9wx=;c=k`GU*73;Q!pb&Oo-20o`3x4mJtN)LtGmnSz{r-RZPJ3u9MJap8ZHZJu
z$?`^s#yX7co+*u8sFW6lWQ(zckloBM*@f)J*k{I2Nel*M8M6PbKEKEJuO5$yhq<r&
zI_JF3b<TNS&w2L1&nuMf)uF{BT4`5H&E?+K3AXAyjK;^6C*ck3iMKte!{rX^uCR+B
zILt9Gme2>Smy?D~{k5QHrCA<uhG^JI4zJr at cvo>k3y(l3Y(5tHhG!PWmT}(Ag|R~o
z+>7@=rj9F=kBG;5<@+c+Fn2oczo|+<PraVa5jnDhVU6LD`Tk!3Y^6MCRol1p;q%nB
zpO at t^zu?3E at k{qO=Q8$PEq^4}PAXd1cI3kT_iQiPg1WBz3C<nY_h;0!8wN~VH+HQ|
z>jZXVl^f8X-%#tOtlu(D1;j0>kPgOMkmlBVnI%cl_zn+v8$VY&T>c}A;AHw4-`JFj
z9_7L$>7AOcL&zcrGI81 at oAI#o_2_<G=IWpHZC(ulGsH&meKHVe$iJO<8aI0v@)k)r
zOW1IL!imOEr$=w!#ZR(V-W<sl)oY-bw4eOR02TYj8B)T8d+BonG*|Z0xtFI1XAbc|
zW}s{6ofaP<^s_FRNEf5~E1K<9pn(q1c(N<2$>Dgub8jcnvc^0$nR-)@%=At1Q6t!$
zM{K5(T%DO+rD`U}*z!>JxaI<!g=?6Zt%9>2HB6a5(i%cy-?QYef}X3E^~xw^Rw>(h
z<Lx7L_ZY6Hvh3pF$)DDBACdOtNf{0NjoPP;DVf~SD*CD8D>0k8yV=#eJ;m$O(XxKr
zsj?d!SVqh%{p^f>rPSs0kiMmmyPW1*+jDgbW5enxi~5x`wUUCnvj^CA8Tk$tWPy9F
zr`j3&&b-NHe)Xt&gO3rDc5F~j;6DPwWS+mTg!8?ICSi*_hKueAp=&W8J!BBrlkC&*
z8&@z9X)A?z5kxVYe!>&}`mrlOg!~YIt~>io*+u6&M$0*hy-Kkqy529mJn4+q8pz0%
zHn at Ms`ib5l6 at 6&)BH`Ta3R=312AC`xR-tErLdX3)KH{7VWWXw?^TWuvl(yDL($h3{
zDq4|ZE at v-RkY{9fTsw~uqpfN;YQRVq$H6 at Z$*S^AMGhI^_nRE5>h|Qv6T^$sQmr3O
zc9g!y|89T2xQB76<+ObWb#VQq-Ul;5f)noMrkKjht+1g#<BuA0%?q8`tvt~xmI;XQ
z3*(`Q2B}*m1?w=fzd&`ZV?s!dE%Q!gJ8GqCK_D<2Uh(<)5{&Pu;Xl2dJ!rzQ at I2+8
zJYY0Yr&6+bsJ}n2Ml^bNIt8DUpLy{Oa>aVtVrk=KVhMkohD_fAwW;qqT9t@?Zl7`R
zQiBw-eaiD`%;JaaxD+YIlQdVZU5wZ99tXLzu>M-z#eo-%&kX`~pvfjuX%gD>gsSR!
z<QMTw_-?SMcxq~gc#n3(=SFcMk^oWUgjGDx6fJd0flpTY4z9oQ1FF{({$XcI at 1qb-
zeZ*xeWiWdkTC#dS`oNDG61%}2BS$2lpx>vIzP$=}8AztY?npX#KC*`s6=pD5Tp)-#
zF8Mh=6MTuWbGKigaD2n_+mpT#TZ10;K}5UWF&gHNy25NRNDtw0v3>c|7c$FvmxUwV
zHYg7%yn_0w{fgva<?nwSezzYIj;cGvY^fg^gOMKjskm&CF{k?g^m^7^sWDW>vB3=A
zq0P8-!s)5MXcJpIBFm;NR1P(2K%N|ZUwSIQTTl`8*p99FHPLF{(@O`OWEyTj&aJ`H
zP!_&WBOA(qL*;Gs?~RDmp|4~4tuHAH{yPwB^^NT0sXqQl>jHw6sCIgs%AFabW{-uw
z<4FoQkaIEW<&TcClLtP<6%@J;Rr>7Svdk!Xqoq-6d8m2ss#WgMF-(}kXHTZFO4oH0
zsz3j(+*d<At2yX<Pk;Mdp&{2k=CNIK6YX=@O#AQd8@@$jy|lw?8?S=mqzb;5rg1Z9
zX+gC)Md#r&S<F8JU35LD`yAmDYG;ho`M|z at yEoCmoBXmY(x|bAtaMeI_8e)EnejMw
zp`Ce|M^Y<ZNc2DeG%S&lDC}`!SO!{?fcT5kvS|>4<}lhLtZUz;kqxh!R*f<zf`lOi
z+C8j)VS{@a at fmG>L}N<@arW;uvSDc>78-GdAJ>atdBVZBi9%pBVpb5Iu$n<fCwJ`8
zCAE45pAEtL*h3TFYL7OTc(m^#oU>`jiW5idAv`%D&YpkX`wHdGK+=kt2<{tGc$XvL
zi7_;Fs^2c!fJj_iKSdz&e<w=_!t0H2IJcz^9aKPBT)*6Oh4~&QDN;<F7pauRoJCxO
zxVssz#F*2Db`6XjQ1=+)BY{dC3+06fN`7R;EmegFr+U1m3x8?i{1lV?a1P;w^ow7r
zc+}-d33KX)muH7}n$F(7@#?8~prKgBFcz>`)_R4t#H{WOj;biYzdUsv{WSQ!dD2$h
z$J$7*7k)g=i~jx2liM$JYdcx~@P$=6&o=p-qe>~qss0Z%%fj(02?im#l82zEMjd7Q
z40v%(PA#CWy*Qy~A(A{2S~|*)n7k2_P<`-Nw1MR@$lCbxJE?nMLQa8sBAb||v#-;G
zTssR3f$2#Uv2`!}(-^vLk#t96f=--799Lt&CYLCo)G~D7e#GjKsrURHW(nI)%dKdf
z(be=^xl^b06(5KS(ae$<0|%14QSgI!JS9;Gl|fibfah;Rmm^x!v8Lv_;6{+g#|Sf6
z|AHC?|JMD}%X at XhHQ(XcXG=j(s(661b_Se&>wNwha3ls&UL+i at _O?_$s8$xtOys|w
zg9uqRZ?}d{LUv>&1s2A?X6WHjgj<ndd)(fG|7L1tjamqeV+-RsLtSW`^89#^M%&@N
z+YseU2Xt`LwuvjBrk+Z~G&~t-=8;)?Wdk at X0ycm-S=6PzqJC(HrCpm@?ctt-+7JD>
zk~90q7TSuvV-y5jwJxN_JN4iHld~+m>+HSzBM%;r3t#oEY5tsI(KebmJ?KRgbY0H~
zkrKN)nLI$FWSJw5=EzVOZ<8~+54A5};pjBoEzpWP%<THM%deZr6H+Yo*Wu8oHY+RT
zT(<EinZMG|8%)w-^?v>*=@&D-GO#ywnEO6l3`@apD;F+dJbCIjb%KU&5QJmKvZ<jF
zVTHUm1B<G4VisRZgw6UD9X&sqb+MB6jdffSGJBDmueMa3VjDE{Y)OyEoG|z>E7s6g
zcGf^}p=!b~!gFVNCo-2abp^tfY}kG8tzV>n1{0%v<vFUEZ!QY#Lqrz8mVshbvFVql
znyj03hJC!?zAq&3&U(0*CvPc3H<AS>Yk2+t8;ncoSSSWQ at EG(ughxpE7ug5bCI$%O
z;fTl%iP#u<YdfnYp}{L0H}2z0*q<Y1t}IHg_yyPRUpker#|C*Sq6O34pHB!X!z$Q{
z9mb?@i(bM5Wlu}LdEyFx8~m^e+Y3A3hGLu~&fjz!I-lchX96Cw!jM&s9+t;mMpS(J
zRG}DRpz!Ve+X#ZJ{6nh5>1HInSe6?gwo4Uz_knm at XlIV0c)pv^9 at x`5(b3cdx<Q<)
z+T7KfX!@FhqqjX7Qo>%7rcPSTNKq?Jj*bW`Ye9jUkr6!BVHq{qFXXcqtpv5Lahe)f
zNve+0 at k|YGHOTtAWY6FKT2gHNhZdCrI`VfKYvvgUFN$1!HCN-hgLrOB!sXCshboQi
zX%EzxrpJla^w}tt0is6)qB|1tZp#yXPMQ(^rRgT|+fAs?N<%R_!XaA4p^6$hu9+FT
z^_6I>+1Dsf;CVul+zUU(?D^1ySKKnjwY3C)>WKg9>%6HLhp3nrfufXqhaO69b-Q~x
zf{6+AIpq?j3QC<yXnv%nH4et2)Rs=@U>SIVdF=T`caLjsQ+t#YZ|p0v%1zt(>a4{P
zN#9e}FUPL=aLqKoFY86UXiwhwaA4ew$vQl>qx(|$8DEy)i^K4*`r?4V6h2Z{<e=4_
z?e|Q7e6IZ~DU3x`J&OGxE%|t>;Q(vKyrR+5<VeqOtQ0|&7H#3EXRbSZq6ZHnKb_b2
zLr<+#ir(p$sFd2*o9rIjdGy|w(0kL9&lL}>vG*Vh85g~^ZQgPkQt&^jc}cbYGo_6v
z7-AJ5cU5w9E2Q{tjfycZ0yc2-aQ~;eJ-pCK`wYZ!;r6UjhHr|ikxH}9A*LWHUoP~%
zDi(Q_<Jznv`>4d{`X{5gJsNUdyPv%3NGMFpT%BG at IxV6+^A`WGST(#Dtfk#fChNBN
zfhzJ5$j!0EU#vht2<~%7$kL at Wu+Pq1OMk<)U#$8MG|hH%3~rx$Eu))X+L&k{U!R4s
zph`dr*%uMk2jwBG=Y<D4O$PGvSgW?sD~v9Wo!#FZD7?^69olW^lKW5zggDF`u_H0V
zBMA|B<vMZ0U&ex|b{S0u-<?C7h*2J+c3K$EN)?>}DS|<|5@>qq)ibEjY(@7fH4EkI
zR-DaxXYo}2S5s at HgVuPAaZ(=k?q!Q_ZQl$OLd at WB)$>k1i3a?kZD&xSc$+XUd!kL`
zWkQsPqFuDp4@$u at KSI{A0Tb!fvocf>d#l$#Gkcpv9s<>ny^vaQ7T#q~_8dC#oO)(!
z?ya+*T)_jgu-!7tizg7x{?BvPU*e08_EhI0lnYA-6HUW#TGt)aQ(Jg4cFWtaLwC3G
z2(1{!RWduqL#>mp at bkz!2{w?{bw%`;<!NZs$l}R)wAW~QQ%Ti`b;=e$JSg_4p+O!#
z^-D9CcOX{Tr`(=JK8jrKzVjcQ`xmXlQuI-S(SwKGj9eOYBHEA at 0IsjVmn*~Du+5%-
z+mBFWTCZ^P(Pv+Nm-uQ&Wtf>0Z!A{8MwkD0j#DRoqrf|^mODnP59VC(Rd&`9YBsjg
z<Zfo=3uGGhklrYryEgMfFX&6?z|-fT6K*@9GqJmFPqM||lygbdDO;dD5w+8mDNQiA
zv8hoLVek+Qy}UzahI|kxRz1XckCn&46Q$%?&W9pzItidr0wAk^su=vCh<4_oe8dHY
z%k3w1O>yU}dWaH`mvx3XCn~0V5njc1iNW&(C-N0B1hyUdc*_L}McT^~H~^`!P at E7$
zlC=XP#J8*y!wia_;j7JA)d}Ow_q3wILUAU1fl=n59=qbr4R>eswKH#NY>hFdy)A~b
zc((DbEs$=%+BI<z(%Fpm>LFc?Aa<)j)01AXAi^GZygW at sMj5Gwl}$mQkC)q5o>9(!
zlQBPT*yeu+j%efQeLd9WtY>~<m^Ja6>vBy+koO4kqQ+^2OJt>-{yyKhQ(axx)e0F_
zUignjg<daBH*}{~Chd5SY8x*v7ZzzPzi0&aOQ-z!TWSRVNr?X)#rv_xXia3j$>LAB
zwQYuj%gst`*ZfA8jfDPW;Uu4DvFBS;7|5Z!oX?2{NBH5X+|$MTZ#mzMe{reWo5F;}
z8DHv}242ld<6UTb454Jh`9tsyf`N4rD*F9DozNhBrE+GVZV#XRXjP&{lmY*)Jp>BT
zUFag=@t06p*^o^wUTE=*)0KwM&T>;`$yCf+Qnv}~>fEPOWMZaZ$=bR$vuq$k6&mpW
zIL6ydirW3jzScaNXTFj7qaIeLIc8vQbJtT*$3xH7U%LF0A&8igEu9>i{vj=$1z)lY
znNtCW3k%|-_h>rO4!wePq27Nxb*+!AsZip0lnmda#iSw5f=CGdHvvvW$AM9;XcdTY
z;vnO_l7cuPB%126LK|-3nc=T}Mh#0sSiupkpobDRCkc#)R+4{d9?B~4 at lnjkya;Bg
z_wC5U>7Oa<`{DyVa#I$6nl*gV+(N8(#d at z^JN=j at Jhi(J9&ai2%&r_SApOWNIg*)b
zR%G;!|2qFOrSn0Yg~&gX at xR5ytZrZwEe3dMHl<ScZjCR`B?s=#a&xJW)1N`^tv+bd
zOU)#UOpE_igObHJU^x9Ygw`FqVfjbii<_I|*;o1~`>0v^)5`{C1$_sg`jVM}+O-#s
z$KS&rHAWPm<P_U|jad^x6lbjmQwJo%CQs!M9JSmXJvEQCWfkq5EG&p^ECwG4#h^jK
z{gY}BSzvWxp>wjy6Yfp)>UJM!P2#*cbA4ku(kWwod9;`DyyUn~O%lGOph}wX)vi~?
z|M-6pxA;NBMM4}y at w2mCLtm0rowyRSg;w*-;L%R_?|!&%e=fSgk986XE at 6J%10-~e
zhN75PG0H=~U+q(w*j<^gkDzZVh`OVH<I#$#Tj5ReXVDH-1nQUBjqnwk0XuY5KIklg
zPfhvIZ(pqMX~1?EksrAIdooMugZ6{L0l5g25)q8(s795SdA>C{$WVH}bJFi<XsFWY
zHI8mRVnJPtwP<zKmB<cJI=|T&Z_{vx#jh&iKQ+C-U)Hx)^9TLg-(9&C_4kb=r}tR6
z#07biC%5?kkg~?sBdC~jO^xb5R_JxFL)^#ZW=>~!LFKIU5@~1mM_e=4fu=KYyzeM9
z5q|7c1R-wlu%5=2D)U6egPl&O3Dn^qGwO)(u2YrFkE8H48LHV&`MRu9=0%BSZRV~x
zZ{H88rP8nBNk?}Oh6n5vt7a0>(c&mdtariAaJ3_4jF_=vUdP5V54yPo1c)2AF>@*i
z$)acPxOfr~BgIFm1H?*a)7Z?6lsSEvu at 6B(#>E?uw$HD339wsA{kJ0=mTh`ePKCZQ
zays5oJcnlZesy5jHSm$n;%0Y2c&hlm0b+NcL-=aiC=;gK_wAD$Xbr`aZY#eo7akjx
zPeD+Ir at AKd;ZI7XVol#w2n%e at jPkQi8R5M3N-L3#XqQ?r8!1h5W(=XRzDrfi&S2~%
zWyd^RgHFGq8si$}ZB(G!dk at 59x9x=Ayp`ptPX`uG-;V3Di^i(G&iPMhh$}iNpTp%8
z{xVDZ5G1@>Gyh>P5uM-n`*^O%tu76 at H#;!Hp4r2Le)T(>=~tJJ3C|pRxx`SM3Vu$?
zU0p4DENtuNl_#z0Pf(dD>ECVCeaB^)zE&uue5Qk=yH9ZG+_io6Kz6JiG?l*Zm53 at n
zOAir3m{lQMp=6HEQ*&F915eMHTg(d%?<goT=YbT8>g<d5<ZVt9Fu}vwmp?4N3Djj?
zBaUbghACUq!)244x(*Mmz2t4`O>cEPmKQJvdlmbg+Ea^SrCx4+P6t(;#ZjF$<P;X^
z1;0{nvx{DW?a19%ITJIxme;C1M~=ksaGI$>-yb+Wf6S{;s0Q7*a~o>vhrL at W*uq}D
z$K!V0>JnCej!!Xti<R3Rr5l_3<*uek1j6gI*kwfj<H+S>XTCkcb#{5+3K$a}WY%ry
zYlSg61mHg?d&01W`yUm^_&XO(zfF+6`Kv8inN*&->Gxd>J`=r?d$IDmfcDuN3fXPx
zB~1qEZ_7&zSk>`&$;P#sl~>;nqBOG0P(v3nMD*TmYwQjGUxLbOA!j{?Od!vpFOSad
z_=3O^=Q>m~4}7~0sfBumPp!ndC;VO+=I}r_79SaW<4msf`QtE?q|eXs+X^LsGIVhr
z43gWD;V#^tM?SQ_^_Jf=RbYi&HFlBoZMbb&{al<NS-O3et<|OzUfhk-yS4v67BuYa
z)A|^%n(5>-WEHkM!SoCVRC-mjOP;sf%WEx51C4p1@?m(Xi1Qm(!*@N04viU`S*GW>
z9UG19c(FWx at jmT)B{NN~O&nHtnDH;B{~QJmj~ydyfsl%raTOGsm*W0*a at 24Lw~u}c
z#yV|wd|XI<Uz|1?s at LqfX=?5gzJ5Wt$=6CuD|vIGEKOc`BT0?H;jzrCTz^^2!Y-yA
z7f`0G>utr}Upd^d-psH3>{sZyCdB;3 at 4uVz*PQosQFB_tQ9Wl#lZ?#UJHDf}nyBK#
zo*wz_!Ou at NTyZvG-gru48R8LX(r+XX$3_KWo$+H-$DtB~5QX2U#}jL>TKr9!^55Em
z-wd at 8_O3*R at KAXU?|n6po7O$52g>X-ln2mR7)lobf0+6(9FdF=ZYi6)SDSt0TAo8y
z%HE7U+guZOgxiness!&8q+I<m$#t8z%EjDwv<$@z at _AyQ*Pa61^f0f8ypPMqM!jVL
zHgu&o728Z{PA_{uL`&T at d(l?3E!AZ}>+p>d-x-@{blZUES_7Q1>23BLQplzH-;ZYu
z)+bYg5%kz;->Tax5*6RJz1^Y=$h&=R+9cC7Z0oXA at dlF?b~Uo+!jEXb<9UzV2VEZy
ztb9c0^=iDp*LoSt<Gi274(x4G*F9}SY$e`qyi6$fi2e_nd^q$`3{E_)ZTiDTt*%K5
z5aS(pGR=IC4}{9HK)V#vH(iQCX14SuZj#$odwnReS0|;IAF<Ht3Zo1RoZBcgh<g+p
zUvO&hXwZkc4-vjrd873=v6FgnN1;Oms&`$|{kp8qVou6lz(A=hQ)o7ji_D!m-~^@(
zYXfYoKu=B|S)%<Ip^P{lbE)tb-XnwgN$T+mvvJYC#DD0r7(B#@5>~#>f95PaRiRUN
zz<ns+ at pvNq*w(WruG<603nhtN5v<^XQKntW%o+4ghK2&$(N?NHD*<gPXMcR at GmGRG
zctryn6M+o!CMrZI4KFl|bm0-S<>K2fN8LV)HeGOaY;)wtqmKT3Uz{V^cfHhQ=$g{0
zq&KK{JjzT#RqP&EefV=*qG at Y6<M|#!&bsp@?5VGRBY18v(IW|)EB19()mP3d!{|q#
zfI2rcI?fOIMHqBgL=a2|rX2k?$xjRf?%KV<dw$J?bD8TGgueP>fAvr1z!Bkd2E9N2
zb7p8S*Qtj-Nx<v_<52#nKM58#^&yup7nz%BJXv}lpWUE;`#HEwkjt4cTJik7eWvKJ
z*3?;zj9Bk`emaWdY0_afoC_-N&Y4+huB=MaD)5I2qPlxX>NFn3ZPnd5Q+t9J=(RWA
zjIE~dg-<WKWGEC#J&JK&kcqd_INRBf)l18znVV%+dHt7KP5($EM$w#-b$d59 at 7hl0
z1=l+Fa?S+KoG*Of8DR%zWyA>|*Q~W5Ju!cGxUYYDKde5UvvXftXwLB$HSe(kgr2v<
z24v$^%eJiCmL$_vCbp9acc_A at h7FB&CV=l&dG at -xUtEYg6yBP`KbVoyZX+=YTaD^%
zdO}P7o~lszc1!et8Vo~C{$ImI^$Rp+0RZQnXQ)9^%eU>h540>#eQwc7m6dahZc~dw
zF(%ZGP<2kx62T$d<bYe-o*PT(DP|XI4#m8+|0u%)?(lfg`J#mi3NCcwoSD$8XgtLh
zVz at XL&hdX=Uc1+>)BGoE4XeidHj%_i`V#u}?{0Wn#oH1}`lUSK6p-hzE)Rdbv}Io%
zb-mWyh^#8EoaA77YIm-`y0W^=mSufbnPR#9u?zb$#{3p$#zSSH=CROl`M*JSL)#F_
ziYe?g*VEtzEzU*_>k#-?CA{lXEvMIcqj@>- at AW5Ew+|s_4|FUTE2C)#-Fyy=g96uM
z&0=)S=1c+e^L3eLR^#a_Ikdh1*9)MmfHm;{o%LsZrAw!9Y{xZ at ch7B;%Q7=xux=ZM
zPNOTm at OwI0;!Oj%g254|QOr1gZF#6M^q>UILqqcg59*M|F)!LMTz?-$X2NH_7@~V~
zO<zB4d`Qy1vzQdhX|`nS8V<;Q_jT5;-p*8o;T!MVz%pJN!x80?&-!i;s3U^q5dj(%
z?H~n+h6nv1%EG{T#{24oQ>3Fe+^UTn!A$4IndyNkz9=5P^nh9PC at 69jzit?1Ot3zg
zI;@LAW#<TgVYoASOWIyhWONwrjNS?-mwST#J2<I)gt$UmVIm>r=bx`W2<paZZG8Kw
z0!=yXQ6OJBG`Bd}JFC5VE<ET}rzCZxtIy=hU2c|VGb&eOcJ=D>w854A*-9wEW^4K2
zY|GDB<R@&WETczFd*l1KzZJt~q|bpC6oi1`uxcfE!megN)MxWB0^g1IKZ^)F?sJH6
z)2mQ}55dyiI03D?`S2iSK5BU}QJ^hXfpN=vY1j@`8?>L$IbZ^2Sw2|9&(2(8-2Hfe
zksra5^yUF;@`x(YFtBzL()m0o0Om#i?ncD=4v7-VRhH6;Y3^Ppv~@sf&qce1D8E at q
zl+SmFJ-NwGIKM)ZfI9_7*#H&56~{GH*8gKt0KyUXJJ<QQLCI2+^YDy!)9RSp at b%Qn
zd65cYI=qOdzFU78wAF;pDs-P-4%l`5Np7ybku%y~?cmv%I60v}*_r*(v#JKtt5PLp
z0ft3<Tv3+`PSqHvtrx~XE#}F^itQWy`avopQ=2|;vxHCnz+x7&>>1k%LJ2S4VRX^3
z7e?ho5fw)(3?M5pP at VCgOb|ep3QZk@)Fd)inRkkb$6w-#iK)F`f11GIhD=^SPdN_=
zfpXL=>2@>N<@<9KBm8_4AQBC<BsHP)2XOld<<I8}$q80@?A7B`YK|%6R`uq1I&9b)
z3`4jT+K^Rs3{_q}D1us!YapN((%GS)`(VqEKeS0^A0C&;6Nvp at 25uOhEx)5$3|i!9
zTAEi-hm22*WX9XvU{U at A2FLKQAOERhb-1`x+`6!D2WmUW5BO!&tl}<rODSv&^<8(X
z<@l5K=meiFWG|gO?WJ`8UGZQ@!k#0R96Oujp5#$0sPMJF1+(M4Q#L8>0`DCLW3&y8
zB3}u`U!ChJ(&R$~990jc_9dw)Bm5Ib9Y)oxZK6Ajh+tqEP)6=YUe$yBF>}rFJjuAF
z*1xLE_x_us15--yIAEE0Olv!7-IoSkIxGhq;1fv#($N6PGP;9vKSUlf1sj4a&>lPh
zdm>?*Uqi*Nr-5L&V3hKsly0L~Ly&Gi^wN58>E`!K?!rq+J=2T0!D-V6j)_^54v68e
zljv`Y)s>KkXEb`KV*($}_Is87srPF|%_aIt{@C2z*SmPm#1GJxHwtI9cha}wQeGu3
z2Mw(Hc=QmiX(~%UkBy6L`-N1ywK`NIN-h%FYo+<9K)tysGvrW1 at tS(*hC=zfS}Axs
zj}G`$rOh~SID8tV#bm;ZHw95(qOYdrsuZH4rF=)rF^JMJb`MIJXV=O=6!Zok90A1N
zP!8<*urGDkChzw#MDjH2!tZ9lWI=(72VIQsUt~08mbnQ9)uEH9fU+<IcM5?a;t6)A
z)ytFeK?c|fhXvzK9%~pYrYzllOyu#O?KOWJ<=Re*H~jz?rL0xY`6(ebESJ{;AE0>o
zw`?P&Hop7Q6>-Nu1!sQ)cgNSM>YACgEL5>>fupsnPd at W(Q(tvbXbOMkN57d}DM!B<
zIa)*0 at 4Xx%_q=BNeOl4pg`WE%9d0$wJG~~ICq+&pX8?h1l$(eT+)(iuRBUV#?(pQB
z&fTec0TJKnAyIj!IPC(cuN7zv1eYM~c>wh&gc?e!yo^{~<Mwk*APg&|qiJkWxe1*S
zVDlKzTdEJD84QJZ9Eq4pBMKZml3kqUUK+OzPfUp3W}OHKA_K)lqf~3{Vb22Z^QXK8
z2`Ci(FcUU>jmjoj9v{U(vWib4r4Uz|Y!j(DD>N&}-C<qzkyhnw$LxxiDFEaB`&5vi
z1U#u9`KsXBVz%Zm#&L1a{pIAv|CP!VHw{zQY96S6wgtCu6&4nTv$c&qg8|pBa=37<
zGVUA4AYMwjPseH1d5^MUg+2NoH1<&8;nD%4tsQi3`ZsIig4CM09{SDIa?WbE%PhOh
z0e9Z%?gdxd!&5wo1x1+_**ErO$AkcKUhsT*O<c`61YP{k3CQzIIOZ}EhP_3UApf)c
zs0_Ze$b$$WaEWi%{SYuA7BpMYlYPPI4kLV$^dOA-zOTV1k49}O-Cr_x2uzuo7dL|?
zvwg;+ at zlB<-3nUhh^l^lm|}tG{c`v at Q`n{6pBM5TW*QW$o(B;beS1^!g3uN5t at 4BA
zX;gIAkndSAq`p2>K4MKJOs-|nl;Y*fvoMZdRCRkF`q`PE*jK+TJYlcfpo}VQVU}Dz
z^>T4UyZ3Ukv{9`sRi~)dp8vECk9Dd*^+N9#m!2#m6#QYeonB|8nSG7RO$+2sz4I?C
z30j=$&kPa#pTm8<$IIv8Ny`IglUl20)JGgpoHLqlU?gxWOom0Chz}&oE>MCOb;ck@
zm%F?Fn4wX<%`RvuwmPVqI@<#yU%$Ll_`^ZVXbuUx{JCG>lmhDEX%{|alLT<98Su1$
zuv13Js2pP`5L#LQCrSSXs=$CT%Pu1|lBlY*CD6_jX|LtvBMYgOYbZr@^UR+Iu_aMC
z+jX%2kY5Tt5TcLN at gs(}##c6*eM!MPXbVRhm*;x=or$H`yW`;T#S07FwfxcKw7m|C
z=-y&<mZ1jf^~*pF7u%;YQI8m#>;CMCDKV{sl&1AUj7;jCy*a5Yb0TH8h*#l5=0t^e
zmdHs6xAdH%G<q5;OrOP(JWjqfBofySCxhOiUHZfXDc@|^^ZL*`DZjPL;}C;EiOnwV
z{%lVfo@{<WO^WUmB$S%)YOn#Zjw`DYhd;8z!ongNh7r~Q|4>}!J3QloA-%_u)7-f^
z at O1BYq6!2U1}ac<)5+27p`3BXgw;!cPt$f(WS>(3SQ97I9n1J%nrz1fj}9Kpnv=}V
z`wcpuYV1U=u8F6NZW~bWozYVF=f>A{@$)ohGrAf=&g=`Pq3Of!?rv+5#)?`>>82Ls
zJMKc`?-b~Kl&pcLQ}@}POe^-Sy%{qZSk3H^1l-j>2Ws!Y$V6 at _4C5!t8R4qw(gjhL
z_2VX`yv at aFG$TL?AO}ra?Y)nf?%|bl8lC?xLOwG98+I>LI{L&rD4OrYSuh!|UrO0q
z=do=Y(A1<yL?S)IlmViWJG1OE#~l=JLCHN_C_kxw{GC^^x6sSHPLyl7W-N7(e at m1I
zT1({v##wE_ovq^;NeEdg!8#DMWm<0>3G7t;4QQ9p6|O&*$@SL>u$ZE|D=Xdi`=A*a
z##0)fmCEXUVApZ@{?<cldPbsmHMuWaW7W;vHf{1X%yGxO+)=UC^P;`5N%O9jo|E+H
zw|N6kPiYu`@Gmxw1m$&!|5zbF*8t~5FYX4AYU3$Y2BVq>6t(N7=h at ltv~?x5>1uZ|
zbK+}5BN#%hWRyW$rvHnuWF}*DO7I^V4?JQ?a|}Mu*E<}~yX|vh)9jxhL#U8DE=wYg
z at y6f_+HLCpbxjo$x$B>)p at q6QxI}D-pOB+6{*O5Xh6LT2`oJ^%gXuMc5or;W7CR{n
zU==hQ$B)TxYC8Z-9vJob3)naF<4PM{=m15(s}RCWWY-6;X^C<FKa9AE)$cy78WIRC
z^Z*63EFSn>`AN9z07etOugRIGYwC#U6}7<lPn-kPLa$<@`mChVtimq<4-rpF=)L~!
z6he(bv*tWBg|kW;?=Z^}OAPv-cCB0nz=t><%%#tFH94g9DjqPuND0Lo<{~xZg6eem
zt($(IM$i`|G-|7b3!G3z{n;ddK6K}<y8pwLO|!)B)3%J!D7u<7Am25yN>gy~tjQ)h
z4s<91EFL%>Pa#ml-YT<5HAI#1+ at o196KdFEx6MQZT0(!QPL5>I5muUx^y!tF?{i%*
zHv3wxk-H<@40`#M2>{C#e0K3oXN^^VWk#lzW_%2)!{I^B0Bt}xQsZ;cG-iJkXEn;E
zj;h465*;h%uFG0P;D{cRBmh0ENkO`6mfa)=VIcs<P=zjE8v+DEaBzyNDfQpPkrGG+
z$evgIfa{iQWRJ3KO>Jw6y at yQXF<1g(R|n-;VB^LL%ufjpPev=2g6Afix5+o7b7H*0
zsYDN024P`BX-f1r9G^EvE7C9bP%di%p2k1C+g;OU6lfixegQ7x{|CFYJ39gi<s;=x
z{W0pDM-4cVKp1MZwp;khjeSU4Tc6LCtIM3NA}62F4&OTih`J~z)#v^iGj$mRhtr6&
z{UOe-*jtF?9<SC6+c?VW-Xqou3G%up{0Fu6E(|{R0;{of-DkI^|JZDgDu6?Nn*l_v
z=BbxRdKj+Ko6e_GluS#r1jeerQ;(_N|1_NF(JGXcF9b;0==<!h{M3LU0Ht#0uA3hF
zKoC}5<bvb%_zt-!U7`D$o_vflY-Q82!^0mjJpVX$t{Yv9q${!bJO17l063YY^pE~1
zWk_w5ulxb>l0wJLBp?RnmdY%Tjb_iMmcrA|y$lK(-dzRvYfj;QX}aSYO7~XFJ;Ij#
z(rJ!W76FK+et#2a)fqWG?Ewl7NTtgV;)@I`qesDtrqVyeD7`*V8yO+dkZ8&2R;S^n
zaxvA37^7Q7Q6+JagB{&@mTqDebS3Y~;U91COI{BxCz!2OoCD!DQRVppTy~~fld8MU
zj87mhDBqzfhj|MZB`Pl)=rYR+_gc5E^CPO=MaTu7t^-E)TFqv?mv8lY+8NzqGDp!o
zh_$JHbc3o$(ye^rqWTL17UfmCOIPo+PSt>+aH0SKX9@#_n`kDah(*Fk4c{gPV<4==
zxpAmWHI_Q$uXRN-m4FY at 1Y_vJS0IFiTudhT`8qT?K~UM$oofQ29_<dOPT<tx0G^F2
ze*0b6KfeHSitGmWkAgAOqz-zc&erq^!ky;7S+2#y*knNdkPp%u|M_kkQ$B at 6jGig?
zz`f?L{hG1 at IwCmi{G9kEq7sah-+Zs?1!H~P!Zlw|&kqok<iC}E(+3bDv70Dg%K;a+
zi1e22+xK0BJi<xXZFLoZY}43Mg!{W)>s at He()lk>vanqxJU>;Q91*lv5mb(;{<hAc
zWoT9g86;*2fi`O$dh5h)^PTic5un;LopDU_2-l58-0<1HfmOWaA1d?k;Dt{(ddO1j
zdeW{}r-XpRP;MBU at s5U@Jl{4mj#n at kg~I=y&q)SRIdWVmTo%HOjsy3~MvdwiErLMo
z8aWdhAMb$k at +xf`m`{RXpB(vw_HqV;(>=%?Pl5r7O4$%87OCbm1TwDHQvdvc5kc=y
zt0x|GFx$<Z_#Z;7J&!JI%>D{snG9TK1PV9*2 at pv?q83-~X7m9`y!S%$*S``F3SiPW
z)GgXKf=sKI4ZT8<)s{t4yL|5YvuZ~S>zzz;V9EEJawC7D8IfsMG``lTHy>?g#mPYF
z*PiWSe9-k`vaLACyZEp18Jp9&+ppbz_22U+j!sUU+%2*YO8=!UmGH;Le3LBQL>u)(
z#$g^y688z0O78MEWBG>LDl1og!U$SX46*Nz{kYc*aaIZOLZkN!20E4#e6mT>k>7q`
z9|!+kYsq-zkJamjDWZl&#&L%oRQPpnO1$}biC28<icY`IP0jSXJzvMpZRJF6UH$fb
z?b1{!^Y`pC^-?R0zxk;~qT(g8It_s96w5d#(18M;uvva8?{Qtn2vytA?Oew|>xd3f
z<dQ;RgC9(mJnR at t#I-?Te^%pN3GF}B%HS~t^(`k>Xpy^TMedAjG^h9gdYIS@{?|!8
zvYkQ|RS(unTurA~?rkF$Vg|Un5 at ij3<-8V8**+}kceYm}F#{tlND5~Bx~h5OLXnt3
zGKs4Flc9|vUrew?6TmmJW>w|$*LFahc{^L3P4dJL(rc5<OJ7i at Sc<<0?x&RR3tpvZ
zDC<`jZk4Mq%+1;Vk`Gr8HIC8gb}`EiroFlD8DP!GI)O*~t*)wYbUz1Q+IWzGe4~@0
z8W_BS*sw0y5oq)MWcF{_yZwhc^bfNglP-&NzI}Ft7}7S2)9dN|>}yhBXJgVdcjmRG
zY;=1=mRsa8{~V&CZT!#IH3%muYaOgL>+fF=GuDy9w+GH}7@?z;+LYU^hizgpCg5UP
z*#N#dFEY>AehZ?(0dYm6M1SGuE(sW9qJIizyzZo|1EN0LhJrbvPABq=9AFc9X#Hkj
zJ#9-dC$6~=oF2Z=rp*1WiNH+c*}lLab?AXyCkEO^FhB at ae4ytq%#se9vv4Aq{k#WW
z%a5cYGR9<cLJ~ukR at OIoYnwgvN0j0>{HVbUqvd6=QtKD+$E{!QM1!ba>??EfQNI-J
z7#l_wGWY#Z0F>OaxE69T_D&R^Utey&%Z-$To_ at FdSK~h~In2Lo8++tv3H9dZO&yHT
z$q=AA*V~QbTgL5I?rO-4`u*W*=L#?Il7Cm-+q<I#zM at eZ(Doq=78CrX&XTTwRp^Fz
z*)45#vGmrRAq=_Ad)0|zdD*HOW_^sQlx>G3E;c(2ijV!U&B9bI1PM^)WNqA{m)eV|
zlAA5|3Slt$m1B7!<`hPt_7Ll at VOSo8ntr~N#1qK1#VCG<!m{>o2Aejz+l%p9*9V9^
z(S=U(S9eERIU at L4eETV?Mw?`S)0NoBgvok>cdj4P*zyCL#s%veOYuuy7`G_`)M&Pi
z1e6R-RT3>$R3IyY at f#HhM{&zTr0acC(fkp$kyWR<87?<Zlundf4Syf*@SZ1w>0kFW
z=RseF)eNw;3GSLH%gORoznhnvX`r{J#p>)EF}TcZ<v&Z+1K!YsX=KjbEX{^Y{JHB>
zUTwcjep?k~pIf}AO&e`FBK5xhdS~yk3*+j$arU}rGYh|DYA@)_hrwE`a*QWGo7sfX
z-PfhSDsUk9CHw7uYX(R60KJR3`RuV7WsbODi@^o4I#_-l!mNkJ?{B>WmglwJt-$(p
zM9*tK4TX5=?shKNl9F)2HAtWa7~<_Z<fa>8g>pMh+$Izwd!>m+=BcEGIXrgTxt2?@
zcYd6L*-TnUjlqnMX$HGeJbeF3mXC1I2n&tgz(=gRc>!}vot4IFGBIz|BW-H=X3UQ^
zj9iLX*x<)F9yPw1)Az=3lx;jEqV4gfFOT{sOt1U57ww^A+t~bK3U_T|lI`*IQ1#UW
zee{7+1(A}tt|Oe!hiJ608p)LJ`z<55gqJAw!$Hvb{S~~tkCKOXxBuE(^o;W`mNK%I
z{rp(rAjD}i- at FG$i+- at l!koITXwwI6t}3vQF=Ax>S?l6TuRrVUFwRm?pjFOR{IFvJ
zJXZ0Z8}{egkOi=(fx3lMXP;i%HyGIvPH_Y#uJJGMP-^l)2^jI{))ziO)&P8kCTKry
zYHtaSW1^Xza!vA|soJ;(3k<<)*~<E|a#e1XDtDMxQzPJKb2DX3Ucl(*pFbDp^Ixe;
ziN1L?-X{_(+HSPe at yk-!FHToN&p5ANtbM+PbX>BXgdP`VO>~+`#tINRPADP}2t{92
zhYfQ9>bt%fgdsahn*Ow0S}d>pYw^Rk`YK$eY32UE{%*=o&*(&i#9&kgyaj)0W5gcM
z_<;>z92`qY*n6`46=vY+w#<E#a_!JpdP*~t_qM{K|KINTbiKBXS19=kb5;^=xN?E@
zHlXz4oUbKiq}-|>3Mw2ZHE6R)r9<s at vh6p8ZAvi{kv11te{Eg at +migZODvTn?p%Lj
z;sKvzT}<<2b%|J)V$3Bx&8fkiD1!FC6_XWfl56L2B7}{H#$yQaQCnpgoA{xJ%;ZNb
zeeviV%*`*U&II+dm>JKwg<sU at R>wAh^rD2>1pBd;uXaKL<qHmB at t8~2nO*i~RfpmY
z)~B8RT(j|E<%h7hh^%pS^|xko>wIHRKmOHfKNkx2aXeN%5 at WL6QGh-|QdQt1Qq|!(
zNlG^--W9ROw%Msj%C)8glEC&m4K`i)%3+{|Q-aM{`So5ud~8E4!HS$($?(FE576yX
zFmWqW;5jR52Aw>sE30Jbiv0q>LdrqCB$hHKq|O;c$MSEfv6^rV+EpdBzlQ!}qrc5&
z`L$ow&9IO8`4!3-xulngKGEp*=i%%X&hnb#4#es-Df@#{tloK&beMUb($2NKo~Ssz
z%!~2u@`AjyUG$g(Z)^HQ^F at w_m=S|GKUXBgvX7oV9IVHD7R%P2TL(ddF=_^ns&O>M
zS$%G$iU)2_C*?J)s152woGHclf74#3QX)Xe{CMJy4Ij(p%7zmo)a?@Ip^yp1INL1&
zV?Lsm)C~3f)-1w|%eYqRvpPoAst&PK=yjOUgNpQ0o{es8j8 at 00q{lSL?+ozFpISs&
zzU;s#Om6>F_&>`4!R1tPUOUA=GGgN%CWB5VQY+-IHtw`+go3F&wpgq$aLgKtSGzrg
zr-%486Ov>*)G_FRT%s|)<x<pb1A<9gdRy?_k_n$)(8+aS-6)|ke4olU`||@2)P;*Q
zgpo~N_fB%+>*pmVe{$6Gui7A?p4xqf9Z#~5C+Q<*EOfuNqeZLNpRkHUB9$!=w$co4
z`1(`Sck at KdXfCXHSTi7jGWU@qN;$gSOK5 at tREHYH(mNZNslW+GA(l$Y7VvE&Bzh_S
zdwDyFs(!vMjDbE1K1J?jd*r(#YJ!Ye`C;r at x55Smmajq$R`C8VgFCOcBfmm&K()-4
zTPio%_Wj?pGAWif at 0^*Q4abnw{Wp4N-XAs2xtqas(W&`x&6}lyG^GHArN5cM-x;8!
zm=JY+Z%EyVNbiLC=XrwTPJcdWXY}5^QLdlpVT~+xe=0|!N}7-s96c at S7UU4gHF_-R
zXl&K1UGgDPu`)vtJGQ{l;Vp^k^e`JphR&ThdlV|_GB>gx3VX<G|6!arDDK4ut}pMe
z+h?kRZFMfj#9Dn2eKOe7n72c%W>o=0b`xBaXEpg`0wE>1W3i&?FK}SM%hy&7{Q)wm
zw98Ui`R;ZpmG?I62%(i#zqOa48Q1%A{TxT7r%LtU%WhG8+A()BCw7jV&vcwEO~;hz
z8X4?_4nKBi_^xT%(e>0qGL}EGxwmaj)P%UXDypJ&fYVGQM}7ewILlGW^jJX6p|JI{
z4l5 at 2YTHYw3ZM33MvJo5PRsQ|YT<GXkc3}7P(&l{64du3gQ at h&#IUP}(*%DdQ^|O7
zS<OAH4&1viHM0`@sQZ>10sn$As(FF+ at iABZ^$76K3buj$Ku#s6(4jEku3)Vmt{HPY
zU4AncZkYXDr9vshnD|5#fp)2J(n2cu1+(!`ITmCQrCgMV$US=@Aj?}>W{~!2J=-Lw
z5xqbsey%)<M=Od-8ozE$(2x%+OCcE;pO6=h%s|TO7SRbrp|e2uc=;D*;m;bP%j{#s
zip_rQH7$crKR%k~F8nR^VW^i5xxEiD0Nxw7`6wf=m^wZ_euGuE>$@4NDN_JEb^EI)
zz{U<uI)NZU>NbPPg&&=B5jab*W3i`(%Rvm+8 at DK>x?D~qQgeIy@&=oZ_kbAV^k0M~
zAM4{8oxCIQ!2bL`2o~jGhC~Wb1hZe?<Qxc29&i-Kkp)8hU4_~Rj4#{diX6zMam*E(
z8l}8#=;2AHB5fe|a1BnB+hdx)ju%8D02 at 0Gt4*#!j8zGYRS7o)$%RVkCE{rMDePXw
zO8tp5v;~1wrG|u760B2gFOY&ULoTVS*SderKDN_=YjW at E$QiC0 at kx7eki`D05m<JP
za!14J>nHvK at 3|sjn0 at kAXoA<=x-b%aUxmlh6_gPgh_rF%^V at -J;}r7-Pna>qm1eAB
zeDmE2evHut23mmPYt1UVD;>hA0LIKE!O??kVg%-|e;X8Y#b8A&{$h<j>*KqXFh)}=
zne%tbiH$a6eY`as4^(bBxE}H;2z%zQQNYJrrj1f8Pc;t^soJP at GX~mtQ}IFh948S0
zWC33*4-G}|L(<wycvStK$4T(I&7XC#1aBIM4;zc4 at 12-^vXU|L>Zz8H)rm&W!A$!3
z6Pe5Gk~{J?6c1h=8tss?4(iN##MgOaJ((BW(FreM^sug7j$_JbomrZoTDXGm0Zz6k
z{@#^9+KISGm0NWJCSn`y#XPz$!JU-3?rET=;=wH?S{F(>AiayWAR8FUr8A-R*?QsH
zPD+CEJKKIpqUWEQKMBiYK6hByW?~o{u^7R^+boaeZ5TzGNc92Wq^%$2wEw(!V4QSo
zwlA>sx04-dqk<WFDZ#=XY=~(y#<=K8q}B)e>$xHV#wL5{q4mF%0BpiGo}xAgWO-Tt
z2}CwK+xY;=(M!{^Ef~?Qwn?q&+~K2;pznTQCe%Ld25*O>Lc$xL;_?rouPHfnPVdh!
z{L5UQm+fPZV%o<(Hmyrukr8aqrdtRw7b1P)`S6DE*Po1g1<Sb?HME!DZBm^PLQCx=
zJa1n6;mz|P`0kp>1v2G5nA8b9a>me?MwW6)*bF+b2S{-fF|iNBivQOOu(mMRw0{mP
z*zG#IQ*~1&SA5Nhc%NWeC4HodV#)0+Kq171^R7KHH+z-D*E~=P+`)z#6CJCvgaV1;
zLMpHY3xQGFP|T^ZP&V`Aa>cmj*dtZS=g-;R;HeeaBw*B~R>_8MO^(}~6usJb&Qrh0
zr*c at 4(oNfcs`<8UUVq|^)_pQk@$J1DiZM;HS8UPNg1;nDY%k*DoMgVRhi^F!10X=W
zeO8Xl#C$qm^JYfYjo|fB04%^jEc$UjWlm<CbIUXp<mcB^hakgU$Yn$8EMNgnc?`4=
zQ_pr!;=3$w*5C4qSC~^Hq^%)%bafN>C(ak7c~pRHGb9mQ(pi4{_K~6nuX`_PWe0Y(
zfZR8tTA!8ll2a^8U!b)@VUM~0KmRtw-YRV1#36uk9~i5v!LAq;n1{{z3i_oqkBp2g
zUWsTP1=p6EYWDnI9{uy at p<1`;(=>WO^|uoKqtEq0ceKli=H}*Z4j28VQM%nhUAWm%
z;dMqv20vcMbb^UTD36QoEOFL}&O6tUZ<6!X?$Y~}OEp8Gu at ZA|nBy;%9f(7FoX;(R
zr1jU=PtQjl?g_S5X^sgOl%JINr0Z5SaU2o<V<Gc4htZ at vTNI6ntILbS7noA)m2b7K
zOHw=@&j8W#Cnp|*P_6TVM@@)W#LGuzn8yMGei+k#36drak{t$VnenzXOdS3fAG4`;
zEwUA=`8XqqY4~bq&AK>J1+zK`?-V2me9c2pPE)(+MP0X*Z~tOW%TJCQAx0Cdvh1-@
zVEK4Fz7z&0E5Ow3MJwE}6O{5>*s>02z8 at _9!lQ<;UsO3M<r5Z8!NI{<Dxbif|2=xJ
zuGG<d`KyoVfsstQE28 at IY+~LeAmbRr!}yt*nfLnQy=)!U1QLk&1P5Z9q*(y^#1R5@
z92x$JV}B)R;N-q>YtQd~@<w-t^2VJ4g!YX+>{wMVt9P0yDFa{p&iED*9xbYT^ui~;
zTo;{yF}W0fmoJj9Uum3=DZcxte?P at iH+9Qwa9nhCjZLIVRvsLmF#!qNP at NnJ$Qoeq
zCx+}#vN{&}*+hJUlI`CAMalEYwS#CP=Dnv3nMz8w#Uj4Dmv%tyKmP?L(mL44RI^{2
z7OsfYPwPs`NEzjr+MK(Ry`r}^-%z4dp1~P(C&d0kA7RtH{w&cO69439!tZY`m$P1k
z|4MMJv?_oU1ropQ5BwBVs~LE<omBpEuIgT`Hh*_})54uQkF9-A<c-I_4nd*`?Ozva
zVUUaMePql+LMh)d4a5Z}oRDlU#IDP?{R)A!HonoT>>}l_*AF#hEau;Vj~l`1J=d$8
zmtBhYQ3;*~Dq#g219Z0UESF{>cOQOENz>Hx5R$FmSq=>1!WMA-ryBp}{d$_;)*4_9
z60^D}Kg;qoaiP`6i7l^w(RL)T^>*`O8m<7vl2z0$LS){Pjn6JRSSZ0D*m+5??n=h0
zsHv${UN(Ioo9vu(9C?afcX(7%r6nf+yvN(CK_5E=&o7<A1RF$EoTrxUQ}aG5eCvR1
z0LTk~AjZEV0ZnOrn+80cO|3K#<B7l_RrqeUml$OC`sGmOUU#b3uT_1V1_ at M2fZfTC
zRc&~5)5SQx3llBME_DAFDM3UxIjB_B1LdfA+pv&2f|YJ8>4t@^dvL~cFCkW!MYf$6
zxYodFaC~B7B6ASLwCHEU*67UzR40$=Gfho2>yKA5;^f}MH=q9G-jy`XL@}E#JhhB7
z2-J6brk<dm<)xiFSN|;FBy(0TQvpR2=nOC8{YmZM9Gln5{<D7f at -2=3un!IGdnB|c
zj|DtVR=MRGNOvop<Vb`ZJovu;$pD87vX)-D>EWAOSARd1CiC#^mPpG~KU><$y$05x
z=0O{T*BKq69OZq-u5TU?eGFVx@#w=S9JvLOyc@^V(TqMlDW|6VbH{{+>2QijG-gjo
zUElusp^i$Nn$f~65(tmq at rm9tWS$M<HfZ7BVZ~n#pQ>^_KM=|l>`;pFlY3}{*HMtv
zhOHa_i&e5nh{of=0+M2S=;L}f$Xo<bBstrvixH((1+g@$I%{I>SacAOSIrhhZlI}E
zT)f at ku^uHL7DtwjDDcl7PbPRRh#2aF!zT7zf8JmyThC{f)QNu#4pyY!pd{-DsKJFj
zP~NZ5_D(ztZTxLr0ca>c9Ecq5h)0fq{Ynd)%NhDl)i{N%SgJkwxpo6HNBF)jzBy*Q
zdA??SzMa8fyc&6^Qr(q9ES0^W>*AN9TR9xzR;m`bFIS!Wy~C99V_zp<to*i#Ym>{a
zuuOfNnz&^gHGJCXp at 4z^pucs-C45VaUCWap*ED){L(b9raZVuRKwnBH@#Hy13 at xaq
zRwkQil5e>u at pnHeSKq+CEAI9EFW4emFEw`9{^z;#As3RpY%VvCx;qxJvr-Lab{aQd
z4|Z;@x22J!)sj0Cy7N8T`@7F17_!CNNv;lQ%LC=z!M{y+d!z0SNqr%<XDb>cd+Q~(
zryVHF!D&5~R+`|h&dtp&vi+PFEro3Ju;Fk97XMvhW4LjLN?a!i&b?UwBX7%`()}B^
zo)3v~yhNn3iyPJcA5GW&NcH#sO9_#^iOg$7BI}CCCF|ORi|k0a*0q(9J at 1uyscT##
zgtEumUb(VD#x*Y29v9hs at 8^f_AMm>OyzV{cxgO)N)F7>=_Ds=3SFw3Hdv`_~e<KTa
zl9H3r%Az0y;##TMClI{t87G$&{&~PJGEit~;uJz{ef?@=^5C4>ImHJ4-oLV;`&US*
z{hzDGq5O?DT!50v<M9&{qqq*EJw2glx2`Fs%cEvS&Zv8 at Qk{?I967GsRpouaM{~zb
zdBBjySyO0aT7H5(rZw$7IaBI$7HAbhZoM|8r5uZ%TGeylh?CP#iH3pmA5V7pgcWwb
zkZdw6)v=kn7{?OB1HW3oZBUbUWXJaxtMcRcL(cHJ(V)?(rY3~<!wLBe2@@(VVkdM`
zP&J8MZlmp$JhyOv<$V3J^mTsQ#a7#_=2<LOb3u4bBe!Aw$_H?!aFs|8-c=p-W~GiM
zYKUM(r^qF7#03AyVTS8Zb`1>;sWZyGA8pO~mNN!z2)t^c$GmNR!#-pkywNE6zd&td
zvklX#Gm)|xiK}|&Qh-VC8WK$(l>RhSrzqQG)FhS03SLznwDrNij#+OdPyPHp6L{YE
zdqfH>d9&2%9{ssG_VIw at s>XTS0*=`XejNuh#9Co(+UBkv9NMjZ0~vHzg&vom;=``-
zr}KNECw3zVp&P_v(A0J;b<K;zc8i*Z2AvU6C>YXDEEGyt`iXP*x;hO1im}fd9#o_`
z%cCLU-JGMhiBUD1>pL;xz$Z3dl#M?UTl81VOGUk_pC#7YDC?^HfG;hN?%!%sjOci?
zw%5|HC1zYP*dglwR#9k{5hVHZ!SRpdfTO1H#x&o**0Islr^Lst7l=u`6#lEmEwI#q
z!<YXk_h(DVr0cL4D2<Oeb}?e2xJNFZz2wO{?Bt#8Um9b-%+rU<Bp8-T6XAeAS#q4*
z+#_;MGoPZZ at Sn>b;Xb9743D7WzvYiQK{Dw0?;%(X=8=J|T*TNJ!NFv}m;!(gObiU%
z=H}-9U&**2rDTQ_6^=y^^Z(pjuJGph)%7ouZxt04S-`KrExc*|-s0jL*D2$VxsF7o
zP64l(GbAcudx=s)qhRz1ybn$Vp!U}IUkNblFyg9w){>KwoW6wa_yyf-4h{}h9RIcM
zqcC2Wbgflq at U`G%-LKhbR&vA6uB%puR7l===Ck(nkwSj?f`)U$)Ru1FrIzB61#wlO
zGJ=PJ$b74+z3pus29a~V=iFy at S9*2h=5UYS@{>qJg|B;5;~(eG?W3@%MpRRBwy79>
zmRiyMH@?hleWwuC%a#VSTm#R~IJ8?45M9fY8Hdp%cD)D3;a=-7&W8_m+ne3Wy$eoG
zrds8{1eJW^<cSpt#c8hwF`^xe1QP<?=iOmV+MTfjBA&+=j1jBlM@^Uqwqi}P(b3UH
zVP8pdDc%u3&hMLWLAjzD;d|T?@r{cO_-($uu8?{Z)?NF}S;(><yDq;G;-G!bcc#Vk
zme`^Q_72t6aIB<YCNUTcRW7k4yZO~<8<Bh+`9S`Reg-_ES~of~c}TcazffZh3TQLI
z8GKA`%(oLd%vUdvd=4X!B}ln(;R3jbi|Zw${fw3?lryX_MPqgGd3z(Qk1u|6ANbD8
z{~buzTwOWJ3b=<bqjy)IEqP_+MZ9+^kBAx_OmGWhzJHl)Tt==n{%<oM++O$&Z?{b?
z<+OmM5q)ja&(I6X0?c2+a)?#n66p$K`j{c<Q;si$RpM;Z0%!1CpSZ-0<3OqVK7$YN
zUQRfE`A&ljeVf<aoNTW(Q^n)I`yZx-m?UlgD1Bw?D1siz&scj_F3&`nbPQ);AS0IT
zx*Bh`cWXpgD)p2{x{(i!*>WR=<VpO*)}Rj^xb5UZL^=xN9zt#c{2ZcmogB9t-pwTD
zKqu3kopX)Id<Sqk={`@)&Cv1G))bl4&1oF+bgeASkI#X?F9;{ZV<F}Ky-H{F<7x%V
zg=+oVzfSao^L{JUJb;V)WgMSLZybU%I4RM&oB#R)$}PJFxc4G=6X>6Zzy$t at sUfC?
zc?6X*=4}NWx4&)S9f5we#~1R$W8ThQrMFVk%!+pm{X>zWekfyp0z}^?pQ1?NZxY*y
zqty|>XU&zWKYzV>V`l$k2qpyG->p^x!UICoMP7->?L*||Uc9z_E{hZujMP~R8S8av
z#I!IN`-(eQBA at +LZ~F|gM~`P^{VhA-yBR=5W9RRb-iKVb?B*)vuuBB)9%+Pkeg9ZY
z0(bs9P at 6>c<~uG at _GfK41<#pEWZ)B-_2w<?1jIWmjo9hu3u&VJBh$ovk-qNc<eR=s
zDRJI4(d-iEvIlaAyTZ^#?^T51wQ8M`oLr`SU)-od(9us3<D-R at 1AmK1ufc(h2DiS~
z-6UB^?}7a^z5<FLmqnLMIi`^s8?D0fL$Q=0!tdeu05=bhk?uE4{pU(zUmikvXQg&U
zFx9MYo{q3q;ouaaz?D+cw!Ay*kP9^s=*v*Y1%L9m$Gki^GhI&@BMD;^(^Gm8g$T9Y
zldvSrt^2xH0gScJ9^^1&A8nj9J&CuAD+ZnK5 at fUW`*+>wDP_>!+RfuwPc0E(?dueY
zd18!Oka+g;Oe4|yc~wM2#KuEYBi+58-sH<qL&{R^F4FAdK;azy^$*WpZbF3biL&6b
zoDW~@X}iOT=^AMCYyG>CdJ;vcHQ+KXdt^v`*Nc%_;|)G{lk!{B at z-a(_NbNgBCZCJ
zm-jRtpBR`7R!dh0pI>_IM<$KZH3UEUYANC{-6}8<A)?F)lsb6h46%9 at GD2(~YR5a5
z?pK1qoCWl%8EFD%+R^D&FVg0XZMSNDn&-1pTbqKL<`h`Y>k(9y<)QvOD*ktXx#zn+
zi`)FkeJgAY5xJQd-TQo-^Y#iVY5YvVZ2uWQ5<M+^Bd)+FqJM0iO|{WXx7l&)5xQ$N
z$m=vx!vH<sEU6W@&hHC=j2T5GwE at w(IEC*q+E5<p^c16vI9|9_bn%9~YjzP{j0{NQ
zzLEP}_pLd9F{1ux=5EiIaYq(CJO%(2b7*M(pl>{*9z}j9vaPBsI7 at E5xjN;bl{(V7
zTDu}ln{IjLqmf<5q9E|h{q|q=5iOW{BL8{0 at xcgCc(z=-YOw_PHPZOs at 5Yr81`__+
zjf<^XIuX^9vc30Ts(c*9qi^X7!n4*QhWxy%!m+~jj{)pj+a|b!X1X;LP&+fhI)mGJ
zT(fS}+v%fd*w>rSkb4Vk%wRFhs`iXqVbv;_>fF_@%ZT=EYsMb;SR<6 at ZZFT8#E*wN
zE4qL+<zIBH_{^KrLfw;u{P`YbMe1rwaHho4O0L}?_h5dZpOmEf2z;if9r~JU$w+5y
zhRTsn2w3>VHv3bxWY?TtqTO>!JQ8Zx6`Aqlj!cKo+9ao^zq}2g+x%6LajFJ?O4|i7
zJ%4;x)32>UjkE-*QBXRpO%hlRv+sy=p)~n&XcQvCCsS)iU4Irs|C1NXrezr08Jns}
z6#PhSJ~6U!mEKo$X;l`BJU7x^Dvq7B$HySO^A(7Y<$EE=$zPFhMOwcma*ao@@PUS0
zAs$tqeWm5GEor&tuI_tV%^N5Y9s!xxD=)7&D9j@#q5Sz4#XXUx8Pg0jcF9bf1LOK1
z-k^nj4b1z00o|JVYmnl+EMmgdZ^mk0<=Y?&13XEW-_4|cfjfo|+Wi+VClIA0W_$~+
zuu>y&=hj0Cw1L)XrhbigC2#y~wUH3(k3);uj^_V6*>|OMRnF#*4~fI!zwbv!4i5ti
zd);Z_Az;$!+m5$*WTxexFw)p|mM&`a=NA_$u!xlzB1=GXLgySF)N%klSkiSYTn21D
z<8Ql<yVwG!Dt8wq`Uhu(3sfZzG?7FOt#4xF-I9z*&MBX<95v&H9=Z=W*eF*uKeEx8
z-ICved>`$S(#x`%*XWEz7$1N)eVI=PR^fW1W+Jgf at AEVq@NxeD!`v7;SLcsWENOF(
zTW-n4uhQEb?hD`TQvo)+x_nv#B1`sNiT<I4-f20_XDkT0 at 3SIdU%S<bR>h&<ssT%H
zM~R-tx`d;P*I#PR7B6{1VfX<rt+Kt(;mXww_(Cu?QTJi5FtbALH_4?5*ot$;`^&k_
zu(l$|^=}rI8Ut;~TdF4b0Y8RwOk_G~4SNOdRuIq1^@j(~+A2o|G4gc6dEXe6FpyMQ
zN3WO-iL7^qs;@^DGE^083`USdZucZkDv*<JPlr at 2UOE&;NM=Mc7Gz;dQndxdlMitH
zr!W|~6k2nRM$_h(Tp at 27?9=ca-YmJE$wo#Eb*0YtD{ZD&<Q#O3<5xUI>K`O(nccnt
z^UVAFDTDg*4<t^AH9kD69n(d0rOYiz69fk{o)WvNd#qeS)^0X&g+tv$cltq{LI3IL
z#L+wamzorSa`!|Qwij|%C<bG?zCj}zor2J$sPyk?tgmvP#(roK<2NsR#c!jsx7v}_
z0Ux+*ai<zU^Z$^topc;qhrf1^XM6rmz%384kxPsDlB%Fw-hJyej?PP{rEMYNqs{y~
z;tCdzLO4nI=ahL~D54{8r5=98_wq-N3n4kc%dh+WPcry|lF~JccYGA2KzZ2=oZ90u
zb0xnVtm|;z$C2qqr1 at SVFV?+<I!vJh|K%x+XEP5JyXB_btORj8$m-Uf&O-|Fx}60C
zsq~4(*|@V+`J~gEC&ut4b(hf4dyjneDU80Rgs1s-6yH5`?9|x(04T&@<&~6_Ud8}2
zJ{Cfm6||m`n=PtJUnN|oUfv5Zu1UlsDtysV749gFG=b at Nz^&wDOoixGgviiSm+qKj
zpHVizNEuIY?Xn$74N|FUIaAN=^{ragH{%-rY^nZ5n&>~sr>$*#)Lu!Fjf9>{W!N$0
zE$kuknpuc9)I>`S-}b8Q_I*Tnk at AwBKq30MDx;O?aKZ_{ao_=QO(?$R3Sr<;C1&Jo
z+Vk#D5VA9|&gSC~(kr{%<!;mO3WSGj5fq64>HOh4G7`ZGddoj{8Lx8aO?xR at SyD;G
zJ{$*7WE7G|y+p`&6vssBJtW6Fywt;*QAm6}j*|~>s_CEm`!_p}V!>P{a0d4W&*z*D
zOB&~odsuY&03CU`s}P@)lQZt!<=wG%`_N%Q{@m`l+1k9CR_e$r8@=h=N565yPd)xL
zE- at k?{AV0UZm$*ueCTALQusEdS057IH&S^CYR^BhYRqq|C;pSP#sU2?kNxB#V7ITd
zB?DkW<kel_N!7ERg9Zaiz%63|zNwEi-5Rx8zs!B%YQlVF_8pjD*DT`wnt~&d)hYVm
zr<_3ic8bV;t<W}ccXXs0k)~Z)+3D@=X{R3 at Cf!t+mOCrh3d`MXPT~JCK2W+pKAi<t
z?+D))^7A;h3J~{qH;ldAH at K<D at KOuKgJ!({NT=y&t|#it-*js;UQI$3fQ#QZK35B{
zj<o{ok9?ZvwDPfwFI_}f+*Oyn<$Eyg>tOfatpZ*Q%QRiH*z8v8g!z>Bn-lY-smapy
zC!~E22jEVH$z?TZoVTF0^>s`X4f0F*jHY6 at 27&sak*sBhK`iA6QXw~YI>iQe5zT4c
z;}8#$09xg)e?L%_yF2nx+t16Psu(U?!K(OtiHQQPC9hO%J2iR+Qh=p_1Q4H}*a`er
zdJa&^OKUjNNO(zj-Zs^NE<6wDeJ1c@?$a<y#+=ysojA4culR%^-44v{N>+FhIs9Gv
zaD=NC#hSMNJ$pI$J!TR&nLsK*e3WxGUNEZc5gOcP97UT$*5Vx*&5*ZB%inn((>GNp
zA at F_4Q<s^9y35yqJw*1twZ3AsuIN=Lh1(N005)a>X+$~Vu~u3)W(NFamY<K;g8mvw
z6ooZzW)aAq@%A$;sj1<?1K*b&?+=!#b_Z0RhbXYPn#RF3#_F%zvrUOhYaDAdt<4xF
z{Th;a=M;fRG+PiB at usU*-IX=qP`jWl#Rb_Rw&>U%%?@$zV<c(tK6$x{tA4ocQVQ^m
zCLIO7*gLz3b$Fv`G1E=Q6SXo}kXtFGY<Imlq#96c_1L30GqsD)1$g{|`~bS4E+D9b
zv9eBK>EX^KxdmKldi%dKCAZ!hn=g>@@%0P(UjNKkO*5VsZ`u16s6vf-R+e8XXcCfr
zTo4nU_ftE$80-ffklm{Y25&JQM=yK`tWRZZK=>eK$AN=;SVZ5Oy{ODQ>BC*4jJ&nC
zh(ay=%_)hZU05TPHrA}pw?)Y|;IgHA%23=G)@ch94p0T$Hx!7`OijK#gE(?%xzqn!
z8;cXRtNFsYZC!h at GK-S0^Rv#;mN;)5SNo(Dh!N#e>o0n9tdP&aU at B-5X;W>qnwFny
z_w?%o%w9IT&h|FZIAYm`I?qaxKL2=z;`mVl5rR^E?vL*uCJ2|%lf{MYgA19f2W9Th
z5h~8z6^xAA4OR0k{=OP})@UN)5bSYBnWMSS_-<OVgQ{*6KOQMhrk?33$W{3n(9ipo
zJ$L%tP=h%(SH^%hbKD2a)Gt9;{3Qnxzhi$pq~c{Cr`Ica6EBD9|4_=m8||h31D0Sk
za6kGoR56x=B~oSH9kKUET6PinlvgcXyX)m4c+#Z}MBHj293O6{!N_vJL`9wN^^v+)
zvQv^`%gC^QqyECquip1_qf)2*leWExA>xF77>~h at co#`kouDJXQ`YZ8HgC4(=qd-W
zdp+%8Ff)uHUlxc9An0bA_EJYqFy~2&ky{$j78xJ`kjc9^W4|TRMl_}*{1Q(e0j690
z8&I!dX<)qk`X0wn0#>X#HRDlj`^xUFrmJ5Fx{iyh`}N-HPY%Rj<oPiq08P#fBY!5$
z#26}9;8Z;LTjJ at G5oa|WFT!!g`2HW00rKYsMh=E*X##g10nIBV^-P|2_HtVO3gOZb
zGh`=3hMrAlAO*N%y`4$r<+}ZA^bIsVLhkz+H!?&ZMYPNgQHQ+eet}jF4_~Ft2h&h7
zfaM_>+Ya at hpf{Ni%BSn#Unl>0W`jsrCCY}7hCd^I%LqaPWyC%D7qvmM_w;lhG*op}
zcj at fo?uM{v#Rc_*JgThPo456<m9v9AQ>4iY|7<Wn2tQ*S7=zAKI=rmBgC>cTqNUkW
zq?^LxrM0MGT%0^T3}2-SFoPW(9SQF#9*-lJ9u`xH10DJChCLeBk*<D-i-{XElpgpY
zjNyqeVYdp9uvu2hAP}|$S3DD)hjtnxGCj4*7NztWqDItXqgKxF at 6l+(uV3uj#Eh*J
z1%~pB1L$NqsnJRp7}7KP0f^UsH}m_LU*x`i<-B}QZs;K-b?ZN15%ATdB;iG-Phqg6
z<j&=lcmT!)vFE$bD!$<|6U*>s-i5#xusi*OHz5j|0*h;2lcUh-crB-EXSn7NER*Oj
zz80JO9r#VI5NJ-Eg3vl)N%5R)e$htbB?zGh25fHAqwS@&U^(G1?tCESLp)N_wlL*3
z2RFv?QK_YKHi+wNTv$2 at W1<xj2i3<WBVnV=!DAXXD{V?Yn>7cT;-v5QJo!ZbzCf^k
z7agiJ$+@^7jCx;Esfqi*Vkle*_<ESI<R<8PUnFcNiux=?TuC)dtwxDdnzL+>R|ktU
zQUVu{mmglm6IQ9Y at ofKEO^(bGUW%9N3Vrh)LI>0*fAk+E2fR6{Hx}tR7`4^uUFok;
z)LQj&^Odnz%v0MqB5b~FY^kBDBrC&Z+uh!dtiGd7FMzcfh at eg|yFwsw*LMWpBZwZ_
znXtC3lylURR`76u%dah-0Zox=W*;3E6PjPp`ADf0%ddA-in#JmQ(ms5khu1Ge?{by
zzaL6%4KHU1lTS1Gx>5rV+|?24F?o}UpSDwwAIxgnaRHKg`Q`h9jUCQAbqFtfpwfO$
zeIGTm;$B?Ia?Rbl3dNZ-uN-JP7mU7DFJ(+cs>V}OQ`;$86+er$uyU0QAij;9VpQYz
z-%EZj0)kC_bMh}|w3+P`VGFkf+<vd7H%=JfRUfka{nQa{73?}+o6>*C(4bp8sT6Rd
z7>|mPB3=({EfN>g)m1?39ko$X!iTM9UTH+g8`aO3<6uzk at rz%ilR0CkC<YbdT5%oz
zQZ7raN;yU>N3EMu)$^7&rZ54U<Au&u*iUGFq24?nM`Bb`P_PnXC>+O|?B-<$yl2+&
zda%gw=sdzj6*&7kw!cQxVJ1E*D?lbz(=TooQ`3LAeKhk7^I`;IkaVfV{Is$Ty|_6x
zfom~%5y3zwsEZ>*2CfMa6sc*FQ+_2Ej84Z0r8}Q0<5C+DS4&Ira<Wln;9f~~U6c at k
zIA`kyz-|7Y3y{<jBlW}{yk$sH-Ilyd+T1)huV!vxhILqZ*`5<i#&Bn++}5B-^~1b<
z8TKJ3=daU+35<lG?ZUo&E+^GJDVU)VDM}{zfG3AWoJTB)Y{@{8!x)dt<J%Rnz4O0P
z4qoWbt0+6;z)9q8Qa0-xT?aBpsN5Vu@(B8I4D04}MQnMMFS%w4?Q)NWi}ktryWx}_
znU8F?NuTlzxBX6wy5C5Rv03AK4o;r_&BvYkTXIc9Yc2NA*Y^W6EBq;AD+(;xe?4iq
zY%ywwo{6{QVF`RKBbAi{oG(UV85{uJ7cdytyGBS}uP}=Q&t(oQ+z5<sbs7HPT at G>3
zj^c`cp>grbH=Qtqv!bZ(<Q<(#YFMN>w9qJA2iJHKSZy2uMl}D48hMe%p<=AVXjivg
zF7Y>q0S-Wq?wjLs8}-nAm&;l1po3BDwf*)VwO$DnM5M>5`5}m|_NhCaL8URu&`D#N
z|53hAO<ez>IYrxq`<*IG17lo)RfjqeqVs`$q~<{K14|ZGjQ|PYM58;ZUDG?ZA5tQw
z at Yvbe96^O#)6{j1r)@*)3Jdu)+2WEqCeo at ZkmYHLofb|-mbp>BZ_3T`kOeivx~&zs
z at vwWXTe<j$^1IN+FWwH9s9N$#nDYk|bxWM&QkyWTHlV0m)gQL(EUz%xxXG;;=dm{*
zuh9pec9SirJG8xAZq>ZJXb)k#GE~#KN0<2SU`fM6<KJm$@Kif<`}HxIfr3Bn&ECz4
zi_i6LSTA<lUCp}t2m*D!XA&FCKZ0cD{gPJS>#Z%IVi#|<6E)9%k5+(5EEj^ANcSUh
zG=<Xbf-kLtug|*PhMdNq_B1y`iSWk?mixzYMwmBHrfjkVtg#6~3>B>_-SAxdx3h4E
zo;povgBU@=e=AH8qLV@(BE`24TF)`*DnL*~LBxBAqw9 at _vHkJ9pIWVr%hO{F<u?x$
zulHwYMjNh at 4`B5<X#A#})~Xf`q$Uu=o_{%YQhl~Nvh2KP6R)!OWcT`78Fjv(+--d=
z*LLwwg-R=tc!>T6)i3{<l|{+0fxg^YlTIM55&Wj}x|H6>uG!Q$F5+|~>_RMX)m5kW
zij{@qpm%n!x7kD5?xv&uz+`p)^h{&c;Bjk8tC$8eP5U)J7bAB!W|u#k<G7#V!BF(U
z6>?<R{Mzpl+rE&L*uS#4%e~wl?a?ja;n7V4yJ1vT<W?)6jA at yOt5-gM;_mjRfF>zH
zBE<M4J6KKp1ETx8Hj056?Y(mGf^$=A-CRvAHF-H_<VNcH)RQmtsy&oG(XiXJHbz3}
zLRzp{Ik7z`OzNJ|wShnx(~j#X{j8WES~th`L~}0aNo at O7j~>bpV}H{zbubwUP-<)A
zzQHSVb#o|Rfr5`rMgLX|_aBOhpxaC#6f^ek-o3l0S0$&$`eZLME^+j&v`M7>)Iwvf
zxbEZGQ#(~&hV`LitO(}GsHeO!^HY9iAelP;{O`|q&W~cxcd0vyOCFes>1QDz`qB0^
zDLhoYCm(75_KxfhLUJ)9wD3cf;FCUV--?RV!gcfw)6L4cI at Kp4MW)w4yj|bCIiP^S
zCX^6hT-nZD?@_nBzA=A#bf{5%LHs9MbB5pQo~aaN>VWU#EOvSt-#*Kc9H=SD4b?z$
z?EYLXd{O-Yq91D0(Py$q-?T>GJ+}dxxWl79r~$E1;I#`13cBZBN|N)$8Y!Re=VB}9
zP3=`rZqA>dy6-Js<TK;mS*zH~K(f;|J at xswU*vNriH;l~tbT9Kt5Y$+8E0A at vr?EM
z%KZcTD(e2()c*+PjRn@|_mgw_A64JB73W5Bo>Ozhy)F84E5)qJyN4t_=tQo9H#_=O
zWtQD1B)=6^8MjW~7)Xr^jcI4?ffrc+5LqoT6_MoR>>ZC*?p`TSQEO!OXge{On=Vmv
z*_XRM+A%=H8*rYek2VH~ZqAd9O6>LK)MI0if%05oL9)Bg|0a+1`n3>AT+{E3QTM+g
zw+ev+Y3%#_<&7PUQz{~=W3^6(YkWZftbz(c|AEavO%S75-Xi^v2 at s$1E3zE=Krfx{
zZ$M}!t06$M>=up$m_*|%?ms$7ic6CfDfayKEwxSi?zrYTXzg`Qp*xGn8;wYy|C&ob
zaA5Q#;B?J`<s+?HpQE4rKR?pKjyJ3`>rdL+Z*&#ce=hHZosCadYES`=W9*dG;W1l#
zA*>#C%?BHRla<rc#J5vh1`o~nMhL7&WCmr30*g}hM&qP&^$@`?o_}$kzl>AYv>zTH
zii`#0No}7}n|bDu**@787kyKm0)@anua3U`ff{vF+asRCql(u4PX$6CDUnI71e&&F
zvgoc%<80{8pPdHNt-g7Qwgmh<?{30LLC6krI=)M;?K%`9s+?5CO=bVi19(q)F8*pd
zk;cQL_h1|i-CN*ytw1&e9I7Mk5f57xH|WoF!lna#y*msA5!U$04!y*MUT*BxPKVrF
zHOz>hAQhm3g>1n;5gkuzu2<v+>zA(*trbrRwntm_%K+|nI*tP81DpI{w)|th(1Qba
z#uZKJ*&V4TtX{h@&4MFcJn^aND2sAXqu=w;a|6+&_I3tX`<Y1HztDiR-x~6~TRkkq
zhsh$K#xixw|AIWaiF#z$D=p)}mD7Lmz-pV#ZcEuZy8???US-W!G|fdqAYopP?pDBx
z|5lgjQQktLN50N-LH><B<lSexn`q#{Wd1H_b;WYDGTqs4-}8Vc<Y!l~03H*<@0#l=
zFUcWVTB>$m&`2a5rOc{ktu`UDDio(E!(JiO!%zHu86}gNZ?5uFJ=&Q(wtt{57Qvjd
z3kkCx?R00OT at 5!~wbOfgb|=HIWhZ+^n)WmCdmyRZ%Y)jtHet$sLq)8~pA1CIP=*z1
zt=94CR4ZE&ZL#jAv1|Vlr{9~PyaLg=!P-i^9DK$x6TB)a^dTAd(bU<Qw0}Wzfck0%
zuYM;1xcIr3AagFJc4d!*b&hN~MeW%Hx#MBcB(AY6#kO;xm}Pa5smmy+v>*PaHtoJ9
zCW2`j1Nayyv(jNer46he7hgU*89}vsuiRxC#U^{Shq1Ooh27guLXWt at IFkR-@CMp+
z7XXMkJ`oNnHLX%BkWRR;nNQwrVB|oyHvDl>bGa02YY1XQ`tcEjP}PUvxwe at YJT{EM
z=4PLtP}04&Fzk;{Y|U~Kpmf0Bil<b_0$<m<sAe0=<Kpg`IqC|>(+7?`{LnNKX{pes
zu9S2J7ae=5Ok~4)13eO+oba{8sgk-*7#@6vCNy%dJhA~i{s2ugB8^@!IvaAKWOQ0$
zzs166*fun$+xReEN8}26eDCYGBiTq+?~cmg$0rt&%DmF~2<j`vvxG?da|8lq?wXJ?
zG at w2t-3Q*`T6~oYPI>BS{uvbHEvm2s-d6T!Hb<alxAJt1U5BTep?vOE at 48_&3-P;h
z$^A_SJM&d5F7 at 195zf#X3?7P at L^a>Mp9_&rT0z5>+uK9AfU at rD$NQndSCcS<2^ptX
zd8Io?oHR9Y0-y6|H+<P<cm5?P@@Q(#IjWM=1aJl;A*8#8JmP6%@x&3o`lqBqkEuO0
zyhyREiFh?;3?Y1>bnL|Y>z$cTAkG~$i5V at q*0!X-!bqgOqm|o^A+)94yOxvwg;0#B
zG#z-!K{id=F=)At=@#xwW20%6k=<)>5`BAjNO}LbqoQypq5s~z+$PP+-wWkL%c;78
znYo14c|R((yJBX%f(38g+|`R9v6%|tM#t#PNi6<HtV5W*3e!@zIKwz*SN5Q#R5f})
zracFPNDG=59`vexW!$+j(A1>7<0nc~_~9nOb8b!tXXq1qLq>p6>h9I)d9!n>$3hHJ
zOS$cA8?3mVY;Rw{US!Bu=jXTbC$WMxk$R;gR6>x9W~JPtEq<lo%K!4ng;V1>VYlma
zGdfgyHgWxW-#7Ri?ZGSI2;ILlR}3TYvje9JEac~BJx_&{&bp8>^EuV^260}Fet*+-
z1yfhesq&SRzJ>7B4Z&G8<k_bdVp at kyjV+OH(|LQzM(kd<eBhQh?u?=rBI&p_y5WPN
zg%>~){hR>{ExynFW{=mokL~5S)WdRnx+KE5vD~`Le-pPxMOLdvT{RjFV`B^y&&L4=
zJrUM!?>*E7z`Mgv7e6Gu at 0$Sw{|N=I4o}Yu_3f`ek*REFYbJiD^lbIdT9y^(WE3z@
zE%dLVrw$Mxg0qIc1QHttYE at DJ0V@QfbG at nN<V-QK9TGy#FC+{KM|#S!cEcmw8GCGl
zZ at zKBzi~v5kVy)&8$5iTFmmlLkq2h4w&d<<9chcfSJTNZG%&9kK3A{=j=CV0_ZI_>
z&I^PHMoZ~`<#sPOhWrhE?5d37_mnR7{Qae4NH&e;?(V+3%i0p)+_0af&E_jU5#VI2
zV!n+CCJ+g|zZ&g$3hh43l}&gl?}^u{;0FsZWS%w3A&sIrhQj*4MFh6uQWLyIq%(~-
z=1RSF8N2 at c`J)5KK1*EYL~G-`z%`nP=)P3n%AOtBI^HIl<=LxHMBl|h4-0Jh!WrJ+
zN6aH}yzDs at CF;U8E$l(FJ0%D~N!A3E^}zD3nN82h1xR``VD9FK=3qxfIqn+^nO<J+
z7vtpf^(UbXCyt79*yO6VCXRr2vhLe%>ID`_3T}E}Zq4~$9zF|4kP;oOFrr+yUxuK8
zND^#v{$JVlw^x(f*4NFILIL#g!F`pKs(!gw>1uJW)^*Bx(B54|No~jl6H8$g9U<ZO
z_(6*V at 1x_kFoQkKYg%+k;Ae4iHS3&g8nH3*EMs_1 at N>L%wTfQovqPuVy1}4h*e<{@
z7xmtV^G#fTipEej-%on=vj>OnO7%|}D7A_Xo at l6X61&E`*a|QpP6!lqV&S%yyfW^Q
z4=OSyHoyHrdMg_R8V5TC5t#{Ol9>)rpNYhhpDV+&+<nc!^yzI#JS>c0yZvlSQf{}m
z-~tPhQA)ai?e&JX(e0SZ-<zS#q#WqzPVo}Mgs_F{ZSXcLN_~A(dcd3Enzr4$E2WYD
zjov8gzD5Q6#pacq68~+JJqfPZ+|)?sqdbIVQ4>N?kSd9DW9x}0_8zbhVe{vP74lkW
zA9a?*;q{f at QrNBK{=+M(*pZq<`rD+B>~O-v>t#*~viu2jVMEnY2eotALqHX|2yqb*
zzuW_0^M(Ry-W~Mf at aA+~h`5)H6IPaF^Lxx_?iqOOc5~GG6>!qcufV75MIO)REh%{Z
z6_|yN0fb_dBGQxy%dcN-%?vZ#dGocvJ^9)a$yRom^6C}!gLHQvcjx|dgXBN%qINf1
z{u9YU8GI<^1Y7IwrLK#EtLrECt^iQEZyG_hOa?B!7u=zYK}hu<IY?G6&K}rFzD7YU
zT`M}dAP3ZPwQGHp|2+A8SaxNn9vjbrG~o12wtJ%B@(I#>b$Gf at 3?x6HgkbKFLlABX
z8-L>A-u7Ria{yz2nxDdBQG$VD*hKQY<rM1KYGbZfd2d0C+|@2Q^>*+OS&HSV=RH;3
zW4EMaJ&G;#Z-i5M$o<jBsQ&nMu4B}nw;;*w-iT;D`<1`LB^iYNc*E||tJ9-q>z2dX
z_Skn7n~aCz;8!>R%+*sd#-f?-m at v>NN>Gfu^a1pJVWBG$#wIaXgGm}YkikmWv(<g!
zvL`joqG6q&GBF3n%W0MO^|A%VaitZ+TU^vi8FMVB>}tXo(_1)3;sduKv#|r$hyGsv
ztgXa4^BV4MEYj64f}Ean)hKPDYbIu^=X-regSqFMnpGTE2mHMk*gj{QU<PyfWOq{q
zzPV*iR#F&PQ|?$FmNjobXk at f&g+)F9mKojO>=2|ygBGm*EQs2Cz+b2Mhk=79tct at 9
z9_%CjI^!3J;s6cfWK?I`GV3aw;?Pkl1=`6Zwp!57$FpI<*;)a9oTs$iqh7?G{zv^N
zDZd+zj$l1WDv)LE*&*sJl>G6gEg>PYM5$HJ{;Aw1vDRpujngXS+!^*uXr5pHcdz>R
zIvN at h1pKD}_xDmvaxJ1Cu4rxe*Sq6?kvPnnd;$Iaut&XsSwoMjr*>D)0$Cwc;O|)p
zKtnfMjLawF!=i5u^wrXd61mO!_l4AJADM=tuz&z3{G8+oKb2V{fFq7kZ>e!n6)c1E
z!Luj!Qt_$}>mY%vA(0x at OBy|O2wKLyyS4$0PZts4XEdNkM{IZd_<4I>NF#ZgE%J(U
z6S^wh275*#!x$<{V`JdQtL4I;OJ}L<UlQyGbA0jr9!?87p{2zo=OJl9dSzMF90)@u
zc!wpi(~lcZdjIobbA at 5>g|EaQ$8dkp$nv5;<M2rs+nxz`A0YpEf^`+ku$M53(V*P4
zVBB2;YMkUHV5gX+=J7PaqMXaXqgO*YMA<JVomE$Bv^0YcD4-2Y_~c+sxc!RpC{;1N
zbxq(RvZG%!g`uDeGb(<3G4Slo<a3YwXll{-Tdex7-3;8?{zh8%c|jbU_*cANB^Vr8
zk|+QHk6P9v<4*lYPgI4zkng6X4XpYFZf+emA2u6gTVS$Jtui`%H4UsBGA?~c1+}ES
z#(G>b?f;-jH!+FRq34QiK?EzsX>ri|vBVV>0Y3{mgR-7x<+Eo0i*wTn4h{nez2!I3
z39Ki}GaUxTLB!i8{R*r^LDr0^Grjg{m8*rpQxq8!USvtznh#+!pRKe-P_*3Tw-)KU
zw(I0VKc}cNE0}-Q$YUAZgB7%#skGD|3bpyqCGWugR*#B-7$c?w at Mvg-Ow3A``wt>^
z1rr_pTcTElP1f?}vlw<t*jq^CCRof}zL9M@*;Q{15cQMcz4z0VDmi&&U|caND8N{B
zvSg}^$S^4|P7=z{l4M6ptFt4Ktj}+F^0s$+u`RVs at Bx<-5#@l8a!69}zF6LB&_Vr_
zWvZU~=uAoP33fh_yKJi9Zy4uA7u0PbR7&REq?A6b?<36 at CY`+-a(7NB8`gz|gA`*%
zzi^CjDJDTnnUP38&iNe>o%w`<M^7L3F381;^JFiSz3cBy0<ym#W757}K7s6{J$^oU
zA!&Zt$Yn!L-fZ4lc5rnID#zaQ=il)3rd!{^8(<j?^>PQ?84BU*IV4Nwd*=aiF5s&0
zJ52Z?y~jC{m=8RNp1ysIQG^LVv1DIaBW+q~-Q|(AG=R}9KYIjAYO-F2lDdFJjwRHa
zIIalU(==w6wJ&Fr^jAtUq^myur?+y|s>Qg%%RX$#SYU{Q8xRwpn)3>yAEZ>R{3jg<
z%DHOsm at q&DhxU50VbcjqP>Idi#J6`2!3%8ZjpPD6$&vH+svt&6A8~26)g#48#otK8
zmE3cHnaV$JRtc7MF9zAKwqn5+6 at RGI(%L3qrJngQZ=RlC5susH2Qw^yGx?h)I;W5|
z8`M)Z$0w!BV;jP5l{0bc3-Ns`UK8pX2R&x3(<Ptn_K#E&U<#u%ZW=dd<LiIeB{5nC
z0~ZG3>AV~d>=3Kfv+f!OoNA4x at w^ht8#Kz@$F02Q5sDTb6ZQq8F}$AubLDRISJo1!
zv4k9t`J^39F8B%niqF|w#w%aQZA!l5=yB;$(d!+c`&`4)4qRFl`I1%jB+P*N(X`cl
zrqLZg=LVuPkEhvvlM$a{-!*w#6hSyYF-{I!)EWEW{mZ}MT_Z?f5oc85?+N3GeJ`+N
zV|?QB%Ur`IH`yH3wmZ=&nsG(H>*xa>MQ2D7p$G+*LAnygeqoWN72#`Xd1*q=xvUqV
zg}lI%(py93s6Xd~Vt1}6Yda<Fd(VMA(KzBDHg4nqD&gLG?6e(vA(y99^LBeK#`WeA
zSLg+3ZoZ^@6e>}fu9fNt7b5Vw9tS$iIIvF#&aY$|*S^L2ODxDWvC!<!Cu*!}{eWTP
zdYynz6DnGbin?E@`~8wXs5bP-?)&(a3TdxK;rzudH<`w$z$j^MvUF^9(bkW`He-6l
zF~!c*b%v?$Dp#G(Qs*(0l-8ZiO!gD|A-~&M|MQ<0AG9%wAM}~w(dqX!IkkbK$wNxW
z*T1TtA~`ck=+-*%;?bhN6e7y^l=dHNdeNS{x8;;Vs`@HUlw+0`WDm~vZl1^SqS{Vu
z-Ja<oYF#-h-pXtmFa~gP{#*H5VOfp6db%5WuK8mYIo*0?yKQV=+<)j;s1rkxdUT~i
zrQhZe0pf&-O0vObtJ#*dol3vsrtNpN<O6ODj{@gesnt^*R~!EAHbYx4bg62@%9{6j
z$Yl4rxs`8}4_+2=uKx844&G7U-r4Et>N{D+IOq5NOum*}5OXvTxi>1>$~Gk{%Zn}P
z{_>LrY4NOV3Y#>@ea)D!JX{dt)N(OiZ;yVSR3*3~v<ltizesfq_~Ew at 3lqWiwO-it
zm?fIF)LX`nzGa=+S4$NiA_x()rPra~kD&my_o538$EKViP{8%kKtzmC&oL~NnY%UY
zF-lH2mpYl++0T#`n9J)3%)9CK3z!fs%1r2^>p~y&;79mebD$RmC-!KC1m^++hgCzJ
zB<|jVK68W}{p#9r!-9Cv^+~j3<y-=dQX7{|=s9REXgb!foGo!&wG#V0NwbavKKi70
zh1U<5L)<fOcjuC3Wr^i}zEZ3rA;uM;biEN&J?{Q1molRhtvuGKPrsb$&64^XLwU~(
z%iTSH7hySEBPN4DQ04a`N2m*k!S9{N`#y)X9{%L@?fC?xhTifPK%@HbAcro(9Z|oK
zM1$q*mc at p0**x??8O|oroVcr%FT at bm^`Q81boE8Y$cnlEaek!HJ;3h at nMvRXvV{8F
z44vX!o^2ivpPruQIRE>2+D5I{yD`*yxUEP%80yV(|Ldc<)n!-`gdD|AzWS)IkLORE
zX6}zvzL$=Vd*zu$axb?|0&W960H5+X at X(a<6j$mLJdu&KCuKigVk`oxos82eiitkq
z>Mb0Lv#iG^4;wNUXykW?&4qDwo%bDF16LZn_u@~h$R<nN=M(aYnIdR*^>poE>R{Lu
zAmgFKo1?>9^}cs_%M!Xjj6CgH at sd{9>&9aL#s_=S&hW=~c(P7fOVlVPyG<lt;geB0
zCI$U*({0rZAejUM8F}~}{V at ns=Mq0L at i7tN#YWD9V!Z_j*d1vh$BEOXU1f0x)IOcm
z!QFjb{Rbc-lFga;^6hgLqF@(C)9A`}HX?o^K09Pq>kmt+0c`2?K2*ZIev*tIRIYTD
z(ZLOuJ`ZpUP9W+$Ctd$1<V0wPaA#}h)k0Auf8_((YKNk}d_F+W*X4HW9{$2!|Euru
z2tCX>oeH~}YVgKmsHy`*HYi$V<81;-U_$9b2AO{vlnQ&}BO7r6P~Q5$^RIf!>c%3g
zZ|f~n at uUv8bK=l at F^e`|bh|o15cMTjMk2!dA;L{6;E$R*OCpmpkD at q_4jD!yC&*QC
z2B4_*kZ~~m{EpF6Wj!>Ka`W{sPoqlCRKfd1G&Jz65kVxm5C69uT>bS?v;v at MJ$G)S
zdE><Uq8vjiFU{XYr&P43!Sra*wdqfTcoXwi$tAx=Bk;M8`}BJQ)PI-;8wb_r(^h^U
zh8e+;+I2r0PXUw<s-*{|7krC!k0{T~+L$K7_P>sXimH&oIe$C4yn8T>^kl8-LgepX
zx;S at 2Afw$3WU6m6_YHSe at 6sB_q2!`gZ+mq;UIukjO#Bq$9TGGUH!B`XJP#Rml3GT1
z8!<|Rm+$7D-di!+m>(d*hJMRAWs?@tL?CB*qObM)d$kJY>YL;F^|oW#g9E?E_qq%m
zX7~v${sy-^+|(%i at FenHq~xPKx6>(>sS2xw!0 at s`9o2J^HJ0k1lUZ4uhHsY~(xzf!
z2o!g<VU<ECNNKObz8IJC!yZfSVA=}TU(zhau*yk=$D1`-NY*3S?Onsh`0Eed4l=&e
ztfNRTn<0{>Tfs(FH$rjbe3@$jT*!(FxHmNLFJrVIT=Rb(PSQDmTPkPeU0p&h0nnf9
zJ5Ex9=3JAm^1R?Yt48CvfzptkpZZThOzJAkjv4}1+YqTF&yGsbwvE;(UVXepyCubA
z$*ndOE2z%R8qn|Pn&4s_z3ipjtLfz+4Gp+`@lG%OoAl_YGd?nFu<RVj^ZPK;oE05h
z&7(OpN7{Ex7dcwZgJ<9<`;@L#)L*-8oOh<?xg5nGc&3ISn)RS!jC at bl{{<R|#Fc8z
zZ2u5LVfT<)#rc9492}`UGc0<U*!h!vsI9F0lekd=odPWUi|`5js(}_V&~gn<dhqoG
z7qI?oi;B`(AjpGA&=vb>N{zzLyUCyj>iB4gQu2QMQR%1qo=Et_QBKg?=@k2?n9FES
z;b-9k1&(c<&u+VdPa{7|TA$JE&9#KMM!p-ADSSY_IRq3?OT at rWK@f7xLttB2%#$#$
zAs1i>^V+ZoNmle0*gJ~EfKwsk{IJ~SO5}PY|5`Zoq#29Uaheuz=qw at Yk31yZIR7#3
z!=7@~M2*&#ZPR}!3gTK_R|%}PX0hGs at v36@X5*;d`tiO5<Qh=KA at Z)2u=>Zwuc;-4
zXCmIDB3y!n^z296?<ZgZ|7l at 7QD|B>#Sq#vm_Beu912lUSPcZb-p(s#hB)+63*Ncg
zNUc-0J`tE=SHx=>w_WUzMN|hJHcP%q3B&CRXIK~R7!6t?Sd42>i+GWjRCx+U=lSL2
zbQbEWiog=DMcfI|^@|NX;0 at YkY<@mh^hH$=w3hMSsxAkgrp*&lb*G5qYR2V9d2DhQ
z-K&4-v_}AFAkyBE`TOPeHW&QEpp_v1gjxAdHW$~n%38r)ruvxLAZd1_-)%I0H!6JG
zymZFU%}sh`_~wAdK$uCAHOVP0K>XzJ!A=q$T?hzZY_WH3`JF+(xfE0#?pFBh|G5A}
z1;3NR24ta+<R>J_9D^-|9RK?{TMerX9(%6T3a{BYnnRtw at qTeTt*TU#Pk4rHQc^k*
zS9OW0CO_QW7t8pXX|?&bIX!X;PZ$-?R-JTxmYvp_93wWRlmc%zTK^LF at CA`H;q}5~
z(haV+h%}D&6`2bC3weZ1tt&_&0q#|{fSSEKw_~ICB$gS&y>_(zG*V6Q{Eno!$R^ok
zG(rJvw2yT|V5%inNF&%MMH88)zB2uw<;JBSgYbY=(a0skS1M;T2j at p*grc1Bq8W)$
zWyfyE=0OC&OL3h4kcmoSLf(0GZXh*Pna2)PH;P19kslMS=zD~9A2R}2yG-tSX>Ceo
z?+bf9WOOFq0ups8A3Z2laf)V4qasgzohjzgHNrV_7@$3`p19DcB2Mb5#6L~scK<Qm
zx!a&ezr+~!XMNm2BZjGdwl>A!D=ywteweV@<7O&E#$y*%<|JZ#c~YLT)M&f%fq{($
z`UnEo^;ioHuk*Gj%6{prJvJ5 at 5ooPwmOUf?6tdlQH;umU+a`tZBQ7kG^A45CKn&B-
zPDP;qH;9!}k|&v<_?#~4fLG%+zl7+m at 09EN!hZT8P#PNG&+e?u-v+;9p?XvST*P~w
z8Et*LKNL^A32s?Oif~agebjlqihF&x`1=4+(4DIJ_`(5}jYSUpkf7o3oj5q18+tKG
ztvXIVR6wmz#NoT!kP^qh(fQBEeNBMcCmgb?F(*6l9x(}a`F&Wsb!BvFu9pqT9+iD>
zl$|<)6j8wiqzLs>3-0AgKqp at VL72%OI$-d~r+qWRALH(gcJv at m1PkRq_j+K&SC%|%
zMxo?J+Iu0gy|F1!9%#y#c3y^%KDYIP3B(+b{nXGYV_!H=R8{53n%|!=_vEAFNA0ke
zjuk}S&4}J<LN}uJg`h`b&JXi9=mu(qDM;qGk<GNPVkFLuCKCKH6ji)lA8 at 7%&PX0?
z`Jz{;Ta2)+11t+?Ayb4a_eE3WdkK-B$o%FW%^0d{`wzoX(R5zqL10e!6h+GdsX2wo
z!?6E>h059OAd5MFqkA9h5Xjo>`{bX_y<FjCU`+kOp0^vB7xD622n?Rr3|o-jN&7;>
zQek-85Y{>M$a91ew*5QfT)cr1r(Xy~auAFIDiPm+VKMTzyk+sG0elF!%sdaXLgb%u
zKR3H^?hW4s+g?xXc%KVHPCCZhkzsaq(P}ciEm!|FzHzg*d68z|UtT`#pS2iT?6~Ue
z24rJSNFvi<<cD{cT(Lh-*otfWubuUBL%evD1L5{Zz1seW^qqCl)>l3UH1p;XyE9)-
z1ghI;6&sy<S1IuaYPi=k$1I%TlN=K4=>VM2G~FUWNkJ0(crhL(r!;Z&Ns*R5LmrvA
zvuo<yi`nKX4+{14^mMvtVR<TE_ySVMK!;QtNNoXt_-hU9<OC#Mg$vV^laTj?Ax0ff
zBBH=WhFPiHIy;MW2)?4tjsv^6SDBp#O%tLL^anrB*;HMFyPDjH?q{IF_rzMmS9 at b`
zTt-}Xxch^`rWWJcWBTz%`!NuGG37(gY;_k`Ek1fvbm1V(qVVXL;&DNj&#xx+O at 2*!
zQxwVPCyZbwP7<|#UXxGc5j<kO6nWHB{M{N+^dSCR+^g5f!}wQ&|3Gi}RmRK=5g#*s
z1+8$~qud8q0ph}FEg><00 at bayjaiDaQUUjELSwtZZLMd(fyEl~ajBzL6EVV3DE|k;
z8l(KE7MWfine^9p2lIc|wH?Nfi;?Q7J~PBYn6-{>yNREwYGdbdhBYllIH|PP+bOD@
z&wMM7JP>8D(|TFc%c~GT)@7<}dc*W at N(UC2QKW%N6~1y;f<awI31XM2D_}FHW56DU
z#DnA9=6){k3(qU>R(s0{z*WHlq^WC_jH<a=+dv+xL?#cd(uS`Reo$H_c5&T`%(X(-
zbBo>eC6f1fqC^h8;+t_xc at hqZwx#FkvjHD>#=XH1xvOK6tP)E6oB at RYXGUCrhe$nc
z3pe0(LN74R79I147>>H~@t<@71ay{B124xRhfD{On}2rHteBlU!MlkeGO0)~AQEOY
zJmx}*++dV)YB2h>74l&*=xvPgtFkPLrXmqPBF<1e__^a)z4LJELHhS%C244;7L|0h
z?T6nZ4EPdkUu62e(4h6;Vq44Jw&2d1jz${GXmxP#qoi3UyDl=VhC8xThP=}z@}~hM
zZeOX($n^I9ODq3xa1w2x^xn=S&v55a0*EM42J}TIJ^tg2zWmZ)WQ^fy`wUm4zsmhE
zNRa}QJ0pr>Gh_liedLY6FJAWxxf}}ATy9UKoD{}iM6WRg5ciknL-{A1!}Mw0q~4{a
zBxr;Cv{e5NnVmKvbek#-Bwrl^!?3*IlIWNBeZ|*tNl8h?bxeIxAU^20IH at Jk)8f0L
zo}9VPK6ndHVZxIep2+5B<H&K(jPT-B+2;^ONP2%jDj-Hr>nfHyujdwra19ZUZTG$m
z5krvk81lSSLMi-rG>Q9fUkTbY9F<KZA6_f{gop3n at q5MOOirhusF<s{OOY=UXLsLw
z$yzjz5+5K`N)Y(j{mn?hbokCQlLqA&(jU8gl*WXy;4TG<ougw$q^%)QKVJ;}1%Dr6
z4P~0M*)UJ7dX-1Mly}q<9`0}0SE%D02O%4r33 at rgB70FO3*J;rIumDl&Z5Wai+}Y7
z_O|uqm*-@^8+i#T*rBB at B002ijNj}mnIL(lbmnqy=d~=y^e6*PDK_(iZW|N8jtO%j
zV4 at ZYvcbr@$%}EDYKq;uB0{Nz#jzC>H()qwGGcWtByjrD#At!7Goxg4ld|g=8~<{f
zzU#cUy<J&K-Y2j8E!mt at 7Ye>F0#-Rb%$_sU`M~gyxuMD1E%!G|v-C5L%LQWsX-oJ4
zVQ=tEcy?!42Ruc32i!yAp|AngJ#?BHavD<$7Xco23)gUT*@(2{w2?E=C_V9mA7wMZ
zea$Bw7j27cSnk})P%ZXMS>W*{r)?iHC%AdvGu7CxcI(4x*gX}9DQ)OnR*g2H5U}<2
zL2a+m!mWu)9ra1DKfe1 at 96;o0EDv5<Ga6|k<LFO8xBPnM{{RO;_`a)lc6W4GsYT8X
z2st`0)bwITUQo}DusRar30q at gqNxNEG6qk|FSBEzVuIaWI&e-cIB`)Yj82M0BY9_j
zk(D@*lcPe0vXw5En(F2d6VD`+(=Ot!HPZKqk8fP|u`_K$s0W)13?SZJX4g*yP at M(&
z6LMsDZU`+SCY=OOcIN!flHBW3v?-+>LWBqbVu0WzjfH{35!eZ%zy+tIY<!T^t>>;g
zrSHb#fKyJ{j>}64=Vb76^(u!?QM`l`AKzWzlS0CYNB||@(HHm<2BY8OusQD%IxmdK
z0T$3aS1NS$d6jf=X9k}oxft{}EMnOWcdn+o&*adsgUY0fusu#hSm3%sWU6@}f51XV
zcz*KASZK_%En&d=?k)nsE#<DVs54Kv=nIjK><r|PlHU%WVu9?<OcKVq--ldF=0lvW
zD~39UhB2H{_blSbwMb37bS~uUxgvsaFRGR)nRgy6C%i7OF;7KNMId9gzB`*j@}=bD
zoe|&w*MUXh*4EY;aS~3eI-Sl;Y?(<|ZK6ZMJE5$U5a!}%!l%^eB%(y;#%<#}vzT9S
zYC5lYXEN^JjmdqAc0i>tr)22;_55TzJsURc1eNtQ0c^5!`cCO-SIlMJ%;`9rmz2_H
z5vOxSPM&f*-f>O}8KWr at F?Y`ll`DL_$SR(WfJ8(UA}NVseE<bN$1$cjGSzBzh6AIq
zw7P_jgY?75(W@@H!=rqB$PpJi3WVXXBjKuJDKZ+nzp{<X3(|@DRD#niF2i~ulu$h*
zXPP3cyVkhx1EEx`l5tJ}RF#v%!%ny_BlUeE9Nqe!7m~i2kWQsmPd|H#2jUPRCQU4&
zd at QYt?C;OuO9&5bqX5BVmrjy*M#TW9S%m12%un8#&V&jzmrv%MViD;Y at Z8Jba;Q94
zsl5$!f=nzNd+b|(Q(ZzfP8{k%I3_z~44$;Df;#UMZOek3*k(d}$eofsXj=v_+K$1M
zjT5RzrKDih;iQm(lPFmTIai@%%3SibOgNbok+4oK1Pf4yxv)d4={XBr=g6?}q5_yu
z5Ecu1ok}@uI?cmv^K}>4V6fv9(Itc(9;HHt&=TKHPc8%($T6vMyuEBgZWPs}xc7m{
zJf{x67t6VxRIehek0KNF2VCAqkqJ)f+~2Txcm9z##K at 5$-k-%ir&%r at qKOI#?VO%-
ze-VFP{!@jF7dp=6)VbhPVctSb-Z^hdrE&n}Ixae+h8)#G=h at ErMdB;E<hhDCk3))M
zi<Ul;SLW(bzJh_x19tU2*{5%(FP5MVi#RTYB>bDAHTpizf1VXDDbMWx;j(mZRuVeT
zbKy#VIyah(`IJ-s#wR+=ugIyBujRr{azRsfhN2YQA?RovUy;B#!iJk{t?%xFJ#1F8
zvBHUsY{w}i`O)OfJ95CKqjeU%naL?A_dD|a^@nkc6R;{TB|G0bP#hc65s(DQ%9CA0
zCxoe6BL^ubH!ry9BGMqfN5*y1T?bu7k-B&sy$V0e4Wk at 83#O7Hbg^^p-5#pd at bBU}
z5NFBGduqcv$+rq_uI9ptj1!N&5YgZ1;HkPnxB)S!J3Bkm;#S>ZT|~k9_{ZT-gkKTL
zp}$j2CM6=l4x|zzeHUWV$sb||Q;8}`kUln^r*l3lNggxFILWp8E}TN@{k_x0q|2qP
zN$Tdr#|i7H#6kryiy*-fJYh^F4osSakL8`>BrLV3#^DZZ9{An{es}T#C?%be{pOAx
zAGvd5vc8|Iy)gK(aWMp$pW-4eckT+1<Y_o>Oz-8kVM0k2L&wC^UwKl-4y1Gbe9}f3
z at jSIXo*SJj`T#0($ydu>Iyc;{MBAqJI`Fx=IEmsA1H1gBiUm$k9H!!gbz;`pd1nWc
z6BzOl*|ef<83ze(^4&~SP;y_)bK#;g^cN{9dxxG8%1Yl!?v?vu-%}$#0AY9JYAP1Z
z+asf?0U<yX7jaIXb6|8QHDOR3B6N#tl=|+3hOv1_8Gnc6)oQia-``I{2HoHIUM${e
zP8D3))E6TvPHC#Z;$BTDCDWAUcCtQq$;~V?$M52~(w-S|nKa=|#UZYj at aeSv5UoR5
zZ<6_asUsW5UIcRWhENx3G^K3gf<8p<u!xhtAXJN-JozKHjqf_)xpgQkCv7h1L+Cym
zevF%Jr24{eof|g631JrW&Kn<W%y`p>uPe at xW5b3Vr_(OaOgaf0y}Uz2+svaau*u{o
zE-wOIia$A-(TAdP1ywwJOvDF9a;`&!7`%NeunrqL7GBj;p^BX{1yVh1mpk<UL77P%
zRyh}!t at LD^hrL>@#{T~P3<lLPq{KNAmn~aRhEDG<2dAWq2`k5!+@$Th2V@(nImrPM
zuAo4tZjR#^x$RlcRY|Fwpqz3F2kG0OQ}3_m=hD*(zT}~hgf5v~cAq(RW;cilEl2Xi
zm$GxtX_b?6oqMIgPws>|pt8T8D|Wt#5oM9dWSx*i!Jk;rQ#FknlL<+rG&PHV-6{RN
z0)U9RDuh%NbDHD{qc1uo!BqZ(&(&3gxVy>y5tDh at U5Sg2rS;hz)1D%2vxDmVAQpix
zgrMNTBGGZ#E+OnBOfJxsbhIxnbh5w8c5~`^cz8HdAnRP}bwXJQM_~7vv490GVKnSQ
za!ShJ$Idt>DpUb-;S`^!D8Z9$<*U4*M)EA-nuILMU+CxkyF0;D!IjMm{yuFfcNHNe
z4h-JvF1r*gJM+GKiT*+jG1-6xw5vY}_C{U?cfIMmF?pA-mcQZhKkXD_H<~ctEX$@4
zY6|{P#&uTGygZ|<<wam>hmI=+vbo6S0rL+wUYJkFAL(@#GCCJb=4Cs+Kbr%D!Eh2t
zseBfdo12@{?@LZ0zdPfUFNGA;mPKM}`7!rWIicM}B*-61 at t+BuXL0Yl;A9*52#F=>
z9JuYh$Q0C-YJ7wY3XS6nda1(bDu^t?i0V)wLmsS(E*0l&9_X{nf3parzaamJaZ!{D
z!iafp#34 at YZki{S#N3Wz11xZ5J4Ys at COQ;Da&D6gs}POD39f9zKir|?1#r1sj!vgD
zb0?HndtU6mmXwXDXaob06HI-#K`H?G2#h0rs!KVhodJxvZQo5W9*@ru+FeVWl_ at un
zvKzz%Qci%<jZE+y9>osnJW>*IlvF%PCF_)(ESJkuAq9uY5R=ZaGbMx_dn_o3;~agn
ztiFq at ThYO?NObrUlWle&2!mlVo?7 at M2hR%I&lO>F44%4(lqaNvr(y~hopGe!Xf$S=
zqzWAdPfoK4TceYa(@nvvyi=th?l2YxXBU~EzCOE8gz)Ix=ygIKl^DAGAu;Xjpt4Bh
z#D~oVU;4;NnJfK~Lqlw?t3%Q0F(Kp*9>SMcP%9y27cV8ROu2Z+9=nPVc^>2=sE}d8
z%8kmL;F1qOsEEUKSwy&8sqadmFZST5B8|-qCRHq?{JHA6t4QOd&ll9Ot4V+4lRk%@
zQA|MojLm at 5w2UNbz0Sbyift|`!z7LcFqiYCxK(_eus$VFvMrkn>K^MeyM%E{3O2Rx
zgHRCtKK{HCJ{EDlSBg*!U!lOHEd{%C)P*=a6s1v-sAeRmr1EF7jT4W(`>UU4jMkl1
zGVlA)JdTmn?FBSZ8-C{~D#KlFES%gnEP$2lbE at jQTBdtu!0qzAS(GfNKhfFXol~5X
zZFFaK=6zDA27>O4CLElida_KVLQaS{p=BY%hFS_9<$Oc89ieAzJUf4yzu%W$vtdW|
zPI9-XzR5`;$^KO8^Bp at b4nl6Y{267tDVmkyV)9Osc0j^A&z<~<kWM}&B~619V#4a^
zkH~c->VvR6LZ}JR_T5dK$aFfLGl&*W!wD($0-0P-<xE`EDrxE@%#59QCmz!YIfsV9
zQ^Cvk)KDUi!Hrx8eJKW4R at Ef9>gSy(NYXVEQg-HD3f7@#?2M;4Hhh1_NjkaK^|Za4
zM9e#rD%!>+J4u436LYAC3mvFXA;~g at 4W{x<N}bB3X8HLXlTJkys<rTS{yrxARI-s`
z2bZRD$Bq}kDY6<d?J9)$*$F-KBF&Y%G?tzxvrA~1E~Y0%E;7N3%qgZEmrp6#+1H)n
zZUM)f6FMet6}vHxpXHq+L6rN2bcWgKqC7LFQS={<za at u-gm|7CcBTkpA<RWh3w3bS
z`E|0s5(5?*@-6Ll`^=6VHYZ&2lbky$EcteO$NQ7lmfCJlJU`EgHxHO_QU!>KjeL8m
zGtTek9Zq&Y$!C<UIc at SgN6sC;JD2t{ad1wZ at 5Q1j8Wozj6O2;&JU7nCONoP|wuqBh
z%mUisnwoCQpKwVmrKNf9h*_6EVF#57=XgAxfzhzx=EP;53!OWk>=RZ;E`u*+q-{9C
z^)&)6lgs8r3XiWlDIeurP4YP8uYA!ei*-W3crN4*z4OgQt>jYB-#BDZw)Ol&=bFCS
z`9&<0$P-Z$*7GCZ=i&R%2*c&1PyUL0M<>KP$HpPnY{)qmLir7gFp2^2x%-YCB1*WF
zk?<z+G+3ylB+Hfi`M$FhkCn-|^VUd+_w^FWt at K%#JI>qr#XQ=5wKrM`pW?!9HZRy{
zrNBmNF*6~Ho;MRhtuxO8SwF8cC|Pbo7M*)e)Rn`}*~q1Qb4pE^vfs?le8&!-1qCva
zoEcS)?2yjW3g>u}1rZ;J6F|lFU{XhQC>?e>Xjf10jsvy4eMH9YEum%lH;&|;TuWI?
zISOuI_gySHjIJe41toPziMwV8G_~=VooyF7APJI^o+)_LJQAc6y2!C{`DGR!3J_G@
z;=xk4CPl)e{Gk_dI?O)NA=k)Bls;9UgLi#>-!nt_6QLA(FXFOw?g^{&(W*LGghz3t
z&e5y>8(nmY4RDG<2oSr3PKM(GIXyQPI!b2QtzqK8q>Cg>FY*XmJUl#{NerlhsHs6}
zk=VS~$=yon|4W*h39)SJ_*!;@ytzObU0;&MC1%dqW1+%?l*PNNASwV*ez{hw&2(>F
z64bd8vMmDy$^QCzPiUR+E<5Pl$cJ!?I43p?zDzhBuE4}W6Ic&^^nJQBde*+1$w}8N
zaJ~3fF+eCSw}=zsqkB&oUY;v;9yyI-Ql_&<`DL9eUrtP4O at SScV@$@mUx>Sz)Ew}g
zU&OS#{BkNWU<cHHzblWXB#f#2#m+e)*PI$qdCQkRst9C*Oa6$91$`fgLxjj>;Ai(;
zDU9**oen8vj3!*uxt`n+q`&J<G48Q>pw|g?B{$1OBoxDm%Fy{FkCY0JuAZqFz#V|x
zKF`=ne?wVrLf81m&lPRQon9_I?a918V+xK**ctC{rBXSw=+uieuI})iT$D#9e2TUs
z{F1q0mSwTEwKc<6q(5UblSn6*!e=g;QoGYRm%kx$fcX){j$A~`VZQREg!!|nl-eVs
zW~E*yWYG5qIa0~R0AzcfEB(A;uM3b7Nu?r|FyX0PowV&_f7c3U$CXK)oFuspo;dJ<
zQyD}5=EP=>M%g{4JhB{_4!gq<lz5SdM;Hs8oQ&lXz{2x8q1~k)eeZ)RN8c0Ug%-QZ
z#1`u^4Tr-SNPxp=R0Qg?u=`6V>05U>%_5o1t8NmmxI;&0gTa;fSiQ%=!NJs#c!8|Z
zDK9Q1LAmQi7r=w76Hu8{63_2b1r?e6>`quGDciftMNv$##q2IK@$gBZ5>lN5ojW;R
zj{JpLC;3*R+Z04eL4Z6FCQaT+<DxHe9Vo*~$c)~bvX>;Y`b5QdRwyyy&I;oF9bZe5
zCLO%q at 9^+&=Gk$(Jf&p$^Qizsf8$e7c0lQ`)CJ_EkQ_Lj8_F;HB#sLNS;*+Sb9%M4
zwKW4fkuT+)B&3KCBTB(4sgf at z|B2nx)W&5J at VUs9P*t7_E>>pT at aed|8yEO;dc=fL
zT|y=fj6<A)rly!|?2w$xZnIuzQ;K{6cAp7Z)c**hQTJHSj&V#yEzb?lykLLiAGwMT
z?+o`k5YJCv$)t)L8BM=kn1y#{JRVP{ZJrn at sgkG;r(HaE<ZG(CtaGLAFq376Jo=JZ
zq9WM2_M|O!r<kz%?j^#*neb9tnnDeZs?h6%<q>(nbLA5qpQunNP<B;wL1#l#Qu%6%
z5lI|`oorW0l&{wBlYBB8!8})-b`b)^MXu!3$+r3ol#}Pa5Q>lJxlm!!3psCsv*D)u
zIGIeQ|DV2&a7s>?$tzRC&I$31`D|9|Tya9f9D#REah at Dwo;yy<*eKQ%)OQT(TyP at 9
zrj)PVkS|yKR)I-Qp6A`%A;|R<^cU`rSafiIqjE=b^0ePbe^+j)d&vAs=jzO!897O+
zOR?Kb<q6_rT|eJ<T5!ZhyuV`&QyboS8Hj@<{ECN}8tj6cC^2!3dI}ZDiKqkOQm?+X
zmmLKiRw{{+Kg4c~l40WUiD}ni^o5vI^$^U3Nmt4?`mBU%FtMQ04Ix6j$gUj0&bRL#
zNG<aucZwYem)PUhU+1u}z}3(5A``ks$RkyRIGQEYgRfJjm%CJmucwo&)oN!n-n|gw
z!c2#`xQ at C*jN~Xd1=U4&jd}e%$IjfT!HEmGRgNw8kv(B3I#+Bw=v?{oJ34qd9^&=&
z^LmE5b6%jjiV!(@OzNDor(~Ro1v{in*0~d79*@N3o7q{X8jKU(c^_ScNQIE at v@dN;
zZG&dQ>s!QW8&`u#?QYWlXO~YZK}@P-8|T1K)r?7(^Mic4PMC^!;e4-yFYsmH7f*wd
zpOiZ#L6lQapBm5~5p$l}kwd(_%QN%Y&AU_NJ5qXDe<<9Nl2j*5M)y6{8K*=rJNM)Z
z(wFKSy3{@K`n*%V|A;Ucy;o`hFDJzGS2`CYb<1{yvFN>IJNjBCT~xPnWC6KPoMQU!
zC69A_uAaa6o;&W?Ay+dMhxFYk%;IoO6)G+Zt~=l`VTZ=EQOd>8YNRMp_hzH3p1C>|
z_my!9N-n9dk8u9<Xf%p$w>!<}QoJ(v)q0&fbO>D|e4IR3ojFc)1oKTTO6787UrOzw
zHspGGUhDf6$?0>YKlfK$QcJXuV7@*<PASIe{b at U%JEAr?#pD###fEq%NhhH%<sLh4
zj4;NNuQ(o$r?J)-=sJX&le#3#j0vj_f#YYHm^kU0hna*hI!Oi)aurfs203uS(Hyhx
z^2{#Ztc%Ft$}ur_7o;ATtD<@ElB3Xn<5LG;21=fX6I2DeBUgcmgG+i6W9lP$;`O=p
zH>G&u62d7i1E*EKON9>JwZa|lz=W09VkS)~GCqU1a~)U!bENKMek~KN)oN$pRV1qs
z&Y<t7*9qldhmxHt?vZg>OJA}^9rzRx(C-}gDll<TVnW=tPx43vOeO1jjwv}*-6`U#
z9Y4z=&389(V&l@&N=Ws0PI#3xDGBlAe5oBgoK`t;+4s13f$Nxb?iZp`jy{XaC(Cx^
zrO`Hg|M7S{vrU?vE<)2%opo|}6bOBBBH@^99&p;kB24EZ#s6`h2q$^EC)_*bMV{_d
zY6-3EMLBtO=?I(Q#DyJJD&25`!YL#%=c%R?p<}uSzSqi&e=m?-dfL1GBp$OV#dD$G
zMPE*tU2$jxpYpv`j1|sh at JSnCH6Fv6m=MP6iwnIwtm2$fv%Wuw%}Bo!ByDq2=gM4!
zkNfo8A&G>0a=OkOgxzA2qRCI<4jw`zUBH79!roYMGCuPUD*3VT!E?ubX57H;d__WZ
zm~ZfPLCg4ulIUKX%NOhC*-Z3gopDTda?u)crzG^miIUC at n?B6#9Q8n7>P4XMnep99
zl=XJrn#UoY8}evV-<{0~SG;8-n2izN>A7V-*Z=?^07*naR7Kty(Kds at V44^Eej%<{
zAZkJaIofwdK_7B-7{l3&q%W2~BhQtbKrix$Byd$UPBHz?$QKjk#oRL~0Kn>rdfW^U
zO4?M-vm+sFF#`k-6BlNBfY4Ne$+kLGa(tB7bAA5QVWiwCNAld2!li1y55%#4#7PoD
z!~jBEret*We!is5aga<bWIsAdK2R#@P<4z|FCjv5Lh4*`YTz9S;%}MEGvOrWT;H7m
zhtsCXWO7EHFtwwH0guT()uq at ab&{l>B_VaLMpv)bXH<gN{bf?c<$Q9IBw;csbNsD3
z<IWeLbRz=_VRiF%HxZJ^se~`rQ#VEDj$6d#fcf3&ptYn{PEg4*i+h(_X8|khFq;R2
zs_J!i!d&ume}8}aEUD(g#D&4t<=}ZP=!A(Mc2zP?dz4V>bxy0fY}6A at 3LOxxKxjv*
z6Gdnl<(GA?7(87n*5RP!LJ+g=+n~Akf&SA~$=Jc<)PQ at fJmGXzuz5>ld8eFL#yjaU
zw>k at 6<fWuyDU9&{v-j??+OGLs*YAD~>wKC$oujjvGJ``1t)eYhN=hKmq}H|sC84y@
zXiTu0SV=U3nn;>p48#}+|CkyGB!rZzAlg7uv04)>q$!rb)D&z|Ct7x=hyAX#-gm9_
zoc&|1&%HkPcU|k9J<};8`@QdEl6m*Dp2L0J*Wq{g9 at 6(A{m>F_O7+?mO0N?FQu{ij
z$Bj88E&m}qVVkdLC~2!W;KE8u;e%;6q&Yc*3H7j_2v8EsMY}R?Y<qT?Ee_$ri(z%_
z)ehzpLSxx)C%{fnQ#gen*4?P>c3W3hSN*wX-dY;;dM|d at k~K#V?ft0b-IRoN))eng
zR7NVg85NP<OPM6P7|C;W_sB&d1bbZNPp;?b>1qEu at kR1HEK%$Zt_!(7<9#-Gzf0q2
zCwXa3>@KE*{Z^sY3AE#@goZhorl`a-F+bYKhTN~<?Nn8rpPxTLT^KHPette!Q$EL9
zv;%h;EouV_$@e~+%?2F`)|_Fo7LhP&g4oY-G4sZ-J>QGZDceg>RK_O2LQyFO;3Bni
zibN(DQt0A<f8Ud2h7a{0IgxSO+CiJEN5=Z4(hiACy2HAy<xMB0WG$1MrjacIs)O;A
z2Xt1ST?ym$4R1=A%jM<epwa~f)NluH9DF|SPn;xUW0;H;PpBRP1)*Z$_MxS%ZK{+G
z?5{J_%xaCX#RO)q@=d4HelqiWO$cKnG1nmt?u`59^Id^S*-UQ~Y$&Pvk$xaPyiB4@
z--lL((@-+z4P&1McFb8SSE-igVBKS5;<PcX%qtRDE2a>zCbTReNG4Ibt!%Fppb+l#
zC4Yy2FUhZL!r<jIL1rx3<Q#B1 at JQ)tKlj{3(`}mXcjY_}&#ZLu`R**3WJsZa1HxT{
z?C at r=P6gD7kOPP0IuKA=gu?qt9w1H at T2lB{m}Jd(ja$x?{U&9-?S*203#$O7q8kT)
zLJG}&V&1s=>v`Zr#e2C0G>p%8(B#9F=jy^s&YKjqvABu(jx8k}W76GSH{l)59_x{!
zodqbI04EH_{2e;5hUJ;(nw>zn4$SF<5nJ-y1;6wc@?MLDLh?WiUE}Y~A7V|j_i^ur
zM;Tt_PM at J?37<-bcE=aYX+DEBmq{F56qBkQbh-PTa8Gw7Qkj%QhQ!El((IPC3cXgJ
z at _u4ON&3jRtKc)!iB1OdaAaD=M&<<^8vFFM1T at S6W<POk$h~pS8G`NNt3A0aHjt{W
zMjqrD??k8tWo-$!q#qjh){-FRJ6JOwTc5#}u6EJL4T3aUH3ZUew-Hl at Od73YgJJd?
z&`qteGjbqBBGSy$B3tg{W!&uqHa!HBhia6G6=^M5-tw+A-1CXgj1MnYOj3Ti1&=a0
z_c>B_3kOMyjKkHNU`s;J*kzk-<pXI!$FlXx;p8e at 1_o|xyJBHtv6XC$UC!4t*tWE_
z?~RRsih&aqx(bG8F*YXpWo5m!kj(>m&WJ2s#0fks-|Pd&usf14lj+Pe at nlbzakrHd
z;**=0IWUIh at oZa_GIOUqFPRsvd?$~@N;;_?)q+R)a5TZ510XBs>HFZZ%Zi1$RmRum
zyt2ZQ;h4z}viFj^JDyi=Tc<Rm)nJmV!2dTyC&$hr6vjfkN at tazl$B(^NTCCFkR5PZ
zDbQ6u8v&-$PQoRgD-Kxx*#WI#Fs=@#OSySznf&`%q+(l|54$s9b3V(V^0yAET;WUu
zx`Z>N^mHn|`CxXCV+c at I-d(tGVBwC6;hbp_YfrDN9_N1H4zSIK-Bn1>3KS?)Dxcsu
z=ap5<(y80ZUMbt{Gt`hodpCJMN*<~S=MJLmPh`BliyP)?Sc2F*5MC#kw?n&;2RZMU
zS00;mw at +oSge-c^r-Bpvhu2iXc<DlB0-n`jLt#0?3251GOx91&E_a(+g;*zD6c at ZE
zQkcamVUCYdyd;$X85;{?cx(tr-Q}?Cw$(FRCbH(OG0)R0&PK1Vn-}H?`-~<=;2iS%
znHPpjdaq9b3kxk7k at 7leY8zUnw^M807?SAN&IzvX&AwC_JGv;9zEqZHHvfqKZ+=lr
zO5ZSJ#;(OLO3897pV~OpT+SAsF=f3|tjOowbG)->rJ21 at TLe-jfG2YjwhSFhi9N#+
z98eOho3L&eix+Ad|5%zaO&hJO<@dL|4;)k_oWV+5&&i#-lI3K;o)>l at XQ6ZN?zkAo
znC|q3Go(bZan;7h64+l}UJklj4h(?Zr4Nj=^p-kR68*f1nMlaINV0z7BuyqW48{ip
z2Y=#U?N5~C+SEaR&I={Sp5JPWX&yihs@%Fw13OojU9m6*G^;suDZQpzYc9JE=4Pcs
zI}jpQI2}|O+snQCFv1gq at u1_vSWvC8T1!??Jx>e~0`A~0XwDl47OWXIHLnQ^XqY5v
zIEVKGcLl7Z=RGn555FJDP6yw1+BTHcT}*dufX#6~*)?d*8xE`7GjhK%*CFMVlgH6Y
z5)CbL;NUfpa_^SVqyotvXMRvZ7A+!?>YDa_Z~@Lnt=ToOfvz#>>38M?HvQ22eitsx
z$+Nt&tHX)sw_Iw=@65rv<xqk60fVs=t!2DjK{Zsv#AToR7J)Ea)5V9DOl}%8yIARf
z(+G?_M+`Lu8DLJ{$;rte0rr})w6qIuX=>f#Ugg;5yfG at o5FS3C$~OtDxt>nq46AeT
zAkP{2iuPhbV%UBk&)EpD-&jp96Cutq&V}>y^C!px!+MQ8Fo)Pmg%18HI=P_6csNO8
z9`Eh#4S1|BXqz9D=ERO)h at TQ3<?gllMTWW>>Xik#l<iJ6yi9-%IW*@k{e at gKvP`&D
z$CB{w4zN7{*^4s?WZtCYIb-j03}gW32nl-53$HoWOmb{oSh0yM`=$3AtFBti$U;!8
z85jJR*UlrJaArtkOw>u$vJB=Om}GUCh0Xw*LqmnrxNFM`o0OClP#zNPzvL=df-fOL
z4w4KF14GItl2We5khZFXJ|L|2VmU%@6y_J14ClkMrO)5uN+glc9yqR+xN=1&jlTh|
z;D9kXH0d+bf+LvAkkuGhP~DO@|Hnj0zu$+ean)=D-lW_$V9up+VJaB81HvZCXA*21
zZ_lP+DcF>5Z1IoWR&K#HJ+BP!@;W^{JnSnlCJH)W%}N)~y5%CCo)_GkiF|BK-o#il
z?nbo&O2Zk<RY3CG)gO3imLN7nh(wD6--LDUkNt<PgdvNDa=7C{N5fDqD>&MR#v%}|
z40%6Ecly?TlZ6+HNF?0TL76e{4q%h7XmzVJsrCI?C?U;@U7a=T&fTW$ej8TjM8zFh
z!<$$$1T_imvKRor_44v^04ZYL7$$5;qC0&FIn1#!vVee<dCOi-V8NI;Sogtg7|V0U
z&2V5)r!tqpWPi?$%gf6FRLyG!IHzGVPBJrSTd&tWXODo>-6rt*KIfd|QIO-iTI!t%
zEwdt=d8R&Rp7ViW?9ybGe<OpN>)lY*<OsXl)q-<6DQxi>J$9Vo=CZob<8urS4EIm+
z?{mfwK%**>S7tFHcU)K>sIGcVCSNf<dXgWM#Rq?Xj;*`b6l at 7dSF6<k=8FJ;tuk`n
z7&_*AGY{2kDrK*U&C;{WWAAxqz9RD~Z3MjLtlVXj*@TBXST{VJ1fP4(;sE1g+lO3J
zJ|~Q}$wb2)UeG+A7v`aQP0~@ixVRX2?07Hs8SX^I=Ul1*yThBlR&@W<7~1F9lVrw+
zpE)pTY-l`x%Fy}nZ at It1CrD{Vs?P~6vniyFw3f@|K+z<F`E;+(z<>wpEF5exf1e6U
z4%V44t|GXj<H~!!&b_C!BYc5W8FI_si44I$<7WwDV~aVwTrINigOj}UxJmOp;}nzJ
z>kK(DqAj=SRIjp{R!V}Vp;Q`XI%u?ERGLPnTAoc4O`3LML16M+r7FFd7 at KsjH!<4t
zlueB1L(r8NQLjnXmmxr{ZkXX!3HMA6jXf_C(wMT9&sDNKFOUfKJmUb$PF at R-kH?Pp
zql9zPX|%+!6;Dzc(wn6B8+#kLqvHhFgm^0;Ww8I83XlWRR3&pz$AQ!G3vnkP<(X;8
zw{Y1B17_?KD&qY$l>|9t3Fg_4lDG_fDq%7fjp6Wg;KIS`!!Lzf_&4*yo*3rb`11`}
zOn)QuP%KAk+_vW(=TLGzJ?~7;wcM#Yfv!;6P?KQYuN#(UZk3BtzL2 at K8lOAHsR-u;
z+vkjnRtX0+soP0l!a=P<WayYXKHfW92E9q at Hd3I)ne$$0n62TQPQY8T-|4-?IdgS&
zHGoh8ugXHOyZ;H#vV5~uS%LVpIw}@!aj~!Epl)PAavl8KZ30VW-SHBH^%UT666&H+
za;s3+v_OaX(>8@<-Z{p|u7nE}6yz)-;k}wf!XA8S=<Qf9Efkz+_?)vjG5bMFAS30K
zTWcocYIki7N%VeX>k&(18wPA|MURbRL-vRDdOh%kN;qah=P8^R-f53P_DUnCC=Rd(
zW)kNZ!bm8qcP7`<U0u^zX3qXv_*u8WOoB9lG^@kLU7PD*kB)>#S?<&=w)8?_le2^|
z0cpx&Cd9~@s|lkm@~kJ5-)~<A!}3hl2V)9s&bVt6(t*ji66W@#14_fIjN5irZt2EU
z%3*SuJlisLOhQ<itl2$2v+CAHkc4(aNz7rftT$tqox-eSnR{iKUE}$^kdw>cpv|gh
zc|hdh=S|j|nCA@#dwO1&P at b(*Z{Q?a`P?(;GH%)}dGi5$0NC3gRfbFywyb0xo=MI%
zlq7j$<`>zdt91Z)9=np&k{C{JB_9weOX-%r_oJ3KlUwp8v?pHQNfiO76I2IL_Q1(X
znX$tTIJ2wJg1&j)_yBRD;tntK(%p6AvRPA}w}!2mSLW_H2bf_lo>%s5F)Yt2JuM-H
zRMN2 at n#sE at se40=e2yWU(&7YqP1zXH3QF!4Q(aDokvqIjfUTnF!VB+b-f~Wwf0Q0Q
zCVgk&gz=!lYIl0`8S{)!3x(`rI+(Wal!I+UT|r%N at 8&x?Sf at Ii92oCM2?w<zTq?e~
z`pa0ld(M92zxTYuW5<b#rKx?6xto<TyU(quJf{-QN#P`Ut|^6|owDR+`QDNX>W+=Q
zRt(`u(soO>+xv+X-3%?W&rI?_e1<bGIHzpAVc0+CAcYef_|nmFY-nZD>>#rynI}$k
zTJ{ny=-Ic*h1M1)uhpeZ-k5!*%;j|QZ(2ig?mRCNve;5lwCZchekVLU<0C6n`W$l+
z+y!`dR9XUH&`~^(&5g?aB<J0rGvkUyssJ%rTB;mwD?ewFW+z!6ZagqoTaxr`oMX!D
z+6|h8ZRnYO8;rAbOUtTd$Q!!bWSLzSOLknmIMUe13yrMW2LLJ)BzrtCOEcOD+nXd~
zlaiin;t6BHDcd;7gu!G-$1>UQ0jv_#N)la>aJw+gM4ce}fU%EEcAHFAOLDFgjr6qe
z!A?-+mOc<4lORp}174M?9Z85cp}tim^a16Co|Uxp;7O&M)|&HkGe^dqIMzf~LsC}K
zl_hg%z^r at yCoj#?i^lUC^WKtI_ShQY;x+G0j^cs2OB_PXQ`U@&HV#sZIrqG1`OKI=
zYB~2TocK8#u0RE|)$;e6@;rNvlV|L38fH3?;c%p at Ku`uQ+HlS+D%tbGd#!~I3}bV*
z$<Q)$uhO^5a7*t;7LnlDI*Bu;-9<H at V_6)?>Mwf+?{!d@#)kI2GTGjV2wf}oI{O#V
zaWSXP!91Nf4s;49K+l{&)9G`9n{x8*5N9XQ;vg0a at Hyq`Fz1+gp6oX*saVz=>&!t<
z@<7-xoXD6<*>zptiOaF~*m>TWTb0SXi%yngH=of#m*bxlcJaJPvrZR79nfZcW4U*8
z=2|uY$%D1Mg!ghM&?daQBV&k=;Z$kdZ1qmYKFx>ydyKkZ&A6LowMxq`x4M{%#iH+8
zxESe9n&IV+Kg@?Tl+`gpu1WTr7O#voXZR>dRw4tknAzfqB>$&X<aWo!hL-N0=Q-sf
zvtj&>U+h8XHRE~Xb0#Spv)QbNbGCf+97ANcD<RlUkkc&P=a}OkkBwvbiL3732;d>`
zqw;|<!N{(%MP at hxuVs7C`uqeYE$ngPBpuLN3fcpj!MFnpUbiO(ue*InYm^C_UMp-Q
z4#ry!ryNp-1XzC1YA+ at VCMKPYfa<NQyFPqqAG$hh$e=NzEhq=DH*W+^ggBfHn{z;H
z{4SF at 392kMDq(3j<*Yt=9vq$ow*)54L(5hg_iXqS_wL^gKHl&rZ-UH4Lx30?SGqhe
z=oEU>^t>=UtHn=pW#6r1!=GAXlaiJm*IYBq&lWd|gFk;8_wQhx=kDO%YtH;5W7dJ^
zSVGvrK7n}h)(j_gSHiwFY?36;CViWHYf^U0 at t7*1H)Q)VaPX7F0 at X+#nddycd^of2
z&d$yTIPI)1JJ^1%3u-R}2m6-E&2E)DefB4^#}yqF#;?WMbBDzH5rKoDtqHqpd4Boe
z;&5ygz08F$f2ie|;f{`B8cu+jpI%cA##1?qv9akizl;5Vy&*+w7#oY`*tdcGi2V;Q
z6?e1P&-k}(0t}Vq_Zq4J1Sk_Bo^=x1y>{70+)bkL&YaFJW(xk8E5N+*8aq2X8}O72
z%S-r^*PJa9{PzUB+^fgVd`Cl!-0dRC<Xmid#aQvp9bWI%_O)si>|9WD;iJXX%tVCo
z<8{W4bF4*}cVWeel-C&hA^(m2$OSjX0r<EDI1=J))zd@{xD)6^!aNJ+1;qt-n|y}1
ziqtMjxgck;02cr+FE9K12FB}o=7JrCq34iJtT}#9nj0r-!-bVxbB33 at o0URNF63H#
zg#E~d;Wp at X?C1A;|KWA7c{dEqmo(BT_hK9TI)?FH{G>BuuN40%vf at -&Vn9>6(bb;B
z_of<*4^Ox3t-+qEWqx45TrBzNj*M~F$+NI}l*x3d5 at eo+;RKe!H9po^wO!852S|tz
zz6~bCgP&y+vgbvr$xsPP2vWMwd$L+h#-@(mfD<0&P0lbDYsj+ at -JVSOK}&|ZO6bLt
z@`NS|GPcI<qKINxpWF3Ti^)XC)nkI;mi%BE)R{Y#9U+h1#l^*d%-d4!@IrS>A4NCw
zJUn*kGeZ^9iX<jck`!1-fjLaaBfAF7f4-XzqN_12hjyDnwu}d at Ld3K8CYbw);ZrFl
zV10cPsne&%ZR_O7m|MlzxJzodrvujHRx#duw=1wth+W-n>E|CD91Pm<nZ$YQ4NWuG
z!cYri=7G`p at XN!M{cb*=54xnRce_!$I_<#1FkX99War<UI+J%3s!9dh`%(HjWXH!&
z+lE*9-tB9Zxa{X-xs$JGckLFO)1>bdO0Z}|@<0g6_<NtxbP8Pngo}`C(%da~>ROd`
z!#OQ&Z8>;Dai5c-O#@$wl`eR>3z`BOmTPx)*XM+TYgg{`-p%o4?%Jp|rS5s%XRx2m
zYPITxTP$5|{t;^iiD4I=3}JHdfahii5DBoAO<VHL38%EusFSpoX|)p-!-P{J*!xxb
z59RCb!T{TIhdSk%4a;-a!90&tHM11Hd9p2qNEiGPK9z}x|82u>#>O3Q7iR3q#hkal
zk*z%pyECWHQv4n}+YA_)kYWL#eSmKzbl&0}6!enYog5m+hPme4T_;iDxtk}O+;hi<
z=GY`0lXJ!%Jee~LU}ou{o;Ph}trQEeZ-fb;Y+|XrWkadFsU)DbWGhWfCZKfX$<DWi
zATfa~TbVBC9KKYC=?tU<v85s%klM5;tHZ|6GC9(_fGSqD)Soki;{BE at B?wuqRs*vw
zb7b6pv at v2z@NxKBUNASoREP2==k}pDAvVbjc&WgrX9a<QgDxj=%-fVOCLqmfPkIvo
zSMb90yfVzia0mxkE#k4EYgUxYO(><QTkt63W3Bd*0c$G0CC7#NVaan6T$5j0lAkUv
zq>_!-oE1l?l(|sCchiY5gem=t^4|IFPGHlU!1re5tvs9wXgT1#-&it~0)Zig9L|RL
zq~xceX)df7&X7=9=5(qAnfv7~3D4FClnWy+ZkV)f=$Y39dj|)5%SbhaRa}%JV0CdI
zP1>vg>BGuvCY1mkcsN-wkvWYEefYMxo=$KRLY<g(_9L%%7u-?=!d*^xB^-1y?<_6N
z{_Z5uoIQWO&5;cOGQ`?zj^u(f*wD58{rv%k-+_bg&9d7*L(SbvcY5;yvXkb*hM^?P
zyX4%Z#e*S2-V<`a;l8Z0=tRczIDKL~FL-X;Px_saAiE&uz246yc_QhRLIUdo7;7>O
zGh4i~ly6Q|RZHD_UO3(|4}>$;ohb9xTzqgxhI!$l6G>bvc1*)>l6Mz+nO80<+lwyG
zDMO at 98z3>@-Wi*G?nXuUjOSi0ubigT-fP{JuynQg)t2o}{!rQ!aKFqOVkURj?G=|C
z7(>^b$Yfk>k3qiM=EbdUQWor7;J3wslQd#CL!jM_vPHtPYG$q;8-CSV=q<v!gDy7c
zB)fT``+#W4%-QW3>?MjK*?Mg$b7gzb8;J>|c>uY}=WY^R2P)qLRT=DCLNp0ouJSQ9
zEF^cUc-=CQ{%y3C4J)x!>}s{@IW*=Mx$AIoaWT-8w>%+or#2gPHO6D>B+x-u@{1gh
zTFuUzP{QiCUmMsZNz%R!e3yxOY=TbWQU=#uMssY^!^hkzcO_rEcrhUQB_E(=rj_K{
zRF`UL%sYWKtj+<cja1WY)PaeiTb4BEx$v8=uCAU09{#-!3|y&VlLlX#N`HJuLIU>p
z_Xo*^KcBTvpo4%0K_Yt<8?*gF2#PQe^Vm3fw`jzR7cU0tD^$MiZD13})6>&_Tn&Xy
z*-3t%yIG8_$J)U>&@y{?nAFXjut}xYB$aXA<0Q}lpCNyS*znw$OV`)egTs at 9lfyTK
z66gx>`x35 at ueU1eyvBa#!<cTClT>#K*|$@GgWv8>iG8s+r}#|s6?yI?VeC<v+*3Jc
z-Pj|C-)_DalI4c|xzJ;18U;0<Eu0nJ&p2CvTYBEmfkQpha81^fJwmLOM^S}9&B6F{
z62S?9_B=EU*fs)&6nae_9UTplPGof1kAX;Aq{3%3P*r;~wM-)^ptSrzQg|hO^3r(F
zLIL)HVcvMn@!R+I_6E|^Dd(O(cb3Ubl|?7_Ev}}O{>*`4Y}kiWmDOYCLa&QP=7waF
zXN5__?p+j0L`fDtvIuUtraSdEWn^ABadNQEe%I=9GF~q5TanEiVh8KoyZJ?)SH#84
zNq1Z!>yy}}&{K=+=`{mo!fL*TzVmwe6B$<L*wHzIVaARfEiLUNi#20jmB-FSbVJLZ
zm1gFPleBHAG%%ukP%CqFR_%_B+tzN8k$n*$01>i#JU7i`;Q^)&yEm!iaai_}AP`AU
z4rd1z#@D(9M-b>18Vf8{&D?@(buCc+u&E{!B+WwE2$CRb7z~r0acyCTEf(PJR`NiA
zM-iB?iJC0u#pSL-$`kr^Hf1(x?%Ap#31>)0V=G(O at t7)`m9?^~VB&DXT#Tzu3 at G!)
zFceD&8wYL~Tn_KV=O%}y1)p-o!}BTyI9LzvR=Jwv3TGd%J_LP>#ofb3QdPC9gZ+cr
ztXH*KE^9h{Nb+`7+ug(AdU#ap)iMs}T~$5KtD9FZ9|{EbpTF5`s;jQL$^GHHxVx*#
z<Ppj-nM|u{*H<AIcenlTd3pV^rnBjz0 at Q3)i at V$Es;kv{U5mwCb={;^%lklV)m1$p
z_-nhpFT8a1(4pPmd$_knAJn at Gy0^Di>(#P0>u%tsQq@)0-5)Tk<)XHmZB3?=y1INZ
z=n5Pi9o2HNsO@$$z!q0^wcBm$^z^LmZf>f&dg7>jUsyS+)pDVEbN#USKNb%bcef9F
z&bDrEZ~D*gx~jeT>|yM71JAGRc2~36w5F3u|N8v_xv0sctFD{eKaWXQyX_`8dsUOk
zec;1$bI?=O)oQt@{r!X5Z8x=Ct*Sb at P51YGAIu-s;*P|stDBowPY9;V#a$Fe?%&^a
zUG2?hb$5F+IH&ISs;aKLPmphKUdeFt)%|bX?rJu_Uo$taUOp6#Hg$LR`2N{!T3yZR
z?)J8JyRGgI)v;M^)~njA at 7K{?-?g}ZHuL%X{`J+WHrve;^W&qV`{%ma-LI0nhxvWK
z$5b629NxcvKjrJ at _U3+m7u~4CTHM_gG3?FF{p-~|DBA7q*WK+Sd}DF9s9o&_$-v{h
z+0 at O=ZT}oSw$tgf?rv`%&iMPWna^icyKUXPx`$ldyn0ou)p8(CvYm8wyINJ(mEcp4
zoWAX5Q_JnPYPYMq#a(UIo9ZT$+HUVV%*(}{c(nKH=l<F6>hSQO7Pq&xtKA?Nf9w?A
zuQ~Rg+q=7m{bU%lxhS}0Hvj-207*naRBK^Aq~)3U?M|@I&(8;B{Pbo at WiP{@9IPkI
z*M^%;Bw8}L#7hL67Gg-aWh!U6^Op7$$S*T5C={CyNfHUyAyvtI#+w_K-c1%CA&zk|
z)7>r?SDb*S@)m*da6cF-k1`%ka4kmU4z92CdNa>sI-L##gBW}BFD<m-Zk3Bt7OY80
zbH>K}RznigY~3-u6(|$3n4&ZwjZ&D!MQJB_hVfe1#T^>^%%pddg=08pn78goxgp{B
zhGfS at tU)r<a>^zdNV!z=4-&7R)#1dX^L{5QOekZETLyJ$-uF8FellC%EY)8RsFOCs
zud-$Ds+2M1Ez(jtlx9W45FsXG`hi$p8A7 at pm#HqBWNGMG2J?mty4u6Wl&WNwo at OJk
z;*#HQjHfH_Ho!Bi&-do)vdMQ;$K8HRiDF~kUBzc1o49LdYqy1&cRsuf8EhqKNespx
zC{1RKO*RDbIZV3o{3%^+5~bl+mbUiT5JcSE+zenP^ZC4Xn{{n!Qt!^*su$gU-OjgF
zdyiZW)?5!`I at k;#1O2A9tJ-WgwV7-Ng!{>4Qr+x+(_7W5c89w`waJ_2V!NpBtQ%B7
z-$}F3)2dw!E5v=JuNKwKyMffL)%uo;Wp&5H&v#(6+FuRGzWlykyrH}A6xOb4GMx-6
z<-6UkRtFCR)!jqDF`Wz!iS5aDfDeAB>#CbSl85W)5n8r4-y{C(5BEB)C&XxTgu2si
zz)kbmE|<&N9q$JBe*gaah<UkO*5q_DC=fU>S=YL1uLcK*=k at wvJvf}1<K6t>_2c!R
zBgDMn-nU2F`}nh~K>*d?`|)F-FrUq<x*Bw8yOVAp6YM}{xm;Fv_V}D!7^$jSZCBMD
zcTYMG?x1%^T|e(!JYZ}mXAk$@O=>ou4LE`8Ze86$Hz+`OO|1{sPr7CGkjShz>)IYa
zj?H{FuWmAwQ?26~1U5M@>Zk at C9q;YS<+8TN+rjI6cXjt`l6xC`{_Nqb*)FQv>-xX<
zn(56_j~)Y|z4=~0j=SBiR=ZVA4j$)?&-m?jTkCFJlkVa5>14pMS+Cc%IodoSjqi55
z>Z)qDx~rqvbsgWnQ`6ej@#)#Xqr_*d;g*IW8^UAgm^m)y(0EQ*8vAt)@2s~}s5FN-
z)%1K0xocrqUaJ#m)mBSc+w{>~OJWvx at _0Y{tNDy6`|a2;z2JyntafLABTJea&S_eK
zePXiXV>9$jbXp#Q_FGG+YZ|R4v at 8w5z0b3kn$O4?Z$2ZjpLw*NSLWb&J<=frVPHt4
zq4$h!8iqTuNRL5tgr6()W`n at 0WG>_;-;pA=lTs((wlzs^me+)#^8<km!_3GONi_VS
zCe*v at V7Nk(+1RjB3Kn9sb<TMpR3MGdP2(Q(K#ad7kg at WXy--rZ&lQ)H$xVa0lvhsv
zj~6o4Z)=5Tz-b|Z491NWw3(KZft36-89(v*>Asp=2v<lg9cjXP9sq8wre_8BZcMtn
z2A+)8pwEtr$IfJYDqHsRa5cuC&n5_e$Xq5=J9rk%o0P$A$s?vvf?a`Ktx4`w9-h`&
z=XD!mnyZi|YMH>gYGz-D<#KtyUN`G{w>zo-^Y}N_=Xa-dwb`rP-sC<i=_qdQY7kXh
zG^BrBFTU>egHRmV#s7Ko`fm8|FZuO{|9)6s;_J`dTa3 at qYwmsjbz>8+<*?SS>aaC-
zeE05|d+%N|w(%v0-Fv_HC!hbiv3U>kV*gh%Z at R{Fd#__tPoLY9d9l0yeXkpvFM8g5
zIbMG+b9(oM*UbK}#+vIMf9w}}c1OR0vDts!*zBr1+}3HgsJAxn)~9~yZ&&y7-8wuz
z>EU at 4JSa+8KHkuI7p*8p`gOyA=}1tNvS)_li<H?lgxtY8P*#HZ^sOSkatFrel(`NT
ztx3{%8Y3EZmtq3uLRhuTFkSPD9G_&D(makN`x`=J4h?^6S#QJUtgdSbV#d~m3ZrT8
zVzKX4DvR0=&2g{glZ`krC(uQ1OW_*^Yi_xDs>u;fbxnISF;_tIF!tuerEIt7g*^yc
zW}hxZr{9^2NW`927Bx2<IH>u}DF<&l3iE~{tCO at 84;dsgEEYSk8;5DEACu9UtqGoN
z7*-{-+^G|hl;E?@y0O8AN7=_AWh-e5Tk_LzE4Rpi5cvV|`3`8U+{0u~c$7)!#_XpM
z0f~;4AzCit4%Tf3>fd6umGo(G63Op9KR<6y)@-d>8r$=O$!@K1XYou%@X}dvFkzj!
zVZ1#_qKV<Hj*LBc%zd)ji{%Hwx4QddjHs(IZ1|R?v=0pjjMeN69pm$8y}FWS#S_Nf
z#RFH_Jg>};p~~ST&hGRkZ5vy>Ua#w_JE_0@*6*(C?SB2i-}>?TuCM!Oy?wD?lZMRU
zc#YS1jn_XZ*KW6~&%L{-zxa3Fsqg=>pR2o*kJYdHhd)pk50z&p7*<gvU^N#a4R)VH
zlvp{8&vyJneB(-W786~RvP>>#A`b2B{|;zVWFn>N6Ln#gMW5j=umKU`tl=DUK{9zB
zCd at k-vDqjAsgo?DWgI&iHfKI#dZkzjpEKNrTq8<|9bJ&m*w3g4VoTdk7#U#rH}^)|
zY+)9wwwgA;*je<&rjc}uT)Z`p%kwJDKHUIFuQ<N{^73*ZxRG(OJ0garWpl%vJQs4E
z=y**bLIPUHv<WBB?zm(U>IB*G>%cVAJQIR02W`elCZXL69VmcZ%$e+7h)MQ$wZvr1
z%$luAW@%|xQ-A>Zvgd`9G#<d&+1a42?99^8vvkIF#lsJr%DUaI{lH8#c6-vBoC&7p
zWq1QlEpN-AvI&BJb;TkH=Z4{#unvCK-Kx|IClR9Bl1|)i54zHoSvk+fZF4KWdES^{
znr_hvn=?+@#)NEwBm+JGY<%bggZG;&@tjO<I=C~oUK6f(Sh_K>$0>tLHOE~}Z-S52
zlx?lIyZVXqf1&nI&g%z$|7YqOzWTft>s at WL@;YAQHD2TOPu$hjXFhyX|M|Cly1wIU
zzN-H9zw{64bD#XyTL0vqsl)w8c&iEXc@|iKlC#wXIg|a(S9JUWsv?yFfoi72u)7+Z
zQ$9yh^~~@o7u*c-NzW}8^sMA%E<-}=SF2SIp*F<G#Zll>*|i|fFa$cKui<f6yu&Jw
zd5+m<&qk;GK7#4w at KW%!%Ax(vd`8;~%E7of!rY%@$CTw}-tgNTU(rP&SSN`|_*6=!
z8 at 5Ns#{Pz>NSm;^L^9=^PqR^;dCL4#sI|9^ImX1 at R$;S3Wvhs8F#+46nE%asbhpdJ
z=&A?POaf9CgPn7I(+;XgWKv=;Wibt-v2Vrg?d^bPVjXs}em={}681_lS<Z<-YPg$}
zZPO(FmWqWp0&9I6D`<?VVRZzQJPaorNboVS!AYhGTdG%)u^%5FKY?eN%fw{1VKkj}
zR1 at yo#z_I`?nY3$91T(mN*Htr3>Y0FN9P1-COJ|>q`O<XLmEcPKw^}1z4QA!?>YOI
zb9VOd#C=_#`?{$PUYSF<kyk74?<WMev^d%njrrNa+%6US-ZlRMEgW)D7?Jlb7f$mQ
zZvNypFApa;bRIQYS?K$bt^Z7DM{3;0V&QenTlyAsIFztu-CuD=n3Q;*CM@#u=r4B~
z!(Z8pFK6E|%stU>n_bp}fUo5j3OWyyhqo#Lh$WC`%VJ#A$iJ=F=2Cv(tlv=L6mYi$
zI(rqk&9l3^#(B0|5~y5;a=yMxX#9x@)ICE(ad at M7Zk@Yyo!fNVZ%^nCj-1uOhg(G}
z>B5X9-=*2OSVSKr*{A-P9deE0N}b-VSqTFSr3!({j-V<oyxQCPzw2Tro$s$bJW5{>
zRE*SyizjoR=Nas9H01%~?)J;Rg!_1#q|x3&#iKM)jmcQd4{swqtA2G!-+o003o_bp
zQMy(2L$5~fn9+suba+(R2)R~11dP!)ru3mlh+aYlvp!eLR}5liATZ8MU(zXEKF-mU
zoOELaCD;@4BpjU(9VR`=zkDl0a?19>VsI*!y9e%I5lKdf=&BOQ?%TDt$uMjv5zt^+
zwvaPqKFZ+PC=QWP0#I|#bLS0XdhbmaTSK8z3$DW%bEBMH0vR_|{_IgPVeavAK;Vxw
zk#BaWSC!fuUnqW}Y^tK%4u3e)$z+=Gq<s8dVqUb2?ne!Qn0r0GTPjkMRIlZ4*w)qK
zy7c#UOv13=Ny~F-iaO5R-|I9Hso<9bYaq3ybOElcaZq=#&)KPSOL30erAJ%9`?D7L
z)2_uB_5ZD#cEzZ(e#f4e%M4FkiJAZJy<HU2x&!Y+LXA#P(%FIov&Ky(CQ_+NSgvEO
z={i#+9N$OkFa&SIIgzl0s!U at MAR1y>*g`@eu-ULA6x%q?Ox?X2%e2-&{$Qn8zJ*Y^
z1?Giqx9a#Hx|*eaqAP~eUoBB|UEm`$6nMUU!HBC!WUeIF8(@j?xEIM<pcdZt-UlT(
zoiU*$yXGfhm7pZJ%*!K<x?d9+xcipa+Lkwxx4x3a#V~29tIKJ&&k39nS(R~f_I)K<
z;VY8+Nu`&d_+!I%N|U~}wAigA%^M2$(y_InW at 1-0mdi<gK<J%gS+lC at UTn+?w*5Su
z;P6%+6nHLg?zUdHL9lslq1P8eXZQ-?WTy`-mERhY?pU=k>>TpR1yENnex_vzKXoKz
z+_WplDSOwK;<p{-{H9P#2A<2ugqlxt1l3G<1cNARTS|$=5M|&wObTlTn+*Qc at h4Hi
zNa?GVU#D1uTH}zLh{|`3*Vta^-DE_(@aCM at tlBGC8NovFZxJ;9of+Y_d5^qBKsAOR
zW7ii9NIdF{W=c}$Jmq96e%;yqyZnHHV*gIh!#RhB65pGRT&;`dW~obaC)PFdOm at M@
zt}~DRC(+5!7atNf`Gr$q0V}TD=k{Y9Snt=~L&lC6uL5E9?`XD|^3n#=p$3WUuc9>A
z47LxW$TQVMXxhC){VWw|#iUO6b5w;Lg{W_$bmTbRXL2$4rl_-gpViWdlsl#cOFX`h
z53nJ^Ye;<zz!Y4jV0Ej|`*OOMSr>SoD_Yul$;9x9EAEnK^iv3x5g-$*RkeOO0F3oo
z)SRVNwK}py)30(nRVL)z`J_fsBkCBC6d9M`{#fGae$A`Ir3=*MBdT<2r<<Numq~dm
z?V^z_t1f}skuh7bM7bv`vF57_^rSIbn1l-x&xMx7FU0%@CDj(|`VuG-z!k_4I-@?&
z at l_xKHhIJgTi1A9y^BXpikcI3k7+ymS>|m0QwGk_RUYO9r=wS1w3p#b?C%3 at cJ+)`
zPaxKh=bK^u+Xeo4$2Ca3g0YsWUM^J>)DX1X7ka*@mKQ#K$dfoooYCtA28#|{egHAo
zyaU2(tX*1N930aNk)$F3CN@;4(bFyhez<vY_Clm*oylzT_vZ)2$Y15o`oPZrE!?Vu
z%i at g3)Qqo0*_jQ3R<fd^0?+TMqVWlHS*O*Oz)i at vyKuQZ6G%fYiJz3}vvW^xm89Xp
zCaZZyOb~|_MdHTgPH!}Az}E7S+lq^V*b>p at 4Rh}I)@lpS&W;aHL#i<Ay3(B;NJ0bd
zXQzI}3Hc+9o#MCzsqH=}%~w?%me~)$wwUUCFjzv+bb$)RjoV=>i3e|!K9!gq%Qri&
ztQUQK1m(|YxkS$`j?q$HL_y?%EC4Xzu`CB4^}T<-3L<gkNPkKNQwaXaam5qjJ(B6F
z)oA!k_+|CkH?hq at jR~vMb|NGx3CSZ<SW8O_=It;vBPIQ`+gW|G*=Wj-b^z2DE;77A
zK~xwYBl7+HiL3CKRkbD6H?B}m8Mi{i6w{Hi$Rud0{~S8y5#y^$=a5T7F}- at Ogj5px
zn at RuSO5=X~{Z_O~obsnB0UXdiHl6s5x|(S<OGSm(GAhTqTU@)R*hWgo;8ITx=xDMK
z`ZjecjsRYB%l?VFBWo3_J;iPPPCfK5H^@<#aFQ`(4rhj8m9aNW!-HtsqpsUZYK`Q4
zAaC>8@$@l61^RR0?fvp0sLhBp7bx)IfGZ&EVtc=mmdQ_KP=)4i at YqdeH8_=BNxpE(
zcBV^qn<~cwVuSTse^v at 4>CJu$f3u5~9d_j(#Gxfw=nuWQ<Ki7WtF<M*wQqhDcegxQ
zwNV!4iFe8s;@>XA+Y`5(Iw_8fq9YDh3y+?Me!>>OmUhX*wI#gu@*_HFj-XQ0$=opz
zn771)>eJVQ>SUV at Q9V*!p354E3sEFl(%mhh07u2WgRI|;=_&&v3U4JgI0K{EqdcrK
z)eNr}IrOn}=pP}lk-M%*&2ntqx{R;>XpAPiSNiHTtwCe*HGE(}wXmmF$V&;*>1wc^
zi!l4%B*Bey<=bD4JkNJ1Gg5|(QBNV&3F%1#31>#V!xt-|Gm!m6R)5q=qF3!wE5dMa
zF<m1?Z{++dpP}=W)VmP8q)WqiMpH3wIFa9}5?1|7Z)l2NvG376ss9?bwzMZo%W%*}
zI_umCge(yGu0wQb+ at 90Z^_dqiUAvHMjDlc5V4MV}m_Ud%TLg5b;C)V$Hrme at M0>NE
z`HTgr{SK{td&F%3_)Xiqt0<nS$9(`4?&G+r*w3>+PV)WAaqL;YL?$k(QHS_R at IQdg
zsPCrC_vNh;7)T-v5<d<NIC<(}7$DY^*_l7Z-5JQbkmyG7l4z2VmeBA;r~N&dt{+d7
zK$OJ~d^+gqsv{!t0)^FDP=*K at oS&#(LS25FBdiTsT3S*(o?)i<sg#vqG_(1t=x<J7
z^On|M;-b&x%>z53K|<t_<H)+_vXgU*jHkc+>1QsOlv5(FGVh(AkDLs8zWkb at OncP;
zb;s!Kc8ZZp&d6V<j888{Nx$Sq&lSbUusyLATUaH@)3O>UmRr*)6DtWUFERgNcpW17
z4m0%kEN at pM`)j0DV?I!U0)XvZlKC65Z@|Rw;kP`pecB$HWQrS4EZ_n=Bj__dIDYve
zsec}l-wFD at 74h?T-3B8QBi<%@>O8h)fEmx4cW*c9ymid#_XXEve8gDmn`(LYfn;8w
zWE;V|ca`KNeDCbIcX8m`s49{6*(`Z at ve6j5E&X_ya~k!b=%kzR!Y59~Oj0_YcUrE7
zl+IN*<}Ckq(6KM9e8%1s53_1)2rU&ZM4PhP<TR|2s*1bg#$>4Nv~HyaKpAgHNyFP%
zNMfEu9<+dR(gv-jaz13b3w><g4-0C{hPqI)l6R!-4Ia8%rZBTBhbLj91s9J(iN)_*
zdEISNmrw53 at 3bgt)HEx#_<QHC at 6b*RHeC+&f)66o#!`WAYGE0{WSjF#&&vH36o+0X
z62g&ijF>Sm6%DL12!^Rx;#s~y!RE)9fZYO7O9x#*Rg>8mVoAAkS$H^qD20WlR6Ck#
zdSX=}6{sM>v6BjdrR$(xLzJ|=8U_Z+&G0b6)>-ETEhHL`<b~Sa?mOH6Y{8rE^4*||
zkB`So)9YBBigu1YS$h9+?0cf~M^OOxV=V2BkWrf&#l0`3vveOiQe!!y{H?0^f1{yD
zj*rgowPMt)k{GRT%VlK$D0f?VQrO4v0v%piZ*mo#Pk^-_ at _KTczgn23QWEpblbnyn
ze%-Lx$a}sr%D7oQkI{jkCSlYn$OmWGK`6PR+ at D86##g&XE!l4{Dve_Lz0h73Il3bR
z{c2C7HSRDSscBgWJ$@fEvJ2kx{G65Yr=Y}Q$B==Qd-o?ZHSI_wxn#rB9k-WcK-Wju
z7LT4`h7T}PG8)<3_DCV;g=7HGzLtRlrSh2)e6=QT<>CFjP4}3~(JCN~SeZ1^vH+;6
z+%a|3QhXq?V=gmzOBWbs>*l}dOn*#UWx)VFZDqnX&>bPhp$%z@@i=LNpIUxPpnT$P
z0(KNFM=C{jO<cu98$;83Qev3L7g at sMOrs*2f*6Ym4LaG<-TWpDpGS95_&Kv<0;{TN
z2>S&DyR9fVen(_d_?j7{6ahPlo`IL<!v%pFhyvl1Lr=`YET{DSfdPmpNFq7{<=4<E
zQo)G5`#BsYO5<Bkdv|sF at I|54T>!2p_&4PieWhw~pl#8)=#QW(`pv;T^}lZ*Hqrr7
zfM<IL<_IUtl9YFeu6|RM at +DhR>Q*d?r9OG|Mm8iwWgs31Q(%l!5|=>PfVaB~%JLe+
z+)>@izp>e<yVU?KQ8qGSXZ*J}#Duzih}iqyL|o<<l-u>Z?86|LH6Hp3C1^3Q6Ou$*
z(fcxwDtkk(l29DqNORa_X_nc!s}n*XbjT)fdB*C#SoUE}EJnog7Yy!4YUySugnH@$
zAJHNABUi_?ZL91_0F}3Y&%Bg8*m1z1?lyub2P<V8(zRD_FwmF=!d~RDBNTvGA<Gg~
z?IN$1TXQepe6^U-jZeOd78TUO6poLb*>%K6;k5Pg)s(4&3;7>)&XY)sh*aFn02PQ^
z--Fqu%{4`he&%bmgQ^Q?8jVe~tkB0Z-pOERzR$zVjP7cvQN^66mlwd6r at q=!A4Mr|
zU79m!k5ki{Q@=}_ME8heEABD;^SZYA3-yzM9W*(yBuPo$P(}>jbXf>*i^7C&$`BK8
zo at U`RGg$qUj=~?Juo|O*2*2v<YF!$;jY}CPvO*8UZlV?S<$(y9wbFUOiHO~wj3hsW
zUD%a at 6>810A`N9bCxlO<vtfU6z at 3=pf9$$<HQ2T~-$;gxDhX_u2Wpds(AA~=?=o>7
zb=7j!q8HSB)mL1MhS1_6=jZ3wyv=u0BZ-4wzW{k3+w32{B<ZAnVj$k%Cm+!MR!}p_
zB1hRS#x~TC7jDEnbWE!1tlX+d;>s<<wiV+7!AWY(_1Uw`&jU?RNWLoL)zj79pp^XC
zF45iOBi9cYeXah8C?3p1`do%nDN- at g(Bwy5WHRACYRt9o)Gw2bv8ZQ{g^|KUerZDV
zw2)Z6$G2OZ`{JdE(-3aOX at K4rPi*#&pi+?{>w}{Qgd3Q)x>smpL8j}u#4_1v$aqZ2
z_#G=g%%w at 6yXM#tr{)={?M6JSBvZ=Yn>9>N(>Weq6EAJeGFO&JV>18>-SqHCC*_iJ
z?KxE(F>xy^HL-m6x2Mv8@)4P|3vQ*kE~`Lz1kweV2RV`A`-sLwm_3hb%8 at 1?KVDQP
z_>={2l@^;dPr{^Xz}>q$pBvAHy)RIwq^mjAtFzk;cHbn-8-D-sX=MBz8w!Dyw=E31
zf8B%}LO$pQaKJ82C=8I+uNBafeHFDS92>3l!h&%ZH5X at ST$i|d&uv8c1uW3t7j0Jh
zjPu%{_5bFLppSX4?UMt$(<1+q0#gG=SvM%X1x8fWwglly;8`ohxVEX?bU?tjFs*%{
zPg9;X&NrO?Bk`vy1$6Hh^-WAnh}fn`4Ay-YLqmd--AA`G?<StEJ?Y6P{{#W(t-PLA
zxz1xR7DK;!chX>Lxxaf at d-T3jUpCMyVl6^*=VbNV%`XE$AW*>Vi at dq0!~+5RzANW^
zQ8lP!1u=2WT0C(#bLmnH46;6-c=<`nGT*19x|zMx{rTUO<1dW(K7S=yELMaAFZYk7
ztN5ydXfmRLd{7e{bot>L8OAg3PoF>O_MrMGh9@$ZT&ZL9#xgBpKem&MQ+fFPqtrpv
zpz6)|5V<p{5l7>5wiH&4dr}x8ylngSMNH0C!#58g;da`|kaGyR4>+A46eSm*wS`CD
zLL>Y5Vs6?{LUH7x&kE^%e0A=1JYV1ew0w~`pWm#i|8pu5#SL+E{I+YpY)YsvPA7wI
zM3;!+A&iaKd~Hy#S4Qp<_r{mhs&M>XG3Crlf<M64gz2cYG8oEdp>sTvRegK1va%8^
zvsGpBVg1OjB1-*YxBPy2_2abf+{_ZIT=D90QQP88|MJ2gRLWUu&~E*Tsa{qNYOcY5
z)FNx&3uyFTh4j(i%}U~Tx~o at 6v#Wj=!n=7 at KvzHK_&l#F^|P);)W`REqS1QKHeDik
z@&QT8MA|dF)l_wtMBXNm2T43|=5(5VD7s3i4mjZ-AGu(x2W6916poZfP)!lWiDgJq
z^_pz(C^s-^h-u+0A&-3bcP=N?*Y2R?4At}1=eCN!WGf<rg8Lf2yfLnnL_eTQqO)l1
z!Aa^d=FZ6wAaqvdoO4oRr8U4d;k(x at R!~M}?iMG|IaNv=8h3m}L#P(d!qd?vUgMV3
zltAz_HosP;ggEa#4`PUVfm?KJ3LCXs?Kz*7CdoI>H3ExW-L&cyZ6t~;puc+|(6)1)
zW*Q_gnnuQ{4d_l?X2J1F74=+p7~%_KM~@kl_7pxC%m#wm6XkrE9Q_<eSS=|t$G5|{
zoZHMuiE>6l)@!u2v>w5sQo>pr^N~gsV&?=M;8#4%@mX9(#PM;&_8bfEss^wL99b~D
z+B~twGB`wP64RRW2g^joM^F2f`6zT;sQO5LY3|M~`$_$6DgLvid3W=07riLha{Ya^
zU4Qj5J%7=-Ec;-ivF66H at Kr?sd(n>Rf&Dppl`lU&6kOvSqIM4|?#%->6 at tuoL?1D8
zsJ&eH^WQxeP>~v(gvCWeu>Z`9-CN`r=qV<hUtJ4Mj|B9n5eOs8UEVX at IoqaWHJtcF
z*W;I?SvQ)zb}@gs&;<Zlyh-RMvt?AN_o=Km5cVGm1icKWdp!I4r1Xn*oN#feVUHF`
z6|VbEt>N?839nPhDe<Xu3KSrH>EJRv?y)-hk%UYpycPT#TCYx0DZ};sNy3jKQ!1Ie
z``?oks}r%W^L2O*wLE-ctMZ2}bLfY`VmzY)+L*CSe*H7IUfIm98mFi%96bUXB;z?Y
zd!n07KXh%-M$`7qbjTTJSiO5$mA|v6k)>o4(I5X|%eBLhdI-A=JzJWDPHZXbKyq>i
zK2jjRf0dqdh|cIKd&|2%^NiI^m4Qpcz?K<CESCvNZ92angL^aWBqpYMY<3 at Yd}d
zqV=cw9*fNS_KuF>RO?9N<#5&UOY at kgh^LINkDFs>ijn`%0<>r%wdjpfln8F+m3vPx
z@)m#I8LM at bxA%>M*@bqh@(&zE;i_~-FMsrz-W>T|ooub0ne2?fZ&n|A&%{Y=OlL|<
z?yml-^Uclgm)Aef(i!E}g)Ne>S;Pm`l&Cv77`32r4K&MQ*HB`3asAEya9x6Fq%e$R
z>(0-+Zs|`=O9c~`b8DYN>-|GeQ;oKMH?Bku(CgWSnIj9YtJ68SyDLf|lJI at t0&a~z
zBG3WQ;~_G$tDAY8DI&<#VlW7D?^~J*Io$Tl=TO5Ub_4i-uB!PICner4;g?6I{iOBr
zjx0#@$YqTEwD8 at mXnc<>IVWXsq*S8%P7t at KK(<=(ne;pMv8s&nGO3*(M+&H{s`J*g
zQ5(;I07OSl)v5OriN`ziz`^-%^iMBPagUFaXAXQ2S!&)&rH|o=A5`hCh4E<&-zX2C
z2MxGqJPIb~X?3ps#UDnczmkqKRy^v-##V<#IRiR%`N6O319B}T>cX)U%~0+>tkGb~
ziPw@&HO>*Zxc;r=Q&mMLhZ$4DWxmy-Y2a=1=l9Q!Uc)Bh=UFPg?2NO0R^HY(CnwdU
zPzkuEsfmgBAo!VprZB1;n=vE|lIu{Ucz7WbQnwM+i?RIkw^U=&m$DBO<U&k%H_lno
zT~1ec$0n0=+ZToY)yH+&68_(t3>|;2P#G`tnbo|{rOf)x8WLc$>G^!%w9|PiJrj28
z?t@?@`}A?vJg8-1THF7;_&%Doskq~~rsQUSv*diQrTq`~8EfFCT>#j{ShvM at +kFmg
zyABD>k=~6o at A`M#XRY3ZG+(o>6m=X$w=CX#kDt*F+E&f-h6 at qNlobCdE$O&gy>$$@
zd8jSFJ~F)1UzIIVxKsEz2MP)_KC9}!Za=&?xXTOj)q|slBQB%=J^D&I^h$KQZY!tx
zgfnzdqD1p%Zs&<rC#fwIFJo$3b)HhSBn*KTezM;U7=e6ri9hSnADuMEQc2-Sy<#3Q
zo;;A+de5d*KVBId5*?d48IZWo9tHloX%#{jd?7jiecpD^(%*6<%rjB?$>;TuBgdp1
z;)CEg;t4UlWx-~~Y?4=f$GY6o0$dawy&<iXI=^Vrl=sfAquwed9W%?k at A0x+t)3OW
z{zUh)vi0{G-7Z?=o2tO>zK(e$sv7Ye6!$#HVZb8V%N$eWBju`jbHmh2ON at USm&BHN
z)*!MxrcG~IUYw}kC&+C3bRM6d+x){<om38j&AzhyG0Qya7`hk5DGP1)ySw&B%{<{E
zUw>FOg5ztSn{b5&;I(kK%BXvE4n4 at CN&P<8di;+j8ZY;Lhyl`nCw5xSswQ_v_eu_J
zSN7A`uLZBQyq_7d#5`v`X$5;`ySdkK at sY^VB9mza$0H7HU}E&6^A?2cjmAioA!>qX
zT%Q$T!1<bp*8<%K{ZxYwdK4a5P8&I<e(&T;gea*T8kTe=7G^*XvqG~SC)+_y_kG)5
zXL}vz*k^u0!*&54RcK#Tf2Ans4_^6h)>SPk at Lu=MIA}d}_tX7kIg(Yj)a5?*(^>b!
zrqFCqL$)5X=I*Vl{13|ji(IuC5BVbL3_V19>ETtP<{h-6?Z at hEk>Sji)7_-P>DBe*
zsM&#bAIpDr=#2UJh1ud_v{;&i#{3MpgLOx)>j2%cn|p)0>?^j76It#>W^zC{&WFqw
zF-tZXvED!K2Lzt)^$3yJ61QE at qs%ixS&zVMDt{({<zc{ADlnq~oM?gt$1kgJCHz2V
z8eUh9Ev-x$fL_28Gp>7fuUcM)W72KjD(mdy9vqrbj{7RRf=Ow#0 at pDqi;7I(de2pl
z7azOJeA6^P=;E1}8SMu`rH^Re0wW}7-;m2}1ZJYaG*{&wEGDFWp#u4!La{AZqca(u
zBETZ}!**urGBx(2FZ+?KSw4VAUxchXOU<ma2?&!fKAc at _sc@`+kXnFrFfSShvU7)T
zxrp6QPsMOwA7AxhHMiONe9>eTI2hoz^(1Q~aSX-zwNURxk=hrPa$HCInMVv3Ld+nV
zX^dLqy1MO2XqL0p74>!;XtrZ*{@SJV+f!OpR)29UN+e)knu(Z#SxAL~-o0WZ5mWTf
z at 2ojFKnlM^-?Tc at 1u$RlO<*<V_m{24C$iqac+H>UFQ=D_OOXjLU^reM`*O`)JoSV2
zD>{nxVde6-#`5nKE?okv+aFpK^n&)iGiQ$j^&bvbZz8URf^75^?te*~!Sq{-)n`~Q
zQ6Kdm4myq<c0YA&mtC)cFCiagx2^T-5ETmdE)R?7(D?_>vsXb&>H)U1x at FG0742e0
zcMDcAEB_7&2UoW~_!|pFW;38r18pX at 7VPYRCyC7F+<qf3KR;jb)y_<b{@orF|B1)w
zgr8X<=f;pct`H;XcafR{2}dGL_E{4=-n|KI6Dhn{<<8fRwk%OkK1T(q>9FlF%3J5i
znn?sLR7$)1KLZ!`$45{Qxoj+ai;rpBAc{v1nP^;pscE27OwGvss$V@@>L*mcY2NM~
zU&+EkcVVvpPl%0H0Xz38K(#UxKV89zRqlpVD#UXcg_ELG7X5dG5jlxKped-4wy(Ah
zuW?nK`w^5vURd^Tc8(Rze&Co0Y`B#WtIQ4sbDs9$xI4^z<L0hqf8ktq0=E_7rV+lv
z&mQr=_mF0G6(C|B9wCo~@bIc>7cLa?F)Vo1+xMf5eT+aWAL=9SP5$-QM**%@^HhdJ
z8fr3gSa5gR9>W$HZrM|v1B1v&r|vhRD6a4(xwOj<0QLr2fz!0>yOi?p at ZUpl8Awc7
ziy=DcCCoWhhI_z<AtPn1AzOc0;bAOdh<o5rJ(1w%v^L58sH7armlDV>Mr%NMd$X~z
zQN?h&#pgDQ?EQKlk6ujpw9CV^MO#2)*@BgE#}(zx*?FL at rq`MG!+Np2cTEx8RCh-4
zZun!%N4yr#fJ at 5$vohM2YwEjPMEPzR?7BW)vjokWmc(&;%C>2P%~o_hfgqcIuZXYs
zz-eq;nX#aLdBHR(wh{LcQ{2z*GjX3a!gfDoDrY)nis1x6>8etBUZt6fAr2r2CKj~k
zzcT0|T#Gn*8rTwGvjZRxl5BVTny7 at Qa~#!XG9gAqG>r=?&pXtOzqR+HTf||!r0$@-
zCmWZfc60hcVAOvy%!NJixKwhul`Zjg%}I;{d+n)Td|ce4;tH*w{C~eJdjxj>11pw#
zTEP@{V?sIF`?0jlZqR3pNE?XRWD$p<dX07oBZy~=fY$-K{Q at hkiap3hg!A#G-gX%U
zh&zZ1wqPZ-_oD^Z#uJw^yV}y?1IInc^BI7GM{D*MAU-U%kM13hMPP@^yvgHGh%$o6
zw1(~luY3BDHK$;AgNAJbUc8vL{s*Izk at J^%o`Wy9V>_X#W6fEAO-)USzldx2;7RvA
z at C=H1O_~xg+GlVAn^b`shCBTJmHq7!53}Oo)p=AM2&Uv^E>q%TcZqMobJa^dE)pxW
z&*{b)S>tBa8~nu(<sK$pPeyRw=!>f at JBlL(izTGIrCSGG8w1s^x}BFO_YXUA(O}>7
z{tEtgGr_q!M5#mb(k!^9Y^ytGl+>oK;SY<n(o%D)@r-kO(H}2Uq1lhn9V<YYA!58l
z{c=5K*XAGe at qAve=fe{=Z?beUyUnYz$}f+<;I!_`a6N`-8M^jw6Lr<A+6vbpFTju7
z_1^y#y&W3LPoewHw@!HTSULDoURqw at hM*g at oGi>AFSht2GUb{I^aCboDRcV5(Q9m*
zhZKP8cM{`Gv=$c=V5KJM-zPJvzEvJWTxS1<AGF{s-|f#j!EYzj74#-MG7lJ27LC-J
zdV1t%#@!J)PyXl6?`*ilBMCVvVZn0lslkcBamL4l_vPX4&G;xm>*5)R?4v;<La8uM
zBLg%KIvzK5HQUvWFfCFu2#q%nM3-TU(J5>0Hh%_3gPS(Gx*K at Ymtf0;rnso&2vqQF
z51>S7o;q#S*|SKmzxT5%v^>4vA~U~43gy-0nNca*kTqJ93;*&xR*GH|DPfWIIeZ&8
z3ZI(h4biXU0p~Ah{3EG0GQ7pq at d(AzRCeHZ!JRzAg8nTS>J;8lyts0CX0;X at irtCe
z?Tf2-tB+_KEVy{DcNM%<_pK<MwlA8YJbfmuo$<Wjvd2SL;eoJXx8m-1eVi95+)<*e
z;^D7FK)><QbwyB9$-`FvYFWqad3pP~tEs{ztYX)_q}XV5cj=*N^Ex&MQBw0qv(0$;
z`o80w at GN~*x+3RhKl(aP-&FU4Z=d?0_}MSn{{cR==`vJpd7XBx9guS9izQMVdb55N
z2vkNM+$Gq;0D<!KM4B&7_+V+_{R+%d>B4<}u1-sN<s?9w^*7Hgagl~tz&3S#9T33v
zQdngX)Jo`^c?`WvCmd=Tq1R$xj3lGwi<-;ap#yAhJ7<?h7X&&R#(3OrVs!{GsktJY
zz{_t^6XuA^wil!TBU(8TMEps~)yq`+VqPYKsbS#=RgaDQze3=zz<6eO#QSer3oe##
z%)Im1VUiO1%T*!_KelV7%r#l*mF-Kf9F?T8&0E`bpI_$98oqMK?81=WB79G=>Qc>+
zUV)wA@#6Wys0kiTbj0IqqR%=~37s`n7QR_Tx3bgk)?0!x4CzBxd#$|cpo3#IxtklB
zQ|do>a7;<>v(1;v40sry4nf#kC_yni0^Wr5WR8B6wTsarU!b>!ld-G25zb$8C{199
zAL1g~Wdk<duS?qKr28-}$O&Kv2b`O)vnUfYX;DgxMAHPtCC~J<2eE&$NPEzy17U-|
zqZ}%tv5{-7`gX`0k!{wN>!OFf;`R$r#r0T!NpI=>bkNb at b^Jpe>0JEnU`|EORa5HO
zr~6wcW^FIeEBg<7`b*bNt7m_%FXUHdyaM%BZ#zuqNCN|n70x9TKCWI<nwqY7oUOMN
z!y~Gbc%*dnVW4Kd_zr>U at _#iyL&cnq4gNVnkK}gdKqqNPei9ja&`cl#fW at U`mzQ9Q
z$>(iopHmZlIpD7 at m@kSJFh)4(E*3V-m&w=&>1(I+V?M8mRnw^}#`+LmQi75-3k6I^
z=?~{CB8t&Y-U5Ma at so;?nkpk^koanjdhY1huUZE2IKs8KJ0gMnO^XQe)6^>`lsVlj
zvT^BU$ulQSesvSguVWWC)pYOQ%n;R?A*%>)Sr{!Xl4^BY+&MP6Mox#0qvd=Z71qP2
zFUIESU%MO at 6u%X7ze)H66b;H?sFHMCv}Jk4%kRdCjLI#{5&&>(>z)~H^53F6h0L}Q
zFu6SI6n%|L%8p)9aLVM?s?}B>LDGzvVGK-Tiw|!Tnd=(FufnG4;gA2_PDZSWX&((K
z`yOxfQlbwd2Y#A(;tN#pVz at VKCNst$J at hp!f}(T)sX2XAG~Mrwi^-0oPc;SVGvjlu
zST@>fr<ZZTK{^{Ich3Wd#cIgXC6M!tQ|J!n@#F|c5zJxV_hnTHA;#AL3m^=9vucwS
z6KnlUVDQQ;5xq|}ZGK71rA;q%)y8eZGQ40J9_Wv$X0!U}_tWc%ihz>9zY2F&0f%$U
zvxfS0^Im7iAKlG at HsbxA?kZNnZ};G;0;K1=<998r6$-cGEYs**gtlM#*S}V860hUB
z{l-RC{NMlD&Gs^AE_N0zf_++bt(GW4u_vaF7wY2uDh{|e)<3=arbWu_=_^^*{U>!c
z{C{S<JIF at nDKB|#6VOs8s-y#F(}VhLyQqcS`a7Ij5AM?aL3F-XKiSTpm1r<Nd)+ww
zo;d<nQGeG|${Q5oJ|Ig)L0{6=l>2h7t5U2d!7<XVJgjX%1L at rr?}J2_Uarm-A#0XT
zfS4RmF|<O=>n at VAch)Rq!{F;OjeGQL1z4j^VGg(du(MScBfxAd0_driU#&5)yZj<0
z{xWx7S$He8rF;*~wdPsG8IH#Jz~V?+SvMHn9huw>Dxb2$E`^NLx|aD)$IAY0JEx4w
zmqoq|9i3+=`}H at yis#Wna%{kU@<zlaO&Y7(aQ~B7&*I{7BEuJByJeu!;DVm)rJn->
zhIZYAlO}klCbE%w=c4|f#~U`_Rly!AM3|!DBMfH?DK;E$%Lbj3G~;CfDf63m?X27-
zPoP)w-T6drmZk603H|xA#2cJV4 at 7PUQD-`SJ__nzu2fg>OaE?Q|77?(VodQwpN+`R
zy>P6U*?H@`M_maP8i9B8iS6CBA49k4Nd)j3mebVTMj3#(8Ej}Ladh8^RX>`4+WL%{
zsZ}B;9pR;465p<ScpDY3qq$w~DSJN()}8a-lfLRyyc<-woH;ABIqgRcfOUmj4(;m}
zbQ(<OR<CZ$?`Kvoj<3h%8})ykH3#k<J}3pOMwb`Er{{ufE6%^`)<GV#8=GdLM+x(=
z{>WHm<(CkmtuxRM=svvKT at 2VZ)79KX+30!?n+ELWKuYdW5`neFaD4%NPe==We#3vK
z4HafA1$(Y0A)a#oyr0;PWrsG)qniqX<CG##QH&k|TtD<!7K~T^J%Krcp}jH9<s~&W
zHHzyC5mp<l{jZ*RS<UDxkDH7*PCn-E*q at KTXd>G?M7B|dj<RC0B+H9(**x?5eHm$4
zG^u=^F47TM^_&*lS}=)jgR>u_KJw_sbjPz{cmiOlu#_|}HgUVN--t1~jfMc=HvwqP
zt at Ct3t?)~>*If8^SH at B6oBPBT)40{Ap)!efMRzA=A4D^8niCv8hvN$R6XRf%wwqsd
zO?TJdv`ReY-KO_Q2X11D7Y**dM=^Y}k2D4^Q$<g}VpYO1YvvwP<LP7Yhk(5OHo0PR
z3XC>2KM!V@;PF7b^q=28>+hQoYp^N1M2}^lO-gQ<P~=gxhE=B$($`2-p}B=XK?Add
zsw(y`B?8DO*F=odrO^<PPf!xN875??$ajG{TF{xi`3S41&L|L6-QExN!+u!gi1ZE9
z7Qu*?l}uEel3mYW0>ltUC2T*@mFKB_y5MT~JY3TzpvM1@=fTTZs617-&R?_O^#10f
ziBR!g%IF-)_oeHaptIAn?vir(0Qs`8#aZo#)#&S6FJruiY2!1wjz8bdy@!qJjh?lb
zw%vdYO&b{ektfckCA~IBrtq_JGZVpL`=_ at e|GhA_qUpN6Cp68u_rZRr?b*?rgaVWo
z5ON?PfJf|QpXj~dz!PvMu8i_9zN7%TV~zWmNRINkZ~nY3N!6(ApL0p{WZuT{XJe+r
zGT1?2|Cz_L>aU-IjUO+n?&t}-_`n3Hl2|o`okiux5xuWZRn#^l^I at F8D{G|gXZrN`
z7=DT4$fj*<LfmH?Mnr?XBiqv_r7;;y78_>K#J^iz!3iwVDKj>Xk=l+?N=ep>p~>MN
z>X%M`zC4BA)mb%V=}4Vt)HOdwTKMGoRx^H8-h)Ni<0rDqXPcPc8Tdf6=`;G2y^v~e
zU+KbgC(>p{_%ALlZhB(QsYvH#$$@u9a5m9KfZS^#DjLyLnD{sPG7c|visp~jmapbY
zbd(&%CFnM$Edss_tGeFk2#_{9BO}d&*d*4C!q(Q1kY at obYa{s9$xUK7OClE}>(Gau
z{ds9}LrA`VV at TIBa#8aZo!{tO$Pv|~>ye-NqHrpw#Gi|y&sye+N6{vKV0COg<ug|)
zIcs|i!V=v<NLzGt*2{%6es|FP{cQB3yMe-eM at K2^T at b2xRu|SlvU_nG&02JLlhUv|
zcUb07We_x(b7%Ij^dHBcI&RusI8vpl>_RJZ00YhFaq0o!nxuzFCTxcB_WLf<Kv#?h
zEtStweTF}t^sO;ri2ym3`_bt#KBR#lB*eAiNA<}9PUf;gB-Q-^hx?<_9xobGNpyIG
znkvt3m(7lW_upRLtNkWAJ43sb at wOAk*qF7`os6Tqg+#?NLENC2KJ}g`_F(yLG&LU7
z=bp|9G{|}qdB^ljk6R+Eip_aUNw6y0x^3OLV8d96h505OZ25c at JvsM?)^bcr{Y at Sg
z=W99{cv#DoML`D@{+pdU*jSAE!dM)>8pPb}sYcvL2IZSq$o^1QKbMB3vo8OnX4CYB
z*Z5HsT!4}|O!5;P4B%(j4?Y$hpvm#tg&+H`DKT<Ef<v<(&O*K?!4*&7=#~ps$5uzM
z|0CFfVZ+ig{YY5F)_taxQJ^rfSkr|^yyt8-H8Eeda2M<dg&nK{y>NE{5Y|oFo%l(z
z$qFG1N3>S1uCCZ1jjgTw9fS*S8th^G+xEoN<ofJW)bmzSyt?wTWq at CyahP~k`~DSn
zNyvJUWI@=U+a+Uxg^vdgby?F5cPP?1 at 4%ZS-5NuL@}!q8+zGKFU|%)wuNwHT7sIE`
zFm<LXVTgwXW8)w$It*}b$>$<P?%Ksqu-C)KdOh*!+P$y$_2;6pP&kAOH9*EGxw63|
zwmKzCf`58 at o`UU{Aq`fDiRC*?!ST}XlqJjg0R2M`*q$Hh@;MQ2T*H9pSj01L at G1N|
zxG}{?ZVRsbS03c$SIwS55r%;as?I*|=6M=(N&25mz7X`vfJfxUhk5p=kRU^-noB~?
z9_2jD8oQib*i<X13!nCJ7;6oT^1YG#ZsAVVa1a8U5Z$mj{bY0>O#=qcP1!?62)*yo
z)gG*0v=zq`U|kzZc_5?gkH5%2)3-|DdSWU7v8EjR&^}?H02^YShOlFISd#4*{Cw1}
zWCP=5!`%QXp!K_U3FTnf$@CZ<Jl~G^PpXzt<}Os+kDCQFU-f=-aW~*cS8SaLT+$zw
zJNRh+U at IFp&D7WX at r`#uGe!tW at TKL^1}||u&WsYSdVK at 0+U_d4i>g(09FZ&~vs$g5
z^ur)~Lg_Jz4C44<W+dU&4doM$*qa)0&Zq?9JR=pw3S%CnE9upT<Q>z}*(Kj&Fn)pS
zhTQ)uvyy<TO!gn4I|nFVULCO30<<#_WQW};wY7!-$yOMT4w2cn>RmdnX|Krq!i#su
z-=QPR<!W6j=}q=7(GMvWj-OG&>w!km9ZLZnNbqiMy%?Qk&cXY0%E?=a*suCpm(Y!)
zPdKi|>5 at K}6mVMgL{YED6jv6P<iw8Ke(sHly&6Xsy?ZYlr*bCO$JIvc7n~Wv++35c
z{EhE=gakwVR>))+MuB$rfk2wBsGP=S4B_7sQXzJj0%r0+ry38Q1oc-Tc&polB)(IK
z`^!roVRoh?qlKTcl)UR!E+mVY1Hn(k36^BZX~NbG45hrSS$^sjr;uls>y?DCMumBn
zXfGJfGBG&}Y+Dtc4ZXDEx7c7ZW at e<RW`2)IwtZsP$4gP#qU)IDK|$W~Yl;8M98BT2
z3a?un4WT)wIXj~-5+{AoPV61ruI at K60=ylVzF(%&|FZOU$x1w&OqP^3TJ- at k!l+;D
zlcf?C%SI}JZ0*I`NAzG?`U{;x=l<EW>R&18PZ#NAnhm+EsaT<{)fFZiYp4WV=Ko~S
z)_XTor~&$}cz^q>BNKpiq{6h{ASvpfv%db!;x?10Vx|Oba+2AHy3r;IJTjk|{W9rf
z$V7+bl*hyK8l{%*h0))8oEQcPCqakjpbc+4OSb%wea=nG{OI&J1^n47e at g}B{>b<#
z<^KE6P=~7(;tJ7*<$5;3YO(r}Cv4Gr@^w$cU at Ey6w?VYN#<R at n=9Dt^RG##3^s7OU
z|IMpj^#0Mq!@~>ss<P~qhjm&rnix{P at d%H}@`iRHG8?ifSdbh;e3K)YDB?dNT8*O{
z^~wGFHlyfV*Ec8qpQDsrV%-$J1FR<yf!0jphFdREU+LDu)YrSEr&oIVt`ytma>Q9o
zKiHX_Vv3%xL)gabM=7iLDzDTXKRbp(UET$-(GPOXSYmKvRVUDcZgMNtGl1B&@x7zm
zecp!W<bjFIsMs)-vWVYbAl=^dLBsBWS{<u|3)1^&<r8}yT}JWOc80oRWhSUI$|vS>
zFO)?HoMWzG_Ygk!oR?yoUv?7jyAhBhZlA>)*xUo22>;tNF34WUx(XNbqN(t3xyp>3
z2Y+l1v+~;*4IfDm?-6(mtGoY0ddcoPXlhLeU6}g>!aEd_1Fu(9gII4cV(oq*t2cal
z{HcZFe*enf>|fUQO$a_Y&st5tq*KGvzbM8RF>8sgdPsVgDvaCt>^;2 at wY(2X`XL>4
z`b?XLD!4oT!xK~X-da}tHY)6?23ObD&8#xt3d$<IAP}jiR5 at 8$#L^B()`g$}fByc#
z7yV2fQi58_8fH8TCx_VWW8Mo~Xq~#r_*}>%4^Z}8BfXML|8;iD6^6n<rL3{L4(>=y
za9YF=v2R`#8A0EHaK;eT7!f_jFy4tvH0I@<06rP%bZc at +Nr~ddR%zBybBRdGz^Rqj
z%`eiCZ}uxL{2!e~b&d(@%XVxaT{QiD at Z6;_E>=AcPQx{+dBO-yx@>$?JZ~!vXnsag
zrR?zCWOG5Nvc&KV6Dn)mCR6<dz28w$JCT5UZ-`Yte8j8efReh8<(BVZbV8V>cq<W+
zfmmAFTg{Od)A~jy(+GqzeJ??m7rV3_l<Y=@G0&K3y?4_j`1ixlnm&WraXVHSFKq>+
z{#!O1(GOu?$xQHRZ}1adJU4Ltq*RC-^mKQM`N9k?TJLK0cK7v_HQu)#e59Uh-_qd-
z4dIJJX5}=#sGiCI+e>HoYqXroQaWzZjUpn>|DpNnQ`+D;1)%5mX?aD(jlq<Xb`LoT
zk_V=KSnyLy+fl7ks}fb^Hi@{<a$MXXeP_iDa7>SCo=@YTh{~uO2)k0GAr)p{L63 at b
zEJ<4sb_c-EEMLmLxm5K3ly~Oek*EtjNcS5%b$iwSvaH^N-Hg*2*~Fj;tCX at O7*j3%
z`$}S1J)?~sKB&R#-n2Od{!{>7{I;q8|15wLf6no}bF9(xn7B{Oi^L+}n+bWbl(k{Z
zf=$az>w3MbK+uf9wy`#V_YmM&tN$4$I?P!pjSYLgMZlgZmFC?rcrZqzFhICq<&TA&
zPS`dye3j)4TYraoX|3l>^mH?kqNjGBSiSaywo--?+4hGXZ0k(32 at FiIZukR$z|LCp
zN`7xU_gjtg0jAL at IbGcQ_0<-B>TK5eZf>0~OS5V9p1*OyE(vY?JkT6KlG1;N4$h7L
ze-w4jtA#$7x0TkN##PI3W at h4QxkT#I2(}wh!fqC_la3zac5p&iIW8FEn2{*~JVxH=
zu9eQ?z at nB^e<!`o_JcC#*yIoOc6kJ$Z(N1R&Y6_;Wy2%@>1MzoDL}Q8BK1gE0sqn`
zTEXeQ?n;>;O9DMdw>2i{tw7DETuLhna>h{^X8`|r6;BoE>Y)Kb)%7&Kx@(Q at XM_pt
zYBbNn`N)weNJ{>Aei1m~LGAsMU&s74_URZi?FK7Pqn1(WXCz1GNc4&@Z8tpA^y<~5
zWlc69>~N?)%#FLDWVqFtL?dZNV~0bmp<B9w5t#m&YeBF6MDMjii)#IX<8 at pV9~M7F
z$Jm82C`;wX7Iyc`<YMb|m6IE$w=IZ)n!Jp|dNFt{-#e07G;|6RFCF9RA^M&*kf2l0
zW9A@=Y)khimE}$5YxG_ at R2jk1gohw4!C$SECw|k46n;n!)BIco+OK|s>K>h8U{so%
zMM at cjtt9l)EKjYxQO6NCu>`<peBC8pivJVn&-%P<@H0%Jv??U9-jC7bTKu6-{ra5S
zx<OJ{@Y4FlP`XnUXGhNI{11G%8PBIVXo_GXJys9I`gh3HIL<HbQklT7d*%u?f0c(-
z(8dZncbz?@O2R($rY-?1+-po at m=BKUP=%S()gz(xmbtXsO at wsj$n|j at G>#nJgt?}b
z#vY9_!eB)MAx_n4gBJ_!p;hZH#^>bc>oxss?!P9)kg+m?=mgsbG8rR-s5w}WlPcf?
zuj4mq^t6Dg9QN2}atB-&=(u(<iQ4v0Gl;hP^)Z_omi8|PiVb?q2^6L7oA>X=+DlhD
zu{E9nyr1CfUEL9Vli{^;ZT+_pgBtK*GUgl4BSiKHvT|+FVbr(ydHR{C+2sfwpKbOa
zdQbq{8;N%lhJH%F`0obV5(cb$!&V*QnfX#0Gd5EElGwVWMD=9#`^LY=wXSmYJF?n1
z%n10Q%94Xmueg1x30m@%dqcPJ{*KrSj}QXvc;>hUQvO<1Sw9(a#pQW7(!1YN6(v%i
zed=6PqeT&iQHoARn?sjZo12?Ak0;a`S^uf35`TA_Ujdc7yO}HACO5D*h86$)oX@#o
zj!q*Ft^SR1b85=u$$^HmEq@;$yX8#J%X7%^X0Ai~^0V!1Td0>PoPdnM;=Nj8fAuP}
z<^5 at CX|a92Y$ehgyT`o~*zCy4%>0WhueKQ{#jlwaNf{c at AK31lAMw;C!&Qr;dv%E?
zexA2&!|}r0w)u`coe=%!0T<DiQEv6?)<1`%D2YZJ?CISi2&)9aEsE<96o*J;20xVy
zpnB>fI^)x*U)2gs(l0bdUyYgYB}T8`=6wD$LY}>5;q4%Wtsd01GnM2UzY1kN8r{SA
zikr<CQ6r%|+{ti#gE0FY^1Zt#031X9oPX><oua_;0a9HZ<?2$tT%%rq7k8z)45xn6
zDmh@%HYrIU-v8(f&s+VyZZ|Bw*LF+bjTl=0SbN7$<#&`umcv1KTffg;(B3}ih3vGN
z!@TqNR!1u^Q at yPgFsqO>zvKkfzDKh5(!a0>D#h!z3K6}TT7_X%4qdxHxE63m9bgg8
zN%`stD?Q-RnA?Yc>XYw>ia{%Bw%jmjHbLPcc<_ucJ?!Aa#HX*YP1YO8H`a_zPTDq#
z45S!K91%!7Q~?J%h+X9;cVXkxL at vfg>hHq#{^@)ZU1o%t`Hf!0s8R_rz*t^<Pzc-#
z6r%E}284*?rK!Zxu?bL6$XoYHAaT1I-_iGw-i}{5>p-c2cP5Q<;i<;DGc4gqXiFvB
ztszkdsddZ at m^P`H3lI?xV%-b99J&4ah2Pt8J`{BtP>;+70?7$FXoq1m9@&@ZT(mN=
zY%Z}eq5}y_JL^TAWj3;};gde#?|B8uEgC5`{?!mR0sb63aoyok5V8JG%py&8xwRMm
zJF;bSdm#qF1 at s@VgxJ+)eY|NLFJ_my4jdg=@HaEzCc{TbnlXCSv9x77k6yw`nfHa&
zSM2K;TD9~J>Yr2eoKNHde<j(}0;@|DWf^%ym*L3*8u<B1eHRey20T()ykL=vlrk>G
z`T^{ySx3O$>S0Q28-dxUis#}nnmNzAO~eKhxrUh1rwu`4V)BlmYBVR(Swmakce;q&
zjsIxU&9nQ1KG}UY(;2HN;xStadS!nmbXN@^H6$(yu{ny#-Oip}Rm_J8&pRw%W}NBT
z63eXV4wZ?+<QF&)TfuG6dtn#p$sh#haj>(?>57{%!SQa08diGSx*ADGCIopYqrO>F
zHqv_oV|DtqtMZM`Otlhq*<-0n&uVCywrX#{DiR!E2zDeA@~(7Va6ut}sg`PSckj#Q
zjuQv(sU{(9x<5Q)EOzAG(6;hdP!$jQDKAaX7G#=QO)az7lMJz at +hj`@c{%;Q#;amH
zcf at EjMc=FPkZlArzhtgFriE~0B%%D%6DZ<mbt*yfO^>1xmQeDuec{J;OGmtoL^$ba
zLOBc|3hY)^^vwuPt6CQ$uHeW$VEwE!*x2C#8jX1UikrBgbO%|wpoFh;XBt(F^U+Jg
zAA>6}#ji%k5^SY5by>z0W#S>=qtMk}BC at hpR--kX6S0{h8?+fmnI*jm92I&EGMYB>
zzf9XqLcjZ_xI|l1{j~Sph5}oz73-j&bcWNF-z>P&UUhrTi>P9=Hh;qk8o0<J{eS&+
zE)q6!Wqy8TgXThypbo9_An|QF%&+Xzoxupj!Ez<v!6v#tU#Vy#7IhAPUx2e)azR+_
z at 7QrNGc}<r`ZK{iO8%R4Up=9V^JMtq7jY`WsvnK{$v7{W#KI%X!+|oid}Y2itnxwG
z5hVCX2m)6Qg*YZXhIK66+TH9Y+Fmx0T`<&d)3MoM$GIdiKF`v^LvZ&&zt%VH^#lfX
z^!M3!qI{2}Rh_-9BH>N68 at pf50OBidH8M^#WDX0jBmqE at ZaJP54N9XOZdsYx%mcn_
zEqEA!Pt#x_8q>RkCQ4R*-k{^m7tzqz7z5jHc0Rf<e#P>b6es2>_V)g0ACyS)=&81i
zKC;MG*zi~BFFI}gKGWD^C3nVobYwVOhzIh=+(;MuK9PC(%4PP4b}v9uUXNF7E>uM@
zf+{BLn~dd*D1}L}NV$rL(A2SHRWG_<pJxPT at j^QIm0S$5le7G4nUPW9GHZgWAZ-2Q
zlvs)_>MNtQ@;f9mccp*(s0yrS2eM_aZK;AtaVFO|Ac?&d9Y05VC6#}w2~H$Dq`X_4
zboJ}@-gX)ixpw?#;F}%7Rcu6y!Uh8mnhA*iU~Y%DEpC5_etASryxG>=ygSZ6CPJGx
z^$OZHuL#dOg^+N^&ziZXEP79DU!wJBTCmix38H?aqlE&=K}X$1Kiq`ZI%wufKf%DO
z&G9>U8kjmY-2)Y*tM_3E^g{BHD;Szin at 0aNa=W$Mk;PS!FQjG^^@?M5;#A`3si~3+
zFDRlnmLLlrGoG5C at I@hRzcMj~27C}4VHVvARdN~QTgou7T&~I+y!KB42GVwo9(#&(
zvPc&h>|I7Zc%eho>7p?~eNh_Go0gkhnT{l=@v*V&r^1F)l3REJi6H*mEx2i!us^T0
z*9Rd+CEC|aYflf3P+sZi-Vp^`<}(k2i<fKm8ubNj<aDfiehO&Ok)MjPT&;&GrUeMR
z6;My1q(?(pcqoLEmrE%0;2m`(XZ4ftgDT){aSM)f7P_saM$r2{sar`u?7>FOa?aD!
z*H=1NjbgvW>411;h6Np`^?y9QWmJ^!_dTqLgn&p2NC*-VLx;4|jWo;v(%s!C-AKyN
zA<Ya8GL&>k=MY1e4BgE$e!jo|v(~(rm$T-+uXCNV_da`1H>szffcz9!JD0qLzz7><
zmQ^oFrcW2EJAp~R(?6!)z1xD{TYP{FY&=loHzsu~$NdkF`vSdvdD+64WIf&Wu<uWk
zT_Mchpewij@$giOucXBl1GLv4Bup;^sHR7g)LDvrI#h`cbiDc{EGO^PNE4ZWnfY9s
zs*80*U- at +w5zG;u6%Ee(cE at kRqH_*u8_<*6T%ryQ^A&9SwwE(Q>D}u(*D3}e#?7fY
zNhM$oi&J|Wn6*o8DKen!QqGn$<Z2oxsKzCN2sL-L@)FN6e{gpxms{HjYr=9+2z!G*
z`f2u~s9uAx|5=PK3X(>n3 at d!vTsx at OD{d{`(PE{*bNUh2v|0tmdI${x$%?jW$JEx5
zeWjHM<{y{5<&dAdcvdYGj15xJRO&aOU8l at A`DXYb3|g3jb$M|4CScR3bvoNFHuhS$
zG6{Yv!NmOSF)2*-Vu$M`Hv;5;_`5hec(Wt+q+9-O-_-yciaX<-Rn7a at Z<-{ZNkp#G
zu*b9h>}%{K4!|7H`U<sTt;`Y`aA4NpWop>ZjA7LEzDrQ_Fw^dX_bA^FienF{gXxEh
z%W at bL_BWWb%VJ|F=HJt}y-XjqoK|Min#Mc2Nu3{cMJ1rOI2eZI833ljXhq!klyp6-
zQ0%tr(9^<TYc!eHiJ$-r4_zjL)g{V`V3<>WVuy&y6B$u5pPc?@lCv6eEX~Fc`mtlx
z=x26yv7zaNJ~`Dn!S;O)Z32DbqbLV)eN}>t5aM^<lW3X!KSQcRGf$Q#&*tes-AX7w
z?JN`aCks4vLrV(G3;Wfsc4=;eYd}eKgYE{|yk*B7Jw<|%Ea6dB$rm8g?GM&t;A)9P
zY-Gy;|ErT=!xAu7J#p%lolbAoc{5;hDB<gj828Ht`<*Fu)m%}O-|6Mn1x->G{Zr})
zRxBea1f40JdDVUt`WtM(2PPbc*ok2 at o9!XDYF*r90M-n^z&<}O*xPL}>zkymfB=g*
z^ZkMb&f*7I7Bvyqsoh0Uli+P0C+Mb$U8WJ}YbQ4Jb+AET?fM%1=z|n}mDpm8DF4|I
z&M?Zis(AP#!sU{2w`;`4eQBl1 at 2WcCD1a0;`xAe*ZNdGIewv6}WxN6Szi#c(@Y46h
zpS$b9N{zg$%Ns%U`gIoER<M}zkskNM<*rEa#2Jj_vrAkd7f&c~LGkBF2`Uif`L<cE
zdBopCSW64#@A!y7EcM9;T5r0oezKr$y&u)@j(<G&-m8}E>yvg#>KuN|TQGwgke2SJ
zB;Nhq>;I5uVW?|P^1$o-?YY0Y`w%viHazpuDH%`8_8R|s$TKL5^i_c9uvE1%7bY1z
zbDW!8U_rK*v4(x68OJ*P>-A_DC_P8nndVn<f}#qc##_5Bsjd$SoZ0$Y6iSRq|A`1L
zXQpkYRVm&|Ipj5^yf8+n+ooFZoDG at rcYSAbj!D#LkU`Wt^#soj%->f*C=)1-&=*j)
zmFELymu3w*FOHa^pS>j*T01e at bSD~8iW-dScWK%qqWwvt940CEZD7km(?m}G?S2i?
zMzM1qNJS#<**ijlX&SDFd$8hV=iR=lZ^xVZ-185D;vx+92~KT1Zq^45Xvi?Rsm(T!
zU+s(brW0M_BBNuzij}IWDkfu{hlq;aAB4j!4fFylKgjJ->0tCiZP at Og3~*^y=dx<K
zG}m$yAZdk*ziq<d&XxQ&x;6FG1vRUpn2g+KW-py2A}SU)zb27AiFl=hG4=6L&=)sn
zO`vJamO6rnN at r#`oIeD!J9<>=b}YBw!Y$6&nVu!n*m``0J|2}tgobi<&YraGIb<3?
zzQr3Jg>$Z|@z=TCB^6C=jeTHmh^LmeS^MSZ(EUWa-+j-jzPV1+d2hf{&|_F?2*J(-
zVGj$spcUgzXKK<Sf5YfTO`nn=^I*@u;wn!6YY~b1iAfki98BE7BQXZu22ESCzE6}>
z-x;}YF1(__JcUG|Kdlb-w!HWC^}T=AsH&t;pRjZE5JF}iJ)Fb`s=SDN%9IA+K0v&p
zg)u^7KtkjDlAZ-uo(=fqpyr35g1T2hObaH}WOY%98zn!sNZj=_d;1Lgg#Ie;Q#;+X
zp=i?Z-jm^`Pr_cRe6Lk!Hpbv=(J$f#9I{`tnK{za_lL2q9ZT|s(8tf>{i(fkVeEHk
zP1i|XWM%TF7LLc$`c6D1SJ=KcHHYpgcw+hwkw)SjOk62#W<JrD@)Uh0vqmTRQ!xBP
z*Lxs=uM<j2znG}w@$D72xTQ!AN|XVW%nsi2AzZ$?WbmUD=MBh^wx3X?pDwk_GkWv1
zF9`h>LdR#CLrEH6-%Q9KyK$?(<KEX>ZQQnuUD3B>=xqJvQ@*JKN#v_Xi1dYL)gj#n
zM3EBjVzskhXUm%By!g0;N}Meq<oiPudw05T3MDxc5T(WopJ*M)4x;BGU}Z;N$muuj
zySMx?h4xx2-sGvwknYZkJh!Pj(U<w4Y=SW#Zr^uK$mv(~mSJp$KqJF`>>QKh>u>ZU
z1QQJ at 9N*!t$mzpNv)cF=0a_i`eq7fYU~30(1rlnbRJy9VL~no7f9aj1IQwOt7%^Vm
z%{d4{$@X8m9;UwMH%3{<usqQgG2Y9nnxLrn%M;`sNU)Y?q6jeOfiBV~?exKQOMYi$
zf^O<mj`NJ|2y5glasAlD1R|*#L}~>}yVHsu+9CsEAfN*=5%3QcG@>8(AyyxH|A)*l
z@>{#fX!QR~3%RQ?=%u0*4k#^SI%59*Tx>h>S!P(8wSL;k06Qb09nohBK_h4o?FaT>
zU`od~PjlX(qbSiW7qPw+r+lNGc04}FowT26j%WcRB at F|9$gz8(b)?B_9`ZLJHZu2B
z^eGV?PdpTDJ>-B-y+-ryqmpoyZ!1yhS>k%z)~UC6Wkf=SMff=e*C&ZTB9(T!2U5Lv
z`NZ6B8x#ZTT7L`yR09$q0z<SGEkINz-|4S0#n(Jd>oP)u-!A4ey*h-26<)@Ij5N0f
z+OP<%hh2_8dVeha{PCkg{cpXdY4QqaN{0x}D9Q6g`sBA{oMv80lBU>espTBH;sF9l
z)4RBJS%8l1imbTkXF$yD>^(c;)Q=;xdON>+MH=M2!cCJ1yI&S5ql<`%1<)lM(a|0;
z1qdHD+Ez9bqRa#+>l|7m=Zbs7RIGb at K73$RrG4%RXc?Foa9sc&y4LqV+aY-KqbZMD
z^uu>_FY!Dx%F4F!6NaAYDFvuCED916Heh1#ZQ?NVUp*oFpSJ-~68Q_4uu_dNZtI1j
zgv^c$aJ6Z3t0tlMitBsq!<GZrm)#M at eC+(`NTW$<Pklm?j>EdrckP(KPk$si at 5MgI
z;<}I0HMDNA0kSAf;<MxtD847+b&xl!BY~5!ZgH9{SHi483@=6B7#BNw;3COeL#J=q
z%K`rWq7hG3P-Rs542eWOE$iyI^AoE?1yz0OW2BAOHW)T35%u{c`!04zn>=BSPFUJ$
zO}jVc5+oHwKmJ{s&?w*!O3?f at a05PaXQP<jT)T}<&ij2kb~W4Yktm0}=3PJt>)`=~
z7nj$QZ#zy&|F&FzTV`WEla&ts)ZmlsoR-Q_7musg1gadFp^V}9@#m?YxR!WkJxFVa
z>@(&vpr(yS`Ddv&Y6E=w;{ljHzUP2`go=i7!1c-irZtl$YdA+m^M^!|xNfzGh&-vj
z24ZK<&ZKAe!43tURgdC`#Q&R^-rJK7wz#CcB_biDJrLk30Z1x0KXmS!7=nvU9$r1h
zTCSjkZfN~3b`td7i_O*D^xHFOmm;P_wQ(@kXwtD<MVmr#-<6~5p}z?X|3LwcHr%!P
z?3mA6NV(>=UmQmYwy8)RDO3-&H@$Qc6~y_{<|nvP<U*PjKLECbqI0DZuxc(}i;Zyg
ziM_>)a3pk2w8-ubNQ(lx^U+SE3V3u3RTo4 at HW<lyZz}yny(lz=beYi!1NbKTi|*@p
z9<pH)kl<^SN&p3&(PWk22zk>p&W-1l|Mmjv5z{jF36mx`&35(-h0r&=r=pi3Ez1Y>
zQ1aUUt`b_q26=KaQMETMq$qT&)KuKqJjL^URV0^+)8SXt3MenzPPJsJ<XH0^KmA@|
zv at +<?5Xo(HZdO~j;Hulk+gDolEzZZ}9&08`Z(gzIaFjH?)&V9DiHil*{;sSM?e8A-
zZ4}{wXeD)`a`*^)yOii?4lRTE^kPG;Xvn+Dul(Y(yy>Vxm`KACH-@`~Z(mT>X4e37
zRzP0gEo3V(OkHV<Si%W3m-61Vl1$j~=wsi+7c2e at yq^$6Dt~)FW{lP-nXk^V94DTD
z(Wytu$TaaE!0pk-5+aKmb<%`wJ5NR#^-ga7Q+~{5c!ASYSNq0l7NhNf%A9-9p4C<3
zz=zwIM%rRQHew&__jr#ZR~Xlu#LxOA*bf_HpKO~^n9P^Q at nrKX*P)@!6Du5%Cx$I)
zhbmhIVBC^77tX#pj>bmq%%7SW^q=1XSVG+~+j~Ud+Ic_Xlukq at UL{qdkYv;K?G2+G
zbir2jY@$4;pv-F8<%E-=A;mQ&6AeGo;mJ at _Ni~|sygI(scCH5NI)!RpoDOVeUi$Cw
zMBh(sbEmyaiEc6aW*!MQsC%WQ4V2{&>%gBOc53EQq*)Qn(%e`y<hX0l7%^^#Zk9c>
zYf-adMxRTMT|0Bx(ea6jlJaZ-2f*7l8usJYNdtX^_mu}{y-rkNaciW7wlcR7UCzRw
z+k5 at k)#bTVkG}4Xmh)4{`F^NX4jF4vlcEuo+q^FX+U06*n at x3TB1d<`%we`gg&ESM
z6$5w^K!`2M?{Ti|jWYQktLctloXg=`HKXh|Zp#i+OD!5fk(m8&>hNWmfQ!PWj%>V`
zQp?sFfBgP+UA;(UMT;6T>xep98EAzshX>cxCvAy8*%~tDm0QgSzLjP4Q}$$aJ0-5K
zY$eAFgle6FtFG at yofgnPsBz`pyZ465NW){7o?0e00BDD<bW5<W{5YE5NT{@VGDVUr
zz41}0x~CNHN3bwi$Hex;=~tYQJAeqv4}o}a18gR5Y$_i64hc1S>(ovDz<K%1`{2yC
z#Vp`F>#bOCI|KwRy<MLjxv^ok(q*amT9VNJP<yLZq;@uQJJyxBUCgTYisr!T>+?Eo
z!6W7xi??!-;XGUs;ay10IC;&*W8<2j$2#uU-~uYCzZ5 at diSau=s8eI%cW}3CMUH`u
zYMS;l$GFzt8|W4L?+n=V2=FIXc$t|~VG-dc_ZV|MNu+d4jIsC7N5$)Lw~;LP9o~^L
z5=BZAVgm^FlqZtrD5?1cvuRETqa1ss#fobWRI)%#@?-^s+vus=$&ks7$0HaCqD7ty
z6`k_SW(LbOd$=oc8+uVSkofl2X|oAs)x#tuX=qu{5YWDj_`j3klfahtMQ$v0oAN20
zSHOtE$|^BiwXT!e3uq`S5`FQi at HlJBdo00ub@n)NpTVnA+O-PXDSutUom3d*WNHo>
zw%}R$mbRS`V4bNI*1Mn at LKbQE&t#a_RYh++)mM5v)vPnBE|(n_QoJB7Ym7?K{w&AP
zuy&c&B~dl%sUu4A%!w=Us^_({Gb1;4hN7gCiTvBxMUK<n(?LoqCg+1N!3%R0Uprj+
zjoOK$+npV&uRrO;)&x<J&X=PII^7t+oz0r??NC+GP~ZiUS2gB=c0ln!dl at WGEwgJ-
zaE>?IF~+Hi_1KTPz&g;aR_Uqsh(1ru*qGmk$?9dlx=NB)1hC~cE021YdJ&<bb5e$`
z=DH&&=#qtY at 2IQ3`YrYJNVn$&jq*hfLJ;&_O`(>!rQRHNRp1COZeOA^#x4nu{1t7c
zL-RZ3e0l<|@zIe6^aaN6g-8y-rJZ6@$TtHEuJH+3=h3WQRNIBA>a#}%wD9-mpx5yQ
zhNb!8FQJW+#}<O>ntzJ?dCg&n`}VsE9bkAz#T2&xfB1^Lj!t~GQJ5?$!gx2Gk#T`2
z=01Zbo$j^a`$#*^rR7g15;33c-8mhpZE*s6$cF at b+8n!_)-tsF!fS{7pBFfb at Hb3Y
zkq})!Zk2NLXO5#dnzwT}ak**Le1MK>hNpm%7bfT<7DO|#7tR9F%d(3Dy2XFrQQ<G7
zrrB<y!HB53ZZiAnd50Pp4m_OOkEGtGwfSAUynQ_kFOq(ST>+p}_Yu<if?(#|4BB`u
z6+yu2?HGVqii at Kf{xYbNwQk~qaWHI^{nzcL+paYnd at Wg#`MjG+m>aqw?D`JLc*XZ}
z;-Df-l^i(J`RU|ZdnD+0YkT{05^Ol(*z7bnF$G4qI#?epPKvgi@`~<_jS&3e>l+VQ
z>7EdF#*AR^?5 at YYrK|^=>@83K_K{N8vSwSsY0+n<z9L>Y-SDrXFCumJs<~Fa(gsP@
z1SQHw=F`(XD$>(!s!>Z}zrdG65BW&gKsE>OH40`TL+fAg60m@!8kXJId5_(<-MR-N
zbxci}vRP*R<x`81VwWe)0kem&wm+6!w(Lgx#wfpqxM*r224{`*>ZWO>a^<q7av(3L
z(xU*l=Ws-nI_t>sG at FDViTAknbY9c-Z{v?#pC`<C_q*kl2iHV at 1E*kwiB`pq5`U80
z91v$d0B0I~(1ATSQ6dTxyj?yCtZ49Bd9MulDuWqvN8Ric?o5XIa7<Rc`;7ZaWR6GQ
z7du)G1-9&-vT5(~6~{Pi>sz`#ZwxwT4lWnZJdQ7lCm}jN%Q)$06e8Vtu_anuBxLEz
zlOiqJ*ASAn=kPc0lnuH~e>w`Uw#8R2$hWn66AhnNBz}Zf699{Jq9ia!AdzEx5&b*_
z>0kV&+!ta`mXsfR1`@cAdHDnXpB8|f{~KN`&-Et|^*6>}AiO8`@=@+t8A(Y=t?(+_
z+IPI`HgC|~C(jb=`WF`uqww95VgiYEPQVMBoF0 at upNmg^fb)+S7Jj5No(EgdO@;i>
zgXx0o)>a$Nsu&uXINqbnZDKnorZW!UtIHZhsP1==x{lSc>}xME<(21tu<nDgH#qoy
z$GfmcX#i(ctZmBCH2RI!-Y)wfA+6zgJ at fvlkCTfHbE??J#@+yaP_a#{?~|!r)nbDf
zt7!LVDZL<ojOO2NK;AP^m+bSm<y}zB_^MxJeA=kw3qyGFbVIpriX(+g(|Fy%)aaq1
za^r53!$$p_HPH|MBd}mh*N2!NH9W2 at 962J<DwCGIbm}EIg+@%XwXJZIon*O}K*ups
zn@(3bYFRO!9!ds at dqcr)CMG6fY$Jj<&tX|a80)<Pq&&U`S6cGfCqr$9T&@y7W63RK
zWvb~?6mcxhiNJ<T2F>zDkxG_TB3i9GMSQX*G6osdg=Nqavy^@Q0pz39DX}Cx^c8H2
zoEm7M$XODi-qS=J6#L}_3^wyOm2EO`9kzswQ%nbr&w>=`vKW7=Y1PUcax4+myccgq
zugCayDMlQ-?qwm~S$xv6gVCQ?`g~^iJZxz2E?Iry#h~UF&Jx>C3Ss5$W$`i7uVTL~
zhA2&J97dd<ej--?Y3OmK;|@<6ulN5zl=bTk#WS$d*>&5pLz>CcvYPsVbA$S+Vp|7!
zwdlfI#&PIO;iWf at wxyzBeacLzD{K6_OjObwzA`1P02ghzy+!9ikPb5|l-D#o0@`F!
zTs&_uod*5Fm&&}hf^=|M($VS(3aiIfeK*6q3z}SNrq(xaXWD~Gjj-f}ZyQtgqCSe?
zG2H0T5oQ897upbUzL2M{CC>~6d)@uFZWp43w~K3Z5Z6LHbnnywwPUul+UBFB={`O_
zH_1v+)KPiYnhJPXHOr_<kM(&wl}qY)Hp8*4={1f at z;~-`Lav18`E&|s>uShQ^*eK}
z6NKk7;uM(hPCsFeURmNM_Kkpt7-#I;(4N=F#lEVM>eVH31&MNkg1uN!98;`yi{W_^
za8+9AYSF~Bnvew=fWCT}+724xJRusgNfO8`inuNOtV9rriBG-9yz*kZLJmQJ1l!_?
znX4~^E75>KjSl+;KfU}ApbRrX_Q^t53BSRSyYa)8(-FfWkz)_o<bpFe at _V#32C^)D
zF5O*X%LFW+ErdMzs9Bp%rXkFadh2`z^kcom15K1dqp`VI(sbJNGR>m(IEXi|6woU$
zN|mZpa>ZEF9IKn)J%S_QdGu<9T+3ewnP_ZK5z#u%W<_y6r#nw`X_Ld$HQ0=_gMA(~
zO_`sjo^s={ZsIq|myT9OrK3;2)L~_-y&7Y*{?i`S`w4A@^W{3H;fz|IUH0)oVHR_z
zzECl>s83zF%<BqPxJGr&eN$`OV3P=ti0Xdi#&2~sE0{v~&pWlLqL1xH%XBBnU$Vz;
z$Z5bIbaD6Hu at 5MM%A*)nB^QDL_!6NcB3(?7yerwOL|0b77L#Jjq6<=wU7>XniIVcM
z<@tdO`JZCE9)g5-382Cqt+A^$d|_^sbWgi?+8w~?X817v(=KE_?Scpt<@BlR&Yxr;
zbVjv5uYt)!v^alZy)XW<LX43^`LWm1TX^m>{1nXmm2{L5*P=|3+zw?Mbe8KlfDeN+
zJm?BKR$G at a>*USaJ3oKA3&hpE-6wh`l+px at 0FVi@cdjvF)G1FW*Ft5Y<?*S!-#)Jp
zi@;bXyf0cckM<tKx4~cun4wqX)(<&*upimSonZ>_DBoWcc|W{k;*eFJ<_l at 48VC<l
z{Y1*-p=$-MNpHx?T39;$cZGme200YwVeXqSXQIq2y>eC$a>Y)VD)dctk2W433(r&S
znVLi7lg}g9|DM9jb#rAikpe`tmRvg3YeC)~A-ZR5CCbp^AQ2)8#&9_FTfke=gjfNK
zYSbc-i}bnh<f&?2 at Q6J2h6dIreCian{gMv~W<G&qo at zu{<v_=hmcp?~kpd<W{T)9`
zKi7A=649aL?Zl?K8y7K$_q6JnAfneqLxk9mOYY;X0RBW81klz1yH%%JIol4Ya&4ZV
za>GQrocsi{JmdL;7^~Jyt|dr9-KDG9BQz&nxM`gq{Y>=?93{-q?k%RF%D|I2tr at iQ
z3CiMhxYR1Tm%~Z<Y`zUXQ!;HXFTcj$g~mea<l_Sy86CakU4wiW!ro^bGBU8z0dVqk
zFt at WAw?bv~%u?KgPydcNfP^G|fT4o~t7MQVI5it<c86D`=YD52<ESKBirE7p_`sPG
z99ikEQEOVDsx+(3 at CO>&;cmYl7O611+&dM_{!Piwak``p<d6zqOSJa~wj45gJKNpt
zv&>@2{(`~gHERCeBW6)S?pc1uht5Q`5QGrk55OFB8H#bgQK%)7Hl0?03?3c&SG8I)
zO>u6PP;UE`yEdPu{*@e0kD<Y)o?bAPGTBk3#S6XaYM!x!K2(6>K at 5LF8aHh6u;6NC
zZOsJr#~lxxo$j!)G$8HD%Z)fIZNTzyO*fnytvjPWa|)Xx6(FsiginE#OposR^U#+H
znr8}X^=#LsdB8lnn}-o6>!-aVq$ZAwzp8@~d_P!zU~s%H)yy~HnsG=8`be7)HCwk8
z at u-ogYsZ&V2cbJZTSYF(mRhyd<#0BkxIH9a!e6k@)zK=otS*C@=^rEK7jDV at O)qm4
zEO2}AU_OxWPXWL86tG;u2bB$xFM8L3 at UX;Uli#pH6$V at t2|tk-Ypm(vto`P*Dm+da
zF~46pL7UEX?>D~DSK9UUG}NCAKR>$}k_)Tl;o{02&Z-g?7y$mA)Ewv$30{S%iOOlf
zfP at 9E$hB6_!=(dSC9yHKc6Z~(GR%${I~=zL3uU_EJ0rd3^ovn$3R{#s^-(XSj9(rE
zPPd2DU+{kl1mPRr<sQ^u>6)|N;?-x}wxZA{U- at Ey=jscCB>KS>jKi#U*9fcsPEH{u
zC=Bu3d>*%iVg{KtN^-{-uN at sS!kiQ<2GZzH#35iN;R%&uHZR}R?eH6`6=JX56&K|8
zhnh(G>|h15yiNIHmZ!b(tu8p=aKl^aQ_fb=<&J<!-fR<i%o{+-W}-S>jUKpX;{}-<
z((v-KtTK_#9`C{G4Z=9>)!}Kg7E=m=c``oh$u7&s9_2nD at tIjfry`=T$kXJ0OxAI5
zxPd^t at dk=TYUOjB2HyxcRNP)39zFz|42HP!D<p4hvR1RtZ+E|Oh*sRh2I*tivs>`=
z&4+uK8T#(mi{3k)H=yi8J$>dugn^>C&ML`~8H2>nD_E#Bn>^kf192}lDR>85-+k80
z at 3G(%Ul`H0O}6C6KKqn8*1*3?th|v>vb!35Fzi7 at j9J?KWfq#3I7pcE-9fhG5%M^e
ztiwN`fuS*LyfAW~A+)OvyV<9DYa)lVNuy8wj)TlttYB`pQ*6Cm@~npvo4*p`Z^c%s
z(&ANnsn*lLFBtud(OFbOl&C&#dUVuM2CL_P_xzt3 at c0`kYFpo8X~+mOL*jWP^GZEP
zT-tg*df^ZiMR`^7RfFB~@K68)pF>Q8arUZEs+gzN^|Sf-fcsA739djx2G_^-{kuCq
z)d0N?YT9K`rK(ia)4FQoF+XoQB13i?$xY~su%vC9JIg(Iz1{~r4;>MH#I{x!@*dh8
z&|F<mG}9~FE8t?KBzAMRWr&{>DaY)w=wq-0PjwHkYGF1&=ubIU7fiUH2MiA_2i)$r
z(yQ<_gYRrNSQsSx?|9M0!T4=neBP96h;B3mg_`Fx@!C{**nIGY0y@&s%gfvaK2B_&
zCsUS1gUu(y4Ug%sXk}o1w{J(HLOR-jtAmdN?w?bBhPH2hdpE*W13XpBpES`zg1n}9
zCvA*pwbB5d;>$gJ-i!(yEEq-$P0Gx1ana-MT75r9Z4hZ#?)yG_LpHHB2%CP at gmCJ*
z1NYgPZ-r-WSt5eW=_LcIHV2G*D$_6VpRk%kz%$YrR!G=rx<Vjm_5hjGzr7XkZwd)N
z=8m0Anr!818ua)!s~P`7s0e>}gOxP%g(z}48H=5KCvyxbHBN5svRP#{B;rl!ZdMoX
zb-Uk~6BWpIHebyQZzz9D+vYH(gq9&o6l)DLs2-c$RP~%;Ca5^8+fK^?JkDSBEu%!f
zOPAjJot2pxS96nHmM67<p>%W=0=Cs<NGu_Ff&zujU;&95_qfOn2S1C+<s}b)a?N<U
zKWSgl<t0ed-aqxHH*$i$ru`5Mo}r}EO<&O4NcF5#9k$?}j8BBynd|Jphvv1s5;>QH
zxs|DKY?}2nQk2#^m)fQKcQ2!!lHllm6nQo=It at gq7rk2J!9FhYL6=lt^ZMf-V6pG<
zTtNnw9Z3LyXPF6j)3vr6`E?%bRrMbxJe#~sL5B_0W6S`3U6CgHtGsHZ6PvxpwmQ}_
z&E{IZWxcwkHm&t=zU0JiI0i=mAE5<)rMy0Nm082vNXCRj-a|xlWAk>BaQ$@R>zW-#
zt3)RKNj$^;kMd^Wwzh-H2mia#3n^r6IrQXGxOaXyT$Vag1fR9XK4pxNS?^k-y0p<6
zDEa~x!H$jvzVCmUZRqG9s2?)YG;&24J^~&w7VOsQ6~>&Me=W(ai*HlRC!6E=dI<Vk
z%03xu06Q`8XK4ZA{dViJp5K%&Wd72h#N}405-_b54eu2n;9+eP5%r-))$H)j?=ICd
z^96QfH16X2J4zaML at R`Qx$cZ~F3lF-miTOBEg<K_vH}5TXIPoejWaZzJid>_LZ8t)
zmm3Q$im^f>KhG|m!mQKvKJMbZLL)A1=D<FDWHYHXd!$~|8{au?&SMlJYyf^|HhrHk
z>#3UgGv%6v?!<RKq(}*>|C~w5ORF*i9#Uz~rHtJMwBs=Xq^XXA*kw!!pBoH$)E3p5
zN(m{)Cl~I``+T=Ry5V%`(P?l7I6GHQ8asBBU$~&Y&7NB!tT?qA%V)P4;g^jLyH|A<
zH+RgS(unRokMjTlr{M-AH+{@cFF>_g6E|W#Ps%QM8yTzomuvgo9O$Xz>^tpsHMsqS
zwhxp{@M(wtyVQT05=KXJ at vi$KA&nkST{>XBWBAk}@ZjE2lWonzAq}P5hzE~!3lLaG
z;#aNQ`u51j^^6xD_pK?;tjNyh=t70gC|Y8Pw19VmtRVToqm_;Wpv06MosNtE&htmZ
zb;}-f302<4&R-<p7eJl8S<4I~k0KULqkLnX4xUE(DyWj{54o=U+sjKd<l38IxNuJB
z`JC3@`l!OV1ADIUx=0Fi(l1(jv9gFm`4sn);#dSwvNlOazwA};L--c%uzAl at 2;bhB
zsNa=S<Cet;Eme>EJ2yzC=`5Ie$98q+x7hLB8f9^@G!bWYKxeVfXZPz&GWAW&l$}YZ
zQX_+x%0wkKp(q5<B9;JBF{*5l2rJG@`bqyKN9gaQq@}`M{oiSi)OC|+dx<}b8|wF*
z);06BGxH3eJd%ikX^}A@=lt@)mX-DrFYWKsR}`uoxfX!#4(HVb&&sf*<QJ3AJskG5
z1w9ePTZSj#?>*LM^$dSRLFJ-52vE73v7B!uRYuHjKZ`Y*bHB1mn(<ME*?--96wd$Q
zC&*Ve8E;j$e;yr;kVf|9u at o(X4^D`LwC{LEkJf1HpR9SG!8lh5309Te0Ya=oU5YAY
zEz$Ek_f36=>Dn~iIvx+GWqEnI9Q~0s!0Nh({)@CP-kT}KekVn<pz5rbM?l*lR~2uI
zJZq9u%^?8l(pp=*xE{90E}<iUL<cw;#BKotK38Y;46dlP_WhdSS){v&`NA03-(+oI
z&oI^#=Za94%R7$8L$iL)$PJ3J#ny!*(p&s!gI}1X5!Ds>TMWu)|K-szLJ3-y`|OC$
zse^@#*>~+Rxmb46pBCdQQl*f_04fMm&{VkcpT}5)Y11da;)kmm&dpTn{Q?(<02W3p
zj$xH$y4-nRh8soVsd)tk09j`M+`s>N%=seU)_qB$6d~vPjG7dKW|w~Ui=cDDLhpUX
zUmkvTO}_g8kKlXivnv6XOl#s9$41!ki16XwRuNyR%sndcJBLKPWZ4~ctXxGJ(kCQK
zBY_1rao?XF#%g_NHa<NnuV3V0dhkF#`CEI*-!YkiIXQ#^QM$aWiNMxr)=z};jB9P*
zvPh_9tmV8g-0!Jf&tHi at VqRTOygpClfouC~M8uiMg7in_bp?LCOqk$&NFOu=)uFMj
zPad+R)rPIO=-26{-C3=_5oC;F>Ced?yMjXKomtwz^d69t;$r3tl(arus(R3XWrkGs
zJpdryqNb0~FCPTzkHfe=E!9vZpc-CMlWun|VRzCdNxhV}IQBYtUJ{4JV3>0~g7eVe
z_=j8p`R%z9>7$h!@c3hTmm&9LhMjm=up5`c-CUx{>8FDt?Bh}swP?j`*~mEXg5P(D
zpRLc737-aWmmunqoF-P;;s~s|Pyt^JN2i<vDsn<R9d+ at Sh!sjq@>$aHCCvha#l%V`
zu`1~8%EI_^2qzRZac6LPd(uX1VlM?>D!E=Bt#*n2n%P+Cr%5j}XKnyb!Q at FR%5P{1
zMs4CFB~I<o78c*XD-Hadkroa{uuN~2J<Q4DBwCg0^yg1ZpWY*o^MmQm%F at Knh?Bvk
zz{5 at 2{QqHDE at W=z#-ERe at +awUi$Bf at YH`=3;6|`<M${qmR#d5oTGvA2+(+!MH?Co`
zGvs!h96$10QH$Zt=peH|(~tqR0Ms;K_?x0dfx03`hqm#m=c?qYud_BHVdVD+pBjm<
zINu#!<A_&abkE?()yT+ShT?gL$5i~-JL^2t9*+BA6j^L|LL07|ZOaw at JRnw6@$07e
z>w<a=kU-n=hXz}nfH}+D+xcZVoQN-o$LyMATmODhM+bXOVo%lX$mL=d;HZ9kyOeCo
zTyY|KaGApxssiRD25DVOh<^vTmoZlt^VmnbQz$57B?w4Gw#wUNQ&M1SG3ceg_3mml
z9)0nij~`cPYZ1}pYFTM6Q0qa1v5D`CkYWo^E10oep57LZe&vW-AF$K<k}WH*e>rli
zooHEKhzaRdc{jzM==5EJlz}4kcW>UfcnQ6u&_Y>DUY#js|KGoVHS8 at TUFv0Sp#cjm
z9>b!R3`6wQQWDsw*ndvvfjW%tVy=@512*xPA(+`!&4ha^=n(KJlTLWV)_?HHZivjA
zr;&ZVue2xdV7MPbJ9OzYdX&6jq^!sbD_nyb(>v}}wR}3<E!MM(g+{DHj6WE4C%jvN
zrbm_4bx+GrMtYe at qGIop;~I3yPjWw;4kR(DemV at bvQ0qcWLHa8csa6dSj^0k+gIsV
z0VwtJ(C#B)*@+_8!;C@@RzdzA*eHvPhds{)&hdo*<@wuaq6QrS#U1|~lKqdmhLwM+
z&)Y_%tXMkrN>bWQ6Bg-}nfI`jPr(`3UWYnootKB#LrRgY1E-uw(mq|fNolzYM~Tfb
zrK^-N-lmtW?L9)Y5*~hcka|OVgi2)F!wj~)bB2}Mz6;Nu%`dWjAg^j?MyDW)+e)xa
zK7*a|OO+3 at 3%#8e8<^)Xh{5J_d&I>x%NO`VZGIlxr5&p(wir<sVM at RseH{be4436E
z>XR7lo4X6By&~JFk97{+>=`9WNwYHs;ZcA`=&*60`5 at 0iO->C$bjLL*<IUaFcSnTs
z+`$9jV0iqgna6*4```C(`N^#+Rj3rCBDcREos39Jo6ko}+G8bTKW|(Te>ReP3VM}`
zn)X|zBsOQgUk(y9nDR7b5AJx348tL_4O4so(m}2Z%1NZX!Yjw)Xts?g*mqWfK51!z
z^_-}0Jdw4oYIhsABm!lx>=HM at ZO`LbKJj62K5#iFI&n0X-Og|S&>fbN-T^z;qe|bz
z%t=A4vT{*zx?yC0$Y$w#OIcZO^KAz)4b+N^syp-M*beP`SzUa}(9G=JA-F@`2|Mr5
zS9b~<o1u5TnqHcKn!oQ%kr#TA3Q3IOmb*Vy+v95-XhgIG%luf2^$BOT&+pys^x2YV
zekwuD_*n at p5U|NhnCt5bXvX{A$tL at b61C-9dqt)kk=M3?mFQm}vs*BSWQdlQAWXnP
zz4aiN&1^g_I^!qj*8^9`^wx}x64mQG<Ak^SjB|-~iJHhM_qqB@$H^~p5AhjkC&Sv|
zcBQJ`I|r>-qjQlNRYK;?3*8%ah!$^G&)n=Ult01v|B$Oq%Fb?~V(xslw8pngF-$wU
z9Zg4vV^2Kn=>2tK&SG at tYW>?n6r_0x-jKL3Vd`SVPfWZt{W>xLb&sC1uX30*x!I6b
z<V*nH(Y1cwz_izMJVTtsYmy-6m4BY83knL(ed=Pl>Ul<>y$xmw1p2<f-p{H=ylGuS
zX(24{aJOQkErWzZa}|1taY}xRi#nxmzqs;wrIN>ZtvKl8=v;ZQ*i>uT06mvEJj`aD
z(o`qqZHG_KvYw5&GoZVSWH~ps_}ZIZB!cII&1)!V28qT68^iNBYMyV!m+fn6XFe<4
zec?j2XCt at E51;u~hb_Pgz1R7Dw=-TK+UM4)vb*y^P+}6e=if%A#+6$;Z#pBI!n_qM
zMzWlItBCPAhrD)|f6VZ*QPx6Zq)OR_mE6kVrUhFx33H--+M{89y$F&3N7bNgikLUj
zr`xx-!mOIPz&|ME;6a{3g3?36egIyUU1YRqmc$E2Z(E2c*H;vTu*bW#pj$C9ed4K+
z99+OwI57pHBZ4egM=&Qi-QY}D3(E1({Da*8%!92t0?u~EsS`jVfm{;Xjrt=OYil_d
z>;LpCLhGz?q;4da{ij%KlY!ysoF0VgY<UKiAD(rNKu}A*2y(#dPN_nkHUe=UQXk>)
z%~!T$hLmgM4vmWD97)lM11lOnN155#2joE19@(7M`-i{nT7R;l?6Nv~ByAzBP0S5Q
zL*m;~7j0alAl7(E>L{x$sISB!i6UwqrOO!eWhN&P0<5V1{W~TEu_n?#ESEkqiB25a
z>XE2Cj?V{P9v~Lp-HwjN2LjAZJ#Jcls4HyXpJ(tVftk73;wG^7WmzydTR&U88R#jC
z^C8OT)}f-!Gl$LIBJ9!Kqb>TRa?+?1xfMbB9vK_>bCAR<rrC~*m1Kdv`4mqFt{=Lk
zUfc`wwbGXL#meQR`j-mSa`><o+yOHN?gniJvnI0U2e&aTK<$mWw7CPlhZ%)K5bVW|
z2qn3K41H=D#xadH&V)$9mBgSedu^DCii(G=G8}{t3;0Oo;2$=|;XbyneXRtaSa#_>
zKO(;HbaAOE_Tex8MDnttj_TjTF>Z+&P#Op#S#4QCVVhb!<*O%}cpronHPeW}Z)YXb
zV)R2HCYC+*Xfr{7){3DJlROdK=oAfizUn8-j(tT}7TQbF{X<gH>{eC6T6)FqvihpS
zV@%>8tJb=3;#Ic@$AhBpK_`PeVuXCvS`qbQAWH3o#Ve)*uSZ6aa&#bBo>h9{#~!pI
zQEBM|LX!12!u<Ch(OLQKKmiY_J#JEQVpbIB!~dB88W&%OhS#i^EQN#@)@5wAR(F}+
znItS&9x&&SgN(GEuf5(YYo=Muq^^4~9Nv~!*u8gnA=<AIFcuXmlH?Gv-}9IK%WX9@
zBw9lYe-p2ny3(Fe!IfxoO#ZKR(#KeQCd^(lTI#-J3(X?-Ow)FAo6tYsnBfjwEcOVr
zjFDeNKBRT!FTv5~3SU&sp at 2xy`$!-EKRNwIZKFPy2+vD?u7$z$PzPtLviDe~8l;oY
ze%5Ov8*Z(Nq3)~3vx_g9k?wp;8IB9R+OA6K3uN;fuvvR_gJ#>d2G`MKr*OSiRD=7k
z$1UwWzx@{fT*llXcm(t+X`K$!;s#u=1B$4J!}WFrU$>Oi(q+p&0`8cvk}X?Io_vb2
z*lZnT5j%0m-hPgx5M*VnD{NzqmqOy<4D`nJs%B~Qyq;_gU=^!*!+_b#(}p}h&$XUp
zRY8MEyy$fZXgiLrMi9SCzsub!g0oJ^xpE19aEVaXR9cIvL_xR?sp6vhtT8#<xQ<Xo
zG*rO*>~My_Wv->6?`$QxmGs^kyor6+B$Y^MFw~~~xF9xukXdR$mwp*J<n_!xL0P1&
zdt;8eqQ=4e%ftnJbG>dz+;dS4e}z#B=kMm(q7kJ`N|HlMjy<0$Q><^`YZ)n*4rv{~
zcJUBZVqZFa0hU at VTZ>Kd9$lKpHT5V4WTpf^EOIclCIq<D*4}NB9;$86HNdM_IX`h{
zO}y1L<~M>4N7sqH-Wr*;q~jqXsP1ZYD6VYMNUd3hRG7~`-XJRvJFdijwA3PN>Py|~
z!;9&N23f_uPs}h=G^&*!X+xiA-YA~bLN{0iz6i=a`5#{>IKnY9TTYx}!Bw~G{B4Q&
z*-<9T4$)SAi_5F+rApN$-aYM at 64&0ZoN<nk{hFjHm?j^sbv`0-X(jM*JSKU471!Wj
zwW%vC?>4X&?79Dr*Eyf$03<T#2c6YSyl(bL9<eqR<npeVbrENC8n61fQd)fsB$c&h
zSWJG<Yg^$-YtU)v1M)-z)Q(N?&;v7&Wmm<^KQ_F$LgX_iCJ>&L`&+{q&F&=Overm&
zx1eWjfhk($YT<yt82A0dS_U96Ux-_RP#}q%AxN3uF7Mh0|KuMLxhvmM`~uc<dM=<0
ze3e@&#t?2{fzYlgb~EXyn}{;_F)@*Z$?dqa!ICyNUz2o(ILs(BvnUcBat|I-V(@E9
zyY*{+2?|p)SkT<sJ?->D^^}CPp(Inrs5WWv%>|WMKlQ6gVwXXWMqOb!pHd?W@&Bg<
zcoh^E$-~#-;4n{*8hX(GZrMqrGH~$AY&iW7frnkYz{#7}eCZ$}GXbwzW%wquJ>oVv
z8~d4C64G7ZeAdv{e$=lbb_La*9 at 4ZR-#&5rul?HQTmkne(T>o)7DD=oiv3*T=yVE+
z*QrbN92cCP<H7MbF~jlLM3%IWpzE2d(+*{6Fv|4Go_t`eYdg%K7AAFJ3b7LU{bv&w
z$bUV_D3R}6wg;-fH8kHVv_YoEE6s9~%+`G#^XY2J7%cF)8fvP2=ZYedFmoohD^Cq|
zv!k4Qc!s}x3!G(#<dWq|RC3)AOA<m%^E`c6&&hjJhhy=+{T=6NLjHqyjz=~un;ra$
zLMR)cfS at -5vv1R0g!&G|oCFch at 6+?<v6lqZklG5+iUbxwyY{Z?e%a at RZt~pDCz4%+
zmH26GSsgi4ar71S2rJVvl)HB+o1MY`-gh?HJu34+=0_6e7+<R6-H_Ir2_*5?cNT|a
zkFggPHpeqiOztTJe9nN|36DA?XH+Emd+Zj8wO{FNW;Flc8Cd8fZDikCOxf{z@*d-J
zeig$4;!eROxx(?!68bOYn&pGVVV328GYa~ob<yUn=o5B!b`OQ%!Ph<?>pHT<#jb|_
zJ1c(#<Kiz?wX&WQCKYp+9-W|RuV(<Lks)OEU<shpE+vxf6^w(WU=&}ElXix*C2F<^
ze<?&3)oT(o*Ro1Q1<**G16({uyu)5Uq9SqjdK^yTx5(K~e*aX=X??Mm<(+kG(CErk
z*Xqsp0IqvpiRhNimI*ZymLq!jY1b&Bio&Q2vKDf`5D6{U_Ym;6Rht&vhafm{>Jhaj
zif_=>g?80dp5hTDp)hu`B^akzdJDH}Tw)9OtANGbPthKBFjqm$-Q7Q=0;s9sxG==|
zQmNw?<r}R5MrL{QC}6qvmc5#L*A0Yl-nMlF`i*Sdp~L`_XH-ZG)+dw)Dl=OnOX=q!
z%ek6EDO*JE%J6GC&Zcr_WqUENQB0gF`JcEUQt=X_TfHjb+5 at oMPKRmnu#IX)nneLh
zo+2tYmAs!F_SwbEVxf`#$aTO+^&MAXp%!1QDGzA3lRzXh<egk%CVqN*qtu{O|0Szx
zNxC9 at m0o(Y5d3>&Bd}cS{~&ku*aG~#k8}#j=Kx)8-l8XySCZ_K9oCUCw|8u$sS$1}
z<jZL#x-o1RJ25CUq^!J_bzD&U^Bj_qFp5e!`nj|vV};6kSN#lisc$sScs)ugY3CUx
zFsq<?yAbM_ at mYl<`AT{;YBW>W^hxw$KsKe}@WgosvQ|2IC;mh0S~3}XWCoos$%;KA
zJThsWRa|ZdZ1dZlU=v>%D2X(o=*jr_Bcu*md at p6|Bk|{KymqpIVPgt5zF-Z_$Yx%z
zCJKfGo!4AEC^PdOKQIWH%Mu1M>ZxeR1Zskf1$4vDsn6!E?ImjMD-u?_!tp($6(dEc
zr0|@y0 at d3-L!5=#F)}f3EsFeS_9*0jvB+zr{G_kMtj8RVi_ojVuOW%9fusDoTBT&Y
zv?A4`t#_+3NdAbsRI5CU?O7;G4)J?W?<Jo#WXuGMp(YhW_nBM!+9V5xK^sNvs+YZx
zj2W4lRR5gsy`>%k@`<}88DB5wAfQc5tuBp;Ne7M51bL%Np#15}W&Ym2cp94j8%qi)
zB^HD+aehiE%U#TR{W4k#(w8>yznYKMA_c6Zr?>)0i)g*xy{vu;Iv&t;-)F-HYAd;T
zcr;k5(vC_^*Fqadb+8n)v{|=%K4{cgFbW;h?WXbSxZ7<E at W1HQ8qJ~>o at 6>4FOXHe
z-XLdPY7Y$bL`eJzDH7b{w^p1GZ0j-Q<F7a>$p>B9_X;@w*)Q?hPZBo^ve_#!k1CMr
zaY)XgX@`x&{$5)fU;$jS%v9C-WEY6mGfV<qF+%e<HgRV6z%`&LUld`x2TW6*57JQd
z^D#Mtfg$)lC~1Pgg5lyIo4e(-qPfK|V2cpdi8WwCjJ&!mrSr?aZnR+2z7R(S{k=Vh
zTPJ1ohA)jVtCEG)9r8qGgaBx|p@#>EW>sujECNm2_KQ3OpmsO0r3u>uB31&$0d0xy
zFgQb^Nv$t?n>6Ot<cy~C`DO6<l)v(M*Ta(Jq)c5ZLn!$Lv~B05%F{(qFtn=w;ohFz
ztSHX_@;BSl9D7@?iX^GIUfp9OM($3$y+oDTv41 at lN{>~>^$d3_%X4WCCoJ)cHo{e5
z)i&n+vA04`Sq$)Z8QI6}+ at 2wn48g)P at fg6U9W%Ai%>$Pz9Q}S|_}jLH#Ja`y@;o{^
z`ut+S at i5EvB%B3K!tuTqG<N;3c1*Rf!R1-Mo3g6X=ZGeKh at Q!35t0lxxkNC;l1Sbf
z at I-3DV3))>yy8UaB{ivGX)J3L?QUVS*u*ZnXa;u$YrxPk;#EdqvAeOph%`0Z(d$OB
zX!SfBFkZ;aYU<<n#BG#e6S5;1(-)1RSG=sv1CRebi`yuC6axh^YWyzY`i{R#`os9<
zx6%)lYc$b_!EX60^&rRclO;SY`SQ3CJH&iGvesuTrzdnQUh=L2QHJ6>jlD at RG-=55
ztdnRoL;L6*%YpBBhnoo6e)85)Q8mj0WL~>Qj!mV#Hl6R{^0#V8X6~j|)#&qna(3PE
z#+E~62b{&9Wj(FdxKL=57Osq6lc9S$vnZ at d$xNUgr`OYfEswkYcU7ASI?F(z;#kDr
zguPu+vkgP2hiJ$j{g0(GryM+*$L`nkMP`m4R<ycdWGYa4hBg2A(eI`*aGv=pUvDV$
zm6aNfL|ROx(jp7v#qx^-EN4<J<2=t7HzB*P$j7{?T|P2s5im^_R9(qJi^u#&tJmIz
z=7tz~e!;T|#T_Bbm6C7!+~IX<>Q|t%h<g#OXR*jCqM+xHqG-8zS3#EB6p5kUS0v$T
z*&^+*&s5YGha6%5DaIitQ1;YT2Do@#E}yPSQ1SQOB#iljCm}tRed0wO-`pwKy5s6?
zd9WBwT@$>MOUO7eE_sF3)vn__SFe<m$s09r&5H5n)`c?gk3v5hMCv8%guN#<%AX2;
zkN at -S8LD~noi(lR{W at LIG%A2ijPt?yyNO)JZLTGSjQos_pb7Fcqxpf~Jo-8}iaF~;
ze<Z-6K(004$T$5Pj7- at Gv7)Fs|BKO11)c>r67^AXD&8wZ6*~OcSVY-NtN|yJEXbBF
zb}b>pl<^;?B4fp+wNE5zfAiiEOYBu@{Z7;eRsSF1v9Lo4eu?zyAa}*$n2p~<(cYda
zZbhWY<VSzq^Pe^IKgF2r71-a*J|?NE%SqD@#}>6Edq-CBrfTHtlvJPVkjXmGc66-f
zYn^TR_cH5q+sf7kLlom-(87FY&HBKFp=-O}G&+mTdeH)d{Wnqz7a(QM!M)<02T`7N
zm7nYFZu-x>(^F(FUZ-vgLRiWN3mJ_i+BbBVesT(SABQ)rWq2=ZF=XI<UAs6i9pfJV
z0F4gFsWu&}AEVQFBFXhMLAxiQ_JdJkNx#;t16u10unz-N4;l3P6QO1K9!ZM9lfr<K
zu at 0$ano-4)uJ65=>O5(G*X2&oSw4>yLOl1t3U3tE`fd9WMlyDB`DwYr>+GRS5O26n
zA+bSIFg=<ui?j{6){%2(pMbat*xo`(%tgJ9R+z2QT<=#pf?Eeu+FN5$(LEU at 9Uk~L
zI4ag1FC(Z;Xrw^p!{r?<HUNs)rnLR<Q}(-!=;19bEsKh1w at RTei)7;=vwDARsD_ at s
zkFm<|o6g=+bYwJ$M8cIAsPgcA_T0RD_U-8=3yPb5`QKi2SpE;}9i;7Ux}O?sK035^
zSTqFC6`GiA8{Jl$NM~L1kU3V)$o&3VbCn<Hi-KGX=}1NNX~=LK7=^N2dlg;Gpirns
z=-OHv`4{rf9{yRPC?$ja?>L3W=Bpx}U+_vY8J_V-If4hoA^5HUI(#J^vC6hF!ZR-=
zbDXJ%u0sGF#fhD4^*Y%Y$bKamIC)#Y#F_9HsED?yJ&Zmhv3JIyPOk`*xK!XBA&!)j
zGyYRxnGSgqc;0e$JM=6DQ2bpY)R2IQ1Rv%hjOsusebJuOKMpl?exKP*KY)G;sbF6a
zi|N*omBenf^p14X*kehaBN<xYvqJ0n&cB+NjjO9wTw^;<ulzE0U;OoH@)vCh)$2`a
zw`b~E_WK^z{ADV)GbW at tHn!6<rP1|YA5cw#Z)Q4f at y&h`E=mE^TI>|(0CPy3<Z8k+
z_$wpoBlK~;?wrXcDGR#};6&^DseMEHxpjr<RIujn%5rF8CPeudVj`!kuGLr0AkKHR
zeib6h|MX(MaY$~z|GlGbp<->>%jhi&QNjPe0cKM#Jb~-!d?dHYZ`CD>`{_KIezArI
zXE`M}5bpD7f8NU6PRado;@8Y;7EOwGb|mkjQ8~sYQ8V4f<4iKTH51c7Po=mR%a*A0
zR>QqitJuLWy#bwl#h7_V`PQnmcF<MFLtF>w1{{vZ(^3B&WVaKDf^?B8)lZ_~Ku_Wv
ztT)6BI#ulHvQmo9u3S#oHFCu;X~>_o-GK5)nNVOQ0^K`3uMryKxaYDvTvvba(~p=#
z`4)RKYg6^dZ~jJ!XP1fOv@*(RUjBs>C@|?lzc=Nr_BVO2=nmLPu(HXtCBumVVdsmR
zToq{WK{b1?L;o4h|3}k#hqL{?asS()YE at BG6{WVKYVTI5Qls{Wy;o=vYPUw!-h1zz
zSTRDVy>}(H)+R=S7_pvDf6w#$>vFkrIXUM(=Y7B5ubYB}wO*w&*-E0OL95skP>UH(
zTeS^U*tkIwJKXuW<rPa%r3Y^@vo(46o+4-k- at TPI$<EgX;bRvU13tXZ{xNrUsa?M7
zuoJmjZM#+De#>O6M;-g=&hfE3x=IsQ;8^$M7yHaY7}kjlT$Vpe<FOyibDSH_Ox<N@
zvChtZtTMBxeftqeid>ecc;sqgV#53IEZ6$~3iF!}?>)c!zV_-7&*W6Td>61L!|rxD
z`zKj%>wKL1N|6iDpO5a$#Cy`r!Tx*!=I=gke=Iwz5m#bf<ZsA1JToq6LS)fm;6WzO
zSa=CX%~8`gk_xWNR>+8o|HN+rO)lx7PII1yggXhx^=_t4dMi4O%0A&`9-9b?c>R2A
z^IAew#k!)p5AmuiNga!FF}aF@>&<*>TXS4AaD+|y%k|912hiVT|3(~4P*Eq&QmBC#
zEFM#NZZ}Hvr=sWV47<8`CpR$uY1-`#Lv6Ws)~PbvMU1NdD;K$rVp8Y5J{lMl$$S5g
z!M&+LeiwpD-VOf<n>-|R377cWao;faUM4sm(Tw4Psd+E+rhyNIcG#1IN!sK4#Ws7J
zb1w6EtNsFfja5n+4?Yiun4YmgYi=b>Be;q_?5iBHmJ#M?1L0Uu4Jmi48m(iCk{jC5
z+^H#O{2F^}oj}z}Xje$7F5Pk-ak2Hs7T$ZOR8?(uFne`2`bsKEkz8XM5EostNdJWF
z3_p6Q8_Z*0Q(=)mB`%8mz4miP<1;_s<Aav<=FzXNA0QC9zDLM3lTUta51FWvTJ=|6
zso;i*ozt`QDtBK at k1VpP`ok6WtIQT=YDVS4f-j%3{WzMy3`+u{d{&1^#!In38XYYe
z8M_=Ca8F)rP$b=Mw*jZfz0y)1#U?=$EoF2RdPzzxu97$49n~?fKfHaqnfeK;6g2G;
zzY7!Y6Vf_puF>M0ZRcClKH~jT*DoFNU^h|0uk5~aW?Fs*+HK{n3%v at Lu(_D-D49Mk
z4Xdas8yk53%CF~k_YU>T2)Lw#gkjFru5HfYx9vA!94v~(@}<i+|H^_2F!XGl1oYA4
z>zYOD$(*B4;oqhQ9>SHG9}4T><>jgD@*OMM!Wek1s~5d8X`@mDQK`-nF8OXUfV6X@
zf+yK>KttcO!WN<1#Fekm+CFjPY=4FZqh>65j1wfMpJa!<KZRo&Stj0 at 4aw*mpKAEs
zKo?Q=K)=O=nLyId7&e{mx#VRl?SJ_NcE~X>Dc|dyh<Vo&&&!rE=D7740*_wu^Q`h*
zHpV=o@&o)@E77Z~aOXusG^`DOedB-Yd&if7_aTL%}`oVb5}V(wn*9})?B+3Ezv
zqcsxJey7?ryfZ-UOf?`KH~4gOeI;#D8#WHiON%C)Z}K_aH+eH8=ZH-U8(Wib`Yf)%
z$a&xDwV`M!+Q(&6za|B%&@<>C^K`MWU|o3u=%~gtJiG+e2At|JA+L*@CxZIU6d5c3
zexhOy!rG?2Q)7B!-NM$TE(k%cseI&U^m$SxA_}b|74<_3?;+yinG0X)XN8y@{bzq?
zkb at +xzWU))H=2%;A1H0g-LyI1(W at B7HSSI2kwIXU&_a_twX?I at X6Y9H4Gxb)59w~q
zo{q|wM2E`}tUToiwI+Fs2N2DB&Ks<^%h^mE8+vrv+O5onY}rZocDH7PIrY(z%9Iw%
zt3l7Mr_FqwA4!+S&#oQ(N*a$SIuImM+0Kv3jhcy$txeW(Q_*JMRkt;4p|N=Jfs)O@
z1F7=??_<qdVVBx}pA3+-i2vMANlB3$aHaaq_{$`xoB=c$2 at 2<6yYUdGCi%4Ju?O*$
zc*fqLZE(P$o?VHlz>HP=_j3Z|Qbm8Wn^Q%fbA2q)nR)!bHgNU#VGIm51UpZMoF|z!
zLzz`%Z=wpxn<;zA((X8yrBi>zaPrg239wF=1m}?OVxHF3^2QXpmDT|wLC9|eM|PfE
zs_d|MjAzo(O0(EcSGr(UolkZ2I+umyDw{JxQIF(Uom>vzdoRj?a}LC5^LxyUwH22u
zYIWQ7wpyg-M*U!mGiu~Nw;?Q#fV2D{r+BdpK|_y9dbs!8p};vlkyN~M<VyZYn3(+{
zX9f7q>zHhWIaKS4Hir#UMVb5bkA#G4K|`#X+_R{da3+O3fS_}#yEM+1ra at dq*d=eZ
z^p}@_t;WBh$-BKf>$V!v8Ztor8_}1<;8QaZ)t{_gT>M+XGc0b;|IW1xcu2FiI^1jh
z^Q_U(&O#-F{*O9nkxw;hZG70wKm3;6W9w=@DTjy`w$-wA8zOnLt~nO}HKebT+wa%~
zI<Wk~+*{RgEO!uY1V4k at WDw4eg36h+rk}sc=!zbHl*TzwpRjo=*WHr-xLfB!Wnj4(
zxY8Y`rL|V4EqH=Qvhp8D7X5@=dF>591%eD}{=W%PJ$eB+Ls1v#D!nKQJ27EM7zGDj
zqO{D^`g(e3%+8K$RpYXWsQ*?dYMM3xOOiC~9!*`SrmYaB(sAf+*I4n8dC_7m`1Mf8
z*3lwnv4Z5i<fcS{UjSAsL=${h**&``T=%tP#IGKSshL@~_dn{#y}as`?|b%E7~0gh
z$`yWC$z}`A#n$;hms`xZNRuBGL}1|hP1KUkpMx_Zcpr=$KTC|1mA=nGUf4|K at BBx*
zKR;v+u-&o<S`ICNNHs1s<K}~37if|7UC4;PWPdXCwgkc)@ZQAlbg^k}2G*Q)$+BAD
zwXE(t)6!r5V9}Shf{Kr;g&zERZY3ue3aBp9jpyv{5#!XyDj~&dcN*PMw(G6AHI=pW
zC^#Y&OvYn1j?+<nC?_;sz at 9fmDE=ds*zPcN;lAO+@^I=(&_p$SF7V}NuYcZ=*H491
zuGQVNY+v_?sy<(5ns$b<)P^KPMxx+N140Kji}x^{hsq}LMZ3#^tRkM!h%)8?fB!Z|
z&}nsQ|FM5x at U$wK_kgRh4}HB&p4Oyq{A@#YkJefqS?wK{h`ZbAB1)I77sHu3uvOEu
z5XkxBGLlc`qy{G_dn$-Y at jp*NP2+C40=ElnYs~6u0#3p7ZwQ8p>84xad?3fDMD{Gm
zF{@pSI1JJhvhF?#kx|uF6p&Mj_4zzrb21mWN1Q=0zqbxD`E)PSl{#3Fy8Gm+hrpFO
z{8sRH)%y^v#^&3Hg}2{~8Sor%qts&Fz#7G0q>2z_hDC?hE9;T))+x)X*6>=K&X)vN
z at Bh7b5pIOb*iC)B>**}ocxa~jG0IfM3gP1FRQw(#1n0Zf5T2IXrwMIr24MR}fO)+I
zGs at AM`Wui*4(4=x6Iz57nhZmGvY|efv- at C9*3|-pk}^b5^t17?Pl)5FZE<Fv#es=!
zFNvB(6Vd+n`o}ib0hFB$q{7p;fm(NO3N+eC*~Z$k{r0(HZ^P$^MLxxW;AxD+{i&uB
zXizMhwKs&!xyDeuF})5x^Uva3f-s=G1&*2nYa$F~K90lU%K#U;EL)zf8OW#Fk!L_?
zreVnZqNbs_lfrF3{>WK?ei#&1JB7w^u`v6iRBJ<_j*fh5{Z7amfU~{`h+Q$h|Lf{7
zh_wY&!TXRqOXq$d2LUY;uTDCfdBZFmZ?p<pbH2H&0fPP}*{tK~3=DudeGP at 7fh~wn
z%efl%{&I7TpX5I~Ltq2V_5mY-$;M|d2;6^L?|R)3jmGepyk;gRDRUKGd*n=Tv<E9!
z?150 at i?*UnxTufITOIi)(*D<kS6T_zoO}DFcnRs_>8bW8w&B$C`<Pqh7>QxA*qeOu
ztJBt#u)&x9#BxGBm>$Iu)y?{z;Xp55^1!xJQ8sRNd$y0F&I>a<x*qRb*u4C{*O>RH
z6qQM?2D!Kx2&GB|Z)otUGly8TAnens9DA3Vo#X8moJw56<(-Uuo->#2XJLncn#;KN
znu2%P<*7-Y-h-%dI46A%e{bHC at 9NtaiErHJ!k!}vAxo&LACF*OFhN12X7Qs8+45Zn
zWw_FPs&`a$ZQ<Xk$=C0Iqtw=+fqrDXU?%Q>%CZ8{?iWi|W+W!o7Xq0D)M17&S0|Nw
zkK|sOQJd0}vu!H|8Hln4`N2kdWQwR;VBp_c%|nFEQS#4gt{WV+a0ROM3e$)($J{3-
z7&&Xcnt=w|5Z3Zy&4^ZrbtgBoNuLGvY`Q4<R~Z;96b^?2ZfG#QdJKb(ENiCnMvB!o
zBK<IED&r^j%&yHWQT^mJyO$Ss-;F~1DFXw{^sL8Jzx|-X{{SI~F#Dh3{4#pp))Osz
z9dJE>&ocdsr9C_aNsDYy+!pGI=GLXLRDo0kLPv`~(q%mlU%IQxV>jheux2&)!TsK;
ziz|afmt<FXK(XoEi at WO4)%P<kT4v(}a-Fh^Q!;6Y*gj|d!3G5-7pYn6<;#~eb9vOi
zhJO4t at 6wLc+pW}}xkSUaP7V8op?gO!L_7{&EU0z10GH at A$6kMGZv~zAUqtm~rKK0c
zn7IP2HH#F at b9nQMAUaNl6h=BT?-+yY9y+SPZvI3vlpI4Qr^7{6zmcJnK0|8E$E<3y
z63MPY5uQE+!>sHPr+QNc(+>co_WQ<XG6`>2gFW2<Blu}zT~*Q%H;rF*Ia7S{ZmEi8
zwvtDku|4`Z(I3XU=Wi{}h1i8=P9S$i!*C=qX|MF$92IT2(~mEVj4V{Z<Z48#G~Gh<
zIuu1w?^(<;GL at EuE?#`lGx3spAbe*pPbIF<LFq7fYS+yo0lYZZ&@h;++f4m~o4Cr@
zy167j<MO#cp>w><53RRLgmCA0LhBjx&l7T#No(~aa|q!#i}5(;J8iydx5Enx;CwJX
z^z33C#JAQ|=YNhuQy;VI4C&F){i>mgAzF{o;88v8!%PinW!bm^Ed004pE~56;IH2}
zU~BmhyjtZL`%Mgg;*i|$zA>j7uWnzXk^LU#bE02KdRw}gSgw{=^TQ6*Qedo%GL0Bc
z<Ncv?&FgXH7^{k1Is={b7a=)eeSQi|T3YbY=+*}OagSVi$8n at fV6=fezl?;etZAdm
z@{(4aARnI$7kkq4Rlg+3bqoj_H-2%t<l}-an;Lg at tx$0~9-j!9U};p?*%lBp_XM8Q
z`;igUJhfUSPnLZBdZ&G41g+oKK^%0U(FlDwC6OR&Qgf%Bp?R#kI|KqB9UVQnZ(Qd5
z=o5%elr!^Tj*|Dz(Zw~5Y6Oz7x}na5kJn0gYu*aTsd>6hEVy at -)Z_)bvVEOz>J(Rg
zPrGC_-;64)Mxspv{L~>YB1^*}-)2Dsia}?~VHB!KmJVT!6!rQo<lwu`JI=p9o6UW+
zb%c|dC?p^ZfX-|-w2I8wS(ln1=-b at rA`ev_JX_bj0ynp;a&FDT691wnF1 at rVPDROW
z{`?SSG$nWUgVmfi at PR$DGBKOoR4e$PW--6 at 4MyMpr8cvdKfAlvJ6lAbvar9JGG8<k
z*X|8Qsq>W#=5cfB3~P&PM|}VHIU8M4wp6Cxo#FwQ(B_rPblHnv9`~qaai?!8_e$^Q
z5Jx>nYfXMBx4Kt1^+8Qm$nW^rd&<uQ0Eavyz<3aaFG@(3g#Om{<!PvFG9oo|DyK~S
zk*M at x3xDBX)XX#P?6s@%CVOA&6nXKHVtz*B!6zjPftYdVz;gpf)2(eh-W!SSrO&u@
zpk7 at 2r6&I&XZcFAreS7$jfKsM%1kmuZZo0^G(~Ksay`06oA&z&PtN1x41rNp#h?))
zvcd~0iA=h1ZYZ}<EvF_Be+3r#7XqV>n0-Q4fsS?ZT<wiA)+^|t3+}h-2<=i;Ie*J@
zkj|%C_mO%&ShmbiS9d;$waue}9ik^Zv;XF}O_jw=Y`{N8Vh3!Yd-#E6{t`Trd>8+z
z+(^T*!3T`)Om2m?X~`Iz+n^Qb739yj%~#AfgY5c>RL3FgYt>e-e^|oilN)MnSSD|6
zA~f*ca${1 at G^YTQLxV3mztBr55sx2xbqDvg*?%-JVv{*d-2MB5#c*2T<}+WZI{uyN
z9aB=xxQTsVpPCa&X2Hr~$HCIz8m#I-jNBbSkNDzwgrVaLo)w%sUH)freQozfy*8kI
zaS$;sWbI2mtC1#jzcnnS|8~Uhk*E&DrnXWpM)^zp-x8E*P1g8X+t7>(>`~Cg?{%c?
zT3}f0z&GQlGX<=v4e2-?FSr8`*=0eb760E0AS$wO$e~&2K&+7T(c#2?0rOHxuq_Sd
z at _FcA*sP{N;Cm}goSIgffxoAtjV2$vkyh7VI(p|3RX1A;-&c1?v6pWmyDu{Of8E>3
zAC$^CW<0LtHy(6+?)6x8OJCI8W>5O#y&=^m>IfOrp7_9 at b3svOvI#?Gj=EoxjKgRw
zb8=F at 8r`GH3e>5%RF)iMa^S1P&zt<xuOWkUW+(@*(Q<V^b63e$QYr(l^1inqFDLw|
zavOO7VY3Nb at GVU)5yB<HwXxmKiEbQ3laN2(tl)}yfg5T%F+l%!k)5;m7sQg~RfX^2
zq)>3W at yBT^?+vME-Lc$5NXTm=V;NcF*aApB2mQak?R%A+o9;b8Q)WQ^*4*h4-COSY
zZ@;LsOQ-b3_1X038>)z=>?;?Yp-7iVQ{rdyLpU`J1_!x9viBc^<gI_{OmOsmbvJa`
zqHd(Vaqq3L!_e`Dz5~{ClI}+3Eb;FrRoV#YlGelEY}{<G$0A7r!SwDUo>%^9GD3A3
z!qV=+*>tkPqEnq6!4u78AIm=mF7TkE!bXks at LLAmD8jLsk4$uX9O0(nMXe`eMRN#h
zJraXVY{FP%R$J3Ljmv3#8vC(9_fs!c4>IkKljQQ}uNh_*BUinIZkb<sBWW_lh8RR1
z&^5j4tKFgd1)u5pGU}i#D(_{%(MqG25m;Er1q59eT;g^`g7$#_91id_BEv(Be$4g8
zqrLqGc|2u<k+|z-A}*`k at y=uA?Ka0mZnX*dZd54|^lz!*NkbOLSQnX*FZdwGm}ov>
zG^-j3g*l8~UP1 at ti&ZC;lPAN=;lD=0cU|UZofGBA2FV+2O8TPX*Ik|PU}vDyXw91=
zO0-rG)c!AQOOn)t+#0LgNhj!%OI(PEqNoq8-f_94vIiB7dqt=94-fj#5EJ}Js0S<d
zJ~qEssYPl=<9Y$gvz{UxlkbHFB^?phB>Y`E7$7fPS(fTcG=<W`t?_oZB_v;sg_CVw
ze2^#gEwRT5K^}c(8GCDYvD-AGGyb-(sp&$(o at 6SZ2HFMqEEua^_vbMNhfDm at NDEUt
zV)Ny3_}ZgD6*p`DLIb-b=Bc%<PH|t7Z|dzwz!$7F!0*VD|7q$`+)Pkfni1!7z3Ph>
zT|;#BNp{CQaG92V_FpGiNp99l?m41nkk2HlJf%l}(jIFu%fJ;?SB!=|3W_Bwj6>3N
zD!iHPLD!==9Bv7Inp at -~0PpNEFHcyqT?gVRM7)k~Mtbz&d7)tL{QF52hHHK<cEvik
zrNaCn#dC$bTTS0QO)n}bv(8 at XmLI3Zsif?@b1R}KXQ8gMn6RBmc3uR$B4Kb;mLye{
znWye~@d_x^wq1DFC8x;qYZG|Bm+{>>iL at T|GzRi_Kq~TW%0@`m3~ggVQ6`oZf~jUy
zmxIdL7KTL<AQR!i9wTllO<JYl at 4__O1+$fMI4%cH>2El_q^R=B#2iJrYYGE5N9`xX
zM%0xe1Esxs=x*%3*fXP8E9F`2k{JWDYW`ieBLV_t&l&writm0teW$f!(KY&)h at 5u9
z!b$8ZOuqi^NJ at q^r7eYTxcuXJYCxxM#i2kg5QBLAR*hG`19)IkS5%E=KCYiuXxW}S
zFE~4u|4o$BDo?jhHp#SatYDqk=-F-RhoLzAy&p;dzTR?DYf~+NKxNUB7ydmMFuFa=
z>UH{tD{wCc=bhwMu&h|@<@+MPHU=c{OklKTJ9~Bxw7e1F-v^D9MMoVE-f-&Eni`U5
zcv;h8SnD8fM-bFhTgz+xcVY2ooZqJ$;)+#9RR>;EhiyRN`A$WXsCa^k|4P45(pCB_
zEvR^2_?Ot^#=jK4p0tA#8lP`$^L~uy;IBNWNPn(U-Av({dwHm>kOBTIyX+82<jTMh
z_H~gKouy=f>2*%k`Dsjfo=Kn(`t=CVm}2`cZAd at kv`l6Py`QFRkIUp)@Ac?3g!~7l
zlO030wpXoAE)SZg^}M(KB$>1R&E133upm`~K=6-2XJf1XmE6h<XJU2FowC$2mdyH~
z(Xx%v$FE^cCKZQ#10eYUp{fUPW_5V;>|r2}$KuMkP)=`jf at P&UJos#XWX&XOgF at q#
zj#fmA<1;&L{+#{`n_UsGYP#%df)Yn_Tbl{s)%D?So8+(=1z*}*w at 0`H<EWRxd9C4D
z%CS0ryc9cL at aF|%OU3_v-FxHpSc?ORZhWfJ_$mG##v1O*fM}NKXMd7VUq5Y8QJ`s^
zchEp!yY5SQg=mOxdes$4R&oSZTJjBu at KRn2bK5;_2-C^?nAYi_6fsfRWaiC{;7T-8
zEK(hmSA4bP#KgU~wUAhkl1XF|3W5;r4N#rrqD-_=n)+EXufVP&LG4J^7h7pydnT)>
zpX at TaQRkF_N;V`<P^Sa at a{%*3rk%dH=Nl^Nbig^u?SNf(eFN|i>GjmXCCxok4l-pG
z1tyNBxFlG$+accx>bm@{Zv35dN;Xf>K4eph?>xP)#)(aYLw*&Tb^4O^k|4qb*23=l
zp;_K!hlWMkR#SFoS$3AJ{Jf7l&E%m_3fl$#_!z(ZmS2cb9xj1NC`l>AcKf+j>+ at FS
z>thvnp(tPmv6=K*r^-hKzQ-*JA5v*ZJu2AC<st~0bw;8r6cQ{GLISaIlPJTN?qClF
z!<6(S_2@{c*#T)<P5oW_)4|(q3`te;rM7Z^LhVSD(}!w4JKGp7Ei`<OT9m)wyvv4v
z_e~&5+;bq(n1E;X-n^=v4&Jb0YP>9 at YEyytCC@{D|0=CegT}uv$OK1*6UkqcCYtHm
z at F>1pC*mj~)TnJYrcQV%{!&X3xy+N2H>St-0+w{!!rJ3#YrDmJ5vmYju&qe`g|@;*
zZ;-#jcbz at MzTiwBbSSfxaA(SeU#WU!yzAjLeEGTOpt5dKK7z&=7S6Wfxc+xWIqO|z
zRZFg)96Goy=^3CXFiIYV7LOu6-TQN!Q5PYsuB4X3)uKAOckJPfo7Ovhka*|O*8h~)
zUR#|Xu_u(o`;WB4`e+aMnLZEl40)0=E_u==+JAe=7Ct|3dnp`8FvX$%MH`!L+f?qL
zHT~lLSn{)&o?e6QY$^S#Q5G<*79A5rZGd8*lvc*MvZMuR!gUzIUiI^L+gWkD=nQ|{
ztfp}m0|ix7JZfM<X9BqPETjE+-!=Wi9T<W<L2iNxQtL at qej|HpP*G8jjPQ*0<3~5C
zoH|>)N*RlsEjq4ta`TTxGrDztfcJ~7BNj at D&pKyb#2-Lx3};q|N|xN;Xzpk`-?bSr
z$Fl3fh<4r_C at ul_LfTl>r<P*x#YN%}o0}=E|J*mQ5ccoxx-W$8m9t4FHM9QmeCq at 2
zXe*B4Jt at osFV7OBN^IY&j9*W``NyvznE$s`l`UrEIcAK at tso3|G8pn?j*+OM2cQIP
zynAZXfpD8*7fEVlQ5p>osuqv>IceS)WC7B9pk{gR=$|M51Gnw%R)Q8S?M_u_C}fDt
z at D`b$jl_a?u{%zup+$Aj_Jy;yqttG7JJ{J`#oDJhTd`@7ISzPnez`@JPJ3Jv#bLSL
zER7gE*M5){>~Xp?tMg-1BbOG<oDCbya|93ZgOoh^O&#~%tdgN53D+f57y;$PTmrPn
zJ@)0#BE=lq(5Gh at IPIBr)M+ASdYpTykS0=s)Uz+PsAYkB7ZWnAzx5iA at ww|=R1&gB
zcOylTUL5 at CbDpg)1APlkPob;R1vm at q>Z`DPHg71}8;&iwkZsYybDX60j+~PZBu$1E
zv%>U6w*0WrtWKro(mdu#rLEK-kN(8=)>L_sz=^3 at Gr*B`gn~R8aetR$JOxgFyT7qf
z)E%vOFXdQso_oqb#UtitAr$OTbK1DMx#?4G0|Yl-{3hMd;RRgr4ozb37mdOEbE>s-
z`I5-NhtgZprN%kNLC&QSS_)KG0oqb=|G6k~c715M*IDt8nL=9OFf!Lb-N#92$1W$q
za{9Z}Nh9Af(69s+)d^Jy3-6Y#!&B<hw#@w5k0Puag}Xg}pETU<Fp4D9PO9cTe?xT9
zDO^>k3UA>yzw%EgL at 6BUH<oW&en`h+SNq12#)e^RoDznP$fGlhtA()u8>Ii~34Y7v
z;<3^=7GE}Yd5k!k8^F)d`eI=%NAB;-v&ja;-N_$Vx`A82w$IA5<}?OsGry)g4Ko@~
zZ9aQPFgQxYEJt9bb+7SEv9r0u^;S`c>1v6=78pib%bVXbMlSwP{ym|m_^X8Hm18PL
zmU?f0#9`Hqeq at it%b%uNw5%vE{>cDIO7+ at M&qf&|8!Ya}Jv^+73c!m}#kHCCn~nRe
z7FgWRvt6W5kdg$H7^lYmCVj1e?J+yb#&x$6-mve>y^7&d!>k&1es1%A07Z!1OWH;5
zBE*r{EA#1N>Q$AONmsg6qhbO4X<o^%(238Ws)e=5QltW<bp*QA(3(8|XS}HR=R{Zn
z%+zsB50Z_FBc==GkhJ$qP8X#kl-AL@*Tm}|3$|^3IB<+Nqa$^pQx<Ln*4E1ELv!a>
zkI|}`-}ZJ~<nlyjqUm7?^#uZp20cpmTI$yKi=SWX3QLjkFa8GHi=;mf^ooX+le5H_
zlD+<$0jJNbW)u0D{W>_k*y}b1jJT*QrF8ryoBfo^hk{=yopu0KyxDLH+vF6JHdJi+
zvE at dP+o!0ANm=ssyb5VQqeb^EHPu}g99&Of;4P;zUsgwODK|0gZEbkZ%qm$d$IU7(
zI0|T3g>{%;-Xtuvm1fcfoddnC-O;xBMwbH!ng<Vw_J|G{@r3C*G?+sSn9{OK((K$v
z>5jdeX9cj42U1)z#1QkJ^tAN{Q{HcJ!=qtbumy3OpZ1C+ZccJXC2v~<e!4e`iU{q$
zxK6`Hpo{C>(Hx23bcw-l0v^7}v**X*lCrYPSr-X6FFaeD&@<r9L#ZyDtrM at kWd0BN
zxANg(qw<+svaCgNc4<Vr$;@8{{MuE&z0?^}kuPM>?)Im#?&2%Os-DVSL+S%9%Jwg^
zh1?8q?z4$^ul}_SuS%5+C#6kf<HAl;9+^<)cW3Lrc8R at JW*kN1p5(&R>+I2iKo^k0
zJL;9vA5YF2W?kl&rAQ;yd;_Y*g?HIX0Gp(fdSvP0ci^#!{&}*>+M at 7Cn_&p$9Htx=
zO-&d=S+2hYVPQ5dsJ at nYYNh1JK)0S`%QlqfWIc%*{HnJXR|!lo_2Kz0WF1{LXYN>!
z*1D<#37;!~f9 at 2X4j+@M-gdye+t+rp{`^`&Sd at CxBqwbX%5&uSEu8_GGrrIa at i8{a
zs${x2UN$wo;azS9L_66TZFN)>J;x*dXh1#38Z!Crudh!d5QxG#NPTpS>_f1a|II<-
zxlHqC%Y)_Y^8KZznrNA(m@#}tml&&Md(q}Gfu7L3viz~6;7ps_=BV?*USwmgo^KuG
zJN-uw5s&Yl$#(-Ny=_GO<i=ji7;NoD(t5p2QV3B`BmL4#_tDTRg^AUIl{M-qZN$u#
zhxkt-j*(_RpdqAHUQYQdg3MN+e))f)=f1PwdW)ucSZ+6A*{Si`vp$RUN5@<pI-GfD
z-TH&_z0t}8-9jI7Z1Uu2`1$xy^e(M6jm~Ro)IKx;_ZRheVPD>CT?tw6zR3;;0};fV
zchkPqXFEsKUa1N@&_$L;*o8_`$(hO?P$3_)v9jHRFPHZdG6NP%S|Pu`9egO~AM6VM
zIxRi3F%s+_Q>EfWmwnyTNAj$4Gs?NF^k0jz&xhUvSini`+Cnuv%!<9vNidz7)NnBS
zXICrY;*k62FMoL?muOJhIZhW&R_e*6l(RG(2dk?R$pW#}?y at fyy0THqY~tnR=E91v
z7AnO!85aHcW1XJ=JpjhVoa9<735w{kDPI-u`ve34g%ZgZcA%c_J*e9t at N1-Y%67e<
zwYp0&&|YaNu}J%~{C-kwr+-U0SY~Ss^vSb6+JAcam()@-ZV+F~e`Aa}@W(S%!LH^4
ze2}gO1sFX3{*M)`M7xwpz|n#4GJZSfIt;fjc~Ci(u!@75;v~_czN?Lu1qoA-Rl6#t
zvxyu-+3T2g&#Ua^Q<o|xd>oTO%(B0u- at 2Z!h2M_Wa*hAWrff?aKqAV*opg;sm#?Tz
zYp?s6 at CBHyjS;xam+v>zSB<C}9CEqQAG;}22Zi#Z^n6z$P$g~aAoQXSlQDWs;O|E6
zU&!OowZC2YpiQ&s)s=|yA(|}W)}+TYEZ~<*bmh&<$KNQF*~@$m-v at rYI2}8r+J2FG
zLOmwY6=lwCLrlSKmUTkOZJPz82q9v`$r%+E?H2zfNZrw;w!hf7kR@?7$v`h1xa=qD
zHGFie<_~zUt<=RjiUDSTQo+shX1uZ|r;$rHsONohm6y2|SW2Uyi+^|}u3Z`?YI@)%
ztgu^k7x6gXO4Tmaj**Ivf`{dueB#;gj}tB>N8?{{Tp}5l%%^!=s#lMOD=XXh7d0C=
z1$9`On5yo68c?l5`=|DPry?(L125ZFFR`x$+6$Nfr}B1bg{Se$idM5UTgt9C!Nu~X
z3=E5=6&os*W`{xPQHB!_ at j9T{bG;wA^de+gq_Ighzw}Ene#r)<-_@@Gro)EXG`SZe
zWt$Uy$$~KXeQ}|NwJ!d#<O?HOz71%Je4j&<&VQ1hJ at Ca(hMhimnlj4zw}vk6ww;`Z
z8 at 1whDln)jPzxq1;Mc}FqK+4=sK^^2DWPS%*gP93IIKK{#bUkJ;hR0S8-8KvfGj3A
z2&7r&e7fD|YMB430w>zO=~5|+E4e=Qc5Pnn5N~fX<mlVPNVctKpsFN2(Y8#j at V3*7
zfKSNNB~#O7Y-pRKF%0hflnG{fz8i!ik-bR3NVZ>r&@BhXRR`y72gWW}IRS22PfaTi
zE`N!_`e^$wup83=pT!GcY;D^*`E?k?%d1A_;_m?d=w|4qwQc7^`zODtoHI+z&X(0x
zf62`Np6BMm)cEGQ{j>zd)42aMaJ=ga(W`V?TAN}iR{{A=l`J9(E-gQ;F4Z7}#0`ic
zVPNX-Q%zonh>B;gUPm9Sg+0pA|0Ecf_As9=R>tdajSIS2Nd0Kp{X2;)znKoo`(7pc
zz0O1Kc+WQPXeAWdr>D6l*Vfni6JxD;c`^hnH~@rE?*x!_v at j`?dS1~8M&<0TQMaqS
zRZ*x9jNWeNyg at YSY^4#op2F|y^qYmu_-EMUOH;8Z*XM9*2zX2<7tZ`OaQHcwU;l1(
zasG8ItYAh11J&P4%SyA_>Yi(!DZZ^00ja<_DCDo at 5gOATD|t+v_4O<S&B)bao+Yd6
zL~~I!Dkx7jjic6qk)9s`Bl6W6cfG!?Pt7^t&Qw05tMm*Cd4{{FdjI~uBNdfpIjwTU
zv_nK#q?jU7tysu%xk{>TPobzN<f+Hr6i4q}I9Vsez)|mf15ovl$^Px8N4!);BFyOX
z<2;Qh=WzLc at T96?Q{bR4Rc#YI%>IkGHIM4Y_1`lSHQXG>l~Egbtk0Ob{4tEq$`n}o
zY!jHv`G$Jc4UYe+8K)(Ct&Zlnj#_R!C2TY?z${<A4fs-3aJqT?!N1QCExHe7y1s5l
zEcu-7LGW`IM18Y+dT7yrE;Otz#@ET%6ownh at oT#NvwQ=>j9r%8^hh*Afc>9Y8Guj7
zF_1l3%`wTrpA5mBGokHAr){1{>|hVRAmF$KCE*=_ylz;&Ccw1c<XrdRVAt#Xu$X}D
zEZXNZ(ySt(So$reOWmzemHY6gRL!Iwed|B%h`G>tn?t!yhi10b&H at _QKa7d5UO#$1
zr)fPh?&E4EA(~{`kgMA&ay~&No~s^NjZpgV_b6n48R>J%1ua>5BPf%8La7V_*-dx#
z>FZi`$*-2SS~Kf?NwRnwe-&~G*OjX*-QZ!d{%|rcxNxQzW-%evtEJ3Jd#5S7*r~C`
z06U_>5 at E_MM?X(@q#n?-vTwl{r_w7s5>hSAHUZKb6vVs{TRrrTQCOkEIz73wUBr at C
zp>d&}g0&S-RI9?4ae-~hgLA$ha&0|$i2?SmUz<T411+;0m5jB|1j?aZm9#AQMV>Xj
z-$}YuXAb;f-Xk0B{Ii^NQ7AI~%;<BhmH^v2u@|pyg73J`N8 at 2|VEi9o?v5vYPB at rX
zH!N`KEr*;QnuhQlsRQ}`@o$Y}ADMn>sX^NGTy;B8MvVMhhL{UKUF;*dhw*le4i at kC
zDpgr>W4lCZ03J>7bA73opO6p?>f+(V=DYuXqiG)*o0wF=E^GOXOwZVW11E^->KMPm
zf4+kplWP84>wm^{6M-YYz9xq at E_+vhNSAT-@BxmQ1PK1k>DtL22sqiy(iJhsYrXh>
z<UFQ#L=QE+zK)QPF==#OG*OqC*@dAd at G0$=ZWwGq1kUtE^k$DScXzSxpz<_ZN=6<L
zigo=t3^iQ{Zu;u}gj_A;{hh&QlK{-nt;D<7>H-*`iUYiX41H#Er1x`bYi0gyPknz)
z9vwFLFyAs?OW<RB99KexSxmSSK_bobh%2d8g$M57>yzJF1jBE-jvv>b%`AAJ20AoW
z#5m2KuJY=e+-i0!5%N^pVZAu at ab85gX)gvSXbfekk}RGC;Z~@ShQ;^0BVE|j6`k>!
zk`&LcqUwWr?J<B$bwNV3NAxhG#C$`Z1x)k?H=6)jf;aC6vYs%a72GKa#MFFWH%jom
z8Pe{2b;PsvDpx!ECBrez3h749y3_oM6ySSwX~p(3S}AEZ8+~8m-<G^T(T%4Y#w?Xf
z)zJlzyu2P)ImB0aM6lOa_K37lf_lUJ-jO>jmo0fzBL}`|)H?5!66PE(sp{0VnUZ<e
zo$S9Imn(wlH2hF0Vae1tDJlRr&ui4Y6@>Q+&pRYIXa5VhKmJH2>=O%oO|0bZe`UyE
z6v-hXkBxuL96 at C&x%m#7Fr6-8uX}F8p>C2ID~B$cPNl8Vs$T7Oe{XF3uQoJR$)0ZB
zwBXXlF1tf>KD*ancf?$s;oA<*9WkKx>r<Gz at AiR_sA+SvKYo)5I7T|!Yi<mfJ~=Jj
z?4K(97abFgo*?YJ<<q_mv}+iuAP@*r=6c>4c7TW8m`Q)%Y6jdTS at Vq#7-9fok(mwu
zj+l(Z(tHI;KRda6Yry6x099ZVa`HGy3WxA}W at csWK|VEH$|YiBD!9mdkV|fyR)N8u
zUYvt#%3ltKp{_19P&e-D$WO&|!yvB%Qjz3L8sh94N>qzz7WV4eLNUlsTr!*s>@^T}
zB9JO7^GZKw{3Q{FDqCl_R3Q+ns+9Y_#9&w`xsFPdiaO*$`VBFh-~!+huJ`i$=R7rQ
z)+ui*|9P=CkYIeOo)?_<EP_*ml|@K>p#Y^b(AY`9#(kw5rHO2?#SfQOTcM<x- at S>|
z)(5(6P{ZH4qa^yOPQ#=+DLcz+EQKoO!ks61-Y5(ClJ37WLcGjDG>%eX&ZWQrmUdPb
zK3##-DW at SqEh4j|c3 at ntOJ|=4|NauP#S_-h at 2urjG5YJ50c@ov1g0}L=MYo1__CPb
zH`sO25tL$_L5_&+rd(Ju{owyZ*ZY}18RcZt`jKW}g_JpAa8jknFCcDr0G<T#de!tu
z3j$<xNs*&BIqYCagoLjXXkJrKqi}ii8+O0tKt at jpXG(H%ZI|-*>E3S}Ccmp`oQwbT
zf$7a(#hX6}#O3(dHb=ltAG*&Zz}jz7)F0z~<$EKGr^WP+=N$xjhOYM>97 at K-pzvoL
zZBAD!>b~BKQf(%-?N^Nl6mDbueAzs+7{JyyricCG#VD%gyxU<F2-B|APSd^!1L!Z(
z-AdSrM;;X1fNBeROe4d_jQrXp*!1<2>z4?Z<FL5pDLOFAbJw3=^5oyQQ;7crJ>2v)
z{g<`f%-qTHUSd6FZEf)qnK at WEewq>XeZ0m$qq@~zR^t*tZ2hRhy%Ts{Q;_50B-Ubp
zCntbW8jAGXmA5W6a$xrCg^Q3jG-=^)hFR*%t*9kK7Ky|YJ;rVAOf_~n>s7v>wMiO&
zEF!oC4scb`F*U|xg<)zn^%nnSWTx at 9lauiz#mzfpeW%V0=I1HkwjDu_sE{-Wo>16s
zTcia;sN$?#vpxwF-<#J;H>}K#P%Yw-<O5YV&oYvxv)6+oOn+g(7E|ZCyq~D&9Wp$p
zaB}uF$G^kfGU=NbC9aUc#{*IEtCO8%jKUC<4m8#38d`UEhHz{w=V=NhFWR2|4dLXP
zuCS+Z0g!dPuR?ad<ie)xcZCYcFeCg*O?Z${y9EASC-&Q1e11-l2&mVGz1bP^8)()M
z-(&N`nt4Genj_#quc{r7_V?xGe#LYV$Zwc)JuGV~dwJRx;I~H7_T_3u_9hG$k#jx(
zq582Lnw354Cq4)H;=O(4yI}{Elgfj$UYO}k7obAnNdmU{Ve0;e37Bb+EvD}D00#Ut
z2Bz+JBw8gZgRgn}())3H+3JyngZGui#qgu&GoRam at J=?VOX-i%5VKdh4GQ9S{TlV{
zL*Hdr*`AR;Zsb17wyd*b3w_reb~p$!3LVXp0oCM(&-nS<Hq~TxG?{RN>c2{`3(o8x
z+3wm|FE#Hi<k(<X-m$;R8*CpBprQ-1w`^bHZ-4(Q_;1PR*)ALV at uL2SvqpJ22=%n8
zi<i7}#f<8An+p&?2#p39b0A_f6@&dH(?fokBa1Toi_vIRw*vQi%#K^n$dqaSy{|-g
zXg?UEwH2GRN27Jq0{z<28eFX{*?r=r0Wg at Z!c(-~IkVqU+tFsNapiYc4V|j`I_>a*
zN+t{JH@<KeL!4U5$)8&O?#SKCs~L!Ro<2$*Up67BI>%g%?D>xSr2 at xzc6@KLon at EE
z|MvoLSU76y!~j#Hj60c`E21N0UZk_bDUOYKd%a9Cm1T&}fN^HC!_C*X^`Cu)=Au9`
z=ESg(ZDvptp_XX!B5vZwF8=C+dwK at q3DPt#cmt|x#9|Q^OsE|;_~^+v>90Fh4M|li
zJvZ1ipQ91c9EoQlIkTG;yhrr-qnLo*0?car>Ia!&SCrv0{=jz+FKv1R!T9)ZDWXjA
zJON(Fh9#5bYlZ+{r04Zg`?b0_{%;a6D+F=@r^m>ilehaIu?nUQz^u)ypTMv01%Pf&
zW3K!0-L(Eri)}t0KPt&r*SChBw$I22b`}70S|jV at pXSu~<+>?PIgZ(x|IC_j6_D(@
zXdV3vl>TS2J}s}1pmJN+uaF#CiG%ZHaUHa|cZX^Y9rF-%AWkwN=+)J at _5)+gTc*^N
zum4_}UMmYNo-X9~w&?a2N;ySajPqZG#~@_omLq%+G2959*P?CX_uE*xlQhIz>)!mv
zBv`IWe7vtr5iX<N!9>9^f=nb=;6%Jz<<~J*pvM_dJ>i%2PLJAYw~L!|1Tb9-?9J=f
z9_XT07(9DJFULvx%;G(IjzfV2wzCX$Lmm{$l(Ije>f@|`5ou3Lceixe#<4!4!7o+*
zZ?aV0-T+`PcDEB11PgAtt&i`PDgKFC33 at cD@%a{6!Ekw%m<mxFjmN;(>1-gh<1~x_
zlj{nk)h5~CEZz&#!_y0{+ae5{pvIy0!E-on^%=xxfgGS}ZXly$>4OY>++a`hziT!W
zwV=)4SFywSf}yiSnS?*8OsSlD{=+-tF81nG`z at A@HNAi@&_5b!3+<ossz?K at n7Fu?
z^Gd8~MBnfQ;WQ3^$S(s5*l53mp?Z4O5pCDG-fn))*K3~F9q_gz$t6?E&4VhyuyNgA
z()Rf(&gG&wydSf3XmJI-*_FNd`QpIA?+Wd^jsLFh-y<R0e)gLmie@@Pz>EWaV`R>+
z)A7H(&McSl5KN3823_T5763zf)Lx%4T{pn5|2FPj^+pU0-5K6}X%fvhPtrO}vOv5N
z?m|3CELOr at QEr9*ZBU)CsyQx3#?N-4uIcg6HmOa;J-C>fswXdvh9sO}Acm_=LvEJE
z(0M04Obsx7I8iZ>An#?;92XNt8xxNG{l{x+U6JVHwr~{VQ?@)Ti6ARsF at h0}IqXv_
z&xFSW;)?Eb_?FLndg74YJxxY+4K5kG_bpbA{_cn>qr^zcLC$;bk;w?=$f37jckmmU
zix+Wfz0)I8$yG{jRMu~VO%&?G$rQe&b%(e+EOC!JMwyp at 1=A=njReedEW$dUKT^$o
zog{+e9IO|Zs<PoyaVC0-#xN?KkzhS(o;Z!bFMPdW=6i<mvbzV=5<fU+MtCvQ7!G;6
zhODZSV;`S~RboHf+zV2}`nv_V`NgpC!`Hr729(~$IZ}^x#&#q)Z`t+oiw^m$8qFwW
zR82El<=IKw`DFuCk(-H8hHLw%Gm{*p^iM%DrnUZHN6_`ui=pK9g9F2od?lh<`VL);
z&a2D}{m|u6CZd8VS}x9(HWMGQHDk)pSmy5CvpeD&!19zV9r*CWplAf*>_4Q(@vluO
zT(<3H^uIv4NSOB<kRT1cuqdBK9C at zXI?BWaGMk at Zd`AaFeJAx+g~jb2{(Fh>=V*Lv
zA2TyD(6}b!FScywNx9s)rB^lZu9&MgOC=Bo|5xmt)YCOuW1Mmk1Pzg*JjHPt3Q}e9
z$}8C}tlg-PzYfBlc(t2u%?1acqh9$F%Ur(@ilOXw{c7yV&VA^^y_WtkCASw2Hr9TM
ziUmd2ER-4)W?wQ-h`5fGw2upsOv~D_81D4nb<3z-PLMVJ{8MmQ7(`)ojk9 at GP#auM
z4>I8}zY2Dpl at ly=6`)n&W`051cQAjbTvK4_Q~$MIrP<6x4lx-K2VH+6hVb~Ku{aJL
zL9GMt)RV*}cT?5CCP!Hyl@*k2 at Hy3(ga??hL5dnFx1Bd2wWHVC>w>E1=U4><;UxG3
zJF2R7^WuWD_qw=-kZdhT$a15EpI=*SKjRMLF)uSg!f at G`OW*>+ZgKc7syuc4B^Jh=
zexJ;ds(y0qNdO at GE+HPKR7vGQJ9I%iXH68wZAWWf;Xh;orq_W5={m#7HY)OagtE64
zY^vDi0zzG}q_uZdD{U^Emgkigsd=@GB%e+%&rI2E(4{*N(hhnJf$BOXE}OlSA at E_b
zCNYQBIx{ycL*+jyrH4hDxMux1ln)&31Ce>d$W=Gf>%R{40QkKDt>AJCYt|zZ+PGIi
z*y{$1;&BfGFC*HldBHHPt=|UN2+gT{b{jo8p%|jSYo?MZ9xE%lBTdaspFD(D9uDQ8
z+$D#SQAL=+vy$fYcV!+0kuk;G>8J3SEubS$ST)98c-HTX){+ryxG8r6tiLiZBTGBr
zRTH%)UeEtEL61n918%NOP}1!IJN6ZAX4SG}W!(}Y%=rG{uR8n`48Qh9odBQV<DDPF
z4k|g!q5m(pY^J`0#R105^3_Q>R94$>qqC&NQjus8V(Y)e-;G~_os|D>C$T)JRn at fS
zV-6j3ZsB8TDbs)jS7&HP7^~Qg*VY~?#xU+F;kiUUK_ED7U0LR+H at 8*3Rt=Jf|C(;}
zsB!Rk;spWAJg-}MmYK)5kyzx;aPrKB$cYtXuT$OJNF^qklJbPx?SJr|#jQ;Am`e9|
zsTd%5oWHy5Gum(Kbg&=UXlMP9#vy;l at 0RTw$g5VlWzyaV0cH2yeNg3YBy^P}9{{x3
zHiW%X%2dj>{bCisJW1ogbL^0P4Lq(FrMXg5_>t>cmWR*MOMFC=TI9p}vD3c<7 at cm_
zSiC333#re>w~`yTEkuxOy9;V?#Z5e#hiLl#I!FKs69hy?fI>T92oG_w&sLGD1;LL*
zhtEo)M}@SOcPzN?PG782HWo*;;C^yF(BZ0HGs!Fc7jU8AqjEa9u(5r|A5UXK*FKAO
zx7A6 at C(1Gk4%<X4=~>DHL?}s_axJcc3TB&ek;QGCTpUl_jsZi$w(opU<>e8nzN&WR
zM&j1l at A+(yqckoz8Ioe8?Ik)f at yNb&N88uU*=gj&0M>dq$XDUwT%n(slp>5)sz|pi
z8bZOUuF7_5bOd694PNdq+;8C-aMWseE+qace$lYvpzUHm``23Xal!Oc<{0Th5JN`d
z$}tmVtr+N};kd`zMMq0zGTpW%5%Pe|Ky7>b6q=pmx^r|_M;!2%0OU7dLsbEo_6~J9
zuY5ia6$z>m&f&H3`{be;lmwK0J%g>&J74N`H+b8)?+a0I3?6%kgwH+9F1lM&JR{MK
z#uDK^9c_#t^+(V0W>n6!LO!-oA{J%;rRQT9$vT;Ugj7ke_r=K`vRmctr$3tn{Vqrx
zO3O{F)uzuTLK6!-PNfaIfW;3eCXBId%}i-B7ztfCqLWmc`xY`|LAshzrq3hl>sn!?
zcg1L_DBd>ex4=EJrPGRQ33qW)>!(U+5&Dx(6BaT`g3KX;-nIk=g&YzX#o8qE+K}Zo
z<eJ+AY8iCO%Q3#c)jD2pZ?qLO!_Hb?X=WmgA%b}yAWu<%BQKgnBVweXrkp{Sbz$u|
zZi3&coWH3|*i-j}?0RUY;_(^6N*JlV%O0lXR5P?ayV9 at XcO_!&#b}(tkX1<6!dO(1
z!?ygwOZ7QQWTLEeMM6_?QQ458Vab#O>YVs^!v6y`^;N{$__04a>B-R`IYJ3wn9U>J
z{=D0K;T+oI5Jvc8Y(c1u8u~J!9%z(GrEJB%eFYHqA-EORaDHyvjb5yO$B5kYuEbUy
zT734YiZy^pcV)H_s5^}?`ujBT&hzqoLEm&u`j4Z63%NCJ!^<|lmgqbn^WXh-+RU$4
z7BNt9sl$vi)2ffYh1n%`rwQ-fewr}svMWm9<BgOrl&iA!?Rk$}D~`#onLqwdlk{~b
z!p#!h(f!6bi6M)QKHbdm7<wP=>vtHW{B_+_9WL1n!mp`byDRLQ{EIzk0rYGXlItYn
z^XCGHAlZPeTHeja_H{s;E*v%dX>qFu)A%ef8K>~XM2%2OP at QLU>E(bkuMO4>kOqkM
zAgT|u{yP6iN at FY(YD#$6V3GUy=US6~O)Mt&s7h=AAV`5g*D>V|%J)C430CYc2T~bm
z*ne))Cp*!qc{u}R$?f_y9sAzM;&l?O(1ZrBjl+1#eVo}K)oeOFS|Kd*Rhn*oc_9vj
z at JFjMu;I?vO=gpIM at HqX58HNGyv4r9z^(ZVM!Ue?w3(Tiy8z@}?;c(GKxw;6Bc{3B
zkV#As$e!@qxSj>d)S at w6@@)Fa*a4c9I%I>Je023 at DreZgEBa{C=<TtdL`9O<LAJA5
zjb@^EG*vmsHcD#DI~oF|=hU4HY=b$s8wWyCt0f}Rvfko>prVZ7w{bk;9?0Uq9 at FyF
zZ4G at 2qqYWPiV(_2u7{EC&Kw4&LaH5246#6SKxml7%}ro>SAPD{oiED~sz49x?zwt4
zwr-q9mXk4}G`gxeE!^49gb46DI7$f{Up<T<`;fl=5a1`kfz3vrr7$1oKUAMHZuu!?
zSf8%Zk8`chOgc?Waj%2jy#nqqUy9C1Y$EjwAor%Cx>UvyGrzW(1{FHvy4mUp7vo#T
zgDix5QFi*su($34ElqQr#J?SR)U!M`i<_4wZ__r|f|?IpY6$(xuf70bJdEya4OiaO
zM+c9BxyL0GsnnqWacWfKl|R}OU>~6!RMY2rWT at 3E&Az-oz5pm084bLC=L%J!`{1P8
zlHYVlivcvi#gfm#o|2%<hZ^~rOhP%wx$wTVB4JvvtE<iNUu;^<D)3mml)HHQ4^4&;
z0Cf3^oK~hgrKx3{QQ4*hTj}(nFJ8W{d+6imhumLoZzo|~jNnNnW=@yViz2tp(-ZhF
z0CvkZ#3<<8BG%%+_3*v-?!D<hR0PMozJosUG+-7mq{9B*z+3Xv%r}h94{Ej?-XgUi
zvwYhet7?fDQ)hI-sxxE|4~%3vKsrmpk*&HBX}yXdf=da$-VeR}RV`I#)|wJ1!xni(
zDi>;(hzuRgX$g5@^9dQ6evD1pvlOE~hVc2KxlD{rdfq9>)>W4NKVtDJI10FIdDKK5
zEbk5v4_BMD5Qz%z2DaD{Sy|iKT$L*hC~UnUhfZ6}|GAQV){=G~(v?W-^gOO!h~ama
znBm0MclRqToXTpK1Y>+<iDZQdJCz99!o%{V2F0B at 3ounh0n0rdf6X&A6xlpGsUbRm
zSyE`N1uq8f;dmprwV^L5C`=7M_%S{N&n%)*Ki-uX!wi}yqqGo+7qXWX<mEep+znoP
zgEl7yx^Bgl)=9Mw81pQpo0R$0w&g)3*B<1l+p^l!HHAh2%%D2QDu}l$-sl{l$1%^y
zMlQcD`E&Hk-cKWEF=8k}`q$fz*8V%j!|R3(DGiOf{r`uiv+#=g`@X)?ND9)8gp{Oo
zNT(ozGzbhZbi>fyLwAE9Al=<L#L&{+AUMRp01`g)`9AA6|G<0Ay6fJ1&g<^8_k#bX
zd6Ci7tC)d7u_I2~v0!C|R<~BS3NKTcJ+VO?^#YHGTi<;`vNg6|@zDFJEG`0Cj-!;V
z`CA9{Jr)-RvI+#5ln1_~*M%tvmWSNOSzlfiuuIO$&fJww+rx4Vk&1zi;R4dQMs#I+
ztenbawq#^5cecN6Jr6j~I3X(a)g3atQ0DVU1PdSX1YRNTkD~kK#5J~7#C)A|iuOtZ
z$(iVlf@{hn%04KZlNmTc&pWaK8PH=Jv&0ext>~CG2%9Wxq!kMvdQ*=hkJF<4(#J0?
zdc9cs8_r_vPoB!3*qzW{&uQ!<fr&5LJJh+JZ^v2VCRPWpn6LF4Zz^`Q!QX7`!^sa>
zEadw!KgFw2XB_%?8VPW@^4=EWB*Yx;tYbOxaR at Ez;&C?w!T}$wWk|(d*xx&`eY3vX
zXCbAiK?Szx80yxHjn!+)2B?19sxjO68Nv0B>n-on*J(9l<&?IpkJFA{3m9NNEGkHa
zv>v2ZJW!H<TGrVg>mtw&<F0q%{L~3?(|x at A3PZY){zydI!)u_nR5UG$Smb at mo><za
zo2-+q(()hS%h<u`II9#jg`a^<U;mwu0GEpH${H2l1Kr+UtI}n$6>ysW_)h+XH)sHR
zGEV%>G%_;8ljJ&t!{nXbZR4p9iIm<CK|xOPrGQ;zh at No*ozy1!9noUw2u>(cvAIqq
z=ILa>F*5m=d;ELW=?K3`@dDBE$bO&p{-y!haJ)*)?V2%&A+Ld?ejC=jWYcK()57~y
zMg^kgUYcF&#^0S|<iy%&XIf;Aa6<yB|M8?oaY7oUr at 8V-2c#Vf$$4#k(ee=AG at s(y
zfSDOi`ods~;V<BV4s6GE;Gk`JJeSC4>eE%2gkH)!@<k01=}$>#qSp^;+jjjF>qu=Y
z%t~?i(~SDBUqnkl1wI3U-$?IMmaf`Hf8m=4hwdr4;l;|Do^b=grSb*u7kYSErAfxV
zVZ0kQmF^PY7ppJn$G&*&4NX^w3KFlM*#CDvnFK!F&@egG+$-}q7_WZHmixFi#a5GB
z(CemT{=e`kp=)T*zklEQh7SJ@)`Uf5k{W=&HJL`?d~Ya6=PS8Fj?)wjJXCglXwOGa
zgZ*Kos_L3R-(Ym86kiL(Nl-EO!btV3{Li6!i6#bh{@rsHt#}VCb8dnE^?2lTjY1&z
zS<Pt!UoSJ7r7ojo4ayU2Nr(4xcXyXf_Tp9Zu=sF1GK9*rV)la&a at ZP5!d!e`m-98L
zr_HfqKz(5;>sT9W5$Y!cQJL$=4*=(hru^h`QYNv?qXKk_fF|Qm$k`dl$fznwGH(6(
zkCv~q*tR)M1&*`%+Q#?U(bwcV$qk+V>vcAqrFwt+n4 at yll~2v!)#DwqaBP`&^m-2Z
zI0+dlThY1Gr3&o(&-^xM+AdY-ek^?a7~)dGAmvRzWqj_`b4@(k?rE-#b6DoyypUVo
zRWhyK-z1*IrlH4Z+AIgs at fiQp)<j-u{gb&S1~N2_DC~?D)&1|YhGZ?*T4BTpAqH^E
z87osEqAbRyMr^@=NqV&fc4KPC;&3%pq2yKVL+tg at eY^R6E*0_Be=4 at Gy!d1PKfTR<
z8a8`5Tl1SX at JG<sNQ9{wN#1qZ3AJ6IL+$x`BYoMW8BjV}9k at 62Kn2BoO(aSx(9_6d
zt^e{L>33s~@~L`4){g0nZRJ%`mxcwG6LAd#gSPgo@&9~(-qPKV(u%9p9LxQ9$6zmA
z&p&rp5+B>E5uh13FT#d4PA=V)fOtKe|BAuFXTygb!Jg07GgD at Dipy=no0LT7z__>m
z-&lih3yW(QH#c`dGEctwix{~#bf20uPHlbo(W?nc^^wXx{GB9^;wHcP!Cil$=u-+d
zW$lhtnHuA%?kQ*$Ik{=f0e_OsoS|CFXqQr2YgqqvU~TX7-+UzHA<lC#h8pU1pO{wQ
zo|6u}yG#2`GS8`PZ2(>fa#zv4T|1?mv>oqi!MfDi)g{QQwvBzHUmI|9^pn7!%*{E8
zT{Ck3qhhEblQ|@YeLf$xF#K-pOG)fWn)#x!;^?q_Yo$d$+TueEWGc1!Y;|}VL7yJ>
zN?E(b)zkhkRJ_wzOBn*3VsgoLS#hZ!2NIQeeXQ*iEWms>^PlJ|;F&BS!2b~}84!g}
zu$RcxOTPyUgaMZnrLJZ@`~xlro)G$3=dpJGYWbW%>vF at U9d1={-^xn*>kXMYq5-_=
z?-Xy<;_JniuzP>s4#SV1Mij?cD`7T$D-<R>3o_;A3f<rERe(*(>Be9YAz~d?{a(h#
zv7nj1F!1A%Daf_6gp2&`Pp`Gii%OFvAK8=Ngmk1FV0lMm)E;qCVyGPtH&J=ps>kv=
zHXRwhRoUmj;kKjyKv9Y|3{EokTT;!sE5;d_+1ZJvKdzws>9n+cg*_zaW2+-I3%i7t
z)_%n)3|>ZYm;WM&hJ=66=4_9JLBo>LD&n>PIsGVS2u<o?&6*_DkB%X*C1x?3FkQoh
z*eVkZV*KzhGRU>MR=)UDRA?Lt^ge6yR- at Qbw*9 at z*!cnUHKmkY5v+-8Q;UomvyI8I
zAW-FUGyJWUJ!@(V*$X-8nZV?NmO2~-6il_m2&m;pFXRetA5OJrQC`~4;B at +?o9A#{
zc13C9otm(#>QDHMt7q at CQR$~Ss-(A$s4)UnznwKAL-?#MISgAnKOx`+V^v5K_?zg2
zK=Y?Z?#D;u)c$=|p2hF~tjoo>qIateTNhb-?ubu+vj&*cbemFV>$_L%<#&{BI^<un
z at a4<utd?C_zpP#WV4uqriX8zN-H@~gSvq!0H1twuPsO9Cbg#Qxlj(o<vj|odh#w8A
zS>X4ou%mp)8Wq;flg+zFZ_2wg46uF at 49^t>-Kc2lPuxLFO at 1lW7vFvo_%!}wL~7*w
zD-x`=lwJovt>j<8<;&RuO%?f5C4CqX1ppE=Lt^j&%Bgwr(1|$o_t_`cy?s8ZwO+3-
z%3d$ueSPF9bLwwpWdu9AeKsGgc1+g}@3v6DEtk%y)u7%F%lFXaG9{+j(NcLaRTKFi
zN5p_Th_|erspyFay>^v(rL?BRMB`vHnsbbHnPkCrUDeWL9L`gO4C&)iyBgYSdA%&U
z at VR2xfCJ=H-KIB<)Nz}7q}Z1dN`qJA<e&Trg4mj7jyka|E0{)_Zb4k{5sP`z3yTV7
zAFTflWzrjtvG+H7hzr%@M_r60bBe7CxMx#dAen*?vXtw^k6Lt7Hjj>~Z7tXTQ&0Re
zJ3r^|)a4!AkkWVw1gpB~&qh-9hbxKss{fFjR}W<P{@&;O(a(6Rt-i()`6ARa2$vM_
zZ+h|bNFE)z!3Q!*AN-CoH=Jo!;{rtqny`;^Z_aoMKRjPjCu3G*&ZV!E(Td#9P!x=k
zWnZuYdW(yT|5H+Y(#su*dP0o3Nk~eX{O7UU$dxIBMYPK*Wj$@R9Xc(B>_5?`CpC`l
z_M at YeutmT6y_webY9ksj&cTSA%roKeJWM9sY>13%DHK|deJOy(Ey<3-t-uCrBIL}r
z{>yDJlpZM2X@>O2{T|L{QMc%W93^xqy!+_^WGwD-<@IdXI6x&K%M}BkY5g!i;@=D7
zc)Rq&YcO^Dw71OU=FeK|ZR$Yo1&h4?zDcY6B3?m6)+SHoe9J#5Cv(_W&BR|4X{}v|
z>KcXGHAepB)@pl3Mw at jx%Zdm!icRHgS7M!zw&DNqh;gK<d};?1i+45)$yp~uYd^xU
zgL|@8SXrL_*YvHy+Wy~G<Y<NXf+wOs-~6SDSj%hulP~%D-UIt-2Q#BdY_F5)4dl%!
zlUi)jnAn|uLYqZTeK3D|?FJhbeKEg5#szf`*{FncjG=R#ZsrygoL9sy=@x9!j^5;n
zAp^pC%)0*q|DB0Gr+xGO*J?!9!S`R&J1#6CY9O>^piB3#+;N9+`nEI(gtcpoNJf3o
zwr(&jyZlaVH0_n9xYwsvQ|9Xr+}3$4(#;DuLVB27c<cN$IS^R{o+6_~%7fgq-+SVd
zRI(}TpK3*o=}q(N$wHsS2>PFq9)$6+geND`dfx?({fk6cM5SR(L8IA&_^B1u%+h&#
zDMuAe&Dgefwxna7i04wKDGy!=ceS>?^fd<#QlgVzPoI^f at m=NZ+mC#(ZXUoA;hUJ3
zZW~Y;Sn9Wc^cR@`N-OoZ-c&DGW&}0fjLvl0)baxu`LR#>o$UcP#jG|4;yFaVRuQ|@
z3$JQFus^Es^`^mlCaOA_&i*rASC{T at 5^_`7&Pvm`|Hz=UF+*Bb!QfMFZEMjy93xw8
z!NEeT1N=}L`6(dr&hQ{@P_Wc!_C^4dqG-Oh)Y70}uEO8(e${BOa4OvotR>5GFOL+?
zsTZuXudT9pPj)`iJ%wkBDJMFZGxvE^`Xq+FZHq>VR2 at axI~@h$NU{(4`M*2t)_j_J
z`qLo+3e0)vX|(;MY<IVebf@*$+aEb<=6CbIg>^jcvo0-U1e_T3ef(cm3OW_iiRe^l
z)9ZV3R>;>*Qk??u>-}goaCo(wJyFWn_gq#pCNg&^Eol6OO}<QQVptxv6L0S?5bNuw
zJ~;nK2i_(OB0Yv0=N9n36~N$(20v)Xx7E2jOg%_mz*Xn-OlTFORW9en_gbeecF8vW
z9FRq05OoOdoXk=F^-GZ<)&u`?wJ1HgIr~LH#?itAs`%jW_^ac at gk-B}idAYA<KyM@
z_3~^Zi$QQit{_%vSK~%avfILGw%BX#`GA4L=;>TzHHcO&g`qu{V6>1*y~BywZE-8q
z>9@}td*8w2qy>fr%;sTw8{gywpP4U4pSe5FTV!}>7C&?notE)s(4=#57K}uvC^nE(
z-I|vFoHHk({raJF*zn`p`hw>M-zVEpm>K&RGN5@!buzB at c1<;m>7jLbjl9ym{e9_B
ze*Y8hVVSOq+tO2Re@}D-=IFnP%}&V`&qYu`um9=1zxq~uygL&OHbZ~VODd{CQ&R!G
zmc0i{BC!^TTQn=1Zp9b2-m%`4iXZH0%6w_jka&q$;#};@Wm+uSk)Sv{@-Q?RdbFeK
zgLR)<ST}q(cX|=%|6qfMX7ACtlwC9;T6w!^CvmDj4e#{hwtrE>!eG%i5PmJNbQmM&
z7@)*&pl at YoR|&sWcVBnec}5@*>24_26a^ptMb_8Fn*WBcb at s_g^*9MoF6b>}E|pe^
zmEVUF=oq)pVTL}<(gB~yabZvAvDENlZwP<vQ#yHw>FmY%b-x?qzSn3)O^b7#-s^u3
zT4zlO&PC>4UNMVa37{e~ORgNg?34#v^bZhje5Gpp?0UMTkq_JRiXo=QJ!ZaHLo~Fs
zwEWkS<y7*1mIf~YIp#|7Pt<3!Sr^?o5a~zPFGLjM$^WMXK*1FsH;%ae=KlEWD!cJ_
z*1fXA8jq)6FLCs~4udov^I+Y-^wF at Rye(`udo>Q{Gb`R=IhW?U1?*~#<L;;6vrk#_
z?&ei$g$d03Mol;M*d4f+yzAo^KY#sbK}m at o3uwn${c;$Osp31cU_;!3Rf?Uik3~*6
zaV$#in5D1pF(}ES_8Dc$-v8>wq(_~sO@;1dgI-AH7>sNsIvKCnIwSO7$tu9RUyVrF
zlXKE~tdr at A!pE|qH$`0cO&@-lWMB*H#-s}MkF~TKYo1zh0xs#Z7<6R|B&e7DsYdkl
zWk#n(BUVJ<kf42Th-IMblF`P#){=t^Ebrjp;8DTdq|+|R^JCrcH{AE75L4f+&_?eD
z=11hxJh`Z+)QT>;*tEwQ(#(7LBWQNtE;>B~*G<<eHfrd1kBjTa=)hFSXU%2AX~+-^
zpUGgbOiUG?Q at tq@SEHO;5;9jdt8CKkJG6Nv2-^EmOCqd{fp7!jRpYAtfT-H#3BJr*
zS_0RB at gI#V_7p;2j+-$P?nRNdi!@|pZ~ru#<DfzMTQ-Aa0jZev-_1ZauTId`lneK)
zz-q$z{6*;TgiDSqj)x?9GN#_JFDSsKs5Jkpv*}EEtHI5??)?p4lh;C>IhH1p=ReGR
z`y?tWA}G|>$m_#*1jrasb%2JRY^~p-ZW^kWQ}yIdf2`pQ6MokLgM(71Q78E{&?rQ7
zIsF_Ce`dZLMRjEyv_N#DUhZtg*5*xGHMh1d+4w(Lz5t95wq7%ComZ`zzYw?3m9u9b
z13NAVa1`kU%)mp?qvc0g5-c_%p4#Ki!uxEw#i_O)>;+Fb-$bNe8fo>kTecj)p;RE0
zd6%p$z~%+D!ORC(UV7)4v!Ge%w|)7!xj2}DOZQ=k<p&HDHXJ|E_jI(ho=Uk)qUCqU
z#rbc2dR((=rg0x~+li`%&(^AjH;XsoKr at Gh;K2*0o~>6Yf|yOf2<BvC`(`yq1981y
z5&l!*Mj`jeI;JFy`*v4?r#A0Jx+yY|&p*OqoRDeam?$t4$LvnnH&0|}NLOd(U^Ci3
z>QlSWdE>{^j2{;d{o<G30c0Z!%1KA^*-38ahbk1==Wr+vn1Z+V>@uaGHJi3y^x<h|
z$4rqo{%(vmOkGBqC|VOAA73<@I@*LKI`$?Uhb;XZ6}w490K4^v(o~}WWJ#GiP{VJq
zai^Wwm)Ni)czb!0Q9o}=4P#GDTf<X!Li{B)r`Wayp<1b%{D2AD$lsT;q0kWv1((UI
z(DItTW-3LS{HU>KaY8CQ%Ek1lc9AS%QH8bae}b9`zSCrrILbbGUiO)4%6gz=#pYq8
zSgUGmhu40JhU&Blem`b0w?o&RO%N;Q;n=QK9x at 79&ipyrd|3p948L+?8Psp#JNo2W
z8T;C at 9~nQq2k0KvzYOz+EPK-?{@~T+Qnm3u2;*$Py3d2VHCnWHXBcpKxB5I3OZ_dD
zn%d)~Oo;Ed#+q7D>~8T*U{-L}9J|!089t1*;GH#!5@@#CkQ5d^K0|jljjbq5nGYfC
zN9FBeKggJm=tFN!&-y9ChtS&FgtDnG at V**DYiHBhXKcTpbtf^p;OCs84gFZ(4g#gv
z$L2Szrqg at cTQ_RLQ?L#t1j`jN8a83(KQdw#&Y)bk%UQnp)Mk`~i8qtMyw^R$Qdiy(
zRzX}L%uH{<aP!${(-6wKjVe;I&e|g=Bt<PG#>-~}*W*j^5`KuzT-U(i<XD3(^XTay
z8p<&GS;g^vy at WG`B2w)DACdXhjDzRx)u&`Dgp9pj7Q;GRZa2e3ecDr5$7~vzIOu<*
zYlJu$1)&y?YKXE`8H~-{=uDxc7zZX%mfsW)I6aG3<9<tC;;?OcxO~fMo|qu57>CA;
zP2({dPB59W6a9(<iWHPlSrHvZLc-am)n&bIsM-t#7k;xiL|6W^xTpivbZs846Yh~B
zQEX5>LCa9d at wYZ$v8~a20omVhJ|!*sR!g(^-(ERt;4hAcK0gN-cX_!`fC#soHx~e8
zC3mz_8fEh(4e7UEQ5KCVtEp8!ADZTSYzEK`NuebUNu9mjgv`|r`ZnE0YhxJ8xDTQ3
zJVX~Lp at 2Z31n-i}K#NnnS0R47;J16eM_ZG;f_~I|JpgWa0h_Cv1Cz_y+Izl-cFGPI
zemEEDyDwtcYSulU7!u;+ZGC+^Wy_r*L&lhu_Z{RbDn!xY4yws6wcr_bZ6XI*+}|=>
zm#Fn5iZb|5Q)(<Jt7~hgLyGiCbG at _Fl;#GMZxn1ObQE2JM1G^KZ9pm>c=$1#fxt4<
z4~<q$p`t9YlMd^mmh_xbnMP6C>81lR7L4z1KJn^*`s>IRpBN>q+1T-hV4aH_ at R2L5
zPZq=&=2y5D-Pzfhhp_139P8)pA;n7iCdg`l at L@<|*#6)LX74c${1o9<B<ramG|rdE
znY>=vt!@yJVKRgf+Mmob@?;Q at 6&`iYVy7`I%#Bu~t-qQS2nZdOf8)KM9u<}XPZ8x?
z;jOoCNfDrux!)xBJuHXhU%DEu;sgt|sae?ncr}vhTbFfAB)A0R``^JfMNByu6zxQ9
zM>w+ at yg^7GBDm-TC*k6?k4jELR}ictYwv`0N66Ifn5Cz)V9;Zg6r10r;5ahLJmUEl
z;<zg85jtPxh>3~i;m7;`J%oEh6h};4jB3q%IXE~bP66MTB#Q}^zh~Ds|BUa%h&7&j
zWiNW-%Nn3G`~fx}W3Rw&Ni>>2<yKa#^|iUXyPNa9ugOJTY#cESB;vhJa+UC+`|I^b
zYf*0|4)<%NCTe63sOy)HNh^3LWIFsWnPCTigS7YrFJRt+U0O_1L(PZFP^-o%u|39?
zJ#L~BfF%Fou2tW0kg)YGSXo=xnVz{5z-M4KcJWTP_C5eEm&{>?j&9KSn9gy^NyLI(
z@;3zg1Pvab={?)^Ing at l9R;eb&B#9H3TDJqq at g{jiZf#pk&iePJN_f>MTO33nlFE;
ztH1w~ULA~Sl6=kxtvsD)ww!b&b|S`J+s-J-w879sq at c6lt4_ybLm|TaC-qU55DWYP
z&Y8$^SYk_Yw2|JT`+_R!AnjY6Qd at of?5qulId1ZGNSVuQME+%K^qOZ02i}LuGU&Bp
z;59@<;vI_5lR)eef;e8ol|X&K_pf&*#I}}1w#wKWIK2lydmDk>`O|VJ2AuX0&gHWw
zvCz-?kjbF13DCk=I#L#F$i&J>$&8Rl4_w>Y`X)2rfTbR*kR*D)a%Q$NIes?^2;3P6
zk53E%yg(@Dln~P~vm<XeHxpcf)*azJAe|)UUOIhCd9x--Xum1j-C*}?-Oxps?-|~9
z%d~)rZn$^y$7zn3yrH}Ih4b<PauR!1tdv>&Jf5Y_7L0Q0ro#r1h!$q$fJQOFi3qix
zYaQms^fpw5koSC2AS1QXVj5Mku^Haps43eGM!@%=&rW=lp~p3$sOnUr`lU;#Fw)FV
z3{SfT1JhY-dzORBs@!}lqWC2$7GFAEQ!@Zm8%*QD9*fu`aJYVwY0{toA0F>UwF*&j
zb6?h3#AHd6y9|VHxiv9ZgwK&9G%ZiPY~pCD+c16YSpjxE+dd%6df9k5BmB~8v+mtz
z&21AkS2bZ4ZXXry(%)GeX70SiuE*+BTk=SQZR!0+P)a={k$y-26HAI@!AZjNae|w7
zTd{O(U;cjcYCg at OSm|~=SYZ<q<y7 at vekrJV)mL~}3A9C1x2g~%L2xHLEWJy1J{w=l
zxn*Bd)=n53s=O5;Y&Z;!$T{Sz6B5Co&t!?WNH|=bbZfSGd$e-2+#3BdN*Q|D?AHL!
zQcr~j3U<Xjl)VMS#{ooGMbY4g2Ei75t?T1Oq+@*5L7C`py@}Sf;o*js at wIyfvJ;=V
zCfe2_HsAjglQiG_K_NQ5o=O0bQWvMzeSoW5-1!M|Z_n_+;+ at VCQWYTr^L);Nf@(Er
z+<A>}Cx#9ZTC~TgW8Hp;zTrkOChuI8x#MG~ME~ZR7U<^Y=3R}J%F+ca`t>D}?`(>%
zy9PQxX3aKm at 8d;p)YxbudldW9Lufo at GKJR+w1^_4KS=@}!Z7?=Tp=oYmMf(k_Z~7b
z7SgG&e7s9dLO_bo(QzphG2)H-GE`ZJ<6f%km?hWckIuryA*4&$F*VKJ3n=ac)!3ym
zW!PTz65RY;RSMLj`K$^DclD(ht$pwkr(JU9J$ajrT##qs*1W9PZ+ew at cmOV;H#m1+
zeM*{Q3-Fw-XdO45Y8Kp|rR9a`(GerJ|J_sAug6VA_Xsdk-;ZVi`n)+38l0T-&qp*S
z(|lC5I%n+mUp!E5u;9$KEg#qO69`Ip+1J02D_D-LAG_;A5I`|yA=Id!sRe99>Urf}
zuQ(E+?PnO{did=F0R>qVqKBbCSydcm{rb4O at V1hY!&4F9jnJz{bpiWu>2-$$Y6vTR
zG at mDvCS#4 at 2GgY6q*TK$mrJkBD+Rt;ao&w^z;VX&)xpF>bjH;L8*i+dk?5Y4V#!w*
zXK*5Wu=0+P0D*;I4i}v;K|&2G!D~M@?&Qj6$A7#ZIp1hQvh2l8Nndfhj at Wd#YWU88
zbH4-CtU$cEXa at FuIOw;w)$Xn86pFpai|w~EX67bD1DqD70qT{26!Mu0(H5oEH_5(7
z|J3#JODMc0%eS0H%_{<!k`luS^)^>m4IrZn4QY;XQ%CRvQ0H!<a%!bWdEj)HMZT9k
z-%FOHAK8P;2I*_?kp(7 at rtyh6DsTI=vQ^;!&N6Rttf-Z9X$MYJhU($76yyam;gJVV
zzhN%)xXC;>F91x-C at ej^@ofWtiC8B5_ZjL|WO3KFP;Q@;XpA|-r9T=jxLqS_U`P0%
zU$p!{`jP`X{OdP|Gqu?MBQ2DyAvO}1jWqh at qs^+0-}N4>lfHG};5T9$<?v;ZV23}m
zr0pT+p&p7O>9FIwUgK?6#J))v#La1?d3z-(isfM7(K)Atm63T;VZ+qf2+DueRW}o2
zgZX}c^;^_(I%s?e;-A at iC^wGXP%xRv{oStb-|^3j#N+t=gwps9)|_de-9oiiWp at A9
zLLY~@WHC|UTx5$(Ygb)LD`<>Uvq6*KSIDwg){s8-*wZ at 1+p*iXtRJ~SzF;p#6^JbG
z7IIJAJF3orI_J~G(8Fbs^5V5L2RoLWwI2Ktu2~?fv73dGwt-b4t=I^*eSN40;A0Zf
zvAt27c`WQ+))75N7F9W3y}+=*(a_hv`=^NV)v^`Y9Ck}RRGm at 8i9`@|^`#>l#L}*R
zqLJD*_uo!APJp|AmInS|qW=(`;~G!z-M>>CPrLC6*n;my_3DZ#ELSwKx**}?c4
zYVxs9$xoJH$qz`j{w`v*e}gb at e^f6(MDw*ynul&5&1<)?m8IxEK^iMoFL+;kW?_M&
zN`wNFiH7?s4Pc1FQN5dm3r?aWfon$>i!a^+c#uyBjd?}nO!lR>AQcrA#H+!`mt{1H
zqWM)jQ(;8D2m&=9=BtRv at wQB=(th}0Ibh8o^kO~wEy8_Z(oN`=oq00vhozC~+0kL-
z-s5);SoI=Xa7sJjNuT2v&*THI*Y}+L!es3&EuPTt8|E+7bfkDxMSS@}(3^C;aW+%+
zq%^Er>AX#0GUSRj_zBo{?Vowt)sAhMqwyE at gJ=j-_C at r73}#6x(PqhAOigejhqjXz
z0dQ5L1qX=1&StmpyJfymS1u<S)9XVk?}n=)(U&C#Y19<5kmFz8_H&96761o_YCzN&
z*j`vV`RPynU^6^R;MHE2kW`LY$!iXH1X;H{qE)R_h>-Zn%TX|uFSYT%j^^*4IE})~
znFZ${+nTT?b4k0s15Sm8gnEsvGU+;)+ at K`CcF*KjXGILG1~ERw%G;j0Z)->#o#5ZQ
zvx at l6uze#5lo7v7Vwlq at U>vhU?>f_pcqZQBsd-~=95&LFbcZF1x}@Hp;M=IkV8TI7
z#%*%ub;cwmRxM(miF~t;^#`Z-f!gLVcZU^9x&Fz6`Liz6zYBKCBcfdx0R+?mV*b~-
zYmJfk(;qrD56LJNfk|BO#>swVZy*s@$JfJju@<;D{>YTPHN=q`qQ*bQdC#zS()Ny}
zhCwA=$@3tOY%&j>6#f0W-bWK{md48}HNg<UI!{>UT`;`p(%<w?EP$zvCQgBdn}moB
zaN8&CD)sDdQ0A!Hpk$!b&s~w$X-_ at mtzpH&0XSM@=MLdeOt(VQIePz+n{xUD$!_yF
zGY|!1_9pvP%Mo$~Yr*)7dCi at ByK-aHbWZeK^Ge+2Ec5sBe27eRal>7%WTp+4X|Yx)
z64OM=0{l3q2WZ8hs;$v(n}>(iW3HgeuKSL)18 at 0-kRMU|J-R^H|8`6^^y1%EkAEle
zkWYf=<Di*%Z+kA{x~MKYI at z0kNa)a2__bNWphmdqQh!&d4T5cO8JFRzyI$k$&mWJr
z at 9AR>mqtQ at g6R*`0XAs6>jeN5UD(sZ*;@IO&GQ#9D at s>%J at 1>1Jx6Ym&OugjHZv#M
z9MXR)8$X|(p71q>06^~pQnP$H$gb-1^NRgqFpO#}HQZ!^yYr>#u#nqy7F?O5j?abT
z at F**Zo*%M4Y+<qntgT3ou@?smK#?&tIb`uqU&a#Jfe+a5Y|*h;yyCuMeUL=SueNuR
zd+~8*0v3<>dR(L*Tl at 5z7pO+XX{u80nIlpox2r_HiYPTGl_nB2%>>i6jUg|wHjO*k
z6Vu;vr3V-Jgbbu?z&~tSNA<i?Y>*LiY)4hYcfs;2&(is7v|_q#xV7VBnGNfQ%g*`U
z!)_YX2PLW*qRu?0g`Ea_Ep1|gh@@b{VW)YA at tDv8L)Q$yT0wKm&8AU%^{{mx^lzu~
z0+#(xoLWSA at o~)4c;S10mEz|o|2FkW{%_0J)8JE2?KUG<#h0S6F+F=b-?we at 0SY(W
z0&=m|sSL&J91*S(C+#v)qKhDeW4>rF(ipK442l!LIq#@Arv7fKSqpWsJ7D-ZF|m(*
zcj1k at 8wLQBZh!y&-QYag-RMLqI(^6IiN)-l(1IB^oJ>vSLl6;o#>jseyz%GHKfs#^
z at 1J9I=Jp#0b&NRxv}9fo&0PRdM;NEU>x|{~I?=;sO$tZCHZ4UI73f&k53PN)1($m8
z++jY|mrN1#E#w at Uxyn%Udl|9!h%RwWuFS~XapH*brt2yPTe+L%mnE03qx+PQ%o)Ca
zI_v_{UZA4n3Obz+Z%vy;wJSY-%MA-F>@oSDt65<_V9^lL8=5D;)#v(x{>rP)7o|F}
zU<+WRj=@^^gq11-644Ca1tW@?BR2keIG;J{Pzt&{nQW&V^>>-SMm-u`zG586bA?!n
z=Dn|<P at ikCoSryPA$PD54PN=X|Da_eVpv>Gx;I6=Y;HHoAKwFVGKGqOL^cE^l>zy9
z1Bvo`cAu^RM%{#YrKZPJOTC(%zMVi(;or!Tj2mLg^Yc&jpN=m7dnoDKSW)NChs}!@
z<w(V+KRY-s8kZ+yo;S$y4lkJHnPFL|;e{m^*)1pUSv;Qf&)fEtm?Zp7ynpIgnt$U6
zA4)J2I!#&q1HrNYJ(}nU09H&=wG5Z<v9kE<m?U-1pl=i;JMpigU+w*oSiNv1`z}#S
zEtCV0eFW(Ba=kIAe~b4*OVDUY{kVHLb}k@<e6T>seX`)T8<?~fV~?0&@Vu6s&OH(u
zrI=IXPHEat<JDbXr;p~xb-oY$9`X5W-fwQ9KS8a`y=R#D-0aeC$@U8;$MMF#Dq($I
z;Q0O7+RYFpVeEGh*>KX3GNt)`5O?<%BZ^i&j9a at snO02x#wHB$tOgNICbRT!7_^p+
z8bl-&&+6LS|MVC$k)DxkUBcT=TxMtT$%w)N-+{w9&eUitd)|MIGa-1~pY{PpDNv0N
zI~yBW2>q#BHB^5BC;3gBLh<UxhJ=;p!Q?pkmqLK at HC)VGS%Vm_y29$@_oB?Uw`@_W
z=$UqTZWn9+FQ)N(KNF6WG_4(eesbL3B^lo;YP;?ZR`m>Pck0e(kTqH^az|IhAHsc}
z!P5(~vzo^K7q(ne<kkxnCTQVjsM;Xoeb=JB!ZE@!&R;}7iFq0 at eX9jevWw~&KDK<W
zTZ-P;-N8Ddb)b6Ti-MA1J}vLhPE3Q~ni4CtBxv}YiW71M7>eJ-<g%Dqg*5CXKhooH
zl#u0itDT|FQ&J(U$;dX4qzq at 5^-y_4D*Bxbv&-S=4E>8&N6Ry|y(dx@&-Dix8!ikj
z0=QEf6#}T}238*JlarHE;*Ei?-SX`w;?-o}8%YcZH^1aWS*jANbu|b}lG33RovM{^
zzr`WAPoKplOS+Il^DBgiL^cd-`KqX)XvZ at rtyM`NmyN}Y<~=F_?{|PmmfQF3%@p8n
zOsHY&yP}ILN>ytv7Y-h0r!FWyVzRY<g_OHPjHM>swDh2A9ahD1$}hP1GZJ&x?$%9F
zaibwMU1uM at DL_=*f%LG9jEtl?sI4OP))cIQ4TR%N*b?G6{D#l_w5%F)%)Z>SxgwvN
z6}M}JwtN0-T^nz|znp4|bC4Gr896s5#XRE&ypBRL9%6>W9^y0KjqE|K*V?#|gFesq
zN2hoi;`(bD+`2c;jmUCNE0B{E+~M*>b+ZniUU*9&HHS?<HGb2{=k#o at g3B7aJc_29
zu at Z@th0UL!k)!1CeB;RRDR505?wFGNXk?{HK|~`e_(pi1FxNEO0{g at UA{8OW8aZ-t
zDIjUYN!r}mxhCDW9DqU_^@lTelsrwk%knFqs7x$Z6fuPC{j$rs!d{{tlEcJL=Zkc`
zPv%!=l4;T7Q51Gi4NBLi%x3J^F;uUjhNdXBliPepfxH;{Wka_kEHEioeW;pztX^W~
z1ob|Ajom<8 at J4iWd2Zd6RmJ9M$Gg8R)SZu$z&blcj*KpznIFv|7kV~IP1YGJrlp=A
zd5<9&X3pRY#>-R_%`}J*^7vIYZ&O`W#Tn|&EvhDn5gwE#-OQKK+~@rQ-}+?qVyj08
zV`VPhQOckr>0fEM6-Y<Jid33aNbpmG`K#z4j#r0dNnhb>O!^ir5!@w`Jt=Z2)m15*
zA?fu|?S}Fh=AwCv$jEdtsu$E*OpWb-pc5IkJlmWibGQPNP2z&;VP3q|($g~i!un~@
zJ8kZZ!@5k6mG?oaqec9rRU;BJ8tNc$L4{nO(s<I)B%G?e_-GSOO?^&(^?faEv_a;`
z?oh@<7RvsEbilV1dfs<Qf1za0S5OlvW7M2K8yy~%TBd4%;S}Masv~y^y~-Vxw!ddG
zC4ac>HKgn3e0P!0A8!aIJ)A9bPj6|RWF1*G-~Vj(qNSx8Y^3gOGd)BpB&Hd>YEu{y
z6yrnMn?}tlm#!T4H$af1gFa{-YvEV#{<ZY<^u$sa_zL6+!ypQk%I(`-1th#EOF7sz
z;rT{YOz#orV$v-XY;H~HG;WLlUMAL2reP*Zao<Bf9}R<>g*@TIw4~3D<e5{+=eb|?
z=d(lME%poui9>z>mrKL0ebT++21=u at 3JYUX-`oXTqiw4?c8mTy+}BsA^{C~RYwH0_
zm4{CH7F97;kzPd1y~p~RJn_l$QJ5A7*q9Gfzp+PxH8dxsC0C9N|H!sh_iIwJ-rLU2
zN3_%{UF5Fw+AzzgTbMZ5$4a!Ud{tLq?c-V*-#2*)o{)z=((ZkQcL^n4M>8air}tEP
zF^Q_9{NdkA_eVwmTwHe>8oUl5G**|L&fU(|Jp_%DYaL#@i&hUmUiZmhgi6Pa>`BU;
zB|P5=hQfQN0ODD{oO#4k_T)98(J`S8m|vAML47CjxR=<84rJHMkhz&T!tb1DtdYy(
zr6;n;^2(b!dX+~p(yqRNYzY7u;Izt4{lu7Jgo!9msS??4o2hoyePIv+Pz2fgo$DMm
znRDf_K_Xy3^%y3jW5bKO2&kHq6v_@?tcCIrGe82U*?M!~Bf}~atgK%~;qlA!srb8Z
zVH*~{AYsm;;VxBqAyyU}xpSHK_1_6txATRtx!}usV at UF{sWBxI?_q^yRsOyc=_J&S
zyZEOkn_Lq`#m$;roHjF5P_~yo+|XmNG}aT?j7yDbMXMaJN#yHkcyp8mbzGtFN#}DJ
zLGj_s$py*_!9RMvp6^}=bKhh76F&}4tLeoKv>hYpsD{dzp4d5I`ECA at Kg3u5aoM~{
zKSwyfY;IDMVo>?mB18y&c_$Bq>HB0amM!e&zJN1!EZBO>m{_omA~QPd9R+h}23b<}
znP+FBKdUNk$PH?TUN+yiQ?7|2?=4vWhE}L+S at u5OpXRRg=VR2zM)KT$&8+;zjfO$a
zx8eSCl2$fnYKkmr&D73TjJxo at Agt?2x01}vktr^U^})eGfDzh$QZNw6xF_L*q$uAl
zZHTwY`#<xC_)lp;nQEL5)=gZ`x+5k<UYiG&WscGkoW-Nf{(NOFG}uUkx*VE#H+U4S
zA at 2EJ-O<s}QylFNx}u-l8Rj+gypUu==`%lK&&QzUEtB_2|6mv6Pu3nKSyhOE*BN=V
zMHD?ic3q`tFfd0db#8uHBhlLQ&yKf at J<vMS45W at yeGNGmi57scqy+k6<-ePR%65Ch
ztyno)pt)nN;!Les$E(8p;n%4Z7D#hNTn8-q#WUOJZ$^WgMlL)N{0n4NHGLLM;*HoQ
zeU(I!V;1g3d-93)%V`hSIG2nozax_NU*}Ru4qKpfpi3?uZ6G{+XUNr^V%EjD2M-Ue
z6i?SAKd8Gys~Z#~sKU}Xsu~^h+$+bH-z3`!%}&^IQ#-qy;hx6F5-SnC<aT`&gbzex
z{ryXtwTy&9Qvg}Yd)$H}ePpM at g)W$D;e%R_6<#|{t|L2rhK>8Q`hQvgp*}Yuqu@#C
zdd2*k*qdm%!0YIf73Fmdpi$Kz(SQP#y^|9i$G*W==tF9WX=4LShPxN at C`n>+SRu#2
z(3t%-SM^=wbXh{4g#BFR%pwJK#2q1&_#^R5Hh))Vr(w#N#hB&F^764)FL{e1 at 8V@9
zI4z=w!UuALgtqujgAs8j03aPDLN4alSv%LUc!AK5L|=~vo`PvR5a>3us{#DGkOjAs
zUuso3yOU at g<a3s&^cu=9*w-JG(++}c3{6IqX5FeohMG{Q0tUHm-GFh-E$&6BF7-zw
zT>`R at hEdodRusuw3(mYx#DygD?r1M!(VNtAL%lJu_h=oLg_U&^h{4wQv7z^!p!4@@
zN?oIQzptLi^03h#$A!+~!5kPm@{NhX%1b9kIbrU6s+B&=r$Z!QBc=7phUqxgoV0$g
zSv(0qQd3s?xdhqRn=d at H>82|)4ZlQgx7?hd;lF- at CN?XmnJ8^uWpR0{-tnFr%*DFX
zG|XAz+L(jyy9}QltFIX0TeM<>cm at s!*U|N at MBv1uCYM=QThn1&I3YRJpoHd}ONi3~
z!8S$&M{Z0Z{Q2MMf6Z at W$~$}v;6t}%!COK%-sJ8S(|ksTm(1aM=KxRB=@9CE;fGA-
zcrNH}H$Bbz%AWC=8t)G|hdS15?LVe#4|=ejG2(i&Qh!)bd=}lGyW##ea9l)Wr=HFG
zcfC#wY=~ps&_76P9(2^(DcV()FwW^*6PEY+j8}a(Z8_+ateSLO+;7Z at hA_Nfhl)Vf
znX7T8<#vc+OV0iZ0K)%+F#9<&TG$2UQ!BfC(|S1|ziB%=0GR{5{qXJ$&~2!~ifahj
zA3*%9aGg{@e{*9GZ8DvQgK{bpMUP2Q>$(_lqC|LV{MP=^R68T7u4&7*mdU$E#<iCV
z+#J0QCpNkQ<gH8(R7a!TD>%$?!I^4Y0ff;iS8};n_nTf6&>e>8Mt2WNbtIKEVJY`X
zUuR?CNJ)_!p<$@_fFNsN#{>WhC^+(&B^N1g$W2P|JH=>O221Qq%siO9#WAUD`N-5t
z-->`NCzuo_zFe(yJ$wq8kVzr`oZJ+)fPDG}!}hnhZg-sZ8s|~^^|f!j)dH`Lvl~4E
z!Na at I-p>Cj%-Eh!%qtuQM(T?ODJ}XFE393RM$DY)<07J$<vT~u&rM|)lIce@|Abv!
zEb~Hg8Ke;pbvu@>K{U`t%#OW*?iHs=8I4T{HK!pnC-PZ*r5La)v5p{SGE>)HW<4<_
zjBWM1T2HEXtq3oK61zY~9_f45#Px*xS~BXwLuQ3-?k1%lXRrF-3cA at x*$YLoQE|ai
z?`7i|)Tpf4URp5%-Y%Y*6WK8bzPq0%4R$sfcXIpl2$~@D%dOV)wOuy*g|r`9-0eb@
zVHLHASGO?Qu=-dn-oGU}yX|8TK!>}CtZTYPYq}Z}$wd#LGkVfs^i20OB0n`x4yX22
zSEQ_;S#s&(9muze9a+9?&JqbVLFb~?$ZI4#e$A(4)c2|VGJk0!d>}V+w{EXW<)iQc
zOqPV~i#^$O+bH+y-<E%9$%G at H_3sQ?UGld1xYtYN^Rwh8s<k*4nqU$%Nk{N|Bt8uX
zdqY5V!9RqE^F&#_yFfaoW}z=zfJkpOHn#TmGgrh*;D4AqcM!C|_pH;};FF5uhmSC(
zK}cpFX=P1ZP2eLRs%ZW#hxGTi$OF~cf2}h1Q=2BgpJ4T+bK`;e<Mz|Qo%4ien at y)#
zqh%?6y<}Twz-&5;9Ey7+1wfWd(dy4PE^z?BTc2GvA_f#I?Fn)_b5&8`+S(e8SNqOh
zIr&mZO&05J4YFIvCw?h%o<U3lS{44nG(j8e?CxK!-hfLXP!u*8ZZbl!`eMlmMsk_7
z$HmI`aUzH_IqH&@XpNEqKp;K%DhmRe(%T>3le!KGFTfHy9`D3l2z>#G7<1Z_H5GIR
z;ns?>!J*LP3 at 8bviF&WKnoeMVlT$4`NZG=G1ba2m;+M1adX4+TYz5uP#njDrHR;ce
zv{-XsM53}5lP(~)J|#`8+zrCad`)inkfc|Zhd|Ex7VR%qO1N_xPlko50T=iao{*3z
z9ZXF1Vmd7x7mMB)b0j+^oY;P3io1h@(i3<n->eiyHg?9+ at A8tsK9KSHCTkvx!OKK1
zpU at APXz_zn_;%`s`v9ZZQiJH2Y~#*+;!8)eyDdsF<@H9^f2Udc4DR%MC}+6tmw=TR
z4Ym at E`c#;Y$_XliIl*+009gG at OHk0FwoW4^tvA=YEk|xC7=Zj`@tER%`eNZl(hKlV
z-(|(D8<L8}e97xuj5l1pIVMq;P~S={Muh2Xd}fw@*{t`%80Q?IU`hUU=cq%DMM)_}
zf=>3+uC(9Pnbf}5#G}Iy*1CjS?8h at 3{5Z>QV<u3DTCURL9(hoR at TIEEv>#UlwWyVl
zVuT$Mi%y{QfVZJ8=2C+&+-l64tW><p%$G;|Tba5#du}`ZSCbbAZz)1irK`X)e%XU9
zh1lpL)=DRvU{)J8%VXRW<!Fhzst8>QoY9~e6Q;sOoDM?^v{T2dB-{(9DK(os*Z7R!
za7dU3Y|<PhHjX(WPV+<0qJv$pHOrL#Ur`QHoiMi|(<$)U9A{DV<v#P31;}nGhP4N@
z3PvQ=H^_^wp?m`5cJ&!%XP<(aquR~=s!6u2PaX_#J7wSXr!kXagBU)Y!NJx^(W#~C
zPrg0Vn<@xeQ@=@$P>_}GHtBgRFq-idPF$sgy1Te%Xn!F-EVrTW_zjx8Kk(RTaVM at i
zuqBWL)emtLVP^G)gBWGMFh(x2J9*%T|5evHrOR$juqK6I_z&`QN&bjUD#?QZhisFA
zef8<59H<jk;w^>lNJ^>$EytrZ=vAyZ{WF70{fEesN}A7m@<6+UrUIqaAckdi>V{0^
zy8Q9th#ub!9tZk8s=<jBfU>q<e!Dq7?-F3%PIjJ9m*?N;j9&uYl3ju{MCwte;yzjK
zvdW=lY}se?$LAEwUhgv8>f76t{q~d$T8YxeAPd{?ZOL>FutnYi3Xrz-WtP|3m~B+z
zhW>_(%3bnWWYa&dyFQD#tVN<;{Fxvu3X_GoMg-$XGoSuOQA2E=p{ck)%4~dmylC~O
zR!qp=<(0fu)m&&KbS}ohgy;75RxFL-PFl?b^Yo-%wt2)D0}ih88o2R2%Ze?pI*2C_
zR;iGx8L?mlJgeJ|=IoE&tQJQ&CL3l2Xu`XA^X=&)IO8FE2N-?gbw$cD^Hr<;1IM;8
z-vQ~mh#M-yGx_+_9q}37lp8KF8>Np#a>O-#Pkdzr`1tA>QbXID|NaKS_W^vgOBVqj
z=aGWB?9H`Cuh at uUbw+8ARe9!f03w8cWlNq}_Vh%&j$1D+wpsk?WA4w)&<R?YUCG{n
ziKU)l5o4A5Fr_MFSlSHZ)E&;{Y2oo1Oi at x~=t-ic`mrw3*G*{LT%ID9YEfZb-hSjc
zdxjt34BAvv-F}#)QyEkt9&fCCdB%;?Y=f|IOcN6%t!M1NStg?L*|a2rWKLT(suL-;
zjxN%~(k!X0Pu{%zwD&wuI3Jyyqy&|Jn9<`LV|-Ja9+g>;%1FGATYh|Kx0gkI3e}5P
z;s%po%<0XJ6LqOYq2C1)RkiPKzdS0+8@;$%ISn)2Vy8Z79$-8m+c3g3uvSjzXJe;(
z*PBN)aPq>b+8Lx>^*8M*j0qj7y~GaO?UkU|AaN$j=nqg4>iBDR>thOfl-OYB&TcX(
zuWPg0Rw08AjFXg;IIgI`B)(ZZr?cy^H;63Xf)mNVkn+Ov<fmxGO~H5){BJlrjTett
zquniIeT90*qT at Ksm`2xCJ$E^~kJ<CX at o|++L!HTfCHBtm^SfoUAC>Wbr^Hvh>6d!6
z?!IVGSg3va9r!g8d~dgUAk1IySwQ_S?!5H*pSsmZ at l+r(BCM>KCEZT}LfB^-+fnC_
zW}GHqCCDCv-;UEgHfYMtgO(MNL$gBs!HoB<p<UfGD#6iKS3(JHO*<j}VG7;;7Lcw*
zH}+mWKEWR2mBGjcU9xyGnG~7t3m*bOZH|<_>gs9$vRCh4ksPR}+q0pQ*ySMO5B`=V
zXcqiEHKAozj5j_>3D#CsRplPDte$vDcjc7S$5+Nh`uXP70b at 14!6n|@V(ppot>0h2
zKM_5hQB${6!v}J#orz2;@j383KG1kfQ>nCjGDXO*u=XEU8Q;=V=>@ykd5cI<oews%
zN;r;A=4BKi-1%#PUz^WtFP=EjMqY`6LGnX-11bCHh8I=#8={&nA0o*%@_2fWovmHZ
z3}DykrH3Ys9Q_uqJWd-PveRC(^8#bYzoDV8nyVhvJftO)X`8%bs>2+r2=M=VowOsb
zF-)ZEt0vfJ9VSG0`qP(TRJ{-~K&~md<*FvQKa<9Jh{uii`}glv0O!5UiX%w6dNqkj
z6=W~0fszN_FUOAQiPrNLrv7#GZMixSA@#4dxw~C|aJKu^?7<}X=J~d#l{WB+s^Ym6
zqpsHF{VXd65LIx2RbcCHZjZ;Q4y#qYS`8QF@)5BK?2bi*@6DtA*0y=+*J=B=rWA&l
znKr1Vpxb>}N`ph+J;|<w`e|~?UOmqAkvaW~w?Qn3VgTS2A6}+KyZYOhc5Qvo0r2tl
zI`+?k5*tjGJ>o!@bC{<KmwTnrwWnW-$-B+H4NX2Et2a{wEGJo-`XleJxiy=gSqezY
zx5m*w`0^tq9|yNL^nUiqyN--pjjeZ{u&6UCKj%g1b^K*&B7mm?Gi0#iEjQ|Uuc6b8
zDNx}gUfMXY8aZx-73&Ulu#kS%1P}SdadNYvKfA|b+=3ep7r&TnB6*#CH{bThV@@e0
zq4Mz82M;M6JHDW$or{Y)mXtBxlM(l)Pt-s7b=gs(uz4s9iF~R1D%%2u1)lwZJ1Yh^
zGNwo&-9<hberY>Mdn{Seyttm4N|xw}F`H at _V|$T at hSZ>7r1Ee38t)4DhamzXsZy-N
zaqqpkYLV`3Rw9LCQHN!q9LXNmo#hI at 21C0_s4Rt9bBfz72X`*6!x*-hp!PiEzpRC;
zswY)%08-cP5*IT7k6W1Z(^!FjN5D~NuVF8OAh20SsP!Cl0rR(+NC;+6=(LS&)L$^y
z9NgJ{7BNi)XHVi++G=ueklBh#R1H5(jfSVCi5hU)dj6B3iHrC^tI at GB@?gA3iJQLF
zT(ysf at j+j|eMy2k&X$LKvHyBI?VK{M5+l at r(<eAgl0wY*wpEXFN&p(`D=aLmr{j?_
zF(#P?yV(TJ*@b(ojRuEdm5>L0)ty`jJCgRZuzZjCL;t?zdnu|oA;)Gh4Nvx<d9>Ls
z-IN%;NBtZ%*&wW;aHPAj%w;pobFel_!{BHhXIQz&yZpkGi at _e`9h3Cf{dIDAZ_>qP
zjMcCTGM#r0v_C6`EO#h52qf&8bAUvWkV|gcJ;rd@>+ocDpas`9iSyjP8*SLk;!otH
zAXPjYZM^PkD5^b*+Y*6nbn&ZSse$xa_;a_-v`FgkJ2*})BC<rTiZ1HPUo5j8UR*er
zvyb$a at TD`zJO^OJ#RL<xwKl0m6a!=n9X!}U+UZ<26gc{`XagU(KFa#hUwJoB7TcW2
zv*Z|Nuymnz7H?$B$xK)k>zSwF5s}nv$bC$H>1OK6*SQKHvQQn&M_Z~knJ};lSqnib
zhg(}(bdY0=6X9SoiMTJsq9eESIxNd&)ws|kb>s1X&bO%%+3LRy5 at komHkbrovQl>a
zq&380)5~6E8q>MbV2ul#trG?$aGm>Am|A_fBfzknc(v=SM_})?uz*QdCC_EcYf#?n
zhiLS$yY-=o=U$`>JR7{(&FIx`Tro5DH?7PMIQO-E7+-jpcGu(fJ2?0|swnm4!B at yu
zfO-*-Ag(tp{-hSCqkDRA>U*O|_w2mU_Uwv>8S1nD{m<Y2vaN4I1iHV!{rmRM?&&(=
zS+TkP$&^Md;rIWe=`F*e?7shP5fqT_?g3PK=tdf8m2QUa?vU;d=|;M{LApVS0fz4G
zuIIYH|L1oczV+2L?7j9{=jU9$596!lryfQfE7vQx^JYAiio%bg-bXRMT`xV8uis|f
zz6Go|zdRQS>G<9hWfw18DG1)2C3);1W|s^f6cVe>s#UF)tUj&@mu27QQj`imY!w}j
zvIyu2UtitMAFe)3JdEvTSH<{T^>XsJYn?uwG|lRtfB5~lR1$n!aQAYjK&xoF%<9OO
z>4N<x7Op%y+LpAsHX4V*y+Sw)QB*{F`h(FIy3b*#)fY)o2*<9HBKxk3+6t%B=nqfN
zxUgoSc%FFV55XeEV=6g^-7Ai6Zq4mn8w8GSL?n*-+J&yD-R?X~K#Pb-80)+J>64%*
z$Gj}n+?h>pk4}!Onm?i6u1yv1U~sZpBU6}sMHElXB<f}GrRt%v!nYy$+OCMPNT%8)
zuazLpvSqfLVZ~Zva>%bKkA%k-?twpV3H!1XoU{?>Uvh`63UD at 0?}m8a&D)IP#}A>W
z^?nhAxBSB=JR%XN6L+PaO5OGW!74adgKeCYs4Tf<*8E%Zv$!-fA)t<b79ESDdaOg|
zC!9`Hb20hgHFCyU$(hun02aD}zoeGz_ow8ffC4F5K5?<^runco`JL`&Zz;<L+Q8V|
z9 at kb&{m9QO4nkVk`epHKRc_PE_B9+vCdX&u4)E2&v7DP!m;8Q(d0(*iB*tK$G!K59
z9oImf7;pbTHLWLJzC<!PCW9toe{y7iIVMhVQTz&v7AW1gK-D*?=j!EERoQ7u2<AJs
zw9UGVd)3SbC(8kRY4Voswcl90y}NWDMjWqinmS8Xo-4a_xQhZFR(*GyEPZ!9R8+i=
zN!qTLx*n at 6F8}0Y`Am8q9NYRz>8vhS<>#9(w|XnRZoqeG<>xP5yZWpxUq`!o`7URX
z&o1*fS#JLQ+Tr9~)%kKUZ^1)2Q?XR%aUQgLz#?>;TDqV-UUpDe)uBxw6;V3fjL%uT
z`g+z?_PQ%ZQO>RHS-o;U;X1F at X<zp8_`2Rz*57kXjEcyaK5l7ys`@<ldf(&m1bE<E
zvLA+9pUwbZ>STv{*E5T68F^Q$&Z+mU=Yb=OSB22EDMeL}>zl7zy#IwlbPY at p>JW;P
z_Zx64)^(23i)Cx(^<iTVi~b_%hq1b!xV$;${qoY`6%5~W26$5^$u89G4e_KDt(o2%
z6Bt(<e5KwN9}Fcr$^OII({BAXbTrf!AT6`J=X|L8R2%Q4zYirdg|5TQ at xNM`al}A$
z?&g7JT}db!4)Kmn>L#zhJGMT7?D9U1&CbfF94+y(!r)!bOi);tfv#Ogv|i+#y_fhm
zv8T;0Zs9P(KWv?C8aJtIg}tX=!i_S;J=c7OvE-!et&*tq$Wn+{0>j3UzvKzZ3?v?)
z*AozdOpg(a2Y&D!z5|-X at RGe-l+bNY9gWHGcZl#`e`ZX9ThUdmE`R<`<|(E8v?`b6
zk1VyFr7uA5xj`9KwcU2!YS51DYw@=!EO742Bxrn=qz|b!e<QiQ3{Q^hWqbs0?PFAS
zgHwZnXA364!YSlPfPg8Fnc4_Ep8*Fbwp<7&%&GBOz_}<It*`4>M27R<<IhK5 at n3-n
zempBvee74i<n4)Fn|b}6sHMLEY0jBKp0$u;=E6}09F_ME2iMQ7-lm$_Pczx`Boy8`
z%sM{BjjGHuuE6M6Z{<;I<znuk==F*FV7sba=}_yJ<?GxrG5PU4hVW(fTw%p%gF54Z
zpzq_OB{1ZBiPCbmJKXkoReUwn at xBVvWW>KdaqZ0i9TLJRoHj3pA*?)at6kNl67jI1
z)}<OFbSFYK9&>O~(UFEqQT$8y#iQf6gj)seeM6mV*~`)7YrW4+$g4ufwx at 4S>CW{G
z$%^*t=Ie#x;p$WRY8l1rzFs*otZksF^L+Zj at 3!N0<*|csM)-BjcJ6WIMd$j3;-#jv
zr#j2)z;?FlE)!$M=~dSI3Pw at 1n@N^+9GKD_mNTZUIEcjTLafm(q#!kjNxgYb27h;{
zir?_?o3~R{M}99Ai{+{FmMY!CQBdIrOog?6EY{i)@28%|Sy4ZYJ@@E=%5b*J7mPjC
z5tg>4?V9zbsE at hOUGaWohI7S%H!zkbN_y~4HAr#J5Ft3b>0~+Fw!~wHTG%(;vpGTJ
zB+A`%BxsuXhP6I4a8tE2=B_uqMUsoiCTz-&x8LSXfv}R0>*WF3Zv7pc#6=<pJ+ecd
zSU|VK%wRkb&WgSMWH>y$O&7-dK5fL!kH8a=5ZWUsBmYs0 at bM%(g!T?K#-ZBQEy<mH
z*zY{TXf_%b%!)t7cjQzHYy8c50IHNYXaxV#@r&wmmgps%(MHHDB;HLS{9c*)E_jvO
zU at T$b<g#6QKlDgnz`zx_x5=miK})G5#wxYiTd-q?hJoeJ^ybNGbdR?kT72;}+(#40
zwY*@LXJ<=XD5Uk_A(JhYVlS28?d6DrZhVHPRlM5H_&=LYsej+!-WESPUTB3zMDIjA
zJY17FUryB1CD?ZW`%9|0g|2@@sWJbU%@KMjQJnwPd8a*oGTE}9snyWcq@@zj+TNht
zi?VdBMRBKgJ=BXa4~Y at fR1`Y at fi}3=+RRr{F*<($Pw_N=eb+E}u-G7VI83jr$53Xe
z5>U!5bpOM9yCr7cOZOUBrRLsoUov<wI*)NMs^`&I*<s$M>#-jJT)Ho3&j-89X=JeC
z5DM=+bc|E9o22pC#a4%g&a>^^QvBO<ScH4WvAk``{(3q7rMo;vi1X$l%gpSlw=WZZ
zK-y%C#qpm4@@9v^&eqpIuB4x5D4x%)+uKcD&}-&Me#=e+o-bWHrgglHgsUg8-rvli
zL_LKcK`0hC)1!jWo at N{j->i`~EXJJ+<@;St#fzbJ&0{~YCsFEn?RT<TU1?@$kBR-U
z<$EUSaJ>g^Ht3c67H3vuuTyyIbu0Au6O2<NLbDqfsjm<f)g83k6Y>5aRo9Qu{4me)
z4u`jvHp#O-yo!|B<owB%Tt;jvkmpAs*tzr`;pIq>de?VKk0))xqKds_plJ&6!FF6Z
zO>{&z9Q{2hCoB1j<ZF3$-Hufzan)%=V>@NV5D?mnegu|LEE79Z8|`a!4P}+zJf0cd
z-m99JLnJN(GLUEqHb7$ZVu5l4Mfnid2U3zdu>qC8*prQH!^jmXx{MR)rW+qZ8vfKR
z8b(JGfW>+RY}G$5M_oXnmi;fHbY*N at J0=>c@%pQm(G!GIVBMcvCUI{}n<83vcPB=-
z+|BmQeO3XR&SWOSL#D+#q{PS_%Yl0&wh#8Cuu)MXvb*7;`ZnL#*aTd9+j;nSkSmqF
z=d={uYv8>{lU+RNeGqf#xpFht>aZP_HeYSCk~%y6v~uaAfB5Y=U+<y+;b>P#Z&L79
z+xueDw~LGA<;(N4-d$m<n|Z#^z3~0Q!&BYle4U<KqtJD(aCt+LaIxOqLUvgNB1L7H
zTH~RjkV}Wna at yP|i+737iMOzZ>j3w`_v}YEYvG$^X9L!<@rq;5Q$r>T0aBQw%)B?i
zV9Xu!hMiZJ;&Wz|&#VcJ*(j at U3YVU{)o;<FzE{~iXTTfzQuTi7zaJD?Z%;K%v6wMM
zB67bpI-<&vfrcG>*g~n1lQv^B#Hibh<G|_N+UJ7EF0^((r6xXbrBxlXgSX_ryUQ0J
z&wjsfyQbk?>$_vovUR;5b7(B!+HN6malG-9VNW*bFh6Cdv at _QrIIB<zcZx0F7iMoC
zZ>C{0h#4Xam!kF|+FV*e&Tu7(DulU at _`MYsJc-YDBW}exJ84%Ud77N>za&eUd?j)&
znJxGmor<C-p+mEFvSnnKI?OlVB0~CIR2x>P`iv8Hm!r>Qw7p4jr{fnU6^un~I_7jS
z$Tfm1-Vh_%n>^R!n>@BGr-(aloA6f+ljz~0RrL1(i;If~(i^<WwXL}Gi3eylzSyzx
zGC+JN)3)f}e(l9XuPIEuuN`R-H;kZ2!o`tVOk^~o9f-$LeXs$t#dJ*sZ?Tg&#_IpR
zi}<(+U?+843OJ;oFCBQRRy*4S1_I<PRl<5k*!q=&cWQiom2*?ynkFN>Ew%R at il#_Y
z at f%ZK*|;KEWPXPQ3TWj(l5Jg<U^3*jGe5N5k`><W2NRu`_2Y at XmkG@1hIM$lc$*Ni
z#4oCqR%`<65?-2Du5V6DZ(o;zN~`OB{Cev!yS&Hj8}Qt06FwwhnE|$dc^>@oc{!aG
zzMp-~Lk}UjUg)}WLzBvHZEpRx`nbHR(sg$0)A};1_t>Dh+^U*=AECJ7>B==<CP{Eu
z=X-BefsS$5Qx-ErqW5alad+ME at TYEa7J{Ku5%KHfi>j)css$g#EKs`tQmM-??a2If
z=oclc(yPpnT{i5d#9*1;(B)e;1rbV9TW)W;4fp>63}-Od9~+~m-DdVbDDfh`wf=$V
z+1z%C?~=<mmL*vee_H2(Tl|iPx=~3#o1;F$yH8v8hRxs7OaJb1D_pnB$D8QQTdWJs
z)}|)cF$P*|1Z+{GdbCjdlbE{*8}xq3fpIfp$55GCFtX8Wong8%LG&^q$<26XW+tTg
zgX_P)kU{J|>F<u#`z+#-Yo{Uk5Vnto02rsB8C47nF5|c(;`%ai9hPg%&-24LL$OFb
zv3#2?4Sm8R*6ac^mEh6XZ(*z1HD#OZ+4Ltg$l|EoGGT2hxOajqA04vy*de at X3~C^Z
zz_EWgwLxrx0s`7XnCbSvN8R85`y`w)LO|zK7*HZ;*UZJhx8Mh~EFsd%{j4R!#8<<Y
z)t-!yy2i#vxkM$OH~ALPkqn1V_`uxoyDFNaY8Fdtoejw+u#12i{b!Y`Gm&ztY-|r+
zmhwr(0c#a(AK}?E)Gh!wZ&_+9w2ksu<zGhh8NKjt4|U;i8O;uQb1$OS`UH~!L7z~i
zD8n4N<i5E79}Dou>e(kfDh+;9A(vkWn0wRIu4B^m)|@}A5c2Pgn;(pM)xCXl^1e~}
zDB#O%P=oCC1-H%2wXIivw1rZ(_f5oq4`L--_bqEq016qH827l}COGV2P_r=J7F~w6
z>C`QJsi>@&tyl`VhB;=Jgiy3<5-^v~y&MOmk&({?q1 at u1k4Ig%-T>lvn%9%nxrUHN
z3%m7if-cwJ&{Vk&fU7v}p|h!@Mpaey(5$9-RO|5iZqv5X_c0D*{-2`o_k`Jq>-|aJ
zR-4myZQ<(#VTaR7#4ke>s21Q-kH_2gx|b^!A!Q8V3w51EXeCSMU4zGd8OvPhOD913
z|8V*~>E<%7sSuk{92uzRUcoI+Vg%R!Rra{eQ-K<isx!!a^u0x at DKhsTAe5N%d|7UD
z{q;_SAbi16L}yEATYT)DC=DVZNj@{GBDXKGC7LUf2s&mUak8lqkmOUl`Q-oo4af!J
z<>$)(vX;t6IT0O^0EZ%2IG6)81TENwzLGP}LpU%tKO7i>QyHlu7T&P7!=yj%1eqh-
zAQ8I!y1|MjJH9l;5CLW!J}z~zVc7*6f-}KJdiy~%4bX5Mwaw=h;>vyM6CQr%d+M}u
z6J#Nu`XE;tEPH1n(In2oWpX+6$aOWQS#TMDtUIyTL3GqQmk-u`Wio#U1D(tkJ4Ro)
zZF}MngX8g8fB=!8d#tI6f6FyrsvMt+w^-LV6qrmNj*=R}U(At&<%;#bt_v7hWG_6M
z!Lo&mOC at LSGVyJ4B^|QWx+z*4yLjx^gkdY2xVGal=-GYZwu?kB3DWJzHJi;CgRMG!
z!;waxHWFnIr_uDC_6n~WMB7_t-?CS5`9fF)?!3wF)9uXY33G>T>tMOhMu<;=&{ghg
z+3rizYB34{-F2(w{J~;=l~yGL*daGV;e7>h=Gb25D{T_EZ}m7Bx2<~S|M%eg`b>Yg
zxAr31#ZyXODX49GpLN>R)F~&~(AcTVedBUSpY_t2#)9AAVxV;Ri=y&S??Fz`<2qLp
zxC$dADs&0wV}vf9y!S9(s(m(_UX9U0^3zZWt|5~GI#r&VO9y*qs+afA=&9JF5=;kz
zr*2x$tB>3VO+shBGb1Af<eppWtzP#I$H1lw%Q>{enD1F??fAb_O`)a(+L$-w;^sV)
znqS8fcDz8;eNqT2I|kJRm}BWEJ(^i;KX3JAarr6b9>cfRn%8!`Ig-AhVb~r+m{nU-
z%(KdAgLS6ZV;Tyj5532-6(2wNX00~mD9kblV0LEf^KViJZHn4oh|BS>Ju>cX3a*GM
zkKv&_q- at 3;N<@=os at t7vY`IWze<JC_3^n4-;g%YZA)ow=x6G)M`DD72Btd^vXX;lS
z=_?KTCp8Ik9CX>~KC><1GWB8a_XBdg6Z$=0S{<?ioj&gd*Q5w!kKk%2 at -h#2{pF)&
zgTi1(awcz8g&<~{;c$dv2S$A;TEq%KYIkgIGp at 2jHCeh>F48*%H7k-4ysv#|lR%IQ
zAQV6hn~WB at iOc(x-u>uKqR9|>^%qLe;BSdLu<}%OYahOrA+&Zz;b+ve)qa6iX9~hE
z34I`7I5DA6<N@!K+?8uR_S~?AD4*z>*LRvA^7pT65_6_)R8?W#W at BBOyn+#`=@@`W
z;js`8NU*cOG!DBj6b$Un$3b94-KAo^*DBwRf&BBDH#RluGbFmM4Ow?mz>mFy1wc7;
z#~RdUfaaaj>q6DjMaLv_nL{rzYOu3=;X(G(2+O?ou6n?Ux0kN)gR5_j&zAQoP)z-}
z%=e5Rd%Y8W0iLKn?F0D+rt+<|9lFA=?7}{$sj%1Eb2BFlfyQEwr-Q-=Tc787OE5Xh
zq?(G3rdCPz{j}+U*~?35f1YHo0h5JNM8ER*l`8<BRv8<5B)5UP2i^4ixWAh#{0N at 6
zxM?{m23?Ky57cAj<P1EF3-z7C^-!IQ)DK87i6x_Tn6dy|NRTdr?E?Lj<B$$UJkOx;
zrx+_yp<?74Y82icc?<VcJMWwDx`m?2^xd?Y%uNEJ>>9na3eQzJwl|MgMED`6<3K?K
zj;qQ2jgl-WkC}p_)lwGQKd_~W#l1u^-N{By@}cGAWm9ak<`!y{o7}u8Q@|_S7wn~%
z=gf0zL+Z#E0WZ^%(_(NcJ$VnPpm3lNR(4&dCe>vjP-s0WDTaUwkW+1iY>Z7+b9SX<
z+!|Taf}h5LZ#&5G_oVDzWMI?2qN<98paggfEUvDeHvbNwDt!KR-23C@!U*B}-c7#N
zl-y2Yu4CRhXfjxd(a=js(5{<}m<07`A`E{XP2ul+?`St5hd!kUz}1X=<CZ8N6WPX5
zJ~2WV8PTGUoGC6pDMNWX(eri^C64$KG_+8{zBL6`jbpSEq#_;5$W7XV;#cNnMQO88
z*Q5S7p%3BMyOOL>B!Q84w-KDJ2+h3b{(-Cr?AC6=td}21P<u{4H~Ya!oOySDj=Y=P
ze5!VTGHs_$GoHJB>W$)StDb=(B9tM%ulHEoA*`T=?X2o;GJ_{AM3dx9BHWuqDJi|z
z5fK+GLNfiwGt-l&CW+xT8m_UaiQlt$li+lHxW|B^UJYhgQ at p&qJRxL~C8I(Xpje2A
z(Pisy_PE8yb at X~82JiCgcj(DiV8Sy5uf<q>+mf>@nA|rSilamnESnl&l at -P>6iiC&
z(^*^lmkptbn(49HTE^?tsh2dOfss&~htmnwEvYaxVcytRBH`XW8P|{uVn=?Gz#roD
zcAxm%y|M;xsb$oEtEEl;1ghSE%2TxZsqFciK(&Zu8NZ+l|M);iW%(sF_E_6EBqgd1
zUrw@%@DtV%J^{fvJh%B!SiFox<;Ob-P(s7{Z+CJ8cdmjf>SP|NA*&lvw%0+K9C&YC
zu&y}yM?4f^uO`IrDm30k4&ZoHw>Xc6#ya{y`Z^q_D(eJ~2bQBmz^Ok?!kq at bIsa$J
z<I2Q^<s^jpiH7<kG>t3j`LD5=KZ*5Zu~Q!&K}QNF*4XK_$zEOZCVmVc(tjv$m(f9i
z<A6HACOte at _!RArin!0~Mt=ln7dyW*YhC9i at D8&74Nhfels^A}koNN*^A=sX;|gZJ
zD%(FDWHB#TjUW72mW4au)R2z;TgAAp$ehx0ajd`0_70Pxa+y>o=RW$l9Rmm}HDE2(
zU}y|*uW!G!^YfjUq)sWYCG?h>N|L)-p~ig0ApLwRDFkvFlMZ22RVez0UNGDv)Gt>V
z1*FP*uPDG*<6X9Qxb{Xa2_ogq38sJA2WQC$2FF2f`zXV9YAnil2kzQ=dbmP at o0nv$
zFDLBe%bMMF*E@{Nd=|fhq*7|^1={3H%)0ES_nk$nt#!p6h+uJWI~#Jbb7iwdwVNAV
zihmPuh!8is(@D#}XX+ve8D>d}4qELc5-OEBoQa%0uK6hAZLadzmS-=;F#3bIy7Q0L
zY(lZDO)H13EnU$VSD!v;n at pPvrwNNU^w%zAa665Oen>Ur!IJq$gRSmLd-QZbuwZSR
zuu#sKwQDWD<38wpndkn8zpQD4__muG5?NeWZ+&$z⪼mDSr{tK2+EhOBG_{{`e&G
zH~MVEN}>O)*KNHFdsndCf1J?E-CXp1VE$!h`-`Si>xZL41yFpInX|kj9w~(~f^kK|
zdLc>!rO=%~za&bXdgjPM7FWkk#w=$C260XNz%>5*A^-Gep=Q at p$fr9oR=F{FaX#-G
z)JNg{m5Y^S=bUD<`e+01qX0lK6UU!>txBflkuX%B2AZg$V0*hej-`-=d>)g)F-cN(
zPwZgEf+zcZa`%#U`%jqopV5C(1E*HRHLWBAP=00?*umY<N2Y;gBky<-`n3vC8{+<S
z?j2Y3*05cHn(Y2Jk%`1jx;~mll^OI;=0M1czFK9J at +9T<i-~!dKyOlpGe$`7;=+P?
zYaO^pE*L at u1`SvI3$(Rg(Ltnx$WncVSH*!_wtg#R{u0~vAuBQ?KP`c8&uhin_ymJI
z6xnp56-V_~snI^a=)8Xrk{jNzUzo=LIso6Or#^>825empxGkOyPc%MN2--+vds_kA
zG_H}?%5u4rxJ`)<p=R>m7)C<@{sfK+lU)T}%Q(k|BHB at Ffl^*eua#LG&!cLj2Rna$
z;;0Al--^E<ezpluY<vFk$S5!iH`@tQ8gj_xLO#8 at 8qtRVJ!+l`>K(&^s7z}EeQE4-
zj7MfmLFq^UJy0-6iH?BRJZ)Q;X0!e&^7mcO53)K%IS0XUV>>L^$;DBLLIL3^aMneK
zZvyh0LC<Kx#XO!)7e}+RG)LC1wl>dl%Q(_aaS1!Zr1iU at 6$x_w6Q)_WR1z=lRf*~e
zV59b!UcU2MH!B9|tDRt<RPwb8tPS81mA^V;2?XV#j at D5XCn(%0tG+c-SYl0}=AFc9
z4Nj-uw>8uJ`HU6gY(mOGq}z|s at EK9(-Dl!YG`sjJst7;>T|Z5Ki4<RYVS at Db=7ulH
zqt at Z&Ki)23C`SRHPj1sOX|SpIzzX<delo(Cz4=FC31Ekp*SesAX7*HXYoarU)2G!n
zTtPU>Nc$DYWCy=Uu<4(T^~pABQCW^cBC_(frG8QU1=$3U-*b!RrVU<~wVbIcZZVIY
zFQLhWr%zlefx<zzTf7{va!n~>w!Q!Ob&GL!L=M0E$E^C93)uL at +jPS>R+J}u%@M;-
z845+tk8{W0H`)KCi`)P><aEJWWM|vS(|0F`ZG*&H`=E7Y<V^01pQ7d;9;#LA2Kj{8
zgy|*BztPPXhokZ=?EZKE0EUfILo*d76bAqXJ%doxx6-k_t%*5i!gd$Q>vhxeSUfq?
zKysnpcrzOo8=!;pR|laeR#w1--MLkzWsrWdZ$xVh3!5fhPRsF3LsrdGmlmTh>?cY;
z5|v#CNW<p at KODR@Ma~y(duOw;gI_)&<a1+F(;<G?-jDQ+O90Pu`M9>AB^_}GNegKt
zym5>~>>p~=A<`S at GUvK-rE~#8&62p!^s>*EADCBrI>%p5$pp0o2PXoVuxz(ditpd=
z_8bOI8{yVk^iRVWeLWlrOa#1;d$;Lf$!G9e&&!DIn{2kcNP<9SHQaBhe>6(vX*!hL
zjw)7<hoSK%^&2EmL!4`~r6vKVc;T(fU_~~3RS8FlUVz4H=Dnd~qkE<2+|eo7<cGd_
z%4;P_GUATuV9WF3o+WKneiB-y!{_BvOkgD9&x%?anLD*rVN6EeGxSNL&g*3OOW{qw
zZe_x5>Y?zH&cL^N9{Dk+je18k7PWa#+-vi0NGI?rY}h|zGd*$GI7VUf3yEM|45kz`
z_TNz87LwN4U><l!stzM{%EoyDRsCLIUersRAjI>Q9KfD}O;d&Ypy|8ocL-UQrSZxl
z90K9csd|JBRm1m#(Lg#7BNC$6TV{2aS(AU7Ni8fB&ktHa2H7-N5N#ga1 at +nuA3<Xg
z=nw}Wzs$(#tNTot%rw5Hu{Z9#@zmXhVqSh{ERwc9{rZuNG}?X;kojI(+N0flW6h~s
zDE|-nV8N@^_2+7<`rXDbf}d4xl&sBIp<>$DDb&Q`o at 0~#`-)nIkcB!TR!<zKlr&PW
z*)BJMH*GYQN0N`LT|GI=MWUz67IhDhWx18qBN at m^9 at cB!|A9!w?<@E*ysuZd_dG17
zmm0Y6w=r+C9($V!9CZ|lmjmI}`xIOFJQqPPFSy^%1Z2=2Ko{;<vg{RGy6#x=Hc1TF
zH^pqQzriVCI&{ce5-%8G;wi$3;@v{chcQBa`!SaS+#i#%-YA!Y*jW1(zEuwg>Dyii
zN%oBQPaF|%37JH*dJ4QY8N0OThNlwAIog&mevJeo?Ps4nbCqz}4VKSiZrv~`ynaQb
z28Vbap)O at B6p?Yre_jD|!MOWH5i3-kWP87gB{uug^Wi^H5h}(ZI);9dyjb1|gB}T3
z%Z4t8Mr7&}$8FfmSaE4Zqn+nK-fS3(^_Od!Nav&U{|;4`4sYg-*rMk|3Qf;MOi^8P
z4Sy?~$tQM5*2RN0dN&|Vqwn}z>FDUl$pPqn@&xxx5pPJiqKwjsB5WeK4gB0---OGP
z=%-8>jm3M1|DlQg8N3~lfk{o5v94y`Y|i8qkKk`lN9`v}M$js=lT+|0kmQ<hd5q|P
z at E#*z_{ftUi_K at Qn!A8No`WMYre^msjzU{QWB*59ElL0DPqmiKZ5ve=yfNMy0V<gs
z=f9T{^-tM_*%e<U-wOksgj(2>kmDcNXCGfrPfuRJUV9#4u}2K_N(b(>jh4>=P75O|
zxqv=Q!KLo*k>j#}+JIfj)&*qGxbgV-IC`3$O%3;x+++^%@%j9itO`$fue`JEKab{F
z`p+c6F}63NaMC+CdYEHH4#`+FM*-!tl5}pXj@=(PR+8*)zTDVd3VaMF5<T_~y$jnK
z*FnC?WgJ?7P6g at S0D3Ixcqq=k1#2Vv?`7+a#s3byQ0$!Jr*yzLf?FhoA>m+#_(U$m
z^(lBu5LS$~^(*XC<iQ*HO=`a2R9uEs;ZV4gbYMw#MKpaBKUZ|cohLAXd*}P{6Hx{t
z-|2flEQaW3Lalthqq at O%hxRRKO!J}+E=^`A+5V5hX9Q%h)C0=G>Y!uV?npzN>D>xn
zCXua6iO5<weArJMB1NvxAIwpW2EWTbVNYEwSGuViLNOx6Y3(DueB*0vms at Ao?Fs3J
zBgR}ER|u68_N6b74l;|^*n0a|yM}_lCfmrVuw8<_wJ<FG0f`Qv6L)Tj56_a)p=9!G
zhUt`i-Ah&Zrw+aIR%0B4XA4e5`(q8k=Ux2M?xY%EPal11h$TzIRyKYHOOZ+iGKpKs
z9R$2PAe(6)F5OTlC2TzJukpQT(~%Au_^7h9tN?;Rp6;ARu{HkBBx|fq_7`(zD{BEp
z<$sPq*WId3p0qA(j+((XBoo3IybNej`I!;P&(edTElsOXg?FAj at 7PC=OuJKbZSdjs
z^#W-&y#w{3 at 3?Px{Y3 at dD#m}L%c>hxNDEtBUcpE0boI<@L9#YCyP?(kXcRxRn?V1k
z!GyYRSH7BFee#sMqMHol82UZ5r^oBh=z7x9BK!--JbGS`E5XRS$xm3HPC_whFc0mm
zv;N_hB#=zF5~C&7!W0ry+HTgUl-C8{R3v1I3 at XC-Px1O4UB4{1+kMG03Y}c6EyN=s
zmo>pY49S*Ool7l84q#&&RR1Ct2{WONTW=4zPUZ`E7JzATl8$O_`(Tl=wk|>bQOioD
zUyUPtH8<BR3!|0m$AJheH%Mnmy>wEEN0Q-8UxdnW1row49OjNd6FrT~8kv35$y~_s
z5;J$|vPTQ>g9$_x4x{{Sg3|Hx8}u40)w9zzG_~Bo03eGyL-D942r0uX7S?t-1YH1)
zv!n^SWdzb5G4q1kzXL_z&$Q?P{J5M8GxH(i^R<aD6rtB&)?4;fuO_dnOso)rX70w3
zZrA#E+$*HyF9lmd;$C9c%?%+q`5^m+u)sKE?eDTGvpPY^pUYbE6+oIMyE~tuQo$Y5
z;7(*FSxfYrk{_$}V6%&mjAp_W`9Y959P?K#yz!xcz?jEHx%alT#rwLGzBuKMQ}%4c
z{YE|{nS3@}R}391q_=;^9U|BAYI9GW<TTIh!;6^L*sHAf^)X1XwX at oUv&jf#6_?Kb
zK9Q#vvb#(m3sj*BI${rYkPI7{TXIW<K5K(crP;F!VvR~f+v<RFR->-YZc!TbP1^L_
zKe~JgSy;s^fSYoR!+i?a2oDPYWF?+$ThtO|aS|geX$Gzd!v+7S(}DWve4~E?+F}_S
ztY|b&my at t}w)z7%1BnfvDTZ9LtAubD_`kl7ea-ozbEr;ZC_#E0Vy91eU1`&wtXFXP
z^lN{|ph8k%pK)b1VV~73VIJE}u!c2_M+ur~S?N3+BNh(T{QP4pQ92ztdS!*bnkxvE
z(apxXDzZMYyYH0zXAD9h2^qQny=?#oQ1aFHFD at 5`Ly<DG`-AHTY>(tYFqkQ+9dWcZ
zy4=Zks3Omf^xh&+4ND1x5yJmK92li*Z%g0uPj#pK0Z4c<fAH>VvWG!1b{9#r)w5E2
z!!2NKXzhT%@z**0c>-Yk at 1fD>GVB+KzRG2L8Wzwea0s&vHLmN<rdGlKDs6*@Txl(v
z at uOzYv4iMU9Vwi!I}a0<t}<GyW!!rfSjBFe%3Y$l1B#ADsllwt9-Ir_*g*s&LHL at b
zrNCol|6?^)6BvI-m8jpjoE;J$tHKYPtqx>OEreIK at fQafZy+5}_G$=C9gB4hePTPp
z&j8SZJ3@~EBV#Pt-j4}sJd^PDoWYcdph<B-2HS?xPd;o~gi0)FW;1OK`yUc&{9&Gr
zLC=hG$+F+ at R1oPdo%oKmg{L?aO%9W_B-0S4XR&bk8M8CaKI22^iIY1xUXh*{Hn$}v
zNQoc`f|KCs1)xb8D>_}h%b)UV&G48;jCyOXnBUK7G~?<a^9v(olARUxq0O&xK6%z{
zen#Gt8losk=VH?fO*Ls2oz@?Z+_#nx at 68`7myesa3f;@X^QUXgb2%1D4NYCHwiH4E
z6-41Sz?}oE9!B_*x~ue=u at H*cXB at Futq>!bU#J&~Lp1phc=${#Mhm|4Y_)##Q+>%O
zJ|`xn?;T^rA|`z^B%xnAf_9pXYMP3x-s3k)rW4sW_nF{Lkb9q!`bW%Fd)vkx$~kj9
z3$&Q8qJn1(H-PG=b9I^VvPcJk+lfM5r?j<|#OQ})#F-5R(Z<e}T2qeJ82=*$oyO|9
zB3+om`_N&=`tDmC$Ga6A<o<@1B?*`n)yLiq>9_Yxo-=O-ozM-%<gsUt5FB&>5Tpre
z^(3Zx`jeA3{CH!ZU|6HWc_cIScR-0&U2>SCTJNy`(y#7(LXkuBrYBLxeA%YqW3g71
ztg-GQxxKFx_`*|OloPGq$LKpUtS}cFnLVNh390@&H3r8*=ud*T>7t7?gSR$7G_|C8
zX*)Uw?>pcav4|ZPz==0g1PV?S=dp8W!tySfH#;b9t`sm;LIzoCbB&SHX};`u at Y==~
z8naYPPPRj8<ePV8`r%pPT{s%!(N+Wz5fO{15i|fo=nfJyUpFbFg&}YzVk-7OWzawO
zv6vm_=YeaF4QIuS&unqFH+EiMdZI*A``;kdE(_jj%2(SM`O6cKIW3GvIj8EUJ5Me<
zKZZfEgd$Qa+k5?}*t%(^fMl!=W|tcVcVL<zY>ET1+>VHmV@=fh!4Gus*61x<Ijw&Q
z?D5q5G&tD)G&%;gtPUfJ|DCEe=R&r754nvS!TbR9w>tKD1j_IZfqlmbFeOR&NC1kH
zyu~EBAR3Hz`Z2~}&s|!|7qn)D$-^aw&L&NNvOL8RlL--yph|V<v8B)WXVHyIz*wM<
z&Q_DVx^H4iM^7_?`|^zf*qfdC6SO4lWF(NfjK1~Aw3&_<g8EV3qn0l at 0d7cq;>D~2
z{6^$w@~ox2Nm=~)*%S35UP?{A;d*03nP8<lXuYgI&H!sm;u`9SwcTDO4>at7Ab4uz
zNnc!X4%Osa+n6k;V|f~t!yJ-T3v#K>P!O at M_`i_ga7mQLT?>Wxm%J<~B;+Jq9~l;Y
zX3O7iU*X#w&fGy03*`nOj#b^O4lD{UO#Ax^BqX#EN+=MEr<12WCj`of{=7NW|3*9W
z79Kpu4151M7pRB`(GC|IEIEnfEjm-OWuU1t_ac^>KIY7-nw&}gX}46pk at qiGVFpZ%
z2EVC9g4=5bail=0tE2?}?qY}X#fU_JjT at cSv;9^*-~MAUtrRpAYf$khml=A$LN=Bz
zb@;QM)+LeaedX9vZ^-HHqI+ee;|H?lDGOJRfe}&p9gNg(aK~>XxXVWG9~U;!+Thb9
z&)Ef?ewxxM2A<|4jjzV`6?S26Zq}F+c`Q}`B_#obj(MSqdk&3#kw;Sd&1C92e>eqg
zy?lIqyAsYWCTNAtQpZx7Q42;i*sLjCjkH at 7wm&!;ja^o21}sGY_mK;5P;+ynk6Tz;
zTJomWZHi5qtAI_n+ZlH#c$C*ATrF#iKP>zij0f?qIkC!Pn+~sV)NQN?x&Tb!FMm&N
zm)IKa*C7&AfCcM4`HDL~;?A;IITu^Z%5ovmFy+T at 9oeA5iL|rK#Z`cb9;wpp;^M-W
zj$QG6fI+J)toN$jQ7iRp^6V9KjZw6xo$Ce~7M=7GiN(1Pb*Q7KcPcVDmdjQ!z4CQn
zlrJow7;?mR8GZY~>sX(MhZF7{GOc6vf7UdG*BW(33*`v*^dV?sYEEPhT67h|?Gc0&
z1TOF2u>jId##7rlQO?58LQn?v!B2O*l<zf7YThEYQ^G at 8zFp4-uOVa%ZyQb0r6`Ic
zcS+=ZG1T8n4Y2Oa_8yY3A>gj~Isk1mv)-;acZ0=!G_gue0J0=ajPBIGNt>6%pG;N2
zay1D at wh`|L*#C8`WODLRJK at JJ-?U3ZGu$c9LU>N^Lfy at o+nytU43~wit?hled!ytd
z<|<|#?@7ZTrG0Bqil(6q%o6Aq!j?S$8u=PZ#RNh4<30b$f=`Z}OpyA at y(A)rNz<aD
zq7?XJN4N<@sry!!pi}B1{?4p<UKE7iWRLEDKjnRkJ2P_0dv|38PMrZRD*b2aL{u?I
zZ5v77&&%rXJ_~{8_(T&CiS#6RXnJMtq_8$BiB9hLAgl3KV=1ll8heTSYw+0-QPq}T
z3cm#QP at NH&WN~}0gh7YV;hws#d&<G}I at mM64dEtbRo1E&jb%R=aO+nrIK5NI3O8<R
zag7&=!RS&voUP_j)3WM2u!tR;^LT6 at vO!6R)re0(BgtF+3%`&1UJCd_1OEBWA_^Iz
z{P{l?0IrP+2n4c$Deoh5$e-LdNN(^MYzy~L16>9Yg0t4~cB$3>^y&=JzGwZx)RM8X
zdt_>u{!_f(uImJ<gmmLtc!3XRURq1sdF(wL=yoUeGzTz4eZo6_XRCdReWrAMB(0JH
z5~x#oOa=2OK~|oq at d(61Ha1CZ%J@%k=kfLM5qMa_P{`nITK$`)c%Gid9Hm9slvD91
zqXpY|`@!eFzLOznHj)-LNeN#gh_0wt`e_Rx#dYMJ+h7ZRT(uR~Y3h3NV0>!gJ+0+V
zUO8!xxSfPw02fvW!+RT?d%u)2eez($878i#S0G{MJ_ at Cq?+N~H<2Rip`wb@{Q=e01
z5=q*$PGeVsmQvm<HNcj^S6Rc>`G?!|lL)Zx9;-I6s!ds&KOu_Xcp?*6F-<9emDMm_
z4I?(bC_=DzvC44P8mIL(if7#khr1lR at Z(as*t&64#4f<muMClx=sNxE$6(IX&uxoI
zr}5XN5i@`rX(wqtCBsyp-QA>U!VZ3bxY=)9^4OYHw+$-A@!uD+XU0g^tW&MyGTjzT
z>JTAse#`>DM#sSL>}pt1T!^e31z!Zd<kCiu!~IsW-0O(Lpu`}x(h^$e%AR8HEgNH-
zs0`dBFy#0D at xg()0GnZ5*-Wp!UIa*s2NeJS)?gsvPeGVYTvAe!Ld{<t#B?EId(qr8
zAikrjrp6zJx@%pdf7dcCWPbdmhAsCxQfDQ-O+&%XeIgo7C-C;v{#faAXq${t3O6|k
zNun0p#HGJz`EHas;!dXVV6Z2Z4VP3(U<AVKaNBNFOpTt~+pkSSkqPwzx$vrG at w_!_
z5^`BcETu9_Sw}9vcHet{M{u7TFabLp{}_<pQS at R=81^C84UF`4u9j!DVXw$2ujEPD
z{qh%x5^7rc;D5^9l^8j>@*&c;wvRW>8Y(j%0+{-ZZg+^ZeIw_4j_fuazxnxj{;;nj
zx_`ME7sH=J%6T@*Gk<;BP2zVB28o`5uxiv$Ajs1(y~vCe^IllTA{oJ{$Yhrhat(p5
z9~NwFJ3k$#1g9oH$(_RC_w+so2<81h->@g<4<eOy(Q>L0Qb`r1V&`jUD9)NnFoLq6
ziLdmJ;Aa7=6mw-#wIcaa6N=3hYz>jzx!`q~5trP%Ssrj_liY<vHq8s$e1gCBC?+gO
z`=p;V6?K5@%%p~Wd}=&QfdzM!-()vBM!P^)N9P!~C2Fpw)~qzxUU*-5ZxV-_L?P=u
zZgAyxCEPatVm%re`E6J at zaJ@nk3$^H438$NncHX7p7Zh#GQAVtWQ1x_4E$c|ClY*B
zhl{SO)OCsN{+bw6jPgRqlMz7r7aTlIeEr7|OiG$M2ebiZk2?~fqhpCTA9t4 at oT{VE
zjbxnz5c}LA;>)UBiUAT6Ok83==@Mk5EWH3cJBdLpIyHz7#kAJ(6=>~@n)X8pKZGE#
z`HIbV_q0<fE8v at DUNC-7qInLAZE(t4*C*Y#z@|OP44esMT?~n=SQ-fiwK}JXqU<2D
z*)s91+u-Rk!^&n)<apS9hq6s|d6a86WYWqt<{p7xWPopjW`uEDhuK0~STxq|g4gjy
zMB1nq+iCv)21GnfVW>(pqcFO`zFED5#)S~2M?<FFx-<REP|UGjxK4n}p#R7&7u>Lz
zjHWRrhg6S6%X~-l+o})s%xQzd_1#`^GuXD7OTxmCcu;s}sD9`HC at 5tY-@qM5k#O^6
zke)gM!}_;y>~L22;b>&CTW{yB_K4481WiI?LXm;*{ZH~k2d>V3B2k!842jPYrtoD^
zSj^Grt~k;Q=6vQE1K<-{xsARK!D5eIVoH~1OMbL3!f?0DF$O6stjHLJPLpL9XtV-T
z&LcCPA{-;V!|l;uOPNG3-Ao*a^*7A+*YgJ|Cz|!uJ~lYKj#~n&_Q3LQbn~#`qtm8(
zYeVtpN1)ODZgBOl%Z@(Sv1$$*Q8+y~O%4 at 5oZ~$>%Ndwc{8NFhtmwYKK_~!yV8o3i
z>8V|^?9OkdSPaoc(w3+$9W(-Kh>o_0YF;zqDLa6*@>efL==##NjF+9twt1)5PN|gB
zJhz!cv`%1c4TJI@;q?xK-bF|8gHN(*;I^PGOi}K*#8*ESC~+<njAfTCn4G+{z1a#_
zb0L_|?f33jS33Y7X2EuP|LK3{nh?gE;p12}1;4&?E^;#l9Lr(#eJHSfwhHHF|M>V=
zfepK|$bci73ea?K|E*W2>~5^7=Vir(QPy9kqt6}pB8o5Sey)6IE9*8bX}?^}Xo6zx
zLVKB#6MxU048<}6#oQjzZPt_*4K1dYgO^dAa=ssGRjo5(7)9}i&InJ}qb>CjX<9%+
z0@`V}Z{HMUL2e#?#GiH;42A%1ZQdd#BqI#*^dUZ<uhFbEET<vnXdrvaZ=@u at E0E_M
z;?pwu?K|fSQ{s3yxVQzA$8x%jQuU17mWj7z at 4f*RrUt{zYt&?ScNq|&lI&Vb$KG67
zfPH5+9KAA|0=PqcY}4*=_HQK2lUR}naUY*JVO+ygh;_B?ykR2k`S!#_Lw5?YDLyls
z*Y^`l)S{M+cryUqa+gJF?bwT!K3rj1-U|=b%3f$SW-cIn(<N^>2X><Vqycnf*G#pZ
za%W;)`~3-$3g%#+0d;WdlMk1OCjp__adgzZm`_ppgF($39Pzs2jEE^Kt}=et(;wLr
z|MNn($e9FJ-L1hb8+vn5_b0hlHPGMtxn*ApZB_bvUs>&0BQ*rrpVq`ywz!BDqfyv?
zIc$;g?ONYH63d{!p?Oca#$mohY7j5d+a!lVIZR`|wg{+8i+Nn?KNYMW?)YKmBot&i
zoqiIuK8(Z_t==G!usIngHHaY#1;Sw8xNTRoUzpy#1ZKCzT3Vt_&~uDWRTmh6D!LQV
zDTDeDxvqYToI)o|vLiDgNMf7o!9|NzN!Mc))Ituh3>d at Zg*m31)nC?sY+W(ATB-Z&
zkW`)~Ke<St4MavFjLCvvZZ*^^L*}CEM8}tq`l~-R7a4*Y>rOdvVQ*_^^dusf!_ at m#
zH(3A!f67FIXVs*8<Q^#W3VCC70(5Gmd*yNVGNow^#)6f&1UKwh6<Dp@@Dj!^sZTo^
zh8nhzl|gVfA;BG|{Q#p9VBatphVD2~p;Fe+Ot$~a5A6>ri7dlI`}VJdv7Kaq3TD;h
z{4#SnajWpwQsWGC32-W|XAQ_9XYF4laGN^*Z>@@70ms=Vu|aUB%ohq0e-h=llSw&a
z=O~_Wyx=eoeWoTh>POsp>F%Lh+FT(C>vqH?mWtBkM;7Vu2m%(D4f>lJSnmS+c*6C4
zeYV|^DXv8LyD53FQ?_~;UUh9up~fc}&^tE*%S at w|&3^}<QwF~r?FqvAdx6fa^S}w<
z at g3ZWB6)K(9c at dvRByH>Fa(OA<qfu*Ub1i6B%tr^)7|;~uP~qYOH){L3iEGeO)h`L
zLSqSTZec(j($LJKZ%aQAZG(Fr8>b}6hlS#y!0c^ev(mnRd;p`Sp>#HUyOK=-On8qG
zHcL3ONYkAfIagMXCEia2r at 3@y%F&GyOhciGYCFck at V&b@<lE&7a76 at UbbMX?4eaZr
zk-&@`{XNIM)W9Uz&n at SMq=q$M{X5e(3yYzgOIFh4l3e1i)g(IBKUu6Lq4A;!BE15s
zXzBUKWA2VdPwu at Z861^WRj%<UpLHVN5l)vI8LRb at rUH~t at tmD77xgGJt?1jz4UN?-
zi4kDUO}p0L at ZjHUF3BzkmEF56dYv$L)tft_D>iumWcJPY7ZCj{180D*S(AN6Zj)d^
zIa0ohoarjnclOc9#}7_xg_mscSkN?-i|m(Ek!eK}eB1IqlkkyX#zdE}B`wpPa5UO|
zMJeBVJqIf(FQYWLN5W<LL1Ey666S2x39ef at Be6s$F<JcacQV+0ox1UUdLJGl{^2$`
zcny at IP2tIU4xHI{J{uToo57&pAvw<>kpomWP8$%-KSp5Q=}=A_JXeW3?j06095;^t
zv|Mp)zm`5$Sn0-oXT6#F;GoMZMagBvd~$N)!WSe<8f(CWd~W|3gSb&CVzN!IlSq35
z6RjioDjLd2GdMa9zZt|4{TJL}<XJzYR3VKlNUm-%)+U&GfHq)8ton;*WF|*(Uvdln
zp2YRX5s<)Oi|NJg`?P8mW~f;g{9IW34kbdXOrxSEkTr=}u at Xk9E)vBwk=%x(!~*_r
zLUE}bbzc8r7;vB!%^r#OX9^AcBb+IhW_3|zVs}~mI|BlP_>h!98mp&cGEdZEgW71d
zm~VFlF=Q?XF<AWRJ_2Lz|2|0(#D_z#vH|}}W>$rsuMeFo$jY7w_1u22|NSr3E`%h5
zbDB|x at 8wR|?_-ij+6)F168G8*J{3?22`PGQ14CB|S2QnMjcWEZx;Qw=OG5WGz-+r?
z$0M-AzDeB_hX at MN*lJvhfk+vKZmG2$c0=u^lB%aIJ|{Q`@w>kOM;gpw&?TDbxJw#q
z>GDqo>7X#~nGWi8dtT@<dLl{(G&xqfP#9~<y>eFa`s3mvCM<p at i#r%svwq|>@)KU4
z)&%mmp*3~zralZ~jPM&yWBEkvtSLlfdG<^~t6{9CS&svQFxA)v51@#uaMqOZKijR@
zsKg{@?MPflSnUzqo{YsKer+_Xh01_ieMCT?vlum6xXULrT6j5Jp5<dQ1DEYP<_uh^
zd#@dBZ`RJK(NePm|IKD4x;W)Q?&f58WJ=kx)CSPo;*BYYcVr%B)N7b>Az@^{zneNT
z$TAQMTT&3qCX;xMb<jISe$f7$eD=7%csN0Rnz){(yB4ycdj0=@g-tV`8RVS>%a19%
zB638_Tkh)3L3cw*o{0a at 2jtC6_3|KqE#`Ts77D%iYJl;3bK~w~?)k?Ex{%;LN);`~
z7{r&E59*&xh=ooJX(3DDWaG*TF=V}6enZpN)N%H4OJSkoBI6KF>Y(1`&x6V6b7Wd+
zddHW{S7};FLE7;mF9YGtV+>h-anet^vT1yUMfXDV)gpD8Qy!kEX*Qx>iPiixQH-PG
z9ZS9+jXT&)t3`s9RfmPa%Yp8zawdBz1**;PU+Ds<M3Yl#lyf*O_PG%+OFm0h+h!r+
zA^ZHR_>R+w)Eza;KG}PqJaJ at Fr(p`N|BS9%Fh)}&KneFLfdvOo)2vduxnmC$*B4l`
z>+=jQun3`20G=(wV}E*$Xw7TWA|xosdi9m7IUp_vZqW<L3Q+AoH(sapSG=&so%?3Z
z-ga>11qdv}Qj51xtj@~K`11?*2Xk9KW}ys`@52s2+IVSvBg!d10lbr$z at he$QRc)Z
zh4zcP at IH?`hV3oZ|2v`%dxK#+CD at otr!*)H!7VA1(1R?`3L9r_sB6NmK at H90&=eb$
zI-QRp#pQ~5Wxz2Ns-F#!Vf@~i_t82jIf)h{t52A;0mfuaVYB%n96s8Kp*ru3PK2D3
zrl>N0yhGlf>jKTH2v~6c0{I^aJD$!@^74^zjL`v}n;KfJizYc0&;%&j%zK%PPlS?@
zv6P<VOJcDKSrwcaur|20=J=Y?yTFtc7z6!g^!<2LZD|?CBMGq9ka?A8)Tb?d8^LW)
zd;osLh?bSz$%-p|_CHK?Dl8{5o%Ma<Tq(hO5}}sXvGr&<7pIKOxO<J2*vde7O(YeB
zHh at f}uu8>;I|l0^eQVTng2*Kl^-vF8KS<~T9^H<P<>8TWVM8n<*uKj>oR~Pmpjig}
zh;HhA>tfHS$UJ2N99?5lgLLrGWxR=&6(x*2ER=Iye#aDxc9^wk#M*q+$#JE2#U*BY
zq4w_a0houT87wGZ<7LUyiGuicpi^-MRMK7**<v2-3sNQ=#Lh-cXk?q0S+1#1Bwb7Y
zbzXo7Glsv?oQh|E4M9!JdDoVEfgX{rZF$qMsS_I*rGW^yHo48s;=1H2yso5iUF#_I
z<||dFLp8eB$i;Z at o5I1U?T9en@{E3Ri#yydb5Z_VlWYQdzb7Hj=3LXG{Stu#|Lok$
zlu|8ClA-L)w%OTP1 at Icebidp{M?ZyO2CuCrvM~3J89*dZ+tq**qzAas*uQ at qxiz84
zINBo&>o at fq;FqbLN@&^b6K3wlQFH9tp<v&=w{{%lwPIldRE>^~bvSx0qvlv)CZ+?}
zoi+v<Dgim;)g)>HPa<+p_FN|5bS<N&m;Xe))nxqj*)!xEfrz(irAQNtOy|F_J(I&O
zBaTk6=O at Hms;xxZX#<y+Yol9EmkVqijUr>l%Y{^iQ^t~q;3Z9}a9`&BMxVI3gVUve
z95X-hPBHYB7Ed14x7HlnaZn~@aAKKtq6NoHIzI?q(?nCd44AlhW(Axslk=-oHNWLY
z7Jo^7ml4$cB6gzr+X`6MZ9+Suqo8)L-GBL~rm=BO8S8%!`xl;=kfhvp3{ZQ9NVF)!
zVHrx{$<x34Y7an!9n3tmAUp9p=17p)qfjx6YUbX(6&)ms>oE>*zfES=nQMyQKn11m
z6jhFT1ijdwjg!lbt&5hT)F88c)%3r0yA=4 at Un2!nwc6iYt;Xs&ug1>hQG66?doC5!
zGuJm&S86#CZzp{+bkI(ggVXxdm?#K0bhG$h*?kvpcP5KITMl4K@=Z^t%FzuLlzcy*
zgE{;dwX%$trbTFtOmv8z7PaT);`n+5Y_v<8e3}0LX!^>yCLgeCX{8KG+5{2llF=w#
z0#c)MFh)p+w1NtVh?EnCbd4UJBHgvo-6JG6V6gG-|2*#lAAt}2cHdW=bFOpN6Vp!Y
zs at Rfd1f)QrHGY;P at 3IqtODW5bKRGDkvw0|gI7GNgeTcDH*rmHl89Aw%wwwa4oKMzY
zzDE6#rSrGh`=wPeLJB?$q!F2h%LhKlymO#>p&}JM(a)?cS?8NnK`%~6uiY<Ju#%_X
zVdnnak{rqWsMkh5uUtShah`vK=DRq<F{|3Ya#<=ZlLFRfr~{S-jh~LZhWk%NGF`~K
zvv*Dg=X_kT%_50Hm0cQ>CxITVAz}Id8z|VprPr?Ud)T0y+;eeDdscT!>~KY%_O2bb
z%q?Z&%@$ZfMF{K3OS5;x%jETWVQ}rAykq6#2eN$S+Ol>Vf-I*N+Y+yPyL#tyEC+qY
z=Im301DH?mrGPR^&OE6muruBdYaLHBxgz5-exF5Kn at z=m)_87kth~NlpFTd*J+^4q
z>vU(aGv{EtXX9=9YZ*{WbOKc=`?ZYASO)G3eSk>W6EnBYT&F}I#BB1i4!hKRh3S;^
z>Xi0~oYEwu)SH)-nT9j1cU990aWZk;WO3sIf-;9&&+EQAo#M+#q$rHPk@#-*#jbzV
zukF2Qd?6nhNcpUbwBFA(BFXaSsRPPt?O8Pj95A)AvU2SBXvQv4?0u{;|L0G<{7WN&
zb$Mpw4RvoJWK<e<NuQ~c;%}vCWL>D#BoA?u+W(xkvrh<F)UeVNJHCv**m$(1%WX#m
zQ6*}#CNgtZza_uuJbs}ty(?*!8 at V<7pOb_?^Sz{vVyncf^|Sv(jTO at NuQgUJJk{Nk
z^O$t1*3a(G{eOZw;65Qk<uO)?Wqz846IPMH+M(R at w=ev+3n3I~C(~XaVs~)#M3lVW
zc<ae>%|~VB!z9mP`F{Cz8&4wE&Uzg#TX7gm48ye5g~_%m><hf;`BfqFYUKW0Qr7jR
z9=q}ZY4b<M7Y at rr$>-x(3#Cm^f at 6Yz#lGAbc7KjDl)+vrT<@y0HS@~l at aXS@=#>Uj
zaR0|9{R6N2K`B=cy`6vE at K*R+^R?yI>wDM#%yk{oPK<4|%<nDUT75?}Z#F)HWcdi2
zh+ar3xa_ at t{O-s6GBFB)co0Zm)JyU-Y2mhwy?u^7rL!RUmStZ725ir5qG%8~Jq03F
z at P9fO6+yLHI_(4_I%}0Wai=qPGje at q(k9;N0fe3>C8mB3m&hy1_?!OP{gpORwjkWU
zuhcCVVs}5RZM#Ny0g)x3ac{fqqm1L*C%_Lrp<>AmM3?1koMLiZAZgeqbWE@#;{J&N
z5`{{zeY at b;mqG+xM`~3VYgqYW8JTXIn7{aABXYw^)xTtXFX>7A5|*+954=0<wssnA
z=e?W(#Wepf_*Kx8Mak)_ffX at 9T7Em>8nXQ(W5pM(x4*Y1{@Y%cGVa3zf{5N<72)AJ
z2xWaJRp3tEs&e_o<Gpu_ojaeV7ZxjjJyeW~PiiGboY>cp`UeblRD$_~+3nGhS!<0S
z?l;(Mm3{o}eQ=)J)UvWdw1(bqAFVk3VlT_bEXw?Z?EoCGNBkFL{=9X`*S%T|-1>Wq
zaA&D!+B at yiedgdrWYW4mIj`SI^ScPxpWsKyX>G(<vtJJ=gzHUs0TxZMi=O4 at bwqyr
zYoq6J0^k=bzx7L*DqAPz_Z;86#`u_A<sdgPvh9%DkrY0zlecr9Dna7-KKP;QWyJEb
zSH9dxl6y#Oxn-p?)Bcavz;V}^Bf)p8$Sa8+V`TQ7ypzvLCEPQk8CXp?i1|7iSsSVQ
zT<A)vP~=Mu=ES#US-|$`G=9fzQ`bZ?Kadf9toHPa0RURoKa(HEoA^6v%ORrn<XENN
z`j+>=BGawmYR|;&Cknk4a^1sI-#=`ajR{nC@($6I3E at AVH)AkcCxLKn<DiMb|6ZGy
zsXb#?g^!sA<kz!4$^Fdw>I*|i{<bw{(}CUh77=*3SN5Ud*T0u9N4WI#g#|bUD{T{`
z5<bZNI`1Jeml~12mk~rMhur*|bK|WgJB`25(P}e#PiQJPc>`h9RC=+UTE4K8`6l}h
zNk4S<$JVAtDj!}wIEi=Dvz>8QID6q`o;frB&j0N*Q7E(Ge1EgI6u+BRDbL=Mp&#+D
zbJv at 5p&RF2&fIpdU{qbi`sqLZi6XE})mHj5Sqf;o*|Bay<{rI>_a<=@$%?}QHH-3S
z0&#!ulYs?4uuzj4i at q|!o8Nh0e^KhcPg19gBVG(ubvihw(q$}1OsjPlvzOrtxIaZ%
zbKMkz at lzL7XMTaaAm<7r#*=jO_Ej_2-!j)Y7p456GA>k=%%?tBsswWgty^CZ at ak$W
zb~xxY#fdz{rKK^uEH}&f?OFdlv48kG{_x4LyhzHvlRnWTzIM)jEm$v5`I08Fz3L^I
zfR^*m3kA<|(+ at y<w4_fX_K#Ne^o=u at d+W!GF)X-G|JzwWqB+ay*$G3R=`#G^BnO0c
z+5oNivH<7uFYdhrrO~1`%1AnD@?7Xz>O{mY(|%*fbEA>4C%xYH-uHiEYBc)G-rh6x
zs_)5Iv$6Ll%U;C&@7IgP_R^Br2-bw2f$4;IufOpIKAL&wGV?Xf-d+f>#O};>qWuD=
zSl55$!k^@HMU1jOfeB1HJS2Oya&^H7^dybF^TQVJ((87c^OE<c@$%ou;H^+8DJhvF
z$`jJ_{05V2?qGke>dV;_3_d7d;sAkMY<^(KRC5o0cQ^dy)br=yr$BOhV8LrQxa7O`
ze6V2-!VRZ3 at g|3P&eS{){5-#s&KIKcDAI`WVffoSjNg>3qFadHpgr#3utR*qh;O-x
z+j<CU5lwh1Q?Yp25VM47ie8f)S$jFmx^9%%CpnAcwlqMSR~sKlc2sy6 at Kzz`7`Y!C
z7TJzF0MAvwQjn?m&aw~F|8vyX%K|#gWIdfdAnAK3F#35b{W9_`oF|r*s)XKPWc<3G
z4>O~C)5Xio#8vNQPq$aDa{JoangDfT=z=51&pSF;7ntd-QAHj$bDL1$9^Xx<om4}c
zZg- at xz^5tIzNpe>&X`HfOq!+f!VQf9Bqd<?O%T>ybk-Qy=Sn7!G-a{VAay9-o>ng9
z5p=z7q-B!E_H(nDm2PW@*hL$|t_j90%iFZ^ZOKIMDfFlDt;7BFGZbOg`qEW~PeLhU
z>syOKu3yo+BTVGy?Tw7J{izI{eN2Qezx<cloSVMGnJ}2g_r%p4OUCWb+~VM4j at WGb
zsy8^Z{m1#;sz8fy1;yEVB3A>ay3Hk9ke5a$!4wh`<^xHpdSb4Qs;o$u%0C_YN%A>N
zyJokU$#jWno%MAz$sei8caX{ll-rmagea=pncfnH=7N41$$v=mgga%|=<b!A|Hu+j
z{BhUd+kIxi&kM4KUSre1 at WP(2IG80#nVVXbN2Z&~?uvbd0{f7wV#*Wy>S*%PkV1|T
z<|a9 at FB}^h{r=Um(`YX|Pmf_oFwBKzR5L)uZgyMua+8!ojBP at Gl)gahTVl>mxK at Jb
zC+LDX0+bnUfZjPML0L|>lzB%BK5}_T{bO>uH|oV>kr1Tshm!X%WgeB3SMHU5{3j at t
z>QXKXL;E!G=h#XNek^Wl<6)p|$2SF=>>*Xh(JI#|S5vfRen`Y)2I at mccjd<PK}{?6
z0HfN)rC;tzP}hD<OMBjhiSa$3_f13%E%Va3W5a=hoayzyC^fXrNXVS^CHf<(1Bm{&
z49?(y`}$NMkH)4NL)_qVs4^tn)dbz$2TV2bxUL&9dB4rChze^|OBOZ^cc;P>Q<HWN
z^PK at Zn((Um%L~l3u5daEzzryuD6I_*rPyKSfI%)Oi=nl0)jsRa^5n%^&2OiCth_tV
zd?@MKK5-ID=pQ&}jMYupZc2&sv%M6F+Zi+AGk{03Mo-f|=fy)|A>WeXR~kN;QCp#>
zOe=|lUni&hRAV3R9eH09 at bJawtL&A(zsGMn)HGSvF3L5LW{`gE+uWIv5-N~y%qn<N
zS^siIsb11dd2PlUv1(UQuAd|lRUf>{&M#(;B<?)4veXWwR*sB}AtUmFf^SvSyeL3j
zj`Z7m at 1a9wG#4t^LH3q*876k_-kKSK>ZR}!-{~omDV at RK+k@uOnKTO at ffxD@_IYv(
zi;ou>tBu$)?CopSgoOku6brV%GxcA-S*=ohj{jKZB)}+UJ_}6w{M~wPTKp_u?&G7|
z;{T at w_}vj6(LYIrX-qG38GzsV0JT_yKMf at DgwBhTjaD^})RkIfJ#0|~TEyg>ID08>
z(2vl`TltpDl;?6tCeY1WQ-))imV%l?F)Xd!2i0v@;`<iJ3HJ?fgQI&)&{#wX=IE>p
z*|X4K!5wzyh2KtSuz=xiZJ{URkL>WDP(rAkt`2~lbuc?t`orN9`UU=kgoL_zIh}jy
zH>w)movXBDr+XuQeaWBtU2Ig*r3~u%djo556o+as<m?gLO_i(%B+c^b<&cbY6zk(X
zno0}gdH`E{9Sm3z^-~U`q at 1;%Z0YSdpHc+XZ_xX%?n%IM?^L5(Bj=W<$M^X&k0LKL
z_J88I&6w;)STrQHMfGxcqh2DmC?8Rz<C$4`4d_9SjozL3IPRxoAx>f0ty-4Ab2WVR
zRAG_U#PR_7_2f`fekP3*?r!x(e4ak9H$#5mjEzm>*FH0eQITSkZ+Xk_Q=8tx5GCB7
zl6-+TrP3+poTPkA-cV(8V{`wdweXprJo>uL*gO)gOWhAGjl^{4Kj<p!J_fO~mq;1*
zf?)TpQ)Nm~{`MvMk!RTg8>eP<YnAq{uhcLK)o4#U0zHhi*I{VdbPt>hu5}Vzw~*Om
zu+Q(;*;`$;GZYCNQ?AvEYu+W)^$DaL*oci;w$Raf7K9cZ8Y)aS2c_Q_hP%4LQP>Br
zVf*D_ndoCMoEJoe?%V0WwW_&>EKJF~Ey_V0ShWHDJ*?n*7iqB=_R!fK+%LW0T6!dK
zWcW5#iEhjA`fO*S0E!=z56oPN#8{Tbv0!A92$taw<Xj}BbnQ!-S5yFZM_4cS0*4)Q
z*d=3uo2&vM&mk!E7_5}-r6h&Er6`s7m!Ih;mRq at 7Z<&&JW at o2AGFVN9{t1Q+DbiIr
zasT|6gadD>Og}cMy1+p`HE2xV-By?L-rJnk1sNO;1u|^B32MNzOr>1T=jUbzPWg|J
zx0R1@$yJ9X{vbXWWe+Q@&-<w3e*AF`sb+0_0iV&vH`wHVEFI_(WM8mMG8 at gepMVsL
z4`^4DH4QUOARvN1yupkQ0)HH9g=9II at 9Dy}`ADqrit~TTb5kT~C`mir8S%zsPqhjn
zeXC#TAW1oVxl#lMHpORRi_0yWY8$LO&Mz)58Us%@d3qs9qm)%~ACdyGzeU(j{;hNh
z9L=ul8~bjb0gWZq=Z%g%9 at f2FD+E>v-4RvKbQg4wG=58ZY1xRF?&*5qp4u0s^os<7
z{EWXmSZFeLRqkKz>gozwi<gpwg?M^a{LaLjQ2@#`#F!g*5c%}CZ(Bc?s&-W~LC+om
z3$}u at 5X5(~?TuN|b+9i+((!~a5ryGY2&iv8W!FPynAaiOuEjFp*Z)9rmLBtsvrYHC
z`hYi=)Eg at Gtjb;GWZ(`ue!JSw(_n12LsSkt>W5X?6AgBMbcH<}!z2+0zxdJIWuocR
zhf_g7NG)=1 at 8|zC$Gh0NVBODjQ`QAb&+af>xt8xqbKFeDqNW3)*|mRc at 1HUDo(6*w
zxG*YTE;<tt0{UvJOlfC$p3_b>Ea+E6+(|`cati28apK#WCaZ+x--${jW$u2)P+dJe
zsg79O at ATe`j+Vv?v#Y{m%qG;sJrZ at W@Feiiqx4|0rRf%_EBqmSoA=hRldd{+j$90%
z5b at 4!)9KdW-XY_Fk$$h<+((P7A5QJPzF6QGLHHZWfjMr#esD@#$+XQM;GOq7 at sAi(
z5C{xOY*Ie6 at BYgr`(?$Ves-{-53}T2-cqYVS3GN!(td28X9QK$81NP~0SMUe-vN6K
z9$>xqf)2!rvEYa7S-=?v2+gMNFDT&7j?pYovb?4&(_N(6+ua@(937z>^9ee*7w7t5
zqPenEwxO%(W%dx67#oIpv{C@@;n3euTw3_{$jQlx&hg6L)m2{KxD^~x#$E1vvJTG3
zJp7F$&NbKLWjP2gc{x+-e<tpwLRZJ^XsPSc0<^b0#wTQ!*Q&HL3Lz+Hz3^LFPHth>
zl6OcY1HGrKK$3?Y+SPSn_8B&HGda8;V%hVI?Dw<fjFpLo$>P at lGge;5O_?=+R)V&_
zPKH`Rix(4nWjfspUrD-eZ1?3tuL5HGuOEf@!la5W#tZyxUsV>_=crDDQ@?tMCR#ly
z68;RQcz0rFr%+^@BriBEb%*-jTu>+Jt6O{B!%o|^i|S2JC6gP8#q^*Blr*EiByrih
z_x#Q_mR|w_M|8AMSXS2`Wn&o(P70oMQjh)JFi%eBfkt%ua6*}w#FiTQ#idE(zI^ck
zr42LcNNPd8lvRzoK31O;_^9s5_5krHr^SYeUCT6bX=Y*Z3 at S2hL^P*gbSICn>VgRT
z4TaW7lik(1N4{nlc6xraCQ#YNmZniI`aD%ew&{R6bANY^5`OZ*P7I^eB6x;^#Eyh4
zLX{P&pMHJ at H}135;hwDiLH7J?y2 at WElj}rau}?sf!70nG&&su1lMuhJO<$j%-_b>T
z53!LF-0bqwcYkA7%=@f+DrgNk)p+f|J-Ann#|X6qc~>DPsu6^_w)gh<zVgP_(47PY
z%eJ*Gc}s;|G8S~-OiA6Q;IL5bcXcE2**Uo_&1v5<ZO)ie{*op9brWu#_0u$?xgpz}
z)_natd+*x8=%uD%5d=MTe{~<mSEeR49X2US27M056r;4P-pOHfCd+HD+A<9XzT%P)
zHk8bwRNX^@ieSi~Ah0v>iATn8<}JELPqGRT5+zyW(RGa5raMp at YfU>h4QkClU6LND
z@|mjBfkyX&*&Y^hnsiph0+7?bhuG1(YnSs~Qp3Sf^=5ext05;eWuftEW8L at B#Y>(C
zUUo*^iT1nUsST-{4yoQ^XO3ND=;Q|SIZEZ^2fiD<PEw-<Y4AcLrS#J$Wa;ifv)q?K
z;U)t%8P$7K+0otk>dDJ-F9d$ibgG>d at q`;iNJ?w9G`ceyndtgfQKndas`FS{ys?Q`
zL>Qko0HmM8HCbOQqkW6)fc#|`zb&Ap_^&~M^_?I|m9&sdrqpf|HD;N)pYbl4j>n^y
zGR at S-kZh!~PK9I!!N)$)xL{-JMN5!}kqGEIo8Ski9nyK55IE59t%Io}YJ|||+ZzV6
zZJ{UNkY(hCRZ%mss@`^d<Lw5&Ee|ja+q-UP4PE4JttO-rKh3h1$b5ED63F$k+33s|
z>w?vb6UD2EFi};fS3`<9jTSrR`%^PQG_$0o#C~~!KziE%Bz4Ys<ZsQnD3!KU;gJBU
z0^QdcssKx<ot{4*R5?E?BfM7eky>r0$>&*u-)_|8Kfh={j}?ZYxXE5^;l)e0FK%I7
z-Ga2{kxOT2$ZpGAf!_1?Fb|mAR)&+NEl1M2-Ho9y#p}t>1V7QV-S0iMpvm@=xXMJ1
zfy0B_;L?8-jC?2WNO?HjkaKII^LbHr-{jd$fMA+5(Y*TXU}28bGMR-JRj$FHXArw$
z7QIV#stEFvZqbUJ65JI0>mstJyc;2IN?}WioKXt-a<O*I=j1(c9AQR)+BFcQK1Na+
z=%{viCEo^3<Tl&_Ca1A?lok&5J#U+e)^>}ejL=O%AX9WZ=~~bJ3P|4ZT2U21%S8l|
zu}T+E2F^+i<Up(dl1%`vId$#26lNgQ!F!hMkLIH6)vpO-3of~!n&FWVsfdJ#;hNga
z5T{v(p*Jr*avx7av<MIwx5qhAVvcrvJlysU?G<vmAM)hCAvFe#%cP1yOA$WLp{1^N
z%+WI!#PE7?Dylh~X78gRsik>Rw^iscAA`?Is%Lj+%x$UQBjVR49v`B?2gmXHF7hN(
zDr3i>Kq at j$1 at n%kco;~iuD!<Q&6TZTUuYPB{_>+w^mAP1nU(Te#ksRNq1Ww at KV>NU
z+z-5tYd%Q6Plv&7mBN-ros3C|kNoC7a&kfshNzX!LD=-22DLWLGda$c{KQBA6Q at fj
zV at q2w4J>)RcHFe{pllkjvMDa!vLr9I*fcawhjp~&liE2vTxx4$FfVR9z!aXHTn6i?
z4ghmTwA&YYy-c`SKX$2j3o<|Mq-=(!#NJn*+o&$fay1C|IoS0Tqi^buauR<L0wlO5
z{R}s(u;{ikiNW at fOes%i{e#yn&Sn#DxCd#oynbRoEH>2!wzlbb0!^TN#g8WZO9m=d
z at 7?!Hnn^Bt?)m(ax79k6yIJEq_dOm2L{i1;afRzY3>qcHc7KR;eFUs!)|DTog?3%@
zC5A<ec~|pSu-CAqZ#Kmwxq`j4b+}IF^Y(SzD{Gp5c{<HBo>@2f?YjxgXc?ym?#}{Y
zrx62nO5I$b17ZPPA;F+fII%D^(boS^-s*Z^D7aaEEom6FQBrYZspufsU1uWAMU^q<
z?_k4ME#QsRZwxjbaVCo-(@uCj;s|m7;lx8SPCn##wG%XAX5^K>?#M^d2twUVi~QAi
z3wf>oj`&{%Q3LWbu!^-$v=-cdkNS14ng(YHm0p;uP;!O&dEr?sC*6lXUw32Jn)-eU
zvx4sh&w6P|GnQ)6L2+4SR%d3q_&0XfGs1>JxXD)YqjWbtp8*>7=R0>`&e7rsGuv1E
zvb#AnHhIH(At%2~upq|kX?qawP^plc$Z0tB+h4RTi^`~lVxfgM7B@~(?jX{=71wY~
zrj|rwJgqk{SGC*oXNS*icZMI>(0O)0+&?SveKQH~g59VcY*Jb*8w^~6i+v<&6^ZHA
z!Rv(#GmcB8VjrLSsw8k1i_h_hM=7!x+uMtkh(7Xbb^9~&QIb8rkJES?MY(?oudmTC
z{$5V)e51@>gGwE0>T{!s)Ewy^wKQd~2L4GSgx8O-fjZdlTwY#<qHA8jjQUCWw1$uK
z=Wb?m<nzyw*Mka#m}=|mfoQSNzZZ>u&9 at ziOCiqF(!>?+TZNQ*zcq&QC!D*YwOR=d
z3$hJCOT3I<6BhUR7z(S3 at 7V1B8l(2(VfPIf*Urj%tSH+>c*;VC#?QTWUn<wdcE_``
z)84`JRV<=;_P7*6o2O3A1quL+e3Qm8P7~<v?k``MU^7u5>}WcunQf`i5dhx>G859}
zyZ|VV`T9zYd~n+ytK8+_k5X9$1?&GB2zgLasC<tT93kOnYuM4+_cv0}jH!C8Df!Qg
zwKL`D%5H^Y{q$k2iPj0v``>2alhwkFheC<wkIeU8O8i|JopJEfl!p|$bb%yg4#S|@
zPb^3B?dQBZv{SPScO(Sk^FD7UWMT)XW8$u^I$Fz4UPHspLKm3cKZv~0EZ^GNGRF=i
zAJTHLy^#>b0 at H^rTihL<$rbAi9#j$Q;%4OM*0$nE9INl6iH1kGACYB|gPN-of0Ysf
z at kdMpOcYI{PPa29sjH=iVl5*pT=WXft=O9%4MeiCc(EpKS|&AoZ)PwL-KTw91M+*U
z-aO+ip<d#!2zd6XdUbWhpIF-APT79=3^PT30L7P-`Cv<t#X%q6YsX?9&K2TLC&Xma
zP;Y at Q2syrJZ1wor@L%P;23Vk}xVTHLPgKg`3b<q`<i6|Sp=ZA5&}+9~kJIPYspGPU
zETQqfpQS%W6xf}p`<=4u92`30+{p7W)u%=G{IFz+(xV<4k8_6YYu{|kTD#5#mMCg^
zhYKsWp$0EXfj=5NAfV2F6^`fqPQUFspVJx&D->ZQ$)(iMv_{8wa-LLJT~cADz&3wU
zRwh}=XWI%d(_2hSdwq1JjIq|g*wQ#mI-eU`YL3o<RFiH!WiT%J#qtzL^LFyw?{K(e
zU|@jGSGx|tK)B5<KM$Tx4+ToCBB3>nGarn3zKiq>+wce-?IgKhj8frdUCZ4ft|5N0
z$l~pr$jdRu@{CfjGjN-(vE?mksiAPb`{Tz^E=hBs0egrj`0ckPUm9ZCAHy5JL&=C5
z;FO&Uhrm7%i42qJk%SinpR)^))7YvmSUEl+J(Qf-UCh^Olyf6uK<EGU*wqo{^`U$X
zygw0J5{PN!35Lcz^(Lzfjbi(0cBKEoMNE)vaHh}*svb}7mGtgaCUKCpk<N4jrs%Ra
zk;c=Hkp7b-Ma8vbRF$PjI^}CEn6c(d2B0!#VpCTdn}O(_(7i6)-{4?|a6F<--s`jk
z5sGG60){OQxR-UFRen-+YX5t4e~yKP1^r+98!vpFaR{LyE4=Gh9(HwpWSrCEEG$B%
zIq8?es9hLy)7x3(g at ks+602azpTT-M8IahUk@R5^7lIKKfQATFB7y#giwl4xZrOl}
zsbS at e5+sr`0`U3c{-pABq!LO@$0Iv_h)Y%<uB)qCOPb-SvgDWtUqZGNC06d*+$fzZ
zKQ9Ot``pUktKIZ8lX__#DFaP5u5_^w2diJZhEGq6yVoY9QCk0``#7Y1Rm)Q<iLtEo
zW$W=ge1Bk7rm+>j|I`VgwUDmy?-h#{gG;0PTYyp8M9glI{5}=pb2X^@zrNJ*;ea-z
zO+0;v$*Nl!RlT_6fXH5TFygnp5Dxk=DH#?Vp>8j+V`%s-kM5AT%&V$T^N7RQ_vK;q
zxmz|<%4jg0(~Z)PsL&QDKj|LUPPDKN8RcJS)X<!xDRrG#Q2x65Hhd0b>YJvNJM)vL
zW|*VTPn(Im^@Vg{Us9ZCw8mD#G*a1L|6vD2J>Wfn|x|Az!G!!zK}_v_u}#K*Hg
z!DLA8HdIFHxRMsV1rd23NUiAjyVC`1I|9j at yDq&vnQ9h90Y{MXX?S&OHCKFVo2NHE
zy}T9MO7BcMleCGJc8S#6HM!s6;1t~Qc^2zv#$Nf{LC2!W&y8$TYmzcRtI+JCZm1oS
zHiJHigW*S;0i85{jLoSZGEey!0#;Lp&xfy*l9Do1^_+ImdE;iqVkXn?B;zO3U3XJy
z at 8xayQkui7T2w%u_m$sIIwI6T6QLeFcNj|1I50)NCXB?hUg~|#z;<8d&h^sASkTlX
zy138t|DuiBNm&o&;yoeH&E9sA+luU@$ocEk(Ee%m?{Vrk`lDc6qAfd8`z$6j&HDL}
z<CoR}tJHVQ-!`icZ2Ilvco=WIKVI)ksW7Ad#t3aSrye_%Mn#rql_;t}iBb=*3!ie)
z={KW}LO+VR#&dXVjN-~EyLI{>fT^q2(<o~N`1t{GTh1;<vzcXF1_P&NQvcF2ybJCR
z_nBtpOM+8Qw;bL=+O)`vh=1hHb*FKtp(EHMUWaBz8%cZ!QuZCsHV>hMD|sooUGrY2
zKR at fRlB2av5~!BfoMLOXX3`6($@SfSPTqn-LMRM7${KK%4cekYn}p%2iKyspXN6Uz
zt~JaG-E$!nko(dHf3bAz9I}YM+`7JN9Sd>|A;6jttykt>QAaD6hXfydG1#{2DYf6V
zq?jPWicb6b`n}xMV at LDdkOL!1eNn3HH>rcC9A5|mly7)tC=PpidPc^efKG}ZRnPXS
zr7B^Q6&fV7jwy@;L$pg*!3Xm*BpQ2tm&|#4qGbSkYbh<u0|KrsBS`N(!-Nw30ueDJ
zrKR!0X at D8wb_jX7q->mx#PB;Y4S0z6tst0Ag!<XU^!-9 at w}2BcWgvxZr7>>b*fiG=
zJTiaCz-|l&57+Vly?Lmd4)c+=-l06d;ihsZkdx$Dtg1cMpCwD6>IYfzgVHt;9RFxK
zkWy?-rHkU;c=D;b&?+jkVrg-`L=4Wxss%Kr$cOn!zDqvpS2x88+$k<CC^3WCGCb>O
zO}}(WMDY}k1gYNCb*h$jw{v+ at Gv*F)s)kGZQAC41XC0tYEp2TX&|k8B7PE|V=6AtL
zvw<kOP)fj1Y-aFGT0ok>+XV>ix9as5%Qds&mIICb-9Cq4hhI`DSC-q3uE5 at RNzlh`
zj6dIsC&<cz%mUe-{;>GBXq|%I1;e4duJ~fTB@>W*cEn(hyx9_gYRSU-+)zm2{m2R!
z?u+-r$8iU?${z)A55E6f9);jikTHc__8gQF*TjG&Bj>+DhHLzkMBb|C?$_1%&|NF@
zU~-a@;cV;*v~MsJmW~;&9R58mj0FUq|68FXBhSBdBYvdjj9cP=c)<Q+IUM}#(J^##
zsQ1^orgN0Gsbfm#Jz`dy5dt!HM0>6YRw2y1mB&-NPT+qn<<F~$(r0E75nq&m_8#1A
zJKM;^S{BQ;f=ZD$Cuh1QH8Z6(mHG+`zkbDUN)#5}<E3;SmSS;VXhd{<*lpMYKUun@
z0e}@&(6v5hXg5u}v+?R%C(P~Gz}@~ovT}2zJ*PTM_x&ivB0_Sc*!h5Lh|Z#NJ+?R|
zRtoD0Rn$Q_CBQGnXwvPowy;OH(!bV$fjLNA%iH%Y{J6KV+CoQtcje^e7sqc?q at A36
zwUWr-pX4@^ulboboU^Q?R_D?-&okqYaEw~w@$#`vuS_G784<dR!Dk0 at b$6%Lrz(wP
zp0?G39>U9)mh8Z!BTg2xWV6CziFP#|q<ogrw2{<`bKmkOh6WuZgtRG5{c8Oq*fo^)
zb5rtKM8%LK6Zo01LLCE6=+*qpy9>vrVL>Dgu5dXcLwR(Ge(cN1Wf8L7zc2+vM_!j%
z-MN1ebR9~9a0$7DW4b-ULhv1j=IG^bhv!=tWq8c1d!xTH;27!awG7PO`xYTS5D%~*
zYtg&7+R@|@szqMD&A7^-l&N{(MQ at 9Nv05+!&R1GL4SIU@*aiXnX(Kn97Ck-K at K!Xc
zdAMl!O^KQ9{iO8WD2SNNooCQ|@8b5-!M6Au-WJU(<TQD7rve+D>1Q-;jafs8(_Sa&
zaRC3j$ah6V6#NoO#9ko>a79hdk`^G396v<*UFEc1U9;uadV?+a<P5FPDwN1hGL|_0
z92yTk0IULO8;B^Wv2|;ZA=cw4_N4665Jn^fuBEX(DZhD^=Oxl{4=Eod>vFyk+wv9#
z|1QWXA^C3Q>*rVdF8`aBvr8?N-7URxFE_sh2Wp-{++`#4pNWAvo#J4BNR3Hml73|<
z?ui5-UWbiM?A}G8j2S|2c<k?1ke62#$%v!N;O43M)b;d0-p~yA`!JBQK1F`Rnau$=
zKlhqOd{fzXafr?e^>s5j(*LrzW^}!W8XMBa8NWeoes`>KOtC*O=Wc}kM8sLPL_uD|
zY+-kPFp9Q)QHwK_mzUT4{d%gPeIpXL;$cy0eUzk&VhNi<guFSalFxNbMW=@1c5tV+
zEy|)MIx$RP*RweOCBJ&Xghe_B`3tp7xHVyI7{yKmeLTYOeYjfG2udgr?~IqS_G`}M
zI5;1a8b%&o6tSSo3GwV`4|xmp`kF2(?AXNwJrXu_g!{oA))>0lQi37lmNg5*9cGjs
z22@$W1rxX{3;p2bmt{Ga%j at wWjCCkB=}hkzR at Y9A+NboE*ky}kaNc$nqcF`|BYbW4
zJ-Plft at 5AmuZ5MjzJ!ajy#r~qS+ZN3KYOi!qL<F{Q0ac&6}!Dwt)e`w+apzEJK^g)
zd&=DV!!#~_q9u<k at ttT?O at +PB<Dv_rCfZ{s^z9O*#(lq;sDcLr4!`kHkm-eL=vijB
zNzjGhJiqE_^8?8Cbg{=z?Yz$kxddK*Pl!3oPiNnqfVp2LLULqx`F-X6llJ11y6CJ?
z>q>3`U9sJ&^DWh)3^!|wa-UW)_gEB8 at XJ<)L3{Tg=3RL)@UF$Z<a>Ax#iD;f*v~r=
z63_HM5s9xm*#Cy=_E1)e0qEH7y8i69{s%fiZ)q03^i3+)-zP^On{dwYIsFe;oZvNH
zFnRs!*DuJ6^HQgVyQdfL;y8mb8m&vuU(*OgSVVlQT^N$kc~m?uE;Rdk!MQ54)@Qfb
z*$T14xXv`s__{X0eW|r2-QPP(&)z<|1ERsidYkCTW!N;OeCC-!xEg|LNc#*0w4cs{
z{(0PJa`}!uof&`%$XTINuRlx>o%Q4?t_`euSkN?~15p^NFzgPleWe4p&3y#H7cHH7
z;>%zGm0*TbJ_X`W#M*YoaLox#7F$%QXjBN+9DO at vaShWH)_u|V?jrK}a7HzT`+B|r
zE#}^WKTJxHwro3OQLwr`DG#U$o$pw|H7)tphmMcDuW8+8kvHeAzU`$@ieka<qtPX;
z``aN53VwvM>tK54a#<)DHYh at MEBn?X5|_h3?A{DzDQH`)>x$HXU5ur0`i=$lw?6G7
zeUQqe=$xTxM%d~0m@$kMp2y at k!c1SymrLAr_6##h;+Ubv1GQrg9pI_l7(F_VGo<wW
z<tbLJ_jz!?h;MT5oU+8oEVfiY&BNAB-L)VYgdrsxxa1F63zsL06!eLSjKsp;o`lKw
zxk^LQhlDpWM$3{6SJjy4<i=ACTRt*Yw+`PX25u(9w;VT{j1UvseKwn>xKSdE7IZQs
zRTotE+FRdLwke=Ls)lT*v{(Ho{gm&q8g~GRK5K-$KfURspcuWEB7=i(d5UVD-i}Ae
z;bO}WIRF5deIL4J2(l1k3#m)@4_U{M9Y$yhpciZIxQov9bko(+HC|s6UDBl83^$s1
zK5-pKxXDcDqQQYFsi~<WW;YeypL-6R$!2_V++yvmdFiL$vu82aT>RZ}(kg4Mx#S+|
zY$Q54#Te9`bp!RaN55^-DLv7X0kXLLb&DsTD&!iwxWR=6BRO6`9l{|wMr7Mn5}+-R
zkbwCXaX^5b*$*T2F4s>mCT%+o2~Vu^(LQj!%Xu}lRI6Wo=mN_kG0qKEhM at N-YdhCE
zEEgh_g3w`?F?C1<*(Qs&RTg<O6YD@%{Jc;@Yo<k+?^R_1T8I$r0Y3?gKEYmW%=%=t
zH3D5NIZB1_yHNC5XxA8!$kc9}m18#A4t(&_LT$D3=VX`TgE8o!({r1Uj?@K<uqzX}
zAnVge(OVcI=Rx;|cFFnkixx0gB;o7V9v#8i|I-3UGXLFQ$Y7$ly_!RsJi}0WW-PHS
z<rf`8Li;w?(d4eEH&@Qzzpkf8mU5(Y4giy-_a{T}Q0MYC0*+Zly`lx#1pFjCm!p<Y
zdv8FL2EYrCF7nX5=8)Ha%t84Lpb&g#wg#{_b#cgg;9U)V(4rZ4=RPV$CgYQwceb9+
z6=Qzd{zDvIQ?S{eF62Ai;FmAjS!{hV34f<+1uD(9V!tm}Bf7<d3?w~$d}<Ds+O9be
z5bS+%p56yJXR!&IZ%c;2kX+Z<)Xj$e!T$(S;{22{mmF at ib<6ibHBDgB(+YR{S2Cr#
z{w3j|Hx}*zX&Ty+SM4|Fd&eFS?_bE{@bMe3iX7cIE=sAUd0YCe_$GwRVVJ5Lb?ytZ
z;3rS;&(W%4C*y6TCr*qt{E|>n8D>3Bb*OW!CjAy;skyw*?^+EBX33DZ+MwEQ;=P_s
zt(%=wRE>%IV#?6x6cmYm_;iSi_^93XjdUG53DGpJe?W<0 at D#0Q2 at j^!Tr8w#Q2qY)
zYt*m!-h6?8WZr$6x$WF1t)(bL4uVh}hVE<hb+gV0Y<RQ0fs?q#ZQ#_F0z*Rj{LAVP
zf>f^fjPjPs)}6Hxq+W9f;%m8esrBjS7_?sKL|;%42K(8Iu)vEJ3jO!b`ek_N at u>|y
zBh0hrB2&$S6YgP_ie at M~-0F&{`%#IsCIs`MuW?~|$iA`5$7wqpMz^z6Du%8}b4gaM
zgl1euXcj7p52$7b-An2q<#ok(RMZ8c7 at b%dr2R2-M6<bPDFANDidE5$_iW4z at KphR
zN#gX1{*Sk|H at p1Ivg5$sRBUGaAzR(wX<)PHOO at 80C69f4L>NCHW6bH_<pII)akZA;
z0|^L=YFb2GSxI~b<tqc~DQi8qWNqH4?oFM at z%Xl)8UaJ6JEjkEr<bIcJYaN9j+Z`d
zl%k@>xT~U-79!=Iq7&38UgBcgvX{|hQse?2 at h4iST)r?B!l9}1eQ!QFs2UUa#wS`s
zc1b*2sH>q?`I;j6A8UVcwXKiW(GMn*e~f}kdB~$ktZo!9w|x1Q?zLk^qRE at HV8&E3
z^guT=PqtT*nqQD~wtJCFCMiV<qe7uGj?Mk*>%sO^+ZD}RwV~MMQ>~viDI#|7%fc!b
zRHPE(+Ske at 8y__(42Ku^fdwbqo4<O_0CmmXU4q3F%fwxG5OkiDqF*lH=Y=xWVfsv|
zNa!Q=49`hb2 at k-PEC*Uhyh&s33hmhP->4d=2e5`+r|Y4D8hgGA-KK5^UiZf%bh)|8
z3jTH`jNC?^Sy`1O0L;+K+hBY}R21gl>GHzz1{i+${{258jzJ4c&eDQ3N(;{BA$6Hq
z7Dstv@)d%RbB)I~*1ta-NFLmUW=Q@<vMwx!5q%GJy1K<`y;WOs;+T}6ObkV58TJ`X
zV2ICC8m+1G1~GZucSss-)ZWKO6zZGdcv(QqkXP)GHo5D>94kuN;a*^BXwdj^{tKn6
zRn~I-Ka;o3hD6Qy<f~kA&sF!NcMRDGd*gbCRd<XBJ?<FaF$qUck2vJX-K6pPtJj1R
zDyD;#l^Z)yhr=f|tYNyHwl||h5j)07PVej_BUzR{Ci at 7uT77~&&wQ37tp3*h*ut?}
zbc_)@c<g9nrqmQ}D4-1d#B5Dtq}0S=fS^szx(d-jGQX1T;+u6J%~#2sEbqfqU%eDV
zlZ>|qg?q6~qf~W8+MsDPh&~}b16N{2-<oC;9+np#U!8rDm#Jg&wGb5A8d;t>R0^DS
zY(2K7>fKu`R<DXLYm4`KNyd6nMEz%ena%;2*2FRMVh6n|BDV=W8LFfYFZQ}PlS%Pr
z_%UwU)fE@*-CD`NJ at 0tW_L~{=h;};R+}(hkfYzdaxd at Omg<X4RmcdSnK*1%OsT+*|
zi=`_hP-?N>H0XGtArv8hwCstWm_U>X(xViJ2rYO0JA|ax<v%dK5LHIF9%=|#KK at Q#
z<r?y at qXX9&hQ~EtaFwSuCh+g3<iC)UrA<7jC=I)88qQ{`BY#HW%VRL5tX?^WkWiE!
zSytTic?)e>hx7*!BR#o@@EwJ)o5Bj~Vt^@PG*R-ZnuZ-~1`daFnEDnL-!WyrbGXZ}
zcBvz3LMQrc7qgh7%A at +3NICWlwW`KOTjCy;m;tq<kj4;dAK9FO^u%eQpnz1iWlzUL
z1!?IS(V*Q$NVNO)-)AvnINIZ&;c9`;_Dv->vM52TIXlR?Lqk6sSlU0Gh*S-*BgHsV
zXD<)9j`l`S7UgY{ae|b<Clt^;$udKo!7L_nCMKU`sIMQ=S+kYYy6)dpF;sds=kJ>e
zdn(w`__TcS at XXxzle~n~_ZlUgX9EzdRpk|nUR9rapl9P(1PNMx%)?b#?)~|{1}9_6
zd%Ll?eRr?_0AgxwHg at Q9OvreSIB=9r##Oyqg3#hFVDxlwbGozpxn+dznqk(- at ApXa
zPvdm&4=CH+4de!1X2t9IXv=LPz6<txFM@|&Mk&VMt5K*Km%4pNO2ZdKTv3RGa*NV?
z1zFSo9TO`(EDi($6$Vj9M?f`RS0XPmd*x45_q1+%aKrVkK1^Wv!%n9f{c4ayXcP3-
z^^XEHL+k!5ZdZ*8eYLZKQ at B2w!b!k_YUK~QiNEH9kjJTIz^zY3QZMV*TS7U at FiT+@
z at tDn|DBpivp=kzj^R5%0duQLQxhfC;{TA-aR;TVEwPO6p-ykkGOfTpM;7-yYAlR3i
z!pzuauiae%F+4A<4C*2V<J84D{V at qq1-<_vRdgizm$v3-ocO4|y*PuHUARkh?(eU1
z=YUT8HFZuc88oXxRK?7zg4doSwme=_%dd9~zS}-vB&0|Bmslnp8IZIqY6LqvQWyzn
z$H at nsIx~c;wV*!reNi9roqc at CF=a9r`X_MW<;<H2EE7RyA$|Yp-xSJvqaU<iY1-Ys
zw=z at SATf~XpX+$LQt6nhm{G>==ZuPW_ft&v65CG=&LWjWkWtV!KE6L)cqo!%)5#kp
zu4O at uDZM{qD_2R_`@N>>pqkU`1 at PF}O*D3<?w|Us9#&;As``!oZ at 72rn>P=$*iR=9
zr-j8pw=Cse2x0MHhgs+5CC!5`3r;yxp$XVNYSs*YxfrX|B-Xmxv%@Nr16IU0CyAnq
zrIv=i`37$ge?^t1bhQX^?u3%%zRHXH(7emHDRo(+B{QWuT0NE-2uJ9`<bp<SBybbD
zH*n>leMuN-+c_4nVB#!K%X(hod)YmO+xu at PSm$k}0hV)flwPll5MldGq7I30!cA}v
zA(V$y$X~)Z;GMxNXhRRKvLynjyxb$K3b{dCDpuQkTtha?L#hae*ULWm1 at 4!o+`f1)
zzI~&ku`x((`a1it#Sfvoc+ncwS$FL=9pYJm93qNt1Gt$&{+1mE2UHLe%A0CKH}vE!
zLByB}m#;>lm-cwYKMFkj1N3#*#YX=)40u<qIF|Py29pAzN53X&RQZ9v9OG>={@TXH
zAGbNEgZtj5xsd{T8m$pGGon at n6cmDzrag$Oot<{<D)7a5C_ at 7U?Zn+WZ-m(5>+-m?
zVoR)YqRzzhXP7om^j)?#(hN%;lkt+E0}4$wH8u14`X!#SMaKd7jJ{GPa<Z22rmAw_
zE()yK(L_P|^mdCi+WAO at i5sKZuj6!Mak`1;PZxHy@;bYANmCMHePjV+Rj7%JiWq*u
z4OAUp^~aLAh+x|N#&Q_r%!862KOY+U)Hc|xU&h>B9kmmuy)n{{5*z>VQxY0doAz_C
zprF8<3j;_IH=AW-EY*WrW;ATJxXON$cTVADH*e};L5x%`F_8z|IIVM6uKt;85{Q~#
zuX5iDb?R<Ew&NK4W!bMj{iC$%-P#z>X7i6)lLxEHLhTTUQ)eL``LDwz-$P?40CMW$
zkr{l>s>ovD>#-AT#n|g}=x&GivwXYAZZ?UKKbz1+oyoqmxZZ&^HPGu~Reo}7J|Al&
z;!;gvrw$n$7H%$vU+L+QsO#kpKs|sc592)~?hC}FM5C at 8*>TZ<i&+Y3Ze6*&jhvF1
z*p+G9C&p=ptq0)O6WUCrZqp;BLV8wk6tGKY{4Zz>dS&Av?i$z1jy at q2xT4v)OA%j@
zLD+pMR2yE!1YN at 2rX>-Krb<8_5*X at Gbs^XCKQGiR^+xECsUasvxOqJpOSPE8F&6^;
zKN0W6^zl#uRbjqK0@}(d>!FRro62K_j+$Zf%&1+({Gzy9GOPmQn*eLMf=Mc~j>NzR
zCCb6h5~7rv8Drx)-zl^ORO-hS`^5lPk3%fPZX_i}m_y%b4pgt&9qX&TbO~OZd*9~s
zj*O{<(tzIAa>}`%D^jdu$s1N~9{=+eL0B;W0uE<Dm&Ah?hrpA2ZKe;_8^0xr2A_VQ
zqkEr=AHgyhmM%5B32N^Lkhr5qo-~%nx_#YBkS4aOdq#TgC8+`Wb;iR2lZ#DSo`N<t
zz?@*^@`5#IQ8hZK)v`e83`o@^UXnUws(}7Ajco=W5JIV(LRDZE9zIp+U4>B`+-(|#
zLUdK*@8!2tCG8U>y03!0A;r|hmA>Purc845-5&5$yh^fcwT30Qgbmsr^h0JVgG!M#
zp7fz*-zJGIqKMjtcq#LQeIH&~y?Rf<4|fP1;_H1O?91>XTuOa#XgE+t<vW~Vp8-xT
zSq}8(YAq|WS{jVy)msuHQEEG>BkUER2}w~H>+6r~u9izt{oGYHn=@lLE$i!%iqgiH
zrq(9{yl7V^MP-VO%hoezJTcp5%Ud4j6VkzJQCf~4&+%t>9X<^4sv%r0Da^h{c6F{{
zo-WnnL7)+Ol*#+G6 at qlghw?T|f*w*K at WeA@T+OnTH!KVkd63CU+co=5bxk^lsg$vV
zfQ(LcMDtPvtv)7uc<HNtBqCOpw&bnZ?h^cErhfD?L4Hv>H${ovlA%j%rbz4Ou&Jcs
z?QJQ^Onagv=%%?opZ=VOG!Z@)T^D(yuO_pw>tM at xbLO;ii;J*h_Nn~Oea+|D`CX5m
z-$_#P`VTh<F1Q;B`ANzYRX;O0p?a8cM7d`BiqpmI_iBr^m6dy;?aJ<d=;;s?QWtFL
zir$=pr12%Wh-Ns2%km4xXGAPRZar?TG}|T;`y0(SJf8OK5NsS?%4F>pk14;Iej$b6
zo{fA~JmqRp{x2N^iw_xp-kayj0Jh0K_t}WCoLU*nQ8SkVSk>GoADpl=<${G9sntJw
zZPZD6qO##+|I^0hA>=fVpsIGqQmQn1XJMg*2Dwl}eGC*ndUARBBAW9uGIl2#WhdSX
zJr(G3*WEm50Ve}E$=1!rDnaq2L!`HMhz7f*h=n^7amt5%-zRP~MU}<d1WmKQoayWt
zhs2any&dUpuu<t&?5Xl;3t`x9?zz!BLu3-qSmexZ!#GP7jyF(efBvPO<4nQ^Cooj<
zXh_I_g1ps|_q&GBj)Dw0_w{-=PKtmX171d_9$ti>nYUefhM>>d{G(V$`qUD*-0s;*
z)QFGv*_pnXkrtsi at +-gnD%WV6Hi6YfMXlNKfo+xO)dPZykV$OTt#~_vRjT^|t2_fj
zzmUlN`S~3hlR{d4hg7ZQ=tnaCzUN+LOMW7v>m$D~^}=UY{7=GHOPgR5Ax64jh!a;x
z at rXYJQRaSCRZBmolTl*RT>Jq$AldTO7`4PAYfd*lwfCQL$tHZ~)I8hxc at u7jm_zLQ
z-_1t5b^do%gN4iexw^W|qS`si>Bbc4kuC+E4$#w)FL6p)Q_n><jbZ716h9L3hvp&g
zi6D31L!JCS at P+p*`)rHE*lFyGXwYXJl*j`2o`uYQDyZ$wrLXu5Cp0~=a8=CB%U at 2I
zPuY++8}F6W)d%$L2z?lN^fJ at k%TatVUp!sm$9)|s7IuJ+NZV8ytNPA4(xYN07v|BW
z+Ve7_qnO;Uyn3xF#NnqmaYBUJ at Yb=AMVJ{&ejD3y0+-XiaZ}y(fW-sp9x+k-c|5&c
zOdMVI*h-(`7}KzIM`cq8xnL~B(!#2lw+L9k;)-X1;REo)BeRzhZG$L<i{T_p4`J~L
zAlCro4qmgtPn9<#LUCdKuK1{y&7Ba2(W`h5xj?-MIj!iR;lACM3JOcbn)Rq?4?vGk
z!M(Tp**5G%iA8j|rW0j1S?+jKaLenXnmbrpY at ATy+>A&O=1UnTwA&uw&D2XSS}@$1
zKUZz?<=iDzrT_x_dtjWCTOcJV89zVu=;4=f2cvDLtxLD{B71m!K-Kffph4_CfVakB
z)p&tiHO{5T&9*1A8i{PGF{%pju}B)rE}5>;%fx}B+7DW!Ej{{)W at LW#b%7I?5?^-l
zqPlx>MGl>5+5A`4WBF3fUN4E_wHozHB~C`5^A7t at 2#{8*{5U#xu!gF%W;RPF$Vfks
zrlfbGcU&=F at fBU1jZFK@rU;2EQ_dqNGCF?2>g?m}!G>&)60_Z?pIHE at fJ3?Yox2_n
zs!PmLpf*Xq*xq-B3=lPF63jeHOzPayt|qc(+s2 at W+LIkhB+D^Ka}PH{t!4&vzQ$Vc
z)7?GxhLK?ZMF~IoCdu^HS5nLiR>e<rcGFIjff-899loqgTPie01snn*dG@;I19gi*
zXv_Vn;OQ^h+n(?x%t>Y`H-QNF2wbD#brV9tn`2tOav=dVgn8?>2EzPQ)3QHjS%}0w
z-is5C$y at TN3LOy&I9`08 at 31FxwqN1?z+hZsjR}4XdQ|7#ouvv5<G%)8=_*|g{_>}%
zSl3z4|5))zOs4Q~TvL4{=<Z2YaZJQtZ3A?((dDf!!o*Fb3ZmO;i3V0QapmFuu%fDf
z%g9*tO2&Ysp#t#%c~V3qX4~4n#Ia=(tlW}Gy!tfRTc979m!55!e821WmitGmbn~}8
z#j7<B7+m_h!#UwI-cQ5;ay07wjSV at UKFe2P)Y4W-!`;&RLUAFztkkZ@)M{tfF~ZHr
ziTu*<zHcRS16Gld4)KrH2d58sW at _XtDsco<2Rlr*mtrJ87K|tW06^kB-n3Ww_-z?*
z`WerNKC~eemLx~-GLu+LkEIa-ORjypuZuGbpX#&wR#2i!gV>AY7!RHM?-~!C_b6HG
zH!Q=oK;_ at w<B7AOLQAC?AGvCKuaWGkfD_fbdDtk)fqSJaijp22u$}~N4~lws#xKHj
z_c)u(zQeEsMx>zb-<Q>=&%=!S^X%=ff0MF)^fAt%b>KOxr<+u at b&DKwiKqO3G<}CZ
zmGA$55{iscghVN_WgH<ZD?6LRvDY!P;}}u0$sWhb<{a}l_Cbm4J<hSoK33r<I{Mw-
zpWoMCa6GR2x~|vtoFH7<>C<>%;5JSEi3sUOors5QzCY>O-*bgq^b8Uu1GvO|{|^7_
zptW6;oml}}oF~LjPaK_YC`iK`EWBlRWAD6=yrp5Ec88~zTPjCc-bk3*OY(>G`{Fb|
znoN^C>aKIw99C##>$v2uHNyuB^CGew!hp!w3l=GOCSWT0<m at 7<)?3#3A;;391ugBk
zJ0`+9H`#P=Yf at dw@S~9=Zg`z9%)yyPtj8d$=ziACyKus}UEA~O5`Mo;A8d^T!@9O~
zT~pJDjDvZEU>292R55Z{sZyk9HHJD>|2P<8h5sp%6JIQ+)fa(Dbcr-kvgZt-ekamN
z=Pu1SSd=P+Z34WRoJV{oNS;{SkF%ibEhUbvWtdn6S{Vl_uDLrdP(`{Coz}1YFwLtu
zyjQdN;~$g}`Yr`TPItU7<xufu_a}hAA=}2|xiy-UhFb<`tP(APuhKE_DmXmQF!?6A
zecnCsG2F2uC3UgN_Ssm-w%p*xpnVaMp~Heomdr-r_}d%)!)%N<D>PBRq%qUcAnMzN
zy}HvKdno!!!=`O<m8R1J_IR{)uq!{@)F6=A0&qgYpf+!I&Gd$XP=P45*?A|{l(8*T
zDaRb_q@@K=R0Yj<pZ!`QSO!gZ_%>+8PtWbG{AV|1BhQ@%Tbx2v at V}*-Qs3 at t1WW+m
zny-BVT8=>uKg^9;*ui|1$x&*^JM<C3a~9ujV{v>Xm=&Asjb!e+SF{eE_EXQxA`X7j
z1|8n40qQWG5l&6^c4D)@!w|xt(>ugghNb&_m#o#h;pX9$&OnE^zrWj-3D}OOJAGc>
zM2tlxmFaEct2^3H+_|Hy6 at F^lFmWhRC#dd+-C<p~#eZNezSjRLkwKgk3#p#VdxpB=
z;YZ@#XMaBU0fOdh9OtSWVK+<{6Z<CaHjgcsj==bQ4id;H-x+26_Ot$0;@6#0?L4<@
z5dL;XlOe<4T@`$(t1ZsYwdvwTAXflOsI}xkNOIQnOM&b3v5m%;Y682`GWNxp7)2_5
z9@;tmU&qJZ&cdeCh89Kfh25f3OIqh&dfZw(Q>Z;Zi-QcP10b7GnXb at Xz|P7g6i0J=
zV7smOQ%%|2K7owt3 at PPqFE$V^!yjF2l&bUg78)5o`s7LH#}wi}%u=`;U3p??T>qJ0
z8=gC<K4lJ1sWEiiH1-0x76-)m<I4?R=a83j^uvfPfT;1ufqA9ui8EWJ?BT#7IPWZq
z(OKH`Tx|&O)v$fs8Jr248G}vdn*1G?DB>RaCTRG?zPe>m&|*m at z%IS`-a>m2YyhXv
z>XNVNP`w?%aDp5`6o~lLG;n7ShA#-J2$9GbpU*wTik`<IA_t)0s?|sQ+JArG7h3B+
zLOP^TS56cbVAuht^x56vxA59I3T<Ly5TWFw_+KGAGN?;{;V|#EUXbA|uNY{k)t1cq
zgGT*Xa5;2VT<U;RT3sYGOp%lofRwaz<JPG3Mc>vGB;9&>FM!b(d1b6^+!k>)^fwo2
zTurh3)}%HYxPMIAilCcm`GPglnrK4q`FXq0JVJNdAXRJN71p67+&t~<=a29B-CY+{
z&7EI298b=2i85#B=xIZ`Qj{Vy(|O|7Y^}OQ3SRjxD_i7CSrHmS6mDwL1AJ(J$&lIk
z<#oc-_{av-J6<)+ND_3gP}Oc<cgKaPsQHt_m0gTdE54cesU{dgWdb;{22I^D==E&B
zbHZL_Qd{US4u>nT7DhcmnHY97hMSitI%QfDA+t#HbPEJt#kygmUemDk)ZFj0IBoHQ
zSm_k-zOOnOKx@&=oK59<w6y=8kp*`gc;zCKf1sz$UD_{w8Bn1k^pbyDJk1j9JZkUy
zS+&>bhn!5i<T#T4!^nG<oNJOccGB0<Wc67{7P3UqH(skj)YTtyD3$V+TjeC{4dk<%
z*RUG<xqQ>+oV<D@*&ZI^ZI at H`zP+QiR%PXq-^%h at 1lC_YkCo`;^zK~7rv}hhfVS6)
zf52UsbF`;=jrW{fI4?Y0N{Dq;)q0!Yce8#th1a;y$!b-Tn{1V6(9}~qGD0GNxX#qo
z#99ZPDCp93n^$sk#~KV|ZDPy|jNZp?3{_pkLTzvEJJ2;4WNxcyzn*6C5z4TB{-sHr
zPo;h&JwPmIGG>?Z at dj!6x8mP2XL=!dJxa9;fy?8yYv23ty40dy$MvIWK^c(>&iNcl
zWqsJwAvw-3EkiG-{?(7d82t9<aaWOm5ZE at ZVFpIuRql}pDkY+rnbmjP3dki{AK1UQ
zH(H9lZ7%A*`U%8XG8Xz{5hFe_S#z8 at L?ykp{$|$V)m}<yY_TD2WNzjCVY5D-setFu
zlu!KVsWKiP*Iy50$WF<7eUd at H51csO%7%*?9q2=42*c}Vta*RDgYXA1FJe!~(YB-v
z7;jlUg$1185sx$eY|uV%6Eh5|Hq-Sk at rW@z%@Nn#EdH}!aD%F6uXtR-(MwiLn3JXZ
z$|X8GJD at qaFPu}(GZy0HSajWo(0yOXnC>5Ri=(p2>y at 0OPu)($wWAzoP~0vC^WY+}
z%JxZRZDwe{z~6C)wU!+$?vcC-7<TAg62T9|)E34!lZ8q~FkPGDE%q0I7gKCdD>BdI
zCLi^vLA<6L9{1CnvBc4384Y~_(wpY>j2OgZ=lKbfvjOq0DKC>N<KtYigPlX;TfAXX
z67Dzc8(OX$cdo5Mi-E(iE?c~^j624v(CxfezvMO&;o~R_F3xx<?H})4SsAO8yb!X~
z5fW0G5D*%<{^d_FfAn3-S&WYn)F)Xd*kL#8cPiRXqFo{r{V_#v`=wFjOmTZ}8Mc<+
z)G9Bt%A1`m%k9n(6=`7w!>swf6J at zhm;lGbAN7#nLITZo*p_H at mU>uFxz*5*tK|&6
zYf9n=C389OL+>XdmeVJNR~EW7_usTR!xfuv7$$Caiuk|IFBn$;oPU;eiudtoo_3z8
zo at P5+PnbFQ`$v0*jo6RJR|g&SouwT}ftN!5Ssoz&Gnp3Q&)L}8xRS}j&M&WslZXj(
z38$dnoN+Z(4&y26YCiEAPDER~$ve8!A2&Y|`b8c(bSrjNM8!?Mtt at TrD3@<YS956F
zv^0nsR^xsZAE)_H`uilsdVryI0LXX$WZM|AypTWm*sE{!qO!g8)bV3cyiL}_%<G_^
zNc3_2Q at 35pz|B*2eDcd;zAtK!*`uT!=38RbMSVkr+x at p~nZ+74gb at i11vZv<2~>^k
zfDQ#tsT~?!0^y`6`Y1*a^duE1`Q#?CoxjSJ<IotExn(4{Q)i;jk9ILSHS}SR-Xz6e
z)oN|b3Tm*n-ZpyUW^YclQb(NNTF~tOs7+?2`@Mv*Nq*i%!%-hH>ItZVH-Dqjl>HW3
z0snaeQ;hK69mV=BI8~5jTD^ogA%1Un4CP!WM)>s@;I$Hj^-`~oU%`$D?&MC#dbyOk
z`kmT$_poa_<1YX;7HYNNdn-H}$4VLpF;Eld2E5<VIQRP7Ms(At`IEWLEVx!E>XwP~
zFJd4d5<Zy*?Au#&M)=czt6ca-4B!PF@?)*8{u5t#;@9!xZO~LBTebVYeZS~Y30H$;
z87zh5xpN3nr24%O;jQQYX#vptvJ!#X<RUrL4h{~ca*jLHq)2qSqo9n8Ot2Qh<OHZd
z6_pb9XC#wsyG1tZ#rdLcpjjWV0MAxnUxnPZ$b6kVU9IzFH?a`onNH0+<y2u;gHg0J
zt1SESaWmsyzL)Wt|5Ek#%iph at veK0)LOmcO_6C+Mbsx3AcJIWvJa%Vmlff$iTH|jn
zyPOv{I6gop4ZEj3%#}KBi;Gj(({@58{dj}Op at QSeOq~q$-UmCYVzoQLaB*orQe()#
z+1|=(j}0iv&)h96lN{prm;xi{N>_?E4vjS+Q&I_t;_Y>!D~+p~tOMGo|FaO2pa1<E
zi0BG<H+9=E3>mDT<HeF3s!VHkN+yNGOM+MzM0rPFb;gDfx->cWG9i(udP!CwXh)UR
zYsJ9O_hIWBASqY|w4-<yG)vF0MnD2~Ra{0LH+d`wP_h|oX0aybFgl at H8fiE-m13TO
z%`=Ppr1!4?nZ5rCHyl}1^Qw7OyhdXCsx)ijtbdiPf1j1 at O=>q0;P2W?MDd!6sMj8B
zUfT1&mr`5?V#pGcM`pCoi;hl?cfF-0Oz{+X_mP0I?8gc9Qc!*S3M_tFJmg>{;CR=P
zxSZT|vb!B%>V=|p0-QJj@;#Q7wC4AbU8jzA%30B&gUG6MNQcLd9{Z5R;_y-bdQ3w;
zXKjb{v)RTy#&L6CbSGAN6?)l&uI0T$qn>qQo1a7Uqzb1Bb{;&DR&ziux>q-rlV(ne
z at CxL5T{M*60zHL?#=7L7P$>SG6`^-Db<BkO4<5KR|J3S<##W;|$E%soA$RX4uaWyt
z at TuaRSY9!I8~T_Ab@?`BJy2!^SVy#A>u=D{O*q2L4>B1Qcfe^k(vJOVZSQsak2Nur
zY0ST%N3V#n<fvov$Ss-gyYh(aP{hWYZAoiDz7G!%=i*PFG3r{H$5;(`+1>FZ(!G&+
zduS>0Ob}3HUyj8}O35lFLSvkXn7S-DASiWBjk~ldtoMQneMzc=ac-i%j(*8N{0YTd
zZ{dNSw49+GmTNqZT{wiE;ui;>9=D>5d>=NBmX5S&rmtmy6BBdStwlJVky)h9qZ=Cp
z<EcExOY15DJ65=)Qrb{Vk125!>^$IF<v)`R(1FPD&iY$WVn$C-?aYZy3#N=s?fP at x
zAdJPr>!T)^J6~ZKp at ox%mA#r-OE9?A!xQb6jXde8M4WK51+ at hK(Kf~(T2{V)k7$e$
zrZ`}5ybRp1U=z+Ykv;sqEZt}*Fudf`leF;&qt5 at qAY!=rN(+se(_L3rD?OE=Pgk>Z
z^j27Mlr<-{s0WI2Gbbq#e=Z>RKHHW>ZK$&1=S8f_coE9iB^JrwO53=WWiouV-)iv;
zXVW;Im9%N_dpd^DQZxzMwEUO0$8n-z5-ML9wY(@xKSTum9I2XqxX{r}dj9R+7IsrB
z$fp`nI5jpcBc#VssQk7P4V4<7e`Pp&;I+8c&%D@|X6lp~HOm7Enx4Gw%s^-8zW?fb
zeTQ{wJChtfz>n{B!ol<v%?Cv<`XF`%Pn8LiTLZI--t4bk*p|iSTnruw$#$O+2^9~B
z!)@(xEo4QwZ_v-B%E~kGe>#hdwr9t%lXykS at mLMl4DS4#p;wh^*EXgY#r(N^2Kx#w
zzIR)va?C<vx;3k)=Xqi{Zw0s8;ThCf66MY9Hi55pQ|*_b%dyqWw=bK|Tgi={Ws>~b
zec{}<sA)|6WaA8a6<RjpO5WL$23=@Eh~kymsXYh+HOP6+MrU(<)wVXt1&&(uboUha
zU_a>m(C#u>!>WH8cC2zx(03=c-XdW5+VfJST4elFWpZYc^X+!rrZy$|F1^ovi~u$r
zJk7Mb3DB(WyfwNtGCmc0hBYy at 1?BO_$bHNQ)4Ood7h|PG7OFXy^mzbg5QhD_|C40a
z|6_Xd%&UqeZge{e_qh4EJh*ze1g!4- at lNoi_uuKW5bW^ImGt_V6OAA=wPdN-Ns5c3
zJfAdV`eTzm-if|=r?C5 at wF)Wr&m4rlrLLs}*`yISX!{Zh6`&fFSQ5FJo_?*-y5WZX
zwYf0PpwViJj&`z)AD^5OkjlzmQW?IETe|E!L{*aH4d0dKQ+E^)<yHZtP${lc1xu^%
z&gH!GqF+wFG`PQk(WZ_AU;kcpo?+)uS^UpLGI9SzAx<+?tz+t!m5pF!RoT+b{+qYs
zqKk*baL1qW9`!=*kARx5hDw0a%+Xt3yX%}ISFrhNur<)b>N at U;+~)Jz!k>e-OuhP=
z9uFI%&@^CruVk<Hr&nr^_5c+ar=DHo7SooQnHe$$5yX)Oc%KL}ykMOGie$$pyeCeT
zeqvuy0gE^geE at EG*b8}j8lc*MJC^K}%p`+2$y0luwcYm2Nv-3YEK8ZpLPkR+ZDd8H
zYNSAr)_~*4JZlC(!p!F5PS3`)<+zp-^eaYG7<^}-<<n1V+T6a9OilxGX!7D at Ta9a!
zWt$>$wgQJ)ypWUh0ulnwq4)(cQ=u}p+opsIh&{=W1aA;M<A_|D+S)EZ4*QA~B^E()
zT=ZB?V)ux8RYTypdkQKNl8|#q{l>CgzRKU?y=Y;fFpcth^dC}4=*x1uP!H~x6OW8p
zBkmM2s2^9zbd4i3{m2f2+nH`{>k*YnKa<aEDn5ft(((#~t>Z?a0*YLP)}X?Tp2fO4
z8;*o=O`QkD=F1 at 0x;xH)bQ{w-TP0~lXjmWUGVsE+Tn(zV&+S~%rjBu~@m$iS=cfnm
zso|*H{g4=4tnni7wc?L%+71%1K5vJqL`>|nT0&5P(NDQ5hh5YnEWGL^%E^^y>aMbq
zF1Pv}xc&KaQ2pORAl at n+-6GxM0ddRKa(=xw%geQu8yX!N4)gf^-RmjKJfzBQB`>Kg
zS;o%3O+6q5JUT2na)@&nQFJ?XjtPG%x5|6cI}wbtwUIP26?*zAp<zkF-^U02gypFf
z<38msOt6pUS{u>#OIym9;eUq-8U;9uXD*wYr}s(mWcI-R9dKon7HcEp*-6)&{Aj at p
zXN10O?RXlqFp}*@&ru{R9OX9hb(?|jha#5^+Gqi8!{z2Sq>6~~<RT!NR<b_nK2IKX
z9&;#(Ry1_Fu~f2*>BzjB)9JC^RmJT{O9%3IF~*S^C0i?$Lpf$hjT)_F6R#abXGibI
zrVvr@%kmMulO^&;p+i-zhWdBD4%MOVkF+dkv7IpJF1N?N3ww*w1fh5eb$q|FSD&j#
zVwH`nQ#k`ks^Il6`f<|JC929q{*U{p8?O0<eTujT1HGu-dCbU#B7af at Et}f~W;$T_
z)o1 at P<3$Y2?}!LR*w0w1my#Wl;TB;wg%A2Pu*lyjeRVq9fo|gxb43Bt14A^~0LF%<
zb@=Z}sa}1;`t+<B=HEAc6Xr`YO<2uL$r>(zvTBg4S*1zTOwabWF>ZZOqV(2yH6-J|
zk|(2}<F}bDpDmdb+(9m9 at PyL#8 at rXli8Aw<D9DN(Vxg(*lriy#(U at SqOKLM!Faxl1
zt;PQS|7nvmW-LO2)CD2kB_hvj+yxn#c!U2H?P=Dq$pFi1X=12!_u=~&kRki4OG_JV
zTYi%vV-l4zE$lij&tY4RPxb#js?9rNBeiAX&T@>JGt~=9rxrI&wsJt&#T9y0986p8
zHe2>=sh``ad#7T(9S&7YIP17=JNsi*n8?CqTf(;ZJ}(EQOIszMtaL?~5}!{-rHnb!
zWetv_?;ql4s@;`BD0ld!5Nxw2EmQ2S0c6Oa4jPVM>^Xxd at D%Y{T5F>OZi3>;<Gktk
zfbaq8T$_ov<QY_9ET$()zfAqMBL;o9q8W at E`Lf>(ve(pRPl|BI7*OuzOnSKvy56%>
z?Qke(k~?TDuz43qJUba$DO)d{<&(%akk1hZ`f!(~R;<JZ+y)F=v;6=a2`s!9xbM&L
zsqJb!s?hPK;t!B313i&?*m;~3Yevy4AjIQbTKsAt(KOD at ArSWGMFi!CYboQ^<HFt_
zD-z3{=rRO7Sg{B9btk2_jp*4 at Kg}tT at Z<|wLAwrB7ii~j(ifM^+2}7o5WZO at Q_Wu4
z@$C9;^DLKO;Nynu-^xx|%GW0ro6Y$Ep_b~O`TfbQjJ332yW33_AL7j5;zT1ldy;$!
z*8PUBdQV3E?bNTkw(jLUUDt8p3eIY&+bEtCNj?T}k3|zMd8iKvD%~JjZVBw{d?&-Z
z%y0bTwKg81|FnQ3${doFCpN`RZr^0e)N-f<KCP2$L55~oNRL<R5|Wv*6<o3nGd@#}
ztEzDP(QFa3sYGrnTPX!*{RJS at 2?G7e9{lBeuIV~Tgegy@$?{_={&_s)nV#6PjMq%o
ziLW?%88mw590+-18M}kWD+y${Bl(*Tc+}HX^<KO8Eoc~~wrmt(D9(2GgQ~b0ohVi(
z&7mLiZz$R at Rky||Cfe9-YJ!05+W+m7ttk@*fk=;4iIQy%OE9l7y{8 at rlHn0-U6pjd
z^+nf|<nB)RIP4m7l}%PQI-##OjPIwmbr7i_tQq_JHFa#?%k$6N8-iopZw`o%@jOpW
zu_#x;CIBsBt?cVj)e&Y#Cs>4jig)6y^<#SS!94&H=a#o{z{nUu4B+giyt(?K%g*+L
zdy!FjLRz1wX5H5ay*eE+)xV;!UD0^dw(pU>;WIJPvM3i$T5=Y$M=gJ}cCg=M>*@jH
zzVvlJL;EZZqGJx4uM*UZENgmQx)l&z2alAgF<)AjvCA)Hcp1~q`KoxVy^8{D(j4VF
z^;yo|lZ5mSzpW4REG-YnS=jGDdNLS(%sCKZB2{rTN?H3WpXmllF!<u;2WBaWs#LZ)
zZ1n7&)&aHwyDNl1e2ke=E(cAz?81?D4>#I=wo;J~dP9Yuq2ybS<u5I3;G3XW&u2`_
z;=U**!!OZh(C}dLQN2MnyD?JBboq~(SkL}v{_KzyKvE1pRT0PP|DvHeb+iYDEaHip
zd9EHo0WO*`99^+A9!S<DlIUE0XXNcq&3gc!xA_SiDF>H!FNpUURteodB_~kzR8Sgg
z>QbyqOc8OTV-?C_zR8KY1DCM^>w|V;s$XEtW5Ce01c3Jq%+^_3C)s$jR^YwBFoh9m
zt2MBBLHfiZ;fwH`dZdL$f$7g}6GWbXDoZ;z&REWb#FAN}+m^C%-|1R)@GDL|8^&Pz
zIRN-eQL5d}7GK>hU!Y`UvDI?I#Ji$0w{F^gb=NsahG^j4kvMupj1-HBqdUJ}aCCB$
z_0kkwI1&r^CuZqT-RxI15Oi^6;qzAx#)SvNvD6Lsm`AsFK6lrEJkmr;Gqg4<pT5)^
zHJF_J;G3)`#Hl at Q{tz^wTdkL0)LjF&e&WG}nyE795h&SBTpwwHjwGD}XeOw-5lgwx
zC+NiH_($7;pH-(I_env0qfWXc9i!S&y#(~hD0N3%emFEF|1a_GvIF at tYQk4HE{6IU
zn#{;-hh#ZxOs=b|VF>MEU}{%b2N?IVQ>9)cQ;EARVkZXww at KEDVUrp>xGxa<P{KfH
z)nSCFW%Gq0*^BQ*{k$%O6aOARfg*zpzy_%{mRLF1w4Z+wL{to1 at X|kP-pshOx8FT|
z->S=)@nXg=^CSWH`jZeZPuTXb%$ItbLc{u{Dp1A2C&?0CutEG`9K-ijblCGbb#J$b
ze<dvD|Egx!@dROAzp93E2fI&(kHp%94m4c@{=t)?!#ZW=)F2%Ic at oROKhV9W%gi;W
zl9qPV?+;DL;hPZ4Ka^m+HXG=}n^C)|<X+$A=>6m#t$qVt^v$7H*gLvEvx-Nq#*ur;
z(CsDi8m#BCfA^jhWQk%h(0*va5}M<_M`5k}HCiLjeOqMW!xh9jV489*vD=*IOv!N_
zx~H*|6{>H;dry##`yTem^ubYS_?sn%PsKMr5W+7AxXCRb>jFMrnWAu_AQ_T+1201V
z9#hsz<dZ@`l3-?6+^(2 at vL}O{l?}k-mu5e5eb?)^?$F$?t$z{z4qU)^Z6~GhN7TzN
zkm-rEaPf$x36wN2{Qx)*CTZr&td at O4y0%T~toD|G*j}RRoh>G}5y27e<V at 5^F1Qb;
z%{OW<#;vU0VZ#5-WzfYh08O)_xSQ+{ar!6t{1E4?w1aVYYvX+TTmfDEX;IpQKI=vq
zN!rib8T+~x^$6|QpncmPW$I&PJSF3kD%voIO#`eTI4e%SFd?El%ZS`Vx^yEvAonmK
z{!LsA89D55uomC=al7l~v&@2a{08F2hu at Ayrt}`@XI;oU?Y&uGr_5OTa_CAmzq36X
zcGtveTZEk at V>%Zn47{sjc(=}dPTp7rPO1b=dSPCdOn;^rwav+|gl!X*<0&^zbOc}X
zc=FL at zEB~}>1<k9a+NV)f3!DD at yPW6V4^TTdss{l7<bhN at D~oJ0o??*YXLcoYmS<(
z(5BkatTFbg(}o+&TcRMaUgNEys`j)TAV6j&N6N2(=P|VODgkW720$CT=|c@$*TpyE
zUdkUV$PG{jQ<4p>-eqsB9dt_83eI|Q?=eH~AbT~BmG|}Sw27A5k#q*5PmYEMz!JNs
zx13H70t>TOZFJlMHZpa+Ciz41V2Z=nEi%MjSU3kSQ0Z{MNSd9STSXhVOggfXcL9Q%
zZEv at zXZ|5%pSaZgT)C;}O{0gW!@m?MyxmN=x10Ses?x_Nj(Q54 at w*M6QKtdf{THOY
zm at h#x^X$pbgwWVJ(&PlNkvi2)_o0s|)?EQPcbb$~@#AX`=W%TkQc`o{v|=FZ@}$%_
z*P|ZxY8b8Qj+;1Sr07L%PLAu-C~H}`X0*F+6miOEL{6zu62=uy<lI}T-6k$LM9l`n
zQbD}_<NKn~vz9jUb(YUxGvs?&DUmq+Bz#Vt<Iy>3k-RN(KpYicd~3rS%{Xc=Qc4>D
z5b}BqU-eXk)xBHQs#CQpDUGitGus<2;+h+l+(brA9=Ny!EJs8{z+p2lwQ0}ZCTV_p
zo{uRVakq(9k@(Wqq0N&;c)t_VAbg%dkIiY1?Fy_Se`$B0k2XMVYo&_c?}(G8Vg$33
z7bdi{WVW?9`+Qz;Vzjp_n>B&De!TPTvI)q at V$wZj4#?S at D%fvyiDqfi9P;$qKA`#p
zL=#=0r+cz=f`47kUcer5GCHp<0dc0*_f1h+RBm1?LY at Du5|Ir2)x+ZM@&rt37dl#I
zN1*5a>=PW^?vH_uwl{mdp>NuA6ihsF%;<d}F;;rV+E1&TUzo|!rpvU^&Gq&dk<7Ao
zE)9`61uVWuPN||5yZ`(5+ro$YJ0}7N=n4Do-?Xtud+wmP<3;sr+Hr4wa|Yg?=(YWU
z1nsGfs=uGu?Nu{7@*@}K?CTO-EeCF?y_?=y&RLG(_{y6l7^eq3yk%ELF|!UMPE)%p
z6EAj8Zm%Q<xQl2bQWjz`55+^b4atAxustxSkZ({d3Gy5>2$4da&914j>YZ9CsB_B+
z=ywR_sN`AQ(1_Mat~?btVFQA<`g)%3H28nM`p+b7Is&p|q7#%@In2<SrE}8hV}?S`
zlZtp&I$7rbSW5$QRt{UrRm|P|b;nyGGo~NCjNti<byeQerMc_1ol!7aGjn&gTtr7*
z48<?ty|naJ8xLJDqZGaQz+OQ^B0pJ at Q*0<&r$ePQyG~w`tl@^%Z0_`w-UsZ`uzfDd
zZ at hhE@V~Lxp#4q?MT_LjRKR{g#Eekjc;L{WbKX3YENaAlk-Bak?_lt`;=SfmvZAcJ
z>t$l)Cl|gf_8$}M4ZhksIK&NpIMm65R;LWVg?e%BY7n-OQ%kQBD0ks&G#x3g4sPc5
z_3j6O>0s^+jx{_wtKh$nG5rL3$@HCjTtSF)Zn*|#yB{v}TdVdzBjmF=4Xk9v1XdXH
zT2I}c2)b-}<^6U at w=EpeHUg1u?TfoGT_hzrb^}?mvmWq}M*H24CXtLp3aGz_k;2oU
z at mBj&f3`?)6i&jA{L#Xi%lyR4>EN0^uzyY85?&86+B5yqaFA1a2k3BP!S`?$?(2;q
z>ggI>AUB4qI+YVW$QG^@8{PFeJ)d8zU&b%#sQ^dbJ`&_IYuDl8|2kmu$M*#BQ=5EU
zPIcng{ki at GL)87&rf#CS*yABMPRzJA+eSnkl^lW~sO_apim9jTcD0C0l=!|+^KIn4
zBEX{C^U at qWl^ZtyyeQ}bpm5VTqU3Ysi!w_k4*t9Ffd@)U)pS~!6#I<%oH=o=FPZ;*
zUC!v<>ZJ~HQe;lWyQf0p=gBZ7iSy>`RLY@`lHVm6MRRWK!aw1&Pv-gPZgoV`QYuQ8
z*7*@`9>f~r+4<cGNy%Xg65{aBh=eo)E3$948-0C!<Srvlx*1k=k6QfRlkmPEC)J}c
zy~09($KEE}%l&C}g*3B5Ui!!ITi(#1_F2x&P;AYW8QbFe=5kCH^D at NEr}Z#y5*7CR
zyi at f1O-0es>*@o~Zy25KYS3T<6n+#zTF(34;$Dd|e}Z82IT>F!UR8ITT^p7W#&A(t
zx^8T|gF^*BdC0}BuK&VW1sVP5f|81F>)7`crx|?qOx{^sd&2{+6Xh{BIuz(GbBWWb
zJLa}HaOWGErJJa0gy$QC3+vc{!F=RUPbQXD&Nn)!;;Asj6Qx;Cu6 at ebgYn*82#ECA
zUiw}62W)KaVr{#)dzH>3W}miEK8y7?OpA9HML%!hz#cyj at uw!fpvZ|I3*lARj-)n&
z?%Z=x-HZrCY8wJ${=ey%$AaR(`rWV$3orbQv*5w~G2?E<D%IlQObAiVzDxb*5Woh~
zU!38q-S-x*0#-+1Qd{J8NA)$rxf)irG9-~^8pivY`#N6Z=F*^yA0aWZT{?MQk7`B2
z7x44 at LkdaHSHnpt>AV?oEIS at I+Tgw7&L-XS90IF(r^Rn9digEh>(ywqL>sKYq5RUk
zpw;=ZBjTJIJofH;lArNa2!nwV<+ss9cp-`+Aymue2X<(+SAffw)OI^#jK5p<lI*o_
zbD5T!ec#y at s?q76MoWqpKspL!-N=xb3C8`h%6rBiwr2+O_iw%offbV<*A;z*S!6$!
z<0J00d_GEh(XP0Ia$0^_5%`=-{S at Hdz}6zyv-hcia7R<~6;NPO#5U(;BG%?^dJeKh
z7E45HqRYTLaF%4d^`}vWW|Wpb)1IURi4lLX6KU2f#9Xy>gVf+dijX&`TE*7n5Z(;I
zd!J-YyGxh60c``n4F$r0ywkoAL<Kb#R71cU7VY^0w8(1=&WhGm)6MV at +CTnH;O>+N
z41h=iXIHhY)kl#sFGy{$D%ae#$dEvYpEmD5!@IMH^HW>R`Adk+<x)n)5UiszXTG!;
z?BP*c9I=~CmAt05vB-A8Q|JnRZ~TxLjCcT6n=8rRQ9(vRQ-pkwpnvrVkl)HL3Y1Hx
z?-OC^GG|}jQ<%~;>m1nNBQ=S^P_Hb(KF3V#Aux>Kf#U=ZOhprS>ME4I`bDr;-jaK)
zMr`O3>0uZciXxw+eo_c+q?cqxt5DlsFa3mdd=6a#qRUGC)<+n-(G1Jev at PEDbC-@W
ziKCnlpI%{`*{)3v at bz1m67rg*RYP%$9FUG<`lDkq{ocRtdq0V`IfH1A`I at gN&x+LP
z?;39Fv%WeIEc{GfR?!pt0_~o=u<64NrJrm!@uMj8Wc2)J7%PZzN~0yKm)V8HdrpL5
zpDxyU+HLMXp^mfLRI3J3bP3DP=<VsAJWoHHa(A}c?^kSA9g5asX at eKZXH%j5ABwp+
zz44UBo0w)TtdA_c6tD4&-v{ftT1uWUT??qz^V{I`0u07gOTn&74*&PA%-I|t at p-*-
zKg;lZ56xLwM52C#u6UT&A!qOOj#{x~*e7>|lS7Pm+`365FnwCSM$mGP*kY$?gerf(
zm(6!w_s~sb40_!bHHNeKZeQpW%hkTU2t3?rQx$37#oQ`dFyY6$qv-Z^(=3HO8}eQ&
zOrT;eY{k at F?zMZEYf#6=tyM-EvkU#<_Td9*{R^>iNL8TLJW at 83rf-f5Vz%*V(Y>v{
zmYbXF2AzP2JfZlSX{hR>L@#a{=V at MMF*iP_NDVKZdLXy3?f0kV{Nh5U^SRU~Ag)EE
z>dwQU$&*OIf`)H)`qIRzVxzvodTS0w?U}m15OizBbX<ECb}+mOVL}+tyD3g)!TiJ+
zG;M86g at L+Os$dpO=Dr0?YbuL>zOPOxI?1NQ??u`eSk at 6df{}A at vmW9V(aX{}{zJKl
z*wSz{q=NcZ`MfvOFuF2_CtE``CKVf<clPF?S64a3X*)8Dy%wP`iRK|`l}!VRcdP#(
z_02IyTrkD|BIN^~RKGvjHy7Z2$zKYqv{$iy2Z_C7D)ee7ozo@%5x$@z{P;)}lV|Xr
zX)D7qr@(1sD@=6g+BYsB{`L|5lK1ep=ZWom65J?u<){{FCSK0nqIT1TBuR#kLZd%p
z)4_u6S(xR3Gy-E5M)#YzA+ at ina0yv$pK|hi&R87e%(48>DjX{}REfK8u$MZd%**3=
z^`T5wlcd?-M}KYJ9JGy>$;Z7p;}H9*M`}aMx*1MngosFf1vW<7hGt~B-J8z_8#n&i
z(`I;u+h0j0<>`K9getQl6HdeO<;+^?=N4NxxCMa7J>^8HYK~kJOA8(?6y87FSD{+w
zEChKIqWU2HPtD?DL2X2t!e7vX?2BIEU&xP2d3Deqce3q at vDRBhE|Iu{X5YP8`w8u*
zSWIc+Hclf*=cr$<<Uruln1uTo5_aH(0>Aat-;)(pZ&fC`-Xv=p3I({Xq0QD&7|7!l
zi~#DYyW!#$kUr9aOMe>SS|a^#{{OT9#?dEY%Z|DFNe8F4FdX(WK!G0cVx$%SuU!Lg
z(7Ge?gUPgRm~fl;k8)c2yV~;#qurZ}Q-YNT(HBKpPyS9WBE8ZkYliv1G)<ldCrHK)
z{|rkrKR6lzl3P14sP7-LV{cRYNT%a&Vf}m#i0+)Vg(~IYukdsiNhYJ%Kj%{4H#TGP
ziX52Mp!ERsT;mY{Vm`Zfjj$*I3Oo6Oi(5c8iP9Kc?J7Q5hTfO%^0A$`HEiy6vVvH>
z$5FC5-{z*}{Adgt-pVh8ZTQBnZF;b=tD$Skt&emkVdoQrhiU~KO|HkV7MJ+2wrnBz
zu2q0tz=y-ge|$M=2|LPn2xT77QGPb^4Tm2u*<R<#vM3w0w*rUp^tH@&S#@s-ql{a%
zdEdQXKsiPof*4gMol-g=pDl|`4^A$#^rH3od8^UW#Pid}xA7#i3<Xb~@1-LgxibLm
z^6WLRYduJShsV9H at e`cOuBC-12dp{Ut+`KBI at Ua-i45+L&mzVIfG)wY0;6vJ{pOiM
z2g)55Db^J}XO>;jg!<z8U02#%n%<4}DptUr2A3;jpD<S?Fl5AOj0_Khi0_d}V9x~E
zxs{abM>!LLmrxnH!@N&DE&}Frqo#t{zP<SB$Y2YhpQPtamkT`|`6scTKuA6HZ$4c4
zbb&~VmtJT2N`mS$#80Bk_K)PLF$uly at 5<A01EQ6QarDpg2z at JgQ41yUXs<sfGZst2
zhndV4CsPFL?IWqpYlECqTzHO}1&RBG#UhIztnb2mG at UZ*Lfb7w-T|D9PSAcfBQ%iO
zl8d}%$x3xMH)yte-yJkW!zQ*#yr=<`&6>J?wB%YVg at -9ov(tJu58WD6_a at _69?u4J
zJ&+<8?$qfJIfJ+V)rz>;71a at v@ulYmmVrh$2BYJKNH&!%8)n1#q at 8@L0T-~kqrGu#
zg<q;UtYf{a!1%oP`UVxJ`C6nfq`M{E#rHhOkk$SZCvDx5Df<d%u|oD=WA*B at B9?C^
zsm}olmGT$o$k>H~XUr5^=9pt01D)wl?n3sUey8;H?j8lF%ylKy)d?GOO1V at S@k3nX
zlyEEV5o|XbsFbmL8~{-t+0cZyKk8GJcHXTB?A{AXd|gwU6OpVry6fQuj4Zi1GIQTW
z{)Ynml9YTgyOYj<?gd(Rzh8axWVeLI*U-f`b9T4DPdf)lKU~|G6ux(}jNYS~vCE&~
zGR<$`W~aI5_`u$JN%xz{TJ&NG3)HuWVe+xxCQ&q+lI_OgMANGdT|>)9Saw~J$0p2B
z%YcOXHr2eAVB#5rGF?Xs-Mmsq5)UIwDSNrd3m3;nfL)&9+lmeozw}Ib9)rrrrhqS^
zGhZTk7Gd%(Bgnic4O)~>^!&{$F4dtv9|%l<m#C?gZga`kT*I^I8-FWzLU!4T`2QFR
zO}x`~pyYA}DiU$&z7tCE((jn0hlZO3^qa%LR|qx(vFdqAq!mwJEE_35+`OS~=J^6X
z*qqjP;w2Y^(HzvQpny{7pD0Z{8gcp*JRgUlG76Ylqh#)Vx`uD%{5M at Y@Ts$}!pEDc
zGCbE<;CtgfCdvS3yaHKQ at _C$=Q at k#gS;~vcW{gv)mMUju*|tb4cHpRi<hXKCh|a>9
z$bdxC!!Z@<hgMI#HoKF#v>PNhE8?=AoR>Km-Y`XxOOngD75uj<#FGk$5q?3g<bxUb
z`g`i3E4Gm1Gl6K7=6%GLcNMm+3G)Iu$+Vd1JmJEkGEhOMp?#)zLjjigG at EA0*hlD=
zlur%w*{dKy`I3*yyW&IfUz5kvJsGG4dwX=!*n`Z1lA@;f7v##=M{DP9M|UXD9)zIM
z=fAlPu|R#sH?AE4-WYsd!$R&);3xIcGafkgN_%)6iK;3Kf4XY9x$sR^+UWgx*{Nad
zx4%ykr!2$;cWZ6(Q3#6shQ)q^BvwZudlI?#F`7ag#(7K;Okym(fP255r)-?u=*-}_
z3_9Y{hm<QD`Vy;@h|=V^d(K$4wP<P6WzP7TXDf?|LQH_a{*gM1y<{dN<I-!<U)2UY
z6il;H&A!)<Cd=H#s0l54!K>Jk8`4o9<Q;4#>?dqpKA$%ltOkH6TYz*OB2J^8w6o4<
z1YJ8A{92`P|B0LDX+S_g%i`M~ar_mTM-`gmafL2gBj%0iS6QWZs8jAs{po9UX?74n
zLavTDx(}r?vA2Gjdx``PlP+H}RI5dXNe3n`-X1RRg&YhB|9|{!$E at LM61n}3?ZN=2
zNUm{)GX63b8y8bLY(TX_ICv_PLzbhr%3FT!#41^8FH7gclPqxvJWe&Q3dg<a82XsJ
z!eU2~s{rr~L>Q;F>q}RbQ1rAim#)w#CgP+(8z=OlP1oQh>-VaUaAtyjT;1oAFHy?Z
zTd~i@=qoEMZ^J;7_0k`Pi|Aud^HRQ{r^y*lUF`pTzLXeQ$)ok0EBSYfZDtODNOrGX
z%G>A2tIIt=@CMP4y at t8?RwyT(wNx_2gzbR;UAO%si^mTBRl+u at mdZw;>}=YiUl#Q4
zEdke_a@{j}xA8J}U4{R+g6DZAaDg`dt*382xu|<KQBZwA2)+9l7rLl9ToD$}g at Uz7
z-Xt>tYm2w<$WhuNo63IF?66mkXnKLg2`$u>f7^pYn5d<e7`CvTYK^Vl>=&Sc_i6KU
zk8i#jQq&ZeBE3aC#jHMnb!HGVhs|37{@xfKt~`M9c49C35q0&&z_gpE6N0kfzLXTF
z_V;ASLIImhVABa-w)pt1s;a8#FDr`~{{K-kPUczb-frq4Nx|mq%M#NvvWTTUv~H^g
zC&7Q4Nh(6}J((S44w<XfwUHqyzkQcsnr$6UPmEvrPfkzQ0RD?@jlKIf5jer38BK4s
z(0%0i9j at 3>n4o|_uJf5OyN$i95JI`+0Piy*Uv8KCrNMY~3Vp>e08rrclUrNsk8Puh
zhSML5Ti%rdk7cHO*;m<VmCsgnqq?Gd1UDk5u>PPrhrd9EMaFbH%<4siClzAheOEhO
zwhMSOG3i-UlB}l-m__%zhQ$SknUz8F6ccx=yZ+>FeHM3ATHp9o-+oPCHT3?ggOTkl
zf7&Of81L{-&&g!WifTbd0H|*JyQ5J;U9Fiou9h)YcFfJ5Lp%A!cenrEu_+|-0+g3<
z3Sv>yyx83h7iK&IBr6OQX!cr7Y3jJNP&>YH?3P&~0#~J37ilh at S#g^`Wh0v!&R5KE
z&7QlwvSB(VF6aI at w?5yMhI&aTjIh=BxS$({ElaE|nBZ)Tslt)y+-SN2kuP;F(Hwsu
zJ$_?tL~Q{6;Q0K_|HlN(bHAVx26v+#W~8H^K}<`-f4cmg4|dPX?EHJp2eOhL>~6Va
z{w8PT>PFS at n~|vPor=sv*X!e0ea!Y^kz?uIlUOYd5wf2sC57J(JJr%&4zQ^DJ65to
zS2V1pd{^0iM)kcym;@POUvG{rvVBDUV&E<GYI6EyQ;Phej96$@UE2u9>IP{aRlyPy
zA7KwLPn at XRzQ(Vn_q;T_kJc#BXU?P~$8;=}1h+0dAn^VM{x9B45>Ml?2CgBNa at Urz
zJ>*~t+Q^Jy8Lto>?Z7xv_ZuVg=Z*d2tR_&$HfLeUiN9Cp?horJcAzA7{f+QY&&SZ8
zj<OSHCi!`WU+j%j|JBoK6eb^isCr;$({_p at 3HCKgT@?M&V8fN+?%~8BgrM<!zpe_Z
z9nfc5)&lak3Bo3EM=mLn5(Oyl9nNB6-F-cjIEqh3OxRG&<vAJwwtG at dYRSx6&)p<{
z3UNKeeAn!uZtKXqufr?scIbPuAO;9*FpFl}hrGS*KvI!p2p;!f3 at 8P;oX7^u`IBYV
zCFse(XDJ3(pM^OD-atN84st+JmAkH_ at _>ky;Nc79)2Ck=`d+(+TxzgXo63tP2Vcoy
zB{tmW?0V^Cwq^WsR;;_uwxS#+RaE5bzUo$|UMQb6*@z@>NmJ1WkU`^6gaH(;`S*8o
zZtL&EhdmDDJWqJJ(82KwF at sl%PLu}dM|xYX`^7i}LO`!c_C?3)BD7r!4qwZg-7_<)
zYj0h)U`V&Vh;nu~k2IP8ls41$tOVQbEqpz&Y9uys4tR&W1W_{Tca!iB2rN~OB#%_*
z4<0mrySwaiyE*aR);)vMAf@;)IRv?Op3FjBdPBi@*R+C6<@+!%5(ld0pB~B1g`?{>
zhK2R_fJQmBL>)gH!Fw}Ph2iGQMP47*A(f2O-oAgzI?8SXy<F#mTaqP~i+vR%%^@9#
zh>@6M^)%nPn>>A|aJcv{Xa2&uQE2oE5ZPw;1LQ&*2{aLIW(}$#M6Ls=(xf&G#nJX(
zI&j&$nN%CaHkaLhe0`cS8L at y3;Xg8FPnVuudM=oE=PqeI#;=ZZI-pf4?A&S7I0NwX
z?!1y at E1~flM|m$D$L8ITfOWspL}ckF4fVv}1k<VWjt_YrE#!sy?ZrtKPW`=<pHlG>
z0`d}r%V2qz9du8csn67~<)O9FpJ{wK!)$y-;~VlaVv~57cXX*fv~*Bj0oo;^0Mz~M
ztE92EIlCl-mkT2Ea{cVjz>A`KPUeo*I>loSko?<(n7XnCr`3&~=2Hgj-i~$=eZE%!
zf#UWYPNipav5oJ#`)(d$@VXESUAVMn_Ll0zgBrHPu6M=r{ji at mrxFK$<$~TsFJ!$-
z)f#%PQ5jy~DsrR~SihXST4=c#8zw3)av+(M at iRlGIZSYAiF0OcshcF{FIakmYep!y
z=<K0uz~03y`8`){KV)X at sJdBh(MV+(uC6ZL0d?+d5W`TROzx{ct#6$cPT#6|t0=P`
z$A{R}J?im)Cbc=NY- at jiH+ybl3~M~@zRQbmaH~h>GDYOhd8fet;`R;R#|zLdVc at v`
zA^R9f+PT&NKE#h2>twCRgwQ+8 at +SY_)XjDVy9LkvhRaoH2H|g#Ig!dGURo>=1cRYV
z03^U*Gy5(lH4F*<fY}}6Ky*F!vMK)9BhtQxw6S5g`Lxk2zJU0ulDl$s86uxwFa5sr
zSb_35NP4HOQjn9w4&+3OMabVcPhE>QbZ3*~e!mlPHdn9r<l}^|W}uy1RfCyA{%!QI
z^Im3YpV0x-yiAi(cF!q;DOY3^YCc#i^5#ZsIAphQGwa#sn&Ql{P|LK at Yq6ekWUZcL
zq?vl9WAA!58`&bMTw9`>J{7V-^~5Ra<&;??@`apx9^@Cea;U2pDz7W&+Ak6VIle<b
zJM<_BEs?^9Uc{LJC3$)DMVAk8)Nfx+LlXDXs*5td_({>`FJSThTLz;t>L_U=?x=}e
z6Vv`hS*5h-KU^wak}XrO&;wN+3vg?xO{Ed=v!(6rZNsjifUUQky|*gIOF6PxcIt_S
zd^2qxddW*pedaBt at f_o<py^4N#{YmAGC>mXv6oNH)o;TRFpOpna#Qy%?e+?1`!~V8
z?y!||AG#&Sd- at ymple6>MQ<S(^ihRR6|EY9iX|qd?%ofXmNJ2Qy8ccd>?TsS&;@$-
z?bq_}S++DVmqlv3n6l%o314_$Z%g!6Y&ARow!z0A8r%&%>=T$>-0j%H3~YET-n*_@
z8!YcLTnw7LY2ojFM9i`kO9O1;{ghwRR+A-sQM7SU^BZvn!;q><PHcBDX7RT%yQ8_P
z0jx?`FG{_${Cy|D8nhZ#AN(zA85t2+Baz^i^iMqJxc`R4`5&CVpnG at q79CF+EfVhG
z`1vkb`kw}rE3KlCc}k_$HyNQ;M?c+>EVEFn5Q`tif2v_)cfUCS0WT#saJc7!Y3UEu
zC4Olhp at mKE=Rh)>b9_#f<uH8vx<j$s*{Kva3bQNnpU`~MLaD5F>)oZp-nIaok at f1{
z^6-`ErN!s7k1LyP6$YEW#A`<6;gV>y|J1T7kL{nen<V1wAkt_9a+y~1j+T~LmMj0e
zGjIsZ=!Ms%lWP_+7qd576%X18G|Kd<bd+lRcHMr%!A4>3rZMK=zO#F}j9r&{PNN34
z+$V$BV?Fo#A}KESXC2+05BOoGtyq~U;;Rra9-@~O98&EU;uI;p=}WR0M#c+emMB)(
zLm}!<V90L<uD4H>V|bepEDIWw4<0<Ix>SPd%uR(3iUc=2NsOB?<BQ~#__H-uNZnw9
zhn(9zi)OY;&WRg}x&4KVIqQX82a?d{|3D`3%<kXkjkYGE`8}^jyO>nT+9JZh*v at 1@
zN6koVOLX(=A3s`Oqm at w#+f{w{+4my!C3DslAY+5}=Y>91jwCo-12y6xq425k(p0nW
zRW10-{nf^HNBV3_GwQg>T3m!OWg?YnO*P8spIc#MyD012ntTuI^puTm*P4W3RFbcF
z_XSz9A)FZomua|HBJ-;C<+fh55Wg(tGz`RgwHia1HN4|425rIlTzL%QmCH at b5m@Uf
z at weg7=Z^SQz~9VL-~9UI;9#-vCddyUh-sR7?2{WR<17>Yzj$)FxES*eD7tv&A*nQD
z-=GeTQYp~_t#~b6A}jnoQ852JwzntQB4hZ)0|`Pw#fKnA+gL{@y_)4r=u3VV&hFU{
zW~U`pzB3q!Y25+I()wJG4x(IhWCKuhvY3IV<oK0cvU`U23C#OzYM|DM7!sGs2LyVS
zVG(nBM2~XT{AEyA{nqKh($d$PtLZ at Jh33CUr2HM#{&pxGmI;J=mJJ7}J`tnpmb~m`
zuF9$hds3)q=FFD45&qmL&OJ2NxyN58zaAz0!&W!qVR&hDufWJAlm8C(arpO&Fp#IG
zp+j{Fr#_2{Wqat2Pg+hUxPb0cC~FJgrv8-&;Mn#K8w)Pcgg*WkBDXa`IqgWNr-rD%
z#{N1FEw7k4f$i`YhWMSZ=LZm&9fGEnj{v?-7CJ=bpMt`rL4xMK-He1YE&{!IIsB6B
z;QM3y$oq>eKF)|g+iN4tkJVb?LADk464iIE&PvSG<}}RzD)NaLQ&lll7iVqm{$(-6
z$bD0^69i~f!4VV`=l%bqhEv<_C=R at Etj+;nhYIL87JX$YbHs84>rz;=kcj*sf|3)H
z{pnD0UL}7nhPlOht>3l(0~|pMZT?<ed|R>NqsfM)%2*j;PG0Ielm6EoeRg&l51f84
zFu9KYIo_TCoG!-`M~mliJ1(xDh01MK;gCw%ug?idda|~U!~z>)RBdn1Z89{#m9HB<
zoHP{kT|HK9rDu#uIE$lSiX>J6!yKU2_SYM?3T1y7+_A*|x><EZ5~T6ggK$OP at O8o4
z9luy6%G;Hk4 at P#wlMNme=J$^~(jt*z1tpvc2k9|0<Ug!m>q8nWUOy+j3#3xz<;l(n
z+Wxx7J5&)mX44*SHfp$ynkhxE?urzeyt8u{=wE>89P!b%jFJ^im;e$?9j^`*d6<p3
zcr7Ee at c61<?OS(pkDUlnNxDI2i>KHb(vGEZ6i`Smzv|sHYJ&7HjZy^q3;FXCV5b{i
zI<lhNakF6NEnAKJj*EJ8Zx`6VD)t&=20Z($07}06r825(Y-~*O{sQv<Ame6WRoVo3
zXBo%dsoN7;LN(4kj(O;duNopwIh~3lOjgD;EOmi?97Ljtb8CY6seRX*Z6iUorp)I#
z`}%f^4(#KYEPp{d6tw8HguEwu^ybypnVLLF>e|96u+IZ)l+Z_qKnLVxz&VwKdjS{W
ztZ10!jwUb&bBG~plLBOGi;rG{;;=!CZfU+;7n$*BU7A9oHs0yyh=6NzcXWB{Wq+ih
z#zVBmx&6<P`>h)tn8a@}re6lZ2Tpe<)g0ZC_ at 1iU@OP+R`R^us_2p(sT|VQ at rn}k!
zAC)0gOu#lBs4=kBeFrWxNbc{M<mw^UFkrP$xZfNG_+j1!0y?);WSzHfxR&zw9+w2x
z<)M4`6eR`P7p<SZaTW#xCXUqUSd0u8d_<mubTb^Io9&J1(Bz+UJE!;23>ux}y34LU
z=bVfxJi2y1>tk;_+LToprLg0E^e#i|d20Zb at szi@Qp}M#07)-qrXu*H&*=>yx at 9vc
zDJh^oS at iz{jkguB*~U&V$)w?lx(=N{7ul6_DUttkN%evK;w#WX+x644<JK-&EQKd`
z-t=VsKce2lkqtN6AMT=xE}GDytyx>`QlnCPuUN5am!Q<1ty09^o0=tw5F<9F_NGRN
zP<!t^`^Np=`+NU`Bu}2_oby>{Wkx87bAruuGd#;6_+M0m|7s=Y%=iTg&7fl;Ys{cy
z1xRFu<a~V>0t5-H4*ir07H-D<u>Mo<_43xI-$ueev>aYCG2Nm58dzG&4Chn?OFT{L
z4WDw#jXBLYO;L-iMD&G<<mHwhXYwvTo0q&wnpvzFxl~yA;bBvg>g;o0uTF;~+Z1Q^
z(R$Lc>C)|D=l8=Tf5h36q6ro9{B-Xp_)0UU#yXS{N|8?;v$IQ)Q0dPqq&eDq at _v8s
zF!XVeHd=!<8AS4|7}b<3bI at MEq&4}K=z?NLqWlr9BAdman?<THaD at YOOcz&ge}lFo
zYk1gqIyEM33rj6bMU~du<a4 at b`~2h_Kf~;28?Z`_1MO=v at R*fJ+Lm%p6jPzH<in)W
z7u{!k-4)EpZJ4<-oNVG#v<}V7Z4qY;ujwT)4}&T*T#1lpX(C745OU&kt5~THAq6O7
zsQMUa^u62#G|ey${c_wCqSeWgZ@=1Jg$8%jDGn-boFZAC!D9s_SbmX(t$$Gm`s5b{
z(Xyyvs|Ak4OWr6^#o>{~f%=;hDyZ9Lvm`KSteHC{+fCO$ntO(CK%a}H3yzO=c0R2R
zrhkye2PSfkvz!vFaL=<G!&7jsbq?cHJ_^_evW(h2-8F;U1E0vO+JrOS>T|lFY>kn%
zOYBJ~@-0v)u4lmKAn?RvETo(DadcGq_qZG(n7`1_Yp0l>^#6XI18%vvySpn`Jm=RE
zjw!Osu5cBj0PCMO<lo=8?77LUaBvJz)Vnv^??H(*>$v6e!4=rGcw*3*a95M}kKV|g
z<2R8_pP+M@#~Tq5FvorxO8OY}h~gtk=3hPHRk>Px+EX8sH1lFIB<AM?Z&&hL(;xr&
zsn+rP_wUhXSF1m>P|i>4^!-<RI|cPl;`QErW2c(yUf`xjM3|R5<c|SwF;zfuQQaHx
zybr(Z-%Wy!CjuU^X&8n<Ie>1=^~Zt|P=?N+*Bn(i0I~LaHj`4T0>uNtr}u5<J2 at qE
zbAE_!;S5~)$Vw(vI>!pgjN}$s(u at M9!|<#njV1mX{&k67=4^ST%lZ!@wi_^?(*~~{
z4Wn$x!!v5kDWMqq$BY{Cekpg*8HW*hco2!(J!kzg%Q9YX<eyvIj$AnH6WDjdqi~1$
z#+yYnoK!YN4im<;uc_?sB(4u0pQE}BG8o-#I9t~OjNhI1 at H81V7c7EE=+=+%>p`>7
zQpfD^$nJ9M0hEu~LYG_Qgwurg%!w75?Ui>Oc%8^P{AGu%C07S`<fp8Xs0ax at gKr_V
zgE_OkemOONs@=Y4wS6~mWF=U*R<KB}P&~@)?d;0g!_{oY4qbF^0w$4>wxhtTi1u%-
zyAVmBfGxFyAy-n7=ji2Io at Z|x*ti&|sA#I*@IW(998s|;@D3$TAgChHJ;RbLQCRQz
zoH(2dNH50)T)cf>esdb at wfVL0WWdLmNnT+^5j4=61A9O7ShT>{ElmGjeVLoE0&W<$
z%Z6~+E5c&z7Xw^(OQd=X3u8|gJvkp}`q*z5byW|KMaXSRdNOeE*1u7_pYDR;QYarD
zmDLPThxkC&{0GQgz+Lg=?r{h%{0zT_ZFT}@wSuipO|`9X#-~x89I=<mUsP at dNgriS
zksvWx1#Qm1gu}Ybefybk4>oI!Osx2Ft&@o~H7H?Y*wf?T9Z2(YjTf2Tdxi-wQR)zS
z-TB2wPh1Tbn!UawI>(+ms8e6meTMV<&`pYW#IsJL0*{R^80r;mQpae3Dd&*1&L=Y=
z!*BLuVjj)B)dpctWFKbC<+fvvjq9syp5NPs1af~(u(o3`zc42^ZT1H^(WJ$``iBYC
zrjreuf{8t$;dbe**3ow)Yh(Eu^)w%qtl@;FO<Q4i?ompvSYmyk!&O~9oi6p5G)~&{
zw{BOs*I09;&<aI6!_zHJ>h0{-y&?z8MI1~ft~m&*Q|x3)={-tGdSc7wn8O%ZmSi|C
zMG_O+;z-z&K)yq0=A#G_%N}A%;!(GG3ZlMl2q#7s!f9V05plE1N<S7az-XWSaplR7
ziXJ}p<+&f1JJqCfE at 8VGpFNY(iZi|N!-Y`2)wSn;D5_G;y at xQRS2rb^26>kg%x==D
zy7?$;LmRlS#un<`33&v^cI(;-&ce55lOU at UO^6tHLg9mrc8mzu*MkBpx9g)gqu}}G
zR706DJ1OV#{mxg6-J^lZa<-7 at Hbr_-;(hichwz~q>vtTsb5~baw at UWXy$PET7A56s
zw+xFqp|Lt*8qK{YR$(!K0J1mZWDc{lExFp`oO-HY at Z?t+$G7aj8u4I39wQzRjTdBe
z{2E=XmCLpp;aNb5QNlEBQt#oE-(t&9j$zW^?w at ->AJ*nd%G{|Dd2Z;FJ9YA`tpw_h
zHXoxCyfOE1l~)gnZP1b4YN%#`K6>J~Ag&KRIXhfesxM)Hth27Jnoardsa<s~I%XAJ
zI`}Zr9!z&Nu4$QF##e_e(??k-Xc6bBkU&a69g*|ZbD|{TT4o+K<lVgrlMZ}83p8ZR
zMfhMuSTim1cj1;aQYqG>C%PrZMlrwc>ygRp^3?r<cF1VDrx~ObUI1}PS63}(iuGPX
zt|O3ic02G;bWeroI>jz&dzC93>Q3{OmO6-{bw;OXm~$jDlIv8I at A~N1UXDJ)kJ;|4
z#^xndEF~!9g!U5t3ne4Q$oLeC%%XpJBYXd+1(>K*2zC^Fj2>Q`C8R^oqKc#S2%~Hf
z-#)=Q6(&4#9sH2-za_=Hfk2UyMxxHN+tj~({AM3<|NNN8q_KVtq`gsLM^DlGqbI;f
z<`-cJ<MZR=<D^^2!q6YqEXD&_l1)!CsXPZostQTxU&O&5@#L_;+ygJyE$6TsPq_xb
z58r3+;=Ms+5n+41 at WiKtDC^BC-DBKkf)60qr7 at UTbJP_Kj)?M#YKwI3)7IwD)7>Zp
zl_-4J)!=<^4)Iy?9{pB|KEEy*OfiebfTXuaPE~<N2*ssKVayrj$3*TbIGT#PXxQW)
ze6PogV{~^_Lg^D-7~yJgxX#ADDSjJxT14$Wn)3Lz!8_X}TcE at GXb}4c<&zPLT7mJd
zYPps~8Y#VB#Gc@{{d@!EUq0tQO)4F=K<!PFJ({-YSVqHIQq;or-QtW!AK<>Nui2fe
z(ON2Grsciq-mHdFOvu7hRwU{IPk^-x=e7FwEtq^)Iw6D*qG=D5f`r5b!znm=GNPMP
zgHVlr(V*po;y;^K`h6c6&j_o~QKCV<(=%sBI7c4pAv{T{Foh!Cbl~KD7-Gv&*xh&g
zc_!TynBL!Hap3<QlP4hDOSa^)wdK#-Z*S*=MoD%b$1qHow8DrQ`c2=8PTt^zw}244
zF-CW9pNon*L)j0y520f0R@{8=WFV5l_bQy5{H)t0m6TYE20_i})om&q_{lN(H0X1i
z{3f$DO9JNQM!#v}HpC`T(!R=00}xfzcmx5F>dM>FhhA>ZrCntXzHW;SHwsGR>Zo!6
z6Zx3`ek0H_y at 1-rA`+{<&$dZ7{Nax*!O$~*b%VM=mHQX{ByCeCqFAChr;G3Dq<vIS
zvAV<uicvsJX-bdE(tC;b%^tQXvrt-Bw)B>H>-N<B!Xj&ecJ~&05Zz}f7iB!k?q>-+
zhU3PIcgLX>O|QfhSFoucpCXk!w$CF~ni}48++SLkWy{u${b?&_PA at 4>zNUXZ;4l)|
z$DXrc;V6Y1Y&HwiGXF?l_gLF$#dGqnih$076gHjiY0x8R at fjy>@nC}efybaw$>b9%
zFAP%`^RsR=o5q at 7ri8DT*yR}lBK<$L=8S<Se`{W}Itk at D<7 at +$a971tJ^P1z;_qFT
zXU{R8D(WT)`ti17jAvo{sUKNX?9WM&N<XVi{ykF;<7 at T+-u<F}E&Q&Xu2~q?S&B->
z-HLj8f<w%(nU3-?;;P+mPmei|2G{j)^4I~YOIScXz|ee*yl|$Y$+nI#`saJUZBZ_a
zHO9o=CthA!VLj#FV2U20xa`BRDrJp9T9jDWAWLB}8yI{JO}M4IsoR-tmGxGLrE_mh
zu+PUVSSEep^70Z8HBVR+nnX1m81Zm0|G_z&C%)n7NHMP&Pb<>o?s1tH{W~MDz%v1k
z`R2JZKQ5GkeaG%A7v#<O7ZsZgll~Yg_iPxiJz8J~EY=G at KX1rmQI2beDTFFhn(z;{
zSHc1r$eoqfx&_=+p965 at OSt$s9YNsrD`N52*CAkoc%~j*%o$wJmP0yDFrI}%$7b9a
z&T6Qit;e=*xf}UbDIVk9XN-iT9!fTlO+_aOFA<j<e`&k9jUQVj at ck&4vEri&mVv*d
z{pUg_|I-O?o at vIV1l7n-Vz4y{?#HUPH3w>#E4=&NwrpYspH|}C$=oRB7QNU*7{}>7
zM&RZ^MwjnYj;obR<$}*0r|WApXAWrJM$S|8QhgzI5{lu=q)4^$`Rvw?2%%y4jV(1R
zm}iGG2&gvs%Z|-39PEXW$A;ORM~s)4nB3c{_t>55Ha#aSr%b{wY;A2_NAT~xHjH{c
z>cim%`=Sr#%eL2)2ox~r)t1jjuODw{0^gDvnee+ at e#>Llmgmy=xUq<BeNiS7%N*9#
zWan11TvW?Fyc*k^obfaqM-f-*@Ot`XO3mb<`a|zmh>1k5>eo3}4Pea9F%=oLTAp>0
z?~3dX79Sd^Z%ZuWUq%78Wn2?8UvyU2&d<;1gJ1YnYa%G*P6;nPBH~AvEs+dComB_7
zwq3gW!HbX*0+3 at V)1 at pSdgh~?t4SA;M84btIc+BRPmJ0Xa$gI3JiL>iE9rOPv5Wo4
z$fdXaStUWSbU>&%!O{5N7od6qYAN{MUdsL^!M==o at FFhAJ|p#S?Y%=zu-Igtmzyvf
zJ%#665uSy?i;MjM-P#>Gb+xU`DTdVl#uraKoxAQ%_L1!=tb5R{ef<=CSiR3L at eA|^
zCdK*vYSYobZqN2!`yUBke}DhOnjJ*HDN!is`2pl~gY85sMr$QyjD`$-Wcb(s19Px8
zlf`>G1uW}z1)|e-dkFt>=D(Zg>~Y)|@GrV#!K5%|?>&T)o8kl5rKr|9v~OfwBFF#5
zhKfzn09;+0jy^0ajbyRee2VkcM0HK|cwl|?1of{6(a~+~jWa;BW=u78&4ak;)>@;>
zM1>z9k{(C5>EtOYVIITsb8o_l#}@Qwp*>W-qUUc|v8;B&zU0}XeHtG{c=rEQo5Lr{
z?QKkyBY-9;=1nE4wSc>Va|yO&9M#3+Tlu{X;J(&p-0goHG<kZvw)D8_yCXvt3<ogH
z^`p-!Th0yB&C=q#0g5JR3xb%Q7Y6R<;4xc1r8g$wg#aQ?2Ij9ixzBniM%tyq3*mHJ
z$ZBxxrtfxTMpEz08&WO~kt)rj>)C^Cm<#HV;e?P!UX+Ex4A~pf&MwD7WKA$`m&evL
zJ_A77Y!Qs&mlqO#)iMHA>x8+6XKzhe|FCC}7_c#RG9lfO{G-9^J`Xd}F8OpmO48WL
zL$DQEGJW#%bDlIyr#6xBB}kyp*kg2md4NX at vY0Y3A`<4f!G1 at hOx>%!MCj?@FWgB!
z!+xfD+vhzoW$81+%(ZsmHXc{#8LmCEjfX*1?6=JM!TBB^Onfsr<fYRzmUjZ%f2#ps
zK9?0+G{^Xsy}hhGl9aBHxE`e5P)Cts_MpzlZEwMWjm)pW7Ly at XXGE$}q%-cXt1`e;
z>}qk5>z{M{iHKh-(-Tr+-Aaf5fM+F at C_YO|c>7o92u#QE*>JvvqWG4GQ#7uY3+wRV
z5Gw8%H_<yVws{Q&FyB2{8$}>m7kW=VF^5z6;~djER~Y}4Z(#+py^ch=FU5_%4zPTt
zeb&()@zO(!%nsZYm<b5)F|mc(^JF#?EK3ftOXY~)4zX6k at Q6I7pDO*ZZxY<DYXRSj
za}@rK1r^@-F5TKVQ?I{)uIKZ$IBTHdF*bB^3H*NDfblt=AG;~&8q_fj0-Ne9$U^sk
zf2L4`ThrLu-y65yfK|lcoo;J-KHtm-9BfSY=xWb-+*T!PFrt?Yltc6a>fsD&v~&GC
z2`{HjA*18{F^hcESssy38C at Q*QICjBJZ&O+OV$8DZ`yX=<o09x%N4_R<P6mrt%Nr&
zrMLn%M5#?Y+Mh8VOm9Ae@|F=AiI9uTHv*b0wBGmj``_N%b_+}uZXaQg)n=wF8UZtC
za at zTfc=Nj{_ZH at zENA&QhR^E at cdKTaL!is4>&Fqn1YAsT{DixzJN;LGFC|X2S?^5l
z;lqbXFEqrnC7qWT89Un6_Ca4<+5zk1?{R`Q*>&oaWGma31ZM-4W;H%9Gk+Um&r2Ck
zM&Hq9I%92e-wTrULefv{n#~{<L;iTM%fe1dUvZE0l6|5OXD%pv??VU5n#|a0)T9zn
zKDSvI at 5<BkQ|21!ND(#*F79VCve((R5bV-6{)FE=pEC8$c4T&@ASyn(bKg#teFE>j
z`$<cPU;>iMzhB*yCHCQ8BgWZ0x4oWlVVAGp)QjW!6a4uPC*ja_U-&kU#Se7#lNS!W
zeS}f8YMrb;Fj7G}GK#grm=ekykVR-9+896b at Fe#;_RS<MuZb`}#57rt=lrNNZM1E$
zUf47BzdBv!7%c-w#eS=6t~b{bV?nB>eYrBu5zaVYCt4Q4V%fMhMe;>|UVLo3EgkO?
z85UR=UE9_zDw^ZEAxor$V?sT6r;v_LQ!pLm6A>l+w7P4aiccVgqXNUG_<^wd<8mdQ
zbwSfyW<6x%+xa4fF^~u7d)XmTW=eHNZIVE=?*PCyEXLq7p*I-Pl&ANLO?;j6OK0?O
zjz9M-ZsL!_ojvId&A{>T-~wgLnkQx959C0b$PuXRim)tHPBtW_c!(u;kXO<q`!?E3
zA}x at 2x0owWB~ZCcSzCJ(3k!VHF;X_!dWP#}tkQqd3qcPGTQ4S!HyG1eQ2#BacKJvR
zW>!=U>oz7pZBLFO*Pm5*w0fY#vbWm at k|1Eg_HB1Z_LhmhGO`>((Butp?c~e0D>t@)
zzstUIIa$HxVKu)$FRT3XGx8O`p);o0rFtrr#I*hY-xzY*t|MoaqA<rvVHE*o;`q;z
z)l)S_LkcBN%pZ7`x*Cej?~ky0?xx4BtIKtmSuT&jbzQgEc?@%Y)Pk+6ceeYr78Bl9
zRoskLZ)*Rpv$QGNxxce7epe=a1MA+Dv1=f3=Y_DIBkj8A3eQ6Mf>fbT*<Mei%6@^n
zmE2EH4fGIU`Nbber)8DF60<u1`};>3R1I&J!RERh1=Z(oBFXOR5h}nJ7&bEEN}M4=
z at ghBLQZ2*-?eTY;C%B-gq_&i`R6;Vriu*=fHRJPvV7<`@`|SzAN7if=%H-De5RL~#
zOR5DFk0DvHv8l>??14MlF?w2Z+oQnAR1hj~ruKKLO|^nS(e}jnhT<Q2-jY;`&?xX|
zuD3~6YJjT<AKZcIt!Lt$%m{ltE9Fzj9>u-Q6M<|RNM(z66)u*_y!Pyz<zwyH_a>tW
zr4Q~pwDFCqwdk4gr|y@*@s)<gDG3GqTM2e%^uef_O=q~1W5DFB6$O<cKkZ(*wQ$yd
zV`Y+OXlWtec8Y@~q{Z91bkNK4Q<B|}BJ-Q8GxK~SPOF~@X7#AR#CuNM606~o-_*k<
zPY6rzz#Vz0Z$NUQ{b6Eh{XCL&5nb{jENc$}4h7w9k0j2^FlPWQI6e6X-N1^#gH^M5
z=6(nG404%&5o`eNqJyS?nET3MGi*Jr;UCj}$fl^<qpBzGV9s|NQbUkAxE8j<m?3MH
zR at jv^OSNmR&|@@-Lx<(50xthaQ2re9A~Pb&K&y{~=8<lfa+rkJKmFG;vZg`{AbxMk
zp2D&u{8N(<3I4s$nB1J1;AV{1$fcj?s%_{vdu1E=Q~h(%t4rqkb)R*!3F(5o78T?@
z9<lBq&W$ZJD&S3*Q1++z4kyE!t1XMDe~j@^OEwi3ZRWV;4`vid)P0Da(P%QiW!P2`
zQ|U26Be}W0>$^fGwYs=V;+>SW?{~k1hF?i>w=O>HieSI#o~^j#zdP3kw$t9uZy&Rb
zg0ZrM>Oi2Y-fwgb3lGl;ZO44q?gnt^zw*(kr02M7$omU86)0atMfTXB at m+uvuz|C)
zt#SidZujF;n1%Pf8O1w2y8uzESQe`NQG~AUr at eT|x?}an8G_8B8F6gEsSB<J>`k0a
z@|CK-4zK}O5V_vsuY+ at d-8t9%i;jK=T?J#h$EWWY6k#{DyS)g_(Hb|G8u;pS#Z8fh
zb~(Zqm*B~~XYlX%B2>D^hIC>(g!QAt6MkXGL^pNlgmoKFdknD1yTmy+Kr1ubX`}jp
zravvS53A7{Qd(<vI%iDDydSYRc)^^~Rc>}$byfwVnviX$c``W1xw(S<u4t>`5zpju
zTk{pdqKa70bM{2U&81iQ1;4$E=`?{D{Hl8B8P*HbO*6|nrcqo-&_BuwBIz34IZvy^
z#psWgYYRh7x+&T8sP?Lw&&&bAApsl~f4^T5aQKfk{#O^LC&B(F!5oHG=6_`Wcsojs
zM3CNQPf<;`2vhTHnH;7VR4mm(YiOV%duoZ5g!XsJxu#@aMsbct8S(dX(1$XA?dHLu
zhg50 at iY?eaHc}5$)ClFj?%1CB=M`r2ACd{>E9YMDG}cQu<jvhVyL1HPi*;~jvj4{E
z|A<XB3cj!R_9sw+xx4i*M*1DNY_SG7!zpc at y=zBeOi@)Zp84%sV<x&hhfQYnl(q9o
zR{5%sFX1!YL?D_6ZHWy6w5xjG=y)6v`r`z`Z>=iQ1|uR+CRRUEt#Dm&x1o={B)2Ja
zmY<evhJ63qvc+jNMynp9lO4!UUl{91w!^}}!p9Eq-o~%DM<U#G1CVIA1YeIN9|~BM
z*A(-q7eG?C9c=#ssGb_sqv1qf^8Osu)7uy?xwSu%HsV=TX}4ZEqnU!}uGDKXfVu%{
zOAKtRzT at lYUQn$O_uMZu3ce~%iwE5$8iYss5|%;o48w4VI)|KCf^BIsvKQ223#od{
zx?6?%1?C*#<<WaM%_LV48O-H*UmzhN{-4$!V|%%Z>aC{DHUd~2DdJ}RT#Vg&vz|f{
zhs}doRdq{$2zmm|&{5DV{JZhxaldJg(O0s3I@}#4n0*ad-8%jb|GAHO?|)Zi5K-P@
zdQMn2NToO6M626eW+nsb2(&11E}W?{9T&0g=rA=r8L7p&vnbX&sF{Ss*rfLF^!EyK
zRPi}Nmqe;5eiK(jN&P0pB$xobW+wD5EPfgIlm+SKXLBqF3AL%wYbx5rqg7AKlL_l#
zwC%ZsD$R3)P0h_?>!YRXRN5X{6S&Y5=YdK=g+$yo?j=^*s%F;u2(VX at A>1B`PdlRA
z3j_9<$N1F6vnbO1OU}z!e8QnZCtQD`_+}Ao-5yj3{~pLQtJae}A!*CPdBNtPt=sJK
z4g2Nri&xReEyzjSF-3j%%<&?3dxi8*|J?9&p5E at Ne?}+6jnT~KI1P=QlexRM{>evW
zj%w&K=!O5p!|ln!;x_O)#cUt>Vm^K at y<}}FL{3RB^U_-SzrVa-e*mHg>Z@$7Dm4i4
zb+}arW4^TSuo7llj98bw_mDMo-56Y^ub?I(U=~))s<)}3qUQOrE)PHzALSPJq$-1{
zCZPbpS50W2u4j*3%?!TC at KTEpwM6S%mBj1K1I!gwx at 5lo$lCOV*0ZT%wM=VhsGi?P
zqIs!6vE^8`qjU;m2OqHRd*_DTn1MzZlpWFSI;hmfq(Sp_%ZPt4Q#{0F225TwpsV3V
zhGtNWf35mhr%hOf>ddgki}0E2%<zCvy(lS4!;eJkM8|scV-9+4-B-p86g?4q1S!v5
z5rI&{i6VXpLU&XVW~LwoJU<`S5a1h~?-&@DE0FF0m4Zk>Jp!TPfEz0;_SvImb{cM4
zdv|SP^fQFkw+cwD;<zy~V=8v=>YLWh75c~m*)vyx(|{8jC{|i5a-M+)Yo<YFcvxiL
z0Ni0$tA;U0^kGzmhn&i66}1`WS&BZ4TysTN`-IJ{UJ0xdwa90=Q!{RWSgH+tr3O~V
z4eEC?OJD)U%+Pi}9x9j3z#{?S!ou+dZj_uuPPciQH}Pz0)o=@pta~;`gv}!SPK~FA
zk}s~mL5|}?motL9e2P8)g;8fi*b*3zd>JN1MDvz|0roonqHgJb-leK_r6#}2!*N99
zaZeIY3GAmc7wM#qCxV|7R7d-ei(;cucLgvv<#<pfKt2;-c=Kl=`2d!*GV^`rZu8m(
z!wHn|?wh*fO?GxVs`D~FXY{!OD6;hVhXR~FxQe?I)m{10QH6P4ZaFiDZ+c09A(w`N
zbsZGg&FU#Uo=)=e;13x3b5QHTZkw$_b%qxuK?y3AZ at eE!0Z8}_>j-n_x|8$^7R#r>
zi&>w}yGO`duoXm`=x<450;i9mM*VNECoERF#=6+!x!h;Z`#88hT*dZod>Ow*nN;Lt
zCb~JtIzvbY&u95?q-|RHMiJ3tckzd8)l#2V50p%n{X_LZclSef%Bn$rv=6A~pjAIB
z1*mj$Cya{c3MG&`D3Jd&NUm$Yv~sc>vGHTyJ}bpW`{`;G_^>c{I1omnSB8%4VDV(R
zEne3Rc>H+tbpwHtR%BMW?~OM}LrV3m0ofj7r&hL8?y!sF3w}=6D8zStdA3ao5IA0V
z$QF&BR_dpD>xsza?yv%PLEpMJv8Qg#)&U~m;#rdTFIN9unf*0R4}#$gkbX5gJKLT3
z!_;`;%WhZ;H+X9?5g7f<g{woBa;txqG=-jwe5rWDofxol=(!vG`i)3S+YJ^~x3IuN
zB at f{*zK3h0MR0i2j3-{i=5;+CO-BK!Y&S|wC+=5(p$Y<Updp`qoE%Mv$n$CgGwI5I
zP@(5)1%?YtIF|(Kt{OMRhs8!mq-6-Vwe=M5odftcu?Lw-x6bRGxW*>#X!=zsU_l)i
zt#Lgtt&J+KxJ+dDZHfHW^4U&T6tFlqH8Z-IBP+#0y=80-32{;<?*H;<qo~(ggc}j}
zd^|^*h3?qEkT`vAaSbb<NEx8rAv+tuZ{A#-jxcrpeyC-p77}IQkJqOn!(JX;W*XT{
ztRZp6P$v#vXk~$l8y;-b35J~2!<*umKgxXDmEe#0M4uMI`ETWXyQzr at +(*N~>gO*h
zj4i1&$XApR&Njm2<L^YxpM)7?a`}Th+>8Z|5WB`bjfxq2Uokp_St-=!PvzzYR{n-7
zCFKiTgOT6Af*zm$p}_)pY8W}#wb13h)t?8s1Ff4=9`-WaZaiH|>#3O%DM;4%>UuLJ
z$k3i-t#jp9V|O0VYy3n%*p2e3j7|K|=quTf=s-8mXTYh2yQ4C^LL21ceheqEp|L;`
z*Idygl{uz*8eGa9;`Q~Zu}=Jn4Re6FoS>pBA at x1HN*c$?Vk&IQM&oQcW+wGdZXU6y
zOGVWq%+1Y>h6pw!Sfd8n^K;PpkH2#TlsvAtNsHjx1hHFbXX{)I2}wRXKOCxC>n#*V
z!ILTch_Y=}!@eC9+?UUQf_%LG2K*+d(@bWW7CW`^E9bGJi5n~?&D}M$DVywAV<@lw
zsSao&h&$VmuklTH5dLtFmd4ktH#Om<LpCf+klF;yA6H at Ogx95gN|i{PC_z=ATUoFb
z{cK-lNj^%&&B$lKqRw7dG)1>Ho5`WCG+npB{Zz8stE5R?g3mQqKoQ_fEu?QrQv)Wz
zKCjrU_1dHy61e=pe~_5!rLobfZU4hjU0o2VYZ|Irsmf#Nf4KP|7CuOPnP|P?J&tYg
z*nN3j&R^6_B<klFnV<7-P=B=`;o3&sCvx1aRWp9xqX{eN2Jd&~?kCg{SUnhitg!_Z
zsF1m=-EBxbPt@(q{OlM2($jP&U~|<HToJm<=`u?y(iK;%5;5=pG`M{4*{!rQtx|ZA
zlECWryh}=lw`%#YA+&(kK?r4-B|bk!q1P7uq!})6RFA&M$s!E>-TpQ;;OmC1H-=(I
zhMkM~cmK2-?~DDHh60g_enu>zf;`I8JmypWBmn^Q&wE<0P29BKO)+Wkc=HnqA|g_~
zYLVbjO?p|}WwZ1%s#kc%=d(ugTDCy(Mi3GmbrW%?xZ>CO%vt?C+_LY#Yutj=hSAs2
zd*~<+ZlR!yJ1k9ewF;S7fJKjPTe6Ni`Vu%ff8KOW7VlR$T$N)9`#<}?3JQ&0hik(h
z^g<g6fHGNd!7;e<rvi0knJ2TKaCp&PAKqlU>~@O^>fhE)v{g2XXkUiwVZxnjeI1zq
zl4$NG`ecHFe!CJTo%Y`B=3df<n}T$OAkNU^^6YT2N;qcXykv6N-M-62*(OV@;s3D5
zqcub1-%(?viTuqXG5v34q+UdG8M}7u6OE{r1>goOO8a?br(L!XeP)CsIjgw2jFF4%
z-3Up>`t{$|uN|O2;rjkf=&+s|KWk8-$}PszFydh{RRgKrXqZDw2NxesL%+4_`ou%&
zG0}B<T^U1{%diyo`Ub*RWq%BF9%`DAmixFimq$U=pnWE;!szWL9s=q;AZJ!&9&fV^
z8$-`)?)|AR{KPFOnq63#wIW&4AU$}#ICxM~f0j at HJgWMh>f4l_<L=9Tqm)_=9l-H;
z>dt+yF?VfN_3sXra|@!$`k6IN#zdAE#quhmGqr<#hH0D*X0Fg at 0`$@<Apv+`Z4;HM
za{^m$IP)!b7gOAXLp+|-Bw4`}d<qtex&6m#s4nFFJm~Rzc(xXqejLlJiYwxxejB%G
zfSn at V$HXQ$Ixt4F7FJZ=mEJy7&MXz->e5`5sf%{gW|~i0C_auI{ZZ`E`61>;tu6On
zRDV6$#!B_aq&p}BV>~TB54S+jta^u8{Wp<pRBjy-gPk7-nzLnbl2?Bgev#UL^736q
zZkSl-fW>`&GWH-fg<lV1a>|l~Zh(4_;bAC!&qZ><pm$V1pEhAN^fjxDo!nfsE5zrk
zJ7ad!Da?$r$3PAtj{vi07rZ6aq#M>DfCQz*yTxbAXPx!F=SQUdSC_{#Ce1Yqe at QY-
zt`1uU5;n)=8<|R&G?+%Zd6E_cskCLdrnPrfYCD`Riq<AQ0FX7bdG^?nj7^$KGyuvv
z#3rQt?!7c at Q0RVJ#Qk-k2oH}0f5T1y{MN98GRffHyM<pPuKHY#5Cr>Y at WhrRM4##v
zn-u$sev|b(_Wq&X3Kb<(OE*s%tA6(2vZdwRn0ZGR#>yb}^86yrv9Tr=YX?oR#vD#=
zbMUYtQ9#4c_gTlr2siAN7OciL!eGw&y9V5g^FsrgLrQ!<MMJVlF@{<L*NrhwpwiA%
zZxgOlVb3W{X1UTK{}>$6UtvubBlz|3_*|UIKq2|=FP&8k1x6tq_R5X{a%;-lp7Lz7
zY9_Mom2mXL{~(M#o82RLn-Yn6TXy0f0~u1_M=u7R-rGI*B;uc)<#2l<UD#kq9q}kz
zd^s>ud<lTZ{#E-wEr4z_!c?6^eHlg3c9yRo&(pY;zD~PG(B&_Y7O at AXwhFqf|NhyL
zE#a9lwD-yTh`R#?+DPT=rZ--XSp2|hRk0f(TL}3z9$ex+RX(A at ml93muyL$+F<;*E
zZ`C*fKbF{P&9TKDGg#O-Q>AX`WA<&f7h}=k7BMZjKT_wMMk7%dA2AlMSgdPnHTR}3
zHR-OIWz)SnqnnNfpV=*!Fmr<zf?9vXjUV*I;&rSW7G#E9DSR<jLBgwsb=?%}gVRbz
zpn5-g$dDf0k&1S&;&?ooiHp<0LdX+PyH<PeC{3!##X5mf%MR1 at kH8&sU^BX(SO=mh
zGEi`~S?#n9F1K&HK(Dkjf>JG;dA&|SQ0Ms#_~^u0g&no5w#*aClqH`TcWB~!M#F3+
z`XKGmRBLvO0 at D;hp_k+EXAZ at s%*u0ionx8$-$8`cBPYj=N<ymkx>C*lT{Bj9a7MGI
zxMT78AW8cR^Iz6Engm6Q^pn7~B%O9L&3R`7ec?>~(XsLq>!xjgDg&UvOmg0r5wpB3
z8gd?guZV|9auol5V$~uY6w)s~YEWLAGt-ASTn4crtO{mWv%KwslXfLEgC~mPiDm4o
zW7~+iund)3-i;omZE_miimGG&PI2`MF?Ce{(BLb_kN1Q~Dx%aUsy!|D-xsFDldQ4|
zQ3H$r%*+r=)t4Wpc$(1&ooJ^_#^%(o-ckV&lb(5<;w#dAnaPv6Fv}czJKZGpx^9eD
zJLMBU{~`+{^C(U)VV5JT^d47ho!M^cu(aW8|0=@hlTdTSspO at ZAtm$X?Q^S|BEN$g
zJWB>4M7b{7Fho&_roQQ#`=--7ACT^JNJ?99qV<1T_qqW8KCL1S?2!N>v9>aFy|sBz
zl=yQvoW?L%H*{_$?T^C~>jV_a!xE2}g8R+rIPA9%q~#KT|N7w%<Gd5n{WYa9HWoer
z_1W?NLmGWNx8liL?O9`nE=mT<)k8Y61D&itE+dye at k%v&ojc(@BPhqGus3*D>gi&x
zP=+Dp)^F#3v3?&B(fQjHWcbZ at KqDw~0Yq3TJ{wDZkYSd5d6jC$vs!0XVWvcSgaz0@
zVHr9pN at a~cixD^HesMmun4MoIxQ`zdXP4JXzcP*&qsX>&n^(TEp7>N4vSBE#un#Bx
zD$h8&5l>t7i1XR22P*h{=UZWadv-S+A+#$KW4AlGt at kHec7P9+K|OaDTK?tpm(wN^
zymlF0RtH)4C!baCTtqoRkrHJ7>@ganzsHc2M(KHbUF@*r6jZN6oJ?pf3qrMdH7_ix
z(z43$1x7U~n)^W+Q*p0L0$0HI%IJZG6#Irrzlw%e2T0^3>ihQSm^C1(-QY?+iJ<j9
zbJ%IwTNspoVt710T3YgKzC2~rkzu6V{#;Xv6x?MX&-`43q3$c88}~PH(AF)B<51bG
z7m4GkD7T5NvV9#9F_4Qqc5~r2>P<`h?^2L8!X!ysx3;%=h^n~UVDhW9l%Nq~NAl?1
zii|rE*$CAVpU=B-JI?mR+Mg)IwSK{)G6u}vO^8 at K@jq{Gm(<x}w#1=D%9mDXDO_it
zB7K9l_5kbQ_s44)Em~UAE)25^DN-^WH`&&zHyTnp3!`bC`iD(5;FMo@`*k!9&_tQt
z5#i=A+N^)%HB<lE4Vk8;Y4~ao9dlRb_J^PxSci7HZ!h@>2t^lXJ&<XH6!yw&m;ER6
z_8oACYIOwb_^RZ%LS`#$ARPP^=#^E>7xbpfPy19VR3vQIrED_5ph(|x>7eLw&(Gf<
zi*fu<jVl`m<ni{JJ-2z2t1OMiO=oox06*FefDfFY-Q)7ZM8XX7Ye~6~9xw4qWR*gW
zg95yTwQWC@(VNZXOy~jKi2VCkX5I3dHWaUr{kF<sb{r4b6D#f&yW|G)&w{xGAZN at V
zmO>V=Ywp26{gqU*K6Jw0nzIY%sxwq{M}{uO*uHN~#q`$H%wS%hL&9)GmZZOgLt at H*
zL*dbx57z)^tH>LDBL1)lFEhPQapunLmMiCWB#lQ;yfR!OUE53G2nmm~-X~40%BGga
zqkIEw8i2EvBEw0K39x!$*NGh^!2Es9qxKtK3nX-85~J9A`z61o52>T1c^O2wK;vhP
zctk#+GY-$hYctW!K_)^D_n_^tG;XyYHONKt>hUzL9*5D5W27S^f()B at f@LcrX=mpg
z=6UEt$u>=X?_^N152LF7c<r#dlwz2p1W9xXXGyKb-iH9h80$G68`>4$<n*=;V3j-}
zh#1J6YSOqrPr)zuq*KL+kwiYuHgk#<8bm6H0Ch4IE~nd_w{$pwjjvt%tL)Gx1~m^X
z2b`D{_u{dCHa_3a2y_c|1as6|f2J=Hs8lefP0duh(kK-b78eefuG??7g(YyJ+ia7v
zQY4PH#|8GTD?P(+wp(Zr3G*}fm!QY?P6 at 3O6uQ=zXtd*piD8qEtJ4|LH-w9})E-0t
z9 at Zt-N(o!@r*Jjf#|^3fL7!d+vo-v$u+B4djf6p)d{AU0WlY3ovB6YwC4!=xJqpJ8
z$Td6LV>x*_aF8&D{=3pVc`^s}$+-o&nJ;t;)I1je<9zM+SmKHhdB7pi5Bj|!^wIwV
znjcl9kjZqoDU<;~lMNCiU}HF=mFc>y#jeyleitXZ*D4f3m~%_SB|!oqrza3OC^Vn7
z6l?SihGy|>>vOWuehztDEGlXwUMInWdl%9K=<b%5eUYl7{meVt8nm9KOC}OuvRSXq
zrtY6pDaZyCjpIy`G;;bOc$s8j1%ciV(68~Rrl32l_*TP8&pF$GtP5%&tBI7$N(w1N
zT8_We#1urR_7m5?+a|yf at Xhl-YLZ5!rD~aCBG*6_N64U><fTjHBNdhrPu+}`Z63)&
zWD^>P)LWGgdW38jnC(qfqEJyjNI at U2nU&ge4V4Vw4 at NX3Bj*Eh1)i2}ZXSEPvwKer
z>-vevXY1FXeqnSHMuij*G?g$$U+c?Y0d~j(rL=S!kA3#)0Jt at QgRM1KsZ)S)8Q-$~
z2e~WXq~Y`<Xv)XFPvF%glVY^eBj#Jv*95!6c#=#0l8sOKa(erqFL%ZCT3LN;?fP{j
zg$oyF0JvuRn4?ht6Cy<CLhH4ou)K%%vh77?tzw3GyBZLl(1riJ6yEc<{H}j&Sgjc4
zwwmWs<@BIvt~J|`hP^7N;Ub43)T~Nnn0!pdRAo(U{t#xz8H*S4vwa|N1lvG{NN=N(
zf8X((pEDZ)P)3`Z)9Xe;joQI=<&2un_P1)yWPoUn3L(GHPYJCY2%~IIPfHL`$>MBA
z`Ad~KWm6}p1m*%5@*Ov#`nW`x)_N>-tg4h1kTWxJ2J6J%bStBK#Ase}JiGojzp~B@
zSCSJx3qPjHw0I- at l!Jj{>URh{oqlXP$;7YbU8eGIs_BP&_L8ZFc_Fc at qbcl@&ZY({
zmW!CmAc7;ln?LE02FYRmY8GK?;%U_}j1)~b|JN7<ts5G1^fzJa9+h%8_9ftjN$7{{
z<Cg$rm7aiN0^>Y3!>L4P%$t%PvXKfF-1gccC|9#-6El4wTk!o;-x}SBh);d&6wVg?
z7Im9gftgq#|FeVD-79=C&wuheKAu_gOsx{*hT4FoErO7{fav$uA{iGX?0fZtYZa;s
zJ9#&0L0wY4cH+(zf&Efaej;EJMN>y=y>&qLA at LQ1n)&TvQnVeT`UX>dQSwie^l}Vc
zTF at 4mc=;pLOSK*LVv%qYX)v at DCGAAu(~X0SXO-IBtgoal?H|7)!a0A+fyNu2oQp at n
zZ5Xl at Z)NE2A~JM`fjX{G`k0obGecM#%b;^en(*b(@B><$M3Q9jrS!UnzQZMr{SE5#
zd*hr!^?NBr`+q?R2O}V^Uq*C?#7O^=?0ijIj82=v<Q)4xWEjK50MWkm<!>l+uw3(@
zCkkXC!(>B3tiHEw5p**ONulyLt#3L~561pp1g$jxIc7vwv1vP%7DIz`(Gb6Ah2+tU
zgzqDdJ-=NRk7;*JO1ER+32-2MzEOft5h8bB_eZrdx5i4T5ra-(q$<NMwD;UGXrrXe
zE^Y}O-<;4jH|~_0x51q%OEyWj-}lQle;!!;H2VquoS-k}`Fym*|KCaEyyf?Qmn;x-
z5WbxbA&FU at 1KKVcwB9^QFK1<Wh>?~d>L+z(kl3IooT^MXZgl)w9FVbf)P92lSXzK3
zTE~AYt)Y8++aTK#NW<j=dlQqT?VRIM8444Nq{vvLrV8f}`_T}z8 at l7lM!BcQp;;pH
zZ5h?3oNeCT7m*Qo)b84KCgIKd1rDcaVlCNN_UZ$40I6usMcmkTxkwS!2Gm&<w<%NR
zxXgQekH!{IDH0FMR=g7uOY6%B3N4)^Gm~n4_vZS9&j8|Qk1jQBAJ#r%mO5_P?8M%@
zx2{{DlQUvA-4<J3{2<RO4GY4}l$g)Y%=C^TC#WVJ#|-WVRDkZ9Jss5-RuJofDeW1C
zTyB1<k3F<6c9U$GyH<?W6A<1#{WxEhsK6Y;{2;B+Qa8#J*9{ksh}i3ni29y*iCfAW
zO$M$h+D_^`7*3A<D&0sC!@s&(u9%pGE32YhDKDJNUL&kHY|p+eKW-}AJQkNBq>xA#
z*}sba>qv3qzxuu#ix||`08d%G`>p(q{r0Q*G_wLx7I0Qr6saDUTleQ;Mok~46cbNN
zj%`Kq65i}b+5K!}Xu?qO#<<DPH$hpObM%R3WcZ)}WpTjat!WsPs1*PW>Zigf$XAt>
z5VgRV521jeI`_D*qzzu#2h$k4>>`YWcMqMgF}q*vPdlXEcn-FJ!E+nr-{!&B_Aspd
zvFKR(2qNDhPM%SvhK2yvfk+8y+uU8!_fRAhGv@@}QHE2&!Rz>$oGc<5Y>&S~*lVAu
zQaQWSM_>xsR8{zCHrmP+41uz_B9UT`L*L?DS^t)uO)<PSt>iGxVR%p`ozrZSTNIF;
z{A<qK8*{CiYUD^PQ9fSmNupvnBrtV*y|%r_Q|u^v;U1Lqd at byiLk>n2NAeuk+HHF|
zW!smcQ&l#pB4o+d_GQxb5oD?*k?CWH6=2pauHt;D9<s=dMy+2Nye@$UN49|;Kzz8E
zY9K5~w>`K#t2n-1BXh!G>>4^s=|J$#%ocVbZF#`n&;|#HL7YKdULVb==>N?kRKC8A
z- at 7`qH`2=(896%|rW&x9ZbZIkRo32>%i6n9&86xku!IaExE--?3G1^Ytrfi^3Km6%
zPsWWto^3DKUv7r~yE at -4x%1t{l!sc^*OqQ7!J4~^Lt>r0>gD(w8i?!R2D`VuSjCN!
zM<9R5iw06ZVjKse;bO(3ltnWWF&X>B{K>ivW*RI1R(+#$VAJ4@<CwMD`|Tg+?J8HB
z?d>OROniP7Q{29LW4Wc$@`2&<uRgfD)hQRQ-$Cia`{Jg1t~sZ`^!hD=(?%cCscMDj
zu`1AEs-?#pC5_-MgzVhE=(3ED73FO`SAL+<O#zl1S(_d!YI6K#dtTaAXyMF*ys10U
zGlqz(>?Y*>)oPr at kn|uJ%|AhOrWZbL)COjXU?PGC8tD?Y at TkDz@c<`EJz)yS9+z~V
zqWuf68>|l-D12>45Z~QdBv)AU+ulFNrlx09PT4Ds53LSrxZ$jIJO3*Go*qL?G1EuE
z-H?%9kAf~6?{21+P7F8wFPF%lbn5dp$z5m!9IaPR`xmB26V8#vIZ*in!6a`i)52-z
zI4fd3E_K)+Wa9ddsBzDtuAlt3_|L#dFv(Fm0kC&O!OHjEZD3d8tf9->h&6+Yazm1=
z;?Ky>o624WGPwSe*o1%&z9&y?hkJ at mPs9C<S`gUSkc9Tn9sLX#Gr2Y%YYD!--yWsR
zub%b2b*wcR^$GK)duuMq2I#v#8{O^)3^-S=P`Ow#`#o(rP#_#fH{33v;3D$t$~R(R
zyiTDrCnQP9x`4`2{fPR3rfZSkNS at qpr4M{zx!T(XmdJ$E;@lkX20GxYw3{D!w0{>h
z^7xIRe(MmmoTY?7DU#6H7FV~<fo43M>A8=7+#24(=P7xNUJG^`OTPOY?_DeGF`ox3
z8edc(@7KYC1~EaSMtmj<ak_WR-nzO$M>HI#lS4>W*Y`vG9QbPI#@x0fg at rKrZNPCa
zdsV&7Re#F)ryFV_mW%hk9f~|`GeQLJCl6ttO6c%4!B`aK*6|}V6u5P)&$W2sVD}GK
zPR;ef_@;FAz5v)Aul+E|&|+aA-MeEi{5W*ICWqhG1f2tmAwFMM<&iefYVU8pcFy?W
zs2OY^%N8=c2?~M|8-8T+g8NWIud7?Kiz!u%6+v_THZpcXrd&g-=RjM))T$>9&A>{~
zsONV_2J;vQnD5(V|CC_8VRk^Qd{|13J*RV6@&rNG*tYj=VWOQ<gH at 4-D*Hn}M_lWo
zE{{8W`HfcKpH~BSY7Vtyt-kupFu?TL&5pg at a(#|OBie-9zD+h$<0cyF6s^eR+w4XE
zK2x=qY3bE=CH8!YuLupljrpGB1el~fAiH<VB1kGLrLL}yqb+vwn+_+&74oZwTIbdJ
zvws!56Rzst8kghLQEw3nW=$LuDp%3dtSxgbQb*6{e%Y8=c<*$@y`u8dXgZ#23sXv(
z=aqS4$ua(@-1I7Z19;>tnFPg5ad4=xeXbnhBIf7w50>3l5v*T2CEQwWvYJ*7{jEdn
zs-Hih-$rcd6pv5iqa?3RsD8hS(}5sFSr7+R)2b1^qrgi~=ssy3PI~!G<ov1dfTINe
zf5l~ww0(M-E3lTjz1urTDTb053EV)YCy}&fv#~-#O;1IDt!IYxEZMsmvpR6V23nm1
zsk+q$3<#2!^xRvxl|_MOAeCN_T28--pi3#9;vra49KX-BZ1pSCM94WOZToXHeuRRI
zkm7+d(4ZgTQ3TEfWX~z)1Ni)nsCz=cHT==e$)D2)wslUl9r?)<|5#ia2LQ3LxpnvU
zTG-})g-FM4m`vH{<gn|*Fzq>K3n?Ti?;zSCKqsr at iE`Y~M`QWb9lw&;l-JR=U+uar
zN*!YfE2P0uo1G_o%yeu|e)LzT*zuex`)1$7_iBJ6S>BP2a%+=$(oLQVr%J4~F|?1O
zSA(ztT0jp=w at tT+KHIXoX3V2A6kV<XV!hF}Eyq^vCPs9X0 at ETf>6~QFNbG|14=YJX
z%Be6XtMMEMIdHqaJAf25RCG;_zP{=3ezU3=IMHHEVM$9(5Yn|Po6^vX_g#yPYmP--
zt<CNDhTljM{BS2*b=#=F<PGBzjw*}Ix$uru-!bORcUNnOlE{H9zq<e9NcPH}6{~#l
zxae<$|3O at _@#>?#uW3jHYO~mv=y1L}Nmxr(qSoasGBZOfX87Nhjk!xo{L#l|j!~`k
zixA16`A*TTE-tG~g(pfhpEj85<=%|@wJ?1$Z=xWoQ*!>aE~FnQLAk+u5~)cqCwmZM
zwbIRhEUc0jo&~E>rbxKtF3{}j_jcT1Jb%S!$%z3ewQRBP;6?{^@`%5_ZcwoRhFWaA
zI$jGmpTas!ac;i6Ivjqs)`^r4T$kNNoo^PpeADT#^3`L|B14WL5)OkN5oKvUtUEH(
zuSpBh`{idM?8PyD<wvGa?1c8Q4wb*{z>t?&xhcL|!oon5UYSpzr7@<pD%=;vgS;x=
z0{w^_*BTBaXmQ}N;a){h@<J7%FSw9tRKHR)cNCQ6^P|f*nBlN*D4X`3F5h0ZBP}9?
z1J5nx50AK&PX;oLBRZ`*+HcF7^L9+5HD+eU-~-07AMJ!<Ew{_K3uCh)RHpAhiib?(
z>x*o8ic<*C938>Fwv}V$=Dz-)u<i=|>h;Fwx^ajyGQ`TqytE;QfAieS*rlK3;V~_N
zRh!{n(`=U`9%$!j`6-%o{{-n{C(kYH?D^d80*Wp}eWRr$i)&XiYFBHMl<+2rY9ITo
zoMI&Ia^a%^$e~TtdBpykX|UBQ?oC|lBmPTk%Ew_b4R_7o`<iXYCcJe24q2&W)PU-d
zqxV%u+9NlC{JuP?F=O|{$_05FHAvusnm>mEtI<WKwmHLC>SK1|!SZ5;;t*iN^8{36
znFa;6{t=NIb072<JF$y`oR=B0wR8*B{cuc`gI_u7oFM4G_G>fm8*+Xi8#NVQ(GSxa
zEh}4E9JF~-;WddHdhCTM);g6U3_m!fJ4lA1?ZXWnSo|YDLZbTO1VS(Q4ly0a at 1%{a
z@?tz(luzZasi*JrU at NdxB5UEQR-FHg_kN3N#%A+_8-mkzabxIG{(@8^ntEBdvxRNV
zc_wawNy^}!mj4V>87T~A&-}MfgSSA3^Q?-?1rcBuzgExQwZ6T|RciIax(v(Q`TX@>
z+?J%jn1ruH<ijinhQ9xK%KWFs&!e&;)v^f2r`=tiOaSP|;aiTBH(~yPja1?8vd8$%
zNcTwQgc%W<aVgirtwn;X{aqkuaxpxmO}Xv?yMM7VD#*-t=S-XuK>sfE{={Q;;?ma*
zM3tuQz?!O;x;Ki6K!e4#!1IlWK4)lPBG*Id2dc|Ro#zZOoX*F`flq{l+U@)rk5Q&-
z+kFnB1CsxI5?G%igWn8gwn$s{4Zlx+V)9YRtjrXO#UA)a^l5^W=e&S#WdWO;BQ*tz
zKgyqcgc?%9FB4mfzE>r(5frI$3MA2^mI)1{^2O;iBMKP)ANKDI;w>-CZf+J9lFnIF
z&QSyx^equwNxFKC9!w4IC^IIbVlT<wWJJ4>_Q&(Lx{_|MJss`A_)<6OcqHIi5WM!W
zI;pfYm92sa8#BRi8|6$VNDM2ndh9FoV5COMVQrmGgH4<rrK53tg^+&T3`Mrk_sQ-{
z at 5Q@my)7h at t<TPdczw+b<aOX)n9>e=u?VAW_5Y8ivkqwTeZ#$qAR$sR8U<lWmvjk&
zw4kujos!ZGQeULIOG<>%F=C7X(lxqa(h_3=!lcjmopb(Qzt5ice(w9aKG(sqMZ!|g
zCVrmh1C3k&1H4`6`hF-^3orobYQ?Np8+^HRxv at l6lh7P|>2VdKi(nFUZTMdkMs~4!
zWX1JLx8~NX{d%cvBL{V})^fYIul7ejq6Pj}tlE5l{=a={+rs7|L)%S29x<~T+w9Li
zAtT<mGqy2d=f8Fnd0mQ;OZ!~^`HgXK7o!Y}h_6+{w;k at +DIWCoIcHcr!0C~E8aeAh
zt)fKS1WAb<Dkf5-;v9F<`IYZ?6$gtvC)n#h90EaP+Tg{sf{Ib7Y#%v56epTsX$kjE
z5u>8R4~*v0D4KokM(qGYf*RutJ<~Uxnk#N&@Qm6y^Gf9FUy*N6Ny_y41EYHRN7Vw)
zLdRU*e at LFs{%{0kZE^U=nZ>a`Q!2%wx0Jvc96=%c{3HTA at yfEMe)ajOFCK5@=zaZ1
zXUT;onUsFu;<R7>>J~1te1-1yX9yMCq@`kH>dWc*$&N0AaRIj3esp$?oaEK+<zuh1
z1+b;1u;Ny9-wsZ_sQWST(*VQB+~hu-E6_>!-Hle&rW2pU*=URisie%1P)*@>^2z}?
zZ325P!MgORVWY0Xl1`@em66 at uoP|wdX^=~f>pu32+d(+Gs$Y``>SSzqaZMU%?>M;B
zR#n8}e2G&a^j~WBAGuu5-8OF&Ag(>G%5KkP88w|3M*cUge71XvGsgY1y{!oryXi$1
zBw%iPZ;x91FUqX0D_p>TCozsr4 at 4&FXd!!9QDc3w_!r>qFl8E{cHGEF)yK at 2mX&1l
z-=gcT(R3}$o%=(MOfaswc?FM7^0JD)*5O6FxbP!T8P9OdCR0=D<yAy*u)qj+{A*`!
zJ>8@;?o135pz;zkSJunw-TS`ZKtZ*@up|hV_0A6EmZ{IoS~omOfW9d7jF!7tRsjCf
zkMNZY>6Ojf?Hlo&)WH+E&m))CK#3iSkLf0HE8~7>sDL%r|1BLaOTkwqO6}RiQ(n9=
z&rxgscspC at rq0#vC`-RwcS)*kswOlU)g1V8waP3wY8alX)AjmrqH*9$Bg($8CcL(*
z{ts75Z7)*f8~AZ}5Qq-rLIk4%H~%R&X`!8-QE_3RPn1~jxTZFRRoHPtxiyP5v~E&T
zn(E4ntmIp$BNr!mo(dGHJ$$;cP<opfr5=uLaGuKYD7F%&o}Ybb1J_ISGJ30l+cYPf
z(;m=e$3X}6<96YY--V6Ei9I9LuL}%7Wc_E5nvOP|-S8Lx4tbrnY)zSDZy>h^|7vck
zZr6 at 5w+%1*gE6R^!+)4tNxpdRXEIC$GAJ|K|GS|ws*If2YR2E5$OgM#@!d`Z2QA-T
z at g->9B7?o8f`fQkYxXi_yvq$e<3I6dl__4j+qO&12|qNIZQK&nshu)kkuUFZOLKwD
z0r;BDywbxtY8Z7JXuJOXh>!Vi)w4lrCt5CihWe6-3^zS635&e+#eQU6o5wV`G&`he
zY>}NF0MKc)hq*@awRM#;eBFmnyY_-4H}Z7d0;G$#;<2a~m;V3l3)qFoHonJF-YTi~
z0XqW`JHfci4oX`5$5Hq|yoWuc at Y5!Z_zqQ4V!9R!IEl;s!8MJ>dYi0b{azzZFEGNQ
zqCx>38i)W>tGkSsxK|BPz3;0{AxQPaH?Xpar)S`OsN9Ytzo57$C`jzA16gD$G+Psg
z|5LLXB1Yg?%flp2o!3sK#iQAIu}<{y#wjbdhCbR=noE(_ww|+F<6p}H?~H at C&IhF1
zunbRyC(JgwEI(h0zXsN3%M(jFu%vG)rjyjCk9PxGfP$VwfVYcHssUp$X)depb7TZS
zk1J*~D}PW<0?Vw*oE*rM$-Zu<^@f1BKlHFT&w#TXVHFg&n}bsuz0J7mG<LfqD}IB~
zyx}_vVfz1CfU^GEP1%14=G&9o355R@^5)U)*%9jM==^AN_Q(HDY1g+$r at JSvR~ff|
z4*#L93T_bnw|l|2eDTO<sAqgPWVnTLnz9icZlnbopI(6H)8rlDgXHbPTWPhNJIgbM
zC?_Qo(#X#qXPg*z>S15{q>+~d!4w7?<O-x&#sHR87sDVz1FvlXyXJBX2@{Dy`gmwv
z;TculQ6b<0-M;KMoA6AQ`OY~Uy){-+CEbt#tsTD}o5)uwpzpo68N3un>Gqqh;{;fe
z0wD4Gh3n5?XmSQqs0H;NR3g>gf8ih#obSjfEJCZt<y^gQuhC1*x=|lg^06+VMwHEo
z3RD3U0@)7LUm|k-Nd5u-aXmHlw8<t+?jSk7D5gwF8;F_L7B;lzf&A1ki5linSb7JP
z at XLDLX)}Xg>CEW#bg$*|dd3`c8DmcUKxc`sJGU0**(V$o^J1#B!3pb}z6A6E)*Q^+
z(eLUhY`Yx)ci-s&?MOz`CGY9)g~7J}a#Y_!T|qpPN`25%FLvDHbiQ+Dsie<5B`pqr
z9DQx9T*xm?y`oC+G;O|4D2ZdxA$NtX_ZRfHrxfpkz at Wp6W!~>d-jZ58E07%hGf7uf
zCE51tjQ(Kk?e()~x95lxS(zL7?Fwuo_y}>$7oQ;N`Ty>%q5Hc>=l?DaH;&Mk1 at X^r
z8*YF598U%NN?jgaa`jd|muDBIUJg%R5FUStbgzV;<47xToz+Xpp<ZWQa~6r@`qN}X
zUil0YcWTKknVyJ0jQfl~p4%Qj*L_Wx$i(6c-0!Sr*_K}--WJBiKnYFk#?F2IXy+d_
z?WL2fc?Nf))MaTo(tEAh6@=l6A?Qu~Oa9nP_i<zDWBfp!%TZRj8d!4s*q>y}^9fsK
zN#Hjb2MnBch}Bai`zTSx!nMx#%U3GNh`!Sx-l{i^2}JcqReexiJ0cV(bnw3O0d=T^
z at Tj9;!QhBfe`y9x(ADC;=!C$l24PP9F at OO>mp<#pyNRBOd0T5Y-FLe2amfP~3jT#q
zwM!%T{-LgHB4r*ZV-b+U^n}QqC$-O<i`m{4>j)8PwrV_t$0-(>VpjYe at G!=(C<%QH
zg-X55O<d-la)zl+GVS+S)r_uo%t~b-(Gjo&$a);(SZ>H}=cwMPp(Q$z#NB-Iy>5kc
zIlbfaSl{<LM-6e2ifp17$l^K>iwm4En(fy`BE&n+Yi?sU5T`XabNxBbZkGCUYHk?%
zFJGE6J(Il_NH36iR*-<~$4HFfD%lpv!~82=w~NbL9pOLN+bx{;TubBEUAf+c>ToDN
zU%t&jV)7Ziy)zOLkc^8339 at k>nBUB%U8=YtoQ&+TFA5<!7JR#RbMvoz2N at 9L?Y#yt
zmc4xD?cr?{c(c=hod5hh at FoDKY|cj?B5^Nubu;XZNVvt}LgHnEuUi&-FwDMZ!Babz
zCQQS9XJQO6*}iSu+h^Fe)8}lojO3so+X!Tp?0;yit)JCuzzrU+hj7hU-*&w1<uLa4
z-&Mlp<<;(qHQ=D(HmC0})F9JV@{4o8)!$vSv at 3D1;E_m(ujew8X8sjNS`hquQ1Ah4
z%J+0<9w!KQ#hf at wikvuVa`_$X94Y_1!U`XqAJ at n}3;tm>DJ*7~(vLE9Uq+p_i}PNN
zx(bTmezahgtG4aKcx1nB|K$eE^mglLv*6Y={$;`HGo)#Idk;Q-3a8ePrSL05-mm}#
z^S+CL7MkYOIWi5JlZN<s!4}p>0N45fyg1V4U)v~cYM!_6uNR*B85q0~c=v;7rkrw<
zBB^K(Qddmbl^?bkIzT4)ZN^f|A=b>ZyMJz^-E5Jywf(7h- at bFrLswf|x-C9Vs_<{X
zV*8^A^U3%`fwHo>rET)O!Bp|P`IRBRVW&B at k3ZEpn1X_~H5>oSJ}N7994L4)SW;9~
zmp98)9hLSSn&Y`AloI-dJbNa*y4QMZ8IT(E9K`+jmGN)rt<DVpiM!jhtN7GUk#8&2
zp?$JkJZKVk7ED8A4bLyn!n4+>RGwNBs1c!%T2rT?&z%I7xNk1Z*7SGxnPXN4w=$bi
zK-GAykgx<*TL0&G+wbo>XvpqSPXbJrfOFl-alNzUDhs$%;Z|O?M{$+5;W2O^nLndv
z{=Ql1Fq?*O#`dQIu46Mp-N!#7QOqW`^~>3TB3|^~P1}o!-lL5Du2TLt=%cH{=8b>4
zw+S1)JDUBM*kDPSpeqlY at aB>4>C}!IIZn-Mdd=J-)ha0ycyax?;{{O*BKSh7{W?+z
z)1MIB11(5^Nq&v)cf~E4qlC`=mWLXe`7+}9%hKX9*8)(Q(`MX4EyH5_al|p+t`W>i
zXF~A9$O1n9iIrzvH<x73;*r4*ulijXk%yQB*h}x=o(Av!ezIr0SKq3_%h`NR#pPDF
z7H$a}dxiHM9hcy?;_(~*?oI#2a&Awl-NWuq^>6%)Owc7dOnDjnaLwCWcV!y3A(p?2
zy3JST$LNT)A!1hw@?;=g*Fhh)B5`P*7Hwp{v}FGB3R8h{E#H0gGs_M3Bq&NZ`RZ+Z
z-3He8=%vCr*6d2N^%QkGqWyfNKqg2^=Gc*j=oW^;TSo1SmeDO;LiUa^mM8v#<(~&!
z17ubax1Ud$af0Xt;_3p{(?bjn>7d!)U~4K+6E8a!vL9NAudtJ6>Am|I5qx_&P#o?f
zf{EV{qHG8zh{(8JKiSzBd`1}7CqJNa2?5=V at z0g`?^rwDD2H!-BV2PcNi{pfn99h~
z<=l)GoE)AU?N04LE)mMFP_mMT2;U$n--{LYf$O`*6prk7=Js9&*S;b~n!fpMa<Sxs
zFs5V3cV&`#ggo1eb7 at 0{8e86Tdf-(fdb8{D_p;)<Fu20O?+K>{k8UGv>1EVQ$fu?{
z(=Mohyrp))i-2X;maC#TQ@<eOFSHHai>J>bpdUUQJ{FkN8-AAjXbBsZA^H;86RRo{
zsyk>dkffKd#6(B&V)8-y3(JF+lOftS^SQP`QOdU~4|RRFa4@@hZjTYRI&VwX7pf53
zG`xdsiudJ(KG^ESu++Fa*#&W%*G$%KA)463N2TSXt?}dX`?g{#gID<Bs(*Or3IUmn
z`8bvkggAn-OKv!ztI34 at V0c0NMR@CYSch<y<h{9>x%gP>M?|KcY>YYVC2A%q8*YsK
z5gSDoQTMAP_HnSJ{yW9PIr2`?w at xFC>yX|_pl4u}iyPs`?qp&bag35&1oH4|yhvFb
zPt}f9Zm}Nw95+VX0(n<JYk7QSu~=$6J2^Yx-aA&JhKL`N8Zn{+7AI}K+7CYT+t9Q<
zQr=fkF0}WQAcl>DCfy4!1FgBF8PSPQ-zF8%*7;V3X?zXhx?yq;2x2`W4T&YHWmCbk
zxP{fWf~-`~NKUgyZ at L->16wSql6G`_b)gfajl}yw!T5s9rpuk!h0DM&PRJMPdp*3(
z1%7Y*5CooG#481cLhN7U^~2hTQ_lbMcagnRf3R!fuvR2|ecBv+NCCu9Kk85%=zZdN
zvhFZO13^|XQB{#jrG~=U41yo3Fx8G0O3VYQ!qaj`8Div<Tu$HBe%o%~NW)+Q6ELfA
z$&NK?2HJ;;*Eacq;=Ua*8i3q6>e8#g(i at G*@C59Yqzi7x at M)UM>8#fHvXkq+dMzgv
zXnB$wuFD6_M~h!3ob;hg at xLE}{J%uU_1>?j7IBWt%Qwj at B(UD^G^urBeM(k>W$y2V
zFIyqt5(66Kg*Sb7<|Z>?zd`B|n5=#+m&{(!<5?PJP;%Mx1bL!prgEv$%r9Mj7)8%f
zoc89(3^tb!cm3LLE}$KQFHN{L at DIE9PPirldVQw_-Q#@i0)?25n9V5&2Kie%K!j$I
zl98ONv!5EM%7`I9NED$GOKG|?@f(7Cu`W;j1P`m!eE-w2&sSOa4QHr1U)`4<LOh9k
zs-x}K5Bw2r#Dg``%dPv9cJECJ=wtJ7n6yV2s&DOnA;$-_QdsI{fu|ler1t@?%uKnH
z-z&=NX)6nvKQbcJN<kr!ocoY6H1JNms#a9Imle}xKdq|SpCqvF6suNWL9YBtmldg@
zU6XP*tH?VYaO<v9J*H2fERBd4{`7kK at y(`{Xp(+>T-8dbZy5S>a$q%m{&BE$&3#L1
zvbxTtrrPZKne^?rlY=|{Lk09->%1l8L3YZWd7vV!<e=GU$0?7P<F(#O`bD%t=BqY}
z*EKp;R2h{r!H>@P5La#-w69$Z3szuqhXj?ly<`c;|NkZ2#iz&d>-C^og*&wdu^8ya
zK|?=lR$~!f_^ltMjV}Fysk3!(Bo$1nz%GOrWz)iOsV&Ft=u#jjZt=iIW`r`1Q9+mJ
z`mt~}KxNM3O8VG>X5HaO<cGDFAdp0X2CJu~WnvqVBeq)hOV`<*vko*;*VZ0v>PkWO
zhC~=x2wxHsvyBR6vg`luUR}3Pq|;-8Z3Zd3js6yNjx?ava2RtRX#K_LsgdtWC(+M<
z>8-?Bs$;^(1Y||c_Ae=uyhm~0#6{N<zC9RcjM!<ncU(p(O26h)_se^Wc33&N8`P{^
zdJ16SSQ7&wk~|tgYZfpFOyYGcrv64TmYa-i!<LGUJ-k55*R37*OA><}yELbieCw<6
z*0kAu`n)Q-EAr{8p3fUwF8Lo^20E{mK!p50;ky}S8xF7V2I+Uhc5vv9Gkc=_K3O<}
zqE~oijX#`mZ99U|>Jw=-2kBUjF8Wd1lFRZwikBDqn{mCQLGw`Oa)OvZ|INNSM>>y;
z!C}j?I|)Ny&?qjE9Sb`%548JRppx!C<FgW@*!Wrm at Caw5`<n6;`Q0x~-y7YZ_R)dL
zQLwtlBr1_HyFvlZUue4D$!p|5niH<MAkU at m6PsG{I4@=5xgA7URg=aMmY7#bkPALy
z^IRfzsCUx+$*a)S5zYx|2zFrsIPQOJ|HEMzfM5B3yLXN^!E!4Pxt->Oih$CMU=QT!
zbvtVJ!t0m0mI4Vlbb`ibAy&dO$Lf=QUXr{d&5kCGI1DEjlT+_oy#gm|GE-k$$i+mq
z;iujQYklK!!`~ov5WMZ|*GU3IuWMgTyxQdrahj@<Uz9MMLsisVyV(BI$CFNbu+NWG
zujVLx4rWptxDf494?p#N-i}*noaHkgS~1?g+JF(Ef6pmnmX^7;xpkm#N9tThPY=*?
zhe{Sh##6wkj=4Uc2t&Ub)ga=Xrv^njj`u%3s at F;kElM8Y;p9+6&69YZGVTXYr9gyt
z+CL*c9T;eOA<!Q=t)}L4!lOiL9maRSsook*+naBPJjD#P^YGE7XbNBm49F=0^~MkT
z;HymgStS=gDx%Hnzv{N{QPK7$V<bB(mJum9LguNxMyn~cm at tiGfA&st{bh%3<5vpH
zuc5rw9xE{#t6KwNn2YN)-LqIzhI`_?_$OZY>$RC|e*fk018!;Y4#ce<lcV48+FTZ%
zQ95)zPuQpnH9DHY`SI1F)-`T4bQFyL9=Q4~5Br}rY1zH^ez#B6u#;F<XxU(O+do#<
z_ilbQf32FX|NRfh__c9LpHlwYoLAI%54TL;Vj|K9%{k6ajE7|R++&iw=1zZ6fM1Sy
z&-?*r8+e+`Eu|r2#ngn0SJ*r=WVO*>8NC2H3-1hwq|;u~e}+BD@$~;kT{#?5C)j8l
z_QZFMTAm<#MB_g*ew$wAc(uJ%yf^1vxH*ln1aL@{q0)O?zY3R*@W>4u_u-W}^-`r-
zb<e6Ls2%8Dr3?FzJhKM|4PM~Nn48dRknm3pM>0fOQ)5+oeLB!{lp*5j!5=XZ0?&2#
zJW-}<r(|FYD6Ddu)<?O>h=LHFb- at ECacmX!f_tw$?v8R(cc#)rmtJ1tgd2Pgwa|t|
zjBQ9*5hHNEDvNUnpMU_!?!EujQL+4JmJM1bAou6w8$IA*syk*iP=v}6V=N3K?E|5x
zW}A`D<4sJ|EOAcbT^Wy4!wm^G?5Y>z_CBAy5&3K<OT=8?-ZWc@?C1 at _p%_h8LC%wq
z<avK0)%uUMz-MaDt2RFVsn4f9)bKONwDS;2vl0%f+M)F5FL(bDUDwsV6N})}X|lzL
zF1dimrtiUQb>Tyv&>&V%@vY6QW$5?6?c_LJ?I*cvwh4t2_c7WxzyDaQ=IE|OT3z(5
z9xkk(2jj{K2y430_;wZbN<;O3ic(Yuq1_#*`PVfhVwY$w>ioCCWZNHE=7bg>>ixcS
zvx{~CVE9TtJgLL)>agVRkjJkouR5rq{Sxu3&zZ#8O*-!S0PGpx`aOMob)H9Q8y9um
zk2BZuUTzj~=F;S~dRZ+(A}Z)#5Q;A=C_TZ^f%$(?Yuh6yl#roW{8q>T30{$VY?oZp
zaCt3ufLy=dteJ1#ecw?c at y4GPkLI7$D<0ld;WwY9Y=O at YxW0Wze%W8 at eskBj#wmF&
zGb}dgyocP?F~fl(zNa`Eaq6yzPh$%tRd_9&u*x-oF)Ij*8>D2!8lL`V;Gz1IOZG>3
z at _k!_4bt$g_OVtc-U>}3^N&iacq*r_SXAXXa8JszLoT9BJ~nsxM#WcYi?#xe35+iW
zDrusT)fQ1s7@)%pvp|UifQu#9K2q<m at qqlZGq?y}kJ&7`9x at L9{ep@>Cu8}JF9-1A
z at vIxkc{OAH+okctYi3y-K6?g6nGH?DinKoYiW7OpJUp%#Y_Vx82nTRK!3|j3Ng!GA
z8n;*+vBH;(DW5*)>|hiXd|h*UIwRGzNX5I<!}a6chBj+sq7poBxiQBZ-x|Nd%ZSm?
zoS2<QwaDKET%X!2^6TIdU$Gl*lu{+064|%PYmIH<i~)wMMA{4DgTRNCthm at 3ib{|~
zVOf><TrBk{yZ+Fn{i^RcO)NG)`0A*iYq at cy@=5<$`fRE(CHqvG6m}uKz-q_jYyL?Q
z*2Y4s%K=6_+O at KC$86=$(OWyf2H~EC_!H(g_EIyS at eU64eCLj)hpUl60v05GcbGmw
zhQ~-0EEqRfoWU+(RNDeX?{+x+(9LTiY-O~5f6?>RIu1Q&M}JfNTrVWoNBtG*j%hg8
z2C4z)AJ?Sune0z^mhcSs at re5-#b at cC(r=sW1%1kBDEeqTCXAipst)W8)Uyg9Uri1+
z9-xt#p+o8Uzt at RPRkLrd!1C(u;v{An|AvLRQbA86$zQZSk^kWjPE(ZZhm17y@;p^L
zbGbrJ3xUp#8S4qrCZAa5x~meGLIXb$_R3b}_*BQ0ecrtZa?qIpV`@%YE2=NZsA(YT
z_GRxCMPqsrT!&*uH`67{B4!po?7~qfl&Kv)+Pq4Iq|1wEuDG_&)e-sas7U0Xg)k4B
zD>xx=7>Lu;C`uK!_!goK8Oet at r5fsz`1}wR+;=M2b%q~~<`Iow&ecyHmx2kzldGGr
zTl{8tr*AawB2(lH`@VXq(6>7=z;G?7Gxy$m;ZR}mbSwRF_EsJ4+C7j%c4N2)jB?2U
z?V{^c*TfmCd6Qtmv4&HtdDP7>O8+d;HHI$D0A2QH at Z@P#3%pUog}Z+|QeOXZFlpuB
z;noZcW{Cu|rP54C-u;zz<qF?bWPhrXDvY#6xojjoEH}3aiE`-Ha8sG<uJQAN)FiX{
z<0k%|n9;P^-1=;GR&aOt+OB5Fy~saYDlMGf8 at EXa91R(Ae;nHwE~fiGa`_z70TE33
zTyVIu9+#N5C34;hQoat!)urZBEmFN9-Hv$CQcz{}BUgqjvCkPVA-Uxc;)}2syvE4?
z45wfi$@n7TP2;7j^u5miZX!V55*2It67d6t{VYsz%$-!p>xhIycTA8ZkY<9^yEVrC
zYG0q5bD`<aFOefV$Lxmcg=7UMq6$IYxd!(?ckXc=VRRATu_zzwJrZI4%-A#h3iq at 2
zE{MUDoV9Ld at B55B?QS2ESIB=~50&6$X9iSOTp09AFF76FrWYlDhTK at dU6b%`xSq~C
z<Z3qhoJWL!Y2U at OZ{K^{|16iYqjvwB;9Qa5SX*ZD^?rP_ChjnQ6a9i)YWbgCYssOK
zd`ZM#z{sUbp6Kw_)7ga!X#J|6a7cPETHG>Ys_q!h)bGmS1w}02gU;2e%T{<(6wcqu
zoAWRZQ1fWv3>ZRDxL{*up+=9Ia*|KYFyT_p?Dm=HESVgCglm((EAn}zm$~n7flR~p
zD`p?us<YPM`0dtb`<MIE;p-h9)m!!~iW&?7+NyeJ?wQ`BNg<0`lG9kD{cblru!WwW
zahUCrk2tTbRC4bJ-X|YPeb=<1CL|ww<Q6SX_#t~NgRa!+>El7~(y1&O?FGP-qtVn<
zS|;OPJ``(<e)fIdcGLC&7h09 at Q=>XQwmyUTowFOXieV{PipnhP`BB4=Np- at ArIke3
zcPBV6qCaArz~w>vXZ(J!*xQh|k;TWu6%Tm|S9lfj+GR}Nj)GwBj>O6!{>fN~@F&HY
zy?Uoz>2LI8TdKmu4tU;Fub&$o)KjasK7})o$y#?oIzRn!U>{oV8v1V^xDxcj)i*4#
z5bX48^yJPsB;ko>IgFHl65&QDv|tu6V*$XR#0d3`P?1%ivp0EompbKJy4)@{C45?%
zWQZ5TSH$?j>(5pXo(wWf;Viz^1u?^b>RN|tc)-?bO0w`P4-IiX?h8Fqld=5Fzx_S;
z)UCjQQ=tam6TIpV@)>G*bsMnTCN&o}<AN*-GC66U?BS$R-~feFPAV&sXMmnDvreu`
zRtp6>leuttg1(m!ud;`A4)4E?t8Vf2_X=BXT{|8CM4CnL`;;p3c^XaPYcPRWs<pK$
z at xiM;KF<{7<F1Gd>;cf%O}vT4Zj`6TFX<6yw=m!1Rhk>Cx|3MQZu_{}*!vC3KO7NH
z(qFF6>(RPm91iAYdyu!O#R!<{(^<st*tg5sf at ebK-Uxd>laAt@?X1e?<wFZ4%eUe^
z9dpD at eX_Rxb?uF(rqlfH8#&ZAu11GxgtO$TQ~l0EKVQwnh1!OFfBt5#f=}S$4m_n_
zmt}pwZU!pMUY~5eeL?%gZSZFOIgRcLuta~hf-CcDrrqzt1{0wC&yhvX{1u#bu~t}d
zZ-vOxHKpp9J-4f~XRwmH^nNL)td|EdrS2>9qXt-FFM?jjldp@^FUYV4OeB4!V^)9c
zEd1S9x6`1WEvhwoh~Azvu}(pb47C#8({E4P)LxgbvAfGoOfN>rMCE**DT4^<k_WKo
z8n8FgPxiHg+ACDr<Y0q5!OFfLV5!dIG16xzhc90J7d2=(7<`-aIdVHMPnvx=?Mh1R
z0qKy$Jss9Y)mNLHV<Az>42 at R)D)CG~%+6k<H_SSoYvgE}vEg6o@&ZpKe#DgHZU#1`
ze>6U?@a2}d$$;g`525)qLsu1ly|>2?O$=Erbc=opq_sbnk-jA;p?2DPM>2yu+Xg)&
z7`C+yG1dzcoSUY92G;qQz9 at 82x98$6r+$$Y_a;#>M%AJ4+hmz-i+?#26Vsx`O-^$*
z6GN>*CPmW(W7_^F^Y5p+T3hGU5%OQjS;pe8FP0bJtHRV|vpzP+)^&!B;_CoJjVh#X
zoE0xMra7~G{>wT`cA;n)$a-daf=#WuBvjh=zf9X8mND2_%;^Lb-5;!&SpE at g`@rDe
zxx95CjTiFS$%MP(MKf1GeW)aTxoQ-7okb*g at eP6w(S|U^D{Rnyt>M~$qVcma?`6IG
z$O-V;5w~V#n>$f|eo(2l>(6uFB=b+!kcB_`c<jBTkd0T9Z{=BK9Wpt+XZ6m+ui8~I
zINzsNRLqhp3NkBXtO!vPQ>9`7NlOGo<Z~>10-KaNkP4j=@awsx{Ki&-|6ZTs>HFFg
zXk at C*uT{<dMdcjuZc?(ahgM~F;P}3K{4_#*+weCd-yE6-beoEyXBC81<;7N_JJ}#9
z(ei5L<cpU1w0Y<B<1nCa{I&d7b>_YKzlf#}Z2g~<zJCD?6bH~jzKn|R{I at xCT1lSb
zT=t%JB8#@OA|2<%kIX4SCy!_(l6Gi3*s{^TnkR;Ygc;Ay<{3vubU9Lw+sDRtOXrN&
zg<hXMWJ)p=imyuEA^!Z=MZzpxi70EiI^tyPC+HO<QQ`dFetBWZd4(>KxRKa*dBXK*
zlI*`C<oVBI!Oq~WIR8(VX-LkD?jab^8JLESBw+Ts)JTkA5v>VbB!C&Rgm3-D_ZFPc
zj~JjXP0IK_-5xdczj_Jh*WwhI{8H`yp7#eo0Q8l+CCkjg at i&HRkazm6_I`4wv9 at 8B
z=yT!E^WCbJmUW-8lV~^Im&k at r;pSXfmbh+l>9P*oIGp6Rb3IgG1bnFR98|N!_Wp?C
zT88)|4ovB<-Pk8Q(Qw*&Jmer-SY(bdMkJ0skd!$#<9SFz=3Ub`zGUL;`mNeb3rw|{
z9IOEWJ!q<}uZ0rxCAWC<kuf(Z{>}G9zYL%0tpRYXiSL at gSG-|8RsH!0HlMW()yEEm
z)eAoyRFk+0R>lyC4oO<<onAFT7rSL#9k@}I<%=Hu1ZJGYQFg;7g~YrAEjk9Fe|V_a
z7nJ872V3FPu+N!F$O_2^3W3`W2Dn#IvrbuQAu-|a2g~Kd7d>8|2|PDm7y?8JwvpO}
z{h0li&AhPK#8o#r<>aOj4XR02;0*s^t9|-Y0r(`U1jzNliwVlk=jhD-Hp9npecGyO
zvix{9yXE}S*6l|i;+~_xMk^xwm+GQ{Vl#TW+~^4VOA|6)k};^SE5BaH#GKNZuQ9mp
zqy`(;@VGPBGD{iCfr3%9pK3d9W}!`UjykU*lXt+Y8ndAKIzI>MN#U6_J8I3XO5AyN
zsLVTLW+$x!+ESawFU`mZ>vQ64`|<y^0DV{wpg?=ye_X}>-w}x9t#vdqRFKLD|4n))
z{aFjfuzftEtFBJ1o<CFQUm6nlboRa3qwuK2#7;`;xlF+c!<AFGs#engXsrYu7+81k
zu<cnDSuBB9G*#o=ejs~^)^clm<E+u8M#Q7S=kX4`_d%32?^{3C(J^rDuiQLkS+Q^S
zxBkO%E}Lw7(x^v!)LlGg=D%O|y*7rC5l8d>hpSOw0IzjFFRrDfa);GZMz3aR+s75E
z-!v$j9QnJ at 3!7 at yI%v)?T<2vAqTY5nN>E9#4^Sl;+8m at W@OV#zm)gIW?P}68=l6te
zBqm&|++}Se?wYQ>y*ui&THz=5kQk}N7sVy5Hbq?TJo-i}ep at D|C+Y+jUzeb!8{2HD
z?3-2cagd7UO<aZ<Ph~E}`ie^<1^H3Y+8O7hL`{HK%tyc`cw$uE3DbmVepkV{&D-Pm
ziHQ2qfz56iaJd0KD>ftD)v_S$kYteb6!{r{;OctH>RqKVT3P^2Py!h;$M-P2poFq{
z<kR70ff)2W#0=@0tJ=Fd_<B0!riyEa_exw0TM<n>zEoM9b5KDV1E3NxAsiG_cfozQ
z*jX|<SgEJ|LZHYN2cZn{&YU+e&O7A<F~{e8{cGYsM*wOYS*n^`dPB4>oJd9aYwZ(c
zF2XL^R#-WpGEb}(WNRFQe&>6yaXftDD at EE4%Pme!@+%b>;w-_X;Z#(Y{0$ULIy*;u
z6gynYHjqXO=AF>68*J#Neo96m>rk67=i+W2gXbBev;C2GA%1ifR)UFm?u38(Sg;lu
zG}}ZDZN{+%9#I;A(|CQR>AY~&p!}ER7*7hUw0MmSE)O${#*61Me;Rz5ZM5$6MoQg4
zXcW>va$owNhE at 1V>-U2n2PW+U_wc&=E5Z*&@#Ss(;SU%|QhXneeOlX4 at 8am9MIZ=Z
zUPfcznDZ^Ybi&_|Ff6Qpu?jZlzZjWU418P at ydAaHP?Nn1$P at 8J@ov$XuYCDnmud7+
zGL1`v2RXBevh|j|#Hp at t+}<zHsfB#B3Ss;eaSckXh<Rn?F3#^oTonspeC2I_{+9X$
zNaeMP)Ct(l(O9Uee2bg})^Oso6<`^j4>C^|HZ)BlIG?iRjLQ32ZSGq^bo|#Pj%iEQ
z;Wxa!VTF$}Z-T^H(ic#^)j3mTU=^C!9hb8eD!~U{Xe=5Bbb;iALOfSbO>}<`)-`MI
z&>aThS{LhY9QxoM=7F~URX-rJ2VOS`xDlgI=d|iyCGV8i4JY4GIHo0jlpbTLpgU83
zkm=Mw#0x^Fh8HhHyA_nTc<P3)JBFwn>`R_~HO5m>lb7DCeI2xZO$v2rm6nn+vfgrb
z^Rub!kLQtq$U0e2&XNwzJ{@GMCAPx^LZ;x_qb(j`&Mdm+XP;BvzIfQ*sgVB_^rrV=
zz}bU at RsWn+-gOD`;nG at 9h_`%9famPbuV)zDT^pQ|)D6cgNKbU8v`woS`vstREVgg4
zm_1`x<J%NJ0F-bJg<g>kLFKvf5z>XY27Xm+%|KXAX4l2KWv?~ExQNLL3~RG>g{uHF
zd>4W?%x&K2mARS+j^&)T&p*`j$w>T3&1JXh<6=9rD}(a2UhAn#N`-fj$Ww+L at md|J
zpVgzZKd!J%!Tqc~yjO*5NQR`0sONn~0$Q%+4rc&qeth`Ai}z9D-WmkfPA+!`z?odr
z!)ao6F+SCB9atl*+Ni=9A644bGC4!tctEJ1I3-_bYbs;u6POZ0J)nnrL at F-*c4;_c
zdFg`efmO)J^><(EIg2z+;k4Au<yGe`n1aGqjW9gDVXgs-3wv55iTF<EDC)x5c4|V}
zHcRr}F3aIqePI}`cbG1?>QL!;R4B~;*Lc?+q#L6ml5`YX{pVvW)n1XU3xeOvXhx8S
zXpeI`iqOEt+y?0rm=2z{k&KAZ6W;*qvo+&gXC{WO(Bn%;z2ppdH9g)yquF8uo^hmj
z2}n!#Z)z9neaO6DlzoqnrqP#0U9TRY_)=1^`)6rR?m3_H`=dKDyl1Adkf*>Ff3v9v
z##LIgG;1^(`INY_Z=PLidlu?Otz`YH=Om^8BtJdKW->;@s>`A>F1&m|t_82C?xkFW
zJp&C_TIs{lC!tV)pWJ8`RkK$7)-z!dKQeA58^Z$QJ9eMx;uswHWNxca%nS4yTF<Om
z;+zpb6t}<5)+}uo(GVY5zXEKD$#E7mj57G>{Yd>*I=~5$@#J#dWr=Wuriv&x1QZO@
zSnibb<UG0{*e4M5<8e|mp;adVeNDKype8eN=dxXF|3FkLZvL_cLy}US%>G(~bv?Tg
zeSe~DkKf35ODKsb29LnFiVptZ;2yRW<H<fK%=~m{v27y94BH?aVU!=4*Z#zRF4vx)
z3*or6{7|2=Jc1e$9_^poszSr<Si~wm%W3YeXar4EXeD;LVG9(6t|D;?2<w9JN46wf
zD>Ww;BwU`P(Bc=<mJrwlzum!d(DU2|v&#_<!(*p?{z>eiDDIQ{9>2+^F_aehD*3{b
zOL$+LEw$-%JIM0bNN%k2jfH#H4S1I40UTFya+-_ki4r+T-4!ask|Ym!9!~l;FiXZr
zkvlKUpC4{5R6p&Y?2FcE#L$y3ax{`JnJh7v9;eHA0h3_5hOdcbW~3YEcm)>snrv&k
z{O*^39s_xLYUoOhb6KY-uuNuKTpoB8EG_+=Fr0EA!Vm}jmTX#mZ`&7rOm|vzvS6s)
z-5+s(pL)l{@PWk_-qa>D!<5C at GU61@`oXQ&ILSLur%C+m4oNVP6EU`rY*8+^AQR^o
zA>6dhks=f~x`8TxpM?X6<od%qh9$MFEbx7o6P7i{V%Gz)Snxl8mL+;ms)n{o-RMVO
zX+LT_Yc8&*9_wvXtM}-vG<$asWT9!7Rl=^3aCO}a!Wu%I4V6joCrG|Ua91zVI1d}M
zGi(tVZZdZ;^Q*;!@PhDE2R}1aA5%F>^3imoGE#Y<J`izE?bNh=<61$O#Q at F)_2mPt
z90j2 at U*19TK4Z?cl=4P59U!NjcA^)-Y1$%1-AcZ%t!>8oJ#dX&2BsjcVPdRpyQya$
zf;$X(dSi at Rw!!Y3G_5N1iPaa=s$Cb(;X>iV&}>VZX$>vHWJ~s7<xl<F*B!b$f7efS
zRcaL!8QZkTe62~2K8>ah+_7XTV$Su7rUIpL0twYuU0-xs!dKi&A-dTHc3I@#s3pWw
z$PW`KM0w<Nf?3E+HEc36wzHpx{>|Jh8~kGL=Qr||#rwU1q7h-^BbXLwZiN1?L06;v
zqCbkwNtzE}(zI!i2i=<2`)ufTcr0}wG2qSpJ7v71R+>E=^n~Y+<XZwgkK={K80{2?
zn#O<Mu8xU02qA`8KfKx5D9#vLMq2BD9MNiACObjyDkNe&&J>qk6T8D1sfcK#Y?a{b
zmE}Y)44yDflJsr{&p<*6eF<uGbBP*DoX+F-i at kwtrL@TbZ^eIdnXoPk5PG7FYg$eT
z9ao3$d(|9X=Hpa+VQ3BXRx~@i7)ypWU;0*l&iK&j0i%II7m(gdLsZVV6>EWb9 at mY?
zI4*Siw4+y7zN&W3GnYHd)Hg!{Lc3Ejjm|UW%r18$;(~R~F4Y7Zd~SrEXz&QaDEFOR
zo{!&uZe$S`lHL;V4&2~r|E5AUQ7YlEA6kPlP2OO3_Wx6JoQ{@jaE63e+*2g?oJuD9
z<{hG^u%>(L&(>4Gbme3LeNVIV8(4C6tnbesT0U<f?UgOcw8}M6CSH&aQ2UR|PP@)(
zD~IOTZp&!7DI=tdZm#gB_D={JTvhWHrTYkuyNBJW&Oy5d`YsUh?hLP06@$vH4kN-s
zb53u4^QJ9c*-x+!;F!mH5e at +ULA8b<U9ASI8}>^7d)(7Me`@lE;i~b6-K*S{9<tSR
zWSUW31kB(fu$02#tff at q)AW34f3KztP8d&_GYoYB7Or`$tjnP_P`K at V*aSmyM0HpN
zgD9v~^+wL+#no$1Bj(`-UvX`KVYu6BrTXFe5we9GadkYL=ACk>LaYKW^IQk}4huJ(
z$bU`1*aTKR?bP$+NVy-#^faF1vsjoVZ?1MwVy5?;!pXM4eNto+=rEZaAvfU#3op{E
zobK!N-I)I^<6{2Pw<*XD-D^neIx6B4UgY;ZyOR^#NStg-zV|@Yw-KV%8f52I at OXO;
zqh8-p+tyI@!F|yd6Dup^*;s*aJM1G@{YMOuOo7I~Xh(J+f`PRY%s;***n4uxn<ur^
z>1O+#&jD<nZt4g9b-Pf9Hc@{%$n)+NkAviFz~+|jk&m9x7EA~kggmBV?|;|ScDgB{
zT>?Vm<PF{#7CVbdxxMMO(M{1-`eM5a=~FNNj<|nE+|m@#S#ufw!1+#4yfK9l_MVFh
zy>ZV;FVdooyEFAcdmrUL0AykBS0H{~HU|y=WvLAvMi^Y5S at V+hbjo+bqTc^06Y-hR
zvoAMPX+GvrvLPyobE(n~bPn&D?>3xUm2q*?S6Q-;cV6UN(X(z$dC4d at XB@`cs_D>C
zw$nRAcIJOUQ)RV7x9Lh%*l#oxQD1qU4}uDX?z%zJ#T;v$Jr$S#;<%?#lZJyx(>o7%
zAw_p_>Vf?)zRDV3_wASK^e!6JKmG29JnH1UPoHRjZ#2Ictt?ivoRBTLvJcU%scy at p
zRQJa?FSZHaO%Q%%Gi!D4g$wEFH%GVJ;DPy at A+_y7;{I+5m9Zo+s`Pqb6PG*J@<+RD
zhwkd1s(xn&ehjbRe6hd<X9NP+fDe!>z&UMM>Z6;1wJVU?HcvfMnRPmW)-S>X>6~&E
z*-fH1Q^6OSHDl#xR4l4~LTLj&fJ#aD$#Q(06!}~(vD~3C=#Y!pv#-Jr2j4E5SO{v0
z8Ygg)8*Y143IP#2=JBkWZhmpY;J3=NE+xPaJn!sd^&U88Odd9WR_7sBS72-8+Too$
zajY?k|LpEcWtGw{l-3(DLCCYuO<B!;RW9#5*zYDB5tz@;x?en(&AEN#f@@*Y0|G;j
zhUftA_UBvXmc&WCytnCWSQ~MSXIfu(z$Rc7UJK)S(z4C1x=`LgyC7c7YKaLX at q@%K
zU`ok-zx%-4FjaIZkEl`Hm3jgE=FK7GlggmkEg at XQoS18%)miT3uoFnX+0L3`(MPFc
zy&O5BN|+<9AL8^UEl?^2tb;C9T_Y#~3a&X+J&AxhcX!~3hMd|W-;7&A`RN6A_iI-%
zE=vZwX6(o5({O4n at z-7jMqeov^0*Dr`Z8Z;ep5^QKIspj3te~}<j19#2ZgtMtmWJd
zA71Tz`_eJYQ{V at 5IwDkzFIQ>ZP*?sRPTiQ{TYPilMh&0`mVf-oF$(Posdh)pBg4^I
zS1zIsgP(z49i9T4hu-Igd*FqMd>(zM at ujzf#P-h{fh0;QKE5$&d6kbdHsQ~!C?F5P
zu9Hh{d>_c`=TRW03Tz$F!L^v!UiY}c3{{tc<2r3~huq-u&}V|!%Kf(r{h<|KnhttP
zE}i#fa at ZD+=6}v~N8HFc5G)q*9gH2ef at IE>*vFY-kKd?eDohbvV*J?NH`jM<dj
zt1)LSHXX2J`b{cDtjwUcmY(bl^G34xei}B^ezMAI>)+ao7h`7od9>e=SZ8%{uOXmU
zi1tsnp3Vo48r&54rYPVYi$vbi(VGAaK?@*lQS)iGfSk!;dN&uksX~p2EaQbG4QS&-
z>tpb&8Uc5J<M<ZcVgrT_Zo+wN#l@=^%P%7?Br^T0S^ijlxD7?ggtfq1KQq8i1#9cd
z$N%Zxp3Pi<YY{dvnbmCh4INP%K*#G4kCudpp0dKFGK7A2C~_nz98Y?!(puU*;Y_vz
z(eoIfv+Yc>-oWPU8~5l|b{tk%+~h2GW|xo6njH1-KiRmENl?;xz_>gmWTYsF&wKET
zUX~|dxd_Q&+ec$@IT39`P3AeW<x8mT8>{^L`>V)4Qj@?SvU{!z$=M at q$Z47}{u0h2
z<ukt4 at _jQ(Y^JHQR)WcD_Z}Nc#)j5<%SdmT`3-c_(+rE1HZ%GSjczV}(KlTkHeMeg
zOE;1~NVSMQzEs<s`aJY)NW<;=jYtTz^swC^_}g~cXCA{F!#cg6>Tx=TRBpJ)D1%!T
z*Qx#Kz}a+YDPPp_<6wu$A2J=7Kyz-jze2z5-(wxQd=KZpF0Eb{Ij31-cE-47%3ouI
zvYOFGTmEyYnWw_?pmPVV55q$GtC=WScZKvy)Vx#V{5MtHK2y|e10ZJIHB at Zz+~XA&
zB{YmsCMrQk0BE3>Xp;b&_l_AKozvXPz+((c-vIJ*kM(|5Hh)h}@gA)-{~rCx(3eK2
zdU^Ly$+jNlKQ?e`L^wXg=aTG|zRVY}7n|^E0cEx-Y;MLk=N@)mF$`?4Zhc@<_&k3N
zNIyn`q%-G_gKLR7-3w11Xw}wI64K(@Nxq&_+Zs7>0O>Npwxf6S9M&C2oz{BI7Wa<g
zoeHqnzs~hq?I+y|eZJJX4gX4o8-nZrT<n!x#!f8WvZl_d(Jdr!J}_jedF2Ps1#NA$
zqxY?TP@?TWU<<r?`cL|c06+nEfc*y5+E&~Ky%47TldSmuL;FIr<Z=r5&h!wR>qBMR
zcV+g#11LFT#)%^z240a3e5BVHzjD-Ytt`AsJ!n6A7YY?U{E3p|<Dk{eM+MxrO%Uc<
zT&vM2m1L4h4K^$rI#~Q}z#DeIG_oMzp30P0DsdmXNDQ(myJ03fRHUv8T(6riPFYH=
z)zsPBe|Fs~x5#PCo+oVvws1*v^E<2X0FPzpITlS5EC3gP^YWa7^+Txp<EW{~?Z+8B
z at 1_;{zNvm4Yx~M4vY_!tfJ&IFdW>t0FgPKniRh1I8s}&&apP+X<EyGjQwRGL1xSDL
zd0MjZ?rsGdNFSfKs&4ylNti3G-_^#kC2EA&?#J2se3fIVN<RHxr_lBKJY5;sD*kcs
zqJnS~H3pG*Ps6$DeGM{}S(0o0S9|TB53H=Qv)4Ugrukp}%kycL>L|uIY>|g8iOg6A
zGF=D~h|4#W|5C|%BdvlIerBRsRrLit$n}HLJ-?(Zf&%~b>t7)G`7o3-)F18k89LSM
zRu10A!TzJnsGR3uc`d?OJW&mAC&Xt^$qhR}tVWaWv)$1<xi?AxvIu|Pb`_JHzR2Me
z&wQc+!RLS?tC8mk3cNoe67odzCkQ+*qPQQw``YM+wp9(Sro-zw{c8YfT)`~w?{E4(
zp>y2ln>KN<UhR$v_w2WUXQ_)JA0wK-0Zk`DS8>|EoAns$10Uc^K67|{EI(ZFvQl%E
zj;0ZH=DwA2y#$D6&lME`a2X46d3?sPjb8i~(spc(NJ&#bb;s0M9>pngiT4mUf7PK>
zDYY<)Fc5$3U{cvKfOBBf5R2Z`d+ZbXvW=xijn4>OtHs8B><Y)}5Lb5MeY$%Yq at 9!s
z8TT%>M{^*RlI=lw^nHyPl?to&1G*phPbwpTJ^h_s#0OyIQSP~AB&R78`yG@}FG6TS
zKf{IWC8Pmd0Y0AcGD*%~LG91g)cifu at Nj$<o#lO8Gj--iLz`NK2fJTh;kcsqZ;`zc
z(omh9VkIi+DvkKJAR>_F;+Um0=DDi;pQI!s_D`b(x2(!_P}=d>ug3)AP#JdCHX?(<
zzxU>S&1-{fjO at 0S-<u$knzb>&sI{Bb?8|b37ox)&?RbhajoaCI9cb`E(ud9>al}Jy
zrnt+F&+Mgo8aJeiQg0R$774 at Zvmc&~amuu;aYfpj_j$j_ExJtc{;m~TzcQM0%F9o|
zKaZ;Z62y?~(#$ZU*GdzkPxE~V!|@1(`d`wlga|k|(972qn1pk|{&q8|@`+OUrpU3C
z#!gVsI at N4CApIkUjbr&*Nqp*Xr6?H#zaC-JY!5z}ePG~#3;fFy<+5+E3LZTjn=Xdt
z=oDFMHKCCERXYiyHWP#JJ4sP6OJL48Z;d)fz>bEcZJEnxoVUiOPKOVwNkmlR`G)z5
zUC^jdm307vB4|Lj at x^2iC8qLnHx`5N?jtEaVl?CppPW=%Jj|U{*Oy1^fxAEORO-=|
z7q8Q`-Y@%2<Mg0 at RS(0?=UXc&GEBYVJe#lGmws(>Qtj$$QXcvvbSG=~)JvQc8lko~
zVd>b?q3suxM{UtWWG5vNnV!SG{Bh`=l)j`)G~N$D`;9_3q6sCIf`%q?Jq6X@&=*#O
z+6jDoQqP!us^)(u(s}8E%{kzDZ*G&E&uFGHVS#@ALAwsuFdTe?2dvYJI~RNn2lpTs
z)AUr3LLapU-?0t12 at KH?%O(Fs1I>P!D|K_`i1l~|Q)@24V at RQrK&5w2VvLi7s993(
z&zR{<x)uT|5qD_l%lZ3-S7x^+zTFitus=9^!b~PJR=?#R$aQJmw#v-wUM2Pme<pgf
zillX!Q?!+o8%OT>(Y}fg{YxVOwcL at 1w)t;AE0Hrgv0x8f2}rHx{j6o;>AG+{t6qD#
z{N+>~r?GYGYGWG~>V`Rtd0K{Y`_9>#VjdJ$$Qd)_w15aS2p%wZbk{8N&GK2{OC2b?
zsF{ES<Mf0hQunpk)n4 at j$in?9Cn|{CB9YAGKzjT|8JJsXmt!+O>!*MSQ^1qD`(+=m
z<Q2gR-S2-L_Db at 7Ts5FFpwa_%zkX!$WC#!_@`rzdVsGs_b%2&!ty46_<aZXoDb~-|
zsoThluX$=NoA3b~*yKg+A>hKzr78}vWy}_iXk;jms(0uUx^hIgjS>nRuRPq>FE>ar
zN`w0`BXty=bUrLsha;US%1<j9+qL{sDwEZdo?LVuh_e^MPn~fxJs<XP(GCMT6k9m5
z?FWD+eYn-$7Y$2pTe^jNQ at j{Gq5exD!AB!M_AT_;IYZNTTyJs5C}MG%IL<f%UG-A$
zC`HEix?nHYD-+#LV(p2rLpFzT>6?~(>E_-q&d{55Ye-e{GD+K{^CuQh4Q6}j&%ppt
zL-Xf6_wQRGo%*}@Z}6c%Nvnub?o at OFF4+ku!bU6MjXSj#P;@+&+GOSKIJ;Gvhw}`2
zvgy(j<h&}^d^j$Gxs87DrQ|<K;*xFqw7~P9DfU8HQR-mO;XDO%klrJuJ$4Utgrp23
z!E|`NRDwfgJLcrEDOZ-M^ueC>FcpQZeujIX6{G2*obWx#4kOCvSsEiSZE~2naIWAQ
zTw>=mWMS(^c at px_hRI_@zAs8eslZ<}W1}wb6(3T1DIfmlRiU*>5R;m&oXV~}3Wl6T
z?rWCB9!^`Ft#Ub`vtC6_%5O^ud08GP|8v|5QGP?+?1UYVSDF!k{T$jfS$#;OS at NeW
z$pKAp?yI!7Z?#KR`k~^*C7K-ziXaF#o#9#R>G3IPHJRDN at h^Vusg?e1Jn9S7edJAI
zww4W2X+KLFY%3tSZj-142(s_zr0O%$lJRENsEPxZ{J@!s;G?R~YHOO^q~X8k#TN84
z9<fe)uK3UJu<umd`_%nX(9FRyqc-0dH;i`ElUeW06P$&b>#F;eLeii(^jhYdm`-#K
z++hs_2mx>c1T!vd#QA~4y4-*o%+A)q;K`pS-b3ZxA2H=<hPBl9$bEL(DU}}8-h0F^
zpr2-%>Y}W$2Gjk-dO7m)pwpMhLg4t}mfUTnwEAWrk=0Ll<35d;*`_9P`y&@^CEjpG
z(}HXHRGr6f-p7wdtxQBe|35UHby$;s*u`xLl?D|>x?yyqGC>-N(J-XD25i(olu0W+
zT9EF}5jsK|q#KFRZ1iZ}{oeO_|KGK1yPoa)+|PZ^`5cgc2Q!FxdG|~fRaA<onh8x9
z)z0Evi75!XdX4K&=NiXKY1y~$CbwBwH`W9C{V)~|S(z#2FOs^d;S0hTTs^tAm at znj
zhCP*jCZ{e>LQ+ at -N&*w8bZg%1<XxLrpz5oqYYH(SpZ(J3zMrWoMPTU16*)U8Zc$c=
zgi?_<#9V+!j%w(0cJ72H-w-Ot8JdRBAB(D8wArTzG at 2;?e4|sH0V~?9sEbzz{bI}&
zcD^EH#3$9Z(X>22OaioWU*QiOqFkMKhzf*QPo`qdKF_h=u|TVa;&NPGB53?oCy>D<
z*^DtCp7iHY67E7=#v`kkjqbS)v{lQzC22aAUODkWBX{iSg04Xos$~%)QWPh#f3BXw
z?^H=34YvGeNPEm*S=-1M7Hgc)1$9naEzIMPgJ0OJD-mfv7F0zaLHJI*l at rp%dahL`
z5aTo-06}AYA1K1EZV2el8-DvHx6xRSNfQIQrafK`A&tp;s0FgTuxmV?@(yd(y!R?-
zS*W8#YwN_6)PSu!N*tA+wlPLNT8Jj#PMj?U)h94eVqx%Y?2G}C^AOpye=~;vied{2
zz72d~ThWOh!7FEMTWc4W)b|=<Q#%hzuO at 6@E;LK4?gd2a$w#KU>&A?e8{^n2swvqU
z_Kv7=ok{9vjJz)URtqW`--BBx4K$Cre5z=jzcf8BPy0n(w at y7848u)$TW0;-uNwHm
ztio%xHE&h5`?7qxk;*1tSJgmaNX at 54M_W?F&vk at SZ4J}k04ORM_j9 at UiBD2`N$(rZ
z)^j*)yEc7q>auVT(zt|tlfCDr at RFcC?wJPYcFxlLgUsrd%r{}DBWwFUqy?CLT@(}R
z9j7jG$g&JV`Kee9Er;RL!W*2sX at Gn;(|$$!Yo$qrN9N;&i6uOE@$5>t{qdQf9KoAQ
zhWqbLUly8Z$359AaxsAvAW>H$m8Nb9za4g}895)RSX8p;hqbGmO8L@&HHAyeCumdz
zBpEaysiu*eZt>C^2_N`HcF^0ZQ(HBTj at 3C%Jq<nAlt23_?CDU?j~^&YC&m39cP9iQ
z{Z4+<TwYPCz=rWJx3ybq{U#n8WlrZ>J*-|eLiM3cSiMwbupKt{*G>!+*HoL-1Rh=q
zX&NwY!z+H2Q<vm)f2&2h6+u8Dc#Yt+7g)&GUbpuD_X2=0ipoQMG!2)G99~^<yQ!w1
z2+M at 81ltVLC?hPnVfT)<U at rO3(huf=%XOp)rMJEk>UraQ0X?e2%6`aD&GF6=IDWZ`
zZQbPq{Xa7^v&HUO_6u+q`p173UvY-8OBT{%$p-yIRPc%D6W))opj{V=MDdMeO0=|&
zbR0DQY8I-rO}xei?q13$jf%T^Eh#|==v|-)ety|s%kdJl7JQ3;iF=#cBLWdGR7lLU
zZEQ_fI!Xr?autl0=7%Kw(B-SS<MF<8JXs%|BcFb!EuWY&{Fd1kT{&mFXvnqW5|zB0
zT$CXhG%u at 143_lKkVULcOW3=Ye~-LupHU_H;}3_!`@YY?M90Ni?K`+d29$r2bFw9h
z%kh7(a@@`-BQDH~hMqV(b(2wcp^n9$1rlB_ at JK(=uM$pfo0~r{-)|QGw3XT;SHXLd
z_W at D_d(T_l?d+XnNrP*A#^T}vO4HjKF_N;Adw)lbi0SI`?67BFG^3{l at +lME@s*gw
zifFeja`pJ%bk0y$m-SODHALOPLs+(gI!tq;$9t)zYVGqSlew4kYnjvj9i-HO8M(-2
z)u>LGnPAFRj&#+m&B7OK<|Lml()drrvSVjWs;8c{9dVjYlvm2h#q8z*q$RDU^NCpw
zmYb2r=;XhZ>CO7h<&TgsW#XS`tpCaVJzwzYAvgdS>MQ9xT|S%r^pjgC6y4FTN6}eX
zZQ69 at Dpx`fa%I&gV0%pfwMU7XzDcbCSLeSfDZVrXuD5dC+lYnL8MFKbaqRligY=A<
z?pkx{cbJ0NP;+(pojCxl=XIx_zqK?sH(v#yB#}oy=gsr0ctA4Z7gyV$Lf|U3PF65l
zkW|;1NyH!xsgH at PuS3FqkrB-ASi-uCqrT|1pdUj*3v>;!kRl<n1Y*qbz5!a-<5n*?
zH7w{fh`#G+=id<npYS`U*}XO~#1TYr=?E@;wak5uXD0AxCaD>Q<{c4q2X9ZDRKDpA
z9zkZn?ksJJGHv^7L;j^}^Pqx1qMLE$4No>Gk)lzTCIuxIdWJZ*IUbeWNZfS2{;E`H
zxLYsx*}@^VBUf{xbSQ7Vi=G&>AWX=e`4N)A`Ste*k6tuf?T5uXwI~IzqJuAKMg|qd
zCAGwrT|<7~kBtPGL~jHa3|O07dsPn^s(Na^rXv#L<T$#Yzmh7gqQ`nRqj^(?ec7E=
zdcNx&G*hKwY<{w at hD~wK2Ubf546VOxhUaoBST<Jb0jMLwdOPWHiN>wX%`$KM=EP}U
z?N2*3 at g<5TizlYg^DpqepVrh-d&_V4xDBu|J^1&{&DqdHKVpyIGYef-N1T172{CNQ
zsWD?MQS3ARkeRe=0CLA^Wi?!JR-9gGY*OV|o!(|`gsf9dG^>*xCa1pE!YCz{sARCh
z5SM4M07&<W+l`e-Z!n07nAQ9IA+mrj`26DFi^(wX(+<&w*nDAdm|{Y`nAiz|uu9gk
ziP3wNd^J>g_&(qFC_XxXYiX)<D at P+YErO%!n<A6Ufgh;&08*^@eg3DHvOlgUT+*n;
z|5Y#9R&~8Fwv{I>>(sz~cF2m0r>*3DGoi8!XuuFE6I+ at dCjkgO2<dpBZ`cRVCP!Ce
zEBKfEaLcwFNF(K84I18H5L#P7i_XIw22T8<=J46ru<wmyb5c$6QzBdP_dH0sok|@Q
z>CE%tOG0AL)zO%6&1l%PCaQmG>cVL<MD at 6787mt*R<AD+l5`Nes?t|V_eHksm)0TA
zQaovprSg at dRX_zPd#Wea%O6M9TKB8OxMGLA-Q~9LTJk2w?*_xdMj3m71&GaFs=_7^
z+rW=7rFaj0t02nX7`^19F{1G`AU#WpQ6HeGK?l7iQkzKH)X_$wd at M!b3-tj{3GlFL
zl at -{&FL1ytAl~8_juvS2CcAo0#s}qE5}axhrP*?Z?&v-FmVO+uV>Y;emCP~+j;{7V
zcjGsmo2MiThCk!u{ktOWHZwcl at cdB#AtXOlHeA|jJu8DVg at ngVIn@X<zv*t)4T!n%
zOWg7MFfHT8tn;MOwrkF9n~{3luYazXL3Wl7fr;WME&yQ?Y8N=uMpE9{rF^!8v^(#;
zCb~uRx3QUcEuK&D{rHnyE8`6!3d-;6i~94ubZZS08c2EzlZP*RcNu2GjK=vMfJXlE
z|8cC at nwqv9Z#<c<uIGkPI|yMhzKtg;M5FstF41d&yLAnQ$Rkc?AGXM{sB~`e;tTZR
zdbM+n1HL2J^VFDhXSYwa&N%m_I$J^_!FpAQZZ!@I=nSS?u?N~CaRk(*_bC=l;SV+U
zV2|9c>sI&9vs-Q at 0F`R_&h%<!IY<uF9_V|oRc1H-Q1~}d^feiy=bU2IT=3(MRN|M|
z8QGI*DNIdVZC{`*BuER5>TL7A?#r6LGmTae{1jW4t^(Tlg*TFftwbq|XUyAfdp5ro
z3Qr&md at jb*s*@vF&wOU+CdtbDId&R9{X<!Yep~O-&!+2809>%6TV~tSn31e9Pd3R1
z`<<s{E>c83UEy(VI+gyog`0DCc at b7i1o~w$aNE2Js7qSxu}d9PvEAn9q^!I$KA1MT
z4d)-L6T46IuL0ZW3z0o6ouRINku0jG(yLcm2zI5M(N&%s;sx*elj at 3Q?4;4<p)TK#
zKs%ND<<ul*IrVlm#s%p)MDM|7nwfXGH36;W0}+7kpTva);lJ0M{JW)#qd(uFZ^=)q
zf`%JCanmJt>~F5smeZCGBl$)fB&NqbT0UuvNqu=sVn9s%NNu;@rPp4#n(Af#qDC|i
zqWt*lzLGm7M-1x5xhjDJ_5Q6E9nH~S^v4^S0(-}=KTCoW4RxlvOJ~w6S|0v*R{7__
z-qoSoq{Fa2c5D^gMkpVJ-uBNznLJig4eh+3mv~V~=$fW_={}7hDs6B3;ap{A+3rhr
zdL~w^a~}};@`$_6=c#|4?<=QO7sVV(U!dfwyXP(~5ma*L&bVVPRRWq~M=8mBhq2f{
zyZ%?K7d}iGSs at j1JE{|;KHI$jXIU__1{9wcwVYl}V2pw6YF#-iLeGm!piGEf8$Tbu
zp289<A9IxtH~-Cc*DG(XSAM_US}v8mU3K9Eo953+=U2q4Fv3{dBHHm4IVGm8w3*P8
z?N?S=I<-i)9D=Y|#Vj|*$m3b+cCT`f$BK6>c$ybHamzsIvk6gz2x$<F5Q&>e@&xDc
zK~95=TbiDa4Q-z+i)s-o-1st8q5+!0^<#c5_!`*TvW?WT(?_+Jb at Gc3$N)x8uIIzw
zS{7am8no8_6;^9#_hLtUdEN)OuR=AF9 at R9uU6~z?9$aNx(8Bz+=uM|KngRvc+xAK?
z1bYtgAN&$#SM%P|VrO4_iXPns1MDdw23|Z&5eek9Ra1kf7)NU+%jQb=s!RDY`TKBw
z4 at +58uwS^6mc{~C5iCq#p>tM!5jM#E6$C=SwkB+FW!#}Obkj3WKSYWHBOmg`T>{AT
zXgc}=fKPE5 at C!&Ks39MbqBDj at 0kmG=3Q4XDKHCLYF$uE9bp{;L>pnT=m|6D~AAj)c
z!A)y+l!auMBV?0lO8Lh!OX|6v(r;#u`&9%sv6UCl>3WG8ME1M2{_4uT-LV4IJbkI?
zT0mvPPCLvMoPGv1PT at _BcHmuIa;x6WLS*n6E~1^^nP``9KTz(PoIlpiZ}PV)=~b8E
zrRJx^bd97mOLkUtYePrMK52jN-IJ<X95R`I-lDf-bu}4yH3{oA29u-DUu>3B{x}F0
zs^ekyiYViXP4^SU5GWME_Cn73zg!|61Vk<PU at 8ouDnMkLrmSF^k;$-Nu9ax~jKbVE
zbncL=cHONOi?{dlz9sO*^WI@&@XKqK!IvOkI6M|y9{?pqPT9v@(FCcy;YL>oZ{`eJ
zwQ7>0B%u^u=+?{<OsN+uE@!Zo>%<$UO}qqu!xY1QvF%A*UbItpQ3k;h_|DP5xT at Yp
z<B$5a{iHyXlV!wDYG at O5En|O#-4N_!V{VTipEhmHDHVtRI1MEXeQ09Cx#WZ)k3z-?
zl=5BE at mzlTJF>r5cWBm%iGsu4Ns2^_`;}u!&lEBY^M{~oJk39q(1SUnT$abeAce^;
z;atgz`K9 at n1VJ?Mb!vBklS9_B>`a(i{yKtaw;v4i=kO`|tD7)>r$OvCtzm|w0_({_
z%fs!f)#~JTyi3&Y8w|D at 3(%`<9A?B8%CoKd9+LTK>BHeO!*A>y?Xy_)L2rb1S)42;
z{p=U at Ut3BFjZo5(8m~GpM(varL|w8hB}F_FJ0ysJi at F;<dD at 3RdZB(HlSY>6d!?2N
zFSb}lxi$}$doPQ>)(;H?@>==BAd-lAA9noB#R7iOBz8?BX<!$WQ`)#cYLRDxP_48g
zZHfSoNA+$%<!zRk>I at i^inkns%-)+9)h0cac<$wCq-X^ox)PsYGhw9M=2&QZe)Qn9
z%(>@O1#<oDg`5v?|5E?c!kEH~Tw-hGc!WOjamC6%Kch_YYW`QY4bES77FGmsei|rG
zD0X*iTFdRZHE<K- at aJRB)>e+bue+Sf%ZGw#2j4*`djB4m5}8=9&7A|{HlfN2 at -2*E
zM#!qfm&iLW9fkq!_CdTol}T<b+B;=ppTrA`mQ&NYz9cQEiWX3P`v)3fEbMTr`~zgJ
zSM;@ckXqeM1?2!ZBhBJ=;nxQT2M_c&{N~^A>}8pt=9hfIM{2!yH}6f?nyR at Su*d7Y
zdY)e)1`ZzQOV%^VK^haxP)|rHW_(SE?SHh4jIv7x-drrc`bX|uA|a}|X4blban$V@
z;#R8TvTpAO{sGF<-|o3oN#XgX{rXeq6^O`>EahL1?VK!gNx6&xj!F8^Pi#pC%agx-
ztkLw`W#*QX*~B55xx!z8p6B>3mtvlGKxz!PIgOFc`g~XfIdkrjtnkGJA|y51*G9KJ
z?v2%LUbDZKf8IO!*h8?r;v#QmUbcC&-!oj58_Ef#iG$%9#XcXadZe&h%~<(6W)pR^
zE;bApsZB-euvIc3G}J)4FIV at T!BjGehrLsiiv*s#N?|;mPXfQ}*1kRIpSg$cHyHxo
zbe<<C-#jg6J>-eieYdBQ=(@O at QT3MgTcMRtLU=^)9s~RV;7!Ccb8bI!su2sdMM4Je
z!H+Gw2?~Q;Fb^%`<WkYh?j>!t3w|;Nbx%vN*yTN{7`h)kut~)tzfS1h^j;y86cw1J
z^UagqexhbB049G)7H$t)b@{X?_dE}doK)aVEIH{{zECL&W-<6D#V}W`uQ&2!Q$m0?
z8IkA{{qjR1OZLz3u#hl?moqmPZ8sOU2QyRDqBJm4 at vlJqpDowZ<C>yX?O;buwX>}U
zpShZQ;XE&Np3U{@h1)N#r_?APjk5X4X- at ZQWG9|F?G)Dsm9;(CAP~V<_&&L|JmhGQ
zfI*yA0m%kL4{OgfYoBJ>vzwx^b*}sYe_zAU##jEi7MT88zhd#Ydmh9&Dvd?)D+opr
zwWM$ba6)~v)3J6;W)s}IP*GCUZELA@#J~+{nZK?f*m-DHHN$=OjEC=_IfUdkW%yQd
z)h*f-JuU)2y(toR#^0zz1-7hZrlgacgqv&Us2Ff~`PHdvo7hcV(@P3<S$N!v!*Qd>
z3umnY7hR)*3I3txvD^&xKhE7;+&YMC+8dSMiKOnt<q|PxC%dy>Ix1{!hNQd`_TL*+
zjuxqV`?2$7rb|t|FtC*OQsd}`yzG_c3F!oO_{kXssk8W$5D*Bp<VI`MpzfcrON+{j
z34e$EqV7+-^z;E#Q^StAZhhw+L^0TxF3mCPMu8o&+Zin~6Q$0L>)9q7)wb1HN*ok?
zFUg5G_)1)EVCq{U_v-h}vHIq;xw%ofKO0tm{l|)!M*_ at R`*!_tD)Tq{e_r7T*qYN%
zZd`bWwwux<L!e{5cNhYa1LbAS1Y5!5y#7p}tHbSa$OSs6LuJU=zM(c4^{IF(-;EUt
z`<*$zSnNTtD6g9I)CahXn-shk%z1v7FVv8j?g^9A2MkHz0>2p`S~Xxg{034t|26K{
zChLdG(ubpcI(7y<)zI&qiz;rl!!ZJSBXz|47#F}39RqOZt+BN>#<$=M_1=uLASLqo
z<dM{0_7fTEm&KZO?oLql9fO at rlo+Huyv@tW8E at GAV^~ad1CyToX!7l3-zahUDCd{7
z{hyS-I-Mtx4yNecPQn*%W(&IrD0-^*+7MEv86zhMisVTHJsl)rBPEs2Y>LOpstA;l
zqZ2fr7bA?hb2N!90E|A)89nT#2nsr3vw{#bFY+{WSXz0p_0Mt at rkhB(kQ_}3%uOc%
zXO<?`K3%_hjT+^qBID at T%`{piE*9oGRO4gVMd^F>hed%oBfMxY*i93}CyJdfeD~$6
z+F++A>Ey3cHM<VjYXAU%>tk8`_~0U<x8ULTVc}dX{(^7hh?MKu%@8&7JPgZ2nha!6
zS7PfRO*hT<9`;#DhIunZXe{pL&7SEkG*-<WP|#UQ<%;Nq$yC_u+O<?PX;jaNS1;@>
z)VOO?O^cE7-XRrU at T(^>c~WihaSuXjg-5jN(j}W=v?Jv6<w#6G(_?=9 at 5`b-rl$IK
zn##l-Fu_7pH!Gsuiz+?LEfwqxxn6}UaaL3cqlBwvTWSscp(^$|JzXKMziT)pvYhf$
zlaC%?P(6`3dA@}vdmQ30;!WgTRFaqU3STh)bRYU<uwreTt{2yzh%cR`MP?&^i%{p6
z+|Ih3OIz}~p}%gxkL(3AL|>PnS_GcaBywkO-(Mb*u3EIIxyyK@#-c4)z>-wfP4#)z
zV0O at lxPTV8bv$cG$Fe0?92moLwp>;3+VKZG5?MB|;I*XF&OrAw$Eks`olbHB_~%aD
zUcv9;jA!X8Xn!9cpHG0}b<$(<t|}bQSi9BY+FNOJ%KJQhrmpONCeFJ<7srKHmgl?{
z8_H=jG3n3BzpjgCNODyWy>OqlM>+^PJ^`8J#AaO>dl{7P;Mvr7MU?02=sH^c6i?1;
zrh?{i0`8oT)`m!!&fcj at uwBq^&pzdP)Fo`(h^O!%wJ-5a80EH1r=l7%p_+IutpDVA
zD-8)_f4KJ9w*b06L`vgsM!a2|(>TQ68c=C+zxRqC{!D5fy0sL%#;iMO4#)eoB$GTY
z9x=ltIBKK1dIrM+Y<-1IE2Nkrq~8HUZCY(di=yb17rW at q`D=f0lGP2L9ej_ktM&Oe
z!~0hU-Qf12F at rFFsA3sF3ym@cKTL7#x!HZ`kmoknmKye0n>b^aggti;@i%5MdK)b;
zggTqYA4u`Z#mzOo?TrYT-aUtRAE_>ud-%nOtZTV+1DQEOx*+tW0WgnuZ|aHSjcePS
zWkysrZbt_2Gh5ph9rPEO8L{eyw?Xzs9?aZZoJnFSaNCrB9})Z}!6txkEuJ>&%WjSI
z>1Bg;DWo63myp*1RCfipi+=Meg}asx^><bpDrQRU&>QRjwbCT}qQ at cTWvjc{<uY_9
zo7nO38VSZAi>>2N4C;2keY=4R)<1d)PHy+(Xo-yoBhkS2_I4^$92J$c&NAzbQwf~n
zESzF~CiHs?$uqLp*8n>4UO1*hVe!G@#gl{ZU+mim9*NtPe#SC4{Q6WOj>{`XJo5%`
zqL*#Q*B8MtEG(4<1{sc)bb-V_S|7J^M4^wo$bmWM at rcO1qVr!wg0Xx2GR46 at Y|@y2
zV^+|0IB{+#{$!qAiye*}4l1(p6U(AKjyXF&-lnfnGsJa`94LW23e!+g6uJ at A0Qcpe
zL<+j(051O at Ee~2$2&vkw)*@TP=<ae=A54T68MxY!LnsIMZYquM#K3IcId_IpIppIA
zjj`oUQkx-q2v!cS?JYW>^TAHCyM<1zG)|754LI7HORhqQm{Zu_=5wEh>)d3KIK}S;
z#MB|ag$+;1P7F41BNmo^a`#SC^)~$wy!mTsE4ZIL)IVs-7VIn))?0Av&vOT{s5Fv|
zff_#-p$1WH-L<-5;i35GcTBGld3=(vEw{o}v1vLQb4#m>Ibaq;aD-ytBy~)5;K~f=
zL$gMxdVZgWsf?g_Vt&(QfsV$?fJGzrWQ1BT^z at 4F4$>IgAGTGH^vTEF(yJwz`fdSP
zMt4vIvQF61#qOGgw_J0=R|hMr%bTgA%|+MyjUKf)F at RNbk0c=LPQUR~0$K)r!amIw
zkly<?u5Pd!FS%bSK at JgMOM96Y3nNw31bUlF5f`A|p5R_g(`{u9MV7TOto|U>oIfrj
z=oq)1LJCzRALvRmctr3|{{EG{X+0pn{ks~A{oI^`RY#wk@$2tb0zZW-<K#O at e|5C?
z)g&FMCTc(Jz0*@s4mH>f-B8a2j>eX;@qt^vz4xL3y!Q;b$o~=Gs}u^;oV`z7j(a-!
zq$qYBOpfqq(xaV1{Zcb1zGJ1Bja>hndC~keh3Ds_Y29|Md~1=FbTzv!K?)1>u0ubD
zuD#ftYza_C?so+nNP^w~c=xt6q&rK at Lg$?$-U1eBghVZ_gtI==C=(_)wxr(ZsszHq
z%oF0wn)&=@PCSJUu(`jknpE%e(IQK&b%6v$c(zkjniSY;rgbqi<58bE at rg3xvx@gK
z^N%x;o;wK#NlIPNXFOAI-eGq6P|RrGTr0OxqgIxmj#K$P(~{6G^xBd`D15 at e?sOqa
zzc&B{4Jf-;iHL41CsAi(Fsqu^2#p$thR{VE(^qP3=4iZXVhj0FtNYr}KqbpMqO%u3
zsyz3y9Mrn6wED^aF77!;*MX);r{1S_;rjLJVTzg7%O2%_6WSd;#|wWr=6s7DIb>A_
ziqUT8{>*8F)hx4!R(hdJavJ at 2o>wLs=YAYo9=L8*$6^AIXKpmiS7*S?s9fJ%UfNVE
zM>6xQ?7zi<X4fNqeSNbX);?YwLUa}iBHs`hXHnr!7g)Ye<u+ at OEI1w$bxckOB>@5-
z`!sGI*wHEep&9?8xp^7FRnQB at gqa96qV3YU$9NQSGnSWFAB4qGkMaw4f9v#;qlUHc
z7rlJUqfdG}fiL*;QxNxEeY>O%%zqe{T?FWd8G}+(M|>6))ONgW^Ye>jFQjT!jn3NC
z8H9;|I$MM*k5h)Xu=JobXinx6Id|`HGO00yghe*&*pH=-ZCF}bFnt at jr=Qe6@&4I@
z7cbb%tWBqn3Tc{~N at K5!v2$N^iBL#iooRt7UNVe1Oqt2Q1w5Us3pDF*8jgqhQEx<V
zS1{U+u#Z{V)-9-~i<KUNXyliYW^K{Lb#-)eA8|&O^7qA>WfHbd`l)B?2G6g3qG*1o
zyXNiE&u`a at N#p#mXg2kePTEwZM>^P<shIhhGA$OoO4t%ma-wr|yTe;2K_Ne9lGW`8
zfR at bIRHjXU&WBm-VY9#E&JM=pZ?dh`4V)w5q6>m*pVdEn=dtVbSvPENdDw(IGS(Fn
zq!%<Y*u0=Ni#(8WqBUC8^#Nf at Qi3K9f!^_H&F4lm+$iDo;GXyE7L|E17ygSMz;lD3
z#*Bm8)L~B_b=l<1n<FS^N=m##-?%mlG)@9?UaTxwB8f|FT`F1+WO!qtcvw>zQyy-7
zwdw1ELUT99Nl3Pw`jAf747Mhw<wF>J|4+2z>f1e-PDq{1`1x3pLns16qgut}&@6PL
zwL926?uQn(#ZJI6Gt(vljW+}_>>dBsOv1X9OCpskZm%>-huWU_c#1;IHo#ht>5t9a
z0V%U{5Z7vjKRTTbVSIA+{KG^vDupyc{2C{ha+d6$l|AXj`sg!DiQnzhM&-X=XVYvT
zmVg|m{p+oZh#xdO4G~3MUxz;OAG|ecETUc60Eur{hyeJ5D`coZUsfluBhO(noPphy
zHJ6#H)*H;xGg_B_-dyj0at12|MwRMDQi+ at 1FfEaxO%jhJ&Uk7{9QbKtFx<RcGYq<x
z0dzML at 9pgcQy_L_9ltA2V#}l&=tf&f^8#4>09e&V^4J%uRn3u_Y$f=0^(KBbR8{P8
z$#Agx4Rh*UplsTE$=LdTB_V_Sp?$}bgqx*JTc0pY-Fy3C)u6ZF_JIubKXT)p`;4|_
zqrB4H?Aykuh=)JPKZCh=Dz>*X1^TXy at rX28(z)}XlGA!}!HJ2FWh$Ruqb`bG3-KIm
zIa<qjG`%iRbe}wa6}wFs!0{jiNgcGvRt#+V0D^HJ!|fy!5+cCnmY$|0PqxwHqk{~d
zd*`vA$LFT7rD?Kf3N*D8QrZAX+&_pYGO|1gjBbJ-5{R=nvT!$MGU!9XVIDSsE!$RW
z1VnPgww8O>ypRjEIE&=Al=PZfr1o+9y(Z(a at Q&ob6Ijv|Pel`P!K89Imp9sq+Vh}U
z;*KA#rO|`^eZo747?g(N`?;E{;Mw?CN0!n||MyE6v>Z<#pGBv1gH at oU2=Zo_#+A01
zRJ7DQ&rv5UpYS1W0t7k}R*YeOXKyryFuA&n?cS_A8rbncE4W3Ze(FY&^a+D-eQ^r7
zGnPcRw0Ftck=aa(sOIt4hl7#)X-J-md4^&Dm7a8_bfn)BElFpngA*syl~gG5ThjwC
zBw6H?84A_;=e$vdJfB4Mk*6EoLm!``ql3BX)S5<U!mF_(cNy|GlfeUw2FrW7Lv3Yk
zsc>D~wO^Yt+>UUnyvlrmK5(e3y_*@)5Zx{{Ng{c~=*Xy#9p?{_esJB~u$F?*>;5RU
zO)6y(H*QELWg~QbetwSq at AkGAGhMx{jinv~c4!!~NuyjRmP*vhl#vWlFB?@q?{rvi
z%M`qy)G(MwsF#V$At+Z}yq<ee%(OJ~dGdo(UJE0KKg*C|rjBD`K5bzd?Ar(Zl&2x(
z+_(MJ&yPyTjY|$D_!-aMaX$vfiRBmUx^Xvae-)@%{eLfj$LoZ8+CEcyxK-MF!#Thv
zw~2XR at m`*Lxf(Bj$g!{Qw2VMy#c*S!0pS<8oO;RJ_(V)k>}mnG#rolX?sGjc`;o(+
z1M<4$Ep+U#E!jzLR=moFfprT^|8yrq5|hd!yDOhZOX94;r#0i3%GeXjpPIl{V=SNt
zFB%!w5UgM4vugg++)gKr*)SQdv5j4GHWFQ;mRh?v71kSjCi|V(l7bELi7z at GGBdr<
z(J^>>- at NWEgS_2({}0z7XO?=an-o2>wJty0#f6wdz1WO?ys>q=+J`b*^?cdXv+pGF
z$J50*XVLN(J`ul0NSfE3_@}(JCX5lvy5yK&;o+LY`Mud<W2=ft7Jt!)!A)WeN$slB
z!+IUkbHa9`-L~c0AAK&mN<u91Qii_0f61fYzTo2K!+ at qBL2k(X__FCWoZiroEUsl3
zJr{xW-~P<6G&5f+QgaY=eMq1IA2A9x?Jx3IEAQ-Hxa^X^+^kxa(RY4}6%ALXuusFq
zG^xK7IpW?I>-s(0H!v^_3()H{p52#t6x+#8KgLb at H|FY}PQs&7QXeX#%1LN!q8k=?
zU@=Ky*jWdCQ5T~A$br|cK5vf;^Zm+JdGfKg#rI==axoT9=a<8~$>Fy>k9aZy-?%>1
zIp(C9?|9(1##^PQR4R-L25}lveYee^d5!8hC7 at Xkpk4nNFWG@wS6As5;Id<{ieHn;
zv-XMewvxP2;v~0|K$~|DBO at wEfuGMNy6{C~#p=0iHQZEX!_yZrfvc at r*8AGeOF*U9
z?`ZF`iAkS5KdTeEK|qqmJeMsl8zYkuioPFq)s#n0Ak<KfNx7+g%<RW%ONA{)FLsTx
zDD84!X89fOA#s-vXI~+r5z2J2*=l72D)?N-!qvw6H4ZSkqhhzAgSWh^YQNZW0GrxX
zCP}lg+z~l63Vf_mf`Xfn-MV~47jC_c08_4jl2|=jTMnMGHKW*MeLIGTL!+_HE0YTP
zUb^E|eZb#-{Z>AHb&sVzs?%rB`%5-!7H<e8I}bCICN+H4_u2X?3z<y at 5V`jyyvThj
zlrzr0kMfRhom{9C4nsRGv(a1^*N5T4i8xbE=TZdF`5wPkYG1xh&vmZTj5OFApDV+?
zsu=)PsG{E6azg{<bsSa at qg+F2`&N=kjX!J$FMHumGP4U3aGS(`Te-~sy<1xZo^C+2
zbPcJ&8w%^y874kDVB|*bpk~;T%Dr+Tp?!mBP3QNW6xOeb({z1+?&GAtj_(#)7`u;>
z?l~Y-zg4d=em&Bb)v-0*aaTm?D_Y2 at HQyA0WnH*qI3B*g&rbS`43hg%_QklexFOEq
z9Ni`rGd%<1bH$ZKw?}=*|F#U0n>4#C*8);`Bo<SUuK<85uANiK9x{+uw|3YCIgUiK
z16yQXZUV9r;&*aBSObPS at 0?JI$0<cz**bW$D?kWli&#fY)b52pp_QEJSNYq-z_H4j
zv?eV5q|F`&0VOqDWTWp at l))t(4>6)9(G2~!6-{zmn?}7L<icX!Ha8b8#vz0#ayW0m
zt*_stf?92>ysuT3R5fdv>N<elql2?4qzIlG!Kz@}G}%;|_B2=5BHy(m_~JVE9XPH_
z7&Fs%Y%-$T-vk at zu3hi|ucGT|riOFs(7a;&+#yYCpI!qHil)~<UB1H$efj04cDy)d
z`0}_s5FT-irN1v9tmx(3aX8xuU0x=v0PV80&Iqi1ICSO5uweeWF=16M)(JuhFOBnH
zTnVv4RNxIhFmNxdFcQ0bZT+ArEUL4uAWHol^oLimOPHhTZANLU{@RCyefDj-etn7c
zjK9HpQyI;*ozgUpJfvmKRl@|(wKId~^EFv!PbWWfb%=*>%p<WLy6?friPvbZP46P0
z77fdYQF~#OqaTxz{FL2+L$<y`LopHcw42-$!s=(SAR>|R;BA>rsdQ^<zX4+Q?=Z+6
zX}k2{!Cz;wB{_6)Nea?{Xh_>jEo`YbImLUd{`bB9h{c$e)M-YR+g^ys2Isir*Qp3i
zNda1SuVb(3+GvWwidr6uiqokFjaLC|2mDVW9W6)3YISL=<us<TP-<UEhlO>KUU=oY
zJ=(x-nqLuv>;w&FwX6jI+rn?tyaF_<6ogKFjQ9op4w$PINO;i0J-v}zWjnd@{xohr
z1yVk<*<{kusoQ7lv1o!lf%fja?i;8Yt!1sBXT&EwfY2m+6S(%UBoE?a_SuBX5{|Dg
zXug!Z7To^C9sEzJ)nz0u??i1v#=y=Ppl{uxu9oNxx|O|ZQrUSRbCeccV#ej4;BeHv
zzYb&XH04?JKkJuJ*q!0s7btYdVsR=TxcykTyzm#sN9%@(^q)$Gbb_0i%VOkgC2?iC
zhb*KwYg3jzup1A4BZ5zV`BznN5Y=jRNg4;{EZ*+|Dgfe1UxRbsu8c1f-#>V6b8(Fx
z6|bc5`fIRL(+B*+wH*G)oL`JC(pKy}$z3e<Xjd=Rtx>0sV#~I!ZN3oLr~{mASy9ND
zx}?XIoKO+^knuWP!-TEi6sc68JCnmsN%xogb=r96dws8FS|KSQ&Y}vbv)~2cE}m4f
z1FL!fA0?ms>c57%qMqr0lXkicrK6|5M+V(?ubr+fV=%H4FU-j|foU|iir10*dGV3x
z(Bg2LCrimE8NxW-sIp3bN86Z<Rta;PxKiq&H>acE?mHDoTWM>(BI!_Lc?{L8oHKHW
zk;|~{bR0Up6KR}<L+p5{M|ITT{`qJkZke)peM!sKX)(U^AJY3=NSqy98ROB(CZ4q;
zS4UJ5TyYR|;e(0nj7|aZ$zA?uq!qv!)8o|vL$OOK!w%s!eXa&uv|-Q}P)UBJBsKbf
zY|&-KIb;L5nXCa5!T9A@#C*jMzq1_uXZ({en{2rjqCZY^S$uj=*P$|c8pCOiA}IMV
z>7mC!m5kZ at ye8(`Af(&STzHi-Kreg2<(qAn@}iVF4M$~l9iw5kPQJ1#@B2D4&AM(%
z=2gsOSMQxuLZkWOKO)+S7RKOdPGiFc3}syU5KWlMXwkifCw4xL>}kgI(m`y8IN8!d
zYdSZ-fW3nB@!d_|EQtYz4#nKJxu*$e!2UEamm7#?itId3r}<W>oe3muQLQWIwR#XW
z6FhlGZ={~Rb~4$+%yW at AHLjRZA01YzqsdXBAz4mbdN2UAMa0@Mqmnj;W-El5YNt0d
zkgz&9O!*RfF#~E^K<#nk1UYUrs)OH at 8aCcL)Yfv!)^GdPc{j_2nO;7gQ=M=1Z*UcR
zwOBJZVi5>zgptyCh-a0|+~S2%F at WV5aN)kCoQkfNJ_GM_>tXE9t9r_sF+{1PMX|)`
zl%jvFnoTr)EYZjZ=Fl0dQQz)csp*(EJf`K}&06%He?MvT!6)?3exftdb2*pjSbKw<
z_K_44V{vYP6PN}lzXFv`m7MatJ+$!+yMq%W(>(9XQkQQ*3;<p|s0$Xm^le?RP}
z0Q&~a*7}*2&ep423_M|wkn)bj1J^Cu7ShaKs#$?p4^j1*uUCX3;`ZgoLjZ<F(rnF`
zbD+plY3h-65i4(*0Bz%o3;&0meWk5W0`R7k-#Qe3){twHHec8v;^~kG?I<!HcN2Rh
z1nr3v)Z;<6pwg_f`=U}obzJS8rr1>71CQsmzsxPN4DDnAC(SE*x~%A&5-Z6pCU&v%
z@^V+lz-N^X>`iYgYYi!^9zqpnJ}-P;Z7nC%Lxq$g<m|%TX*(hwYLImPGJgBN>P^7)
z*?I_i?bXfcpD%eW_YZX6>L2fD2hTQ at 4;T9U5VXDle~8ck6&>lfk;Sodbj;HEiJz18
zWEH-<@aHhOa9wPbRr;;RuWJ_a?I at wFHJF;US#_}XbW+W8zkjo#(+{t1UAwJlqvN<;
zYtV{gGx5N8$A<2Q5N4P&+R2t5_<kN=OPPg09ve9MPa3J^<Ks^4xp!2C>JGI6nm_}y
zVmK_73__u1AUn#;7Cb&3U2X0yS<@HO_(&M<a&pNNTfT-~C{@<I at 4*fJX})IBjpfSC
z=6g`1*`UUPNq=kv$alSPQ7FEaV?QLZ8 at mlAf-+5@+9$m=72Ju7I~$3wgdd(j&Y`b*
zN4?qeate1TC;A*+;?RyHM%_Q-npBDRl83+v>WB~@XoAROh>b1uEaoh<6Qy9JV1IN<
zA!vEKMYvd`VbA67Yq3j*0VYLxGCAC7kpOKiQ_(x`de|klvQsL{GD5KnkYBKNd4YQq
zczv1qug=>NYgZ!Tx*)q|l=5z at br~KeYwQNF6(^kYiXWG!n_u7+`n;ld0)HFidH;kU
z2OBJ|Jk{#%ZkyYO)P_6hYv&|-)6DXJ2zRFC8A{>aWmK`LCgqeV-YcG*oWxPbKEMn=
zn+*0wcC(e2d_^^2*%>ezGz{awRqg{?5gzuB;+v52#qQSD$LNE!s)jnCs1&h?AuNTh
ztSN(z8$*qA9bq{tng7Xlo12wbv0*G%FEn%=KuCCS<vvR=s}nX0h)ME<+Zeqyi+h{;
zu=C06E`<&@c!F^w!&IippZ<kq at v8npN?I$yEvx*8t1#@#eqQVkXwz4F0KS*C=*gC}
z&UuHD!EVRe^22dNvvwt$^F`y!G0}(dJ-W}0l1(LrC}-H3^%o5JgIk|;Eu%ldq2}CC
ziX=4ME983B2E4DbG-fntBI(js)w%VO`tz)x)1Q~6e=P*oU`vUYuv~B(ZlAKB-$`Or
zyVO%s$O%HTQ(amMq`c{*chz@|WL7vC08p<U=7N!gd6G00e(h- at -}deFS(B-zeeFdE
z6%L!Ea<?YzVL at 5s8>)|o?2*LwvTb!Z5h~N$CSKf at jc7iI6?Im{Z~<42ThT7*{4URs
zzq%aYTLihCB-+ at P#yNpkTu-0(BYrOS3W(F~r`fNBTi+e<wv3yB6An;i54<VOEHv+=
zEazo|t9;ti?}_ at PR68?HyLqt&0W}U##P`0Kn1|b*bJAc=$AO6S_tQ18%ggtC+M|4Z
zO|Rwiht#MhbU%X0QMWp1!5tY=_B_Uotn&DCZcb4_&1Zc>yKY;dP9wGdj6<LURUHg|
z&+5o2h6q6+SyY#`sFse>?=N*9t^S~G>xIF>nkX)d2!Kr6s=&AfXr%E{W=lQu at +0aK
zZO}JT0F_uSgKT$-c_BZW`!u6o+qYPZURv>qg>6sA$B_}}d~hQuV>(Aw4dupxVnfXD
zLOg}03O`vMvRwcrBMgy!jKta$L|M--OlgB;<1`|6ns(JT!pvg|n2m|^zQ9D4>Qp&S
zCWW<J65TYcAukQhqP~}UT!n0zehf0n2#tOx9e-R)>6_Q#hH95S1Sc-<JDxPwQn7pd
z_TC*)?&TkA&x@`!G62JiS=mYZMiI?P9*_N1XT*X$n-)6S?R7a2X!X=+7qU90dgcKx
z0(lSLIWd37e~w!^3G>=iW6p at tY4?F)$@fTnJU((u5BSN+$S1E?*na(j5CUBkt#uI2
zM8Q*|j&r#e7J*&N&KCyeiCOHtDQdmXhk|)s7JIWzM=&$-W}acU3GPX_WlUaSEdf3Q
zL6UDf=H?@1#?OPi^Hfd%kyC!%ei}rzux6kJtx%czW6#N_?jzp2sWjXfjSEZ8Vu>L?
zSG^JXDh71DMoL+T at Xmmq^Lg=J$oB7*>eL-S#qX~`6eXCT+O>^pKeCyBI9U+aWgkZu
zuJwjEh~FZ2j&I0Bf$?N0p;w%NsE@~b<sd624i8E>o2_ at nT@z-1*+^kWaCWjDsx5Z2
zY-{LAA+nf?Onf#s8YI+8!a`?0fA2&35wI`*RgI>QB!2xr;CV=;$4ix63GX129Bfp4
z1mDT>D|x$+nc%Ua8SJj`i`Dnp(4vkSo>GIGER_N1Wq!wxo~u<&f-JyW$6Zdn+uf63
zb2KfI#w}>5D-<E`!&nxz=-ksV9PwY+XDN~zQo!*wTVGOS9+t4fi!VAgl-_1nAIIS^
z22^4ZxLuz=-H?wRqxgOi!KqfGWhRPY(vO<DSuY;w0zP0g5P8#*`gZ2z*=%9Y9bBA)
z&!{2ZY<<snd~c5hL;b)dd-1hS%}=9W78W<x*2bHOETk$MEUM>cveSxA(HKFKrF`?!
z#;%grkwXi>JfX(U8hSwdU(w2`jQAk~i2}_iF`KkiA2Nb!@Vk6i2$x7}cyQYUmSu^A
zjl>>{_467a1^9i2N4K{aNN07p+x$NrSQYnUj^=XYgC0d`J2Qa(st?Zh-)$o#2!>l|
znpz3}yBd4|MM%PY-LuRW&BXSNI#^>48TNQb{;|_Ws^mWT39j6)%dvINBwlxT34Xa5
z|D21wYv8doRk+cQmj4_r^MsN*hSeI!cbduIRH~osX%46S4^n4a1(WNuPWt2b56GGr
zhY^mxHq8&=dXhrn-^bYBUTgW-D%{nLe}5gVGpuehaZ7&}yZrfy)<{<$O))(Wp+m|C
zRPwTXfmroyT+G4NSlf?yW%1t%?Qn)+>Rp;}U#aA0o@&n;my2G0!DmXPn2P65SxVy$
zWJLOFhAW at Pd+&gL7rv8TLFOY~4)QJ2deSSsumlXXXmaqY^0Io;kXYdD1Zc at D)0-3{
z(}c?^M6+DuhIJ;itcj&d5&#p`=t_5DV-kS3<V;VjF=oiIqe$;`B5x$h_jDt9Nu;+3
zd|YVyP1nhz#DoL;<_pgT5d488LIULt{$}yE_%+*$QJ_5fQaJYoCTo@}&fAV-Fl^u?
zYFH4}cQLC`t>SWQQKzY;toVBP&ZQKPDr+hORMyh5p051mV at rC+6US)rf(*BjPC^(b
z-yCX?@VWFHM5W!RsgbYl%X$I(ynQt5Jqmo+MuAs2zCsjfe68nxcYN0!y)(0Q=H=B3
zLRJX_WK@?u5^l|6cuam5eyxyRdW4YXUEs^`wrO6!K74a?_}fWy(?J@?!$_Um_?%}M
zP49{@E|SuF*DIS!T>j$OP;gJ{V at Xm9(w%d$Zot&b7GWmOQrvs=IaVNx5edwdF~};@
zMQUI5*w|!Q2H<Vu0>gUH*)qbAeEzC7oe*E}RDX$oH9k#e!fQ?82_c=WV%H!k--i`U
zeUDmkh(?|ASacG*kjD7#*imIl1W_&bLQuGx`l)mgSN1sf$%(IX4b%|SSG6gWb4>ns
za8!b79UT~(^MS2pce8T{(w=KFhAP}EWItT%EZRSNtt!p=X0Cbq>wF5o(d~xvU`uep
zR}HRh;q0hiUSu at 7?qQx+hd*xo|LySM=8dM(Du(yf0 at j7IH)HdnTgg%F!uC{mMCy(9
zoh;sNFG%s8+*c$|(JT9$w0+e~cbp6KEF`Ku(D`HX6C(Og_7Un+GoxB>$B;_*0YoQn
zu<-YL?6%#`K?S$Il%JdpvAs0}l`Oq0^o;+-?^~|7+Aa|prUG<h?Tif_Z_{#`iLw|M
zTjA1*TkKDC at +r&94HK!7RRi4QGLyVeZqLJXZ}%*k**i$`_d>uyAE^?SixMttx_R&f
zAD#4}*G!q`O6zt`DWKs?SO~6Gu1Zdca~mOBM??>8fb1b|=~7;)Nbqd82%q&Aq89EI
zby6p;uP0!jW>cLyBRVoIJ*^jAoAp2Fs<Aaiqh+19bg2=L0-{>Dq3ah%=g8U!+w10$
zN%ljiK&q$dooBS&>`$T;U#D&*rT*hzAVO7#dYbW7?)TGdHA$BWykHB3iH~!k_EmtW
z00!Oj!+wb%=<=Z&(<bC20JinngVu;$ZOU&@Ia4J_jLc}GK%j9IR at oZvc411>y|LQ%
z+6S1H>gHf)Xo-fudK^%0H8+T=th<&+Oz6M#c;otwStQWW^6;&KIKe*e%01h%$YER7
zQ)8=5yj-jdSO4S~N|5~h!uLm>e+bs$o)Zcf)@7w#bJQu?N-u*iEg|PnjyhnY7_}(z
z10%hh=Mfm3!~i#$erR>~7t(KqzP1S6ODwJFOh%{(WfV)`3^N4ZZ(XTrx$gdp?_f)7
zqxH;1XtWS0xOuE%*a?r}yg(PR at z+g#`{MHV;>_#kBMTQXNdZ+Q^|e$t-=KmgUgo#y
zI#MKvWGOP(n7~QjhbuMigV57*%>>_kNU1)}?8!VHXVmfdm2u-3T>npRS&MeH{`zc3
z#|>9jeY*kv{EAQ7`NEGj=0VT>jq{*WCk>hxKGMF&%aa?9*;=`D2{t9GHlk~6 at YJ!>
z9fl5|B<m;aooJ#4t2r-tT{$!_%|>~v474*CO!W+-qR3kE^%C>jGRBUBkdDZYPnfR#
z)b?nL#Imu!2I|vmDr66dt;grBD at 1ieeZuYWxJhCZkf<xd_l at B_-?P+cqf8ZVeFZHI
z at MCCa4osVatOL6zY{nxg0W{n`aIOLj$+JBlQj0t07VxoYat%(D*mqB<>GN`Asqf7x
z5^91DdX2Qo at B|Z=8#V~n!z~YX<Q4W~;BAC*;S2|FjX!<IJNKr8>()9UR%&bFouI28
z;ab^3P^<SP+JyBG`KJ=zXgkY5z at hut5<)d}(@E}I2Hjcv7Uay5{!yJ`R5VBKl=kf!
zq<7V=@bd%>A!)ou>#5r~w)qPJohVIchL2iyEXrE^gZ+Kp-`yCai3`@B%7VGY*%ONG
zA-+TL^wuSMpger$nO2tLJZu)fu#Z&utdLk_c at 3xMIT+#Q&gL-4E#zBvc)<N;2ENYf
zBKZlA?zok4_Df>Uo8ao{PQ at Q~xey{9EqYpI{z|FuGnUpA7w&7s%e%->3nxe&A_})E
zU4rRCPr>T*B~Gb?T>MT|rO at 2{>YK%0ZM#IOXvnkRH>T+o<|FuvR>GG2C0WkMxR=a=
zTp9D6=xdW@!KdHBoZOsz=Cw+^Wb!-i(&}C_Sd4Dk>fR~s-7f=SxA~X?=+3OyY70LH
z{bW at Yw;119h15jUKXC*Q#j&H>flpx39gAhzmGY{%px$Ku$_mXU%7^MU33_v_M?&+M
z##+jg$tU*G7g(OSx?NNc!0g_b*u&Lk<<Fk4;>GjC<@T>BmGBoKDB9Q!qlmUr*yu^F
z|LwSAN at AW(L&61!FeRt_F3N2Du%^RmB`m#!)}3?@b0qtPSH+Ib!gDwE>f63ruudq7
zR;3oZzr4%-D`iYi)&Y4Kn at FkYC}8_nlwg3KMGIr-xU9=<yDWa6Di#URPQr;%gqzcg
zbg1qo?)dnaY2V<su>BU>xeBb<*9Oh$?!C=9DHmF8`^&0zk6?~xE9X_y_pyn1E1i>o
znV1{u0E(iR>5t}&gk0Uh02;it`m??uExCiwL~uf><L{&W_7F0%Xh+fn7$G%yK`88d
zcc<CU<z}$9R=7M8i$yG05;pm_{tWgH{v$ESS7s*L at i)GO&!{>DP)|tvXim(hJL>V*
zHQ}IZP660y-I7w?)9cwz3wmFbMBKbo(24)-h8Ky$^+%SeuQSV03+#L!|7&e}*j;P;
z9+#KVm>yHwGF;8`Z1I^{Oy1MD`+liYjyC+RHSWx0dh(%xv$fB at A5(VkG3<X6C!=MC
z8#Zw+Hh)bYa#=9t&rfS6j8q%mT|*XmM$1T0N}kFxh9Gh-R{YURY=2xYy&F0(h}wEg
z`V%En<Wy-DaN7VJVv6QV0u(gtG>yVo0eYJLyRn*HGiG2g!(OAVh}Lv5%MG^#mtWyg
zb^sG;tSb8h4=&<rx8T@){FPs{x(uu7?EbK$g4)GiCHpLtGa|brCW*KdcSWfkZ8gn2
z47bg9Latn=o3>&ND}QV7`JQdHFq?Sjd|56-{O-OxE#LJM1aUc222O&(;8qr`-t?lB
zj4*_4-fO<z4I|E}+q!m3(;|Jgxce0_6se7$M^E#`me36<)@RB1^<p*u(!}7C&DZ)L
z+ku4+0ukZ~k6??`u4WWr2Q>5Iv<dADJRwD&SC^yG&sy|lTOQcgR0=_=s*)1^diC0m
zs@!MY-@^!n%C$-OohLK`oC=gr>Zx2k(D0??u_+%MT%o$bHOo;$i;%cFwfm;;#YOcx
zA`sQC!KI$4u6AilYKM!7 at YC%%1p4!v@#LHH-KjMo_hJ(CiR)5*l=)MPP=E7~;F1l2
z5${6loJ$Ix`1<S=SaH(*9ujqNsr(3Q{F;nDh*V@>i5O?raGGj#P5XI*(y#L0 at 9k3Y
zDTDqGO=lg|)F1b8^(Rt-gn%NbAl==lpfpTsG();ua)b&~LYmRt-Ms;l(gUPpNDPpg
z<b)B=^?A<oFXwR1xZ~XWy`Rtf{d#p6_s*a2eO0haGeK$Hd8jJzRO|-$Iut9xSlx{E
z$Ca;dvX8!=EjvhCP}&9MnWc?}MpzO1CDw0!Ko?EX3yTrT)YA!d2|FU^J0^_Yly1|E
zqgRcOX~IQEtK5dN78%U(PV&Sc$tcWdxzE?dznslW46k2YbjfxeryBk!mD=XDQdQ?$
z`fec?-rgPyh=^bQDiSqBw2<HHYNr^*myzU+wGFx{*@0p<=6wA`Ik^cHkK1htwaCto
zLK3&}!kH&tGwm|vVcLXeSJzRvB%+6ezin2q)n!Vn#-b{VQcy`1T^?fX`}S8~dvo;s
z+b)?8FHW^N-ws#>?$*{en!aRrJx!f>TUnO?Qm0jq;KZqaF!Pm!wCo&7?CjPYRI4OJ
z4`YIeQB-U?EnTc~JWE{#>XZ={k*E0B*A8_D8{@v7?o3lT{Dl2$kf at 9O^rMh(;^`?I
zcicJqiQ$Y4KS4V1ySP-FOnK40P_ryEHZT1(rp{kSdvzgg!|ho#Rr@#nuo at z&er;Ap
zjGpO}@E<fT_PCj%v9qWERbUH?R`al1cvR{NmJ~n>`$w9L^JZWD8$3Q?(6w8z_ at -Uw
zaYO<G!;}>YG9{Uk!O3kcM6{&(J!8yRDydj$)(5 at N@uDdbGDHvNQ-kF5+2gh?p1d8=
zt;8uCYw+kd at hBy3tBeg(TnbVoD$~ct=K(LLr`hnJV?||!4@#GM#`a!^*=*|nX8}5n
zzFs(i5=O2 at ZX<u}VD#!b&SRp`j%EYyrCkTTDjC}YOb1ywh++LC at gZxqNuPM+_e$8f
z&l7e`*Nm;}O}nEf@%7$_Z?#dV%Ss9^qD;Vb`E9Q~{Ew?F$>@HXc(b7)SR}IUB9|AP
z(h07u6zvmcDkc{n$=*=PcCdlA;+bejX4?5m7kh_GKV|x;#7|%7nGVIB at zK`ybwAd%
zee_b#qr3&%b^)a84_6Hx|LT4#%{TsmR=dmJ?(}0QFn9OY0nFs?<nW%()3BE9Xi(oy
zL`X&6U{FxF0w6^CMv`wx`27~YVU at sRS??u%HJ&sl1eRsx0<t{9rg6`gnlSrn<$8Yw
zeRZ*0{lF1no9(ZP(=hiN;xCtHVaW*(AyH)m!<JQsARoQ+exm5C&TtL_&BGd}MHm15
ztGZKSk++f({XRMIR0`>ndBe)23a2c8xTptKN{MPxDx^ffA_kktciDC^gk-2r*>+#c
zZo`(Mvad(#4pfLnO7FFS>&cbs#EKU<ThIdc-zGpA`*P9RZoWX>V42lz71|J+s at onq
zuHtd9g~_a}KX_ at vll1O=K<#j`63QYai_ZHozskGT9Di}=%)VV8uAJLTqTuZgDs6+?
zWPa9O)z$IYQL%Eeq4NWy3yd8pcHO at _I9IP83;hz}TRJz+HNVY!|1a>C_Uc($Ca6=5
zfmUy83pCcmU)I*<%d(=C5~-3J>y)kyk2I at yw?%J$jG`{C&uj?*$WYGw6042E2L+?j
zkSyhCNlYurp%$ff<QEN^dy&TS#(bY^e#w{cS`9rYGb|;ENBrkp0v~a$3p|uq at U_3z
z<_u7HuBR-q-!?LdKgQ at Inhv-<mClnk#XV%p;|;8<ME~%v at x9DHqjsd9FIkq>CUD2w
z;I8N!5uJqu4_`uV6bMB4+9IfJ*x!~N!e{jg*F_(KX-#FM&284|z}*zdyj>sCL9YK1
zAA2zB_Wu#6h-^lQGYik-wz5qxG3I-$Bwg<HJ2eNe+5*RwcYRGe*njS=QCr2Ms&%<l
zqM%N2wYLv{h!ni}-sv2|pxZ`hFSM{9273V at cp!e7<SPo2eE(3c92sA-E0OgK$rfwH
zAWNlQADyc}aUiXa2td5<l>^Xw^7gsf%w`x6*`H{mSAiENnz}C+eW19DC}lezF6R3-
zB+8j0<S{Q>HsL8F+(0QM-gOpi+-$R=!4IcW{u&HE90kp!5z_LJFt+fY{t>MGt!r_(
z3Cy!xiHkL(yC}JGYLAO}3f)F!)7_#(ALx=)7&pL1NTS-yhc<!$r`K(g$%0Yg*0{h`
z9h$k4qoh$H>U7n+(&n^PT(0F-!Azo{9fv#Ry4TN>y+UZ|#Y~zQCs)fbC!8usD=7A-
zux&RI|7+GPIB<>*M8dBik>HL9L%n_O6rgKvZ>!2t?l!W2&UP<i!S?~LAvTqp#U1P6
zs2>;JSFPcO(H?j*KP5MK*0-NFvf#JU#wDZ`RzEtFCME`)OxRgU#(n*&BH7jcobY=L
z{SNL#(Yz^(`Svs5Nh7!2f+-qmSX=MoEK~PrA+>ent$1xIlTU7$yrHwVe}B?S;+s8L
zHY+W=tD*wO0H^roMuYXfKwt}hZA>QY>_n{c(C=44<q~J5sCROBzu|!mHMG?<@MuGk
z7^T<P*v%~_jrlIY=tCu;a?Jc7)YrHd9BOf>h-EXs3D&ckmR7NwL&pIj$M@{6P;Wva
zu`Z`xlG!CJ{_o*>h`c)|U70N{s}0`~owRlLd%cpxz0GaiJPRc!i%Hhr-Dsn%A(Dc?
zRdBSIW-~P=Y=kdsFf-kcP?@-cz)gJX^W3#*po8APLnxB$J)O2t=imj#rE|!WZewQ5
z%Jgrd<^!_gJqT1zH)uX|B0M6wcy4{I3Ae|^Vt5OSuS^#S*ne+vPo<cg+k%gVIkK0v
zLDj7My9je`tlVL})GXhCgpD^n+kHieLTuoMku-KUbpLt!Eq(ZU{C(3S!`j=ZJ(4%l
zxOG(ygrP4O(F1O#60$3<V6z8XCCKc)wT1d;@)7SEOC!Q)=U(I-_`w_`&d%<XQ{yap
zK5vYT#*<RVu+q_f$_l6d_4|kRPsP!f(s7hY%`R<o7Qmc*fXjB?G;1qa6SdEc_{jB}
zN0P#&&9lLPhj5_Vif-bpvSp71 at hIjD3jFunYi3A29NMErY%Q{iJQb~_Xe&B;XW3Y{
z44=5#Z(e!YmLngKm~}SNx+P}1Vjb)!?)(nn9Vr+|NHv3rl3)eje|;VMS^CtwYyo}H
z8pvL}2xcl{&d{066+2n4eU0v at KYxGQ;kNU&dGidm!@w0%vl&`D$KvMLeAl4o56yts
ziMKw{v*u4FLMfkLa&=2m3Oy~oSSXr`P^JcvE>WRLvxUSLq11<yC{h&$kN0>xpMXeW
z%hvPc^O%hGz?Vkd=yD%q7>(uO9?=<OL`fvIQEM05oSJjDwy#s+J?j_D(r@!^MpJUY
zi557EX7!MCwv&2p5G}0r0<1|FIm*pjSKe`s3cfzhwYTnZf`x at W%yw=yWtu#FbfUh%
z!S_u2Z!3ONI{UGBWctLj_;LXm<B*i25jJq&9THU8hxGz0X$wyo!!2X$Ww9hZ+MkrE
zroE&;U4B at uyfaI8lnXqgF;{Ejq2<GdIC~e9N3ZNO at FG=J#=ZA5r8riLjlD9xvIn`b
zM;=Z*XfsAHQeu_ZQzNYnx#T}D5#etVnB5n<%g^>e2;FQW at qScahCcIL?I~t-ioDbk
z6Xn4Fh7;b&cW#4G=l#gN-x65cUKiMW>aowYyT72fFyRu-IO<XD<Rsx$1Kn3{$>azr
z(9|z<;J4;ok24`cXka$T4#t7k at Ff5r@&jgQHaUgc`LKX<S(_j)S1 at 3T^q`3t)@z&h
zZ3xw|aEE(v$p#MYx$N&+=P{Jwi`-C|x8dzG0**XMP>gJyZ^PDny=zRXcYpbC at W37Y
zrvsSpF8Yv_FEoCz=s{BM?1{$qjSX&D=bp;CWmLeEi2Hv$r8AsWr-$EC5(d8Cq1Ji1
zM(_iP)a9x#*WJqsJX|p-JxV?-<BGr=NA`h2VJsJZC at 0oISk^v%VQ!psERgk~_fIZt
zoQEhT)wjsR7#DROGhUzhxcDjFkC%a`ZN!x%rp-e-Qs9- at b-wEQ*tc=v;uLvoWJJqI
zBu%cvZJtYHD9(|~T|+XekH(?ykof~-BK3%jP|}2F23PiF1-~S1Z~zBF*^@KCRnwwt
zJmZ-4bnMJ7<#GZ8T$7!*3NA at e04MHLr#u7iRn!rZszRg_q$!^qdSVI^?QLL2%QaJQ
zGC2x7;+96pTEu(}ZX`K_ah@(bH|)L;_Op4_Jlt%hXgK1f>3F}ub3e<Kku)JM5F$A>
zL`sY8B;zn2o+t-b{>+Wi<0deEMM*tm8^PwC#@GCtzOpS9Car9TU6{KnaZqG;N8C!(
z_olKHa>=c0w^4e1J)YGUdit*oyGstZA44a|ZNZ^?6_MGZt0r;9tC%c}L6p~dlPhgO
zn`={(nvso*blAJWTG<3|z)2j7VBHM7tu}Ij)-TSWl>*ggbki4$j3lzOHkO)W_;S2z
zt2RFtxFpo6Dq#`)zd(~nHx0x`NRvPR{+)XKZt5}$Yw=Lbc5B6_-B&vqSjV0rqQpIl
zoyg~`>Ds)yBv}i}w{0p!(f2PJ*LqdZ5)$+?m9G!p+7Ns`RQ&3-ZYZ5220AGaU~-n>
zN;X$8dPR3{-LHD-_ZrM`>w|Ggg+dN>os`$B$Ud6wSOM3y8lTQU{S-B8k5jm?y}LzT
zTaikp&}AeY?Nc#o;I$Y1e2k7xm)M-ttxwhION2kgrtvE(CPj=ty(?|~={9v<#jj|5
z5yfVo|7<^wOJ?Za(iSTFS?K)@c5uhPJ=Kazp4m^n1U!0m*mc9-h1bUScWV7(Kqlt#
zVs)9u-A=e}iQThvCHUq_+U|;EJM&!i9rVX=$TB{V?OqLAo=$iNLN+_rv3QhLNUSmo
z6C~Eaqr21oLG;1Nqa_s7MkIH+S8td6m_PC at Qw*4PS=REu??_{so&_S2B>g13bV_PL
zQ8~hC+U1v4c=7dZE=!5)`W}Fm25uh)XB23DTeXGNmR60|9&{|;8Kt5QNu(Q5e6Qv*
zt3utxk_u|+{@k`>5F))NfH0h;M3b7akMNlt*58XOkB!T at NbbDEEdTp!b1eK*A8l}<
zkimLce||g*4j}s6qvepu!Q!3|{;x+2k?EIfU8YkiSH0K7K#z&tO<aycI(Y8dP0fu5
z7LX(2H`u(q^LO!@k2E3&OrzBlS^2Oz(yUs{2ASTgS|DiB(vZDpLFd(`fsd_?&ZofH
ze>tPO+kij!)d$ZrbTby#$GN+2U<mjs>eia}LEJg!`ahX{@ZD9Icx^v>?}(;Xq60K+
z%)g<UKiiAFiN8Kx*#ZtvEn(py#Ln=$ytEGVzf;@UJ{@p^he;NV)f46x at 3h)vg%rV+
zm<4 at zbK}jTlDE#M*UXe-W8X?2r;iUbnjqmkCWZ%@t*lm<OkzUDW;=Wni5kN8Y=tPK
z^hPuA8CQ8bb9E3CEga}%`PyC1$vk>%6jng}p4tKc{*af;TT#^sH#T}l7<zG%GFkU%
zY{KTHelJ3o838>dB+YFkBE~MrNl<el&EsP4r6a^?vgC8&C>d)K*mOFi8r#S0;wa5(
zfPEWTL31M?;QfP-yy<n7pF7NOi7w<eU7D+0kf?v=Yty2*mobCaY`xCpVMKBIT73&c
zwfZ?dMN>hY0_~Zt9zT2tjX9j9upM6ePVv&L%c-U#_T=OCDVMpK#0quS>I8=uCM9J*
zk3_j~_^nR6>--%<t;g-fPE$KN^)}x$^^e81=<u#M&yb<>P8=Ymitnaest7_;8qsL+
zHE&y>;S*pR{po1NyTpf;_xXupNz}Nq!qS`Y#^l4F>t6E9_wc;!jU}<v$~1===i0;W
z5+M-3blUDYM(7%t7Mggu(wwnvpqMpeuI_*kKk$BVk$VKS-$mWs>DfN){~Pqx&UF}c
zx1nJE$_r==^MTO|p#;N1It`vB{e36wb7@%Yn-__1P!XzqLvQSl-)}5<jWzQt`ew6#
z`B~z~#dL6SB+toUfv<|+RD17_#^J~!*w$&}$JvVn=vXB+iWtw6^Yd-{X8Pj-!asX^
zHu0ai%zT*00TJS^khcwCKQbjr?UXLMv%j%-|LHY#6wnv9GZ*qG4vjvCMEbef1|F(%
z8cbVp(XE6|sr({&T#U`)T!;JmrIT7rVuTvZZH^95$*-oqEWPB9d1F^)+uz%5u=im}
zSU9C7wo7aS5S7)ALTh?g(>}FTv+$KOZ**wZY*B4++Cw|dA_)@w%%L5NqBUGN2wdR_
zsYaXbkBXCqgzpg&+pM#~Iz7W&1Y(_(c{;y;lS247m%d~Kao}%!P{i&Kq at fJ8OR4{~
z)C%ZGMi>s&pFscy^5=`ith+IUb+WAb^*Uoi-dHpmyRu+-i at V3TG@$R>5}jHD_`+Dm
zw2pVDTV>HYQ!C#WR;tG`^HUAW#z`lC9Ow#C$=sP4c5&>yqZb#+h1UCMc^+r0${7$x
z907f(2Ye<2$mnZa)hMrXL)w!h?{Ndi1N~^M$2PTMg<zZ;;p#oGa#^%Lt1OvCIfHS@
z-@>ouNesqI4J6Fb-yJv#xl((r5!~%2<t7t!TqA{O0yeg)D5)JOYyF|dNACo8*B&LS
zCl2SZe at Qu$N0B6GNp_RUzu{#1%2wh1d?VHOlhc0(TcTR!itUP}m``CUH~*SKuf4ey
zb(L3vY~eFDuAv)Z+ZJFyR{N2DX}-^sezOC3A>S*+PnLc<8ili)Y#FQkai=tTy~xPd
zS-hjQ?_}m^iJPxIJ#+ps!)7Xq5c*yJC+(S1g1t&S8{V5US+gpKTCbTi2L{3<z at C^~
z;H9alBD2pwRp1fW_P~i-z?Tj(ZBNY*OBMP3=Ede^{0TD0n%15T391HLdERmI*n_St
z3>s=}Hr;DC>kJCq9-EOfl_>gIr`Bd<cmN{fi^(|bS7!*q?>B!9Jzd)a2hF2q{i+B-
zmaX`Hw#l65S at w})1QHv5DSKuqo}^ak+UahNNS;ze79<4T{2kt7(QWXw;?M$TvYG*s
z**Kxef=o7(@4=umB1fv5iz5%Uw4V-SnNEE_C<T&N&5C=%>zk~L#{5jL9mVv#7p3dR
zYgHdT+0Be5MS0Ze3*O>=n0V?f^vi0}*P3#Ru_HkH<$9Jzn3inkH%yk~lV_V>LWudF
zA#*G<1?bjHdfaA>Zbws1e(j%MUQI3E(#QH{YdGGY#_XJm6}-C|8v!2pj^0VoX=v5c
z&`pZ0+M~%GW7Zhp77P|bCE{W=iZvV?C`(k=d?rVXQ at oT#!5&V$4|+>src$h- at I~X?
z{1wH7LyOz(uRpxw4gJwu09uUiCQAb^mqf%e>K21VQ_4SOhJV$(PYU;5ZJG~txPMQ_
z)(GBcl0N+BXfl at H1xnT90e}!+B{Y7hB)hxcZ?aTodQERpmb8Uw;md at 5BX*R&13lY^
zm%6l60}0szqwx3q&kqrcP}PUk#vi<5_H)`|G#K{QocH%)t8Srj^B8+e3of}n*<C-a
zYtZVw3$YT4=GyuffT+RyFsWs4J~X0&yZj;%t-)1g=hPz1{;Ydg2R$Ez8*4r+K?;%5
zSo6c<m+Q}u*<y{;+h?- at +t}@X$2z{RHm_csjMz_|wS7tT()1~-DT=#?WHp>Yyk-j3
zuv25GlG0thm*x`$q(Hl}M|#(SueXBHSG#66{@>lDqjowNmgEdp4oI-^X*H=eXX?as
z7r@&ZnomEML0&Esy_dDPQhmRwgZwD?;lQ6xeg>Ur4O!na7X|tO{<;t at b`;B)bjQz<
zzWlZG%(J;=uStFWRu4f~yi4^tWS3uem4<q#+eG(cVzr3!+FDGkf_aBnW!g>3e{%sf
z^&OX8^0v6&=)P&)vXRO=PgLWR3G;;XkF%?y at T#vUH5^X+;-4-1HUwA2K+^TlZ^Zo5
zZ at zWfAEK=~*cyXyeIY9I)l4-8{)Q}%hGAKL#iaHPlswHQg10K!xZ)d;^Cr_vS}hoQ
zBZTK{P20%pY6DqH9_$AFrGw+qKMy=c=>V}@xvocy(;L+fJ9%G{Y?MV!lm5%GVk+CN
zHI~BW3A<R*GYMhn<LFACF7P|3oCRZ))CwO*YGUQiOo at 750<Vc_pi%+u$mqH0N3*=i
z-mcIY((X6}%7LkYj+rTFy(<t^Hdta{0q$%BXh}=&!w1RhcXXn+?tkx=<s+7f6l0Z(
z^fbw3u66xn75whmW2Ga}pGIq<<fB1F5H1jJB75R<hvaelBvrAp3EoHd?=)yNSXv7f
z8RPxw8i=McuxsCW!ni_fo;L;Bj+;>MzOrAoq<+Ev$=mY`L6}ghv!VMYV2|o02Gs2R
z;zBA3o$6WHdj at 2RUU9Uy1lG&S9wa8b#P$6{b at uO1@-#rWAOb^rWhhsmE9myvVZmU&
z!@U5DO?qXOYsIvdYJjBJSqRnROLiL<^Pb75aobHz`jN-uqp`pfy5zIVhj0}kOcd6l
z>Fdi2d_|i2?>PIZp^`s|s;@tNIDN1;Hw$vyH~9<Hp)D({%WPs%$ljl2ncSM`RZI at M
zB#uL4&(>yJYHIzV<|gC&FxCpun??Kt)@k&ss{W$g`~m=uqV6e5B&eY!@!rJmaV5V@
zr+9a(hh at yBSm5!h23=y~;0GWCUeVvFk%IYrVCpoqaNx#EMN*mkAM-aqd16>!>a)~f
zgN*-+1p}r&@q>@&@5sb?nZ3$a>YcM4UkFJ0wCg!-44p4Z&vtjI<Q#fH6>0kEU$ixi
zwtKsVr5QksAZZ;U7*H$L;Zu#Y5q-~E)V+3Do$lfd9hVj3_l_Qp(SJs=-47MBW$j6a
z(=qST5xiKmn|w+JRD15m>)jQ=lX30P>$f=OyrOot(R(}m1&yBG_yyiNiCzH;r0=}O
zmi1ROZ1}QMqQgaK%S=lD8s?fUUM`M+7$ZWaD2778D(`-%GrCVF*0LyZzsaRn?MnM#
zzt#$v$+ZG4Hd6mOh4}B~JRmfb1Y_cqT*?sT>#yLv>I0!wyl#*oYDf~|)}DmH9DqEN
z&Hz)UX?|YfLfk at JCTT7(W=l=;P0EFyHLK5fk+~?nDfz+r%5KuKd5&{kSmN^_t_7^d
zlQ=>1%s4REwEuMO at N>;;Gz&<gWO6dOz^<@7vnI{g*AIY<oCd}cYP+(@3hc0%rbOZ$
zQa-Q~up!}Zrmc}rrMN>$yl5slY*Bo<wVH*D>rvrKh#wKR=T72Y70 at qd{jg6B|CHI%
zUMyulES*4Tf#hP4S4XHyiT=lXGGe=eLhz?0N(vs1*x7M@)6Y&WM<9K5IHBe~(m&O7
zNp?MlO8+Y7R>Al6I{az_Y$xTFIKq5@$~ukM{1#g%h``DJ9NqpkDP;;Za%X1q)1R_F
zeMu>dLy|FASD`g8sA^{(U4NOo??<X#c#$avc2eFpv~Jc|&>NVtdGCW1Sjij=G;7tN
z^*fDEFtb8(aw1T`$+W=v(6_H$@=HRuZI&7430Jx4YT{M1hgIl1_*U+tIEoxv3phs-
zp>a?GfTa1l8N_y+=|cAuV)RK~4Rp=hol!<&coJQ82h%6pDdB^*oGqx1GMPTw7~py3
z5L6HJtV=xXv}T~{18ZZ68a`wJ;(|Lqo$BSdz{@L-@~TUv0gLl6?)RpPxOnxz`JMv)
zIJ#%$|3QI?E@$*O(qz$Z#ct*>e|gob`^)_DUpG@>npg(@w1<)wI(<LN4E`q6FtVQU
z$=pOVT)FT!1NeIh-R$6Heetgh^zPFZGv#i&2FvgdG-J<EJrmAXuQPh#$X&T5f*Q`G
zP|rx^kdl-SG#V@@+6z{jKo=CPef-rTaeaAp at 1Mea$g}{HBK(wZqPo{s>3~}b^PR~4
zp?CAGPVA<^{2hOV3`h0 at f495E8uwZ~>^2}YSpMcAV$gp9t>B>`e!;nwI>EX%$ib9?
z@(M=614s)g9iga5ahWDz^v_6S9S^H3nq#vnE9t%wG$hCa(-_GN5!$NX7$ozUFf04J
z&Zx)=v-x4Rib(M`1vBjidDHzF7m|znT)P<kLrUryS=5;ZX`J`rkXnN0mTbZ7;7rwE
z%i0V2C$#i4EBtruh^r4(s}qL0#Am8o$9;9}Qn42vlLx6~w#l1a9!%agJa;rejRxC^
z6QNVRZ^KsmqC8Z!YCrZ_z<V|ZDm**xIifOla^OXJ%5pkNPaJ3p1<?=vu_6QZ(-Eip
z<?;yi8Rru&FYLme$>Vn<uG-37UozI1+3+;nZJ|0R(+-waQ3-*wZ9mmg=%zKZAK^4w
zGw5!%+DN&aO$pSFvyUXWHVPia6I8YSQ%~aO2b}9C?Hdv!`>6XA#Fq8=(2CWl>;1)M
zaZ$u_>kvNx(3$;-L`I=$!#!kYV?AHHg|9t|d3XshTX?X*WWbFi1n6~my{~pKWEUf~
zNN1R8DNgY$cd%yN5B+_IFWQ6O_upe-#~BNouXHb49WX65<aR8kkIzb~z*>hBFbqy=
zmAFh$Rh>1@`mOkjmC`Te^lqqb at 5=&K0|+O)qpCWDxH5UmdZgq8vPwis<xPzF?o08|
zk78 at D&rH2l^FBsXV<y?{U`t$T8P}RoL-vQ1#XAN@<kzYy!Vub5+RyiqRdHE7lU`ZC
zloIGI4YufLn|6z)(s&q<tDPPLf*p)=u8!v`T&6-+1b3A);}ZAx+Qug{Mlb5=dwI<p
zJo%7iCWN`<Rr^`9;Tpj~Zg&)(KK#!huJmmizHZ3GTcTNv_7ixx9C>t>IN0GEK;2P^
z4}HYvxi+-11Fp-~clwoV7UZ{>95ToOH?yc4g>`*YAfGddZQlIQA=E1WoYyL}L>KHt
zCZ4cQI}Xbm!U2U+KX04RE+WAU<WW%2;Q;ewC;MigqoeIIalJ>ecMR^vb$=m%V$I^P
zgZW2400OYAbns(sKy1O4s%}@ucFW%UEAo!B9BqlFE<-3 at g0(Wbt`pDEek)g)P~S|i
z^thw`jZal^2&*8UicHtsyhXaQS>7aUr{K&3sUnWhYbB4zXN;$DTI!{FqKitjMj#UI
zYNUZPb-=xj>xz5G?)(TlEe^RiYQ(!~bZSrLuqB$^IarT_HhvKYNVFyshjq_zHSOp9
zRI1+v3z<GAg**<zI<7Ai7zzj;y_-=+p9JEtFPmdyUmybwU0QFD!l(E5^C`gWUI^}?
zIIUF=q_DG^RIT4oYUvw<Nz{<hj6GsqZPZ)j>?jAT=Ip7l=8}w+O7XT#`mi5w->ei+
zZu(aC1B>&)=Q+}(KcW at 6F9d=+<-GYd=-ip)0n+0}waVi4j9A5r7olnEWV<janIM*J
zmepy0o-E$`_1T^=wld0uIH8W!*`r$3yWI022pxCRks#FF=UfflTi|^AYrBE1h7D*Y
z-gmg?E9+~Lo(9`_@<QtmFg+kUuByNV=~ctoDi8)fa@)&R?(MjZhv1P`SnL+K*l8Mq
zG@*Oo-4!E^Ay|Vo+&MpzFI5i31M6w2(f+aP07O9aCEbQMxkeG(xKX+sak(}<-KRtR
z;}#!7cegV3cEY(VerzO5DJ)hdx~z-nble^xkfNp<eCV)jYv~7X&2ZXluOu>{(^PN6
zn#$a;9=*T4hcSe)^4mUfNd|COwH}<_HbC_D_py2 at 2;)<3u~c*t#23?36yIwGzK<a^
z%sI$fz|M6{;D(^se-WiWEGo;wf4x at 76bqKC75_gA@FH{oTH$+x)=`tm_?%W#={_ke
zZ1)Wo9{bj^F+svJ(LH~MrWx2wINI7AS_pO<bgl*Cb`JikUHGG_a$<BMBNFyp>hUsF
zAqpvfj)o!f%JsO=JmJW9z_RqbYTmx1aIeWt9eyvfZin~`AR%}c(NbTyWL!H=Ja at 1}
z35PW<l^q`Oe9TPowXGf~zcH6}J6Sr)5}pCE$X6w5PVY+>XW*~!<aEh8pK|-^Y06;J
zUU`-Y0poQ;+}zntKl=@A;`DdP&An*uQpM$c|6)59Xjxw?`MDv~qx_rxaO9{Q+eqH6
zuTe(0UOacLJF|{Df|^)dr*`n-r7pKg9<X>q6YLUkq#H66E;E|*fb}&8a(n|DyP=P=
z&c%3?y at e03gD{F0ZR8r(z8XUdqnvNIJ at U~ujp-KRB`?mY$d=VbE0%1Y6adwN+mL!q
z*0VGbPX28h at VNti4THh#0|GEIkLW_ez7pj7TxM7nXW)LpIBBo^AoDxlsX}jk%CMv0
zlTtu?KCJcG2?L6>$8LMsx^%ACC%*084~cu&4C!7givSkB5o~k}=C|iSdOv1(8_EQ$
z_X=(M<Jy at YXU>`Ekn&$#e9~QLV>IZKbMQ5!%HLY<kBVg at 5K))V7}{u=st0;1hl(rr
zG%R4}JHODr#gD$j$~%4)AWU#rKF)vyA-K~CvZlw7rkCpNZY4{>yDA&Y)}_)u>8R at _
zF*+FsmBAY}+XZM9UNQGBsZ&B7mm>|cmArkuCdlmY^60Dg=1C=$p8g|sjq20SKW&RB
zo`b{oGO8u?KWW=LMu9|Ir at uE7J4<@?zgX4pKgyECK5iu!^%8mNY<A(Ye7u-kHJS!8
zc4cQ~J5JV*=<CD}0RnQeJZ3;K8NTDwti0Hf!c;VP(NR6~lv(dzWaTaE!?AM!g?jLB
zPyJCuO18S8Q9+Lw1N5?GxLi#g{D9|OJ{QK~T<bVn>;>H}AF-u5G^i7x;xBz;Z!C5*
zo3DAY(ElatrC|3pAGmH<$p)pxFEy(Og0S~qJb?RD?=^o&S`K*^Xj8F3S5QSc_c?LX
z at 7}z{7>smE at Vq;Pw%Y9PRD6~5uU7y7%LOWDU=Rgg`8=**u<|+mgvULWgQH at Uj@fS(
zpr;3t5*%KV288rUdQ|uL{|H7|@oFrT-JjvhQb{H>>roHyliv-6 at a9gnXc9#yYxzBw
zE-71<^-Nyr(AqCmNfn at RU&eR-BQScM<6VFupPo+1SA}9Wr*4}29{#y0Cv#U1K{Yw!
z&ux;OO>g8SjV}31=Q<W1&*m%1w`F=pX=?Cr736587Pz1aj(&k?hSVH|u13;x=B!8u
z_SLS0+r*BBPPRE?daah at +U~x)31T0)klH@?;+#+UCeGxQx1KuRcWGNY6PS-jQanX?
zgWk><9O52a7a-c1AFh>M1t^pgZ at r}R3GB)b_2BqjTF at FEzP#KWAkA6+6%<7}{AqqA
zO(^N9H2jSylh<T(aB&E9x{%~e)k3CYeIPQ$;uF%>`gYk8Lh>Ut0J~hELYd-jx8XN;
zYq7)0XRh>ZdK5T60Xoe*5olahjGH=h;eE&=RxSB{{f&EW<QA8YTB{Fcj;`k+M9Ukx
z)m{2&Cj*Ke`s3p4%x6ON<04Q(tI58xabD6WS9qWr;)*fi+JXQvAVllTb68e*-%fIJ
zvba$fx*lHzv~E4PS1KqzGaG=zPSkhK8-44fO*(~{zKRh(l!}ela*XbyAPv`8XsDiJ
z>{L{k4#4c$x7V)l|IkM-ScjEnAP at U}YuAtix4`70m?S!W*Ojz4j!{?5E2XLX4+g9a
zFgA3kxXZHU)z!0LaPrZSCrjt(0S0K$!Un7tT2PU^=&<rX#qCxJQittaBGbb8Dqzz<
zG8r~<+D{<H1&m{{YD)+WQZtH{OVvYfXS!gR*+ro!`-#McHc_ at vEyZ=isFXays+IM)
z at 7VZl#AxL}Z{br`oV|7p_kd5UUgeleq|TQsq+@=^&5xL8&lLZto#C!G=*aF_c6EgC
zu}rYIhbshHrR}9Bwz|sbtes=b8$QCf+0Aty4U24+qg<C_%?dn{=e7=60Q&gxzPjPZ
zMc?hzdNteImEXTGKjdOL9g!SdgwFO>?&zRcMjgL%+b<4(aJxq!wi9E;L$fAK6fe;2
zh33s!6!9<uQyWriOG0<QLGO`-ln$oFzM)y>OPK2`KbqViBqm%IQ8O^hwNL(VTKE#f
zQq4 at g>%UXTc4O1osaQ at wH>e=M)aWLt7rCVmSI5%M9vpq4lIMNvk3If(5>pmRZrSUc
zH_Z<Vb<E$HKZ6T30>!5T)0hmJ0qD#PKKKUvL=kds#TrVwTKia&lJx59M&Z6XFM8j_
z<yfv|J11%M_EIw2Zd4!W$UiGGO%v|aX%_x|RZBhxw=(o#0YHdsWj}kq$X2oFGZc%z
zavIsgsg=yCfgq`)1X!90nMfs+`eXjcyR3aTTfis{(RdETfkTjpDEPi~WFS*Gh;av0
zO=V6X_63lmTUoxjZe~E26IaDKXwiAdVTgc{z*wd7 at d%)X<#*0b_I^$^DBU5mpqA1X
zK6v1Ju6UHs-zc4~cVKq at 6Eh-{VspLk8Vtp2M|<O__*BN_HIT29)FEunq#kNk?I!JW
z8u2 at _&r9vUcBy*t>xRXyI45rj%LId^&+z}C$4$SymAy=6kgkO73Rya2SAKh;tyOHO
z3+pLPW6$<0Tp!9`60TI&tMIKPJ~QMMyrHt7nL3lTz>8@%2hd8pePunq_nAw?%gIsc
zjZlZ9PUeZDRcCv#?HAvGAKm!nU0r7q9bfS2DL_Z#?q(GERtI%t(&>9hR=8u~g44UR
z%Xb(k-m35Yb}u9SA^ax)uzWJQrvl-6cHSn4DzJb_J3Y|<R7#QC_XN at Gb(_C>IIy17
z3OXuZ2w?}6Kjf$E0K`$cR$I$)!R$g$2D!h~9k{B*4{Z;f3qSo$twX&aTA>>(Bq(U!
zAn8WA#(S at 6%=w#%MsC`Z2iQ)7-y%El9AbwC>H@#%t=t{+1 at joENbL4TPTQqR7gr!o
zxU81H-<ThWK*XMM<}g(pq}__-p%_|~^`=oBDwLAj>9v7sPS>#dO0|&63Zv)lr!XK?
z-eJ(ZDeXO`P--;2cskM56*f4S+d?mte%LE}1;zc7yG%Z1^e9;)wz<h04GySB at T^Sq
zhbIIp*hg^8qd2H?=`v)Z(je)=a|Va%(~oNL{hLa;Rq;)ylnh*N46>-xX{EZ)(s_m(
z_omEm^kd{!93_2Db2-1wUT*(ebrDjSYJ##4%XA{exTEyDL;2UODH+p0Ljrn(e9|+M
z%{Q&*_B*svr+lq)fBIVWXefx|P7m(DsB}fC*_;>x6Ko*bALJAg+XL9Dk^EkAvKvAi
z(9(?T{AoQiu&gnK*KJh^S8LzF at 8^4M*DiZY@`^%1)|`F4H-Kd2flcl-RrOuKeH}&E
zeyeO~qRbRSG at Yy3F>R?d>7}yD%@Ue4xLy*P1sh=Ff^nxj3Trg|`eCrTM!MMW>O2xE
z+K3qXHRD at D)#H7CLuzVE!FNiEwwpL9QI_;BtvlXC;tk>l8##QC at w_R18x){-=_-r)
zRC31bvQYZT?XKt=cPEeiBC!iDD%p}|eulvf=snI!xOeY1sH$JgfXuk5L!|hU$6bVT
zS{%UvO=lo-XweLeJ9Q<H)d|FDfI>W#cFsuo_9PPA!);^wXoMBoS}@FFk5`2=^LtRw
z91*BX at QSEMsJCU1*!`E|*}}K6wy(k9aKJ87e%RYsDsOrI4Jb0{b${STMfw-c`Tjm>
zhq%Eb>Fyn?*C@$7qXt>J<1~2b7v!8}IKMShCsbA<#c8<Ow<2WRx=lDQFLFian<%&p
zJ5 at inEhZBJPdYNucFhg<xt5maKp at PnVyQnu!3ej!mO83@%npF at _pNkPrb0(y0HWHf
zVcenq=yMzWyDH(W6I%@zY^}U0jeKd^@>(A{hQLm?D|86rhLSfN?&Aqo7JQNZU$TRt
z>|MCXN{7G=Ct<&@SLJ99o;JLn^jzuS2@~v;$jMUSWxm1!I@`}r63E8`w2M1DuYhfL
zhaQ&f1D>jHcHuVf?P=29ve^))+&uM+{CW9K-3f|K?RVca7*A?SmdfZt!3eqys+VRZ
z$t$zfW-Dz!lDjg}mx1wt!bscgHuPO%#J#^msxJSvi2?BD2bZ~PuKO&KQT5X6^`$ba
ze?QDA4!T8eur`q1rf+cSEC<SHrt96de>mB_{`El@>t~6f_!$*bY16)f#XvO9t8ARl
zJaT~brKs4+of=Kf-wS-`HeL|pbgcf}yt@;oHf3Mn5_|Qs$G;2->tUKqG4Q+KQYB_{
zNg=Mu`QHvmttM at vIM_%>`X~Xy0oue0?!fi^x2in^x&B|iHxS^A{Y5S{!>pZOzjh8U
zY#4yDg+5=JwC$wQ=Fb`89&SxoXBHWWG+Am?nV->t_o~jjI-97S%f$l%`zq6fD%1C~
zBEwcC+UID??);NCIv`z$VR44M(mxu4De{lHh`on1UrSM at yE73Baxu(s(nfzK(4Qt;
zgJEc0(*sFRrbCcxEU&dVUp3O1 at jbIsb<|&p^uM#LI!&sziqG)?>a_Js+Wxfzv+=Wb
z|I8`%skM$EI}azP_klomTI3Raem&cHeM(WD$!7m1Cj)8w_b39&hCHhHDEdqXVwi$u
zrDB?zHgK{m%rePycM{|46wKyq2y!e|2nl$B-EMz!Oos~n$>W)l=RWh^L`G<~ah|iG
zBWfXSV1^xAhvs;-UAHOllsC)Z*07q+$2UV?6!MgdBVstpUVPJE_<j~U`7=4S^`&2b
zy1dHO3Y6N68bY>Rrdh*Z8NS$-1$Go9I(v>)3(wcx)F2uc^+uD at Nm)!5?#$C#1l($U
zDCNa1+wKwt6rdRQbjkkP>FskFa~pIa#}I;*C-rmxl$7f<+QK;u_(BN-JA(`MRR<5;
zT!m*jq1f5y&AnEAgE`MLjqJ3GieYn>WW|Z6w4V(oPXyLgiH!g9m at glfpsG<LXPf^{
zM4vsVA*`Pl2`ZYq>H{6eXHwjfl?OehXZ3^4x*`c8_NPhjS<=;_*xnY)#F9AaCLw at b
zm7m9l4AnV5vs!IdhJ<NVo%9-d7R-1ep?2z0rE4z31)oIeA_7v!_b(&c_gN*0;4HpP
zezt50IK3G-7w>RcaeX(JpOgPizJWG|H(qWXcAo{F at I87}68<&Y)r`Y1NM+x6o5!V`
z2nW12-(#%z`}NiaZ-e(vP|j`-vg}t(Fuw}n`M{;ZcO7&z_!8=TS4Oz!Sf9j9Vrwj<
z7PvvLd;#T%|6asaPiCX4-hF#2gI~Ji*8$$IKw!CO76VT)!^wmaZA)dg%v8Y7nzBmi
z-!yZwDk+X-u~kO01C37$-@`SkH*Gm((CQG}zu^17K<pdg580$-^-MV6*T3d9<cUhP
zh@(%kOruvBtH!&nQ+_X;pA*DYm0GrDbZ-Jt at Fj$d9xRWm=!EC1oAasg;`w8BgPsu@
zci~DsV$JOo9Zk~re)f)Y`>uv}`Shf<fJYzC)ev+stnskUchl&%aiNHpW$n-7%u<a+
zlH=vAGS7o8n#?%8aRZ*tIbVF{t&f%&Qi(2m$YImtS6A`@=BnORPjtNq60WGA5!w5?
z`3z59 at kdX{+mBbXf*BpvP7sQ2>1)2 at ju&%f#$mBTChaoN@!l{93exhXwh!Xs?b?<~
zqSPXQ;W|zkd8KpuXKS~H4;_pjbBR(hmZsfDx;lR`J3T55$YC5}E0C8If$8jHuJE`A
z1um=P>n&khbTKRByHd1tPT2Vlqqr at C_r)W3{N-jy`^hVoGb*FrzDlq^SL12|?@Y at s
z2R1hHo~Rq3pMQ-MUvu22YO9{wqB{;sWuyP at Xu;joa)(ZecJ_5M?90U^E%P#+cQDRL
z+Km25*>~M$d#0}k>0*kZ6MMFqclFGF-&}Rx;JjODyDclkm?|a0b~L#{{Mb|v;7_c(
z+Oy3Lnb}=UVAnx{7&cSK0kC~B*PD(fsEj)dz;s*;ELW#p1MczUU6g4_Q+0m1J!)l(
zmbZakAF&%b2@`HlSzy}*p1`PRU4hJ6Vn6XWyn{+IP96M1y~r8F!Mf;MBYOrou*Gjj
zU1V|!nO_47dxvtM-Ou*@_r**HE%CBA{%IuaBGuWbDWlAUVE>tuVv}ZD3%S}1{9OF0
zzfERUxdT_8wPU at k$aeerJEpe>?o0p^k~cKtF1cUL);=RJ><4n+P9LORLJa+ERUeT`
zJ``P*W!)PK%r^;G)gKP_|KW<-ZJb=YPIYQV3Z)xu_JK^6#5?r;s+@^-P;*~QuquU{
zQKu1a_ta-k7Q&-58gPvKO?6W;)m-xT%GNBU*SM~yC+rZYe|pMAJMXUw#B20orsM^z
zR`XY)VWo1No#3B&J2|gjNJbDWeXbTh=<UCSoY)mBkKkaPUFcgJ7Ei4jaluf+$`aqa
zI53h=^}Qwl5No1q?Mr2yuHBsP at -t7p&La>mU#Ft;bO=`|*fQ8sR7dqHtr_+BWA{l5
z-@~$q77;|h<J(TzICS%*cIfzw!!+3W;;;A(&|`^=WFZ+knz(j_MFk4c0ZBo at Lpx6Z
zm$Aft)1;6UMaqh5u7>X|)nn^g+~z~R*fZ~T at E}#@G6d4fCQRdVU|k$Iz6?2!JpxAI
z$IZang307HXql=P=mOX?sW(Ts!5E~>Av{1*MkPIn3Ak~snj!@ORh=*-<(u(qz=muK
zW7JJZ?7(FWdJ)6UBV@)~TCd-fJ%Ui|I7+$dIM`~JeEI3hB)@-c^gYeZ#aWk at M#^Rh
zSe6{hkN9JL?N62)>G4ZolADw8_#+9P9S5Gkb1$c7<ZCb7TS7mq+f$GAIh at M^e&7m`
zS7|byVB;uE8Hbb#^oxvJ8Vgg<u30csyQ;`sduZB_8nwH2RS)ZcPEf<(Uv&9-f-T72
z5mitlvzi7g8~V?_4sB!M=eT~;!oQ^N|B6Q20RGm}P>Uu{=!DKFuGtE`R6AZBNN4HH
zF19Fcj8L06`&_nA1JGozLgn8bg^WO}p=D1)vIZmTo3T5olx+|L^y0D=0lT0fL7{U$
zBa)!2Oeu9QG9fYe=a5$25^dm%D!G_@*&df1FWW-T2?o1<^|HCXDH}4^wodj~qDb)K
zN6G!r%{qihNHrP=*rim&tXs%)7n!bnt<)$6_po7C;M}?CAEpa+6DYll>p~rT+Ai9}
z*m$8$rd6jUhOxVSu9UtsQqhXT?Nm>#*`aP>8d at 9jdpNURYibu(TC(`S=I&zeTD}2a
zzuybH9TTCWDoYVug8OQA=>`&;SHS&x5lCtIvxVmVJ%%Qqiq}DrcT5d(<h1{jN++cK
zPHIO*Tur<O)J^^){gd35c>B5=KTBHJp$8SC9`B~%IokNeA<qOnL)iJCrt&zX!rF|Y
zwE*>GB_gxtXy_Xps4AGMHw9L!wn9|k8k{f#8BcjrXAm%wHsScXgLwGz^xxrw7i|i_
zj47!nuaMz#?a4{HzY*3*ikRvLBj5r6NgS%RU5*qlwBQEi2}GKNu_kg&mXa5?gyH7W
zNIP(uDv<)SeuGHK&lJpue`%$T>|}-I!xBALf;%@u0u<n#-=>WbmHCpYqxiEb=M-L7
z&6Ym-9!2L>t;OThcpciS1#z{Z>!ajOB>vxLIa>zMX`rd&U9LOaUm60;DYm^2L`N#Z
zLfu9J*;SU=5=DQR%C|kLv&9{^C-+}0>$I=Ky7uRz^fw~_^sFmSLB?45#lq!}q6D(~
zNGL1SZ>mbc>^Z2tXKptSe&y?fXXvq|H5gZd*n^EC*BEJyofE)J*F1b at ezV8p2Z`HU
ztZ|RCUq0^F!Jo?dFRP9_PR=CH%w*~eFK!9{3{~0tAh^YqB?0F!ta2F#i&F1yJ at O+i
z*Cdm+U3<>R%`afwn7qZ*P@!E{_D<GwO^>qB<tIJJa62p;0IZcAP>sPWPp-B<)xUmT
zY(v!@@1xNqDwbHmrc at lkNjkp9a21s7kz5qd<<;=y180$PbRz|olpZ{r*4<*EZ&vE4
zd9l8+^%AyYnSZaH980J8;pV3EYOz!HkGiVJ$#d*+*Xc$jFQxHXt?crhnSx;}zZLze
zH`d&;!jXi at KA*zFe1l;RcOb45&33@$)Fh{Q*UxLjK3d?oEBGm#zVPKb9j9RjDtpkw
z?9k5l+VodX1y)@I61A24{cFO<;at<sm^AtSooA$%04#FxPk<3kZh38D%5KQ~cj#Z>
z5sQ5Z9LC4(o87hTcQPf5S&pe&mDeNLy%|p}CXlE*KG<oi6;E4zvqJ8KRkhKoB{t~{
z(O;DVA&xpXd9u*(QIBiBpUO;ck0wRLP7b#38d9T0ADmsjc{-OVn)T4Nn#*9Y72drv
z^*Sr<sZ6B!5g`{UpzElCQnS+K5L9oC{R5=j#C_o=AObO9H{2uC#Uec`w&#>#r)v7D
zKC^r|_mo}x&kt!xHI1amrV<;D=D)wf^KRAw7|Sxi3}A12E!3XWy!y6q<`L#^6EP&H
zLGtyv3e-E-+Fy7OQ(<3VyJLjtTixddI!r}+EIaeo$GJgvwC2OvCl(3Ar6d;4N|))U
zL{m!DWtJqoQxEn(-}YGnPd6%-i at g|)<b4fWg=lyXbc|UP)g`1$`L>?r7{jqgy4q9Z
zjw%}7A{A-+QMA#TcBv8UR5F=TCN}!fgpAVCb^M3EnS6y7IHwDF-7{@<1Q at X#Pp?X>
zUz5IW&?b;fYpz$>&BQV_tWe at q=ve+AV$L2BFvR_ieL1x0MPTl8u$?xGJPq>$e_7wq
zQsrJp?fOQ>GswJ}^bPFRG`GV25|-hMf&0(6%~U7P|6IdG_^oQ`LVpV7I%mzZ;WZpi
zQaRtfou<Gnl;>D!+fdqz7YiXkM;lxwmrOJ(7w5n3O9%H at V@;d=#)p4~R;fx;t!0+@
zJ|0>Y`mNoh{WtVB#H7*IW=r27>nB(77JU;ZQ-w$)vH>W7{#W(Mlv<D4Xf>(dqOcg8
zU#IMZ^w73l?+xTpvboH;y2^Tt3IIq9M|^*$+Ym$Ti{~A>UqVG7<huuc{MR58^|R9;
zDmEmuC+=VjQDe=doIWM_+tX}NdU3(Y8JzQQM*rMKx<tN$Zr21M3fddN`cyw|>(n8=
zmpvLDSqnjSB5N)Nc=Y^j^nqDk at Fua%wa%lc%iQkH%z?z=Uk#;X^%x}&lZ-6!`5D`O
z={A8CTa=A$yVZ3cwXAojGF at 6xVvzGa8J!~&eIkyO`b&G<xG>nDPt6|{#wPS?BEN=W
zOEnAMdNhPLJ$>}Bso7WikWz~q^WZT+GvQ6^H*ncI%ZhKFVXo{SZj9kLsmMT*-vY>`
z4 at hLWt=|Os<Q~s344(tN?TKXb at K4Fv;c~(De$QtK#%qt<X1j|k%J~0+rFZ4yd%g6T
zRGf~;Bcgw>V)<V4Z-dinsi6KAbA6t|JE?*ml^%s_hO7uO_SRcX*_~D%vL(EC`lJ at E
zO=5-3_on3bs(ph=DSt$w1PX?hAV;AVk;9)R7Qata$i#9Lahw~*TSs;C&@N~RF!471
zMg6HyRvIe;L(gbbQCZ8Rd2U}a!>_(s+>%a^?<pHE;3*sztR2nLGUu{bP`gNiT6dRN
z9+AK`#C)F0QXe2Z^40rcmQ6pczJAzpbt9lw#uXA&WkOfAhNSf^T9_Ze-&6*5hKD?r
zjz64bOnSZ0n{)Xh*BX?cK4PXr at Cw-YbllJUth$NCwBdHA<Pt<k=l1Q}Q+vUSB1c=?
zR^yHCD+BtvS9JiUw26r at v8m~oXldE2I1)H`hN`F at m8nhATtgAZ?m>x`F5MN`nU`Jf
z5HSA`AKc~3ACn=*joTxsmS8$y883o=mgz626^a;}V~Fj{*X$yA#!uHEqff(#u~>K%
zSIh)x*xV(BRMntGWldYD(>lZQ1M>Eri at wL-b~UdX4hwd)fvfTI^j|`;QUh$5y{rQi
z&VOc~e@{$cuaqn7*aTMk?dzj4EbDYy7C%e=><lMa!M>d*th at sYvW_-C;Q0va7Y{C-
zxLhmc3M1id5sOgQRUd3z+3FtUrJ|uY9uegi%X)<Sk+}e^vw3tgkG$l+_n)*Wq>6RZ
zZjAlRH&XWwV4M0^gniyqnxh-wBFhhC{(mb_8wEa5zlIs})Cwr;-Tw|sq+mMyyZDz@
z4)J{NDKu8?dFJ>hE=#g_jMP-J+ylm3mc{o^fUK~nAZ43g+*g7o=N4z*2W?dyp!)lH
zcpNMUeAgnphm8V7MaUX>g{*1)7Z at blsm1OtKm<~4vmS{mnh;JrM>bBp>lLmIEL24B
zt?wT|<lIzd&)~hA51zf0QLq1p_r!jCfO$DEdNl7d=(=*y?qfzAY$T{dP#D-8u3RGa
zg8iLE?Zs*QA*lilNqLuZD+%VA##lp&_xfP`X{Mm0SbCYnB)`~se7cX>qjv!L&Q$M@
zWVp_R`aoVc=h`{%<Pd+^@ZYgvDiA*+Q-wexbd<<8_Nz8KmS(l8a>X?ptFFO0Zop^K
z<=ZIBdtcE#-rZhrd+v0$SEEmily$mriT&BDpn%xR#xRq*sx>R%j`aYOEKOO4zl8s}
z{^u<XsZoPb&0H-*#q?YpoNptfJ+K{{JwRndBB82VFwnc0;>hYBv<{nN3;GZ-R72s>
z2E45j92J#-O&f`pg4tv8^Mu*JnI(_7ec1Mq{7;D=HzYu!vHwHUS%x+F{(V?blu$up
zlp-JlVT6Em>3)iYAT at Fu(!vPo94Ij929Xv;x*N8EBBM*XySpd-+&;(gf6EIv4tDRp
zuIqb!KIaK+RM;q)fmT1hv1<5l#s9JZepYVYuBeTM;(cq5LC}c2 at sC~n!Z7@?pTQ8X
zoXaA4VqDD*ac`luX65fcL*M(b2!@N8MPuqaPvtw8M9n^KRTy1Mq%v%7JMJdf#Y!yG
zJD=r4Zyjyc2kO00TP4hM^_{PYlnv>ruHsXh7~WIf+;Z<&qjT&h`6WhDZ9RBUuWyt2
z)Oz(4Vt6S3w at Z>!JAG{Xa48%@Qnh^?>rhm`MJib4_S8!%SYBIC|CR;eC#d4l)%+f?
zQ{r~c^BT-5%8u&jqHq}J=$oqQD?gRC4FEC)`J<OpyA at RXV7`vbvFEO&V4d%V^Q=Yr
zNU&e7nH@#8iZ3!-IrK$auV!77V<Sz*154$2CuTuOsN={|$kRNQbmQ|4U%xm<;j9EV
zTs+>!oICY5XP?#BQe9-_a}C<>k)21byR#1SS`;QJRIz*l`+Uj`f*HVrh)AnlN<h#O
zCfrZeLlC}b^o9D(k!%93Ax}9}4L?bVg~V5xk^)1fZFHI0`H!N4=;jM~e43l(@l>jf
z(vyU6oN_uLTq6c7HsK7T-8`)C6J|An!j3}zRH)9~*gN+U<s}GNZP(2BdVg at f_(wWl
z{X``&L8MDw9;fF-5F~*0d4)gRlBgd;!ktRVKz at -=-EE<T{WP6!Rw_+}v~Y6wR9$93
zf{FREAXcw!8JR*#@Ms<J^(xrP%G>l>Qwldz<<VzJ+2<K*@2>uT3k at 77uDj^^al$}L
zbpQ;Nt&k8j|49A!aFSa-2fu at NkB3>g{6V7_MD09vQwA|!4=AtmHD(|u!5AYJp%*ZZ
z-ha5^E#w1{w;SJNE2NY>3$b)*vD-7AdSf at -ldJr7B1_l;ni|DCUEe7DclXOfxig==
z9N?Z_3{}Z at -&wl{Al;PVTdnBchRKpi>xem1uIYR)m0~?z7V2;_4z)L8O<7H|G<bIP
zcOi=U%yK<LCIcp(uv6;}mPK5BYq4Q<gTff<VtX{B<ioH;UEfDoyMQG9O-xar0XvQ0
z9M!<dansq(z8HInnJ}r1 at Crx-#B!5Yrd-c`G=NXpDdZ!i&>bhRT^K7PvTCQHY676~
zHfT at _wO;j(;sx7XVMbU`HIR^az&?C2!x`&yjX$Z%56|#M{OGXe!Sfp$#f7P6k$+w(
zRQ_(#*Euoph=-lW4h?@O?jY973Weu-oORaB8K%INN;SqJ1I#RB3cdS)Zua}gbC|n`
z3CwQYsY!RKm5TE~E>1Aui`g7)z{Q22ugMcN_Ug6?(Shg2o=aha_^E{i-^r>9qpb1i
z{2O)D*lRu#jEfrZ>ck7$7XpFOap`#p*+~7#rc?gF_#bezFGm>P9RK9kw|)#?k=OJR
zd(`9iRFuB$hQTsa8jT%eRB0>GRs%|#jys5qB)n{*_tN;6Qt2(j0RkB95L0s>WL8GA
zED$YWJ?>$SduQsLgz at TK72sUdhz!4<vh^YK#%|YE(vxX{W>1bjCn;Cn#J=sMy_FU^
zDQ^N at N=#>_!I$t$MP3Kq(C<;<PZ%v4 at hhO%$4Tx$Eu;!Mkg8?>Uyr#DK5_m(!K++v
zb+%%7A4Z80CGokw6-yP^^6nC at W!bcn1V31itLS_re02{gcn-Ar33yuO_nvsqAXOO+
zL<Jgl3Ec5pjp!JS|7__`;4*%Qr?l0)=Y`)&%2(R(Ioxd07I+3gc1tRQe5%u&lCNqV
z0+)s)9mg%SJ%HW`0%*8B_OwJ9bC|#XQ2;Z56T}Z}=H8|lRhJmbEQH)o4pW#KhkI6t
z5uAF{)MZSLtx5!R_|3(~K%&Ltp;TUV;bEP+6wt`76bT15b||7J|5L4j?5fkd!21+_
zd~0G#$XlL6$l;ye&oUkRK%R;8h5527?Z`!=vfq)&Ga{>k;iC0&9Soh(ct0tj{b(%k
zjX|c2p+K8H7vFy0^FO=g%1O8IJ+_j{LeX-$Vakc`ryFP}%R?O?3hy|$lBPMGFG9GY
zx5+eU1_r*lBIyh%vLFlveEQ1a8e!nCNLlI;OA9Xqt8lJcKA*XlLhm4aQV-d%9mY_*
zJ3lRImD54AY%SZ~fxeITa&6MGnrKl;On8!_+AwCVH#1fRnf}`tc8jGBsoj-E8BApC
z0T9(jN`q^WJGG<cLanZEjdNQ>+vcFHPhDO16XP$rVQ!Zf-i+C3Ij`Y3)ukf4yM?Ls
zR?mW?G=K-rP~L2&YOU%HHi3T!d2&IVF~$SV)#vTK+a*x43At&HJPrQ{2B3p_j{B|V
z#lN4N3%}2NAs?7uU9J8dUVt*L+ezJB-<?K$^-3tK{*o(PaR#`r=*)=;?mm>EiAv4s
zygzc%O8-tLdV|l;)>CVQbnD00V(6GzW$-)m2~xokj8d**mVwt)S>O8`;qDpk&<`|j
zc^j>cB%?!%d5IgZSqt2yk at wab3|L9Pfg^rOf0CSP?bP2Xn9$)RebpNETwlMeUTXU?
zG4|wOr6^%fNk<VSRP<A(0ex_JaTe6F*Fi8M_sky7C~I74eyO79trA>0xfhDF0 at 5kx
zQ&Ei<#}n6Y{RL*JLiu^iJj)W0mCIRCGYOu_l6CctTkAc1gQjYO%|P3Ne2cty#*fn=
z`Ae_~LyHsG0unZ6sn>JJoQdwfqNmKwzw9&yY|%0hGDyR5{r#E+n!8#7G9ymH*^ym(
zD!Nf at ueNRa!XiEgjy*5>ZJ1f_RLp%W-5kb|Fj`2f8xnMWpF`C2$&l2@&hH&lQxgD1
zQFE-vg92Y0AwyIBeX!O^ch49yruMiawqCT;@R3lC1=1HpR2{$j(0l9T@)Gp1z~&fG
zhTXDn5tVIxx&A{P>^s~!Zm-fmU^+g<c-l4ktFmlff1G_SeYi%YZeU({W3pk@{onbX
zrbN(L0S}u7@(DD4(iPy(h)9r=7b|(5&Qamc03p_+{RfS8VqZ(x{p2Ihm{v#TqG}=j
z4`D-S#WLK=7Ab9H={d(8pD8`aWVwn|zLA{vc%AgZmNiwHfVnMS9x2z2y3Pvs6<F
zU;lQL7RHCf5@?$_9N?4$mHz#;zW8XJZlJ-27Cv7_8Lfu>{E!|l#uh}g8k;|zGQdqH
zZpfOmGoe4GpWeKyZtK-EtjJV)rkl8zPTY at m9$%t|Ib_ePMKCaoZKj4@;~lH1mH1rJ
z7I5<B?3<jPuMWKOq|dvWIbSlQ%y4Zy;eo>p{Tq;o=O4<&k2h3xV!A&~=QAanRf~H;
zC>AEpv(9tz1&JN|!^M;3Rd==?nM^|qW{86SM40~-8q<wCHA?D&8ar8?rR^PyhgvLt
zqSE<Zd7QlJa3f~)3^p}lsbF8 at f8*}Yi<MRN0i}fRGVyvFhQEvDij-b>8&aoDRcuia
zu62<;d}|4N5r&<<H|aJ#bR6~Hf&wGS&{s=njoF+u%xxW}zrW&Ef7{elX++cWj;NZF
z_nK*(-jEr^&VJD5S3dJnr`$`kCNJJ(rk}r4Ya$cxp7ttSowMiUj(2*kK4$Q~_qs;Z
zLBcAe9YR~yaMz6jmN?#Qina`Fmt=UHDKOg>W4!}v23p~?F}XioRm#tth6-Y1#eyNB
zCX9O`EEA;T)`O9{7 at N`d{VCfTr37}m>vZGkBUvi&s;OkcU1QWh?}7^aJx~C+o^ttW
z<JWgi6~+pE)3i!-3HJcENlM`enT}kC$C7tdoGan`QBmxQiI$tPzY4rsR0v*)*0iPf
zg^>uv|9;^|7e%nEaZ|rM^t{JdWL6Opc%OyG^OSllzWh2iHeG!NQ!i+)>A*w$F=g?R
zYq-$)B?{NNc{%=6M3{!NvcG?0%|bJACg}-l2EK~1qn;S8t&(GqpX|9D_=2w`v*f=$
z8xwwU#^Hiy%em98cpZZqy4O0>Xr;a~sy<<CjFP3>$pa8xE8`Ufk$H7{hWvovz9=GX
z1ClwF*Cd+WGX0BtL;bgkJ`ha84qNqBIon~L4(BHDaLzZQH94}Pwd+iFel34Q)#O|5
z``J?3 at e58DN(R@>oF=WIs`$dNC5w>cGm7gCeX{uupc=Z(Kj(v-<>tuWc4#x5-$re7
z`@_1nU%l;Lmb-0r6-a=>C}S3YE6%yE%iUh0TMbB2O>noJztE<7N8rmz2}1a8uByL2
z?T=eS&)Az=durZaZ+yn!$7<RB&ThFy9r=VRYJEPj?cItG+FUo`Kb+q!t(^c>sD5!k
z2mxGyA~*y&fj=>tjW3Jmm4}U*?9IEm<m=d8p)t3I(XLebBbI4q4A4 at W<1wz8_3e7W
zWz$4hlR<zKm3eoi+fy5&8(4vAS)DBK5r2)%91LoHI~aLQ_1z3-sg+Ths}Q*-7r>tL
zb-V!F5YO0eDSqjGIp~~aZ*}hP_4q?sgLdeP;0!S(iq5z=9{Fn0nxlNr(z~0|cE)78
zkyS)eeb411E#b_IM;S~UP-HR0WtP68%GS6 at +imB$F`1Mg=;s#e&}Mxq;7w_GobF*T
zh7p~XT&ws~ehCF;pjM-3i-C8-D~VBE^Vvt}+QnJM^4#tZDAc{bS1W9E$JOgeDP21{
zKesC=%FNNdfm6LbUEq<1{Z8>)O@)y7ufK|W?X>_*0C#Y`hc`9iEZd66W+c*B<^~Q2
z3zmdzy1udFsC3_K@(~(EJSj%0SU1&1zZ%*Nltc~M$gYjq(Yj`*^HvvyY>tyN6%bbd
z!{eSw*>TdVUTAN!qNJF9y9+ at U6j|3-mUhUSHJId56c}}D!8K$2 at vvEIc68kwhH39^
zwPQK*@m7jepNHAec&sgMm+hd-?q1#H%Z=YF(ep`@Sh{Hjbpx(At76i6BKKyoN5y18
z)v!KnxGE}o!MpvJ(G7VeQGl$_<MF(Qs+qB$tkP^H;mWyk{mbeMAVdCbweb@<3)fb{
zYslVK9vZVabgELKORR(6qykSxGkR5HI+82L%4p)YM at J)HyuT@<sy9E&WRPcol>=jL
z{?U<o4R7kDG&3O3f{*W87|!zTp(I**;%G7k-{NFpK6I4*2S+EaF8rj7iA9uuxM3_Y
z%HIZWt3EhNTRcLaM%^-C3LnVdlGL9xY6Gal8p{2+Bgz(2i5B}3<)r>$H65@;qK-6y
zhLcNqfJ#ZyA90?oS%g+L*g<^Dw9?|$ADNaD3V+#4Nd>3VRgS(O!lFdl?E8nv-qJ8M
znQ<&+^;0!>!rrAm=#$g-HLin+>GB5##@a8ugdYR!pA3hrLjn$UX;oOF5vpp!GkG^p
zvGDW}#mN53X|u;3D=KV_c77?M%8emLwFj|7%7KwfiOqDYCpy_}HJ=H+ at B#-5$R at 9P
z+*KP^t at kf!yKWFC>B%XFeNyQMG<K<dR1)L__HkCJG_0K?KP8w#;UNH!RPL#LeApYn
zT5J<JNAF6wX7kP?Xktn{6LBx-@)1{ABcibSXBGL=nOYAs)T9pucu*F=`hyFdg4I0E
zWEU_fGmarFFLLbt(?-gc0{Y7qIu5A%JU=N$q8(B}arrMppcA+=<*mZ?%u3~*5z#i7
zZXs-d3jlN$8im>M32<E6h<E(5w)?y(lvCmXdNWM&!TgHBi_+eD8-P&ee8E*UsOE;+
zg;KoHYj?mH508JZ(#+iX_oM_grL~dgs4=d8vrZtUN(EYd)93p}5UpX8o%!3PpC$kx
zuxAJ}n4+Z5bO{Y#eA(8&68o;s8n3+fCB1T=WXb3b2dcf~CR}r?END3=Jlb1%V6JS$
z_hjvZV3N9z{qyofb~p#;*OXWKX<wXLJDeVJ(Tc~qA54U7l#cIhjZq11T-r#q<u_bg
ze~}vo+qcn&HG20ZfAX1Wh5l#jIKv~Q?K-GNqu_h~_x)InxOcP>78pADi1tggW6#69
zgo+|?5RSO{VpYS>tY9HE at ckK8)K>bidAEJ|Eu*z{LGrK;zw?EM)Mi`%SS9B>f-{0`
z|9B;E{m4a`gGhqjO%IA(<=a$pSla8b-+~+gJ*j-=u}6e>;?(6orMM4qUaeO!q`Y&&
z5>tyB+BYo8wn*ucXs4p=uYVk{!SyEwtE{~8GQgN(4+7q308ZV%e=im_XEN#HH1Zqd
z9&Oim4nkMQ8brnaDFHtwTH*{O1G?#QIMd!>TU}{T4Q&jo6`?%fBB)v#rLBlB;rkA7
zH$L=_#=lJfpf&Pbo at sfPicUG|!ADvKzM7aw;5PKIV^bVl<*89-Aj>PxUESYMe;cv|
zckewkXmFSEp5J3EnQ3rt!jV1 at pS4w4yQrjmlOJ@9NM(0l7KBwK&@>F@(TnUx`daQ{
z;UWM3QPx>WCsLADIlv(cni at Jk{$ljq-;h1js;l%K$r5^JFk{?i+V^BGmqSqJyR)g*
z9=4?is%EzfShMuUR@{5v(Up?bK92T9zSgn*s?T4e(`IttM6Pj|$03FcB+b3yFpWD=
zEF%8n(abU0iE41<3{P_(u>9pywy*eO84$bJB-LHeO=5dEenY65c<};vc!9zl5^Zoy
zs&?OMc$OYc<O=k#s-9gjq#0cHQHWMh)zxk!ST$ssN?2nR-#w_zm$q2EPhHHFt0Ix1
z0LcH^D)>f5er2uC&%$Ycr|1t-XbWVs8w5E$m`<2Ga#F5q>eOIsk5pG9ufc8-1mURG
zp1JCP_eW=80?0b;IW;`wK at 4o!Pzo0IQ?W4_D!ni9j)Kf!W$Zzk3RnF1`MF(unAFuH
z-{>ix1UH?FXethFgna^62d#QQ)?|Tej?k0poneXzL4<-tCY&@^n~aFJ5h5!)ehI%N
z$2<PtHY at hM{6xp*<vqAFLvnqy-l^tjI*CzkFy9NeSlqMMpOzl3p_T$$Jz{Tfd(j=*
zqM#`|{&c939sm&;hoSNGw2v`&uNB4Gh#(^qDWem=pDR<n_A|!eyGhXx4r5|)1!bsS
z?s!=3k7&iEMAsCMjZ;!cC{}RJk+a{uLZ)c7d;giP+<-^9ILY<`hAE-crm%Lv+0(+Q
zz;NQoo{u+QX0zGS0&BM_ at UToDuT?76_4+jkIOp2WUkG7-94(5lxk at Z~TUY^^g)$${
zauwqpEJDhY2g6A<{yS8O-`X(Yzk>`)^P%s$39vsD0!%L|4=(^pLQatPn72C9o|6=V
zuCQ(a6VHoxb$6%dsDv7&H<~^~9BhpJ&<{pB{W~qFa_ETGqO}W$9}kIg at b`)4k-sd{
zRj2|gyncgnqX)V-j at hK0QL`wLaX&zMYvH%oKaA>L4#>TIu#7pWFX8`iRIQ!cfgUjb
z<DmmAevV`0!OI5kQWT7-K4Io=X1e)fBN8jVtnEX1E6p;g{_;H$*!$~mY-h2)^f>kT
zWR<y3I~Lhs$A)ICzjogQ!6xk;P32#3U(*WC6iyeF-o5u#tK1DGxI>a)-`t3NM5J1%
zGn{pLcV72^)|1_)&3OAz^>64(+4o*6nhb`I8ciN}okh>bC)T8=T>)0$P`Ngc^u{s2
ztwzFEt8_;0RKB_MKi-KsbBnL-<4YxTQs;{|`rC{4HFoG>lSe8{B_V|x5il?|`4$RP
zuT55WvzO&jr=ug615vNx8EUR!Zw#aQ#b<&-`y~Jz%*WH8XPETM#fc;Nn}$a^I_&`6
zqGGYfd at tk8M>Q(Q@$Jse5fiWs_@*&8DxD&XNPE5Rws-_^%OhLQVnc8e-swE(qx-Mc
zQaPHeSTVPg?$1m3;?I4hLueUxGl?OTJL?bcBD8d*CR6msoe$}Z`}*h-h>Et>Ql&LU
zPrOW at P;;D*vKsL-!BIIjWKWz at BSf&^4T$;MrrNd-825>Ac>keFd$I;)V=PTc_lH#3
z98&M7q6}ajVB+3lLySNfnSgI)a~_P1>;JSd+^TTkD5w3U9{2frMQUTG*?aJS1jiI-
z>3J at 1OzvIc&{BeytRY~gb=nbc4y>YhqXr$#@NO;XMfOh9_cxa8IS-uJv5mI58nZZf
z885p*DVKapjFU at op_M(UcPbiEoOb0?pl>d=aEar3%lP87GxatzRHLb4lg|%1+#;SE
z<VC`tn%T|wX+U$$>0SKf<R6>om0{YqwCZk0*2%1b1;KaoV*XyJ)i-Yt`9UK1*RAXF
z-c$6(xfBT+(e)kNsk+_xz<*nVX97>T;jk!a11M?g>Y$@O^h;^d-y5o at x|%&-y+cR}
zDWglP{G04`l}BzWQ^BR4;@wRg!zKjDt3qHM6tSxf6=oc_6 at 7}HSGr?&a~SCQ=(V)|
z#@;7HpKdl~Y_d_E7_q&Y!S7)E!!L0$_$Ro8AMqP~gUxy7WVXFk<tfN(O$^eB8{qQx
zbGK((%ZEs~4E~<H at 41ItR1M9#Xne7_$yD<%cK+L?9yR6DdMilU9}!8 at 1$2yYDR*W;
zB2XVbo%lyv*p8xgQ9a($EE`WVtXmohN7P1G)fab)eA at SfQq=Uwp^<;yKsJ4R;99X^
z8eL>4uHn_x93 at X2Cq7L!&et8*S&vie;EzsN+D7CXa*t>`FT_U90MHx~`Kt11wU^_p
zkP_P<mu?Jdl!8~ny8p?5RYmZGjC|Xi*Wb!x&=;99;iR22a&TVsAGU9zBg}}G;&jVL
z*Z;iA-r=@Br9JdqrqI1-Z9DX6#h(Q7Gn3#S*PtdT;30GHjW5sxxQiN1gHjnj)^Qo`
zn)swQQ(|84?hvCZTV}w_RmM~$4+IJJUf8NLMfpGFi(CYtiGr6d-OQ{`r_ at C;Htx6+
z)wAqWv$%`xGP}01U>I7I+-av=w1#e6-VgY0_t6(Dh}Q22ntyz+1sezqDpvcj_m&mU
zKm-`xj9$BNaZ;d3-1*=1#cyf_pX;87#DuVsj8)#Q*Qtv`CJdxp;$!yZ&uu~i{Z0om
zkpJfPnZHeFw1v+0<u!t)VlL}%LcD8$V2K)}ttc>EgE~$mPTa&5Jke<}Y7M(;=wRf|
zYRdU{1(%oyO?yJ8W#J<9UD&VK<$M1?Ljf#Dgk0tC`aS~yFSW$02aZ-|QuVpz<Jbdl
z*d%i;_L0_h9!a-xvr)+%d^PgmRjrFAz>c-bUaYmy9)`Ub`(dk9eRorRoc|p-m1x`B
zReXM;;uIQX_i$TZ|4n#3H-uumfg;L*WG5b`Wq-EHk|&cV%4<L;K2s3#aUd5)YD;O8
zQ at EneH(dPv%n47Y!z+?mbuWwdO*iAz1|ns?J2^s{4AC}+$=SINC*WHG9FIYXQ`7(4
zrT-Ofjx7r1#Xhz-stuqeT;Mtf+_5VD;z&Vxvosq!()i4wV1w5+jEyu)cDe0kd3#!p
zS+9$cycaU3ZHM-_%_BPvxq&t8loKnDTIW+tWiTLwDhY6ZYjq?-6wPyzwl_855G<1n
z?sF=cw3^<7Xx<<BB{R8Q{=RG2`6LtyN->OoA>BUUYYNOXXDv7j7(>sWabTbx)z6Lr
z)G at er+bBgPQ96g_o1GzIcYnTAR-aCnVr&0(_?h^bZ7!k=9&>9>voqi*+$)MVI`b+<
z?dTzJfB0i{m2LgCV3tP1f^P$D^PX?oCu{L_u3qk=CaE<0k$6KX52}dh>kO7n9(so3
z=da=ncl>Yr$j}i?J^7mg1@=R8LcxfWsLz6&y7UjN%Z*9Q9UFra>{x(5VF-9Q!kIK>
zU>(%OIz`{LU%iJ4Z at N$rJh&C!Ss`<S6H_ExmP86u4n+a-bjrG>OtM&>;T^A6$9{{%
zvIS-8c`sJUq0)^;c at cG;;Y5z#IZGjx&&LZd;eg48zp3Ed2W at J|8ixk>1OlRCRjS0o
zGZaU8e`w0)22#kNo6`{-ice*5)F6Lu{pw#qWXkBrTcIR4I5+`s+gp5l2l||=vxqOb
z!>D6c#i<g)%xoMPhDr1|^9NeMbUh3|H3Wwmcj5<o8z*y at +D6GLRe4fPBAUHgAuIMP
z at Vk-k1^pTb{-n%K-$ByDYz*F$=|^2-vKqj|sT7FS6eSdGI_;OoeXUoHvT};!Oi=_%
z$*<&$tj=TqL(K1U-%aNQ+)G9+<DEa%F)f!<M?8F)u27tZ at 5{$eZ_zW)DiBgsDf*ym
z``XTcLI*`RJA+hDpX9sa#ZcvFGn?gr&I8pid%_JIhQzkisWP9Afk?L+4kPbWnZ#J$
zefytA-Y6u!%?P_)_Ev=N31yVlZRN(wge|0$7m?t#`eg<#@8yf6_;C`mt7Uf+fCnq5
zB&aYEWja=oy9cw$VZ&>YpLdICK8890vZKLEK5u~_%Q~102NL{@VnhAIl- at r4id-H^
zVymrep_M}`Mr|mRGCK0Kpla<P(MZtdzk3CCxd?w*&}ea*56?nKs=~<#$Wz=&VjAw#
zx-{hQNKbvHUsE^GG-oG`_hOnYG^w*z!}_JzGJy3n<6Fj+9dTE>HGKwD_xYq+SL%!w
z2&$Z$+~KUV8B(PsHNT+0WrM>whECi9zTEmFXq=V_bWId=rXa$$<=bSlOM}mcCVK_b
zn0oxbz>a|2UkPJZApi>pU<aF(c~uUg`J~wcM at tj4tAjnn`I8}$nn%3Hb)80cyIAN1
zL!3f>gAd4N>xDrd5g<7%lNNDk-a#f<g~nlTMkY+ at U5q<3Yw^7T1x6?^_#0_%WjA!6
z2pk~A-_6$0Q8NIZ=E*#=L(}m)T5d){8BDAk(jZ{>NEDi97v}*b;?FsyM6lurU)Pi7
zRG}cn?Lo00g?($DBdKp51NJ at RhuP6hIj<itedMJrOK0MqC{pYGnC4dJfcX^M33A^e
zGv6$E=D6kNkMn6M(D3BuC_LX+X9%2aK6*-GYg78gg+qR0wgH75I1*DpzM<L?z6cpk
z^`N?!GsECXSeF3KJWp8 at oQ+LDW}d(;SxZa7c4ki*#S-DV_5KVqU$+YGe^~$_<e?|!
za$(Gx`WL%Y+kyP{kH8YkiQ=v&V11hHbc at LXLQ%`tn#?;%=)0m{VQJnGo)4S;Ql1bu
z9Qla9Vrw3gbLUVQ|1M5FTnnT!#PhoSPIvZR3mX3V;q>?%=j~#FFEMXe)5LtDL5;Yb
zgmz};DH*X|JNPbU- at w&gV(!g*@88Je;q05`?nJR5cu!AdU*&A7x?CD``+>dh_sZ%}
zJI<uf#t*titOpG5w*^gRN4-lqj at Ww_qXfas>~yXjj0Mhpu4#NmuE){NzTjVcx8CD?
z=(q2|a(6)Uv at fsBiokn-2Ps}qRy5AYllSR-{a_+S!*!D-rtT|<bUxqpf+3P!cQ={O
zrSBic{ikP)@nQwUYW;8D_MYkM1T#E6?9`XfN<eUeh-?}oLU<>-xwppxxL*CZ`y*|a
z)aTdy!AdW6X*?h%_IpG-cU4UX-n5s=aywQn-MqB<RAshubiGd6K=pO?*#?=(K5oA&
zB_8qO*_CzjV#U~rVbT<Em}LQvDzL6ibg!A-jeUDd)7ri_+?Qh{eQ-hXid}dvOqrT(
zsiAZhwyon+^du?avD=m#-yGR|FYI}&`+Sm<v1 at j*hq>vTdsU|{u9h+eqj$6|O;;Sz
zjqz=?qA;vxQ at BLarEP6eG1IinW3RsJ<6pj|u-M3_j-dV7w0(LND9P%uDD82Rk2dTh
zpN1g4uEJA>c-zW01ux)#NadsQE{T+t at 9lVBg-H&7P20zwuKgFFNM467-W-uDFoH#&
zTX?c at V4Uinmh9JM|Cf`1ufTl_jk3Z+-#jj)ONd1;glI=>T_W$)EjdX)aIkZmapC5p
zm8*c>$9zr- at BBf2Tot?S^k5Om+_{A6Sc3OVt2d^d%OH$11CMAn<sfs|RN0j4;AXKj
zS<(Ie`SU#e3ArJxov{>0b#DA|sjQwgSsD?BxKpO(Xvgt=v)bpmCPUL~@np&0;fB&O
zqZqy0DC4#N%-C=?Zp%{y2>OEF?Oqj!%QUAW#z?p7HJKjkxw_7x|MvKog^3$)1V-0R
zp|psUp!RS~D2%A`YaPp;J-O%;;aLb5@@zu>?JzXFP3|mAE|~i389RqB#|v&8n2jus
zuNQDRd=f(*jxp-;FhYGJC0m!QCD~jyCoMP6KsU}<=h)?5hpp69WShc+T<d5dN9z?S
zm17(X9c8<@N24(X>?3c{@4R-9_WMsb0}FndGtL13AL?GqkNoh=dCNJ?Emj3%$z~NA
z_qugav!J1h?6Fm_wSDU^>v-k3mE(EoLI8@<!OnA{EC2JyVa?<d$0>k1*OHTEg~H}r
zy8dqJgqY8A6$8$I3c*FUHJuWzEYrPHqqfJo<@ZzHk5M(o`ap;_3^QDnBWPVhk at 8!L
z4KcNS+=O-FxmQS7aAGeNfl66Q3s_M$4`pOH#C08H51i;J%jq7X9}M%mFbuu^7I;lg
zn=*dJY^9#`R7)VP^L_g)k^nvDpi|@dNrk2J8orp9%hRq2X>Ia>ooH6J1Xjx7ZQLhb
z!wu{)I&OA4 at C~d?)e)O^(x5rQe$91RcYQjq&`Ley3&V8{UjT at LF{ZE5JYSf9Bsh{;
z#UMW<mvyV}hhWvTYTDYc+ZIRQUytmwi)<E<XTh^PJ(V(FhB+Ozjn`Ep9n`j`g<dd6
z`%IG&xysZ=%qzl}(JH=F=E~r2eEC!&^v6Jcvje?qthWx^xBMh+ip<>nA>K)?itdB$
zLj+T4--%rtg_O?8;Qe2sdLK6)6!UwO;+%4p4y~t5E*G%Ey?1W%=e#NVjwuJB5)W45
zwa99MOcf`I(AL+*uAg0>uD4B^BR5O3!y~WalPXU6=ALp?I&bS6Bq3T+Du)JbF72c3
z{RS|>X6SQW`S%tcX at 5t>CYyf?B7qOQ>C~~7c~Lr7y{i4MJhp*K9;+SXO2SClKVI at 8
z9TUFa)%j2h-BE=##}i7C%_bP8`;dtcTHv>jk$Uc(yOFrFxbDg7Hk`zcO;x$NU@=_`
zTx!*X!W0ilM+5S{eLum;N>17lZ(^4hpqp9>DNJ22?mnfW*c;p4Q&DxewvGRCgCdGD
zyIj%aCZep7 at LjCZ#n_<jkVx!0+~K>&&;N!k=**@!i|qYb52t$BH4dm-hJemzoOcY$
z&UEa at gy?sF^Y-IY^y9$NbWqE_oG1ibus`f-xk*c at 1}TPsN>u`&2q9j5v#kzD3jJ8L
zvz8UKUYu05L5#!5LLkm_NJ_7C<)5oosof@%J<oe;P0#<Ye?AC;Um4yU at EB;=M_Avi
zPe%gFm6eL`8)9@{^;<!wdH!fH?rakzawU{oKpt;3t=5zgm~Qa6Juhy<(}16ThfjyT
zj>fR@?Av6aXqmjXdN77UNI_}v6FkJu-?;sJzu)#o3Q9T?Bn{HJnvd{&vn5w~(g|h3
zx9ZIBr`w7&`dW2HiR&6G7KBd2aaE>?Ws{uS^PjQREsdMJ)xkz at gylRyNWnrsaHmjK
zT;G$O2e+<4ZZ!@ApUqaoUb^pN%RwKvt_lyy0^O>XguabZuC3hsPmjt4T!wd*tzWff
zc$Iw#4=YLdGRcvsk;j#D3#}Y$`t$-lcbo4`rBvWl`!8YPH3zD=y02VrPj%AYAvP}U
zX++6A`>@vx-7$CXLlPwi(_Aa9d5p9l0r`uEZB`Wl_3}?Qs><QFWN4ATrrY>ylQk1_
zF2+(3Hq_f>yZ<yXLTAHhvkx_ at 4m8;0>k$0obcNg?<#_c`nX)?at$aMwBB%rirf_K-
zRX+Jya!nEOll&WYWl5SoesMA{9Na}9b)UN#*#$G&>#C3XtN=V!`y|zSw1w)J95Hlw
zXXzJL;VqEC#Di*@*lYDx>Z>EjYg>EsF=s7kcV(KCEGdTQfQp;=&=>l%ZrRm+dtLmQ
z at UByq%w+na)H8AUVRLaNRX=AKNH5I>Z4Q at FvqifX?0<K;qGaIbd1HK&E+~QDcon#1
zu=8<o-*T at JE?01v8RdP0u*r$1q63-ga3b%%J*Nv at A2f?0+czJ%G0gcUeKR!5qm}CV
zXBpQd^f9{nr+}`)LGnSQ;B=ea-?f|!w$P5Fb|Yb~lv~9S5ez2XEfusXnO02&p%S4T
zwIzok_mEXSEz@>%`kw3{+!mGEgYG5zDuXIn6W4E?sq})>ZaaBE7wGfE&&GLWqQ=Hv
zxVMG9bvoeq(JgJ_Z<)qK-HO?MUFV=HHcavpYM|#q at LtujIEt*%#A4c@(HL(k&Ee$l
zJN-%J+@&}F0(c1tHvefE>dVlLX`AT$?=hgdkWcAMS46)n;`+ZGNTL;^Qbt~Qu~6kb
zU;@(uO*}D<Y@=OP{gS{K|NYVD5p`{n at qkU8rjRfsFG?r->4M;2Az(1 at tcjoe82vl?
zc(aMQxzhXN+Qi%W?;8H?m<M6BVWI5GQ(z0DT>7UNg^+t<KX=F+PtdhvjE2kP#$DJa
ziSh$6eu*ni=C at _Z)`lA*Rg~ROdLk%dZ4VI`M+NQHL}b*EpH0kM9zWrQzX=f>xolw4
z!hZ0w%;l_12kpP6j7`^k$;ThPR2Q6CbA954BKlOYH^Kj?%V1UVa;HM*UNA#u at H4)#
zMsu9|02$|EAN1wHvyecUn6)ljE96=mj6`dA0(eoT((v%eH!YvO@$Qhr!!d$M$tp4k
z2`Rngdh}8}bgXly;cR;dh{7VLH-^YIUzb>$zlWMUaon%A9y&;Hv9{- at H_a@Z0BHJr
z52mE8!{23od*bhN?c`-Iw|Fm$(AGsnB6#8=g0gNt)coqm?lIeuXZ=784+BD9C?0cd
z4L|q*|0$^{Q$^of*R$AhpWkB!h%;T2i#tcnSEQS7El567=fzWjbgd4);;lrA$$kSi
zfQLQ>xP<^hQYG1d07da$`At0c!c=QhCxgnnhxVe{A!Y(BsekE(FsS1T2D~+bf4 at Fw
znA%RQq~^~A5ivA8ZRBp^%RW`M4?jca&@V at BshZR-=`FLXd!+x$ssF8OZb}xAI at lgl
z_Q(4BD7UkfdQ6Detbjr&NFx&*n}@dLAAXI9jF`!(vTN*QU?|e|HCx~|#4PWoF*BgN
z^%$hn!ull9#yP?h0F=`Xx7%a8)$wuuO-Yug`@pmrb$?gnY?EtBbn+Kli&{){VBtRu
zai*mH%uNYzeYu>wG1aawj(3Z!TJ~k#vK-1CNVA$^v+OBy3%sf|qJ}Lgb_zy^myNsX
zr|83;!9Kk1*xZNl=Zbtw&HJQ at PYEsL7E46E-zko40ZF5(e?*=VV%E;apEC$G!f)i<
z-I$n_p9EU-$=Q_idqP(56E(75vA5$y5G_k=Arr;d*Y#_9MVOJXOC5_Wi|GuGh;zP~
z<_IlI;@G%KI)WqUNUJQMzSiyz58<a9H{gNlu6!zTun&OSa&Ceg(}aJp9{pVN411ME
zmt$fYrB{B?ogyJ*?z^CDRqZjCB+8bT<?Q&N9+&tw-&pB^VkQWANOezSnmkPV_Rq*%
z+NLeY&}wS&$b~pFjp1?<OdV+<hz;By-Yl)|fzmE5w!3Oj^vxS?$3M^*G0hNYq+S at R
z4>zV`#+ZSSRpx#tFTJiYJ7{SFdq_Ucm15C at e`19n945}0a at L|h^=tV;rp&yT1 at +Tp
zVGALBPw}&-cMFn-8?Zh_)fJ7UIB=@bHHdn-Ryh^5L^{QqCg1S<RnlwwGQ-QhWpeJH
zpculVxGvPU1$qr(E|{_2Y*SU9$LETiYeBi6#C)fhn=C#HD%3A}C0u at Xw)$Snv<u7&
zW&bwv#(yRFTREAy67+Hms2=L|Pd1i3JzA<*Nkj1$nJnY0?<XC_lu7O0mUi&11Z4FH
z_m5iR({mTTy=M~+jp*y1lelr2hVvDXE}gYe>rqa1P|+h=WgU#vPu}jym)lHA2CBdw
zIyaVI&u at mz_~e(bePT(cr|}m=y(+~k_%ZiF3<_YHYW9&)Cl;whCq{5}Q29aV&4sgo
zNgxR#{nHZ=Ri^)}Xl6hHPhl|D=WYG at q{jLN)-4i=X}7)QOxOQlOvabL?Xadgh11bM
zkYG9t`|UL2Syv=;VLCigsrle==!?Xf$egb4?tDUmqz4IkoMWusy~mlARTIts)%x$}
zo*kr_vdpS>1fr0ntPtk<h$ulB6MhvL;Ab>(>`3ia%xA>uS^C)4S2tlGmrd22m48q)
zSnx7^(P&Ql=6mAHh{UD7$9}e^Wr8z_&AU(*Jxnh8QBY6wZ~a1ezBxP-#T{<iq1XJ)
zbtXe%4nZ-SV5~dU(QF>luCnGX49Q}jG+9cqOLb9C<=$E}hWcO at Pw5cy!sv%X!c&au
zAha8g>qUdc7*6X{aKC35*ZXObyAV2(+EzTdz8$6}S<|P<jPi6)?U?rN(8o=ybw0AT
zTeS4F%=oo^JQf(ReWOmlfo20k!77A_9rG}lP8O+!#GyF)XO6p$r!mu=bk at Dzug<1B
zw@&NI#yzq-=Db#!P>DuWFVpMhPBG*W?irpzC42=S3WnMS;*pBxb1jef?v8>GI}+S`
zb*i-N8SzD3&%u at g0G%~-z=UGFi96q9uo<7!`mQ(kMgFWqh<KJ+idz_Y)aRk;TOq6O
zdB9S{=V?C;0P6RH0yT*Cc8BSNuJtTEW-lgwmsA$GqA3g?sW`IatTx_!SM{3<r!%vY
zG+TUp5z`0850V7M?~xIApqKFQHK+Hl8~)wgKe7Bw-PinsG4)2-%VY$UVl9!X?vo}u
zz1<_FeH*|6k at m+fiH{w#dykP<>8F~Pe{RZae%>N9PCBNpzneR(>)CWW4F at OOogj1B
z^mX;SW2$=SY|I;!&t=(OPvT=?i^qX(4pi{I<Jk6Y?fAz-ylD*4`A at 4RA2>WYp|%K(
zFa8s1-6C~MPjs)&vgr-?I8$7Q5T_eiyIy+aW*Fm~_E+McE(vDZZ_o<fXrr1J`FhZW
z_q{kJDKTDnQ5?{WI68qnh*S92#RyvVFB7+3m*3boG+49daW#!HqBeQrbgKKYzq8^6
zqN-s&ynIS^eA}t2jduL2LbO%!jW-56s<MmBGo at 8$KsrF8Y#I%02q;1{ViMfl`2LJ(
zNTG-k-PglDB2v`IA?hmG7@@I6>t1)Dwm$(8qmHizMHv^`<A?p9hnVEBOn)!Ja93>o
z2kX>nt(5wD?Gu^P%XGCzb1`XBGQDmsOMD)0s&-<H8>Y`x2+{<Xb at r=PbdCQrJS+Ck
z^nV))fSBSqBG9Q$FQrg#74Q}>5i)WWOYS3BAuR<<zlyo)zCHc*!4C9AVJtk}uSoX1
z!>OQty;+f|M2VFrAA&J<ek;|y|BT<<zgy~Jxblw-oC(N*j;N#uSCWqCqM`(71B{Y4
zOQL^S;0mL<)W09vYbASMbkJ+nrmNj8InPYUm#BHF>mG!y?(i{IJjm(o`VnAng&@tB
zY`t5)`>8?4Px8LGaewz?M^7G+g5Yuu8n7JjS}`+8)DVFSy at _m>9x$vDx at 9?H$?+^Q
z)0=|~;dhy%aIrS at PaP3T5+^Rab%BGvLwsEF(w7uV*Wqp5Ghuv|@~3m;u4xEHAE`DD
z>J_ at 7#1!_WN3b=$6;0Rma=(!AX9x1;E1Ch{x^Sb_)mr{)4?60LXIyfL`lG_5P^GqS
zAukd$;AC`@l#>m{?^WkCxpSevho5ROa9j`3xa&CMTE94}Po7Z9!ZfAlN>Y;NZ)PR+
zbc4~9WXjua>tDe3XGAo6zOoU?bd{Ka#2m2CP2Wn|pPFDUzlOZHjCIUpab?ykce=B9
z3^28=Ik>_V?FavbKq5kl<V73{0#VCz3-p8j((lHcYMQfxTB`%RTu)Ak!{}+jjIs?8
ziRsQiYl&s!osLv*Q>f*PA`*N4x=jP)oj}~V8bAM6{E96fg616=zlw)U)W)syG-oR0
z4<r#U;PRRzA|2K%gwODL2ndzElltNFV6<=Vc2a?i0GFd at sn`#HJv%F$C~u9;!XHX_
zZO)P|*@L*50k)@^h`iC^@5>+PScy2Ki^^OWW!Zr}38D~`U{Y)@T7L7}?hBcfZJFLl
z?oQP1M$&lT)8hX!cH%XCHD(Y|575V6jf9F&S+f(q<>4C=#-izMS6l8!Nt$cDEd=qh
zr8b~ldJ>5%pPg8i0kS?G&m4ngS0hLK-p$Rad{&^Vijl$7yrY_JxPoS(cR-+TBBzK<
zE15}}wJi5I at oO!Nz2Om)V!rZd%gr9-G-;$On9cb4yS-z#p7VaxYSy?atBd1Ifp8-Q
zDnxC;Fq7N#g5Tw}?Cn_HYQ8tYM%9oSmIKxL&rfD5ZT70zUhLKUlYZ<{3I8<Kh^lXO
zP2Q9&JUo2)`YtCI2fX%$g0Uww!%jG>K-kamZE<7(#R_<=js$so6(j<wfGj#vpE^AV
z+$FaPCa+aAXFI$T%S{PXUH%+9TIz49Wm at dFq&nFX^-as at Qp8xWU)hTzloMjpw>vRY
zu+>2XlH`t1Z}P38USu&szC*=}+s at X5#D&C=KhVHELz?1{l*Sh(yFRwbK2D)st(C!y
zegJG^oN_>wkd at +&Xh!Uwr4TtQgnI%)d#|~btDCboutM-{#zXioQhk6S+c7-p0q$Lb
z+7{}vjVZRa^!H>rZA0R)ig}lKK+>*zxGD@}B_<k*oduWC07vlAKvKV-(m8gZ_?W<b
zaPeR+cK-op2|-ar$1Jk~vfi at W`FkV-(KV7KZ(Kh+GJt$7^JPzGX83ZPZp0McYp?l3
zdL at 5Ifb)gms=B!@@}wiGIHSa;LaM2SE(ZaURx^kgdTuQcomf$`o1YBb`T;Op&x+;^
z6 at -wv`USa!tMlF~S(;Vst9bTmP2BWr)cWHL;osfUM_!x!0-2(&Q+xfCFF1?LPgIN@
zWF2XFCY^7QcbX;aj8+h*8QB`tz^r&^V?6}wNlvt#Ih55BKka4t1n9k5I-0g^j|~C^
zc6{aBQWtr557dM!(gcTeC%c*+4CAM>+B<eR5hXqKBwmotdSSO0xKzVk!h!e6)%ig$
z_493J<c#1vpOHR6<r%`^x={3`S-&Zxqlt5Gy%fL{8Tf{AQmWT2QzOvUX*PY|r1d3E
zxeN6 at p;PI80dBq(C;W at PqL@Qx=J`^QYZ%gZz)h)!e3HsE0N!g!f|q|%A6y`*b*&nE
zAJ<_YLGdk=H^OqMa1dAp?RaqPgENeG>v2z);)JG?F&!YsxpJ6y*-r+)jU+5rcbX-0
zGvTf~w_cA6?Dkd`5Tqb0#q at Ejb&iP&uPUfst76KPB+43JLbn{{ocxD8HLw0TdfOW!
z+lsoq3=a)D9mlAk;0Ix{JPk(V0<RRw`_g$+kWLIZ9*{h^u!OVQd<0Ovk9xS)jX?Mo
z4spE`qHA(l_X|Rl{rq;y)ZVFu$~qUYTL-!H4tDT#4#C-!&Y;Cj+^OQ!OOH-ZimZsK
zYIzv%V$BVf#SV at b92WJcvQV_b*D`VOM7=d)s7MXdrv3qgLZ%(fzr-lrdBW<XK3>hS
zB440nOUcz-2UR3`odkoDobD~kjC;C=TCc!eRq?uTR&Z;YQ-`whiS}imxZ-E3b at MmA
z757c<{2I~TuxYMFZh(1&iY&jY_=?|3W%+CCZ7Ke0bom2!W$*Ej_${}Y!u2ueMrRn-
z$}r`~&CrBl2SnVm5GnY$Q;a^dk;6+{se8ycw=mXy?JP*_9bGA~(cR|JdW*Vwu$*IK
z>7<XlHrW*!qTus)H)7%- at -WS5^)>1i>`MoWdQnKqBJQr&^LMZIn=)P}-*>Fatd7?7
zH4y&b8uz*LEomV(|I6``)*+E44Vll**r at b37D^eB at F-0p!ceRF{r5XiAe%;=D$wsH
zny*Cb*QSmgHC3MSeooI7SG;`?du}_E7r2nsL#5JY(ta%cF-4N;Lz<2Xmrj{lI)>uy
z%dgF58CwgjQ9 at 5X{Da({0{f8vTAx=GPDhNId0Jnh_kI;<Wo_<+zKHjDI<DK^TjnBr
z&v6Puf>Ta9f9T1{GRfSmyN#%GllgjaW)gMQ3w=JWmxhVu#0Iil9oaHczu4hMKRDk^
z$Of+6yvIF&StCR${qizd1mqW6<icf)GYZx~&5XPL5)!YYD$E{e(l<<ry(^>=_l-7+
z at -4*zs%NDl<wg--Qf%6(VHI_R#61nWKytDWqaTwM?>mq1PW?5qF|iMoCuA6`ZTg6e
z1NKCB*j)xi-V+_!7p&Jtph$zAizEqcl=rW<lQm9~(xMEnK%)@(Z_rpaY1ZD?qp72h
zZNKr?H0X*y{CwryZj-`ZE&lJleze at 35;QYo`91F0#b~MuK!<!7JaD#63{4vD=0y>|
z5S*;C-NE at y=Y){3VdfMCu<~?oXGVOz#BgU^m9rob;EAG`wx`&~6(1(O%pz}v$B^F%
z5i%|ivx8suHWk<m=lVZ(&p+ZHrlgh-`kXk7D2?- at dU)~&HCq7365+XlX{K&(0RLZu
z!Fe$=kHp&kE888|*W`f|8Kmr3&&d9Ew?OySqV`SKttkca)8MEox+QXcXI4lr0Sk7|
z&&qw?-YJ%vMUf|aF9C~#ZxzB;<DaZ<(6qR{dK<}@Ccj1AMb*q%*b9eOPLs;?U+wr^
zojqGuU-1254tu__k06iPu>>UQMkCo&S?+WpTD4=MWLbARX(`fJawYp;C>A=%Mh)BG
zsc!q5z98JimT=*2HSWvQ?C3O&W%UMDHJdFZhz-yt59`a)T2MqzMf)0m%g`!S-QAqg
z<E{~X^h)tEW;gFR6w`C_IabQ8pHf7+(gAomihxriH){Yy4l9x- at wR>U^%-oti&eJh
zT!VhCMdA)2;qfkmL;aH@@mlr>w+!&i_BdsU2y<~CMbBH><pxKuqW#3^mqNbaKQf)g
zMYUT6R800pa|}|>VXVe^KAv{TKY5J{Lp8MfreCIcGR$p$rCgZGQf<7GaE<6BHg^t;
z@~$&Nd^P-pn0C}#(+&j^e|7o-9n?|iKs^6QZatpk%`5eEUklVZuI~v320E~}LZ%0)
z{b;}<xw)@)0HkZ3o)8D7XK+7=tBXqX5MEo2{<Q3iEfF+^%)z|hz&_Z^YE>#a(nip2
zsdrXPnNNqjrm))p->A>BBa;@Kf$Rw91VTX!mVd4Y=Q*T?0A#rs#Fr?Y{k|um-IWDa
zq0PM8>Cmj+c;*&ixa3<U1boHQ4RZ^2E)9NfYZcx}b{MFeRR8ge_19Jk3`}<^Fyb_q
ze1ZEiBBvi74zc+tRM`;H+4P(-lrN~od)NPIeaTY=#sr`hQ_^q)O<yH^Ri;!p$9=oT
zgZ);k_pXVEwno3|i&)dR$gQlkFZ?IEb=q`vGDLye{UR#43ZqJjtw<q)g^(qhK^w=u
zc=g4nq^tPJ7nq*D?OxN{VKj`X)AR*w89)iHYZ6Cerc`#vC^p8Zayv!u8CE~KTJmfw
zGZ;|3BQ%2c^}O$9>?0I=QnN7Y?Ow at uD<|u9BMDYBVslBT)?xU`K$+_qlu7MDAAS;K
zR0y~BBPNB_?VzQevIaJ1m5>vF8n)QP(sG+$Yrl-ReKPpcty>WjT3Mp94D?BO^?Emo
zBS`91m281^E?tV4K=A_;eLu-`+B6`s7AR-G<kJa@;W6DS5*cY>^|KEuze120IfCO|
zWEM=v8Td-0qkpo*f8WXXQ0mS88@!io{#JNR`e%)h7xl)jV3%I)ikm*Bojj$Qw<;C)
z@}^E8g at w@{<~rC$0x;9xVV08a_(eR~?|IEKGWf at RBZ+<)2;5TM`BHg=6rdG&k8!6e
z(EjoRnnmgow`JvVHLDF_b9xTKH1KxKzb|=*`Ck?Q8&@-&?&@D)UN3 at mswn2v5X?KK
zW1RWJyCE*B=cyx^bKiIiXsFO}M7R|sSOJQilmAqfjOmh&?CWQz7 at OZkBnq&+MDUwC
zF3szG^O)1_45IJJOH5UJ^ye9<c0y8Xd1l!^PCf_mhZ5&*8#pYxN=)lpAE>eU+2n)I
z8P{|2@%xt}vsBv4LL2hyhAS=p6z5s|Q{4I%SCR14Sjq!^7`SHt+a7H`OkRb~iCr^v
z9wnET5|y at _5D<QjqmOs{wh#}DgHxtD%VuiK-n;s3r5Z`)Pn$E&+#3U!9XQW}J9^K_
zxRs~e^v|a4mI(-NCSAxmr(FB1@&i1rH|wH`Z2YKpxwf->20l!m)|`%^6$c}Pbt2z{
zr`OzFY2xq#rCE=}Yp!j8D|prHt~D;I<Jq}{4HuPJguWJeX6)ub<~E%w59}OE=xQE>
z98vc_>EKel<u2z at e+|gIea;hZ#B_LVdem``F;9=mH8KXuix{=p^4MfdZEq!8!(60d
z?rmEW$3(55*!Q<&Ow{kZR!a2XC#gdJIk-up)%Hy3+f8hG5_shJ$}@ZMXRv_y*PR=6
z=tr+wshXGl$qJ*DX9yLddiQty%YO5^*qXS{A0330T|+)(=4n>$F817GLCPP*lwnc*
zOM|mO^bqZ;W?ns4?UXB)a7bkUt(T2jVyr3=d_$FqnDT6Dl+%WW2X6fzP3Pgx*8l$h
zzO`DURa<McsJ)_Qts<?eSu3{Kd&j0|OKO!`p*FQgY+|pXh`qO>u}RI?{hfY(*Y^+L
zy28mh=XKxD=i||5lfdD?u{i9#n)7|WzXM|o6zvKBq#*ph&Yq1pj(<+B5L(>Or3lDu
z(Q76wYisMWV214Ene*y?Jp4q&b at x}Y2f=&A`#cik$IU{}gEpxdC|mVMENfX`8z&Jq
zJ}JK7x~o`g*42Hrijt9>FC!Vt<MpubIgGjBglWO2T9wP{Mt79&EM7GLq+X!N18OBn
z5EY^wU7aw4>dMO#J;Z%U4XzP8z7MDHJ~uEXc-(!PP*508ZNM(mYeNa=lriwhb3pqZ
zB!Nv}|60b(GJ>$auU;k%b<0#jJm<4M6 at Q;d+5h}{-GP~AE~hSWZn~w5wqjHXVD=(R
z%(Cw+ph3 at A5*t6UoYd(GOC%Fl)l at e6X6%p?*p|+1#*Y!I6ms4OWRsS at f46c^J3OcK
zt%p#t*3JD5pT6|d%V<Q?Rmh?~5p?s>F~ifkx=#8zTE=#MG#?Aks)3<2ShO;RQx9FR
zq5Gp1k1p$g{M=3CL>e%glXKp&Iak1ZJiocbnP_9E41h`(h*|piF=(`QX1_`x5gD<_
zZ-$64y7hd|OO~%w3g_Ts_os5Cfhhmq^P&FigkKNK$2O=M2J95dcXN%&Sb)*PO|JS!
z;*!e2^^cTEBtIi+s6X27ed0Mjm-~>wN=tHiG%O?I>X*QPBM^Maec8e|c6yysQFLaV
zZPv+c<1&Z<bL at GNqx}s(xok)dG`@V^Es^~Q@@heh&1vbuKK%m`Pra`N^{&H>UzAeH
zgPYW&{-v?N@>#?s at j(qxHj&QMv}R)n(GE3wq#PO}?B)jHv2h8g40(I+UGqeNK at -{2
zxD&Kc>*sH%NcNhZvUKyQnCgS7Kx>{4l at 8UaY->>rj27o?1Li-5_N$wzQe)G($ax$b
zIcrqjnxBu-aeyAvxM`A48E|KfHfdNw=s(<SWf%-Cv+wNFPgnVvSK%0UlMSrK`91_Y
zl>LXJ`yAQxe5tV4`r|^b`-6_P`k7<FchS#yd53Y^A-XQ?4c}W*>EIN9<V79b%~p13
zB)Sg~RNS8 at Z18R61Shk?{g5}Cm&GoP;NR_zgO$Khq71b$?Les`)+9i~!SD57I%H<l
zR;ckUo9HUTw1|)5e55|wr-Cwnt;%oOStq`+I}8 at VHcX`3l(n4&sy at g{(ev;%koqmS
zWYv6?tsJ0atLLzx_a52852l8SGtA=70QJL0OUS!dTneeHO#ZrlFx%CsIaEVtemuDz
z`VkpVOSt at 4jMwV@xFjun|1M2#x at EG@i;LzfNEv{oD-M{DYyHw?K%Y&wA32muyiwdY
zQ$&$jVpJ at U#&^ijP%fh(Kn|Wp7 at WDQQqm4>WuRZ#yMfW%L^1w>1r*ATFk<t_7Z2XE
z)#B#-mzo(=`*pTlIJ&%A_g;c at E41=sIwp-O9&H+RQMwf~r8zK%qXtEFE~43A?x!No
z%hLQeRN-asdq{p`cYTwIEx6212DWHf?(~LCaQ);aEOzx()J+`$2EOBV_`L2uZgrBP
znwX-I(JvFVTNxS|zNz;XNB1Z>E+Nu$hKK%M#lI4&gT5#zrAYD_YA|Hm&=iUCAkO{r
z6Ku*V&3~xX*DbCcK5WR~{tCz^#@$n6X)01+7_GguE^i|@sukUv)>F!L8E*f_C93OU
zG-7h1e=FUdJ+wsDHor<gMwx!~Zhjz!%XZkKk~GK&yR=?O%SeVx4y$I?;=fUvP7eia
zoYQU_EIBYg6H{c3H+mQOdPQsR{3XUt%RAkiV2KdJh~wAO%Qz at wZy1I(!y8*8TtuGO
zLte<&%!tB at WE-qA0W61!s7~rM4aRu>@L68baNie8eK1)8L8tBgIIn}7UMnN_mk*1F
z>UK7=pVY|>C0(mrjArWc-ucgfGjvT}lEopeu178stECV54jbMl8f0;*ZCAa&8$;qE
zXjd$`F0AY;n{7Ak;}-P*+V57%mym;BH~Rx$U~yArqfOfLpC>T*7D>3Df;dHcIVG-D
z<>>a^fZ}JnUU7!r8;wS&e;w*Ne4S>EVo9~I8%|((xMvq&>Q{HV7`*^qzH8N at +a{Bj
z*1a<yt1lDND7}NKAyI`h?h<S#w2TNh=wce&S;4HM>z_sh*G3Qf`3Zo7!3s$_7f`V7
zy%XPHDzK;DccbP3Ry<L@`Vl^|U&5wQMztFuWwfouz4A?Org;+&{co-(tnX?+^@M$7
zWpVvuU!9Fw at UoNRj4Obh_URJ+Jr(+<^1oE2{d4I1oy(L`G>}2y{9xu5r1)q)MktZK
z{I}ptg#$`kQQObpQMoG5Z~|djzY%-yl29v}X$XU&IIMqw9@<sv=D+{uTYvwqvrS;j
z>eQ>BXXb9s&pZQA3E0*+PY~Awzw|eJmZOq>zDy1ff8P#bPp2_k3#?$55eN~bOEW-&
zFOKUwIKlac`u{Y!><NKxUW+zBF^m52^DjvSN%4SY=1~R1<H-7{9-(Ki=f1m&2Y{>=
z!y{Y=7sco!y-mtILlH`qV=U#({?{Wl&jps%*)$x!Qs34KtBIOg6jMv(=elb7fr-kX
z5z=`F3G=F!gjOigT5Myv19i9*6%*$l;}H72VH+l!GyU~N8GnFtWD;q9>R#L<;2R=G
z#r~|u@!%@(FUpaTXZm`t{ZV^TWW`+%^C_O!QoV7rH&+`nGO`~g^wDb-OLuh^x!h3_
zNJ~*>nfWOFStW77eR_ogFX673#4o9Oxwdg}i{@Wd=h7gso={ZOI8)@m_Vts_2O&H_
zoPfZWaml!;(IMq_O2Q<nLHKv3FQstbIMnzl-SEWrkxOVzC0szbAjZ at 3$jctQuMO#g
zTfq@<ql4FaX at oWD+$;AZ2saZQv#ZitJjox%FU^HF>Bto=FALG4`*Zs+ZsNk3F9ZBs
z at ns_iD#R```Ed^Dm^Xbl81G#ilFBQC>YlzC5_^nVu)~LN%l0%4rM(oScR)0f1nU><
z<(4dpb at OD`n3rXCFdNWQ!VfMW8oa_f_kXPl)(o*j4RiN|If-H%)}#wq8{ZVNXMxZO
ze_%%t&TsM=oxF$ryZrMphW|y;SyLoMb^EV#uQrELsf|`U$g_lyA at 2ZT(JiyDm<B_i
z1S2(&BOVz>UH}z+SXariVx(C=yu`Sl49s>IlCcv- at EN=v#BevE#B{t+&nVD>w~n}m
zAr+Ikne5;4<mDL2v2$Fx&!WXek^Ta at TwBEGm9n_7AKci+8HuK{wgX=-I!d7IX953b
zcX2UIBwsJsO0xkgYES)9?+1?W=0u^!t?Ft^dA&^t$=V1ZOu{N3z_IItL83AS*@cKX
zzv&<w0$)X*;<>fZVs4#ZM$u8>2#Z2Q*$JNYsN_PU!14K(@<rVtNT!J)=_STe$~Nhl
z05(=PefzNHE!fcIwn at xgFIb>c at xS7#k6&p>#W(LJIR{ScCHYUzo`uL3&})Li{X;_A
z6=Eos{W1=l at Y&hJo;mmZ3J`E!2Qzw~oTszWOd!d0_)oYgMC>P72NlzZbH;PoG`Ne3
z2<EqsQcH2kl*QQ|wTsHP<rmEkCXF*t*Kv(|>cxrZ at K=j*L&zn<{Vi3!%Q87W)|c~x
zid75v8SJc&;aNgo^Rlsslz0%FSsUG$a0jn)dSuF*PM>Y4R=t}xuPB&pw2Uwn&^=g6
zuAOJFZux5~=rCTys at Z_&7szJedAK)M7MB(N)9Otl!=r4bj+{>&r7o}VT@;Z~c=9O(
zLz(6;_5?L%ezi<|T&0Bggb1GJ<Icu)6TIX%+}V4k)=tTg#gaJ}p6K)5%q>-T_Jd)e
z0)9gDp}{gDdh6czw%E(5vzl=M=C?~0EMOYX(P}={N`i*km>mFMjq9@;^XsPmnmE$h
zcOxokc!|}qgYVoi at Yzd&8D?R444shz>xk%CDS^atiYyx?-?gEjDCDWrvZ{ahe$0Dw
z#{^)|x58W(2waC&@4CHf0FlINc06d$1go`T%yKV{43BS;d5!tDJ5MDD_Ke#Inep$+
z*Yel?oBcc4X@)Q=33S0LqcvH2nXA_{HYv(;*>FA at F%&kp>C4NMXK6dbb!Sxi`d>x6
zLuC>2iun%CwLzE8nI<@`i at 3>uiZzHVydu(;h4;QZZ`L<>cyNC+U(GHZz5jp6N8g08
z8`+U|%iU_a;Rr>jV(K?9N#LJcUQ&MeF;xX;>$$kW_TE>#k$Lx27+R>scBk+`VaBQX
zTis4 at _)FEfZI<oJU)EYXCW1zcQHakcEytUcKN|BD%s<8-YeQx*4i6)L8~ZZt at vIo~
zsHW3pEEXVi`J}cr)wdxa6P~Z;l7;kly3_7GFeEkuGf|qd1tQfPm*3x9ozu5HoOIFo
ztef$(asFPpX1bC}qr-RzG<i4S)^$MqlLF}-)vVleueVV3ImNW3sbbdcTThMT%<ior
z-+#aq89p|qoMOLUtc8^uXUlr at p|6p6-K#V39GgT7sr`&puA5e!6S8fNtpJ`W=ki{i
zG~3)=n-W?ecegQ{Qqu1u=iaMkf`JXwsl1>gq{89-yUmKRGP-5Pwgw2`97wS=U1V6c
zc{nvCpd~+e(oD9xki7H6C`ZSv%OPur%AN3qp9=}IPbeBcg?siQUp0r#7$?o?&HbYA
zfw)z$)00Oo{p31~{pMLdYZ*yAY#xrlTdCG59&I-v4Xr9Its~qo=H!29sW{KmTvcpC
zn>Nm17Ad=u(tlj%GW8HO)F}KZ?nIi>Ysg=eZE*Ti2UmX7)W6D*T+6$gn7+n8rA~3F
zmko6eiTlgoM0y8 at DW_NOT5~9GY0!3?7ihux_->q7!38c2DXF^U3zvs;8R3px6bAq|
zK+E)pbv~h2<zW?@;`-Gp(Y)-uWMI^K6mpu%9k-cRqG$QCePDZmd$!@xJLs1Q5^p)b
zO at ISJ8l@i1CfDz&*Y=g5-jz at x)>HX+uke-|tI3Fl;?ILscB|DosL7uunIp}Hh;~&@
zteb~zQ!@#br^U7!r?C at yJ??3ZVa{%zWut^f=Q at A(9k&?vBONS|ocNq*k7&|o8-D2y
z{DNhOEf at _Ie%`Ae7N)w7lNsM=^8qd_&}O$2m|=XV&RQ20MaG&3!@@kXXBYWqUW`o}
znqre_W#*INyeNw3%l=4Tg;R)}iY;Fi&9oEk=x?K?nd)1utV##95Q^^HQ~{dT!SHVb
z;C+L#SGYyRg^b6bNbK*T586_3mJI|9o!UB6hM%_8T)T5Yo+$TLEd+nyHAH9MLp*@K
zL^UOXR=3$8Sp2#-<ehk|Mzci$jz>Dc%`(wHFG&ff^$3TZoy5+~ox^CwT|Gmm$CZba
zF2B1^RG&zeByt?e0 at b4<Nx9QYE`Y6 at 6<bW1<n)F+#!W=XiIgbY%K&Qe`qctL9dyp~
zgcxC5{sQ-$kE{%0GyHp9M%m}@Ar|w4b(px~iA;dWTGSuc$S(LTLSJoMO+$9>dEB`t
zTDQ|@I6>=Oq(8Fdx8Mt_iZc`8A&IVXUT<$7ZvfbxeWF&aGwH~TD4E+nz6yOB=tGuw
zm{IhhcB^@$=K36t;frx-7A`Vy*1 at M8sQve4$Y|&N;w!^2UdvIgLaly;aL>nsftfQ~
z$j-UbvaQU@@8PRXyF{`*r#tgm^Ubq&Td&f!ZneuaZbNU#e@@BCmG<bgEf+WKSIn3X
zR!M9sOTd4_$le152Fxd3(yGi*?6`k>NYz2s=Op&w>l-DZIWtd{D at XG+YY~lEJLK>_
zw*H?~9ZvoUo-krORM$%TP&1u3&lFp_8RmEoDrR#~%TBWsZkBBUuSj>N+(ec+SC^Dp
zF}o*=N_gq4sPty5&0O<U{@C+n{=$Q4f#;h?8XM-J_zu%_#A{>j=*K)an`Bb6jUdZX
zu`LhL{_lPRlzj~qg;NcBMmgl^UngEM7SV*08lOL}({iB&pe$>7krM>I-SWFN`b50e
zEnN9C7AvYWU(Bb{MNi&c<}W|IYmqd3R>@wYly3qrKGde_jamEtrR<Kn;xw(Cc3H4$
z9^yY`*^|RVxRcY>^;EuPw_^HLPKHd8UeGeehjPyRx_ELnjf}#slv<*W%q~@Jo}rMK
zW5bzxe#*ZH(yg~U(M~YeB^#Z7BM&6kc2QsUMW030c78}F+CqMR6x01l2EAn=SgO|!
z2%p777<8Ck5!F^2wf^R=B97OPQ_OhlU9iAA_$ECX*SgbUPc!#Y$Br8?)=4o=O+)0m
z!oAOm6Mernl>4137r9uq at EsZeS*cXl2p|1!16501M(yZ77Y3;9V#*lov3?;h-p<Uo
z_)#71(>s)G=>Ex##ea^ZOmJELL>oUY+G3`%nOK<X&B9fF^X%u8ULv!<5K at 2G`Ka95
zV9+N916KPJvuAa+s9V*~$MN8Mo9CEv?J#ZDpX}&{?%OtR9$fr!Wh|ZCz!8wMFclew
zdWltsRCLp%CfGsH)`tB$r)|o`tTmFz8AwmA0*8|{JY-RPRKH<Nw;a}T at l)pJ;7{B1
zd^@=zVgfSHPf%>(R6B_3-^o(SA8*F7&|RQU?ipZ-!RVXTB$tdw at PaY@>CCrbBk~u{
zdv)Vh%vz>@2#RH$t85i4S{_i{-o(w<E=RYwqWQs*ki5*K`eunu3O#C2jQd)vp4~Qp
zd>k#UhlhuFWoYSbs{qB*5B$&PoCnoP5 at 5WtAbs8^dO+~qEK*We^vzfnEvy1wM5r(Q
zJn`)&>sam}sgqk4zj at LRrO9&3f}2-yWl7(R4qE$-;KV8^2L5@^c|3NXV7C5ee}Op0
z&R|>Y1p_nccQQ=!7%e<yXuVPAS=$LIy{CBWZIX>rfo3UqNCq;YwoWY)2-r5!Hn+Bt
z2HgCkAO6xxttmRwA-8STzum<5D>%QlKuIcXrpC)F)5(Y^(`dMSKby}L*w*iNd)mHB
z9pJIgp;fwKUEE^3yh~Z9ZlKk7+9Lj;tz2+Qjd2R6BK|)1KUGKm)dSD3z;#IY6dlV`
zFzjQK{aq|!8yfhR+FGODs$flZ!(XOjU&-33UL<O}l<?ycaRu3WME*WGeF^&-=IO=1
zS=tN1osRJ({Tuc3uUa~6QPYqP0IRhD;IhPf&HUNU(lSih*J#aiyA1jcqwZZ_x-7Q_
zoLwO^hIr&3W~P7YpN2hgib7^6?2r~%WeZAF?**)6h~!=Hi}q1_Zq3r at a3qcQL_CqA
z`MY=!@Hwr;+-^rFJJ%)AHv7=ty-NPcjHUOjgI_{x6Yas)8v)^;qu(&1Bv!fqB-9ku
zxQn}qB?hv0Pbr^23vb~bzgd(h^skhRqlL5bpX+}(T}^VRSh~|`dOCY~1ys%2JRT>&
zYJM~rtf2M?ziLAC6o;W9JD0VhtE`C6=f<@0&at_FV_;l&-$%;EyHTbhXKUvfpEu$v
z;-yx|_ERzMx<*lJ%I6Aux8nnzXT*(56iVvAf?r6|We_Vy^IW!!eKEcT`EYSXawqad
z9~y=F*aPZvFW}0(>@Vu}>Q5;wb@`+<jQwp~Y?;A at A0))iWSTfM9rX7oUVh)GrLT$0
zR0~Tt;Qg9I+zTPa_VQj8 at n_}sLKOjo at zbZjsHs053aBtNG9+P`p3eqY+=EUEW-|eu
zl>hi+VQ0w7xm at LVLo?6))S>2n{Z88ufu<?;+&v5v$-kB97QudNz3XCs5&uGV+g2-#
zRJD5|Z>V9UdTNQlH!3^nkr73fUG73C25&aG%lk!#uUv0d$Y at D5aCsH_IS77NS8;^P
z#@m)`=f=7cMmfj!gh!eWr(L+$nR$E+RB5<E{}e;l$H1 at 06;e}0(}A*umF?Hw+p+GO
z-X%mHN^?y!MZsha1r&Ri*n!%8>>c(5(Fud)NYM66>cMB`Rs|HIivVTIE-{L>U<c?Y
zCezHZKLo&(l<B8$9L6_5j7J%Id9tx;G!k<}j--{=TVtdHdlv!236!StPE(;hTqTu0
z(BY|e at 0Aqpx)WdO<rW^*T11cur7eA++O!idP8$8v|Diy&Nckx965u*`oDmzLlLNa#
zjeVh^JbW=RzHjOs12xnSH&bwwq=P~S`YUk7aNT>eU7e(PA^h<YlIN=oY`Eg*Z47il
ztyPK6ItrOQmAW5r_+W)|w2|b`U at z7XA>qK?PtWbfY&{3xsNTP77D+hF+Ui*Avhp13
z=2w<5$^1rI+$=EN6HxFsM$Q!)villE)Wrtg6dynF9=zUNRs0TULGEa-7``-YB?WA1
zkM?J$-VgJqIaFV+1C40g6iVtQ at yKE5-Rb>d(R=)lRQ!7hptw8)!-eDO_eEW0sl;a%
zQu^;eD^OVA^xUyKR&7xMBLn9inVWZNJp(GF`mhwEd*E`aMIcE!QxS<rw_We80F1WM
z`Y;(B9A>wTIdX_>e`)eE=d!0Lcu5)ZValYJwCsTpy_lNz0x+i9 at lA+3QHi)eV}m=w
zwm))^e?oL=NSKSXfwi_n-t!B#8L5kVCp}H+^V2Lv8RNe+S7RlJ6pg_3E%(G=zWFyq
zesyG7*pIyLEUpnDSiOZEaIShM<cA|kvMc{I;9YFiG%(;VWJswE)gv~~D{&&_)rKO4
zTGT^ifkOGd?YLc}u=|ITxcH>0<*7!Cyxknevr7<V>mdie{{7GVWz6}}K(Df42crhL
zs38<-TvlLXFD`)j8+-XXVJttUYO&uB_>NZ1O>cm``<u^JZvm>{c*9v-WK}j<e3TJk
zkk?t|-)7N+(@&!<&_ at G#rWN^d&L2E`YC*c#2HFpPvpUhfI;Hp2{w`nmZib-D4e!1C
zR8-N(|FK)Hcr)LA_Qt51H`p at ws9P>Yuh8|kHSN7EJ$(x~%257kf at Lpn+ItN-qm7P)
zAht6g?0P6*Kpo*`_O{&nnS#PXZTAN)LNneAM1rfnX}Njo9}emSsm;#EyQbV<c|&aD
z*&_oUR{8uz=9NCHRDX!?CSiM_SVJ^%R-u>;<EHs2slnBb7A=lLJ(7*vfcVfDu#@Y%
z6y(PoLP7 at l6na=j+A?!dmn<(r7I!f7vL?lt5zXvRLknyt_DMt10gp#c at b;v~yWKei
zr%m3tClTjNz{DzU6C!@qpbiD?D&KDxnw-cI!nRfiH)w^6;C8${Bb}YlZ>vA%-y5O^
zr|e=-+u{h~^0Z?3AE2KK(20~<MG_^kMz<H0<rIe_<9vq~;_A}dPZwF8$`zt-<o=;t
zOa5W#Wk~|O_^9}!zW`zHXJvkqBy5hc=;rD;V~f4=wwsGFV`rzdH_49w02PP&I%Drs
zW9J#(`Zbyd(0eVp2efLD7OaWx)`>IOyi?0ecahG0T~o at nmI5-7pJVHNMthv1S@!h{
zr2+Gh^w$Rsh!>b2i*NprFwf{|Kuc>cfp_)WtCk4eDGvh~A#%2oxO(|C8 at 1N#Cm~JX
z^0wt+zHg}+lCf?k#u;V+pXO0}1i7MkMdfOO`@LJD&1t{NzKvp;eW(S~lb77nWbw at c
zOIT}TpqRIY;tGkkmpM><t|j<1TA(c0Snj7((z?epVQFweWjrt1Z)T^)m_vE2E)|Mo
zDuK~zvs4&2h7A%5M?Kg}YnpAA5?i^S>KOW}bC#QTOBD4EkWLfv3H3q;Hfc>`wPSXD
zX$_|2N=GU`v_uH>*&35MvpnD7#+G`2ynIs__S+bg4ARtF)flrBbm1tuWni-yJoY3h
z$x3tmiSE=W2=b7z?Q(k~wPvfxjo7kR*?rduQp}Y{=z0b?({?nS(Kf2~d~wqq0je{O
z{62S2H)uxKtl0nda{x_0qtobgfA1Tkmmku-gUhr)R<4L!kB1#g0in%|`D9+*k1g+`
z!}%?Av6&prA}zIqs59>j8{Qt$6doGh*Z;XZw?KdvxRn+r<u-gfiSrx|OUF|LtLkAn
zW|Kv^3 at K+-r?A$1#{)wbUOng|{<Nc%jQJJE;>x=oCH%F0t%7K^9PL!YjL^a0mJI;u
z9l+MC^yo_~S=@DIdXaf0AspWXd(38~Mx8RFccyqeNu^o&0sE12p$h-aKQN$xhQK&5
z=diG?t=J0gahg$c1p9RJZ+Ewla~;4T0l=MpEnUpSXeDFblsDHPoITkc1^I*r at U0_0
zzE5bl4On at FQOh`A#8>>~ysyi{{SbYGQtCYbJIaL)e^7g}`hQt~U2RC~TKA8b$k_({
zYLD!blmLU at Tu)Y|9~q59-jKRK31&Z1ZEO0GUeBwbXW0QS5iT-jlZ}+6M=y3<41`e?
z#+DQ$In+kQlKh$)&W~5uwP at jt8Mk?3qyKy-S|`9PI`70vJ;jX at _-vTU%EJZzUu?^c
zx at z&F#yxwsg=MD9E8RF-=vxh1yv|89?cRIIC5K{`jzC|gq*83k6KbkYSU!~==V<l&
zs__ZGb~MS0S2n$@c%V0MCmI%3(y_<@APSiw2d7k<&S%PZ#5cx(sAmIoHS?0%;fx91
zr?b;49(}Gnxu(o+s?W;<p2fcFju-i1P at hkt<kc2{y9lVS>nus@{SCH^DSaEbPPgly
zG_g15h_(Xq6ZYW#2FxDCC6AX+14;kpelM)|J8rV}a>wNF#WpzT9E0(D!FED0V>h`k
z3D#}G00nVTo^w0hirjuh3xB`KKPtsjBbopSPdT7RGCq~f1{VR~UXAAWUZxuH%+AiC
zz5IRo%1blnQC=n!>eXjt?A3w|G`{eC8dx4xE5492btpmel6K+;*G at keJb;bst9{I5
zZ*F0B&}p4F7#hd#`{YpNbk;Z(kz{zMSj7P1*YTc>9eib%T_ssd2D9?^<KV|c#RXZG
z)}D`O>xoDz&eDd?1WYDZ`nplKLnx%RN*40;H`#MDyi<k!t*Mgr`VMU>8V9envncIT
zbkpo}{EA95!))>whSxhfeH?nlebFDB_sWI1_&W58T{}`n__-}sup-t2sq^Cjt*YCR
zac0i-X_CJ64hy at ixI^8Enc3Qg`Ya`7P>G>|Y^9CECkLkp-E;?ED;f!98;w$1{Nk3-
z8n)pN7qhI>qj+v=MU~<NGM(5iCT)d|t`5=-tMBY4vQK)I>`9m at GFVT2nwq>CbynXI
zvQ}a)cO#p;zO=kCot~Rv(+2%-@^G>t^Y@(oYr4bL#>`A*)qm5)z6aIDLw7p>NXiQ!
z6nghD<ySUOe?0>ZkdZW)KmGV5)~&dLjENbN;w at 37+u*?b5~WJUguK{wjgT`=I#jLG
z?NIEll^9QTy*Q6-qbA4=3sH;}Yyv1jLc4#|s1tvh2?ia=GJxh!N`4drn>1 at M+3kAc
zH}Tw{g(;xQKaJ&pnZ)H$CP(;#9#hI at oA6+{hksy(bCvmn|L}@S97-i{*2#)K*L#{w
z4Vj4ypzJ at b6);7j`N at g0%>YgnuSg;fe^tM+97*@LqzdjNZf(!Oa0GASBhEJNeZQ!5
zu-+n at MD>#Db+kijm#ag;?{g(0Tq_sMcbK?)CbQ($R<h^n_fJ{})A{i%G%4-errEBM
zmNyh*HdicW-l8C}djjXiPm>Xg;@1Fv<mUAr8 at +v56n@4puVx6ck+k7=9&V({2q5~>
zI0?)Ge|s3pRJW|1>>50MH2KHzj)?=BbicTME}_aD=I+53ax$Y|JsMfjYV-~Wd&Br}
z13h6=bOA}H(0EyT4g=o87hB0xBs+7w12YWmit{YUFIbS3@&1IB{UYO>&1{z_4jN;#
zvZ5Mc4+rD at S5nq_*7MWPdBDJ$rP;`*{__%OS|wRysr8^YsP!o8n>L|wW6vCfKwDOm
z*VIbrvO!6vuYLQ{^rsxO9HAgWL$goyTEV=MbpXoRaP^uYc5B;V^5#CIhD6PLEQzyz
zzsgH0#P3)tY2+icwy#RAc-fn~g2J0U7q#~fiJ4|ity!_XRNVM$%xvcxsDdciu*K*?
zf7IfciW0`L&M`(sGZDP;Sc)-K+da~qk{Cy<AJ3L#PG?+IlKsMta?be at 9n5P+EE#Q4
zl3Nhr;B{_L&e&HT6#LC{G3!BGSrlOzVu(H0e6HzCNA^|UA*NloE#`#Xb*^rKJJO-R
zE{VQ|tSD~O{B8Qt%XdcAMq#b*M!>_s+55V|W*tzcfhj9jk%Vrpg!1fDmQ!7p)G69u
z4Fc7P?RIj!wRZTgN^Ev6H$}#ht2u=pFZ073rfp^?;3l<+#zR4t&nnDsv9o(EUHV51
zm3}FsT*$Zv?q}1=?{&@f08a#WD&%lT$HRI!fh_YzhMq at Ml*;*evTjki-g1+>d9I6&
z4a}2k&GUITDQeLU+G6z7qB79JKNQdZrIrqLdWqVjlXQ^DuJLrp+4v0K3uv2Cc#%K&
z5!pxm(%Pbj#Yu9<Yba6-tH>S6KP^iX(=ZE{R<^xVkRg}$y0}r*UPw~=;Lv*#7?RN~
zY4~i~+#gV2(>0`E#ni%DLM12zGJk2ItZ0a?3*J=x;h^_(I~;h|%%OZb at BJ6pbUwYg
z-evpJeaJkxm!_0ZJwrxSHoL6%BH#Au<Suus?ya1Y_@@&YUM#E0_5oP3HlTQA<<t`D
zXwTzhy!HkF0ky-&PdLWznsSU71gGUEH;$WVR-`8Q%Jm6VrfAW at gVSVmU#hcZ?A<+q
zppTr!v;_2a4^r6m!%E-(+Qu6e8Xfin8!qj0ybjB7Y;)jKxVV8Nv-3q|>G5}HHRD}h
z7F0<PCd8vfn*yZwq&KgBlrXR8_u=c^nBs*z+8 at Ok;l{A)5mRq9%ir%jKYDZ^cU=lF
zpiWuSd$o`*;%G%^Qf3mCCYd_+I_O`E=IkYjrBT(Au|O=Va&d?sZ<3t67$^@pI~k-v
zq((c?SrSq!?x{C$j+l0t^IWOhOYmjC-1n1t93&O5tnSGR6Wo8>7BVrEv90ITxZ6A(
z<Mw^^7+8YCGHAb8O*@<Mf{@hZF3g(Q&x}?y9~;CHrz-9BH68`FMNpfy_ee-?ux}^X
z=pN*L*Eox%{R?!m)3FFXDz8*cYCQYP&XzQZ_tzIEA90+&M|+eRUqv>rF8T at 0R=CgQ
z)`uyk_BF at XpVU{1k1YRh2E}2rk~jrBt6$(O*l3ZVoSMr2<Uc6}MUNdRKhue<iStc`
zEP^6hzXjEJDf^flS(piS+B)_UGxtC2^6x78bWqHqGMa)I^~hIkr!}9LL*@F~n6K!n
zi7QVa{v1m$h{3nN)QajX=&D8uch|XTzES}<4&`bQo`3!~W{8b6k+0`F<c;BTMb{_s
zG`{2!y{+q}b5nEJyB=3;)9QD!{Xa^s_S1NO6EkXTsyughx?skv4|yH>${yJEw}`oj
z;@wS<w6wwY6nH$h<;Cua+V<>xs=osGr&S9N(DRRZbuRy1B1GL~ZT&cT)I;Nbk--An
zn3}3eK5Znr?*bMW#G36LwZQg`?#{HjyA=<kqA^8}*H}p9TQbj%q&4{Cf!gFIri4e%
zYXDZ`KjTd5r@&&n7ct`KK3HYc#0XIG8Z#vax220D*5wQaE>>Bg((bu!>d^=jC$f0S
zyoZBA4;c?Gc9OHVLj}?7X at IjqY*<2HsfGJ_vnyt2Hj&3I3ibegc?n~Zqe)e&!Kp+{
zsa|~2iomxu{(yasoCasq&_;65w2SiZc2ai<zcC6uK{z<CS@=Ft>aG(tmQ8P%`oZGn
zHr*(PuIuM0$w#YC-n1!0O9P&r>wLqIn9iKTTnJKc|6~6YF*U at zVt&h>pcLpO#w(_L
z==6tsGHbW$1g|Qrlh^B0os=}r?#l|&-JDItRKRgG+<PSmY=g`1V{w#0p9ga==185t
z)zTO?OTq^5EdSPTDAz3(psr~~QmJZP-s1poNb1tbcW&X at scOhj`rv=(axa at IUbZz6
zuUXwzchAl}Sml8M!>wR}c6b;?e`G06I=|`qP&TA9MFv^HJzXYTt9b#MHi9&@xxCuf
zWYb#Q)=U!gu8w`*J!d2Jka(xtJfQLmcA82X`GXope!`5m&#qGIH;8PxH)ulh<VImh
zh2$~s_t&<`S6L#v3;uuXHT~DUOsL;E+VgP?2Rvh#2#+S)&vSH)&N8UD+5!>mQB|?m
zz3-t$R`wp at lOoRtE!X2>4cXEdKcWJI7zxG3`*|Wy46)$@=c12I-rWy=Lu}Qzclck|
zFf6*?%l&jCHAZREFR_%~vU^8)W*e at a8H822bcRLWO?Hh|sufkG5Ji`@IKQ#tqm|*=
zbp|m*<p4)Y5CacLyoRWS!a!UA)MQu|j8I!veQ$rc{<T at nOA`<Dx&Qyf8y>bATbfWx
zh$G?ZMG0<Iy{(A>a*#=7!8aIiTl1Z=y)j~p&{iCXdAg$#5J4XPjH96)Y6$T%<Mev*
z;QKW`!XFQ%{X%FTwA{7EQd(}g(J8L`+WZ9HeOWH1HJmS8TZP=-z#D&><SX+N4`Acx
za_`ffkeUE}7kXCE^Q|Jo6yWm&&u1*@@vt5M1^wke{j5$P4!vQLY!iR>UEAUr_5_cD
z4KLa9{i>v#Ae^A62X{r6bpbTVFTbiv6q!cnVJ+!i{AXsg#@F>=EJg5CEFH3)yC+>>
zm%FXe<M+39+-2D4Ql4noYiQcWnmLsHQVG at Sd$cZhSNBl_<<!a3!;DyqY8Em$`inP&
zK}-jaPpvBJ%*k}o>L*xyQ(o-o#;pC*C<8$mJCrtlfY41AXslChW3y`m0;vBz7_aVo
z=7vgv*cWcK9v*@H!(}A2Q00UbX_EBM4BUB_)h8!*REXt0KaD1gGsr$CKjJ`118qxl
z*{^A*Ks*rXp7gLaYQZGv`sCw$<L9M_$Wo0fKk(#>t$l;sxTptwRC65ITOt!c1=DO1
z9Wily?oi33a?b7XTCJ29EuYf+(dC5 at D0A$pC)YvY)Q>|iIRc{-3=>QjYy_xrzD&mW
zDn|0D|C~Om^eDeTm=vv7WzaV1GxFdi?-JyhBQnC>ObWvoGAT4AYuHG4_}kQ at B68U^
zOI8B6zTsx{j68!3>l6C?{&1KHt+47YFGnNf)NW#35hA7AuK4SDT0%DjRdc<Vnd+yC
z=+DMde@`#C9mxS*@3OS)bCtQdA2&CdH^&9K|Acw!KY_p3B1V2{<C2#qTuxehJ|4q7
zAph{Ya(cg75+x7~0Qz=*lpcxD{|q#1n`^0W$Bb*5k0$fWqQO at I%;5nWAeoYy8m*xS
zB;N;r9Y$o+ttoYPU)BJzpV#v%$MEA8+IO8i{{y3^B47XM8Oy-`BdMse66XfUFca*Y
zPgX-2%D43 at nn>W1I7!6SzZ0J8e-d1VTU&A8Pc+H*e<k}(X&Vq#Ujph8<1DdH at vkUD
zMgH=v69J?lb-0Zn?zhP!*UI{?ZsPKV5 at lqm_hRdoZ@G_^*i8Q9zm9EH9iSeAu$NNP
z&ruXcBZX_pvMGj6zX;F`hEMNmb!1}UbNbU&zbFJb#f|B2;fnUT&lMc at feznt%f%%S
z%}}2(##vjO5TeAE`mu1566MCUW}ajdIi}^vK|);ZX_Vq}<1j7S!MPNk)aoyqegpha
z>&!c%AcGZ}RC3RymLJpO1A2R`BSmtQI!8H3|7GhH63bEwQ{b7KCc+-kJx at gQazFVG
zsY#%E<#~z#sB*}564GOx$B?#PIW<+g(@f*9X;(uwwrm5{!Z^rluoAKE$sS}!DX7Us
zPL_Eh;@)!6bM9lPM+Fl>Yk}VeN=<rKXK9)i-rjWnoEp^E%C&sX_5 at Vv)>TL02a1n<
zU7xS8eI%(VmJEBEEOMC;Y6fk6DcC>aYsM*3GF9KTEt)Eyu_n`G=|8gLOeG5?oex)J
z4Bo3VqNG-wH0He9pp47`we#oAtWtc9V at C?<w7LS2fG&J`iq4DC%J1IA**7hSPl{2_
zBOr0 at 7NzDO`OSaRIRQD%2k-P2FMR94UM4hD=<(VmHOWTmyGMY8=blvCqFn(+XTj8B
zU>};j`ffHr<6`6`z?+-AciL&{hTOc4-c8~xJg#xQ3;n!XQTB64q8XP=VP8d}4ERR&
zPv{=Q1RL3(^er at ky_UcICZ0BOM$TAt%cr#><`a2F5p1xa!PnHcD?WIc2(v*Wri6GB
zCM~bwk*5R40b+LBaAa^bfZwk{07-=Qe#y(r7TpIznVzQ96nc4WSQzTwuvaTMBQzJs
zHc<ZX3vrJ3F~G}u>cb*Y!-L<astMq6^OZ3PtFf`h6(J8${>>x_aeJyaw5z*}EeH9z
zCAhjJCCt;R-ucfdK(IdI)5%^d1#G`H*4w(2KU?eS^;`3UuKk*@xJYz9Gd`}EcF74c
z-!}f*I^L6csIzU*g{H1RAW|zT1DldjepNNtv2Tte&#nL%7b?AwT=&K&;_!<^nE*hJ
z&MrcOdG%b^*h(wAPIUL;COsKAln*a6f%;2m_i}=A2&*W8QgxoC)S7+27Am$0=CWkr
z$Ac2ndLSe36rv7RIin{6oGD(irQ5n=<G?Of>06{vJ=QmjFOjv#<2&t#wl+je&U|{k
z9_M4$?yUVyKprHL1bsWl<jwYk{SED#$^9z15sjR+jtA!EU(u=V9VM(y$=c!pV};tC
zO#<IYZy>`H6twis+j^0i#<BOr1q^@jPy8S~=szYo*qR072*6~3Q6}q-mLzoEiHm4U
z(rv2(*WGq;4WT=6j{8X-sIw2vppy&veGipZWE6&+HKr8JEAlj*=2-c3GOJSI?=J`a
z+Z(K4_vYXVj;8VANNW#qr=ATdmOxRYtYh^)l#c*F1Wcst=i&XgCcf5`UlBxm!(efr
z$jhup{ZacKSF^2LfzIP^my#LB%*O$E6Wp)JNVBGA4hZ_DOt2Zpu2*}nC-{kQ3Bgdj
z_$4i%N-^OHLsXp}En&-|;JDQjY7Pw}OFUL71&1?Xc#QnZe>1wI1>Aikx_t{+FsQMQ
z#vkt=9IIU<7~=7&5zWEV8*e<hsX3!gcAiyB#VoCPWln=t^?n^n{qBAAHRJ<Wp`M`5
z-}`}A($C7UcxYG+peH<cT;@dJT6v}<tae>4oslOnwdKPhs`i;Ho9-{i$8aZ6n)!*M
z5xZih<>zM;>tNbBYv5%W(-e22Ebh=9_C*Yp&K+*pD;3;H!Z;7f8OCK4iJQuCJslOY
zTI=eRlc|X`VO6NV+S32nY{MVRcf@!8>LQQt=ZxMSPVCB6c4SzW^u|nZ?eEsNz7WqA
zO_EO_cMW}WlNolX(^R)H`qrTo|G))IfQ?4{dk_$uqgQDZOn@#DvNXAxC($<6L5P7Y
zHR-&nrnLQ{E>IF%_jil-s_H)CIVrx|l4?A&aPd<3d8NQPAjo{BAglYUcsnaZDR9or
z_*{<pjbVsWEShwWI~TfH+OZ(PB6$#VpZ;N2FlWz|L@&>e9XXNqd*l>9TNb#@K2rNq
z(5D+DXp0<71S at ol5~op%cuq~rs>OyvJ?7PrEM&B>pvs>eTq1Ptht?a-T?)G;6^(oZ
z<@=R=HAyz|(T5neHOL3Y_q#QH1kggeHcF#x at 3mfO<SY8e`>B8#>E%`6<q%h~0Bsbx
za$<8cKcuNrk4+{@9gyx4d9v&FLpSwQIheyKRDwCdOE-r#6&Rb?21?4j69k#(^e&Ya
ze2>mKVjAdNt;I at _;mCpHtWU at -)YC8qhNenYX6j^D6aFN*dK-K$nIf=xhlro27jm8y
zGt>(<0<4cV#g(QZYG1=JpZqC~bxaZ%+*WOVtB(UCbEv{MUA_L%rtUA_acOgI55_N>
zH?&?_EB29Nsil9xGTXQ)orG3~e!(kX`zD{#T&dav)^`Eko6=klhjLZfEYJ?)ttX^t
zW?lCmnRYaDts1NyXX-cOFp)$$m#KTh)_I6mZ7#e}mU_uKf+fYk2a?Pqfvtld={^r9
zTt#@((5`=0yFmo;h&w;iF?`sdySGK1UisD#^ckDs{S)5=Jd!U<+WubSz+tgYr8O?K
zgke*z2h}G`+QJGiwa52XKlc*4zxwO at A(`uO<Da6qK8NirmWaMHHMY)~^-sHUVCE8T
z6O+4ruFALeK6s35$AwLT=-8#QGtqWB27Z-+cSk+Ts0Ep>l)_)$?%+<D34qzXX#p_+
zs6V1-qcKWf86$fwd1(Et-Ts^(ZQOhGE6<h%y}}Yz&XN|c5FUBOvT`4E!f6L`;ghn@
zesq_BLxQo4A~FN_j})pnOYy+lvd!l&kPeVx{it+xdQPLWKfh;tyvxq6wznV#E4zNS
zWk``HXA2GStLuL6- at u(^MmvIm=2Q;N`~#RslmQVZJhRMO&$0~T-nD*%IcB~-UJd*J
z-FzKcqmKi{dQ<bozM-rxQ#q0R&iq`B&cCveIBq!rzX%G=Kg-6)MJ1hH1B<s-w|JdB
zHD91Uq4r+Ktm-e{>%w(NWxigMF(l87TClKs5j(@G at udk7eUKXjr~uCXT<-DY9V7a3
znTqBzHn_rKx@^P+cuwq at tDA+W;|z4;MI&8OL6Ezue%v4U2#~_S;%ILEIW at uc|L80K
z9wec;eR}%|6aHoRM3b=apAjm%bG(jf)#_%Rk;Qs}F)=b0mFYefl?Pn}3nBGFHe-b{
z;e!LnIMn%Qi~aLi8xr3y!-eW`Hfq>WCmj++;lCQTd613A!leZIn)T{Bc?E+mztgYD
zfzKi9ZDLcG-wyd98ft4|E0nd8KiG1rdSDKEzyZKG$H1uJ`vApm@^cCzdZhfOt$F=-
zaw)?V%R^okF$Gs8?mGsy3u<hBFnKzOc+E#sucuh5mT8rYv&W3j at W6#fA9;t~T(si|
zW$;WlbpfO*6hv;IbH6rQFWB^f(9?+Ixa;mi at t%FAa=&1T0LeqK$KH;7Zu-6Lts}^*
zgg>=v(_Z8|{3g&!sW{Si_ZG>&5m$sOhLm>8)y+r-0&O5(hGr>bt<my5(CeRbQNO#7
zlsR#qxHcc%@vq}Q2VR*dn#5`9i^pgFg9e$*7%i8Bs%mS)s+)Mf^gw=kKWm*Dx>l<O
z01P#yEOyY*w8ELm_!4zNKH3#cg61rX>!_|<D!er87M)yFT>&}G*^5 at U%ZBU7vX?OZ
zJjxj;S!d~KUghRi+P_%CJf-h)Dr+?&nu}^W6%x{3+NQD3EL@#UdQV(COUP$MwvILq
z|5Hf`Av%GH=o|LE6X(5jzkPNwvMK#*E<*9)K2uspZ0mR_qJya1U}@Is?%W(eh}&+Y
zZTp<S^L$~saAZcWOuW(|=f|bmPlq%QYn^><pM<I<_B9AyQ-P5r2*fy)YH)m6@@Bdk
z*X<l{OMJvlJ~d;z7bONXNZMcg=S5e0VDDR_s_6etbT`BsD78rbiJ0t3rKYXyZOY9v
zZaPsGnr&0DzTU^!c$jNFo3cv^OF;A&!?yjk5~n0#Yc}LOJn=jJnvC|8t*6a4Ixqvo
zP}!j0 at i#3Z494Q8&l>QmUAW$z(XjO6AOHFuJ;56Clw34V*cVwoWBE5(FOCwaJYdW5
z5m=D-38CZtp;DSdivgq3*juLJf~ilXDV1Csouv-0B&5NKDLY7Xgi(c^rL)ZswSIa3
zIReAK%o@}Vm06)#s*d!NhnDF}Z8~71aRspw#jkyJ#Cv%sPBF&>2TaOj##%XntpYTR
zQH+1Z>Gtp^{4qvNi;2j-TJ^?U^9R2`CwgG2_=8VbgsZDI<xKf&mGn)6^->SnuJ{9j
zD#yKq*}8BujgX)FRj=CttxJ4eMhjPZy*=f<$-G3FiH?zUm at fn>a$h1^2OG|tW@^>s
zZL;4wGHxCj6knWfo>D>LUUVxlwRWKp!CN-r5I>ZmE7j^c2#RlQt_6m!f5y}j7C0O9
zy$nx3x$cEj%@XrGnXEh- at H{t;LW1axIFx!<Zls7t;oB;8d~Z)shXb4*Obc>(jBBd6
zX_nz|fFA`2cQO8w8`E=dZ%uB<XCn{?Bqz2PeA;zf8)}XrLYp$I?293u4J3ZnM#jx2
z2_u|PeH_n{qZ at d*Qz+hG at ni{$JSj6wT{6B at dW0#CMrpSi|3%mkQzl00YYhrDv5;Zh
zMRZb+>ur+sctbcl8-b%B`tv+w8vH1V5;h5j?pMX{w`%mDFFSG-R+6CACF-+R1y^}j
zKUsL+n)~O4j9Xr>`n_!WAuR+ at xM`EWxCm(x)u!)>Fqn{*QzlUh#@w!cDYR#&N{<2a
zJ0mMZaD4zoVfo=Xba=nU9@*e%SxR-&Z$Ixb$D*;4C=%si!bhvsT~9qzxKh`ubx1w9
z=xAQP(3B7vfZL129#8iEQQ=hFmkDPy{=A&z)Hin5aYp~Q?^jfBViYy=*zmsVT9o&3
zu<#MLJJ+BN*-i}Iuahp@>U~h<e6e|-no-=Y$EUH)s^C+=4j&q;L;H65Iun?&D?=v3
zR4YI1y)DhP0hPrj=f_5Iq;CRryL*cm_a^a_oyiB4WV0;q&a at 6cs#X6_0Q(xq)?E%_
zcQIcTG at 0OgKblkDgG@B*=Iy30-VpI=8~0oKci&>I_N)kLC;GbGf*ScSOw(NCefCd9
zw at k<ucKH&P!Ih!+2T1O=fpMkLAxpOze>XCFp*<gnW>ZSkQPMA`^8cm?<{?mxm=p6_
zjLQS=f2{f`J~O=P_f3J_eaxq-1sIbmGn>W at 798ZO&Me5~U~fuh{OtKk;!3shdOBUH
zc4-?pLG&BO>nlP=JXyJJo)q<$SFA)xOXU!bG&L~iO8DOOJI`Id)Y&QNn`6}y_ICy>
z<1 at F#-uaXk=Ua8sHV1FHAh23yrC-1^-tA)`%r3;?yH`Rd=0|@;K0O{@a at UQ7(Xp9K
zt;o?GuRRRRD%9ru&Pug!{9rHS_Af=wZRw^K3*d>*vvH3mpyyWfVia?_>IxsfEMc%H
z%TlkeJi+u`93ii4VDfL+Fqr?+$|Q-6HVquA$?_0XDIVBq4fl3M^K;d=;eq_-mgH<Z
z_r`{en@$szJ^*CBuQ+KNsl$w_23M{+W1~^12Tu^!lqHzi1Ga?xyd?TP1%mm%EWjHj
zFKP+Buk93bzdF+&OT+z6{|N?q;rPXWuo<R{U)A$^4Rl~23fy$~`l=zqqvX^<OY!x9
z=Dp)QgB)+<4ewY;V~>pyRFK|!>D6L(afH6?Jnyke{~~;@c5r~C=*Am2w6VibI8`#*
zJmO35?7)8UV4!r6Q^i`c&`X$Q#<12z5H7JJ;kOv;pW1P-5?4I!aZnEE5KI2?WZr*X
zYhi0Pq3F`(P(gl086nI|Yt|rNrkcxhr)aB;Lc7Bxkm^PG{A(#@imNbq>BX6`Y~*8I
zC5=v`WrOEfnFQ%Q{cHzFG2K!(YOd>htzp!~Dbxb{vOJ(VE?w at s4&mGCQBWesx)Clf
zuz;zEKx;VVN8 at _#!E2Q;KK_s*Dk8qSWkVN-ksgGBQ_OsC?Yg)b#+bYm<H}oafW5w?
zJiAJYS1x$K>fo#sP4XpOJlhJ^gE?|d!AkO0lBJd^nQzQSwket<Mf_n$HUXwh#qkm#
zT<kh6N}FcgSG039Ki)lOuKdg!=^>owXj0bx`P<%*wm_^zE(xK}!xw!nO0&z9bJ*8;
zpivg}Hd0 at f&MPX)GeE2TRA5KR?^N>orsoc&Ci2$2H(S1_bwa<1TISXFsL6gfy=0`=
zo(R6C^&z#r(k$&ms;fWIFq2}S at zVx={~@qVh>sQ$zG6eR9pFV>wtM3 at jFQlfBBT$T
zyR|Fa7jlSS4hlN?cOOt|%rI7-GHDJ_OeU at a#^lc_-aNb0G-JVwBGdR-<?jrI(iYo8
z^arNh9k4TK@*SMAI_*pTE}NFr8g=zFQ$ndPHrQJc9K;VOpCG$jFaI4FmJ2y)j^+xK
zuxKy8NX{9pK=V;+a&`sp>HGjJ>xkki(BrVq>XaLNE)1G<7_yYsx1)zI9_%3^dVw`j
z{Etwec+BPXx2u6CX}`%E9mb&72M=2AiIO)NZe2J9)tZqqnRl;uiXPM4+yL>Wm?I{-
z5byiBbCHVilgO$>^XslsJWgWj6rng#ZBHxV^?0Xd){l5tg0z!bSd{0vo>ZXm2h#7f
zU0ziDj+JCAO?S#r6)hm;N5ZJArmLJ!X)zx$mG!l;j^KSmEw+cDIg0?YOcfHgdb`ve
zB^4tQaQunPdkHt6jAu#w^Th5lZm+eA;CFbKN$rRLa|@|Cp%3n#J5BfBBI=hCm8J4s
z24%2JuXA)OX{V!T7_nW={J1#faM@}&<ABJ$-G(M3w#)L^ZSIugUD1brq6MVXTtI&;
zAYgF|ak3 at j>ZX^X!`G(?-xJ!ORMP+lF%M4&JxvCl$4_M&wAK`pmMNwdy)lxM?7XZR
zOUda~Q#w97UQ5#pGs=K}0;^^`4}g}p8(D_B<O)L>lGz1&J|NENaCPTQVAT^Ye0R^Y
z0$iujwkgTUrV3XSN+Y``Y+j{Q96)}XwVO{N9caBaq}M~HeI~2tjRcmy`4CwlLB+(V
zW}*1Sp*Biu;-ekvf~>DN)w791W@&exlg2=65^c`^SJ!#Qv-$pQxIeAds8%UDP!zGX
zRa&b`sU3U9Ua_~>v(zfJ_o}^P6EWHtwKpMz8nH+15#xXNdH=*auks<euj~3==Xo43
zv;Tbf6D8 at 1kS>NKB}X%EMd-UfeHT+>8-e0`{nsF2&d+t5D*drK*DBQ>ECHDlGs?3B
z9_H;hP7+^3cvIRJFt=uOtM8inufq6JD5R%67Ei*im(kMiXM)hm5 at h)rvV+*GB(AP%
zBY%xmyVet at Z%xg(wE6S=&9AQ+Q!l(%)ito%9ICx at s`O=Q;KXa);Y7ll#n2Z9yIG_a
z%X|GDzJF7lP@^w2=){}4P}<D;WjQO;GrLvk=T9G~qKb%1ywKcLF9DEkug8BH$M=3b
zF;Qi)L(a^S8yLW*SO_o$Y9yLLmctCxj>5AfPw&*n1kB^ul16qThpz!Kyu;@UHwbeK
z$Kp&a=y<EH_f|XIqlcw=TKks<(S#nE4Y<=giz?NUI(_+1X~ua<oOn}0oZn;gssrL0
zNTYSoM*1VI4BK^{f+V+9LO9<C4ew5f>o}Nm@>)p`cT)VflObHMZJA0hQnuGVy}~LG
z`CCiFmh{mVOR;34b!OE#)9F9BO#Mz%gnrifl!b4B?KdJa7rUkKY5uoAF(TRycYZi^
z7j+#vEK4bP%O-arpxt~d?UrPl>Q~NoQ8Y{EzA#eN<#38lnpL0p$`CQ)M&O<$_2;ul
z?}o%<YE2*(=>|{UUchX$uC%?%>Ln!G+(cGesy(O=p7I{*{Nxv-26%=9GFN)0pIBw0
zy?gUNXO)x4WU+^+!1~Sy8s*Lq<eN=eneDqq!}-we_V$=g66wh at b=%qCQ4iA&YkwYE
zwPDh$z$v(?pr;&mw%}bmV%Kp|r`v>5^ZXOA>5D$z#ihXtc{>~h1+a>lsknO2RqNu4
zpI={LPvW3U7rS7`R;Z?oxcyW}^Q+%g)nyJE!)+qpfnj-u$0L?59 at 6QvPXeFN{wj>Y
zCYemy{85*_R5tvV4W7z8+$}A>ARjFI8plT=tbsSlaK^|bRmF_&GREO0OwlZgre9P{
zkdII!9 at QKW$3|nSYi^6%z?qvjZ4#&DhyO>lY0Sus5V+j#dq{FzDqq~)!aKmAi$c~U
z&jxBZt8YjZQE)=or<As<XrE{6Co=H91JN%sL*(Oy;%nyfGB at OX`#v%mm+k7(e3M0U
z;Lf(`3rROeYqvIM{kI>$J1!`QcLL;UT;=}mVv)%makd3?Azjq{FJ+-vvlcU~MDZy@
z=x3QcyfQqoSy6F^XOA_$^hCqIKRmoJdWVu%3>iSNM5ep-<E56d at LokLvCUi=9jEuN
z@&%dXqUeDo=)2Ut1#F4L+OJz&33<1s1-Ax{^m+4mPqAym*)Mn)&=%FdvNncd at SmSV
zDr-^UG$S;7l|Ve1`^ThC6sKG8_7ASj3f)Mb;3T=f3EFesmHT5i$t?$6_q0p2D8FA*
z@<3kSqFP)z>iq|rkR08B5hHB0)Joa2l8eZY&<EQBPFyt#_c6c4u8zh at J4-#xDBQZ7
z_o}(8LaJR6{qi$~$#{wPYb3SB9}$0xudkG!wnC(!npp_GYT9()y{?83Hr|K%Uo#Z*
zOc2m!(F*tYo^TB*%2Hhsa)P?Tn6kc2$=?KeRFbXfk3YwbYjq4>_72m)pnfk8KCYMT
z_xO$?6ZVRGI>$%^reGFFGeEez&5?uYo0eb9*VNYJUGeAEt)~?0gLFV>^0OcdnUF=E
zmh3T(kAtU%iBhf<Ub0fUPt7Np at D@9j%wg%fAWEM^n_{;DV@>+x6Hccwckj^6P_lP=
z!Qn-#|IIb7cIC3-S=OBMp3fdh7ZH~$M>7wE!gH^z((__Kz18!KR(_TkqT1+jl^E;2
z8pc&(^)AxP*RXi`CmjN^ehHLe9*R7aO%h`Ap4spm#g%LI^=V>ublghasHjU-$d6`1
zU=^4Fmg=H`N}Aw&8<2=7k}{q<L6c*u6w_ZDJpLL%7sVe^w>(-~l4dc<)24~zd3T7r
zr`iZ|_fni at Mpl@lhsgNDPb;+|hOp5Fz?kCxD#t-HZ3v-k!&cB=2GZkK``W%&HY at P8
z5LO!lgH0^{kXv$Fot=@Zy$9NUCT<d`W#Zw4?Uz at Zk?#cyA4VvY|AH%P$0sE|F<=WN
zpygP6;&6XN&U!cB-rQcXwB?ooklfk)C;62n at W<~oIxvf24<mIPa$jb+U<+qoCdWuX
z?KOg at WRWffL3w(_i~|q`L;I0FkhjkD(YVsXVWe|OWt7kF#KQTnb6^r6NlJjl at K?tg
znvK=RHvnPPuC*nr&KoDWrL1HK;JdI061d&(4Qcz>4wuM;?xM=!2OE6u-YQg;Huyg8
zk6i+$)$YYUUHyi|P#S0T+Hu(&>;hn0Lob;8@&G<FjT|chHfYiO^+76!1SQQ1FiyE>
zkF>g)v9Xx6D?z~j(NKxjT*1eujdGLd5F>a#;yiL*e&@OHo?H^>=i;678-BZs8w|1$
z+Z at eF+7ZXqM@}2*TuCMtmp$<iL?KQQ3QH)<zN+|vA!&a8-xwVQ5xM7Km3u|0&f%*E
z2c05(zmmb!B*IplC+HNQXF2eAbvE at a$ZALEclwJ8l}m8#Ksx%NqI#FW!^iiXhrQwD
z6gm5n>zB^_G?nbh6S*UWNtaBC_cJSJ%@*oQJ{pA8jpOBCs|9?Qd^)6T|5Fx(jSke<
zFxl74Ql2~R0{~`Sqh-pEWaI3 at M2j^S?KEF+TycX~<<?7dSHl!vzHQaiJUK{+i6E?l
zENeqNp*Z3lTSzeX=ZQh45{O^ycwu~Smc9u8lG3UVCwAJ{verISjVShg4@*ijY{`&J
z4wkI{oJG)k71CLv33W#k56U)-MVF+w+`g3kGEd4(u~HfrzJ at +DStN&X>8=UoWX30U
zas8lrS5cjheG<Q;F at N#w$hPa#l&LgZ`d at aj^c2 at c8qmVs$s&bfmbJ72xJV5aN;$AJ
ziP}6_15CD{VKcwQ`z&{Vy at N43pdbOsF77CExUIVlh}jAK`FfOEXjYu65E-|@LLfh4
zivhBm?F|7*0lIInACg|yHd&{C21HOYTMF2?V`>Sy$DLNO!S0EzQ=C#I+Ba>)#Y at aU
zPX16-aZ^FB<%}lIvQ}jxxT^WY2rr at Zjgt0=8Pxu!(dKqlCyuo<qQ{nz$-z$Xr6?su
z^5D}c|6<>g>3}^u064bX|0t;zDk78_K2?c^%(}f_V9(3=U|K+HHu+ks+Z~~0W4I_<
zbdXg14VOrzB*JIoW%nTG=hyv}d_9if9^ZocuS79a+cUI3>l42>_2oS;bN6ZoLM-f0
zY-VXL9<ukCj=J<+J?7YtHgG7^2!`yQhu>aKRqy;&p9r<6RmB8aW}di4eIIHnt$HBV
zVhWkvoyKYjU;d at HF`QARWWAi)toxGWnT4f(mzQ$9bKr>}cF}1H4EZ#Fhs8uA+Aihu
z0cUGUsZ!p!o8eCXgHkgA<XyW5;Q<uQEeuJ_Ix&K>>*3$^8E@}j*niCw;<A_v*c;x%
zm2iaidMzO7)C)>zN*BZ6QQLLp(Lv(YlX{yyTt8Z`)-bZGG~e5mNnhvmB?`syjuhvc
z#%v!>s5tIqZr8&x=_bl78IjzYcT9w5QT(Dko)4!({>AfqW4&Z$R4beN<(YYU>fKSS
z-ky~zDKs)r>(=xJ`C^IqJ02Pj+%60XXwSv({wm~9JW$8Ip3fhK{|QNkzI2adMK{z#
z*vd0Of^R{IlAxdIbym;V6^i_M_nSK9 at +K7DM@s8g+EA1QsfUX%)b at J7x5#jHeX9ZX
zV~{(##awen;a&Xn)T_=MW6XDj6(J?S%`dkj&gqFfIs at +Ols4zS`o&tiC+xLhz0kSz
zKOseNxm(1$baHR$Q!dT*kJ?z+5HM}=mhBdG>4(<!KzI}EQrPb at WV|sSzdn%&pq^?Z
zJUF0J^7$MoQncmFE=j*$MK984v3&8P_l53g>b$pLkb9lp-P4dL9bY)LE?o6bX_{3E
zqNR=n-w02OI5N<zk|v5-8!U|a`}erF_9?r6vqyu-11bmi<}BY%?&AU6Vku@*6qh=8
zDaTl1SEt*la|wv6C|ZTv7I??3M4k20Pf+upR*A%yBfret(yl5sX~MJaA_PC3M at HC#
z+i`n!4vD7JxPm$SMQTNcclC8rkyf>?aS|!CyKmxNu5-%nN!o0NP|ng5x2JIBbw%|a
znV_Rj at UJbU#`vGWH}Bp=&c=ih%XO#tiSm at jbg<@cbM$Ysw$kQX8{+Esb8c;g&3>$2
znWG4Gt4#dM(=c6%SdlX4{r!c7cT1WHrZfDF@<#UFMJ5rU2DvVf-PX<|ta~!#=Z=>N
z8<PF>;Ttr2aP4~V-Gbg9BGiGG*wu9w1h4ue`on7!T-8-=U((lCdKdLtF=53b{QN=X
zA}$qSm|dT5t?~5;hKX$rk0LH&dhGmkMc{40_5h)5-A{p6#6_?6V at Pwyvi7^JW{Ed3
zSvJF`UR|-nJ3v5%#`f<&fuyL2h#paKS6N%q3ufbaCWp!G6^WEESI?7k4e!_VGZ~f@
zI3bx_R|=5cFD8{X!|;%ONf}ccmBWwInQDW_7DAp6-_zB~PwW2));f!i!(Cs`w=1%<
zh;~%j>_W at qKaFRNZUIoixzHu?n+omu;cVu9njx!g9}kbFkMF>!S35R1<;=&hA_1&H
zn at P6sWC?Q}evV3xJZ^cInm5B at 7Mm!Ys~A95_xty6`9^m#KAV<uwrE;91c|^sfqOA{
zjojUQc>dsOkn%LiwqN!*Gw~J`Sok$UN{06?(G`gR)K9J4Q0!s4CK!!-$#YNJ`x|#%
zi at anx8-0y6u)|q@=@KO4E{*;>*N$xqm#zsC0<|qVmr-B0LU)-j$6WaQt5xhq5s0Gk
zb9D-D2VvQ|r-<OwA*5&F;JwJhEc4s91e;qOqB6Y&<gkq}8&hS!vd}*fGH2H~=Ms7j
z*8$>c#1E;zBw-b!_*lN$(id{PrPQX4-n>dtRPUZTyk?f%QO}8-$X7I}y(gxf0q_O@
zbg_93`OPM-?I2XHH3CjWY8eBuvMD>^iHYAXV6{tke8zknsAJCca5c_F at g#(^u7Sn;
zt}NvkzY68*5=Len1D^8w>-tLnxf9xp^1W__yk#hCQt$p9(&J+9mYA-#-%Kh#JK>-)
z47b0`Zv2z+F8x{2HkS5slR2TzQ`-v>La)W#vXmOrjSyyzjgn?{yhL1m$OzEJHoz_{
z7!Kt-4p6%H=PM7Bg1~aUn88Q%ICT^$s(w76l21!ymOY<|EY5)@9=O!yM~<h~R*w;y
zP!uo75LQLShSWq at HTDCuLIQGory%l*{GvU#c;Dv+tct$ZR6SLK4EGCeP5 at bqo{>vt
z?==L<T4}LgSh5)*nIRIOnUg2kMSvhs3+clp+I4{4ikA}UI&f8Us>*MY(qy=lmV-~V
zqy`_ at xQEcvEGmJK;3{Ebq0*$x9t7A{529G15j-30AiQ>9Ijc3V2K2F8w>d?BWn}Tf
z2SxYj%EjWWz4}eb>>uARtgrvrz at Gof>pZp;+TFagE75NIS-0iXT}#{ibaH%ryzAl0
zR2vX!j7WU`z2%Ei^<2FR1>5BuyXpAKGrkBi9fo(+D$Ek~`olokQ;MFe-E(gmr<Hw2
z;IXhO|Jc`zxV2sR<v;@ZQnm&MzzbJ57#=M$5znzj-8Aoljl}MQ^+Uc)dBi$2ovXBI
zI!k57HN(LXO(gspE;2USZOa8IGmlb9o9Ax}g(bZ&zsynoPXCcInf@=za{I(XoXA}}
zRsV*&1aHRN at I>WH`Kq^Obn`Ip-HBWlH#Vwadty4asHVh?C5Ef*tx;2u4H<ve0?Dwd
zv~Me+Yngy?3vQX|t6Ecs+`GybVV60H_qlsofaIJfFZaA3i&$c={%%sHCvma2I2W<Y
z?;*&~2*y^zcpb_{{xyj9d_ at Tg^_1D}wE0Z$#;>dOjs|h@)=ob2g~VOJh=7_NYV19T
zd*z<*C(qEqfQB}nIb at Uk)_WgF^D#X1B|c7oN=<LpEkNv?QuYK`eG-v+&(o=>Rk|RI
ziqwHcJXy)<^K!ldykSu|RMF;`jxFziJ7c(0Z7_LBK;2+SeBF_OJ++k$M*F{=i9f;V
zfNI2~eP1T!_cN2ECm!D`B&*dTA#<fy+wz-$(rP(;+$P at BSl~eN@$_`~Xz%v;*I79%
z{QI{((WXL+>_-^>+xja%VGdCb=f6N?-ut#|Fz~wCUJY?AO#!vbmv26{<&AR*qOhr1
z?8JK!LtM0K555&n9lULkwj~h!#r at -Pt|g_Hxg+=67ARV2$1DuNTFdF?ALrc|wiT^$
zpy%Q49(8x7OBYZlom(>w<<ei;vX1xN>Nl=-T2vSJG#B(lHXO(#-J2Dy@#$_YvYkkS
zloHvL+wlsH3ZDP%mDZa?L!vN)Wez0_5lbXNTsVpUUL!V8i&}$drtMBd{MH6WpOueP
zTDt>;e68`-nPu+V-QLWUVuewr=^u}UxjLnbX8?&A4<+6HwOm9cD$X%XqfoiGo5vs|
ziJoEhm)`ZrGa8|bqXUSkgcve!((Lulb(;3Jx{35|+IxGAU5lw0YvVwWv?-8mDlRuk
z7a!rtORUdy at uhRM`49_LqI~+gaEVLbCL7sCR#}04Vf@~pjrH@@ht^auiL8E>1b-*1
zJWTk}lvXCkS$xPhsT>2g1DOjE#RJXT^T0Y0aU$jIDayO;S`s&XsIS+kHlo3$((@B&
zJTS;JxHadg4gnHIN*M*}2B>MLnc?)DguXtWB+(>{GJ8jzI6F?#>POCmFL2ge=N_Aq
zws4wB+nYJ+^_}mIe3k6h_kdvK=^Lvph34-{s%I#{M3Dt1$3%M+K2k at FrLL^1&bg at T
zG^bd?wM8q<08XHq-RLcss%Hvs_m6tmIu`|HZ35eJ1texCL7GwA-4`SP|4PG=heqw(
z7#B;^TyS(`<yEN|5HDu#3h_2|vuRY;eI9Y$s_~ITrz&pMro~6d1*9=`yj^2#VJcO;
zvFq6toq+QPR>E?-Ob0>V`A;^~%?1u-Jm$43k_t91aa at KD1(^aH_r~}zOmJ<0DB81F
zI@&9?=}x54%97abyzkdeSdREHHtrnP8hRXSg?(&a{m5s at dNa`FAhyJ_iq;6kvuY at z
zNaMUN%6g=*qMog<{yTy$T*UGj%a|NdU64qwo9zhF!B#y5&mYd$Fq3~B#5bO<8u+nN
znkK at zs4Rv#%TB+C>?iEx#fulb;@ss~$?&}1{HMYn0h(U(A68*5yJzN0ozyfva!)iG
zUa35?c~Yr&swJ$$u{iC-w!i1{+eukeE^hgQBeES_D at S_)IBxBJ{#(kID57fuct)%C
z^Rdk4?2V9G3F0kYX4>4y$x)|3Bajov%yykTst|AedXMG7^#@)w#l!f+INw&)%f?qp
z{+e9txAQLl^cHK(Ps;kuL`yEz`Y{j^EUIk<w|1H%eW=4hXX-DHr)tdR>-R)@g(2;6
z1oh$*C11m(hAa8dx?HZd;r%cfy58AEb)yba3tv5jZf}2<!#4Ytnt+Deoa!CK-)$Cf
zKGxvJha!|V_Ijb}W2ay<1+E~Xow|(`vZ{H)Uyon}b6H6X<HL;t*q1DLlX-pl$pZCp
zh-Er>9<>W5XB1B1AZ&nj3-eybTbTlK&>`pDB#~L&b1wk`iC~OY>v!Pqum)vmDLtO{
zWyyEi6C~pcIeWh`yIV~!+ at -r5i`6A`pXwhJb@&8arUswIc}D)^CrvB at 7_>(%-ZdTt
zLW#ZC9FgoEFKzY3UzlIml}}e~4hU8!eqm~q+hbLEg4$&AMNVDN_yWW-&z%d}vZO|m
z1kvZhH<8+plF*rI(6&S6dA3t_?Rfz^%`{z}LT`-lv>C?C$M;AffNFg`y0J;So&PlP
zZ^gmyOd_{Jp`tR8%~Z(uU&o(p40{XaSnI4|BveEi`u0r{>O20P<>@!YSypW?hwDx9
zgdt9pdnK7YL at xmSa=c)*@~E at ravua)4fCE@)6!JcLx8bcssKlf5~v8IKbHLrp*1U%
z;CLlism}G2v~aZP;)0XKJIGL{KHKP3<fF-9NzV at Y6b^Cmvio<+rgBTWQB+fkUi+6H
z8h6xF-yUBFJC~Q_sn$e4<kk&|D94xi+#=h&5A5S=qkAi^46=YxHTe0&l#kNJ#-y=(
z-DVe at Y0g<2{3;ca;^Oa at ep^B`7*;RfCfxQ_N6Sp2smOk!?8Kx<e?1wGVlNrC_GLWs
zRH;{x$s^CzIN4PAAS$ZwK~L)2e`kt0FIe4UBI~Ij`&J5<j}58za;(&JT%}@n)H~mk
zDR9qX1YxnkBt0O0xVW+zV|{&o$2`%$uG%Z=p<=gtpLNTDb8SCp#nHC_GtM8Sz8c&3
z54^gXRbarzPF(s?XWS|gIrmPHOv7<3W=xbLf1jDLMQwsoNwP8s#pShrqz4!xibb`C
zw^_}>1nKK+A?<IPQMKyHH8D<oR^>oUxLmV1qq&1Ru<Wva+(Gz!3tc at g4;E}x9>umD
z&TUn+it+lC5?94^n$-LBW;$o(lykOk)9s0>)!6<3)T;uinignnOPAc!X}YY4ZSX|~
zxi at Pv$fU)|F!i~RzWdU08%z%PNZ=};y+FZrk(5u{`4A*AX);;rPc%C9Ha38S+*+1S
zaa5utwC;KuJxF${z&`Dwn||HyUOaw^^J|nI9Hd^I^@mjAyna>0`ao58Q!Hr_Te+UW
zT(H7~HiJ+5ckd_neoHR<&wwz{b*xL!OS at B6sG*@2sKxiaNr`;ZDi>7wW@@QTsqi~p
zosltXOCKLF61iOqV9z-=%V|0}^5r7rERRVynB48;Fh?=k#bKrnMfxx`+C&n&NOe2a
z!m%Oh*fdtF-L>@zvr8<HD`BQCJ6Xat(F7+$vHBqtNs><s^$S|3b`x9$vnGlMtT53l
zjpSDPZ#`X})e}60y;9Vpm4|Bw%-^{y8##C46aFs*$E!BcgLoFzTR{Hd_~^(ruwlc>
zI8>cYmhyQNv4;0(CyX(c%E^EMM(iF}<eF#wD$CusM8pM<`_iWWD`b$?3-2RPM)pxh
zbg5+#Q+O<Rf}?>-NqycLdki|L#Wx<~{}O16k%#Db@%Fb`FL3cdLi$dWyV?~wk&bd&
z>2<_;IwARSaXhf)NooKI=<R at d{SPtGkJEXbLl6sX_FyWU<0~Kl_Os(<|FouKQtCop
zg0H}}%^6CoDEU4Ea8~fiuK2KCHg4j-t2DMK1NJVHAJA?}Lf>tl>>MlS&7io;9S47;
zho7g?Odu5xPIURLf}0XZ1RS3fW55Sv45y-5 at Wbzz+coEDu*?S62fqay{0)`NxOI!>
zTvk$Cy<JRu0cExl`#5s;UU%LHq=?p!N|r+`qXfDco&2{AT3Ww{xWGf6#}Z16Uu<K!
zx1gG8#VdzEJ2jcMW2w#8R3ysKuI0TG9AmS~DcYWv^WLeXq%Q196nM~I)6<pkO+s_B
zAvY8*tVdLbFZJcD^Gj58Z*GIuY{XQ(6GKX+6+d|1>I|PUtoDEhR*Gng{?cT#Ci9RI
zuei7Pudupi(JR|9OYBtD!s}xJ%Vko^GeZ)p$<KY+?An{isjj{^6CU&7&H0CEE3riz
z7SRpXR<)2W5}p at E*e#YAduW at PTc%A2!gHUq-L{5nq9YdRT+DgS&NW<pXmz<BVkBYp
zrt&mEbw=)Tl0~nc2AivuglA4L3LWpoytw`w%6lfw8n$GU{DQe{k|(oI5Jh%!a0y(+
z8v=(g|HXnO-1 at pkEOGB8$i!u>v*cI!3$r(SIJW!|2884X^E#R&kVs#pzxVM!UY_4B
zC at VC+jmJHn%b16ReflcNkfB?n$0T0p6tIS7--mU%?O_lCpxR-8LH0fQl!w0EcM<x?
zxv3^0D|H-0MM?djT7sA}aC-~%U?BWn%__>~;tVJ>@Sc6;Sk%6Be}KEk{ldu9w|ya3
zNmhmB6V-EVrTe(#DCt?kI`X)0?NGV4oUXd~$}{mcnve&Y9#ZTxQSWvZeO`EF1Ld5S
zpG--IXw1g*#kUKh3u_QU*&iy;BdH7o&j-pGS4;TX?lxb&6Ljz1+#US0$nwXDrH?V=
z7VmJq*_^LwG*C6Zu^j{bXw4to at NfjTCc<)a9TI_*Oi=<?G6d&xN^fHao>!oLBf#75
zu;SJ5o%(~un$P(+5^+HdZFu7#S*C>b;3)d)>IzqTGVkp#@1f;n7umw~n5%gT%Bm~A
zH!R%dQBV5}p)K&&&RO`FynZp&5tFad5*B-4aX#)Wm>dr+kB)Ql+S7&BoeH@`IMxqc
z3`~#I>Qpg3T9xkV(D<O?rTeHN^E1C?Op;OT+S}5#q+js5JEv2G7KJq-;>rWfvhl=a
z)|^Wa7Aiz4buCZZ)ZqHM3$L_>DA>6a1hS|69<*ZciY|deK77g`fP{tZWzo^HkR5uX
zl-$XOZBc%l>G(#piO#IZn4*Dt$#jgh#rpN(RvmZ7ub~#bP=dfvZ)2`DvBc`;k3K_N
zeB*?S#N(a0YxA|G-eu9vexC_}z{=J=lY5;K1q9Ql2Dc1{qfSD^7Sw-_+S;IT)->>s
z%H)`#i?p9ve~2jdgYHwS)4<yuLx#-o%;z{GF3xkHbst?79txg|<c8VFW770CAq9bO
ze0RQl*mu0W(<mpx3RF65I>tiZe#2 at zWTxLv-U}$AgB!3|tY`<7Jyj3bLnD5)sJm05
za!I0}W2Etro6B9)Rg>sfp{i8QE1G3l{4VhNcl0hpB9TyuR$3aTg`$$L#Cs at inpGPb
zWfb1|Ku%ZvLT%6<#9=a&IB6h8p03x6=zqD7 at Fn|D-?>6zg2eVi-%>A7Tvn&I`dMZf
zBD7%ck;xS{d+qt<{_>W|TO+BJ%Is4#ks-;v>~p?p at I(V{l>E*E_zL1woeXIwx070J
zsq2X|saGu0Ft6X|SQ}amynI24iZ?DijiIGIos?KcBdvrFw_Z>CDU+|8 at h*Bh3=<n}
zo>~qYJz{%!!pyVu*tK;|GvRae0MkS8$Xn3Qt^|E=gxV at O)|CHMNR1{DaMk5mJpOEP
z)>kRJqLszkH1hN$%14IO5~#KcDoN$Wd`j#FI}V<-{QYb6bARfs$>d`%M23WZV=P|k
z^?0tJ3B--CY`5EgX-8-s_ at CD7td7}vX?#_WcFb=(2r^*UGHBObjLot)-oNyGy|HDr
zXz6O~&T1ZsY}hnZ9q0a5d^Ss0;q at N;25CTEf#t9X&)cpK+2OBnuB})I{mZE#nm{u*
z)T~+)A)}p$96cp?uc(($f8-{tND)c5;qGbo2-NwTfwf^;c0tH)&vMEt<!h>(*t3rz
zeA9zE_fC%8rp;y<fCnJJFn<Nwt|oXQ at NgxuBw}?7=+r)sZ0b4$MC{jXowHe2(FIyk
zqr}xvxjaqYcK)2m_gqRH-QQ@!IHZ?qLgL=LX|GQ&RcaY6=UcO`>eY*;e?~n8Q$F3l
zcFs=vwEVa}{5!|DMoHGA0+RVU%BPDevmQDn)A~r<!x_TIcTKtW_Jl<Z+j6D;U~Xxz
zA05IhcUXBJf0~9Qx9iKspNF`k|C at B_M^k=fFF8PXS!Cqey8H}}{=g^E{<tF6Ki_C*
zezY<(>gkV{HVSO1H!B5zi1In8NO-<5G1G;t9Rj7Caw{^l^s_-yJ};8?gDuBiO9{|?
zqmd62+gE>gkL_kZOUF+I&dXel%vt^9sCX55>A8276;(a`Rj+Hox#+Dlx^r at PemFII
zeP at Nv;WA#Wu}zD0JiL#H4l=Jx#?LbPPHeNaN4S>VwA#*o##>B>ji^YE^zL%_K`+Nt
z#8mZSJ%N#gJ}{ui&1EbAhh8Jb5Q!Wms2qRm!E?_8L!w*TICjq|1`c}vR$^u(dx6E9
zHs>M(a at H1Mlx_i?bgl3;1cgT-6OIz}ws2614WjZ6BT&DY9*+BV&6DBdz!G5}IojrR
zZ~ZrZzf?c5|1f8zn6;vS=rO#1YEas;NN5xY2{>JX@$vq0kuD?r`@vz3OEwKm?0P(j
zH&T3&DfeVWp&>*h>lJSH(J1eVBo_cWvQJD-#?l(QS4MgG05mu?lWP3x%Bhns@`E?j
zNZ6QDv?47MZ-JEM3})!9CU~durpTkQIY1(8%DZ>1ZNHn at QooySLrhduRLP7(^KzRa
zUI~nb^mqhLUx~^R at s{8x&H!;~Q5VG&8aK;i3n;Q4WTkd#l+n9c)60l7j93}6b1Wyo
z$Xt_uHWNJG<<#gs0{3l6=E9Tnd^$p^GxAG9WJu#*GwSchHg|A>9JrF}?3PhXN at jt>
z5(yte!r(J!L~+x at 84M$wd0TWoadC-SusEfLFv`2NelNuPgTM6k*7Ci0D5;W8GIuQZ
z`eaX(b)YM}|AG=Bu==9$@&g9=5;_Ic7dbAlG0xpVmwfqL;l28}^|i6SIXB{mzz-Ux
ziUnzW$LA_&scgEVqOTeCX0!5G{nIAkaj4*-RPAT%jam(sW;ZVPi2Dm##*$nR-8lCZ
z`^VTcju(?8hRm1AQA-!P)YZ%#_~+_PTUI$a_w(6O&0P9XO-de4Kc?hoR4o~vZ|4u+
zanJTJ?|S0<H)+rE&`9)7>)PX$Hx6wwe5e1>3d?(-kE#b-9KSq>bS`jP?LrGB8Tj6G
z38uMLI41|99t7T*;D6YH+qGt>qAciWe(4X$XUpLdagr^i_C<H25+Uh3-9C!hVqwEz
zWG4k_o?wZVAU7nwfn^+rud2zAQzFHUn75#{igO}28yEb%S<$7R*Vsm at 4|Yi at bt5Ie
z=t&TR9 at 0;mFsqyxaJXI=@P-lm7%yy=EqgEty!GRpN<qVr4!K+M7?>@Wp7B*=LTWjY
z?GE5=_CPRT+|%mV&r5RkXnMe8u%$frz+OK*D?(~Gfq=Fmd;TsfeQC63VEK)5&780A
z<=Or@;%h%OjFVRUCO2yk#UJ at D;)~1)6*b$#PG8fdnv4(6U!;BBt?SK~0cXrr at Q|~N
z`@%)hJjm8dt^`{H84NYaNSn)&2?1y0)*Vx)h4)S>#8vHZjQ*Y?TO at H_ma*t;2w%@T
zF2-X7u;4gb%8%slnSElAv^4jM^c1kCmf%K<@5g>H4FAF*vHvjw)OA3 at SajF_Vmvzw
zU1>EOt~CYS7&!8S8O{L{c at j;~&n*@-zSfCJM6S)OeYhU7EamASv6Z2la#IKQ;&J}Z
zYnOT*%O~8W*G|sTt3;W8eRXzrmN6lSQ#YBOo@;Y!<_YaK)9oCvYUW91H2c;2Nt&u7
z{=31A+S|g at wkSQu&*C}wZNOmL^f<N4WHD`bc2|5kR`D<M;GnOseqB^CNl{9d8i=P$
z)g=JO*9^`0!|~m=W4j~tVe%=)WrzNsrjanZBF%x^8a-d{WC+_M<^}5T+zei=76pVg
zVKk&AONv|OlzJ~GsCr&ell*A=IiNmNmB*-}{3H at QRT{DJsu?_^iQU at zBjW=gYlo(i
z8GXv1oobeDac~6}OF2o@)ueFjbJ3!ryDxqg2fsXNjPi(EsdL%&s1CJ+w$#Vo%YCEy
zWW-H7xvHK-ZmXD!#$>W+J4dLxrr5T8XMM7={W6E5Gzdnlzh#d0i_+F`c_e1jsN+Cj
z*vRR~q|+CxQg16<yx at OxCH1SzH*Yi4bc52O)x at Zkm<#o+^=@jyEsXc+eXqg~{@0h=
zgDV)~hi;oyc!{3e>_ORVAA&E_SvqtWI$;_I)C~!IjGT|4Fu8VmIi5h3xM-v%KJ1Gl
znE2pdc_aJu$Ye^?MS_VYZ8Zd>pw-mjMZ-1cV(jMb?oJc-J*G2$4v#YW_HNgTu_yEC
zc?7Ep02GP>D1*X3$}8$qU{~Q83|ml(Q%`_H#|40swh$5|{4HE#ns?FYt8L?<NLg>z
ztMe9R5lT+izyF%@APITxc3kx`9zahynLzD(8>wX#e|O>W8JPARQN$fDgX!~z9%0!<
z;Z`j=wUmCj$Gn%9X4MSpn*41VcKU4P;~bQ#Xt2a(+DMu|k$c>TeQc5OsYFL`UfG0}
zX{VLnY0PO#jHGcVe^dhdUNri%c!`~cp`CM?b5k)%ync2%8Rw7V19)pk@(XT}Io4WA
zMlxPuHRl-gva&&M7J|y+wdS5A)VK$XMt^g~C5ytHe`{5s*=+_x>ixABH~~TOf}g*8
zs02wxW{3)+=sJ?)+*2v(W!T)ojeDW(09Rul at 7{lVCyjn;;vV6@<I=z{-%4L>S(Z1z
zN}-&Cmbgs|%@3YmM&hEk57@;lV>qqUn5KhA`&8Cb19OI7KK_IwX?>)?)k5no(zK!{
zT#kC=<H4ET at -@kO<gvA~eqZnrb%W>YT(Dk4`f`t7eP^;a%Qp*_Fo&nldCVLcKZ3pp
z6Bhz*!4&0h>(t at VUb9-g*0U_?6532TtY(cOFqoa(SEYG{Owu3bWlgK8`$7BnE5$~<
zgavyK3E0FNpJ?|irHu&HBsUh?7W^#>(j!h#p2#oA{7URjKIVa;DeJ7AUU7TsJ_a3M
zOOgqGMN5^i9pF{?)>qFHhoh;`k^^)#<(yA3snz%`7u9B6sivins at BXpD&Fm2QV==Q
z1P&Uw?E>@-)OsVuwDrA>0V|sM-Z0H~>#XfMIUR at 7M8dMaZ1D~8BDH`(G)TE=cbb)H
zX-Bak5(E^zYk_SvXpaSvi)xe?@iOE{k7$17S01q>YcRtMXs6($ivsg(Iz0EM?HllY
z+SrBKTQ|?zW!7iVf7Im8w at i3`V71GdCnbV|qpf~g|8VVp;&dLfDkdr>eApdt at Xksv
ztgdiME)4);X!cU-w3*_Y-S+5hF7)Dy5ABVsH#5Oxb6Ql<oB~EDr0V&zUk;|7-aT{5
zPLEsXC1%+cT4>YNxD0fI^jJVu&SvTd5KIu6AR*6D(4j&JIkdcj9GH&%r)TfJ^no~5
zz~9;qIA8Fbs(bDqJe5);>ZepO8Q)YLc)}b)vlEonM836^b6GRJoLF&m{BNS6Q{y6i
zK`l2ME~Lmk_0#@$cVpZ>Ph)8}Zsgx(nc%DQ#;pL1o&JXPqGDfW#F|#7Id4j#zHftu
zQ7MO5MMYIh998c%3oFV3Gf*l$BRZ8Z`lV%MhWmiJwvx8A7XXdupEG=9{YHW5qA#m*
z<uC&SeTB6X`pll~^}76ZvwYnc&JAa#<u3aelG_*qCo{jeYEi+a+4DHbnKo at eL}8^`
z$Rsz6>aQmKxf)2g4fb%~xv#pD&V!!vJr||&e5A~B3ud9JZBshZR^b9P(@&dOYu*04
zy5fXbnV6X719!PoVG20z=bW&QnE}t0rkL%{!%&;Bh4;SmyH%NQ{QaBk22bW_05K+k
znaiIfouawoW|zn{F;6htIs1S)i|DKt%E)J^A~T9?Iq{MSfM|MF`_Yp!Qn<8}y-UB>
zMM?QmI0cYBD9Y<Kgh6DM!hbhsJw14Y%eZre*??tBp?u<nVsHI>+M4$<w9N4#sxcO8
ztajAXvyN(ip^+`POkx!Qc3~$Ety>-W;3se?tXx|Er24j{=&!!-EuctgiDg9(t!b&(
zFHbW?qWNEFvQ)DdEzy_iq}_g^1QgEkwih11lMU at U>~}Z^vW3)8qEs)1_&JY3o2^Kt
zD4Nx-Uylmt-gfD+Urt%1&!sP<+<t76Jl+^aS(GO60PmST*8f9AQTuHa;aLQxJSI?Y
zMB at VT1b&*4Wza>M7|uC%x&6$KH$%0#KZMV8a%<f&5t+eZi)%Uv;Ax`qATFV$k*=2~
zg0$RFD4gbyLSHQ=j<l(fioSJy`i|Y^i#3-AN*uEvqxZa_>5jeAxF*(wQ0WY#*nGrF
z{<ZOvF|nR at rmXyjt&vThq*1!z<U>+%;hY1JxdGNKx|S?t%07<fJY#l16seT`flk!R
z3kIgs^^TOFN_m{>m{uTCn<+qr6)>(RN-%1+&^nk(s at v%_=T%xj(gcjuooHls4k-+K
z73Ejx?}__Vyg_u4h7YDqM65O9kr6D;d0t9aEuV`c6pGJS^QG-I at RiU}%tT=H?Uz~Y
zeB;ACy|X4p1!a4?yII5P)e^lf)xW_3tqckoZ}-&3TK4qo#Yi9d8m$CsGr*z$MlJ=P
zFm1%nHLnaQF at Ok6og&RbWg1TjW-J;e at KmIe*Nz--oxfIjpfRtzr)Zq0$Q2<S5z3|I
zD)?%ab~@jdak|TyQ9{51m?tUt;`{42uD0wKyeo{+Sq=Ddad;OJ5lBtyoV~K5!<Km&
zy7D4Zq$7e3`^C$?+$z7fh0t+NT(xPOM|dq$EK!=K&pH-#(<7{X*5rPccJK5;;N`pj
z^XnE6C5}U5J*;8P4pCapoNr&i(pXAOaDQe)!Gd-xx(s{4TI|p+(Qh>TiBXCFpf_&*
z{{AW?|FSJVLCfJiSY0Zqc7H%V&XHC^dRYHjt(=FKYi3G89THFB1^ilIm592kh<&Y>
zKs;r>qod=HUO8#DFagi=0Nm~(h79^t5jAoRCuV1>F)yztCtjVyGWpa9H at B*{I4XH}
zXMy<sRrn0A&X&I?lfqbJg^BFW6ctE><Ob!&Ty5L#dVmN)yibHT?#{#`vd?CM{&>}U
zq?`oB7-8_Wv)qifQ3EhLO<rWaBGt?NdW|;NiJ}bp5XDr{KRc9^;?hO5Jy7<Bskf$6
z`nQL$27vrrLumM_r9AKoRXIz*k_$_~#xiv4)+VfIDj6iDX<VFU>Aq6j`|^jlx#6>U
z|KLF_{NDFcTd%(vkJB2KjZt2hcaPSv?$i<n;O4v8X1_GFG4)Oyi>WSlCknbB;dObv
zA^u7{olBv!G<~0tCuwrj-{<lUzH_uGvSmICOV|9^VU;+?mguS{y!eo{#o4hzMkG_#
zY4%xl>MeY$ej6)k+Rcoyo{QOe%(Y$ia at vR8y1wvlHfTIH`*fh915f;pr%*Iy&}7rD
z at Cl{vb19Cu_qGR!)vAeRwRbTSj<v+Nw*9O(Nk~l~cf<A8*%ig5r%nk0$!zJY>Q}2x
zoP6!ME1d5KYt@{4$9ZorlM8_Dhe|CQULPcD{mY3H>Ovnl9>gIhQ_;v?4;DjbQ24y5
z%}S|4Rm;ac_UACLHeh0B5jV|5ai(dOy#ivmHm1M0{d at V`<W`SuT<o|hY|5J)zBzn=
z>>)xzpZ`wwH>+{@qUdq9QH%FFkKD&4yddWM at N1a6JeauOeNMamgLhdW`V^fK+gQjp
zloq at Dcyf3*!CBPrTjJ_FAe`sa;#mv0-tW*Ls?;VjYdE$|=F6SxBvf(lS{I(h0$>Nf
z<K^#S*J%H}(0{Vr{-tx=*RzGTYxpJh#vXp-e{FlS>ARoZ;&6?`Z<;T(`kW-!dm at Sq
zPA2;?mxdqIZhCD_oh`1RaL9Js)iK)8 at amwS_jlCs!T<BKcQU!M`Ql#1LeB-so0MC?
NOI8XjSt(%@^gj?LcDMil
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/docs/kimchi-templates.png b/src/wok/plugins/kimchi/docs/kimchi-templates.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca3ba585b02668de97015bdd9ec4af64265592bd
GIT binary patch
literal 329678
zcmXt91ymI6*9SpDK)OpndZjy+mJTWDZjf$Jl<w|M=?>{`mTp+drMvSRe82wz&T{7L
z?9M)OpL>6`!HV*dXm5z#z`($ueU=hahJk@&hk<!jf`kAZ>D`?I0S^d<GLm92&o4h&
zt%b3`5#(=DnvO6qDA+H5urMiU1i(Q=r_XZYh%3lAn7lYm`HAMhAwnl{4JT1M8ygc_
zCm2x&69Xp`<9DtWPUi0<Kg%hq|9FcJ1M?2%v)HFEZi@#iu4&7vt<R@(w+ZxGH47K=
zSg$m(Ucn=OkV60P?vg<YAG0 at f?rOXwOS^Rsy)lPQx%^FzwwMR*tL(r8cvSkl=vA&%
z>&!D7=)+S|`rwFZ>;Vm|(TxB(I+=mlw$?U3doxrJng&*qNo3;8fJRH_7gbdBUwiw#
z`)C!8A%aBl3q$0ghCaX2CbhbnEoSijpmB at _C?Hn8 at N?l*o-+N=@G$R282hFr^2;-k
zD6XWyLiZqP`W!lu*3&-XzH<Q@`7|k2Ra^rC!?5U*_y3;sYktF+jd0at{{u|v-JOTu
zyLZX5SnxmK3IBVI9x}#gsjRr1- at lP*Q76;9&UlU4EUcFjN~nI_I4Qo7p=Tj#C2sFl
zO7LexSn0(VU23)iH@?SflF4DcJ<mS}BjlnrpA$L>jmaOqHlfGqAoB|M#}GLnQz?*L
z`+-Q-flP(MqLDz|$|e%jN?W4ARlaYS992sG>P^3M)d!SXaKQ|DmHw&pa&(~mPNl;I
z6D^THa%%GP)qU+1S#S0|8nr1tXRU=<=YGw+wonkVk)#TyilDIHA%-JKhdw2_Fb8Qv
ze^7H1Wa|eM`|`%MsjJ#60h}>v2{zPNF(c5#uG~!5ES*7?m?a$<XUOce8#QiK9rSTV
zoNOpHgC6%_ at f35w6Ov+zTO^EnMb5O12K@;}EvuhT78ch%=fh+ADxXRoQ$#lQ>*rNx
zya<;FQq|n#SEH~_Se8DiC`^$9Rpou*P5;77Go4!{?OXrgxP6yZ_r2o>qh16<st6P1
zV_bpr23mT4Pf%bu9c_rqscV+<PFAvOrgvKWeP%CgF5<@5;%}MxTJHC!?Pr}?Mg)Jr
zbVDl{N2`?<ov0bU8{~Q6qgmZd`g@%-VtoaN-I6ye7tUG3yxU#p1nStwns%|Tmaa5U
zx?%+&n+}%k!C|`_H7D^<x0MQmy}v&RCm4qxcEM-$>~SFm8#`L2uII-AT`mHqtG?XF
z9GX08l2NQ7PgLj|VN(+9zKhthR&w9^zW*dtv$2^e$-!Ad=lMijqkBgT1}{t9c6<sW
zP#wMb=|DWF$3^jLzL~doPy(nzyy!&3jg<J(1Lt?qSIN(NMh}m5O*h>NTg_%9vZ@>z
znWXMqG-oG|=5y%gsD0lLdFJc)Zer+s^~45X${#YH#W68|O~^ltal-#LovqN6E2+2O
zW}oNrVemf0GZngiTS5#9Qy1q8^AJKEArN35+=a9U{~p5dr}$)EX^ps4uVfwuJ3RQ9
z=2`ydUXV^Awpeep*aM{j!xZ%8^2zwoVeF=JH0?L45&?!px~B at q4|I8-?s8o#VY!Wz
z%RH-ywPpxUC=u>DBJ3nH)h`UsiU&5f2<<l%J-RaVppB~aLrM3YWcQvu`E{+t%#W&3
zrVC5H&{f1tD&9*3AD(=4$4t+p`%Lf9>TY?X at nZGlnx?SNDq!gM11*7z2a=XO)-?Cs
zUJ~BCumLNB)iC^|t2 at t9ySYXaQJ!bUM8|K;vHS%M(Q{;t;e?K}SmaJHP+d16Y=qix
zU{{~c<xi6Khxt&}+R4S+LR^{2KklqDv&Kc+XsbmHQeSwC1>g`^gi5wshHAjAeIa<{
zTUTp;jTF}6jNa0;ZGW<DIV6?s65mC#!SR+L?@VlWV6%H}CqFf;8UC#9mHFF<Pm*56
zLC1!FnArCL%~x+Rf)y4PH;nfHek{#_$J<aR at b~!cux6t6s9C=no}V-h$4L*^&eTK8
zPo?69tnhGYOqBa6ZSGOJFM_P^Pg6}5t#2T?e3?P#{*>Exz9xrTfJU!AP39AC1hL-W
z#gg6j<?I`V1Hy+3{tC8}amL$4sAclwvP#R%tN;;QYKTxSukGHK2r`vXMDXK}XHOr}
z*z!A?Oyb!tIM=5L^e)kxMPIKB?-*&3C=3xNQ5^AyZSHo1p*Z^KnVHKQ89vB$GOG~+
zl|-2S=0G&i^K^Y5o%_NFyMr*P{<I1cn$rB5XC#E9Lu at d?Ll;iZwtNWIcI!O-Vv&ha
zNs?%+Noc}~QifJfTv%G|H!>NIDzxp^vcR5nevqljwf;?>=akNL%q_HCL2JOQjpIjr
zjo#+q?y+IGPy`A(sr3B3NQIkid7v_$jf`;4V^S`!(MLO7uTxRo)P}G>ZI4oMiAo7U
zM)dV}=_MdUZefJbqR`cxh^!nqLn_*u<2|Tm%Z>K~=Q%Q#D9`4{NN&9$eZ{<e2((JF
zV1n!5+nBI7YFVi6)-9C0yZo>l+DFn$tsd5!lS~M19U7_!!AX*T%zs^F9Fqsd+TYP+
z;B(mJVKy3%Hte|BxNXR_{2XO+IMRN;Jc935cFZ!yXNXa3-X`s%BGbTnJ!&@J!tz$*
zg7}v3E&n?SP;wqf7Nh19vA96;`-EVr*SKj;o#OBBzf{?F?hD+F$lj4UzJ*4X80;>A
z&mKf0mDzXRyybl)nH4<e2>n@==6KY3vA>jxuIC+K26>2D#RhMVD1{_fv~|@yU&EZ*
zY4=airi~7%UbF2d_g4iJY9<j5EvU<yWWMKTg-9V$JaO_w{8TOuZBGnfL2Yg&AFg(2
zy^>ba(vo3I?x{Z{JElby?PA$1Ygna>9ULDY at 8}CBCKPb{w$@Vr?7AwIgel at h)W#>h
zq4_pG8c`xU{K!0`L_}pJDWVhu;X>#PRsP=Ek9Ky%MAe%SyD+2AY{lP;<5`f4+lJ=Q
zOtaaR_t1xYOlaSj=F&d6mSz&eq$3H*wWl-9;b0=p%<A^<47$0+D3&duqZ%JPnqq>?
zU2cEl{pl7 at IfWG2NW40kOnh*N2l5&1Z>6dqUfW3q%je7IrD2oPB+f$j)MQ&|aCGAP
zL%x+<TBByPq<uZe-Jh>RHBO%NZoW+*j0v3R_sQ)Hcd2J)WtaI^!!d2PVE186l`ZiI
z*K85tLMpTm^aa_UgnoX(z;vf4k%_jje#i3jn at m^KE)u(iP|7_GiYS^|Sk(d80P%v}
zTf5)1xD+3e)bWkvfmX!Z8ZQ<b3Y(!HuPe at Puuzz%{NgPPu7*H?WR>KPF$&ckNBuq<
zeM*PiCnI-tZc4rpf`<e&YIl{kudTQ~=#M?fkvMl@$O{{>$sDJT-J|I2MLduMqW*pt
z=LZYScAkNj`=e$KE-qVVz2nu^+YvLNsj_!DafZDixTRm~-sIzW-(48oo^6$C)*$rT
z^PCM(HIteH7^k1qmBg;?mPRH4)LCy6A$X;MfJP*SbLe){@QV;=!g9nNVq%<`2FeQp
ztC|m7zW1JXOhV3-xaA9M)<aRL&l3~+3Sat>;llGlSz*P$C{8$<LW~j0&=A6v-qr^r
zy&9N#tLWe7)*|qhk8-k!m$FZh?RTqV5^G-;RpjjKtacJ>6KA{AAiT at Z)ydgH$UrWE
zC1hA~fg(+?Nq8dl&-hQnus%9}8&m at fEXzue{{%vr=<El#pJuvlfzwe_w@>1T*uw~7
zwiaNS!D#0r?Kco8Jz~w3`;q&Zjv?ID+WeG!mgUUU^7B`te(jXWcKTahf$XWs8s>Yp
zep1DB&u~9fpZTvBIW|r52}aloeDFUaClJQP77ccu5Lrqo13I&Q1{K4yKD_g%Q8(pB
z73ree<MActe}n8-grQeA82^2&VDVH@!@R|s-zU#L?tv6X<RIS{yRNU^hQw^2kS4+8
z()`Kmbc2DBvEffe;XOSgBUS96zGl+|vJ#H-!q3_jmY1QIsSU?dduKnS-X?z*>3Tk-
zrEr38a(b(R-nlw^{5gGTHts^o`nI<;4IU2RK-8Z-HZj9DwYWPFi;G)@%TO4hw*mgW
z2it4mGkVCgvXA{#LabC>eQv|~a7)YeM;a1)jPfT`BkUA+|JgqUUN=8boihKDJ8rY*
zP-eML$f|j6ku*NTjBGavT%JHQp%I%0MuAoKgUY31oIeqI`E^<k)7t&stpwPC?yku?
z+eC{su5=M*lv>Nq>kD?)O;yTj>wiZOe=w|Cmn8hNtf+ZGCJ?}|`VM;^Ja7M#LaNGi
zg2A#_M_Q(V at Jox|4{t=w2K=+VeMfrovRnOLBIN at 7*#0XT%ex at 63}19+u3tZ|<yft*
zP)(1yV~ix`q%PTkGNeZpeJlKMBBH-T;<UK5)QtPCb~cPmFy+r5J{Vn}Ta&%Ly&Xuq
zFicrl*~+5AQyLyf<D- at qajs+}O}zB!S|Ir=mT!MMGDedpzTz{yLZawd{TN8G;1p7u
zN<sX^arreqw&0CfLHiYkujT4M-rC>%DGk#2-kfpTSovr)P6;b7W*NRiYzd+=(dq?`
zUAlK&2GgJVS at UP0TMe1p5!X2KUNBG{!I&RaNX+S!hqq#jS#n3vF!HS6lPL=}%}6P$
zTBb*nikc6##tnCi7BW7S9|MIJoQNQy<MPyj8E%+?B~h|8q8P?fg|GbR-Y=L at n#rw<
zurs%fk>j_#a^c*F5KO0c{%M|h$-Qbf9+z0Q`P=iTFNzW7+bwQCwlRAi`&*y5`v9ha
zywCUcugX}>A7oR)(y5VNr5W^pTc1~LIqBr^X?Lg2^^`PLrWa_>Ri}UE7N-a0B3D~X
z?t(teE4?1w>?-&KjfiEvA#K(5p^@Vo+Kec1%ul%w7YbpQw=`QUdG3F1!Rr=RS~UYf
z$#^i!C?8})YVot`D5|l-_#faGm%Me|FNJJ92lHD at 31Y!Qp;VU2E$5pmBifkX4rZYC
zedBo5R(8<jz>ES&ou2;ln@}mNa12A{>Dk%(mHTF5GPY#YWLX3w)UB<pn>Ga*8JWoI
z+&Y?QDMfYl{_n7GCj#h&xt6A`9wBGGX48+?5W6v<duuO9qPiwh)wLo+!$%qf(yag;
z&D;2GRyvcP6Z#y{Ty(=-$_(5ba;^euKO%B+Y#LVQ67-5O10sxwMDs2a99dEZ6g`Ca
zFXKQU8Qig^O`+kwp-g6dO|E>sh^+{j{tdoo*r~5Z3ob`@J4iP3ec*zP$gr+zRofFC
z$%-gSZsUrQ*HR4!GIn(lBlQs_&b8EFdViCx2=%kHH&Eq^yG`<n(n%|Q2glU7{K~jJ
z9`(vY9Z#KK80%BT)zvZ9T-VfdW8X*$$A9O<b=i~T(Cw+w%7E}Ts`|;g2P17_dD(&H
z9>NMwijAb&UmU6=DJo10;)uc3?}{oqsi8oXX+YyYE@{k8Z%=<<RV~M~k at jWc%}n=@
zrfAZk<2&y91*<gCmP-eEY+XGS2=-(0B#Tr2bt^1E8aeu$1~J<O2hh#4Wr18}=Aa4u
z){01k>Bp;2_Vq0p(MJ#AdQTbwEIUp%;S at O~b4X6+(&efc2aEfZzc4b at K79Dle9>IP
z15aq=G2IjcW>$vzh;&Lnz-ii?-ER$rjxE_*>E$=1%A-iz3a<I$XHIb8mvSt%88x at Q
z?Mu at 6gHS*Wt<OE*IjUP-b)H}4;$LikX`VqV58PMSJmtXb`A467+Kq#%H<kZ!a{!#+
zdRt1fLungLYc#ze$Fqh4A_sDy;Vx$#tY9$%+`n`oC*I`XbBFWKF4=)x!uHH~p_q~V
z&7fzxe=lZWO6w<!BR)MhSL1$e3bf>AZ4RlRR!xF!=^L8Z&j{#bVH-Rg+}t%DmwO@|
z3-K^m;+RS}Ywl#-0cg4E6}oKMUtcZ+%hV;XuTMg)LU%Opb8Jy@@g7|>1KNkv-RwG=
z*uj%A{$u?muDZH9kj|etSU3blEv-<SrDkdtP7aPr<3X&qd^_(9wbaCLUKEEYmKydj
z)>5s82v(y$MO9Vm&|e`6Wnz?_jrJRE*DJ2}I{0Orz<w~USy*ui8yb?{+ut8FX2UXl
z`9M{L0fhdC^GPgu%~c;YU2N^E>E2IgYF}~~q3$}RthRb4j>IGTeMcjnRngIr1KQyy
z44?~sOi4+R%2y5};SJduPMoUH6J}sw*j%A}+7ee1laoXH{UyYSPiH55VM3d5X{ZdE
zji$pCq;bZ}T)Kie at ERYu>YfY?Qyg2i&t3H_n`+s!$*KbG5RQNhM~Zt|QI|A1)YOEw
z&JA$OPse$GZF^(ioSj%?jy?jvcXXv}Z!jYJ-EY>~F++QKcd~wJ)R=M}9v*&Czcw6A
z;k2Hw{DDbzWpK2NE>)<K=6Q6xl4O?q4IBAjoQn9!3mjQZf at P1$oO<Y_^8w2Q*@-Kh
znN-G*ws*t6i{(9Px9w}f?+y5zY-XD5*w<xiQPHg~jnW>j>c_Y*D}9sH9Y%>ae6|d3
z1CvAae&Snnh4p?GzQaW1d%KeEobywyK=|zapeXZN&HeS_T0^rAX9sY}7Vmf?e%dU!
zwKa4f{(MKLsnB0<127v-pX=skB){(l-2u6AB37f>fj$L_ySpvtW6*+BpHBn<;*M`{
zPS4oBaEWuhGU=z2Y23*QhWdK5p9?$EKMPeccaB{M(T7gox!zpDq3|4AC9;hNziH at C
zM_YF3^<_WlZ{J93gKbNw`_VHN=vn5x#$MI>G50&7t{(Wdf6g9^a-PIf?9r?z28cTb
zfC>O$2<ar)e2xz#>TG`*pNEfywB#9B=ujtMyQ|WoI?!1XL?khXs_jWrS&)KiKWV-#
zx5D<Y;ixCr>kBjdsEV3P_3*BT!2ht3r=Ic+T-erMjW at ZXB4yu5Qai32A0w7{Zu98F
z$T$)5ary`f+8-#%eRwkW+n(eE?CyWi=(%t~%&qL~ptD+bOKaLctht7r=N=`q*AVee
z-Kg4yHpGa0Si&<&_bTmYSJLiV6C3}kyRzLDZ4 at 1;NEC7Mt8UE_<gmzzic<Yxx|>}#
z_p40%oXH;=QvF at u?3(%g2!SX;fWO1mO7tnGE<sh(=<zH*ftC>S%U#8I-eie2>tFBL
zu%|>p!gF{O7v3)N^Z^%S`o!+GO0bWB*(}e#L>xB9ECH~&z&a=beXYw*`}0FEgzd1~
zq{VY;wAN?e3f23X>B!Cf1D%}1CQjS+v5JPn^Yey*9b0?jow+IG86uD_6hiK`D;87V
z9kfQ}W`Bo5kW0YnfOFh(kB5Rcve9vh{in`U7Rt#1sDw=qXEKe at 3}HYytZ&j0AcI1M
zpY6(<wyoY{1$(u0yJ%}O8s0Mcu6wrYbx^x55942{mVQ;1bMB(JNYT8S at aUow^^OI1
zup+VzEOsEG%<0b^4O46&U{C4)#u?roHR~-vm7n=Y69&PDkulR~(&rlfs&YZd8UYt@
z-9?b9`*@GpuoceeB1aHlUe at sD)*l?oRXU$k&?Jbji<5$ux`-qg>56Ad8OG6CvVOpx
z^{PZgwZn_v30O^$pvYA3F<$6{+cPj<<u^pvcqmYG-4YVFLHbYp6(`GD`vih*!YGAc
z(;bV#wf0Nbgz%;$Js&6v30G0Fme0jIXGlwMrtc+XM9}DZdnT9HRw^{+ at f)U!uNz~b
zhQfKP9 at AC|<SF5q#||s?=?*)?L1AOjvA<@0;@-_;mvZ|<`QPFSy at 8HjpXfs=eg;-s
zOi64rC-ralje>MrqTu?;d!i*tTD$GO=h7Jt#!w$LKz#hO4Zm6ipc0Be+PoW at TUi6z
zyziB at mI{pwYr5>KN4$0ngpj<qM^<}YL+;+1g at s}7fS6aFWS(^GF(j$+PagMe4ID=?
z(ngORj$5Y|qDK8}H~od5k^`y=9d0m^+`-I^w_9=-zw0gL$H%g~ud_$AMsu%)75)@6
z+un<iJ?@uGli9zzSDSHMQiYhD2jjC=u~Eh_xAl&B{aoXDVPzM`kW6bX8Gx2G+ at V_A
zp5M%<3@?lq+!P57j|<_JmfGdoRluXn=4n>)jfS$TpDw`NV>`;s6(~tp8FVAuUG7Vo
znB;4Jd$~OaPZ&l^ps%$>&4TO**cNxB?lkzMY42=`cTz|2jza0omVf+IN(L?T&6Ez6
znvVH;`xnBrAgEC at n4exzg>d*_MCslO$$6ujJ+B6Y?SdyHr_V0ZE^nYDL%4~v_IvHZ
zUG&19VQ?OVEfIcFz}QJ++j1iFUB^@_)fn at +pJCmt1hgDAS)Vc4sv{<hqA&Q7DwxN@
zw<P%98~Czhnm@=bNVE+44SPVZ=PwouBc{MYnWr=1d5|{0=_kkrO8 at o7_{ILiL4KWf
zje?-7z*3)y>qFFrht|y}_yp17*F%Vr+ZT>w(C at lr@g?PJkGFCp+#OwV at 4w+nMPN2l
z3Y!(Ut;(`OBBjhkxf)E(WuQX84Dvqr=xF!%)sxOzThgLZh1u8Nz4{oC{G!pX$BrKw
zm`YeN1cqhXS`+SebQx$W{rqa+3{Q+(kw at u{G54^C5OJ`Du^Yq^cCt9TCCy_MuEY6D
zZ2t|Bx41KCIK{-~f=DSmRkP3TC~fo?d!+HM-tks0T!ldqwjm#p)TvvVBlwnE*K at -p
zBHat*#6ExnMjPO+G^`@<y_*tzxN2~Xk}qsXz02 at C(qw9XkX}D^W11&K>s$L})z)(+
z>C;_v{}46Rch#w%#ga`lG+aU#`9sa#LzTMHYKS$OQj?IX^g3vf*j)ClkyyMOjzkkQ
z7E+&+a at Htfm1^uSlY}-wdOs)Lk6~!G8R+M4&^Uu3`+X>{_r$XM0e4?<C<?@EB(l;r
z;^z5QZ4=W!1sriGv#hFhxrYZH#C&O=^Hg23J0_>y5q9>h-)T++I56&ne$dQ~A94N|
zR&YyheuBD!$b^w-mjbxW*`RW@$lj53XH}Bvqfm*bAb#I#Ga9uD=xyCb(?f~3+tzAo
zvhbdlZL2L?#qw3=!>*m(*(jJ?Vsdd(s at f(rRzV=Y-%7*D_M5-Kz~*2-2K<^!!_-&D
zzdx}5Xp^>reN-APHK-srz0XvSqsNY?YpUs~VOq~c^$+@&WP^0a^tzhULy2$8saK|D
z31n<rn`)7JZ4)xtYsxy5629GZ;-mM}gW~+yeQ&TH at 71QJW41>j^3+J22F3#(28niH
zQdKGJe?Z_ at R~QA7A<5$m`L~WN9$oVebILo%&W4Iy8e8`5>XH+Le&n!Eh<Jz@*Q#x;
z`eegg1zE1X2odF-E;jP*4>Dg=tweN&c_DWS626tc3iNp(Ee5ad)h!cb1wxO}Nq=H%
zka$mU?=-CT at 8t;AvWK2JUmiL##1E;;ER7w-DU-%ehTLbPE?jXfdJ}j|`!8E-J^U?%
zWSv6n^uPU$MnmiSl{ck%hB>5Ax8aNvG3gU>CHqlP=*Rw(HyiiLlOPi-m+c|^)5cQb
zxE{2Ars*f9v5GN2!+^=s(ka>sQ}BnLD<SkHhEZ$Oyc&Zw_N?zIy76>4W%QZ){QGp5
zdD1B_)>TirqVMgn-iW4Iy8rRL=V9!HcP1jaR}{0)X=sljD-0kEace)rwLNTE5wLuN
z=}YQbWJ at r~juR(9fdABS{Cv$+-gs8rRj-dEh`vEHFzP)EpAlJQG*2V8#8f_c^P?}k
ziSFH*U>J6PRfiZ^n at e!Bn!!?KZkRJ at +YmF}me|dlF~Can?`@F=iR5J1{O4dXzs$!2
zGuaf5;DQ1gfXuthhdK=FK~E+R>SU8S;_P(4y^CIb;$yEd9bJzSeQPjZY2eTaI9*6p
zOTC7y8E)&r8S$o1>N7Lky%|vZTU_<Cd*S8YVA_n4G~Q?ZsR9J1wi{(#&qGzAhi|ZR
zde25aXR+k$mtpMoIt at H<>pj at Lquk3~U{(jXNo&KZ528~C8eYS*E-ghZ4z^kin+JS0
z`+bAYn|&K+N4U*bXcCg<5M9{sV^8Oyh>qPR*vO*c_+tDIEzUF84F8aMv$tiJER>i1
zs};a1y281i;@%<g-0cj~nM9A8HeO5)SJ?!9DNfh2ZNi0IyIPv3Vt5vNCGFb&J at GRS
zq$oHylYap>B3&c4mW|H15;=4XU)UJigi}ZHo`mD22b;wX;xmKSuW$QLU;Dumy*$-x
zxwQ2WnIYfY(vp%a($!OkkmAY|7>sX8hyFP411#lEBSJ}4bw+7O`{kwAH#R=nb{#F&
zS)sIIB$ynkqCE!$AiQvsT@%cljdMZwGvigCdmHUJlgGQu=6hmzfG=6t+5!yc|49JT
zF!=H{9W%4pbdi!)m#ohxX~;D&vb=5`@R&3zJ>lde-RBHxTu*F-+GO}yov5D$Rz1$;
z+-Z>vP!mknc;3pTa{Gn_MrWG>^(bZ*v4H^(EB)DGF{5@%GMsF5Kq;4{?=O#hcKF(6
z>{t|q==j%IsrMRfUcBt9UfBK4u3A3}8Xc6GN{U3#qf{>pQ`RLEm5k_~{TPRb{3-L_
z?CVK6e*U+H2fNlwrn9A*B;M0XO_-us<}OmO$8Gma?a$rh1pF?bdK+wUOalU2WcJ&S
zMw)o_Ho0|u=zcnHk#8|#E7Ibg at jL3Rt$_h^7~!n*h2p^Jt&l(M6z2DkpNjV5|C%U<
zp+bILL0w&ZQEu4>oB1OP8!JYfi#@N=wDm0gu+Hm8k;w&}Pc*3A+EKwAN+o?-<OZl;
z4pjoC`k7i9Z~G;cevMrZi4oPp$`~|p;c+EYOTUWv at 16qg-qE`xSsEqj_>sX6zmmNa
zB!#A(>c))~x at 8Fhnx1nounD_nh+G}hC_V`re!(ui3M&4JY_uS<gWQdQR#Y0eG98kB
zD)kFM{z%yNerN9uGA+Y4)+_THB>J{dUaBTYQ1jHwsjSY65Q5fAir-5$cxEM)a4`ay
z05;G7pF?RLx?PirrudFgtRl-&gZKArNlHCmUXP|uT1)v31k6`2Z`2_Scj>exoQ0?E
zV1K>fX7a9*GK^Ic3NKEsvmz=Y=OtKaC}4rmkaxXo3}ED7f7Wt_RwUaj`G1@;Ng70F
z4(;C%Q>slwv(Wfo7GNqqh)>~Wu1~+h{<lS`Nt)w3(VS?Wf-sJh?>ycm2#OU6Ta%Uq
zn5hkMu!n?wN}cdns4DghRY3-r`sSRNmo}P0N$oL&fixCn42-+U(cHoRy|W7O_N3_w
z?<Wk5(B2d8Oj(+rHcR;iea<T)bED+}$?Lj=@oE>kdc)blpASm<4JlLA*u*4Md at 9Ay
zqg*u5hdvsfI`q{R@(8VFA_p_v(FcaGh}D_FzGevMWcf;6gpy5Tbt(qo`P3g(Umk++
zul4|n{wuk~t69rQL4b@|_Om at nAq#1NaT4(9;Xi%f|I at t89?M*&J*zRMu at BSNj2&ba
zYt1$qH%DFB*HHDxg^)O9R)2vjcvLRTT;6^<Te5rnQ_E}#iGL2wK6|~;=s;8GH=?f}
z<FQ3qVMaf3db?GP<gc8+(UJR49{`9tnQ7k2B7560Hax5nPP8lyia5+00~%D(AwWv#
z8YmAS%>Qs_ddJFT597Tn>NqZcd&(q(o(it+GcjJAbkjtivzKDh6g|d{F!Fe|{Dzz2
zRG!!$p$La28736s>uHMDI$I6{a#D?Pzdsb6t}bU`-I=PC(mNGny at mO=01s9Hgckjm
zvXs$4?qS`XY{9zzn<vG{ruyWFI>pk0epDtSoW4bB+aGecl^;C6;qU&^2=N@~%-ZM%
zCSDF0v;9&MYc#;d4J7TUeo{@M>zJHS+n*AMwKQAc#pX3IBE?Nz)cAHnr~6y)GhaH>
z`?_>eQ#^Rs-(TJgSJN>vGA8TCwd*ICL`%K at MuJ$8OG`%<x$)<SRxOwkRg{Q`h~UMz
z`m@=O;&N$#><0t6t^$R+3ABy&zxlT}6lg{^mx|d&O3ehoRH)q|+12lmq`Sjd5y0nC
z at 3H)mFPj(HH|SEoHlyQyqK?L`-t4(8wbT&b at dw<`>IG2r?0o!I?L{$-bbckDh?qfZ
za>RGTFoW5^^JL=4jrSi~Ue~aG(r~kW()J_*#VG^A6T8U}j-{2A`|VcZsQ~(L^?+$j
zZ9{`&7cwo2^*oEv&0n}}aAu^<Qku`*Zp-zmCkH3z8qZk&(<_GjH*=f4_<F{77rV<|
z=c8^Jb6Xp^bU95;$#8FZz5|Si&Gkr|9`>IOcB=4}UFS7%l~KLT2G3hSerYV%YFyd%
zvOlLUJb!&WhBD>umg0aD?DonkSMILX1<w at kZ+@!??kmW(<5CmXt~J6;Rb;szunuuU
z)NJ`dVH9sf>E5vRK3|H_#I9NC-4op()S#o_f%Gr;X52C)9Ua+eGric_pDrtIcXA_N
zWG&XdZ at c-4XEPN(@yYCF4lB-cxE^&v$hYw1 at URgZfA62v_F=a&+h<c=KnZ{d%A1e)
zfEHdOV}<xHd=s>SZR#;Oi>K8#f9$oAwq6 at +2ZN6oeAGgx<sb0?n~nh<&G~V;p*B^U
zgG{;^V7nD)i8~vJ+<kZyIWC$1HP}SU{zJIEPPHu-q>P3w%bK{^XabypKs19Hb2fvS
zLzk1E at 1K%F<O5)&$<@`d%Q-y-Pfvb;5CL!^me+Bc#b%KM*g|i*&xDS+ebvdo+pN4*
zR8i^9jTDl`5wESQ8w~s>%B*LSn7TM8Y1(TYO|h*@&;wu#P_{KSH9tdTfL&0Mgp1C)
zq}1KuCYZdQt(%~%Q7<Rf)3+E7KP<qN$Mx4;GYIDsMjZV2^;N%eOFLpC#rmI1&BB~&
zXx%!IuoE<s2H0{wR3);UmjwYV)vlJhQm3bNv$gg0SOF9O0m%%?3Ceufq^+&3jgp6k
zV1YC$zsoSU#)X8u0T{|BjHp3lB)=?0E+*kGWu>KI8XyTkXIZ7o$1yQ60i=quF>X}A
z?y$B+(v_T-d5=ZiOL#Wdb1uMTv-qW`IbD_}xYyACJApVR_o^EeE-o%`O3WN!A-{l;
zGlPN>{i*artYCPvbZ5LdT~C{}tNY{j%s?`aAh}eo!<lotFjhdd0g&b=45t-#Ak<S`
z+O>IobmS%zHIYY^Dw{<Y`6=J#ouBHX`uLZ&WQ|$sFv>4^^<Vo7N;3S{-<ULI;Dvr9
zo|Sy7<Se`w5Wa0~MsJhde>Pgy((W#3mmfI34Fstc8AcCx<l>*XQ%AAjVcTy<?FiUS
zQC*kq5zn_r8GoUG&lRQZFK5)JCMUb7A_YVMb$E8xVbvXK5AnVRT<>9I+O&_9(fW(E
z79h=Pc<^}=hXs}-nfv>QjTfPp#rMez;B*E_Uuj|u0GxzME|f;EQov$7fI-r4Fp(qf
zbul6NB5SUnB+D1_KHY2(a@&$v&6cj^C+Y$QI$-()=L7-3%eHY10gp+0Al0so-tnKf
zOL6s`Woqgw$!1C0X+m7vWx<5HK at a#(HjO8`q at vBE!WQ~FhxhW95=P5E`QiQ514hMq
zvGG!jZ`cIpA>UZcm2Q$4E`t#Pu9eyM73m?Xjr0vO7TaF<0|sKqIm#zf&->#CL&kgu
z1C;sY`JU%|tP5V__q1vteU0|7S5}sW1B=cN&KqsUle;mrO|2U^0Zq=p%-k<;j)+wd
zN`ASGg_%Bo#`j|?E at lfA$N_na2#;BJq#IorfF at xCtbV{n5-rv9UN1XZSX&zdnGi2v
zH*KG1J`225gjuFHmz<p3K at C_)+hLG;+539MpJmgXY=5o-y07=lr>^6S%gG5y<{W?T
zh4k(w6K_r<ePzA9z1OsL=C<1Ik8=O~AsVhODl6LxVFW~@lJXqD`%~Ono0MVRidWZN
zYrS3toYsM~e?~%(uVHQr|KZdapzQYoeR6rr8z at HML_Hr~KtbX^b$f_KG0j%cw>CVY
zRr$az>;Z!4LKsFi;eO4q9_L9iqXyg+aUYHU{QS0<3R}~w)`D6T`xpyFc_er>*Gr0b
zW|wI1 at -8N8GWMu$y}w{->1Jb{;fhqHPpAs@{-PppsH~84Vk}oCR>N|*CH0WB at cb~A
zMsB@&n91mLy?5E?{&2othwVKRdGVRSh&>4)J8Rc4d+*9ToCFFRZ;vFCc%5`=`#xU2
ztkV0~&o9NYJ(?={V)S>DKXu@@--rX;h7*`*=C-!mXT!`;e#q_Hm!({SJaJuKUix!n
z$kNEXTKrv at F=P}e*r(&VB8~z7vhe<0 at WQu)3g2`ZHcyokG+%b_x}J*9#dN)F63Y)3
zRN*QXqpl#>%+{D#5Aa5IzuEc%xvvRCq|UgX;vmUN56iTR1!Pg=YDS`$E%kjuaW=6U
zQ!@K5tZS^GDyFV+m1uffT;JMsx;-FdI$<@9^kT#bmn)>iiO@)+&61k=>UfyCD*yd5
zfwzacW5L(Xw2|mijkzFYr+uDVqxt$#RdpTz*_0P=1n>Zt?Aqlhqv?3Bu0&>mA{-Qc
zIz<PvC|iko+ko)CF)oU}m7rz21}K;P)gVB!>a6g&Wc0b|CTDXy(dV+B{|GEt(@7VK
zg at wf$G2{jT at UW=&A90>hS<J>rj+&3#y1w!N<%$kXb9~!R?km8(;xwfuj_hJW@#Uqd
zAyw^%pjclzjg4I0w6z~T5{eSQ>uVB_W`}nL_g3N(kYd3rmGe}ZtTn!Mu|HPA!3w}c
zP#o&BCk4GWpb at _`YwK{oUj;*se3NB?X1lz#kx{qt$JQWE$tNO8CG94Mt_wh-qK*6%
z at 5oKl++r$And`B;qiDz!Ciye6syed<!|g(yenmLV%?x=YjnvL+d_BMVni(6Dg1Lo2
zlK5i_GY}O?qpGtrr?$mWJ;c){PPtU0$}f=ICn at vkqVVA_qVUT$G2G}2_xG4hzn*b_
z27<8E at zQ|7Ma*rRm!JRoJG$^g6kW(06tA&VZuIXHxsvRjSJn~{B%gJ3NP)3Up2}sz
z5QYpA0<X^*0fr5Lb0&8=3<#=?2V=Sjy0S$BtF0HR%Y;BHgna*5ZbD at I{3E4hW#O7N
zruIA8fiCXPK%4d3;L$mnlD^ok9cIqDC3ht7=&>hRWHw&ZvxEBkT2l(`xiPi>eJ^qC
zxKMjzL)QAtif3lnW8;5S^JO-Ds257oJ+2#a>8Q80hL~w0zG(25e(v;=YW+)`+*+Sr
zc<<zS<JR51M&M)B>lCkM4J$bSdw=0zBmvu}b&cme45h4iE5%g at X{C(Q(T&&#v;0uV
z%N1GJpj-BMOv*q=TF)R2%g(0m4XBS&biF8V#G_(dtg>!c65T$7Vv1w>K5US`AhcVc
zm5u!E{MmFi#OUc%ev1*~%Z^JftVc{-UkZ&?NQjS*hbh%=s;(T9SBEy1y;Jo{d-&Fw
z@!sRVS~8O^oLY9C(*XdUoihYzn<E#yQ!;olAd8Y_lLOy_{AG`G^&%aibm8YiLcEzm
zmRzPyh3nOx&)(c8eI?|I{98-Qw}r%nP-A32)T2hL#%EtUeZNc0icyWO0r2xL$ip3R
zSlDY0aB?4tOidow*w!iH5tP~2^Ct~RXzUE`_BZJgiRt#eQ29O{1I0zrK8kpFx}hVE
z%LBZP<~K&h0n=&%6I>Bl`}pdNfxw^ZWTbFK9kg4LVhGk9%1o{6nDra_;s%3UOK;eE
zKV<{OGhE$xSii)xn-`nJ=gcrwAZK)Su%HvrGIr0z+s<^fzt;o}yoUXvriM4f?dptH
z?^;@J3t6>!;e>!vJJqzZknWN^o3gn0^=0e6#@Ft6fn7l1+1S`DI}CpqN#{@WdA!4w
zKybDdC9<j1PV&C4Xng#wN%z`^YmnDfyYnQx9hzt5E91DlZ8xQM+Ogl at aNBf!a`|kt
z8AGo9$?IrT`#$qJHkdKPqb@@-^BGSi@{zdR-IOAf>&9)%>PCN7_N$>iDF3_mJ&A*8
z*Gpz+0Zz5$t)VMj{+r=wy8IJ?3XTzt1XU at gbQxN^<JYh(Lph5aisjWeZGH7P6qOt^
z#Oj2Tq=<|{$r)`Yx95{;@N{uX- at BBE@~Lp%<l+p$&)0|AXeJdw!*2jP(`L!*ehIS8
z?0bs>c|3A$x|ozX6{r~IUaR-(zFKYRZD7ndH#g7v{X2LtmKJ}zYm;$gt772_Z}ea<
zt^OJo>)+C40<zKP=F-;IbO3mq4C_5%4P16<d!6?Ba}q1??Y=Ki$b8$eU(r6+&~{l?
z7KuFX!Cs at zZAkC`3A-1O#lo1Ek<2T?gZ6V%Zq}t7S#se`!(%@dvsUi}m36|yI(14q
zyh%hCM{8dVqtD0=Ce=61bi3 at B<A~jd<*OA}y`z?MdBZA=MDQVyvDpUvzYn`63ra}<
zkFw^{Vte&F at 8YA++Q_<Y)KMjfxV<de-UE-li{d?Of4%1PY$CGiqrrwHpTrMbqAfvW
zj$Sk;8Qz<Cx%W$V7<*AJC8*6g-1hCTO9Wx at hRHgCWoj7J8!S`2?{V<qH2yfzzo0k(
zSbosEU!1#{i1ZN?AcGtc+k0l`msCc#;{oH(45+{~KpR|k+X(mC*McyBzHk0v>JCI_
zPM(I$__)M9P>=jSP5qVpfJOXr7f>3~U02;v30PptI03)h{cN+#JC;^q8{PK?E>YXz
z^KKNo(YrSdvI<$b&plD8-waXv=)$rU1%{oL!-pEk9j|kD8Y at ozc1=f)fsK!rn_iIH
zvO6^Wi>hjTt*2en79N?~-ygPe$b*nfW``&}9(G~sZh9Ymdu~N2g&e<7kl)r6A-^q%
z+!!I&2}I=lx?}}z2ivOSx|&)cr|{h5P3-(*kS-i!mI7Xlz$c8(nkOEQxyB0_V>bx#
zQ0>Af9X9T4z`}$FS1*25;{jWTih^J-ePLP`e%s0G0=d*a{^J%Ey70tQ=D7QcoB9V}
zK>i3R>A at 8idbY!WU-sB9dx=&3Rw;DYjFw~r;4Ki!0Y(Uq at ZChD8vvA1S~+jUQXpnf
zM}}2b=>HRCLH?0n1_L*z8x4OR0fx7_&9%`VNgI+AGa;xI5uI6JP+4u2TvZzmBt9kD
z`F+J>O*Ygs2W~ewtTK}&3%uDYyl@=0ENGR^J2Is--`r&k5q4|2`Rq!%5s3(k at G{Ya
z1X-`Jj+9R4h=(=;^V|Jyw-CkV at AF;7^E!ZN7%Vbfpeb9>YtIbz$$Dl$$9oPTUR^<B
zm!^NH2gGFZ4x$rxJnjU8brX;Ud4M`sLYpb(qKwh+NtlUrBOHY%?nR86q0bRZK~vMA
z1MDD;l>z1yMtX%F^U+eu3qdakEx`S=7BY<427v{XqKVbHN?LY>cxyY)sA_v2){SHe
zlg~M8HrSE^<FTv$P~=+Er_ at lFGCB)jk>SMLcvq?9UE4fw0qx`D=0ULrg}EgPg{kp-
ztUO;ZkY5AhZ0>u%3jyTD6ox5VI0ewRgb|zKq9T1Dc0vtX0K|l at u3S=5Q#}RHrT<my
zfvzC^=(6gk!VEIFkHm`gIyj~s_Fvu4wwrIdydhhw%|q_`66}(?PSoD`!b9PaAZoRO
zoBhb+zYoG*>HJTH358HX`IZL<zXl&Lc15{(Q$QX2^QT at 5T8F`2t6TGPB3;i@??pab
zSVie7m&32}yjwVAz7O_Ct=GCQN;{bX?~e~t`e&ppx86nV4_nOJBkbUwY7ju>r0Jh-
z`h^{qY#MB87(~<!`l>-B{hjro093M%E*)#7NQhG;)C(={A1u!Wil-Qh)abFI1G}6&
zZ&aWxDy_a at pJ;7*TDUU;#4UiPa at 4E#CfE5h^5)onnf3mIH-z?IoafZLJ&#E9biBrk
z+W!GQ?*ZILkV8iae5*#hNta@{`i&|+5C$6bIcJuB;n{?yOZCAyMc?E?L*X{bH{8hp
zZtK5vX6FJv59;3ll#il>*%_l3CxN1e7F-S59!noiHp>`X?+tBe#xTWzmrdu3|MTaM
zZ3E<m=$&3fsBx&Z1Z*(zWL|NTZKrR^X^BK+c9OCtgME*9Brcs79wtB;4@)Yb(VpO?
zte>Fx`}Cf6Il++58O8R$a%8^NL{>lH%S~9meCu)7+nlfZNrwVGOU-<Y_i)%Bcfu6|
zrVcO!D(g)YK-!H_FZu_zf<P6<JOFeDX){MI0o4F*Q-=N8ST1JW?%`aJ!)ng1$Hpxo
zTXkkyxlf8#f-jnq4M6}dq|1Z7*T6(ep|tURjWV9*S49`G_6ZXXkbGikXlzAF0<+!n
z$|_R7Jxd>;1N<rFDu`o1CcSlbKkH}8h>P=;SHi(v%}c*dCAU<2xLNl-XZC{L$0<|8
z7T>gad7oNyHLv_nCewxHbJWkxx{w4GW_W}E$hl=H+}8-TN~6?iPs)@X{J7SjpU4yx
zj7_U?iFdusM>XeZqzO#I5{|EME at 891%=Z0q%-h>j8h8=d-31#yU)>*{Z8ubHScbZs
zNpb$LD72lQ+ge#I?H2b*{}v%$Ca7_?Fg21jK>f;=41!NNdJ8*@nDP$kP4;^f4o+ at Y
zt1)S4K#OwIkTG8RY+^8ne6lE4RkE=r+6*gVzcW%x7E4~~IT2U0k;%-FZeZm3Rr-Q_
zSLnYA$jEg=n!jor05@!ahWAbtYswdW6AqocGpj2}Lq9x<HVr=aUh_w&ww%WVKP4RM
zFX%uTYHaon{W<2G2Tg0J&;8ywngT$+x|B at r0iu>gpIm9j(TGgR9YBom*GwkE96FvC
zN9mv)_KF*6oK%qHs}*Repw$Zw?yir%L|(s+k))sI#4kqof9bbXD&akP;nw%U`8jzo
zAAx#a`>{f5THiYTJ2yzSC9Thm^HVj6I^kVCH<q1UpBQEV3pus=^Qb+Ea>A%-zX590
zm?`Vm+`3P^c!z@$%TE>v2i)Jq@;fc)C6)M^bh^U+)5Wnb0Y#dw)%2F0G at V@<(50Gf
zfLf0%Np_A;tDP0A7gee7`IWmDgtmmQN3T|@)7gQ0{&~7W!d(-DI#i8J8c2gf{2^2n
z5uLi`Ml@`eZiyzy%p%mLj}(LLAxig4c#u)QHCwnm6C&<wLc*`q|9pTevGl}G3(3X0
znOwb89bv3DZF+PGs#vCR%I~p|s}~MzKL<<G*AjP!5s2Pyswlz*7~GPf68EO0_!Nng
zD^^*cmCwl&ST5T5%l8lpnd%KCfM|>~H9n`#%rZO-aTOy{6Moa at tV4{$EK!{IVP2ed
z0xeU0`lrbOfl9SD<!>OoeUFI|plW^;oWH-zC at 5_C#dbl&k~IA{dcKN>pt8ghyMiC1
zLfvkWtJE(+4kM3((CpiD8;M$b%2qPRQ2l(;vef-|HH5H=Jn#UU<z4^hxF)f_?$t*0
z at RG%GK6NFKo~rDt|Grl^kL}E)Ono?e6xwS at 9q-rhhW)me-1F<Cn^v51(L4Q{A@|xl
z6%8_lbt8xU4jw>5Cud-IH)LoL*&V}`EBy6icd_bxeK;3Ud!l47Ci2i8)_VqRkV!P_
zC at S*X{M$o at uc?W+c>T-qFf{+xwucte^v at eE!~PKVkmGy*rSx^gx`qZ7U0rz)-cmkF
znqFdWwM|Q;P~P?!F at f)16Nr#CV}`4i{-=qkyJp&2{d&i&T8i07R$cz<_S~fbF0QRs
zh6R>NLY?Ry?vyxbdl*`*R+cc%(8RxpWEoIgX}00_4F5<Cg at NfYV4(qw;?<~{LEp7E
zP)4 at p!?rtH0}9i at wSAD5XjR|V)F;)MFk;paCr#=IKWSmnjm4Q#uqjgRvSDPhY{ABR
zPAVdaiKU8Ojqr=`JC^J<jg-RtBE6a*AVULa{K)M8V6Vu*pn*g{@?qM)%;#`*rA at O_
zl4ds1_YI7IHCsZ{1avX~c%k5l=|$=N7G9qE at M;?_f{!-5ypU_4y&B08qWC(7M6*j^
z&Y~Ao9Ci2Qk8;=+(e7{g$#SKB(4<rOH)w+dc>%e?x+j7 at Kd9F*Px*IOOR@;?-G#pZ
zZO3Yzq at Y;}2sY%u7IFTPToXrG392>0=H-g8G2)lE<y6UMp}_~DT<=jua_HWNa3BCF
z!kvL!gDXQU$JkP5BGw^{09Z|M_pm8)7Y3=g`3F1r|A=8=AmK3On^y;PsX)t%(2lbm
zPj(4%2sH*0ssdm}H1^wCzz7{EP-(;-d*`zC)L37)Bv1K@@^whrzC~(;I6Le?&Jx^f
zijZlpn6lRzXLtX38NQfCb*4Y|qXZNSq at 3o)SqxR$A6b>82zFzNP5li_7p(D?>g`Da
z3$8#iTpZXn)C~U?0EpbWKS)i at XY>Mt+$0_cmJXHupIs*gN`8+72a+++tY-NAuZv);
zXZBAvRq6B*)H0=8ecAD#mwkv7iHjloUoXp`m{cm4N;1I=wMm}SOJWDShf_Ba$hCtY
z8(X37e{WZX$kM0(y(kyXw1g#gzkWeke&L<_f4de5ur1g=wuNax>!{1tS+D~r=)`d>
zqITK-D~BLKigBllk)DmyF200uaSKxu2cwBRt^Yr_inh{*c+MG#N at bGY2se-rd=7X^
z1XP0mUrRxPqSH!wBhD)^ODKZu2_`^jxRa+z+&s_hf9E4A4t1SZo99-7O2+wBkk~Vz
zfP)>8p2}{7N`TDq|CivK<3*!1)CHtal(hm0`|X2rkVq|>4F7k50VbMFzgddPp(C64
z+4d_05gP-z{}L%ct_!nvmZx46gvY39R)Ap&0GRCIf*aWX&O|x|8}s$0(8s5;$3k%m
zNy|9v>+&ONI<pl0eRmr_RNM$niTA?Pg~yl|nD3_QEV!Q5_uezD>M2~W%+#-}xI*t;
zOd&dlB{ymO&(HN&D>F?;J04zX_eXne<*QVl>ut^Ft4Dj6v0%At$WrsU<N4?I2G?3U
zce`OvttXm;h2ukCfADDiD%Eo-c(ng<^-29H_1$55<gT5c- at n~gIOXEcvT-j2K&u^=
z4i{^Ot&w_?mXg@{Rqv(dR{kYdSIE+mi`mu6icRw$U-kM&o~zc}C805I#O%K657sm1
z*HQ}L`>9I1+vNu<U)#;r566cJ_mE!-8=ju7$DZn|_s#c?HHEDW*LmRZmImRBcH}++
z?K$dbDGcYu(mW1FNeG(6Gxl&2AzXxL`!jeoHP9+S{jwF(dd;8qdz<XLt;efB$!6xk
z0t|lU?=ayxgWyhyWKk^*r)e2ht-?MBt%{*3#qLMZ?ey|wQDQZ|lc!_jTG5|EyZERu
zV>AkFnIbzPhkChsud3ds at u>=aQ9soJt0<(OXI!rwueKXJwpo=Of3-5n+FJc1$CZ)5
zSIIZk=(E#iXwt99Z>n;b$pQ6}NsrIZ9 at Arp<5XVZP)?vvoaTr>a?>x>yi$z#m`kHK
zspWgq^k=O>DDT-vp at 4GVBeAwcV7lC)xVa5}JIgVzTKnDwwbm+%(TYf}ApeM$FBU=Y
zaR2jlS-kWXPt5zz|9<t(Vm{X_$j0t|aj#mH*#2c{>a1hMmo9BqZD2Z8L~=Bqs(UKt
zeV8GEUK($CCM&19Ym|AL<8#PfLX=oH&0HH*Cb~Y6r)H;7#B8Ca#!zw at 6ywnp(CYzX
z#aHrWj<^E9>5G}ij8$eKdE*t8#{@(+o_TYRGrV96!D+++4dM3mS5A$F<(9`HHuLy?
zX0=Ky&D?p0&kxfENXh=&nH2em9a<kK4XG;AR+Go0_M>ddC_}s^%}m|2 at z7n<9a$zw
zy*;yJfNM71z2(dQvH-Gm1}Pl-0Vi3U9~tGit=Ef7Icf;gp+pys@$9?36<!IeUc-e>
zmwI7wXme02u97b{BdV*+9P?R%@}`#(I&HEGeaji6%4*3O*Cq<nS{XHY%@HFUHVz-S
zBrolr=RPoGIz{{3e$IdDJYFfVkG0Cq1U`Ck at y$bc-&FYHqVdpuQ}x-+&F=xu0~>hz
zREZ5uYR=>@#>z8A!l3C`j>8t0|E>ODt{4&hF#DyaV7zngg7xgvZ%)&@$F`6hMc#Be
z at EB@XW`cj)TAjiS`oVlfg=c^IACofWbm(HU(I?N4WSW_ekaJQ6rDM3cy|Qbmg)Xwk
zYu^Wg*2BZOeY-yYa-X&MJ7GPijH_9r$FWQw-S&rDRnFdz72dm37X^h!<5|hOc0vxh
zK6mxvtxsJ)n7nr#FEY#&F2>p)TAtcHGM_f)bn|H6vXi!WwznNe+RovFe*}Fh|4QC=
z#pS(|BB3cXo(f*dHu808^*IXoJ*_v<ev?pgDVO-xd1vg=<DB1amNPb^ZF at hXKz;fA
zdxQX#t<}M#RL=`~dH457=0b+qH_YSuVD9>P4c~dcc7j at 6K;Ev!S}Au$=8t85A)M>M
zoWkSQ3ZIlwaZHB&W$a}v^L%bU8nO2_d&3SQ#I+(N6g;=jq&rQWD4=ree)om^W*&N3
zlbN=I%j{X~v!lsBqsO1~d?v}ghkjgA+gP1*?0p-1frgK+svvm>sHAB=TQyWB?k=-O
z1J&)Kkms0l=auI>t;b=ooGPlvAAK{0*v^m7H?Q&cE%0aVy3fgTm+YD}pAQ5BFV>mc
zrG-5%g+3_EU0hxJ>bAR|OYJf52DYssFM2wa4l_f_w1mH<3poLASdsB3XUnwU`sosS
zF-0z%QxH|`zjF86u3cHLxp|uWVaEH<<^tp0C8R}{obdW0Uhn_7dJC{7-|v6idV at -d
zsB{PjD&4h#igXFm(nvXa<R}#-gn at LA?vl=dNaq+e8p$z6NRH<JyubDF_rET#3wE*R
zex9BCoY(z2ulw9*mk%!1Nses0?bTW@=TSI^I<?q=r2h%n-t4=hYYoYHXg5h6%?A!`
zl at p22`nBXVZN(Xiii(7Wg{w4?^=}t0b6WiI4xZ~l<MQpkU`glSf0D at +i&FkEhV7~Y
z`%cO7 at Kab<F4wfCiblh!(kV0F_ZB=xCXb$)upwsRnd^w$k at RyTtincD-(HMf9huKX
z at om^)RfwHhO?T=obJE0&^7VY(Sb4U_n_912V5k}CGN)FtQ5|Y>_X2HtXYrXQZ}UtL
zrFsG1W4YeWksk83o_&SksHIEw&Np9zx1ONJomw?v=zta-siVy?dc*>z?sA0lpf-#T
z!+gceH-eYGkU%abNM~aFm#YpYu=C~RXL!pEKJN8#Q@<AfC9F(gK!7+V#pF=<;*U_*
zX$3wH{|`G|p>CePpQ at AhnOdWDZBF_*0*mvUh}f`V24!3wc3Q$_fzWu!%v4w)<TnUG
zl$%a^Mz$PLmt&6i`VU*gjB?-kAHlZ#CRSlX)Bea)>TS)M`hu_oJlsay$L4iR)a8*h
zPN8Kx^mJy4_hNjj+ihVnDOPFcY?2Xn@=0r9m(vsH{0zMHRb!YBRGz<cS`&#I0#mPV
zEu3r5UA)8KE`njOd7+_EG{Lku;HcR2jn2VgbFR;U#^oN2an=QKnJy-+BICT?eo7(s
z;52F{pv=U1j`J|CwIUDWzrTMdt2b~Ep#|I4lTmAhjVmr3a50akoiSxET&)$mjq(M^
z2Q=swE5d~S8{3uko_^1Z+T+%9;*aGR-5wd>^^B)JAtEmIet#tbA4Ant6}VwO at QB0}
z%~7w{U7aN0lEqqIGoRP0)MP(@*KRX6VwnF`1c|t8qw-vrO_$8*Eqh`-owAXw06UHE
zCWz2Q3Ii^`sxhB$vpIOsc>#HDTs#=kl)ACjUV}J`B{{5Ad8ETck5}|2>iTVdfyJU>
z_3sy!5Awp~Pv=_SjjmGj;Qo-+;q#D at qx}R?tti~i<+=RD&Y4XkZcVnajuuZn-(>0;
zsQ at DkcDtdMsmIIdt-iWpYCLfl#5R4_R7gTzI}A;gAoAso{`)v-zd1k2MoR<K^jn-p
znZalrYO>VdxX at 8_!q~Xja5huS*kIj(8TNvNy2KW{7<h{JEuTO3!p&z>ZHYV8wQTpz
zHTo7#FcKnl(pL8cxbsfSTTdx3M)A-6mQ~WTD9-;R;887yg2p1Y+M;+!mE(tT?=ouB
zTG^{JS<m(4apkj}dX3hrPI=R-$;^$siH)1Zr$5OkY)d}~r>MDa4Jy=}eST;xVKnOF
z1QgY(Q0MqjuS*daCt6QNiG>}zP6r9|nLcq!f&U;cL&Hv&Bc(H}7b=<FmEzi$pZH;y
zp>gieh|;SAz6+JBk=FnEHMAX|C6Q9Jumj<zsn)N854<<X%d^uS>WjC$`fap8-|TmZ
zuyUAh58Z*}jEner%wkmdws6!th^Ibgt(WL`JHwWUOVGv9LVp~F{-5bS_<5-0Tc_ph
zuXl})Cyik^X9HvjdZpIqV5rGPvhqq7i8E$HZWMt}Yx7O>y5Tz`o~_G6hvtQta-l?q
z5sH=z81gg;i!Vm_h5DPBX4hR_lEJRpT-&Gn8`EuO-lyg*(+#@tUDTG(9iHl9CeA%q
z+#&UANW`Ok1mg0GUt<R5Em|0cI&+$+p~B$|veAZYR(N?!a0*VJ$4V``#4&bNYr=lu
z<!C_>M5IPr2mX!q?F55Za-Xl9%qfq?I2Ae57`3j774?CRO#@5~X~N}XNgivnA=1Fx
z;8xy}Hz3kOH}|KmZlf!(rVM$we_FWv^)$JE2%`rMkSjKA*11|k?O+V!)83Z|%W$OO
zcib>Xfk=<+5(eBHbF<0L<qI~Rt%-m$4ByDRbZCCdzFC#|ib&sBL60E34`w+487wjk
z^u2%-7wJm83)tD4-#>^cZ`2+~1|R;+8Tsl16$zezR1lJtV~TX+u^;-BW31C&859g#
z@=cc}Y&njh=;p4bqz=(%%ByNT<5LEewagI^oBTqo=-IofUN6vVj5Pev)B0$zF!fHp
z&(^3x00nkh{cH_g;l#9M^Xu7WN_Fk%^raSvD%ntNwE9TdW+<FZ2<dNnNM!rL+j^^0
ziv5zO-#LJu at _}A|Q3|}FxcyA5h%#2;Af7Or9f`dB=X4h*a(aS~SWkq(`j#Kn7%}LS
zGvVJ7llY-x9_7$SY~0~%exY}e3ll|~&UtGuc-a+tUe1#>dW(#HP1v63LnrATZBDev
zdg8JEJC901XAP$Z^t{8%^Df2YYC>tPd<hY1!gEb;O>2tBn0@~cU2HEoUThF#6i`OJ
z2Q4?@d!#W9y?#y-OukNMV&T2dOq;eZr6cgO48IQ#--J|_X!;ShVBI$pY*8B*r;DxP
zEIiyey97RbnP#a?k!Bu at _cYFdI}1)yI(ptGAL%{OdAioxY~1RrP^Jf72KjC0(F;$7
zY>K!);n_sjfpdom=YR4K+iK*Hi#~ih<#w^-z>!?Rw7POm#uUY>z|*-Vh~L7V;?+i-
z(`aU6J{O`|;V?=$a-mL^*r~<X>1171!>@Pzv<AC55h2s608yI|;4qlHDKcT2cr!wW
zI at 7to202xOFU9-{ibX#0n;CC%+lLcy?F3cf*@hfW9;-&|AJyd|^hm_3s$K2T#tF_H
z!_jxGo3AdW^C{N1=X?$+_;&CF8BwiyQcObhhr+U&W}kF~5GV`NvOn6GKbf6=5!GKK
z3*R`~o at mO~7^7%$Hdr{KhMZ0ZcvUc^>lJZAU<<}<7r|+7FN$T(KW`^LXguDVqhl!3
zF4z`llkD0+SJrA^r*|)>clz&LfP0M`VGi at A9_O^`^|e<X$r%4PkS6Kf4FB5`N3z}=
zsn at iY^xX%i?8;k%p$;<2s4v7wCw at +f!<OA03fMwwp^$l1%^YYC^3E7jhWhLWjVRl4
z<FIe3t&;>?vI_Tl1ctbRDXT)W1m0q5tVeM$J8MIEW3hEULdTy&TOE=5sk~*$Jobl4
z+sLC)*in?q;r_xO-?@V=61uUsew#vdc;Wy82P3U04C~~lTz(GV5Xu-lk#6kyS}YRs
zP_3}_^7r9sXo9p(z=4x#VHm7tyAj%Y**SBiuHd;nj`Hi?KNyQM%9bTQO!r@=^D|76
zCS0bt&v>>fDzsYUrF)~OtIxlv9A5eFkdxt)F4x-A$0HX+446|JC0yF<MK~BzsJhr&
z2wo3=5C?2U3~GsS8Z{Ns>!{^@(mjl6JrKB9sgu_83|Nj9HXJ3Ex%5Wj_JehF;MQtY
z{%MWqk|MF>M at mJ{)r#Fe=p)1$7n1{FUBxX%1Y^;$LyWKb!eJ<}HbhBhyg-+OvBh}d
ztc~PA<qFg9{`;r-MQ<q;V^fZ1l-_BIOskyOWegVohfnwvE^|_Uxmq6Zx)YLK3c1{`
zsxD5#LB;0s#9Fq#2Sv8(UoGqKjmfpEQf#)qlR2F+9X5{BeqiokU@(yq9>rDN+3L_(
zE45}{T;q2a<7h2Z%DXwP(TcN!okqNhK`ZWfUnv}3q$55wy8$I38#cK8E1dG&Q4-`}
z$@HqkABGh=q`unSf!GO-lq2z at r-3uweMC3obdZ{kQka`{3t66}(i%Gf`znV&(Xyw1
zun~5tR)%Am7n1=<-K+hkR-<4Op>d}R9QgE?ecd;JB)8xVOV2Oz at qtb!#EmTFZZi&^
z8$R<MfsQHCJ%De;p5<ApN=<mwvCd6e4nBhXS~>~apLBO9iz<UC at EIU`>2S&eGaJ*!
zkWDv?$E+9ydV2nVNn=?xv9(roVTJ;K>T?TNf98WN7OEjWO=t2c<y(UXTe6i-)yP9n
z<+C+a#GOIWa=&korsA|;*?tZ(ABMgtv`zb0Bkt_Z!X{C-(x#J!OXvl>5#>#@c*ChK
z_o{{S!3F!4OMI&d(nN!Vgd{n9;=uHBljCB2$F%q*-_C8ay#R+ at f?7#y1Hm((w(R*}
zUbo6_QBNEJdbsbtY$rIcc=}AR&_0&$P~=UO$!G6c^TE}IJ#!6Y<A_`3?j?5u(bu5P
z(;JDZqRpra3vgr(58lXj7$teoIYIE-6Trb1faO%le_^{Ovj4r2@&zKOv+=rAnl?Sr
z3`_#w#)7feDtZPpTrcIz+O5~E7=FtK(N2i7)+uY_$Hbw$K40$ibHE0roY1xtigKBk
z8E+6G_ywVL$YUqrwD=+wC2x*ZxHguK_W?chO<4lTHZ|Rm5FjaNJI-n#ip2(Ui?k%b
zCZbaGkLXsWlwM(`EmUihy9d`+GwYAe&+ at C3;h5ryZnI&Td8oV&+e0u}a8ll=vRZ?A
z4*6X&SVLvr1khoE{z!Q8jeLw<1CwgMXqP0H at TS#sBJf~DiJhop_3~G~VH=ZoIIe&V
z$+;;m?IGW-L%+AA80_g7p=s#nwDdT{N&cBQZLWt<V~6#QL>$EFkYP%x;Lf|!)>0E6
zFU*mwA4lp5B%KU$b};lM*waBK79;%@;!_L>C at kHoGGDNz$0*zUn)2dM?KhO!S3`|c
zTwLTAa;w1Q*_1|_<`2tGK3EqQ7aJNFXimgueW*R&D|@+pdZo=_eo+I832M)3k2WTT
zLId!ntu2l*@3qh}{sHu0Xb=h5_iESZV*~y{!`MRK&0$-l$*<lncD$Dpro$Z$ucb-f
z^2JUpKUZphiH7|nXw at A+IK#^aUY<fC_Q-<Cca^*mc8TR!`c=8I)t8yTPowydo%X1`
zQJwBvu?@oAj%$l*w%FfZ>#mbr6IksGnw5rcUwto=H1t!9Q!Jz`qaBu=C^~E0e;Lv|
zI5}-xJ`{TjYxjSAcu_Kvk)VV$nIxfKo}G+&TOPnWZ)flUqoXnLuGQBdJIQTvzQz9}
zEq%<PZ_Ftf4hi-fO&yw^|6uP%2l0~Hca=Po&u at 0BZSlZl0@c(tDLmU}ZsmR)6G!bX
z93|yjj*N|IhY9KLdB!;Bit|0Us+LtJ=WCb;rv1f_)N0`b87-S%f$dT$<zInA*Fp_W
zOdCRrnI<#&P!5pcgoh-RDAMDt6aVPMC{s{-CP$3>v;m2L4-&BlN=P=8iz*MyHA?Yq
zP`7Z0g!Rr20qYInJ>gB-ubPzL-RbdXCTH6I^F#agSlYV%%WZ;nv}5D;K5XuAM8M~;
z?vRwi8V*XuI5K^L;A6XvGaEhPZ6puAqHw`Sgt7jdsgkjq-PRjeQZktl$eA|b{r=Mh
zvHT`^rcl3q#edf`-$KM48*7Jrp+$grjZCZC{9<$F7=stNf;IA<-UUiZ86zRb!5|a{
zPW!L4ruJ6mm!EZXs)JyPy8D$dynTvg+%4;ZJ{0;tSz0u^O^mQwX=9mo+$v1>c8-X3
zQITOe>6^H|{pISc|4IA*`@Is-i2+Gy$@-zTy3NKR%)xuDL0SkvoagyeaaBoU+GTwy
z|Ihnv<TsRSZt{JS6xF+CCQMhTw?cPt_SlBw|L*+nA44C7YXp^$S#RR0=_0#1>4X3j
zlhZ8FTS*S@#^-)BSdo+Tj%zwT_28-jGhn2X?DGxhJj#)P3^i1vv5HXl2$(6Qo3vjx
z5iPbBClKUs>LeHH^HKZ(4h}z<=)r0Gf>JO?g(hdJrCUNZPE37=1ZNW;Dd?qh+16;`
zk0bzI2}v0WC)3g~Hop=^{tIa-9?s*QGkNd=SGaS4=rA5{3yYNFIQx at uhcLXZ2A>Q<
zsGVX=()+}@rA24)%kf#^qu=6FH5wll9hPghfYDLzMRLia^!tO)c|7JudzHPN>V9-8
zt>qO78Mp9{Q1}nV9B>7=hn0cH^rA#4dTTVi;i=m-sEHcC#;*`2Tn#b};$-8HzR at C)
zc1XCrmEu61<jp>DR5;t;-cUQ5<gA{0XU0&&W>3|YDa#KkTC$~pPx_H|;ZbDs>gaa*
zok7}3pdp-BzKIik)M`Usb_EQH*no>NL&pa;8g(1c;kEDqdrwPt at 8cZrd(c1pC`?K3
zVf}_9a at n+1U8DZ^2J(1HV*+wHCw1_319Vt*y2*rPw;?bH+wtVoqz!$kel*f at 5}g#d
zW}b?2<4E-`EIypa8{{>X>F9K;d?rNDgK7X7aSzVK`k|;gD#jjJmaIyR^Y{DBvrrh<
znK{w*c5A93OXe&|Y@^tJy%iUK+PqAe{Fm#f_g at 3#+qk}>k-fc2>#C%_%2Y9HK$eWR
zN>=4~-akb&$gL8XkTaU&M2D-)P4Zv%G0kRFA>q`H_rhqjyevOUS{OYHKEvm>#QbMe
z37&O>I&C2(o=*Fr#EQpN)%6Ab<(xX>pnP7XXtHN1stKfehy6~zU(1?TDv}5KsOGCY
zvETex)yl_Yyz$KVoe0vg{*(temH(Abm0UNpbo%y<F4|sL>HM1nKO8i)w3bZ!AkOeX
zFv(UlMOm$s;}eSgrL|gF_c#F;Ie%{4=)AD4E-N41S2U3u2{vs#v%FF)Kd&%FtBucB
z at df`UG<uT~tijKPl2o<DHinXDNr~`t!ufG9IbNOISnB$aMwJ4)7)<Rx470<%Q#&rw
zIPcSl*=7)K_LM at oRN8=m6-i`m#(T$O`|->gR at A?o9=ChJ2HSbp@~%lYUfbfagY|F;
zH_rx819EmSE^|!MXjhr_YDS-pV%N{f=K`FHng1|of7Cq4_M?`W=WOl0WoED~d_8JG
z%;sP^vi4sufNrRYV=+e_U4$sZ8SGxtAG1S3LoMK*!xuirg?1kvdY3gC@?CrLptD)P
zk|h5rtkE`eB#bYy5TlZr#NKW7*y*6XJRtXI+elN#Nv1E_D#;()ZBovBwbPnEE*MkU
zVXFFnmaYT?Dr2On;}|`ujz)gpe)Av(QEV;BKt3)EZ&@rx<m(w-#0tAAsej+C2HCyN
zQ{e?&fshvqex}Op%KtZtYoFEuak6^;^L{OZ_%z!A(qLHtFYWkgY~3AlcD<tId3t3z
zbc`YHu at l<=cTx1)m^`~`DE0*aN<~GEmh#aao0FO2<KwlTtmD^T{DozyRq{8kWT-5B
zEV-Jp?dU|*M%ViO_+yKbR=vv>oeR*mZe7gWf4!fbA~M#hP&Swx2b>NVeJ_|)eD6q6
zN%MiBk<l1%0IJ%D;CKi_s=<?rinK8`Fr-PHK#Wz=x2$0|NpRcJ-vjkFSoZu|vUdt}
z(aYv4Z`Q)52l%Tjz;bfzk|!>0ljVcS8Ar;Dn?yxy&*!tAHl|pwd6)IRA2DG;5B%qY
zvP;zE*wHbHJHNmfLE$Dxl?g!IIlutwfW13zpAP$vjV63mpd?k{G<Elbb<M5mn&SO4
zo2n%F>?n`z*(thL&@NSDOgCP{$%699Uyrx48P`}=6L94Z-cLe}?d`cjdLGDSf>79K
zJhOUlrK-DeaT!EJExVFiBuRCxk9YJMJt+|#d2sTe^;~XJN}eVHO9z)PDti9^J}faj
zX?$GA7^qf^b~Ef!9Tf&<mabGy2Lp%6WyZx>Jwz at ewKT>HfO9N7Dka?g64NPAYe2cS
z7aesLAM*ks#H<;#`YKhe3^*+R6L(6{P}M|L4K at zc{?QJnkTh^X6kG6Nr__}`L3JDB
z%s<?+kH{+K_0Nsphs}6=S<u7O^i_`83V(oF&=}bz=OIzMULXb8l>Q{ZWdqw@#PqV$
z{;wkXudP#;gUHBY-wFifjaF<+9m%*``W5df<;|~4OrK5aK at 74T6l{|7?Ch-bQcwI7
zTb<|(jWK{nZ1P at v6Q2vfY9+UdaMgcMO=;+5=Hq+t<hKH!BLax7oM_|*pP2*`4TfT5
zOioGwaZWPLBf<J8WhwYCC{%KF><w(YO!2dx`#yybScY^2yi?M<1#JJM+Q(qMA&gJ5
z{~wF=hq&Cz0g5Efob*($&kU#*;0?z`9d2W{`32i;$?UAHBPBe$)TFVt)&}u*=H at Ri
z`~%ATp?`Un(h!*?$EE-C>*33qv8Nq01EOr)=;Ph1ceFa{p|o&$V16CAk{Wtc%Q2%s
z)x`MUUU_m~z?$Zt&~hj1kJ>utGcfaymAo1u13x~vHmisCxY6pDS&OEr>pb}S=+PtL
zl)*K4Qr1)Lcq_=H8~Cp%28f2gCC6Ifuvbr|YE18IVsZu at k--N|-NI_wH8r8hjpCPv
z#<<Iw?U)Unaj$?p)&Bne=_*f6HE9iv8E(@&ya at Hv>_I`B0mYG}r7U2^-6R1?=|A((
zD`7v}k^U^ESJiXj%ICCcx7;?KC**O2JbX;ChWr_(@#Wibv5jRyv#PhkX at Ey-HQ`Sr
z?xDsh5zso$>!OP1?lu0^&ee<y9~(PsLcF<B^?!y2eCAz{YIv70WA%^2zV~cuDQCi?
zOQK~)A0}q&rV>8Ps^)U*{UiJ3pKJQJGx~pT5Y8MbDgnR&{LpFO;LPu#Tqf{}O(BB)
z|Mm0XMBJ%FOa9ZlJbdIi<MLLbX<-9T-{nVI8E6=sCCIyjb+XHZ<K$~xX_WSZ9>NoC
zolgiwMZyf^B6RRZHX(c{XxvDg^RGZ>$Ce2!8^!Y8e8018v;J%fuXB{JW at oLIjkZ-I
zj_`XCoNU?0zB<JOl%wj|DVP*VKOSK#<u?6S&$AbWz>^xwW|l0i49cz?s4M|UfOi8g
z@=VG-E$r4z%JaGVg_$Dbu-<~!e>s)}fC9%(RYg`|Bq(%MLVEF~8NVJ)N!jzctDnfz
z%?(bs9}-!rNqbB8!OMFA<=r~LQfC9gYI&}eq6$K6HQXZ$ji>+GNG<=Z8b{0#9awr2
z0Ak3izk?+jy6|I4wMe;0ew0dDEJar<W_euIoky)pXt4Ij6VYPB+Bi)sAlTa%-;Cm_
z{hT2GD&cKr{5H>4y%E+De;Ek++Cn2?iw1Nq(_gtP!CUbG%BGVd+`748IXbSF*Z;E!
z-?$Y at do>~D=wABn4G=}6eMEm<&MwgeWa1vItj6++qlz1<H8{~&Q6C4PWCPzTz<~Qc
zs$x=Yi2zpsT%h;+Ul*=0#J&yfvv((RpA;OF^-V{w)BZQSjt>B=svPsyApV`Uh~i&%
z?VWNQsJ4pMXs@>u{UtbcN4V;3lSxjq!=oe@;jXv at DZ76+>IIVuxcjNZ9sar#yM$PH
zQYmThmSVgW0O5vA>cSF|n!JT0ifZwN=t5(sDia~i|B4<R1Qz;F|C+5ekU*5yw7c5=
z|3|SEP9<l9h#QSPjJ%LD_BY5}G-I*TY(Gup(D74_qP=2<+F00Gj}G{5P1%bAjt;}i
zJd%q#9r!D7TqEd&jDrSoW>>6DigG#yiI1Xl?EJKKkbahVMMa_&GV<0-sGJ0N_wtcb
zsXz?2A#c<U^7jDIE3+{)yW->DtkEnIjD>hZD}xWBDTB1aDYRz)#Ro*!muwP+tk13W
z?kN5bEWd=lG5p_Jfd97W5F at ZISiP4J)QVrVqZi8eq0rH>19&2c2|(u|ooD#0q&O=H
zj7?Xq3S<DF1R#_M1NjW`f9Ov%dv6090Ietlxb!i=35AnX)un#9Hg<()3yRtn6 at 54}
z_CSx#mQ-=8 at Njdx5t1ruVw8pc3QbqXJ_OjuZKa2DYpO~i8?6Y42 at bC=*sKP|+`-he
z03p&da*>0qbfo at EHXg{Gd8$NC44LuUmZrY{+a9jlO05eC?2KSob*>M<oxrT<B>nr1
zWspM{*cdqL*|_wL3n&Ml;5ha~dWtjDS|ww{lRzjPObuXJ`pmzlxVM25$n?As5P)Nx
z9c at WjHtY>88km?kX1_)kxL*G_WuKSzbS*v5X^-B*_OFi;&5n()e%J;B1D~|u={JR0
zA^^|<d%C;pWTOj&Bv*W%f6E$7k!VYN_U#pL2P*^VtUG_xG<FFgEuFXsMyWiY*{bw&
z(&E9KG6+D?fR;wR?_DiMRWT6WZ?7N_h@{t_j7n}Pe4kL&_CewKmQn0+v#ByFpwi|-
z>m7;dhy9cZx8x?iP7yy*_?9&RCR!F*okz8;SiiiO&{*ca_?24O&?#|>HYq9x=T_w3
zTHXy>69D>`B%EIO&!oyn13e*A-nG-Ac;n)+4M2(pnCQ%>b-{_sZ4cxmvxADdX;U07
zlIw#s at u3*PR-jjtCwW(OAAGIk2FRk_0(LmA8nL<31-kHWy=bNiJ-)CXYQKB;vI%1B
zW8YV4ztd|ZZQ7mgj<lCaU%*1Vjr>pyY>_U;m at VwFQFDYTGkLHBo3;$<y`Vw*v5Cg=
zZoQv}e*zZBTL4B}9co|@U$g(Zg*AmbDQlh3bijnovP(W{L<EcPcq597p2t}gwwVn}
zm#23^+91zFwJOKA&#Js4hyq_qT_H52Tf1kV09PCnhM!(s&e9bZDgP@?4q8JY<Cqn~
zezLj+SAQik4^vN=a2B^0<HycfuDGlrPg+3!{v7l4DVE-#eUP3(JOCnTJ7L~#6%=t;
z6h1W#W?&HorKGw#PX(T at k@I-~o@(3R?R#YW`DU|?OghG2M`w%fw@*FM`IQ&Q5tCRx
zShMCnHPN&X;#}oPz0>A{ZuOZzmt<67QYn)i%57~&38krH4<fK#gbe{V|C}5TzEhK>
zmV6VJi-0n_1t$Qd&eE|#*l`F<GOd>2g#0ZMYh at s{=D*h2+1YToSh06p2 at y^oM`3F^
z+<%@}e=fwNr1z%p?jJMNj-Y{Ow8XkpZ|~CWCGQ!L5d}&#iebK`qh!uZe67zA$oOMl
z&2lK??s-;3QIT@{qO<yrv;A?^&Zh-5{!o|>K8-&!Io}5u>#tw0-gWjsS6r51>%SNg
z^h at MovuxXDd}Kp~>BS_T$4q`(AyUm(bzxG?<OSKjj-b@~c0xd7ePBAlYu9MM>Qqu%
z7B1zRmh}`^L}x01RwA6gBkJ=C13<*a_3aRJBQEnN;{<#{2XRwri$P&_(XWAa`_HlS
zWvO0mpp-ayOZR9SBLW{HRgw*sr)=_ABwzN$r)E8!-WAuGHJ|JD8~rL(R5UV_CN%>&
zX at qu#JC)hd0TF5ol-QB~IU$-0vldLMruyLA at Z$%+Sd#7oB14cOK-ku#cjT7vygWRE
zjKfScfvITQF=?-I41_bqEF~icgU3x)SWY)Uu?&+O_4(1Yt|7`lse}N#^zKid{I1$N
z^jz^StEmwo3vTzY&=+w8AcrL3TYA^G?m?0^)N0^Qj1hn+-NoE0TeA&S$b?<562G&f
z!B2N?G)-pogw+7g$j4W=(Cs7eCueETrgSB-MDFHPN(`RmhV17XTrxMLBgn{}GYbM}
zu(eMLOdne!VW&NTcp8`zAdw-ly>rij8&(F6oKN)Uy;%j=BYFK_KUd}0@}!o_1j4 at e
zeHNpXM>S;nTBgvHgJn#lJlnsClTHp%?mV=`hI!k?9%*uMKCi&UiJJP?V?(gRchSWE
zAlc^^bX}XtDHzK6CgSQoAGjmM?!<zLT0HSA^hcoj+roZu?tY+A!q{_{7T^#!<QVqv
zL;ArGWPOu8{b!LG9gSazE3Z>tS+iLCEuO3xa$c)cuZTDjI(FZImfw`AdznM{)anCR
zta0$#EFO)Y)Nz`P2`7eXKG<Rim(Ok>vY#0BcZ^JEL!u&p4A_UT?Qsr97!lAfUk`6q
zSOtpEiKD#;u>Dg`n!O8ZIrKaUcG~7qTm4lXdfi39>!@J^X~U?HiQaVIB)F(S!GQT5
z>3f+pwD`)H&;x+&;81GZIv;$C9^tfL<92tr_xIVMm+MeT7+GuyF=+eN-b8i>BM?9^
zp{0mL=gAwks1*0m!(x|D*NX@#JC>4ZKt{;J%UhcsR-avlKLYL6pKi|F1rBMJ)h?S~
zG|_IeJOwk(E_%<Cdg`MbzDgCuFmrGJxakg at sZOg8JWW=2Um{<+vqWCbRW7rT0DqkB
zX<Q!|wBz9%96$h}Pu42-PnK)8A at ruNXDKl<F5M#|T98{KQ)a#`wA;U-Q;*-zR at B!|
z(#27F9yjk0&Qg}hmz%bh$m!YMEt03ZPoVu<cU(YBb@(aEZJ~v;+;Mcd_aNl*-vi>~
zyx}J0nCA>!<Sj#kFJ91sZ!}A&j{z`9 at t9BFiBwvcNBzb%ClHqyIY*oL!{F=3OG_3~
z-=!1D486>}skH9g2YJ6l7h_$r?pMEBdPV5^GwJ1`|8jK3EO-58%(aAIp-=hc*!DQH
zUt#eJ-K~^f(@R$D7C`tx!2qpD2QNq;6r7)jA1M1EkVGZgNcGK%<ti5wo)#wL?G~GW
z348|zIDEh5>0Rca4=XvZqp4YZ{0i0XES@@}uk8w&#GT|-9we at M&okv2o!v6O1qEd0
zu&}T#!yj#waPZCdH^59L(q=SqyH)zsUg7I6516u}aDEyZmEDNo&v61WRA4;Fmo*WK
z3TGK6kq?Yk9&3%1&z4y38KU_t+Zs%CAKYfbj4+KvQjnClm)VlFIq9tg?(BkLAZlvr
znTDKsVQ~VIa+AvU)T994Y(gCPvY6WPplOxU2}F_o&paEGXW(smfrIaY$!*~6GxqO4
z{C~^~vE)|B{T?U~?4E;+V1v3t%)T&I`0)v_%2L#0ZGiQzix<8%0SVdN!!uFMmmkJ_
z`r;l+;eGP~ES0vw<lQ?6<}=yNh?lJkn2n7OQixkM;Ty-z7TVEf at sg3y-`G_cZsYeB
z{zM`~iqz<WNeaG1yW_I`i}98Q;2kDx>xbS>7t}7n82qnazwQi0$1IXpJ{}+typCzT
zyIw2sXG;i+_k3K`7rJY~{o*^|UuNnz+H&9xrOv at 9SG+)Eg3CXjKx7GT+ZZR*qE>$j
zrA~fBTLe&`YD1*F90fjTfYvaD*$wH)GC#j%HB=bNcD|~+5Asbtkau=bq`hhyl0tb^
z>P$@g7HClp6?bf^ZzsQw2h;hWGf^Vz*t%tSePCN8?`)g25K}9?Q}b at U!1B%Uz8;da
zd3!F$8}DWK#h{q0Tj^1iYr&R^3pZscC at B1WewXIp<XC at Nc*UCBW;)eA(#^}UK6biQ
zGdmD<bdRT(cjG2!(6>ayQ?31GaZp=J%L10{H?~3!C1?9_DII5LImY!lc0F#9M*q_k
z+s~Sx?L&kmxes3l$zI$HTXy)$5Elu)fAH(Xhw=Flc=S!^yfB?$OYo$)=<~Dnsr{}c
z$vx<v5Tal4CVxm?-TX%uSPSmuD(pvhS6}zXkZ-ei-p|I*8JV|@0*wN45F^Fw-u(Ql
zF9*DL-PaZQzq7x|;q9v|IaH1=T9WYm@&(O&<L0)kyow at c=rz>uSb1o;q9N^>r%yT?
zKTBG?rXyaD?g~L4$xL={!$fNs#CtF)=j6n_dEa~MGF{X4=H_jX5&*E7Wk)tjJ{d9H
z85orE#p at Sx#J32Xg(B$C7vJ=SbNqsaLo9PbP%muacH+9|4+F8ImX7z at ut)B;ZgP at h
z6x#qn1YizEKr+!>EQ`BFp4p5vBBhaC$D|Xh2q^?b&Zr#B+!(`SHAN1_^X>d&5?C!V
zVjUvo%Y$zZkpf+6D!46 at m**=|aBPQQH9Hui_NoC4ymyey^3<{;R#Of243mK2b|Efw
zbSt2|cHgt3NZYtRyVzC7&Fv4ZB7~j(*R?ppN)=pYG_!_wI|LmKcnsOFBJF;?ms)f*
z=Bw0t#t-Ol`k at bv#DUiv8TV2<dW)3B2(KUy&ErC-Z6bPCVL2E}f$Iba#TDze8SQ)e
zB#K9#&Sk9IEKIYcp3V^$J6-fn+CxS+$Vua*WT(h+r~Dz0{T;(;46_9HvT8 at ZDchKv
zn-9gPYHR~ZI7#M-6gWh;s~I8Ftw@{=s at 6yD+TR<NQk5H!9qMxeGN)DOo0nBusnkF#
zA8=&elc{BOK4A*s2(WDH{73B%qGPt3Q<gu^SP3H})BEaA_?aTHtoD?fXy=-&Y}Uub
z35bHplW|IsvagB_yP#y=pKzQ@)+d$eX#j|k^&sK;%%wH9YgyC at CZcqIbf<HE&}>dV
ztrQz0W+EdAyfyNc^pO&N at o_&AyR%;pa~h$44U5>BN?$Y|Onr{Oi+Tv&1gUPy0m_|y
zd2dhXPA5=^-<}bFaL4r{_>uHvy_mNjmmVq`sS?%IrN}~n<#a{er)>Y at QOzIunb?o|
zupM=8U+~x<?2tK4X^cX2)8ch7EZk&3G46+Ym<e>`PN~mD_yn~{K5sehLM}sLhY=hc
zPCo8FC*K7sa{~cw6JZ0(-pjHHQ9_c%x7Y5(E1~zAT`7D>8InAN1Aw)l@!5!tMOi3@
z$6eSCGS;LvYU}RquAbi2Oms5{;Pvv?o39kZveZNHGm^=%f|3=@L=qg~9X?3!05^15
zQu(qw$|nrvkhZ!jy3O+QvDdQX`Zt6C^H23#BVf4Hu_Vr&($i}wL`s~<ct~NHoG#ie
zDCw03=pkGi#Vn9~_>9bTLBUP9GKZ(TcNyQ4kD}U$<7ITXP&w5a!|#$>C%>TH{*wrs
zzq6rcYBm2lr)SixnwO(%n$&Yx(fptd@>mN6BAUPIU=)_O%Mh&Vsb{N9to_9}pKzYy
zLdy7OA|)!Wf_7V9Uq4ZbxS4?a&c6Kz><}bXUkCVQ83!YDz-Fl#c>UDjeb);Sjz7`L
zZGp+>(yb_?P4UniFSJx=>RneKHgLzawBCXP@<f6PK92Gs4CHlByhITt79(;Ybdt7`
z{LY~B9=$}}3NbH0L+--o8QwDcI*jNJd}a3vBMOf at 0G4e$IJ0hs%E?ifP5Ge3c>qk!
z1X-Yl#(?<Nl09AY8?061{_KzT)qZ-#*8TAdJ{*w`5MZX~Xo!98zz$2IMMo%P;%+xR
z)Z9FCFyS$OA-*y9i+2o~WU;~KQd9W5?TeUKijA=^-;w&vK-9DQ?nV=RrT9mZj^TQU
zQnPl}N-}-O=?l&`2Q&&l*8_VH-aA5p&@#S-R!rW*CxxZqABF`M!Acu+aIFApyK6br
zbWhRCJ3SnBB{^F6d=oJP?TPbZ^120_q{kq!36cq_D8w3a)h9pui%&A_ at n>)O>8*~8
zPdmGL*dc^3Gwbe~l@?3kj-RvT<z;0<jJ4s~l=@!01wKj*W-a%_)V(&9VlpmsJtu<2
z*gz8)qE({12ZGT|OD8oE)|V9EwHz(_=3%_OnTql~Ts%TnhObRE{5Cp-->=W+bL%L%
z;7D`x1Wm8Uo-{@{jOe at W14fR6wKK^}leO8SvkM7Bv9>}CU3Yr#DQ7#Qi4ai^y6_&n
z3s`4cBQr+o1J9z+=vpC(7tgvs6M*gpf<V4T&2}En5_MPOIcj8NB)-1gC#Aj}mX1&S
zN3z5;T*~&raFWXG%ShjxsnNpuuTnjEKO&rOwUBuJIPTG{Z`YO`fqS<^-B6!hM5@*j
zy8zt<M=M@(+HzaS+MCb5Bz{A^ow58;oNeh|<()=nVw`ISqd;Zv`o3;`AR4?xE`O74
zo24`H#7E$RrBCN6G{U;;-hJGi)Ri)2x!Kgqxjyba-NL7do3i(qxLypCXhiV0f4zl7
zu<Z3E84cXy1P>p?3L47pFe0xrP{C}PHT4faKVS_?&&H<rW(ouc3n!KJu><=yMz(>s
zd?=Efe)dqO$9O*=b)qv9c$R|T_2H+XV~FgA(kC`UUBQg*-+~lN9(C+QoWn%DS2?~h
zslx2)c`d!B3AX=i7Cjc`ZG6?Ex>o)9{g)UMbr^kp-U)Q&>nVVu>~AWg|LD_YD3~dK
zr!6Ep0L9F|bQHq|9%S?0rD%g=sxg at u_Ch8jpYu6wz8weow~6cyEb6BZ(vxCoVQWgV
z*<#Zm6VzAmQ7S}In#TJ_rrfmsLDByA{IXo>Pzej+0=wJ%_wU*1pkEwbR_=3_;q*^J
z8Z3?W1+wlvyMLf1rj`xl;JTdAwSZ9dW8|TdwdNhzm3XVbbucUlNBT#yqAVlklN|YN
zE#EGFRFJpbL5R?Y7hq;^w!iKM^$jNGNdXPG<?pH>6IHq&2(gh`()+YqVIRYl`b*}i
zi_<&r28XM5_&%18qrG4OhuJuEFd799q%9dZ3j(alsoh;@w(YL*!1XM1fMM+rycHGX
zOB at vpC0rD8y4_dJT~&KvzYRlTStOG!$d^2v6~b5cODqo}<6g0C{}FN|_S6q{43cWz
zX5Id=T*CEAVb;8xEv-Scxgfg`TOecm6!>RB>$+{W^zUTO?LP)TXJ5?Q0HElZ1f%9+
z7EEKYu)7 at aeJr`ix*g)JlmAVs at rN*(nS8Cm=GSV=jf{yz at 4c9Gkmo&qfha^s;=24-
z)npptG^O(DO^f3+#AMm)vc&HD;Fwt>($=nFuKwbYX=~d=?<eFZbf8I}SCJfc90x3D
z7PA`qy<p4S at 4VC3V=_Q%3=ldi0UTyuxxCa=%xu|u*~d$biBz+2#CgAdx5;6%lJz#1
z?wb>5%I*)Ys>knpQp~-$02Y<BNqwDMqS)8O$B{PI{8*HuqSKchHgkuSt%vP6#N at kv
z-`Fw at 6(gH5>g+3`lBOa@&>|{SF>EPyG+W*>8usbq$Le%jmMY)(B_F%pRqpi|kpv}6
z5N^F)c at OnZ6j!|&C`Y|1addeEp|o`^yK~p#nez=XEi%hXMuI2~JfAJSVzByMv#dUk
zw#F=WVtGkow`$tU<q4B32JCq7<^FFv7NN+%Wep9!m`FcyiRgP|hOoPq+tKhFSgi_I
z)6LZvA6UpvdN2_ua-g#%*jjy+*G&?hAFmy99MFo7<G#b9g)<Zd7S9#3qva%SuVpi_
zGJgH|Sd#7b3p;V>g<RTTj|H~^lggvfJC(HC8H;o-#A)(TcUNyy5}Z32-F^VsrAmh9
zVg$`Di*XfKKq#f*hBf~A%?^O<3yAT=zp!Q(DeEqERv4)J4RsCJ<9?F+Ew-URDwG1J
z9Xi&gpO-8V6K?OmNG^G|(K+}~4;Zowad(@A{_&&4Z(~+V<aiZHwGahw>q+l6MbYfh
zlAql^HWE9Dfi#Q;l%8&L`+#T8=I5L_5PR|mCreCnw}PpY%q?_pDW$&F-C|AqhP>Sq
zn4|YKEH?M|x?MK94L+^I6ye@#M+yCWd-C at 49&D~4XL>Y!%C#^PI at s4^P`Hr*Uyv at B
z9ZjlNJZN*nfGVb=QMrHb4`B3-d~>;LZG-K5!<0tdf{nb`4?F6ljL}^5T>8VeGYILu
zsESKzsz&4^yBDy_k^!0_4li~yi_a{Dvg#Xa*MCK?g6`oyg)zC8%_J7|jZ8(|=-KPx
z_W0Q+h89|XZv=C&XmFv^JQx_J{f+!}`^K{;QA<k=8PVC7EH%QqVjFvoolN&`rHAkR
zIIvD27CWjB4b5}A-?3q_VgxN~I)$DvO|}N9Q!^)5FbB6WkdW|y89Lm$+0?Jd4vvR)
z?6>2Ss?@Q!!kUjI$o7&Tlrdkj{nzF_=gl|OEMVUcucLzW)A}fl<YO#;3ASm3i*|eq
ziz;Vqi%!R!eX&%3&UT#{8~8C&GPQw3-~<sz%~qG%Wlg=sc{KJrN$z8BbY9Mn at 6#{&
zZ8by<?z`pO>j9MZsf`<2d4m<Purai-==!2nuiFy&4Q5H*^@Dxr$d8Bz6_Ya0mdLd}
zmk_hci98}+e|}>b+4bsy+XuOBE>t1!EG2wOpNxyH1t96XsxN{yxKDwEAVa9XK2S3L
z;Q);v+jhvE1p$h|A?xL&^#iL1-|GX%%qyvY^@?nqclKpI!x^WX9|PAr0Etp5Izkkv
zw?n>~(wv0cN8Ldvl*FoZlc284HvzOOFG7CWrGt at DMd+?#I1_+><pRm#HUs?U>N~fn
z9d9+;|5_uqw0O_mut~Pe-bh2o`C~W8N{|LwTkTP5H2LM*Qec=)M3!FYBP-Id&etLn
z8#dwzDc>JUK$VqH7EIT()dqG#7d_vKSd>%5CmsdW)Cun4ET23W`C4zbZk{tf=zC*9
zh)lT^BcV0Vox>x5{iIECQ+8CT`MW_ii>QpHogoMO9s1Z`S5FUn_fALqSIBfm4Dr*4
zIDqJrQS3*g6%4Ff9{k?D7uHNz&)iG)_~m=RQMvbkjQYll&lEBgcK5 at 7{4nQuW?8oJ
z(8t`%w7Y=&8JT~cVpCRvor{Z0ndc2;NeeTx>d>Iz*OAt at V(83QFM4jUju{+$sVsTQ
zWi{2`xmS45Qt^sX#Vk7ccYzSqfVZu)8dZ*g7`k at _YXqnZ&v<S<F&Y)tEr{`x5mvT)
z4Rz|Y6(b{CgWroC6=*AXRr0e_tCgE$Q2;)ukE6}6f}@Go4BimKK+PWd=byF7OoC%&
zME|jNyp0QJj=<2UWbLW`uCJheV3)MrV4eLP-v|A*uCIDvV{#9<hcqc46g!x#lzh7X
z&;mh~@*dXe9jRa$J)U5Z{xHHX$5IaED9oX+6Bb9>TbB?0au7S{Ox)@Nhz3!``a`0U
zl!;dl>EC#GH-}1D>?9P7HY at -M9<rRo^L2I(iRYvcYNuL#3HU}9Ey-xhu at tpZzaS5h
zS-4dZoGqkDUwLll3E5Q19Z|6w*<c-Jr0Ev7`OutoeV|07+aK?p%DVgSWbLUv^~EYk
z4*{~IUK1i!z-QrTQ__WR*!sojCTJfdHECK2 at UR7PXhx6dpCr{&R{F1vA8)heLc2(*
zuYHQRuCn>{9`bQX7gay0f;9I_1`1b>IP?->hg3)Kf%<Z{_dlc+hS#O02Fs(kn8D#k
zL;KfkuI?MQr=Ux2J6d22_#Oqy1^HOobxpP<BJMtCf3DA at RU!G{VL=nbhplp7^wX2>
zWV2tyJ=U7+e2!d?TM}YJC!?CeCSG**78o4NcUDfGr;oorw-@*n at p~}SenF^>fy&0O
zo{FWbawck{yNES>^W@&4Q2j6Rm=U{UZ@;KLg(8NB&v5nvoF6Hf*Tm|-JtotNq}s3Y
zqUpBQyY=~&i6-&)U%xI!b#g<5D-sVJoXm1+?>~6m$VlZ at xX=3LXdym6-q7g*wz-(i
z^WYEcB3c(xo(a$A?PF?#l|*;lez1REKf=SsMYB7CF-7VHD;bx3O{v0^zJ!*sV#=<U
zICb>32u+KT at 0PCx9|;Ojr&d23k*dE+I-|667_$`RwdCVR?d<LCG3Z2e$!_{|eR234
z>m{Rlj)g at uMvgOV`9<V*DXF~Al5qFi93L6y_{i8>s$ubLK`|!$EXXg;%fzLb74pev
z4l-sF(=B2_CMn^^Oe7w)qahnIl-=`!{|%?V!1nLc at Z3D_AsWv~n!^SGpbW^FI1Jh$
zu>d4|{e%0FSlbT9fwx)2K6ZA6os8UjKLCM(a##PEi2OTC;m`YnAgg6^$(RtStTt*K
zBI3&^CB5C4bb^<<0sv#T(>Ot4itpe95j5V5-Y?Jl`@A|H<-q0Wo>46%-K}`I{TpVs
zlCCYYOe*<V-!`Ab)2pl`aw~)2>BXcNx7?tx_9*EdrDumObr;;EyF^|YEMhb8dMAT9
zInKW^8pV3?Q~BG?_982wUc{kWgG<41_8=r??E!`7XNk4y*VDws3T~PYdUV1OT0tXh
z3Evw?&cmr=D9l<TgCBuMDSNsu8E;J;)T4b?P-rf7E390PGoM&7vW6%FeMb9Cs6vCn
z?nwnJ#Yx7|pAND?Z|o;#IB^icvL_`a9U=(ZU8jwRE2o)`(3bvulqgjTYzG{DGE4eh
zzqbDATksQXY*0Fdos;zqE`_ at m5%PL6;giJQKxSoj+Y(xh&DM<5SVTyy;Enh4q~505
zo5J5L_V{9IalPybDL_J(mjmAW9g at p+Cmiflk*-~`F3-PHBqY#Bk82!bb5T=hR9T at I
z4O71P<%xe`wxy29ntjK56$Q@?o})WB<q`Ok6T8?S_i0RRBFI&;x;}X2p!s3;k?drh
z`n;eudx2izN9>Cdlw`EJv*CW_tUBKt`+oCpgxfk-c-w3~`2`t$5yHZ^#@Cf&D5_9R
zzIfj8!LEWJTawc|OACAtB16?b*Pp%4F&8l9U2B!c-p07iMn-Y;LxWb|Z-p2FTRw-6
z$dvK<0C1%TGCBLqDBZNQglLT~)Bbj`l;M+B=wQqtk(;HoGZa3 at y=U>_+-C6)S^Wc+
zcNyxhv`-VKMEz;d|CM%4@~DYT$DV7p4JH5FhkE<B_kds5xwJg7SUaQe7^_;?Lvc&;
zXW1%Ip_I_l^_Bc>HmXnPx<Th)IP*p{&51?wC#oBU-v3(*kS-*dS}Fu=J>CWO8PKwM
zpWGfUgt#dZsR9cwMhUba3AOI=v-zc`YIwvEN};hFZ1M!w*Ko%{po&|d$<fDb5*iq1
zlSP~qUrF&eP>2b1(1*V7aXZpvKk<t^9m#c)ec at vRE&rZQ>zc^2z!<ZSCcH<{f9f?|
zgzTp0%YaVc678SDKJCBG=w6FI;y$@F at JaQ4BXB*6_#*|?<-m7W2D~C;W^h!7q^?&M
zT3O?cL at lXLxAhO{A5%Xgt1EkCtbRTJB*pf1UTXVc2P^Ra+Jf*tsM9;KvXQD`Kp;3Q
z?)&8W0I{B4*-O=5aBUVQVT8|(>qj{AR$5q`#Sp!nClfw5H<zkFO7+d5_{kgAuRRbJ
zQQku@=k&ygpOvZM<jy9R=-aS_^Ah2)i?q$bU$O}F<LB=^G9tQ!k&~LlS~foLACH-0
z&ZY_?BI5Pkzsp<O&(ofL{Ly9svQ>p!y?#FOCM!4rDQA0aSW1z9Xo<;%fi*yCjiF2N
z+so?Wy^i;9Z^+IQXa8QAh~d4Dk{h{96jBamW&30l+ at kR4#UHN|`zK_@#eKA&_TCGk
z0ZD)X{3ZPmDTnNFZ54K;d6K<2)U3OWOe|nbduUSZcJ#(mvu<=oo%q#kOb4S!k$kdc
zI8ltG+U(2r34(Ha2R<B76cF`+L`EH^z;vGm3NyvuwNW|+cvY}=$#=OQ_;i4N!BKFj
zk^n%HVo$0MB-7jaZQVw>G&~vkv{IMhVyeQjn_-&;91{@_Y%9sz)#oWyMM4@$JUg_O
zKq_nw<y_PPqP3i1p%QPl4?9_jQ%MAG&=_RT&ya7MnKSHAtoZ=MZ8D{V#Pd6AuPu3+
zh>lKLqENf6c#yp%Cu;I>tS*m_1iz-F=+ at q#cLsyit~JZBc}V(`1B++|YC7-56_FA8
z{tXtito%=P@?0_rS3cS$n?l_iJg}k0zEc-p at d;fIg#As<z2s7wq#x=#;z*KPQ>n5+
zBnF=&;ZYV*!L}C){?-QrRfU}3tQ^VVxBXu}aC~)l?}a07JhzG9+`rGNXjy)3zV%_L
zoyz%8PmHyLFO%|sP^bhElSaG)+|R)mu0I|G at _v5(`TLvOG!J*rlInXnY(*b6-gj%r
zQ!)*YGTh6Va_YiZlri;pHJT@%#nSlx`C$`9sjFgfQ+aKUpD^f61(Xwf>|P5p;am9y
zWsXv(qAIkMP>m0U&(A5UgoV~~8`I*xl{M2qPP(l_N-Su&dZYSe&8#jPF!!>THZ>@H
zg1%?<YbD=u1V9)?8px*5VA&!!*6wB&MbrU>lXJr|aSwK-&D^-PKCd5CMI6;ARqRU(
zg4 at YuWE56vg`(1{>k=1~%&-_GO^chTdg7 at ENt!%2BPVBq at Kc1&`-Q?RcjjrxBHf<I
zv(cWIv&SJ{HYy)LQG%gqFVeIj at _wOG=f;2o2 at Bo8C2CX{&!Tm}k>fvT8bTWAO?GZA
zbugAZ=<-|lvFQXM9s?VX at nma$LVLfmSO?z0CG72Ohg{nbfX+MUte`rArKNLGFnY&L
zde4P8`z4SS^dyH47B)F6xXBCJNv|nJ?E&A#H=>xwYw?XZO^18<y=5$V7Dyw`aGC)^
zd%YrZ=L})a!#@{kdp-uL*b6E5K&5MIe?yO%*20s at ir#8V9$XuF#r`Dln~dxE`tH%E
zX{)hgAEnWZgipat67Hbt0?-{IO9H+iy!qqQ$8h>!VO|cQ5&8%1-vvBBJ=skRXTWh)
zydqa=k>~$;SESmxFwrO>O`GXP3(ftSrG0&xj_-FnZ<%vS!u&1AKACmHkM%D;|15#{
zbw20ajJij{_`T>QUnbJd*s3I3k7bA_21{d6*Bw|bz=3N73B!FS{3FfX<Vg~p9u~f;
zsJ7;oP>v*`(7Taod%N at 2Ti3UCw<EfjB}~Lm`s_jSZ{{Bs=9(<}=L)DjzX#rwX6c3I
zoA*mpQ_}W>t7PH{ffV$kLC4&hNm?jxZlfEbp9jl03c_uN&lup>H$JUPuph!TdnTKn
zU8X@%LqjVa``6gEQ1h=~Y;3s^XWuB9b)CY-|J4jk@}t_%AJFRvE9$dK#8=tG@@YBV
ze%?!$VX`9efa<f~BeeLFRo>60CZnj=H=}&rZrn!DihlPZ8X2}OCz0s~07Ctb$Nub|
ziA at Aco1U<?#mvos)*U`w%W%f!rml1y at ldYG1P89!m*pn_#U8I=-TvJO26h*vb;m3L
zom9YL#mDNB!iCt~dEg`@%3hMUNm*71h1353Xu7JPwz at 4`q(EDw6qi7O;toNB7K%H;
z-L<%DDO%j!-QC??gG+GtqQ!6ihkKqglbLh&?6uZs%MLk(8FuK<zeLqhl;)$t&;>DY
z2q>8v$3B>-9d at gj%MiFmhr(DQ{hJJZ5B4=o`rRLEJ%_F^(rLMmhOtDg)3(-VsX7*0
zaR=Qno~gaNj(j_E>8<#at2M6QH=`Y}o%rc{N$pc-v9&Gx%oBDIIf0g(-L{#NAr^iM
zV-m!Dv!yH30*0iF9n*-2CX at ifK3?Aim5~3M9rj!$a?+_V|3o&6FE?)NJZv6G<@&=3
zls|{=W#7qXe~DXb#irpYK^>c=7#(Ghsg0b&A=H!s-y2Ag7|BHM2$S at DIe^8W*<Z76
z&`~jpBe1&UMBpf)<StA9+Wfje8CAdz!vLS<RP)IAL#9TLsW24=YV_-w6Va#zq1jP?
zVrq&)hWsZQ4Zj6mP)m@#kMvrv9IUPpC12cuNx*59VAIn%ADR|P^<S1hWUuNOrDaJt
zB2dnFjgN5&UMSdxlFNr=MK#zIs4|%aO;PXs=aHcA;=z?nt;+d1HNm0xG$k=}lzc2l
z&O051sBV+i&Ha@(;|(F0E~>YGkc|0G+xN}AK5Ng!bcc}Midqv1VX)jL3(Gob_xI1L
zM^mYu=CDE%#Cr}3 at z{>(kIjEm!*^G9qK at B&{&_2Wm|i8kCM+&G%4SgyGch$1O-z9K
zV1v3-`R*!%hVtPt-^G$!{}StC-bTN8FF;R$#X!>kj7k+^8wfJwx?WlhIB4=MoD7TC
z+;10M>oFJ2M;#E*)fKniBrbDtKn(#Ix}PMcPbuw$Bf`MV&p>5C`-<2*$y74O1e7HL
zfDsdA$15xOXb700MLy3S)>B<m-Z_Le`~PFZH4AO-i;M^Xk?VxVgiBBu)sK4q!ft at w
zJYlW<9K#K=2fP<)l)EWu_)|W2sK>nkFF||cGD0i_r>)2(=FkCxWCYjmSp+VErj^Ke
z=JnmVUyKBVZge55QnrCrMsh`@zcZ!izMzw|q|1;S6^C+Mc)y+Qo^Ald_O>oQ<5$?(
zyc1{kx^&z=GT0RsW;u!Y>G6wyIKO3CdYn#0hPbFU(kWNn0mhCss2ENb)!dFB2Jx$(
zBFf1R!}y)DVG6s#p`yi;hS02d&e;M(9z74c!<LW&_7A=4?v}75 at JhP)C)(*%?6yot
zz(eY*_9>6Bkj!OwsChWbG=i<|hq3xE{hveF54uOg-czctPY1iB!qw5{46U!nE&<ua
zc9*zgDOn^Pvn%ycQr at jj$%dvUl<-^15EhbkTT(K-pIn2VEjqNjeB(49mfjbj+BCRj
zTzEV1luR-3{p2FJkAKOc-yldx%_o{dKM*Pd>`XSE at GqtB3Y~XIo;&K0jnXd{#qDsJ
z3(oiF_816o{w=p3)6e&v&^Q0C8pyLq+e1jd!!s4Sf#*q%iHOBOu)AbYQ(q4(;?e*I
z at W^u}qK+>QM|wHKV+vC6|7B?3Jb`8BPt2$u^_cFBFC{~GS9lkFjm|$?7%;$pA7w-X
zo<Nwg`=yj>;HW7+FkA^?v^dv%qE1J3jlRPvEBWH8 at P_F+%|dmqZxeLndrAoj1W6E`
zSZ>3_XxTZ9IOpn`n!Lh`{Tvoh9D8KP1a<8{gBmcZ1yf>8I30^<^@}UF{Opd*OI>U0
z%Ii<q64H6+yA at 9~WiI=(rC(089)xB<J9VmLB<iVmygC-Z+HGwHu*jP5UBKcgY=xgT
zCjH3|F`JaAFZRI);m!UBKh$gttVg9``nKJcNJW^y&br(qU3+T*>C+qTED#2_+M`-z
z=igqfU3Dz?n0kLMYf!YUGw*|mrHi>=gzn;5%mPP7JMCRWquLEUw2UBp(j9Ee<L`pj
zzo at c@==d5PiP>sWOF|yQZhMV5Fi1zk<+w3B>B&;FBES_(w>*ib5hQp2HO-v(7Ovr9
ztRoo>L*8A8&${LR$vDJ{4 at P(TA>lPn)bya3SP3cR)7<ghf9guiiTaUb?yAW-Nm-dB
z5KPqGl6b>eiKN0C_85`LLa>a$J{gH4f%<rE8L7YT{R{WVLfX<V0gpt~*TWS3pT1)6
z4Cg65X+DT)Y)6x at dVmZk+&Qaq7n2LpTU?9+dOW8`?hp^luXen}R&aV+7MU!vz at wS;
zB+oKe2OeMb*6yYAVx~k2h#c?mQ=?uA41ar^j?1i2IyN3U=?C&xiV!Zoq7!8zy4*-y
zIjc5>MliJaXxM#)ptQSq3A+4CR_eL!F(ZeP|28M>t_k4IOGBi}SNqqgF2)1#Hl)xe
z9AdEUasCdFvop$D(r4R8`CRRa^K at y2L?AQSSeb7y+;ZbR>nFjBc2Ce_rpDeOkz-2o
zrHWt?m?1LrH8hCJ!sU7L&@Ko4s*@7maORyV-x~UP$oqg~qITE;!^C>hk8xQH6fvyj
z at 0iTT8`_446-k{yYI5f!pi*W}egTZrX0Ya~=`}BpG~d}YZtmOJVhw4g*k<RgH^kD~
zM<Z~x%YZ=+JFzjEiT|iwLMT&=qIeRUH<-?|?K@!AvJ!@p0@*nG0ONt at bjyH}m;XMb
zRaUb<ruufII{!4jJ*c^F3Pv|J`x;UTiVa494E>7Se9{$CQ=T<~R$C<TL!FcPTr4Aj
zmH3$^_(^-bDgIv)iWoUO6%O~pype}}@B3 at RN#iahEJ8EnGz@;LFyQxu at VU`7t0VDp
zx*Pk5?xMu$4cmF&tPPrK$hdtIPf7 at uurT~hWR(;rKRSRzU(;{X%o-qFmNoZFqK7=2
z%EWI^Ns>O-Z<yz=m$*JQJ>vj8@~)g#$_#xsAMt+d=YCOyNMtja&-KE`V&Rx9gX_XF
z+s^g0oZd!R<Q{sG1tIHdoc}0pgV7O51lE{iPR6{j=~-}lzHTI)1W1nLYY#Y7vMMfT
z|K5}5qOY0Y3rTJgEj8XfWrH8^48!Tjox!{<ieOH%GtERil0eiubrrT$oJ(S54iw|_
zq#A%gX6kU-qFpI<u1NBPO at i@+dH8SUUUVIiD(=1xDK(!;&n6fX_K;l*9>PVfE2t`-
z<UT|*0pb)i?3t)K<4TA2OUj$ELB)>Y?U@#zr~jE?1H~dL#yT3?e%Y!i%T{io+%)TQ
zA9N-jIpl{<yMHE<gBVSfTCK^)ko;(+yS^p=!31e0L4|1xKsnH_k?u4zG*R>E!wi35
z7eG at 90t^;4iGLSYh2`2`I0`IO&&)*Eh8UML9pS at jSdH74i<BvtYF1rptu-{#=3IHd
zIwp3{8 at H?&)?jfu+K7tBDZ at 2)8ZyCn$4DoB{59eI2^Tx$Sy~t(dTp2*Leb_DG}PW7
z0+I;!;<iK1P+c7W=<x0ZK*q}*MAw;4a at d{5X^^SOR1b6Djcm}Y3THtha`~uxb$1ON
zMu_bU!ox}qGekp(VhAnjBQUu_S5$oHp^5=YRat8so<2i`1dGg+p|#NHH-jscl(-&9
zFpz~n>6=1PATgFq3%+|c8{Fzg*2GKWNcd~E;?Fx|gghIF>N+#b at aSq7hOwDLw3V!r
zAmQpo<PGsYE+v%K)Bu9=L00NFXpR$!8=tWeB?gI4jUr{)eoU+R at w<b-ElpDJDMfdH
zexz$TI(8dbogXQNoD!AM$cEb{M52Jge{^Cq-rZunEd(0}9-a5SA^gws(*CE=`D8<q
zcVqny=!OZb9(jfqCdXJVX)rye;|zi-Mcx)(NmtDq#yy%dJz5gJI~mt1Z`8;@xW4;K
z?Kf&ah21HbB4)YhuZa|@b3oR{JAcPPhYA^{gPx7~&ruz at hN2NB5<H2ST;hhr6I4)k
z!e&Gbod-0A^3N1>&za`c1FzURDwqTlksk(i+;hT{>%QR8JFqf`;6xj;ODX9ds$Z^o
zRC at ocJV|E8j>uOJN(28mcGyO*1VM&j)x#O>s0Y?%JBqLM^xwf4KDE9cbp`+Cyf8Vb
z%~A8k5j$i!qkh0-N=S3x6Z8I3zbeK!Aau`vSwDHIyX6FSgd}bH0Xj<sumS%I9&O7^
zkI<U1xQ6ws_4p=D#Sq&zIxf?8GNx<vBt9But;tf~jAI{c;~!u_1eUWaVx+9e+iOUK
z4nr1V+w72sXtvP}$qp+2ddj_bt&ZLL0A!yP_R2$#t7H4r5yUVv^tg=}rd`a}?p1fQ
zJ-}4T$M=Dc=g&B+J`Sbh3xSO>V$g?Z^sE6%a^IM+l#IM1KjV1+Fcz0l=RYDIT81K&
z9z at A`-Gi~=?^s(_KMl=cQ2iYYrMk(F#*&Q2;&0w{7|J(ORr=d8yNboXL99icQBxJ&
zhV9vjqPbK*VZ=`or4{-PO{oeHJd$EG5ZMpz#?+48nHv0^&*Hvj#N~)fyty?(CtAZw
zipG~%6w#e98WQx!YR+ at by&2 at O=e%>fwD%{>{ZqIPOV;Ql8id1eo>=WM*Pa+_->86#
z^dk(qtstjb<PkH~7#RLF{peqiipJMW+J3KbG`x75T%#u=LsM{{s2^=4>%I3k1R1l#
zvk)3>D;tWF$HW?H!;hbqP|HAvHOCXI`^mpYzY>wX;|%y^>Fp2Fw|lOqQ1$zoQj_pR
z_ty%nWv`^E&3k+K)N9#LcIl|0b+npN!ZI2d^6Qa<VW(_s7%SK@&l;L?(4wlUy8j4q
zf(v63iH*!v_ep-7xfZ8-7oitLi58;n<R`~`Q8aA5`G6}eJ&PsH+%mLyAUe(-I<g9r
z0xYeiM53OQqQI1Q`aie`Cm7JIUq%I#@_GL9!I1W6*Ddt@#vi3gNBMl966F8rzMqi5
z4 at hm~uH%k|>uO1HQ4v)cv%Nfj&_<5h^W-8E?Ak()F12%a{=`t?S>}qQnyK+&z|03s
zm=qU$dJ+-!==yMsL>-muqlZfUfEokKd{@ZBc>C9FbkIk93p3-S$sw3d^=|06GLjqf
z<nw>B2gAViBPWmVI3iW7Vht}|<w^wh;^Q%NV-D-d263Vgis4Vz7_Frc^Pd&B4sPEU
z78W==fs1zB$)EnrY*PjHfAqsKMxk*>8G78eF+J?j(bAeVXH$%UWvqI_)&?U!3g4)5
zMu1iBDl6Vd=(%RJ at Ic>(@|8JVN>4QR%IA((B>J|5+?gg!3nEGQVS8|63hR!LE@|e2
zhirg^RzHCdYu<U-G-p+ at SXgUq9g?g*7&!!EfZShnxx;bYdLVi1_^3{&OUFq1#}?BU
z7QoD68_WMfRO?bah&Iejh68viGiKagQfg%^k2OE;ebAVp@;FRk8Bto0QI8V)Iwm!%
zd~o~2Xx^mks3vm0(J*B+Iat`lAd@{Wrk#`4 at ia*YA$pTfjMK0SrP7x032a!?8rOrG
zl at u(chM##a;{o5{r;~7j+KI~2VvA4k^)QN(0hVs8YZ=8Fk%}^>jyduxqcvjiQ^y<w
zlCYW7E^yW^$3P^yH^6(+Qw>2?RXlW^ma{E<e#MYLmlMUfKE%Z2$QxR&iRVdL4dy&T
zU?^Bl5XAJXXE`2h=Y^*{=HdlQyx;d+`W)qTs$QBhC}!O#*)dFG$nbBA--L-TOo63$
zV3cnyk72imL-w-QF$ibfZ7Tm*Blrt&W at ZRQU@Wb6h3I1JUeZG$-$6`B5`jkm>$+ul
zLErc5Ie>FMqNT;jlpxz(4<>?0u9NB>5coFNR1-^nv|-&M<nIUOhr}Pg+kBAt3X}9_
z*O`Hu{imcG;fBa at JwjEW_#aGtwn|{&f__X#{~>Uv)4~5IZ<L0$pJJ{$PIyalO_pZ<
zmg_B6zCQ=#9}Kp4!vE}gNo=<K6t at +r4xbt5NPeD;)q_68)G^@QCuQ3YU^v92|Lbwq
zue}Vz%<>!l`l#3cI;pgh9fDkhBRTkPz!viyvvwK4ra|vKKV*6Wm_wCe%K2sEwW0E1
zP1f?As-_iJoCm0K&Pw-wenmsg(ZK$Wti~|XTkG`9umLX--uS at 4rXA*G&5U&3L4Fll
zBt1I$!2Iu{_g-CQabfDD#ulbIK)@~Qy!Fgf_BiKG_Z6Fet9_v5Ui~P}p&KDfDw>R+
zxzfnWs`Y;5{$%Irlg{mF)wD8`&O!&5w-^`HCHUNTv$#;D;uT_}^ALV;)FR&|^TIHj
zgW!6yg3+PZ1c*UB3R at QfO|^-t`3{6R4P^dEQ22d=)E^{eoqWjhwZr7 at l*RarhsWV2
z<h=bg?{U}6R+Y0|h}mbNtikJ24(c`w&|IpKPvUzxYPGXVcab2}MYKddZ`B}uxYRqc
zyZhF0?5tOyBMWnZqQfO6RPhtStYsCz0Z{>X8V}hKM(QLE2*wAuWX~Q;Ah^4nP~_bh
ziVk9VXQm_Kp at G4&8N5^_J3Y0SDLIs3pJ&{(uCeGd#_`g1K<2!}R+t>Jssj6xK6c<}
z;MPWRwuBD{THsPx5cYWGvF2$sF;V9a*fKbP+iCjTn3N-5F at L8I>CvYc4{VB}n9zZj
z!>e(a_4_}s0^E0IyVK%{QlUb&TGylqzI7ss at 8zlz)WWA9us{>+_8f`ACIi%WAN4u-
zAn47($%6gg<_>#Iz{#-Ep!=a)(!vO*b?GSMUEqM6;W{qGw>5E~6oEl_px|>xzQEOG
z)WG*vx?Wb&psy)BNT<jKI)(truRWcHNQX|uHRObzve9xRpMqFwk`k(O4aTQpTDK4W
zGa2YnpN9n50lU?)X>eC^{)(*`Xky$K4y_`gm*skBx4$lNja&J}_^N^;%8`$`lx~)U
z()fQo--m#f-X-o$|KV2;pk!mWmH at +vM3WD`m;r=&u?1l*X7WXEZF at f*D+~<<opAit
zylXOS?K20aN-s4rWjp?U65#!lYjCvdCa&!@@t+HTsXtFZ-is6lC*xWg2(}OR8r*PY
zaygm*eZJu_O2<R{sQQ*CM}B_UGK_LjvW<RR*(`6=smUiok-#s8q!r2?L6Debk{n%t
zoP>+(w0p;VyhHj_OlLwDni)!-1h(SLC at GPSz_sewoo8Oi&MXbuHee2Ih!~FK`Z#9j
zQO9b1ac?&>Nj)wZVF~#6Tyzto#U4TW1k`z%lU4znq;cavB>k6##qSg)@S1c1ac&}>
z-FrKvzVY_-C_O1>ytXotn5;~2n+5&^j@};|_rUz8^AS|RHq%e*_n6)_OJ&qvw_LPS
z=*N*5ubu1Ovl4sOrBw8Dq^P$e@?M%xT}PlBj4Gessg|W}0{65!b%M(4G8~Krxr>YX
zmy+Jk%C1Lx?GLNB$)<%~MmtZ-Udaj%8gS8VBk%XkU}-SoQ6xX#&P7ZdHkrI1m9wTT
zuhn%Puhb6zJ_%O5y<}oo%%R at KUOd`+za)g6?eBSMK0N5FFLx;KJY6h^3phqlsqsm_
zJ^%2`Zx_V-YiL5CDzgJ0m2qqYFTjOjL8Utd9xdk+i7FLl!cc~{Bx(Zdo+_-X at Pv^4
zq^c927W?=OjSDg%QMV;5_SzuQnr|B2wU+Q{pp;DD+Y(Cj4YjJ^7RONwS+s$>yhl&6
zaxazNxK at a+imGmSAgJ7|nB6TTTEN06FyfyK@})4LC-sc7sO^_9QaALq_HbTmu{6GO
zpiHu-u%+o~p$&$fiV7@|EaloIR!qc$DUYc9<1W8YDdO0eM`cP at w|(eKxCC5*a^MWS
zOT8|PlND}^pyssWEWQ)CPBlf)6613dV!to~5;i2HExAR4Kkc(j`wx?tj~f~7(c{Kv
z8}*v0sdW(xQai%^do3+pnY_uws5B$=*F^vxsw)Iy3prfyEMS8FIZpwu1Gqc$#Zo<n
zIyLe=2au{e(do}>+)1S`*)0j3mBJ$(<X7<xYCigN at alwk8_pmR(T6(`4J#(a?33Iw
z3{A}mTu>-KSM)6*Gwd7HthrjB5`AL*9Pco04irD;$_s6`J)tAQ93RV_5jyyCOYnqi
zqOo9DtX{e}iCu_RZHFSQ0}Bh|B_1OM5%xBc_5;EfSW5w*d3Ha+yFX;-mp&%o23U{2
zKm at 4ExB6mR{a&~q(C(`0W!#?@Sk)TN!F#K|-3F5#kc5K{qxF3(@~y;n1`1LLGR`!s
zYAzt at tXTAhOP&Too5)$=LmrQ6UEnD1*DxSq#qou}UD4xVk&R*szpm}S7~A>xd+Jv6
z3KQP0M~w{}D$W&Kc8b!l9E&#Bs?lXIO#T5Y1NUWz7%Dd&u#~`fJbuQiQ*fsA&U_xB
zys4(P?#z2U-QodVdDt1A?|HhIbyKzE)>eRm>55K(Mc0#E3iM;rv8kLM at f;BgViXY=
z(5e~pTn{5*hN^P&i*@hOIdkXR<VXNd?qB1=BkRJvduYzflep%xcV=otZ1_+l$%1)1
zdI&CVQoZfQ!%CZ3QX~mau2I>L)9ImN#L&qiY;0SpF)F&t at a+Vvr6ypVz3oyvJ>}1>
z)4yiw+CBV!jH5hLUnwy2I^#N;XLfHqe#x4)eLDs@%^r6=ZUzgM;R){ir86sFGg0E0
zsjPyzVlUKA=fv0VgCEPRZ0C<VNEh_hZWtdM=^X*wUh2W<0@*X><zgp6bEA<N|2eaf
zUT#+oFxGstV2OsDxN?;Mkn2(V^_1Ge9IwN_Xmk?p>^(r6(`z7}C2z*@@Rq-(4&dnd
z6BF2$dub`Yg-tTA57~Klm{rz{UA9c at 9_n6puDx8cr}I?rarx_<HDu=hT7XDmfp(wd
zg_GcyN~mZ3Mf>%_;zH!7oAM&vLix3JJ+96t=*pYPMnT682kqFw_vO>miJ(Fm65}&Z
zar)-J1S=+eB1s*lDEz9|$5N=qO2%r<8#8c0?G`dDwET&N#>+$M1Ak1Mj7ZQh#QfQb
zJOqf1j2K)t3#f;KJD#){n3#?aXY#0b!}?dAYUWBDagx2P-$|k~5z*D=#=xaxSat=E
z>>_y}QRV|44`3$wMn|ztSk}@il9ToK!F)aOP?P|-u9 at qBzd(u5f*mx6WIbV~hO9LA
zUksj;4_wLjt}85NSs#7X(me^qPWwbWvZmf~`Z#_Y`I=6`s}#{3EO~aEi!@l93A{-@
zQCMt%jXIiu&-6r)GRd8RUx9nRKc8#DS at Ue1SgM2l?^!!?V7I*^5{=`%`p+>Be-pzL
zR|A$FrknPl#Yxx#*Z(ZAi8CCxOYefO`<`JTklF11QzR7DyEn>BHPxsf&pL3saFnBs
z<a<Nm;L1|Jam?G)!o1)Qqcd at 19K*x38TvK(_4j%Vcw at sDi?k6E`w%x`!@e&32IrCU
zTpCR}oJDwH=KGu>7nld*Y;pTmMkEr+bv#3#TrdnjI<VUdcu^s7VqoENf;35*mcL3n
zp!x}E8`kke1h}tzS88QFWjUuiH}`-j%ynmLEQ!$=Pmn;><zcY$d0?2(0DD at Vb;LMA
z2tq)|t(koQk|-FHvbPE&KP-x1Mk+Io41XQUY)P#=^vf<-g4B0+uYGilA<ZF}<N3}y
z^oJy$AnaGd at 3$k9SA>n6%lLLlI%tWLm*7^`k6{T4{CK+ML)vW9ehBx+oy-jMR+bzc
zI68lKsVz2U-m*IG(W{;-D?1jCAUv_AKnht$lQn+M8dlCif+huP-T>V1XwgV5?Ob!8
z+$G^h&~{@HnMORxl0LKOBiIuYhacfrv$EPWN3Obg%$tkx$`*C{N}P-zSib<-<?QT!
zPhMZ at djiF~u3pYBRy?aZ7V2GWI^>)5?nPd97uxEbbIS`qYIe9}FnLTC at VY`3EgQ>P
zk1pP17OhF=Mh?;|*Y-V~FD6 at qR5OY{F$*Z~fqb%w&X at 92PL(P=2c>U8RlM>oUaBCQ
zW~r=)9)2a8lt at 8~7S471s>0RxfSPmdmz64hy|Uoq9A=YRf}d|&2RF;4HmViNN=;D3
zR$w94lv}Cp)$g!|c7^$*w~LMA$a4p at edPKxE7Dm|*W7ffS(mP at _oPOtO`Eh}$Eyd_
z<KBM-rqoOznt?6$uGRgwE$t+#xYD*m2K{$t<vi9w)KC?pq)Cetv~U>cdr6{GPnT!v
z9(=yUk|WnvmT<uLLwZgTqy<r4e-!3tWaKbCUYXY}D$3$0z1>(XIKK&xm!glGC<eJ=
zr9jv!)a%5GGCY3UXmu%ip6ICDsc@*oP&Eo>XF>l_K%JgCRs=K@={d4FhB7M61nygS
zPXbg{y3Eqf|E<qIZZY0lsI`ze7o2W7WISzeOn=IBYA>WBT~HHzWrecU$W*=P`Br{P
zG;_KDEFOjWzDC}0k`y(0Z(}5!xOjq_j_<OLu9$ta_MWRDsWWI<FYMk%9%4~%FHy&f
zYNwEhjds|a(ID(;)+!}EnxuN9(RI6V^E)o71bS-zU~k0{+osYs>UvClpK#lb<sfC|
z(6P|Wh3uC>OO&2wPgwz`yB+a|x!~w--Dct*zi&hwS`x2bA_fTvK|}ZLNK5R%5(Y#~
zniY5boW<|@-r>o<mjs2iyP(61$yK%m+W$%e;y{Si6Rr#lgf6V|wg`~HX#aB6-mCbz
zMYPLPWutrKCsfl7f21f=LeDR>eQ1RxRbB{@>2F3;Vo6+0=A|m%Y=qQFI#HVzjRxm$
zWYAaHbA}z814*coQi2iSFrf1k^UN*<sM*hQ>XICvBP`8g9EP`iAnOtac5FSPof{am
zB1rCvNC|&PExyZ;e^^^SqMiub|0$=$V=dD_=2C<T=0Udjwa0Ph%ZZ=o)wS_q0xeIw
zZs1!o_LFCOp>%=Lg=@_D$TC(bO3atx$#;JIaA=f<FCYzqhOOExv at qgAT}75**5GXv
zZE51&13pAw!HGM=CSG_+-mp5)iT>DMi8q2nf|XjX1s~pZAV0V32;XTK+Z}lmy;yif
zby6W{4V6of=JHY_SJ2Y+KRJHy?vJV`JI7T1{VbOYSCB;-Jmt*~HVYfkO;3pk3`$8!
z>HIc-(76L=h6_kq;@|c#wl-oT!1)?yE%F==h$2T at dCLHNsXF4;J9izFbG^YN$4P!4
z;tz8$7m%OZ&HUO=dA(@Ib1 at 1B85;a9$7kdDw-yeP=(}~D^-2v4?dt*9>(x5$sPFU=
zx5Y>fws>cx4F5D+jiMtvy3xj|-P;<C&#xquwRn4lwqCa_9<HQul{P;DJ8s;~XzDI>
zz3*4jZszGhgaFUHNMadUE&RD at 1=X}g`9oSf-Q1a{&MGY~zVZvb4&gwf%$!fmd{RxX
zyQURy>w-rhJU*2v;xn3r2 at 5-Yg$S^8$xPkNaTA|xllPf)>w{m`aoL7Oj+)L at KLUXR
zZ^d_kB1rAf(KB9p(Y*AP<wBA3Tg2kwAW>IARR#Z#uG^cun{YkPKvN%>lW<LO_SmfR
zN0+OV;#rIeY_rA7Ntbp3sm=NEoFns$V-(SBzX;b6vfy*2092z;&}|})qh-$p>NO;W
z#`jn0<qj)KwNZJoG9pc7eA1?VWtZu!M5bhx03ulwDRo>5JujY3dG8SSRHU+T|LeTj
zObTivN1f?YF7*(8=h9ji1x!%#^k{0dwXhgV{8`GSX~{X{v~4dvSNwBMXQM-GquskL
zk;E}b_paCZSZ=N2!e_ at +=OLj!vGZtNv-VByW%IF3MR4D#W7|Z2;mS*V at 6TB&W6DJC
zY)bhRf<GN at 7~!z#yybkt$S#nDrC7;DA;sptdpZ)L>9dCAJmPr1m>}3L9$}*^?=i4?
zo3BD(qRKem>DgJ3wRV+VYo=Y!mF3y~(bCfJ8h0<$F|tjEmcL$8Jh66#a|Uwv)Kuy@
z`q#2)g<lgM?mY&hD*I{Tc&YbI`eqMS#OIRo9~4Y57}+w;50@(g14orLk2D$!Fq(!H
z;!qe8{EN%0Mf-e5!ZCX}Fp#^RnBGx9KUqNmg{*Xwd-L-tma$kUwu)D5yS;g|*k0kk
z_Lr$nfypD*KiP()J%JNMXafB5B7H!QayPWUnrnNZhTmd3KS!+O8pba&Vl<kgN<R|u
zEajI}=M8O4ETgwlJlPq~Cx=SNh-#Yv-`zR4)(tfb=GYQ#4j6b+X|4+*(v<(YHd~_n
z!%oA;QnIw~eX=C9X%*K;V=^A80sKjY7B4BKO)4`Dn{rrp7-%SWOM0=pk~---U0n*%
z6adN+Te)pK^iA3r`SXywuc2O_X_RYb^~0s2!B^yGefL`z2VZ^Ce;T!$E(RSJg{S2U
z4t^t}yZ at nS4_tOsI_<>>6V<il(|fkj4s`MBpGuC`ej{!J%DjGnPw8$o-(3>Ij9Eg9
z@*&B;ad63<F~6Y+m1}I*^NLtI$*-<OIkeKh8se!dmJuVcx`4~NmNCsx5N*XekR;GD
zJV^h|fVc`?HTo_;&x9xCy>X7MsGGv}z;}SZm`6sxNcM>xX`hcC9cBwb6|W{Wd;TX-
zf#SxpCLBs}Fdd;5YlkfUg=TOdg$|O8f$Unn6Bhu&%{BHsbC;bs8Sj55D?)ljJyJ!@
zk&`3}ZaS%y^~|>xJ6q9(I-YdV%~zJDjTCdV=wR4Fb2zB6=M&~E8l6w;^s at 1E?Q+i<
ze=hQ4Jc}lzz}C2My`&DhtXBdspatGqg$?#Y;cP|(lC-cL$DP1Jv-Zm`{65*GIY(N~
zPkXMGCnBpr6 at ONZwgT@sWjf+}dO|JVD3WH+tWkE^gft5r2gaXnc2P=r8M*UAS@{Km
z9dbmxKNBJabj;ElM3raRSKRNNAD0(euL6b7Htv4eK${dRR_bdJG|swqsD8 at p6mM;3
zvmKR>VyqWveN?H??GP*Cd-x9MqAPMKD-bIvH1!tKshB=CC{e5`n@{m3cq%GXS-<{O
z*>*(-<(yf#GMa)&XF5kBK_)a>)APZN*;f;Kb9x(zN^SEB{2fwB&vzHcC1WcqFVkYs
z8VjWoZLx_f8>sV`tWp`d37h5VdOoA)7_aHFQUS<<<NkDd%BD?398jZVCC at E;klC)v
zqa+`nn&zpr-5xxb5U=E8-m*a4CboQXp^}$2QyMo3!IB#;)~v9)zO06ngj*6Vo+S1p
zs#a+h#7(+|F7Vs at Q97!>dPt8anY%L7T!DhU-)ttF<iRjEDOZTZM~S%wYWzP};XtI_
zoFBYca6-gNW}h-}h)Ep&em3dtKSy<+P)tp$(79kn{#bh794fwSt`wg85e1nN3JAG@
zcWE!S+1}V8(<Z$_-!32gH(jY(=FQGJ<Jvt(jchSmD84L9<vin0K{y4=UL#4~gzM#j
zYn)FRul-`;K@$9(w!!)rZi&-5>Ob#l$k;DZt=&#>QfoeZ3fUlpaT(Dig4!>U8z#V{
zU9#bCSzr#*{rtw5FC)8AkY0u_q9W3Co)4Z!vptAQf}{gqxQV9%{GfPxO)XEaOp^`x
zUZ!<*^;-TV5;%W32!urIv;?sbWYJ$8D%e`KUsxo~7UMmmv9rzfWi^xGfII3yEUJuf
zNv8Mg+$TrJba3!(W!hDkG?0*(r-Tu6$TW9wO39iN%^Ic|t<lw4q)4nL at jN=Mg$%De
zVoK(Y32Xm`!HQmN7JeM60A8gLZg+bmDno}DkBnS_7+y+nP|#yH#mj?sv%WZm6l>Ze
zQN_1nCMm+$i=pjL&!C!jBm+vx_0heOA}Vhr8?Lb-a0gw*4kJ94N`=ohJVV$S2YChu
zQ&_GFXv}m at FuC4tjQ#H=GMB<(nN4@>9n|^vNBoDkhlr5(ytvWmfgp39%?+5AL70__
zGE)A0Iwf_;_0*;n)X$gXITa8+&xQHIfv-TDGuF6k%_Vx=Xa+tRN2BDVPfbsr?l)Fx
znNegU1*9hIXXG(Cx4y3+Ayt%uE<dE$h-bu5G&tCC+DlHrow}5j$>9;7&ix8qt{k1k
zDL at WNxR5$aA(#MSd}Gg0m2NnaeOxya%o*#vLx6U^lKot6Rl%D5S)feYV5Vs~IRYS6
z$IKvcx|ozHDU4S-E>>Ny>cGNEEo}sAHfkG5Ut2oY at xK1WJL;{AnuS>Zz*u(=>%3;x
zo5}Ls^gU+hvR0ysOU>|1 at n##%FIZa(Tdy;Va{1Y+wb5~v<uto*ffm89Tjjo*=6p4*
z-Ow<b(SagavX+g6{7I^)0Q^%5<a(wEN>FN5QLC6$l~O8GoZ0Oskv%P=?Xm`sB_-yA
z#RF>`Z$j}hOKQBtL8P5pTweDlk8?w>O1|y`x3F2Fc=lX^mbM^rr6REv8o81Y*@}#k
z-EorCdh7y<t at h((ESXg-o1YuqnVKy)$SR+)*1_2DOsjkvRCyc|d<hYF=s*U}CM(u0
zr)G3WPVpNk|JnbQ9MMyLC)&ql`*BJtT8nhvZ^=7{sRK^`rj<-Q>B}Et;~TP`$=_V9
zJ#a^?HhZ<Dm`Bol->x3KNKGo$8Sd`#5NhJE!|1-1OfBz5&wC;8Ah9(%c%PNyEB8dP
z#iNS}6ff8Aw|_yt%KK2J^|<e&e8v4J+wxsP+&PpXd41ber9$<IZe0$k1^18^tIVn#
zRlF;d29wyIiGD{wfqPhP296YIKVp_WpnD7%&@x`g{lnrU*;?5k<X*UdmVPZ7emBx2
z-Qcg|&HdnV0?msi4K@(=*m4ej4f$hH0!~${p$3fLh+H6$S~`tTO;f!OVylj4bnZRn
z*n88ZOL+WcnJ&4hdFy%o9HSDQTZFgam({crdz5JZZvD+BP;nBahF+2s-=&6P?DvQ<
z!&mO39fscrtiuqN5Ek=4Pyil5x#b8V{l}c<Pr|7Hd*q$AEb5B{X#NtE?UGHxK|2Hr
ze#HALa5x}RdbPQ!Z!5HHwL0Yoeea1v>7M2m74y1_n8kLdc$b_jl24O at zHc_<EGuO!
zv!076xRbc3-k_O5-9-}Sy*?!)+R+6NCy<8?Csp(?-nNT^u2GREyk7UBAeoqZhNWQQ
z!;kjLZ)=#oc=pI)k~7WmAF$1W$rDWtx3i)gt{Au-I{(~g?4Z-3eR2If1=C}qdz65W
zCmeWa?;Ue`3d{^))!8jdvf2MH-8Q;Qp2j=Va4OGVzoo8u*}=_Q at I|%nF#@%jilhnv
z*lGFO5PQb4y?PPG3hjICmvdXb9|)EuDrt~i;~xVvDy6E8Q^MQlr*>f>G0MoV1HSv+
z9KjW7?4CDutLG|zL*g5uUBb6cQh}6xgbceLdU2z>b5QRx8)$~2%`S at 0RVvqExzWeg
zmr{(AFu`)Vs^yeaC#nJ`OSvOc!=&R|VYFQbLfr>$#<TT&{*(mX3(Bg+x=Ft88LA at e
zd;BZx{KXVuvS%wZ(>u)G6_ctuZ7%0?k6Kl;Q8t=YCtVG?RlFDKXpFS9X;X9sv}ei3
z$MrKBQJH^a1!wO&Z+}7?N(yUsvWgEnZk7qtR<ik_ia64BNbb=1Ig5q*-RJugUjbY7
zjn?Pc#{*Jmg;v*<FGuJ8i^pB+yk_EvIXNZZHURHPmYH9=MNYZmF`nvvzQNc!@HhcV
zm-)!oakdst<#M*Lfb3IV<@;g^^*r&A6}bLGNQX|Fl&F+K at N=zRxrlgqzCTl^v_Yxk
zV1qwejW%JDCN9(S$5|wuC-vNUWLfl><!WYaWY^}R^Wy;8*-DEt#`<3o at 3+Ucn;qMY
z0yRCiT%=UlhE$xhDwljGv4<^I6OI$Ex at eiNWorWZDGK<g(QQ+ca`D&^?GCDpBkzlP
zvAKXPm2%wb6*|N5 at d<|LL&~xNH>|1@#fD<pqS5#`s_EhXSZp}c_$?LUdv+P#gDM&{
zWeb!nGS~SYCSL2*WpB4O9}<gYjO7|Ta at 4(ds>$8kk$k~o;Xs7OtO*M<j&!F)nh64x
zzGsrds_o;?I77MHnod7S2nmnN_ObLa(9uh^neHhA;#2k>O&qokBnSx$qT=#HjSNR@
zkoQ)1o&z at YoO&Xa`ewW!i}>ELhtwk3TW^C;IinG9el4d7QUzS1vO+tq;sTydm7JHG
z4T_T)PGlD#>MJJR&-#ymi16^6UjSjmvL>HO-C1CgW9<)jqu<&e*{h}GFXb<LDv9Zr
zwBIDJDPsn|e?&Qmh%Jsv&-q)&`p!`%kCx0HxlMmYkcKz;=`~|_kU;W{FAiP_x5YIX
zaR{9`O9e(`huGm~P{o0jcGpNJzA%b*w_v+CSl~}AE6`upxb0jVFvt|m9^s%CBOToD
z3Wk9h!uH)bL*hwxgu1vONyUcA*hR!<>fapws76>~0jf$rCcb7n+1<n&h^GSS(Vu4f
zB06b(&e!X_1i?^8$kv6?nrRIaE`a#{koE^CNF2+xI!@A(0d$j2mcIo1Hehy>?X%tG
zIa^%6=8HcdzQw-p!e7p_$*SWr+#%yL;ZrJ#=wk!!sWQCKJhFmsIEj36Qvz?;(CZeW
z`iBMj+nEe5OYTL*Jl*+on4#Kpp2+Dj24S?o^i8e_v|2N4%3il2qD<>wW>a+kq9m1(
zLi at 5i+BN$k9Y%Mto+n3F<$NMH8%l|=B5<z;SuPigQZF;fIB765t+Hu*Jz06o13WHg
z#EtH+k;q#a9~B2lizu~LLIodlUl;i)9uvZ{s;=dHOPSn{Zy%p7tQVR(uV|qUFN%Au
z?4=3R^*qj*0{<q%I9eWx9<Ky9D*a3-=&)-`&(gqk%hQmd3RTuL6(j4w#6+=rXNRtH
zU%M=y+jIkGj=TuLe?jMKym{IJWiBRhowpD2lP*7k<Q9oG-2Pmp)U%Z=d!99#&P|Zy
z)J=8?xvn)xp4_WCUvpK>x7d0H>e~Gsc^o$3I_k;tlJspkLZ&lWv7Cb~Bqf?H^Swsn
zrMix0dh1`z#~A|?4wvby7MV6x^weN75)gtd^aCULT)<7|^e2sFf<=IWN|&>xN-??$
zu$q(!+o;*BRFNq=ECI5Dl3vxannJdTu=Tbq3sPvyy!cS%UNA^~v0x_P>3?M;&7m-C
zVQTq(!c>_;yb4U4G$YedIXLI?leQ^gq!8%STQlmsQaTC8jQouXD}NRL+c%y<$65F5
zI?FRDgkTX#X4XrCp#WjBQ6A;qxeaAl^~0_~{hTWmk74=-xM1~B`vPSy&2L`Wzi^tq
zy#L43?*im`tAXGml=yS`m0qM>^CB|wi5}r}>r3eJ#-U=YDe=eX6drQQ9VtTcB-HHi
z0_Q!YYHOh+6Cxc{M{rvQy}RLOu2Nc_ufKyqB|hhJ16w{yzqh;DA0~IZ9o6R-4+)S3
z9Ceuw6eRR=A3tXq#p{~>g(Xq0Ss_F;XY#21(ELWri^R{QP;E5qXEP~KEz<AY+lA#P
zce(`m%vO3K$}a4|sj&I`Pkb1P4El1xPP9$>ROnzP__v|jve4Aj=tWvR1(luLyXONL
zM2lhkxQ%Ag<o++owFrc=*dKcTWiGK^wcb7Mtw-swDxsHH;~`H0*q0lO$om^4XFei$
zL-xsEI0TqoBP5MX(hY_EH;6uwfS<@2Cq7hfa4gbfeb{qKVfkXNY|s1{7fmOn;Z6U3
z at VEHsI?EQUczVyPcx6o~qD9~Ds*B+Wr^<O$%(nizNOQDC+eF7jhz<2f-wK^$ta4Q<
z^QwsNuLRR|kc-}s!VC_M)WQBB?RL*^&Hld;KW#-8|K3-Z7NjWkX9 at r%g9qg(C{r{p
zVH!WHq~^X2SN&2V{Xc1|^V)AsVtF$~@d{=0;Nb%xFIb at os#?T9CPlaVk at x)f;z`u{
zUpjuDiC=d%oqG3z^%_s92p+w&Q;QZ>;v8&jxmz+?6$=anv}t1&drKj6mSxZsZ$)YG
zP{Q#ENxVWu9u+l&zM;cqW<L26?>3J4;iH={y^_VwL+uJezzjrNtK#nTK5-$vYU3qC
z+F3NG at X5AKg-E&R<OegK?u4cYU}6*v1GQ?dF4OssoCZfR?AY?#y@{-JHsyj#vmN#R
zB6~cYFfD}M)N}r9*2DO at UU7G6@A2vg+y9Ug8_9czSfQgb-I<Yg)9sC6{<NOBpnJ*N
zaWUUT&Y?LPRX(#5rCBH=w&Ji;K}TP)wUvvc>D<t!<IF32w$UN7+ITU2cedJKzbfDi
z(TG4z0;ZpoLTyUQ!j)pB=;dd}vfSHO&LUlYwkvbJSvM{4y)-=L3A(k&0j4bO3z2WS
z`?NUb2^Qiq{{l1I`m4o;qUMjNBg<G}paax5i)5Xxq<~s4d&BePQ at zKxs+fYE*3BPP
zvn^3X3*-H&vW2QAy=LiEdnrLHXO&k7?u_*N3CH#GDL-?~cZVHsAMrBE_F59}F4oIE
zFP5{V3bPZ+7LJ=KLQ_{7G%(hEvl`DUPl}5=zrXD?9F&4)6*^e+uJ(iLn|SiPUfnXh
zEfp&k{NU<L>q;D2)^;k|987d8{dvs at B~q at 0Pb$gwa7M13Oy*VOO0CpWxqr*6+IkO*
zl_)@}+f}`ztADexuw+|vuI3d+bMEwI0kNg%;zY)Ha1mJE1n4?`EbF`Y<r)JMf{XV>
zzaHujYkbtRtx-RP68Y2i)RnEzun%0Ad3dx|<q`n;0ZSQ(k06~bLzVbUVbpXVB!PYn
z9Frfdx>ffN+&t<;+=Mb>$|BSs>}BgrCXaa^9%Qz)F&)R&yP}{CGE}o=3p0y@$R&&T
zB|x7kM2>tT%>1 at GGX*R(ZtpjLe}8WuL>Wl23+|#5`231D9Qb3Mda-^3D-ND6J*I9F
zAt9b*2(8MNdN%O8 at PJ`W6P}S at pA|oyFlLCy9a*WRy($eIvqnJAhs;G_kI5RBZkHTl
zv#)oMr%&(6?+ at 5*;WBo`qsF`{4Vq^&BN7qUoo4W(@V|HLnUYSlW;+Gm&}Umv0|0`I
zgN8zV at Cas7G`2Dc^blj7cd$8IPo667Xd)LM{Kf5&IG5`)h=nP3fZhK$fzJ?jw0-*Z
z%06F47HeCRw%{q}Q)jzt$5eacvln;Xe!#TOm&fuJh2#-qkJ^`ZCYM2O<=q#358#w3
zu389x$~&b;zDZdg;j($l4(~xZ+~CO+2?gK)40&&FQvs?J%6RqzeBK27xg&-Bux49A
zK+is<jtd0HeSmyyu{B{678ecNUcf8#CK{F<W at _jlY!Gqi4ujUXl}GV^Jf^iVokqre
zJYye){@9LmSHG+sV>%IddziY2Q!!T9|Ee1wDO1E==MP0z2upQAV??FP8XG5~yl`5v
z<kT9)``Ga())dw}IF6beXoj(~E5Yh26X>2 at M^;AeII~Q!V$8N#J|zb02ITvQo)JHA
z-?$p9BxMHa$hlRmD^TSs at bglY%u4al(UCl|mV2-^UC(mfKV-Q!LFX-9B$6s%AKi0&
z at fVNfJxk=(DVaYnt-TF?T+-9Yfi81+oVBf&IS#`9GvhJ?8CY-<5rp)$ZE>f*sFrZp
z%;SF18d%_ at +G5@O+eW<N&e~9Y^QmVjSd=Plc2kJ#L34%CnSFV^!9`1!V<kgCQs}Ky
ztjzy at K+v*Gv#gA-L7D4$$E5XcKZ5ssj}!vR>iEviJ|SQP6UnrXjP5yXn38$Zse&ca
z9314tJxaeTjs(PxqJBk%#O%mC64F!O2wc8!ccY`C7HczEnVT062~$r5zvEC9A`qov
zl=1k$Q at m?i_g(D3go<Dv9n|gF7`So{RL_T?%33dX=o{kSo?6_QT~66VmsxuaTC<9e
zh@;cil22A}e0=)97U2F2fq`W6bb(s}q#kR!_e+LOt9)<<nr1U;J>giL;Luav{bW`m
zBR*-5&6wQ^D2qY50n$ZSTAq@`K)wWDoqZ6ZzSL$~%tK1%JQR$&$!IP_!$(Orf0QEp
zw1{Sbwf5=R(-gP*qs%Yqw-4w1B$2z0;y84p-P9$-4vl>my?}3!b(-d#ETf at uLEBk@
zDn`=F{7V9B7N1tEvzKj4PEa)FH at 3oo6jpfabC9YY?K}ykt;US07tHtas2Jm896fSQ
z5U55Y+RFqtpZ!n3szEbqu-Cw5YQt?xx%gKG|Kzzsaqr(CwmH6oWa2vMUK{eA8jv+u
zE8Nn%ovO-F3EXnNRFU0Ea1ZwbXN`Yr#m;OVN<`N at a4$pqAfX6cxM|&9%f at m#$8<r-
z1 at UdTp4zbuUJ<t7MSzx6BB}aeY8&xFg}T1c+zk8fyg#7kpm0Z6O8Mlm<AHuNg$IAl
zC0^TVjTS!Wn1M!7itmGKwQ@=TXz9VSY4!0~t*dlAOz(LcBi#uid5tdLDEzX)Q_kHc
zG}q*ox>@eBQXydD0(7yQ^b4HS9uZ9AVVO3HN<i>W2GC|G-FEuUqn$Jr$7vMSG4skB
zl_Y99jwqKwRjJaBh}Nw+(?;`^y&=EiUrriEQX>S=e7cgon2M;rX=9+SEQ@@tU at HBr
zE6PY at V8T8cUOvP6Kr3r0F*X>vfVqQUInFO``rO%w4&N0F at p_pM>nc^@jZ2Y6PwU85
zE}QpYX95%(Hxqt_Cb1uK|69Is3n_8Ra;#T65?JPcn at kZCfd!8<$J7w2R&cI9%1p>u
zj79z&jS`e(erl)#PA4l8z0$3N!GE?dz4DLT*c~X8UP4s7k-g9>9J&Qk?_<Ouvn=8q
z;Y$8|(YaUB5Pb)yF3PD?Aj0F6=+Ff>!gltT;607(Y&n54OE550WSwu=jYXj%RA}v@
zPvxf+N*sbLwFxANc**^+uCG_5A6fc_Og}KpYV0ER*<GnNH-|K%FK;6Z&H!8Jk63s-
zHRXIjFp+PjRS>)E-|Fp-{z-HTfTB&>#)LopNKK}|`+SwlRGI^6mQh1^&<i3OpJ*OE
z at Sg7lTfL`X1HI+&l=GkaV{6Lv!-Zlrna9GkP;4(3tHr@>UGK6hXD<QhV?=c;$pE=}
zKN(|yNWEky<{Do9L`tHF!i4iMI*HjR3N~%fmy&PxssRWc+ELG>d%J+Pe;X9%o2Zx|
z-F$aNR5F*Z5(oKPO!o$-F4Jq%zFc&RHBUqdUEH6HG>aEW!)(B0d7pUO{7$jiN+LdL
z#8k>w5tS-k31mpLVhsfJ9GC&M^Gi6wjMJBmg at 2!9edQvIb3h8!d7ydR%%2$n#rZ;t
zb9uNfGS(%-W74xI&$E?CcgX&Be{c4e%8QXo2mrZtKD@>v>cAkK+)cEuEXjhvpSgco
z5ANM6XN#h)C-P5XBYLhWQjxJ-?V_g3)0~t;3Ci`lUWM3p462eFV%Ucowc?$_keM-L
z;Axc^-1K?c%${KI7!3b$qN{+E8r|j>>11DLx<oE8(3bKepD(W$VqzfBT5u?;CJBWR
zR9E at o1k(TrDcL at J)T~Hcsfbj~@+w@&@QNjA@(|TQ{T#b0Q)CYxN3%F2(gPQuZFqcq
zEp&qvDyFeJ_6YdQat&27jLAeAuYPIgK24Y~otMRP>TRVy9;Z&vH(8E9W=HPES)B()
zhue(8REkQsIfQ7h_~r!P)PK4n|H>wZfVZ=05YksWcaLhXw at N=^v>gIIo6WQvyktro
z*<YGfhiyiG>5nfp3FJXXcfbv7S2_PNDqcGZKn9n@?r;F;bNH6Lv(mk<UiIM#Xwky?
zE3;#Zh=L{1t_&%o>L@!+uhW*%DBO18#`C*RekpaW`67DQ3#IFjU$jX)P%Ng7gl173
z{SKE+_uqvhEb#77TQ<1l5Vxd=Lny8I!5g$#ZGjK8D9C5_dmkv2-0WBwlp*4<Kp_#i
zftAt4BRJTXA<_+&HR?Tg?U at W*RQ0XvSiN7<(TL2&I)%L%_D=VRmgxacgFq<sR3b0j
zW-pyS_af0(kd`Ojwg?Y<;A`@wxc*ovckmqJVK?G0Cs_oaZFH&{#7ONZpGj;M{rf+T
zX5kpvaDOsDqugmEJCS%Gc}W0jCK=*cy8pM^80bX^=pXtHv7$`!KVlw{qySLtezU~i
zTnu9Rf3V&n{pXgz9gl?{oC{ep at W=EN$8IhyNP11=hS%O}TR~vaw4dTHA1oeRr}nV!
zyY1J^nDjrPbiSv}n6A~c!_M24V_Tc(9uszhf!E+cKs?ji{U&-Q7WStQtJEJWOYX4X
z%GAjHmJGQf!IT<oy)}hrGm>{;_K;FszB%(<5m{$=IYE7gvphJhHmGW$0@%V_Vl0VK
zg|ncOOhyl*%n#Ajx<e^q03+rj<z(ve;5B<T1|r6TdP;7SSlzrLuVZ%H078EluN0LS
zmrLWAyR9M_jjA_okJaXI%DZcI9&0gON at 3+)=DOTLT#6%I<oM=~mcTTrvNA9ow8&>b
zzn4r$wb`&%gjaJ7e;r$QR$#nEj(dq1ZQ at k;dkPro{gf=XpV9kBaM&<fAw73+3p6z{
zD46)pwAa8A<034R4h)|wh=j&-BqqlTud at EntK@D_3QL&#fLG#-&CNswIu)T}eSU!N
zmQv5oYKGU3%xj{T0)FryKS-sMN7VFTE>xRl2)~h6(s|Ya$K;k<o`!zb{_88VvgB--
z^lkLue>8n{RFvQMwMvQ74N^*{q{PtON{4{-&<#VUN_QhYLw8DtbazVE&;!!_KA-P;
zfB#Odb)S3hIcJ}}_i?!jM2`U(9TD~9n*N(M?GHe2PY5kS?N at lG>2;&R)HF2qbG~(+
zXLdpE_#DBz(|gv7;O!eCq479X`@<7NR$<i-FCyq)jNHTTLQXZnWXAp1^rd`YYQhYC
zLisQH4|5Iqjtf7Nm){2oN=GtS96zWt5_oa-35Ad{co_ETz7z3wC%kFVMZP5CIH4|2
z8s|ob++;FrVD%9yX4l4#HK8-~=_7>x%Ci8BfwuZT(Vp=oWLAzn;zu|fA|P>d+yn}K
zB7?M^8Zq(r6hw556$y^A at i(v6Bzbb_PjVvJ6R<_7h`tEV at 92WoTJS$_Vh#PSwd{mN
z at Ek0>chR1|LWQYRmx at Q;$~mDC{*~)>W>w6SQ0wB^#KMMid%7<FOM{dCVjTJNJray@
zrh8Fqe9b&G=<*r=9rrHh3D?=#c{TM5X<I<ufeiYA4tS*6a#kF+oBb4z!wzkgz~XmO
zmo;tJ^E>Poa*kds`0(O7h~8m=Z`QirYe>tG5tZvnSbhc%%|uJY)3T-BI;$QrKTA#-
z3QLR?m2>RR83f~-8x7Xe*>xMm&0=9C$B6>k*-{bP%bJ!hYn022Tagd3TrsJLBtllL
zC&pmKCZm6K!l__FEUj=-j at vc#H}d1uIuV24V5Vm+!s_crQeH|*OQtM~HtEN1&mb!*
zA=qO5dEn+Ph8A_v#TIxS at rl~i=qx+oO`p*qf|Q(G2^N1!#>9hzNnA`R)$Ulv(Ncq-
zV9eYtRVA7EEXQXol%wQuQEs$u_9E)oQ%zCHdn;EiT+en?7H*<8^dTx(UKyrVO_l<i
z>N}xka<ASKH&ym$xGoO#*2hN9gC(i1 at _Ln3z3oSQ051{f`hj^`Xm^5LG1SiXzIID3
zBc`rx&NbXiZj?xWTSY2Vjr%smiY8vWUhEjjvNQ+wA5{5g$;XZJ1I>p1NA_ZUS!*!C
zWDcXG+HZzCvFdkyw`6OTZ&9Dxj at of>WW{l(n(~<VTHdH?#s#F0M`!WlLRh7?BKv*=
zULxY1QlX8(gjU3rfROFTRUhtlHWJf0KE8~iQ7PIFlWQ_ at mL$W0Z^#u!GzO#a01|4L
zvlAQhp|ml2jZmuCb<tVqM$a308~#nKK5O-)_ at b2R($VjUJer$Wro!&k#Ut)OD|XzU
zNP+kdg^;=rWfe|m8c7yQ3;{&y8JMs$)u}(A_=iGY9cZIu%8u=--GNGKaI<kCr%U`F
z37kSI>Bfx46fNW!TpV}l704PR&``L&EXp-l*WX67?{Ox;RJDZkJv^q#W7sAv-w+D4
zxcZv!l9ehseMw~lp&GH&Rn?3d$&iuV4xX5#E#V3LNMtcXiA%Ga!l at BQz0LLcr22~U
z->$Ce#b&h7Mq?P10cFKcmkBQB#?x6#Zn7<1Q;O^PS4Gapzl^;~?=v$onw2LuOt|k&
zP&QivwbsI7uUX5?c*eu?f{De>Y8WMEQ=X}l{<x}8;9>fTLXd6{-juTCQ7=;DHB}dX
zFbjouTY>W1Q|~Z4n>+qfF^fN=-7znc(YTlh%c8mL&&Dxn7YR+&a0M=T;<r}e2vhMt
zn!L}E2pX+hIVz(KYUf>FY-Dm3u2dtbAu=n6vN6 at Glq9VwK9e8W_sK}laV%q4Ezh#p
zQH&V4`(-{d$lNNMzHF_#3(~Y}>EQ|)#p~2O#r$PK(*{}a55hDz513lmGCP2oP-jA4
zd)!Z4cxvhb*$Y)Ax;{rT!*dG9$At3O#1}fGBLT at _45oBZx=c(X;h(xhnO3XMdpq#y
z908N%arzCc{+Hpuq;`?!_cwrHFQ_#vKnac9lz|zRxePGVs-f*TCq}<ho%%RA!bQn3
zAg3cA+)^oCtNp<uhMcC|dwNWO)Xuh!ED6 at B*LhE<={}Z>_mWBwMYd{LnaF=@q+J%@
z5%0 at kY~Ap7nG7Nc;!H=aoy15uFOzSiA==iNFvcAh{q-GGv<yVuP~p7I5BcTTKS2+X
zA9gs<A+%#7rv)Yj`@w%HaM?F4C%VykJyFxm&L9(n8HA=<lq3s}AQP0N)(!sU-XG(^
zT=Xwsg4O5ZR_Ycvu;8BD6Azq8^kjwi+YSHL3pdd^f>jofCtPb{<jMHnn`2Yx++>Z|
zf!{9H(R;B;%{!oyX_?4LN7VQz{gk5%3wmpK3d?phn(A6gsvG#Yn>)r#*Nf@%txUm@
zLUktu!L4=w`ZPX3O5<BZxsTSO?pY|C$yipeK<H}?-D=*`a2Fo^UqY!K>r&z5*m7gG
zy^q}jC|b8gSAAgVI}C8-0<Iay#q|w!jHV+osm>+PSn`cNuHGaq?Wxx5P3E)0R%%^9
zah1UTp_Org+lnK`&14Z0g@}<%rd&7Ui$K at Qurr$KB~f at 1FfHjaf3VM@h{Pl~Fv63y
zCL=r>=#9ZbI6Z~-qK>U{;L_`u;|97o`7})Oq`xsmwnr9f)w*-Sd97B}DT?6DH2WtP
zY=l61wpTRcrUYTBh6~VpA4N(vLo(>Xe+Fk2Um$kMSil+--25(m;s`lYGZP82<Y!^Q
z-{-8`dZE^~JrqtBaVT0|CekI_xsI|Ik48J0U?Zi8rs()Yvc<ElOFYxqtR5Q%;ZTEi
z*&xv75qE-u*K6F2Yag`WG<LA$ayi50{Gr|ZW#f at Sm*l}!i7X{xXSkcnKbxL?+Qb^m
z!GZ8E7E*o5D72^!Kp{s&dDuIzFl<EA_73v*EBX+&D8(svZL<)uB{+uY;sDTb>bBI^
zuu#zE!`Q}pbg0v=o5iLh3vt{_B!>^q4^52}b(Y&nJQ;(^+eW0BItdw}TgGyCLBTJ;
ze3l1NUP#=+sDKG|o;p9+dzbWz`im1sc<a6;&+d>)S)Ef(qMf+HJDGD<mUjMtbH9Nf
zuIn4QD!Sssl{J4TXA^WD!6uzru4NT!PqT;sa$EZY%c-Gok3?IuU%#Al%f<xc-W}nw
zs$u&X8RdLrti2zoz(g}oD4Crxyf&(tkGVa`=%AJksU?xO+mt(xEWhM`p@^f5g8xce
zkyN%GbfVdCEigh7CF~2BV(oZGj`xqx^1N-AHRKEFV^SR@=>cyaUfgpP<*HH$oNV9V
z6V%d>fOx81HU)SfFgfh-5IN-TCx<NE&{>@dSt>3dj5}}$r>k<sQ5*1|9H-(qAv_C$
zxRp?0sB}EIm(MN~UcOu>&5Heq-DXpu<g*)2mpx0eEE$wcT%(w0eXFMrH^hb+O6Pob
z?5`afA3R({{N)_5PKQ0+tVqkA>KOb+&%V|n_`WX4NwVptHWT<qn4PsRnjHQ{zl%O1
zSY9;Yz1HkL*0^tv3Sd){ImPC7DBMfZ2HZ6tl%0sRb{;_(tc#e`glY0`ozUhPuU|N!
zB>=R4x$?pX5fqw?3_K}%&3T#=xx734FY0#A at 0Yt8H%XMd>P%Tsz7M>hK3ON1?xA>k
z1j3SQ8|`w}m?!yBp(9=dj~P`j??7!dBA|1{n-3l0xZ+(9v3m|Xpu~VwnJQab15Lx`
zy)H*I!V4_G?K>CDDnP!xaTz-!ZvK*ieg^otKkqc$wh`G3FFK7zBfzNr$=X6Wjqi_E
zN31`5oe+7QX7%fp7!u1=OzL9w5?;PQF?(0{FUc#vstSI`gle{aY1udLSo$#s_!6!i
zjJk(j at u9TvE{hdxR!wgp6uhvPJ<1|`#3W9M&}4KM*BvRv1@}pu#1;_K;;UUe^fpII
zvBXD4q$^R2CD$P1zmq<mf~U=+c9pmd;Y~98zG8-aEH98NHO`H><SxsLVB2DZAhEKs
z+I$5hzBPw!sdr`0ud`RAwWR?=re>0B^dxPcFJ~gciN|l6MoZ&iwTnc%8`57!j1+je
z8y=y}`mjnz;TpU{UowyhP_L}w%Tq|xe^Sj#oYB^5FGAhA+(u$_et4{C8}~>R?7YV@
zV_;R7tXb;c2D!iUV4P-5aK&fNQpF5+HAyG0iP(Tpg20m(i5l4Sg%4T$M-)j at a)Y_B
z!fV|~sxsGqj=LjbN`JNj<(HyOal}Q$Ia^RzfA-olf$WuX<b(4xyjep922ErG#Xgn1
zu5la?7-CfG{17~DcJeNKSZb- at B}as*$mfG9+R$?@T;Q?Fo(0e at Z-^H5%PJ8-(>U=D
z_iTE{yz#yi_%8yW0YM%x3D5${l{U|u;GHgm2a!Uzc^(4 at +iF=0ZVG=Wj{4YUaKoMM
z)`CH;DKr4uFb908uNLOqt3x8K6soykp!A1A30Y`-_XGJBIj}W%fiW(hi6Z{tLcXwu
zxqK%`+{peFh4Z+-pji;cxwB$g$lRAiyKL+u&TaTiNpF+E3kwJtAL#C-aALQj933GA
zp*hD3z1CSY$H^1G8y&vk$P~N5Ig8>P=<^J)^e}hqxqan)Yr+>)K5F at i__FaaV8H*A
zbhJjWWhB8YO}rR!$SFw=hO6$zmVQ*W8xK#O4-FbQW*$=+4hzM_na&=CT3 at oY1I%dR
zI7366od+rNHIGMZJoj-4P3f-ukggD8-f#3-XUo0bH!q4=D)MS;lpQeXr4z+3jJpH2
zXtRRQ{8kABbDHr&k}-Kqe{f^f%M2+eUPMtaKC>F^q2Ck>5tYsyc~wbJvdAZTZD+{F
zZ({6YI4#V2_x8T36gQ+obBF#>5i)wjB7Ljl5vCv$w at FAR04@9YQacg<iW1(*Y4xg_
zYkWZ#U)24(4hq=ER`M=$kPIBx8e-5JZ6xRwG#MKkmViwK*%yfE8p;4>NWY|9h+CCj
z<ppQytne8 at sW1siZz)7<7GA0_S5;HvGUXzZNAe2QZ6Tr#>ByA(q~gM)kn^e~Wla?j
z%KdZ-qzS(3B|O61{GXGM{Y;z>UHVwxWGOrCrL6z(4o>nOo9lUFOF$HwN!2I3mXK`|
zZwt5*nW6TW*tSw(9m$pedx%CsNp=|*G)j<d<d)ezSBC_o;jZ-bTd>UPO@|ygdB|9;
z(`PQG^(v9KBJCnr|J18C<2IxBxUvCc_5FsI5qK4mLH}FzmNk34RG)qPaIXKh%yPu8
ztXC?bv3p+ZAsuL2eC$8L#}{+gZX-$)!+})k;1nCHst6Dr0Q6zFxIB8)xfttRm8HzI
z;U*RXNFzE*x<7a$+LN1`A=}6K8w-nb=@!QaK1Fhj4~5zBj%AEG`}D>C`l7l at LIN$y
zwbTKsSYb}06rZkT0Q(SD4clk{fiN?M94Z=`HvziySAhZYkaF~%g%ysdE~7wAV>Gt0
z7dH at mm^71AiMRB;Z4eTfDXwFB{7yKbfw_Rxkb?UKB#him3q^ROKRN#qf1oK^-h!uL
z`@Kp#L(5N?c6I%z0^v&z?9Rrg{d7t?!{dZl+Kv%g?jbR+w#F&^N3r-ws>dgC0+SjA
zUJg;k3I_m)LsQ~5?T at eJD0@{?)g`911uCJDrh>@{(1_6=#~y}#cy-jAYQI<CdyD^y
zK^;lo>gsM|M9!5ZCcX$c;9_aR=dF3M?+edzb%78x==>Yd6b~i0Z`463?no~d{$ov^
z*Sl+!m4T*JlKWH)b-{$6anYkrKVzz?gOVHBNn{sC*M%|>^?(*f)w<|lAlKU+qxh5v
zRCU3dR|6AInCA=(EY<?#YWpAMgAw{P$inURZ)I=@;!14p-fX=<Vc^duxV?E|*BX6n
zjp*GJ>Sh1dQ5lx=$?HH03~}Cp!Z`4e!a1wFDO%9pqWe$avkS%o8>%w<2RnVE;q)hM
z5&h*ZmvOK<a;IxGSe(8BX!iBn8robuLQR;QWXB`Po#qD>GYXC8znk!CJ#Vt2L?Bgj
zj3U#IIXA00d_i1;xVfhfB}iHSgClkrRY!uz_6_wN^b1A2qi_N4Dx<f`*SC5|9QML^
z%ecMtI#m`aA&o#sivdWwCad|!d%9<87m`E?PSzJB6NSP3u|MY{GlA=^UEq$A4k#Kv
zjOkywSu~!Z`z%OAAWb<{1T6B05YT9g{u;ds;Q9Lv<{BF$b!uM0PiURT%8EqDQu at Fi
zq~?$V)AA-iGRt3>Js!}t_}9~&eon*Vn+Ib7%kwwd;gDgzY>IuIlb4S37v7Gru3yro
zGg3PUPL%moMsRN6%)x&*>bTW1yo2&ix$;5ZQ&~PBWe^wSHTn0)b$#pzTj|zhYq-%s
zt=dd<VNfI*LWeMyrxZ=alrJ{q-8?$J6jqB2f(+Hxy@!N94;vewnrzHjSs=|kzc)mK
zCv4l;q62w~C$q<e{l~e)B!7ga-BjJ?y0dHIHLG-nsqtiINEEj7SnT9S>M`##U#aoe
z^iQZ_C(hN9e>|h*FmtVqx3$i1 at pEX;>YxNZ8i`?IoY~{oStuai0=3v=NkYC3;^q`@
zHjke%2IeA?71I5$h at 4-CdUPB$%6O4=<(1ASj_lr<{0<t*MAbmOh<q2PwhfC`>pH5c
zkyKE?MJs`}GMWZnXTb;a(7so$+(!j0A)@j~IIY6hhr%#+egZSE5t(<(k<>v3awae6
zpADyx7c>IHo%=%mP at J*K0r5&lV0g1OyOtUm#?IXI1?Y=zW+|(E2f`hz9}eV86m!LX
zD2V)57$|j_ZZxOH<3Lz!WDDGNYe5tZ_)h)+npto39NU~zGaG5h`t?++wMs9GX{RhR
z6|4a3ca>1nK-0R)X%tNeX&7kp)Dwn;2h at iE2D&h;atkC>PGrReeH5zfONX7(fbC76
z65?>-@%=E(W+o7Jr*<r*6lvy2rbER6|5ftrG?}-+oIZ8;`g==@lMzQp-k}fiLp?{L
zVSmROsDdePT{SSnRvDcd`Q at Dgn|Ex*<6cSl8E-G*wmQBJOXRhvKaxAc36K9l9=;_c
z-uiP-YRvmzCsnX7xn;zx%_{ajHmp$^{WEjgnWWx#@zT;*Ath3yJ!P>s5&kjQgKEVy
zg(}@D1axs}9GqhRyaqRR&!KPYvDHedzX*pcJ2cO`2)o1zhl}tpno9pHH$qL}cT at _*
zq!iQ$cn=m0`pKU&B-u at fO@*B3cOe4a9QEGCsh!8VJyFg7etgc)Ek;K4EbMN{FDKuD
zSz)8*(MsPoP9cUq0(DSSs%X{TYB$NVwpQ8x3(6u*RaMK><mq_l6%lJ8-rdVsJ+}Bx
zYr at w<^`DS?Q`<KhF{OC10-knkKZO&SCH+L<C`$fG#|gwIh2p;Jo;UADL*@T+ at H31K
zYr0VWIZ}`w)X_2 at jJdw2Q>K3sFfTKGA6gy!g1TZ~4m})QAi;oPL*oy$BkdZ?H?gt6
z>b3k5MIhJ9veJ5|-R}hF1JD?*3VC!n*j07J`Wk}2M?k9&?QSskPHH)hwp<ydUPp&^
z4>pD8g!cA3Yzep at Dr*7ofB<jvx|$y+-`=ym%6qp_;t<XKO|jU3?#Bvgz<EmvKoD>a
z&mto={qHiQmc at _uF6D{30kE8*>?q^Ee0*!<5vUE;0CP810F89Z0Cs9$g(@Jes{?*p
zo at Y5U4f@In at 5HEo$EY!wB=CN%1Mp>?!fWaS5QJ10TEM*~_Rv-EF_W}e(mOcrUpKYH
z&M%L1jOD}zXlKB4J6|4l at g5m@$nUhBIQw|Bn?AGeghL)WKqLF&j4chLX-GnZiY0qF
zvii at iSns+#&IvPT;EUT(<npp)&RA(l(W!Dq&f#Q>WgT0JK8Ps??wVqJvVcIft1v^<
z&ja^r6T+rVCrK^=$NX>w^LD=UG_Ek`(#)FhY8J5{BJ|{CuM$4s6KdYv=RL5Mh9IM0
zHD(;HThP6ZiC%W1=FplEuvA=+9p2GkPr2Wd_OmZ*?>+e4R4z0i_swWM1}_O28+k%?
zEW^in`khG)0le=6UsmmV5u>)XJTorOr6WA<0Gau7Mu<wgFcU4zu~#6RABq=+)#g{s
zAxphyM%^c*wcZGc|E_<-jl8QLlHq3RmULhl`CchY&MpT7tl^SZ at --eHRwAoXX1-A`
z at RAAHle5Yn%4Mk)!rxQG-O2Erkoip8=i+>6YJ&5_!Nd2cNL6GNZkHiStvL*ats$+^
z?UWZY%bdP5McYDy^X*6dp$+2UqIXdhjzcN6TvA%@@>H7o20SQ6ItoychBrV0^G*bs
z(VLF!ObRpVyP06XXsE(aU6=(OGU1^-naTQpTmb$%AKV+RF=wrCAX0t-X1J{FG5xtW
znh)ayy4k_=$F*tamOO?#E!8$YJru}eld|JKGJy(^-3NBo`>4!pL%w|Nm3x;Lp?k9D
zoYl{{bpPwxCbILs;I+n)HIQVjt29CU8MY*WP4}ht?}!e-D`6$VANt`a%i0LQU$OrH
zK(y<R77sXEmYb#{8;u&fRt^OUVq#%j<*C=RTb0ZWLSo6s_;MlsKL5L2AOG(S?8{@{
z*D^G1w9_i6covNqFAOybWSve^LVjY;N#su4w>%g&({tx=3TzsSXK}M|RCFd#$s72(
zlY4ml{%fbnoYcOqh!Vl?I1+dai&}rNot;mcjhMAN<M)9dyb^b?U5RfH7vV$_1o<d&
zy;k5S?rCU$i5ZL~4m50mDjyr8H+O$e;<KmhKVK*@Dq(Hj6d6AFu3$nsgFyEDiAFP~
zJMKTWk$et*l8&Y+?+^jGv$4Q*FE7~+1*y({%}6w6W?Wj)-Tw%;!QuvOhS~rhih`Br
zEOM1DQXIzVeC#Ny1`BR=(K^8-Uzm$A#60tZRw8#~dw;+xBTJ0C9tR%_bQg{F4l!qr
zZjtLuP1umf!qay-_*u^NMV+cv{8MC-<M78fNkT?x%tsM_$Fs at rim2s7Ao9#f3cjL>
z-$)UhTDQ<vPP!7^(VdA;^Vyl(=yR#aHy8keP<U4ipfD-oY#Om*-!-}~yf^zDQ{cr~
zB`x#P^yPdmJ_FIM9C299QL74lEsPMjRXi|Rfo|~=6)*uHNV<~<u!aO?xA)jC<L*?^
z__CuzV!0G(4EvgZL>eHMbyGa}E+aTss|OUa8A_Br9R#vGVs1fEARWd{a at d(tzS{ny
z_l1Y<YlsvoHZZ$bmw?B}IqUn!s9}?M`N3Vrx=!w-#%|8wUN(TwzkwyH4x!BJ;mHn$
zx5>HC#DYVTe*lG}2W9`_RVc`ZB9Rto2Kq$~qO~l^1GWax=f8k{g6hObz01GffN^S7
z-ZQJvqE7+&FH|+*uhI8oZZ*1A&yv{#p>qyxviO+}6BZGyr?Xgdkf0Vh3C=#wkocn|
zWzX2lmd_QAy~KTU9vUT1I4(&&FVhmS at 2abs`^_fCp?c+G)5KuH=vHOQ*6n{Fk9q6*
z_AZGa_vT7jmyx1^Eip>oznC=-M>@Ck#PLb(3nrIq=4u2?=JJFLV+2*ais3K5-cb6S
zdsC2;AN?ApE=*caJ`gy%n~;hKu{b*Ya!kwYa0Yr9*SL$gz|_7mp<ch=B#ZFlRAmPJ
zvmYFeIT!Ou_OYLIVZ_Q;JSgt#S>$#9$S=FYOp at SL`7t~U$Mw#UCLpG-cry2I#co**
znWZ}C=sZ4?==Nngu`S2C|J6n(vnbjp-^N~h=4 at qso2N&^>2~(?S29Cc37JKdyTZK+
zCR3Dj%25=VKQuxY%xQc>HO1c4;7s(S4l3|@?j1GXjO$Kpum)8A(7^om7JkUzLLw|M
zu;DHthvgYL85g3``S~E7WjeAux-`SnSetQ3GocwDbQE1FB&%N(wuvPaqa<$n-q^yT
zz=1uSg1cgz7TvY)13e$IZ-&+Ij&qxf2s(tHvg))8iyo0Slh#-OMfOR2;RgduY?<$r
zfk^3oNW&&@!q#pBh){k|K+||!vVpC_QcPOM^*&0iy at x_0eMc#=gT<@(2JtWQ>uUhq
zIAtw3eOn!j=$9vIk)A|OtF;3#(>`UrXdvcUrc)LNPj1JD!vL^KT2T$2M=nB&)gujL
zff^&w%NJH7xDctqtHy%Gs4c|Ko*Yk at h5dTa3-H83Z<xVZyBYluV@*)!n~#5$GK at Fg
zZ$-|`BC83vzG%`dmOMUq^R;8LBls=--OHPn!Q$QFNH*3fGZOOG6Ax`=SsdJMgx}Ld
zULv!|Y8;tdrY8Al8HV?oWCx*ePZf2H9nhnVd3MG-jCU%lGiZ&c>Qu*%c9mI9^o27A
zs_|Tz+VC>(NEbSO`|X+O_i5WV;Z;v}92$KkQ#xzBB3b<+pz+f`@V7t<5D``t_$k7o
z8Wg*HKwGR#@4ubFC3eb@$I8J%hOD7_93J+%^bxg96*DF$n>jSG(=2~5uo@`hG}&~+
zA_+DBS?dn03#&e|jFm}sywi%3d%4r9hkU~d1I#KX<fdh`Mrgp9^E(1K%vy_lVgC>W
zuZ&-jMPTTo at t`QjS6u5^y#FJ)9+?8ma at NV3r(EMq;MCfo>ByLR^jU=oNNd}ri`CF{
zyA1~#{hP at oKR4jSYSeQOMLLmXpn@@|iTtX2kCpk(=Tz8nA$2_n%=Fel$luht*8{h-
zGJ`if+`XDi<um4qqQXo(>L7T)qp#w9uWkmiw4O$yZxq)aGMIC4bG#~`?{eggK+ at aA
zYA_xyxZH#eq##-Qiwb_zcnyW<PDRpH{>ZGN#ii>L3%2R=86%G)?UMTS3RiWcYsgOH
zT|St+#Z|*#YgrdI+#l@{Pv8(qq0s|9#lqhhs0*V&QmbTiBX2=9d)2G*X%RVJtvH1z
zAx<pZl;E2Vqf<2A*^!d>T2;cJ3hq4W7F9ON7T%fjg at IXF)H%>EsXia!J?@b8dXGXn
z at P)d<WPZMS=8y+~S=*yDRxc0dSrqMUHTupZf2F2QthRaIH>T^0O(HYO*VCsTN}u<?
z9$?&0yD**`^#4qz5EVU+Oow()q2zPpy}715^!*kd7fc?~M&w0_<~?@?f<oOeBF`v#
z59OQ3V31Dg3%S*K2?Qk94gc%OnaEasKO(}PPhK}TL{0<ytEDnSc}EdFVP+rpRV45W
zX9iM(<FIRwB6t>Tig><`<&H(GY!BrN{j!iPziihlY4()qi;FsXdU~(G{V&(47k*d`
z?s=>?5;ipZ_e5&CVK#S;bLSEW4ki`a74O!H*SkdFZ{?ZY-u4DJe!?b%5;s5ps1UY_
zp=%q4!6}l0HtQ)4JU<dZp&_bMEuRHhHbJ4$GjE0e-ms at K_P}va at bkJXTAy!}u<Hwm
z!@tTS=tcMx1Y}*-VPK0+K7g=%cIJc$5G>V-FJ79`ODY`@FC8MgJDo&ww`y$LeEQ{k
z{!uAF9{S<OXo(!M9*jG_fjA8vH9l at t-jOUqjn&9mCG3LQpNeojPdm9Ifr8KdM_P_!
zn`&>wxu%K=f1 at G5mkT~eZJ87ankP~&Eq30$cezfbUZN01vLIrLw`_<5$PV95r2T(e
zDf#$MA|kw#;^%jqn_|Xx;ri?;-a#}+b$z4<jEdvDqxNzaH8h#43O1AX;bA06h&MkZ
z5Seq<^{eA9C!EDd at +`@;ntVh9d7kW6{z9^H<7OK_Hw|FWT1U8viW<YuBh1ZcfP;WN
z`qt-gt~?$FjTS74`PzD;`@rh=1R&8-Kj|45E+-_ht!7I!h3_b^jj`4^tIt>$li9w`
z?7P-kjFMquVzTu`_Kt7DJ5CE1ZLOW1)!u!worsgAES{X4Y&Q!c5Y>WP(c$cCRO=m<
zRQit%zHWI}fJYe7OW8;-9K!AP)b=C*SsEla@}WtEak0RWJViCqT(qY}CFz<pm}k%5
z44QGZVQIzl;p}@IWjH^Lh2>ZFa@}SG at 4E_?Xq5^#h{0L}!%pix<^m-bcx+(vxTX69
zzIn|bm<(8dN`D#KUJ0WI+pZ9n0TONzPP4RBi{0<AFN_!HxRV5_8ZITx(&h%!TO$gg
zsK*+|AATfddW&Ma%d{5gvKsv!Qh>2ze6gEH4 at IOUjxP*ew8g6_2I6?>I(cMs+f!cs
zzB51ilQO)s+VWrWG~c5_uIZch;6yL%J|XZ;!8VRAG#4)xKMmMVY~R{_45b~<YJs(V
zn7`k47AV(mQX5YBINyyex}1;#BsXpE%^Ko$2}j}QOAU6vfE6w{J3H%5t^V&Dcs at 0Y
zWm;uAxz*L2b_-SF at qh+(2EHYwhehXv`E$S@;*=DB{oqj$IAn7%@&3oen)FjU7{@kr
zkTxO-JaxdR(Q_NYs5tD&Gba9Jz4sioU1WS(T2MK$hORB%fH3_7NJiEh_3oR%t<jW}
zuD6%0^t25`=Rw7~UN2kpwQt^XaZYEjI9DkG^)8M`MI6-~{gKs&t)0rhQoM0Z7|v<=
zLh1a#q<SF*2ef~72iva7uFPh*4oryVAD4aO!t)F}<F>lbfYeu^Yfd~E3V=qgab~xC
z41cvBsZjhPhOM6q2#{W6t=rPgQ}+wW at t&{!UaU at FkCC`B<S*TW9P;iy^dNF(tuNhH
zyqF4!o2VY5DL`I17Pzsjeng at jLR4tE&=?WD76{@bEmKCN9a{>mPx;p;D<2>It*xyH
zPE%mnZ|NdPi!~HvseJ3MPFDUhEW9sH@%VxgBabXzBF=_l_fV^Kz!h-D(dhpP3l*P7
z0Zs4&L3(H=@hfAjf3li208Y`Z%o7Kbst|8VAW9eMTkK=BQMvr|?bkCq3Q`%FO%+ at 5
zb%w9+iGpK8;DK%iL#`_aoP^EGq)ORQWvCi4DVAdG=XY|VS3Uh%;E9oJ%O)pMkkDA*
zohkJQDdSko<hz0Om7y4w_%@<P^1YSq>mG1-&*<idj58XPiCVoZ^M7uFi at WL3D-uMn
zp*U})wd8i714R4z88puSY-g)1iAG^5D_ToAQkUG!G-_8F;ol8y>i8_{_5M2|JF+L=
z)}WxIqo;h*$UVv|Kw9g%KP4?z^WWBr4@&S6shpftRaR2EU_=M1lQ#EOd{X9z|9`Ag
zu1%LYczI{}6lKYX1g?;+kEC!2TqagU2w967gKT5X((w{7`e2r{iu(p{IB;5>t_Eih
ztm{kk%I8vSC)e1m3>U=WoSQDa+R)Yoyd`SCU^%KAj2VqzP$QWJt7#uHA#4v418WlK
z+o^)>AW+L_+f%CiHRvQgA=AoE4j0KNfffJ0O>TAlI5{(hpnweznKciYu$!2uKZ9p7
zp+(Aw{0s5Ad7Sc(jII($n#2CnwjyJHr#=Kzi0EmPG;%vRPua-3Gbj+$7&%Kc9n0-s
zxLoiGo;e5MGWi1q+vgo%Zn at 4z^m(7kn2+#Dr01h*X55UDVQKdM$jC@*P_QNjpl%Q@
z|Cr{)F}UMgqQOi?N~#+<5|Q0I{?Su{TTrmX_x@^B-PQ%AREL#0d)#KN-8X{U?Z5X;
zM)v5qc|>8bYF~NAwa at 2z!8T*%Bs!k%!Lx__McE4Z8pRsBX;ow|-VHd7b#@NS at DaNe
z7xcWe4_5Hc#z%F}#0Wqq(%qo9`#I|e;R49Li*C<Y4DSoHIZ4g_P|J6BcLPMX|DG?C
z9TH?J2FU)tZORM2V|gf$td6JDY>^XyN~5gNweTvPKKNwlNY_e_-Q0kIkFB+^B`J^r
zC4 at Jh3cZ!6Ns{EZ-w6t8m#wRoQuZ%I`S}+V4;EBi{&m)m(5B?!9r19a<vD+?UDN=I
zKR1VkMYDLxuP7bb>a>f+k=%?KDesda=atXx8JLxpppd-mV0=7L#r{_j4j!M++SFgu
zY(`7u=BO3Jfbv^gY46f8bGC_)C^LXq^nZ)E)~^;;X1UlC9`Yzr)BN8{oA8uFNm84B
z4CYvYu2A|viD$f3VXLY<J-l+<Re5T^5-35T(=X!0{)&weI%!|;vza5PribDa#nW(f
zRp!OM334z<<O{#Sa9sF19>PuG(;)B1`$VClks+6?kiTk+^Rfu#Mcyd#ql^!QhNDY7
zczx`p=Wsfx>FgZl!vnU;<076N*~3Cy;tM+qQAxxIjkW2NM-S;{WS at EErljH9KeK|}
z9x^hFWS+SdS`&t3p-x`wjpv()->ibZi9&l0>xeFoU!R)~rAu<~f8N+zO`MFy+ex?5
z`>w&DO^Vwc!=ywINMlx0VOnS0Qy=mt`u27$2%+ys0MN)<WSUn`CQK^osRGWX5D~L)
zMD}g=^T4D0;41C8<oQ=()4okGrv+;tMhDWX588SHj7ps<F+AA%e<lCCXa_vX7_BK&
zKkbBdcPk}g*rV5BTrt|bdz{4R)30`SN>Q8Rd5qqznRJN`_~=!9o5o=rN*|SRzW#tq
z=k<tDgk_;OF*2fr-5BrHKNhy-`9Qi>>QBt%^^{t%4G|Ad0GWJBiK=VjcRfKw{EYL%
zQo3S<AKn|+$Qq;Exp~?-p@#DmGnP|<>@U#65%Y&3Kidpt+bJ24MlEVn82O7$;9O(<
z6Dfo9e-0zY<NuvpIET~M`=t1_tJ<d>Sjs2A at +oYOSwQ($f72$2n=8eiAWDxoNxvOu
zNmBTDyRT^RfH(5)@i+2NKXa-sxy;izx*XBk-;Lwn&!N6>>y&4Kp+fd;|5_4mBGKnb
z`H>EDHuk>A?B{;Gu8UvQOUWR<Xo?E{`*F)DJ9#~?oT_QlFmq7ZyU1omapp+SN7SEM
zumkrNVMj9 at z_!8boP^w>aFMojfyc-dp8iCRy4C6sY|ZR5dAUqzrFF>UpmfS!Jg(l~
zkzhas;ac!L<z9EmD>h4fxD*NplVD89N8~Z&f at EOmH7q*^&1-2dIcK}}zDh9Jb(oR`
z$?Tht6E~fA!Hp2_yjB|j_R=~V8Hrtb830EbxM6%LXzwS#&;}sg^qQyw((`frK~WG8
z?+df~7in2u2pSthA`Dvjm&Z4u34RLNpr$<i-}o5x6+V7X0t~$>{PLgAL423P^LrI!
zqf5$2ZZ#*o%7c~+w>=~mPvLJMzC7ID)@cMVe9rLk at tISGefz{?eyke+#uk7|(|kDj
za&V8$kFq5j)^Pu!Dg#@=(&y4L7~ff!M!Q*u)!NJJ4%e5;^k?v%>CWQr`K{rI(GK|R
zzg0Kw+wjjwB!M}pSOB^t>`-phMyOGMvNZG1Hre*1dSB-fxT7m00dG8u1X=Js2k}~G
z7WxagAAe=1H8+Tb@&F>S<tFf-w}#Fyi=2XIv)V<GFmvrD_2R^2R^2=RAM*Z$goGq~
zx(64ByG6WNAnsWQ)TQHn@`Qx-mIVigIcpL5PMBGlwrYVR=;is%$KH}l8cq6h6B84y
zZ`u=N)FU#?_|q<hCujx+NoVUU#YVay<Mm(I#{B!RLbLt<bE_!-5;f|_>_=Z9Melax
zV*o?_2Pbb~v>EfHgg_r6+X~WrZnGF|H{hcuCW%8=*#e$s at z%zu3hBSB;oe5z&`e4Q
znq7fnts11b@!LZrkP|u-gdKRZmo$5WfB^DS5x&qZfZ=|$kn7b}0Yuz#-P(fB2J6*d
zih-!M^xGl(lf!Bm at cMtrVzu)%No9re0{bAkH*PBIju9Q1IcAPw3PWEyj3>0)Q?$kX
zSgl at fb}C=7-s|$9Ut@&h_1_Nvjt1MsynMx!tL=Sa(U_IgjqXH^(B9Ouh$zy6U{Xex
ziFD2%=*iENRxB4x8%<(g2=d)A^W;pSu#Zg28igNHⅅOnbhWduq*EF?|q_xg7h<I
zWPII)w-bgdc<^86q->8EH_$`}ZkhlgIB(t>T6R97YlePE&BY=p3#7E3!Nae5_VC at G
zo!N7-XIgUgq(P@^I3P8X9BB^Fgu$t{Y`6vx?kzyrA_L4B=rm8pni958$Pm*u<5`03
zDiA3D+6MTrXU>1zCddT&i4tOvD%NyQ{AjK;3iaWd at 0d5!zc>82%GWMCU9%Ul{hglZ
zT%dasPJvJTjp1=8Bhgz}?RflJs at N5Q8C_Ksv2%%#N-~h2;>?7}E^~fNJ9|t2`SeSd
z6JR|I2(AQoQ%&z~pfUNMKmD4$xoJ#hHz*0A^3&OO)q?`nqmpHO&_l=Nmj`L`qPXcB
zx#tIB6b1gy`D6Eb|7SlS56}HvZ*t~hWLK$EEzwWq{{USTckGQ-=^$SgCjXMCQdsW-
zR~a1{5!yBFTUgNfXaQ3ze&&&m{c&|E!O6Ja(GMZ*fXDUp%7VsX)$L<Bd3p0O-+cmH
zuh>z;PJyzAjEZU=ogrfaX(VPBVPZZTz~QCE&ly at BAQn;67=K5;iMgk2{C;+b(4xZ4
z+dGwcx96v(;}|scKqA1rN@)Wht6aTn<P~$Pg*$j}U`*UC{51v^)>Ys%aF*tcU3UH=
z9ig^TYF#4=)igAQO+HBEGi#j*blTx4Y at h_$xxdYLeXD=HX1cipCxaV4us_<DH}6UX
z$1kZ8Eg6t|Wt?930yEK+^}R2ij5oXOU$%VIpPu|3ir$djfo}(ydjNA5zvrC*2szm+
zga01AD<=@4E~fg!Pb)mXqs~P#Ugj-x&6iXr{dftf0GN(>C&GJUm>`{Gwn7H{q|3W-
z>IaiG4({zASVc0>+&1s)gBkVDz9Z+ukB)N{2BiSJVdLT9vD%3*ip7D^?3YF!E|`Ix
zB>Dv1McVsx)H!s|n=%)I{P&<^4;yXN{bacqjnYHxv)5EYo$X?cG%cQ(ahu`1 at AXRI
zSNkSuaJKIibZLVFoJvTB#sU$;Mu`S$Uw6c6x%y|}OU@*zj~9{LX_5c^vG+-ntYR{&
zfaQn>tNzD)E#EyE=9i@|yKCoga*!M;2L~q!HDOPZr595V0z7*&8OnV$aJ1U?^>Ds&
zUI3l}t*)-_HNu^fgHBF7UawXDa%k86- at of2zh7JF?5;&|eWWLe{MRbd()wii-uR3C
zo2V9K6 at sFY-Vdae<KbT~Ugzq641{d&-7l(o1RN-w;E}khcZIE~vl87`4B8`(-CN)^
zrb3%(_+y7RO}ZQ5D@@;7vawOHeVz$GIhNu)$`|JxhNr$-rJ8_g$;hGp%_G1n5#{5Z
z$TC-vX;ks?C9i=Wh0mjH5x04lnZU2t(+EXP*P!BU_-I&J34InrA3*JiNRU4V{BX!7
zxF0q$zI+C-FxuT2{<44Ydb~|1>1V3jfNUf890sdRCccfS6TIVA-A$_%y2^mk@{Q_0
z8p>O_#_y?Mq1~*IUizw0cdm6KC-%lkrR!?A at oQW<z{fK6>aAxxS`H_U6^dt$o)r!9
z6V>>5Qv%)94 at y{=X7AJdKa0c;ngNfJ>v*l>+b~cpSE&h1TUx?{e;=%}sVj^>0(!?%
zy5T;z<$bWFXM1UP(~e3Zw0Qq9-DBOJw at +n$pMh2T_v4-x1e6)gyz{u!;0bj<UV=6_
z3vS-1yDoE<Ce0q9vS^o-sMyaJME&B`wX^bAWX^P6Vj^SNoxMe&Y9KH9TW6KP-gYr1
zO;96-#`0_QAW>aqG83{|44mRUSb~bz3?8!f4GC3Ik#nO#S`v%)7!pd%&S$~QxrK#P
zpb9Mo3jBVvSG(a$7f)?V^=?r2lk%bjg<>9|66jo3jwV!E`Dm$N<!gh at tkvg<p^d;M
z<idPk(7erbbaS-l!=hfYmG$#QU4gs(%<i$bhJ$+&8;134oa|vLG)4nlP>_kel84qX
zpQtk4*Xt^nFJUa#pLxY1XmT5?_TF=)))Wc^iwfuR;(TbS>y$3oQob2_0>$AjnJxKb
zzg(pFvCUOg*C7xNTx4#WVGP!fcb8tLU1;_8E6uWY${-a|ABI8P`w_bQ at 2+e}M9xRL
zx8 at 8#HFy}%xw*O9K12q30p6H{i_S#dovh7SvV)$%e%g_``dpczC0~<mcH1~eX at rYb
z?Ee!ngKzfUTdHSapr+AIIP{HojR(Al4NF5rsGO6_#K_ZIS!a2lIkto7R6fv{hbMjr
z{<2m{O01y={XjNKhd!4{-3;A19}HNc;POk!e!FjKh=h9RXP at y{0LOTa9I`wj;kd28
zd6CqV0rM)4RoH{~BX?Hwqzo4W{$lZJQylN2WX6H%!L;`vXf6X{P~*!Ro2vUhUxmu|
zSSRYtzX-I}WP#RG8ybV4-<n}emZyno=XLydkWR*)I=3l3gz=yg057#F4Idp|(b=Y$
z*Vg{BFhL}`pDb2Bs%wt&d{xMY1xl!xLc8?@+BGEe#f$%HwoI!QPHQq>4xo{Y8oP1T
z8clqL*CXCJ%%88i)v9<*dFmw{7EK?QaJXlzUJm+C^bV(6H(<%_ob__jAl&m^{bauR
zcK^6rUn=E!tS2t2fAO0~<Qgd{s;+s(Z>y4#W)bojk4koZXo`5UdmKJ);cYSviN3$Y
z-v65ISJ^ksHVY;z`Mg^C(Qi-qE~3(5meZ!6r`q^ewD;uw#cfQ7s%hrfN7~%5>o(JV
ztn#nF+0VqD%%2)RY;Oz$nG3Ly528UQ6HJ8}T$M at p=SuMgs!%i}q_bR+9cNt@?TUxb
zytQ-3?z}=mWq>;t0K+`Q9$q_MeG<oGamSiDDw8tW=@=Iu)+)^hYUhKi(kBhX)1gC2
zi&=d#p<enbU-1e4TCs!A=Dg<W75C#4w_zSw-?#8-PnTib56oOS*5+SasDCHWcAi|Z
z+R>2r2=SFhcp_vkwhX!j-Oc5>>q{)0x9-}ozvZR~SLZ0FJpatPCiZr{OBkPxSNghA
zF=NX%X(M_HzZ?A~thsMr2pKJQmHAb9A8U9U?NDmCRvxyb+U$d%Z}Ta>I4|1guxMm)
z`Gd|d0&QR$8zE<uYg}saxpiJ~>Zj2AZNCCl2zEzVtRvCB#B{v%ejG<lM;$2mL3%Nf
zFH)jKI#UxoAj(i=Ci|0;?#XcM(+$FTycy3y3|O3HMU2<&BSAT4)uo4&SA2~CeL~oc
zwL}cp$jiR>*%oJ?xgMXA9`mT|i*uTx$b*B*>pgM={D3wNuay#+p at HTG-sU*>9UXPH
zav?1ALS$2OYUoH&0`ab2Zi{YQzlwX4mXX;~b%a`h(7U2%?a-{x0LjD(B2i=srsIzg
zI2B1%s`<Lp6RGxB#5)ti88u1?^T~dSv^X3N-=dARnLx)K_kPo$koo8TxBxniltbv~
zaQz37m887tg6mdc7t4Y}VTU(*cz~>OK!)tKvMbRWM|)GxmqJ`$W;6wb?;Yu{l at Gl|
z+rQ4QcvPNv8vP<0jV3E^SjwzWa}jHg1!SbLllUqiEn;D}%q*X|FhFDItG6Dr-F<Z)
zMDFaC#72<cHGR?l?I}6yH>?D(b*Pw9FfUo+*43u}r7Du5$~>znlAzU+parSe(X*-J
z)fr&PR%V$#W)@AHlw&HafGISU>D593Gl)ecy|lVSErs%vGJS)#%(*G?VnG_r7=ol@
z9$rm{;>iQ%6nUlumEzcO<^+Y(mCVoH@`Y;5ky&}a{cpIv-12j&{BN4>B<SZ$QyZ4J
zo1aTMCaL_r3PpSlu`h;9(du^kp3A`oclURX=UJs6TW#~3%db8X2njL*1ze95xcbl1
z at yi5-{5-AFSw5=Ma~~Dh+f=f3UwC*V_N?Sf+5X69TSOdT&X0<=>3yK{U|BGGe0<D$
z?cS8<#RsKBGMIhGwBu|=IK^bHMo}+Vi>6htrwN_a%mot16GUO6TB-2g;v<W<WFxLK
zmW7GK1;A1;B^;E at 9Ta`?EEGBG`naC~(J#Pmf3gCMrAkzkEw%GuCiMA_#gXAObeOwb
zxdy^H5(PyPGV$~mpQ${uE7JVR{T{Zk_ndx2lhudQU!Q0j-{uG&H#j48GiTjM`92J>
zxb}(pHgv};lmf2IuD|ictN>Xpysi1+0#bZ+yf)9h)}h!mW81qksRM-x0>$|4;q*BQ
zupaQ+Gr8{|%KiHs0!~a~Q*w^czHpfeRQ!M%W(OSUUUv0vD_T<g7`bexq`xobo<~Y}
zLvGQpQe#OqYNr3dIsscJJok^Oj<;ZWZEm_z0<LF6hL0Ld+$04(Y~Y`)?CTweho6!{
zf=^H<2pmpb-sgt~pZG=dz_uUb3XZPf>`9t`mM^&&ubM-pO~-m2Uu1H#Mz3gfonsKU
zu&aD|z2HglWbi~e{QbV;-t!dVGFJc~&+#3Ahm88>770>IB<cmbt*YMN!B=mMR=+-h
z)dtJdz$H*CXN|`MtO at QmQMTX{tO!JytE}2Tpjn^2>aS$xD at uL?H*_y#r%!ys@?TJe
z%BrQ8^SEsAYn-2>nxrY|sqdse-BdoQ!aE)$@2LEp^4onM4VIcsCGZmx(zCL(>eaOJ
z)#heq65Wr}CVq~#T*S<;mhp95a|=G3Q_ZaTZh)*CmYyyABf6EFEpnx_560>VYOOSf
zrqlKO>!0q=$7gCbj0yWyCf_|@$y$%tr8?J_p;g{V3hyl75{76Wq9E?$>3<mjp{ecf
zghqbZJ at 8(p|C9nIHnvUg{>KRhhoy2`y#q7uyM1rU%8jknoX>vSZhD!+R(qOjs_(TY
ze?NDu&8n*y0_I4 at m=sP8t8R;zB at M)KpK59Jyr%>+tFA1gh^7Iyn?_+-_Nq_i5V%#|
zf!{Pqq4#~c(BZAu{!()LSy*LJSt8|I<fzv&{D7xy-M6`C(o~(Lf0HNf6NzJ8Gyuc1
z=_Qql at kR&pBiN!KcYmnv<aWsWq7Gln(!)cibj+jp>1nQQs370{Q~tZ>Z2bC%M7{$k
z!oPZsl|s$$fv4?QT~yU2x|y>HQt0=u334zP^KO1(A~xFd;Lvq;MO~p#y at YT0u7$W_
zj;_+Xa`mx<!DetGR%Xr+_SyH at IKM{MT+sVseLHlH(j`*iw$AzXWmLI{R$+FXLQ^7^
z{Gmc2EYMaLBC4T!w!m=Uq*yy-26#yd7SuCj!Dy1<-cFpnviHZC6pLjw=vz`u^7&^8
zu1m!X)|Y$h{vJm<k)-FQfXUVufG^&ppT&27asI^5nN$6K|06IpGvr(4yf+0V(pF&L
zOQ3z$?uq42k at rxCmLzOu-$8;+q+L2o*$I9nEw5Laaof at 2xE0<Yo>O|C at zy2YA^_gu
zAZ9sE#(<}F^+A{s$bEnwebh^m#9Es_(S#unw at R-klrd{-ND?SJXue_l%JF~O^oHvb
zw1}@pXc=--yKM~n+oO~Q1_owHai_6oyxmN{^xk@?d?}ECAu2f*?D*(WeyWsD91B9u
zV&crX^4<(+F4oIJIdfr%Eu<C$u$9T~n|8~CAz#xlmkzY?ce=c>gUq8=Or9fBLxa)t
zE%3+(%C at XbA)UPRC%LCASHTtVi=kU)2%<Gc9(=C1sTbjr4cHM;adIlxS}UN<%5FKP
zG0$H#vG~Kl9lPCkM at f7|i`GmD)`|w&`pwqALB7x2y(QE3%n1jUi1r$hhr!Cjq>gKJ
zU-(_ij5TC8dNi9RN!EoYbQe}}KV*LQK-^LE(SQGqf$s_uvqPgyrDxaI%W2cqJcm`E
zkoK$jkMq}SSGH}t!(S6sAUwCh9TRj8PZ=scaM8o7za6>Y<L8p6yQ}Coq*ev9Gbc8y
z`EOSrP%`hLKOQFk^@EA>yVUv}G7%rBUpFKvLXt*_W|q!)AB)bNA8nr#Klwb6TF>eY
zl?zHDZbhH-e%ap^x1WX(?}tO$m9>|v71Lxr4j1)RfNR29Q)Aw?%Hh+2HDmeQ&%=5<
ztOcRDX51K=`3+HTNZ&p0R4XN0fCQ7eHiqumgSjss(DGt)tKZ6At9a`VSIB&PDs>$$
zpWnY$F|1tknc}`|LK6f|i_)jcr2-qbHC)70w1xI>- at E*~C6Hl}Xp2{H$>>kYhksu$
z!>^Zfi2X0fRvxAgFTOG?m#_Kle7)E at W&^Gac7ti`b{D9M*J08Us9xRwaWi`LHY>(b
zU01JtSHJBP-TQL#`msXf;&=A^?AlF*eUo>vb<~`3TZ)F>P_oL at u%TChMf(#`+e3%1
z#<$i3vd7bJ4$}>T2eztUcJ?`XzJnze_G#kwQxpTg+nwgk?Dpai$UN2by*a1F1>}<)
zx>ubEDhMU9DyojJBw+FPQ1wshF{7wiBY!l_T#PTbqL7zLnbk*?;;Dh}O7EULv7CO9
zNm<8<w<j<MOKZ&(a{y;XI|T|!Nnl5srL-|S at x1d#P11;{33v%sdstia<jir+ll_8N
zlMFb%mODgda7~oC_T09qGR|*tPF%}pPJ7w(?Cle+S`;czJYR(`{7tdV5YfUAj^Xqa
z99A{I)!7*UfPo0oJKcNlq6YYR6<}Ic?C0LHLRlUu!lP2hM!C+OGT*dj3Wx#I%_NS$
zhh}0hyjRr;KzT82^S5-+dsO~a1oe^Y?X$12%F*6p&*NuO at YrPU+Qz~*yz^Sg7$tn@
z;#6J at lrG8pyvkh4cj}96H=XTs#Qb<@hs~UMP!juVD+mIAemKgDFR2IYtbwuhTrf4K
z22IUkUJW*F*ZI3BulsBt!|{$ArM7dn6zj#Q+ at _vgIL-~7`4m$zZ$7B<x%~?M^}uzB
zOu$^}a&Go+v1I;m)!!o}daq%I|NQgCVoOIs;d4j!l&s<1n(Oh-n%ZF=_8|+xFN at 2-
z>iFA3wSDW=hn3YhuFT`RKWm1ix$x(x_S3cOQhRN^`?Jsg5AQ$_zw6%bo~zINpYQ7>
zA3a~0R9m^R^Ywv0d%4!6q-J48`=$nT=2>UyU%q^${_3)wYIbTWw$|&jH}BA!&RYG5
z2<Z8NWqQVWXDD~sC-g^GJV)>T)uZ*$H$JN?AF3;}s;ZgCFnC||2kHkV(Zuc12JHTQ
z3?Sz6Mo#g6wPfW`<&V6!>2n|dhQ?m{S^fQ6pRI03I`(fqt-G&#x-R?7^}6Jb&Q&JW
z)xeP#=-uzSSjBc*M_%*}z3W9^(5J5cx?Xw4>H5T<ep^p_-%s?R*Pf%9nWm2U^G|F2
zb6%qBe)^D(d+LZ%D(J~Cf3x2F>=Tu$RCVs9uh)@Z`Uh>@U(<=l9ItnL{_8sO??0z&
z{^@`J|LnbaoE>GEJ$~M*yWiVeI!R|E`$|Ft0YO1zQxqLQ1yMlMpW`sj$b5BlMn%wZ
z#03=>6b2aq9Z(S&ktj2Yz^EV!%94aF3t2lM>GXQ{rIz0xw@>BV>Q2%L2_$gKPd<ip
z-&<Ah`_^0MJkNQ~gC9P-5tY~!ob`#T@$C<vQqQFL08Bme>IWcS?=6luf9ZDoc)?Bh
z at BjHNuKMIRvAM_KsB<pFl~;ZNuby0&#d^6OJoe!4u_5BrYi1HNG5yHbV^&uZW2)>o
z%{}9#+(Q-29mwZ}=U_BjEmyf;glo+d<TEos;KR>rZGqYbhkL2$_Y$PC at S4PdSr#4|
z at zq)pb(GSM?BODJwZvuJfp)6bEDq;^08=Gant at P~p#V2*9jsmLRcfaIQDsUbI$BSp
z^(9&yueCR<0U<ypX4KjXwYw&<)tU{CIp<Zata%^WXp#V1>ogdx=e1H6r{t4FizGs=
ziJ1vx7DF9pNrtpAUL}rNVxeR~C3ZR%Bm>N<sol7)XEosp_u1q5I7Ylj$}=g)(;6b3
zKmJ^ap_&eG9!VOs0WHT$Yn_M%bPaP}wZUq*PgA(xlV-bg9g+-kP8D}(UC#(I6V at E=
zPDdLqyxiRpjYjeNKR<;}eff3_X7h+d415o}aRW23EQ9{RJYIdoTwM6}*W=hDXQMrn
zfHA;ezKTEmbq&6C)4izWda>-DN3mwzc3geMdoXSC*qht!>HaLs2U0Wf(d%x(S#2d$
zT_3rj?YQOh-$M22|H0A;w*=Sg75ahdL~O5A(cL$QX{R3n8$hL6MKL-9Crq>Os1KM*
zKc4F^W5z{C2C2EcKMlvvkKnOQtC9Ckh3|Waw9dt31Ng3kVyS}u4Ugc;_g{=>7F>uA
zp8XEApbyTPhw#im88FyopNQa}O&ve at z7Go#EV=OCaO<jPalyNf$M;*~a66B}xyNR3
z*Y=5M4aVlBkDxX)GP at tAU4iWVse#wRbVjiVIJm*4)9HFm$9~!~4%YGB?X{PBuzH}1
z8E at dTT}A=Zar|5xw{<^<qW4<B_YiNLi%ABkxejXO8ro+~MeoXfRQlIoWe(VQ)fwpg
zmVxgBzUN?YsEm&c^~3X9;F~DgGwm<{JkJFXK>}rzhhHG$X1xv{`P{Mi|2|PbZ|^qT
zcjIOFf1kVr$G&+5&W=W4%y989cE0F5$AJf{o}%|1_|d6&>xVAKn=bk&2D1fhd~z8+
ze$GGO%Tt!(hJU*NmSvEhc^v-jhFfrCyfn;R4D3h*zUPm1KpWQZ?)u^EsW`p4XY9Xh
z)&AZylw at cPjP}OR&g%q0TD!|AF6AqX+!GjTVLNdQ$x^sS2 at CHDg0<I7K<9 at +EWw!K
zqe7t&04#z=-G_OfN{+M_h-NdiiJ at B9@_Q5vsw7Gy)k at qnGETxnu&1?T1n30SDsxk5
zkM=>~JQfOtfYd07Q`b4IA=2y)zn}L`aH`j at SrY}kYIYDNF=_;{6T4YKHbhB_5 at t&H
z!me9kgC(ttVY9}tWw)9rFv}G_kIJx>U}zRAY-XT!>6+<LV#5qhu~=;QekHs-Ka1~m
zU!}vC+HtG#fm$<jd?>@?`L!nv=YYRYLd12!Iz5gtf2O2RpCztMJ}V at bp63P4Qb*0q
z?5&1&ESujS|MCnz{>9r-E)`)}W{)pCV|<j#4zBpv`MBhQQv%5oC$F<3gE at yCk7(Ou
zeB<W(P}}w_o?f#VpZv<t at a@lCfcDmOT}HKEBnJkOC=iLp;9DM2sU%urF|?fWaol(9
zMMxS0kHxNuc66Ew(y25G+xy|eMYUQ(tvrO at ybsG5L{hD2PsY)=b~9YeLAg|hTOGiT
zUI&ReU5Fbm(0mvG-Y}`yvEh%nukr>g`|j7UxXnS|mM8FF8}QUF#xjr*cpg08z;|6Z
zjtf8H1MuPatvKt8_n~;jc0Bdm0LD*paqTI`AoKe3Fav<&A3QJEretLIQPvlW9H@^z
zH$85&v=JRkX6EHNe?II)D>@P}tX{hbJ`O{vJp63;yGXQ6KomY452y`p#I_R9QY)ie
zE}_udi)5w+E#oF*yfIkv at 5}J5bGlHe4tE-l#L&?-3AIvRKpaM7(_Ih6Vga6CcZam&
zNwkiej8o4%6Z3EUB_8Om;l1-((c0<Z=}kLOt<Hqwcqo-C$Zp((nmrNI+JS1Rj6&5x
zEE<KeVn}5ybS-=<{`P{2_|(RA$X18#@xh|dorW$3ql06|ap1Tfhzs2sQ2&p*-r8|p
z#I%o%<J4<#Bq|(s=Goi5q`7A_N>dLckr^!jqFD=VWU1K-0wM*1VX2N<JFBx3Bg$$)
zt3ZkW#`+bK7HvF8`BOTb4!|EXLfYt2`|&AW3OAOdjV?hpfj{qyq(bfPmEdVD0qvZX
zv}tgOpCvF3JF4+sIhHK2CPCpoo=&F&xfjQXMcvxHoz}wIM48zWS`lkTjOGA*hj0wp
zbd;onAe;bJNgE||YNkNK$9JJ-O$dB-&GXu|p{QmCSc}4r_1uFhl}b=!q!|p7K3*pa
z`_;->l at m&|ltgiT^E=h)i*u!R%gm~=w~sbzEf$LnmgRI#<2uq_K&)M1=1|ucuQl9%
zDH at F;m&=Ws0oA=)?~?%pj-yIW!`9zQTu7Yw-TYoY=cQ7qL6u@@1dM~VKWb)t-$(cJ
z{rJ+gzeKT67_NWW{f6l{E+UaAzW?<P<HHx8QnzAu>$b={2eu9#Cbvb9>YR$UdB-D?
zNaB&lSK+JI-!1Zq7nUZkFEj&9aYPesIO+7$(DL|QxZ|-csF`}<Yi+0-8+&}DGLvxT
zn_i7=KfNAzKD8aLTgLW3{R}@{>mg<v#3J)>{#i?~<@^7J at 7?zlwrt&mwZHxrzVqxj
zyy3hzq7@!2A(I9M(O4AebPJ;8ZCKmggK{N at br1gr4?NNbchqj&K)GDR*3BESdGlrr
zmK>C`z1Xz=Ic)DQ!b4s2{`>p?4}X33dAQX+JaFA7 at r@m?!WX{qCIBw{gZL%f{NwKt
zm>ekS2n!wga at I8XO9L4FQU8Y*c?J8v4=X(n7oM{S8@~5BeE)Y(W9!yUSp7fW!1Ze;
z;iR)qMg}f?SSarJ1Frked$6v13${LWH*Wn|H%@-tiI{lUNx0;^X?Wz8Td{IS6?Vji
zam(o4-iu1P?ow!lh>T at e-{&LS`!xRRyEoyUhaSf>tJh-v+Ld_l-uv;~&@7xbw*@Ve
z=HP_W=Ht%q+<;&HaXHpLw-%e9z8BxV=00>B^Fh32Dp0NV;I8YxkK2Cz0G2<!8ta~0
zjpv^DHGX+t9~R77i1vg9&-dY!bJ(!vS*%*M3TxJ^!G;Z+Fjy#$81-7MhJn8A*tC8f
zwha~mRPg-zb?AP+4^`JishG#=zx)P2zyC>8y?Qol!- at y--#`BYhTOUgsDHx~xa((k
z;+d>F=K8>JCawABrP((WKx=fKnSqv;mIjclG9z`+A{ZjMRjCRcn>2#1*&l*MO3Vn-
z2pn5lS^_DYW`lTMtx+JTQVE<Ags`I;?P&@6m`P$0wPrL3f(aOT-CAfJb_v^wo1B0Q
zB$LSzl01!elZbF`QmIrBHCI5Y8G+FP3EcB3Gh!A<$tlOBrKP1I6UB at M3(s|4ND3(%
z;~bD&h3hqG6v6xDcWZ42*N$GF5>TB}7QnMciy59`u^5msW-PQMgLOePFwovUN_Ysy
zd406NR)V92{NZ{Ujys96y3MhepL40ioa4^tO|zQJ>QH*dIahg~1}?R~lGYcc)9GMb
zSf at lHrEYNySZDwuOr-c7Bx5R54HLu>nHd%X?T<bc^@*`?<u$*+nho1gcLO!M1R3?y
z)f=gO^)naZl;an|b6vn#L6&7OS3<4kAel;GTYnip{oOjawF;uK1X^ai3RwRrmfia}
z+FO(O>_^XSa5>o9YmX=5Xt9exF^if6Lv1U9d1w3`e)x?cT=u1Z#E*+rSdkdgZR2p%
z1=r)$<EG%)5B at u@eeM!`;+!{O;^YbFJZv709tYf?^I*ZoDWCigTr+eju6)m#_-ZnW
zN;QeMUws>{c<VSs;34H at Q5q}__j>UWjYKf}sB`cSr~C?+zxQppc0xPaCyhs9TpU9c
zZ<I|2NJa;6>*bf?2Y*?E!Oi{1;k!8Z(f>l`#2fJBPtQRHn{n%x{~7l_(+k)hl82p$
zZ`}Sfd|-wT$2qvWvhUBAaJV1Ep(+!3F|J*;>zak(#<#bT^L?i;^{BoD3&z-W%0FTr
zefYiyA3i+ag8^WS73 at L2&zG6C->wRN0&l$H`?$JrDL(tIGm%KzDA!u>?(h5rpLk<C
zYPlgqY#*`qSHXScYk1Ff>(IYr5cA*t4SeFl*B}KS=YHc3Z28P(_{8~dgBP)3MbntL
z_$|2V%ZFp>)C?k(L1c?H_`@%zmQ)PIp&UHRMkW=-hTq?eZ~f=hsCX7Ew~ShH8ZP|C
zf8wIqDFAU?^e at +<_tPK8$1Z*cU`K&k72}WlC~o`q$1w>WoJ<R>Eq}n(H~$9)3l$jS
zq2~CQe)1Lg*2m7p<dy`sn;gm;ev6O1{S2f`eb4r4Nxb8W-@{cGzaCMjM9jjDXYRoJ
zF8DfnD?NY*Tyf4xxN`E_@!Pw<j5$ez$L{zvF1hDz*z&|ubi^!d`@_w6?`0eC(BGVj
zW0EmgYwyAZ at 4p%!d*VENW1NBO_%G at 6aj5PY;T~o$)}BF-%Pd3yJfyyZk#K!yhe;5N
z^%Xo3I4KBIIgu9I6U-3=X|XiPhSnl58=*BET0C7W76US-%>`Am#lm)NXbGUf;Y_7c
zjP&!G_!-SkFw4avZzT at ePsa~QIhp0*e`}|B1&CpXI1(aev^1-sL2xAw+Dk`kMfl#J
z{VwgSwb5v)R6;713hsf|qBSZ?d{l18wZiNJ0Ws&9WJ>E(_`RGflDW~cdd$r5oZ1^m
z$u+Sw-OIG+jApPn-+Yg%34u!Rl)S0im)7oZJ!}1r)>+Z at O#=m7L%Qx#sniHLp7!G*
zIp+Lv&bju(wJ|Cm3^&PT=8r#T51?>{N9)LV{c5HWG%>yP)?59v&ptcwCO5|5`RAWU
zTU%Su=OcXBwvFY>mt*PDr6UR~>kn}RcijC5K6TX{h)2h=>HDZT9^Q2FQMmdu7a|g=
z7n&MlVS8U5mtA!m9$m2(j^iTJ+6upYChV5+uzYv83$=~n_I0TCu7e#-;Xl88F^*n3
z8}2BD at s&yiJv}{`K7IObuFJryWRWccnf7)>ea%)F7&s^uiYQkdz*w*%Q6!Qn#3RF-
zh*L&BUxEV*(L at R{r+|vxindIoZuwj*AzvuN at c=6tN4h10s2MKKEDa%Bi=(|g4R~%a
zK2EiSLZJfB7{ua9SY8!wG=tWJJxY<QhhjE|itE7`3x*NvNDIcb#o#+N6bl7ZYA#?|
zh{n^%q~d|A+)MewrOo2Xl`FAi$&w(I8rDXS7A4x3$e}i2I#dou!g9GB1_lODEEch4
z%NCq}{`tEdr+qnW+s5OMKaL}gI3n1XHNr at +(A(RKWHO1iwzge<59f4mi?aP;0%Dm6
zEMvho7IL+I3>3E_SKEPnwGX}z*d~H>tOJ?Y1au at Pp(QpBo(Fhv;rkw3-$Beu2BgUM
zJ$SymM`Gi;E;eo2ggJBO?BUuCe5d|wyB=Ug6Uek?V0#V*OGP~V&x>)<!xv!X at -HLV
z*9Xr;k;=3n5#5=t_nmV6^F9D$Ar?;}nTWx_Lp48yS|o!^DhA*4;JY;x@?|93S`mSd
zTBU??wF;;HVc5|)(&-dzvlH03)e?%OO8xsS8;Mj4QgI8uH=Oo&DyWpJs5<pM&sY&8
zQfVY(Hay>lTN*^R<TqF|`#um)w;&xK>1gNHO2}nPfX%3)2j3*n)|Q4150z3DB{z=t
z)+FG2sFjPzmwdE!w7`N7uUbU5P(iZ26LI5>S|h_fWA*CQm_B_vCQO)c!1fFlFCS`q
z27z5Ro5kSZAPR-T0o^m6c;X2xUc7jO%0u at Ij-?iV6F^bYs(?)asP=kMiHb^jw2Qcc
zUTwaoU|ai}XyJ9ZZwPy!sYH#982SBlhoVH6pphhn;E<UFk`}dpCfFp&AfaGXUL*1f
zAXTcPgh;!=lc;G^MiMY}D`RJOf^mXX0$R;vDd^N^EFO;s(lwQLDZ$jni at IjRq=h7k
zH6RL_nV}08)~ijmk~wXlsw9?kPiYo214>Mk#BeUP5hrWBw0=bisP-<?tP!PE+E`TA
z2iLqh!6|toSyCdRMjIp&YM|l!en8GigsRmlQmIr!(^3W|v~XX?o^zzxFKv9v at zPp3
z?Kz`;i8yck95Y=?y15RFF<7>2Sv at nu#m$FKwWniA<A*Z?xqJy<|K6_<j~V!504|oP
z7yX}g`m2!`ejyrTuwqp=F1YkN7#hr?wIu}ugTcN&SpB_7PhWy~$5fbMP!jK$gmUjD
z_)Zny`_cWlcG2_^k+iXBhY6odEQ9vAf$ur+MnEeI at l*zhv>EZjsLyB|E$s>UNjqWy
zTsEV$<H)qh&;5F%PyjHAR<tJ#e7Dh2&W<M0){&Bbi8ttq!=NhJ(u$NBU0?6RLL%LQ
zq(&J%_a%=shTS{HGH10~4TWM6(MSZTWCF(8HNdDxf@(-6<FM`e3n$y(11mEDlRH}v
zxvb1+H8cBLMxvXbT0*MqOr2-;v}f!sX!3{qJk`81hAKT+J at 5xS)q5{C=T at Lp%OaMH
zz$RcaK0Mb)wd5fY$zWV^8fLT|g}H67#mx3&@z}OI@#n3#VeYu&Fg1MyX0;uQ*7yX(
z>=dF_0-is5&EVMOIez`w*Js;v;0{NL6Sfc610t4<_V$h-``Qq6vE#_J#zPr^dIlt#
zZbQtNde#~MtO(Mr85sERd>?i!flNF(BCz2}ZJiZOpe2?ZxhHU*?HH1oIFh3fIsmZZ
zt>{RYT|U1f_V!2uZQ~OArkX1N03ZNKL_t)ejB8y!98I(!3e?G&@57EI(H=K|U;jBG
z3AD8*0k{qKv8Qb9p7sp()<~t2u=coT)C<xHQnUR%Fv$)~n$UqmrE8Mz6))DF!Kf at r
z1*6{tj08jB=7|I;nM|gk#|xz|YU8T?J`_+hJD|~K0#{nZs?0 at e05rl*0I9}E>2!L8
zD;w{R*QI?}NPI{@Sl__^4$l!YC>mi8JD8DJ=yzzAN2Ntd`oi@{N=~%bi58fvvzfZ2
zX)Owgh-QU|DQRuYIpKQXxN4smEtc1@;W<<;rKCw~r1(e4fD$3zKV at s`uBHuMIX-HJ
zpzDU?9F0bU+9S224x3h}6Cb~awKxn=s$(42F6V}lJl-!QiCiZnbKy1#9493lYNt%O
zr3M-JtZLSavOn^Ka=9EdHPyNpZQQAuEG3rOH%Wt1>LjSLL+xk88mAE!=z7Ddlib%M
z8j0YWH~ufOg&GXJF#;B#qb-BQ^QYC%@B1i~YPjmUWhj@*Xlu>X7Z-e3whj0`3R~A8
zn(ly!)LqW(SOQie1;3QVid9?ir$^V|b;r!#txRBVqzZfc^8 at kOy?xodkZU+tWfI|Q
z&gJvyUiBDOJhcYXPJRzgpVx+(+gK#YjV_xV!j@;B!1m}=oOIMYM57i49{UY`Qa&1A
zyx at 3v!%-E!i1`49Ndq?)wI0-H(B2$c{JE?94ikXzSiBhXs2X<ac-2~zk-+^p;jpYI
z3blSb(|aFQ^#2c5_dbLgN{B}i at O^`rm4c~QBZ3W4%ZG~^`YP+u+q)JIb>E8C#6-mG
zBy!GnJl=OF{@U|1crGwK^J*-fa2lq!z6vwjj)7f=*85EY$gxYt<CuB!d+~uOuR#LC
z<{ta-Z0 at Oedw-Z{9Eg2mZ at zPP4rTje&nOfM*t}*1o?Q79CZ6~%ylFuv9B<^FVcRxx
zxg55vS%GbC2TnL<F(MHQxo025kG4$374JVCw(mB8op60fc+b$j3yhw=7<<NOfyftQ
z&sN)6?yam%psrrslNf1ck-uhh)GbSkhB<z$%OGK5FB$GtJU595vnt`JweJ543<>PC
znWs9YF;hd(rN5(*bOJ`!-DsqIv>qDjl%+P!dd&ox{2YO$X3$fq)TmM{%HSNw39PGG
z??RBy?>55?eo5B!{i=4vnz7KRJTp(sF0lqfBl&83t!th2E0m5gvqEyqvE}_S2%(nP
z8r>%#=6tBbnr65(3#L}sI^PU-sF8u%94o<8xfFvcB*dDHVnb6(EOjk}=U?|2ts&FB
zh4-(Y;rQuz>pA$HymqZw<2|O+>EIb77En_LB_b-VWTuMqpxGj3cqpsn-*x=ejjw^s
zFw&|I{yyLj3=9?U;3I2b85d*y8pm-laeO<*k81^tfdydG^Zi)y%m&1wBV|-R0KZm2
zE!T%c=V5gXyk*0VrBKTcU?^L_!%sYi<BpnJciMTGb{&5u9HSNUYU)3qAHwG458$?+
z-igYSlktZCI2R~ZP%ITOFqi|3K`IeLI+aAZkVE%V58?K{`8e)~*@*cLI$v`(J~OTp
zp6g;@U=W2;8PSN1L_CVtOd77|V at K}*tXLFL--8Q-)=UbCSQOb at 5xGJUv1kPGSQPE8
zX&4xc)uGn1ENtGq8TouZcv*z+J(J0xtE+27x944r%Yi!7kw{<m3ZC|t?8d+#V#o04
z_Pg-VwjW??{uwxqTQ|h;Q}Aj#>+k$s1x!2x&ocll#H<J^P5~9C0N=A=T!VNlfkop_
z!=&^A6sv<+x#Kr at KEDblPJ17G_<>{Bemfi&Gv56beA at s{t%hdzlb3GK$mOzl{@I7|
zvs-UL-=pL3hVNepyHrK7RKmbu7BB|ML=2f!5|u&@+txmY+g7FVsv{PlE#jbc at oD(v
ziQ{1VE(V8&kk6M8jao>=V`xdI;QIzU`ubs_QAB+gE-bX9lSsy6$mUDP<_p7nMg(oG
znZ4dKy1ToP&*uYqQTX1|=`<!yn$)moyx74Hl`N?(tr9J5hNv!6;i#_a^eJ1>qI!NW
zU9kWJu1N%R1Zl-$F=)!Ejr){*sx`AliPc(}KV#uHuT$@X-=|GIwSIub=33{%bE)OA
z7D<y75&#o~7mLLPaHyFI0)K7psEtH9AN*{1&a at s<?~V6LD`u_h(RHc)a|qg*P0*|m
zYi3B=)a*dzMg-&9t3=Ha2<&-3;pWb~C(6v#_(2QPIVZd}mH+XaDy>uLDQikdG}V5Z
z;}>oOsdK}h$K&yUV5&5Y<4z*NERz~gXdMynQzc^BcZ$yrKd%<t+M|fiq&o32)2R}4
z-DkqCcbcgQTX9p`M^g*VRTy_ at kR%{${7WnrYgkD87QF?YS-S;&L#5$GHMULD^L(U}
zF(hI(T+f4TS;*zfs8*f2V~-gbCH8&5bE+_w1>be+5Qv)CXbg|8+=ybiigYs8Br}J|
zvAam)X#Z9!l~5RX9?!1bic>Fo4<7#EE%;UUJMp$Q2R%J~DD|zx&u_R9_dVSMt79R~
z``1g+`@8?cn&<zBi~jT at Oga7%ymRtn`0v^qaMgQ`Lf?+fSpC2qxasx>(C4+_#Pj|R
z|9HXa$PKN<&p!Vp>^SlbC@=pbHkZ0^(PzJeQzw_O;s1Vw|M>Ae=q~uk%s&g?{raVt
z-5MElY`<2k;q0@|-es+c=Xp5qyz}sx&wQpKMf+kOjNa*sUL%RxgXV>1WQtA>cdq>$
zo-5stQf~OA>Kkz-9_#%}wBM`mBgPmQSV$+ at Fe7s`{<{4REb2TRsb~jQ^*)Ft<KKkV
zc-H~hGrU?A)#hXVl9HTqxs3c!FV?SJi=*FhK33lGQ{1`n-FVjo7dv|UQ66{-%l`95
z{CfEo_^tEs&ddH4m3w}LXEsFe!N- at O^QaHu{YR|F&z_%)&%f_v3~b+m4UhZ+-~Z8l
z*j`QIn6o~BkA3iOP|9z_9iRCuHoxW!;IZFhU9JP~y8J6RbEbpMf4m*n-*PuLWId#3
zosO?v^>Hko7~iXX@~pGYLVJ7rF89XMPCE_X{N^`<#)!Mi%p8cdPLQe at E6u`CE<<ww
z)#X#d61K at Dc~elT#6mMQnl&kx%Rwf9b-)Cb#5 at FADmM$;AZyopeitLkjGps*wSb=>
zQ-QSBrD)N;Hf<y^AlOsFp#51GXd<9xfxTt|ITz`4I*|EM!lbo7+`~C0;iiTB9)fh<
zH|Ky^GbL4pLIIgfCdh)Z4o3kk0Wv{0e>aoK1ar at V`tUrd6>}<;3gk=#`RW9x1?L3p
z+89#J52!*Q381V=$&IcRf_nB-VYZB8r`FQ^Y%Z4z=87Ply?FFGNUT&c$T>?S62bc5
zd~qCAEuv-vTzkA{H7?MsRHaf0-tF2qNTpv~Gn#?bz^4-ONF)-->6n?)W~N;0{9awd
zTBF5tYyC__H#u6+g;V5vihL=VS^4ZH3=C#rnXv(my3^3kg3_Iu%et&=w8C7!-s}KY
zG&x+8GaU7CYA}`sz{ko}o3L%iAm+{N8dbt at C^qkVxgW~tcUQZ>zh|>KWVb(ub$xAk
z=ke#G<Inftt{**wQ~rJ_YL!j+#aFII_T206;H^gk+gIU{{uD}YJri4VN8<+{{~Pr8
zZpDK){Ryt^qf{*6`IYzKwm<p!!krIdQr|=P>g8AA_Q{9gEej*?N+l#GzX at Nu?6cT(
z=f`l_*KWd*UwIvFx@|d5|Kd;ap`$x7w0!`POk~XV;I8Xp`t<3z>#n<S at x>Q6M8imQ
zPCM;1eE##FM=qBeF%G-yGjkwnW*BV^+(X1g=Y`bSDFEszuE%YwKaOq1r(tUGhNiGD
z^p-piNF-t?Rf>QULDemx?B&q!tb^?)Q87c<URsT|_ at oA4(cCi*jXh&e>&^FlWOI2G
z`qyLC1`8*jb0KCt^E>?a%@5$re|Zg at N;iJ_rLSPqo4<+Q-+Tfhy=(C2o+O-iybBwj
zn}F|LaWTsM+wiB`z6;m$Q7V<u_uL=xli&8 at 6F>SL=GUIUw=erFZeBJW=f5 at zIAtL5
zT732P%klg#KY@>a`Fb4l-M_()Z~qHk_n9B!*4Iu!p|2l)CN}10)^%NUb#>vs`|iWJ
z=bjq?S<RpxfBf;d=9+67_6#lZ4-=aGow4EfDDb4to**ifN(F=_kw~CWC^UfMR4Nt7
z(6~1!Kv$_1B}ODdDm_tRz?vMj#?|O}rBXpAlL_`-trt<}Dt at L=C<Ivvk`9t9Eu7{x
zFe?-WZd$X$JvKZ~JU;<lxap^w0VpA$%#Pp5?;*KV^2f{pe~%G#t%p!47uO!wAFoYo
zNC?gqgz|eyfYRyoh$f9Bp9+raHEyZEgn{cxW!}6dZF;Ik3tE?<H8Hww!wo65?~d9)
z^YfaS;kc2=r~??+iaP4i&REA>O)}I3f^(xzV3uVCQZz02S3C1$G8tSCNl-Kz4FU!#
zIn<ge%DOU{OkgvvYg)6OYIjZo$FXJbL7!!=-)J-%IGB;Za1O(6hB{{?@BADfeP+m3
z>D;hSQLjo3tJn9yb4M at M9F55Y`n?c%HI at a-7>x2G!1rM%(ulQ;t9QaS^@4e~QiL~b
zzgjBSu=3f>u#D9NATNW6YWPp3Qo&FzhfT|Whw8LN=xS at l5pO*S*@te!@_qxe{UJO!
zxCEEH?`WW0LbYW&rl%d0D^<9)GP0!#a>dH9A$Yyeyl3+&%zgc-SkMMkqEm6)Yv*G9
zh7E9yg;=TuN4()Rh!lok&sd5HwXG<(F2Wfn&BF4ZejA^?@>{s~nXNFMJ8H4*?s`2O
zal{e0{`%`1K>fhL0N(e$_u+fr`yTT7{7c?5LiNdE`GR(d-p3h+ZKBwkdlo-gb1Amu
zo&=m2eB<udd$1xt7POy&lcs(U at eGi4daz`|n_&BKOi0hd4(}<f>i-=KEcj^d885dz
zqgt&Zo6BR{ihHnQ+#<}F*p4IKb~0*zx&;q!2dv&l at P9oE@R3VSfL$)3oIVUQT3nPX
zRXDW at viS;fg-XyU888^=UV-sPoq|_QilSsD;kZ+e#J2U%qU>9UMiN-^#@8cJ9E5e)
zQcQNXAfKL#(@&a at XYafYpZ&tsxcl*qsGBtG-JUUh`gHu at 2R{fR-~cc*G=%fdKOaB(
z(T_KaHMfj+`b4++``NY%ZIvM_=#&2T7yQT;vt5E#=?AlyNok$wJ-7M*M6L7PT0
z;;(L3S{ScV7q!Rb{;iH#%zhAnmdoWJ;?2)9>qMzlsZ<Iw at miBe`HkKuBkN)NVXZ%6
zwuR%B&*vM)l3<iTIh{@iay&IUV3eF-QeEWO^F at Iu$)=hq at V}WkQ0W~1pWs>7DoJHH
zs1}|FM(io$(>W%<=UjxFpQ@~kpHoSn)-v&a)MSD{orG6wakTwOkWCPGFs+s0b#M+f
z6U0Nam;4TnE3cabN*&I4?<$2<^9Uul9A~wcR>K62OSxQbkSB5+h#4q@)JCZq^iU^0
zKF=h6iaV5uYlgNVGs6_BcKY7i2wA1#pr<zn%dWR~)5yZk#Zqtf=EFm+TGzo>Yc<qr
zJGFrI2g^mdTt#HK&x~ywL at W!g>%fY{keRv=RwN#{9l4bP+;U-<(fWu*BUrnBJB(%E
zJAPAY_A&z}`FsIRxf_q&zXH#cx8QTn{u+KQi!HrztXSTSGdfZ*UJ={34Pv4xz{C>u
z27 at qgt3?#@c{olD!~U~KBoeSAHj3FH^z`%~J2V92xrhXtvVo7`^sM8-hleUUapwE~
z0ZY1{$NIHT;D2wt7T$y_ at s0(ZaK>0LM#;r7#~g!Y%a-AU6HY)Pk-(=u^(lPhBOeJ~
zI{T|AdS4H^&x9=<S!_#ZlYNt<*chs8$B$QEiow!WMEvA1y{tE`HN#{7g4d8|uzu)a
zoH6rX at aoK2Sia+KY%8orU$Gl2d;b>;I^Kw*C!SX~8rg3>Xqv~tuy+7JzEFfy-HN~7
zvm9%OHsA{%`y=3F at qC|;zyA3-%$=Qv<(IH++W-!W6yZnWFaSINZmo<$J`aBw6!@}d
zl=JmHqcAuG%X47c5g3E|`ZXRL*R3~=hL5V>iqqcnA<WzIJT^S{B<}sm^{BR8fp@=p
z+L&uqNz4{4T7<jqx(ly+-RqD at Byh<km*BF?E*o{vcq#hK5PTDe5u6u`#Q-P~peUfB
zJCa7T2 at o0ir)FRE`gD8BWHJqs7?KIiKqxq66q`U!duVB4x<-}>@F^V%*9Q at lQ9{GU
zkm0%&%8wLCh66~2LZLx!L*mChnes3#R99PIb+gh8N4Z=MfTGqO at b{D)RjXBGGMRu#
zaZH(6Q at NhHlBo=g05_dZ2lK}9*Y^vF4C^t%H50tvYPA{!-&HCWc4FgaxZXIoD%n%Q
z6V4`ae6{%|$pP;#pU*d#M(DMZ3~)}_XGpW9N>;Sls#-d;6h!Nlct0vVRHFmUcBxSb
z*M`<jY4(R!;v`0z^<e;ogk0-~Nc#C)kesTLgwKOw2wpSopEWbZXCjO{xG#*5nR%Xv
zd_Ip<D%H^Gd+dP3Ld|h8lrO<DRy|`9A~K#k9F6fT*pURLOi9DGEYxZaCQckzANb*m
zojAS~3+K;3sa%C+fPArvp+W_z_AaC*&xajP!Vf0Ypxn0wzV86A>b+GggP#8Eu#Bxq
zWL{2W#`8RQuo3P44VK%-;~PKw8Wu&$7#JGDU+?-d{`axJ;H-aqJKi$=7r5ctU*Mn5
ze>GYP-PqRlDopI`K<SCi*xuid)|iEOto{gO(ito`@<janx_j`)qh?`AvKtToWh;*O
zz*4klhF}ka6U(-dOvPb*gG%3O-1Fo*OrJ9yix$qqqxU|73hce^VZjZftE&quR;<9~
zmtT&Le)OZr<#MAE8I9uZ&;Ag*JHk44x~r)B%L|#?Woxg*P-Q!O*M=4IVOthl$A_`%
z{T-`C0KRzv850BeKC-2LEbIO>lC?=Vb>@e$bo`n1P1CJlQ~oh*&aJ at I%;9i-uSsYQ
z at gpp)@?ash<+u2Ac`3ej$9HgKyo`Zt9#8$|tN6)Z{{Zie=isb)x8eG4-huXuk3)ND
z3%0f_#e~jrsBGPUZM}WyO4~@pqA&nbsU&6}c^V48xfAz4wgks at _To>!TZOsrd_N|%
zI*1HE5|(8nm5KqrL3Lmw?tkhjbj_H7`3n}{nFs!avS(nKy7%W;pJnbD<Hn7{s#UA-
z{`bEhpZnbBcDZMSWvMU5o}rO+0xhk at ARx@=^MMqG*32Xy`Fy^?6hM2bgc}g at JOuv)
zWQ<Vr{3=)BXG^7006Gb*!uGaWq#cXJg2sp>Y6R_Sx<L6HvjL1&lccd`fZf}f!Qjv7
zEJisI0c|3Y2mmXI17%*6U@=RfvNI)OT8vGip-y|6txzeWX2R5NndFfKfaeVx1gI01
zHn8ON at -teasr`WX4&vNuq&}C+jcB&0SqLRonnhD0%P}H|XNFG4hHH)Aseqo at y<{>O
zkQ&V(aZQsTX0zE~p2N*2HDJh65RzsV?T3jUi4$wM^jXmB=Gx`&5cl&wwHFe{UB6T1
zX8itKF4s_7#%t7GQY4BTW0EN)f+Rtdl5x(}6d;T{BAi4ve$wVuyVJjiH$_fjwOR`R
zhws;8tG?$Ul59b`a|+ye2aZ}W8DIR+v6$4cYf0PunO*qx5C3Ins?zas%Wv1>#$T^P
z#PaIB7W}$Zb1m18a{rcLB2$-{834snrQQWR<Y)b2N2i*{-Vv6u5a*6 at aXh!SisLT)
z7+!x^D=Nh}Qke`gZ+$=3-u@(Nn1T;|`#Q8<djqby@@`lib8+4$Pr_?Xc?-_jcmuBb
z>}8mI+~4Ek!<S&;PzR#XDCQq`7Cu$2;)g%}E`IH`;Dq;HfeTKX2UFaLS&I%wYoZS7
zCw3i%1&iln+W1!VbpIJQ|LP7 at trQlYaS7hJXaZcXw$IVybUKY2Z at dxNY<8bq1rJou
z2-W$9U+ntw-|Lzg-^co)$FRBbSNM)WEFQz6_S11p*SVOGnuUr}z;lCt!lOI>8_yS?
zhUWmo$yid9da9RxBR)p$edWW2=MOi`D_I!yyK%?5kHff0q^<EVwu=erS$O;GE8+QG
zJsUJiO+j<dI5hVRz at Vc&j*V+ec=d&!!09vEP%g%i%Cw;M%)iB|n}3I5xf37w_6=yg
z?s{DN#e3kl&cr+Z^#mMu+$ng++8glQFMJxUOFx8vJn3*OjCUdyjbO%-H{w(ORK(3c
zz7Bt=CUML=ufPY+S%PS}8#51I0+Xsoo+nJ4hJ{NOVA}W=tlj<?{_B at _qJlW)pYmRu
zf6PpHer=yEuZ=PI`OkljY&N at 3HFO7J&rr7}byXq|;=Z9kM{DsIz1HGlb%tU_L#1C@
z!=R*t*Teb;0!f}jK`Vck5%93vl=gtp$TzbWYETfi<|bHXlw5o05D*i{YvV+1q{zs%
zz8eTSNeDEmt?pt<{zz_lKelZ*G{{uTX0=4-IFn$Ja8N=O?(Y(bL{KOcf^|URrt`&X
zQaK`>;*>Ci*9ga4YnsyObVIESuP=;iHCvz=KAwvtlk-bc1!i}&W`;E at YREuhz&Ri(
zP;$#T=XZLZhhnkVU_-5SH(|FkZKuLD%(boA6%q%nuTu#o?@{}<aBP^R<G5(ng#WJ+
zNOhp&xN264|Ic8I_P5l1f@?CIUDLI$L>2(dt+(FlpLNz*4Xm%Hrw1)9ErBn2_!zC5
zx9fW7AI#%#KY0_nxAhG-LGu7(BRypv5*<@uB2nZD72Nvildxn~2RyGHd4-Q*DT%)u
z01MO{5AXc!edx`WVcQYFvQf+SAh%&9JhvJ&Of<&8 at eEFT?LvI#3m2nObzsTj-?3u{
zrcImH1SSVzB$XTElTSX0!w)|^=t|2!I%m;j8VSomv0QIVSSPnpq>?dID;2n&K|Gm2
zJQ at Lf50zpOC8z$fNW`P?oC-=cAa1!RR)(7!#^OjN60j at -w^l*1T!HKQh^JC8wKB>z
z7d~vH({VVJ8cZ~bcq|Ib7`U}6N|g#6=fE}~WuzvT%LU!MckI}Kcfb4H4c4Fg<FIWT
zD^{$);fEjIke=4U!BVLdM8sNKTX*?APe1)M7A{=aNDkoR{>|6o{*C{ENYutVW`7Aw
z#=jX)_WcIk*_DXf87vrg5+<h?;E!8>fO|Jz1LN*=i}Oqk5i5pNv<+3ajIx`B<wpVE
z0!%%q0b{VV>kPzA1~pSa$;ra?TqNyQ#O(|w#O7dX+hR=590}Ws!t>n`<K5lejajp1
z?YD7l9{YFCa9tN`)~vzw>C at 5K*}3aIBaueZc2FogI~(KK5u}oF)T&iDE)Yw^5syV-
zd=HgU5v7`kcp`yBJO<ybpj7b at vwf7S4jk7-BpOF58Lwv(YZa8r6*$9thE*%0RCD3O
zLOPRxQ?9{8qKL=qdxqy!Q7TtZJHUH}=XofX%gE(&7#bQvKA%6Jd&bI at E3s(Nq5$-0
zJw#Y$LW!1=2g-gJsa6YN%AYhcte{4V*%?t+DUCJ&=6SRWyV~cf+tz4u9)e|Ns|nUg
zoRZ08a1Lfk2*$L)oaZJe*IGpG_bRgs%XU<vqvVfLA1$KSMx!dbQZmSYBc9UUB3iGY
z*&cqEx^HP+kAi1r4zx+7+F*}n+QjQoH#DuK(Co-)Bv;8msZ<K;T(~Zn4bnOx&Cuz3
zAkk5>6<*UMUJBHif#ckVGmUDgtaVKKF4A5x>UgHvGgVHgD;r6Ky1c3R#Aum2C1oTp
z%+k278#n}NT at Kg2${o4>NlHo7SSLpUNnF8s(#*|HK41cQrssKBwrp8r&5Zi8?{zdr
zW2L at 795Xd&ow*dzmQKL)0k6)iw)PdVWL5_(%Sd>2nAGe>u97RcC^`m_SR7uhisJLD
zQQEO-7_e9k#0Q>__SRJWQha|D7lGz+C`Mp)ldBf<Bdl&+r;1!|=f66+DvAx=)O{2S
zHI#}wQ|J}>e6?IcwOktEWL3)N6dE9(8_vE|D<~Jum?EGDDkA-2oKy9%1RZMesm at 7b
zK8z2?En{o`Ntl>}`I*!3s)=vIub#US%X4>ND4Rn(5yd0 at H{*5VFTttP{{dyUfIn>h
zJ|b2OK7341ABnfkxeRUbNpQR>Ru4RgdpCUxWhW2cv*AZ7c+JEM at zz<N9G*EBo?i!!
zwy|NENbp at g{1HT^c^uk%M)>)tmPXq%YRKhwW>cMf6{XOgQ7Yt7D(rkeRpdKsl at f+3
zW7spY`JH=4>BZeM_O`L={x}~UyeMHJs3EY|$f|-gW&^a at Aqj?dG1n+CrB3RarF}QF
zaGhY0#6|mKFsiK?l`y!~>s4nfEmRI?KnQSoz5Fhf*JwQo|FAZO87bDfs3`)2v}&3_
z;K;F5 at XC8+@S0=JK7;ClrA7 at Z4P%ywZe%1Ybf!}BK at hIMpFii?P>G#pQo^ol+N?4h
z$>+}rk~PDigpJw2ump_bqkV5Qd!xWy<yn;eaqhXUcn=(NDlbS(IbX~c5~PQ-X*>^W
zgqVd1XPeZ>K at BT-Em||B<_aV`D%T8WrL^uy%?k9H(>WlY(DkFvbIh7jibf)%l13VF
zDB-5mjJSjI2T08ffWRX01?k`Gj0B!jMP|x;#M&mpbB2rW;G-oS$CW>L1l984SU9~C
z#sIGCW77B*v}O{)%@)fwZ0#A^No0yu+;G=Q3~bv1zch$)|2Fuw3JjTkXtQ=)53^@X
z+@;NL^Efn#%>L>=zCXL1zt|Z*ZpvB{aG(z at lGUO}Zc_WwXU6mD<RMq<h3C0g*m*Lt
z<sK{_T!uNBQ*g$@PoO)y0{3=bgWqiV3Z}Olh2ti at 8>_STp)b1)>2w-r&;55y%`Aiq
z2L=X+ep8VE03ZNKL_t(1Onoorw!aoPJ^cY>%RTUX51onWu&pRuzXlso*e2Q#;b9<V
zzc<Qk9tZr`U2m!vQd71kx#Xd?XN32Q7mLtnq+EN(P(ngIe?FfN0KHoL(r%gVW2sas
zAVca-MkyAFiAsi4_Cl*-W~z9d>d455uhtf*tCh-RG?T#JQNqM5jdp?827;^$(B2$s
zi>%ovUb7advpypdi8K%b?bSk3$E<@!);V_k9y(}|v=HP{W~OreSS;3HtE-*jc~2x(
zx(1beDzV|ul~k$Iofh`1nS*{_|4j`HG;62@<s^UnZ{kIDB-7$}y<Y87uf$R7JD8==
zOrnxY?fpYi$_AM<m|zW%5)G9-YTqKR9j-6_tXwV!5<JSsDwRq at qgf@{>iDOo5+vDb
z_CpN7-(md^=a at F<;Vh6oM+`3T9Gp9TC)a|SUg&uPGQ-JJKkj|q><kQi&x4)FAlWqw
zzU$UC>ptL?3n*?|gVInhE_viWBw{v<Wl*lvaQcZ$@q?=`f#>_MjlttjZNx>Feg~Ef
z7$0yvAMkx7V+OwG!-_;;hM9NxrB?qZ4-4i at 9@QecDK9&Cqo~c};2cY}0#%n1ZggX5
zv^&~$8CZzfDZl^~XSn#+En`AzHcGWY%xpgfr{iPz^^VWt51VhqhmZOprp1pzU*hMm
zYZEacH3P1{GZkNTOPG+Fg%2&h6*oWqx7bm87F!EXBVxtjyZaW{cri0z&13I_9D7=~
z&3VHf-4OTp7^(GaxW7oa(Ii2c2CTFug|@HE>S$9;trKC5fJX62D412yjDYsX&}<F+
zUl3IB-?a8dZGQQkVVO`Ok!XmlE3s43pxGd1R5W8mX^zU at XmhJY^_FD?5+ar5aokC!
z_}|)BCL&l$$sBE?mH365iW2a$;bJbA3qYr4E_BXFf;6MV?@}O6BB at d^&cDi$!eCs-
zQ`b2612v$~enO*V>PTuhZs8te%ouVF77B%+_ at 4wN-05B=X?$Kt-Zi6 at N~MC&aJ{Jf
zk84LA!T9gIPLg;&10)<;f5v-J(#TAU${v}~;<%{GoX%m8R2U{dB$aBftj>3ICewX_
z_o&%RH6P%01=iilvY9eecDJXO`>20+9i*nr0IUdnw*t$u;Z}+mdhStpP6ZLmMq4IU
zubF`Xq83W!O2auUV-SfL*uzq^sHr=?_yCN}YTwZ#bH-ShbyyeXOrO}0-rUu-H;;oK
zoP>3=uk>-+lQYr&HUQAglREIdX(~C|?-*lXTTyf+=VRT_!+5mk=Qv^Nd$F|hZFpe&
z^>{S*LrnEf#F?}I7191A28&za`oM|P-Uswlux`f_aJ?FATdY-K!SQNni%-V+^RC8k
zw|pHd2A1Is`M*QLZb8gWA#SIdgyt2pXM}4WUg_hsyDayCXqu_fSe2j<6f(-1PNxGW
zB(43>UNR&{s=-%DlS+luzFB+55Kw96i1>g⪻gYAy<i$*4^-X7~$4F9lRG_zXCwb
znrID+%ApASbPNf;305f+WAtA$KjD3gpV9gxmE?tGU<8tm<DjLbrJ*6Hx~cIRm~BzX
zQ`qTCuTlHMXq|>;?RY*OVG_gf2-kCt*85Cli3;?!zDBb<D%s*VXf{q8m8yJ7<%T5i
z;eJG#K~Yeygfm<d!}X*F8yxG=*0eUDRGAqMwHsH$p!G9+1~jv%YiDPp`<)p>UDIl|
zplc+on$md-yVp^QsF~03z8=iBYTNduW~L#vY)24p8xP+dcB!x|<TgJA&#Ayzk)TG#
zvdpk`vIX0w%fj&YfRiE?fjiH#+iP%K7e_ChiF7L7ESGtiy@;C!Ub3c{x=C_lr;b*8
z0gO3%3j^Ckv9SFVJT>?~=&d}5UvIb?@0xoxmJXbWs#m~*wo~!wwmVU(<S;og9|pjL
z)NGtJ{R_xX?uCIhVm~m$)@EJldAMl)^;k3T0G{l*2TLZL0oz1?eIPT<<K>Z&Xa+%E
zJZY**bO-<mdiifEX9~MEX~u(pS9u!Gp;2CSr3%+*r~*an0~7#;qsOcZ)ZQWLNXE=X
zSW*`NtYHAF<E=F~%pA40wl+lfxwjHfhMQxOAn{(<lu*IE5<W_wbT6mODV&|6n-|Fu
zo1C%{YuJ^I?*m<Dnh9feEgp{t<b={9m2zoa4(F#(C^TfT!p^iRlT$*=wV_Qt)lG{4
zU7I{=c7p_p(kwcbsgoGrc?9qL9yLQyqX{L<;XW|TV5qgS_SDfe9kwD5t0XkLp&3$M
z6UTuG3|d5Uy>Z>^xG3S#o=Zx0)L4Sqw|qVykPuzdDy5{60OfU at H)aF1o}bw|o|h!N
zfy_{I$@JF?*fL>7;xKj;20macIF%A=g+Un09+g-a at mi&KKwz=Fm%Sd0F^EMYIA+NV
z#A6XO-(`pH5tfKF2~A_PIlR#w=(%9JnCIp}{px6uu(90Fyv`G`XyDCQF>n_ieEw!^
zFRa1wQ!YTl8i$9r-hv0W-i(SV<J1KoM$N0%+i4mLZSg6)4QyD(g714+*m)`zkAD+f
zpUzgzO`%ElUs;D1#=jV3MrA(X`Xz!QN=)bkMcD`?NZL at 7pD7lL4cQCFaZoCi(9+V<
z09w@?KuHnL$%wJqDeIo5awAH?lF1}8nM^~!4Pd97j5QM~d(te85<8XO at V*Gvip63>
z6koF|YMrZDnsB6?q)*+^H2c6z0zq>)JHr5#c5P=p3&|(5LF^Ai62&?uCA5_7sVkc{
zOC{LWc_YzazZ#WOshg&PZi0E9gL4#?rl~qWWqRR$cIvRk_btJ-I)G{RP^DPB9 at YWT
z`HQ65_x*<X=KGZLLd`%ZK_v;``XQmx`!^vI6P0^$PUG=-P-{i9!KSKw4m5kFMgzL9
zXpn+)p3mn;%%#c{bsqG()ec-q9_wrP9VFu;GBaVF>OMlAIvcU9;lBgEW#GHDVE|!9
zp+10T49u{c%me_*f#><K%--qTjWL)zYZ6{}?EJcnt(lfN<OobS<*N}zec`-PfttGA
z>`zP8-5u)luKgRrQnP)TZ}`C9%)T6%?r~T?@C!VX`z=;JeRthz+p^G^o{lpnd>V7w
zk3-ch55GKY_`bKt=i3--*uAVNHF`Pk8R1M!nDoEW_Y4*XYXSO;5s1=8gam*J^a+^4
z{ZTYqqeZ|9tOy!;Z|u>+?@(DA at 10{okjsd$UbjlN2*R|PqFU5yGfH+n*XVS(7mfCz
z;qMTTYDPgDdy*h&eIl=)|IcW)5*J3U)v8z<X!0{WAA{Ni$?62hLVS&`Yn=|=!+1>u
z<T at 7N%$sFdNG6jb0+w1IqAqL-x>bUuy=R!|p{+01h{{bhL#SC8&1k8UnGzMw1<9c9
zEpE`neP^ai*SNaiX;x4PKJS~vkHkWq!8GfrCJSN5I3*71h{y3$qX-f<evX+LbqUl=
zo7S9ZHj`t-xeCiL_4+wB9B+=FHUbTgAJ?y9#1UjBtXbR}{ky@=o)N|jlNZl}Z`*+H
z!j7k5MWXQC8hqbs06>w5jZ(IPxw9q*nHk^rF))-zwN^vKj_(EFGVl?>d2cxy6UViV
z>fPV0nK`t;2_Hljh`o}53D<0`Rzs;&LZwm(q9LP2rT5o48A;M!4*GMxjK{KPj81&&
zwR5LUyA+GZoq<i+$I(|^56iNUw#H+2+wqu^S%j)v9>aI-;yzwLHm12}9C}#@f`R6q
z;WuP3%H{HiPVf7BZI4z95tiMkbuIs$plCFiJ8LzP$z%iR&}eQv9*66?0jXeyfY!I+
zD0-N9D0v9?C{j?UGAG^-&#A at K3d9KnG<|hY+uiqcp=fa_?q1y8S|~21xVr}l?ox^s
zcXxMp*I>cj-QArx&-b0*41bZ#By(;)_ny1EXLl|`E^p;nuy7~)9=s(?#z`~zE|3bG
z>X5azi_iaSliNUE_{WTxG=a}j2st!@n}-_FL|m7+M`|QK-Qtq*wT=F2Cv~cmD!$4R
z9L66PGxqI$S0F;co!%9h5Ds0=I!+N&y7Fu6 at 3R-oO693L?Xo$DU*eyGzb~o~n;DMY
zPI0O&k1Bo=E0oF!#b&s~hsp&>3fYE0nZ5YQ8%LQT&NlJha!vjO*wV8`Zd_HPyhx`l
zXZaMOtcnn35?eUW4)<YwFJ(KT{dmU^v%wxmVvQJt>9_;(HXlBUt9(HN9Qp)$Ev at Ot
zBD8dJLh{Q;<+M#tJY}=MSk8qeRyz;)anBQAF(23mBbXwTeCME0G{UAv16jvLuf%0V
z#tb4emnrxiaDOXGvYOsd97h$TR8liE<^rEAxG~T_3vepfpY^R;7cK3q;*=J@!RyQH
zX&62T=wMCtl<=O|bUVxhl4UVL6C`+AQi=``6C_Xdx|nG%0?><j6n4!ap$1|BcF>ku
zDAr(Pw2^+!>G2y{%urEKRm4|!Tbo1BGw$(QgJ`;z&w8DU*Fq-;Rnn_#Y((|XI!qLa
zCwF0Rw*^k<rY at 6x!xT-GVix5eaoFB=o{^Ax^)J at IUT;&noZm({l?GO*qTORJ6uh)-
zWW{sOaS-bN*42=k1~4N}Q5J;kB)-!g?N%!OE2GQJw&G}u00|2kQwMfgD=c4=s#0Ey
zr;OSm899da$UGrE?pIkkGvrv at 5&d1orAa@$yKJ%<Yn=OL??g(y^(BqzvSl`vQ1`<s
zkyT5P2r^Avg6(SG5xDjw5shD4gM06Qzs~sFM7GRNGRSe6L9m?>Os+YUTW##<t;`0e
zH}_Lp8*bzM0WG_(LeIi<35Q-4{z0f2dTMC#6Tw-MfWYtO_fb;69d2ss;N!3)G*NAB
zNWRCS-_I}{SQCgWBRqt;Jyw)3&)93TMN@(TBb-#^-7hoiS+_IX{oMXw3)dsc&;P>n
zPHyCqQ+v=#m<Vj#<QZhDX<=#k-PM%`0>A|bL42LMav#F&y@~znY*z3 at d|si5apwj8
zu0_o5g&63)M54QuevX&vq&uQGG!gp4Z*3VwixWnk2IjuyB99 at HqUBv6K#Qnl(4bA3
z^1+?5z=jYgP`{KZiZ*p1_URX?TuNkwaA~Qg%9hdd?dVRW<VZbDGOO{t*96i;($kzb
z1s#A}lG#YD6VYDVq;}j$qzMQ|f+7aV?EM@=8B#zcU+3}a-3c!Z^F*vAXBQ3;rdZnF
z{a#AINsn`~G*&o6=?BhpVc0$vcPwz$<$K~zfDe=rNvk5ngB(X%z9q=?colQ;omf7O
z0d*jN at n@)c5A6hx5;22hvYV%EuNc;tWQPtm>mdR!6uM&0$mXC1<>yyctU?rllokS}
zfR$eyd8aN_Jj{5=Ct!mmrFi&8ayB2hQx%5ri{6qs)(ch1o#GP7yjVi<f_;PKeAM*2
zL3QKjU7&L|TsJoy&)WN^`O1}lK;jf3oJ%y>^QrmR9 at Q*iQsTb+Voe4|i%zc=oFavc
ze-Hy>qB6CLAOB5UJxY5o>RW!I)<GDNpS=<MPtgHi?-DenEALyT=izG>6kd~h#*hZm
zJH!7pIX4%0w$fw_iHNbVvqKZLDp9dI$FDVKEp2nV+WyQ>LjRS#d#YC-c1!DU{KWLr
z&x*edK)vQkJ<4tvbt<u8liD1+h)l&3rDS=-{lA~$HwLU}Qz+OdifIs3rUywF0o=v;
z;ZzFLvWB5wyTb6P&0-%p{>)SZWCIKca%eGrujn+8&~)!P1G^5mtU4lOz`Z*qfm{C=
z`XbN~{ZxMxXDt9A{f`xy$1!rzQlY&F(K>t`(%7VhM7T4F4CCzIAMzBv#AkdsuNl=N
z-*k2gOtLOiiIu7StOCGnN-yS^(bZT)2Wn|XLDYI<)5YMHdoPM_CNvV(EswACz}>n^
zt_CV|dRWyzz2<TYaWZGOn)@0zd=>~e_SLGLbw$iQd6q*$8%R_}eInwWFP8OSAsiCq
z-@^!<?++j&4|TXof!AvBpoXH at XRpgD>nku}Vosh=ha`ouCS2wLB}UkeBdHJ}sKbhe
zXd%F6?q#YQzTFHwM(!?7fkEWH8*_MmKG^Df5<PM75b%9ql=2JM8RBQkW;sp8sMCy|
zk&ywP-`8X{sOpjpuH}5J;qe^IK|o0J9PH^ZXVh)Q)@}s!Jl~zfjPB`Oc}lpUNK#-x
z<XnbZy at AQBhW`ySg)m?z)3X_vXnAVTxv3f8pDSTihLQE)S2X5nFj8bF at I*t~z~C_>
zA2iVUeZkc&`<xj2)5U%P5PyFG@$H9_rZk*PB^Zf}H#y9d{Un^)9**&3FF~$jmnWn@
zs~Ns9h9F#(k<GDM9uvzsl7A>J85(1 at 0dYGnm#-5`<wAaN*m}e)Dy^5E$P*{S3Cn?8
z2k_8-73QZPMP_irp-i;lWUA9Ae98_!1I_7t=U}n=M$$OBzX*J at B2N0_dp6h4n9AQ|
zIS6rNuufeVuwKXxFe93S&Tts}kGVt`5!$)pg*3UM+$kxP-;_1;?j?SU(XQtS+fn_1
zD8gI_2Z{3tJ{3#YXHl5+`JRTr8sp<_{81+Q;j{ClzmTzK^&4^WRKj;KFyNiN@?h at n
z@)D!QM(}x7LdRnuBIIZA+T^{ciI>KZ$#(NO(#1f&G!_u7Yh7bt1s5lPRc$bt7 at Auq
zG{tEoB(C2H*|qA-CkETyZ(KC-mdA|FsPLZ6eMwiVQ;g77Dms5#V?qQU4d#$lA4})M
za at -%YJjZWa<k2e^63a;7Z2KWvGGz-3IQ}wl$kt<5qaiLUi{#LvBbN8$ow>k7OG-Yv
z3XC94gl*3zyZs^zp{9NrqbCkwc&X8U&7V1fqexaL3h-cpZikEo8r6hAJ_WnP+9_i}
z?nmJrm!W}Hi3)*Kpv+W#x86&^-wJzao!TXUy-xzpx02m148O9L05f+46E5SQpDM1o
z$5}-BPShXR6UtgD3DLigtMmS-I(LBtSV6U$LsS}6z;sK>ij-`KpNXG+B*Vlo8`6U?
z1sk$<nB!YXM5C4iR`-p8*&p!;Yo-_}81Zz++?|Ss?>Y;miJM$kDWfLrJ+E|{5UFgc
zb~G7v+;C7LQ#_FaQ_;*(x0;T;ATQ+PN#&b<rt*g43K+LmUhT0)(-z=~#-B4im+e9@
zW~9Pmlgn6)L`iEx8wFF)p#cKanGBtsh2O7Fy@=|v%W at Xv8uqh`Sc3J}9$+e4j?SO^
z at czj}Gb{au`*h_7ElDg)to}NqnJidCd?_ at RlHMDeV$=M7&UI)Jx-({6#3^2%2Fh_i
zq?t|!O?^+t4Erpf`51eE6s6QgV-Ep9XEJl<OTjw at OB@<_irvK+0H#wlZL_nt9sm^5
z72>t(bb+l_X^}a0ifBBBe!_?q at n4A&ME<YYC3j49R4|b+x;l1LKg0RURKA_QiW}v}
z(%q9xNd(J?H(2PUi9j^?=b$kO3or&q1!<XY{mXvKM4SoTWue?Z40mV0ne&^}f^9y|
z(Lyr4Is*v4>b7A&)?kNtVj(zzRI8Udpw#kJx(%m4&SDZf8v<eeJcVr7&bSd0F%Yl|
zIDBv;RWySFdp7n3DC8)An0}OOeWUCguZ*7|gMbw(J{cCe^WCA+J1{w7Hd97NKxR_K
ztT<LaQd>C7?(nY9T`eVlp3PEC(z?ExMn!n}5I}?<Q!_Vag6G=51Kf3JiGk#hWpIO5
z()wy4+arXAKNS>g_xdc at 1pS!|Gpwfqo3;KN_}Vqfv$eakZ at h1a1v$sWKSW8&7HkG~
z6f64%&xs-2VF)Ofvb7x=t`bd!0o6!}uu8;*eElgg54c@(W2gx?ml_sg!&<`xwZhG7
zrbioYI+^;9`%}$6(4y1c8Ov^buM%`5Dw92X^_PX*8PgIoWgl35hQG>?>N$A0lkcDV
z`MU|HRpr2<6SOR(7S718>D=Ftc}6KMCp{5%zGligzijCdP|3fh&r=q|gijN_3-3vd
ztru6+-Gk{Mck#FH_4azYV+eE&W<SpY`izV5u at bnBnz7J>5apU<^4Di9gyd$&wE|XQ
z%AZ|fYsUzRO}iu(r8Rh6=|M77nEu|)W_E5J^hvwUadIWP)!cSeHL9T6YH6s2=#isd
zoSo&Wpx7UnTGSR}WLI_Z1(rDU={ZPMB9)YpEtnFKZDs^qLqjKXnZLIHB%nlgNi)n8
z`Po!vZW+~YMAU&gAMx$qu4Xn0IOS1j;+ at Kfl%#17Qa6hFrRs!HOo9mia at Q><p`4!C
z2@|ZiAa6aBevsxWN$3E&@opc?fuJf9e;!6Aj=^qrIEW9DRN+>iBpCJ+L$$H9E^elF
zUv7)C{V`(j&h8G5;q$CQer(MatU3>ry%1 at bd1DVdoSmS@?>C7Ed{v|Q*$&dwPX+Gn
zPLdF^ZyFTd&YG|e69&$MxXDCa=Ge;7Yfejb{lT5Pwhj{aFEU%HhstYRwp0tuj+4i2
zI0*S;1v|W~9Mm`+4 at Qr!+5dB}d12{|?%x0{ex^~igtSgbTyk5N`jeu#;4=}39 at 1Bn
z#c+{?k3eGF{K&pVFO1<->DEbZxo-)5i<$OZFpm_?WT*S1iAeyh0=-sU5+O5<U~tDz
zSM!^_yJf2*rW{I?J^{j*+EttGKRqhU^xn7$3R`_v0;3iK1LnPfI?nP|B2;=JAo-K|
zUKFaYo7QT7cY4S0r1OOdiL5JdDMAe=2r_9Qy6C0vdP)3;M;?=dsn27V2EfjFLZICC
zm7AC^RRS^n)Aj*mKfiqO>?OvCFe_&0$wdAnVVw<<ep}q=#J3Z)WFvVUB>=2(SJ%B3
zWSW#Hq96Yqe5g?tpy|R5TY)4pvUxs>GbVH3*P*2$;8{JqZAGp}@NlG8$NJt$CL_ at G
z*>;|$O5WgU!z6hI$WShRkOO*J7!2}Qz+y+gqNi6m{(F%yCO=)gEiO*{m+<G)cu^<;
zfu)&ijj)`)j!Nt>3vrE%?B2i`0w{HLF4%(hdmUz;+<i$Vv$-ufe`YAIm*+{n#AIpd
z;LNm_{8+&TLN&w;nOcNg%`VZnPk%Hc%1>I{z=EW{ihHVCmDgjemN(<o+8JiC(?^_;
zu?EP26A;KP{db(aiWU$E-cXg!z$u9Ho4S%?Dpkdlq!8_{y!$@3%$nC%QxN)zgTX0w
zW|?dp|00kE{ndy6=<2ORD6C$oES8*_oqlWjuH64q1={RsTx%pmyp(KxW}TcKbT-uz
z)Ib~CNjgl}3s!t$gd`1|$}AGA4zpWNJAwaNA36!~+@@@ao_ at O<3(jaAy+rE#U12zt
zUczhCW5_x$42|2B>3k)KR(a3|<g>h!8$V3R8T=qUGr%g?pAv*fjfhu&wZtevXJeGE
z5zDdFS=|3>F^7)*|F2;Y!fL_%h}Zr$Pxfg+;vWIymTNIGt&VIicgJ#hG&>PA7qqv{
zW=SlQL{h_K`W+zwA5Dm<t|H{t%-DknoiKFO+JK)k&xkHa?`KRC_H#`ODfir_KG=-g
zf9E$NPQZ(qlV`miv6VnM3a2!llr46*^~P5&*-fvnUts%<YO+H%YRfkXR58C+exD{F
zvym#Pw4;LGT4o^-MvuNBB9h$}F+)^oEVlm9wt%HmMwnSCVv|`a9+*W=zSpMgiC*#=
z{(w$XYDfuX_QJcMm74QV+Hs`fQPiMd<&(1yZB+y&iEp<{xB=>3Wj5f1WT8N;n>YlU
zBAe!WEYVd?qTN{XV)1bn5BF=@P)hUiK6i9<B(oV0A{ZEj`|o(z>pZ~nh2lS at vH96_
zvFdi3YC=>By}QG4X&Cd6>fLW=?|jLVH+*Y6E_Q7)KV7W(4AH&hnK`4WvCnL5Z2a%H
zyC}(?w}d8RgWZ4GC5<`@mg_0LANZxM&%|4l9=a*TfgR6NvMWibf{AVIC~W4L%!Ob~
znUH|djp26WuDR3w7P}w^`WB%UC;s;(=kH77Ut*>dFvYLAKQ^(%)L~ZQ+0H*<nyo%%
zKZp)1E-J~qtgvp66X3xf!`v at VWuV$G+XY^HrKYsnD~}bTrpWWAVO*I;M)|DDKd2Q_
znL?%8RQhZBG;f?MP3C%?i=o&03(w(fH~A-s>5eExp^4bbroEmNoU;vms49fD-6UHL
z^6wY-Y`r9yjnz6?Bm!C5!_JaOSzY%4HxKH4!i~Q}4+9T8ws^0-pgIrqbEhnR^>g5`
z#|@hptZ>7@!%Mz-b1>4@>2+sil;q=fmMk|$KurEAQsmAXTE5>{kW}3U5aQ^UmwKvM
zcAwuPw|3v&-4SC3K{eVKuQb{~P($#T9OP{;=z_B$Oi*8XsJ?Rp;e8cNnW$)MG|F>C
z!tRO4i;)%z=?<y8XN(@iDf}%smkpT8uJhz*u+S+Jz!>$l!H7^5IF<}jGiH4R&S+^W
z78 at 95yv-Mru>Ta)TB}N(qQrw9s)R&%amz;yozjeRm<?Zr;969*Aeni8HWP8o8HTrs
z%2ew|ZZ#bHA40}GA at cK~RytAh099%fs{|sr0eTPxqH^}c$)u4}B<w^E7s2uEXgEA5
zbP1-Cfr~P9z=(2?pCl^k(;X))LYitZQOwTIlqR!$y045lVLco<Cc1T`>9pW^V5bU6
zp#*9?w!>-z&OZ~qg<3eYSrh+<bVyJ1OpM|~H$_?Ud(_?rM&Qrb;XuT|R{w*yTq-A`
zn3xzuO#^RZ%r1NiDO$iu>*4XSm4rr`<jvx!*xOmda3YRM<ep}_pga42wjJ>BXwO1<
z5Xn}9R>gk at -F{7!XAm at 7!Z7+I2F#REQjEi&R7il{X75j<zA<?>G{bC&kr>Q@`nROz
z*Vf7~NH?9{2Du%5V#mZA5Z5{_ueA6w-S8<D_I1jlK1VpPJ3L!8Y+jm*PTlza2j#}A
zE>3Bk#9uPiI{11Jjp!~O>q>s$T6rkB(ysX|ub<j1%%s(d9B!3;oRS^~NbRf~qC7R2
z055+VS>dcJ;G&Ixx_W^?bekFy6uCjc95|}~rv-pb9o{;Sik4<=(X(*rqfC*5g9*J5
zu~{79Cr(fWdhrP#%Shzrq}1Ar5GE*Ge at N3yk2R~+voTe%B*^4wRlo^3-+DlPr=Jm3
zzv(usV=QC~gRGh$7(Zb?km$f(BKCJbM7K3GW61&z$2d?w2%Nx0#5zbgQOWuU66V-K
zF;Zl)H%5j`u>S4r>?D%`R)2k{U4*108XnJ<1c$d5xN}AYz%E*IhOoHVWEW_r*7&^-
z$I<3hRk2Jukd}K&a1so}e^X8+-u-Wxf`!Ds=eNdMqWm4n;57IVt+**mhE=IMx%t^w
zAqD9p0_8)4OcC8i6X!ny#SZ-s3j{(Q-HVo^2}tF`Ime=`+0 at CK{8ykN199tyo)(Xm
ze_)bHk}~3y?Y91nWP$m8<PagdA%%+al8T^RBvToTrcova{S#1B2%9Ru;{y&)Y|XPo
z36z0T#VLA>p^7rlviZlgJkiiUVOjW{L+;s5&<!OW33gy>xwJYUHL?VgGU01!N?;@7
zB=obr+IL`MYtj{oG at TP;y<#l)yGkssZQ=;mh`E0)lMiVq&&I`;MEUYB)e}9sqkP2A
z!y)&bTOM0P(eZJ~tPl(&(-C5TK%lYNI%^&?p&*Wn(*>~WhQua)S65fxbg*abc;tE;
zJN$1KfDrp=-rq{s(?!J!P(1k|W;6YvSOMS*1Bl+Iz}^18cjU#)TGV(qGc<3bzPH_P
zPkO}IH#yrBgSuvXQpi#;bpD8fTP^gXS;-dGSz&7P=1z*!<&jDeb?~K3*ASqJ=AkUb
z6k&Ux+giJ<#4|-T_iVP{;$gz5`~{2tc!P1Se3F5a$WfSFe`G5P$a{=TG7Wf%#8F4D
z>kI$ARF5Rgy7^g4?wP~vX#uM8gEzo;`3*n#gNa<tLYy+J6!WK$scutMnF}JAK78-j
zZ-yfogl=97+T6X}<Ke%MP>K4%Ag1ChDg2Hy%0HV^pmU*BBi&zlCw>7*<=9bLy0}Qx
z5rB*5m`aG5q<X&s-0doPQd&rDg_7*3KgF(n8RtxU5NAcmw%rqQA0Ot)S`eII2nLsW
z441g6%_zs*-L+Z4Ft8!L at QwP`=&+2w)x3Vo5D=nupl5;~q%T;CWj5U^SEd6ElwvP4
zDz~<)JebH*S40QsmK|)Ng13 at 6@{lb2edcnsnybX>Em+}<S$!ImsurRWe$dtC;x1Oj
z=_*AV{_o!}L7xh0(;I==6pzrdy~NP at iQTqs|Fm=Kjt{@)s3Inu#)r%t4F)>|&3g9J
z|NKV4C~8hjFU#DtC(6BISQC_c0G-sxm+b?(Z<9tMC}vck)`ZT6E~g)u-k`<>aBx3&
zb&fjll~dJ<?!UkLbfuI~Pp*u`<!&cZv8Y18PDH at 69&e&Z!A66(eED^vXnA*YC2e%s
zOSR_LlALdpIb8GW4O&c)Tr#%l_C4LBF|A;^1KES_(yF7iBIkKwtro*H`D)bk&KZ8g
z#G<(I)?uh$G!if62H7&G0c6=~Wp@)%l_dwG++p$$iS?+};A#uvc($o$OD0CeQTlpK
zs84(nR&)$4Rsxb~<kNa8WphO;V~ppM at 5GK~PD8sHD1!#bg9a8F(CySSh05mvY<Q4A
z0_c<N-w2zUWX6P-OR+VaLkVIAd(KQ*0}^+zr#8MAKV4Nv3Sv3<WE#t5v+E#PLZeQz
zVT$;~qrl0I<;sghUkXo4!p~OYiGDV)YARaBo}F|8MtsQ7W86EGtZM-7mjcn&Ad0ib
zSE<^k0i&8OTQxOp9Zc`wvm=TU(+)H$d;oQ|O{j|28~xhd+P|N4o`%$EHm;tgqvZru
zL~U|3j^#^ru#1+fW!@@q;LaIFv|)aHhktuxN63ddC+lbHnzilEm-(to0DZC*KqI6^
zBIX(DEAg{tleaI8 at rt=n6>29MpOvqQrybVr<roA?$}>=)HBx|W=85f96DM*fo?o3N
zy~<P5ANg=x7qk7qBdy&3a^>qCJpZfD6_{8}VMd~?e5)ol{eK0k#&@94P9nz$!DPj0
zR%(g$G5gv8L-4b*QO39tKYQ=E<gbJXR&&$u#t|#2uX2%Le$5qoP3>s@;{Ht9BPM&1
z15X(CjhM|xG?|TC`9z!yc7Q$Sia0~+RA&?*J}2WrUuniSO7fz~#F-^zB`p#@rgj6w
zixEr<`FQE-SNs(^rO5ET)kBZvzWT8`Rx5~xb?`gpWP at k<b%~Sm at 3TB2s5F$R2`1dW
zYw?PmJU)$c6)m!!d$rmWkqlC83Dbwg>qY>U^62Nfj-=ZR%(7_8g76 at 55+@e540%t}
zgz at R|a+_UxNv(s4%9efGg82$cqbH5jHk*2zstOLPmlZFJ^Fwp9T)OSeO~0+Jt)kme
zcw<($oirhA-5N_XLWGza{KfDdyzrjtPlGaxTEc;!-g|nWAYB6J*}S-Y<Q`P*ZH3)~
zYf+0iGG9}p<UlwDTdY?0CRGR9*oZu27IN##z{DU*Z^}w2)L0-uKj5t<={m~Q_-TqC
z^XN1R{0V_|B`CWwCNE-t1v%lXA^K4Kj)83CZHp5NF<3oY(=*P8WypV4*aD?IHt|f;
zn8U?mLqpR#fne!wPFO=y1s}T1zVK-|D33e9XcVczTuqc5d=(pCkNvotUFzBKD9~DX
zuJi(UA+lU-Das&bXg7Xg)l`BLNUGOy&>|oIhe>ChA1idyt_d*<J_lUjoxrRh=c~@w
znR;@U8P!#(K`Cm2oVo}yR2l4{XgGFWgadzUA*F5n at 4@4-JA^f%)SWlbq}cuMIYbVk
zmJO at R{$LcvIIk{XY at DS|0}I1;157ljt)PD|0q&FIa!;d1mQc~qN)}GMGlNCryA#hg
zD=#n>8*-@|FT!Oir~6G9YOH(m6JT)Ao5n-GGWktBk7=;CgHcOf%g|2cW(Anavfv`<
zt7?~^PKYccRQb(c1~hux_nIt-zs at C<S3fe(OD6;v)j1>vm=Kelj2(CGQI)k<Kt7x>
zy- at n(=v`pD$HJFd3_xsr7Z4-YxIcU50{Jp;7xNxw>?xfb*&GFL^IrXIP54+RzqCNK
z2!A@$Yv1K3#EC$VIbp~*hfMi{YE>JH;?AW}BhR`hBO}r|5=fUxI7Z%=$o|ahqjtRm
z3X*N~X*>%PdLY;vXnt1sg+5De2bD0rdi;isi(_TgY;*E|<&tQf=aXM0;${EuIW!FR
zD~*6diY`i%D#b?hz{gs`gEC%O5RVLaXIV9pZ2^=-K9VO|$En at aDug8jHlhaFl$TVV
zKg;o3rJoa0O3K_Ucpy;8GKx~`Yay*1>3mwa=d1DlUaw$TO$R?VKDX?&<e<Be$g3$F
zY*Kos3Epr>gc)ZFs<+a$I!tz9W)zWJ`s#12O>glezb$d(cr;COVlecigrAsBKk8W%
zyQW22kv5*`%*`~sVP<#Rrq-eOP%fvmoKx)`ed}0J=Zp#9Ry6&~{n?z@<SKDjWAO&?
zlWf|2JkkH?;;2>u4B}sj6<P4MwsDpy_sH;B7%5)?q at W}g4t%+Na1zNhwlcf!o at oF;
z_9sG_CDg%B(L=nWq6armJ{J&Eruxoz17yIUfmfYP(5HWXF at 6OUL(u)A`WbS4*EfJX
zaeqN1=AR=A4_YbONb%)56 at JwSgN+Bl2~jwHGUn_s?SKp13~$01oJveTtn5a}y4f;!
zmz^wFaY2mV*rHR<x0yGqUK+bs&DzDA8w*?#9VzUq*agZ~O-IKWCwkv?Ps%sslW36I
ztv3K5cTWYt2Z?D&ekC=$8kxvjhnf^QQ~jg`XJmrG(lsNW^oZQzX|T)<0B+)smnp!h
z3n$*%2S;(GlXYHtzG3dy^u2g(1fz|+rdG(04VLj=TFd<4of?HkCZ$=vMujq_sJbN?
zX}wWjsVr9p35YL at CN;k|B<AvT*|kmgOW+TEn4ay(P7WKC=(%i?a64|gr_rw0(eGIi
zJ#JsJ7l$(Rq`0T~>`gjTC=sCFpQ}DRqNhm1i-P=`5-b}E3>!~}=<SCy5jY_xK^sX-
zR@`ZdP&WR3P6zhdRV<$h$v3HgnLY{86aQX{U?;^{EmawVc4LrcYS5?%6lU0D%w`}f
zy=csLSefYiBMa7_vSW}k7<DVxQf)OX0Shk0GMN6 at m9j#E$+v;o80V9}ZK77tVo6g~
zy45?Wa9@;2Ze&RT?_1bhKY4XwD}0zONJfU)gadk7MO`7=e&KE5OSO<PC#e8WSV2W!
z?EXK5a&1#?Q&W{h^9)!9Is at 6se!?0@`3L)2>JW!N at zkm<X_?d~ZpX{~<__Bxy&Bj*
zLF4u5R>M*&GzEzQW*iM_v6`L+d at 7Bgu^W33o4G_>ZAop<<34J^Gh~nV>-_yMLH#Q)
z9%nu=G6)FAZOoeKU|)brBbqx_S at DF67yEg~odlv6)nCpJsjOv%j)vB5WGl3KVG4=+
zjQ&$8i!^(hc4bn at PceIq|7Rkh(dY>Foo&;~tW|@tw at f*^R)?NQqUw}4WWcT{KX0!8
zmt*Z8s5_6hWa#9x46Gn>2-p2_;Ucv62~lpjxWl;|TNm<lWW^I#?|q-ILAP(3?n_M@
zDJ*9%6i%yzu5B-HqExsFif2OC7ne!Xf*&=6q}qFLmXmOBBQ02PT5zX9nxpq+jTk6h
zefANDe4DByj}8S$kYg4u;wOzj{!xZll}6F7^)iR{UB<<R>bGQ=cV|5a<M^>b7%|9J
z17+xG+IY*iGCBY6+mL0nhyg5CeqzzxypWbZlu#5su9q5q4mg at S4eVneHXc1M+s-}u
zd3sq0$@Nz3LW_*4mgFzXzxl#pn<HPvk5l)q57XA*B5G3j9bcdN_t8^F4-Mn%vQyLN
zHsK4w*HTAW{n2+J?+m+RJq9b90P|51pA3$hlmE`y#c+S{qX#l!1dc}SDw=kziL8ps
zmt9^|NZ~YGJ!MZ5jSU4_v{$IA&4w4aa~Zdr$CGlm?o*E^a;(dchwq_l`t9B{yVaHw
zjcVNFYUHvXGz;|Add9fb>i2B89rF$1_7F={WH-!BBUSg!6MD-7@;Mk1c+2d~s0#v@
z>S?u%{a@=HQqG$45ZYvJX7wc>68C>Bkq9&<MebK|O}{T<{!G)Iykis at ltHqNIMs0$
z+4j>&;MRt$;8Z)HBp-ISLF-Jz;8%x@*TzMbYen5z6lEaS5<#2#vMd8;PMzgm%Rt1`
z`m&EW#m-7BkWeZ*pumx(Xy9Gv!3dW8cFn~OKr`pC>ZEq&KHq{1N#1MT!84agGZtv@
z$;`1L;aUg&f}clU09rPzaBABS!MEpOYtmeHKb6Cf|D!mLfCHwZn?YZ<MDqeOJv0|_
ze^#h{2IZ&>Io>Y2ogZ|aBH6O~yfs*HYjbMLulk^vUKn2Mpk+eAsAMex8m_#felUma
zxKZglpb2E4-buuHF;iW7r&f$leNN}&R`*scTRY0?VT~h4 at WRxYPP)LF5{zQSLYHK#
za3P#{Kn(CxXcDWNgUCCgue>ocQU3bqM&CIv`u-Gy5eG0eFg-oCza0C=;H(wDq<|4P
znlmNK5*qQLQXs_myYYKD*L%D3hx7fezQ@~v|DIhe_^I8~ra_A{l}YEIF7*bG+;j8F
z(ukiaDNMS}|DM!{FEo%Naj}E~omzn!c at mAn(G4sT+lceAqjsC9!MD+wI9m$mJz9wd
z(1;bS6f9ZAp?qflei>1Z?*N^tI$|0+)VM0mEnc9uZCElZp%5S%mD`WAsfiqSzGf&J
zkF7a>0QmU2!Z-!-2msdT;F_Y9kHjYE%?mAJk|wkuB3RjAmo&X5JEf$<Ms1T6Gqf_H
zs3%HpRAp%!RGEvT2CA0MdNJwumlhoHRc}}lH*ng4TymTGy|w>nRH*&e7K}%TwhD<g
z0>IqsDxpblU7zYRs`kK(jQ`%jG921dfsh!4Is!SZ=*o_1O)E|UZ*o|^_+{+`L(LjE
zKJ3QTk?W>%lNutJ49l}5p_ymYx5)U>e#ze)<G)L8Rr<6}cC91g$)}$!E}YG5s>sg@
zzFz!F1e>+qUL>X&pZ&d;GH;vcsDbY<<nKa=S1DCJPOwoUWvs1Lrgr%;crboBy>~+e
z=7+a-ZGJF_=u->NVzR#;5oq^l6>Xav1nQ=Oao|@*1)E)y&iZhkLd(1!1aN_oxrmLf
zf%|jC7neth8%3!C0}t<W)-Yf=C7Hnf`5Dcf6mGeID;7^n8qp%%y>-uvnp*v{iYi=o
z&W7#?b^UB2HxOzANq(P9;2Mah<;5h;L$Js7<L-j>m|9$Ny@@2;iDz^DDSUCG8NA`!
z3=ZVkFkqZ9u(pgi-4!e{Q`}4&QmarqFgW9WASqY2q=jk0L{i__-&1zyKRd5^-cl&)
z>v_k~W+22i$H5~VQ5IS>vUX0(dE$_Zzag?+-L~6U+dX#e0uOJEDRY&~)2)!es*y|)
z6jiO@*YjVq3pTz#hq<{ZVJnrWl&HIEc-lwpoqf?|4+k?|PS43UpTPxNyS8}x1_qdg
z<L;-ly$ZDZRLZ>!SvIi1zc?sXd3q=UP%7tzgf{Ap!p|o%L7Y<3lKwV3JOYX at 7aJyN
zP?MGm?w3<9f=kP^3YeGd$QiuD)>WND_IQE~nLr}t6164IYc^LB8>KKww-<OjM+&FT
zc<`YUC2G^f^}|I)-R1F#9IgOBNRt{b%h1p#wfhaZUDeu|{=~J}^W(7ND-Q3|^h&!+
zp?I73YN9j0E-G5%qLv=50N=!}MauG)%SMn~WMawL>fVJ<Yj0rF#{Oz3bPf4}k1`<0
z8JUrE;KAFfVVNyd|HY?Ltqep&a25mhDPCW9NmRUng*gO7p?fE(YR0}+*gVs|l20bu
zmLKveh@@tyVb<M$e+}cL75(@oX2Kz48OV)<2m1{0C2oUwP1pOa-n+yQ*O6&h16t at C
zdrD-M%Eb(A^1<i at b9>lV3tZ(^>EJ&awjp1wCp!<l7UdG|SKl*L!FArhIpI5ab^(PM
zlnhVlwyl;NDy`-fNir}tN15r$-dWgNj3Pt#UKsCcngx678iAr^zs!h<GeA1bl8{y-
z5o)G$7+9kzS^<$S3gU=HQ!>BIT5v)pDM2#G6_@^J111yxnPMkiS_h0-6Qpr2jSq!&
z#Rt>tC(0 at K#9p$+?&nA)GX-;tJ5w)Ro6 at eybq7_O>WR&+AI1d4!3;>uO}4_hs_EO)
z3EzqV4vUbDv2XpHyBUg&%`?p!V7tHvyyMbKPs#0UlC9G#A{;R3WgIYyu`QDCP$U0G
z7D?#DZ^Q2+&hxMM;$jNW5P~&ic7u$9hT$wgbb2v;PGurSN)&>b)I39 at fXQx{n3I!}
zH?(T-`fOL4DTXCUyj+nSr(U%QV5zx&6no!zL-oCEV~J5g^?1Hkf&ls3 at KE4o?y{))
z&@VIXE_d`xws9F9Uoz-=Z at j(~ursqYjF2z=NRb;nu=hn1K^We at p#q8*&B#j5YYPar
zx}tTRv#Zdvva9rej)lpcCxB!^{@~>7L&BwzqEAz??nv5ve`n5c38qs(U?<N!_${!y
zzm?&+%MUdcIaOkFvw5!@v<6L%)vxEj^dv2l1M2A^iSWRhcnHl4VNEI$<P>jO%hlq`
zUWt&lx0f2il`-k{(`xupv<3&FPGb2*pM)s*U|qNN4^XHI$Y-bMcsnq6pwt3;llWdb
zk~GSs3%dpayaNY7O^=!kTgQQdkcG&{iFDk$X4JEZ>yWs3_7qrg^9j-^5ie6Km^xev
zA&biq<doZNfmC)1(D>{bJG_raKtgj|?`gepgiaehii^+}t+nUpLfd;ov`t5&PZz_o
zYsqcJX~mVx+cRN8mly;*{LQyWi-j}1Cx(i4Z%>@{qeQ$;FK-EePTRr%Iz36pj4?N2
z$U=`Z at OO!5&%xcmG4c<Y^lZV}zm%?f%=hyzqq3woS at -;}Jr`Z!%0k&d6OKP}i*Y>_
zXVuRZ5iVxw>UusY&^9hE^iHip)yi~<S31RNs0fbKwM)psFP_bMqLsg>q_-*4rV8}d
zcCNOCwgZxLa at dW<ehR{462;!bLDoo)!}m{^dLghZ?Q{W)Unwczt>fLttd}GzTW at J^
zYR&V}8J;JF!s-?v)k%oy!OX^Iwoi*cZptgTn5Sngc;lspigxId*9jil3;Wv={XB)=
z3mo3Rjvo;-d98{9S9h;Nrfe#_AbF7iz!N$;4r5|r?R6{vbibOj0>jV?HI42>pQZgM
zOC{*Ck)-pZT&YgcluuQDjVSSluH|B8gpA9`A+_?{{B{NQ6*{$|#q2-1SB!rm<&T>Z
zYLBEy#Vy$k$DV!UW(vJ+c29Yio(?AtTAn4a)%AOLOK2j3CnVOKqjLH33F(jJEWnJk
zlxNu1AJhwgI$IZoJC6?EL`L}jM9y#8*`E^Dtf71oC{a;Rh?W1=MM at BXc5j|K<?0er
z8@~YQzhjX~cBq%n))8?N4o!JYn~N_AtNzkxG3U$Tj!PUiDW0=>WBdo5tQ8F4UJ(I}
zoLY31NBet6GIq%x=tNeZUFCaEx;KosgUdrbUBfA9`;48Z?y^N#mN97&Gu}XqbI>@I
zYnv-}nTEbMRJJ=J*H`n*SG`n`Y0=HXsLYhKRrbz4$;GNg_lGnh?@md$K9 at oSC)!TL
z!EXgGUMdgCqjnAtJ#e-(R90L=iu${+PTkW*JeuoabP<V`k{x|h#U#~thd2+Ub{N5$
zt!K<LEbZeBfrc*Xwl_T$#1cgk*@Q~TsfBed67UxD$H-YNBiak&aX`2|vybVm=;(ev
z=JtCy<2hxo$DNPyvjzdLTer-VK?+wA+pQpSr7~&5eIl_r+EW)Hi&Mv!bs8Q$dWVa=
zv{{`b+m0VR0t0g=xJ#{fj<#nCH+`g?z3<PuK37}hT{m6tB%L!a^Ku9)O^L+<B<ttw
zA|D_cyVosO-Yut4!KfeH0XzLvdR6T}z!m{ZCf)C)HKVsJCX#XzOcM?#E#g6itUhhs
z+#`1<o}?D<=D>xDnR}u8L|k`Q?<i$+9TFznUwX}=EiL^M?_1nGi!hp2rz)7^Iv=RG
zH2meOZy_%X at Fu~MQpcXBJQ7duq+J8=0cg!_>xC)^((OdJl^p{qSi(STU!nUYarT*`
zJC=WA54nF4*8->$OG)Z*t8Uipy1KXK;l7`IYz3_8F0UC)n7QHWfDGNv+12+YrI+PX
z8JZr0(bQTlgMG(#dnnIWeZ<$0ax`fLykizB_41Xq_svB*<yqOJdu*yZ7Pe+(d3bq_
z>KrbxNNjk9f=D8`$Mie`Ll1>TUIsA5X5y&sh*4XqD?6T;26Ih?JwCXdtK`_Qwj%Wp
zz_|Yag0FrLq_~d(q at 6#FFW5xh4!%~tu0P;et{wy^W=8*|{=q_%?jE3yV{kJ}jFa?m
z*%xhFCjB%k+wORVOoF)KR<=XcuaxMxuwhW!BK at A_(_a*Iaov*#i_?nM?CeWS8%J%+
zGnC2OXW^NV5h<Il((G!NaV^`&=yQvq3ZgDmw+zN=zdbfZz33Q~w9b2-LbLm|)H*TY
z(*lkVdDgwYrT at x-zvx{r4!*KSU3eT2advw{>jcN+Vzn?oRhx5M{#p05e*eNEmr!zk
zR(<uz{h)q-)rY*MmX;G|j at Xp>%T=g-P4%4f{xX-JX(F%fD&)bnj4}Pj-OD${{+ at _7
zUDfA3FA5k0`sN|uh{m7ZeoxFiK~=u?kvu>vU=kz&Oocz4lks}+^$cF#Nn6#bRAw~k
z8MS{Nxv;k!q<v0ZMAoLKGO$XhV2sArsMSnz5?9AZT*CIp^A{wHz<r!QU_$GGHW|gQ
zF_2mK>b_1N{B4xdkKq$Qdb#nYg=wMz!#xeC)F_aFQeB|=?-3~tG5*V<>@U$29KyRs
zeCiWc;j)d;?p)QkS|U_a8bH0?c=CP)COsd`JYW5uj at oLsS;#In;v at ZUI}Tb0g$C3{
zme4&dgqh=X%W-IkiIj%HM&|>g`m7q&Vo<f(zm-f{u&k#YG202cwom-{-?Om16K&8O
z=4Qo=Nm(i<t#&I-L*qP#ytpP^g>2i}x%oGnmb~;U^E+D^9`?BhEzl(92NT-9yCCsd
z0iXwW3w6OZHN+;1c6cSqtA4pZGb{_ya;|jNimBH~YSn7ztK#*bb`@(vnf*!M!{e}`
zPyfdIBdV^5$@8 at H`zD%i7831Xa%$ROlpwR$$%~FQf~LO5kAn4cQ~hP<#B&iN&pTmR
zPhGRh_C5xd at tkgzrbh7eHT~M~3FLmTvAt{2y at MuVC~|e>jW&Up+;z{i?semA7A9=C
zIeF$1vV(eJO*qRxo`gw^7k-fO`KK1KeYUFI?-FM^6Cr!zR8M$7Ig_%bm58-qOPid_
zmLQgooZ&XIU57hVQQ9v$6Z>3dAaq55DT&>^9w0@|FDzh3rgZ8e*p;}d`?SC at KJIT#
z9Lsfp$TM at Cza#eAU%4YHp7r)Yar^Fyhm9Rtk$2Dc_o4?2PE-xewd|?$$+P++&U?*Q
zr+^rw1G+&(<%6oLvkRZ3uq1`J6PhvI&Yq^O7kXGsqKT8M0G+6AG`ti(knBPg>$c0H
zre2=rnxUm*)a5K;yYmivUtqKxdh~?(QDZ45WfTAylCq>(C{ZiPv1k2R?i6XAzG{(w
z?O+*sg4(hvR0p0VE>F4YR~gq3c3uA&s;y7Z!ba=3PRV#il<+30?=|K7Xq4^LJ%?Oo
z+u+5=$;N?6Vc-4rXO~yL&bx6}x2s;x;HdMu){Re~fd`Ioxvaf{1zY>ZS<}5M??#tK
zxAsoi6FT;dk~904eadA$zl%UQ{pOL(5?bj0(*nq<PsCZP@(Py6Ij5bfwKb;@^%>9T
z at N$I*2b?^cunVtGy}x{i^c-XdDvM=5AD5tw<Lc7W7$z%-Yg=0-D%_n0Q@@`3I%Ito
z^z!|+Ei-+?tQ7&5V3npb*mp&g`tp@~A(6M(H4-2Zu=gVSSXab{LA49<F}cxBx-zE2
z`LWt88!!4|5Ey)NHUS9AoRSmWgx}<)LgdxUJd!=YqcF5M7VP at y@`^etm;4iOB3j4^
zir~>V<JaFCpYlApc)#L~Pz#)ExXXJxowOvm-n{4Eb2R@(i?~z7d^7&gIf2BINl8j8
zm*JaY=X(M76PIYA&rz3Xf%@`u5Djkg^|9*UpX7{!giN93#lf_;o{M((h^gOFoA4dy
zw;5j|DrGh3ID|MrV;bkyrW`O*fTwT>Qi@&5DVc(K2dFU>gl@;_*6yzIRc=Xw?Me-M
z_8;<><^ieXYdO}Zka$;}=~Rgz4J{33C5BPjhS_jh_-B9}w0#1p`&K3xJZu-#N_CH}
zX-&<`vCN2tPb}zn4BYWreansuExeXB6Y`9Q_q7B}t9Au7Y~%KXG{*ncqG`!yAeK>?
z%N}#;^9>$zQGz57er!~9OfS`>V`(><5sGX3*)8;QJJ0F;yS4M(;OBl;C_6UGpg(zC
zycPgUms-xVNo84{glkJ`DukWSnJv}d-<!`LsRx~E;<q{t=Xpm~q}LK*pD5=Ocm2q*
z5AQRD6`bygFiydDH&%;0bDvV%c=#5Mg5~tEwBgpjd`JW=lQFJ})K90d<O#i|ZFV|?
zF<*gSec5{{uM#w?1EvCYf059~_CsnO*xxf at HatioPP{sWq|?P7kVfV9J#l`yjVdw#
z_wn(25PERr&Snd$H0I7Ti8N6Rl32TK*pLu~hx<<&N!iCcZh<Jfn%VT-V<cRQDz9!@
zcs5kj$`hiU1?0h*_4Au?(OxAXb-M<>)%E_1^BTv=KmDdAR>}7+ at UFWQReC9d)IAfs
zWR-O%L>;@{Q6nQv=amb|!k&Q~=j<07YZQ@~L<>Ek+Ox-8xe5meAG{sxU%Q<JU*$x9
z{J;c>LM|#C5=ul$Whzo%l-n<_IS;g6R-Xo502Nh}ye*%klQ#QJ_1ZZ9#rcu$hPG+<
zQ&9o`?ubTTMU5O9NePGH4TpshM*%wJ at aC_8hpmX2Gig}|FK(H#*{6lL4#$BDz$CTB
zrM3O}X#%FA{xTN1x4}3M(-4&nTS_`L8!5~CgSDuGCv1t};r<nsMv~fEsCp~Td#lGl
z@<W$HGur0IX<l<?wdRla7sd)fqdH)u7f+4`GbYGpyEtseQ#=E8$tzQi2;(8vxq|~!
zlB(I{?Jt#r6sA;c^6QwXZ8{UNH(h?GZ*V{2x35Sr5$IVk+sxyOVeK~(iL_-a0LHb0
z_Z^z9hu{SuG1>XAs=1J58_Xhg=C5*k2WRS}HMKQ;({HLIRpRY$72ndE14Mjc)b-Q5
zrO6N+!%aOJkDHW`H%Ax4ePA%`)00Q;aSWZh*A3%%9q?1|0~Pt3`^??<3N!`D5bB~i
zOPc*=>hR|pR#r9F%wKQ6>LK$yZQg%TiuXGaT`gR1!dJKeCeVFm{=QFFOZt#`QcR3N
z>i<ux;75Gg=JcHOcs-h?*Mqm(LSjjVXH8QU7OwkQAfgo6&@TD<-c`&SkZ8!n3v-rD
znEn3h&~F=aKWNCz7#fsw)-RM6L)HA<@8n0eXzmW1<Gb_rDf>#Bz-mj24A;obenVWz
z$@_jLY(ky}Yz-L#1cAp68|XZ(7;$3s*Vv<LWC;X>tBhshLN)#Sg;V|I6+r{(a)qvW
zX#2O<v{$?(x<N#4h*g6}xr(Hp(kdcYdZE@^AV1tRbn>5r^|}M^^ea6dH~o#$UwzDu
z#N8 at uhEiKXqmio^<?NFsgie__fU(lg?L8?e<|RnC@>aX+!2nzC+f?AwiVLOD_5o_P
zmo)FEPb&D at 29a$zBUfbmCG0nL0B_G{oMA7SCdBc30NnqDotrDw!~KV?7xrEc_EXoG
zuU(tpwp-ZDiq2d+09w-0<)j@~7$MxWRl{?nP2Lp5|M at lxpPJ+L^qBF}8**YgjdV#F
zk%FUTgBJFeK;exuO$r<}wqFWm&h}1?y{!3D7PlYigTx*_0PgCGF^wuM`1ckiEl`f&
z9j3aX?e*5O(0Z9&+}U}ZCIj#);U?Vt;jzm1h9o|S?oqcfjqT}*ZxD%u;i3cN+gS%{
z5P8QM{E<Z!3Dk`;a!)QfvTQtOs%hS3-{xMlLcSU)fR(@zF*$h${WV5>QTiJNx}0T<
zGd32~c=kivQ6gCJ{9B}NOmk3!=|&|D54uC(AU7NYSyDFx0|GkW+?bI~^gjakOrwWk
z9xFf3x?gUwxT}a{PyfRg{vci#<mov(vz)(R2HFi9_E*$tl5X#n(Ow<`W!O`YTOeFt
z$u_Sp{Y%68=Qt*|V-zewO=BRNY;A`u?YFIGVMFf24E%|rc+%YTfV&1sFE at _SJzT{Y
z>K>pV`!Ki2`-|dLP|#2tapN*#!LYjmc*5SzH+*0YewD?EZV<k_>ELPpj(rc%yFX2l
zMZ;XQA4IojG*7bDW1VSO8&4kUVa|p7%nO8$lw`);reWJu7GxW+0LDZ}Ufg`I6K~L>
z%?XclT3XU5Bssv#!Yk-(irjJMt$b<t#uwZ3`<6~V^OeGsW+HHUH%v#MVf=*w&HVw_
z6FXLnyVQMLud~~!q}TT)Eeq?b4EAeshez<~5D^w^)?FIUQ(D at I&il?s#*#9v=KCfF
z>4p`?{Jcff1kk7$#&Z+Brr{pFX}`MjfX!u}>R=+uvHAAz+}uwRGxMQF7mX<9%i|wG
zyhj-cI>P;-n3y0?33E-ep1GUF-+awHO+|$3pAr&-Lu<Z60q|&us5}-Jkl5O*p3fu~
z{o#?3(|m%vla6!|itIvM!|QpHjLZYbN`@V5Jr|KtSeU+fXA(3B2wu49aA+dW)UseP
z)Dzv2gY_+KbC6p#&*(@I10%D0_%l<ZH6OEnN}r+;CfN|oZY_Cc+$JyETwf;Gp5v#)
zP2S&!tZKI|zqYoYX+)6+aT9ldpq&@&FtPX>RM{0-uSdhs(ImwfSKeCuw%1)ro|lV?
z3<+_cQ>r4fB8yDkp7%J(RR)qXbH{%?`ow&-B504CL-x-m6F~qbCI^N;OH=C)+t0h~
z!u at QUv7^t;K)F~qY+4$8h9nKhDD8!7kOh&7^w4&6b=TeBKHJ2aP^DwfGTzGIofazn
zxXk%~^GF(6?_m at bYU1KCPEdUQ)Y`wzU@;iKYfzc`|9sQ=u;U~E$*koUQ%R2e at hp>~
zo1`+ZlwB&9^4qUE{kMm>)N)J$L2l=NYSNFs)F^~gTk;S at 2p`7ZQ2JFOkDL2bU1;q0
z{Qd%<T9X*D*}(Vz1*MUuTT>w8;IzBC$j($YuS%cr+^vb~KOR6ttcvjMhO9{9B3X`R
z27b3Saqs5<P_9DF*v;(`k1k1!`T#Ofx8l8?DgPGPA);+-TF|g3dPt;wAbw&iTMa0b
zf3fnV0m&aIn2&ssUv#ZeMXZa=UQ^HT6+rXWJ5X4{Gxa=uotel2`;4 at p`$~w+)R{8~
za-tD_`VW%nXwo4KV>#_8lwI%ey|H at -e|TSQ4;XVLv>x8bND{&8 at EC0GLdWe98FJ^d
z3W5ic^!7)d at S#}@nsvysz_CooY~I&`RjbWo(JNu%UnLY+U9B=}v(WcP<-ilsj=Di0
zT0GM6AF-Qe|KzgL%{}(9Z+7?u7pQr-M^6vwux4iD6cpJw*v5X5_utiqPw4J~)mfrl
zdv1to12N3Z6w#lV_hOX(>4`IZWA`;n-P-zANF#x;x+{xF;xz;5dso}t<I2>ld~Eke
z9t6D>@&ttk?MwP67qJhRyC49~ehwC!Aa~EBy<2 at 2wV47FD~D1q$kfd$F*FAAX^Tyw
zFZ1>2ag~#@Z)a?b$=<^wS%+C{^B{%aJ1BGu!)(8h&Wva^d-lbVdE!tiQV#u(_GbSW
zop48aTGlWJ_iu_Ulwq9U6h3GFBz at 1A+ygcrqx2jjIEd*|Upl{I>~IW*L{P2CE3(_q
zeVly=Z4z?@oo*2F6qon+drV3T{)jso2+ScQGOEEB7UveOFu}^sFUM^)>8uOAL2Wf#
z9C)+p=I$@o^u25imS=Q#3AfqloeDp9<MHNz7qzXeZES4pHbSvgI*}qmf7X7%`SYM6
zGb>j-?O4!ma8a}U6M?!uuk_(F<R~7EWr|Np6#(7w=ot;2b?n}V8ILig8+ic!gvJnM
z?kMA>9W0Nsu<6~Fke1iAJ9Xb4-K67v<KT8oEvwSWA=*#=e>9zUINR?R_d988by3?_
zThvy2k5;L at Y3v$_k=T2-)l#*Jnh~Q`?Gd83Qq+vtF>8wmHIg90li%}P&voUm{E_SW
z+_~@1xz9PT_j%{C7H3k%(dLVdVvcBZ(<Oo;lF_HG+HwptbXhr2P?)UFg4_LGdUP_s
zZ4l0kl9r;a-}~_Y4ut2(hUX3xaF=WXnFm`Mppezy#j?REf;H{k>Z2e(aD4JO3e7My
z3{&n6k|UXlrY`eB4-Wddd^ZNukV+FBTdS?gl>a|^h$mX3RQ71qzXN~BpW~q(?35F`
zBBY=4_v|LGL9Ro9Pv(`Ff&qYjJY6yutFt6FYE4{TYG8X?b^=~1D<MIVDslhw(alxv
zk6n3NvQ@(WNu=7s9_W#6+|jlDI#=w^YLFanN#E at p+m0EUqxht6Nuz)7n(!eH2C*6Z
zp(2G3)@UE~EVXrWZ|dhc`GCKnR)n(t`+Yz&oSVJ%+bgjP`IpLhbF2S0`P#&h1nr}6
zcA25c1;w=<xt!n5ej(AQx_k9Tsnu(De~Ngw>QCjZ^a+Cg^a)#5(Z{lhd!IcPwU&Q5
zjk)Oa1zOKI2L@&w92|5Ma*Me at Vm4}LH$SA$_*C`~jfwzQCe!87w`y7S%h3fmUXLj~
zMhs#@o9SE0sVL&yR at E3;f71d%9EK0J2xWdtXbcAmfzah%0M1x;7POOl2INs7lv_&^
zJ3*h+flO~k at 9kRJ$#DqCq+EC4C~jzhn!ST_EH>5*dI4_RFJ@?Gj~9<3-FQ+uJXF}g
zU9|*T{S-#3*Mj_(wI0NoK|S|TrXN=KJ92Jezge|GdIf}3o(bQ{7s?A~z=ry#?<&n2
ztJus?{U?m<m8T-W36|!k1}wt!ntfE)8~6}*DP&|djNRQES$QWrV!1j{-h|p~Ym_5L
zg#=g8i8$%uA}Gx~`!YK>w-dNbe!Tk8b7w2{Dfdo5tgemY+=CwPTVZ)mV`INRNs`gp
z_G^85Td5<iny)b6Mve{f2Lb)wqm-y*?k1KPA^_65ruH}asWFrHt!tf^q_1~h9hmg_
zh$#<^lTY(5<s#2YBSYe8iEWQExQ=%wLm6CjClfxep2(3{Qf2?PiYz{pm%q;0K?HPW
zJ&na^Xx1l at vmHKvU)m4NjiU&5l)n(<6JJi^IB}Pt#g8fqQIE0sh<+m3R=72JpDeUG
zX0kkf9vYeCZ9|>%(c|Gth{#^Db;DXqP_<6$g#GDa-oL#yrPZf>19^WN_rqdn9J#B^
z*^mlfUVM>dCU0i2H&+j>u0FP?vBhPG%sxx8%_WgY>PG5yZ_c}OaswNdU7;)NxWG<x
zxi8zyP?TM$2@>|3LKI|dUX-5qcb>ib<av3|(+>8*Bj%ZWN_(+I#}Nxk>hYKRipcN~
zmBK>#<BsH{v#n90N@(5Mv38oD$eHM;!tew~{5LPs(QdYJ)UpQj;8Enkqx1Plk|)W2
z)fW<dm9ITe%@daTaq^TBx-}CGo90P5%112XpD~I(z~4s5^kc&Ni=)d8a32U%OC%fY
zmyV`aGqOSN`8%?EEBfnOXXwjxdvk=%6fe5gpRK4I4N+V9r80LvukJjuvCSODpUtwv
zgcAorp#c~f(s at vBe|sn~=yW54q-v2E)$(~>=!0r=!tUI=@)4KWl>aLJ6_0c1_#v)X
zT`^1!o!?SV_P5e5wiTZ~rBFVStO*fv+2VJv{WfP+#EIRe6*Nhvf?fMSh`4zyWcMef
zyeht`HvU}+du7A#CbQ{!maK;LHlA<pBaq1Z^IYnoE;FY3F~VGMXH5Ysru at dI;Z^}a
z*u8sG6!@p}w{F%0=Rni@&cUyJQY5(q(O|3KS#edlS`05tKFX)|sc)q?KUN69 at 8Ml5
z57X~#6I`V4m3KodejaV`_o+H>6!wI#QX~A|=khpnn=Ju3Y+*wb?ugO{0$uK&rhN3V
z+(BRHZuleK|46fK!n)^yM$Cw162PH<l~FD_9G5+jCk%OMS<Y}k`IOt`RWrXenlFw?
z1HI_vJ)%Qo|Fw0=HxWztIpn}y#r<BiM}I#vr`?S~>b03I(}tw+pGa1u5|`bog!e;K
zc;7|e!2x_Mgt8NewAU8(WA=O_woaBQoP+04Mj`1y_H>RYOEULz`Wix?X?$P at 3Q3>x
zZz|H(`F5Vdh*#R$U?IWOQSiK at ZzHuF*(8Gd$^FZ%OaHVkqN^0tfP4-J=#DUx|8Y=x
zszl7`L+-&RZ~@x^)Y7Y2(rdoE2S=kZ;SckOSv8YDMUaY>-5l^=)<~@LbsL~<M2t%F
zLDtCFnYvNNvsD^c52fAzHjm@|W1V<<N^h}hTJ&@P2saf-b5xxPux$!|qwc}9tvjS>
z6$_jveYdP4{7S*LP?XlnV-4Ec>1>a^+=5vUqF)BnZ~PMyWBS*S!!Xa#KX@*H{k92z
z^CF1#E6uk#aGdZ>cs{!P1v>uA(@e<2rE5C at t&0|ODdfg>BXEi8398)8HOWjK2)}FG
zXfj}A8LxUT)a;5A9DQ*)v0*tUdLU$3WzO|*o^ny72Ry$Tx{R<E6n2IXrM`Uch`Of4
z)1+POBlO^VXv0pp00(@0P~O0tdjvQS9!MkTbu(Gc+g>Me+Tq at Cr56Swrh9-&m6ZtG
zMp1a(`<oPEkA0_Yp0<RYK`V8>t8PTmm7^CqZp+W+tg~9#V%MTMUZ*TkY>atBUY03y
z$J=`e-9M~UVd#6rFwZ{3imV|4f^v1s!rxvXl|=;vS!Sy#$e3l7%|q0ga6Jn`sNY9O
zD0U8b=P6bGcKf at x?ET>>?bsGFC;zJFtrNf%PqV?NZbk05-_e-T7=8hJZshmc7%6q;
za9Pzm1<S4m6~PV6PY2U6+Z^16ycdZbNO|?g7FLbbk}+yTP%v_uzb at yd9E$)Bo;MM0
zRUNbW);SR}kOa{#Uv668qa at WL8CV6TL1UMtx&3Ef&d_2Nb0voYa(56Pb at CM#B?0b5
zq{hS_jJGK^my*zt(h#zX2coQW$=}DP>du?Ffv?APvW_kN9!(VC7Wb_W5zzy8gtt|&
zIa+iEzB88C^MSHDiu}ofIXYa87Hf$1Q4Ni5V4~QZT8jk6zbqVA!xi|qj5~jkruiWO
zp#Wt{^}*&JtY+%IUnijJL8ot6%5PqiE|&hEOrle{RtLKoxfm0Uv0~A%iaUqa?sZl<
zTSq;wWwC2Qfu&t3)X at jTy98k<3Mr)8kl!bN&4(VG<z9%A?YmbOE(DJ85 at djRjPd;g
zo3-D_=D~o2h0{$OVf<-qx796gzkUBI)DGjZhdH9Kv1iumg8N{d6XDL+EWATgb=t;=
zm^ecJpt_)-lbkG*`rM(YV5*>3xzI<#?1%M`_NBo4rmIEnlUTg6ONNO{urfl8vNaWX
zHH8-33dv0G+#@I=2xeKtjyvm_4fbp4CvLwIJZW$jP^zIHePT0>Hk#H`G04N1S4>f#
z5pw=u8tBw`q#(h3h^?=qo!WxF&DNJ~v*1$ya>z?dITQ2YE3%v0ZV6yOmKgw^=tOCy
z%wLDztVfnk+p?5M?v24gLp*stK(HS^m`>vV2?XRGPSqJbn)e0%RsFv(H%IyrH?#o!
z`Q~r)J8uA~Am^LEX$)_tcID<UzgI}>_+h$q|KH7cp|_mdAgUX-6C<?#Tt4(p```in
zmdn_YZ_f at z^IdSokSnh58<lIoiP|3Etw0)8EIwrU{k<zyGgyOzdk>wP0IWAF*K2Pv
z4`sn~_!cX=JhF*zIYeky8=D6IK3j9(DTBo3`+vT%gwJDqGBzi0J->OD{`jnQ!|Ka}
zYEm7K8-W7^f8+`>B|0#+t!LiJpZ5_bR}+dTd_1hNVKsw2Xy{4(j_sX@*KXE{vHn5p
z!{~Z-tm%A&%$a`Lr(zgK>t%pmm12W1Y%<p}nYJRkGThAIzwpk7BPmZQBd;pE^KsbY
zg_5jtZhxx!-v5iWM-NI>62dJ5y#FU>qUv$DbCt2e!wJeT$Xz>Vf^d3m|7zVy=L+JU
zYZ?F`5(VLX<`7h7D$jdfxUa9-HL<?_zxPa3{_eYao>hAQqX=7-IhEGmMM9-31+~TE
z9qH7BKb!kmE<6~qz?Ro@<C*Vin&_(+qPCHO&=Jljhm?|=xS_O;{fsd>uc18sUAdY0
zgcQUzXWA5-j@%*<xobVygzp$qNb?SpQgDiDjdp=h=?nT)M)A8YGy8+T#>iHs^MhXV
zzzhL=>Uo1OG{poofJvWtyU~RU^WV=d{m9)AfoL!~GK)4zOfXBM41)n)zAF`1rd)H#
zxngI{{-1a8LV-G2Dsn~X6Q%#XA8plsS!MX4x<+b(;*p2GX#f0#;uUp<tsxmsAC~36
zyRc7_9UqC>eVy`Azx5^Gmp`9atdTs44=BtX1#_h7v8#v~0$Cn>rMrG6F4oyMwu13%
zd8&oX{Fp_XISF`(pLG84-*(w5?G<!Q<0wqOv~;Ji<B3{LvNIe_mEu^RRgFDHY7w^I
z$v`QL>JwUte>WGaLXC>)jV8&ugD77u=G{dLrAo!`w4ZrKOWfn~{PpD*KU3&SqV at Nm
z#O|KcjJbG9J^n#7OHR!npkJ%a9E at IT!Q{`*tFKXxTV{lc`GhNJlTKcXYU!jb>;jGe
z(YSj<_Nk;L<aOo9zogeF3bk5~uDz^22us?{Xkcm20Pera9H9sIUH*9cr2EUN<yR+(
z_G_8a<DM$1ls^a+EI3e(og0qdO^(ia0Oh&+p9Lmi(9x;qcV4ZtsyV+73)7I6QAyX}
zVhImO_ at rK2PkObQWV&vNjGETGMm5OE-{MI+y!Bd;WM3Q!$;#QNeQl=SW%bTl->$%L
zyQZ+70U;B&=?dq<&?bQ2$#M~34g*9t4gQrYxH6pJb+4eHSv$KSy89U~u`X~^#O?sl
zr~zaNdJl5etW3367#|9T176seJPjBUu506cPj1l8?l1s69;zD$nN_>$T>7O~dA%p-
zxEK7V${bBrYGQweE6(M>ejDURwG=nQTdGIf)7~_(h&gj^s8_61m|kPd|0>}K7h7H7
z7n~Elty}tO<8)_Ci7fuXW6}w;2Hj2GSZK6h36M9fXa$RijI%2A#)0%#A1J}8jG$nx
zmhk(A*ss)0d&c<E=7Tf2wt!MTwA*pn#7upsr-{+xj~+s5t0H=VkGE&HcPK~MsAS5`
zL}B5ryMOFR6mQll^CJ=4ZQ?s-+C&!ER#j}5Rh4aFUF+yhAAMthZnfm-Zq`lNH>(GQ
zbS?VVey&IJ%KC;}ErpNt7;xRw7xp?krp34OEp&E{oM3cvvbdf+ml`GP9v41KxT6yn
zI1BOn*DfyFhG#AGP*<F7sW}$<!;BUgGk1NZKC(3*FD=;QQNMT~dvu76549<u3P&*Q
z8w(;2yFbA{`b9cJQ4ouuAQC-w&fh+^NB<N!93BjunSnJP`lD at Z*AM#WjqZ#26YhgR
z8khhDb_)G=>;$t^c$_K<_u9KA;aD6YLy*<q4!{a6cJ!XTrLj&L-=@tF$t(V=dPpb7
zhYa<6Q#w5t?<V-zirtwo?Ao>?ki=Oz?tR6&zSu}VPcDuNcld9DI>^yCM<Mdd<}dNM
zI4JE%?pAk}R*J{g5kv#tcen~cxI+}1eit`+i0#pV`z*qlo=&-6>Y*SsUcz!{joFRu
zJC)dAa~54z^&u7`CceeiSMSik599aince{aKsg0zc`#{aR+*Ve3>&g)_6Jb6xKZ`H
zHit=0z}(i-r|&Fq{-*7{a6y at zJzi1cmQ8!O<e+s?=-)r+<U8qUM^oXm%T4>#f_)A{
zmp8(0{={?E>1U)pMvyfcsC^!<$Ct3lSpB*-1h2iKqSemVuysG>-rw}WoLw#DyhwpK
z5Jw=af)X()_Qh&8MCPluS=2Vm@(-lfO2eD9gQm;sq>=I|1OR;eFQKw1t#4evX0$>0
zQ^N-qX{cN8v*R29^-TGKmKuOX)XKaJ>9Sun2kYe+0m6wKNbwhoNYn#=_J2`|pK5=t
z at eL^g%En_IzMruYGZ3x_Yl?!r(Gq6as7-qPYxQ4k_uGxHZjBo4wuQ!JoaAQx(naNQ
z)IOg1&zA399ty5ZnNpdi{mHyS%g5<6J%b>{kCI-HkurS}rVo9J at eivqt$6CKn|bir
z-9Ovt_voMiHSR{gw`<c*rAo(06^ZnaQuc=|tbn*g$3N$&H4oQ3EHiLHWV0(a_l9yU
z16|>--a37D*}q35aJ$aTTFw_i`IGSql?$gIiF?ARJ;bby9muza-j=FGN_tv)cFEJw
z6Y;~ef};FbdYSV(9G?WN_=Hu>^mdWSo+J<fwo659>t2^P at 16cSIqVTAo7JuUla>dP
z`0$?&H at L2$VYr8n+HWoMXWb~dSlEp&L%$UyL3x-e^VCFe-wOAX+th5lTj$drZtgD+
z6qlc5AXlE=p0Z5n>B+Tmkq(tEoWLAIG>VN2jH?K4WvQ8#Rikf<Lmu`Xy=J96{_x%o
zYbahMm+Nn^2yRDY>X}aS!&=gba%Wp`Mo(gB<)|E+yq^O7X#sazz$eYXrM0a%6w7P#
z|IY#le;DIp&n+bCz^B&jPet}4!{Ykg{SSM3o>J>9%<H^v at kh)^yOM%^)G``-=i35F
zR}(y-?Fn?!2*IZjw-)80?pQExs;tS<v_gt9z;nNNx{1Y%b!0Pn#0xXYI?2EQ0L<k-
zIL;Ph=(A7&FDLjN&mOwm$QG)zOt!oF^s4ClFlh5VX5(X9XRSLw`R`_r0RN}f!+yz!
zoHASsd<?Ss(5zaon$4pecQj6s<}NT^m8J0$X80p7P+x$ktgx*ink`Wh*UJttRloMD
zd3?S82X>`oRIv!}{hwwj^+zeUJ`Bd*uogZ+ at aUUATLElDFjda)>r`X{Vj*%)gY|#z
z)v at 1Y`&*wfu{ty>E{gM{^vvvZ^6FA{DeiX5?tcXS7Q?L&SuU(9<rVEXBS)RyN>hZA
z4&tNk5n_<yS}iD3{ong~o at wqWB`ez$;VC#B0K%(>1W+z03U&mE>{kDEDX#oT4=@Hm
zx!-QuQ%2T1x_!c=$XCVYXbaM(^l@|~gbhxde($(fjWy0z=-FNjL at x&Y{<W<oP~qOt
zeXTc{n?7B6W4fKE9Ct%hVYt}Bwq)`r(jb!Xapi%tTTG18mcg2*qC+QLV%}TAATijx
zZG<o<0M$=70cn<bC_5bNy+p9xOU$5zl^IzTrQa)k!Vwo2@@po}^nrn~K72uBToVi3
zW2VbJ&!C4Q|5{Z}=zV9F{%i71B2EW-D{>);-mzsCgl&4e)#Gz5X*PqPOBC-E_IB_x
zixa3rQIgw at v$mn*6<ngb^DHp3`^8xC15Nf_uEP_Nr*-`&0}{hP%Nvc6_TDvGfh~bS
z95cW03(B)MW6U9Op_IPgj at qMs-)A{tu;q4TJ$KJ6uFDBc-OIlQLB4JubZQp6E;m$s
zOIQ9<UG?aH|NhFdg*>>3XOTrN4 at oS1f^1|-)Nv(9t~E8y+J$y4O$NJFxJ#aY&5HFd
zA8Km$Cq9qCG0T{2b~k3QB;@`>Ui#&&{=QYUb2Y13;v+O^7Q!nV(X}48yf$Z=0mDm~
zw<yzW@%`{rTKTm|0#CNe>i at wA&NR!aXh60^R7j`ydrW#JiA0y1Pud8Cz|6sZ#go>~
zx6iXyLnBYF1FIMQYsJ4KN+T#sHgk0A!&j4xrS(ag+Q?divc_IfqWsgJvWfMtZr|o%
zvTYe&+2f>M3`fvs(<U$-aAZhFMN3>Us_5S7qiO_ZEt3K-skeGQ2e2E-$*vEOb4QqA
zN+V^)FAx_`Ja94?zav?C*=l#N27_z^RzawPC^8fZVMlVSgu?bar4343MpekAcH(D?
zDx0`dqtWFcj?1XL1J_0ha`7{n2G!*fme!-uck|iJk5kqL$v$aGvA2X&%a<hF2p}lc
z+-o>H9ki-0i;-=`An?tjpC(6Y&_%d$TXuziG#H(g*3$?83z93FZ;MH@(hY9-Tn0`Y
zHH?VA`fbr*scN_JCjGT%GyPfo#iF)V#j*C$#N1$qyUM!y+=ZyXQQgs4E`U)Cdi!2&
z6Dj~|R!%wV!!c(36OHTkF4Y2>^`rH;14kWrJ$m=~FRH7K&N<&sDFb at R^$Lrr{_?x+
zZ*tRbQ2QmW2hACa$bB1>oeQN{@nE|E&tv`4-lvHmvRs{?^?KLSm;Am{DUn&-H!k7I
z2AgxEYTutyHOZq~HPf{F*;&$z-A1LKI9<Qj!r<Hw*65dpO$Dl$j0~4}cfJNr`Tv)i
z=MW)a9~c at pcp*Oo6|VpEAl{kqGkohFqxSHy-o1dPAmU<-pCZF at thWYJ(2>HjW3HLB
zg4`z3c73qecR1mr><_lGmrcQ4Yos{v^B%V4h!~T?+j$+N+a#OP8UBUXKf1PmcXVie
zrrAhK69$+Dbz$;Dr=R2w-#?aX-$QA!uU(<^CQx-oIpqF at 7GLPp2$lZA_XOYg8?wxK
zcH-j-k{ol3(g$PwyixSjF^mE+?LPuve8BdCmD_rvdKD^n`QmlsQ$~W?Q`nLZ5=Hid
zIMv)!ix+u&(QxbFgZo>cm;vC6!6$1u%|Y+cD`A&vajQ?Ru=LXg>{f7@|LUVs1>e{{
zie7t{r||3C at 6XBwQ|LUl5-fGAK2?`VV4<D#j{LLhcvte&DT84tRCUPvwzb!wMB4>!
z-?z`ov5G}3l<?TXR<?hjPAGAW!0tH1<7Nhk2+C;OyKNgun$MA2 at ur}xv#x~t`dsMU
z_`H?kiqZiJmS=_LHF+ixyhFQ%%q_|^8tj}wD``2%hM*?d=mG)|a at L*5wGk0MB+Q{G
zQ%-~$_s$@7L!qg;6Jd}8wJ*7alF{9{I2s)O{A7;e)P4F?B8#3B6Jts**pNtR>h^+F
zn){<d1B2=xNk}TcP(DtYr-kv)JlWo at Z?oc)36B;OwO#FAxOFO4q$t^kp?Q?aB~194
zvbdMLpK at 38`sv=~y_a1UU3wpP{F*|C<cwy#(U0agY!l<n-0H`FUmHk|EclE7XX1=f
z(gBF^S at YmQ!Us93+{CVoG$<lmfBiG1zURo}BA}My_(Z%t;f<B6y^Y0 at MS!)>pn1fM
zj|$i#5X=57l&7nDm!fh~n3hCU$DF0j(x&BTIwz^0nah<CY7L*UW8I&4BoXxY{pNi&
z5<mERfMZQ56E=N4ZUmX7IO{A3CGodMB3McYy87<_tI-C4Oa5q^552FepUZ}B`20al
zZdIAQh24^SFYsv+?!Z>P(+2RSk at H5ZkNbeY(S6D<ktrqV5*I?$wjfjA8EeQBGw+!7
z_}Q)xxMnBka)_Mu{~%Ny|B{LO!%TsSCRbErl*r4zzY-paDMo(r!gISbKzIEg^N!jA
zp9Q~`iM>6z7N4}q%m(}W!Q!{p^y?gU8j!w(R4>Yt{Pg(0M^H!l94#m91>y%ay+h
zW0;0peWfgdo0#~-d&=md<e(c*f9ofsv-t0f at NyfxP7z7aP(NK@)KCA?U}d%w{fvnt
z?fc4^u88#-ew?>8#^%cdXK5(+sjg~@Ung@{<n>>Fj;5caj@&z8S=bS0m@#<%Q0CwR
zt=7U5wbZ9USzjH3zYR=SWM$<Rg`eEb_!v;3(P-SOC$IkVXQC!>m%XNq8Q#*~6Gg4J
z5H`HN&gf9{rx-gk;Cx at 8Q65&v8l3adqvGaLzSb%w3vd#G^hgT!ySjf>nE~d=>jhv$
zunha&V>^Z&XZN2}qGDTb6hH6Nq=`?8_Z}5pm4iOjk8Vx{W#$Sb2iADYg$$353d{@I
zL{|iBKcdloxEe~oX#OD5DW%Rh*C{M#p~smu_T at dw@|l>Je9QSLl=OO)K0za6HEU=%
z<BOlA6g^aLwMdg8sg+~(r^Pj+3W`i%os)sf)41gy)pASNozg}7%fEMLd<THy4e~ZQ
zPy0_T>_8r%WV?vtcX^#n!wW<MwegFpfEHooo-afrljqOJpCrKrJC&X{<K1-EQe@?Q
z-gFH)J)=*P^*(%60xF4hGw^zEUaG%Q`+|4x?$tzWDhuH6#v^DY7<cej?K<E5%5T%G
zk3w5^&HBoIWs^G%3X95}W%F)oVwB<|9#D&NVl!%_6Nd1ARZY0*?}~96qN&aQbI8#x
zwwpnXP6-~;xl5U|^BA2ggD`1l7nK7siOspRq`hL&vi{HR-OS;~%Hb+Tp1XOy0w%?B
z^euLR- at kf%E5lkweA at j<c;VYLn)t3*xk9O)r_aZ-=m$`(YFazrgoWolz*!R<o0;|!
zVceTu!Oiz8mvLUqWb{2deN~~j5$4MiISu6M>THS|4w~~4`WCMLPWTgi$4Ma2lvlSX
zz<bb71D9o>^BC)k*pI_iIl`k_(sA=emEU-FtqQJSC+AaMS49aYn|i%yYxKKa?B8Wt
z0^AqH(OSh!Qz>)^?F9))6vkkNq;Wnr8QuScOkUoD&NHq$<z(3A6iF(+cs at L~IA6RG
zeF9VB^lTW2i4av}BeoGXSEP*s;y+FJK2(sR2-UcUSLNyd8ZmP^ySRKFJ?sw)x#Y%T
z-6b`Faz=l?-VQ5rcyNQ$<JwdD+j at KCZIvU7NRkO6`*~v(qjVF)c8gc-MP_J{^yhay
zWDY{b^V8a%(LrU$QUmd9B(1GSXSbJ4#=_Wbk<q-aIGI!QGWj~!az{_-<-ewLaFvb-
z?dK;+&5vwX`tTWYk#1kw^6su{WU&RJmn}E;O1XTAqXI^}`F;*}N)aO-d`<xoxdSQ4
zUuRVQ{e^W$nU`n#mnnH7T;mX#Su3lJT6C}XoRH|!TgRH`hJ~arG4I~RfB#;5)=4|R
zl at 9w!-+U+pFT6e9$~d=ZRBe;>{S9YH&Jc>SLYR*?P}~O6mQE6y$l#PQjGrqf7&RDQ
z>lKpdvtS?U_(&X}h>kzJ)$^oKy`t&F>3|z6I5ZhkB4;$5G7zLG-NSvW?Fn|}8iey=
zz4PDx<wO#|vu`qRn$pTG#L1c>(g9&VH53x%7J~k?$5b at LrG8se@>p!?x2 at 8fTw2Sx
zTweY+F<;TZuzxgR7dE_B%#)rG7_tK?EOb)bV)Ip2NebL<Q8K<fJ!PpMrB}IZjr?0U
z9~gAWcbO1r>yb<oo-*rvwqRx(if0tb$t_ at hdINn=KQYvlKoP|b=<O}o7GQ(Fl>iTR
z6m}8UOSU$%SZ>QL%;raHV(rr|FDxPlRFoHr=UwYN5yNWjQELc*O<T{7KEz(4W0m`z
z8{4h9ah9u~t9}%T!yT>k_39rDx4IFP+5q->t6u4=5C5dJeB*(J=4y&$Jjocscbd?D
zeix*C32>%t^<>C5pG at sEu<JKQhOgaeBhO}UwNyXJ=TrW&r$?*_g=fY1@#k)Uwp$Ro
zv%m#h1jhF*Gi8V+31OQ<@zIXl?O4B26nimkG`Tc)A!#09F at pfTNPH(N6^?&d7*eu7
zVcnoI_;5D&1%U|R`maK_q|qcwbHpxzk5UBZ`s<$HFS60)CUWf%)A!BNvt6O;DFWyJ
zwC;*v<$s#}_jh?ht3szhl*0b<b3|f!j&<5^0B8CQnaSUi@@(m;&ZPOGp;uLYO=jYg
zik6zzAp<g2jH=M^alG(et(%WLykA^G{tBi6ePpLg|7lf>4=G}3v(TLt4r|uUu=L0d
zTndhY%Iw#M?bF-xA}1+Vz64p?G~&PwWi{TH+>Z>~FF)d at m_7a8TPz1fm928>ynHDM
zyY at EXBUWbVKhgo8P*vsXmcc=k=d!(G-Y+gr2bUkOl%dYD%-<DFOTHqF1ejO^80Bc=
z9uD0UXfj97?tNur<1PdHYz6$;&2rT)=!vRwo_35mY at P`wPYK at ehMFt>D7Z*tXYF at 9
z8?-vNKjF+15~*u#)O(Y&GQJ?&gI9`<89Kk*Z3m^=Y^4=9S2xApxPL|M?tizn9>QK5
zJ>1at(5@=a#^k!`sgI~ns*|%%pPv~Tap5183^kPP+~-gEUV1C#pNK?F;1RbkhjQS`
z(<_6&Z>=ib`|q>lR_;+Yxw at S==N`yPP2DrOuxe>#NB(8^<7}s*CFrPxX+-mQe5hu-
zSQIbSF>VeyDOhTiPut-L$MLC5t}RA;KsY9*&F#n$c8k;1R2eGMKjx+n9*idtm(3~=
zRWMktIq}(xW$R9^uY-HtiF5H9Pv~NLNOxQ)bsqm#tB_TUD3$=tXb3r;5Bc6c=@Ov5
zOu8T*pVcf)_V0HTTNV~-=7yM;8b~&V?`F<bT`$+JnV&pqj|(A<8&5fI;RgddYv5!h
zo4KXwy at pcrP#w{>LmMf}8cdH)-j8Yd(#wAn``ai-2rePXoiy7K0z)Jcn;OHxIyhTR
zvaMY|;%v^6V>bRk!NTu!$B;72WBgyq(wV<i61hKPYF~OvA>c(hz5m9c>d~1sXjG+a
zZQe?LdcOkUuiI}B;NKQuW})0(XjWA$+J2sKwj^WVF3k#Nx(n{h0(BO5Dk2K)+DQc-
zHm%jb{d-Ej7YzYS*CC!<CQX1Du(Zm<06>{71T&;^LStqdZpLNXS>{SE>L9dx?m+Dp
z$JZ@&8c}rZksBsu)6;O3i-O#3sm9RV%tQ!&YI&z(2Il6s;fSlTl<$}r8(~;BgG|ko
zP4qWh8*%U at UtG7nF=6 at y>nHz;{H|~?K$lsF`^xYTJ#}bPW`<`i_%vua$|zLlSH0N6
zXiQ!&3ZkuM!Yu$3(L`m{iES6(VSYtVJ4pM^q$6wfhACd$Ii~lhGAZBJsLH&twUttd
zu~45zpMN#-1ddssKtL(=T~z7A|D6&udk>aP3&l5`$SM5^`&)J5T{4CU_(tUiEX4-N
zc;%~~&;)r_DDCmx>Wl;5W>wg$J;g^^JgdyJEDq8iefv8E1597vcItB#W3EIEKl}Qt
zvN&%fZv#HJ))il at lIpk~To5lmWcagWXs7M<qL9h`;)&O#-$t_{)7OS*fAGNKHrrG#
zPmvZXBs6k5=pBVq5pF9W+2BJ=VEQ_ZgW6H3_bsZ$mL{!>#&FcvhH(e!38#R3rlKkB
zwE@#1vsbtPlY|f(Mh<ZPfM2y`dvyT3<RGXVy_z4X4o4XlKOQMD(JPUtGH3Lc*Q-j`
z(JS$l%BGvDNQ;WN(U?6q(!!fs##CNDai$w(UGYhya9}RnVyNd&zhCu+Po0sZLcBVe
zynNYyvA2J*_dfga^bTF4mGBf+N=tBr_krFc!A46uvvi#VUXvnci*i#pw?->!sLi;~
z^BEUKltY~{9BoMXG#aBQ-vo(Ig*6+OPMAA4j|E9vv at aP}oC4J5!laeX$-Pu+=U1-`
zP;-UlXV`|6iA_%K6aClv==69WQ1r7TkjoC8zdU5BLXa-zfgVW0Ou(#B0oPMm(U6Ih
z%o3S$nKtDIM^Ab*PP$B*$>k6a{36DDivTlD;uC%m_6=4e*P+kzM!qcL0xV+)ppp=H
z0kG;jDoDW0eMgevVen?fm$?z-$(E(C6l+4`8*QAv2|l|Rn31i|o2|R$hRAj^6{JQQ
zSCpX at cMsdGT@<sb{p&AG5G<Gf7%uZW$@87Usyk#zbgO2KBvfAtCd>ft+mV2Jdp*-B
zH=S~8WZ1%wNyqbLmyWy{mC9v5?r>|GFLy0Q`2_ at 3OMdB4i96NpK?ONVT)dNBYu?Hg
zBqYDjE}TaHOQcxQ{-7-q(pKMkkN=NK^2R{ov();YRX@!+x^CKw`}r(}rBQ1ApA*?&
zoP&l6JCOVlk_kSpYt9a|BF8~Dp0rC_m)iczc~F;RqqTVW^ZCDTQoj)- at Xl+Er2d=+
z1^IVn%6+!N)ejEN><d&B&>-M2fN5H*PV-Bz>$%dP8Jy~yK0RCO8JhpxK7VhkXrlMv
zJG^hR=35xA|8wU)jO^@b!IO2;8CrMi$k%62DRAil{gtov{ba1vSMvKXm2t^3*?v|w
z>6i@#aUEd)EGboup<>-gI-CA`zi-`}?MIy_y`U@>fjfr#<Os^!1r?@jqr+d#<V#2G
zn;?KT)pviOz&a|`-A>O7EWxZxWc@;UReLXJrVxmrOkL*wQ(ZU)lvk$$UBC}lOlkL=
zRt9xYW0L>9YT;}EmdrN5%Lt%}##aGj*8cU<%X#GXF&EiM=HA?kr65Jh-sr$$qsV0B
zW+>%IS)W=Xe>O)nHLB*q>Eb&3ZSOOPGaR8!NiqHg6f?(Pe><cdWpkDrN5_Hjnn#Uz
z3Qv<+gO1noUe4N_Kt at E0LDLhXaMlrv(mQY|>(lP4p=IburrzGQo74{8ItiLR<H1UU
zKw1VGPl!ZG!Ox~TmdM#gdw!=VGobvNpI`yXG%afrRek`|bGC=5rP;S{i)L7EUA7gT
z1eE`9>g#x3G<*_~I-pLDh!h?liB}EqCNAIjJo>oKN`aI(EB8m)lT)IT?^h6@^8w-7
zTTf<%rx8pF8sAueCBwvG_(sk17SDq#k?9zn>WcjDX?duvSh)5Di%JxS+I7Df+kX+&
zt at cdOsBndEe%ctrv?;ZF4HLJWAYWi2<v!1K99bM{xIl5w`1UM|0$OdHK;taFxJR%n
zH86HIVDYoWl`Wr6Hu?J=+OEY?pn1h=zwX6`^l-cLFu(6wM#ozu7P3DT-Om!GlJoGH
zuICb(_wM9!nX%^E)-<If&K3JA+5k(7FRq<lYLbVIR01d89_QzI*C5f>oh0snn$w7{
zd6$Yu<o{kULa{_&BgpT*Vd`*#{K?C?_)zljzMI5-^>rmm(!WPUL){%EI$l2tjrEg<
zNoh00{Q*S2{qGO(9r{*sxU#ON)OJ%y`qk(Ba=R94{sNlcZvV{~Dkd;ocNzAot@}@H
z#!FTxBxAPjwLfKUJUZ)8-Y@!BG7zY-(B3}$cJQ+tzu}GO%DA`vAs;+-7Ug?ZNkKUj
zgstGsG+25H7hqOpPQ%#Xcja7&lL1((dx<5I+?9N8eb*9{2m(&%$g>9Ana2 at WnTfL^
zOf+~B*<nG~=zG-afe)}^9#`$mL>2)bZWHUT<K*hr-22C+9v7{h>N?YXHXHfL#G0V7
zqMK=nshMyEmJAsG>F6ZpE>Ap^Uq)iz3j|OrEh|@S9sc}UpvKB?wl!-#wT}x#MD+;W
zr at 1V%&iEM>p5GP|K9yB{kRW4PLDwZ4e7L^ZwQQZoa%Y>6q*3^o71I^->(A!d>Rdd<
z_a|Xw);drwg-W|<!7v~Tz@*btumAfS at 1r~L3 at SL+#gdDpWkr(xG&hH}W)naW8PX*r
zS+cek!WQK^ZNseIdeM&@n9JHtA9Yb-gwp=UAKleqn>gM219};t9wDCfP*0358cy{|
z|0_nx+=#MBy&&hFez2F at e<Prh`{}<ZRE5nD_yn$G8}RgpSbBXw=gTO+Yc3$eH!}`%
zZ(A2do<)v^@!-Bb<dYU`>{&sso{6U=0}|LJm`3+;xGFi!E^+NZx+*E$`hMYrx72K)
z`8RUh8%;;eWqlP1-i4T=TR^4>>=3Do_%CSg)M at NpH~r|I*o0>PSAS<siaz;?nZ)7F
zx6w_*vsGI-T33aPF_8J|=Ua94=8&<m^f=Z25fCUnlb1X4KY4O}nHt(U5KX6WOY8l2
zT46RlR<RU~ZkKj7A*ii!OY at W)W56I~;=>Y$Q2<2mgJhJ*^|$l#nlU_#y?+DPZ*}*r
zd8@&W;B$b#q&gXT=%f3F_ivccau??+!1S-~Zc8%zu at 0X#XH6Z#CC+dkB9k6)=qKIV
zAF+K(4`w- at NPfHdOJ!ef<U%Y0RFNasswTJdFw@?5$fL=sQbnO8CsZ0JnMstW^M3YT
z-o5sac)nn}wOiUV_mBxEF=XHW%ML^}2zXq>D8S&Wf4+z2igxclSt9<+nJ;Kc-N(yh
z=}K}Y(S)!u_HIuaqvOeMU-vwr$ewOj3KyoZrrk{H=J>Rx+0&z8%<^m2+O9Hg=N_>o
zWjSJU=Hjwr at VgI@wA3C^x~s&MUUvfdUIDJ(kW_+D@!y4F<FI32<&SFT<3p8Z`hW||
zK*RTfFzdr}6PCgJQT-2vb?DGf<rPJrljl9(fos)40%qMs$S+g;#k#EbUEf|bNr<)E
z)_57p(icUb0Qph9BL9|NQuU4M&tklkZeR7gb4?7|6a5Xbvdh!cp}=`PF#)bYbrEJe
zD#)QHO;ddR*Tv&pE1>bL!EcraphiUz=k^dG)xXWew5scwR|}jZ;KpEOifxf3GwmIK
zhrrV5QlIwjNDmkayActc*Y6(fulg|k?>S)mJ$BOJN+si<cZpxqOd;FHxw6J11GgV4
zN#EoNHs4=Bmw%y!k{CH8tFKOD$1npIdZr-~dw;{8OSJM{>3WFf?M5{31sYAj+!z<`
zM$)1}JRfT!Shr2o!y^SMzFunM at 3Q$^=02e^-N at Hhq#<%{4&N*mhx{Q|Cwf7uNASTA
zN-Yot?ih1;ep!fM39A-|*2(XFYOoZRk-q*n-FWZfrIzzVrZrrxn8(<HFICHENNule
z>+_)YjUs;Q?(B!i+gShIKX>oSi|hY~&1SylW77FKPuKae>ISF%+N;6U`m$n36~7-R
zwSwECN7E08mzo^ZdybzasecC_;x0uiv_s6Pn~8({E;2LXkNYKb=O$&ckAJHT4u at mR
zpYW3bS)b=9o9zA!ft+;YKDc%wUYeH`)$3r?CJK$M&+Q>4I@}pfc|N4dD6PV#A~7RP
z^Y>J_+72L+ at o6qQZ$|pV+V<{~;#mHmU-I{Bq>Rz$OA#KOO?eY|2~IwOe_f&D)~`m*
zT~yB;rRyGSbL74h8YVq`S&JBv(hIPRRoGS6=dQ8?ee34D>`O*lGx+H7KCx*H15EU4
zlX04UXOrnvQ8tS$A$oC^CVX6S6>C-;w^0qGS0WNGG^>vm1vK+sUD@|v#`t|-WV7%O
zjV!WkFN0|!G3xuOgFdngGk- at RxTF%dhF1CT&G<QdxkeA=*SvMs&@b>BCi8sA?c>-E
zzn=yKVqjw+DO~{H!5O}qW1d=9ZP#3R04~_8)AZX+c4Va`_+balM%?{jvi{}@{h{TG
zzwcRS+uy(2Fb~1)?RiN5-fY>If+hNs56_fY=mY(+gN;4mhd%-kq;a>?P&mu^B6TAR
z9BtYvQ at u02WH@DMq5v9o165R<hLx<?+eIzT&#~#7diwjFB}?o`Vp)>{{IPv{2_?Q$
zJ9?0P#qXN>oT>Cr(n+M&xmN#|6_$2M%E9_+81<PNTa=5qS!<*v2$?(P^|QvxqT0>8
z40AHd0#j_pkIm73cw4R|SMk=%)9s<V*zEfp)j#&n3sF>?HzPTd7k6*>_ at i(EG-s7@
z3mo{SiQj+fyzjfS(O#pg#RZ|Ra(ns0)CA&LK8^?1ne at I^iHh-fHW2u|sG6~l_H+N5
zw^6D6S6BPYPup_TiPxE$MgKnwFgEWk`44a1Qr)vA&rB;RYx?k52~CSytF^3ZplEr_
zZ+K*XgISwka*Y0kwumM~G32U92Ru!SE%yq@&QvSZm4quO at 4ty!Yc5f}0TUfxd6xaM
zbkM!Op|A4#Q8q7QioOmN!%qV4>l?EKpRruuX-zEwcISzwT3e5CDF9Z`${WXTYTWzo
zHEasTeh%BZCi08YEwq7|eLpvc#hl^yuFhIBFtz9G?07EC^g>(9 at thM)k>@sz1X1iv
z&7~zNuBGGL*iMvSnVr~IZZ24ER^cX1&$_Ay@}&d{;SA#{bF)|D;5x%XN at 4_<3F{aO
zk~b-SY$nJk#ZZ_<eV7Pe4J=OE!S|`<C8N*tu^|-&7{8J<fgS%jw?;Qs>$BHf3+yhJ
zo3HIo4_sl2(^F272CW$?;|lv>KQPmY<s=zAr4MpU&d4=}M40Wj;p;5>E$7-pOs3XA
z$A@|3*C0z1y;2FfnvT+$rSsQ41K#9b69ZTG`ck&M3ypod7Vbt)RA9u}6aN?sJfX&J
z2IgwEMbYh(N)243V2a;-A!}RLyTi;W>TJpj%3j*B1e+K3gF$53v^ZR2`GP^kG|<b;
zv-321Z at 4_<9F6D*t}MlP6}c6Ex5U}+Be!VuYWHU#8a7qHmvOynk*xFa8imy%Rn-`9
zM9 at hDP{Ix0B0tjiek4<P(nCfPI@)0PimY!n0 at N!M<ihq~Ls=Ktw-5Hg*!2TpJ*v>T
zc0%1!I5s>Xl+ToHVT?4BJCPT at 29Qdh!H+_@%9|HaON~(DNKL!Ti#%*tU;!n0K1g6V
zo^$7NiS(g_{X+}CHt|WE;3NE~rbWY#{cVLv`~wJG4R*0<X{>6%I7#tTk9 at Mr?<yYg
zY%5#puAk&>0d(s}`!PiBBnL2%_Vc+vVdB5EKUW62^3Wm?=~rbXxG#jRcbk4+J!0{i
zL)jBP`^iT2*7qewL`+NGr6skaD|*UZcH3WEy{1APN*W7(n$~~xwm)VxdMl;zMNtk4
zQz+?=ioR~MgxMW`z9#=~Hr0INpgy(hPy7284x#HFK-)}i=YYv03=*gr3Ir&npDSG?
zE)VGQWpP{p6aw5+y7OJQUJVT6cRTqbM})HSQXgtoKUdHTXgl|{<zrg-XSp6E7u84m
z%(;LiKHqonj3ueAKi*HrWWKF53 at N_w>q;Pu^Wj7a)ZJG}wbHiH&1}k22agsG_c_Sc
z-?g18nl>`gF*8HCNRBV at d17!xm8lEUIr$^!_J8MVE#zMnA*8iWoJ!AUirF5(LRPi#
zeKUBdd#HTGo}3bKl111f>_^}d`Lzs{ZzE!Kn{D|t8c`t;ezqivALWyPDKw7vX9P4F
zzbdsoskRL&Dum{B6wEBy>|mEq%LDAlk8ChXW&7d#Q2EQ%z{!@g4qH-&T?I<fbT2c(
zA9u#rVoOfBIO`Y13_>qoT at ubnEk~;s_}Mbhap(C4JbQ$<<!Dc3Cr{;PRfP;l-rKEu
zW4(Uq@^4FvLXwL&q+oM}O#fX)Sjs%`7)lhy)}2ZvOqs)_EecVlRkjo7+z{DOAYcOH
zmtefo6VQSw>1gKc0zM=;1zT~2djUYDGm_;EQ<b8oRi=`xNs=eWkaqG#e~U!&S!v#6
zoM at O9=}}~{j0!V$cvRcMBfcSg?>6ksA}S`sqbzchrTyQ6oUmtD5k<yjI70xr5ezWc
z<q&{ELR$6trWE<CCz(^h2E~^_sXB~G)NJ?mC%O^`Yw$yMN%)1PT-3?PWr at KK2*1b`
zZjls at vvRY&G^`;{V9RBo<)(t!$dZ=eHAfp8*i7X4fnW=MPX!x!e)w|nY;GdNXRG4u
zz)q={5>6EMFXJvwVe>6vkP?Zl^zq{_OQEEcxzbTL at 8C)ec-i1jpS$a2jg#ej7;=*+
zW+;J;RfNrLdb3=H{&DZoz)Sgwn7{K`48}ovSH;6W-^5WlRGI6n9sD$WE<QWZLd_It
z#S>=~8YLBFtwGRQE(l3~&k22+?Xw1sSL at _|4^F}43Q%=dK0lCXU5Y|qcX&QsX{`3e
zD46N(1gf4^6zl%R*FiG|z;x*W9DM!2p(+}FN91FmdF(26z~@~*O8NG&iMkd9Xs%fE
zkow=rNtRy1p><I8)={vUBmDYi=vh4C3Fh?pr;ol(VQ;pfbnr2#1yGiUMBhzfn}Mnf
zxrL?+5#{q)q019%j`Ef at Ggd>BUduu3Wq13dGb8qaaKLAk6F{>;rTAuL8Hbn&OS?gi
z)GFuOfKPO<$t)36z^i3m+h7O6mBXOBft2Uf85xF-(?lGBj$%*^^(u^7j8zSm5bVGa
zWbtgBQa=qZT6;8F0k?MRc;n(j3MZ4?J5iO9wn%0C4~>kavB*$dOFE;gbX$qSNdNJ6
z-6!P;lCaH$Hw;(hhfgK?ogVVEUsMG8hx=F~+y2F~t|j3wFV+;Y&9RokkFptRFd^jI
z?dQ0R<Jqig<#5vX06s^YO-IogTGM|IWwIk#UOvU at CJ8leEFXLei$C`m`UEVjD{pt)
znG`IaR&W!dnuAq0lut^*Xr)+|Ch^#pQVRXYf3m89sS0QRreq{T*MngyOW(|OMoOiZ
zbc8MX{Z?MswNg$ju^NY+P2HNbs%kKPRguOy=dUVKU1*x9YQ#lZ3`dDQBKeECWi`To
zWuPNKCHUpO4Vw$8TMnPDGxA7Bj}pluBXQU1=94hZrAXHR9E3b1TH|V#yxD_oS(Gh=
z_gl1_FDbN0;xMR)S27~)g>iYdsG8+4D~o8Wkj>t$sVtl6$kWm$$+GF9jTc8NbT&1)
z6GJs&FOyUd#e(}0l?rQh1kuRvgBTO}z`gjEgzWOh7S<6aN;$6!$S%E~L#J8p*ECsW
zW>ytA^@hGt2H;YbU6PvI*8^?w4$lv9*GbCVcbD!cWUvdj=`pdJ_>`)rMKc15IZmI_
z9@<Fn at Ox_&WnecGYO(j@@*^a=VZ5i6zCMyhA*&VG?Z;^Rf!5Hvv$eh5=E|Oasfqe2
z-RAA`BrX+O*~f{Go91z=fwb9kxPSw2QF2yp1LfA!*=cvh2<T3W7zTPfElKhyyrfi1
zuhbU(zITh_rT8=HwOt{tq*>v1*H~S_8KbNI|IVAW at 0Bk`es}KFBJ~rS&DK~Gq6tJ|
z+yzg7H6T(Q#XOPQw|0<y62&2AoR~RaZ**=i_NIdC`B&oBNk at Q_ZrS%6UZoTK(>!p4
z2$iHb4l|R@`huqzs|Y^iJ?DYNm>*~`1)5 at X)S4^!r6}PrKR^G;MD>+|j;O)}C?>hx
zU3`KfC;S3VlwhOyRh?u at e6wAnzZO&zr02Wzj9%UBSAC`F-pwS~OgZrh-1H&*-z>bq
zBYEX<!pH2tl)$sNZ>eSM%v0qikDuBy>+}aSS%8i=CiH~UjT_CU&PO47?u=C>q?U-#
z^3)`yY6;jUriwJCsfn|`A-f6mgq1O_C^wk!N-4OyX2YR)0A`c$NWxz<%*Mbj$QqQG
zXNa3FovT2YRtZT>xROu!mQfQ1N~NWoDm6>%j^SRXCN}L8W1oDtOaZ2TE1H*Dk>ssq
z)4=Bx at RRt!-Fr5?!?vcvvcgRY>LSL@@$cBoq{_$ZD{iT+h-gbL7OB?XfvTMQhL?3t
zp3hN-><8#A?r_+&H}g&Lg<MX_G&Yr2SSFhfl?Qa3eGiFpZ+R|PKvOzzDPqwJQmK4I
z_cK8e8vVcAuNmB5{vB4+kw5x3+e0_dZ^e|<1vIV5-p9FFR=qxYU%kwZ`JHtnKM!;7
zNMV{vJv-A8-CoFon7Pe|>|h?@i~EyYn=4&fT1yYW-wCOrI~bZR{PsYq+d at a>qP9-j
zptdh=n_A@}F*o=O5WaE1*U)%k%4K_ at p5bZkzqk9qO{n-t<-`sjdA>pP1Ivvcj{!|h
zQ9cJ*tY(e2Q*O$r3$JHYOyiUjLrZlXx7hKW!8X*aGYf(#=DPTli?(zNSbNeQsIwzQ
z at Y|THHpgcv2jTS=0aIpWuPciERxvf$ljD-=J>v0i%--9!jTHn73tGmI_p`(DJ?)FR
z0x?xxywG)hnPmyDV`OT}8kkOkqdHKG at V2f~EwAuc<W0cCrIE*Uf3z5n;P<*x`!+y4
znI(g)QJO`fa%;cn36%`uvrmf?vV_JXPH0W(jyg^7BaUu&wKYMFmaekwZtm_CnG)mK
zVaTE}wCnSC&T8#5U;3lF?+J~A%!jdGqzo>CLEYzVqup<4yH#GIZYFZ^hx&zOsyT$G
zZ*>vZT2B at McB{z3&r$o&+39KebERHVIsk8CI30n;iq*NAGX=A6oux;wJv#Lr)-al$
zQ=>xG-4xShfWwBfA1&u45-C+kil7-sUZwgGtMFQ(xW>42r4H0skOirxZg!jcQl9q3
zJS`1j5UwTK=J!hG4C&H(P)8qx(Syl)8#m6>luyeS(AdfG&{gjYu4m2-4H-9954!Q2
z2^d$EyE*fi6{VH$z+?+HH?pa?Itz#j^DXUxniEx}4HM;Vre&`iTg)fQcqd{l`Sh{J
z1X9b%FHJXsJ{AS%lVS<`zI=YT+%T_HTB97U2Dh4NXjK at me~h#1EE0s3C*lzelpy?Q
znWVZOF=>kLW7I<+cT8KW4;m{%_7i0M9hXoK?34?4U~w(Ra)nEya!QwA19-1>6AV*k
zYF060R>7|B-IS<O_Q)>6mJe$;u1}1<c=+P_E^uU3Tl(g_H540R(HNpym0~_8 at 2w^p
zu@(&ThyW<S+*8cUr`hDaLp1TH{pHdK{JI6FnRAd?hQ|M)=_;e5>c6fCf;33SAT1yu
zFysua3?U#bEjdF<cQXP?Hw>*b(j!QRbeA;JAzjk--e;}%|Ah}T7Z!8p-1FOKpMCb}
znJiu!Ez!`l1b~S~92bro`2HQ at rmlNBz2Ry*-P>U|@8h5PGQ|hn{U0R_I%P^Vp*rYd
z_V2~C1~1Nfzhp_?9<fZO&wH=*$qUha7<ah83-}8^C6&0lozP!sD2Fz_9(p;xyh&js
zIW_Ly`aLsq!lvmeZn1Gjdw0q*>Zhu8;r!J4aH03ZnTV_X)bA^N#N<qC(Yx=6-%ux=
z5sCTVt}UYnK|vEG8bFuweVP84(n~iWZ&kFO2-&|H*>(;1 at cb5cPze9tNWo4X+10kW
zlRg)(#YBk--mz!2G8ybn##WB at PPjHVQBEq^n`{quqokWZHv5BVEvuKinr%v`qA?U%
zUleT_n9?;h_^iq}2+s$53Om at nuGAG?_(|O{+>}}u-W(HD1(L*^@NaFM68WShJ>{TA
zI_x4R-LFprXVw at s7o?>y-{Qu|y)QWM%JMUw1>A(-nCg^An(e?|8yj&3s at -0f>224k
zHxx4qV{0n<6w?g5PP&Hgb{O at D?*Xhd;V5eOvi5 at Blki$h<6~O<ioeGI>;}a-wIb0I
znTlp9z56OH7wrPS*emifuD|eo4(T(T=meG0nct1;4-rT-57hu%S&hDmkSzrd6~&~1
zL}tK&fw!^{Ao@^@$k!?^xtMu--FLBhec0+N|8N`Q at O@IE;Kc`D{k!9!Dw`kBxt%G&
z58RV>7e6M8ZK`yO-FB?+t}arp3m>ju-i-v@=<e^kTz`M~2ig}zG|ZOR){Ezu3~sro
zP^m~9Uq(ybPqLj2i&vlxv<azHwujw}(z8aVYp-eVMm}uUyfxQ;`7&zpDxdcbUetOo
z)mm5~{t&-85ipq!=*_j~px5`rtz{E;wFf|bx|vx;8CCCpI%RuZIsQ8&<z9Bl|5~xx
zaYs at 6<y*gh-yceB-+$ai9X6FtB&0V?7FpNp7Ejsjj#adLn<%m7pL=gv_4|bB!YcKk
zP~G9 at ylvdq|89*nI8CKySDS}Qqj`2}c%tGj>7?NE1BSWC at P?R{BB=-Tm;0O6*1~|R
zo{QgmcH74l68U8|Mgv`MqIBekJ{p~Ny%}<UKR=O18IhmX)0+3(FCahQdh5eZ%ENVW
znnBD?;lsR#TL~NC93c;tOBoUI#%y(g%a+H#v7wmXzUxmUs*ENbwclGFhL-C<yjzwg
z_9jLC&2<HF>Dyek?>0C)<vrXzT(@NTUhk%<+-p~~-oGubFLUsF at PT-I`+m2gAmR{H
zV>Re{ocUpUwNXgo`u4+){44SDiv5iD`PJk3KOeN;OEs4wTF$B&jP|TYOKrunOQx)>
zw+3GAek##d<t?e!wW=?f(ezOOP4DQhXLNN8Qi|FP2b;Z&pedypRHI$2>r!`ixmWzk
zzbw?otR^7MLJ{#Oyhgk>0NcHMjei+IOiTHzF*!C6>f>DHn4ZXml;-+3JEmZ%7z4s!
z at R^+9H^VvKGg?)~1_>eI5MMEbjzjJs_{o!7m+};*vo9zTs8q5Y`=6-sIRgU&U`Axe
z6*9N9^eSV#w9%P8YL+0_3F?t2Qa!VvDnzkR)QJci&X!Bd&wRcZgJ+)gLW4b_#9o^p
zK_Pay2ks;w&W~<p5M8pH={vJ596H?EvgjT*U+1QreljgQE!ZVI<0u#+tXya@@tc_}
z+8FGQvqr>K2)NRoW>@&1qqEC6`3#%AYf^KD&bpfS>X-0~rs!1c&l=NI3TP<>ytLhX
zKtj7hgrO_|XsVc2M~{u#)c^LCoUo`>EBrI+TMN)m?|)AG241vkP%HGRRPUKUBEL`C
zDd<~6P*#Fj3P~l`&9#)L`5%|+a}A~?Cu?Gs#u}$}uFnJR4J0P%tpY at KzE9{}RDO1C
ziEr4a6diXVJP%7#M%dKq at 3_tZ!&7Oh#F8B&3!JnyJVM#3HB$7Tk3Yh9qC&6lqA4fp
zv2&}qCQE9sK|=+n$SPf4V&?8Y(fUIT*vPTh@&hG0fWqhao3YnM(y!6V<?+znoyqSZ
zZ`L-inQ=t*Z9y$DwKQQj>uMmy68gEwhR}|<&4DEEKjmpduPqB_zYbY}0;|R>%0J#L
zn}AfPY(#8JlxS79Y=r3m)K+4Z-)B*BZ1HWf<ePCt*`#yvyobBn%{7}*^JVm6z4*ky
z!_~u-OJ>|THjB`_{TYNurQ3WcS)*|BjS;mS4DDqCF3}!>YZA(v^CZ7KYsg&9F)B+2
z3T#>eBRVzpGUNBHOOrM&qb7ooN=x9gqU%F*k5{rFl{EYC*T{CYgs|W6rlVi at wp|_3
z^yx%!17)%IFsIpyJOEHHhpBd02yoi)?VMfflV`SNK0}ux`8>^aLb`U5?IvXk3uE3I
zJ-V+<V*Bqw{;E*&(ibMR>C#hcZ_+4ageKYcpRxjRN{5u0zD)hL)$(eOc<XO-Kv+9h
z$y@%@)j at Kfb&^}~yk!qF{vC?bROJbX75d)&*UYClRbnu7aEhYz8Tlw0DKQ-gW*pWj
z<3yO=0XQC5;cCl9m#twJbl49oai0+-&U&da#F4Xn>`XZ_q9o6?5mPKFA2#KKbQL%^
zt4^%XbUk<vR}_bnGanh(X0O~Go-O;WdgY&bksmlx?)|?UV9}M#@{eI;?^1#iU;57Z
zzFt)zad}86G6=>u>eHB={|BG<^y~Uxo0{<hI}Kll!=pXpGMzM)7qqK1O|gdyC=dfV
z#eeKnL(H~;l&9*u3k2=K2y2-jO_U&1YaUpCGMBD09oZ<-=PCHxRlqpHU2*(=(GXAq
zG<xgOH*K|}|Fk@@KMQfaIrr|A)wdR;w-NWQYxJHku8I5k^~dqTzk)f#>}mKqz{rR0
z3Y$Az1lf1rW6nex&E)7bm)LAYwp<|*XA4#Jp*IuAz&=l{r{1MHFL{2!XCxzgSX9`v
zC*kD6<^io7<h*DaKw{uAwdlw2a6eH+Q%f8<J~x*Ci`>>qL1JJqQik4^#qi&tnH}7g
zgJmF#%9lM@%bigq^GkJ)-MUrm{uVz+{sNzNgTl%M8bZ78Q$vhI5b?Ua<NxL`Yl_g?
z>s6;jRS)<Q9YpxIey|wYJ5ra6tRX8013TnGXp^&pB&;)>MBVpNv5_)gV>fQp+J}Z8
zp^03rbgfihjOHYNdzwWCWi)=3I5xb8wGnnVycg1OO^xXTk>{@7GQ4z<Y7B at O`6Vfx
z^?ZV at m~w0D?S^2uCZ7+=7DD&MyA*Yo(*z91aGk%}r%HDp$IV^a6mzHSihKnrN{nG|
zj?{ZE1#W$}&@Qp&R6e0;8UE1)0JzQlM1}=p1NTPfKE%%1x8C_0ljo=&w;f*qM9X#D
zwa;AxvnKLJmP^nbbU^xr?~I&KwRH;q6Yw0mUU(Wg7kRUvAeAvxR1~n2VJz;m;!#bL
z_u9^``%empO4x^0l%=fSBwFIN0 at TGQNakxhvs?s0-9kX8G>V)%m>W`j-~6AxfqU?{
zFp at jFCufY*T7GEXs?uBnta2~mpG`xDG#Vefz0*SWmp;uDnA(b+0 at nB8%lDhhN!u`v
zMEqIFTshuC=PVs=Dzu;tC_yI8m`hRQEW(=qMg$t(ZS}3K4pIS)L7um639HF%>C1mc
zh8oC)C;m06F=v>Owh(tcQC3t|N<)8kjcuZ;`;Z|vz)g$EskraVqulsMr*LA-gpUL7
z{4R at AvVD$csl!#g91J<3e54>B_gffl26k+-;{;6&QiDRE;Wry*XUt0gWHzn08-(RL
zksbqrilqqkq{xLzjOooeL*fu{4WL3fig<E0v8|OmR`h5#TA^_>XUwYfETnJqOCl?K
z^MG`raRpWDJ4d at l%eEOi;fQXZ;&{s!1I$mb4D^~D^eo?!(S1T&&Htc5Lg1Df{;B<j
z*xOox&Y^86x(EW2KzLb1?hM10dt(_O_Rx80%9VkS{(>O^FI_vntqg6S#e(-`gt+XJ
zY$FP+cqs9sV7ao at Gv-5APK4x^1+&@Rfpg}Av at B4j0-<YgX1(dxW;9b4*%DNHQ#r`F
zmHOPuRHvUPGV`0^gmJ6ktJ{X at Mi6m8?e3TApHUz at Y;5t7^7qb^151d4 at iVa`B{{&1
zz>&QvMfbG2wY4>w=j~S3tWC^IOdR8E<HK&E;m%9{JvNJlI5#MFh#uJ^M{j#F(?5ps
z2L`Xu^(~?)gl=Uz6N`(+$2F>jXdSi2`j(mLyB$m6X{wjKZ<1bM%8mOHN=HFcN%_>y
z4=as7B}!qcVhY0F67(wQnT4XbbPA5uwEN=Bprl$>=45gY<q-?BETM-hvTm(~wj5E-
zGoMD+UY~JkF5R~5shF9(<@-oWVN0*zWA at Vx>Uu8*ucZzuWQmo<@|SO|04X58kIPtI
zcw=f}nj<e)9Cb%G6?!acM}i;cwRrte-;NMib}tq8&qMIz1J&nLHSK*yVsXKB+Vt~G
z`sjD(lct$(&!3oujt}$PEI1DKbND1eF0L;iuJ(~2^$JDdT(@^jQ1NDC2bHh96zdsm
zr-un<TU&YNn{zDiou;g27%-@|@<uNw(0R^wn4r<8;?zTAnhFwJuZNj_CDr76blv9K
z*%!6}Zw7inv@?cSD%gD3&e%0txZnemk?=jCj>pH7Hrj#LI^VU`^6L(C8CCn!T6+r8
z^6b>@qvAda=l*j^kW7|aRg^G;BS$*taG~!@yG#NDLk<|ex0|Smf at XcXb0$=i+FQZG
zd6%NdUv^ZPV#8(Ifwgzs_rsyZ_u|7iEdR2|vUyxT`VmiI*Wdr at Hy9MSlDs#9NHh36
z*wbcgYv#$(Sh?^nkSD1|XZP*K3kj5J9xojEm$swP2n-Mx!04q3^ek<q<(Ob*dbN^8
zoS=i)Y(uNxk;oBhnDW|Maipj`5gUnGn$?np#Jcayv?bW4MMIwOHn~rw!65>b|CQ_j
zJ{Rb>VLABwj;kBE7d7?5R6(zxUJ1X<(#=fP|CY)SM|=i>3jUSmUJi4pX%{QA4Kem*
z53u{@EmFU!iep8y4zsGE!n^ttEmd)iFyCTYPrauey`m}BnA$zV^Rh<n9D6pMOSmf`
zh at VTfVsNpQaHh7=QpZTpS$QktGVf!hVs}HRM|d(Zps%#5nH}M;dj=QkPn(v;qS$5!
z#{_x^%ALwcO%Nao%VIQdCk^13t0n%NqPKK;`vPvC-1EscWn{GiwX>D>5=xZy904wh
z-Gr6+4|884?8CPtceO9;UG26j`ES;1HYHZYT>YLs5x6B9{;eifzH~^{PB=k=gAB5%
zN%L+tj*~H8Vrd0qvNn}qz0 at +BF$4%bd)^PKG!v;;l}g^dKu!W)p#gRd9exK8&v0l^
z1_l+-HP-0~6L`qurg at 5xsbg8h*2GROCu1_Q<)bE74bQ|APPORq(1h<PlbT$4%{GmL
z22>82b=jJGNiX5(;&zkD0=^A}8xy|Ryl;9h at -vMl*3!sha)VftzTes<R-NhA%<n&@
zZ$K41*at!xVx}MKx-&-6NH7drT)OC`m{#ua7p}?3$DfS*s|pj;kSPfXmSbw({T;n(
zNo+i)cQmR@?vJMKS%}U(K6Vt<0{Q~G(;W at elr2!Qc5c+Pkalk!EW-=j6)h+Xt#uc`
zLAD#I7&P<lOMAb%WZ0{C-6c9w1CpJBs<0=RDeGphA8)%i%Be)%;cDE#a^wEfeMM at T
z4zJSr`1o`+oZQS7zvah&$fyvqhV#Y~YMTH@=8)VZIfM6lFGLA$8u(v)O;cS6Q2!uX
zX13ybUxi}c<|<I0ZJDVu84AfvO7yh+5MJuXzg)XYZEZR%JWA^5STMb-s1aAp_cxc7
zAOBZoKHpO?$BWo}B`OdOrZeViShixEIr3f1bNe4lNfNH21&L|3WS!U%+`|Q2DN+&9
zfQ1ZqU~}<nciu=A6*>WlK~>C%J<hLob4eqVP<!5|udL)A?G0nAg{S+O>{$WAyqZCV
zq;~NvW2)g#Gsnlix<_rQ`7%DjviV#fkP4*C^%*MZM4VN7WOttYH6m04W5lIv at 2hs3
zI2FMojEwI8X#tcpc>kydKV;8}NaZf2&vGBC;A?yOrsn^n-(WatQd8)SezlwN8LF(v
z^NH>6U}fDfW|NbR at bu=jnX#nkU{HP{M}$G~PIVR4e?e#$iXV>KaQ9Hlxo3+&nM`S>
zhW=V)Deb6gR#YO(?FM{Snx!=gE^oPW;Bi$T#(oC$IZI<cTJP(P{beTMjNY<6UAhoQ
z-XKkprcLUPLf0MLgf~uD(Ks>?Xa`y?OYZON%Hnv>@FLwzt$taJJ}4VR{{kwtXAU3T
zzc9s+IF#8!y3v=`n~^DL9HwfUyN8&OVNVTXi#3||nQP4KRnB at LvZ;mJT_2eH-)l;@
zUF1$EQ-~re77lxM!?<xNZ_u!=k!9}qOnk`M9!`fdS+v+iknI#TK at Qmnchb_(+IB=~
z%!*?jdq>utEj0<>WVI&@X40G!4RjXXn27ub20kp<Iyk&5RL$gyq|4=ucGu>j05pn1
zSy%r(l)DjL`-g|SRXq$70RH&PJ at _ki(Za-P!E~#K)bl|qs3^BPF)*JSjS(BP<SA~P
za3|!EJ>~>~Y0;avw_q5ZuYox%$<)SIxho7Rrtx=Xoa=wz-{0$F4%$6d7{h2uX*cc{
zNx!zF8+s}c@#~JLU`@<?*<)zL{3v|Qf$y-Ch7*ygiYU|RT%KRE#QU1b1c at 08zd{wK
z_9-V(4F0{0)k)#fr_`tf!xSwvXeEdV2CF`HA1e0DtHLX$U)t#DYOX8CS|*~C*&`0_
zpbR2X>9#f*nauW4C?(0(fRyn;a##-8;mtA4tZ0(YZ&!u>4>vU2NR<_Wa%&}<MvU)Z
zb@#f|cEyGEoKB-*f|~K&vxeHAKizK5_oFNqfxCn6O^A&NY at yE-_i|Qg7 at vFCyBoC=
zcDucF`cv<M06PK^<|p%NTDFd;efVwRgkEk-rS<b-aqdAx;G`D05<T5Q<w$sYECxD=
zfz5?56g7z&f_scv5N6mN0;YsxWL<J|?$z}6FF<|STeOb at 3NoK_rP7e2g+gWWK@d#H
z)Ql%L=VKH3el4N#UgcKjb7Z(313r}9E>U^;-5H-ooHzqu1!X%#Z*;L at 7vmFid6&@)
zOgu=K$Iw-v`YbdoBz%D!$o$%(Cz{Hq%5#r!aTXc6^C9D%R7~q4!0Kg~P2E?@u+yme
z3&YKC2kWspoc8x3FCK^BH=S>1%m+D at QCxgks+ia&mpZ(1-i-K0XS_7{##`maMWV%B
zw)#2wbTWwP at CDao+%vA?oDouw8P0!*Q52`MgjOoBsT>k;-^6R&R5bt7p~CO7Agm3D
zxPXQfLKGNH#cQYwt)n(Q-sl}efe}9pc}0ZHft2?ub;xnur`~X9Zx(I)n{y4ngu7}O
znG;Jy!1*qrFV9hJhUF7u%JMYhAmdOXQ^_mZ41w?i2tJqCtfGt7+>^nAUzHAcEE~gG
z2C6A~VTpR@%^dG+eFpTgFV6T#UL56<rMjo6J_n at Hx(~d?ULPM>zo;(N=^9Z!15X9U
za&_9pFa1G5F9?tQ_D2DYN)0S6a&#Vb>{s+?Q;bhdSX4y%9C5 at AjIngpBhqw*gIGiO
zrm3@|B)nP6&JvDC>JL8G2>T!I#jQ*Er|hk*`mJ46X=Jvl9%Bms`IqVr0Rhcwp<?^2
zGrQO!f<%zkAz_8$%`;<zEF5fxneW{rYiIF(PNGxB)5UNdQSjz9F#EFJmjI~pXo<oA
z(&@w7!&~9^Hti3*(}!!uts`4rx>+kRE14pP7d?#yATcrj+q&yJf73vaUd>ll50pk4
zVmL#+ at y`@cs at cJ4&h}#3DM$G}mP-xZUl|=<@a=C&g(8N8?!x at pF?A8}n>&B?x?NdY
zOdWa6JD*~cE at PJ2#CRb_tOH!TqV=wCj+m?neS%1W9F>3*bR|djKWYR*A)9{`K`Q#>
zsqWD`j7OL<m<m(w)Q(d&LjQfz2C95#y;rLURW-%Y5oSB7bc`QcA<fQ!1>fAwTYVSm
zJLUU^VneKKJ7%SzN0iP!2hFN8>7SnsxBR?8dD>UOyB{r`+R4{&(;>nFC1P*6fm-Iz
z#|vIW0Z_QO$QCY)9H#M4={vO)<@DI4Ze_U1-5L#-fo)x-w?B`@Db<Knylg!Ls00(f
zx?Qn)VLvJ8$)5W9S;vw~s4IXl^ymT#4rTfadP44YGFF<Y4j5}WGH86J1<6$_&TsC1
zHRd)M2oHQcdE6{ulac=2dhHFNx6j8t?}4ZCz>|LZrtENkDc`jEMXxL9th^bQ-g at O%
z!3%{Xl2-&fUeIRckx6684NOg(3^_!>UTnbj6Zv5$R5FxKx$5n!o=j;sQF=<!F938B
zM4Y%Jxhcand1IQjmF-yn3i)tLh(wpFwZxJ7!EmYfFMO*bs;3|0lN1{r{(VeXKV3Zy
z;HY3p+5nqXaQ|l1P!V<`BiMPh9-+=eSHfR5cX)w+cRg!Y0O&P^(jKSBT=@(0MHhHV
z4sD##9$mX_S)DXAGjO;mqAcb0GyE?aevsz-GDE at 8{@R+F8u!b~*rSFOrVidAe<|9x
zE+fSW?{YTzM;3{(JQ)H4q6sDIceGSZMI29#?oi^tGp^4~huH&_k*6f)uG8*)cw#Me
z?>u{t_zGzgv(bS1UG6pKsx)8k(^BFiAR#po?>~YD&EJp0pz#X%&ykFpoKIan9nKdk
z?a!Mfq<Gye(K7P1S3>3XQa`i1Oy;yW=8ZILnqc+sL>-JhYFTP0u4sPH>{<Q-cL~Q)
zEe*_Km9ueutl~(~VvdfmjJwNVFqcZ-niZboQqp>MLeFQm>$h>Y<K<zIj*zgg!q2&L
zSS5-f^U1mtYo3~Y7ZS2aPc=tAhY7cOdfwX#u<jv4XcfkgP(jYa*Cpo1E)um_Qot{;
zL{yw+How31=iV9qTz^67gu|~7SDA_FK{!12sZf!^&(z{Fu!OOp^(9kgJLBt+TUgWS
zmcC!0fRmJZVfzJFN9J&+r^EH`LN>24BD80D)_vd<Sf#kNHU~V|U1`;_G$5;~U}_If
z at l=qKDc+%h*|V5{aEVLsj8*bK+3^j#clPEnAZTrJ&5yzQtuCT)`%~bwJ}>T>u0v8M
z&C+X}_}*8GBxH}B_xb$siB}3)93fcveZT2&zxm*`i9!JGQB&cIPaEv^iil(m=hHud
z5O=1<GMNi%kEvb>D7~nD$u~(a9;@2dKtt8+>YyR at N~o^+_{!xs%f;i12Tc&NOMl%5
zZj%8rA*}PYB2!S}B6{}9J*HVCHk%E<`j#8mB!hnOlt1Ui<%(G$ypE6>zvY(On8h`t
z2>0Nkiu7C6dE?C;3hzS3+`NNX4(4=Qx_LiGV;V#oA<Ow*A^dT!^Mai+nyiwPS~Iiz
z!bC9IImn;)@v~OCjZuR#o%R~b=bywQX(laP1Rq+bNprOrp5G5$37dS2`<h_GxFVz&
zxQWa(`f``0wf7aRklT&PNau1*3{}<C3neXzRLcKFIO!>Vp2)r-K1Xxhaw>jwlZ8*`
z$q*lzb0Y1i&K8t2-LUj!M|x57hhh`X1#C{Zyftrf#*3e0H49N__51*fJnwmBqgXL$
zapFGB8nPH8X&{Pd`M~v*KQ*p4*w9J%WPqdjf-WK?fy`mvA~udxvo)qCIxr4{Gs`JY
zX{PT*8{#=(|G0O|i%|>dPc>M^2+4GN96xsSsc>!{!L8TOP0L<jmb&(17}YL#;unO3
zD!kETW~;uP)IJI$YJ~idWopuqkoskvaA$4EEX~^EId|-j)Un at IQ%1C~ubQ4qNEuJK
z!UV?msy2*G59uKPIzJeG*Mj8sKC&gd9dy+dFDySix^-5r|7b^SA7+PN_aHh=B+G}6
zuTk6X6=;NgeGECR{p#<ZWm-E>y2~HR<QGE at Zf$hJ10hP1*+P#F$#&I^(})T|WY9AL
zVG^H8_kmQd?I8CYmDg)&&T0U3+5PEBq}iPo&7TQ-!JV4JSibD7)Ig8S at 8lhnBsCbX
zI%$lh?YS4Wqt;KZsR~45ia0c%O(BLOMN}TM(^<mWQs<5_6hG3{2ldTcz=JWBhVx%!
zOBZlI>)4e3H%@K25^DJ-iBtMjn{p2rZ=i at oMk@E4cyDpU$Uk^Nt%R4bj`G!<wK-&{
zRXzm&RVV<5lbIZyG7q~xKPF~U(%Gc0u8+ at 7DE>(62g~6E|GheS at F@lFD5!NPn9#m~
zB-ldML}Rz5Nj`xEvaOwA^q~5qjM4VDTc6i@|4QYOa%QI{V$hPndQ;h4+uAQy^er~W
z)SqGcExvGDso%sU+7FDaP|?$>C>&fKGxjWVRB3#nQm}u;yC5H#Ax77ACd;WaLWarX
z at 4>*k4nmVMP^5_C7<=T+T$5b*5hmJq6kWZmlnqBB$s>CO%vGe at Y82%svwMX4v)?wv
z5z}MZ!l~m2hTZy_2S0<oR`uR?Nj{cjQCK at Z^=SO_OMRK9y#pmzu*a*S)-UuH at 0r+~
zdua1L2chzfjE};NA|eBUnG{g{S3G at Xb{MTYea?qIXmQX8P^drgQUB7rMZ6I*dpm3^
z6cjV<D?IS_${c>@^^uQJI-Hcv0Q_>@uh+?vOyS^5qGYXkl8_)4iok at wsNE@Nq8q&_
z<A{SSl(dch1;PrwzryJPp~}uq1uB&*0W>WU7w44a<Qn{UZ=$c)4loRX<C1xZcBBcx
zzCa0n0rMrsH at +|>CLadetS`{NkB$sY?jkPCs%3#cR^AA~^Y9!>Ss^mBo+z=JD3*O6
z3XNav(tkNum1k10Cfn3 at hTx7v2<^`LN<rm0L$d0Sl34S<EJzlGL+g+}<5HTU;1S82
zJ^g>biB;Fu+u;q-!%C=fh>T<|4c5<pq1$EPsD1^rmQPa1P-GaN1O!eg+Ly?hXTf0o
zTrdz<p`J-G<@B3L6(jmF>Z=)L5T_^{Tf8<;hCjD+NX0xgeVUXA^YJhlOGp!f@~Jn5
zfcI{fLkE2MO&1xgr+TeIDrR}ccI*NEDN@`#n6Nc>nw149n00FxOgYR0qK1585RvCb
z at tgh-jhLn0W@n2XnoJcanE0!JeL<6nQ^9inbopzi*gBJPpas_l_;9r%s3$fvkj8J-
zbG`_yCR>>zoymyA5d%G=)eU~5G2N7cD=c<V`{Gt_f>B&2vcQ?h+F<W<yz1YYwpFbW
zOnZ*@Cuod32Qf|Ax#u@{j*@>3C&b|Y7N~sKQ<J;ylB4$H4^<#fWI!zKkvZUT1;(~O
zlAbKaAoceZcVkvR3b^I?2Ef54Ul=E3=rpqGLUHq~a?wuA#mvS?-xpcWGguyT2Y(`<
zCC!UVOSu#HOMfb<*!YhoL2ezZeYQ6mrSe#EF=h4xoI at jeYNR{V)9{^T9kN|xT=&F|
zHAm0~Nn<^A&3cey-udmqm0%_(u9hv`9X@?Rzb3G-BBZh)!>H7gsmeIrobDOl@*x!J
z*}`vCH)RCc{cIv-Jqk>8O;G}DIJIkzEOqhqJ&i`T=*Lb_-im<QPR&T$mwjO;98jCU
zLfl~*a3I4pqMu`V at CCKCVWy|YH at 7PT?_xSy)blO(xTSiIphU_y@;u^=q!D4%pSGY*
zVM|G<9`2;x&AQp?k38Vl_2R+w#2g@!=S_JQu{*Jg{8x_Amz6GDgjmE7-edtDN0%GG
z=qFN~pr2e+!8#Yb5~NZX72>$}S?NoM;4g7%&@rQECI1F9OKUuii?i*Oa_Ng4go;v-
z2xTS~?cLxw--*gKR&G%=Upg5ydjuaRmR!ai<jx+MBVnx|$c&N|$uWn&w8R5-UEDfJ
z-U>}gj}~d-F9|Ww+wQc|X^pqDS;n>15~z8)(7n;X_#F2VR`-;)X!AAE%VLz>GkIz0
z<+pPtB`KAQ!A-{F7|pO$iErk8yn_V6v6QmL-1xz`(llSputrCuW7CL8axJa3XvR(?
z&%fGms!hd=&G_s!6X7~m`v`-JOYay>&M&<xNMc!I*Y6qCHYM43CN7>6VB0PawN1Ie
zq5IMVGM44-)j|hXUwM|9Z0798|9GaJ+)@*T+5T%R%`{`;C05hWp0!Um33c;!m24hv
zYAtqrQ#s%V+e%%!(9gl*1S{-eXNRjVQW043C-menfy(kk_>Ve5UHqlE1gq8{oIxm+
zuQuc(q!%7v{aBJhwZJh;$Yr7_`DY${qn+K}1f$Nw2O-e$#aQ0GiUhCrJsHT?*~UC>
z%_JdGAZS`}_HlaxeZCQRcoG1a2&Fe{r-$7|EqG%O#EW|HnZSa~y!3+UHI);NeY8}}
zWyGU&<)`6VqdH_Bmw!CFuTCSO)IbO4z=X1uz=Kc0Zb7EsF?t at kN;KufKbkuD96sg$
zybf8{eaXD*5BwXqSEVERE^tp4n47?Of(<iP1ooBWQQ!MK4^<io7)Te|k*Ha)O9OhL
zdn{|2HkIC%#VwX>`1>CR8uhGQG?U%CWN)<}nPo#vj=_kN95Isf#oFjY`4>}++ at 6Rr
zFcrnbC~2GJj=1I|xAAE~-l-U%z$E8 at o(nwNcNK^*M-PYUaX&U-D31&#$r}x_AdfsV
ziaa6+>!|5K70;1dGKS5s_5Do%5yRq!9BO0)I83_()AqM35!eahH at SbI(T|+7nsD^?
zQiM1cSq#4`gTc%exk{L at GJlxDtvF}#- at 7c^Iam3L=MVu&N17_3nCw5nWNjym>prYJ
z33A=ofAr`&ORKE${6CKT%=CKhK3j$QO(>lDGQyBQ*dZ*u$>9Kls`>_vYy1?OlTImp
zODHoa;zu!7-F9c3^Bd{c5P^Lq4Wp;*pt5`ud5F!eq#mZBCf1-KF{hn5>7!tC=XKmq
z0}ZYdUL3i)TUiKA1<a~FGY6CQwkKDoipS=RQ7Fpb<Gh1$MZS#$8tK+BkQH`H{I{-0
zn&CM4<H`0R7xfo(xwnJxWVhFa`@FfE)!n at K$J at H`J3Yr&_D=G8Do;o5s?F>c(F7ij
zgvk`QWFAN2xtY8jpgo%SI+k>cYqO;kAYL+(YE%hAPv`^G7TT2wyA-RxH)mpv$C7zC
z65+;!Q at 8jp?ld>PN8%}mgPg*u#+w~+b_=NqF48trXFswX<bd1f@^RWh^kF_LMA&J)
zbEZ)PcfcjKeLB6$<lqBW-sWy<!G-}8Q$Pl%?Rb|$-w8g+C-p8Suk3#(+cfbm+0vQA
z8t%7)MRLyPO-IFt2e`~XGqDpxgQ6ehYDU`JY*FW%T7(!%L8P^|j?wYq2{>;wo{oPR
zgwRh#@m(wQW2K9Fp)L2HB}r&7#I3;^Fr{K}TBUMJsU;i7o?*rLzvg-*M+3YytZ0n&
zT5Dnj9k*tUX(?^&?#Q<@LQ6(DY54(zvZksiLu$)s9v40OBv(<qQrENRF$AWqU|M~=
zJ`#@}6jHGi9mf>dP=?TOzEC7Hb45vq{$q>rbI%?2VD9R%O$@n+G(2$}LWb0^4XT}-
z-Wv0E<|&cqsuLtybSA2dP}^J7rq7a4`cBk;wIB8-n_`QVU$UtQhZl)!O|kOIbbU3t
zXfVl?o04%RgkJt?{wpNw#??v}0aLV9xHc()R87SPeNL3z!05Mv*kjs9`gkAxsb=`i
zrExD29PpSCw!3?FP0PXgJ!M(U#zvSTki)y(57o{eQ=i$DHw`a{->1=Ne}$Rlnl>=S
zpIJswH%7y5`B~)!imkW6UrQR?_O(Ni)(7%>yJ?BogKyW7{4}@@`9l?9L&&RGsF<uc
zH$}d-a+RPPbskz%kd5PU>BpIxXv<bbm7fOYNJ4dXf{ekIbu1UEbDV2LbG5($NB~BI
zz3we)1Bn74pE*Zk&pANKa7(hcV9&%-{E-)6-A<6<QoZ|tqkIXaX1nn5m!9rm9-!6x
zH|b562I9- at t=>ERP$)IQ#$40$14jFlGa-f)Aw;Mk??-okD at qK~NK32{y7>OrIsloB
zZ95*RJS3+7ItB&%gp&{?8gXoxySnPJla6SA**srLXu_IHK#g_}QYUa1%#Ty?yW{R<
zU&?~jmCi(VXLdEYOVU4aPmBpES+5f)Gpv}N-VA9A1O?yuV$DQyc}6RqouX%~#)7I+
zGVv&BiZ9GONcnS_uw)~PG#O$!KlFbuz|){C;lJ)aXepJbdQ-i$w5Dusq*JHDw>NUS
zvbDtWq;F`T`Yk^T56VWB?FV<LO20HroTIWmE!?iZyNIo4);vy7omOh9>$viS!DBt^
zRN0L(T<ucLeX4scoy$gVzC)655uKMGn<bsI3bVzUcD2)B<4F(5FJU3JfM{|ehCfq=
zXcU#m)o?@n^ggV)DcI1-Flo~ygb%uHD$`*|aB^q(lo;~M0=P<{2FxjbiPG-><_mvQ
zABOf1qIm`LLM558E}Cbk#_#7 at uF$l*sS9W`YPMvzeG0;U%%7d>JG}nz!sG|0j8{Mw
z4yW}{u<evkwSzq5srZBDF$cvvMa;L`PVn&=md-ksk*Qn5IjfTk!f0StoQYjF{VxGT
z4>U^~cqlWg&n3y5GQf<NE!5yjK>g1-FcRejuOXxMu_N=afRFu4&vnEBeFJ`2C%G1J
zyxKbrtLr!mC5TR1AsTKRQO$}I->RE_=AmYmjUen|{|wa)Q+^Rhg9YFH3@!3LOV
zAhPtnKm{U{dIH03ZyBn7EM=c=OLXQur;+T$v#jg59G~SKd6ItvmXV3<CHR2dO#K5$
zhpwKfDpDnX+5rxo3e(}u$Zs4G7NSA+SiB at vOq@?4)$1))k0zJQ1))Cg)#R8ZEMc>X
z1IHL`4dk}>6T3sfGF)%e3Y)n*EJoMltU9(Z7wFPC+akFw4k at HssicYx2MyI{JLP^x
zuIG`n5wmOfW;FaDV7dt=S&siX^fzV8Q2=EHD7$9_|DE7=YUuD&6j*VHmq(KDL$q}=
zl;lxe#gVC1V&oLC85Wj&6-5ja${06^?SG_>qoV3_8A4dfWeA%r!+<INDhz5c-|RHA
zWekeVJT{n1mOeMHlqAw+SirX1Ol8EhV!AOR999mg at 4({DOE|VANRCA~U=GRNudkng
zs3q7a!mPdEm(N&9nj9U#q6x)*(KJZDVw=uyW=NhX`&ew*FM1mK);)Ssu}?|}IFe at D
zwG=Fjluybux1;=!MLHXp)8h|VKCY=W#UskZxn8&8!y+T;I^Sz_66CfxHp(^sL`pp4
zz|UNhPVaDwP3+jClkr*MCf>!WPKTgB6q~>rf&N9f&xEA&fgUkj=2@^K>=f4!SAeFD
zIVaDay90z}L}Q00%S0(d7CAq at Sumv=y8cw^#gyMyhYZ3DMgy{3xwQ=Orw5GMSwx~C
zn!5PP;ao`K+A+=wf2oBPCq$W2HCI1yGIc-m$YZ9|w&e85l-oziFdpO(is5<WU1EXj
z^<Kr>#_qmw3Y*>sjyWW~`_tK40BVVTejRQdE)cgPztGNLuxF4&BLgS;lJBLXP5|V|
zx_yoX8OvIrh8!FexKUgR^6yClcLbY{gQ^{&nlL+?zTRi;7{rf=)F=<C6m?sdUSUV3
zXV;KN`X&~$i&FGGH4x at t<_QaMi93z$XLu>jhs)KAx$gJ0P9VP*6WBzDgFSH;DVX<$
zyYc(8woMtk5?n&YrLZ_IDp&Rzrigl6*VLBv0?X{rdzS-0Sc|o^rc71dz!bnc$`E?7
zQN5Hl{*m%A!};IB2=?GHtf^y*eL~_8?$73w{O!+flJoGCVJ=0#5}f;Qje^}K_?n*=
zXC)9CXue(wa~mf)Jxuh1J2}D}n{{sK%e|DIpa-R$cur&AGCe{#4v>GhnvWlTEsvVz
z!q!av!nIp3=hlfeOY^k%x><{9wdLE1+0^jNF(aSZ3jekXR$eU<`!D%FN8!wnl@>(5
z7`joYo$LuKbtY^6FBCsg68lTFIylIpL_7Zejl6IOb1GYYX5TN9If`+kh5ED*v|Yp2
zvB#$+^6z;AYC<tu`+1%x^aU;}Vq1%BJjplN<gjoXR-eEcuvXvzw^Z)Lt>Lgr_zqB@
zaVXFnEYJ4ry|4`jDs<yhJ08=8cJyc4G(ARt)q`1}#<B<L8vJVA9vu@?T99cVL_g{T
z)u$MW3?2_`rhI{N=>GcbKlOh0UQPSRzm8?sKy3I6l-iJsEDk_fIGp{nT8Ub^tI at uN
zBS@&PD*J(goJsg|Qjfe|S%5iUr(tC|FxiaKP5Z|OS>3Bj(wbbDC_OX3!*{|-{}RBk
z;PgAKB?1n66&7MGxIW7*aKlnL%s%OG>o+d at tO;no3w0%F-J8bga at o#462Oyg%cNgg
zU*>0)TTAZez@^n3W4-#3#TX5eVIt-ZrlOpPpGGygkL#6&b`@x0DM^|rZuBv{q_-V^
z)cEJ)F{&Wmk_Ek|r0QP=R+7ZBzb#7BNRA#FN+c2_h6s1Q?I)vnt2^EKnn`R+`TLg4
zn`Td8^Sp+*q(7Hl#uuD)Z#xEs_Bo)FT?&{Rmq`>!r;Zz at FfLqT9|mb<q>G>E#zzvE
zs+W?lz!Rh7G*y%VrTRQO-+-*x2jNZbfz>0uOK{fP at 8&dh-T|?Yw&7_@@5^oF`j#L)
zvho)UAM<eIr#d^LG`95u+PN7li%{Cf5XJd;di#^ZS;I*|P>B at eElMK3?!LM=$)y)U
z20;|ZC%f@;=I>mvcOe7AZocHCF$xx|CPFt(6OVUrVO9~i;~L*GWVqqGnyXnQwuzhU
zZgKx!#e5CI0J$KRn<Zxh!E*RTTCgr=_>2Bey44PNbUZF2l?WY_(wKT35=E`i@@!#r
z(dA<k%ukpP|1dP1TvMSj34l4CtI=4$XR(B2n0y+kJ@~AgUoFJxkx!WmD5$}6E9yNh
z{-*^159s|@_|u0#PsINrME|z$K}WF5F`{dxo54E_{}BZyI6c8A1*pB`PilHqj2OH8
z*d3?R8(#p52VMa%x+geVr}nGDLL4FB9U<`YwfH~AI+pC81i*1QOT&_#*$Lu=#oEgO
zaZPZ4*>to}c7`&Ywx`3BCl(D9&d_>eCfFV^g`djl&J~_Ik at e(rBtd+ZhWjJHE|3r#
zDa1z4I~=K2KrQ1gzqQ4G-5&hGpJ&%bx3 at p|<GV@>UsRE_&Cfz!NY9dQH#t|Y>K`qV
zzP}{9 at 2sqVJ&paD)oFUZU9``H^>Xb*wx92%$Rc}HesKuymRDP|YX{gJ&3thOTy?@4
zm$J=Yn|Ey$B#Pvg=jBu#65PCr4OKWAMDm<Xp{@};)QxKbWGLqt;k-Vv;qtjie-htH
zqA$`+bo2!$bhc08iTa;@r2GIb8M?>BYD-LEOEuFfQ_kpI0`qj8hqdF<-jTENJ&EA5
z(26|v<Tp!>vcV;4S}euu`6t1t<6B;x#?hKyY(UPy_~<yJ`YXdORWY-oH>EB4t$zWB
zXZBbNyEIQkIbww;iQCH(ag#^pEm3$Yz}evMuUR&O43=p~e7V`KOxGo(Gli949;foR
z+T3Rfq<+$%9GXV+4BNMf2rzcm7mj<fhIJKL=M1WZ2a;N!tYqq$NMP*J4mMw;!2>9!
z@{%YR!LQ$5IZdfMOK57O3{!H75PkG=An^cDUVmhs9ym8SO4$1OXQ<sNwIzT_u)H~M
zSAE#?1#dRh{)Gr$50=M^#g*uKEoyKFj at -|$5(V$?Rdjj_0fjpcu)eNFD66?vfa|ad
zk<9P&+A at IR`{VeMzSEH3_EW$Z at _Bui{<lt0BFAR^TX_`1V3laZh~}V|Ajyd+{hC4B
z^&L|P5Q<xH2e!G`L9-=%kGwh}r!XX52L38hIGNgCWL at r<6}eD&MAzzpBv_Tq+5EJd
zlPvYmufDka9R)Z-L!~`nPx*=s*b*eYrzp#^hx|;|jhP)MD(qs$qXbwZiJtifcvuWA
z(vk}ub*gE9N=Wy8<E-6W1-knYbf$YLsndG=Ys1vWd}vc$EBNdCp<h;ozfW_HbVsSx
z at qGnpfyEYOePrW-H_|`HT>lVqsw|{xrG9f|&HP)fIwV|On!;4+KBlYjG2UNuimYpx
zp14ww70aEb+2Y^K$ls2 at 9QI=U#8N??u59bquSt47zY>uw78>M(yiEwn!IH&p*jznz
zw6I9%YA7vR0mr{SI6mrPz^Hdnz&zG1;CL-Oe&Q)squRFVvAVJ$vH5uW<Il#awwSiS
zIF^7+lq at BgX4bfE=q%wdDT^VuC;L8M629VdX6-nd%)D<i?tC|}o!9Uxa6-2v#~>dd
zBW<J|amvzo6L>oC*J-vzDUFKLNBoD;L!yn8*XN0LbG3oC-u9S5)l?lNy!2_3Cse-h
zs`CU_Q7Ms|#C%N~gOLWJY9<Aoymb-#lKq@%VDl-uJNi*{V3)Z{2_Ysawp8L+KAw&{
z$(H9F44oD0x~oNG+04N5vsA8+plX^(h6JFA$VcRWZyzE(j)*oB<umBFV@~?z+X~ch
zjl<GFsv;mFy9M{Iw^3i at _l(n6;85xM^aXy}>Tbt4U&{U6wErAg{{<?J-3_YU_AMk>
zj*VL})+G2rMgWlB;iOg1sr7K>SE31mSr1I47i8R4qb=}9#kQ`JBtD3zbdrf{rmApu
zfVwIDVXH*dZVKuMlNlF913CTmJI644TyUgaO&hoNR2nc-{Og|7qf(6HiPRoJGTtLT
zhzTt=%Uq<1mkU%w<!Z8;J%tlL{h6!sfY at 8<qcx7VFcfD<y0K}&$+oVOCY+e?<YAAE
zPFEm4p72`0HUW=@v!mx&mz&Zy#3k?T5ok{aOfkq2;A~Elf07DEY8GM*r19qGcC>(%
z{Z1dPeeIrOcdkG^8R*WOeUc7Kj6=I}G at 0rew0HEb?S7WbeWKNA&Y~QxsKi&@D31S9
zQ=)%lY4>bOAYk!QoLjFk5!AVTi8$@r18jji1edWUig{(XUPU}ZFIPo|r?}abm-SwY
zMAxGk@>-5es>lA_StshnDi!uKieS=cZJS!OMq&;MWs-W2+fmcx{TVQ(P(Dp?Z+prb
zB+6pVO^I-iR(G9y1o!jm9qU`mT0`@5BpG!m`T=VRpByQ<{n|^k_mROPv4vD0vtr_M
zs=WsGtqXH<M`9x`_7ZV7>+<*Wmm{|VYu=zRoYW<sU}=1AGw*`1Bf00z4tO3~k+y at p
zmavXBWgH|8(5oBYO8sIc%?h?M1edb(Z+`i~X=pG=jn0`~`|CGQB+BN5+g3CObU7{$
z36uajXl?>P&S-bnYR&aeD1&H1&KYqL&W7bG at Ij8gq3{6P0pnSy>XHKzN<H|p1C%!i
zK%jQFjeDa~WWHZsbHUxWiC%6VJz)z0J_St}+lvE6owcj<)DT at UC!EaXD_>)*fIe2n
zMb>2AT>g|Vq-uuYtF##ib8Ki(=jp6DmlIC0ck9c89Epv40MqlmRb7aS`aLV?!m~8;
zIWGvx@>4kg(v^@NL)`v at O5(2okp%IL)_*2;9+o)O=bz%-TYrdrVX3fulorOF|EL*5
z at ALNIY2Xplo3$+8y~ts{{R955WO7JFM0*%zvvKPO8WNVXkq}qGa4mc at Cl<}bA-D?<
zB=yNp%f%L|MOO$9hh`-AC=(Oox#yfo{C(#S0ib6*qL;YCA(or6$1xD4M8Q$;`-->p
z_*?Fq$}aEhYN4UtN=sSIFRYp+<i#f0xQGmAK&~`v62I2X0h%<?g~GQ2pY>Um7|(*z
z4pqf0;kc=$`7X+|sbYIrxisXds)b!?s$%jbWuw-o)QwNm8O3~X_``=J`pVbD9W}Ni
z!;HR9a&eSkUC5vPGr`IZV`DKehSuU2|ApnK;BnYv$*>*9Ma6;BQT=hXU&=-L9?4*H
zrzV*$_o{CS$VYG~?4c7ufAs`adg7x6f~<t?SS at +8+jB-PzQ(gt#4324T)RqeEJbCw
zPG}ZPY|o959>J;HA$N;t<JWrVZq+qC7fXZon%KHPqFS(U!9HtXVHE2Vu8qrm!Ahb}
z?vh=s88!W at K6v+e6DkXFL?2O6o3p~SQF!wKQVZ>VJ<8c5+H>M?GoTA6sdC1CU=o}1
z at 2}l@>ee<upyNr9c(B^G4+iEs$}8<Kgg|xIhZKBPiLzG+TuD6mo(|c$0&pBY;22gF
zyES{0wk+;r=2fbT^B)6Vnj}f)L6Qo+*%$=2{)wkoH%qTZ=T-_LmEZ=B!<vk&8-)_j
zyFr}Kj=UUky2?L81wKoM38wRsX_l(%W}-~LW<IFq<9?JaJfx=B>YQlIeN4Wq)Zb7Q
z at 4Y<YwmxDbanB7AcMa~nS;N>EYA5H%FKl8|3^H#RD1QAwko#E6c$pQB{F$he*Pp;5
zt$ND8(aRABC=;V<Qq5j`Kn+thDyJO#X!53=J at J2Euvc6sn@{TfPt^l#-fo9KQ9PSd
z7J2e(5Eb=#%UYbFf}$AQ-(e=8#Q8!*3`5Yi^J$CNLDs9_2k!CnL!T&i$39q~*3Gvc
z-!HI<14e|lc^J$AxuficUmq<FgxA&I%2(s_SLJ8(VPcw_8EDr><4mhxm1fsU-FmSN
zEW5_-*kO1w;p`T8k}SVyK(#|GDnWNzzB%4Y;CL1JAT8=v=zj4u-n7>EX?5SLU6-d>
z+Y9`U2WW9)8tr+vNnCxK{dxMVAEm~3{D{+mtv1D1zctzPGACOf#Itx4N2-5vP+x#c
zQcc+_6J<eqS$S?57Qz^23#OAewOcuiE9r&Q{^*<aOu}G3z at JKHyHxV>g2gN1<aa3a
zB&u-FZt;MpEo};FA8N-4n3Gqcu>yaL5rk47ZHN~5oq7ui12{Sur}VkyR{&beL;h>0
z%=H01w+jt7e#|gbm+Dd0pXI*tuSd_&3;&&lr8p9J9<kpBBpeFc+WR_*fa?WV4#J?-
zM4y2&&<wRb*pQWY$gbN;b--6Mm<{+ at y7;|Xkinz0{z%XO&{W~shu!{&Jdy^Yxc02U
zW%PLnH#WQjpdgl_v<?U|l2)R%tW<2))$2N3T47-DyNS3rB7w|Z!Pa1(iuF#f3B;B$
zt-`xBmZ;*85#%4@;o<5?S<e;qFFg;#t}M;J#Ooy5xjzm4`tZ at vXVewz)+Zy at uDiF0
zGO5(_ at 1?Pp23Nx1a3t}~jwo$g12WNR9j>JK>vsl%RD^|Q)+iG at YzS2}|8CAOoS*O6
zic=0oo_XdF#r9u*gUtsK68?%LE$RneVjoDT;e}wgGR}<`h-t_lhlc00y?0ANK3LuK
zF;1}VIFB9U0!s&x1#C+~wMB}}eLMF0k%FH7V<Ff_>iiL7;yljL$|_!NXoO}Bpyp0;
z&fLDOisR%ImOQe;(cS9sXB79;ZC&ZeaKkS(J<%UH7|zp;M+{$=C-SpfcE#yKv0G9y
zG2|VrrDhRK#PaUbs!UPUdxb2?UNalCXXu%OJTuaLtf0CJmfZZo%2{5rH`VvUryKld
z2v-0T!^$lP)C7Z~h4x9e8TQ_7O4+e2e>OW`=!G!M)hp$H1E$K|`4D3+ at N?XT>hrKO
zJuUuq$sCtA#a8on?%G?61>|6s);y!}dXw7VEeg=ni{4`~87IPdv{wCFU`HND2WWPU
z#R(^bK_UMe%j#VRyeiMR+CZ#FEI(;ruNZB;CzY_u2Ji=ruH*;3{wzOc7kaosN4{dZ
z(*3WBXD)t$7EdMLYM88E0M~qzrdxLjD=GT|^^A5p1PIS5*omDup2wx#jd)$h?7Zs^
zb!1_~JW!X)JgF{r-t#(tabR*jc40!2CR{?`aVgdmhO&0yixw0Lueq%SBI?KHpamf2
z(Wi_VciG6ROnH*@xwlzG@`vVbX}gJ_WMkg=Qz)$hmj(=zy8SCoR+cbDVygPr6*y9?
z#AGxTp(%ZmSX|O&^}a+kQSL3La2t|~PBh;5*JFz*GDnv2;(>ys$gGpV7fGWy_+5ko
zX)ws6`WQtvPR%7HUV&U$+{@}X1dOe&V3svXeBaJJN#K`q4EQFVi;G-bLA%oK6Kag3
z#5Xa&<8IcjGbuA2{R;Q$pPe_#O#!PEwV2N|qF<Isp-Q7MPazV*njcr<;96-#aEHdG
z;`X!vk)rvdljGj2<_kO~r!4d#wseh2B%-WGyvs`rwj|CM>~6vV*X#jC&z41R<fQvB
zGk@#C8~*l=!3y*EZ&uZ~rp}XFJGzVW^v71<u3&3Vay*lX(Y)h4qph at pPyFb2vpB4_
zCYR!St*;vuwgi@(fGU<S(2r5`&**NHx?AwQR-h7*WbRGgN;Of}@YBYxE?KiT$T+KD
ztpj_=ZL#}?L_*j4|Izf_(QrP_*GhyCOFp8;BGFqUN|Z&2Nc6s|i at thibwWhch!!P!
zU%jv1d+%-a7HxH+zt8u)=jT7?V0m`T+<WKFOkelPRlni0HpII%v+t4HPLZs9=7X;n
zNe~+zYp(mJ(USC`G_k87oSNA4O{#G^bC#ez;R44_ at E{JLVD@&`L|&62$|8efRn!6o
z|GWf7lcGAoZd(A)r_-F4a2j$dodab{;D_x2^q<2Q2qoFdEK-sk^}%;1&K2wpGb(G5
z*;({KkZ_{P<}kOPsH}Z-d6Qd~DzDXvw+AU&5<Ms|q;qw%3KCI%y79}gtNb32vhc8w
z1xg>pU!7-=Y4D0jl+d<xZ`q-rzq{sg$z}xBj!uWOzBnl(%cmsEdSOGAFz!h^JJ~xN
zTi;^O8u<x$QKy)b)*RfAuH+YI$Mj1vbBSCkrymUYe~)EU1iTgDywyj3jB3~q+7x!B
ziCJpEhFA*CMTHR}^e9tLxd;Y_tLVJ!c?14?K}8=RO0Z*Ew$%A4b~0FRLXTc!C!IEf
zF(jPel)*IO8JLzs_Lum_qqL#Pr=rx<<`JYR?<m0WIe%qIGNif$Y~O5bn@%Q03KT#A
z1NA>%zF+?#&F<nX-c%l{s~r+#s~-iXNn3F-&Wn?(>%AnR>Kn`Jm81iO|A}t at l$7Z=
z;?xt<XIku#x{^3-roC=p?qi!(u@(3*T%<`iOD8|iWG;0V3^L|8Jyywl3ZE9BYIIM@
zPNM#5{g|(U`qhs25`I<7{+5!J4pNKvx}Szqu2Ma*|I~D}YlW!N`4Roj<gd)Zz!b3z
z(VyWb=I{9+N#e^w7v`EOI*C4#TAH7FzWcD#iZN5MG)<TsIGUCcFT8t9<X&^d(E&D?
zU}uTKiby03&<apq!(Ia+-|BFONgsBC&55I$JIt4#PaBd(pcpIf*;79>v|j=ftRkaX
z4#C^(J0CT=fgfO6pz`l4gP7UnVGyM8CqZ;w$!tg0sg<Ss#B>6A`3LI2?fpBo?~q0c
z8+=qP`<piNj3r$c(I=fd8vwO?yfiz?D~-^~+9=O8Hd+IT1DWrJ(dkw!{(n}M^b>Fb
zVAb4mZT(b2t<^%0NxxGJ^#Q~Qq!X7~fN!xmi at LClyYv*vCq~hof;Ul?M>ZUt?V9~4
zX8jQ9vT&6Op|F^K1A2uNz95+-!c9{4xSa?w0QoK1OeZk4{Q4EX5yQ(7GuEl$J%CxD
z*4{ME2q2IYo2XMzG~b>^E4;?MBDi!{-Hm^CyrE$(=$d=4{pR3`QHIr`_sqg7Red-%
zISC)k_%zk}Q|?@0tAD7 at 34k;7ZbfqmqtrgjDSpbK=2i%Sy6p}5e12k=cOuN<Yd8Kw
z?IBG%NZ4-fZ`d$bmg&Zfd6|D#TKKz|($t8q3jFBHbV(XUSz0Nin3)eAW9>$A<$ZVX
zn-}?SaegE9*w<x`@dBQyk5D}|p62M1oFxi~6~dU!2ULWI%+S}3-E$#D9ra|cUTT%C
zx7QPmn<Zc~x*NJAQEQk(Z8+5peCzZmoQn6IB_WER<Hjd9I>{u=CdW-I<H|J}nD+d=
ze$*rmlVXckvT2<5*BO_wjtGA;+_|MzDMP5d>ork))b_5&zoxc`6)*6WwuJJi{fi;t
zVSxj_ApbG=n at UGBpQ%}*P;A~c(BmgD+HLi`KYwoboGRf-0YRl;&S$v>f|!W6h<$!e
z4 at fW8wqT+AY<@C?ie6u+9Z3Krza}0Ps6_18r%LG6CnJNFWbL;8YJGpY0(xKR`1x_b
z|I|q1s1JbW>93aOZ9WM8BD#uYp0D)D%<0ut!VqIl<aWa)XJCYHFwis6&TU1=pxd}8
zQvfeQ8^iY=;qtT*V*KUtR3HIT^E=|3{SI+eOBrz<^psSas>4)9nn##-yCl=IF^AgH
z{w;QV>E-aRUG}{(qeLjK&|<s*Yh7Q(9L-JLoBE#2H=hKwp8{LZi3;>^uuu3bi~fp5
zv-U>LX5*UmM~*0BCE!I|7(NL|_%LETp&;#9;_dGsHI|Ubm`n&?vf&zDqYqT0s5*6)
z^^*-up!uiKaQv8+J`rt9vBa18XI+L6L>!SkWcCr5DITL3r`~bNmNd)_bk&I*=WYLU
z{#aqt+$5iW^pSNqjc2MYx?<hQ{F&CR0=3oQ9x!%%cXwwju4US1qoq9^dZ?@<P<^j0
zA?E=_ZkJ_HUL8m3ydaG_wQCTddWy+ZEgJ#7|J|J|ow>1J$ri1x>x3c}p=vu at O3(T*
z+`O0WP4zY|jkmxXRssbsmljFo#qSk!t at rG6fj_*9Hu*w?)ZtZk&?xsD$0eXRog;Aj
zJ9+8Z)Nr9DXL4GWD?v<R>U8sjZbH`7P1x(u{i*E(d!s}>(+d|~f|zP1gWyPUr$v=&
zD?dNK;*eKn{jxX1b%v4<v#Gk=n1FU)fyeAm>4YVE>jgg#Xjcu3G{z2^^AM-%c7lcP
z+3DK-u^jP7UZ(xDdDOfAc`ee$Tp#G_|1gUB!Eg3BG#?Fr3N-zuFL1IJGy=`GmfLjG
zF7F?ndS^2Z44PA8j+{vmq!4C|A;Y(?WNRRiCBT3;NbYywi|PR3_3Zni0;%7dSIDlP
zULK&;UPgUoBK+*oWcH=RYc<lP8*ndCVKHC~e}0HJexsGx&eG>8Yc}2qeyU{})oWt3
z-HGam)h!Xj<Y|~yGAg6XYinz}GhcSUCq$q(2TA|AXHv-;!!1vac{c|S`4)%24!&L%
zXR9RO3VS#;WR)=H7h%LaVpH(B=1Y{WsA9_+1LWV)${CP)@tpsUVPGCVUb?s!e=uU?
zDd|N1po{|@Dx(0 at hS#a{<i$XCMA?H}fCELl8J`44R}@@!J7Ek$<0$gWn*>K8(1C;6
zQU9cM8~YP!H-g!fH^OI}WKQ&#i9`~1);oS3jk}e$U#fJ0Uwm1h!CI$l<@~I_FO6bj
z3(Uk>8 at Tv*lQO9vv1JpheiFTL|L1Tbsbu9(LRtD{cSJprc?R4Nz<1p-d>k7#=o!9|
z8Y7kR%b5l~jrGRlcgn7Z46l>ChdGTYy^M`qlB+0}LEaC7hDEYBWM^+zVzo8ish(HD
z9l7_&s161|7aBvxk6tG~g%3T>auoF at -YsV8(|JzUo0yWrLE&|s9g{2|;zCMgsr)(E
zdj5<Azj{!|5Q~-FYHlx}Kgj0eUiH+D3!zukSHVxl9)3SbX5>P_qvofyrs at 6+QBEig
zyMBu|J67J5emu*}Km?JB`%Tm5hVvgkx at _I<0*l)NJbpP&L%7sZM99pw#${hCELtq&
zFBJfJsI*x>^(}o2fi!*|0F)?7x7-9H2E4b at po#;$7lJI9Bi}RU>~uA1jLg at lo7Ko{
zh`MBCP3X-JxLSV&kmHWpE)COu17&l at qJJOm@rk49moXqe{Q6n|wD;UoneL_zyZC<d
zx5rKck+RWL at vySp2KN1*H%0F0XITmJh$n*Bj126G)>5+Kv{#+~n-7Etu)f=)(&AaS
z%UHBS6w6n}smVaH5D9YP;Vv;&#-vJ&QmlDT4b8K^b&oy%88J<Tt<)jg{~xh0g>D58
z!Dd3D>Z_IY!+&*DbK992``pCw5n>(<eM5Q2M$fp3niBMnyecU|)!KpdanCgK<FEtg
zD3&-UFm95BVoZ%Wl8~t>Mhkk4dgT+uWY2-0-)Z8kNlHiBZohI7f3CUC_>9whQUe
zsXrSZdOzd?ZsOzE0J3bta(2qLH(`|n7xa=o9Px7$i4TMM$gHBuxgwQH<6nLkdoojR
zmj#JZ)x|{`V!RG=DSWjL@#)s);!>);T$Z#(;wmy|882>SSpO)!B60I&Vb9Bc`YcK@
zZz2=>g_$XtQ2El2b5%XR>@&wNN8ZPt3<BZlzhW8O99i`liHfOX8RDi|dPK5qXk<ev
zcDUv^ISa=2Tbwn(&&gkDzhAF2e)scK8U9O~W%}zg!wQC!!}tRn3(c5U{o-`q%HwrZ
zZ0l5xkyNtE=wD)sKshQP=y5&+vW9!tidatwD$r?i{a6dw9<SAqyZTQw-GU(H8o<KS
ze^rpee9_d!;)Dp5 at mnCh)Fe}H0d|zVf&}K5x?i80tb-och_d*8647{CMT&3`2b=`B
zM+~SyjmC<kTA-1v(Fs&Evop(ii`3sPZrXfGtltv(fnr(;AaqOJa6H>uF`n!gFSIP&
zWF at ld?KEMom7d5!C+=kjxD#!YR0rehkcu6~nz)*aVG5(SbU at Aa%?&^Pq(?Q^__{hr
z9X9d3FWNi2*K4&*D1vD5#Sdw7YU*rfNxbKNB at yXywoYUftE6IXuiw1D887KKE#~9>
zJD at 7hVf&V2kWI0FxjZV~dw6me&d-ue=-CW-Hx-@$_tbX}6*~ik8-Cx2u?;0%j!4Bm
zJE&Nq-UvHs<*-ie*=AIX3^u at FcG3c-sYzt%J+s*y#CWF^Nt1rP2zZAaoI7HzO=E~K
z>A8M;L1MJZ!#LAtuN>j|;>CCzRmLE{P^C+_DRZx3RHg!zzf0LZvs7zqN1!yuGTEK&
zS8m6?zyae|K`^%Y813S~a5pu9%;??2v0G`MBVAubNd~8+|E{Bjs92`hP->SBHx5H>
z$oSP}S)PF at w&7(BV`WXeO!{tv=_k*R?x?-K^1uwW`tv=<cU{!a3NLbcCS at BtP)G_6
zhn1s?i<DNUiq!^lJYl8W?+eypO*qrAg1AwbzC*f47hXY(2z21iEzKHJR{|%)75lo+
zRG7L+ou%idcvUnz9kM87t%p=gK2_%Bx}bw}Y}RcFLq(<pX3o0)8dM&mQph16;?`Z2
z`p;d}-aGj!X&V((&o~6f`8fs$4Xj4GS$AQLA5mmAZLLLKtM!E+(`u=vBXt*U<TEdt
z)HH(al~7Xb*Ihbckra`otC6Zt!f^M$yKVJ8Qt0<^4Bo8~Z&?GyxgESa1i#LuL<lJ{
zV2<|PNid{oA&@@<MNSFQ6=WC(x@{Uv{+sVln#48LdO{&OlYEca6A$kiDG{;LI(VI8
zMBM*n>xDt8^tDA#eQwWZzWnY}_*y;Z#YtXcvDc`VsK+cHM|@72Ph=_llZ6Wx=LPM}
z+0I1Je}PHpQ(a5fwhpPl*X%UrodMaPH~kMWY8fBK1ES6-1O2P8JVJEO<YA)On``wF
zkoOt}+ZedS#LD(*&AF8u_sC*k*WSsc0GO{JMrx-zZLm&3A*prpXRBM;42CpYPE{ZR
z>Dh-h{x74xLNi6)2zSQie4JCciEv+HWN~q^%RetL6oEkS5Iz#vbV(ts;0V%Bf2rRp
zRw|sfa=$UI>(S)~+b<&AqK!WIlN_5mP8d#^b#-=aJF+lc<H<Fmjf`^v&t#>FyM2sJ
zsvcFxKMG(cSv9aP)L8f&kc{)5tjP^R@!~O3B*FSs&H0AjC;UZ7l{iE8amItX$NtFs
zhsHW!BTIsh2zFoBG1*W~rALaq<8;Ssg$NDJVnJ*QLw5?ovUe?p at PUp-V=xPAfZKA%
zz1Q<T3OuD1MI#DayF<1A^8zf_P5DK9=5$=bfhqpprn74-=d2YPd;ROi?r^d_H13cC
zxaP%$IV!3W at g@c)k<~oPP#xRL+EL^J$|xzXN7NuU^Zfuj`dR|-c5v!vLh?FFisa>X
zaQ8YHMyt_>2QxZzNP~&Wr~pYgeh$(Jg(x{S2k1KnKdv3WM*0e01oE$tVU9%qQguB+
zaDg<i3d|eb*ux;xP_kP}gvQGfR2D}l%VCy32;qHwwi8s5h3Y^#w}YFV#W<90g1T9V
zJfJGBwq7L*)jmc^+EQ5}Cbd>us|Vi&9BeCL^C<FEU**kPPcdB==+nXtv%**X_OREZ
zl;c*D0^2%6SjDjgg|=l{x%TOkZ^rlDjXC}s at n^*=k{In6k=tt4RdmAtkz5qJK5rE=
zqDPn(8|8^h at I!$Bk115i1tcr?JCmrGg&NgQDR?C^^d|N(!-H!-9qa+Zw(F(RtR-QK
z7~?pxWUKogdanMT5Q_B^u~pX+Zq<Ru&J(o|r9Wp)g2I>Mq<H#Z3q9y)`nHkkIjYz)
zu%%IlhyvvOJ83h?kvJJ0Pci+ at cLy)0|L+$jK~F3Ty9JhK2g6j>`oN761;|{nso<}Z
zC62o}yUgVU;~4XT0}Z5awsAsw`rZO&$CAhPXSf0Sb;YaacoX6`-JkFvFzh0Y>x*x3
z!^Kzj%gtiyFN(!s9H=Vx^(uaT$rcGz>#*r?-J_WgaJ`&xh+xHG1*z(J5zW)2L7^fZ
z(&NDy{CvVt)|GoY^r}Hk`Wjk2#<#TR&@nfsqJe^gyV;-ve10yx3Tmt8h;kDSh3w1B
z8b#6VRdd;Ce{{?>y=gWU?asGGWyyI$Wgx4OA<lXo;F6sghtFc|qEZ|qw=|d|E_O`*
zkIy+<ijm5wb<=+9XL5~WuU2(Y9c#a~m1e3^ZM(pP3C|H)8X`lfDFE6k4M>y@;8>no
zGYcs>&Ow<3b&3HC0Jkoe{oeNjXEM}%JxTmrdy4--<F%<r9ZPD{2if!)27U;1+Z5K%
zwIo|yzVX<E{VH~PPB8aMU7+*A>8l at crT5%p%N?zyTI&1}MUDh4%_&lkY`I(Er}oLp
z>2}iQQ?)1kP((pxol_eJ1 at T6b4fP`p>tFVIc;WwhrkdIq4939!D_->%zq|9ftlo67
z(7x7FWH-(?F?main at j9C78}@4R_=!LS6vmpc-AqI!)6uhrvhK++KgXJ8=5A2e^u6o
za<cEPKzcnhWfGt2P&?80+fowr#gQ{v`?Dla<Mo0H8HyIk?tY3KvRae{6s_iWJ#LFO
z%-=I8sfm>^>0T;s#yTfR%-)S|gI#kOaIL<j+rM{p;#o#(3(ZtXHLKk<lI*<6LoiUK
z{#3injBY>Qp7)~rth-7s&7`0-KSn*8Tx78g(m5CG;~&=YE at 1t((sT8!K#k=%RBgXW
z>!|Fev`6Q?t|T7zIIy1bdOz4$pmA^f(GZiqXR-JPfr94=`&VdS_tOt752YgAohy5V
z6Ys at lS6f1v+IaN)gZxkk7e7I(h7wXaIC`kG*m5L9EnOL9;`m87n8sbVXou8~Sb2dt
zy5yV!^F~-?s4t|T$omBxJ#nK13=pt~{?mHoNrVs;7dKGJzgEDz99{-OVQ*v`_E2Yy
zlF}3I-v>Tjnj2jMHPGPhu*{6(SSNY5gDHY@&i#NiazztQ;6BZs_65D_gSxPJCnHc=
ze!TYCv1d4B*sD}#{!xoU00n&~n5A1ygGYpKT}#B&1K^o&e_#T9Jw5A>DrSFI;btl5
zZJHm1?i*Go)sLha+-w<N9Lh<-FtGbH=XaoY1ytsr*m-pOC8xx#Qklw-96!DyxUCn~
z>~isfV*W$>Ujfg}^YrR;JIqVdV0wS~(b>htMNo3xA`aZ=(PjT}U0wEP at 2iu|4~w>v
zSI5W4)KoAN??d+|VZkwd!I$chD5%q>_yNHIH4mF?%Dgij&vJ(}BXT%a<9bFwzs{gQ
z at I(rNMjMF;H?g$2UJ1BA9CeV4+;p0 at oiEDWNt_2{pTcs?7MGXb)0<}XSy1dI)fg9s
z!=?FaF6im#UUTpv;eEIiKZ<oQZF|@@U5hw at fvq$v)NJ at T*}eJAj1P0);AzKaXD%5w
z**3LPB5A*+#tNS!#B}QfEsuRX+_kUbesT|)9XhRiA))^I&pgM?wt0d14eM at sUw!n*
zFpC|xEis`|#9WRt^r at u!lqYxG<IUSv<KcS+lEhHae^+to^kOzx%OA8GX59MS-mwK)
z<IOwQNUgX<XWPoM>V?OZm~ChCL94}QMU$liC?*v6p}5sC$f{yT>n^43Z3VR)F3l%{
z#_Q9egZ at 78hRcbX(v+bPemM$66;al;Va$fxyxuYZhR82cKKEC?Q11kDzxn~;kFW{y
zwmuX?Wu1OO^4E~PQ_UUrj`iL5X!3%ct!;Rn(qL3rnznbQ7oH&Y4ag(PNB!EtDW~Tt
zOTZclrcjEIcMf0BM%WJj^w35KMWetJL>OL)rDO2%WM`F&%iFR_4k*=ggiw{eHyMJ;
zD-5z99twF*6XSW;4(|@qXIHUzN>)>{25ZP8*dFw#)j4^+X0Ht<JA05{Tc_LBL?UL^
zx024RIk64$`lZcBSRbA=NP%VeviMgflO<l~49^p}bA&(nkMox;-lrbhyZ0PnS|m?!
zbBKof<F>Mfh2wmoOV+x3M6VwA)=*eKhKJ2?<Vy}Sc^#blOiNhd+Ih6)h*gI&HJNm@
z4?El)_s~-&*YYRPq`~wp_Xa3hY>%y9pNzjE-g=B0{xw%{<gDO(ZhL~IX4+<jgqlL$
z5X$fCYcytwQ+3B&v)hi$w2r>c3(SRJX=tFG|8sG<$bZgNpfql!0gvf^iB}lMzrNU)
zQ1&Sq`Tgql5`La1a=dl^aW{OB<o)f at Q`1K}oG^E`_=>$d;Dl6tk<5=u>^OKeTg7(m
z9VW at 9wjqVW#6&XmNq%s}CC@>x at h7~e(@hjB2!GhSj-|9EJ`SG5TMQ!SEn(<Qqe46S
zg*a~EeX$l#O;Qxm8C0%necj`YDo)s2UM#NYDlK?B^GZC(l^DUMR*|L)AEkbgc50l$
z6+%PT@*TqU;Yt|F<V}Ros;0!PW?W)gZ$e2KdI4YjbfwX;Kq|tT6}_5d8|-wbAMPBj
zF1`w~EM;~5OvL2-0K^D5ggg|&F#|-2TkCBRxt|hH#=cFKcaz*@UO;XzVw^<FYmpOr
zIX5L0d*k-XjL#mpG5Mb5v1eo$s%fv6ScWPF%x#jHctp4+l&-?%Gz{~PiybqF3bA{;
zUjH86kRyz+9b|dkf5d%M6QFxvd%1r3o9Ok=s at r|o7utIo^0v^izj8EW+Rw&WKfSht
zP~+UfRvtw=(Z%%^J6FB1oY}`pC*Ri}L4K(b7m#o^__*ytVsh0As`GFdXgYZMgCD!p
z&w8RmsX*&+aYR!`P283w%E{sUtgP6&a7My1dVXURSCQMxj72P}P{}2eaWc`J7S4GO
zn}Bfry$wqDyo4i^CAis^o!tnu`C7%ZSf-%4I}Rn-^>OFw(a at k==z&P^`pqc4>0yVd
z^eXPo`(fC=*ZGI&08icy8(K9v#O3@;O|tX=z2)NAXwWW9x=g=AE- at a?-PCGzHeEiR
z1-nQ8W{DqPlM9349ekW|EcqCk(r<b56kc8PCHsR->1;8Z^c+=YUT<I6htOz-kM<OY
zeN+Z*DL&n@|7qi~Y$K<KR2;JSUSQboIJ{@n8bq?vQ9-~zzphAXnnN%cwFV+81KwWk
zFP?6WJ+dFARlm_ZSlXZ>*Du#V)Nc;@wf<UWvSYOH&%Z(B8YmF%O0rkgF)uM?y_*L4
zi_#Il&x6=cyCduH&QrEo(Jv#$eaf4POC!4yLK)Z`m at 6~>TMxyq@)Dg-40=Tr!`(Yw
zsOZol#2qO<MB5Ssd0yfH1YPU0Q2+GsLmJBD@~qVFZg1-|ZUJU4=VQ at -YzLpPOm0vI
zW3c>BV<(l<yM_1lP|mAjC*4B~CRKReS{NxYE~!shb{5#v(-Zdcjypd%I5<ptzqRIt
z=ZIy?<@w%BScg`GT>*(RqPeN5DZSX{yIER`RA*~uHgaans*~b- at P04}eQF`oLa(CI
zqG*o0&7y+6-(uic^#;4Vz)8}KEj88bVF?(+H|L!8Uow76oLbC4k_uGUuhASE8j<>l
zJg$Itg~nphAuCi926th?NFbxLt>x{Bcd{3?aTYgg?F7G6Qq(Md&&$gTOH8`vMcu!f
zDDxK%(e|6csPBA*rPP#A+<v-=p(#JF`PiDE(zil9v%It<j%Wky3niOx<P{g`oRp+^
zo@~B`HX^Nl$K{Q2Q2ayi^!v=$%^|{@oq=~SJh#<EdQ@`YxM*+J2EWtYXlA;@d}^3E
zcL9-Sr?#DZMmIO#*wW&MX_c?eKS^8?RLib$`{T8sb9;Mr8rI<$oOydhu25r8(;^pK
z!B*zAtP?Z+SGx-Fg-k65e}`^!SN`-GAg*bbB~$V~ihqb)n_F87oo0tWLkPylDGoWx
zj!#G4zc1v9Tz!N6{jO0?)vMXdj$4PotqXj2N`}doi`haNld&gr(#TnR5F=0&R<BW&
z+W>^Ds|P3*i*!K8u$(x6bOvwtpDyq@!iMHTi+L<FbSIL&Xhymp`l7n|U~+Q;=$8rA
zZ0o1<4>uq)iNA{P&<x~SX{p2L1K~kdi?=@iO|O9z-JqtEqpo|<(Cs%NXBYaX4#7cO
zVn*3FKqV3f0)9VV?TfO$Wm80r;DHJSVm1Ub+j&udG9ipu1HrG{d|!LaHQWJzjD0Hb
zacH!BygBfDds`2^%7saNxQInb5&a<a7e$zNzoqprJIQ<UTl7%u8?m9zvk4QEG}}#S
z2Q(g=gezHLnNi#a5{hl#qI+S2!&e1M4<+YJL2U0)fw6cUpq4$)g_pCoRWZ)?n>5NN
zep6?HRFD|HC`QW5ot+)wC~d_r#ul|^m+Xq|)=|H?zG&c<b1M~Mfr1VbT at 6Q&;m_GD
z8KLboZ+tvGJ(mo{UqIf&p5niTcUryhc;V&JOT4Bd%WnH=)Hxc at jjhQ=u>n6WS%1YX
zRdUCe<S%nbiC<xaV(29tT0HOiSO4YRr(kPvM=`JPj}k7koEH&9Fm~4$OJ5mt92sN`
zGbL@{439~R>8u~4KFVTc{x=e0l^*E6;}6Z}EdEF+-{gp7ut5JZm=iJ<l<0Ata&V&u
zSx|ff4K`@*`wQb1xCcC^C~$yMEEwpwo4P9VZ8niHAN_9BEw0+*`SF5)*1ammXxq$s
zI^g?aJ56p4=}HsysvP$UmsI}WMNy4lZC=gDrL#|}S4+w!e~HCYlvw>E$DlA|_|ED?
zWRpI1gPZ`=Rk0xrfO92lAkJyn5v3qnGsgkr`zHh7UgUIKbiF7QiF8zlHrd<Is*Y~`
z@;=OGw2@;Q-?&}!h%|cjsNtsV6otxq#nS~Q|IZ??-paYUZMG;7)q%4`=r1Q at eNgr&
zlP_T{GDdS|`b+?AWK#ze%=u6VvXd1<^^OfgWq?tbyy({W+y&+(nzr?HcSp5?4T4Ru
zyTHx0K6!F(DJB&^n#5jWv{oOOEOM%Vn*Fw|?)SXO4~X39Ys?#^FQbDTX_^8dNnLRx
zxh6L3q>sBmO(YvS1xt#rN%s#Cr2nG;wBvEYHWK9l at Gu?qdb2vOf4Z>&u7%kg+E1eQ
zc6F{qOC?E-bGjwroTlSOx75-Uk3cxD^^NgTmu6C1;+i;g3Puj~BE1a+XD}J$A2=5l
zvT?+S at tVvF)t1r-?QqDj9X<A8wl;M-#3f1JFS*5(LL-7dS`v=iWf#q1zmasH8h1P9
zpj2}ZxlysZ5OHBG_9e-Ny8W?qYPyb8Hm?VbXfDks#t!q$3V^{y_X4msijT#ioc=~!
zQRdLy?&yC`(?0ag4gK;&<2gYEG+7&kvi`wV1=O(BM at 9k3)&|r*-Qzk%PV*tLuvbSX
zUN<)SBXnnBW8}~Bc_VJrtfKnnFv^4>XHv{t4dO(G*;iM3oWj<s?b$QuI*#OUp+{~=
zW;qDo_d>1OJ$-y5e}xY5As*{SxMW5p8+4gWg*^vZWu;i&1c%<~c)Q#ssCdET$T=~y
zr^2g|2Vi!~9G9u&tmpv>T at C-|h`)2kbZAw%LOK&dWaD?p^jkL9$;=XtUn~QP9~4Tu
zn3G<{H|wCs5^2BMh`D8-MF^YxY8B#kZAN8v#jZsTV_+0l-youu*~bs8Ktb~XP*DPh
z&Jhj9;@4PWBLz_>m_k5jlnYa)!Y at 7a@ECE%rOrMqB#Jg_2Z)+Vi|{x1LO$~zQ*$Eo
z*4CAV&_7rQOhox^i1Srf{1SHE6mi{O at e5v7_OHDv$9212d<~Uqea(Lr29DNu(1CVX
zWvJzf#CpvVO>1;jtbGyw6xblCV<i>WB+9j at b<+s7(;zJ;pU3UN;%CryZh=MO;n4K$
zy!&#W6J68aNO-n8x5mfocyP3iw5pdsydp{{`f$MD9G}%_06juBo5AH71nCYfO$bG&
z7p-e0qTHgNyM6g9)FJ?f4-sCMOq8Jip&NM2l&lS)@1NZf@$<Z3E3`Q;8NzLR@=ZS~
z=^qVc|0&|=NW(Q+&4 at QEVA1m5lF*icnuzmE{cDRj&qo%!TQd<0iSa%o7UFveA|DON
zbR#67g1lqkl%Df~q8s03BmEqRa`X-oe+O(XU2QiWF$P|m7OHX_l{A1yYdooP*1`rA
zWP#d|xpREhH#v9=+hVsMX2qNwt&fF2!rQS}orS^ec|vZ{r}n(to)uxGt>N$l|K%&e
zuT9&?j?uV)bFbQ(n$I;`MRv7Bha#FAZN}OSwXEoJz7C&lbgV4$c`_MB$YZAoA3<Pc
zMihIU_g`kerrJ+*TKC6G|DX`^=hlC20qp!e053NM??&4sr*f1VM2--`-9#G at QO-XT
z5;PqfW70yuj2Bu39e_$!K~wcgC=+l#AS8Z(BbJT3bWtXU|Gq&)@&P<e at d0^#lPYj9
zXP~}7hEd7<B2tF*p<uqdWgY+sM8|+>?g6jlHR#TK2;5mE!XRLK&n!}n*~T0meo3&X
z&)5^0UwsK@)(|=NOv;z}To%y$QN})&BRFo!DA%$}vzjuFec#-63;xi&Y~7$(VBMCq
z;zYFZQCszSs|T4!y`spbjPL#JRc5^zkvjd$!gyC+O06fEE)ms8^Gu^2yFDq=H-tZ4
z;njSe5?ID&dYDQ_Du*0ay3pwd5_{r`u{=vz-`T!oIPf<i?t&c at AH&#LV2efHp%jyZ
zDrQkl2G|w+gd~r#<sd3 at L_|0Z%Ebmd1*X-`hmQV^qKkL?&84SLZXy9VM>%DVz18<f
zIm$0OqU2;8bNTy=uSdzg8`f0E(6E0+6`jS at JiWeQtWv=vH)+w%Y&x##*NNx`XOwSw
zjtfN6aNQHn;IRs2p^`rR4s&rpQg6Pu$>yS#<*#B6FQ_7N3>n1F858GUy?(f_!;YfR
z-`H=^%yzOX=IYj}21^KHYpa=2_Ld|XsK92Gac3!H6iitJZCPz!AM46Pf?2=3jw%}Y
z2HlL2kazrC;9n91`eFZGI8F1HKd at huawId<rArFH#l`=0pmiuI1`eo-?Cp$0Paow+
zOLr5fW6zqLqCqg^78E2{KMhFA{aFy}4ZV};uyjA`ySy~tdJmwUL><;-X_Ax!LJuSG
zt at S^l?3@^tO@)ir`ujCd%gD!$j~0C<5c}bGbtF(TT6J0b^u+~2y_5!<nF{wjxI5&Y
zMRAyv5>b^r^BT>*6k4o=TIc68m%Ib^3*rjEdhkUxD5I=3x3wTRH)@rw;=MlG at 1m{V
z+nGxuNWASQ=ZNtS_f%S>`VHUtFVxhzRF6l=@tvAI*;3fLh_?P~KE3DTK3fD?dlO5j
z_`)i7m<gIL<#}Qy7{%6GFqx-~3QR+G%(6#akDE>b?K(+vc21aWvb~{B|GaE~qhVWm
z_VLnE3h1xXS6k;K87kWS&?mky%ei`Ofyyd{7zfDnJiFckLYx0sRM1h at IcDbuH1>70
z`ykea+`aPje;*6o6qlaPTHR at u`n{E*Cy4n9x*}}cPq*z|_=*`{K6^Tf+tHD^$kQeL
z=RJqmUnY6&P3gGt at Gw|_^=R$+;hpA`vOuX at -GJX^3TEVB>uFK{#Jh5p@&V8~h`!Ke
zZ#;3oZYz8z#hN;zIFn}lMR;1tYRp*~`Tej(N%U?dC9PK(5vnFPg^!Pp>-aA^_psy;
zeR+0t<nZWG>RTLnMS%$I`-lH2q+Go({q&K)4L)#?3&>swd%a8f9-V?H6DgU`>;K|a
zYrhIAnCup5P#)K{dTtq<7sL#$?*tEb0|khyT{fs1=V5sTl=x&h5VF6a8DfX(5NP at a
z5VBYV1>%R}zVA~6muxw3N0&EFxeJWr3|V5S!!ZpWU1S`WO(w7rtF<`r$k6%##Hao6
zK)(S8W|Xf8mE}CSmyT)p4l!*9UPT1Hd7HKE;27NXt9W}jRo5cfJ$8G=%i(hYoU$)G
zusnxwHmKaT)T=_ff%ZV1d2m%u_$O>o|I90-Mk_~Ho11+oGqB7x5BfBn_S8x7yhWvS
z>7{uCsjdVL9SO%(qj at fJ;_qTscvU5B at uR7KMXd$s>3(?;3H|xVL?3)6sPlrS3RWAu
z^jYGRCdmRbKB(_EqPZlMHv^_8GCPZX(?3X<S)_xa-fJsM-&{4T9 at w?;SP&4fA<q&u
zYzvaD4L-NPB?{LSgh7j`v~6p<7UzBz$3gjvnLJP;mk!a7FSPe~c^(=o;Vd|GysV|+
z^`QfE=ZG9e)Mrj;;YlPzVenA+h4&Y6&Gl at 2qwPhO$#S35qzxw$Did|`6PMgWfvcaD
z%*YJ_oT7Yrqsm#sT7#e}3T2Ta8 at +;+ujQ?mss*mw6uUbwkK(U0TEiTdH(Fl>?oCsd
z437wLs+w%L?TYkdjiq|Q at w(KyIF>n}72_x4k$RN}YaU7nmW&jR!Vyn_Vs(?+!NmGC
zP-#Knk{i1ypA`il=k6J&4)Vyuom2BVmWK)d!Ox>Ti4g=^!0xS|hh5-d0!uxwcJP6Y
zoFhjNLh6i#n1XS at -H}C$aOw#nw%U*~50$lSk8ghH4Ub)WoO&)dM)}}=KYwrx7&-R*
zX9YxoxYJy+Ubl%@kuO-D2VjYm4<P%bGj`9?6e#OADCA(Mf8I7QD|)8NzKvz)*E>mD
ziA-`W;XBQ;Z7|y>a<~>E_y=yR8AraFdd|sVBCH7`#@M923tLtcW~dvPA)b{pB^PGd
z7M56lskX8qS&y7pUth1>$E1dc$^^UE)=qgD;vZprzFq;mhdSXN;FyAG;y#{jU4m>W
z{#n7vhP77DYh>`8JaGsJHD%FaC15TGSiJ+kfW8G}Ws1RAz<p{TDuCzWWKH=muenmv
z4o>4nrOiGuAeoc+6^q1g6LojRtl~w&*N*n2{pYG!I9_#L<E6J&n7xXT9^Gl|z<Avh
zc0|FB at +6F_J*_xvT+b!T)~tf<4zq`MhM@{96WE;v<SF0hmBpD$cJ!B<3#B3y^UuIh
zxQ*LfvoDmFL!0}dx~FmqA|$M7nyi at Ne4o4P^AA?F#+(5o0OQ}@`yEhY{qJbCLwc=I
z0D)xUbS<7&lC+Ow%E7<6g4JmzLeZ at rg(GS2-}fMxQ}N_)8pY__iaubu9!>{&OW1IH
zBhOH^?U{v{vBe#Q>)%}VZTu!WG<d76Ha4M at 41Vfk98THo8>SBHO1a`~w)OY+n$rF%
zw*J4AQ}=??R%-qiR=+cxe2Mv^j?k>|=&aqIX;5-;jGIf&<2bA4_v*bLhMNGG%7ZCW
zdmT}WgFozMcfcj?LxM?obZ=aT+R`W+TX9JVr3bD6*P$GV5nB6i9LW$|1r=BqfG|F0
zmcUioAHxD+MQ8YjE)tkzJ_S4Wh)?)5o|?OKu7TFKo1LG`uyuL$r07qUmO7ow*YuED
zyp&C<CbUeQO5y?dxbxs}3AAt8c_3gG=s82tFTb;4qB8eHkJ!vA9cG0c+QGWY>c1wf
z3`aiqum9K7Rd6t|>PJMDWY>a^5DG)QExa7 at yFY!ny}vme5fr`mD3s1yH4eg}T{~z!
zqSy%7-{KLaLX?AkC6;qjiHnIXq8AsN-YoLsUNB4u`w~smR8eQAQWMG0$k>(xy&UmV
zCOlUd_eM8z-i_uu)!-T!55V^f&hJRUD=7B#a+o*&LK-~{uXef=TXG`H8c#=7Ox9$y
z>CJ!j9tB5(ic)C*aDFU%)ZaN4sPaZbs;J*)q3^%Hx*pX|HHI~<nL0ltRXnpp=EM<k
zbe2!l-V}#Y`9q0z9nSr`CBj(paD9kKtuH;b-05N4DKB+053x~3Q;z#!gZOBp+H~kR
zXoW<}O{sUK2wT6dZDR0?@tSBq$h|>SK(Y8)34`R-D4q$kD}v+&-S5!9o)dN2Bk9b|
z^)fRI$~qxkPq4GB9WU!q^UHH$Pe%_7D7-|yFZZG73Y3axd<uBxY&t^pFtmQZ{{Hx<
zpI)z_y=}OX4&tn-v{`doe6#g1(MFMnPMg_Yb7<BMp~lPt4~KQ}+i`vJ_<LBVTbxqc
zmwNi&qn71rb0dfM at RNpZv7|(Bl$e(^*9E4?NuIel8#C++*~?-(@TNq_(AP}3{<m9h
zy}e&B at -Xwo&nLB|j3`^w)v?ETVEST<;Y$ZNZYu4Mb8xBR{c~RxRVVm(^e4xjkToV-
z)uhHs`GCoxL6^}7FNfd{PawfHcF=Iwd-st}<n7vWYz5b?n|LisDrAjA$;zutNR at CS
z6!%>W<^OpBCe_B9fzaXPz?69%3cMiFh#*5uimcLL{#~{_+y%faB^&ts-9lP??>xUk
zvSE~n*&qZ<>7)Vs{<swId#SDcX*s!DDA!Sy6uEIU|K#txCdfg|T3s-83jLf-CG%N}
zlz*=>=52j9UHw!9^!EmeFq~N9oSnLt5`{_9IVdi<d(1<rBDxQ0EqauZW;R_EUW9{B
zN64W*S(y3w=lEkJi|Twg#W%?|YxF1moPpK$euKkpysx?mp){y}g_*Cg9L)QrPCD0%
z_}$@na%pcf%DHs~J(us6mZz&E2C7$AjoVET?JN5$nZ at RTq1LKPo|{_A_v~OMQS22k
zSAYf-%D?T>Z28u(FErR7qWn(~@2^^YeZnlLfS7zqA2vkZacvoN#@*a|^*fi5=l;2_
zQtC5ZFJ0X0 at v3@u?y^2L$bXL!ic^mW^JZt5n&sY?R2J_buZwAP7+OOA)~7A3mjrcn
z%gM->M+Zy_9QYJc!5FuY(4>#-HZK*CU^`+;ZluhON{MD_eHBe`VQqKp&v at QVgA4Cs
z<$)6T^ZC$Uw<iNUf`B7*1PZmx5!mA!(<~myY`<Mo=!c0?nR%`()y1URvnUg~YK0Wz
zkLjYM=nIeq(?9=mqsOc&Q6|<tL4!cEeY><1d at iv-J@#l2qYBrp8U7BrIOXK;cPX>B
z%*&5u-l<-T^!x;LR4=(PvuR-v&t{RpcPw(p^A4S<)mG(h>;Tp(T3G<U#;EKrChS&L
zi~`M*1T2IyB?9FK1Q1n6{KgN6HzncZ4~S`vjHB~V2*eWu1PIHY6hChg%#l9OzhBXa
zYX30l%v(7;$Z^F1Tv?zUJ&!sw`@_bliv?K`5jE|}Q)?9$3T)9RsmUPDKiL?H!XqCT
z1iMsqWE7<v_F!#<=`nwdxVl!Iq|8=}tB)^yZXUnbAq7;@3CU%Bd2;E=cZlP}1gco2
zeslT!nlW0TH0wjqa?EZ}Slx5t;29BG7ChBue`rWiKq74~54U2vxID}sd8D4h%c;gn
z^Px%ZsTFJzPXd#84H6cuM-JsDa;$JaLy#mB#MxPDs+N>8w5`lpA;BZa{)EP=1+Vd@
zOB(P8n6&j8;bV1jotkdiEsak#xM_tBH$|QVI at n|zLTM|NwS>#Yfe%9X>n~BOGipl3
z9QKEGKR0z6mUL6VTG50$Ir4C5l90~S>6_RJqs at xNUY}*;`N__K`F<)LJv|Q_m77t~
zSpyy9X!q;x&9f?9z49MZm1RNv>n2mNk3=x!JE2*ve`19O^i)zck8xTM$3BjWK6#hl
zeKo|E8~mP&6*Su8fA_g;80q>8>|3BQf#JQUrQpHjU+0q>j5s)c7IR0QRUsHF(<en|
zs=8imI;D`ix~Y%Q7j7O@>4?odeByw^<&#$ad@}-?S&z_G9wrHRzlQg8%HApgT?=$x
z37=&-pb9KEH8gmUBPQjfLiNgf0d=}sv%abI_8UYe9Ek)pWoucqV+05VKc_=y97Svo
z`vpQ2BoMIqHVTA><B0%Tl_&x5Qs}#x!>WHt6$bpk9D;USs22T8b$*clG&3L84p+u(
z7kH;XuG71gtMP~uJ~cTvU#{G9GB-&#ZS1M5qhUj6O`--LnWZp){c*ciy&`hPf#Ncg
z_(F-hj&T+JB$*H#?yP8#yaMmA?bo59&3;9bAOEzlmFdt$!g-Oa at C!(B1~+?G&DHk{
zIebqQx%O__y;}SyOA5?kPs at M@H1i7wzc3zpRs1PlPLX3B$yXbk#qvXujhtw9siLqB
zUX!+1d6V{Vl@?~zvs3_1>etmxgx<rj@|OLdi(QT9RO+-<8rK at Rv#Y|+ at SHur2<cWN
z at Y5`&9vXk+?`P4+<sKKn&vgy9ha;><uAap_xZz&h-|{sy$Mq~ZQ at PsB80W|vjuO_B
z7bih?cN=dey0oPQ3qHUk6}dL8bXTVqdJ~C9p4DB96BSeF#$Exf4C((W9xR{EA~T2g
zJXv-wop__I6%M%KQssu-6Mh^Z6!eNx?S{D9RHBTJjh#ikG$AiG)8)UGM{{z^OOl8E
z8vZ=%czSDJ+hw<Vv1JkM`s|AW8>Vdcb;^+#%4E-ZMA5(g!JzSXCI^ue`lWl!yFC$g
zyICus*sO3#_koH}DZVs&*UeHw;8qEif8s=5D>|2Z1})qHJ~lD)Z5gy<=$==uTMUpS
z$Zwt at _R;grzna!>i}agaf8h0}AgCi+P*TgK6atsax^SRxe=iOR>;x|?4`-8vu}!Ck
zCIyk0<(_xGO$DX>K482nXQaoxcMO)MCobWxNp<Kc_-l{wUCep7TYhMgF#uY!{=Dc6
zzv!TfyGv=_tmwEne$FuQZ+Ph<Cm5q4_9{9o*6O^ZNZ}3ZSBCN1M?bZ%n`abMr|?Nw
zJz`)XRziUD4>1;PkTXb_N3_~Q at 7H*>{`0+^oxOb;rIkP>_+ursq&|YWsCd$rG#K}i
z7GD&}S=v8WYrkwqM at N?$SUS>8m at y^8xe4QZ%0T!!HrN0$uRr770LzW at n<V)}SNU9I
zIdLoErn#CQk6^shP3E`wR at ni@tZ|Q{b~fJaegKq{o)OCsY^hruPttNOsIq5Rzu02y
zOQI1oqMRl!78qE3e1{-UyGZ=sGrs~1lXz^uYYGSz7EWPX&<9l~Z~Uv&ORS9VE+ at U0
zMfmZ}Ks|Q`{4H$<C9B!w964&muMR}ONcyQBuL8NLrHRy>xRGM|nPw~5yhPT*HP32`
z*A~W0c57?jyp&|en;7x%l|qVg1ID8jOrf?;?hU)9!$mTZi`e>+7nb*#XGQuQYbR^2
z#PN_yUdO;Eo?5ZIeT(Asq~%iPti7)zkDb;i8&a7W)b{^W&ffr<j=NH)U at PWS-2*8n
z12fTw1ekLUg~hOD1aovv{TX at WETK#vQQ`yn5mr}%&76Kf*cb%y{+yKR3jp;SMyLx)
z>LM6rf_3q}4LrVg0Uzdx7%#Bsu`KbZOy;CRi1$*LauC2y?g40js at nz5A^-ox>b;+@
zlK7vVihqc9uyN5^q at 0wOn`}yKU&U1yVbC9k;3poC!(mYlmGs~*aOKifP@*6q*6r=-
z$jI4FjO{m6$H&|c^26i at HyXSAN{82OC5`w9t-tR9i<_>t5WpnM&%SZ|PkVIf;}2<;
zG3U_Ny^<8jMwrlbn>(+U3 at Gbkxv&i~>|<NqjC2h2XPo>Ih$;GGNt{ZU9c%KsbpBnc
zcI6r4(5uUKffiA0i-nxsq2x}RKyoVU(W!Tp+*+L73*oRi9f1RE-Q(Z at BJ2=v4U%hQ
z=|80+tLdBejO|ci4dLOHal`4|B(z12`sEVgTCsxmqN+oBV0c{Qb5qYBv&<8!I=exO
zV9r;=`W{*wHY)RQc7ubm{CSpt+;=W}R`@<}E4c~I6v=aDvA7}yuU6qa^Dc|l(ZJ3*
zT6PCK9}tJUvx<Pl;m6b2afwT%eW%`KN)7Hl(Y~BLqm8d>KZE)?yjJWL4=bOKy%Bb#
zE1(mBIUcyDh!)ha=pN{Lza8T~A6VW)YcxH|Hr5a>su(ENm@(4L_$tO2Mo<Xj#2USd
z2?%1oZr=8^aRrUaou-b|pW`Z0q`57nZrtf&@fjeKcIqZKT-QVlO2MQJhi-5U6<)g}
ziP>VepEnqe%a-%Jb}h%?e&kIFhoBs*i&l#>=^E&5RM78o$)zxe_v0?`c<ufVDnKPF
zSsljp at J*bQk2r;dK}3Hmp|aj<qQ|PaF<SfLKwAX31_>0jJ3xxw^{R3n*-oF=727~-
z5~{n?Q5WWHCF|uIvrRA5Wqv(fO4k3+G5D~()BMs2kRog*1xxQEIP%!dp#uScYF#AF
zrH?kM at FhmbU@sxu=wzlpH>^?iDL~^l1UaGby}7n#IrdA^lt0OF))11Z^NSBYq~_*M
zPPUcoLwkqr343#6NJR)E%S#+bW`5gWFHCp8zV&C!(==RtI)>zPiifmh at +JqS5H(xp
z=?EZVXt+cgwGE0USt+%vm#r-}&J*JhxNg1kxP20hhe`i+Pup#ZZz?yGXMdS89g`GU
zHmV*c);f<audh$9#zc+eSLzE?xI|c=?d;1!6L(ctM=bdZwft8GjD`=cswZ-!wN<AW
z3JugsiWg^?B=(5a)wy$I_SnmD7yK9e_WS?+#Q&tY)c=;k+p7t43~Mf_^BtJDV2Isi
zRy2hwW0$?Hk1nB`O_|yC<?EXuvZxYYPu^;e;}eLSJZP4XBdw at jzkfa&XFgU(f*tSt
z9`od|!O_hztCCh-a6GL?yD&+K<5l{r>Cn${zh|t{#TnEne1gRn)WhTLjLuy{j5vF{
z>6d@@r>5kI6mWTxV1&QUh$A%8Kt5j6DV+$w8a6yZ^8u||zcoAxm^<KRN|`i(o}6!8
zvQ37uXy?X6iNm8^+QGO-YAt{-em5T_l|dOc4AGTu;-i}b7kX|v^puQ%jKi$#S0jfR
z$q{D?w#GV#R9zl_bouJ6j;H5hT*;<WMxEL}oLZ*#3UTI6U;!B at q;k8ZV%v;cwokC{
z{8m+?<4OQhWcK|>jv^air9CjzWhn5AMVZW0{?l&Z!PB_d=ZQ`PeL9FLYtpTJR~W at 2
zrTY(zQ&L#jvAugUgPSX59pKAJUhJN4Yxl}{R9{d!OQFC9B<*TAh}U44zMB2Vqmb8j
znMP=H^KevOx=5;eAky_Cg*%Od7?(i$K9)h8Qqd^Sn|~#RQK}NPhBa>XL(c^MJm0Wv
ztPRbGi%;{rzuG$89vKO2NwF-yW?>kc99nf$eAwu+uOvb%e;|X2#a0Nsb&kx(A%zhi
znDRf1x|kqL*=uzz->%#(M;kTJf*upq{QkiXx52SK$1p{`)ZYVid`~w|Sb5$VE2ja?
zi5#{%@1m<Ej(rcXkfLzIb`c??Hro7eOHxDFh#i-%!YyLoj{9rEyOuQ?Odp+Gvvm^^
ztqH47fme>}Ow_0m*WTl$v2dL<;^EG4l(4Q(gTh}dUoNV3Z?Uf4sG~cF52nvjXO_~8
zNh27^Q_G!1bRwP)GD{AN&k9#Zv8rhB`W?#Wyn- at wd)6&0z}#x$bc}!NIA9vXM+&T4
zPG5DCSeoH%s3ma>7zlgj_ at x9EW1EZhbb@h?07&w9%uVeAA at Bys_B$~F6MzD#_7|@f
zX+XonrDuaNT82kk{wmk#r7#6Ne=o~u?0z?+I=;=I?BJQ1FM)zW77Z}7E&+-Tao^j2
z?PVS)sVmEo%HkGRna_MnUVh%*jaUDU*AYN;4JDb%`T^E7?_7a!*k~uU3Hji6h=P!J
zH!E5-M!soO?h6ItZ*tA~toD(P>n$s)L+sy&ByF=8Px%C98og=r8qeHsYZO;@o^wr0
zlr=AGwRP}p<rfbxN71=wtB~542`U|4lc>9_#ypA6m0cXRgMzB+>K42w0ihGLZ5T&f
zgX>av#hh2RS(uxrM*%fr4=~@2GvrZb`~yaj9uJ;KF-!Xj6V*J!{&PXXfMLq2tV-Hr
zH~|09qfv=?tLTXMPhw+onGM6tOSq+KKy`mrDpDGk2ecylb6&E-a6 at Gc>$}dS)sj7(
zad4me at VW7L!^g#&q_;@~a(q!7TTxB7nw%eQKm|+(8?tx{UT80}R$Xn*e`U4?SChap
z$|tG;-jjTBtz2s^_d`sbAC=zh8&vB1MUO6>&VDU=l<(-SmJ7R)Puoj^t=iovsWddL
zO734H3(qAE{D&<PL5Z9yuN2!&yTvf*A at PY>7O at X~|3DWa at 82NPq`_hc5%?RwH(><#
zmBWEsxh04g6*AY$jI$U}t)^??ch7O)Fc@#mo at Qlr`a?1wHY;If7hy~shw_0RMXqOV
z!(*k2(l`o1@#hEvV{VorteV3`5!%l!02wMrWvQ(UkGN0(!xaGmfs-YYj=@hNFS8Go
zV#aI#A5CW+)%5$maU`XNA5u^dRJuhJm>`OPbZ&Ha_a-1MqO`zhkQ%YUq#2A9P(ix8
zq+_EI5d6LUp7Zk@|IwrWydR$DzVGXGUAJdc4HOt>H()VL3{ywbp4R{jKV?B3%Oe_`
zrv4tdrB<qa$NKGofg#q#&;{E$;AvM4cD3+(Ri!6;>Rey3lF9RhnX2o#oWsGXSW2+e
z2z}fQYbr10{(&5)t=xO~sp~2)F#uwO(PAv6VLIGpNX$&P>@tW|nWs>0HpaGC=>vqT
znrfJ~IQWA2+}yb1Q-v*EnSC{{fSTPMcGA?WjeK*v7~$JEk*i&A?iPxz|9BiZtjTda
za+yDS+RiRl^Gt- at nG6>W<ZOI+MsDbDRv8l#z0pJDK2aWUjkR+VzisV?_T7gkD7GAP
zPN;ePG*r9_VkQt?onOKn67 at g}0(Xcbr4IP-wZf1S)|Z3sHL{rH57G_+cBaP&9V|pV
zCSkHk0qkU!ALHa(RWgFfXvN4MUPWZ93_Y97^XT?lQjKyxn_fUiYjHe*HQX&qTVFXb
z=F{FQ at sX2!SDqLlpU0 at w5tqxwa|1NyVmWbMmpLE;%YJByzUf$J68)u{c7r|63Ce8n
z$<@!OeIuV=qlA&KBMHA1{oIw{BF9_zQ^9DwZ{Frbp0oV7l8XKut8Z5WuMn;GLpM2b
zkDF!h2%e5esa90t*5tpi%O&^bb_=ABH+=1y5C1 at k(jSGH3vcUt=_BRD-z6=YG$5 at 6
z(1LhA<dn;F%Rh-L&pZqMh8k|l at Y^3S)4Z$3cCPkI3r_Z_EDuPYe_jF+#(RSRY3iPX
z&b7q~C^@hU;L2dCdveD5(nij{_t-)JtxQ2Wt0-)9K;R5p3$rQomGe?=Su#$k_^XT1
zo*h4w&UWl#zIYZ04VAdgvQ33mB<)hdX$n7pon at L_(o4HN3!Nicm6Nl$uYtZ^WVP-3
z<V)5)K at X$IWIG3_GC8K6A2F%l<Y(D0P=2R_3`J=M>7^;+6~4yda53^L at EQBmk@cla
z)4$%Ui1 at h;nujJg%p&a&fpi`c%PRkY)oL9a_eI<a>GSH-5d|WlzUlqjCBhS;7Okdy
zjW?y#?OV>09TMH%kSI}9y3JDO83Y*w<9O20+IL<l at h4F|b$3CeK$#@?&Fmm&)9iA3
z&Q*|Rg*@Fap!UftGfx-ZjtuI_4NS?!e#L~)O=w;rXQ7<1$>1fJJ80hG^Yf5a&&|_&
zU~$X~FcWlX_tZFS&hH1s1g_+8L)A>x%A3#Adz&L^#A7vzj_7qDf1RRn+L0iKHKqhK
z?qP;+on0O&^@0RUPGjIvn4Vro&5BS>9j8FIL4QX28#+N;yHbXdsUu#Q<EVu16U)F5
z-$(LG&F$dzg+eo5|MBp*lb6=XJ09aueleg^^M{geFZdGuwoT-ZQ^{+PbbGm#Idg7b
zq9%|SRd>vu+|`{Qu40o)R_NENY6WYV$Tku{EPWj)ADg)$ggzPpN!H^4jL{34z3G{I
zhPumdVP0~y0&<#z=Ei`JmjRv!+7G-lX9hSgVwDY+>=?(9;-dP3hXYDCSMS}s_u0#s
zX*e3JzUeH#mHFgg{xe}0Za*MVh*bc*81UT%phm6*iP;-K%6;1hDC at Tg=REi!Y|Ge7
zJB%<U{$fF-Yh{!Yp8jml3<MuDK}MG>Bx8RuCIikv*|UUu&s#runPuTAe2BcFtkta(
zx{(!&vS$OjT9Qy|3Nq`7{Ke~*#>Pf{iJEHTEd}&IvfAv=6t>EaIkyjFZ#pukYgnhu
z`-t_V1J=w5$h~jQtqm><g8 at es-`w+Q_4!(aLOee&- at iWHo0TY;CTdwi|Lroa=eVuv
zmg>CLVTFL^7Fnt!Ho{jz3yQ<*d7l0OpB>h<R?zRYKPeL?Ohj)_guV?jc~9;qSTj0B
z;A-lPbg`oNGm|mzoB8xyj at FXrqaWRZYzP2+oJ)hWXL`KXS0A_I2#5Qo-425xf!(wo
zeoA{VlX2MnXRm36+>o;eBWJJK|Ljo+Zh?9T!Aw$#^w=(+Gk5OR+K;`h9t73rl}W#v
zk{5;YhQ%)d+lREgfJf7r5x>RfI0_8Y at xX7s8%>u}9rIjg^JtYE`h1chze2eD<N&g}
zgsn%VMNiIe`@O)W5%P<J!dl#3w91{SR=_FpvmXd=P$afX+VMf{`faH2WUsu<X=UI^
zhq0R8BYAmYV3=Y;<2kRQ1N$qiNfltiCFulN_nWjl6v^o`5_1~qeT3u4c|Mnc`<z8u
z(SxfkV(Wy~&lVtZGR|FJJDJ?A7Hjme at JP!P30TaT4x$F=cD`~OGQ$^lDYDgEK8fo%
z$1^!7(gUWi-l-dvH9DMtT6!#jG at S1E4=$w)AZ2XR({2<1C+Dg+H_QrXxo3-1i at bAI
zPp7BvM!u~tHcepW+0*_27RWG@`C|4xz<6)od1u(at at ot~5rEZ;Cli9x73ajAF_f!G
zNPvCWkO;zdS||F#VxFHgRihuY`ko%Y1KURIUjH+$+Lz6k7 at +!$DsOWz!8g_TnM}0q
zkkMZQ9eWxv(c!+n@<HBo=SaGmzzefV#A;n+={bT^QIao+(={X~wv_p%LH=WHwrtZ^
zk`+5kTTcS*PV_^klombh%b2Oj(Y7?EDupPv$Vb^A5d(1*Pjh}bv^(y5S?p^DM{X2}
zW&N|K5&4gi`tK{K%UHpNv&{8LOD(nY&eXvOUOFD>>VWwl8W47;yh3O0U?oLfl=Zq2
z>_b}wrrvAqEH}keAhLD!MW`M1+dH#x=yK#d&ZR+ff(n}c!Pw|*A(nPzF=a6&pwuIF
z-5>eswxyugo=>%|;rV*<D0W+?*D7mBhL13F$T2T^c6KJZZc$Fu#G}Cs{wq<lR6!lb
z6&Dth5X~~>#9ZF91I?W1t(h;DjX*s;58mx!YKCE3b2)T7?ryqv56Ol^59e5wUg!r!
zliEW6V;Yt^ukj^!+enjmzjIe4f7ocw`bT>{rJ4iJr78M at eQe!JmumMLR=JFls&&cb
zG%b`ZzE7QAu=h2L=1DYfy9wC2J^zW<mc$UVNq$Xff&+?yCmOmT<1I%3sIZH=^;Do@
zMnV0BbKr?0b~+pHz;h;@>@XuhYdGb|DVcG_NW40cOq#H_YRvghT*XTnGPfIl!69tR
z1UDp_X$9()n9TugK(q+w%bg$a(Enj~som)_$WMJYCuDTsm++j`+a1?ZY-f$SR~Aqt
zg(s1{2}-ON%^~<|%tDf(|D^rjb#>5tkC4rRnl)I$^vO%2b}lE}BPgxg7U2cq7PL{B
z0S!G%`N*`Y8e}MGU|wo|Pe8ghdPU7^vk#T?%zcXqdRzARa%9!}r=%ZNC*m=;=ue8;
z>XpH4ayqwVRw;CT+q)mCNi`3e`V1m}2rW|SwGhkD7|_vDOi~@I^Q0)6dG24jjb{oO
zu9-)^82rG~f|#2a_YX7wlIQJPaai8FgYzr|pV`!Pb;^$lMQk`}i1JMbO(&Y!mF&>z
z<azcxbcn=vG;wf~EKT-VR<xrSc`JTwc=z|?B<L at mWQdh*uIDey@^ce9j8$zZ%GhD`
z3aI;W0)jz2cjV2|ikZHTbd%12mVx<5N<qU|ZYMqRYPu<S0JrO}vZW{6-x>0E%5Ii*
z2%|- at C7Uu&=#9Y#3%yR^S*^Qmks|s;4%cd0NEKiHx?0L~?STVZ(Bz2Xvj^KdOE~YA
z(hs~gc at obCe$@r8Np8!FSi*<e)>{Ui`C%vG(>^8+nwt<0IxZ^Th=)weOf{q%&gmG<
zLQpZ_)Jode^MU$>*gJrT-rj}UVA{Sln!c2to#S{)=wR2dj$_LCSzUvzd2?+7$`qWb
zd^Lwr82nCEe6z^qxGd~2sb~eXfy11?fK0Ws(s)Is6z80q`LO$!=0%Kj at hXh8E)JkS
zg73}&%~V%%Va-P{w0*a)2k at t|vu-%V-GBiqu*_2*S~Zsd0sN+Rn_^_|E(;0kci>1~
z1Dbjk;HzLkB`c4rM||U0Vs75sAEt0U`MI+vZ!>G|4sv*26fibg&{2@&3yP?(Ua>MD
z+`REwK+*o4eFymwvAcyP!bH`-tZ4w0BI`ou_SX!5BsJxxOdyaKl&ilcGcGnqePG(p
zjGxYQYxjAf=5=5RSNN$Yd|R7RH9(Vgq+G-(zqG5S$Agxr0b0Sxrmo(M++b=qZt-LH
zm^TTMWz~b;>R8fe802__af-;Zrh!e8dLy)+aABk~75;F1<A^<RtEzGKe3Fp at vix%p
zgb@>yI}&(`S{wh>GZ6ljR^Tb^YZ;#vOIL?e<JkS6z5TjTu7tNe{kc(-OMx?NhZj3*
zIwX2GV%Wvj-oich3<KJqD4{D0vvDqHa>rI1Ct<%B47^>kjgvcwB6^R;Z=z#Lm+X-Z
zHZmj3dqXo at I+@D(aF_5~78Ph at g`q4~!4HJWc5)Zy&@s45iDGLMBaEmGcquNZe8v*T
z;j^TATjOTGCR+8G25DGX5z7{_rfIr!`CRKs=3Y^%WkBa^v<~#(Id}%1vguP5#lahY
zl80g^p>xBsItSq^pqLzH$!>P$u()pK8{G=s>;e5#(@!*o;*F=0!ppn7j3k(EGJgC-
zK9R8yJ-mDV_z7?#w$*AJ3Zy=;r>=k)sJ)^Xtz))$UIHVK4GFTD-$unRfw^AMJnhC{
zgMlXdX093U+`)q6-qib#X^K;$eYgTXfm%R#kemEEw$cGi{zZ~AoXZKf9y{{8m3)pE
zzxJY}ka_0WU%eXKYh$4{Ow>&B>TELXHsZ6f#_lcuGOnEuQrVIVc}!7mVl1)akpiVs
z+7-sJ^URH1huS+0+Pr~+cT@@ZqjD;fx~U`9AOD8 at F$zZ7zRq?cM87u%$lf@<t~scj
ze1rLxkPJGNF6;2%-UoKbH=Z=_z(34C^coB~EOYVMrg6Jp(>Ci<Y0Rr!*SYeZwK at C$
zS%AYf^ycHGN_g$%R8!3b-}8m&rHS+QggM(Sr%QKk!3sybym#t%s-Fu^{$<cOv>X6v
z*$#ybf+kdjt5HR^UljIvMlTm2<4+UOw(G<fot>TCVJ(+vt(38v{!dfOW%3_TF6a>z
ziu0|K&$%{f+wXS7-1_%&rdSOfko4y`hc9ZJdH?MeK`2Tq<c%X;*A at Y$*EaOW$*$|r
zY3N}Ohv`83&0NWBAz6jWh8Aoz&a8><o}8&K;pby9ygR{Fi*L6&h#xIqsb|3}h#y#%
z619wKC+*P065bFtetl06y<1E15S9p5TfQXt3CMH(Y?s_LYF?a|@e<8q<P)oETWoCs
zs_Fbz$sSvZz?_|_i`tiMnxAvVZ?w;+0kfHP2K;6V at PUC(n|p>wO<in2ysC4`mqCyb
zU~<QdFLEWYXNgVMB~m$Tpa7<{^Wm*vYIw>84&S^DUjecIqL}%6vGc`YZW(?vlU*Gy
zr<k|H0d;(tPzLn-zjf!hsM|^H9G3o7bmAeOubA;e#vQf+>_;o{+`-H?vwPD0IZ%Yp
zqF{@QxYFFRX%l$|aQrvwB&30xGX2MCf@{SJNcpKyv0w1dm2<^MzrrEj+GTPz%|KuE
zjLzLC->BW|bzsLtp5s~wor1qn|1Wj at zG{d(zeVsQXFu at 1I5!jrnRrrX^Vm|eN!S?M
zxwdzxHdXj-S$IEYCx(kPbygwnBc7UTo2q<=5I-%i2Ppi`s2EpxgaKmEmuR?ah|1Ez
z()m5|S%HKE$iGn<rQ}fkIM0E;A at 5<_&m}vi$+)tY2@!+d4dXuzeCD0C(5i>;*_&$+
zLS|LpEKq4<ve<2hU(JG%g7bENlV$8qjNFewUSXlm?oc~P8-~2;e(wR5#$9g=@<|V&
zUPkZZR0|9D^QWuZG~@CrWtKtL^?Pn{Ca#q$g1 at yPTKN?H>*~ZUgsYs+8Y-o!3KUT^
z at tqOc(`Qg&$;NV)$hViOyQ<=eRLHER_umH$__)l-p3+%5Xr7({tOd(~&yJ2o=Edgk
z_#8r|nvv>JDaXkCaeH-O>j`hv!mFXLiA*jIs*f|6iNGH9x62Pc=LO}p*K`}A{t%KV
zaCywP$h!piv at NjxXc|)?4g*Q2$wxyD^rDgdtknZ%sr7>R-xnu4M-DMy)s8yLqPNXe
zvp({3`7*XwhCnS%|N5-Xx%ouG|ClY+eb30#DEltn6YB49_KpO0nr3Yd4$CZZp5R+k
zo8z*qb!ptF$Cw()qUI}pV^`fGDHxh^0W?}MYmS76lP5{gKHF0niP2ydMvZrQZ>%Iq
z9rSvBCkk>{%9aJBDrUe3rux(GGf+cKiogWxjMT?6npfhPN>h%_)o(dOgS$o$hN&a<
zaB20HAY6-MfzX73=H>kiCol$7<^JyQ8Q5Z!(}W6I1Ah^b)w`V}+QH>;ua{ZAMfMxl
z)BW^4 at avMk>^$}DY@^*$tKL7;&b2wNm3u<bh>s(W%N<Q5?|yh%iD0$?8w#Y%9Ids?
ztR#zY`nh&2lGx=WuxYyGr;2RU$$01vtgA50D<Bsbh~JH7p0drHo`gCl=^RNh_(rX(
zem~r=$?<rZ at 1TWax|k{bQzyAc)Ee4NRZ#ooV%<>u>A@$S&4o|j);czgrOODAi^<+y
z;+Bu2>(Z+OY(ivC=v03(97r>mN!0{=Y!3Hhc#WtR_{vFEK)>b(hR3(BL`q0<e3cWN
zOmL~@;KDx$nIJ*GcZRlTgsN(Yd1*sOrwm2O$|Cn>dRZ4Y$|cs8gCFV0srZ6zo-XN&
zBcku?gC?w#4~pks-$0qU*;%A%Q^&>)M{`PTlsTu90om>9BH0>=E894;r|l97e)Y+s
z$+cCm`$%cyQt5tLRTuFC!62o3alj2>_GnVcDF7xcqX+qT;4+R^{X$m at zPG&J;?V0E
zRq%{C9<WdF2lF`B$?dnW7S6lC24cXPt*V&uWp*a9Zc}qThqrMKg(s~5`2$BWZ?j5<
zKJ&xzlmqW5TeA2Z@!3H8z%4W29`n{pk!9!{E&l<;D)ezz==7PBE7-i%kQ27O;>9W`
zLYbi5bTAMav>{QO0q}^ryV2m&OVP1D<6$_7boTn-1 at dPlnb&}p5H)0AoMu)vGAg1c
zj8oCQ3c=o15`RkFZvR!}C0d%tR<$_*t0k=zyaF(=WJ6~QcMXs2V(oPs{GR4 at 6oc^2
zJ7^iZ$RQ2eaJw_>vvqAJI(`Oazbp3pLVw{*%;Qlr`G@=e?T$ax>>wQ%p$SKX`d*`+
z>4W(Z)+yW8XalW#+!-hIrT!KgGrLk3&*@|%K1pz0#N573w!zU1BV)IOG{HJvG2LGq
zoL7S&y`E3w(^fb?l$%zPV+KgFj}K*6WdiNfz9622#Z`63XCE%18VxHD_DBavj99=u
zCYm3Gn67e)tjN0zoovqTap{g|nWC{hyrOd+J7bG+y at ML%kaC`c_P~|VO&u|L6-&BH
z9V>Kc1O8o9VT~m$hIF?LAiHYlzMuZK&LRWRK?XDMzq&bCX$G2E6`(JeYvCT5>MB-y
zyR+7|WXiFW8mW8c##T(W(prv_-!bp1CRaYlm#`~e85D^zxn}hNrkceKBLI*d at MeTN
z>Nk-VU<=!;y)@^lF4^#voSvC*1~?z@?%ZsToc#8+b^gL5&|k2gz86OfzcqzdluL7T
z65 at lLUlcIA84w1D3>bVjB{%6;+>_ELf`$`!RLG;N0QtQ03edw=a2Td(AWCe*05DFh
z)&a1(-{Faxu1ZyL2k;Oj?M&3GtOsk7e;5n2$@H2ghAL~$3GTeZZ=4dUnQC7<an1St
z3AZnvkr&hm{A6MpU^w>BB}%71Kjn7qcFn{{dj!dWy+cK8W{<nnm}*<zi>6oo94@!&
z9V$_C%<*@x$yhdQWo#_9Yr8js1WGo-5lOn=ZNV>et&2N6#A-*@v^THcew>ui(+w`a
zbu-<d+r&WmdAPR=g)<y*C6qfMmL>#xat9}%L9yyXeZO}OXP5sDCy>TNt(hNB2;U-o
zBPEp#ak6!ifNDWhYmD6|2i{el8Td~N1o8n(GCLP*W-Bx3kuf`wg)aNSgB!x0iOf}g
z<*}8a6I?zW`D}k;WHoL!0M$)y?ic?X|EjNW;xQK=p3d}w+*T$loD|6`LC>lAIiD~0
z<HsVrac9}+?J?;%W+nmd3eNB&`H|t&bdP(?u}1n{W`qTbiM!qnSyl&yN2IzOXZ}?0
z`93;RXqjKNH>xT%_5GaXxGMZg4pLB4(0$(!t>O0}?WdWZc?<{WZ-byYQVMDHln#r%
z26$50z*ED at E%o=R@;kX$W$-JZ9}9AUfVyPKg?&Gxl4Oj0I%qFn<ee6@>>#P6mLY)G
z7MaQjA7%oW;@xNG9CO33j79mqzEe>E^+seY1AgeC_n<4g+^><-MCXqnOM>*xISqTE
zApnz}x(4Rg(K>I*6A}^z={E|;fD1*p01(q%bb!?7mNyQce%#hW)nOI<{{oULP9OLW
zk7_mQ-$&(W0RPao at v+Km0H0$2O2MV#mx2MMz}(|NlUHbC_m;0vnp<~fxb*}8ui@?L
z%eTWBjY?WmF&Jtr^<t_wMYL%jNFF9uozw;S>2=hLfOQJon;EQOciBhuE+rnQKV-Ru
z6yAJ=>$X8|Fz(XMK`m*mp=W5{@q7z(jP6a}vx-X;Nw4>vv>#F)*5C7cy*UJUdt(Q^
z=Ju{~&M<=YV?{w}X2cE}yBNOY%^-u^ae0r(c>$lOT}HA>$@z}&7qz$hXc<9 at 6CN++
zf)TG&sp+2?ugx8$c#rr!b?Rn&C-b1Px7s(6*!!$ZrMcZEOkdtB^DoL%sVrtMpmrPi
zRR?zq*g)4#b^osCSw?Mm-Q^69erUGrZmC3-LD at G+E4U)3HLxEyVA4G7O;A`-C_j4k
z#BBu!*KV!OQF;OVJPJIoAF48XMQ5uKay8v;GFfW>V at E*fQw^UsSquNlG(T9nO%3cz
zaC%viX^TS;E1`es8j?!2e%6~DeP=9LMqGR0RPktg<2DXSiq9ESD;n&=0xs{QXaUc0
zk}_fm-his^+!fIIdGLhOywqQSe1G!|5$+oMXt}C$#|Uz_aOZ7uYc)fC)RUOz)p?N8
z+K?nSKz-i&U~FopJP;4Sfcc^AQ&JwwAl%E|>>W8#{N|e%4AsmFLYe78|D5hiApVLy
z9w4g4<Pe|(KLDMU1M&gww>>~04N8m#o8nFm(PbL|;oKeZh&WaSI5(F*zD5q42!)0Z
zg5-dEklNGa=<mg3n|p9MW4-_-$f at F@Ot%ZjGBAJRU0Pci_JpNI-qvUu)R+9Y$Sf8r
z*<@H>MIaDF$MQ)h(8Q(h3wvY2jsT at wbY@U8+B>n5B({)9WfFCs#F(b4>mlCr;5f95
zO;=F7WN_v(<7T*}_DqU`jdv)LHMQPGu~i`n##X+K54!zqW~8F*SFrnz at +ivXTMU$s
z`BfUxwp)#)$UdfMh1_5HMxskADyI4ujDS+I3v3NIfNBN>liQ3ZrQr25^|;96%n+~K
z#Sq~IPLrFo-m9{V<zFY{VFV|_9Mz}wAO!jI{)N4q_*U$4$cqFF{?a`xPbJLk2Kv}M
z<Vt*--s8k+a2{^lK^!(Qfw#XsVV5}Kk|sZDc4c<=hr!pDr7 at AD8XuqK(<TGjCuIO(
z<R|HL<d376l-6q+?XnsiEV7sx8Hfo-aICUXWcnJr<+7OvnFag~gi(^#4?_05>P!Cw
z-I(N8QX`;slPO1Xhfkf(55pZ9yvuTR-^UI!W9R+`;z4&rb2FcrSTaiN9>osl?sT)O
z$?Y+VV5BV|fM5Js6{FH35PERa5UgNr5U?@g8HGygW{+V<)d(*O;2mQ{DjRS+Gik&R
z at ue9RwKW4gyTSU@zJp&Jjh7QKPUsD}OP+rhQH>lsu(RxkXJV40^2<OnaFksNK!pj}
zmhLx7x~u>W<0%KjcJn#BP+H#NeIu_Z7_+c%FW at 6xmYfsMwz?7E0uZNMcmt>UnjSl<
zx+wsAp393APhQW;%2NBBAzbwLGUP9zAJA`(^4EbtZYjjm?Bpso{+2xBF%!;v&x4zX
zQbPbU;u7^~s5s~5UvZJOp8b(-zO`4fM?vqI%*TWDH^e%O+98#eqDChvLGP2w*nT;g
z8*GgG1(UBB#O)GgM3gbTEd7{&N8#L#ffNyz>1kN!`Qs<7dMuaw4RXbZzf`k{KG%Do
z#C}3EXHocfc0n)E;_B^&4CdN;dv)E_I8_QA!lGYYyPci0ORwL3GIa&R#x3eMlH#L3
zyUr at Sib(u_nPrKgMaHI++23Kpy2;L`3Z0}}?7yyFA64qC_>b|D<bf7ogc&0rx9J5I
zUq4}$ZgKu2BJH;?8(lQ)&S)Tds27zI26Cc;$je-|BZ&4_&63*Ypot##79VgXhuSAp
zzAZx|cPt4I+MU3H+2`%lFhe88CJpuE8fzYL9CM_j$oGODSIn{@q9LC-!O>b;T2KG}
z{{CEqUfSVi?1tLc-8cO7OEm`JwU65Ml&bGLZCIZ@;2eDwFy~Eo*3>cE0WJ%Nz~=7%
zVnpdLq at YT8_3b)^`Bd7<X=)xLAZL>w{p_s|^yb7lccf)41rX)$Lzu$=k9yf1yl3mm
zJ0NQbI1$H3)eO*kOjqIhVM(WU at cyFG-k6yGP~E~W0IqAGFyn(GrgXQByyE&nu^^fA
z*#k2pbV5)u)~5Xw$b?cVkfnnfas-2yL1f;5Gr6a(JC+ChZEJb?A9NYAKnXXbVFN8(
zI6HKOulF!cz3dz)=I#eH)3dEVsgx>SQDpJ)6u*UF!nn`O`)o1H&!04G_&=(%oTf67
zz<r_4%y3hhg at NVY-a^M_>qo1z^%Wqq%OPzV^;C`So8A`l$A?7?tmuc<WX^Oz#0!2M
z2nAc=c9Yl(otVFPY+ClT`$=53Ig^z0&CPJ11A#(pq(R6%C#a-pd31u?kMJvD8g5dJ
zccgQwA-&&gaYY%ak80)M3{+Pd#$KW<-gBySsbRDv31(rcq$ZNP*<s^l6=9(Ff+j{x
zMK{ud21C<1hwHY>-&4f)i~>W6?j?7 at Fm_b-WW4(>xCkb{<09c{Cs{H6pWqroecp#v
zej!M35j7cceG}NJ?es#I+?nRh;cZ8Q;pI6<E9 at 3wK9})mM#pn+qUBA<x;)w}0pnE0
z4ZcbHLsb=CI%Y)oMME{~C5a?w*7yFNo)*<8-d}Z4XbwebQ_9CQriCvSZ3}-+XFXWh
zNxux*s#`iw&gAcf#lk=u)iQd8P8Ly@!t&U(c{Ld6v0anW&d_BK%AuvMJU3uM<%>{v
zV7unl_Nb-D9+iv>@BSexAprV1<&nWfipY-cd;MwC6#<0Ct-`tTLFKt+)@QN0$aa_N
z%5L^RI52ww=)gb#FEmi`MH~xAp5xTg)gL!J0cvDWl#8bzauW02A$h|Z*J$DZ6wkUv
zK+%-l^q6Vg at qST5>a_@<b{z^o at v{I5A&s{v>w0)S(BC at IZw$<Q1n;KT)vRU!k15vS
zpVzsc&;&p|$B;Ro6ax6%3)8$~bIfvlKi+M^I3Y)z8m7bue_g>0HxzryW5BotSadE4
zZG$6y&}t}cCDYb^Zby#*+P9Q=0^%`CKk2K>74Aay`lmJ0|7H=ob;3DpTmUB$oaRgE
zpy at 2OMJ&sjP3gRoDzIpwiOpLt+FpO3^kw%?0!7MUF$u5Q{j=S2Ph&;?wC3%{YY`W*
zDNv!o>1`;xkIVY`zigYq0KV?&I*6QSH|w$RjKopPY3T7Zl;>>qg;j$+MN=3`p at TyN
z{b7b)G-_61HblT~6D%uTcj+T=@n-5WUck!@Qs)+I2hljxy6aDeXnNN0MvRk}TYdC9
zOiqjByWE}6`FSU+a-x=F&yl)Sc-drk2A|1`Bps(mkbLz0xIr}=iSzD5ELe2aFGIWZ
z=H^?gep6(8j?@_Lbar;ufh|3!9H#y at K@!5`dOV}0xx^$jUFWDjx!scUEo{MzfEtCe
z#`RB5)V{nMo%33yc88POb<s+Baz}5uim1E5D0vERaieCw8TPQKy(||gKTtX$nf=86
z#3;w!s+*l>h1bVAQl^WYiLyG&cur^9-eDBOFFLViej?2vhU4CQh%2TD26T6)9snzR
z+|9o5xrUXjUl5c&1yIE`EgB;Foi&D2(sH<OHk4BFoOnKoRa-J0vhHu~4FGjKsPe-5
zv&85c5Z2ra{0@*yql(X7XV72+N7(<Dx1GbRmZNjfhI|+UzT4YyzI4V2Kb`}^IrIC~
zVzL2+#E$Q-hJ+SLAP?iuboQ~sP~R%wn-{B+c at JFH_Q*}|zHAU&Z8OObbDH96rZxMV
z=6s!YxGW3NYPQ$lC`RAU^iw4}B+~x7Nc!5+NUyfH8uYGgZNWK at 8WXX@&Ql+`b(FSZ
zcT&h$5f(@GAo&$ZKFOde7k)n#H0Jy&P7_ at 2VySnHJ?xXb;dca?XzIkDQ0mTHK2+t(
zGh^!RU6r>c3_292E7^TVWTmLChZaRuhs{n at xu}WNND31rEjY|Bl2kNZaLDy08gu}8
z)-dxKt6G7H8zHp!D^d`G7}d1ASC*CW%M<aGufxhYgj;{^DRPU=8(h5Hl}>YqOgn`6
zZ%8(O106i!e=;C)Al9J+H8%H4{t)zKWZduS39#-CWt<z>_nR;8%*S*QeOo}6Q+o%9
zKbTTeMt8ZzP=&KFNR00lX{5gr85qCU3ol at FE5qvk++EFht+JDnX=k at kQ>l1AEMjp(
zsC%rdTvZJ`o4ISM!5w5ax=`ZPWTr=b19GmL_k!{_P at sgK0G1Y=MBtO6 at _;ZMeW13<
zt}_|2F2Z(ZkRykbx5N*C7bw{(Unw>B2EH5C2ZUkn{FDUdz~5wmvttc&SpY7DVu11L
zBOkQ;JNp^XD?cm>WoNuIS#{I}ZVgwB7;x+zTs%M(bKzyN3cdA|-zec at y<b_SWt&YE
zV7D4Hk3~|Xe+6R&`kNJTOWSHDiYrCHOn3-{H9>rOx;>|{c5A$pxmFe^z-h*e#LtM5
zU3RRQX+YVxf3uX+wpP?iY0tJ9aM>cV-G1wQd~8u|X2#-{{Hf(wr(*XHmer4r<quy2
zn0J|MRu5d2OC(~yQA+xLyOc0^ciSCNvQ*b9!%G!u6cX1_6o_?K^++CVTiUYX%fai*
z^3A)SodLlBz8cJPu`llj{aRjLE|A^vGt}^XV?Le$!ci?SmqWbETpE`qNgM{@l-I-=
zj}UEFr?Zg at e<yOsC)i4j4&dfR-$G*;ygg?9=W2cfsN_-WY-Z(;;pjr5*S%REYs9+-
zP-ZbOM_0gk-Lzwj$P8!aS0AX^-2iyYH#&QDSq%yUot;4j0vZf287d$=O!uoQts}K9
ziU6lFi<ubzJKR10iJ0%qal6?93oF4DFVl}{=+rtwy at yP+bls2xDkRTz#^0KgoZ?wF
z%E<F1E9ThTZ?ww_(00D7b-;WKoxkUBD*z;@CHzL;?#Hx1RFp}F1$V1r^|!^V43{^N
zQ9uh!IDd at RovZp?Q?&kS>$Dt5IIU%{?enZK<OAk(Z~r2l`Ae-SFxXc>MX_7{ixU1=
zoDneGDLDZrWP_ja<}G+E>*3-GXlw4mu;=aVmNDy>g9R(`%=evd&$vfC`W+y^1lKS9
zy6S}erH{q*&X at I6*2!4q@;uB9>1O{Inu5l5*8MwI27+JkcTK#MHN>>GV+YVN;Cc=v
ztKi`bC+eRx*o at i=(eqqTxSzyr*Sp4o4k5=S2X`Ud!<0}<o1y(mGbQ6RgNRUtQ)sbE
zfYVNuC3MmVr@*_INY?57`>FCVkjuLW_>5)Yu6<u+H&6B}1Mb at m;y;|}O4dUy8(yGR
ztlAkFsZ41x;fPF0X<l(oE+)kxXy#n-r0rB3Axy7R;2e+9!MO at N+1pU3saR51RNJr8
z5Hy^7Keq at 8xY+m{5`2A^pQ*xhS2}J)r#CJN!IVM<C7E?<AAdDVI%F%)l+C>Zezr@`
z%6XD!yyU$ULhv74A5+wgRMK=aA$*HAi}95?>%}+9Po2kudIE!B-1>TtdK!W-+V2&a
z9DH|&das at iQQs=chW5A(?ykOa>w`+WKif{u|Ah(M!Sxzk9J%H|=SxRsF7Hx1A_<MW
zKerZZG8wQd_hB;vmvflRz~HlAaz at V<IL_u at x6sQ|A8NiYgo;*VHo><eAWvR7fYn}9
zFWE%pZEF+fFcTqRZ?r~sioW`-qjcK}>kU7;%?bLn<Dp*4f9E%LGtBd;aFHN2LH&J>
zIj&pm`2B3{uYY8LjRG~YIwk)uo_61}nSln>M<B+~-x&Fv!HJr2C0;;sMg=jjE0n90
z4&bBL)BZN}E=krUDxqe1&FQY$LiogZi=!!E<U9N!+7 at Wt#b8Fwrd+SOC6a?aZ(X|+
z<Rf~6;;X8K@~rBXC6!+bR0C41<xjDJkJci%wSS&@pHF>n#7f_eayG_PSMW)q$$i%1
zQj<KLc^gJXmuJXjOuq0c(#&2ElOeeqjC{@gYK+-k?I1)3jbJ*}7qt<a(6WZAxxRke
zpenZ*HqIa=VoSOnU?=GB0m|RkyV`q=M#Fw$6Voi8jSx^$`uc4aPj*$zw;+D at +1md(
zo`9czi8t=!-z8_c6i90B^q?Z#d|u><bb*J!w?Z-*{;M=vOG;hdnDi)!ig1|}0p!4Y
z7O!1rPYItP)-?;1+wIiByS;wynoJBa)F*H;73SB!Ih-e^q^hX$EE|*XBhQO$WlDE4
zTi2~Is+wC&pbeQX#U#ITP54Qn{6J|gg3rJFzHHMGKW+nF^9zH?s-AdV;l5~jT|6vo
z!SeTO7Rn7KFnkFKln-sb%)DDxyNDvt{BCNkFgHKi<BwD1X!0o-xuF#-uy#C4yYE0@
z$~fwYsSdW(P)C-(sTVHRe^Ew`yl$*f$sH$_kLpw=VNQpR7)LK)oZ5@^tG<E4CPKo&
zZ_i*V#|8fa*;4*I1v1{^&Q{`K+}-T>Js at wr6;}+ at tQz<jaCA?7T27<qUs|{j*I{$D
z;T~HRy7G3JR3y6tf=f`x{gC%}16BZ8Gx1+83s6w})5Ea89+CoX7L5Pk#fT-Y7@#3A
z{Uw0y*Km`W;iKq61Xw6H-IoPE7LLR!G;4cQQh&~1pF+6oawf{LK%b+b+~2G2Uer5O
zr0e^HKo$p*UA^>4<*(ct8`(#y1wC~=Zqr(de(ObzPYBza9J?%D(31)LYq9^~@BMpw
zdp=<Ec8~E<A~yqMkCGW?Uj5E7I^hTN(Bu~j(WGq19q?m==&;b*YpR`xd(#zEZ3^R^
z_)NpF?0_hBH at Z9f6^B~U!yRDh8H7Y?iF0_Jq+60lWU;f7F0qzUq(xhBkkxHII&+3v
zxu|+SM7yMpbQy%U=u+ggZ!MG%s(qjd_gsv$JOYl)Q@{i`7;p}wo{z#<_50=UJNxzB
z{zZr{^ax!DWbOYxphg>vyo2QkvJX$C{i3QeQ&T>T`t0z%W_<rb<94#?o#bg>x?J*k
z<PUvmuf_Q=n=_k at K-H2R?Jes{#{UQ=8G2Vrt3TAlpYWtVe68jevRAV=wG}cvfbee7
z{m<nGEHLo0xfreuKC8JZG*oUpso<lso>43-C`w5RYF$u3#%GRY_g(yHWfnfWKFxp;
zul-Gnu6<K5n2}Q5RNtW2>ht~gjO|bjP_u52|3h9lu3pCems<fO&~C;edb&uzq^<ow
z3!u`oB|MkE6l#_OkW)og&w&7b7!mTtMCq`DKRvw^Q==&mz7(Z001Q#g8pyOKYbDGs
z7lMjiE`UD}d^Ii!_Rcw~`OS&nEPvx*R`hj(dRth?OlEH(i}1DX`E%hI3gaNx`Hx@$
zkNK87eXKJq=xI!UAjJwfe|WN^C_eE&9i7OSujkMIo)7*#0@|Fm+sv*FFH{ZvD?xqI
zMUcWT(bR_LrOGkcN4=wN3jad0*Bcgt1IZ<IX;8RDqhtUKct*m&l1dRf9uApou!Jx5
zTqZa0PkKOf<7UeBU54rd4eZ~DYT7(WM%1g*=E)60wwo8pqMX(Q2_{D+sxfSQ6)-e)
zTZEF+KzK95{*(Rk%m%pjjrRdFyGCPnv!M4;Z5^)@Yh1uO%BBy%SQ)7~*1MCwjo)#>
zYcB=iO*^_}s&T)8UL@;ZE#WJL);lpZT$&NvoXDk&sSOi2;A?RovA$pIlpYlo`~X^D
zBEFMf8F=e;zz6iLhAVM?<tVdxi@=h=+#myDe9ua5sXMzXW2um)QPphb!bR%6Imtk_
zP~pirsyZ*d9!ucyYgPU3IEhSQqpMIIHJ0>v>5&HMmT8>!9!&dVaB5yf!BkO?$<{hr
z((fHZ75xbwKT!8xi%AH#hY#Ql$lMtlH*4l*+|Cqathw9g3!yqeU!MQ{b5ui at N$8C}
zSo!Pp0XwjV<2j3w(<e at d9>yk+IRfY&@z?NOAk{?w#u8AN3<CklZ-KCv_0bY7QQ#43
zz;*_`0TNQ27G*rIZLv1&D!@y6U-jgOW=;;ZQY3!?40Bf=)%ovd?6GNipB!O_yUyN$
zi%6hXr|-Z#C$2i>=2in!nd$-Vq9STFu4h;8z?#lcm}O>*oTER$E`mlN(Y^kI{q97R
zgWTJHT{aK557q{S!298(d8X9l--F*b)<+d>2o8Jb3{Mx{10q|v`}<C-o;^2lAOk@?
zO>N0r?Y==stBjq-drxce^Wh+h%D4U^b0|@oN|U|K{H0}pgIRfOXdE{G^NfRLp+1p1
z*R-_a*=s$1L$3~faWtsAm4uEOc`)~biO%t4w!Mfl!)+CWYWj%AwYtY76{5cVP6!)~
z at XGR#V1<d2vZ5YrAs>fO$tsy1&4vcnQ)dVAQt#@assp%x&*kfSmZT6QZ`_zgk<$ke
zZ~K}?hy7XVRm5!wWKAtK<mnr&V8UQ8sM0Iw>Fz!m!m;E~jHG<=d4Q2sq|_YQ;<(V|
zbD^2=e^z$y at CyDK_csk|D#3qpYh=}D(E3c2yT`K4f%o1b#@2yPCfnVvuTh8svIk`?
zftS`&wWfz`KlTNwCkhe4-JtBHhl_ZAn~2CrT}fk=39*`i1KC1NYgS!ebtu^-rj9KQ
zbGgzas64;Ol45?OT}{2tYMotso4?}6N~a9wa=QB-!GLDzNQ?u*<mI9k5_{uZz^$yd
z<ibE!`ZTATT at aT0${wI)<VwO;fwu*+02H!ktv)Js>HG7lcj_WUlYwShMd$F9k)%Bf
z+|aY!^ypeMhNLAp8k|D5D4VGckO~rUKyMwxAZb4*WAO|#b`D%nN3WYIv4!?Obrpnp
zqQRsDKxm-mjP6zcNB|;AKefM{n3(%GVINBm-*pA{)fnn at Hh=XoJBVhpRoj6O^&YK9
zKCVgfay!XIy*p$j18)}yY8iI_2OzSGVe7&G>e6{OzsU=U3iz0kR9F6+jd$>pp?QMa
z*gfb*I`K_*tcc`G%YSz>O(L?8{}$&}slvQ>-ux6YxctPFDtafcv!2#bO+diQW$6%1
z<tbSR*z0JF_ at 7fy2tFuPP1r&C&>h0i&?1lT0`=pQ9z_3TPw+QF=%XNr+1lubl?Gwo
zo?9$Q3{kd&vF-?%+p(&lOuBHC(et7`f+|6v&c$H_({~-*lMZ>g at r|Ywd3VdE(q)=s
z#%lP~KPpYw-B1|jp$}18yv=_TYKRocewF|u@`H7NN^4t~ACo5P`jz7+<*VrbH2uUu
z_jcLz<`u4S6ln2R0jXxW7fVxQPCBLEoOMAhTGULxei&?NC9hRDIjq;WX)rRv6G5x+
zo*Ii?)_I-0ox7jK$Ga4`K0 at A~1<gFTnFJ2xaV)Pwt=tkA_pg5f+ot4cKg~{25alZi
z>Kve(rk;<PF9BTFu9FFhA%M6vm<semVcCGDtmQ)s-&8nd#&2fgX+DZ;@2*c5R4=#U
zB5#H?C|ugyyluh5#tE6- at GLmQX9~Y!glF5=3-Uca@|j$oh*V0m{wPqy4Brh#a;06j
zz=hF8k&ulqwdBBu7fWp*k)3m}b|>D=o(zcrqa5wiy0APF_5?r-7{-dw!n!f$E({Yu
zaOr!ChY~L0GL<FjpDBKjGc^o>X#(N!Gt={{f8P2JGa3Ug#yD4FDrZEd+{Ue98n;<=
z-N^4MNq$<WbzbeUDC|Uv6v4#n`2Z<c1k at O0f1UuPnVI=4SUz5T<&WGcir)>b#M!qu
z+(%~Wv+Nqrc=u{W5K62LMlDepenB36m2Tn&WEGl(H2?wwTDB2^$o8|QI?+65maTt-
zU?3kX!>9SAzH5N%hX6sP|E`n{kb7uD at ssZpJ|p_2W4(-}^~TGkseI?p2qJl+7Rl at L
zqm2hly5^Nj=cMnLf)bB}k!~s<qqeUXHnzE1H(D2GGoiA|Mw6;fsHxBcx at 7|c4}WmG
zPrmfro-^(S7qR%=oaw~Qla>YWAWdeQ!~;W{4C;gBf-Zdjiy{|$!m`vVcCdeaQd7Dz
z5lsz@`3J>+ZWx5>$k(%qppi^;V#^0|vI_dv|Kfm&@~N_JGHazwxa3fwPrp at -gldI|
zApIQ{7e1RSF2KQ$5jMg(IL_&=WzvU`V?B+2&8|1Up?G1j+xJif_DP%{ygV|A;vNu&
z8VCU+yH9~%|HcB;=ntQRFSh<o$P12inzb`iiE7x>{2sOd)Sh<q8yCCx<3K-TUaqAD
z>0u_c0TshsPu&~TV^3Ot<PA_tYLmg7m82P}-28#AA&`wdF*ST05(dt!WW&L(cx!yS
z<D8*;>UvjtGBJW^z=*oP!4BEa?PC9z&Q{MYmV4HB^mg~p7i{NefU44^0)~W>-Rw^&
zogH0?gN#R+W%jb=o;@>N0y6|KpxgdlUp~svnb7blV{eC^7`PphuXPwrmv$|h|8TrL
zTML$2>#ASzLb+-vm{A(8B~&Qwah$l{lKPyKLFU0txcG{EvnN01sG0aEl#c~E{oH?^
z;~_bj{{cFW_O0RcnWq^U^m7*EkAVLE@$vB=Ie4Nb!df9~#FO-IX5?PRu76G}`m~Qx
zJ<+>5 at E#wl{8oE@#5%QZRtzekFUd1G7YJW#o9eo3^}fofo8}Ue$?9y6*4oTA`^%JU
z#O^Ej1^u?px0$SzyU%PC!elI8?fsPZ0&0S=EzhblJ&_v>1Id;?b95Cpxb_>o?u?>)
z`cE4gv<NVX`#r-hc4IcoayDe=@6R+*mOrbi_Pt!@BPF+9X$+pW#)-x_onTp!{Y5`e
z2p_Vw)P$t5<$klj*o#)5s1I4C!u4S4trz-=vJ?juR4_3teRa6ajRB`kvtPK8XnlPY
z at 4M=~IB63FT{hCUf$LD*2~ADXRJ4r)y}Bmk<|AfUu}aT$00S%C-ovegn!nIIWuKRW
zW3rdr+}}vKCj^OXzWS>QKth~d;ps-s8Q8)DcLyz-ejtDLAXvN!+sRsb0j5mV0v4bn
zm>vr|mhJP**Y&9M69?5}js&K2QjCP{4U2%mef9x8{I~jB17;g!K@)!OnC^c|tipM0
z?|Rk$IBPtsJE<IK5r1Xu5a|QR+F2yW8Uw&mEv+tQY?n3AnCB8o9f4vdtOKM4(UxR1
zdulkB at 9+y4B-+UiVz>?JR7=}t1HF{(kliByswJwLoSG_(_tenp-v#!GpuVG&yl+Fi
z`IwyUO!VusSbG at v2U8@?(;!GwlB_)s*0!#V&2!tk6biOY?LYa6Eq2~fHj9o;`UHiK
z-B0s|7aSp)R>M<Qv>^{93?Q1t7_UdHHAyCg5;ua at I6d6m-T%c|klr%+3borC+U3wU
zI~<bgzvbu&q~r7S5hp{Lca at GqjS=}HA0R`(=jhO~G(Y+wOYKC*qmFbkqMW+~@Y=RF
z<RE4?A<_ek;AE(Np)9y at K04^Ot^SI%j`(h$5D)fy1q{>V=wMJeo^P{70xR3y-Ms>B
zdQ|ELn6zk}3T at QnJ^Ca;3VW>n>=fkp!rfqZ)m2uk?tTnJXX{~%9b0rS0KRp`$3>>>
z&9es!@br$?3p5pJcs6YCuc3StWuHAIDO5N=Jq6jKEB}?a{Q!KXScSZ%%`p+rucpUK
z)LpL2`S84+DU$Cw at rcCfb4S^ofso;uzUb2j>;^>k5MPK3cmQ?%7$$5bxS7oHYd0m(
z4Q2I+%6Z+%TUTZVP>dz=&{Lf<^SS>CI7y4@&E at +Ztc)$3UE{pFF{5Pxz^Yqy-Ldbt
zJ*<&G-U+~S^lCVFG68~NF!&&vEOr at WbM2{Ir4i{3R7p83_4Fblvv9u!4X6G2ozc-z
zYG;>?YH0eH)afhUEAu%WnMLd4T&)Z#pcngCx^j1gcH^*qQSd|6#{DaxV7{1MiRXFB
zO#iqz#mO3uQKadXYr6Lb56ljW>Kx0)j!m$I-&+6Opg>>Ca at p8Zg6(v003BM}+dnlM
zFA(^I6?2mvfBYS_;G~VBc6zE)(?`rBoy|V7ON<usrBMBOz8kiZ_l3I1y$(|D**W&z
z3Q|72M at 3GmMEw%!dlQqIXsGz<YaN08`J&Zfa@#w~ErB}3<w<UTt!%SwIZP|??_O%l
z6ZuvbLf%$*)C<SY267H at Tx1`h%t)u#%40S!Egz<}Ae at r7*qg`;8CtexUi{)=nJW8j
z!_+n|=wR?{bJzKGOgVoc5o%}ZZ2#Yw at tK@l>wfGoc95!oX|sYvPz>?}WgaZJBlmrz
zv3v?wT%oy@>_xwMJG9DsE3<xPUe+S+I!uqCfvCOkklL8I?H1Mhdn2^63MZg3QdE9n
z02zSS205L~hYv`ODkMv9vE{6lJy%5}rgV?fl~Q`$NMPr>k^4Bcf`p<6mn*EDVqLQX
zALw4`+iFs+sJL6!gX8r37#Q<97Y8uMRGB-N!=rG6FMfls%e*L>b8gU!ZQVeId|>BP
zqzj<U;dL4wxjzP2<%rQHjh6l?Kovs8t^aEI6&f%)MHO9TN5AE>5=`a8d&&YwqvVZj
zQ_k=94byvff7x<pA-4S5E?uADzy^AARVOmVp$B>5inkUE!W;^)3N?6OE#p<T5~sTH
zoX?#PllZ*Dk%8v{B6V*B$bpS}>~4c64|%H2%2nWit9WnZEudpEZvyfbTs+LB!@fHj
z7!^EVgA6mm-(H^XJ<2cw_Ikg;qHorbVMfox*Pax4C$8O2o!toyI9Vcd+l$||Wb6N`
z3O~=+JK2{hAKBCP)X6F at H|Bfo*RJ2m`}AX$%bgzBFZ+aN>5w+ogyFESJ**g%L2xi_
zW;yh?^iM3pAypT<QyuOKG0Xg<U>OtwN~@Pydtr&t_vH0NG~ItQRdbIen925qO~hx!
z$|zB(N^kBosO4&bvbO1yWHDMg!|Z__|M<5ChNZX3Y`ai$GPaQ?n$bZ4gEu{q7PS|@
zmW%J_kfalT)ln!Cr(CDe6`<TZ13%#Qvl>*oDD5d%yam2>;=iRnY at MNy&CyJLy0?hg
zQf&#~Q_b<()D0-0?4#!c>u3GF)1uC;N at 05jA}xdU at 7*R0&D3RXQkOR?D at yG0xqCP=
zHrXza&Jcf{sP(-`N0={Z$FBdp=pWl1!xTEa+Muk at t=Oh6SpRwdN;%C}LqDgY@)ytR
zg_(&E2SPtdp!iSFl>N at LkY|FBN00oEE(KrtWcDO2)Dn`owDWKNQn)hbx%cI61%9iw
z5C}_u^l%(L*#yd~RbW~sEeEl%bWy$4(!B(BK+I$2fxBTow!!nebuj>NqJMM(ONtiH
zWCQUdp*b6O#AE at t?jZ1m>*<)Q0K#G3XhV2nIFK6tW<3SP?KW_pw*q2fL>dA|4%P+y
z{l~nc=OcV9e^t95RUMa4g{X1)VJdhs at q!GgnFZ0$cUPI<uP5t%neYI+L4HOi4~|%u
zw(VRp!=)CyzOv7Th&tN;N}Z_kLs3B^zxkngLs`t7ULm(qoN6;StZX??-p>#N>F>>c
z`=(pkL6k~9Q!nl-dq?d6UUVg-ry$ss2==-*DTH at Tprg#l8!1`AqbVkjqzF>0UzW9;
zwZqouL%k|j)_IJ+8rRkS^J-D~)ZgDxHy<d12npVT)E(8xzCFVz`)k)Zg|x-h7-9bH
z$?*$FBKV!Ejk83=j0g4)_QLCvR>6jTjR^iI%BKzMHM299Kwxb at FhTGdKJ~*Wvn5p!
zn!vMV$Mb}mlo!Inhqglww;&l`=2I)ch*DMY*)a3SHWa6%v{`wjt}q|--0d%<kzjqz
zbu`)J!tBb|qDDb(7t?Z?*ofs3Qw_!(y-IZ6oXb2O(L0t0&CEIb75kns5A+8Hvls6L
zK`Bn3-a~qPpZF@;_Q(5(5c2mj+#O4RM0!P>U-Xp9 at CG@D5QYK}Z%|#35K3_Oz|vzS
zkJdb*(R>qrGu|T`+#Zj4p%Y&jK7(IY?P8z_A4rag at II+{H7hx9{svf>!u4DCNGS$N
z+|*yQHCRm$#cTUI5`Zx6KY`RQM*#7<cP;H;S-oQ-4BP4Vuymri5o;svt4O(J^{ov!
zcr^5hS=a<syBEfDR?8id^U{?oUtr<@&2YH at xMecw;X<uOW82NS5^uWMtM6c{{#{*E
z2`M9E62(+bfs?@SwWSeA4Yc}Id4h at R2OLAx-Os%GR32L&{%uv}PFjosHz!aA<}~*n
zBSvi8C$U$TKpzux-cxa86*pqRL|ztNai3)+zIVjpwZ#9?bk<Q#zW*Bs5fD&7DWw#H
z7$FL%FhCHIPTA;^?%rq#B^41E4N^lGT_Z-9^ynNZNNz)ruHW<dp7Yz^oWnVLp56C5
zuIqIHWi^o{3tQ|)+CAA+P0Jrlo7sO~h-D!rW&&kgAg2PdIOd?ZS at e6tu`I3TYGGiE
z%VR!l{$>%YXx4NIsHL3xHLYA9q^vOhfi2d$SDsFiC17v at mOR^VFuZS|zL!h`Mc|8G
z$BZ`(Md^T>o7vq{r4-p!YfJFp8TgJXdb>PyL9Ho;8ltDHrrqaB*}PPFv?7q4rMY%*
zj=*^b;^|&sVp2(Lq&9%m#<RE_m5CUzy7*?X+Cn3 at T5~IM80F{IQUhi(re%c=e!ZO`
z^104r-iy%8{#l9S$TS(S4WDi$(EHLIF+h;1mmER0G_|27_VT~S4vXb*==l;>mok0V
zjitOQ6TdR;Patzpz?(It at KiM&4$g(DSkCe~O;ArH%HpVc2scCyN^x2)$u!{f)xJ=b
z%nK+K&{@nqeX8`;WIzk1w|t9Iw*+b^h%Q)4eQsX1-4I%TfPDUrAky7jE|*`pRM at eS
z`a&P&@+DHS at NI^aS6H^^=##urg at 7b&aTUzLjKK|ITIKhAgyGj^lcYSoe}VbTiiMRO
z3kygnCp?_!Y7^F_w0TlVj(!U45&UhSbAo|eHn4UMT1UWwxAX2SJqpY&<Pv@?hI6}v
zuVc>rdLZa5I8t_MM>$c;IT>65mOT8@)s*1_<XeAK^kIglKQ8Up0g|&k(OuX5=SzpS
znN at Tv&=0TqnQUhrI@)CioO~wc11%f}(y%$!I&rp|x|Hk{>s(>T@?ed9bJTaIv4CIK
zP$gwU-ky3YHHFGX>K8eGz=lSCBPHoBW8#ulV(5Qa+;Vtsz!mrW at uH@WS#XnCZt28O
zjAv%=pm}?tVhBw>`(zFG+K0(#xtPBokv>b`SUoSV8%A07+SvvX5PicA3R%8Kftkv$
zI91ss4q|7j_8*k@&7Sa+sr!_kiAV{s_duE~<i3n5vOZWH1)cEn8d<sO2(5iXW)_1!
zz;nZ at Qa`FUk6*wB`+o&Zko9?$xa~ANR at MRUI!{b~QeVFP`St1+b*iXial1- at U~!+y
zpoff}*~70x_wL)-aP~mM`2G009H(q3ivq8M%1Zdn5pG2Ez6a;KwQ-fSa<+s2Qk}AY
zhrIeRKY4-LfhddceQ#*Ak(}9=QsJ}nO|pH*2T>H0wRw6dNukcpT6&WpvCn;2BBOlt
zH(lqUe{YC<0du#}7?Y|i-BJ2qRbj63v%H-hpc0n<x$}0 at S<9)l0CIZKT)hv?SL?|;
zI88qi at JAbdgb2^pM1l>5i)Y6&5mh>)0TLqmxQccC{%e?sE{^|dQu%D4atShNi$FyK
zgTH5`WXFWt<ahFzqU1X{I1V{43tOV7v&8;LQ;8`Z>^TY_Hid!vqRPufuh`rauoM9>
z)Z2!$dreM%J=aIXaLcD2UkMmMWdVHxY&>EqxVh(~L78HFK>psVUNKySp5yJJZ8=iF
z4&nK-OErwHsTqh&%H{YzO?;&=^JX#H@=tX{f>k2FEewBayGAR?jLgTl4qkzN&LOe4
z?syxV{#0?Kyr_?w)0g5M<@c%CQnqvEwveJKjx~4tK=f8N1j26=AC3DVX5I)KdD%$k
z&mZDGr<&f<NeP;O08;?L7~kjBsn%jy;R?5qfP+A2)m_8iURE<BEUkCy+;v-(tf~h1
zAv*2v%oAc4cPoV^5N{w-18Vh0rtfEzzb9G<z0^HzEqr4sqrbxQp!SiE+HI?;ii_HV
zo#BPU!P(AuB09&S()lOEY{@U~)b0rIMrK)6F2fD75wt5FEI~7BI0?jy+)*vNLS!`6
zP0AS9lEFrW1R-c+Aqk=Z^wD7oFYn%U&-|&q%PrX#0+Mpt1FsbrM~ghet4c&{`k1XP
z_*{>tI%?n$UsuW_PDHpl%yw$mJ5R-Jx4s?tfL++0^xRYl>4J6bNC;*gW}({&>D@!9
zCT!Cqrqy>oI4>~W`cBfgq at 5g|nk{-ZAnu_>r9{5$rdRiT#;rMvp>XB(qHqL4KfbJj
z)&6b4w{JOj&O89TU$n9mkS#8>Na&=3^Wu%OsllnEPa#EHvDH-ui0YRWfWD#lSfW at n
znAR;Evg<`6FxmVWyn|+f_q5OWjUodb+Rcd!gGRWKCfA(D4%$1M1 at s|xa^K at BVdxh;
zH_dF?)q(Kykh?<;Ut|HuRY(IIjH~lDd0jDd57T^P<NFF74`dExerE2Bl1txq^91xg
zF}4A46lh!jJ#HC{o2hl4q=H9;r{Bj(H72K|V79JJf!xtnM<nDpGzAAtETX|JY2I$b
z;-HNhBRIhU&FCs8cjW2mkiDnI at U+U5-)(OM?h0v8f3TV3_G~WD<Uw&lDI;5vt+I9L
zDS`9 at Kb$Ilf!dH)OyrILF|~vqzkpgmADF#?Se0$<rFk3ucJqtX&(`5kFE4$VVgHKu
zI_l;JKa4w4McoUD&RJ!x>98i**{vK`pd6v3HLyz977CgrLN4-^Aw#B0_4GFiN0G|k
zlp-eDq2?MxBb<AnZK}B11#)`#aQ?ZvCO7~Q{f<kyNtDss<>%;pTj3$OaP;l<<uUud
zdKlVxY|T%1%hRFNKATF1?>=-F6q41ODdL|YKE7VGuULA2(QD091s<ET<XSL3g<n)w
zDk9-auBLxz=0!3;Q-HGP)5$9Kr`s4Ksg at _jv>+V?OeAmuuPQbws&XAnpfZ>_0C<6=
zZ2bE_s9emVSR^yOXdBpPXTW0s?!2B|#jsXDLz|(*JJ?qzG^je8P3(A+;9xqod9)NW
z*av}{c=5086$RDnaTCfv2;o&A%FzaZX0Ka0QoOzySeJJTV<p?{Y}n5ifJ at AoKm}JE
zWQ6mcKO_vlI{YtpM_MG~p26)tf-RQTO<@Yq=OiQozTI+$;fJ3;|5=GadHaT?CqJ0m
zCdkF#FHDFs2a=M;3(%t5T|7(xi1fp52B3T=;N#=+0Nn*Mwhgevz*b^1TaXn|;JhD+
z+_oJSSUljid@;rBc&nNnN8F8(lcNw;L)@H}E*{M)mgMF4w|99-Z at 8wtQ0@;^i-O(a
z6o4{-SEo9=9UB0b$>d<&+fFreHnlZoQ&*o$w$gFjxQ)^85+?~3qYG+A?P0N6?l>p~
z^&dyCevw3Uez9HsKh9TEua<e%L`gq8=&lKrX{_-tR)kiOy at 4`ju!+dbO5OhVLeIAc
zETXCWg*Yvgij^VfegZ{4f$lZ#b at OaaYri)5d^^Gb!cO9rrAzYAwGbQgPnJ>=={{MY
z9rXiSHae$GD)HEbd}J#b+e22Tg#BRD6rQ*8s$*@xSTg?)=IjU>E2WxF<Jz4?Rgv(L
z{H3HP`B&{72~`J5WX9ZR2)|>cO_`xj_^=>jx{jyLth*YGKp7v5>ap=h4$m3`p at Q#2
zAKbS at T#{U#`O2+uUY<!pXdoH_vBH0+52|goz9%q$2i4DdblW)ZJ(WjRZ*}iNGx+oV
zvJy4~WNBzKUyp92!+}f at Z%&L5n+P!P6Dg_dAOtxy)X4?YSyhSwN)Okk^{_cH=WB+!
zN*H+NuWM%??zUin&Pn=jq7CK{;8t*zU~^JEQNVu7cx*_{m%@`Cu+G&ic(~Pdh^u4d
zyRJ!F5T}kYIZyysJQ|SSarzvND(3ULU?uRD0{^=1DIol7E{jji_1m|c7)f~=pTi<r
zrIqud+$*(XI;r%uDm*7HrjOa7?Oud>Ga33;Ngg%rS~)DJ{}#$X-AY5_s^INd)X$08
zJsl}Cd)%L3VzeYVms+kUt0&n^bEanKgliE9dYoZ+TX=%LqV!NqN^l7zs6g`b9Ck9u
zDGiDeG&9V2fgdFKe=R^<^ZElLy1e;XrdZYwGjF7+s9u%tgo)a*6l;{IB at yCT_1c1z
z0*pPtXTzXR*mAPCYv3v4LZ;G9ZDx)I_$!EOLkBt`!Iv3wp1bb_`=oQrD92GtPFRPv
z7^^(;i53gp%}o%bi-i6-yWp`i1Pc%K>S=j+!(ZzLe at 0nv-YDbRJuj4WgrND%Sa^Hn
zm}6i4^OtCpvQ*2X762`1B3={<g(x&pH{@^Qxq`M+6V<KG7fi|@7N(kqe?d;*eTr2y
zmC-tw5k0kHg%i8Dv6N1ShwN%V0R5evdX0?iP3g*qrXFLy{NiO#ys({WH?t~=&)%cr
zWlUxk2e%N=jUztA)y7b>g^T=ODuthhiv6DwT!oGWaavI|SY7>tA?t?B0~&rp0Z)=l
zo%g`UbSDqAtXWasKR`22PAErRnc$WIzO|wcp!W2=V1$n|6ut%)TnW!{>YsFqYh4vK
zt(Y%>vu68G^k7tW6gZtn08u){1xPYXY&KcTfL-TrrA6e?Tuj;a at V?pE+Y0vefoQNn
zmhVUkAN|Gym(U>DmOH(3cRAm2US5k*9yTD=lFgS}L-IM@?Ypje`swI{@N7T;ppZy0
z6>4>7NGZNCyvhVNeUJouO^p2=7NHTB!PdPXqJL)}&|_v3Jf3g5%hm})Ym6P<li#yC
z>1#@7tgS{|8*IQRkBQ7wp&IRrW%XiCTmJ#|-RE>$@uj)WG=@qB3t at YHQ!`^A%8Un0
z0`cP?EaK<_ZSloEh|o*2-Eu&m^q)vUGKy{yNshzfc-#zk at jHlp5*kkKbj~{z^Gynr
z?{4M$ayY4BXs?cce`7g4%D7eJt0s2NbE&m?=&Q1WeNikuJhE)mHqzTRf7ilM->rRB
znQZD-6#ueN4Ir?kOwx$Ug0cd12aGX9t+(GnyPAhCnc)>DeWl;T%r8=(uZC>7Qupme
zZNKQhshbw&3Ti-2iS&q-#3hi8Ft4GH=KjX!*m${aTi!wbx4>FpI1^tFRe#<;R~zki
zN}=ys5dJA{Oa&&Gse>GPt4%Jj7%4zy)rB|U!(i at x$*?)Ftn{|{*>x9hqz8@}f&k at e
z!mI;#1Tf4GCko=8eW at U7>$T=+HH{eo!N5R_`oAyWyd|LF5v|3EC2Xw+zW<|-GiNcn
z{UhTjx at ccpD{lUJId>fDCF&Yje0e42!w^6;X at oHwTL5dUeHQpmJ(H2kqEi{22XLo&
zzo<{_GXZAE43usP at hQMH^1Si}!0KP;Cd5|a_2lg8GWz)#y1WbS_7z+ZdWZb`zuawd
zbnC3r+-j&QW$7JYPSyVD;86Izh0e$UM}7R|`Jk&)m5ThZ-au%%wJo{;O~u?QI%q`y
z<KgG0<tYL4A8#c)Q%`6XJ13LYGR-l&OlaqUk^^Y+x7(IgV`Lkp?=%dg)w2l~+v=AT
zylg9se%yqL)Hzv3pJ=2V>u42xNMK6c<IWJ#I;}yel?v8h02;HW63k?HCvvzt%9t_0
z^##U)zdA0ibhD`}ILj-Webh5UU+G`#Tyu><VUprzC`D#SBzk#%Y)Bxvvp&B_T6@#_
zN2JJ2(4d~UXWhY-1>Pj-w`5Gdv0Oj1yyMRP>%l4R7Z0EKTqt*nz4Rp+zGPf3e|t>?
zn~#ww0`ZS^_=Y>K-zauv%9<-F3Rn63be76JMomnCKNsSaaA`SF*v{JL%fCF=;qdQf
znbQ$QKlIe at 7^_O|z{+<+<okD8$n2Yszd~KZD?Q_+%5E|Lu%=LVXz-xW-rRE2 at -e3o
zLM$Vmb0Y`zGvc$}tv{q5Ka#>|{4Sxk;UQZly|<`TR<Whpy~?_oY5k!%i<KdOBIC92
zySn_ZJlq-D4yy0+rj&n-SYq|E-UBW1v&~)iBjeo5dW35{g4I$v*YvN>lb;#lY45iN
zT-?I301qu;=mp>L4S0gVA27=jCST<z&=u{h;%9uWa>GIS7QbW|^k}Y0Uv+<DAe6_h
z___-+!gbWDcY=>x6`C$3w%-GaE>vW>pJVI7<5n at jcRB*V2>Ea76I7H3U|*0IfkX>#
z6yCMDv%K^DnE^W=!F5st+G^t#t_r+&G<BGkm!ku7)#$J1yL~r^6t!lzjI<vaHD<W&
zQWV2b5zkATD8prPp2r!oPvjiQ2+5nvjNhYpS@@v3w5SB8q`Ohx0AY~ga->oDwz)J<
zvC??IXc@}Lp;Oa7MF{RVhJ4Vf&ljQGV=2;lT4Of#<W~E=JSXLNu~7S|-1$UhE7pGv
zOU53MF+PMml1n`MTF<2g&x+_{=ZE%Q+9#@XuctH-_PA*ZTu3oFNH#L^Tc6rRJyaY?
zrf2MVAF5wm-AT)F>L at ngk>wwGS~}ksPZd=40I}@!83N&9m>nwBGv8T&WoB1h6FZiI
z^nrCB(8qyBeMB%?qp~}#64*5n^qs<IMHM at F29wlTOE!Kp_6r3brMIvl;xa0K_vv58
z+_*`ZDQWrDA;XQgDR2J{_bX;ze_cW(a}T3SVPyJzrLq{f9RHw!LymMY3Qle$R#;4;
zIB1I(LNq)QMjb^(CE@*bU*+sAekFsk!R`ZtT at VyG>{J#(&dy43Tm&9MCSMmv$jgd$
zYVscd`{<FX*_9z~Ipvs>pozYa!eu|)DK#%9#lDw1(&@E7(wMP*ritMI2oT~Qjy3=V
z#CD~3wOCVChX;_87MZwibulj;3N~=%=g+IN&}+CRI?pf2>n+Xp5$Evp-XP#j`3{_J
zBZ at a6K7kOyGj{ODO~>QNFx&R#yZ^$h^B=07go$BNo`)db8<xEW6!#g3d-yj at NkSC$
zS?C5o#WZqOUi1xXGs_h*vpmTy&W1K68wc6b%k_s9do#?bq3dgHDCOKzU*jqyN?%?$
z7nqYO0ZVzR`M at a<{G^T|YgAH#>`}`InM_02mM5AF+-V2Vn#d~=EFy(UF}~f%N+s$>
z?w|vtBB0-=k7k`>S$FsL_WB^E03vCCIFpTv=qOwf3L5{Ygk(IJnfpuMDq1)zA{^nF
z)huGeBcD|=!5I^x5F9gpjSke}@vI$nCGGL|jeH(yG`^+etUJm#RYz5(A-IZbbT)lC
z)v at 58m<<(@pBfn8K36J?dQWF=Aw&MQcy#I$*6WpT&NYF)d78`r;#_PY(QGA9iBClK
z5!xn(l4<8k8Rgj=n=ov4H7_4md`|85RNKd*!02DvC&hPsALzy|0h)$~!D&ICbr>+9
zK20{Fn7n6<YRZ8ZYk&r91};tY#W)`Nb8hBY{cEqRMs6?^_6o;OrpI)5m_{*cMx22Z
zwyr!U3uvGGx;T`HSAeG0tF#qR^8XcZumQAoMk=sZ06vksT>(%pa7-Ba1J)8nHL=Xb
zaPSvdl?Kr?NB_dPCgQHte-3^rVb%>Lf14IlUq`oa<JQqC!Gby%2Wi1#Y at G!b(C<m!
z7dTB|ouTcqar>nMq%MIdvNr*6`V+v(6i^^wAHWRnf$mD%m-?lii8!}}gFD?(+JLm{
zDv%DoGrMquL_pJXSS_aE+^A5MhJ+%G)<M_WiDlcI7hyM1XoWy>;z^*PCPH~MkU}sd
zc%1#E_z0OfU4u{!bnYNoxb6E-Q;rKKcFLIT7K at 3t#EJ)FOOwUMi?lDxBh`^X0UC%0
zP|z5mKVb~^&8Y at NQy-NURDqw~t3#^v*1mXO#`D?antO;^T^`*gbh|Nz%oQPAY(KD(
zNHGq1t9t6#gi$~bsqCX#B7!>2Uky4Hxvw0(>g2iWs`iTRz023WWg$-9RZThYgo%2(
zedvag)^I at i2_GFJCTXb1=PH^(*#cGM at _=LB<(WD$W(Z6*{FURHw4J<RG;0Z!V$)RV
zdp>^d7VS?C>L}lI?&K+JbJaxH1~f*mLzGffWeNcnBrlQXEA?YIlA;;(V$zO%1I at nO
zW?R<6?uxl_`minxMf;>_0ABv8yw80z!z*U-N+ACvBSQhCNPp}VYiQAzdPzml$*lqz
zN~E~uj`p6_2bY0<q?D_ONcP$p#?EpgLRM0o-41|b;=ca6l6`@=<k-O at BnE(q>)_1O
z=RK<8bNsz+p88K^B*ltl`I=1;tm%PVm8R_!{f4x0`)CAUl>7!Xz1EPC3i%+QVIG<u
zGN1tirxf}w4=~F`jIOKf0FqGND<fRRD<E{kPXSbT`4muCXs28NcgLjh`bvz0j#2az
z!(VAmLWF|y;g6x<&R5Zk{K?HJDQ;sYvDXWsu)Z1GHBF}C%=<;D$s7h^Tj{~d&k*t@
zl9jl9<tHw`LHs);I|Ph+A15n5Y9|);EoP=f^wG=w#rF#M;0?jORFFZFkW(?yCapb6
zCN!`qKs0PTtv%Sq<_^02Xy0U?M3M6RkE*dng>fix4DO6{mpg?_2$!e4!ec4Yr5^k1
zBGh1NhVwJnGK(eidWWhK$@2FGp|Wjf`b$;5289~|L)KmY0<?F`N$aC at 5YVLldAVwP
zJ|_?G+>6gi!Bu<F_y!=$>Tmm2;aP`RKn~6mOZQ;%XP(GgXn1<dEPFOp=On?U<pQSl
zT}&(9+3Xro<YlSiSAGPvA=yk}X%C1Ql;sn3t3BNst^yX%n@`wjyS86y*U0mKKZuy|
zD3_^Nta0GM4-)h^Dl at F~LRO`GTIaNQg9;j;<j=N#XFdKq+0nqDQh<DGzh$jZs1)?K
zT^(_xy$J(LoDNJQ52PINPxGB)3ac0}Lxl<IuH8*fgvUIO9tSvmcO~y*xK(=YOXC-H
z?#(e2q=>IJ)WtnZRCN25X*%D}@d6$6JJ6QP-r<xLaFY;kmN?#$%|dv&g{$x0Uyk9v
zu4aOaDx1#HsT=KsWZ*D$fKP#tUVys~G&o5+^zlvKfOyq9V4mY*9V;2HUfoK~5D8ZA
zbEGXKHYq!Zv^kG7t!M!+Q~tnz9rg(;p at 2SKo-0L+nzZN5=&xZ9zdEmH2G(kB;eJhk
zUBPx_X0T)=+Oj*_y~@kbu_O$fU|2?O=zYzsh?=9k_DMr{xeTV*n{BAi!Y8qxcKd}3
z#)P)Atypk|+x;w~#vVc<5+O9rW{cK40`GlWyGiYCuzV;Cqyq^01P>|wRSv9WdNyB-
z+?pwz&R$q|M-gDl6VpRc2_)zV&Z181O=M^dqU^qU(HuwleAsMb(iI~vVH at O>yWQ*a
z9h!eQQ1T@?2;YGBW|cIeJG*Hkd;O+g8MNM0^rMeYy=J4`(#CMzgft}Q<|Ison)dnz
z#9aKzB7!&>R6KifdMPjizQsnkSD&vTxr!Q{mLDdwdj0gZ(bJ^&0*)W50-CPMYQxCT
zKt8H!akooWRma~9g at Wv~7Slq<iAM<7K_J>%tr8BiH8GU$W+F{r<1aDC4%5zE8Y?IL
zoh%K?GEB|wgP}B`QB!*3;%q)=hT+^(nLa;5X5tv*UHJ2(A0dMh-qij09`jJINJD2(
z7+>xs6 at BacW?R*>22O2QN<ZT?=J`yuOvBlt$d>rxP{=maF?(Y;6Kid$%%-!fjWchv
z8tnpH^0dZo3Vi>D{@vSFzU at Z`S4<PRH*G)<PhTDCdd&P4(><%kM<|$0EWTyYeu!H!
zuyKe6pZm{H5t>r{rjC$xzu&r5Ml8L0(-f>~3(Mf4iHp|)&@xXufkM`5%jyLayw23$
zB-6NCiY7^<p!7zZ8Z}0u(pI{iBRcIr_BIpkK0J!e;d|DH6}HqArs{beB!na1 at bgc}
zDVUXi<nP8)o6!nK4}y8$^3js8j4!W1JdUQiz21KI)f5s|ZCKSh5_Iz8>U`bnu5&n|
z&1ClN$v-un>n3=Uoq)QNBEjaYhHbBWvyVSX^CoU!%!IN=l&^mvH^TQZHKxvESvq8D
zTOaGu2SJcXLR0SZI!<saK6ulQGvI at R12%x#ra7E71 at c7g*UJ2liBVLsqE~Tso!k#?
zW}VRIkx79S%vF%;YiFmN$*Y8*;;Tr9EKX7>O(P81+UPsBr4k{(vLdq*R-u*v;trq{
z4UtC5HIWPltYmX<><&+>e){)ly<T!dA>+>75*q7eE9{$4O(1czW|@^&MtdNa`hzds
zOk0U=P<ZBe5ue;luMQxAE;h(@=<y=%WID)FD<ij6xOhLSmSxe#u%+oVRzEjE{*d^j
z`@LU%%(_7RQdC;kW>zO~mQ|0uK`Clq6DAG)R5Ybp=!q=l`?V-OG1NcZG;_*HlKA3}
zfBN=>cqqtxVq{@;Gzz$FuJAUZIgZaNJ)bj>90k|qhSlK%6T=FyVL^dJO$~n1KMh|%
z{|*{)QakJ}zZ{I0zq$SrLkthKoK}s}kf#%uV*(B(t~2n=`X%h)kJ5TRGQ)4=XmD?d
zp*bQl?<f7|@W1H40ie;1%hro*>Kva8_Ne?|s$zmC8?nG&-7mam>!v^xMExsaa%THB
z{HDh=7o^q3xUqzf&k_;}xtX7lGO`><0oOsF4-Tj at IT-x?{!!c at G-koQ1^!?b<=$h$
z6r=Ugah=!=xWX1(cOb}N+X2+*Ilrm_5EkZQ0(@kLU+f1?0S4FH2~o<}!#n+UI5FDc
z9pUmEyp59Drskg)NgWUbx4;t at HZ7N^25hPT!N71rd*t0^`2-~k&W`?l7KZC()nPDV
z<hG6_!>SjrFSbo~-02$RtI>{jH(JOc-x at MxzX2Gh2KV>($)6gYb`!dsds at 2#Ct;Vs
z)Fv&c#qai8s<8hc11NV3FF4a*JOf=W`75$)nfwXM*K<;WuA=4eyC$ubSv<URfsNKe
z{CX~knJ838K1i-6?!8>E#59IwM>~-KC3)}w<w*#NFtbC*+w9*Q!arp51Mv_8%kSiG
zX8e09b?30DsK-fT3S(2 at efIwKt>9Xj2I=>s^oN9hkM(7HxUeuH^j?y3<yIYIvHPXk
z7YBMfH+7jp?d8lg_YJ5AIiL1d{+fAnEB*syH6b%&xg6AT?=vf!`f+i{3kv6jysqnr
z+JwWzmNGuG;4~_Ld1l>ZrC+cEQ-*?7fuN;qt=R2>9VM;)gI!L-U0xuqk`qnIYzknf
zHH1p1#`>HOftmgM1E+FNcJQB3fHVql8fd3nUOQrIIsn$0)lR`pnBZip<lUA-0UZ)g
zXC+{ZSiWHy0>xE`iS}h1KffsIj00{r)>3$W9w=pQzcLFZRr8S^uCr>sef$WQeFZEY
zD}b<%N8Hb7!6+{LAy8iVz?{evZ|dIruhiPYJxeLnkB@#Au3MCe3}q}%>w<4+mzF*-
zG7W{s%$<5XvR$>!(cUkVu$ntGwCXy{##_FuL at X*R7z~Q1d{gR5d7du$`!v$Cbr6;%
z`1c~kp8YcL>+vCuk%!kxl{LCrW|M<Q*sQj at gSeX6BxfCD^J5uc#VrXpoom at iqE_#|
zy}s-83*E512r02|b6|SUkCLXDD~C*iYI00?AZ=-KXg?W}wVj0CHCqP?+wd+7o&SrH
z#2=!^6LqHavwrDZMs%->OwfdYn4(qwGCobvg(9NqN!S{KjbZChsQf)&LFpI|%Pw at Q
zHvh;*8-&SMQ)e#MMT%BDJ4r-uu_MT-kU+4B1lfbv&AlN;=K+ZnS@;j*E$xKt3a!r#
z&;{0)*AdJeIF^tsSd}UX<Kb?Q5ab;)19pX!AI}>{o%fpQ^jh#QL9H~Jp(<ex);8bU
zrLv;(>^;>K?Y((2oE at XOZp$k%vc`r~zDcjL^mD=Aorcto<ujr~IHp_`K8u`Y;`@NX
z#`CqIW8mS>(ZD`{42|s8hUjbk@~1Uy`tk-cB!8u2ill-rb(n>L-|*tVZNKIl-N0aW
z{Z+c07&p);p~7_g)~$~PP|4{4Z!^Ahg%&Y>35+qP-d5G+iaZAIBircUI`*a%0L0vC
z3qmT%7YECn{WQNns(uN0rwWVclCFpzhQXzua{<L>l1fneh+}pS{1WKf*VM1FyAq-;
z-$}W&^aRf|`5SlLYUJ>C&(E!X7JOny+m6nA=eAJi?`n0Dr>00=(f3H$^+rGHNaoVg
zXD(od2=2iJ*E=bSm(!Z)7Z!f9$S^=EGFoC3nZ%~6ro|X<Oa=QA$8Ba$s6w5?n;rDl
ztC$)SVr&hY)R)%2C!IdqE#_JZ*`}pJ3eJB~)&?6nyzE!ACYce_3CNS!oUnSDm1H4w
ze<87c^!plKWpPFX#WK+BCpdrW>0D}(dR|Xx>+svrA$yyoRi&xAqUwZEYRMbhx4Go8
zaz91PN_(4rbiG;(Rg$G6Ur$$!Gd_a_e=%3{mw1aisToO15HpSAJ@|E2nYsx!K^E^b
zYYX5lC0s;F=7MdDP9YJDt#A{SXE!)H;A-2vv^S{61%#*D7`(qJ+h|(}z@*?pDttZx
z#_E|`UK1~%K7ry9+nmJNm!%T-Ev-hye%~Bk`1a;ShM{W)h8Zt&9P^K>q7t*NeVZOr
z8wF0 at 0TmgLwQ04$-od41NE~JJ>*TE8*{$KXP6dGa0R{#ZL(bU%ufgkPEH`8&=JXBK
zG(@Ia#r$Eh&fy9+^Q6I3d8M}el#?KA2l#PO1#3QyH8lr-iL!LN;u?1;Py+1~Olu96
zY(KI-nhH5Di~w}rsM1C8!+zIapF|REi+}%g1l|n2r9&L*xov<iaN~$_9SYPI2u&Di
zq%h6lD^a2-*AXhXKn3fzxnt>(YxpfnECYi#!w!(%BR9JjM$XVzgYflYZQOgXD2uYh
z^{NGi$1*X8cOZp}yHKp(@Vaf`ThPI4POpg`eX{pW;c2GARm4+(OY4Ai4V{CMY^7;q
z>8+r*a at 6Xmvs5_;Dp}5(1I`XnLpoPU0SlSNMFFE6?BnsK#mn&spZfSTzGEPZqe})o
zaR&iQz_XFmQZJCsriOV*-P1wR_?S(3<j9RdHz4=*+XaK14swEwFPlVI&{twFMXAv3
zwd;%2*${g9>v;-aq(8V<-U~Gzo2<UPww+h_#IyrTfyQ5r(Ytp&2g&L`iv)tHi7&5?
zK3>7I?@pkb9ki7bvfMl#zIUF50|4s>d5`PQT(G$aU%UL&4W$aL567a6&N&Z|x$bk&
zuEaXT?AF1AqBhDL^ACYZ9DOuzvE8Y at Kba`<Ma(9FuIypbdeFbQRKizn(b(E)C&}sk
z1Ct{Tpe-qz!pw+Zt5GCSEtTCRX-!BK(`h%;S~`!J#T%j|YP~8$1k)7VhBP6Z8*3?n
z%A(ZfioC2$zc?E$5*=Mq@^n5-s;3##7Y$_CjN0^HA1RGoZ#FZ+aamRCfWWsh=wh|)
ze|jx0S2>f<Tx>Uh2zNK)oo$!92|KO3hn+G9Ln;`%(VwqF!C&fEXlHI`)b0mFg7Zxb
zapt&Mel8%a&N};C3da?o0v%MSlM{Dd-)8h4d9=-#iyz1sR|dD>?zOX`8cLmR0>_o=
z0At8)l_>0?O$P^obkk-bEtj0zcvNig7W+0YLAZhuUc7sXpR1iZs`9$p+jFl_Uwka$
z-qk--qm91>d0s`<Hg%l(^GBIye&{?m>4m=R$fY9(+nl4duc4WgqeOB3a<&IA8Mm0(
zEH=i4zbB5{jIBlqDjQETzJ7SHJw+qNCSu3Wu=n&o9JVehydyHu)J~b_B_Zk#5IS$7
zIA@@RTK_g>a|RJAPpKp7D)(hp&2EXgjS_9n)iIi08>Q@}q)Jy|D1Wcxx|jhNEptKA
z?xd(z=riOmM0Y~wIG3JP<5|6Xy at RNAJA{s89ZBu06YVeob7<x2ivNayNcx<h6a8HO
z7X$j=lYQO}vv*o!^H<rA&(SYbm at idfag};iq&>kMZi(MhN^^^y>ho3`Qa066)+Jfj
zJk0EBHS!rXaamXUBF+P;AN>h6hLB{%^_D7OR5Ii$M5^j+zr29*F=~TQ){Q at _-kk0b
zTzVV)))Q6<HpQZ~tm5@<c6vkM-lm2&B3sqol}A>PgVkNUM at 4j{mxNaGH_4|0cYRGm
zh}Wu^I?^W+`mEBQNf$}$eilG*fqAs!=RoiYzJ-{ikK93wrge1N?<d|kx&2zG|NEPj
z;Hu%x+&}<EY9oMZ{3}y96R=PWfb`_IYph^McYTeU!od`lFC)sXqBHG*>FvsFr^@eD
zU=gr{t5U^jRk?y+M&C~rBi?fy>ZsYwthoV}Fm+P^{|8*W+qHgBRreck?v%YzHKsvo
z6Fm|eeJ+0hrj;{bPIE2*PT!`6IC%h*%<YFMBM85zURMi~>h%Fo6ZO!k36_^;i4vN~
zC*VhCMi-O`Qq^lUt(BoTY~t+d152-Vjqp<xHAnuxa;Bi<T~S58`<t>wBa@|LstxL0
zPA^~RS6?*R)IQGZ!0tI1`v-7OoWslKLX~9Z-kM>pnI^e4IBcPUoqcn?^F9c>;CO7c
zd-4=$h=SgZG(>133Uy~fEbsmsFiS~;A^8~74E!NvaCNfj=SPM5O=yY^?Y>XqB5Eu9
zLGDAQpUGTbohPoeIo2lOm#Svvht1(jsC at 3Zz8wQDU7=C?q=m-^BzHWg(lxe}PL`05
zd&TZ2 at 6zu$eu4;GRL@$KOotK&ER|ae-c~}q3O(1(SvIP3q3>k_ViQHbG|UMVP54CL
z?lvS<$f!ql at S@CgjiL~8^HFB$ho!w0jMZAAc_s<X+v57Unnzc(t~MS92XJXwGV8^{
z_1d70^~$K?ah*lH%<vsSERO|N;$27|C_RO~*n0~*SHcUkZR;$}a5()0hH<1aNQAqB
z6!~0pAEs!p0l9=r0ECrebcoG1dHP-$q{U&$7{?W%n|dUL8xiL`8nLER%VZASK}UhN
zx at sR9x&2a#Y4jNUxj!;wl0l%bz%l>77C^0!reH3^VCwws0eCqk^BY8RPAXlp6yTJd
zawRs~>AqusLWotL3Q71uoP7?R`jflxd?lvT&cf58$FDB;jhGcbP-GqC%^Wmkr#O)r
z*6fGg8V`{dkG<8imgw>qTvroi at -;`trXb`qM1rzW;~E*wTk9dAAo2!i_pNreJMTx!
zX8$P9EA>}KSwOcASo7w4XdP<TT0#k{_qAUBgWO%Mr-mJVc~RYnP14v|ehMj|ouL&k
zn|)Nbd#3AiP at ce?C*VAnugve8^>wV6C2pS*^T(;Kf%gZa5tKX$B<z~iS*pG?zY6iM
zeDg8KK(E)6S<%(u?BfqBn^st$ahDnj^vJ*iY?GnxFzzG4kW32&)2ts5ZFEUNHNB7f
z<a$FJP-f7{tv~_cn*Bzsp5*B8a8#D at w-AnaCno=`>}s#AtbnP1nTsp&BooSc4@?@$
z&59qqYxqSAwHQ47y--hC4^gF4w)u#o<MH^d<y!kvx7_UtvQmeT3g0@|t$2?#i0eu)
z-j=w^V2~)xM!c)O0O>tzbBD=VX#I|r>Fh+yKZwUe!ZO76E|HH6Ni?<VR)j|z$am64
zW}3^VwMf&oEy=A)Oo%fCK*msRQGNHJ-zw0iH0~UR%u_PN3|)twE`~&&sf}#|=)1o>
ze;+)V=mKIi0DL|erMxciZQ%(3dEWU4D4`$%fc%^O^@(&R2j&~FoPH2}ve at zwI0@{n
z1(~&QfR`vhAGgd}%LXF2TKBIzvy6U7tCJ%iW*|(@?inEKfrEqE^5?^d&kfimT074n
zihxgG)pp5n{2tJ<^Ey6a=)R``_)&0`j}8Td;!^%ghjX=qYYO%VZj{{tDUKZ5v(3nj
zWINYv{WNYN>hV`nUjB!Rpotm at D?#5)vekQ1yq82dYzO at rYDM!F^N#K;#X_H>Ix6S%
z8_sFsX|cDDts!4kNX-(cfUV1#DNI_I^wXU at WqqPJb@vqaVsPR8m at ETLM;5E8wexV0
z*<N%>SkKsjLD>nl*O;G6U;CtJ%^%~^jFLj`>1!f|k?vO|OZ~)ZWf#gUdqYk|WUW5c
zp3GizI{4Y`iVwAZ3r%<rz&^LAGd<g71Q|RMHmeE1EeBGvi`6B#XMfrRLM0ZCl_zwj
zf>&U=8DGoI9+vdCxwI9v&QR}AB)-gQAbp3ip^fzAt*LrcJ0mn#Bi5vM3J5m1J{M;H
z;I2L6Ahos{E4kE%IM(Q1rFMN<Utf=oX`}slvMm7hNgMzxZdIBssK>jFzX>I$r>w$X
z5*Do60iI$@)9r8H-%HyZ1MynXZ$diuQ at b<%yx=gKH at UdHIQx%(T4eK0B*D=148!V8
zy#?pwLtsAnc>eH;LtoZ#+S*JwM{>%bf<X!IqY|H;in5o~XBel(Kb(@8jhm&lB^pbp
zE`Ct9(F9@*3|_%Uybq3#y`L?judCojs(i3SpkRs43e;kL5}*N$1Dh)DmUQ?*bRdcU
z!JvJ1unQd=h9ALaJgA)5U at XurbKR)PwNceV!IS%aco;qwopx{xJ%(}D#T^3x*`LY|
zQ|XPyN@{_%3RW0Erl(<2h3|s7{fYzZPtzAf31*j<uaVDl<u78O37jB`4O|WpTD7`D
zdtvYYYgX*0N|G4Fyr5}pCFbHHE#+QSDSEHAzVCMlPncZiR*Yea_KX#abYZKpC71>z
zSS?skjZA^l$?%g)U_h_y!pqQ?v;`oJnGi#H+i(n1yI>gfv)Ci;l3(@-eIh&^QdXk#
zu at s{5>U>mU{d+R^BgB>V^o@)2k5S$*OLnxVt6_x>PUZ)Po$qLzXFhD$L^<#1y&MWc
z|1VaPrn%d~SycRx(+CPX6d}9cOjlp)g%_OYm<04=_!suo*2pf}UX+=i2FAH&#lhNc
zYV4wTvn0qPbP0B?cp!b%Un<LSUYAK8w0MX_z>LS{-)sL$eQU5ATU0!-)=7t>fxMkt
zcT#)lHZm~v3f=U3DK~>b>PNA<iWp-t>(s1TiE53p<hlnV#V&`cpldZGe$BYU|Hbty
zrX^u>G{aiz`&5IVoiiNK`TkDoAtyQ?LN*K6%V6&L at i+}Bq*CD?R4dnb%@8Yv_<Ow-
zmcDiHfk$7gA;YbkwCG2-u at ozXGykf4YFga8)tjmpzhP1bNkukMk$Ezs_4oLzudR~y
z<0<1i0LIxKU^3leAjH~>wA!ql*Z^9DBEU6yv&|B5)ya`6GFjzP*MSA_Xt3gZhmeiT
zaT?$V664D#2~=32wetBo2!v$jbTSGG&yn7NJC?mPe|Fd_Y_J0&OmjNC+!d*_ShRRK
zdsOu1Pv8}!jRTc=@PuXCkrP~lI!{D#Na~(PCx_HnH4h(QI%Vn0I2C*&yY`cZ{7pU!
zzf0yObY|Z1z1Qf{h2epnusRt?a_l>8wPV_7IN`(Vme6i8XUggz&(|%e1(3Eq#!pYY
z&hD4o%p7_gdB)4f-=&fosq`iC2WdWH=%P5T(7Nyz1??_Gt2i`*)d~>?iBg(S1x*x_
zdCbL5ye at mL#$;vW3VXcTY+x)H{(b at ZU_osm5sip#cu}^e>l;o)k=YLE0HI0LYpBN%
zQPi`PacYG8_1YodyEl>7J!$)?GbuCu`beJ17 at uk}8L$@!-G at 6^hnaF0ILXoo`_l2W
zFi$zG&8tO7#F~73OvF+<V=6Od_)BueziA7qy+~`U&;QDD%2#)#_TqZ2Un1<e!z)lm
z|AFBM;}iHAzLusyvf8thHqga*%C<H{5Yi(tcs$+YC8*3`l<t0OE;1haVLdD7{()Xa
z6yBF{npeJv`bSI4+2SQb9z?kj;`6%y?pU&*Q`NImOSJ75X{JGSvMX57frA^f{P5_f
zdY$el^J=|E6BGMtS#WpOGF%fy7;VJ2p~v*@_x+jSI;y{=aLdKT)WN6fN*VBPhy~C=
zS=^b}U1s=A;n at rjp*)vMBx_&3d$wc~yAm at h8t@|{7vJhP)sF?_49~haG9o9ls{XS-
z2|$^C7A|d`Ne+Gzbxs?f`qmdx;D at dvDsN*nUPps*Ke!7!-ZLNTOfu*KgvN^e95Q at k
z;3x1U(9zUhBjMz27&Ew4k at K@3L)l`c_tTCAVVok7Lrt-&>8qIRYTR!Le?9ti)g=>G
zMA^NHH&AouR>(4c`PR&VM?r&%|Jq;=_+MSta^qWmILwqib+Yi}-#JIle(TmB=SoyD
z(n*u=)sW>lZxyjR<PLIqJbg%JGt2yBASC;5(nP?bn6iiPjq&fs$YKuHiI26$h8-{X
ztW17C4pCcx(L-+cMd>5R`rS-&yyAosJp^p@>^r5$<UUr>QoLeHRqyua7A)!ZY5FNn
zce24*01HAbJifadB!)h@#3%MiT>|vir(Z_;mP at biM`~9c5Cn7!-$Kk#JgO5HM!&S(
zimgvL1sn99p-0hT;`F*y^U at mei>xw2(9(XBNY4QGJk{h at s<`WnqlVP>ths=lc1kY*
zmM3&N!+mDJ;@$iu=l2oj&sVx at Y07PW6iE*&^=xbFs~&HYOsm}uzyiUPlcTiw=hWOr
zV;EYyioW2v-sdTfN5~&8j!dp%leKa{0!HR~rqpO6!~(cO7&+t63+vEcPpgcB(ajVC
z6kr!v;TW2HRrKuhPw31=BM|h?GTj7tk9c+gB)MmE`{Ra$w?CA~X;VF&)b!aait?w_
z-98(ChD8}>*^v%-yQMB3HZj4+HRtO*m8BhpBEau{)cWbr04!s- at OFBjp?V1HwHLyb
z<C&h8%WC1wYp33X?|hn1dcHyZkq>j(|Fp%3TZC2ZMeJ6&J-I2T<;(1+^?e}isXqaG
zK))Rgs#sbKUZ%zABlt7|KblZkZ@%C9Yv{(Ld2$a;>DO9RLP!r0gi~TQsF}{1HXT&-
z3w{oHpZn1Q@|wE;e01+COu3!jXd)}eteq4}K=&LDpcK0IxhNMB?j?>Hl9lW|fdr2R
z4JacbL)i><|3z`u)uXewDW1x=U7rfbN{W3D5V|hr;na at 5`5BSex3QJ|sHv?qq7Mdj
z#NU;0$ge^N7xt+bej{iwP>^}aUakZO<pc`)4HebZ!QX{et+g=MHu{ogEH0l%{i_C%
z7JhtMWB!plV1Ubp-{L}2ja_XCTwaoj4a(7}q5e3YTM#$q*8)Dqv5`fTa at o;e9u*k=
z{_9|-H|1+rh1f;M=i5eC4k0oZ8VU at 3?A*I!2AOJ3iL*QG-{cFsSV+@|wjYm<fLYKV
zQvm#*w&hG?o}0`na_DShz<<k at Xhl>@jlwz|{rMsv?sKFHEMJ}$#Eu4Sub5CeGgNik
zMSBg6G?aeL9n$xigevR0u~@7fmdq~zwJ3JJL`(`R`NQx=%^Q;+w}{zY;>c9s4;Sp;
z>ESBiJDQCm-oVJeWOL!8TX?c{pr`g7Kx-vnC1&gQfKbr%xhwb^5KH%6`TNt67th!T
z8|;=~GGK0_<0>YkC!=?}|EM(L6R}ax%cECNxB(pvRu$dJ!=L8w0dJsQxwu!klg`e5
zv;{tyFfi`jsGI~yCq7*EM9el_o-JNAN4!?~faGhwO;Qe8cP)w at GS5ekCCVxVS1Q{d
znu6k~Z-!XTe}{b5>v|XX2joC8Vb#pWSzM_W{}3#{Hww0Rc&j~ev+#|rYeQ30Q-OD#
z4?IGUM3-D%IoO}Lx$MGatCJ6|pSZ&WRy~(ke>6RlO%z#JrxmCV_P at l~gu1U~fuB}l
z{aqI9DW?c-OL+;eh#fauD4UfGm=tclDspr-E~sesnug~qhVH-KJLMnrkK57_f{<w5
z&w++-t($pSv=x~=H-1VEN2ieA*Dk$jjUFs%Ewo?JtpDR5;ti(lX61W;>Z}3jQ+<&A
zcWC|OwUp-31tOu?5aR%M8=ih&{{ehsh?V+K9bw0?b-JD`lWFT1;@#3Ory<=O{x7Zs
z|M$u5-=~I!ua&q}Xl897eJ6R+GoO|%bEfkO!V>Yx0{MdP*zOl!*CouxgeK5jxTN<N
z&DCy2i^07n<t5^Ki?&;R6tF<?yiVhioVjMG5w%rEE5V|3#egM?W)W*QDR#iQbG9Bk
zhZsL;Wgzfcm3UME)FQasufUH`iZgb^sp^+)axr!QJ9UKA*;t9`-uThRv5-cU1jLYb
zws#Iy0F&CSq7IJHLN$_34y&8M=E3Ik7r<gKr$XJb{R!OZZ{_6=Tt7O~RPnd7cO$P}
zMNf$+Mf!qoLtdWUB)GzAh^pp4p9l`!tzQQMpX|<tI%{}=H)kiX6A0}A3g&}<ci_d3
zYKI1{*0Uycl5hS2(WUFajRw&1>d`Xl)j<ZjP|`0TAqsyRwL>$BFLh)!BzYb*CP|_d
zw6ZA^5_v-Oa~`-Qh}Utge&Pt*v~~F(t_c}Ozr|aRu#;ad^FBLUnF3)({6%{(9wXb2
zXLF0r0FTHy at Zw-fH&oWf_)whYvTt+7x%LUJqpD+DXtkysQm-FW^SLG1D*is50rA%-
zjhRJ|OwGJgd-e8nGhz^9M3L;`gT<h2#{|-k#J6jL{GGH<RZ38Az6aOeiAeo0A*bvX
zgg0kcFH|bjv|`iOpAPZBaF!_QvZ6^!{-b_C%(c9B|1(Da=N~R=31L(yn<%v=&EHl%
z+Dhe+c(k1Pg0}j(O*@WE_hW+ZSwe$dc-yfxvbgFUD=Do`DW(F;eiuzY+@@#I5ftR$
z)?#WUvX&+0Rk~R at g*T9Xq6vNvQmp#OqEmd at 991rIlYnub5!AE=ZOlB*koQmr2YQ*p
zFQ`)c)Q|DCz?T8^c)T{s_n0GQ5D22FOZ|}HY_QJpk_+%v{fDw7 at 0nCZOIv&(i_U`n
zmz3=b*P8}51lRuy4RF|4+E=>fKlOU6;$w?tk62|BH$j+>0scy5=>m99_G5thq|Jv8
zUe~Smual#a62$+MLaSjh$8vL^kHb(kq1y}aOzs0-P8yt6x1w7(5EE$5)9)vim=FiV
zTLiKdppOm5RHl^O!YeKw;g&IgxFTeIH~6!)n}XdZ<|#?jgQ}STy#&6mK3HV052gfA
z=FkX~ehz3^;b9RGS!@o#_yGK-f}tMyYG0e0v89$T>LM?FylD-cN&h>W0>@y_9~HfM
z^YvG1Nr}fJQ_Ta4H8SI+lJokMB5G|r`69Oin^*;tK^K<l$e<DjyJscGsad^)j7BLW
zI}04;i6&;qyy$UwrC*xF=a~ys=e4h}!D4j7GmR}N*7cOElXHbRy>KfmoRKNu>1s#O
z=_>bOKq0DnYdR$QoufAI7OSI!aqCjkjz>xCnNWf>K_I!rxkv&fusK)}FpILP*-T;=
zQe<T_z{An)a9)Tf<#1*iQ)S7C7pP>o*1_t@$Clr|iJXt-%a^8WTCjjOzCm;4-n4yI
z38f-a49F<kvwGn+N8Dt;IjP^`v)(}|j26>Ql(>RUHiAP)TQO;uAo4E2HOwplY7zU7
z{6{^LyU$p6HlB~q*cdDr0WmL6unbQt68>Z3;-c&_v!4)Vv6tuX{WYfcvTuUL7Ln+)
z_h%YB?K@|Z7G=b6>A*}ThJ|pAx51<D`QDtkSsmKZoclydB?_I%&Utjsc$aW-@!x&$
z-xEomDL6kV>^Hzw_$AtNi`6pjYuTj5Hiv^}E8GD_xCG0&K8`C{;1&>yq8XH1m-~W*
z2V at LBLtrli2)6731p2yK{y!q+5z8meUpNV|)Q6k|-fmuF?KZ9nKj7kew~nAbI6wFI
z0N$>V$nmmwI4y(8Oo&@JnquyL7gcWmkCo^hYNC9)KEmjCB!?<yNNlC#NE1jEBigtr
ztk0oMg>0=`fXbMksMVFG{WVXrdXVoIJZ&m;9CrC1m$9#@5y;)N at Gg`!;K1{XIMQ=y
zmLu}>s at Yvw%F<6z=Zy3*`PB~P+FRxU?m5h>uXM+v+<lTK$XvFEj;!fLNJ}u4VF_X?
z+OYc3x>IP6>^z0hlSMKuSN)n=Qtfa{jnKk5OIC7VgK%T(=!4aJHE;e1?IDml*H3 at S
zZj_)i8bHnBBwxR7frjOA=nTsYT{Tb5g!!0>j(i{e!~OJb0%m(4B!i-8%KhK3;DuS^
zH_Ik_!o!VPEk6R9tzEC>8t>2kLm-QJl%&jdC=}2B(!-j2mfh-?(!_a<6=*9xUYF#<
z&2;%rnxY~8bDQ5MwO at Zz>Pbpmk}jP6B57 at rcMf}^eeiD at OAILUd)D_w+3shbRhOP}
z7n|Zdc3X8(O3#XSYJ0`6(E2BtM^-1-HvT8!2?IT*WC$<VCMx9F<4yD>F_u7nz8?S3
z&Pn;ROA~s<L?YX-pYRpp5>1!3?g7mPm^w3psR=Kje}YK5qsqy at b+rdCcije3mWBb<
zulK@%E!Xne+S(uN>#N3A4j9DY!&Zx-G2FWCq4kskUkvaPbdr;8cVov+&H$Inhuq~q
zO8yql;G^64E#=>Uy+CzKG!<`BwQpaUo!2t{C_WUBV1ZAgN4l$)i~6(yo$qXlvBI0a
zgN2N)`xYh&cm7>FzX3o0`|Ez$K77<ea8%4qVmYSkj at vIn$KTH%HmRYT41i|cl at mH<
z=oX&K-Nmu83`qGpDsVff&-EiZvKws<pBwjjv_&Nt`LCMPSN8OgXXEKraRCd_|JYw9
zXX!b)i5&vXFN4dIIAjmxO<8!lY#}jQ=qUBey&k-8Z<UvI+g7E$=TDzh3K*Fl<%ue{
zs<jxb=y5?Pwog)GdRlJw)1>n3An*YuU|l4QI-G`c$Vr{T!I_FtP_axeUFm4NaVahG
z#REVH(7Wl|grSpdpv4WXD%OgU_!fvBAEl(>CTnwhyL)f^n+1D>S)Tu?nSqy3v^PJM
zZ6adaCqwGBt-mrIfKbaB8P}V_Bz4MCep5-R8c28ypFE~(0|iVZkNLUHPyWnyZ|<HS
zyj_#(&)SVXo!7s+X_kR6xVgS!@_#g)Wmwbi+s2Vp5HJV<LG&lJ5h at _Kks>0U8{J9`
zkgm~43kKa?8ynr-f-t&AgGdd at 5u(r6=Q#c^c)=?UIBxFU*L9xf=PU{GXiEB~I33?6
z$qDZfo38RD5-z#JPUJ at obICe!bvDx37US*MNj3D!MPqtAHN}ogKQviTbk4ojyUOFE
zuT at Np)~g~sFXusNNrwXrw3mBf?SV`W-Njo at w&`SDUiZBDk<ruZ&)iV0D-dEcGO_II
z&s?1YOtp?<AV2}P-kB5rVsroZO+vXiOnYN2m{MeV5)Y}n>vw0j<Q%hKS1+f(LXAp)
zdo10_K1PwySC<D&;AEOCTfO$cT5k2PZhf8(P?EF%P3`^WLq8mndog6k|3(Hy4IoI}
z9=$5uoV?*V6Ips#ylIg_2RmmF_VRDJO)~S{0STMaYd8(|nD>Q0qkRR<Hck$1am*ek
z$-VZSt;&UyIEo96o(*q&ju9HAdeLWvw!lP8kEr<omC)WecCYcEdb&Z?!2B^5l}2;l
z*Dw_7(jo4;D3PcZPie$ibMdgiHmDS&ydmS$j=h9QN8SyXQq}m=;>zrJ4^2LqU3b;6
z-G4`66NB0kQdI~vPqGLg9R2z$$v_^43e{O1i7F7-yf%iljVp(}y*biYN%QjNfZ-a}
zmQ3}08^yvz5-;6qriV%mEZFnEn`^h2_2YKwYe&qR2U>DVm+l<h165?h6g0tWKCp at R
zg_rN0WjO7ut3y^j^eNP_MecgLohc-cHW;i3mE*w9S2C;TAgaY_I+uMpOx$4+LB*R*
z)Ib|Es4~9hC)fxjly^;teyb9Ht~fr9SL1tz-SP-lVZtA=UNYW-eeCkqu*^U3x^zeC
z%Vykl(kAJ;baB#U#g)9#4&a48h(=RSAG3QU>J^kpTmjjVeOdhIDv%6OY>RSUjqUk_
z;)Aq}oCpz~+;D$wTb+}claZ$<zZjf7eF#t-s%Ag**Dnxi+YIqJr1O9(zz}xJlb^%m
z!JGahYCvPAGrk+G^+X|E!{7vKm|B*{Xz>}SW~Q;;l;!saEaF*&rdcVCZGYsq4+G+R
z_Y0DL0(DOJf%4@$-|i-Q;Iw*LE)+}be_RjQwu9yStqEH$vkh(ht6OwMH51x*0R#1^
z(u1Fz=ICGyCw#PnxzM7EL(SU!eiT-wgKqB6`CKFpl`N0y<TUlBu@=Iyu!7SJeYu%c
zd+~vooAX%a-|#~%P$F5%q)i>^PiQ5ZPD_An-heYrDaHxHTyD*^-z3<~VFCAaC;%Pp
z$`JYo?Gp0%h~nDIn=EF>$X{kz-6sI8je>VcwC>7pHF4hRc}e_{fUe1iz+|~gAI?0v
z)IoLU%ae=53~s;tW?URGOxD<T|E`U at O<O_{sLtlhCbaEH at ua9>>fsYTxM^F$pSX~d
zRoxf6OgG^lO8DMEY1cHwI!+pd9?o*`oqa8n8nJHvi4TlYgQdBQz*&oj6>o=-+EDq@
zIFhe`1o{gWj~IM;Ga9c-?cP#6Bfq08q1*iLxoUDPixD7?xMOs6@)$&jVTd`psBHhN
zs at 2)Z$_;Nj#`<T&s#1G1kaX}ply?ctnSB%CCUMc*8nA%9Th*Z-6;us(_EbydHPHJC
zD)q+N$MlW^qto>4f>vrbJF8}vlS26Be2*qcyC>pcSrTvl%rSU_KfPXVLp?zm?L`E<
z0RQ;d0CsG-#?A<*QXRaozV;vf;pZjDv4j8?>OKmr+KyQPM(}X`v-b=dCE=Pt^}BC0
zkg=}tD-O_g?&F=Ed&_I3BO8JXsAp~s`1=PCFt^-*bZw(R0-Wgs!z+q-mFqy#z9BU@
zRfRzrDp!4PJw<@<>)g;OuEYft40P8*nfpI>xCy;akfmK2s7PY=M<S8VvWv|$w*GgN
zkW=QyFc4MxeXqFQ+`M9rn at HJ1vJFLQR!rb-qgqJP+N<vy&qIC#t{HhQE3>X7t6qEb
zl$;V^+tm1;b(#%pEMG1h5Yd9!rE-hm<vIrqwFd<tXilpux*<=2J=dhiigj8smcxh;
zcNe`)>dQ|7zt<j(5JqM`WAEhp{1Si9`4c2r;<$v9*!7$3zw^16bUa6G%We|3)IxJV
z!vPiiWqRq<8H^;jo?Pvv{sy8wKY)LNPNNCO2(78L`R#6jH}h3V7TZDKWW*zj8ZYOL
z%W-s`EA^P*{I#m>caw9H`Ehk!pT^SW7*o=G-TyG>kyBr)#R+mPAarUU!}=~7W6ScY
zTQ(mqbZjdXK}1?N*Nx)YziZNgD>+qbj%1)DlI8h-?X-*nn9(P6oStfCRJJkFp2JF0
zsN$`v5qhfw53@!k3($@iJ2ubb!yc~<_f`$WTKmZS8fI9#UE6Zl&k7csu3Ze^IDY<<
ztZHfzPLA%aGFqtgzPlPb(={!UzRUVKOJDZCzcs;|D|jI4>+ at XY|Ha&TfuXr;n9zO!
z*j+-^_lN5}zUtOOt6bYt$o7HG(@pO5BSue~ZtqTZ)i9}OC_i_jn2yvDk%+bHU-`Y>
zSeGGxI9QtoCXDdbKO$>dikz;0%{_839PsCemY|W|D_AD~y~iQtl?nQ#POo&+JouwP
z;-sz`B+2-F#c^as<^E!8wVCBLbXBe at 9Tc&3IeWB(EDOW|&jmy}z*Orw5z9!Cw4n+^
z=~c3wW{=-e$JQ_lFt;psZo8sc=|-M^hJN!~eY<aNm#lX~AFU3rEy$aY7(>-}`NO{%
zaeBZ91v6-iJ42qei2eZITimyOHo4tGWxXZF!DN^&DlAg`yhFPppW4ytSF6}is>noD
zp82opah)C%q*phxYoJdi8?$>wyhEgrFVS#Oo97TMPgwo=*)1V6KAd5f4`yUJxJMgM
z7|+FZ|LQM15}C|L10KTemk)%|C2w2*ckhHFAG4=n{Di3){&k+IO6DbX!7&}NKyeJL
zAmsW#F90YPM*_3`)*g^MZE!G|U?~3_oRLr{xY7Bc4>i-DV-lrCH4i2$H5er{__JZ@
z6Kd1nm4M!ctFULgzh at mz)oYZNn4sXyq-foT`zA2f<a##>S{hj^8{B6Ne1BlE)7<l*
zsg1G5>9grR|FFDe^{}pUAPT<SY{K>W?xT0BY&;b81*O#>)L43?A=gzwlD@=GmYlZF
zoFlFQ`!2vcqF_PC+En?Wo2sYrIRTn9ah@^0-?#{@NTkY!mt&vN>}sfo>EksA0H0m5
zo<4(%Ds%)B8e;JfaD^U>BI~<AzkxO-n%;WOP~4;HNNsE0w0fX$DJSCuqWO)LUO+=^
zF=ZVz23$6J5!%M1Gj6GDqCYYQH&3+gdKQxyg$3^GHEd!4n$V5NiV-hs=05Tv(yY)1
z0JXRKnI<a**QO_Gv}#fA98pIYb+MX0oqu^h;x69j37x%TRU;?y1ve==Q2av+b6Xbi
z$kfC{aPBBr;Q`)l5SGcyYnKgMZcmabx7-N`Ux=*2cNq<*3A8peqkLCM8V#0lcwVUf
zf8re at s1~|pTdO%yOHLP8=rJJZ5~Bsv`-c@#@Xs^rQ&BG93sl&R=U1EmsLA7I&ji&?
zmaA)?{AB=3(y4j|y6(Fo3__~e+qp at bHeYO{zWqsDDb*MfcE>DU{X_kWieu9_Bkb-t
zo{Vj0D)s at 7WrSES0xjz(&j-5m3+T&;w*G1EGPfCgcQWxf)JEPv&;wx6qZGp?i&_I-
z{4yM;LAfL(i5R$x;dV&`J~dW0E@&SvrM<D2<XtOysZMhj>3F130kzlK8T?l4Vi>2T
z^;(EG2`^|W889`<+`N}sK&JG-WU~J0+ at mOV?WN1&;$T(dR at ky(c*i+8IFB30Wb``e
zaMrNn-~EhW^xj9y{fsU<xutcrnXkir>sJ#@+HSR}{`pBGDy(Fxz|Iy{$Y1HE?taU7
zg>*7o<#Am&J8u%xV!i1wt#co$J at X6F|Hw at 9V0^U$chrL3lMMJFi9Z0!DNMhupgn#_
z98Oh-g#%&Q?G=EqXdDUEnd2vvv#qn(6`h@*pXajK-tN81d70?1O)UUe9ZC;99rsuX
zx0>l0{(<YttfNCKfV08gA9w5X4gKlr8zX at I^CM`;#adIfoVbXRvL$uu<m){I>X%7n
z^E7Fgy4VW<h7qr}5aFK5*NYwd%!8_Jw`f%!^Nf{PF)87KjNM;ezP`Q`cOCgR-ce|3
zajr|C1xy at UQc`Ycw6NKqC-`S)1qscQ$>@)Rk|&~Hx+>0}*PeUqBQ~kA=-|~VG}10X
zKtiI_k>5!v at 9xa(#tYbQ_GMNLDZZ!u<5DkX4fKC~b_^XrI>o)G<#*C|F8lA0?kn9O
zn+?b<+d7y%@O<cc>V448HEU5npoL=@BL^eq^Xo~DUmw+HrtdlQ0i4vPTXwJleI(LM
z4HR6N|L2mV2=BhM<nMtoo;=8Baf_98ZEt8-KBx?S)MnDJ;0IQ#PNU|({sSXkg0tkR
z?KP9y=dgnRNZ|D3KvncUitfCoCAi+5^>)cnHtw0;xK^7bRsN0YvCIWi>N{`fXD`da
z??Sz(*6uu|dJCIEy{+O7*Q$oI*U;!U#<_)YvGK^MG?gKx300SumtrEy?>r2D&v^gK
z3`3YLC2rg7a<Id(pJFqZtW{OMs!ZKCBV^ay__%2qV;{qX5lL&GW%<%475JavNDtmm
z0+he`1u=KzbNRZ1at+`Hx$!O#nzepQ)d6UE*LbNHc=Mb4gLc+uuK~orNsopDmB{sp
z-B~qx=WuGZ`AwvBuXzU$5 at 3iq_!~2fz4Y1KQ%L~v5XueSC*}550AN_&*-=sbB)UoO
zH^bS$MmZGhtY8iHbDYoec%XKa9PI7fhb_1f$6&T5TM(--UEN at 2j?UEcP+$Uw_aI0d
z!e=(?+zT2_u0jAv#PHUWzW_uSu{q;0Bs^VXxYMdVs($nD>(quy_YDcuhsQBJf-wRk
zW0D5%m>F0G*`vl_ at MRmuc9!`4r8ZNys8SNcq1nwndHQl9i%!%yS*|}d$W~MwF*9>b
ziR!+3M%b15FO4|9CU%PE4DFfKy2f?0QVGOeiEB}8`2dk90nT$ja0gN at N#Kul%Nrxz
z{*7(?2T^8gw>zxr?#;HN(jdWT1f^AFfj2sHybKRa)(BN1%Hh|=^z`;AiBSTsj7TQE
zg1MSp&_-8HK}0A5&B)34J6&i*y<=Muyn&`vaxPg-V-&I_Arm?rrf}gtg5~qcV~(}a
z9h443Gw at fp-Qe>}qQXyUz$UbV6lyL%!LIztCSTX3p5@#xp5>4j+G4Tx3&;2>+rAiO
z-Tk9KF$)=qA18c`BnFmBY at yUpbL*Qd$b5gjJz>X*J}bt<q@<)Y;0)>R7hl{enK=b+
z-DyD_!Ia0#5;iQgDG{&q-1#%ga at 1kC%kPnU at 5?abY^JdMM8gIt at 0d53FSS1;^!aKR
z_i?3M$=t{UNYW4EIyb*}Mp*!~&Z)QZ*(j(v)r-)Uu?Fxy+T`##-<0^2GTBdT?|N1@
zn)-^|vMqYOZJ!lG!2ukJThY+Dejr(AuS(NtjJBW{_B at D$T at ju7`k_UL?xUGk<G43|
z+09r#z~4zBV_9O?bn(EQqqpY2A6w0umMN}{JtnJk#A(3oK;`i at TzZAB$2L9T at SIOj
z(>yEc?LBS0^lEHNoLFIs)ySbG?5Bp~<n~9-_C)WPuiF;}liV*-k!Q%ysSVz=V+;2S
z?Is5ve!Eh8(T{PQvzW|RalZ#HU>(j7-*<$(d!b&9!QCq<!FDRr4yg$XD;EzyrAu<o
z>9!NmmW@<FT_Z{}iQ|Ix2i_j9UqQ55)Ji+!535P`bN1VG?eL(4>4%v9*|gNzN!986
zUpm*O-dzHCu7-b-D5g=_(xta3!H0gZwj26tI^`bP7e48*k@?u*B;uBc&R9kI)?uFL
zNhOT`fo>52WOD;+G|oeTVs&F#SD#$IJ5<DRle>kKb2^J6`z~=NwluO|kwdTCeq$(q
zu&c2 at V!C2qQ1w;O0dDu~K4br9g6=Z3 at oV^J<mj30U{xcJ89xlA7@^hRQR5dIES7-c
z_c*hsDc^gdpCH<Bdv`ZgVjnbS_7OX_VXNwCO0b5 at p0a>q&EL(<l$a^X+meTo at -Kx_
z8}V%J$5~8H9XC!fF&n#jNbhWDKfQr&U8Rfjvh2U%X at j4^Rd#|!(<hOIjyv#?r7reN
zU`EQ}mE%+ONDYUQhXHzJl;XW%Vhe!rRi!8bQgRnxBBAlGnM$YCIz3?k`B`C28G7){
zs+(Oa6Rd2))vh%h1?4AU_KXPn=$?tBR&ZNF!huDeMA7LcwZiYi??PgLb6VFqe4#tD
zfd at ZI-bT5u<pl^DtbZWkZJTTNO*S73Sy{oKvU#xze3vy9&Z*gkJbAnzlcxw)S-VsB
zbxUquR at kRQDnR5qqa0JUdm4vO<6bvV^J~J-O4V#U2p1 at bVkw_~s!2frx*=mMzWsd3
zMjB6?kyQr2ozx;a@$XM4mFP%;AFRoNG5DZKjxo at X{eitnUw+rX?(<oc3^E+CFo3QD
zYeV85U8n2TUm<c<#1#+Bv at R{1%7eBj*|(D{9y{s8SPyq!+Gz>ApZL&D-es=Q!*z<M
zr9=PPGr=_L-8Os at H&*Fast^(yE;--S)RYE%O^fQ at 4#oWKp|#$Tc(cv;ti19C$BTBC
z?u~8ca%`}O*;{wFwrN>~cb3dF{=d(h9}XEoa#|@2)q~MMACzuvt753|eXK2?I8Rh!
z!rs75^mgUdyUJ#3E`hwlRCoiEvMRyj2 at oOf=t3OIR1TQ_sg7rXm0aLngHOCav0C(u
zbvsEn)l2wHoF)oG{;k#j$zD56OP;0LP{(>sc%!QA{lhD&T%b-q2lvW+X-V`6<MV}Y
z1<iA^)nhNHN2Zp)fB)W-sq3!n^U>{2319T+9{=Rg_bSELG9 at dxa9+jto1>($Vd1Qb
zg8q8q6*61|8(BI0sCODLZeioqe&N<<-2?pnTZ?Ug at t)5ZN1N#s{zs-#Nk`ew%ggJk
zv}XiBk6a2?bl|j|!-?5H1Gin7=-LAQ`X2#Ff^K%?6l3xeHKQ(e?y9lku-nnl*On04
z8nK*sE7RA(8Swy9c*VvV&Hju+&|^=jHi at -GZyQ<lpD)0qkcFB225=R^Q3fR>yi<n0
zY$ow0h7X=tzup5{E_v6VSPcQhEqNZ#s#H*ulBnO_;79P^e{uN=yGe~3V;;BeCo<OS
z+!zePUY&z#x0}<r2*TXo5mwTKJt<3iWn&+)uL&XVN*h1zb0T(3)U1rt>Yh^C(`Y?E
zt_k!VP{Uj(BPwCoxzFKeHvE^dz}g~uXWn(;rIFd>WoIbib2b&R<k7=${R^0}1<}>#
z)<jR!p1pSx#{iOfKAVPvwAo?G&y?}BbjrI0u4zCEhs?pz8A|WO(HrmObsW4K&N$Wq
z3Q}2+m4H3EO6wkNW}a{VQPPj~3zvX_s>OXtK%e;2oPl$P>%5s=(TC)t1h{Ex2N=I=
zJoD^0{^x+8pm4gx#|FWOFj-<%!QOT5y=oovL0nbj?$mF(ZAo>%DyF+c*QP}0PbXvs
z5*nIgpfpB)KBs{O-G!oKnf>>}$|iN;<st<=CdAl&Eyj;_XFEZ>Cswa>FW%~X!7t6r
ziZY=-SG5R@;62@?{!I+QKQ>EeL8Z9<nHpoQw?VJC9&M83b5VDCX0cuu3cGohI^xYO
zuvG~KN#b$3S7GGA++_qB;)#?T=Uel>^_NloKsXg$-j%tKNwmmxX^MIl0Y&M#(|TTy
zC90sS=Z-9plXTPmy8n#~8B!a0#zM=`#o=yPZmMVp|6%{vhNQ!gXei^g*`^F>#Vb;v
zvxQ^6WK_LWYmzCHUr%6VCZ$GL!3?1F{dvE<^hgo7_j_OFJ=Ftk0gzAxX1y_^2PYJ*
zi|@La<sGOJUh3?O`c!EMDC&G&MO8rk`(;PB-?YZsdq!1Y(f#V(Q<wU+f9~RcM=TsD
z0TGNb*<qYHDVVKZXzsZ+`FM{c8tQ+(k))iOBC$Sjec*QOkZr--^SW!g6nBJ7aA(i|
z2o9c(GM)c%T++67GEC$atxZ&qa?ldp#T6fJ<g9c~d%h!ayf(DF-NCI<R*@92 at 2RUh
zKcIfTPdVfu7?f(|yNyEV=%yH-%pmk?x~ysD2KJ-^@JGgLVe)kcC%>G`Mss%A at 34O;
zeONfXnd7+A;7>=&(j-c!H85Vf(?}KdH4nB`uC%vwgA&|t*J&t^#<GM|?5i1HDk)|C
zh&)vhqhCEjC@=2p?tU`bg~YMxLWErRgjEf;n<~5X8cP{BJV+MSw4_S$FVHIx{uq}4
zNAs2LI>D=gj4(!LiHOFc<M{GCAYSg3c*nM=Up&|88$nK%q+>hq3&lNartkC57nM?G
zq_)lHL}4}HXgjzfTb|*sS&j#0hPwUR$XSZ9{NIC7250unP|EviE(eQwC|6LcqBE#Q
zN3`l%DqR(nS)=S3)D6nR?Z!#b?--;4a6+Zx7;k|L?I)+-%Af`tEu*k*Pg*x)k#_sv
z38_!J))&bw78sT;fkMJ$MzR?P?T?*Rts?z*3AfbKr>d(LxyXU#;>BQD$q;Pt2XL=c
zjg`U0%gJ{4=WXYYW>{}~?n<%yX=rNF$9sIF at _N9*A?RBGd^!>fOptp$>^PbzXtPwb
z)icj-<sNoX^Rlmn6fbA_GTpKA(9ipTaDF{=uTliSCt+Ds0l1&&;OV9aKkWC`2k5Em
zdvX#8$$Ofz at ITLrSRb8}zyzONI$BhCOhyXvXUM<%8aH7RBea1}MC##MXmCUJ39^ly
z1}p5_wU5j-g!xcfU-7D<1PV&Q*oA1A0 at S?Vdv(uNu12|RY_3c{E;d2kI(6F(yPFx*
z at cILiNan($5kR^PK!7V6oBgMY!!wV`ugNjml5fyVM3EGGZ8$YHuR%CzK0*gQwGuVs
z0fHM<CPg3|3EFeGEz^U+6!~pN(L$=TRs)R_BoRUWlkdrQV0Yd8WsmSKhY7sy!)`w;
zrg>+W<Ljq(1YqT3DM{l^?j*jGFV+$g+E_yx3A?HNmY%qk>Ou-`rU-lzV{rMHK at M4{
zxREl26pDgHU4lfl5{(;w8A!D99Q})ZxsW+7WeQ0}s<OUQRbo4exz=kuZBVevJUkV-
zg9J=}$ci1Ecdr5zZtZ4Q=seoYH$vdXX3h^bOYOm<rakrAPYa9{H at Qoz(;l;it7uR&
zC_JnSB(mV0pRt`l4PR9snc`O#h5Ktm&>-VYuP~^NEyR1On5nR6VyY8>LYnw^WJKjQ
zR!j?_D%*knROsGe+J^?<F$99FsubEYS%=1-{(bMHU_C<lmGR}BOIFt?WoVK0$LgkY
z4nna`6UC at fGgJ<+6lM-7XM%15v2$_FXP#le#NYU!QS2?f2#Y(N^5jd}$QJsi<wRc{
zVM7>h3RM|ONy$awXHI7)dXFWrH2K>kTJy^homEql_qnIm9UqxJSy)ZKDx5AW9t}@U
z68CaS4>aIno2SHdBnkX-)GOgm%>`C*QyIdfj^ztPKzj(CFAKzQfDuB8)~J=QB0Tg_
z0wXXj&?7Tq7YZv_R}kWM%Tx`sT<F$MkvH at q1Eo6l+->h<^QKoLt+M)y6dLTwdss_<
zhs;WG2rUk28mx%!$#Z`5SEOC<U_o*c|9#2%dB=yU<FVcl3Yn~sz?sdGHkt4V<6#iS
zTU>}^x1oP20B}(J)F8M{V-t7KpSm)Y6DU3R4!x9<c2iGC;{8`uVt at 3QWGR{el`nE0
z_rOg%IoZv{J6&(P>)ZA#T}m%v)Cjoli3)>u^O~U+^G8Kp=eWG6d%H3cinH|9)J*Es
zFOYvlF$_*~CnZ^55;Vb?+ at w1$=lhMV(B}6<Eo%7CnOe5TaUvZP6q$$8Z at RSrjT!Qg
zQ4y3ZLfG%6?_g^v!+O{$k`o|_xoa<+I@!6?Q2Btu)Cyp%rY5xq-<p-WN^l1QlhLM6
z9F^?vRiN5bQ&^4W7A{UyGvWDPKnM>SNZvpucx?IhFLo5a=}qqCwVfUN#W1dUQd)0`
zFu<<}|K%s}PWoTE46gtyAPWKbE7<{pX~5M9Bun?c_GL)iOsG89v|@A;Q}{=WVG(0j
z#dYC#y+bO1cjF`94r=%Q&)?I4m8_^)K44fR4!TJX<S_pg)=K_Tu$;k%{vL<V8q%U!
z-=GEHb)st%Dd((ZEg)v(8!0 at ji+s)H4aFn)y#3IQ2;TfHx{{KbHsF}NzA$jb`h|V-
z%6E8Lf=o^DHnHx`%CDX0y4DZy<ZzvxhZWLst_}H>oQq~JY!$$L+%BZD;5)6*xPfsz
z?$0@}Lqr&Qv+V#-kw>@Q55Zc;P94FgJfT@*47!muX%&f$W^M7ZLFnx2_`Wgp%@1&E
zig*5rq_ at Yo=bpp+ReMtJ?)9_WfPN{sP=U`3r0*Mk3FJVL8rqtV_1}MMACyftSKz+@
zgg`Z1j+qWplnfKzFKnZiTM=_C_n?+1el`h)FE%9S>He}kfE;6V%AWSEPfIhG+J}vi
z!o6qUm4*kH2}kG at ma3y&k!9ququDstGCWn;{8tP5m5o>_NShmsrIJ^{(@P5FhfHqD
zmkIE>!Q?9~45Q+W3m1+a=R*HliOG;`s)TGt_NTgh0|34x$scD|Tqw<fdI2}*zCVUr
z8-TrYVF-8)d#AX20PExo^%@%Z>^Y0?A7J12)6N?Ic!QN-qp&pmB&Ymv5!aG?3phhr
zx}R#8VnlhaZW2B>f|B9O?}ohtTF*QE`u-yDnh$a=e)>{+0_oSqe;qq7^Sk`8ZR4Uq
zbrg`aituC9n%$)H)QK|cg2z?;W%Qh3sc{0>0Kf3!?i2U<KF_*GjRGPT*>SB1k>>l@
z+(nYQqx at J*on5q0?pT6ym`ECWH#e;-yl`iiw7~&cuqJU2rhp<e|4`@VfizO9u^Wl~
zx5o|goXIhs|FZK$KT_jP)ui;hTeK6(_lfLU5=uz at liWRzf&!}ibyO{=noO6126~-x
z6!QtzLjJzCOx^V%WiO25dskAL5o0o~)2Sznz9cyEzSdo6lQ62?-eEiKVVUtQU7zKt
zW4aWjAQ~H`Yv^4pGIzK;Tcb*@tYE)9NMmH1<IaepEaFbVP3#{5$#|w}&wU;;RWj86
zWNfgo7~}PF!?CHRiN`^vTPQdsWBAW~?{+tv8sPvQvR9!pr$&W;xXR<U|8ua73_9!r
zg>JFssRx-ghZS&FXEM??+I8z!4WLF?(7OXLh)#ks{d}BftZ^h9<0sZM<$iD1%ai*h
z%6x4^CK=gv%^T_mkGU#}^3TvMhc2cRxZl+|jQ`Ix^-HKQdeP&ZO0uLf|5SZ=>iyKW
zyTchJ<zURNZ}<#aqtX2d-u&eOU|d;H+HyP1p1St0>JLzu>TtL#K&2Xfx&{zDHA7!F
zSphGED^<X;x!c@}O7oF|903UVKcy<Me<?i0bz!C)O|;X!l)Lu;*WZsl0T4`Uj(}{_
zF3UzOVqHN6rS)<!6>Hy&7?<jfb3Mr|9X_`Jahfy0<kh2*il%60m4)5~5uQAC%qeE?
zh;vY+1zNIGB=cMB(SBM~@kSVOOK>nHU&jZX>+I>uWXbuNfv`qHs;HaEr14|u?OGEO
z6Vyolw!K)>sH9$EN?A|ij)|7}_tF9Ggsa_=ED_O;kFcj`H&FYoHB%|1Th#w=aLDj^
zerL^gPKOSak+q}!C%C4(&j(knv1aQ0+AkE!sP+^cKKdPN<^2lfs+!!jMkDo5N{;||
z?v9tCcb}4Q+1T6gZv%i<LNyGtK?QWjd%y0u?`IRA2(O^6U98gj2&eU<RFXGzh$EYq
ztn9M<VMI1TGr<0=E{gjX{8i_6egZ0}p4GXgEB{kmg7QWPhLf*o&)j+pZu$`H6#Vl_
zt>zdC<)O_VKqg$Am^lwKys490Gg5B3Z8RR$9G|whjk=L*+{E;WUqe5~a09tBde70w
zHLJ-#->qa_dxJmj2*ZXRLvGF+5+X4z*PMto+j1U9AJuWF8xqtr9_n<vo+Kv13PJXk
zE}Mp at A9vU-ds=#<kyP9dds(t<C3)1O9#aSc>li)7Ef~`;;7zE66eRq*Z`-MhU$Kt(
z6a}@rJ;DO`>4xhv4SQFBLfj^VMms;o3858=V#2C%qgLtA`#5?Q!{`GKfi8Bi#pFGg
zdN~Ndq%aKjuoY;GfQJ32W}(5DS{_)nUltLvP=HD5&Fhr~q^J7O3&j51YHG0J{tb;{
z2C)JS=qsr#-~v-h+#3*jj=DG#uJ5{xYyIhMetVgANTo3v1cKI|@XWk6M5t;%4M*oI
zR&O9)BML0o1|LfCIl`Le$Yx&S$;uujaMp at MT&ZK7RHK+klD4K^jV%8Q_h~v;2J=aF
z=Bu3Ba=Bsb1;zChwRT$n&{1ajz|S}^k7s|tI%lKS>6EGb6Yw6cyNmgIv#Sff3Syxw
zeze!r$=sA#|2?&XYo*JK>Ly9i4X!^OU;$}WukGO8--{OfNBZ%C;d_e?9(S=A3VM37
z!9`c}V at lP{mg7gx0y8mR)Ul<jz+AZ_tL+ at Qr*4ZV;MEhDm|fidQrWw4YCwxVoXy+|
zt`2I+emRiAp>sH{D{HD!Ui at D{-kxXEo9L&wwY`S-s^E?V@*g at ex_|1ULIE7)+j?Dy
z${xR3fx$+C5Qky2)}Kc1AZkvx86>iF at dnC2;|Igu at 06clgTu|NfL7K{z7CYdBCx_9
z0v0W3nyW at Vri4=*!;A*ZDZDgt(gv6CYSCNVBczlH>IgH$yYI3<+U#ztOFyxGlW)!f
z&4(+gisF>3Mrrb2Qj+e1m{ZnMII)d_L;0)11?oG_hd}C6bNLqM+?S)d`0m89YU}?9
z#b=T1ZqReUY90&#@TC7E*ccgqG+5;)jNDnCHVtSw2hbddo9vFMZ{ijO26pE(Z{vZj
z4Ljto<IcdVb%5+iEMAUveURC&RdLK#b;j#hQa|LR3muQU4>u|a%K&bxEq8!B-AGgs
zPH`tV^dxxHCVd0eKbvRW>~mZb``^`4XB2>@<!u1_iJf16g<oMYh$Kj+?G+8V>E_!a
ze3G{wrIcvJq@;w1H;r1kC}q{!nKPTon9ogW#gyjnRqd!B0f(n!QYRRftyA++GQa<c
zk~E?mPouqKtcIZC-5{o_yjiJ0l(%a}sj8xnapg*@*)Z<|jwp{%w}iSi;Xg#W6bfjI
zLp<L^%dAqBaZ9bGYHa=u2sG!|HRG*lJ)+aBQ|kr}-jffyr$>HLV7A3&S)+ujYx~ck
z&_Q?W79kp_0 at D>dZ*?7ZO<1HuGzqcSqfvuc`Q?KBph9ac@@DlCW7y{kyV-}WO61_F
zm7Jodh1hP&C$bn}W7c2 at TY*xhVj at -Ivq}&CjHeZ#iJ+g5+sHSA- at CiJ^a`y5$I`i9
zd(7p#O{G^>%MpJ^zD6*2k~<9h_J at t(m6Mf_?&<~t3)w{A)a+ETM_^oH<FC;JhS*+3
zYk`<~oX4E}Sd#pc72g?|2vRD#eNWoN*cR8m*}R2)Y at cH}15=Df2AS}zo|XYBPX<xp
zyECnpR~Sj%nXJP5dMqV%PcBr1A+eaWP)eXcz2>v7d?C)&!6B_X5_+E;pwed~{rjBy
zw?+&-t^vK%Qi&mIJ2KjD8*}$y>Mi##fw$h!a>G-vr-Rrp!1pc`)J+`R*3p}t-3d$o
z^8)m+`vkkSP92$)&$_Mx99V!g%LI^JJ@&x29ES)H2BQ*U?Byz80rLH_YW=&cSaUcP
zsC*V5ezBCo at Es5&MCX1kj(_b1URC)^Roy2-3y2DwuwT99nYwH!hHd)ICTAUYOc(B}
zvhH1BP_wzE<$iw);*O*5LJfzXmBg`!>sV^3gh`x;)H!Q1pIvn|rx}-`K`^}^r at 5FL
zP*I|3YcEq>sk1?DS{Z-S`wWg#=Xju+KIN`gQzm4by(5~u0#$$7ZtdRfI3V+$>ICyM
zRm0#*F_o<RO^{kS^)zMB<is at 18`LM*iv}Wl*wK{%3|>1c`n-L5$-Q1L#>=qTu+B%=
zey!BiYWn-iBK7TRT13;I^&%&S!XD}d(0jw_rb0S>vG({fL&gVNEVzp|=(y9T?e#SR
z;d*xJvVk|!USrweNpw at PPPVr^cnWH+x5nHx9`^XK%dwlO at ZO2m*2e3re{I$DJ at -at
z at T?E<=kDG}(Qt#@45>Ew8 at jOu3~bil39ltneFm9BGTFM6G*3u8eta89XKWpCoI81@
z_(aNK2u{%cl}`-DAG9d*g>Vm!C4mfun%c=4T?)qpPJNTQ8?tu#I8PL^7hgP_r1uj<
zhJlcTfarN9S5*5{zI-5e&s1=Tv^8VP0%Q$+S$??2<nytuhkafQ7nJb>%x}iRqizRF
z_zYkLG=P4C<cN9s+M`L~zW at x>*#!uwlva*O<27$=1D6!YF{K!4_>@u5@}qcO6&GC`
z&_c;lF|7170w`-9Rbl!DWHU|H6e0dQ`qJ4x7JihT^-`z4A}Wi>vQ5~QsRh>Kw;G(P
zS7j-whrZ{L-825g+HAY82>hInfeK_O9nSwYatJbSI1Y&My?tpZDX_(9$(bKB796^8
zyQD4*<;7Lg9#DAdI1+_Yd}aE91ozmEZ8%Hc>?h~fE-Qy&zNe)Yi773d9$G164<YFg
zF;2gs70HCJA`xS9uR~)=?fJOil?KM2eJn{_<=iyJ1Ad=_(zbr`lhouEzAc=5Lc1}S
z>y~lzIOVabzy7bsef3{QI0muP#!2_rF5<3h7<wNpYm^jPX%wv&x^ly9Fw}`VrcPj0
z+%+q7pHx%r)d}4_cJm;^A|KV#_4jocdmi_!mFC!M8o#s^_Qz$iLt>-ECfM?NP3FZ~
zzoV$JE;^p>;6o2;kK)OjD&Fs8BZbN7j<&_y^4CT3g#vt*`*71(*Wt0K)C?}@BiyOZ
zyYE-^o4c6~IZ7IQTs@?TJAJr_X|A49S7pQRK5nJAa>T|+dNa3BUCK;$t#$=7j|Vz~
zj^bHAqE6S0Vyd(}z-oV#a1wj^G#Bf|Npm`%?%!?Z78_GywN$mw;L^B(kwIoPq=?0R
zS_=4kl}l!%6nmrzx(-^`#8>PX<j8|!6CA85A;~Q at P02z|fK$o<TD(5_(3dL at Xy&r^
zp9HpPJc<b7kHD)Np2hVWr2s$AT+B$5!CI_rg%0Y?jS~1h8)Ms9spnn!^4F#SLj?4`
zCZL3>&H)}{0bmQ8|7l?2iOKBfuhP01Gt&Qh=CF13c@*(<eVzgtQ!Uo7 at 5)1oIK=aZ
zm1vlBzSdy6ZkgA2#fJAH&q`MR(agJWRX0&$c2>1|?0Sv}T?c2|2Xx)B+YjHwTRco^
z+!GUvzBrcp8CUT++viyWC>dtqN|o)#%XiK2^W~Dvuy~(iR4Ro&7crFoGghhTns@>i
z!@ZHeMNz6A$@vIxuYS4XzfgPMXH(S>o`|s$BTn6oO7_NDX-qEtH+SBVm?sIzH77}D
zH8Daly-^+hg<Y|Ztl&<{-j)XoiIU5hNBe(NBQPE}=5$6%9>~5Zz?tkp210eGyaHNZ
zFc>E=-xTY%2}Xpz)`px{?#y|7L+-!sTfaJ&Nr35Fo7qbuRpAcs4s?n&7bmjbQF@*o
z?G$lzYwY|&7<5u!1|c_MK8<5p$^=R{bvvNvI%nz|RvRN_oz_L&>+h$<J&)ZNxt}(l
z*!jBuohmI`l-8=wN8U44xeree=}%x2 at M8bWkiA1&Y2D!0^1)6q5PuG5-*aQDOCQzQ
z+XLi+M`~}_2&`_Z=tBUQqHmBf&GyDeAx0FDx at mG^olx(-?3s<KHt8q<eZZ=MD-%GT
zwH at BgkWzHDbx<CMiInxEU=KSOOYrOe3+T{s`$VU3ofgs_KmxT{s>?zLL`<Zw#%2&N
z2oX?f8>rB##B#hW(5!t?4vJH52jDlZUrrPo!=MskJ4oxXx3U%WUF+Qz={>qlZM~zb
zv2zk$#>lC$8$De(Qzp-|bbIQV1)Yk)-0;dV1jpc<%)80Bxipgi*!61h71xR#mrnLB
zHQ+~=GhNHK0 at k~KQvOIs%l|t+u1lEWt~A_7wxJa at Sd53p8ENS&h+OXM*XmE>PtcJQ
zbd+FkLk$->D9^}1!Eua3F1uCme>I(w_B-u}r2H^V<ZK?+YdN9L_v^?msqlzyaKpvC
zlxNGk(h&p2r^OdHj~V8W&u`7!&NS)rzVrzL8VepYjjEwIxXV%Ov$#5~yoV(yDN3zt
zO`S~hB0ykAq3`Y8Tiz`gJ&>FpXio7|S6CWssl}@ndAO)(n}!N<sCrMQ09lx7!5Dzi
z2~Qpf^sOMS?hi;Wy6aPH|7xQ&B;}!Z$vT>{V~^h(BwRrE|N9(gQk)y7SW=h+|E^-N
zo9XtZ@>rhFmJF~}Ni@&r;9bR2V1$5#MI9;k{nn?AT4)ZRKP~NZgk;9{)B{y>v|M$<
z9j09y*2}&J0Y=HnQ@`I=$c{InCMUBx9Jh<Xi*huiQM!87v+4OFh1jj3{`jvO_Bz)t
zYs3r7zJyZg-xO7Qe$JL{Y>yWD%AV-cpX}RMv~60|nX_#NMS?n7kp`<)2WHddZ|7eQ
z7Nfcz|D_>(uHYnmE}Wfd!Yay}QqL8b&0b^kswLTIUINsd(3?Ka;aZ~wR6?1<>U)nh
zwD3>o;*J_lZdXM&c<$NfSG at q#?Z-I)&Ad351IXf{etzn;b6JzLxrf+n)S3<cVf;69
zcv05&!=B4MIp*jXL&++2WK}Rr=1xY!UMeBwt+N>d4iGv^zb*r=!@ZQ%*ne>&{KA59
zdI*k<g@%Dk1LUg*<nbzye!{~4F;988ZasxJOa20L8OfI`MP7_K?D)iCX23ZHu`T$s
zxZyyu%i7-3N_fVe$bD`SF_t^z1}XC|wa#BNa%`!iKYEUgTZ^R{hHFbcCSQ*d64z*u
zU2053#8wk80IS;4zaM<F_C{D~FC<?t;}Vl{_yB#q*8ORNB6tm+h5DBFGPz0*_xxnI
zz<$P9^JIYTv%m#z`i<(YOgUNY-W?C|;TVU|W_DRF{{q1`LZFjwoGvu}&pDw5*UV8!
z`N(<&^c_qw(yizd&6s-;R4ikC|Bj8K;oZj&3H}+(TV%#!T at q!XUEnrU0 at m~~2WTp@
zW%#KZ7vSoOk(qkXw*!l47u{Q_A__ at Xho?u0!XlpKRK$%xgoiI;IH`FVW}m1{nT<!)
z4$pY$K{CyHgHv28xUcz#XENgmFva(m%AqeCRxT>t{Vk_0!gK%7Yn at Ac|Hy?>zyvq$
zEJ at C2&hNkZ>yk0SS!?_-ngdz)|FL->dM4SmtKxksEiL`;&(jh)?IFQ$QGc37 at +Lga
z?#FEFz7r1Z+ziagRS_%p>wsI-ce3n_>rm<wB;gMb$yFy9r+)Uxl)>lZ?pUCDvwDwN
z1J$~-p8}P*tBnXC+^I&nwHk}Dh4tm9BtC-TH5*)pg at NdmEzQ3MkNq6^8<U$VH*2_y
zbw6DyQX6i{*94W91E|Pe#73KP|J3(k3k!f6ibLqU*R5M+))HZdI%5p^<L10N*^5Xg
zo~C?RE97W)<wd0NfwzMu2U;hSNq-wB--qA*=!a#f^0`(WjBWfx(?Di+sExjC*<nBX
zS@=B7p=LBO`8f6B^K}WMn?*0e1$@Y+na<`4Fr9O$OQbah9xj*Id54D8)NG|ayGxyv
z7D-e3$++3+M!!P^1cRQiSb;EfdU;77Hs2NiY%E2K37fr^?t5MuGl^JG{EajR&*@OI
z1Ijn_lZ_SgIf%o;2^&67(*MG_ByTd;Gwv3X>PzN<UO#+SB#6ffmjwhV&83Hb|El(4
zY0L;oTks(PYe}Kt6XJR&qohR92JA9sdDY-kq_;I+HMf+~K0AbBDTz|{$W_Hooy<zj
zn}COKLEEGjn;z>9)2<4PV96Mj0R!83;1OTM0mpJpSBKYSdp}}n6{dfC*B6afJ>Gi-
z$<vZ*<18iX#qprjp1-RbMef!&N$<#WPfq8n^fVinv0n=q_9l~_*0U&@c-$LRf22_G
z`JTeZJ|<I<NfZ9LIk2&QmgrhK(CpT{DG`YM*gDa_8XNT9Ib>oRAla|Y2LO`vt>63v
zja~x-Q!WewV&H9KnFg`|hG}Rn#U&silE2^wRD_2uGo($KFM-;@1hv&ybB1TTekMF$
z!k^i)GH<u#>;Fs=GIa!cLrkrcJUmK&t*Cq?I%)!-zmfa~r7xB?zk%0HFn<Ei-<yQ;
z>~||_=Gnk4bCKX6&~}hA`WV$Q2+!p<gM3ozs(8i|;jH-rU#+6v1G*OX`%OYMesDmK
zz`gm<EL+6OFy=|U0JJWoiUce1lf%jVr$ZBqS30zqZ-Qw at rq*HipJ?&2%s2c8FeOs3
zcM at Jv`2(vuM8jnNMaFfP4BcOTpa*FCpAhxE-5V&(8 at Ds{0LqwlfH3WI1b{96*=C|;
z?ZJ<fM0M44gQ&LD=*V<keE0FOZ$j_fbm9Is_G!I8^(OUtX{tSdlB^pKL?ay-=U|YH
z4w_xjCS%4yzha4l)9&dqQz7yvyHBWb^M~-8G8H#NCLv$P@$cnTWL&facW#x-I`3mU
zd?LdppkQ~8FSV5L8bmqKZ_2*LxDiGFuLSK!-I702^-c5QpYfG>r6- at XY&E-bJc-Ax
zWeK}Vp1KFGdqChZEi=_Sj4LD43LsnAqW-DX)<@JASvK)??p5xHcU}ugJy%!6spB7y
z>e at VQ(jL>iq_7db(&q4C-`o2y`iU0kV}T(XBg%Qfk#^5}-kj(MvuiNsnXWYv#f9#s
zGHFBB>L26Ova$QzRHC%CG$W4(1lIwY(P0ZnWbOrnr;QiCp4jcD{l|F6mu)q?QeO0)
z;?`$XfceI6Gl1ct4N?Eb+jo9IoAKtq--p!mrnQ8GL^GCV=r-^I_V+jdMu at Qa`M(}?
zfSI9bo4XaTv$r_&=i9%P={g1MRju5QGcim>&`h9 at -B7)NhRIW<d=((To!2AeAlQt2
zU at E7V_XT88^<$3HOk#5YrRR*_UC#&}CWPnnIrEw--!FqR{&@b-*~TcP1QNV5o=o(`
zY!Bo*kj;d-k%fWOxcP(Cm?ME(<aNw41DTV!>Ue8odFljgY|JrUz;3=6F7*6t$6n#2
z#({$1ldk+FZ0g!~;@Jd9Jma{7h%D&hPo_3w%1)QpAmVrRO`1W*9#i*!A9>T}2LQkC
zOW*8-ASE)IYQ|T^BJQ at NwKK}v at o*je<yvDuN4iCLq*^;T at T5(>D-T9j(X!wCnd+m1
zi8Txofp*TGez^QAyB5kbgpDlO(TK#?)~O0EgqTzrc^fZ)6&mj4rr`S(jk9fTg1uad
zfd`aFJcb&afTsS$jd8Cr&8|iKfMUq2s45p2jpO%9^;pn5r=qCrEO7E^BT};0rbK`2
zmQhj>_Or0a+IJ{om80^mVBpd<zFSU<!>F<z5TCTazx*w at gF6Niv46inSg&X&!D5W~
z=xp&saaeP^;l~HuTXFi0%##L>Vtp<?>k$5zfF5KL5g{U|$oQ-lB5ZN8KxZNudo1_#
zg=XL at A7$t8e!IygR!d+o;=?f_fkKUZg-B>BIbg1m8g5xbEoV6ODZVN|X;UWx8O@)q
zkc?2K_9!UBZ`)1>W}ptreDjo*@JmH=bU4}awvBvU6eWY_n^C;~Oy)1VJx`VK>bTd3
z`mRoZ!Y5LB(N%nir1h+hc$hGA#?|^2gw|Sn;y8V*P at i`%8)&>;AGPic-;p!^YO#Yk
zeoSS*ad+Fzh;M)$s3F0Ksl+gEq)|UMxH>M^vzB at CXs=UVgY_lzhu=Ni>hM$i=P at 17
zJAv$<GO1=VzXSpW>pWNjPEHK<YqV at V1d{a%tmTq<Sb8CDp8pY$3IShId5znLu`(Y*
zZ0W+p9y)aHzW&KsIlMG0NG5OCj4Z1iTu4s%v^V%QXdG2M+}t(2SQHXLnL^inBMdap
zYZf213 at M*)c&s%Ln&7#VlE6ow%VD<>JpHs0J6Q0a?V+v90wJc#bYl{&R-ZlZZfo9d
zT`$*g*iTx at N^Iewe$-Mz6%c)&BbmE+Ae-7g#=DmV?SvCy{cn!NNj=_CJIQnMV!LTg
z*52I!Qb1BIaf~~6=dEQx!Poavn*=F-NLe at Cz>&urXa at +Dm=QMlbXcI6R)Y-Dumq0U
zbwybcD9fLe{c<f7={ENYj`B=RO-hN$hDn$_uCZG=&GkV84-jw at p8Q~{ZyXd~1q7o>
z^DoMO3)Rcr_{SL`F!EJ1B`MVyc~%@hoyJs^0A*lZK&ard4v?egkR_1ZelzEA9Sndy
z^6bgSDi#60fuYQ3fb&4C|2j#?S@~h$#o*~hfG=QB9T`dU`!naRxbB8AKrawhin#{d
zIh_}34kYz`lG4zy0|1$pTv4CrA8?5U at Z_oAzNS(bsb1ahhVU^1UWG){jOf0O$>YAz
z`gZH4i at r|}#QvW3Nej~LNv^-^bZMwtHi}RR0P)x*^ueuytiv6^n4;iOrio{7n)JV$
zu)V^+IwUX9;w>m$&%F~F$6nL3+g@`c55*lUI3z)o at ccz>2XZ&Ee8X(33OR{>!OqL=
z<0uiXhL)-cEF=BG*bWP#y#AUU^>7~4L25IJc>bVj$K+kVC}P<VIY&nL@#BZPxCb#W
zuYu~DRUYNdQgP at ne<cy+7h9?D8Ce;0Hv(F~QBSCmOar~cbgr3?rm)GbS at c;%SAQxY
zaghGT>|us~+rK>*mXrnbbpIr2O7yEcf}f<7E9+>yy;-5UgzK`vpAu{}s;I`rN22MY
z3!+_>Zn2rF_%^*a0^?rY{0)}hzV=o=VBi1Q54dkuR+dn{TTDU0qfgYe*5I>=kCh^I
zhkpws^))eXE8{B%nrLbna-Q74D0~WLBn(N)alu<^B_BZ9TEC}qz?J+e*8k1dx4-!3
zvg)4`2`Mgr8OMqls<V3>e=O!8mR^uobg$0H9M}jl(W~-rD{o2<xY3-Y$DIK-mbk7K
zfMO)Ly|)|z<>%kM`LrMKk^h>e8=W#D_GGrzTN3pY*MJgs)%j~8h4yq4EV=Ie1zxPt
zs6zOW$rYU^phvCVq=~-jJ6dNYJQ;;DDgYiSP=WHiz->=2xcyKh^f}wcVEwQYcY*3l
zA_o(dsOA*UsCdmVO6Zf453Uw~r-^HCpD8APCoBUQ<7EAV536)+bPA$XrhuRB2f&sI
zCRj!{VjiRAcNV?Gm2*ara*E;|S{ruk+tZ&qwu_?;dN^NnLE}{^$-9+slQtDy>RKMP
z^~9Hk8FQ4<=QYJlZ{ImYJ*20nXHKvT2uQyQs&wA#3#gkjquhUJhIXXFN&h+c6y46%
zR}tclWCl5T*P}kZO>A4PmNRFYqvfQ1yKk1kZ5@)I_GTKLyYPd4TT}C{BD!_5wXDIG
zN|2qDNoB9GwruwfoZmcaoZJC#j8>E)gTk9)xl}f4=GE#>@W^VEPJ_Wl0PN-bzWtwe
z&}1-{5|uHpHM?_qdU{emL!4CTk#)H?JGHRi2H0f(MG#eG at Wh`U0&Q*7;;9P`>NLG|
zf0I7iG1)MW=oR6y{hL$AnN`En$mFGdtU};Y3f=T}W|K%0*Ah1k+=@b-qZ&>Aekjq!
z%DOJ<ov<y&-j^1tdLh7jh7>)-WcLJ4Dqfe7E{+T6_L_ at Idjm@y(^}h>0YV^A_bw9o
z{UJ#Y{d%d(FTFPlcgny1nWqZ&CRPfkC?S)k&@W0ejAe6RmX^g7k?x*JZd-`Q?DC(d
zg7!Ul41BA>jdrc5cz{w<GVTvd%-x-j>+3DO0M8qF*T9<6)?K;ed<M^(rqze<S1^wI
z^GCSs*%)@h48F^$&mVAQ at yFEXbuy_+37pyo4ANOTf4>xAnb9wKphp{xuH>S;I9Ti3
z at jU>N3iNSa&f#`7Aaa9zlje%ME!fUX=V&)TabPzhBBw6;89b{E0YSaVzl1pL)VHYM
z9FB_Ub#M;XgBh8PmH<m3U*~WN)nUJl)Fn47$UU3OVf)!Y`!t*Ou`UhlJJmXfwpm}%
z!Zotgz*p`uJ}_|}&U<y^n$rmI7tvd;IrDRik_P9+%GK<7?7t|VfXx%0yU{7g6qX0~
zC+eSroQjkx+g+|<k2~!u!E!UQ_O at UtL)xEn)Qe4Dg__MaZ(;ZQPV<$#3dCNF*ip16
zVr8s)3n<M(Qd~K(m~o>Bkw;LmR-q<Wn8>r)Qk|oIPKN*<-lwxHdc-RfYC_a(1Sas^
z`pG-)malf7w;%^8G^ZSZU`i)V?;KQTHvDQrRLZF_M7gI2zMH-S!eFZ&jmgKeOATFP
zyl&v<=k4t+X{IJpEcsx~N;dB6pwI6KNuP}G6jxkexDn%j<w*Ud5LS>uO%fe|Ai-8|
zMoc^{p&*--vS!45WG7`KhRA%|6m<8Y%B#$x;A4_oKV$x8_*f&?tA9MQ(wedPNbmw)
ztWoRNVCQq!aZ^4c<clYEtGK7{DkGSomn7N*b4t+9;8kN%6<IhQ+{2qqM=MqY4thQ;
zXYh2(BtGs0st3i(bnI$e#(UWRH0&$mS55#-u;OwLU21*TJ$<{J$W at D|df=vUTK1FC
zFI{QVrJEntzB51jIw(L=O^p+%GgON&#XOx3vyTJjpaFrjnM5tX1MHwDgR&?-_yNe1
zUkg|NkEZL6ruzT?R#aAzSu{RIW_INgl0CB5wfElF#m$H$Nm<vv_U0P*y4RL1d%L*T
zEZLWgD at py{eb4#*k8>_Buh;YWn8j23h!qZ^YtqmuFLCRYiJw}n25Y~DW&eXUV4T_2
zJ9npD;0qf2+#x<Xqdh?LJxaW%mN9BosR$uEf{PptiP4l{?PTkG@>?dqd9*{h^ifaj
z_fy(J-TqvDu25#=((zB!6hxM}L2&k8fXKfbfP)3yjGmYwt}5!aP502pzAjEUmq%P<
zpU<r3E(R*!UI)VzAl>_Gj)^Hzep6=$N{zOUxTeN2zm|4TWPJ(zR)x2&cf~NAc?W_t
zj)Lj!i(0l-X3m8k*B`8Osd5FL?VXM6UQQ3?;Q}RaOpe!W+2lxs{W=SlT7%>nUZu#k
zAHTYqN_9rE-^`NL(WKSvaKEiF4iiyDq>kOI#W`A9RE$@jEh|qvcxTk#r!RB>wi%l+
za#&dd5~Y_OpGDeY5lY7CsfXBv1J0YNBHyuJt5K853dZ5W#0>U*+lK5Gm~jE}7(BI7
z{8;Ey<!W@{-I5-!2;Cpr3nnT?REDPkKibOg#YFgMdo%44k|@7(s%iQ8+3a~*7Tym7
zvffJk|Jr<FIjgL%Jutda$&@sh##F<30-&&-NF%MKSB%h^y4t3q2g;Ne>q%Mhtk6J4
z*PpGY2LVCzU{E~Jz470*UU^X4CIq+uxNh7f&b!=#rk1v!ncd}W<=ua8ZZsvk%1Ja+
zvvmQeam2IPYlwQ#H65w6Ak{%pp!Bq$(kkY;JAU=4ss1~@Yu7b%d<W*f0-9lu9RQMJ
z&}TLP>46(_7mNcfwI|v1$E%T$3ON7tx<MGCER+!{{1*4$j=E&kWRf}2`ghcuz$}V<
z<B^l}dWy#A at q4E72UgWelR<f2p3!)+c!Mz$Gxu<;t)S`UH`!gK5DB~Ek_C==ig~`o
zi-TiyRN+kd>y=7)eEyw2&L#Nqft?%NQ;OWl0g`9D*;@J7Lu**0<{KLBLm71<1}_x+
z&-D<3ekfjk?kZrzP%LYNrK(td(y_^4xrj)Tu&wiL2dhA_4!f}Nu`~$$L#Pcc;GcD0
zcRii-Ht&;GHP?$+3AR0|u<c?3N9P27<Q5DSGheDVFiYuVa22ibbbhgD2G^Cb;juM2
znta{O8N<<2oPy9kNQD|xp!+>3(<x&5gwC4kjePEHdKKdny1(8RyhlnTpet8_doV_%
zPbxKnrO9G&Np>DWR5X?`Dqsh(jg3kF+2^XvaE{XB{DfvTNXd!Wz4Y0~WAq;2DQAbA
zT{>lNyz*DB-OiWT+LxWV>w3bfbT+2q5-Imt?HW@<nzwXhcx5M4wWso;Mnl;}TuDG(
zdKaEMjkW}mH%m1O0Lx|RjvGMx-MzDEw!gD?9-3=*IP-Av+hSDAu?(R0Ob23K?bZPY
zr2&u`O!1ujmEVAL1r!(9r$DtC#3ZGGjlT~87|V$>O>!ELMK&dnwx*8UfA=P?p~1;T
z>Yu{@F<=LP!N%Y0aT4o1I^+SI&UjFWcqj~U{?U+I5(unZ$-_Vaw^4t?()bo`47G<A
zR?JR}bJ8vS44{4J^K}M=-GuRxsA8J3whk|MHta1vd}&F!v5HGP^z*J5{LV`yWagnv
zA>8V`H>!5BZAiu2v`C@~E)}$eG~V$;8ynWcTkh4V_ygd6z4(>PixH<86BTHaNoI8_
zb%i<u9b at nUIUZ(aU%x=(7T|vvmJUBSxsiS(v(s0B6e2seGIKM2kNthd%-jFICOMLC
z#-!qkE5)4bvMI$hrTc6GXU!l2LIxf8R$6fpoefAWSo*~B#Xv(A$A{_maHZ+fEx(60
z*rY9FnKQG+g34EWNHem at 6vJ`?;vN651wbBa)`j~1BAkU3`E6yjIjY!x&l#BOcV-vV
zT_fn|uz*7(^)ag`3=XqxhYohaw||_A@?JUq at IXg`YcG&*gx%q$y4##4Y%#$q793)?
zRCzjH_p|O&+5+L{<)P_!bKAetFl1iiY2u<GXH`$1iA&=^4la?kq at Yq<&t0{Tyi(g-
z{|=)+GlhdKXcM`UH4;MPylY}4!D>DssV}VJ`#C~~^^9kD#XTTpb!tF_P6Ljjb^cxc
zp&=){l_{v>7RA<YZ-5gRv8Oh_k*h`A%nGw;PJcelp(V6l15~lgPG|Sl-ZLPq<p%!g
zmIefUEw;RWPTw9~o{ZEQWH$A13^5bgpEMqmI0*VaT=7hN6YC6q6 at 9<{X&Zu%tpN at p
ztG;Ht&O;Mu|H>PTtw%Xe1DN0 at zR~2?)x<w#>BIJg?6!b<*iIV{k`K9=*5UEkY>&Sk
zyK4mR=0v9>F`K_tvlhsQ1shXqt-Y&RK6!g~wdAdJExkw6cCHC-gk3}tCOqtFWI?$_
zk>$}-*C|t>`>V$7vU0bm?D;Pt6)IN69nsWYum7^z!|i0_ at B5fOYw5)5u7jk0xBWAe
zeFwG)`|@Sw-Zzc!gOP{la$Z`Z(`nBq&R+x0)_Bn*0NKBrV;L<p?Ox|vHaS!vIwSbg
zh at dp|iQHy`T`7~sjlR!B0RN2B>P5=9JTrMx^aAz45qh}M<VwkI&raPn8_Ji=lg2j1
zP-B9k3V($Ha%;{CrcnqRl3#0igmB5 at pAAs3G2i5Bni4m?A`0=zYjt#ObALVbo(rD`
zp03*AcvSrp?r(5Cy1u>#ebio(T0yZeZ}a)Tu9Db}xN!O)5SgI#kZy0wA at U@bIz)$a
z|Hh1XM>Oix-xamV2~}KK@$!_fc*s%P$guYd3~990|CN_-DZ3#%6Z9Rr|LD;pHkY&q
zSA)Jbik>~QMCa~O>{xvzp;RO{c}&%PRfh#Xe_*`wTz6U3SOf$Rk$N--yPpg()xeH?
ztpqmQRMJ+ at v{_{d;vwGI1sX4gd;vcD97v#lh_pJW>VG~io+%8tFD+Cuo(Q_?YkuZB
z2%FpTVRgj*DILP`7&L~^J{gm2B;zIeRx9O;7O8kJj>2yTye!T5#ReJEB8%we+HU|V
z#x_Zs5kfU7=Ep!o7}*y;CLJK*<SiP1bEoYXfD$!~aYf_v87F+1+rGKk{p2=iDEKAC
zuJd_EwFsfotKor=8TLVQ<r_;I at EPn!lx9lK6_iuD;j;?2WEKm!MlqW?*HN8};-e=%
zDTD1Y*{0rOL=%?UpwIqV;I4WD9LEiOq`cAotuN^&&L~wA{GKu1 at 9V)~wOXXRijIuC
zds*f*10^{)c2Q1hc$A<7uC$JIL)Nh0(%j6xZsqhJ{hWyp!N%Yd5FNBq&WW>AzP!~h
zj#)IkJoDd2;C)^77dshvXVa@?JKEYTss3AvLcTS|^v<K^Fmfl;cSha9LLRX^^KD-k
zJiI(x1-N68kiR3V-n at -0fXI#eXU(|2O`3W_Zb@$yO)iVqL4;D6Wr#zA#`v7Z*R;S~
z<P|r+AkEZqV{_G^@2&<g)A$8GS(e%xfwV?vFoS#UasnmOYp<M?bz1iBT=kT)yyG-(
zK7zdMW=bI#|2Qf?Yvc5(nOJ=#czbO~Jl+3Qve*)29vR5}+>g<%Vyr*_ZCPn{*<_ir
zOJ=rL4=&cgy3}yR at Ln~kJ>x>%)in-?&xO^Fna`}&3&xGrsNXkC*an`F)+y27>`b8S
zOT at nl+(uS!qhYBI(QqTLIbAP at O?!)&lwuaZdRsgMV&q%W?sPB1*8l<Z^W;GhA)<Td
z0R8-{z&sI1;Ulf=Mq(s`k4lm=Cq5SUm3$0rs6u<NK+O`vfgp%zP%*7(r;`Gjs at K~*
zMSc^}%VobU?wqy<h>Q_y|G3Ez(B6AX^-O$AaLUM4nODBqlK(<5T~jU$Hj=K7^m|p?
zeYEw<uX%5L+q23Z_vAy7RYg&4{U?c6QSrPi8@^hx;#(EpH}2bAQPH&lLjnYs<OdH-
zi<XsS7$-T==iOe?#8nBUMRK_tGHQ6Q!00}W{4RRqQwhkhv8o5OYt%#p7F#=8^qAe7
zi{pgms&RbPTC%1D-&OD at lfJWKWRM0#PxJ!t0v9IizKWkIF)5uZMgC2O`=wAjNyztV
zzdw`zV;=KBDkbOFDskMLO(}&sfMSNBS=I&vSuk&s&r8Wm`k~xWBS{YXV^Bi6qeIP=
z16{5<e!kBN-Vk3i2)9zWRb?fZo$$*g#+<pGoDSqNc8dtzH%egLd|fV%-?{}vRSxW~
zm9~Y(ZWzx at KDI?I`v27e*U|2fdrmbp{fEH)#7gs%Nra?|@<H at 8wT<sK#v&Sh$?y+i
z&uVg7{pTsV2JbW;iLkT;+-t2FrBVl<a;bksX9+`Ge~e~k3lhx_f3zjah>FdJrf8Zf
zI|${2TTL<=t&Kovv8K&Rsn)an!9vMvtTYjTtN5Q>GRYR0Hb~#L+%<OvLE+t8Q3if$
zCCRa%6QznFJHOZ%3703rOz=O}1bvmBAaD0Aw at n-IPe8ymd`ei9_N~ZOpb0F8ElciS
zl|tNepi4r!FD%DcTwg9^MFWxYc99C^H?h!$h>d at w$rtek^fq>GyCTlBKIzu*D9tFg
zh~hz6cT=Ao(%|H^;i9GB#WkqWRTaV-%wPj36|zHpGcR|$P;2`7L=sJpy<VW`@@NN$
zraDy-Nt~4qXM+Hmyqk_}zgay`yl?D<7`9FT=}-U7H?Es84|6ie-tac at Wb3=%{%dke
z$o at uRjcp9_7CrCBvk=;#F*<XBh6je at tStQ}U=Fx9c^N at -Be(H~uI>`{{EmBVQu)~I
zuap at j+z#SebT=IzijtL2Nirosy_WNodVo3+84saG{?bTi`kC><2Pyg*yU{YLFt{Fi
zMg7=Jj4%#Xacfj*d8=6NHHY2Ye^*{^>|oL-o)w7r&1kW0Ah7dE;ZLxaLL=Dz)L_w$
zap(%p>eG;!Kj{q3 at CdXuA6@r781Whv<!Wz!_YVBX-Ck%l?YS*YMJ_XNhyy`^?FUPn
zkL)Bu=ASj(7IG>@Wmbloi)XXHVIdkXB%p)(H#JrXR(T<ttEocBcUrC0|Fd at k3*>D|
z3&tNQgbx35KAW(9tFy7F#Yr=Q)Y at ILa=AL12A00CkAH3kk&LL(Pk2Tv#xbcF17(~%
zO9Mn#E2ewQE9htVI5sZhcaT$;JYywAbGsz4_RP)!xg<~Wj0ltCcZqc=kBEmO)|Nkk
zcz>VV+}!2B{o6%WyR7p2VwvyWfr3nc1E5{J`^WmaBd!c^$F86;olOlrL!Pu5 at t{=g
zgUo})KR}k!@HI8+y*BF}F2Ofh+CDzgNoY|0&r87fec!}!$~~Frf?G8u*wI*)7}AQs
zHYKYYf`N)e*MW*A2m5R53|Aif2KmL_dS3rxHry&6&>J_KWSN`Oq24XRNmf7ud_{OO
zoA(AT+Oj2H8E`=Ohj+#|*t at B?yjHi>M|$dvf1^sH{;q5?groPF^F9>JGpKWr?m&GG
zx?kyYaApDMkKf*6du at 2-I#%pEezMDlvS{24XA8IXJVVGnShitF-U|-N7+SC?)C(^*
zNT0fWMQ{I}(MZ8HWL%Iu&})zxyrsUswx|7OmTe;n8aBpl?0)KKEs&t;D==|8LvYD<
z7szGEZ%}-3XkzLpgr$Dod<u!PE@>Qu=Zb}W5Ar0@!J2LbBDt2=4y?=it;f~^6+cU|
zvv3^V^SiwMuEa}y!42M4S_%r at nVwjKDJ2L#4?;?<PA3suic?V5tWzlM4r+tyWZXln
zJvArdT1}9m?0B#Ng~YRSZi^3sm=Rr|levyhWz?fuE#3GJ%Q0)j%gXSm853xUpa=lO
zzTBt?S3p?RJ&{?(p1RtNJ(cNFcCoo2y8F8~PQ58wN`4QR_O6cUUbH`BA1gq-zgy#0
zHDFMrwwBBZlq&pMUErOG?U5t`c7X?uv+^uRv5uy{l?2xuCgxjEGexmdj1~_|-BJ!9
z%aR1cFGRl(TCzf_>(Nt0gTGh4gQr<8Dh6y?0mEH?S^Elb2dyCaHbDxO)600^CDRcS
z!8G+y4e6eYf%EpC{go%^Kl(D(0i2`vX8 at VC91FnE7k|+~wS#`#8mPDTEBa^^5eupZ
z5s%UD-6U_43DnPSrl-rFKA@$N{tt~!Q_tUNbyN)n;t1ZIeyHci`~BEi<kdD?i2|{@
z$n)1Gb1=$lZQvb;8D^<PZ|_Y!g$a1Rcq|~%d4A}mRJGDDSW92$erHK4O5}7_La*_c
zd4m^=C9NP;0^gnR4hfF-A7=q+zd$$Y!+%<TT3zaTcd>^uX$|*cpFN%vYS%$?zZ(0h
zx4Vyl<!AV^&g9VDciiMRZ>Ze7Cx#(1EG|;vqY8dy47d2`KwD0i<9S!a!(0AyQ&}FD
zF&h at WDw{_2G_!Gacqb`gdtZ5~sv{r5^hxGjE**WtTupEP^>H4mXJ{F7sF@>Ij at -S5
z{X4XtB`?6vw at X1B?bc_q)w5mdLB}Tn)}O;DFrz1zLgp=>KYy;<BMm+ at v|>z94nk7R
zIQfseGI&u$YutVHSrf&lqR-hB_O+`Z`h#N<oIYiMp)RHRaKhx*tnx&&h;GqinP116
zGE{k9vW=l&@Qm>V6*KoD1XiW5y5M^uW->@HFCmx<ygeSuA at f;>aOU8aIlB at iN@Ymd
zzO>#*I*7 at ei#;F#hwWM at oN_4fgG>MX>#X&UPpki>27hR{mM(Xyz1I}eUu+R>swzS(
z=j?hS!aAwlnY)fmSZDAGi3eH4h}k_Py0Yx4`Kn#$!5uYKYb%|*ogylzDXL7qoWNve
zEsH5@&ps|kfuza+i~I7k=A&jc{$?(6fZ@(!+e7 at L$t$~OxqW`5zsP-pjuu9CzXP at K
z;cq({crgZzs(7z4FcSqC--8JJ#G6&Xd6O;$xQk05L?xcqbWj_~ai-UAUEXdKVHM=_
zdQdTZ3LA8DxLgRyl#ltg?W;*?ii~JHq!L09te+bH?XW)Ii56K{v=r{qtLhr!!Ya{y
zlrdc-!{)8np`j=p<G7^iNiwC&?_NXb7YF3KF2Db!c*B4cZ at IJPk6W-BT&Pkt-BjpZ
zLGwgoGcwl=C*w%wBC*Yku?_aC3#tv!J~9Ve8^wUj75DE|OSQ&rChG2LdvA`oo}Ah=
z_S%pI*oW-?bSSjG_GYy4SO2HtI?cJ_66UI~yH*}1PNa}us|S+qk1BMk$0GPwtF)_i
zDm9gKg5iucwaQ`8rBZESDtm^z=p!@)_w$Lbk3v>713gK?I)x%HxAmC5dPLT2$~~hR
z?SUd)Fwn#6Q>2k2DC3)4OV~erm-^xURZ-^Y^%jq-sP*Fa<!Iv`pLN;0(?7>PlGoe4
z<y7M54S818w=8Q#`~~4W3ec9_OA<RL1vGw-xY%zT&c%{j=Nl~$a}k~uE*|>@rhcgL
zVNB(+m2C$EvuQ;rAT6J*NMEuNCNW0<)6~3cf#ug?>&qI`=KSZK8%Gy6DG%!Lnh_D}
z9}R76mYm~3JO_Y}mdETZ$o=BLJpW3>EN_4HIs*>78~)FmJ0i3Z68=Yopbr)2nhK|a
zzB2{BLk_`Z!lvOj at a0{59s^}<3Lx)!19<lCSJ*vAyG&<V`T$jUITi`fM_L&NAs=1=
z!ef|Wf{p3m2OEP;9vTzx0QU<%m~BNzys}qLW at T2G{McDtTGG%}*9)+7^PD#%MB-@@
za#t?XYFJ`lGx=4936-N0(qx~5&hcSHihTKqqRF(sSBbNzZiLUc1|Ks1WhbsvEPv82
z$cr!?v`D!~?Jo`Yn!;~Z-M;&E?{~psfvBC;scM?hHSps)y1xv;CH7ITVr#d{foyr2
z7GcETyXw49gOs}%97%RNO$vcjez+?WoRx|GYn`V``Jq$S1m)2(CP_O(+I`3d33?BE
zxuC~*`}4GW`d*{AQwI$_yROrL at k2~x`ZWphMkWW|flVRGg{M!)wvMb9m1lmUm9=kc
zE8wC0wi9*vmp6zpDS^tZ+M_oYYmEgC=AXOV4RICnnH-uE^g^a5VBkVPey&(^kd*^h
z!^4ViITEm&Amu`NZHc&NHs)dDYAIs4*uTUB*YdACfhqJ~7b-_{U&60KbQXIas>?i;
z at tZ6SCv*K!b?JcUssHBa(#+y{27 at UB`;Wvh7XcsQ-`}*(z?=l!8h-ExaUenRgGgJQ
z=kF_i516&QsR0zOzA!G#J)h?-j)V(%TP5a?N7L70qo=?Q|AKkzGZ1keoUjY|0~jYs
z94|Gc9(Gx=T)qK)!1Qo+00ih(zM=7hteGuYY`}7WX0;Vz^7S{(9Uf`p_`vTUCF(vl
zPK-7*^*nJo+Fm&4BtFDGB<jfslZWO=8d_y>Ob_mN_kc~=y$pAKYQ9^N+RfWolG?Rx
z6mRoydez=Gh}H1^5t8A7cz7dl$JZr&=6+ at P_b5}!%obJhQJFWd&v*{%MyfCLIQSRR
z0R_+U(#nbrt3DDX&FSlh5ntRMh<cZGU)at6IMkP=c+tTg8=f`RN*^Y8`sl`>ASALV
zPOZx&R`_}y)QcN6J6vVTa&I=g;hOU8^e`EZN>*1e`SwBRXX^n5GQ<mEd}Rb%Lxm2>
z0+cZtZTtEXnAzROhpbzmI=0eWeoF#B3{*F>o{bi=!<sg69az3#z7#~lJ-i!1uav)H
z^~045eoLPO5sKkK9-qNh%}6Qz+YTPD42E2K+;ByaYUh?T`<Qbx59jQ6 at EhYKGdG*q
zgX^kXhYOl-$p)!Hj0GGTTySQyhK%`R4wtP at hqkd8C_%bNAjUYSziAMH`)1wj5C`A?
z&nuHRBQ>pwn+F>B7`^C$Zr+S$y+F0 at T<FMJJoQb0E(Yt|ai1nY`F}1-dyB+ at c%*qU
z9ACA6B4K3%F-=A70r+9f7TJK>CT0GKkF7V%!Wp6SRp!hEW8ZE<Jzsjw!~kp){#hn(
z>iS2LsxIp(V7W`;W`mmfc`|(uamEw^a&iXz-7;AI*?sEmEbAlVYeh{xkOv$98jN`A
z%Ji_yN!$0sTex at 1^7=<6N+#C*oBO}jQgYT9>OI6`T#T(wvzoRu%=o_yQG(v*Hx+$E
z+t*Y%_S-4CCt2D4YQyce(NCacoZR=~Zpsl?_|rM3Q8e~sQp&ppvgzEzy%zltRSl&=
zY+9I-toavjsr;NfWjoEa?MJMMM@{aTp#16p5Z#>fC at lQbr%$GaaUNL{#je at C9%me>
z_buFlZg-Zpg=7v#Jx+OS2I?K8v{1fog?F@=Im8XkDol5q>Qo1PWDqf=@rHQhO)3?7
z%ewH<O$gK`!ezJD8t;0(g-rYC;Rinfp8U>0)SAq-%oMFWxMD-fCl}^6%qq-;d;J4l
zE!z0*g;Q#UNM;@bPTEJW(al;6mK89&X1UmJ`rricNm_qbZ4jU33obG4Z_(_N)4r0|
z!LOrcF)6le^oOT2X_D)wze2DpR>|zP1;-As911bB>#+Y4O=JIJFEiNK1%6wr3tQ}&
zdtED;Qn~wV at ZKGxo!mtWLxc9{8S`r<&xf5G$(szcBO=fZR6fXHQP#m1dDPpd=UX4K
z5SK@)DL76Rb!~=JT3Hfw*NffO>qyw#jQN(I8Z!xK7%Vv>klJegv-`RVlpAl58a*1~
zGMc^u{|bT}zE-zsosdG8{%_xUe3we^MOSvtI;v`~Ka5_`fi2JPh0#LQAKZd&P4E(*
zEU;gAQ}u$rz6WW)(C+kJ`^Z;3^hC(7vSI+pAi5n+OMKF&q`{pa3Jf4|H3C3KW-2)=
zbnnkfI}8vco&-8gikuq~3do13hbpNImgP0FlGjpHe#d>O8BFNKG${-3hAWI^E--3`
z-Z!*@UT1!t#<NRd$EXOSw{Ui^FeK@{ohJiz%6~7q1YO8wQwSX=iX3vYmRA)lt>7nc
z9pqdhGlehv?|W=Jn{!z6nZlM0?|BF`#4QusnVq~AtsU~SVH_BEBgGA^IcgosSV?0l
z1U2hv2gI(zs6KRhR5mf;L~JRbp)o&y*3Ote7DQf at fQLPXvxn{@Q?Id7ebDr!rbAK$
z`}~vr5T8Z-c{Quvnr~S8Ww3+jw4_ok8mz~z2>*~FwKvh2HND!=j)bG57u?~y1qN7c
zu69YvhQ+|T>RGxH21;{oN2_5F9aR@`VLVUaZdIZM<pCPLG-z->Li+trfkVH~?H`q7
z2pJ4E$D4L_FiA06d`<9JblZ2D;G%Z<AbP{X5XPuv9)f7Se%)iB4dW2g#b@(ci8l&9
z;#Tj;9R3%aIQjZZ8F at fsR`0NS?RC?T?QgI#dU1^a8N-$I%iAXC9Fqgg{uxbZ^$r$S
zitZsj1K&i2%v*Q1Q{vvXhepsqgWs}28zS at -rRmm=fyP^eY=8#s`4|F)Yob5Tt+HMb
zA*|T~T?e~J%8Gqy4AhM8Rg=S!p5K7)bDAHEmOgnu<^p*`E-o(5uC}iO@|PTK8mi9;
zv!qdVZY{#%ZCAo6ffd?>1M9OB%l9A|L*(s%Eny9#0GzEiFPVA(k!Sq1te8E|`bu+x
zG@;&1E`>_G^hd=`D!55`U1MZD7fpj-8+}AacGB=z&v<2b&0^_LgETqSp!1%gDwzY7
z`ki8)z9orNM@>QFNJTePurpLZ`K5D?;;lyVQB3>KvG638Ek}E{T6&16_T~9Nkg)pR
zm7(hyiow2lzw#FEt|}od^JjC at B$0H at GSz8;>hRb0H0k4`7eXmmvd=mW>n7O#-L!M|
zx>H$^>2#~@#Y$$)l51%Qozj=l-xepDcjtd|Iwfhw&CxZT$st;dxnF<u7;{e}w~1Sh
ziuO<&t=gS>`$Luu>7$YD#_>uia>TU64>422io4jC<Jg?qYsSxaoS~p4ca&Fc(E%d9
zc(podk*_XSw8+*1Y$)74(H0Zm3 at a+etl>Z0h4qFVaj#r_5jBR_@;zoK2bI4R<hK}c
ztOVXV&I<I#D?JRTm>D21+RyV{Z}JFT?G6)tXU(Ge_3GE;ANYzbFeM}})u>7!#-oHp
ziZT~jOJFQ3h}C*8`$;EOIVE`-LqrR)1syuyhU at U??tC2j!dY}Swi8us|4pQ+XiCrl
z;ulL5Lqz~WVaW<zvgGCYJY^0&vixYFP5h|{k6=B*+Ajg3Z$cQrF8fVhF~nQB at FH$K
z1o8vgFDs(Tv?rHkac`T7;PJrUeDfCq5Drf?t~0FI)prkC{Qi3#+K^>K at bh=CiZ1)k
zs(C6KYI_i|neOeq&VcL(23$eu(Ry1kLP2(^%L!0AhOTCVbHr}U3wsZuKE%{;-*(-4
z4%sQoH?8QEc}r6h0d;SiBAR*C(mr3%+sxdvTliXMYd>or3(e*ozM;M1?Y#4V5S^|s
z^$<256`|!Xq66AepCC{hZwMkxMDVMD_~}F4i0`|&+H_kG-|WGpb=}@h<Ov0V(6V@=
z1>%s1iRdnM-&e(dbFPh^6+=oun5xhOnU=i2fH{Z&%sF>CQWwXwPPRWd`4WANwf=~l
zW3`t#?q^YXD(q$}u$o2ME`XW3B at X63P_|fp+W#arv3D=ib0A+ZMFEwM2Ge=hNM~n@
zVA9<r*}>#NRte3PhiUXcKCy^}&^Q<R3F}}c158&l)52V at dm}aUubZ$mw+ZU8jL#3N
z8`E~q at mhRjGSXVs^A1JAx-zw;jIu1J=NBFDTMaZyY~6!0XJgv0-0kb2tD%o;YOi}4
zPyJy$`%~lM5i06wk|Wd_REdqOzF3y8rp$|e%0*FrGCVXf=Z-o1Gd7pSlp=q35TqtD
zlT_!JCmQ0g&UGCbqO=fT)mYtYwtwd;*phqr(X|Kpzk&Ryg)Sg{N`619!%0Y#xaF(s
z7aKIi;2(5Yd+#UU&#wQT`Xulq>Ii4T2G_~u>Eleg>Ih`kT?!Br#kNDfpNnL=#F%MU
z{)lhtc{a{agiPx3jWss7nBnPOe8fXM+)HUn?VYq$VNvuOApHOgQSo*ejlOCyn9$3{
z#})*A=1Te2<Qqd)Y(4<NFow}yd1lq-4rycP+t+7-s?Xh78tLD=Du!W#bXQEVB26)O
zF_sU%N(8Nai(jGs3oigA!CIhRLHKu$bza9L?v}aCR-3Z6Y%A}38{DM8ciB_!*zI9i
zo&V1Ca<m6jyDkYGTIP}TZWPh7Cr0RP+ZWl*A_pNlvzrG{c+*2I!UevywoQd2pDy9R
zB3|P$f>fZXPs&wz_0t#f2od*nQGd?p+Uxvr?yI~;6d{bc79w*NGdtO;w^0S$BeY*6
zT!%`i9B7|Rf7qRpeCtN{&hs1afj1%%N}T}6x&&xcAMw2Lf6dDyTat07(bV?9ndVF9
z3CRSJuNy#L>18t1G!9=|$!n~K;VkW+pTE8MVy-hr_oTV|RwC%mnBXyk$L#`0IcH?H
za>k1hqD$CwizPu!Dt!QTtcK#|BR6md#H@(UA^Jn;2E>G|`iUm at Op?ooJSG+|{l<@^
zS2V7O?;V)tH<QaL3V(in{TF+>Lomzh;Rz$2F-&?yHH4L3i~r7Vfe-`{vuf~j_Sm^{
zryj8M!DiE2HriDGnWy^K@`|&8Fi}EE`(T3)J%g{Dyu6i05%z4)hnY(B`<|6sIso%p
z`uMj&8qsR`qQr8nO=cn!tB}iBBolNCB}nf2z)3|tB^6=U&zsVKym*=S%!;fgEd4VO
z_}b^{<nrG8jaQAy1JCiiZ%cE3R{FT$ZAAGwzMoPl!%9d@*CV2ty$s?0p0ww{|7!sz
z=SoQodY at xJp{$u1?9BUYu)lvUXNCD#u0S5_-TT(K$}ni-H?SV>ud^};2H1?ZC<Ujq
z<Tw-i)LnXL8|;ku;MCj61CTFY0#eX_zmh0W8o%7LXV$*4EY0?guwIfkfaeMQCqdz~
zqC4$O&qtX(^pZ6Pa|fZ&B!iZqb3d8c7fh+lQH$><f0X&&ySLu`--p=<O%*YV!b at YN
zJmTh(>qC1PUK$Lc?9`oqYd#tI2Kudm?V&6;U}gr&BAo=i!VfGFD0-Q2eBe%`krT(x
z{Y&r1A5sRuqG?>!48fi;`RD*Yxwbonf=}e1Ru5wL^NF4}m3{z6iX|KGHpCrheX#ws
z at vK)f$smpMR{2wajcYrKUD?!<+7fhq(9+{SZq28Q#q&UL&Cz<TE3(+xK9yMIF6D(s
zN(r$stE1uXQMG*Ge~4sYn321NfMLm;6?U-cX>!k{(Lz#MBc(8(<5<tcNmp>8Ga;NS
zrCBqKFwLY;7F`}KwqJ(w=e=o=tvk-Zzp(3QCf&K*SNTDrkYN at g6BSoooRc;Q%G*=(
zP<D at PpSv95;3E0_s%8ZO3diRCkl8<fdZ*pmPUbVaUA`Fhw0hCHZ}D;^IRrKq_-<WY
z&OD;3ssCvI6EK{&0`2ia+J64B7eME2lsx=hlY=UAAD2lmkZt4k8>nP92h!3oT28>#
zbEzS%$w{1twa0+=UW&y{>HuZSSd;gl>cj+L0ir8K8OZ)jcQf&4GXUeTEbb=d{|L2W
z?Bn9Q$?rk{(gFVLcYvKBI9dPV<0)CTvP+fqj|@20Jg<F)XU{q^K1)a0Z4S|~YL{ZF
zS)*C`F`Oc9zyE9M*&zYAG#^`XIK#>kELj^^@(>5j9qP`OKZodFb*80YltdC|G|F at Z
zTm7Ono$R><9RzmYV?DMf)S?gF^vcW|VrTx{jQ)OH_1f45Ph`9<SN2Z9QuGh1d~Hs_
z5;w_w6cRNf<L%Ss{iA%~RLraYv*XyaYaAAr7b2NK^clq_Uw5Ij{>U4U`OHC2^6A0r
zKOASlXKXmtus^h=12?K}?(01nUebKd`T{OiPGd}Ct%glz<jQJnm&SrKHDjqb^+2||
zm$eDCnoA9QjZqII1tdM4CSZ7LlCAKKv!`Gkg!IL?h^5+=|1$63Yu7C~87Zo+^T`n}
zTjYPqdCt_nn!!}l`@`PIkpbP#2`wWHg~lE(ypluOs??*1>a;$tWt at 8mEHCsSmaQ+G
z>g(su#rMBDl#L^eYjuN6DYmKHO2Q~VYWB$9-j}+$1ex2ZrDg*KLcMpsZ*{7UkN52w
zzl4ii)KvF-*<20W;dYYvFA?|RJC6ePrn!8C!^!gN7ug?mhDv$mv<rK=!fp1~0Xo~A
zS?Jy=-OdHjZ<*QN&RWB9aeMFDD<PsDH-P_7E*QZXu+ITfQ>XAR1F=rl$rwY)jClH_
z5d3_Lm6*6Srxf^k^C at 6~9E#KV$ou&{$jBc6b;o4C{QNev!CgCD%yi1oAwmvr{`<^>
z#h_{kA#@D1A3kdhbN?+uys`PO#Q7E=OxBI|(osLNPPjtq`dmJ;wdXLM%%-R15FLU^
zqzD-fa<3ZYlz%01xA{pLmkG1$9DaOZy;0LIBI0kM_?SVhfAJ9b)dcsBv|M64RG%Sm
zp=tKDCPM{i+y4r+OiJ^;pnY1NA@;zBe&mD8TRD#C^$I%hwh6z(imYvF_0MNkj90KS
z!?L*Nk$~gypgavzZOFe7q*Jw$ewq_lD1Q~PMd;NvS;UwvILE3~DlcOe4oY8WPLvuZ
z#u_3SF`}Z`MIIA#6~DZ@{4Rt&<wS+{6u~9;WQdRQ6XIkvCcO>r?S at t(JT|XpJTxnj
z3)vE4l)T^g+|R$IqK2S6Z1DTfiu?FnyJV23rs)IQm)d8}h#E`Es_KMEl2|o%5i|3%
zbieG_Fq9#+bN=r$;E9#qYZ|R%V3%@+PLz7TzqqWR()})jSKF1W)b4YvN%)CzT3Np7
z7)bXzOv$U%c+Q!nyEk~MLeu$WG~x<BVkIz(&F+EleaGr)rbR~;Ei;V|cC<8>Lu0=f
zbY8`SEb+j7(cumwuzPy~cSDdB;`65L!REYryEHmn3HF4v_u)zzdG3Dgjo(0Yk#RrZ
zVPR1cE?CpJcr7^j>n1 at z{)c at 7Fb7BY4QNP&FaBKw{q^x1U=s9;{dxQbbcY89%-2M~
zJQGx^2{?7z_F+xR73CMIQO_lM<QvR76l{c9pnJck27j;;_1X;yYuvc}7eFOzh#i at 2
z-T+xL%R2@$^j_nrSXkRg^TrTK;in{Zm52qe+L%fO>tulj_ZI1qFxpZ;tBhJnD>g`g
zK4}y^vf%HPJro*QUhfT2cAk1Mr0jSwtORa75NC2ISbV%H&%Sy^#Q6wS!yk!0^~;jM
zS1<O9jo$aPAc+|+Itqkm>)&(2h67BwUEoa8MSFOj at m<Dr at qp<~a8TMpvH;tQQ}aQ<
zhfpUxA6Z3KX^?a!@^#j0ONClA*J9&0az}I1$eEC<)cOe5Kyc+{-I?Y2`)d`8kh3oK
zm*l_yEQHU5RR&mC2%!D&O%4iaEk9-XgEFi})u`0>>-`d*vb2l7l-YbVIq}w%%(G~F
zT}S?$jg63wmuy)y*Y_hnUuYpcy;kZOxB~gW(kAWT at M0K<-Evy;dS)_6omUXC9R7r{
zpL}OX&hbFLb9M)}QU9I!88o7Q2WyCFcVYe`|JS&Cm=hYF{APxIlBB&;=-6$EW+1m1
z<+TL!Y1gD%t^AwDB(-^1gBW}=0-OSSxJV~}Qsv+eKtvaUF~`+<LpuS;1f&dV{a=?H
zNUCC9tQ(P(B62$&;0;L=K^-~+7HwCc4-+mxO+Bxd0Z}Nrw2$*53DiV#OlW_~4}_{2
zO0P^R7J7EfPTuX};<MMSJ2O8Bhz0FQ;yIr*`vRa~;P(mO;po5L=o{<6sHy3ZvYgB3
zH^39t!_}k47dfPsFb&s!nO5_y@#6QJPulCX$(dJfyng%PV|CkyB&FGy*|=W(p>qyG
zOteTC?bwY{z`<6!K81#+KeePxC+jMeq)gH#Ff<rSmrk3cV?3Om-azSi=f&e51uS34
z+)lgvVgAosJyc^#3JOyS&BKi^^;J3~9Z`1Gl4 at ipgr~9Q!x#r9De6EEB>C8j=_?(h
zSeG3IlFxj$KC*=OOq>pq9^kc|=8xiHN&S+`Aa^d at K)J*@)75J`<x)5Yd7Y19O|fM5
zmi|8GUGZkjwn$$!)*J5WJDQupO;Z at 6cZ*Ko^oF)qM3suk-<pxZOUtr06pnk{il!>#
zDi5KE=;8ACsY_*#KE at 7dX@adfuw0$8j+VVCIGps(uN_!Ij^HTL;^cJ$UWEouABRfV
zxHQsHMV at r^E{sK1YC4+0o%WF_ at y2AaZCw8DK=kx`&6M~18`Bd*44y=>wtX5WR9SDn
zONuV+3IpbzDBcGWL583AhBtkPfZyOst_Z^hJV?tA_TkiXtsqDX6qF)b?~S<E^NawL
z&VmOQPB&-(&jvDdDq>4__vnBYe$9{vkQEjIqC!f+$7X<0jB0C=UmueM^Y^baIK at M<
zkiX9W<OBwk=CoCscz$Ym>w|QIU*U7HItI>DYRGqwbMKhLIgZ^`=M5*YLhD_tpgt}V
z=-2XxFd+D21>01F^9Amh#}M(h7*I#p1&IQ>XPq- at ws7(ZAe}z3Pgd&1`m;hkS6r<+
zc0(s6|NBy*a4G6|yTGJe=D2xlw4rhuJJ={|uZ84#-b_;yZ3u{=Tp~sz5#3capGVCh
z!+K-la|CJ`NCpZOwT<$CcL(2dlWaZOka at 429sgx0aW6{#snu#0P5Ei62+-aZ5ayq~
zc)ToGY3yAK8E-2YmdM{vm&kAx-+^B1nElpbVuGy9&ZP%}IyJe4<G_Pr?B at ippj#t5
z_JRJ7B%TNjG)o&9Z7VLlU({|UGZfjYi0ye(uRJ`IcG1odvGm&Ev;bS{ehO!M@&R|i
zq>i1!_gj}xA+P6TNSdo<g3kiEN>WpUC!~U|zlQ@?@J_6g0^TE^#kWkkitB9E{Zsm^
z{}~$AEm#d3eS;y}=v5@$@K*LL0mloGUhn;KH;{N+f86Nqy`J at qT=g~DCF#Zd#o58Z
zKNxYNa(?CU!mYMB at yXt4dA-2|QFT~aRZY-4{}fOjj<h<Lm_MD1iW1wX!{3$Y%8e--
zs!sk-jooYsJzmk&vpGSY+%Hn4bwO7W#`SAwlcTklOI8PfQTX`x9pvd*mOwx$G7G>D
zg5=DB_kzbo$W)Xl_8KhVXn*`)Q<2X1n$x8eYE4elcOWCWg at egwa+~5T(5*4k*>NB#
zxKaKwa98k{xjf8lfG}iSgI{#N&QOQ~X?6>2w8VgTOupYL{kG_?z7a<11!SCXeXp~+
z70ggM$sql=+|5MO!I7xXk=4J3DTor4+-4LghR2*Y{L)^_einD6gmx%q{t(aS&az0|
zX}PEPP^f&)Z<f63?jk(vDxzjdrA)s&4k7>o^SuaiiPu2{N3U~cUvcN=mc0)ND0dM3
z at 4I{`vg+{F&%?Dsn_G at s-Rp`oGMu{cg2$*S6fs!z(CP2XmoH66KHvl#EEF9gA2GKa
zhzhN7`imx&gd*R8=wGd1U`xwp7`uKtnY%lc1|imvR=8tElRU6wlApHolea74|J=CU
zkiCa}UWND-nU>b+RlT&*yzJOWwe*Yz_MGZBzKj at B6+luBk+(RQ^T!1 at c%U?!d+lRC
z)1<AO1NJT<7XhLB4v!Ja^`~u3_Y_UMeJgY49qb;d3kh)Pm6!eHENxUx714O$7SlT4
zY}OE7$q<k3_KL0;ACO*y;hg8(+Yc5MBo|Dq9rpH4jd1(TUtt*c6M(%@$%TmhaQx3i
zPLpRF<>F+=a?1(dA0V{F_m<R#MA<rYgmIZr?so;e%e`mv!2Lfi9v-Yr$E$OHr$<$C
za~aNseiVjf;Z*?Q1{<heUevPl(e_hY`Rgb?bcc&g at 4s|ehR`v<!o&pl$`qTKSNEm=
z^;LLl7Go%iZWrx-ouLV#g|dS|CW at IyK$ni78<U08;J0RbPQO_A)vnL-Vx*Yuu_wS(
z68r-w*Ot8Mr*>@&3~)@}mfwTq#?Rz5JD<!i$V>bNpusja7sUkiDT#K$N}O*j+z9Z1
z=e(6SS%Z8uhF~y1yUFs2bk5qX<kAsbiW^<)bTqf$2_@{jS+OeC_%K at Qz6(U21Va?P
z{en<FyrQxJA%{Tn7kME5;VdI@)weS}cYdd_>c3R;o39d1{ohxIT2f|5j at Ut+8cvx_
zTak!zj`oqkz$z1ancMmI$`<W5I~#IDdcfyN`OY2%x_oJ~jSOs#+6;Kd(zK;(y%K*H
zi-J(iu}WNiq&7$I>y}>5)*<0ahkq|W|2-=VfstF{@sDge{^5K!L+$Q+9#LybGr4?-
zR4MmFCsUci{VHuVQ>wgAl`=R02+e7`0BYQ>d|Lz?GZn&Wlerd5q>s68L{TbzB%wI-
zzI2`)`tVLs7T_MeV^b%dX*0=&wH`_E-Xx*-Gv__(Uo?Km_>n)$s6pQak4 at EXynMv1
z3TC|Gg5L0|eb2KHh=T~?+i}iD at W{O)x|-ydj6?rOCzpFjXXM9_KYJWoho*R<MgkAn
z?yFK^$MFhM2ZLS?W$KuHzeQJ1EA*g7 at U6n%-^c$foPVNtrj;sK9<4Ye&`_@@z*}7q
z;#x;^JfYunMjj8jdO(+~DPh#_L4lFU4=Y~%KsG7&Ab5XPng&Lp*otMkVT_!O>I at Ip
zfM>)JV+^P3tZljH_Vv8 at IICxJY22Q}t8-TtNRB<=jBq|Z at RZt62Dam;$r&*2e{A2T
zHx2W}N{=0~!E4kf?5RWFAML#Cv{OL0 at X_H0)bsP7tHi at gjJwz0l+AXy`L*cvk1OF9
z`;}3$DO`R7V;G>eiq@{&2=LMIc!aV-k$@X27omar5$dt2B7vs2 at SUQ1p=vg|jryru
zv&09Y9}wQE8gEMgIz9>PqzI!;Tt#^ra*x^KhQT85L$s88^0$d{iYs2$r}LyvqvPhz
zCgq4#&%uPCNc!Gzl1!|VqSFKJJNwKMb?l0sFLr%JF-Ib7v>k!2mHh2BDv)c*8}&oD
zj=Z#|FR at D|6`og3tn**k)0M#N6>!`S&1Xq at Zm4|cr6Hr!uVZ94-w845eYRvv)TK!8
z0 at 8cS<mKp-8!Z!nd};~m%WqJ1&oIIGqhD79hn52+j}H})jeKPir4mHE3&Oq~($Z5J
z at Jb5Gj`xldy(n91zc>1%!no$5{bS_Nk>h?U{wcbQwXW4VE|(ah!6Fns3m0lX4!CrI
z1?+k#1o)#GY_vF%gdrs&T!hW=sileeZ&@<f`N$S|qrtj8baj<ZQ<NmLFU=*~%WK8W
zCB}7NxpY|~T{H1<^swY))AY_~Tw!(!Zqb_a!Yqe>qb)Uwqkm(ms$bqj+$s-1{%4Al
z9}E2<#a}&y9`JDkFO1_p&@mVSPy{pOMe;pB?NU-PNn?hDB|8!UWH6Itj()K?8$!XG
zIc{b at wf$I~LI4qlrJgKuT6Vihm&!|Y*l>C1T;Gd_?@b^kpiLJ6H;}qMH9lX{df)Z>
zTnO;aL{LH5tAOi=blJmYUB;x4@`9F0^ViEJ<>%m at gt4Cs9ez(L^D4yScl)@j*#exa
z>oT6)3O2 at J?;+!(!dRT$c1+Lm at 63I>Cykl(W>xqr^=5Lk<w`;6yrN+&JgvskQ6hQv
z-R)Z<LLlR|2!1_Ob&J7Tly%uT at k}sgdUEjTEzKA at 0;)0U3gb7KHlk$eR`A5on?Ygl
z+HKf;SDp at qQ%_axoRwztNaO|)KlOLcH2W1O)*(;f!kh6>_c$o!d at pM+$okWzEh^wo
zW?pO95%9RMg$e9m)(;wieVLJC@~&UoIU#2l#T9Ob(+<>6P;n#UV?!lH7pG3xT#E&@
zMcJLISPzMC<b%lt`Jwyx3C|Bx3H2I8_BLMcSv7DBrgufDdx%_ipkFyWQoqiKIm$xJ
zbaQV)JteYVG^Mvi=_#8UAghUcNXu0R`ME;M^#8;;ag`#W9exW^8N|gF7F2V<@ZR%t
zxv)L#E??gd!hAuyncId<=Ss*mnMy4^4DR{a2!rt)cBb-tdAc|Ru2pGPx7|i9Nc#IQ
zMe=o(RkcEGujPjVI*$lGN$dE4+X)^F`UL&9sWZa%j^>Rj;=`L;+IKlF*FKWI1hISI
z+BLF at fkQEl@qQ(-%%$osZNbs(-wQohwqoKCnTrR>G6HCb)T2dfKo4`U_6C&WF->Jd
zGyJhh at 2C;oh<bEU4}8rcusNRt^YxlsL*Er#l*ABVTQZm>T@?R(DE>g4H*N0 at 3Ruh0
ze|%$cRsq6JUxv;JxPG9N3uvM<LXf;;=~o(@W$szjc!_zjf<Ikwtx{~|h5y<vy!7I$
zLYC`fgYQ{fNKY@>)zDz)KJ3s~t)7<pM4z5?P=rt}vgWVc_o!~`jd6lhCY++OXqhAo
z5EkAhNV-DFfS at KX!x2scunNZ)u2=i;?Z{zcuao?{x3Mnh$R&gA!HO?0zB&$jz4b{h
zJgLH#4>hMAniVWy1|us|((Ho%ORq2&TM2s at yV!aMT}-{8SR`HV<Wv^Y_+}|r%H_Xc
zy}-LTosst{xIiz_m(FCGg^sQmZ1veI7Ye$c*Hd>Hq)QDb927 at -?8aSxlo%eg)8v)?
z3Xwhm8DWebi_c7Su3GbdS#-!!ggkMv>LtB`>I}V;^-<z$lDvt1Ij2 at 1R)_g2b*k|!
zwNb`g0PW>}`H%a$B;kEb6A1Ak at sixdCQg@6&7D$sz8b|=V~^%vr-K{&<zBzr^Nn5I
zHsk*}P4E80L81lBCq9OCgD-h3bLNFFT`vi{F7t_2l=pD&@!?3VO53#~doYb9mQ6cO
zlNqw$C{&!Qv>$hTe*11bsCsWN_dN*P-^;~6(7Mh*zSZcnLL?p>JleD*&-5 at b`6bfi
z06Ss at WKGR6pujmMMK-89yQfYZhyd*B$z~8;BfhO_MgDpGI2Q8H5NX(8P~I~?*TA|G
zp7yQx4>;T2tNCTXU#UXbwT~K&y<EHv5kSnyvgS!bL+V2ldyhirE61$F@>d1~{VA7m
zu)Whx6ri{g8y{0Ps3|q7Ybs*-!UoT*S46Z4-SCs-xYd4 at msO@H!ET=N;d~txj at ofU
zGmK1D>>+OF_1anurFw~zb at oE@?U_|aCjGKZlrqC(skr0AJx9X at v0-<Fk>@l7^7o?V
zb)I*Q?8%p))-Q1Xh1Qd`o>;9SoZQJied1~2xgpB&Xje9+0y9$eV!)uhD{z*dnVnH<
z!$6{c`h+3p*}s{0<`g7+FAQki)?A)wrspy;L+&nrqK86gs`u?<*%t5o{QditUHopE
zF;2+5HDv=;BM-?$)%#wo#4Rv!>}=2e&3?20r?u3oszYIa3Qo_V2<C<|a`af7GrxG^
zs~cA(DzS)Mj4q^1p~)h at 1UOXF==TXaL;ekAsg4q=w{P!POp;!CEK(JA2CYacenT63
z<HB!z{UW at r!@lRzka;3?rgH7eKVA!fu8kw&s9p+T;Ku6en6inUAit$crx?f85pMpH
zDAab8-Nk#tMSlr`QD at 8jx}lpv?79H*7|L5M6KUZxMw*ol*{9=o0wIO}Noj|UTKS&;
zH-&Y+QUXY1Nu7f2#?GZ9z-DDP0Z8_<o at H_gd<FzC)S;-YXHTmIw@>K=h<XhF2H>--
z-|ky=e~IDsg?|7r)~QGtKA4>B#P#^)aZ+_ZVDvWXLuJ11;mX>32O at c!AQmtgzq1kn
zsJ7wEGkEI_C<vHhn8N>)np+Vj&gU*f0N;T1_>h(w_;;a5O553KIM^~J6DW|=u3ul-
zaXO1ab$yNpeUw0pzuJGfH6g2|jPXG}Zkfu}g<%SG|86b*GLAoZ;}xAJTtPFN!NBOw
zR!F9nXb$d@$U``KTv6IpX4D@(kkP8rNL8s&`KDNO4-?%<S3OIxII8|$KUm&18X_mN
zW5QZT-$sU207JCs1DviqNmY65AF7+vrl=#i;7K309~Yg~?Yu4uvO12w;=~)agB*C~
zCF{da2G-v at 3+l=JJ+o`HPF}rdh;7>NxB4n~(%^e~&vFB~2VOdLEdIde_3pHD&Show
zz_yW7%QL~#%9wv|*{5#hFVz<18G`|Hv1qQjKw#(pc+9$#4Fk<@kxv<$Qr;4FKA~z`
zBE0Uhrb_?BI~2aD2pZ>$C#i3T&%RynZ&;K`zjYiYctDV?)AVq1`WTn&MAACt2zH*y
ztd6 at Jt3!m5j6Lr*=U&3Dv84!}xtGZ5bjX9?uQB#p3eU<?axj;C#3ZC!?AMBMQ&n^3
z+q~9`OE}eKY2=QBpL^P8Qi72IkdcZ|@~4H~dJ_lAK_3AmP$<iQk;NujCJ4`_Pv$9i
zBarhmk2A8G1sWJM2XKjA>UZx?Xm*Pb3cjI}7m%a&^eM;Srk;SUz#0OORfeZr00y6<
zCQdb}df*yL-Nm?62dfh7k_)7a*4=mi(MUmnj5ovRu`2LX5xb8y2;z5YK?lH3PJRW9
z$aA^kkG_w1_UyE+c5hS2!DaDV#lo60MhJqL?*>g;&`bJ$iR@>^@Fl*>A9~BQOmAj4
z+pi_8PA2CkV7Nc<<INb)m!SNaAWFMzyt7*w1Ma;0=&w{YMbWQW*rycJt!Ee=((m8D
zpO<;{oIEqkjHj(ubUjm;*tDC9TT9~v#VnnceeD+z5Ibyy_I4m;M$V5 at exC-w!PmR_
zX^zNlKABBYYn0|qlaPmbQ;x~l?j(NA-M?qKa6kJ5|7}Iu>MU``^2%;Y(w9GU<%pp_
zM3B-KMQ at sf^D{)S=W&zh3z%A#{LGThxrvK^Mz8Cq{X9^eVTCRK-0;!=@pRtdRR90~
zx8-dWMTjVy2pvK~DkFOwTh=j-J&r at iR;i3+uVZh{!7<LU$tYX4W0Pc at Bgr`;`n~#I
z*XQSt{&1a3UA>-O&&RmmZ};l6Am-d~>=D~g5yN#a(u|ld{YF*XO4~UMZRYiqApLXA
zD?gcIn+iJT0-+af65a%dE#0J2%2K236r6G|YI*sz`jQiT*nUyrp8Wh?)ypqmEzGr7
z-M6k{s^T*A*;ZA23}A^C5-!3lUXsm9wUu!R%_Ps}B5B2fUz(B4`8$Cj`39=iOGb-!
zQMf at nUX8RRV2<0t0qB>+Yw6^|w*?=jTwH~psGyn2eiE;EMHl2sj78WxOd=BY)_`Gr
zGN7mZt`;~~IWy>(3;aUsa>Ob3sS7jXk0nBs*Ar8go6<&EELJ-2QhFP_9e)mF83_BK
z5Y^2~y!xSx at O?hPP{0|W+r6jX-sh{G%+ek(x_H#`sub8j;pIrcrpfNO7!<%InX{Q*
zd1v0@!dq<VXHqhiYqF>|{#FZMp5VT_C15)2K)8wJa%L83xN<{TYb2wKT7BSINRDNx
zx@%1xeW|z1>50PLz60jT!wKl@;?pi650V&R0SIk;4r)V5KV67r{+(VKaq)Y*4G^$B
zr;U%2qs~r`RUWBEwF7^J&Q*@D$G=wt78-nfVrJ;`KM^Z?Nj4|mfeU1L*_=yaG08?%
z7h(J(<EKB?dzUviH%sRn$3rQ73dYn9rwmkWb6?*utT-Ft_NNyF!ZXmMmj^*nAJ-zX
z%WqXkP*}VNb2+gtMXf8*RPJ0`^Hzmtx1^1s+)KfX{=mQ|<HVkS_R!l;V{l%rEbnAd
z6&yfw)NpvCWg~K&_NXI8=5h7)OUYhumhf`T&{RwbUZ=JrP<9`aO&xLWGyLav`O>yt
zWOF#@^XY0V`Lh5{grYvg0<%lSeHK02TbIcwu^RC|Er4s6IbxJ!IM=g7#SC7he=PO6
z;qS<Qz3#*)?FLut>Q01kTX|R~_fOWF4{a_GdysPu-leL?p9FvXGu?f$@r<5wIqYZv
zCI&X6FOrwsyR7DR@)AfxY at ztlT{WSeM%S$ecebKskCkG9Xxn9iuA=sEO${f!20kMf
z?zaUL826wuFAmJP&VftOtN}<?(t1POPoX(!!}Y45LB69<{f6iJ2}d0)&JsS$Wb|__
zraBrY|KhM%oJP#+WhbDD{bEVTj{2t+VRR}wF2BcBhXG_;_a)Cw!wkLmGT)y^NTl$7
zCT3N5HmUT&s8`zdJ at fig*Ax3658}+)K=D}&F|vc!0Oow+n=7FWlyev%lKlN(Es>?}
z=2P4&<#6D9WTbJGPe2V^n^o)~rM*9Q_zL#Dw*Q+iHY`W+{)fqNsX-cT2n0f%(X=Ry
zRNc>>IP<D$3>w42E}0_9YXbGG>uy=QZQo_~O14fB6%I`LMThH|JN4WLO&DGs8FA1w
z%g8g03PU6WF&y$KTs8k at T;xTcF55h849=NOX~AkR{>5mzI-|TZggLi$cs|xhJ611Z
z at ejlp;@XihRg<cM82$_PPraCy85Dkzb-DUEv=Ez4m$%PaPuX#9it$6%8oO7R^;4q8
zsNFVCwNHz`I*t3vX%GDYblwzV*O!io6jOwq%}?(+DeC_=E80;!FV7!HA~|JV{?6jG
z at wK~etgD`LxTAJoLm?~r_FP;+|KuOX%E<Pbe6s{hy6l&7Ma%FmDIK1x;*sfM;2><+
znkN^8c7S=+(ze)?0~aCQ!uHZ4Vd1Z}``(0YZOh+|?Jm~_L0|sA)0~2fw%X0t)HfF*
zkAO$GrFg%*#@hw<DLMF`>rvYItyTCoR|^??05^EZ==7X0qo+jY4_gI<F;E<+kh%E`
zG5AJp`NUH0Ex>oMP>Qma2wZ_X{Zr8~%s7%hUru?}^QY5#$>ACXu&bG}mjkN2 at hNto
zQURj6ChWo|2gm&V&=Za`kw3Mbxh8APB2T4(H<SKPk-z7HUiW(ZY_-0A*Afl?{y;20
zCs~0$kJ$EaSVz0|%%+tOFtX_AaKPQ>9cA0L5&nC&kDP6mxl<lkF8#=FMS&Ku8%~q9
zOZCSQX(Npc#s^`b0qFOU0ZF*~Z!ngn6wH^4R6GCi<HyHiXV$SiR?1hSP{xv7A6k~y
z4`T2A5C3cZl??yV;wwo#o1nR{K#|eY%EGPk10*t0STadZ0PRtM%^7%nhuaC^$e-4#
z0a<a}pvEPi at zLxEJ*JUa6}PnMids*hfnH2nQ|qZ{hUbA1gpbd-6`Q4o-7R=ITCgn$
z at 3C0;ucs9pFF(}$%W8O>H;JgCUUm%|?GuyTQ|o_&^?mDU$o-7WAH2iA=92yF{nagt
z9w)C)+f<)Jx4Z6Ri!?mLwl6~Guzm)Yi*k|%-}9q2wr%7Hj6aT?SCu`g#=t_6t(^D>
zP`AUiinM#`c{7%*c~Obb$tFYjZ^~`GP0&Z6*$KYNjuf=J(AzvsLR+<mk%aQt8I)?L
z)2*qS&Ur4CX_E+-nfuz-p at rE8Cy*0UfzcR=0DV*a@)6f2^jPBW7oqx~3B>z0;(6C3
z?_4fM*eTEzsCDPhLI5lSHT219XA^cUQ7AAWj?@OsX583{C?7!-5=-uL-Mmx=uo at SD
z?s#?G+E-Ig<-uQM7KX2YB;d`8 at Xn+GFnHV88Ck#B#EQQ>OY2tL72ZtE2JQ at 5+hz&!
z`!^+sbsv4LdI2-RS)LfMbsE0 at H%+y5)yy{&_s&Nm?UyB>4YrF at CXEA(5!ET~4qPvJ
ztwC`;ae2y2_I85 at +r~h{JuI!oCz_P#Av4LgEZly7A`qQeBP2%IPtk|z(H`0LT7A1Q
zidOk^quYJTuaw at UbY@9>rXjUrZ1U at uaDfKjnD|(9g8 at fHUVeUUbaQ$gcyyZgg;ulr
z at XG^0mGyHB_`bB6075%;_p{@Iw8NlzS?j^0!94P<;?>7`sEfhZGi7!NQD}m7kU^w9
zs31L0hrT)E8 at K7Vxp#>w%-(By9O+GP(LDQ(w;K7Id0R`ysgv%@P*7pbOx{jOG<CO^
z?(+H2Sg`#iI@)KbHI`g1oTlMO;#`$6eLX{W;3VG8=9=5v(bEq!fl8DFyt(=j0?YA@
z4Gg~(%OtMwW6eET;>38e#KsQ+WfR#}oB8ok$H2CahAB?{Y^6U<MYHLUXi{2Bs|6Mm
zPMCPurF}a1Xh9=D*0EG!fR@!(U3-*Xi9$bs9kc`P*!A36Y49)Ya~p at A83^?_=CI+j
z9j~8>uUkAi+^g-f<Bo*+OnRB#s+6pJnI_{%-fxi at mgEN;SN7ra=bmCa;)MmQi-Fdu
zDNE&epUAEE5I7lQZ2Sae_DJuWEO0kw&w~*L_;jD!f0w+rc}K)QlsEwZ at SOd$m8|)F
z%j_HZR|UAM=W}a+0fXZo&s$PlpGa8r^8#t?8QZuO=DEJvk<Lw^Vec>&SrTZTJf6Pa
z;%d&Rio9gNfIax}Qn~6S8~ly+Zu0i$*BdMdN5DR%bB!~OWTU*_3N+d(2{M67CQnaq
z<21?@25+X!K9l`FAmJ+*l0Gjv0W#AHS)jl at Y3py&@W at w<lzY~Jzdcvou3#$B3j`<)
zgMM?RU$m;vbQ5W_#XOYVTD<H(=}mmIqb|j-L~)kd!2q#4^W*e1`dg at Af-9hH@p-H~
z#-fwkn?dmv at K^X(3|C##vId*ZwelA?PxEgx at lr?Ulvs9=R-u2>=!n at h;T6j$kI}sM
zY)M0BB+nPCcq=RM*+R{UDLPZgyYRe7SC1zP#??IXlggQs=T;&-3&&~4sP4hWVQ5fr
zuIva9+g&~0m<=gF!^-zwG-nX!Xf>if<+bR&=JjrQh%>oW{-+=2vDH1aP1VNliQ!W}
zV9ALZR1!tK*EFnHdL%p~{$|a&Gz at _vap@b_-MF42ayQ7n1hY{OxB39^<GXxgOm*hp
z?amhJ_3RSKc_^zz&fsk9x}<=Ur`JpR;D0KbQo#w-=N5N at +4n%N1V-<c=Pwci{m+t@
z!E*5m9(BiIdnF~m-0P2PyDnPKe(g-nyfD|t279c=X`u9mXr54Ov_+gTl00Yr8su~}
zIo71M9B>;YH(GL$uKl<1PWh?#RrvK-5%LY9MKU(Pajp&SRy6g_I3*T%^8~yw<IrQ;
zXMh^-x4}_9b)Gyu)|HrBgf>hqz*h^v0<wv{V#A`H8oondtu)zlMY^9CeVFoJuWL<<
z-m)9eLfLJwAhkV8y^dFhCOS1V_+w20PZY%bzfRa<h%fIgubYMU)d%-FeGrXhMniuE
zRRi5&bYF?6b1bRWl;~57#Pv210A3RN)lC3B5I;SUe%7Cx#o}7ykvUonmJR)Z;jw<x
zRDU&h{ta5#qWm6G=!OMk=SvPKE@&!qa99^lUDEp=?S!dWl$2j#c>uZ}WL4AiXs;9B
z8g%j{-23lAlu(5XBl#jNWgh`H#<qA;KKZ7rfZ<ikF-16DhRhkr=Z0UbBtTa1i9xrp
zo`mRu at YMucPK?q}+SYW_nD%m74A+FMhmIJtO>1SQXvp`)OHwhL(;JjbtkO||UJu9@
zoG;<F)O<~?L7l_NVwUYzL$fy=$WvtqR{H#|UT0cLWYBX8QvjFpez6uT at aYlr_w0#%
zH7>@|S1sT<*;A}bD${45gwG#YOu2X<C-)R4WG%(AncPt_1_4=0?Z3e6IPYNDQWzu8
z_g{6t*7knER};JyyqHwAzXt`KbcT_ at _)l*6&YDd>_U}G9D{JHgF)Rff@#(ztwAEe_
zHCuSNqB0XSyO;i<NwqITV?e7^5<EqM3*T2}rP-FRhU?(cXIB0uLqvwEBg}W at W8M?8
zKql5^RU<nb#JcRSz9WDb*X$;@<cVZ_aob<?w!FmI#UDQ8Q?f2W<ud&G-o1P72f)s8
z_cdOg6MpHs&wAq24W7T at sy>sh`?KfciVyLEamw)-#0ElKYXR|3?!pHKeTn&gUY0Ii
zqOZNX>!l$1#lfb11R%$J|1v>#GFu8D2YmUZ8=@!V$TZJqA_Yja0#}^;KFuQM5i(<3
zDg$5gR?%-$LIXO$0OFcGgdwAtGBVM6INhVaf at NBFkj;ah3Y;kX3~X&=%Q+3;<MM61
zXfm7p+2aF0XXO;IIAVJ4WXN|9g#tN$bn17qnS+%4Go$vRH_B>Vel{Ax;;g3JBp5Nz
z?{s<JhB+R%b9a=QrwDYMR12B&nVvWFl$}#|I`t$b3rpOxp6Z<HgwwxaD6pN9U#bK(
z37{yvbLNB}BTus@=7(o~qQ|jTyD9<O6a?kKSof}Eb<Fr|Z>z~{+MfI9cf=0OAxqai
zKabj{B6bo7(+PXdSNZK5KML7<*1oO at bA?)(U17 at qmfI-S+3;N4sH)M3!p`7=#qRib
z(8?<_2HxgV<hcz*k+ATggHLX+4fNZGws(Bj at ZP3zeqq8#9W|P4-pQrDu~qjNSQ=$@
zdT>x?pB3su8ZlRzryiniofVKwcJ!lXlF~NkcJ8upo&IIZlVdXu?zfpEATS~|nC&rP
zMU*>23$N+CWg%iL at nE@}3JZ`^-6>9hf<hp?yv6 at E;(`UB00Xd(nKlD3;STXfKFbHx
zE7Z9mNZP1uE6aMRerRM22b>S)?PqV^Dcdks{U@%BkRX0<nIHJWPQ1%NjK?PDHYotb
zu;I0mqnx)E%yRmGO=0)N6}a21!+51DYNlh#H;6rn6uqbP2fXB905ELMixYa%x=u$>
z9PgBYO+k4B=!ilsw*L4oa at dS8KYP7Z748pv-kQe6Ll4ROKjR$0#W|jkB$L&xZ=rsT
zKG~%H^0k|-Y9{tYX`2I*wUDn(=}`{LS<#KFxPr}f+uJeqe at KVl=Y=lUtG9(I&^ht6
zH(M^L0hOzy8_E8s^0y$V$2tjk1&8PF8?2fKvS;Rc0KvjTje()OyR3K_oz{SwmzC0g
z$_?_R$X~zi5*QRbQs(4K^|MQ-Y=x-96W1a<KE_o3yid at 8Ky)RYUqTq^6PXJLi_nQ3
z&-~Ur%fY}*wB8Dpa at 5zAj%0I!BW>?PIOM5at(?vDpSgbb14j&v$P<sOg>{%nY{&bX
zs&-~R<Z~~gynE$WXkQ}H0pE>vEZv;!G-0TaQkE~42sy4hEbw_?f at y$<b7$`SRaR{6
z;PTofJh<AEr;Q at JP))$Ssluw+W`vLXu`O#0zq<B(_L0a&Ghxv0G3R>M#=WN47VX!P
zHD;t%5W`QUj&SWHUBB&`>)5nGH%;5E9_>dEn8VDAQMw!T{1q_t_!vz}!m$f5&^a{S
z_{Kq;KYpWZrN{;kypPhM7up1ECH?a6K6t;zGQMsi8zND55}qa?-?INX`er|Giq!>R
z>tFZ?BpmPPCcjoz%A9g7jvu1L;BUlDai_dfmVblW%?9s;#_}{jNb4s1#*RPPcp9x~
z@{Z+21fZ{o{N0Wh!Q+0bEES&ZJLbJs*kCyz0EG|vMcT-Tqcuy$!jdpjvvV}u$`Q<6
zLhvK3NS-gAG>=>QHzt%wyn34ucG=}%cX=_cShaH`hB<EdM+g0~wUzDNg4u<NsgzN>
zx!Z+OCfjjQ_iaV~Fg;s<h1XGr<dk<@YFbAVEuXH&n2EeoLhr8{97!oT%;`xVO_X#O
z>L6~C-2TmdhB~d at O2GZ^*F at G65o3}SN4ePs!!2p*LEJxuudyc0b$3Hou0Mqlb-4C<
z7aFqpx|m#$o6XWbLZwva%bx~sJkl<pyZO8`v}N)?<@W;`g~=V^SnX#q0TO+BfoadD
zwe{EL3teqDg`cviu$(qTV>5BE9nW{de8|*Jgo4ZoAeBfvTHA=b7KQ&Fv|?N;DuV4A
zYvekDWt$fa4oNBku1R!qu`na)c>iIL%9zsS3gTsCixz$DLW)>q%}nFo(7S31J56bI
zV&?&n|A=XxZ8P=oj6(a_wUqQ(mc}(i*J_v(-a|evGCIZI?WumyB4d=$nY^l^a3(Ii
zDHGzOn!7i!@@lm6!&fn4g~#f^718zSsungyKh3Q at -lV1V+#G6o?euG05 at DnwW_Y0d
zNS=|O<|t1eFR8?BITT30c at G$I+r?ex5sfzkF^m7yn&?8HyE-Pc1KRD90iCqIGP#Zi
zT}qkr!9GpJbdn_TW;S5?bo<e2SHxcpoQ7H_$m_;L3wA&fsDrP3_uV2KqDr+Zu@^cP
z9KgL};$RGlj44jT!S8Rcr2KSV)_ryt5ElDE4lbTRT;jVU-!OT}O?y$$3!{x at bHLvw
z2e-V}^usc);9Z(4O=oTSJ6 at SG+Idl^;OM!V#de#8=IiMlYs#ZqA#xCAS%Pej4$irw
zF at qE-sq74vybIf{d$CVd`J%yE>EKbLz$A5ve1BUIBxKCc-F->zc>-?oZ3j;lns0Ut
zW at yzAURV!;NmxM!1e=vYklW5Lm#Jk at cZP?gMzVU3!;@VvwJZPl62h!g4$iW&zqUkt
z2sy5 at O*i`)+1gaLxLtTdS9`k?Yu1n*9 at yC@SWbn*`<+VZ at u`G9;0GxgN!VGwTWull
ztxVTz%O&a;%4;3m^}n1G)ygn)U6ry><H9-9Rzvs}Ax9=^F*~TPM*D|*QJY85xbNVi
zdxDk?&PTBH&!++6KR$aEzV^oKyDWrzy=M1UC3ya@{b^nehSA>H3?*)%D6LpH4IPKb
z5>c)_BPi%2cJ{evo1Zrxxq4)&?Z;z>oL4LIQO*-#guI1-DkO9i)|`*j>Dn#SuCuTY
zQv&A04Bx<%fGfH(`vlOTtN^~r-tMM6Fn-IjEuah7H_d~jWx_oVo&{S~`miI&`Sng7
zddV-e%bbUR9YWvC{mtC#JU^E;vA(hXMo1pz at xfpqgHWaLDxe2nQUDk0<214W`j9B<
z8XV`6{>%J|V5QI2X{wr*U|<DV*ZTph8Ry9#AUW<GRZ96au~w3b9QgvSKWZ at q{rLts
zkI1Kb8 at gb--pRIfAbfqxlECA2Bjd24zUJW%=#xET=Ozce?!`W&{ECCB)G3IurOqlm
zNKPWQ0+svL;JkH|`}m`I)onRqocY|Ux)<SDl2G!UnYq9B?pWP*7nb^r32FD2fgRDx
zD6L7}wV<poZ0s;gZ(nqix{i9RP8#a9*h$)NldRiwmK>OcxGvU+`PI~Vrg^MFb7wA5
zH=NrvBzZ!HotIueI<WM at sG~2AsXeIPj1^Yob!xOvU$tgiLHLB&wnXX{zU)EmSsX#U
zqM8ovFkqG6=w9dLcUdJ`PVql2Q>s`Zyc$pp>1Sh)o7f&n+z;>E?=r4R{{k^rv6t9x
z;GVr+b9J~dVBiyX>gTID4-O7QP}cq3L!&E|9RjiiyqEXR&%6noH7!q$5A;*bABy=o
zKC1RC>VOYjC3ER`=myd~<P_-wMv#8ERG7Tj%=E{H4Ft<-H6jf8v*w1Fik&|yrZnv%
zB_r9xc1f`J1qaxBt`LV7tJXzfSbjj+jI`HQuwem8IUz1U7%{yz{;n-J1YF-5!%d$S
z)mod|j=o}WQ0~78uF$2})1RUF%0av<p9hHeYEmWI%4joMcg5O*&{l|W(wWXH+9{z3
zafg2*O@%(*fD}M|rIQKVYbvrE)1-5*2B7kJJL}mO^|hb(cKvJR)Gzs`wZJk0a4re=
zJh<}85#R>Y`MYdY0fx+(>%xT_+sduQ=W;}a)l$E$m&*I)$C7^z{$3okReNJ-Z?JwJ
z8%?@%_r(1`{4O{9<bT8RpD~ut_kqd2nPZ8|L?n^Y(N}@uyFP~E>+3+5ST&pG#mL%g
zK3uFQV(w}6aV^VJ2{N;9+kGr9JBv8Z6pmNnw%`peN5rvz^s+*o&B*S{z+?k}={`LF
zVOZ;_3M?6hx$N8u_{4xH0@?b4b%%D3!@7V8uq$hDMUZdd`1p|8 at E69wf1j>;edhz-
zH48^nCS5?<cjvL7ju`d)AR)wRXINW%jt~Qk`iR%9R*_0wt#y0d^Cc>R=OMBOlMgps
z5*JeffNg%PR_<(nX0Ls|zUI&rTzt`d>c`rwEdo{v4iE3#J*;|CG4{;5tEm%+daZwr
zmw+oBkxtRQ;WW1Uf`Nir`uqr at G;gbQ<zxEE{~Y0~ahfd6iyeBMII`$sOYlZ~0{BJK
zZmnh1i+vd~rdH>U*UIuy{Xud19JG%U(MSynw`9g7S9*+J{GBQ{FqfGh at I`V%unAkj
z at xl>p99~8$DQSA*PcDFoZ>`0bQEEA$n{xoIJKrl*>U~$Ow}8OnYoU+rX*CoklEFF&
zV5Hmo2?ls$Q4y8K(z>T)&J^|`5XM#8eL&RSS#<228YbJe3W{$5s+lYoa$vO+&?T$K
zJ!>LK6DtCWaJ^+GT+@<4jNSdbO}z(9g6uliKpTlF!@yco at d@HnL!T62ZIZGK`^YP7
z+0Sd{Wa=$WoX<|ivB4X6w>miCfk46ifKfH<H1OIH>XOHx&(AYJQ!w*MkXZL=z!hDX
zkv81VlV&Y^cY~#Lzn3>r2)Jv{f32ALX)Zqs`;;*h&(y**Ur_i!i${mLkf%y74l%DE
zn$F;nQn at z3hDSR@KL4E%i at z6&r$YEFj==s{)rA1WPn=-|(&wmxTK>+S7%;mRrLH@@
z9f!Bek`K1THxHuqpJ66+q at d4Ll05hgbGrE6lWbFAN@<sn+NMc`bm8N5y%XZ^@2+8^
z+5$94l0m^xB&u;jPb%1$u3TVXWh%N0+%2n!1o89SqOKAur{;q%?^e at 4kT_Iqd3R0M
z^Jb8!mjnwYgP`DhGf1tl+b{n>X#!Mk%%PrSU%nLr8!d;{(AO7yrp#jD at i?B at t>9iW
zsePO92Jvlocy4<6YxyK&IsY8KdE6bLVLdw*U72V*3I}p_?7j;KwJonFu<6a@!;PEF
z&V}BP)<%U_V6A6Ht at m6EwG+Q;3GsVLt>~7>e_D(+qrWR59_?NIk<D%>zOhfC+5PWx
zcY|>zuMQ!n)F2(<p{2Ii)am(1k4FwBa7%(&0`JF#s<-4j>}|M$-v*juK#rG$SE*(7
zPHPpgu&DPq)YndDUs}xh8ZLj4^I-laf4%r`dH0gETXO)(L#Q9vN4)w2JiOuAu?X#M
zN~8Lzyah7AJL5>Rh1vx|iR2|I;>3l8<t8A$>K-L+;OwAD&Y=&032)a|3v$^B8rLh>
zfz!yfSQ20WWMIZWoS)v(J_fd%>L`FW&G_k!a-cEt at had=5WG^F<9 at b^WrfX~v@}G3
z^`wYy4+Vb1h2&DyZ5Fh7R5*W0P4;`=-a!onisXx<EL!YbONT5aQ{Z^79`)l>y3njz
z^1<r!)0ZS)$$*1(ge^FI;1|lWp^UQC73SFf6QxhIRYTLw9aO;TDO|>TpFnOevt;db
zdW0<MB%Y4jwym6`zfvZ&ftx!Ka<HtRu+h289&FXqh8ee5H^3pYb=Je0>~yS}`CG{j
zmcrC}+roqiULcwnnsuy1KQlW;UDEJ0mHm$W3ZNPu{9Gd_iky%#V%#L0|J$r8*3UaH
zM7fEG2<AUoei15-Tz4AJUi-K^xuGS2Z0j-;r}4%&Nv(-ne=x0_*7>a?l6BBV=29+!
zRM9G0Z|=oSeev{zo?+NPz!(+F{WII-x?H?8I0f{y{?Y1C`cV*RL4=2d&zuE)DjOpT
z<wu>K1J2iK${?`2P<-<Wy?t6kbI)?{Oiu<C!Q|#MUJ5;X-4)bR-1vVd<N$f*9DYR{
z>}3 at 6WyfY-2RO7wtvQ3xSVrzhrX(ea?(s;}Bvkjxd0DBN+0t(FYSlROey-MOBuLbo
z4_vpSE;8fH at XefOpaCYfyn^`M;Mh~Nquf&c_74u=52+{xCS%8HT=CnFK%>M@`fBf1
zG~K7YRDXT`>mucQ(%L)a*1UdR?zHL19RNe|k_^N`dBa3xQF4n`*KP{fEfpezy$UsF
zv0|$h=1cXioiv(qksFEZD*)o`pd6<$*ZHseJQlaC7YDck-n9q+qH4A-ixKM_EwmSb
zEklYKS&*kM(8Op+aQItyArxd_(oK8dEv%|xSfXDqB``FCZzz`c$*)hY7ScElJ;g8<
zK{PzxmIql?_C2(gH>AI{P^MDs_0vlh!szXSwAqaefX>4U=ju@@d4zz9w#-DQrbU!q
z!(^h0Y8Lg at 1K6c%)^=v+^mYO-{@}kLh;*nFU7M9Bmf_1#)-?<Zwpz2bM$_v<$AJ8v
zr8qX at sr$Ox5z9`>7Iu7L;INenuS;mNd61O0{DNfYA?NRvi2Suwxi!Sj&H86`1<8;)
zn1$ANs#8)Z#t0xh^u6uD^3dD+-NVB6h;gUD#m%n>?ikx==0dl|-rkkDEB~L1-b;@h
zPu4fdGES{brG9G3PX{av9Yg(mZ4oJrA6A;A^$l3PpY*DThis{c=Sa3Ki_HvNn`=Bh
zfD*8paH&M2{Uqn6UznPK?<}$M%|5el^aeWv)YHZh_0aRkXadzWo{uOyN%Zs;4|^y@
z8^=zoEB8&0!Y+gu at p5FAr!sB3jMc<H_>{D9=&dUiLmMxZmBuw%+B_TICIIW^Q^0|A
zjTwN{XkD_?4m1|vgnxbs&}yQ(&Prt66O@$#+qENU7FT<CVLcexg^(v80pLDkmaw@^
zLb&z#M0*{3&aHke*N)IuXJ&)uc(LvP^|gCiT7fV&4+v^uyV}pIJSFr*=f9R_&pBV!
zRuR-o08EVD7SGC}Hnz1*bpgdy>yJe}Rrplj^FJ*B<WlbI8oR?qtPdQBX3B`MmprQ6
z0o>u)(*Ix%AEF6K=RdcGmw~j&v=JwD<0Le7 at 1P@2ufxkXaH`dC$iH%7HQMkKlxx8O
zh_nv0!x(vvFNs@~w;fP4et~y2kV}Whx#v_~LX?z!C)ZzqCG=lk#?;ew4ZhcXM5<x>
z#z-{-h4b&Ne7TO+A8q=Bu$p4_b`pfB?oLnrJlWSg)+f8_g_fzK%(k8Fl)Fi~N=%+)
zpPN?8F;xmPlPv|ircsJAL at J{kRk)r`W4nTS!%u#m40`+BTVIdoghSby{|9h at CWxQQ
zCG928UC;=XB0~!A=`lh|d1ro-e}A^iVyfr>%T5WFr59#D2pluZX$4)WgZDiR-wJ|~
z6^;g+M`)nqKaRG?&9&3dU^35CE-D4W2Ge5{)5_9oltz6H4T)>thFVCH|0-xRf?rpj
zcpF#*^<ogCG>R95x|VUDoRc?}9qU|#bUvpRDJtl>;z*^U<Eg*ze5ogUzn at F~AbdR3
zLSw2lykNSlD3xZi`jHo(4^$mesTgg7KOiNMLVQEvHh=&AJ^AvV54G|n^!)VLSiP~f
z45#tC>g^j94$>kQr|v^2s`g#KYl&H1SQ~evR`ThRhx{QBEtqR3S=ICAt=in)9pDvp
z0SDS^gXRbicaIZI-&mRQ*Y}^@@Lou(rUK+Rgaw&A9?tkhkx8e6_KxC2nk=QY;S6c>
zfX^gXWp+-iO-dDlLjv`g%Ub`yMAvx9!LL~3yO38OFA#$vEg>hnq5Ovalr#82X4- at K
zUzIn8^=3z`8NcYKgY#?T()MGSh!*^|ppoxTvHSM+?h(?T*SuT2r1kE~cDtxX=BP{i
zbMaArxv&fR7_)5b*YF#NE3ICj_r5!P49QgHS{{H>rtYK02YL}XHoxD7??jtF8>1_h
z?LdlquotRLep5u6(R9itlN<(f8`sAu?Pi7n+vkS3g!rZ?fMLGdQ8$v^>Y<*?oWq+~
z*09WG!6R~qku!JrryF~#MmXZJgxe^nQM#$ezh_|EjAH_Hr!H^G2EiKtEcr4Y4O$U4
z4Z0>qar|3ZchY&RN$|(_&>LA$a<rLHic2*e>do)vwuh_bVc|12<`>wGJpr$o%1K>h
zVq;{}sqHX4<!?5%q}cOZu5RQ1Ab%6yS~aa$c at 9@dHDCWkBQd01bu_DD%&>kD78|jp
z0-ce-+V-ODKR;y8+SH#-Z%K6k={McPq)})x1<y90mRS|l*Rl!CksNo%R!!1sUvrQ~
zXO)&g%Xvbpz{(je;3jd!X{-154FdMpLiLIv$AcvS6Q9+MJ4*st9#reC0Nz2!|6t&2
zP}qYFmMsAAEaQj^+92%#E?upwm+X}fh86XJW*sA&ujiUPUu&}@;3xX_R-rd-1G%Db
z8u%$a`%0?oi9>%3dc{`XDRV2-B*OSI4}ipOYR>ALBu|}*e^A*A&SD{W>c}kGW>X9R
zc}i`)9FRlgkXO*jTp&-`8#;8J1*AIAu%t(sU^yuUU!N_>z_!R*ShDqxQWT{@+c!*=
zR&?oG;MR}u2X~dph4k at k3Jbp5bl0ajfv99msm|lnZOQq at -QwX4Zzr#dy<gvCw8zqa
z at IkOcZY>MU+)di|2ItqS<x+lL?Wt7PyW4n{V)k>TQB>u;MV}Y1_QGHn$2=)7A at 6JL
z?c;8%Sa>i4!r2!|*`PcjrXC+9Ogy_AN6;N^JWZ(mMumcuTs<nrZ at bP;Ara$hzI#?x
ze;P-c{dw6LA#RK8iy|UNOtq-AMzEBA*dvgaA+c1jFs9S$)JHYF<BkshqAos<PD0Pl
zI>$qzFc6tb7mSw_zdy at zHhoY!qFo6ViUz&UENf4G{I<&My}|jtCY%ar9nb#VuF7nW
z#VEgJyq{qS1gWIOoICPPiv`$>hUO%RI8B*uOy`#iXsFjmC?xSG;aAv3_UxKGcKD%A
z<+27d%t|P2zF;)>CsJM`6s%(zz~HAzKD73W6&$wq`?N%QryNw~%`1le)!u+b(*ReA
zLwkUJQkWLe)-Q={XT1;Tqb33Oo72Jhul>b?ilw2dai9T<CcH2!Y9=3nmyDd4at;m7
z9|0!?vCToeJiG$L-X at +4fxGW<eZNFoZKNExUkpT*YE8yV`qSm_L2w#Hzweo&&(lER
z-?JYMR_aYFf47pIgv0JpRNO=y_aV1 at lfUKuA|G!w|9YNY%x<{2h8=ItYS8-x)2YiY
z`PMdPdJxb6Bb0OyX~UllvaIhG%?x0zEVzWCc4UuDHVMRX;~4!sKAxTRy2le2qU^1h
zkKUhKJ8%rlM5Oe at P@*uMd>)wGMKMu;qO&beXSrF^u9-9!Wz=c?ti7$w>yHv^i1cwM
z_REV^AAc{iLaAV?T<|>_RysX$-_ZDqkGfM%BQ~8zQeH|aznd~vSas~B at 5A>$>v`|D
zPRz$YPwwdy&a!kBRg5253xBaK%tBc9Px{{7>xr~=rP?CKMkS!#kqx at gROqyPBZGQ%
zbol%625K7~joi>MkH~V2^_(Ljl!iT<P1K>Pzi#kbcZ}L6a!I2fI(#t}8P}9=9yDFm
z5ca}a6WRgW3XHU&r^C;;gMblJR;kQrNl6Jl`F^#7d;t7)Ha-YIBaJ_#`K!NEscn^#
zC``qB$<xs}&BTRtwHQ$R at 8{zWhVq^XpZoa6eq9(_90N(Tz=78H6EL7H^z=0QD76B#
zzvlo8=H<ea%cI)1ti8DljZ!1vN$YkvFIoe^CaXaDdIjJexIox(1}bL^gS=)M{)@yL
z<vgws+|8B`A!HLL)=j7Ztgj3MFs)qv$jj34=gQK0_)d!e at w-JF5VVu>soC4}PS!o}
zSlgb3XS*!L$+qg>kpA!cw0iFq6MlJj#~p3qp9 at HAK1kTP9cJnA75y}jsJ7Th%Lk^#
zZ#Trsl{d0qnqTi4wWWjf>;re>yPb-sZLzMPT)sT$hO$OanL4Y9ZHDgE84G3Yh5hDI
zi-<0Y^^E7?Er=H{Ui3(jCX$ZfUxKveli72?kk6iX8#nANU(B_``6I6+#S1OeL|O)?
zD<Y+)x8)}I+rIx_yt?d-@!m<-Gr-8|&@(#@Va>kStA01bJ$(!SPS5{25d7<OCoP^1
z3HHQ{(zOlRO(TcjU9x~&9FLoCI5nZdZVc7!Gnfq59%XhZ*wz{sk_wT!_iR+rF@!E!
z_02a2vsEiBV&`Wd5x;S7FV^eQ>&G|Gf^tLZ+0KYg%||*pxv<FvGix7G*LVMNqo_&o
z97UL?DZS5=Zps0jn{bqD0GJD+fpYVrSYPRQYa?-m^wE>o`(R8qSf)pjmoE_{W2A)r
zYNB0-M|j06&ke03lMP!#6`f6^^&{I3RLn-P7eM9!y2_7KJoKwM-{bI!Hu4&M&VkqT
zO2{$b%iuhC{-YV!Y|*)gt$ozyU#+t7mJ;Ik>5j=wzfZ*BvyAxbQbtzLnf;f_rch5+
zQC1M2*zM)`d at 2J5fFYhm1g?y-JvJDyU1s}3ti%=j0ojz|uP_GyVF=WPE6#^(JRHmh
z3Yt1Ub)K{S`JrrR7@!=kf#W)~&d|pgfMMi%hd6N>!2t9@<U#C4B9L1dzz(mOgIogu
zu}v~S++=w*Zu6gF<CmPGUFp}Dj?a!9>>2AUXR$U4Y{J0#E%{Kt^91tL<=g+4bx^13
zEj}~06QUNcK<63TOH{)!41oSKUs`SQsS2wm{r)8@=MAMAT~t#5l<AV!<vVdMmCFJN
zyQ_%I>hq%)L-PB1`q`Vj7x}6YoykvN{-MuOtlZKUe*6x~8_SDxp(N1HyVQ%gjQ{?(
zy^&Yi`?!WJvtAw_h|ZZm(PwtX{Ai^{db08EH^S?-x1+qco-ahwe^HC9N$=6rt4MFf
zKdKsU#uvuDk7>o*&-FCxn;Zy;<X8-5dkf3oZly~LvJz-ou=elk?Yx%Go%j#PbsV-I
zAbG^21y?&!N%Q at T!<tthOz- at iZJ4PX3|G1|j;I at ID1@}qqv3rBpRS_5c#cvuV`(GG
z?Y>08Xo0*NmSJA740FvEMY3#@XMQ5sF!To$6xgYqz!m!R**&W(UQK3-d13sd%cSl(
z=l(GF;}YT{)Ct4ur*697sloZNYlk;(bXWb+R(Q6Ync5lr-6N+8QnmL*++|spb{+k`
zU)yQ<GZn8K=q#yjv1|DCqT9tm#NV at jNU<ly#~XjUlLP at i9<JhA&329df>8e15g^?>
zH4k^oFT`mqv?QyZ3B)OjXDBjT9M`Ob%h>_$eLeg5jObAvi#X*_SGmRzAY(`7^5g*F
zpJ%~}Aq9s%@!P9T`vDx66>C{sleH|c(_YQ%O$Pe+ymR18bgToNkNM*_*EW$@fTZ>T
zsx!f7&!FWO>sN*AZ4xDlE*!)casQX~wd=Jqw<_S$8hT^)4;70o9vK<=+ at sYRKlor4
zjBYMfaaL+8n2gbrmPgb$_w-A$yZP4N5Y15%Hs{bin`n&=_ObfnezvP}EJVl}Qk(A%
zgl@=wmJCVK`_Z<`WOQ(neoy7<jg_rG3A=r$@avw4&lNpab1Ucx_GUs#RE)@)Dl^zg
zc08(EjRHO0--OYLO}?~jsicnUc#!Up1`4_<+F=oi^3Zk_2Ss`j{tMm at gR*MbHrk}z
zQIROzUt;RXium?odA<DQ$hZ-yF{}mdMkQ9UPjjj?xkFK=t6hiLs|r|g&n!;I%BqsW
z-Kr7Kz`}9R@$T&6wsh3}-z}}Prg_^xmQ^%2qdiNyzjW9rBh>ZCjUFyc&^xKF at slNb
z%Q$-P1V*~f8XC7bOR7F{1&#Z7Z`m?wCb)BF(z$=-8+0>Wg;)LqBa1T5=g at c3l+t^Y
zN?gN#+!P~P7u5Xr++29D^`@d~)z2EGOCaqG(`t__YWu}nh@;$^<KIlH7k-)|8H at ue
z)K&s}zW4#PaUQ=|kEXMd?DIJQ_5cLR&OBoG<%-x^Z)yl*1Yi;77nYZU8Q~UTV#K>f
zMBnegr(Uxn;V>(DozhTxQdQ;yEhciVC*z}WVNI3mIfSWy$?EV5v&O%SfK7rZzlMbm
z^^N5{e7goDFB81;p|Ql1*eS_=;P#Se0zfwGvWJCx1H0dVu}c870Xe21BD_$us_qx=
ze&!-sn$sV&8I&S^xLW|?8tbf(H*x>qD%4v>mJbfHH%5m3N3{NleJMJ>ATTE^T5dg@
zM^L<@_Ma3)#<~00LLqqYYUTJ+PXS#!p3L%}X|1#<US-~3eT41V*^t)|=@Lt5xIA%q
zEq7>IWR##*$W)0DMBRh5(5CQSb}90yTR5Ki)&fpI&U^SDgwHpC>K9;p*L)s%`6kU6
zMLTp2UFc`U284xX$ba&<xp#(X^ged+%q(z-b=%g-Y<GKg#{~FqaCZOO_3o97L6V$e
z28E$-33$0v*wv9a)gaGa&Z`=Z2NV!Z8R~G2zik0!so|M*Gp2=leQbiVv($Ib7IeDw
z>!02=G@)d6X}>Ad!X2|8hL!EgmlNBea7_tAN`ndwF$<Q@&dA}|_>%3&*-~0+YJU)$
zp-cPrCI}xlX$iF&9sZad={YK~?BRnnmOzxe at b+2T1O~J-3*Q==tvvtM48=@wbHIbk
z6wRv=z5}exGZ*o<*WmZ3P;Uz-Ex26jwNj?>1J-Z%mlD~D6FY<Bhe(fa4o@^Rr4i5c
zDrO`6pq-tslyk+LF?*K3ZsRuZX<53Lj90n3`^7SRbNmIIs3?Zdj*b4``n8w$fXfG6
zDDwuVAv>Ix4zPT60~z7Lvu~BH?30!zZAVt+_}c8kq=mDP5!fcBN3ikb&RXsrt<X*&
z^~-DbdfIX?qsKSBi}ZeZt<3W(&iw};rqr75to$2Kurb;4PyHC~GxgYO^m%@AuhpvG
z+i#9*C}!0z4$=etO}0#dg;bbMnJ1JndUdckxspdny4$u9$u*afltguGo7BR{o at zPr
z=fE2jnx4RD#L->yF}X9!=U at j=a^8AAzkd6&i2)i!Tq%`RRrnn~3#uo3Qdw^^FSOu4
zXB#q2XRZYXf7AZ&yRt>ri$vXjfQJX4Xs^KLl;>%d=(0NwTDCru2n{P;5fKdB-kvEL
zgSWDmyj6yiGn2j(vFDwA3yKVk6{r#`TMLTxD^No`%<9;t-STdAyfY%0X$~+wE&~tk
zTJas8Jw&EHe6FiYZuXxr<IgF~&2MyHsc|9KdYV+gJdrXaj;#r>C?7&hgdA{x*bno5
zF8$3t(D8WT{+%~&tVPE7j at vzf<>8D~v~?so-Hi!FJ!=t=#UY-&L>R97sXT}(D4KB~
zPn at bZIi`QOYI-TzCXOX=Z$H+m%o>Hqs~r1E at p<wp?bw2P#^Qy<<z)@1c67 at +Ol;R^
z#21g^zF>yq*saaamitBN)qR*xL-m|J$L2l&!m9w2!2tGEcHF(5Ca76-zss at AY(KA#
zK5&1;i4D<ZoCHZdJ$p*(%!N5U>VN~?@>@&5e`)t;KNlHBc6LI-O7(&z{FRz_beb~F
zE0+XY;v%fOfFB?ltDLF~-cV?-GHZ1$(mO!A(|19M02BC6eLzkSi}>wdr>4>0M|N#^
z8L({CY;r(#{`xu*2-Cs+YPugV=zI=@=9*5Z0HpK#8KWJZ&+$O9t at zwe6G;#3NDqAy
zKzuerasX8QvUl at y%lI)3gc^1p2{_G{Re&l%Mq0{{Go146e%@$ly7Tf^%$8l8nvP4g
z#@!5?@3$aFzoHu{^%oY1nswO6qs)~wkIirQ#0eQIylrkpHhiJ{fKdj7&gKx8m at KX?
zqG4-9=4b|No+|YV_<iN;=hj-3W!~KBr!&RX$LT$3kh|Kpw{{&izoES6V|-NDh5hB1
z9{&3`G$PSx4{KP#N{+{%itA?k95klOtQ_1%BZO9GMbdJKcv!E1y-N#Y81$C|a|a#%
z#<NIa9?~v0sY?}m!XAgbq`;v?nhs4Dz4|@)yDyTLW53aZrIg-`?s-Jp-}Vw2x2`<Q
ztKpljAJnLmy&5qFGgnOX_5zc28-qGXB9<i8e!lARm97Idk1s=E(78K%7hA&_)heFH
zzOnURA8+H_3O4dggtsrxM6n9NR^rZ`*m#i%0m=8Dm6-)RyzGo=dbdg%7;Crc$I9+-
zZLcYAlD-+3;)|bz at k}OEBcn`B5`@D&(xopqi`z4yHyvCDe>ZrHpq(plPUm*wDp0w9
zzBpGvSTPHx6$mk0DvZ}!lA(aUav>A*c(P=53u^$x;$3vGEuNVDL#v1(Q-}s7zpz(F
zGnw at mK?WP|?prMt4%weP39;3CWK*5D3GlD_C*FC*j*HWC!sFjqK#l>rUdSJ<Myqqy
z6HfS>umqXbL*SLvi0rj|z~-)#wj4wJ0>C`;PPmEpuPC?ivFrT(E1tDb^poPKAH;9<
zp>EJbER#NcA(!7qY%<)yy~o?0Cs?nE at mFVGTKgY;)<>-A_&l^@<NnH59m`Q|#(gp(
zm{EK$RlvIAopG$wX`6^wRl?R8)A{MBo8IL>#ly9gqtz(XpC0Bf{4N1*ISzXQt6eu^
z>JwHk;-j9}y3!b?(70CtM!58uH6yRuo+bW3i7W2 at Tgr=PqK3aFKK#bFHMkpe+w$KR
zc3G<(?9z at j%ddAWH^vMeQ6*^y5Of!L9Pj3gS?PJPKT<c#@@3~>rP_?qn+8Bxly|C+
zfw+Ut%t>$lnum*DI|k9?J&#vkPO5nLtCm at 6S9z|iEE3z8zc;n3*1zE8aCNF>fbwL)
z;{1?JR1LlJF3%;j&Q_gaR16Xp<#|lyo{S#_Q&T;pn&V|W-}eqCuQt at 2i>X+gpQCoH
zu4J?WJlV7B_B;$<_$UxIHP>hJ;HnBmPsm#N<ue#z%BEv5?cKYQ6kl4cvw##pfMC6g
zww%$RH{kdh+=*wOet265m-jpx<oaUzC(MN}>|5J=fO)jl06gH2vtL)kI{-dRwS~88
zH?W5MZR|hw&KeP~5)nic-Dwlzs-cA;fmG!&mn(?ihreyD+j at D4gMg3Ucb?>tZIk&@
zG|ehmj_s>p4+lIIXY>xxcx^1`i~|*I?9&(N+~de<!FrV?;}96V at ZO0imxw^E(a^@+
z%0ZO_w<w^)pn=RhS_Qlc!$SG`IHx_ryj+9-Vxy<Bg}I~DbroiUKc(oWiJ=*dM+;N#
zK?z$AqGH*j!_<e;ofGlXyBp}mSCD%BhtH!+&-yq_j&r5DX at lsavwqYh+ut&rlS#>j
za?{4>tdkzxXubc#H+#1#?0a;&c76v)_NOeDyfirs_d88gEUe)}J at ubd)9ZaqBRZPG
zM at F9>ibd}0o~5NyR#3w>nnuH@>`QOj{T;&1#O2R6t|8QL7surwuR2q1ejW^50qh?+
zTQXVonoYk4HRg+N$Hx_Ft9L!mnpBH^N{=qbKeY-oWedJV12sbnZIfDr{1DW8_0sB-
zd=xRYYw&9yb%X at zQdO<Q8XpOW1p at Q<YbJlrheFfHO|gc;`qhRKEQ<=ry(W;e>PzmR
zQgLEzf18Pu$98$3eDco$p$I&M^?I$1#vFev60B6^V$0?^`IKvql4f
kbi{8Dx<
z4x#hdz&oBQ1E~Ri^CuoWpE?%ottC4DsqpHgT*R5VyFQXFK}Ei`EzerOGFoY=9&Q3m
zZtR(k&jD8ArRILdG{?@@%6K2wtukkCR}V7=W6gR37WhR+m+YJIoC3Bv;V+G)X=6hb
zdu}30Xk^FaPZEc87AJiAdevJZu#uEPlw0}@%>$U3G(#aW;GYv^h(mW|tGvZF3j>DT
z+|nYO8fxU?A2jsoCetQVTXzu0o<2L$d$bEg?b2~<usD64jd`sq95)aJ$d?@#fC725
zivra)omn~6x7~3y=2dGCFxzLWE=-5zAMZ?+a~i*r{h^Y&KUKf_1ZAItKK=Uwfw(+_
zuZNh}raRZyxWT6I!5&$`jN#IwoJ%fB&)UJ!`Wl5pk=MHiQY%Gfn$T>Re?mCozcoz)
z3MuS86`G^7mpfIak<v3J3_Ze)3`XzfnZ&-H4XfB+o4>ZO#e%I0bvdY~Z;M at 72EKp|
z7vuZm)6$$8txNN{ZWD*CO0h-EQM^Gy!KvDnpkhd<<t at rijLDWKrdS@&lk3GXx1`SR
zIr*hiT!@x*NphgVe3cBlzn(YfSwI_#JY9lT9TaHjEpzJ6t{lxv(ju5M_B~wqd6o(b
zt+d)SXIbm|YB0s<SNLRWfpkj_QO1f?oeEBPQr74nu)FS4T1H_DS`;t8=le`@ks$VQ
zf|(+{8h34t=#ZUNVVw+?sa<1L|Im8Tx%4yj5rX^=IVHbiEuErn)ikgC56~5tr&cYm
z^e)6p_%AB`H<QArM|V}-Q!%2*cS<RG*856q at 04e&g^1s;N3n2UgG-`0ORPWS(Ef72
z>&fuAx<%Ln=^6-_>E8N>iN9_55Ar at eK+}pBo%~dxGi5W6-#3f{h*M^d>F03*W;hR7
z$LrP;DG6dv`gm^}F0TS%J(<8R!J at Kis>I{Zw8`{^2z&h4DIn<*M;fodfx>y&Ys7~Y
zz9>zylh-fRFSy+TD7c1#?yzx}N8x}%{_nn~pXOO&A5HSDxIwUY;_Qel9Cq@>>gT-$
z{N#tVZfaD3{Vt7 at m~ELEX*r=qP>m}tD<o(0&Q^xrm3<HOohGl_rymX2O$>A~6xO7U
zQdeHjk(D&vY59c$B{ipfHTqYeO5ei~r!a;X{?AWJcpC}~&P;f^A>Gr5i%j3fe}{;)
zJ+u at RS(JavR=4x6=$D?aL**2Fu`?duK5J!MXJYbFzQ_BH=K+H-DtxGDi92<+a(`;A
zl_O2cq6pn-3rzSfW}Y34+ej0w?^x at lc7>e<nK{m07?mwhta4rAGn{#<EIC5w!a86r
zN1Yn<y>;V94~ar?(Oz!}nzX1YSip7SuLMI-pnlHM;ltms{H(To%FeS8%o<c}PZ&N_
z`R at gte|#nCvY5FWZ4qf&$mnU}%*FJ!sYo6bY%41c0^4RQ5jR>saHso{celEYO<boo
z{!6PN>=Ev-wPQOOcYmIyhuqxZx*5u~ZB_ at nV@&KAH~+TX`2p$Gzl7USO>;z`iEx0w
zO8X;p|99=<XQBQW_u6^@wFl|ZyM+I={y<``W~Lat5o9}dG><S2x5G98t at X_PxxTzl
zz#gI0!tw-|EKiGvoJk>cQNd<K03TZQ{MXdKM&Jru%N}+Cu5G|+)KrCG#$Cpz^D+Tf
zR1r`NW!ht{Ox(8s)1A$b;0d7CqXqbV-+yew-YWk&0~;7%{QP2Bf`|G5G1mCKY5+d5
zOI72jq0o?D-S0W5PxnczjC$O94Fi?e#V;DE{Os=TPLB`?#)dqX_RX?xcy=6toU at NE
zyqytKbVJIFd7b0s%9>rqTzh_oWduOOPs>H0bEY#95DSc}a6-p at ZJQs3`qPugY8|RR
zYnjTXt_!I$O*VV>JqtWU-g!x)O^!?|6=b>Dlg@<fBa8Jfm4vZokVMlQ%rW(SxUlEt
zdGA;rv(J0hp1|p3gcO|`AUzN%>#eHI#A`GQ7#SI!M<OT0$Wftfyr8&&Y0iVe$iZp!
z^KT_1 at 6(25%4Ea##C#v&WGNsHZJqsm62ai>4+^&Bw<)v<*~+il=|7?eV<J|4N<&7P
z5R2<6N at TYQ0iOHHt`c0dw?%{v?liG6=BET5rm3|yH)s4)u1!sX-ODG%v{_i~)n7I*
z5?X4!+_pv-Vba(Crv->OKb~9m={hIfQuiEBn>id}50jVe<&|>Fy?kQPzZ_AkQxC_?
z|0XPA<0|8SUar1 at NFPEc)PuD-58ys$H-w&)bE!rznfXDdB>9)QFt~5od|&vr1;0RQ
zrvWe@@gd-%-g at l@dVJaZRUZ-VUw<C%_sRXFa<AXn@^`gVIKWp^OuRlAu9(se3|O2R
z=UO~C;ea^m48L%&;NUZoe2YGX$eX*=L(|*O`|NW+FTM at lnd-j+Tu&DpiAZyRzDCk%
zDI>31Pi-WwU#eer$DLhD-uQnson=^)f85296p$H&gyRn?Agv$>j0uP!jl}5gZbl4{
zP!SM8QaVSCj?vxSqd`h~bk}q9JlFFE-f(T##qRy$e9!ruUqbs>s1Kmc=b7j5^bAzy
zt~fX<)moPX5_>P(5{so&S7mrxs-3j`7J7ot)}V1heBZX5jn|{JZtDUnQ5*h-uQE3*
zf!<VhyjQ<o at 97&`R8wH6T5n>2rdQrqk0=~)<@W{*p6}>lp(dz`g+b5*K}vN=-4kyH
zSE91~PY7kNbA;oaID82(Bid=lBpnhmv_{Il<}hn6`^U7b38DX{7G%kfmJW~(D0n6_
zrE at Rz&H7M at Rg)Fgs`15J>ANmC;^sT0o~URhSDu=FIR$k1S^$YC>y)}ypMS-leBym4
zUtZ(cjp(BAWGl0tUYT36k(Rr%X1q at 5t}g=8pm(hRwZLywuu{_6zn$HV1)nLOc(jXX
zdqlDGmyREtN{{c?5COYq?A>4WB4%8Lf&00SdTPE~qqS;AfEItD4HqdYDPMfX<d(pI
z)PG=d$jNC7v8&DM-~E-N5tdw!s^;5)=6{hKF at -YV@gm?nRj%bcVz%4?gBEg8^cPqt
zq6W at 6-D&lJA)|h+zEwiKf(Zrjnpml)uFtFGn8D<PuBmOhGEW~)#n0B<UY#FC8 at 7p-
zI29L=l23MgJAvOdP+;|MFD95aE;~hT90e8W0l>ymZUora=6C{>MZv*t36q36=$WY<
zv}%ggTx}??`p%u$QHR)cQE?RHRkwN%I;_P;_ElKX=giO;ekfflCEiSioRpNO+wVrf
zfW5aOEC%4F4})g-N(C~@?aikL(iTajr5rnBx%CV4aMhZvcDE0w2Hyke(m(lJdr#bK
z08{8m;S9p2-8y9-h&wTc0dPM7w%@E`Is47Pd`#48xA2XBG}~Gy;KDHiFc&#Z?xa`;
z>W#pM{}ql2 at JH<?J~H0;v7uM?-$d|?L*V4ZAAqNH0Vr4<MsFM at O8IdStUyyxoZKHK
z(r3I*fWhJvc$ZV)v=qYW?HDLY1vH&B0x`GLl0kEg9)VZb;!jg1b|s&*w--UC&P$+3
zu(|Y9&*GnN?FsC0aSydRikRHQ{F_ at sB1)c8*8?jacCOaV?SJPMY^>2v2ETu4UzSZ>
zM9bSY`r(+RHvOE(M+MYG6$q@@6V39-B!pIQRLBe)B5<pqjedKeL>(Mj>-qqTlo#Yi
z3%yi+400X|$ze_}Q|A8ra^+YJOr653sc<kj=?YT*Zvv_VqfC!%b(%$KQoxUR9+<Yu
zYgrRnr|UK`gxD@;jQIN1_Dg?$pC#AtJN><Zi4PDLxU()i8EW6Vg+k<nyM%@{W$h3+
zC*}hmMhN=Md{PV%eJ%|uc2y>xM7o?4<KHKU6^g!?3ZB3;1@#!v&6=$Jn4_L)(t#Rd
z*VK%{uR9sj(+B6fVCpkyxSC^$QI_{k#GiX_cQW0=3eA^GIf|{jTwmc;o*6F0{`;?D
z?&(iDB4Lek=6S8hd)i=E+nTISdWgZK_`LN^(d|W1 at 2Rcr&sCezi<3HDh=Maanricx
zx#CE~hbgD-hw|ibdqix<S5QC{a$b-nWIL{k at AXjCipiGwEf;yAjh1u#iI<Fm2UTe5
zP+JT2N(yVX<KLY9FAM{lvH(Rk>mW at C0hiQ5(4Nczr#fyEb6`Z_#B=YjbQ*xQmWl$h
znl$r14*%jpZ=Se3Va?N?bvxnVhOg&TEZhPy<!IB=ug3t})@fr;=h6nvO~qmj<uEH5
zsXt at Eh9BjZS?a#7cZ+ at s!o?b>0DUih&T<O%*|L3~oPr=iUBfi0u3o~w$qN|=(@uhR
zp*{ek7<;<#r7<3F>ZT6J0p+k^b28${ZnYHwe{~@fw5<iz000&=C at T-lc1u5Ahor@E
zTIN2s57_#%qICk3-5z3mYC<<|>s9fVb8>W7Kae^gJ7khDYcmnT)POV#wDXv&&DQ$L
zb#J>|rDB9f#6OB>jQ(}SA<ESh!SW2W(Q+_Xkv9Jo#h>de_;?+%+xlRBW0JoGy at 9%L
z;dQ#_oNy-3A-rzltfSr|jZYlI+lx*(asjW?8du2AD7#h?wkRO^n^-qCQtNrTS<d5}
zkTU%`_5{yd^U5Ng=Nj&6-YXUR!eC0AbXlY_3=z-tG$$WW!=K(V8cEMg-Lm-l9maf5
zo?P`I;q5TC4B`H!huOi{%$(e!#Hw%et21iBzrKftjdafddaU|DW6Vycv!T6LSCNR=
zsuxTDNM~%n18O?>J at pf-R6*a&i_f?%GKHZ<;B?ll{QQ<4Ehbu~J-NRSO~itdx+D_a
zk#(}NW9}Um|MbDo7)>|tFtzT}T(<j?Q8YxVZ#aTbqh_|&kS|%|+!IH++~w$DQ>%n$
zw*W+zruuywxF!x%CH)+I3Q$LlyJd=|CQZ{b5?!Sms#>R9aNQjP*SwM2Ng)&WegQ)Z
zy32w8gau^)x5myC&}ubgvRqKr`i8+ZcQ!dUS9M|(2nkMj7NkN101Sb04Und=vUvXQ
zd>1iWQ{2N$Ulxcw9j8C)5o1aPA~|ZC5zkS73#^WSCSYk5&U6_YOrHp<VxIe_d=9}3
z?oxgNWNwz^$1id#4 at hn1{4&@~?R8Dae<~Z_hqx~@>*q<YfSU>|(u?RD+&BH8)>goE
z!*;s#UHjJjmtLLnG0xGIj|+AdDH*FD*kOdlHH at 5lDAt7()QsNe%G`0u_4-zV9B`dK
zHPW#cLq^4eR``kC_8m=3RwIC3b;|sdupBpTwv!9*OXxeq1a=U}?BI)l8FJ|YX>T_z
zz2Ul}pfKLo5acy5nGH^xceYdfh6yb_mbLQKfK at J3v-1?4pyHy|Bb-WGI4 at VdQxfl2
zGFQSw**pGoz0ry+TrmBK;tJ@|Mn62!N${N(*sRTko?wn<`+C^;8$5C}rz_VC5tVw^
zwPD>xp}GWKxF47QC<J30wXpn;Eh){E4Z5GqIn}Xzu{SV at NG|c}Ai6gV9FJkbR5)6K
zn_hT`XdUAd at c4tyW`BR4$b(470PAUUCX1&QHDPL;`!v(~#znnfZVprK&I0Vx$%v-&
z=gi}_0!7y)%#?bUCfdxr9Tt9NO+ITyzrKe6#R;9juEVvJnyE~rPvw^QOb#ev_lyB*
zE^Bp0mq5$6p1W{c5DDL#`0Z?1j^DIDgq+B at JhkdqR`MV~`#X92)GhIWywJ?xR`J7L
zwxBJigYHGp-1N4X at FECo5i13ZN5blPGofVwV}1L at Ezmx6P;CyxDK2k%N^7%bRBpb6
zLePXM0Gp)o_KwZ52uYb*(qtNG9XZ(oY$V>mTd3-?@fy27fa3)in{ZU;l^r+VUw`^)
zOn_@|w^3bf*3TqPEs(3MgTTG4o*q-0T=RMIs%97anQ`rP9k7 at 2NK85*Y(GO2#{)0T
z5$_{?IWK3|JREw<CvBLthdRon8Eqc8z1THiKdi!sC;Ypcl}uMqrOOib4s0XJTU;^C
zSd{k*{YIbqE~S%a73DBQy`fi+(!XsL)~};3ZrnUQ5FNDH=IpW<6V4k^AqkHMKc+QS
z*?PFfzFUpv{j2AB?^oM5chWWg8(~eiz&rr3vu3X^wu;<<GfQKk%-|O9y3PaFJj9oZ
z)tv{S-HgJIPWp%_PN7(^d6`Xt{Ydp?!L@#=9FOw}Qdn462h?y(A!Ty^?-p~`PbE#v
zO&zcH2}ld33 at V1Ehi1d~v^#}3rVz-W7HZRl3Q9Ki=*_;J^J2y?yB>ed_Z#?gK=wyB
zRQmixpFEOBm`;_=Ka$l=SsR8$jl{I~E_}JYe!`9~c|z{7YwWl7z|7P%`iD at EB~+((
z(mPD+c(nK((#7=$kLA$DV6tz){+r1{2^8PXnyRM`;$kPI-KROXdk))u!x_p~o>w7L
z?DO at y*8H~_t=2-JzRR1mYbY3hvth1=kBaMNC-ITnA9v1y$@RutPWtXB_N0p6dbx@~
z!(EKyXx_f3z*}c({;4t^F><#t{x2!@H=*q)K&JYInKEkqj4OKyvpI63QfIG|@p at YM
z7Uxf*?ZmRjoJ at o{;1V%y$&~9k`wq$P%9%WGYyxZ7o~S`e4ICTLv%rR_Y_{sXWjI>g
z0i-cnt18+KfCg!2qst`_5jK8^4Kfe8NVz>vVF$>B#cePnz`nM(8wTZ#$)x(Rtu7ed
zXBt5z`apRzOuJdhlh>DlPJ<@gPUOO+@(4}m<~xm>1rp(TD)SG27-3-zk7(BuE!|K@
zFW+sH#ToNuw3a9i+kYx$7E|T$AH1X*4zzni|1b?PU_yTL^D7tR at 9S;3w4Ozqnlixw
z^Mz*5Q8{#;NyN69i_ at WxzT{L-bb_}eMQ!$ps)k|2>h$60fXgqIBz!DFC9r_<7^4XO
zjow!rk$3F|T_;o&a2fE>o$#O8ohIF7#zypap*FY4gr9u?K<J&NVsp?{tZWxW^-G3J
z%kz|hf`ZIqn%6O2y at ao1{zd(ku8K@&{<`}f+oH;dQA$vd82NV^`9DWdtULIY58Y^3
zmVL9pc#zFY#cOx9N_^JR+S~KNFId1Mq?d1Q3i99W_);`{j6x;8(PDv;yV~kpH>eRR
z@;CACgPM{v8`PemW4{2ffV=z0)1YI~;?Q3H?3p3XVc6DT^@Ya1#(}D3<wAwbJkF8H
zyC-Z|qRXE(yW`7{n5GKI-=(*%ahGw}ZQ(<$xkgCQOZrU?%LQB1H#J$po|-iws1Bar
zPIJ2mQ;B~XQ0FXtFO%e+W8fyCW1zPTXbAngt}5e+i(_XKI$Dx54038)W!w{|RRbB^
zq{!9<d~S=MmjPiix%Sd^*YKpb=R-8YHL319#7m?dToVAVxxP==Jqt)0%&L6&pHFHh
zh4M?2<J+}@nt?M=Q_NBLgPd{nrS)#hqz`Z;qX**3)bsRn$2EXVku+E9-b%6r*zWDu
zDh?F(+jai6fg!g^@<&D%W(9<hbrdGL_6Jn;U75-#=PAE$vP+4=^8%KtfGLyqL>(-y
z%7|gLe7!E+*!T=&5w?*?Co0*$=!4kb>`PiUC>}Z)bIJ&yA``IE+6gFD{D)sIlsku~
zWBywU27mPzgc9=ZdOyK6Az_Q>LPUk$9Af^wFoi3}E^%`2emaNiDMN80SHebf7FqhW
zu}qlNM&5Sc?rYJl%@-l&ktUHB)BVZil@;mZ3bXSx3E#*>dx~t_v3+<`CU^w~BYIR*
zfE&1qo^7K<q*LZAo^d at rg8Zjo#Si<{>_QLhXgx%pBTAN&U+`UrUI^1<($(CP#*boT
z!a}5CAv at FWQQQmWq!!~)6nE^O{XHe->{%q<16!+k$U at _UtHRLe7A!cOYhh5348G+>
z_)y(eYK at BJ5mhGXvz<4&<r>o2TUh)kg^0?MM3k~Sp-_R&>43J%bi!xPLc9Oeam`l6
z<IuYmWDB5oc1z2L6Ms4exnD&}J at N&N^fDUdF+jz$gGgm;Q~hc+J9aP0wLwD~lsyQX
zp4Q)b%#rRema)Cf|Mwuf{X&fpK$eb55&s1|j^iZ&hb0IDRM`Xbeq-w!fLmyy_P}gc
z%kgKGINxW-PlzP>KQlyD$A#WwNwVco<NtyXY6q#%tR8VdBLAt9Jvj%>+%5!K#ha4t
zbt~r^y|Zr;KlbmHWwAqx028$4g~FL$>S$1NM1}GX&#${>cjT^8JfvVxu;=7`JI*yN
zE%-3zw~dHOuhPTi7&+5>eOWt*l6{*~lukOYbQJa{>*Uf<!M`zlC?SUAM?iuCM>Kzs
zaWGhJOoBOsn>X9+=I!n$gD*zOW6_(XFZPO1vrovtd0wAD_jULTah6Sp at +m}5+`XCS
zijC>z8KOOiKbmj|=bX$Xaj!rt7v)p8o<+`A@=*JgOQ-f%GNTdt*a?v190XHs74Tng
zlSM0PHJ3L_CwAI~?diTpLcWK9?GB{a$;K5Zf3Fpn?l_Sna<sgi5`0>~Ji)6UiH}mk
zy#WDV{Fx at K(8fnQ1VPm4jyIa9x#HE9P2|DS%KTy`J%6Yb(VV7{Kd$+}k>|-xzReiD
zDqc9VEm(_PEG at HnMFM4P>;DN|t#B&bd6w(9aPySfHGC5%nz(667U{3%p5HJNwOef-
zQ7o_+XL4LrXfa?O at oa<UFJ$<0syLP^@Xo}LYm-~E?%RBw(Ox5+Bc2$I7TQyPzV#I{
zEz9_q1_f{f7h?Ya;Pscn0EdY=sl${Q=o1R0oCJQ1GZ~AKB}yJ`*O)9;i~}W`t1Zsv
zC2oihvx^p>ow(@fWK7~OfG>A)XNA7w!xbcI<VGGv){T`EWF|UFP2CtNnr4D|cCHJa
z%vass2G!222o$}rY^CmgPT&hvGo3Wj*|$E&iHKP_j|QtR2#|d^XuD)<F$}`5NeOe_
zG=Z6#+SvnBnhASrSYFPU0ECy_A*h0*q1*uFVI7jw4)%TzoaL+>1KsBjE%yyXvKPy%
z#ADh|4il1SLdkSBxMJ$>!`eHPFxe6cc0`THK>?sxD>7j`FV0q8q-<b5UiAcLgb^cO
z+WZ$ZC9`FLRPm|zdXJ*vqu3eBj7Y$v<~o6fFr^4V!i0tmxdr<?;b&n74d8#<yoGuV
zfsPYFN9{1`XCq at NInf>76IUQ1ozwHfHBx=IMqbfjk{}YR0q$-BIF1hTxoN8Hf at fp4
z)zHaTV!6N+<e{LKJ^}SZDC#Zz&4WEptuBHI+18~1UMppG{uJi%PP;(s^dkx;3xZwd
z-^v|cA~H}}XV`ORA}r<<bGH7P4dddI8}+mn4#NWAOQ$utM6jee0Sd5H9XI)T-MTu#
zx&8l(gf5p8R=aA6Flp8%UvPFwpqD?3aI$YvI+bWyKkYsKTQQRqPPL5K|6EC1b@)-A
zIr16VPUeGYv3bNgL}k3^`CRhGD^99g$@-kYDB at JrM-!<MK}_xg&cDn`sW<1#{5P~l
zXVQ2LqP^z^?<^LSzpb{b1jj+gMQ1Bh8 at n^r(L8KB0RFVNNyE~9BL2{+9gOHqTIP$H
ze&hI%!fjTFT(L(Ucxbc$`-al{MG&-wExh!2`+V6W{W0>*G#~FQ8bO0CHb`@6SjIo}
zaKiSspd{ER=dAW-pSL4`5+miAIO<h(+EE7u$4|9P+}zyiH*afW0o0m$Rja!$NyA!v
z$-!M|z!Kn$Y|{!Z?Y at zAS^b&;*eT<cjL&4`Cb(r-0bz;Yc|Gpd!}5LK_Wcnp?^E^e
zpG4XyW5P4gM-mcks0#O&hn<Y9Yb5ANq)QTge01eK8kDGzzcr4 at YWssx(C|OT*)#g$
z=u%!KCHc0siof;|jO|&v1#0DeYVsfOK?7~~eQZXjXtWrLwO=5+NK)x66HG;wh589k
zpBZt0Et;%|N}n09m+NKJd5eW54iK87!jz#W9%}kXHq5o|qfLW&>8Zj`sXK|1+A|}M
zpT($^4wHO8$cHga9qvr?dQ9JFx97`fv8XSquykQcafbgC2Rla^k{6B`3Xid8F|Jl9
zm*%l~FvxoR-t~^aL(fzpaz%b7b1C2BT$*f-fj=iZ_(&er at sD;SK*Cq!h5ExizXiCD
z at XO5)b_5f69$sgzFE~__D6VxvX6R<jQNh^PrOPOhkfhh<N<y{e*k1;lFNc);0!DwD
z1lqX{#^k+A)pKAybCQBl=E;ol$5G{Uzj^nMWTl{qq!d3qdbiS|)Xg@%*4dFb9&BvR
z5GBhU`f-RUb`HM|%t`tHU~indX^l3RFCSqgisHzcAnFXQz~bb^lH|yNEgpJ>4bRKF
zNURd~UGt_^2a at YwO82adL}nMORVsw<Rd)|Wtht^ALo!ETp{l{D3n+KsYb5b*uzC?R
zX!{1xD9_xMK()g>R>2UhKOPUUdp4Zdoc*g)hrlh(qPGMA3eNL|?ZCrwYUossD1F3;
z-E#&|Q66zj{sR&d3DO)pQ$P%)T`;Bfw;2YW9Ox4;rB_E0&!!~!lGVX6bwOgKV=wij
zHWS{Z8x>~t4fC>FlvRC at hLYW0jeYgZ!(x{JHNBX&)f&Uj8aUY|{^- at K6Fv26XN@^K
zUr7_%hw(O>sWooq6^iqyfG{qrqLL9b+M=Ll=6XMz at ->%Z*`~(eeafh-8>emUg5jfX
zn&e>0oVO|i8<<)KiGFu;o}PQItwk5F%*!{$3OAU(*_oku*(wBi$AZsr|NPozo=*~a
zTt#zsYIkyuOGQ?k+3!Mc8F(S;p8HLE)aehH-_3p!T!L#uS#$FQw02 at JwAHp^9u)9i
znvaV2GX!O*j%ue^BimA3X3Raegu2kyp6F)8C;z)hjOI10)PTju4jP{pACHJn|IvS6
z9`v=_WJ54MM2LNqTFAlZ6Ouw!tm>^vWbmk=Rpt6v(kq<Y4b<3!l%f{gWAowH8nm(@
zf!c~PWeIP!d|y at MNup^bFx+hlm1C^1ntY!b8d&{M97p6lAkN^e@)auEv at F+9@ZO)^
z1`LT_l^u`Cr6yVjzL18)qdB$C2He1f-bJm)rs<6DmE=pRGAO1ad(^$-GRxx1wO{jh
z^8|@3f|eDGcY&s>yCBc!@Mc^a$H1g6!1J0cH>=c>1js}FOrNkBv>ga6X9KIll3aX}
zeZ9enpglla;6m;v35^=zEiVF(jWenp+ at U>46`4<t-HXG73_L$gF0!gb5Is$y3H-FW
z!OZ~kblGv{_R+7we#Z+{duL-kwUiX&V=0K7bUC{LXvA)Jwlb|bHP%eJjgmC!*Z_BW
z<va(PmmR2bg45+Nk$LZ%tMlldFgg#R!@Ic$>;qBa3|X;L$*xMglGV&~oBt(2T;A6%
z%Ow1j?pBkO#sK**IL$%Q8Pd51sb=8?I+}hlzt%b?ol7HlC4SoGz{r3>f}V$Il_VLP
zwIv+0beDv^TRNXptRhj?yHIY+1Baa5 at PZ}3lXF&=U;T!A1T3t!pi|att((e`dQwT0
zNevvZafaOy#T%DaF9!3l3GZlLm9a0yv%Ra+I at NwUz!g`8GO>Uys2u^*HMo*k+4Gg=
zHJcujw}_nHZjrcPz<u<i4PziL&gpAIZ?JElQg&^|XkcxPKqtRIeHCOuF4ueA-to4V
z>hzxahwR{?wi8^PiVy}<p+`;snKn7M=ILx$`HPc at yIGKw7IYL^WJFBoAP`UQxK#(2
zmYttBwZ?<2R?KnB+}J863VVG0=5`7)VE_2Gb&e<6e4H)e$)|}Y=h~H*KDFi-4M{m(
zJBd}DI*QEC{lRO at S?(3P*Q>Gmh4ZIIGZYc?0T4;Y(x%eWdh=J<^~AxGK;B<v1drSj
z<r3P#+UnY)*di($q<8hLH+M1}GBp^o{V4d285m&xc$Zhaz-rw4K!O3rBgLGU35Qdl
zO`;<hqE`IG?QMf>+`=?9cG5%VHiFIM!e(p#fPU66-Sh)XRf?^zwaaCz>+W>?&<}e3
zB~Zu};yph(M-!FXWD;y-J~KB9t-M`n-v*|_wWc(T?G;q%x70q<m at WHJ{%3mF_y6|5
zM1y_X%hMinNiA`(CzyGr1>xaQ&CvsGy1u2FXKT7ZYM8P<^$GbB7{=XYB_SAy5Jf}k
z%~1cTozIs0m)a&*9IQ|jLM<csUzaqu)f-e#sf})%bR%^{RVAkxt40~F^zt~{m0rN1
zYF>2f-fEFJNiPfUdEPUja}5l6o8si5*dz76bM#(Xxw-DJx7ww1J^$OdQYS{y&qy-^
z<%_t3FQhuaBYiiK at mXaw@y|Dqe0SiF<eDXI8`(pvpD0kidu7{gClkG#Kc?lkzzYup
zm_poPw++5R#i;7&w+zie(YMfrizk}LXgZ{W at 4tMtY^u5kzu5lWmm_*c6m<tZJv};d
zaSgYAtvNI*rn<r8y215OpGJq(WyeZ-%lVdzDsE^ZNIQjdS6j5ARWU%>{E42P9#@o7
z2ov*PB>kAzL|$&;SVq#FdDHjLAuIA?yjiFF3(+6ssB6_^HFOGJdlXOi(tEi)Y5AZ_
zHkR{jqp4K71Th$gPeApvTUqLDyz`vuRT at QthmaI!!Qf|e6$sr(Pd4#7TMm0v#b2}E
zT^i-r4x2*)io?)VSJLmH!=BppL~d^_)kP&|7v~)%v0ovc{SCLk>T-qI?ZF>bC}eQm
zl at Iv_+|u4V22!Y#e<1bev*z&CD`kb+U-qRrx5G9y%gm2~#MYD|-W8u0zu4qW&V-_Q
ze$r*WKtz at JU}bD<toj^HEsfSa3;cP7nnOT~Bp(<$D-+*q1<R^Vc&jS|6Jlp%k2L$=
zveUZ35{D|cX>3mE7yx$!htziz0L!F3P+9CzM+A)g>f_^bhcn_d9==@@aEU9j$w^&!
zpvh1ds+B$MZ?`6pf0Or$@6oIw7lhFNHR?TC-(@m^c&!NdLzz*{w_V>{?lwP*TF52M
z+>EXU%gzaiH{~P2kpgv76s=M;GkXl-Siiwpq1 at Y3y#gHoyU}=1%L-2YC)dEc_G`9@
z&2-z_!=l;)pO!uq+?5~pH85<j&%lDOYjK4Zvm+EO!k4N=JY`tU013BI7k^AV4!5yQ
zIf?Qe=kkp|0&!AN3mqEH(f_{}KrW}XCJJZyyI5CikDF?I$iDcdcrD`688%Rpb^1)z
z#94$a{AcMf4bjBX{3+m_qLlwctls{b at I4$yTY83($1!9sz=xoL{mX**)XLDyzI#UG
zv&<wr<u3ZF_40XfGDZi<_TBS^Whye!6afQAi9()*mSX>s)1*V^c6W$Sg?tau)<v`l
zgN|$cuLjr~Jbcx=v+)KB22jNn*LF{g8D&Ln88al}dp at bh4Pg87{;GX|ibP%O;_}@C
zks5j0!2Z>krO685vznT_|Kh~v@~|K~rtYC8-#agK0 at Ja_FaKbEPJCENX$R|$c5p(S
zx62bXSg@=FKY+yzAK-J`Wg!>eyPXVkNl93LhsaC-2P4rRNqdx<q5D`C$3VFk=A1v1
zmO$U6P8N7bR7LsH3hu{5P3|uKVurBOUTMxMT`A8F4 at 9<JV;{rhk~*!oIWsoivM)eQ
z$(ImSt#PVf1{e4&^*O3!%yf#!MPmbn9jXJD`+iV9g at QKO>=4tN5z#B)N3OIdLzO~W
zf~u5$!cj6%XGc~R_V$$(x+VXKfHt+{hzj~}{|Xq-ib4vAhdq8y6qg9NXVY;}Gv&)?
z<#$!bSwDbLhCtaDQU<Llg`?k5(C+!p45f)y63adOt{WhoTK at 8$mHfYaW!cb!b9d2k
z?o2l00a}5HMX~bqX3KD$@a1?HJbO-&yOJdX6#Sq7hC*q@=cxwEbNrZeoEnrai_$A@
zRsHffwC+Oi0-t(Mv7<!!DvH!KNz)?dUCWIR at IEHyPcrveg&1JHSZVgM`A*PcfnxQx
z+H!$pyh}}(qHgC16VwHhH!)W$>FK#lt&;Su_(Cw%t2al5%fr%Q1kiO<e~#*>fzNwf
zCO#KQX5k)peE0(2ns^=;lo!#*?56gR-E&zu5$OL3O7t#f-<hWDV^`8q_pA*AJ++>;
zK<d6`Dd?s7#QFiwiU48XSN>uv&|8KLj`+6&Gm(K8*D6u0g~Q8i_3hw+=4}MgG#oT3
z287$GF7eL+e}5(I;YniQ&w at A8EBRHeACIW88qu}7Jg`y1GgBE=wZ?zLBlAakB>~gC
z at +7}6Ma#CAK$gGS!CE>RD*zNoCG8qW%fDYwv>exRBLf0xC3gin#u)<a&y+cAV?Q36
zks`57A-H*&1sSUlC&H{j!1N>;;)<1=-s+aB+fL3i1Pq<q^9tp)8J1b&k=`31BX(sK
z at 8M%@`Xjc8k*{O>R2BuW)7FO~Iu+jt80t6j=2hFpQtb_fq7;3x|Mv8te^I%1)<fc>
z@^+_fp``<o{ReOH59sB+Y$Ab@%)!{f-{=zG@{_U<hhHrj#MAWo#8Yxi;20_n5}BDK
zno1aqJi6)u$xI@>lk$4v)@vN%WTdgHidHE3Tfybm1{c7x3M+7`>h~z^aTXF5dJT^#
z%5P2=EhhW}2j?e~`tDG>r_ypjDIVw?KMh}4&}3PthZWBS5M_Ys)xgN6io;UtsrZ at N
zve0^l8os(gea62)_`is4dcKjOqT3G3a97H*<i6`bvFDccsU{|M2=9~33Z|#Gw|8|A
zQ=`5iJGBR5&}NFIWmt2c;Aaa6{&<|~q%T;sd}?EF(;zuzV;SK89sXZtv&W-^%nDg8
zJbp;bh-i|0j`Bi;#fE#qW)H6jO(zN0o%B{Nxa`Q};07NcZ_O0Fh;4XwbLr!ws&Cr0
zg;U73zLN0t5_}OYgN8D`ezH!j?uGV=X(uMXZ0`!T?$UacI)2!0uKqjux;mYlxvv%M
z`b2-klF_QM%>6kwT+g)yjO at 6p7HC5_b_zj9Ds<JCeqA8S*8#%M6!qY=VKLO2^ba&J
z^H#&Q=*y(gU-<byU05{xDhe#hjkSnvH4$gv1dw?XJxzjHDkH_mhJKxGc3W2F&ZLGc
zvn5-~p$;|xME+E<omXL-V2W-aLCEcl3Twe4v-%n0iX8{^OUEhPbR&s&FtRFs9k8ub
z!>iOM-I at Ar3~2dU`AcAQFhv{I9URTiF_Bx0N<}p6si+1G at Bc)+G#mVsH@{NQTodOL
z)-d9ms^m=)mR>w38pF0oi+%7AgWwe`32mFQYx63gGNZ3tUVWywo{2=HfMw>=Y+UPS
zJN at 4^*F~#q7vlcOTih0;oAqXi+#^5R_L!8J+e->e;PD?Zi$X?|R2}c6p|>94VB^^z
zZ$8S`<$*XrzaHsQzlwCTm6!(#?3of=+?od1`hj-))#?27-rU09(Fe(F_0$hg7-iac
z%I2PT>Xg0rmSNG)bP8=;ke;z^HVo=ov;Jvwk3&!E^vTDr>-W12HN?)1zV`q%+NxF_
z<2UV63*Akfd2rBLZ5YbE%IJ6dJrVoBHB1zkWkP371fRcSy&V|WfQAY-pya1Db1>8F
zrxW<9aBTklU2iu%+qbz%hH!l^HUF;m=b<>zzv}C+L0XOlBQg0nn#5FJ^6r~X%xY#c
zO+o)w+QY-O at wI33kbXy>AUsKn&fbFd&;QswL3wWMH5vIyf24VeHC)cvQhh^ks*lv1
zu%u4qI-aY7{l=S+aqJW|a||3`9~cJ?8Ly)2&O~MzllL_-f^+@}44!WffIM1!w(c;G
z7+~VB-;0{Oi?xw at lDZ|DDRA)D1j?>ax>+!Lwt(R#PmM8e+;%T%2DlWafqkf&htwY~
zrRJcqJ<-r)cYRW%ybs{SJuzeRO=T^(Lztws2=ka0&M#DM`Rjnc=<_9TAn)Ax3UIox
z^LoR53PPvHkjWItYb>6F)XXCLy$G at 9ZFxmdz0~Y$++eniF;_1uVzVT(U+<~UZ$Tz%
zlA{KELuHFQ1jsq{`qzo%IXwwtTQSeFn9ZE*Y`JR$pd5t!E_3tWU6fco|IYe~>mZ7j
zf2uQM0%oxOyQma<oS02xbIZoE&1DQGd1|aTzYW-b)~b*H<p+>3tY%Mepmk2K6U95B
zZBZb5Wp5tKEt}YAr-%QYN;5rx2}KCOxCv at Qwp6!ia+geuSdo%!0nvN)D$Po)zeg0|
zbJ~N)32)9Fewhr~6Ne6V26SJ$=S9g3A3+p}^U86}4Y%1ee-{QgnG*|(QmB=b+UroA
zRjSwqy6V0%e=PiG+ebisN%(8PhBE8+h>h-4yIWFi)@m(edALG*@1L(TQ8db6MJsCQ
z?;v|vp?aueb{QSpE8;%cEdl9~&2FbW?2PLS at 3hAXhu+#thy#~;Ls0CcsKZJ{Ek7Us
zT!V{VD#5)F`H=)P{amfG>s)Vv%Tu?U*R0s}JwVc990x8}cFA}nz=b at L#!@0<X_9ka
zZcpclo2qbjFly-+<wsQ~U{YU8p2VcwmP2m|n?Ld at N;^7r=nVeU3g-I>c+MKL>jQZW
zffuN6RhZkS8qG|<{F(VllOyk7G6Jwzrl_zQ7AndMC-F6Y1BfpQRm+H|#R4XCwa~bB
za31NM;0^e`>sbJH at Rl1Ks9?~?^vpY3#=_ at g)`1wBQ;+VL-Anc^Lg%L`VpSx3a8LB)
zvn6NWev+W^R;Mi8D->bwbEJWv?+O5N*z|N;C!Iw;I=d#J{qvZ6-Q%@@cBwVoPyJgL
z16D_Tl^1zXfD4Hec^4)sMJ&zh)+kG(9Jsr4MeRGrP<fbkxr^)9)YKEv{e5 at Zq<ztt
z-9AbCHw49|^UxbL#L~+B&P{hBS_G5Ofkj5YSkUiB3ni=?mJJSr=Z;s3_e~nr?-vJe
z$i=o3i~XReXO35s)q?5kJfgrXe+q{wf^U5gLr|nhutDF~Jj!m*#2g9>n at 4TsEhZHe
z9p6ANYq?1$cZ8-Y-UQ{9q!WF6PIAnV^Y;@ng7ZTnraUMzsR*!Z^e%2QI0echD>S5c
z_s|SA- at OW-vSYMa5{&759Yv?C!%J6al!S5_>X<`8T$etCQAnMs+^q*$gU)|DtQUMX
z^Nm9Bpxl)#+ll38={4rC^6h-VJsYRRW6$~O6sRoW73Y(R;vt%Vn#9v7z$!ga``vqh
z(@B+WE<K^DH3j(mINYn|Lm)1nVyl&A-{hqe2LPfTr*Q~FrOS#+a|a@~QfAF97$V2a
zSw;O{Y?H;u>1*|{mOOnf*3U}|!-RvgOTP?-S^v-qYA3Q`9YEPPuMiku*`QJoLIFna
z=)-q{`J#UNO(rt4X}Af9nSY{yn)HYiz=wP??FCN&1zTPxJdr??Qrk$9DSx$_!bFur
zW?bBP5^gxB?8C2wvaANmIyQzyo-eXBab|lg9&*>S<>TzMN4qtAYrr!~&<`?138)R6
zENnGNO~uWkDF4%S>*dAT1ksIc4f&Rq{x~3x#(*7m!i#r@@MZWI<g3&KReV$*S at D#a
z^AEjXC}jIg$szpOx=Kyr(Y;}<Xwc?Niz`{JkIpFC*|o?H={eXgbGYsep$2m$_Z8SW
z;~A|HO?ymU#&DI_kN?fu4HI{P390Cz+XHuA;6*Ia^`rm{TPRE5wzPC!{&VWmvW%Vt
z-`RS&)~NC;B;EMik+?iKb#HB9V$tO=wD7G>ZQa4Jyt44mpV<TNSbvUya{tN~R;G4d
z=T7v4NG)x8u4KH60~~- at QIKrM<9i0)&)z<sgJ_r*QA)3IpXBeH>>2=sgSrds1)*lB
z?m?qb>lH_$>vXLxWh05a+FWI$yuw@={44X&@E<)Hc_`1eq)b_vEJwlT;b>4a;uovP
zEN%;C#Mh*sm%Vl~F`~Q1K#g2BcND(hWfuM6z3ZItVf5#D;UB!JBLUV%fQ5&zjBj9y
zl?_{5+lW8xzlvELAZ@?5-2^Ndk8XjuBzxWn24jio;#xTok3I^9sFv)++kMKQ80ZP6
z%g}vDWfKgc2nY6}SN+?2o{oXwK&8_p2_TPe`JOd(Ga+YJ-SHFIpf~dpXaar8nz~R1
z{tmEb^kxB9;j7fqm5Oh{@J|%2IYc^B4+d(j1O5ul&}vN-IO}Q8$gX2-!Pv8%$_2f}
zUjv1^dcaK8BQcvl<4S#16Z$t3`Dcpc!?iuTJYapOc!ga3c&+hwyLoX)DU^p at eah++
zlYHze4jLzmLIX1feFn~^okyO!@vHYeLtSGlY;(D#W-1C4dVbR<S#(cZc9k9S&U|(H
zxvEW)BS(lfD2S)~NrvlBig#;9ycun<C)}-<obzgcL$&);_P_mkB;huoD$*A|`3RvV
z>>Bvb^*#n(6{re!;-g`oYb%T%#E^U^Oak%G43E)CbWgh)#J}o-#!{tTOkn(j0*vml
z*#Gjr6_vR+geiAgoI%kEx!!cNm5$x7eV}`&OHM0w=kD0V(HNO$JQ>Iuv+u!`lOGW7
z+d3R+&4?0|HzydI37lWXWJ;R&V at L48%F)WE5eB%*toD&t?dnXI_R{OxniT8tXCNHx
z%}GA=;Z+~p-y6O&AJeECDM8AU^bIu`fSADceLr{O23*Ha*_<JGg~Z;Rk_gqp%8^Q$
ze}%!&fm(B<(L1clAd{spd#UPmPg&#J1waaczS=bYfE>}RO}#{f#IuQzxoJp|yCt^i
zwE at XCDh^84+}%GDKw01R`|W(|wku#7rfog)d1|NKio703fdtl8wVpRt0{PobU?VuN
zX#*EV0^$7yAP75IqrtOxx!bsK7an(Yk%bl%jRQElU6+%8sz+z^*kV$k+tvotMUyrs
zo>J-9Syk)CYC944hCCGr2uPW~OiCb6pmG}%R%8F#PE-E~I0QdKvnblc6>OkPvNn0a
zHa3WHHKinDdA9tHGX$Z~xS*D_(+k)}$GwY&&!+5<a-Wg&A}qRYOvtdPWlF3J>Qaqq
z7?LR at 5#B*-fXgCax6}{$$1|RJy%l^kxxu9udjN8oxly6a?{J9 at ci|VUcm>N_X`uaa
z8g at u~z(=;%qxjBGpuiHv*(05dDTl?4rr8`UH7g4m+{$Sh-b)IIq*sLt=Pv>6G5xtb
zx$|3W#ZFGP`u5irTpMCL&cFFzHO`wj&uUt#GoPzvAs2JYN3G-{@ytIyaE~4<un0`m
z6^n$gJvhND at 5z~n&8^!RupSF*GRY~;lv#>jmm;=2)xvQ+uy$1IRFEM at M&gw<6_+-$
zIM~h(OR3+K5tUt{-gJ=UL?yRdM?OULu<eq`+4S4>!;pRVu1Ac~S(M%zb-#l0T00>k
zB-GkNucz{^Y%SG~KOH23$+EMYkuGE}F=6d%wiBa&##gRBuJX|w#3c)1>K{>QYuc
zNL9Y=PmCc at 2R><CLdQ?uL2 at 7D%D4BD90INXeT7iu0ok6!W1C^w&+PrOK?eIHz-;2i
zZwZvE0Yp!YKA6t~W2i&G(<QX5{$lm|hT<Obk+r>2N5`qdrwKbTgvjn!hyuYW at ZglS
zLqBtHB4?<r+;omBNeFEoawp$V&KeFco5)=Njt<{}6LH7DlEN3{w`ZLqSfBOOuvr5p
z)6N-K$Spum$m3Dx{!TCqTEOz&;V at 5u_Ig>2&U`^&pkIctaX;VMjdt8LfglW-$T|5T
zcIkBrA+L;|_iA9l5A30BKrbD4vDFeENrz5R0s(ika(GkoGHr|IDoy(!nMLs#z}1Ao
zq<N+MV#JfsYzdQ-Nx3-wg+(>E6Js(2AWOMpXX;c(dA7{dtJV2lwuk=#V1~~b0Q6<o
zj>%`DCM5-TI8UIk(L1JredkHJ&`W}JPObU}`LA}*6~Pj%l?7jPe-b^B_fa)1J<P6-
zZAGkx at 7}1Y&+ty2QvH>Zo<gvOb|U8aifS%^PyywhO^|&OneW9Evl{6p+p1I``Rpz&
zl4+Y)5~ci1>|8s#QI4?EC+grRUiQ=Uv_o=RTHkORev?{OG&-iClJ6Rr%;=d}<jY`C
zIW96p=W_vw at 8nw+5#?2^EHemw_3pOWuUa11JSbcM{-()D)0`d<F|Yk+?q(WeNkSqO
zd`LdAFJA_G_;%=H-g6WffyH1&3eN8uv^OlMw9&hj3KTBI+QravzJ|jNL5SZC)&piT
zkqrcMeu3JHoHLEqF)o1nOR4akc|W|L*GZU|SWs4LcF`Fg{$=C_tg4sqk|LY**lqjz
zf!nLIC2t$WpNvb}6Z50RkunkTV^l0cy~P4RW$l`9oI_+dP+jfCAG717)~_&|cCiEm
zH#96-3NE5|t><V69=#QG{Z;G!`J4VkSB?h|G)nNS_yIBD+PRSo0E&|YUT}JU_Ikg$
zqQM?oP-`yI2pBNJr8BC;8R;B9g-Sgow{8MT3XcVWw42nf?e7&UGqb=M-)6$mJh_*#
z3a&viD?*n_9wIZ^fcHO^u^VVU+`-<FqwZ at z7IJ*|^e2n6+rhUI*_CHM$K!3$oL2Hb
zw}mvjb!z42vx(|SRl@?kJ1u|cfUKJT;ZEYFid76^Hh<JCJDI7+jmer8*s#0f5(N&f
z&`(gHuFk<Nc<=@mzpsfJp at TZ&wWsmCe0$n_06(ejSyzu;Puv{g at WU>1L!Nm?5q21^
zBGLh>Bc}%Mvh~hoC>L+X%Pm}1<2||bbpDBcJ_O4xpz!PWhDkb?*A!?@48FIY*m9dX
ze)Gp}Zub!WAL&>4fX*P+kd;ox#Hx-ZscoSwepBZ+jE&&YgR_CfjZ)yhwuh$9E-O`S
zy7x}3kb)YOlbv?CzX=_3gM#YRv@|a=o+Q9ER24_Ed&Jzy_x<oDf+ at bvp`u0lHBK9*
z&!;LTgUH(+sMhESSIrQ+1B0E*JIsHtj}AxChY8RM5NuK>PIN&kTOVtWo|+v3glKic
z{=#CjUuvO9j>;jYJgF3uyrc at vgGP{F5{QPPR>bl(tf|bxFt%e#!8=d#p{p$rlf5 at r
z1|u%_{{X1NT1iXO4y_J>s{Q`VWQKre<5eMXR>?WAqdAzaxm!1wO<dTxyq?BapB_Jn
zD$&OHNy`Ji*Y*>;(<m4D(@>YRb|KScg5%_7U=1AX6hRG_R*CmMiqw(M1}<TwkF*oo
zW0K<b_3om3%~0TY-7abw(s8fEWsS}IQ(hPL8Ks-*lS|H7M{7)#OklRr_o`MX%q(Ki
z*}CR~K*swJUOo~Zrv5sspn^GCF-tphUtux=8N<@_N<1|J5_2>B-z*zVXq5s50ftxg
zW at 1hTEqMzTL_*y?57o`JeL2ob+IO2(S4sQ%j?;1|9AO_5&vW5*Z)@461^&xeNg);I
z9Uvf?!P0+pb%#A}k9(jU1;4OK&?e^9uxv9^e!aJtb$r2YStB|HKgP^<%XY~uNGC~5
zN6!&M*@YfHPaRqr8t89hLVu^yfE=+^SXpa1)Z!Tt1w1K_?;i)(GuuZySKLn(TaI`S
z)lqX*=PB<I=%8D*BAa$qx93?rEJHT9m%7=QXSB|#4JSR$`IyIRfL%cMD}pU*aj?Aw
zrv#>cwSQ&5J at tmljjcZ1-Bo|=29 at O=KC-hOr8Zs6D|;uiC7WHkTwG!Be0PyWLiYFf
z$lQNV_L-#A0(MpkbI{(|o9Pmu=oqgB+57k!$?RBrOGa8su7A=>dG~*;Y36DV=(6IJ
zTJvZ|&@TJzc*Qx3^3mF?8Cp*dD(@={lFF0pObaZi61fk`^s~u-d`nFAi0;J=3DyBV
zB#?Fx?KIwF2e}1AL1u%H$H2ThmO58tWZ+q?C>2ps=j$nl!hIn6I;(cvKWRJMGO0Uj
z7}%iP1>BzGKL7!<folF|{yO9+mB21RwGhPt6mY)&0KmaX(}8Capy8>O6jq7L{3Ukl
zVkl(*^y<kJ){mK00nXbU57&5}4n{2ljR>MWb^iQ^<!%7<ktZf|I_6*YpI%^k?{2-;
z-FSPwJ7Hy}{2``#7f*F9{F0?AddUFU#J|RGWJ&>a|EM+Uh((gITA=eXJzXDFj=NIk
zVm8Tt_OPmVx4+E1d90?GKbg|kr=v=HNt3#Hu*I7f(@;9Zr#hms1Jp-XMHp6GEMM;a
zb3TOMq(uOw3v^97WBz!x_ymQ^jnhl~1{Xi;lhtaVZvnpK+4G4SFRSW-Bvx%?SJUU7
zB(Y3FJ=9kh9A%PF at jr#8^&E*ow5#a|RS;Gv06htIDy%c|`x at QTlN-~>2`zsTP5<$-
zQ_Tl8OOFF8xBqXqMlKwzMpd5h*4;M#%S9bQ+1%hk7#Lgd@)D;dZ$!Q at 6DRJcRERT~
z4Blii>iKVJrKHKZ|6s<Yys)Bts^9rHoKsYPHSU+9^j4dduhp(~T87*h$%gat52j%~
zJk2E#?B_b3D- at 5=;4t6Ld5-$GEwR+nigdP_Ce-)hf^_xSv~Hik^h+J at h2w+`;n2Se
z&6e^CJ6Xqlb|dQHwr((>huuXN>pic{4t$c;<L1lsj~Ha_*`(^fL4+Z)X%*z`(3`Ii
zHjI&x-WJhms&$2Pz|Nxzb~vfq*({L8XDAx2lgI`3E~KvgYXa&cAJz`wn#F&o1qyQ2
zSDFp%HiMZ*krA;@GhA*!@D at F*S*>OFL%xT;c-;V~FaT)^Ed8Qt+%B$3(Y~5RB#8bR
zL{%B at 8=ao(%_?PJ02`R_(nyXftd!g^p+G!v^%s0n^WDb90Ea_ at G<NW5-|2I<>~);|
zyr&TS9&$U^0sexcNSSBJqF+^uK%BDIPi%;VZH8qS9hWu6=Xlk|TQn)2mJ at v+`-S^B
zG`?m7ij%j#cwN*|T8NROrqp!sL#dX)i-{)r6KMY(-yizickkl*vRkFKr!dhgaFdP2
zuBnvQoIq28d##qjXQ;9*_&3bwG?kJVCYcyl+VanD)x1mg*g<D}<E7V7TRPr!9xi2$
z)^&u>5Z_K}s>}BtKhjrGe~-&5vm^tRS36}i+ldk%=ESF2>suP5lE6A#m6P}mgLQ<Z
z{#v)*Tk3n<|5X#M-&|$dV7xVs88`5bDV;U+d`;9lsvso4h)vm at a9urCJEkv40Dc0&
zl;IMf@}Sn%5#0SUo580_FY4Q$`)zS<oQ{0mDpGUX$y4=szwNvUdjZRFyiu*T<3W|C
zC2b at v!Z8FV$tC_bckQUp4JAxDOt_LEO#o5qo8x8wOX*o9WZ6Y&js|dm$ZPb_y*vaI
zy|V$O?YLJHH-Iq91FR?`S)6*FRJ-#>+PMbZB*h&OcO*NpG$S(7SX?9WXx%`Z>MC(9
zC*yL$Uxnv at eP|{h3d}=o=Cc8Z;7f_2>r5F<)+Ng47R at 8+lfYrR9p5T5AM95p4j*?2
z%wS|Ls5KiLjr=74NdUOcjU>4Vvz}lZlL!C=Rb7PHiT~SBmvBr#n at pYR%d*DJLDI3S
zMDPGCpmeU`>0Mt6U$G73GehI~j~>Qdt)5Vqro!M4e2 at 96FgXfCylewhomWr1EJ+{0
zwIAT~xkRdLx5T3If2*;+TyB7Dt#srSh1fb1z4b1<)I|n>`?UAgTaM?Wj+}L?S#5RI
z3Sl at J-&ntVLh at 0*#eW6o%~w60nhc`*QCf=W3As{4t<qVk5f5H2G;Za-{8AY#t>(@j
zl8&m3CJTs%U5)xxrA*CVoHpKi-^FWD!HL)w<saMgN8wsClfmfdg?=9Q#zOLXYT91>
znU0W)M(UZd!6G;R3A+PJTvlq7rLO#RCX>4crfck_#5ZUt3$opP5Hy?|VG2<{Ca05f
zrSDoA#QbRYCp)^>&TO(>5GpS^s&`gnenfAQ6kziV6PUG$2nk at euW{U}Fj`Y#VB$>Q
zGCIXV==vQl6{WT3#uN*;E`1g<D4mwm-qwvEKV{4u&fPc>rX4Yo- at Xro7l7-~0y&>l
z)-)BwXMr3&)7QUQ1VGt9N%zt|CaNRlrXJ>aenlyBPLF+*0YH4l#+QC6w?R8OWP%}t
zJ;3NwNQSd~-Ju0o3;}DPs%5Y7N=?<)|9b&?wx8`MQ?bW<CIjMP=q!Q;VCHn`q?QjL
z^L}t)1!%Ydn?0CvGM>sUM+Z3nILw75S5N+X|K%a}vyB<Tp}mAw3=kcef9uXFnGSdg
z0-hZxY9zidlpOo0(c at -gVHq;(dbQvApIhVAL9c1QE)%a>dS6fcD$H9-f?F)uCERS)
zHV{r_JWfs)aG|R$wewR$cT-MQx3VCs#;<aCC$F6Rg{?Ww(tBe{^n6)jCo{X+b2S*c
z*8m57ts at SdnL;b;rqcVqC%t#WMvh)BNYxI~spwB-Kg;vVARhH`8~pg%k}^-act<fH
zPd6jd#okmz-ezS`U19XZN4rbeY5SGH%j&_(){-=%z at qwOxIoe{E2qpOE3qaVrX)-2
zZPhoZk!T-YbVemJmBBVX?Rx&pE!V|bDue0alF{Y9uLh;58E?l6igd-zx9~+SAw+5g
zH<iYp&8<z93v?=^Mhhb;Kau+%BqHB<3}Jdjr{f$m+yAST7*XFYKUY9TR1KnD35Gup
ze=RAHkXd7DS at RwRhvL7ZJrhh&p^eY#tNiyYnhqVz1{QaHxhw&TpAMyRs4apv>hyLn
z_*D~UJ2NsrdM_Ty3n70Wrrau*Z^dQ(ZJ~a%dTF-TvOy+%f$spIj6FWqgh}N81$34i
zsUR0^zcOCyqza+MU+^LYbD-avl2gp|^y78J$s9=u at cdjV15?MTID-T0XQy>JB%8!;
zQi{8MA-j`*p37!*M=xlSR1#wVt8q1318W2DDkG^$ya$4=@)KTYG{gHaS~L)u`BPUV
zzRx6~@*UDf5o~@%1K1 at jmz6`Tfu0;sNnqk+fxYT6 at 8D3+mARcgsV!)(QPeJ>s-pX7
zrzHPO;UpYB9A}tNFLbpbIV#X4S|4ZzFX~I?tb at h&pw!zxL{l{`JT)^tQeB0R3D3B`
z-a~*#l7QQbCy|hj9O;l+q|0JO|EsxfG}3F6Q}QVq_U+5{mj2U?ZIFZZYKfJN_FP*<
znQ#r0Y{uSRIotZB64e-=jvYEM#2Pcu-d)~bVaubkOB2}2mmZDa(w_ at R8<-)S>>qHE
zL`K`Nzg3p6`yv*{fH^fT9TkMIUtnVioy_&|;jWeMs*Bm``8WxbnzEk<19T~KI2umf
z6^ZueC*UOKhML03;*Dc&UasbTAmDw9nu<^D<g*p#`F<a(_3=q&oQ;fx<+}zVbKPQs
z`vpTDVFQ#E&v(w#oQ9Hvbh`(bw4}#6bMSgP{6X#7Ki7Z$Zbe<^E5D$cIKn?HgJY%2
z9wqM9ZODa-R}@abY*;*BydDb4!9$1GXE06KQs!@wE7^yaK5WC?YAL*2bgm4!gw854
z5)4|iRvZUd1{ON|@`3YH!pf-fDk<Hh!cI at ic^<j_ycmr$rL2 at g+ZSvA67HsD;$MIO
zHRkd^G at W%+lmGk1K?D>8RHRfeK7cS<LfA+#VDw<4TNvGJ0 at 5OqqA=<1jqVO9snOja
z(woxF at 9}%i?+?%62!nIj!}Hwl>%OknHDTU}Z8#z>(L(64g(v)4AOq)DVi7AhfXU{(
z!wP8>Cclkp0}eI#K!P_ddf(8#89|{xyL9|XQJ-8%@47&s+>}{Z7~@pLK?iG-{DYeZ
z!DV^cE1oN(R%XkGn*Oa9z|>PAuS>q5ofA(MKjtE~_#LOO{r-jd7%%u0kKvE>{{-CV
z>du?tk2}A_rXm^juyJAf(kYm5DW}Rp99*WSMNEUq4yjf!P4Gqd|5_uK9J0l}w~y}b
zU08F})VJ4<(xRvcoMMY|5rxC1-JwUfxjbb-YC4|j40q||Cq80~Q{~B2;l%5j36WDd
z^W|b2R at F+ki(HG2%7~SqoxKARoQF-|uxwJOV0}}91%}%8%%{cTERFRZkEPG|a{Xip
z-RG4D$fK7g<yV!@t18pmvtj9o%R?i8uW6GVvXh5AmD!H3|Fm_}f?<gCZ}di%NH&yX
zf_Fe3FW<8D9rj<`q-$++v#&*+t*F-99mI!fMuul!?}KF5rNxBkW%GWo%CJ2*Dkjk-
zFX^a<kBHRctaDB9su+gj!j2A6Y947d(t>-NbNUwHly?8PEdP|P-ty;vMJ!o_lTVzF
zCmr08sE1nP>_zv+>XHTWUEky=Vvr?5uSP~dD3%A%%);8VQ8;B(b__v6&3$M<$E^8i
zk!2FUHokA%%F3WTB}|X5Im!;<Q4;v<YDtu;$$UM^x!1u8>gI3ayR+Tbr4L{=ZMJlM
z?@|XW)AozQ7kCM`m9$=~o~#0&!56eN2f%>aVJFHF&OPc(aa5AbrpxNZ1{{@zHFBrq
z`uTxt2Q?Q8Ih>vO`us$YZE}hSSSg&c5xD;AS~L1ePOiDho&RiN^4{gZ6h1kBMw5!D
zpe?l&X}G`<fATN-*&8&vuMEWI`|zp?7tTWy`7?fSroYk4uZ&|br8G$I)BTMfOd{*u
zwfc{7{?ip*kW|w!k1$JrCBk}{s+2t9qT)58MNHaVt|plwUmyCZ3bql(bgToUGCE1M
z*VJ>kGE^IF?60MIUdE6$Zp}U!iDxW#qx^d2Lvy$iE1(l!6E8c(@u$T~yDu~~Fp6d$
zGO23#DplLRtGn=WJfZ4ZISt^heLo!iO150yQ2GPqtbP5AziX2zshht}ozCi%6mRDh
zlT+e3jkw!)tJnTeHT_oWY_+Jz6Q}QPAeSu07NL0Ro@)H|>5ZR9L}6Qo513Rtr0jgD
zVyMfq{({%Q&L4tqoq&NOYvj at N^*<2hhxdyoU$U-748U#~^rDPW1NaTap>_2}zkc>n
zLiNA|KA5D{y+XB}$_=$c&U!$jt2{%j4zq#Pz1K>=DJQ?;Wc|3%ZKhkA<0?CE>OiCY
zN4tgBjA$cqGS$|S%R3uEgF4-&+K%VpFF~8#`I9AX^A|Roo{-Y<sYC8U4=NzN6d4MT
zx(iV+-qh#3#jp}eH0^?0ulrsqqQU_=g#Huo&L at A}iSG~@xc)bxCUckooMv`*^%|>}
zjd~;T_8}hatW;|?%{vXfgC_u53jF<O7GJF6_LP?KghyIy!>4o~*cIrModJg_)fn4}
zii+aq00{4JKf3!zhT{1j8|SXyX~0VIq0%6i`%%*?<<R)M7gVe3nR|e;*>o8HmxE8i
zdRL1Zez0FZDLI=3&wH==XXHv^eM1H at EagNlg@KQwTcMuiYdsrN($bYCDz6M4uf9mI
zK0CLQ&}+?q5i#X^LPS6dPaW^Pf3F*4eK2zbiMRAO;z(z;+%e at 493!m>{-fntAWigk
zvsy?Ox2Aa(8apP_uK at Y1{e_wb;&4A7IG2K5OMD;6I^sqh%z2Wl)YTGBrIM<fv^sIu
zv*0tkcG;Zbe>QJhOUz-yi?AUWQ#n5(7K%biX|e7tItgF}Me6)Z^Rz?*Q?(Q)+>wNH
zpOuWX1&JV3(u7fUhV;NqI$7&X7)kbu0+0)^5uC8exm%6klv1w#BFPR9)~FiU+HNqx
zofTQH*sLhiAtk0V-zu6{2^%??l)badU$TU(2Dl(iL4k&}@8z5>LOy5 at cgGwSbLX>?
zT;a2RcxUR(DSn&3-dZ#rf-AnSZQTP(<NI56J8i%IUSE$4q<ulS<A-VVciKYz7B0eV
z*GY0Tq1#(ClmMJV<o3HEO0%V@^bK(Srag8PNb45hhq@#58|Y>{Zie}H0NI!9cPO#U
zzw@>i<uz@@JJpqB+hAZgUCQ><X30DV1#6gKlD`iD7v1xMWVO_MAW!v-pzhLO==7Ey
zP-fO^0*Gy1*1^6+MF}FRC=Bw>_q{#pZn76Dd3tJ7^6aannD+kZT`idzS=iBzp&u6M
z_2d~mm-aRytjS)-`YmF2JM#THXd|!oi_K#%LBxR#Gm>0Zac<Zr3;%xdCq&vK_1LUX
zWM?2(((?6mq}<83;e^Achoc8)u{6cdx>WkSnET?F`4~TY#%M~OF4&HqXh|baYUMSW
z<Wwv2;a~Q|H*3G3!V}5`pNu$HaXO<Wg at JV!SD-*$Q&c9 at _PN4(ZAqK`mhtK{f1}!2
zia)0}CixxI=g*98YiA5?8qw=oJK*URZ`!@Jvz={K3-pK>0^n;vhZJ1f-0Nqp_)+4P
z$v_%b3<0LzhCEVV_zr)%Lvh at Arc3`8_l at l7nQF9tqe<3E&EfTNA2jLEawT~V>@j%V
zD|AGZpFxYIi~O=E7*(bA^m%S*M%#L3$~yUPWfdCA<l?)1aqAd1?8p3W#Z}#jS`R>%
z1wB<@DbpNd?_BQ7W5SE4SfZyT=9?;+C3=F%Nuw!_5<+vZ_7e2ww-}G7B!~?`Zg(%5
zz*!4ZUlO+J9^Jd4XBQJ`1Rm`!{td8gr{i4pl3juAat(#yKvQq0;!&Ekd<W~n!x_(e
z_kbCbl|M+K^R|;QPvlbV;LBJ=EHdtpVFvgL!p?GJKj(Lt-R at w9I*r<nUtKURE9aei
zBWX5ByFqr=`J1J~M23j|M7!A at ->k;cgRoTKhU2;U`B^B0mv(1OdHWJT;l!7nsoqKG
zP<x%k%hs^jx2`{E`d0X_vjA)R^Bcav6J+<UG@#zPI}tc1j9gqRGO`qP3{83~-84lt
z7Xnl0iz&Oq2SNIqez5|Rpq#M=i-m!Kfmo77rwpH`^I@``eyb+Q!+xxFFu5)}U2gS2
zZ*I#_Mg{-LCljxV+K|t>M;t)(yrfW^uV_~JY2n9=Jz8v7(x+_@`E1V_?K7z`EhW7Y
zmcm5<1F)OKAaeVsj+}K+e_+G>YlH?yrXXSdaG8rj>D9xW0&4_~gG%_(CEv at R$p8b+
z*my{$im+v#abChOPh(t{vz1t$)fu^VINoF{^j5m`;p*Q%DqyWW4RE<_rTh;D4sn{6
zDzoj|NRJ5+<=ECw=87#M+xCG%VD#_OKyPA+V)cHX<3iKi#RU;S2~n%p&4Ko<i-ySh
zkFdidmuJADcbzHYo#WBwzb?a#;bXSxA#isHf78aDGS^iA=vi#V;VBUF5+Hb2H(%_8
zT2`%P7Jv3bdX?{yFuLq7I at 3jh^{C9r*+5dpn~H15={rTw^Y*NE4(*G*I=9OyKfd|v
zDwFyl at P08cGyr32WXIJ%%o)p3uRyawvNgCCsNfsn8p9Kmfx%`zbv*~`Wsf)e`})7m
z<w#JRL{{_hZ`XN`(tuoYIo97^RX~?b(FTL2+7HU)@<EKzB9?NXNUiD<IS_7#kXb&T
zU5+X>*nVcO)Mo75HSU2CRC6t7<Y-Sf?83YOo^tNu+X_{g2f&Y>ZER?mode1<`!$Px
zrhkdIJq6H-;YCkY%`O33I- at Lz^N9mm#n!y+NF=BGA5!b+A2_9BsgXWR!^;7X<7{;J
znc*piY1(p?^d=oGr0O_c+PU5<!=Rt!X}PcZk0cxZfhW;`ktCaUh$^1pF|ISfTz`Nq
z1|gwbc3mE0!SJj5;yYtTV&QJP;YZ8afb!E-D`snI!#`C$pX9J(B>?H_s_xb|Tdi!D
z!QcOZ)pwq3nU=KW!hH|MA)f_)O4Gc=Ayyt&NcO_N-;<9zwEP2<)_TH2W*{IHY>U}e
z54I#Zh+NWNR;Ek7eY2F)EIUU>j%5*;3q_1g7so7g2c8^FkB7LiP)@4g3q2+B^beX4
z);w2rezi+KK#!p0WiNGPp45|U%>%4I=8MCf83u+l!W!Z$1uAP=1TXHjN($fD#D2Q@
z%bk~qwg=7-#Xqc$%*s6uTEsQ#vl?n>p))n^Kb43KamNk!AQFn{(61QKGnJe)o$^^!
z)~33#$CAb+Xg7_z(&#@gPM+cX_u~XRj^Vkh=MNG{w3<eb?Q?tZ#@;zqOo+mwhs~pq
ziBpn15yll?Da(g{3V#laS8a7jRh}(K3#9=1hM4WYxYFJ7k0|D}nl>*GLC|MPSN8|8
zrRwi!Wgh$a_;7b$O~wnxTL+WY)oxqo!0|X-Yl>s%ygnE(X?Y>S!GQF#e+1l at P_=~Z
zqVasAv<swjm)SS at BVTg#=SLk-MhYO9pe1wur;QvPSHP_{NBc48`06^EOU!ISbF7b{
ziuV|}I1if3#JO1U1GA79x-afb+u2YrE=SId at Q4b}L_7<rYP at lfQ#cv-cg$d9+?KL|
z<|SK$<pKrw27?RvoYnmoQ`agBIS03H>q}I^VUxc{S!SwmqoCl`g8_}N8Rr+Le<zzX
zJAQme&Ls5ojYla)X_#kF at lV=MA`6Bc+;iLV0+1U|z3}&;49qu}Rrib8#Js+f?`I<`
zu}!iypm at I=VK%n*Rad<Z;S&9jL%{-AVsIl|Yhqt-+cDm@(nibIkCTaw$~K}pz<_0@
z=~+Ex!2KhowQs7U5zztB at c-x`6LoGR{$GsPJHtFv*MH2j<TKJGR4@#VCBZJM7qj?$
zHs0X{Z#vA>O`QFZs<4f1a)pKCxDCS|VJF2kvxb%xX{WAROw{meV)pOdzoW%_Qm|x#
z8C7=Uqdn&5t+JZ^osj38{CL`X&`TYv7xF8aGMQ#QJP?@<pC_fyuk`u^Q#sn>gr2EN
zDS&w<@!7AR%#9|-RO=7b-d|hL8hrS3rmh}1m2phi^i at Vx{2Ml@=C#@i!o8e><2qj|
zZbWymCR at 8oRU}-bF4EFB{i`?3GI2H!(ONqLf+yfFHqXWu=Jf1tU9l0IiqyfUMW#Xa
zq~&wJ0s8|l$(RCg|7v_ok7z9&0E$J=(L{LA9IzHzP+D`HC1W_cjsAIE+(X!-b87W_
z`jSsRQMZFB6!IZ9oBqmpk=9wOu~YI(_O)iH<@hd$=p2@=+E%r9>uG(f)S!PGfGaY%
zCm~4^GYZhZ6;&g$ruERIrzW;qW49ay78a at _8W!CBb=;*ZcgZ&k at 9Fy|{P;>)=XRHe
z_ZlrkjyBB0kagdHakiG0r_OSY8v5*jPL2R-p%7rI#FWhyW2&z;-0$0YTwI2!+r7L5
zc#8bCNEuCM%2pf9yJ<$TJ4aJQJ?)@7A1n0oM0PLFuE(i1OtY4GRg3b84tfsiw$3y=
zN<Hu^9F0k^3>vxSzo&DpLF&t{n;{Y$t#7D}n#u_6e8<obr9ba)ZS6oVS9Q2W()4Sd
zs`7aqq1*j=wqaa_f^{^NgnK&vF6uqZpZY?EH$Z_J^pi;tu{lDhnCpWdutKX{m!9O@
zkYA|~equO)2aOG+xpK at K*H>@VDf(}G&<fU2fnqS#0A{m%%@~t5oDuU`EMG{Xq;AgD
zbZd&%G>ki7xo}RRamK&$W#NPK?r_a`V_XGxdF*`!f+Qt2z!mocIs?EXjfXzi9Om6R
zNo{4Nz2P{ZeE;+#WR^~!nszhQ>1~80?)(r?P~)bHGTh1x18d9|797wQTUq4*Lh{?n
zPCTHfP~Yre-MO3EZtJiVnUDw)IbfT8f~w1YZj=58FvP?yumFj)5`|HZtfk1It~%*Z
zNROYo`!>)NyKFY~6lfk+A+i8AsHCdrzfnp%RpM{=*k;oeck2Rx6IKEHTC3z<lD6k-
z;Suw!oh<s;_pZX5sgCr at +VhVW1J_MbZMfka)}m@@rLj#aSef9ldD3brai$;)qwzbQ
zPU;p483r(z1n3yLsJ{E%>ywv|ZMG7J(@-R~I(6ul%1SeK&Q3$�#jfNGR9ga5FKn
zUm$g!S?&2%d7AB_3pYse6+DJSajt8J<Y+ybm`l0%=l1s|dW3_8Llxks(>Ha~hBzj~
zO3Rgoy*AIDP%aP>{Gb-mq at m8CeC)@Dc+&%^{V7O+w$JhSm*>m(<Hie$lb_<kGF^E8
zfI at g%5<h0PVi#>De);Q>V>uW^o%rV3Y<>lJHYO*L4}}j`BFE-iq%*5`3b6x<?%dUN
zfRXA2L$U~!$j#Xc9*Mclazk3WpFQ`KtX=y at CA`Ut=QD$$9MI%Oz3PINsUxgkDB#-K
zuE at AO9CLjc)}gf at J*~~+Y&f`zOqK0Ti4Eylzh8FuVS?DauKzsvTaI<`OTh~C1+W<5
zFc^CIZPNfHcJ32qE&8ouck at pPMQjlUJCOgp+SbFzr)gVYjA4h1+D-*^bn6mG{&Sg^
zNzIyG(~Y0^M~0E;1J$fq8;MC=FHLs;FcP>>|6T%hQyEX%!gK=Qnn}@aE5Q8XDkk$+
z+d0^c3oZ-XNxUa4e*v~_d>&xB+Vn3I13sQcFu&N&qj|xImINYSzZI%2W244C0~aXo
zr!cz8dtdo9K7CT`zlpY5-Ug52Y&t%R3Gxo|ztJ|jkg93>_%0dpfRWJ`)a(0W7^3NO
zycE3k?oBZnPT|06D$Jei`@oFsZ<8vz*Q<1N{|VIHtwf0a8i$aqE>*vN?)OeCzxQv8
z94op%d at c(-UQM=4s<oF at Wl;D>Nmt06zdvVFD7won&e+}~V&T5>%+#dUBr<|ueXpYN
zi#Lj)R#^c=ZgtQpmi3^$r+D at h@2z8fkD2+;zi2m2-=<Kh?7!bK`OCuTpB+pMw2M<d
zMn7`c%_KSkUd>>svxYMZoCIp8XZ7^Y6Q at r9wGhI22j3!F=R?;wST`t&%)TW1gY6#7
z7EC723JCIS%<)IFi4%(N?~G~aI5_n)dOIQxHbsR?7VT0(zGFq*yNa|5{O08G8Ii6E
z&&*#h3<WgWsIzrqtg6enMSqe)7xv5+mQ$!?0%Yk)eeqd}n_0Gc(FUz6vWYKm(+XYf
zrCv2$`vm)TD4{<R#=?0W7La|<<~eUo{$4c^T9 at rA0CNtnoQVx!p3qto)!XN3>|lOz
z|MPIpP6M^b0bw_x at K0S1PwiaM*()k#CwK)eyJdc4d~l-JSRmu&H5tsIr1o}36-a;(
z6)<tEKCMHO!ef{Dj&Qg;UV#j&F+ckKFblJB@{XAr*y>OPj=tBn!M>RXvU1#Ss^idM
z831yEN*8cS8C9u4B2ffh=15h$b9!^&A|h8>u&8(5DTAwe#r^qi+<OzPW2ZZua|Hu3
zPfJRK2#C?dd<c1)yKlRHCz#$J#<UO!;oXD_4Ng57JNaKY`QL!+{@>O at wfGu~=eLXb
zIw?RvUarseJzsf*mbuYFAQFo~EiOa)hJ!5A>3s>aR#fk{3Z{>#wVsJ4YWkJ_AUv5j
zUAEkUtrffs|6OJ~5;WKIjweI3YG#f3-L0f5J}KselUSRKq#TpQtY;2mE)(KJ3isBF
zhfEQQS{z|26p8IS#9Zc;#?)JyJJVVntG|3rl$r?m)5seiv{lOL1Z|RXLK8UjSZygS
zdJGzaS(y`LLCDP|0+Q- at TWtJb!h=mtjt(goy1Qb3pzogF{MnUiH`|b&?MBmo6CwB^
z@?+7X%?qmITiZM5;#ZFwape!^_2G!^Jkk7Uiq+YqF&W=#27r;fP*0LI>ycU+;=fEY
ze5`EO)2}UrkEg7EsV|`PJ$w)0RxP&0^X{mk=M(LdRQ41Vk*p=~12ak+#fifLp;zU#
zczqh3g0ph;n(&@puP?Du*IT;qtjM%AaA5LjYFcrQ7sd?1UAWe+_-5wF at u_AViW{mj
zo%G<V84NB`T)r2;$L_(HcRAsz==4i(53D?Y_yOcT-^fmryGI5*C5S*sQTf_-7O)3`
zrr=vXLnwecB>ZvVjK)<10NAT!H6be751c26pGNkMPl^^rZ%8Itj;B0}ASP at 2&;f+w
z+vtkV>$gmiOe*^fan3Z%UGF~ds;b3c0d{F^&G3&<+gy;5=by<+bzN1(Uw|A8n8E;3
zxZ-I0@(AA<J$)3Q2U^1gAVd!PGU)qG(vIdL_Kk`7p|4&$?zjQ!CNh^~%Dg+@!)%N<
zo#Fxm4n(GqT#2)rZW}Lw{4bDP*Xu{D{c~r>82xIbwnTk_%@knkYRTU at m_*b)#1_V+
z-HoDkn7(8*QPzVgZt`1-wiXJieb;lytccN=M{sYKB(_e8mZ9^R0~lC%UcfzdgG~p#
z6w|tk_A9-MgUjIBsoERtzQ96rZe?YKp}!4eDuHKJt`-(a2$4K=j~eH&Mcexx0zv$L
zIA;$$txUq~gMGt91S`5({|wsk-B^Y}j((SRjfP!XN~$q|y7cjr5<~L-_C^LPj=5}%
zvW*L?X};VrRn~u#t&>Y*HW6dp1P at 3t0<iq>5^m^e3muu1<SnuB|Ew~zjqR;uk8+)Z
zx{n0ETEGGvJ|4Y6aL}--f$=pMWDww7yuG~#+#3IFy|p_7IMcD3{CJ)2(YL0Qalxl4
zCqS^9gJOq`oE;@;aOU+0Z$%}UJQlNTd9J^zKJXMmj;bvHIY#VA%mT+)u6v0x)1p5u
zOSZHYg#3#Gd-cOO%TvgjWN>Yo0mExb&^)qZl#OI`_JfGB5naxD?_uU-GM#W1r|J8E
z+qWtQ<H1jG;_sbY*-q);HwQ`ptR5`ItIw7mKy=qNE>Ty;0Gl&O0%Qe$YMf~}kiJa2
z;a0 at NFb7a*@q3{Wai0OX$2AWY1wSfxh0Qu|zDpeZ*S%K!WMlm2VH{8mSj4z!vs=4$
z7yX`)7b<aXHH^US9=;2k>|m{wWMLSi4XVjpewcX}64(sXxUY`=$J+ZYtHyl5Ak-?6
zDn%Z}iHRl{-GxNRl}wrsO_&Xt5f9b+!5xA1oJhNg_*!;hcM3KV#&+IGFQMHY9sxU-
zw4&o~&9r&`-3Xj<u}e_ACr%8+V;!(T5<8|y31Ye~@^!k?aL~SFeqiQAx1 at Afr)RvS
zi(u{VC3_AiHdylMUqv|@)HV<;Tnvnk5$EQWdN5zIXL-#OgCh{g6tHi{4$zdbk{YRM
z5Eq16b-ETrqp|R2i134GHMh70Bv)7Ua3%}_CeicFydS6+Vl#*d!_`juAOc?pM#j|B
zceKYphtSN(z`_8WBmcZQOltEte{7>PTYv~XOBfks@$eSK<Em#UM?|UNSI2w*?*(XJ
z<fh3k=-%78UnpejF_!BPxc>v5fNdo{oImV3)WkS}M;ovI0vxN?(hho9Zr~Jx-=GP-
zr>LDl)FIC8Nj|u+4|BQb8iW6xhRq<&rUIMTai|xwQ_F_3>bx2<w{eE%4_r9fPLpb0
zgwEExdsM&YI2dsVy<0Y1cPNe7Lol}l7_TN(6W}jKLK=d^Iq-ATj0EMpYDxf9QS_S`
zCzh8HPwcEsE85uU0!os!b9~9N86PVnVwG!-LLnkwc#9X_naFMqEJi{d9z58-WDKvo
zp)D7dG60;h6)K%+2r1QTF{t9QEW^a1b|55`kd^{W-hdK>#cZtoSHmw2SnZJcJ!bI&
z at Yivm(6S4xO5m-8Wm@=F6-Cx7C~MIgFdylZ=m>S_c>Q4I8Bfeg9(RKrF4I!iMqZnA
zA31NV$rR(@+dbl)x<pGs>TA(||NZ>|LF$8|@E3rw!fc4g`nN>`wcVDb!lQLc-Kmlb
zyMu8i&)rZbE=3bDCn at -6K6V}pOvYTBa~me-zuZPX?=b;8;jOot4BQ*M6h3q&*%#MI
zun$jof3 at nfmgwoo58B^- at hO>lA?Qk&3v04U)al=BNeBa?U;!)~%GHVh{|Mx}fJEAk
zRO*}<N)VyB1i`9+rBBlo2wWqBCZ$=n^vyxAy1~Lj{lPPqd^$Mf8|M&oOfg#p3QL~F
znT;K&)5}+`sr5Kw<Q<Xi{&sX7-j~-tti9s&E>g_#vbOd9+YQZu!k^t&uB{65IB)<R
z6hpmHf>}Iq>t~U6+0{H+Cb{<t%Sj3TbuQEfHmY2Y7J3>>3kN3Cl~dCPIzw?rx(I=Y
z-21GFX~~wyypi!yDR)&?x)rZgbbcWVLKGYkDE*X<TqBCV*#_%7riNm8i~jM~zKy`N
z$CoPVr~RFfudtvsmd0h>>}oZ)=f2ertN3xnzcrOP$)%VdYZ5kZ`#duIm))aP*$jA+
zwA$NKMXTH?RD$3^AKF<%M|Hju*rek5p;NX(vRHfgWzrmwG)emXnH<OH+$ha`3A}3u
zzoZfxc>fYE3Rjx5-hgXUV9%zP02$AsHD-Ffi3$DQD2xGo<*M`qACPop)yECQ=00pG
zUNJg%;f0;was$MP%5A~;m@>eTX%<aI1x!;vo~y6{9Lb0BfM;jjpdkash~RN4L%+xL
zDbTqx;~!Tg(sSus<OO{BAb+x&-0yTJiPq~R^_imS3&+<t3$QoAs&{MIQV?%e-=0c5
z+dveLERMd*3#{D|%qu8c9F}jB?{6D!Lo*203*mYYy>leE_L7)fsjz6zc#I^E5a at SB
zz%yAbQ#=wzTReYfEYR_F6I6pjHd=?<iL*(mB_SMViEyO8(r4T3)=?|+4qm{8a?%vY
zYMP{NAZSJ!h_rm#4psiRd#QB_UM+F5);2s$Q at W&;#}{@-n0s`%SVqc27W^SMAaL}O
z&3M#DFXfaQpxD3zi>bOx_NJ?^Ud)MVduqiS$i=mdbSl$a=!NXu(jq#ZVMCH_>lSO;
z=2FNoN&>`Ma{of4?|98qOwMR{QFoCwz{CF7B%FKgHECLiN58cSim|v}2E;%J|AHAn
z8NAgH4&iS(h=;S)?N*ZeoTlG+ex3E&6=Nz$bSvS|K*U3vt4lTJtcxWKHJ~!6dh;8y
zM7RYI{t1n!tT2cw+v{mz=FCP;>PN72HNfUD3Iwm~tQ&nLZOJzn6{X5~%d}#0k!8E>
zTi~iat=Xl5Z*KK~bVCAAjwCfBW;%eA`++#t-&_g at ehY{5zxEITObiz2*`vQ#chScK
zz at kekJ}G%9u~(`HYq1fCe=GI|pa$IHMJl0XimfbdV;#lo#<Wk8SNI|ySy%S-IfF#6
zUD$ZeNbiz+4T{!U|8ZNy1xNd$cG;ZPl at l-+tYvzY7ps+P>G-=M at X^_}#m-EF`>Fl4
z8tlO}<KSOVo;^<#A8jc(YjZYKQ9DAmP|SlFv6 at eTI&dxN=W%~qSwLD59jrnJ^aX1T
zl<Bbx%<{K_h1sZ-1RIOy+Qut#bl|Go?j6@#yca*AZ)<F3VMah2q8fi&+*FQ}haW3*
zQDkKW>%1<5jkmWQZG8yevn8j16EzI77}D^Dirl*%_p}sf_SV2!2LHh+xi5TDE$HQ}
zbAY-sT_;;x6Ikjekjymsqd#$R!7{~bkx%JRHgCTS4!qH}<8ftBynQ1TTms`Q2(MCF
zk^C|+NH$3 at syB0wkpYaLwEN;t>*MT}_a0D2QX3pfi#&BNjEnm+y;fOFmPa?#{a?R?
zg7wVm*W!BfrIzyY3eD7b`3?&)=B|4}`B&cqH)iTJ8?{b;HZG|jQ>9}?RK$T$5~FVi
z>)GWp?b at qs84T-FAnFDPHjrj2xAUtOR?i`={m!)=kMXImOSEI>Nxd6Rm%#7@*J#h^
z0iFj9chPazLm*kazCc+5y9D6dj0b{DJ54&w>cG<e3OLFSEr{A5*>0JZ!@{(c1c8<J
z19Cv-nf~|o(*ZosSBam28a8UKMk3?S?c3aDPx(~t<S#{n#_}yuuZ5!p3{ueC2<be-
zLG}reDB;@=Cim9{a~IvxsK-TxW6(RdRB&^&9JS(-H56iYC*9^E)U*EU13SL7sT1UI
zBM+5<1~Ix=nj%mu(7dvSdu$#hS@}zHvP%lFiu<JBWK2m?*q}vGYbe6Av<io|>K*i8
zPY83S9UM;dvL$<uS&?&jHm9jp2G4>d<tE4X#o(25g}0~dtvb|7CQOF0eHRxOJal1f
zc`69(pf)scPd&SvTWw={&NQ3uCFNS7K_VCTu7>yfiG3 at o=BvxIxwV1R;((D5!p5o5
z((9FS(l<C~sIF(t_F!B?c91{lg<|)%<ab-oiRyQ1f<;r)R+LK9_pWgVsjO60{Z<Px
zm77ZGZy}DC?*$u<5cukKk~vB|K`r({j>PVF0JrR0)%`Nh0lc5MtF}H#JsTN{_5tz!
zw4AzI8&y`S#d(>2C6R^lgC*9BKU9)AEQxyZQa$Yz-S at db#Vl8IeczOzh}HT_5YdCR
zkbU7BY-|yAjTR;!(T1>x^V>3<O4Z1d#uZw#kQ8}e&3$aXQ~)X$(wWQ~ToVD!g;S_=
zsNZ9A$t*VOcR4D*oz*C?TL;jFd#5<+U3|}G7Wjocoe#Pm`8J#ZYq*7W)?p&l at S%_3
z{4|D#FbU=&2oeBI`5ifsj*Yt^{^;- at _yxF_c2N&hYve&jN1N6Tu%%lQZq9G%<%9+S
z%}>&!UQS<==eJh>4sZ`j<ei-gG710`q1#F`$;Pc}vrFaEERN5;FntA^?AiG~Je;Js
zTb?AK3w?><iy{ma@?Kw-ZO>YU0ZI9Nvj?N;uY8L|uJN!`xsmg-8D&r2utFKr7CDfL
zB^KXQ546GsA|Qoa+IpUe>a}3HAaVt{Pl+px?ypLIMWwU?9O<?JJhV}KvwhpQx=z2#
zjwb-7!g%Y}bIkb+Y0lC+`bLMEo(n2y&(%V!nQ04&W^-C&v4=Hpp2Yroii>%D4rbIo
zchK}0Tji0bCwk-xe!oGgPN;R`rrU$6&s<DjKuoOAvMs~}-QmHWbG}9IFzLaAE&mnu
zTuU2#N6ecQ(JEK7Tk8h>qf=RjF?H~p_H<mx>4(Sra|FmH8JtMJ;2jMm*22b%I(CG(
zDYrIb-)PdC2TxG`^z<%bSSh^HQ7FZ(^G0=);YCFdDcA!%vkr$3AZ3O=f#jigItBZ8
z^u88u+nc{5YL{rfwI9eVw3tXrn>{1+CC%jx4?4ud$E#Z7;|t>f=SfZg`)3|PUg4|N
zW#Df;KZ1wir-^!{qG>GsMPGSYP1~AbzH$9JBPMGvscFQwm=cZ*Dx6o^;Ukpz at sdb&
z?@?zY=K}DD4?{;lZ_tViFlfM%8kWv4I at m1|0P_NALl7iO)r<f8_kU_KVH3~<sm->~
zf4z^&WrU~7y<iJ$+(`gjv{q{37&vH67cc}@ku%(w6s|k&yKy`AM2R}_Nh~!?Pd%85
zNFea at DQ>`E<f9?6h^*Pnog#pkhFh#7v{0}W7Vrt)-+!~Eo;cqx(JkSz2QsRR_$`MR
zksV9?a0jMW^_P)7JATItK~n-2F{Pl(Gh6`JJ=x2+4{MA=;b~Mr{<yl?5G#PdUq8Tk
zK9Ed)5|v<HqM0zYCT6_^|GZtWb9O{~{{}e*;rfhay|q!)FnBBfiDEj~8ICD^IG0;!
zJrM=++)1$8AvPAf;6yfL7sn6h6KOlEyx!V^BD#)j#&W29*$l9ErYM+{f39hFy2zBf
zmks>!jXveetsfJE8=xHZ_g2S<wI1REV%!Fc^GtEjiNTK=WGZs?=V$Y0O(U<YY(1$|
z{%zeXZkO*|{5w?aJ!P2F;jPkZURaRSVBNCy%y;bTzSHE4pK2W5lMHVH)~*sJZw2P-
zT#4Ikn}L8Vu$v0t;^ng&Xda`*I%?896GHkA>o;Xl;(Y4jeRkS&5(%K6mF4PWQbDp=
z&Wt4jmb^v;wmOGoTS*ogoQuWRoHR9cF=v+5&Lh@;a7yP+Ae}HM?vxQHQT;?kO&AYE
zr-hJ2-)(Z|;H~NSx{jc_G5wY)iS&<W<FAr;yzo29!p;ET^<Q~(!q?~4>*wphviYk{
z?FR^~DRDUxl?^NtI+Ei#r~g*^J^sV!*UW^rQhe;K49FqEe0-rYVGzbJ##jL5Xaj=y
z0x|1k=Gb;thRQz;l{1fNcWx!U_OZq>X2aDgZgUc%^creFgg?9hR+O5En)oN$)yeg&
zdococEd@=-HGAh at n1Q|k1CC|vkyKMUA=Bmb$fe2W!qXZK3PkgiTDzD#6}u&GJ^;P6
zD*F9rETGz7`KBbUUCHR7n47%T{js)UJ}{2 at T1?|F@(9vT34S|u`Zp_H*0pD+JUZLH
zC`X$F^$g7asPwcKb(i~z%+t+`5%dlkWi&1+_D?5q*bT%sOj?wCYIRQ}=wpq>@k#p(
zQcpLZ?lk<5Ep!4#I^X{^X4=3o<9{2O&qz|p2w5cf&-*t<v!vgxpx&$+-U17-_CJBj
z>5LUUG%$9DJ4s{X$1roQGy+m-+19#uhS%LFKf`l9Rk{33nTGH%{a=Mek=M+IfAxis
zERgOElTacg_bK8GVx`Vi;Ri6B<g8m5Azfd-iX#?Pugy_#e^fTMJ3=vAo`^_1ngtS|
z)zpKtdN9+zkLjaoDuzre4ACqcqqHF;xfMDS?_S at SrH<A<oc*WygOU`#4w;OKHonS&
z`_`W<G<ny10ddYvc73>1x0 at 1qfx61hjaee+ug>FZ8Uyd@{qX%$qHZN<;;M+6&C|@g
z6F}pg#ONQbHoFbue=la&4ZFw$F`x_5I9C-(AJ at 0SeuYB7blT<XK(;#3Rxz==3APAd
zi(x!tBn;B2-9Mp%rg$F=Y)HCTYqYU?`Y_9Y=?rE~ziG{y#tw+`0jHiGAu@<H-a%r^
zd_sQ7AAp7!LcW>wUGdbkoy9D#CM7v%)U-tc>9xsHe!`z5AlARm1$ad>#~=Qaf6VIc
zq20y}J&XV5xRx?{sFW00S@!hZG{Jn(RP$!gYc|+;MaM%IQDsEwr^SBPuNPOqyNV^%
zH$W6aj%^Uuf65P#Bu)UxMyD>EEVpM*@AZp6yfsuh+csP&CfO?L|9zfsP%&(Vn5&CE
zWQu=K&Crj%y+a}pWJ&hda(36aFb=E^ZnEYkA^!;Jo7OE^)z_2PFO+_OOQ;W~@9)Fw
zCj-X3%!!CG)gVeOcKVu~6YP2A+OpFJ%!h4~+MGv^9u<RRI8!|%ZU|yWE76wMmPM(J
za0tyt at 95zB$JW0rsypH|Lnp0t4P7y_`<@~qnju52nslE#IO#;>a-d+Bze*ggZ{DWW
zZpMzr4KIPb=V`y+OrnzD)F&I>%_QgX`4ZeXnop}o^wiF`Lyk~weCSM~ykqdaj%#o)
zmEl252->keB_aHzJj}Hy9$KJu5L376UQNGqWgCi{G9-7oPNGjIZJwVBPZ4%dg5$j9
z@;PX$m4q}WU&?YN+X)TT-pDpRniYAyQ>%5$B)2LMK;|(9gm)-`087+(lG9smz*^&-
z+d<;o75eIQ|8vNvn}-I64^^&hSKUL$%p3fro at gMSf$kDn!XUF`m*<L0qkFHTHqyMg
z^&w|qB1enNMXh21>u(^z#?-CD+0pA at q>{&12P#mvXeqS7u&Mco0I2|Gwaa4X-~v+m
zdtn;{4_#7Nb9D}!e|$O%6u-A1{QdnL at Hm}_AP3bq;QhB051<KCxB9{t$k(3kn-qUY
zKc4^#Dai{SAD`u>U(p7R$EImTCHy!M+-Bb<C)U|ro!o|a{bziTMffi$%jC76Zs~Qh
zg)-Po8;;TA2FBJXc#CvcpCX3#uZ?O|sJ}EHCPMTluBX&%S6KPd4dO6tt6dbi!dcCK
zd at YqTFq9&%Me~Iv-3<$@t&_!=WeyD0_mKZ^pz4KPq2~hQJ#4eU`W-FZC-<xzFLZ>8
zhC`A+_7D(T^NkCw19iG;=|4%mgSE+jko|{PC`hTp8;+nzRd at eX^%inr?q>D$&mSGm
zhF|?M8Gsw6l%0*pH`-3GS%|uAnQy^1TliMM6D?o`##aR{`uQ;n1{xn3=pQ;UXbJp{
z>ZyEXF=2bl=Id*Q0zBAV$J6!3C1HMVK<4U$=)>8fNj^2IFt at o>QS_ci;aSDfsr!$&
zQ%;Wv_1YLQHYG<9OQoRl`c0p?z1SugnfX!io)W@>r^ftczOhDquXix)m(61JE7`v!
zNb_v%*m-TpC*aW`DR3D6&<fQ&c3xG}cAyW&{T-rRRAeZH6GLB$lL4W5=JM$XV$w&i
z>QA`bfE3pdASKYJj=avJF((QDXi&?+kgV^z?@LUyH`YyWS_~b0#dfp-w}_J}eO-(o
zQc+cyeSX9 at 0Fp(g_kjs5ZfpL0tyX(>3Ef1Au4qYHP6&MutgqJd0mCN?7tjTQes7F_
z+61+%(xIV%A4Gw~BJ)_2ZB8KKvo<kfv-eRz8MGmn4fUt9DfkC172M3pbkMWPeAYKB
zDths*(R{bP>`}0BEM{vu!jQ&^W=89k at Dx@}-dcVvoLCSs_P#ZI?-8pGhH{ROa8xM^
zA>Ixo&`R;#eAcE8vBTeSC;ZmJlw9K%Ee`4PG44tCYjL+;2A}p|smF3;+<T$aUk^>;
z at 3pR_UIqNcu2vO5x*j`@ui4b2cBA0GroFUOdXY`CLfDURHJ({c;u$2k(Oy at Z3ij8J
zLPXA;!CU!80T?lqN2Q0mK|o_h`2_VP6J1oSjadoz@;(55&mM{T;ZA8^xn!@Yxcmp_
z`D7ax2~NbQ at 25Eigj)}GUQUXBd-<e!UT!Uc(;-E+O`4|%cj%$OAOBFh2`Yp8Ks;mO
zQKQIan{|&tExN_Tg*vX^F)y`nwxPVFeJ7VpcJ2;l+RiV6hlb398Q2E>XZTZ`KX~;b
zCkdl at uQ`A2c&195d-ba-NEvQhF;l91RFdD<othJT;y#~KW9~}ha#o)@$3uP;TJ+wB
zKz#Gx>@;Kv06Y+DeE>7%Sc|W7*Ehuhj|(LDCvhNrtW+3qHJH9^ssW0s333n}UqJ5<
z|2mfGpE+SIS0USc`SI!|L6DoDP|~JXdjaf`8aK;XBDo0aibENPz$*jTA-`YQYya*0
zXuj|SZfon_-7KtRfpas;-7=j3z9*}*U=g#x{}z*gM4PPu5EUnV(EOK}gm`!gt$;p!
z_VvG7+2PF>dp3(!oEuR%vVf{oCO<gFD#OCh&Y}$z5q~Z=<Ch)Zzz|~?EX;T93ml1V
z5x+q!iGEN7QW{$k5dEQSKwI_UgyUmCm{cabL#-_>+dsxjf(@rQP&gHcDv3GUOGr&g
zDLU at zxvl-p3)8jxl4d!fU$MicqvNp&lj_Oq?BcBoT=iRP&$B-JaVg4T=L!A`janVD
z?+J&6mSCr67K)0S<RX}U$%d`dttVLt>3ehmOdhQm!|F`4><-dX`u-M^+}uIJ4FAWN
z_7FoW!TO^i-5CEnbd|&7D82_7#KE!_^hC46XTy&E2 at xS?t|H~*7L|p8aeyHnS#f5W
zbip>8`My$b6T(DN^q|4EER93PJC!fl(ys$q{3Dw(bDxI(6*UBJpqm~;HDq(FSf?*B
z10K}o`-u;T5eiOE&K&$T88^bx>wOgh<0&+MtRR|J*Vp^y=%n@;k1cPU#(u{ueB_rV
zA$_J!<%>MGpoI(Y+jlM&$RCk)k4r<mr3me;FkN^z2!l23-GK-N4tIb!6bpAgl#qWn
ztS=8*jvR_RY}nVZegb4%p#aJmYD^f2jv)dB@)`y1y9JDB1^pvWjA?O}6AimJ8f9Rh
z1{~B;CEGv^2Y>}FcIx}x81drSW;*L<z<g8h4J<%y^0WONbmoaX9m59&lk(1QrGhGM
ze3c&e&>8p-Vg`Ic`Cs6M(^PCYqIZ*bsF-OE7+|*30LLbSg$2!)jb!%y;P*7jh$<V)
z7k<l at MXeZ8CmTi-MS%|$Ndc96D`E9Zmz{gIEB`a&yK-yTOSrQ-rk`{crjPx|8CUFe
z9MXx%EP%3tf7+Al%d_i`@`D*ZJ}i-mw}!uNA9tJi0ZPx463Cm#Ds_p(*v)#<KbD9x
z63(TCruNazjoOS1<f&M2XPb&TYCe3aS|q2-GT at DGiDi|9H-5K*Gx_>f4eSd(=Y|yx
zhawlctpA|S)Nb|+b00R4*X-Ic(B+G`amzOGOiX_JNbb=(dsq^4pN^6^vibcU2x*{f
zKt44Lw0vk8W0$|p<<P34#GGZcL$s_bT(avASD76PZ^cX}7$2G4qp5#DhQ&S^S89z6
zylGQAO7 at j=p+30ZU4o?G=^|)l>sQ{UR_Iq7A5H~E+-Bx*KxD;3f318?)H&*gHt6u(
z^12r)YQ~}WZaCh=&T-lv<2k1LZ8&i!)HC850-3KRFzV7m7{9AEp~wCDpzf>LCb5AD
zt-PcO@@lrVZH4a1#_vOs{Gpl at B?ezG6^QTSCxY}TfH}93+yhhvB<3H+F`>0~^%6<A
zU14ZdL+1KH(WiXCaeInyb|^mlXp#0cSByPC67X}&yDDC!t(TdB at H_{8L|htR1iiOd
z@|nmRJz)Rd-K#GvjR>{;N=|RS9NHD}LMZ at DjU9~CGBl4Q2l8 at V3V`d+ro7}L*DtJt
zy7*+QFMR)L;Om)r#B=PFVZ@)Rjzrx`tntl$a8u6&0;T?9r|}nm`z}FbQ6x}AXy!*A
zf7Q_hw0aTC|C<bSt-}8u<xM40E2SAKCE-ojwQ~o!N!4S0cWVm!Rl+;VYS6^D{`)51
zXY|37Vk;zH5|u-HX`g0ClJlLiOROXRjJ_Hr)6-L0D^rzIS-2q=aQ4F{qqX#sqssWA
z2#lWb*cuq6vp7Qs*ThiLvEW=>!V3$iI5&Mu7m2)mEoF0IY(9wVh04<`npG1$W$=X4
zvTfm`ivv2rH&d+7#i6dkijJ!@{F`PSpGMI#2qMN(Thq8h8mECz)pZhLoX$7e7A*Z5
zsd*YeSp at RHc8L43mqhi9c(f*v5vCE91UvZJQc{>;&P;^RO`{jUWJ01^`NV^Gsp{>0
zeKfbWH$a6xKj3Y&cSJN~EuAuQ(*q`;CN%9(PS%ZwxQ+jK)w1^ZV3d$awg;oz$<Ug^
zA3cMZ4rHa33DZ`(L`Aw}tS04s=u7}o(T9K!3Nf4AjlpULT23U~Tm_yK&f0a~j<m-=
zH%WH9WBk{3Nv8p%l`{9d at J~Y_4dZ}kH+rMcxlOzVxp~4<R2Kx<o(48JT9eC>dbHa<
zC>q8`fILUc at +9?$^uPm?GVzT4NwH}~KdJQys`@;BcmznVi~`nOM*1ZGGvS&{&J~6q
z-zYpWeII}V-fvH!#3}jjSRuZBS{V>rLe}Q7_E)Imwbe)coYl7xueZ}MM(i$vnE3ge
zO1M$>m)%>1DN~lQFjJh~-;aDbl`kkst~cCg0!f#U>jiSrNd-Cv8<3L at -$MvZ`%bhP
zsGi*uVte$+xbi}UD$!m0w`NLiNc`-YP0W#ri>y6{d?KfN1gH)r_yECxUU%YcZy>|5
z+RoE#{K%hG6;8#&FswSv<-s<MD4{OH{nqUFSsVQI8^mfo44(I)QwfY{^~N02sM{`9
z4Y=jieM&@?-%@}fZY^?FGt%yN>I`Dbow&b4_K((ZDRr^l^9SOS1NF@|A~+TkWSXSY
zw)%Zn5ei}T31&xI%fBwfQrG9tUe~kUgEs5U>UQ<KUyj;MsT7ixtz}*u;JxJb-mG(J
zDoL)!evwG6zNmXukj!YItCValI%`vuOoi0k?%bA)(+Mg?gjTk7(q>V$zzMj#h{b8z
z)F0Q9M<lyz9Co|`w4Mw9eKo!Jn+9Xj6U)huCv5)IJx;8AegXjCE4~?y)ZIDgR~I)m
zI6Ju`+B$VnbS9e9=><eh<Ts3mTL8~g=o2j|8(Z78ueN%vn0_1k0dB6vX5jzBsPBtG
z`<a at z?MAw6JEY)-0L-Om=U=#K2M}u2gZF3Y36lwI5%^Sep~p^-9&jhwPnxP1<VR37
zk$0eivcEE*<F;?1#m{Ut>{zQ9)Gb~EG+^=aqT64SONKL4d{k at 9L&k5SEA~#LW``Vr
z__e9&RBhsKl4o$S)G_$;ktg<#3jAjRN7^&S)K2Vn)pK1+C}*JgyUtYzdwD7c9H5qi
zaf48Ylo*@7*@Mo~GodAt8SL<H#ylp2*q`TzGmfz~N@;`AF8}WZplSRiPi(P!FxSs*
zg7axA^ul5PwTY8}CDtj3HkpuP>(zmtfEaqp#+V#NUZAjG;a_<R6bkh2&M^nwIwZ16
zR!?*KRaodT;P9N=@f9=Uv`KDKJSz`wi8|wM;V^R-7svGh^ZCe|CU4bXZ1CIpzp{>u
zyG#}u`3|6~<0gk|slH7QzwzASjf3{*iDXmCa-bt<$aT)*@xvz$KL4sG|5fB_pABK_
z8muQims*_t>5Ua&0>8X40vtg6TNAb7xEMx<hdujqI}%f at h&yV67Vd>^kGNSm9Yv9b
zv!&(w5*|F32s;KhD~$S!(`0(G;4p8hr{Y@`$ZXz{=X0FJa2CMHYHzC89C)HXg7OhP
z-|=sH+G<u&^v7iYhh1|jznLNoN7c`);`+8_=h|hVUuTH1MgQFxd|^&3u?)~;dA{^5
zpr*Na`@+Z93u;V%<o69IxrLPBUuYGM#sTtep1=?gU952hFfT;HUyZh`!8{#cP3&_8
zoPZ3+AJ#STqIl8#p^)$)*c2lZs+icpI-~Yn?>c4&rsaM35n?%2vi2Wqk)pYZSr}xS
z4Y)B0hb~7NuG~bwpAVNZ9eO#|IG6kW&%h!r@`7<Bh6F9pOo^V1-%Rp!?&^NiuKOrL
zZvm(XbGN^{?YiJSjiE;?1Qxe$I|bKxeHu#1E&j$riM%*EO?104)a-g=kP4kmuJo4Y
zq8(c~)}8Pk)S;{RLLy;@)6TzEP|ZkyT4ZkBD_?Y1<Z(BAv^Z1#03(IUBfjdLUMs?K
zxGOl`#z}*M6uKuZF-_{^QB~fn`!)|P8S*9H$`v-xY}Z?UNbb;q)g#Mz7iwdmv|GD{
z+&SHKl$Dkr3c+rl6#l at IFJPn~fx7fr?5EnCi>}Cst=fu*^^b=?Y8BDHf1i43G&6?)
zD1>8idifKn-G1l{5?;Z2<o>3Hhq5~xBzxC087ZNd{Xl at xZs*3%pqJ9`Mp!hb7MaE~
zN3MEF&|ihFT@%qK2T}J*>L_~uYJ;bij{Uh)L%M&3{PujVS at qJ##ZachCmZVBgkRgx
zchMW^@zx)LD4s!kpHo1h>WP@)b)wEItiUTk^q}0%8ylMQxW6)stzcx at XSb&8R at Lag
zEJ%SQ6}DF^HVNNE3`9JFA^2_-?dh6u|FnH>>R%T0F9{ps9cB+qnAY<Z!V2VvO=rMB
zLRlU$f})pv2FM?B=FV at Ub>W#wtbnfyyj5Dc2kZcJyljg{e*ncfUx9y*_>zDjXIkPe
zdepWz0MOUu%XdMGd~96s#sJ{Dh{>q+PLm3%X<LpGs`oMgMxOEINP1Px+Oiy=-Ox}I
z@@V@<63}ou6q&bRIGZm1rrxIsw?r$HTw^}54<%`7Pbcd?;B#U#4-N+zIdsw<6+n at z
z1K2EIX_Bq5vf)w{D|nwNoW~i at G5Tj9P@CWoEkHL!5u=I8!*ujqOi%N!M=#_>J21gF
zK3q$n#ZSGNMN%#A_ueK+*zk(t^JBh!Jqm~S at Ph_V=BU3Mr6GF3d>gg0Iho0913oaM
z{qjorMPi%8!PnhVisZ1zyQ_!1rH{V$gP!5F4^FGeyDKGqjB%!y+$`Ix5;oatk?%*4
zX+_m;6>>`ax6}|IYw#FL6*<Qe{j&aJb`thYcBtMej|wl)O_w$)njp#IM*aX&lNDOw
zYEy486kaGWku~d_&#;v-x^v1-Www<4^e(I~YpM|E1ieP?hT>AG1L_n_o|c^bS!xRk
zHGRGC&a>hfWnyCA&3Uy=#ekC at +|iy^$gYpgE>iNINRelrURD!0`OHRpglx8P_=j0o
zgs7obi-k<Rstr<Q{3by;6*)GJA2%7`4|~Jl?4+W*?R4351ZXG~cZ=$xO$L!egnr=t
z{E&XVOs5lRBPqyY at Du<cvH<k<Uf at jI=sTcBTmgvT%!Gs at tDiT~ZiRr<FWy^=%#Lwf
zsjHB#&rC^1*<s?u*k%|;-9`?!lfEQRGcs;lX_uDYYvu5o4`f}%$5(t_kYFDODpN;Y
z0vNjYi@?%z1ikhqn_t at yvASaV;$o_ui;5C%Ph=#B_sfPrHiPy+ at l*YTMed`~Z94&#
z(2wO5xPS-OC4Wws0Rj7 at LJZx^fy)*67H_qxY~7a7of7Ec?R>J-OUJ+{P?m%ah^A$$
za^<lfjLxVowooCkgffutuO~{Od$ThM{RJb()c($b=^c3 at E8!^Z`*>+f<v~f`bdViK
zTaRrv`RcY(BGw}fp2MLI3D>?b9P2XOvhN|k&+Pyo)4%N?=uV4F<;bllzgtCwW4@{J
z5Aw?BQ;pN!Af0LQ?J*VgKagU%k?k0MH!Z1lGl-%Y6{IY(b6&$)I9jm`YOxMzh<hSs
z(h*DhIx!qb^cjqQ!hpH?7^$-2$9Y{y2C>P~GXGk*rYGS3yDSB+E0Po4FKmU>qjXih
zTay(l$9CAn4zBJm&YYG(H%N<bd=j$Vd*(8-#Uf%N1pLOZx+Q;a4PF>p at Jl_!+G&aA
zph_MVJc`ryu(hq)f4ov1a0~CE`}6;3`tE2d{Qv*#BBP8_h<Y2 at vf`SlWRKiyuk5|A
zomB}X;VN4;*B;m9+Ot&GcI~ZeUdgy2{9Zo4^X;7esif0=o!9I6d`$7)XVRkygR#YG
z2~R$%ONd-E&^A(9E*m(+FtO1DpLh%?GScDpWetVaTov6Ej~ygMW=`onEB?4O4Cm{F
z(J{X50eF7Z at Q!9)4R(pnLCK(De`XdR;MT*gVRksXL<cbwI!sO2-hsadmk;MO-4ln%
zZgw~X?8y;MJ8fCKnUjE(mQvJ at 1rpvX2iWIO6)@ZEO%b^WM!2GR-YS2d$`e?9M`-{+
zigkq=^*hm#BH(X2v1o6TTnXfPz7FgIcRORff?-0AKqX-?#R?9zAmu|J0gg(=Pxv9M
zzr(Ai9`k!%7PEK%2}srom7e}#iGxPljd_pDGBuNR{uul6b=QyBNn|K{vt=D}QGUG>
zc78HOHYJLoIt{NHWpaA_Cs`|Ps&r&5XvR7-=E50yA;0xw at auSJfa5<WZ3yqyY7MUS
zu2av9YPsD%d-wVeh|ZESA7Ab3^%GN0Plk!oL8%C6oZH`1VgQ~@viy=`_oxg-gg4|d
z)YHX5<2lBSj{ca(!Y|jK?h*C7D~;xy at -)evbFHjxwbXnEB2|g?&cV^|Y23-#psaO?
z7CBqlw?9k1tBZTyQ^zb;wvySbMxNOJbZ6Ez%+*q)9Y}x8**|A;dugR7^T(7&juZSk
zMvh|n?~UK?7GD0(j9p2JWXfNr&YabXk<|&x^VxhPSn8qzoXwSNkuKh)yY#^a0}`h@
z4NZ8zJN}}+DvLb5`VWhKq5K}Gt*ODJtCOUR=4s9=6z=N((quSflQtt{bi~Mt58ZyE
z!h+AQQBN0mtr3*$!vOLLZ-}G6UBS#t8wRH7Fsw;5PPF{5J4Sr6KKIxNpFfp46rx|K
zOj}oO_K8&1Imzto)=kv+s^Hm-G~i!y)8`}%>W-&MrgFF5v5URYMieLWoE`{fA^QV9
zp?Q&Nx2|=4RWKi$Ch>lAUPhg`d(Ecuj2Yj^d+!6z-!btj$oh4eg9sBQFbH8xZCEWW
z*5Kg{qQ%UY>nZH%7eQ<8h&j>77qo71kmDI<E-~eDzi_ll#3%47I*>5S-elR$d{+D1
z5!6;}6@!UcbN{Jq$|FIZVxFJF8=+D>KlPn^*o73B{r|obG+^=17&WuA3{*57sgxD}
zBcLIcx{-9fcEfp^y0)CR{lVo%BZ-f`x?l72aQ0TZp~cq`1svO)-ejNsK3y*qdA0Gd
zd`g4Xlfh7>2Kz7hxe4CB!=8ODl!GUlW3;ImN2WS(b1X817v{88rKUH*(*VV^<MAhu
zvq_dULYGRYvVk%c5_#ae&Qp_E$cFy+FYOj;%(!u2I43{hudA6MrmsKIM5sdX^`%)!
zy{aPRFFjF_u<X=Y5e(0%Tv?r8l}ATyFKqRm#~qDD$6Q^j;<AI7TXhGU?K#m(c8>(!
zS^4jds^73O4NchzbqSw4;=%b+$f01A)PgIn@}}MB)t0JBD(;z8m|<&6axzvf`8v0i
zU)c5(`<(Ep$~i at w%SqWcFK%V_e}3bAZOCWgT^RTRY#kv!7yrq}J2EWHqk7-~wNoBa
ziZARP#6B%~ldtKz++qc<p21Ek)V@^Rc2|2|chfueTEVnYOQl<+%Q$KA4y=940;&*F
zZO#&bwo#j(^C<8vZxuKN>e=^W0=dP>Mx4ALlWGXyw~?6_uq?bm=&3914m&t9ts-%d
z7ulqqNy2eeFLk`4pSEGyc2dz51_}~$w>O#ds{=s$4q;ms)Sq}yv6fJ$I!XZ!GTfYm
z2}%aOoP|twWSk_>OVwe`xy8y=m!YrTOsY$0Mr=lx^)N|451m(MYYYXg7M8d#_h at -?
z;M4ExEwUqTEX7j`wdjlcT++IwE^Ztc1O1W^Z{;!zJ8`5SeJM~heHF8ASDgg$y*c$`
zl+$V~G+h;%+fUOJ1NAq#Z8XT`=@rGy88Eoh<fhidC&6Q8<$w97)=YnCoO!Gc6(984
zwJqq!?h{GA&0wp7PE^f?9BhjGJNwg5Q;VF0mvFbS5jj-{S7+TuTF2KvPms6L#{P>g
zXgO>ec7EqfT0?ZbURIMX at i1zWj}+k#ebTS}rDHxvzzu6{R`4hjQk7;>J4QE12*Op1
zcGN^}atS~m(I=v2L*Kw=&G%r5+Y3&y_$hy#PgC%;Jmf3X81b}`&H8=;Sv-$cBq8?p
zvyc3rVcW=xg~)p(A0$}DP*Z+VP7<)u&)!}W=q<d4c~zWMbg0#kGMwfr>^$>zP0duG
z2s5wgO<6ViPmGouMNn6#>LO(`64)x7Vhx&BJ7R=wQ5st*QK=qQgd|u{e;8#UdT9A=
zYku0P5Pjqzr(P at GQBP*3OjZJKC1UFWEr7Cxe_!uj*HU~hJNU%EcCnvTycs6=(=-8Z
zt&g|PCcgf^JYRVTEfCo82u&wJT#)+yAeUKS)d8k3|JgL^H>kXYf!`b+e%BDoz5mjM
zMRvxT4LELf2Y-Pj2v2#jmk+4vK8d*L1l}Wf>tJp>SkSXS`DDfEXlQE*+M3+g1|v1!
zy%zyi0~Pq*Z{!mJxcmxI_1<nnadAnxTK;0G2DY#p86sUNze)#rb+^fWa|bd|A2%qw
z at UN124+&Xqg$wqzR^%ZVe5+m5S1uK0jL}K~in=PX^FL9q#Q+`TRov=7a+a+ZCBJj!
zvdB6kuQ_=DyP~+-{RtD}s`LK^75 at 3-O_4V9by!kDlIfCx%9#X{o87o`n<CEm((G4x
zL1M6raeq%G6;=vu|2Z!~f)C0&Cuts4JiAxfb{1q;Dm(Rx^9TPkEdz?z6{gU4<Trwt
zAKrA%*$t)r7f&UOgXy|H;Ita?QA_Joqn`28Gsc}_i>XK<fgM=Vy0j9`*D;uv<fa%%
zLUOljXET{{qb&xO_k99^Os=Ckq+?rGP_V>JC`{A!ys*GO*0wK;GlVRtesDHBNT^NV
zdOIm at D))IFW<Klx*5v(2lzNrn at 4N3u4s@6GPPr+kp85+gh+acpt1vGuH=RFUbM_Nx
z$O}z;#xl6pFxp|_ASjsv*V;^~b??oZ$Ew?`w$C-iZ$I`3yHZhV)HH8s{am)P^CmRO
zWwlBBH*%_fKzgy_Jk?xmzH1JOxEu$`h^e~G)5>~^Ony*OUhy0k*FNE1C-%+SN%@7B
zYBq9 at 75;@kx7KHBDakkI7AHZ_uvpdEa=nh_Me-f at f;M|Bi`Uf8s^{j{K5g4!@IjM}
z7MVoQX`;E1nf?5WW+jJLv<n^>r1o!ocq$;>8_RW}tV!o at Hr8dLLW{U+yJr8d!S?>P
zqeI22>GdHX9=|y#_J)y=@NuNx8_e;GyXt9;XACIhbdAu5a*`mSuik^Jq9Uw+|L!io
z=5_L06AJuMIxbOsf_EzzXY!<J-jJpn6B&^|BLDm1e~`yT*{SxR`wZQ01V$mgwO=9g
z_9P{$b6qZWG^T!2{-LI3GfyMBpU-46`9^utfr1TH!el7BmlmpYbmYIz{)~=1?e^^o
zBU%KN$w(6gVp#I3Rk`luVR=UZBC{M{I{YwhB^>nTcBK1=w%$Yf({NBKI7pRZf3cZh
zJfWYCfrL~5dRqWTdA}`>uq~g at _H@?Dhvw?=!qtU6(VIrU2NCdfIoRqmm#@EcOAv<i
zED<3{HIPimxGi-Y&piBFNleBY?%W=x_SU8AWNP4{u24%YRdo26bDH*yWT^n($RLWd
zJ=<SIeRuN2=z&Cg2ne`1C at WZ*+ at AUokzB>^F3fXvX4^rC`eEK`8r<?K`CoQ*^kyb!
zf!Ek+&k9!B4f|uV4|}ARG!>#xQrgK1H>av1H-vxX-x133sWd99ZC?$p&vBGA)7{89
z{PwYVcoX~Dzz#|_5 at h|1hJ!F+?3O`jtq}B|ysYmcKL9R^O*5~b`1|sz$H|#4xB~Pt
z$TJx$OKtxLV>WwN9kB_<XVT09Kf>rFnprlKk_R#zDL*3EYw&R-umL_L#K7!7iZ9!L
zU at Q%f&r|`m?{U06z(tZYgO2&cZaMIeK!G0vLW}Rf3lN)RYw&DweCre#ayQamO(QU`
zA!hjDmHZM=`)ml_samA1eZ*6CXD55oEck6Hw0oibfyz0ROvZ4Lwn{Nfhg^Xs_mB80
zV)|5%yKfwMJ&HG*5`XOn`Hi;?fjY6*iZ;GevfsEWw;)ODE0&FJP$#eOQy9C(j7m=T
ztN#4(Ta;gM*v=Tf_I0TKq#mR>lKMnkrkpa#d`HdHJnRN-7aYt4S8U7vB20HMemO>D
z<IWk=?1``!0&^9*v&rQ at f;p#2%B)@^ZbrjfEXK~Y&!~nq*~Z=Q!#lGIV!OXDIobJi
zG%pnWiGi|gm1#Ly at Y5P!zS%CmST5Zi*%%X{(sn8wI6o|J{(UZ*Xdlrj+2)c=_uqV2
z^uTz=fR2g1e7SFh;!n%KHDlMrG%nij<X>ZLoURRzz4L$<yD*e7M2CdLS at SEHXw8@~
z$r+B1P+Q+0ilmA at -n=%p=ZH5dcu6$dr`lyTfREMc7`n024a at ijHZ0f{sSPgw&~jMI
zxUFZ<{TF}XG21K%bMP8SWp{X at 4%y^vuqvTMw1&|H!qNXuT0~gyfW0W~7j at l+-{Mv*
zbv%n_rnKZCaHqL6)v*q!LoLeR0)XwZsJsAxAmh<p-I!Pd_IA`IP at SaJ1Qd2xQ?9$|
z>xXdy5C=r#F=n>_g9z=+`<<ou7YwI#I^shwm?!15zG?(Q3qZWLXy7pzd^n!PW;mK$
zC at E~5ZH5CO^F6=e#Oj_O+l(d2nf{eJmJsj%-)}L<xKxz=vgy`nwd`bRUHHZYfa;0&
z=aak#<91>uhsLqobQRc+pkXT%wL$oA&<Yo-oeFvB89#b1D<DMnfJT<WlkC1aPR4dj
z`N=e%UsRL!XaDY~|AyK0e_!-J^Oq)9PF(Vk>?E;9tmhjR7Z#E%&7A}F_pFZMsqcl!
zi6UXEvoT`TjCyYTjie`(W>zuV3kUwdYN|l(hDrLyhwHHg^JrrfM?)cQL-2_v{rmZ_
z^V6C$#OJv-$QoMGHn-&84rvF7kf^ZFDQp^1Czj&XIceUaD%q?2iv7pt^}=9_W6PZf
z?vI*J&T(yLejg|6)8S!Z=lwqhyPh#vvkiMqhyMz%IO!s&(r3wkhZY@}-g=AjsctE;
zMUk?%>OfmdJ8QzX=Sm{ymj*#%c>u{!us!K-^-3L*r at G}sxmQx6GdbN{>Y$Z99gTtz
z)9U)#(<;B}dcz$NfxOM8`s<Z}WtSXXX65hZ)I2afnrs=^uK#vZK&Wg7_w9pnIA_bG
zpMkgy#s{`x7{he4aYv3O*;X=!&oN23AvZopZRiy+X(ErPk|xTnlX&q`{humDjE~M)
zMp%N0KmMg+V=oee7U^t|YIs08;OiYa#z)8FUJphz)AE^e)^_=UrX>gjwDfsyy#<Ys
zfbaH&Gj5pU#^crIgl2XRHgTAXZ$Q^q3;|G{2k^GUU%M&&J`nC#;Pr{pap{-q%F^uk
z81OD2JU^H}q<!okhP at mE*)qUnHDn7a(cLq(YWUtXpNdaL=RN(%VsRk~mAlix8wc56
zzvdqR-;t3bICZz6mjr)}a at B{3UW4T}9^Mb8Z?S|Fo7PUN9uGo;0InV?%QFmgHU~d`
z0ImNH;GZgM7KSqO9kwD3xA#d|^4aV3y?(@wON~z*_~{?|L)wPaE6HNNACl9- at 1&Wh
z%)3*THKoiZqMZDy=kNOJxr$8)4I=Z@&0tRb+;u-2f7S*Qejg}=Sv at v+Rq7*Yd|fG(
z8*;C at TX(hT4hSY70E4A71I8d?m at 7Z9ctIkk;!o`D&U}YGfj!oV`R##ZDqo-NHY(3j
z at 8zw5aMPc2D8&_x%3-5D^>c at ujY|!0EJ~$VFZszFwn*^>TU|DqjoS9!l7Dx&Y9dHc
z^vmRr4~8;jUl49oBEf1IS=jJ_Nuwjc^bcKnmhDT5Q#xggJ- at GRs#lWu^ik%K=Nqk(
z0q-LLhmD-wrT9(t{zUzuUK)r##sdG2{F3)K0bb#PvAf}Q5SzM%C-kp-9PyMM_k{yR
z1zzdiCk{U^9ko&QX={*?9+0r9qu?A6>`}_6CJdO3gg%9YxODR!IN*nu4#xi^?xsnY
zh7$KOYNzVgqVpTe)Sn~VQyyUIMM7uLg0tO^k_S2oO=IhpVW$VzZyW}v*WYTbLZiti
zBEMIBkIXpfW_?>;4<-wNjj~yOM2p}VaDR7_ at VF0u5Db}!Sx?<;enG3hopO7g5(d4+
z<o_(mkHhF=;dANYNU0w7JZDrKX!XLRxGkrG)}7zkppnp2P`A8zV@~9W-f9*0m!H*~
zZMW^z9&~1L@**mHz1dW*8fk1PX!H4^kQ=U@{Pi3pF;>_!Y1|eGHFHj9*P*atG7<X*
zd%st?5FhjdbaTiE5{j(}OGJU})Qcky<he}buB3|6MP_KXIXaNM+uM;99hqL2EU6qz
z_4$pnvy%X$pizlRqt)=2HmuLhhamrMl}dahskW?+G`pZxq_ik?>`cUkn8t?x_ at CQt
zeT}=uIdhY}TVc|*?^#K6ibsg}y&9yuEs4QEU8<(@_2MA9)Q=q3I0!IW0e{zmS?ZiC
zue=L*D2V at _th5n={NEbrIfUVR>uY#IJE%X+HikCrXSYCZRHfSyp(A4#5j;^=>(1_k
z(|6xK#_Ev?z=RMtn2cy8o}I`<XbR+^kOfwB`Lcth-%N1PR_60u>;vp)N!pTA?R0hy
zOsKh8Mg at GVwShYNK__9e+?X3JusGY^9J*Z<X6IBOW^g|Duui2jKC9hJfeUm&sBe{B
zu`2s#;+e1kdtKLmw~`v)(Mk=c`U294assVxGBPt%1=|;RL&c9y4<=+{+6{U`PV7TY
zLU%5*$VQC$qMPV&y&1QnQ0-NrCW<BczYQ{LgG{)&7?m7yGUmOE&USZqp*_Q-iJQax
z=*<%e6>r(|CZ2Z!`bc<NtRA{GfB9wug$zrloC?xlP13}!p0B|@AD``D>J|Mi$~>A$
z692G(Hcq9GA5_oX275m-3nNaWVS9K4p4ZaXQ{S%nKXl-K0 at bvq0@0q<(MEtH<7@#c
zNSVA~bRIRh{2cBzIBeTD3<4uwRcJYt;B`NDB#Mm}NXG2$8U?yz9uq+Uw7ysLiw7(y
z%|Z3PB<OzxUGu at m)(c@*Mu8>kV{WYpmJcKrROLAP>-QKjb^!C2^|s at -%-eDx5~#Gd
z?-x*TLQWS{1?N7BLqL$3&?P>Kj&wJvb!*EphUhI>O{XUvuN_r;!`E|~WtVvb^(773
zMN^T1UwYFImc>eBz6p=J1&Wv*>6Xwbh<6mo{$+13zn{SrhYCB*MB#3)7&Mm%u2neE
zn5ajwN2xmnKVwbyy^hM`8nbelaxTvlj2=7;J`nXjHI?)-YR&M?ZrmA>oYhX}EFH#~
z690I(?M#VX6QsUbp3+!|ytdPxOXWpUe1eX`QR-zskI-l-k*yqe81|b#_j5ynX;r!-
zj?H~OGb+X<j<_duwGJ})_}G at Pxu+)!^PJmZeit-|F5GsNH4{L5KgxxbP<+J>`u0|L
zQo-lno$%E2aPiP_^lAv+a0veGgvA-to*U1&9$*r`!)KEpOCOs495wRCIqTmIue!H+
zt6|f&VCwHYUBuW%zdZ4(?i-v8KLok`d&1iE9RcGzH~iwg*mw761N(uQ=ht}%qT>?P
zB}xDua{2C3A$t)C;ojo)_?_Mi*Vi4n<@Hd2K8Ix8Vw4W_AgKoF!O@#oLaqzw%E*_I
z{8m{8q<?uXQ~4M$YR$h=-KfqK at KUuI0G=7GvslJA5UCFaA_xF~J1(F6<wdK!QG*Dv
zqyT(C=qZ32oK+Wma8GU9qy-N-2nn4t_D|ySGuh>ifBXaO+0xq0p}LY&i5x at 9s*G>F
z8T$PEta0BvonHz4^2Ybt)TK4TEfJ8>9{=KLxRbbZ#J7==k at q2)N{>C8`QZW{`cEX9
zB-$^xr|kMK8o&nHkyXk+>4~!^nW(06DbtUW9pdga;u0ugX0Z33aRH<5&Cw9bV5!@Y
zwbS(*S=4vkn*sKjK6&YAJ94G;)CjRBD#=w9X)-cizOE11x^;Xa=_~oQu0}@vE&Fi4
zJJNGyvBjS|$6#q#rRwGFR(g`S#HL7KO_+;A$Y!Tgy+WM%y-IeJR6u($7Zq=0x>Wqh
z!$_Nd5O5QKss<WWehV-NL+~p*U*}1{@aj0T=}!5blqZow{!a^#`%+0D@?pTdwO2N@
z#aml@=@{Pla?APQ?|ExmdM at P*m(thQk>^=r>OJn3pPZX+j)@mU)oqeCfuuXrt;Ao;
zc+Ji!P%&l2{^F29aVUU7uGib)MH#x(9VRIikv-#MH(<*2;EfT9`|COWMsY?cvQA^I
zmZj{yFsR2Z;e|#gO|67}cwsiPhzF04{N_1j&cAoZ=5<Nl^!{l0_VCR%!eacX&g4vx
zXJg-cO9ZX|_QnBM!W<A5RVZoqICQhu7!wxhpgP+DF%Usn*K!@0nbX#(X^N_s>Odh#
z8r{g4O`wi?W-ds$=?0zo5<3sj<#R&z5}nwWWQ&1=@^xT{xOxDhLZ9ehf?1|}<C~%(
zg5AJHli^ZSiO##ZjF9kw(p-cTn2mE>PE&Mu{MK(Kz$U*nmEyASk=hDcF~?5k_A*-p
zHcuH<w;v at tB$7~0R at 3!0qKw-EhCrq)D&yjnT9l?*_dRDFJ_(N~t7lsl*nGE?V3b;C
ze7iHS3P2CT)qEHY)titr_!{h+URIq%x7&E=Cpi!L<`(?-Rc{Ij%8yMg5Kq^lF6VZI
z?>U6<5{VvtCAQBfm)x|ZQCR`TNY}Q?P0iJ`mgn4+R17G%K=ecB*bIBJx25JBg}gG$
zp+&Q1%FUg$q~UaQK at +ghe)W8k36jV3kCPOZKj;_I#k~X?<HG)zxxe`q=SV_q#_4{N
zFcHUI{76jZe#pzL)N^%;74dSF#LTA7yH)j^Vbr9>?a%YqExnBMCE|AuEKG(}lsH?4
z9gJmylk}mO!>d%W1vXp38P8pNULv~quOg5hHMot!IfY>qxdFr!C0v%3BJN&Ppud86
zHplvW-M+*&Ym;z#ik-8>i*ESkdOpQeD?|-(+F3mtO1VDj4*02B3|Oje(+cVQsTi&x
zKd&&qKMYN(>4MYyGc5%5!tR<t2a;A=_e?=J5nNHyMNaRgR&OjMmX_`E&e?Pt>}`+F
zBA`#-|CtNP+;tcLECg at XM4sCF;Hg)`4(Q<Dr^c6#IA*HFf#rM4`ReoWR|YfH at _T@3
zLeNycI{?gV;6`ae8Yu5FYG?8PTzCH!r}i~}M;4 at 8J64!`G4p)3K88Il0pUG~JwRgL
z(OYqbrjM&kTL0yK5S&0~Y0Blz8F1Up`6i{b^b_TD93T(;$?7Tj1#XeX4#Q+WR0kUh
zDUWeDJZD>(rKxW!|CYx56%~RM<yLZBx_3UVm_%m~i1GH??6X0_mA`j|4LlA~4&}}t
zuTL}gL(_GayHrPYb&rr)An3@}fKjgt4Cj`qsWSfw4_0Z3_>Zf6?e5dcuZd4 at nSmv7
zkvyYip#6({B+Ize$|T`*Y^bzUpE+u$DR|ggdWe$edRFbSn8slxJ|PoA;Pi|t2$_IU
z`03pUxE#B4CCE3c6J4V+;8*9rCO)41NGZQ0tGb<BJB*)OOvf1>jN^F$3w_ at P7j1f}
z+GElaB&L}+blm?JgQ;xMs5CF#8n2nt at t)r_T|U`j at LqPAU8mUAf6p5-e6xjIeQ@lk
zkG(8C4oRO#>CN(ooR@&VMb|J)xcWJl1-8GLxkyA at Zv+`;>lyj4uXKFavoG~)tSpE$
zalFahuU@`68NZ)Z{-i8+FTh^L({e`dLxCD-4}#&2(&)7Rb;Rp;pdT?(G-fJ#zO*_w
zs at iBy@Zsd0;rewv4{&A4%pDi&(F)_&q9Hm<F)ZTpra&`%Uu|1^yrmUw!=9FAomK1y
zLOe~_MJ6nURG-c)UY*S<QqTt_2YWrD&}l$*`ArFfh>&*_%v;@>+jnn2H}x!=@u~L3
z1OvO~QbDlNjNZBA>z5&fv-A7 at u+=gjPry^bs$pu=@BfDTvchc4M0KBBZS0f$nKY%3
zsD#7QzKnSyAAB6Ehw~J)>*0;4{!!S$1;_>R`aV~0KA2Z=<Lo|4;m9qxyGF*9J(6Q0
zocHe$GTOU9gJwEZ(uSqmcu2OfZ9M&JcaQSm##axY{XjpKo>!w*+f|?2>j?7-xX>bM
zf#6Emu3UnK{KIcCSq81-B&PS=mT?1lV?W_6W$wmuRW at 92Ih3BiF!~a{eM%ySvBQ?u
zyVN`UYPUneDdCLt_&Zx at KbU%H{H1;eZY$rgZDOXIu1uM_a=GaEep%GUs>IGD|DKsM
z!t00R_Cmv)2-f)u-S*A0KL!5K63^Mb{t}#v?U;v6HEszb at 7K^wx!nDtfY}|x&NB*h
z%{3 at BABd7b^4ejACX#u8n>Xz;iUwDkr&40-pH~Z=c&hfo?(6nfwXy1i<ph+E8pZ6i
zPF7<U)q8PCl=+W}*rY!{dHenD4`qFWYmndLsV`7zqEsi595<=^(`;bd_n$7X63ljw
zuKWV+0|(E}*`4g6nvj^ow-Bar-PZZsuZOK at 6;Wdn(y;|O#Z2S%nQY*7<0GsIg4>`g
zzA3l_5L?L<(V(RE{Sw{sh}ufGwlcGyknZKbvpPgj4QM(uM7MsO2;LyX9JY!$_l~s`
zcFS at Hn8`Vcs-wX#muAlcqCNK*92 at ml08S2b53yI5tU7Ih*T*UQm8WqSZ(m@?2X~a4
zyNW3>;2|(~JdwdaK&7r+Graaf`gE}?8d)+<SOq_RwL`7Ho}Ys_sOW)gMN6{$49(0c
zNNtr%y at _qy4nQ`K9gt}F?-A_h47;cWkk0s%!Tr5#3kO+>kP8sAQ<4?J`8VdwNXTm4
zk{H+TT)6rD_y+iY7^EeO%m&pp at y|E62P)-{Q8St<UyMUq;lCG(r{1{)?YL#=o<3Ni
zoL;R%R!a(@O(dbUBj!F)gR9<+JZCQ(&crGG5OCp7-^T`QeW=tM(zc5E9af7reCg at w
zagy>Mk}Di=hIlW^_zUxG3uV+9>6&aL+$sOvBvvGV$<|d%fYJ4dhA8~O*O>u&*Pn)+
z{{@SA8MLwc4wJI~nmt_;Fks-^E>rp2A8|X%IW3?RO9;1kH(qO97o|QK23#IN=X-l5
zl73^>G8?28%V(|UV7vLHG>f0CuQx4-*|<n77=R&a%TLng=;VyLMHlaEdwAh-mSHV1
zEfkgo%|=@w8 at Wm0gpf*0i~FHVpLv|He{Q(YA?a2>b9W?hDv5u54VtIxm*pWgKmhA6
zc6BRwD at S%PSXMD}U{YqY-kEOpZhQ;@NO3D%Od_(d0j0%oASz`B at dAsVdp=vfJX%#B
zxS^sZ4}t<L&cNs0b;0w<-w>qU6tf|{Hz7!vAikrNys`|07v at Pk9XdKX()&*btmgCf
zbGM<y78e~a3a`GZsLirH;ocE=2ysr%RMr7Smu+R9W{WrIVK?mqr&06Wb__rPHnR<_
zR$f8&kAW{|M6xyLP~(n|uTATt>5=sGYyPeuK$F6+`{+}-BU at TEt;oZ8fRYowfP%`B
z7q&F6acW(jxCspQUHN0n1#kusRCrg7)gWZTm*Xg!kT65~w?ce at AIAI|y7Vqpx@^$R
zqZrF8{9F5;6tiX^vSrUVl)vQpWTqU%GB9O4rf0JievNG}I3#98*Ik8Nr~OOzkVmoL
z#=`)QC+!=^ff{B*dTC at 4Wr=xIdtDv!C-cnaE53FsTshgByy?sCurZeQ;J-lw8l(rP
zDra}G_9)v9&GNA94-aOc&}+ZTdffiVga$Ky!m=07)$qqKrIyBDG1=llJc4#yrajS)
zWQP{s{#`tjYrr<W)SIQACIE3={Thsv{*Z`->zR!dyyh<wY at 1cDVZKi<DX<yraGH%X
zBh++Fc^4{z))n^asO2T%?S>f at 5Jr`kDOoZR7lUqPjbyrS4tHX~ecEy&@Kpv`wT=$+
zNb-cRSi>#Vd1)31Y5}-APF~*GINQ0;9(WgrRCYy7^l)S{f4zpT9(}~4_Z~u`slOW!
zk%#$QwPW6pR~qhRgNFJ6!JYYwD|6<~h2q(nlSk`C*`O(M%8StpSGRPH`tGwX&`J9c
z at 8rKPKT}<A?WKNcDt-a1!8h{Qd5JaJdqJKtkYw_?TbuvfU&qO9f{B^$Fi at WOUVe#A
z(SH{v)vq?!Y7bnMgb8sR#vO0!r3!(xYP|OVL_1b6_5>~ztP_l*rk&{Ehd4NRsR{_b
zflj)(l%l(gL|>0A#czKA7gNCj$hiecl^@V589572Fyfi=CW-$M5}Mqoj6!~ewxy+(
z+)DiiC&|5 at q`)^lv>KOEXh&nr3w0vtS36uNHY at IzMMOgHHYk~L6fjGhzUA)>@I3ib
zDs9oE*;uS4ykTf<7hpA|t{wOl7L#8yaUFFKm at 87(beEzNRdA-9IU at 7z4!s0T*{Tt0
zSeT+qa1Iq9xeAT(k!pt(biAOd=Y&a$A^(G&8st348Qa%oKt(AX!RTcL=pt`SV-M~*
z_vz%A%V at 4M3@d9hKVYWx54fqhMLt1&XYk{_Hbn?`2~CD~810YYKJ_;7q2DjJ1vRRD
zPGu|q>uXygKMN5+zz_{EGfS<nWhtqTOO9>Jwi1>dFV8CSM3kN;r#Q`QwPTncFY60r
z6Z9P3o3MHRZ1Ai-Z!6t)3ZHQQSeG4n)}N(r&0p}fTa`fsF(Phz;@A at pOWhQy&3$FC
z++#<}EPs1bhzp^vOuPP|*OrD~-}c?L(%;5%YYc5sU+MBRY<5%Y9iPX*20jr~Nsd2X
zd5H=x at NHj;Ctd27p~*S}aT9{Q;K?!q>7Ofw;(-T082w$tQghJS@{C~0acZ2)d(A*Y
zJKG1`o2;H5T0p<vEDd5C|8`ZZXMGeOU!r4X)5 at 2%*G;u1Vg`Db5MFIQFpysED!;V@
zAucxBew;kgp<zJ`xL4~<S(JRkdNBKMSzLIoR^vI>bn17m at qYi~WQe}Y1X7fW1qlI?
z;yz2H(<YTnB~Y2 at wtURzX8|?`dBzZ3Y}IU(+jYD^$Y0pW at g;%#4`U;Kec<T!MyOu<
zosD%t=dcT-5-S-GUmBK}(1(%5`qoB-x6GVjv#iH@<QQ(TK~{{Oqtfn<rB1&uN=4*6
zr7Q2+;+>CCH*Y{#?g=7gh94F_`t>^#cXxg&N{w(lr*kw!*JxaTBv~h|9IF{(TjkcF
zYiZsykCL<AftIE$=;~adp+1&F+%OlHqZ%pCp9~$`uW5g>NDiUhRR8<~dvmlqpC|Mn
zu|zsPyyVdpbJc^JL#ZeGbh5tAW37Al5L>RD7LrY}P{T3pcAx8WYm0_EB=k%InFvz9
z-}9%=-bT*3RH#}O9#WpCa7P6Dp)oEKvoMD3n~Sg-Bu#pPP9wU9o3A_lw18YLbJWBa
zr_C6}NWcg)j?#;DMFkxhKQbs1GmD&y&`(2O7PU`xS8b&72oV%<k0 at x!^(YeJ1iXom
zsL{x%f!`pO+`aTqMbV?hEB=C6CNnktW}sg3Mno~%hDppz)$Siu-R0`8 at hu&JoVspU
zO6)8P?mgZdKb_A{@4xnFM_hNT9^}-7Jb8HdPRG6qXq9*RI&Ds;{sj+o!IOYd_`BJM
z;mWx#c9t{%uqixWcgqYDL&5GI&3CYW`o0<qnex)7s9&aeaR_(|@HKy+PJ8A at W=z*X
zywas3tcSh*c>HYK1g#sRY{n^gd(9;e%QbN_^=!K>{{u^?xCTtIyHc?sjTEHs=U0RY
z%8H7L^ZyB9#(#=jWi#LiiZ+ at qFL&R!Iy>2Ey90)eE|B2)zCXeDi{0unZ$noOe at abH
zu(nT~zk9b7p>=@5e6QDwsl1eqsq}5VLybcdYN^3vo&(qhJt*(Z=Fpkb+(Mx)DnM2(
zsaKvtoGyt6O0Zf8)I+;Y=lHj2ggLS}%s32gA^o(b?dv03B^y}_Ni_=e8wy=W?Wr_3
zKC#Vgr$5iF4W8wgs!j24JD4lYW9MHrB+j4joS(LBVk{|4By&%<?3a=W?&%W|8|*dU
zf2q*>m(`hLP#)FgKL at WSiAR~`{I|;d`L@$6Ei5knX_h4`MtXB+ANx^_abBtHKZIuw
zN7qw2f4z%nw>b&R770k(iM6tiZuPN)?(*|hY49$Dfz}ohJ=kW3^?o}_G&ic2`KTNN
zLSS5eJmA^32rUAwC6xh0Ns`&n3Ki}i9QJS6zrHXtBG$eWjux>Fz6c#L6P6x(3h5;s
zZYk;+=#hrDvb1HqcOkm&I7?A+%mue$v&L2J2i)*`FIr~Dhcgbv<36U}m~AyEG~_Ri
z!Hqloyds~cE;7qn>^&L2H<t}!imN2&8!fz|_tk%@M?-AQ|DI!jHXZAoa#nYK4%#*3
zK!Ww`*Yuqh_pCv2)8m at 1VIU8JBA(U{%x!%}+az`bOE1ygPs0Wqb<Z}|<E?ie-9qT^
z1M36?;H||No+R7#q8|1hIRFFv`hpI<Z(~cuw<Zi5_E&FwlGI`LU+a?Ia{Mw!EV9LX
z`*<=}I~w^0ooD`NbzQ(%NNA?^DWc2z7r^Ik^ArDsm)xNDcTHCL$Psso|KZf<Do4?>
z-yrH3C`EWG;Wxmk<sp%+;v(uvMht70rsVzkY&NDYvbkT%I`g2qWkD$Rlvt#bZBb82
ztX0SnE+x75v)f=`B2KrboYGZR|8^BQhUY4b6(3#I;{vHt>4Qb5RZq{khu8L>10p5q
z%1#zE*7GmY;x1kAdaYIcNXpCEbhi$T0-vg3Wmkbl_~U#LgX*&Qj^F_W;x`Hpc9>Ve
zXgFmBste(TpkCKhU5$gjGa1u7{x)7mqO at EpU-^CYk8_SWe~*Ggj#iQ=QB~m1Ng0-W
zYl=$t#B8g~wNhlwmr at 7ohl%own)5l{ZkVrd38M6dKWrE{;2Xa4=vE99sm<pYyXlGH
zett^p`miPXwEtjQs at y#IaTXsI56yARfL7Kl*)W~2aV0*cIxySehH||ieMZa0>Y_qZ
z?W5NpK6U~qo at j6eZ%c2KHw>W-oD%1%BGYyaMXh at bpnO0(Ky=fp;LKBxFO?;um^MXR
zfd{~|xh at Oxja?d0nR9`k)vBd0Nn3n4L53XgzZqL=YVRdoe7MIm!pxx?YyP~s=M#5S
zt0}i3G2>!TqtFDjfrI6*&g=O=s1qkbn3!S_6cESw at e_<(-IO&LJV<)z{)Ss)HsgxY
zmfUxy3aZjU?n(14g6E-zQp;xjh_3ZpYo>wMJr*VXy}UFp!p at HHl9OQIGRkN456BAk
z0AqZ{kUIu#W27`wO`7Tjy9$$ifx-8%2hU??0M{lCGMl#M0z5#;;_}jmztvm$!))oz
zS9SO-s{N}^8_!d6fnX9#4ixA!WkZ?wdY=s(!+#tC7#m*v529sZIrKx~Q4+l?v>=O4
zKfOP@?gS{)Q+G)h_^jL=J7A$K{Ike!A35%2Hahk|zriGN6f&el#=fZ))hbgPb^5yD
z)|CV5eeJ|Iext%g)!1!}4#Wx;vSM&D8A<Sl6qwe_B9{;Tt^^Z>Uk28o&{|eyL9+R#
z;;sDFM_DVZpKjGlRycibSG}*~AkcKQlBpph7C6rNJO76rcke0gr&&E$C9b`oX^4)e
zMALkPy|p1|%q0m9ZDS4_Z?P#8trkOT{FEs#N^^xZ8T1GQf&$8fW3B*w_VT-=`ut{b
zWWm at JW?w(47cMUbUbbW8Y#Eozul*b<>o$(~q;S6lJ1LAwviN>TR7$B+VJyP(Jaovb
zc at N$^vDIqBTSmuo-$I)?l>MG6{!}qRm;Qarug>ELUj{mad37qrXZMR{SYOLC4h*IJ
zf{~~n*SEPeds#Z$n>fEanQ`82;xZkfX8Vi|(mBbZdq(g17sE at YKr5$V%pz?dn9sqp
zSpkH_A at W2+TZ2o_8jr9jBM|<XVDbF<0wZ??Wi5CDQ$^wZXVL)p(e*z*onCqytZb4a
zyn7PJoeMs_lVHV at U;shKn1h<;;$+b9-0K)OrN0BP>VenPVwp=w5RVO-(FP1J=TOW)
z$euy=utUk+ at P<-j<Avz1dJoqdpIpxo%=#aTmj1#WnG6%Awr|b(wf#xe%Urg7Ydh`s
zpo{bv)#r>FvEG?|Tj;L;mYiw2`1?~GYWCp2$RIz**@z|nuMgAp`gZ^5wE=kdH^4IU
zOmeH!$h6A6vqPlGc}RPb#O$LjB!iuwZrx3PTt=0$AwydMqaZ?%kx14#S5pALN-6Iq
z7$??jys_%U&kq!Til^!xFHs&O`8iB!mOdSTeSLFlc1DXMA6o*`@9#R>{k_Q+ug=HQ
z%oBd0X(zeK3uVlXBI?m6`@KbF!6YyC+j<jRly=7 at rz@r-bPO7dTRZ9`4~ok>H<evE
zXD|=`8prt1(>n^qaG3W+#szEL_b~l^d?`7R=iyA-f$!S6=ET-z$<#ev35#bo)wf&=
zEK5^Qv=w|I%A~5e>b7Oq*X&>X^fmJ}U-%gr?kkbR>5niqO~^ycJnj~-A%h2GvY?#;
zq4R#mRJ(Nc#DBZ~c<r|T8a5y-8|0*|Dj1JmxgK#@PGNH+CtMJGBBs14fpg$L$8(DZ
zYqdTVJxdV*U(_>M at Pau_Fme>8Z!x}C!7I9Lo*!*)?iDS8>$&R{{fL)0EFHAF#94rG
zmsoWhnSKnC2Z9d{o%~zG`fhFqf3g7CC~>t|zDikuLWlpn<h~j#uzwFwn6MeH<#z2j
zw2DY#Fxtk;$(7D)On!#zrG(h-l$?h-Z|_=A&D$@UvT_6YU7)0SO|z)~vsM#wp^<3E
z^-QM$aA5()d*7Gh7hAbs=lyl3MVSU}v_n~c7u(x6*e*OxeHyjsj_wNcu3?`!a1i)#
zf3?H;PlX!d)=>*`P0&+QXSP41rU)8drH?d*GV_)Bp8j3_fJ^;C_a<n8?`_VvY<3>$
zuV-_3GwOHE+VrMW$vPG2^1&^cAJ-<|R~^1UDlLb}ehz)$jl7mI)*a#F<iKymS8QeH
zx1i5Vi!2Z3Mc5zafD-ow^AdCEZ{zW?FQGWyR~;&5vQflZ>gMZl<$v5~Jx~i0Mi$HB
z^iPN`^xXI-a+;EzLT+E(Q;5#Qu2)L2h0G6e*`Nsbeu>!JCna4`fdkOStYp^_B*6kP
z%e#FPFaIBuUHlDSo~%M66yl^!>Q&$d5_sN1RvP_1cpIJ7B$t?)LCHd+cm#5v#>tG|
zq25O5w at FCV-qK*vYf)q*hwt_qnRemKo{ijoDN-H>Qf+oJqGudO<avdYypS#B=M^=g
z_g{-XkJ)jde+H+OnPepT%-8)x0W4D~D|R4hJp5lcd-1fO26MLN1D%>SvX2Gmbv>yj
ze+>Hr(tH;FJHn?(CfkDU%<~6QQ>>nc?R0L at C;mEJO0i^DnS`?%0&G+P1u-S*d_#4n
z+NC8LVv=J(t^#msFhLO);tAZuc=IxD6N=ibG1Ct$qjGuqo$Bmzi*(D?4h25nwLqdj
ziyx56juC2^{WF at _)t_j%`JOj?EnA495XUew-#g|2GWoI?e<7xfh*OIhF4z?MYfOyT
z%n-TV&ALn*r&z$!8#>!B|H}TGv|W7DsO(MPTf^M~!nSD+>}SiMEQ4Xv6acgQjc4yi
z9m<lQBeu%}pJ%$#8cDt_BYg!myRW;NvU6;IxEe7RWyG*XY;ddGuQdNG{79e%&Uv*N
zx@>&ds-nlL%qRgJzr~;_OkP-ET7p_xbYXUkUcW%&c6 at FR_rL13TP<t)#m3=rPy+<F
z1_n<OIexvoW+1R;rCVa^S->02d2;fys0$sdaQTPaE5ye`&Obith~0!_*sqxn>T=L8
zNkn(QI^UbjEu|{+u`gC%G`uXsuK(K#HhwZ|Oj at Es(;TE^l;Ig(S8Cf!g4~2UGd at E)
zuUXsaTYiEw=1`-H;RejPX+J?tHJ61_`K$U}TtyL7j$WVMd|k;8?ccT at v2?4fI*U}?
zycTLOT$#7evHY%UlLgy!$GOn3ajkrPn^pkRYd&BAF`!<&oCX~pRs8-aKKD}G5PVI0
z-xV(?=fL0MoM`IYkoW`Jw-HMS$$DJ^B2OUT?O at TBwsF~QKgtX4iR+0k6)Sn!czV!+
z?&1n$t_4Ixw&XQA5OmU?_H2yTGe9S2{X`;5gQjvS6JOOysW8HFL+h<zkP$gZ at x#x8
zZHxs0_A<CLkS?OZpnY*G#};j!3I at tpJ3%<}9Jdv0DW1_-ma%CYYH0?2cIk1iVgIKd
zPZZ=M at SQ14n)21`0-fS(83g}!u2cmZM11xgzr&R@$bT-s8QyKRPmAV6&CukOhfGWP
zRH+?*B5MwI$_qpII2GW6y(b1qo<?^iZyKawl|28j4$<WI>K*hut`1vOU%G!;>>0|%
zmizE=haSsxzaRSw`_qc^ACZXmajswdm#;izb7!hk6E|h>Mvqc=e!J7v(MRe&o!InE
z`|TIRNA-^;ACr--`6DTqZ#G)_W;zA-ej~wE72mBW>`A;MTHC*?H17$aib7L{x%$;4
zKcnBw4iu at hYfqk)E47zQRJ%tb at IhK?eY-guTgE>fPuL8)hNkm-y?L@&jGh16n6psT
zr>GtNrAfWv#wp*YjR>~p3<!3}9$|fZY?FF<i at 1p?XfB^+gFM5uF&C=SY{)X^*SX|(
zJ20OI{iZ2%5m+!w+cmi~cSNDwTO!+HlzSt+UtP%H3KP7%mA6EfR1!j9Dc^t2uUoId
zW0mB*bTwj+KGQ|kn7J73$ZdT1<i6I40!dTM$8SwA21!XFyJCZ+;~!Vv#6k?#0ZVR4
zlx--CgG?2iff=0xY`Z@(Wga7~8eG at CqB%!N)yf&oMgXV9%d0z8k$~=c$jAJA3MBKP
zvzgx4q*<`(=^pENMi>6jx~tRwx=2zL_VE9-0Fk?Zl~{*+sp5C at oxrJCVy?EQ$dT<b
za-K0o+iV)nd>P0cp3&bnBRim(b^tF>LX2-N-pzc%EtuZ_t62 at FeIj0NC^7X8dn{w}
zGxLeUz>ts-yZCw<Gm7Ro-|&zy%dToQY7Of at 40VrMpEw|p_AkD_#T`wOnhT83DI*@S
z+0JvxWAVw%a7zwZ7zdAWQPv5Ihb3yE-MNGR`N<B&z3D1%bi=y;pu65P#^k-W?oo1Y
z<_7{6rvGR>)$g|g7pF|8zOGcmy;V)!rj4cyljspczlxz!@6>5m1s^IYig-WWhNYsB
zM&|E+#)oq1?7uB28MeH&s@>d7$ijVYl}2o{^RaQt+if~35`n~4K~6zot}eNJi(oAD
z7wP<<zU7;&`v=)UVRQS<j>Bpt?5n|@L>}jlHZDO#_#bN%3PaW*^E~~E>3gs<O*&Kq
z{4f8JS^L at k{(gT5oL`CO7Hle1aoD>swl36$%4T3XwY-Oo{-E^ZShv<fi)2f^BZXF}
zIie$j?BgT5o?x6}%$WQ#*p;He{<KXQFlfm76OB~rR2X>dxU2LMvty+WVYz=HO~4se
zU!vEK?hb8LhtT{>3BchOHgT0WY at L|PP7mFyefiLoee>ZT-VV7vB6iRHf71Qfku^}5
zmK8iu?LRzhbBJ7+SQ-jDCx*?Jbzxoj)XEk0F=4|GZ&bPrZcNI~a24ZzDWf_7rp()b
z&hv at P6Xf4D`@-`6cF}^t%$MQRCzAwx|E9n?I0b8__2<Hb;xQ$N%#_krh~D at tX|mPx
z(mZGAv_luW`h~ftv>6;Nh`^zO4%%k7qyPLxX5vI9w@(;4jLnI`e`|}6;Q7l2_aZT1
z<7==2lfTik-LOrw(p%1|uAtT9Ip#9e-VJ}CT5Y)IFQ`E4FF40qTQ55J!L8 at rHy@C?
z{hA4%t!`?%wI+A+Uc$$TldcuPudA-(1obODtX*a4U-i)&&8d_lpf<|bT*VEPzdl)9
zNJl^pu-|*26}}>>^X%fwB9^T)S8vH)-fB1Y>!YZ*&oWJhKW;{yny*WcdPRL;{w0s2
zm_h|2wwb at uU)nIOIrn%n&02)I)9}`CY=bkcJm3iz(=$)=mnVnYix)MhYceN|UKuUf
z<@b-4NXOjtqsqu$v17+9ZE@&sBN^4CczMQ%Li5y8!AZ4=Hsq@%!H8NB7dsb&NwO|%
z7vZ936 at kL+4{`&rP$w}N?#Uv!-FbCzTXgog;kpSB*M8tcGuy6*hrT>E5mFFz47xON
zaG&;@^3T&O_6oRQhS<kagG!R+5~6#NRrK%ozs}CjLq2ua-!*-rC=dis<6o<qH;yjX
zADhF+YHUkrT7Oj!fM%8b%i^PK?c45~#RDwu=Tr?wVX&pM{f*9zy!_rZn!M<NiqHYv
z1b at P$Otp)7O{w*lg^u{H at w{(!HOufvTP(&xDQ{NKj6b$(Kf}0Sh0DXoj^vn$aCrrh
zI7e)O at Z#ZBzOT<q=iRX{LcCOoX>(pIl$s2oQb6PJ0sO2wr<vh80g<BlzI(DS#2ubr
z?A-zcBh863 at u$fBVk5P6(+XD19f1e*{(^5p!A+D~Dy`<Fx;hQ!AI?l2R&%uX5|0e&
z7Et%Rn^>8O{0(G3I3-4C>fJ7Opp?ZyFUVcHIdDyC0(R^hUVb;ZoQ83L5$N(Q--)q6
ze__yhWy}trT&1?o&q1U&{RQpzM1OZJjkc2fl3ZEn$AfECLC*Hh{&|#ceyLgf(L&D1
zM|2OQYt4CPCsX7(e~Pj*O#L#eZ{B!FXR|&!&9&;LAigV`xzl4bG@&^xwJ4R15JKAB
zdRtod-`}Z&MlU(X{IKmka$UGDn`7O9Iph5#(fJR}-ZCFh(*+<w+vrZtus>5;0wZPs
z8TNW0kE-$Z)VL$n1KLZdw<p+UDGW7%#5C`?c<TffV_ajUYR8#JtxQOQHkW4H9b~ie
z`5l5Q?0Z%2flIs+?K0OjFkTyCf{~`gD|j$wU_GI4>W`28QY;25k29D`;IQqdZf>%U
z7JlM^8!#DWoMWe;(6jr)+fHF^b25^7wX%W~V~@W)z|)1 at A`4N?ySuGa9qI8!ojT5J
zy}XBe*)*FUX53O)l$^<~{AI^f^!Z*_`N;84gYZYpU$*V=gA)2%sdt6E`t7v5sa|Zo
zdba1gEp(J%0o7rMK0aVANp`iV{kCu^+@*{|a#(SrTAaK3_`#LY_xFdHD4v!|8JB;0
zIbLDw#>qc(Zz5T}$zNd2mmMD7gtifDx_T*z#3rw<Vq4NHx{jE}bt at YBk$q10b!Dy!
z;OMtOzK#qBR0OIHJZja$c*0gHWnHiWbmasrVl$0mO=P>n%I|5hJ`WWOKL5DlpOGxA
zgH{o=Z at w7A6KY1z<Ux1D<}FJYbu-#~9zz#TQJtC2^H+%UnW+%L5%2wXq%+Xw6?+{Z
z#isR*4j4`rqwiQ~i0>?3^)y&EMHFl};P|xW9HUn$?s3$?N+G`;sH~#9NeiG;{NH>h
zFvhj~Jf%AZ1mme!689o at P5us(@^?)|@UXx6w07lESzU>Y`;!`G2AOCMPv$ELFBj_{
zj#LM~1ne|xVTDoDLf3hHTB|UE<2LG1I^Wk+)a{k}8;>*jo2Hq_Sc2VYT%Z3bE%U&k
zl&Z>g6i4tiQFAAoqJ>xT$ad5*$4Bk~Q8pCf$qch?o9CmCv9DYPew-Sq2A<EX=-nIX
zKc8ByVzka(44yc<KFI2#&g=c*_UD2CI;#MyQPWN(p|F`r9*1o?O--icc?&Z{?2F-F
z7R)yhn=PNA6w1g9cs2X*r<dz~rJVn at OR*fqCu`5O$PiKWZp_d5BljLN`>vOnB4?pP
z>pu!MY)My1=p9H)t&H15aIasJGKx`9*&l8+>p?E_l=1{Yv+77oyr+~(@iwRL^Iu*b
zey>+F$>rcK_^>XD at b0bJ{#=-Y3xv#+H3&K+=Ro;(OIupXCEVFekG~P!#frch0YA?Z
z8OC3cpnx at cA{VXF(~+cBTC+5*l9!*l!0gW_Z#Gj6%0vDDtCn{%&nhd>AxcC5HR;Ny
zKOk$>lHwUZ@>IvOj}Yq6JYUJ5VNMY at glz`dJnb_+p;l&4xv at vl5SYXtvl4@*6E9-r
z4<E1S;prB|0oS;faS%-5Y+D%KzwUEoLS$`GENZ5UJva-#C3o^~4%=}Cu9- at RI8xMD
z&(O&(y>Ld!!LaNmwbU)N)IxdeCzaWvFZR(tRxXcs*=O5X5eI9R at QNE>1PqOv`p{vf
zg3G0)i`yhladSCttKW0n8oGj^`1vp5N!LsdF`vBjkuP4nHVj;1l+WpkLx~Ak&WsoR
za)B|DXR_DSnh^Zn-JU1(#B9#Te)JK*RLG|{Q6h6~8VZ&!aVXJXVL>ZD`zI|#XDR1T
zD<T(z1qUX&^Scnx46&~nnw5uheV;4_Ev`R^RinR(tCPr=j{=hTnIGE|h$?T(Sj`<}
z&o5EL|I}%HOGQgaxv8eQUYzJv9C@^z!V5a;$joiT3N(?`mfRA^TGU8UMZUxiX=rBG
z=ABW}?}uIX`x!dLUTY=CGhNz}wJm*cmJN%RMg}{NOx|loM`q==?k$tEre%XWdCay+
zHD3ES^5iY^?MzCb%>B6?iIh-CdA^C0!AA}1<YteKt+OLgMy<u&tROJ0m_<R6*b9$7
zpfWJMTzmuP=yxC|#<gDtg4?>fF7z=8gjmu4N7GqHHTl19Tv|XtK|s-=ev}#^0+Se^
zh)6dZ-QCUT6p<8xAxuX1V04ZYK|(@c)aZ~NN(zYl9=_-N{6qinaOUyZc|Z64zOL(a
z1^ff&h*$FesX1_CKzOn2vlDL$-$pp8dSm+&%-rR>Rq83x)YGT+ceo2j=9hr7V8@}M
zkD$NH3FWTt-{zZ)*(lz<gYKlERkC)mjjlTu22<{dZIMs)1+W}Y97}!5(@&X>uiU<X
zl)?bQ)3~nml$r}|WEbe at -i)x2O&wIEg)_o#Pb=gxt&&pd<awpzjJ`ayAF_A!cjLw;
zP%Dz`oGd!L1OB1J0mKjWskK0J!U5`CAhw9h-`^fo;J-^6sqKGZ?--DvqcPktJha(k
z|L!4vqH+6SqRYf{Ec+7}mk^J^r+j^Dd~ALio!QJ9P*v}djS|B at 8C&fe*7#57n-x`g
z3dBjbb1^3-;()sTpQHjEoHYGRJ0*O1m=>FHURCa at W&N#mSFV+}J`DA6XPxR8pN<gt
zwzyrBD)i74|8S<m*`l&8pBE>a!zm4Uh&0iPfb1=F4ML0|0)$!ulTr?$fBp<nk6}A%
z_IE{Z4G2|c_kH&2YnFkII6ji0*1;5d*eK_S45f+OHc}Mlk*k%4vs>(@fm!#=jYIBX
z{vx|w{#(gz>}!rlgYK}Bm3?o>-3>F3(tU8ZA_#A_-V^u&s-kPB`D%=&Au4kB-w?%h
z35>KQ;!RB7a^|p7N3jtG-_<Q}x<8~BPv7*27{)MZ5mf%Xk}v)hTVhP&fm_v<-K}m%
zSKU{l-c)lGpU|R}4>cuH(33v?e2IGTsSOLBlQr|coXFMjs?zDDcm5#0=cm;xOSbwQ
zc9I%72Y}aRsA|mb3kdpR=NN9%SnG{TZ&Qw~iutS{Umfv~SB_Z?r>RAU$b1hq!uf0f
z*r*M(^^63{E^Ks(;=^a>gTEWNr^F4m-x+vGpl5!m$srum at k82mxJv*%SIDBlm+x&e
zfZcQZw)|xx-7#NU(+ArPqRF@;`d1B#?7ACJ=${T8PGDQZgVH7a#mZzDA3t$wy6T{{
zrU_8U-s$oQDq>7twM}sl6FIV}a>1c7ilF4XbHSL`wO!`=#%nB6FERBigXfiH;hS#8
z6%>Y(S{dXq<<bKyb3JhCK3RPjm<%7DeYf>&jxr&Pyo5C9x6L5_FMxs9f$&D5sCTbb
zwMuAUV^ChC>klPvwyYbji5sqkUpHKG!P1{jD$cBSo;<ytl)52kOGQ=?ia(l1Xg;Dz
zuA}RoD47R;GG at h*w5>P4h5j-;aTV|OnfW_Q>dLH=kzQ$Fr8^2gn23Ev2Ycpzp)gRQ
zUFoP=s at N)9)`<RFct5kE*>rtB!+qmM{9a#cO<jElpGK*XdsA=g@!1W#<-$MF2ar+R
zjbEr?YQ2IeF++_H|0O4Lyx;###d&@szK at J*e!Z^?bC6O{rq6r<c%?9pjy(1agZLI}
zfIDYxe=U-wYoYTJ<>TNU50Ca^TUAO)+2@}|PS%9IpI6R5>+#1F6+z0W;;J;Wb*(Y}
zoyEO{_Zl7N1>V()LG}HGr)3U3rC!K$2tZzU88SsL(+|=#^n7{(_$EM#>Op|GRM{8>
zRe4q53cRfXY;ALg-^ec0_)qmYjkZJPUd2cJ3|QYjV at b?xL1ol9$mg#QS{T`X*!_N|
zJt{0tipBp(YZC{=j{PS980up8^q@~xO1f+3q&RR_4N3)cuuSLNoL at 55V~9*(VXCn+
z(D=(Vn?v2`C=;RN9(DUG*a7(1?io%)AB~ph!@99gp!WjR{3GyL#iX)8c*elHp5LW=
z_Pg2$cWbw- at +pD-Ovl=y{c(}O%nv&g%E#!`&+(Jrhs^~G;N{gbJii1F%=oS4sLey*
z*;?~Jt#G*1pc07O+pNW<474gesHFpOLEcI3k*L_iU7YUMs*{Z(eIR1HW{5?dUz(oH
zAb(0a23E5Aj-D_(^qka2!8bi*U8GZ;t)s<DO*35s6W)AWJv{V^Y~xro`W0rc!J7=>
zb=;p+v%_O%auR2B4isT+Wr6AU`#<c4R^uIbEs1xTJUIC1wtU=n-cs)<M`-vo2%Eqa
z2N1`hZZ7ucx;HCNX1;2%p+MNMi{#j<{R~XcRuaGU;FhkXXOv+1tLEpZT3))HjzGGV
z9X1^bj|GVMuyMQ6a~5en=?rcR*4}c^erg<2u4D!^M*U*GX^8g0=GJi1muD7dDKSpM
zX4iEeQ8LAiB2^n(1PbyH3q86~V^?zJWBmp5O{v&!&RBc?>>Y%9!cQzd<YN1O+lTH^
z at x^K14FG`sh?@za*IU}37Al|d<MJudO?o-NO at 6(^U`JdtL}bb32Qa+crUS~VV!@n}
zWM9LbpjT}(dnU7*Gr&uWDH;F``V;`Mif-0|q*#2ZkO469gnR*URuY+FuW_2raPbkh
z)&I12f|O){bsZVta{=g>bJ^vsC93rU{tSo|@ui(?mCwucdnLhIfQ9-W(5iRe)@D_j
zZT0)V$v60T!tqWumadX_-Iim>CARbh<u+4%Hy=UHJhZ&4HtHBVw>S|~+D5ZIaYyI)
z%OIarFYSyDGgy84(^6%w;->{JL_nDD?c#oC|B)@cS){?)2M4jCdpl<^nY;0_XYnL9
zcx8s1-}w};aqmFyJ-$%H)tl{dW;C9|(Oz#SKCN~|F)&<_yS57U&c|_k=czt;gfsqo
zYKf6CkKH+rU90?i>N|6elK<|F3d|hM1RLn)3GF}+SyS at 4c5WuJ*}nAt*<I({kdLg`
zPdBX6$4xsV22 at 6rl=|qW=yyOqY98iregw5Ve{**n7fdK*y}8 at OrhI}pDlhI0ooDqI
zZ7SN*%=UfnX}dccKVd`VFLEvF1 at v{fVtF6I;!jDltCoS_&ibVBOn$Y{PqI6>_5Nyu
zG*7q!g at R?DbijJ5Fqk>+)~fR!@dP12L-X9SO1v6OI>RGcs9<?3zpNS at S~KRN6_86q
zyALgMTGOi(X at YmU?2_%!8>k92CR^xp`Pr9nlEoT>@8R8=8)e<R84zL!%SV>d5?r%6
z#vOp1R971;2|Trlbn2q*e5Gu_kgT=MtYc47(D$~{l6fDfaS$D{1;$=JIL|-x at 3ncs
zUqI)cst=_?j%(r{@X{R3#{jmClt&h2f(d_4&VHr82OI4JPGm=|c7)WeP+)@=-*@_L
z%!+Wz#0^IF>BM##1q>+x*h00MRp5(v(D0$wSZs-&c?_WZPgMnS3_4MqkH1-<HG0<&
zF&*=n8IIYY>?yV3soN at Ke!u%jOoYE3-X{%N at Lt6FjfS7hEO9yn@N6w%!fOWkx_cb@
zp64OKd!}a2N9s{t3z43T=YJ`V01Na&??LI176}DL#YHVE3w$@I9?qnmuumZ%(L+P8
z3_JL>ukWzo at Sm9UU%<&)2e!LeS);u<)h|B)afbX@?eFi%^o$xa)HHOPk#JAwvXV`o
zWXllP;JySGjMg{8z6{oTC45~3Bc{Rv7s9kM2!?={MpQ(eF#B&<DbbkD{?Wc~1MAaI
z1DLSaoywb^k6u?fE(S}{@nt?iO5LE?H6#;u#dLW!{e#gb(QHYlXjR*0AL9Cuwej!@
z0M~S&{27cM__M(mYgTOYar8gcFU*QOb3gJuParReai)X(&|c|Ehy6{n%b^D)KLYCE
z%jL}y%I1&W)HTq5)n%O6o(^(0E`L}blz+d(HlsT!%x;)!rPk3%V+A!2frDF(ym+UM
zQkZ-j{xeak4SpODtQ6q*-8cs|T95fzyJzxuKTyg$&LEAOc#~XQl+d`>d<&uQLrAlp
z7noIXT#>1P3+EYkOV~akTA^fLl_56u1pZcs$;mKZDOJ9g(=ua%`+$eJxf2A7^!(ua
z4o4pgO%=gkZUL#Q_0NDLu`EJ0vCGZhcM}l^IJB35`z>(WqJAI)LMO;^vb^&*U{-vx
z%}%ULp0LOSwzhpA^u0ZVv}<|hZBJD*pXY25K)>3wi1eJvN08QRPE)DznDL~l(Bszb
z=NNom>G^oeXv7=A)*H1wa8NH_R6E<{U^DMgLx{+%P at mi506PP`A*7KEg+CQF_q<k5
zk2_Kji~!oSPrtxp)D8q3s&!8X$i6x1FP3U!vIjbB at C8B`hiF}M<$vp>CHRT{bf2_^
zMWKhSiwj*Pe|PqMk at fXSR>)bJz;#`6BQ}kuH#2 at -++zYp%!xBY4YCf(bsjzS-#~?B
z&r14gwg*mD!`yOXVV#)j@^HD3_Am5Udj`IBzB2ZPgXOwC1Nene_W(`KV((VA<QWJY
zE*Hy<3~RR~opJDhe)o|&nVqDlB1}n*Hi<S(dH?Y_mRCoIJ(PO{=HJTvU775X*BC0t
zG^r6}8JBZrAZ`c~U-i$NjyJtO;+X4o-!gQL^+Z!9E8^Etrr`4|v9-AuL-*2r^}Y-K
zoK$IE2#^@wQES$nC~3%By3o7tHtewFFxl6b2S&Ra%QZ4nLosWT>a at yO`-LXq+Z6dj
zo#2AM0OeMn2*flGkh?Lsgxex^J3P$I)W8PS<$bd`=}STFiGP0VX~LF7#ad`&&ocQ*
zme}i<Le8<wZNSx~IyVnAOEqTA>|OvFoaBJXs(^*orh_s1m_}Jk;u&YU%6q7R7?`-B
ze+UQ`>j~Q>G)c?!6~_2QEC*m9vj-}(Cg|;fOz6iu7?W5)x19T?DpW&dDs at IdLFN@7
zq9Z+(OOVxD`z|XlYEajPiFUqb-%+(Z7O(eG%s`!C(`E&ixi32SkKi&c`sxK!ShTE$
zfBKypbZ%=A at aI1$blMIKVmJk9gcZi_G-5s<knVvkhC1{folJW_rcSt>EEYC>W-JDM
z6awGMTzsRbAe9J~aiplOj^s>h`^3Jgy=aI00&$JX>ui0KSg)r(&%ah8amNIeIJp<7
z64e3?8Bxmk#{risOPg@>T6iQ at ZeG}KC<s<>5GE~9sr7KR^*#U5)tmN6x5<--GmHX*
z{E9D`?HUzNZ)<=bP#kbJ`P9%<^UC0cXJl{-H3wr at MTWp+a0T9XJHYXgVsP8u2xQU)
z72vpCZc{)?N^2$cVN3MKBLh6v%Sd;6K)}jYp5W)T>*Gd{HAad}CdWjb+v3$_O3qa{
zq!>a-S{x1C(aEIR6eQ$H;T{yasn<Ux1SiGJ&1?1hTaZK5<8p}i<ow7(mJ_5NtZNjM
zi9z%2UNgD>e&a4bed{XYQrrz9{zm!FOfy<$#Pz|t37!Pc-6Lj1Z7eWq^jKMb1>Qt?
zUyt(CqeG1)^3ZS54*>hI at CHyHBOGMI61(&BJ(T7PU?R2+(Md22w+ZAQRCXww%J=ll
z)VJ6KEM$&VL$858do at LCruu-!JeAPV-JP#}rQm>N0QKMcSk=4H(pRn2mM#-^r&ZBr
zm7N#`pZlM69zQ^zF8W!A6mL}^R7LBge7$tJX8IoMkKoIz&_~~pNW5pLLwZh<2Q!V`
zP50sfv$0g00t1kUQFljVr3}U+&3P^>sTv+JI3(rt?Jj=x*VR$ya*eKC>FItO0B^8z
z6k9W!C3csdL>uI(m?FO(XG*Lr<pe3Y_&C!K=${gPYA8B+WnSSdBofbd2 at O~34#iuK
zz6Ld_=lLA=sSehPrlgp`yqm=mwR?bq)?)uz>6<1HTa at L%sotg{?f=a>4!ir67(QuJ
zZD(C~TaIDzcj at +?1&8iPB>-5BN0*!$I$!LD`U5}OlLi~|PfOFFK~W6>u#N{;Hqz5Q
zr;CjTOM;dRq*)PUU*PEwh9eZq<D)qT#6-T8k#|t?bKwSWF8<y$N4bVK*6<%HsYl%Q
zCw5iCTMI)8J_>JgYP2_GY(yP&1Pd$+exnxaKhM3k9d1y1LDS6lNaSPbmJP={g1Dgg
z at AR`aUIr*l&vIdPQvkyd&G?x0&k9Z+!0YPZv9p68%4fTzDGMALYQIsb*vfLFflw*z
zHd!waP0BW^ZIryN6*uwtj;9$w!43G0-m58aRzx=3Y^-aoQTcTS_<Y-e_84KPTWP8v
zJ9r5&(Q)47d;;A5$M2M-zX#^l^M+{SNQ)gaUwY_(Kk&CKP(#EU#nwZ#ep*tekioAZ
zR|*<F at a_TOw<ib)jPEF9=KtcS)bsUaKybf#9RCMk6YK!P?haqF at h?DpKR5xD9Kh|>
z+GzWH4{|}f>&1%DBd;Ct`~q at L)N9cdD^_f?J?AC4Rw6ef!Toe9ozl>RQX1s+Sx at KI
zm)MEuaqt&<8DkIi at l=VZ8G5ApbVAb8wiq^>GPJnhwScEScBO2qBf0l1Lr(tw{d?ur
zqQFu{gBZ^bj4v~HMGh%see%kB2blg{oGd($4*3_T?OZzt)DYcn0At16OtD)N<A3U5
zbInCx))v!XfHbH2aF<b>)q12M#%Z6^?02G<v&6UYepAe}hoyXUrSn3Lp<hb?CHS#^
z^hYggTYGd~+h=Xq4>C<NxExoQJl%QOlyl}+F!I0}nyo~2*s9v3+_4 at Qx;N at jLdwDk
z#o0g~*LNs)C;!ZL>pn)$eWp01+mU$k^d{?{yZ6eQ_nI>}rq8ENh-fJQhl;7vawexK
zxHfZ9W*c=V#>9WR&7xUWrq0)Wp|M0d{GMZbmu7~eeoNxndo3Y~71dCRrvwJ}%5Yee
z-`sF4h at zj~$5i0cy$8H=4GpeToFdQo=Ts66OpE6Nf}|uxC23hPg;o>Tv_hn^mchkg
z**(L~)k>`eC{z9s_421|MMoHTBKK|echGD_O4EOA)f|8auOyfgH5$f3<>QjU7z^P0
zk7laMH-UWL$r13TaWAUPZ6#<y(33FsfV~YMU3aD8=`Nmygh8!LYeQ at 3&yI(Qs?C1^
z3UkN2FN~IIa$yfh%w0XT2x0Q6A(7KK!#MoDEXCkxOa0|;nSmfshgAI<n0$mDf-73q
zTghK9#Tl;*J&4ss2jCCA0$M?`JZsAd*iA60=&h$fS7=r4TlXockV)H~2$@Jy!r)3*
zz1GH(&La{`#k^kpa(#5mv~x#&#|;qzIT+p>B<gmSy(6&eS+7VTqeZ^8X}0+5yi6mY
z<5Tjcj3ul)qF&MjBStBOc|2NtpF8=oT`5VXWk11YBK*6yg at IcM33{lLU2Pw`TxEgy
ze=opV_t}o4+eUVQOm!Qn^aH;|NIwvS^Ir?AvQlJ=j0$zERy*tmxwIE&!s0JcwoUI~
z!S?t@&<&pGQQK9oNlag-l)Yck-TP6C(Bfh??e2$?I&Tz<8?;X%0!n|{8OoEUmgjMN
z_rVxEt0rKUEG-krnrYxE9$+~owol`I6{hX;#gExU^I5^NyZ_3SkhPC-^qif$|EA=A
zgOCSL(Z$3;t=jy-6#D;QxnMOP=VN+w*vuo7(hrBX(4&S^No+OVm9pCDM?Q4?De2db
zex*3n4YwN!Ot!jf-7X8PopqDx9nv0N*-h7a?U-U`<ei%PCI%_7XWKkUSxAvk<Wdz-
z_VSliir$ALV0C^a7+?$hF$@^9_$CxcB$g7I(;R02W&uv5N`t2H;0aI$VLJnStqQ_m
zVDAu at EHCxuc`4TIxjd^s?Geyp{T`lV at v2<g1luUv!M;1Ez&&1|+*Nxp{q*MdDby`8
z-9H7w@@UBObRdJL3S7R35U|Eo$Ul{hU9VDWo$+U1eF3!GhpWBa75J2HXdLwsB_qOD
zt!?YOPIaA)H&|&ZS6GA132t7;Jbj!Wp;o^R*h1oy!v30j?_2^dzRwe>RL8;XcZ<Ss
zNncMwqrHS5crc?WLs@;jb$3IzfctLm2x%ZvK`w`}hcC0`7sTuB680u8WfG at Z=D~>p
zEGq)2XL|@Ag at iX|FYB3&$DT!f*_zatZ}o_#KZsXby)n|3SE^3`=kx1Sm)u;PsBf@`
zGZNTXKirKYus&>{-zvVHoVnl at IIwbfVcoeL6H^<&Gey*B5 at slRJAK?3?Ydq_&I<me
zkmqTfnLk+m$7lXK#6-6FjDlOg?8d&>4i_ZVo5m;WYRL+iU3bjY7x#?t!gU1LHb2}O
z_9;h(!stqc4G4Lv{*qo2H at 8*70LoWp`DGAxua5Z{M=!)|4)P&W)TA9C8L;OQHfCCV
zb+!zGM($UOMl;$;=(OZ_sijB9KSR`}!dz6vFp`ZYnvYjmaOB*iEA&6$-Y)3iurJu{
z+mp!53*Z2*pl)K;kClq0g}zXoCy$K>1=zMu492F-KILI_LvZ6fJuY<{yXe*2qlCQz
zTmV|l#In?E&fC+_DQd(<`xEa%&uTz;)&s_*(w<#m;9bRE>k^Vm2`oTmP at r*>bp5~^
zt}?5+P@$Q9d<xXYR(zNJ+zXf{V%4oh-z#67clUaO-$9hfME#~wu0JMy!E at zpVZi)r
z9s?X at xQvYfAa;OV&z$^mr(SF~6SFwl!~D;9R#VB+J!+X$`K{HQ&X4ic6VCLKRYyoc
z!O^&(Z1CF5;0ZUY#1qWcSmzY~!>CQ?6TfQ`mG#r~Oz{+yst+*lMvvi40yVG@>><Q2
zo!(}5aiZoM%~zB9gc>-8{HM(zD8KaWhFH<4eyPRU-_cO?Y%hf%)u~QOGO0y at 5lzm$
zDRT?I74(mhNB^Q80PV|wZ26J1?4Tm7DybmPNbI4 at fL_64C^`GrfCcz}TUJkx`n at 05
zy^QXJ at uTZXL&Ck(O5kL?_5Mg{Cuk$6L<-mX0%{8nV$Rplu?RHaotF;5h$6FLHx at -S
zc3NxCYR`|&Anpq}0Zm5ObApm}E7<@2MoX)=^SZ-!&6iuj4cTtzf#|zbz6~#66<XeX
zE^<)~y3yV}uO5!kG)f+feK+TA9xC8IFF%o?d)2_u at Zm%fCYzGvBne3kXdU%cQQ9Ge
z)ylXt;W`TheJ^qIB#|U(t)?WAw?D%9AVb2Z+oun^tsTF=_U-7{o5Fn-`7<#zq`1(!
z-r&WKyMS~^4?4EVA!g3;+OIow`{M!#e{61fZ#$oRoj4se3 at xH=L9^#C>~i6kaot=@
zwL>N;Y(?L+nc|0R#G)F$c6m?ht)DLW*DM0#$&@iJ3Od`)LTT(dzhdavEF!<=gC6|o
z{D^p`eE1d65Mfzc*x(jLIcNP*0qqksgC?BmjRGwsS{2HtGtzD*Koj2&;ubKABgegs
zo=5d%Dz?wt#sZ9;A$OR<tJxpeQNZ;h1Vq`T45?3J^mkE^?cg=xn%F8fSAyc1`r0S;
zSJ$}GjW!i1uiHx+cJzOBAydTPx`TYc!z}mD4abMv#O$MxNDp?Z>|@DPJ~}%+G*8D>
zs+~8vQA;m_b?S(p7Y-h#&<2mvM;Z at fr%BAC?jo)^Q at +gRW1UJZakkwIF!>}qPRfw1
z9CcsyJp^70ab32tuJbhIj0ny``pKkb{WvYdBKygSrwR|IJ&!V_Zu^)*H3Frz_%kdG
ztDA-rUrr+6p=O;O*of#lkvyiszDKfnxkGyQVO~t510t#bM2hgqi74?2WeG_+^B&Rp
z^{hWJ#xz{2T~|Vexf+b)Y0cf at gW2(^4mx0&&%tufE8AOIT4vPgg&l=<4w$Z&8gb&Q
zXd*E;T~skP<Bu$C{dEMu__1NP>`C!&>`7-<clMN9J at -m>riMQ1q=AJ?^>m~6Q6Wm!
z)t_4++INpi6?QY%CLNzGqN*Z_+`^Y{b2ZtoN7TOvFpm9!?dqY4^!NWK2DL1j^E5^I
z^7sH<S1Q0^5Rd7p;7lNk1d=9g-JtV1rh?W3YjE|hglb&eqxe0p%iLvpSl4Z*yUbd%
z?nyqtbxQA}#~s9hf34g1h{aXE+GC+AB9akr?(NiNaaXcH!O`vKY#a5SC4#^X*ZMxg
z6$rWXzSLlzlCqOg$|%#Rvz-8b<i2KcyS{r=beUK!a5Ixf&BPt7{rJqp)-w9H4qGN)
zIM8SP$P`lZ;QW=E+L%&HKiVm>T%-W*TaaEd?Bdhnuthq{K14bqt^3ddrrx&suFZk3
zHniRWX1!S!syA1KFF?Jeop*`Wsh!)Fw$$JMc{hW>Eo}yjN}&c32ur1#=`EN1ZkSNE
z?z^Ez<G|4<T5}7+1POCjP~A$}k~LKKTm(Qi+jN7yN`242N!W2w`C{q|y7bDcN9$h*
z>mwM%7_uGGClUTsXw|93rHQ%B!3_`2Cop=#1+fFgC4=$O3NY%Tz=Xf_zNGLgO>d+$
zvMd$si>;fnsT+Fxs-h_D&HBA9PjlUImokqw<`uWLm!(OyA4}4ZRKZ#uC03O+s&I4$
zB9X?N at 3z7)vZ?KP>{IVp)+e-1#$)j7K@;FI{G8!0{j8W)M`Y4Y?-YKTomo)%$1 at w(
z9;;^~t8xwo7colR)rmQ;tZ4P%y#+VLZN*96!3Z#VCq|Clkw(XYakci4qTZ-2t?Ikv
zV)U0Eum%-Tt_y8az&CRC*XnNKT`F>l*vTH-^_1hCf54mno<Y^N`swOL&9>l@*r@|L
zKMJB;o5t1q+&y*c1gQToZSLl<PC`T33_JHA*xHA{KEpx<*Kt?Pa{G3i(qG&YnZ6=H
zW_|)t0Q4E$qxQ0EM76Bq!+bvS#Y}Yr;L<6nxzoMbdEz=SCimZdCatvQ_(MD9q(qR5
z_y at 43x;*JneUd*qVdUqyuQPk(2PSilllGI1hSpzBZn78x#+u^`CIfK1e^!xc7WKRC
zLXL>J$3E_#$}(GAC1h&@VE(w#0~jNK+<7|nI|K+MqSH022fJp#UC)31yrwhfQI&=s
zIJmgdyXlu93WnL>##z;?!c<gfF{O2G0n5MV+d`8d1?^8j{aI80Y7 at 1{Ypp$#X}KCb
zzs2*iAJT`)cOp9-vdU|c+uupkQpgP5R?yWel+>_BC>tch<aqaK!}qtHW$Udauhq!9
zMw}MBRtOR7&5{tOd>C<Zg&BnzR#|vBbn`|#{tQWafc?_@{PSL8#!}EvpqcmYueE_s
z_YNjGO4;Y>jRY$H_Yd1q$#EDCK3Ai7f}DW+!2v62AakXJ^B(F at UbCR*wKo1P=3AbQ
z(^FgsLa&)c-Ern_3 at mn+dy2odx*cNuaQqSBXwM+|lcYrMwo%)~{J_iAYhB>aR|Yxn
zOC%>39$O<ongF;)x6e-jF9VXQP3 at go->WX^fOE&}Mc}TL<|{1fUgH)}px8;WSRUC8
zAH0s-m^;`Otnumwi2**hNe7J5+xYX*8^<aLejoqa at +FmTYi<!+cMS_VxB0Mc-8O~C
zL#ZOHEd-gVQ!5#VJ|}38x9tmYk4f6D1Dj#n6Ye|XJ6O-hv3dK%hMxtJ$S+Q7jY7?w
z(%3%Ws-ugzA>QOU^SVMwHI~2`tV|i_iB{L*>j>N8uoz|BO~I=m++nkiC`Mcggkb=3
z=kaHAphx8;Affk<>Tb18Q06%_J=e8Lw6M<g&2^bTxH(SM7<p?jg-Y#JTj!&IE=Mzz
zM)4V^??SqHn0J78z#=>GS70$oOXPdzk(1fy13`>zA2;2Hf7Qjj1)PQ+K_#<XN8#rH
zRe`-N at YG{Wl?k|`a+Yxe@>zDn!BrYP;f<DQAq#bC!2gH<in^L&dyT<lf!LLRFK!#M
zeO}*|WCJgq0ux!h3z$Lgogl$x+ELDAjch9}v(5ZZg%6kFy2M5_+j8&KmQuAP(w7tB
zZ@%Qe!*h>Y;~Ck>O%FH!msa;&Po%DCv86Dph_9h}!0q)q(gn90ntXgq;Qt{z!ERLP
z+xW-rIxE}}WjatOKb$5o%0rp;KGLAJzhSYC%ysXzpe25im`c?MGfcKNoW|&=@GI}-
zb2hQx*;S%D^z)^;gKWZI(@fk7ZT)hiV2JNw-OI(lh6NboG4F*V at y{A*y~?{)TUKtz
zBO;n5Rsn|n(qph#-DfirrDIiOUtv#E3SkROO?@mJI_XK2;OwW?j at 8=)Ub3`;1v at 31
zTb7`P(Z}_LfZ9>#(dOv5Rwoi#Uc^CnkLa~~mmy_K^bK$GXoC7CBPpz+b6No!553MS
z<!n2wx3!aR92W4#2X26%8}cTeQwdTW`KTGoXVRh91ogF>4bO5Z{bKp)Un_ at we5dCh
zm7<QLB<^*S47bqq{rO8_qnwM#^6BSK)t3}3nVWV=+MG8UtqHOWKLTtzI+!h+`?VW@
zJWvAEjW at 1Xd4Pj-9)gc_1lQxt?PD at eMiaZQb6Fa$dmLx%3IUwl at 3k5uq)F at R%Z|u_
zuOPyuAvBW~xRGQB^DE6(L9$2fR{-SmtHklPxetw9xf7YLfKm>Lr2^mxJ26ldE!NAg
zAPe?qV~oBq2{Z+!RR(HH5dQqkBa5vl7Mkw}Fcsnk6BOP<`BHZ;2>f6ow{b&X3Prds
z={0uB0b;|_u?KKF=bBFm%P2v~GNqAZQG6bik<7S1@|iJK_+~h>^?lyy9a-+IY9rlC
ztVg8M0T1bjnp{Ld*vP}0NHfv~$BmBF=Y^BYVKuTc*IKV}^UHZYCe(wxT0Zq=SS4+{
z<|NlhdNSRGMcsdRGy`)@b}XyP2CL%78$h`AqUKqE8Ad0iQR$teE26<~UPlV;>wxi*
zJGVW>Y(edI9F$IrMan}az=e^KXAh>TD~1(HOxW+kOC?|O<~eygj*CO}xGecVSwT^R
z1+ZToo3*#W!)h7-0*}3>fGoS~9-g~IrB=*qch&P%66J4|%WFBM+KuRM at PsuzoGTKx
z;Mq{4<+h2yNah(JgP{Sbm}=#F)!N)^>fnR}8dApibEBF%%8`3tr$rYq-QlAuXLGP5
z#!7EhWz8AH-hww4 at vn5-($+MdnHTTE`Wo^W=pO8{H+6MRX|8_aJZwN?3L2w$$|8~<
zCO*a2`b~dw*K(z6GqBtsrP1<yGb93dHl*_$TEL2*qDbp)K{8xOZv|M-4ZT!>j6<cE
zN77H%B%si*Qj9Z{6*1MvjJQ4&1=Z2yBf3$(Hh(l}HMgZ|r6$zZRort`3mJ6tQylQT
zGti$UOebqW?97)s at 9q<)&gu<IZze`pP{*X$ue(lAL)vt%^^1uece(X5dX$(Fmw+Pl
zKuRE2x{??Jcz8y4aD~Q90Y63i;{LJ2i8_&*Z4D$PCSat?EZLND{mh>1?oOzrG;i_l
zSFzb~xCa9kM!iM0MDn;XX$Vr9R<3$EkA+2 at Q#@%CSqq{o1bKLlRQEUz!E2coId%I~
z7HzuaF6krUk>g=?poD=&h|kQ)hu|uQW|I6u#nJTRb&18Ze`sYPH|iVC#%yuN0_8S+
zBz68e at _V3FEfxRD3Er1|-y~=QZteo32ZbC`jWun+`?yuS(XrZg)Lgd<veFUKO}+X$
zU>68I<Q9-NztG93`BGeEiBSR7vl<ak%I$Dj&9?F4`~FnbhmKXbyrRZ283C`e-h2C|
zBon`<DmL#am<f0zK**p8ixRw)eG>dzd7uFY%%mo%jG3--CXn&=FXQc{#b51?Gj$xw
z*@`g^5t*X?$mt~j-zV59(01E=__LNSNW=TVwzE~_*s8MqBqvuUqRkbW*K>U^dfRxc
zw2qXHewLOJsp!o=eQUhyO^I79?5MK%Nu4m1EU19*pZ08yl65*Muv&9c3*C0`;7{{B
z?)1gy%D8{C|8og&yhWrI8bW8b-PFB^3THk{xo7KXhZ!+Xwi7<F3q<5*DoYFkJ{-P>
z3NIKDDQ7_CURVJ0W57~;oLK9oFFI61Jq0Knu?EB+XL|q&)u;x>5=g5IC2XL8?sLyS
z>TdFQt+|scDTP1)s%l3x<b+w65d4!?KVMuPyl|D^=A>x886a5h at C5YAzDr6Ev_zE&
zBXA?XMs)Cvfm5k+KI_f5mkVRU*-lFG1%n-v6JUGDYw#XCE9RXaRn(vcUi%U-wLSop
z0oQj5gZ>nmpm3okJ&h^KN at NN6lSqcMM-&^n>XslZX(Yc+a;lW2M0eqJdBi(*0mlR2
zy2zAJ7ET)#WgEzYx607xrG*!4>kBQ;ray{DU8PcXX9mTKO)TZKj`$~Q$%46b-J#I!
z|L)#djfPHbnpJGKbOzVv!!fF>hqn at G@}5RUAK8!}2g+Y;UGNxg3Uk*fdyA~R<M%@L
z?WCTWwA%1i4hc<%)pGzH3yWQM>U=kiVyIdV9uu~=E#iEZP%cPd+ziIu#d=AXJ4gc>
z1E)Tr?le&4W&sJ^%PZ=uuKC-sxO6IotnxWwoTxMdk0vj-U$3}lWmEpx{jhAGtePO6
zmnD9gpqo&3f8oXl^@Z`mSSdhGc!&E2;`I6H7+KYy!&)f;I2t)11>H5Rh73WIk)WZW
zp9;MCQR4>+eMjX5SJ9EORv$<M<q_`I_-(|_Jd3=_`zvqHMGLTpGxpQ}VnukVe@;6e
zQs2sjv5n_fQ%)Mja^BFIkA><$XVZad0JltSC3{<>4;^qIftZsW)@Ib}8388z+e|pv
z6fjbhK5@(~xH$|MKsUFcIJFo=Opqk-FxDj;j{itCuIPwNJ2~PV8w%&5hIoKY)rjZ&
znV9$i0!1feBeuf(Tz{4cQFg%bMtms&ZO!Ra-SqWI-f(K)ArSM^884636%i)9JEPgr
za6Q*POWL~O!tSc1-?;y`EOCOoj8YXYp%bO`vG1kuP)&N1*_fmIGhe+s<P_a5LQ(Yv
zjrvP0UVegDkU%AT>9t9jFeBm4RoVi%XA=LX-i>!fw~uhqMCEjG|L4jxjh`cBU~x)3
zTduy0E_lpw0aw=5gs0}AF1W$}Xr}O}Be9)8P5^q^SnH+d60y`!a?~ruXiRKlz}F{1
zBr2heEbU>lYN5tR%6ugUA5~?!X_B at 3VSU9q930KC^WSsLg~pDAbLCzYnlh{+qSAv~
zRjFh2ZiF_iDFuILBlBf_T~JmygG>^$b7#1cm=B{=3ps%c6~o*FkWcHW>i4uz;iQa5
z#U6uGb%_L1C8M=Zd*x5NH4Mt8GhV62uZ>QU6 at a$j^aW6-__WILy18jmX!|z%brsA^
zo>~9=_Cy61k4&pu<Z|vwbLCRFIUaVz$q3Z!2E%rB&BwMp at U=TT;!NCw_1V2 at xejQh
zzy|JYkut9b_*}_Y$MI9(LB1Bh;!JP at zwxDe&dr4J5{nPdq-K{6++3rfDo#|5>Q~@E
z>46`f%DN(b2U&m&N(1oTIL%LrV at n4!xjzSBfzNB>oB?1>DO%hnJ9UPCF?yPS39zNK
z9pH6s*l<3=%2#~=`*Hp-xI6XCAQuc8n9}giMLTrUJ^#Kpt!=+2bkm=o`P=4B-R~9P
zljAP>G7dI`#|D4qERIx*8ZwnRte$vEW^BPLL}U4-!j2R@#&e#K>CiEikAFT55LBM4
zUa{=%mDQ;<_D-T#J7F)7i`O!HWwH3Q^^2+&o`JW)`<?(qCb%(cF5dJk26T_tQgtzd
zTEBWdXmTY#Q%(!w)H%~LpM|klxe$GHFt<A_k>dO^1-`zgd-R=5k;fnkvR!2H^3yx(
z(3)4+oCVVAIdzOV%(x1}(SiLG(`Ue-A5k(Vp3J>wi?%LCrFSgQziZLw?dsve`J$$#
z!-`*_sakB1EF3#iz7Ok at 4L4`O!Vvoh?~lcK>?>Y|g<h;48%>^rPnzK1d3Uxy*z_DK
zd2}fSE3;xHQ&muo>09c;^O=N%$)5&QUD~efwg5RUTskb&t2<^vp#<u!lCOs}&}x4Y
zm3mYzK3K*><+|P#o|@7<bh&eIFRvwJ#dcF3M7dXH6IF?f$7jiveh`tDyWXD%M0cq+
z8{lxB5C%joVG(+m?&4$PcmmwgS#Q0C{+-v_fy!^TvLF<m9s*T+Lb^anIbcaPNVeE)
zV#$jGfTKCK-><sOsWkM(dIH^}hMU_s0S=00B|yoJZp_<19r7XYK&oc$R=t`9dZ!~C
zip-}bgSgq9k{(f<0sPyR+X&xOV1(gI0!thKK0uTMaOy}-5_BpD>_>&O(m$uC*B?1S
z{W?nj=Eh~AX7_gn{O)sfr(X-HXZsl*!mAALo_I4at1C;8wTm5<{lU^^WLTq2k{)Qx
zYC at HsGIMy-7-AmPx#3S~0@?-Uvr~eZL6Dcq>z_r!{qH(w7LDUQSSRS8CbRM~f at +C9
z6{jV`PPG2JN^<whgf_{EId!(i_F4?vY_v3`k{RXKpB5`YHWLjAmlzG|INq6&81H0G
zl3$cv<)qXObW=kg?q);ZI&rB$u*o7m$%8 at vUelH>_64DLEHNeE!rN}#wA+H~#Nn+a
zqB-LpT`xTk6lw<hc3PkvmY=b!<V1sti#4&8yZI(ve{DLAGi|#0?qKIDZK_jP)<?BU
z`nPi+Bo6%8X~#5)i(+u~vbOLuxp>jT!3pg9eH5``bg<qgU;17HjU+D*@6l8mU!_K-
zZj-D1f62|0R$3n(CI_v{gPYm|^fc|YS~CsNv`2r-&XSU_THSntcXTCdDEPDv|EjDV
z*WJ8x)3e^T%Au;{ncMHYpJiCCbq+NDR2!fyE(D+N_9Xs(3nfPbQo_rYC}@2<kgfbv
zWURwHQCq=H6x7_xSc<Op6pEIlJJ_o^d}x5^mbnBhH~RpN>+JXjqR|G(m9GL-YQ<D=
z_o#mW))qauKMfei8GmrvVF4+?R#iF7Sn>!}u(#Q_>JL|%{TR-o%4uiS`Inuzv7;ET
zcmg%-^3idA+4yZ2dm0EFOffmj3H~#6$$5LZe}WoUIMaC^G~V47X!*x%6SbxH;ejDF
zoL2?EwGc_GLbc3tjn=0C#Ls;t^K#8f)EML>(oXHv_v?E|V8ZLOdCK#X8jJKll0;sS
z)8As*xsD>Ik9ym0r|jYC9|C(PUBg&c{rKb4^C3guz1<zLl&wU<KbLKr%Tx(`ybW?V
z%UiIPnTbJ~%oAhg!o4Xm>a3FT7s|Y%X2FEDFHxW$ap9Et*8($5<|s*g at FKXSwBydk
ziNJc~!?jX;JW-LX1y+7`&FKZ|HB4=6>o1Up^v?2DD}Cd`$ri4M at mw*7b~QkxD!4H!
zqjFpPX6w0cQnaAtgE$6eUobw1Z5cb9QVZb?Wb5<eCae`R>PoR5d-g~{8<=}FPIpCa
zKMiHNEv~V}hSm*3E*i^j7Uc2%$;6C^z04Q4EhvZ=hyPI%xohbu6<`#gTz~Au;`+w^
z84K1o$1F-j5GTvohq5%7_Ig at k0XMuhEOPR3!A~ND{11*2-J+glTAFR9Z~B47H$&9$
zKTU`VNv3fM>8U at 5V$tFHaSe+QKn2)2kA-qZ8!`hjfjqR3Md1Pf8c&uU)B<<PQv6SJ
z-roMBc<Z)uTIDvA4P(RWH~1PKUfr8u;x8kUxQi=V=~Y%HPCL at q|6f1|urSv+|CV8Z
zPzc^OE4lpCxH68sOPMI}hn*<cHd(ax7JA&GN)Nv=`d}n~vlhS+u-thE&7cN!3_g0`
zg+vVaCj{IHEi5O1eKLO@<)1h|fGz;A6x`5ft2b`GTD07 at wWXTqM}pV)WKwvI at Dvyy
z!)$g9dNE>+4$HPOa%?tCGWjFZ?yH&+54*MAg at 7=E?|_r at MW6X@ZYo)Yk`gSm)Ms_r
z at R4SY%VgzA&OqH=UwhV3jzBn4V8YsfCfa3|-3s03E~Q8DqVMnB*W}DvV0hJt#`cpE
zJ&LCA`!Z7<Mbaz<Qi>D+j6<v+{^9RJM@`qBGoFY$G%fy`2gCJ4>Y-MmZ!&}N4J>~r
zVcs2HiXOa<yKxFZqnE`>Jp2Y3&FUbQtkOyBLa7OQ8*{%f>EmzZzI7k+7lD6%{kj_K
zMXyzF36DN*2|lsK3<DiXCwTH2kDu&nr1X}$>x`1w{tF<~?%(L&K~Y+hpLE)^jwt6@
zSMI;6C at H(vSR12_A70wf@{#!VL~cZF_}}C-3p9WrYiP=8$B8B|5G%$K8;J)2T(Rb0
zRqXqQJNz1+mv=lRY<0lt793}0dR`eD3bs6~lf02~4$^Y}?*(u!>J%sn2<oN_nWsl}
zYeDtk=AZv$PSlP+icRln0;W{kvT#u?#%@rL2h{y2rl#XZO)dNuFm>oDJTp%<w|F+V
zs&*jDEU|5GebnO7yG;KZ)hK&l9PhuY0vuL5&vm4OL!LgitCDH(w|zo!Nz}LP+<s)W
zEFHL%Uf^_i{PTDZP##3y1G~5TGs-C`X2g5(SSa6N`gn9e3{<JeNmC;ZFs2^m3Qr4T
z0f{0x at eLyR`*;1;^4U_EyT$pS-YPHmnJ><An)D8H8<17rg=yK at 1>^1UP9A)lO1;D%
z9!R&jE;E9B2L*w577P!$eA=&p#LcXuG-hJTy-M$m1=xRCe^)2_-xNAV*P6L}1FiC(
zRILv7R{oCdiQjfLOm`N*vz@*}HiW9)mnd57tO<b4j}N;EbRSuWYD%}IDC3 at u>fLyc
zE^sS`3+DHB%$ExsG%N0*CO%G)n8(hQqL}Go>2_6!t!GA1!9DYqI&SY*<^L$;RI!xr
zwjG59wdHLpw9V|jOCFjBgm7jc+3F0fC<Y at cbUNW}YeJJEBlM}I(Znzk^zVX#$`mdm
zlCTSG3RQ^!sh*{JRLhzqZM|W!&@EVEXF at Cb0q?fbwY`h;b527;^-^nUGn&kNU;X=<
zctz&IAumOD!K&H6KPOyx^J4hyZaN at zhd+{10R=S&Z>CX~DaHlpC at p)5JqRip9fH#!
z<yvRwd*ZD6dFT2N?~{=&zdej&Gv!;F2gSaAS`k8TPK;`xa2oi<s7P?#*bn-|b)dN1
zi9bF at Ut6ZcU^xM0ytQ3D`~uiRI=KwS0Eyhc$XLDV%e9l^KDVgS5@<*_h+>#aoek#&
zZKtR$jbTCPxafr%&K7 at 5(i=DdP~3rya^XXB at 1dyI2yA7eCB-;R`*_cnb^Td$Eo0YK
zCZfjQFRzNC7XcOYa1{+)=jG at E3jCC!`@FtVRuybk^AS^32T>h-2oU>4K9UgF_jgk^
zZnQWNXcDngLrcYIEN|6r at B`n=?=&ByVr0f5%ljjm&u}K75VZE`+9y-?%*;#^(74Gk
z(Q~@dL6tTfMJ`dixvcBa45Mzx{M3NZ&EXiIWayyT+>V7Mz9`ApkY&HFX1`x<Bd$|4
zfOGDrR-EFWsT-Usfo;>L)G_9y6dsT^-!i1|>VlR@%tU*tkH!YJpG(_&!wn^3Ig7Di
zlw)tZY3Sj#-`5Vr)j$ppolY))0ly9py~w=y*%WlANY>}sjx4r4wtrj{=T{glUP(h&
z5Q`DX{Kv#!f+WJ4Jl3#uZJuXmFJS(9kxyi*7(WHP>nY__#(H;7zT7PS4?9<mEa#al
z#(zNx8!SyE7iE(4kDj?uNh7mep7p;SeY9{ElJT=jC(M%w at C)u3-(u#0miH at L{^E1n
z_<Pk+C%w&~sC7~{(matdHf~N3_;MT at S?gVWgq?B<oqNFX+ZYq;P0)rp6KpfapKuKu
z<5kvK;=0b*H={;}iX(8?h%oVsY8`W-&e6Z4mnJs=9V?Uj0 at o-DjcRcFW{1OSGQFiw
zg(CD(If at EZ-vMIDi)3K4)|2t<o*Vv2Lg6~({+ at X!MXA86O=&B|D_9CDacw>!f?~`3
zHS{}+3*T*2Ej~iNou5`1P)_A}56=#WXqF=29%eIdIl=hKI^i-OwI0dB$*d*#j1j at d
z(s$jXU2$RN!XV`)f^UNFs&LvU2CCMdHjf)Nxxu|Q<R^KL at r-Z-;rsLAR~N$-DWGDg
z5LE-{s|ip?u6nW3bZ5_<<&)gCpSs41`mdOhE{vnT?x3c8JeQ!u+0^L=JkW8S``SV-
zw8LS2a7k}dUHRbJh~~Bzz;nAc%i;Fo;&7}Bz^U8oEAx+WYp1IxC&BCn8oVm~_Y~Z$
z1brF@<r*R at zGuneVAK14&z}h|jjVJ5Sg1e-3aHkap0b?V{LAPrcb at Iq78-S=T3H+K
zf+IztNRjg!CN4kRXe6Z@`FpJgWjcDNg5nL^!ZA_C1O1{d#&DSGkr<DXPtmGC#XVg6
zJ+qm`)7e_O#PcQ^L6H&-5|@P+{c$b3O3^b?g4cAVCnIbkugg>)*n14B*YGKs(pdRy
zh-v4lCsNSx(D^W=j_dsBy<-7W?XYN&Kbz<FCbH5hqDF~k;2?Z{r`q_$?}?nh9+m-^
zpwe*#o{wLwkF+6;<ykz+yWjOcy`gV<SO3|5Ry>cYFDbhlf7LCx1c2Pn?xJpduFV=>
zS9!>6GPU at xaYM_XKo`oI(}}4a8bV@)Eu+3e0<@@LiTP+>Tn!6Or^_Kcud8vg;SYzL
zm!plxSHllJ;hzF04DCd4tr)a6eAThBD87>#q2m)2*^lC5&E5q~>P+}Py));pW2}PG
zW8P%J!M+j#K#9o$5TM4$^IC|f1h2&VJ_jqnI9mG|>`f5Rc!sA&jNh2LD?JTuqjHz$
z!Dz+r_5)dOpVx-Hb(YT0%pBEbbOC0&$>59idzM9p{kU#&+#Bmvz65X1W at Bj{)Kz7K
zse6<Y$W}%Eyk>jtZ-a at 9k7_FKcVSgt%7gb(T|qyu at cJ@<C5Qxwdq(L^3EDO)+9*x(
zT<ViO5Vbqnr`kXoWHQFZYO^mrM_{}`i^ADDP4X_zynE=~#IYvTsz`&#QmK}(FgO8B
zZWh}pf-;HnszW_MGU}WqQRh~F)Ozj23#X~xPdIba`JqVjsjsa3RY?S;BU6mSDuHoM
z<5zgmy&p>7=xw2 at P;zCSjr;G0UHZx%?mww$fryL0ipnaGbee0BwOJoH@|&?l;U>;I
zm4cHyQ8L8rkl^4p=@m`AH<5QX4Dcoh3-miGyZq{25=0R9ossp$^PSA9 at SVleml1v8
zXUE7O*Jb`X?9dl>7y2If9a->)z1A9b_R;ySi9;!rc7Y{D0_U>NO<s}z*8P8Ls6P!e
zTxr=ezFF&CW2I=u9qAHK2TJwl9zUABu)Keej%q=@?L9G#W4|-<R)dH`*P+#kS;T?S
z`x2k5Ucn=NCMWi^;i#)Y>B)QgwwxJ$x31BPO-TtwKdmg$X)&HYYt{pSUP3+^XC#8_
z{#$H5A>&3$5dC!e{sO at Spx#x*<96Ki-cu5v%t>Nyz~z%J-gldl`3_-M9<XiTOA!i0
z$SYR>8l?0j6VXl32wdCuwr`Ibk=8K>I6B5M!!pH-rlo0VtA(tLZzK5JOG|2M<_q5P
z6M<a}oy4sB4yr=Fdkt`mjc&h-CwRZ$iKbuV?H&K`%Vta6J%HxcJxH2XHM{WRac at m$
z$euX%4%k`m4REnn#%TG8dPEW1?od~elrBBR#y~xrVePh2A^fa7RHsCShfw-=Tn|Hw
z^=S7tXh3e7kLV`{WggyrkehyCzcCVOM5E!C0GeX5qAr!}4QkU`2UkIVt=4GA82C>~
zxG_7ree7j04bKfnIY`2j>3U#q7*(c?8M&_;G*dceuD=5h79?TLTR2{fqMM(WO`HlJ
z(N at +4l+F_1M>XggZYgze#PE{UoekTp8*I9}L`dDhQigo&?QkIy!_&?3Uo=`7W4CTh
zRL$fol8`W&5{}t>w%NS1>#3V4i`j1~bLxE9N0DD1<qG|-$AP8xL|S&7Lbq$xX6fq<
z^k=i^c37Vv7V$I|9BbvzvAxv at SU)UM(ucwSz*ldY?wIdZeyR;$@3YLO_R|o^kOBl*
zx^racXS5uQ+Vlz%O?M at o@B{Iam$e1Vl^Qg2QIrGp=BIJ4^otC3yHaAkd>h(MGAsH_
zk;Km|4QkaV(o~xcql at H*QYVIqWzd#$B2X>W6J<;*r59KvtqTKWLYCEkpxGbO0Iciw
zi<98ik9=)M()|B2R5V*TnR?l3CJ=i-PO6+eAD-zZzv&4~*R`d<`>oH9sWd?4E>9Sm
zi8bn!9-#R9H#ew$M;kh<pVt=hkBVkuNwVdU+rS0U?NbTAp8ylbPP3)a5+n=o{CT=T
z{C{|UY0a9mSD*Y<LQRW at k=#_xF~HZJEry(Qh$e2=WGiMcz^^@R at N6RwFZ|8L%jFzk
zS|A{7$s1Q+D|vV?)Zq6<UGtqX>3(a0%UbGLQvAH4DjDR`v7=bIX4e8!8}NZr%x at m-
zI!*EMSm%hBZ~&PB>(+>rDcR9HcRnR1n&OPXy)U=GJkTeUPs#z8dH!f8gjcv at hD4Kb
zn*MEQ_K6MSbL&ba2JHU0Lp|B7(kL;gnO)+;5Bl`Z9}W{>Bl;*q$(y%<JUObg%y+W(
zfG?bs#L$|rJb`$gLWv|6e at Q}D4E^$TE8iaN^x){{<<(z%P9TQAmZ?9WC~`@OQ9Ez=
z!io|3K)L)#{H04+Hs=>u1?Fr9>+UhxvoUm1cYu+P^k^p=KmR8C{jK+~d6gAjOUf(5
z-Ba~EqqQET58hg?Y&6!Vuu>^jlB at G9>WHRluNA}j!K`Qg=@)H|FP+ at K8Ao?N^Q#r#
zljeD3+MJ)g%6<ks^yM|<D%RM0xFQaF(vosIWO at eEud+kX=kK(Xz|aA8SF&Qb76aY-
zbkzx5b-_Mso(ouThB_ub$j$x$06tbe%+2>l{{h^JK@<z3_qv92MWej-G|d~GAI=~y
z%a87DeQ)P5<(tb1Y=eMvSm{0Sayg+C$zx-6<9RR^sM;a8MR`75rZ1U~H}<KBg&J|i
zoGNgbe$kj+YKf%~o@@l74M3*2YJJBjHByczAd><3#zo$=wTXqIVy9YXkLI5U+tgtU
zc3x2khR at r4!l3jcMLK*1?|dbXf%TTIRyzp5|I=Y%x at L$TlT->x at PC&gG}`$k=uJEY
zFVj?aewZ#VAN=n3?*jy85hb!8 at 74X2k&nVIlHj(~rJ1X5?y=78>GETwNjVjdgepl}
zRZaRw`ks7W{6Ct`JD%$Qi{mIsxD?q}Dl4O5bIlZ)S at +u8&EBs2<&sd8m0Z_eW$$_I
znU%d=E|*Yb-CN`e;rHo}Uw?YsdOUjExA*&;^Lm}<OX0j|Fp}l<z`#J+hjh1~sIb3B
zoNrFf@@Til?+}K^UOi@$8uPtmu^=wz at v3sk=hA+5UsKVP%=bg{?n5T`HEcU?$TMC;
zj70ZB$Me4I2CNlMvCHBKQ*Pi7`5Cu_CEoItX(=mA4&X;IGQg_U^ge#)Ln0_nySmXt
z=yC$uJ4m$2_ at 1Y&=ex*vpM?|SZhw!?c>8R;)DYdl640HwSCaR;gn1?Y{Co+uom+aq
zvmWu!W&N-8lPQJi4h4tuq)!P@=jk>G$9V2~#<JFHx0V!r;MHD?IQak_Bc$GGFBZrJ
z&>`&=)xN^nyBt~%YPps_E{CTD3|_{-a6tMFsm#EytT?7yVlD)5J!KCpA~V>w>C?vN
z-0(^XuEC$d0rV{1KQc9Zq6p=HF<e|hugT%ysaP^T3<$8(%L0NCo$2RK+30Qp4HqsL
zNLM_za47(6ofCUzpk2T|7!b4JcSmXI6!6O=+(VO&f$i|1Bj6$8b%&LlKROu&ng(lT
z4X4;XaKRFmok;()WBk+W&5U~A7$4w($QDVwgR5f9;BEL*>uw7#fUf<}b7uNq6cJ!F
zmY9)N@=WBo8K=Nh&Q1JmdG$r-@>_}-Gj>c1%Z(oi<a at TQO~Sa%oRn+Tqr0m7Cbbcr
znE0g?vzzy%v|0vUk%)mYQ$w+Y`)saq>#+Ep;6-w)TK)R^N%lX3&i9A$okH);@!4tE
z8A?Vh&wXfOt4x(G0!dlKJLws=V&vq0PZ)NkqU+lHuwA1C&TdM;umXli#l6B4E$+!z
zaL$cDvA0BWrUdenWHoG$hA3AW2Bos0;dMv5Dpi9`gFgmWm#$SymJcD5*YIWuLr at D!
z8>f#LYvp0#AVvNBJKJG*Fu9+ZJ2XU|T2!4j4>30SI?H?-+X+Y&uG+;Wt37D{SZ4x!
zkFWc2L2Q!u&_Pp|nrK!)O+kyX()O8%!rq~!8J}|RIfdu%i&{!s*&Nw~{6w;zPI8i<
zK{h2KV`&(91M^Z>*D(>=u3#@I3Qv<_!$MtasPjRH2&VFx-Y9RJiJ?GQ5}$1nXUTPU
zCyn6yK)twdjZVK09OrOYQd?}6!x9r$%c2k(14)Wo&N*rx=9?&TmCy(n2u|tezxVcK
z$Kbek)WLgTLX*mLDj~Qce$)@3vG{<f%<4RVZlvL2%IepUv)hC at Hd<Qc-UTec`{ww7
zab^dTn7{%@u?EdL%!i4`hB$5DZFyg03RS){z}O2`V*Z7(r^CPbk!QMO=U^8any%dF
z3}n)v2ofttW|u=|)8xXqFDxXgIAzkBO~hwhvu6WotatX!L+L2TcrvFxNbv~2ac&#a
z>V)a5csKMJD0<tx{c6etU8REX9Zn at I&vx5xx%iC+sP|}nrpTh%Of>#}75Y&h)Ts7K
zfZ<9&cdLrg%}jpgiaC-s)WolP-{#^3cc^Ga_}!Y$K3GzJ$ENWBlxQv`ZkCu_J8nsF
zKc%kD;ffKnf{2!YqoEe;gF&cO?$>s+rv^ps#_9X|Wit-nLooo58^7wWi~4h{%=n~x
zuhNP1QtT9zeJxcu+U{uxL5P}4OR>Z#K=ElhOKZOlU&H1V`XrQ;0o1ZPVsg9X6C-FF
z^13s`c#^6+rjKRoze{~QC*MO*-m{y-p0C7H4c)Zkn7*2F?=Lhp>SgPkC?(x}0QYcP
z{A at h>l#Q{#DtQBcoO9AKL;6gT3=mzt*#AD<^RGoUzIjA!jI<mFB_r?mxp`MNPyIGr
zFMUxU8sJcWemz{ftaa*FK)^h~s21lq_^H5;7xo7V at nv;zGrIV+N4b?FSo5m?j{reH
zvkx4i1pGo%3G{*Yn#3Y+B3T}|S6J*aAx&oz^hAbNE7;EfSs<1~u89traspng)*wSy
z_?^s+V&D=17QtXKsls?7eMQy#Z4d2di#1}zpY-DDsEeDmKENi6Mym_(S4h)G06MMb
z_)*pH<aI!PtOG756Q_4E^@<LD)K2+Uu3DXS#`H(a>6KA4zy|Nr=BQ7?I#TlmtTWh|
zut)G~6++kYF)thNEu#-_N?M$v7KW6GE7O at rwo)-=zGFlWOAYKm$gk;_RnNkBOMJV9
zv;9>jw3^N(_OI)11A8zG?Ba_!YOALlY^d4i4ZN5UYkrLie<$1RjS8LJe;6u7-bPsf
zkshRGwSYCBoK%?5I+$BiDZ6RLoaU0k*pzfviMP6IJ at cLB8z`t%a<8)3-SB4%#UT*3
z#<evX<SW$Lyjg#0o{RYEM_bzEG#(t40M^VQg|7mmagigUfhRdlARhK&k8`F?oA={X
zY`5?19mRy?R1|5*m~@m$$-%z#(LBfi&5hofI^TX%<AzVz2K`W6?8~#7R&pX)_)zvS
z<(qkco^Hp#i8^bq{V5RIU(PQw1h#1R*Hu<fuyn}S={OMBpJ}8Kj&j-mC|V?}ImD^0
zEPMQ at nWp_YoQUu@;eC8N3hX^5vu7sMY93S;d=aj6F?RNV-CH;G{O_><5F8Kxh4mlp
zU)+1Hno(PA5fQ-7Z9Z4*MRIoPn)^L>`rjt3=&W_`dIjs>1%yqKDaIF={SQPH6%}z+
zmG#Y!ZV>-+&NoLv^3P`vm&|x8=<+4R3WZ+r61{WEI$Dl8O+PjcS3a%cI*O7gzsZ9~
z>hY|Uo&kb&$K!AUz%3WCSo*mC0tW~1B-s_Zac+QsWW}d?41C~9Gr&m8K?N920GHW2
znBL1Khnf(luCeP58Q?U4?x?l_Y%rJsv%cz|fXbkcf4MpC60e`}fv~b1_VT6IDhT5W
z_5R(qh|l at t>ND{0`6h)3{w{zPnC6%;DNF-j#a(@lz7yy9ZEjm^?J?U!<FQegNAu1V
zs;I|j%g=L^2=yfviVIR1rnA at E>#k}!vL;+Ber`@c=~36WHh}OZ at 6ROJs=pa3bIW}K
z<I8^~5weeiWs5%5Rao(Nf5opANYndk>Q;-pNg=pq14>ja9(F{i)51l38jLYj%eMXi
zspc^ZwdX99A(AzGKVCBu3P&3^mk7{Q$dir`C#+0nssyPZihnMS&G2vcEkY`z-*y|Q
zO!SOjTWxXYkq?k!xDUE(uF7IuaRUAD!M9vw^!^HNoS-W66MA4ta~qrh_&a4*Ut*_r
z9wJI=_kZgOAVd3O_SnK&dkVGQbCrW78;ZYXn({|K7e=yL%X at 7ERXppTYfs`nUI7c6
zeD;6CPNyk$vbzAv-R0B?ZqYcr^@yXUr!cnI>U-bYp|7w>Z7sb%kzH<gux!;_yfZGz
zaH{{L!hxh}$2 at L=j^xmj?>*~bR8|N+-v18WZ0*paa at u3Dw1|;|bL^To=Hx5jKYS3z
zw%g$fqY<s+S#)cl?zUXL at kI1!*#3?{H>+Hd468fceHjgxRq|_y`Sq2KeXGp;Ca9-x
zL-&E1av30ETF`Z`03OS$RZT#yUVnQ~FkmX*mbY1|Ii350RQ?xApBD+dY{i at zgv7pY
ztnbKYQ!;KkW=pG_=8r4i4wCz#F9+Pp{D{4JZ+g%^r>`wN0k&X_(1lb0J9p4~?Q8L)
zEkJXA==<C9L&>U2s8jtRBOW0OyF-)}kg%AC6)EIiz7F#)PZ#@|#OR?S6yhM$^wgNd
zfM#bzp&vwH$qCf%m=(p*^O?4>x!kB0VS_QM!NEP-gI6(8A1{*Mw^I;5qowuhB*OYi
zK3B|?y^DJFTuX%?3f)f-xBot9C(9^FiKfv!9QMGTR=R$Mw+4dc8Jnr>H|rG~D>imC
zzPZOqYKw3e9pA#0k2k4%?dxG$tel3rpCeYY-pCG~C!2VRuXWc-<$dkTu8M*=3Fg}c
z%zet%+FP#FYP%Hh>j}f(F@)^bEx*}_0#$um{T975l(ChYhT2Q)pq^8e{P>1aqWoR&
zdhfjSgu%Brva?neCGPR}>tV89FfucyN2?ka?B<K}5z4I;axiX|xS;i9&y at m;fUc#Z
zyE%)u*Fn+R?bVm&q$+Y%V`P+u1rp2Zue~UUFz&9>(uCF>YzA8|PrDSBAEXO59wSc8
z_sYG)eaddE3m_`(#=+wvxV at 6E-$EB_>ZZ2SmroKv05M`lu<DMiuBcc#lwTK!G%GJP
z1`K+5<*R at 8@@bR$z)FI%6uPM*h6YPD_YpKTz_4Ve6mZuG&rI1n#B?apjbB}faXMc!
zT~F8H^3ib8j)BD94)}J{9RMb+XDE5ROsO+19hgH8yaqO0i0OuVhHD`kA(gBufGECs
zk60~n1gr?Z$y@```2#^jwbwK=fklb*8K>6l{=$oss*9jM22S(vIN{7)CQn=RevM95
zJ(Jg`{jmnhBg3M3qkCVXDKgtYtUvyl?#zFKS+^ro-V3oUeS<$RA1gL|wNKfYP)^oF
zOuzLT5)+{A$Ol-83jZefqPdDWfc$Op`$l(Un;LUJVcqy~k{!#8J7r2s?dGJ`Ti>n*
zhNF&xza`6#PiK)^=Kj1 at 8wL#*1XH*1My{EmHkuPq4D_Y{V-w1LtOvFF_T=1%v1Yk=
z(!~~qr--V>-Mj;{*-F<Bns5Fh;TDbLohUmx>-Y=%2)7}Wv=0~Q&-%c78JgUlVZd59
z+ct21kvUU#>h+4u0sYT$$+K)cAW*?kH&=3sS!g$KK5ObLV*Iafv!%smI7|1>xw@#B
zw*3n2GDA=!k at pX<p`%Nqc|Qos0i`yF`;P~@_1xYgoUWm1Du&D<6a*v`zRlE1U8b4h
zsas|1NA(*sD3vxV_(C~UOSIyJm+k|Y+{#xD!RnQCG6fs=zcG2HCW>uG1%IaOvrnBG
zURvU>>7e*)Mcc}ZO+OkV>_Y_`?}jE7MU#(KLRa2?k(FsWb(Wb)V-lG{fegpl{DL1q
zZow}D6WU8l|B_D`gzzNOHhtgawA&8uo7ApXEJ@&dvG3o%m#HyEXwwM;uS(h25Mhy4
zb~T<~el32i62Jg4BLD6WKVbalxT2iOYa0q?62X-CF(Lt7cQrEoJKo^_>1#-Xr}5(@
z$Pb0JpTjTD0Z<jL5|cGhfdNDedaR!p3Ay8s3ULE0I1N?F`RPqK^>qM3-q8()Uz*>l
z7P_0|;gfd|RoR{H8qM6Gu6_%<{=Ll_GoJ~qozMGS*S89sNgrSwY$+KD9GRu`7uorT
zLBATBz)z%x>vgNH4S^mWZqkU-fE2h342wa~^NsNIuDR%_9*av5sIy3d#SOlciOa(g
zE7x){jUI`=E}eledTq}!at*n&l8w{YYhhiup{STf<2S!7!P3Z{;^lAUI#C4qVrwJa
zR%#IZzW$$Vb&YNOc4q83WM2-t%)B&`s-skMz;j5R#5D9f!P=m;1{_{tj&8%k=@@=S
zN}A_Tni`d_oZ at K{$Y-SyG at F{An%;#S$P|3Sw(lXX{>@LAN%{UyQ}T@~2q+GR$}g6z
z--#j+%PO34-{<mgW^W(h>WwuHz at W-UH(_mT)C}DDggVx*LQ*zpmCbBRt|>gL#G%Bm
z-1(QM0K{*UWOCC*f+GBVpK;lYpo&*fFT0(OZPfg~z*TC>0x8-V-B-Z=R;PicUbV3n
ze)-VeS>*GSHW at tiKAEE4+X0Di>#!10l)3`TggjD5y`?)T^K~h*-$YY)j!6}l=LgN(
z at 7ezzEH^xv9DG)bF at cztzD={;J}!7}85UC3*FQP>s`*yzWPgayz>R6U at HLP_!tZo+
z+QvCbf}hH2Q&HG?;`T08Gry{#ArQPO_W?k0Judq^`!5T|^H(Q*%o+&8zT;MZC`e=n
zYXfe)pJQ(Us&S4J_7cfrC(8o3z at jex&4vwhpRicZrzf{pALb5aP>-y|XOUR116~i&
zRUGHjb*K|Z!39vgkD;+$z>_IB8H0c4&oj9e=o9s{A1z}tizjbtOpm}0D$dzogEMy$
zQi-=M|L+C(PqlHORy-{IB(0?7p0SSK<Zz#nT(7H7Sw;hHShajPbW1=$Z*0S~ru29I
z3 at C)veV`&JcOVk8JJy}LpmpdC>e;-Vup}VHR5F>k{nTST*{S_iQ!ZBc=kj!y1$1RQ
zyTdj&&_(JiI5Fjch?HjO at bZV*O!+Y_M9F?+<ZDj4O8XkArqayZ?u87_%Cu*Yn7rMh
zYsS#;kb7 at rooxFo`byE}I#1bMd7OFoQ49^0ThzEPdkY+t+nD2-N^=ebdOOQ3;lKk^
z^TN+}_v~+J;5~<(k%g|Ixx}e;808*|W?*8F&%U%NeDc%VwL4G=VGYZcH#4H&HFcMj
z02l9ipxqmHT(x76W<eCTX4Va%Of-{A5OzjL7l8;ou$VW%P9iRUWYev at qP~Hake#;7
zN>sh4n~gxRqB;Z2x#v^%*VAVIvwBm?c_2TtBd2c!7b&j9uriuUt*ktFc~5fE4eD#z
z*St5)DP^&0MKzy4imZ|N*O=2;vHALFD4LY!7ThlRd(r3}b at O2Ay~4oIwd%VBDKVlD
zw)~xOD^<9zZcLUGfR79y18_$x$yVE&LB5~?4qKmr3*0h63>OI2U at znoxkD+8`&jnt
z!-Gk=0|TM}?m8u(-PyNdq~d8Gp5mThiR at G35*>6`|54psIUsZM<P2<n1r;E(y{cA0
zxbu{+ at nkC0+=(2y at R%44;iTdBQ)WZ{$rO=#NsIgoOt09M>}pg8hJmqA4gPfNrSnR~
z*|NZ`hLG|T*Um-~6gRO3LVZrc5k7-07L6j>0}nQurRsLm<HZFt=Ehimd at k>E&q$_c
zM;+7Y-QPgJFbe6k)$nr5IQKW+&utvBG2#7gJ2W=r%GCuQ!@sI3uN3cCe$R=#loT{D
z9lD48+2u^zO3}ODo^yAxt!G#@Pd-ley+*&rV1%mrD?W#s9Lyeztz`8A4ZJ6dG*YO;
z(K(&J+rluIO<I9yKY4KqJaueok#IvNA*{`(<ToDNGc8kU3;AB6hx1Y*`qJ(}S2;wF
z%FFxHg=imQis#if<x^B8C{9|FY=Y*YepcbCxl6(+BMq8~r&=0WP}SKx7G?|Sl}Qtk
zU-;LgmpL1?vNJ)E+sli0?Qdnshm@`DSxqhI*V-$Z_dAqHV;Dh9!jnu%#zzDWYI2ve
z{Nzx}&KO^S8oT!X5AQiGM>G)>EoEn-WTyGu<&X3CN0nv;BK<ewSj{mDeg|0%CgVtl
zI(HGVmpQcW_T9<^Th>Z!h3>jrmR|nLlGm=ZvO^}0g`>s(kORc#5H8|d3lJ8hkb|dk
z>_MIq8}i2!L83Dzpc5saVvQ=3=%<Gpg_Dh9S&{yx9wOR^<HePC5aBKN9BT#x<4-I|
z*#nJT|IgsXPAE4El0IXmX66VOUxP)roIj9}86&e#tD4kyMdpNw-pcqQquk}&pR><^
z6SR3v{wnayDTIpj90rFlAlcE85dS>MF^&Pii1-Q6UyG;2Kfo#uMbm!ur37B5Pd~=G
ze)`>e`2`(3Dw(DW;EO?7J>;5gagKI5JA5xVBoTXv+U=!y>bdO>4 at +_9K|_`%+5q9f
zsjQNKfYV*EWmpE;M&?U+&+?+<U7ldX!jFW4*49=hwEvOyQn2*M-ncZ8E`UtWDnt&U
z`_#JJGVFdJDhoNym*APxxbt(X9Bt0(HR^n+xypPqoj%2C<@9$makEe?peNws%eMuU
zqMq5*7|NKz?@2~OEv+Pf(MOt%M_nJo!nHG;j&^s{g(!{^%CH;DdtJ_(@n25lngiWh
zBCcU3%ziyGSWLg4m&f-k(ztnE@^jW;om(Ae{Yod_)QcBp2b|Y*wq5dyjS_Y?gubL|
zzb9b at gmoYC2M1K3;>Q4_NC~(9Y)QW-x{9Dt at Yv(4=lkTjHW-T|$09Ew?LohDn#X!5
z%0y3haPM$;x3-0Itb2srDh++HV&{EBe<<$qa-y|4*8|qdqQ24?71WXJ(_V at Xy^*$k
zVV^F2gH1Nx&pLDPZHe?lFQWO{BmP{mT%t1{Lv9CB&b^C+efM_dWJA`co87Cuq2Qx2
z3I at VexuqU0E4nZ&37oFQTW9dS31QY1azg at aCWw=w1)nNlN>whis@?G<9rG{Mm;ygX
zuo`#Q_F|iQ95uB!G?!n5iMkZ~mpA2YzI;^ch}g_AjhlRHJLpO?ncOtJY<4Hash<`J
z6vG{FAqoRhR;60 at H&YZFfiJR*vePCSQeN8;36Y%r@$ko3t$a%wVq)warp`$<@ab?o
zLc}Z=%*0OTI?)b%T;Xa4pIG4VN#Gyaq|np7M(xN_bZkQewH at 4;jeFF2r at Eo%%YGnN
zMd at 9(SpT;e;_dK0Sb!)a=_QFodLUsk=e7FV#!MXUlic>tpeF+?`W`@krvB|ZT{&Gk
z1-M(m8`+4^&`@aPQD}-I5uA}PD`ierb- at G9QK(A8$3}+LD>BRzA at 9`=XPoJD{QI_k
zKF&(mD5`WLP%RU2XZ8K7HM(?KbskIU4F-r8OafI1Prp}~mQa2JOy?fSVlDs{TPda$
zMOLh}5|0Bn2%187+61&jT076kiy8kkliqyTEEPZH;0?ht8PEpWdjZl6{I^Yahy2I(
zXI^r0xbt6gQ%|m$5jS#b1Yb>5cg;r$p>C0f<ucs(QK(z~Yu9__-{22TG$$&ndVc7b
zBCSx7*s!d71IuUR8Vo)i7Mp4=HBVUxqVRN=4oe8U`Os6DbhK67FmBvo$8A<#ocBG5
zrD1GW*}N?nAbljrp<vq^ai{6eMCbP8gdnAE>Em7piQE#rC3aNM#o!F$j_J2h`AqzQ
zt(5P0kwl|om+o6-8syAP{ddhhxq_jSJpYY9Ui#=?ujYX<2ja~8{>c+c<4OR4Vl6c*
zq#vLFT2%`aloA^6UgqoXH36JLKOduQtyCIq^qST)ygHh{#vi&H-!Nwzg+&0joT&PH
z(cQqkwyL%FeHuO*geKr;rf}cC8Wy~GkvcaEC=ieQxOer#+MV&mf26jz5cQt`zG>&6
z<qbrgm)LnkTCvGW0UWcxYH3X?iflfEv6?dHW*B3*A7(^$<csDKR-%4E^Q^R|0spp8
zdg4Z9w{fAaB2xRH)~)49eP{2g3XiwNYiX~o^0n}WcNUGT+JAXo at T}1lYMBI_U7Ae(
zCEV$@ZY9Y6z{T6Zbhd^TdW`0rNv>&pOU;2<nZX}8mXujKxX-@&kF5m1)^hUYejtUp
z at 2=?0?~?6GjN&;N0i(%7d$jlFOO9H at S_7iBK05|F0;_vP8|H-zNAU5a*u+bw46vdN
zb;Ky1N93 at KP|(AF1oDrndt$lH#5_V~av$~7-T6AL72yl=m?Et6C}^v*{x(^dH!m+Y
zV!Bs-gTArImPP}yspPb&(WK=5H)L>Z_Oj!+we6m&(^ODxz6o(kPF at NvwEm!MUg?$y
zx0IlFj)k28&ySzI9ViYjv+*#QoH$#Rv=q%~9mg!0tP1$e$rXoi*F<OZA-kiK+cSy)
z-w-LXy!qgr at uyxYZsYcYE@t+)(tQ@%93*MkYLBu&klIO0FZcqcO-;&{K=q$jok?KL
zfK3I<R^Wv}1HlVEUYMywo3(iPb11o at ytFCreriq(q~6U-`Exebu{4A}Cj#QSYqU^u
z>i?vW^#K2jgyQ$^1)p2%(nQWSTmgoVdcH9K^30dC#9}-^fYSyjl)AVdv`FXkTm@^h
zZSSbw)JF?Xo*(Juy#E&E*3y*s<k|YUTa(&UX;aVTFCmavAWJqjQMB%;G+ at DGZe-DR
z@!@?H4?k+R*`5Zo8ny9q(W}Oev5i|P?VRkE#;57()qZNC(*a8AA-gHy?XGWEi2gWq
zN4rtcUd(mp-87-*V`3}men3I;B{-D4l*Bpjc<-)IT at mCx{AC(pNV*|ay4RDW0r?K4
zUz!-s^zdf3^>6 at MLCYFRf$~aK_?2)7zjoGrOE+gL8<=j{PR2+yNd>0*^%K2TYhQTx
z+3u?^rUxM11LV*R=`H;EFYg9q*Wn4k_ASeP7;>P<gry{6-4u8YY||_SABjl&b-MP|
z`DtF^^jJ$0O%*Mw6%#2J_s~t{b7>ejx;SeE-xvRgKbm7ju5^apI&c!_vmm}?u5P(<
zi-#wBw8lUH&i|NPIeW_tKla91e4#K9JTGq-yc0mPP%0KqyZ%Yw;SlAblgXM6RhKnG
zSyy-nu9W%PB5v|Y+4Qzl^dBHC<H0T|yN5s^+*I3^w-g8RHk1~~^VtP?pk2S~^&TEU
z%d~G{Sg^wq<*<c>mN<gm6<v2l^lpv9^WgEyi>>d}XJkcp&ek3#WWUJZa;IF?Qwj at U
zDp;xd7>C<j15tK{FlI?fMX9U|0?wV(LZAyPb9xaqtVK`z_<4wAVjDm8#raXE&A0J2
z5XWy$Y4#ip7$~_no7=%_ at qL=;yAC4{I{*6moIzGW-`!e*0xy(q!L7J>cM#Dbikryf
zWA`XXdNnLsEdE0#l3+H=;+Jh-kNeg#aj#DI9Pht~zR%;V95eQkU#WL0+iWc!Iuh%Y
z9VT`MfN`IeoDGu`XIcLar3cd0t~817b=6ghwDP8LQbM`bpX>H-D>Z7G|61r_pLfZf
zVAuw%a)zvacN*yO3RJ-SS9+7JwyTY`&7JD&T^2S!&K*d8K+uF&J_|yk_G+g=tmgZ-
zCvHBO&n)B~sI9HDqo)USZ7(8;RJCF3-Vm-RAYvB;*47eylrU=Zcxp8Y6jhp+y<6ma
ziCL%M$!xq=)?n%ay&KeJ$Ln4De!jUe>5P=!(2;fReyhInA^r`Cprh<wHByPQzM7^2
z*93ak2TFcU%>H=)u%6`)H;Skj&8*Enjxqe_5&5>E045Re05vuQj2jm&m$^mjTsYnk
za3HO8c5=Uj9n?GHJnP)c9vK#fkRHnngfu8}S8ULF!;LW-?u<I69}5a=KE~yAKp0zK
z{CnMt=g#ZZzYtMPnrYDCe-^^g(DThuYhk$dRo&kxCeB7`^l96_*VFHDNT`TBnUM4l
zpT5WEulkorkmZ+f`P_QsR{LVVye6grTbVKDF7a#suSM0+m-fEM!{SoI318Ha9K^QF
zY*BfrKh{71mPJ!2I*e#wSGpG~e%oh&{AX_EB>)fbgB_Jg_jg7 at 8k{m)4VG at -`{B2e
z{V#0&VEw(awNll=p8R+oF=OxhyhJ0L`jVZmb9p1%&zbjb1y7f5vpSEv&`3w$1eE-R
zN6pfKK+n&Nkw?9Q2-ws~*^*E%=t^~@tNMEXlbzf+6<`s_TLaCC0w1PGDpp`{u}-Yw
zK4c|2zxl>W)R&gYwB$NEBc=e?7~U}?8!^Tvp{|w9!A2J4HvrrOJHRETXuV{oJ^b_q
zdHT7s6=t8B;>u#pFmM{!8UpF`72*8aC<?NyY?H2f9*0BJ!WNBEvQ5l$0+$Y_{8lSE
ze-s4gCHzNPZf~XH!iqrC?ah2wB;4BdI$3jNRmL|yYlX`zlAnj3Oy6Yo1mc9<WRki=
z0zxf<YddNirRM?+D{`yC)Le9me$07jCp+x)Uzs at bRQyfN3VH3}xm-u!to3>k3$>CD
zVs~zLUS9>})^G_n-Zo>-SRn_Vj#xET`V2{P{@L3qaZ9??kaTC}Y#`Ea^KpG=zoK-4
zVxT&|gaB71311nY6xZd9GhrP?6e+eQH*Gh;3oz1|sl5DPv_k5V0`Q0HPLoqTyTP5$
z)_0>KXxX{L3um6*eV=CS9=FR=C~<4C<@gc87+^dkkIT1;Jz8|Kh<h}-)s{;MCx8ff
zS#{rn44f()3mcBZTcrz!%jw*~JZ1yj=+S1Tp*H*<kN3KSmzjcVe>vbVJg=A4i942g
zxug2d36M135qNQa_MK<X;s%RHyQf#iJT6ydt$TY-N&7f({R>%L*Nso=`JjmivxS2I
zc`Y6^AWEE1>-^^NDzwJo@*GfY&dQm;(|0P}>Hv^m78mj#fquJ^&1w6$dxMF?H%;bG
zL(kmU#CW(SaP$RD4sM^@ovD7xHT9rUbewH6cu!b~KQpHkdgR=Rp<y+ at E?9{|)<3mH
zo1d5rSomn<e7re}Un9v8V;4B8+O#u$IM0cv3r9Mt4w+?39hYjQf+p*~aCq5^(E>8v
z5B94^20jB{nBgcTq)!wm16Wg?G*Oh81rHYoT+NT^idsBo+iu*ks35}xM$TV>CVc+O
z$GL84d)uyej$OZWC7fZC=g;GSt}lfyjO{thsqT-K(|f*d1mqTuH%ep6cw-B0WYW*f
zzg-DSRKkg|W~4JTISA_htk1|Ej-xcC5WD0weX(o+_F8g={i46B9of#v*oF at I(UlPO
zY7h>tZlj at m6BVy04Q_DOG%xue9S6Qvy!+KrV(|>_TNW|-D()0YgK3EtiV!K$r;#Ce
zk^kz*5 at aq(%3B~FS4Zr+ at 0MwV6wsUdNK-Zxji#>sYye-OVk(Q&^_J%@XPCaho^@<@
zjCvP?Nd;vZ`A+f`DoVpBmM-GjD~gX5F|G)q(x|c!p)6C+KDQkevm}+3i0Y`6TI248
zip>e02zh<8M_&8(PYW-HiC at 9cW^2L*tZ<-VVE>w^43pSB-d9{mDR|m6J8l&Ln at 6#M
zvao_`D*8K)G-f%!e-bzQDhWAGsk`NhH(PFM?bkmb`FRhxyqp2z%{GS3IDj~qb6nuW
z%YijeSoumGrrjyl(}A2~JZYFB*nOD2&~*&dGy8}9OOyXe?yDm72<IJuF}2w+ at b-1r
z*qN+=9LT3aiQ!$wTJx=mp*0X(_r@=e-)zWTR6v&2pI)#o&z=deXwK>LHf4{pD*dDH
z7f>5=bSuB)QM}*mxezfy^g7a6z|ICUzw847d3gLiu-YOA_)FArSBW`Xvgf)rYZTPA
zb-orhb+0_Dzpb;(<D+sN1DQx at b>f$26p1hjSr6%^x@(iqWrcj3TqhO?drvI1P at Xyu
zDUX3$GRNa>s&YPG%9~9TzpaM=`;};?w^MssbFi1`3h-0E%xbnhFw4TayBb-WFrJNZ
z74PL!3|$)SuT>nba6$B8@=8h+!QZafF at 87;VTNOCP@%OquV`6C49&Y$+uBY^&o~aM
z8C at wjosbg9Gv)pI(KPTA^W3Im-C5C_Lg^&@6S~xj$8&Eg8nzr9Ftocb9Vao5bgft0
z)9G_I<Ys8K2BU*cS{|ggVFQ;OKh{D0C3ZyPq(fUGgPH;-h{_ywA!HR7!UfD_3-5C_
zxB7hgdbdSJ9JPD+Cg&reTfenWoeQvJ7VPzos85~an;QqW*p(RsSmt+FOSrO~Ug4Hx
zZ8H<3u(ht8DQ6I>sxfg1y=EnR9d6-8r3?5H{JHjHjt4rw$+3FupF*CYnYKsfa~3-M
zY_YjRb~CWjhB;k-Ole?_z*kTffJaU`Vnwnywg60lkU|uXO*llJ?K=?ESe6WHlP at +|
zy8USD=eHE^fyi6tSY~Ip2w+ut{?PqC(b=I5`dH)(hVmtdSgl<38lAtj{PC=U9}|p(
z&6X#>gSh5?{5#wZ`~#E=LkO|@xRlV#$a-;O!-Y~`)Lsna#EHLpCFF?UCnKS4hMynI
z6m>fTpjJ;WDq?z<?gv~-j-7SbNyvp5WEie=grHp5y&S6MQ1BV#7rK7PVPounG*KmN
zmJL?u2p0*6?H~g@(vv?==l%Dk7F(fv1_MM1o}HSb+Ym=|0Ub0zrGJpx=G~k7GE|_I
z)k?%AKKK*5Z8DO_anaVo0a1Yd=&6RMD%vd|cfuVT<{CkTSVYKQ!1ia-5T7N-yHhF`
znG0pA6&N53fAPNhf}332UUftA at Wk(Tt&4vD^XAC7ztamSFN9}FY$;_?;-$28aC%F@
zUb~CB9Y0hCpfF)xlXDGRZ|7~;V#VWNZvHUI=6}s|xi){MRJ8srpbBXn#{1a>J)^to
zR&C!?liL~bRSP6KK|;F5mGK`C-Es{xCdB)}ubYn?N19!SM#d2dMSiXF!{zVLo*%TX
zyEUyM?iKwGX*_PfoP{g>t1<9EWDc~twDP>FN^~sDABN2g<IAm;7vtdb6Qih&8a;qY
zynZxumv@)8zLt<JxUj)rb1F*N;`GxcGWtv*rb-)#0$EA{uJQ?amLYqbFYd_^D{<aQ
z5$HJhC;GsMYQtqfUw|3IM?9PxpMShU2lQp*>EnH1*wM*|=W6_z9w&h2suRS%j(|pI
za{;9aML(a9#;M&AP_mQ?wiMD7BZ4vxPu-gGN+Uzmv)X~GgycOnn5B*WLp(m;={(;l
zYwC&qb*^_~WVryS+~|nK2WjnUYm&^tn|3#~fohy}M?TJ6?u>iM4qDc4F&_D%6gv0a
zDGE*Bqf$iIcSZielt44O&M at kmS><9_{UyhhP13f%RYu+psOHsz+H+p_w7NMIULJRM
zNxYF^JDjYgEvniu=sk!Yd+0!q`Dpri`bHyHdrs?V38FwAci%E1 at g-4DOj>2oSnMHP
zN7k(O6cWV!CG$jKrs4j>@|>=0sx0GjNqn6|?x(g%irZ)slO!V~qX`bA&Ft18+ppL&
zh7NCJeRsT6<SU%<6#0PjTK&Qz?FhMQ#<Z(x;!?LY56O;Fw+wmox_i#BwYFnuG!`uF
z8dN<arCX>mZ2#Q at j-me1>ZuuhW`)}G$L)xw^1nZK&!`aFaa%2`OW$$U6W>mwz5#Yz
zS{7$CL5HFtG{c_C#trbE3I-y0zOXwYQHdr5#PqDRsZclkvP?D?#^7FDg07OLu79ra
zHEfPWc&(qy?ADl*$olfuD(tyquSdVkl`LT%vK4l_#Px9(iAT!i14Tj~QPQizP>>*s
z-V1c3pX&AqY0MTRPsnN#+U?+{QcIJ<v%teL9p7%#S=H3T(_OLE#{zc(RE-0-%&hN9
zC?Ky|+5%HKyePKxh_-TH8azkd<%0l+rsZbz5xE(4#2*$7!Ec&Vbz5^(O_w?VF%bT!
z_}zhfM4{wK)|WLUO%6GmsbPv5J_CuB=8}zA`y;!Xrbn&z2?A67gccKEnv?x&=#SJH
zpy3j<Mc_B?W&<#<l{}z}S94jeb9 at o|Dg-dsi4hhRl+ at v)h$~af`d9_{;ImN&ucfdg
zjBC?R2+Qz at ff`lD;=n@=3S9wz{PrEAp;>E2><rH{s=NHxUhGoosm6Eb)2|V`)hxmJ
z3uF*~+NyY_bTrEJrgNa~6*@vvY0;5HNc?$w|MhTT85<5N!bn4!d-<*PDeJ<a97oSK
zjqlci0)!jEPRP{%9{fPGqx8+M*9rC<-AD7UZ;|wq?Iz00AA2DMA6xXH`)Y1X-CLrP
zN5`Z)`Sa)>5y@#ZDsifgBW;X_*be3O*JDOhhDTN1W_8y^v at l<xi{<fwK0g2zdOQ*i
zV+F3Rq4b+fWy{1%Xz}%Aw??8D4=<LBZ6>*iY3Z7do=(k;tNb at BFG9x1rvmy%%Zm!z
zyb~a9<01Zu(ikJcOnq?U6kN1S*B?xcQ6#0a#yA#Ghi5Bdyqg86y(=LY+I}9|0!3zB
z70F#^(QQ8o7r)e8*)H}yoq`Y;&D8caez(q40qdqWkYFP0X;L2xa^|}yl-g&YqUr8k
z;)45A-PngqkMwbr(^P#{RkM=gEn_S9h(AesKp^!-(m)3wCYbE4RJ^YBD=DXX2Pt=E
zp%W^RG7uq7^gbSJIJ4BX*J6)>M8e%+N4rv2fDfEMPo8hKzj32Km%pj+X&faGi6kdf
z$b$UiwYOTr1)!4K<$;m%- at 3&5ime+ty2Zfo8h2Rkq)u`g-ZBpyQgA&Kw3Tjky_=oh
zE>-`adm=>33$<rIdnU#e5N2*4FqzIytNz<7CC;_3T=dL3pGM`>IH<Z}1a`4&lxMVX
z4{SEGHZ0k~k>%KSWUCxo`^xC<FV>QiF>ptCGWgE+N{FW?Q<TUMOVbPaKD^W>pYJIo
zN#g`HTbr}A%zei-(Lr3atF8u^_EeVz{{Zx=ap4r{L?GeEM1Vt-HiA5%)8igdo17f3
zy174ZGNEp?QcxZ!buKN~AZ~xCHQ24g&t2bmRM%A`Ra)od&fTDDDkv=`3h|z?E&*!V
z?b>paj9AQ_=0=4~_<_jBdB2}sa$D_Ejm7+}S6H^Q;~+7(OK*5Ua89HRz67`6!Pk3s
zcGmaCH|i||vG(JsjmXpRM$olo2p+M$R`AV~slkodHMytAs9eCnGeULN=MPrgD>0iz
zo~k9(DlXo}YURe=){5O-EQgkOYHGb=eGjk7qLbJk;NX^e>g}D|)$^@<@V~M=SW~*n
zf8;q=e4Rnj5RkH&LS_jD5xrNky$8nn?3l7Z76u>K=j9X1u`894f@|?D6!>*$-krg$
zy`G9kniNL?Ko_1gU(w_+IA0oTak1EmQd)k0-)W3olJAYPSi0RU;=HV+pWGbM>36ca
zx|-(R!ag0nlJXTaPQgDRoK*fb<Hwx$1}l;M9sluN;zQcm#1-q?=-+)`-``TUewg0W
zGY<^>l$R_g+khpEzK;H6^hv*&T_1Su1p)szYsf|SGCvR5Ydn!ds!2LbZp$(Sqi5*J
z-=ESR<*{Zj(8^ZROqqO)1fPb4i<zMg-z_>@82_77{2S>HFEO*Vqq}z!?l%4U&Si<r
z(qopP-Fm2z<?foA%hR0PXfctjija~U^iE<d_Itp7>*3NJ1T$ms(3FCrV*4=wNPU2l
zba?^}+z#{Ve66P6Zms<epW5<)ppPI`BjIlP8cE`ORQil|8E^*MfAf`XT8lgW!|DH#
z-wnk!WMiS&%+hcD>Oq%zWMTjJ0^mmHzMLMBs)S({r|8~Y>)8rdkKNYm6NB|~yk!Dc
zblb43#I6bIeZu>o6|xq)m%OB2l!Bm{iMmkJ%BHAyS<mt*PRwbRnadqg)T>sye8eM(
zDkSoUsh3^lG?g_`llFXNv=FJh7)gW;RwRrj{uec#?u+r?t3I$r><L$x#*(v>Cxm)T
z4XrJR|J1zEDu|j+K30f_SE$J-d!w7UO9OuE*wdJearW?#?SYg09ba$eu at +XqnmrXB
z?C{M;?~zk6(|ga4);9cwdbq-J%WO{9>hF*iiq0xq&d9xT`g8p at 1r}OGePA-PX2MNm
z68rBn`ub=HAC&bjTW3nKh_2*T!+_3`-K7S#yGJh at z4)y5sDJZp`<mQKR%g}f;d8=(
zNOEk*8AZSGfSMWss#Y4GD5&cZ5JoKP=#`-Np%1Jppb(`Ta`KxV$sS|f1BS8eBrhyP
zv>fiGY4e)L89wE$Zp<m|5m&4N0(E9_-Wmk2J&#+&YCJGGO51GST3$S<H9Q7pv@%CW
zM<!2(mAraOBnmuNK_b8HxuaBKAi|+mqQNgHcw;_gm6aDWycDY&wk#zr-<j_-twg6K
zy-B21YJSR2A3)*$3LR&ucc;oIDq~ncmgcM21T^Me^~#y~{rbte7RNL#4sN!f)2oi<
zr+3;JwTH0hzspX%33`_UQ8-A`a|Sc&M5-BiQEc<<W#2Huk(CBRcWB0Ei#XSNxRo-a
zFSOjUEZQ(jCh-loonARwa5^*%4o~n5t{OJGiKZp2tk@{#P-{m~r(2Q^E+<t~*Qc#e
zVk`Q|XUAj7{;pupKI5uD_$>iC3!2I;P_5C%fA;IUy88Vam-oT>{FF)L8T;8Q6I!1e
zHWg#9L|PD$dyC&(70TSqxb9%`M1723)FJP_61vSBSiNI<$379duXd$v%o$ND-hDw{
z^r{kWX-zpjJ#{)rRrrq at Ck=bg!rb<!{IXiceIlyryAM~TN!Ip5BQ(F+j<l?W7#8<s
zr~EgWC9jc(98Z1yG+2s=_%@RS->lw$Mi74Pwj>8eupd}U!XJg9V{aswxPFuHRX2F2
zE20hv4&}kXTjdz;)hx__{1GI*WS1yoVf)Bv+zosMDF%7oYmvyNB at 4C}xnw<9*_1~f
zCgY;fmL#As+9|to3u6LcnZ02^xbWl+p>?2uxeS=f%896pY!^kZB$SzpWgB~#>#W&d
zhre~7`O<!J5}l>a0j)Jh(XJim9pxbJUn at rZhhK-Y>WiHLBtq_)1(o=&;#hy$GN1B@
z4L7}ma`AO0{w!a;a_zE*o|iYTU;W`GRRlYqE_$9KIv!^oLy)e!reOKs7=?3B^L|OA
z*NQcD0EY|swd3jb(fNam{RduvvoUA%rolz9{hD6fUihQBBiCQES8(Aq?RTvsM6*Xn
zYj?K88(+;lM5)wYd}45H+<5Fyjtu2Nm5w}lmmQ|*?Qqu;JKP!%zAsHX9Go*(Uwf(h
z{f&1#NwxJiE_rl7KN|*=@e<UErXKJo0*8KFx)t+~`9hI~@z>s24!}Vk(q4HzwID0K
z)~Gq2-GKMU8B9d<f6HUV4LL7O&pMc7f4toHlDaHnc6;b5@<#n&3Tf%uh)U)aQ0oIU
zkAo_67XAeeQP}WBd?k at n%Y*Ev)u)pLJA2q6gswOI)=`PwuV5#PyV<CTnE-Ndl_kgX
z+IKCkWUIN|PjmCNU9}b9;?35ojSi4I_^LZ%i5(ijSTry^B0Os)z9H8*zBOTal;@k7
zT>@?@&kljcR)8}IG(X{~R=4_71i)F8dHHQ1T^R4;^ST3^RyIkC;vR8Au6%IuRyVlP
zg+^GrivhX2;_uh`2BK5n_#%_Z<~W(w#_W%DLyk8PA)@_w?&?<n;T7?y8Jmv#w!?Q&
zcTMK!^0hzOfFku&rW5){!|^%3eZ?hbm=^iWdEUrcV{r{+<#ur$IEXu_Mm!;3UCzxX
z3a7tx`-3xlY^Y=Q){!lWHzX7gJDo^xA+Ei@%bf~Gv%t^3GiDIvn1){!^EBDo+d5>_
z4yubWHKwvEh~36XPx3^9sPJnSt5LV^bHR1cG_OPxy3MnGvi at f0$mq-J-L*&Tw at uwV
z{G*tf)#kRps)LrsW4Fu&(_9CKljbA7-FCi+&KOWLVO^{(ihZxC!DS1+f3Ih{e_FAu
z#$<UqJeK?_{A$7V<h<E87Cfx6NZTw$ZJv{D-HP2AtOIG*30Jb@`i*+$oD|;IfeWOv
zIBIz}*s!2h?UZ}jnB3qN)b(O#A$LXf6%Y4moqLr8yN>a8?0PzMLx1P_;SO1K#%$u+
zif}^s^E5 at 2j(^#-YZJO8t6l1zQ$<WjAx~ljyU at Z`?z2r<S_-_=*Kr}2YSjjDWoE>>
znv<oe6(OCOJAPKOyS{tbbrICqu06<bT9^stop$=va0$kdKIR0&kU=^udK=W0TOpM<
znuc`r+U2FjOm`=wL&p2fxE*>C{bjV_y<>p3CBgi<U%BE9LfMGtdz*xqhXtZkzS~bt
zb15jJK4I=d$yxLnq$b?yJR2Qv7rrC^A!tQ_0tGCD*^O*XOo(r5mG*+O{gykOnr>d_
z8by35ovBvK#b$&8cMthT6O{)VY-<^%7UoORv at OlVBj+~$J5?vhXuASPxx?6_W|UDj
zbjdC_<%tA`c^+z$Q*8OahIbH8hUi8_-jVrX44{xAQBGB>@is4yziVZE4QdEmQ9__n
zz|kkb#_F)s4E4BKNTLw<2`Rw{hXdA3$E#0*F(c(EPd2*0<zA{6zQ9LJrB6iOVr1U*
z{a2{`vng=HI4O!5R at Cc{eevxal<r2U{MT}qzKFmv22(s^^i!wO=;fpPB_&SnqZZn}
z$xu}B(EZb0Zuxo5+LmYRO^!BXl*gD=-uJF3_x91cvFiC1w-3&1I|!+tNoT|-KPeSa
zx&9cV{Z;o at 6}P+7ZVI8ymdabb&`D$Mzm)v3Mkmv^^&Qr(DD6Iyl{&1bZCs8$Tb!54
zut_NwHC=e!>?G&Wbm`8po*Z3nrQ~@te7OZO_zZZzx3;~F=ys2`n0`<wGi!(y4a*8k
zd<Y~c)vEqIKR at 3;CQp{&8s!bo{AupuW%sx_5gnCjobJzRuV!wy<-3nZbb_E+?*Tds
zjqi5HU1ksJ&+L1upW5trXAY~l`_79;X^fcL5o=8CeJ^ub4<Z{1F>^D9hmHfn>o(f^
z{mu^SV^QeqI-A8h;UCZ3tZ1;6m5u{PFAjEZP{z>-P+yNdCW=T*w{*122tX at XQ0l0;
zAD5eVCi>gs-wT)t{M;+4rvhO9lIpl;cH=s10`KTWKKFsCL~%7C^4ifdw{`&qF&q+b
zUM1Y&*BIf4naK3kKvxcBMnfcPn%_XkB%oCycRZJ<A`=4`W3;nl0D4#&!~3NmLMvCt
zk6x6I#-=-<J>1Zgmx_jD3a<Z%+iNVP;TA4+)OW8 at 1b7IQxD@ZG{N6b&D+?>G{(pN#
zF at HxWGajtQA2!NL3}qMai-0_!cAt7{0RgR7$s8UC9Pz3b4l#V2-UD at V64;9hDOZB2
ze1sj%$Js1&kNz-TK!wTxPS>K-luGl&b)|(yuukORy)Nm6M4$5PDsv6S=rB%jx_@!)
zh2yK252i0y97xl9k3p-Gj{p4mGg3L>-a0*q97QA=!t|MJzhchx<%@S!I)8_Md=w-u
zH at 5TZjMRSZ3EY}qoZ*S!D-WZ6>0m(>5xa?Oe6B5ghcA@*^0khZO8hgADUs8EK?v5I
zC)C%%p=IGjgE%ICf$LX?_Jt>Xc;ZEkt>zjE!LOTarvt$P4?K95Ae_&Nv*((O2Qf5Q
zQi+eQ=2A9V8VzII(SxSFIpb1PiIX7~f#U^6VRj0yL~bsc?}r4WexwhGgCwo7Yq&<Z
ze)?)>d}^C>2KwC&ap=vSjuhXi6{M(|Z9P-PDE}v$&TeY8pN*I)eTt<mQE5Gp4EWQi
z<=|xox7^W?1Zj8t=7GeH`*lUvp|n(>cbV2}Z>|s7 at kJzGHm$+SA8_NaqsvcMJ`j;H
zlhOyJ6;+<rP}OnOvR{}8R%AVgC5I^uiX3Yrh242}aFsc{T|%>nnaIRwN?m+b^G<c#
zdoYQaSlm|9)N^k;>i|KA+zpI|n78kKHP^IdZm&21q at o1Vn-tm!fTgCQg#}q$=u#CM
zGP4$MZ&NU`1`>JGGB$f$^XvFEgzr9ojm{V_19CHoddwgUd$hu1;(^T{8p<X8eht}n
zebG7W21JxZ2<U^$re0r|iBI2llGoiG=lO);zsgG2 at H-18ZGT)RS{>6G<;3_KMwQvt
z-r30Q63{`h^FrUtIReOx;ttNgZ)NK~Q6VttR2yL(>AO2b?AcBW5%9=1c5``bPu}Sk
z6e04;V at r4pi(Uj*AgTSOn_7+?7ZIJ}zYIYWx3j~qcaD$lc6aDDoYtp}=c{^LsH8^a
z9eLy$FP6R!LI>u=s62Iv+Kp31j=(tbKyNW00~iCv;2Vlh1e<SAeEHF=$1o(lETZN{
zQ7LV8#pL)S2E@!ZOt at mD>ZyvUH9Bk$*@P3NuGHLdMhtAnDgIZcjv&U?j<w7`o3E#Q
zd0KOjT;ICXJ<|mBi_m-5pp`!ZSN0m8diMzJQ}()a%r(&f7PQ-mH#ZJ%K$NH@&-$Hy
zkVk)f!3 at 3;Bz~^1W#1<C&J>|;-=`?#EqR{CRG+qN{a#L5Oo=?=_B?&`OV%UDp6Z=y
zP)e)kf~T3sUNmI0$2D$DAN*4!p^o&J!+wA{sqK1i)`*Iw%up9%3&nt}ck(%HNmQ-K
zz~U7FUqmvP!2nn>PPb^vyChNJxp&msuSA0!2{f$jI}@sQkLa8_l}|V0KL`Yzed)Ga
zvKxV$^7YaB;@uLu_l$1d2a1xiR}TOUoQL)ua5{<r#Fw%DyA9xrA1b<02~@lRM>nR0
zA;QoL4WMp5)tvGwhn*aWragM=cC`4qca#rh=a3y6_njnt%e)XhxNM(-&9T&=Yp!AR
z(0Ah)>3i7aKvAle!aLHxE~U~^J%bWP{>V%oBRp)~%>-rLag4xHVjuLb>fj|gosnlJ
zwJSg$qnYPlE-zK$wVo!M6yhn-$Pm-P1%D!KPg=nK8o7jYdn&e(jS<Z{A>rSYW_eQ0
zUz&@Pe6?z~v9aGQ`e>TjCel7GEO{cU(t?Inril{ZPDSNXum5XrXWzi$91W=D;LlRZ
zVYrH!o*Q-JYA_4Ma$9_$5!MVL=DN7|Q*K=oT-LT+*-mC?3T=#EZbu;(H2NVlxkLLd
zmlj<JV at BRX|Dl3*0WMzm%kD8_XS6?;atJ9#H_Okiz at 9c;lsH!(L5Y!DSow-?%qh at 4
zO?RC!{(P`TBofU+)vewMBP)%c?z_5wUB>i~9VbIbFp&oJMpo)aiBhm7M+NxoQM=m)
zL2mswxuuUI13qzfK}HR-l!?xdOQ|E(lQliLQbXPg+^>uRA?w+y#|t77_dZl)z|wvL
z_y1YzqB5CCPvag!DhC+2<Ij8sN- at A!Y6#Z^;uhLX*W&vNVfXR=4~P#x9?>hTf;4ZT
zR(5NE3GQmP+*MC8dZfSYw=voE5Yp;vh!$Tn&1FJNfz@<Buxa5#c&4pe!-oYPtRGwS
z*~~<tG(3lq_R<m;IK0dqJ4YDXEAiU|gogcw>-33UePHcf?Q+dKDbE1&&ZBp|=na_^
z$BloRC{$AB52^%v)aT5bui4JAIQFc12D8aAZRQ(fB*FP|va>7eN5+_&;Sj-MZ{9V{
z9A~mi7mJS0{{lx8xa;22s*UAugMp1xm9(^EtyHayZ<7q!<5M}@MQUkp0jG`|X1x2X
z^=@>y*2(!qXDQ3KGRVqMWJBE$-+lMpWsOw>zqPgC`R?7jD;bgN;rs8ufAjOtKR at e>
zGWf2Vx92<kv_qVH7yF*|V0e)19_NbVoQbz at -(KnV)yrDqm0 at pVoa?>z*t=d`ygI<j
z3Wfy0Z@>L^Nz9!^VAAb-Y?aEyT=|g)fz=iPnoL`RX9)~}d8ds#J4UHR2 at L_MJq<GM
zf at b$(2lTn-)CPM{S!ML#DcG5YefKDHHwT;@^piF%akUy?VqgMTw;7pOZKRa}H2Lm(
zUIVjo$~AurZXA%QoTy~c{#}i?2W;KBtS;N5xzDoizysa)D~K=iw}W4ccs1gZ11cE=
ze|<h}RMpkTxmulrr7dlTe}4S<@v7oA!m#nc_0++ek|H(z>Hm5rof^`0Skg3L>ra!C
zRSuU#Ea6ddX)ma_Lwr(pU8$gnxmL~l{U*8gVOmvoJ#{up<vprQ1o*rDlXbDxM`MmL
z_QQt{SMP1lz!+5AA^9LU{v)`<?~@=f*>{eJR`!w(Rs~Kb0AehYq2i8?v~ZBFl2&nt
zxYWIM!W|tdyt8^FmhY~^Lr=Iv3EZj`TZ1RuVa4r)JC;mqTyuYae_8Jv;`<uzC~+z2
z>v=Eku%}AWw*yGU9Tpz;_2I*ZD|0XV>?+HYq!V|DBaS^YYq~YCZk~nNyzF!tijzb@
zCQIk1TC at 7%>)n5McXxTg4r9|&xR#BzM6Qo{hlaJGvi%cEVk}APfMNE!FH3i)X3M&-
z*_Y8i0UNbu3Ejj^cc?bLZ}ZkZwRV7QHniz;6*8S^wpo3zyN+F_P1CY?CQaLHvRbpf
z?$4c?@V6;s5Iu~R4A}%OGimv}t|Rrd7u<Fzs?XOZ{Ozx~=}kVUF1VAtPm&ckxxrpJ
zl!Gk=Q=QdhRn@^{GI=Jc3+$b#vo);@>NGvPvy<9?u(i^r?COf00aEul<pxS*eXl0w
zol<Y_hs?6zdA6vX|5C}!oaKzG+ZXQ55;i7eHbW{g5 at 0%LQ9wTsr-r;qv;9g|2<-b&
zepI{uIc6>K($?Q3#OH5f(3v+ at 8D)8uAIV6!nf5e4$?AkM3mI_bp8_HQu=}Kq*H#V3
zRtua2ohM1~-i3pm+pnog!M&}qiPZ%`{2JIDR3~vFh&jcFecxiI7RQo%&WkcmDdB0a
zjWKPwL$^8E=~Xbq9oqDsa7Sk%`Mh1zo>L>J_6$#hf_pCA!X1l8RtaCj9hKtN?X>py
zUQ36azJxoB%MMU=O)uvC at WT(6HRPI8_0X7p3wMZ#9KTS~SqXdl7S~@{C(9*+RxVGt
zW9!*HAnq^*SzYW%4X>}bV{^1#!W}wUIu at h2qju*@2vlp-rhYM6OZAhJu&o%y9ri^w
zhFf_OceJwani3oQ5!}&p;3}Ch(^A&71v*xE8NOx3+9!7KmI1u3H3lDD6m&xBORdY<
z4)Hee?tYve-62-nM1l}yH4AVytXUeh)ZNBgD at +4Ey81Y5w9UT@+}aOoPdZ>Ou(15@
zqH|GM23Ip$X8V+Rw*gs}%IVsc5yzfXf at 8wcfMNEpc2<jQr4}yy+5mbO3iwt*+;FIs
zMBQ{Jn_4yGJrtEORJJHctL3vSnSD5xuU*qN=IVkbb7wQBiTtibo%9;9Eq%9-;N*NW
zGQ$Q=NrfIxTW?#pOMngh>xY=+M=4H+*IBlAO&bebA18O2Jwt7NbzMBM);_-)Mi`&0
z#;khayHW16pC160$+aIqNsc`-&U)FJR-$9?%&lfj6Tv100|@(Fow-#u%_Ol6yE--Q
z=R5>85YU;-!%f2j?enWCFLS6=MuNfQV&LB?^qno#*$2jTf3LC%otfG<X|+%3jE-uH
zPbPobq}CD0IHmiOJs3 at BJNw1+(1c`3w90|b$f<?wiI~}+D`7Ti8Sdz8q9!fk4)KC!
z8g;?jnwClKUKhM+f;14kJtnXe7;ZnBh`fY5>>tqqPuIWh1(WJdb$<<a$ih2pd?bqo
zBUWPUhw;q)9Nf`)hLRSJ9H_0bvOuL{#T}<!pyCeWuJ5a|dXp`2hrQoc&WcH_jtqB<
zX!=sz(caBlxWnYjWW#4!BGam~eMnY2_q{WJ5N~^Kh&v=3_fGcTOSt2f<DLdOi*wJC
z8C^LRAZ1O)D5|Y?u^Mo;k;Z5YT(}_XP~eb8o3|XABqQI6@`CM_EKR^<W7HzsgjXjV
z7o%XZR(<txH$XcWZJTjZTy27?Ro)3CtW at 8iG)Ay)9`-YA!>H+2lV}p+GnWO|^45mp
z_GOH<8GEPkg30fsYP+5~#>nJ3F<loSeaa2&KGOmTXN%}wBP(P at a1x5&e*5jxsJ5SJ
zaH?hP-lqwv!>u~crp&g|sFmiGGWbl_1m0nJK1&&?Het(Fx*si3Z~ZAx()RRZn`>!Z
zazi;)2lkm*w3kCkP63Md?yQI1w{t}VbCb&mm}HZ5S~D><`Pv%3zrVjQeU(UAt?Gp2
z>C9)hsYPlV>pO2_7N`;gYW8~wE5kLZ*gcqR?2M2pw~DS^dJ{=WsU`)T*`VadKbyR?
z;=bQ)BIla-ejLgvP!lw`W+ho<=J$D(9_=hK?s<k;oe*es`gsRE?;TWfWS^15(#{X(
z|8xkhY_8R#4n^L*uIc>Y;o)+=*PO%3z2gZ?7<I>VpUWl}cPJ4wF4o!7^(ryC`%uCv
z?$DyWxWhB}7Va?77UP(NS`l)sNH8c7wx`X+SKOg2SlnTche_>lhvaE-hv&xrZSuR?
zWWR<xIy=yJsZ7$rm`bX3VzZ)Ag8VhyAu+VyF;&veF8jqRwL2vb`<W8iCIJ#@C){D5
zlTLeElNvpVJGMS<;f_56afd&5!X51`l(ZiCH-(GD$@cgOcN7C`UG{8qy$^r3w?^Et
zYrRTlwy8dR_;59u)5K;6z5|d9R)R+#fMx*$$;x$>q1o)?234DH`Cmzm*{=_7n#yLm
zYWR2P4WyU}jw#fY$p%Hs=-Xr-(6X)0Qn4a6&3Ijhlou%J^6>8Lp7ze{9gGc_WY1(l
zAX>u#0gQ4(1K_;PW!?7kHcFca2^JjWwm`Rlpgd*oPe#%A*$vpFp!)K<mYnQXoyabj
z_rO{+@(y~3+YMY;>X*@IbNJrN0=m+PU5_(tlwk>U_wzE_%K4nUY>*ec)bY*owUtVf
z1(Tr>6;>5=vD)4!INUo~FsqDgpRu)kcX#*Z;o;$`6kf|)88XcnwTI!G1dniSh`
ztGl9=>^-xw^3~}}p439!YEKgrW5LIdAK$!t_wI at jc1D2*u at xNMa%{9O11Y$WZPX^#
zgKBGDfbX0nD?z*7#liM18rLR~P&dD4^7#08HSkvVB3=0Q?^=5sKXd{zIh5tLx>om}
z4m(vcX}qzow9a2+=XVw_5j82&gv2=V%{Sj%Dvdho)s|QQ<vq!A8?#oux5s7cV*A`P
zq=PF3CGP*lo87C#z+%HK++p=lDQ(SoiaShHPPjuL*s1Ns9VI%4gPb)|^NJ3*wYRhO
zxf+Yq7~wRS(Cb+|^*Qc3x8EG7soc%p=-NvcckFtGwftRMGmB3<-&D8w&NMnwhG&Jq
zc`hc%oljTX;Tlp7Chn;G(Td**cUXxL?;6h?M&5RZ4y<fXla<`!4oSoHSS~hbdSgt|
zF}6LblLJaf8SjT77sqemjy+Ff=?InKNu|)IK0k4X#EO>HKJ%+&MxF0zs7>cvbk>I#
zRWR}W_us#HczC!f51uR~1+ at ki8=z#<I at qm4l+-NlA<5==7|L3#cf%Jh`!DEJCo5C2
zV75kG7k{<G_7Taf$Os4`4Khm1ERj0RehkLIpBrrDWD}19)0U5YXM*zrRpo_k)>Px#
zBvSUGzq>M+lP<IFGbSu`|2Q3pHUjsZx$zz!A20XNY2v53GM0DSoY{eaf-G4cH at CV}
z<vv{(W1MzfV|I2=Cz-{mans?mONgr3_WK4-y>EfE at uB+IN>>B`CSP at La%PV<l66cw
zxvwZs5Gd%u?}1ghrq56|teSfNuKHu&Stn3;a(68 at ci2`&S7#;VI2{t}8fq^^b@!)P
z5~p|Ap at zyR+*dwdfleKY_I#Cfn9OZ*xzDumNU4I)w)eAlxb?R+?fIlsv(43=lVPvW
zX^3=(1Q(cX-3~OgqURay-V_vj7CB*E7eL8F%_FRQ_nb9u8>1a&DhS`dkC<sf;2taP
zP_`@CP+R7gaEIi?33pgI5_bs1Ob)uIbw_kooAFZORoqeVUEHDM$ltlxCGMytadC&e
zA~ixW&fdZur_mV7+J-y!UNuKhHtkuVoX_`PJAcgxjALR^D{GPr+9QiGJZE(Pd<l0*
z0;<ALj{X|%Sn_8NkfhJ{)z-8IFP_E9A-(Uu-{OvrPI2!ScNAk)#<#WGYOJ5<Kv&mW
zamUVYhkP1qo>?=SRh2pOAZw7krHfQQekzR{C~THgt2|ISu<I1vmaSV|DI3>@Ho>HG
zY4pRdqnK3^89rH0oqA*m)JFSUckl|>YBy-FNL?>vEcN#ms5&9nL*4i3zw316!PbUG
zH>EmfH%R-i>Y}3lzm40<x0HFPf&TdM<ArszCqS30CK&~f9$Y5pb=mO%?W_#f`YI*@
z7x#l&bE_Sb?3oCaVcuHaT5S_=8S%~!@ZP%Dwug2I?mbx<8Ca}SkwJMnYYB)}|7^_f
z?1SCIdfb$5j*;?k-tW@!MQP{L)6-=?S~1neSGkr>U8nh0-9JhX>|fDtc1-gQ3)x=R
z*7l#?{;sWChhjlufzzrrO~z#FOv<gsd$5#w_jf6I-S1kzfPELfa}V{M0ahWbfQ^t^
z<;>>q+1KhcCcD1(zvrVA+9de2rpN3%nOYF9d5ZVvbKco%l|}ci0x$<9njG)5KYsjp
z6%UNj5 at B_Z8hAC?^*lE*vI=U_B#?0aoP?xqa8FN9m;2FrSn|MX|H)9H(sE;~AlQ3T
zsweKy#ZiYyd)i*Y9S%<UoLt at j00mY_L_t&?$iIa<dN1OR#nM&t#T`~h>^HiFJ636E
z-|?x}%!J>)u5pP5M)oe7EDU$_96I3+&#~^Ity|BXlly6#;Kdzcs#Z!Q;VL=Pj@?9h
z&&Kz0!X0ywEWuOUaceN=E!-i&Qd1ohfcC11QFRjC+Ho!EM0y&q>8z=}-~Em{@O6fl
z$>`RmIH-Mc_O2FpSaGzU+BNj7XJ$X}_U+qC<~-n_?4nbL)yr<dS|QnuDi>2$WLdd3
zs4|dl1OvT^gcXJkGpgfIo1;73bQ at BOx|JVSqBSG+FcWN49 at 7caHnJ^2J4p~suv)@*
zc;!h4yFfdD<UE<OJJUnj{O0>Lqu1ZQERE8eF8t~s1tD8=mPuu^OhRQ9WOik+R+ZZN
z>mXRALo%W!$dx*&ORu!h;LwEe?c29kmV^cmWo<T|FNpX~YscK-n{5=`^|)?Vs<%mZ
zzh^(Yy`){OiIV>N`uO`yW&1mKN;#n#Shehy?N3dT%Go-}e!)^p%$3t+3hM@=wQT2{
zbS8`XbPq)vcD?Uv?@cDFxtAq&uYCLMx0l&LnzG!Q5zuMum2qsXjy+S}FaWIFwr+6t
z?>T?OHEmzb_Mg(3&i-+q*FDJlR#7mC=4l9H->a;&_WW7~FX42**n888W)J?Y0W0fP
zi_4bp9I5=&vq{;W?w|X)fk~@U`@DgBi6(8I1vMr@`?KeZeH^-x8TSPAtxVb^z1Sn}
zSVCWOks6HHAZ=x9&(FRdo3&5Qf&%|9#T}lrUxGVoalH!7&Z`sdknmg|r?^8xb7zz@
z?;LNj&#f%Z7$xq|fzZZ#38WM5=o~xOr%t0M+;JKUvc2guv^uLiUV=k_?!L5Ab7~{-
zec!?zjRnIUl5Wa1Pq;(*p_0$f!5t1^6-R2X{H3^~R_L$c4l(VnXH}Se-`=$@dAD#!
zO~6!-Y>)oOfBeUrZ~pq%zyAK`KmYlP;q&3yEU3$j0ZgflENd5jts4dCmiH|m+1y&&
zX9K;Ao`AL%mMw=HX#80jsl5axM at oX+L`s!9!M0Pj9b#n9$;mNI`ICA at S%}&Jx&UNO
zPHrOFYg*3U=2`=@V5)1NPF4mDnVk+|^85O3dJxKz_&disszomYS-U?2q#AJ>C at m$Q
zeEeOzrwO-p7*PghvSs4xfmoJbmenR&4<aR^9{z#^_1R4<+FRB+9ZH5O{iqeH_fU5!
zlkmQC-M3_>WOequEmv#M;2_O<=<nwQ?<T9t&-{B6qyl)q=d>qf<?ZX*;npE(1&r<?
zhfum!wf^jyE;HNrX`*;yD?OlUFWd(1N`{o<3h3I4W{*rA*G|pr?HTbMmt?a#-e+Bl
z(#~0G71802UDGy}TSau=m2EAko;B=%$ey1K<<6UMa=P}vm2}F`pLz}(Gku;*INTpy
z(^|ZaX;&_Es$?58JN!`GA&@=oJFopqa7QI(t}*3LUxGVMvG;VgSxNmI+|k)9ui*~k
zuJ8CI+|iK<;*Rcr6$GCBjY~@)_x%15+|ju at ui*~+V~ab)6ffZpd%`{!cZgZ*Sok@(
zqcVH at f&V*kNB8>)i%6<{3GUEZUiHTx#T_b>T=W0_ at BjYhn}7SafBXF}fBDN*Mc~$#
zAo)wb{*j;k|MK;J=^1?KwbZ at jbAR@K^Pd06 at A}{RnXg~}f7bN>_4WDnz5nya=s$WL
z|C87M-|^Z1+k4=jb^rW-T+{z(jQ*eaJ^xH=+P<EzXTqB+DdgY&_O~~G`t<43o4 at _-
zZ(kqI*RQW%U%$S7ef|3S_4VuP*VnJFUthoeX%hcWpFX|$FITqO at z-8nT>t<807*qo
IM6N<$f~8PYD*ylh
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/i18n.py b/src/wok/plugins/kimchi/i18n.py
new file mode 100644
index 0000000..253f00d
--- /dev/null
+++ b/src/wok/plugins/kimchi/i18n.py
@@ -0,0 +1,335 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gettext
+
+_ = gettext.gettext
+
+
+messages = {
+ "KCHAPI0001E": _("Unknown parameter %(value)s"),
+
+ "KCHASYNC0003E": _("Timeout of %(seconds)s seconds expired while running task '%(task)s."),
+
+ "KCHAUTH0004E": _("User %(user_id)s not found with given LDAP settings."),
+
+ "KCHDEVS0001E": _('Unknown "_cap" specified'),
+ "KCHDEVS0002E": _('"_passthrough" should be "true" or "false"'),
+ "KCHDEVS0003E": _('"_passthrough_affected_by" should be a device name string'),
+
+ "KCHDISKS0001E": _("Error while getting block devices. Details: %(err)s"),
+ "KCHDISKS0002E": _("Error while getting block device information for %(device)s."),
+
+ "KCHDL0001E": _("Unable to find distro file: %(filename)s"),
+ "KCHDL0002E": _("Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."),
+
+ "KCHISCSI0001E": _("Unable to login to iSCSI host target %(portal)s. Details: %(err)s"),
+ "KCHISCSI0002E": _("Unable to login to iSCSI host %(host)s target %(target)s"),
+
+ "KCHISO0001E": _("Unable to find ISO file %(filename)s"),
+ "KCHISO0002E": _("The ISO file %(filename)s is not bootable"),
+ "KCHISO0003E": _("The ISO file %(filename)s does not have a valid El Torito boot record"),
+ "KCHISO0004E": _("Invalid El Torito validation entry in ISO %(filename)s"),
+ "KCHISO0005E": _("Invalid El Torito boot indicator in ISO %(filename)s"),
+ "KCHISO0006E": _("Unexpected volume type for primary volume in ISO %(filename)s"),
+ "KCHISO0007E": _("Bad format while reading volume descriptor in ISO %(filename)s"),
+ "KCHISO0008E": _("The hypervisor doesn't have permission to use this ISO %(filename)s. "
+ "Consider moving it under /var/lib/libvirt, or set the search permission "
+ "to file access control lists for '%(user)s' user if possible, or add the "
+ "'%(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x 'path_to_iso'."
+ "Details: %(err)s" ),
+
+ "KCHIMG0001E": _("An error occurred when probing image OS information."),
+ "KCHIMG0002E": _("No OS information found in given image."),
+ "KCHIMG0003E": _("Unable to read image file %(filename)s"),
+ "KCHIMG0004E": _("Image file must be an existing file on system. %(filename)s is not a valid input."),
+
+ "KCHVM0001E": _("Virtual machine %(name)s already exists"),
+ "KCHVM0002E": _("Virtual machine %(name)s does not exist"),
+ "KCHVM0003E": _("Unable to rename virtual machine %(name)s. The name %(new_name)s is already in use or the virtual machine is not powered off."),
+ "KCHVM0004E": _("Unable to retrieve screenshot for stopped virtual machine %(name)s"),
+ "KCHVM0005E": _("Remote ISO image is not supported by this server."),
+ "KCHVM0006E": _("Screenshot is not supported on virtual machine %(name)s"),
+ "KCHVM0007E": _("Unable to create virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0008E": _("Unable to update virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0009E": _("Unable to retrieve virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0010E": _("Unable to connect to powered off virtual machine %(name)s."),
+ "KCHVM0011E": _("Virtual machine name must be a string without slashes (/)"),
+ "KCHVM0012E": _("Invalid template URI %(value)s specified for virtual machine"),
+ "KCHVM0013E": _("Invalid storage pool URI %(value)s specified for virtual machine"),
+ "KCHVM0014E": _("Supported virtual machine graphics are Spice or VNC"),
+ "KCHVM0015E": _("Graphics address to listen on must be IPv4 or IPv6"),
+ "KCHVM0016E": _("Specify a template to create a virtual machine from"),
+ "KCHVM0019E": _("Unable to start virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0020E": _("Unable to power off virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0021E": _("Unable to delete virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0022E": _("Unable to reset virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0023E": _("User name list must be an array"),
+ "KCHVM0024E": _("User name must be a string"),
+ "KCHVM0025E": _("Group name list must be an array"),
+ "KCHVM0026E": _("Group name must be a string"),
+ "KCHVM0027E": _("User(s) '%(users)s' do not exist"),
+ "KCHVM0028E": _("Group(s) '%(groups)s' do not exist"),
+ "KCHVM0029E": _("Unable to shutdown virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0030E": _("Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"),
+ "KCHVM0031E": _("The guest console password must be a string."),
+ "KCHVM0032E": _("The life time for the guest console password must be a number."),
+ "KCHVM0033E": _("Virtual machine '%(name)s' must be stopped before cloning it."),
+ "KCHVM0034E": _("Insufficient disk space to clone virtual machine '%(name)s'"),
+ "KCHVM0035E": _("Unable to clone VM '%(name)s'. Details: %(err)s"),
+ "KCHVM0036E": _("Invalid operation for non-persistent virtual machine %(name)s"),
+ "KCHVM0037E": _("Cannot suspend VM '%(name)s' because it is not running."),
+ "KCHVM0038E": _("Unable to suspend VM '%(name)s'. Details: %(err)s"),
+ "KCHVM0039E": _("Cannot resume VM '%(name)s' because it is not paused."),
+ "KCHVM0040E": _("Unable to resume VM '%(name)s'. Details: %(err)s"),
+ "KCHVM0041E": _("Memory assigned is higher then the maximum allowed in the host."),
+ "KCHVM0042E": _("VM '%(name)s' does not support live memory update. Update the memory with the machine offline to enable this feature."),
+ "KCHVM0043E": _("Only increase memory is allowed in active VMs"),
+ "KCHVM0044E": _("For live memory update, new memory value must be equal old memory value plus multiples of 1024 Mib"),
+ "KCHVM0045E": _("There are not enough free slots of 1024 Mib in the guest."),
+ "KCHVM0046E": _("Host's libvirt version does not support memory devices. Libvirt must be >= 1.2.14"),
+ "KCHVM0047E": _("Error attaching memory device. Details: %(error)s"),
+
+ "KCHVMHDEV0001E": _("VM %(vmid)s does not contain directly assigned host device %(dev_name)s."),
+ "KCHVMHDEV0002E": _("The host device %(dev_name)s is not allowed to directly assign to VM."),
+ "KCHVMHDEV0003E": _("No IOMMU groups found. Host PCI pass through needs IOMMU group to function correctly. "
+ "Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify the Kernel is compiled with IOMMU support. "
+ "For Intel CPU, add intel_iommu=on to your Kernel parameter in /boot/grub2/grub.conf. "
+ "For AMD CPU, add iommu=pt iommu=1."),
+ "KCHVMHDEV0004E": _('"name" should be a device name string'),
+ "KCHVMHDEV0005E": _('The device %(name)s is probably in use by the host. Unable to attach it to the guest.'),
+
+ "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"),
+ "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"),
+ "KCHVMIF0004E": _("Supported virtual machine interfaces type is only network"),
+ "KCHVMIF0005E": _("Network name for virtual machine interface must be a string"),
+ "KCHVMIF0006E": _("Invalid network model card specified for virtual machine interface"),
+ "KCHVMIF0007E": _("Specify type and network to add a new virtual machine interface"),
+ "KCHVMIF0008E": _("MAC Address must respect this format FF:FF:FF:FF:FF:FF"),
+ "KCHVMIF0009E": _("MAC Address %(mac)s already exists in virtual machine %(name)s"),
+ "KCHVMIF0010E": _("Invalid MAC Address"),
+ "KCHVMIF0011E": _("Cannot change MAC address of a running virtual machine"),
+
+ "KCHTMPL0001E": _("Template %(name)s already exists"),
+ "KCHTMPL0003E": _("Network '%(network)s' specified for template %(template)s does not exist"),
+ "KCHTMPL0004E": _("Storage pool %(pool)s specified for template %(template)s does not exist"),
+ "KCHTMPL0005E": _("Storage pool %(pool)s specified for template %(template)s is not active"),
+ "KCHTMPL0006E": _("Invalid parameter '%(param)s' specified for CDROM."),
+ "KCHTMPL0007E": _("Network %(network)s specified for template %(template)s is not active"),
+ "KCHTMPL0008E": _("Template name must be a string"),
+ "KCHTMPL0009E": _("Template icon must be a path to the image"),
+ "KCHTMPL0010E": _("Template distribution must be a string"),
+ "KCHTMPL0011E": _("Template distribution version must be a string"),
+ "KCHTMPL0012E": _("The number of CPUs must be an integer greater than 0"),
+ "KCHTMPL0013E": _("Amount of memory (MB) must be an integer greater than 512"),
+ "KCHTMPL0014E": _("Template CDROM must be a local or remote ISO file"),
+ "KCHTMPL0015E": _("Invalid storage pool URI %(value)s specified for template"),
+ "KCHTMPL0016E": _("Specify an ISO image as CDROM or a base image to create a template"),
+ "KCHTMPL0017E": _("All networks for the template must be specified in a list."),
+ "KCHTMPL0018E": _("Specify a volume to a template when storage pool is iSCSI or SCSI"),
+ "KCHTMPL0019E": _("The volume %(volume)s is not in storage pool %(pool)s"),
+ "KCHTMPL0020E": _("Unable to create template due error: %(err)s"),
+ "KCHTMPL0021E": _("Unable to delete template due error: %(err)s"),
+ "KCHTMPL0022E": _("Disk size must be an integer greater than 1GB."),
+ "KCHTMPL0023E": _("Template base image must be a valid local image file"),
+ "KCHTMPL0024E": _("Cannot identify base image %(path)s format"),
+ "KCHTMPL0025E": _("When specifying CPU topology, VCPUs must be a product of sockets, cores, and threads."),
+ "KCHTMPL0026E": _("When specifying CPU topology, each element must be an integer greater than zero."),
+ "KCHTMPL0027E": _("Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
+
+ "KCHPOOL0001E": _("Storage pool %(name)s already exists"),
+ "KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
+ "KCHPOOL0004E": _("Specify %(item)s in order to create the storage pool %(name)s"),
+ "KCHPOOL0005E": _("Unable to delete active storage pool %(name)s"),
+ "KCHPOOL0006E": _("Unable to list storage pools. Details: %(err)s"),
+ "KCHPOOL0007E": _("Unable to create storage pool %(name)s. Details: %(err)s"),
+ "KCHPOOL0008E": _("Unable to get number of storage volumes in storage pool %(name)s. Details: %(err)s"),
+ "KCHPOOL0009E": _("Unable to activate storage pool %(name)s. Details: %(err)s"),
+ "KCHPOOL0010E": _("Unable to deactivate storage pool %(name)s. Details: %(err)s"),
+ "KCHPOOL0011E": _("Unable to delete storage pool %(name)s. Details: %(err)s"),
+ "KCHPOOL0012E": _("Unable to create NFS Pool as export path %(path)s may block during mount"),
+ "KCHPOOL0013E": _("Unable to create NFS Pool as export path %(path)s mount failed"),
+ "KCHPOOL0014E": _("Unsupported storage pool type: %(type)s"),
+ "KCHPOOL0015E": _("Error while retrieving storage pool XML to %(pool)s"),
+ "KCHPOOL0016E": _("Storage pool name must be a string without slashes (/)"),
+ "KCHPOOL0017E": _("Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-iso"),
+ "KCHPOOL0018E": _("Storage pool path must be a string"),
+ "KCHPOOL0019E": _("Storage pool host must be a IP or hostname"),
+ "KCHPOOL0020E": _("Storage pool device must be the absolute path to the block device"),
+ "KCHPOOL0021E": _("Storage pool devices parameter must be a list"),
+ "KCHPOOL0022E": _("Target IQN of an iSCSI pool must be a string"),
+ "KCHPOOL0023E": _("Port of a remote storage server must be an integer between 1 and 65535"),
+ "KCHPOOL0024E": _("iSCSI target username must be a string"),
+ "KCHPOOL0025E": _("iSCSI target password must be a string"),
+ "KCHPOOL0026E": _("Specify name and type to create a storage pool"),
+ "KCHPOOL0027E": _("%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)s."),
+ "KCHPOOL0028E": _("Unable to extend logical pool %(pool)s. Details: %(err)s"),
+ "KCHPOOL0029E": _("The parameter disks only can be updated for logical storage pool."),
+ "KCHPOOL0030E": _("The SCSI host adapter name must be a string."),
+ "KCHPOOL0031E": _("The storage pool kimchi_isos is reserved for internal use"),
+ "KCHPOOL0032E": _("Unable to activate NFS storage pool %(name)s. NFS server %(server)s is unreachable."),
+ "KCHPOOL0033E": _("Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is unreachable."),
+ "KCHPOOL0034E": _("Unable to deactivate pool %(name)s as it is associated with some templates"),
+ "KCHPOOL0035E": _("Unable to delete pool %(name)s as it is associated with some templates"),
+ "KCHPOOL0036E": _("A volume group named '%(name)s' already exists. Please, choose another name to create the logical pool."),
+ "KCHPOOL0037E": _("Unable to update database with deep scan information due error: %(err)s"),
+
+ "KCHVOL0001E": _("Storage volume %(name)s already exists"),
+ "KCHVOL0002E": _("Storage volume %(name)s does not exist in storage pool %(pool)s"),
+ "KCHVOL0003E": _("Unable to create storage volume %(volume)s because storage pool %(pool)s is not active"),
+ "KCHVOL0004E": _("Specify %(item)s in order to create storage volume %(volume)s"),
+ "KCHVOL0006E": _("Unable to list storage volumes because storage pool %(pool)s is not active"),
+ "KCHVOL0007E": _("Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %(err)s"),
+ "KCHVOL0008E": _("Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"),
+ "KCHVOL0009E": _("Unable to wipe storage volumes %(name)s. Details: %(err)s"),
+ "KCHVOL0010E": _("Unable to delete storage volume %(name)s. Details: %(err)s"),
+ "KCHVOL0011E": _("Unable to resize storage volume %(name)s. Details: %(err)s"),
+ "KCHVOL0012E": _("Storage type %(type)s does not support volume create and delete"),
+ "KCHVOL0013E": _("Storage volume name must be a string"),
+ "KCHVOL0014E": _("Storage volume allocation must be an integer number"),
+ "KCHVOL0015E": _("Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
+ "KCHVOL0016E": _("Storage volume requires a volume name"),
+ "KCHVOL0017E": _("Unable to update database with storage volume information due error: %(err)s"),
+ "KCHVOL0018E": _("Only one of parameter %(param)s can be specified"),
+ "KCHVOL0019E": _("Create volume from %(param)s is not supported"),
+ "KCHVOL0020E": _("Storage volume capacity must be an integer number."),
+ "KCHVOL0021E": _("Storage volume URL must be http://, https://, ftp:// or ftps://."),
+ "KCHVOL0022E": _("Unable to access file %(url)s. Please, check it."),
+ "KCHVOL0023E": _("Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)s"),
+ "KCHVOL0024E": _("Specify chunk data and its size to upload a file."),
+ "KCHVOL0025E": _("In order to upload a storage volume, specify the 'upload' parameter."),
+ "KCHVOL0026E": _("Unable to upload chunk data as it does not match with requested chunk size."),
+ "KCHVOL0027E": _("The storage volume %(vol)s is not under an upload process."),
+ "KCHVOL0028E": _("The upload chunk data will exceed the storage volume size."),
+ "KCHVOL0029E": _("Unable to upload chunk data to storage volume. Details: %(err)s."),
+
+ "KCHIFACE0001E": _("Interface %(name)s does not exist"),
+
+ "KCHNET0001E": _("Network %(name)s already exists"),
+ "KCHNET0002E": _("Network %(name)s does not exist"),
+ "KCHNET0003E": _("Subnet %(subnet)s specified for network %(network)s is not valid."),
+ "KCHNET0004E": _("Specify a network interface to create bridged network %(name)s"),
+ "KCHNET0005E": _("Unable to delete active network %(name)s"),
+ "KCHNET0006E": _("Interface %(iface)s specified for network %(network)s is already in use"),
+ "KCHNET0007E": _("Interface should be bare NIC, bonding or bridge device."),
+ "KCHNET0008E": _("Unable to create network %(name)s. Details: %(err)s"),
+ "KCHNET0009E": _("Unable to find a free IP address for network '%(name)s'"),
+ "KCHNET0010E": _("The interface %(iface)s already exists."),
+ "KCHNET0011E": _("Network name must be a string without slashes (/) or quotes (\")"),
+ "KCHNET0012E": _("Supported network types are isolated, NAT and bridge"),
+ "KCHNET0013E": _("Network subnet must be a string with IP address and prefix or netmask"),
+ "KCHNET0014E": _("Network interface must be a string"),
+ "KCHNET0015E": _("Network VLAN ID must be an integer between 1 and 4094"),
+ "KCHNET0016E": _("Specify name and type to create a Network"),
+ "KCHNET0017E": _("Unable to delete network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."),
+ "KCHNET0018E": _("Unable to deactivate network %(name)s. There are some virtual machines %(vms)s and/or templates linked to this network."),
+ "KCHNET0019E": _("Bridge device %(name)s can not be the trunk device of a VLAN."),
+ "KCHNET0020E": _("Failed to activate interface %(iface)s: %(err)s."),
+ "KCHNET0021E": _("Failed to activate interface %(iface)s. Please check the physical link status."),
+ "KCHNET0022E": _("Failed to start network %(name)s. Details: %(err)s"),
+
+ "KCHDR0001E": _("Debug report %(name)s does not exist"),
+ "KCHDR0002E": _("Debug report tool not found in system"),
+ "KCHDR0003E": _("Unable to create debug report %(name)s. Details: %(err)s."),
+ "KCHDR0004E": _("Can not find any debug report with the given name %(name)s"),
+ "KCHDR0005E": _("Unable to generate debug report %(name)s. Details: %(err)s"),
+ "KCHDR0006E": _("You should give a name for the debug report file."),
+ "KCHDR0007E": _("Debug report name must be a string. Only letters, digits, underscore ('_') and hyphen ('-') are allowed."),
+ "KCHDR0008E": _("The debug report with specified name \"%(name)s\" already exists. Please use another one."),
+
+ "KCHSR0001E": _("Storage server %(server)s was not used by Kimchi"),
+
+ "KCHDISTRO0001E": _("Distro '%(name)s' does not exist"),
+
+ "KCHPART0001E": _("Partition %(name)s does not exist in the host"),
+
+ "KCHHOST0001E": _("Unable to shutdown host machine as there are running virtual machines"),
+ "KCHHOST0002E": _("Unable to reboot host machine as there are running virtual machines"),
+ "KCHHOST0003E": _("Node device '%(name)s' not found"),
+ "KCHHOST0004E": _("Conflicting flag filters specified."),
+
+ "KCHPKGUPD0001E": _("No packages marked for update"),
+ "KCHPKGUPD0002E": _("Package %(name)s is not marked to be updated."),
+ "KCHPKGUPD0003E": _("Error while getting packages marked to be updated. Details: %(err)s"),
+ "KCHPKGUPD0004E": _("There is no compatible package manager for this system."),
+
+ "KCHUTILS0003E": _("Unable to choose a virtual machine name"),
+
+ "KCHVMSTOR0002E": _("Invalid storage type. Types supported: 'cdrom', 'disk'"),
+ "KCHVMSTOR0003E": _("The path '%(value)s' is not a valid local/remote path for the device"),
+ "KCHVMSTOR0006E": _("Only CDROM path can be update."),
+ "KCHVMSTOR0007E": _("The storage device %(dev_name)s does not exist in the virtual machine %(vm_name)s"),
+ "KCHVMSTOR0008E": _("Error while creating new storage device: %(error)s"),
+ "KCHVMSTOR0009E": _("Error while updating storage device: %(error)s"),
+ "KCHVMSTOR0010E": _("Error while removing storage device: %(error)s"),
+ "KCHVMSTOR0011E": _("Do not support IDE device hot plug"),
+ "KCHVMSTOR0012E": _("Specify type and path or type and pool/volume to add a new virtual machine disk"),
+ "KCHVMSTOR0013E": _("Specify path to update virtual machine disk"),
+ "KCHVMSTOR0014E": _("Controller type %(type)s limitation of %(limit)s devices reached"),
+ "KCHVMSTOR0015E": _("Cannot retrieve disk path information for given pool/volume: %(error)s"),
+ "KCHVMSTOR0016E": _("Volume already in use by other virtual machine."),
+ "KCHVMSTOR0017E": _("Only one of path or pool/volume can be specified to add a new virtual machine disk"),
+ "KCHVMSTOR0018E": _("Volume chosen with format %(format)s does not fit in the storage type %(type)s"),
+
+ "KCHREPOS0001E": _("YUM Repository ID must be one word only string."),
+ "KCHREPOS0002E": _("Repository URL must be an http://, ftp:// or file:// URL."),
+ "KCHREPOS0003E": _("Repository configuration is a dictionary with specific values according to repository type."),
+ "KCHREPOS0004E": _("Distribution to DEB repository must be a string"),
+ "KCHREPOS0005E": _("Components to DEB repository must be listed in a array"),
+ "KCHREPOS0006E": _("Components to DEB repository must be a string"),
+ "KCHREPOS0007E": _("Mirror list to repository must be a string"),
+ "KCHREPOS0008E": _("YUM Repository name must be string."),
+ "KCHREPOS0009E": _("GPG check must be a boolean value."),
+ "KCHREPOS0010E": _("GPG key must be a URL pointing to the ASCII-armored file."),
+ "KCHREPOS0011E": _("Could not update repository %(repo_id)s."),
+ "KCHREPOS0012E": _("Repository %(repo_id)s does not exist."),
+ "KCHREPOS0013E": _("Specify repository base URL, mirror list or metalink in order to create or update a YUM repository."),
+ "KCHREPOS0014E": _("Repository management tool was not recognized for your system."),
+ "KCHREPOS0015E": _("Repository %(repo_id)s is already enabled."),
+ "KCHREPOS0016E": _("Repository %(repo_id)s is already disabled."),
+ "KCHREPOS0017E": _("Could not remove repository %(repo_id)s."),
+ "KCHREPOS0018E": _("Could not write repository configuration file %(repo_file)s"),
+ "KCHREPOS0019E": _("Specify repository distribution in order to create a DEB repository."),
+ "KCHREPOS0020E": _("Could not enable repository %(repo_id)s."),
+ "KCHREPOS0021E": _("Could not disable repository %(repo_id)s."),
+ "KCHREPOS0022E": _("YUM Repository ID already exists"),
+ "KCHREPOS0023E": _("YUM Repository name must be a string"),
+ "KCHREPOS0024E": _("Unable to list repositories. Details: '%(err)s'"),
+ "KCHREPOS0025E": _("Unable to retrieve repository information. Details: '%(err)s'"),
+ "KCHREPOS0026E": _("Unable to add repository. Details: '%(err)s'"),
+ "KCHREPOS0027E": _("Unable to remove repository. Details: '%(err)s'"),
+ "KCHREPOS0028E": _("Configuration items: '%(items)s' are not supported by repository manager"),
+ "KCHREPOS0029E": _("Repository metalink must be an http://, ftp:// or file:// URL."),
+ "KCHREPOS0030E": _("Cannot specify mirrorlist and metalink at the same time."),
+
+ "KCHSNAP0001E": _("Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."),
+ "KCHSNAP0002E": _("Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0003E": _("Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."),
+ "KCHSNAP0004E": _("Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0005E": _("Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0006E": _("Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0008E": _("Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0009E": _("Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %(err)s"),
+ "KCHSNAP0010E": _("Unable to create snapshot of virtual machine '%(vm)s' because it contains a disk with format '%(format)s'; only 'qcow2' is supported."),
+
+ "KCHCPUINF0001E": _("The number of vCPUs is too large for this system."),
+ "KCHCPUINF0002E": _("Invalid vCPU/topology combination."),
+ "KCHCPUINF0003E": _("This host (or current configuration) does not allow CPU topology."),
+
+}
diff --git a/src/wok/plugins/kimchi/imageinfo.py b/src/wok/plugins/kimchi/imageinfo.py
new file mode 100644
index 0000000..8a22495
--- /dev/null
+++ b/src/wok/plugins/kimchi/imageinfo.py
@@ -0,0 +1,72 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import guestfs
+import json
+import os
+import sys
+
+from wok.exception import ImageFormatError, InvalidParameter, TimeoutExpired
+from wok.utils import run_command, wok_log
+
+
+def probe_img_info(path):
+ cmd = ["qemu-img", "info", "--output=json", path]
+ info = dict()
+ try:
+ out = run_command(cmd, 10)[0]
+ except TimeoutExpired:
+ wok_log.warning("Cannot decide format of base img %s", path)
+ return None
+
+ info = json.loads(out)
+ info['virtual-size'] = info['virtual-size'] >> 30
+ info['actual-size'] = info['actual-size'] >> 30
+ return info
+
+
+def probe_image(image_path):
+ if not os.path.isfile(image_path):
+ raise InvalidParameter("KCHIMG0004E", {'filename': image_path})
+
+ if not os.access(image_path, os.R_OK):
+ raise ImageFormatError("KCHIMG0003E", {'filename': image_path})
+
+ g = guestfs.GuestFS(python_return_dict=True)
+ g.add_drive_opts(image_path, readonly=1)
+ g.launch()
+
+ try:
+ roots = g.inspect_os()
+ except:
+ raise ImageFormatError("KCHIMG0001E")
+
+ if len(roots) == 0:
+ raise ImageFormatError("KCHIMG0002E")
+
+ for root in roots:
+ version = "%d.%d" % (g.inspect_get_major_version(root),
+ g.inspect_get_minor_version(root))
+ distro = "%s" % (g.inspect_get_distro(root))
+
+ return (distro, version)
+
+
+if __name__ == '__main__':
+ print probe_image(sys.argv[1])
diff --git a/src/wok/plugins/kimchi/iscsi.py b/src/wok/plugins/kimchi/iscsi.py
new file mode 100644
index 0000000..02886ac
--- /dev/null
+++ b/src/wok/plugins/kimchi/iscsi.py
@@ -0,0 +1,88 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301USA
+
+import subprocess
+
+
+from wok.exception import OperationFailed
+
+
+class TargetClient(object):
+ def __init__(self, target, host, port=None, auth=None):
+ self.portal = host + ("" if port is None else ":%s" % port)
+ self.target = target
+ self.auth = auth
+ self.targetCmd = ['iscsiadm', '--mode', 'node', '--targetname',
+ self.target, '--portal', self.portal]
+
+ def _update_db(self, Name, Value):
+ self._run_cmd(['--op=update', '--name', Name, '--value', Value])
+
+ def _update_auth(self):
+ if self.auth is None:
+ items = (('node.session.auth.authmethod', 'None'),
+ ('node.session.auth.username', ''),
+ ('node.session.auth.password', ''))
+ else:
+ items = (('node.session.auth.authmethod', 'CHAP'),
+ ('node.session.auth.username', self.auth['username']),
+ ('node.session.auth.password', self.auth['password']))
+ for name, value in items:
+ self._update_db(name, value)
+
+ def _run_cmd(self, cmd):
+ iscsiadm = subprocess.Popen(
+ self.targetCmd + cmd,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = iscsiadm.communicate()
+ if iscsiadm.returncode != 0:
+ msg_args = {'portal': self.portal, 'err': err}
+ raise OperationFailed("KCHISCSI0001E", msg_args)
+ return out
+
+ def _discover(self):
+ iscsiadm = subprocess.Popen(
+ ['iscsiadm', '--mode', 'discovery', '--type', 'sendtargets',
+ '--portal', self.portal],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = iscsiadm.communicate()
+ if iscsiadm.returncode != 0:
+ msg_args = {'portal': self.portal, 'err': err}
+ raise OperationFailed("KCHISCSI0001E", msg_args)
+ return out
+
+ def _run_op(self, op):
+ self._run_cmd(['--' + op])
+
+ def login(self):
+ self._discover()
+ self._update_auth()
+ self._run_op('login')
+
+ def logout(self):
+ self._run_op('logout')
+
+ def validate(self):
+ try:
+ self.login()
+ except OperationFailed:
+ return False
+
+ self.logout()
+ return True
diff --git a/src/wok/plugins/kimchi/isoinfo.py b/src/wok/plugins/kimchi/isoinfo.py
new file mode 100644
index 0000000..8de6885
--- /dev/null
+++ b/src/wok/plugins/kimchi/isoinfo.py
@@ -0,0 +1,506 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import contextlib
+import glob
+import os
+import platform
+import re
+import stat
+import struct
+import sys
+import urllib2
+
+
+from wok.exception import IsoFormatError
+from wok.utils import check_url_path, wok_log
+
+
+iso_dir = [
+ ##
+ # Portions of this data from libosinfo: http://libosinfo.org/
+ #
+ # Each tuple has the following three members:
+ # Distro ID: Nickname for the distro or OS family
+ # Distro Version: A function or string that provides a specific version
+ # given a regular expression match on the volume id string
+ # Regular Expression: A regex to match against the ISO Volume ID
+ ##
+ ('openbsd', lambda m: m.group(2),
+ ('OpenBSD/(i386|amd64) (\d+\.\d+) Install CD')),
+ ('centos', lambda m: m.group(1),
+ ('CentOS_(\d+\.\d+)_Final')),
+ ('windows', '2000',
+ ('W2AFPP|SP1AFPP|SP2AFPP|YRMAFPP|ZRMAFPP|W2AOEM|SP1AOEM|SP2AOEM' +
+ '|YRMAOEM|ZRMAOEM|W2ASEL|SP2ASEL|W2SFPP|SP1SFPP|SP2SFPP|YRMSFPP' +
+ '|ZRMSFPP|W2SOEM|W2SOEM|SP1SOEM|SP2SOEM|YRMSOEM|ZRMSOEM|W2SSEL' +
+ '|SP2SSEL|W2PFPP|SP1PFPP|SP2PFPP|YRMPFPP|ZRMPFPP|W2POEM|SP1POEM' +
+ '|SP2POEM|YRMPOEM|ZRMPOEM|W2PSEL|SP2PSEL|W2PCCP|WIN2000|W2K_SP4')),
+ ('windows', 'xp',
+ ('WXPFPP|WXHFPP|WXPCCP|WXHCCP|WXPOEM|WXHOEM|WXPVOL|WXPEVL|XRMPFPP' +
+ '|XRMHFPP|XRMPCCP|XRMHCCP|XRMPOEM|XRMHOEM|XRMPVOL|XRMSD2|X1APFPP' +
+ '|X1AHFPP|X1APCCP|X1APCCP|X1AHCCP|X1APOEM|X1AHOEM|X1APVOL|VRMPFPP' +
+ '|VRMHFPP|VRMPCCP|VRMHCCP|VRMPOEM|VRMHOEM|VRMPVOL|VRMSD2|VX2PFPP' +
+ '|VX2HFPP|VX2PCCP|VX2HCCP|VX2POEM|VX2HOEM|VX2PRMFPP|VX2PVOL|GRTMUPD' +
+ '|GRTMPFPP|GRTMPRMFPP|GRTMHFPP|GRTMHKFPP|GRTMHKNFPP|GRTMHRMFPP' +
+ '|GRTMPOEM|GRTMHOEM|GRTMPVOL|GRTMPKNVOL|GRTMPKVOL|GRTMPRMVOL' +
+ '|MX2PFPP|MRMSD2|ARMPXFPP|ARMPXCCP|ARMPXOEM|ARMPXVOL|AX2PXCFPP' +
+ '|AX2PXFPP|NRMPIFPP')),
+ ('windows', '2003',
+ ('ARMECHK|ARMEVOL|ARMSVOL|ARMWVOL|ARMEEVL|ARMSEVL|ARMWEVL|ARMEOEM' +
+ '|ARMDOEM|ARMSOEM|ARMWOEM|ARMEFPP|ARMDFPP|ARMSFPP|ARMWFPP|NRMECHK' +
+ '|NRMEVOL|NRMSVOL|NRMWVOL|NRMEEVL|NRMSEVL|NRMWEVL|NRMEOEM|NRMDOEM' +
+ '|NRMSOEM|NRMWOEM|NRMEFPP|NRMDFPP|NRMSFPP|NRMSFPP|CRMSVOL|CRMSXVOL' +
+ '|BRMEVOL|BX2DVOL|ARMEEVL|BRMEEVL|CR0SP2|ARMEICHK|ARMEIFPP|ARMEIEVL' +
+ '|ARMEIOEM|ARMDIOEM|ARMEXFPP|ARMDFPP|ARMSXFPP|CR0SPX2|NRMEICHK' +
+ '|NRMEIFPP|NRMDIFPP|NRMEIOEM|NRMDIOEM|NRMEIVOL|NRMEIEVL|BRMEXVOL' +
+ '|BX2DXVOL|ARMEIFPP|CR0SPI2')),
+ ('windows', '2003r2',
+ ('CRMEFPP|CRMSFPP|CR0SCD2|CR0ECD2|BX2SFPP|BX2EFPP|BRMECD2FRE' +
+ '|BRMSCD2FRE|CRMEXFPP|CRMSXFPP|CR0SCD2X|CR0ECD2X|BX2SXFPP|BX2EXFPP' +
+ '|BRMECD2XFRE|BRMSCD2XFRE|CRMDVOL|CRMDXVOL')),
+ ('windows', '2008',
+ ('KRTMSVOL|KRTMSCHK|KRMWVOL|KRMSVOL|KRTMSXVOL|KRTMSXCHK|KRMWXVOL' +
+ '|KRMSXVOL')),
+ ('windows', '2008r2',
+ ('GRMSXVOL|GRMSXFRER|GRMSHXVOL|GRMSIAIVOL|SRVHPCR2')),
+ ('windows', 'vista',
+ ('FB1EVOL|LRMCFRE|FRTMBVOL|FRMBVOL|FRMEVOL|FB1EXVOL|LRMCXFRE' +
+ '|FRTMBXVOL|FRMBXVOL|FRMEXVOL|LRMEVOL|LRMEXVOL')),
+ ('windows', '7',
+ ('GRMCULFRER|GSP1RMCNPRFRER|GSP1RMCNULFRER|GSP1RMCULFRER' +
+ '|GSP1RMCPRFRER|GRMCENVOL|GRMCNENVOL|GRMCPRFRER|GSP1RMCPRVOL' +
+ '|GRMCULXFRER|GSP1RMCPRXFRER|GSP1RMCNHPXFRER|GRMCHPXFRER|GRMCXCHK' +
+ '|GSP1RMCENXVOL|GRMCENXVOL|GRMCNENXVOL|GRMCPRXFRER|GSP1RMCPRXVOL')),
+ ('windows', '8',
+ ('HB1_CCPA_X86FRE|HRM_CCSA_X86FRE|HRM_CCSA_X86CHK|HRM_CCSNA_X86CHK' +
+ '|HRM_CCSNA_X86FRE|HRM_CENA_X86FREV|HRM_CENA_X86CHKV' +
+ '|HRM_CENNA_X86FREV|HRM_CENNA_X86CHKV|HRM_CPRA_X86FREV' +
+ '|HRM_CPRNA_X86FREV|HB1_CCPA_X64FRE|HRM_CCSA_X64FRE' +
+ '|HRM_CCSA_X64CHK|HRM_CCSNA_X64FRE|HRM_CCSNA_X64CHK' +
+ '|HRM_CENNA_X64FREV|HRM_CENNA_X64CHKV|HRM_CENA_X64FREV' +
+ '|HRM_CENA_X64CHKV|HRM_CPRA_X64FREV|HRM_CPRNA_X64FREV')),
+ ('sles', '10', 'SLES10|SUSE-Linux-Enterprise-Server.001'),
+ ('sles', '11', 'SUSE_SLES-11-0-0'),
+ ('sles', '12', 'SLE-12'),
+ ('sles', lambda m: "11sp%s" % m.group(1), 'SLES-11-SP(\d+)'),
+ ('opensuse', lambda m: m.group(1), 'openSUSE[ -](\d+\.\d+)'),
+ ('opensuse', '11.1', 'SU1110.001'),
+ ('opensuse', '11.3',
+ 'openSUSE-DVD-i586-Build0702..001|openSUSE-DVD-x86_64.0702..001'),
+ ('opensuse', '11.4',
+ 'openSUSE-DVD-i586-Build0024|openSUSE-DVD-x86_640024'),
+ ('opensuse', '12.1',
+ 'openSUSE-DVD-i586-Build0039|openSUSE-DVD-x86_640039'),
+ ('opensuse', '12.2',
+ 'openSUSE-DVD-i586-Build0167|openSUSE-DVD-x86_640167'),
+ ('rhel', '4.8', 'RHEL/4-U8'),
+ ('rhel', lambda m: m.group(2), 'RHEL(-LE)?[_/-](\d+\.\d+)'),
+ ('debian', lambda m: m.group(1), 'Debian (\d+\.\d+)'),
+ ('ubuntu', lambda m: m.group(2), '[Uu]buntu(-Server)? (\d+\.\d+)'),
+ ('fedora', lambda m: m.group(1), 'Fedora[ -](\d+)'),
+ ('fedora', lambda m: m.group(1), 'Fedora.*-(\d+)-'),
+ ('gentoo', lambda m: m.group(1), 'Gentoo Linux \w+ (\d+)'),
+ ('powerkvm', 'live_cd', 'POWERKVM_LIVECD'),
+ ('arch', lambda m: m.group(1), 'ARCH_(\d+)'),
+]
+
+
+class IsoImage(object):
+ """
+ Scan an iso9660 image to extract the Volume ID and check for boot-ability
+
+ ISO-9660 specification:
+ http://www.ecma-international.org/publications/standards/Ecma-119.htm
+
+ El-Torito specification:
+ http://download.intel.com/support/motherboards/desktop/sb/specscdrom.pdf
+ """
+ SECTOR_SIZE = 2048
+ VOL_DESC = struct.Struct("=B5sBB32s32s")
+ EL_TORITO_BOOT_RECORD = struct.Struct("=B5sB32s32sI")
+ EL_TORITO_VALIDATION_ENTRY = struct.Struct("=BBH24sHBB")
+ EL_TORITO_BOOT_ENTRY = struct.Struct("=BBHBBHL20x")
+ # Path table info starting in ISO9660 offset 132. We force little
+ # endian byte order (the '<' sign) because Power systems can run on
+ # both.
+ # First int is path table size, next 4 bytes are discarded (it is
+ # the same info but in big endian) and next int is the location.
+ PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
+
+ def __init__(self, path):
+ self.path = path
+ self.remote = self._is_iso_remote()
+ self.volume_id = None
+ self.bootable = False
+ self._scan()
+
+ def _is_iso_remote(self):
+ if os.path.exists(self.path):
+ st_mode = os.stat(self.path).st_mode
+ if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
+ return False
+
+ if check_url_path(self.path):
+ return True
+
+ raise IsoFormatError("KCHISO0001E", {'filename': self.path})
+
+ def probe(self):
+ if not self.bootable:
+ raise IsoFormatError("KCHISO0002E", {'filename': self.path})
+
+ matcher = Matcher(self.volume_id)
+
+ for d, v, regex in iso_dir:
+ if matcher.search(regex):
+ distro = d
+ if hasattr(v, '__call__'):
+ version = v(matcher)
+ else:
+ version = v
+ return (distro, version)
+
+ msg = "probe_iso: Unable to identify ISO %s with Volume ID: %s"
+ wok_log.debug(msg, self.path, self.volume_id)
+
+ return ('unknown', 'unknown')
+
+ def _unpack(self, s, data):
+ return s.unpack(data[:s.size])
+
+ def _scan_el_torito(self, data):
+ """
+ Search the Volume Descriptor Table for an El Torito boot record. If
+ found, the boot record will provide a link to a boot catalogue. The
+ first entry in the boot catalogue is a validation entry. The next
+ entry contains the default boot entry. The default boot entry will
+ indicate whether the image is considered bootable.
+ """
+ vd_type = -1
+ for i in xrange(1, 4):
+ fmt = IsoImage.EL_TORITO_BOOT_RECORD
+ ptr = i * IsoImage.SECTOR_SIZE
+ tmp_data = data[ptr:ptr + fmt.size]
+ if len(tmp_data) < fmt.size:
+ return
+
+ (vd_type, vd_ident, vd_ver,
+ et_ident, pad0, boot_cat) = self._unpack(fmt, tmp_data)
+ if vd_type == 255: # Volume record terminator
+ return
+ if vd_type == 0: # Found El-Torito Boot Record
+ break
+ if not et_ident.startswith('EL TORITO SPECIFICATION'):
+ raise IsoFormatError("KCHISO0003E",
+ {'filename': self.path})
+
+ offset = IsoImage.SECTOR_SIZE * boot_cat
+ size = IsoImage.EL_TORITO_VALIDATION_ENTRY.size + \
+ IsoImage.EL_TORITO_BOOT_ENTRY.size
+ data = self._get_iso_data(offset, size)
+
+ fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
+ tmp_data = data[0:fmt.size]
+ ptr = fmt.size
+ (hdr_id, platform_id, pad0,
+ ident, csum, key55, keyAA) = self._unpack(fmt, tmp_data)
+ if key55 != 0x55 or keyAA != 0xaa:
+ raise IsoFormatError("KCHISO0004E",
+ {'filename': self.path})
+
+ fmt = IsoImage.EL_TORITO_BOOT_ENTRY
+ tmp_data = data[ptr:ptr + fmt.size]
+ (boot, media_type, load_seg, sys_type,
+ pad0, sectors, load_rba) = self._unpack(fmt, tmp_data)
+ if boot == 0x88:
+ self.bootable = True
+ elif boot == 0:
+ self.bootable = False
+ else:
+ raise IsoFormatError("KCHISO0005E",
+ {'filename': self.path})
+
+ def _scan_ppc(self):
+ """
+ PowerPC firmware does not use the conventional El Torito boot
+ specification. Instead, it looks for a file '/ppc/bootinfo.txt'
+ which contains boot information. A PPC image is bootable if
+ this file exists in the filesystem [1].
+
+ To detect if a PPC ISO is bootable, we could simply mount the
+ ISO and search for the boot file as we would with any other
+ file in the filesystem. We can also look for the boot file
+ searching byte by byte the ISO image. This is possible because
+ the PPC ISO image follows the ISO9660 standard [2]. Mounting
+ the ISO requires extra resources and it takes longer than
+ searching the image data, thus we chose the latter approach
+ in this code.
+
+ To locate a file we must access the Path Table, which contains
+ the records of all the directories in the ISO. After locating
+ the directory/subdirectory that contains the file, we access
+ the Directory Record to find it.
+
+
+ .. [1] https://www.ibm.com/developerworks/community/wikis/home?\
+lang=en#!/wiki/W51a7ffcf4dfd_4b40_9d82_446ebc23c550/page/PowerLinux\
+%20Boot%20howto
+ .. [2] http://wiki.osdev.org/ISO_9660
+ """
+
+ # To locate any file we must access the Path Table, which
+ # contains the records of all the directories in the ISO.
+ # ISO9660 dictates that the Path Table location information
+ # is at offset 132, inside the Primary Volume Descriptor,
+ # after the SystemArea (16*SECTOR_SIZE).
+ #
+ # In the Path table info we're forcing little endian byte
+ # order (the '<' sign) because Power systems can run on
+ # both.
+ #
+ # First int is path table size, next 4 bytes are discarded (it is
+ # the same info but in big endian) and next int is the location.
+ PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
+ PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
+
+ path_table_loc_data = self._get_iso_data(PATH_TABLE_LOC_OFFSET,
+ PATH_TABLE_SIZE_LOC.size)
+ path_size, unused, path_loc = self._unpack(PATH_TABLE_SIZE_LOC,
+ path_table_loc_data)
+ # Fetch the Path Table using location and size found above
+ path_table_offset = path_loc * IsoImage.SECTOR_SIZE
+ path_table_data = self._get_iso_data(path_table_offset, path_size)
+
+ # Loop inside the path table to find the directory 'ppc'.
+ # The contents of the registers are:
+ # - length of the directory identifier (1 byte)
+ # - extended attribute record length (1 byte)
+ # - location of directory register (4 bytes)
+ # - directory number of parent dir (2 bytes)
+ # - directory name (size varies according to length)
+ # - padding field - 1 byte if the length is odd, not present if even
+ DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H")
+ dir_struct_size = DIR_NAMELEN_LOCATION_PARENT.size
+ i = 0
+ while i < path_size:
+ dir_data = path_table_data[i: i+dir_struct_size]
+ i += dir_struct_size
+ # We won't use the Extended Attribute Record
+ dir_namelen, unused, dir_loc, dir_parent = \
+ self._unpack(DIR_NAMELEN_LOCATION_PARENT, dir_data)
+ if dir_parent == 1:
+ # read the dir name using the namelen
+ dir_name = path_table_data[i: i+dir_namelen].rstrip()
+ if dir_name.lower() == 'ppc':
+ # stop searching, dir was found
+ break
+ # Need to consider the optional padding field as well
+ i += dir_namelen + dir_namelen % 2
+
+ if i > path_size:
+ # Didn't find the '/ppc' directory. ISO is not bootable.
+ self.bootable = False
+ return
+
+ # Get the 'ppc' directory record using 'dir_loc'.
+ ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
+
+ # We need to find the sector size of this dir entry. The
+ # size of the File Section is located 10 bytes after
+ # the dir location.
+ DIR_SIZE_FMT = struct.Struct("<10sI")
+ data = self._get_iso_data(ppc_dir_offset, DIR_SIZE_FMT.size)
+ unused, dir_size = self._unpack(DIR_SIZE_FMT, data)
+ # If the dir is in the middle of a sector, the sector is
+ # padded zero and won't be utilized. We need to round up
+ # the result
+ dir_sectorsize = dir_size / IsoImage.SECTOR_SIZE
+ if dir_size % IsoImage.SECTOR_SIZE:
+ dir_sectorsize += 1
+
+ # Fixed-size directory record fields:
+ # - length of directory record (1 byte)
+ # - extended attr. record length (1 byte)
+ # - location of extend in both-endian format (8 bytes)
+ # - data length (size of extend) in both-endian (8 bytes)
+ # - recording date and time (7 bytes)
+ # - file flags (1 byte)
+ # - file unit size interleaved (1 byte)
+ # - interleave gap size (1 byte)
+ # - volume sequence number (4 bytes)
+ # - length of file identifier (1 byte)
+ #
+ # Of all these fields, we will use only 3 of them, 'ignoring'
+ # 30 bytes total.
+ STATIC_DIR_RECORD_FMT = struct.Struct("<B 24s B 6s B")
+ static_rec_size = STATIC_DIR_RECORD_FMT.size
+
+ # Maximum offset possible of all the records of this directory
+ DIR_REC_MAX = ppc_dir_offset + dir_sectorsize*IsoImage.SECTOR_SIZE
+ # Max size of a given directory record
+ MAX_DIR_SIZE = 255
+ # Name of the boot file
+ BOOT_FILE_NAME = "bootinfo.txt"
+
+ # Loop until one of the following happens:
+ # - boot file is found
+ # - end of directory record listing for the 'ppc' dir
+ while ppc_dir_offset < DIR_REC_MAX:
+ record_data = self._get_iso_data(ppc_dir_offset, MAX_DIR_SIZE)
+ dir_rec_len, unused, file_flags, unused2, file_name_len = \
+ self._unpack(STATIC_DIR_RECORD_FMT, record_data)
+
+ # if dir_rec_len = 0, increment offset (skip the
+ # dir_rec_len byte) and continue the loop
+ if dir_rec_len == 0:
+ ppc_dir_offset += 1
+ continue
+
+ # Get filename of the file/dir we're at.
+ filename = record_data[static_rec_size:
+ static_rec_size + file_name_len].rstrip()
+ # The second bit of the file_flags indicate if this record
+ # is a directory.
+ if BOOT_FILE_NAME in filename.lower() and (file_flags & 2) != 1:
+ self.bootable = True
+ return
+
+ # Update offset and keep looking. There is a padding here
+ # if the length of the file identifier is EVEN.
+ padding = 0
+ if not file_name_len % 2:
+ padding = 1
+ ppc_dir_offset += dir_rec_len + padding
+ # If reached this point the file wasn't found = not bootable
+ self.bootable = False
+
+ def _scan_primary_vol(self, data):
+ """
+ Scan one sector for a Primary Volume Descriptor and extract the
+ Volume ID from the table
+ """
+ primary_vol_data = data[0: -1]
+ info = self._unpack(IsoImage.VOL_DESC, primary_vol_data)
+ (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id) = info
+ if vd_type != 1:
+ raise IsoFormatError("KCHISO0006E", {'filename': self.path})
+ if vd_ident != 'CD001' or vd_ver != 1:
+ raise IsoFormatError("KCHISO0007E", {'filename': self.path})
+ if vol_id.strip() == 'RED_HAT':
+ # Some RHEL ISO images store the infomation of volume id in the
+ # location of volume set id mistakenly.
+ self.volume_id = self._get_volume_set_id(data)
+ else:
+ self.volume_id = vol_id
+
+ def _get_volume_set_id(self, data):
+ # The index is picked from ISO-9660 specification.
+ return data[190: 318]
+
+ def _get_iso_data(self, offset, size):
+ if self.remote:
+ request = urllib2.Request(self.path)
+ range_header = "bytes=%d-%d" % (offset, offset + size - 1)
+ request.add_header("range", range_header)
+ with contextlib.closing(urllib2.urlopen(request)) as response:
+ data = response.read()
+ else:
+ with open(self.path) as fd:
+ fd.seek(offset)
+ data = fd.read(size)
+
+ return data
+
+ def _scan(self):
+ offset = 16 * IsoImage.SECTOR_SIZE
+ size = 4 * IsoImage.SECTOR_SIZE
+ data = self._get_iso_data(offset, size)
+ if len(data) < 2 * IsoImage.SECTOR_SIZE:
+ return
+
+ self._scan_primary_vol(data)
+ if platform.machine().startswith('ppc'):
+ self._scan_ppc()
+ else:
+ self._scan_el_torito(data)
+
+
+class Matcher(object):
+ """
+ Simple utility class to assist with matching a given string against a
+ series of regular expressions.
+ """
+ def __init__(self, matchstring):
+ self.matchstring = matchstring
+
+ def search(self, regex):
+ self.lastmatch = re.search(regex, self.matchstring)
+ return bool(self.lastmatch)
+
+ def group(self, num):
+ return self.lastmatch.group(num)
+
+
+def probe_iso(status_helper, params):
+ loc = params['path'].encode("utf-8")
+ updater = params['updater']
+ ignore = False
+ ignore_list = params.get('ignore_list', [])
+
+ def update_result(iso, ret):
+ path = os.path.abspath(iso) if os.path.isfile(iso) else iso
+ updater({'path': path, 'distro': ret[0], 'version': ret[1]})
+
+ if os.path.isdir(loc):
+ for root, dirs, files in os.walk(loc):
+ for dir_name in ignore_list:
+ if root in glob.glob(dir_name):
+ ignore = True
+ break
+ if ignore:
+ ignore = False
+ continue
+ for name in files:
+ if not name.lower().endswith('.iso'):
+ continue
+ iso = os.path.join(root, name)
+ try:
+ iso_img = IsoImage(iso)
+ ret = iso_img.probe()
+ update_result(iso, ret)
+ except:
+ continue
+ else:
+ iso_img = IsoImage(loc)
+ ret = iso_img.probe()
+ update_result(loc, ret)
+
+ if status_helper is not None:
+ status_helper('', True)
+
+
+if __name__ == '__main__':
+ iso_list = []
+
+ def updater(iso_info):
+ iso_list.append(iso_info)
+
+ probe_iso(None, dict(path=sys.argv[1], updater=updater))
+ print iso_list
diff --git a/src/wok/plugins/kimchi/kimchi.conf b/src/wok/plugins/kimchi/kimchi.conf
new file mode 100644
index 0000000..1bf78e4
--- /dev/null
+++ b/src/wok/plugins/kimchi/kimchi.conf
@@ -0,0 +1,37 @@
+[wok]
+enable = True
+plugin_class = "KimchiRoot"
+uri = "/plugins/kimchi"
+extra_auth_api_class = "control.sub_nodes"
+
+[/]
+tools.trailing_slash.on = False
+request.methods_with_bodies = ('POST', 'PUT')
+tools.nocache.on = True
+tools.proxy.on = True
+tools.sessions.on = True
+tools.sessions.name = 'wok'
+tools.sessions.secure = True
+tools.sessions.httponly = True
+tools.sessions.locking = 'explicit'
+tools.sessions.storage_type = 'ram'
+tools.sessions.timeout = 10
+tools.wokauth.on = True
+
+[/data/screenshots]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir + '/screenshots'
+tools.nocache.on = False
+
+[/data/debugreports]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir + '/debugreports'
+tools.nocache.on = False
+tools.wokauth.on = True
+tools.staticdir.content_types = {'xz': 'application/x-xz'}
+
+[/help]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').ui_dir + '/pages/help'
+tools.nocache.on = True
+
diff --git a/src/wok/plugins/kimchi/kvmusertests.py b/src/wok/plugins/kimchi/kvmusertests.py
new file mode 100644
index 0000000..35350d8
--- /dev/null
+++ b/src/wok/plugins/kimchi/kvmusertests.py
@@ -0,0 +1,79 @@
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import platform
+import psutil
+import threading
+
+
+from wok.rollbackcontext import RollbackContext
+
+KVMUSERTEST_VM_NAME = "KVMUSERTEST_VM"
+
+
+class UserTests(object):
+ SIMPLE_VM_XML = """
+ <domain type='kvm'>
+ <name>%(name)s</name>
+ <memory unit='KiB'>262144</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ </domain>"""
+ lock = threading.Lock()
+ user = None
+
+ @classmethod
+ def probe_user(cls):
+ with cls.lock:
+ if cls.user:
+ return cls.user
+
+ arch = 'ppc64' if platform.machine() == 'ppc64le' \
+ else platform.machine()
+
+ xml = cls.SIMPLE_VM_XML % {'name': KVMUSERTEST_VM_NAME, 'arch': arch}
+
+ with RollbackContext() as rollback:
+ with cls.lock:
+ conn = libvirt.open(None)
+ rollback.prependDefer(conn.close)
+ f = libvirt.VIR_DOMAIN_START_AUTODESTROY
+ dom = conn.createXML(xml, flags=f)
+ rollback.prependDefer(dom.destroy)
+ filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME
+ with open(filename) as f:
+ pidStr = f.read()
+ p = psutil.Process(int(pidStr))
+
+ # bug fix #357
+ # in psutil 2.0 and above versions, username will be a method,
+ # not a string
+ if callable(p.username):
+ cls.user = p.username()
+ else:
+ cls.user = p.username
+
+ return cls.user
+
+
+if __name__ == '__main__':
+ ut = UserTests()
+ print ut.probe_user()
diff --git a/src/wok/plugins/kimchi/m4/ac_python_module.m4 b/src/wok/plugins/kimchi/m4/ac_python_module.m4
new file mode 100644
index 0000000..32b9d72
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/ac_python_module.m4
@@ -0,0 +1,30 @@
+dnl @synopsis AC_PYTHON_MODULE(modname[, fatal])
+dnl
+dnl Checks for Python module.
+dnl
+dnl If fatal is non-empty then absence of a module will trigger an
+dnl error.
+dnl
+dnl @category InstalledPackages
+dnl @author Andrew Collier <colliera at nu.ac.za>.
+dnl @version 2004-07-14
+dnl @license AllPermissive
+
+AC_DEFUN([AC_PYTHON_MODULE],[
+ AC_MSG_CHECKING(python module: $1)
+ python -c "import $1" 2>/dev/null
+ if test $? -eq 0;
+ then
+ AC_MSG_RESULT(yes)
+ eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
+ else
+ AC_MSG_RESULT(no)
+ eval AS_TR_CPP(HAVE_PYMOD_$1)=no
+ #
+ if test -n "$2"
+ then
+ AC_MSG_ERROR(failed to find required module $1)
+ exit 1
+ fi
+ fi
+])
diff --git a/src/wok/plugins/kimchi/m4/gettext.m4 b/src/wok/plugins/kimchi/m4/gettext.m4
new file mode 100644
index 0000000..f84e6a5
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/gettext.m4
@@ -0,0 +1,383 @@
+# gettext.m4 serial 63 (gettext-0.18)
+dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper at cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible at clisp.cons.org>, 2000-2006, 2008-2010.
+
+dnl Macro to add for using GNU gettext.
+
+dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
+dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The
+dnl default (if it is not specified or empty) is 'no-libtool'.
+dnl INTLSYMBOL should be 'external' for packages with no intl directory,
+dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory.
+dnl If INTLSYMBOL is 'use-libtool', then a libtool library
+dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
+dnl depending on --{enable,disable}-{shared,static} and on the presence of
+dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
+dnl $(top_builddir)/intl/libintl.a will be created.
+dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
+dnl implementations (in libc or libintl) without the ngettext() function
+dnl will be ignored. If NEEDSYMBOL is specified and is
+dnl 'need-formatstring-macros', then GNU gettext implementations that don't
+dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
+dnl INTLDIR is used to find the intl libraries. If empty,
+dnl the value `$(top_builddir)/intl/' is used.
+dnl
+dnl The result of the configuration is one of three cases:
+dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
+dnl and used.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 2) GNU gettext has been found in the system's C library.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 3) No internationalization, always use English msgid.
+dnl Catalog format: none
+dnl Catalog extension: none
+dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
+dnl The use of .gmo is historical (it was needed to avoid overwriting the
+dnl GNU format catalogs when building on a platform with an X/Open gettext),
+dnl but we keep it in order not to force irrelevant filename changes on the
+dnl maintainers.
+dnl
+AC_DEFUN([AM_GNU_GETTEXT],
+[
+ dnl Argument checking.
+ ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], ,
+ [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
+])])])])])
+ ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
+ [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])])
+ ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], ,
+ [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
+])])])])
+ define([gt_included_intl],
+ ifelse([$1], [external],
+ ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
+ [yes]))
+ define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+ gt_NEEDS_INIT
+ AM_GNU_GETTEXT_NEED([$2])
+
+ AC_REQUIRE([AM_PO_SUBDIRS])dnl
+ ifelse(gt_included_intl, yes, [
+ AC_REQUIRE([AM_INTL_SUBDIR])dnl
+ ])
+
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ dnl Ideally we would do this search only after the
+ dnl if test "$USE_NLS" = "yes"; then
+ dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+ dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
+ dnl the configure script would need to contain the same shell code
+ dnl again, outside any 'if'. There are two solutions:
+ dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
+ dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
+ dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
+ dnl documented, we avoid it.
+ ifelse(gt_included_intl, yes, , [
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+ ])
+
+ dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
+ gt_INTL_MACOSX
+
+ dnl Set USE_NLS.
+ AC_REQUIRE([AM_NLS])
+
+ ifelse(gt_included_intl, yes, [
+ BUILD_INCLUDED_LIBINTL=no
+ USE_INCLUDED_LIBINTL=no
+ ])
+ LIBINTL=
+ LTLIBINTL=
+ POSUB=
+
+ dnl Add a version number to the cache macros.
+ case " $gt_needs " in
+ *" need-formatstring-macros "*) gt_api_version=3 ;;
+ *" need-ngettext "*) gt_api_version=2 ;;
+ *) gt_api_version=1 ;;
+ esac
+ gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+ gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ gt_use_preinstalled_gnugettext=no
+ ifelse(gt_included_intl, yes, [
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH([included-gettext],
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ ])
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If GNU gettext is available we use this. Else we have
+ dnl to fall back to GNU NLS library.
+
+ if test $gt_api_version -ge 3; then
+ gt_revision_test_code='
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+'
+ else
+ gt_revision_test_code=
+ fi
+ if test $gt_api_version -ge 2; then
+ gt_expression_test_code=' + * ngettext ("", "", 0)'
+ else
+ gt_expression_test_code=
+ fi
+
+ AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
+ [AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings],
+ [eval "$gt_func_gnugettext_libc=yes"],
+ [eval "$gt_func_gnugettext_libc=no"])])
+
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ ifelse(gt_included_intl, yes, , [
+ AM_ICONV_LINK
+ ])
+ dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
+ dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
+ dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
+ dnl even if libiconv doesn't exist.
+ AC_LIB_LINKFLAGS_BODY([intl])
+ AC_CACHE_CHECK([for GNU gettext in libintl],
+ [$gt_func_gnugettext_libintl],
+ [gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $INCINTL"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBINTL"
+ dnl Now see whether libintl exists and does not depend on libiconv.
+ AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ [eval "$gt_func_gnugettext_libintl=yes"],
+ [eval "$gt_func_gnugettext_libintl=no"])
+ dnl Now see whether libintl exists and depends on libiconv.
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")],
+ [LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ eval "$gt_func_gnugettext_libintl=yes"
+ ])
+ fi
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"])
+ fi
+
+ dnl If an already present or preinstalled GNU gettext() is found,
+ dnl use it. But if this macro is used in GNU gettext, and GNU
+ dnl gettext is already preinstalled in libintl, we update this
+ dnl libintl. (Cf. the install rule in intl/Makefile.in.)
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \
+ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \
+ && test "$PACKAGE" != gettext-runtime \
+ && test "$PACKAGE" != gettext-tools; }; then
+ gt_use_preinstalled_gnugettext=yes
+ else
+ dnl Reset the values set by searching for libintl.
+ LIBINTL=
+ LTLIBINTL=
+ INCINTL=
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ if test "$gt_use_preinstalled_gnugettext" != "yes"; then
+ dnl GNU gettext is not found in the C library.
+ dnl Fall back on included GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ BUILD_INCLUDED_LIBINTL=yes
+ USE_INCLUDED_LIBINTL=yes
+ LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD"
+ LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD"
+ LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'`
+ fi
+
+ CATOBJEXT=
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions to use GNU gettext tools.
+ CATOBJEXT=.gmo
+ fi
+ ])
+
+ if test -n "$INTL_MACOSX_LIBS"; then
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Some extra flags are needed during linking.
+ LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+ LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+ fi
+ fi
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ AC_DEFINE([ENABLE_NLS], [1],
+ [Define to 1 if translation of program messages to the user's native language
+ is requested.])
+ else
+ USE_NLS=no
+ fi
+ fi
+
+ AC_MSG_CHECKING([whether to use NLS])
+ AC_MSG_RESULT([$USE_NLS])
+ if test "$USE_NLS" = "yes"; then
+ AC_MSG_CHECKING([where the gettext function comes from])
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+ gt_source="external libintl"
+ else
+ gt_source="libc"
+ fi
+ else
+ gt_source="included intl directory"
+ fi
+ AC_MSG_RESULT([$gt_source])
+ fi
+
+ if test "$USE_NLS" = "yes"; then
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then
+ AC_MSG_CHECKING([how to link with libintl])
+ AC_MSG_RESULT([$LIBINTL])
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
+ fi
+
+ dnl For backward compatibility. Some packages may be using this.
+ AC_DEFINE([HAVE_GETTEXT], [1],
+ [Define if the GNU gettext() function is already present or preinstalled.])
+ AC_DEFINE([HAVE_DCGETTEXT], [1],
+ [Define if the GNU dcgettext() function is already present or preinstalled.])
+ fi
+
+ dnl We need to process the po/ directory.
+ POSUB=po
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
+ dnl to 'yes' because some of the testsuite requires it.
+ if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then
+ BUILD_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST([BUILD_INCLUDED_LIBINTL])
+ AC_SUBST([USE_INCLUDED_LIBINTL])
+ AC_SUBST([CATOBJEXT])
+
+ dnl For backward compatibility. Some configure.ins may be using this.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ DATADIRNAME=share
+ AC_SUBST([DATADIRNAME])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INSTOBJEXT=.mo
+ AC_SUBST([INSTOBJEXT])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ GENCAT=gencat
+ AC_SUBST([GENCAT])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLOBJS=
+ if test "$USE_INCLUDED_LIBINTL" = yes; then
+ INTLOBJS="\$(GETTOBJS)"
+ fi
+ AC_SUBST([INTLOBJS])
+
+ dnl Enable libtool support if the surrounding package wishes it.
+ INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
+ AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
+ ])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLLIBS="$LIBINTL"
+ AC_SUBST([INTLLIBS])
+
+ dnl Make all documented variables known to autoconf.
+ AC_SUBST([LIBINTL])
+ AC_SUBST([LTLIBINTL])
+ AC_SUBST([POSUB])
+])
+
+
+dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
+m4_define([gt_NEEDS_INIT],
+[
+ m4_divert_text([DEFAULTS], [gt_needs=])
+ m4_define([gt_NEEDS_INIT], [])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
+AC_DEFUN([AM_GNU_GETTEXT_NEED],
+[
+ m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/src/wok/plugins/kimchi/m4/iconv.m4 b/src/wok/plugins/kimchi/m4/iconv.m4
new file mode 100644
index 0000000..e2041b9
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/iconv.m4
@@ -0,0 +1,214 @@
+# iconv.m4 serial 11 (gettext-0.18.1)
+dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+ dnl those with the standalone portable GNU libiconv installed).
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+ dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed libiconv and not disabled its use
+ dnl via --without-libiconv-prefix, he wants to use it. The first
+ dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
+ am_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+ AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ [am_cv_func_iconv=yes])
+ if test "$am_cv_func_iconv" != yes; then
+ am_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ [am_cv_lib_iconv=yes]
+ [am_cv_func_iconv=yes])
+ LIBS="$am_save_LIBS"
+ fi
+ ])
+ if test "$am_cv_func_iconv" = yes; then
+ AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
+ dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10.
+ am_save_LIBS="$LIBS"
+ if test $am_cv_lib_iconv = yes; then
+ LIBS="$LIBS $LIBICONV"
+ fi
+ AC_TRY_RUN([
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+ /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+ returns. */
+ {
+ iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+ if (cd_utf8_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\342\202\254"; /* EURO SIGN */
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+ /* Test against Solaris 10 bug: Failures are not distinguishable from
+ successful returns. */
+ {
+ iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+ if (cd_ascii_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\263";
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_ascii_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+#if 0 /* This bug could be worked around by the caller. */
+ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337";
+ char buf[50];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if ((int)res > 0)
+ return 1;
+ }
+ }
+#endif
+ /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+ provided. */
+ if (/* Try standardized names. */
+ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+ /* Try IRIX, OSF/1 names. */
+ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+ /* Try AIX names. */
+ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+ /* Try HP-UX names. */
+ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+ return 1;
+ return 0;
+}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
+ [case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac])
+ LIBS="$am_save_LIBS"
+ ])
+ case "$am_cv_func_iconv_works" in
+ *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+ *) am_func_iconv=yes ;;
+ esac
+ else
+ am_func_iconv=no am_cv_lib_iconv=no
+ fi
+ if test "$am_func_iconv" = yes; then
+ AC_DEFINE([HAVE_ICONV], [1],
+ [Define if you have the iconv() function and it works.])
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ AC_MSG_CHECKING([how to link with libiconv])
+ AC_MSG_RESULT([$LIBICONV])
+ else
+ dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+ dnl either.
+ CPPFLAGS="$am_save_CPPFLAGS"
+ LIBICONV=
+ LTLIBICONV=
+ fi
+ AC_SUBST([LIBICONV])
+ AC_SUBST([LTLIBICONV])
+])
+
+dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
+dnl avoid warnings like
+dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
+dnl This is tricky because of the way 'aclocal' is implemented:
+dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
+dnl Otherwise aclocal's initial scan pass would miss the macro definition.
+dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
+dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
+dnl warnings.
+m4_define([gl_iconv_AC_DEFUN],
+ m4_version_prereq([2.64],
+ [[AC_DEFUN_ONCE(
+ [$1], [$2])]],
+ [[AC_DEFUN(
+ [$1], [$2])]]))
+gl_iconv_AC_DEFUN([AM_ICONV],
+[
+ AM_ICONV_LINK
+ if test "$am_cv_func_iconv" = yes; then
+ AC_MSG_CHECKING([for iconv declaration])
+ AC_CACHE_VAL([am_cv_proto_iconv], [
+ AC_TRY_COMPILE([
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
+#else
+size_t iconv();
+#endif
+], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"])
+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+ am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
+ AC_MSG_RESULT([
+ $am_cv_proto_iconv])
+ AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+ [Define as const if the declaration of iconv() needs const.])
+ fi
+])
diff --git a/src/wok/plugins/kimchi/m4/intlmacosx.m4 b/src/wok/plugins/kimchi/m4/intlmacosx.m4
new file mode 100644
index 0000000..dd91025
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/intlmacosx.m4
@@ -0,0 +1,51 @@
+# intlmacosx.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2004-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Checks for special options needed on MacOS X.
+dnl Defines INTL_MACOSX_LIBS.
+AC_DEFUN([gt_INTL_MACOSX],
+[
+ dnl Check for API introduced in MacOS X 10.2.
+ AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
+ [gt_cv_func_CFPreferencesCopyAppValue],
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
+ [CFPreferencesCopyAppValue(NULL, NULL)],
+ [gt_cv_func_CFPreferencesCopyAppValue=yes],
+ [gt_cv_func_CFPreferencesCopyAppValue=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+ AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
+ [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.])
+ fi
+ dnl Check for API introduced in MacOS X 10.3.
+ AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
+ [gt_cv_func_CFLocaleCopyCurrent=yes],
+ [gt_cv_func_CFLocaleCopyCurrent=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
+ [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.])
+ fi
+ INTL_MACOSX_LIBS=
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+ fi
+ AC_SUBST([INTL_MACOSX_LIBS])
+])
diff --git a/src/wok/plugins/kimchi/m4/lib-ld.m4 b/src/wok/plugins/kimchi/m4/lib-ld.m4
new file mode 100644
index 0000000..ebb3052
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/lib-ld.m4
@@ -0,0 +1,110 @@
+# lib-ld.m4 serial 4 (gettext-0.18)
+dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Subroutines of libtool.m4,
+dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
+dnl with libtool.m4.
+
+dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
+AC_DEFUN([AC_LIB_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ acl_cv_prog_gnu_ld=yes ;;
+*)
+ acl_cv_prog_gnu_ld=no ;;
+esac])
+with_gnu_ld=$acl_cv_prog_gnu_ld
+])
+
+dnl From libtool-1.4. Sets the variable LD.
+AC_DEFUN([AC_LIB_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]* | [A-Za-z]:[\\/]*)]
+ [re_direlt='/[^/][^/]*/\.\./']
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL([acl_cv_path_LD],
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ acl_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break ;;
+ *)
+ test "$with_gnu_ld" != yes && break ;;
+ esac
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT([$LD])
+else
+ AC_MSG_RESULT([no])
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_LIB_PROG_LD_GNU
+])
diff --git a/src/wok/plugins/kimchi/m4/lib-link.m4 b/src/wok/plugins/kimchi/m4/lib-link.m4
new file mode 100644
index 0000000..c73bd8e
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/lib-link.m4
@@ -0,0 +1,774 @@
+# lib-link.m4 serial 21 (gettext-0.18)
+dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_PREREQ([2.54])
+
+dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
+dnl augments the CPPFLAGS variable.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[translit([$1],[./-], [___])])
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+ ac_cv_lib[]Name[]_libs="$LIB[]NAME"
+ ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
+ ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
+ ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
+ ])
+ LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+ LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+ INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+ LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
+ dnl results of this search when this library appears as a dependency.
+ HAVE_LIB[]NAME=yes
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
+dnl searches for libname and the libraries corresponding to explicit and
+dnl implicit dependencies, together with the specified include files and
+dnl the ability to compile and link the specified testcode. The missing-message
+dnl defaults to 'no' and may contain additional hints for the user.
+dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
+dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
+dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[translit([$1],[./-], [___])])
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+
+ dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+
+ dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed lib[]Name and not disabled its use
+ dnl via --without-lib[]Name-prefix, he wants to use it.
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+
+ AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
+ ac_save_LIBS="$LIBS"
+ dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
+ dnl because these -l options might require -L options that are present in
+ dnl LIBS. -l options benefit only from the -L options listed before it.
+ dnl Otherwise, add it to the front of LIBS, because it may be a static
+ dnl library that depends on another static library that is present in LIBS.
+ dnl Static libraries benefit only from the static libraries listed after
+ dnl it.
+ case " $LIB[]NAME" in
+ *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
+ *) LIBS="$LIB[]NAME $LIBS" ;;
+ esac
+ AC_TRY_LINK([$3], [$4],
+ [ac_cv_lib[]Name=yes],
+ [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
+ LIBS="$ac_save_LIBS"
+ ])
+ if test "$ac_cv_lib[]Name" = yes; then
+ HAVE_LIB[]NAME=yes
+ AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
+ AC_MSG_CHECKING([how to link with lib[]$1])
+ AC_MSG_RESULT([$LIB[]NAME])
+ else
+ HAVE_LIB[]NAME=no
+ dnl If $LIB[]NAME didn't lead to a usable library, we don't need
+ dnl $INC[]NAME either.
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIB[]NAME=
+ LTLIB[]NAME=
+ LIB[]NAME[]_PREFIX=
+ fi
+ AC_SUBST([HAVE_LIB]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl acl_libext,
+dnl acl_shlibext,
+dnl acl_hardcode_libdir_flag_spec,
+dnl acl_hardcode_libdir_separator,
+dnl acl_hardcode_direct,
+dnl acl_hardcode_minus_L.
+AC_DEFUN([AC_LIB_RPATH],
+[
+ dnl Tell automake >= 1.10 to complain if config.rpath is missing.
+ m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
+ AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
+ AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+ AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
+ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
+ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
+ . ./conftest.sh
+ rm -f ./conftest.sh
+ acl_cv_rpath=done
+ ])
+ wl="$acl_cv_wl"
+ acl_libext="$acl_cv_libext"
+ acl_shlibext="$acl_cv_shlibext"
+ acl_libname_spec="$acl_cv_libname_spec"
+ acl_library_names_spec="$acl_cv_library_names_spec"
+ acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ acl_hardcode_direct="$acl_cv_hardcode_direct"
+ acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+ dnl Determine whether the user wants rpath handling at all.
+ AC_ARG_ENABLE([rpath],
+ [ --disable-rpath do not hardcode runtime library paths],
+ :, enable_rpath=yes)
+])
+
+dnl AC_LIB_FROMPACKAGE(name, package)
+dnl declares that libname comes from the given package. The configure file
+dnl will then not have a --with-libname-prefix option but a
+dnl --with-package-prefix option. Several libraries can come from the same
+dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
+dnl macro call that searches for libname.
+AC_DEFUN([AC_LIB_FROMPACKAGE],
+[
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ define([acl_frompackage_]NAME, [$2])
+ popdef([NAME])
+ pushdef([PACK],[$2])
+ pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ define([acl_libsinpackage_]PACKUP,
+ m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
+ popdef([PACKUP])
+ popdef([PACK])
+])
+
+dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
+dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
+dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
+ pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])])
+ dnl Autoconf >= 2.61 supports dots in --with options.
+ pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_ARG_WITH(P_A_C_K[-prefix],
+[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
+ --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ if test "$acl_libdirstem2" != "$acl_libdirstem" \
+ && ! test -d "$withval/$acl_libdirstem"; then
+ additional_libdir="$withval/$acl_libdirstem2"
+ fi
+ fi
+ fi
+])
+ dnl Search the library and its dependencies in $additional_libdir and
+ dnl $LDFLAGS. Using breadth-first-seach.
+ LIB[]NAME=
+ LTLIB[]NAME=
+ INC[]NAME=
+ LIB[]NAME[]_PREFIX=
+ dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
+ dnl computed. So it has to be reset here.
+ HAVE_LIB[]NAME=
+ rpathdirs=
+ ltrpathdirs=
+ names_already_handled=
+ names_next_round='$1 $2'
+ while test -n "$names_next_round"; do
+ names_this_round="$names_next_round"
+ names_next_round=
+ for name in $names_this_round; do
+ already_handled=
+ for n in $names_already_handled; do
+ if test "$n" = "$name"; then
+ already_handled=yes
+ break
+ fi
+ done
+ if test -z "$already_handled"; then
+ names_already_handled="$names_already_handled $name"
+ dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
+ dnl or AC_LIB_HAVE_LINKFLAGS call.
+ uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ eval value=\"\$HAVE_LIB$uppername\"
+ if test -n "$value"; then
+ if test "$value" = yes; then
+ eval value=\"\$LIB$uppername\"
+ test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
+ eval value=\"\$LTLIB$uppername\"
+ test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
+ else
+ dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
+ dnl that this library doesn't exist. So just drop it.
+ :
+ fi
+ else
+ dnl Search the library lib$name in $additional_libdir and $LDFLAGS
+ dnl and the already constructed $LIBNAME/$LTLIBNAME.
+ found_dir=
+ found_la=
+ found_so=
+ found_a=
+ eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
+ if test -n "$acl_shlibext"; then
+ shrext=".$acl_shlibext" # typically: shrext=.so
+ else
+ shrext=
+ fi
+ if test $use_additional = yes; then
+ dir="$additional_libdir"
+ dnl The same code as in the loop below:
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ case "$x" in
+ -L*)
+ dir=`echo "X$x" | sed -e 's/^X-L//'`
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ fi
+ fi
+ ;;
+ esac
+ if test "X$found_dir" != "X"; then
+ break
+ fi
+ done
+ fi
+ if test "X$found_dir" != "X"; then
+ dnl Found the library.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
+ if test "X$found_so" != "X"; then
+ dnl Linking with a shared library. We attempt to hardcode its
+ dnl directory into the executable's runpath, unless it's the
+ dnl standard /usr/lib.
+ if test "$enable_rpath" = no \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem" \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then
+ dnl No hardcoding is needed.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $found_dir"
+ fi
+ dnl The hardcoding into $LIBNAME is system dependent.
+ if test "$acl_hardcode_direct" = yes; then
+ dnl Using DIR/libNAME.so during linking hardcodes DIR into the
+ dnl resulting binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $found_dir"
+ fi
+ else
+ dnl Rely on "-L$found_dir".
+ dnl But don't add it if it's already contained in the LDFLAGS
+ dnl or the already constructed $LIBNAME
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
+ fi
+ if test "$acl_hardcode_minus_L" != no; then
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
+ dnl here, because this doesn't fit in flags passed to the
+ dnl compiler. So give up. No hardcoding. This affects only
+ dnl very old systems.
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ fi
+ else
+ if test "X$found_a" != "X"; then
+ dnl Linking with a static library.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
+ else
+ dnl We shouldn't come here, but anyway it's good to have a
+ dnl fallback.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
+ fi
+ fi
+ dnl Assume the include files are nearby.
+ additional_includedir=
+ case "$found_dir" in
+ */$acl_libdirstem | */$acl_libdirstem/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ */$acl_libdirstem2 | */$acl_libdirstem2/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ esac
+ if test "X$additional_includedir" != "X"; then
+ dnl Potentially add $additional_includedir to $INCNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 3. if it's already present in $CPPFLAGS or the already
+ dnl constructed $INCNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ for x in $CPPFLAGS $INC[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $INCNAME.
+ INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ fi
+ dnl Look for dependencies.
+ if test -n "$found_la"; then
+ dnl Read the .la file. It defines the variables
+ dnl dlname, library_names, old_library, dependency_libs, current,
+ dnl age, revision, installed, dlopen, dlpreopen, libdir.
+ save_libdir="$libdir"
+ case "$found_la" in
+ */* | *\\*) . "$found_la" ;;
+ *) . "./$found_la" ;;
+ esac
+ libdir="$save_libdir"
+ dnl We use only dependency_libs.
+ for dep in $dependency_libs; do
+ case "$dep" in
+ -L*)
+ additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
+ dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 3. if it's already present in $LDFLAGS or the already
+ dnl constructed $LIBNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \
+ && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then
+ haveit=
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \
+ || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LIBNAME.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ haveit=
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LTLIBNAME.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ -R*)
+ dir=`echo "X$dep" | sed -e 's/^X-R//'`
+ if test "$enable_rpath" != no; then
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $dir"
+ fi
+ fi
+ ;;
+ -l*)
+ dnl Handle this in the next round.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
+ ;;
+ *.la)
+ dnl Handle this in the next round. Throw away the .la's
+ dnl directory; it is already contained in a preceding -L
+ dnl option.
+ names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
+ ;;
+ *)
+ dnl Most likely an immediate library name.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
+ ;;
+ esac
+ done
+ fi
+ else
+ dnl Didn't find the library; assume it is in the system directories
+ dnl known to the linker and runtime loader. (All the system
+ dnl directories known to the linker should also be known to the
+ dnl runtime loader, otherwise the system is severely misconfigured.)
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ done
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n "$acl_hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user must
+ dnl pass all path elements in one option. We can arrange that for a
+ dnl single library, but not when more than one $LIBNAMEs are used.
+ alldirs=
+ for found_dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+ done
+ dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for found_dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$found_dir"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ done
+ fi
+ fi
+ if test "X$ltrpathdirs" != "X"; then
+ dnl When using libtool, the option that works for both libraries and
+ dnl executables is -R. The -R options are cumulative.
+ for found_dir in $ltrpathdirs; do
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
+ done
+ fi
+ popdef([P_A_C_K])
+ popdef([PACKLIBS])
+ popdef([PACKUP])
+ popdef([PACK])
+ popdef([NAME])
+])
+
+dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
+dnl unless already present in VAR.
+dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
+dnl contains two or three consecutive elements that belong together.
+AC_DEFUN([AC_LIB_APPENDTOVAR],
+[
+ for element in [$2]; do
+ haveit=
+ for x in $[$1]; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ [$1]="${[$1]}${[$1]:+ }$element"
+ fi
+ done
+])
+
+dnl For those cases where a variable contains several -L and -l options
+dnl referring to unknown libraries and directories, this macro determines the
+dnl necessary additional linker options for the runtime path.
+dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
+dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
+dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
+dnl otherwise linking without libtool is assumed.
+AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
+[
+ AC_REQUIRE([AC_LIB_RPATH])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ $1=
+ if test "$enable_rpath" != no; then
+ if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode directories into the resulting
+ dnl binary.
+ rpathdirs=
+ next=
+ for opt in $2; do
+ if test -n "$next"; then
+ dir="$next"
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next=
+ else
+ case $opt in
+ -L) next=yes ;;
+ -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" != "X/usr/$acl_libdirstem2"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next= ;;
+ *) next= ;;
+ esac
+ fi
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n ""$3""; then
+ dnl libtool is used for linking. Use -R options.
+ for dir in $rpathdirs; do
+ $1="${$1}${$1:+ }-R$dir"
+ done
+ else
+ dnl The linker is used for linking directly.
+ if test -n "$acl_hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user
+ dnl must pass all path elements in one option.
+ alldirs=
+ for dir in $rpathdirs; do
+ alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$dir"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="${$1}${$1:+ }$flag"
+ done
+ fi
+ fi
+ fi
+ fi
+ fi
+ AC_SUBST([$1])
+])
diff --git a/src/wok/plugins/kimchi/m4/lib-prefix.m4 b/src/wok/plugins/kimchi/m4/lib-prefix.m4
new file mode 100644
index 0000000..1601cea
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/lib-prefix.m4
@@ -0,0 +1,224 @@
+# lib-prefix.m4 serial 7 (gettext-0.18)
+dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
+dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
+dnl require excessive bracketing.
+ifdef([AC_HELP_STRING],
+[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
+[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
+
+dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
+dnl to access previously installed libraries. The basic assumption is that
+dnl a user will want packages to use other packages he previously installed
+dnl with the same --prefix option.
+dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
+dnl libraries, but is otherwise very convenient.
+AC_DEFUN([AC_LIB_PREFIX],
+[
+ AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_LIB_ARG_WITH([lib-prefix],
+[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+ --without-lib-prefix don't search for libraries in includedir and libdir],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ fi
+ fi
+])
+ if test $use_additional = yes; then
+ dnl Potentially add $additional_includedir to $CPPFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's already present in $CPPFLAGS,
+ dnl 3. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ for x in $CPPFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_includedir" = "X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $CPPFLAGS.
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ dnl Potentially add $additional_libdir to $LDFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's already present in $LDFLAGS,
+ dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
+ haveit=
+ for x in $LDFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux*) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LDFLAGS.
+ LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ fi
+])
+
+dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
+dnl acl_final_exec_prefix, containing the values to which $prefix and
+dnl $exec_prefix will expand at the end of the configure script.
+AC_DEFUN([AC_LIB_PREPARE_PREFIX],
+[
+ dnl Unfortunately, prefix and exec_prefix get only finally determined
+ dnl at the end of configure.
+ if test "X$prefix" = "XNONE"; then
+ acl_final_prefix="$ac_default_prefix"
+ else
+ acl_final_prefix="$prefix"
+ fi
+ if test "X$exec_prefix" = "XNONE"; then
+ acl_final_exec_prefix='${prefix}'
+ else
+ acl_final_exec_prefix="$exec_prefix"
+ fi
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
+dnl variables prefix and exec_prefix bound to the values they will have
+dnl at the end of the configure script.
+AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
+[
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ $1
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_PREPARE_MULTILIB creates
+dnl - a variable acl_libdirstem, containing the basename of the libdir, either
+dnl "lib" or "lib64" or "lib/64",
+dnl - a variable acl_libdirstem2, as a secondary possible value for
+dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
+dnl "lib/amd64".
+AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
+[
+ dnl There is no formal standard regarding lib and lib64.
+ dnl On glibc systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
+ dnl the compiler's default mode by looking at the compiler's library search
+ dnl path. If at least one of its elements ends in /lib64 or points to a
+ dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
+ dnl Otherwise we use the default, namely "lib".
+ dnl On Solaris systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
+ dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ acl_libdirstem=lib
+ acl_libdirstem2=
+ case "$host_os" in
+ solaris*)
+ dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment
+ dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
+ dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link."
+ dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
+ dnl symlink is missing, so we set acl_libdirstem2 too.
+ AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
+ [AC_EGREP_CPP([sixtyfour bits], [
+#ifdef _LP64
+sixtyfour bits
+#endif
+ ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
+ ])
+ if test $gl_cv_solaris_64bit = yes; then
+ acl_libdirstem=lib/64
+ case "$host_cpu" in
+ sparc*) acl_libdirstem2=lib/sparcv9 ;;
+ i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+ esac
+ fi
+ ;;
+ *)
+ searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test -n "$searchpath"; then
+ acl_save_IFS="${IFS= }"; IFS=":"
+ for searchdir in $searchpath; do
+ if test -d "$searchdir"; then
+ case "$searchdir" in
+ */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+ */../ | */.. )
+ # Better ignore directories of this form. They are misleading.
+ ;;
+ *) searchdir=`cd "$searchdir" && pwd`
+ case "$searchdir" in
+ */lib64 ) acl_libdirstem=lib64 ;;
+ esac ;;
+ esac
+ fi
+ done
+ IFS="$acl_save_IFS"
+ fi
+ ;;
+ esac
+ test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+])
diff --git a/src/wok/plugins/kimchi/m4/nls.m4 b/src/wok/plugins/kimchi/m4/nls.m4
new file mode 100644
index 0000000..003704c
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/nls.m4
@@ -0,0 +1,32 @@
+# nls.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper at cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible at clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_NLS],
+[
+ AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE([nls],
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT([$USE_NLS])
+ AC_SUBST([USE_NLS])
+])
diff --git a/src/wok/plugins/kimchi/m4/po.m4 b/src/wok/plugins/kimchi/m4/po.m4
new file mode 100644
index 0000000..8bc921d
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/po.m4
@@ -0,0 +1,449 @@
+# po.m4 serial 17 (gettext-0.18)
+dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper at cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible at clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.50])
+
+dnl Checks for all prerequisites of the po subdirectory.
+AC_DEFUN([AM_PO_SUBDIRS],
+[
+ AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+ AC_REQUIRE([AC_PROG_MKDIR_P])dnl defined by autoconf
+ AC_REQUIRE([AM_NLS])dnl
+
+ dnl Release version of the gettext macros. This is used to ensure that
+ dnl the gettext macros and po/Makefile.in.in are in sync.
+ AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
+
+ dnl Perform the following tests also if --disable-nls has been given,
+ dnl because they are needed for "make dist" to work.
+
+ dnl Search for GNU msgfmt in the PATH.
+ dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
+ dnl The second test excludes FreeBSD msgfmt.
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+ :)
+ AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
+
+ dnl Test whether it is GNU msgfmt >= 0.15.
+changequote(,)dnl
+ case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+ *) MSGFMT_015=$MSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([MSGFMT_015])
+changequote(,)dnl
+ case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+ *) GMSGFMT_015=$GMSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([GMSGFMT_015])
+
+ dnl Search for GNU xgettext 0.12 or newer in the PATH.
+ dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
+ dnl The second test excludes FreeBSD xgettext.
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
+ :)
+ dnl Remove leftover from FreeBSD xgettext call.
+ rm -f messages.po
+
+ dnl Test whether it is GNU xgettext >= 0.15.
+changequote(,)dnl
+ case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+ *) XGETTEXT_015=$XGETTEXT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([XGETTEXT_015])
+
+ dnl Search for GNU msgmerge 0.11 or newer in the PATH.
+ AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
+ [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
+
+ dnl Installation directories.
+ dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
+ dnl have to define it here, so that it can be used in po/Makefile.
+ test -n "$localedir" || localedir='${datadir}/locale'
+ AC_SUBST([localedir])
+
+ dnl Support for AM_XGETTEXT_OPTION.
+ test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+ AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
+
+ AC_CONFIG_COMMANDS([po-directories], [[
+ for ac_file in $CONFIG_FILES; do
+ # Support "outfile[:infile[:infile...]]"
+ case "$ac_file" in
+ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ esac
+ # PO directories have a Makefile.in generated from Makefile.in.in.
+ case "$ac_file" in */Makefile.in)
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+ # Treat a directory as a PO directory if and only if it has a
+ # POTFILES.in file. This allows packages to have multiple PO
+ # directories under different names or in different locations.
+ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+ rm -f "$ac_dir/POTFILES"
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+ POMAKEFILEDEPS="POTFILES.in"
+ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+ # on $ac_dir but don't depend on user-specified configuration
+ # parameters.
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ fi
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ done
+ fi
+ test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+ if test -f "$f"; then
+ case "$f" in
+ *.orig | *.bak | *~) ;;
+ *) cat "$f" >> "$ac_dir/Makefile" ;;
+ esac
+ fi
+ done
+ fi
+ ;;
+ esac
+ done]],
+ [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+ # from automake < 1.5.
+ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="${LINGUAS-%UNSET%}"
+ ])
+])
+
+dnl Postprocesses a Makefile in a directory containing PO files.
+AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
+[
+ # When this code is run, in config.status, two variables have already been
+ # set:
+ # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
+ # - LINGUAS is the value of the environment variable LINGUAS at configure
+ # time.
+
+changequote(,)dnl
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ # Find a way to echo strings without interpreting backslash.
+ if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
+ gt_echo='echo'
+ else
+ if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
+ gt_echo='printf %s\n'
+ else
+ echo_func () {
+ cat <<EOT
+$*
+EOT
+ }
+ gt_echo='echo_func'
+ fi
+ fi
+
+ # A sed script that extracts the value of VARIABLE from a Makefile.
+ sed_x_variable='
+# Test if the hold space is empty.
+x
+s/P/P/
+x
+ta
+# Yes it was empty. Look if we have the expected variable definition.
+/^[ ]*VARIABLE[ ]*=/{
+ # Seen the first line of the variable definition.
+ s/^[ ]*VARIABLE[ ]*=//
+ ba
+}
+bd
+:a
+# Here we are processing a line from the variable definition.
+# Remove comment, more precisely replace it with a space.
+s/#.*$/ /
+# See if the line ends in a backslash.
+tb
+:b
+s/\\$//
+# Print the line, without the trailing backslash.
+p
+tc
+# There was no trailing backslash. The end of the variable definition is
+# reached. Clear the hold space.
+s/^.*$//
+x
+bd
+:c
+# A trailing backslash means that the variable definition continues in the
+# next line. Put a nonempty string into the hold space to indicate this.
+s/^.*$/P/
+x
+:d
+'
+changequote([,])dnl
+
+ # Set POTFILES to the value of the Makefile variable POTFILES.
+ sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
+ POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
+ # Compute POTFILES_DEPS as
+ # $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
+ POTFILES_DEPS=
+ for file in $POTFILES; do
+ POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
+ done
+ POMAKEFILEDEPS=""
+
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
+ fi
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
+ sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
+ ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
+ fi
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ # Compute PROPERTIESFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
+ # Compute CLASSFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
+ # Compute QMFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
+ # Compute MSGFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
+ # Compute RESOURCESDLLFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ PROPERTIESFILES=
+ CLASSFILES=
+ QMFILES=
+ MSGFILES=
+ RESOURCESDLLFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
+ CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
+ QMFILES="$QMFILES $srcdirpre$lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ JAVACATALOGS=
+ QTCATALOGS=
+ TCLCATALOGS=
+ CSHARPCATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
+ QTCATALOGS="$QTCATALOGS $lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ fi
+
+ sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
+ if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang.msg: $lang.po
+ @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+ \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
+ @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
+ \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if test -n "$POMAKEFILEDEPS"; then
+ cat >> "$ac_file.tmp" <<EOF
+Makefile: $POMAKEFILEDEPS
+EOF
+ fi
+ mv "$ac_file.tmp" "$ac_file"
+])
+
+dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
+AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
+[
+ XGETTEXT_EXTRA_OPTIONS=
+])
+
+dnl Registers an option to be passed to xgettext in the po subdirectory.
+AC_DEFUN([AM_XGETTEXT_OPTION],
+[
+ AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
+ XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
+])
diff --git a/src/wok/plugins/kimchi/m4/progtest.m4 b/src/wok/plugins/kimchi/m4/progtest.m4
new file mode 100644
index 0000000..2d804ac
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/progtest.m4
@@ -0,0 +1,92 @@
+# progtest.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper at cygnus.com>, 1996.
+
+AC_PREREQ([2.50])
+
+# Search path for a program which passes the given test.
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST],
+[
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL([ac_cv_path_$1],
+[case "[$]$1" in
+ [[\\/]]* | ?:[[\\/]]*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+ AC_MSG_RESULT([$][$1])
+else
+ AC_MSG_RESULT([no])
+fi
+AC_SUBST([$1])dnl
+])
diff --git a/src/wok/plugins/kimchi/mockmodel.py b/src/wok/plugins/kimchi/mockmodel.py
new file mode 100644
index 0000000..b269c26
--- /dev/null
+++ b/src/wok/plugins/kimchi/mockmodel.py
@@ -0,0 +1,627 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import os
+import random
+import time
+from lxml import objectify
+from lxml.builder import E
+
+from wok.exception import NotFoundError, OperationFailed
+from wok.objectstore import ObjectStore
+from wok.utils import add_task, get_next_clone_name, wok_log
+from wok.xmlutils.utils import xml_item_update
+
+import config
+import imageinfo
+import osinfo
+from model import cpuinfo
+from model.debugreports import DebugReportsModel
+from model.host import DeviceModel
+from model.libvirtstoragepool import IscsiPoolDef, NetfsPoolDef
+from model.libvirtstoragepool import StoragePoolDef
+from model.model import Model
+from model.storagepools import StoragePoolModel
+from model.storagevolumes import StorageVolumeModel, StorageVolumesModel
+from model.templates import LibvirtVMTemplate
+from model.users import PAMUsersModel
+from model.groups import PAMGroupsModel
+from vmtemplate import VMTemplate
+
+
+fake_user = {'root': 'letmein!'}
+mockmodel_defaults = {
+ 'storagepool': '/plugins/kimchi/storagepools/default-pool',
+ 'domain': 'test', 'arch': 'i686'
+}
+
+
+class MockModel(Model):
+ _mock_vms = {}
+ _mock_snapshots = {}
+ _XMLDesc = libvirt.virDomain.XMLDesc
+ _defineXML = libvirt.virConnect.defineXML
+ _undefineDomain = libvirt.virDomain.undefine
+ _libvirt_get_vol_path = LibvirtVMTemplate._get_volume_path
+
+ def __init__(self, objstore_loc=None):
+ # Override osinfo.defaults to ajust the values according to
+ # test:///default driver
+ defaults = dict(osinfo.defaults)
+ defaults.update(mockmodel_defaults)
+ osinfo.defaults = dict(defaults)
+
+ self._mock_devices = MockDevices()
+ self._mock_partitions = MockPartitions()
+ self._mock_storagevolumes = MockStorageVolumes()
+ self._mock_swupdate = MockSoftwareUpdate()
+ self._mock_repositories = MockRepositories()
+
+ cpuinfo.get_topo_capabilities = \
+ MockModel.get_topo_capabilities
+ libvirt.virConnect.defineXML = MockModel.domainDefineXML
+ libvirt.virDomain.XMLDesc = MockModel.domainXMLDesc
+ libvirt.virDomain.undefine = MockModel.undefineDomain
+ libvirt.virDomain.attachDeviceFlags = MockModel.attachDeviceFlags
+ libvirt.virDomain.detachDeviceFlags = MockModel.detachDeviceFlags
+ libvirt.virDomain.updateDeviceFlags = MockModel.updateDeviceFlags
+ libvirt.virStorageVol.resize = MockModel.volResize
+ libvirt.virStorageVol.wipePattern = MockModel.volWipePattern
+
+ IscsiPoolDef.prepare = NetfsPoolDef.prepare = StoragePoolDef.prepare
+
+ PAMUsersModel.auth_type = 'fake'
+ PAMGroupsModel.auth_type = 'fake'
+
+ super(MockModel, self).__init__('test:///default', objstore_loc)
+ self.objstore_loc = objstore_loc
+ self.objstore = ObjectStore(objstore_loc)
+
+ # The MockModel methods are instantiated on runtime according to Model
+ # and BaseModel
+ # Because that a normal method override will not work here
+ # Instead of that we also need to do the override on runtime
+ for method in dir(self):
+ if method.startswith('_mock_'):
+ mock_method = getattr(self, method)
+ if not callable(mock_method):
+ continue
+
+ m = method[6:]
+ model_method = getattr(self, m)
+ setattr(self, '_model_' + m, model_method)
+ setattr(self, m, mock_method)
+
+ DeviceModel.lookup = self._mock_device_lookup
+ StoragePoolModel._update_lvm_disks = self._update_lvm_disks
+ StorageVolumesModel.get_list = self._mock_storagevolumes_get_list
+ StorageVolumeModel.doUpload = self._mock_storagevolume_doUpload
+ DebugReportsModel._gen_debugreport_file = self._gen_debugreport_file
+ LibvirtVMTemplate._get_volume_path = self._get_volume_path
+ VMTemplate.get_iso_info = self._probe_image
+ imageinfo.probe_image = self._probe_image
+
+ def reset(self):
+ MockModel._mock_vms = {}
+ MockModel._mock_snapshots = {}
+ self._mock_swupdate = MockSoftwareUpdate()
+ self._mock_repositories = MockRepositories()
+
+ if hasattr(self, 'objstore'):
+ self.objstore = ObjectStore(self.objstore_loc)
+
+ params = {'vms': [u'test'], 'templates': [],
+ 'networks': [u'default'], 'storagepools': [u'default-pool']}
+
+ for res, items in params.iteritems():
+ resources = getattr(self, '%s_get_list' % res)()
+ for i in resources:
+ if i in items:
+ continue
+
+ try:
+ getattr(self, '%s_deactivate' % res[:-1])(i)
+ except:
+ pass
+
+ getattr(self, '%s_delete' % res[:-1])(i)
+
+ volumes = self.storagevolumes_get_list('default-pool')
+ for v in volumes:
+ self.storagevolume_delete('default-pool', v)
+
+ @staticmethod
+ def get_topo_capabilities(conn):
+ # The libvirt test driver doesn't return topology.
+ xml = "<topology sockets='1' cores='2' threads='2'/>"
+ return ET.fromstring(xml)
+
+ @staticmethod
+ def domainDefineXML(conn, xml):
+ name = objectify.fromstring(xml).name.text
+ try:
+ dom = conn.lookupByName(name)
+ if not dom.isActive():
+ MockModel._mock_vms[name] = xml
+ except:
+ pass
+
+ return MockModel._defineXML(conn, xml)
+
+ @staticmethod
+ def domainXMLDesc(dom, flags=0):
+ return MockModel._mock_vms.get(dom.name(),
+ MockModel._XMLDesc(dom, flags))
+
+ @staticmethod
+ def undefineDomain(dom):
+ name = dom.name()
+ if name in MockModel._mock_vms.keys():
+ del MockModel._mock_vms[dom.name()]
+ return MockModel._undefineDomain(dom)
+
+ @staticmethod
+ def attachDeviceFlags(dom, xml, flags=0):
+ old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+ root = objectify.fromstring(old_xml)
+ dev = objectify.fromstring(xml)
+ root.devices.append(dev)
+
+ MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
+
+ @staticmethod
+ def _get_device_node(dom, xml):
+ xpath_map = {'disk': 'target',
+ 'interface': 'mac',
+ 'graphics': 'listen'}
+
+ dev = objectify.fromstring(xml)
+ dev_id = dev.find(xpath_map[dev.tag]).items()
+
+ dev_filter = ''
+ for key, value in dev_id:
+ dev_filter += "[@%s='%s']" % (key, value)
+
+ old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+ root = objectify.fromstring(old_xml)
+ devices = root.devices
+
+ dev = devices.find("./%s/%s%s/.." % (dev.tag, xpath_map[dev.tag],
+ dev_filter))
+
+ return (root, dev)
+
+ @staticmethod
+ def detachDeviceFlags(dom, xml, flags=0):
+ root, dev = MockModel._get_device_node(dom, xml)
+ root.devices.remove(dev)
+
+ MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
+
+ @staticmethod
+ def updateDeviceFlags(dom, xml, flags=0):
+ root, old_dev = MockModel._get_device_node(dom, xml)
+ root.devices.replace(old_dev, objectify.fromstring(xml))
+ MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
+
+ @staticmethod
+ def volResize(vol, size, flags=0):
+ new_xml = xml_item_update(vol.XMLDesc(0), './capacity', str(size))
+ vol.delete(0)
+ pool = vol.storagePoolLookupByVolume()
+ pool.createXML(new_xml)
+
+ @staticmethod
+ def volWipePattern(vol, algorithm, flags=0):
+ new_xml = xml_item_update(vol.XMLDesc(0), './allocation', '0')
+ vol.delete(0)
+ pool = vol.storagePoolLookupByVolume()
+ pool.createXML(new_xml)
+
+ def _probe_image(self, path):
+ return ('unknown', 'unknown')
+
+ def _get_volume_path(self, pool, vol):
+ pool_info = self.storagepool_lookup(pool)
+ if pool_info['type'] == 'scsi':
+ return self._mock_storagevolumes.scsi_volumes[vol]['path']
+
+ return MockModel._libvirt_get_vol_path(pool, vol)
+
+ def _gen_debugreport_file(self, name):
+ return add_task('/plugins/kimchi/debugreports/%s' % name,
+ self._create_log, self.objstore, name)
+
+ def _create_log(self, cb, name):
+ path = config.get_debugreports_path()
+ tmpf = os.path.join(path, name + '.tmp')
+ realf = os.path.join(path, name + '.txt')
+ length = random.randint(1000, 10000)
+ with open(tmpf, 'w') as fd:
+ while length:
+ fd.write('I am logged')
+ length = length - 1
+ os.rename(tmpf, realf)
+ cb("OK", True)
+
+ def _update_lvm_disks(self, pool_name, disks):
+ conn = self.conn.get()
+ pool = conn.storagePoolLookupByName(pool_name.encode('utf-8'))
+ xml = pool.XMLDesc(0)
+
+ root = ET.fromstring(xml)
+ source = root.xpath('./source')[0]
+
+ for d in disks:
+ dev = E.device(path=d)
+ source.append(dev)
+
+ conn.storagePoolDefineXML(ET.tostring(root), 0)
+
+ def _mock_host_shutdown(self, *name):
+ wok_log.info("The host system will be shutted down")
+
+ def _mock_host_reboot(self, *name):
+ wok_log.info("The host system will be rebooted")
+
+ def _mock_storagevolumes_create(self, pool, params):
+ vol_source = ['url', 'capacity']
+ index_list = list(i for i in range(len(vol_source))
+ if vol_source[i] in params)
+ create_param = vol_source[index_list[0]]
+ name = params.get('name')
+ if name is None and create_param == 'url':
+ params['name'] = os.path.basename(params['url'])
+ del params['url']
+ params['capacity'] = 1024
+
+ return self._model_storagevolumes_create(pool, params)
+
+ def _mock_storagevolumes_get_list(self, pool):
+ pool_info = self.storagepool_lookup(pool)
+ if pool_info['type'] == 'scsi':
+ return self._mock_storagevolumes.scsi_volumes.keys()
+
+ return self._model_storagevolumes_get_list(pool)
+
+ def _mock_storagevolume_lookup(self, pool, vol):
+ pool_info = self.storagepool_lookup(pool)
+ if pool_info['type'] == 'scsi':
+ return self._mock_storagevolumes.scsi_volumes[vol]
+
+ return self._model_storagevolume_lookup(pool, vol)
+
+ def _mock_storagevolume_doUpload(self, cb, vol, offset, data, data_size):
+ vol_path = vol.path()
+
+ # MockModel does not create the storage volume as a file
+ # So create it to do the file upload
+ if offset == 0:
+ dirname = os.path.dirname(vol_path)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ open(vol_path, 'w').close()
+
+ try:
+ with open(vol_path, 'a') as fd:
+ fd.seek(offset)
+ fd.write(data)
+ except Exception, e:
+ os.remove(vol_path)
+ cb('', False)
+ raise OperationFailed("KCHVOL0029E", {"err": e.message})
+
+ def _mock_partitions_get_list(self):
+ return self._mock_partitions.partitions.keys()
+
+ def _mock_partition_lookup(self, name):
+ return self._mock_partitions.partitions[name]
+
+ def _mock_devices_get_list(self, _cap=None, _passthrough=None,
+ _passthrough_affected_by=None):
+ if _cap is None:
+ return self._mock_devices.devices.keys()
+
+ if _cap == 'fc_host':
+ _cap = 'scsi_host'
+
+ return [dev['name'] for dev in self._mock_devices.devices.values()
+ if dev['device_type'] == _cap]
+
+ def _mock_device_lookup(self, dev_name):
+ return self._mock_devices.devices[dev_name]
+
+ def _mock_packagesupdate_get_list(self):
+ return self._mock_swupdate.pkgs.keys()
+
+ def _mock_packageupdate_lookup(self, pkg_name):
+ return self._mock_swupdate.pkgs[pkg_name]
+
+ def _mock_host_swupdate(self, args=None):
+ task_id = add_task('/plugins/kimchi/host/swupdate',
+ self._mock_swupdate.doUpdate, self.objstore)
+ return self.task_lookup(task_id)
+
+ def _mock_repositories_get_list(self):
+ return self._mock_repositories.repos.keys()
+
+ def _mock_repositories_create(self, params):
+ # Create a repo_id if not given by user. The repo_id will follow
+ # the format kimchi_repo_<integer>, where integer is the number of
+ # seconds since the Epoch (January 1st, 1970), in UTC.
+ repo_id = params.get('repo_id', None)
+ if repo_id is None:
+ repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
+ params.update({'repo_id': repo_id})
+
+ config = params.get('config', {})
+ info = {'repo_id': repo_id,
+ 'baseurl': params['baseurl'],
+ 'enabled': True,
+ 'config': {'repo_name': config.get('repo_name', repo_id),
+ 'gpgkey': config.get('gpgkey', []),
+ 'gpgcheck': True,
+ 'mirrorlist': params.get('mirrorlist', '')}}
+ self._mock_repositories.repos[repo_id] = info
+ return repo_id
+
+ def _mock_repository_lookup(self, repo_id):
+ return self._mock_repositories.repos[repo_id]
+
+ def _mock_repository_delete(self, repo_id):
+ del self._mock_repositories.repos[repo_id]
+
+ def _mock_repository_enable(self, repo_id):
+ self._mock_repositories.repos[repo_id]['enabled'] = True
+
+ def _mock_repository_disable(self, repo_id):
+ self._mock_repositories.repos[repo_id]['enabled'] = False
+
+ def _mock_repository_update(self, repo_id, params):
+ self._mock_repositories.repos[repo_id].update(params)
+ return repo_id
+
+ def _mock_vm_clone(self, name):
+ new_name = get_next_clone_name(self.vms_get_list(), name)
+ snapshots = MockModel._mock_snapshots.get(name, [])
+ MockModel._mock_snapshots[new_name] = snapshots
+ return self._model_vm_clone(name)
+
+ def _mock_vmsnapshots_create(self, vm_name, params):
+ name = params.get('name', unicode(int(time.time())))
+ params = {'vm_name': vm_name, 'name': name}
+ taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' %
+ (vm_name, name), self._vmsnapshots_create_task,
+ self.objstore, params)
+ return self.task_lookup(taskid)
+
+ def _vmsnapshots_create_task(self, cb, params):
+ vm_name = params['vm_name']
+ name = params['name']
+ parent = u''
+
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ for sn in snapshots:
+ if sn.current:
+ sn.current = False
+ parent = sn.name
+
+ snapshots.append(MockVMSnapshot(name, {'parent': parent}))
+ MockModel._mock_snapshots[vm_name] = snapshots
+
+ cb('OK', True)
+
+ def _mock_vmsnapshots_get_list(self, vm_name):
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ return sorted([snap.name for snap in snapshots])
+
+ def _mock_currentvmsnapshot_lookup(self, vm_name):
+ for sn in MockModel._mock_snapshots.get(vm_name, []):
+ if sn.current:
+ return sn.info
+
+ def _mock_vmsnapshot_lookup(self, vm_name, name):
+ for sn in MockModel._mock_snapshots.get(vm_name, []):
+ if sn.name == name:
+ return sn.info
+
+ raise NotFoundError('KCHSNAP0003E', {'name': name, 'vm': vm_name})
+
+ def _mock_vmsnapshot_delete(self, vm_name, name):
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ for sn in snapshots:
+ if sn.name == name:
+ del snapshots[snapshots.index(sn)]
+
+ MockModel._mock_snapshots[vm_name] = snapshots
+
+ def _mock_vmsnapshot_revert(self, vm_name, name):
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ for sn in snapshots:
+ if sn.current:
+ sn.current = False
+
+ for sn in snapshots:
+ if sn.name == name:
+ sn.current = True
+
+
+class MockStorageVolumes(object):
+ def __init__(self):
+ base_path = "/dev/disk/by-path/pci-0000:0e:00.0-fc-0x20-lun"
+ self.scsi_volumes = {'unit:0:0:1': {'capacity': 1024,
+ 'format': 'unknown',
+ 'allocation': 512,
+ 'type': 'block',
+ 'path': base_path + '1',
+ 'used_by': []},
+ 'unit:0:0:2': {'capacity': 2048,
+ 'format': 'unknown',
+ 'allocation': 512,
+ 'type': 'block',
+ 'path': base_path + '2',
+ 'used_by': []}}
+
+
+class MockPartitions(object):
+ def __init__(self):
+ self.partitions = {"vdx": {"available": True, "name": "vdx",
+ "fstype": "", "path": "/dev/vdx",
+ "mountpoint": "", "type": "disk",
+ "size": "2147483648"},
+ "vdz": {"available": True, "name": "vdz",
+ "fstype": "", "path": "/dev/vdz",
+ "mountpoint": "", "type": "disk",
+ "size": "2147483648"}}
+
+
+class MockDevices(object):
+ def __init__(self):
+ self.devices = {
+ 'computer': {'device_type': 'system',
+ 'firmware': {'release_date': '01/01/2012',
+ 'vendor': 'LENOVO',
+ 'version': 'XXXXX (X.XX )'},
+ 'hardware': {'serial': 'PXXXXX',
+ 'uuid':
+ '9d660370-820f-4241-8731-5a60c97e8aa6',
+ 'vendor': 'LENOVO',
+ 'version': 'ThinkPad T420'},
+ 'name': 'computer',
+ 'parent': None,
+ 'product': '4180XXX'},
+ 'pci_0000_03_00_0': {'bus': 3,
+ 'device_type': 'pci',
+ 'domain': 0,
+ 'driver': {'name': 'iwlwifi'},
+ 'function': 0,
+ 'iommuGroup': 7,
+ 'name': 'pci_0000_03_00_0',
+ 'parent': 'computer',
+ 'path':
+ '/sys/devices/pci0000:00/0000:03:00.0',
+ 'product': {
+ 'description':
+ 'Centrino Advanced-N 6205 [Taylor Peak]',
+ 'id': '0x0085'},
+ 'slot': 0,
+ 'vendor': {'description': 'Intel Corporation',
+ 'id': '0x8086'}},
+ 'pci_0000_0d_00_0': {'bus': 13,
+ 'device_type': 'pci',
+ 'domain': 0,
+ 'driver': {'name': 'sdhci-pci'},
+ 'function': 0,
+ 'iommuGroup': 7,
+ 'name': 'pci_0000_0d_00_0',
+ 'parent': 'computer',
+ 'path':
+ '/sys/devices/pci0000:00/0000:0d:00.0',
+ 'product': {'description':
+ 'PCIe SDXC/MMC Host Controller',
+ 'id': '0xe823'},
+ 'slot': 0,
+ 'vendor': {'description': 'Ricoh Co Ltd',
+ 'id': '0x1180'}},
+ 'scsi_host0': {'adapter': {'fabric_wwn': '37df6c1efa1b4388',
+ 'type': 'fc_host',
+ 'wwnn': 'efb6563f06434a98',
+ 'wwpn': '742f32073aab45d7'},
+ 'device_type': 'scsi_host',
+ 'host': 0,
+ 'name': 'scsi_host0',
+ 'parent': 'computer',
+ 'path': '/sys/devices/pci0000:00/0000:40:00.0/0'},
+ 'scsi_host1': {'adapter': {'fabric_wwn': '542efa5dced34123',
+ 'type': 'fc_host',
+ 'wwnn': 'b7433a40c9b84092',
+ 'wwpn': '25c1f485ae42497f'},
+ 'device_type': 'scsi_host',
+ 'host': 0,
+ 'name': 'scsi_host1',
+ 'parent': 'computer',
+ 'path': '/sys/devices/pci0000:00/0000:40:00.0/1'},
+ 'scsi_host2': {'adapter': {'fabric_wwn': '5c373c334c20478d',
+ 'type': 'fc_host',
+ 'wwnn': 'f2030bec4a254e6b',
+ 'wwpn': '07dbca4164d44096'},
+ 'device_type': 'scsi_host',
+ 'host': 0,
+ 'name': 'scsi_host2',
+ 'parent': 'computer',
+ 'path': '/sys/devices/pci0000:00/0000:40:00.0/2'}}
+
+
+class MockSoftwareUpdate(object):
+ def __init__(self):
+ self.pkgs = {
+ 'udevmountd': {'repository': 'openSUSE-13.1-Update',
+ 'version': '0.81.5-14.1',
+ 'arch': 'x86_64',
+ 'package_name': 'udevmountd'},
+ 'sysconfig-network': {'repository': 'openSUSE-13.1-Extras',
+ 'version': '0.81.5-14.1',
+ 'arch': 'x86_64',
+ 'package_name': 'sysconfig-network'},
+ 'libzypp': {'repository': 'openSUSE-13.1-Update',
+ 'version': '13.9.0-10.1',
+ 'arch': 'noarch',
+ 'package_name': 'libzypp'}}
+ self._num2update = 3
+
+ def doUpdate(self, cb, params):
+ msgs = []
+ for pkg in self.pkgs.keys():
+ msgs.append("Updating package %s" % pkg)
+ cb('\n'.join(msgs))
+ time.sleep(1)
+
+ time.sleep(2)
+ msgs.append("All packages updated")
+ cb('\n'.join(msgs), True)
+
+ # After updating all packages any package should be listed to be
+ # updated, so reset self._packages
+ self.pkgs = {}
+
+
+class MockRepositories(object):
+ def __init__(self):
+ self.repos = {"kimchi_repo_1392167832":
+ {"repo_id": "kimchi_repo_1392167832",
+ "enabled": True,
+ "baseurl": "http://www.fedora.org",
+ "config": {"repo_name": "kimchi_repo_1392167832",
+ "gpgkey": [],
+ "gpgcheck": True,
+ "mirrorlist": ""}}}
+
+
+class MockVMSnapshot(object):
+ def __init__(self, name, params={}):
+ self.name = name
+ self.current = True
+
+ self.info = {'created': params.get('created',
+ unicode(int(time.time()))),
+ 'name': name,
+ 'parent': params.get('parent', u''),
+ 'state': params.get('state', u'shutoff')}
diff --git a/src/wok/plugins/kimchi/model/Makefile.am b/src/wok/plugins/kimchi/model/Makefile.am
new file mode 100644
index 0000000..f4f4750
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+model_PYTHON = *.py
+
+modeldir = $(pythondir)/wok/plugins/kimchi/model
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(modeldir)
diff --git a/src/wok/plugins/kimchi/model/__init__.py b/src/wok/plugins/kimchi/model/__init__.py
new file mode 100644
index 0000000..ca7ede4
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/__init__.py
@@ -0,0 +1,18 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/src/wok/plugins/kimchi/model/config.py b/src/wok/plugins/kimchi/model/config.py
new file mode 100644
index 0000000..464ffae
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/config.py
@@ -0,0 +1,176 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+from multiprocessing.pool import ThreadPool
+
+from wok.basemodel import Singleton
+from wok.config import config as kconfig
+from wok.config import get_version
+from wok.exception import NotFoundError
+from wok.utils import check_url_path, run_command, wok_log
+
+from ..config import find_qemu_binary
+from ..distroloader import DistroLoader
+from ..repositories import Repositories
+from ..screenshot import VMScreenshot
+from ..swupdate import SoftwareUpdate
+from debugreports import DebugReportsModel
+from featuretests import FeatureTests, FEATURETEST_POOL_NAME
+from featuretests import FEATURETEST_VM_NAME
+
+
+class ConfigModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ proxy_port = kconfig.get('display', 'display_proxy_port')
+ return {'display_proxy_port': proxy_port,
+ 'version': get_version()}
+
+
+class CapabilitiesModel(object):
+ __metaclass__ = Singleton
+
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.qemu_stream = False
+ self.libvirt_stream_protocols = []
+ self.fc_host_support = False
+ self.metadata_support = False
+ self.kernel_vfio = False
+ self.mem_hotplug_support = False
+
+ # Subscribe function to set host capabilities to be run when cherrypy
+ # server is up
+ # It is needed because some features tests depends on the server
+ cherrypy.engine.subscribe('start', self._set_capabilities)
+
+ # Subscribe function to clean any Kimchi leftovers
+ cherrypy.engine.subscribe('stop', self._clean_leftovers)
+
+ def _clean_leftovers(self):
+ conn = self.conn.get()
+ FeatureTests.disable_libvirt_error_logging()
+ try:
+ dom = conn.lookupByName(FEATURETEST_VM_NAME)
+ dom.undefine()
+ except Exception:
+ # Any exception can be ignored here
+ pass
+
+ try:
+ pool = conn.storagePoolLookupByName(FEATURETEST_POOL_NAME)
+ pool.undefine()
+ except Exception:
+ # Any exception can be ignored here
+ pass
+
+ FeatureTests.enable_libvirt_error_logging()
+
+ def _set_capabilities(self):
+ wok_log.info("*** Running feature tests ***")
+ conn = self.conn.get()
+ self.qemu_stream = FeatureTests.qemu_supports_iso_stream()
+ self.nfs_target_probe = FeatureTests.libvirt_support_nfs_probe(conn)
+ self.fc_host_support = FeatureTests.libvirt_support_fc_host(conn)
+ self.metadata_support = FeatureTests.has_metadata_support(conn)
+ self.kernel_vfio = FeatureTests.kernel_support_vfio()
+ self.mem_hotplug_support = FeatureTests.has_mem_hotplug_support(conn)
+
+ self.libvirt_stream_protocols = []
+ for p in ['http', 'https', 'ftp', 'ftps', 'tftp']:
+ if FeatureTests.libvirt_supports_iso_stream(conn, p):
+ self.libvirt_stream_protocols.append(p)
+
+ wok_log.info("*** Feature tests completed ***")
+ _set_capabilities.priority = 90
+
+ def _qemu_support_spice(self):
+ qemu_path = find_qemu_binary(find_emulator=True)
+ out, err, rc = run_command(['ldd', qemu_path])
+ if rc != 0:
+ wok_log.error('Failed to find qemu binary dependencies: %s',
+ err)
+ return False
+ for line in out.split('\n'):
+ if line.lstrip().startswith('libspice-server.so'):
+ return True
+ return False
+
+ def lookup(self, *ident):
+ report_tool = DebugReportsModel.get_system_report_tool()
+ try:
+ SoftwareUpdate()
+ except Exception:
+ update_tool = False
+ else:
+ update_tool = True
+
+ try:
+ repo = Repositories()
+ except Exception:
+ repo_mngt_tool = None
+ else:
+ repo_mngt_tool = repo._pkg_mnger.TYPE
+
+ return {'libvirt_stream_protocols': self.libvirt_stream_protocols,
+ 'qemu_spice': self._qemu_support_spice(),
+ 'qemu_stream': self.qemu_stream,
+ 'screenshot': VMScreenshot.get_stream_test_result(),
+ 'system_report_tool': bool(report_tool),
+ 'update_tool': update_tool,
+ 'repo_mngt_tool': repo_mngt_tool,
+ 'federation': kconfig.get("server", "federation"),
+ 'auth': kconfig.get("authentication", "method"),
+ 'kernel_vfio': self.kernel_vfio,
+ 'nm_running': FeatureTests.is_nm_running(),
+ 'mem_hotplug_support': self.mem_hotplug_support
+ }
+
+
+class DistrosModel(object):
+ def __init__(self, **kargs):
+ distroloader = DistroLoader()
+ self.distros = distroloader.get()
+
+ def get_list(self):
+ def validate_distro(distro):
+ if check_url_path(distro['path']):
+ return distro['name']
+
+ n_processes = len(self.distros.keys())
+ pool = ThreadPool(processes=n_processes)
+ map_res = pool.map_async(validate_distro, self.distros.values())
+ pool.close()
+ pool.join()
+ res = list(set(map_res.get()) - set([None]))
+ return sorted(res)
+
+
+class DistroModel(object):
+ def __init__(self, **kargs):
+ self._distros = DistrosModel()
+
+ def lookup(self, name):
+ try:
+ return self._distros.distros[name]
+ except KeyError:
+ raise NotFoundError("KCHDISTRO0001E", {'name': name})
diff --git a/src/wok/plugins/kimchi/model/cpuinfo.py b/src/wok/plugins/kimchi/model/cpuinfo.py
new file mode 100644
index 0000000..299e445
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/cpuinfo.py
@@ -0,0 +1,126 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import platform
+from xml.etree import ElementTree as ET
+
+from wok.exception import InvalidParameter, InvalidOperation
+from wok.utils import run_command, wok_log
+
+
+ARCH = 'power' if platform.machine().startswith('ppc') else 'x86'
+
+
+def get_topo_capabilities(connect):
+ """
+ This helper function exists solely to be overridden for
+ mockmodel tests. Since other modules use getCapabilies(),
+ it can't be overridden directly.
+ """
+ xml = connect.getCapabilities()
+ capabilities = ET.fromstring(xml)
+ return capabilities.find('host').find('cpu').find('topology')
+
+
+class CPUInfoModel(object):
+ """
+ Get information about a CPU for hyperthreading (on x86)
+ or SMT (on POWER) for logic when creating templates and VMs.
+ """
+
+ def __init__(self, **kargs):
+ self.guest_threads_enabled = False
+ self.sockets = 0
+ self.cores_present = 0
+ self.cores_available = 0
+ self.cores_per_socket = 0
+ self.threads_per_core = 0
+ self.max_threads = 0
+
+ self.conn = kargs['conn']
+ libvirt_topology = None
+ try:
+ connect = self.conn.get()
+ libvirt_topology = get_topo_capabilities(connect)
+ except Exception as e:
+ wok_log.info("Unable to get CPU topology capabilities: %s"
+ % e.message)
+ return
+ if libvirt_topology is None:
+ wok_log.info("cpu_info topology not supported.")
+ return
+
+ if ARCH == 'power':
+ # IBM PowerPC
+ self.guest_threads_enabled = True
+ out, error, rc = run_command(['ppc64_cpu', '--smt'])
+ if rc or 'on' in out:
+ # SMT has to be disabled for guest to use threads as CPUs.
+ # rc is always zero, whether SMT is off or on.
+ self.guest_threads_enabled = False
+ out, error, rc = run_command(['ppc64_cpu', '--cores-present'])
+ if not rc:
+ self.cores_present = int(out.split()[-1])
+ out, error, rc = run_command(['ppc64_cpu', '--cores-on'])
+ if not rc:
+ self.cores_available = int(out.split()[-1])
+ out, error, rc = run_command(['ppc64_cpu', '--threads-per-core'])
+ if not rc:
+ self.threads_per_core = int(out.split()[-1])
+ self.sockets = self.cores_present/self.threads_per_core
+ if self.sockets == 0:
+ self.sockets = 1
+ self.cores_per_socket = self.cores_present/self.sockets
+ else:
+ # Intel or AMD
+ self.guest_threads_enabled = True
+ self.sockets = int(libvirt_topology.get('sockets'))
+ self.cores_per_socket = int(libvirt_topology.get('cores'))
+ self.cores_present = self.cores_per_socket * self.sockets
+ self.cores_available = self.cores_present
+ self.threads_per_core = int(libvirt_topology.get('threads'))
+
+ def lookup(self, ident):
+ return {
+ 'guest_threads_enabled': self.guest_threads_enabled,
+ 'sockets': self.sockets,
+ 'cores_per_socket': self.cores_per_socket,
+ 'cores_present': self.cores_present,
+ 'cores_available': self.cores_available,
+ 'threads_per_core': self.threads_per_core,
+ }
+
+ def check_topology(self, vcpus, topology):
+ """
+ param vcpus: should be an integer
+ param iso_path: the path of the guest ISO
+ param topology: {'sockets': x, 'cores': x, 'threads': x}
+ """
+ sockets = topology['sockets']
+ cores = topology['cores']
+ threads = topology['threads']
+
+ if not self.guest_threads_enabled:
+ raise InvalidOperation("KCHCPUINF0003E")
+ if vcpus != sockets * cores * threads:
+ raise InvalidParameter("KCHCPUINF0002E")
+ if vcpus > self.cores_available * self.threads_per_core:
+ raise InvalidParameter("KCHCPUINF0001E")
+ if threads > self.threads_per_core:
+ raise InvalidParameter("KCHCPUINF0002E")
diff --git a/src/wok/plugins/kimchi/model/debugreports.py b/src/wok/plugins/kimchi/model/debugreports.py
new file mode 100644
index 0000000..48e6b26
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/debugreports.py
@@ -0,0 +1,213 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import fnmatch
+import glob
+import logging
+import os
+import shutil
+import subprocess
+import time
+
+from wok.exception import InvalidParameter, NotFoundError, OperationFailed
+from wok.exception import WokException
+from wok.utils import add_task, wok_log
+from wok.utils import run_command
+from wok.model.tasks import TaskModel
+
+from .. import config
+
+
+class DebugReportsModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+
+ def create(self, params):
+ ident = params.get('name').strip()
+ # Generate a name with time and millisec precision, if necessary
+ if ident is None or ident == "":
+ ident = 'report-' + str(int(time.time() * 1000))
+ else:
+ if ident in self.get_list():
+ raise InvalidParameter("KCHDR0008E", {"name": ident})
+ taskid = self._gen_debugreport_file(ident)
+ return self.task.lookup(taskid)
+
+ def get_list(self):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, '*.*')
+ file_lists = glob.glob(file_pattern)
+ file_lists = [os.path.split(file)[1] for file in file_lists]
+ name_lists = [file.split('.', 1)[0] for file in file_lists]
+
+ return name_lists
+
+ def _gen_debugreport_file(self, name):
+ gen_cmd = self.get_system_report_tool()
+
+ if gen_cmd is not None:
+ return add_task('/plugins/kimchi/debugreports/%s' % name, gen_cmd,
+ self.objstore, name)
+
+ raise OperationFailed("KCHDR0002E")
+
+ @staticmethod
+ def sosreport_generate(cb, name):
+ def log_error(e):
+ log = logging.getLogger('Model')
+ log.warning('Exception in generating debug file: %s', e)
+
+ try:
+ command = ['sosreport', '--batch', '--name=%s' % name]
+ output, error, retcode = run_command(command)
+
+ if retcode != 0:
+ raise OperationFailed("KCHDR0003E", {'name': name,
+ 'err': retcode})
+
+ # SOSREPORT might create file in /tmp or /var/tmp
+ # FIXME: The right way should be passing the tar.xz file directory
+ # though the parameter '--tmp-dir', but it is failing in Fedora 20
+ patterns = ['/tmp/sosreport-%s-*', '/var/tmp/sosreport-%s-*']
+ reports = []
+ reportFile = None
+ for p in patterns:
+ reports = reports + [f for f in glob.glob(p % name)]
+ for f in reports:
+ if not fnmatch.fnmatch(f, '*.md5'):
+ reportFile = f
+ break
+ # Some error in sosreport happened
+ if reportFile is None:
+ wok_log.error('Debug report file not found. See sosreport '
+ 'output for detail:\n%s', output)
+ fname = (patterns[0] % name).split('/')[-1]
+ raise OperationFailed('KCHDR0004E', {'name': fname})
+
+ md5_report_file = reportFile + '.md5'
+ report_file_extension = '.' + reportFile.split('.', 1)[1]
+ path = config.get_debugreports_path()
+ target = os.path.join(path, name + report_file_extension)
+ # Moving report
+ msg = 'Moving debug report file "%s" to "%s"' % (reportFile,
+ target)
+ wok_log.info(msg)
+ shutil.move(reportFile, target)
+ # Deleting md5
+ msg = 'Deleting report md5 file: "%s"' % (md5_report_file)
+ wok_log.info(msg)
+ with open(md5_report_file) as f:
+ md5 = f.read().strip()
+ wok_log.info('Md5 file content: "%s"', md5)
+ os.remove(md5_report_file)
+ cb('OK', True)
+ return
+
+ except WokException as e:
+ log_error(e)
+ raise
+
+ except OSError as e:
+ log_error(e)
+ raise
+
+ except Exception, e:
+ # No need to call cb to update the task status here.
+ # The task object will catch the exception raised here
+ # and update the task status there
+ log_error(e)
+ raise OperationFailed("KCHDR0005E", {'name': name, 'err': e})
+
+ @staticmethod
+ def get_system_report_tool():
+ # Please add new possible debug report command here
+ # and implement the report generating function
+ # based on the new report command
+ report_tools = ({'cmd': 'sosreport --help',
+ 'fn': DebugReportsModel.sosreport_generate},)
+
+ # check if the command can be found by shell one by one
+ for helper_tool in report_tools:
+ try:
+ retcode = subprocess.call(helper_tool['cmd'], shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ if retcode == 0:
+ return helper_tool['fn']
+ except Exception, e:
+ wok_log.info('Exception running command: %s', e)
+
+ return None
+
+
+class DebugReportModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, name)
+ file_pattern = file_pattern + '.*'
+ try:
+ file_target = glob.glob(file_pattern)[0]
+ except IndexError:
+ raise NotFoundError("KCHDR0001E", {'name': name})
+
+ ctime = os.stat(file_target).st_mtime
+ ctime = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(ctime))
+ file_target = os.path.split(file_target)[-1]
+ file_target = os.path.join("plugins/kimchi/data/debugreports",
+ file_target)
+ return {'uri': file_target,
+ 'ctime': ctime}
+
+ def update(self, name, params):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, name + '.*')
+ try:
+ file_source = glob.glob(file_pattern)[0]
+ except IndexError:
+ raise NotFoundError("KCHDR0001E", {'name': name})
+
+ file_target = file_source.replace(name, params['name'])
+ if os.path.isfile(file_target):
+ raise InvalidParameter('KCHDR0008E', {'name': params['name']})
+
+ shutil.move(file_source, file_target)
+ wok_log.info('%s renamed to %s' % (file_source, file_target))
+ return params['name']
+
+ def delete(self, name):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, name + '.*')
+ try:
+ file_target = glob.glob(file_pattern)[0]
+ except IndexError:
+ raise NotFoundError("KCHDR0001E", {'name': name})
+
+ os.remove(file_target)
+
+
+class DebugReportContentModel(object):
+ def __init__(self, **kargs):
+ self._debugreport = DebugReportModel()
+
+ def lookup(self, name):
+ return self._debugreport.lookup(name)
diff --git a/src/wok/plugins/kimchi/model/diskutils.py b/src/wok/plugins/kimchi/model/diskutils.py
new file mode 100644
index 0000000..350e6eb
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/diskutils.py
@@ -0,0 +1,75 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.exception import OperationFailed, NotFoundError
+from wok.utils import wok_log
+
+from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
+from vms import VMModel, VMsModel
+
+"""
+ Functions that multiple storage-related models (e.g. VMStoragesModel,
+ VolumesModel) will need.
+"""
+
+
+def get_disk_used_by(objstore, conn, path):
+ try:
+ with objstore as session:
+ try:
+ used_by = session.get('storagevolume', path)['used_by']
+ except (KeyError, NotFoundError):
+ wok_log.info('Volume %s not found in obj store.' % path)
+ used_by = []
+ # try to find this volume in existing vm
+ vms_list = VMsModel.get_vms(conn)
+ for vm in vms_list:
+ dom = VMModel.get_vm(vm, conn)
+ storages = get_vm_disks(dom)
+ for disk in storages.keys():
+ d_info = get_vm_disk_info(dom, disk)
+ if path == d_info['path']:
+ used_by.append(vm)
+ try:
+ session.store('storagevolume', path,
+ {'used_by': used_by})
+ except Exception as e:
+ # Let the exception be raised. If we allow disks'
+ # used_by to be out of sync, data corruption could
+ # occour if a disk is added to two guests
+ # unknowingly.
+ wok_log.error('Unable to store storage volume id in'
+ ' objectstore due error: %s',
+ e.message)
+ raise OperationFailed('KCHVOL0017E',
+ {'err': e.message})
+ except Exception as e:
+ # This exception is going to catch errors returned by 'with',
+ # specially ones generated by 'session.store'. It is outside
+ # to avoid conflict with the __exit__ function of 'with'
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
+ return used_by
+
+
+def set_disk_used_by(objstore, path, new_used_by):
+ try:
+ with objstore as session:
+ session.store('storagevolume', path, {'used_by': new_used_by})
+ except Exception as e:
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
diff --git a/src/wok/plugins/kimchi/model/featuretests.py b/src/wok/plugins/kimchi/model/featuretests.py
new file mode 100644
index 0000000..c53d1aa
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/featuretests.py
@@ -0,0 +1,259 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import libvirt
+import lxml.etree as ET
+import platform
+import subprocess
+from lxml.builder import E
+
+from wok.rollbackcontext import RollbackContext
+from wok.utils import run_command, servermethod, wok_log
+
+
+FEATURETEST_VM_NAME = "FEATURETEST_VM"
+FEATURETEST_POOL_NAME = "FEATURETEST_POOL"
+
+ISO_STREAM_XML = """
+<domain type='%(domain)s'>
+ <name>%(name)s</name>
+ <memory unit='KiB'>1048576</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='%(protocol)s' name='/url/path/to/iso/file'>
+ <host name='host.name' port='1234'/>
+ </source>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <alias name='ide0-1-0'/>
+ <address type='drive' controller='0' bus='1' target='0' unit='0'/>
+ </disk>
+ </devices>
+</domain>"""
+
+SIMPLE_VM_XML = """
+<domain type='%(domain)s'>
+ <name>%(name)s</name>
+ <memory unit='KiB'>10240</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+</domain>"""
+
+MAXMEM_VM_XML = """
+<domain type='%(domain)s'>
+ <name>%(name)s</name>
+ <maxMemory slots='1' unit='KiB'>20480</maxMemory>
+ <memory unit='KiB'>10240</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+</domain>"""
+
+DEV_MEM_XML = """
+<memory model='dimm'>
+ <target>
+ <size unit='KiB'>10240</size>
+ <node>0</node>
+ </target>
+</memory>"""
+
+SCSI_FC_XML = """
+<pool type='scsi'>
+ <name>%(name)s</name>
+ <source>
+ <adapter type='fc_host' wwnn='1234567890abcdef' wwpn='abcdef1234567890'/>
+ </source>
+ <target>
+ <path>/dev/disk/by-path</path>
+ </target>
+</pool>
+"""
+
+
+class FeatureTests(object):
+
+ @staticmethod
+ def disable_libvirt_error_logging():
+ def libvirt_errorhandler(userdata, error):
+ # A libvirt error handler to ignore annoying messages in stderr
+ pass
+
+ # Filter functions are enable only in production env
+ if cherrypy.config.get('environment') != 'production':
+ return
+ # Register the error handler to hide libvirt error in stderr
+ libvirt.registerErrorHandler(f=libvirt_errorhandler, ctx=None)
+
+ @staticmethod
+ def enable_libvirt_error_logging():
+ # Filter functions are enable only in production env
+ if cherrypy.config.get('environment') != 'production':
+ return
+ # Unregister the error handler
+ libvirt.registerErrorHandler(f=None, ctx=None)
+
+ @staticmethod
+ def libvirt_supports_iso_stream(conn, protocol):
+ conn_type = conn.getType().lower()
+ domain_type = 'test' if conn_type == 'test' else 'kvm'
+ arch = 'i686' if conn_type == 'test' else platform.machine()
+ arch = 'ppc64' if arch == 'ppc64le' else arch
+ xml = ISO_STREAM_XML % {'name': FEATURETEST_VM_NAME,
+ 'domain': domain_type, 'protocol': protocol,
+ 'arch': arch}
+ try:
+ FeatureTests.disable_libvirt_error_logging()
+ dom = conn.defineXML(xml)
+ dom.undefine()
+ return True
+ except libvirt.libvirtError, e:
+ wok_log.error(e.message)
+ return False
+ finally:
+ FeatureTests.enable_libvirt_error_logging()
+
+ @staticmethod
+ def libvirt_support_nfs_probe(conn):
+ def _get_xml():
+ obj = E.source(E.host(name='localhost'), E.format(type='nfs'))
+ xml = ET.tostring(obj)
+ return xml
+ try:
+ FeatureTests.disable_libvirt_error_logging()
+ conn.findStoragePoolSources('netfs', _get_xml(), 0)
+ except libvirt.libvirtError as e:
+ wok_log.error(e.message)
+ if e.get_error_code() == 38:
+ # if libvirt cannot find showmount,
+ # it returns 38--general system call failure
+ return False
+ finally:
+ FeatureTests.enable_libvirt_error_logging()
+
+ return True
+
+ @staticmethod
+ @servermethod
+ def qemu_supports_iso_stream():
+ host = cherrypy.server.socket_host
+ port = cherrypy.server.socket_port
+ cmd = "qemu-io -r http://%s:%d/images/icon-fedora.png \
+ -c 'read -v 0 512'" % (host, port)
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, shell=True)
+ stdout, stderr = proc.communicate()
+ return len(stderr) == 0
+
+ @staticmethod
+ def libvirt_support_fc_host(conn):
+ try:
+ FeatureTests.disable_libvirt_error_logging()
+ pool = None
+ pool_xml = SCSI_FC_XML % {'name': FEATURETEST_POOL_NAME}
+ pool = conn.storagePoolDefineXML(pool_xml, 0)
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == 27:
+ # Libvirt requires adapter name, not needed when supports to FC
+ return False
+ finally:
+ FeatureTests.enable_libvirt_error_logging()
+ pool is None or pool.undefine()
+ return True
+
+ @staticmethod
+ def has_metadata_support(conn):
+ KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/"
+ KIMCHI_NAMESPACE = "kimchi"
+ with RollbackContext() as rollback:
+ FeatureTests.disable_libvirt_error_logging()
+ rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
+ conn_type = conn.getType().lower()
+ domain_type = 'test' if conn_type == 'test' else 'kvm'
+ arch = 'i686' if conn_type == 'test' else platform.machine()
+ arch = 'ppc64' if arch == 'ppc64le' else arch
+ dom = conn.defineXML(SIMPLE_VM_XML % {'name': FEATURETEST_VM_NAME,
+ 'domain': domain_type,
+ 'arch': arch})
+ rollback.prependDefer(dom.undefine)
+ try:
+ dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
+ "<metatest/>", KIMCHI_NAMESPACE,
+ KIMCHI_META_URL,
+ flags=libvirt.VIR_DOMAIN_AFFECT_CURRENT)
+ return True
+ except libvirt.libvirtError:
+ return False
+
+ @staticmethod
+ def kernel_support_vfio():
+ out, err, rc = run_command(['modprobe', 'vfio-pci'])
+ if rc != 0:
+ wok_log.warning("Unable to load Kernal module vfio-pci.")
+ return False
+ return True
+
+ @staticmethod
+ def is_nm_running():
+ '''Tries to determine whether NetworkManager is running.'''
+
+ out, err, rc = run_command(['nmcli', 'dev', 'status'])
+ if rc != 0:
+ return False
+
+ return True
+
+ @staticmethod
+ def has_mem_hotplug_support(conn):
+ '''
+ A memory device can be hot-plugged or hot-unplugged since libvirt
+ version 1.2.14.
+ '''
+ # Libvirt < 1.2.14 does not support memory devices, so firstly, check
+ # its version, then try to attach a device. These steps avoid errors
+ # with Libvirt 'test' driver for KVM
+ version = 1000000*1 + 1000*2 + 14
+ if libvirt.getVersion() < version:
+ return False
+
+ with RollbackContext() as rollback:
+ FeatureTests.disable_libvirt_error_logging()
+ rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
+ conn_type = conn.getType().lower()
+ domain_type = 'test' if conn_type == 'test' else 'kvm'
+ arch = 'i686' if conn_type == 'test' else platform.machine()
+ arch = 'ppc64' if arch == 'ppc64le' else arch
+ dom = conn.defineXML(MAXMEM_VM_XML % {'name': FEATURETEST_VM_NAME,
+ 'domain': domain_type,
+ 'arch': arch})
+ rollback.prependDefer(dom.undefine)
+ try:
+ dom.attachDeviceFlags(DEV_MEM_XML,
+ libvirt.VIR_DOMAIN_MEM_CONFIG)
+ return True
+ except libvirt.libvirtError:
+ return False
diff --git a/src/wok/plugins/kimchi/model/groups.py b/src/wok/plugins/kimchi/model/groups.py
new file mode 100644
index 0000000..fc63d68
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/groups.py
@@ -0,0 +1,67 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import grp
+
+from wok.config import config
+
+
+class GroupsModel(object):
+ def __init__(self, **args):
+ auth_type = config.get("authentication", "method")
+ for klass in GroupsModel.__subclasses__():
+ if auth_type == klass.auth_type:
+ self.grp = klass(**args)
+
+ def get_list(self, **args):
+ if hasattr(self.grp, '_get_list'):
+ return self.grp._get_list(**args)
+ else:
+ return list()
+
+ def validate(self, gid):
+ return self.grp._validate(gid)
+
+
+class PAMGroupsModel(GroupsModel):
+ auth_type = 'pam'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _get_list(self):
+ return sorted([group.gr_name
+ for group in grp.getgrall()])
+
+ def _validate(self, gid):
+ try:
+ grp.getgrnam(gid)
+ except KeyError:
+ return False
+ return True
+
+
+class LDAPGroupsModel(GroupsModel):
+ auth_type = 'ldap'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _validate(self, gid):
+ return False
diff --git a/src/wok/plugins/kimchi/model/host.py b/src/wok/plugins/kimchi/model/host.py
new file mode 100644
index 0000000..75d4de0
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/host.py
@@ -0,0 +1,476 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import os
+import platform
+import psutil
+import time
+from cherrypy.process.plugins import BackgroundTask
+from collections import defaultdict
+
+from wok.basemodel import Singleton
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import add_task, wok_log
+from wok.xmlutils.utils import xpath_get_text
+from wok.model.tasks import TaskModel
+
+import hostdev
+from .. import disks
+from .. import netinfo
+from ..repositories import Repositories
+from ..swupdate import SoftwareUpdate
+from config import CapabilitiesModel
+from vms import DOM_STATE_MAP
+
+
+HOST_STATS_INTERVAL = 1
+
+
+class HostModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+ self.host_info = self._get_host_info()
+
+ def _get_ppc_cpu_info(self):
+ res = {}
+ with open('/proc/cpuinfo') as f:
+ for line in f.xreadlines():
+ # Parse CPU, CPU's revision and CPU's clock information
+ for key in ['cpu', 'revision', 'clock']:
+ if key in line:
+ info = line.split(':')[1].strip()
+ if key == 'clock':
+ value = float(info.split('MHz')[0].strip()) / 1000
+ else:
+ value = info.split('(')[0].strip()
+ res[key] = value
+
+ # Power machines show, for each cpu/core, a block with
+ # all cpu information. Here we control the scan of the
+ # necessary information (1st block provides
+ # everything), skipping the function when find all
+ # information.
+ if len(res.keys()) == 3:
+ return "%(cpu)s (%(revision)s) @ %(clock)s GHz\
+ " % res
+
+ return ""
+
+ def _get_host_info(self):
+ res = {}
+ if platform.machine().startswith('ppc'):
+ res['cpu_model'] = self._get_ppc_cpu_info()
+ else:
+ with open('/proc/cpuinfo') as f:
+ for line in f.xreadlines():
+ if "model name" in line:
+ res['cpu_model'] = line.split(':')[1].strip()
+ break
+
+ res['cpus'] = 0
+ res['memory'] = 0L
+
+ # Include IBM PowerKVM name to supported distro names
+ _sup_distros = platform._supported_dists + ('ibm_powerkvm',)
+ # 'fedora' '17' 'Beefy Miracle'
+ distro, version, codename = platform.linux_distribution(
+ supported_dists=_sup_distros)
+ res['os_distro'] = distro
+ res['os_version'] = version
+ res['os_codename'] = unicode(codename, "utf-8")
+
+ return res
+
+ def lookup(self, *name):
+ cpus = psutil.NUM_CPUS
+
+ # psutil is unstable on how to get the number of
+ # cpus, different versions call it differently
+ if hasattr(psutil, 'cpu_count'):
+ cpus = psutil.cpu_count()
+
+ elif hasattr(psutil, '_psplatform'):
+ for method_name in ['_get_num_cpus', 'get_num_cpus']:
+
+ method = getattr(psutil._psplatform, method_name, None)
+ if method is not None:
+ cpus = method()
+ break
+
+ self.host_info['cpus'] = cpus
+ self.host_info['memory'] = psutil.phymem_usage().total
+ return self.host_info
+
+ def swupdate(self, *name):
+ try:
+ swupdate = SoftwareUpdate()
+ except:
+ raise OperationFailed('KCHPKGUPD0004E')
+
+ pkgs = swupdate.getNumOfUpdates()
+ if pkgs == 0:
+ raise OperationFailed('KCHPKGUPD0001E')
+
+ wok_log.debug('Host is going to be updated.')
+ taskid = add_task('/plugins/kimchi/host/swupdate', swupdate.doUpdate,
+ self.objstore, None)
+ return self.task.lookup(taskid)
+
+ def shutdown(self, args=None):
+ # Check for running vms before shutdown
+ running_vms = self._get_vms_list_by_state('running')
+ if len(running_vms) > 0:
+ raise OperationFailed("KCHHOST0001E")
+
+ wok_log.info('Host is going to shutdown.')
+ os.system('shutdown -h now')
+
+ def reboot(self, args=None):
+ # Find running VMs
+ running_vms = self._get_vms_list_by_state('running')
+ if len(running_vms) > 0:
+ raise OperationFailed("KCHHOST0002E")
+
+ wok_log.info('Host is going to reboot.')
+ os.system('reboot')
+
+ def _get_vms_list_by_state(self, state):
+ conn = self.conn.get()
+ return [dom.name().decode('utf-8')
+ for dom in conn.listAllDomains(0)
+ if (DOM_STATE_MAP[dom.info()[0]]) == state]
+
+
+class HostStatsModel(object):
+ __metaclass__ = Singleton
+
+ def __init__(self, **kargs):
+ self.host_stats = defaultdict(list)
+ self.host_stats_thread = BackgroundTask(HOST_STATS_INTERVAL,
+ self._update_host_stats)
+ self.host_stats_thread.start()
+
+ def lookup(self, *name):
+ return {'cpu_utilization': self.host_stats['cpu_utilization'][-1],
+ 'memory': self.host_stats['memory'][-1],
+ 'disk_read_rate': self.host_stats['disk_read_rate'][-1],
+ 'disk_write_rate': self.host_stats['disk_write_rate'][-1],
+ 'net_recv_rate': self.host_stats['net_recv_rate'][-1],
+ 'net_sent_rate': self.host_stats['net_sent_rate'][-1]}
+
+ def _update_host_stats(self):
+ preTimeStamp = self.host_stats['timestamp']
+ timestamp = time.time()
+ # FIXME when we upgrade psutil, we can get uptime by psutil.uptime
+ # we get uptime by float(open("/proc/uptime").readline().split()[0])
+ # and calculate the first io_rate after the OS started.
+ with open("/proc/uptime") as time_f:
+ seconds = (timestamp - preTimeStamp if preTimeStamp else
+ float(time_f.readline().split()[0]))
+
+ self.host_stats['timestamp'] = timestamp
+ self._get_host_disk_io_rate(seconds)
+ self._get_host_network_io_rate(seconds)
+
+ self._get_percentage_host_cpu_usage()
+ self._get_host_memory_stats()
+
+ # store only 60 stats (1 min)
+ for key, value in self.host_stats.iteritems():
+ if isinstance(value, list):
+ if len(value) == 60:
+ self.host_stats[key] = value[10:]
+
+ def _get_percentage_host_cpu_usage(self):
+ # This is cpu usage producer. This producer will calculate the usage
+ # at an interval of HOST_STATS_INTERVAL.
+ # The psutil.cpu_percent works as non blocking.
+ # psutil.cpu_percent maintains a cpu time sample.
+ # It will update the cpu time sample when it is called.
+ # So only this producer can call psutil.cpu_percent in kimchi.
+ self.host_stats['cpu_utilization'].append(psutil.cpu_percent(None))
+
+ def _get_host_memory_stats(self):
+ virt_mem = psutil.virtual_memory()
+ # available:
+ # the actual amount of available memory that can be given
+ # instantly to processes that request more memory in bytes; this
+ # is calculated by summing different memory values depending on
+ # the platform (e.g. free + buffers + cached on Linux)
+ memory_stats = {'total': virt_mem.total,
+ 'free': virt_mem.free,
+ 'cached': virt_mem.cached,
+ 'buffers': virt_mem.buffers,
+ 'avail': virt_mem.available}
+ self.host_stats['memory'].append(memory_stats)
+
+ def _get_host_disk_io_rate(self, seconds):
+ disk_read_bytes = self.host_stats['disk_read_bytes']
+ disk_write_bytes = self.host_stats['disk_write_bytes']
+ prev_read_bytes = disk_read_bytes[-1] if disk_read_bytes else 0
+ prev_write_bytes = disk_write_bytes[-1] if disk_write_bytes else 0
+
+ disk_io = psutil.disk_io_counters(False)
+ read_bytes = disk_io.read_bytes
+ write_bytes = disk_io.write_bytes
+
+ rd_rate = int(float(read_bytes - prev_read_bytes) / seconds + 0.5)
+ wr_rate = int(float(write_bytes - prev_write_bytes) / seconds + 0.5)
+
+ self.host_stats['disk_read_rate'].append(rd_rate)
+ self.host_stats['disk_write_rate'].append(wr_rate)
+ self.host_stats['disk_read_bytes'].append(read_bytes)
+ self.host_stats['disk_write_bytes'].append(write_bytes)
+
+ def _get_host_network_io_rate(self, seconds):
+ net_recv_bytes = self.host_stats['net_recv_bytes']
+ net_sent_bytes = self.host_stats['net_sent_bytes']
+ prev_recv_bytes = net_recv_bytes[-1] if net_recv_bytes else 0
+ prev_sent_bytes = net_sent_bytes[-1] if net_sent_bytes else 0
+
+ net_ios = psutil.network_io_counters(True)
+ recv_bytes = 0
+ sent_bytes = 0
+ for key in set(netinfo.nics() +
+ netinfo.wlans()) & set(net_ios.iterkeys()):
+ recv_bytes = recv_bytes + net_ios[key].bytes_recv
+ sent_bytes = sent_bytes + net_ios[key].bytes_sent
+
+ rx_rate = int(float(recv_bytes - prev_recv_bytes) / seconds + 0.5)
+ tx_rate = int(float(sent_bytes - prev_sent_bytes) / seconds + 0.5)
+
+ self.host_stats['net_recv_rate'].append(rx_rate)
+ self.host_stats['net_sent_rate'].append(tx_rate)
+ self.host_stats['net_recv_bytes'].append(recv_bytes)
+ self.host_stats['net_sent_bytes'].append(sent_bytes)
+
+
+class HostStatsHistoryModel(object):
+ def __init__(self, **kargs):
+ self.history = HostStatsModel(**kargs)
+
+ def lookup(self, *name):
+ return {'cpu_utilization': self.history.host_stats['cpu_utilization'],
+ 'memory': self.history.host_stats['memory'],
+ 'disk_read_rate': self.history.host_stats['disk_read_rate'],
+ 'disk_write_rate': self.history.host_stats['disk_write_rate'],
+ 'net_recv_rate': self.history.host_stats['net_recv_rate'],
+ 'net_sent_rate': self.history.host_stats['net_sent_rate']}
+
+
+class PartitionsModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def get_list(self):
+ result = disks.get_partitions_names()
+ return result
+
+
+class PartitionModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ return disks.get_partition_details(name)
+
+
+class DevicesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+ self.cap_map = \
+ {'net': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET,
+ 'pci': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV,
+ 'scsi': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI,
+ 'scsi_host': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST,
+ 'storage': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE,
+ 'usb_device': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV,
+ 'usb':
+ libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE}
+ # TODO: when no longer supporting Libvirt < 1.0.5 distros
+ # (like RHEL6) remove this verification and insert the
+ # key 'fc_host' with the libvirt variable in the hash
+ # declaration above.
+ try:
+ self.cap_map['fc_host'] = \
+ libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
+ except AttributeError:
+ self.cap_map['fc_host'] = None
+
+ def get_list(self, _cap=None, _passthrough=None,
+ _passthrough_affected_by=None):
+ if _passthrough_affected_by is not None:
+ # _passthrough_affected_by conflicts with _cap and _passthrough
+ if (_cap, _passthrough) != (None, None):
+ raise InvalidParameter("KCHHOST0004E")
+ return sorted(
+ self._get_passthrough_affected_devs(_passthrough_affected_by))
+
+ if _cap == 'fc_host':
+ dev_names = self._get_devices_fc_host()
+ else:
+ dev_names = self._get_devices_with_capability(_cap)
+
+ if _passthrough is not None and _passthrough.lower() == 'true':
+ conn = self.conn.get()
+ passthrough_names = [
+ dev['name'] for dev in hostdev.get_passthrough_dev_infos(conn)]
+ dev_names = list(set(dev_names) & set(passthrough_names))
+
+ dev_names.sort()
+ return dev_names
+
+ def _get_devices_with_capability(self, cap):
+ conn = self.conn.get()
+ if cap is None:
+ cap_flag = 0
+ else:
+ cap_flag = self.cap_map.get(cap)
+ if cap_flag is None:
+ return []
+ return [name.name() for name in conn.listAllDevices(cap_flag)]
+
+ def _get_passthrough_affected_devs(self, dev_name):
+ conn = self.conn.get()
+ info = DeviceModel(conn=self.conn).lookup(dev_name)
+ affected = hostdev.get_affected_passthrough_devices(conn, info)
+ return [dev_info['name'] for dev_info in affected]
+
+ def _get_devices_fc_host(self):
+ conn = self.conn.get()
+ # Libvirt < 1.0.5 does not support fc_host capability
+ if not self.caps.fc_host_support:
+ ret = []
+ scsi_hosts = self._get_devices_with_capability('scsi_host')
+ for host in scsi_hosts:
+ xml = conn.nodeDeviceLookupByName(host).XMLDesc(0)
+ path = '/device/capability/capability/@type'
+ if 'fc_host' in xpath_get_text(xml, path):
+ ret.append(host)
+ return ret
+ # Double verification to catch the case where the libvirt
+ # supports fc_host but does not, for some reason, recognize
+ # the libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
+ # attribute.
+ if not self.cap_map['fc_host']:
+ return conn.listDevices('fc_host', 0)
+ return self._get_devices_with_capability('fc_host')
+
+
+class DeviceModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def lookup(self, nodedev_name):
+ conn = self.conn.get()
+ try:
+ dev = conn.nodeDeviceLookupByName(nodedev_name)
+ except:
+ raise NotFoundError('KCHHOST0003E', {'name': nodedev_name})
+ return hostdev.get_dev_info(dev)
+
+
+class PackagesUpdateModel(object):
+ def __init__(self, **kargs):
+ try:
+ self.host_swupdate = SoftwareUpdate()
+ except:
+ self.host_swupdate = None
+
+ def get_list(self):
+ if self.host_swupdate is None:
+ raise OperationFailed('KCHPKGUPD0004E')
+
+ return self.host_swupdate.getUpdates()
+
+
+class PackageUpdateModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ try:
+ swupdate = SoftwareUpdate()
+ except Exception:
+ raise OperationFailed('KCHPKGUPD0004E')
+
+ return swupdate.getUpdate(name)
+
+
+class RepositoriesModel(object):
+ def __init__(self, **kargs):
+ try:
+ self.host_repositories = Repositories()
+ except:
+ self.host_repositories = None
+
+ def get_list(self):
+ if self.host_repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return sorted(self.host_repositories.getRepositories())
+
+ def create(self, params):
+ if self.host_repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self.host_repositories.addRepository(params)
+
+
+class RepositoryModel(object):
+ def __init__(self, **kargs):
+ try:
+ self._repositories = Repositories()
+ except:
+ self._repositories = None
+
+ def lookup(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.getRepository(repo_id)
+
+ def enable(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.enableRepository(repo_id)
+
+ def disable(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.disableRepository(repo_id)
+
+ def update(self, repo_id, params):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.updateRepository(repo_id, params)
+
+ def delete(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.removeRepository(repo_id)
diff --git a/src/wok/plugins/kimchi/model/hostdev.py b/src/wok/plugins/kimchi/model/hostdev.py
new file mode 100644
index 0000000..31211c7
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/hostdev.py
@@ -0,0 +1,324 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+from pprint import pformat
+from pprint import pprint
+
+from wok.utils import wok_log
+from wok.xmlutils.utils import dictize
+
+from libvirtconnection import LibvirtConnection
+
+
+def _get_all_host_dev_infos(libvirt_conn):
+ node_devs = libvirt_conn.listAllDevices(0)
+ return [get_dev_info(node_dev) for node_dev in node_devs]
+
+
+def _get_dev_info_tree(dev_infos):
+ devs = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
+ root = None
+ for dev_info in dev_infos:
+ if dev_info['parent'] is None:
+ root = dev_info
+ continue
+
+ try:
+ parent = devs[dev_info['parent']]
+ except KeyError:
+ wok_log.error('Parent %s of device %s does not exist.',
+ dev_info['parent'], dev_info['name'])
+ continue
+
+ try:
+ children = parent['children']
+ except KeyError:
+ parent['children'] = [dev_info]
+ else:
+ children.append(dev_info)
+ return root
+
+
+def _is_pci_qualified(pci_dev):
+ # PCI bridge is not suitable to passthrough
+ # KVM does not support passthrough graphic card now
+ blacklist_classes = (0x030000, 0x060000)
+
+ with open(os.path.join(pci_dev['path'], 'class')) as f:
+ pci_class = int(f.readline().strip(), 16)
+
+ if pci_class & 0xff0000 in blacklist_classes:
+ return False
+
+ return True
+
+
+def get_passthrough_dev_infos(libvirt_conn):
+ ''' Get devices eligible to be passed through to VM. '''
+
+ def is_eligible(dev):
+ return dev['device_type'] in ('usb_device', 'scsi') or \
+ (dev['device_type'] == 'pci' and _is_pci_qualified(dev))
+
+ dev_infos = _get_all_host_dev_infos(libvirt_conn)
+
+ return [dev_info for dev_info in dev_infos if is_eligible(dev_info)]
+
+
+def _get_same_iommugroup_devices(dev_infos, device_info):
+ dev_dict = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
+
+ def get_iommu_group(dev_info):
+ # Find out the iommu group of a given device.
+ # Child device belongs to the same iommu group as the parent device.
+ try:
+ return dev_info['iommuGroup']
+ except KeyError:
+ pass
+
+ parent = dev_info['parent']
+ while parent is not None:
+ try:
+ parent_info = dev_dict[parent]
+ except KeyError:
+ wok_log.error("Parent %s of device %s does not exist",
+ parent, dev_info['name'])
+ break
+
+ try:
+ iommuGroup = parent_info['iommuGroup']
+ except KeyError:
+ pass
+ else:
+ return iommuGroup
+
+ parent = parent_info['parent']
+
+ return None
+
+ iommu_group = get_iommu_group(device_info)
+
+ if iommu_group is None:
+ return []
+
+ return [dev_info for dev_info in dev_infos
+ if dev_info['name'] != device_info['name'] and
+ get_iommu_group(dev_info) == iommu_group]
+
+
+def _get_children_devices(dev_infos, device_info):
+ def get_children_recursive(parent):
+ try:
+ children = parent['children']
+ except KeyError:
+ return []
+
+ result = []
+ for child in children:
+ result.append(child)
+ result.extend(get_children_recursive(child))
+
+ return result
+
+ # Annotate every the dev_info element with children information
+ _get_dev_info_tree(dev_infos)
+
+ for dev_info in dev_infos:
+ if dev_info['name'] == device_info['name']:
+ return get_children_recursive(dev_info)
+
+ return []
+
+
+def get_affected_passthrough_devices(libvirt_conn, passthrough_dev):
+ dev_infos = _get_all_host_dev_infos(libvirt_conn)
+
+ group_devices = _get_same_iommugroup_devices(dev_infos, passthrough_dev)
+ if not group_devices:
+ # On host without iommu group support, the affected devices should
+ # at least include all children devices
+ group_devices.extend(_get_children_devices(dev_infos, passthrough_dev))
+
+ return group_devices
+
+
+def get_dev_info(node_dev):
+ ''' Parse the node device XML string into dict according to
+ http://libvirt.org/formatnode.html.
+
+ scsi_generic is not documented in libvirt official website. Try to
+ parse scsi_generic according to the following libvirt path series.
+ https://www.redhat.com/archives/libvir-list/2013-June/msg00014.html
+
+ scsi_target is not documented in libvirt official website. Try to
+ parse scsi_target according to the libvirt commit db19834a0a.
+ '''
+
+ xmlstr = node_dev.XMLDesc(0)
+ info = dictize(xmlstr)['device']
+ dev_type = info['capability'].pop('type')
+ info['device_type'] = dev_type
+ cap_dict = info.pop('capability')
+ info.update(cap_dict)
+ info['parent'] = node_dev.parent()
+
+ if dev_type in ('scsi', 'scsi_generic', 'scsi_target', 'system', 'usb'):
+ return info
+
+ if dev_type in ('net', 'pci', 'scsi_host', 'storage', 'usb_device'):
+ return globals()['_get_%s_dev_info' % dev_type](info)
+
+ wok_log.error("Unknown device type: %s", dev_type)
+ return info
+
+
+def _get_net_dev_info(info):
+ cap = info.pop('capability')
+ links = {"80203": "IEEE 802.3", "80211": "IEEE 802.11"}
+ link_raw = cap['type']
+ info['link_type'] = links.get(link_raw, link_raw)
+
+ return info
+
+
+def _get_pci_dev_info(info):
+ for k in ('vendor', 'product'):
+ try:
+ description = info[k].pop('pyval')
+ except KeyError:
+ description = None
+ info[k]['description'] = description
+ if 'path' not in info:
+ # Old libvirt does not provide syspath info
+ info['path'] = \
+ "/sys/bus/pci/devices/" \
+ "%(domain)04x:%(bus)02x:%(slot)02x.%(function)01x" % {
+ 'domain': info['domain'], 'bus': info['bus'],
+ 'slot': info['slot'], 'function': info['function']}
+ try:
+ info['iommuGroup'] = int(info['iommuGroup']['number'])
+ except KeyError:
+ # Old libvirt does not provide syspath info, figure it out ourselves
+ iommu_link = os.path.join(info['path'], 'iommu_group')
+ if os.path.exists(iommu_link):
+ iommu_path = os.path.realpath(iommu_link)
+ try:
+ info['iommuGroup'] = int(iommu_path.rsplit('/', 1)[1])
+ except (ValueError, IndexError):
+ # No IOMMU group support at all.
+ pass
+ else:
+ # No IOMMU group support at all.
+ pass
+ return info
+
+
+def _get_scsi_host_dev_info(info):
+ try:
+ cap_info = info.pop('capability')
+ except KeyError:
+ # kimchi.model.libvirtstoragepool.ScsiPoolDef assumes
+ # info['adapter']['type'] always exists.
+ info['adapter'] = {'type': ''}
+ return info
+ if isinstance(cap_info, list):
+ info['adapter'] = {}
+ for cap in cap_info:
+ if cap['type'] == 'vport_ops':
+ del cap['type']
+ info['adapter']['vport_ops'] = cap
+ else:
+ info['adapter'].update(cap)
+ else:
+ info['adapter'] = cap_info
+ return info
+
+
+def _get_storage_dev_info(info):
+ try:
+ cap_info = info.pop('capability')
+ except KeyError:
+ return info
+
+ if cap_info['type'] == 'removable':
+ cap_info['available'] = bool(cap_info.pop('media_available'))
+ if cap_info['available']:
+ for k in ('size', 'label'):
+ try:
+ cap_info[k] = cap_info.pop('media_' + k)
+ except KeyError:
+ cap_info[k] = None
+ info['media'] = cap_info
+ return info
+
+
+def _get_usb_device_dev_info(info):
+ for k in ('vendor', 'product'):
+ try:
+ info[k]['description'] = info[k].pop('pyval')
+ except KeyError:
+ # Some USB devices don't provide vendor/product description.
+ pass
+ return info
+
+
+# For test and debug
+def _print_host_dev_tree(libvirt_conn):
+ dev_infos = _get_all_host_dev_infos(libvirt_conn)
+ root = _get_dev_info_tree(dev_infos)
+ if root is None:
+ print "No device found"
+ return
+ print '-----------------'
+ print '\n'.join(_format_dev_node(root))
+
+
+def _format_dev_node(node):
+ try:
+ children = node['children']
+ del node['children']
+ except KeyError:
+ children = []
+
+ lines = []
+ lines.extend([' ~' + line for line in pformat(node).split('\n')])
+
+ count = len(children)
+ for i, child in enumerate(children):
+ if count == 1:
+ lines.append(' \-----------------')
+ else:
+ lines.append(' +-----------------')
+ clines = _format_dev_node(child)
+ if i == count - 1:
+ p = ' '
+ else:
+ p = ' |'
+ lines.extend([p + cline for cline in clines])
+ lines.append('')
+
+ return lines
+
+
+if __name__ == '__main__':
+ libvirt_conn = LibvirtConnection('qemu:///system').get()
+ _print_host_dev_tree(libvirt_conn)
+ print 'Eligible passthrough devices:'
+ pprint(get_passthrough_dev_infos(libvirt_conn))
diff --git a/src/wok/plugins/kimchi/model/interfaces.py b/src/wok/plugins/kimchi/model/interfaces.py
new file mode 100644
index 0000000..149afe3
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/interfaces.py
@@ -0,0 +1,44 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.exception import NotFoundError
+
+from .. import netinfo
+from networks import NetworksModel
+
+
+class InterfacesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.networks = NetworksModel(**kargs)
+
+ def get_list(self):
+ return list(set(netinfo.all_favored_interfaces()) -
+ set(self.networks.get_all_networks_interfaces()))
+
+
+class InterfaceModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ try:
+ return netinfo.get_interface_info(name)
+ except ValueError:
+ raise NotFoundError("KCHIFACE0001E", {'name': name})
diff --git a/src/wok/plugins/kimchi/model/libvirtconnection.py b/src/wok/plugins/kimchi/model/libvirtconnection.py
new file mode 100644
index 0000000..73f3dcf
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/libvirtconnection.py
@@ -0,0 +1,136 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import libvirt
+import threading
+import time
+
+from wok.utils import wok_log
+
+
+class LibvirtConnection(object):
+ _connections = {}
+ _connectionLock = threading.Lock()
+
+ def __init__(self, uri):
+ self.uri = uri
+ if self.uri not in LibvirtConnection._connections:
+ LibvirtConnection._connections[self.uri] = {}
+ self._connections = LibvirtConnection._connections[self.uri]
+ self.wrappables = self.get_wrappable_objects()
+
+ def get_wrappable_objects(self):
+ """
+ When a wrapped function returns an instance of another libvirt object,
+ we also want to wrap that object so we can catch errors that happen
+ when calling its methods.
+ """
+ objs = []
+ for name in ('virDomain', 'virDomainSnapshot', 'virInterface',
+ 'virNWFilter', 'virNetwork', 'virNodeDevice', 'virSecret',
+ 'virStoragePool', 'virStorageVol', 'virStream'):
+ try:
+ attr = getattr(libvirt, name)
+ except AttributeError:
+ pass
+ objs.append(attr)
+ return tuple(objs)
+
+ def get(self, conn_id=0):
+ """
+ Return current connection to libvirt or open a new one. Wrap all
+ callable libvirt methods so we can catch connection errors and handle
+ them by restarting the server.
+ """
+ def wrapMethod(f):
+ def wrapper(*args, **kwargs):
+ try:
+ ret = f(*args, **kwargs)
+ return ret
+ except libvirt.libvirtError as e:
+ edom = e.get_error_domain()
+ ecode = e.get_error_code()
+ EDOMAINS = (libvirt.VIR_FROM_REMOTE,
+ libvirt.VIR_FROM_RPC)
+ ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
+ libvirt.VIR_ERR_INTERNAL_ERROR,
+ libvirt.VIR_ERR_NO_CONNECT,
+ libvirt.VIR_ERR_INVALID_CONN)
+ if edom in EDOMAINS and ecode in ECODES:
+ wok_log.error('Connection to libvirt broken. '
+ 'Recycling. ecode: %d edom: %d' %
+ (ecode, edom))
+ with LibvirtConnection._connectionLock:
+ self._connections[conn_id] = None
+ raise
+ wrapper.__name__ = f.__name__
+ wrapper.__doc__ = f.__doc__
+ return wrapper
+
+ with LibvirtConnection._connectionLock:
+ conn = self._connections.get(conn_id)
+ if not conn:
+ retries = 5
+ while True:
+ retries = retries - 1
+ try:
+ conn = libvirt.open(self.uri)
+ break
+ except libvirt.libvirtError:
+ wok_log.error('Unable to connect to libvirt.')
+ if not retries:
+ wok_log.error("Unable to establish connection "
+ "with libvirt. Please check "
+ "your libvirt URI which is often "
+ "defined in "
+ "/etc/libvirt/libvirt.conf")
+ cherrypy.engine.stop()
+ exit(1)
+ time.sleep(2)
+
+ for name in dir(libvirt.virConnect):
+ method = getattr(conn, name)
+ if callable(method) and not name.startswith('_'):
+ setattr(conn, name, wrapMethod(method))
+
+ for cls in self.wrappables:
+ for name in dir(cls):
+ method = getattr(cls, name)
+ if callable(method) and not name.startswith('_'):
+ setattr(cls, name, wrapMethod(method))
+
+ self._connections[conn_id] = conn
+ # In case we're running into troubles with keeping the
+ # connections alive we should place here:
+ # conn.setKeepAlive(interval=5, count=3)
+ # However the values need to be considered wisely to not affect
+ # hosts which are hosting a lot of virtual machines
+ return conn
+
+ def isQemuURI(self):
+ """
+ This method will return True or Value when the system libvirt
+ URI is a qemu based URI. For example:
+ qemu:///system or qemu+tcp://someipaddress/system
+ """
+ if self.get().getURI().startswith('qemu'):
+ return True
+ else:
+ return False
diff --git a/src/wok/plugins/kimchi/model/libvirtstoragepool.py b/src/wok/plugins/kimchi/model/libvirtstoragepool.py
new file mode 100644
index 0000000..b22856b
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/libvirtstoragepool.py
@@ -0,0 +1,264 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import os
+import tempfile
+from lxml.builder import E
+
+from wok.exception import InvalidParameter, OperationFailed, TimeoutExpired
+from wok.rollbackcontext import RollbackContext
+from wok.utils import parse_cmd_output, run_command, wok_log
+
+from ..iscsi import TargetClient
+
+
+class StoragePoolDef(object):
+ @classmethod
+ def create(cls, poolArgs):
+ for klass in cls.__subclasses__():
+ if poolArgs['type'] == klass.poolType:
+ return klass(poolArgs)
+ raise OperationFailed("KCHPOOL0014E", {'type': poolArgs['type']})
+
+ def __init__(self, poolArgs):
+ self.poolArgs = poolArgs
+
+ def prepare(self, conn):
+ ''' Validate pool arguments and perform preparations. Operation which
+ would cause side effect should be put here. Subclasses can optionally
+ override this method, or it always succeeds by default. '''
+ pass
+
+ @property
+ def xml(self):
+ ''' Subclasses have to override this method to actually generate the
+ storage pool XML definition. Should cause no side effect and be
+ idempotent'''
+ # TODO: When add new pool type, should also add the related test in
+ # tests/test_storagepool.py
+ raise OperationFailed("KCHPOOL0015E", {'pool': self})
+
+
+class DirPoolDef(StoragePoolDef):
+ poolType = 'dir'
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # path:
+ pool = E.pool(type='dir')
+ pool.append(E.name(self.poolArgs['name']))
+ pool.append(E.target(E.path(self.poolArgs['path'])))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class NetfsPoolDef(StoragePoolDef):
+ poolType = 'netfs'
+
+ def __init__(self, poolArgs):
+ super(NetfsPoolDef, self).__init__(poolArgs)
+ self.path = '/var/lib/kimchi/nfs_mount/' + self.poolArgs['name']
+
+ def prepare(self, conn):
+ mnt_point = tempfile.mkdtemp(dir='/tmp')
+ export_path = "%s:%s" % (
+ self.poolArgs['source']['host'], self.poolArgs['source']['path'])
+ mount_cmd = ["mount", "-o", 'soft,timeo=100,retrans=3,retry=0',
+ export_path, mnt_point]
+ umount_cmd = ["umount", "-f", export_path]
+ mounted = False
+ # Due to an NFS bug (See Red Hat BZ 1023059), NFSv4 exports may take
+ # 10-15 seconds to mount the first time.
+ cmd_timeout = 15
+
+ with RollbackContext() as rollback:
+ rollback.prependDefer(os.rmdir, mnt_point)
+ try:
+ run_command(mount_cmd, cmd_timeout)
+ rollback.prependDefer(run_command, umount_cmd, cmd_timeout)
+ except TimeoutExpired:
+ raise InvalidParameter("KCHPOOL0012E", {'path': export_path})
+ with open("/proc/mounts", "rb") as f:
+ rawMounts = f.read()
+ output_items = ['dev_path', 'mnt_point', 'type']
+ mounts = parse_cmd_output(rawMounts, output_items)
+ for item in mounts:
+ if 'dev_path' in item and item['dev_path'] == export_path:
+ mounted = True
+
+ if not mounted:
+ raise InvalidParameter("KCHPOOL0013E", {'path': export_path})
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # source[host]:
+ # source[path]:
+ pool = E.pool(type='netfs')
+ pool.append(E.name(self.poolArgs['name']))
+
+ source = E.source()
+ source.append(E.host(name=self.poolArgs['source']['host']))
+ source.append(E.dir(path=self.poolArgs['source']['path']))
+
+ pool.append(source)
+ pool.append(E.target(E.path(self.path)))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class LogicalPoolDef(StoragePoolDef):
+ poolType = 'logical'
+
+ def __init__(self, poolArgs):
+ super(LogicalPoolDef, self).__init__(poolArgs)
+ self.path = '/dev/' + self.poolArgs['name']
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # source[devices]:
+ pool = E.pool(type='logical')
+ pool.append(E.name(self.poolArgs['name']))
+
+ source = E.source()
+ for device_path in self.poolArgs['source']['devices']:
+ source.append(E.device(path=device_path))
+
+ pool.append(source)
+ pool.append(E.target(E.path(self.path)))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class ScsiPoolDef(StoragePoolDef):
+ poolType = 'scsi'
+
+ def prepare(self, conn=None):
+ tmp_name = self.poolArgs['source']['name']
+ self.poolArgs['source']['name'] = tmp_name.replace('scsi_', '')
+ # fc_host adapters type are only available in libvirt >= 1.0.5
+ if not self.poolArgs['fc_host_support']:
+ self.poolArgs['source']['adapter']['type'] = 'scsi_host'
+ msg = "Libvirt version <= 1.0.5. Setting SCSI host name as '%s'; "\
+ "setting SCSI adapter type as 'scsi_host'; "\
+ "ignoring wwnn and wwpn." % tmp_name
+ wok_log.info(msg)
+ # Path for Fibre Channel scsi hosts
+ self.poolArgs['path'] = '/dev/disk/by-path'
+ if not self.poolArgs['source']['adapter']['type']:
+ self.poolArgs['source']['adapter']['type'] = 'scsi_host'
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # source[adapter][type]:
+ # source[name]:
+ # source[adapter][wwnn]:
+ # source[adapter][wwpn]:
+ # path:
+ pool = E.pool(type='scsi')
+ pool.append(E.name(self.poolArgs['name']))
+
+ adapter = E.adapter(type=self.poolArgs['source']['adapter']['type'])
+ adapter.set('name', self.poolArgs['source']['name'])
+ adapter.set('wwnn', self.poolArgs['source']['adapter']['wwnn'])
+ adapter.set('wwpn', self.poolArgs['source']['adapter']['wwpn'])
+
+ pool.append(E.source(adapter))
+ pool.append(E.target(E.path(self.poolArgs['path'])))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class IscsiPoolDef(StoragePoolDef):
+ poolType = 'iscsi'
+
+ def prepare(self, conn):
+ source = self.poolArgs['source']
+ if not TargetClient(**source).validate():
+ msg_args = {'host': source['host'], 'target': source['target']}
+ raise OperationFailed("KCHISCSI0002E", msg_args)
+ self._prepare_auth(conn)
+
+ def _prepare_auth(self, conn):
+ try:
+ auth = self.poolArgs['source']['auth']
+ except KeyError:
+ return
+
+ try:
+ virSecret = conn.secretLookupByUsage(
+ libvirt.VIR_SECRET_USAGE_TYPE_ISCSI, self.poolArgs['name'])
+ except libvirt.libvirtError:
+ secret = E.secret(ephemeral='no', private='yes')
+
+ description = E.description('Secret for iSCSI storage pool %s' %
+ self.poolArgs['name'])
+ secret.append(description)
+ secret.append(E.auth(type='chap', username=auth['username']))
+
+ usage = E.usage(type='iscsi')
+ usage.append(E.target(self.poolArgs['name']))
+ secret.append(usage)
+ virSecret = conn.secretDefineXML(ET.tostring(secret))
+
+ virSecret.setValue(auth['password'])
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # source[host]:
+ # source[target]:
+ #
+ # Optional parameters
+ # source[port]:
+ pool = E.pool(type='iscsi')
+ pool.append(E.name(self.poolArgs['name']))
+
+ host = E.host(name=self.poolArgs['source']['host'])
+ port = self.poolArgs['source'].get('port')
+ if port is not None:
+ host.set('port', str(port))
+
+ source = E.source(host)
+ source.append(E.device(path=self.poolArgs['source']['target']))
+
+ source_auth = self.poolArgs['source'].get('auth')
+ if source_auth is not None:
+ auth = E.auth(type='chap')
+ auth.set('username', source_auth['username'])
+
+ secret = E.secret(type='iscsi')
+ secret.set('usage', self.poolArgs['name'])
+ auth.append(secret)
+
+ source.append(auth)
+
+ pool.append(source)
+ pool.append(E.target(E.path('/dev/disk/by-id')))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
diff --git a/src/wok/plugins/kimchi/model/model.py b/src/wok/plugins/kimchi/model/model.py
new file mode 100644
index 0000000..0c94f63
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/model.py
@@ -0,0 +1,52 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import inspect
+import os
+
+from wok.basemodel import BaseModel
+from wok.objectstore import ObjectStore
+from wok.utils import import_module, listPathModules
+
+from libvirtconnection import LibvirtConnection
+
+
+class Model(BaseModel):
+ def __init__(self, libvirt_uri=None, objstore_loc=None):
+
+ self.objstore = ObjectStore(objstore_loc)
+ self.conn = LibvirtConnection(libvirt_uri)
+ kargs = {'objstore': self.objstore, 'conn': self.conn}
+
+ this = os.path.basename(__file__)
+ this_mod = os.path.splitext(this)[0]
+
+ models = []
+ for mod_name in listPathModules(os.path.dirname(__file__)):
+ if mod_name.startswith("_") or mod_name == this_mod:
+ continue
+
+ module = import_module('plugins.kimchi.model.' + mod_name)
+ members = inspect.getmembers(module, inspect.isclass)
+ for cls_name, instance in members:
+ if inspect.getmodule(instance) == module:
+ if cls_name.endswith('Model'):
+ models.append(instance(**kargs))
+
+ return super(Model, self).__init__(models)
diff --git a/src/wok/plugins/kimchi/model/networks.py b/src/wok/plugins/kimchi/model/networks.py
new file mode 100644
index 0000000..b579865
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/networks.py
@@ -0,0 +1,382 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ipaddr
+import libvirt
+import sys
+import time
+from xml.sax.saxutils import escape
+
+from wok.config import PluginPaths
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import MissingParameter, NotFoundError, OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import run_command, wok_log
+from wok.xmlutils.utils import xpath_get_text
+
+from .. import netinfo
+from .. import network as knetwork
+from ..osinfo import defaults as tmpl_defaults
+from ..xmlutils.network import create_vlan_tagged_bridge_xml
+from ..xmlutils.network import to_network_xml
+
+
+KIMCHI_BRIDGE_PREFIX = 'kb'
+
+
+class NetworksModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ if self.conn.isQemuURI():
+ self._check_default_networks()
+
+ def _check_default_networks(self):
+ networks = list(set(tmpl_defaults['networks']))
+ conn = self.conn.get()
+
+ error_msg = ("Please, check the configuration in %s/template.conf to "
+ "ensure it lists only valid networks." %
+ PluginPaths('kimchi').conf_dir)
+
+ for net_name in networks:
+ try:
+ net = conn.networkLookupByName(net_name)
+ except libvirt.libvirtError, e:
+ msg = "Fatal: Unable to find network %s."
+ wok_log.error(msg, net_name)
+ wok_log.error(error_msg)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ if net.isActive() == 0:
+ try:
+ net.create()
+ except libvirt.libvirtError as e:
+ msg = "Fatal: Unable to activate network %s."
+ wok_log.error(msg, net_name)
+ wok_log.error(error_msg)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ def create(self, params):
+ conn = self.conn.get()
+ name = params['name']
+ if name in self.get_list():
+ raise InvalidOperation("KCHNET0001E", {'name': name})
+
+ connection = params["connection"]
+ # set forward mode, isolated do not need forward
+ if connection != 'isolated':
+ params['forward'] = {'mode': connection}
+
+ # set subnet, bridge network do not need subnet
+ if connection in ["nat", 'isolated']:
+ self._set_network_subnet(params)
+
+ # only bridge network need bridge(linux bridge) or interface(macvtap)
+ if connection == 'bridge':
+ self._set_network_bridge(params)
+
+ params['name'] = escape(params['name'])
+ xml = to_network_xml(**params)
+
+ try:
+ network = conn.networkDefineXML(xml.encode("utf-8"))
+ network.setAutostart(True)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHNET0008E",
+ {'name': name, 'err': e.get_error_message()})
+
+ return name
+
+ def get_list(self):
+ conn = self.conn.get()
+ names = conn.listNetworks() + conn.listDefinedNetworks()
+ return sorted(map(lambda x: x.decode('utf-8'), names))
+
+ def _get_available_address(self, addr_pools=[]):
+ invalid_addrs = []
+ for net_name in self.get_list():
+ network = NetworkModel.get_network(self.conn.get(), net_name)
+ xml = network.XMLDesc(0)
+ subnet = NetworkModel.get_network_from_xml(xml)['subnet']
+ subnet and invalid_addrs.append(ipaddr.IPNetwork(subnet))
+ addr_pools = addr_pools if addr_pools else knetwork.PrivateNets
+ return knetwork.get_one_free_network(invalid_addrs, addr_pools)
+
+ def _set_network_subnet(self, params):
+ netaddr = params.get('subnet', '')
+ # lookup a free network address for nat and isolated automatically
+ if not netaddr:
+ netaddr = self._get_available_address()
+ if not netaddr:
+ raise OperationFailed("KCHNET0009E", {'name': params['name']})
+
+ try:
+ ip = ipaddr.IPNetwork(netaddr)
+ except ValueError:
+ raise InvalidParameter("KCHNET0003E", {'subent': netaddr,
+ 'network': params['name']})
+
+ if ip.ip == ip.network:
+ ip.ip = ip.ip + 1
+
+ dhcp_start = str(ip.ip + ip.numhosts / 2)
+ dhcp_end = str(ip.ip + ip.numhosts - 2)
+ params.update({'net': str(ip),
+ 'dhcp': {'range': {'start': dhcp_start,
+ 'end': dhcp_end}}})
+
+ def _ensure_iface_up(self, iface):
+ if netinfo.operstate(iface) != 'up':
+ _, err, rc = run_command(['ip', 'link', 'set', 'dev', iface, 'up'])
+ if rc != 0:
+ raise OperationFailed("KCHNET0020E",
+ {'iface': iface, 'err': err})
+ # Add a delay to wait for the link change takes into effect.
+ for i in range(10):
+ time.sleep(1)
+ if netinfo.operstate(iface) == 'up':
+ break
+ else:
+ raise OperationFailed("KCHNET0021E", {'iface': iface})
+
+ def _set_network_bridge(self, params):
+ try:
+ iface = params['interface']
+ if iface in self.get_all_networks_interfaces():
+ msg_args = {'iface': iface, 'network': params['name']}
+ raise InvalidParameter("KCHNET0006E", msg_args)
+ except KeyError:
+ raise MissingParameter("KCHNET0004E", {'name': params['name']})
+
+ self._ensure_iface_up(iface)
+ if netinfo.is_bridge(iface):
+ if 'vlan_id' in params:
+ raise InvalidParameter('KCHNET0019E', {'name': iface})
+ params['bridge'] = iface
+ elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
+ if params.get('vlan_id') is None:
+ params['forward']['dev'] = iface
+ else:
+ params['bridge'] = \
+ self._create_vlan_tagged_bridge(str(iface),
+ str(params['vlan_id']))
+ else:
+ raise InvalidParameter("KCHNET0007E")
+
+ def get_all_networks_interfaces(self):
+ net_names = self.get_list()
+ interfaces = []
+ for name in net_names:
+ conn = self.conn.get()
+ network = conn.networkLookupByName(name.encode("utf-8"))
+ xml = network.XMLDesc(0)
+ net_dict = NetworkModel.get_network_from_xml(xml)
+ forward = net_dict['forward']
+ (forward['mode'] == 'bridge' and forward['interface'] and
+ interfaces.append(forward['interface'][0]) is None or
+ interfaces.extend(forward['interface'] + forward['pf']))
+ net_dict['bridge'] and interfaces.append(net_dict['bridge'])
+ return interfaces
+
+ def _create_vlan_tagged_bridge(self, interface, vlan_id):
+ # Truncate the interface name if it exceeds 8 characters to make sure
+ # the length of bridge name is less than 15 (its maximum value).
+ br_name = KIMCHI_BRIDGE_PREFIX + interface[-8:] + '-' + vlan_id
+ br_xml = create_vlan_tagged_bridge_xml(br_name, interface, vlan_id)
+ conn = self.conn.get()
+
+ bridges = []
+ for net in conn.listAllNetworks():
+ # Bridged networks do not have a bridge name
+ # So in those cases, libvirt raises an error when trying to get
+ # the bridge name
+ try:
+ bridges.append(net.bridgeName())
+ except libvirt.libvirtError, e:
+ wok_log.error(e.message)
+
+ if br_name in bridges:
+ raise InvalidOperation("KCHNET0010E", {'iface': br_name})
+
+ with RollbackContext() as rollback:
+ try:
+ vlan_tagged_br = conn.interfaceDefineXML(br_xml, 0)
+ rollback.prependDefer(vlan_tagged_br.destroy)
+ vlan_tagged_br.create(0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed(e.message)
+ else:
+ return br_name
+
+
+class NetworkModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+
+ def lookup(self, name):
+ network = self.get_network(self.conn.get(), name)
+ xml = network.XMLDesc(0)
+ net_dict = self.get_network_from_xml(xml)
+ subnet = net_dict['subnet']
+ dhcp = net_dict['dhcp']
+ forward = net_dict['forward']
+ interface = net_dict['bridge']
+
+ connection = forward['mode'] or "isolated"
+ # FIXME, if we want to support other forward mode well.
+ if connection == 'bridge':
+ # macvtap bridge
+ interface = interface or forward['interface'][0]
+ # exposing the network on linux bridge or macvtap interface
+ interface_subnet = knetwork.get_dev_netaddr(interface)
+ subnet = subnet if subnet else interface_subnet
+
+ # libvirt use format 192.168.0.1/24, standard should be 192.168.0.0/24
+ # http://www.ovirt.org/File:Issue3.png
+ if subnet:
+ subnet = ipaddr.IPNetwork(subnet)
+ subnet = "%s/%s" % (subnet.network, subnet.prefixlen)
+
+ return {'connection': connection,
+ 'interface': interface,
+ 'subnet': subnet,
+ 'dhcp': dhcp,
+ 'vms': self._get_vms_attach_to_a_network(name),
+ 'in_use': self._is_network_in_use(name),
+ 'autostart': network.autostart() == 1,
+ 'state': network.isActive() and "active" or "inactive",
+ 'persistent': True if network.isPersistent() else False}
+
+ def _is_network_in_use(self, name):
+ # All the networks listed as default in template.conf file should not
+ # be deactivate or deleted. Otherwise, we will allow user create
+ # inconsistent templates from scratch
+ if name in tmpl_defaults['networks']:
+ return True
+
+ vms = self._get_vms_attach_to_a_network(name)
+ return bool(vms) or self._is_network_used_by_template(name)
+
+ def _is_network_used_by_template(self, network):
+ with self.objstore as session:
+ templates = session.get_list('template')
+ for tmpl in templates:
+ tmpl_net = session.get('template', tmpl)['networks']
+ if network in tmpl_net:
+ return True
+ return False
+
+ def _get_vms_attach_to_a_network(self, network, filter="all"):
+ DOM_STATE_MAP = {'nostate': 0, 'running': 1, 'blocked': 2,
+ 'paused': 3, 'shutdown': 4, 'shutoff': 5,
+ 'crashed': 6}
+ state = DOM_STATE_MAP.get(filter)
+ vms = []
+ conn = self.conn.get()
+ for dom in conn.listAllDomains(0):
+ networks = self._vm_get_networks(dom)
+ if network.encode('utf-8') in networks and \
+ (state is None or state == dom.state(0)[0]):
+ vms.append(dom.name())
+ return vms
+
+ def _vm_get_networks(self, dom):
+ xml = dom.XMLDesc(0)
+ xpath = "/domain/devices/interface[@type='network']/source/@network"
+ return xpath_get_text(xml, xpath)
+
+ def activate(self, name):
+ network = self.get_network(self.conn.get(), name)
+ try:
+ network.create()
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHNET0022E', {'name': name,
+ 'err': e.message})
+
+ def deactivate(self, name):
+ if self._is_network_in_use(name):
+ vms = self._get_vms_attach_to_a_network(name)
+ vms.sort()
+ raise InvalidOperation("KCHNET0018E", {'name': name,
+ 'vms': ', '.join(vms)})
+
+ network = self.get_network(self.conn.get(), name)
+ network.destroy()
+
+ def delete(self, name):
+ if self._is_network_in_use(name):
+ vms = self._get_vms_attach_to_a_network(name)
+ vms.sort()
+ raise InvalidOperation("KCHNET0017E", {'name': name,
+ 'vms': ', '.join(vms)})
+
+ network = self.get_network(self.conn.get(), name)
+ if network.isActive():
+ raise InvalidOperation("KCHNET0005E", {'name': name})
+
+ self._remove_vlan_tagged_bridge(network)
+ network.undefine()
+
+ @staticmethod
+ def get_network(conn, name):
+ name = name.encode("utf-8")
+ try:
+ return conn.networkLookupByName(name)
+ except libvirt.libvirtError:
+ raise NotFoundError("KCHNET0002E", {'name': name})
+
+ @staticmethod
+ def get_network_from_xml(xml):
+ address = xpath_get_text(xml, "/network/ip/@address")
+ address = address and address[0] or ''
+ netmask = xpath_get_text(xml, "/network/ip/@netmask")
+ netmask = netmask and netmask[0] or ''
+ net = address and netmask and "/".join([address, netmask]) or ''
+
+ dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
+ dhcp_start = dhcp_start and dhcp_start[0] or ''
+ dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
+ dhcp_end = dhcp_end and dhcp_end[0] or ''
+ dhcp = {'start': dhcp_start, 'end': dhcp_end}
+
+ forward_mode = xpath_get_text(xml, "/network/forward/@mode")
+ forward_mode = forward_mode and forward_mode[0] or ''
+ forward_if = xpath_get_text(xml, "/network/forward/interface/@dev")
+ forward_pf = xpath_get_text(xml, "/network/forward/pf/@dev")
+ bridge = xpath_get_text(xml, "/network/bridge/@name")
+ bridge = bridge and bridge[0] or ''
+ return {'subnet': net, 'dhcp': dhcp, 'bridge': bridge,
+ 'forward': {'mode': forward_mode,
+ 'interface': forward_if,
+ 'pf': forward_pf}}
+
+ def _remove_vlan_tagged_bridge(self, network):
+ try:
+ bridge = network.bridgeName()
+ except libvirt.libvirtError:
+ pass
+ else:
+ if bridge.startswith(KIMCHI_BRIDGE_PREFIX):
+ conn = self.conn.get()
+ iface = conn.interfaceLookupByName(bridge)
+ iface.isActive() and iface.destroy(0)
+ iface.undefine()
diff --git a/src/wok/plugins/kimchi/model/peers.py b/src/wok/plugins/kimchi/model/peers.py
new file mode 100644
index 0000000..7577364
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/peers.py
@@ -0,0 +1,72 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import re
+import socket
+
+from wok.config import config
+from wok.utils import run_command, wok_log
+
+
+class PeersModel(object):
+ def __init__(self, **kargs):
+ # check federation feature is enabled on Kimchi server
+ if config.get("server", "federation") == "off":
+ return
+
+ # register server on openslp
+ hostname = socket.getfqdn(config.get("server", "host"))
+ port = config.get("server", "ssl_port")
+ self.url = hostname + ":" + port
+
+ cmd = ["slptool", "register",
+ "service:wokd://%s" % self.url]
+ out, error, ret = run_command(cmd)
+ if out and len(out) != 0:
+ wok_log.error("Unable to register server on openSLP."
+ " Details: %s" % out)
+ cherrypy.engine.subscribe('exit', self._peer_deregister)
+
+ def _peer_deregister(self):
+ cmd = ["slptool", "deregister",
+ "service:wokd://%s" % self.url]
+ out, error, ret = run_command(cmd)
+ if out and len(out) != 0:
+ wok_log.error("Unable to deregister server on openSLP."
+ " Details: %s" % out)
+
+ def get_list(self):
+ # check federation feature is enabled on Kimchi server
+ if config.get("server", "federation") == "off":
+ return []
+
+ cmd = ["slptool", "findsrvs", "service:wokd"]
+ out, error, ret = run_command(cmd)
+ if ret != 0:
+ return []
+
+ peers = []
+ for server in out.strip().split("\n"):
+ match = re.match("service:wokd://(.*?),.*", server)
+ peer = match.group(1)
+ if peer != self.url:
+ peers.append("https://" + peer)
+
+ return peers
diff --git a/src/wok/plugins/kimchi/model/storagepools.py b/src/wok/plugins/kimchi/model/storagepools.py
new file mode 100644
index 0000000..0db2ef4
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storagepools.py
@@ -0,0 +1,490 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import sys
+from lxml.builder import E
+
+from wok.config import config, PluginPaths
+from wok.exception import InvalidOperation, MissingParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import add_task, run_command, wok_log
+from wok.xmlutils.utils import xpath_get_text
+
+from ..osinfo import defaults as tmpl_defaults
+from ..scan import Scanner
+from ..utils import pool_name_from_uri
+from config import CapabilitiesModel
+from host import DeviceModel
+from libvirtstoragepool import StoragePoolDef
+
+
+ISO_POOL_NAME = u'kimchi_isos'
+
+POOL_STATE_MAP = {0: 'inactive',
+ 1: 'initializing',
+ 2: 'active',
+ 3: 'degraded',
+ 4: 'inaccessible'}
+
+# Types of pools supported
+STORAGE_SOURCES = {'netfs': {'addr': '/pool/source/host/@name',
+ 'path': '/pool/source/dir/@path'},
+ 'iscsi': {'addr': '/pool/source/host/@name',
+ 'port': '/pool/source/host/@port',
+ 'path': '/pool/source/device/@path'},
+ 'scsi': {'adapter_type': '/pool/source/adapter/@type',
+ 'adapter_name': '/pool/source/adapter/@name',
+ 'wwnn': '/pool/source/adapter/@wwnn',
+ 'wwpn': '/pool/source/adapter/@wwpn'}}
+
+
+class StoragePoolsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.scanner = Scanner(self._clean_scan)
+ self.scanner.delete()
+ self.caps = CapabilitiesModel(**kargs)
+ self.device = DeviceModel(**kargs)
+
+ if self.conn.isQemuURI():
+ self._check_default_pools()
+
+ def _check_default_pools(self):
+ pools = {}
+
+ default_pool = tmpl_defaults['storagepool']
+ default_pool = default_pool.split('/')[-1]
+
+ pools[default_pool] = {}
+ if default_pool == 'default':
+ pools[default_pool] = {'path': '/var/lib/libvirt/images'}
+
+ if config.get("server", "create_iso_pool") == "true":
+ pools['ISO'] = {'path': '/var/lib/kimchi/isos'}
+
+ error_msg = ("Please, check the configuration in %s/template.conf to "
+ "ensure it has a valid storage pool." %
+ PluginPaths('kimchi').conf_dir)
+
+ conn = self.conn.get()
+ for pool_name in pools:
+ try:
+ pool = conn.storagePoolLookupByName(pool_name)
+ except libvirt.libvirtError, e:
+ pool_path = pools[pool_name].get('path')
+ if pool_path is None:
+ msg = "Fatal: Unable to find storage pool %s. " + error_msg
+ wok_log.error(msg % pool_name)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ # Try to create the pool
+ pool = E.pool(E.name(pool_name), type='dir')
+ pool.append(E.target(E.path(pool_path)))
+ xml = ET.tostring(pool)
+ try:
+ pool = conn.storagePoolDefineXML(xml, 0)
+ except libvirt.libvirtError, e:
+ msg = "Fatal: Unable to create storage pool %s. "
+ msg += error_msg
+ wok_log.error(msg % pool_name)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ # Build and set autostart value to pool
+ # Ignore error as the pool was already successfully created
+ try:
+ # Add build step to make sure target directory created
+ # The build process may fail when the pool directory
+ # already exists on system
+ pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
+ pool.setAutostart(1)
+ except:
+ pass
+
+ if pool.isActive() == 0:
+ try:
+ pool.create(0)
+ except libvirt.libvirtError, e:
+ msg = "Fatal: Unable to craete storage pool %s. "
+ msg += error_msg
+ wok_log.error(msg % pool_name)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ def get_list(self):
+ try:
+ conn = self.conn.get()
+ names = conn.listStoragePools()
+ names += conn.listDefinedStoragePools()
+ return sorted(map(lambda x: x.decode('utf-8'), names))
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0006E",
+ {'err': e.get_error_message()})
+
+ def create(self, params):
+ task_id = None
+ conn = self.conn.get()
+ try:
+ name = params['name']
+ if name == ISO_POOL_NAME:
+ raise InvalidOperation("KCHPOOL0031E")
+
+ # The user may want to create a logical pool with the same name
+ # used before but a volume group will already exist with this name
+ # So check the volume group does not exist to create the pool
+ if params['type'] == 'logical':
+ vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')]
+ output, error, returncode = run_command(vgdisplay_cmd)
+ # From vgdisplay error codes:
+ # 1 error reading VGDA
+ # 2 volume group doesn't exist
+ # 3 not all physical volumes of volume group online
+ # 4 volume group not found
+ # 5 no volume groups found at all
+ # 6 error reading VGDA from lvmtab
+ if returncode not in [2, 4, 5]:
+ raise InvalidOperation("KCHPOOL0036E", {'name': name})
+
+ if params['type'] == 'kimchi-iso':
+ task_id = self._do_deep_scan(params)
+
+ if params['type'] == 'scsi':
+ adapter_name = params['source']['adapter_name']
+ extra_params = self.device.lookup(adapter_name)
+ # Adds name, adapter_type, wwpn and wwnn to source information
+ params['source'].update(extra_params)
+ params['fc_host_support'] = self.caps.fc_host_support
+
+ poolDef = StoragePoolDef.create(params)
+ poolDef.prepare(conn)
+ xml = poolDef.xml.encode("utf-8")
+ except KeyError, item:
+ raise MissingParameter("KCHPOOL0004E",
+ {'item': str(item), 'name': name})
+
+ if name in self.get_list():
+ raise InvalidOperation("KCHPOOL0001E", {'name': name})
+
+ try:
+ if task_id:
+ # Create transient pool for deep scan
+ conn.storagePoolCreateXML(xml, 0)
+ return name
+
+ pool = conn.storagePoolDefineXML(xml, 0)
+ except libvirt.libvirtError as e:
+ wok_log.error("Problem creating Storage Pool: %s", e)
+ raise OperationFailed("KCHPOOL0007E",
+ {'name': name, 'err': e.get_error_message()})
+
+ # Build and set autostart value to pool
+ # Ignore error as the pool was already successfully created
+ # The build process fails when the pool directory already exists
+ try:
+ if params['type'] in ['logical', 'dir', 'netfs', 'scsi']:
+ pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
+ pool.setAutostart(1)
+ else:
+ pool.setAutostart(0)
+ except:
+ pass
+
+ if params['type'] == 'netfs':
+ output, error, returncode = run_command(['setsebool', '-P',
+ 'virt_use_nfs=1'])
+ if error or returncode:
+ wok_log.error("Unable to set virt_use_nfs=1. If you use "
+ "SELinux, this may prevent NFS pools from "
+ "being used.")
+ return name
+
+ def _clean_scan(self, pool_name):
+ try:
+ conn = self.conn.get()
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ pool.destroy()
+ with self.objstore as session:
+ session.delete('scanning', pool_name)
+ except Exception, e:
+ err = "Exception %s occured when cleaning scan result"
+ wok_log.debug(err % e.message)
+
+ def _do_deep_scan(self, params):
+ scan_params = dict(ignore_list=[])
+ scan_params['scan_path'] = params['path']
+ params['type'] = 'dir'
+
+ for pool in self.get_list():
+ try:
+ res = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool)
+ if res['state'] == 'active':
+ scan_params['ignore_list'].append(res['path'])
+ except Exception, e:
+ err = "Exception %s occured when get ignore path"
+ wok_log.debug(err % e.message)
+
+ params['path'] = self.scanner.scan_dir_prepare(params['name'])
+ scan_params['pool_path'] = params['path']
+ task_id = add_task('/plugins/kimchi/storagepools/%s' % ISO_POOL_NAME,
+ self.scanner.start_scan, self.objstore, scan_params)
+ # Record scanning-task/storagepool mapping for future querying
+ try:
+ with self.objstore as session:
+ session.store('scanning', params['name'], task_id)
+ return task_id
+ except Exception as e:
+ raise OperationFailed('KCHPOOL0037E', {'err': e.message})
+
+
+class StoragePoolModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+
+ @staticmethod
+ def get_storagepool(name, conn):
+ conn = conn.get()
+ try:
+ return conn.storagePoolLookupByName(name.encode("utf-8"))
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_POOL:
+ raise NotFoundError("KCHPOOL0002E", {'name': name})
+ else:
+ raise
+
+ def _get_storagepool_vols_num(self, pool):
+ try:
+ if pool.isActive():
+ pool.refresh(0)
+ return pool.numOfVolumes()
+ else:
+ return 0
+ except libvirt.libvirtError as e:
+ # If something (say a busy pool) prevents the refresh,
+ # throwing an Exception here would prevent all pools from
+ # displaying information -- so return None for busy
+ wok_log.error("ERROR: Storage Pool get vol count: %s "
+ % e.get_error_message())
+ wok_log.error("ERROR: Storage Pool get vol count error no: %s "
+ % e.get_error_code())
+ return 0
+ except Exception as e:
+ raise OperationFailed("KCHPOOL0008E",
+ {'name': pool.name(),
+ 'err': e.get_error_message()})
+
+ def _get_storage_source(self, pool_type, pool_xml):
+ source = {}
+ if pool_type not in STORAGE_SOURCES:
+ return source
+
+ for key, val in STORAGE_SOURCES[pool_type].items():
+ res = xpath_get_text(pool_xml, val)
+ if len(res) == 1:
+ source[key] = res[0]
+ elif len(res) == 0:
+ source[key] = ""
+ else:
+ source[key] = res
+ return source
+
+ def _nfs_status_online(self, pool, poolArgs=None):
+ if not poolArgs:
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ source = self._get_storage_source(pool_type, xml)
+ poolArgs = {}
+ poolArgs['name'] = pool.name()
+ poolArgs['type'] = pool_type
+ poolArgs['source'] = {'path': source['path'],
+ 'host': source['addr']}
+ conn = self.conn.get()
+ poolDef = StoragePoolDef.create(poolArgs)
+ try:
+ poolDef.prepare(conn)
+ return True
+ except Exception:
+ return False
+
+ def lookup(self, name):
+ pool = self.get_storagepool(name, self.conn)
+ info = pool.info()
+ autostart = True if pool.autostart() else False
+ persistent = True if pool.isPersistent() else False
+ xml = pool.XMLDesc(0)
+ path = xpath_get_text(xml, "/pool/target/path")[0]
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ source = self._get_storage_source(pool_type, xml)
+ # FIXME: nfs workaround - prevent any libvirt operation
+ # for a nfs if the corresponding NFS server is down.
+ if pool_type == 'netfs' and not self._nfs_status_online(pool):
+ wok_log.debug("NFS pool %s is offline, reason: NFS "
+ "server %s is unreachable.", name, source['addr'])
+ # Mark state as '4' => inaccessible.
+ info[0] = 4
+ # skip calculating volumes
+ nr_volumes = 0
+ else:
+ nr_volumes = self._get_storagepool_vols_num(pool)
+
+ res = {'state': POOL_STATE_MAP[info[0]],
+ 'path': path,
+ 'source': source,
+ 'type': pool_type,
+ 'autostart': autostart,
+ 'capacity': info[1],
+ 'allocated': info[2],
+ 'available': info[3],
+ 'nr_volumes': nr_volumes,
+ 'persistent': persistent}
+
+ if not pool.isPersistent():
+ # Deal with deep scan generated pool
+ try:
+ with self.objstore as session:
+ task_id = session.get('scanning', name)
+ res['task_id'] = str(task_id)
+ res['type'] = 'kimchi-iso'
+ except NotFoundError:
+ # User created normal pool
+ pass
+ return res
+
+ def _update_lvm_disks(self, pool_name, disks):
+ # check if all the disks/partitions exists in the host
+ for disk in disks:
+ lsblk_cmd = ['lsblk', disk]
+ output, error, returncode = run_command(lsblk_cmd)
+ if returncode != 0:
+ wok_log.error('%s is not a valid disk/partition. Could not '
+ 'add it to the pool %s.', disk, pool_name)
+ raise OperationFailed('KCHPOOL0027E', {'disk': disk,
+ 'pool': pool_name})
+ # add disks to the lvm pool using vgextend + virsh refresh
+ vgextend_cmd = ["vgextend", pool_name]
+ vgextend_cmd += disks
+ output, error, returncode = run_command(vgextend_cmd)
+ if returncode != 0:
+ msg = "Could not add disks to pool %s, error: %s"
+ wok_log.error(msg, pool_name, error)
+ raise OperationFailed('KCHPOOL0028E', {'pool': pool_name,
+ 'err': error})
+ # refreshing pool state
+ pool = self.get_storagepool(pool_name, self.conn)
+ if pool.isActive():
+ pool.refresh(0)
+
+ def update(self, name, params):
+ pool = self.get_storagepool(name, self.conn)
+ if 'autostart' in params:
+ if params['autostart']:
+ pool.setAutostart(1)
+ else:
+ pool.setAutostart(0)
+
+ if 'disks' in params:
+ # check if pool is type 'logical'
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type != 'logical':
+ raise InvalidOperation('KCHPOOL0029E')
+ self._update_lvm_disks(name, params['disks'])
+ ident = pool.name()
+ return ident.decode('utf-8')
+
+ def activate(self, name):
+ pool = self.get_storagepool(name, self.conn)
+ # FIXME: nfs workaround - do not activate a NFS pool
+ # if the NFS server is not reachable.
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type == 'netfs' and not self._nfs_status_online(pool):
+ # block the user from activating the pool.
+ source = self._get_storage_source(pool_type, xml)
+ raise OperationFailed("KCHPOOL0032E",
+ {'name': name, 'server': source['addr']})
+ return
+ try:
+ pool.create(0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0009E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def _pool_used_by_template(self, pool_name):
+ with self.objstore as session:
+ templates = session.get_list('template')
+ for tmpl in templates:
+ t_info = session.get('template', tmpl)
+ t_pool = pool_name_from_uri(t_info['storagepool'])
+ if t_pool == pool_name:
+ return True
+ return False
+
+ def deactivate(self, name):
+ if self._pool_used_by_template(name):
+ raise InvalidOperation('KCHPOOL0034E', {'name': name})
+
+ pool = self.get_storagepool(name, self.conn)
+ # FIXME: nfs workaround - do not try to deactivate a NFS pool
+ # if the NFS server is not reachable.
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type == 'netfs' and not self._nfs_status_online(pool):
+ # block the user from dactivating the pool.
+ source = self._get_storage_source(pool_type, xml)
+ raise OperationFailed("KCHPOOL0033E",
+ {'name': name, 'server': source['addr']})
+ return
+ try:
+ persistent = pool.isPersistent()
+ pool.destroy()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0010E",
+ {'name': name, 'err': e.get_error_message()})
+ # If pool was not persistent, then it was erased by destroy() and
+ # must return nothing here, to trigger _redirect() and avoid errors
+ if not persistent:
+ return ""
+
+ def delete(self, name):
+ if self._pool_used_by_template(name):
+ raise InvalidOperation('KCHPOOL0035E', {'name': name})
+
+ pool = self.get_storagepool(name, self.conn)
+ if pool.isActive():
+ raise InvalidOperation("KCHPOOL0005E", {'name': name})
+ try:
+ pool.undefine()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0011E",
+ {'name': name, 'err': e.get_error_message()})
+
+
+class IsoPoolModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ return {'state': 'active',
+ 'type': 'kimchi-iso'}
diff --git a/src/wok/plugins/kimchi/model/storageservers.py b/src/wok/plugins/kimchi/model/storageservers.py
new file mode 100644
index 0000000..accc5f5
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storageservers.py
@@ -0,0 +1,81 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.exception import NotFoundError
+
+from storagepools import StoragePoolModel, StoragePoolsModel
+
+# Types of remote storage servers supported
+STORAGE_SERVERS = ['netfs', 'iscsi']
+
+
+class StorageServersModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.pool = StoragePoolModel(**kargs)
+ self.pools = StoragePoolsModel(**kargs)
+
+ def get_list(self, _target_type=None):
+ if not _target_type:
+ target_type = STORAGE_SERVERS
+ else:
+ target_type = [_target_type]
+
+ pools = self.pools.get_list()
+
+ server_list = []
+ for pool in pools:
+ try:
+ pool_info = self.pool.lookup(pool)
+ if (pool_info['type'] in target_type and
+ pool_info['source']['addr'] not in server_list):
+ # Avoid to add same server for multiple times
+ # if it hosts more than one storage type
+ server_list.append(pool_info['source']['addr'])
+ except NotFoundError:
+ pass
+
+ return server_list
+
+
+class StorageServerModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.pool = StoragePoolModel(**kargs)
+
+ def lookup(self, server):
+ conn = self.conn.get()
+ pools = conn.listStoragePools()
+ pools += conn.listDefinedStoragePools()
+ for pool in pools:
+ try:
+ pool_info = self.pool.lookup(pool)
+ if (pool_info['type'] in STORAGE_SERVERS and
+ pool_info['source']['addr'] == server):
+ info = dict(host=server)
+ if (pool_info['type'] == "iscsi" and
+ 'port' in pool_info['source']):
+ info["port"] = pool_info['source']['port']
+ return info
+ except NotFoundError:
+ # Avoid inconsistent pool result because of lease between list
+ # lookup
+ pass
+
+ raise NotFoundError("KCHSR0001E", {'server': server})
diff --git a/src/wok/plugins/kimchi/model/storagetargets.py b/src/wok/plugins/kimchi/model/storagetargets.py
new file mode 100644
index 0000000..4090b45
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storagetargets.py
@@ -0,0 +1,122 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+from lxml import objectify
+from lxml.builder import E
+
+from wok.utils import patch_find_nfs_target, wok_log
+
+from config import CapabilitiesModel
+from storageservers import STORAGE_SERVERS
+
+
+class StorageTargetsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def get_list(self, storage_server, _target_type=None, _server_port=None):
+ target_list = list()
+ if not _target_type:
+ target_types = STORAGE_SERVERS
+ else:
+ target_types = [_target_type]
+
+ for target_type in target_types:
+ if not self.caps.nfs_target_probe and target_type == 'netfs':
+ targets = patch_find_nfs_target(storage_server)
+ else:
+ xml = self._get_storage_server_spec(server=storage_server,
+ target_type=target_type,
+ server_port=_server_port)
+ conn = self.conn.get()
+ try:
+ ret = conn.findStoragePoolSources(target_type, xml, 0)
+ except libvirt.libvirtError as e:
+ err = "Query storage pool source fails because of %s"
+ wok_log.warning(err, e.get_error_message())
+ continue
+
+ targets = self._parse_target_source_result(target_type, ret)
+
+ target_list.extend(targets)
+
+ # Get all netfs and iscsi paths in use
+ used_paths = []
+ try:
+ conn = self.conn.get()
+ # Get all existing ISCSI and NFS pools
+ pools = conn.listAllStoragePools(
+ libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI |
+ libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_NETFS)
+ for pool in pools:
+ pool_xml = pool.XMLDesc(0)
+ root = objectify.fromstring(pool_xml)
+ if root.get('type') == 'netfs' and \
+ root.source.dir is not None:
+ used_paths.append(root.source.dir.get('path'))
+ elif root.get('type') == 'iscsi' and \
+ root.source.device is not None:
+ used_paths.append(root.source.device.get('path'))
+
+ except libvirt.libvirtError as e:
+ err = "Query storage pool source fails because of %s"
+ wok_log.warning(err, e.get_error_message())
+
+ # Filter target_list to not not show the used paths
+ target_list = [elem for elem in target_list
+ if elem.get('target') not in used_paths]
+ return [dict(t) for t in set(tuple(t.items()) for t in target_list)]
+
+ def _get_storage_server_spec(self, **kwargs):
+ # Required parameters:
+ # server:
+ # target_type:
+ extra_args = []
+ server_type = kwargs['target_type']
+ if server_type == 'netfs':
+ extra_args.append(E.format(type='nfs'))
+ else:
+ extra_args.append(E.format(type=server_type))
+
+ host_attr = {"name": kwargs['server']}
+ server_port = kwargs.get("server_port")
+ if server_port is not None:
+ host_attr['port'] = server_port
+
+ obj = E.source(E.host(host_attr), *extra_args)
+ xml = ET.tostring(obj)
+ return xml
+
+ def _parse_target_source_result(self, target_type, xml_str):
+ root = objectify.fromstring(xml_str)
+ ret = []
+ for source in root.getchildren():
+ if target_type == 'netfs':
+ target_path = source.dir.get('path')
+ type = source.format.get('type')
+ if target_type == 'iscsi':
+ target_path = source.device.get('path')
+ type = target_type
+ host_name = source.host.get('name')
+ ret.append(dict(host=host_name, target_type=type,
+ target=target_path))
+ return ret
diff --git a/src/wok/plugins/kimchi/model/storagevolumes.py b/src/wok/plugins/kimchi/model/storagevolumes.py
new file mode 100644
index 0000000..99b17d3
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storagevolumes.py
@@ -0,0 +1,542 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import contextlib
+import libvirt
+import lxml.etree as ET
+import os
+import tempfile
+import threading
+import time
+import urllib2
+from lxml.builder import E
+
+from wok.exception import InvalidOperation, InvalidParameter, IsoFormatError
+from wok.exception import MissingParameter, NotFoundError, OperationFailed
+from wok.utils import add_task, get_next_clone_name, get_unique_file_name
+from wok.utils import wok_log
+from wok.xmlutils.utils import xpath_get_text
+from wok.model.tasks import TaskModel
+
+from ..config import READONLY_POOL_TYPE
+from ..isoinfo import IsoImage
+from diskutils import get_disk_used_by, set_disk_used_by
+from storagepools import StoragePoolModel
+
+
+VOLUME_TYPE_MAP = {0: 'file',
+ 1: 'block',
+ 2: 'directory',
+ 3: 'network'}
+
+READ_CHUNK_SIZE = 1048576 # 1 MiB
+REQUIRE_NAME_PARAMS = ['capacity']
+
+upload_volumes = dict()
+
+
+class StorageVolumesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+
+ def create(self, pool_name, params):
+ vol_source = ['url', 'capacity']
+
+ name = params.get('name')
+
+ index_list = list(i for i in range(len(vol_source))
+ if vol_source[i] in params)
+ if len(index_list) != 1:
+ raise InvalidParameter("KCHVOL0018E",
+ {'param': ",".join(vol_source)})
+
+ create_param = vol_source[index_list[0]]
+
+ # Verify if the URL is valid
+ if create_param == 'url':
+ url = params['url']
+ try:
+ urllib2.urlopen(url).close()
+ except:
+ raise InvalidParameter('KCHVOL0022E', {'url': url})
+
+ all_vol_names = self.get_list(pool_name)
+
+ if name is None:
+ # the methods listed in 'REQUIRE_NAME_PARAMS' cannot have
+ # 'name' == None
+ if create_param in REQUIRE_NAME_PARAMS:
+ raise InvalidParameter('KCHVOL0016E')
+
+ # if 'name' is omitted - except for the methods listed in
+ # 'REQUIRE_NAME_PARAMS' - the default volume name will be the
+ # file/URL basename.
+ if create_param == 'url':
+ name = os.path.basename(params['url'])
+ else:
+ name = 'upload-%s' % int(time.time())
+
+ name = get_unique_file_name(all_vol_names, name)
+ params['name'] = name
+
+ try:
+ create_func = getattr(self, '_create_volume_with_%s' %
+ create_param)
+ except AttributeError:
+ raise InvalidParameter("KCHVOL0019E", {'param': create_param})
+
+ pool_info = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool_name)
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ raise InvalidParameter("KCHVOL0012E", {'type': pool_info['type']})
+ if pool_info['state'] == 'inactive':
+ raise InvalidParameter('KCHVOL0003E', {'pool': pool_name,
+ 'volume': name})
+ if name in all_vol_names:
+ raise InvalidParameter('KCHVOL0001E', {'name': name})
+
+ params['pool'] = pool_name
+ targeturi = '/plugins/kimchi/storagepools/%s/storagevolumes/%s' \
+ % (pool_name, name)
+ taskid = add_task(targeturi, create_func, self.objstore, params)
+ return self.task.lookup(taskid)
+
+ def _create_volume_with_capacity(self, cb, params):
+ pool_name = params.pop('pool')
+ vol_xml = """
+ <volume>
+ <name>%(name)s</name>
+ <allocation unit='bytes'>%(allocation)s</allocation>
+ <capacity unit='bytes'>%(capacity)s</capacity>
+ <source>
+ </source>
+ <target>
+ <format type='%(format)s'/>
+ </target>
+ </volume>
+ """
+ params.setdefault('allocation', 0)
+ params.setdefault('format', 'qcow2')
+
+ name = params['name']
+ try:
+ pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ xml = vol_xml % params
+ except KeyError, item:
+ raise MissingParameter("KCHVOL0004E", {'item': str(item),
+ 'volume': name})
+
+ try:
+ pool.createXML(xml, 0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0007E",
+ {'name': name, 'pool': pool,
+ 'err': e.get_error_message()})
+
+ vol_info = StorageVolumeModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool_name,
+ name)
+
+ vol_path = vol_info['path']
+ set_disk_used_by(self.objstore, vol_info['path'], [])
+
+ if params.get('upload', False):
+ upload_volumes[vol_path] = {'lock': threading.Lock(),
+ 'offset': 0, 'cb': cb}
+ cb('ready for upload')
+ else:
+ cb('OK', True)
+
+ def _create_volume_with_url(self, cb, params):
+ pool_name = params['pool']
+ name = params['name']
+ url = params['url']
+
+ pool_model = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore)
+ pool = pool_model.lookup(pool_name)
+
+ if pool['type'] in ['dir', 'netfs']:
+ file_path = os.path.join(pool['path'], name)
+ else:
+ file_path = tempfile.mkstemp(prefix=name)[1]
+
+ with contextlib.closing(urllib2.urlopen(url)) as response:
+ with open(file_path, 'w') as volume_file:
+ remote_size = response.info().getheader('Content-Length', '-')
+ downloaded_size = 0
+
+ try:
+ while True:
+ chunk_data = response.read(READ_CHUNK_SIZE)
+ if not chunk_data:
+ break
+
+ volume_file.write(chunk_data)
+ downloaded_size += len(chunk_data)
+ cb('%s/%s' % (downloaded_size, remote_size))
+ except (IOError, libvirt.libvirtError) as e:
+ if os.path.isfile(file_path):
+ os.remove(file_path)
+
+ raise OperationFailed('KCHVOL0007E', {'name': name,
+ 'pool': pool_name,
+ 'err': e.message})
+
+ if pool['type'] in ['dir', 'netfs']:
+ virt_pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ virt_pool.refresh(0)
+ else:
+ def _stream_handler(stream, nbytes, fd):
+ return fd.read(nbytes)
+
+ virt_stream = virt_vol = None
+
+ try:
+ task = self.create(pool_name, {'name': name,
+ 'format': 'raw',
+ 'capacity': downloaded_size,
+ 'allocation': downloaded_size})
+ self.task.wait(task['id'])
+ virt_vol = StorageVolumeModel.get_storagevolume(pool_name,
+ name,
+ self.conn)
+
+ virt_stream = self.conn.get().newStream(0)
+ virt_vol.upload(virt_stream, 0, downloaded_size, 0)
+
+ with open(file_path) as fd:
+ virt_stream.sendAll(_stream_handler, fd)
+
+ virt_stream.finish()
+ except (IOError, libvirt.libvirtError) as e:
+ try:
+ if virt_stream:
+ virt_stream.abort()
+ if virt_vol:
+ virt_vol.delete(0)
+ except libvirt.libvirtError, virt_e:
+ wok_log.error(virt_e.message)
+ finally:
+ raise OperationFailed('KCHVOL0007E', {'name': name,
+ 'pool': pool_name,
+ 'err': e.message})
+ finally:
+ os.remove(file_path)
+
+ vol_info = StorageVolumeModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool_name,
+ name)
+ set_disk_used_by(self.objstore, vol_info['path'], [])
+
+ cb('OK', True)
+
+ def get_list(self, pool_name):
+ pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ if not pool.isActive():
+ raise InvalidOperation("KCHVOL0006E", {'pool': pool_name})
+ try:
+ pool.refresh(0)
+ return sorted(map(lambda x: x.decode('utf-8'), pool.listVolumes()))
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0008E",
+ {'pool': pool_name,
+ 'err': e.get_error_message()})
+
+
+class StorageVolumeModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+ self.storagevolumes = StorageVolumesModel(**kargs)
+ self.storagepool = StoragePoolModel(**kargs)
+
+ @staticmethod
+ def get_storagevolume(poolname, name, conn):
+ pool = StoragePoolModel.get_storagepool(poolname, conn)
+ if not pool.isActive():
+ raise InvalidOperation("KCHVOL0006E", {'name': pool})
+ try:
+ return pool.storageVolLookupByName(name.encode("utf-8"))
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_VOL:
+ raise NotFoundError("KCHVOL0002E", {'name': name,
+ 'pool': poolname})
+ else:
+ raise
+
+ def lookup(self, pool, name):
+ vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ path = vol.path()
+ info = vol.info()
+ xml = vol.XMLDesc(0)
+ try:
+ fmt = xpath_get_text(xml, "/volume/target/format/@type")[0]
+ except IndexError:
+ # Not all types of libvirt storage can provide volume format
+ # infomation. When there is no format information, we assume
+ # it's 'raw'.
+ fmt = 'raw'
+
+ iso_img = None
+
+ # 'raw' volumes from 'logical' pools may actually be 'iso';
+ # libvirt always reports them as 'raw'
+ pool_info = self.storagepool.lookup(pool)
+ if pool_info['type'] == 'logical' and fmt == 'raw':
+ try:
+ iso_img = IsoImage(path)
+ except IsoFormatError:
+ # not 'iso' afterall
+ pass
+ else:
+ fmt = 'iso'
+
+ used_by = get_disk_used_by(self.objstore, self.conn, path)
+ res = dict(type=VOLUME_TYPE_MAP[info[0]],
+ capacity=info[1],
+ allocation=info[2],
+ path=path,
+ used_by=used_by,
+ format=fmt)
+ if fmt == 'iso':
+ if os.path.islink(path):
+ path = os.path.join(os.path.dirname(path), os.readlink(path))
+ os_distro = os_version = 'unknown'
+ try:
+ if iso_img is None:
+ iso_img = IsoImage(path)
+ os_distro, os_version = iso_img.probe()
+ bootable = True
+ except IsoFormatError:
+ bootable = False
+ res.update(
+ dict(os_distro=os_distro, os_version=os_version, path=path,
+ bootable=bootable))
+ return res
+
+ def wipe(self, pool, name):
+ volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ try:
+ volume.wipePattern(libvirt.VIR_STORAGE_VOL_WIPE_ALG_ZERO, 0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0009E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def delete(self, pool, name):
+ pool_info = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool)
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ raise InvalidParameter("KCHVOL0012E", {'type': pool_info['type']})
+
+ volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ try:
+ volume.delete(0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0010E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def resize(self, pool, name, size):
+ volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+
+ # When decreasing the storage volume capacity, the flag
+ # VIR_STORAGE_VOL_RESIZE_SHRINK must be used
+ flags = 0
+ if volume.info()[1] > size:
+ # FIXME: Even using VIR_STORAGE_VOL_RESIZE_SHRINK flag it is not
+ # possible to decrease the volume capacity due a libvirt bug
+ # For reference:
+ # - https://bugzilla.redhat.com/show_bug.cgi?id=1021802
+ flags = libvirt.VIR_STORAGE_VOL_RESIZE_SHRINK
+
+ try:
+ volume.resize(size, flags)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0011E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def clone(self, pool, name, new_pool=None, new_name=None):
+ """Clone a storage volume.
+
+ Arguments:
+ pool -- The name of the original pool.
+ name -- The name of the original volume.
+ new_pool -- The name of the destination pool (optional). If omitted,
+ the new volume will be created on the same pool as the
+ original one.
+ new_name -- The name of the new volume (optional). If omitted, a new
+ value based on the original volume's name will be used.
+
+ Return:
+ A Task running the clone operation.
+ """
+ # the same pool will be used if no pool is specified
+ if new_pool is None:
+ new_pool = pool
+
+ # a default name based on the original name will be used if no name
+ # is specified
+ if new_name is None:
+ base, ext = os.path.splitext(name)
+ new_name = get_next_clone_name(self.storagevolumes.get_list(pool),
+ base, ext)
+
+ params = {'pool': pool,
+ 'name': name,
+ 'new_pool': new_pool,
+ 'new_name': new_name}
+ taskid = add_task(u'/plugins/kimchi/storagepools/%s/storagevolumes/%s'
+ % (pool, new_name), self._clone_task, self.objstore,
+ params)
+ return self.task.lookup(taskid)
+
+ def _clone_task(self, cb, params):
+ """Asynchronous function which performs the clone operation.
+
+ This function copies all the data inside the original volume into the
+ new one.
+
+ Arguments:
+ cb -- A callback function to signal the Task's progress.
+ params -- A dict with the following values:
+ "pool": The name of the original pool.
+ "name": The name of the original volume.
+ "new_pool": The name of the destination pool.
+ "new_name": The name of the new volume.
+ """
+ orig_pool_name = params['pool']
+ orig_vol_name = params['name']
+ new_pool_name = params['new_pool']
+ new_vol_name = params['new_name']
+
+ try:
+ cb('setting up volume cloning')
+ orig_vir_vol = StorageVolumeModel.get_storagevolume(orig_pool_name,
+ orig_vol_name,
+ self.conn)
+ orig_vol = self.lookup(orig_pool_name, orig_vol_name)
+ new_vir_pool = StoragePoolModel.get_storagepool(new_pool_name,
+ self.conn)
+
+ cb('building volume XML')
+ root_elem = E.volume()
+ root_elem.append(E.name(new_vol_name))
+ root_elem.append(E.capacity(unicode(orig_vol['capacity']),
+ unit='bytes'))
+ target_elem = E.target()
+ target_elem.append(E.format(type=orig_vol['format']))
+ root_elem.append(target_elem)
+ new_vol_xml = ET.tostring(root_elem, encoding='utf-8',
+ pretty_print=True)
+
+ cb('cloning volume')
+ new_vir_pool.createXMLFrom(new_vol_xml, orig_vir_vol, 0)
+ except (InvalidOperation, NotFoundError, libvirt.libvirtError), e:
+ raise OperationFailed('KCHVOL0023E',
+ {'name': orig_vol_name,
+ 'pool': orig_pool_name,
+ 'err': e.get_error_message()})
+
+ new_vol = self.lookup(new_pool_name, new_vol_name)
+ cb('adding volume to the object store')
+ set_disk_used_by(self.objstore, new_vol['path'], [])
+
+ cb('OK', True)
+
+ def doUpload(self, cb, vol, offset, data, data_size):
+ try:
+ st = self.conn.get().newStream(0)
+ vol.upload(st, offset, data_size)
+ st.send(data)
+ st.finish()
+ except Exception as e:
+ st and st.abort()
+ cb('', False)
+
+ try:
+ vol.delete(0)
+ except Exception as e:
+ pass
+
+ raise OperationFailed("KCHVOL0029E", {"err": e.message})
+
+ def update(self, pool, name, params):
+ chunk_data = params['chunk'].fullvalue()
+ chunk_size = int(params['chunk_size'])
+
+ if len(chunk_data) != chunk_size:
+ raise OperationFailed("KCHVOL0026E")
+
+ vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ vol_path = vol.path()
+ vol_capacity = vol.info()[1]
+
+ vol_data = upload_volumes.get(vol_path)
+ if vol_data is None:
+ raise OperationFailed("KCHVOL0027E", {"vol": vol_path})
+
+ cb = vol_data['cb']
+ lock = vol_data['lock']
+ with lock:
+ offset = vol_data['offset']
+ if (offset + chunk_size) > vol_capacity:
+ raise OperationFailed("KCHVOL0028E")
+
+ cb('%s/%s' % (offset, vol_capacity))
+ self.doUpload(cb, vol, offset, chunk_data, chunk_size)
+ cb('%s/%s' % (offset + chunk_size, vol_capacity))
+
+ vol_data['offset'] += chunk_size
+ if vol_data['offset'] == vol_capacity:
+ del upload_volumes[vol_path]
+ cb('OK', True)
+
+
+class IsoVolumesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.storagevolume = StorageVolumeModel(**kargs)
+
+ def get_list(self):
+ iso_volumes = []
+ conn = self.conn.get()
+ pools = conn.listStoragePools()
+ pools += conn.listDefinedStoragePools()
+
+ for pool_name in pools:
+ try:
+ pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ pool.refresh(0)
+ volumes = pool.listVolumes()
+ except Exception, e:
+ # Skip inactive pools
+ wok_log.debug("Shallow scan: skipping pool %s because of "
+ "error: %s", (pool_name, e.message))
+ continue
+
+ for volume in volumes:
+ res = self.storagevolume.lookup(pool_name,
+ volume.decode("utf-8"))
+ if res['format'] == 'iso' and res['bootable']:
+ res['name'] = '%s' % volume
+ iso_volumes.append(res)
+ return iso_volumes
diff --git a/src/wok/plugins/kimchi/model/templates.py b/src/wok/plugins/kimchi/model/templates.py
new file mode 100644
index 0000000..4f0b204
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/templates.py
@@ -0,0 +1,303 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import copy
+import libvirt
+import os
+import stat
+
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import probe_file_permission_as_user, run_setfacl_set_attr
+from wok.xmlutils.utils import xpath_get_text
+
+from ..kvmusertests import UserTests
+from ..utils import pool_name_from_uri
+from ..vmtemplate import VMTemplate
+from cpuinfo import CPUInfoModel
+
+
+class TemplatesModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.conn = kargs['conn']
+
+ def create(self, params):
+ name = params.get('name', '').strip()
+ iso = params.get('cdrom')
+ # check search permission
+ if iso and iso.startswith('/') and os.path.exists(iso):
+ st_mode = os.stat(iso).st_mode
+ if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
+ user = UserTests().probe_user()
+ run_setfacl_set_attr(iso, user=user)
+ ret, excp = probe_file_permission_as_user(iso, user)
+ if ret is False:
+ raise InvalidParameter('KCHISO0008E',
+ {'filename': iso, 'user': user,
+ 'err': excp})
+
+ cpu_info = params.get('cpu_info')
+ if cpu_info:
+ topology = cpu_info.get('topology')
+ # Check, even though currently only topology
+ # is supported.
+ if topology:
+ sockets = topology['sockets']
+ cores = topology['cores']
+ threads = topology['threads']
+ if params.get('cpus') is None:
+ params['cpus'] = sockets * cores * threads
+ # check_topoology will raise the appropriate
+ # exception if a topology is invalid.
+ CPUInfoModel(conn=self.conn).\
+ check_topology(params['cpus'], topology)
+
+ conn = self.conn.get()
+ pool_uri = params.get(u'storagepool', '')
+ if pool_uri:
+ try:
+ pool_name = pool_name_from_uri(pool_uri)
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
+ 'template': name})
+
+ tmp_volumes = [disk['volume'] for disk in params.get('disks', [])
+ if 'volume' in disk]
+ self.template_volume_validate(tmp_volumes, pool)
+
+ for net_name in params.get(u'networks', []):
+ try:
+ conn.networkLookupByName(net_name.encode('utf-8'))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
+ 'template': name})
+ # Creates the template class with necessary information
+ # Checkings will be done while creating this class, so any exception
+ # will be raised here
+ t = LibvirtVMTemplate(params, scan=True, conn=self.conn)
+ name = params['name']
+ try:
+ with self.objstore as session:
+ if name in session.get_list('template'):
+ raise InvalidOperation("KCHTMPL0001E", {'name': name})
+ session.store('template', name, t.info)
+ except InvalidOperation:
+ raise
+ except Exception, e:
+ raise OperationFailed('KCHTMPL0020E', {'err': e.message})
+
+ return name
+
+ def get_list(self):
+ with self.objstore as session:
+ return session.get_list('template')
+
+ def template_volume_validate(self, tmp_volumes, pool):
+ kwargs = {'conn': self.conn, 'objstore': self.objstore}
+ pool_type = xpath_get_text(pool.XMLDesc(0), "/pool/@type")[0]
+ pool_name = unicode(pool.name(), 'utf-8')
+
+ # as we discussion, we do not mix disks from 2 different types of
+ # storage pools, for instance: we do not create a template with 2
+ # disks, where one comes from a SCSI pool and other is a .img in
+ # a DIR pool.
+ if pool_type in ['iscsi', 'scsi']:
+ if not tmp_volumes:
+ raise InvalidParameter("KCHTMPL0018E")
+
+ storagevolumes = __import__("kimchi.model.storagevolumes",
+ fromlist=[''])
+ pool_volumes = storagevolumes.StorageVolumesModel(
+ **kwargs).get_list(pool_name)
+ vols = set(tmp_volumes) - set(pool_volumes)
+ if vols:
+ raise InvalidParameter("KCHTMPL0019E", {'pool': pool_name,
+ 'volume': vols})
+
+
+class TemplateModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.conn = kargs['conn']
+ self.templates = TemplatesModel(**kargs)
+
+ @staticmethod
+ def get_template(name, objstore, conn, overrides=None):
+ with objstore as session:
+ params = session.get('template', name)
+ if overrides:
+ params.update(overrides)
+ return LibvirtVMTemplate(params, False, conn)
+
+ def lookup(self, name):
+ t = self.get_template(name, self.objstore, self.conn)
+ return t.validate_integrity()
+
+ def clone(self, name):
+ # set default name
+ subfixs = [v[len(name):] for v in self.templates.get_list()
+ if v.startswith(name)]
+ indexs = [int(v.lstrip("-clone")) for v in subfixs
+ if v.startswith("-clone") and
+ v.lstrip("-clone").isdigit()]
+ indexs.sort()
+ index = "1" if not indexs else str(indexs[-1] + 1)
+ clone_name = name + "-clone" + index
+
+ temp = self.lookup(name)
+ temp['name'] = clone_name
+ ident = self.templates.create(temp)
+ return ident
+
+ def delete(self, name):
+ try:
+ with self.objstore as session:
+ session.delete('template', name)
+ except NotFoundError:
+ raise
+ except Exception as e:
+ raise OperationFailed('KCHTMPL0021E', {'err': e.message})
+
+ def update(self, name, params):
+ old_t = self.lookup(name)
+ new_t = copy.copy(old_t)
+ new_t.update(params)
+
+ if not self._validate_updated_cpu_params(new_t):
+ raise InvalidParameter('KCHTMPL0025E')
+
+ ident = name
+
+ conn = self.conn.get()
+ pool_uri = new_t.get(u'storagepool', '')
+
+ if pool_uri:
+ try:
+ pool_name = pool_name_from_uri(pool_uri)
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
+ 'template': name})
+ tmp_volumes = [disk['volume'] for disk in new_t.get('disks', [])
+ if 'volume' in disk]
+ self.templates.template_volume_validate(tmp_volumes, pool)
+
+ for net_name in params.get(u'networks', []):
+ try:
+ conn.networkLookupByName(net_name.encode('utf-8'))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0003E", {'network': net_name,
+ 'template': name})
+
+ self.delete(name)
+ try:
+ ident = self.templates.create(new_t)
+ except:
+ ident = self.templates.create(old_t)
+ raise
+ return ident
+
+ def _validate_updated_cpu_params(self, info):
+ # Note: cpu_info is the parent of topology. cpus is vcpus
+ vcpus = info['cpus']
+ cpu_info = info.get('cpu_info')
+ # cpu_info will always be at least an empty dict
+ topology = cpu_info.get('topology')
+ if topology is None:
+ return True
+ return vcpus == topology['sockets'] * topology['cores'] * \
+ topology['threads']
+
+
+class LibvirtVMTemplate(VMTemplate):
+ def __init__(self, args, scan=False, conn=None):
+ self.conn = conn
+ VMTemplate.__init__(self, args, scan)
+
+ def _storage_validate(self):
+ pool_uri = self.info['storagepool']
+ pool_name = pool_name_from_uri(pool_uri)
+ try:
+ conn = self.conn.get()
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ except libvirt.libvirtError:
+ raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
+ 'template': self.name})
+
+ if not pool.isActive():
+ raise InvalidParameter("KCHTMPL0005E", {'pool': pool_name,
+ 'template': self.name})
+
+ return pool
+
+ def _get_all_networks_name(self):
+ conn = self.conn.get()
+ return sorted(conn.listNetworks() + conn.listDefinedNetworks())
+
+ def _get_all_storagepools_name(self):
+ conn = self.conn.get()
+ names = conn.listStoragePools() + conn.listDefinedStoragePools()
+ return sorted(map(lambda x: x.decode('utf-8'), names))
+
+ def _network_validate(self):
+ names = self.info['networks']
+ for name in names:
+ try:
+ conn = self.conn.get()
+ network = conn.networkLookupByName(name.encode('utf-8'))
+ except libvirt.libvirtError:
+ raise InvalidParameter("KCHTMPL0003E", {'network': name,
+ 'template': self.name})
+
+ if not network.isActive():
+ raise InvalidParameter("KCHTMPL0007E", {'network': name,
+ 'template': self.name})
+
+ def _get_storage_path(self):
+ pool = self._storage_validate()
+ xml = pool.XMLDesc(0)
+ return xpath_get_text(xml, "/pool/target/path")[0]
+
+ def _get_storage_type(self):
+ pool = self._storage_validate()
+ xml = pool.XMLDesc(0)
+ return xpath_get_text(xml, "/pool/@type")[0]
+
+ def _get_volume_path(self, pool, vol):
+ pool = self._storage_validate()
+ try:
+ return pool.storageVolLookupByName(vol).path()
+ except:
+ raise NotFoundError("KCHVOL0002E", {'name': vol,
+ 'pool': pool})
+
+ def fork_vm_storage(self, vm_uuid):
+ # Provision storage:
+ # TODO: Rebase on the storage API once upstream
+ pool = self._storage_validate()
+ vol_list = self.to_volume_list(vm_uuid)
+ try:
+ for v in vol_list:
+ # outgoing text to libvirt, encode('utf-8')
+ pool.createXML(v['xml'].encode('utf-8'), 0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
+ return vol_list
diff --git a/src/wok/plugins/kimchi/model/users.py b/src/wok/plugins/kimchi/model/users.py
new file mode 100644
index 0000000..2fa65dd
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/users.py
@@ -0,0 +1,90 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ldap
+import pwd
+
+from wok.config import config
+from wok.exception import NotFoundError
+
+
+class UsersModel(object):
+ def __init__(self, **args):
+ auth_type = config.get("authentication", "method")
+ for klass in UsersModel.__subclasses__():
+ if auth_type == klass.auth_type:
+ self.user = klass(**args)
+
+ def get_list(self, **args):
+ return self.user._get_list(**args)
+
+ def validate(self, user):
+ return self.user._validate(user)
+
+
+class PAMUsersModel(UsersModel):
+ auth_type = 'pam'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _get_list(self):
+ return [user.pw_name for user in pwd.getpwall()
+ if user.pw_shell.rsplit("/")[-1] not in ["nologin", "false"]]
+
+ def _validate(self, user):
+ try:
+ return user in self._get_list()
+ except:
+ return False
+
+
+class LDAPUsersModel(UsersModel):
+ auth_type = 'ldap'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _get_list(self, _user_id=''):
+ return self._get_user(_user_id)
+
+ def _validate(self, user):
+ try:
+ self._get_user(user)
+ return True
+ except NotFoundError:
+ return False
+
+ def _get_user(self, _user_id):
+ ldap_server = config.get("authentication", "ldap_server").strip('"')
+ ldap_search_base = config.get(
+ "authentication", "ldap_search_base").strip('"')
+ ldap_search_filter = config.get(
+ "authentication", "ldap_search_filter",
+ vars={"username": _user_id.encode("utf-8")}).strip('"')
+
+ connect = ldap.open(ldap_server)
+ try:
+ result = connect.search_s(
+ ldap_search_base, ldap.SCOPE_SUBTREE, ldap_search_filter)
+ if len(result) == 0:
+ raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
+ return result[0][1]
+ except ldap.NO_SUCH_OBJECT:
+ raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
diff --git a/src/wok/plugins/kimchi/model/utils.py b/src/wok/plugins/kimchi/model/utils.py
new file mode 100644
index 0000000..53d719d
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/utils.py
@@ -0,0 +1,161 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+from lxml import etree, objectify
+from lxml.builder import E, ElementMaker
+
+from wok.exception import OperationFailed
+
+
+KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi"
+KIMCHI_NAMESPACE = "kimchi"
+
+
+def get_vm_name(vm_name, t_name, name_list):
+ if vm_name:
+ return vm_name
+ for i in xrange(1, 1000):
+ # VM will have templace name, but without slashes
+ vm_name = "%s-vm-%i" % (t_name.replace('/', '-'), i)
+ if vm_name not in name_list:
+ return vm_name
+ raise OperationFailed("KCHUTILS0003E")
+
+
+def get_vm_config_flag(dom, mode="persistent"):
+ # libvirt.VIR_DOMAIN_AFFECT_CURRENT is 0
+ # VIR_DOMAIN_AFFECT_LIVE is 1, VIR_DOMAIN_AFFECT_CONFIG is 2
+ flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE,
+ "persistent": libvirt.VIR_DOMAIN_AFFECT_CONFIG,
+ "current": libvirt.VIR_DOMAIN_AFFECT_CURRENT,
+ "all": libvirt.VIR_DOMAIN_AFFECT_CONFIG +
+ libvirt.VIR_DOMAIN_AFFECT_LIVE if dom.isActive() and
+ dom.isPersistent() else libvirt.VIR_DOMAIN_AFFECT_CURRENT}
+
+ return flag[mode]
+
+
+# avoid duplicate codes
+def update_node(root, node):
+ old_node = root.find(node.tag)
+ (root.replace(old_node, node) if old_node is not None
+ else root.append(node))
+ return root
+
+
+def _kimchi_set_metadata_node(dom, node):
+ # some other tools will not let libvirt create a persistent
+ # configuration, raise exception.
+ if not dom.isPersistent():
+ msg = 'The VM has not a persistent configuration'
+ raise OperationFailed("KCHVM0030E",
+ {'name': dom.name(), "err": msg})
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+ kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
+
+ EM = ElementMaker(namespace=KIMCHI_META_URL,
+ nsmap={KIMCHI_NAMESPACE: KIMCHI_META_URL})
+ kimchi = EM("kimchi") if kimchi is None else kimchi
+
+ update_node(kimchi, node)
+ metadata = root.find("metadata")
+ metadata = E.metadata() if metadata is None else metadata
+ update_node(metadata, kimchi)
+ update_node(root, metadata)
+ dom.connect().defineXML(etree.tostring(root))
+
+
+def libvirt_get_kimchi_metadata_node(dom, mode="current"):
+ if not metadata_exists(dom):
+ return None
+ try:
+ xml = dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
+ KIMCHI_META_URL,
+ flags=get_vm_config_flag(dom, mode))
+ return etree.fromstring(xml)
+ except libvirt.libvirtError:
+ return None
+
+
+def set_metadata_node(dom, node, metadata_support, mode="all"):
+ if metadata_support:
+ kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
+ kimchi = E.metadata(E.kimchi()) if kimchi is None else kimchi
+
+ update_node(kimchi, node)
+ kimchi_xml = etree.tostring(kimchi)
+ # From libvirt doc, Passing None for @metadata says to remove that
+ # element from the domain XML (passing the empty string leaves the
+ # element present). Do not support remove the old metadata.
+ dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, kimchi_xml,
+ KIMCHI_NAMESPACE, KIMCHI_META_URL,
+ flags=get_vm_config_flag(dom, mode))
+ else:
+ # FIXME remove this code when all distro libvirt supports metadata
+ # element
+ _kimchi_set_metadata_node(dom, node)
+
+
+def _kimchi_get_metadata_node(dom, tag):
+ # some other tools will not let libvirt create a persistent
+ # configuration, just return empty
+ if not dom.isPersistent():
+ return None
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+ kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
+ # remove the "kimchi" prefix of xml
+ if kimchi is not None:
+ for elem in kimchi.getiterator():
+ if not hasattr(elem.tag, 'find'):
+ continue
+ i = elem.tag.find('}')
+ if i >= 0:
+ elem.tag = elem.tag[i+1:]
+
+ objectify.deannotate(kimchi)
+ etree.cleanup_namespaces(kimchi)
+ return kimchi
+ return None
+
+
+def get_metadata_node(dom, tag, metadata_support, mode="current"):
+ if metadata_support:
+ kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
+ else:
+ # FIXME remove this code when all distro libvirt supports metadata
+ # element
+ kimchi = _kimchi_get_metadata_node(dom, tag)
+
+ if kimchi is not None:
+ node = kimchi.find(tag)
+ if node is not None:
+ return etree.tostring(node)
+ return ""
+
+
+def metadata_exists(dom):
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+
+ if root.find("metadata") is None:
+ return False
+ return True
diff --git a/src/wok/plugins/kimchi/model/vmhostdevs.py b/src/wok/plugins/kimchi/model/vmhostdevs.py
new file mode 100644
index 0000000..0cc6bd3
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmhostdevs.py
@@ -0,0 +1,336 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import glob
+import libvirt
+import os
+import platform
+from lxml import etree, objectify
+from lxml.builder import E
+
+from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
+from wok.exception import OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import run_command, wok_log
+
+from config import CapabilitiesModel
+from host import DeviceModel, DevicesModel
+from utils import get_vm_config_flag
+from vms import DOM_STATE_MAP, VMModel
+
+
+class VMHostDevsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def get_list(self, vmid):
+ dom = VMModel.get_vm(vmid, self.conn)
+ xmlstr = dom.XMLDesc(0)
+ root = objectify.fromstring(xmlstr)
+ try:
+ hostdev = root.devices.hostdev
+ except AttributeError:
+ return []
+
+ return [self._deduce_dev_name(e) for e in hostdev]
+
+ @staticmethod
+ def _toint(num_str):
+ if num_str.startswith('0x'):
+ return int(num_str, 16)
+ elif num_str.startswith('0'):
+ return int(num_str, 8)
+ else:
+ return int(num_str)
+
+ def _deduce_dev_name(self, e):
+ return getattr(self, '_deduce_dev_name_%s' % e.attrib['type'])(e)
+
+ def _deduce_dev_name_pci(self, e):
+ attrib = {}
+ for field in ('domain', 'bus', 'slot', 'function'):
+ attrib[field] = self._toint(e.source.address.attrib[field])
+ return 'pci_%(domain)04x_%(bus)02x_%(slot)02x_%(function)x' % attrib
+
+ def _deduce_dev_name_scsi(self, e):
+ attrib = {}
+ for field in ('bus', 'target', 'unit'):
+ attrib[field] = self._toint(e.source.address.attrib[field])
+ attrib['host'] = self._toint(
+ e.source.adapter.attrib['name'][len('scsi_host'):])
+ return 'scsi_%(host)d_%(bus)d_%(target)d_%(unit)d' % attrib
+
+ def _deduce_dev_name_usb(self, e):
+ dev_names = DevicesModel(conn=self.conn).get_list(_cap='usb_device')
+ usb_infos = [DeviceModel(conn=self.conn).lookup(dev_name)
+ for dev_name in dev_names]
+
+ unknown_dev = None
+
+ try:
+ evendor = self._toint(e.source.vendor.attrib['id'])
+ eproduct = self._toint(e.source.product.attrib['id'])
+ except AttributeError:
+ evendor = 0
+ eproduct = 0
+ else:
+ unknown_dev = 'usb_vendor_%s_product_%s' % (evendor, eproduct)
+
+ try:
+ ebus = self._toint(e.source.address.attrib['bus'])
+ edevice = self._toint(e.source.address.attrib['device'])
+ except AttributeError:
+ ebus = -1
+ edevice = -1
+ else:
+ unknown_dev = 'usb_bus_%s_device_%s' % (ebus, edevice)
+
+ for usb_info in usb_infos:
+ ivendor = self._toint(usb_info['vendor']['id'])
+ iproduct = self._toint(usb_info['product']['id'])
+ if evendor == ivendor and eproduct == iproduct:
+ return usb_info['name']
+ ibus = usb_info['bus']
+ idevice = usb_info['device']
+ if ebus == ibus and edevice == idevice:
+ return usb_info['name']
+ return unknown_dev
+
+ def _passthrough_device_validate(self, dev_name):
+ eligible_dev_names = \
+ DevicesModel(conn=self.conn).get_list(_passthrough='true')
+ if dev_name not in eligible_dev_names:
+ raise InvalidParameter('KCHVMHDEV0002E', {'dev_name': dev_name})
+
+ def create(self, vmid, params):
+ dev_name = params['name']
+ self._passthrough_device_validate(dev_name)
+ dev_info = DeviceModel(conn=self.conn).lookup(dev_name)
+
+ with RollbackContext() as rollback:
+ try:
+ dev = self.conn.get().nodeDeviceLookupByName(dev_name)
+ dev.dettach()
+ except Exception:
+ raise OperationFailed('KCHVMHDEV0005E', {'name': dev_name})
+ else:
+ rollback.prependDefer(dev.reAttach)
+
+ attach_device = getattr(
+ self, '_attach_%s_device' % dev_info['device_type'])
+
+ info = attach_device(vmid, dev_info)
+ rollback.commitAll()
+
+ return info
+
+ def _get_pci_device_xml(self, dev_info):
+ if 'detach_driver' not in dev_info:
+ dev_info['detach_driver'] = 'kvm'
+
+ source = E.source(E.address(domain=str(dev_info['domain']),
+ bus=str(dev_info['bus']),
+ slot=str(dev_info['slot']),
+ function=str(dev_info['function'])))
+ driver = E.driver(name=dev_info['detach_driver'])
+ host_dev = E.hostdev(source, driver,
+ mode='subsystem', type='pci', managed='yes')
+
+ return etree.tostring(host_dev)
+
+ @staticmethod
+ def _validate_pci_passthrough_env():
+ # Linux kernel < 3.5 doesn't provide /sys/kernel/iommu_groups
+ if os.path.isdir('/sys/kernel/iommu_groups'):
+ if not glob.glob('/sys/kernel/iommu_groups/*'):
+ raise InvalidOperation("KCHVMHDEV0003E")
+
+ # Enable virt_use_sysfs on RHEL6 and older distributions
+ # In recent Fedora, there is no virt_use_sysfs.
+ out, err, rc = run_command(['getsebool', 'virt_use_sysfs'])
+ if rc == 0 and out.rstrip('\n') != "virt_use_sysfs --> on":
+ out, err, rc = run_command(['setsebool', '-P',
+ 'virt_use_sysfs=on'])
+ if rc != 0:
+ wok_log.warning("Unable to turn on sebool virt_use_sysfs")
+
+ def _attach_pci_device(self, vmid, dev_info):
+ self._validate_pci_passthrough_env()
+
+ dom = VMModel.get_vm(vmid, self.conn)
+ # Due to libvirt limitation, we don't support live assigne device to
+ # vfio driver.
+ driver = ('vfio' if DOM_STATE_MAP[dom.info()[0]] == "shutoff" and
+ self.caps.kernel_vfio else 'kvm')
+
+ # on powerkvm systems it must be vfio driver.
+ distro, _, _ = platform.linux_distribution()
+ if distro == 'IBM_PowerKVM':
+ driver = 'vfio'
+
+ # Attach all PCI devices in the same IOMMU group
+ dev_model = DeviceModel(conn=self.conn)
+ devs_model = DevicesModel(conn=self.conn)
+ affected_names = devs_model.get_list(
+ _passthrough_affected_by=dev_info['name'])
+ passthrough_names = devs_model.get_list(
+ _cap='pci', _passthrough='true')
+ group_names = list(set(affected_names) & set(passthrough_names))
+ pci_infos = [dev_model.lookup(dev_name) for dev_name in group_names]
+ pci_infos.append(dev_info)
+
+ device_flags = get_vm_config_flag(dom, mode='all')
+
+ with RollbackContext() as rollback:
+ for pci_info in pci_infos:
+ pci_info['detach_driver'] = driver
+ xmlstr = self._get_pci_device_xml(pci_info)
+ try:
+ dom.attachDeviceFlags(xmlstr, device_flags)
+ except libvirt.libvirtError:
+ wok_log.error(
+ 'Failed to attach host device %s to VM %s: \n%s',
+ pci_info['name'], vmid, xmlstr)
+ raise
+ rollback.prependDefer(dom.detachDeviceFlags,
+ xmlstr, device_flags)
+ rollback.commitAll()
+
+ return dev_info['name']
+
+ def _get_scsi_device_xml(self, dev_info):
+ adapter = E.adapter(name=('scsi_host%s' % dev_info['host']))
+ address = E.address(type='scsi', bus=str(dev_info['bus']),
+ target=str(dev_info['target']),
+ unit=str(dev_info['lun']))
+ host_dev = E.hostdev(E.source(adapter, address),
+ mode='subsystem', type='scsi', sgio='unfiltered')
+ return etree.tostring(host_dev)
+
+ def _attach_scsi_device(self, vmid, dev_info):
+ xmlstr = self._get_scsi_device_xml(dev_info)
+ dom = VMModel.get_vm(vmid, self.conn)
+ dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
+ return dev_info['name']
+
+ def _get_usb_device_xml(self, dev_info):
+ source = E.source(
+ E.vendor(id=dev_info['vendor']['id']),
+ E.product(id=dev_info['product']['id']),
+ E.address(bus=str(dev_info['bus']),
+ device=str(dev_info['device'])),
+ startupPolicy='optional')
+ host_dev = E.hostdev(source, mode='subsystem',
+ ype='usb', managed='yes')
+ return etree.tostring(host_dev)
+
+ def _attach_usb_device(self, vmid, dev_info):
+ xmlstr = self._get_usb_device_xml(dev_info)
+ dom = VMModel.get_vm(vmid, self.conn)
+ dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
+ return dev_info['name']
+
+
+class VMHostDevModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def lookup(self, vmid, dev_name):
+ dom = VMModel.get_vm(vmid, self.conn)
+ xmlstr = dom.XMLDesc(0)
+ root = objectify.fromstring(xmlstr)
+ try:
+ hostdev = root.devices.hostdev
+ except AttributeError:
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ devsmodel = VMHostDevsModel(conn=self.conn)
+
+ for e in hostdev:
+ deduced_name = devsmodel._deduce_dev_name(e)
+ if deduced_name == dev_name:
+ return {'name': dev_name, 'type': e.attrib['type']}
+
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ def delete(self, vmid, dev_name):
+ dom = VMModel.get_vm(vmid, self.conn)
+ xmlstr = dom.XMLDesc(0)
+ root = objectify.fromstring(xmlstr)
+
+ try:
+ hostdev = root.devices.hostdev
+ except AttributeError:
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ devsmodel = VMHostDevsModel(conn=self.conn)
+ pci_devs = [(devsmodel._deduce_dev_name(e), e) for e in hostdev
+ if e.attrib['type'] == 'pci']
+
+ for e in hostdev:
+ if devsmodel._deduce_dev_name(e) == dev_name:
+ xmlstr = etree.tostring(e)
+ dom.detachDeviceFlags(
+ xmlstr, get_vm_config_flag(dom, mode='all'))
+ if e.attrib['type'] == 'pci':
+ self._delete_affected_pci_devices(dom, dev_name, pci_devs)
+ break
+ else:
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ def _delete_affected_pci_devices(self, dom, dev_name, pci_devs):
+ dev_model = DeviceModel(conn=self.conn)
+ try:
+ dev_model.lookup(dev_name)
+ except NotFoundError:
+ return
+
+ affected_names = set(
+ DevicesModel(
+ conn=self.conn).get_list(_passthrough_affected_by=dev_name))
+
+ for pci_name, e in pci_devs:
+ if pci_name in affected_names:
+ xmlstr = etree.tostring(e)
+ dom.detachDeviceFlags(
+ xmlstr, get_vm_config_flag(dom, mode='all'))
+
+
+class VMHoldersModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def get_list(self, device_id):
+ devsmodel = VMHostDevsModel(conn=self.conn)
+
+ conn = self.conn.get()
+ doms = conn.listAllDomains(0)
+
+ res = []
+ for dom in doms:
+ dom_name = dom.name()
+ if device_id in devsmodel.get_list(dom_name):
+ state = DOM_STATE_MAP[dom.info()[0]]
+ res.append({"name": dom_name, "state": state})
+ return res
diff --git a/src/wok/plugins/kimchi/model/vmifaces.py b/src/wok/plugins/kimchi/model/vmifaces.py
new file mode 100644
index 0000000..87565c8
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmifaces.py
@@ -0,0 +1,186 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import random
+from lxml import etree, objectify
+
+from wok.exception import InvalidParameter, MissingParameter
+from wok.exception import NotFoundError, InvalidOperation
+
+from ..xmlutils.interface import get_iface_xml
+from config import CapabilitiesModel
+from vms import DOM_STATE_MAP, VMModel
+
+
+class VMIfacesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def get_list(self, vm):
+ macs = []
+ for iface in self.get_vmifaces(vm, self.conn):
+ macs.append(iface.mac.get('address'))
+ return macs
+
+ def create(self, vm, params):
+ conn = self.conn.get()
+ networks = conn.listNetworks() + conn.listDefinedNetworks()
+ networks = map(lambda x: x.decode('utf-8'), networks)
+
+ if params['type'] == 'network':
+ network = params.get("network")
+
+ if network is None:
+ raise MissingParameter('KCHVMIF0007E')
+
+ if network not in networks:
+ raise InvalidParameter('KCHVMIF0002E',
+ {'name': vm, 'network': network})
+
+ macs = (iface.mac.get('address')
+ for iface in self.get_vmifaces(vm, self.conn))
+
+ # user defined customized mac address
+ if 'mac' in params and params['mac']:
+ # make sure it is unique
+ if params['mac'] in macs:
+ raise InvalidParameter('KCHVMIF0009E',
+ {'name': vm, 'mac': params['mac']})
+
+ # otherwise choose a random mac address
+ else:
+ while True:
+ params['mac'] = VMIfacesModel.random_mac()
+ if params['mac'] not in macs:
+ break
+
+ dom = VMModel.get_vm(vm, self.conn)
+
+ os_data = VMModel.vm_get_os_metadata(dom, self.caps.metadata_support)
+ os_version, os_distro = os_data
+ xml = get_iface_xml(params, conn.getInfo()[0], os_distro, os_version)
+
+ flags = 0
+ if dom.isPersistent():
+ flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
+ if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
+ flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
+
+ dom.attachDeviceFlags(xml, flags)
+
+ return params['mac']
+
+ @staticmethod
+ def get_vmifaces(vm, conn):
+ dom = VMModel.get_vm(vm, conn)
+ xml = dom.XMLDesc(0)
+ root = objectify.fromstring(xml)
+
+ return root.devices.findall("interface")
+
+ @staticmethod
+ def random_mac():
+ mac = [0x52, 0x54, 0x00,
+ random.randint(0x00, 0x7f),
+ random.randint(0x00, 0xff),
+ random.randint(0x00, 0xff)]
+ return ':'.join(map(lambda x: u'%02x' % x, mac))
+
+
+class VMIfaceModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def _get_vmiface(self, vm, mac):
+ ifaces = VMIfacesModel.get_vmifaces(vm, self.conn)
+
+ for iface in ifaces:
+ if iface.mac.get('address') == mac:
+ return iface
+ return None
+
+ def lookup(self, vm, mac):
+ info = {}
+
+ iface = self._get_vmiface(vm, mac)
+ if iface is None:
+ raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
+
+ info['type'] = iface.attrib['type']
+ info['mac'] = iface.mac.get('address')
+ if iface.find("model") is not None:
+ info['model'] = iface.model.get('type')
+ if info['type'] == 'network':
+ info['network'] = iface.source.get('network')
+ if info['type'] == 'bridge':
+ info['bridge'] = iface.source.get('bridge')
+
+ return info
+
+ def delete(self, vm, mac):
+ dom = VMModel.get_vm(vm, self.conn)
+ iface = self._get_vmiface(vm, mac)
+
+ if iface is None:
+ raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
+
+ flags = 0
+ if dom.isPersistent():
+ flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
+ if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
+ flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
+
+ dom.detachDeviceFlags(etree.tostring(iface), flags)
+
+ def update(self, vm, mac, params):
+ dom = VMModel.get_vm(vm, self.conn)
+ iface = self._get_vmiface(vm, mac)
+
+ if iface is None:
+ raise NotFoundError("KCHVMIF0001E", {'name': vm, 'iface': mac})
+
+ # cannot change mac address in a running system
+ if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
+ raise InvalidOperation('KCHVMIF0011E')
+
+ # mac address is a required parameter
+ if 'mac' not in params:
+ raise MissingParameter('KCHVMIF0008E')
+
+ # new mac address must be unique
+ if self._get_vmiface(vm, params['mac']) is not None:
+ raise InvalidParameter('KCHVMIF0009E',
+ {'name': vm, 'mac': params['mac']})
+
+ flags = 0
+ if dom.isPersistent():
+ flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
+
+ # remove the current nic
+ xml = etree.tostring(iface)
+ dom.detachDeviceFlags(xml, flags=flags)
+
+ # add the nic with the desired mac address
+ iface.mac.attrib['address'] = params['mac']
+ xml = etree.tostring(iface)
+ dom.attachDeviceFlags(xml, flags=flags)
+
+ return [vm, params['mac']]
diff --git a/src/wok/plugins/kimchi/model/vms.py b/src/wok/plugins/kimchi/model/vms.py
new file mode 100644
index 0000000..f37b5d6
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vms.py
@@ -0,0 +1,1307 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import os
+import random
+import string
+import time
+import uuid
+from lxml import etree, objectify
+from lxml.builder import E
+from xml.etree import ElementTree
+
+from wok.config import config
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import add_task, convert_data_size, get_next_clone_name
+from wok.utils import import_class, run_setfacl_set_attr, wok_log
+from wok.xmlutils.utils import xpath_get_text, xml_item_update
+from wok.xmlutils.utils import dictize
+from wok.model.tasks import TaskModel
+
+from .. import model
+from .. import vnc
+from ..config import READONLY_POOL_TYPE
+from ..kvmusertests import UserTests
+from ..screenshot import VMScreenshot
+from ..utils import template_name_from_uri
+from ..xmlutils.cpu import get_cpu_xml, get_numa_xml
+from config import CapabilitiesModel
+from templates import TemplateModel
+from utils import get_vm_name
+from utils import get_metadata_node
+from utils import set_metadata_node
+
+
+DOM_STATE_MAP = {0: 'nostate',
+ 1: 'running',
+ 2: 'blocked',
+ 3: 'paused',
+ 4: 'shutdown',
+ 5: 'shutoff',
+ 6: 'crashed',
+ 7: 'pmsuspended'}
+
+VM_STATIC_UPDATE_PARAMS = {'name': './name',
+ 'cpus': './vcpu'}
+VM_LIVE_UPDATE_PARAMS = {}
+
+XPATH_DOMAIN_DISK = "/domain/devices/disk[@device='disk']/source/@file"
+XPATH_DOMAIN_DISK_BY_FILE = "./devices/disk[@device='disk']/source[@file='%s']"
+XPATH_DOMAIN_NAME = '/domain/name'
+XPATH_DOMAIN_MAC = "/domain/devices/interface[@type='network']/mac/@address"
+XPATH_DOMAIN_MAC_BY_ADDRESS = "./devices/interface[@type='network']/"\
+ "mac[@address='%s']"
+XPATH_DOMAIN_MEMORY = '/domain/memory'
+XPATH_DOMAIN_MEMORY_UNIT = '/domain/memory/@unit'
+XPATH_DOMAIN_UUID = '/domain/uuid'
+
+XPATH_NUMA_CELL = './cpu/numa/cell'
+
+
+class VMsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+ self.task = TaskModel(**kargs)
+
+ def create(self, params):
+ t_name = template_name_from_uri(params['template'])
+ vm_list = self.get_list()
+ name = get_vm_name(params.get('name'), t_name, vm_list)
+ # incoming text, from js json, is unicode, do not need decode
+ if name in vm_list:
+ raise InvalidOperation("KCHVM0001E", {'name': name})
+
+ vm_overrides = dict()
+ pool_uri = params.get('storagepool')
+ if pool_uri:
+ vm_overrides['storagepool'] = pool_uri
+ vm_overrides['fc_host_support'] = self.caps.fc_host_support
+ t = TemplateModel.get_template(t_name, self.objstore, self.conn,
+ vm_overrides)
+
+ if not self.caps.qemu_stream and t.info.get('iso_stream', False):
+ raise InvalidOperation("KCHVM0005E")
+
+ t.validate()
+ data = {'name': name, 'template': t,
+ 'graphics': params.get('graphics', {})}
+ taskid = add_task(u'/plugins/kimchi/vms/%s' % name, self._create_task,
+ self.objstore, data)
+
+ return self.task.lookup(taskid)
+
+ def _create_task(self, cb, params):
+ """
+ params: A dict with the following values:
+ - vm_uuid: The UUID of the VM being created
+ - template: The template being used to create the VM
+ - name: The name for the new VM
+ """
+ vm_uuid = str(uuid.uuid4())
+ t = params['template']
+ name = params['name']
+ conn = self.conn.get()
+
+ cb('Storing VM icon')
+ # Store the icon for displaying later
+ icon = t.info.get('icon')
+ if icon:
+ try:
+ with self.objstore as session:
+ session.store('vm', vm_uuid, {'icon': icon})
+ except Exception as e:
+ # It is possible to continue Kimchi executions without store
+ # vm icon info
+ wok_log.error('Error trying to update database with guest '
+ 'icon information due error: %s', e.message)
+
+ # If storagepool is SCSI, volumes will be LUNs and must be passed by
+ # the user from UI or manually.
+ cb('Provisioning storage for new VM')
+ vol_list = []
+ if t._get_storage_type() not in ["iscsi", "scsi"]:
+ vol_list = t.fork_vm_storage(vm_uuid)
+
+ graphics = params.get('graphics', {})
+ stream_protocols = self.caps.libvirt_stream_protocols
+ xml = t.to_vm_xml(name, vm_uuid,
+ libvirt_stream_protocols=stream_protocols,
+ graphics=graphics,
+ volumes=vol_list)
+
+ cb('Defining new VM')
+ try:
+ conn.defineXML(xml.encode('utf-8'))
+ except libvirt.libvirtError as e:
+ if t._get_storage_type() not in READONLY_POOL_TYPE:
+ for v in vol_list:
+ vol = conn.storageVolLookupByPath(v['path'])
+ vol.delete(0)
+ raise OperationFailed("KCHVM0007E", {'name': name,
+ 'err': e.get_error_message()})
+
+ cb('Updating VM metadata')
+ VMModel.vm_update_os_metadata(VMModel.get_vm(name, self.conn), t.info,
+ self.caps.metadata_support)
+ cb('OK', True)
+
+ def get_list(self):
+ return VMsModel.get_vms(self.conn)
+
+ @staticmethod
+ def get_vms(conn):
+ conn_ = conn.get()
+ names = [dom.name().decode('utf-8') for dom in conn_.listAllDomains(0)]
+ names = sorted(names, key=unicode.lower)
+ return names
+
+
+class VMModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+ self.vmscreenshot = VMScreenshotModel(**kargs)
+ self.users = import_class(
+ 'plugins.kimchi.model.users.UsersModel'
+ )(**kargs)
+ self.groups = import_class(
+ 'plugins.kimchi.model.groups.GroupsModel'
+ )(**kargs)
+ self.vms = VMsModel(**kargs)
+ self.task = TaskModel(**kargs)
+ self.storagepool = model.storagepools.StoragePoolModel(**kargs)
+ self.storagevolume = model.storagevolumes.StorageVolumeModel(**kargs)
+ self.storagevolumes = model.storagevolumes.StorageVolumesModel(**kargs)
+ cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotModel')
+ self.vmsnapshot = cls(**kargs)
+ cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotsModel')
+ self.vmsnapshots = cls(**kargs)
+ self.stats = {}
+
+ def update(self, name, params):
+ dom = self.get_vm(name, self.conn)
+ dom = self._static_vm_update(dom, params)
+ self._live_vm_update(dom, params)
+ return dom.name().decode('utf-8')
+
+ def clone(self, name):
+ """Clone a virtual machine based on an existing one.
+
+ The new virtual machine will have the exact same configuration as the
+ original VM, except for the name, UUID, MAC addresses and disks. The
+ name will have the form "<name>-clone-<number>", with <number> starting
+ at 1; the UUID will be generated randomly; the MAC addresses will be
+ generated randomly with no conflicts within the original and the new
+ VM; and the disks will be new volumes [mostly] on the same storage
+ pool, with the same content as the original disks. The storage pool
+ 'default' will always be used when cloning SCSI and iSCSI disks and
+ when the original storage pool cannot hold the new volume.
+
+ An exception will be raised if the virtual machine <name> is not
+ shutoff, if there is no available space to copy a new volume to the
+ storage pool 'default' (when there was also no space to copy it to the
+ original storage pool) and if one of the virtual machine's disks belong
+ to a storage pool not supported by Kimchi.
+
+ Parameters:
+ name -- The name of the existing virtual machine to be cloned.
+
+ Return:
+ A Task running the clone operation.
+ """
+ name = name.decode('utf-8')
+
+ # VM must be shutoff in order to clone it
+ info = self.lookup(name)
+ if info['state'] != u'shutoff':
+ raise InvalidParameter('KCHVM0033E', {'name': name})
+
+ # the new VM's name will be used as the Task's 'target_uri' so it needs
+ # to be defined now.
+
+ vms_being_created = []
+
+ # lookup names of VMs being created right now
+ with self.objstore as session:
+ task_names = session.get_list('task')
+ for tn in task_names:
+ t = session.get('task', tn)
+ if t['target_uri'].startswith('/plugins/kimchi/vms/'):
+ uri_name = t['target_uri'].lstrip('/plugins/kimchi/vms/')
+ vms_being_created.append(uri_name)
+
+ current_vm_names = self.vms.get_list() + vms_being_created
+ new_name = get_next_clone_name(current_vm_names, name)
+
+ # create a task with the actual clone function
+ taskid = add_task(u'/plugins/kimchi/vms/%s/clone' % new_name,
+ self._clone_task, self.objstore,
+ {'name': name, 'new_name': new_name})
+
+ return self.task.lookup(taskid)
+
+ def _clone_task(self, cb, params):
+ """Asynchronous function which performs the clone operation.
+
+ Parameters:
+ cb -- A callback function to signal the Task's progress.
+ params -- A dict with the following values:
+ "name": the name of the original VM.
+ "new_name": the name of the new VM.
+ """
+ name = params['name']
+ new_name = params['new_name']
+ vir_conn = self.conn.get()
+
+ # fetch base XML
+ cb('reading source VM XML')
+ try:
+ vir_dom = vir_conn.lookupByName(name)
+ flags = libvirt.VIR_DOMAIN_XML_SECURE
+ xml = vir_dom.XMLDesc(flags).decode('utf-8')
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0035E', {'name': name,
+ 'err': e.message})
+
+ # update UUID
+ cb('updating VM UUID')
+ old_uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
+ new_uuid = unicode(uuid.uuid4())
+ xml = xml_item_update(xml, './uuid', new_uuid)
+
+ # update MAC addresses
+ cb('updating VM MAC addresses')
+ xml = self._clone_update_mac_addresses(xml)
+
+ with RollbackContext() as rollback:
+ # copy disks
+ cb('copying VM disks')
+ xml = self._clone_update_disks(xml, rollback)
+
+ # update objstore entry
+ cb('updating object store')
+ self._clone_update_objstore(old_uuid, new_uuid, rollback)
+
+ # update name
+ cb('updating VM name')
+ xml = xml_item_update(xml, './name', new_name)
+
+ # create new guest
+ cb('defining new VM')
+ try:
+ vir_conn.defineXML(xml)
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0035E', {'name': name,
+ 'err': e.message})
+
+ rollback.commitAll()
+
+ cb('OK', True)
+
+ @staticmethod
+ def _clone_update_mac_addresses(xml):
+ """Update the MAC addresses with new values in the XML descriptor of a
+ cloning domain.
+
+ The new MAC addresses will be generated randomly, and their values are
+ guaranteed to be distinct from the ones in the original VM.
+
+ Arguments:
+ xml -- The XML descriptor of the original domain.
+
+ Return:
+ The XML descriptor <xml> with the new MAC addresses instead of the
+ old ones.
+ """
+ old_macs = xpath_get_text(xml, XPATH_DOMAIN_MAC)
+ new_macs = []
+
+ for mac in old_macs:
+ while True:
+ new_mac = model.vmifaces.VMIfacesModel.random_mac()
+ # make sure the new MAC doesn't conflict with the original VM
+ # and with the new values on the new VM.
+ if new_mac not in (old_macs + new_macs):
+ new_macs.append(new_mac)
+ break
+
+ xml = xml_item_update(xml, XPATH_DOMAIN_MAC_BY_ADDRESS % mac,
+ new_mac, 'address')
+
+ return xml
+
+ def _clone_update_disks(self, xml, rollback):
+ """Clone disks from a virtual machine. The disks are copied as new
+ volumes and the new VM's XML is updated accordingly.
+
+ Arguments:
+ xml -- The XML descriptor of the original VM + new value for
+ "/domain/uuid".
+ rollback -- A rollback context so the new volumes can be removed if an
+ error occurs during the cloning operation.
+
+ Return:
+ The XML descriptor <xml> with the new disk paths instead of the
+ old ones.
+ """
+ # the UUID will be used to create the disk paths
+ uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
+ all_paths = xpath_get_text(xml, XPATH_DOMAIN_DISK)
+
+ vir_conn = self.conn.get()
+
+ def _delete_disk_from_objstore(path):
+ with self.objstore as session:
+ session.delete('storagevolume', path)
+
+ domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
+
+ for i, path in enumerate(all_paths):
+ try:
+ vir_orig_vol = vir_conn.storageVolLookupByPath(path)
+ vir_pool = vir_orig_vol.storagePoolLookupByVolume()
+
+ orig_pool_name = vir_pool.name().decode('utf-8')
+ orig_vol_name = vir_orig_vol.name().decode('utf-8')
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0035E', {'name': domain_name,
+ 'err': e.message})
+
+ orig_pool = self.storagepool.lookup(orig_pool_name)
+ orig_vol = self.storagevolume.lookup(orig_pool_name, orig_vol_name)
+
+ new_pool_name = orig_pool_name
+ new_pool = orig_pool
+
+ if orig_pool['type'] in ['dir', 'netfs', 'logical']:
+ # if a volume in a pool 'dir', 'netfs' or 'logical' cannot hold
+ # a new volume with the same size, the pool 'default' should
+ # be used
+ if orig_vol['capacity'] > orig_pool['available']:
+ wok_log.warning('storage pool \'%s\' doesn\'t have '
+ 'enough free space to store image '
+ '\'%s\'; falling back to \'default\'',
+ orig_pool_name, path)
+ new_pool_name = u'default'
+ new_pool = self.storagepool.lookup(u'default')
+
+ # ...and if even the pool 'default' cannot hold a new
+ # volume, raise an exception
+ if orig_vol['capacity'] > new_pool['available']:
+ domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
+ raise InvalidOperation('KCHVM0034E',
+ {'name': domain_name})
+
+ elif orig_pool['type'] in ['scsi', 'iscsi']:
+ # SCSI and iSCSI always fall back to the storage pool 'default'
+ wok_log.warning('cannot create new volume for clone in '
+ 'storage pool \'%s\'; falling back to '
+ '\'default\'', orig_pool_name)
+ new_pool_name = u'default'
+ new_pool = self.storagepool.lookup(u'default')
+
+ # if the pool 'default' cannot hold a new volume, raise
+ # an exception
+ if orig_vol['capacity'] > new_pool['available']:
+ domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
+ raise InvalidOperation('KCHVM0034E', {'name': domain_name})
+
+ else:
+ # unexpected storage pool type
+ raise InvalidOperation('KCHPOOL0014E',
+ {'type': orig_pool['type']})
+
+ # new volume name: <UUID>-<loop-index>.<original extension>
+ # e.g. 1234-5678-9012-3456-0.img
+ ext = os.path.splitext(path)[1]
+ new_vol_name = u'%s-%d%s' % (uuid, i, ext)
+ task = self.storagevolume.clone(orig_pool_name, orig_vol_name,
+ new_name=new_vol_name)
+ self.task.wait(task['id'], 3600) # 1 h
+
+ # get the new volume path and update the XML descriptor
+ new_vol = self.storagevolume.lookup(new_pool_name, new_vol_name)
+ xml = xml_item_update(xml, XPATH_DOMAIN_DISK_BY_FILE % path,
+ new_vol['path'], 'file')
+
+ # set the new disk's used_by
+ with self.objstore as session:
+ session.store('storagevolume', new_vol['path'],
+ {'used_by': [domain_name]})
+ rollback.prependDefer(_delete_disk_from_objstore, new_vol['path'])
+
+ # remove the new volume should an error occur later
+ rollback.prependDefer(self.storagevolume.delete, new_pool_name,
+ new_vol_name)
+
+ return xml
+
+ def _clone_update_objstore(self, old_uuid, new_uuid, rollback):
+ """Update Kimchi's object store with the cloning VM.
+
+ Arguments:
+ old_uuid -- The UUID of the original VM.
+ new_uuid -- The UUID of the new, clonning VM.
+ rollback -- A rollback context so the object store entry can be removed
+ if an error occurs during the cloning operation.
+ """
+ with self.objstore as session:
+ try:
+ vm = session.get('vm', old_uuid)
+ icon = vm['icon']
+ session.store('vm', new_uuid, {'icon': icon})
+ except NotFoundError:
+ # if we cannot find an object store entry for the original VM,
+ # don't store one with an empty value.
+ pass
+ else:
+ # we need to define a custom function to prepend to the
+ # rollback context because the object store session needs to be
+ # opened and closed correctly (i.e. "prependDefer" only
+ # accepts one command at a time but we need more than one to
+ # handle an object store).
+ def _rollback_objstore():
+ with self.objstore as session_rb:
+ session_rb.delete('vm', new_uuid, ignore_missing=True)
+
+ # remove the new object store entry should an error occur later
+ rollback.prependDefer(_rollback_objstore)
+
+ def _build_access_elem(self, dom, users, groups):
+ auth = config.get("authentication", "method")
+ access_xml = get_metadata_node(dom, "access",
+ self.caps.metadata_support)
+
+ auth_elem = None
+
+ if not access_xml:
+ # there is no metadata element 'access'
+ access_elem = E.access()
+ else:
+ access_elem = ET.fromstring(access_xml)
+
+ same_auth = access_elem.xpath('./auth[@type="%s"]' % auth)
+ if len(same_auth) > 0:
+ # there is already a sub-element 'auth' with the same type;
+ # update it.
+ auth_elem = same_auth[0]
+
+ if users is not None:
+ for u in auth_elem.findall('user'):
+ auth_elem.remove(u)
+
+ if groups is not None:
+ for g in auth_elem.findall('group'):
+ auth_elem.remove(g)
+
+ if auth_elem is None:
+ # there is no sub-element 'auth' with the same type
+ # (or no 'auth' at all); create it.
+ auth_elem = E.auth(type=auth)
+ access_elem.append(auth_elem)
+
+ if users is not None:
+ for u in users:
+ auth_elem.append(E.user(u))
+
+ if groups is not None:
+ for g in groups:
+ auth_elem.append(E.group(g))
+
+ return access_elem
+
+ def _vm_update_access_metadata(self, dom, params):
+ users = groups = None
+ if "users" in params:
+ users = params["users"]
+ for user in users:
+ if not self.users.validate(user):
+ raise InvalidParameter("KCHVM0027E",
+ {'users': user})
+ if "groups" in params:
+ groups = params["groups"]
+ for group in groups:
+ if not self.groups.validate(group):
+ raise InvalidParameter("KCHVM0028E",
+ {'groups': group})
+
+ if users is None and groups is None:
+ return
+
+ node = self._build_access_elem(dom, users, groups)
+ set_metadata_node(dom, node, self.caps.metadata_support)
+
+ def _get_access_info(self, dom):
+ users = groups = list()
+ access_xml = (get_metadata_node(dom, "access",
+ self.caps.metadata_support) or
+ """<access></access>""")
+ access_info = dictize(access_xml)
+ auth = config.get("authentication", "method")
+ if ('auth' in access_info['access'] and
+ ('type' in access_info['access']['auth'] or
+ len(access_info['access']['auth']) > 1)):
+ users = xpath_get_text(access_xml,
+ "/access/auth[@type='%s']/user" % auth)
+ groups = xpath_get_text(access_xml,
+ "/access/auth[@type='%s']/group" % auth)
+ elif auth == 'pam':
+ # Compatible to old permission tagging
+ users = xpath_get_text(access_xml, "/access/user")
+ groups = xpath_get_text(access_xml, "/access/group")
+ return users, groups
+
+ @staticmethod
+ def vm_get_os_metadata(dom, metadata_support):
+ os_xml = (get_metadata_node(dom, "os", metadata_support) or
+ """<os></os>""")
+ os_elem = ET.fromstring(os_xml)
+ return (os_elem.attrib.get("version"), os_elem.attrib.get("distro"))
+
+ @staticmethod
+ def vm_update_os_metadata(dom, params, metadata_support):
+ distro = params.get("os_distro")
+ version = params.get("os_version")
+ if distro is None:
+ return
+ os_elem = E.os({"distro": distro, "version": version})
+ set_metadata_node(dom, os_elem, metadata_support)
+
+ def _update_graphics(self, dom, xml, params):
+ root = objectify.fromstring(xml)
+ graphics = root.devices.find("graphics")
+ if graphics is None:
+ return xml
+
+ password = params['graphics'].get("passwd")
+ if password is not None and len(password.strip()) == 0:
+ password = "".join(random.sample(string.ascii_letters +
+ string.digits, 8))
+
+ if password is not None:
+ graphics.attrib['passwd'] = password
+
+ expire = params['graphics'].get("passwdValidTo")
+ to = graphics.attrib.get('passwdValidTo')
+ if to is not None:
+ if (time.mktime(time.strptime(to, '%Y-%m-%dT%H:%M:%S')) -
+ time.time() <= 0):
+ expire = expire if expire is not None else 30
+
+ if expire is not None:
+ expire_time = time.gmtime(time.time() + float(expire))
+ valid_to = time.strftime('%Y-%m-%dT%H:%M:%S', expire_time)
+ graphics.attrib['passwdValidTo'] = valid_to
+
+ if not dom.isActive():
+ return ET.tostring(root, encoding="utf-8")
+
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+ dom.updateDeviceFlags(etree.tostring(graphics),
+ libvirt.VIR_DOMAIN_AFFECT_LIVE)
+ return xml
+
+ def _backup_snapshots(self, snap, all_info):
+ """ Append "snap" and the children of "snap" to the list "all_info".
+
+ The list *must* always contain the parent snapshots before their
+ children so the function "_redefine_snapshots" can work correctly.
+
+ Arguments:
+ snap -- a native domain snapshot.
+ all_info -- a list of dict keys:
+ "{'xml': <snap XML>, 'current': <is snap current?>'}"
+ """
+ all_info.append({'xml': snap.getXMLDesc(0),
+ 'current': snap.isCurrent(0)})
+
+ for child in snap.listAllChildren(0):
+ self._backup_snapshots(child, all_info)
+
+ def _redefine_snapshots(self, dom, all_info):
+ """ Restore the snapshots stored in "all_info" to the domain "dom".
+
+ Arguments:
+ dom -- the domain which will have its snapshots restored.
+ all_info -- a list of dict keys, as described in "_backup_snapshots",
+ containing the original snapshot information.
+ """
+ for info in all_info:
+ flags = libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
+
+ if info['current']:
+ flags |= libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
+
+ dom.snapshotCreateXML(info['xml'], flags)
+
+ def _static_vm_update(self, dom, params):
+ old_xml = new_xml = dom.XMLDesc(0)
+
+ for key, val in params.items():
+ if key in VM_STATIC_UPDATE_PARAMS:
+ if type(val) == int:
+ val = str(val)
+ xpath = VM_STATIC_UPDATE_PARAMS[key]
+ new_xml = xml_item_update(new_xml, xpath, val)
+
+ # Updating memory and NUMA if necessary, if vm is offline
+ if not dom.isActive():
+ if 'memory' in params:
+ new_xml = self._update_memory_config(new_xml, params)
+ elif 'cpus' in params and \
+ (xpath_get_text(new_xml, XPATH_NUMA_CELL + '/@memory') != []):
+ vcpus = params['cpus']
+ new_xml = xml_item_update(
+ new_xml,
+ XPATH_NUMA_CELL,
+ value='0-' + str(vcpus - 1) if vcpus > 1 else '0',
+ attr='cpus')
+
+ if 'graphics' in params:
+ new_xml = self._update_graphics(dom, new_xml, params)
+
+ snapshots_info = []
+ vm_name = dom.name()
+ conn = self.conn.get()
+ try:
+ if 'name' in params:
+ state = DOM_STATE_MAP[dom.info()[0]]
+ if state != 'shutoff':
+ msg_args = {'name': vm_name, 'new_name': params['name']}
+ raise InvalidParameter("KCHVM0003E", msg_args)
+
+ lflags = libvirt.VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
+ dflags = (libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
+ libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)
+
+ for virt_snap in dom.listAllSnapshots(lflags):
+ snapshots_info.append({'xml': virt_snap.getXMLDesc(0),
+ 'current': virt_snap.isCurrent(0)})
+ self._backup_snapshots(virt_snap, snapshots_info)
+
+ virt_snap.delete(dflags)
+
+ # Undefine old vm, only if name is going to change
+ dom.undefine()
+
+ dom = conn.defineXML(new_xml)
+ if 'name' in params:
+ self._redefine_snapshots(dom, snapshots_info)
+ except libvirt.libvirtError as e:
+ dom = conn.defineXML(old_xml)
+ if 'name' in params:
+ self._redefine_snapshots(dom, snapshots_info)
+
+ raise OperationFailed("KCHVM0008E", {'name': vm_name,
+ 'err': e.get_error_message()})
+ return dom
+
+ def _update_memory_config(self, xml, params):
+ # Checks if NUMA memory is already configured, if not, checks if CPU
+ # element is already configured (topology). Then add NUMA element as
+ # apropriated
+ root = ET.fromstring(xml)
+ numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
+ vcpus = params.get('cpus')
+ if numa_mem == []:
+ if vcpus is None:
+ vcpus = int(xpath_get_text(xml,
+ VM_STATIC_UPDATE_PARAMS['cpus'])[0])
+ cpu = root.find('./cpu')
+ if cpu is None:
+ cpu = get_cpu_xml(vcpus, params['memory'] << 10)
+ root.insert(0, ET.fromstring(cpu))
+ else:
+ numa_element = get_numa_xml(vcpus, params['memory'] << 10)
+ cpu.insert(0, ET.fromstring(numa_element))
+ else:
+ if vcpus is not None:
+ xml = xml_item_update(
+ xml,
+ XPATH_NUMA_CELL,
+ value='0-' + str(vcpus - 1) if vcpus > 1 else '0',
+ attr='cpus')
+ root = ET.fromstring(xml_item_update(xml, XPATH_NUMA_CELL,
+ str(params['memory'] << 10),
+ attr='memory'))
+
+ # Remove currentMemory, automatically set later by libvirt
+ currentMem = root.find('.currentMemory')
+ if currentMem is not None:
+ root.remove(currentMem)
+
+ memory = root.find('.memory')
+ # Update/Adds maxMemory accordingly
+ if not self.caps.mem_hotplug_support:
+ if memory is not None:
+ memory.text = str(params['memory'] << 10)
+ else:
+ if memory is not None:
+ root.remove(memory)
+ maxMem = root.find('.maxMemory')
+ host_mem = self.conn.get().getInfo()[1]
+ slots = (host_mem - params['memory']) >> 10
+ # Libvirt does not accepts slots <= 1
+ if slots < 0:
+ raise OperationFailed("KCHVM0041E")
+ elif slots == 0:
+ slots = 1
+ if maxMem is None:
+ max_mem_xml = E.maxMemory(
+ str(host_mem * 1024),
+ unit='Kib',
+ slots=str(slots))
+ root.insert(0, max_mem_xml)
+ new_xml = ET.tostring(root, encoding="utf-8")
+ else:
+ # Update slots only
+ new_xml = xml_item_update(ET.tostring(root, encoding="utf-8"),
+ './maxMemory',
+ str(slots),
+ attr='slots')
+ return new_xml
+ return ET.tostring(root, encoding="utf-8")
+
+ def _live_vm_update(self, dom, params):
+ self._vm_update_access_metadata(dom, params)
+ if 'memory' in params and dom.isActive():
+ self._update_memory_live(dom, params)
+
+ def _update_memory_live(self, dom, params):
+ # Check if host supports memory device
+ if not self.caps.mem_hotplug_support:
+ raise InvalidOperation("KCHVM0046E")
+
+ # Check if the vm xml supports memory hotplug, if not, static update
+ # must be done firstly, then Kimchi is going to update the xml
+ xml = dom.XMLDesc(0)
+ numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
+ max_mem = xpath_get_text(xml, './maxMemory')
+ if numa_mem == [] or max_mem == []:
+ raise OperationFailed('KCHVM0042E', {'name': dom.name()})
+
+ # Memory live update must be done in chunks of 1024 Mib or 1Gib
+ new_mem = params['memory']
+ old_mem = int(xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]) >> 10
+ if new_mem < old_mem:
+ raise OperationFailed('KCHVM0043E')
+ if (new_mem - old_mem) % 1024 != 0:
+ raise OperationFailed('KCHVM0044E')
+
+ # Check slot spaces:
+ total_slots = int(xpath_get_text(xml, './maxMemory/@slots')[0])
+ needed_slots = (new_mem - old_mem) / 1024
+ used_slots = len(xpath_get_text(xml, './devices/memory'))
+ if needed_slots > (total_slots - used_slots):
+ raise OperationFailed('KCHVM0045E')
+ elif needed_slots == 0:
+ # New memory value is same that current memory set
+ return
+
+ # Finally, we are ok to hot add the memory devices
+ try:
+ self._hot_add_memory_devices(dom, needed_slots)
+ except Exception as e:
+ raise OperationFailed("KCHVM0047E", {'error': e.message})
+
+ def _hot_add_memory_devices(self, dom, amount):
+ # Hot add given number of memory devices in the guest
+ flags = libvirt.VIR_DOMAIN_MEM_CONFIG | libvirt.VIR_DOMAIN_MEM_LIVE
+ # Create memory device xml
+ mem_dev_xml = etree.tostring(
+ E.memory(
+ E.target(
+ E.size('1', unit='GiB'),
+ E.node('0')),
+ model='dimm'))
+ # Add chunks of 1G of memory
+ for i in range(amount):
+ dom.attachDeviceFlags(mem_dev_xml, flags)
+
+ def _has_video(self, dom):
+ dom = ElementTree.fromstring(dom.XMLDesc(0))
+ return dom.find('devices/video') is not None
+
+ def _update_guest_stats(self, name):
+ try:
+ dom = VMModel.get_vm(name, self.conn)
+
+ vm_uuid = dom.UUIDString()
+ info = dom.info()
+ state = DOM_STATE_MAP[info[0]]
+
+ if state != 'running':
+ self.stats[vm_uuid] = {}
+ return
+
+ if self.stats.get(vm_uuid, None) is None:
+ self.stats[vm_uuid] = {}
+
+ timestamp = time.time()
+ prevStats = self.stats.get(vm_uuid, {})
+ seconds = timestamp - prevStats.get('timestamp', 0)
+ self.stats[vm_uuid].update({'timestamp': timestamp})
+
+ self._get_percentage_cpu_usage(vm_uuid, info, seconds)
+ self._get_network_io_rate(vm_uuid, dom, seconds)
+ self._get_disk_io_rate(vm_uuid, dom, seconds)
+ except Exception as e:
+ # VM might be deleted just after we get the list.
+ # This is OK, just skip.
+ wok_log.debug('Error processing VM stats: %s', e.message)
+
+ def _get_percentage_cpu_usage(self, vm_uuid, info, seconds):
+ prevCpuTime = self.stats[vm_uuid].get('cputime', 0)
+
+ cpus = info[3]
+ cpuTime = info[4] - prevCpuTime
+
+ base = (((cpuTime) * 100.0) / (seconds * 1000.0 * 1000.0 * 1000.0))
+ percentage = max(0.0, min(100.0, base / cpus))
+
+ self.stats[vm_uuid].update({'cputime': info[4], 'cpu': percentage})
+
+ def _get_network_io_rate(self, vm_uuid, dom, seconds):
+ prevNetRxKB = self.stats[vm_uuid].get('netRxKB', 0)
+ prevNetTxKB = self.stats[vm_uuid].get('netTxKB', 0)
+ currentMaxNetRate = self.stats[vm_uuid].get('max_net_io', 100)
+
+ rx_bytes = 0
+ tx_bytes = 0
+
+ tree = ElementTree.fromstring(dom.XMLDesc(0))
+ for target in tree.findall('devices/interface/target'):
+ dev = target.get('dev')
+ io = dom.interfaceStats(dev)
+ rx_bytes += io[0]
+ tx_bytes += io[4]
+
+ netRxKB = float(rx_bytes) / 1000
+ netTxKB = float(tx_bytes) / 1000
+
+ rx_stats = (netRxKB - prevNetRxKB) / seconds
+ tx_stats = (netTxKB - prevNetTxKB) / seconds
+
+ rate = rx_stats + tx_stats
+ max_net_io = round(max(currentMaxNetRate, int(rate)), 1)
+
+ self.stats[vm_uuid].update({'net_io': rate, 'max_net_io': max_net_io,
+ 'netRxKB': netRxKB, 'netTxKB': netTxKB})
+
+ def _get_disk_io_rate(self, vm_uuid, dom, seconds):
+ prevDiskRdKB = self.stats[vm_uuid].get('diskRdKB', 0)
+ prevDiskWrKB = self.stats[vm_uuid].get('diskWrKB', 0)
+ currentMaxDiskRate = self.stats[vm_uuid].get('max_disk_io', 100)
+
+ rd_bytes = 0
+ wr_bytes = 0
+
+ tree = ElementTree.fromstring(dom.XMLDesc(0))
+ for target in tree.findall("devices/disk/target"):
+ dev = target.get("dev")
+ io = dom.blockStats(dev)
+ rd_bytes += io[1]
+ wr_bytes += io[3]
+
+ diskRdKB = float(rd_bytes) / 1024
+ diskWrKB = float(wr_bytes) / 1024
+
+ rd_stats = (diskRdKB - prevDiskRdKB) / seconds
+ wr_stats = (diskWrKB - prevDiskWrKB) / seconds
+
+ rate = rd_stats + wr_stats
+ max_disk_io = round(max(currentMaxDiskRate, int(rate)), 1)
+
+ self.stats[vm_uuid].update({'disk_io': rate,
+ 'max_disk_io': max_disk_io,
+ 'diskRdKB': diskRdKB,
+ 'diskWrKB': diskWrKB})
+
+ def lookup(self, name):
+ dom = self.get_vm(name, self.conn)
+ info = dom.info()
+ state = DOM_STATE_MAP[info[0]]
+ screenshot = None
+ # (type, listen, port, passwd, passwdValidTo)
+ graphics = self._vm_get_graphics(name)
+ graphics_port = graphics[2]
+ graphics_port = graphics_port if state == 'running' else None
+ try:
+ if state == 'running' and self._has_video(dom):
+ screenshot = self.vmscreenshot.lookup(name)
+ elif state == 'shutoff':
+ # reset vm stats when it is powered off to avoid sending
+ # incorrect (old) data
+ self.stats[dom.UUIDString()] = {}
+ except NotFoundError:
+ pass
+
+ with self.objstore as session:
+ try:
+ extra_info = session.get('vm', dom.UUIDString())
+ except NotFoundError:
+ extra_info = {}
+ icon = extra_info.get('icon')
+
+ self._update_guest_stats(name)
+ vm_stats = self.stats.get(dom.UUIDString(), {})
+ res = {}
+ res['cpu_utilization'] = vm_stats.get('cpu', 0)
+ res['net_throughput'] = vm_stats.get('net_io', 0)
+ res['net_throughput_peak'] = vm_stats.get('max_net_io', 100)
+ res['io_throughput'] = vm_stats.get('disk_io', 0)
+ res['io_throughput_peak'] = vm_stats.get('max_disk_io', 100)
+ users, groups = self._get_access_info(dom)
+
+ if state == 'shutoff':
+ xml = dom.XMLDesc(0)
+ val = xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]
+ unit_list = xpath_get_text(xml, XPATH_DOMAIN_MEMORY_UNIT)
+ if len(unit_list) > 0:
+ unit = unit_list[0]
+ else:
+ unit = 'KiB'
+ memory = convert_data_size(val, unit, 'MiB')
+ else:
+ memory = info[2] >> 10
+
+ return {'name': name,
+ 'state': state,
+ 'stats': res,
+ 'uuid': dom.UUIDString(),
+ 'memory': memory,
+ 'cpus': info[3],
+ 'screenshot': screenshot,
+ 'icon': icon,
+ # (type, listen, port, passwd, passwdValidTo)
+ 'graphics': {"type": graphics[0],
+ "listen": graphics[1],
+ "port": graphics_port,
+ "passwd": graphics[3],
+ "passwdValidTo": graphics[4]},
+ 'users': users,
+ 'groups': groups,
+ 'access': 'full',
+ 'persistent': True if dom.isPersistent() else False
+ }
+
+ def _vm_get_disk_paths(self, dom):
+ xml = dom.XMLDesc(0)
+ xpath = "/domain/devices/disk[@device='disk']/source/@file"
+ return xpath_get_text(xml, xpath)
+
+ @staticmethod
+ def get_vm(name, conn):
+ conn = conn.get()
+ try:
+ # outgoing text to libvirt, encode('utf-8')
+ return conn.lookupByName(name.encode("utf-8"))
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ raise NotFoundError("KCHVM0002E", {'name': name})
+ else:
+ raise OperationFailed("KCHVM0009E", {'name': name,
+ 'err': e.message})
+
+ def delete(self, name):
+ conn = self.conn.get()
+ dom = self.get_vm(name, self.conn)
+ if not dom.isPersistent():
+ raise InvalidOperation("KCHVM0036E", {'name': name})
+
+ self._vmscreenshot_delete(dom.UUIDString())
+ paths = self._vm_get_disk_paths(dom)
+ info = self.lookup(name)
+
+ if info['state'] != 'shutoff':
+ self.poweroff(name)
+
+ # delete existing snapshots before deleting VM
+
+ # libvirt's Test driver does not support the function
+ # "virDomainListAllSnapshots", so "VMSnapshots.get_list" will raise
+ # "OperationFailed" in that case.
+ try:
+ snapshot_names = self.vmsnapshots.get_list(name)
+ except OperationFailed, e:
+ wok_log.error('cannot list snapshots: %s; '
+ 'skipping snapshot deleting...' % e.message)
+ else:
+ for s in snapshot_names:
+ self.vmsnapshot.delete(name, s)
+
+ try:
+ dom.undefine()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0021E",
+ {'name': name, 'err': e.get_error_message()})
+
+ for path in paths:
+ try:
+ vol = conn.storageVolLookupByPath(path)
+ pool = vol.storagePoolLookupByVolume()
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type not in READONLY_POOL_TYPE:
+ vol.delete(0)
+ # Update objstore to remove the volume
+ with self.objstore as session:
+ session.delete('storagevolume', path,
+ ignore_missing=True)
+ except libvirt.libvirtError as e:
+ wok_log.error('Unable to get storage volume by path: %s' %
+ e.message)
+ except Exception as e:
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
+
+ try:
+ with self.objstore as session:
+ if path in session.get_list('storagevolume'):
+ used_by = session.get('storagevolume', path)['used_by']
+ used_by.remove(name)
+ session.store('storagevolume', path,
+ {'used_by': used_by})
+ except Exception as e:
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
+
+ try:
+ with self.objstore as session:
+ session.delete('vm', dom.UUIDString(), ignore_missing=True)
+ except Exception as e:
+ # It is possible to delete vm without delete its database info
+ wok_log.error('Error deleting vm information from database: '
+ '%s', e.message)
+
+ vnc.remove_proxy_token(name)
+
+ def start(self, name):
+ # make sure the ISO file has read permission
+ dom = self.get_vm(name, self.conn)
+ xml = dom.XMLDesc(0)
+ xpath = "/domain/devices/disk[@device='cdrom']/source/@file"
+ isofiles = xpath_get_text(xml, xpath)
+
+ user = UserTests.probe_user()
+ for iso in isofiles:
+ run_setfacl_set_attr(iso, user=user)
+
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.create()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0019E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def poweroff(self, name):
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.destroy()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0020E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def shutdown(self, name):
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.shutdown()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0029E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def reset(self, name):
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.reset(flags=0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0022E",
+ {'name': name, 'err': e.get_error_message()})
+
+ def _vm_get_graphics(self, name):
+ dom = self.get_vm(name, self.conn)
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+
+ expr = "/domain/devices/graphics/@type"
+ res = xpath_get_text(xml, expr)
+ graphics_type = res[0] if res else None
+
+ expr = "/domain/devices/graphics/@listen"
+ res = xpath_get_text(xml, expr)
+ graphics_listen = res[0] if res else None
+
+ graphics_port = graphics_passwd = graphics_passwdValidTo = None
+ if graphics_type:
+ expr = "/domain/devices/graphics[@type='%s']/@port"
+ res = xpath_get_text(xml, expr % graphics_type)
+ graphics_port = int(res[0]) if res else None
+
+ expr = "/domain/devices/graphics[@type='%s']/@passwd"
+ res = xpath_get_text(xml, expr % graphics_type)
+ graphics_passwd = res[0] if res else None
+
+ expr = "/domain/devices/graphics[@type='%s']/@passwdValidTo"
+ res = xpath_get_text(xml, expr % graphics_type)
+ if res:
+ to = time.mktime(time.strptime(res[0], '%Y-%m-%dT%H:%M:%S'))
+ graphics_passwdValidTo = to - time.mktime(time.gmtime())
+
+ return (graphics_type, graphics_listen, graphics_port,
+ graphics_passwd, graphics_passwdValidTo)
+
+ def connect(self, name):
+ # (type, listen, port, passwd, passwdValidTo)
+ graphics_port = self._vm_get_graphics(name)[2]
+ if graphics_port is not None:
+ vnc.add_proxy_token(name, graphics_port)
+ else:
+ raise OperationFailed("KCHVM0010E", {'name': name})
+
+ def _vmscreenshot_delete(self, vm_uuid):
+ screenshot = VMScreenshotModel.get_screenshot(vm_uuid, self.objstore,
+ self.conn)
+ screenshot.delete()
+ try:
+ with self.objstore as session:
+ session.delete('screenshot', vm_uuid)
+ except Exception as e:
+ # It is possible to continue Kimchi executions without delete
+ # screenshots
+ wok_log.error('Error trying to delete vm screenshot from '
+ 'database due error: %s', e.message)
+
+ def suspend(self, name):
+ """Suspend the virtual machine's execution and puts it in the
+ state 'paused'. Use the function "resume" to restore its state.
+ If the VM is not running, an exception will be raised.
+
+ Parameters:
+ name -- the name of the VM to be suspended.
+ """
+ vm = self.lookup(name)
+ if vm['state'] != 'running':
+ raise InvalidOperation('KCHVM0037E', {'name': name})
+
+ vir_dom = self.get_vm(name, self.conn)
+
+ try:
+ vir_dom.suspend()
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0038E', {'name': name,
+ 'err': e.message})
+
+ def resume(self, name):
+ """Resume the virtual machine's execution and puts it in the
+ state 'running'. The VM should have been suspended previously by the
+ function "suspend" and be in the state 'paused', otherwise an exception
+ will be raised.
+
+ Parameters:
+ name -- the name of the VM to be resumed.
+ """
+ vm = self.lookup(name)
+ if vm['state'] != 'paused':
+ raise InvalidOperation('KCHVM0039E', {'name': name})
+
+ vir_dom = self.get_vm(name, self.conn)
+
+ try:
+ vir_dom.resume()
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0040E', {'name': name,
+ 'err': e.message})
+
+
+class VMScreenshotModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.conn = kargs['conn']
+
+ def lookup(self, name):
+ dom = VMModel.get_vm(name, self.conn)
+ d_info = dom.info()
+ vm_uuid = dom.UUIDString()
+ if DOM_STATE_MAP[d_info[0]] != 'running':
+ raise NotFoundError("KCHVM0004E", {'name': name})
+
+ screenshot = self.get_screenshot(vm_uuid, self.objstore, self.conn)
+ img_path = screenshot.lookup()
+ # screenshot info changed after scratch generation
+ try:
+ with self.objstore as session:
+ session.store('screenshot', vm_uuid, screenshot.info)
+ except Exception as e:
+ # It is possible to continue Kimchi executions without store
+ # screenshots
+ wok_log.error('Error trying to update database with guest '
+ 'screenshot information due error: %s', e.message)
+ return img_path
+
+ @staticmethod
+ def get_screenshot(vm_uuid, objstore, conn):
+ try:
+ with objstore as session:
+ try:
+ params = session.get('screenshot', vm_uuid)
+ except NotFoundError:
+ params = {'uuid': vm_uuid}
+ session.store('screenshot', vm_uuid, params)
+ except Exception as e:
+ # The 'except' outside of 'with' is necessary to catch possible
+ # exception from '__exit__' when calling 'session.store'
+ # It is possible to continue Kimchi vm executions without
+ # screenshots
+ wok_log.error('Error trying to update database with guest '
+ 'screenshot information due error: %s', e.message)
+ return LibvirtVMScreenshot(params, conn)
+
+
+class LibvirtVMScreenshot(VMScreenshot):
+ def __init__(self, vm_uuid, conn):
+ VMScreenshot.__init__(self, vm_uuid)
+ self.conn = conn
+
+ def _generate_scratch(self, thumbnail):
+ def handler(stream, buf, opaque):
+ fd = opaque
+ os.write(fd, buf)
+
+ fd = os.open(thumbnail, os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0644)
+ try:
+ conn = self.conn.get()
+ dom = conn.lookupByUUIDString(self.vm_uuid)
+ vm_name = dom.name()
+ stream = conn.newStream(0)
+ dom.screenshot(stream, 0, 0)
+ stream.recvAll(handler, fd)
+ except libvirt.libvirtError:
+ try:
+ stream.abort()
+ except:
+ pass
+ raise NotFoundError("KCHVM0006E", {'name': vm_name})
+ else:
+ stream.finish()
+ finally:
+ os.close(fd)
diff --git a/src/wok/plugins/kimchi/model/vmsnapshots.py b/src/wok/plugins/kimchi/model/vmsnapshots.py
new file mode 100644
index 0000000..fff1908
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmsnapshots.py
@@ -0,0 +1,204 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import time
+from lxml import objectify
+from lxml.builder import E
+
+from wok.exception import InvalidOperation, NotFoundError, OperationFailed
+from wok.utils import add_task
+from wok.xmlutils.utils import xpath_get_text
+from wok.model.tasks import TaskModel
+
+from vms import DOM_STATE_MAP, VMModel
+from vmstorages import VMStorageModel, VMStoragesModel
+
+
+class VMSnapshotsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+ self.vmstorages = VMStoragesModel(**kargs)
+ self.vmstorage = VMStorageModel(**kargs)
+
+ def create(self, vm_name, params={}):
+ """Create a snapshot with the current domain state.
+
+ The VM must be stopped and contain only disks with format 'qcow2';
+ otherwise an exception will be raised.
+
+ Parameters:
+ vm_name -- the name of the VM where the snapshot will be created.
+ params -- a dict with the following values:
+ "name": The snapshot name (optional). If omitted, a default value
+ based on the current time will be used.
+
+ Return:
+ A Task running the operation.
+ """
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+ if DOM_STATE_MAP[vir_dom.info()[0]] != u'shutoff':
+ raise InvalidOperation('KCHSNAP0001E', {'vm': vm_name})
+
+ # if the VM has a non-CDROM disk with type 'raw', abort.
+ for storage_name in self.vmstorages.get_list(vm_name):
+ storage = self.vmstorage.lookup(vm_name, storage_name)
+ type = storage['type']
+ format = storage['format']
+
+ if type != u'cdrom' and format != u'qcow2':
+ raise InvalidOperation('KCHSNAP0010E', {'vm': vm_name,
+ 'format': format})
+
+ name = params.get('name', unicode(int(time.time())))
+
+ task_params = {'vm_name': vm_name, 'name': name}
+ taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' % (vm_name,
+ name), self._create_task, self.objstore, task_params)
+ return self.task.lookup(taskid)
+
+ def _create_task(self, cb, params):
+ """Asynchronous function which actually creates the snapshot.
+
+ Parameters:
+ cb -- a callback function to signal the Task's progress.
+ params -- a dict with the following values:
+ "vm_name": the name of the VM where the snapshot will be created.
+ "name": the snapshot name.
+ """
+ vm_name = params['vm_name']
+ name = params['name']
+
+ cb('building snapshot XML')
+ root_elem = E.domainsnapshot()
+ root_elem.append(E.name(name))
+ xml = ET.tostring(root_elem, encoding='utf-8')
+
+ try:
+ cb('fetching snapshot domain')
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+ cb('creating snapshot')
+ vir_dom.snapshotCreateXML(xml, 0)
+ except (NotFoundError, OperationFailed, libvirt.libvirtError), e:
+ raise OperationFailed('KCHSNAP0002E',
+ {'name': name, 'vm': vm_name,
+ 'err': e.message})
+
+ cb('OK', True)
+
+ def get_list(self, vm_name):
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+
+ try:
+ vir_snaps = vir_dom.listAllSnapshots(0)
+ return sorted([s.getName().decode('utf-8') for s in vir_snaps],
+ key=unicode.lower)
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0005E',
+ {'vm': vm_name, 'err': e.message})
+
+
+class VMSnapshotModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def lookup(self, vm_name, name):
+ vir_snap = self.get_vmsnapshot(vm_name, name)
+
+ try:
+ snap_xml_str = vir_snap.getXMLDesc(0).decode('utf-8')
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0004E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+ snap_xml = objectify.fromstring(snap_xml_str)
+
+ try:
+ parent = unicode(snap_xml.parent.name)
+ except AttributeError:
+ parent = u''
+
+ return {'created': unicode(snap_xml.creationTime),
+ 'name': unicode(snap_xml.name),
+ 'parent': parent,
+ 'state': unicode(snap_xml.state)}
+
+ def delete(self, vm_name, name):
+ try:
+ vir_snap = self.get_vmsnapshot(vm_name, name)
+ vir_snap.delete(0)
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0006E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+ def revert(self, vm_name, name):
+ try:
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+ vir_snap = self.get_vmsnapshot(vm_name, name)
+ vir_dom.revertToSnapshot(vir_snap, 0)
+
+ # get vm name recorded in the snapshot and return new uri params
+ vm_new_name = xpath_get_text(vir_snap.getXMLDesc(0),
+ 'domain/name')[0]
+ return [vm_new_name, name]
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0009E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+ def get_vmsnapshot(self, vm_name, name):
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+
+ try:
+ return vir_dom.snapshotLookupByName(name, 0)
+ except libvirt.libvirtError, e:
+ code = e.get_error_code()
+ if code == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
+ raise NotFoundError('KCHSNAP0003E', {'name': name,
+ 'vm': vm_name})
+ else:
+ raise OperationFailed('KCHSNAP0004E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+
+class CurrentVMSnapshotModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.vmsnapshot = VMSnapshotModel(**kargs)
+
+ def lookup(self, vm_name):
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+
+ try:
+ vir_snap = vir_dom.snapshotCurrent(0)
+ snap_name = vir_snap.getName().decode('utf-8')
+ except libvirt.libvirtError, e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
+ return {}
+
+ raise OperationFailed('KCHSNAP0008E',
+ {'vm': vm_name, 'err': e.message})
+
+ return self.vmsnapshot.lookup(vm_name, snap_name)
diff --git a/src/wok/plugins/kimchi/model/vmstorages.py b/src/wok/plugins/kimchi/model/vmstorages.py
new file mode 100644
index 0000000..bec16c6
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmstorages.py
@@ -0,0 +1,252 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import string
+from lxml import etree
+
+from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
+from wok.exception import OperationFailed
+from wok.utils import wok_log
+
+from ..osinfo import lookup
+from ..xmlutils.disk import get_device_node, get_disk_xml
+from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
+from config import CapabilitiesModel
+from diskutils import get_disk_used_by, set_disk_used_by
+from storagevolumes import StorageVolumeModel
+from utils import get_vm_config_flag
+from vms import DOM_STATE_MAP, VMModel
+
+
+HOTPLUG_TYPE = ['scsi', 'virtio']
+
+
+def _get_device_bus(dev_type, dom, metadata_support):
+ try:
+ version, distro = VMModel.vm_get_os_metadata(dom, metadata_support)
+ except:
+ version, distro = ('unknown', 'unknown')
+ return lookup(distro, version)[dev_type+'_bus']
+
+
+class VMStoragesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def _get_available_bus_address(self, bus_type, vm_name):
+ if bus_type not in ['ide']:
+ return dict()
+ # libvirt limitation of just 1 ide controller
+ # each controller have at most 2 buses and each bus 2 units.
+ dom = VMModel.get_vm(vm_name, self.conn)
+ disks = self.get_list(vm_name)
+ valid_id = [('0', '0'), ('0', '1'), ('1', '0'), ('1', '1')]
+ controller_id = '0'
+ for dev_name in disks:
+ disk = get_device_node(dom, dev_name)
+ if disk.target.attrib['bus'] == 'ide':
+ controller_id = disk.address.attrib['controller']
+ bus_id = disk.address.attrib['bus']
+ unit_id = disk.address.attrib['unit']
+ if (bus_id, unit_id) in valid_id:
+ valid_id.remove((bus_id, unit_id))
+ continue
+ if not valid_id:
+ raise OperationFailed('KCHVMSTOR0014E',
+ {'type': 'ide', 'limit': 4})
+ else:
+ address = {'controller': controller_id,
+ 'bus': valid_id[0][0], 'unit': valid_id[0][1]}
+ return dict(address=address)
+
+ def create(self, vm_name, params):
+ vol_model = None
+ # Path will never be blank due to API.json verification.
+ # There is no need to cover this case here.
+ if not ('vol' in params) ^ ('path' in params):
+ raise InvalidParameter("KCHVMSTOR0017E")
+
+ dom = VMModel.get_vm(vm_name, self.conn)
+ params['bus'] = _get_device_bus(params['type'], dom,
+ self.caps.metadata_support)
+ params['format'] = 'raw'
+
+ dev_list = [dev for dev, bus in get_vm_disks(dom).iteritems()
+ if bus == params['bus']]
+ dev_list.sort()
+ if len(dev_list) == 0:
+ params['index'] = 0
+ else:
+ char = dev_list.pop()[2]
+ params['index'] = string.ascii_lowercase.index(char) + 1
+
+ if (params['bus'] not in HOTPLUG_TYPE and
+ DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
+ raise InvalidOperation('KCHVMSTOR0011E')
+
+ if params.get('vol'):
+ try:
+ pool = params['pool']
+ vol_model = StorageVolumeModel(conn=self.conn,
+ objstore=self.objstore)
+ vol_info = vol_model.lookup(pool, params['vol'])
+ except KeyError:
+ raise InvalidParameter("KCHVMSTOR0012E")
+ except Exception as e:
+ raise InvalidParameter("KCHVMSTOR0015E", {'error': e})
+ if len(vol_info['used_by']) != 0:
+ raise InvalidParameter("KCHVMSTOR0016E")
+
+ valid_format = {
+ "disk": ["raw", "bochs", "qcow", "qcow2", "qed", "vmdk"],
+ "cdrom": "iso"}
+
+ if vol_info['type'] == 'file':
+ if (params['type'] == 'disk' and
+ vol_info['format'] in valid_format[params['type']]):
+ params['format'] = vol_info['format']
+ else:
+ raise InvalidParameter("KCHVMSTOR0018E",
+ {"format": vol_info['format'],
+ "type": params['type']})
+
+ params['path'] = vol_info['path']
+ params['disk'] = vol_info['type']
+
+ params.update(self._get_available_bus_address(params['bus'], vm_name))
+
+ # Add device to VM
+ dev, xml = get_disk_xml(params)
+ try:
+ conn = self.conn.get()
+ dom = conn.lookupByName(vm_name)
+ dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
+ except Exception as e:
+ raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
+
+ # Don't put a try-block here. Let the exception be raised. If we
+ # allow disks used_by to be out of sync, data corruption could
+ # occour if a disk is added to two guests unknowingly.
+ if params.get('vol'):
+ used_by = vol_info['used_by']
+ used_by.append(vm_name)
+ set_disk_used_by(self.objstore, params['path'], used_by)
+
+ return dev
+
+ def get_list(self, vm_name):
+ dom = VMModel.get_vm(vm_name, self.conn)
+ return get_vm_disks(dom).keys()
+
+
+class VMStorageModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def lookup(self, vm_name, dev_name):
+ # Retrieve disk xml and format return dict
+ dom = VMModel.get_vm(vm_name, self.conn)
+ return get_vm_disk_info(dom, dev_name)
+
+ def delete(self, vm_name, dev_name):
+ conn = self.conn.get()
+
+ try:
+ bus_type = self.lookup(vm_name, dev_name)['bus']
+ dom = conn.lookupByName(vm_name)
+ except NotFoundError:
+ raise
+
+ if (bus_type not in HOTPLUG_TYPE and
+ DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
+ raise InvalidOperation('KCHVMSTOR0011E')
+
+ try:
+ disk = get_device_node(dom, dev_name)
+ path = get_vm_disk_info(dom, dev_name)['path']
+ if path is None or len(path) < 1:
+ path = self.lookup(vm_name, dev_name)['path']
+ # This has to be done before it's detached. If it wasn't
+ # in the obj store, its ref count would have been updated
+ # by get_disk_used_by()
+ if path is not None:
+ used_by = get_disk_used_by(self.objstore, self.conn, path)
+ else:
+ wok_log.error("Unable to decrement volume used_by on"
+ " delete because no path could be found.")
+ dom.detachDeviceFlags(etree.tostring(disk),
+ get_vm_config_flag(dom, 'all'))
+ except Exception as e:
+ raise OperationFailed("KCHVMSTOR0010E", {'error': e.message})
+
+ if used_by is not None and vm_name in used_by:
+ used_by.remove(vm_name)
+ set_disk_used_by(self.objstore, path, used_by)
+ else:
+ wok_log.error("Unable to update %s:%s used_by on delete."
+ % (vm_name, dev_name))
+
+ def update(self, vm_name, dev_name, params):
+ old_disk_used_by = None
+ new_disk_used_by = None
+
+ dom = VMModel.get_vm(vm_name, self.conn)
+
+ dev_info = self.lookup(vm_name, dev_name)
+ if dev_info['type'] != 'cdrom':
+ raise InvalidOperation("KCHVMSTOR0006E")
+
+ params['path'] = params.get('path', '')
+ old_disk_path = dev_info['path']
+ new_disk_path = params['path']
+ if new_disk_path != old_disk_path:
+ # An empty path means a CD-ROM was empty or ejected:
+ if old_disk_path is not '':
+ old_disk_used_by = get_disk_used_by(
+ self.objstore, self.conn, old_disk_path)
+ if new_disk_path is not '':
+ new_disk_used_by = get_disk_used_by(
+ self.objstore, self.conn, new_disk_path)
+
+ dev_info.update(params)
+ dev, xml = get_disk_xml(dev_info)
+
+ try:
+ dom.updateDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
+ except Exception as e:
+ raise OperationFailed("KCHVMSTOR0009E", {'error': e.message})
+
+ try:
+ if old_disk_used_by is not None and \
+ vm_name in old_disk_used_by:
+ old_disk_used_by.remove(vm_name)
+ set_disk_used_by(self.objstore, old_disk_path,
+ old_disk_used_by)
+ if new_disk_used_by is not None:
+ new_disk_used_by.append(vm_name)
+ set_disk_used_by(self.objstore, new_disk_path,
+ new_disk_used_by)
+ except Exception as e:
+ wok_log.error("Unable to update dev used_by on update due to"
+ " %s:" % e.message)
+ return dev
diff --git a/src/wok/plugins/kimchi/netinfo.py b/src/wok/plugins/kimchi/netinfo.py
new file mode 100644
index 0000000..c5746d7
--- /dev/null
+++ b/src/wok/plugins/kimchi/netinfo.py
@@ -0,0 +1,216 @@
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import ethtool
+import glob
+import os
+
+
+NET_PATH = '/sys/class/net'
+NIC_PATH = '/sys/class/net/*/device'
+BRIDGE_PATH = '/sys/class/net/*/bridge'
+BONDING_PATH = '/sys/class/net/*/bonding'
+WLAN_PATH = '/sys/class/net/*/wireless'
+NET_BRPORT = '/sys/class/net/%s/brport'
+NET_MASTER = '/sys/class/net/%s/master'
+NET_STATE = '/sys/class/net/%s/carrier'
+PROC_NET_VLAN = '/proc/net/vlan/'
+BONDING_SLAVES = '/sys/class/net/%s/bonding/slaves'
+BRIDGE_PORTS = '/sys/class/net/%s/brif'
+
+
+def wlans():
+ return [b.split('/')[-2] for b in glob.glob(WLAN_PATH)]
+
+
+def is_wlan(iface):
+ return iface in wlans()
+
+
+# FIXME if we do not want to list usb nic
+def nics():
+ return list(set([b.split('/')[-2] for b in glob.glob(NIC_PATH)]) -
+ set(wlans()))
+
+
+def is_nic(iface):
+ return iface in nics()
+
+
+def bondings():
+ return [b.split('/')[-2] for b in glob.glob(BONDING_PATH)]
+
+
+def is_bonding(iface):
+ return iface in bondings()
+
+
+def vlans():
+ return list(set([b.split('/')[-1]
+ for b in glob.glob(NET_PATH + '/*')]) &
+ set([b.split('/')[-1]
+ for b in glob.glob(PROC_NET_VLAN + '*')]))
+
+
+def is_vlan(iface):
+ return iface in vlans()
+
+
+def bridges():
+ return [b.split('/')[-2] for b in glob.glob(BRIDGE_PATH)]
+
+
+def is_bridge(iface):
+ return iface in bridges()
+
+
+def all_interfaces():
+ return [d.rsplit("/", 1)[-1] for d in glob.glob(NET_PATH + '/*')]
+
+
+def slaves(bonding):
+ with open(BONDING_SLAVES % bonding) as bonding_file:
+ res = bonding_file.readline().split()
+ return res
+
+
+def ports(bridge):
+ return os.listdir(BRIDGE_PORTS % bridge)
+
+
+def is_brport(nic):
+ return os.path.exists(NET_BRPORT % nic)
+
+
+def is_bondlave(nic):
+ return os.path.exists(NET_MASTER % nic)
+
+
+def operstate(dev):
+ link_status = link_detected(dev)
+ return "down" if link_status == "n/a" else "up"
+
+
+def link_detected(dev):
+ # try to read interface carrier (link) status
+ try:
+ with open(NET_STATE % dev) as dev_file:
+ carrier = dev_file.readline().strip()
+ # when IOError is raised, interface is down
+ except IOError:
+ return "n/a"
+
+ # if value is 1, interface up with cable connected
+ # 0 corresponds to interface up with cable disconnected
+ return "yes" if carrier == '1' else "no"
+
+
+def get_vlan_device(vlan):
+ """ Return the device of the given VLAN. """
+ dev = None
+
+ if os.path.exists(PROC_NET_VLAN + vlan):
+ with open(PROC_NET_VLAN + vlan) as vlan_file:
+ for line in vlan_file:
+ if "Device:" in line:
+ dummy, dev = line.split()
+ break
+ return dev
+
+
+def get_bridge_port_device(bridge):
+ """Return the nics list that belongs to bridge."""
+ # br --- v --- bond --- nic1
+ if bridge not in bridges():
+ raise ValueError('unknown bridge %s' % bridge)
+ nics = []
+ for port in ports(bridge):
+ if port in vlans():
+ device = get_vlan_device(port)
+ if device in bondings():
+ nics.extend(slaves(device))
+ else:
+ nics.append(device)
+ if port in bondings():
+ nics.extend(slaves(port))
+ else:
+ nics.append(port)
+ return nics
+
+
+def aggregated_bridges():
+ return [bridge for bridge in bridges() if
+ (set(get_bridge_port_device(bridge)) & set(nics()))]
+
+
+def bare_nics():
+ "The nic is not a port of a bridge or a slave of bond."
+ return [nic for nic in nics() if not (is_brport(nic) or is_bondlave(nic))]
+
+
+def is_bare_nic(iface):
+ return iface in bare_nics()
+
+
+# The nic will not be exposed when it is a port of a bridge or
+# a slave of bond.
+# The bridge will not be exposed when all it's port are tap.
+def all_favored_interfaces():
+ return aggregated_bridges() + bare_nics() + bondings()
+
+
+def get_interface_type(iface):
+ # FIXME if we want to get more device type
+ # just support nic, bridge, bondings and vlan, for we just
+ # want to expose this 4 kinds of interface
+ try:
+ if is_nic(iface):
+ return "nic"
+ if is_bonding(iface):
+ return "bonding"
+ if is_bridge(iface):
+ return "bridge"
+ if is_vlan(iface):
+ return "vlan"
+ return 'unknown'
+ except IOError:
+ return 'unknown'
+
+
+def get_interface_info(iface):
+ if iface not in ethtool.get_devices():
+ raise ValueError('unknown interface: %s' % iface)
+
+ ipaddr = ''
+ netmask = ''
+ try:
+ ipaddr = ethtool.get_ipaddr(iface)
+ netmask = ethtool.get_netmask(iface)
+ except IOError:
+ pass
+
+ iface_link_detected = link_detected(iface)
+ iface_status = 'active' if iface_link_detected != "n/a" else "inactive"
+
+ return {'name': iface,
+ 'type': get_interface_type(iface),
+ 'status': iface_status,
+ 'link_detected': iface_link_detected,
+ 'ipaddr': ipaddr,
+ 'netmask': netmask}
diff --git a/src/wok/plugins/kimchi/network.py b/src/wok/plugins/kimchi/network.py
new file mode 100644
index 0000000..1433b8a
--- /dev/null
+++ b/src/wok/plugins/kimchi/network.py
@@ -0,0 +1,62 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import ethtool
+import ipaddr
+
+
+APrivateNets = ipaddr.IPNetwork("10.0.0.0/8")
+BPrivateNets = ipaddr.IPNetwork("172.16.0.0/12")
+CPrivateNets = ipaddr.IPNetwork('192.168.0.0/16')
+PrivateNets = [CPrivateNets, BPrivateNets, APrivateNets]
+DefaultNetsPool = [ipaddr.IPNetwork('192.168.122.0/23'),
+ ipaddr.IPNetwork('192.168.124.0/22'),
+ ipaddr.IPNetwork('192.168.128.0/17')]
+
+
+def get_dev_netaddr(dev):
+ info = ethtool.get_interfaces_info(dev)[0]
+ return (info.ipv4_address and
+ "%s/%s" % (info.ipv4_address, info.ipv4_netmask) or '')
+
+
+def get_dev_netaddrs():
+ nets = []
+ for dev in ethtool.get_devices():
+ devnet = get_dev_netaddr(dev)
+ devnet and nets.append(ipaddr.IPNetwork(devnet))
+ return nets
+
+
+# used_nets should include all the subnet allocated in libvirt network
+# will get host network by get_dev_netaddrs
+def get_one_free_network(used_nets, nets_pool=PrivateNets):
+ def _get_free_network(nets, used_nets):
+ for net in nets.subnet(new_prefix=24):
+ if not any(net.overlaps(used) for used in used_nets):
+ return str(net)
+ return None
+
+ used_nets = used_nets + get_dev_netaddrs()
+ for nets in nets_pool:
+ net = _get_free_network(nets, used_nets)
+ if net:
+ return net
+ return None
diff --git a/src/wok/plugins/kimchi/osinfo.py b/src/wok/plugins/kimchi/osinfo.py
new file mode 100644
index 0000000..5b1277c
--- /dev/null
+++ b/src/wok/plugins/kimchi/osinfo.py
@@ -0,0 +1,213 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import copy
+import glob
+import os
+import psutil
+from collections import defaultdict
+from configobj import ConfigObj
+from distutils.version import LooseVersion
+
+from wok.config import PluginPaths
+
+
+SUPPORTED_ARCHS = {'x86': ('i386', 'i686', 'x86_64'),
+ 'power': ('ppc', 'ppc64'),
+ 'ppc64le': ('ppc64le')}
+
+
+template_specs = {'x86': {'old': dict(disk_bus='ide',
+ nic_model='e1000', sound_model='ich6'),
+ 'modern': dict(disk_bus='virtio',
+ nic_model='virtio',
+ sound_model='ich6')},
+ 'power': {'old': dict(disk_bus='scsi',
+ nic_model='spapr-vlan',
+ cdrom_bus='scsi',
+ kbd_type="kbd",
+ kbd_bus='usb', mouse_bus='usb',
+ tablet_bus='usb', memory=1280),
+ 'modern': dict(disk_bus='virtio',
+ nic_model='virtio',
+ cdrom_bus='scsi',
+ kbd_bus='usb',
+ kbd_type="kbd",
+ mouse_bus='usb', tablet_bus='usb',
+ memory=1280)},
+ 'ppc64le': {'old': dict(disk_bus='virtio',
+ nic_model='virtio',
+ cdrom_bus='scsi',
+ kbd_bus='usb',
+ kbd_type="keyboard",
+ mouse_bus='usb', tablet_bus='usb',
+ memory=1280),
+ 'modern': dict(disk_bus='virtio',
+ nic_model='virtio',
+ cdrom_bus='scsi',
+ kbd_bus='usb',
+ kbd_type="keyboard",
+ mouse_bus='usb', tablet_bus='usb',
+ memory=1280)}}
+
+
+custom_specs = {'fedora': {'22': dict(video_model='qxl')}}
+
+
+modern_version_bases = {'x86': {'debian': '6.0', 'ubuntu': '7.10',
+ 'opensuse': '10.3', 'centos': '5.3',
+ 'rhel': '6.0', 'fedora': '16', 'gentoo': '0',
+ 'sles': '11', 'arch': '0'},
+ 'power': {'rhel': '6.5', 'fedora': '19',
+ 'ubuntu': '14.04',
+ 'opensuse': '13.1',
+ 'sles': '11sp3'},
+ 'ppc64le': {'rhel': '6.5', 'fedora': '19',
+ 'ubuntu': '14.04',
+ 'opensuse': '13.1',
+ 'sles': '11sp3'}}
+
+
+icon_available_distros = [icon[5:-4] for icon in glob.glob1('%s/images/'
+ % PluginPaths('kimchi').ui_dir, 'icon-*.png')]
+
+
+def _get_tmpl_defaults():
+ """
+ ConfigObj returns a dict like below when no changes were made in the
+ template configuration file (template.conf)
+
+ {'main': {}, 'storage': {'disk.0': {}}, 'processor': {}, 'graphics': {}}
+
+ The default values should be like below:
+
+ {'main': {'networks': ['default'], 'memory': '1024'},
+ 'storage': {'pool': 'default',
+ 'disk.0': {'format': 'qcow2', 'size': '10'}},
+ 'processor': {'cpus': '1'},
+ 'graphics': {'type': 'spice', 'listen': '127.0.0.1'}}
+ """
+ # Create dict with default values
+ tmpl_defaults = defaultdict(dict)
+ tmpl_defaults['main']['networks'] = ['default']
+ tmpl_defaults['main']['memory'] = 1024
+ tmpl_defaults['storage']['pool'] = 'default'
+ tmpl_defaults['storage']['disk.0'] = {'size': 10, 'format': 'qcow2'}
+ tmpl_defaults['processor']['cpus'] = 1
+ tmpl_defaults['graphics'] = {'type': 'vnc', 'listen': '127.0.0.1'}
+
+ default_config = ConfigObj(tmpl_defaults)
+
+ # Load template configuration file
+ config_file = os.path.join(PluginPaths('kimchi').conf_dir, 'template.conf')
+ config = ConfigObj(config_file)
+
+ # Merge default configuration with file configuration
+ default_config.merge(config)
+
+ # Create a dict with default values according to data structure
+ # expected by VMTemplate
+ defaults = {'domain': 'kvm', 'arch': os.uname()[4],
+ 'cdrom_bus': 'ide', 'cdrom_index': 2, 'mouse_bus': 'ps2'}
+
+ # Parse main section to get networks and memory values
+ main_section = default_config.pop('main')
+ defaults.update(main_section)
+
+ # Parse storage section to get storage pool and disks values
+ storage_section = default_config.pop('storage')
+ defaults['storagepool'] = '/plugins/kimchi/storagepools/' + \
+ storage_section.pop('pool')
+ defaults['disks'] = []
+ for disk in storage_section.keys():
+ data = storage_section[disk]
+ data['index'] = int(disk.split('.')[1])
+ defaults['disks'].append(data)
+
+ # Parse processor section to get cpus and cpu_topology values
+ processor_section = default_config.pop('processor')
+ defaults['cpus'] = processor_section.pop('cpus')
+ defaults['cpu_info'] = {}
+ if len(processor_section.keys()) > 0:
+ defaults['cpu_info']['topology'] = processor_section
+
+ # Update defaults values with graphics values
+ defaults['graphics'] = default_config.pop('graphics')
+
+ return defaults
+
+
+# Set defaults values according to template.conf file
+defaults = _get_tmpl_defaults()
+
+
+def _get_arch():
+ for arch, sub_archs in SUPPORTED_ARCHS.iteritems():
+ if os.uname()[4] in sub_archs:
+ return arch
+
+
+def get_template_default(template_type, field):
+ host_arch = _get_arch()
+ # Assuming 'power' = 'ppc64le' because lookup() does the same,
+ # claiming libvirt compatibility.
+ host_arch = 'power' if host_arch == 'ppc64le' else host_arch
+ tmpl_defaults = copy.deepcopy(defaults)
+ tmpl_defaults.update(template_specs[host_arch][template_type])
+ return tmpl_defaults[field]
+
+
+def lookup(distro, version):
+ """
+ Lookup all parameters needed to run a VM of a known or unknown operating
+ system type and version. The data is constructed by starting with the
+ 'defaults' and merging the parameters given for the identified OS. If
+ known, a link to a remote install CD is added.
+ """
+ params = copy.deepcopy(defaults)
+ params['os_distro'] = distro
+ params['os_version'] = version
+ arch = _get_arch()
+
+ # Setting maxMemory of the VM, which will be equal total Host memory in Kib
+ params['max_memory'] = psutil.TOTAL_PHYMEM >> 10
+
+ # set up arch to ppc64 instead of ppc64le due to libvirt compatibility
+ if params["arch"] == "ppc64le":
+ params["arch"] = "ppc64"
+
+ if distro in modern_version_bases[arch]:
+ if LooseVersion(version) >= LooseVersion(
+ modern_version_bases[arch][distro]):
+ params.update(template_specs[arch]['modern'])
+ else:
+ params.update(template_specs[arch]['old'])
+ else:
+ params['os_distro'] = params['os_version'] = "unknown"
+ params.update(template_specs[arch]['old'])
+
+ # Get custom specifications
+ params.update(custom_specs.get(distro, {}).get(version, {}))
+
+ if distro in icon_available_distros:
+ params['icon'] = 'plugins/kimchi/images/icon-%s.png' % distro
+ else:
+ params['icon'] = 'plugins/kimchi/images/icon-vm.png'
+
+ return params
diff --git a/src/wok/plugins/kimchi/po/LINGUAS b/src/wok/plugins/kimchi/po/LINGUAS
new file mode 100644
index 0000000..3fcb18f
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/LINGUAS
@@ -0,0 +1,11 @@
+en_US
+pt_BR
+zh_CN
+de_DE
+es_ES
+fr_FR
+it_IT
+ja_JP
+ko_KR
+ru_RU
+zh_TW
diff --git a/src/wok/plugins/kimchi/po/Makefile.in.in b/src/wok/plugins/kimchi/po/Makefile.in.in
new file mode 100644
index 0000000..d01fb31
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/Makefile.in.in
@@ -0,0 +1,398 @@
+# Makefile for PO directory in any package using GNU gettext.
+# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper at gnu.ai.mit.edu>
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU General Public
+# License but which still want to provide support for the GNU gettext
+# functionality.
+# Please note that the actual code of GNU gettext is covered by the GNU
+# General Public License and is *not* in the public domain.
+#
+# Origin: gettext-0.18
+GETTEXT_MACRO_VERSION = 0.18
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+SHELL = /bin/sh
+ at SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+datadir = @datadir@
+localedir = @prefix@/share/locale
+gettextsrcdir = $(datadir)/gettext/po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+# We use $(MKDIR_P).
+# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
+# on invoking install-sh with the -d option, so your package should contain
+# install-sh as described under AC_PROG_INSTALL.
+mkinstalldirs = $(SHELL) @install_sh@ -d
+install_sh = $(SHELL) @install_sh@
+MKDIR_P = @MKDIR_P@
+MKDIR_P = @MKDIR_P@
+
+GMSGFMT_ = @GMSGFMT@
+GMSGFMT_no = @GMSGFMT@
+GMSGFMT_yes = @GMSGFMT_015@
+GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
+MSGFMT_ = @MSGFMT@
+MSGFMT_no = @MSGFMT@
+MSGFMT_yes = @MSGFMT_015@
+MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
+XGETTEXT_ = @XGETTEXT@
+XGETTEXT_no = @XGETTEXT@
+XGETTEXT_yes = @XGETTEXT_015@
+XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
+MSGMERGE = msgmerge
+MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGINIT = msginit
+MSGCONV = msgconv
+MSGFILTER = msgfilter
+
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+UPDATEPOFILES = @UPDATEPOFILES@
+DUMMYPOFILES = @DUMMYPOFILES@
+DISTFILES.common = Makefile.in.in \
+$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
+DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot.in \
+$(POFILES) $(GMOFILES) \
+$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+
+# Makevars gets inserted here. (Don't remove this line!)
+
+.SUFFIXES:
+.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
+
+.po.mo:
+ @echo "$(MSGFMT) -c -o $@ $<"; \
+ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
+
+.po.gmo:
+ @lang=`echo $* | sed -e 's,.*/,,'`; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
+ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+
+.sin.sed:
+ sed -e '/^#/d' $< > t-$@
+ mv t-$@ $@
+
+
+all: check-macro-version update-gmo all- at USE_NLS@
+
+all-yes: stamp-po
+all-no:
+
+# Ensure that the gettext macros and this Makefile.in.in are in sync.
+check-macro-version:
+ @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
+ || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
+ exit 1; \
+ }
+
+# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
+# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
+# we don't want to bother translators with empty POT files). We assume that
+# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
+# In this case, stamp-po is a nop (i.e. a phony target).
+
+# stamp-po is a timestamp denoting the last time at which the CATALOGS have
+# been loosely updated. Its purpose is that when a developer or translator
+# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
+# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
+# invocations of "make" will do nothing. This timestamp would not be necessary
+# if updating the $(CATALOGS) would always touch them; however, the rule for
+# $(POFILES) has been designed to not touch files that don't need to be
+# changed.
+stamp-po: $(srcdir)/$(DOMAIN).pot
+ test ! -f $(srcdir)/$(DOMAIN).pot || \
+ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
+ @test ! -f $(srcdir)/$(DOMAIN).pot || { \
+ echo "touch stamp-po" && \
+ echo timestamp > stamp-poT && \
+ mv stamp-poT stamp-po; \
+ }
+
+# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
+# otherwise packages like GCC can not be built if only parts of the source
+# have been downloaded.
+
+$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
+ $(srcdir)/gen-pot $(POTFILES)
+
+# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
+# every "make" invocation, only create it when it is missing.
+# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
+$(srcdir)/$(DOMAIN).pot:
+ $(MAKE) $(DOMAIN).pot-update
+
+# This target rebuilds a PO file if $(DOMAIN).pot has changed.
+# Note that a PO file is not touched if it doesn't need to be changed.
+$(POFILES): $(srcdir)/$(DOMAIN).pot
+ @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
+ if test -f "$(srcdir)/$${lang}.po"; then \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
+ cd $(srcdir) \
+ && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
+ esac; \
+ }; \
+ else \
+ $(MAKE) $${lang}.po-create; \
+ fi
+
+
+install: install-exec install-data
+install-exec:
+install-data: install-data- at USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ $(INSTALL_DATA) $(srcdir)/$$file \
+ $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ for file in Makevars; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+install-data-no: all
+install-data-yes: all
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
+ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
+ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
+ fi; \
+ done; \
+ done
+
+install-strip: install
+
+installdirs: installdirs-exec installdirs-data
+installdirs-exec:
+installdirs-data: installdirs-data- at USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ : ; \
+ fi
+installdirs-data-no:
+installdirs-data-yes:
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ fi; \
+ done; \
+ done
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall: uninstall-exec uninstall-data
+uninstall-exec:
+uninstall-data: uninstall-data- at USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+uninstall-data-no:
+uninstall-data-yes:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ done; \
+ done
+
+check: all
+
+info dvi ps pdf html tags TAGS ctags CTAGS ID:
+
+mostlyclean:
+ rm -f remove-potcdate.sed
+ rm -f stamp-poT
+ rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f stamp-po $(GMOFILES)
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir:
+ $(MAKE) update-po
+ @$(MAKE) dist2
+# This is a separate target because 'update-po' must be executed before.
+dist2: stamp-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ dists="$$dists Makevars.template"; \
+ fi; \
+ if test -f $(srcdir)/$(DOMAIN).pot; then \
+ dists="$$dists $(DOMAIN).pot stamp-po"; \
+ fi; \
+ if test -f $(srcdir)/ChangeLog; then \
+ dists="$$dists ChangeLog"; \
+ fi; \
+ for i in 0 1 2 3 4 5 6 7 8 9; do \
+ if test -f $(srcdir)/ChangeLog.$$i; then \
+ dists="$$dists ChangeLog.$$i"; \
+ fi; \
+ done; \
+ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
+ for file in $$dists; do \
+ if test -f $$file; then \
+ cp -p $$file $(distdir) || exit 1; \
+ else \
+ cp -p $(srcdir)/$$file $(distdir) || exit 1; \
+ fi; \
+ done
+
+update-po: Makefile
+ $(MAKE) $(DOMAIN).pot-update
+ test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
+ $(MAKE) update-gmo
+
+# General rule for creating PO files.
+
+.nop.po-create:
+ @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
+ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
+ exit 1
+
+# General rule for updating PO files.
+
+.nop.po-update:
+ @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
+ if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
+ tmpdir=`pwd`; \
+ echo "$$lang:"; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
+ cd $(srcdir); \
+ if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+ esac; \
+ }; then \
+ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "msgmerge for $$lang.po failed!" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi
+
+$(DUMMYPOFILES):
+
+update-gmo: Makefile $(GMOFILES)
+ @:
+
+# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
+# because execution permission bits may not work on the current file system.
+# Use @SHELL@, which is the shell determined by autoconf for the use by its
+# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
+Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
+ cd $(top_builddir) \
+ && @SHELL@ ./config.status $(subdir)/$@.in po-directories
+
+force:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/wok/plugins/kimchi/po/Makevars b/src/wok/plugins/kimchi/po/Makevars
new file mode 100644
index 0000000..c29a807
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/Makevars
@@ -0,0 +1,41 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = kimchi
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER =
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = project-kimchi at googlegroups.com
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/src/wok/plugins/kimchi/po/POTFILES.in b/src/wok/plugins/kimchi/po/POTFILES.in
new file mode 100644
index 0000000..92eef1e
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/POTFILES.in
@@ -0,0 +1,3 @@
+# List of source files which contain translatable strings.
+i18n.py
+ui/pages/*.tmpl
diff --git a/src/wok/plugins/kimchi/po/de_DE.po b/src/wok/plugins/kimchi/po/de_DE.po
new file mode 100644
index 0000000..d3f3cc3
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/de_DE.po
@@ -0,0 +1,2288 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: de_DE\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "Fehler beim Abrufen von Blockeinheiten. Details: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "Fehler beim Abrufen von Blockeinheitinformationen für %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Distro-Datei konnte nicht gefunden werden: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"Distro-Datei konnte nicht analysiert werden: %(filename)s. Stellen Sie "
+"sicher, dass es sich um eine JSON-Datei handelt."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "Fehler beim Anmelden bei iSCSI-Hostziel %(portal)s. Details: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Anmeldung bei iSCSI-Host %(host)s Ziel %(target)s nicht möglich"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "Die ISO-Datei %(filename)s ist nicht bootfähig"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "Die ISO-Datei %(filename)s hat keinen gültigen El Torito-Bootsatz"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Ungültiger El Torito-Prüfeintrag in ISO-Datei %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Ungültiger El Torito-Boot-Indikator in ISO-Datei %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Unerwarteter Datenträgertyp für Primärdatenträger in ISO-Datei %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Ungültiges Format beim Lesen des Datenträgerdeskriptors in ISO-Datei %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"Der Hypervisor hat nicht die Berechtigung, die ISO-Datei %(filename)s zu "
+"verwenden. Verschieben Sie sie entweder nach /var/lib/libvirt oder setzen "
+"Sie, sofern möglich, die Suchberechtigung auf Dateizugriffssteuerungslisten "
+"für den Benutzer '%(user)s' oder fügen Sie '%(user)s' der ISO-Pfadgruppe "
+"hinzu oder (nicht empfohlen) 'chmod -R o+x 'path_to_iso'. Details: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "Virtuelle Maschine %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "Virtuelle Maschine %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Screenshot für gestoppte virtuelle Maschine %(name)s konnte nicht abgerufen "
+"werden"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "Fernes ISO-Image wird von diesem Server nicht unterstützt."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht abgerufen werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+"Verbindung zur abgeschalteten Maschine %(name)s konnte nicht hergestellt "
+"werden."
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "Zu überwachende Grafikadresse muss IPv4 oder IPv6 sein"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Vorlage angeben, aus der eine virtuelle Maschine erstellt werden soll"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gelöscht werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht umbenannt werden. Details: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "Netzname muss eine Zeichenfolge sein"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "Netzname muss eine Zeichenfolge sein"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "Benutzer '%(users)s' ist nicht vorhanden."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "Benutzer '%(groups)s' ist nicht vorhanden."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr ""
+"Schnittstelle %(iface)s ist in virtueller Maschine %(name)s nicht vorhanden"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"Das für die virtuelle Maschine %(name)s angegebene Netz %(network)s ist "
+"nicht vorhanden"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "Unterstützter Schnittstellentyp einer virtuellen Maschine ist nur Netz"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"Netzname für Schnittstelle einer virtuellen Maschine muss eine Zeichenfolge "
+"sein"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Ungültige Netzmodellkarte für Schnittstelle einer virtuellen Maschine "
+"angegeben"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Geben Sie Typ und Netz an, um eine neue Schnittstelle für eine virtuelle "
+"Maschine hinzuzufügen"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Vorlage %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr ""
+"Das für Vorlage %(template)s angegebene Netz '%(network)s' ist nicht "
+"vorhanden"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Der für Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht "
+"vorhanden"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+"Der für Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht "
+"aktiv"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Ungültiger Parameter '%(param)s' für CD-ROM angegeben."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"Das für Vorlage %(template)s angegebene Netz %(network)s ist nicht aktiv"
+
+msgid "Template name must be a string"
+msgstr "Vorlagenname muss eine Zeichenfolge sein"
+
+msgid "Template icon must be a path to the image"
+msgstr "Vorlagensymbol muss ein Pfad zum Image sein"
+
+msgid "Template distribution must be a string"
+msgstr "Vorlagenverteilung muss eine Zeichenfolge sein"
+
+msgid "Template distribution version must be a string"
+msgstr "Vorlagenverteilungsversion muss eine Zeichenfolge sein"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "Die Anzahl der CPUs muss eine Ganzzahl sein"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "Speicherkapazität (MB) muss eine Ganzzahl gröÃer als 512 sein"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "Ungültiger Speicherpool-URI %(value)s für Vorlage angegeben"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "Geben Sie ein ISO-Image als CD-ROM an, um eine Vorlage zu erstellen"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Alle Netze für die Vorlage müssen in einer Liste angegeben werden."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr ""
+"Vorlage kann aufgrund des folgenden Fehlers nicht erstellt werden: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr ""
+"Vorlage kann aufgrund des folgenden Fehlers nicht gelöscht werden: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Speicherpool %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Speicherpool %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Geben Sie %(item)s an, um den Speicherpool %(name)s zu erstellen"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Aktiver Speicherpool %(name)s konnte nicht gelöscht werden"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Speicherpools konnten nicht aufgelistet werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Speicherpool %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Anzahl der Speicherdatenträger im Speicherpool %(name)s konnte nicht "
+"abgerufen werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Speicherpool %(name)s konnte nicht aktiviert werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"Speicherpool %(name)s konnte nicht inaktiviert werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "Speicherpool %(name)s konnte nicht gelöscht werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"NFS-Pool konnte nicht erstellt werden, weil Exportpfad %(path)s beim Mounten "
+"blockieren kann"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"NFS-Pool konnte nicht erstellt werden, weil das Mounten des Exportpfads%"
+"(path)s fehlgeschlagen ist"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Nicht unterstützter Speicherpooltyp: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "Speicherpoolhost muss eine IP oder ein Hostname sein"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Einheitenparameter des Speicherpools muss eine Liste sein"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "Ziel-IQN eines iSCSI-Pools muss eine Zeichenfolge sein"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"Port eines fernen Speicherservers muss eine Ganzzahl zwischen 1 und 65535 "
+"sein"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Geben Sie Name und Typ an, um einen Speicherpool zu erstellen"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s ist keine gültige Platte/Partition. Sie konnte nicht hinzugefügt "
+"werden zum Pool %(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Die Parameterplatten können nur für den logischen Speicherpool aktualisiert "
+"werden."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "Der Name des SCSI-Hostadapters muss eine Zeichenfolge sein."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "Der Speicherpool kimchi_isos ist für die interne Verwendung reserviert"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Der NFS-Speicherpool %(name)s konnte nicht aktiviert werden. NFS-Server %"
+"(server)s ist nicht erreichbar."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Der NFS-Speicherpool %(name)s konnte nicht inaktiviert werden. NFS-Server %"
+"(server)s ist nicht erreichbar."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Pool %(name)s konnte nicht inaktiviert werden, weil er einigen Vorlagen "
+"zugeordnet ist"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"Pool %(name)s konnte nicht gelöscht werden, weil er einigen Vorlagen "
+"zugeordnet ist"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"Eine Datenträgergruppe mit dem Namen '%(name)s' ist bereits vorhanden. "
+"Wählen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"Datenbank mit Tiefenscaninformationen kann aufgrund des folgenden Fehlers "
+"nicht aktualisiert werden: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Speicherdatenträger %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"Speicherdatenträger %(name)s ist nicht im Speicherpool %(pool)s vorhanden"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Geben Sie %(item)s an, um Speicherdatenträger %(volume)s zu erstellen"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"Speicherdatenträger konnten nicht aufgelistet werden, weil Speicherpool %"
+"(pool)s nicht aktiv ist"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"Speicherdatenträger %(name)s konnte nicht in Speicherpool %(pool)s erstellt "
+"werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Speicherdatenträger konnten nicht in Speicherpool %(pool)s aufgelistet "
+"werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+"Speicherdatenträger %(name)s konnten nicht bereinigt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Speicherdatenträger %(name)s konnte nicht gelöscht werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"GröÃe des Speicherdatenträgers %(name)s konnte nicht geändert werden. "
+"Details: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"Speichertyp %(type)s unterstützt nicht das Erstellen und Löschen von "
+"Datenträgern"
+
+msgid "Storage volume name must be a string"
+msgstr "Name des Speicherdatenträgers muss eine Zeichenfolge sein"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "Zuordnung des Speicherdatenträgers muss eine Ganzzahl sein"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "Speicherdatenträger erfordert einen Datenträgernamen"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Datenbank mit Datenträgerinformationen kann aufgrund des folgenden Fehlers "
+"nicht aktualisiert werden: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "Schnittstelle %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Netz %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "Netz %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"Das für das Netz %(network)s angegebene Teilnetz %(subnet)s ist nicht gültig."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"Geben Sie eine Netzschnittstelle an, um überbrücktes Netz %(name)s zu "
+"erstellen"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Aktives Netz %(name)s konnte nicht gelöscht werden"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+"Die für das Netz %(network)s angegebene Schnittstelle %(iface)s wird bereits "
+"verwendet"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "Schnittstelle sollte bloÃes NIC, Bonding oder Brückeneinheit sein."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Netz %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Es konnte keine freie IP-Adresse für Netz '%(name)s' gefunden werden"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Unterstützte Netztypen sind Isoliert, NAT und Brücke"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"Teilnetz des Netzes muss eine Zeichenfolge mit IP-Adresse und Präfix oder "
+"Netzmaske sein"
+
+msgid "Network interface must be a string"
+msgstr "Netzschnittstelle muss eine Zeichenfolge sein"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "Netz-VLAN-ID muss eine Ganzzahl zwischen 1 und 4094 sein"
+
+msgid "Specify name and type to create a Network"
+msgstr "Geben Sie Name und Typ an, um ein Netz zu erstellen"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
+"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verknüpft."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
+"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verknüpft."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "Brückeneinheit %(name)s kann nicht die Trunkeinheit eines VLAN sein."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "Schnittstelle %(iface)s konnte nicht aktiviert werden: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"Schnittstelle %(iface)s konnte nicht aktiviert werden. Bitte überprüfen Sie "
+"den Status der physischen Verbindung."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Debugbericht %(name)s ist nicht vorhanden"
+
+msgid "Debug report tool not found in system"
+msgstr "Debugberichtstool nicht im System gefunden"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "Debugbericht %(name)s konnte nicht erstellt werden. Details: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "Debugbericht %(name)s konnte nicht generiert werden. Details: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"Eine Datenträgergruppe mit dem Namen '%(name)s' ist bereits vorhanden. "
+"Wählen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Speicherserver %(server)s wurde nicht von Kimchi verwendet"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' ist nicht vorhanden"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "Partition %(name)s ist nicht im Host vorhanden"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Hostmaschine konnte nicht heruntergefahren werden, weil virtuelle Maschinen "
+"ausgeführt werden"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"Hostmaschine konnte nicht neu gestartet werden, weil virtuelle Maschinen "
+"ausgeführt werden"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "Knoteneinheit '%(name)s' nicht gefunden"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "Keine Pakete für Aktualisierung markiert"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Paket %(name)s ist nicht für Aktualisierung markiert."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Fehler beim Abrufen von Paketen, die für die Aktualsierung markiert sind. "
+"Details: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "Es gibt keinen kompatiblen Paketmanager für dieses System."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "Ungültiger URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Ungültiger Speichertyp. Unterstützte Typen: 'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "Fehler beim Erstellen einer neuen Speichereinheit: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Fehler beim Aktualisieren einer Speichereinheit: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Fehler beim Entfernen einer Speichereinheit: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Geben Sie Typ und Pfad an, um einen neuen Datenträger für eine virtuelle "
+"Maschine hinzuzfügen"
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+"Geben Sie einen Pfad an, um die Platte der virtuellen Maschine zu "
+"aktualisieren"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Geben Sie Typ und Pfad an, um einen neuen Datenträger für eine virtuelle "
+"Maschine hinzuzfügen"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+"YUM-Repository-ID darf nur ein aus einer Zeichenfolge bestehendes Wort sein."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "Repository-URL muss ein http://-, ftp://- oder file://-URL sein."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"Repository-Konfiguration ist ein Wörterbuch mit bestimmten Werten "
+"hinsichtlich Repository-Typ."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "Verteilung an DEB-Repository muss eine Zeichenfolge sein"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "Komponenten für DEB-Repository müssen in einem Array aufgelistet sein"
+
+msgid "Components to DEB repository must be a string"
+msgstr "Komponenten für DEB-Repository müssen eine Zeichenfolge sein"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Name des YUM-Repositorys muss eine Zeichenfolge sein."
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG-Prüfung muss ein boolescher Wert sein."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG-Schlüssel muss ein URL sein, der auf die ASCII-Armor-Datei zeigt."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht aktualisiert werden."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Repository %(repo_id)s ist nicht vorhanden."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "Repository-Verwaltungstool wurde für Ihr System nicht erkannt."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Repository %(repo_id)s ist bereits aktiviert."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Repository %(repo_id)s ist bereits inaktiviert."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht entfernt werden."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"Repository-Konfigurationsdatei %(repo_file)s konnte nicht geschrieben werden"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Geben Sie die Repository-Verteilung an, um ein DEB-Repository zu erstellen."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht aktiviert werden."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht inaktiviert werden."
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM-Repository-ID ist bereits vorhanden"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM-Repository-Name muss eine Zeichenfolge sein"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Repositorys konnten nicht aufgelistet werden. Details: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+"Repository-Informationen konnten nicht abgerufen werden. Details: '%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Repository konnte nicht hinzugefügt werden. Details: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Repository konnte nicht entfernt werden. Details: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "FEHLERCODE"
+
+msgid "REASON"
+msgstr "GRUND"
+
+msgid "STACK"
+msgstr "STACK"
+
+msgid "Go to Homepage"
+msgstr "Gehe zu Homepage"
+
+msgid "Create a New Virtual Machine"
+msgstr "Neue virtuelle Maschine erstellen"
+
+msgid "Virtual Machine Name"
+msgstr "Name der virtuellen Maschine"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"Der für die Kennzeichnung der virtuellen Maschine verwendete Name. Falls er "
+"ausgelassen wird, wird ein Name anhand der verwendeten Vorlage ausgewählt."
+
+msgid "Template"
+msgstr "Vorlage"
+
+msgid "Please create a template first."
+msgstr "Erstellen Sie zunächst eine Vorlage."
+
+msgid "Create a Template"
+msgstr "Vorlage erstellen"
+
+msgid "Please choose a template."
+msgstr "Wählen Sie eine Vorlage aus."
+
+msgid "OS"
+msgstr "BS"
+
+msgid "OS Version"
+msgstr "BS-Version"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Speicher"
+
+msgid "Create"
+msgstr "Erstellen"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgid "Edit Guest"
+msgstr "Gast bearbeiten"
+
+msgid "General"
+msgstr "Allgemein"
+
+msgid "Storage"
+msgstr "Speicher"
+
+msgid "Interface"
+msgstr "Schnittstelle"
+
+msgid "Permission"
+msgstr "Version"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Name"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "Speicher"
+
+msgid "Icon"
+msgstr "Symbol"
+
+msgid "Device"
+msgstr "Einheitenname"
+
+msgid "Path"
+msgstr "NFS-Pfad"
+
+msgid "Network"
+msgstr "Netz"
+
+msgid "Type"
+msgstr "Typ"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Alle"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "Anbieter"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Speichern"
+
+msgid "Replace"
+msgstr "Ersetzen"
+
+msgid "Detach"
+msgstr "Abhängen"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "Starten"
+
+msgid "Reset"
+msgstr "Zurücksetzen"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "Aktionen"
+
+msgid "Connect"
+msgstr "Verbinden"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "Bearbeiten"
+
+msgid "Shut Down"
+msgstr "Herunterfahren"
+
+msgid "Delete"
+msgstr "Löschen"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "Platten-E/A"
+
+msgid "Network I/O"
+msgstr "Netz-E/A"
+
+msgid "Livetile"
+msgstr "Live Tile"
+
+msgid "No guests found."
+msgstr "Keine Gäste gefunden."
+
+msgid "Add a Storage Device to VM"
+msgstr "Speichereinheit zur virtuellen Maschine hinzufügen"
+
+msgid "Device Type"
+msgstr "Einheitentyp"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "Der Einheitentyp. Derzeit wird nur \"cdrom\" unterstützt."
+
+msgid "Storage Pool"
+msgstr "Speicherpool"
+
+msgid "Storage pool which volume located in"
+msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
+
+msgid "Storage Volume"
+msgstr "Speicherpoolname"
+
+msgid "Storage volume to be attached"
+msgstr "Name des Speicherdatenträgers muss eine Zeichenfolge sein"
+
+msgid "File Path"
+msgstr "Dateipfad"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "Der ISO-Dateipfad auf dem Server für die CD-ROM."
+
+msgid "Attach"
+msgstr "Anhängen"
+
+msgid "Shut down"
+msgstr "Herunterfahren"
+
+msgid "Restart"
+msgstr "Erneut starten"
+
+msgid "Basic Information"
+msgstr "Basisinformationen"
+
+msgid "OS Distro"
+msgstr "BS-Distro"
+
+msgid "OS Code Name"
+msgstr "BS-Codename"
+
+msgid "Processor"
+msgstr "Prozessor"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "Systemstatistik"
+
+msgid "Software Updates"
+msgstr "Software-Updates"
+
+msgid "Update Progress"
+msgstr "Aktualisierungsfortschritt"
+
+msgid "Repositories"
+msgstr "Repositorys"
+
+msgid "Debug Reports"
+msgstr "Debugberichte"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"Der Benutzername oder das Kennwort, den bzw. das Sie eingegeben haben, ist "
+"falsch. Versuchen Sie es bitte erneut."
+
+msgid "This field is required."
+msgstr "Dieses Feld ist erforderlich."
+
+msgid "Log in"
+msgstr "Anmelden"
+
+msgid "Logging in..."
+msgstr "Wird angemeldet..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "Gäste"
+
+msgid "Templates"
+msgstr "Vorlagen"
+
+msgid "Failed to get application configuration"
+msgstr "Anwendungskonfiguration konnte nicht abgerufen werden"
+
+msgid "This is not a valid Linux path"
+msgstr "Dies ist kein gültiger Linux-Pfad"
+
+msgid "This is not a valid URL."
+msgstr "Dies ist kein gültiger URL."
+
+msgid "No such data available."
+msgstr "Keine solchen Daten verfügbar."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"Hostsystem kann nicht kontaktiert werden. Prüfen Sie, ob das Hostsystem "
+"aktiv ist und obNetzkonnektivität besteht. HTTP-Anforderungsantwort %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Löschbestätigung"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Bestätigen"
+
+msgid "Warning"
+msgstr "Warnung"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Wird geladen..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Wiederholen"
+
+msgid "Detailed message:"
+msgstr "Detaillierte Meldung:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "Dies ist keine gültige ISO-Datei."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Dies wird einige Zeit dauern. Möchten Sie fortfahren?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "Hiermit wird die Vorlage dauerhaft gelöscht. Möchten Sie fortfahren?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"System konnte nicht heruntergefahren werden, weil einige virtuellen "
+"Maschinen ausgeführt werden!"
+
+msgid "Max:"
+msgstr "Max:"
+
+msgid "Utilization"
+msgstr "Auslastung"
+
+msgid "Available"
+msgstr "Verfügbar"
+
+msgid "Read Rate"
+msgstr "Leserate"
+
+msgid "Write Rate"
+msgstr "Schreibrate"
+
+msgid "Received"
+msgstr "Empfangen"
+
+msgid "Sent"
+msgstr "Gesendet"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"Durch das Herunterfahren oder Neustarten des Hosts können ungesicherte "
+"Arbeiten verloren gehen. Möchten Sie mit dem Herunterfahren/Neustarten "
+"fortfahren?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Repository wird dauerhaft entfernt und kann nicht wiederhergestellt werden. "
+"Möchten Sie fortfahren?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "Basis-URL"
+
+msgid "Is Mirror"
+msgstr "Ist Spiegel"
+
+msgid "URL Args"
+msgstr "URL-Args"
+
+msgid "Enabled"
+msgstr "Aktiviert"
+
+msgid "GPG Check"
+msgstr "GPG-Prüfung"
+
+msgid "GPG Key"
+msgstr "GPG-Schlüssel"
+
+msgid "Add"
+msgstr "Hinzufügen"
+
+msgid "Remove"
+msgstr "Entfernen"
+
+msgid "Enable"
+msgstr "Aktivieren"
+
+msgid "Disable"
+msgstr "Inaktivieren"
+
+msgid "Package Name"
+msgstr "Paketname"
+
+msgid "Version"
+msgstr "Version"
+
+msgid "Architecture"
+msgstr "Architektur"
+
+msgid "Repository"
+msgstr "Repository"
+
+msgid "Update All"
+msgstr "Alle aktualisieren"
+
+msgid "Updating..."
+msgstr "Wird aktualisiert..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "Pakete konnten nicht aktualisiert werden."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Debugbericht wird dauerhaft entfernt und kann nicht wiederhergestellt "
+"werden. Möchten Sie fortfahren?"
+
+msgid "Generated Time"
+msgstr "Generierte Zeit"
+
+msgid "Generate"
+msgstr "Generieren"
+
+msgid "Generating..."
+msgstr "Wird generiert..."
+
+msgid "Rename"
+msgstr "Umbenennen"
+
+msgid "Download"
+msgstr "Herunterladen"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr ""
+"Berichtsname darf nur Buchstaben, Zahlen und/oder Bindestriche ('-') "
+"enthalten."
+
+msgid "Pending..."
+msgstr "Wird geladen..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"Hiermit werden die virtuelle Maschine und deren virtuellen Platten gelöscht. "
+"Diese Operation kann nicht rückgängig gemacht werden. Möchten Sie fortfahren?"
+
+msgid "Power off Confirmation"
+msgstr "Löschbestätigung"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "Löschbestätigung"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "Löschbestätigung"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "Hiermit wird die Vorlage dauerhaft gelöscht. Möchten Sie fortfahren?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Diese CD-ROM wird dauerhaft abgehängt und Sie können sie neu anhängen. "
+"Möchten Sie mit dem Abhängen fortfahren?"
+
+msgid "Attaching..."
+msgstr "Wird angehängt..."
+
+msgid "Replacing..."
+msgstr "Wird ersetzt..."
+
+msgid "Successfully attached!"
+msgstr "Erfolgreich angehängt!"
+
+msgid "Successfully replaced!"
+msgstr "Erfolgreich ersetzt!"
+
+msgid "Successfully detached!"
+msgstr "Erfolgreich abgehängt!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "Die VLAN-ID muss zwischen 1 und 4094 liegen."
+
+msgid "unavailable"
+msgstr "nicht verfügbar"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"Diese Aktion unterbricht die Netzkonnektivität für jede virtuelle Maschine, "
+"die von diesem Netz abhängt."
+
+msgid "Create a network"
+msgstr "Netz erstellen"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
+"inaktiviert, sondern permanent gelöscht. Möchten Sie fortfahren?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+"Hiermit wird der Speicherpool dauerhaft gelöscht. Möchten Sie fortfahren?"
+
+msgid "This storage pool is empty."
+msgstr "Dieser Speicherpool ist leer."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Hiermit wird Ihre Platte formatiert und Sie verlieren sämtliche Daten "
+"darauf. Sind Sie sicher, dass Sie fortfahren möchten? "
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI-Fibre Channel"
+
+msgid "No SCSI adapters found."
+msgstr "Keine SCSI-Adapter gefunden."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "Der Speicherpoolname darf nicht leer sein."
+
+msgid "The storage pool path can not be blank."
+msgstr "Der Speicherpoolpfad darf nicht leer sein."
+
+msgid "NFS server mount path can not be blank."
+msgstr "Der Mountpfad des NFS-Servers darf nicht leer sein."
+
+msgid "Invalid NFS mount path."
+msgstr "Ungültiger NFS-Mountpfad."
+
+msgid "No logical device selected."
+msgstr "Keine logische Einheit ausgewählt."
+
+msgid "The iSCSI target can not be blank."
+msgstr "Das iSCSI-Ziel darf nicht leer sein."
+
+msgid "Server name can not be blank."
+msgstr "Servername darf nicht leer sein."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "Es wird nach verfügbaren Partitionen gesucht..."
+
+msgid "No available partitions found."
+msgstr "Keine gültigen Partitionen gefunden."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
+"inaktiviert, sondern permanent gelöscht. Möchten Sie fortfahren?"
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+"Repository-Informationen konnten nicht abgerufen werden. Details: '%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Der Speicherpoolname darf nicht leer sein."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "Netzname"
+
+msgid "State"
+msgstr "Status"
+
+msgid "Network Type"
+msgstr "Netztyp"
+
+msgid "Address Space"
+msgstr "Adressraum"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "Ungültiger Speicherpoolname. Er darf nicht '/' enthalten."
+
+msgid "Isolated: no external network connection"
+msgstr "Isolatiert: keine physisische Netzverbindung"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: nur ausgehende physische Netzverbindung"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Ãberbrückt: Virtuelle Maschinen sind direkt mit physischem Netz verbunden"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "Ziel:"
+
+msgid "Enable VLAN"
+msgstr "Virtuelles LAN (VLAN) aktivieren:"
+
+msgid "VLAN ID"
+msgstr "VLAN-ID:"
+
+msgid "Stop"
+msgstr "Stoppen"
+
+msgid "Generate a New Debug Report"
+msgstr "Neuen Debugbericht erstellen"
+
+msgid "Report Name"
+msgstr "Berichtsname"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
+"wird, wird ein Name basierend auf der aktuellen Zeit ausgewählt. Der Name "
+"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
+
+msgid "Rename a Debug Report"
+msgstr "Neuen Debugbericht erstellen"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
+"wird, wird ein Name basierend auf der aktuellen Zeit ausgewählt. Der Name "
+"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "Repository hinzufügen"
+
+msgid "Identifier"
+msgstr "Kennung"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Einzelnes Wort, eindeutige Kennung für das Repository."
+
+msgid "Textual name for the repository."
+msgstr "Textname für das Repository."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Erforderliches Feld"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL zum Repository. Unterstützte Protokolle sind http, ftp und file."
+
+msgid "Repository is a mirror"
+msgstr "Repository ist ein Spiegel."
+
+msgid "Distribution"
+msgstr "Verteilung"
+
+msgid "Distribution of the DEB repository."
+msgstr "Verteilung des DEB-Repositorys."
+
+msgid "Components"
+msgstr "Komponenten"
+
+msgid "List of components in DEB repository."
+msgstr "Liste der Komponenten im DEB-Repository."
+
+msgid "Edit Repository"
+msgstr "Repository bearbeiten"
+
+msgid "Mirror List URL"
+msgstr "Spiegellisten-URL"
+
+msgid "Yes"
+msgstr "Ja"
+
+msgid "No"
+msgstr "Nein"
+
+msgid "Capacity"
+msgstr "Kapazität"
+
+msgid "Allocated"
+msgstr "Zugeordnet"
+
+msgid "Location"
+msgstr "Position"
+
+msgid "Device path"
+msgstr "Einheitenpfad"
+
+msgid "active"
+msgstr "aktiv"
+
+msgid "inactive"
+msgstr "inaktiv"
+
+msgid "Deactivate"
+msgstr "Inaktivieren"
+
+msgid "Activate"
+msgstr "Aktivieren"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "Definition aufheben"
+
+msgid "Format"
+msgstr "Format:"
+
+msgid "Allocation"
+msgstr "Zuordnung:"
+
+msgid "Define a New Storage Pool"
+msgstr "Neuen Speicherpool definieren"
+
+msgid "Storage Pool Name"
+msgstr "Speicherpoolname"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"Der Name, mit dem die Speicherpools gekennzeichnet werden. Er darf nicht "
+"leer sein."
+
+msgid "Storage Pool Type"
+msgstr "Speicherpooltyp"
+
+msgid "Storage Path"
+msgstr "Speicherpfad"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"Der Pfad des Speicherpools. Jeder Speicherpool muss einen eindeutigen Pfad "
+"haben."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"Kimchi versucht, das Verzeichnis zu erstellen, wenn es noch nicht in Ihrem "
+"System vorhanden ist."
+
+msgid "NFS Server IP"
+msgstr "NFS-Server-IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP oder Hostname des NFS-Servers. Diese(r) kann eingegeben oder aus dem "
+"Verlauf ausgewählt werden."
+
+msgid "NFS Path"
+msgstr "NFS-Pfad"
+
+msgid "The NFS exported path on NFS server."
+msgstr "Der NFS-Exportpfad auf dem NFS-Server."
+
+msgid "iSCSI Server"
+msgstr "iSCSI-Server"
+
+msgid "Server"
+msgstr "Server"
+
+msgid "Port"
+msgstr "Port"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP oder Hostname des iSCSI-Servers. Diese(r) darf nicht leer sein."
+
+msgid "Target"
+msgstr "Ziel"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "Das iSCSI-Ziel auf dem iSCSI-Server"
+
+msgid "Add iSCSI Authentication"
+msgstr "iSCSI-Authentifizierung hinzufügen"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI-Authentifizierung"
+
+msgid "User Name"
+msgstr "Benutzername"
+
+msgid "Password"
+msgstr "Kennwort"
+
+msgid "SCSI Adapter"
+msgstr "SCSI-Adapter"
+
+msgid "Please, wait..."
+msgstr "Bitte warten..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "Vorlage hinzufügen"
+
+msgid "Where is the source media for this template? "
+msgstr "Wo ist der Quellendatenträger für diese Vorlage?"
+
+msgid "Local ISO Image"
+msgstr "Lokales ISO-Image"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "Fernes ISO-Image"
+
+msgid "Search ISOs"
+msgstr "ISOs suchen"
+
+msgid "The following ISOs are available:"
+msgstr "Die folgenden ISOs sind verfügbar:"
+
+msgid "OS: "
+msgstr "BS: "
+
+msgid "Version: "
+msgstr "Version: "
+
+msgid "Size: "
+msgstr "GröÃe: "
+
+msgid "Search more ISOs"
+msgstr "Weitere ISOs suchen"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Vorlagen aus ausgewähltem ISO erstellen"
+
+msgid "I want to use a specific ISO file"
+msgstr "Ich möchte eine bestimmte ISO-Datei verwenden"
+
+msgid "Loading default remote ISOs ..."
+msgstr "StandardmäÃige ferne ISOs werden geladen ..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Ich möchte einen benutzerdefinierten URL verwenden"
+
+msgid "Edit Template"
+msgstr "Vorlage bearbeiten"
+
+msgid "CDROM"
+msgstr "CD-ROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "Grafik"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU-Anzahl"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "Keine Vorlagen gefunden."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "Löschen ist nicht zulässig für %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s implementiert keine Aktualisierungsmethode"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Erstellen ist nicht zulässig für %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "JSON-Anfrage konnte nicht analysiert werden"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Diese API unterstützt nur JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Datenspeicher wird nicht im Modellobjekt initialisiert."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr ""
+#~ "Task kann aufgrund des folgenden Fehlers nicht gestartet werden: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr ""
+#~ "Authentifizierung für Benutzer '%(username)s' fehlgeschlagen. "
+#~ "[Fehlercode: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Sie sind nicht berechtigt, auf Kimchi zuzugreifen"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Geben Sie %(item)s an, um sich bei Kimchi anzumelden"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "%(item)s konnten nicht im Datenspeicher gefunden werden"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr ""
+#~ "Zeitlimitüberschreitung beim Ausführen des Befehls '%(cmd)s' nach %"
+#~ "(seconds)s Sekunden"
+
+#~ msgid "Help"
+#~ msgstr "Hilfe"
+
+#~ msgid "About"
+#~ msgstr "Informationen"
+
+#~ msgid "Log out"
+#~ msgstr "Abmelden"
+
+#~ msgid "Version:"
+#~ msgstr "Version:"
diff --git a/src/wok/plugins/kimchi/po/en_US.po b/src/wok/plugins/kimchi/po/en_US.po
new file mode 100644
index 0000000..a5d0d44
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/en_US.po
@@ -0,0 +1,2075 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+# Adam Litke <agl at us.ibm.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en_US\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+
+msgid "Remote ISO image is not supported by this server."
+msgstr ""
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+
+msgid "Specify a template to create a virtual machine from"
+msgstr ""
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr ""
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr ""
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr ""
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+
+msgid "Template name must be a string"
+msgstr ""
+
+msgid "Template icon must be a path to the image"
+msgstr ""
+
+msgid "Template distribution must be a string"
+msgstr ""
+
+msgid "Template distribution version must be a string"
+msgstr ""
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr ""
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr ""
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+
+msgid "All networks for the template must be specified in a list."
+msgstr ""
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr ""
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr ""
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr ""
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr ""
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr ""
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr ""
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr ""
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr ""
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+
+msgid "The SCSI host adapter name must be a string."
+msgstr ""
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+
+msgid "Storage volume name must be a string"
+msgstr ""
+
+msgid "Storage volume allocation must be an integer number"
+msgstr ""
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr ""
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+
+msgid "Network interface must be a string"
+msgstr ""
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr ""
+
+msgid "Specify name and type to create a Network"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr ""
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr ""
+
+msgid "Debug report tool not found in system"
+msgstr ""
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr ""
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr ""
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr ""
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr ""
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr ""
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr ""
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+
+msgid "There is no compatible package manager for this system."
+msgstr ""
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr ""
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr ""
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr ""
+
+msgid "Components to DEB repository must be a string"
+msgstr ""
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr ""
+
+msgid "GPG check must be a boolean value."
+msgstr ""
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr ""
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr ""
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr ""
+
+msgid "YUM Repository ID already exists"
+msgstr ""
+
+msgid "YUM Repository name must be a string"
+msgstr ""
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr ""
+
+msgid "REASON"
+msgstr ""
+
+msgid "STACK"
+msgstr ""
+
+msgid "Go to Homepage"
+msgstr ""
+
+msgid "Create a New Virtual Machine"
+msgstr ""
+
+msgid "Virtual Machine Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Please create a template first."
+msgstr ""
+
+msgid "Create a Template"
+msgstr ""
+
+msgid "Please choose a template."
+msgstr ""
+
+msgid "OS"
+msgstr ""
+
+msgid "OS Version"
+msgstr ""
+
+msgid "CPUS"
+msgstr ""
+
+msgid "Memory"
+msgstr ""
+
+msgid "Create"
+msgstr ""
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Edit Guest"
+msgstr ""
+
+msgid "General"
+msgstr ""
+
+msgid "Storage"
+msgstr ""
+
+msgid "Interface"
+msgstr ""
+
+msgid "Permission"
+msgstr ""
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "CPUs"
+msgstr ""
+
+msgid "Memory (MB)"
+msgstr ""
+
+msgid "Icon"
+msgstr ""
+
+msgid "Device"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid "Network"
+msgstr ""
+
+msgid "Type"
+msgstr ""
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr ""
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr ""
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Replace"
+msgstr ""
+
+msgid "Detach"
+msgstr ""
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr ""
+
+msgid "Reset"
+msgstr ""
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr ""
+
+msgid "Connect"
+msgstr ""
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Shut Down"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "CPU"
+msgstr ""
+
+msgid "Disk I/O"
+msgstr ""
+
+msgid "Network I/O"
+msgstr ""
+
+msgid "Livetile"
+msgstr ""
+
+msgid "No guests found."
+msgstr ""
+
+msgid "Add a Storage Device to VM"
+msgstr ""
+
+msgid "Device Type"
+msgstr ""
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr ""
+
+msgid "Storage Pool"
+msgstr ""
+
+msgid "Storage pool which volume located in"
+msgstr ""
+
+msgid "Storage Volume"
+msgstr ""
+
+msgid "Storage volume to be attached"
+msgstr ""
+
+msgid "File Path"
+msgstr ""
+
+msgid "The ISO file path in the server for CDROM."
+msgstr ""
+
+msgid "Attach"
+msgstr ""
+
+msgid "Shut down"
+msgstr ""
+
+msgid "Restart"
+msgstr ""
+
+msgid "Basic Information"
+msgstr ""
+
+msgid "OS Distro"
+msgstr ""
+
+msgid "OS Code Name"
+msgstr ""
+
+msgid "Processor"
+msgstr ""
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr ""
+
+msgid "Software Updates"
+msgstr ""
+
+msgid "Update Progress"
+msgstr ""
+
+msgid "Repositories"
+msgstr ""
+
+msgid "Debug Reports"
+msgstr ""
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+
+msgid "This field is required."
+msgstr ""
+
+msgid "Log in"
+msgstr ""
+
+msgid "Logging in..."
+msgstr ""
+
+msgid "Host"
+msgstr ""
+
+msgid "Guests"
+msgstr ""
+
+msgid "Templates"
+msgstr ""
+
+msgid "Failed to get application configuration"
+msgstr ""
+
+msgid "This is not a valid Linux path"
+msgstr ""
+
+msgid "This is not a valid URL."
+msgstr ""
+
+msgid "No such data available."
+msgstr ""
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Confirm"
+msgstr ""
+
+msgid "Warning"
+msgstr ""
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr ""
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr ""
+
+msgid "Detailed message:"
+msgstr ""
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr ""
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr ""
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+
+msgid "Max:"
+msgstr ""
+
+msgid "Utilization"
+msgstr ""
+
+msgid "Available"
+msgstr ""
+
+msgid "Read Rate"
+msgstr ""
+
+msgid "Write Rate"
+msgstr ""
+
+msgid "Received"
+msgstr ""
+
+msgid "Sent"
+msgstr ""
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Base URL"
+msgstr ""
+
+msgid "Is Mirror"
+msgstr ""
+
+msgid "URL Args"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "GPG Check"
+msgstr ""
+
+msgid "GPG Key"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Enable"
+msgstr ""
+
+msgid "Disable"
+msgstr ""
+
+msgid "Package Name"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Architecture"
+msgstr ""
+
+msgid "Repository"
+msgstr ""
+
+msgid "Update All"
+msgstr ""
+
+msgid "Updating..."
+msgstr ""
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr ""
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+
+msgid "Generated Time"
+msgstr ""
+
+msgid "Generate"
+msgstr ""
+
+msgid "Generating..."
+msgstr ""
+
+msgid "Rename"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr ""
+
+msgid "Pending..."
+msgstr ""
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+
+msgid "Power off Confirmation"
+msgstr ""
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr ""
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr ""
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+
+msgid "Attaching..."
+msgstr ""
+
+msgid "Replacing..."
+msgstr ""
+
+msgid "Successfully attached!"
+msgstr ""
+
+msgid "Successfully replaced!"
+msgstr ""
+
+msgid "Successfully detached!"
+msgstr ""
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr ""
+
+msgid "unavailable"
+msgstr ""
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+
+msgid "Create a network"
+msgstr ""
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+
+msgid "This storage pool is empty."
+msgstr ""
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+
+msgid "SCSI Fibre Channel"
+msgstr ""
+
+msgid "No SCSI adapters found."
+msgstr ""
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr ""
+
+msgid "The storage pool path can not be blank."
+msgstr ""
+
+msgid "NFS server mount path can not be blank."
+msgstr ""
+
+msgid "Invalid NFS mount path."
+msgstr ""
+
+msgid "No logical device selected."
+msgstr ""
+
+msgid "The iSCSI target can not be blank."
+msgstr ""
+
+msgid "Server name can not be blank."
+msgstr ""
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr ""
+
+msgid "No available partitions found."
+msgstr ""
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr ""
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr ""
+
+msgid "State"
+msgstr ""
+
+msgid "Network Type"
+msgstr ""
+
+msgid "Address Space"
+msgstr ""
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+
+msgid "Isolated: no external network connection"
+msgstr ""
+
+msgid "NAT: outbound physical network connection only"
+msgstr ""
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr ""
+
+msgid "Enable VLAN"
+msgstr ""
+
+msgid "VLAN ID"
+msgstr ""
+
+msgid "Stop"
+msgstr ""
+
+msgid "Generate a New Debug Report"
+msgstr ""
+
+msgid "Report Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+
+msgid "Rename a Debug Report"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr ""
+
+msgid "Identifier"
+msgstr ""
+
+msgid "Single word, unique identifier for the repository."
+msgstr ""
+
+msgid "Textual name for the repository."
+msgstr ""
+
+msgid "URL"
+msgstr ""
+
+msgid "Required Field"
+msgstr ""
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr ""
+
+msgid "Repository is a mirror"
+msgstr ""
+
+msgid "Distribution"
+msgstr ""
+
+msgid "Distribution of the DEB repository."
+msgstr ""
+
+msgid "Components"
+msgstr ""
+
+msgid "List of components in DEB repository."
+msgstr ""
+
+msgid "Edit Repository"
+msgstr ""
+
+msgid "Mirror List URL"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Capacity"
+msgstr ""
+
+msgid "Allocated"
+msgstr ""
+
+msgid "Location"
+msgstr ""
+
+msgid "Device path"
+msgstr ""
+
+msgid "active"
+msgstr ""
+
+msgid "inactive"
+msgstr ""
+
+msgid "Deactivate"
+msgstr ""
+
+msgid "Activate"
+msgstr ""
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr ""
+
+msgid "Format"
+msgstr ""
+
+msgid "Allocation"
+msgstr ""
+
+msgid "Define a New Storage Pool"
+msgstr ""
+
+msgid "Storage Pool Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+
+msgid "Storage Pool Type"
+msgstr ""
+
+msgid "Storage Path"
+msgstr ""
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+
+msgid "NFS Server IP"
+msgstr ""
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+
+msgid "NFS Path"
+msgstr ""
+
+msgid "The NFS exported path on NFS server."
+msgstr ""
+
+msgid "iSCSI Server"
+msgstr ""
+
+msgid "Server"
+msgstr ""
+
+msgid "Port"
+msgstr ""
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr ""
+
+msgid "Target"
+msgstr ""
+
+msgid "The iSCSI target on iSCSI server"
+msgstr ""
+
+msgid "Add iSCSI Authentication"
+msgstr ""
+
+msgid "iSCSI Authentication"
+msgstr ""
+
+msgid "User Name"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "SCSI Adapter"
+msgstr ""
+
+msgid "Please, wait..."
+msgstr ""
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr ""
+
+msgid "Where is the source media for this template? "
+msgstr ""
+
+msgid "Local ISO Image"
+msgstr ""
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr ""
+
+msgid "Search ISOs"
+msgstr ""
+
+msgid "The following ISOs are available:"
+msgstr ""
+
+msgid "OS: "
+msgstr ""
+
+msgid "Version: "
+msgstr ""
+
+msgid "Size: "
+msgstr ""
+
+msgid "Search more ISOs"
+msgstr ""
+
+msgid "Create Templates from Selected ISO"
+msgstr ""
+
+msgid "I want to use a specific ISO file"
+msgstr ""
+
+msgid "Loading default remote ISOs ..."
+msgstr ""
+
+msgid "Arch: "
+msgstr ""
+
+msgid "I want to use a custom URL"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "CDROM"
+msgstr ""
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr ""
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr ""
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr ""
diff --git a/src/wok/plugins/kimchi/po/es_ES.po b/src/wok/plugins/kimchi/po/es_ES.po
new file mode 100644
index 0000000..d71e621
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/es_ES.po
@@ -0,0 +1,2305 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: es_ES\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+"Se ha producido un error al obtener dispositivos de bloque. Detalles: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"Se ha producido un error al obtener información de dispositivo de bloque "
+"para %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "No se puede encontrar el archivo distro: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"No se puede analizar el archivo distro: %(filename)s. Asegúrese de que es un "
+"archivo JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"No se puede iniciar la sesión en %(portal)s del destino de host iSCSI. "
+"Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr ""
+"No se puede iniciar la sesión en el destino %(target)s del %(host)s host de "
+"iSCSI"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "El archivo ISO %(filename)s no es arrancable"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"El archivo ISO %(filename)s no tiene un registro de arranque de El Torito "
+"válido"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Entrada de validación de El Torito no válida en ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicador de arranque de El Torito no válido en ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Tipo de volumen inesperado para el volumen primario en ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Formato incorrecto mientras se leÃa el descriptor de volumen en ISO %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"El hipervisor no tiene permiso para utilizar este ISO %(filename)s. "
+"Considere moverlo a /var/lib/libvirt, o establezca el permiso de búsqueda en "
+"listas de control de accesos de archivo para el usuario '%(user)s' si es "
+"posible, o añada el '%(user)s' al grupo de vÃas de acceso ISO, o (no "
+"recomendado) 'chmod -R o+x 'path_to_iso'.Detalles: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "La máquina virtual %(name)s ya existe"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "La máquina virtual %(name)s no existe"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"No se puede recuperar la captura de pantalla para la máquina virtual "
+"detenida %(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "La imagen ISO remota no está soportada por este servidor."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede crear la máquina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede crear la máquina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede recuperar la máquina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"La dirección de gráficos en que hay que estar a la escucha debe ser IPv4 o "
+"IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr ""
+"Especifique una plantilla a partir de la que se creará una máquina virtual"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede iniciar la máquina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede detener la máquina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede suprimir la máquina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede redenominar la máquina virtual %(name)s. Detalles: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "El nombre de red debe ser una serie"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "El nombre de red debe ser una serie"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "El usuario '%(users)s' no existe."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "El usuario '%(groups)s' no existe."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede detener la máquina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede iniciar la máquina virtual %(name)s. Detalles: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "La interfaz %(iface)s no existe en la máquina virtual %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"La red %(network)s especificada para la máquina virtual %(name)s no existe"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "El tipo de interfaces de máquina virtual soportado es de red solamente"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"El nombre de red para la interfaz de máquina virtual debe ser una serie"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Especificada tarjeta de modelo de red no válida para la interfaz de máquina "
+"virtual"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Especifique el tipo y la red para añadir una interfaz de máquina virtual "
+"nueva"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "La plantilla %(name)s ya existe"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr ""
+"La red '%(network)s' especificada para la plantilla %(template)s no existe"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"La agrupación de almacenamiento %(pool)s especificada para la plantilla %"
+"(template)s no existe"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+"La agrupación de almacenamiento %(pool)s especificada para la plantilla %"
+"(template)s no está activa"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Parámetro no válido '%(param)s' especificado para CDROM."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"La red %(network)s especificada para la plantilla %(template)s no está activa"
+
+msgid "Template name must be a string"
+msgstr "El nombre de plantilla debe ser una serie"
+
+msgid "Template icon must be a path to the image"
+msgstr "El icono de plantilla debe ser una vÃa de acceso a la imagen"
+
+msgid "Template distribution must be a string"
+msgstr "La distribución de plantilla debe ser una serie"
+
+msgid "Template distribution version must be a string"
+msgstr "La versión de distribución de plantilla debe ser una serie"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "El número de CPUs debe ser un entero"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "La cantidad de memoria (MB) debe ser un entero mayor que 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+"URI de agrupación de almacenamiento no válido %(value)s especificado para la "
+"plantilla"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "Especifique una imagen de ISO como CDROM para crear una plantilla"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Todas las redes para la plantilla deben especificarse en una lista."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "No se puede crear la plantilla debido a un error: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "No se puede suprimir la plantilla debido a un error: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "La agrupación de almacenamiento %(name)s ya existe"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "La agrupación de almacenamiento %(name)s no existe"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+"Especifique %(item)s para poder crear la agrupación de almacenamiento %(name)"
+"s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "No se puede suprimir la agrupación de almacenamiento activa %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "No se pueden listar agrupaciones de almacenamiento. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede crear la agrupación de almacenamiento %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"No se puede obtener el número de volúmenes de almacenamiento en la "
+"agrupación de almacenamiento %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede activar la agrupación de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede desactivar la agrupación de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede suprimir la agrupación de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"No se puede crear la agrupación de NFS ya que la vÃa de acceso de "
+"exportación %(path)s podrÃa bloquearse durante el montaje"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"No se puede crear la agrupación de NFS ya que el montaje de la vÃa de acceso "
+"de exportación %(path)s ha fallado"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Tipo de agrupación de almacenamiento no soportado: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "La vÃa de acceso de la agrupación de almacenamiento debe ser una serie"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr ""
+"El host de la agrupación de almacenamiento debe ser un IP o nombre de host"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr ""
+"El parámetro de los dispositivos de agrupación de almacenamiento debe ser "
+"una lista"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "El IQN destino de una agrupación de iSCSI debe ser una serie"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"El puerto de un servidor de almacenamiento remoto debe ser un entero entre 1 "
+"y 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr ""
+"Especifique el nombre y el tipo para crear una agrupación de almacenamiento"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s no es un disco/partición. No se ha podido añadir a la agrupación %"
+"(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Los discos de parámetro sólo pueden actualizarse para la agrupación de "
+"almacenamiento lógico."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "El nombre del adaptador de host SCSI debe ser una serie."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr ""
+"La agrupación de almacenamiento kimchi_isos está reservada para uso interno"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"No se puede activar la agrupación de almacenamiento NFS %(name)s. El "
+"servidor NFS %(server)s está fuera de alcance."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"No se puede desactivar la agrupación de almacenamiento NFS %(name)s. El "
+"servidor NFS %(server)s está fuera de alcance."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"No se puede desactivar la agrupación %(name)s ya que está asociada con "
+"algunas plantillas"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"No se puede suprimir la agrupación %(name)s ya que está asociada con algunas "
+"plantillas"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"Un grupo de volúmenes denominado '%(name)s' ya existe. Elija otro nombre "
+"para crear la agrupación lógica."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"No se puede actualizar la base de datos con la información de exploración "
+"profunda debido a un error: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "El volumen de almacenamiento %(name)s ya existe"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"El volumen de almacenamiento %(name)s no existe en la agrupación de "
+"almacenamiento %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+"Especifique %(item)s para poder crear el volumen de almacenamiento %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"No se pueden listar los volúmenes de almacenamiento porque la agrupación de "
+"almacenamiento %(pool)s no está activa"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"No se puede crear el volumen de almacenamiento %(name)s en la agrupación de "
+"almacenamiento %(pool)s. Detalles: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"No se pueden listar volúmenes de almacenamiento en la agrupación de "
+"almacenamiento %(pool)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+"No se pueden borrar los volúmenes de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede suprimir el volumen de almacenamiento %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede redimensionar el volumen de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"El tipo de almacenamiento %(type)s no da soporte a crear y suprimir volúmenes"
+
+msgid "Storage volume name must be a string"
+msgstr "El nombre de volumen de almacenamiento debe ser una serie"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "La asignación de volumen de almacenamiento debe ser un número entero"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "El volumen de almacenamiento requiere un nombre de volumen"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"No se puede actualizar la base de datos con la información de volumen de "
+"almacenamiento debido a un error: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "La interfaz %(name)s no existe"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "La red %(name)s ya existe"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "La red %(name)s no existe"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"La subred %(subnet)s especificada para la red %(network)s no es válida."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "Especifique una interfaz de red para crear una red puenteada %(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "No se puede suprimir la red activa %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+"La interfaz %(iface)s especificada para la red %(network)s ya está en uso"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "La interfaz debe ser dispositivo de puente, enlazado o NIC simple."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "No se puede crear la red %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "No se puede encontrar una dirección IP libre para la red '%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "La interfaz %(iface)s ya existe"
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Los tipos de red soportados son aislada, NAT y puente"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"La subred de red debe ser una serie con dirección IP y prefijo o máscara de "
+"red"
+
+msgid "Network interface must be a string"
+msgstr "La interfaz de red debe ser una serie"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "El ID de VLAN de red debe ser un entero entre 1 y 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Especifique el nombre y el tipo para crear una red"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"No se puede suprimir la red %(name)s. Hay algunas máquinas virtuales %(vms)s "
+"y/o plantillas enlazadas a esta red."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"No se puede desactivar la red %(name)s. Hay algunas máquinas virtuales %(vms)"
+"s y/o plantillas enlazadas a esta red."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"El dispositivo de puente %(name)s no puede ser el dispositivo de conexión "
+"troncal de una VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "No se puede activar la interfaz %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"No se puede activar la interfaz %(iface)s. Compruebe el estado del enlace "
+"fÃsico."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "El informe de depuración %(name)s no existe"
+
+msgid "Debug report tool not found in system"
+msgstr "Herramienta de informes de depuración no encontrada en el sistema"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+"No se puede crear el informe de depuración %(name)s. Detalles: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede generar el informe de depuración %(name)s. Detalles: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"Un grupo de volúmenes denominado '%(name)s' ya existe. Elija otro nombre "
+"para crear la agrupación lógica."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Kimchi no utilizaba el servidor de almacenamiento %(server)s"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' no existe"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "La partición %(name)s no existe en el host"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"No se puede concluir la máquina host ya que hay máquinas virtuales en "
+"ejecución"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"No se puede rearrancar la máquina host ya que hay máquinas virtuales en "
+"ejecución"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "No se ha encontrado el dispositivo de nodo '%(name)s'"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "No hay paquetes marcados para su actualización"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "El paquete %(name)s no está marcado para su actualización."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Se ha producido un error al obtener paquetes marcados para su actualización. "
+"Detalles: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "No hay ningún gestor de paquetes compatible para este sistema."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s no válido"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Tipo de almacenamiento no válido. Tipos soportados: 'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"Se ha producido un error al crear el nuevo dispositivo de almacenamiento: %"
+"(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+"Se ha producido un error al actualizar el dispositivo de almacenamiento: %"
+"(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+"Se ha producido un error al eliminar el dispositivo de almacenamiento: %"
+"(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Especifique el tipo y la vÃa de acceso para añadir un disco de máquina "
+"virtual nuevo"
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+"Especifique la vÃa de acceso para actualizar el disco de máquina virtual"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Especifique el tipo y la vÃa de acceso para añadir un disco de máquina "
+"virtual nuevo"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "El ID de repositorio YUM debe ser una serie de una sola palabra."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "El URL de repositorio debe ser http://, ftp:// o archivo:// URL."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"La configuración de repositorio es un diccionario con valores especÃficos "
+"según el tipo de repositorio."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "El repositorio de Distribución a DEB debe ser una serie"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "El repositorio de Componentes a DEB debe estar listado en una matriz"
+
+msgid "Components to DEB repository must be a string"
+msgstr "El repositorio de Componentes a DEB debe ser una serie"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "El nombre del repositorio YUM debe ser una serie."
+
+msgid "GPG check must be a boolean value."
+msgstr "La comprobación de GPG debe ser un valor booleano."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "La clave GPG debe ser un URL que apunta al archivo blindado por ASCII."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "No se ha podido actualizar el repositorio %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "El repositorio %(repo_id)s no existe."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+"La herramienta de gestión de repositorio no se ha reconocido para su sistema."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "El repositorio %(repo_id)s ya está habilitado."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "El repositorio %(repo_id)s ya está inhabilitado."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "No se ha podido eliminar el repositorio %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"No se ha podido grabar el archivo de configuración del repositorio %"
+"(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Especifique la distribución del repositorio para crear un repositorio de DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "No se ha podido habilitar el repositorio %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "No se ha podido inhabilitar el repositorio %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "El ID de repositorio de YUM ya existe"
+
+msgid "YUM Repository name must be a string"
+msgstr "El nombre del repositorio de YUM debe ser una serie"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "No se pueden listar repositorios. Detalles: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "No se puede recuperar información del repositorio. Detalles: '%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "No se puede añadir el repositorio. Detalles: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "No se puede eliminar el repositorio. Detalles: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "CÃDIGO DE ERROR"
+
+msgid "REASON"
+msgstr "RAZÃN"
+
+msgid "STACK"
+msgstr "PILA"
+
+msgid "Go to Homepage"
+msgstr "Ir a la página inicial"
+
+msgid "Create a New Virtual Machine"
+msgstr "Crear una nueva máquina virtual"
+
+msgid "Virtual Machine Name"
+msgstr "Nombre de máquina virtual"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"El nombre que se utiliza para identificar la máquina virtual. Si se omite, "
+"se elegirá un nombre basándose en la plantilla utilizada."
+
+msgid "Template"
+msgstr "Plantilla"
+
+msgid "Please create a template first."
+msgstr "Cree una plantilla primero."
+
+msgid "Create a Template"
+msgstr "Crear una plantilla"
+
+msgid "Please choose a template."
+msgstr "Elija una plantilla."
+
+msgid "OS"
+msgstr "SO"
+
+msgid "OS Version"
+msgstr "Versión del SO"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Memoria"
+
+msgid "Create"
+msgstr "Crear"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "Edit Guest"
+msgstr "Editar invitado"
+
+msgid "General"
+msgstr "General"
+
+msgid "Storage"
+msgstr "Almacenamiento"
+
+msgid "Interface"
+msgstr "Interfaz"
+
+msgid "Permission"
+msgstr "Versión"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Nombre"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "Memoria"
+
+msgid "Icon"
+msgstr "Icono"
+
+msgid "Device"
+msgstr "Nombre de dispositivo"
+
+msgid "Path"
+msgstr "VÃa de acceso NFS"
+
+msgid "Network"
+msgstr "Red"
+
+msgid "Type"
+msgstr "Tipo"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Todo"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "Proveedor"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Guardar"
+
+msgid "Replace"
+msgstr "Sustituir"
+
+msgid "Detach"
+msgstr "Desconectar"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "Iniciar"
+
+msgid "Reset"
+msgstr "Restablecer"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "Acciones"
+
+msgid "Connect"
+msgstr "Conectar"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "Editar"
+
+msgid "Shut Down"
+msgstr "Concluir"
+
+msgid "Delete"
+msgstr "Suprimir"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "E/S de disco"
+
+msgid "Network I/O"
+msgstr "E/S de red"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "No se ha encontrado invitados."
+
+msgid "Add a Storage Device to VM"
+msgstr "Añadir un dispositivo de almacenamiento a VM"
+
+msgid "Device Type"
+msgstr "Tipo de dispositivo"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "El tipo de dispositivo. Actualmente sólo está soportado \"cdrom\"."
+
+msgid "Storage Pool"
+msgstr "Agrupación de almacenamiento"
+
+msgid "Storage pool which volume located in"
+msgstr "La vÃa de acceso de la agrupación de almacenamiento debe ser una serie"
+
+msgid "Storage Volume"
+msgstr "Nombre de agrupación de almacenamiento"
+
+msgid "Storage volume to be attached"
+msgstr "El nombre de volumen de almacenamiento debe ser una serie"
+
+msgid "File Path"
+msgstr "VÃa de acceso de archivo"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "La vÃa de acceso del archivo ISO en el servidor para el CDROM."
+
+msgid "Attach"
+msgstr "Conectar"
+
+msgid "Shut down"
+msgstr "Concluir"
+
+msgid "Restart"
+msgstr "Reiniciar"
+
+msgid "Basic Information"
+msgstr "Información básica"
+
+msgid "OS Distro"
+msgstr "Distro de SO"
+
+msgid "OS Code Name"
+msgstr "Nombre de código de SO"
+
+msgid "Processor"
+msgstr "Procesador"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "EstadÃsticas del sistema"
+
+msgid "Software Updates"
+msgstr "Actualizaciones de software"
+
+msgid "Update Progress"
+msgstr "Actualizar progreso"
+
+msgid "Repositories"
+msgstr "Repositorios"
+
+msgid "Debug Reports"
+msgstr "Informes de depuración"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"El nombre de usuario o contraseña que ha especificado es incorrecto. Por "
+"favor, vuelva a intentarlo."
+
+msgid "This field is required."
+msgstr "Este campo es obligatorio."
+
+msgid "Log in"
+msgstr "Iniciar sesión"
+
+msgid "Logging in..."
+msgstr "Iniciando sesión..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "Invitados"
+
+msgid "Templates"
+msgstr "Plantillas"
+
+msgid "Failed to get application configuration"
+msgstr "No se ha podido obtener la configuración de la aplicación"
+
+msgid "This is not a valid Linux path"
+msgstr "No es una vÃa de acceso de Linux válida"
+
+msgid "This is not a valid URL."
+msgstr "No es un URL válido."
+
+msgid "No such data available."
+msgstr "No hay datos de ese tipo disponibles."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"No se puede contactar con el sistema host, Verifique que el sistema host "
+"está activo y que tiene conectividad de red con él. Respuesta de solicitud "
+"HTTP %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Confirmación de supresión"
+
+msgid "OK"
+msgstr "Aceptar"
+
+msgid "Confirm"
+msgstr "Confirmar"
+
+msgid "Warning"
+msgstr "Aviso"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Cargando..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Reintentar"
+
+msgid "Detailed message:"
+msgstr "Mensaje detallado:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "No es un archivo ISO válido."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Tardará mucho tiempo. ¿Desea continuar?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "Esto suprimirá permanentemente la plantilla. ¿Desea continuar?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"No se puede concluir el sistema ya que hay algunas máquinas virtuales en "
+"ejecución."
+
+msgid "Max:"
+msgstr "Máx.:"
+
+msgid "Utilization"
+msgstr "Utilización"
+
+msgid "Available"
+msgstr "Disponible"
+
+msgid "Read Rate"
+msgstr "Velocidad de lectura"
+
+msgid "Write Rate"
+msgstr "Velocidad de escritura"
+
+msgid "Received"
+msgstr "Recibido"
+
+msgid "Sent"
+msgstr "Enviado"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"Concluir o reiniciar el host hará que se pierda el trabajo no guardado. "
+"¿Desea continuar para concluir/reiniciar?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"El repositorio se eliminará de forma permanente y no se puede recuperar. "
+"¿Desea continuar?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL base"
+
+msgid "Is Mirror"
+msgstr "Es duplicado"
+
+msgid "URL Args"
+msgstr "Args de URL"
+
+msgid "Enabled"
+msgstr "Habilitado"
+
+msgid "GPG Check"
+msgstr "Comprobación GPG"
+
+msgid "GPG Key"
+msgstr "Clave GPG"
+
+msgid "Add"
+msgstr "Añadir"
+
+msgid "Remove"
+msgstr "Eliminar"
+
+msgid "Enable"
+msgstr "Habilitar"
+
+msgid "Disable"
+msgstr "Inhabilitar"
+
+msgid "Package Name"
+msgstr "Nombre de paquete"
+
+msgid "Version"
+msgstr "Versión"
+
+msgid "Architecture"
+msgstr "Arquitectura"
+
+msgid "Repository"
+msgstr "Repositorio"
+
+msgid "Update All"
+msgstr "Actualizar todo"
+
+msgid "Updating..."
+msgstr "Actualizando..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "No se han podido actualizar paquetes."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"El informe de depuración se eliminará permanentemente y no se puede "
+"recuperar. ¿Desea continuar?"
+
+msgid "Generated Time"
+msgstr "Tiempo generado"
+
+msgid "Generate"
+msgstr "Generar"
+
+msgid "Generating..."
+msgstr "Generando..."
+
+msgid "Rename"
+msgstr "Redenominar"
+
+msgid "Download"
+msgstr "Descargar"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr ""
+"El nombre de informe debe contener sólo letras, dÃgitos y/o guión ('-')."
+
+msgid "Pending..."
+msgstr "Cargando..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"Esto suprimirá la máquina virtual y sus discos virtuales. Esta operación no "
+"puede deshacerse. ¿Desea continuar?"
+
+msgid "Power off Confirmation"
+msgstr "Confirmación de supresión"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "Confirmación de supresión"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "Confirmación de supresión"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "Esto suprimirá permanentemente la plantilla. ¿Desea continuar?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Este CDROM se desconectará de forma permanente pero puede volver a "
+"conectarlo. ¿Desea continuar para desconectarlo?"
+
+msgid "Attaching..."
+msgstr "Conectando..."
+
+msgid "Replacing..."
+msgstr "Sustituyendo..."
+
+msgid "Successfully attached!"
+msgstr "¡Conectado correctamente!"
+
+msgid "Successfully replaced!"
+msgstr "¡Sustituido correctamente!"
+
+msgid "Successfully detached!"
+msgstr "¡Desconectado correctamente!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "El ID de VLAN debe estar entre 1 y 4094."
+
+msgid "unavailable"
+msgstr "no disponible"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"Esta acción interrumpirá la conectividad de red para cualquier máquina "
+"virtual que dependa de esta red."
+
+msgid "Create a network"
+msgstr "Crear una red"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Esta agrupación de almacenamiento no es persistente. En lugar de desactivar, "
+"esta acción la suprimirá permanentemente. ¿Desea continuar?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+"Esto suprimirá permanentemente la agrupación de almacenamiento. ¿Desea "
+"continuar?"
+
+msgid "This storage pool is empty."
+msgstr "Esta agrupación de almacenamiento está vacÃa."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Dará formato al disco y se perderán los datos que tenga en él. ¿Está seguro "
+"de que desea continuar? "
+
+msgid "SCSI Fibre Channel"
+msgstr "Canal de fibra de SCSI"
+
+msgid "No SCSI adapters found."
+msgstr "No se han encontrado adaptadores SCSI."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "El nombre de la agrupación de almacenamiento no puede estar en blanco."
+
+msgid "The storage pool path can not be blank."
+msgstr ""
+"La vÃa de acceso de la agrupación de almacenamiento no puede estar en blanco."
+
+msgid "NFS server mount path can not be blank."
+msgstr "La vÃa de acceso de montaje del servidor NFS no puede estar en blanco."
+
+msgid "Invalid NFS mount path."
+msgstr "VÃa de acceso de montaje de NFS no válida."
+
+msgid "No logical device selected."
+msgstr "No se ha seleccionado ningún dispositivo lógico."
+
+msgid "The iSCSI target can not be blank."
+msgstr "El destino iSCSI no puede estar en blanco."
+
+msgid "Server name can not be blank."
+msgstr "El nombre de servidor no puede estar en blanco."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "Buscando particiones disponibles..."
+
+msgid "No available partitions found."
+msgstr "No se han encontrado particiones disponibles."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Esta agrupación de almacenamiento no es persistente. En lugar de desactivar, "
+"esta acción la suprimirá permanentemente. ¿Desea continuar?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "No se puede recuperar información del repositorio. Detalles: '%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "El nombre de la agrupación de almacenamiento no puede estar en blanco."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "Nombre de red"
+
+msgid "State"
+msgstr "Estado"
+
+msgid "Network Type"
+msgstr "Tipo de red"
+
+msgid "Address Space"
+msgstr "Espacio de direcciones"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+"Nombre de agrupación de almacenamiento no válido. No debe contener '/'."
+
+msgid "Isolated: no external network connection"
+msgstr "Aislado: no hay conexión de red fÃsica"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: conexión de red fÃsica saliente solamente"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Puenteado: Las máquinas virtuales están conectadas a la red fÃsica "
+"directamente"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "Destino:"
+
+msgid "Enable VLAN"
+msgstr "Habilitar VLAN:"
+
+msgid "VLAN ID"
+msgstr "ID de VLAN:"
+
+msgid "Stop"
+msgstr "Detener"
+
+msgid "Generate a New Debug Report"
+msgstr "Generar un Informe de depuración nuevo"
+
+msgid "Report Name"
+msgstr "Nombre de informe"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"El nombre que se utiliza para identificar el informe. Si se omite, se "
+"elegirá un nombre basándose en la hora actual. El nombre puede contener: "
+"letras, dÃgitos y guión (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "Generar un Informe de depuración nuevo"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"El nombre que se utiliza para identificar el informe. Si se omite, se "
+"elegirá un nombre basándose en la hora actual. El nombre puede contener: "
+"letras, dÃgitos y guión (\"-\")."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "Añadir un repositorio"
+
+msgid "Identifier"
+msgstr "Identificador"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Identificador exclusivo de una sola palabra para el repositorio."
+
+msgid "Textual name for the repository."
+msgstr "Nombre textual para el repositorio."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Campo obligatorio"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL al repositorio. Los protocolos soportados son http, ftp y archivo."
+
+msgid "Repository is a mirror"
+msgstr "El repositorio es un duplicado."
+
+msgid "Distribution"
+msgstr "Distribución"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribución del repositorio DEB."
+
+msgid "Components"
+msgstr "Componentes"
+
+msgid "List of components in DEB repository."
+msgstr "Lista de componentes en el repositorio DEB."
+
+msgid "Edit Repository"
+msgstr "Editar repositorio"
+
+msgid "Mirror List URL"
+msgstr "URL de lista duplicada"
+
+msgid "Yes"
+msgstr "SÃ"
+
+msgid "No"
+msgstr "No"
+
+msgid "Capacity"
+msgstr "Capacidad"
+
+msgid "Allocated"
+msgstr "Asignado"
+
+msgid "Location"
+msgstr "Ubicación"
+
+msgid "Device path"
+msgstr "VÃa de acceso del dispositivo"
+
+msgid "active"
+msgstr "activo"
+
+msgid "inactive"
+msgstr "inactivo"
+
+msgid "Deactivate"
+msgstr "Desactivar"
+
+msgid "Activate"
+msgstr "Activar"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "No definir"
+
+msgid "Format"
+msgstr "Formato:"
+
+msgid "Allocation"
+msgstr "Asignado:"
+
+msgid "Define a New Storage Pool"
+msgstr "Definir una agrupación de almacenamiento nueva"
+
+msgid "Storage Pool Name"
+msgstr "Nombre de agrupación de almacenamiento"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"El nombre que se utiliza para identificar las agrupaciones de almacenamiento "
+"y no debe estar vacÃo."
+
+msgid "Storage Pool Type"
+msgstr "Tipo de agrupación de almacenamiento"
+
+msgid "Storage Path"
+msgstr "VÃa de acceso de almacenamiento"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"La vÃa de acceso de la agrupación de almacenamiento. Cada agrupación de "
+"almacenamiento debe tener una vÃa de acceso exclusiva."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr "Kimchi intentará crear el directorio cuando no existe en el sistema."
+
+msgid "NFS Server IP"
+msgstr "IP de Servidor NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP o nombre de host de servidor NFS. Puede especificarse o elegirse del "
+"historial."
+
+msgid "NFS Path"
+msgstr "VÃa de acceso NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "La vÃa de acceso exportada de NFS en el servidor NFS."
+
+msgid "iSCSI Server"
+msgstr "Servidor iSCSI"
+
+msgid "Server"
+msgstr "Servidor"
+
+msgid "Port"
+msgstr "Puerto"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP o nombre de host de servidor iSCSI. No debe estar vacÃo."
+
+msgid "Target"
+msgstr "Destino"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "El destino iSCSI en el servidor iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "Añadir Autenticación iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Autenticación iSCSI"
+
+msgid "User Name"
+msgstr "Nombre de usuario"
+
+msgid "Password"
+msgstr "Contraseña"
+
+msgid "SCSI Adapter"
+msgstr "Adaptador SCSI"
+
+msgid "Please, wait..."
+msgstr "Por favor, espere..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "Añadir plantilla"
+
+msgid "Where is the source media for this template? "
+msgstr "¿Dónde está el soporte de origen para esta plantilla?"
+
+msgid "Local ISO Image"
+msgstr "Imagen ISO local"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "Imagen ISO remota"
+
+msgid "Search ISOs"
+msgstr "Buscar ISOs"
+
+msgid "The following ISOs are available:"
+msgstr "Las siguientes ISO están disponibles:"
+
+msgid "OS: "
+msgstr "SO: "
+
+msgid "Version: "
+msgstr "Versión: "
+
+msgid "Size: "
+msgstr "Tamaño: "
+
+msgid "Search more ISOs"
+msgstr "Buscar más ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Crear plantillas a partir de ISO seleccionadas"
+
+msgid "I want to use a specific ISO file"
+msgstr "Deseo utilizar un archivo ISO especÃfico"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Cargando ISO remotas predeterminadas ..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Deseo utilizar un URL personalizado"
+
+msgid "Edit Template"
+msgstr "Editar plantilla"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "Gráficos"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "Número de CPU"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "No se han encontrado plantillas."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "Suprimir no está permitido para %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s no implementa método de actualización"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Crear no está permitido para %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "No se puede analizar la solicitud JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Esta API sólo da soporte a JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "El almacén de datos no se ha iniciado en el objeto de modelo."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "No se puede iniciar la tarea debido a un error: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr ""
+#~ "La autenticación ha fallado para el usuario '%(username)s'. [Código de "
+#~ "error: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "No tiene autorización para acceder a Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Especifique %(item)s para iniciar la sesión en Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "No se puede encontrar %(item)s en el almacén de datos"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr ""
+#~ "Tiempo de espera excedido al ejecutar el mandato '%(cmd)s' después de %"
+#~ "(seconds)s segundos"
+
+#~ msgid "Help"
+#~ msgstr "Ayuda"
+
+#~ msgid "About"
+#~ msgstr "Acerca de"
+
+#~ msgid "Log out"
+#~ msgstr "Finalizar sesión"
+
+#~ msgid "Version:"
+#~ msgstr "Versión:"
diff --git a/src/wok/plugins/kimchi/po/fr_FR.po b/src/wok/plugins/kimchi/po/fr_FR.po
new file mode 100644
index 0000000..b996e8a
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/fr_FR.po
@@ -0,0 +1,2338 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2014-08-27 21:30+0000\n"
+"Last-Translator: BobSynfig\n"
+"Language-Team: French (http://www.transifex.com/projects/p/kimchi/language/"
+"fr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fr_FR\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr "Paramètre inconnu %(value)s"
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr "\"_cap\" spécifiée inconnue"
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr "\"_passthrough\" doit être \"true\" ou \"false\""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr "\"_passthrough_affected_by\" doit être un nom de périphérique"
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "Erreur durant l'accès aux périphériques de bloc. Détails: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"Erreur durant l'obtention de l'information sur le périphérique de bloc %"
+"(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Impossible de trouver le fichier de distro: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"Impossible de parser le fichier de distro: %(filename)s. Veuillez vous "
+"assurer qu'il s'agit d'un fichier JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"Impossible de se connecter à l'hôte cible iSCSI %(portal)s. Détails: %(err)s "
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Impossible de se connecter à l'hôte iSCSI %(host)s cible %(target)s"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr "Impossible de trouver le fichier ISO %(filename)s"
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "Le fichier ISO %(filename)s n'est pas bootable"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"Le fichier ISO %(filename)s n'a pas d'enregistrement de boot El Torito valide"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Entrée de validation El Torito invalide dans l'ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicateur de boot El Torito invalide dans l'ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Type de volume inattendu pour le volume primaire dans l'ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Mauvais format durant la lecture du descripteur de volume dans l'ISO %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"L'hyperviseur n'a pas la permission d'utiliser cet ISO %(filename)s. "
+"Veuillez considérer de le déplacer sous /var/lib/libvirt,, ou de définir la "
+"permission de recherche sur les listes de contrpole d'accès fichier pour "
+"l'utilisateur '%(user)s' si possible, ou ajouter le '%(user)s' au groupe de "
+"chemins d'ISO, ou (non recommandé) 'chmod -R o+x 'chemin_vers_iso'.Détails: "
+"%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+"Une erreur est survenue lors de la détection de l'information d'OS de "
+"l'image."
+
+msgid "No OS information found in given image."
+msgstr "Aucune information d'OS trouvée sur l'image donnée."
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr "Impossible de lire le fichier image %(filename)s"
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+"Le fichier image doit être un fichier existant sur le système. %(filename)s "
+"n'est pas une donnée valide."
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "La machine virtuelle %(name)s existe déjà "
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "La machine virtuelle %(name)s n'existe pas"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+"Impossible de renommer la machine virtuelle %(name)s. Le nom %(new_name)s "
+"est déja utilisé ou la machine virtuelle n'est pas éteinte."
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Impossible de récupérer une capture d'écran pour la machine virtuelle "
+"stoppée %(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "L'image ISO distante n'est pas supportée par le serveur."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr "Copie d'écran non supportée par la machine virtuelle %(name)s"
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossible de créer la machine virtuelle %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de mettre à jour la machine virtuelle %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de récupérer la machine virtuelle %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr "Impossible de se connecter à la machine virtuelle éteinte %(name)s."
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "L'adresse d'écoute du graphics doit être IPv4 ou IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Spécifier un modèle à partir duquel créer une machine virtuelle"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossible de démarrer la machine virtuelle %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de mettre hors tension la machine virtuelle %(name)s. Détails: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de supprimer la machine virtuelle %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de réinitrialiser la machine virtuelle %(name)s. Détails: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "Le nom d'utilisateur doit être une chaîne de caractères"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "Le nom de groupe doit être une chaîne de caractères"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "Le(s) utilisateur(s) '%(users)s' n'existe(nt) pas"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "Le(s) groupe(s) '%(groups)s' n'existe(nt) pas"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossible d'éteindre la machine virtuelle %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible d'accéder aux metadata de la machine virtuelle %(name)s. Détails: "
+"%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr "Le mot de passe de console invitée doit être une chaîne de caractères."
+
+msgid "The life time for the guest console password must be a number."
+msgstr "La durée de vie du mot de passe de console invitée doit être un nombre"
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+"La machine virtuelle %(vmid)s ne peut pas contenir le périphérique hôte "
+"directement assigné %(dev_name)s."
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+"The périphérique hôte %(dev_name)s ne peut être directement assigné à la "
+"machine virtuelle"
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr "\"name\" doit être un nom de périphérique"
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "L'interface %(iface)s n'existe pas dans la machine virtuelle %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"Le réseau %(network)s spécifié pour la machine virtuelle %(name)s n'existe "
+"pas"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+"Le type d'interface de machine virtuelle supporté est réseau uniquement"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"Le nom de réseau pour l'interface de la machine virtuelle doit être une "
+"chaîne de caractères"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Modèle de carte réseau spécifié invalide pour l'interface de machine "
+"virtuelle"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Spécifier le type et le réseau à ajouter à la nouvelle interface de la "
+"machine virtuelle"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Le modèle %(name)s existe déjà "
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr ""
+"Le réseau '%(network)s' spécifié pour le modèle %(template)s n'existe pas"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Le pool de stockage spécifié %(pool)s pour le modèle %(template)s n'existe "
+"pas"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+"Le pool de stockage spécifié %(pool)s pour le modèle %(template)s n'est pas "
+"actif"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Paramètres '%(param)s' spécifié invalide pour le CDROM"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"Le réseau %(network)s spécifié pour le modèle %(template)s n'est pas actif"
+
+msgid "Template name must be a string"
+msgstr "Le modèle de nom doit être une chaîne de caractères"
+
+msgid "Template icon must be a path to the image"
+msgstr "Le modèle d'icone doit être un chemin vers l'image"
+
+msgid "Template distribution must be a string"
+msgstr "Le modèle de distribution doit être une chaîne de caractères"
+
+msgid "Template distribution version must be a string"
+msgstr ""
+"Le modèle de version de distribution doit être une chaîne de caractères"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "Le nombre de CPU doit être un nombre entier supérieur à 0"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "La quantité de mémoire (Mo) doit être un nombre entier supérieur à 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Le CDROM modèle doit être un fichier ISO local ou distant"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "URI %(value)s du pool de stockage spécifiée invalide pour le modèle"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+"Spécifiez une image ISO comme CDROM ou une image de base pour créer un modèle"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Tous les réseaux pour le modèle doivent être spécifiés dans une liste"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr "Le volume %(volume)s n'est pas dans le pool de stockage %(pool)s"
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "Impossible de créer le modèle à cause de l'erreur: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "Impossilbe de supprimer le modèle à cause de l'erreur: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr "La taille de disque doit être un entier supérieur à 1Go."
+
+msgid "Template base image must be a valid local image file"
+msgstr "L'image de base de modèle doit petre un fichier image local valide"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr "Ne peut identifier le format de l'image de base %(path)s"
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+"Dans la topologie de CPU, chaque élément doit être un entier strictement "
+"positif."
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Le pool de stockage %(name)s existe déjà "
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Le pool de stockage %(name)s n'existe pas"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Spécifier %(item)s afin de créer le pool de stockage %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Impossible de supprimer le pool de stockage actif %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Impossible de lister les pools de stockage. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Impossilble de créer le pool de stockage %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Impossible d'obtenir le nombre de volumes de stockage dans le pool de "
+"stockage%(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Impossible d'activer le pool de stockage %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de désactiver le pool de stockage %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de supprimer le pool de stockage %(name)s. Détails: %(err)s "
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"Impossible de créer le Pool NFS du fait que le chemin d'export %(path)s "
+"pourrait se bloquer durant le montage"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"Impossible de créer le pool NFS du fait que le montage du chemin d'export %"
+"(path)s a échoué"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Type de pool de stockage non supporté: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+"Les types de pool de stockage supportés sont: dir, netfs, logical, iscsi, "
+"isci et kimchi-iso"
+
+msgid "Storage pool path must be a string"
+msgstr "Le chemin du pool de stockage doit être une chaîne de caractères"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "L'hôte du pool de stockage doit être une IP ou un nom d'hôte"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Le paramètre de périphérique de pool de stockage doit être une list"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "La cible IQN d'un pool iSCSI doit être une chaîne de caractères"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"Le port d'un serveur de stockage distant doit être un nombre entier entre 1 "
+"et 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+"Le nom d'utilisateur de la cible iSCSI doit être une chaîne de caractères"
+
+msgid "iSCSI target password must be a string"
+msgstr "Le mot de passe de la cible iSCSI doit être une chaîne de caractères"
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Spécifier un nom et un type pour créer un pool de stockage"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s n'est pas un(e) disque/partition valide. N'a pu l'ajouter au pool %"
+"(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr "Impossible d'agrandir le pool logique %(pool)s. Détails: %(err)s"
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Les disques en paramètre peuvent seulement être mis à jour pour un pool de "
+"stockage logique."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "Le nom d'adaptateur de l'hôte SCSI doit être une chapine de caractères"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "Le pool de stockage kimchi_isos est réservé à un usage interne"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossible d'activer le pool de stockage NFS%(name)s. Le serveur NFS %"
+"(server)s n'est pas joignable."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossible de désactiver le pool de stockage NFS%(name)s. Le serveur NFS %"
+"(server)s n'est pas joignable."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossible de désactiver le pool %(name)s du fait qu'il est associé à des "
+"modèles"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossible de supprimer le pool %(name)s du fait qu'il est associé à des "
+"modèles"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"Un groupe de volume appelé '%(name)s' existe déjà . Veuillez choisir un autre "
+"nom pour créer le pool logique."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"Impossible de mettre à jour la base de données avec les informations de scan "
+"profond à cause de l'erreur: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Le volume de stockage %(name)s existe déjà "
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"Le volume de stockage %(name)s n'existe pas dans le pool de stockage %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+"Impossible de créer le volume de stockage %(volume)s car le pool de stockage "
+"%(pool)s n'est pas actif"
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Spécifier %(item)s afin de créer le volume de stockage %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"Impossible de lister les volumes de stockage car le pool de stockage %(pool)"
+"s n'est pas actif"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"Impossible de créer le volume de stockage %(name)s dans le pool de stockage %"
+"(pool)s. Détails: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Impossible de lister les volumes de stockage dans le pool de stockage %(pool)"
+"s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "Impossible de wiper les volumes de stockage %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de supprimer le volume de stockage %(name)s. Détails: %(err)s "
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de redimensionner le volume de stockage %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"Le type de stockage %(type)s ne supporte pas ni la création ni la "
+"suppression de volume"
+
+msgid "Storage volume name must be a string"
+msgstr "Le nom de volume de stockage doit être une chaîne de caractères"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "L'allocation de volume de stockage doit être une nombre entier"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "Le volume de stockage requiert un nom de volume"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Impossible de mettre à jour la base de données avec les informations du "
+"volume de stockage à cause de l'erreur: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr "Seulement un seul des paramêtre %(param)s peut être spécifié"
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr "La création de volume avec %(param)s n'est pas supportée"
+
+msgid "Storage volume capacity must be an integer number."
+msgstr "La capacité du volume de stockage doit être un nombre entier."
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+"L'URL du volume de stockage doit être http://, https://, ftp:// ou ftps://."
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr "Impossible d'accéder au fichier %(url)s. Veuillez le vérifier."
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "L'interface %(name)s n'existe pas"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Le réseau %(name)s existe déjà "
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "Le réseau %(name)s n'existe pas"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"Le sous-réseau %(subnet)s spécifié pour le réseau %(network)s n'est pas "
+"valide"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "Spécifier une interface réseau pour créer le réseau bridge %(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Impossible de supprimer le réseau actif %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+"L'interface %(iface)s spécifiée pour le réseau %(network)s est déjà utilisée"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "L'interface doit être un périphérique NIC vide, bonding ou bridgé."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Impossible de créer le réseau %(name)s. Détails: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Impossible de trouver une adresse IP libre pour le réseau '%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "L'interface %(iface)s existe déjà "
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Les types de réseaux supportés sont isolated, NAT et bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"Le sous-réseau doit être une chaine de caractères avec une adresse IP et un "
+"préfixe ou un masque de réseau"
+
+msgid "Network interface must be a string"
+msgstr "L'interface de réseau doit être une chaîne de caractères"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "L'ID de VLAN du réseau doit être un nombre entier entre 1 et 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Spécifiez un nom et un type pour créer un réseau"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"Impossible de supprimer le réseau %(name)s. Il y a des machines virtuelles %"
+"(vms)s et/ou des modèles liés à ce réseau. "
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"Impossible de désactiver réseau %(name)s. Il y a des machines virtuelles%"
+"(vms)s et/ou des modèles liés à ce réseau. "
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"Le périphérique bridge %(name)s ne peut être le périphérique tronc d'un VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "Ãchec durant l'activation de l'interface %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"Ãchec durant l'activation de l'interface %(iface)s. Veuillez vérifier le "
+"statut du lien physique."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Le rapport de déboggage %(name)s n'existe pas"
+
+msgid "Debug report tool not found in system"
+msgstr "L'outil de rapport de déboggage n'a pas été trouvé dans le système"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+"Impossible de créer le rapport de déboggage %(name)s. Détails: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+"Impossible de trouver un rapport de déboggage avec le nom fourni %(name)s"
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de générer le rapport de déboggage %(name)s. Détails: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr "Vous devriez donner un nom au fichier de rapport de déboggage."
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+"Le nom du rapport de déboggage doit être une chaîne de caractères. Seulement "
+"les lettres, chiffres, blanc souligné ('_') et tirets ('-') sont acceptés."
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"Le rapport de déboggage avec le nom spécifié \"%(name)s\" existe déjà . "
+"Veuillez en utiliser un autre."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Le server de stockage %(server)s n'était pas utilisé par Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "La distro '%(name)s' n'existe pas"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "La partition %(name)s n'existe pas sur cet hôte"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Impossible d'éteindre la machine hôte car des machines virtuelles en sont "
+"cours d'exécution"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"Impossible de redémarrer la machine hôte car des machines virtuelles en sont "
+"cours d'exécution"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "Périphérique de noeud '%(name)s' non trouvé"
+
+msgid "Conflicting flag filters specified."
+msgstr "Filtres incompatibles spécifiés."
+
+msgid "No packages marked for update"
+msgstr "Aucun paquet marqué pour mise à jour"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Le paquet %(name)s n'est pas marqué pour mise à jour"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Erreur durant la récupération des paquets marqués pour la miseà jour. "
+"Détails: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "Il n'y a pas de gestionnaire de paquets compatible avec ce système."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s invalide"
+
+msgid "Unable to choose a virtual machine name"
+msgstr "Impossible de sélectionner un nom de machine virtuelle"
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Type de stockage invalide. Les Types supportés sont: 'cdrom', 'disk'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr "Seulement le chemin d'un CDROM peut être modifié."
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+"Le périphérique de stockage %(dev_name)s n'existe pas dans la machine "
+"virtuelle %(vm_name)s"
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"Erreur durant la création du nouveau périphérique de stockage: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Erreur durant la mise à jour du périphérique de stockage: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Erreur durant le retrait du périphérique de stockage: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr "Ne pas supporter le branchement à chaud de périphérique IDE"
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Spécifier le type et le chemin ou le type et le pool/volume pour ajouter un "
+"nouveau disque de machine virtuelle."
+
+msgid "Specify path to update virtual machine disk"
+msgstr "Spécifier un chemin pour mettre à jour le disque de machine virtuelle"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+"La limitation de %(limit)s périphériques a été atteinte pour le contrôleur "
+"de type %(type)s "
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Seul un chemin ou pool/volume peut être spécifié pour ajouter un nouveau "
+"disque de machine virtuelle"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+"Le volume de format %(format)s sélectionné ne correspond pas au type de "
+"stockage %(type)s"
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+"L'ID du dépôt YUM doit être une chaîne de caractères ne comportant qu'un "
+"seul mot"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "L'URL du dépôt doit être une URL en http://, ftp:// ou file://."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"La configuration du dépôt est un dictionaire avec des valeurs spécifiques en "
+"accord avec le type de dépôt."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+"La distribution dans le nom de dépôt DEB doit être une chaîne de caractères"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "Les composants dans le dépôt DEB doivent être listés dans un tableau"
+
+msgid "Components to DEB repository must be a string"
+msgstr "Les composants dans le dépôt DEB doivent être une chaîne de caractères"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Le nom du dépôt YUM doit être une chaîne de caractères"
+
+msgid "GPG check must be a boolean value."
+msgstr "La vérification GPG doit être une valeur booléenne."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "La clé GPG doit être une URL pointant vers un fichier ASCII non armé."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Ne peut mettre à jour le dépôt %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Le dépôt %(repo_id)s n'existe pas."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "L'outil de gestion de dépôt n'a pas été reconnu pour votre système."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Le dépôt %(repo_id)s est déjà activé."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Le dépôt %(repo_id)s est déjà désactivé."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Ne peut supprimer le dépôt %(repo_id)s. "
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "Ne peut écrire le fichier de configuration du dépôt %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "Spécifier la distribution du dépôt afin de créer un dépôt DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Ne peut activer le dépôt %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Ne peut désactiver le dépôt %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "L'ID du dépôt YUM existe déjà "
+
+msgid "YUM Repository name must be a string"
+msgstr "Le nom du dépôt YUM doit être une chaîne de caractères"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Impossible de lister les dépôts. Détails: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "Impossible de récupérer les informations du dépôt. Détails: '%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Impossible d'ajouter un dépôt. Détails: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Impossible de supprimer un dépôt. Détails: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+"Ãléments de configurations: %(items)s ne sont pas supportés par le "
+"gestionnaire de dépôt"
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "ERROR CODE"
+
+msgid "REASON"
+msgstr "REASON"
+
+msgid "STACK"
+msgstr "STACK"
+
+msgid "Go to Homepage"
+msgstr "Aller à la page d'accueil"
+
+msgid "Create a New Virtual Machine"
+msgstr "Créer une nouvelle Machine Virtuelle"
+
+msgid "Virtual Machine Name"
+msgstr "Nom de Machine Virtuelle"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"Le nm est utilisé pour identifier une machine virtuelle. Si omis, un nom "
+"sera choisi en se basant sur le modèle utilisé."
+
+msgid "Template"
+msgstr "Modèle"
+
+msgid "Please create a template first."
+msgstr "Veuillez d'abord créer un modèle."
+
+msgid "Create a Template"
+msgstr "Créer un modèle"
+
+msgid "Please choose a template."
+msgstr "Veuillez choisir un modèle"
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "Version de l'OS"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Mémoire"
+
+msgid "Create"
+msgstr "Créer"
+
+msgid "Creating..."
+msgstr "Création en cours..."
+
+msgid "Cancel"
+msgstr "Annuler"
+
+msgid "Edit Guest"
+msgstr "Ãditer l'Invité"
+
+msgid "General"
+msgstr "Général"
+
+msgid "Storage"
+msgstr "Stockage"
+
+msgid "Interface"
+msgstr "Interface"
+
+msgid "Permission"
+msgstr "Permission"
+
+msgid "Host PCI Device"
+msgstr "Périphérique PCI Hôte"
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Nom"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "Mémoire (Mo)"
+
+msgid "Icon"
+msgstr "Icone"
+
+msgid "Device"
+msgstr "Périphérique"
+
+msgid "Path"
+msgstr "Chemin"
+
+msgid "Network"
+msgstr "Réseau"
+
+msgid "Type"
+msgstr "Type"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr "Utilisateurs et groupes systèmes disponibles"
+
+msgid "Selected system users and groups"
+msgstr "Utilisateurs et groupes systèmes sélectionnés"
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Tous"
+
+msgid "To Add"
+msgstr "Ã Ajouter"
+
+msgid "Added"
+msgstr "Ajouter"
+
+msgid "filter"
+msgstr "Filtre"
+
+msgid "Product"
+msgstr "Produit"
+
+msgid "Vendor"
+msgstr "Vendeur"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Enregistrer"
+
+msgid "Replace"
+msgstr "Remplacer"
+
+msgid "Detach"
+msgstr "Détacher"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "Démarrer"
+
+msgid "Reset"
+msgstr "Réinitialiser"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "Mettre hors tension"
+
+msgid "Actions"
+msgstr "Actions"
+
+msgid "Connect"
+msgstr "Connecter"
+
+msgid "Clone"
+msgstr "Cloner"
+
+msgid "Edit"
+msgstr "Ãditer"
+
+msgid "Shut Down"
+msgstr "Ãteindre"
+
+msgid "Delete"
+msgstr "Supprimer"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "E/S Disque"
+
+msgid "Network I/O"
+msgstr "E/S Réseau"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "Aucun invité trouvé."
+
+msgid "Add a Storage Device to VM"
+msgstr "Ajouter un Périphérique de Stockage à la VM"
+
+msgid "Device Type"
+msgstr "Type de Périphérique"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr ""
+"Le type de périphérique. Actuellement, \"cdrom\" et \"disk\" sont supportés."
+
+msgid "Storage Pool"
+msgstr "Pool de Stockage"
+
+msgid "Storage pool which volume located in"
+msgstr "Pool de Stockage dans lequel le volume est situé"
+
+msgid "Storage Volume"
+msgstr "Volume de Stockage"
+
+msgid "Storage volume to be attached"
+msgstr "Le volume de stockage à attacher"
+
+msgid "File Path"
+msgstr "Chemin de Fichier"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "Le chemin de fichier ISO sur le serveur comme CDROM."
+
+msgid "Attach"
+msgstr "Attacher"
+
+msgid "Shut down"
+msgstr "Ãteindre"
+
+msgid "Restart"
+msgstr "Redémarrer"
+
+msgid "Basic Information"
+msgstr "Informations de Base"
+
+msgid "OS Distro"
+msgstr "Distro de l'OS"
+
+msgid "OS Code Name"
+msgstr "Nom de code de l'OS"
+
+msgid "Processor"
+msgstr "Processeur"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "Statistiques Système"
+
+msgid "Software Updates"
+msgstr "Mises à jour Logiciel"
+
+msgid "Update Progress"
+msgstr "Progrès de la Mise à Jour"
+
+msgid "Repositories"
+msgstr "Dépôts"
+
+msgid "Debug Reports"
+msgstr "Rapports de Déboggage"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"Le nom d'utilisateur ou le mot de passe que vous avez entré est incorrect. "
+"Veuillez essayer à nouveau."
+
+msgid "This field is required."
+msgstr "Ce champ est requis."
+
+msgid "Log in"
+msgstr "Se connecter"
+
+msgid "Logging in..."
+msgstr "En cours de connexion..."
+
+msgid "Host"
+msgstr "Hôte"
+
+msgid "Guests"
+msgstr "Invités"
+
+msgid "Templates"
+msgstr "Modèles"
+
+msgid "Failed to get application configuration"
+msgstr "Ãchec lors de l'obtention de la configuration de l'application"
+
+msgid "This is not a valid Linux path"
+msgstr "Ce n'est pas un chemin Linux valide"
+
+msgid "This is not a valid URL."
+msgstr "Ce n'est pas une URL valide."
+
+msgid "No such data available."
+msgstr "De telles données ne sont pas disponibles."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"Ne peut contacter le système hôte. Vérifiez que le système hôte est allumé "
+"et que vous avez une connectivité réseau avec lui. Réponse de requête HTTP %"
+"1."
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Confirmation de Suppression"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Confirmer"
+
+msgid "Warning"
+msgstr "Avertissement"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Chargement en cours..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Essayer à nouveau"
+
+msgid "Detailed message:"
+msgstr "Message détaillé:"
+
+msgid "No ISO found"
+msgstr "Aucune ISO détectée"
+
+msgid "This is not a valid ISO file."
+msgstr "Ce n'est pas un fichier ISO valide."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Cela va prendre un long moment. Voulez-vous continuer ?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr ""
+"Cela va supprimer de manière permanent le modèle. Souhaites-vous continuer ?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"Impossible d'éteindre le système du fait que certaines machines virtuelles "
+"sont lancées !"
+
+msgid "Max:"
+msgstr "Max:"
+
+msgid "Utilization"
+msgstr "Utilisation"
+
+msgid "Available"
+msgstr "Disponible"
+
+msgid "Read Rate"
+msgstr "Taux en Lecture"
+
+msgid "Write Rate"
+msgstr "Taux en Ãcriture"
+
+msgid "Received"
+msgstr "Reçu"
+
+msgid "Sent"
+msgstr "Envoyé"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"Ãteindre ou redémarrer l'hôte causera la perte de tout travail non "
+"enregistré. Continuer à éteindre/redémarrer ?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Le dépôt sera retiré de façon permanente et ne pourra être rétabli. Voulez-"
+"vous continuer ?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL de base"
+
+msgid "Is Mirror"
+msgstr "Est un miroir"
+
+msgid "URL Args"
+msgstr "Arguments d'URL"
+
+msgid "Enabled"
+msgstr "Activé"
+
+msgid "GPG Check"
+msgstr "Vérification GPG"
+
+msgid "GPG Key"
+msgstr "Clé GPG"
+
+msgid "Add"
+msgstr "Ajouter"
+
+msgid "Remove"
+msgstr "Retirer"
+
+msgid "Enable"
+msgstr "Activer"
+
+msgid "Disable"
+msgstr "Désactiver"
+
+msgid "Package Name"
+msgstr "Nom de paquet"
+
+msgid "Version"
+msgstr "Version"
+
+msgid "Architecture"
+msgstr "Architecture"
+
+msgid "Repository"
+msgstr "Dépôt"
+
+msgid "Update All"
+msgstr "Tout mettre à jour"
+
+msgid "Updating..."
+msgstr "En cours de mise à jour..."
+
+msgid "Failed to retrieve packages update information."
+msgstr "Ãchec de récupération des informations de mise-à -jour des paquets."
+
+msgid "Failed to update package(s)."
+msgstr "Ãchec durant la mise à jour du/des paquet(s)"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Le rapport de déboggage sera enlevé de façon permanente et ne pourra être "
+"rétabli. Voulez-vous continuer ?"
+
+msgid "Generated Time"
+msgstr "Horodatage de génération"
+
+msgid "Generate"
+msgstr "Générer"
+
+msgid "Generating..."
+msgstr "En cours de génération..."
+
+msgid "Rename"
+msgstr "Renommer"
+
+msgid "Download"
+msgstr "Télécharger"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr ""
+"Le nom de rapport devrait contenir uniquement des lettres, nombres, "
+"soulignement ('_') et/ou tiret ('-')."
+
+msgid "Pending..."
+msgstr "En attente..."
+
+msgid "Report name is the same as the original one."
+msgstr "Le nom du rapport est le même que celui d'origine."
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"Cela va supprimer la machine virtuelle et tous ses disques virtuels. Cette "
+"opération est irréversible. Voulez-vous continuer ?"
+
+msgid "Power off Confirmation"
+msgstr "Confirmation de mise hors tension"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+"Cette action pourrait produire des résultats indésirables, par exemple un "
+"cache disque non flushé dans l'invité. Voulez-vous continuer ?"
+
+msgid "Reset Confirmation"
+msgstr "Confirmation de Réinitialisation"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+"Il y a un risque de perte de données causées par une réinitialisation sans "
+"extinction de l'OS invité. Voulez-vous continuer ?"
+
+msgid "Shut Down Confirmation"
+msgstr "Confirmation d'Extinction"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+"Noter que l'OS invité pourrait ignorer cette requête. Voulez-vous continuer ?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr "Confirmation de suppression de Machine Virtuelle"
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Ce CDROM sera détaché de façon permanente et vous pourrez le ré-attacher. "
+"Continuer le détachement ?"
+
+msgid "Attaching..."
+msgstr "En cours d'attachement..."
+
+msgid "Replacing..."
+msgstr "En cours de Remplacement..."
+
+msgid "Successfully attached!"
+msgstr "Attaché avec succès !"
+
+msgid "Successfully replaced!"
+msgstr "Remplacé avec succès !"
+
+msgid "Successfully detached!"
+msgstr "Détaché avec Succès !"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+"Ce disque sera définitivement détaché et peut être ré-attaché. Continuer à "
+"le détacher ?"
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "L'id du VLAN doit être entre 1 et 4094."
+
+msgid "unavailable"
+msgstr "non disponible"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"Cette action va interrompre la connectivité réseau pour tout machine "
+"virtuelle qui dépend de ce réseau."
+
+msgid "Create a network"
+msgstr "Créer un réseau"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Ce réseau n'est pas persistant. Au lieu de s'arrêter, cette actionva le "
+"suppromer de manière permanente. Voulez-vous continuer ?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+"Cela va effacer de manière permanente le pool de stockage. Voulez-vous "
+"continuer ?"
+
+msgid "This storage pool is empty."
+msgstr "Ce pool de stockage est vide."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Cela va formater votre disque et vous allez perdre toutes les données qui "
+"s'y trouvent, êtes-vous sûr de continuer ?"
+
+msgid "SCSI Fibre Channel"
+msgstr "Canal Fibre SCSI"
+
+msgid "No SCSI adapters found."
+msgstr "Aucun adaptateur SCSI trouvé."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "Le nom de pool de stockage ne peut être vierge."
+
+msgid "The storage pool path can not be blank."
+msgstr "Le chemin de pool de stockage ne peut être vierge."
+
+msgid "NFS server mount path can not be blank."
+msgstr "Le chemin de montage du serveur NFS ne peut être vierge."
+
+msgid "Invalid NFS mount path."
+msgstr "Chemin de montage NFS invalide."
+
+msgid "No logical device selected."
+msgstr "Aucun périphérique logique sélectionné."
+
+msgid "The iSCSI target can not be blank."
+msgstr "La cible iSCSI ne peut être vierge."
+
+msgid "Server name can not be blank."
+msgstr "Le nom de serveur ne peut être vierge."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "En cours de recherche de partitions disponibles..."
+
+msgid "No available partitions found."
+msgstr "Aucune partition disponible trouvée."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Le pool de stockage n'est pas persistent. Au lieu de le désactiver, cette "
+"action va le supprimer de manière permanente. Voulez-vous continuer ?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "Impossible de récupérer les informations des partitions."
+
+msgid "In progress..."
+msgstr "En cours..."
+
+msgid "Failed!"
+msgstr "Ãchec!"
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+"Le chemin de CDROM doit être un chemin local/distant valide et ne peut être "
+"virge."
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Le pool de disque ou le volume ne peut être vierge."
+
+#, fuzzy
+msgid "Filter"
+msgstr "Filtre"
+
+msgid "Network Name"
+msgstr "Nom de Réseau"
+
+msgid "State"
+msgstr "Ãtat"
+
+msgid "Network Type"
+msgstr "Type de Réseau"
+
+msgid "Address Space"
+msgstr "Espace d'adressage"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "Le nom ne devrait pas contenir '/' et '\"'."
+
+msgid "Isolated: no external network connection"
+msgstr "Isolé: pas de connexion à un réseau externe"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: connexion physique au réseau sortant uniquement"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Bridgé: Les macines virtuelles sont connectées directement au réseau physique"
+
+msgid "(No interfaces found)"
+msgstr "(Aucune interface trouvée)"
+
+msgid "Destination"
+msgstr "Destination"
+
+msgid "Enable VLAN"
+msgstr "Activer le VLAN"
+
+msgid "VLAN ID"
+msgstr "ID de VLAN"
+
+msgid "Stop"
+msgstr "Arrêter"
+
+msgid "Generate a New Debug Report"
+msgstr "Générer un Nouveau Rapport de Déboggage"
+
+msgid "Report Name"
+msgstr "Nom du Rapport"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"Le nom utilisé pour identifier le rapport. Si omis, un nom sera choisi basé "
+"sur l'heure courante. Le nom peut contenir des lettres, des nombres, le "
+"soulignement (\"_\") et le tiret (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "Renommer un Rapport de Déboggage"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"Le nom utilisé pour identifer le rapport. Le nom peut contenir des lettres, "
+"nombres et tirets (\"-\")."
+
+msgid "Submit"
+msgstr "Soumettre"
+
+msgid "Add a Repository"
+msgstr "Ajouter un Dépôt"
+
+msgid "Identifier"
+msgstr "Identificateur"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Mot unique, identifiant unique pour le dépôt."
+
+msgid "Textual name for the repository."
+msgstr "Nom textuel pour le dépôt."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Champ requis"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL du dépôt. Les protocoles supportés sont http, ftp et ficheir."
+
+msgid "Repository is a mirror"
+msgstr "Le dépôt est un miroir"
+
+msgid "Distribution"
+msgstr "Distribution"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribution du dépôt DEB."
+
+msgid "Components"
+msgstr "Composants"
+
+msgid "List of components in DEB repository."
+msgstr "Liste des composants dans le dépôt DEB."
+
+msgid "Edit Repository"
+msgstr "Editer le Dépôt"
+
+msgid "Mirror List URL"
+msgstr "URL de Liste de Miroir"
+
+msgid "Yes"
+msgstr "Oui"
+
+msgid "No"
+msgstr "Non"
+
+msgid "Capacity"
+msgstr "Capacité"
+
+msgid "Allocated"
+msgstr "Alloué"
+
+msgid "Location"
+msgstr "Emplacement"
+
+msgid "Device path"
+msgstr "Chemin du Périphérique"
+
+msgid "active"
+msgstr "actif"
+
+msgid "inactive"
+msgstr "inactif"
+
+msgid "Deactivate"
+msgstr "Désactiver"
+
+msgid "Activate"
+msgstr "Activer"
+
+msgid "Add Volume"
+msgstr "Ajouter un Volume"
+
+msgid "Extend"
+msgstr "Ãtendre"
+
+msgid "Undefine"
+msgstr "Supprimer"
+
+msgid "Format"
+msgstr "Format"
+
+msgid "Allocation"
+msgstr "Allocation"
+
+msgid "Define a New Storage Pool"
+msgstr "Définir un Nouveau Pool de Stockage"
+
+msgid "Storage Pool Name"
+msgstr "Nom de Pool de Stockage"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"Le nom utilisé pour identifier les pools de stockage, et il ne doit pas être "
+"vide."
+
+msgid "Storage Pool Type"
+msgstr "Type de Pool de Stockage"
+
+msgid "Storage Path"
+msgstr "Chemin de Stockage"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"Le chemin du Pool de Stockage. Chaque Pool de Stockage doit avoir un chemin "
+"unique."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"Kimchi va essayer de créer un répertoire quand il n'existe pas déjà dans "
+"votre système."
+
+msgid "NFS Server IP"
+msgstr "IP du Serveur NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP du Serveur NFS ou nom d'hôte. Il peut être saisi ou entré à partir de "
+"l'historique."
+
+msgid "NFS Path"
+msgstr "Chemin NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "Le chemin NFS exporté sur le serveur NFS."
+
+msgid "iSCSI Server"
+msgstr "Serveur iSCSI"
+
+msgid "Server"
+msgstr "Serveur"
+
+msgid "Port"
+msgstr "Port"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP du Serveur iSCSI ou nom d'hôte. Il ne devrait pas être vide."
+
+msgid "Target"
+msgstr "Cible"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "La cible iSCSI sur le serveur iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "Ajouter l'Authentification iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Authentification iSCSI"
+
+msgid "User Name"
+msgstr "Nom d'Utilisateur"
+
+msgid "Password"
+msgstr "Mot de Passe"
+
+msgid "SCSI Adapter"
+msgstr "Adaptateur SCSI"
+
+msgid "Please, wait..."
+msgstr "Veuillez patienter..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr "iAjouter un Volume au Pool de Stockage"
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr "Saisir une URL distante ici"
+
+msgid "Upload a file"
+msgstr "Charger un fichier"
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "Ajouter un Modèle"
+
+msgid "Where is the source media for this template? "
+msgstr "Où se trouve le media source pour le modèle ?"
+
+msgid "Local ISO Image"
+msgstr "Image ISO Locale"
+
+msgid "Local Image File"
+msgstr "Fichier Image Local"
+
+msgid "Remote ISO Image"
+msgstr "Image ISO Distante"
+
+msgid "Search ISOs"
+msgstr "Rechercher des ISOs"
+
+msgid "The following ISOs are available:"
+msgstr "Les ISOs suivants sont disponibles:"
+
+msgid "OS: "
+msgstr "OS: "
+
+msgid "Version: "
+msgstr "Version: "
+
+msgid "Size: "
+msgstr "Taille: "
+
+msgid "Search more ISOs"
+msgstr "Chercher plus d'ISOs"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Créer des modèles depuis l'ISO sélectionné"
+
+msgid "I want to use a specific ISO file"
+msgstr "Je veux utiliser un fichier ISO spécifique"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Chargement des ISOs distants par défaut en cours..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Je veux utiliser une URL personnalisée"
+
+msgid "Edit Template"
+msgstr "Ãditer un Modèle"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr "Fichier Image"
+
+msgid "Graphics"
+msgstr "Graphiques"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "Nombre de CPU"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "Aucun modèle trouvé."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "La suppression n'est pas autorisée pour %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s n'implémente pas de méthode de mise à jour"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "La création n'est pas autorisée pour %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "Impossible de parser la requête JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Cette API supporte uniquement le JSON"
+
+#~ msgid "Parameters does not match requirement in schema: %(err)s"
+#~ msgstr ""
+#~ "Les paramètres ne correspondent pas à ce qui est requis dans le schéma: %"
+#~ "(err)s"
+
+#~ msgid "You don't have permission to perform this operation."
+#~ msgstr "Vous n'avez pas la permission d'effectuer cette opération."
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Le magasin de données n'est pas initié dans l'objet modèle."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "Impossible de démarrer la tâche à cause de l'erreur: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr ""
+#~ "L'authentification a échoué pour l'utilisateur '%(username)s'. [Code "
+#~ "d'Erreur: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Vous n'êtes pas autorisé à accéder à Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Spécifiez %(item)s pour vous logguer dans Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "Impossible de trouver %(item)s dans le magasin de données"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr ""
+#~ "Timeout durant l'exécution de la commande '%(cmd)s' après %(seconds)s "
+#~ "secondes"
+
+#~ msgid "Help"
+#~ msgstr "Aide"
+
+#~ msgid "About"
+#~ msgstr "A propos..."
+
+#~ msgid "Log out"
+#~ msgstr "Se déconnecter"
+
+#~ msgid "Version:"
+#~ msgstr "Version:"
+
+#~ msgid "Session timeout, please re-login."
+#~ msgstr "Session expirée, veuillez vous reconnecter."
diff --git a/src/wok/plugins/kimchi/po/gen-pot.in b/src/wok/plugins/kimchi/po/gen-pot.in
new file mode 100644
index 0000000..0e3cd10
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/gen-pot.in
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+for src in $@; do
+ if [ ${src: -3} == ".py" ]; then
+ cat $src
+ else
+ cat $src | @CHEETAH@ compile -
+ fi
+done | xgettext --no-location -o kimchi.pot -L Python -
diff --git a/src/wok/plugins/kimchi/po/it_IT.po b/src/wok/plugins/kimchi/po/it_IT.po
new file mode 100644
index 0000000..257c306
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/it_IT.po
@@ -0,0 +1,2274 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: it_IT\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+"Errore durante il richiamo dei dispositivi del blocco. Dettagli: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"Errore durante il richiamo delle informazioni sul dispositivo del blocco per "
+"%(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Impossibile trovare il file distro: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"Impossibile analizzare il file distro: %(filename)s. Verificare che sia un "
+"file JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"Impossibile accedere a %(portal)s di destinazione host iSCSI. Dettagli: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Impossibile accedere alla destinazione %(target)s host %(host)s iSCSI"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "Il file ISO %(filename)s non è avviabile"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "Il file ISO %(filename)s non ha un record di avvio El Torito valido"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Voce di convalida El Torito non valida in ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicatore di avvio El Torito non valido in ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "Tipo di volume imprevisto per il volume primario in ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Formato non corretto durante la lettura del descrittore volume in ISO %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"L'hypervisor non dispone dell'autorizzazione per utilizzare questo ISO %"
+"(filename)s. Spostarlo in /var/lib/libvirt o impostare l'autorizzazione di "
+"ricerca per gli elenchi di controllo accesso ai file per l'utente '%(user)"
+"s', se possibile, o aggiungere '%(user)s' al gruppo percorso ISO o (non "
+"consigliato) 'chmod -R o+x 'path_to_iso'. Dettagli: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "Macchina virtuale %(name)s già esistente"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "La macchina virtuale %(name)s non esiste"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Impossibile richiamare l'immagine per la macchina virtuale arrestata %(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "L'immagine ISO remota non è supportata da questo server."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossibile richiamare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"L'indirizzo dei grafici su cui rimanere in ascolto deve essere IPv4 o IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Specificare un modello da cui creare una macchina virtuale"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile eliminare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossibile ridenominare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "Il nome della rete deve essere una stringa"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "Il nome della rete deve essere una stringa"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "L'utente '%(users)s' non esiste."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "L'utente '%(groups)s' non esiste."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "L'interfaccia %(iface)s non esiste nella macchina virtuale %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"La rete %(network)s specificata per la macchina virtuale %(name)s non esiste"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+"Il tipo supportato per le interfacce della macchina virtuale è solo rete"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"Il nome di rete per l'interfaccia della macchina virtuale deve essere una "
+"stringa"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Scheda modello di rete non valida per l'interfaccia della macchina virtuale"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Specificare il tipo e la rete per aggiungere una nuova interfaccia della "
+"macchina virtuale"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Modello %(name)s già esistente"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr ""
+"La rete '%(network)s' specificata per il modello %(template)s non esiste"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Il pool di memoria %(pool)s specificato per il modello %(template)s non "
+"esiste"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+"Il pool di memoria %(pool)s specificato per il modello %(template)s non è "
+"attivo"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Parametro non valido %(param)s' specificato per CDROM."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"La rete %(network)s specificata per il modello %(template)s non è attiva"
+
+msgid "Template name must be a string"
+msgstr "Il nome del modello deve essere una stringa"
+
+msgid "Template icon must be a path to the image"
+msgstr "L'icona del modello deve essere un percorso all'immagine"
+
+msgid "Template distribution must be a string"
+msgstr "La distribuzione del modello deve essere una stringa"
+
+msgid "Template distribution version must be a string"
+msgstr "La versione della distribuzione del modello deve essere una stringa"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "Il numero di CPU deve essere un numero intero"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr ""
+"La quantità di memoria (MB) deve essere un numero intero maggiore di 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "URI pool di memoria non valido: %(value)s specificato per il modello"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "Specificare un'immagine ISO come CDROM per creare un modello"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Tutte le reti per il modello devono essere specificate in un elenco."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "Impossibile creare il modello a causa dell'errore: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "Impossibile eliminare il modello a causa dell'errore: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Pool di memoria %(name)s già esistente"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Il pool di memoria %(name)s non esiste"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Specificare %(item)s per poter creare il pool di memoria %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Impossibile eliminare il pool di memoria attivo %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Impossibile elencare i pool di memoria. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile creare il pool di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Impossibile ottenere il numero di volumi di memoria nel pool di memoria %"
+"(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile attivare il pool di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile disattivare il pool di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile eliminare il pool di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"Impossibile creare il pool NFS poiché il percorso di esportazione %(path)s "
+"potrebbe bloccarsi durante il montaggio"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"Impossibile creare il pool NFS poiché il montaggio del percorso di "
+"esportazione %(path)s ha avuto esito negativo"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Tipo di pool di memoria non supportato: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "Il percorso del pool di memoria deve essere una stringa"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "L'host del pool di memoria deve essere un nome host o IP"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Il parametro dispositivi pool di memoria deve essere un elenco"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "L'IQN di destinazione di un pool iSCSI deve essere una stringa"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"La porta di un server di memoria remoto deve essere un numero intero tra 1 e "
+"65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Specificare nome e tipo per creare un pool di memoria"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s non è un disco/partizione valido. Impossibile aggiungerlo al pool %"
+"(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Solo il parametro dischi può essere aggiornato per il pool di memoria logico."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "Il nome adattatore host SCSI deve essere una stringa."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "Il pool di memoria kimchi_isos è riservato per uso interno"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossibile attivare il pool di memoria NFS %(name)s. Il server NFS %(server)"
+"s è irraggiungibile."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossibile disattivare il pool di memoria NFS %(name)s. Il server NFS %"
+"(server)s è irraggiungibile."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossibile disattivare il pool %(name)s poiché è associato ad alcuni modelli"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossibile eliminare il pool %(name)s poiché è associato ad alcuni modelli"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"Un gruppo di volumi denominato '%(name)s' esiste già . Scegliere un altro "
+"nome per creare il pool logico."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"Impossibile aggiornare il database con informazioni approfondite sulla "
+"scansione a causa dell'errore: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Volume di memoria %(name)s già esistente"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "Il volume di memoria %(name)s non esiste nel pool di memoria %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Specificare %(item)s per poter creare il volume di memoria %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"Impossibile elencare i volumi di memoria poiché il pool di memoria %(pool)s "
+"non è attivo"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"Impossibile creare il volume di memoria %(name)s nel pool di memoria %(pool)"
+"s. Dettagli: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Impossibile elencare i volumi di memoria nel pool di memoria %(pool)s. "
+"Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "Impossibile ripulire i volumi di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "Impossibile eliminare il volume di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Impossibile ridimensionare il volume di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"Il tipo di memoria %(type)s non supporta la creazione ed eliminazione del "
+"volume"
+
+msgid "Storage volume name must be a string"
+msgstr "Il nome del volume di memoria deve essere una stringa"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "L'assegnazione del volume di memoria deve essere un numero intero"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "Il volume di memoria richiede un nome volume"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Impossibile aggiornare il database con informazioni sul volume di memoria a "
+"causa dell'errore: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "L'interfaccia %(name)s non esiste"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Rete %(name)s già esistente"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "La rete %(name)s non esiste"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"La sottorete %(subnet)s specificata per la rete %(network)s non è valida ."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"Specificare un'interfaccia di rete per creare la rete con bridge %(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Impossibile eliminare la rete attiva %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+"L'interfaccia %(iface)s specificata per la rete %(network)s è già in uso"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+"L'interfaccia deve essere un dispositivo bridge o di collegamento NIC bare-"
+"metal."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Impossibile creare la rete %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Impossibile trovare un indirizzo IP libero per la rete '%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "L'interfaccia %(iface)s già esistente."
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "I tipi di rete supportati sono isolata, NAT e bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"La sottorete della rete deve essere una stringa con indirizzo IP e prefisso "
+"o maschera di rete"
+
+msgid "Network interface must be a string"
+msgstr "L'interfaccia di rete deve essere una stringa"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "L'ID VLAN di rete deve essere un numero intero tra 1 e 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Specificare nome e tipo per creare una rete"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"Impossibile eliminare la rete %(name)s. Ci sono alcune macchine virtuali %"
+"(vms)s e/o modelli collegati a tale rete."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"Impossibile disattivare la rete %(name)s. Ci sono alcune macchine virtualie %"
+"(vms)s e/o modelli collegati a tale rete."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"Il dispositivo bridge %(name)s non può essere il dispositivo trunk di una "
+"VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "Impossibile attivare l'interfaccia %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"Impossibile attivare l'interfaccia %(iface)s. Controllare lo stato del link "
+"fisico."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Il report di debug %(name)s non esiste"
+
+msgid "Debug report tool not found in system"
+msgstr "Strumento report di debug non trovato nel sistema"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "Impossibile creare il report di debug %(name)s. Dettagli: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "Impossibile generare il report di debug %(name)s. Dettagli: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"Un gruppo di volumi denominato '%(name)s' esiste già . Scegliere un altro "
+"nome per creare il pool logico."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Il server di memoria %(server)s non è stato utilizzato da Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' non esistente"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "La partizione %(name)s non esiste nell'host"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Impossibile arrestare la macchina host poiché sono presenti macchine "
+"virtuali in esecuzione"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"Impossibile riavviare la macchina host poiché sono presenti macchine "
+"virtuali in esecuzione"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "Dispositivo nodo '%(name)s' non trovato"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "Nessun pacchetto contrassegnato per l'aggiornamento"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Il pacchetto %(name)s non è contrassegnato per l'aggiornamento."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Errore durante il richiamo dei pacchetti contrassegnati per l'aggiornamento. "
+"Dettagli: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "Non è presente un gestore pacchetti compatibile per questo sistema."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s non valido"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Tipo di memoria non valido. I tipi supportati sono: 'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"Errore durante la creazione del nuovo dispositivo di memoria: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Errore durante l'aggiornamento del dispositivo di memoria: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Errore durante la rimozione del dispositivo di memoria: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
+"virtuale"
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+"Specificare il percorso per aggiornare il disco della macchina virtuale"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
+"virtuale"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "L'ID repository YUM deve essere una stringa di una sola parola."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "L'URL del repository deve essere http://, ftp:// o file:// URL."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"La configurazione del repository è un dizionario con valori specifici in "
+"base al tipo di repository."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "La distribuzione al repository DEB deve essere una stringa"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "I componenti per il repository DEB devono essere elencati in un array"
+
+msgid "Components to DEB repository must be a string"
+msgstr "I componenti per il repository DEB devono essere una stringa"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Il nome del repository YUM deve essere una stringa."
+
+msgid "GPG check must be a boolean value."
+msgstr "Il controllo GPG deve essere un valore booleano."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "La chiave GPG deve essere un URL che punta al file blindato ASCII."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Impossibile aggiornare il repository %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Il repository %(repo_id)s non esiste."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+"Lo strumento di gestione del repository non è stato riconosciuto per il "
+"sistema."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Il repository %(repo_id)s è già abilitato."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Il repository %(repo_id)s è già disabilitato."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Impossibile rimuovere il repository %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"Impossibile scrivere il file di configurazione del repository %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Specificare la distribuzione del repository per poter creare un repository "
+"DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Impossibile abilitare il repository %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Impossibile disabilitare il repository %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "ID repository YUM già esistente"
+
+msgid "YUM Repository name must be a string"
+msgstr "Il nome del repository YUM deve essere una stringa"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Impossibile elencare i repository. Dettagli: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+"Impossibile richiamare le informazioni sul repository. Dettagli: '%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Impossibile aggiungere il repository. Dettagli: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Impossibile rimuovere il repository. Dettagli: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "CODICE DI ERRORE"
+
+msgid "REASON"
+msgstr "CAUSA"
+
+msgid "STACK"
+msgstr "STACK"
+
+msgid "Go to Homepage"
+msgstr "Vai alla home page"
+
+msgid "Create a New Virtual Machine"
+msgstr "Crea una nuova macchina virtuale"
+
+msgid "Virtual Machine Name"
+msgstr "Nome macchina virtuale"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"Il nome utilizzato per identificare la macchina virtuale. Se il nome viene "
+"omesso ne verrà scelto uno in base al modello utilizzato."
+
+msgid "Template"
+msgstr "Modello"
+
+msgid "Please create a template first."
+msgstr "Creare prima un modello."
+
+msgid "Create a Template"
+msgstr "Crea un modello"
+
+msgid "Please choose a template."
+msgstr "Scegliere un modello."
+
+msgid "OS"
+msgstr "SO"
+
+msgid "OS Version"
+msgstr "Versione SO"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Memoria"
+
+msgid "Create"
+msgstr "Crea"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "Annulla"
+
+msgid "Edit Guest"
+msgstr "Modifica guest"
+
+msgid "General"
+msgstr "Generale"
+
+msgid "Storage"
+msgstr "Memoria"
+
+msgid "Interface"
+msgstr "Interfaccia"
+
+msgid "Permission"
+msgstr "Versione"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Nome"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "Memoria"
+
+msgid "Icon"
+msgstr "Icona"
+
+msgid "Device"
+msgstr "Nome dispositivo"
+
+msgid "Path"
+msgstr "Percorso NFS"
+
+msgid "Network"
+msgstr "Rete"
+
+msgid "Type"
+msgstr "Tipo"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Tutti"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "Fornitore"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Salva"
+
+msgid "Replace"
+msgstr "Sostituisci"
+
+msgid "Detach"
+msgstr "Scollega"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "Avvia"
+
+msgid "Reset"
+msgstr "Reimposta"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "Azioni"
+
+msgid "Connect"
+msgstr "Connetti"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "Modifica"
+
+msgid "Shut Down"
+msgstr "Arresta"
+
+msgid "Delete"
+msgstr "Elimina"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "I/O disco"
+
+msgid "Network I/O"
+msgstr "I/O di rete"
+
+msgid "Livetile"
+msgstr "Riquadro animato"
+
+msgid "No guests found."
+msgstr "Nessuna macchina guest trovata."
+
+msgid "Add a Storage Device to VM"
+msgstr "Aggiungi un dispositivo di memoria alla VM"
+
+msgid "Device Type"
+msgstr "Tipo dispositivo"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "Il tipo di dispositivo. Attualmente, è supportato solo \"cdrom\"."
+
+msgid "Storage Pool"
+msgstr "Pool di memoria"
+
+msgid "Storage pool which volume located in"
+msgstr "Il percorso del pool di memoria deve essere una stringa"
+
+msgid "Storage Volume"
+msgstr "Nome pool di memoria"
+
+msgid "Storage volume to be attached"
+msgstr "Il nome del volume di memoria deve essere una stringa"
+
+msgid "File Path"
+msgstr "Percorso file"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "Il percorso file ISO nel server per CDROM."
+
+msgid "Attach"
+msgstr "Allega"
+
+msgid "Shut down"
+msgstr "Arresta"
+
+msgid "Restart"
+msgstr "Riavvia"
+
+msgid "Basic Information"
+msgstr "Informazioni di base"
+
+msgid "OS Distro"
+msgstr "Distro SO"
+
+msgid "OS Code Name"
+msgstr "Nome codice SO"
+
+msgid "Processor"
+msgstr "Processore"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "Statistiche di sistema"
+
+msgid "Software Updates"
+msgstr "Aggiornamenti del software"
+
+msgid "Update Progress"
+msgstr "Avanzamento aggiornamento"
+
+msgid "Repositories"
+msgstr "Repository"
+
+msgid "Debug Reports"
+msgstr "Report di debug"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"Il nome utente o la password immessi non sono corretti. Ripetere "
+"l'operazione."
+
+msgid "This field is required."
+msgstr "Questo campo è obbligatorio."
+
+msgid "Log in"
+msgstr "Accedi"
+
+msgid "Logging in..."
+msgstr "Accesso in corso..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "Guest"
+
+msgid "Templates"
+msgstr "Modelli"
+
+msgid "Failed to get application configuration"
+msgstr "Richiamo della configurazione dell'applicazione non riuscito"
+
+msgid "This is not a valid Linux path"
+msgstr "Non è un percorso Linux valido"
+
+msgid "This is not a valid URL."
+msgstr "Non è un URL valido."
+
+msgid "No such data available."
+msgstr "Dati indicati non disponibili."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"Impossibile contattare il sistema host. Verificare che il sistema host sia "
+"attivo e che si disponga della connettività di rete per tale sistema. "
+"Risposta alla richiesta HTTP %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Conferma"
+
+msgid "Warning"
+msgstr "Avvertenza"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Caricamento in corso..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Riprova"
+
+msgid "Detailed message:"
+msgstr "Messaggio dettagliato:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "Non è un file ISO valido."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Richiederà molto tempo. Continuare?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "L'azione eliminerà permanentemente il modello. Continuare?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"Impossibile arrestare il sistema poiché sono in esecuzione alcune macchine "
+"virtuali."
+
+msgid "Max:"
+msgstr "Massimo:"
+
+msgid "Utilization"
+msgstr "Utilizzo"
+
+msgid "Available"
+msgstr "Disponibile"
+
+msgid "Read Rate"
+msgstr "Velocità di lettura"
+
+msgid "Write Rate"
+msgstr "Velocità di scrittura"
+
+msgid "Received"
+msgstr "Ricevuti"
+
+msgid "Sent"
+msgstr "Inviati"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"L'arresto o il riavvio dell'host provocherà la perdita del lavoro non "
+"salvato. Continuare con l'arresto o il riavvio?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Il repository verrà rimosso permanentemente e non potrà essere ripristinato. "
+"Si desidera continuare?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL di base"
+
+msgid "Is Mirror"
+msgstr "Ã speculare"
+
+msgid "URL Args"
+msgstr "Argomenti URL"
+
+msgid "Enabled"
+msgstr "Abilitato"
+
+msgid "GPG Check"
+msgstr "Controllo GPG"
+
+msgid "GPG Key"
+msgstr "Chiave GPG"
+
+msgid "Add"
+msgstr "Aggiungi"
+
+msgid "Remove"
+msgstr "Rimuovi"
+
+msgid "Enable"
+msgstr "Abilita"
+
+msgid "Disable"
+msgstr "Disabilita"
+
+msgid "Package Name"
+msgstr "Nome pacchetto"
+
+msgid "Version"
+msgstr "Versione"
+
+msgid "Architecture"
+msgstr "Architettura"
+
+msgid "Repository"
+msgstr "Repository"
+
+msgid "Update All"
+msgstr "Aggiorna tutto"
+
+msgid "Updating..."
+msgstr "Aggiornamento in corso..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "Aggiornamento dei pacchetti non riuscito."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Il report del debug verrà rimosso permanentemente e non potrà essere "
+"ripristinato. Si desidera continuare?"
+
+msgid "Generated Time"
+msgstr "Ora di creazione"
+
+msgid "Generate"
+msgstr "Crea"
+
+msgid "Generating..."
+msgstr "Creazione in corso..."
+
+msgid "Rename"
+msgstr "Ridenomina"
+
+msgid "Download"
+msgstr "Scarica"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr ""
+"Il nome del report può contenere solo lettere, cifre e/o trattini ('-')."
+
+msgid "Pending..."
+msgstr "Caricamento in corso..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"L'operazione eliminerà la macchina virtuale e i relativi dischi virtuali e "
+"non è reversibile. Continuare?"
+
+msgid "Power off Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "L'azione eliminerà permanentemente il modello. Continuare?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Il CDROM verrà scollegato permanentemente e non sarà possibile ricollegarlo. "
+"Continuare con lo scollegamento?"
+
+msgid "Attaching..."
+msgstr "Collegamento in corso..."
+
+msgid "Replacing..."
+msgstr "Sostituzione in corso..."
+
+msgid "Successfully attached!"
+msgstr "Collegamento riuscito."
+
+msgid "Successfully replaced!"
+msgstr "Sostituzione riuscita."
+
+msgid "Successfully detached!"
+msgstr "Scollegamento riuscito."
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "L'ID VLAN deve essere compreso tra 1 e 4094."
+
+msgid "unavailable"
+msgstr "non disponibile"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"L'azione interromperà la connettività di rete per qualsiasi macchina "
+"virtuale che dipende da questa rete."
+
+msgid "Create a network"
+msgstr "Crea una rete"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Il pool di memoria non è permanente. Invece di disattivarlo, l'azione lo "
+"eliminerà permanentemente. Continuare?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "L'azione eliminerà permanentemente il pool di memoria. Continuare?"
+
+msgid "This storage pool is empty."
+msgstr "Il pool di memoria è vuoto."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Il disco verrà formattato e tutti i dati su di esso andranno persi, sicuri "
+"di voler continuare? "
+
+msgid "SCSI Fibre Channel"
+msgstr "Canale a fibre ottiche SCSI"
+
+msgid "No SCSI adapters found."
+msgstr "Nessun adattatore SCSI trovato."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "Il campo per il nome del pool di memoria non può essere vuoto."
+
+msgid "The storage pool path can not be blank."
+msgstr "Il campo per il percorso del pool di memoria non può essere vuoto."
+
+msgid "NFS server mount path can not be blank."
+msgstr ""
+"Il campo per il percorso di montaggio del server NFS non può essere vuoto."
+
+msgid "Invalid NFS mount path."
+msgstr "Percorso di montaggio NFS non valido."
+
+msgid "No logical device selected."
+msgstr "Nessun dispositivo logico selezionato."
+
+msgid "The iSCSI target can not be blank."
+msgstr "Il campo per la destinazione iSCSI non può essere vuoto."
+
+msgid "Server name can not be blank."
+msgstr "Il campo per il nome del server non può essere vuoto."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "Ricerca di partizioni disponibili in corso..."
+
+msgid "No available partitions found."
+msgstr "Nessuna partizione disponibile trovata."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Il pool di memoria non è permanente. Invece di disattivarlo, l'azione lo "
+"eliminerà permanentemente. Continuare?"
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+"Impossibile richiamare le informazioni sul repository. Dettagli: '%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Il campo per il nome del pool di memoria non può essere vuoto."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "Nome rete"
+
+msgid "State"
+msgstr "Stato"
+
+msgid "Network Type"
+msgstr "Tipo di Rete"
+
+msgid "Address Space"
+msgstr "Spazio indirizzo"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "Nome pool di memoria non valido. Non deve contenere '/'."
+
+msgid "Isolated: no external network connection"
+msgstr "Isolata: nessuna connessione di rete fisica"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: solo connessione di rete fisica in uscita"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Con bridge: le macchine virtuali sono connesse direttamente alla rete fisica"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "Destinazione:"
+
+msgid "Enable VLAN"
+msgstr "Abilita VLAN:"
+
+msgid "VLAN ID"
+msgstr "ID VLAN:"
+
+msgid "Stop"
+msgstr "Arresta"
+
+msgid "Generate a New Debug Report"
+msgstr "Crea un nuovo report di debug"
+
+msgid "Report Name"
+msgstr "Nome report"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
+"viene scelto uno in base all'ora corrente. Il nome può contenere lettere, "
+"cifre e trattini (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "Crea un nuovo report di debug"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
+"viene scelto uno in base all'ora corrente. Il nome può contenere lettere, "
+"cifre e trattini (\"-\")."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "Aggiungi un repository"
+
+msgid "Identifier"
+msgstr "Identificativo"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Identificativo univoco di una sola parola per il repository."
+
+msgid "Textual name for the repository."
+msgstr "Nome in formato testo per il repository."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Campo obbligatorio"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL al repository. I protocolli supportati sono http, ftp e file."
+
+msgid "Repository is a mirror"
+msgstr "Il repository è un elemento speculare."
+
+msgid "Distribution"
+msgstr "Distribuzione"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribuzione del repository DEB."
+
+msgid "Components"
+msgstr "Componenti"
+
+msgid "List of components in DEB repository."
+msgstr "Elenco di componenti nel repository DEB."
+
+msgid "Edit Repository"
+msgstr "Modifica repository"
+
+msgid "Mirror List URL"
+msgstr "URL elenco elementi speculari"
+
+msgid "Yes"
+msgstr "Sì"
+
+msgid "No"
+msgstr "No"
+
+msgid "Capacity"
+msgstr "Capacità "
+
+msgid "Allocated"
+msgstr "Assegnato"
+
+msgid "Location"
+msgstr "Ubicazione"
+
+msgid "Device path"
+msgstr "Percorso dispositivo"
+
+msgid "active"
+msgstr "attivo"
+
+msgid "inactive"
+msgstr "non attivo"
+
+msgid "Deactivate"
+msgstr "Disattiva"
+
+msgid "Activate"
+msgstr "Attiva"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "Rimuovi definizione"
+
+msgid "Format"
+msgstr "Formato:"
+
+msgid "Allocation"
+msgstr "Allocazione:"
+
+msgid "Define a New Storage Pool"
+msgstr "Definisci un nuovo pool di memoria"
+
+msgid "Storage Pool Name"
+msgstr "Nome pool di memoria"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"Il nome utilizzato per identificare i pool di memoria; il campo non deve "
+"essere vuoto."
+
+msgid "Storage Pool Type"
+msgstr "Tipo di pool di memoria"
+
+msgid "Storage Path"
+msgstr "Percorso di memoria"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"Il percorso del pool di memoria. Ogni pool di memoria deve avere un percorso "
+"univoco."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"Kimchi tenterà di creare la directory nel caso non esista ancora sul sistema."
+
+msgid "NFS Server IP"
+msgstr "IP server NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"Il nome host o l'indirizzo IP del server NFS. Ã possibile immetterlo o "
+"sceglierlo dalla cronologia."
+
+msgid "NFS Path"
+msgstr "Percorso NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "Il percorso esportato NFS sul server NFS."
+
+msgid "iSCSI Server"
+msgstr "Server iSCSI"
+
+msgid "Server"
+msgstr "Server"
+
+msgid "Port"
+msgstr "Porta"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr ""
+"Il nome host o l'indirizzo IP del server iSCSI. Il campo non deve essere "
+"vuoto."
+
+msgid "Target"
+msgstr "Destinazione"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "La destinazione iSCSI sul server iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "Aggiungi autenticazione iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Autenticazione iSCSI"
+
+msgid "User Name"
+msgstr "Nome utente"
+
+msgid "Password"
+msgstr "Password"
+
+msgid "SCSI Adapter"
+msgstr "Adattatore SCSI"
+
+msgid "Please, wait..."
+msgstr "Attendere..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "Aggiungi modello"
+
+msgid "Where is the source media for this template? "
+msgstr "Dov'è il supporto di origine per questo modello?"
+
+msgid "Local ISO Image"
+msgstr "Immagine ISO locale"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "Immagine ISO remota"
+
+msgid "Search ISOs"
+msgstr "Ricerca ISO"
+
+msgid "The following ISOs are available:"
+msgstr "Sono disponibili i seguenti file ISO:"
+
+msgid "OS: "
+msgstr "SO: "
+
+msgid "Version: "
+msgstr "Versione: "
+
+msgid "Size: "
+msgstr "Dimensione: "
+
+msgid "Search more ISOs"
+msgstr "Ricerca più ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Crea modelli da ISO selezionato"
+
+msgid "I want to use a specific ISO file"
+msgstr "Utilizzare un file ISO specifico"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Caricamento di ISO remoti predefiniti in corso..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Utilizzare un URL personalizzato"
+
+msgid "Edit Template"
+msgstr "Modifica modello"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "Grafici"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "Numero CPU"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "Nessun modello trovato."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "Eliminazione non consentita per %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s non implementa il metodo di aggiornamento"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Creazione non consentita per %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "Impossibile analizzare la richiesta JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "L'API supporta solo JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Archivio dati non inizializzato nell'oggetto modello."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "Impossibile avviare l'attività a causa dell'errore: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr ""
+#~ "Autenticazione non riuscita per l'utente '%(username)s'. [Codice di "
+#~ "errore: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Non si dispone dell'autorizzazione ad accedere a Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Specificare %(item)s per accedere a Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "Impossibile trovare %(item)s nell'archivio dati"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr ""
+#~ "Ã stato raggiunto il timeout durante l'esecuzione del comando '%(cmd)s' "
+#~ "dopo %(seconds)s secondi"
+
+#~ msgid "Help"
+#~ msgstr "Guida"
+
+#~ msgid "About"
+#~ msgstr "Info su"
+
+#~ msgid "Log out"
+#~ msgstr "Disconnetti"
+
+#~ msgid "Version:"
+#~ msgstr "Versione:"
diff --git a/src/wok/plugins/kimchi/po/ja_JP.po b/src/wok/plugins/kimchi/po/ja_JP.po
new file mode 100644
index 0000000..a3d3be3
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/ja_JP.po
@@ -0,0 +1,2269 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ja_JP\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+"ãããã¯ã»ããã¤ã¹ãåå¾ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"%(device)s ã®ãããã¯ã»ããã¤ã¹æ
å ±ãåå¾ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ããã"
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã»ãã¡ã¤ã« %(filename)s ãè¦ã¤ããã¾ãã"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã»ãã¡ã¤ã« %(filename)s ãè§£æã§ãã¾ãããJSON ãã¡ã¤ã«"
+"ã§ãããã¨ã確èªãã¦ãã ããã"
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"iSCSI ãã¹ãã»ã¿ã¼ã²ãã %(portal)s ã«ãã°ã¤ã³ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "iSCSI ãã¹ã %(host)s ã¿ã¼ã²ãã %(target)s ã«ãã°ã¤ã³ã§ãã¾ãã"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISO ãã¡ã¤ã« %(filename)s ã¯ããã¼ãå¯è½ã§ã¯ããã¾ãã"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"ISO ãã¡ã¤ã« %(filename)s ã«ã¯ãæå¹ãª El Torito ãã¼ãã»ã¬ã³ã¼ããããã¾ãã"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "ç¡å¹ãª El Torito æ¤è¨¼ã¨ã³ããªã¼ã ISO %(filename)s ã«ããã¾ã"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ç¡å¹ãª El Torito ãã¼ãã»ã¤ã³ã¸ã±ã¼ã¿ã¼ã ISO %(filename)s ã«ããã¾ã"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"1 次ããªã¥ã¼ã ã®äºæããªãããªã¥ã¼ã ã»ã¿ã¤ãã ISO %(filename)s ã«ããã¾ã"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"ããªã¥ã¼ã ã»ãã£ã¹ã¯ãªãã¿ã¼ã ISO %(filename)s ããèªã¿åã£ã¦ãã¾ãããã"
+"ãã©ã¼ãããã䏿£ã§ãã"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"ãã¤ãã¼ãã¤ã¶ã¼ã«ãã® ISO %(filename)s ã使ç¨ããæ¨©éãããã¾ããã/var/lib/"
+"libvirt ã®ä¸ã«ç§»åããããå¯è½ã§ããã°æ¤ç´¢è¨±å¯ãã%(user)sãã¦ã¼ã¶ã¼ã®ãã¡ã¤"
+"ã«ã»ã¢ã¯ã»ã¹å¶å¾¡ãªã¹ãã«è¨å®ããããã%(user)sããISO ãã¹ã»ã°ã«ã¼ãã«è¿½å ã"
+"ãããã¾ãã¯ãchmod -R o+x path_to_isoããå®è¡ (æ¨å¥¨ããã¾ãã) ãã¦ãã ã"
+"ãã詳細: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "ä»®æ³ãã·ã³ %(name)s ã¯æ¢ã«åå¨ãã¾ã"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "ä»®æ³ãã·ã³ %(name)s ã¯åå¨ãã¾ãã"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "忢ãã¦ããä»®æ³ãã·ã³ %(name)s ã®ã¹ã¯ãªã¼ã³ã»ã·ã§ãããåå¾ã§ãã¾ãã"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "ãªã¢ã¼ã ISO ã¤ã¡ã¼ã¸ã¯ããã®ãµã¼ãã¼ã§ã¯ãµãã¼ãããã¦ãã¾ããã"
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ãåå¾ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"listen ãè¡ãã°ã©ãã£ãã¯ã¹ã»ã¢ãã¬ã¹ã¯ãIPv4 ã¾ã㯠IPv6 ã§ãªããã°ãªãã¾ã"
+"ã"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "ä»®æ³ãã·ã³ã®ä½æå
ã¨ãªããã³ãã¬ã¼ããæå®ãã¦ãã ãã"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ãå§åã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ã忢ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ãåé¤ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ãåå夿´ã§ãã¾ããã詳細: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "ãããã¯ã¼ã¯åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "ãããã¯ã¼ã¯åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "ã¦ã¼ã¶ã¼ã%(users)sãã¯åå¨ãã¾ããã"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "ã¦ã¼ã¶ã¼ã%(groups)sãã¯åå¨ãã¾ããã"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ã忢ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "ä»®æ³ãã·ã³ %(name)s ãå§åã§ãã¾ããã詳細: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã¯ä»®æ³ãã·ã³ %(name)s ã«ã¯åå¨ãã¾ãã"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"ä»®æ³ãã·ã³ %(name)s ç¨ã«æå®ããã¦ãããããã¯ã¼ã¯ %(network)s ã¯åå¨ãã¾ãã"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+"ãµãã¼ãããã¦ããä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã»ã¿ã¤ãã¯ããããã¯ã¼ã¯ã ãã§"
+"ã"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"ä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã®ãããã¯ã¼ã¯åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"ç¡å¹ãªãããã¯ã¼ã¯ã»ã¢ãã«ã»ã«ã¼ããä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã«æå®ããã¦"
+"ãã¾ã"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"æ°ããä»®æ³ãã·ã³ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã«è¿½å ããã¿ã¤ãããã³ãããã¯ã¼ã¯ãæå®ã"
+"ã¾ã"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "ãã³ãã¬ã¼ã %(name)s ã¯æ¢ã«åå¨ãã¾ã"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr ""
+"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ãããããã¯ã¼ã¯ã%(network)sãã¯åå¨"
+"ãã¾ãã"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ããã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã¯å"
+"å¨ãã¾ãã"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ããã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã¯ã¢"
+"ã¯ãã£ãã§ã¯ããã¾ãã"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "CDROM ã«æå®ããã¦ãããã©ã¡ã¼ã¿ã¼ã%(param)sãã¯ç¡å¹ã§ãã"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"ãã³ãã¬ã¼ã %(template)s ç¨ã«æå®ããã¦ãããããã¯ã¼ã¯ %(network)s ã¯ã¢ã¯"
+"ãã£ãã§ã¯ããã¾ãã"
+
+msgid "Template name must be a string"
+msgstr "ãã³ãã¬ã¼ãåã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Template icon must be a path to the image"
+msgstr "ãã³ãã¬ã¼ãã»ã¢ã¤ã³ã³ã¯ã¤ã¡ã¼ã¸ã®ãã¹ã§ãªããã°ãªãã¾ãã"
+
+msgid "Template distribution must be a string"
+msgstr "ãã³ãã¬ã¼ãã»ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Template distribution version must be a string"
+msgstr ""
+"ãã³ãã¬ã¼ãã»ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã»ãã¼ã¸ã§ã³ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾"
+"ãã"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPU æ°ã¯æ´æ°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "ã¡ã¢ãªã¼ã®é (MB åä½) ã¯ã512 ãã大ããæ´æ°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr ""
+"ãã³ãã¬ã¼ã CDROM ã¯ããã¼ã«ã«ã¾ãã¯ãªã¢ã¼ã ISO ãã¡ã¤ã«ã§ãªããã°ãªãã¾ã"
+"ã"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+"ç¡å¹ãªã¹ãã¬ã¼ã¸ã»ãã¼ã« URI %(value)s ããã³ãã¬ã¼ãã«æå®ããã¦ãã¾ã"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+"CDROM ã¨ãã¦ããã³ãã¬ã¼ãã使ããããã® ISO ã¤ã¡ã¼ã¸ãæå®ãã¦ãã ãã"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "ãã³ãã¬ã¼ãç¨ã®ãããã¯ã¼ã¯ããã¹ã¦ãªã¹ãã«æå®ããå¿
è¦ãããã¾ãã"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "次ã®ã¨ã©ã¼ã®ããããã³ãã¬ã¼ãã使ã§ãã¾ãã: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "次ã®ã¨ã©ã¼ã®ããããã³ãã¬ã¼ããåé¤ã§ãã¾ãã: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr ""
+"ãã³ãã¬ã¼ã CDROM ã¯ããã¼ã«ã«ã¾ãã¯ãªã¢ã¼ã ISO ãã¡ã¤ã«ã§ãªããã°ãªãã¾ã"
+"ã"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã¯æ¢ã«åå¨ãã¾ã"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã¯åå¨ãã¾ãã"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã使ããããã«ã¯ã%(item)s ãæå®ãã¦ãã ãã"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "ã¢ã¯ãã£ãã»ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã¯åé¤ã§ãã¾ãã"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ããªã¹ãã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ã®ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ã®æ°ãåå¾ã§ãã¾ããã詳"
+"ç´°:%(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãã¢ã¯ãã£ãã«ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãéã¢ã¯ãã£ãã«ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãåé¤ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"ãã¦ã³ãä¸ã«ã¨ã¯ã¹ãã¼ãã»ãã¹ %(path)s ããããã¯ããã¦ããå¯è½æ§ãããã"
+"ããNFS ãã¼ã«ã使ã§ãã¾ãã"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"ã¨ã¯ã¹ãã¼ãã»ãã¹ %(path)s ã®ãã¦ã³ãã«å¤±æãããããNFS ãã¼ã«ã使ã§ãã¾"
+"ãã"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "ãµãã¼ãããã¦ããªãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ã¿ã¤ã: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ãã¯ãIP ã¾ãã¯ãã¹ãåã§ãªããã°ãªãã¾ãã"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ããã¤ã¹ã»ãã©ã¡ã¼ã¿ã¼ã¯ãªã¹ãã§ãªããã°ãªãã¾ãã"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSI ãã¼ã«ã®ã¿ã¼ã²ãã IQN ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"ãªã¢ã¼ãã»ã¹ãã¬ã¼ã¸ã»ãµã¼ãã¼ã®ãã¼ãã¯ã1 ãã 65535 ã¾ã§ã®æ´æ°ã§ãªããã°ãª"
+"ãã¾ãã"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã使ããã«ã¯ãååã¨ã¿ã¤ããæå®ãã¦ãã ãã"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s ã¯ãæå¹ãªãã£ã¹ã¯/ãã¼ãã£ã·ã§ã³ã§ã¯ãªãããããã¼ã« %(pool)s ã«è¿½"
+"å ã§ãã¾ããã§ããã"
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"è«çã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå¯¾è±¡ã«æ´æ°ã§ããã®ã¯ããã©ã¡ã¼ã¿ã¼ã»ãã£ã¹ã¯ã ãã§"
+"ãã"
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI ãã¹ãã»ã¢ããã¿ã¼åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ããã"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« kimchi_isos ã¯ãå
é¨ä½¿ç¨ã®ããã«äºç´ããã¦ãã¾ã"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãã¢ã¯ãã£ãã«ã§ãã¾ãããNFS ãµã¼ãã¼ %"
+"(server)s ã«å°éã§ãã¾ããã"
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãéã¢ã¯ãã£ãã«ã§ãã¾ãããNFS ãµã¼ãã¼ %"
+"(server)s ã«å°éã§ãã¾ããã"
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"ãã¼ã« %(name)s ã¯ããã¤ãã®ãã³ãã¬ã¼ãã«é¢é£ä»ãããã¦ãããããéã¢ã¯ãã£"
+"ãã«ã§ãã¾ãã"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"ãã¼ã« %(name)s ã¯ããã¤ãã®ãã³ãã¬ã¼ãã«é¢é£ä»ãããã¦ãããããåé¤ã§ãã¾"
+"ãã"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"ååã%(name)sãã®ããªã¥ã¼ã ã»ã°ã«ã¼ãã¯æ¢ã«åå¨ãã¾ããè«çãã¼ã«ã使ãã"
+"ã«ã¯ãå¥ã®ååã鏿ãã¦ãã ããã"
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"次ã®ã¨ã©ã¼ã®ããããã¼ã¿ãã¼ã¹ããã£ã¼ãã»ã¹ãã£ã³æ
å ±ã§æ´æ°ã§ãã¾ãã: %"
+"(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ã¯æ¢ã«åå¨ãã¾ã"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ã¯ãã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã«åå¨ãã¾ã"
+"ã"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(volume)s ã使ããããã«ã¯ã%(item)s ãæå®ãã¦ãã "
+"ãã"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ãã¢ã¯ãã£ãã§ã¯ãªããããã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã "
+"ããªã¹ãã§ãã¾ãã"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ãã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã«ä½æã§ãã¾ã"
+"ãã詳細: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(pool)s ã®ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ããªã¹ãã§ãã¾ããã詳"
+"ç´°: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã« %(name)s ãã¯ã¤ãã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ãåé¤ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã %(name)s ããµã¤ãºå¤æ´ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ã¿ã¤ã %(type)s ã§ã¯ãããªã¥ã¼ã 使ããã³åé¤ã¯ãµãã¼ãããã¦ã"
+"ã¾ãã"
+
+msgid "Storage volume name must be a string"
+msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã å²ãæ¯ãã¯æ´æ°ã§ãªããã°ãªãã¾ãã"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ã«ã¯ããªã¥ã¼ã åãå¿
è¦ã§ã"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"次ã®ã¨ã©ã¼ã®ããããã¼ã¿ãã¼ã¹ãã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã æ
å ±ã§æ´æ°ã§ãã¾ãã: %"
+"(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(name)s ã¯åå¨ãã¾ãã"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "ãããã¯ã¼ã¯ %(name)s ã¯æ¢ã«åå¨ãã¾ã"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "ãããã¯ã¼ã¯ %(name)s ã¯åå¨ãã¾ãã"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"ãããã¯ã¼ã¯ %(network)s ç¨ã«æå®ããã¦ãããµãããã %(subnet)s ã¯ç¡å¹ã§ãã"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"ããªãã¸æ¥ç¶ãããã¯ã¼ã¯ %(name)s ã使ããã«ã¯ããããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼"
+"ãã§ã¼ã¹ãæå®ãã¦ãã ãã"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "ã¢ã¯ãã£ãã»ãããã¯ã¼ã¯ %(name)s ã¯åé¤ã§ãã¾ãã"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+"ãããã¯ã¼ã¯ %(network)s ç¨ã«æå®ããã¦ããã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã¯ãæ¢"
+"ã«ä½¿ç¨ããã¦ãã¾ã"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+"ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¯ã㢠NICãçµåãã¾ãã¯ããªãã¸ã»ããã¤ã¹ã§ãªããã°ãªãã¾ã"
+"ãã"
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "ãããã¯ã¼ã¯ %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "ãããã¯ã¼ã¯ã%(name)sãã®ããªã¼ IP ã¢ãã¬ã¹ãè¦ã¤ããã¾ããã"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "ãµãã¼ãããã¦ãããããã¯ã¼ã¯ã»ã¿ã¤ãã¯éé¢ãNATãããã³ããªãã¸ã§ã"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"ãããã¯ã¼ã¯ã»ãµããããã¯ãIP ã¢ãã¬ã¹ã¨ãã¬ãã£ãã¯ã¹ã¾ãã¯ããããã¹ã¯ã"
+"å
¥ã£ãã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Network interface must be a string"
+msgstr "ãããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "ãããã¯ã¼ã¯ VLAN ID ã¯ã1 ãã 4094 ã¾ã§ã®æ´æ°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Specify name and type to create a Network"
+msgstr "ãããã¯ã¼ã¯ã使ããã«ã¯ãååã¨ã¿ã¤ããæå®ãã¦ãã ãã"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"ããªãã¸ã»ããã¤ã¹ %(name)s ããVLAN ã®ãã©ã³ã¯ã»ããã¤ã¹ã«ãããã¨ã¯ã§ãã¾ã"
+"ãã"
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã®æ´»ååã«å¤±æãã¾ãã: %(err)sã"
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"ã¤ã³ã¿ã¼ãã§ã¼ã¹ %(iface)s ã®æ´»ååã«å¤±æãã¾ãããç©çãªã³ã¯ç¶æ³ã確èªãã¦ã"
+"ã ããã"
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "ãããã°ã»ã¬ãã¼ã %(name)s ã¯åå¨ãã¾ããã"
+
+msgid "Debug report tool not found in system"
+msgstr "ãããã°ã»ã¬ãã¼ãã»ãã¼ã«ãã·ã¹ãã ã«è¦ã¤ããã¾ãã"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "ãããã°ã»ã¬ãã¼ã %(name)s ã使ã§ãã¾ããã詳細: %(err)s"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "ãããã°ã»ã¬ãã¼ã %(name)s ãçæã§ãã¾ããã詳細: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"ååã%(name)sãã®ããªã¥ã¼ã ã»ã°ã«ã¼ãã¯æ¢ã«åå¨ãã¾ããè«çãã¼ã«ã使ãã"
+"ã«ã¯ãå¥ã®ååã鏿ãã¦ãã ããã"
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ãµã¼ãã¼ %(server)s ã¯ãKimchi ã«ãã£ã¦ä½¿ç¨ããã¦ãã¾ããã§ãã"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã%(name)sãã¯åå¨ãã¾ãã"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "ãã¼ãã£ã·ã§ã³ %(name)s ã¯ããã¹ãã«åå¨ãã¾ãã"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr "稼åä¸ã®ä»®æ³ãã·ã³ãããããããã¹ãã»ãã·ã³ãã·ã£ãããã¦ã³ã§ãã¾ãã"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "稼åä¸ã®ä»®æ³ãã·ã³ãããããããã¹ãã»ãã·ã³ããªãã¼ãã§ãã¾ãã"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "ãã¼ãã»ããã¤ã¹ã%(name)sããè¦ã¤ããã¾ãã"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "æ´æ°ã®å¯¾è±¡ã¨ãã¦ãã¼ã¯ããã¦ããããã±ã¼ã¸ã¯ããã¾ãã"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "ããã±ã¼ã¸ %(name)s ã¯ãæ´æ°ã®å¯¾è±¡ã¨ãã¦ãã¼ã¯ããã¦ãã¾ããã"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"æ´æ°ã®å¯¾è±¡ã¨ãã¦ãã¼ã¯ãããããã±ã¼ã¸ãåå¾ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ã"
+"ãã詳細: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "ãã®ã·ã¹ãã ç¨ã®äºæããã±ã¼ã¸ã»ããã¼ã¸ã£ã¼ãããã¾ããã"
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "ç¡å¹ãª URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ã¿ã¤ããç¡å¹ã§ãããµãã¼ãããã¦ããã¿ã¤ãã¯ãcdromãã§ãã"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"æ°ããã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã使ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ãã: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãæ´æ°ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ãã: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãåé¤ãã¦ããã¨ãã«ãã¨ã©ã¼ãããã¾ãã: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "æ°ããä»®æ³ãã·ã³ã»ãã£ã¹ã¯ã«è¿½å ããã¿ã¤ãããã³ãã¹ãæå®ãã¾ã"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "ä»®æ³ãã·ã³ã»ãã£ã¹ã¯ãæ´æ°ããã«ã¯ããã¹ãæå®ãã¦ãã ãã"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "æ°ããä»®æ³ãã·ã³ã»ãã£ã¹ã¯ã«è¿½å ããã¿ã¤ãããã³ãã¹ãæå®ãã¾ã"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM ãªãã¸ããªã¼ ID ã¯ã1 ã¯ã¼ãã®ã¿ã®ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr ""
+"ãªãã¸ããªã¼ URL 㯠http://ãftp://ãã¾ã㯠file:// URL ã§ãªããã°ãªãã¾ã"
+"ãã"
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"ãªãã¸ããªã¼æ§æã¨ã¯ããªãã¸ããªã¼ã»ã¿ã¤ãã«å¿ãã¦ç¹å®ã®å¤ãå
¥ã£ããã£ã¯ã·ã§"
+"ããªã¼ã§ãã"
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+"DEB ãªãã¸ããªã¼ã¸ã®ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã¯ãã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr ""
+"DEB ãªãã¸ããªã¼ã¸ã®ã³ã³ãã¼ãã³ãã¯ãé
åã¨ãã¦ãªã¹ãããã¦ããªããã°ãªãã¾"
+"ãã"
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEB ãªãã¸ããªã¼ã¸ã®ã³ã³ãã¼ãã³ãã¯ãã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUM ãªãã¸ããªã¼åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ããã"
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG ãã§ãã¯ã¯ãã¼ã«å¤ã§ãªããã°ãªãã¾ããã"
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG éµã¯ãASCII ã§ä¿åããããã¡ã¤ã«ãæã URL ã§ãªããã°ãªãã¾ããã"
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "ãªãã¸ããªã¼ %(repo_id)s ãæ´æ°ã§ãã¾ããã§ããã"
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "ãªãã¸ããªã¼ %(repo_id)s ã¯åå¨ãã¾ããã"
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "ã·ã¹ãã ç¨ã®ãªãã¸ããªã¼ç®¡çãã¼ã«ãèªèããã¾ããã§ããã"
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "ãªãã¸ããªã¼ %(repo_id)s ã¯æ¢ã«æå¹ã«ãªã£ã¦ãã¾ãã"
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "ãªãã¸ããªã¼ %(repo_id)s ã¯æ¢ã«ç¡å¹ã«ãªã£ã¦ãã¾ãã"
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "ãªãã¸ããªã¼ %(repo_id)s ãåé¤ã§ãã¾ããã§ããã"
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"ãªãã¸ããªã¼æ§æãã¡ã¤ã« %(repo_file)s ãæ¸ãè¾¼ããã¨ãã§ãã¾ããã§ãã"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"DEB ãªãã¸ããªã¼ã使ããããã«ã¯ããªãã¸ããªã¼ã»ãã£ã¹ããªãã¥ã¼ã·ã§ã³ãæ"
+"å®ãã¦ãã ããã"
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "ãªãã¸ããªã¼ %(repo_id)s ãæå¹ã«ã§ãã¾ããã§ããã"
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "ãªãã¸ããªã¼ %(repo_id)s ãç¡å¹ã«ã§ãã¾ããã§ããã"
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM ãªãã¸ããªã¼ ID ã¯æ¢ã«åå¨ãã¾ã"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM ãªãã¸ããªã¼åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "ãªãã¸ããªã¼ããªã¹ãã§ãã¾ããã詳細: ã%(err)sã"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "ãªãã¸ããªã¼æ
å ±ãåå¾ã§ãã¾ããã詳細: ã%(err)sã"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "ãªãã¸ããªã¼ã追å ã§ãã¾ããã詳細: ã%(err)sã"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "ãªãã¸ããªã¼ãåé¤ã§ãã¾ããã詳細: ã%(err)sã"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "ã¨ã©ã¼ã»ã³ã¼ã"
+
+msgid "REASON"
+msgstr "çç±"
+
+msgid "STACK"
+msgstr "ã¹ã¿ãã¯"
+
+msgid "Go to Homepage"
+msgstr "ãã¼ã ã»ãã¼ã¸ã«ç§»åãã"
+
+msgid "Create a New Virtual Machine"
+msgstr "æ°è¦ä»®æ³ãã·ã³ã®ä½æ"
+
+msgid "Virtual Machine Name"
+msgstr "ä»®æ³ãã·ã³å"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"ååã¯ä»®æ³ãã·ã³ãèå¥ããããã«ä½¿ç¨ããã¾ããçç¥ããã¨ã使ç¨ããã¦ãããã³"
+"ãã¬ã¼ãã«åºã¥ãã¦é¸æããã¾ãã"
+
+msgid "Template"
+msgstr "ãã³ãã¬ã¼ã"
+
+msgid "Please create a template first."
+msgstr "ã¾ããã³ãã¬ã¼ãã使ãã¦ãã ããã"
+
+msgid "Create a Template"
+msgstr "ãã³ãã¬ã¼ãã®ä½æ"
+
+msgid "Please choose a template."
+msgstr "ãã³ãã¬ã¼ãã鏿ãã¦ãã ããã"
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "OS ãã¼ã¸ã§ã³"
+
+msgid "CPUS"
+msgstr "CPU"
+
+msgid "Memory"
+msgstr "ã¡ã¢ãªã¼"
+
+msgid "Create"
+msgstr "使"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "åæ¶"
+
+msgid "Edit Guest"
+msgstr "ã²ã¹ãã®ç·¨é"
+
+msgid "General"
+msgstr "ä¸è¬"
+
+msgid "Storage"
+msgstr "ã¹ãã¬ã¼ã¸"
+
+msgid "Interface"
+msgstr "ã¤ã³ã¿ã¼ãã§ã¼ã¹"
+
+msgid "Permission"
+msgstr "ãã¼ã¸ã§ã³"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "åå"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "ã¡ã¢ãªã¼"
+
+msgid "Icon"
+msgstr "ã¢ã¤ã³ã³"
+
+msgid "Device"
+msgstr "ããã¤ã¹å"
+
+msgid "Path"
+msgstr "NFS ãã¹"
+
+msgid "Network"
+msgstr " ãããã¯ã¼ã¯"
+
+msgid "Type"
+msgstr "ã¿ã¤ã"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "ãã¹ã¦"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "ãã³ãã¼"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "ä¿å"
+
+msgid "Replace"
+msgstr "交æ"
+
+msgid "Detach"
+msgstr "åãé¢ã"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "éå§"
+
+msgid "Reset"
+msgstr "ãªã»ãã"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "ã¢ã¯ã·ã§ã³"
+
+msgid "Connect"
+msgstr "æ¥ç¶"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "ç·¨é"
+
+msgid "Shut Down"
+msgstr "ã·ã£ãããã¦ã³"
+
+msgid "Delete"
+msgstr "åé¤"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "ãã£ã¹ã¯å
¥åºå"
+
+msgid "Network I/O"
+msgstr "ãããã¯ã¼ã¯å
¥åºå"
+
+msgid "Livetile"
+msgstr "ã©ã¤ãã¿ã¤ã«"
+
+msgid "No guests found."
+msgstr "ã²ã¹ããè¦ã¤ããã¾ããã"
+
+msgid "Add a Storage Device to VM"
+msgstr "VM ã«ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã追å "
+
+msgid "Device Type"
+msgstr "ããã¤ã¹ã»ã¿ã¤ã"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "ããã¤ã¹ã»ã¿ã¤ããç¾å¨ãµãã¼ãããã¦ããã®ã¯ \"cdrom\" ã®ã¿ã§ãã"
+
+msgid "Storage Pool"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«"
+
+msgid "Storage pool which volume located in"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "Storage Volume"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«å"
+
+msgid "Storage volume to be attached"
+msgstr "ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã åã¯ã¹ããªã³ã°ã§ãªããã°ãªãã¾ãã"
+
+msgid "File Path"
+msgstr "ãã¡ã¤ã«ã»ãã¹"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "ãµã¼ãã¼å
ã§ã® CDROM ã® ISO ãã¡ã¤ã«ã»ãã¹ã"
+
+msgid "Attach"
+msgstr "æ¥ç¶"
+
+msgid "Shut down"
+msgstr "ã·ã£ãããã¦ã³"
+
+msgid "Restart"
+msgstr "åå§å"
+
+msgid "Basic Information"
+msgstr "åºæ¬æ
å ±"
+
+msgid "OS Distro"
+msgstr "OS ãã£ã¹ããªãã¥ã¼ã·ã§ã³"
+
+msgid "OS Code Name"
+msgstr "OS ã³ã¼ãå"
+
+msgid "Processor"
+msgstr "ããã»ããµã¼"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "ã·ã¹ãã çµ±è¨æ
å ±"
+
+msgid "Software Updates"
+msgstr "ã½ããã¦ã§ã¢æ´æ°"
+
+msgid "Update Progress"
+msgstr "æ´æ°ã®é²è¡ç¶æ³"
+
+msgid "Repositories"
+msgstr "ãªãã¸ããªã¼"
+
+msgid "Debug Reports"
+msgstr "ãããã°ã»ã¬ãã¼ã"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr "å
¥åããã¦ã¼ã¶ã¼åã¾ãã¯ãã¹ã¯ã¼ãã誤ã£ã¦ãã¾ããããç´ãã¦ãã ããã"
+
+msgid "This field is required."
+msgstr "ãã®ãã£ã¼ã«ãã¯å¿
é ã§ãã"
+
+msgid "Log in"
+msgstr "ãã°ã¤ã³"
+
+msgid "Logging in..."
+msgstr "ãã°ã¤ã³ãã¦ãã¾ã..."
+
+msgid "Host"
+msgstr "ãã¹ã"
+
+msgid "Guests"
+msgstr "ã²ã¹ã"
+
+msgid "Templates"
+msgstr "ãã³ãã¬ã¼ã"
+
+msgid "Failed to get application configuration"
+msgstr "ã¢ããªã±ã¼ã·ã§ã³æ§æãåå¾ã§ãã¾ããã§ãã"
+
+msgid "This is not a valid Linux path"
+msgstr "æå¹ãª Linux ãã¹ã§ã¯ããã¾ãã"
+
+msgid "This is not a valid URL."
+msgstr "æå¹ãª URL ã§ã¯ããã¾ããã"
+
+msgid "No such data available."
+msgstr "ãã®ãããªãã¼ã¿ã¯ããã¾ããã"
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"ãã¹ãã»ã·ã¹ãã ã«æ¥ç¶ã§ãã¾ããããã¹ãã»ã·ã¹ãã ã稼åãã¦ãã¦ããããã¯ã¼"
+"ã¯æ¥ç¶ãè¡ããã¦ãããã¨ã確èªãã¦ãã ãããHTTP è¦æ±å¿ç %1"
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "åé¤ã®ç¢ºèª"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "確èª"
+
+msgid "Warning"
+msgstr "è¦å"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "ãã¼ããã¦ãã¾ã..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "å試è¡"
+
+msgid "Detailed message:"
+msgstr "詳細ã¡ãã»ã¼ã¸:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "æå¹ãª ISO ãã¡ã¤ã«ã§ã¯ããã¾ããã"
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "ãã°ããæéãããããã¨ãããã¾ããç¶è¡ãã¾ãã?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "ãã³ãã¬ã¼ãã¯å®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"ããã¤ãã®ä»®æ³ãã·ã³ã稼åãã¦ããããã«ãã·ã¹ãã ãã·ã£ãããã¦ã³ã§ãã¾ãã!"
+
+msgid "Max:"
+msgstr "æå¤§:"
+
+msgid "Utilization"
+msgstr "使ç¨ç"
+
+msgid "Available"
+msgstr "使ç¨å¯è½"
+
+msgid "Read Rate"
+msgstr "èªã¿åãé度"
+
+msgid "Write Rate"
+msgstr "æ¸ãè¾¼ã¿é度"
+
+msgid "Received"
+msgstr "åä¿¡æ¸ã¿"
+
+msgid "Sent"
+msgstr "éä¿¡æ¸ã¿"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"ãã¹ããã·ã£ãããã¦ã³ã¾ãã¯åå§åããã¨ãä¿åããã¦ããªã使¥ã¯å¤±ããã¾ãã"
+"ã·ã£ãããã¦ã³/åå§åãç¶è¡ãã¾ãã?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"ãªãã¸ããªã¼ã¯å®å
¨ã«åé¤ããããªã«ããªã¼ã§ããªããªãã¾ããç¶è¡ãã¾ãã?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "ãã¼ã¹ URL"
+
+msgid "Is Mirror"
+msgstr "ãã©ã¼"
+
+msgid "URL Args"
+msgstr "URL 弿°"
+
+msgid "Enabled"
+msgstr "使ç¨å¯è½"
+
+msgid "GPG Check"
+msgstr "GPG ãã§ãã¯"
+
+msgid "GPG Key"
+msgstr "GPG éµ"
+
+msgid "Add"
+msgstr "追å "
+
+msgid "Remove"
+msgstr "é¤å»"
+
+msgid "Enable"
+msgstr "使ç¨å¯è½"
+
+msgid "Disable"
+msgstr "使ç¨ä¸å¯"
+
+msgid "Package Name"
+msgstr "ããã±ã¼ã¸å"
+
+msgid "Version"
+msgstr "ãã¼ã¸ã§ã³"
+
+msgid "Architecture"
+msgstr "ã¢ã¼ããã¯ãã£ã¼"
+
+msgid "Repository"
+msgstr "ãªãã¸ããªã¼"
+
+msgid "Update All"
+msgstr "ãã¹ã¦æ´æ°"
+
+msgid "Updating..."
+msgstr "æ´æ°ãã¦ãã¾ã..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "ããã±ã¼ã¸ãæ´æ°ã§ãã¾ããã§ããã"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"ãããã°ã»ã¬ãã¼ãã¯å®å
¨ã«åé¤ããããªã«ããªã¼ã§ããªããªãã¾ããç¶è¡ãã¾ãã?"
+
+msgid "Generated Time"
+msgstr "çææå»"
+
+msgid "Generate"
+msgstr "çæ"
+
+msgid "Generating..."
+msgstr "çæãã¦ãã¾ã..."
+
+msgid "Rename"
+msgstr "åå夿´"
+
+msgid "Download"
+msgstr "ãã¦ã³ãã¼ã"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr "ã¬ãã¼ãåã«ä½¿ç¨ã§ããã®ã¯ãè±åãæ°åãããã³ãã¤ãã³ (-) ã®ã¿ã§ãã"
+
+msgid "Pending..."
+msgstr "ãã¼ããã¦ãã¾ã..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"ä»®æ³ãã·ã³ã¨ãã®ä»®æ³ãã£ã¹ã¯ãåé¤ããã¾ãããã®æä½ã¯å
ã«æ»ããã¨ãã§ãã¾ã"
+"ããç¶è¡ãã¾ãã?"
+
+msgid "Power off Confirmation"
+msgstr "åé¤ã®ç¢ºèª"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "åé¤ã®ç¢ºèª"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "åé¤ã®ç¢ºèª"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "ãã³ãã¬ã¼ãã¯å®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"ãã® CDROM ã¯å®å
¨ã«åãé¢ããã¾ããã忥ç¶ã§ãã¾ããåãé¢ããç¶è¡ãã¾ãã?"
+
+msgid "Attaching..."
+msgstr "æ¥ç¶ãã¦ãã¾ã..."
+
+msgid "Replacing..."
+msgstr "交æãã¦ãã¾ã..."
+
+msgid "Successfully attached!"
+msgstr "æ£å¸¸ã«æ¥ç¶ãã¾ãã!"
+
+msgid "Successfully replaced!"
+msgstr "æ£å¸¸ã«äº¤æãã¾ãã!"
+
+msgid "Successfully detached!"
+msgstr "æ£å¸¸ã«åãé¢ãã¾ãã!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN ID ã¯ã1 ãã 4094 ã¾ã§ã§ãªããã°ãªãã¾ããã"
+
+msgid "unavailable"
+msgstr "使ç¨ä¸å¯"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"ãã®ã¢ã¯ã·ã§ã³ã¯ããã®ãããã¯ã¼ã¯ã«ä¾åãã¦ããä»®æ³ãã·ã³ã®ãããã¯ã¼ã¯æ¥ç¶"
+"ã妨ãã¾ãã"
+
+msgid "Create a network"
+msgstr "ãããã¯ã¼ã¯ã®ä½æ"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯æ°¸ç¶çãªãã®ã§ã¯ããã¾ããããã®ã¢ã¯ã·ã§ã³ã§ãéã¢ã¯"
+"ãã£ãã«ãªãã®ã§ã¯ãªãå®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯å®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
+
+msgid "This storage pool is empty."
+msgstr "ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯ç©ºã§ãã"
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"ãã£ã¹ã¯ã¯ãã©ã¼ãããããããã®ä¸ã®ãã¼ã¿ã¯ãã¹ã¦å¤±ããã¾ããç¶è¡ãã¾ãã?"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI ãã¡ã¤ãã¼ã»ãã£ãã«"
+
+msgid "No SCSI adapters found."
+msgstr "SCSI ã¢ããã¿ã¼ãè¦ã¤ããã¾ããã"
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«åããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
+
+msgid "The storage pool path can not be blank."
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFS ãµã¼ãã¼ã»ãã¦ã³ãã»ãã¹ããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
+
+msgid "Invalid NFS mount path."
+msgstr "NFS ãã¦ã³ãã»ãã¹ãç¡å¹ã§ãã"
+
+msgid "No logical device selected."
+msgstr "è«çããã¤ã¹ã鏿ããã¦ãã¾ããã"
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSI ã¿ã¼ã²ããããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
+
+msgid "Server name can not be blank."
+msgstr "ãµã¼ãã¼åããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "æç¨å¯è½ãªãã¼ãã£ã·ã§ã³ãæ¢ãã¦ãã¾ã..."
+
+msgid "No available partitions found."
+msgstr "使ç¨å¯è½ãªãã¼ãã£ã·ã§ã³ãè¦ã¤ããã¾ããã"
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã¯æ°¸ç¶çãªãã®ã§ã¯ããã¾ããããã®ã¢ã¯ã·ã§ã³ã§ãéã¢ã¯"
+"ãã£ãã«ãªãã®ã§ã¯ãªãå®å
¨ã«åé¤ããã¾ããç¶è¡ãã¾ãã?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "ãªãã¸ããªã¼æ
å ±ãåå¾ã§ãã¾ããã詳細: ã%(err)sã"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«åããã©ã³ã¯ã«ãããã¨ã¯ã§ãã¾ããã"
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "ãããã¯ã¼ã¯å"
+
+msgid "State"
+msgstr "ç¶æ
"
+
+msgid "Network Type"
+msgstr "ãããã¯ã¼ã¯ã»ã¿ã¤ã"
+
+msgid "Address Space"
+msgstr "ã¢ãã¬ã¹ã»ã¹ãã¼ã¹"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+
+msgid "Isolated: no external network connection"
+msgstr "éé¢: ç©çãããã¯ã¼ã¯æ¥ç¶ãªã"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: ã¢ã¦ããã¦ã³ãç©çãããã¯ã¼ã¯æ¥ç¶ã®ã¿"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "ããªãã¸: ä»®æ³ãã·ã³ãç´æ¥ç©çãããã¯ã¼ã¯ã«æ¥ç¶ããã"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "å®å
:"
+
+msgid "Enable VLAN"
+msgstr "VLAN ã使ç¨å¯è½ã«ãã:"
+
+msgid "VLAN ID"
+msgstr "VLAN ID:"
+
+msgid "Stop"
+msgstr "忢"
+
+msgid "Generate a New Debug Report"
+msgstr "æ°è¦ãããã°ã»ã¬ãã¼ãã®çæ"
+
+msgid "Report Name"
+msgstr "ã¬ãã¼ãå"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"ååã¯ã¬ãã¼ããèå¥ããããã«ä½¿ç¨ããã¾ããçç¥ããã¨ãç¾å¨æå»ã«åºã¥ãã¦é¸"
+"æããã¾ããååã«ã¯è±åãæ°åãããã³ãã¤ãã³ (-) ã使ç¨ã§ãã¾ãã"
+
+msgid "Rename a Debug Report"
+msgstr "æ°è¦ãããã°ã»ã¬ãã¼ãã®çæ"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"ååã¯ã¬ãã¼ããèå¥ããããã«ä½¿ç¨ããã¾ããçç¥ããã¨ãç¾å¨æå»ã«åºã¥ãã¦é¸"
+"æããã¾ããååã«ã¯è±åãæ°åãããã³ãã¤ãã³ (-) ã使ç¨ã§ãã¾ãã"
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "ãªãã¸ããªã¼ã®è¿½å "
+
+msgid "Identifier"
+msgstr "ID"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "ãªãã¸ããªã¼ã®åºæ ID ã示ãåä¸ã®ã¯ã¼ãã"
+
+msgid "Textual name for the repository."
+msgstr "ãªãã¸ããªã¼ã®ããã¹ãåã"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "å¿
é ãã£ã¼ã«ã"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr ""
+"ãªãã¸ããªã¼ã® URL ã§ããµãã¼ãããã¦ãããããã³ã«ã¯ httpãftpãããã³ file "
+"ã§ãã"
+
+msgid "Repository is a mirror"
+msgstr "ãªãã¸ããªã¼ã¯ãã©ã¼ã§ãã"
+
+msgid "Distribution"
+msgstr "ãã£ã¹ããªãã¥ã¼ã·ã§ã³"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEB ãªãã¸ããªã¼ã®ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã"
+
+msgid "Components"
+msgstr "ã³ã³ãã¼ãã³ã"
+
+msgid "List of components in DEB repository."
+msgstr "DEB ãªãã¸ããªã¼å
ã®ã³ã³ãã¼ãã³ãã®ãªã¹ãã"
+
+msgid "Edit Repository"
+msgstr "ãªãã¸ããªã¼ã®ç·¨é"
+
+msgid "Mirror List URL"
+msgstr "ãã©ã¼ã»ãªã¹ã URL"
+
+msgid "Yes"
+msgstr " ã¯ã"
+
+msgid "No"
+msgstr " ããã"
+
+msgid "Capacity"
+msgstr "容é"
+
+msgid "Allocated"
+msgstr "å²ãå½ã¦æ¸ã¿"
+
+msgid "Location"
+msgstr "ãã±ã¼ã·ã§ã³"
+
+msgid "Device path"
+msgstr "ããã¤ã¹ã»ãã¹"
+
+msgid "active"
+msgstr "ã¢ã¯ãã£ã"
+
+msgid "inactive"
+msgstr "éã¢ã¯ãã£ã"
+
+msgid "Deactivate"
+msgstr "éã¢ã¯ãã£ãã«ãã"
+
+msgid "Activate"
+msgstr "ã¢ã¯ãã£ãã«ãã"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "å®ç¾©ãè§£é¤ãã"
+
+msgid "Format"
+msgstr "ãã©ã¼ããã:"
+
+msgid "Allocation"
+msgstr "å²ãæ¯ã:"
+
+msgid "Define a New Storage Pool"
+msgstr "æ°è¦ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®å®ç¾©"
+
+msgid "Storage Pool Name"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«å"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"ååã¯ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãèå¥ããããã«ä½¿ç¨ããã¾ãã空ã«ãããã¨ã¯ã§ãã¾ã"
+"ãã"
+
+msgid "Storage Pool Type"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ã¿ã¤ã"
+
+msgid "Storage Path"
+msgstr "ã¹ãã¬ã¼ã¸ã»ãã¹"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ãã¹ãããããã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«åºæã®ãã¹ãå¿
è¦ã§"
+"ãã"
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"ãã£ã¬ã¯ããªã¼ãã·ã¹ãã ã«åå¨ããªãå ´åãKimchi ããã®ä½æã試ã¿ã¾ãã"
+
+msgid "NFS Server IP"
+msgstr "NFS ãµã¼ãã¼ IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"NFS ãµã¼ãã¼ IP ã¾ãã¯ãã¹ãåãå
¥åãããã¨ãããã¹ããªã¼ãã鏿ãããã¨ã"
+"ã§ãã¾ãã"
+
+msgid "NFS Path"
+msgstr "NFS ãã¹"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFS ããã¹ã NFS ãµã¼ãã¼ã«ã¨ã¯ã¹ãã¼ããã¾ããã"
+
+msgid "iSCSI Server"
+msgstr "iSCSI ãµã¼ãã¼"
+
+msgid "Server"
+msgstr "ãµã¼ãã¼"
+
+msgid "Port"
+msgstr "ãã¼ã"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSI ãµã¼ãã¼ IP ã¾ãã¯ãã¹ãåã空ã«ãããã¨ã¯ã§ãã¾ããã"
+
+msgid "Target"
+msgstr "ã¿ã¼ã²ãã"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSI ãµã¼ãã¼ä¸ã® iSCSI ã¿ã¼ã²ãã"
+
+msgid "Add iSCSI Authentication"
+msgstr "iSCSI èªè¨¼ã®è¿½å "
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI èªè¨¼"
+
+msgid "User Name"
+msgstr "ã¦ã¼ã¶ã¼å"
+
+msgid "Password"
+msgstr "ãã¹ã¯ã¼ã"
+
+msgid "SCSI Adapter"
+msgstr "SCSI ã¢ããã¿ã¼"
+
+msgid "Please, wait..."
+msgstr "ãå¾
ã¡ãã ãã..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "ãã³ãã¬ã¼ãã®è¿½å "
+
+msgid "Where is the source media for this template? "
+msgstr "ãã®ãã³ãã¬ã¼ãã®ã½ã¼ã¹ã»ã¡ãã£ã¢ã¯ã©ãã«ããã¾ãã?"
+
+msgid "Local ISO Image"
+msgstr "ãã¼ã«ã« ISO ã¤ã¡ã¼ã¸"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "ãªã¢ã¼ã ISO ã¤ã¡ã¼ã¸"
+
+msgid "Search ISOs"
+msgstr "ISO ã®æ¤ç´¢"
+
+msgid "The following ISOs are available:"
+msgstr "次㮠ISO ã使ç¨å¯è½ã§ã:"
+
+msgid "OS: "
+msgstr "OS: "
+
+msgid "Version: "
+msgstr "ãã¼ã¸ã§ã³: "
+
+msgid "Size: "
+msgstr "ãµã¤ãº: "
+
+msgid "Search more ISOs"
+msgstr "ISO ãããã«æ¤ç´¢"
+
+msgid "Create Templates from Selected ISO"
+msgstr "鏿ãã ISO ãããã³ãã¬ã¼ãã使"
+
+msgid "I want to use a specific ISO file"
+msgstr "ç¹å®ã® ISO ãã¡ã¤ã«ã使ç¨ãã"
+
+msgid "Loading default remote ISOs ..."
+msgstr "ããã©ã«ãã®ãªã¢ã¼ã ISO ããã¼ããã¦ãã¾ã..."
+
+msgid "Arch: "
+msgstr "ã¢ã¼ããã¯ãã£ã¼: "
+
+msgid "I want to use a custom URL"
+msgstr "ã«ã¹ã¿ã URL ã使ç¨ãã"
+
+msgid "Edit Template"
+msgstr "ãã³ãã¬ã¼ãã®ç·¨é"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "ã°ã©ãã£ãã¯ã¹"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU æ°"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "ãã³ãã¬ã¼ããè¦ã¤ããã¾ããã"
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "%(resource)s ã®åé¤ã¯è¨±å¯ããã¾ãã"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s ã¯æ´æ°ã¡ã½ãããå®è£
ãã¦ãã¾ãã"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "%(resource)s ã®ä½æã¯è¨±å¯ããã¾ãã"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "JSON è¦æ±ãè§£æã§ãã¾ãã"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "ãã® API 㯠JSON ã®ã¿ãµãã¼ããã¾ã"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "ãã¼ã¿ã»ã¹ãã¢ã¯ãã¢ãã«ã»ãªãã¸ã§ã¯ãã§éå§ããã¦ãã¾ããã"
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "次ã®ã¨ã©ã¼ã®ãããã¿ã¹ã¯ãéå§ã§ãã¾ãã: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr ""
+#~ "ã¦ã¼ã¶ã¼ã%(username)sãã®èªè¨¼ã«å¤±æãã¾ããã[ã¨ã©ã¼ã»ã³ã¼ã: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Kimchi ã¸ã®ã¢ã¯ã»ã¹ã許å¯ããã¦ãã¾ãã"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Kimchi ã«ãã°ã¤ã³ããã«ã¯ã%(item)s ãæå®ãã¾ã"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "%(item)s ã¯ãã¼ã¿ã»ã¹ãã¢ã«è¦ã¤ããã¾ãã"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr ""
+#~ "ã³ãã³ãã%(cmd)sããå®è¡ãã¦ãã¾ãããã%(seconds)s ç§ãçµéãã¦ã¿ã¤ã ã¢"
+#~ "ã¦ãã«ãªãã¾ãã"
+
+#~ msgid "Help"
+#~ msgstr "ãã«ã"
+
+#~ msgid "About"
+#~ msgstr "製åæ
å ±"
+
+#~ msgid "Log out"
+#~ msgstr "ãã°ã¢ã¦ã"
+
+#~ msgid "Version:"
+#~ msgstr "ãã¼ã¸ã§ã³: "
diff --git a/src/wok/plugins/kimchi/po/kimchi.pot b/src/wok/plugins/kimchi/po/kimchi.pot
new file mode 100755
index 0000000..d4605c7
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/kimchi.pot
@@ -0,0 +1,2074 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+
+msgid "Remote ISO image is not supported by this server."
+msgstr ""
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+
+msgid "Specify a template to create a virtual machine from"
+msgstr ""
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr ""
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr ""
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr ""
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+
+msgid "Template name must be a string"
+msgstr ""
+
+msgid "Template icon must be a path to the image"
+msgstr ""
+
+msgid "Template distribution must be a string"
+msgstr ""
+
+msgid "Template distribution version must be a string"
+msgstr ""
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr ""
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr ""
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+
+msgid "All networks for the template must be specified in a list."
+msgstr ""
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr ""
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr ""
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr ""
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr ""
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr ""
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr ""
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr ""
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr ""
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+
+msgid "The SCSI host adapter name must be a string."
+msgstr ""
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+
+msgid "Storage volume name must be a string"
+msgstr ""
+
+msgid "Storage volume allocation must be an integer number"
+msgstr ""
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr ""
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+
+msgid "Network interface must be a string"
+msgstr ""
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr ""
+
+msgid "Specify name and type to create a Network"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr ""
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr ""
+
+msgid "Debug report tool not found in system"
+msgstr ""
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr ""
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr ""
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr ""
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr ""
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr ""
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr ""
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+
+msgid "There is no compatible package manager for this system."
+msgstr ""
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr ""
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr ""
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr ""
+
+msgid "Components to DEB repository must be a string"
+msgstr ""
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr ""
+
+msgid "GPG check must be a boolean value."
+msgstr ""
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr ""
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr ""
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr ""
+
+msgid "YUM Repository ID already exists"
+msgstr ""
+
+msgid "YUM Repository name must be a string"
+msgstr ""
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr ""
+
+msgid "REASON"
+msgstr ""
+
+msgid "STACK"
+msgstr ""
+
+msgid "Go to Homepage"
+msgstr ""
+
+msgid "Create a New Virtual Machine"
+msgstr ""
+
+msgid "Virtual Machine Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Please create a template first."
+msgstr ""
+
+msgid "Create a Template"
+msgstr ""
+
+msgid "Please choose a template."
+msgstr ""
+
+msgid "OS"
+msgstr ""
+
+msgid "OS Version"
+msgstr ""
+
+msgid "CPUS"
+msgstr ""
+
+msgid "Memory"
+msgstr ""
+
+msgid "Create"
+msgstr ""
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Edit Guest"
+msgstr ""
+
+msgid "General"
+msgstr ""
+
+msgid "Storage"
+msgstr ""
+
+msgid "Interface"
+msgstr ""
+
+msgid "Permission"
+msgstr ""
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "CPUs"
+msgstr ""
+
+msgid "Memory (MB)"
+msgstr ""
+
+msgid "Icon"
+msgstr ""
+
+msgid "Device"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid "Network"
+msgstr ""
+
+msgid "Type"
+msgstr ""
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr ""
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr ""
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Replace"
+msgstr ""
+
+msgid "Detach"
+msgstr ""
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr ""
+
+msgid "Reset"
+msgstr ""
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr ""
+
+msgid "Connect"
+msgstr ""
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Shut Down"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "CPU"
+msgstr ""
+
+msgid "Disk I/O"
+msgstr ""
+
+msgid "Network I/O"
+msgstr ""
+
+msgid "Livetile"
+msgstr ""
+
+msgid "No guests found."
+msgstr ""
+
+msgid "Add a Storage Device to VM"
+msgstr ""
+
+msgid "Device Type"
+msgstr ""
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr ""
+
+msgid "Storage Pool"
+msgstr ""
+
+msgid "Storage pool which volume located in"
+msgstr ""
+
+msgid "Storage Volume"
+msgstr ""
+
+msgid "Storage volume to be attached"
+msgstr ""
+
+msgid "File Path"
+msgstr ""
+
+msgid "The ISO file path in the server for CDROM."
+msgstr ""
+
+msgid "Attach"
+msgstr ""
+
+msgid "Shut down"
+msgstr ""
+
+msgid "Restart"
+msgstr ""
+
+msgid "Basic Information"
+msgstr ""
+
+msgid "OS Distro"
+msgstr ""
+
+msgid "OS Code Name"
+msgstr ""
+
+msgid "Processor"
+msgstr ""
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr ""
+
+msgid "Software Updates"
+msgstr ""
+
+msgid "Update Progress"
+msgstr ""
+
+msgid "Repositories"
+msgstr ""
+
+msgid "Debug Reports"
+msgstr ""
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+
+msgid "This field is required."
+msgstr ""
+
+msgid "Log in"
+msgstr ""
+
+msgid "Logging in..."
+msgstr ""
+
+msgid "Host"
+msgstr ""
+
+msgid "Guests"
+msgstr ""
+
+msgid "Templates"
+msgstr ""
+
+msgid "Failed to get application configuration"
+msgstr ""
+
+msgid "This is not a valid Linux path"
+msgstr ""
+
+msgid "This is not a valid URL."
+msgstr ""
+
+msgid "No such data available."
+msgstr ""
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Confirm"
+msgstr ""
+
+msgid "Warning"
+msgstr ""
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr ""
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr ""
+
+msgid "Detailed message:"
+msgstr ""
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr ""
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr ""
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+
+msgid "Max:"
+msgstr ""
+
+msgid "Utilization"
+msgstr ""
+
+msgid "Available"
+msgstr ""
+
+msgid "Read Rate"
+msgstr ""
+
+msgid "Write Rate"
+msgstr ""
+
+msgid "Received"
+msgstr ""
+
+msgid "Sent"
+msgstr ""
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Base URL"
+msgstr ""
+
+msgid "Is Mirror"
+msgstr ""
+
+msgid "URL Args"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "GPG Check"
+msgstr ""
+
+msgid "GPG Key"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Enable"
+msgstr ""
+
+msgid "Disable"
+msgstr ""
+
+msgid "Package Name"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Architecture"
+msgstr ""
+
+msgid "Repository"
+msgstr ""
+
+msgid "Update All"
+msgstr ""
+
+msgid "Updating..."
+msgstr ""
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr ""
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+
+msgid "Generated Time"
+msgstr ""
+
+msgid "Generate"
+msgstr ""
+
+msgid "Generating..."
+msgstr ""
+
+msgid "Rename"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr ""
+
+msgid "Pending..."
+msgstr ""
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+
+msgid "Power off Confirmation"
+msgstr ""
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr ""
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr ""
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+
+msgid "Attaching..."
+msgstr ""
+
+msgid "Replacing..."
+msgstr ""
+
+msgid "Successfully attached!"
+msgstr ""
+
+msgid "Successfully replaced!"
+msgstr ""
+
+msgid "Successfully detached!"
+msgstr ""
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr ""
+
+msgid "unavailable"
+msgstr ""
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+
+msgid "Create a network"
+msgstr ""
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+
+msgid "This storage pool is empty."
+msgstr ""
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+
+msgid "SCSI Fibre Channel"
+msgstr ""
+
+msgid "No SCSI adapters found."
+msgstr ""
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr ""
+
+msgid "The storage pool path can not be blank."
+msgstr ""
+
+msgid "NFS server mount path can not be blank."
+msgstr ""
+
+msgid "Invalid NFS mount path."
+msgstr ""
+
+msgid "No logical device selected."
+msgstr ""
+
+msgid "The iSCSI target can not be blank."
+msgstr ""
+
+msgid "Server name can not be blank."
+msgstr ""
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr ""
+
+msgid "No available partitions found."
+msgstr ""
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr ""
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr ""
+
+msgid "State"
+msgstr ""
+
+msgid "Network Type"
+msgstr ""
+
+msgid "Address Space"
+msgstr ""
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+
+msgid "Isolated: no external network connection"
+msgstr ""
+
+msgid "NAT: outbound physical network connection only"
+msgstr ""
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr ""
+
+msgid "Enable VLAN"
+msgstr ""
+
+msgid "VLAN ID"
+msgstr ""
+
+msgid "Stop"
+msgstr ""
+
+msgid "Generate a New Debug Report"
+msgstr ""
+
+msgid "Report Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+
+msgid "Rename a Debug Report"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr ""
+
+msgid "Identifier"
+msgstr ""
+
+msgid "Single word, unique identifier for the repository."
+msgstr ""
+
+msgid "Textual name for the repository."
+msgstr ""
+
+msgid "URL"
+msgstr ""
+
+msgid "Required Field"
+msgstr ""
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr ""
+
+msgid "Repository is a mirror"
+msgstr ""
+
+msgid "Distribution"
+msgstr ""
+
+msgid "Distribution of the DEB repository."
+msgstr ""
+
+msgid "Components"
+msgstr ""
+
+msgid "List of components in DEB repository."
+msgstr ""
+
+msgid "Edit Repository"
+msgstr ""
+
+msgid "Mirror List URL"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Capacity"
+msgstr ""
+
+msgid "Allocated"
+msgstr ""
+
+msgid "Location"
+msgstr ""
+
+msgid "Device path"
+msgstr ""
+
+msgid "active"
+msgstr ""
+
+msgid "inactive"
+msgstr ""
+
+msgid "Deactivate"
+msgstr ""
+
+msgid "Activate"
+msgstr ""
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr ""
+
+msgid "Format"
+msgstr ""
+
+msgid "Allocation"
+msgstr ""
+
+msgid "Define a New Storage Pool"
+msgstr ""
+
+msgid "Storage Pool Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+
+msgid "Storage Pool Type"
+msgstr ""
+
+msgid "Storage Path"
+msgstr ""
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+
+msgid "NFS Server IP"
+msgstr ""
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+
+msgid "NFS Path"
+msgstr ""
+
+msgid "The NFS exported path on NFS server."
+msgstr ""
+
+msgid "iSCSI Server"
+msgstr ""
+
+msgid "Server"
+msgstr ""
+
+msgid "Port"
+msgstr ""
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr ""
+
+msgid "Target"
+msgstr ""
+
+msgid "The iSCSI target on iSCSI server"
+msgstr ""
+
+msgid "Add iSCSI Authentication"
+msgstr ""
+
+msgid "iSCSI Authentication"
+msgstr ""
+
+msgid "User Name"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "SCSI Adapter"
+msgstr ""
+
+msgid "Please, wait..."
+msgstr ""
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr ""
+
+msgid "Where is the source media for this template? "
+msgstr ""
+
+msgid "Local ISO Image"
+msgstr ""
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr ""
+
+msgid "Search ISOs"
+msgstr ""
+
+msgid "The following ISOs are available:"
+msgstr ""
+
+msgid "OS: "
+msgstr ""
+
+msgid "Version: "
+msgstr ""
+
+msgid "Size: "
+msgstr ""
+
+msgid "Search more ISOs"
+msgstr ""
+
+msgid "Create Templates from Selected ISO"
+msgstr ""
+
+msgid "I want to use a specific ISO file"
+msgstr ""
+
+msgid "Loading default remote ISOs ..."
+msgstr ""
+
+msgid "Arch: "
+msgstr ""
+
+msgid "I want to use a custom URL"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "CDROM"
+msgstr ""
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr ""
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr ""
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr ""
diff --git a/src/wok/plugins/kimchi/po/ko_KR.po b/src/wok/plugins/kimchi/po/ko_KR.po
new file mode 100644
index 0000000..08bf222
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/ko_KR.po
@@ -0,0 +1,2197 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ko_KR\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "ë¸ë¡ ì¥ì¹ë¥¼ ê°ì ¸ì¤ë ì¤ì ì¤ë¥ê° ë°ìíìµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "%(device)sì ëí ë¸ë¡ ì¥ì¹ ì 보를 ê°ì ¸ì¤ë ì¤ì ì¤ë¥ê° ë°ìíìµëë¤."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "distro íì¼ì ì°¾ì ì ìì: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"distro íì¼(%(filename)s)ì 구문 ë¶ìí ì ììµëë¤. JSON íì¼ì¸ì§ íì¸íìì"
+"ì¤."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "iSCSI í¸ì¤í¸ ëì %(portal)sì ë¡ê·¸ì¸í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "iSCSI host %(host)s ëì %(target)sì ë¡ê·¸ì¸í ì ììµëë¤."
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISO íì¼ %(filename)sì(ë) ë¶í¸ ê°ë¥íì§ ììµëë¤."
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "ISO íì¼ %(filename)sì ì í¨í El Torito ë¶í¸ ë ì½ëê° ììµëë¤."
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr ""
+"ISO %(filename)sì ì¬ë°ë¥´ì§ ìì El Torito ì í¨ì± ê²ì¦ íëª©ì´ ììµëë¤."
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ISO %(filename)sì ì¬ë°ë¥´ì§ ìì El Torito ë¶í¸ íìê¸°ê° ììµëë¤."
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "ISO %(filename)sìì 기본 ë³¼ë¥¨ì´ ììì¹ ìì 볼륨 ì íì
ëë¤."
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"ISO %(filename)sìì 볼륨 ëì¤í¬ë¦½í°ë¥¼ ì½ë ì¤ì ì못ë íìì´ ë°ê²¬ëììµë"
+"ë¤."
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"íì´í¼ë°ì´ì ê° ì´ ISO %(filename)sì(를) ì¬ì©í ê¶íì´ ììµëë¤. ì´ë¥¼ /var/"
+"lib/libvirt ìëë¡ ì´ëìí¤ê±°ë, (ê°ë¥í ê²½ì°) ê²ì ê¶íì '%(user)s' ì¬ì©ì"
+"ì íì¼ ì¡ì¸ì¤ ì ì´ ëª©ë¡ì ì¤ì íê±°ë, '%(user)s'ì(를) ISO ê²½ë¡ ê·¸ë£¹ì ì¶ê°"
+"íê±°ë, 'chmod -R o+x 'path_to_iso'(ê¶ì¥ëì§ ìì)ì ì¶ê°íììì¤. ì¸ë¶ì¬í: "
+"%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "ê°ì 머ì %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "ê°ì 머ì %(name)sì´(ê°) ììµëë¤."
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "ì¤ì§ë ê°ì 머ì %(name)sì ëí ì¤í¬ë¦°ì·ì ê²ìí ì ììµëë¤."
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "ì격 ISO ì´ë¯¸ì§ë ì´ ìë²ìì ì§ìíì§ ììµëë¤."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ê²ìí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "ì²ì·¨ ëì ê·¸ëí½ ì£¼ìë IPv4 ëë IPv6ì¬ì¼ í©ëë¤."
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "ê°ì 머ì ì ìì±í기 ìí í
í리í¸ë¥¼ ì§ì íììì¤."
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ììí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ì¤ì§í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì ì´ë¦ì ë°ê¿ ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "ë¤í¸ìí¬ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "ë¤í¸ìí¬ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "'%(users)s' ì¬ì©ìê° ììµëë¤."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "'%(groups)s' ì¬ì©ìê° ììµëë¤."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ì¤ì§í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "ê°ì 머ì %(name)sì(를) ììí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "ê°ì 머ì %(name)sì %(iface)s ì¸í°íì´ì¤ê° ììµëë¤."
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr "ê°ì 머ì %(name)sì ëí´ ì§ì ë %(network)s ë¤í¸ìí¬ê° ììµëë¤."
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "ì§ìëë ê°ì 머ì ì¸í°íì´ì¤ ì íì ë¤í¸ìí¬ë¿ì
ëë¤."
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "ê°ì 머ì ì¸í°íì´ì¤ì ë¤í¸ìí¬ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"ê°ì 머ì ì¸í°íì´ì¤ì ëí´ ì¬ë°ë¥´ì§ ìì ë¤í¸ìí¬ ëª¨ë¸ ì¹´ëê° ì§ì ëììµë"
+"ë¤."
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "ì ê°ì 머ì ì¸í°íì´ì¤ë¥¼ ì¶ê°í ì í ë° ë¤í¸ìí¬ë¥¼ ì§ì íììì¤."
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "í
íë¦¬í¸ %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr "í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë '%(network)s' ë¤í¸ìí¬ê° ììµëë¤."
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë ì¤í ë¦¬ì§ í %(pool)sì´(ê°) ììµëë¤."
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+"í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë ì¤í ë¦¬ì§ í %(pool)sì´(ê°) íì±ì´ ìëë"
+"ë¤."
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "CDROMì ëí´ ì¬ë°ë¥´ì§ ìì 매ê°ë³ì '%(param)s'ì´(ê°) ì§ì ëììµëë¤."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"í
íë¦¬í¸ %(template)sì ëí´ ì§ì ë %(network)s ë¤í¸ìí¬ê° íì±ì´ ìëëë¤."
+
+msgid "Template name must be a string"
+msgstr "í
íë¦¬í¸ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Template icon must be a path to the image"
+msgstr "í
íë¦¬í¸ ìì´ì½ì ì´ë¯¸ì§ì ê²½ë¡ì¬ì¼ í©ëë¤."
+
+msgid "Template distribution must be a string"
+msgstr "í
íë¦¬í¸ ë°°í¬ë 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Template distribution version must be a string"
+msgstr "í
íë¦¬í¸ ë°°í¬ ë²ì ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPU ìë ì ìì¬ì¼ í©ëë¤."
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "ë©ëª¨ë¦¬ ì©ë(MB)ì 512ë³´ë¤ í° ì ìì¬ì¼ í©ëë¤."
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "í
íë¦¬í¸ CDROMì ë¡ì»¬ ëë ì격 ISO íì¼ì´ì´ì¼ í©ëë¤."
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+"í
í리í¸ì ëí´ ì¬ë°ë¥´ì§ ìì ì¤í ë¦¬ì§ í URI %(value)sì´(ê°) ì§ì ëììµëë¤."
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "í
í리í¸ë¥¼ ìì±íë ¤ë©´ ISO ì´ë¯¸ì§ë¥¼ CDROMì¼ë¡ ì§ì íììì¤."
+
+msgid "All networks for the template must be specified in a list."
+msgstr "í
í리í¸ì 모ë ë¤í¸ìí¬ê° 목ë¡ì ì§ì ëì´ì¼ í©ëë¤."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "ì¤ë¥ ë문ì í
í리í¸ë¥¼ ìì±í ì ìì: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "ì¤ë¥ ë문ì í
í리í¸ë¥¼ ìì í ì ìì: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "í
íë¦¬í¸ CDROMì ë¡ì»¬ ëë ì격 ISO íì¼ì´ì´ì¼ í©ëë¤."
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì´(ê°) ììµëë¤."
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì±íë ¤ë©´ %(item)sì(를) ì§ì íììì¤."
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "íì± ì¤í ë¦¬ì§ í %(name)sì(를) ìì í ì ììµëë¤."
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ íì ëì´í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"ì¤í ë¦¬ì§ í %(name)sì ìë ì¤í ë¦¬ì§ ë³¼ë¥¨ì ì를 ê°ì ¸ì¬ ì ììµëë¤. ì¸ë¶ì¬"
+"í: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) íì±íí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ë¹íì±íí ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"ë´ë³´ë´ê¸° ê²½ë¡ %(path)sì´(ê°) ë§ì´í¸ ì¤ì ì°¨ë¨ë ì ìì¼ë¯ë¡ NFS íì ìì±í "
+"ì ììµëë¤."
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"ë´ë³´ë´ê¸° ê²½ë¡ %(path)s ë§ì´í¸ê° ì¤í¨íì¼ë¯ë¡ NFS íì ìì±í ì ììµëë¤."
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "ì§ìëì§ ìë ì¤í ë¦¬ì§ í ì í: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "ì¤í ë¦¬ì§ í ê²½ë¡ë 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "ì¤í ë¦¬ì§ í í¸ì¤í¸ë IP ëë í¸ì¤í¸ ì´ë¦ì´ì´ì¼ í©ëë¤."
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "ì¤í ë¦¬ì§ í ì¥ì¹ë 목ë¡ì´ì´ì¼ í©ëë¤."
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSI íì ëì IQNì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "ì격 ì¤í ë¦¬ì§ ìë²ì í¬í¸ë 1ê³¼ 65535 ì¬ì´ì ì ìì¬ì¼ í©ëë¤."
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "ì¤í ë¦¬ì§ íì ìì±íë ¤ë©´ ì´ë¦ ë° ì íì ì§ì íììì¤."
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)sì(ë) ì í¨í ëì¤í¬/íí°ì
ì´ ìëëë¤. ì´ë¥¼ %(pool)s íì ì¶ê°í ì "
+"ììµëë¤."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "ë
¼ë¦¬ ì¤í ë¦¬ì§ íì 매ê°ë³ì ëì¤í¬ë§ ì
ë°ì´í¸í ì ììµëë¤."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI í¸ì¤í¸ ì´ëí° ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "ì¤í ë¦¬ì§ í kimchi_isosë ë´ë¶ ì©ëë¡ ìì½ëììµëë¤."
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ì¤í ë¦¬ì§ í %(name)sì(를) íì±íí ì ììµëë¤. NFS ìë² %(server)sì ì°"
+"ê²°í ì ììµëë¤."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ì¤í ë¦¬ì§ í %(name)sì(를) ë¹íì±íí ì ììµëë¤. NFS ìë² %(server)sì "
+"ì°ê²°í ì ììµëë¤."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"ì¼ë¶ í
í리í¸ì ì°ê´ëì´ ìì¼ë¯ë¡ %(name)s íì ë¹íì±íí ì ììµëë¤."
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "ì¼ë¶ í
í리í¸ì ì°ê´ëì´ ìì¼ë¯ë¡ %(name)s íì ìì í ì ììµëë¤."
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"ì´ë¦ì´ '%(name)s'ì¸ ë³¼ë¥¨ ê·¸ë£¹ì´ ì´ë¯¸ ì¡´ì¬í©ëë¤. ë
¼ë¦¬ íì ìì±íë ¤ë©´ ë¤ë¥¸ ì´"
+"ë¦ì ì ííììì¤."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"ì¤ë¥ ë문ì ìì¸í ì¤ìº ì ë³´ë¡ ë°ì´í°ë² ì´ì¤ë¥¼ ì
ë°ì´í¸í ì ìì: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì´(ê°) ì¤í ë¦¬ì§ í %(pool)sì ììµëë¤."
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(volume)sì(를) ìì±íë ¤ë©´ %(item)sì(를) ì§ì íììì¤."
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"ì¤í ë¦¬ì§ í %(pool)sì´(ê°) íì±ì´ ìëë¯ë¡ ì¤í ë¦¬ì§ ë³¼ë¥¨ì ëì´í ì ììµë"
+"ë¤."
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì(를) ì¤í ë¦¬ì§ í %(pool)sì ìì±í ì ììµëë¤. ì¸ë¶"
+"ì¬í: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"ì¤í ë¦¬ì§ í %(pool)sì ì¤í ë¦¬ì§ ë³¼ë¥¨ì ëì´í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ í %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì(를) ìì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ %(name)sì í¬ê¸°ë¥¼ ì¡°ì í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "ì¤í ë¦¬ì§ ì í %(type)sì(ë) 볼륨 ìì± ë° ìì 를 ì§ìíì§ ììµëë¤."
+
+msgid "Storage volume name must be a string"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ í ë¹ì ì ìì¬ì¼ í©ëë¤."
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ì 볼륨 ì´ë¦ì´ íìí©ëë¤."
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"ì¤ë¥ ë문ì ì¤í ë¦¬ì§ ë³¼ë¥¨ ì ë³´ë¡ ë°ì´í°ë² ì´ì¤ë¥¼ ì
ë°ì´í¸í ì ìì: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "ì¸í°íì´ì¤ %(name)sì´(ê°) ììµëë¤."
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "ë¤í¸ìí¬ %(name)sì´(ê°) ì´ë¯¸ ì¡´ì¬í©ëë¤."
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "ë¤í¸ìí¬ %(name)sì´(ê°) ììµëë¤."
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"ë¤í¸ìí¬ %(network)sì ëí´ ì§ì ë ìë¸ë· %(subnet)sì´(ê°) ì í¨íì§ ììµëë¤."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"ë¸ë¦¿ì§ë ë¤í¸ìí¬ %(name)sì(를) ìì±í ë¤í¸ìí¬ ì¸í°íì´ì¤ë¥¼ ì§ì íììì¤."
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "íì± ë¤í¸ìí¬ %(name)sì(를) ìì í ì ììµëë¤."
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+"ë¤í¸ìí¬ %(network)sì ëí´ ì§ì ë ì¸í°íì´ì¤ %(iface)sì´(ê°) ì´ë¯¸ ì¬ì© ì¤ì
"
+"ëë¤."
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "ì¸í°íì´ì¤ë ìì NIC, ë³¸ë© ëë ë¸ë¦¿ì§ ì¥ì¹ì¬ì¼ í©ëë¤."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "ë¤í¸ìí¬ %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "ë¤í¸ìí¬ '%(name)s'ì ëí ì¬ì IP 주ì를 ì°¾ì ì ììµëë¤."
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "ì§ìëë ë¤í¸ìí¬ ì íì 격리, NAT ë° ë¸ë¦¿ì§ì
ëë¤."
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"ë¤í¸ìí¬ ìë¸ë·ì IP 주ì ë° ì ëë¶ ëë ë·ë§ì¤í¬ê° ìë 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Network interface must be a string"
+msgstr "ë¤í¸ìí¬ ì¸í°íì´ì¤ë 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "ë¤í¸ìí¬ VLAN IDë 1ê³¼ 4094 ì¬ì´ì ì ìì¬ì¼ í©ëë¤."
+
+msgid "Specify name and type to create a Network"
+msgstr "ë¤í¸ìí¬ë¥¼ ìì±íë ¤ë©´ ì´ë¦ ë° ì íì ì§ì íììì¤."
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "ë¸ë¦¿ì§ ì¥ì¹ %(name)sì(ë) VLANì í¸ë í¬ ì¥ì¹ê° ë ì ììµëë¤."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "%(iface)s ì¸í°íì´ì¤ë¥¼ íì±ííì§ ëª»í¨: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"%(iface)s ì¸í°íì´ì¤ë¥¼ íì±ííì§ ëª»íìµëë¤. 물리ì ë§í¬ ìí를 íì¸íìì"
+"ì¤."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "ëë²ê·¸ ë³´ê³ ì %(name)sì´(ê°) ììµëë¤."
+
+msgid "Debug report tool not found in system"
+msgstr "ëë²ê·¸ ë³´ê³ ì ëêµ¬ê° ìì¤í
ì ììµëë¤."
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "ëë²ê·¸ ë³´ê³ ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "ëë²ê·¸ ë³´ê³ ì %(name)sì(를) ìì±í ì ììµëë¤. ì¸ë¶ì¬í: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"ì´ë¦ì´ '%(name)s'ì¸ ë³¼ë¥¨ ê·¸ë£¹ì´ ì´ë¯¸ ì¡´ì¬í©ëë¤. ë
¼ë¦¬ íì ìì±íë ¤ë©´ ë¤ë¥¸ ì´"
+"ë¦ì ì ííììì¤."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "ì¤í ë¦¬ì§ ìë² %(server)sì(ë) Kimchiìì ì¬ì©ëì§ ìììµëë¤."
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s'ì´(ê°) ììµëë¤."
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "íí°ì
%(name)sì´(ê°) í¸ì¤í¸ì ììµëë¤."
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr "ê°ì 머ì ì ì¤í ì¤ì¸ í¸ì¤í¸ 머ì ì ì¢
ë£í ì ììµëë¤."
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "ê°ì 머ì ì ì¤í ì¤ì¸ í¸ì¤í¸ 머ì ì ë¤ì ë¶í
í ì ììµëë¤."
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "ë
¸ë ì¥ì¹ '%(name)s'ì´(ê°) ììµëë¤."
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "ì
ë°ì´í¸ íìë í¨í¤ì§ê° ììµëë¤."
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "í¨í¤ì§ %(name)sì(ë) ì
ë°ì´í¸ëëë¡ íìëì§ ìììµëë¤."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"ì
ë°ì´í¸ëëë¡ íìë í¨í¤ì§ë¥¼ ê°ì ¸ì¤ë ì¤ì ì¤ë¥ê° ë°ìíìµëë¤. ì¸ë¶ì¬í: %"
+"(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "ì´ ìì¤í
ì ëí´ í¸í ê°ë¥í í¨í¤ì§ ê´ë¦¬ìê° ììµëë¤."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "ì¬ë°ë¥´ì§ ìì URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "ì¬ë°ë¥´ì§ ìì ì¤í ë¦¬ì§ ì íì
ëë¤. ì§ìëë ì í: 'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "ì ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ìì±íë ì¤ì ì¤ë¥ ë°ì: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì
ë°ì´í¸íë ì¤ì ì¤ë¥ ë°ì: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì ê±°íë ì¤ì ì¤ë¥ ë°ì: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "ì ê°ì 머ì ëì¤í¬ë¥¼ ì¶ê°í ì í ë° ê²½ë¡ë¥¼ ì§ì íììì¤."
+
+msgid "Specify path to update virtual machine disk"
+msgstr "ê°ì 머ì ëì¤í¬ë¥¼ ì
ë°ì´í¸í ê²½ë¡ë¥¼ ì§ì íììì¤."
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "ì ê°ì 머ì ëì¤í¬ë¥¼ ì¶ê°í ì í ë° ê²½ë¡ë¥¼ ì§ì íììì¤."
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM ì ì¥ì IDë ë¨ì¼ ë¨ì´ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "ì ì¥ì URLì http://, ftp:// ëë file:// URLì´ì´ì¼ í©ëë¤."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr "ì ì¥ì 구ì±ì ì ì¥ì ì íì ë°ë¥¸ í¹ì ê°ì´ ìë ì¬ì ì
ëë¤."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "DEB ì ì¥ìì ëí ë°°í¬ë 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "DEB ì ì¥ìì ëí 구ì±ììë ë°°ì´ì ëì´ëì´ì¼ í©ëë¤."
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEB ì ì¥ìì ëí 구ì±ììë 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUM ì ì¥ì ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG ê²ì¬ë ë¶ì¸ ê°ì´ì´ì¼ í©ëë¤."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG í¤ë ASCII ë³´í¸ íì¼ì ê°ë¦¬í¤ë URLì´ì´ì¼ í©ëë¤."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "%(repo_id)s ì ì¥ì를 ì
ë°ì´í¸í ì ììµëë¤."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "%(repo_id)s ì ì¥ìê° ììµëë¤."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "í´ë¹ ìì¤í
ì ëí ì ì¥ì ê´ë¦¬ ëêµ¬ê° ì¸ìëì§ ìììµëë¤."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "%(repo_id)s ì ì¥ìê° ì´ë¯¸ ì¬ì©ì¼ë¡ ì¤ì ëì´ ììµëë¤."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "%(repo_id)s ì ì¥ìê° ì´ë¯¸ ì¬ì© ìí¨ì¼ë¡ ì¤ì ëì´ ììµëë¤."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "%(repo_id)s ì ì¥ì를 ì ê±°í ì ììµëë¤."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "ì ì¥ì êµ¬ì± íì¼ %(repo_file)sì(를) ìì±í ì ììµëë¤."
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "DEB ì ì¥ì를 ìì±íë ¤ë©´ ì ì¥ì ë°°í¬ë¥¼ ì§ì íììì¤."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "%(repo_id)s ì ì¥ì를 ì¬ì©ì¼ë¡ ì¤ì í ì ììµëë¤."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "%(repo_id)s ì ì¥ì를 ì¬ì© ìí¨ì¼ë¡ ì¤ì í ì ììµëë¤."
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM ì ì¥ì IDê° ì´ë¯¸ ì¡´ì¬í©ëë¤."
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM ì ì¥ì ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "ì ì¥ì를 ëì´í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "ì ì¥ì ì 보를 ëì´í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "ì ì¥ì를 ì¶ê°í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "ì ì¥ì를 ì ê±°í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "ì¤ë¥ ì½ë"
+
+msgid "REASON"
+msgstr "ì´ì "
+
+msgid "STACK"
+msgstr "ì¤í"
+
+msgid "Go to Homepage"
+msgstr "í íì´ì§ë¡ ì´ë"
+
+msgid "Create a New Virtual Machine"
+msgstr "ì ê°ì 머ì ìì±"
+
+msgid "Virtual Machine Name"
+msgstr "ê°ì 머ì ì´ë¦"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"ê°ì 머ì ì ìë³íë ë° ì¬ì©ëë ì´ë¦ì
ëë¤. ìëµëë©´ ì´ë¦ì ì¬ì©ë í
í리í¸"
+"를 기ë°ì¼ë¡ ì íë©ëë¤."
+
+msgid "Template"
+msgstr "í
í리í¸"
+
+msgid "Please create a template first."
+msgstr "í
í리í¸ë¥¼ 먼ì ìì±íììì¤."
+
+msgid "Create a Template"
+msgstr "í
íë¦¬í¸ ìì±"
+
+msgid "Please choose a template."
+msgstr "í
í리í¸ë¥¼ ì ííììì¤."
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "OS ë²ì "
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "ë©ëª¨ë¦¬"
+
+msgid "Create"
+msgstr "ìì±"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "ì·¨ì"
+
+msgid "Edit Guest"
+msgstr "ê²ì¤í¸ í¸ì§"
+
+msgid "General"
+msgstr "ì¼ë°"
+
+msgid "Storage"
+msgstr "ì¤í 리ì§"
+
+msgid "Interface"
+msgstr "ì¸í°íì´ì¤"
+
+msgid "Permission"
+msgstr "ë²ì "
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "ì´ë¦"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "ë©ëª¨ë¦¬"
+
+msgid "Icon"
+msgstr "ìì´ì½"
+
+msgid "Device"
+msgstr "ì¥ì¹ ì´ë¦"
+
+msgid "Path"
+msgstr "NFS ê²½ë¡"
+
+msgid "Network"
+msgstr "ë¤í¸ìí¬"
+
+msgid "Type"
+msgstr "ì í"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "모ë"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "ê³µê¸ì
ì²´"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "ì ì¥"
+
+msgid "Replace"
+msgstr "êµì²´"
+
+msgid "Detach"
+msgstr "ë¶ë¦¬"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "ìì"
+
+msgid "Reset"
+msgstr "ë¤ì ì¤ì "
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "ì¡°ì¹"
+
+msgid "Connect"
+msgstr "ì°ê²°"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "í¸ì§"
+
+msgid "Shut Down"
+msgstr "ìì¤í
ì¢
ë£"
+
+msgid "Delete"
+msgstr "ìì "
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "ëì¤í¬ I/O"
+
+msgid "Network I/O"
+msgstr "ë¤í¸ìí¬ I/O"
+
+msgid "Livetile"
+msgstr "ë¼ì´ë¸íì¼"
+
+msgid "No guests found."
+msgstr "ê²ì¤í¸ê° ììµëë¤."
+
+msgid "Add a Storage Device to VM"
+msgstr "ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ VMì ì¶ê°"
+
+msgid "Device Type"
+msgstr "ì¥ì¹ ì í"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "ì¥ì¹ ì íì
ëë¤. íì¬ \"cdrom\"ë§ ì§ìë©ëë¤."
+
+msgid "Storage Pool"
+msgstr "ì¤í ë¦¬ì§ í"
+
+msgid "Storage pool which volume located in"
+msgstr "ì¤í ë¦¬ì§ í ê²½ë¡ë 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "Storage Volume"
+msgstr "ì¤í ë¦¬ì§ í ì´ë¦"
+
+msgid "Storage volume to be attached"
+msgstr "ì¤í ë¦¬ì§ ë³¼ë¥¨ ì´ë¦ì 문ìì´ì´ì´ì¼ í©ëë¤."
+
+msgid "File Path"
+msgstr "íì¼ ê²½ë¡"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "CDROMì ìí ìë²ì ISO íì¼ ê²½ë¡ì
ëë¤."
+
+msgid "Attach"
+msgstr "ì°ê²°"
+
+msgid "Shut down"
+msgstr "ìì¤í
ì¢
ë£"
+
+msgid "Restart"
+msgstr "ë¤ì ìì"
+
+msgid "Basic Information"
+msgstr "기본 ì ë³´"
+
+msgid "OS Distro"
+msgstr "OS Distro"
+
+msgid "OS Code Name"
+msgstr "OS ì½ë ì´ë¦"
+
+msgid "Processor"
+msgstr "íë¡ì¸ì"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "ìì¤í
íµê³"
+
+msgid "Software Updates"
+msgstr "ìíí¸ì¨ì´ ì
ë°ì´í¸"
+
+msgid "Update Progress"
+msgstr "ì§íìí ì
ë°ì´í¸"
+
+msgid "Repositories"
+msgstr "ì ì¥ì"
+
+msgid "Debug Reports"
+msgstr "ëë²ê·¸ ë³´ê³ ì"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"ì
ë ¥í ì¬ì©ì ì´ë¦ ëë ë¹ë°ë²í¸ê° ì¬ë°ë¥´ì§ ììµëë¤. ë¤ì ìëíììì¤."
+
+msgid "This field is required."
+msgstr "ì´ íëë íìì
ëë¤."
+
+msgid "Log in"
+msgstr "ë¡ê·¸ì¸"
+
+msgid "Logging in..."
+msgstr "ë¡ê·¸ì¸ ì¤..."
+
+msgid "Host"
+msgstr "í¸ì¤í¸"
+
+msgid "Guests"
+msgstr "ê²ì¤í¸"
+
+msgid "Templates"
+msgstr "í
í리í¸"
+
+msgid "Failed to get application configuration"
+msgstr "ì í리ì¼ì´ì
구ì±ì ê°ì ¸ì¤ì§ 못íìµëë¤."
+
+msgid "This is not a valid Linux path"
+msgstr "ì¬ë°ë¥¸ Linux ê²½ë¡ê° ìëëë¤."
+
+msgid "This is not a valid URL."
+msgstr "ì¬ë°ë¥¸ URLì´ ìëëë¤."
+
+msgid "No such data available."
+msgstr "í´ë¹ ë°ì´í°ê° ììµëë¤."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"í¸ì¤í¸ ìì¤í
ì ì ìí ì ììµëë¤. í¸ì¤í¸ ìì¤í
ì´ ê°ëëìê³ ì´ì ëí ë¤í¸"
+"ìí¬ ì°ê²°ì´ ìëì§ íì¸íììì¤. HTTP ìì² ìëµ %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "ìì íì¸"
+
+msgid "OK"
+msgstr "íì¸"
+
+msgid "Confirm"
+msgstr "íì¸"
+
+msgid "Warning"
+msgstr "ê²½ê³ "
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "ë¡ë ì¤..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "ì¬ìë"
+
+msgid "Detailed message:"
+msgstr "ì¸ë¶ ë©ìì§:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "ì¬ë°ë¥¸ ISO íì¼ì´ ìëëë¤."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "ìê°ì´ ì¤ë 걸립ëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "í
í리í¸ê° ì구ì ì¼ë¡ ìì ë©ëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr "ì¼ë¶ ê°ì 머ì ì´ ì¤í ì¤ì´ë¯ë¡ ìì¤í
ì ì¢
ë£í ì ììµëë¤."
+
+msgid "Max:"
+msgstr "ìµë:"
+
+msgid "Utilization"
+msgstr "ì´ì©ë¥ "
+
+msgid "Available"
+msgstr "ì¬ì© ê°ë¥"
+
+msgid "Read Rate"
+msgstr "ì½ê¸° ìë"
+
+msgid "Write Rate"
+msgstr "ì°ê¸° ìë"
+
+msgid "Received"
+msgstr "ë°ì"
+
+msgid "Sent"
+msgstr "ë³´ë"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"í¸ì¤í¸ë¥¼ ì¢
ë£íê±°ë ë¤ì ììíë©´ ì ì¥ëì§ ìì ìì
ì´ ìì¤ë©ëë¤. ìì¤í
ì¢
"
+"ë£/ë¤ì ììì ê³ìíìê² ìµëê¹?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr "ì ì¥ìê° ì구ì ì¼ë¡ ì ê±°ëì´ ë³µêµ¬í ì ììµëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "기본 URL"
+
+msgid "Is Mirror"
+msgstr "미ë¬ì"
+
+msgid "URL Args"
+msgstr "URL ì¸ì"
+
+msgid "Enabled"
+msgstr "ì¬ì©í¨"
+
+msgid "GPG Check"
+msgstr "GPG ê²ì¬"
+
+msgid "GPG Key"
+msgstr "GPG í¤"
+
+msgid "Add"
+msgstr "ì¶ê°"
+
+msgid "Remove"
+msgstr "ì ê±°"
+
+msgid "Enable"
+msgstr "ì¬ì©"
+
+msgid "Disable"
+msgstr "ì¬ì© ìí¨"
+
+msgid "Package Name"
+msgstr "í¨í¤ì§ ì´ë¦"
+
+msgid "Version"
+msgstr "ë²ì "
+
+msgid "Architecture"
+msgstr "ìí¤í
ì²"
+
+msgid "Repository"
+msgstr "ì ì¥ì"
+
+msgid "Update All"
+msgstr "모ë ì
ë°ì´í¸"
+
+msgid "Updating..."
+msgstr "ì
ë°ì´í¸ ì¤..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "í¨í¤ì§ë¥¼ ì
ë°ì´í¸íì§ ëª»íìµëë¤."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"ëë²ê·¸ ë³´ê³ ìê° ì구ì ì¼ë¡ ì ê±°ëì´ ë³µêµ¬í ì ììµëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "Generated Time"
+msgstr "ìì± ìê°"
+
+msgid "Generate"
+msgstr "ìì±"
+
+msgid "Generating..."
+msgstr "ìì± ì¤..."
+
+msgid "Rename"
+msgstr "ì´ë¦ ë°ê¾¸ê¸°"
+
+msgid "Download"
+msgstr "ë¤ì´ë¡ë"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr "ë³´ê³ ì ì´ë¦ìë 문ì, ì«ì ë°/ëë íì´í('-')ë§ í¬í¨ëì´ì¼ í©ëë¤."
+
+msgid "Pending..."
+msgstr "ë¡ë ì¤..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"ê°ì 머ì ë° í´ë¹ ê°ì ëì¤í¬ê° ìì ë©ëë¤. ì´ ì¡°ìì ì¤í ì·¨ìí ì ììµë"
+"ë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "Power off Confirmation"
+msgstr "ìì íì¸"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "ìì íì¸"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "ìì íì¸"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "í
í리í¸ê° ì구ì ì¼ë¡ ìì ë©ëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"ì´ CDROMì ì구ì ì¼ë¡ ë¶ë¦¬ëë©° ë¤ì ì°ê²°í ì ììµëë¤. ë¶ë¦¬ë¥¼ ê³ìíìê² ìµë"
+"ê¹?"
+
+msgid "Attaching..."
+msgstr "ì°ê²° ì¤..."
+
+msgid "Replacing..."
+msgstr "êµì²´ ì¤..."
+
+msgid "Successfully attached!"
+msgstr "ì°ê²°ëììµëë¤."
+
+msgid "Successfully replaced!"
+msgstr "êµì²´ëììµëë¤."
+
+msgid "Successfully detached!"
+msgstr "ë¶ë¦¬ëììµëë¤."
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN IDë 1ê³¼ 4094 ì¬ì´ì¬ì¼ í©ëë¤."
+
+msgid "unavailable"
+msgstr "ì¬ì© ë¶ê°ë¥"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"ì´ ì¡°ì¹ë ì´ ë¤í¸ìí¬ì ìì¡´íë ê°ì 머ì ì ë¤í¸ìí¬ ì°ê²°ì ì¸í°ë½í¸í©ëë¤."
+
+msgid "Create a network"
+msgstr "ë¤í¸ìí¬ ìì±"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"ì´ ì¤í ë¦¬ì§ íì ì§ìì ì´ì§ ììµëë¤. ì´ ì¡°ì¹ë íì ë¹íì±ííì§ ìê³ ì구ì "
+"ì¼ë¡ ìì í©ëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "ì¤í ë¦¬ì§ íì´ ì구ì ì¼ë¡ ìì ë©ëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "This storage pool is empty."
+msgstr "ì´ ì¤í ë¦¬ì§ íì ë¹ì´ ììµëë¤."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr "ëì¤í¬ê° í¬ë§·ëê³ ë°ì´í°ê° ìì¤ë©ëë¤. ê³ìíìê² ìµëê¹? "
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI íì´ë² ì±ë"
+
+msgid "No SCSI adapters found."
+msgstr "SCSI ì´ëí°ê° ììµëë¤."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "ì¤í ë¦¬ì§ í ì´ë¦ì ë¹ìë ì ììµëë¤."
+
+msgid "The storage pool path can not be blank."
+msgstr "ì¤í ë¦¬ì§ í ê²½ë¡ë ë¹ìë ì ììµëë¤."
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFS ìë² ë§ì´í¸ ê²½ë¡ë ë¹ìë ì ììµëë¤."
+
+msgid "Invalid NFS mount path."
+msgstr "ì¬ë°ë¥´ì§ ìì NFS ë§ì´í¸ ê²½ë¡ì
ëë¤."
+
+msgid "No logical device selected."
+msgstr "ë
¼ë¦¬ ì¥ì¹ê° ì íëì§ ìììµëë¤."
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSI ëìì ë¹ìë ì ììµëë¤."
+
+msgid "Server name can not be blank."
+msgstr "ìë² ì´ë¦ì ë¹ìë ì ììµëë¤."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "ì¬ì© ê°ë¥í íí°ì
ì ì°¾ë ì¤..."
+
+msgid "No available partitions found."
+msgstr "ì¬ì© ê°ë¥í íí°ì
ì´ ììµëë¤."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"ì´ ì¤í ë¦¬ì§ íì ì§ìì ì´ì§ ììµëë¤. ì´ ì¡°ì¹ë íì ë¹íì±ííì§ ìê³ ì구ì "
+"ì¼ë¡ ìì í©ëë¤. ê³ìíìê² ìµëê¹?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "ì ì¥ì ì 보를 ëì´í ì ììµëë¤. ì¸ë¶ì¬í: '%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "ì¤í ë¦¬ì§ í ì´ë¦ì ë¹ìë ì ììµëë¤."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "ë¤í¸ìí¬ ì´ë¦"
+
+msgid "State"
+msgstr "ìí"
+
+msgid "Network Type"
+msgstr "ë¤í¸ìí¬ ì í"
+
+msgid "Address Space"
+msgstr "주ì ê³µê°"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "ì¬ë°ë¥´ì§ ìì ì¤í ë¦¬ì§ í ì´ë¦ì
ëë¤. '/'를 í¬í¨íì§ ììì¼ í©ëë¤."
+
+msgid "Isolated: no external network connection"
+msgstr "격리ë¨: 물리ì ë¤í¸ìí¬ ì°ê²° ìì"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: ììë°ì´ë 물리ì ë¤í¸ìí¬ ì°ê²°ë§"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "ë¸ë¦¿ì§ë¨: ê°ì 머ì ì´ ë¬¼ë¦¬ì ë¤í¸ìí¬ì ì§ì ì°ê²°ë¨"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "ëì:"
+
+msgid "Enable VLAN"
+msgstr "VLAN ì¬ì©:"
+
+msgid "VLAN ID"
+msgstr "VLAN ID:"
+
+msgid "Stop"
+msgstr "ì¤ì§"
+
+msgid "Generate a New Debug Report"
+msgstr "ì ëë²ê·¸ ë³´ê³ ì ìì±"
+
+msgid "Report Name"
+msgstr "ë³´ê³ ì ì´ë¦"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"ë³´ê³ ì를 ìë³íë ë° ì¬ì©ëë ì´ë¦ì
ëë¤. ìëµëë©´ ì´ë¦ì íì¬ ìê°ì 기ë°ì¼"
+"ë¡ ì íë©ëë¤. ì´ë¦ì 문ì, ì«ì ë° íì´í(\"-\")ì í¬í¨í ì ììµëë¤."
+
+msgid "Rename a Debug Report"
+msgstr "ì ëë²ê·¸ ë³´ê³ ì ìì±"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"ë³´ê³ ì를 ìë³íë ë° ì¬ì©ëë ì´ë¦ì
ëë¤. ìëµëë©´ ì´ë¦ì íì¬ ìê°ì 기ë°ì¼"
+"ë¡ ì íë©ëë¤. ì´ë¦ì 문ì, ì«ì ë° íì´í(\"-\")ì í¬í¨í ì ììµëë¤."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "ì ì¥ì ì¶ê°"
+
+msgid "Identifier"
+msgstr "ID"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "ì ì¥ìì ëí ë¨ì¼ ë¨ì´ì ê³ ì IDì
ëë¤."
+
+msgid "Textual name for the repository."
+msgstr "ì ì¥ìì ëí í
ì¤í¸ ì´ë¦ì
ëë¤."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "íì íë"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "ì ì¥ìì ëí URLì
ëë¤. ì§ìëë íë¡í ì½ì http, ftp ë° fileì
ëë¤."
+
+msgid "Repository is a mirror"
+msgstr "ì ì¥ìê° ë¯¸ë¬ì
ëë¤."
+
+msgid "Distribution"
+msgstr "ë°°í¬"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEB ì ì¥ìì ë°°í¬ì
ëë¤."
+
+msgid "Components"
+msgstr "구ì±ìì"
+
+msgid "List of components in DEB repository."
+msgstr "DEB ì ì¥ìì 구ì±ìì 목ë¡ì
ëë¤."
+
+msgid "Edit Repository"
+msgstr "ì ì¥ì í¸ì§"
+
+msgid "Mirror List URL"
+msgstr "ë¯¸ë¬ ëª©ë¡ URL"
+
+msgid "Yes"
+msgstr "ì"
+
+msgid "No"
+msgstr "ìëì¤"
+
+msgid "Capacity"
+msgstr "ì©ë"
+
+msgid "Allocated"
+msgstr "í ë¹ë¨"
+
+msgid "Location"
+msgstr "ìì¹"
+
+msgid "Device path"
+msgstr "ì¥ì¹ ê²½ë¡"
+
+msgid "active"
+msgstr "íì±"
+
+msgid "inactive"
+msgstr "ë¹íì±"
+
+msgid "Deactivate"
+msgstr "ë¹íì±í"
+
+msgid "Activate"
+msgstr "íì±í"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "ì ì ì·¨ì"
+
+msgid "Format"
+msgstr "í¬ë§·:"
+
+msgid "Allocation"
+msgstr "í ë¹:"
+
+msgid "Define a New Storage Pool"
+msgstr "ì ì¤í ë¦¬ì§ í ì ì"
+
+msgid "Storage Pool Name"
+msgstr "ì¤í ë¦¬ì§ í ì´ë¦"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "ì¤í ë¦¬ì§ íì ìë³íë ë° ì¬ì©ëë ì´ë¦ì´ë©° ë¹ì´ ìì§ ììì¼ í©ëë¤."
+
+msgid "Storage Pool Type"
+msgstr "ì¤í ë¦¬ì§ í ì í"
+
+msgid "Storage Path"
+msgstr "ì¤í ë¦¬ì§ ê²½ë¡"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr "ì¤í ë¦¬ì§ íì ê²½ë¡ì
ëë¤. ê° ì¤í ë¦¬ì§ íì ê³ ì ê²½ë¡ë¥¼ ê°ì ¸ì¼ í©ëë¤."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"ëë í ë¦¬ê° ìì¤í
ì ì´ë¯¸ ì¡´ì¬íì§ ìì¼ë©´ Kimchiê° ëë í 리 ìì±ì ìëí©ëë¤."
+
+msgid "NFS Server IP"
+msgstr "NFS ìë² IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"NFS ìë² IP ëë í¸ì¤í¸ ì´ë¦ì
ëë¤. ì´ê²ì ì
ë ¥íê±°ë íì¤í 리ìì ì íí ì "
+"ììµëë¤."
+
+msgid "NFS Path"
+msgstr "NFS ê²½ë¡"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFS ìë²ìì NFSì ë´ë³´ë¸ ê²½ë¡ì
ëë¤."
+
+msgid "iSCSI Server"
+msgstr "iSCSI ìë²"
+
+msgid "Server"
+msgstr "ìë²"
+
+msgid "Port"
+msgstr "í¬í¸"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSI ìë² IP ëë í¸ì¤í¸ ì´ë¦ì
ëë¤. ë¹ì´ ìì§ ììì¼ í©ëë¤."
+
+msgid "Target"
+msgstr "ëì"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSI ìë²ì iSCSI ëì"
+
+msgid "Add iSCSI Authentication"
+msgstr "iSCSI ì¸ì¦ ì¶ê°"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI ì¸ì¦"
+
+msgid "User Name"
+msgstr "ì¬ì©ì ì´ë¦"
+
+msgid "Password"
+msgstr "ë¹ë°ë²í¸"
+
+msgid "SCSI Adapter"
+msgstr "SCSI ì´ëí°"
+
+msgid "Please, wait..."
+msgstr "ì ì 기ë¤ë ¤ 주ììì¤."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "í
íë¦¬í¸ ì¶ê°"
+
+msgid "Where is the source media for this template? "
+msgstr "ì´ í
í리í¸ì ìì¤ ë§¤ì²´ë ì´ëì ììµëê¹?"
+
+msgid "Local ISO Image"
+msgstr "ë¡ì»¬ ISO ì´ë¯¸ì§"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "ì격 ISO ì´ë¯¸ì§"
+
+msgid "Search ISOs"
+msgstr "ISO ê²ì"
+
+msgid "The following ISOs are available:"
+msgstr "ë¤ì ISOê° ì¬ì© ê°ë¥í©ëë¤."
+
+msgid "OS: "
+msgstr "OS: "
+
+msgid "Version: "
+msgstr "ë²ì : "
+
+msgid "Size: "
+msgstr "í¬ê¸°: "
+
+msgid "Search more ISOs"
+msgstr "ì¶ê° ISO ê²ì"
+
+msgid "Create Templates from Selected ISO"
+msgstr "ì íí ISOë¡ë¶í° í
íë¦¬í¸ ìì±"
+
+msgid "I want to use a specific ISO file"
+msgstr "í¹ì ISO íì¼ì ì¬ì©íë ¤ê³ í©ëë¤."
+
+msgid "Loading default remote ISOs ..."
+msgstr "기본 ì격 ISO ë¡ë ì¤..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "ì¬ì©ì ì ì URLì ì¬ì©íë ¤ê³ í©ëë¤."
+
+msgid "Edit Template"
+msgstr "í
íë¦¬í¸ í¸ì§"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "ê·¸ëí½"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU ë²í¸"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "í
í리í¸ê° ììµëë¤."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "%(resource)sì ìì ë íì©ëì§ ìì"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)sììë ì
ë°ì´í¸ ë©ìë를 구ííì§ ìì"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "%(resource)sì ìì±ì íì©ëì§ ìì"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "JSON ìì²ì 구문 ë¶ìí ì ììµëë¤."
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "ì´ APIë JSONë§ ì§ìí©ëë¤."
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "ë°ì´í° ì ì¥ìê° ëª¨ë¸ ì¤ë¸ì í¸ìì ììëì§ ìììµëë¤."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "ì¤ë¥ ë문ì ìì
ì ììí ì ìì: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr "ì¬ì©ì '%(username)s'ì ì¸ì¦ì´ ì¤í¨íìµëë¤. [ì¤ë¥ ì½ë: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Kimchiì ì¡ì¸ì¤í ê¶íì´ ììµëë¤."
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Kimchiì ë¡ê·¸ì¸íë ¤ë©´ %(item)sì(를) ì§ì íììì¤."
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "ë°ì´í° ì ì¥ììì %(item)sì(를) ì°¾ì ì ììµëë¤."
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr ""
+#~ "%(seconds)sì´ íì '%(cmd)s' ëª
ë ¹ ì¤í ì¤ ì íìê°ì´ ì´ê³¼ëììµëë¤."
+
+#~ msgid "Help"
+#~ msgstr "ëìë§"
+
+#~ msgid "About"
+#~ msgstr "ì ë³´"
+
+#~ msgid "Log out"
+#~ msgstr "ë¡ê·¸ìì"
+
+#~ msgid "Version:"
+#~ msgstr "ë²ì : "
diff --git a/src/wok/plugins/kimchi/po/pt_BR.po b/src/wok/plugins/kimchi/po/pt_BR.po
new file mode 100644
index 0000000..c2cb4e9
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/pt_BR.po
@@ -0,0 +1,2369 @@
+# i18n portable object for kimchi.
+# Copyright (C) IBM, Corp. 2013-2014
+# ShaoHe Feng <shaohef at linux.vnet.ibm.com>, 2013-04-18.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2015-03-23 12:57+0000\n"
+"Last-Translator: CrÃstian Deives dos Santos Viana <cristiandeives at gmail."
+"com>\n"
+"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/"
+"kimchi/language/pt_BR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pt_BR\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr "Parâmetro desconhecido: %(value)s"
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+"Limite de tempo de %(seconds)s segundos expirado ao executar a tarefa '%"
+"(task)s'."
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr "Usuário %(user_id)s não encontrado com as configurações LDAP dadas."
+
+msgid "Unknown \"_cap\" specified"
+msgstr "\"_cap\" desconhecido especificado"
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr "\"_passthrough\" deve ser \"true\" ou \"false\""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr "\"_passthrough_affected_by\" deve ser um texto do nome do dispositivo"
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "Erro ao consultar block devices. Detalhes %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "Erro ao consultar informações de block devices para %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Não foi possÃvel encontrar o arquivo da distribuição: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"Não foi possÃvel ler o arquivo da distribuição: %(filename)s. Confirme se é "
+"um arquivo JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel logar na máquina alvo do iSCSI %(portal)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Não foi possÃvel logar na máquina %(host)s alvo %(target)s do iSCSI"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr "Não foi possÃvel encontrar a ISO %(filename)s"
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "A ISO %(filename)s não é bootável"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "A ISO %(filename)s não possui uma gravação válida de boot El Torito"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Validação El Torito inválida na ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicador de boot El Torito inválido na ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Tipo de volume não esperado para um volume primário na ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "Formato errado na leitura do descritor de volume na ISO %(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"O servidor não tem permissão para acessar a ISO %(filename)s. Considere mudá-"
+"la para o diretório /var/lib/libvirt, ou mude as permissões para que o "
+"usuário '%(user)s' tenha acesso, ou, adicione o usuário '%(user)s' no grupo "
+"do caminho da ISO, ou (não recomendado) 'chmod -R o+x 'caminho_para_iso'. "
+"Detalhes: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr "Ocorreu um erro ao identificar o sistema operacional da imagem."
+
+msgid "No OS information found in given image."
+msgstr ""
+"Nenhuma informação de sistema operacional encontrada na imagem fornecida."
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr "Não foi possÃvel ler o arquivo de imagem %(filename)s."
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+"Arquivo de imagem deve ser um arquivo existente no sistema. %(filename)s não "
+"é uma entrada válida."
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "Máquina virtual %(name)s já existe"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "Máquina virtual %(name)s não existe"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+"Não foi possÃvel renomear a máquina virtual %(name)s. O nome %(new_name)s já "
+"está em uso ou a máquina virtual não está ligada."
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Não foi possÃvel tirar uma foto da tela para a máquina virtual %(name)s que "
+"está desligada"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "Imagem de ISO remota não é suportada por esse servidor."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr "Foto da tela não é suportado na máquina virtual %(name)s"
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel criar a máquina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel atualizar a máquina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel encontrar a máquina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr "Não foi possÃvel conectar à máquina virtual desligada %(name)s."
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr "URI do Modelo inválida %(value)s especificada para máquina virtual"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+"URI do Storage pool URI inválida %(value)s especificada para máquina virtual"
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr "Gráficos suportados para a máquina virtual são Spice ou VNC"
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "Endereço para receber eventos gráficos deve ser IPv4 ou IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Especifique um modelo para ser base da criação da máquina virtual"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel iniciar a máquina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel forçar o desligamento da máquina virtual %(name)s. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel remover a máquina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel reiniciar a máquina virtual %(name)s. Detalhes: %(err)s"
+
+msgid "User name list must be an array"
+msgstr "Lista de nomes de usuário deve ser um array"
+
+msgid "User name must be a string"
+msgstr "Nome de usuário deve ser um texto"
+
+msgid "Group name list must be an array"
+msgstr "Lista de nomes de grupo deve ser um array"
+
+msgid "Group name must be a string"
+msgstr "Nome de grupo deve ser um texto"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "Usuário(s) '%(users)s' não existe(m)"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "Grupo(s) '%(groups)s' não existe(m)"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel desligar a máquina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel acessar os metadados da máquina virtual %(name)s. Detalhes: "
+"%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr "A senha para o console do guest deve ser um texto."
+
+msgid "The life time for the guest console password must be a number."
+msgstr "O tempo de vida da senha do console do guest deve ser um número."
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr "A máquina virtual '%(name)s' deve estar parada antes de cloná-la."
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr "Espaço em disco insuficiente para clonar a máquina virtual '%(name)s'"
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr "Não foi possÃvel clonar a VM '%(name)s'. Detalhes: %(err)s"
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr "Operação inválida para máquina virtual não-persistente %(name)s"
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+"A VM %(vmid)s não contém o dispositivo de host atribuÃdo diretamente %"
+"(dev_name)s."
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+"Não é permitido atribuir diretamente o dispositivo de host %(dev_name)s."
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+"Nenhum grupo IOMMU encontrado. Passthrough de host PCI necessita do grupo "
+"IOMMU para funcionar corretamente. Por favor, habilite o suporte ao Intel VT-"
+"d ou AMD IOMMU. Para uma CPU Intel, adicione \"intel_iommu=on\" nos seus "
+"parâmetros de kernel em \"/boot/grub2/grub.conf\". Para uma CPU AMD, "
+"adicione \"iommu=pt iommu=1\"."
+
+msgid "\"name\" should be a device name string"
+msgstr "\"nome\" deve ser um texto do nome do dispositivo."
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "Interface %(iface)s não existe na máquina virtual %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"Rede %(network)s especificada para a máquina virtual %(name)s não existe"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "Tipo de interface suportado das máquinas virtuais é somente rede"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "Nome da rede para a interface da máquina virtual deve ser texto"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr "Modelo de placa de rede inválido para a interface da máquina virtual"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Especifique o tipo e a rede para adicionar uma nova interface da máquina "
+"virtual"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Modelo %(name)s já existe"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr "Rede '%(network)s' especificada para o modelo %(template)s não existe"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Storage pool %(pool)s especificado para o modelo %(template)s não existe"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr ""
+"Storage pool %(pool)s especificado para o modelo %(template)s não está ativo"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Parâmetro inválido '%(param)s' especificado para CDROM"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "Rede %(network)s especificada para modelo %(template)s não está ativa"
+
+msgid "Template name must be a string"
+msgstr "Nome do modelo deve ser um texto"
+
+msgid "Template icon must be a path to the image"
+msgstr "Ãcone do modelo deve ser um caminho para uma imagem"
+
+msgid "Template distribution must be a string"
+msgstr "Distribuição do modelo deve ser um texto"
+
+msgid "Template distribution version must be a string"
+msgstr "Versão da distribuição do modelo deve ser um texto"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "O número de CPUs deve ser um inteiro maior do que 0"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "Quantidade de memória (MB) deve ser um inteiro maior que 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Modelo do CDROM deve ser um arquivo ISO local ou remoto"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "URI de storage pool inválido %(value)s especificado para modelo"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+"Especifique uma imagem ISO como CD-ROM ou uma imagem base para criar um "
+"modelo"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Todas redes para o modelo devem ser especificadas em uma lista"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+"Especifique um volume para o template quando o storage pool for iSCSI or SCSI"
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr "O volume %(volume)s não está no storage pool %(pool)s"
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "Não foi possÃvel criar o modelo devido a um erro: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "Não foi possÃvel remover o modelo devido a um erro: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr "O tamanho do disco deve ser um número inteiro maior que 1GB."
+
+msgid "Template base image must be a valid local image file"
+msgstr "Imagem base do modelo deve ser um arquivo de imagem local válido"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr "Não foi possÃvel identificar o formato da imagem base %(path)s"
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+"Ao especificar a topologia de CPU, VCPUs deve ser um produto de sockets, "
+"cores e threads."
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+"Ao especificar a topologia de CPU, cada elemento deve ser um número inteiro "
+"maior do que zero."
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"Formato de imagem de disco inválido. Formatos válidos: bochs, cloop, cow, "
+"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Storage pool %(name)s já existe"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Storage pool %(name)s não existe"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Especifique %(item)s para criar o storage pool %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Não foi possÃvel remover o storage pool ativo %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Não foi possÃvel listar os storage pools. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel criar o storage pool %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Não foi possÃvel saber o número de volumes no storage pool %(name)s. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Não foi possivel ativar o storage pool %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "Não foi possivel desativar o storage pool %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "Não foi possivel remover o storage pool %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"Não foi possÃvel criar Pool NFS uma vez que o caminho de exportação %(path)s "
+"pode bloquear durante a montagem"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"Não foi possÃvel criar NFS Pool uma vez que a montagem do caminho de "
+"exportação %(path)s falhou"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Tipo de storage pool não suportado: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr "Erro durante a leitura do XML do storage pool %(pool)s"
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+"Tipos de storage pool supportados são dir, netfs, logical, iscsi, scsi e "
+"kimchi-iso"
+
+msgid "Storage pool path must be a string"
+msgstr "Caminho para storage pool deve ser um texto"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "Host do storage pool deve ser um IP ou um hostname"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+"Dispositivo do storage pool deve ser o caminho absoluto para o block device"
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Parâmetro dos dispositivos do storage pool devem ser uma lista"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "Alvo IQN de um pool iSCSI deve ser um texto"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"Porta de um servidor remoto de storage deve ser um inteiro entre 1 e 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr "Usuário do iSCSI target deve ser um texto"
+
+msgid "iSCSI target password must be a string"
+msgstr "Senha do iSCSI target deve ser um texto"
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Especifique o nome e o tipo para criar um storage pool"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s não é um disco/partição válido. Não foi possÃvel adicioná-lo ao "
+"pool %(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr "Não foi possÃvel extender o pool lógico %(pool)s. Detalhes: %(err)s"
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"O parâmetro discos somente pode ser atualizado para storage pool lógicos."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "O nome do adaptador SCSI host deve ser um texto"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "O storage pool kimchi_isos é reservado para uso interno"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Não foi possÃvel ativar o storage pool NFS %(name)s. Servidor NFS %(server)s "
+"está inacessÃvel."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Não foi possÃvel desativar o storage pool NFS %(name)s. Servidor NFS %"
+"(server)s está inacessÃvel."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Não foi possÃvel desativar o pool %(name)s uma vez que ele está associado "
+"com algum dos modelos"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"Não foi possÃvel remover o pool %(name)s uma vez que ele está associado com "
+"algum dos modelos"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"Um grupo de volume chamado '%(name)s' já existe. Por favor, escolha outro "
+"nome para criar o pool lógico."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"Não foi possÃvel atualizar a base de dados com informações de mais ISOs "
+"devido a um erro: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Volume de storage %(name)s já existe"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "Volume de storage %(name)s não existe no storage pool %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+"Não foi possÃvel criar o storaget volume %(volume)s pois o storage pool %"
+"(pool)s não está ativo"
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Especifique %(item)s para poder criar o volume %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"Não foi possÃvel listar volumes pois o storage pool %(pool)s não está ativo"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"Não foi possÃvel criar o volume %(name)s no storage pool %(pool)s. Detalhes: "
+"%(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel listar os volumes do storage pool %(pool)s. Detalhes: %(err)"
+"s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel limpar o volume %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel remover o volume %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel redimensionar o volume %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "Storage do tipo %(type)s não suporta criação ou remoção de volume"
+
+msgid "Storage volume name must be a string"
+msgstr "Nome do volume deve ser um texto"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "Alocação do volume de storage deve ser um número inteiro"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"Formato de volume de storage inválido. Formatos válidos: bochs, cloop, cow, "
+"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
+
+msgid "Storage volume requires a volume name"
+msgstr "Volume de storage requer um nome"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Não foi possÃvel atualizar a base de dados com informações de volume de "
+"storage devido a um erro: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr "Somente um parâmetro %(param)s pode ser especificado"
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr "Criar um volume a partir de %(param)s não é suportado"
+
+msgid "Storage volume capacity must be an integer number."
+msgstr "A capacidade do storage volume deve ser um número inteiro."
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+"URL para o storage volume deve ser http://, https://, ftp:// ou ftps://."
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr "Erro ao acessar arquivo %(url)s. Por favor, verifique isso."
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+"Não foi possÃvel clonar o volume de storage '%(name)s' no pool '%(pool)s'. "
+"Detalhes: %(err)s"
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "Interface %(name)s não existe"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Rede %(name)s já existe"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "Rede %(name)s não existe"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"A subrede %(subnet)s especificada para a rede %(network)s não é válida."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "Especifique uma interface de rede para criar a rede de bridge %(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Não foi possÃvel remover a rede ativa %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr ""
+"A interface %(iface)s especificada para a rede %(network)s já está em uso"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "Interface deve ser 'bare NIC', 'bonding' ou 'dispositivo de bridge'."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel criar a rede %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Não foi possÃvel encontrar um endereço IP livre para a rede '%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "A interface %(iface)s já existe"
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Tipos de rede suportados são isolada, NAT e bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"Subrede deve ser um texto com endereço IP e prefixo, ou máscara de rede"
+
+msgid "Network interface must be a string"
+msgstr "Interface de rede deve ser um texto"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "ID da rede VLAN deve ser um inteiro entre 1 e 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Especifique o nome e o tipo para criar uma rede"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"Não foi possÃvel desativar a rede %(name)s. Há alguma máquina virtual %(vms)"
+"s e/ou modelo associados a esta rede."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"Não foi possÃvel desativar a rede %(name)s. Há alguma máquina virtual %(vms)"
+"s e/ou modelo associados a esta rede."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"Dispositivo da bridge %(name)s não pode ser um dispositivo vinculado a uma "
+"VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "Não foi possÃvel ativar a interface %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"Não foi possÃvel ativar a interface %(iface)s. Por favor, verifique o status "
+"da conexão fÃsica."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr "Não foi possÃvel iniciar a rede %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Relatório de debug %(name)s não existe"
+
+msgid "Debug report tool not found in system"
+msgstr "Ferramenta de relatório de debug não encontrada no sistema"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+"Não foi possÃvel criar o relatório de debug %(name)s. Detalhes: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr "Não foi possÃvel encontrar nenhum relatório com o nome %(name)s"
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel gerar o relatório de debug %(name)s. Detalhes: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr "Você deve dar um nome para o arquivo do relatório de debug."
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+"Nome do relatório deve ser um texto. Somente letras, digitos, underscore "
+"('_') e hÃfem ('-') são permitidos."
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"O relatório de debug com o nome especificado \"%(name)s\" já existe. Por "
+"favor, use outro nome."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Servidor de storage %(server)s não foi usado pelo Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distribuição '%(name)s' não existe"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "Partição %(name)s não existe no host"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Não foi possÃvel desligar o host uma vez que há máquinas virtuais ligadas"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"Não foi possÃvel resetar o host uma vez que há máquinas virtuais ligadas"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "Dispositivo de nó '%(name)s' não encontrado"
+
+msgid "Conflicting flag filters specified."
+msgstr "Foram especificados filtros de flag com conflito."
+
+msgid "No packages marked for update"
+msgstr "Nenhum pacote marcado para atualização"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Pacote %(name)s não está marcado para atualização."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr "Erro ao buscar pacotes marcados para atualização. Detalhes: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "Não há gerenciador de pacotes compatÃvel para este sistema."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s inválida"
+
+msgid "Unable to choose a virtual machine name"
+msgstr "Não foi possÃvel escolher um nome para a máquina virtual"
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Tipo de storage inválido. Tipos suportados: 'cdrom', 'disco'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+"O caminho '%(value)s' não é um caminho local/remoto válido para este "
+"dispositivo"
+
+msgid "Only CDROM path can be update."
+msgstr "Apenas o caminho do CD-ROM pode ser atualizado."
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr "O disco %(dev_name)s não existe na máquina virtual %(vm_name)s"
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "Erro ao criar novo dispositivo de storage: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Erro ao atualizar dispositivo de storage: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Erro ao remover dispositivo de storage: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr "Dispositivo IDE hot plug não é suportado"
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Especifique o tipo e o caminho, ou o tipo e o pool/volume, para adicionar um "
+"novo disco da máquina virtual"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "Especifique o caminho para atualizar o disco da máquina virtual"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+"Limitação do tipo do controlador %(type)s de %(limit)s dispositivos foi "
+"alcançada"
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+"Não foi possÃvel buscar informações do caminho do disco para o pool/volume "
+"dado: %(error)s"
+
+msgid "Volume already in use by other virtual machine."
+msgstr "Volume já em uso por outra máquina virtual."
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Somente um caminho ou pool/volume pode ser especificado para adicionar um "
+"novo disco da máquina virtual."
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+"Volume escolhido com formato %(format)s não se enquadra no tipo de storage %"
+"(type)s"
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "ID do repositório YUM deve ser apenas uma palavra."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "URL do repositório deve ser uma URL http://, ftp:// ou file://."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"Configuração do repositório é um dicionário com valores especÃficos de "
+"acordo com o tipo do repositório."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "Distribuição para o repositório DEB deve ser um texto"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "Componentes para o repositório DEB deve ser um array"
+
+msgid "Components to DEB repository must be a string"
+msgstr "Componentes para o repositório DEB deve ser um texto"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Nome do repositório YUM deve ser um texto."
+
+msgid "GPG check must be a boolean value."
+msgstr "Verificação de GPG deve ser um valor booleano."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+"Chave GPG deve ser uma URL apontando para o arquivo no formato ASCII-armor."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Não foi possÃvel atualizar o repositório %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Repositório %(repo_id)s não existe."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+"Ferramenta de gerenciamento de repositório não foi reconhecida no seu "
+"sistema."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Repositório %(repo_id)s já está habilitado."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Repositório %(repo_id)s já está desabilitado."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Não foi possÃvel remover o repositório %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"Não foi possÃvel gravar o arquivo de configuração do repositório %(repo_file)"
+"s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Especificar o repositório de distribuição para poder criar o repositório DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Não foi possÃvel habilitar o repositório %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Não foi possÃvel desabilitar o repositório %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "ID do repositório YUM já existe"
+
+msgid "YUM Repository name must be a string"
+msgstr "Nome do repositório YUM deve ser um texto"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Não é possÃvel listar os repositórios. Detalhes: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+"Não foi possÃvel carregar as informações do repositório. Detalhes: '%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Não foi possÃvel adicionar o repositório. Detalhes: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Não foi possÃvel remover o repositório. Detalhes: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+"Itens de configuração '%(items)s' não são suportados pelo gerenciador de "
+"repositórios."
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+"A máquina virtual '%(vm)s' deve estar parada antes de criar um snapshot dela"
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+"Não foi possÃvel criar o snapshot '%(name)s' na máquina virtual '%(vm)s'. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr "O snapshot '%(name)s' não existe na máquina virtual '%(vm)s'."
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+"Não foi possÃvel recuperar o snapshot '%(name)s' da máquina virtual '%(vm)"
+"s'. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+"Não foi possÃvel listar os snapshots da máquina virtual '%(vm)s'. Detalhes: %"
+"(err)s"
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+"Não foi possÃvel remover o snapshot '%(name)s' da máquina virtual '%(vm)s'. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+"Não foi possÃvel recuperar o snapshot atual da máquina virtual '%(vm)s'. "
+"Detalhes: %(err)s."
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+"Não foi possÃvel reverter a máquina virtual '%(vm)s' para o snapshot '%(name)"
+"s'. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+"Não foi possÃvel criar o snapshot para a máquina virtual '%(vm)s' porque ela "
+"contém discos no formato '%(format)s'; somente 'qcow2' é suportado."
+
+msgid "The number of vCPUs is too large for this system."
+msgstr "O número de VCPUs é grande demais para esse sistema."
+
+msgid "Invalid vCPU/topology combination."
+msgstr "Combinação inválida de VCPU/topologia."
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr "Este host (ou configuração atual) não permite topologia de CPU."
+
+msgid "ERROR CODE"
+msgstr "CÃDIGO DE ERRO"
+
+msgid "REASON"
+msgstr "MOTIVO"
+
+msgid "STACK"
+msgstr "PILHA"
+
+msgid "Go to Homepage"
+msgstr "Ir para a Página Inicial"
+
+msgid "Create a New Virtual Machine"
+msgstr "Criar nova Máquina Virtual"
+
+msgid "Virtual Machine Name"
+msgstr "Nome da Máquina Virtual"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"O nome usado para identificar a máquina virtual. Se ele for omitido, a "
+"escolha será baseada no modelo selecionado."
+
+msgid "Template"
+msgstr "Modelo"
+
+msgid "Please create a template first."
+msgstr "Por favor, crie um modelo primeiro."
+
+msgid "Create a Template"
+msgstr "Criar um Modelo"
+
+msgid "Please choose a template."
+msgstr "Por favor, escolha um modelo."
+
+msgid "OS"
+msgstr "Sistema Operacional"
+
+msgid "OS Version"
+msgstr "Versão do Sistema Speracional"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Memória"
+
+msgid "Create"
+msgstr "Criar"
+
+msgid "Creating..."
+msgstr "Criando..."
+
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "Edit Guest"
+msgstr "Editar Guest"
+
+msgid "General"
+msgstr "Geral"
+
+msgid "Storage"
+msgstr "Storage"
+
+msgid "Interface"
+msgstr "Interface"
+
+msgid "Permission"
+msgstr "Permissão"
+
+msgid "Host PCI Device"
+msgstr "Dispositivo de host PCI"
+
+msgid "Snapshot"
+msgstr "Snapshot"
+
+msgid "Name"
+msgstr "Nome"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "Memória (MB)"
+
+msgid "Icon"
+msgstr "Ãcone"
+
+msgid "Device"
+msgstr "Dispositivo"
+
+msgid "Path"
+msgstr "Caminho"
+
+msgid "Network"
+msgstr "Rede"
+
+msgid "Type"
+msgstr "Tipo"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr "Usuários e grupos de sistema disponÃveis"
+
+msgid "Selected system users and groups"
+msgstr "Usuários e grupos de sistema selecionados"
+
+msgid "User"
+msgstr "Usuário"
+
+msgid "All"
+msgstr "Todos"
+
+msgid "To Add"
+msgstr "Para adicionar"
+
+msgid "Added"
+msgstr "Adicionado"
+
+msgid "filter"
+msgstr "filtro"
+
+msgid "Product"
+msgstr "Produto"
+
+msgid "Vendor"
+msgstr "Vendor"
+
+msgid "Created"
+msgstr "Criado"
+
+msgid "Save"
+msgstr "Salvar"
+
+msgid "Replace"
+msgstr "Substituir"
+
+msgid "Detach"
+msgstr "Remover"
+
+msgid "revert"
+msgstr "Reverter"
+
+msgid "Start"
+msgstr "Iniciar"
+
+msgid "Reset"
+msgstr "Reiniciar"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "Forçar desligamento"
+
+msgid "Actions"
+msgstr "Ações"
+
+msgid "Connect"
+msgstr "Conectar"
+
+msgid "Clone"
+msgstr "Clonar"
+
+msgid "Edit"
+msgstr "Editar"
+
+msgid "Shut Down"
+msgstr "Desligar"
+
+msgid "Delete"
+msgstr "Remover"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "Disco E/S"
+
+msgid "Network I/O"
+msgstr "Rede E/S"
+
+msgid "Livetile"
+msgstr "Tela ao vivo"
+
+msgid "No guests found."
+msgstr "Nenhum guest encontrado."
+
+msgid "Add a Storage Device to VM"
+msgstr "Adicionar um dispositivo de storage à VM"
+
+msgid "Device Type"
+msgstr "Tipo do Dispositivo"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr ""
+"O tipo do dispositivo. Atualmente, \"cdrom\" e \"disco\" são suportados."
+
+msgid "Storage Pool"
+msgstr "Storage Pool"
+
+msgid "Storage pool which volume located in"
+msgstr "Storage pool no qual o volume está localizado"
+
+msgid "Storage Volume"
+msgstr "Volume de storage"
+
+msgid "Storage volume to be attached"
+msgstr "Volume de storage a ser adicionado"
+
+msgid "File Path"
+msgstr "Caminho do Arquivo"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "O caminho do arquivo ISO para o CDROM no servidor."
+
+msgid "Attach"
+msgstr "Adicionar"
+
+msgid "Shut down"
+msgstr "Desligar"
+
+msgid "Restart"
+msgstr "Reiniciar"
+
+msgid "Basic Information"
+msgstr "Informações básicas"
+
+msgid "OS Distro"
+msgstr "Distribuição"
+
+msgid "OS Code Name"
+msgstr "Nome-código do sistema operacional"
+
+msgid "Processor"
+msgstr "Processador"
+
+msgid "CPU(s)"
+msgstr "CPU(s)"
+
+msgid "System Statistics"
+msgstr "EstatÃsticas do sistema"
+
+msgid "Software Updates"
+msgstr "Atualizações de software"
+
+msgid "Update Progress"
+msgstr "Progresso da atualização"
+
+msgid "Repositories"
+msgstr "Repositórios"
+
+msgid "Debug Reports"
+msgstr "Relatórios de Debug"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"O usuário ou senha inseridos estão incorretos. Por favor, tente novamente."
+
+msgid "This field is required."
+msgstr "Esse campo é obrigatório."
+
+msgid "Log in"
+msgstr "Entrar"
+
+msgid "Logging in..."
+msgstr "Entrando..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "Guests"
+
+msgid "Templates"
+msgstr "Modelos"
+
+msgid "Failed to get application configuration"
+msgstr "Não foi possÃvel carregar as configurações da aplicação"
+
+msgid "This is not a valid Linux path"
+msgstr "Este não é um caminho válido no Linux"
+
+msgid "This is not a valid URL."
+msgstr "Essa não é uma URL válida."
+
+msgid "No such data available."
+msgstr "Não há dados disponÃveis."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"Não foi possÃvel contactar o sistema host. Verique se o sistema do host está "
+"ligado e se você possui conectividade de rede com ele. Resposta da "
+"requisição HTTP %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Confirmação de remoção"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Confirmar"
+
+msgid "Warning"
+msgstr "Aviso"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Carregando..."
+
+msgid "An error occurred while retrieving system information."
+msgstr "Ocorreu um erro ao recuperar informações do sistema."
+
+msgid "Retry"
+msgstr "Tentar novamente"
+
+msgid "Detailed message:"
+msgstr "Mensagem detalhada:"
+
+msgid "No ISO found"
+msgstr "Nenhuma ISO encontrada"
+
+msgid "This is not a valid ISO file."
+msgstr "Esse não é um arquivo ISO válido."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Isso vai levar um longo tempo. Deseja continuar?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "O modelo vai ser permanentemente removido. Deseja continuar?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"Não foi possÃvel desligar o sistema porque algumas máquinas virtuais estão "
+"ligadas!"
+
+msgid "Max:"
+msgstr "Máximo:"
+
+msgid "Utilization"
+msgstr "Utilização"
+
+msgid "Available"
+msgstr "DisponÃvel"
+
+msgid "Read Rate"
+msgstr "Taxa de leitura"
+
+msgid "Write Rate"
+msgstr "Taxa de escrita"
+
+msgid "Received"
+msgstr "Recebido"
+
+msgid "Sent"
+msgstr "Enviado"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"Desligar ou reiniciar o host causará perda de trabalho que não foi salvo. "
+"Continuar o processo de desligar/reiniciar?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Repositório será removido permanentemente e não poderá ser recuperado. "
+"Deseja continuar?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL Base"
+
+msgid "Is Mirror"
+msgstr "Ã mirror"
+
+msgid "URL Args"
+msgstr "Argumentos da URL"
+
+msgid "Enabled"
+msgstr "Ativado"
+
+msgid "GPG Check"
+msgstr "Verificação GPG"
+
+msgid "GPG Key"
+msgstr "Chave GPG"
+
+msgid "Add"
+msgstr "Adicionar"
+
+msgid "Remove"
+msgstr "Remover"
+
+msgid "Enable"
+msgstr "Ativar"
+
+msgid "Disable"
+msgstr "Desativar"
+
+msgid "Package Name"
+msgstr "Nome do pacote"
+
+msgid "Version"
+msgstr "Versão"
+
+msgid "Architecture"
+msgstr "Arquitetura"
+
+msgid "Repository"
+msgstr "Repositório"
+
+msgid "Update All"
+msgstr "Atualizar todos"
+
+msgid "Updating..."
+msgstr "Atualizando..."
+
+msgid "Failed to retrieve packages update information."
+msgstr "Não foi possÃvel recuperar as informações de atualização de pacoates."
+
+msgid "Failed to update package(s)."
+msgstr "Erro ao atualizar pacote(s)."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"Relatório de debug será permanentemente removido e não poderá ser "
+"recuperado. Deseja continuar?"
+
+msgid "Generated Time"
+msgstr "Tempo gerado"
+
+msgid "Generate"
+msgstr "Gerar"
+
+msgid "Generating..."
+msgstr "Gerando..."
+
+msgid "Rename"
+msgstr "Renomear"
+
+msgid "Download"
+msgstr "Baixar"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr ""
+"Nome do relatório deve apenas conter letras, números, underscore ('_') e/ou "
+"hÃfen ('-')."
+
+msgid "Pending..."
+msgstr "Pendente..."
+
+msgid "Report name is the same as the original one."
+msgstr "Nome do relatório é o mesmo que o original."
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"A máquina virtual vai ser removida com todos seus discos. Essa operação é "
+"irreversÃvel. Deseja continuar?"
+
+msgid "Power off Confirmation"
+msgstr "Confirmação de desligamento forçado"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+"Essa ação pode produzir resultados não desejáveis, como por exemplo cache de "
+"disco não-atualizado no guest. Deseja continuar?"
+
+msgid "Reset Confirmation"
+msgstr "Confirmação de reinicialização"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+"Existe um risco de perda de dados causado pela reinicialização sem o "
+"desligamento do sistema operacional do guest. Deseja continuar?"
+
+msgid "Shut Down Confirmation"
+msgstr "Confirmação de desligamento"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+"O sistema operacional do guest pode ignorar essa requisição. Deseja "
+"continuar?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr "Confirmação de Remoção da Máquina Virtual"
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+"Essa máquina virtual não é persistente. O desligamento irá removê-la. Deseja "
+"continuar?"
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+"Quando o guest de destino tiver volumes SCSI ou iSCSI, eles serão clonados "
+"no storage pool padrão. O mesmo vai acontecer quando o pool de destino não "
+"tiver espaço suficiente para clonar os volumes. Você deseja continuar?"
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Esse CDROM será desconectado permanentemente e você pode reconectá-lo. "
+"Deseja continuar a remoção? "
+
+msgid "Attaching..."
+msgstr "Adicionando..."
+
+msgid "Replacing..."
+msgstr "Substituindo..."
+
+msgid "Successfully attached!"
+msgstr "Adicionado com sucesso!"
+
+msgid "Successfully replaced!"
+msgstr "SubstituÃdo com sucesso!"
+
+msgid "Successfully detached!"
+msgstr "Removido com sucesso!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+"Esse disco será desconectado permanentemente e você pode reconectá-lo. "
+"Deseja continuar a remoção? "
+
+msgid "interface:"
+msgstr "interface:"
+
+msgid "address:"
+msgstr "endereço:"
+
+msgid "link_type:"
+msgstr "tipo do link:"
+
+msgid "block:"
+msgstr "bloco:"
+
+msgid "drive_type:"
+msgstr "tipo do drive:"
+
+msgid "model:"
+msgstr "modelo:"
+
+msgid "Affected devices:"
+msgstr "Dispositivos afetados:"
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "ID da VLAN deve ser um número entre 1 e 4094."
+
+msgid "unavailable"
+msgstr "indisponÃvel"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"Esta ação irá interromper a conectividade da rede para qualquer máquina "
+"virtual que depende dessa rede."
+
+msgid "Create a network"
+msgstr "Criar uma rede"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Essa rede não é persistente. Ao invés de parar, essa ação irá removê-la "
+"permantemente. Deseja continuar?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "O storage pool vai ser permanentemente removido. Deseja continuar?"
+
+msgid "This storage pool is empty."
+msgstr "Esse storage pool está vazio."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Isso formatará seu disco e você perderá toda informação, você tem certeza "
+"que quer continuar?"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI Fibre Channel"
+
+msgid "No SCSI adapters found."
+msgstr "Nenhum adaptador SCSI encontrado."
+
+msgid "Loading iSCSI targets..."
+msgstr "Carregando iSCSI targets..."
+
+msgid "No iSCSI found. Please input one."
+msgstr "Nenhum iSCSI encontrado. Por favor, forneça um."
+
+msgid "Failed to load iSCSI targets."
+msgstr "Erro ao carregar iSCSI targets."
+
+msgid "The storage pool name can not be blank."
+msgstr "O nome do storage pool não pode ser vazio."
+
+msgid "The storage pool path can not be blank."
+msgstr "O caminho do storage pool não pode ser vazio."
+
+msgid "NFS server mount path can not be blank."
+msgstr "Caminho de montagem do servidor de NFS não pode ser vazio."
+
+msgid "Invalid NFS mount path."
+msgstr "Caminho de montagem do NFS inválido."
+
+msgid "No logical device selected."
+msgstr "Nenhum dispositivo lógico selecionado."
+
+msgid "The iSCSI target can not be blank."
+msgstr "O alvo iSCSI não pode ser vazio."
+
+msgid "Server name can not be blank."
+msgstr "Nome do servidor não pode ser vazio."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr "Este não é um nome ou IP de servidor válido. Por favor, modifique-o."
+
+msgid "Looking for available partitions ..."
+msgstr "Procurando por partições disponÃveis ..."
+
+msgid "No available partitions found."
+msgstr "Nenhuma partição disponÃvel encontrada."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"O storage pool não é persistente. Ao invés de desativar, essa ação vai "
+"removê-lo permanentemente. Deseja continuar?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "Não foi possÃvel recuperar as informações das partições."
+
+msgid "In progress..."
+msgstr "Em progresso..."
+
+msgid "Failed!"
+msgstr "Falhou!"
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+"Caminho do CDROM precisa ser um caminho local válido e não pode ser vazio."
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Pool ou volume do disco não pode ser vazio."
+
+#, fuzzy
+msgid "Filter"
+msgstr "filtro"
+
+msgid "Network Name"
+msgstr "Nome da rede"
+
+msgid "State"
+msgstr "Estado"
+
+msgid "Network Type"
+msgstr "Tipo da rede"
+
+msgid "Address Space"
+msgstr "Espaço de endereço"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "O nome não deve conter '/' and '\"'."
+
+msgid "Isolated: no external network connection"
+msgstr "Isolada: nenhuma conexão externa"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: somente conexão de rede fÃsica de saÃda"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Bridged: Máquinas virtuais estão conectadas diretamente com a rede fÃsica"
+
+msgid "(No interfaces found)"
+msgstr "(Nenhuma interface encontrada)"
+
+msgid "Destination"
+msgstr "Destino"
+
+msgid "Enable VLAN"
+msgstr "Habilitar VLAN"
+
+msgid "VLAN ID"
+msgstr "ID da VLAN"
+
+msgid "Stop"
+msgstr "Parar"
+
+msgid "Generate a New Debug Report"
+msgstr "Gerar um novo Relatório de Debug"
+
+msgid "Report Name"
+msgstr "Nome do Relatório"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"O nome usado para identificar o relatório. Se omitido, um nome será "
+"escolhido baseado no horário atual. O nome pode conter: letras, números, "
+"underscore ('_') e hÃfen ('-')."
+
+msgid "Rename a Debug Report"
+msgstr "Renomear um Relatório de Debug"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"O nome usado para identificar o relatório. O nome pode conter: letras, "
+"dÃgitos e hÃfen (\"-\")."
+
+msgid "Submit"
+msgstr "Enviar"
+
+msgid "Add a Repository"
+msgstr "Adicionar um Repositório"
+
+msgid "Identifier"
+msgstr "Identificador"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Uma única palavra, identificador único para o repositório."
+
+msgid "Textual name for the repository."
+msgstr "Nome textual para o repositório."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Campo Obrigatório"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL para o repositório. Protocolos suportados são http, ftp e file."
+
+msgid "Repository is a mirror"
+msgstr "Repositório é um mirror"
+
+msgid "Distribution"
+msgstr "Distribuição"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribuição para o repositório DEB."
+
+msgid "Components"
+msgstr "Componentes"
+
+msgid "List of components in DEB repository."
+msgstr "Lista de componentes para o repositório DEB."
+
+msgid "Edit Repository"
+msgstr "Editar Repositório"
+
+msgid "Mirror List URL"
+msgstr "URL para a lista de mirror"
+
+msgid "Yes"
+msgstr "Sim"
+
+msgid "No"
+msgstr "Não"
+
+msgid "Capacity"
+msgstr "Capacidade"
+
+msgid "Allocated"
+msgstr "Alocado"
+
+msgid "Location"
+msgstr "Localização"
+
+msgid "Device path"
+msgstr "Caminho do dispositivo"
+
+msgid "active"
+msgstr "ativo"
+
+msgid "inactive"
+msgstr "inativo"
+
+msgid "Deactivate"
+msgstr "Desativar"
+
+msgid "Activate"
+msgstr "Ativar"
+
+msgid "Add Volume"
+msgstr "Adicionar volume"
+
+msgid "Extend"
+msgstr "Aumentar"
+
+msgid "Undefine"
+msgstr "Indefinir"
+
+msgid "Format"
+msgstr "Formato"
+
+msgid "Allocation"
+msgstr "Alocação"
+
+msgid "Define a New Storage Pool"
+msgstr "Definir novo Storage Pool"
+
+msgid "Storage Pool Name"
+msgstr "Nome do Storage Pool"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "O nome usado para identificar o storage pool e não deve ser vazio."
+
+msgid "Storage Pool Type"
+msgstr "Tipo do Storage Pool"
+
+msgid "Storage Path"
+msgstr "Caminho do storage"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"O caminho do Storage Pool. Cada Storage Pool deve ter um caminho único."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"O Kimchi vai tentar criar o diretório se ainda não existir no seu sistema."
+
+msgid "NFS Server IP"
+msgstr "IP do servidor NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP ou hostname do servidor NFS. Pode ser inserido ou escolhido do histórico."
+
+msgid "NFS Path"
+msgstr "Caminho do NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "O caminho exportado do servidor NFS."
+
+msgid "iSCSI Server"
+msgstr "Servidor iSCSI"
+
+msgid "Server"
+msgstr "Servidor"
+
+msgid "Port"
+msgstr "Porta"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP ou hostname do servidor iSCSI. Não deve ser vazio."
+
+msgid "Target"
+msgstr "Alvo"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "O alvo iSCSI no servidor iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "Adicionar as credenciais do iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Credenciais do iSCSI"
+
+msgid "User Name"
+msgstr "Usuário"
+
+msgid "Password"
+msgstr "Senha"
+
+msgid "SCSI Adapter"
+msgstr "Adaptador SCSI"
+
+msgid "Please, wait..."
+msgstr "Por favor, aguarde..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr "Adicionar um volume ao Storage Pool"
+
+msgid "Fetch from remote URL"
+msgstr "Fazer download de uma URL remota"
+
+msgid "Enter the remote URL here."
+msgstr "Digite a URL remota aqui."
+
+msgid "Upload a file"
+msgstr "Fazer upload de um arquivo"
+
+msgid "Choose the file you want to upload."
+msgstr "Escolha o arquivo que você quer fazer upload."
+
+msgid "Add Template"
+msgstr "Adicionar Modelo"
+
+msgid "Where is the source media for this template? "
+msgstr "Onde está a mÃdia de origem desse modelo? "
+
+msgid "Local ISO Image"
+msgstr "Imagem ISO Local"
+
+msgid "Local Image File"
+msgstr "Arquivo de Imagem Local"
+
+msgid "Remote ISO Image"
+msgstr "Imagem ISO Remota"
+
+msgid "Search ISOs"
+msgstr "Procurar ISOs"
+
+msgid "The following ISOs are available:"
+msgstr "As seguintes ISOs estão disponÃveis:"
+
+msgid "OS: "
+msgstr "Sistema Operacional: "
+
+msgid "Version: "
+msgstr "Versão: "
+
+msgid "Size: "
+msgstr "Tamanho: "
+
+msgid "Search more ISOs"
+msgstr "Procurar por mais ISOs"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Criar Modelos a partir das ISOs selecionadas"
+
+msgid "I want to use a specific ISO file"
+msgstr "Eu quero usar um arquivo ISO especÃfico"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Carregando ISOs remotas ..."
+
+msgid "Arch: "
+msgstr "Arquitetura: "
+
+msgid "I want to use a custom URL"
+msgstr "Eu quero usar uma URL personalizada"
+
+msgid "Edit Template"
+msgstr "Editar Modelo"
+
+msgid "CDROM"
+msgstr "CD-ROM"
+
+msgid "Image File"
+msgstr "Arquivo de imagem"
+
+msgid "Graphics"
+msgstr "Gráficos"
+
+msgid "Disk(GB)"
+msgstr "Disco (GB)"
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "Quantidade de CPUs"
+
+msgid "Manually set CPU topology"
+msgstr "Configurar manualmente a topologia de CPU"
+
+msgid "Cores"
+msgstr "Cores"
+
+msgid "Threads"
+msgstr "Threads"
+
+msgid "No templates found."
+msgstr "Nenhum modelo encontrado."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "Método de remoção não é permitido em %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s não implementa método de atualização"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Método de criação não é permitido em %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "Não é possÃvel realizar a leitura da requisição do JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Essa API suporta apenas JSON"
+
+#~ msgid "Parameters does not match requirement in schema: %(err)s"
+#~ msgstr "Parâmetros não correspondem à especificação do esquema: %(err)s"
+
+#~ msgid "You don't have permission to perform this operation."
+#~ msgstr "Você não tem permissão para executar esta operação."
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Datastore não está inicializado no objeto modelo."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "Não foi possÃvel iniciar a tarefa devido a um erro: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr ""
+#~ "Autenticação falhou para o usuário '%(username)s'. [Código de erro: %"
+#~ "(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Você não está autorizado para acessar o Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Especifique %(item)s para autenticar no Kimchi"
+
+#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
+#~ msgstr "Configurações LDAP inválidas: %(item)s : %(value)s"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "Não foi possÃvel encontrar %(item)s no datastore"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr ""
+#~ "Fim do limite de tempo ao rodar comando '%(cmd)s' após %(seconds)s "
+#~ "segundos"
+
+#~ msgid "Invalid data value '%(value)s'"
+#~ msgstr "Valor inválido '%(value)s'"
+
+#~ msgid "Invalid data unit '%(unit)s'"
+#~ msgstr "Unidade inválida '%(unit)s'"
+
+#~ msgid "Peers"
+#~ msgstr "Peers"
+
+#~ msgid "Searching"
+#~ msgstr "Procurando"
+
+#~ msgid "No peers found."
+#~ msgstr "Nenhum peer encontrado."
+
+#~ msgid "Help"
+#~ msgstr "Ajuda"
+
+#~ msgid "About"
+#~ msgstr "Sobre"
+
+#~ msgid "Log out"
+#~ msgstr "Sair"
+
+#~ msgid "Version:"
+#~ msgstr "Versão:"
+
+#~ msgid "Session timeout, please re-login."
+#~ msgstr ""
+#~ "Fim do limite do tempo da sessão, por favor se autentique novamente."
diff --git a/src/wok/plugins/kimchi/po/ru_RU.po b/src/wok/plugins/kimchi/po/ru_RU.po
new file mode 100644
index 0000000..a5dec2e
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/ru_RU.po
@@ -0,0 +1,2198 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2014-08-28 17:32+0000\n"
+"Last-Translator: Aline Manera <aline.manera at gmail.com>\n"
+"Language-Team: Russian (http://www.transifex.com/projects/p/kimchi/language/"
+"ru/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ru_RU\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "ÐÑибка полÑÑÐµÐ½Ð¸Ñ Ð±Ð»Ð¾ÑнÑÑ
ÑÑÑÑойÑÑв. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "ÐÑибка полÑÑÐµÐ½Ð¸Ñ Ð¸Ð½ÑоÑмаÑии о блоÑнÑÑ
ÑÑÑÑойÑÑваÑ
Ð´Ð»Ñ %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Ðе найден Ñайл ваÑианÑа ÐС: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"ÐÑибка анализа Ñайла ваÑианÑа ÐС %(filename)s. УбедиÑеÑÑ, ÑÑо ÑÑо Ñайл JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð²Ð¾Ð¹Ñи в Ñелевой %(portal)s Ñ
оÑÑа iSCSI. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Ðе ÑдалоÑÑ Ð²Ð¾Ð¹Ñи в Ñелевой %(target)s Ñ
оÑÑа iSCSI %(host)s"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "Файл ISO %(filename)s не загÑÑзоÑнÑй"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"Файл ISO %(filename)s не ÑодеÑÐ¶Ð¸Ñ Ð¿ÑавилÑнÑÑ Ð·Ð°Ð³ÑÑзоÑнÑÑ Ð·Ð°Ð¿Ð¸ÑÑ El Torito"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "ÐедопÑÑÑÐ¸Ð¼Ð°Ñ Ð·Ð°Ð¿Ð¸ÑÑ Ð¿ÑовеÑки El Torito в обÑазе ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ÐедопÑÑÑимÑй индикаÑÐ¾Ñ Ð·Ð°Ð³ÑÑзки El Torito в обÑазе ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "ÐеожиданнÑй Ñип Ñома Ð´Ð»Ñ Ð³Ð»Ð°Ð²Ð½Ð¾Ð³Ð¾ Ñома в обÑазе ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "ÐевеÑнÑй ÑоÑÐ¼Ð°Ñ Ð´ÐµÑкÑипÑоÑа Ñома в обÑазе ISO %(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"У гипеÑвизоÑа Ð½ÐµÑ Ð¿Ñав доÑÑÑпа Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑого обÑаза ISO %(filename)"
+"s. ÐеÑемеÑÑиÑе его в каÑалог /var/lib/libvirt, добавÑÑе ÑазÑеÑение на поиÑк "
+"в ÑпиÑки конÑÑÐ¾Ð»Ñ Ð´Ð¾ÑÑÑпа Ð´Ð»Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ %(user)s, еÑли ÑÑо возможно, "
+"добавÑÑе %(user)s в гÑÑÐ¿Ð¿Ñ Ð¿ÑÑи к обÑÐ°Ð·Ñ ISO или (не ÑекомендÑеÑÑÑ) "
+"вÑполниÑе ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ 'chmod -R o+x 'path_to_iso'. СведениÑ: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "ÐиÑÑÑалÑÐ½Ð°Ñ Ð¼Ð°Ñина %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "ÐиÑÑÑалÑÐ½Ð°Ñ Ð¼Ð°Ñина %(name)s не ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ñнимок ÑкÑана Ð´Ð»Ñ Ð¾ÑÑановленной виÑÑÑалÑной маÑÐ¸Ð½Ñ %"
+"(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "УдаленнÑй обÑаз ISO не поддеÑживаеÑÑÑ ÑÑим ÑеÑвеÑом."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"ÐдÑÐµÑ Ð¿Ñиема запÑоÑов Ð´Ð»Ñ Ð³ÑаÑиÑеÑкой подÑиÑÑÐµÐ¼Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ IPv4 или IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "УкажиÑе Ñаблон Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿ÑÑÑиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð¾ÑÑановиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð¿ÐµÑеименоваÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "ÐÐ¼Ñ ÑеÑи должно бÑÑÑ ÑÑÑокой"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "ÐÐ¼Ñ ÑеÑи должно бÑÑÑ ÑÑÑокой"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "ÐолÑзоваÑÐµÐ»Ñ %(users)s не ÑÑÑеÑÑвÑеÑ."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "ÐолÑзоваÑÐµÐ»Ñ %(groups)s не ÑÑÑеÑÑвÑеÑ."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð¾ÑÑановиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿ÑÑÑиÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑÐ¸Ð½Ñ %(name)s. СведениÑ: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "ÐнÑеÑÑÐµÐ¹Ñ %(iface)s не ÑÑÑеÑÑвÑÐµÑ Ð² виÑÑÑалÑной маÑине %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"СеÑÑ %(network)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ Ð²Ð¸ÑÑÑалÑной маÑÐ¸Ð½Ñ %(name)s, не ÑÑÑеÑÑвÑеÑ"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "ÐоддеÑживаеÑÑÑ ÑолÑко один Ñип инÑеÑÑейÑов виÑÑÑалÑной маÑÐ¸Ð½Ñ - ÑеÑÑ"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "ÐÐ¼Ñ ÑеÑи Ð´Ð»Ñ Ð¸Ð½ÑеÑÑейÑа виÑÑÑалÑной маÑÐ¸Ð½Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ бÑÑÑ ÑÑÑокой"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Указана недопÑÑÑÐ¸Ð¼Ð°Ñ ÐºÐ°ÑÑа модели ÑеÑи Ð´Ð»Ñ Ð¸Ð½ÑеÑÑейÑа виÑÑÑалÑной маÑинÑ"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "УкажиÑе Ñип и ÑеÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ инÑеÑÑейÑа виÑÑÑалÑной маÑинÑ"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Шаблон %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr "СеÑÑ %(network)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ Ñаблона %(template)s, не ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr "ÐÑл памÑÑи %(pool)s, ÑказаннÑй Ð´Ð»Ñ Ñаблона %(template)s, не ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr "ÐÑл памÑÑи %(pool)s, ÑказаннÑй Ð´Ð»Ñ Ñаблона %(template)s, не акÑивен"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Указан недопÑÑÑимÑй паÑамеÑÑ %(param)s Ð´Ð»Ñ CDROM."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "СеÑÑ %(network)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ Ñаблона %(template)s, не акÑивна"
+
+msgid "Template name must be a string"
+msgstr "ÐÐ¼Ñ Ñаблона должно бÑÑÑ ÑÑÑокой"
+
+msgid "Template icon must be a path to the image"
+msgstr "ÐнаÑок Ñаблона должен бÑÑÑ Ð¿ÑÑем к обÑазÑ"
+
+msgid "Template distribution must be a string"
+msgstr "ÐаÑÐ¸Ð°Ð½Ñ Ñаблона должен бÑÑÑ ÑÑÑокой"
+
+msgid "Template distribution version must be a string"
+msgstr "ÐеÑÑÐ¸Ñ Ð²Ð°ÑианÑа Ñаблона должна бÑÑÑ ÑÑÑокой"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "ЧиÑло пÑоÑеÑÑоÑов должно бÑÑÑ ÑелÑм ÑиÑлом"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "ÐбÑем памÑÑи (ÐÐ) должен бÑÑÑ ÑелÑм ÑиÑлом болÑÑе 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "CDROM Ñаблона должен бÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑм или ÑдаленнÑм Ñайлом ISO"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "ÐÐ»Ñ Ñаблона Ñказан недопÑÑÑимÑй URI пÑла памÑÑи %(value)s"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "УкажиÑе обÑаз ISO в каÑеÑÑве CDROM Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñаблона"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "ÐÑе ÑеÑи Ð´Ð»Ñ Ñаблона Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÐºÐ°Ð·Ð°Ð½Ñ Ð² ÑпиÑке."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ñаблон из-за оÑибки %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñаблон из-за оÑибки %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "CDROM Ñаблона должен бÑÑÑ Ð»Ð¾ÐºÐ°Ð»ÑнÑм или ÑдаленнÑм Ñайлом ISO"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "ÐÑл памÑÑи %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "ÐÑл памÑÑи %(name)s не ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "УкажиÑе %(item)s Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñла памÑÑи %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð°ÐºÑивнÑй пÑл памÑÑи %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок пÑлов памÑÑи. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÑиÑло Ñомов в пÑле памÑÑи %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð´ÐµÐ°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð¿Ñл памÑÑи %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¿Ñл NFS: ÑкÑпоÑÑиÑованнÑй пÑÑÑ %(path)s мог бÑÑÑ "
+"заблокиÑован во вÑÐµÐ¼Ñ Ð¼Ð¾Ð½ÑиÑованиÑ"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¿Ñл NFS: не ÑдалоÑÑ ÑмонÑиÑоваÑÑ ÑкÑпоÑÑиÑованнÑй пÑÑÑ %"
+"(path)s"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "ÐеподдеÑживаемÑй Ñип пÑла памÑÑи: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи должен бÑÑÑ ÑÑÑокой"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "ХоÑÑ Ð¿Ñла памÑÑи должен бÑÑÑ IP-адÑеÑом или именем Ñ
оÑÑа"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "ÐаÑамеÑÑ ÑÑÑÑойÑÑв пÑла памÑÑи должен бÑÑÑ ÑпиÑком"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "Целевой IQN пÑла iSCSI должен бÑÑÑ ÑÑÑокой"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "ÐоÑÑ Ñдаленного ÑеÑвеÑа памÑÑи должен бÑÑÑ ÑелÑм ÑиÑлом Ð¾Ñ 1 до 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "УкажиÑе Ð¸Ð¼Ñ Ð¸ Ñип Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñла памÑÑи"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s не ÑвлÑеÑÑÑ Ð´Ð¾Ð¿ÑÑÑимÑм диÑком/Ñазделом. Ðе ÑдалоÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ ÐµÐ³Ð¾ в "
+"пÑл %(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "ÐиÑки паÑамеÑÑов можно обновлÑÑÑ ÑолÑко Ð´Ð»Ñ Ð»Ð¾Ð³Ð¸ÑеÑкого пÑла памÑÑи."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "ÐÐ¼Ñ Ð°Ð´Ð°Ð¿ÑеÑа Ñ
оÑÑа SCSI должно бÑÑÑ ÑÑÑокой."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "kimchi_isos пÑла памÑÑи заÑезеÑвиÑован Ð´Ð»Ñ Ð²Ð½ÑÑÑеннего иÑполÑзованиÑ"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Ðе ÑдалоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи NFS %(name)s. СеÑÐ²ÐµÑ NFS %(server)s "
+"недоÑÑÑпен."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Ðе ÑдалоÑÑ Ð´ÐµÐ°ÐºÑивиÑоваÑÑ Ð¿Ñл памÑÑи NFS %(name)s. СеÑÐ²ÐµÑ NFS %(server)s "
+"недоÑÑÑпен."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð´ÐµÐ°ÐºÑивиÑоваÑÑ Ð¿Ñл %(name)s: пÑл ÑвÑзан Ñ Ð½ÐµÐºÐ¾ÑоÑÑми Ñаблонами"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð¿Ñл %(name)s: пÑл ÑвÑзан Ñ Ð½ÐµÐºÐ¾ÑоÑÑми Ñаблонами"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr ""
+"ÐÑÑппа Ñомов Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ %(name)s Ñже ÑÑÑеÑÑвÑеÑ. ÐÑбеÑиÑе дÑÑгое Ð¸Ð¼Ñ Ð´Ð»Ñ "
+"ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð»Ð¾Ð³Ð¸ÑеÑкого пÑла."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
Ñ Ð¸Ð½ÑоÑмаÑией глÑбокого ÑканиÑÐ¾Ð²Ð°Ð½Ð¸Ñ Ð¸Ð·-за "
+"оÑибки %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Том %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "Том %(name)s не ÑÑÑеÑÑвÑÐµÑ Ð² пÑле памÑÑи %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "УкажиÑе %(item)s Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñома %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr "Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок Ñомов: пÑл памÑÑи %(pool)s не акÑивен"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr ""
+"Ðе ÑдалоÑÑ ÑоздаÑÑ Ñом %(name)s в пÑле памÑÑи %(pool)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок Ñомов в пÑле памÑÑи %(pool)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑÑеÑеÑÑ Ñома %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñом %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ñома %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "Тип памÑÑи %(type)s не поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ñоздание и Ñдаление Ñомов"
+
+msgid "Storage volume name must be a string"
+msgstr "ÐÐ¼Ñ Ñома должно бÑÑÑ ÑÑÑокой"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "ÐÑделение Ñома должно бÑÑÑ ÑелÑм ÑиÑлом"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "Ð¢Ð¾Ð¼Ñ ÑÑебÑеÑÑÑ Ð¸Ð¼Ñ"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ
Ñ Ð¸Ð½ÑоÑмаÑией о ÑомаÑ
из-за оÑибки %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "ÐнÑеÑÑÐµÐ¹Ñ %(name)s не ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "СеÑÑ %(name)s Ñже ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "СеÑÑ %(name)s не ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr "ÐодÑеÑÑ %(subnet)s, ÑÐºÐ°Ð·Ð°Ð½Ð½Ð°Ñ Ð´Ð»Ñ ÑеÑи %(network)s, недопÑÑÑима."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"УкажиÑе ÑеÑевой инÑеÑÑÐµÐ¹Ñ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑеÑи %(name)s Ñ Ð´Ð¾ÑÑÑпом ÑеÑез моÑÑ"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ð°ÐºÑивнÑÑ ÑеÑÑ %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr "ÐнÑеÑÑÐµÐ¹Ñ %(iface)s, ÑказаннÑй Ð´Ð»Ñ ÑеÑи %(network)s, Ñже иÑполÑзÑеÑÑÑ"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+"ÐнÑеÑÑÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ ÑеÑевой каÑÑой, ÑÑÑÑойÑÑвом моÑÑа или ÑвÑзÑÑÑим "
+"ÑÑÑÑойÑÑвом."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ ÑеÑÑ %(name)s. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Ðе найден ÑвободнÑй IP-адÑÐµÑ Ð´Ð»Ñ ÑеÑи %(name)s"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "ÐоддеÑживаемÑе ÑÐ¸Ð¿Ñ ÑеÑей: isolated, NAT и bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"ÐодÑеÑÑ ÑеÑи должна бÑÑÑ ÑÑÑокой, ÑодеÑжаÑей IP-адÑеÑ, пÑеÑÐ¸ÐºÑ Ð¸Ð»Ð¸ маÑÐºÑ ÑеÑи"
+
+msgid "Network interface must be a string"
+msgstr "СеÑевой инÑеÑÑÐµÐ¹Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ бÑÑÑ ÑÑÑокой"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "СеÑевой ÐÐ VLAN должен бÑÑÑ ÑелÑм ÑиÑлом Ð¾Ñ 1 до 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "УкажиÑе Ð¸Ð¼Ñ Ð¸ Ñип Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑеÑи"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"УÑÑÑойÑÑво моÑÑа %(name)s не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¼Ð°Ð³Ð¸ÑÑÑалÑнÑм ÑÑÑÑойÑÑвом VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "Ðе ÑдалоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"Ðе далоÑÑ Ð°ÐºÑивиÑоваÑÑ Ð¸Ð½ÑеÑÑÐµÐ¹Ñ %(iface)s. ÐÑовеÑÑÑе ÑоÑÑоÑние ÑизиÑеÑкой "
+"линии ÑвÑзи. "
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "ÐÑладоÑнÑй оÑÑÐµÑ %(name)s не ÑÑÑеÑÑвÑеÑ"
+
+msgid "Debug report tool not found in system"
+msgstr "ÐнÑÑÑÑÐ¼ÐµÐ½Ñ Ð¾ÑладоÑного оÑÑеÑа не найден в ÑиÑÑеме"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¾ÑладоÑнÑй оÑÑÐµÑ %(name)s. СведениÑ: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "Ðе ÑдалоÑÑ ÑоздаÑÑ Ð¾ÑладоÑнÑй оÑÑÐµÑ %(name)s. СведениÑ: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr ""
+"ÐÑÑппа Ñомов Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ %(name)s Ñже ÑÑÑеÑÑвÑеÑ. ÐÑбеÑиÑе дÑÑгое Ð¸Ð¼Ñ Ð´Ð»Ñ "
+"ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð»Ð¾Ð³Ð¸ÑеÑкого пÑла."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "СеÑÐ²ÐµÑ Ð¿Ð°Ð¼ÑÑи %(server)s не иÑполÑзовалÑÑ Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "ÐаÑÐ¸Ð°Ð½Ñ ÐС %(name)s не ÑÑÑеÑÑвÑеÑ"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "Раздел %(name)s не ÑÑÑеÑÑвÑÐµÑ Ð½Ð° Ñ
оÑÑе"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Ðе ÑдалоÑÑ Ð·Ð°Ð²ÐµÑÑиÑÑ ÑабоÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа: вÑполнÑÑÑÑÑ Ð²Ð¸ÑÑÑалÑнÑе маÑинÑ"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "Ðе ÑдалоÑÑ Ð¿ÐµÑезагÑÑзиÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа: вÑполнÑÑÑÑÑ Ð²Ð¸ÑÑÑалÑнÑе маÑинÑ"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "УÑÑÑойÑÑво %(name)s Ñзла не найдено"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "ÐÐµÑ Ð¿Ð°ÐºÐµÑов, помеÑеннÑÑ
Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "ÐÐ°ÐºÐµÑ %(name)s не помеÑен Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr "ÐÑибка полÑÑÐµÐ½Ð¸Ñ Ð¿Ð°ÐºÐµÑов, помеÑеннÑÑ
Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ. СведениÑ: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "ÐÐµÑ ÑовмеÑÑимого админиÑÑÑаÑоÑа пакеÑов Ð´Ð»Ñ ÑÑой ÑиÑÑемÑ."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "ÐедопÑÑÑимÑй URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "ÐедопÑÑÑимÑй Ñип памÑÑи. ÐоддеÑживаемÑе ÑипÑ: cdrom"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "ÐÑибка ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑанениÑ: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "ÐÑибка Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑанениÑ: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "ÐÑибка ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑанениÑ: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "УкажиÑе Ñип и пÑÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ диÑка виÑÑÑалÑной маÑинÑ"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "УкажиÑе пÑÑÑ Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð´Ð¸Ñка виÑÑÑалÑной маÑинÑ"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "УкажиÑе Ñип и пÑÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ диÑка виÑÑÑалÑной маÑинÑ"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+"ÐÐ Ñ
ÑанилиÑа YUM должен бÑÑÑ ÑÑÑокой, ÑоÑÑоÑÑей ÑолÑко из одного Ñлова."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "URL Ñ
ÑанилиÑа должен бÑÑÑ http://, ftp:// или file:// ."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"ÐонÑигÑÑаÑÐ¸Ñ Ñ
ÑанилиÑа пÑедÑÑавлÑÐµÑ Ñобой ÑловаÑÑ Ð·Ð½Ð°Ñений, опÑеделÑемÑÑ
"
+"Ñипом Ñ
ÑанилиÑа."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "ÐаÑÐ¸Ð°Ð½Ñ Ð´Ð»Ñ Ñ
ÑанилиÑа DEB должен бÑÑÑ ÑÑÑокой"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "ÐомпоненÑÑ Ð´Ð»Ñ Ñ
ÑанилиÑа DEB Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÐµÑеÑиÑÐ»ÐµÐ½Ñ Ð² маÑÑиве"
+
+msgid "Components to DEB repository must be a string"
+msgstr "ÐомпоненÑÑ Ð´Ð»Ñ Ñ
ÑанилиÑа DEB Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÑÑокой"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "ÐÐ¼Ñ Ñ
ÑанилиÑа YUM должно бÑÑÑ ÑÑÑокой."
+
+msgid "GPG check must be a boolean value."
+msgstr "ÐÑовеÑка GPG должна бÑÑÑ Ð±ÑлевÑким знаÑением."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+"ÐлÑÑ GPG должен бÑÑÑ URL, ÑказÑваÑÑим на заÑиÑеннÑй Ñайл Ñ ÐºÐ¾Ð´Ð¸Ñованием "
+"ASCII."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ñ
ÑанилиÑе %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Ð¥ÑанилиÑе %(repo_id)s не ÑÑÑеÑÑвÑеÑ."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "Ðе ÑаÑпознан инÑÑÑÑÐ¼ÐµÐ½Ñ ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ñ
ÑанилиÑем Ð´Ð»Ñ ÑиÑÑемÑ."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Ð¥ÑанилиÑе %(repo_id)s Ñже вклÑÑено."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Ð¥ÑанилиÑе %(repo_id)s Ñже вÑклÑÑено."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñ
ÑанилиÑе %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿Ð¸ÑаÑÑ Ð² Ñайл конÑигÑÑаÑии Ñ
ÑанилиÑа %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "УкажиÑе ваÑÐ¸Ð°Ð½Ñ Ñ
ÑанилиÑа Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñ
ÑанилиÑа DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Ðе ÑдалоÑÑ Ð²ÐºÐ»ÑÑиÑÑ Ñ
ÑанилиÑе %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Ðе ÑдалоÑÑ Ð²ÑклÑÑиÑÑ Ñ
ÑанилиÑе %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "ÐÐ Ñ
ÑанилиÑа YUM Ñже ÑÑÑеÑÑвÑеÑ"
+
+msgid "YUM Repository name must be a string"
+msgstr "ÐÐ¼Ñ Ñ
ÑанилиÑа YUM должно бÑÑÑ ÑÑÑокой"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Ðе ÑдалоÑÑ Ð²ÑвеÑÑи ÑпиÑок Ñ
ÑанилиÑ. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Ðе ÑдалоÑÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Ðе ÑдалоÑÑ ÑдалиÑÑ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "Ðод оÑибки"
+
+msgid "REASON"
+msgstr "ÐÐ ÐЧÐÐÐ"
+
+msgid "STACK"
+msgstr "СÑек"
+
+msgid "Go to Homepage"
+msgstr "ÐеÑейÑи на главнÑÑ ÑÑÑаниÑÑ"
+
+msgid "Create a New Virtual Machine"
+msgstr "СоздаÑÑ Ð½Ð¾Ð²ÑÑ Ð²Ð¸ÑÑÑалÑнÑÑ Ð¼Ð°ÑинÑ"
+
+msgid "Virtual Machine Name"
+msgstr "ÐÐ¼Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии виÑÑÑалÑной маÑинÑ. ÐÑли не Ñказано, Ð¸Ð¼Ñ Ð±ÑÐ´ÐµÑ Ð²ÑбÑано "
+"в завиÑимоÑÑи Ð¾Ñ Ð¸ÑполÑзÑемого Ñаблона."
+
+msgid "Template"
+msgstr "Шаблон"
+
+msgid "Please create a template first."
+msgstr "ÐожалÑйÑÑа, ÑоздайÑе Ñаблон в пеÑвÑÑ Ð¾ÑеÑедÑ."
+
+msgid "Create a Template"
+msgstr "СоздаÑÑ Ñаблон"
+
+msgid "Please choose a template."
+msgstr "ÐожалÑйÑÑа, вÑбеÑиÑе Ñаблон."
+
+msgid "OS"
+msgstr "ÐС"
+
+msgid "OS Version"
+msgstr "ÐеÑÑÐ¸Ñ ÐС"
+
+msgid "CPUS"
+msgstr "ÐÑоÑеÑÑоÑÑ"
+
+msgid "Memory"
+msgstr "ÐамÑÑÑ"
+
+msgid "Create"
+msgstr "СоздаÑÑ"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "ÐÑмена"
+
+msgid "Edit Guest"
+msgstr "ÐзмениÑÑ Ð³Ð¾ÑÑевÑÑ ÑиÑÑемÑ"
+
+msgid "General"
+msgstr "ÐбÑее"
+
+msgid "Storage"
+msgstr "Ð¥ÑанилиÑе"
+
+msgid "Interface"
+msgstr "ÐнÑеÑÑейÑ"
+
+msgid "Permission"
+msgstr "ÐеÑÑиÑ"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "ÐмÑ"
+
+msgid "CPUs"
+msgstr "ÐÑоÑеÑÑоÑÑ"
+
+msgid "Memory (MB)"
+msgstr "ÐамÑÑÑ (Ðб)"
+
+msgid "Icon"
+msgstr "ÐнаÑок"
+
+msgid "Device"
+msgstr "ÐÐ¼Ñ ÑÑÑÑойÑÑва"
+
+msgid "Path"
+msgstr "ÐÑÑÑ NFS"
+
+msgid "Network"
+msgstr "СеÑÑ"
+
+msgid "Type"
+msgstr "Тип"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "ÐÑе"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "ÐендоÑ"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "СоÑ
ÑаниÑÑ"
+
+msgid "Replace"
+msgstr "ÐамениÑÑ"
+
+msgid "Detach"
+msgstr "ÐÑклÑÑиÑÑ"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "ÐапÑÑÑиÑÑ"
+
+msgid "Reset"
+msgstr "СбÑоÑиÑÑ"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "ÐÑклÑÑиÑÑ"
+
+msgid "Actions"
+msgstr "ÐейÑÑвиÑ"
+
+msgid "Connect"
+msgstr "ÐодклÑÑиÑÑ"
+
+msgid "Clone"
+msgstr "ÐлониÑоваÑÑ"
+
+msgid "Edit"
+msgstr "РедакÑиÑоваÑÑ"
+
+msgid "Shut Down"
+msgstr "ÐавеÑÑиÑÑ ÑабоÑÑ"
+
+msgid "Delete"
+msgstr "УдалиÑÑ"
+
+msgid "CPU"
+msgstr "ÐÑоÑеÑÑоÑ"
+
+msgid "Disk I/O"
+msgstr "ÐиÑковÑй ввод-вÑвод"
+
+msgid "Network I/O"
+msgstr "СеÑевой ввод-вÑвод"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð³Ð¾ÑÑевÑе ÑиÑÑемÑ."
+
+msgid "Add a Storage Device to VM"
+msgstr "ÐобавиÑÑ ÑÑÑÑойÑÑво Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð² VM"
+
+msgid "Device Type"
+msgstr "Тип ÑÑÑÑойÑÑва"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "Тип ÑÑÑÑойÑÑва. РданнÑй Ð¼Ð¾Ð¼ÐµÐ½Ñ Ð¿Ð¾Ð´Ð´ÐµÑживаеÑÑÑ ÑолÑко \"cdrom\"."
+
+msgid "Storage Pool"
+msgstr "ÐÑл памÑÑи"
+
+msgid "Storage pool which volume located in"
+msgstr "ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи должен бÑÑÑ ÑÑÑокой"
+
+msgid "Storage Volume"
+msgstr "ÐÐ¼Ñ Ð¿Ñла памÑÑи"
+
+msgid "Storage volume to be attached"
+msgstr "ÐÐ¼Ñ Ñома должно бÑÑÑ ÑÑÑокой"
+
+msgid "File Path"
+msgstr "ÐÑÑÑ Ðº ÑайлÑ"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "ÐÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO Ð´Ð»Ñ CDROM на ÑеÑвеÑе."
+
+msgid "Attach"
+msgstr "ÐодклÑÑиÑÑ"
+
+msgid "Shut down"
+msgstr "ÐÑклÑÑен"
+
+msgid "Restart"
+msgstr "ÐеÑезапÑÑк"
+
+msgid "Basic Information"
+msgstr "ÐÐ°Ð·Ð¾Ð²Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ"
+
+msgid "OS Distro"
+msgstr "ÐаÑÐ¸Ð°Ð½Ñ ÐС"
+
+msgid "OS Code Name"
+msgstr "Ðодовое Ð¸Ð¼Ñ ÐС"
+
+msgid "Processor"
+msgstr "ÐÑоÑеÑÑоÑ"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "СиÑÑÐµÐ¼Ð½Ð°Ñ ÑÑаÑиÑÑика"
+
+msgid "Software Updates"
+msgstr "ÐÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑогÑаммного обеÑпеÑениÑ"
+
+msgid "Update Progress"
+msgstr "Ход обновлениÑ"
+
+msgid "Repositories"
+msgstr "Ð¥ÑанилиÑа"
+
+msgid "Debug Reports"
+msgstr "ÐÑладоÑнÑе оÑÑеÑÑ"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr "Указано невеÑное Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¸Ð»Ð¸ паÑолÑ. ÐведиÑе еÑе Ñаз."
+
+msgid "This field is required."
+msgstr "ÐÑо обÑзаÑелÑное поле."
+
+msgid "Log in"
+msgstr "ÐойÑи"
+
+msgid "Logging in..."
+msgstr "ÐÑ
од..."
+
+msgid "Host"
+msgstr "ХоÑÑ"
+
+msgid "Guests"
+msgstr "ÐоÑÑевÑе ÑиÑÑемÑ"
+
+msgid "Templates"
+msgstr "ШаблонÑ"
+
+msgid "Failed to get application configuration"
+msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÐºÐ¾Ð½ÑигÑÑаÑÐ¸Ñ Ð¿ÑиложениÑ"
+
+msgid "This is not a valid Linux path"
+msgstr "ÐÑÐ¾Ñ Ð½ÐµÐ´Ð¾Ð¿ÑÑÑимÑй пÑÑÑ Ð² Linux"
+
+msgid "This is not a valid URL."
+msgstr "ÐÑо недопÑÑÑимÑй URL."
+
+msgid "No such data available."
+msgstr "ÐÐµÑ ÑакиÑ
даннÑÑ
."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"ÐÐµÑ ÑвÑзи Ñ ÑиÑÑемой Ñ
оÑÑа. УбедиÑеÑÑ, ÑÑо ÑиÑÑема Ñ
оÑÑа ÑабоÑÐ°ÐµÑ Ð¸ доÑÑÑпна "
+"Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑениÑ. ÐÑÐ²ÐµÑ Ð½Ð° запÑÐ¾Ñ HTTP: %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "ÐодÑвеÑждение ÑдалениÑ"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "ÐодÑвеÑдиÑÑ"
+
+msgid "Warning"
+msgstr "ÐÑедÑпÑеждение"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "ÐагÑÑжаеÑÑÑ..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "ÐовÑоÑиÑÑ"
+
+msgid "Detailed message:"
+msgstr "ÐодÑобное ÑообÑение:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "ÐÑÐ¾Ñ Ñайл не ÑвлÑеÑÑÑ Ð´Ð¾Ð¿ÑÑÑимÑм обÑазом ISO."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "ÐÑо Ð·Ð°Ð¹Ð¼ÐµÑ Ð¼Ð½Ð¾Ð³Ð¾ вÑемени. ÐÑодолжиÑÑ?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "Шаблон бÑÐ´ÐµÑ Ð±ÐµÐ·Ð²Ð¾Ð·Ð²ÑаÑно Ñдален. ÐÑодолжиÑÑ?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"Ðевозможно завеÑÑиÑÑ ÑабоÑÑ ÑиÑÑемÑ, поÑколÑÐºÑ Ð² ней ÑабоÑаÑÑ Ð²Ð¸ÑÑÑалÑнÑе "
+"маÑинÑ!"
+
+msgid "Max:"
+msgstr "ÐакÑ.:"
+
+msgid "Utilization"
+msgstr "ÐÑполÑзование"
+
+msgid "Available"
+msgstr "ÐоÑÑÑпно"
+
+msgid "Read Rate"
+msgstr "СкоÑоÑÑÑ ÑÑениÑ"
+
+msgid "Write Rate"
+msgstr "СкоÑоÑÑÑ Ð·Ð°Ð¿Ð¸Ñи"
+
+msgid "Received"
+msgstr "ÐолÑÑено"
+
+msgid "Sent"
+msgstr "ÐÑпÑавлено"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"ÐавеÑÑение ÑабоÑÑ Ð¸ пеÑезапÑÑк Ñ
оÑÑа пÑиведÑÑ Ðº поÑеÑе неÑоÑ
Ñаненной ÑабоÑÑ. "
+"ÐÑодолжиÑÑ Ð·Ð°Ð²ÐµÑÑение ÑабоÑÑ/пеÑезапÑÑк?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr "Ð¥ÑанилиÑе бÑÐ´ÐµÑ Ñдалено без возможноÑÑи воÑÑÑановлениÑ. ÐÑодолжиÑÑ?"
+
+msgid "ID"
+msgstr "ÐÐ"
+
+msgid "Base URL"
+msgstr "ÐазовÑй URL"
+
+msgid "Is Mirror"
+msgstr "ÐеÑкалÑÐ½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ"
+
+msgid "URL Args"
+msgstr "ÐÑгÑменÑÑ URL"
+
+msgid "Enabled"
+msgstr "ÐклÑÑено"
+
+msgid "GPG Check"
+msgstr "ÐÑовеÑка GPG"
+
+msgid "GPG Key"
+msgstr "ÐлÑÑ GPG"
+
+msgid "Add"
+msgstr "ÐобавиÑÑ"
+
+msgid "Remove"
+msgstr "УдалиÑÑ"
+
+msgid "Enable"
+msgstr "ÐклÑÑиÑÑ"
+
+msgid "Disable"
+msgstr "ÐÑклÑÑиÑÑ"
+
+msgid "Package Name"
+msgstr "ÐÐ¼Ñ Ð¿Ð°ÐºÐµÑа"
+
+msgid "Version"
+msgstr "ÐеÑÑиÑ"
+
+msgid "Architecture"
+msgstr "ÐÑÑ
иÑекÑÑÑа"
+
+msgid "Repository"
+msgstr "Ð¥ÑанилиÑе"
+
+msgid "Update All"
+msgstr "ÐбновиÑÑ Ð²ÑÑ"
+
+msgid "Updating..."
+msgstr "Ðбновление..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "Ðе ÑдалоÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð¸ÑÑ Ð¿Ð°ÐºÐµÑÑ."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr ""
+"ÐÑладоÑнÑй оÑÑÐµÑ Ð±ÑÐ´ÐµÑ Ñдален без возможноÑÑи воÑÑÑановлениÑ. ÐÑодолжиÑÑ?"
+
+msgid "Generated Time"
+msgstr "ÐÑÐµÐ¼Ñ ÑозданиÑ"
+
+msgid "Generate"
+msgstr "СоздаÑÑ"
+
+msgid "Generating..."
+msgstr "Создание..."
+
+msgid "Rename"
+msgstr "ÐеÑеименоваÑÑ"
+
+msgid "Download"
+msgstr "ÐагÑÑзиÑÑ"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr "ÐÐ¼Ñ Ð¾ÑÑеÑа должно ÑодеÑжаÑÑ ÑолÑко бÑквÑ, ÑиÑÑÑ Ð¸ деÑиÑÑ ('-')."
+
+msgid "Pending..."
+msgstr "ÐагÑÑжаеÑÑÑ..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"ÐÑÐ´ÐµÑ Ñдалена виÑÑÑалÑÐ½Ð°Ñ Ð¼Ð°Ñина вмеÑÑе Ñо Ñвоими виÑÑÑалÑнÑми диÑками. ÐÑо "
+"необÑаÑÐ¸Ð¼Ð°Ñ Ð¾Ð¿ÐµÑаÑиÑ. ÐÑодолжиÑÑ?"
+
+msgid "Power off Confirmation"
+msgstr "ÐодÑвеÑждение ÑдалениÑ"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "ÐодÑвеÑждение ÑдалениÑ"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "ÐодÑвеÑждение ÑдалениÑ"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "Шаблон бÑÐ´ÐµÑ Ð±ÐµÐ·Ð²Ð¾Ð·Ð²ÑаÑно Ñдален. ÐÑодолжиÑÑ?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"ÐÑÐ¾Ñ CDROM бÑÐ´ÐµÑ Ð¾ÑклÑÑен. Ðго можно бÑÐ´ÐµÑ Ñнова подклÑÑиÑÑ. ÐÑклÑÑиÑÑ?"
+
+msgid "Attaching..."
+msgstr "ÐодклÑÑение..."
+
+msgid "Replacing..."
+msgstr "Ðамена..."
+
+msgid "Successfully attached!"
+msgstr "УÑпеÑно подклÑÑен!"
+
+msgid "Successfully replaced!"
+msgstr "УÑпеÑно заменен!"
+
+msgid "Successfully detached!"
+msgstr "УÑпеÑно оÑклÑÑен!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "ÐÐ VLAN должен бÑÑÑ Ð¾Ñ 1 до 4094."
+
+msgid "unavailable"
+msgstr "недоÑÑÑпно"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr ""
+"ÐÑо дейÑÑвие наÑÑÑÐ¸Ñ ÑеÑевÑе ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ñ Ð²ÑеÑ
виÑÑÑалÑнÑÑ
маÑин, коÑоÑÑе "
+"завиÑÑÑ Ð¾Ñ ÑÑой ÑеÑи."
+
+msgid "Create a network"
+msgstr "СоздаÑÑ ÑеÑÑ"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"ÐÑÐ¾Ñ Ð¿Ñл памÑÑи не поÑÑоÑннÑй. ÐмеÑÑо деакÑиваÑии, ÑÑо дейÑÑвие безвозвÑаÑно "
+"его ÑдалиÑ. ÐÑодолжиÑÑ?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "ÐÑл памÑÑи бÑÐ´ÐµÑ Ð±ÐµÐ·Ð²Ð¾Ð·Ð²ÑаÑно Ñдален. ÐÑодолжиÑÑ?"
+
+msgid "This storage pool is empty."
+msgstr "ÐÑÐ¾Ñ Ð¿Ñл памÑÑи пÑÑÑой."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"ÐиÑк бÑÐ´ÐµÑ Ð¾ÑÑоÑмаÑиÑован, и вÑе даннÑе на нем бÑдÑÑ Ð¿Ð¾ÑеÑÑнÑ. ÐÑ "
+"дейÑÑвиÑелÑно Ñ
оÑиÑе пÑодолжиÑÑ? "
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI Fibre Channel"
+
+msgid "No SCSI adapters found."
+msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð°Ð´Ð°Ð¿ÑеÑÑ SCSI."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "Ðе Ñказано Ð¸Ð¼Ñ Ð¿Ñла памÑÑи."
+
+msgid "The storage pool path can not be blank."
+msgstr "Ðе Ñказан пÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи."
+
+msgid "NFS server mount path can not be blank."
+msgstr "Ðе Ñказан пÑÑÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ ÑеÑвеÑа NFS."
+
+msgid "Invalid NFS mount path."
+msgstr "ÐедопÑÑÑимÑй пÑÑÑ Ð¼Ð¾Ð½ÑиÑÐ¾Ð²Ð°Ð½Ð¸Ñ NFS."
+
+msgid "No logical device selected."
+msgstr "Ðе вÑбÑано логиÑеÑкое ÑÑÑÑойÑÑво."
+
+msgid "The iSCSI target can not be blank."
+msgstr "Ðе Ñказан Ñелевой обÑÐµÐºÑ iSCSI."
+
+msgid "Server name can not be blank."
+msgstr "Ðе Ñказано Ð¸Ð¼Ñ ÑеÑвеÑа."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "ÐоиÑк доÑÑÑпнÑÑ
Ñазделов..."
+
+msgid "No available partitions found."
+msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ Ð´Ð¾ÑÑÑпнÑе ÑазделÑ."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"ÐÑÐ¾Ñ Ð¿Ñл памÑÑи не поÑÑоÑннÑй. ÐмеÑÑо деакÑиваÑии, ÑÑо дейÑÑвие безвозвÑаÑно "
+"его ÑдалиÑ. ÐÑодолжиÑÑ?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "Ðе ÑдалоÑÑ Ð¿Ð¾Ð»ÑÑиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñ
ÑанилиÑе. СведениÑ: %(err)s"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Ðе Ñказано Ð¸Ð¼Ñ Ð¿Ñла памÑÑи."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "ÐÐ¼Ñ ÑеÑи"
+
+msgid "State"
+msgstr "СоÑÑоÑние"
+
+msgid "Network Type"
+msgstr "Тип ÑеÑи"
+
+msgid "Address Space"
+msgstr "ÐдÑеÑное пÑоÑÑÑанÑÑво"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "ÐедопÑÑÑимое Ð¸Ð¼Ñ Ð¿Ñла памÑÑи. Римени не должно бÑÑÑ Ñимволов '/'."
+
+msgid "Isolated: no external network connection"
+msgstr "ÐзолиÑованнÑй (без ÑизиÑеÑкиÑ
ÑеÑевÑÑ
Ñоединений)"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT (ÑолÑко иÑÑ
одÑÑее ÑизиÑеÑкое ÑеÑевое Ñоединение)"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "ЧеÑез моÑÑ (пÑÑмое подклÑÑение виÑÑÑалÑнÑÑ
маÑин к ÑизиÑеÑкой ÑеÑи)"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "Целевое ÑаÑположение:"
+
+msgid "Enable VLAN"
+msgstr "ÐклÑÑиÑÑ VLAN:"
+
+msgid "VLAN ID"
+msgstr ""
+
+msgid "Stop"
+msgstr "ÐавеÑÑиÑÑ"
+
+msgid "Generate a New Debug Report"
+msgstr "СоздаÑÑ Ð½Ð¾Ð²Ñй оÑладоÑнÑй оÑÑеÑ"
+
+msgid "Report Name"
+msgstr "ÐÐ¼Ñ Ð¾ÑÑеÑа"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии оÑÑеÑа. ÐÑли не Ñказано, Ð¸Ð¼Ñ Ð±ÑÐ´ÐµÑ ÑÑоÑмиÑовано на "
+"оÑнове ÑекÑÑего вÑемени. ÐÐ¼Ñ Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ: бÑквÑ, ÑиÑÑÑ Ð¸ деÑиÑÑ (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "СоздаÑÑ Ð½Ð¾Ð²Ñй оÑладоÑнÑй оÑÑеÑ"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии оÑÑеÑа. ÐÑли не Ñказано, Ð¸Ð¼Ñ Ð±ÑÐ´ÐµÑ ÑÑоÑмиÑовано на "
+"оÑнове ÑекÑÑего вÑемени. ÐÐ¼Ñ Ð¼Ð¾Ð¶ÐµÑ ÑодеÑжаÑÑ: бÑквÑ, ÑиÑÑÑ Ð¸ деÑиÑÑ (\"-\")."
+
+msgid "Submit"
+msgstr "ÐодÑвеÑдиÑÑ"
+
+msgid "Add a Repository"
+msgstr "ÐобавиÑÑ Ñ
ÑанилиÑе"
+
+msgid "Identifier"
+msgstr "ÐденÑиÑикаÑоÑ"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "ÐдиноÑное Ñлово - ÑникалÑнÑй иденÑиÑикаÑÐ¾Ñ Ñ
ÑанилиÑа."
+
+msgid "Textual name for the repository."
+msgstr "ТекÑÑовое Ð¸Ð¼Ñ Ñ
ÑанилиÑа."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "ÐбÑзаÑелÑное поле"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL Ñ
ÑанилиÑа. ÐоддеÑживаемÑе пÑоÑоколÑ: http, ftp, file."
+
+msgid "Repository is a mirror"
+msgstr "Ð¥ÑанилиÑе ÑвлÑеÑÑÑ Ð·ÐµÑкалÑной копией."
+
+msgid "Distribution"
+msgstr "ÐаÑианÑ"
+
+msgid "Distribution of the DEB repository."
+msgstr "ÐаÑÐ¸Ð°Ð½Ñ Ñ
ÑанилиÑа DEB."
+
+msgid "Components"
+msgstr "ÐомпоненÑÑ"
+
+msgid "List of components in DEB repository."
+msgstr "СпиÑок компоненÑов в Ñ
ÑанилиÑе DEB."
+
+msgid "Edit Repository"
+msgstr "ÐзмениÑÑ Ñ
ÑанилиÑе"
+
+msgid "Mirror List URL"
+msgstr "URL ÑпиÑка зеÑкалÑнÑÑ
копий"
+
+msgid "Yes"
+msgstr "Ðа"
+
+msgid "No"
+msgstr "ÐеÑ"
+
+msgid "Capacity"
+msgstr "ÐмкоÑÑÑ"
+
+msgid "Allocated"
+msgstr "ÐÑделено"
+
+msgid "Location"
+msgstr "РаÑположение"
+
+msgid "Device path"
+msgstr "ÐÑÑÑ Ðº ÑÑÑÑойÑÑвÑ"
+
+msgid "active"
+msgstr "акÑивен"
+
+msgid "inactive"
+msgstr "неакÑивен"
+
+msgid "Deactivate"
+msgstr "ÐÑклÑÑиÑÑ"
+
+msgid "Activate"
+msgstr "ÐкÑивиÑоваÑÑ"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "УдалиÑÑ"
+
+msgid "Format"
+msgstr "ФоÑмаÑ:"
+
+msgid "Allocation"
+msgstr "ÐÑделение ÑеÑÑÑÑов:"
+
+msgid "Define a New Storage Pool"
+msgstr "СоздаÑÑ Ð¿Ñл памÑÑи"
+
+msgid "Storage Pool Name"
+msgstr "ÐÐ¼Ñ Ð¿Ñла памÑÑи"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "ÐÐ¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии пÑлов памÑÑи. Ðе Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑÑм."
+
+msgid "Storage Pool Type"
+msgstr "Тип пÑла памÑÑи"
+
+msgid "Storage Path"
+msgstr "ÐÑÑÑ Ðº диÑкÑ"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr "ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи. ÐаждÑй пÑл памÑÑи должен имеÑÑ ÑникалÑнÑй пÑÑÑ."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr "Kimchi попÑÑаеÑÑÑ ÑоздаÑÑ ÐºÐ°Ñалог, еÑли он не ÑÑÑеÑÑвÑÐµÑ Ð² ÑиÑÑеме."
+
+msgid "NFS Server IP"
+msgstr "IP-адÑÐµÑ ÑеÑвеÑа NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP-адÑÐµÑ Ð¸Ð»Ð¸ Ð¸Ð¼Ñ Ñ
оÑÑа ÑеÑвеÑа NFS. Ðго можно ввеÑÑи или вÑбÑаÑÑ Ð² "
+"Ñ
Ñонологии."
+
+msgid "NFS Path"
+msgstr "ÐÑÑÑ NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "ÐкÑпоÑÑиÑованнÑй пÑÑÑ NFS на ÑеÑвеÑе NFS."
+
+msgid "iSCSI Server"
+msgstr "СеÑÐ²ÐµÑ iSCSI"
+
+msgid "Server"
+msgstr "СеÑвеÑ"
+
+msgid "Port"
+msgstr "ÐоÑÑ"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP-адÑÐµÑ Ð¸Ð»Ð¸ Ð¸Ð¼Ñ Ñ
оÑÑа ÑеÑвеÑа iSCSI. Ðе Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑÑм."
+
+msgid "Target"
+msgstr "Целевой обÑекÑ"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "Целевой обÑÐµÐºÑ iSCSI на ÑеÑвеÑе iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "ÐобавиÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¸Ñ iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "ÐденÑиÑикаÑÐ¸Ñ iSCSI"
+
+msgid "User Name"
+msgstr "ÐÐ¼Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ"
+
+msgid "Password"
+msgstr "ÐаÑолÑ"
+
+msgid "SCSI Adapter"
+msgstr "ÐдапÑÐµÑ SCSI"
+
+msgid "Please, wait..."
+msgstr "ÐодождиÑе..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "ÐобавиÑÑ Ñаблон"
+
+msgid "Where is the source media for this template? "
+msgstr "Ðде наÑ
одиÑÑÑ Ð¸ÑÑ
однÑй ноÑиÑÐµÐ»Ñ Ð´Ð»Ñ ÑÑого Ñаблона?"
+
+msgid "Local ISO Image"
+msgstr "ÐокалÑнÑй обÑаз ISO"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "УдаленнÑй обÑаз ISO"
+
+msgid "Search ISOs"
+msgstr "ÐоиÑк обÑазов ISO"
+
+msgid "The following ISOs are available:"
+msgstr "ÐоÑÑÑпнÑе обÑÐ°Ð·Ñ ISO:"
+
+msgid "OS: "
+msgstr "ÐС: "
+
+msgid "Version: "
+msgstr "ÐеÑÑиÑ: "
+
+msgid "Size: "
+msgstr "РазмеÑ: "
+
+msgid "Search more ISOs"
+msgstr "ÐоиÑк дополниÑелÑнÑÑ
обÑазов ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "СоздаÑÑ ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð¸Ð· вÑбÑаннÑÑ
обÑазов ISO"
+
+msgid "I want to use a specific ISO file"
+msgstr "ÐÑполÑзоваÑÑ ÐºÐ¾Ð½ÐºÑеÑнÑй Ñайл ISO"
+
+msgid "Loading default remote ISOs ..."
+msgstr "ÐагÑÑзка ÑдаленнÑÑ
ISO по ÑмолÑаниÑ..."
+
+msgid "Arch: "
+msgstr "ÐÑÑ
иÑекÑÑÑа: "
+
+msgid "I want to use a custom URL"
+msgstr "ÐÑполÑзоваÑÑ Ð´ÑÑгой URL"
+
+msgid "Edit Template"
+msgstr "ÐзмениÑÑ Ñаблон"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "ÐÑаÑика"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "ÐолиÑеÑÑво пÑоÑеÑÑоÑов"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "Ðе Ð½Ð°Ð¹Ð´ÐµÐ½Ñ ÑаблонÑ."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "Удаление запÑеÑено Ð´Ð»Ñ %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s не ÑеализÑÑÑ Ð¼ÐµÑод обновлениÑ"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Создание запÑеÑено Ð´Ð»Ñ %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "ÐÑибка анализа запÑоÑа JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "ÐÑа ÑÑнкÑÐ¸Ñ API поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ ÑолÑко JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Ð¥ÑанилиÑе даннÑÑ
в обÑекÑе модели не иниÑиализиÑовано."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "Ðе ÑдалоÑÑ Ð·Ð°Ð¿ÑÑÑиÑÑ Ð·Ð°Ð´Ð°ÑÑ Ð¸Ð·-за оÑибки %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr ""
+#~ "Сбой иденÑиÑикаÑии полÑзоваÑÐµÐ»Ñ %(username)s. [Ðод оÑибки: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "ÐÐµÑ Ð¿Ñав доÑÑÑпа к Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "УкажиÑе %(item)s Ð´Ð»Ñ Ð²Ñ
ода в Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "Ðе найден %(item)s в Ñ
ÑанилиÑе даннÑÑ
"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr "ÐÑÑек Ñайм-аÑÑ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ %(cmd)s (%(seconds)s Ñ)"
+
+#~ msgid "Help"
+#~ msgstr "ÐомоÑÑ"
+
+#~ msgid "About"
+#~ msgstr "РпÑогÑамме"
+
+#~ msgid "Log out"
+#~ msgstr "ÐÑйÑи"
+
+#~ msgid "Version:"
+#~ msgstr "ÐеÑÑиÑ:"
diff --git a/src/wok/plugins/kimchi/po/zh_CN.po b/src/wok/plugins/kimchi/po/zh_CN.po
new file mode 100644
index 0000000..fc6dd84
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/zh_CN.po
@@ -0,0 +1,2186 @@
+# i18n portable object for kimchi.
+# Copyright (C) IBM, Corp. 2013-2014
+# ShaoHe Feng <shaohef at linux.vnet.ibm.com>, 2013-04-18.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-06-27 10:48+0000\n"
+"Last-Translator: ShaoHe Feng <shaohef at linux.vnet.ibm.com>\n"
+"Language-Team: ShaoHe Feng <shaohef at linux.vnet.ibm.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Generated-By: pygettext.py 1.5\n"
+"X-Poedit-Country: CHINA\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr "æªç¥åé %(value)s"
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr "ä»»å¡'%(task)sè¶
æ¶%(seconds)sç§ã"
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr "ä½¿ç¨æå®çLDAPé
ç½®æªæ¾å°%(user_id)sç¨æ·"
+
+msgid "Unknown \"_cap\" specified"
+msgstr "æªè¯å«ç\"_cap\""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr "\"_passthrough\"å¼åºä¸º\"true\"æè
\"false\""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr "\"_passthrough_affected_by\"åºä¸ºä¸ä¸ªå符串å设å¤å"
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "è·ååè®¾å¤æ¶åºéã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "è·ååè®¾å¤ %(device)s ä¿¡æ¯æ¶åºéã"
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "æ¾ä¸å°åè¡çæä»¶ï¼%(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr "ä¸è½è§£æåè¡çæä»¶ï¼%(filename)sã请确ä¿å®æ¯ä¸ä¸ªJSONæ ¼å¼çæä»¶ã"
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "æ æ³éè¿ %(portal)s ç»å½iSCSI主æºåç®æ ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "æ æ³ç»å½iSCSI主æº%(host)sä¸çç®æ %(target)sã"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr "æªè½æ¾å°ISOæä»¶ %(filename)s"
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISOæä»¶%(filename)sä¸å¯å¼å¯¼ã"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "ISOæä»¶%(filename)sæ²¡æææçEl Toritoå¼å¯¼è®°å½ã"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "å¨ISOæä»¶%(filename)sä¸åç°æ æçEl Toritoæ ¡éªæ¡ç®ãã"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ISOæä»¶%(filename)sçEl Toritoå¼å¯¼æ å¿æ¯æ æç"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "æªè½è¯å«ISOæä»¶%(filename)sç主å·ç±»å"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "ISOæä»¶%(filename)sçå·æè¿°ç¬¦æ ¼å¼é误"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"hypervisor没æè®¿é®ISOæä»¶%(filename)sçæéãå¯ä»¥å°ISOç§»å°/var/lib/libvirtç®"
+"å½ä¸ï¼æä¸º'%(user)s'ç¨æ·è®¾ç½®è®¿é®æéï¼æå°'%(user)s'ç¨æ·å¢å å°ISOè·¯å¾çå±ç»ï¼"
+"æè
为ææçç¨æ·å¢å è®¿é®æé 'chmod -R o+x 'ï¼ä¸æ¨èï¼ã详æ
ï¼%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr "æç´¢éåæä½ç³»ç»ä¿¡æ¯æ¶åçé误ã"
+
+msgid "No OS information found in given image."
+msgstr "卿å®çéåæä»¶ä¸æªåç°æä½ç³»ç»ä¿¡æ¯ã"
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr "æªè½è¯»åéåæä»¶ %(filename)s"
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr "ç£çæä»¶å¿
须已åå¨ç³»ç»ä¸ï¼%(filename)s䏿¯åæ³æä»¶å"
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "èææº%(name)så·²ç»åå¨"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "èææº%(name)sä¸åå¨"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+"æªè½å®ç°èææº %(name)s éå½åï¼åç§° %(new_name)s å·²è¢«ä½¿ç¨æè
è¯¥èææºæªå
³"
+"æºã"
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "ä¸è½è·ååæ¢ç¶æçèææº%(name)sçæªå±"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "该æå¡å¨ä¸æ¯æè¿ç¨ISOéåã"
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr "èææº %(name)s 䏿¯æå¿«ç
§"
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "ä¸è½åå»ºèææº%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "ä¸è½æ´æ°èææº%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "ä¸è½è·åèææº%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr "èææº%(name)så·²å
³æºï¼è¿æ¥å¤±è´¥ã"
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr "æ æçèææºæ¨¡æ¿URI %(value)s"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr "æ æçèææºå卿± URI %(value)s"
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr "èææºå¾å½¢çé¢ä»
æ¯æSpice以åVNC"
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "è¿ç¨å¾å½¢è®¿é®ççå¬å°åå¿
é¡»æ¯IPv4æIPv6å°åã"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "æå®ç¨äºåå»ºèææºç模æ¿"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "ä¸è½å¯å¨èææº %(name)s. 详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "ä¸è½å
³éèææº%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "ä¸è½å é¤èææº %(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "æªè½éç½®èææº%(name)sã详æ
ï¼%(err)s"
+
+msgid "User name list must be an array"
+msgstr "ç¨æ·åå表å¿
须为ä¸ä¸ªæ°ç»"
+
+msgid "User name must be a string"
+msgstr "ç¨æ·åå¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "Group name list must be an array"
+msgstr "ç»åç§°å表å¿
须为ä¸ä¸ªæ°ç»"
+
+msgid "Group name must be a string"
+msgstr "ç¨æ·ç»åç§°å¿
é¡»æ¯ä¸ä¸ªå符串"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "ç¨æ·'%(users)s'ä¸åå¨"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "ç¨æ·ç»'%(groups)s'ä¸åå¨"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "æªè½å
³éèææº%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "æ æ³è·å¾èææº %(name)sçå
æ°æ®ï¼è¯¦æ
ï¼%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr "å®¢æ·æºæ§å¶å°å¯ç å¿
须为ä¸ä¸ªå符串ã"
+
+msgid "The life time for the guest console password must be a number."
+msgstr "å®¢æ·æºå½ä»¤è¡å¯ç æææ¶é´å¿
é¡»æ¯ä¸ä¸ªæ°åã"
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr "èææº'%(name)s'å¨å¶ä½å¯æ¬åå¿
é¡»å
³æºã"
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr "å¶ä½èææº'%(name)s'坿¬æéçç£ç空é´ä¸è¶³"
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr "æªè½æåå¶ä½èææº'%(name)s'坿¬ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr "èææº%(vmid)sæªææè¢«åé
ç主æºè®¾å¤%(dev_name)sã"
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr "主æºè®¾å¤%(dev_name)sä¸å
è®¸ç´æ¥åé
ç»èææºã"
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+"æªæ¾å°IOMMU groupsã主æºPCI pass throughéè¦IOMMU groupæå¯ä»¥æ£ç¡®å·¥ä½ã请å¨"
+"BIOS设置éå°Intel VT-d æè
AMD IOMMU 设为使è½ï¼èå确认å
æ ¸æ¯æIOMMUã对äº"
+"Intel CPUï¼å¨è·¯å¾/boot/grub2/grub.conf䏿·»å å
æ ¸åéintel_iommu=onã对äºAMD "
+"CPUï¼åæ·»å iommu=pt iommu=1ã"
+
+msgid "\"name\" should be a device name string"
+msgstr "\"name\"åºè¯¥ä¸ºä¸ä¸ªå符串åç设å¤å"
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "èææº %(name)s 䏿²¡ææ¥å£ %(iface)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr "ä¸ºèææº%(name)sæå®çç½ç»%(network)sä¸åå¨"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "åªæ¯æç½ç»ç±»åçèææºæ¥å£"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "èææºæ¥å£çç½ç»ååå¿
é¡»æ¯å符串"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr "èææºæ¥å£æå®çç½ç»æ¨¡å塿 æ"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "为æ°çèææºæ¥å£æå®ç±»ååç½ç»"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "æ¨¡æ¿ %(name)s å·²ç»åå¨"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çç½ç» '%(network)s' ä¸åå¨"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çå卿± '%(pool)s' ä¸åå¨"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çå卿± '%(pool)s' æ²¡ææ¿æ´»"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "为CDROMæå®çåæ° '%(param)s' æ æ"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "ä¸ºæ¨¡æ¿ %(template)s æå®çç½ç» '%(network)s' æ²¡ææ¿æ´»"
+
+msgid "Template name must be a string"
+msgstr "模æ¿çååå¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "Template icon must be a path to the image"
+msgstr "模æ¿ç徿 å¿
é¡»æ¯ä¸ä¸ªæåéåçè·¯å¾"
+
+msgid "Template distribution must be a string"
+msgstr "模æ¿çåè¡çå¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "Template distribution version must be a string"
+msgstr "模æ¿çåè¡ççæ¬å·å¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPUæ°éå¿
须为ä¸ä¸ªå¤§äº0çæ´æ°"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "æ»å
åæ°ï¼MB为åä½ï¼å¿
é¡»æ¯ä¸ä¸ªå¤§äº512çæ´æ°"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "模æ¿çCDROMå¿
é¡»æ¯ä¸ä¸ªæ¬å°æè
è¿ç¨çISOæä»¶"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "ç»æ¨¡æ¿æå®äºæ æçå卿± URI %(value)s"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "æå®ä¸ä¸ªISOéåä½ä¸ºå建模æ¿çCDROMæè
åºç¡éå"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "ä¸ºæ¨¡æ¿æå®çç½ç»å¿
é¡»å¨ä¸ä¸ªå表ä¸"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr "å½å卿± ç±»å为iSCSIæè
SCSIçæ¶åé¡»ä¸ºæ¨¡æ¿æå®ä¸ä¸ªå·"
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr "å·%(volume)sä¸å¨å卿± %(pool)sä¸"
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "å建模æ¿å¤±è´¥ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "ç±äºé误ï¼%(err)sï¼æªè½å 餿¨¡æ¿"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr "ç£ç大å°å¿
须大äº1GBã"
+
+msgid "Template base image must be a valid local image file"
+msgstr "模æ¿åºç¡éåå¿
须为ä¸ä¸ªææçæ¬å°éåæä»¶"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr "æªè½è¯å«åºç¡éå%(path)sæ ¼å¼"
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr "CPUææä¸ï¼VCPUså¿
é¡»å
æ¬sockets, cores 以åthreadsã"
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr "CPUææä¸ï¼æ¯ä¸ä¸ªåæ°å¿
须为大äºé¶çæ´æ°ã"
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"æ æçç£çéåæ ¼å¼ãææçæ ¼å¼ä¸ºï¼bochs, cloop, cow, dmg, qcow, qcow2, qed, "
+"raw, vmdk, vpcã"
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "å卿± %(name)så·²ç»åå¨"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "å卿± %(name)sä¸åå¨"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "为æ°å卿± %(name)sæå®%(item)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "ä¸è½å 餿¿æ´»çå卿± %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "ä¸è½å举å卿± ã 详æ
ï¼ %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "ä¸è½å建å卿± %(name)sã详æ
ï¼ %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr "ä¸è½è·åå¨åæ± %(name)sä¸å·çæ°ç®ã详æ
ï¼ %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "ä¸è½æ¿æ´»å¨åæ± %(name)sã详æ
ï¼ %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "ä¸è½åç¨å¨åæ± %(name)sã详æ
ï¼ %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "ä¸è½å é¤å¨åæ± %(name)sã详æ
ï¼ %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr "ä¸è½å建NFSå卿± ï¼å¯è½å¯¼åºè·¯å¾%(path)så¨æè½½æ¶è¢«é»å¡äº"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr "ä¸è½å建NFSå卿± ï¼æè½½å¯¼åºè·¯å¾%(path)s失败"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "䏿¯æçå卿± ç±»åï¼%(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr "æ¥è¯¢å卿± XMLå°%(pool)sæ¶åºç°é误"
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr "å卿± ç±»åä»
æ¯ædirï¼netfsï¼logicalï¼iscsiï¼isci以åkimchi-iso"
+
+msgid "Storage pool path must be a string"
+msgstr "å卿± è·¯å¾å¿
é¡»æ¯å符串"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "å卿± 主æºå¿
é¡»æ¯ä¸ä¸ªIPåè
主æºå"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr "å卿± 设å¤å¿
须为å设å¤çä¸ä¸ªç»å¯¹è·¯å¾"
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "å卿± 设å¤åæ°å¿
é¡»æ¯ä¸ä¸ªå表"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSIå卿± çç®æ IQNå¿
é¡»æ¯å符串"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "è¿ç¨å卿å¡å¨ç端å£å¿
é¡»æ¯1å°65535ä¹é´çæ´æ°"
+
+msgid "iSCSI target username must be a string"
+msgstr "iSCSIç®æ ç¨æ·åå¿
须为ä¸ä¸ªå符串"
+
+msgid "iSCSI target password must be a string"
+msgstr "iSCSIç®æ å¯ç å¿
须为ä¸ä¸ªå符串"
+
+msgid "Specify name and type to create a storage pool"
+msgstr "为æ°å卿± æå®åååç±»å"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr "%(disk)s 䏿¯ææçç£ç/ååºãä¸è½è¢«æ·»å å°å卿± %(pool)sä¸"
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr "æªè½å®ç°é»è¾æ± %(pool)sçæ©å±ï¼è¯¦æ
ï¼%(err)s"
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "åªæé»è¾å卿± æ¯ææ´æ°ç£çåæ°ã"
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI主æºéé
å¨åå¿
é¡»æ¯ä¸ªå符串"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "å卿± kimchi_isosçä½å
é¨ä½¿ç¨"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr "ä¸è½æ¿æ´»NFSå卿± %(name)sãNFSæå¡å¨%(server)sä¸å¯å°è¾¾ã"
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr "ä¸è½åç¨NFSå卿± %(name)sãNFSæå¡å¨%(server)sä¸å¯å°è¾¾ã"
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr "ä¸è½åç¨å卿± %(name)sï¼è¯¥å卿± ä¸ä¸äºæ¨¡æ¿å
³è"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "ä¸è½å é¤å卿± %(name)sï¼è¯¥å卿± ä¸ä¸äºæ¨¡æ¿å
³è"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr "å·ç»'%(name)s'å·²ç»åå¨ï¼è¯·éæ©å
¶å®çå忥å建é»è¾å卿± ã"
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr "å
¨çæ«æä¿¡æ¯æ´æ°å¤±è´¥ã详æ
ï¼%(err)sã"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "åå¨å·%(name)så·²ç»åå¨"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "å卿± %(pool)s䏿²¡æåå¨å·%(name)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr "æªè½å建åå¨å·%(volume)sï¼å 为å卿± %(pool)s æªè¢«æ¿æ´»"
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "为æ°åå¨å·%(volume)sæå®æå®%(item)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr "ä¸è½ååºåå¨å·ï¼å 为å卿± %(pool)sæ²¡ææ¿æ´»"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr "ä¸è½å¨å卿± %(pool)sä¸å建åå¨å·%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr "ä¸è½å¨å卿± %(pool)sä¸ååºåå¨å·ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "ä¸è½æ¦é¤åå¨å·%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "ä¸è½å é¤åå¨å·%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "ä¸è½æ¹ååå¨å·%(name)sç大å°ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "åå¨ç±»å%(type)s䏿¯æå·çå建åå é¤"
+
+msgid "Storage volume name must be a string"
+msgstr "åå¨å·çååå¿
é¡»æ¯å符串"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "åå¨å·åé
é¢å¿
é¡»æ¯æ´æ°"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"䏿¯æè¯¥åå¨å·æ ¼å¼ï¼æ¯æçæ ¼å¼ï¼bochs, cloop, cow, dmg, qcow, qcow2, qed, "
+"raw, vmdk, vpcã"
+
+msgid "Storage volume requires a volume name"
+msgstr "åå¨å·éè¦åå"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr "åå¨å·ä¿¡æ¯æ´æ°å¤±è´¥ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr "åªè½å¯¹åæ°%(param)sä¸çä¸ä¸ªè¿è¡æå®"
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr "䏿¯æä»%(param)såå»ºèææº"
+
+msgid "Storage volume capacity must be an integer number."
+msgstr "åå¨å·å®¹éå¿
须为ä¸ä¸ªæ´æ°"
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr "åå¨å·URLå¿
须为http://ï¼https://ï¼ftp://æftps://"
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr "ä¸è½è®¿é®æä»¶%(url)sï¼è¯·æ£æ¥è¯¥æä»¶æ¯å¦åå¨ã"
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr "æªè½äºå卿± '%(pool)s'å¶ä½åå¨å·'%(name)s'ç坿¬ï¼è¯¦æ
ï¼%(err)s"
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "æ¥å£%(name)sä¸åå¨"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "ç½ç»%(name)så·²ç»åå¨"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "ç½ç»%(name)sä¸åå¨"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr "ç»ç½ç»%(network)sæå®çåç½%(subnet)sæ æ"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "æå®ä¸ä¸ªç½ç»æ¥å£æ¥å建桥æ¥ç±»åçç½ç»%(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "ä¸è½å 餿¿æ´»çç½ç»%(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr "ç»ç½ç»%(network)sæå®çæ¥å£%(iface)s已被使ç¨"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "æ¥å£åºè¯¥æ¯ä¸ä¸ªè£¸çç½ç»æ¥å£å¡ãbondingæè
æ¡¥æ¥è®¾å¤ã"
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "ä¸è½å建ç½ç»%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "ä¸è½ä¸ºç½ç»'%(name)s'æ¾å°ä¸ä¸ªæªä½¿ç¨çIPç½ç»å°åã"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "æ¯æçç½ç»ç±»åæé离ãNATåæ¡¥æ¥"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr "ç½ç»åç½å¿
é¡»æ¯ä¸ä¸ªIPå°åå ç½ç»åç¼æåç½æ©ç çå符串"
+
+msgid "Network interface must be a string"
+msgstr "ç½ç»æ¥å£å¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "ç½ç»VLANå·å¿
é¡»æ¯1å°4094ä¹é´çæ´æ°"
+
+msgid "Specify name and type to create a Network"
+msgstr "为æ°ç½ç»æå®åååç±»å"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "ä¸è½ä»¥æ¡¥è®¾å¤%(name)sä½ä¸ºVLANçtrunk设å¤ã"
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "ç½ç»æ¥å£å¯å¨å¤±è´¥ %(iface)sï¼%(err)sã"
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr "ç½ç»æ¥å£%(iface)så¯å¨å¤±è´¥ï¼è¯·æ£æ¥ç½ç»è¿æ¥æ
åµã"
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr "å¯å¨ç½ç»%(name)s失败ï¼è¯¦æ
ï¼%(err)s"
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "è¯ææ¥å%(name)sä¸åå¨"
+
+msgid "Debug report tool not found in system"
+msgstr "ç³»ç»ä¸æ²¡æè¯ææ¥åå·¥å
·"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "ä¸è½åå»ºè¯ææ¥å%(name)sã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr "æªè½æ¾å°æå®åç§°%(name)sçè°è¯æ¥å"
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "ä¸è½çæè¯ææ¥å%(name)sã详æ
ï¼%(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr "ä¸è½çæè¯ææ¥å%(name)sã详æ
ï¼%(err)s"
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+"è°è¯æ¥ååç§°å¿
须为ä¸ä¸ªå符串ãåªæè±æåç¬¦ï¼æ°åï¼ä¸å线('_')以åè¿å符('-')"
+"ä¸ºåæ³å符ã"
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr "åå为\"'%(name)s\"çè°è¯æ¥åå·²ç»åå¨ï¼è¯·éæ©å
¶å®çååã"
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "å卿å¡å¨%(server)sæªè¢«Kimchi使ç¨"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "åè¡çæ¬'%(name)s'ä¸åå¨"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "主æºä¸ä¸æ²¡æååº%(name)s"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr "æèææºå¨è¿è¡ï¼ä¸è½å
³é主æº"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "æèææºå¨è¿è¡ï¼ä¸è½é起主æº"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "æ²¡ææ¾å°èç¹è®¾å¤'%(name)s'"
+
+msgid "Conflicting flag filters specified."
+msgstr "flag filterså²çªã"
+
+msgid "No packages marked for update"
+msgstr "没æè½¯ä»¶å
æ è¯è¦å级"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "软件å
%(name)sæ²¡ææ è¯ä¸ºè¦å级"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr "è·åæ è¯ä¸ºè¦å级ç软件å
æ¶åºéã详æ
ï¼%(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "ç³»ç»ä¸æ²¡æå
¼å®¹ç软件å
管çå¨"
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "æ æçURI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr "æªè½éæ©ä¸ä¸ªèææºåç§°"
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "æ æçåå¨ç±»åãæ¯æç±»å为ï¼'cdrom'ï¼'disk'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr "è·¯å¾'%(value)s'䏿¯è®¾å¤çæææ¬å°/è¿ç¨è·¯å¾"
+
+msgid "Only CDROM path can be update."
+msgstr "ä»
æ¯æCDROMè·¯å¾æ´æ°ã"
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr "åå¨è®¾å¤%(dev_name)så¨èææº%(vm_name)sä¸ä¸åå¨"
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "å建æ°çåå¨è®¾å¤æ¶åºéï¼%(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "æ´æ°åå¨è®¾å¤æ¶åºéï¼%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "ç§»é¤åå¨è®¾å¤æ¶åºéï¼%(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr "䏿¯æIDE设å¤ççææ"
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "ä¸ºæ·»å æ°å»ºèææºç£çæå®ç±»ååè·¯å¾æè
ç±»ååå卿± /åå¨å·"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "æå®æ´æ°èææºç£ççè·¯å¾"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr "æ§å¶å¨ç±»å为%(type)sç设å¤è¾¾å°ä¸é%(limit)s"
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr "æªè½ä¸ºç»åºçå卿± /åå¨å·æ¾å°å¯¹åºç£çè·¯å¾ä¿¡æ¯ï¼%(error)s"
+
+msgid "Volume already in use by other virtual machine."
+msgstr "该å·å·²ç»è¢«å
¶ä»èææºä½¿ç¨ã"
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "å¢å èææºç£çæ¶ï¼ä»
è½æå®è·¯å¾æå卿± /åå¨å·ä¸çä¸ä¸ª"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr "æ ¼å¼ä¸º%(format)sçå·ä¸ç¬¦ååå¨ç±»å%(type)s"
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM软件ä»åºIDå¿
é¡»æ¯åªå
å«ä¸ä¸ªåè¯çå符串"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "软件ä»åºURLå¿
é¡»æ¯http://ã ftp:// æ file://"
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr "软件ä»åºé
ç½®æ¯ä¸ä¸ªä¸ä»åºé®åç¹å®å¼å¯¹åºçåå
¸"
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "DEBä»åºçåè¡çæ¬å¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "DEBä»åºçç»ä»¶å¿
须以æ°ç»å½¢å¼ååº"
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEBä»åºçç»ä»¶å¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUMä»åºçååå¿
é¡»æ¯ä¸ä¸ªå符串"
+
+msgid "GPG check must be a boolean value."
+msgstr "GPGæ ¡éªå¿
é¡»æ¯ä¸ä¸ªå¸å°å¼"
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPGé®å¿
é¡»æ¯ä¸ä¸ªæåASCIIè½¬ä¹æä»¶ï¼.ascæä»¶ï¼çURL"
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "ä¸è½æ´æ°è½¯ä»¶ä»åº%(repo_id)s"
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "软件ä»åº%(repo_id)sä¸åå¨ã"
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "æ¨çç³»ç»æ æ³è¯å«è½¯ä»¶ç®¡çå·¥å
·"
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "软件ä»åº%(repo_id)så·²ç»å¯ç¨ã"
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "软件ä»åº%(repo_id)så·²ç»ç¦ç¨ã"
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "ä¸è½ç§»é¤è½¯ä»¶ä»åº%(repo_id)s"
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "æ æ³å软件ä»åºçé
ç½®æä»¶%(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "æå®è½¯ä»¶ä»åºåè¡çæ¬æ¥å建ä¸ä¸ªDEBä»åºã"
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "ä¸è½å¯ç¨è½¯ä»¶ä»åº%(repo_id)s"
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "ä¸è½ç¦ç¨è½¯ä»¶ä»åº%(repo_id)s"
+
+msgid "YUM Repository ID already exists"
+msgstr "YUMä»åºIDå·²ç»åå¨"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUMä»åºååå¿
é¡»æ¯ä¸ä¸ªå符串"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "ä¸è½å举软件ä»åºã详æ
ï¼'%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "ä¸è½è·å软件ä»åºçä¿¡æ¯ã详æ
ï¼'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "ä¸è½å¢å 软件ä»åºã详æ
ï¼'%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "ä¸è½ç§»é¤è½¯ä»¶ä»åºã详æ
ï¼'%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr "软件ä»åºä¸æ¯æé
置类å: %(items)s"
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr "èææº'%(vm)s'å¨å¶ä½å¿«ç
§åå¿
é¡»å
³æºã"
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr "æªè½ä¸ºèææº'%(vm)s'å¶ä½å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr "å¿«ç
§'%(name)s'ä¸åå¨èææº'%(vm)s'ä¸ã"
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr "æªè½å¨èææº'%(vm)s'æ¾å°å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr "æªè½ååºèææº'%(vm)s'çå¿«ç
§ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr "æªè½å é¤èææº'%(vm)s'å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr "æªè½æ¾å°èææº'%(vm)s'å½åå¿«ç
§ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr "æªè½æ¢å¤èææº'%(vm)s'å°å¿«ç
§'%(name)s'ã详æ
ï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+"æªè½ä¸ºèææº'%(vm)s'å建快ç
§å 为å
¶ä½¿ç¨äºæ ¼å¼ä¸º'%(format)s'çç£çï¼å½åä»
æ¯"
+"æ'qcow2'æ ¼å¼ã"
+
+msgid "The number of vCPUs is too large for this system."
+msgstr "vCPUsçæ°é对该系ç»èè¨å¤ªå¤§ã"
+
+msgid "Invalid vCPU/topology combination."
+msgstr "æ æçvCPU/topologyç»åã"
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr "å½å主æºï¼æå½åé
ç½®ï¼ä¸å
许CPUææã"
+
+msgid "ERROR CODE"
+msgstr "é误ç "
+
+msgid "REASON"
+msgstr "åå "
+
+msgid "STACK"
+msgstr "è°ç¨æ "
+
+msgid "Go to Homepage"
+msgstr "è¿å主页"
+
+msgid "Create a New Virtual Machine"
+msgstr "å建ä¸ä¸ªæ°çèææº"
+
+msgid "Virtual Machine Name"
+msgstr "èææºåç§°"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr "ååæ¯èææºçæ è¯ã妿çç¥ï¼å°ä¼åºäºä½¿ç¨ç模æ¿éæ©ä¸ä¸ªååã"
+
+msgid "Template"
+msgstr "模æ¿"
+
+msgid "Please create a template first."
+msgstr "请å
éæ©ä¸ä¸ªæ¨¡æ¿"
+
+msgid "Create a Template"
+msgstr "å建ä¸ä¸ªæ¨¡æ¿"
+
+msgid "Please choose a template."
+msgstr "è¯·éæ©æ¨¡æ¿ã"
+
+msgid "OS"
+msgstr "æä½ç³»ç»"
+
+msgid "OS Version"
+msgstr "æä½ç³»ç»çæ¬"
+
+msgid "CPUS"
+msgstr "ä¸å¤®å¤çå¨"
+
+msgid "Memory"
+msgstr "å
å"
+
+msgid "Create"
+msgstr "å建"
+
+msgid "Creating..."
+msgstr "æ£å¨å建..."
+
+msgid "Cancel"
+msgstr "åæ¶"
+
+msgid "Edit Guest"
+msgstr "ä¿®æ¹å®¢æ·æº"
+
+msgid "General"
+msgstr "常è§"
+
+msgid "Storage"
+msgstr "åå¨"
+
+msgid "Interface"
+msgstr "ç½ç»æ¥å£"
+
+msgid "Permission"
+msgstr "æé"
+
+msgid "Host PCI Device"
+msgstr "主æºPCI设å¤"
+
+msgid "Snapshot"
+msgstr "å¿«ç
§"
+
+msgid "Name"
+msgstr "åç§°"
+
+msgid "CPUs"
+msgstr "ä¸å¤®å¤çå¨"
+
+msgid "Memory (MB)"
+msgstr "å
å(MB)"
+
+msgid "Icon"
+msgstr "徿 "
+
+msgid "Device"
+msgstr "设å¤åç§°"
+
+msgid "Path"
+msgstr "è·¯å¾"
+
+msgid "Network"
+msgstr "ç½ç»"
+
+msgid "Type"
+msgstr "ç±»å"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr "å¯éçç³»ç»ç¨æ·åç¨æ·ç»"
+
+msgid "Selected system users and groups"
+msgstr "å·²éçç³»ç»ç¨æ·åç¨æ·ç»"
+
+msgid "User"
+msgstr "ç¨æ·"
+
+msgid "All"
+msgstr "ææ"
+
+msgid "To Add"
+msgstr "å¾
æ·»å "
+
+msgid "Added"
+msgstr "已添å "
+
+msgid "filter"
+msgstr "è¿æ»¤å¨"
+
+msgid "Product"
+msgstr "产å"
+
+msgid "Vendor"
+msgstr "åå"
+
+msgid "Created"
+msgstr "å建äº"
+
+msgid "Save"
+msgstr "ä¿å"
+
+msgid "Replace"
+msgstr "æ¿æ¢"
+
+msgid "Detach"
+msgstr "å¸è½½"
+
+msgid "revert"
+msgstr "æ¢å¤"
+
+msgid "Start"
+msgstr "å¯ç¨"
+
+msgid "Reset"
+msgstr "éç½®"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "å
³éçµæº"
+
+msgid "Actions"
+msgstr "æä½"
+
+msgid "Connect"
+msgstr "è¿æ¥å°"
+
+msgid "Clone"
+msgstr "å¶ä½å¯æ¬"
+
+msgid "Edit"
+msgstr "ç¼è¾"
+
+msgid "Shut Down"
+msgstr "å
³æº"
+
+msgid "Delete"
+msgstr "å é¤"
+
+msgid "CPU"
+msgstr "å¤çå¨"
+
+msgid "Disk I/O"
+msgstr "ç£çI/O"
+
+msgid "Network I/O"
+msgstr "ç½ç»I/O"
+
+msgid "Livetile"
+msgstr "å±å¹"
+
+msgid "No guests found."
+msgstr "没æåç°å®¢æ·æº"
+
+msgid "Add a Storage Device to VM"
+msgstr "ä¸ºèææºæ·»å ä¸ä¸ªåå¨è®¾å¤"
+
+msgid "Device Type"
+msgstr "设å¤ç±»å"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "设å¤ç±»åãç®åæ¯æè®¾å¤ç±»åï¼\"cdrom\"å\"disk\"ã "
+
+msgid "Storage Pool"
+msgstr "å卿± "
+
+msgid "Storage pool which volume located in"
+msgstr "åå¨å·æå¨çå卿± "
+
+msgid "Storage Volume"
+msgstr "åå¨å·"
+
+msgid "Storage volume to be attached"
+msgstr "被添å çåå¨å·"
+
+msgid "File Path"
+msgstr "æä»¶è·¯å¾"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "æå¡å¨ç«¯CDROMæä½¿ç¨çISOæä»¶è·¯å¾"
+
+msgid "Attach"
+msgstr "è£
è½½"
+
+msgid "Shut down"
+msgstr "å
³æº"
+
+msgid "Restart"
+msgstr "éå¯"
+
+msgid "Basic Information"
+msgstr "åºæ¬ä¿¡æ¯"
+
+msgid "OS Distro"
+msgstr "æä½ç³»ç»åè¡ç"
+
+msgid "OS Code Name"
+msgstr "æä½ç³»ç»ä»£å·"
+
+msgid "Processor"
+msgstr "å¤çå¨"
+
+msgid "CPU(s)"
+msgstr "CPU(s)"
+
+msgid "System Statistics"
+msgstr "ç³»ç»ç»è®¡ä¿¡æ¯"
+
+msgid "Software Updates"
+msgstr "è½¯ä»¶æ´æ°"
+
+msgid "Update Progress"
+msgstr "æ´æ°è¿åº¦"
+
+msgid "Repositories"
+msgstr "软件ä»åº"
+
+msgid "Debug Reports"
+msgstr "主æºè¯ææ¥å"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr "ç¨æ·åæå¯ç é误ï¼è¯·éæ°è¾å
¥ã"
+
+msgid "This field is required."
+msgstr "éè¦å¡«åæ¤å¤"
+
+msgid "Log in"
+msgstr "ç»å½"
+
+msgid "Logging in..."
+msgstr "ç»å½ä¸..."
+
+msgid "Host"
+msgstr "主æº"
+
+msgid "Guests"
+msgstr "å®¢æ·æº"
+
+msgid "Templates"
+msgstr "模æ¿"
+
+msgid "Failed to get application configuration"
+msgstr "è·ååºç¨é
置失败"
+
+msgid "This is not a valid Linux path"
+msgstr "è¿ä¸æ¯ä¸ä¸ªææçLinuxè·¯å¾"
+
+msgid "This is not a valid URL."
+msgstr "è¿ä¸æ¯ä¸ä¸ªææçURL"
+
+msgid "No such data available."
+msgstr "没æå¯ç¨çæ°æ®"
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"è¿æ¥ä¸ä¸ä¸»æºã请确ä¿ä¸»æºç³»ç»å·²å¯å¨ï¼å¹¶ä¸è½éè¿ç½ç»è¿æ¥ä¸»æºãHTTP请æ±ååºï¼%1"
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "å é¤ç¡®è®¤"
+
+msgid "OK"
+msgstr "ç¡®å®"
+
+msgid "Confirm"
+msgstr "确认"
+
+msgid "Warning"
+msgstr "è¦å"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "æ£å¨å è½½..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "éè¯"
+
+msgid "Detailed message:"
+msgstr "è¯¦ç»æ¶æ¯ï¼"
+
+msgid "No ISO found"
+msgstr "没æåç°ISOæä»¶"
+
+msgid "This is not a valid ISO file."
+msgstr "è¿ä¸æ¯ä¸ä¸ªææçISOæä»¶"
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "è¿éè¦ä¸æ®µæ¶é´ãæ¯å¦ç»§ç»ï¼"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "è¿å°æ°¸ä¹
å 餿¨¡æ¿ãæ¯å¦ç»§ç»ï¼"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr "æèææºå¨è¿è¡ï¼ä¸è½å
³é主æºã"
+
+msgid "Max:"
+msgstr "æå¤§ï¼"
+
+msgid "Utilization"
+msgstr "å©ç¨ç"
+
+msgid "Available"
+msgstr "å¯å©ç¨ç"
+
+msgid "Read Rate"
+msgstr "读éç"
+
+msgid "Write Rate"
+msgstr "åéç"
+
+msgid "Received"
+msgstr "æ¥æ¶"
+
+msgid "Sent"
+msgstr "åé"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr "å
³éæè
éå¯ä¸»æºä¼å¯¼è´æ²¡æä¿åçå·¥ä½ä¸¢å¤±ãç»§ç»å
³æº/éå¯ï¼"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr "软件ä»åºå°è¢«æ°¸ä¹
å é¤ï¼ä¸è½æ¢å¤ãæ¯å¦ç»§ç»ï¼"
+
+msgid "ID"
+msgstr "æ è¯ç¬¦"
+
+msgid "Base URL"
+msgstr "åºæ¬URL"
+
+msgid "Is Mirror"
+msgstr "æ¯å¦ä¸ºéå"
+
+msgid "URL Args"
+msgstr "URLåæ°"
+
+msgid "Enabled"
+msgstr "å·²å¯ç¨"
+
+msgid "GPG Check"
+msgstr "GPGæ ¡éª"
+
+msgid "GPG Key"
+msgstr "GPGé®"
+
+msgid "Add"
+msgstr "å¢å "
+
+msgid "Remove"
+msgstr "å é¤"
+
+msgid "Enable"
+msgstr "使è½"
+
+msgid "Disable"
+msgstr "ç¦ç¨"
+
+msgid "Package Name"
+msgstr "软件å
åç§°"
+
+msgid "Version"
+msgstr "çæ¬"
+
+msgid "Architecture"
+msgstr "ä½ç³»ç»æ"
+
+msgid "Repository"
+msgstr "软件ä»åº"
+
+msgid "Update All"
+msgstr "æ´æ°ææ"
+
+msgid "Updating..."
+msgstr "æ£å¨æ´æ°..."
+
+msgid "Failed to retrieve packages update information."
+msgstr "æ¥æ¾è½¯ä»¶å
æ´æ°ä¿¡æ¯å¤±è´¥ã"
+
+msgid "Failed to update package(s)."
+msgstr "æ´æ°è½¯ä»¶å
失败"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr "è¯ææ¥åå°è¢«æ°¸ä¹
å é¤ï¼å¹¶ä¸ä¸è½æ¢å¤ãæ¯å¦ç»§ç»ï¼"
+
+msgid "Generated Time"
+msgstr "çææ¶é´"
+
+msgid "Generate"
+msgstr "çæ"
+
+msgid "Generating..."
+msgstr "æ£å¨çæ..."
+
+msgid "Rename"
+msgstr "éå½å"
+
+msgid "Download"
+msgstr "ä¸è½½"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr "æ¥åååä¸åªè½å
å«åæ¯ãæ°åãä¸å线('_')åè¿å符('-')"
+
+msgid "Pending..."
+msgstr "æ£å¨å è½½..."
+
+msgid "Report name is the same as the original one."
+msgstr "æ¥ååç§°ä¸åå§åç§°éå¤ã"
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr "è¿å°å é¤èææºåå®çèæç£çã该æä½ä¸è½æ¤éï¼ç»§ç»åï¼"
+
+msgid "Power off Confirmation"
+msgstr "å
³éçµæºç¡®è®¤"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr "è¿æ ·åå¯è½å¯¼è´ä¸è¯åæï¼æ¯å¦å®¢æ·æºç£çç¼åæªå·æ°ï¼ç¡®è®¤è¦ç»§ç»åï¼"
+
+msgid "Reset Confirmation"
+msgstr "é置确认"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr "å¨å®¢æ·æºæä½ç³»ç»æªå
³éçæ
åµä¸éç½®æé£é©å¯¼è´æ°æ®ä¸¢å¤±ï¼ç¡®è®¤è¦ç»§ç»åï¼"
+
+msgid "Shut Down Confirmation"
+msgstr "å
³æºç¡®è®¤"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "注æï¼å®¢æ·æºæä½ç³»ç»å¯è½ä¼å¿½ç¥è¿ä¸ªè¯·æ±ï¼ç¡®è®¤è¦ç»§ç»åï¼"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr "èææºå é¤ç¡®è®¤"
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr "è¯¥èææºä¸æ¯ä¸ä¸ªç¨³å®çèææºï¼å
³æºå°ä¼å é¤å®ï¼æ¯å¦ç»§ç»ï¼"
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+"å½ç®æ å®¢æ·æºä½¿ç¨SCSIæè
iSCSIåå¨å·æ¶ï¼è¿äºåå¨å·ç坿¬å°è¢«æ¾ç½®äºé»è®¤å卿± "
+"ä¸ãå¨ç®æ å卿± 没æè¶³å¤ç©ºé´æ¾ç½®å
¶ä»åå¨å·çæ¶åä¹ä¼å¦æ¤ã确认继ç»ï¼"
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr "CDROMå°è¢«æ°¸ä¹
å¸è½½ï¼ä½ å¯ä»¥éæ°è£
è½½å®ãç»§ç»å¸è½½ï¼"
+
+msgid "Attaching..."
+msgstr "æ£å¨è£
è½½"
+
+msgid "Replacing..."
+msgstr "æ£å¨æ¿æ¢..."
+
+msgid "Successfully attached!"
+msgstr "æåè£
è½½"
+
+msgid "Successfully replaced!"
+msgstr "æåæ¿æ¢"
+
+msgid "Successfully detached!"
+msgstr "æåå¸è½½"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr "该ç£çå°ä¼è¢«æ°¸ä¹
å¸è½½ï¼ä½ å¯ä»¥éæ°æ·»å å®ï¼ç»§ç»æ§è¡å¸è½½æä½å?"
+
+msgid "interface:"
+msgstr "æ¥å£ï¼"
+
+msgid "address:"
+msgstr "å°åï¼"
+
+msgid "link_type:"
+msgstr "è¿æ¥ç±»åï¼"
+
+msgid "block:"
+msgstr "åï¼"
+
+msgid "drive_type:"
+msgstr "设å¤ç±»åï¼"
+
+msgid "model:"
+msgstr "模åï¼"
+
+msgid "Affected devices:"
+msgstr "被影åç设å¤ï¼"
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN æ è¯ç¬¦å¿
é¡»å¨1è³4094ä¹é´"
+
+msgid "unavailable"
+msgstr "æ æ³è·å"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr "ï»¿æ¤æä½å°ä¸æä¾èµæ¤ç½ç»çèææºçç½ç»è¿æ¥ã"
+
+msgid "Create a network"
+msgstr "å建ä¸ä¸ªç½ç»"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"è¿æ¯ä¸ä¸ªä¸´æ¶çç½ç»é
ç½®ï¼è¯¥æä½ä¼æ°¸ä¹
å°å é¤è¿ä¸ªç½ç»è䏿¯åæ¢å
¶è¿è¡ï¼ç¡®å®è¦ç»§"
+"ç»åï¼"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "è¿å°æ°¸ä¹
å é¤å卿± ãæ¯å¦ç»§ç»ï¼"
+
+msgid "This storage pool is empty."
+msgstr "è¿ä¸ªå卿± 为空"
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr "ä½ çç£çå°ä¼æ ¼å¼åï¼ç£çä¸çæ°æ®ä¼ä¸¢å¤±ï¼ä½ ç¡®å®è¦ç»§ç»åï¼"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSIå
纤éé"
+
+msgid "No SCSI adapters found."
+msgstr "没æåç°SCSIéé
å¨"
+
+msgid "Loading iSCSI targets..."
+msgstr "读åiSCSIç®æ ..."
+
+msgid "No iSCSI found. Please input one."
+msgstr "æªè½æ¾å°iSCSI,请è¾å
¥ä¸ä¸ªã"
+
+msgid "Failed to load iSCSI targets."
+msgstr "读åiSCSIç®æ 失败ã"
+
+msgid "The storage pool name can not be blank."
+msgstr "å卿± çåç§°ä¸è½ä¸ºç©ºã"
+
+msgid "The storage pool path can not be blank."
+msgstr "å卿± çè·¯å¾ä¸è½ä¸ºç©ºã"
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFSæå¡å¨æè½½è·¯å¾ä¸è½ä¸ºç©ºã"
+
+msgid "Invalid NFS mount path."
+msgstr "æ æçNFSæè½½è·¯å¾ã"
+
+msgid "No logical device selected."
+msgstr "没æéæ©é»è¾è®¾å¤ã"
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSIç®æ ä¸è½ä¸ºç©ºã"
+
+msgid "Server name can not be blank."
+msgstr "æå¡å¨ä¸è½ä¸ºç©ºã"
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr "è¿ä¸æ¯ä½ 个ææçæå¡å¨åç§°æIPå°åï¼è¯·å¯¹å
¶è¿è¡ä¿®æ¹ã"
+
+msgid "Looking for available partitions ..."
+msgstr "æ¥æ¾ææçååº ..."
+
+msgid "No available partitions found."
+msgstr "没æåç°æ¨¡æ¿ã"
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr "对äºéæä¹
å卿± ï¼è¿ä¸ªæä½å°ä¼æ°¸ä¹
å é¤å卿± è䏿¯åç¨ãæ¯å¦ç»§ç»ï¼"
+
+msgid "Unable to retrieve partitions information."
+msgstr "æªè½æ¾å°ååºä¿¡æ¯ã"
+
+msgid "In progress..."
+msgstr "æ£å¨è¿è¡..."
+
+msgid "Failed!"
+msgstr "失败ï¼"
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr "CDROMè·¯å¾éè¦ä¸ä¸ªææçæ¬å°/è¿ç¨è·¯å¾ä¸ä¸è½ä¸ºç©ºã"
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "å卿± æå·ä¸è½ä¸ºç©º"
+
+#, fuzzy
+msgid "Filter"
+msgstr "è¿æ»¤å¨"
+
+msgid "Network Name"
+msgstr "ç½ç»åç§°"
+
+msgid "State"
+msgstr "ç¶æ"
+
+msgid "Network Type"
+msgstr "ç½ç»ç±»å"
+
+msgid "Address Space"
+msgstr "å°å空é´"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "ååä¸ä¸è½å
å«â/âå'\"'ã"
+
+msgid "Isolated: no external network connection"
+msgstr "é离: åç©çç½ç»ä¸è¿é"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: ä»èææºå°ç©çç½ç»ååè¿æ¥"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "æ¡¥æ¥ï¼èææºå¯ä»¥ç´æ¥è¿æ¥å°ç©çç½ç»ä¸ã"
+
+msgid "(No interfaces found)"
+msgstr "(没æåç°ç½ç»æ¥å£)"
+
+msgid "Destination"
+msgstr "ç®æ 设å¤"
+
+msgid "Enable VLAN"
+msgstr "å¯ç¨VLAN"
+
+msgid "VLAN ID"
+msgstr "VLANå·"
+
+msgid "Stop"
+msgstr "忢"
+
+msgid "Generate a New Debug Report"
+msgstr "产çä¸ä¸ªæ°çè¯ææ¥å"
+
+msgid "Report Name"
+msgstr "è¯ææ¥åå"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"ååç¨æ¥æ è¯è¯ææ¥åã妿çç¥ï¼å°ä¼åºäºå½åæ¶é´çæä¸ä¸ªæ°ååãååä¸å¯ä»¥å
"
+"å«åæ¯ãæ°åãä¸å线 ('_') åè¿å符ï¼'-'ï¼"
+
+msgid "Rename a Debug Report"
+msgstr "éå½åä¸ä¸ªè°è¯æ¥å"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr "æ¥åçå¯ä¸è¡¨ç¤ºåç§°ï¼åç§°å¯ä»¥å
å«ï¼è±æåç¬¦ï¼æ°ååè¿å符(\"-\")ã"
+
+msgid "Submit"
+msgstr "æäº¤"
+
+msgid "Add a Repository"
+msgstr "å¢å ä¸ä¸ªè½¯ä»¶ä»åº"
+
+msgid "Identifier"
+msgstr "æ è¯ç¬¦"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "ä¸ä¸ªåè¯ï¼å¯ä¸æ è¯è½¯ä»¶ä»åº"
+
+msgid "Textual name for the repository."
+msgstr "软件ä»åºçåé¢åå"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "å¿
éçåæ®µ"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "软件ä»åºçURLï¼æ¯æçåè®®æhttpãftpãåfile"
+
+msgid "Repository is a mirror"
+msgstr "软件ä»åºæ¯ä¸ä¸ªéå"
+
+msgid "Distribution"
+msgstr "åè¡ç"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEBä»åºçåè¡ç"
+
+msgid "Components"
+msgstr "ç»ä»¶"
+
+msgid "List of components in DEB repository."
+msgstr "DEBä»åºä¸çç»ä»¶å表"
+
+msgid "Edit Repository"
+msgstr "ä¿®æ¹è½¯ä»¶ä»åº"
+
+msgid "Mirror List URL"
+msgstr "éåå表URL"
+
+msgid "Yes"
+msgstr "æ¯"
+
+msgid "No"
+msgstr "å¦"
+
+msgid "Capacity"
+msgstr "容é"
+
+msgid "Allocated"
+msgstr "å·²åé
"
+
+msgid "Location"
+msgstr "è·¯å¾"
+
+msgid "Device path"
+msgstr "设å¤è·¯å¾"
+
+msgid "active"
+msgstr "å·²æ¿æ´»"
+
+msgid "inactive"
+msgstr "æªæ¿æ´»"
+
+msgid "Deactivate"
+msgstr "åç¨"
+
+msgid "Activate"
+msgstr "æ¿æ´»"
+
+msgid "Add Volume"
+msgstr "æ·»å å·"
+
+msgid "Extend"
+msgstr "æ©å±"
+
+msgid "Undefine"
+msgstr "åæ¶å®ä¹"
+
+msgid "Format"
+msgstr "æ ¼å¼"
+
+msgid "Allocation"
+msgstr "åé
"
+
+msgid "Define a New Storage Pool"
+msgstr "å®ä¹ä¸ä¸ªæ°çå卿± "
+
+msgid "Storage Pool Name"
+msgstr "å卿± åç§°"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "该åç§°ç¨æ¥å¯ä¸æ è¯å卿± ï¼è¯¥åç§°ä¸è½ä¸ºç©ºã"
+
+msgid "Storage Pool Type"
+msgstr "å卿± ç±»å"
+
+msgid "Storage Path"
+msgstr "åå¨è·¯å¾"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr "å卿± çè·¯å¾.æ¯ä¸ªå卿± çè·¯å¾æ¯å¯ä¸çã"
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr "妿ç®å½ä¸åå¨ï¼KIMCHIä¼èªå¨å¨ç³»ç»ä¸å建ä¸ä¸ªæ°çç®å½"
+
+msgid "NFS Server IP"
+msgstr "NFSæå¡å¨IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr "NFSæå¡å¨IPæè
主æºåï¼å¯ä»¥ç´æ¥è¾å
¥æè
ä»åå²è®°å½ä¸éåã"
+
+msgid "NFS Path"
+msgstr "NFS è·¯å¾"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFSæå¡å¨ä¸å¯¼åºçNFSè·¯å¾"
+
+msgid "iSCSI Server"
+msgstr "iSCSIæå¡å¨"
+
+msgid "Server"
+msgstr "æå¡å¨"
+
+msgid "Port"
+msgstr "端å£"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSIæå¡å¨IPæè
主æºåï¼ ä¸è½ä¸ºç©ºã"
+
+msgid "Target"
+msgstr "ç®æ "
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSIç®æ "
+
+msgid "Add iSCSI Authentication"
+msgstr "æ·»å ISCSI认è¯"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI认è¯"
+
+msgid "User Name"
+msgstr "ç¨æ·å"
+
+msgid "Password"
+msgstr "å¯ç "
+
+msgid "SCSI Adapter"
+msgstr "SCSIéé
å¨"
+
+msgid "Please, wait..."
+msgstr "请çå¾
..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr "为å卿± æ·»å ä¸ä¸ªå·"
+
+msgid "Fetch from remote URL"
+msgstr "ä»è¿ç¨URLè·å"
+
+msgid "Enter the remote URL here."
+msgstr "å¨è¿éè¾å
¥è¿ç¨URLã"
+
+msgid "Upload a file"
+msgstr "ä¸ä¼ ä¸ä¸ªæä»¶"
+
+msgid "Choose the file you want to upload."
+msgstr "éæ©éè¦ä¸ä¼ çæä»¶ã"
+
+msgid "Add Template"
+msgstr "å建模æ¿"
+
+msgid "Where is the source media for this template? "
+msgstr "模æ¿çæºä»è´¨å¨åªéï¼"
+
+msgid "Local ISO Image"
+msgstr "æ¬å°ISOéå"
+
+msgid "Local Image File"
+msgstr "æ¬å°éåæä»¶"
+
+msgid "Remote ISO Image"
+msgstr "è¿ç¨ISOéå"
+
+msgid "Search ISOs"
+msgstr "æç´¢ISO"
+
+msgid "The following ISOs are available:"
+msgstr "å¯ç¨ISOæä»¶å¦ä¸"
+
+msgid "OS: "
+msgstr "æä½ç³»ç»ï¼ "
+
+msgid "Version: "
+msgstr "çæ¬ï¼ "
+
+msgid "Size: "
+msgstr "大å°ï¼"
+
+msgid "Search more ISOs"
+msgstr "æç´¢æ´å¤ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "ä»éä¸çISOä¸å建模æ¿"
+
+msgid "I want to use a specific ISO file"
+msgstr "æå®ä¸ä¸ªISOæä»¶"
+
+msgid "Loading default remote ISOs ..."
+msgstr "å è½½é»è®¤çè¿ç¨ISOs ..."
+
+msgid "Arch: "
+msgstr "ä½ç³»ç»æï¼"
+
+msgid "I want to use a custom URL"
+msgstr "ææ³ç¨ä¸ä¸ªèªå®ä¹çURL"
+
+msgid "Edit Template"
+msgstr "ç¼è¾æ¨¡æ¿"
+
+msgid "CDROM"
+msgstr "å
驱"
+
+msgid "Image File"
+msgstr "éåæä»¶"
+
+msgid "Graphics"
+msgstr "å¾å½¢"
+
+msgid "Disk(GB)"
+msgstr "ç£ç(GB)"
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU个æ°"
+
+msgid "Manually set CPU topology"
+msgstr "æå¨é
ç½®CPUææ"
+
+msgid "Cores"
+msgstr "å
æ ¸æ°"
+
+msgid "Threads"
+msgstr "线ç¨"
+
+msgid "No templates found."
+msgstr "没æåç°æ¨¡æ¿"
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "ä¸å
许å é¤%(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "䏿¯ææ´æ°%(resource)s"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "ä¸å
许å建%(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "æ æ³è§£æJSON请æ±"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "è¿ä¸ªAPIä»
æ¯æJSON"
+
+#~ msgid "Parameters does not match requirement in schema: %(err)s"
+#~ msgstr "åæ°ä¸ç¬¦åè¦æ±çæ ¼å¼ï¼%(err)s"
+
+#~ msgid "You don't have permission to perform this operation."
+#~ msgstr "æ¨æ²¡ææéæ§è¡è¿é¡¹æä½ã"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "å°æªä¸ºmodel对象åå§åæ°æ®åå¨ã"
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "ç±äºé误%(err)sä»»å¡å¯å¨å¤±è´¥"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr "ç¨æ·'%(username)s'身份éªè¯å¤±è´¥.[é误代ç ï¼%(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "æ¨æ²¡æè¢«ææè®¿é®Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "æå®ç»å½Kimchiç%(item)s"
+
+#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
+#~ msgstr "æ æçLDAPé
ç½®ï¼%(item)s : %(value)s"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "卿°æ®åå¨ä¸æ¾ä¸å°%(item)s"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr "å½ä»¤'%(cmd)s'è¿è¡%(seconds)sç§åè¶
æ¶ã"
+
+#~ msgid "Peers"
+#~ msgstr "å¯¹çæº"
+
+#~ msgid "Searching"
+#~ msgstr "æ£å¨æ¥è¯¢"
+
+#~ msgid "No peers found."
+#~ msgstr "没æåç°å¯¹çæºã"
+
+#~ msgid "Help"
+#~ msgstr "帮å©"
+
+#~ msgid "About"
+#~ msgstr "å
³äº"
+
+#~ msgid "Log out"
+#~ msgstr "ç»åº"
+
+#~ msgid "Version:"
+#~ msgstr "çæ¬ï¼"
+
+#~ msgid "Session timeout, please re-login."
+#~ msgstr "ç»å½è¶
æ¶ï¼è¯·éæ°ç»å½ã"
diff --git a/src/wok/plugins/kimchi/po/zh_TW.po b/src/wok/plugins/kimchi/po/zh_TW.po
new file mode 100644
index 0000000..90045b5
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/zh_TW.po
@@ -0,0 +1,2138 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_TW\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task '%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or \"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "åå¾åå¡è£ç½®æç¼çé¯èª¤ãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "åå¾ %(device)s çåå¡è£ç½®è³è¨æç¼çé¯èª¤ã"
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "æ¾ä¸å° distro æªæ¡ï¼%(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr "ç¡æ³åæ distro æªæ¡ï¼%(filename)sãè«ç¢ºä¿å®æ¯ JSON æªæ¡ã"
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "ç¡æ³ç»å
¥ iSCSI 主æ©ç®æ¨ %(portal)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "ç¡æ³ç»å
¥ iSCSI ä¸»æ© %(host)s ç®æ¨ %(target)s"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISO æªæ¡ %(filename)s ä¸å¯éæ©"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "ISO æªæ¡ %(filename)s æ²æææç El Torito éæ©è¨é"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "ISO %(filename)s ä¸æç¡æç El Torito é©èé
ç®"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ISO %(filename)s ä¸æç¡æç El Torito ååæç¤ºå¨"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "ISO %(filename)s 䏿䏻è¦ç£ç¢åçéé æç£åé¡å"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "è®å ISO %(filename)s ä¸çç£åæè¿°åæéå°ä¸ç¶çæ ¼å¼"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the '%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"Hypervisor æ²æä½¿ç¨æ¤ ISO %(filename)s çè¨±å¯æ¬ãè«èéå°å
¶ç§»åè³ /var/lib/"
+"libvirt ä¸ãå°æå°è¨±å¯æ¬è¨çº'%(user)s' 使ç¨è
çæªæ¡ååæ§å¶æ¸
å®ï¼è¥æå¯è½ï¼ã"
+"å° '%(user)s' æ°å¢è³ ISO è·¯å¾ç¾¤çµæï¼å»ºè°ä¸è¦å·è¡æ¤åä½ï¼å·è¡ 'chmod -R o+x "
+"'path_to_iso'ãè©³ç´°è³æï¼%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "èæ¬æ©å¨ %(name)s å·²åå¨"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "èæ¬æ©å¨ %(name)s ä¸åå¨"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "ç¡æ³æ·åå·²åæ¢èæ¬æ©å¨ %(name)s çç«é¢"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "æ¤ä¼ºæå¨ä¸æ¯æ´é 端 ISO æ åæªã"
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³å»ºç«èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³å»ºç«èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³æ·åèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "è¦æ¥è½çåå½¢å¡ä½åå¿
é æ¯ IPv4 æ IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "æå®ç¨æ¼å»ºç«èæ¬æ©å¨çç¯æ¬"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³ååèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³åæ¢èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³åªé¤èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³éæ°å½åèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "網路å稱å¿
é æ¯å串"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "網路å稱å¿
é æ¯å串"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "使ç¨è
'%(users)s' ä¸åå¨ã"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "使ç¨è
'%(groups)s' ä¸åå¨ã"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³åæ¢èæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "ç¡æ³ååèæ¬æ©å¨ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with "
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus "
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >= "
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on "
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt "
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "ä»é¢ %(iface)s ä¸å卿¼èæ¬æ©å¨ %(name)s ä¸"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr "çºèæ¬æ©å¨ %(name)s æå®ç網路 %(network)s ä¸åå¨"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "å¯ä¸åæ¯æ´çèæ¬æ©å¨ä»é¢é¡åæ¯ç¶²è·¯"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "èæ¬æ©å¨ä»é¢ç網路å稱å¿
é æ¯å串"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr "çºèæ¬æ©å¨ä»é¢æå®ç網路模åå¡ç¡æ"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "æå®é¡åå網路以æ°å¢èæ¬æ©å¨ä»é¢"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "ç¯æ¬ %(name)s å·²åå¨"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not exist"
+msgstr "çºç¯æ¬ %(template)s æå®ç網路 '%(network)s' ä¸åå¨"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr "çºç¯æ¬ %(template)s æå®çå²åå '%(pool)s' ä¸åå¨"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not active"
+msgstr "çºç¯æ¬ %(template)s æå®çå²åå '%(pool)s' æªèæ¼ä½ç¨ä¸çæ
"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "çº CDROM æå®ç忏 '%(param)s' ç¡æã"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "çºç¯æ¬ %(template)s æå®ç網路 %(network)s æªèæ¼ä½ç¨ä¸çæ
"
+
+msgid "Template name must be a string"
+msgstr "ç¯æ¬å稱å¿
é æ¯å串"
+
+msgid "Template icon must be a path to the image"
+msgstr "ç¯æ¬å示å¿
é æ¯å½±åçè·¯å¾"
+
+msgid "Template distribution must be a string"
+msgstr "ç¯æ¬ç¼è¡å¥ä»¶å¿
é æ¯å串"
+
+msgid "Template distribution version must be a string"
+msgstr "ç¯æ¬ç¼è¡çæ¬å¿
é æ¯å串"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPU æ¸ç®å¿
é æ¯æ´æ¸"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "è¨æ¶é«æ¸é (MB) å¿
é æ¯å¤§æ¼ 512 çæ´æ¸"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "ç¯æ¬ CDROM å¿
é æ¯æ¬ç«¯æé 端 ISO æªæ¡"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "çºç¯æ¬æå®çå²åå URI %(value)s ç¡æ"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "æå® ISO æ åæªä½çº CDROM 以建ç«ç¯æ¬"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "ç¯æ¬çææç¶²è·¯é½å¿
é 卿¸
å®ä¸æå®ã"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³å»ºç«ç¯æ¬ï¼%(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³åªé¤ç¯æ¬ï¼%(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "ç¯æ¬ CDROM å¿
é æ¯æ¬ç«¯æé 端 ISO æªæ¡"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and "
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "å²åå %(name)s å·²åå¨"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "å²åå %(name)s ä¸åå¨"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "æå® %(item)s 以建ç«å²åå %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "ç¡æ³åªé¤ä½ç¨ä¸çå²åå %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "ç¡æ³ååºå²ååãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "ç¡æ³å»ºç«å²åå %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr "ç¡æ³åå¾å²åå %(name)s ä¸å²åç£åçæ¸ç®ãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "ç¡æ³ååå²åå %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "ç¡æ³åæ¶ååå²åå %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "ç¡æ³åªé¤å²åå %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr "ç¡æ³å»ºç« NFS å²ååï¼å çºå¨è£è¼æéï¼å¯åºè·¯å¾ %(path)s å¯è½æå°é"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr "ç¡æ³å»ºç« NFS å²ååï¼å çºå¯åºè·¯å¾ %(path)s è£è¼å¤±æ"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "ä¸åæ¯æ´çå²ååé¡åï¼%(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "å²ååè·¯å¾å¿
é æ¯å串"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "å²åå主æ©å¿
é æ¯ IP æä¸»æ©å稱"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "å²ååè£ç½®åæ¸å¿
é æ¯æ¸
å®"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSI å²ååçç®æ¨ IQN å¿
é æ¯å串"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "é 端å²åé«ä¼ºæå¨çå å¿
é æ¯ä»æ¼ 1 å 65535 ä¹éçæ´æ¸"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "æå®å稱åé¡å以建ç«å²åå"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr "%(disk)s 䏿¯ææçç£ç¢/åå²åãç¡æ³å°å®æ°å¢è³å²åå%(pool)sã"
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "åªè½éå°é輯å²ååæ´æ°ãå
éç£ç¢ã忏ã"
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI 主æ©é
æ¥å¡å稱å¿
é æ¯å串ã"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "å²åå kimchi_isos ä¿çä¾å
§é¨ä½¿ç¨"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr "ç¡æ³åå NFS å²åå %(name)sãNFS 伺æå¨ %(server)sç¡æ³é£ç·ã"
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr "ç¡æ³åæ¶åå NFS å²åå %(name)sãNFS 伺æå¨ %(server)sç¡æ³é£ç·ã"
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr "ç¡æ³åæ¶ååå²åå %(name)sï¼å çºå®èé¨åç¯æ¬ç¸éè¯"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "ç¡æ³åªé¤å²åå %(name)sï¼å çºå®èé¨åç¯æ¬ç¸éè¯"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name "
+"to create the logical pool."
+msgstr "åçº '%(name)s' çç£å群çµå·²åå¨ãè«é¸æå¦ä¸åå稱以建ç«é輯å²ååã"
+
+#, python-format
+msgid "Unable to update database with deep scan information due error: %(err)s"
+msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³ä½¿ç¨æ·±å±¤ææè³è¨ä¾æ´æ°è³æåº«ï¼%(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "å²åç£å %(name)s å·²åå¨"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "å²åç£å %(name)s ä¸å卿¼å²åå %(pool)s ä¸"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "æå® %(item)s 以建ç«å²åç£å %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr "ç¡æ³ååºå²åç£åï¼å çºå²åå %(pool)s æªèæ¼ä½ç¨ä¸çæ
"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details: %"
+"(err)s"
+msgstr "ç¡æ³å¨å²åå %(pool)s ä¸å»ºç«å²åç£å %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr "ç¡æ³ååºå²åå %(pool)s ä¸çå²åç£åãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "ç¡æ³æ¸
é¤å²åç£å %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "ç¡æ³åªé¤å²åç£å %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "ç¡æ³èª¿æ´å²åç£å %(name)s ç大å°ãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "å²åé«é¡å %(type)s 䏿¯æ´ç£å建ç«ååªé¤"
+
+msgid "Storage volume name must be a string"
+msgstr "å²åç£åå稱å¿
é æ¯å串"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "å²åç£åé
ç½®å¿
é æ¯æ´æ¸"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "å²åç£åéè¦ç£åå稱"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³ä½¿ç¨å²åç£åè³è¨ä¾æ´æ°è³æåº«ï¼%(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'. Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload' parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "ä»é¢ %(name)s ä¸åå¨"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "網路 %(name)s å·²åå¨"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "網路 %(name)s ä¸åå¨"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr "çºç¶²è·¯ %(network)s æå®çå網路 %(subnet)s ç¡æã"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "æå®ç¶²è·¯ä»é¢ä»¥å»ºç«æ©æ¥ç網路 %(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "ç¡æ³åªé¤ä½ç¨ä¸ç網路 %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in use"
+msgstr "çºç¶²è·¯ %(network)s æå®çä»é¢ %(iface)s å·²å¨ä½¿ç¨ä¸"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "ä»é¢æè©²æ¯è£¸é² NICãæ¥åè£ç½®ææ©æ¥å¨è£ç½®ã"
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "ç¡æ³å»ºç«ç¶²è·¯ %(name)sãè©³ç´°è³æï¼%(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "æ¾ä¸å°ç¶²è·¯ '%(name)s' çå¯ç¨ IP ä½å"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "忝æ´ç網路é¡åæ¯éé¢å¼ãNAT åæ©æ¥å¨"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr "網路çå網路å¿
é æ¯å«æ IP ä½åãåé¦æç¶²è·¯é®ç½©çå串"
+
+msgid "Network interface must be a string"
+msgstr "網路ä»é¢å¿
é æ¯å串"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "網路 VLAN ID å¿
é æ¯ä»æ¼ 1 å 4094 ä¹éçæ´æ¸"
+
+msgid "Specify name and type to create a Network"
+msgstr "æå®å稱åé¡å以建ç«ç¶²è·¯"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines %(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "æ©æ¥å¨è£ç½® %(name)s ä¸è½æ¯ VLAN çå¹¹ç·è£ç½®ã"
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "ç¡æ³ååä»é¢ %(iface)sï¼%(err)sã"
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr "ç¡æ³ååä»é¢ %(iface)sãè«æª¢æ¥å¯¦ééçµçæ
ã"
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "é¤é¯å ±å %(name)s ä¸åå¨"
+
+msgid "Debug report tool not found in system"
+msgstr "å¨ç³»çµ±ä¸æ¾ä¸å°é¤é¯å ±åå·¥å
·"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "ç¡æ³å»ºç«é¤é¯å ±å %(name)sãè©³ç´°è³æï¼%(err)sã"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "ç¡æ³ç¢çé¤é¯å ±å %(name)sãè©³ç´°è³æï¼%(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_') "
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please use "
+"another one."
+msgstr "åçº '%(name)s' çç£å群çµå·²åå¨ãè«é¸æå¦ä¸åå稱以建ç«é輯å²ååã"
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Kimchi æªä½¿ç¨å²åé«ä¼ºæå¨ %(server)s"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' ä¸åå¨"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "åå²å %(name)s ä¸å卿¼ä¸»æ©ä¸"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr "ç¡æ³éé主æ©ï¼å çºæä¸äºèæ¬æ©å¨æ£å¨å·è¡ä¸"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "ç¡æ³å°ä¸»æ©éæ°éæ©ï¼å çºæä¸äºèæ¬æ©å¨æ£å¨å·è¡ä¸"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "æ¾ä¸å°ç¯é»è£ç½® '%(name)s'"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "æ²æå¥ä»¶æ¨ç¤ºçºè¦é²è¡æ´æ°"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "å¥ä»¶ %(name)s æªæ¨ç¤ºçºè¦é²è¡æ´æ°ã"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr "å徿¨ç¤ºçºè¦é²è¡æ´æ°çå¥ä»¶æç¼çé¯èª¤ãè©³ç´°è³æï¼%(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "æ²ææ¤ç³»çµ±çç¸å®¹å¥ä»¶ç®¡çç¨å¼ã"
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s ç¡æ"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "å²åé«é¡åç¡æã忝æ´çé¡åï¼'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "å»ºç«æ°çå²åè£ç½®æç¼çé¯èª¤ï¼%(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "æ´æ°å²åè£ç½®æç¼çé¯èª¤ï¼%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "ç§»é¤å²åè£ç½®æç¼çé¯èª¤ï¼%(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "æå®é¡ååè·¯å¾ä»¥æ°å¢èæ¬æ©å¨ç£ç¢"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "æå®è·¯å¾ä»¥æ´æ°èæ¬æ©å¨ç£ç¢"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "æå®é¡ååè·¯å¾ä»¥æ°å¢èæ¬æ©å¨ç£ç¢"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type %(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM å²å庫 ID å¿
é æ¯å
éä¸åå®åçå串ã"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "å²å庫 URL å¿
é æ¯ http://ãftp:// æ file:// URLã"
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr "å²å庫é
ç½®æ¯åå
¸ï¼å
¶ä¸å
嫿¼å²å庫é¡åå°æçç¹å®å¼ã"
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "DEB å²å庫çç¼è¡å¥ä»¶å¿
é æ¯å串"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "DEB å²å庫çå
ä»¶å¿
é 以é£åçå½¢å¼ååº"
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEB å²å庫çå
ä»¶å¿
é æ¯å串"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUM å²å庫å稱å¿
é æ¯å串ã"
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG 檢æ¥å¿
é æ¯å¸æå¼ã"
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG éé°å¿
é æ¯æå ASCII è£ç²æªæ¡ç URLã"
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "ç¡æ³æ´æ°å²å庫 %(repo_id)sã"
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "å²å庫 %(repo_id)s ä¸åå¨ã"
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "æªè½è¾¨è系統çå²å庫管çå·¥å
·ã"
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "å·²åç¨å²å庫 %(repo_id)sã"
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "å·²åç¨å²å庫 %(repo_id)sã"
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "ç¡æ³ç§»é¤å²å庫 %(repo_id)sã"
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "ç¡æ³å¯«å
¥å²å庫é
ç½®æª %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "æå®å²å庫ç¼è¡å¥ä»¶ä»¥å»ºç« DEB å²å庫ã"
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "ç¡æ³åç¨å²å庫 %(repo_id)sã"
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "ç¡æ³åç¨å²å庫 %(repo_id)sã"
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM å²å庫 ID å·²åå¨"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM å²å庫å稱å¿
é æ¯å串"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "ç¡æ³ååºå²å庫ãè©³ç´°è³æï¼'%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "ç¡æ³æ·åå²å庫è³è¨ãè©³ç´°è³æï¼'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "ç¡æ³æ°å¢å²å庫ãè©³ç´°è³æï¼'%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "ç¡æ³ç§»é¤å²å庫ãè©³ç´°è³æï¼'%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine '%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'. Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a "
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "é¯èª¤ç¢¼"
+
+msgid "REASON"
+msgstr "åå "
+
+msgid "STACK"
+msgstr "å ç"
+
+msgid "Go to Homepage"
+msgstr "è·³è³é¦é "
+
+msgid "Create a New Virtual Machine"
+msgstr "å»ºç«æ°çèæ¬æ©å¨"
+
+msgid "Virtual Machine Name"
+msgstr "èæ¬æ©å¨å稱"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr "ç¨ä¾èå¥èæ¬æ©å¨çå稱ã妿çç¥ï¼åææ ¹ææç¨çç¯æ¬é¸æå稱ã"
+
+msgid "Template"
+msgstr "ç¯æ¬"
+
+msgid "Please create a template first."
+msgstr "è«å
建ç«ç¯æ¬ã"
+
+msgid "Create a Template"
+msgstr "建ç«ç¯æ¬"
+
+msgid "Please choose a template."
+msgstr "è«é¸æç¯æ¬ã"
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "OS çæ¬"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "è¨æ¶é«"
+
+msgid "Create"
+msgstr "建ç«"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "åæ¶ "
+
+msgid "Edit Guest"
+msgstr "編輯客é«"
+
+msgid "General"
+msgstr "ä¸è¬"
+
+msgid "Storage"
+msgstr "å²åé«"
+
+msgid "Interface"
+msgstr "ä»é¢"
+
+msgid "Permission"
+msgstr "çæ¬"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "å稱"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "è¨æ¶é«"
+
+msgid "Icon"
+msgstr "å示"
+
+msgid "Device"
+msgstr "è£ç½®å稱"
+
+msgid "Path"
+msgstr "NFS è·¯å¾"
+
+msgid "Network"
+msgstr "網路"
+
+msgid "Type"
+msgstr "é¡å"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "å
¨é¨"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "便å"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "å²å"
+
+msgid "Replace"
+msgstr "å代"
+
+msgid "Detach"
+msgstr "åé¢"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "éå§"
+
+msgid "Reset"
+msgstr "éè¨"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "åä½"
+
+msgid "Connect"
+msgstr "飿¥"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "編輯"
+
+msgid "Shut Down"
+msgstr "éé"
+
+msgid "Delete"
+msgstr "åªé¤"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "ç£ç¢ I/O"
+
+msgid "Network I/O"
+msgstr "網路 I/O"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "æ¾ä¸å°å®¢é«ã"
+
+msgid "Add a Storage Device to VM"
+msgstr "å°å²åè£ç½®æ°å¢è³ VM"
+
+msgid "Device Type"
+msgstr "è£ç½®é¡å"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are supported."
+msgstr "è£ç½®é¡åãç®åå
æ¯æ´ \"cdrom\"ã"
+
+msgid "Storage Pool"
+msgstr "å²åå"
+
+msgid "Storage pool which volume located in"
+msgstr "å²ååè·¯å¾å¿
é æ¯å串"
+
+msgid "Storage Volume"
+msgstr "å²ååå稱"
+
+msgid "Storage volume to be attached"
+msgstr "å²åç£åå稱å¿
é æ¯å串"
+
+msgid "File Path"
+msgstr "æªæ¡è·¯å¾"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "CDROM ç ISO æªæ¡è·¯å¾å¨ä¼ºæå¨ä¸ã"
+
+msgid "Attach"
+msgstr "飿¥"
+
+msgid "Shut down"
+msgstr "éé"
+
+msgid "Restart"
+msgstr "éæ°åå"
+
+msgid "Basic Information"
+msgstr "åºæ¬è³è¨"
+
+msgid "OS Distro"
+msgstr "OS Distro"
+
+msgid "OS Code Name"
+msgstr "OS ç¨å¼ç¢¼å稱"
+
+msgid "Processor"
+msgstr "èçå¨"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "系統統è¨è³æ"
+
+msgid "Software Updates"
+msgstr "è»é«æ´æ°"
+
+msgid "Update Progress"
+msgstr "æ´æ°é²åº¦"
+
+msgid "Repositories"
+msgstr "å²å庫"
+
+msgid "Debug Reports"
+msgstr "é¤é¯å ±å"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr "æ¨è¼¸å
¥ç使ç¨è
å稱æå¯ç¢¼ä¸æ£ç¢ºãè«é試ã"
+
+msgid "This field is required."
+msgstr "æ¤æ¬ä½æ¯å¿
è¦çã"
+
+msgid "Log in"
+msgstr "ç»å
¥"
+
+msgid "Logging in..."
+msgstr "æ£å¨ç»å
¥..."
+
+msgid "Host"
+msgstr "主æ©"
+
+msgid "Guests"
+msgstr "客é«"
+
+msgid "Templates"
+msgstr "ç¯æ¬"
+
+msgid "Failed to get application configuration"
+msgstr "ç¡æ³å徿ç¨ç¨å¼é
ç½®"
+
+msgid "This is not a valid Linux path"
+msgstr "éæ¯ç¡æç Linux è·¯å¾"
+
+msgid "This is not a valid URL."
+msgstr "éæ¯ç¡æç URLã"
+
+msgid "No such data available."
+msgstr "æ²ææ¤é¡å¯ç¨è³æã"
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"ç¡æ³é£æ¥è³ä¸»æ©ç³»çµ±ãè«é©è主æ©ç³»çµ±æ¯å¦å·²ååï¼ä»¥åæ¨æ¯å¦å
·æèå®çé£ç·ãHTTP "
+"è¦æ±åæçº %1ã"
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "åªé¤ç¢ºèª"
+
+msgid "OK"
+msgstr "確å®"
+
+msgid "Confirm"
+msgstr "確èª"
+
+msgid "Warning"
+msgstr "è¦å"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "æ£å¨è¼å
¥..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "é試"
+
+msgid "Detailed message:"
+msgstr "詳細çè¨æ¯ï¼"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "éæ¯ç¡æç ISO æªæ¡ã"
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "å®å°éè¦å¾é·æéãè¦ç¹¼çºåï¼"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "æ¤åä½å°æ°¸ä¹
å°åªé¤ç¯æ¬ãè¦ç¹¼çºåï¼"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr "ç¡æ³éé系統ï¼å çºæå¹¾åèæ¬æ©å¨æ£å¨å·è¡ä¸ï¼"
+
+msgid "Max:"
+msgstr "ä¸éï¼"
+
+msgid "Utilization"
+msgstr "使ç¨ç"
+
+msgid "Available"
+msgstr "å¯ç¨"
+
+msgid "Read Rate"
+msgstr "è®åéç"
+
+msgid "Write Rate"
+msgstr "寫å
¥éç"
+
+msgid "Received"
+msgstr "å·²æ¥æ¶"
+
+msgid "Sent"
+msgstr "å·²å³é"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr "ééæéæ°åå主æ©å°å°è´æªå²åçå·¥ä½éºå¤±ãè¦ç¹¼çºéé/éæ°åååï¼"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr "å°ææ°¸ä¹
å°ç§»é¤å²å庫並ä¸ç¡æ³å復ãè¦ç¹¼çºåï¼"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "åºæ¬ URL"
+
+msgid "Is Mirror"
+msgstr "æ¯é¡æ "
+
+msgid "URL Args"
+msgstr "URL 弿¸"
+
+msgid "Enabled"
+msgstr "å·²åç¨"
+
+msgid "GPG Check"
+msgstr "GPG 檢æ¥"
+
+msgid "GPG Key"
+msgstr "GPG éé°"
+
+msgid "Add"
+msgstr "æ°å¢"
+
+msgid "Remove"
+msgstr "ç§»é¤"
+
+msgid "Enable"
+msgstr "åç¨"
+
+msgid "Disable"
+msgstr "åç¨"
+
+msgid "Package Name"
+msgstr "å¥ä»¶å稱"
+
+msgid "Version"
+msgstr "çæ¬"
+
+msgid "Architecture"
+msgstr "æ¶æ§"
+
+msgid "Repository"
+msgstr "å²å庫"
+
+msgid "Update All"
+msgstr "å
¨é¨æ´æ°"
+
+msgid "Updating..."
+msgstr "æ£å¨æ´æ°..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "ç¡æ³æ´æ°å¥ä»¶ã"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want "
+"to continue?"
+msgstr "å°ææ°¸ä¹
å°ç§»é¤é¤é¯å ±å並ä¸ç¡æ³å復ãè¦ç¹¼çºåï¼"
+
+msgid "Generated Time"
+msgstr "ç¢çæé"
+
+msgid "Generate"
+msgstr "ç¢ç"
+
+msgid "Generating..."
+msgstr "æ£å¨ç¢ç..."
+
+msgid "Rename"
+msgstr "éæ°å½å"
+
+msgid "Download"
+msgstr "ä¸è¼"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or "
+"hyphen ('-')."
+msgstr "å ±ååç¨±åªæè©²å
å«åæ¯ãæ¸åå/æé£åè ('-')ã"
+
+msgid "Pending..."
+msgstr "æ£å¨è¼å
¥..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr "æ¤åä½å°æåªé¤èæ¬æ©å¨åå
¶èæ¬ç£ç¢ãæ¤ä½æ¥ç¡æ³å¾©åãè¦ç¹¼çºåï¼"
+
+msgid "Power off Confirmation"
+msgstr "åªé¤ç¢ºèª"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "åªé¤ç¢ºèª"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "åªé¤ç¢ºèª"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "æ¤åä½å°æ°¸ä¹
å°åªé¤ç¯æ¬ãè¦ç¹¼çºåï¼"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"å°ææ°¸ä¹
å°å颿¤ CDROMï¼ä½æ¯æ¨å¯ä»¥å°å
¶éæ°é£æ¥ãè¦ç¹¼çºå颿¤ CDROM åï¼"
+
+msgid "Attaching..."
+msgstr "æ£å¨é£æ¥..."
+
+msgid "Replacing..."
+msgstr "æ£å¨å代..."
+
+msgid "Successfully attached!"
+msgstr "å·²é å©é£æ¥ï¼"
+
+msgid "Successfully replaced!"
+msgstr "å·²é å©å代ï¼"
+
+msgid "Successfully detached!"
+msgstr "å·²é å©åé¢ï¼"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to "
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN ID å¿
é 仿¼ 1 å 4094 ä¹éã"
+
+msgid "unavailable"
+msgstr "ç¡æ³ä½¿ç¨"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that "
+"depend on this network."
+msgstr "æ¤åä½å°æå²æ·ä¾è³´æ¼æ¤ç¶²è·¯ä¹ææèæ¬æ©å¨ç網路é£ç·åè½ã"
+
+msgid "Create a network"
+msgstr "建ç«ç¶²è·¯"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"æ¤å²åå䏿¯æçºæ§çãæ¤åä½ä¸æ¯æå°å
¶åæ¶ååï¼èæ¯æå°å
¶æ°¸ä¹
å°åªé¤ãè¦ç¹¼çº"
+"åï¼"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "æ¤åä½å°æ°¸ä¹
å°åªé¤å²ååãè¦ç¹¼çºåï¼"
+
+msgid "This storage pool is empty."
+msgstr "æ¤å²ååæ¯ç©ºçã"
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr "æ¤åä½ææ ¼å¼åæ¨çç£ç¢ï¼èæ¨å°æéºå¤±ç£ç¢ä¸çææè³æã確å®è¦ç¹¼çºåï¼"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI å
çºéé"
+
+msgid "No SCSI adapters found."
+msgstr "æ¾ä¸å° SCSI é
æ¥å¡ã"
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "å²ååå稱ä¸è½ç©ºç½ã"
+
+msgid "The storage pool path can not be blank."
+msgstr "å²ååè·¯å¾ä¸è½ç©ºç½ã"
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFS 伺æå¨è£è¼è·¯å¾ä¸è½ç©ºç½ã"
+
+msgid "Invalid NFS mount path."
+msgstr "NFS è£è¼è·¯å¾ç¡æã"
+
+msgid "No logical device selected."
+msgstr "æªé¸åé輯è£ç½®ã"
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSI ç®æ¨ä¸è½ç©ºç½ã"
+
+msgid "Server name can not be blank."
+msgstr "伺æå¨å稱ä¸è½ç©ºç½ã"
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "æ£å¨å°æ¾å¯ç¨çåå²å ..."
+
+msgid "No available partitions found."
+msgstr "æ¾ä¸å°å¯ç¨çåå²åã"
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"æ¤å²åå䏿¯æçºæ§çãæ¤åä½ä¸æ¯æå°å
¶åæ¶ååï¼èæ¯æå°å
¶æ°¸ä¹
å°åªé¤ãè¦ç¹¼çº"
+"åï¼"
+
+msgid "Unable to retrieve partitions information."
+msgstr "ç¡æ³æ·åå²å庫è³è¨ãè©³ç´°è³æï¼'%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "å²ååå稱ä¸è½ç©ºç½ã"
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "網路å稱"
+
+msgid "State"
+msgstr "çæ
"
+
+msgid "Network Type"
+msgstr "網路é¡å"
+
+msgid "Address Space"
+msgstr "ä½å空é"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "å²åååç¨±ç¡æãå®ä¸æè©²å
å« '/'ã"
+
+msgid "Isolated: no external network connection"
+msgstr "å·²éé¢ï¼æ²æå¯¦é«ç¶²è·¯é£ç·"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NATï¼å
éåºå 實é«ç¶²è·¯é£ç·"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "å·²æ©æ¥ï¼èæ¬æ©å¨ç´æ¥å·²é£æ¥è³å¯¦é«ç¶²è·¯"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "ç®çå°ï¼"
+
+msgid "Enable VLAN"
+msgstr "åç¨ VLANï¼"
+
+msgid "VLAN ID"
+msgstr "VLAN IDï¼"
+
+msgid "Stop"
+msgstr "忢"
+
+msgid "Generate a New Debug Report"
+msgstr "ç¢çæ°çé¤é¯å ±å"
+
+msgid "Report Name"
+msgstr "å ±åå稱"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore (\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"ç¨ä¾èå¥å ±åçå稱ã妿çç¥ï¼åææ ¹æç¾è¡æé鏿å稱ãå稱å¯ä»¥å
å«ï¼åæ¯ã"
+"æ¸ååé£åè (\"-\")ã"
+
+msgid "Rename a Debug Report"
+msgstr "ç¢çæ°çé¤é¯å ±å"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"ç¨ä¾èå¥å ±åçå稱ã妿çç¥ï¼åææ ¹æç¾è¡æé鏿å稱ãå稱å¯ä»¥å
å«ï¼åæ¯ã"
+"æ¸ååé£åè (\"-\")ã"
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "æ°å¢å²å庫"
+
+msgid "Identifier"
+msgstr "ID"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "å®åï¼å²å庫çå¯ä¸ IDã"
+
+msgid "Textual name for the repository."
+msgstr "å²å庫çæåå稱ã"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "å¿
è¦æ¬ä½"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "å²å庫ç URLã忝æ´çéè¨åå®å
æ¬ httpãftp å fileã"
+
+msgid "Repository is a mirror"
+msgstr "å²å庫æ¯é¡æ ã"
+
+msgid "Distribution"
+msgstr "ç¼è¡å¥ä»¶"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEB å²å庫çç¼è¡å¥ä»¶ã"
+
+msgid "Components"
+msgstr "å
ä»¶"
+
+msgid "List of components in DEB repository."
+msgstr "DEB å²å庫ä¸çå
ä»¶æ¸
å®ã"
+
+msgid "Edit Repository"
+msgstr "編輯å²å庫"
+
+msgid "Mirror List URL"
+msgstr "顿 æ¸
å® URL"
+
+msgid "Yes"
+msgstr "æ¯"
+
+msgid "No"
+msgstr "å¦"
+
+msgid "Capacity"
+msgstr "容é"
+
+msgid "Allocated"
+msgstr "å·²é
ç½®"
+
+msgid "Location"
+msgstr "ä½ç½®"
+
+msgid "Device path"
+msgstr "è£ç½®è·¯å¾"
+
+msgid "active"
+msgstr "ä½ç¨ä¸"
+
+msgid "inactive"
+msgstr "éä½ç¨ä¸"
+
+msgid "Deactivate"
+msgstr "åæ¶åå"
+
+msgid "Activate"
+msgstr "åå"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "åæ¶å®ç¾©"
+
+msgid "Format"
+msgstr "æ ¼å¼ï¼"
+
+msgid "Allocation"
+msgstr "é
ç½®ï¼"
+
+msgid "Define a New Storage Pool"
+msgstr "å®ç¾©æ°çå²åå"
+
+msgid "Storage Pool Name"
+msgstr "å²ååå稱"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "ç¨ä¾èå¥å²ååçå稱ï¼ä¸æè©²æ¯ç©ºçã"
+
+msgid "Storage Pool Type"
+msgstr "å²ååé¡å"
+
+msgid "Storage Path"
+msgstr "å²åé«è·¯å¾"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr "å²ååçè·¯å¾ãæ¯ä¸åå²ååé½å¿
é æä¸åå¯ä¸çè·¯å¾ã"
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr "Kimchi å°å試建ç«è©²ç®éï¼ç¶è©²ç®éå°ä¸å卿¼ç³»çµ±ä¸æï¼ã"
+
+msgid "NFS Server IP"
+msgstr "NFS 伺æå¨ IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr "NFS 伺æå¨ IP æä¸»æ©å稱ãå¯ä»¥ç´æ¥è¼¸å
¥ï¼ä¹å¯ä»¥å¾æ·ç¨ä¸é¸æã"
+
+msgid "NFS Path"
+msgstr "NFS è·¯å¾"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFS 伺æå¨ä¸ NFS å¯åºçè·¯å¾ã"
+
+msgid "iSCSI Server"
+msgstr "iSCSI 伺æå¨"
+
+msgid "Server"
+msgstr "伺æå¨"
+
+msgid "Port"
+msgstr "å "
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSI 伺æå¨ IP æä¸»æ©å稱ãå®ä¸æè©²æ¯ç©ºçã"
+
+msgid "Target"
+msgstr "ç®æ¨"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSI 伺æå¨ä¸ç iSCSI ç®æ¨"
+
+msgid "Add iSCSI Authentication"
+msgstr "æ°å¢ iSCSI éå¥"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI éå¥"
+
+msgid "User Name"
+msgstr "使ç¨è
å稱"
+
+msgid "Password"
+msgstr "å¯ç¢¼"
+
+msgid "SCSI Adapter"
+msgstr "SCSI é
æ¥å¡"
+
+msgid "Please, wait..."
+msgstr "è«ç¨å..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "æ°å¢ç¯æ¬"
+
+msgid "Where is the source media for this template? "
+msgstr "æ¤ç¯æ¬ç便ºåªé«ä½æ¼ä½èï¼"
+
+msgid "Local ISO Image"
+msgstr "æ¬ç«¯ ISO æ åæª"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "é 端 ISO æ åæª"
+
+msgid "Search ISOs"
+msgstr "æå° ISO"
+
+msgid "The following ISOs are available:"
+msgstr "ä¸å ISO å¯ç¨ï¼"
+
+msgid "OS: "
+msgstr "OSï¼"
+
+msgid "Version: "
+msgstr "çæ¬ï¼"
+
+msgid "Size: "
+msgstr "大å°ï¼"
+
+msgid "Search more ISOs"
+msgstr "æå°æ´å¤ ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "å¾æé¸ ISO 建ç«ç¯æ¬"
+
+msgid "I want to use a specific ISO file"
+msgstr "ææ³ä½¿ç¨ç¹å®ç ISO æªæ¡"
+
+msgid "Loading default remote ISOs ..."
+msgstr "æ£å¨è¼å
¥é è¨é 端 ISO ..."
+
+msgid "Arch: "
+msgstr "æ¶æ§ï¼"
+
+msgid "I want to use a custom URL"
+msgstr "ææ³ä½¿ç¨èªè¨ URL"
+
+msgid "Edit Template"
+msgstr "ç·¨è¼¯ç¯æ¬"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "åå½¢å¡"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU æ¸ç®"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "æ¾ä¸å°ç¯æ¬ã"
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "ä¸å®¹è¨±éå° %(resource)s å·è¡åªé¤"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s æªå¯¦ä½æ´æ°æ¹æ³"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "ä¸å®¹è¨±éå° %(resource)s å·è¡å»ºç«"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "ç¡æ³åæ JSON è¦æ±"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "æ¤ API å
æ¯æ´ JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "æªå¨æ¨¡åç©ä»¶ä¸èµ·å§è³æå²å庫ã"
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "ç±æ¼ä¸åé¯èª¤ï¼ç¡æ³éå§å·¥ä½ï¼%(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code: %(code)s]"
+#~ msgstr "使ç¨è
'%(username)s' çéå¥å¤±æã[é¯èª¤ç¢¼ï¼%(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "æ¨æªç²ææ¬ä¾åå Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "æå® %(item)s 以ç»å
¥ Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "å¨è³æå²ååº«ä¸æ¾ä¸å° %(item)s"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s seconds"
+#~ msgstr "å·è¡æä»¤ '%(cmd)s' %(seconds)s ç§ä¹å¾é¾æ"
+
+#~ msgid "Help"
+#~ msgstr "說æ"
+
+#~ msgid "About"
+#~ msgstr "ç¸é"
+
+#~ msgid "Log out"
+#~ msgstr "ç»åº"
+
+#~ msgid "Version:"
+#~ msgstr "çæ¬ï¼"
diff --git a/src/wok/plugins/kimchi/repositories.py b/src/wok/plugins/kimchi/repositories.py
new file mode 100644
index 0000000..9caabc4
--- /dev/null
+++ b/src/wok/plugins/kimchi/repositories.py
@@ -0,0 +1,529 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import copy
+import os
+import time
+import urlparse
+from ConfigParser import ConfigParser
+
+from wok.basemodel import Singleton
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import OperationFailed, NotFoundError, MissingParameter
+from wok.utils import validate_repo_url
+
+from config import kimchiLock
+from yumparser import get_yum_repositories, write_repo_to_file
+
+
+class Repositories(object):
+ __metaclass__ = Singleton
+
+ """
+ Class to represent and operate with repositories information.
+ """
+ def __init__(self):
+ try:
+ __import__('yum')
+ self._pkg_mnger = YumRepo()
+ except ImportError:
+ try:
+ __import__('apt_pkg')
+ self._pkg_mnger = AptRepo()
+ except ImportError:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ def addRepository(self, params):
+ """
+ Add and enable a new repository
+ """
+ config = params.get('config', {})
+ extra_keys = list(
+ set(config.keys()).difference(set(self._pkg_mnger.CONFIG_ENTRY)))
+ if len(extra_keys) > 0:
+ raise InvalidParameter("KCHREPOS0028E",
+ {'items': ",".join(extra_keys)})
+
+ return self._pkg_mnger.addRepo(params)
+
+ def getRepositories(self):
+ """
+ Return a dictionary with all Kimchi's repositories. Each element uses
+ the format {<repo_id>: {repo}}, where repo is a dictionary in the
+ repositories.Repositories() format.
+ """
+ return self._pkg_mnger.getRepositoriesList()
+
+ def getRepository(self, repo_id):
+ """
+ Return a dictionary with all info from a given repository ID.
+ """
+ info = self._pkg_mnger.getRepo(repo_id)
+ info['repo_id'] = repo_id
+ return info
+
+ def enableRepository(self, repo_id):
+ """
+ Enable a repository.
+ """
+ return self._pkg_mnger.toggleRepo(repo_id, True)
+
+ def disableRepository(self, repo_id):
+ """
+ Disable a given repository.
+ """
+ return self._pkg_mnger.toggleRepo(repo_id, False)
+
+ def updateRepository(self, repo_id, params):
+ """
+ Update the information of a given repository.
+ The input is the repo_id of the repository to be updated and a dict
+ with the information to be updated.
+ """
+ return self._pkg_mnger.updateRepo(repo_id, params)
+
+ def removeRepository(self, repo_id):
+ """
+ Remove a given repository
+ """
+ return self._pkg_mnger.removeRepo(repo_id)
+
+
+class YumRepo(object):
+ """
+ Class to represent and operate with YUM repositories.
+ It's loaded only on those systems listed at YUM_DISTROS and loads necessary
+ modules in runtime.
+ """
+ TYPE = 'yum'
+ DEFAULT_CONF_DIR = "/etc/yum.repos.d"
+ CONFIG_ENTRY = ('repo_name', 'mirrorlist', 'metalink')
+
+ def __init__(self):
+ self._confdir = self.DEFAULT_CONF_DIR
+
+ def _get_repos(self, errcode):
+ try:
+ kimchiLock.acquire()
+ repos = get_yum_repositories()
+ except Exception, e:
+ kimchiLock.release()
+ raise OperationFailed(errcode, {'err': str(e)})
+ finally:
+ kimchiLock.release()
+
+ return repos
+
+ def getRepositoriesList(self):
+ """
+ Return a list of repositories IDs
+ """
+ repos = self._get_repos('KCHREPOS0024E')
+ return repos.keys()
+
+ def getRepo(self, repo_id):
+ """
+ Return a dictionary in the repositories.Repositories() of the given
+ repository ID format with the information of a YumRepository object.
+ """
+ repos = self._get_repos('KCHREPOS0025E')
+
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+
+ info = {}
+ info['enabled'] = entry.enabled
+ info['baseurl'] = entry.baseurl or ''
+ info['config'] = {}
+ info['config']['repo_name'] = entry.name or ''
+ info['config']['gpgcheck'] = entry.gpgcheck
+ info['config']['gpgkey'] = entry.gpgkey or ''
+ info['config']['mirrorlist'] = entry.mirrorlist or ''
+ info['config']['metalink'] = entry.metalink or ''
+ return info
+
+ def addRepo(self, params):
+ """
+ Add a given repository to YumBase
+ """
+ # At least one base url, or one mirror, must be given.
+ baseurl = params.get('baseurl', '')
+
+ config = params.get('config', {})
+ mirrorlist = config.get('mirrorlist', '')
+ metalink = config.get('metalink', '')
+ if not baseurl and not mirrorlist and not metalink:
+ raise MissingParameter("KCHREPOS0013E")
+
+ if baseurl:
+ validate_repo_url(baseurl)
+
+ if mirrorlist:
+ validate_repo_url(mirrorlist)
+
+ if metalink:
+ validate_repo_url(metalink)
+
+ if mirrorlist and metalink:
+ raise InvalidOperation('KCHREPOS0030E')
+
+ repo_id = params.get('repo_id', None)
+ if repo_id is None:
+ repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
+
+ repos = self._get_repos('KCHREPOS0026E')
+ if repo_id in repos.keys():
+ raise InvalidOperation("KCHREPOS0022E", {'repo_id': repo_id})
+
+ repo_name = config.get('repo_name', repo_id)
+ repo = {'baseurl': baseurl, 'mirrorlist': mirrorlist,
+ 'name': repo_name, 'gpgcheck': 1,
+ 'gpgkey': [], 'enabled': 1, 'metalink': metalink}
+
+ # write a repo file in the system with repo{} information.
+ parser = ConfigParser()
+ parser.add_section(repo_id)
+
+ for key, value in repo.iteritems():
+ if value:
+ parser.set(repo_id, key, value)
+
+ repofile = os.path.join(self._confdir, repo_id + '.repo')
+ try:
+ with open(repofile, 'w') as fd:
+ parser.write(fd)
+ except:
+ raise OperationFailed("KCHREPOS0018E",
+ {'repo_file': repofile})
+
+ return repo_id
+
+ def toggleRepo(self, repo_id, enable):
+ repos = self._get_repos('KCHREPOS0011E')
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+ if enable and entry.enabled:
+ raise InvalidOperation("KCHREPOS0015E", {'repo_id': repo_id})
+
+ if not enable and not entry.enabled:
+ raise InvalidOperation("KCHREPOS0016E", {'repo_id': repo_id})
+
+ kimchiLock.acquire()
+ try:
+ if enable:
+ entry.enable()
+ else:
+ entry.disable()
+
+ write_repo_to_file(entry)
+ except:
+ if enable:
+ raise OperationFailed("KCHREPOS0020E", {'repo_id': repo_id})
+
+ raise OperationFailed("KCHREPOS0021E", {'repo_id': repo_id})
+ finally:
+ kimchiLock.release()
+
+ return repo_id
+
+ def updateRepo(self, repo_id, params):
+ """
+ Update a given repository in repositories.Repositories() format
+ """
+ repos = self._get_repos('KCHREPOS0011E')
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+
+ baseurl = params.get('baseurl', None)
+ config = params.get('config', {})
+ mirrorlist = config.get('mirrorlist', None)
+ metalink = config.get('metalink', None)
+
+ if baseurl is not None and len(baseurl.strip()) == 0:
+ baseurl = None
+
+ if mirrorlist is not None and len(mirrorlist.strip()) == 0:
+ mirrorlist = None
+
+ if metalink is not None and len(metalink.strip()) == 0:
+ metalink = None
+
+ if baseurl is None and mirrorlist is None and metalink is None:
+ raise MissingParameter("KCHREPOS0013E")
+
+ if baseurl is not None:
+ validate_repo_url(baseurl)
+ entry.baseurl = baseurl
+
+ if mirrorlist is not None:
+ validate_repo_url(mirrorlist)
+ entry.mirrorlist = mirrorlist
+
+ if metalink is not None:
+ validate_repo_url(metalink)
+ entry.metalink = metalink
+
+ if mirrorlist and metalink:
+ raise InvalidOperation('KCHREPOS0030E')
+
+ entry.id = params.get('repo_id', repo_id)
+ entry.name = config.get('repo_name', entry.name)
+ entry.gpgcheck = config.get('gpgcheck', entry.gpgcheck)
+ entry.gpgkey = config.get('gpgkey', entry.gpgkey)
+ kimchiLock.acquire()
+ write_repo_to_file(entry)
+ kimchiLock.release()
+ return repo_id
+
+ def removeRepo(self, repo_id):
+ """
+ Remove a given repository
+ """
+ repos = self._get_repos('KCHREPOS0027E')
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+ parser = ConfigParser()
+ with open(entry.repofile) as fd:
+ parser.readfp(fd)
+
+ if len(parser.sections()) == 1:
+ os.remove(entry.repofile)
+ return
+
+ parser.remove_section(repo_id)
+ with open(entry.repofile, "w") as fd:
+ parser.write(fd)
+
+
+class AptRepo(object):
+ """
+ Class to represent and operate with YUM repositories.
+ It's loaded only on those systems listed at YUM_DISTROS and loads necessary
+ modules in runtime.
+ """
+ TYPE = 'deb'
+ KIMCHI_LIST = "kimchi-source.list"
+ CONFIG_ENTRY = ('dist', 'comps')
+
+ def __init__(self):
+ getattr(__import__('apt_pkg'), 'init_config')()
+ getattr(__import__('apt_pkg'), 'init_system')()
+ config = getattr(__import__('apt_pkg'), 'config')
+ self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
+ module = __import__('aptsources.sourceslist', globals(), locals(),
+ ['SourcesList'], -1)
+
+ self._sourceparts_path = '/%s%s' % (
+ config.get('Dir::Etc'), config.get('Dir::Etc::sourceparts'))
+ self._sourceslist = getattr(module, 'SourcesList')
+ self.filename = os.path.join(self._sourceparts_path, self.KIMCHI_LIST)
+ if not os.path.exists(self.filename):
+ with open(self.filename, 'w') as fd:
+ fd.write("# This file is managed by Kimchi and it must not "
+ "be modified manually\n")
+
+ def _get_repos(self):
+ try:
+ with self.pkg_lock():
+ repos = self._sourceslist()
+ repos.refresh()
+ except Exception, e:
+ kimchiLock.release()
+ raise OperationFailed('KCHREPOS0025E', {'err': e.message})
+
+ return repos
+
+ def _get_repo_id(self, repo):
+ data = urlparse.urlparse(repo.uri)
+ name = data.hostname or data.path
+ return '%s-%s-%s' % (name, repo.dist, "-".join(repo.comps))
+
+ def _get_source_entry(self, repo_id):
+ kimchiLock.acquire()
+ repos = self._get_repos()
+ kimchiLock.release()
+
+ for r in repos:
+ # Ignore deb-src repositories
+ if r.type != 'deb':
+ continue
+
+ if self._get_repo_id(r) != repo_id:
+ continue
+
+ return r
+
+ return None
+
+ def getRepositoriesList(self):
+ """
+ Return a list of repositories IDs
+
+ APT repositories there aren't the concept about repository ID, so for
+ internal control, the repository ID will be built as described in
+ _get_repo_id()
+ """
+ kimchiLock.acquire()
+ repos = self._get_repos()
+ kimchiLock.release()
+
+ res = []
+ for r in repos:
+ # Ignore deb-src repositories
+ if r.type != 'deb':
+ continue
+
+ res.append(self._get_repo_id(r))
+
+ return res
+
+ def getRepo(self, repo_id):
+ """
+ Return a dictionary in the repositories.Repositories() format of the
+ given repository ID with the information of a SourceEntry object.
+ """
+ r = self._get_source_entry(repo_id)
+ if r is None:
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ info = {'enabled': not r.disabled,
+ 'baseurl': r.uri,
+ 'config': {'dist': r.dist,
+ 'comps': r.comps}}
+ return info
+
+ def addRepo(self, params):
+ """
+ Add a new APT repository based on <params>
+ """
+ # To create a APT repository the dist is a required parameter
+ # (in addition to baseurl, verified on controller through API.json)
+ config = params.get('config', None)
+ if config is None:
+ raise MissingParameter("KCHREPOS0019E")
+
+ if 'dist' not in config.keys():
+ raise MissingParameter("KCHREPOS0019E")
+
+ uri = params['baseurl']
+ dist = config['dist']
+ comps = config.get('comps', [])
+
+ validate_repo_url(uri)
+
+ kimchiLock.acquire()
+ try:
+ repos = self._get_repos()
+ source_entry = repos.add('deb', uri, dist, comps,
+ file=self.filename)
+ with self.pkg_lock():
+ repos.save()
+ except Exception as e:
+ kimchiLock.release()
+ raise OperationFailed("KCHREPOS0026E", {'err': e.message})
+ kimchiLock.release()
+ return self._get_repo_id(source_entry)
+
+ def toggleRepo(self, repo_id, enable):
+ """
+ Enable a given repository
+ """
+ r = self._get_source_entry(repo_id)
+ if r is None:
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ if enable and not r.disabled:
+ raise InvalidOperation("KCHREPOS0015E", {'repo_id': repo_id})
+
+ if not enable and r.disabled:
+ raise InvalidOperation("KCHREPOS0016E", {'repo_id': repo_id})
+
+ if enable:
+ line = 'deb'
+ else:
+ line = '#deb'
+
+ kimchiLock.acquire()
+ try:
+ repos = self._get_repos()
+ with self.pkg_lock():
+ repos.remove(r)
+ repos.add(line, r.uri, r.dist, r.comps, file=self.filename)
+ repos.save()
+ except:
+ kimchiLock.release()
+ if enable:
+ raise OperationFailed("KCHREPOS0020E", {'repo_id': repo_id})
+
+ raise OperationFailed("KCHREPOS0021E", {'repo_id': repo_id})
+ finally:
+ kimchiLock.release()
+
+ return repo_id
+
+ def updateRepo(self, repo_id, params):
+ """
+ Update a given repository in repositories.Repositories() format
+ """
+ old_info = self.getRepo(repo_id)
+ updated_info = copy.deepcopy(old_info)
+ updated_info['baseurl'] = params.get(
+ 'baseurl', updated_info['baseurl'])
+
+ if 'config' in params.keys():
+ config = params['config']
+ updated_info['config']['dist'] = config.get(
+ 'dist', old_info['config']['dist'])
+ updated_info['config']['comps'] = config.get(
+ 'comps', old_info['config']['comps'])
+
+ self.removeRepo(repo_id)
+ try:
+ return self.addRepo(updated_info)
+ except:
+ self.addRepo(old_info)
+ raise
+
+ def removeRepo(self, repo_id):
+ """
+ Remove a given repository
+ """
+ r = self._get_source_entry(repo_id)
+ if r is None:
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ kimchiLock.acquire()
+ try:
+ repos = self._get_repos()
+ with self.pkg_lock():
+ repos.remove(r)
+ repos.save()
+ except:
+ kimchiLock.release()
+ raise OperationFailed("KCHREPOS0017E", {'repo_id': repo_id})
+ finally:
+ kimchiLock.release()
diff --git a/src/wok/plugins/kimchi/root.py b/src/wok/plugins/kimchi/root.py
new file mode 100644
index 0000000..1e2bfc7
--- /dev/null
+++ b/src/wok/plugins/kimchi/root.py
@@ -0,0 +1,69 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import cherrypy
+
+from wok.i18n import messages
+from wok.root import WokRoot
+
+import config
+import mockmodel
+import vnc
+from control import sub_nodes
+from model import model as kimchiModel
+
+
+class KimchiRoot(WokRoot):
+ def __init__(self, wok_options):
+ if hasattr(wok_options, "model"):
+ self.model = wok_options.model
+ elif wok_options.test:
+ self.model = mockmodel.MockModel()
+ else:
+ self.model = kimchiModel.Model()
+
+ dev_env = wok_options.environment != 'production'
+ super(KimchiRoot, self).__init__(self.model, dev_env)
+
+ for ident, node in sub_nodes.items():
+ setattr(self, ident, node(self.model))
+
+ if isinstance(self.model, kimchiModel.Model):
+ vnc_ws_proxy = vnc.new_ws_proxy()
+ cherrypy.engine.subscribe('exit', vnc_ws_proxy.terminate)
+
+ self.api_schema = json.load(open(os.path.join(os.path.dirname(
+ os.path.abspath(__file__)), 'API.json')))
+ self.paths = config.kimchiPaths
+ self.domain = 'kimchi'
+ self.messages = messages
+
+ make_dirs = [
+ os.path.abspath(config.get_distros_store()),
+ os.path.abspath(config.get_debugreports_path()),
+ os.path.abspath(config.get_screenshot_path())
+ ]
+ for directory in make_dirs:
+ if not os.path.isdir(directory):
+ os.makedirs(directory)
+
+ def get_custom_conf(self):
+ return config.KimchiConfig()
diff --git a/src/wok/plugins/kimchi/scan.py b/src/wok/plugins/kimchi/scan.py
new file mode 100644
index 0000000..b475c46
--- /dev/null
+++ b/src/wok/plugins/kimchi/scan.py
@@ -0,0 +1,89 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import glob
+import hashlib
+import os.path
+import shutil
+import tempfile
+import time
+
+from wok.utils import wok_log
+
+from isoinfo import IsoImage, probe_iso
+
+
+SCAN_IGNORE = ['/tmp/kimchi-scan-*']
+
+
+class Scanner(object):
+ SCAN_TTL = 300
+
+ def __init__(self, record_clean_cb):
+ self.clean_cb = record_clean_cb
+
+ def delete(self):
+ self.clean_stale(-1)
+
+ def clean_stale(self, window=SCAN_TTL):
+ """
+ Clear scan pools generated before time window,
+ Clear all scan pools if window is -1.
+ """
+ try:
+ now = time.time()
+ clean_list = glob.glob("/tmp/kimchi-scan-*")
+ for d in clean_list:
+ transient_pool = \
+ os.path.basename(d).replace('kimchi-scan-', '')[0: -6]
+ if now - os.path.getmtime(d) > window:
+ shutil.rmtree(d)
+ self.clean_cb(transient_pool)
+ except OSError as e:
+ msg = "Exception %s occured when cleaning stale pool, ignore"
+ wok_log.debug(msg % e.message)
+
+ def scan_dir_prepare(self, name):
+ # clean stale scan storage pools
+ self.clean_stale()
+ return tempfile.mkdtemp(prefix='kimchi-scan-' + name, dir='/tmp')
+
+ def start_scan(self, cb, params):
+ def updater(iso_info):
+ iso_name = os.path.basename(iso_info['path'])[:-3]
+
+ duplicates = "%s/%s*" % (params['pool_path'], iso_name)
+ for f in glob.glob(duplicates):
+ iso_img = IsoImage(f)
+ if (iso_info['distro'], iso_info['version']) == \
+ iso_img.probe():
+ return
+
+ iso_path = iso_name + hashlib.md5(iso_info['path']).hexdigest() + \
+ '.iso'
+ link_name = os.path.join(params['pool_path'],
+ os.path.basename(iso_path))
+ os.symlink(iso_info['path'], link_name)
+
+ ignore_paths = params.get('ignore_list', [])
+ scan_params = dict(path=params['scan_path'], updater=updater,
+ ignore_list=ignore_paths + SCAN_IGNORE)
+ probe_iso(None, scan_params)
+ cb('', True)
diff --git a/src/wok/plugins/kimchi/screenshot.py b/src/wok/plugins/kimchi/screenshot.py
new file mode 100644
index 0000000..ffe5a1a
--- /dev/null
+++ b/src/wok/plugins/kimchi/screenshot.py
@@ -0,0 +1,184 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import glob
+import os
+import signal
+import tempfile
+import time
+import uuid
+
+try:
+ from PIL import Image
+except ImportError:
+ import Image
+
+
+from wok.utils import wok_log
+
+import config
+
+
+(fd, pipe) = tempfile.mkstemp()
+stream_test_result = None
+
+
+class VMScreenshot(object):
+ OUTDATED_SECS = 5
+ THUMBNAIL_SIZE = (256, 256)
+ LIVE_WINDOW = 60
+ MAX_STREAM_ATTEMPTS = 10
+
+ def __init__(self, args):
+ self.vm_uuid = args['uuid']
+ args.setdefault('thumbnail',
+ os.path.join(config.get_screenshot_path(),
+ '%s-%s.png' %
+ (self.vm_uuid, str(uuid.uuid4()))))
+ self.info = args
+
+ @staticmethod
+ def get_stream_test_result():
+ return stream_test_result
+
+ def lookup(self):
+ now = time.time()
+ try:
+ last_update = os.path.getmtime(self.info['thumbnail'])
+ except OSError:
+ last_update = 0
+
+ if now - last_update > self.OUTDATED_SECS:
+ self._clean_extra(self.LIVE_WINDOW)
+ self._generate_thumbnail()
+ return 'plugins/kimchi/data/screenshots/%s' %\
+ os.path.basename(self.info['thumbnail'])
+
+ def _clean_extra(self, window=-1):
+ """
+ Clear screenshots before time specified by window,
+ Clear all screenshots if window is -1.
+ """
+ try:
+ now = time.time()
+ clear_list = glob.glob("%s/%s-*.png" %
+ (config.get_screenshot_path(),
+ self.vm_uuid))
+ for f in clear_list:
+ if now - os.path.getmtime(f) > window:
+ os.unlink(f)
+ except OSError:
+ pass
+
+ def delete(self):
+ return self._clean_extra()
+
+ def _generate_scratch(self, thumbnail):
+ """
+ Generate screenshot of given vm.
+ Override me in child class.
+ """
+ pass
+
+ def _create_black_image(self, thumbnail):
+ image = Image.new("RGB", self.THUMBNAIL_SIZE, 'black')
+ image.save(thumbnail)
+
+ def _watch_stream_creation(self, thumbnail):
+ """
+ This is a verification test for libvirt stream functionality.
+
+ It is necessary to avoid the server hangs while creating the screenshot
+ image using libvirt stream API.
+
+ This problem was found in libvirt 0.9.6 for SLES11 SP2.
+
+ This test consists in running the screeshot creation with a timeout.
+ If timeout occurs, the libvirt is taking too much time to create the
+ screenshot image and the stream must be disabled it if happens
+ successively (to avoid blocking server requests).
+ """
+ pid = os.fork()
+ if pid == 0:
+ try:
+ self._generate_scratch(thumbnail)
+ os._exit(0)
+ except:
+ os._exit(1)
+ else:
+ counter = 0
+ ret = os.waitpid(pid, os.WNOHANG)
+ while ret == (0, 0) and counter < 3:
+ counter += 1
+ time.sleep(1)
+ ret = os.waitpid(pid, os.WNOHANG)
+
+ fd = open(pipe, "a")
+ if ret != (pid, 0):
+ fd.write("-")
+ if ret[0] != pid:
+ os.kill(int(pid), signal.SIGKILL)
+ os.waitpid(pid, 0)
+ else:
+ fd.write("+")
+ fd.close()
+
+ def _get_test_result(self):
+ if not os.path.exists(pipe):
+ return
+
+ fd = open(pipe, "r")
+ data = fd.read()
+ fd.close()
+
+ if len(data) >= self.MAX_STREAM_ATTEMPTS or bool('+' in data):
+ global stream_test_result
+ stream_test_result = bool('+' in data)
+ os.remove(pipe)
+
+ def _generate_thumbnail(self):
+ thumbnail = os.path.join(config.get_screenshot_path(), '%s-%s.png' %
+ (self.vm_uuid, str(uuid.uuid4())))
+
+ self._get_test_result()
+ if stream_test_result is None:
+ self._watch_stream_creation(thumbnail)
+ elif stream_test_result:
+ try:
+ self._generate_scratch(thumbnail)
+ except:
+ wok_log.error("screenshot_creation: Unable to create "
+ "screenshot image %s." % thumbnail)
+ else:
+ self._create_black_image(thumbnail)
+
+ if os.path.getsize(thumbnail) == 0:
+ self._create_black_image(thumbnail)
+ else:
+ im = Image.open(thumbnail)
+ try:
+ # Prevent Image lib from lazy load,
+ # work around pic truncate validation in thumbnail generation
+ im.thumbnail(self.THUMBNAIL_SIZE)
+ except Exception as e:
+ wok_log.warning("Image load with warning: %s." % e)
+ im.save(thumbnail, "PNG")
+
+ self.info['thumbnail'] = thumbnail
diff --git a/src/wok/plugins/kimchi/swupdate.py b/src/wok/plugins/kimchi/swupdate.py
new file mode 100644
index 0000000..84b927f
--- /dev/null
+++ b/src/wok/plugins/kimchi/swupdate.py
@@ -0,0 +1,263 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import subprocess
+import time
+
+from wok.basemodel import Singleton
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import run_command, wok_log
+
+from config import kimchiLock
+from yumparser import get_yum_packages_list_update
+
+
+class SoftwareUpdate(object):
+ __metaclass__ = Singleton
+
+ """
+ Class to represent and operate with OS software update.
+ """
+ def __init__(self):
+ # This stores all packages to be updated for Kimchi perspective. It's a
+ # dictionary of dictionaries, in the format {'package_name': package},
+ # where:
+ # package = {'package_name': <string>, 'version': <string>,
+ # 'arch': <string>, 'repository': <string>
+ # }
+ self._packages = {}
+
+ # This stores the number of packages to update
+ self._num2update = 0
+
+ # Get the distro of host machine and creates an object related to
+ # correct package management system
+ try:
+ __import__('yum')
+ wok_log.info("Loading YumUpdate features.")
+ self._pkg_mnger = YumUpdate()
+ except ImportError:
+ try:
+ __import__('apt')
+ wok_log.info("Loading AptUpdate features.")
+ self._pkg_mnger = AptUpdate()
+ except ImportError:
+ zypper_help = ["zypper", "--help"]
+ (stdout, stderr, returncode) = run_command(zypper_help)
+ if returncode == 0:
+ wok_log.info("Loading ZypperUpdate features.")
+ self._pkg_mnger = ZypperUpdate()
+ else:
+ raise Exception("There is no compatible package manager "
+ "for this system.")
+
+ def _scanUpdates(self):
+ """
+ Update self._packages with packages to be updated.
+ """
+ self._packages = {}
+ self._num2update = 0
+
+ # Call system pkg_mnger to get the packages as list of dictionaries.
+ for pkg in self._pkg_mnger.getPackagesList():
+
+ # Check if already exist a package in self._packages
+ pkg_id = pkg.get('package_name')
+ if pkg_id in self._packages.keys():
+ # package already listed to update. do nothing
+ continue
+
+ # Update the self._packages and self._num2update
+ self._packages[pkg_id] = pkg
+ self._num2update = self._num2update + 1
+
+ def getUpdates(self):
+ """
+ Return the self._packages.
+ """
+ self._scanUpdates()
+ return self._packages
+
+ def getUpdate(self, name):
+ """
+ Return a dictionary with all info from a given package name.
+ """
+ if name not in self._packages.keys():
+ raise NotFoundError('KCHPKGUPD0002E', {'name': name})
+
+ return self._packages[name]
+
+ def getNumOfUpdates(self):
+ """
+ Return the number of packages to be updated.
+ """
+ self._scanUpdates()
+ return self._num2update
+
+ def doUpdate(self, cb, params):
+ """
+ Execute the update
+ """
+ # reset messages
+ cb('')
+
+ cmd = self._pkg_mnger.update_cmd
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ msgs = []
+ while proc.poll() is None:
+ msgs.append(proc.stdout.readline())
+ cb(''.join(msgs))
+ time.sleep(0.5)
+
+ # read the final output lines
+ msgs.extend(proc.stdout.readlines())
+
+ retcode = proc.poll()
+ if retcode == 0:
+ return cb(''.join(msgs), True)
+
+ msgs.extend(proc.stderr.readlines())
+ return cb(''.join(msgs), False)
+
+
+class YumUpdate(object):
+ """
+ Class to represent and operate with YUM software update system.
+ It's loaded only on those systems listed at YUM_DISTROS and loads necessary
+ modules in runtime.
+ """
+ def __init__(self):
+ self._pkgs = {}
+ self.update_cmd = ["yum", "-y", "update"]
+
+ def _refreshUpdateList(self):
+ """
+ Update the list of packages to be updated in the system.
+ """
+ try:
+ kimchiLock.acquire()
+ self._pkgs = get_yum_packages_list_update()
+ except Exception, e:
+ raise OperationFailed('KCHPKGUPD0003E', {'err': str(e)})
+ finally:
+ kimchiLock.release()
+
+ def getPackagesList(self):
+ """
+ Return a list of package's dictionaries. Each dictionary contains the
+ information about a package, in the format:
+ package = {'package_name': <string>, 'version': <string>,
+ 'arch': <string>, 'repository': <string>}
+ """
+ self._refreshUpdateList()
+ pkg_list = []
+ for pkg in self._pkgs:
+ package = {'package_name': pkg.name, 'version': pkg.version,
+ 'arch': pkg.arch, 'repository': pkg.ui_from_repo}
+ pkg_list.append(package)
+ return pkg_list
+
+
+class AptUpdate(object):
+ """
+ Class to represent and operate with APT software update system.
+ It's loaded only on those systems listed at APT_DISTROS and loads necessary
+ modules in runtime.
+ """
+ def __init__(self):
+ self._pkgs = {}
+ self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
+ self.update_cmd = ['apt-get', 'upgrade', '-y']
+
+ def _refreshUpdateList(self):
+ """
+ Update the list of packages to be updated in the system.
+ """
+ apt_cache = getattr(__import__('apt'), 'Cache')()
+ try:
+ with self.pkg_lock():
+ apt_cache.update()
+ apt_cache.upgrade()
+ self._pkgs = apt_cache.get_changes()
+ except Exception, e:
+ kimchiLock.release()
+ raise OperationFailed('KCHPKGUPD0003E', {'err': e.message})
+
+ def getPackagesList(self):
+ """
+ Return a list of package's dictionaries. Each dictionary contains the
+ information about a package, in the format
+ package = {'package_name': <string>, 'version': <string>,
+ 'arch': <string>, 'repository': <string>}
+ """
+ kimchiLock.acquire()
+ self._refreshUpdateList()
+ kimchiLock.release()
+ pkg_list = []
+ for pkg in self._pkgs:
+ package = {'package_name': pkg.shortname,
+ 'version': pkg.candidate.version,
+ 'arch': pkg._pkg.architecture,
+ 'repository': pkg.candidate.origins[0].label}
+ pkg_list.append(package)
+
+ return pkg_list
+
+
+class ZypperUpdate(object):
+ """
+ Class to represent and operate with Zypper software update system.
+ It's loaded only on those systems listed at ZYPPER_DISTROS and loads
+ necessary modules in runtime.
+ """
+ def __init__(self):
+ self._pkgs = {}
+ self.update_cmd = ["zypper", "--non-interactive", "update",
+ "--auto-agree-with-licenses"]
+
+ def _refreshUpdateList(self):
+ """
+ Update the list of packages to be updated in the system.
+ """
+ self._pkgs = []
+ cmd = ["zypper", "list-updates"]
+ (stdout, stderr, returncode) = run_command(cmd)
+
+ if len(stderr) > 0:
+ raise OperationFailed('KCHPKGUPD0003E', {'err': stderr})
+
+ for line in stdout.split('\n'):
+ if line.find('v |') >= 0:
+ info = line.split(' | ')
+ package = {'package_name': info[2], 'version': info[4],
+ 'arch': info[5], 'repository': info[1]}
+ self._pkgs.append(package)
+
+ def getPackagesList(self):
+ """
+ Return a list of package's dictionaries. Each dictionary contains the
+ information about a package, in the format
+ package = {'package_name': <string>, 'version': <string>,
+ 'arch': <string>, 'repository': <string>}
+ """
+ kimchiLock.acquire()
+ self._refreshUpdateList()
+ kimchiLock.release()
+ return self._pkgs
diff --git a/src/wok/plugins/kimchi/template.conf b/src/wok/plugins/kimchi/template.conf
new file mode 100644
index 0000000..f3615e6
--- /dev/null
+++ b/src/wok/plugins/kimchi/template.conf
@@ -0,0 +1,47 @@
+#
+# Configuration file for Kimchi Templates
+#
+
+[main]
+# Memory in MB
+#memory = 1024
+
+# List of networks separated by comma
+# Represents the virtual network interfaces to be assigned to guest
+#networks = default,
+
+[storage]
+# Storage pool used to handle the guest disk
+#pool = default
+
+# Specify multiple [[disk.X]] sub-sections to add multiples disks to guest
+# All the disk files will be created in the same storage pool as set above
+[[disk.0]]
+# Disk size in GB
+#size = 10
+
+# Disk format
+#format = qcow2
+
+[graphics]
+# Graphics type
+# Valid options: vnc | spice
+#type = vnc
+
+# The network which the vnc/spice server listens on
+#listen = 127.0.0.1
+
+[processor]
+# Number of vcpus
+# When specifying CPU topology, make sure cpus value is equal to the product
+# of sockets, cores, and threads.
+#cpus = 1
+
+# Number of sockets (not set by default)
+#sockets =
+
+# Number of cores per socket (not set by default)
+#cores =
+
+# Number of threads per core (not set by default)
+#threads =
diff --git a/src/wok/plugins/kimchi/tests/Makefile.am b/src/wok/plugins/kimchi/tests/Makefile.am
new file mode 100644
index 0000000..c1f6784
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/Makefile.am
@@ -0,0 +1,50 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = \
+ Makefile.am \
+ run_tests.sh.in \
+ test_config.py.in \
+ $(filter-out test_config.py, $(wildcard *.py)) \
+ $(NULL)
+
+noinst_SCRIPTS = run_tests.sh
+
+do_substitution = \
+ sed -e 's,[@]HAVE_PYMOD_UNITTEST[@],$(HAVE_PYMOD_UNITTEST),g' \
+ -e 's,[@]prefix[@],$(prefix),g' \
+ -e 's,[@]datadir[@],$(datadir),g' \
+ -e 's,[@]PYTHON_VERSION[@],$(PYTHON_VERSION),g' \
+ -e 's,[@]wokdir[@],$(pythondir)/wok,g' \
+ -e 's,[@]pkgdatadir[@],$(pkgdatadir),g'
+
+
+run_tests.sh: run_tests.sh.in Makefile
+ $(do_substitution) < $(srcdir)/run_tests.sh.in > run_tests.sh
+ chmod +x run_tests.sh
+
+test_config.py: test_config.py.in Makefile
+ $(do_substitution) < $(srcdir)/test_config.py.in > test_config.py
+
+check-local:
+ $(MKDIR_P) $(top_srcdir)/data/screenshots
+ ./run_tests.sh
+
+BUILT_SOURCES = test_config.py
+CLEANFILES = run_tests.sh test_config.py
diff --git a/src/wok/plugins/kimchi/tests/iso_gen.py b/src/wok/plugins/kimchi/tests/iso_gen.py
new file mode 100644
index 0000000..736c660
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/iso_gen.py
@@ -0,0 +1,212 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import platform
+import struct
+
+from wok.plugins.kimchi.isoinfo import IsoImage
+
+
+iso_des = [
+ ('openbsd', lambda v: True,
+ lambda v: 'OpenBSD/i386 %s Install CD' % v),
+ ('centos', lambda v: True, lambda v: 'CentOS_%s_Final' % v),
+ ('windows', '2000', 'W2AFPP'),
+ ('windows', 'xp', 'WXPFPP'),
+ ('windows', '2003', 'ARMECHK'),
+ ('windows', '2003r2', 'CRMEFPP'),
+ ('windows', '2008', 'KRTMSVOL'),
+ ('windows', '2008r2', 'GRMSXVOL'),
+ ('windows', 'vista', 'FB1EVOL'),
+ ('windows', '7', 'GRMCULFRER'),
+ ('windows', '8', 'HB1_CCPA_X86FRE'),
+ ('sles', '10', 'SLES10'),
+ ('sles', '11', 'SUSE_SLES-11-0-0'),
+ ('opensuse', '11.1', 'SU1110.001'),
+ ('opensuse', '11.3', 'openSUSE-DVD-x86_64.0702..001'),
+ ('opensuse', '11.4', 'openSUSE-DVD-x86_640024'),
+ ('opensuse', '12.1', 'openSUSE-DVD-x86_640039'),
+ ('opensuse', '12.2', 'openSUSE-DVD-x86_640167'),
+ ('opensuse', lambda v: True, lambda v: 'openSUSE-%s' % v),
+ ('rhel', '4.8', 'RHEL/4-U8'),
+ ('rhel', lambda v: v.startswith('6.'), lambda v: 'RHEL_%s' % v),
+ ('debian', lambda v: True, lambda v: 'Debian %s' % v),
+ ('ubuntu',
+ lambda v: v in ('7.10', '8.04', '8.10', '9.04', '9.10', '10.04', '10.10',
+ '11.04', '11.10', '12.04', '12.10', '13.04', '13.10',
+ '14.04'),
+ lambda v: 'Ubuntu %s' % v),
+ ('fedora',
+ lambda v: v in ('16', '17', '18', '19'),
+ lambda v: 'Fedora %s' % v)
+]
+
+
+class FakeIsoImage(object):
+ def _build_iso(self, fd, iso_volid, bootable):
+ if platform.machine().startswith('ppc'):
+ self._build_powerpc_bootable_iso(fd, iso_volid)
+ return
+ self._build_intel_iso(fd, iso_volid, bootable)
+
+ def _build_powerpc_bootable_iso(self, fd, iso_volid):
+ self._build_prim_vol(fd, iso_volid)
+ self._build_bootable_ppc_path_table(fd)
+
+ def _build_intel_iso(self, fd, iso_volid, bootable):
+ # Do not change the order of the method calls
+ self._build_el_boot(fd, bootable)
+ self._build_prim_vol(fd, iso_volid)
+ self._build_el_torito(fd)
+
+ def _build_prim_vol(self, fd, iso_volid):
+ fd.seek(16 * IsoImage.SECTOR_SIZE)
+ fmt = IsoImage.VOL_DESC
+ vd_type = 1
+ vd_ident = 'CD001'
+ vd_ver = 1
+ pad0 = 1
+ sys_id = 'fake os'
+ vol_id = iso_volid
+ data = (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id)
+ s = fmt.pack(*data)
+ fd.write(s)
+ self._add_sector_padding(fd, s)
+
+ def _add_sector_padding(self, fd, s):
+ padding_len = IsoImage.SECTOR_SIZE - len(s)
+ fmt = struct.Struct('=%ss' % padding_len)
+ s = fmt.pack('a' * padding_len)
+ fd.write(s)
+
+ def _build_el_torito(self, fd):
+ fmt = IsoImage.EL_TORITO_BOOT_RECORD
+ vd_type = 0
+ vd_ident = 'CD001'
+ vd_ver = 1
+ et_ident = "EL TORITO SPECIFICATION:"
+ pad0 = 'a' * 32
+ boot_cat = 0
+ data = (vd_type, vd_ident, vd_ver, et_ident, pad0, boot_cat)
+ s = fmt.pack(*data)
+ fd.write(s)
+ self._add_sector_padding(fd, s)
+
+ def _build_el_boot(self, fd, bootable):
+ fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
+ hdr_id = 0
+ platform_id = 0
+ pad0 = 1
+ ident = 'c' * 24
+ csum = 1
+ key55 = 0x55
+ keyAA = 0xaa
+ data = (hdr_id, platform_id, pad0, ident, csum, key55, keyAA)
+ s = fmt.pack(*data)
+ fd.write(s)
+
+ fmt = IsoImage.EL_TORITO_BOOT_ENTRY
+ if bootable:
+ boot = 0x88
+ else:
+ boot = 0
+ media_type = 1
+ load_seg = 1
+ sys_type = 1
+ pad0 = 1
+ sectors = 1
+ load_rba = 1
+ data = (boot, media_type, load_seg, sys_type, pad0, sectors, load_rba)
+ s = fmt.pack(*data)
+ fd.write(s)
+
+ s = 'a' * IsoImage.SECTOR_SIZE
+ fd.write(s)
+
+ def _build_bootable_ppc_path_table(self, fd):
+ # write path table locator
+ PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
+ PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
+ path_table_size = 64
+ path_table_loc = 18
+ fd.seek(PATH_TABLE_LOC_OFFSET)
+ fmt = PATH_TABLE_SIZE_LOC
+ data = (path_table_size, 4*'0', path_table_loc)
+ s = fmt.pack(*data)
+ fd.write(s)
+ # write path table entry
+ fd.seek(path_table_loc * IsoImage.SECTOR_SIZE)
+ DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H 3s")
+ dir_namelen = 3
+ dir_loc = 19
+ dir_parent = 1
+ dir_name = 'ppc'
+ data = (dir_namelen, 0, dir_loc, dir_parent, dir_name)
+ fmt = DIR_NAMELEN_LOCATION_PARENT
+ s = fmt.pack(*data)
+ fd.write(s)
+ # write 'ppc' dir record
+ ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
+ fd.seek(ppc_dir_offset)
+ STATIC_DIR_RECORD_FMT = struct.Struct("<B 9s I 11s B 6s B 12s")
+ dir_rec_len = 1
+ unused1 = 9 * '0'
+ dir_size = 100
+ unused2 = 11 * '0'
+ file_flags = 0
+ unused3 = 6 * '0'
+ file_name_len = 12
+ boot_file_name = "bootinfo.txt"
+ data = (dir_rec_len, unused1, dir_size, unused2, file_flags,
+ unused3, file_name_len, boot_file_name)
+ fmt = STATIC_DIR_RECORD_FMT
+ s = fmt.pack(*data)
+ fd.write(s)
+
+
+def construct_fake_iso(path, bootable, version, distro):
+ iso = FakeIsoImage()
+
+ for d, v, gen_id in iso_des:
+ if d != distro:
+ continue
+ if hasattr(v, '__call__'):
+ supported = v(version)
+ else:
+ supported = version == v
+
+ if not supported:
+ continue
+
+ if hasattr(gen_id, '__call__'):
+ vol_id = gen_id(version)
+ else:
+ vol_id = gen_id
+ with open(path, 'w') as fd:
+ return iso._build_iso(fd, vol_id, bootable)
+
+ raise Exception("%s: %s not supported generation" % (distro, version))
+
+
+if __name__ == '__main__':
+ construct_fake_iso('centos.iso', True, '6.1', 'centos')
+ construct_fake_iso('ubuntu12.04.iso', True, '12.04', 'ubuntu')
+ construct_fake_iso('fedora17.iso', True, '17', 'fedora')
+ construct_fake_iso('sles10.iso', True, '10', 'sles')
+ construct_fake_iso('openbsd.iso', True, '5.0', 'openbsd')
diff --git a/src/wok/plugins/kimchi/tests/run_tests.sh.in b/src/wok/plugins/kimchi/tests/run_tests.sh.in
new file mode 100644
index 0000000..beef75e
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/run_tests.sh.in
@@ -0,0 +1,55 @@
+#!/bin/bash
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+HAVE_UNITTEST=@HAVE_PYMOD_UNITTEST@
+PYTHON_VER=@PYTHON_VERSION@
+
+if [ "$1" = "-v" ]; then
+ OPTS="-v"
+ shift
+else
+ OPTS=""
+fi
+
+if [ $# -ne 0 ]; then
+ ARGS="$@"
+else
+ ARGS=`find -name "test_*.py" | xargs -I @ basename @ .py`
+fi
+
+if [ "$HAVE_UNITTEST" != "yes" -o "$PYTHON_VER" == "2.6" ]; then
+ CMD="unit2"
+else
+ CMD="python -m unittest"
+fi
+
+LIST=($ARGS)
+MODEL_LIST=()
+MOCK_LIST=()
+for ((i=0;i<${#LIST[@]};i++)); do
+
+ if [[ ${LIST[$i]} == test_model* ]]; then
+ MODEL_LIST+=(${LIST[$i]})
+ else
+ MOCK_LIST+=(${LIST[$i]})
+ fi
+done
+
+PYTHONPATH=../plugins:../src:../ $CMD $OPTS ${MODEL_LIST[@]} ${MOCK_LIST[@]}
diff --git a/src/wok/plugins/kimchi/tests/test_authorization.py b/src/wok/plugins/kimchi/tests/test_authorization.py
new file mode 100644
index 0000000..87d68ab
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_authorization.py
@@ -0,0 +1,178 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi import mockmodel
+
+from iso_gen import construct_fake_iso
+from utils import get_free_port, patch_auth, request
+from utils import run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+fake_iso = '/tmp/fake.iso'
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port
+
+ patch_auth(sudo=False)
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ test_server = run_server(host, port, ssl_port, test_mode=True, model=model)
+
+ # Create fake ISO to do the tests
+ construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+ os.unlink(fake_iso)
+
+
+class AuthorizationTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def test_nonroot_access(self):
+ # Non-root users can access static host information
+ resp = self.request('/plugins/kimchi/host', '{}', 'GET')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can access host stats
+ resp = self.request('/plugins/kimchi/host/stats', '{}', 'GET')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not reboot/shutdown host system
+ resp = self.request('/plugins/kimchi/host/reboot', '{}', 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/host/shutdown', '{}', 'POST')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not get or debug reports
+ resp = self.request('/plugins/kimchi/debugreports', '{}', 'GET')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/debugreports', '{}', 'POST')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not create or delete network (only get)
+ resp = self.request('/plugins/kimchi/networks', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/networks', '{}', 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/networks/default/activate', '{}',
+ 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/networks/default', '{}', 'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not create or delete storage pool (only get)
+ resp = self.request('/plugins/kimchi/storagepools', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools', '{}', 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/default/activate',
+ '{}', 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/default', '{}',
+ 'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not update or delete a template
+ # but he can get and create a new one
+ resp = self.request('/plugins/kimchi/templates', '{}', 'GET')
+ self.assertEquals(403, resp.status)
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/templates/test', '{}', 'PUT')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can only get vms authorized to them
+ model.templates_create({'name': u'test', 'cdrom': fake_iso})
+
+ task_info = model.vms_create({
+ 'name': u'test-me',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+
+ model.vm_update(u'test-me',
+ {'users': [mockmodel.fake_user.keys()[0]],
+ 'groups': []})
+
+ task_info = model.vms_create({
+ 'name': u'test-usera',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+
+ non_root = list(set(model.users_get_list()) - set(['root']))[0]
+ model.vm_update(u'test-usera', {'users': [non_root], 'groups': []})
+
+ task_info = model.vms_create({
+ 'name': u'test-groupa',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+ a_group = model.groups_get_list()[0]
+ model.vm_update(u'test-groupa', {'groups': [a_group]})
+
+ resp = self.request('/plugins/kimchi/vms', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ vms_data = json.loads(resp.read())
+ self.assertEquals([u'test-groupa', u'test-me'],
+ sorted([v['name'] for v in vms_data]))
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(403, resp.status)
+
+ # Create a vm using mockmodel directly to test Resource access
+ task_info = model.vms_create({
+ 'name': 'kimchi-test',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+ resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}', 'PUT')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}', 'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can only update VMs authorized by them
+ resp = self.request('/plugins/kimchi/vms/test-me/start', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-usera/start', '{}',
+ 'POST')
+ self.assertEquals(403, resp.status)
+
+ model.template_delete('test')
+ model.vm_delete('test-me')
diff --git a/src/wok/plugins/kimchi/tests/test_config.py.in b/src/wok/plugins/kimchi/tests/test_config.py.in
new file mode 100644
index 0000000..4604eb1
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_config.py.in
@@ -0,0 +1,267 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+from cherrypy.lib.reprconf import Parser
+
+from wok.config import Paths, PluginPaths, WokConfig
+
+from wok.plugins.kimchi.config import get_debugreports_path
+from wok.plugins.kimchi.config import get_screenshot_path
+from wok.plugins.kimchi.config import KimchiConfig, KimchiPaths
+
+
+get_prefix = None
+
+
+def setUpModule():
+ global get_prefix
+ get_prefix = Paths.get_prefix
+
+
+def tearDownModule():
+ Paths.get_prefix = KimchiPaths.get_prefix = get_prefix
+
+
+class ConfigTests(unittest.TestCase):
+ def assertInstalledPath(self, actual, expected):
+ if '@pkgdatadir@' != '/usr/share/kimchi':
+ usr_local = '/usr/local'
+ if not expected.startswith('/usr'):
+ expected = usr_local + expected
+ self.assertEquals(actual, expected)
+
+ def test_installed_paths(self):
+ Paths.get_prefix = lambda self: '@datadir@/wok'
+ paths = Paths()
+ self.assertInstalledPath(paths.state_dir, '/var/lib/wok')
+ self.assertInstalledPath(paths.log_dir, '/var/log/wok')
+ self.assertInstalledPath(paths.conf_dir, '/etc/wok')
+ self.assertInstalledPath(paths.src_dir, '@wokdir@')
+ self.assertInstalledPath(paths.plugins_dir, '@wokdir@/plugins')
+ self.assertInstalledPath(paths.ui_dir, '@datadir@/wok/ui')
+ self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
+
+ def test_uninstalled_paths(self):
+ Paths.get_prefix = lambda self: '/home/user/wok'
+ paths = Paths()
+ self.assertEquals(paths.state_dir, '/home/user/wok/data')
+ self.assertEquals(paths.log_dir, '/home/user/wok/log')
+ self.assertEquals(paths.conf_dir, '/home/user/wok/src')
+ self.assertEquals(paths.src_dir, '/home/user/wok/src/wok')
+ self.assertEquals(paths.plugins_dir, '/home/user/wok/plugins')
+ self.assertEquals(paths.ui_dir, '/home/user/wok/ui')
+ self.assertEquals(paths.mo_dir, '/home/user/wok/mo')
+
+ def test_installed_plugin_paths(self):
+ KimchiPaths.get_prefix = lambda self: '@datadir@/wok'
+ paths = KimchiPaths()
+ self.assertInstalledPath(paths.conf_dir, '/etc/wok/plugins.d')
+ self.assertInstalledPath(paths.conf_file,
+ '/etc/wok/plugins.d/kimchi.conf')
+ self.assertInstalledPath(paths.src_dir, '@wokdir@/plugins/kimchi')
+ self.assertInstalledPath(paths.ui_dir,
+ '@datadir@/wok/plugins/kimchi/ui')
+ self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
+
+ def test_uninstalled_plugin_paths(self):
+ KimchiPaths.get_prefix = lambda self: '/home/user/wok'
+ paths = KimchiPaths()
+ self.assertEquals(paths.conf_dir, '/home/user/wok/plugins/kimchi')
+ self.assertEquals(
+ paths.conf_file, '/home/user/wok/plugins/kimchi/kimchi.conf')
+ self.assertEquals(paths.src_dir, '/home/user/wok/plugins/kimchi')
+ self.assertEquals(paths.ui_dir, '/home/user/wok/plugins/kimchi/ui')
+ self.assertEquals(paths.mo_dir, '/home/user/wok/plugins/kimchi/mo')
+
+ def test_wok_config(self):
+ Paths.get_prefix = PluginPaths.get_prefix = get_prefix
+ paths = Paths()
+ CACHEEXPIRES = 31536000
+ SESSIONSTIMEOUT = 10
+ configObj = {
+ '/': {
+ 'tools.trailing_slash.on': False,
+ 'request.methods_with_bodies': ('POST', 'PUT'),
+ 'tools.nocache.on': True,
+ 'tools.proxy.on': True,
+ 'tools.sessions.on': True,
+ 'tools.sessions.name': 'wok',
+ 'tools.sessions.secure': True,
+ 'tools.sessions.httponly': True,
+ 'tools.sessions.locking': 'explicit',
+ 'tools.sessions.storage_type': 'ram',
+ 'tools.sessions.timeout': SESSIONSTIMEOUT,
+ 'tools.wokauth.on': False
+ },
+ '/wok-ui.html': {
+ 'tools.wokauth.on': True
+ },
+ '/css': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/css' % paths.prefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/js': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/js' % paths.prefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/libs': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/libs' % paths.prefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/images': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/images' % paths.prefix,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/favicon.ico': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename':
+ '%s/images/logo.ico' % paths.ui_dir
+ },
+ '/robots.txt': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': '%s/robots.txt' % paths.ui_dir
+ },
+ }
+
+ wok_config = WokConfig()
+ self.assertEquals(wok_config, configObj)
+
+
+ def test_kimchi_config(self):
+ KimchiPaths.get_prefix = PluginPaths.get_prefix = get_prefix
+ paths = KimchiPaths()
+ pluginPrefix = paths.add_prefix(paths.plugin_dir)
+ CACHEEXPIRES = 31536000
+ SESSIONSTIMEOUT = 10
+ configObj = {
+ 'wok': {
+ 'enable': True,
+ 'plugin_class': "KimchiRoot",
+ 'uri': '/%s' % paths.plugin_dir,
+ 'extra_auth_api_class': "control.sub_nodes"
+ },
+ '/': {
+ 'tools.trailing_slash.on': False,
+ 'request.methods_with_bodies': ('POST', 'PUT'),
+ 'tools.nocache.on': True,
+ 'tools.proxy.on': True,
+ 'tools.sessions.on': True,
+ 'tools.sessions.name': 'wok',
+ 'tools.sessions.secure': True,
+ 'tools.sessions.httponly': True,
+ 'tools.sessions.locking': 'explicit',
+ 'tools.sessions.storage_type': 'ram',
+ 'tools.sessions.timeout': SESSIONSTIMEOUT,
+ 'tools.wokauth.on': True
+ },
+ '/novnc': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': paths.novnc_dir,
+ 'tools.nocache.on': True,
+ 'tools.wokauth.on': True
+ },
+ '/spice_auto.html': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': paths.spice_file,
+ 'tools.nocache.on': True,
+ 'tools.wokauth.on': True
+ },
+ '/spice-html5': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': paths.spice_dir,
+ 'tools.nocache.on': True
+ },
+ '/spice-html5/spice.css': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': paths.spice_css_file,
+ 'tools.nocache.on': True,
+ },
+ '/ui/config/tab-ext.xml': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': '%s/ui/config/tab-ext.xml' %
+ pluginPrefix,
+ 'tools.nocache.on': True
+ },
+ '/css': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/css' % pluginPrefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/js': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/js' % pluginPrefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/libs': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/libs' % pluginPrefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False,
+ },
+ '/images': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/images' % pluginPrefix,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/data/screenshots': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': get_screenshot_path(),
+ 'tools.nocache.on': False
+ },
+ '/data/debugreports': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': get_debugreports_path(),
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': True,
+ 'tools.staticdir.content_types': {'xz': 'application/x-xz'}
+ },
+ '/help': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/pages/help' % pluginPrefix,
+ 'tools.nocache.on': True
+ }
+ }
+
+ kimchi_config = Parser().dict_from_file(KimchiPaths().conf_file)
+ kimchi_config.update(KimchiConfig())
+ self.assertEquals(kimchi_config, configObj)
diff --git a/src/wok/plugins/kimchi/tests/test_exception.py b/src/wok/plugins/kimchi/tests/test_exception.py
new file mode 100644
index 0000000..4459aa6
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_exception.py
@@ -0,0 +1,123 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+
+from wok.plugins.kimchi import mockmodel
+
+from utils import get_free_port, patch_auth, request, run_server
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+
+
+def setup_server(environment='development'):
+ global test_server, model, host, port, ssl_port
+
+ patch_auth()
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ test_server = run_server(host, port, ssl_port, test_mode=True, model=model,
+ environment=environment)
+
+
+class ExceptionTests(unittest.TestCase):
+ def tearDown(self):
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+ def test_production_env(self):
+ """
+ Test reasons sanitized in production env
+ """
+ setup_server('production')
+ # test 404
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
+ )
+ self.assertEquals('404 Not Found', resp.get('code'))
+
+ # test 405 wrong method
+ resp = json.loads(request(host, ssl_port, '/', None, 'DELETE').read())
+ msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
+ self.assertEquals('405 Method Not Allowed', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+
+ # test 400 parse error
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', '{', 'POST').read()
+ )
+ msg = u'WOKAPI0006E: Unable to parse JSON request'
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+ self.assertNotIn('call_stack', resp)
+
+ # test 400 missing required parameter
+ req = json.dumps({})
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', req, 'POST').read()
+ )
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ m = u"KCHVM0016E: Specify a template to create a virtual machine from"
+ self.assertEquals(m, resp.get('reason'))
+ self.assertNotIn('call_stack', resp)
+
+ def test_development_env(self):
+ """
+ Test traceback thrown in development env
+ """
+ setup_server()
+ # test 404
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
+ )
+ self.assertEquals('404 Not Found', resp.get('code'))
+
+ # test 405 wrong method
+ resp = json.loads(request(host, ssl_port, '/', None, 'DELETE').read())
+ msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
+ self.assertEquals('405 Method Not Allowed', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+
+ # test 400 parse error
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', '{', 'POST').read()
+ )
+ msg = u'WOKAPI0006E: Unable to parse JSON request'
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+ self.assertIn('call_stack', resp)
+
+ # test 400 missing required parameter
+ req = json.dumps({})
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', req, 'POST').read()
+ )
+ m = u"KCHVM0016E: Specify a template to create a virtual machine from"
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ self.assertEquals(m, resp.get('reason'))
+ self.assertIn('call_stack', resp)
diff --git a/src/wok/plugins/kimchi/tests/test_host.py b/src/wok/plugins/kimchi/tests/test_host.py
new file mode 100644
index 0000000..6cd0833
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_host.py
@@ -0,0 +1,206 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import platform
+import psutil
+import tempfile
+import time
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from utils import get_free_port, patch_auth, request, run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+ssl_port = None
+tmpfile = None
+
+
+def setUpModule():
+ global test_server, model, host, ssl_port, tmpfile
+
+ patch_auth()
+ tmpfile = tempfile.mktemp()
+ model = MockModel(tmpfile)
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink(tmpfile)
+
+
+class HostTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_hostinfo(self):
+ resp = self.request('/plugins/kimchi/host').read()
+ info = json.loads(resp)
+ keys = ['os_distro', 'os_version', 'os_codename', 'cpu_model',
+ 'memory', 'cpus']
+ self.assertEquals(sorted(keys), sorted(info.keys()))
+
+ distro, version, codename = platform.linux_distribution()
+ self.assertEquals(distro, info['os_distro'])
+ self.assertEquals(version, info['os_version'])
+ self.assertEquals(unicode(codename, "utf-8"), info['os_codename'])
+ self.assertEquals(psutil.TOTAL_PHYMEM, info['memory'])
+
+ def test_hoststats(self):
+ time.sleep(1)
+ stats_keys = ['cpu_utilization', 'memory', 'disk_read_rate',
+ 'disk_write_rate', 'net_recv_rate', 'net_sent_rate']
+ resp = self.request('/plugins/kimchi/host/stats').read()
+ stats = json.loads(resp)
+ self.assertEquals(sorted(stats_keys), sorted(stats.keys()))
+
+ cpu_utilization = stats['cpu_utilization']
+ self.assertIsInstance(cpu_utilization, float)
+ self.assertGreaterEqual(cpu_utilization, 0.0)
+ self.assertTrue(cpu_utilization <= 100.0)
+
+ memory_stats = stats['memory']
+ self.assertIn('total', memory_stats)
+ self.assertIn('free', memory_stats)
+ self.assertIn('cached', memory_stats)
+ self.assertIn('buffers', memory_stats)
+ self.assertIn('avail', memory_stats)
+
+ resp = self.request('/plugins/kimchi/host/stats/history').read()
+ history = json.loads(resp)
+ self.assertEquals(sorted(stats_keys), sorted(history.keys()))
+
+ def test_host_actions(self):
+ def _task_lookup(taskid):
+ return json.loads(
+ self.request('/plugins/kimchi/tasks/%s' % taskid).read()
+ )
+
+ resp = self.request('/plugins/kimchi/host/shutdown', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/host/reboot', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+
+ # Test system update
+ resp = self.request('/plugins/kimchi/host/packagesupdate', None, 'GET')
+ pkgs = json.loads(resp.read())
+ self.assertEquals(3, len(pkgs))
+
+ pkg_keys = ['package_name', 'repository', 'arch', 'version']
+ for p in pkgs:
+ name = p['package_name']
+ resp = self.request('/plugins/kimchi/host/packagesupdate/' + name,
+ None, 'GET')
+ info = json.loads(resp.read())
+ self.assertEquals(sorted(pkg_keys), sorted(info.keys()))
+
+ resp = self.request('/plugins/kimchi/host/swupdate', '{}', 'POST')
+ task = json.loads(resp.read())
+ task_params = [u'id', u'message', u'status', u'target_uri']
+ self.assertEquals(sorted(task_params), sorted(task.keys()))
+
+ resp = self.request('/tasks/' + task[u'id'], None,
+ 'GET')
+ task_info = json.loads(resp.read())
+ self.assertEquals(task_info['status'], 'running')
+ wait_task(_task_lookup, task_info['id'])
+ resp = self.request('/tasks/' + task[u'id'], None,
+ 'GET')
+ task_info = json.loads(resp.read())
+ self.assertEquals(task_info['status'], 'finished')
+ self.assertIn(u'All packages updated', task_info['message'])
+ pkgs = model.packagesupdate_get_list()
+ self.assertEquals(0, len(pkgs))
+
+ def test_host_partitions(self):
+ resp = self.request('/plugins/kimchi/host/partitions')
+ self.assertEquals(200, resp.status)
+ partitions = json.loads(resp.read())
+
+ keys = ['name', 'path', 'type', 'fstype', 'size', 'mountpoint',
+ 'available']
+ for item in partitions:
+ resp = self.request('/plugins/kimchi/host/partitions/%s' %
+ item['name'])
+ info = json.loads(resp.read())
+ self.assertEquals(sorted(info.keys()), sorted(keys))
+
+ def test_host_devices(self):
+ def asset_devices_type(devices, dev_type):
+ for dev in devices:
+ self.assertEquals(dev['device_type'], dev_type)
+
+ resp = self.request('/plugins/kimchi/host/devices?_cap=scsi_host')
+ nodedevs = json.loads(resp.read())
+ # Mockmodel brings 3 preconfigured scsi fc_host
+ self.assertEquals(3, len(nodedevs))
+
+ nodedev = json.loads(
+ self.request('/plugins/kimchi/host/devices/scsi_host2').read()
+ )
+ # Mockmodel generates random wwpn and wwnn
+ self.assertEquals('scsi_host2', nodedev['name'])
+ self.assertEquals('fc_host', nodedev['adapter']['type'])
+ self.assertEquals(16, len(nodedev['adapter']['wwpn']))
+ self.assertEquals(16, len(nodedev['adapter']['wwnn']))
+
+ devs = json.loads(self.request('/plugins/kimchi/host/devices').read())
+ dev_names = [dev['name'] for dev in devs]
+ for dev_type in ('pci', 'usb_device', 'scsi'):
+ resp = self.request('/plugins/kimchi/host/devices?_cap=%s' %
+ dev_type)
+ devsByType = json.loads(resp.read())
+ names = [dev['name'] for dev in devsByType]
+ self.assertTrue(set(names) <= set(dev_names))
+ asset_devices_type(devsByType, dev_type)
+
+ resp = self.request('/plugins/kimchi/host/devices?_passthrough=true')
+ passthru_devs = [dev['name'] for dev in json.loads(resp.read())]
+ self.assertTrue(set(passthru_devs) <= set(dev_names))
+
+ for dev_type in ('pci', 'usb_device', 'scsi'):
+ resp = self.request(
+ '/plugins/kimchi/host/devices?_cap=%s&_passthrough=true' %
+ dev_type
+ )
+ filteredDevs = json.loads(resp.read())
+ filteredNames = [dev['name'] for dev in filteredDevs]
+ self.assertTrue(set(filteredNames) <= set(dev_names))
+ asset_devices_type(filteredDevs, dev_type)
+
+ for dev in passthru_devs:
+ resp = self.request(
+ '/plugins/kimchi/host/devices?_passthrough_affected_by=%s' %
+ dev
+ )
+ affected_devs = [dev['name'] for dev in json.loads(resp.read())]
+ self.assertTrue(set(affected_devs) <= set(dev_names))
diff --git a/src/wok/plugins/kimchi/tests/test_mock_network.py b/src/wok/plugins/kimchi/tests/test_mock_network.py
new file mode 100644
index 0000000..4e2a939
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mock_network.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from test_model_network import _do_network_test
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class MockNetworkTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def test_vlan_tag_bridge(self):
+ # Verify the current system has at least one interface to create a
+ # bridged network
+ interfaces = json.loads(
+ self.request('/plugins/kimchi/interfaces?type=nic').read()
+ )
+ if len(interfaces) > 0:
+ iface = interfaces[0]['name']
+ _do_network_test(self, model, {'name': u'bridge-network',
+ 'connection': 'bridge',
+ 'interface': iface, 'vlan_id': 987})
diff --git a/src/wok/plugins/kimchi/tests/test_mock_storagepool.py b/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
new file mode 100644
index 0000000..5cf5b3e
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class MockStoragepoolTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def _task_lookup(self, taskid):
+ return json.loads(
+ self.request('/tasks/%s' % taskid).read()
+ )
+
+ def test_storagepool(self):
+ # MockModel always returns 2 partitions (vdx, vdz)
+ partitions = json.loads(
+ self.request('/plugins/kimchi/host/partitions').read()
+ )
+ devs = [dev['path'] for dev in partitions]
+
+ # MockModel always returns 3 FC devices
+ fc_devs = json.loads(
+ self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
+ )
+ fc_devs = [dev['name'] for dev in fc_devs]
+
+ poolDefs = [
+ {'type': 'dir', 'name': u'kīмÑhÄ«UnitTestDirPool',
+ 'path': '/tmp/kimchi-images'},
+ {'type': 'netfs', 'name': u'kīмÑhÄ«UnitTestNSFPool',
+ 'source': {'host': 'localhost',
+ 'path': '/var/lib/kimchi/nfs-pool'}},
+ {'type': 'scsi', 'name': u'kīмÑhÄ«UnitTestSCSIFCPool',
+ 'source': {'adapter_name': fc_devs[0]}},
+ {'type': 'iscsi', 'name': u'kīмÑhÄ«UnitTestISCSIPool',
+ 'source': {'host': '127.0.0.1',
+ 'target': 'iqn.2015-01.localhost.kimchiUnitTest'}},
+ {'type': 'logical', 'name': u'kīмÑhÄ«UnitTestLogicalPool',
+ 'source': {'devices': [devs[0]]}}]
+
+ def _do_test(params):
+ name = params['name']
+ uri = '/plugins/kimchi/storagepools/%s' % name.encode('utf-8')
+
+ req = json.dumps(params)
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # activate the storage pool
+ resp = self.request(uri + '/activate', '{}', 'POST')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals('active', storagepool['state'])
+
+ # Set autostart flag of an active storage pool
+ for autostart in [True, False]:
+ t = {'autostart': autostart}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals(autostart, storagepool['autostart'])
+
+ # Extend an active logical pool
+ if params['type'] == 'logical':
+ t = {'disks': [devs[1]]}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+
+ # Deactivate the storage pool
+ resp = self.request(uri + '/deactivate', '{}', 'POST')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals('inactive', storagepool['state'])
+
+ # Set autostart flag of an inactive storage pool
+ for autostart in [True, False]:
+ t = {'autostart': autostart}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals(autostart, storagepool['autostart'])
+
+ # Extend an inactive logical pool
+ if params['type'] == 'logical':
+ t = {'disks': [devs[1]]}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+
+ # Delete the storage pool
+ resp = self.request(uri, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ for pool in poolDefs:
+ _do_test(pool)
diff --git a/src/wok/plugins/kimchi/tests/test_mock_storagevolume.py b/src/wok/plugins/kimchi/tests/test_mock_storagevolume.py
new file mode 100644
index 0000000..9d0a5ad
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mock_storagevolume.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from test_model_storagevolume import _do_volume_test
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class MockStorageVolumeTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_storagevolume(self):
+ # MockModel always returns 2 partitions (vdx, vdz)
+ partitions = json.loads(
+ self.request('/plugins/kimchi/host/partitions').read()
+ )
+ devs = [dev['path'] for dev in partitions]
+
+ # MockModel always returns 3 FC devices
+ fc_devs = json.loads(
+ self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
+ )
+ fc_devs = [dev['name'] for dev in fc_devs]
+
+ poolDefs = [
+ {'type': 'dir', 'name': u'kīмÑhÄ«UnitTestDirPool',
+ 'path': '/tmp/kimchi-images'},
+ {'type': 'netfs', 'name': u'kīмÑhÄ«UnitTestNSFPool',
+ 'source': {'host': 'localhost',
+ 'path': '/var/lib/kimchi/nfs-pool'}},
+ {'type': 'scsi', 'name': u'kīмÑhÄ«UnitTestSCSIFCPool',
+ 'source': {'adapter_name': fc_devs[0]}},
+ {'type': 'iscsi', 'name': u'kīмÑhÄ«UnitTestISCSIPool',
+ 'source': {'host': '127.0.0.1',
+ 'target': 'iqn.2015-01.localhost.kimchiUnitTest'}},
+ {'type': 'logical', 'name': u'kīмÑhÄ«UnitTestLogicalPool',
+ 'source': {'devices': [devs[0]]}}]
+
+ for pool in poolDefs:
+ pool_name = pool['name']
+ uri = '/plugins/kimchi/storagepools/%s' % pool_name.encode('utf-8')
+ req = json.dumps(pool)
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+ # activate the storage pool
+ resp = self.request(uri + '/activate', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ _do_volume_test(self, model, host, ssl_port, pool_name)
diff --git a/src/wok/plugins/kimchi/tests/test_mockmodel.py b/src/wok/plugins/kimchi/tests/test_mockmodel.py
new file mode 100644
index 0000000..ffbf8d5
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mockmodel.py
@@ -0,0 +1,141 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import json
+import os
+import time
+import unittest
+
+from wok.plugins.kimchi import mockmodel
+from wok.plugins.kimchi.osinfo import get_template_default
+
+from utils import get_free_port, patch_auth, request, run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+fake_iso = None
+
+
+def setUpModule():
+ global host, port, ssl_port, model, test_server, fake_iso
+ cherrypy.request.headers = {'Accept': 'application/json'}
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ patch_auth()
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ host = '127.0.0.1'
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ model=model)
+ fake_iso = '/tmp/fake.iso'
+ open(fake_iso, 'w').close()
+
+
+def tearDown():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+ os.unlink(fake_iso)
+
+
+class MockModelTests(unittest.TestCase):
+ def setUp(self):
+ model.reset()
+
+ def test_screenshot_refresh(self):
+ # Create a VM
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ request(host, ssl_port, '/plugins/kimchi/templates', req, 'POST')
+ req = json.dumps({'name': 'test-vm', 'template': '/templates/test'})
+ resp = request(host, ssl_port, '/plugins/kimchi/vms', req, 'POST')
+ task = json.loads(resp.read())
+ wait_task(model.task_lookup, task['id'])
+
+ # Test screenshot refresh for running vm
+ request(host, ssl_port, '/plugins/kimchi/vms/test-vm/start', '{}',
+ 'POST')
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(200, resp.status)
+ self.assertEquals('image/png', resp.getheader('content-type'))
+ resp1 = request(host, ssl_port, '/plugins/kimchi/vms/test-vm')
+ rspBody = resp1.read()
+ testvm_Data = json.loads(rspBody)
+ screenshotURL = testvm_Data['screenshot']
+ time.sleep(5)
+ resp2 = request(host, ssl_port, screenshotURL)
+ self.assertEquals(200, resp2.status)
+ self.assertEquals(resp2.getheader('content-type'),
+ resp.getheader('content-type'))
+ self.assertEquals(resp2.getheader('content-length'),
+ resp.getheader('content-length'))
+ self.assertEquals(resp2.getheader('last-modified'),
+ resp.getheader('last-modified'))
+
+ def test_vm_list_sorted(self):
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ request(host, ssl_port, '/plugins/kimchi/templates', req, 'POST')
+
+ def add_vm(name):
+ # Create a VM
+ req = json.dumps({'name': name,
+ 'template': '/plugins/kimchi/templates/test'})
+ task = json.loads(request(host, ssl_port, '/plugins/kimchi/vms',
+ req, 'POST').read())
+ wait_task(model.task_lookup, task['id'])
+
+ vms = [u'abc', u'bca', u'cab', u'xba']
+ for vm in vms:
+ add_vm(vm)
+
+ vms.append(u'test')
+ self.assertEqual(model.vms_get_list(), sorted(vms))
+
+ def test_vm_info(self):
+ model.templates_create({'name': u'test',
+ 'cdrom': fake_iso})
+ task = model.vms_create({'name': u'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ wait_task(model.task_lookup, task['id'])
+ vms = model.vms_get_list()
+ self.assertEquals(2, len(vms))
+ self.assertIn(u'test-vm', vms)
+
+ keys = set(('name', 'state', 'stats', 'uuid', 'memory', 'cpus',
+ 'screenshot', 'icon', 'graphics', 'users', 'groups',
+ 'access', 'persistent'))
+
+ stats_keys = set(('cpu_utilization',
+ 'net_throughput', 'net_throughput_peak',
+ 'io_throughput', 'io_throughput_peak'))
+
+ info = model.vm_lookup(u'test-vm')
+ self.assertEquals(keys, set(info.keys()))
+ self.assertEquals('shutoff', info['state'])
+ self.assertEquals('test-vm', info['name'])
+ self.assertEquals(get_template_default('old', 'memory'),
+ info['memory'])
+ self.assertEquals(1, info['cpus'])
+ self.assertEquals('images/icon-vm.png', info['icon'])
+ self.assertEquals(stats_keys, set(info['stats'].keys()))
+ self.assertEquals('vnc', info['graphics']['type'])
+ self.assertEquals('127.0.0.1', info['graphics']['listen'])
diff --git a/src/wok/plugins/kimchi/tests/test_model.py b/src/wok/plugins/kimchi/tests/test_model.py
new file mode 100644
index 0000000..7c89048
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model.py
@@ -0,0 +1,1248 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import grp
+import os
+import pwd
+import re
+import shutil
+import time
+import unittest
+import uuid
+
+import wok.objectstore
+from wok.basemodel import Singleton
+from wok.config import config
+from wok.exception import InvalidOperation
+from wok.exception import InvalidParameter, NotFoundError, OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import add_task
+
+from wok.plugins.kimchi import netinfo
+from wok.plugins.kimchi.osinfo import get_template_default
+from wok.plugins.kimchi.model import model
+from wok.plugins.kimchi.model.libvirtconnection import LibvirtConnection
+
+import iso_gen
+import utils
+
+
+invalid_repository_urls = ['www.fedora.org', # missing protocol
+ '://www.fedora.org', # missing protocol
+ 'http://www.fedora', # invalid domain name
+ 'file:///home/foobar'] # invalid path
+
+TMP_DIR = '/var/lib/kimchi/tests/'
+UBUNTU_ISO = TMP_DIR + 'ubuntu14.04.iso'
+
+
+def setUpModule():
+ if not os.path.exists(TMP_DIR):
+ os.makedirs(TMP_DIR)
+
+ iso_gen.construct_fake_iso(UBUNTU_ISO, True, '14.04', 'ubuntu')
+
+ # Some FeatureTests functions depend on server to validate their result.
+ # As CapabilitiesModel is a Singleton class it will get the first result
+ # from FeatureTests which may be wrong when using the Model instance
+ # directly - the case of this test_model.py
+ # So clean Singleton instances to make sure to get the right result when
+ # running the following tests.
+ Singleton._instances = {}
+
+
+def tearDownModule():
+ shutil.rmtree(TMP_DIR)
+
+
+class ModelTests(unittest.TestCase):
+ def setUp(self):
+ self.tmp_store = '/tmp/kimchi-store-test'
+
+ def tearDown(self):
+ # FIXME: Tests using 'test:///default' URI should be moved to
+ # test_rest or test_mockmodel to avoid overriding problems
+ LibvirtConnection._connections['test:///default'] = {}
+
+ os.unlink(self.tmp_store)
+
+ def test_vm_info(self):
+ inst = model.Model('test:///default', self.tmp_store)
+ vms = inst.vms_get_list()
+ self.assertEquals(1, len(vms))
+ self.assertEquals('test', vms[0])
+
+ keys = set(('name', 'state', 'stats', 'uuid', 'memory', 'cpus',
+ 'screenshot', 'icon', 'graphics', 'users', 'groups',
+ 'access', 'persistent'))
+
+ stats_keys = set(('cpu_utilization',
+ 'net_throughput', 'net_throughput_peak',
+ 'io_throughput', 'io_throughput_peak'))
+ info = inst.vm_lookup('test')
+ self.assertEquals(keys, set(info.keys()))
+ self.assertEquals('running', info['state'])
+ self.assertEquals('test', info['name'])
+ self.assertEquals(2048, info['memory'])
+ self.assertEquals(2, info['cpus'])
+ self.assertEquals(None, info['icon'])
+ self.assertEquals(stats_keys, set(info['stats'].keys()))
+ self.assertRaises(NotFoundError, inst.vm_lookup, 'nosuchvm')
+ self.assertEquals([], info['users'])
+ self.assertEquals([], info['groups'])
+ self.assertTrue(info['persistent'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_lifecycle(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ vol_params = {'name': u'test-vol', 'capacity': 1024}
+ task = inst.storagevolumes_create(u'default', vol_params)
+ rollback.prependDefer(inst.storagevolume_delete, u'default',
+ vol_params['name'])
+ inst.task_wait(task['id'])
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+ vol = inst.storagevolume_lookup(u'default', vol_params['name'])
+
+ params = {'name': 'test', 'disks': [{'base': vol['path'],
+ 'size': 1}],
+ 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+ inst.task_wait(task['id'], 10)
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+
+ vms = inst.vms_get_list()
+ self.assertTrue('kimchi-vm' in vms)
+
+ inst.vm_start('kimchi-vm')
+
+ info = inst.vm_lookup('kimchi-vm')
+ self.assertEquals('running', info['state'])
+
+ self.assertRaises(InvalidOperation, inst.vmsnapshots_create,
+ u'kimchi-vm')
+
+ inst.vm_poweroff(u'kimchi-vm')
+ vm = inst.vm_lookup(u'kimchi-vm')
+
+ empty_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals({}, empty_snap)
+
+ # this snapshot should be deleted when its VM is deleted
+ params = {'name': u'mysnap'}
+ task = inst.vmsnapshots_create(u'kimchi-vm', params)
+ inst.task_wait(task['id'])
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+
+ self.assertRaises(NotFoundError, inst.vmsnapshot_lookup,
+ u'kimchi-vm', u'foobar')
+
+ snap = inst.vmsnapshot_lookup(u'kimchi-vm', params['name'])
+ self.assertTrue(int(time.time()) >= int(snap['created']))
+ self.assertEquals(vm['state'], snap['state'])
+ self.assertEquals(params['name'], snap['name'])
+ self.assertEquals(u'', snap['parent'])
+
+ snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
+ self.assertEquals([params['name']], snaps)
+
+ current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals(snap, current_snap)
+
+ task = inst.vmsnapshots_create(u'kimchi-vm')
+ snap_name = task['target_uri'].split('/')[-1]
+ rollback.prependDefer(inst.vmsnapshot_delete,
+ u'kimchi-vm', snap_name)
+ inst.task_wait(task['id'])
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+
+ snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
+ self.assertEquals(sorted([params['name'], snap_name],
+ key=unicode.lower), snaps)
+
+ snap = inst.vmsnapshot_lookup(u'kimchi-vm', snap_name)
+ current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals(snap, current_snap)
+
+ # update vm name
+ inst.vm_update('kimchi-vm', {'name': u'kimchi-vm-new'})
+
+ # Look up the first created snapshot from the renamed vm
+ snap = inst.vmsnapshot_lookup(u'kimchi-vm-new', params['name'])
+
+ # snapshot revert to the first created vm
+ result = inst.vmsnapshot_revert(u'kimchi-vm-new', params['name'])
+ self.assertEquals(result, [u'kimchi-vm', snap['name']])
+
+ vm = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(vm['state'], snap['state'])
+
+ current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals(params['name'], current_snap['name'])
+
+ self.assertRaises(NotFoundError, inst.vmsnapshot_delete,
+ u'kimchi-vm', u'foobar')
+
+ # suspend and resume the VM
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'shutoff')
+ self.assertRaises(InvalidOperation, inst.vm_suspend, u'kimchi-vm')
+ inst.vm_start(u'kimchi-vm')
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'running')
+ inst.vm_suspend(u'kimchi-vm')
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'paused')
+ self.assertRaises(InvalidParameter, inst.vm_update, u'kimchi-vm',
+ {'name': 'foo'})
+ inst.vm_resume(u'kimchi-vm')
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'running')
+ self.assertRaises(InvalidOperation, inst.vm_resume, u'kimchi-vm')
+ # leave the VM suspended to make sure a paused VM can be
+ # deleted correctly
+ inst.vm_suspend(u'kimchi-vm')
+
+ vms = inst.vms_get_list()
+ self.assertFalse('kimchi-vm' in vms)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_image_based_template(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ vol = 'base-vol.img'
+ params = {'name': vol,
+ 'capacity': 1073741824, # 1 GiB
+ 'allocation': 1048576, # 1 MiB
+ 'format': 'qcow2'}
+ task_id = inst.storagevolumes_create('default', params)['id']
+ rollback.prependDefer(inst.storagevolume_delete, 'default', vol)
+ inst.task_wait(task_id)
+ self.assertEquals('finished', inst.task_lookup(task_id)['status'])
+ vol_path = inst.storagevolume_lookup('default', vol)['path']
+
+ params = {'name': 'test', 'disks': [{'base': vol_path}]}
+ self.assertRaises(OperationFailed, inst.templates_create, params)
+
+ # Hack the model objstore to add a new template
+ # It is needed as the image file must be a bootable image when
+ # using model
+ # As it is difficult to create one on test runtime, inject a
+ # template with an empty image file to the objstore to test the
+ # feature
+ tmpl_name = "img-tmpl"
+ tmpl_info = {"cpus": 1, "cdrom": "",
+ "graphics": {"type": "vnc", "listen": "127.0.0.1"},
+ "networks": ["default"], "memory": 1024, "folder": [],
+ "icon": "images/icon-vm.png",
+ "os_distro": "unknown", "os_version": "unknown",
+ "disks": [{"base": vol_path, "size": 10}],
+ "storagepool": "/plugins/kimchi/storagepools/default"}
+
+ with inst.objstore as session:
+ session.store('template', tmpl_name, tmpl_info)
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/img-tmpl'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+
+ vms = inst.vms_get_list()
+ self.assertTrue('kimchi-vm' in vms)
+
+ inst.vm_start('kimchi-vm')
+ rollback.prependDefer(inst.vm_poweroff, 'kimchi-vm')
+
+ info = inst.vm_lookup('kimchi-vm')
+ self.assertEquals('running', info['state'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_graphics(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+ params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ with RollbackContext() as rollback:
+ params = {'name': 'kimchi-vnc',
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vnc')
+
+ info = inst.vm_lookup('kimchi-vnc')
+ self.assertEquals('vnc', info['graphics']['type'])
+ self.assertEquals('127.0.0.1', info['graphics']['listen'])
+
+ graphics = {'type': 'spice', 'listen': '127.0.0.1'}
+ params = {'name': 'kimchi-spice',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics}
+ task2 = inst.vms_create(params)
+ inst.task_wait(task2['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-spice')
+
+ info = inst.vm_lookup('kimchi-spice')
+ self.assertEquals('spice', info['graphics']['type'])
+ self.assertEquals('127.0.0.1', info['graphics']['listen'])
+
+ inst.template_delete('test')
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_ifaces(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ # Create a network
+ net_name = 'test-network'
+ net_args = {'name': net_name,
+ 'connection': 'nat',
+ 'subnet': '127.0.100.0/24'}
+ inst.networks_create(net_args)
+ rollback.prependDefer(inst.network_delete, net_name)
+ inst.network_activate(net_name)
+ rollback.prependDefer(inst.network_deactivate, net_name)
+
+ for vm_name in ['kimchi-ifaces', 'kimchi-ifaces-running']:
+ params = {'name': vm_name,
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ ifaces = inst.vmifaces_get_list(vm_name)
+ self.assertEquals(1, len(ifaces))
+
+ iface = inst.vmiface_lookup(vm_name, ifaces[0])
+ self.assertEquals(17, len(iface['mac']))
+ self.assertEquals("default", iface['network'])
+ self.assertIn("model", iface)
+
+ # attach network interface to vm
+ iface_args = {"type": "network",
+ "network": "test-network",
+ "model": "virtio"}
+ mac = inst.vmifaces_create(vm_name, iface_args)
+ # detach network interface from vm
+ rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
+ self.assertEquals(17, len(mac))
+
+ iface = inst.vmiface_lookup(vm_name, mac)
+ self.assertEquals("network", iface["type"])
+ self.assertEquals("test-network", iface['network'])
+ self.assertEquals("virtio", iface["model"])
+
+ # attach network interface to vm without providing model
+ iface_args = {"type": "network",
+ "network": "test-network"}
+ mac = inst.vmifaces_create(vm_name, iface_args)
+ rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
+
+ iface = inst.vmiface_lookup(vm_name, mac)
+ self.assertEquals("network", iface["type"])
+ self.assertEquals("test-network", iface['network'])
+
+ # update vm interface
+ newMacAddr = '54:50:e3:44:8a:af'
+ iface_args = {"mac": newMacAddr}
+ inst.vmiface_update(vm_name, mac, iface_args)
+ iface = inst.vmiface_lookup(vm_name, newMacAddr)
+ self.assertEquals(newMacAddr, iface['mac'])
+
+ # undo mac address change
+ iface_args = {"mac": mac}
+ inst.vmiface_update(vm_name, newMacAddr, iface_args)
+ iface = inst.vmiface_lookup(vm_name, mac)
+ self.assertEquals(mac, iface['mac'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_disk(self):
+ disk_path = os.path.join(TMP_DIR, 'existent2.iso')
+ open(disk_path, 'w').close()
+ modern_disk_bus = get_template_default('modern', 'disk_bus')
+
+ def _attach_disk(expect_bus=modern_disk_bus):
+ disk_args = {"type": "disk",
+ "pool": pool,
+ "vol": vol}
+ disk = inst.vmstorages_create(vm_name, disk_args)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count + 1, len(storage_list))
+
+ # Check the bus type to be 'virtio'
+ disk_info = inst.vmstorage_lookup(vm_name, disk)
+ self.assertEquals(u'disk', disk_info['type'])
+ self.assertEquals(vol_path, disk_info['path'])
+ self.assertEquals(expect_bus, disk_info['bus'])
+ return disk
+
+ inst = model.Model(objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ path = os.path.join(TMP_DIR, 'kimchi-images')
+ pool = 'test-pool'
+ vol = 'test-volume.img'
+ vol_path = "%s/%s" % (path, vol)
+ if not os.path.exists(path):
+ os.mkdir(path)
+ rollback.prependDefer(shutil.rmtree, path)
+
+ args = {'name': pool,
+ 'path': path,
+ 'type': 'dir'}
+ inst.storagepools_create(args)
+ rollback.prependDefer(inst.storagepool_delete, pool)
+
+ # Activate the pool before adding any volume
+ inst.storagepool_activate(pool)
+ rollback.prependDefer(inst.storagepool_deactivate, pool)
+
+ params = {'name': vol,
+ 'capacity': 1073741824, # 1 GiB
+ 'allocation': 536870912, # 512 MiB
+ 'format': 'qcow2'}
+ task_id = inst.storagevolumes_create(pool, params)['id']
+ rollback.prependDefer(inst.storagevolume_delete, pool, vol)
+ inst.task_wait(task_id)
+
+ vm_name = 'kimchi-cdrom'
+ params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+ params = {'name': vm_name,
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ prev_count = len(inst.vmstorages_get_list(vm_name))
+ self.assertEquals(1, prev_count)
+
+ # Volume format with mismatched type raise error
+ cdrom_args = {"type": "cdrom", "pool": pool, "vol": vol}
+ self.assertRaises(InvalidParameter, inst.vmstorages_create,
+ vm_name, cdrom_args)
+
+ # Cold plug and unplug a disk
+ disk = _attach_disk()
+ inst.vmstorage_delete(vm_name, disk)
+
+ # Hot plug a disk
+ inst.vm_start(vm_name)
+ disk = _attach_disk()
+
+ # VM disk still there after powered off
+ inst.vm_poweroff(vm_name)
+ disk_info = inst.vmstorage_lookup(vm_name, disk)
+ self.assertEquals(u'disk', disk_info['type'])
+ inst.vmstorage_delete(vm_name, disk)
+
+ # Specifying pool and path at same time will fail
+ disk_args = {"type": "disk",
+ "pool": pool,
+ "vol": vol,
+ "path": disk_path}
+ self.assertRaises(
+ InvalidParameter, inst.vmstorages_create, vm_name, disk_args)
+
+ old_distro_iso = TMP_DIR + 'rhel4_8.iso'
+ iso_gen.construct_fake_iso(old_distro_iso, True, '4.8', 'rhel')
+
+ vm_name = 'kimchi-ide-bus-vm'
+ params = {'name': 'old_distro_template', 'disks': [],
+ 'cdrom': old_distro_iso}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'old_distro_template')
+ params = {
+ 'name': vm_name,
+ 'template': '/plugins/kimchi/templates/old_distro_template'
+ }
+ task2 = inst.vms_create(params)
+ inst.task_wait(task2['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ # Need to check the right disk_bus for old distro
+ disk = _attach_disk(get_template_default('old', 'disk_bus'))
+ inst.vmstorage_delete('kimchi-ide-bus-vm', disk)
+
+ # Hot plug IDE bus disk does not work
+ inst.vm_start(vm_name)
+ self.assertRaises(InvalidOperation, _attach_disk)
+ inst.vm_poweroff(vm_name)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_cdrom(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ vm_name = 'kimchi-cdrom'
+ params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+ params = {'name': vm_name,
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ prev_count = len(inst.vmstorages_get_list(vm_name))
+ self.assertEquals(1, prev_count)
+
+ # dummy .iso files
+ iso_path = os.path.join(TMP_DIR, 'existent.iso')
+ iso_path2 = os.path.join(TMP_DIR, 'existent2.iso')
+ open(iso_path, 'w').close()
+ rollback.prependDefer(os.remove, iso_path)
+ open(iso_path2, 'w').close()
+ rollback.prependDefer(os.remove, iso_path2)
+ wrong_iso_path = '/nonexistent.iso'
+
+ # Create a cdrom
+ cdrom_args = {"type": "cdrom",
+ "path": iso_path}
+ cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count + 1, len(storage_list))
+
+ # Get cdrom info
+ cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(u'cdrom', cd_info['type'])
+ self.assertEquals(iso_path, cd_info['path'])
+
+ # update path of existing cd with
+ # non existent iso
+ self.assertRaises(InvalidParameter, inst.vmstorage_update,
+ vm_name, cdrom_dev, {'path': wrong_iso_path})
+
+ # Make sure CD ROM still exists after failure
+ cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(u'cdrom', cd_info['type'])
+ self.assertEquals(iso_path, cd_info['path'])
+
+ # update path of existing cd with existent iso of shutoff vm
+ inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path2})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(iso_path2, cdrom_info['path'])
+
+ # update path of existing cd with existent iso of running vm
+ inst.vm_start(vm_name)
+ inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(iso_path, cdrom_info['path'])
+
+ # eject cdrom
+ cdrom_dev = inst.vmstorage_update(vm_name, cdrom_dev, {'path': ''})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals('', cdrom_info['path'])
+ inst.vm_poweroff(vm_name)
+
+ # removing non existent cdrom
+ self.assertRaises(NotFoundError, inst.vmstorage_delete, vm_name,
+ "fakedev")
+
+ # removing valid cdrom
+ inst.vmstorage_delete(vm_name, cdrom_dev)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count, len(storage_list))
+
+ # Create a new cdrom using a remote iso
+ valid_remote_iso_path = utils.get_remote_iso_path()
+ cdrom_args = {"type": "cdrom",
+ "path": valid_remote_iso_path}
+ cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count + 1, len(storage_list))
+
+ # Update remote-backed cdrom with the same ISO
+ inst.vmstorage_update(vm_name, cdrom_dev,
+ {'path': valid_remote_iso_path})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ cur_cdrom_path = re.sub(":80/", '/', cdrom_info['path'])
+ self.assertEquals(valid_remote_iso_path, cur_cdrom_path)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_storage_provisioning(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {'name': 'test', 'disks': [{'size': 1}],
+ 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'test-vm-1',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'test-vm-1')
+
+ vm_info = inst.vm_lookup(params['name'])
+ disk_path = '%s/%s-0.img' % (
+ inst.storagepool_lookup('default')['path'], vm_info['uuid'])
+ self.assertTrue(os.access(disk_path, os.F_OK))
+ self.assertFalse(os.access(disk_path, os.F_OK))
+
+ def test_vm_memory_hotplug(self):
+ config.set("authentication", "method", "pam")
+ inst = model.Model(None, objstore_loc=self.tmp_store)
+ orig_params = {'name': 'test', 'memory': 1024, 'cdrom': UBUNTU_ISO}
+ inst.templates_create(orig_params)
+
+ with RollbackContext() as rollback:
+ params = {'name': 'kimchi-vm1',
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm1')
+ # Start vm
+ inst.vm_start('kimchi-vm1')
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
+ 'kimchi-vm1')
+
+ # Hotplug memory, only available in Libvirt >= 1.2.14
+ params = {'memory': 2048}
+ if inst.capabilities_lookup()['mem_hotplug_support']:
+ inst.vm_update('kimchi-vm1', params)
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm1')
+ self.assertEquals(params['memory'],
+ inst.vm_lookup('kimchi-vm1')['memory'])
+ else:
+ self.assertRaises(InvalidOperation, inst.vm_update,
+ 'kimchi-vm1', params)
+
+ def test_vm_edit(self):
+ config.set("authentication", "method", "pam")
+ inst = model.Model(None,
+ objstore_loc=self.tmp_store)
+
+ orig_params = {'name': 'test', 'memory': 1024, 'cpus': 1,
+ 'cdrom': UBUNTU_ISO}
+ inst.templates_create(orig_params)
+
+ with RollbackContext() as rollback:
+ params_1 = {'name': 'kimchi-vm1',
+ 'template': '/plugins/kimchi/templates/test'}
+ params_2 = {'name': 'kimchi-vm2',
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params_1)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm1')
+ task2 = inst.vms_create(params_2)
+ inst.task_wait(task2['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm2')
+
+ vms = inst.vms_get_list()
+ self.assertTrue('kimchi-vm1' in vms)
+
+ # make sure "vm_update" works when the domain has a snapshot
+ inst.vmsnapshots_create(u'kimchi-vm1')
+
+ # update vm graphics when vm is not running
+ inst.vm_update(u'kimchi-vm1',
+ {"graphics": {"passwd": "123456"}})
+
+ inst.vm_start('kimchi-vm1')
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
+ 'kimchi-vm1')
+
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals('123456', vm_info['graphics']["passwd"])
+ self.assertEquals(None, vm_info['graphics']["passwdValidTo"])
+
+ # update vm graphics when vm is running
+ inst.vm_update(u'kimchi-vm1',
+ {"graphics": {"passwd": "abcdef",
+ "passwdValidTo": 20}})
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals('abcdef', vm_info['graphics']["passwd"])
+ self.assertGreaterEqual(20, vm_info['graphics']['passwdValidTo'])
+
+ info = inst.vm_lookup('kimchi-vm1')
+ self.assertEquals('running', info['state'])
+
+ params = {'name': 'new-vm'}
+ self.assertRaises(InvalidParameter, inst.vm_update,
+ 'kimchi-vm1', params)
+
+ # change VM users and groups, when wm is running.
+ inst.vm_update(u'kimchi-vm1',
+ {'users': ['root'], 'groups': ['root']})
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals(['root'], vm_info['users'])
+ self.assertEquals(['root'], vm_info['groups'])
+ # change VM users and groups by removing all elements,
+ # when wm is running.
+ inst.vm_update(u'kimchi-vm1', {'users': [], 'groups': []})
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals([], vm_info['users'])
+ self.assertEquals([], vm_info['groups'])
+
+ inst.vm_poweroff('kimchi-vm1')
+ self.assertRaises(OperationFailed, inst.vm_update,
+ 'kimchi-vm1', {'name': 'kimchi-vm2'})
+
+ params = {'name': u'пeÏ-â¨Ð¼', 'cpus': 4, 'memory': 2048}
+ inst.vm_update('kimchi-vm1', params)
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ u'пeÏ-â¨Ð¼')
+ self.assertEquals(info['uuid'], inst.vm_lookup(u'пeÏ-â¨Ð¼')['uuid'])
+ info = inst.vm_lookup(u'пeÏ-â¨Ð¼')
+ for key in params.keys():
+ self.assertEquals(params[key], info[key])
+
+ # change only VM users - groups are not changed (default is empty)
+ users = inst.users_get_list()[:3]
+ inst.vm_update(u'пeÏ-â¨Ð¼', {'users': users})
+ self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
+ self.assertEquals([], inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
+
+ # change only VM groups - users are not changed (default is empty)
+ groups = inst.groups_get_list()[:2]
+ inst.vm_update(u'пeÏ-â¨Ð¼', {'groups': groups})
+ self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
+ self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
+
+ # change VM users and groups by adding a new element to each one
+ users.append(pwd.getpwuid(os.getuid()).pw_name)
+ groups.append(grp.getgrgid(os.getgid()).gr_name)
+ inst.vm_update(u'пeÏ-â¨Ð¼', {'users': users, 'groups': groups})
+ self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
+ self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
+
+ # change VM users (wrong value) and groups
+ # when an error occurs, everything fails and nothing is changed
+ self.assertRaises(InvalidParameter, inst.vm_update, u'пeÏ-â¨Ð¼',
+ {'users': ['userdoesnotexist'], 'groups': []})
+ self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
+ self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
+
+ # change VM users and groups (wrong value)
+ # when an error occurs, everything fails and nothing is changed
+ self.assertRaises(InvalidParameter, inst.vm_update, u'пeÏ-â¨Ð¼',
+ {'users': [], 'groups': ['groupdoesnotexist']})
+ self.assertEquals(users, inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
+ self.assertEquals(groups, inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
+
+ # change VM users and groups by removing all elements
+ inst.vm_update(u'пeÏ-â¨Ð¼', {'users': [], 'groups': []})
+ self.assertEquals([], inst.vm_lookup(u'пeÏ-â¨Ð¼')['users'])
+ self.assertEquals([], inst.vm_lookup(u'пeÏ-â¨Ð¼')['groups'])
+
+ def test_get_interfaces(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+ expected_ifaces = netinfo.all_favored_interfaces()
+ ifaces = inst.interfaces_get_list()
+ self.assertEquals(len(expected_ifaces), len(ifaces))
+ for name in expected_ifaces:
+ iface = inst.interface_lookup(name)
+ self.assertEquals(iface['name'], name)
+ self.assertIn('type', iface)
+ self.assertIn('status', iface)
+ self.assertIn('ipaddr', iface)
+ self.assertIn('netmask', iface)
+
+ def test_async_tasks(self):
+ class task_except(Exception):
+ pass
+
+ def quick_op(cb, message):
+ cb(message, True)
+
+ def long_op(cb, params):
+ time.sleep(params.get('delay', 3))
+ cb(params.get('message', ''), params.get('result', False))
+
+ def abnormal_op(cb, params):
+ try:
+ raise task_except
+ except:
+ cb("Exception raised", False)
+
+ def continuous_ops(cb, params):
+ cb("step 1 OK")
+ time.sleep(2)
+ cb("step 2 OK")
+ time.sleep(2)
+ cb("step 3 OK", params.get('result', True))
+
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+ taskid = add_task('', quick_op, inst.objstore, 'Hello')
+ inst.task_wait(taskid)
+ self.assertEquals(1, taskid)
+ self.assertEquals('finished', inst.task_lookup(taskid)['status'])
+ self.assertEquals('Hello', inst.task_lookup(taskid)['message'])
+
+ taskid = add_task('', long_op, inst.objstore,
+ {'delay': 3, 'result': False,
+ 'message': 'It was not meant to be'})
+ self.assertEquals(2, taskid)
+ self.assertEquals('running', inst.task_lookup(taskid)['status'])
+ self.assertEquals('OK', inst.task_lookup(taskid)['message'])
+ inst.task_wait(taskid)
+ self.assertEquals('failed', inst.task_lookup(taskid)['status'])
+ self.assertEquals('It was not meant to be',
+ inst.task_lookup(taskid)['message'])
+ taskid = add_task('', abnormal_op, inst.objstore, {})
+ inst.task_wait(taskid)
+ self.assertEquals('Exception raised',
+ inst.task_lookup(taskid)['message'])
+ self.assertEquals('failed', inst.task_lookup(taskid)['status'])
+
+ taskid = add_task('', continuous_ops, inst.objstore,
+ {'result': True})
+ self.assertEquals('running', inst.task_lookup(taskid)['status'])
+ inst.task_wait(taskid, timeout=10)
+ self.assertEquals('finished', inst.task_lookup(taskid)['status'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_delete_running_vm(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {'name': u'test', 'disks': [], 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': u'kīмÑhÄ«-â¨Ð¼',
+ 'template': u'/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ u'kīмÑhÄ«-â¨Ð¼')
+
+ inst.vm_start(u'kīмÑhÄ«-â¨Ð¼')
+ self.assertEquals(inst.vm_lookup(u'kīмÑhÄ«-â¨Ð¼')['state'], 'running')
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
+ u'kīмÑhÄ«-â¨Ð¼')
+
+ inst.vm_delete(u'kīмÑhÄ«-â¨Ð¼')
+
+ vms = inst.vms_get_list()
+ self.assertFalse(u'kīмÑhÄ«-â¨Ð¼' in vms)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_list_sorted(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {'name': 'test', 'disks': [], 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+
+ vms = inst.vms_get_list()
+
+ self.assertEquals(vms, sorted(vms, key=unicode.lower))
+
+ def test_vm_clone(self):
+ inst = model.Model('test:///default', objstore_loc=self.tmp_store)
+
+ all_vm_names = inst.vms_get_list()
+ name = all_vm_names[0]
+
+ original_vm = inst.vm_lookup(name)
+ if original_vm['state'] == u'shutoff':
+ inst.vm_start(name)
+
+ # the VM 'test' should be running by now, so we can't clone it yet
+ self.assertRaises(InvalidParameter, inst.vm_clone, name)
+
+ with RollbackContext() as rollback:
+ inst.vm_poweroff(name)
+ rollback.prependDefer(inst.vm_start, name)
+
+ # create two simultaneous clones of the same VM
+ # and make sure both of them complete successfully
+ task1 = inst.vm_clone(name)
+ task2 = inst.vm_clone(name)
+ clone1_name = task1['target_uri'].split('/')[-2]
+ rollback.prependDefer(inst.vm_delete, clone1_name)
+ clone2_name = task2['target_uri'].split('/')[-2]
+ rollback.prependDefer(inst.vm_delete, clone2_name)
+ inst.task_wait(task1['id'])
+ task1 = inst.task_lookup(task1['id'])
+ self.assertEquals('finished', task1['status'])
+ inst.task_wait(task2['id'])
+ task2 = inst.task_lookup(task2['id'])
+ self.assertEquals('finished', task2['status'])
+
+ # update the original VM info because its state has changed
+ original_vm = inst.vm_lookup(name)
+ clone_vm = inst.vm_lookup(clone1_name)
+
+ self.assertNotEqual(original_vm['name'], clone_vm['name'])
+ self.assertTrue(re.match(u'%s-clone-\d+' % original_vm['name'],
+ clone_vm['name']))
+ del original_vm['name']
+ del clone_vm['name']
+
+ self.assertNotEqual(original_vm['uuid'], clone_vm['uuid'])
+ del original_vm['uuid']
+ del clone_vm['uuid']
+
+ # compare all VM settings except the ones already compared
+ # (and removed) above (i.e. 'name' and 'uuid')
+ self.assertEquals(original_vm, clone_vm)
+
+ def test_use_test_host(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {
+ 'name': 'test',
+ 'disks': [],
+ 'cdrom': UBUNTU_ISO,
+ 'storagepool': '/plugins/kimchi/storagepools/default-pool',
+ 'domain': 'test',
+ 'arch': 'i686'
+ }
+
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+
+ vms = inst.vms_get_list()
+
+ self.assertTrue('kimchi-vm' in vms)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_debug_reports(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ if not inst.capabilities_lookup()['system_report_tool']:
+ raise unittest.SkipTest("Without debug report tool")
+
+ try:
+ timeout = int(os.environ['TEST_REPORT_TIMEOUT'])
+ except (ValueError, KeyError):
+ timeout = 120
+
+ namePrefix = 'unitTestReport'
+ # sosreport always deletes unsual letters like '-' and '_' in the
+ # generated report file name.
+ uuidstr = str(uuid.uuid4()).translate(None, "-_")
+ reportName = namePrefix + uuidstr
+ try:
+ inst.debugreport_delete(namePrefix + '*')
+ except NotFoundError:
+ pass
+ with RollbackContext() as rollback:
+ report_list = inst.debugreports_get_list()
+ self.assertFalse(reportName in report_list)
+ try:
+ tmp_name = reportName + "_1"
+ task = inst.debugreports_create({'name': reportName})
+ rollback.prependDefer(inst.debugreport_delete, tmp_name)
+ taskid = task['id']
+ inst.task_wait(taskid, timeout)
+ self.assertEquals('finished',
+ inst.task_lookup(taskid)['status'],
+ "It is not necessary an error. "
+ "You may need to increase the "
+ "timeout number by "
+ "TEST_REPORT_TIMEOUT=200 "
+ "./run_tests.sh test_model")
+ report_list = inst.debugreports_get_list()
+ self.assertTrue(reportName in report_list)
+ name = inst.debugreport_update(reportName, {'name': tmp_name})
+ self.assertEquals(name, tmp_name)
+ report_list = inst.debugreports_get_list()
+ self.assertTrue(tmp_name in report_list)
+ except OperationFailed, e:
+ if 'debugreport tool not found' not in e.message:
+ raise e
+
+ def test_get_distros(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+ distros = inst.distros_get_list()
+ for d in distros:
+ distro = inst.distro_lookup(d)
+ self.assertIn('name', distro)
+ self.assertIn('os_distro', distro)
+ self.assertIn('os_version', distro)
+ self.assertIn('os_arch', distro)
+ self.assertIn('path', distro)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_deep_scan(self):
+ inst = model.Model(None,
+ objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ deep_path = os.path.join(TMP_DIR, 'deep-scan')
+ subdir_path = os.path.join(deep_path, 'isos')
+ if not os.path.exists(subdir_path):
+ os.makedirs(subdir_path)
+ ubuntu_iso = os.path.join(deep_path, 'ubuntu12.04.iso')
+ sles_iso = os.path.join(subdir_path, 'sles10.iso')
+ iso_gen.construct_fake_iso(ubuntu_iso, True, '12.04', 'ubuntu')
+ iso_gen.construct_fake_iso(sles_iso, True, '10', 'sles')
+
+ args = {'name': 'kimchi-scanning-pool',
+ 'path': deep_path,
+ 'type': 'kimchi-iso'}
+ inst.storagepools_create(args)
+ rollback.prependDefer(shutil.rmtree, deep_path)
+ rollback.prependDefer(shutil.rmtree, args['path'])
+ rollback.prependDefer(inst.storagepool_deactivate, args['name'])
+
+ time.sleep(1)
+ volumes = inst.storagevolumes_get_list(args['name'])
+ self.assertEquals(len(volumes), 2)
+
+ def test_repository_create(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ yum_repos = [{'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'},
+ {'repo_id': 'fedora-updates-fake',
+ 'config':
+ {'mirrorlist': 'http://www.fedoraproject.org'}}]
+
+ deb_repos = [{'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal'}},
+ {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal', 'comps': ['main']}}]
+
+ yum_invalid_repos = []
+ deb_invalid_repos = []
+
+ for url in invalid_repository_urls:
+ wrong_baseurl = {'repo_id': 'wrong-id', 'baseurl': url}
+ wrong_mirrorlist = {'repo_id': 'wrong-id',
+ 'baseurl': 'www.example.com',
+ 'config': {'mirrorlist': url}}
+ wrong_config_item = {
+ 'repo_id': 'wrong-id',
+ 'baseurl': 'www.example.com',
+ 'config': {
+ 'gpgkey': 'file:///tmp/KEY-fedora-updates-fake-19'}}
+
+ yum_invalid_repos.append(wrong_baseurl)
+ yum_invalid_repos.append(wrong_mirrorlist)
+ yum_invalid_repos.append(wrong_config_item)
+
+ wrong_baseurl['config'] = {'dist': 'tasty'}
+ wrong_config = {'baseurl': deb_repos[0]['baseurl'],
+ 'config': {
+ 'unsupported_item': "a_unsupported_item"}}
+ deb_invalid_repos.append(wrong_baseurl)
+ deb_invalid_repos.append(wrong_config)
+
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ if repo_type == 'yum':
+ test_repos = yum_repos
+ invalid_repos = yum_invalid_repos
+ elif repo_type == 'deb':
+ test_repos = deb_repos
+ invalid_repos = deb_invalid_repos
+ else:
+ # repository management tool was not recognized by Kimchi
+ # skip test case
+ return
+
+ # create repositories with invalid data
+ for repo in invalid_repos:
+ self.assertRaises(InvalidParameter, inst.repositories_create, repo)
+
+ for repo in test_repos:
+ system_host_repos = len(inst.repositories_get_list())
+ repo_id = inst.repositories_create(repo)
+ host_repos = inst.repositories_get_list()
+ self.assertEquals(system_host_repos + 1, len(host_repos))
+
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(repo_id, repo_info['repo_id'])
+ self.assertEquals(True, repo_info.get('enabled'))
+ self.assertEquals(repo.get('baseurl', ''),
+ repo_info.get('baseurl'))
+
+ original_config = repo.get('config', {})
+ config_info = repo_info.get('config', {})
+
+ if repo_type == 'yum':
+ self.assertEquals(original_config.get('mirrorlist', ''),
+ config_info.get('mirrorlist', ''))
+ self.assertEquals(True, config_info['gpgcheck'])
+ else:
+ self.assertEquals(original_config['dist'], config_info['dist'])
+ self.assertEquals(original_config.get('comps', []),
+ config_info.get('comps', []))
+
+ inst.repository_delete(repo_id)
+ self.assertRaises(NotFoundError, inst.repository_lookup, repo_id)
+
+ self.assertRaises(NotFoundError, inst.repository_lookup, 'google')
+
+ def test_repository_update(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ yum_repo = {'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'}
+ yum_new_repo = {'baseurl': 'http://www.fedoraproject.org'}
+
+ deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal'}}
+ deb_new_repo = {'baseurl': 'http://br.archive.canonical.com/ubuntu/',
+ 'config': {'dist': 'utopic'}}
+
+ yum_invalid_repos = []
+ deb_invalid_repos = []
+
+ for url in invalid_repository_urls:
+ wrong_baseurl = {'baseurl': url}
+ wrong_mirrorlist = {'baseurl': 'www.example.com',
+ 'config': {'mirrorlist': url}}
+
+ yum_invalid_repos.append(wrong_baseurl)
+ yum_invalid_repos.append(wrong_mirrorlist)
+
+ wrong_baseurl['config'] = {'dist': 'tasty'}
+ deb_invalid_repos.append(wrong_baseurl)
+
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ if repo_type == 'yum':
+ repo = yum_repo
+ new_repo = yum_new_repo
+ invalid_repos = yum_invalid_repos
+ elif repo_type == 'deb':
+ repo = deb_repo
+ new_repo = deb_new_repo
+ invalid_repos = deb_invalid_repos
+ else:
+ # repository management tool was not recognized by Kimchi
+ # skip test case
+ return
+
+ system_host_repos = len(inst.repositories_get_list())
+
+ with RollbackContext() as rollback:
+ repo_id = inst.repositories_create(repo)
+ rollback.prependDefer(inst.repository_delete, repo_id)
+
+ host_repos = inst.repositories_get_list()
+ self.assertEquals(system_host_repos + 1, len(host_repos))
+
+ # update repositories with invalid data
+ for tmp_repo in invalid_repos:
+ self.assertRaises(InvalidParameter, inst.repository_update,
+ repo_id, tmp_repo)
+
+ new_repo_id = inst.repository_update(repo_id, new_repo)
+ repo_info = inst.repository_lookup(new_repo_id)
+
+ self.assertEquals(new_repo_id, repo_info['repo_id'])
+ self.assertEquals(new_repo['baseurl'], repo_info['baseurl'])
+ self.assertEquals(True, repo_info['enabled'])
+ inst.repository_update(new_repo_id, repo)
+
+ def test_repository_disable_enable(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ yum_repo = {'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'}
+ deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal'}}
+
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ if repo_type == 'yum':
+ repo = yum_repo
+ elif repo_type == 'deb':
+ repo = deb_repo
+ else:
+ # repository management tool was not recognized by Kimchi
+ # skip test case
+ return
+
+ system_host_repos = len(inst.repositories_get_list())
+
+ repo_id = inst.repositories_create(repo)
+
+ host_repos = inst.repositories_get_list()
+ self.assertEquals(system_host_repos + 1, len(host_repos))
+
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(True, repo_info['enabled'])
+
+ inst.repository_disable(repo_id)
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(False, repo_info['enabled'])
+
+ inst.repository_enable(repo_id)
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(True, repo_info['enabled'])
+
+ # remove files creates
+ inst.repository_delete(repo_id)
+
+
+class BaseModelTests(unittest.TestCase):
+ class FoosModel(object):
+ def __init__(self):
+ self.data = {}
+
+ def create(self, params):
+ self.data.update(params)
+
+ def get_list(self):
+ return list(self.data)
+
+ class TestModel(wok.basemodel.BaseModel):
+ def __init__(self):
+ foo = BaseModelTests.FoosModel()
+ super(BaseModelTests.TestModel, self).__init__([foo])
+
+ def test_root_model(self):
+ t = BaseModelTests.TestModel()
+ t.foos_create({'item1': 10})
+ self.assertEquals(t.foos_get_list(), ['item1'])
diff --git a/src/wok/plugins/kimchi/tests/test_model_network.py b/src/wok/plugins/kimchi/tests/test_model_network.py
new file mode 100644
index 0000000..e4cf5ef
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model_network.py
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.model.model import Model
+
+from utils import get_free_port, patch_auth, request, rollback_wrapper
+from utils import run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = Model(None, '/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+def _do_network_test(self, model, params):
+ with RollbackContext() as rollback:
+ net_name = params['name']
+ uri = '/plugins/kimchi/networks/%s' % net_name.encode('utf-8')
+
+ # Create a network
+ req = json.dumps(params)
+ resp = self.request('/plugins/kimchi/networks', req, 'POST')
+ rollback.prependDefer(rollback_wrapper, model.network_delete,
+ net_name)
+ self.assertEquals(201, resp.status)
+
+ # Verify the network
+ resp = self.request(uri)
+ network = json.loads(resp.read())
+ self.assertEquals('inactive', network['state'])
+ self.assertTrue(network['persistent'])
+
+ # activate the network
+ resp = self.request(uri + '/activate', '{}', 'POST')
+ rollback.prependDefer(rollback_wrapper,
+ model.network_deactivate, net_name)
+ self.assertEquals(200, resp.status)
+ resp = self.request(uri)
+ network = json.loads(resp.read())
+ self.assertEquals('active', network['state'])
+
+ # Deactivate the network
+ resp = self.request(uri + '/deactivate', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request(uri)
+ network = json.loads(resp.read())
+ self.assertEquals('inactive', network['state'])
+
+ # Delete the network
+ resp = self.request(uri, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+
+class NetworkTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_get_networks(self):
+ networks = json.loads(self.request('/plugins/kimchi/networks').read())
+ self.assertIn('default', [net['name'] for net in networks])
+
+ with RollbackContext() as rollback:
+ # Now add a couple of Networks to the mock model
+ for i in xrange(5):
+ name = 'network-%i' % i
+ req = json.dumps({'name': name,
+ 'connection': 'nat',
+ 'subnet': '127.0.10%i.0/24' % i})
+
+ resp = self.request('/plugins/kimchi/networks', req, 'POST')
+ rollback.prependDefer(model.network_delete, name)
+ self.assertEquals(201, resp.status)
+ network = json.loads(resp.read())
+ self.assertEquals([], network["vms"])
+
+ nets = json.loads(self.request('/plugins/kimchi/networks').read())
+ self.assertEquals(len(networks) + 5, len(nets))
+
+ network = json.loads(
+ self.request('/plugins/kimchi/networks/network-1').read()
+ )
+ keys = [u'name', u'connection', u'interface', u'subnet', u'dhcp',
+ u'vms', u'in_use', u'autostart', u'state', u'persistent']
+ self.assertEquals(sorted(keys), sorted(network.keys()))
+
+ def test_network_lifecycle(self):
+ # Verify all the supported network type
+ networks = [{'name': u'kīмÑhÄ«-пet', 'connection': 'isolated'},
+ {'name': u'nat-network', 'connection': 'nat'},
+ {'name': u'subnet-network', 'connection': 'nat',
+ 'subnet': '127.0.100.0/24'}]
+
+ # Verify the current system has at least one interface to create a
+ # bridged network
+ interfaces = json.loads(
+ self.request('/plugins/kimchi/interfaces?type=nic').read()
+ )
+ if len(interfaces) > 0:
+ iface = interfaces[0]['name']
+ networks.append({'name': u'bridge-network', 'connection': 'bridge',
+ 'interface': iface})
+
+ for net in networks:
+ _do_network_test(self, model, net)
diff --git a/src/wok/plugins/kimchi/tests/test_model_storagepool.py b/src/wok/plugins/kimchi/tests/test_model_storagepool.py
new file mode 100644
index 0000000..5f9b966
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model_storagepool.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import tempfile
+import unittest
+from functools import partial
+
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.model.model import Model
+
+from utils import get_free_port, patch_auth, request
+from utils import run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = Model(None, '/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class StoragepoolTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_get_storagepools(self):
+ storagepools = json.loads(
+ self.request('/plugins/kimchi/storagepools').read()
+ )
+ self.assertIn('default', [pool['name'] for pool in storagepools])
+
+ with RollbackContext() as rollback:
+ # Now add a couple of storage pools
+ for i in xrange(3):
+ name = u'kīмÑhÄ«-storagepool-%i' % i
+ req = json.dumps({'name': name, 'type': 'dir',
+ 'path': '/var/lib/libvirt/images/%i' % i})
+ resp = self.request('/plugins/kimchi/storagepools', req,
+ 'POST')
+ rollback.prependDefer(model.storagepool_delete, name)
+
+ self.assertEquals(201, resp.status)
+
+ # Pool name must be unique
+ req = json.dumps({'name': name, 'type': 'dir',
+ 'path': '/var/lib/libvirt/images/%i' % i})
+ resp = self.request('/plugins/kimchi/storagepools', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Verify pool information
+ resp = self.request('/plugins/kimchi/storagepools/%s' %
+ name.encode("utf-8"))
+ p = json.loads(resp.read())
+ keys = [u'name', u'state', u'capacity', u'allocated',
+ u'available', u'path', u'source', u'type',
+ u'nr_volumes', u'autostart', u'persistent']
+ self.assertEquals(sorted(keys), sorted(p.keys()))
+ self.assertEquals(name, p['name'])
+ self.assertEquals('inactive', p['state'])
+ self.assertEquals(True, p['persistent'])
+ self.assertEquals(True, p['autostart'])
+ self.assertEquals(0, p['nr_volumes'])
+
+ pools = json.loads(
+ self.request('/plugins/kimchi/storagepools').read()
+ )
+ self.assertEquals(len(storagepools) + 3, len(pools))
+
+ # Create a pool with an existing path
+ tmp_path = tempfile.mkdtemp(dir='/var/lib/kimchi')
+ rollback.prependDefer(os.rmdir, tmp_path)
+ req = json.dumps({'name': 'existing_path', 'type': 'dir',
+ 'path': tmp_path})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ rollback.prependDefer(model.storagepool_delete, 'existing_path')
+ self.assertEquals(201, resp.status)
+
+ # Reserved pool return 400
+ req = json.dumps({'name': 'kimchi_isos', 'type': 'dir',
+ 'path': '/var/lib/libvirt/images/%i' % i})
+ resp = request(host, ssl_port, '/plugins/kimchi/storagepools', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
diff --git a/src/wok/plugins/kimchi/tests/test_model_storagevolume.py b/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
new file mode 100644
index 0000000..46c07bd
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
@@ -0,0 +1,280 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import requests
+import unittest
+from functools import partial
+
+from wok.config import paths
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.config import READONLY_POOL_TYPE
+from wok.plugins.kimchi.mockmodel import MockModel
+from wok.plugins.kimchi.model.model import Model
+
+from utils import fake_auth_header, get_free_port, patch_auth, request
+from utils import rollback_wrapper, run_server, wait_task
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = Model(None, '/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+def _do_volume_test(self, model, host, ssl_port, pool_name):
+ def _task_lookup(taskid):
+ return json.loads(
+ self.request('/tasks/%s' % taskid).read()
+ )
+
+ uri = '/plugins/kimchi/storagepools/%s/storagevolumes' \
+ % pool_name.encode('utf-8')
+ resp = self.request(uri)
+ self.assertEquals(200, resp.status)
+
+ resp = self.request('/plugins/kimchi/storagepools/%s' %
+ pool_name.encode('utf-8'))
+ pool_info = json.loads(resp.read())
+ with RollbackContext() as rollback:
+ # Create storage volume with 'capacity'
+ vol = 'test-volume'
+ vol_uri = uri + '/' + vol
+ req = json.dumps({'name': vol, 'format': 'raw',
+ 'capacity': 1073741824}) # 1 GiB
+ resp = self.request(uri, req, 'POST')
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ self.assertEquals(400, resp.status)
+ else:
+ rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
+ pool_name, vol)
+ self.assertEquals(202, resp.status)
+ task_id = json.loads(resp.read())['id']
+ wait_task(_task_lookup, task_id)
+ status = json.loads(
+ self.request('/tasks/%s' % task_id).read()
+ )
+ self.assertEquals('finished', status['status'])
+ vol_info = json.loads(self.request(vol_uri).read())
+ vol_info['name'] = vol
+ vol_info['format'] = 'raw'
+ vol_info['capacity'] = 1073741824
+
+ # Resize the storage volume: increase its capacity to 2 GiB
+ req = json.dumps({'size': 2147483648}) # 2 GiB
+ resp = self.request(vol_uri + '/resize', req, 'POST')
+ self.assertEquals(200, resp.status)
+ storagevolume = json.loads(self.request(vol_uri).read())
+ self.assertEquals(2147483648, storagevolume['capacity'])
+
+ # Resize the storage volume: decrease its capacity to 512 MiB
+ # FIXME: Due a libvirt bug it is not possible to decrease the
+ # volume capacity
+ # For reference:
+ # - https://bugzilla.redhat.com/show_bug.cgi?id=1021802
+ req = json.dumps({'size': 536870912}) # 512 MiB
+ resp = self.request(vol_uri + '/resize', req, 'POST')
+ # It is only possible when using MockModel
+ if isinstance(model, MockModel):
+ self.assertEquals(200, resp.status)
+ storagevolume = json.loads(self.request(vol_uri).read())
+ self.assertEquals(536870912, storagevolume['capacity'])
+ else:
+ self.assertEquals(500, resp.status)
+
+ # Wipe the storage volume
+ resp = self.request(vol_uri + '/wipe', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ storagevolume = json.loads(self.request(vol_uri).read())
+ self.assertEquals(0, storagevolume['allocation'])
+
+ # Clone the storage volume
+ vol_info = json.loads(self.request(vol_uri).read())
+ resp = self.request(vol_uri + '/clone', '{}', 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ cloned_vol_name = task['target_uri'].split('/')[-1]
+ rollback.prependDefer(model.storagevolume_delete, pool_name,
+ cloned_vol_name)
+ wait_task(_task_lookup, task['id'])
+ task = json.loads(
+ self.request('/tasks/%s' % task['id']).read()
+ )
+ self.assertEquals('finished', task['status'])
+ resp = self.request(uri + '/' + cloned_vol_name.encode('utf-8'))
+
+ self.assertEquals(200, resp.status)
+ cloned_vol = json.loads(resp.read())
+
+ self.assertNotEquals(vol_info['name'], cloned_vol['name'])
+ self.assertNotEquals(vol_info['path'], cloned_vol['path'])
+ for key in ['name', 'path', 'allocation']:
+ del vol_info[key]
+ del cloned_vol[key]
+
+ self.assertEquals(vol_info, cloned_vol)
+
+ # Delete the storage volume
+ resp = self.request(vol_uri, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+ resp = self.request(vol_uri)
+ self.assertEquals(404, resp.status)
+
+ # Storage volume upload
+ # It is done through a sequence of POST and several PUT requests
+ filename = 'COPYING.LGPL'
+ filepath = os.path.join(paths.get_prefix(), filename)
+ filesize = os.stat(filepath).st_size
+
+ # Create storage volume for upload
+ req = json.dumps({'name': filename, 'format': 'raw',
+ 'capacity': filesize, 'upload': True})
+ resp = self.request(uri, req, 'POST')
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ self.assertEquals(400, resp.status)
+ else:
+ rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
+ pool_name, filename)
+ self.assertEquals(202, resp.status)
+ task_id = json.loads(resp.read())['id']
+ wait_task(_task_lookup, task_id)
+ status = json.loads(self.request('/tasks/%s' %
+ task_id).read())
+ self.assertEquals('ready for upload', status['message'])
+
+ # Upload volume content
+ url = 'https://%s:%s' % (host, ssl_port) + uri + '/' + filename
+
+ # Create a file with 5M to upload
+ # Max body size is set to 4M so the upload will fail with 413
+ newfile = '/tmp/5m-file'
+ with open(newfile, 'wb') as fd:
+ fd.seek(5*1024*1024-1)
+ fd.write("\0")
+ rollback.prependDefer(os.remove, newfile)
+
+ with open(newfile, 'rb') as fd:
+ with open(newfile + '.tmp', 'wb') as tmp_fd:
+ data = fd.read()
+ tmp_fd.write(data)
+
+ with open(newfile + '.tmp', 'rb') as tmp_fd:
+ r = requests.put(url, data={'chunk_size': len(data)},
+ files={'chunk': tmp_fd},
+ verify=False,
+ headers=fake_auth_header())
+ self.assertEquals(r.status_code, 413)
+
+ # Do upload
+ index = 0
+ chunk_size = 2 * 1024
+ content = ''
+
+ with open(filepath, 'rb') as fd:
+ while True:
+ with open(filepath + '.tmp', 'wb') as tmp_fd:
+ fd.seek(index*chunk_size)
+ data = fd.read(chunk_size)
+ tmp_fd.write(data)
+
+ with open(filepath + '.tmp', 'rb') as tmp_fd:
+ r = requests.put(url, data={'chunk_size': len(data)},
+ files={'chunk': tmp_fd},
+ verify=False,
+ headers=fake_auth_header())
+ self.assertEquals(r.status_code, 200)
+ content += data
+ index = index + 1
+
+ if len(data) < chunk_size:
+ break
+
+ rollback.prependDefer(os.remove, filepath + '.tmp')
+ resp = self.request(uri + '/' + filename)
+ self.assertEquals(200, resp.status)
+ uploaded_path = json.loads(resp.read())['path']
+ with open(uploaded_path) as fd:
+ uploaded_content = fd.read()
+
+ self.assertEquals(content, uploaded_content)
+
+ # Create storage volume with 'url'
+ url = 'https://github.com/kimchi-project/kimchi/raw/master/COPYING'
+ req = json.dumps({'url': url})
+ resp = self.request(uri, req, 'POST')
+
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ self.assertEquals(400, resp.status)
+ else:
+ rollback.prependDefer(model.storagevolume_delete, pool_name,
+ 'COPYING')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(_task_lookup, task['id'])
+ resp = self.request(uri + '/COPYING')
+ self.assertEquals(200, resp.status)
+
+
+class StorageVolumeTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_get_storagevolume(self):
+ uri = '/plugins/kimchi/storagepools/default/storagevolumes'
+ resp = self.request(uri)
+ self.assertEquals(200, resp.status)
+
+ keys = [u'name', u'type', u'capacity', u'allocation', u'path',
+ u'used_by', u'format']
+ for vol in json.loads(resp.read()):
+ resp = self.request(uri + '/' + vol['name'])
+ self.assertEquals(200, resp.status)
+
+ all_keys = keys[:]
+ vol_info = json.loads(resp.read())
+ if vol_info['format'] == 'iso':
+ all_keys.extend([u'os_distro', u'os_version', u'bootable'])
+
+ self.assertEquals(sorted(all_keys), sorted(vol_info.keys()))
+
+ def test_storagevolume_action(self):
+ _do_volume_test(self, model, host, ssl_port, 'default')
diff --git a/src/wok/plugins/kimchi/tests/test_networkxml.py b/src/wok/plugins/kimchi/tests/test_networkxml.py
new file mode 100644
index 0000000..a64b6c2
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_networkxml.py
@@ -0,0 +1,172 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ipaddr
+import lxml.etree as ET
+import unittest
+
+from wok.xmlutils.utils import xpath_get_text
+
+from wok.plugins.kimchi.xmlutils import network as nxml
+
+import utils
+
+
+class NetworkXmlTests(unittest.TestCase):
+ def test_dhcp_xml(self):
+ """
+ Test network dhcp xml
+ """
+ dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"}
+ host1 = {"mac": "00:16:3e:77:e2:ed",
+ "name": "foo.example.com",
+ "ip": "192.168.122.10"}
+ host2 = {"mac": "00:16:3e:3e:a9:1a",
+ "name": "bar.example.com",
+ "ip": "192.168.122.11"}
+ params = {}
+
+ dhcp = nxml._get_dhcp_elem(**params)
+ self.assertEquals(None, dhcp)
+
+ params["range"] = dhcp_range
+ xml = ET.tostring(nxml._get_dhcp_elem(**params))
+ start = xpath_get_text(xml, "/dhcp/range/@start")
+ end = xpath_get_text(xml, "/dhcp/range/@end")
+ self.assertEquals(dhcp_range['start'], start[0])
+ self.assertEquals(dhcp_range['end'], end[0])
+
+ params["hosts"] = [host1, host2]
+ xml = ET.tostring(nxml._get_dhcp_elem(**params))
+ ip = xpath_get_text(xml, "/dhcp/host/@ip")
+ self.assertEquals(ip, [host1['ip'], host2['ip']])
+
+ def test_ip_xml(self):
+ """
+ Test network ip xml
+ """
+ dhcp_range = {"start": "192.168.122.100", "end": "192.168.122.254"}
+ params = {}
+
+ dhcp = nxml._get_dhcp_elem(**params)
+ self.assertEquals(None, dhcp)
+
+ params["net"] = "192.168.122.0/255.255.255.0"
+ params["dhcp"] = {'range': dhcp_range}
+ xml = ET.tostring(nxml._get_ip_elem(**params))
+ start = xpath_get_text(xml, "/ip/dhcp/range/@start")[0]
+ end = xpath_get_text(xml, "/ip/dhcp/range/@end")[0]
+ self.assertEquals(dhcp_range['start'], start)
+ self.assertEquals(dhcp_range['end'], end)
+
+ address = xpath_get_text(xml, "/ip/@address")[0]
+ netmask = xpath_get_text(xml, "/ip/@netmask")[0]
+ self.assertEquals(address, params["net"].split("/")[0])
+ self.assertEquals(netmask, params["net"].split("/")[1])
+
+ # test _get_ip_xml can accepts strings: '192.168.122.0/24',
+ # which is same as "192.168.122.0/255.255.255.0"
+ params["net"] = "192.168.122.0/24"
+ xml = ET.tostring(nxml._get_ip_elem(**params))
+ netmask = xpath_get_text(xml, "/ip/@netmask")[0]
+ self.assertEquals(netmask,
+ str(ipaddr.IPNetwork(params["net"]).netmask))
+
+ def test_forward_xml(self):
+ """
+ Test network forward xml
+ """
+ params = {"mode": None}
+
+ forward = nxml._get_forward_elem(**params)
+ self.assertEquals(None, forward)
+
+ params["mode"] = 'nat'
+ params["dev"] = 'eth0'
+ xml = ET.tostring(nxml._get_forward_elem(**params))
+ mode = xpath_get_text(xml, "/forward/@mode")[0]
+ dev = xpath_get_text(xml, "/forward/@dev")[0]
+ self.assertEquals(params['mode'], mode)
+ self.assertEquals(params['dev'], dev)
+
+ def test_network_xml(self):
+ """
+ Test network xml
+ """
+ params = {"name": "test",
+ "forward": {"mode": "nat", "dev": ""},
+ "net": "192.168.0.0/255.255.255.0"}
+ xml = nxml.to_network_xml(**params)
+ name = xpath_get_text(xml, "/network/name")[0]
+ self.assertEquals(name, params['name'])
+
+ forward_mode = xpath_get_text(xml, "/network/forward/@mode")[0]
+ self.assertEquals(forward_mode, params['forward']['mode'])
+ forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
+ self.assertEquals(forward_dev, '')
+
+ address = xpath_get_text(xml, "/network/ip/@address")[0]
+ self.assertEquals(address, params["net"].split("/")[0])
+ netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
+ self.assertEquals(netmask, params["net"].split("/")[1])
+
+ dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
+ self.assertEquals(dhcp_start, [])
+ dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
+ self.assertEquals(dhcp_end, [])
+
+ # test optional params
+ params['forward']['dev'] = "eth0"
+ params['dhcp'] = {"range": {'start': '192.168.0.1',
+ 'end': '192.168.0.254'}}
+ xml = nxml.to_network_xml(**params)
+ forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
+ self.assertEquals(forward_dev, params['forward']['dev'])
+
+ dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")[0]
+ self.assertEquals(dhcp_start, params['dhcp']['range']['start'])
+ dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")[0]
+ self.assertEquals(dhcp_end, params['dhcp']['range']['end'])
+
+ # test _get_ip_xml can accepts strings: '192.168.122.0/24',
+ # which is same as "192.168.122.0/255.255.255.0"
+ params["net"] = "192.168.0.0/24"
+ xml = nxml.to_network_xml(**params)
+ netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
+ self.assertEquals(netmask,
+ str(ipaddr.IPNetwork(params["net"]).netmask))
+
+
+class InterfaceXmlTests(unittest.TestCase):
+
+ def test_vlan_tagged_bridge_no_ip(self):
+ expected_xml = """
+ <interface type='bridge' name='br10'>
+ <start mode='onboot'/>
+ <bridge>
+ <interface type='vlan' name='em1.10'>
+ <vlan tag='10'>
+ <interface name='em1'/>
+ </vlan>
+ </interface>
+ </bridge>
+ </interface>
+ """
+ actual_xml = nxml.create_vlan_tagged_bridge_xml('br10', 'em1', '10')
+ self.assertEquals(actual_xml, utils.normalize_xml(expected_xml))
diff --git a/src/wok/plugins/kimchi/tests/test_objectstore.py b/src/wok/plugins/kimchi/tests/test_objectstore.py
new file mode 100644
index 0000000..632786f
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_objectstore.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import tempfile
+import threading
+import unittest
+
+from wok import objectstore
+from wok.exception import NotFoundError
+
+
+tmpfile = None
+
+
+def setUpModule():
+ global tmpfile
+ tmpfile = tempfile.mktemp()
+
+
+def tearDownModule():
+ os.unlink(tmpfile)
+
+
+class ObjectStoreTests(unittest.TestCase):
+ def test_objectstore(self):
+ store = objectstore.ObjectStore(tmpfile)
+
+ with store as session:
+ # Test create
+ session.store('fÇÇ', 'tÄst1', {'α': 1})
+ session.store('fÇÇ', 'tÄst2', {'β': 2})
+
+ # Test list
+ items = session.get_list('fÇÇ')
+ self.assertTrue(u'tÄst1' in items)
+ self.assertTrue(u'tÄst2' in items)
+
+ # Test get
+ item = session.get('fÇÇ', 'tÄst1')
+ self.assertEquals(1, item[u'α'])
+
+ # Test delete
+ session.delete('fÇÇ', 'tÄst2')
+ self.assertEquals(1, len(session.get_list('fÇÇ')))
+
+ # Test get non-existent item
+
+ self.assertRaises(NotFoundError, session.get,
+ 'α', 'β')
+
+ # Test delete non-existent item
+ self.assertRaises(NotFoundError, session.delete,
+ 'fÇÇ', 'tÄst2')
+
+ # Test refresh existing item
+ session.store('fÇÇ', 'tÄst1', {'α': 2})
+ item = session.get('fÇÇ', 'tÄst1')
+ self.assertEquals(2, item[u'α'])
+
+ def test_object_store_threaded(self):
+ def worker(ident):
+ with store as session:
+ session.store('foo', ident, {})
+
+ store = objectstore.ObjectStore(tmpfile)
+
+ threads = []
+ for i in xrange(50):
+ t = threading.Thread(target=worker, args=(i,))
+ t.setDaemon(True)
+ t.start()
+ threads.append(t)
+
+ for t in threads:
+ t.join()
+
+ with store as session:
+ self.assertEquals(50, len(session.get_list('foo')))
+ self.assertEquals(10, len(store._connections.keys()))
diff --git a/src/wok/plugins/kimchi/tests/test_osinfo.py b/src/wok/plugins/kimchi/tests/test_osinfo.py
new file mode 100644
index 0000000..bd2af58
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_osinfo.py
@@ -0,0 +1,69 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+
+from wok.plugins.kimchi.osinfo import _get_arch, get_template_default, lookup
+from wok.plugins.kimchi.osinfo import modern_version_bases
+
+
+class OSInfoTests(unittest.TestCase):
+ def test_default_lookup(self):
+ entry = lookup(None, None)
+ self.assertEquals('unknown', entry['os_distro'])
+ self.assertEquals('unknown', entry['os_version'])
+ self.assertEquals(['default'], entry['networks'])
+
+ def test_old_distros(self):
+ old_versions = {'debian': '5.0', 'ubuntu': '7.04', 'opensuse': '10.1',
+ 'centos': '5.1', 'rhel': '5.1', 'fedora': '15'}
+ for distro, version in old_versions.iteritems():
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('old', 'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('old', 'nic_model'))
+
+ def test_modern_bases(self):
+ for distro, version in modern_version_bases[_get_arch()].iteritems():
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('modern', 'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('modern', 'nic_model'))
+
+ def test_modern_distros(self):
+ # versions based on ppc64 modern distros
+ modern_versions = {'ubuntu': '14.04', 'opensuse': '13.1',
+ 'rhel': '6.5', 'fedora': '19', 'sles': '11sp3'}
+ for distro, version in modern_versions.iteritems():
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('modern', 'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('modern', 'nic_model'))
+
+ def test_lookup_unknown_distro_version_returns_old_distro(self):
+ distro = 'unknown_distro'
+ version = 'unknown_version'
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('old', 'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('old', 'nic_model'))
diff --git a/src/wok/plugins/kimchi/tests/test_plugin.py b/src/wok/plugins/kimchi/tests/test_plugin.py
new file mode 100644
index 0000000..fc8e277
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_plugin.py
@@ -0,0 +1,126 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.utils import get_enabled_plugins
+
+from wok.plugins.kimchi import mockmodel
+
+import utils
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port
+
+ utils.patch_auth()
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = utils.get_free_port('http')
+ ssl_port = utils.get_free_port('https')
+ test_server = utils.run_server(host, port, ssl_port, test_mode=True,
+ model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+ at unittest.skipUnless(
+ 'sample' in [plugin for plugin, _config in get_enabled_plugins()],
+ 'sample plugin is not enabled, skip this test!')
+class PluginTests(unittest.TestCase):
+
+ def setUp(self):
+ self.request = partial(utils.request, host, ssl_port)
+
+ def _create_rectangle(self, name, length, width):
+ req = json.dumps({'name': name, 'length': length, 'width': width})
+ resp = self.request('/plugins/sample/rectangles', req, 'POST')
+ return resp
+
+ def _get_rectangle(self, name):
+ resp = self.request('/plugins/sample/rectangles/%s' % name)
+ return json.loads(resp.read())
+
+ def _create_rectangle_and_assert(self, name, length, width):
+ resp = self._create_rectangle(name, length, width)
+ self.assertEquals(201, resp.status)
+
+ rectangle = self._get_rectangle(name)
+ self.assertEquals(rectangle['name'], name)
+ self.assertEquals(rectangle['length'], length)
+ self.assertEquals(rectangle['width'], width)
+
+ def _get_rectangles_list(self):
+ resp = self.request('/plugins/sample/rectangles')
+ rectangles = json.loads(resp.read())
+ name_list = [rectangle['name'] for rectangle in rectangles]
+ return name_list
+
+ def test_rectangles(self):
+ # Create two new rectangles
+ self._create_rectangle_and_assert('small', 10, 8)
+ self._create_rectangle_and_assert('big', 20, 16)
+
+ # Verify they're in the list
+ name_list = self._get_rectangles_list()
+ self.assertIn('small', name_list)
+ self.assertIn('big', name_list)
+
+ # Update the big rectangle.
+ req = json.dumps({'length': 40, 'width': 30})
+ resp = self.request('/plugins/sample/rectangles/big', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ big = self._get_rectangle('big')
+ self.assertEquals(big['length'], 40)
+ self.assertEquals(big['width'], 30)
+
+ # Delete two rectangles
+ resp = self.request('/plugins/sample/rectangles/big', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+ resp = self.request('/plugins/sample/rectangles/small', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+ name_list = self._get_rectangles_list()
+ self.assertEquals([], name_list)
+
+ def test_bad_params(self):
+ # Bad name
+ resp = self._create_rectangle(1.0, 30, 40)
+ self.assertEquals(400, resp.status)
+
+ # Bad length value
+ resp = self._create_rectangle('test', -10.0, 40)
+ self.assertEquals(400, resp.status)
+
+ # Missing param for width
+ req = json.dumps({'name': 'nowidth', 'length': 40})
+ resp = self.request('/plugins/sample/rectangles', req, 'POST')
+ self.assertEquals(400, resp.status)
diff --git a/src/wok/plugins/kimchi/tests/test_rest.py b/src/wok/plugins/kimchi/tests/test_rest.py
new file mode 100644
index 0000000..243074e
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_rest.py
@@ -0,0 +1,1327 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import re
+import time
+import unittest
+import urllib2
+import urlparse
+from functools import partial
+
+from wok.rollbackcontext import RollbackContext
+from wok.utils import add_task
+
+from wok.plugins.kimchi import mockmodel
+from wok.plugins.kimchi.osinfo import get_template_default
+
+import iso_gen
+from utils import get_free_port, patch_auth, request
+from utils import run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+fake_iso = '/tmp/fake.iso'
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+ # Create fake ISO to do the tests
+ iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
+ iso_gen.construct_fake_iso("/var/lib/libvirt/images/fedora.iso", True,
+ "17", "fedora")
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+ os.unlink(fake_iso)
+ os.unlink("/var/lib/libvirt/images/fedora.iso")
+
+
+class RestTests(unittest.TestCase):
+ def _async_op(self, cb, opaque):
+ time.sleep(1)
+ cb('success', True)
+
+ def _except_op(self, cb, opaque):
+ time.sleep(1)
+ raise Exception("Oops, this is an exception handle test."
+ " You can ignore it safely")
+ cb('success', True)
+
+ def _intermid_op(self, cb, opaque):
+ time.sleep(1)
+ cb('in progress')
+
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def assertHTTPStatus(self, code, *args):
+ resp = self.request(*args)
+ self.assertEquals(code, resp.status)
+
+ def test_get_vms(self):
+ vms = json.loads(self.request('/plugins/kimchi/vms').read())
+ # test_rest.py uses MockModel() which connects to libvirt URI
+ # test:///default. By default this driver already has one VM created
+ self.assertEquals(1, len(vms))
+
+ # Create a template as a base for our VMs
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ test_users = ['root']
+ test_groups = ['wheel']
+ # Now add a couple of VMs to the mock model
+ for i in xrange(10):
+ name = 'vm-%i' % i
+ req = json.dumps({'name': name,
+ 'template': '/plugins/kimchi/templates/test',
+ 'users': test_users, 'groups': test_groups})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ vms = json.loads(self.request('/plugins/kimchi/vms').read())
+ self.assertEquals(11, len(vms))
+
+ vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
+ self.assertEquals('vm-1', vm['name'])
+ self.assertEquals('shutoff', vm['state'])
+ self.assertEquals([], vm['users'])
+ self.assertEquals([], vm['groups'])
+
+ def test_edit_vm(self):
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ req = json.dumps({'name': 'vm-1',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
+ self.assertEquals('vm-1', vm['name'])
+
+ resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+
+ req = json.dumps({'unsupported-attr': 'attr'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'name': 'new-vm'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'cpus': 3})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+
+ # Check if there is support to memory hotplug, once vm is running
+ resp = self.request('/plugins/kimchi/config/capabilities').read()
+ conf = json.loads(resp)
+ req = json.dumps({'memory': 2048})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ if conf['mem_hotplug_support']:
+ self.assertEquals(200, resp.status)
+ else:
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({"graphics": {'passwd': "abcdef"}})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ info = json.loads(resp.read())
+ self.assertEquals('abcdef', info["graphics"]["passwd"])
+ self.assertEquals(None, info["graphics"]["passwdValidTo"])
+
+ resp = self.request('/plugins/kimchi/vms/vm-1/poweroff', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+
+ req = json.dumps({"graphics": {'passwd': "123456",
+ 'passwdValidTo': 20}})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ info = json.loads(resp.read())
+ self.assertEquals('123456', info["graphics"]["passwd"])
+ self.assertGreaterEqual(20, info["graphics"]["passwdValidTo"])
+
+ req = json.dumps({'name': 12})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'name': ''})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'cpus': -2})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'cpus': 'four'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'memory': 100})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'memory': 'ten gigas'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'name': 'new-name', 'cpus': 5, 'UUID': 'notallowed'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ params = {'name': u'â¨Ð¼-ÑÑdαtеd', 'cpus': 5, 'memory': 3072}
+ req = json.dumps(params)
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(303, resp.status)
+ vm = json.loads(
+ self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req).read()
+ )
+ for key in params.keys():
+ self.assertEquals(params[key], vm[key])
+
+ # change only VM users - groups are not changed (default is empty)
+ resp = self.request('/plugins/kimchi/users', '{}', 'GET')
+ users = json.loads(resp.read())
+ req = json.dumps({'users': users})
+ resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ info = json.loads(
+ self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', '{}').read()
+ )
+ self.assertEquals(users, info['users'])
+
+ # change only VM groups - users are not changed (default is empty)
+ resp = self.request('/plugins/kimchi/groups', '{}', 'GET')
+ groups = json.loads(resp.read())
+ req = json.dumps({'groups': groups})
+ resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ info = json.loads(
+ self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', '{}').read()
+ )
+ self.assertEquals(groups, info['groups'])
+
+ # change VM users (wrong value) and groups
+ # when an error occurs, everything fails and nothing is changed
+ req = json.dumps({'users': ['userdoesnotexist'], 'groups': []})
+ resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ # change VM users and groups (wrong value)
+ # when an error occurs, everything fails and nothing is changed
+ req = json.dumps({'users': [], 'groups': ['groupdoesnotexist']})
+ resp = self.request('/plugins/kimchi/vms/â¨Ð¼-ÑÑdαtеd', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ def test_vm_lifecycle(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'disks': [{'size': 1}],
+ 'icon': 'images/icon-debian.png',
+ 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create a VM
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ self.assertEquals(202, resp.status)
+
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('shutoff', vm['state'])
+ self.assertEquals('images/icon-debian.png', vm['icon'])
+
+ # Verify the volume was created
+ vol_uri = '/plugins/kimchi/storagepools/default-pool/storagevolumes/' \
+ + '%s-0.img'
+ resp = self.request(vol_uri % vm['uuid'])
+ vol = json.loads(resp.read())
+ self.assertEquals(1 << 30, vol['capacity'])
+ self.assertEquals(['test-vm'], vol['used_by'])
+
+ # Start the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('running', vm['state'])
+
+ # Test screenshot
+ resp = self.request(vm['screenshot'], method='HEAD')
+ self.assertEquals(200, resp.status)
+ self.assertTrue(resp.getheader('Content-type').startswith('image'))
+
+ # Clone a running VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}', 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Force poweroff the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}',
+ 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('shutoff', vm['state'])
+
+ # Test create VM with same name fails with 400
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Clone a VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}', 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ task = json.loads(
+ self.request('/tasks/%s' % task['id'], '{}').read()
+ )
+ self.assertEquals('finished', task['status'])
+ clone_vm_name = task['target_uri'].split('/')[-2]
+ self.assertTrue(re.match(u'test-vm-clone-\d+', clone_vm_name))
+
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}')
+ original_vm_info = json.loads(resp.read())
+ resp = self.request('/plugins/kimchi/vms/%s' % clone_vm_name, '{}')
+ self.assertEquals(200, resp.status)
+ clone_vm_info = json.loads(resp.read())
+
+ self.assertNotEqual(original_vm_info['name'], clone_vm_info['name'])
+ del original_vm_info['name']
+ del clone_vm_info['name']
+
+ self.assertNotEqual(original_vm_info['uuid'], clone_vm_info['uuid'])
+ del original_vm_info['uuid']
+ del clone_vm_info['uuid']
+
+ self.assertEquals(original_vm_info, clone_vm_info)
+
+ # Create a snapshot on a stopped VM
+ params = {'name': 'test-snap'}
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
+ json.dumps(params),
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ task = json.loads(
+ self.request('/tasks/%s' % task['id']).read()
+ )
+ self.assertEquals('finished', task['status'])
+
+ # Look up a non-existing snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/snap404',
+ '{}', 'GET')
+ self.assertEquals(404, resp.status)
+
+ # Look up a snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
+ params['name'], '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ self.assertTrue(int(time.time()) >= int(snap['created']))
+ self.assertEquals(params['name'], snap['name'])
+ self.assertEquals(u'', snap['parent'])
+ self.assertEquals(u'shutoff', snap['state'])
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots', '{}',
+ 'GET')
+ self.assertEquals(200, resp.status)
+ snaps = json.loads(resp.read())
+ self.assertEquals(1, len(snaps))
+
+ # Look up current snapshot (the one created above)
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
+ '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ self.assertEquals(params['name'], snap['name'])
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots', '{}',
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ snap_name = task['target_uri'].split('/')[-1]
+ wait_task(self._task_lookup, task['id'])
+ resp = self.request('/tasks/%s' % task['id'], '{}',
+ 'GET')
+ task = json.loads(resp.read())
+ self.assertEquals('finished', task['status'])
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots', '{}',
+ 'GET')
+ self.assertEquals(200, resp.status)
+ snaps = json.loads(resp.read())
+ self.assertEquals(2, len(snaps))
+
+ # Look up current snapshot (the one created above)
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
+ '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ self.assertEquals(snap_name, snap['name'])
+
+ # Revert to snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s/revert' %
+ params['name'], '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], snap['state'])
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
+ '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ current_snap = json.loads(resp.read())
+ self.assertEquals(snap, current_snap)
+
+ # Delete a snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
+ params['name'], '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Suspend the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'shutoff')
+ resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
+ 'POST')
+ self.assertEquals(400, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'running')
+ resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
+ 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'paused')
+
+ # Resume the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/resume', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'running')
+
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Delete the Template
+ resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Verify the volume was deleted
+ self.assertHTTPStatus(404, vol_uri % vm['uuid'])
+
+ def test_vm_graphics(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create a VM with default args
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('127.0.0.1', vm['graphics']['listen'])
+ self.assertEquals('vnc', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a VM with specified graphics type and listen
+ graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('127.0.0.1', vm['graphics']['listen'])
+ self.assertEquals('vnc', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a VM with listen as ipv6 address
+ graphics = {'type': 'spice', 'listen': 'fe00::0'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('fe00::0', vm['graphics']['listen'])
+ self.assertEquals('spice', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a VM with specified graphics type and default listen
+ graphics = {'type': 'spice'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('127.0.0.1', vm['graphics']['listen'])
+ self.assertEquals('spice', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Try to create a VM with invalid graphics type
+ graphics = {'type': 'invalid'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Try to create a VM with invalid graphics listen
+ graphics = {'type': 'spice', 'listen': 'invalid'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Delete the Template
+ resp = self.request('/plugins/kimchi/templates/test', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_vm_storage_devices(self):
+
+ with RollbackContext() as rollback:
+ # Create a template as a base for our VMs
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ # Delete the template
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/templates/test', '{}',
+ 'DELETE')
+
+ # Create a VM with default args
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Delete the VM
+ rollback.prependDefer(self.request, '/plugins/kimchi/vms/test-vm',
+ '{}', 'DELETE')
+
+ # Check storage devices
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages', '{}',
+ 'GET')
+ devices = json.loads(resp.read())
+ self.assertEquals(2, len(devices))
+ dev_types = []
+ for d in devices:
+ self.assertIn(u'type', d.keys())
+ self.assertIn(u'dev', d.keys())
+ self.assertIn(u'path', d.keys())
+ dev_types.append(d['type'])
+
+ self.assertEquals(['cdrom', 'disk'], sorted(dev_types))
+
+ # Attach cdrom with nonexistent iso
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'cdrom',
+ 'path': '/tmp/nonexistent.iso'})
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Create temp storage pool
+ req = json.dumps({'name': 'tmp',
+ 'capacity': 1024,
+ 'allocated': 512,
+ 'path': '/tmp',
+ 'type': 'dir'})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/tmp/activate',
+ req, 'POST')
+ self.assertEquals(200, resp.status)
+
+ # 'name' is required for this type of volume
+ req = json.dumps({'capacity': 1024,
+ 'allocation': 512,
+ 'type': 'disk',
+ 'format': 'raw'})
+ resp = self.request(
+ '/plugins/kimchi/storagepools/tmp/storagevolumes', req, 'POST'
+ )
+ self.assertEquals(400, resp.status)
+ req = json.dumps({'name': "attach-volume",
+ 'capacity': 1024,
+ 'allocation': 512,
+ 'type': 'disk',
+ 'format': 'raw'})
+ resp = self.request(
+ '/plugins/kimchi/storagepools/tmp/storagevolumes', req, 'POST'
+ )
+ self.assertEquals(202, resp.status)
+ time.sleep(1)
+
+ # Attach cdrom with both path and volume specified
+ open('/tmp/existent.iso', 'w').close()
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'cdrom',
+ 'pool': 'tmp',
+ 'vol': 'attach-volume',
+ 'path': '/tmp/existent.iso'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(400, resp.status)
+
+ # Attach disk with both path and volume specified
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'disk',
+ 'pool': 'tmp',
+ 'vol': 'attach-volume',
+ 'path': '/tmp/existent.iso'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(400, resp.status)
+
+ # Attach disk with only pool specified
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'cdrom',
+ 'pool': 'tmp'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(400, resp.status)
+
+ # Attach disk with pool and vol specified
+ req = json.dumps({'type': 'disk',
+ 'pool': 'tmp',
+ 'vol': 'attach-volume'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(201, resp.status)
+ cd_info = json.loads(resp.read())
+ self.assertEquals('disk', cd_info['type'])
+
+ # Attach a cdrom with existent dev name
+ req = json.dumps({'type': 'cdrom',
+ 'path': '/tmp/existent.iso'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(201, resp.status)
+ cd_info = json.loads(resp.read())
+ cd_dev = cd_info['dev']
+ self.assertEquals('cdrom', cd_info['type'])
+ self.assertEquals('/tmp/existent.iso', cd_info['path'])
+ # Delete the file and cdrom
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/vms/test-vm/storages/hdx',
+ '{}', 'DELETE')
+ os.remove('/tmp/existent.iso')
+
+ # Change path of storage cdrom
+ cdrom = u'http://fedora.mirrors.tds.net/pub/fedora/releases/20/'\
+ 'Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso'
+ req = json.dumps({'path': cdrom})
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
+ cd_dev, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ cd_info = json.loads(resp.read())
+ self.assertEquals(urlparse.urlparse(cdrom).path,
+ urlparse.urlparse(cd_info['path']).path)
+
+ # Test GET
+ devs = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/storages').read()
+ )
+ self.assertEquals(4, len(devs))
+
+ # Detach storage cdrom
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
+ cd_dev, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Test GET
+ devs = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/storages').read()
+ )
+ self.assertEquals(3, len(devs))
+ resp = self.request('/plugins/kimchi/storagepools/tmp/deactivate',
+ {}, 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/tmp', {},
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_vm_iface(self):
+
+ with RollbackContext() as rollback:
+ # Create a template as a base for our VMs
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ # Delete the template
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/templates/test', '{}',
+ 'DELETE')
+
+ # Create a VM with default args
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Delete the VM
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/vms/test-vm', '{}',
+ 'DELETE')
+
+ # Create a network
+ req = json.dumps({'name': 'test-network',
+ 'connection': 'nat',
+ 'net': '127.0.1.0/24'})
+ resp = self.request('/plugins/kimchi/networks', req, 'POST')
+ self.assertEquals(201, resp.status)
+ # Delete the network
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/networks/test-network',
+ '{}', 'DELETE')
+
+ ifaces = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/ifaces').read()
+ )
+ self.assertEquals(1, len(ifaces))
+
+ for iface in ifaces:
+ res = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ iface['mac']).read()
+ )
+ self.assertEquals('default', res['network'])
+ self.assertEquals(17, len(res['mac']))
+ self.assertEquals(get_template_default('old', 'nic_model'),
+ res['model'])
+
+ # try to attach an interface without specifying 'model'
+ req = json.dumps({'type': 'network'})
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
+
+ # attach network interface to vm
+ req = json.dumps({"type": "network",
+ "network": "test-network",
+ "model": "virtio"})
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
+ 'POST')
+ self.assertEquals(201, resp.status)
+ iface = json.loads(resp.read())
+
+ self.assertEquals('test-network', iface['network'])
+ self.assertEquals(17, len(iface['mac']))
+ self.assertEquals('virtio', iface['model'])
+ self.assertEquals('network', iface['type'])
+
+ # update vm interface
+ newMacAddr = '54:50:e3:44:8a:af'
+ req = json.dumps({"network": "default", "model": "virtio",
+ "type": "network", "mac": newMacAddr})
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ iface['mac'], req, 'PUT')
+ self.assertEquals(303, resp.status)
+ iface = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ newMacAddr).read()
+ )
+ self.assertEquals(newMacAddr, iface['mac'])
+
+ # detach network interface from vm
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ iface['mac'], '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_vm_customise_storage(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso,
+ 'disks': [{'size': 1}]})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create alternate storage
+ req = json.dumps({'name': 'alt',
+ 'capacity': 1024,
+ 'allocated': 512,
+ 'path': '/tmp',
+ 'type': 'dir'})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/alt/activate', req,
+ 'POST')
+ self.assertEquals(200, resp.status)
+
+ # Create a VM
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'storagepool': '/plugins/kimchi/storagepools/alt'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ resp = self.request('/plugins/kimchi/vms/test-vm', {}, 'GET')
+ vm_info = json.loads(resp.read())
+
+ # Test template not changed after vm customise its pool
+ t = json.loads(self.request('/plugins/kimchi/templates/test').read())
+ self.assertEquals(t['storagepool'],
+ '/plugins/kimchi/storagepools/default-pool')
+
+ # Verify the volume was created
+ vol_uri = '/plugins/kimchi/storagepools/alt/storagevolumes/%s-0.img' \
+ % vm_info['uuid']
+ resp = self.request(vol_uri)
+ vol = json.loads(resp.read())
+ self.assertEquals(1 << 30, vol['capacity'])
+
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Verify the volume was deleted
+ self.assertHTTPStatus(404, vol_uri)
+
+ def test_scsi_fc_storage(self):
+ # Create scsi fc pool
+ req = json.dumps({'name': 'scsi_fc_pool',
+ 'type': 'scsi',
+ 'source': {'adapter_name': 'scsi_host2'}})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Test create vms using lun of this pool
+ # activate the storage pool
+ resp = self.request(
+ '/plugins/kimchi/storagepools/scsi_fc_pool/activate', '{}', 'POST'
+ )
+
+ # Create template fails because SCSI volume is missing
+ tmpl_params = {
+ 'name': 'test_fc_pool', 'cdrom': fake_iso,
+ 'storagepool': '/plugins/kimchi/storagepools/scsi_fc_pool'
+ }
+ req = json.dumps(tmpl_params)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Choose SCSI volume to create template
+ resp = self.request(
+ '/plugins/kimchi/storagepools/scsi_fc_pool/storagevolumes'
+ )
+ lun_name = json.loads(resp.read())[0]['name']
+
+ tmpl_params['disks'] = [{'index': 0, 'volume': lun_name}]
+ req = json.dumps(tmpl_params)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create vm in scsi pool
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test_fc_pool'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ # Start the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('running', vm['state'])
+
+ # Force poweroff the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}',
+ 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('shutoff', vm['state'])
+
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_unnamed_vms(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create 5 unnamed vms from this template
+ for i in xrange(1, 6):
+ req = json.dumps({'template': '/plugins/kimchi/templates/test'})
+ task = json.loads(self.request('/plugins/kimchi/vms',
+ req, 'POST').read())
+ wait_task(self._task_lookup, task['id'])
+ resp = self.request('/plugins/kimchi/vms/test-vm-%i' % i, {},
+ 'GET')
+ self.assertEquals(resp.status, 200)
+ count = len(json.loads(self.request('/plugins/kimchi/vms').read()))
+ self.assertEquals(6, count)
+
+ def test_create_vm_without_template(self):
+ req = json.dumps({'name': 'vm-without-template'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+ resp = json.loads(resp.read())
+ self.assertIn(u"KCHVM0016E:", resp['reason'])
+
+ def test_create_vm_with_bad_template_uri(self):
+ req = json.dumps({'name': 'vm-bad-template',
+ 'template': '/mytemplate'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+ resp = json.loads(resp.read())
+ self.assertIn(u"KCHVM0012E", resp['reason'])
+
+ def test_create_vm_with_img_based_template(self):
+ resp = json.loads(
+ self.request(
+ '/plugins/kimchi/storagepools/default-pool/storagevolumes'
+ ).read()
+ )
+ self.assertEquals(0, len(resp))
+
+ # Create a Template
+ mock_base = '/tmp/mock.img'
+ open(mock_base, 'w').close()
+ req = json.dumps({'name': 'test', 'disks': [{'base': mock_base}]})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ req = json.dumps({'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ # Test storage volume created with backing store of base file
+ resp = json.loads(
+ self.request(
+ '/plugins/kimchi/storagepools/default-pool/storagevolumes'
+ ).read()
+ )
+ self.assertEquals(1, len(resp))
+
+ def _create_pool(self, name):
+ req = json.dumps({'name': name,
+ 'capacity': 10240,
+ 'allocated': 5120,
+ 'path': '/var/lib/libvirt/images/',
+ 'type': 'dir'})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the storage pool
+ storagepool = json.loads(self.request('/plugins/kimchi/storagepools/%s'
+ % name).read())
+ self.assertEquals('inactive', storagepool['state'])
+ return name
+
+ def _delete_pool(self, name):
+ # Delete the storage pool
+ resp = self.request('/plugins/kimchi/storagepools/%s' % name, '{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_iso_scan_shallow(self):
+ # fake environment preparation
+ self._create_pool('pool-3')
+ self.request('/plugins/kimchi/storagepools/pool-3/activate', '{}',
+ 'POST')
+ params = {'name': 'fedora.iso',
+ 'capacity': 1073741824, # 1 GiB
+ 'type': 'file',
+ 'format': 'iso'}
+ task_info = model.storagevolumes_create('pool-3', params)
+ wait_task(self._task_lookup, task_info['id'])
+
+ storagevolume = json.loads(
+ self.request(
+ '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes/'
+ ).read()
+ )[0]
+ self.assertEquals('fedora.iso', storagevolume['name'])
+ self.assertEquals('iso', storagevolume['format'])
+ self.assertEquals('/var/lib/libvirt/images/fedora.iso',
+ storagevolume['path'])
+ self.assertEquals(1073741824, storagevolume['capacity']) # 1 GiB
+ self.assertEquals(0, storagevolume['allocation'])
+ self.assertEquals('17', storagevolume['os_version'])
+ self.assertEquals('fedora', storagevolume['os_distro'])
+ self.assertEquals(True, storagevolume['bootable'])
+
+ # Create a template
+ # In real model os distro/version can be omitted
+ # as we will scan the iso
+ req = json.dumps({'name': 'test',
+ 'cdrom': storagevolume['path'],
+ 'os_distro': storagevolume['os_distro'],
+ 'os_version': storagevolume['os_version']})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the template
+ t = json.loads(self.request('/plugins/kimchi/templates/test').read())
+ self.assertEquals('test', t['name'])
+ self.assertEquals('fedora', t['os_distro'])
+ self.assertEquals('17', t['os_version'])
+ self.assertEquals(get_template_default('old', 'memory'), t['memory'])
+
+ # Deactivate or destroy scan pool return 405
+ resp = self.request(
+ '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes'
+ '/deactivate', '{}', 'POST'
+ )
+ self.assertEquals(405, resp.status)
+
+ resp = self.request(
+ '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
+ '{}', 'DELETE'
+ )
+ self.assertEquals(405, resp.status)
+
+ # Delete the template
+ resp = self.request('/plugins/kimchi/templates/%s' % t['name'], '{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ resp = self.request('/plugins/kimchi/storagepools/pool-3/deactivate',
+ '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ self._delete_pool('pool-3')
+
+ def test_screenshot_refresh(self):
+ # Create a VM
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ # Test screenshot for shut-off state vm
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(404, resp.status)
+
+ # Test screenshot for running vm
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+
+ resp = self.request(vm['screenshot'], method='HEAD')
+ self.assertEquals(200, resp.status)
+ self.assertTrue(resp.getheader('Content-type').startswith('image'))
+
+ # Test screenshot sub-resource redirect
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(200, resp.status)
+ self.assertEquals('image/png', resp.getheader('content-type'))
+ lastMod1 = resp.getheader('last-modified')
+
+ # Take another screenshot instantly and compare the last Modified date
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ lastMod2 = resp.getheader('last-modified')
+ self.assertEquals(lastMod2, lastMod1)
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot', '{}',
+ 'DELETE')
+ self.assertEquals(405, resp.status)
+
+ # No screenshot after stopped the VM
+ self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}', 'POST')
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(404, resp.status)
+
+ # Picture link not available after VM deleted
+ self.request('/plugins/kimchi/vms/test-vm/start', '{}', 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ img_lnk = vm['screenshot']
+ self.request('/plugins/kimchi/vms/test-vm', '{}', 'DELETE')
+ resp = self.request(img_lnk)
+ self.assertEquals(404, resp.status)
+
+ def test_interfaces(self):
+ resp = self.request('/plugins/kimchi/interfaces').read()
+ self.assertIn('name', resp)
+ interfaces = json.loads(resp)
+ keys = ['name', 'type', 'ipaddr', 'netmask', 'status']
+ for interface in interfaces:
+ self.assertEquals(sorted(keys), sorted(interface.keys()))
+
+ def _task_lookup(self, taskid):
+ return json.loads(
+ self.request('/tasks/%s' % taskid).read()
+ )
+
+ def test_tasks(self):
+ id1 = add_task('/tasks/1', self._async_op,
+ model.objstore)
+ id2 = add_task('/tasks/2', self._except_op,
+ model.objstore)
+ id3 = add_task('/tasks/3', self._intermid_op,
+ model.objstore)
+
+ target_uri = urllib2.quote('^/tasks/*', safe="")
+ filter_data = 'status=running&target_uri=%s' % target_uri
+ tasks = json.loads(
+ self.request('/tasks?%s' % filter_data).read()
+ )
+ self.assertEquals(3, len(tasks))
+
+ tasks = json.loads(self.request('/tasks').read())
+ tasks_ids = [int(t['id']) for t in tasks]
+ self.assertEquals(set([id1, id2, id3]) - set(tasks_ids), set([]))
+ wait_task(self._task_lookup, id2)
+ foo2 = json.loads(
+ self.request('/tasks/%s' % id2).read()
+ )
+ keys = ['id', 'status', 'message', 'target_uri']
+ self.assertEquals(sorted(keys), sorted(foo2.keys()))
+ self.assertEquals('failed', foo2['status'])
+ wait_task(self._task_lookup, id3)
+ foo3 = json.loads(
+ self.request('/tasks/%s' % id3).read()
+ )
+ self.assertEquals('in progress', foo3['message'])
+ self.assertEquals('running', foo3['status'])
+
+ def test_config(self):
+ resp = self.request('/plugins/kimchi/config').read()
+ conf = json.loads(resp)
+ keys = ["display_proxy_port", "version"]
+ self.assertEquals(keys, sorted(conf.keys()))
+
+ def test_capabilities(self):
+ resp = self.request('/plugins/kimchi/config/capabilities').read()
+ conf = json.loads(resp)
+
+ keys = [u'libvirt_stream_protocols', u'qemu_stream', u'qemu_spice',
+ u'screenshot', u'system_report_tool', u'update_tool',
+ u'repo_mngt_tool', u'federation', u'kernel_vfio', u'auth',
+ u'nm_running', u'mem_hotplug_support']
+ self.assertEquals(sorted(keys), sorted(conf.keys()))
+
+ def test_peers(self):
+ resp = self.request('/plugins/kimchi/peers').read()
+ self.assertEquals([], json.loads(resp))
+
+ def test_distros(self):
+ resp = self.request('/plugins/kimchi/config/distros').read()
+ distros = json.loads(resp)
+ for distro in distros:
+ self.assertIn('name', distro)
+ self.assertIn('os_distro', distro)
+ self.assertIn('os_version', distro)
+ self.assertIn('path', distro)
+
+ # Test in X86
+ ident = "Fedora 20"
+ resp = self.request('/plugins/kimchi/config/distros/%s' %
+ urllib2.quote(ident)).read()
+ distro = json.loads(resp)
+ if os.uname()[4] in ['x86_64', 'amd64']:
+ self.assertEquals(distro['name'], ident)
+ self.assertEquals(distro['os_distro'], "fedora")
+ self.assertEquals(distro['os_version'], "20")
+ self.assertEquals(distro['os_arch'], "x86_64")
+ self.assertIn('path', distro)
+ else:
+ # Distro not found error
+ self.assertIn('KCHDISTRO0001E', distro.get('reason'))
+
+ # Test in PPC
+ ident = "Fedora 20 (PPC64)"
+ resp = self.request('/plugins/kimchi/config/distros/%s' %
+ urllib2.quote(ident)).read()
+ distro = json.loads(resp)
+ if os.uname()[4] == 'ppc64':
+ self.assertEquals(distro['name'], ident)
+ self.assertEquals(distro['os_distro'], "fedora")
+ self.assertEquals(distro['os_version'], "20")
+ self.assertEquals(distro['os_arch'], "ppc64")
+ self.assertIn('path', distro)
+ else:
+ # Distro not found error
+ self.assertIn('KCHDISTRO0001E', distro.get('reason'))
+
+ def test_debugreports(self):
+ resp = request(host, ssl_port, '/plugins/kimchi/debugreports')
+ self.assertEquals(200, resp.status)
+
+ def _report_delete(self, name):
+ request(host, ssl_port, '/plugins/kimchi/debugreports/%s' % name, '{}',
+ 'DELETE')
+
+ def test_create_debugreport(self):
+ req = json.dumps({'name': 'report1'})
+ with RollbackContext() as rollback:
+ resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ # make sure the debugreport doesn't exist until the
+ # the task is finished
+ wait_task(self._task_lookup, task['id'])
+ rollback.prependDefer(self._report_delete, 'report2')
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1')
+ debugreport = json.loads(resp.read())
+ self.assertEquals("report1", debugreport['name'])
+ self.assertEquals(200, resp.status)
+ req = json.dumps({'name': 'report2'})
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1', req, 'PUT')
+ self.assertEquals(303, resp.status)
+
+ def test_debugreport_download(self):
+ req = json.dumps({'name': 'report1'})
+ with RollbackContext() as rollback:
+ resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ # make sure the debugreport doesn't exist until the
+ # the task is finished
+ wait_task(self._task_lookup, task['id'], 20)
+ rollback.prependDefer(self._report_delete, 'report1')
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1')
+ debugreport = json.loads(resp.read())
+ self.assertEquals("report1", debugreport['name'])
+ self.assertEquals(200, resp.status)
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1/content')
+ self.assertEquals(200, resp.status)
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1')
+ debugre = json.loads(resp.read())
+ resp = request(host, ssl_port, debugre['uri'])
+ self.assertEquals(200, resp.status)
+
+ def test_repositories(self):
+ def verify_repo(t, res):
+ for field in ('repo_id', 'enabled', 'baseurl', 'config'):
+ if field in t.keys():
+ self.assertEquals(t[field], res[field])
+
+ base_uri = '/plugins/kimchi/host/repositories'
+ resp = self.request(base_uri)
+ self.assertEquals(200, resp.status)
+ # Already have one repo in Kimchi's system
+ self.assertEquals(1, len(json.loads(resp.read())))
+
+ # Create a repository
+ repo = {'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'}
+ req = json.dumps(repo)
+ resp = self.request(base_uri, req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the repository
+ res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
+ verify_repo(repo, res)
+
+ # Update the repository
+ params = {}
+ params['baseurl'] = repo['baseurl'] = 'http://www.fedoraproject.org'
+ resp = self.request('%s/fedora-fake' % base_uri, json.dumps(params),
+ 'PUT')
+
+ # Verify the repository
+ res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
+ verify_repo(repo, res)
+
+ # Delete the repository
+ resp = self.request('%s/fedora-fake' % base_uri, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+
+class HttpsRestTests(RestTests):
+ """
+ Run all of the same tests as above, but use https instead
+ """
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
diff --git a/src/wok/plugins/kimchi/tests/test_rollbackcontext.py b/src/wok/plugins/kimchi/tests/test_rollbackcontext.py
new file mode 100644
index 0000000..6eac6d0
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_rollbackcontext.py
@@ -0,0 +1,99 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+
+from wok.rollbackcontext import RollbackContext
+
+
+class FirstError(Exception):
+ '''A hypothetical exception to be raise in the test firstly.'''
+ pass
+
+
+class SecondError(Exception):
+ '''A hypothetical exception to be raise in the test secondly.'''
+ pass
+
+
+class RollbackContextTests(unittest.TestCase):
+
+ def setUp(self):
+ self._counter = 0
+
+ def _inc_counter(self):
+ self._counter += 1
+
+ def _raise(self, exception=FirstError):
+ raise exception()
+
+ def test_rollback(self):
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._inc_counter)
+ rollback.prependDefer(self._inc_counter)
+ self.assertEquals(self._counter, 2)
+
+ def test_raise(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._inc_counter)
+ rollback.prependDefer(self._inc_counter)
+ raise FirstError()
+ rollback.prependDefer(self._inc_counter)
+ except FirstError:
+ # All undo before the FirstError should be run
+ self.assertEquals(self._counter, 2)
+ else:
+ self.fail('Should have raised FirstError')
+
+ def test_raise_undo(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._inc_counter)
+ rollback.prependDefer(self._raise)
+ rollback.prependDefer(self._inc_counter)
+ except FirstError:
+ # All undo should be run
+ self.assertEquals(self._counter, 2)
+ else:
+ self.fail('Should have raised FirstError')
+
+ def test_raise_prefer_original(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._raise, SecondError)
+ raise FirstError()
+ except FirstError:
+ pass
+ except SecondError:
+ self.fail('Should have preferred FirstError to SecondError')
+ else:
+ self.fail('Should have raised FirstError')
+
+ def test_raise_prefer_first_undo(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._raise, SecondError)
+ rollback.prependDefer(self._raise, FirstError)
+ except FirstError:
+ pass
+ except SecondError:
+ self.fail('Should have preferred FirstError to SecondError')
+ else:
+ self.fail('Should have raised FirstError')
diff --git a/src/wok/plugins/kimchi/tests/test_server.py b/src/wok/plugins/kimchi/tests/test_server.py
new file mode 100644
index 0000000..d5ef565
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_server.py
@@ -0,0 +1,289 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import base64
+import cherrypy
+import json
+import os
+import tempfile
+import threading
+import unittest
+from functools import partial
+
+from wok.control.base import Collection, Resource
+
+from wok.plugins.kimchi import mockmodel
+
+import utils
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+tmpfile = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port, tmpfile
+
+ utils.patch_auth()
+ tmpfile = tempfile.mktemp()
+ model = mockmodel.MockModel(tmpfile)
+ host = '127.0.0.1'
+ port = utils.get_free_port('http')
+ ssl_port = utils.get_free_port('https')
+ cherrypy_port = utils.get_free_port('cherrypy_port')
+ test_server = utils.run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink(tmpfile)
+
+
+class ServerTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(utils.request, host, ssl_port)
+ model.reset()
+
+ def assertValidJSON(self, txt):
+ try:
+ json.loads(txt)
+ except ValueError:
+ self.fail("Invalid JSON: %s" % txt)
+
+ def test_server_start(self):
+ """
+ Test that we can start a server and receive HTTP:200.
+ """
+ resp = self.request('/')
+ self.assertEquals(200, resp.status)
+
+ def test_multithreaded_connection(self):
+ def worker():
+ for i in xrange(100):
+ ret = model.vms_get_list()
+ self.assertEquals('test', ret[0])
+
+ threads = []
+ for i in xrange(100):
+ t = threading.Thread(target=worker)
+ t.setDaemon(True)
+ t.start()
+ threads.append(t)
+ for t in threads:
+ t.join()
+
+ def test_collection(self):
+ c = Collection(model)
+
+ # The base Collection is always empty
+ cherrypy.request.method = 'GET'
+ cherrypy.request.headers['Accept'] = 'application/json'
+ self.assertEquals('[]', c.index())
+
+ # POST and DELETE raise HTTP:405 by default
+ for method in ('POST', 'DELETE'):
+ cherrypy.request.method = method
+ try:
+ c.index()
+ except cherrypy.HTTPError, e:
+ self.assertEquals(405, e.code)
+ else:
+ self.fail("Expected exception not raised")
+
+ def test_resource(self):
+ r = Resource(model)
+
+ # Test the base Resource representation
+ cherrypy.request.method = 'GET'
+ cherrypy.request.headers['Accept'] = 'application/json'
+ self.assertEquals('{}', r.index())
+
+ # POST and DELETE raise HTTP:405 by default
+ for method in ('POST', 'DELETE'):
+ cherrypy.request.method = method
+ try:
+ r.index()
+ except cherrypy.HTTPError, e:
+ self.assertEquals(405, e.code)
+ else:
+ self.fail("Expected exception not raised")
+
+ def test_404(self):
+ """
+ A non-existent path should return HTTP:404
+ """
+ url_list = ['/plugins/kimchi/doesnotexist', '/plugins/kimchi/vms/blah']
+ for url in url_list:
+ resp = self.request(url)
+ self.assertEquals(404, resp.status)
+
+ # Verify it works for DELETE too
+ resp = self.request('/plugins/kimchi/templates/blah', '', 'DELETE')
+ self.assertEquals(404, resp.status)
+
+ def test_accepts(self):
+ """
+ Verify the following expectations regarding the client Accept header:
+ If omitted, default to html
+ If 'application/json', serve the rest api
+ If 'text/html', serve the UI
+ If both of the above (in any order), serve the rest api
+ If neither of the above, HTTP:406
+ """
+ resp = self.request("/", headers={})
+ location = resp.getheader('location')
+ self.assertTrue(location.endswith("login.html"))
+ resp = self.request("/login.html", headers={})
+ self.assertTrue('<!doctype html>' in resp.read().lower())
+
+ resp = self.request("/", headers={'Accept': 'application/json'})
+ self.assertValidJSON(resp.read())
+
+ resp = self.request("/", headers={'Accept': 'text/html'})
+ location = resp.getheader('location')
+ self.assertTrue(location.endswith("login.html"))
+
+ resp = self.request("/", headers={'Accept':
+ 'application/json, text/html'})
+ self.assertValidJSON(resp.read())
+
+ resp = self.request("/", headers={'Accept':
+ 'text/html, application/json'})
+ self.assertValidJSON(resp.read())
+
+ h = {'Accept': 'text/plain'}
+ resp = self.request('/', None, 'GET', h)
+ self.assertEquals(406, resp.status)
+
+ def test_auth_unprotected(self):
+ hdrs = {'AUTHORIZATION': ''}
+ uris = ['/plugins/kimchi/js/kimchi.min.js',
+ '/plugins/kimchi/css/theme-default.min.css',
+ '/plugins/kimchi/images/icon-vm.png',
+ '/libs/jquery-1.10.0.min.js',
+ '/login.html',
+ '/logout']
+
+ for uri in uris:
+ resp = self.request(uri, None, 'HEAD', hdrs)
+ self.assertEquals(200, resp.status)
+
+ def test_auth_protected(self):
+ hdrs = {'AUTHORIZATION': ''}
+ uris = ['/plugins/kimchi/vms',
+ '/plugins/kimchi/vms/doesnotexist',
+ '/tasks']
+
+ for uri in uris:
+ resp = self.request(uri, None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ def test_auth_bad_creds(self):
+ # Test HTTPBA
+ hdrs = {'AUTHORIZATION': "Basic " + base64.b64encode("nouser:badpass")}
+ resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ # Test REST API
+ hdrs = {'AUTHORIZATION': ''}
+ req = json.dumps({'username': 'nouser', 'password': 'badpass'})
+ resp = self.request('/login', req, 'POST', hdrs)
+ self.assertEquals(401, resp.status)
+
+ def test_auth_browser_no_httpba(self):
+ # Kimchi detects REST requests from the browser by looking for a
+ # specific header
+ hdrs = {"X-Requested-With": "XMLHttpRequest"}
+
+ # Try our request (Note that request() will add a valid HTTPBA header)
+ resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+ self.assertEquals(None, resp.getheader('WWW-Authenticate'))
+
+ def test_auth_session(self):
+ hdrs = {'AUTHORIZATION': '',
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json'}
+
+ # Test we are logged out
+ resp = self.request('/tasks', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ # Execute a login call
+ user, pw = mockmodel.fake_user.items()[0]
+ req = json.dumps({'username': user, 'password': pw})
+ resp = self.request('/login', req, 'POST', hdrs)
+ self.assertEquals(200, resp.status)
+
+ user_info = json.loads(resp.read())
+ self.assertEquals(sorted(user_info.keys()),
+ ['groups', 'roles', 'username'])
+ roles = user_info['roles']
+ for tab, role in roles.iteritems():
+ self.assertEquals(role, u'admin')
+
+ cookie = resp.getheader('set-cookie')
+ hdrs['Cookie'] = cookie
+
+ # Test we are logged in with the cookie
+ resp = self.request('/tasks', None, 'GET', hdrs)
+ self.assertEquals(200, resp.status)
+
+ # Execute a logout call
+ resp = self.request('/logout', '{}', 'POST', hdrs)
+ self.assertEquals(200, resp.status)
+ del hdrs['Cookie']
+
+ # Test we are logged out
+ resp = self.request('/tasks', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ def test_get_param(self):
+ # Create a mock ISO file
+ mockiso = '/tmp/mock.iso'
+ open('/tmp/mock.iso', 'w').close()
+
+ # Create 2 different templates
+ req = json.dumps({'name': 'test-tmpl1', 'cdrom': mockiso})
+ self.request('/plugins/kimchi/templates', req, 'POST')
+
+ req = json.dumps({'name': 'test-tmpl2', 'cdrom': mockiso})
+ self.request('/plugins/kimchi/templates', req, 'POST')
+
+ # Remove mock iso
+ os.unlink(mockiso)
+
+ # Get the templates
+ resp = self.request('/plugins/kimchi/templates')
+ self.assertEquals(200, resp.status)
+ res = json.loads(resp.read())
+ self.assertEquals(2, len(res))
+
+ # Get a specific template
+ resp = self.request('/plugins/kimchi/templates?name=test-tmpl1')
+ self.assertEquals(200, resp.status)
+ res = json.loads(resp.read())
+ self.assertEquals(1, len(res))
+ self.assertEquals('test-tmpl1', res[0]['name'])
diff --git a/src/wok/plugins/kimchi/tests/test_storagepoolxml.py b/src/wok/plugins/kimchi/tests/test_storagepoolxml.py
new file mode 100644
index 0000000..7e45cca
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_storagepoolxml.py
@@ -0,0 +1,171 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+import unittest
+
+from wok.plugins.kimchi.model.libvirtstoragepool import StoragePoolDef
+
+
+class StoragepoolXMLTests(unittest.TestCase):
+ def test_get_storagepool_xml(self):
+ poolDefs = [
+ {'def':
+ {'type': 'dir',
+ 'name': 'unitTestDirPool',
+ 'path': '/var/temp/images'},
+ 'xml':
+ """
+ <pool type='dir'>
+ <name>unitTestDirPool</name>
+ <target>
+ <path>/var/temp/images</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'netfs',
+ 'name': 'unitTestNFSPool',
+ 'source': {'host': '127.0.0.1',
+ 'path': '/var/export'}},
+ 'xml':
+ """
+ <pool type='netfs'>
+ <name>unitTestNFSPool</name>
+ <source>
+ <host name='127.0.0.1'/>
+ <dir path='/var/export'/>
+ </source>
+ <target>
+ <path>/var/lib/kimchi/nfs_mount/unitTestNFSPool</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'logical',
+ 'name': 'unitTestLogicalPool',
+ 'source': {'devices': ['/dev/hda', '/dev/hdb']}},
+ 'xml':
+ """
+ <pool type='logical'>
+ <name>unitTestLogicalPool</name>
+ <source>
+ <device path="/dev/hda" />
+ <device path="/dev/hdb" />
+ </source>
+ <target>
+ <path>/dev/unitTestLogicalPool</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'iscsi',
+ 'name': 'unitTestISCSIPool',
+ 'source': {
+ 'host': '127.0.0.1',
+ 'target': 'iqn.2003-01.org.linux-iscsi.localhost'}},
+ 'xml':
+ """
+ <pool type='iscsi'>
+ <name>unitTestISCSIPool</name>
+ <source>
+ <host name='127.0.0.1' />
+ <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
+ </source>
+ <target>
+ <path>/dev/disk/by-id</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'iscsi',
+ 'name': 'unitTestISCSIPoolPort',
+ 'source': {
+ 'host': '127.0.0.1',
+ 'port': 3266,
+ 'target': 'iqn.2003-01.org.linux-iscsi.localhost'}},
+ 'xml':
+ """
+ <pool type='iscsi'>
+ <name>unitTestISCSIPoolPort</name>
+ <source>
+ <host name='127.0.0.1' port='3266' />
+ <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
+ </source>
+ <target>
+ <path>/dev/disk/by-id</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'iscsi',
+ 'name': 'unitTestISCSIPoolAuth',
+ 'source': {
+ 'host': '127.0.0.1',
+ 'target': 'iqn.2003-01.org.linux-iscsi.localhost',
+ 'auth': {'username': 'testUser',
+ 'password': 'ActuallyNotUsedInPoolXML'}}},
+ 'xml':
+ """
+ <pool type='iscsi'>
+ <name>unitTestISCSIPoolAuth</name>
+ <source>
+ <host name='127.0.0.1' />
+ <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
+ <auth type='chap' username='testUser'>
+ <secret type='iscsi' usage='unitTestISCSIPoolAuth'/>
+ </auth>
+ </source>
+ <target>
+ <path>/dev/disk/by-id</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'scsi',
+ 'name': 'unitTestSCSIFCPool',
+ 'path': '/dev/disk/by-path',
+ 'source': {
+ 'name': 'scsi_host3',
+ 'adapter': {
+ 'type': 'fc_host',
+ 'wwpn': '0123456789abcdef',
+ 'wwnn': 'abcdef0123456789'}}},
+ 'xml':
+ """
+ <pool type='scsi'>
+ <name>unitTestSCSIFCPool</name>
+ <source>
+ <adapter type='fc_host' name='scsi_host3'
+ wwnn='abcdef0123456789' wwpn='0123456789abcdef'></adapter>
+ </source>
+ <target>
+ <path>/dev/disk/by-path</path>
+ </target>
+ </pool>
+ """}]
+
+ for poolDef in poolDefs:
+ defObj = StoragePoolDef.create(poolDef['def'])
+ xmlStr = defObj.xml
+
+ parser = ET.XMLParser(remove_blank_text=True)
+ t1 = ET.fromstring(xmlStr, parser)
+ t2 = ET.fromstring(poolDef['xml'], parser)
+ self.assertEquals(ET.tostring(t1), ET.tostring(t2))
diff --git a/src/wok/plugins/kimchi/tests/test_template.py b/src/wok/plugins/kimchi/tests/test_template.py
new file mode 100644
index 0000000..c7de182
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_template.py
@@ -0,0 +1,387 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.config import READONLY_POOL_TYPE
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class TemplateTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def test_tmpl_lifecycle(self):
+ resp = self.request('/plugins/kimchi/templates')
+ self.assertEquals(200, resp.status)
+ self.assertEquals(0, len(json.loads(resp.read())))
+
+ # Create a template without cdrom and disk specified fails with 400
+ t = {'name': 'test', 'os_distro': 'ImagineOS',
+ 'os_version': '1.0', 'memory': 1024, 'cpus': 1,
+ 'storagepool': '/plugins/kimchi/storagepools/alt'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the template
+ keys = ['name', 'icon', 'invalid', 'os_distro', 'os_version', 'cpus',
+ 'memory', 'cdrom', 'disks', 'storagepool', 'networks',
+ 'folder', 'graphics', 'cpu_info']
+ tmpl = json.loads(
+ self.request('/plugins/kimchi/templates/test').read()
+ )
+ self.assertEquals(sorted(tmpl.keys()), sorted(keys))
+
+ # Verify if default disk format was configured
+ self.assertEquals(tmpl['disks'][0]['format'], 'qcow2')
+
+ # Clone a template
+ resp = self.request('/plugins/kimchi/templates/test/clone', '{}',
+ 'POST')
+ self.assertEquals(303, resp.status)
+
+ # Verify the cloned template
+ tmpl_cloned = json.loads(
+ self.request('/plugins/kimchi/templates/test-clone1').read()
+ )
+ del tmpl['name']
+ del tmpl_cloned['name']
+ self.assertEquals(tmpl, tmpl_cloned)
+
+ # Delete the cloned template
+ resp = self.request('/plugins/kimchi/templates/test-clone1', '{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a template with same name fails with 400
+ req = json.dumps({'name': 'test', 'cdrom': '/tmp/mock.iso'})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Create an image based template
+ open('/tmp/mock.img', 'w').close()
+ t = {'name': 'test_img_template',
+ 'disks': [{'base': '/tmp/mock.img'}]}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ os.remove('/tmp/mock.img')
+
+ # Test disk format
+ t = {'name': 'test-format', 'cdrom': '/tmp/mock.iso',
+ 'disks': [{'index': 0, 'size': 10, 'format': 'vmdk'}]}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ tmpl = json.loads(
+ self.request('/plugins/kimchi/templates/test-format').read()
+ )
+ self.assertEquals(tmpl['disks'][0]['format'], 'vmdk')
+
+ def test_customized_tmpl(self):
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ tmpl = json.loads(
+ self.request('/plugins/kimchi/templates/test').read()
+ )
+
+ # Update name
+ new_name = u'kīмÑhÄ«Tmpl'
+ new_tmpl_uri = '/plugins/kimchi/templates/%s' \
+ % new_name.encode('utf-8')
+ req = json.dumps({'name': new_name})
+ resp = self.request('/plugins/kimchi/templates/test', req, 'PUT')
+ self.assertEquals(303, resp.status)
+ resp = self.request(new_tmpl_uri)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(new_name, update_tmpl['name'])
+ del tmpl['name']
+ del update_tmpl['name']
+ self.assertEquals(tmpl, update_tmpl)
+
+ # Update icon
+ req = json.dumps({'icon': 'kimchi/images/icon-fedora.png'})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('kimchi/images/icon-fedora.png', update_tmpl['icon'])
+
+ # Update os_distro and os_version
+ req = json.dumps({'os_distro': 'fedora', 'os_version': '21'})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('fedora', update_tmpl['os_distro'])
+ self.assertEquals('21', update_tmpl['os_version'])
+
+ # Update cpus
+ req = json.dumps({'cpus': 2})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(2, update_tmpl['cpus'])
+
+ # Update memory
+ req = json.dumps({'memory': 2048})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(2048, update_tmpl['memory'])
+
+ # Update cpu_info
+ resp = self.request(new_tmpl_uri)
+ cpu_info = json.loads(resp.read())['cpu_info']
+ self.assertEquals(cpu_info, {})
+ self.assertEquals(cpu_info.get('topology'), None)
+
+ cpu_info_data = {'cpu_info': {'topology': {'sockets': 1,
+ 'cores': 2,
+ 'threads': 1}}}
+ resp = self.request(new_tmpl_uri, json.dumps(cpu_info_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(update_tmpl['cpu_info'], cpu_info_data['cpu_info'])
+
+ # Update cdrom
+ cdrom_data = {'cdrom': '/tmp/mock2.iso'}
+ resp = self.request(new_tmpl_uri, json.dumps(cdrom_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(update_tmpl['cdrom'], cdrom_data['cdrom'])
+
+ # Update disks
+ disk_data = {'disks': [{'index': 0, 'size': 10},
+ {'index': 1, 'size': 20}]}
+ resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request(new_tmpl_uri)
+ self.assertEquals(200, resp.status)
+ updated_tmpl = json.loads(resp.read())
+ self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
+
+ # For all supported types, edit the template and check if
+ # the change was made.
+ disk_types = ['bochs', 'cloop', 'cow', 'dmg', 'qcow', 'qcow2',
+ 'qed', 'raw', 'vmdk', 'vpc']
+ for disk_type in disk_types:
+ disk_data = {'disks': [{'index': 0, 'format': disk_type,
+ 'size': 10}]}
+ resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
+ self.assertEquals(200, resp.status)
+
+ resp = self.request(new_tmpl_uri)
+ self.assertEquals(200, resp.status)
+ updated_tmpl = json.loads(resp.read())
+ self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
+
+ # Update folder
+ folder_data = {'folder': ['mock', 'isos']}
+ resp = self.request(new_tmpl_uri, json.dumps(folder_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(update_tmpl['folder'], folder_data['folder'])
+
+ # Update graphics
+ req = json.dumps({'graphics': {'type': 'spice'}})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('spice', update_tmpl['graphics']['type'])
+
+ req = json.dumps({'graphics': {'type': 'vnc', 'listen': 'fe00::0'}})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('vnc', update_tmpl['graphics']['type'])
+ self.assertEquals('fe00::0', update_tmpl['graphics']['listen'])
+
+ def test_customized_network(self):
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create networks to be used for testing
+ networks = [{'name': u'kīмÑhÄ«-пet', 'connection': 'isolated'},
+ {'name': u'nat-network', 'connection': 'nat'},
+ {'name': u'subnet-network', 'connection': 'nat',
+ 'subnet': '127.0.100.0/24'}]
+
+ # Verify the current system has at least one interface to create a
+ # bridged network
+ interfaces = json.loads(
+ self.request('/plugins/kimchi/interfaces?type=nic').read()
+ )
+ if len(interfaces) > 0:
+ iface = interfaces[0]['name']
+ networks.append({'name': u'bridge-network', 'connection': 'bridge',
+ 'interface': iface})
+ networks.append({'name': u'bridge-network', 'connection': 'bridge',
+ 'interface': iface, 'vlan_id': 987})
+
+ tmpl_nets = []
+ for net in networks:
+ self.request('/plugins/kimchi/networks', json.dumps(net), 'POST')
+ tmpl_nets.append(net['name'])
+ req = json.dumps({'networks': tmpl_nets})
+ resp = self.request('/plugins/kimchi/templates/test', req, 'PUT')
+ self.assertEquals(200, resp.status)
+
+ def test_customized_storagepool(self):
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # MockModel always returns 2 partitions (vdx, vdz)
+ partitions = json.loads(
+ self.request('/plugins/kimchi/host/partitions').read()
+ )
+ devs = [dev['path'] for dev in partitions]
+
+ # MockModel always returns 3 FC devices
+ fc_devs = json.loads(
+ self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
+ )
+ fc_devs = [dev['name'] for dev in fc_devs]
+
+ poolDefs = [
+ {'type': 'dir', 'name': u'kīмÑhÄ«UnitTestDirPool',
+ 'path': '/tmp/kimchi-images'},
+ {'type': 'netfs', 'name': u'kīмÑhÄ«UnitTestNSFPool',
+ 'source': {'host': 'localhost',
+ 'path': '/var/lib/kimchi/nfs-pool'}},
+ {'type': 'scsi', 'name': u'kīмÑhÄ«UnitTestSCSIFCPool',
+ 'source': {'adapter_name': fc_devs[0]}},
+ {'type': 'iscsi', 'name': u'kīмÑhÄ«UnitTestISCSIPool',
+ 'source': {'host': '127.0.0.1',
+ 'target': 'iqn.2015-01.localhost.kimchiUnitTest'}},
+ {'type': 'logical', 'name': u'kīмÑhÄ«UnitTestLogicalPool',
+ 'source': {'devices': [devs[0]]}}]
+
+ for pool in poolDefs:
+ self.request('/plugins/kimchi/storagepools', json.dumps(pool),
+ 'POST')
+ pool_uri = '/plugins/kimchi/storagepools/%s' \
+ % pool['name'].encode('utf-8')
+ self.request(pool_uri + '/activate', '{}', 'POST')
+
+ req = None
+ if pool['type'] in READONLY_POOL_TYPE:
+ resp = self.request(pool_uri + '/storagevolumes')
+ vols = json.loads(resp.read())
+ if len(vols) > 0:
+ vol = vols[0]['name']
+ req = json.dumps({'storagepool': pool_uri,
+ 'disks': [{'volume': vol}]})
+ else:
+ req = json.dumps({'storagepool': pool_uri})
+
+ if req is not None:
+ resp = self.request('/plugins/kimchi/templates/test', req,
+ 'PUT')
+ self.assertEquals(200, resp.status)
+
+ def test_tmpl_integrity(self):
+ # Create a network and a pool for testing template integrity
+ net = {'name': u'nat-network', 'connection': 'nat'}
+ self.request('/plugins/kimchi/networks', json.dumps(net), 'POST')
+
+ pool = {'type': 'dir', 'name': 'dir-pool', 'path': '/tmp/dir-pool'}
+ self.request('/plugins/kimchi/storagepools', json.dumps(pool), 'POST')
+ pool_uri = '/plugins/kimchi/storagepools/%s' \
+ % pool['name'].encode('utf-8')
+ self.request(pool_uri + '/activate', '{}', 'POST')
+
+ # Create a template using the custom network and pool
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso',
+ 'networks': ['nat-network'],
+ 'storagepool': '/plugins/kimchi/storagepools/dir-pool'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Try to delete network
+ # It should fail as it is associated to a template
+ resp = self.request('/plugins/kimchi/networks/nat-network', '{}',
+ 'DELETE')
+ self.assertIn("KCHNET0017E", json.loads(resp.read())["reason"])
+
+ # Update template to release network and then delete it
+ params = {'networks': []}
+ req = json.dumps(params)
+ self.request('/plugins/kimchi/templates/test', req, 'PUT')
+ resp = self.request('/plugins/kimchi/networks/nat-network', '{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Try to delete the storagepool
+ # It should fail as it is associated to a template
+ resp = self.request('/plugins/kimchi/storagepools/dir-pool', '{}',
+ 'DELETE')
+ self.assertEquals(400, resp.status)
+
+ # Verify the template
+ res = json.loads(self.request('/plugins/kimchi/templates/test').read())
+ self.assertEquals(res['invalid']['cdrom'], ['/tmp/mock.iso'])
diff --git a/src/wok/plugins/kimchi/tests/test_utils.py b/src/wok/plugins/kimchi/tests/test_utils.py
new file mode 100644
index 0000000..bcb14e2
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_utils.py
@@ -0,0 +1,69 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+
+from wok.exception import InvalidParameter
+from wok.utils import convert_data_size
+
+
+class UtilsTests(unittest.TestCase):
+ def test_convert_data_size(self):
+ failure_data = [{'val': None, 'from': 'MiB'},
+ {'val': self, 'from': 'MiB'},
+ {'val': 1, 'from': None},
+ {'val': 1, 'from': ''},
+ {'val': 1, 'from': 'foo'},
+ {'val': 1, 'from': 'kib'},
+ {'val': 1, 'from': 'MiB', 'to': None},
+ {'val': 1, 'from': 'MiB', 'to': ''},
+ {'val': 1, 'from': 'MiB', 'to': 'foo'},
+ {'val': 1, 'from': 'MiB', 'to': 'kib'}]
+
+ for d in failure_data:
+ if 'to' in d:
+ self.assertRaises(InvalidParameter, convert_data_size,
+ d['val'], d['from'], d['to'])
+ else:
+ self.assertRaises(InvalidParameter, convert_data_size,
+ d['val'], d['from'])
+
+ success_data = [{'got': convert_data_size(5, 'MiB', 'MiB'),
+ 'want': 5},
+ {'got': convert_data_size(5, 'MiB', 'KiB'),
+ 'want': 5120},
+ {'got': convert_data_size(5, 'MiB', 'M'),
+ 'want': 5.24288},
+ {'got': convert_data_size(5, 'MiB', 'GiB'),
+ 'want': 0.0048828125},
+ {'got': convert_data_size(5, 'MiB', 'Tb'),
+ 'want': 4.194304e-05},
+ {'got': convert_data_size(5, 'KiB', 'MiB'),
+ 'want': 0.0048828125},
+ {'got': convert_data_size(5, 'M', 'MiB'),
+ 'want': 4.76837158203125},
+ {'got': convert_data_size(5, 'GiB', 'MiB'),
+ 'want': 5120},
+ {'got': convert_data_size(5, 'Tb', 'MiB'),
+ 'want': 596046.4477539062},
+ {'got': convert_data_size(5, 'MiB'),
+ 'want': convert_data_size(5, 'MiB', 'B')}]
+
+ for d in success_data:
+ self.assertEquals(d['got'], d['want'])
diff --git a/src/wok/plugins/kimchi/tests/test_vmtemplate.py b/src/wok/plugins/kimchi/tests/test_vmtemplate.py
new file mode 100644
index 0000000..0bca215
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_vmtemplate.py
@@ -0,0 +1,116 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import unittest
+import uuid
+
+from wok.xmlutils.utils import xpath_get_text
+
+from wok.plugins.kimchi.osinfo import get_template_default
+from wok.plugins.kimchi.vmtemplate import VMTemplate
+
+
+class VMTemplateTests(unittest.TestCase):
+ def setUp(self):
+ self.iso = '/tmp/mock.iso'
+ open(self.iso, 'w').close()
+
+ def tearDown(self):
+ os.unlink(self.iso)
+
+ def test_minimal_construct(self):
+ disk_bus = get_template_default('old', 'disk_bus')
+ memory = get_template_default('old', 'memory')
+ nic_model = get_template_default('old', 'nic_model')
+ fields = (('name', 'test'), ('os_distro', 'unknown'),
+ ('os_version', 'unknown'), ('cpus', 1),
+ ('memory', memory), ('networks', ['default']),
+ ('disk_bus', disk_bus), ('nic_model', nic_model),
+ ('graphics', {'type': 'vnc', 'listen': '127.0.0.1'}),
+ ('cdrom', self.iso))
+
+ args = {'name': 'test', 'cdrom': self.iso}
+ t = VMTemplate(args)
+ for name, val in fields:
+ self.assertEquals(val, t.info.get(name))
+
+ def test_construct_overrides(self):
+ graphics = {'type': 'spice', 'listen': '127.0.0.1'}
+ args = {'name': 'test', 'disks': [{'size': 10}, {'size': 20}],
+ 'graphics': graphics, "cdrom": self.iso}
+ t = VMTemplate(args)
+ self.assertEquals(2, len(t.info['disks']))
+ self.assertEquals(graphics, t.info['graphics'])
+
+ def test_specified_graphics(self):
+ # Test specified listen
+ graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
+ args = {'name': 'test', 'disks': [{'size': 10}, {'size': 20}],
+ 'graphics': graphics, 'cdrom': self.iso}
+ t = VMTemplate(args)
+ self.assertEquals(graphics, t.info['graphics'])
+
+ # Test specified type
+ graphics = {'type': 'spice', 'listen': '127.0.0.1'}
+ args['graphics'] = graphics
+ t = VMTemplate(args)
+ self.assertEquals(graphics, t.info['graphics'])
+
+ # If no listen specified, test the default listen
+ graphics = {'type': 'vnc'}
+ args['graphics'] = graphics
+ t = VMTemplate(args)
+ self.assertEquals(graphics['type'], t.info['graphics']['type'])
+ self.assertEquals('127.0.0.1', t.info['graphics']['listen'])
+
+ def test_to_xml(self):
+ graphics = {'type': 'spice', 'listen': '127.0.0.1'}
+ vm_uuid = str(uuid.uuid4()).replace('-', '')
+ if os.uname()[4] in ['ppc', 'ppc64', 'ppc64le']:
+ maxmem = 3328
+ else:
+ maxmem = 3072
+ t = VMTemplate({'name': 'test-template', 'cdrom': self.iso,
+ 'max_memory': maxmem << 10})
+ xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics)
+ self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0])
+ self.assertEquals('test-vm', xpath_get_text(xml, "/domain/name")[0])
+ expr = "/domain/devices/graphics/@type"
+ self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0])
+ expr = "/domain/devices/graphics/@listen"
+ self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0])
+ expr = "/domain/maxMemory/@slots"
+ self.assertEquals('2', xpath_get_text(xml, expr)[0])
+
+ def test_arg_merging(self):
+ """
+ Make sure that default parameters from osinfo do not override user-
+ provided parameters.
+ """
+ graphics = {'type': 'vnc', 'listen': '127.0.0.1'}
+ args = {'name': 'test', 'os_distro': 'opensuse', 'os_version': '12.3',
+ 'cpus': 2, 'memory': 2048, 'networks': ['foo'],
+ 'cdrom': self.iso, 'graphics': graphics}
+ t = VMTemplate(args)
+ self.assertEquals(2, t.info.get('cpus'))
+ self.assertEquals(2048, t.info.get('memory'))
+ self.assertEquals(['foo'], t.info.get('networks'))
+ self.assertEquals(self.iso, t.info.get('cdrom'))
+ self.assertEquals(graphics, t.info.get('graphics'))
diff --git a/src/wok/plugins/kimchi/tests/test_yumparser.py b/src/wok/plugins/kimchi/tests/test_yumparser.py
new file mode 100644
index 0000000..be5e95c
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_yumparser.py
@@ -0,0 +1,162 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import tempfile
+import unittest
+
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.model import model
+from wok.plugins.kimchi.yumparser import delete_repo_from_file, get_repo_files
+from wok.plugins.kimchi.yumparser import get_yum_packages_list_update
+from wok.plugins.kimchi.yumparser import get_yum_repositories
+from wok.plugins.kimchi.yumparser import write_repo_to_file, YumRepoObject
+
+
+TEMP_REPO_FILE = ''
+
+
+def _is_yum_distro():
+ inst = model.Model('test:///default')
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ return repo_type == 'yum'
+
+
+def _create_fake_repos(repo_file_name):
+ repo1 = YumRepoObject('fake-repo-1', repo_file_name)
+ repo2 = YumRepoObject('fake-repo-2', repo_file_name)
+ repo3 = YumRepoObject('fake-repo-3', repo_file_name)
+ repo4 = YumRepoObject('fake-repo-4', repo_file_name)
+ repos = [repo1, repo2, repo3, repo4]
+ return repos
+
+
+def _create_empty_repo_file():
+ data = """
+#
+# This is a repository file with no repositories at all
+# No repositories must be added after reading this file.
+#
+ """
+ _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
+ dir='/etc/yum.repos.d')
+ with open(tmp_file_name, 'w') as f:
+ f.writelines(data)
+
+ return tmp_file_name
+
+
+def _create_fake_repos_file():
+ _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
+ dir='/etc/yum.repos.d')
+
+ fake_repos = _create_fake_repos(tmp_file_name)
+ file_data = ''
+ for repo in fake_repos:
+ file_data += str(repo) + '\n'
+
+ with open(tmp_file_name, 'w') as f:
+ f.writelines(file_data)
+
+ return tmp_file_name
+
+
+def _generate_yumcheckupdate_output():
+ output = """
+Repository 'REPOSITORY1' is missing name in configuration, using id
+Repository 'REPOSITORY1-OPTIONAL' is missing name in configuration, using id
+
+PACKAGE1.noarch 20150611.-gg-FAKE1 REPOSITORY1
+PACKAGE2.x86_64 20150611.-no-FAKE2 REPOSITORY2
+PACKAGE3.dot.dot.i386 20150611.-re-FAKE3 REPOSITORY3
+
+Obsoleting Packages
+OBSOLETE4.dot.dot.i386 20150611.FAKE4 REPOSITORY4
+OBSOLETE5.dot.dot.fakearch 20150611.FAKE5 REPOSITORY5
+ """
+ return output
+
+
+ at unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
+def setUpModule():
+ global TEMP_REPO_FILE
+ TEMP_REPO_FILE = _create_fake_repos_file()
+
+
+ at unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
+def tearDownModule():
+ os.remove(TEMP_REPO_FILE)
+
+
+ at unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
+class YumParserTests(unittest.TestCase):
+
+ def test_get_yum_repositories(self):
+ repo_files = get_repo_files()
+ repo_objects = get_yum_repositories()
+ self.assertGreaterEqual(len(repo_objects), len(repo_files))
+
+ def test_empty_repo_file(self):
+ with RollbackContext() as rollback:
+ repos = get_yum_repositories()
+ tmp_file_name = _create_empty_repo_file()
+ rollback.prependDefer(os.remove, tmp_file_name)
+ repos_after = get_yum_repositories()
+ self.assertEqual(len(repos_after), len(repos))
+
+ def test_update_repo_attributes(self):
+ repos = get_yum_repositories()
+ fake_repo_2 = repos['fake-repo-2']
+ fake_repo_2.disable()
+ fake_repo_2.name = 'This is a fake repo'
+ fake_repo_2.baseurl = 'http://a.fake.repo.url'
+ fake_repo_2.gpgkey = 'file://a/fake/gpg/key.fake'
+ fake_repo_2.gpgcheck = False
+ fake_repo_2.metalink = 'this is not a true metalink'
+ fake_repo_2.mirrorlist = 'fake mirrorlist'
+ write_repo_to_file(fake_repo_2)
+
+ repos = get_yum_repositories()
+ fake_repo_2 = repos['fake-repo-2']
+ self.assertEqual(False, fake_repo_2.enabled)
+ self.assertEqual(False, fake_repo_2.gpgcheck)
+ self.assertEqual('This is a fake repo', fake_repo_2.name)
+ self.assertEqual('http://a.fake.repo.url', fake_repo_2.baseurl)
+ self.assertEqual('file://a/fake/gpg/key.fake', fake_repo_2.gpgkey)
+ self.assertEqual('this is not a true metalink', fake_repo_2.metalink)
+ self.assertEqual('fake mirrorlist', fake_repo_2.mirrorlist)
+
+ def test_delete_repo_from_file(self):
+ repos = get_yum_repositories()
+ fake_repo_3 = repos['fake-repo-3']
+ delete_repo_from_file(fake_repo_3)
+
+ repos = get_yum_repositories()
+ repos_id = repos.keys()
+ self.assertNotIn('fake-repo-3', repos_id)
+
+ def test_yum_checkupdate_parsing(self):
+ output = _generate_yumcheckupdate_output()
+ packages = get_yum_packages_list_update(output)
+ self.assertEqual(len(packages), 3)
+ self.assertEqual(packages[0].ui_from_repo, 'REPOSITORY1')
+ self.assertEqual(packages[1].version, '20150611.-no-FAKE2')
+ self.assertEqual(packages[2].name, 'PACKAGE3.dot.dot')
+ self.assertEqual(packages[2].arch, 'i386')
diff --git a/src/wok/plugins/kimchi/tests/utils.py b/src/wok/plugins/kimchi/tests/utils.py
new file mode 100644
index 0000000..ecaa87f
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/utils.py
@@ -0,0 +1,260 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import base64
+import cherrypy
+import grp
+import httplib
+import inspect
+import json
+import os
+import socket
+import ssl
+import sys
+import threading
+import time
+import unittest
+from contextlib import closing
+from lxml import etree
+
+import wok.server
+from wok.config import config, PluginPaths
+from wok.auth import User, USER_NAME, USER_GROUPS, USER_ROLES, tabs
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import wok_log
+
+from wok.plugins.kimchi import mockmodel
+
+
+_ports = {}
+
+# provide missing unittest decorators and API for python 2.6; these decorators
+# do not actually work, just avoid the syntax failure
+if sys.version_info[:2] == (2, 6):
+ def skipUnless(condition, reason):
+ if not condition:
+ sys.stderr.write('[expected failure] ')
+ raise Exception(reason)
+ return lambda obj: obj
+
+ unittest.skipUnless = skipUnless
+ unittest.expectedFailure = lambda obj: obj
+
+ def assertGreater(self, a, b, msg=None):
+ if not a > b:
+ self.fail('%s not greater than %s' % (repr(a), repr(b)))
+
+ def assertGreaterEqual(self, a, b, msg=None):
+ if not a >= b:
+ self.fail('%s not greater than or equal to %s'
+ % (repr(a), repr(b)))
+
+ def assertIsInstance(self, obj, cls, msg=None):
+ if not isinstance(obj, cls):
+ self.fail('%s is not an instance of %r' % (repr(obj), cls))
+
+ def assertIn(self, a, b, msg=None):
+ if a not in b:
+ self.fail("%s is not in %b" % (repr(a), repr(b)))
+
+ def assertNotIn(self, a, b, msg=None):
+ if a in b:
+ self.fail("%s is in %b" % (repr(a), repr(b)))
+
+ unittest.TestCase.assertGreaterEqual = assertGreaterEqual
+ unittest.TestCase.assertGreater = assertGreater
+ unittest.TestCase.assertIsInstance = assertIsInstance
+ unittest.TestCase.assertIn = assertIn
+ unittest.TestCase.assertNotIn = assertNotIn
+
+
+def get_free_port(name='http'):
+ global _ports
+ if _ports.get(name) is not None:
+ return _ports[name]
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ with closing(sock):
+ try:
+ sock.bind(("0.0.0.0", 0))
+ except:
+ raise Exception("Could not find a free port")
+ _ports[name] = sock.getsockname()[1]
+ return _ports[name]
+
+
+def run_server(host, port, ssl_port, test_mode, cherrypy_port=None,
+ model=None, environment='development'):
+
+ if cherrypy_port is None:
+ cherrypy_port = get_free_port('cherrypy_port')
+
+ if ssl_port is None:
+ ssl_port = get_free_port('https')
+
+ args = type('_', (object,),
+ {'host': host, 'port': port, 'ssl_port': ssl_port,
+ 'cherrypy_port': cherrypy_port, 'max_body_size': '4*1024',
+ 'ssl_cert': '', 'ssl_key': '',
+ 'test': test_mode, 'access_log': '/dev/null',
+ 'error_log': '/dev/null', 'environment': environment,
+ 'log_level': 'debug'})()
+ if model is not None:
+ setattr(args, 'model', model)
+
+ s = wok.server.Server(args)
+ t = threading.Thread(target=s.start)
+ t.setDaemon(True)
+ t.start()
+ cherrypy.engine.wait(cherrypy.engine.states.STARTED)
+ return s
+
+
+def silence_server():
+ """
+ Silence server status messages on stdout
+ """
+ cherrypy.config.update({"environment": "embedded"})
+
+
+def running_as_root():
+ return os.geteuid() == 0
+
+
+def _request(conn, path, data, method, headers):
+ if headers is None:
+ headers = {'Content-Type': 'application/json',
+ 'Accept': 'application/json'}
+ if 'AUTHORIZATION' not in headers.keys():
+ user, pw = mockmodel.fake_user.items()[0]
+ hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
+ headers['AUTHORIZATION'] = hdr
+ conn.request(method, path, data, headers)
+ return conn.getresponse()
+
+
+def request(host, port, path, data=None, method='GET', headers=None):
+ # verify if HTTPSConnection has context parameter
+ if "context" in inspect.getargspec(httplib.HTTPSConnection.__init__).args:
+ context = ssl._create_unverified_context()
+ conn = httplib.HTTPSConnection(host, port, context=context)
+ else:
+ conn = httplib.HTTPSConnection(host, port)
+
+ return _request(conn, path, data, method, headers)
+
+
+def get_remote_iso_path():
+ """
+ Get a remote iso with the right arch from the distro files shipped
+ with kimchi.
+ """
+ host_arch = os.uname()[4]
+ remote_path = ''
+ with open(os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d',
+ 'fedora.json')) as fedora_isos:
+ # Get a list of dicts
+ json_isos_list = json.load(fedora_isos)
+ for iso in json_isos_list:
+ if (iso.get('os_arch')) == host_arch:
+ remote_path = iso.get('path')
+ break
+
+ return remote_path
+
+
+class FakeUser(User):
+ auth_type = "fake"
+ sudo = True
+
+ def __init__(self, username):
+ self.user = {}
+ self.user[USER_NAME] = username
+ self.user[USER_GROUPS] = None
+ self.user[USER_ROLES] = dict.fromkeys(tabs, 'user')
+
+ def get_groups(self):
+ return sorted([group.gr_name for group in grp.getgrall()])[0:3]
+
+ def get_roles(self):
+ if self.sudo:
+ self.user[USER_ROLES] = dict.fromkeys(tabs, 'admin')
+ return self.user[USER_ROLES]
+
+ def get_user(self):
+ return self.user
+
+ @staticmethod
+ def authenticate(username, password, service="passwd"):
+ try:
+ return mockmodel.fake_user[username] == password
+ except KeyError, e:
+ raise OperationFailed("WOKAUTH0001E", {'username': 'username',
+ 'code': e.message})
+
+
+def patch_auth(sudo=True):
+ """
+ Override the authenticate function with a simple test against an
+ internal dict of users and passwords.
+ """
+ config.set("authentication", "method", "fake")
+ FakeUser.sudo = sudo
+
+
+def normalize_xml(xml_str):
+ return etree.tostring(etree.fromstring(xml_str,
+ etree.XMLParser(remove_blank_text=True)))
+
+
+def wait_task(task_lookup, taskid, timeout=10):
+ for i in range(0, timeout):
+ task_info = task_lookup(taskid)
+ if task_info['status'] == "running":
+ wok_log.info("Waiting task %s, message: %s",
+ taskid, task_info['message'])
+ time.sleep(1)
+ else:
+ return
+ wok_log.error("Timeout while process long-run task, "
+ "try to increase timeout value.")
+
+
+# The action functions in model backend raise NotFoundError exception if the
+# element is not found. But in some tests, these functions are called after
+# the element has been deleted if test finishes correctly, then NofFoundError
+# exception is raised and rollback breaks. To avoid it, this wrapper ignores
+# the NotFoundError.
+def rollback_wrapper(func, resource, *args):
+ try:
+ func(resource, *args)
+ except NotFoundError:
+ # VM has been deleted already
+ return
+
+
+# This function is used to test storage volume upload.
+# If we use self.request, we may encode multipart formdata by ourselves
+# requests lib take care of encode part, so use this lib instead
+def fake_auth_header():
+ headers = {'Accept': 'application/json'}
+ user, pw = mockmodel.fake_user.items()[0]
+ hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
+ headers['AUTHORIZATION'] = hdr
+ return headers
diff --git a/src/wok/plugins/kimchi/ui/Makefile.am b/src/wok/plugins/kimchi/ui/Makefile.am
new file mode 100644
index 0000000..21fe703
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+SUBDIRS = config css images js pages spice-html5
+
+uidir = $(datadir)/wok/plugins/kimchi/ui
diff --git a/src/wok/plugins/kimchi/ui/config/Makefile.am b/src/wok/plugins/kimchi/ui/config/Makefile.am
new file mode 100644
index 0000000..e3b3d19
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/config/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+xmldir = $(datadir)/wok/plugins/kimchi/ui/config
+
+dist_xml_DATA = \
+ tab-ext.xml \
+ $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/config/tab-ext.xml b/src/wok/plugins/kimchi/ui/config/tab-ext.xml
new file mode 100644
index 0000000..ee88c88
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/config/tab-ext.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<tabs-ext>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>Host</title>
+ <path>plugins/kimchi/host.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="byInstance"/>
+
+ <title>Guests</title>
+ <path>plugins/kimchi/guests.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>Templates</title>
+ <path>plugins/kimchi/templates.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="read-only"/>
+
+ <title>Storage</title>
+ <path>plugins/kimchi/storage.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="read-only"/>
+
+ <title>Network</title>
+ <path>plugins/kimchi/network.html</path>
+ </tab>
+</tabs-ext>
diff --git a/src/wok/plugins/kimchi/ui/css/Makefile.am b/src/wok/plugins/kimchi/ui/css/Makefile.am
new file mode 100644
index 0000000..5071d29
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+EXTRA_DIST = theme-default
+
+cssdir = $(datadir)/wok/plugins/kimchi/ui/css
+dist_css_DATA = theme-default.min.css
+
+theme-default.min.css: theme-default/*.css
+ cat $^ > $@
+
+CLEANFILES = theme-default.min.css
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css b/src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
new file mode 100644
index 0000000..b661159
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
@@ -0,0 +1,424 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+#guest-edit-window {
+ font-size: 13px;
+ height: 420px;
+ width: 820px;
+}
+
+#guest-edit-window #action-button-container {
+ padding-right: 0;
+}
+
+#guest-edit-window #guest-edit-button-cancel {
+ margin-left: 10px;
+}
+
+#guest-edit-tabs {
+ background: transparent;
+ border: none;
+ height: 100%;
+ padding: 0;
+}
+
+#form-guest-edit-general {
+ padding: 1em;
+}
+
+#form-guest-edit-general .edit-general-inline {
+ display: inline-block;
+}
+
+#form-guest-edit-storage input[readonly] {
+ background: none;
+ border-color: transparent;
+ text-overflow: ellipsis;
+}
+
+.guest-edit-fieldset {
+ padding-right: 0;
+}
+
+.guest-edit-wrapper-label {
+ height: 30px;
+ line-height: 30px;
+ margin-top: 10px;
+ vertical-align: top;
+ min-width: 100px;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
+
+#form-guest-edit-storage .guest-edit-wrapper-label {
+ width: 60px;
+}
+
+.guest-edit-wrapper-controls {
+ width: 470px;
+ margin-top: 5px;Ã
+}
+
+#form-guest-edit-storage .guest-edit-wrapper-controls {
+ width: 486px;
+}
+
+.guest-edit-wrapper-controls input[type="text"] {
+ font-size: 16px;
+ height: 30px;
+ width: 450px;
+ border: 1px solid #CCCCCC;
+}
+
+.guest-edit-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+ border: 1px solid #CCCCCC;
+}
+
+.guest-edit-cdrom-row-container {
+ max-height: 180px;
+ overflow: auto;
+}
+
+.guest-edit-cdrom-row-container input[type="text"] {
+ width: 400px;
+}
+
+#form-guest-edit-storage .header,
+.guest-edit-snapshot .header,
+.guest-edit-interface .header,
+#form-guest-edit-permission .ldap .header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ overflow: hidden;
+}
+
+#form-guest-edit-storage .body .item,
+.guest-edit-snapshot .body .item,
+.guest-edit-snapshot .task .item,
+.guest-edit-interface .body .item {
+ margin: 5px 0;
+}
+
+#form-guest-edit-storage .cell,
+.guest-edit-interface .cell {
+ display: inline-block;
+ width: 200px;
+}
+
+.guest-edit-snapshot .cell {
+ display: inline-block;
+}
+
+.guest-edit-snapshot .sel {
+ width: 25px;
+ vertical-align: top;
+}
+
+.guest-edit-snapshot .icon {
+ background: url('../images/theme-default/kimchi-loading15x15.gif') no-repeat;
+ display: block;
+ width: 16px;
+ height: 16px;
+ vertical-align: middle;
+ margin-left: 2px;
+}
+
+.guest-edit-snapshot .name {
+ width: 400px;
+}
+
+.guest-edit-snapshot .created {
+ width: 270px;
+}
+
+#form-guest-edit-storage .cell.dev {
+ width: 60px;
+}
+
+#form-guest-edit-storage .cell.path {
+ width: 440px;
+}
+
+#form-guest-edit-storage .cell.dev input,
+#form-guest-edit-storage .cell.path input {
+ box-sizing: border-box;
+ width: 100%;
+}
+
+.guest-edit-interface .body select {
+ width: 180px;
+ padding: 0px;
+}
+
+#form-guest-edit-storage .action-area,
+.guest-edit-snapshot .action-area,
+.guest-edit-interface .action-area {
+ float: right;
+}
+
+#form-guest-edit-storage .action-area {
+ line-height: 24px;
+}
+
+#form-guest-edit-storage button,
+.guest-edit-snapshot button,
+.guest-edit-interface button {
+ width: 20px;
+ height: 20px;
+}
+
+#form-guest-edit-storage .body button:not(:last-child),
+.guest-edit-interface .body button:not(:last-child) {
+ margin-right: 2px;
+}
+
+.guest-edit-snapshot .hide,
+.guest-edit-interface .hide {
+ display: none!important;
+}
+
+.guest-edit-permission .pam {
+ height: 220px;
+ padding: 5px 10px!important;
+}
+
+.guest-edit-permission .hide {
+ display: none;
+}
+
+.guest-edit-permission .pam .column {
+ display: inline-block;
+ vertical-align: top;
+}
+
+.guest-edit-permission .pam .title {
+ margin-bottom: 3px;
+}
+
+.guest-edit-permission .pam input[type="text"] {
+ margin-bottom: 3px;
+ font-size: 12px;
+ width: 97%;
+}
+
+.guest-edit-permission .pam .body {
+ border: 1px solid #999999;
+ font-size: 12px;
+ padding: 1px;
+ height: 192px;
+ overflow: auto;
+}
+
+.guest-edit-permission .pam .body .head {
+ margin-bottom: 3px;
+ font-weight: bold;
+ background: linear-gradient(to bottom, #E5E5E5 0%, #C4C4C4 100%) repeat scroll 0 0 transparent;
+}
+
+.guest-edit-permission .pam .body .item {
+ padding: 2px 3px;
+ margin-bottom: 1px;
+ cursor: pointer;
+}
+
+.guest-edit-permission .pam .body .item:hover {
+ background-color: #AAAAAA;
+}
+
+.guest-edit-permission .pam .body .item-picked {
+ background-color: #BBBBBB;
+}
+
+.guest-edit-permission .pam .body .item .icon {
+ display: inline-block;
+ height: 15px;
+ width: 15px;
+ vertical-align: bottom;
+}
+
+.guest-edit-permission .pam .body .item .user-icon {
+ background: url('../images/theme-default/user.png') no-repeat scroll;
+ background-size: 15px 15px;
+}
+
+.guest-edit-permission .pam .body .item .group-icon {
+ background: url('../images/theme-default/group.png') no-repeat scroll;
+ background-size: 15px 15px;
+}
+
+.guest-edit-permission .pam .body .column-user {
+ width: 48%;
+}
+.guest-edit-permission .pam .body .column-group {
+ width: 50%;
+}
+
+.guest-edit-permission .pam .control {
+ width: 5%;
+}
+
+.guest-edit-permission .pam .control button {
+ width: 26px;
+ margin-left: 7px;
+}
+
+.guest-edit-permission .pam .control button:first-child {
+ margin-top: 110px;
+ margin-bottom: 2px;
+}
+
+.guest-edit-permission .pam .control .ui-button-text-only .ui-button-text {
+ padding: 2px 8px;
+}
+
+.guest-edit-permission .pam .avail {
+ width: 46%;
+}
+
+.guest-edit-permission .pam .selected {
+ width: 46%;
+ float: right;
+}
+
+#form-guest-edit-permission .ldap .body .item {
+ margin: 8px 0;
+}
+
+#form-guest-edit-permission .ldap .cell {
+ width: 250px;
+}
+
+#form-guest-edit-permission .ldap .action-area {
+ float: right;
+ line-height: 24px;
+}
+
+#form-guest-edit-permission .ldap button {
+ width: 20px;
+ height: 20px;
+}
+
+#form-guest-edit-permission input[type="text"] {
+ width: 300px;
+}
+
+#form-guest-edit-permission .ldap .header button {
+ margin-bottom: 1px;
+}
+
+#form-guest-edit-permission .ldap .checked {
+ border-color: red;
+ border-style: solid;
+ border-width: 1px;
+}
+
+#form-guest-edit-permission .ldap .checked.hide {
+ display: none;
+}
+
+.guest-edit-pci {
+ height: 79%;
+ overflow: auto;
+ font-size: 12px;
+}
+
+.guest-edit-pci .guest-scroll-indent {
+ width: 783px;
+}
+
+.guest-edit-pci .filter {
+ height: 35px;
+ margin-right: 5px;
+ overflow: hidden;
+}
+
+.guest-edit-pci .group {
+ float: right;
+}
+
+.guest-edit-pci .filter .control {
+ border: 1px solid #AAAAAA;
+ font-size: 12px;
+ background-color: white;
+}
+
+.guest-edit-pci .filter select {
+ border-right: 0px!important;
+ border-radius: 7px 0px 0px 7px;
+ padding: 2px 2px 2px 7px;
+ width: 100px;
+ height: 24px;
+}
+
+.guest-edit-pci .filter select option {
+ padding-left: 7px;
+}
+
+.guest-edit-pci .filter input {
+ border-radius: 0px 7px 7px 0px;
+ padding: 3px 3px 3px 10px;
+ width: 200px;
+ height: 16px;
+ font-style: italic;
+}
+
+.guest-edit-pci .header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+
+.guest-edit-pci .item {
+ margin-bottom: 4px;
+ overflow: hidden;
+}
+
+.guest-edit-pci .cell {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 10px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.guest-edit-pci .item button {
+ width: 20px;
+ height: 20px;
+ float: right;
+}
+
+.guest-edit-pci .name {
+ width: 18%;
+ max-width: 18%;
+}
+
+.guest-edit-pci .product {
+ width: 45%;
+ max-width: 45%;
+}
+
+.guest-edit-pci .vendor {
+ width: 25%;
+ max-width: 25%;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css b/src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
new file mode 100644
index 0000000..9cc41e8
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
@@ -0,0 +1,81 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+#guest-storage-add-window {
+ font-size: 13px;
+ height: 600px;
+ width: 700px;
+}
+
+.guest-storage-add-fieldset {
+ padding: 1em;
+}
+
+#guest-storage-add-window .btn {
+ width: 587px;
+}
+
+#form-guest-storage-add .form-section .field {
+ overflow: visible;
+}
+
+#guest-storage-add-window input[type="text"] {
+ font-size: 16px;
+ height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding-left: 10px;
+ width: 600px;
+}
+
+#guest-storage-add-window input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+.guest-storage-add-wrapper-label, .guest-storage-add-wrapper-controls {
+ display: inline-block;
+}
+
+.guest-storage-add-wrapper-label {
+ height: 38px;
+ line-height: 38px;
+ margin-top: 5px;
+ vertical-align: top;
+ width: 80px;
+}
+
+.guest-storage-add-wrapper-controls {
+ width: 470px;
+}
+
+#vm-storage-button-add[disabled] {
+ background: #c0c0c0;
+ color: #ddd;
+ padding-left: 26px;
+}
+
+#vm-storage-button-add.loading[disabled] {
+ background: url("../../images/theme-default/loading.gif") 7px center no-repeat #c0c0c0;
+ color: #ddd;
+ padding-left: 26px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/host.css b/src/wok/plugins/kimchi/ui/css/theme-default/host.css
new file mode 100644
index 0000000..a0cccb1
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/host.css
@@ -0,0 +1,287 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+.host-panel {
+ font-size: 12px;
+ margin-bottom: 100px;
+}
+
+.host-panel .logo-container, .host-panel .info-container,
+.host-panel .section-label, .host-panel .section-value {
+ display: inline-block;
+ vertical-align: top;
+}
+
+.host-panel .section-label {
+ display: inline-block;
+ margin-right: 1em;
+ vertical-align: top;
+}
+
+.host-panel .logo {
+ background: url("plugins/kimchi/images/icon-vm.png") no-repeat left top;
+ height: 128px;
+ width: 128px;
+}
+
+.host-panel .hostname {
+ text-decoration: underline;
+}
+
+.host-panel .action-panel {
+ margin-top: 2em;
+ padding-left: 10px;
+}
+
+.host-panel .button-icon {
+ background: url("../images/theme-default/host-icon-sprite.png") no-repeat
+ left top;
+ display: inline-block;
+ height: 12px;
+ width: 12px;
+}
+
+.host-panel .action-icon-stop {
+ background-position: -14px 0;
+}
+
+.host-panel .action-icon-restart {
+ background-position: -28px 0;
+}
+
+.host-panel .action-icon-download {
+ background-position: -42px 0;
+}
+
+.host-panel .action-icon-connect {
+ background-position: -56px 0;
+}
+
+.host-panel .action-icon-add {
+ background-position: -70px 0;
+}
+
+.host-panel .action-icon-edit {
+ background-position: -84px 0;
+}
+
+.host-panel .action-icon-remove {
+ background-position: -98px 0;
+}
+
+.host-panel button:disabled .action-icon-start {
+ background-position: 0 -14px;
+}
+
+.host-panel button:disabled .action-icon-stop {
+ background-position: -14px -14px;
+}
+
+.host-panel button:disabled .action-icon-restart {
+ background-position: -28px -14px;
+}
+
+.host-panel button:disabled .action-icon-download {
+ background-position: -42px -14px;
+}
+
+.host-panel button:disabled .action-icon-connect {
+ background-position: -56px -14px;
+}
+
+.host-panel button:disabled .action-icon-add {
+ background-position: -70px -14px;
+}
+
+.host-panel button:disabled .action-icon-edit {
+ background-position: -84px -14px;
+}
+
+.host-panel button:disabled .action-icon-remove {
+ background-position: -98px -14px;
+}
+
+.host-panel .info-container {
+ padding-top: 16px;
+ width: 890px;
+}
+
+.host-panel .section-header {
+ background: #EEE;
+ border-radius: 5px;
+ cursor: pointer;
+ line-height: 2em;
+ margin: 1em 0 1em;
+ padding-left: 6px;
+}
+
+.host-panel .section-header:hover {
+ background: #06f;
+ color: white;
+}
+
+.host-panel .section-content {
+ padding-left: 1em;
+}
+
+.host-panel .section-header .arrow {
+ border-color: transparent;
+ border-style: solid;
+ display: inline-block;
+ margin-right: 6px;
+ width: 0;
+}
+
+.host-panel .section-header[aria-expanded="true"] .arrow {
+ border-top-color: black;
+ border-width: 8px 4px 0;
+ border-bottom: none;
+}
+
+.host-panel .section-header[aria-expanded="true"]:hover .arrow {
+ border-top-color: white;
+}
+
+.host-panel .section-header[aria-expanded="false"] .arrow {
+ border-left-color: black;
+ border-right: none;
+ border-width: 4px 0 4px 8px;
+}
+
+.host-panel .section-header[aria-expanded="false"]:hover .arrow {
+ border-left-color: white;
+}
+
+.host-panel .section-row {
+ line-height: 1.6em;
+ margin-bottom: 1em;
+}
+
+.host-panel .section-label {
+ width: 100px;
+}
+
+#frequency-textbox {
+ width: 20px;
+}
+
+#container-chart-cpu,
+#container-chart-memory,
+#container-chart-disk-io,
+#container-chart-network-io {
+ border: 1px solid white;
+ box-shadow: 2px 2px 2px gray, 2px -2px 2px gray, -2px -2px 2px gray, -2px
+ 2px 2px gray;
+ height: 100px;
+ width: 500px;
+}
+
+#container-chart-disk-io .disk-write,
+#container-chart-network-io .network-sent {
+ stroke: #f80;
+}
+
+/* Debug Report */
+.cell-text-wrapper {
+ margin-left: 10px;
+}
+
+.host-panel #available-reports-grid {
+ border-color: #ddd;
+ height: 400px;
+ width: 850px;
+}
+
+.host-panel select#available-reports-list {
+ width: 300px;
+}
+
+.host-panel select#available-reports-list option {
+ margin: .2em 1em;
+}
+
+.debug-report-name,
+.debug-report-time {
+ width: 424px;
+}
+
+#id-debug-img {
+ background: url(../images/theme-default/kimchi-loading15x15.gif) 12px
+ center no-repeat;
+ padding-left: 23px;
+}
+
+/* End of Debug Report */
+
+/* Software Updates */
+.host-panel #software-updates-grid {
+ border-color: #ddd;
+ height: 300px;
+ width: 850px;
+}
+
+.software-update-name,
+.software-update-repos {
+ width: 224px;
+}
+
+.software-update-version,
+.software-update-arch {
+ width: 200px;
+}
+
+.host-panel #software-updates-progress-textarea {
+ border: 1px solid #ddd;
+ box-sizing: border-box;
+ height: 100px;
+ padding: .2em .5em;
+ resize: vertical;
+ width: 852px;
+}
+/* End of Software Updates */
+
+/* Repository */
+.host-panel #repositories-grid {
+ border-color: #ddd;
+ height: 200px;
+ width: 850px;
+}
+
+.host-panel #repositories-grid .repository-id {
+ width: 120px;
+}
+
+.host-panel #repositories-grid .repository-name {
+ width: 640px;
+}
+
+.host-panel #repositories-grid .repository-enabled {
+ width: 88px;
+}
+
+.host-panel #repositories-grid .repository-baseurl.deb {
+ width: 400px;
+}
+
+.host-panel #repositories-grid .repository-enabled.deb {
+ width: 100px;
+}
+
+.host-panel #repositories-grid .repository-gpgcheck.deb {
+ width: 150px;
+}
+/* End of Repository */
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/icon.css b/src/wok/plugins/kimchi/ui/css/theme-default/icon.css
new file mode 100644
index 0000000..f82d45d
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/icon.css
@@ -0,0 +1,106 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+ /* Generated at http://colorzilla.com/gradient-editor/ */
+
+.btn.loading {
+ box-shadow: none;
+ cursor: default;
+}
+
+.btn.loading .icon {
+ background: url(../images/theme-default/icon-load.png) center
+ center no-repeat;
+}
+
+.btn.pause-gray .icon {
+ background: url(../images/theme-default/ac22_pause_grey.png) center
+ center no-repeat;
+}
+
+.btn.resume-gray .icon {
+ background: url(../images/theme-default/ac24_resume_grey.png) center
+ center no-repeat;
+}
+
+.icon.reset {
+ background: url(../images/theme-default/icon-reset.png) center
+ center no-repeat;
+}
+
+.icon.power-up {
+ background: url(../images/theme-default/icon-power-up.png) center
+ center no-repeat;
+}
+
+.icon.power-down {
+ background: url(../images/theme-default/icon-power-down.png) center
+ center no-repeat;
+}
+
+.icon.pause {
+ background: url(../images/theme-default/ac22_pause.png) center
+ center no-repeat;
+}
+
+.icon.resume {
+ background: url(../images/theme-default/ac24_resume.png) center
+ center no-repeat;
+}
+
+.icon.search {
+ background: url(../images/theme-default/icon-search.png) no-repeat
+ center center;
+}
+
+.icon.sort {
+ background: url(../images/theme-default/icon-sort.png) no-repeat
+ center center;
+}
+
+.icon.design {
+ background: url(../images/theme-default/icon-design.png) no-repeat
+ center center;
+}
+
+.icon.list {
+ background: url(../images/theme-default/icon-list.png) no-repeat
+ center center;
+}
+
+.icon.detail {
+ background: url(../images/theme-default/icon-detail.png) no-repeat
+ center center;
+}
+
+.icon.add {
+ line-height: 32px;
+ text-align: center;
+ text-shadow: -1px -1px 1px #aaa, 1px 1px 1px #eee;
+ font-size: 38px;
+ font-weight: bold;
+ color: #7cae0a;
+}
+
+.icon.tree {
+ width: 42px;
+ background: url(../images/theme-default/icon-tree.png) no-repeat
+ center center;
+}
+
+
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/list.css b/src/wok/plugins/kimchi/ui/css/theme-default/list.css
new file mode 100644
index 0000000..8c78623
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/list.css
@@ -0,0 +1,326 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+.list-vm {
+ margin: 10px;
+}
+
+/* Generated at http://colorzilla.com/gradient-editor/ */
+.list-vm>li {
+ margin-bottom: 10px;
+ background: #ffffff;
+ background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -webkit-gradient(linear, left top, left bottom,
+ color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
+ background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
+ endColorstr='#e5e5e5', GradientType=0);
+ border: 1px solid #ccc;
+ color: #333;
+ -webkit-border-radius: 8px;
+ -moz-border-radius: 8px;
+ border-radius: 8px;
+}
+
+.list-vm li>* {
+ height: 130px;
+ display: table-cell;
+ vertical-align: top;
+ position: relative;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #fff;
+}
+
+.list-vm li>*:FIRST-CHILD {
+ border-left: none;
+}
+
+.list-vm li>*:LAST-CHILD {
+ border-right: none;
+}
+
+.list-vm li>.guest-tile{
+ text-align: center;
+ vertical-align: middle;
+}
+
+.list-vm .handle {
+ display: block;
+ width: 50px;
+ height: 130px;
+ box-sizing: border-box;
+ box-shadow: inset 4px 4px 4px #0289e2, inset -4px -4px 4px #04385d;
+ background: #0b6bad url(../images/theme-default/arrow_out.png) center
+ center no-repeat;
+ border-top-right: 1px solid #CCC;
+ -webkit-border-top-right-radius: 8px;
+ -moz-border-top-right-radius: 8px;
+ border-top-right-radius: 8px;
+ border-bottom-right: 1px solid #CCC;
+ -webkit-border-bottom-right-radius: 8px;
+ -moz-border-bottom-right-radius: 8px;
+ border-bottom-right-radius: 8px;
+}
+
+.list-vm .subtitle {
+ color: #666;
+ font-size: 13px;
+ text-align: center;
+ line-height: 10px;
+ font-weight: bold;
+}
+
+.list-vm .tile .imgload {
+ display: none;
+}
+
+.list-vm .tile.shutoff .imgactive {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ display:inline;
+ border: none;
+ position: relative;
+}
+
+.list-vm .tile.paused .imgactive {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ display:inline;
+ border: none;
+ position: relative;
+}
+
+.list-vm .tile.running .imgactive{
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ display:inline;
+ border: none;
+ cursor: crosshair;
+ cursor: -moz-zoom-in;
+ cursor: -webkit-zoom-in;
+}
+
+.list-vm .tile .overlay {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ position:absolute;
+ bottom:0;
+ right:0;
+ display:none;
+}
+
+.guest-type {
+ width: 257px;
+}
+
+.guest-cpu {
+ width: 91px;
+}
+
+.guest-network {
+ width: 91px;
+}
+
+.guest-storage {
+ width: 91px;
+}
+
+.guest-tile {
+ width: 190px;
+}
+
+.guest-users {
+ width: 93px;
+}
+
+.guest-actions {
+ width: 125px;
+ min-width: 125px;
+}
+
+.guest-handle {
+ width: 50px;
+}
+
+.guest-general {
+ padding: 10px;
+ border-bottom: 1px solid #ccc;
+ width: 237px;
+}
+
+.guest-ip {
+ padding: 0 10px;
+ border-top: 1px solid #fff;
+}
+
+.guest-general .title {
+ color: #666;
+ font-size: 16px;
+ font-weight: normal;
+ height: 25px;
+ line-height: 25px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ max-width: 237px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.guest-general .text {
+ font-weight: bold;
+ color: #999;
+ font-size: 11px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+}
+
+.guest-users .top {
+ border-bottom: 1px solid #ccc;
+ padding: 3px 10px;
+}
+
+.guest-users .bottom {
+ border-top: 1px solid #fff;
+ padding: 3px 10px;
+}
+
+.guest-users .users {
+ height: 45px;
+ line-height: 45px;
+ background: url(../images/theme-default/icon-user.png) left
+ center no-repeat;
+ padding-left: 50px;
+ font-size: 36px;
+ font-weight: bold;
+}
+
+.guest-users .snapshots {
+ height: 40px;
+ line-height: 40px;
+ background: url(../images/theme-default/icon-camera.png) left
+ center no-repeat;
+ padding-left: 50px;
+ font-size: 36px;
+ font-weight: bold;
+}
+
+.guest-users .mini-text {
+ font-size: 11px;
+ font-weight: normal;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+}
+
+.guest-actions .top {
+ padding: 7px 10px;
+ width: 200px;
+}
+
+.guest-actions .top button {
+ display: inline-block;
+ width: 42px;
+ height: 42px;
+}
+
+ at -moz-document url-prefix() {
+ .guest-actions .top button span {
+ margin-left: -3px;
+ margin-top: -1px;
+ }
+}
+
+.guest-actions .bottom {
+ padding: 0 10px;
+}
+
+.list-vm .tile {
+ max-width: 170px;
+ max-height: 110px;
+ width: auto;
+ height: auto;
+ margin: 10px;
+}
+
+.list-vm .tile:not(.shutoff) && .tile:not(.paused) img {
+ box-shadow: -1px -1px 2px rgb(0, 0, 0, .25), 3px 3px 3px #fff;
+}
+
+.list-vm .shutoff {
+ position: relative;
+ box-shadow: none !important;
+}
+
+.list-vm .shutoff img {
+ opacity: 0.4;
+}
+
+.list-vm .paused {
+ position: relative;
+ box-shadow: none !important;
+}
+
+.list-vm .paused img {
+ opacity: 0.6;
+}
+
+.list-title {
+ color: #666;
+ font-weight: bold;
+ font-size: 12px;
+ overflow: hidden;
+ margin: 10px;
+}
+
+.list-title li {
+ display: table-cell;
+ padding: 0 1px;
+}
+
+.list-no-result {
+ font-size: 16px;
+ height: 48px;
+ line-height: 48px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ padding-left: 10px;
+}
+
+.guest-pending {
+ margin: 10px;
+}
+
+.guest-pending .icon {
+ background: url('../images/theme-default/kimchi-loading15x15.gif') no-repeat;
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ vertical-align: middle;
+}
+
+.guest-pending .text {
+ color: #666666;
+ margin-left: 5px;
+ text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/network.css b/src/wok/plugins/kimchi/ui/css/theme-default/network.css
new file mode 100644
index 0000000..fc8a24f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/network.css
@@ -0,0 +1,267 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+.network {
+ margin: 5px;
+}
+
+.network .grid-control {
+ height: 40px;
+ padding: 5px 0;
+}
+
+.network .grid-control .filter {
+ width: 300px;
+ padding: 5px;
+ float: right;
+}
+
+.network .list .column-name {
+ width: 20%;
+ max-width: 20%;
+ text-overflow: ellipsis;
+}
+
+.network .list .column-state {
+ width: 10%;
+}
+
+.network .list .column-type {
+ width: 15%;
+}
+
+.network .list .column-interface {
+ width: 15%;
+}
+
+.network .list .column-space {
+ width: 25%;
+}
+
+.network .list .column-action {
+ display: inline-block;
+ float: right;
+ height: 40px;
+}
+
+.network .list .hide-action-item {
+ display: none;
+}
+
+.network .list .menu-container {
+ display: none;
+ top: 58px;
+}
+
+.network .list .action-button {
+ float: right;
+ margin-top: 2px;
+ margin-left: 5px;
+}
+
+.network .list .action-button-icon {
+ background: url("../images/theme-default/arrow-down-black.png") no-repeat
+ scroll center center transparent;
+}
+
+.network .list .ui-state-disabled {
+ margin: 0px;
+}
+
+.network .list .network-state {
+ display: inline-block;
+ height: 16px;
+ width: 16px;
+ border-radius: 8px;
+ margin-left: 10px;
+}
+
+.network .list .nw-loading {
+ background: #c0c0c0 url(../images/theme-default/loading.gif)
+ center no-repeat;
+}
+
+.network .list .up {
+ background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
+ #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
+}
+
+.network .list .down {
+ background: linear-gradient(to bottom, #AFAFAF 0%, #AFAFAF 50%,
+ #AFAFAF 51%, #AFAFAF 100%) repeat scroll 0 0 transparent;
+}
+
+.network-config {
+ font-family: Arial;
+ font-size: 12px;
+ margin-bottom: 40px;
+ display: none;
+}
+
+.network-config .section-container {
+ margin-top: 20px;
+}
+
+.network-config .section-container:first-child {
+ margin-top: 10px;
+}
+
+.network-config .section-container:last-child {
+ height: 200px;
+}
+
+.network-config .section-container .bridged-inline {
+ display: inline-block;
+ vertical-align: top;
+ max-width: 520px;
+}
+
+.network-config .section-header {
+ font-size: 14px;
+ font-weight: lighter;
+}
+
+.network-config .section-content {
+ margin-top: 10px;
+}
+
+.network-config input[type="text"] {
+ border: 1px solid #CCCCCC;
+ font-size: 16px;
+ height: 30px;
+ width: 300px;
+ line-height: 30px;
+ padding: 0 5px;
+}
+
+.network-config input.invalid-field[type="text"] {
+ border-color: #FF4444;
+}
+
+.network-config input.invalid-field[type="text"][disabled] {
+ border-color: #666666;
+}
+
+.network-config input[type="radio"] {
+ margin-right: 5px;
+ margin-top: 0px;
+}
+
+.network-config select {
+ color: #666666;
+ border: solid 1px;
+ background-color: white;
+ padding: 3px 4px 3px 0;
+}
+
+.network-config .input-container {
+ height: 20px;
+}
+
+.network-config label {
+ vertical-align: top;
+}
+
+.network-type-wrapper-controls input[type="text"] {
+ height: 38px;
+ line-height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding: 0 10px;
+ margin-top: 5px;
+ width: 50px;
+}
+
+.network-type-wrapper-controls > .dropdown {
+ margin: 5px 0 0 1px;
+ width: 180px;
+}
+
+.network-type-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+.network-type-wrapper-controls span[type="text"] {
+ padding: 0 10px;
+}
+
+.bridge-option-column {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.bridge-option-column label {
+ margin-left: 42px;
+}
+
+.network-type-wrapper-controls {
+ width: 80px;
+ display: inline-block;
+ vertical-align: top;
+ padding: 5px 5px 5px 22px;
+}
+
+#enableVlan {
+ margin-left: 42px;
+ vertical-align: middle;
+}
+
+#labelEnableVlan {
+ vertical-align: middle;
+}
+
+#labelNetworkVlanID {
+ margin-left: 42px;
+ vertical-align: middle;
+ display: none;
+}
+
+#networkVlanID {
+ width: 80px;
+ vertical-align: middle;
+ display: none;
+}
+
+.network-config .input-hint-icon {
+ margin: -1px 1px 0 0;
+ display: inline-block;
+}
+
+.network-config .input-hint {
+ margin-top: 3px;
+}
+
+.network-config .input-hint-text {
+ color: #999999;
+ font-weight: lighter;
+ font-size: 12px;
+}
+
+.ui-state-default a {
+ color: #212121;
+}
+
+#networkConfig {
+ padding-left: 30px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css b/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css
new file mode 100644
index 0000000..8020182
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css
@@ -0,0 +1,37 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+#report-add-window {
+ height: 300px;
+ width: 400px;
+}
+
+#report-add-window .field {
+ font-size: 12px;
+}
+
+#report-name-textbox {
+ margin: 0;
+ width: 100%;
+}
+
+.info-add-debug-report {
+ font-size: 12px;
+ color: #999999;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
\ No newline at end of file
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css b/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css
new file mode 100644
index 0000000..2fb2698
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css
@@ -0,0 +1,39 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+#report-rename-window {
+ height: 300px;
+ width: 400px;
+}
+
+#report-rename-window .field {
+ font-size: 12px;
+}
+
+#report-name-textbox {
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0;
+ width: 100%;
+}
+
+.info-debug-report-rename {
+ font-size: 12px;
+ color: #999999;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css b/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css
new file mode 100644
index 0000000..4344569
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css
@@ -0,0 +1,42 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+#repository-add-window {
+ height: 500px;
+ width: 1000px;
+}
+
+#repository-add-window span.required {
+ color: red;
+ padding-left: 5px;
+ vertical-align: top;
+}
+
+#repository-add-window .textbox-wrapper input[type="text"] {
+ box-sizing: border-box;
+ width: 100%;
+}
+
+#repository-add-window .textbox-wrapper label {
+ vertical-align: middle;
+}
+
+#isMirrorLabel {
+ font-size: 14px;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
\ No newline at end of file
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css b/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css
new file mode 100644
index 0000000..383a7fe
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css
@@ -0,0 +1,88 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+.yum div#repository-edit-window {
+ height: 680px;
+ width: 1000px;
+}
+
+.deb div#repository-edit-window {
+ height: 480px;
+ width: 1000px;
+}
+
+
+.repository-edit-fieldset {
+ float: left;
+ padding: 0 30px;
+ width: 95%;
+}
+
+.repository-edit-wrapper-label, .repository-edit-wrapper-controls {
+ display: inline-block;
+ height: 30px;
+ line-height: 30px;
+ font-size: 14px;
+ vertical-align: top;
+}
+
+.repository-edit-wrapper-label {
+ margin-top: 10px;
+ width: 150px;
+}
+
+.repository-edit-wrapper-controls label {
+ vertical-align: middle;
+}
+
+.repository-edit-wrapper-controls {
+ width: 100%;
+}
+
+.repository-edit-wrapper-controls input[type="text"] {
+ font-size: 16px;
+ height: 30px;
+ line-height: 30px;
+ padding: 0 10px;
+ width: 100%;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ border: 1px solid #CCCCCC;
+}
+
+
+.repository-edit-wrapper-controls input[type="text"][readonly] {
+ color: #bbb;
+ background-color: #fafafa;
+}
+
+
+.repository-edit-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+
+.deb .yum{
+ display: none;
+}
+
+
+.yum .deb{
+ display: none;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/storage.css b/src/wok/plugins/kimchi/ui/css/theme-default/storage.css
new file mode 100644
index 0000000..88447b5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/storage.css
@@ -0,0 +1,550 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+/* STORAGE */
+.storage {
+ margin: 5px;
+}
+
+
+.storage .grid-control {
+ height: 40px;
+ padding: 5px 0;
+}
+
+.storage .grid-control .filter {
+ width: 300px;
+ padding: 5px;
+ float: right;
+}
+
+.storage-allocate-padding-user {
+ padding-right: 108px;
+}
+
+.usage {
+ float: right;
+ margin-right: 30px;
+}
+
+.list-storage .storage-li>.guest-tile {
+ text-align: center;
+ vertical-align: middle;
+}
+
+.list-storage .subtitle {
+ color: #666;
+ font-size: 13px;
+ text-align: center;
+ line-height: 10px;
+ font-weight: bold;
+}
+
+.list-storage .tile .imgload {
+ display: none;
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+}
+
+.list-storage .tile .imgactive {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+}
+
+.storage-volum {
+ height: 40px;
+ width: 186px;
+ display: table-cell;
+ vertical-align: top;
+ position: relative;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #fff;
+}
+
+.storage-name {
+ width: 15%;
+}
+
+.storage-state {
+ width: 10%;
+}
+
+.storage-type {
+ width: 10%;
+}
+
+.storage-capacity {
+ width: 10%;
+}
+
+.storage-allocate {
+ width: 10%;
+}
+
+.storage-location {
+ width: 30%;
+}
+
+.storage-button {
+ width: 9%;
+}
+
+.handle {
+ width: 2%;
+}
+
+.status-dot {
+ background: #72AA00;
+ background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
+ #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
+ border: 1px solid #72AA00;
+ border-radius: 13px;
+ box-shadow: 3px 3px 3px #FFFFFF, -3px -3px 3px #DDDDDD;
+ height: 13px;
+ width: 13px;
+ margin-left: 10px;
+}
+
+.toolable {
+ position: relative;
+}
+
+.toolable .tooltip {
+ display: none;
+ border: 2px solid #0B6BAD;
+ background: #fff;
+ padding: 6px;
+ position: absolute;
+ color: #666666;
+ font-weight: bold;
+ font-size: 11px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ z-index: 100;
+ top: -300%;
+ left: -140%;
+ white-space: nowrap;
+}
+
+.toolable:hover .tooltip {
+ display: block;
+}
+
+.toolable .tooltip:after {
+ -moz-border-bottom-colors: none;
+ -moz-border-left-colors: none;
+ -moz-border-right-colors: none;
+ -moz-border-top-colors: none;
+ border-color: #fff transparent transparent;
+ border-image: none;
+ border-style: solid;
+ border-width: 7px;
+ content: "";
+ display: block;
+ left: 15px;
+ position: absolute;
+ bottom: -14px;
+}
+
+.toolable .tooltip:before {
+ -moz-border-bottom-colors: none;
+ -moz-border-left-colors: none;
+ -moz-border-right-colors: none;
+ -moz-border-top-colors: none;
+ border-color: #0B6BAD transparent transparent;
+ border-image: none;
+ border-style: solid;
+ border-width: 8px;
+ content: "";
+ display: block;
+ left: 14px;
+ position: absolute;
+ bottom: -18px;
+}
+
+.inactive {
+ background: #E80501;
+ background: linear-gradient(to bottom, #E88692 0%, #E84845 50%,
+ #E80501 51%, #E84845 100%) repeat scroll 0 0 transparent;
+ border: 1px solid #FF340C;
+}
+
+.storage-volumes {
+ width: 90px;
+}
+
+.storage-actions {
+ width: 125px;
+}
+
+.storage-action {
+ width: 70px;
+}
+
+.detail-view-icon {
+ background: url(../images/large_details_icon.png) no-repeat center
+ center;
+ height: 30px;
+ width: 42px;
+}
+
+.volumes {
+ background: #73716F;
+ width: 1004px;
+ display: none;
+ margin-top: 10px;
+ border: 1px solid rgb(204, 204, 204);
+}
+
+.volumeslist {
+ padding: 7px;
+ max-height: 272px;
+ min-height: 136px;
+ overflow: auto;
+ color: #ffffff;
+}
+
+.volumes>.footer {
+ height: 48px;
+ z-index: 100;
+ box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.15);
+}
+
+.volume-title {
+ float: left;
+ padding: 4px;
+ margin-bottom: 5px;
+ width: 130px;
+}
+
+.pool-empty {
+ text-align:center;
+ line-height:136px;
+}
+.volume-title>.volume-name {
+ font-size: 14px;
+ font-weight: normal;
+ padding-bottom: 5px;
+ max-width: 120px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.volume-box {
+ border-radius: 8px;
+ background: white;
+ color: #666666;
+ float: left;
+ height: 100px;
+ margin: 7px;
+ padding: 10px;
+ width: 205px;
+ border: 1px solid rgb(204, 204, 204);
+}
+
+.volume-box .volume-state {
+ font-size: 75%;
+}
+
+.volume-box .label {
+ color: white;
+ font-weight: bold;
+ padding: 1px 5px;
+ text-shadow: none;
+}
+
+.volume-box .used {
+ background-color: #FF7121;
+ border-radius: 5px 5px 5px 5px;
+}
+
+.volume-box .free {
+ background: none repeat scroll 0 0 #72AA00;
+ border-radius: 5px 5px 5px 5px;
+}
+
+.volume-setting {
+ float: right;
+ padding: 5px;
+}
+
+.volume-setting>* {
+ height: 16px;
+ width: 16px;
+ border: none;
+ float: left;
+ padding: 2px;
+ cursor: pointer;
+}
+
+.field>select {
+ height: 30px;
+ width: 160px;
+ font-size: 14px;
+ padding-left: 8px;
+}
+
+.clear {
+ clear: both;
+}
+
+.volume-text {
+ color: #999999;
+ float: left;
+ font-size: 10px;
+ font-weight: bold;
+ height: 18px;
+ line-height: 18px;
+ width: 142px;
+ max-width: 85px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.volume-textquota {
+ color: #999999;
+ float: left;
+ font-size: 10px;
+ font-weight: bold;
+ height: 18px;
+ line-height: 18px;
+ width: 142px;
+ max-width: 95px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.volume-type-position {
+ display: inline;
+ padding-right: 5px;
+ clear: both;
+ width: 90px;
+ border-right: 1px solid #999;
+ float: left;
+ white-space: nowrap;
+}
+
+.volume-quota-position {
+ display: inline;
+ width: 90px;
+ padding-left: 5px;
+ float: left;
+ border-left: 1px solid #eee;
+ white-space: nowrap;
+}
+
+.list-storage .storage-li[data-stat="active"]>.handle>.arrow-down {
+ background: url(../images/theme-default/arrow-down.png) no-repeat center
+ center;
+ height: 18px;
+ width: 18px;
+}
+
+.list-storage .storage-li[data-stat="inactive"]>.handle>.arrow-down {
+ background: url(../images/theme-default/arrow-down-disable.png) no-repeat
+ center center;
+ height: 18px;
+ width: 18px;
+}
+
+.arrow-up {
+ background: url(../images/theme-default/arrow-up.png) no-repeat center
+ center;
+ height: 18px;
+ width: 18px;
+}
+
+.storage-icon {
+ border: 1px solid #CCCCCC;
+ border-radius: 8px 8px 8px 8px;
+ height: 40px;
+ width: 40px;
+ margin: 0 10px 10px 0;
+ float: left;
+ display: inline;
+}
+
+.volume-default {
+ background: url(../images/theme-default/icon-volume-default.png)
+ no-repeat center center;
+}
+
+.icon-raw {
+ background: url(../images/theme-default/icon-raw.png) no-repeat center
+ center;
+}
+
+.icon-qcow2 {
+ background: url(../images/theme-default/icon-qcow2.png) no-repeat center
+ center;
+}
+
+.icon-iso {
+ background: url(../images/theme-default/icon-iso.png) no-repeat center
+ center;
+}
+
+.host-partition {
+ padding-left:13px;
+}
+
+.host-partition>div {
+ font-size: 13px;
+ height: 18px;
+ padding: 10px;
+ color: #666;
+ float: left;
+ max-width: 200px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-weight: bold;
+ line-height: 18px;
+ white-space: nowrap;
+}
+
+.storage-type-wrapper-controls {
+ width: 300px;
+ display: inline-block;
+ vertical-align: top;
+ padding: 5px 5px 5px 22px;
+}
+
+.storage-type-wrapper-controls input[type="text"] {
+ height: 38px;
+ line-height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding: 0 10px;
+ margin-top: 5px;
+ width: 250px;
+}
+
+.storage-type-wrapper-controls > .dropdown {
+ margin: 5px 0 0 1px;
+ width: 200px;
+}
+
+.storage-type-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+.storage-add-input-width {
+ width: 285px;
+}
+
+.form-section .storage-field {
+ overflow: visible;
+}
+
+.storage-base-input-width {
+ width: 300px;
+}
+
+.storage-window {
+ width: 600px;
+ height: 700px;
+}
+
+.storage-port-width {
+ width:40px;
+}
+
+.storage-auth-width {
+ width: 150px;
+}
+
+.storage-window .form-section .field {
+ overflow: visible;
+}
+
+#pool-loading {
+ margin: 10px 15px;
+ background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
+ center no-repeat;
+ padding: 0 20px 0 26px;
+}
+
+.storage-admin .filter-select {
+ display: inline-block;
+ position: relative;
+}
+
+#iscsiportId, .storage-admin .filter-select input {
+ border: 1px solid #CCCCCC;
+ border-radius: 1px;
+ font-size: 14px;
+ padding: 3px 3px 3px 10px;
+ height: 30px;
+}
+
+.storage-admin .filter-select input::-ms-clear {
+ display: none;
+}
+
+#iSCSIServer input {
+ width: 410px;
+}
+
+#iscsiportId {
+ width: 60px;
+}
+
+#iSCSITarget input {
+ width: 493px;
+}
+
+/* Progress bar */
+.volume-progress {
+ clear: both;
+ width: 140px;
+}
+
+.volume-progress .progress-bar-outer {
+ background: #ccc;
+ height: 4px;
+ overflow: hidden;
+ width: 100%;
+}
+
+.volume-progress .progress-bar-inner {
+ background: #090;
+ height: 100%;
+ width: 0%;
+}
+
+.volume-progress .progress-label {
+ color: #999;
+ font-size: 10px;
+ line-height: 16px;
+}
+
+.volume-progress .progress-transferred {
+ float: right;
+}
+/* End of Progress bar */
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css b/src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
new file mode 100644
index 0000000..6e8a551
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
@@ -0,0 +1,36 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+#sp-add-volume-window {
+ height: 400px;
+ width: 500px;
+}
+
+#sp-add-volume-window .textbox-wrapper input[type="text"] {
+ box-sizing: border-box;
+ width: 100%;
+}
+
+#sp-add-volume-window .textbox-wrapper label {
+ vertical-align: middle;
+}
+
+#sp-add-volume-window input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css b/src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css
new file mode 100644
index 0000000..7c93117
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css
@@ -0,0 +1,175 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+#template-edit-window {
+ font-size: 13px;
+ height: 500px;
+ width: 800px;
+}
+
+#edit-template-tabs {
+ background: none repeat scroll 0 0 transparent;
+ border: medium none;
+ height: 100%;
+ padding: 0;
+}
+
+#edit-template-tabs .form-template-inline-wrapper {
+ display: inline-block;
+ vertical-align: top;
+}
+
+.template-edit-wrapper-label {
+ vertical-align: top;
+ min-width: 100px;
+ height: 35px;
+ line-height: 35px;
+ margin: 7px 0 8px;
+}
+
+.template-edit-wrapper-controls {
+ vertical-align: top;
+ width: 400px;
+}
+
+.template-edit-wrapper-controls input[type="text"] {
+ height: 38px;
+ line-height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding: 0 10px;
+ margin-top: 5px;
+ width: 100%;
+}
+
+.template-edit-wrapper-controls > .dropdown {
+ margin: 5px 0 0 1px;
+ width: 372px;
+}
+
+.template-edit-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+#edit-template-tabs .template-tab-header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ overflow: hidden;
+}
+
+#edit-template-tabs .template-tab-header .action-area {
+ float: right;
+ height: 20px;
+ width: 20px;
+}
+
+#edit-template-tabs .template-interface-cell {
+ display: inline-block;
+ width: 250px;
+}
+
+#edit-template-tabs .template-storage-cell{
+ display: inline-block;
+ width: 180px;
+}
+
+#edit-template-tabs .template-storage-cell label {
+ height: 25px;
+ padding: 2px;
+ border: 1px;
+}
+
+#form-template-storage .template-tab-body select {
+ width: 140px;
+}
+
+#form-template-storage .template-tab-body input {
+ width: 56px;
+ height: 17px;
+}
+
+#form-template-storage .template-tab-body .template-storage-name {
+ width: 170px;
+}
+
+#form-template-storage .template-tab-body .template-storage-disk-format {
+ width: 160px;
+}
+
+#edit-template-tabs .template-tab-body input[readonly] {
+ background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
+ border-color: transparent;
+ text-overflow: ellipsis;
+}
+
+#edit-template-tabs .template-tab-body .item {
+ height: 25px;
+}
+
+#form-template-interface .template-tab-body select {
+ width: 180px;
+}
+
+#edit-template-tabs .template-tab-body .action-area {
+ float: right;
+}
+
+#edit-template-tabs .template-tab-body .action-area button {
+ width: 20px;
+ height: 20px;
+}
+
+#edit-template-tabs .hide {
+ display: none;
+}
+
+#form-template-processor select,
+#form-template-processor input[type="text"] {
+ margin-left: 10px;
+}
+
+#form-template-processor input[type="checkbox"] {
+ margin-right: 5px;
+}
+
+#form-template-processor .manual {
+ margin-top: 10px;
+ margin-left: -3px;
+}
+
+#form-template-processor .topology {
+ margin: 10px 30px;
+}
+
+#form-template-processor .topology div {
+ margin-bottom: 10px;
+}
+
+#form-template-processor .topology select {
+ width: 80px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template.css b/src/wok/plugins/kimchi/ui/css/theme-default/template.css
new file mode 100644
index 0000000..27fe404
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template.css
@@ -0,0 +1,85 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+.tile-template>li>label:hover .summary {
+ opacity: 0.1;
+}
+
+.tile-template>li>label:hover .list-info {
+ top: 0;
+}
+
+.tile-template .summary {
+ -webkit-transition: opacity 0.25s;
+ -moz-transition: opacity 0.25s;
+ transition: opacity 0.25s;
+}
+
+.tile-template .list-info {
+ -webkit-transition: top 0.25s;
+ -moz-transition: top 0.25s;
+ transition: top 0.25s;
+ position: absolute;
+ top: 100%;
+ width: 100%;
+}
+
+.tile-template .list-info>li {
+ border-bottom: 1px dotted #ccc;
+ padding: 5px;
+ font-size: 12px;
+ line-height: 20px;
+ overflow: hidden;
+ width: 96%;
+}
+
+.tile-template .list-info>li>label {
+ display: inline-block;
+ color: #111;
+ width: auto;
+ text-align: left;
+ cursor: pointer;
+}
+
+.tile-template .list-info>li>span {
+ float: right;
+ color: #444693;
+ width: auto;
+ text-align: right;
+}
+
+.os-icon {
+ text-align: center;
+}
+
+.os-icon .title {
+ display: block;
+ font-size: 14px;
+ margin-bottom: 5px;
+ overflow: hidden;
+ width: 260px;
+ word-break: break-all;
+ word-wrap: break-word;
+ height: 50px;
+ line-height: 25px;
+}
+
+.os-icon img {
+ margin-top: 7px;
+ width: 64px;
+ height: 64px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template_add.css b/src/wok/plugins/kimchi/ui/css/theme-default/template_add.css
new file mode 100644
index 0000000..f1e28c5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template_add.css
@@ -0,0 +1,317 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+.page-list {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ overflow: hidden;
+}
+
+.page {
+ position: absolute;
+ left: 100%;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+}
+
+.page>header {
+ position: relative;
+ overflow: hidden;
+}
+
+.button-group {
+ margin-left: 5px;
+}
+
+.back {
+ float: left; display : block;
+ width: 50px;
+ height: 52px;
+ background: url(../images/theme-default/icon-back.png) center
+ center no-repeat;
+ cursor: pointer;
+ display: block;
+}
+
+.step-title {
+ color: #333;
+ font-size: 18px;
+ font-weight: normal;
+ padding: 15px 10px;
+}
+
+.step-choose>li>a {
+ display: block;
+ margin: 0 10px 10px;
+ padding: 20px 10px 20px 65px;
+ border: 2px solid #ccc;
+ background: url(../images/theme-default/icon-local.png) 15px
+ center no-repeat;
+ cursor: pointer;
+}
+
+.step-choose>li>a.local {
+ background-image: url(../images/theme-default/icon-local.png);
+}
+
+.step-choose>li>a.remote {
+ background-image: url(../images/theme-default/icon-remote.png);
+}
+
+.step-choose>li>a:HOVER {
+ border: 2px solid #06C;
+}
+
+.step-subtitle {
+ font-size: 16px;
+ height: 48px;
+ line-height: 48px;
+ color: #06C;
+ margin: 0 10px;
+ font-weight: bold;
+ text-shadow: -1px -1px 1px #eaeaea, 1px 1px 1px #fff;
+}
+
+.custom-iso-field {
+ position: relative;
+ padding: 0 10px 10px;
+}
+
+.custom-iso-field>.input-wrapper {
+ margin-right: 110px;
+}
+
+.custom-iso-field>.input-wrapper>input.text {
+ padding: 10px;
+ color: #333;
+ font-size: 13px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ width: 100%;
+}
+
+.custom-iso-field>button {
+ position: absolute;
+ top: -6px;
+ right: 8px;
+}
+
+.iso-field .button-field {
+ padding: 0 20px;
+ text-align: right;
+}
+
+.check-all {
+ display: inline-block;
+ position: relative;
+ height: 38px;
+ line-height: 38px;
+ margin: 5px;
+ font-size: 13px;
+}
+
+.check-all input {
+ margin: 0 5px 0 0;
+}
+
+.box {
+ background: #ffffff;
+ background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -webkit-gradient(linear, left top, left bottom,
+ color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
+ background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
+ endColorstr='#e5e5e5', GradientType=0);
+ border: 1px solid #ccc;
+ color: #333;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ -webkit-border-radius: 8px;
+ -moz-border-radius: 8px;
+ border-radius: 8px;
+}
+
+.box:HOVER {
+ border: 1px solid #aaa;
+ -webkit-box-shadow: #bbb 0px 0px 5px;
+ box-shadow: #bbb 0px 0px 5px;
+}
+
+.box-iso {
+ padding: 10px;
+ margin: 5px;
+ overflow: hidden;
+}
+
+.iso-icon {
+ float: left;
+ width: 58px;
+ height: 58px;
+ margin: 0 5px 0 0;
+ border: 1px solid #CCCCCC;
+ border-radius: 8px;
+ background: url(../images/icon-vm.png) center center no-repeat;
+ background-size: 58px;
+}
+
+.iso-icon.centos {
+ background-image: url(../images/icon-centos.png);
+}
+
+.iso-icon.debian {
+ background-image: url(../images/icon-debian.png);
+}
+
+.iso-icon.fedora {
+ background-image: url(../images/icon-fedora.png);
+}
+
+.iso-icon.opensuse {
+ background-image: url(../images/icon-opensuse.png);
+}
+
+.iso-icon.ubuntu {
+ background-image: url(../images/icon-ubuntu.png);
+}
+
+.iso-icon.gentoo {
+ background-image: url(../images/icon-gentoo.png);
+}
+
+.list-iso {
+ overflow: hidden;
+ margin: 5px;
+}
+
+.list-iso li {
+ float: left;
+ width: 320px;
+}
+
+.list-iso>li>label {
+ display: block;
+ cursor: pointer;
+}
+
+.list-iso>li>label>input[type="checkbox"] {
+ display: none;
+}
+
+.list-iso>li>label>input[type="checkbox"]:CHECKED+.box-iso {
+ border: 1px solid rgb(11, 107, 173);
+ -webkit-box-shadow: rgb(11, 107, 173) 0px 0px 4px;
+ box-shadow: rgb(11, 107, 173) 0px 0px 4px;
+}
+
+.iso-title {
+ margin: 0;
+ display: block;
+ position: relative;
+ height: 23px;
+ line-height: 23px;
+ font-size: 14px;
+ font-weight: normal;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.iso-title>label>input {
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 2px;
+}
+
+.iso-info {
+ margin-top: 5px;
+ overflow: hidden;
+}
+
+.iso-info-col {
+ float: left;
+ width: 50%;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0 0 0 5px;
+}
+
+.iso-info-col:FIRST-CHILD {
+ padding: 0 5px 0 0;
+ border-right: 1px solid #999;
+}
+
+.iso-info-item {
+ font-weight: bold;
+ color: #999;
+ font-size: 11px;
+ line-height: 18px;
+ max-width: 106px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+#iso-search {
+ margin: 10px 15px;
+}
+
+#iso-search-loading {
+ margin: 10px 15px;
+ background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
+ center no-repeat;
+ padding: 0 20px 0 26px;
+}
+
+#iso-more-loading {
+ background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
+ center no-repeat;
+ padding: 0 20px 0 26px;
+}
+
+#vm-image-local-box .body {
+ margin: 30px 0 0 26px;
+}
+
+#vm-image-local-box .body input {
+ background: none repeat scroll 0 0 #FFFFFF;
+ border-left: 1px solid #BBBBBB;
+ border-radius: 5px 5px 5px 5px;
+ border-top: 1px solid #BBBBBB;
+ box-shadow: 2px 2px 2px #EEEEEE inset;
+ color: #333333;
+ font-size: 13px;
+ padding: 10px;
+ margin-left: 10px;
+ width: 600px;
+}
+
+#vm-image-local-box .body button {
+ margin-left: 10px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template_list.css b/src/wok/plugins/kimchi/ui/css/theme-default/template_list.css
new file mode 100644
index 0000000..3161a33
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template_list.css
@@ -0,0 +1,267 @@
+/*
+* Project Kimchi
+*
+* Copyright IBM, Corp. 2013-2014
+*
+* 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.
+*/
+.list-template.framework {
+ float: left;
+ clear: both;
+}
+
+.template-box {
+ border-radius: 8px 8px 8px 8px;
+ box-shadow: none;
+ color: #666666;
+ float: left;
+ height: auto;
+ margin: 10px 11px 10px 0;
+ padding: 10px;
+ width: 308px;
+}
+
+.template-title {
+ font-size: 16px;
+ height: 25px;
+ line-height: 25px;
+}
+
+.template-icon {
+ border: 1px solid #CCCCCC;
+ border-radius: 8px 8px 8px 8px;
+ height: 58px;
+ margin: 0 10px 10px 0;
+ width: 48px;
+}
+
+.template-icon img {
+ width: 58px;
+}
+
+.template-text {
+ color: #999999;
+ float: left;
+ font-size: 11px;
+ font-weight: bold;
+ height: 18px;
+ line-height: 18px;
+ width: 142px;
+ display: table;
+}
+
+.white-box {
+ background: #ffffff;
+ background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -webkit-gradient(linear, left top, left bottom,
+ color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
+ background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
+ endColorstr='#e5e5e5', GradientType=0);
+ border: 1px solid #CCCCCC;
+ color: #333333;
+ text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
+}
+
+.row-select {
+ -moz-border-bottom-colors: none;
+ -moz-border-left-colors: none;
+ -moz-border-right-colors: none;
+ -moz-border-top-colors: none;
+ background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
+ scroll 0 0 transparent;
+ border-color: #999999 #AAAAAA #AAAAAA #999999;
+ border-image: none;
+ border-radius: 5px 5px 5px 5px;
+ border-right: 1px solid #AAAAAA;
+ border-style: solid;
+ border-width: 1px;
+ float: left;
+ font-size: 13px;
+ height: 42px;
+ line-height: 42px;
+ margin: 5px 0 0 10px;
+ padding-left: 10px;
+ text-align: left;
+ text-shadow: -1px -1px 1px #AAAAAA, 1px 1px 1px #FFFFFF;
+ width: 100px;
+}
+
+.bevel3 {
+ box-shadow: -2px -2px 2px #EAEAEA, 2px 2px 2px #FFFFFF, 3px 3px 3px white
+ inset, -3px -3px 3px rgba(0, 0, 0, 0.25) inset;
+ color: #333333;
+}
+
+.row-drop {
+ left: 10px;
+ position: relative;
+ top: 50px;
+}
+
+.template-action-hidden {
+ visibility: hidden;
+}
+
+.template-action-show {
+ visibility: visible;
+ display: block;
+}
+
+template-hidden {
+ display: none;
+}
+
+.select-drop {
+ background: none repeat scroll 0 0 #EEEEEE;
+ border: 2px solid #096AAD;
+ border-radius: 5px 5px 5px 5px;
+ box-shadow: 6px 6px 6px;
+ height: 147px;
+ left: 0;
+ position: absolute;
+ top: 8px;
+ width: 250px;
+ z-index: 2147483647;
+}
+
+.button-drop {
+ background: linear-gradient(to bottom, #EEEEEE 0%, #CCCCCC 10px, #CCCCCC
+ 96%, #A5A5A5 100%) repeat scroll 0 0 transparent;
+}
+
+.action-bevel {
+ box-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #EEEEEE;
+}
+
+.template-border {
+ border: 1px solid rgb(204, 204, 204);
+}
+
+.template-button-position {
+ position: relative;
+ left: 250px;
+ top: 55px;
+ z-index: 5555;
+}
+
+.tempate-action-position {
+ float: right;
+ width: 83px;
+ margin: 0;
+}
+
+.template-actiontext-position {
+ width: 250px;
+ height: 160px;
+}
+
+.template-line {
+ left: 200px;
+}
+
+.template-os-position {
+ padding-right: 10px;
+ clear: both;
+ width: 142px;
+ border-right: 1px solid #999;
+ float: left;
+}
+
+.template-cpu-position {
+ border-left: 1px solid #eee;
+ padding-left: 10px;
+ float: left;
+ width: 132px;
+}
+
+.template-icon-position {
+ float: left;
+ height: 58px;
+ width: 58px;
+}
+
+.template-icon img.template-type-icon-position {
+ width: 20px;
+ height: 20px;
+ position: relative;
+ top: -15px;
+ left: 49px;
+}
+
+.template-title-position {
+ float: left;
+ width: 120px;
+}
+
+.template-results {
+ background: linear-gradient(to bottom, #FFFFFF 35px, rgba(255, 255, 255, 0)
+ 100%) repeat scroll 0 0 transparent;
+ float: left;
+ height: 60px;
+ margin-bottom: -22px;
+ padding-left: 10px;
+ width: 1014px;
+}
+
+.select-row-action {
+ background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
+ scroll 0 0 transparent;
+ border: 1px solid #CCCCCC;
+ border-radius: 5px 5px 5px 5px;
+ float: left;
+ font-size: 13px;
+ height: 38px;
+ line-height: 38px;
+ margin: 10px 10px 0;
+ text-align: center;
+ text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
+ width: 230px;
+}
+
+.select-row-delete {
+ background: linear-gradient(to bottom, #FF3019 0%, #CF0404 100%) repeat
+ scroll 0 0 transparent;
+ border: 1px solid #B10F14;
+ border-radius: 5px 5px 5px 5px;
+ color: #FFFFFF;
+ float: left;
+ font-size: 13px;
+ font-weight: bold;
+ height: 38px;
+ line-height: 38px;
+ margin: 10px 10px 0;
+ text-align: center;
+ text-shadow: -1px -1px 1px #9E0505, 1px 1px 1px #FC5D4C;
+ width: 230px;
+}
+
+.template-general .title {
+ color: black;
+ font-size: 16px;
+ font-weight: normal;
+ height: 25px;
+ line-height: 25px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ max-width: 130px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.processing {
+ cursor: wait;
+}
diff --git a/src/wok/plugins/kimchi/ui/images/Makefile.am b/src/wok/plugins/kimchi/ui/images/Makefile.am
new file mode 100644
index 0000000..ca3ee6e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/images/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+SUBDIRS = theme-default
+
+imagedir = $(datadir)/wok/plugins/kimchi/ui/images
+
+dist_image_DATA = *.png
diff --git a/src/wok/plugins/kimchi/ui/images/icon-centos.png b/src/wok/plugins/kimchi/ui/images/icon-centos.png
new file mode 100644
index 0000000000000000000000000000000000000000..5afb7b4b63462412d825f63542beb1f7e26b3d7f
GIT binary patch
literal 4734
zcmV-^5`pcBP)<h;3K|Lk000e1NJLTq002J#002A)1^@s6(aU0S00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3h)2`3h)6!tTdPa000McNliru)C(I02nLeE_`m=F03CEi
zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9 at 01@IzL_t(|+U1*hcvRKh
z$3N%ZnaMIFAqh#y3V{%o5Fj9gC1DY;#iC$^YO7C+h_9~|#0>=mSt5p|A_ceVTdio-
zqR<x*go4NpAwWpj5yBGoB?%-mlg!M$zxR&>N`OGZ=G*o>&-rKWnS0Lnw=d_yT^=H$
ziAcJLOcs&){HF{N(M6=2h?y;hr&L5{h)9 at -{6~OK6Omlw`~fN3`>B}j3l0(alZe#$
zcjtJTm}b8BY>r%5e7_WZnIO(B6U20%_ln5-A`)@8B|y6yz=58?d)~8K8#*_S!#KYW
z0QdemxN at iI;wkwZFcFBlo8Z+Q1`d!8GSe(M+{Ur?S&Z|0t8S|_e49UoPm5>Dl*RrT
z at B-jaO8x7CujF_)kiQzIH`jM=8ii4MsG2PmwnhW+Ydu1gPw?l!D5cb~e at U?y5esl1
zV$SfM&aUs=nt at Sr@Z!_US5{0haUc3$%JQZwabFk+GG0WY at 3ak2H2`9*)Ww<-N`ThD
zRMT-R(YgKw3`fCb8!E(8f*3B8H4t>)Dg^OuIv87%$IF$)ZyqoKaMuD)8E{%DW!x_C
zO at IZ087yMnSd^3n5W6X69Sj%ZDY-;9r7Cci<xazWa322cCt;25jcJ-ygi+aoP`X8w
zrp}5frkLgpVJKaplv)iuqm(*V6Y!RrvC<4VdVWp#@sg}+sU<*UKzm|?x^b#Bhl2Af
z5izP9(9ar1v(WyaSwIAIADksVZ2NdEB9{w*;9J*UB|nxLW*R1Y=5EDtrleY4={AkV
zeOeNp6dh0-J7%e&5_6(7o4ivWqbcngk4+*2I?^PxKWCl0SaWzZ7s?B+S{LHil!UrJ
ztMXn~VJSKPvz9BltCYfdx`cb4?T&wV09kJ@!{hQ?6PnfEMo2;g;YrbV#^5Ow74GNi
z85P)>o{iqd<vGLm2cD}0e&sr?TBazi0_^1zAn&scteLck*e;FfHT_rEBLXiGrpj8S
zZpv?Iw`MIh;(~h6Id%+Z9C>U!IvI!O<Zbn!2fo|M+DVIvYS)0YQGKWr8T9|d)!8fo
zB!xdtpieA$r#_*mZ2xT!9ZavmzWLiYo_&b;Ud?HIUlL-<PX}Hpjk><^cnk-dj{bqO
z&Rukj9Z7_}EyC^f&AQD(+o!t`*R=`T|C+_FIh(Qi+pq=t{uJO9v4P#`*=Q!s!+uRs
z*?!g at 8Ha{W$JkMX+go$Hf)m|lq4l87q&$_*jxRQ``Q4QmZZGYJ-Anh0{VP=97WS$Y
zcoCBZLEY&P^AbLK5N+x|P4jw>Q0zLu+9R){P^34=AlNVAmL)(;q0N(Nqzp;tz;`>y
znz0<i<0WNC8p)4$B)(@ex=-wfPmuo=QR5u}uZRokL3+bU6ua_Su;*7CC|pRJ$Y*F9
z^(-e#b69m~6kfwg&qgzdu&3Pgp)5WY?s>L5?VjnzuCF(<=8Z)lkorPz?iqS7*|S!#
zV&pu+lA`$8A0MGkWZj#RHcL$x#s+nxX}yOzc3~ZxkN=TU&k44kco$O)nuZR*ZIrU-
z%p6u99z)lLljt1#8d*oDa-uZ5b_epa()OvYBtM=??kDTW`DhJFQ>4Doo5nv+BKPBU
z<bApx(=hS6+;p4Rk8ZE`MYmb*2<Js9T_WnF;P9McL%}3UD*d?IC?)6Q2kbBUmX!L>
zRN8<aS$`x0l%h-AIO_T~uDJvVq&$^Q^5dx-ShADsSu60Cc}W?PPRn1nXV2WNY<_Pg
zhQ~lmA^-c`tjk<XXtPKn+cn at CnbXaK7ZD$z2T0J7;+3q(e~~h8aTRywF-qBVbQ-(Q
zenrcO-;x^r3Wct{{E+`LPS0t2H-3kxfKCYJbwOMGZFGG3K2ip!kvDq-t0pYK;%lYL
z$e+`CP-oUpTgvA5e!y^ht3-kO7UuE&t8*zmb%DwREM7#^ErG8D{wTtD5!3gyV;e3{
z_4&fK6Cbem>|7G-Jw$TE6O?*Ru<pnN+(ro<Vnz at Z(6QS8TJ1L4{#RF$9%)a`pVzYO
z<8>%as}S`*E!p<TI(B}s3Dav{BRW(Z&pyb>oFf29z$75)Mm9i1lvdpX;4#x<ym313
zXq4MgUcsL0(9>f&$vycId(O-uIbtv^!v}G}eT>zIU&Cv<=-MEIaC at t(f*?)TXg~B`
zT0WM_?zvmo^4>}SIt;s)rv2Km{qrnxK3aomnAb}^Fuf*)g{697p`$18ZVe>Bs$B!P
z4fu^|m@|J|yglaoQFHOSJT=lGujyp- at tN#C^Cig<zoSF+ixj%{vFgxhO5DdujTwoL
zrEZn~1UCw!<*z%C_m}l#y|oP8$3mA;eP}(XGaIKbBj>}_RYd)IBR98zv18}yM~@bD
z1wN}z0xF48N4w%jU*Jj8FsJVRdW(Ji<nJgy at 2ahbCimn=>^%KBjf4BrE^;X4-Xc~X
z8qGQ9E|k(xKEWuTAT+;vm|l}jGgpxF=e6iQ7ShN3g1D}UY?`@(U4P5IF2}EqJQZ0R
z4={SvHykY}>LemFf%es?K!A2dvGGwc%&`S)evDd|xwyiJ+(aSKYr5Ee>J#>yokMcO
z6SNHfEv4?`Y(4P~ZqtQN!ejWgn}{CPo(o5d$eX<$5uyFCdrA03E4F{Wk=(zmuNCl1
zxqvBb+_;~NjQQG`GbLStS=XovE5P4U3EUqTVz|ATyXI{6-!N?{?$UBprG6@<2=#A4
zLdXNCTEs=?%MVfH+DEI1CkgP0rMT<>N@=EMk14j<V>F=5>gTTC<bl>S?9q%y_qE{2
zs(rZ5IcU;1xyCt?ZnF>=8^VbT&P(TAv0^tR!@tnSPw1bTm{@<FhztidDW#+myhVwK
z9eBd<7_aY{yESa%^kultmR39#s1q4TzuAMa2H6nt)=~ikO<B;D6^q at 1W>cbTwqj84
z00)7dVoHCb+-r9mCa!W1hTDr6wT#vj=vJMq?1PLQGY^NO{1OpbwTj{G8NV?iBkQiy
zH1z_I1L#0AB_c12VZM^TY<JkQ5ntnVR;?FmR-KT9aFniYHd;k#iiSO#)Bg9}O{Hr~
zfuWV)I|5TnF1XS at _+TX)HtfHpe4w<njDmtf%*#?<(-gXNX~MYi{ml6Iu+6}4fqWoA
z1CF6osb7d4pE^F*j*)LMOVe}>|4=(rR8>y{-b&H40U>UWL2<EzJ5j1u3eKG?!Qm)Z
zKo}5Qxp%p$bZvdblxas+|JZ1C#zKk at o~<Yk3Dk)SqTi>3(d{<8-r5-;5wO{GELI)O
z*9y8aZ8l4xQfdlNQd!%-UyO2JXBm{08(@@!n6*c!S=pF%n6YE#UJ`qNxVTVe%=nEo
zYaY2v*R>JAKPtgTT9i_55m~4-rQ*6a`7mwN{UNJfpMNo2tcV5zd|8#9&krkhqcl}h
zg-6#lh7RjRUAv91zRIGw*r^S9s#|bCfbZ{thziGW(zk5KJNU#uguPx{-1&>~p2 at CV
zMyT1aH5!23?q8)<*05nc#*cr9q?Xb7z$jp;Qp&9CCK;AW!{7ntiijh=XY*MBF~JGn
z4*8Ul<HeU)xNGMz=FiVTs{wcs2o1F};*~!5``gIOT*TkL%A#$%h75WlO)v8n#TT4k
zMO;vKtfm)F!FPC%Eyu6jIIJ<f at t)p*`|zR~6F^z~v4p1rO)mj&-XfYQQwB=2W|8}W
zfk0lRrN20gEB)5 at C`Q$5T7O at UH~JHj5MFB|CjucMc7{KHA8BccOn++$3+Cq#9BgOs
z;B at K)*w}OSE7lcE;6!OQnmrod<mV9)Tsd#zE!>W8%VF5!?!UQupi(qWh#({5A!*Vi
zA{Q8b4d8MW_(}=*JBnu;bZdI1`^0_(#0J;c5Q%`Vua#F{y`NsalKAMum3;YS7IwRh
zF=HR3SFa>AO}J2g6p!J=ZIpuP#nxy5zO7zBJPur0BQY)<!tb8(SR=dEy84sQIGoJP
z0kmoryI0q>=Yb_x0KW*{qg^9JG=SwOo`~uYzo+*f24bt at TVqk5FtI;f(h`|AbuqJN
zuO}+1E)ysIlC-oYeDMAXii(_7_-T~nQ<nP{)|lS-wa-AjrMNbY#&diXejVP#*06s?
zVZR0=p-BXjrwlY(w~pNjJPxe62JnmEy;^lKGO$!>>ZQP#;C&W9E4oF$F7SHw>hRLb
zeMn17<PXypvtU6EAt81qX8e+-%_5ncxrpV<cUJMi7b6sR{v678%)}Dj0l$>dfZ*Di
zfpKmdzRAy55a32CpfqA)Ld^L1upFh-?}4pKsq487w|1Q*!CUDTMroQ>+BH3q`1pEP
zx%>)uW?|ImzNDuo^8R}(Sg;_6y1{lvjqXdURx!N$&T<wm+*ZB$Fg=tX_=d6_v#`eX
z#W#64m>yhPCt?)s!mstqSfhJfn*d^>1;k^i+Z?6HSBjCq+G;p{Idi?*4YDLJuw5w}
zDQz3@!Jh`vpke4G0*F9(cmPwT4x~eeMogWunAx+}5g8fG)TzIsQ>O%8dhsjf&(Eol
zG`UWEDqh_Czr?jQ155P1_;;F)c$_%1Ud3~K75=Hyu*E-IRRzRE54#8d&TpdyB>?;g
z<lKPc7qLl=l*uqmwep8OxSVb#O?sH5q$os$h=@Q&ymCKn+cqTg&2L${bUXFy2QhAZ
zKVoA;$b9qL+J&r2!+m%@Wjkh}2Pff|G7_cxQkFXv at 2U0pCjB?IMguMpKo4z&fBT8x
zabOhf;<CozZ7f|2Y}s;%(WAd1E-sXD<NK4+wgIob_5d9_He%MS<t$v7L*2Umj2qvd
z7A>Nf{?-x}Ey}%#{*-|`{~OA3r(uo#Iliq&AY$Om9*a at 96TddEVvXsI9@+-~4w+zj
zE9^t%C8s;nrB$$V=P`y3{R~~#_~erzB)5toW8wn7`Fa!a at nK|U4kS4_hF4yh!;&T2
zZ>3{_`_SKUZJvlFA{GDCX at KC|JQnw%1^9Q!q)yil!6?VEb|^;i?wg7UwA#fFioDzc
zGBOshbH_0zPhP~b<vXcgKZr?h4j?)vm<i+Ovwq!vZuvHq(s3VINLk)n=)ukKYxjDE
z3T&H-=jd{b;ypOC$6%Hg+;nra)|LK?1Q<U2a|#QcL`Mbl+L#B3jR|Jbq=l?lv5VVw
zi%d-1hrb0e at M}9B)w&`IbmdG!S^P1bC%Bc(ZmLTwBAh$tz-rZbZg_9HcW=gf at 2_C_
z@?Ez*C9P0_1-K7<i6y2tJ}sU`%8M$1|CIfCkH^awf89u4ZUK)zl1jUF4R1eqG%OLF
zu*UYmIJ*UR{x>y_`0glp5!klvFk{EeBQVg9F=HR3MT_X$c6k61EMe{Nzb6B;{2Z>W
zZ(tPfy^Un8nWsafLfo&M0DJeH;OVFTLP<#(v)*}(HYssetv5}nK0y+bOBWI^yO?N=
z>4kslWK7pdoNJ!NIKTg&_t~zRcgWyrnxcJ&cns65){2V=$Bz|}k`l)oZ#>N6#d(yK
zd#com!@~pd^Rt5UG6U)pg00z;a78aqX+GEz9!1%LFi)+=+VH_ at jhoVJ=oJy(Z3k~^
znmX65TQf;dPrPv%S=UHxTHm*ELU^EIdQ`db&&H-w3Z*$Q#EU{<m}Qh(HE1!Y$~$~4
zL1 at YfN-qTQ*y0D&$Te1$#%e4EHNAcsT}x*g3uKlX7dovu{F*xL$g8rU+bG3rmSNKa
zuxLJ)PAg&(AABEeBZnEjmbz<!=PCi!bll$Sr#I;eHJ}~H<RaJp9$CkxsG}FwU$&XL
z%$i*MMI$CCowT^|hMzU;JB9Wtu={%1*)3Og at 6?Mcn}IEXFN$3Ilhz#>uTDC)T(jdN
z2(f|bbdDQKfGy?+V3<;BCwF+<@f-aj(j54s%X6;h%0nZx<0V;F0dErWARS^x7=D(}
zWxycd)ZO^l;EsQ00_*`s`dLF)c8Yz?j1KH_nE}*k5Y&VA(Jy-aETKz)my}X>1^8VX
zBBDejQN+wDE<0#0-uI+ at xH(alA9zk2?vo-S--<}nnqDXQS0zGI5&4J1ecH%7`LQ_N
zXFMXZSVSWDcOR7!kR)O*G)zyKh&e|@8vRFnR9IC7WQK?&{*-6=Kk6Dayw&uIx&QzG
M07*qoM6N<$f~4IfuK)l5
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-debian.png b/src/wok/plugins/kimchi/ui/images/icon-debian.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff49a39696fdfa5f232b0e79de04d90af6557111
GIT binary patch
literal 4239
zcmWldc{o(>8^+K0B4eq^STcyLC8fm@!jx?!k~OkNF}Cb}Swoa9yKG_XYqDi0W6jcx
zC0mvdLx$`|mf!0-*E#39&L4B$=e+mxx$kG*X=$o5(WB at g2x3yhC~1Rx!0Aax3$A#1
zi(YV}wNzJCf=*74%%=P}@C5!6W9SM&49uq|Y;el&5Ij8Nrlz5MW{R4FiCvo15Ud74
z2rf0Hd%9i|WRph^IbX1yXgpi!Ht!PpLl;+a!^1gV-yve$#8&Jx@#3Ynv<Eq*mI5Bt
z{erdHuKa90*RGB%#FiQfAgi at Wa9r?Ynf+eHVA)}QX-$j<ZNvj6dNq6dAahv%Me`?<
zWAh5P=Q+-8HOwKld|TF=X1r&-*Z;HXj&^=^uUj3mKTsU at lL-%UV|(yS7&2E#@1R(O
zE{v*P`mJ!C{oP}T at WVTKY&*1|)Q0QC#1QXj$;2-A%;rziL#UO*fm8R#Mb~i6N`a>k
zd^Ta7qk6*&mW;meARE^3uKMJ*X>rK3M8NH(iA- at +rnraYRaDpRUU)b4{Tu(*=8XM$
zVjkhhHeBo~pOCj;N)hS51*&guadEz9r<ZJGj#v3_Tk1?^g;BY$Qt(uJR)UtHcP61|
z!$Y3#jXqN(o_2~LK}z%Jc at mx{+?uDL<Z#!twX<(4<hZ3&pTW=F6?!#_)`@#<vlwZX
zen_8;e)4x6=gD;6-!-$<y_@<D4W}7nBtAs_qXIYb5~%acG8gnVkt?`y<FGb#svWgE
zG)}c)Yw{79-hhyU?P_xjg?WeBSG`~A)id6VfI$Nup3JvkBD4L*0Y<1MvzM_c++ at vv
z&fCt!+d{R<2yU21V%+ffn&w>YpNoQTbj;}KOHu!pMdMZQ?;7!iLanAE&t4Jz!$o&9
zw7UeqU+|NoyqMEP@`9CY{F0Rrbgq?&6tR0Wo+0(X4a+6 at WbvZ-PeFv`_#ykz7cbcz
zP@<dSXw*=f8+~o!;Rz_8EEKDHW&TDD&e^m%zemd1N7Y$`t~H-v=Q%<A?ap)6(a7v&
zuHLQJ2<=BL_(=+HKHGBG$zwc*_cF|s^6~Kk$#=ltDZ7K!_uS{>zfU#a{=_gNv?mTd
z^117?>;k8Ll5=n6?GzfixVzNbV$c|it*tj{<DLe81=O!IXD6zxSN?!U^1_HEsh`AA
zgte;qzB<W*61K}#SmN(V<a~yXola%Rn_sLa{L{Fgkn3Y$#Ye*@@IN%moAs%Si;)a%
zUu4O(cTWs(h4AvEZy#_|cmd9s98adXspJL?&!8UV54{Ezq;!>QZ3n}m#r;wd?=yR4
z9aWIH(!E>G9Vc}3rS)qwpJk+djpxVQsJ(8pXG&faD`!^p5im`Oq*lKh+}D_ at BbjGr
zE1o&OOJ`Kdb~%!kXq;6c#|XYR&Y7lBjP(7ZSfSCp<s1FT at Q*j$>YXqZ%u>s~_e*P=
z+ at Ipl@tL`LT=4RQRi_;57t`=4H7Bkv{)f*0M|*FSW;pD~jm=mf<&NO#zKXC at jkq-A
zgSF#HQo$?_eFZ=GAfM+FwPvzX{uc#QE{LLP4_%K|@NUi-OY^IA!d+2pd_}|!i6;Ac
z{`peE#oF75?^ym$-9}(dt}+%-(eqAn+||I;Y=yv=4*t>M_c6W}J9wv#djXNjG!?yn
z<YPXS=`W=H=+6i0dtN3b?sJ>noJ{*fDwHj}TFMo+vNQjtXs!Fvzr~?4-eq6yjaIk+
zO+f)c{O1cQcFj|Re$wTKo2mDSIr&{`>%64$_0an;y!)hN&}KF#IAZ8V`Gni2Mv5 at e
zIn|H>(4uScIQ9kOBvJXLvtsuZSkdF7SEHGY6v0vJfX56a3TeuH6b>5bw5fMOq8sZ1
zuw`-*XE~?O`CR(epP!wG-~DU#^*h*rg0fxoJZWBn+eAZ*+Ck2L*GFwR&ErQ0Uzkd|
z-^7c1dv9zceP2kcl`5olboNpCtsd2`E^Xq+c}o0qWE}n5dn2GJLUq`NTq$z9>>hZr
z^^yM%GF9xfFiSeDL}*d!-`aiA$QbX!h-J`&tjivj4%nJJ?*jlbpmwE(&>n;47ip&7
zKk|4W67IK=*V$oQyKF8*#jFBPnE&e0h4eK}b?9$>+p>Yp2u6-6Y;L$EnL&%V_A543
zbMKrDm#?5V?P-_mi$~eti1 at N~FFJc~gQv^v@^wxb at w1%I=+gbKmDNl}Z?#{Rbj-X?
zWv|NK1EhoD5)Qhc(2_B5- at RJ(Z@>R<Z~aY?#I*^z$tgA71Ew2>2Q%#d{9nnaRe68t
zQ?^WFaVjd?jTa2KU)<?vNv>_lnzDT{6{nTNpoL=6nsn$AE{cWg*^C5UJ<;aVTSqCa
zZ{D3wuX_qqS$8ad+CIV7YcTzvrkWxi;!*OQL7=HFK7Cy|mEI2Pl at G3`Lsy=I02GS(
zI*%|fD>GUsfK=<06aBr;B)+zPuf^VuzGwHkGAUAnurCU`gM7W+mMijsH<uU?wQ>F{
zmIBbI<9CJC#Hm$P at 3ZrYP9S-)phPahF5wkQbbk${%2QnY%X92w$%Dm{*cT7Ac3S2>
z$_!`@O6>Y{Zrb~M0`tgm9=o78cu1NDj^L~^`J62nO6Y4Dv_TB-EeY$h7)d;AhGQ(6
zdE^EpGsN2vnSqr2rC)Tv_qO6hA{`qRk;e6(>fzDh?HBr62>A*pud1hPlZI!PTm-$C
z1kt%eW==$YgM0-Ab(NW1b(&=K2bMJG;f4rA3JK;%H%k&5Xj98FGDon5HdChcYw)Km
zMpul_58hpTDxBqt*qH?&>&#de`jN?5FH}NPkaPD99|kM`1hEUhatL;xCFxkk%*;90
z*2|9ZJm1d=b?b)|4dlZOH+}?9a}b$i*?*kUykQsIJog4N&J(dSswMFyiyf2xg*{iy
zT|gxrgt1fI=%1QLc5t^Rw6o0Ak~r`j4yoc>5Jfr6^4>=O2g1t9VR=x2YS0bV(U;^O
zUZ0^9A&DkSG~n(xRv%yvB&V})`OgnC&KA9{_$(u2s=r{nDhaG{>z<6Ni!#+m at c?C(
z at bQSDPO%76;SYIP1R|@!I9g2^ChTLYRXeJ at LY~Y{bx{A+N30**in3<sy-#r1+)2dd
zE(TfEjhQ*KJhq~`G{9`!hzPjqQQ<BZ>1Xy<en)K`Su|*(CLM40Pd?3K+Rz-Xqz+}Z
zebO!qT}L&w^`|O#?Z1`gWE`!gbsPU*;eYNH+cIBOIZ|_s(S<bFcvg at pF6VwmD(w0_
zG%d+SJRjl_k(Co|DHj43Xe?AKkPiz(3Vt%|6D~>c0TyKQDcfuvB#a%M6Jc|iBT6uv
zvXEBE<$*XS<$0!FqthntEPP})&6U^upt*NNKox4TYc=kr3javZY>=KgbWNw%|GSav
zdfwv*YhTW7BCu2THBf-i+2;z7rYo0s8<5_?zlF})pv!`>xgsjat!DNLs^+rermoFM
zd7oVC%7OvS=n9a}7UiA$Qz%dCy`Pu?-KtP5VTS9@`SZiF$vW$(8^vY2yhz4p?k=cg
zG#&f0{Qam++74<`?a}#xoxSsvXA7WRkUYO6iWTNE_PO;2oZvfWrymO=3hO6aEpd6#
zGsP_5n1c5;R at Q~<Bh7#@`{){O;b29}><j#ilZKkw*JS!*Cme&mVWl6RE0>YJ7G}5F
zq}$2j>Zk94!W3eQe6I1LsN#Dm;IpLll@|lO(=CwXpwR3;9!NV-$DIxCdAuhog-fKG
zB6i>ulRHuWv^23|@5m=%>@y#v^ZOk8ygGJkBxo$^y5$fL4&YR`VJPYp7py1Qf#1pb
zm0m=Dbp-PQ-_4b->GwU_8}d_M3R<KIg!Oh2`a69ZNdr|tf4qcRg#~+0;h1gttZt&W
z*Y^`CfX7p7H*!Payd)uwz*qc1MpAM}I>jsp#kv>I!Y+nj3sfwuVI%@Zl;k$U3p~QU
z?{4VvB4oNf!{-`vA=h=H|M^TiT>UQ)!DWesl&g)Ka at hcFRzVig)~2et!Z{2hRo at 0_
z;=il$*wZ8FQ+$w%kzEX`u70BX)-I?&I+ZyCwo?8G%0aNulk~LCb3YWcjl&fuR;;Lg
zRXj6hoaYaGgn6-(u`ViHi1|`kg08y$J^78f2WT}@1=9dPx6?SMJky^Fei(#A!?lFX
zK*M{YxR{ZiPZz|pNc!$K#Y-xVsZM?zXW1u}Kbc!gD)Sx&+y(g{vF;2Y_Tv6u?uws6
z#Ezs9#*mzzM0oJ$i~-yrNiq^I6gH|M&5s85sW;H>i=Y^Z%TYj=tt9o>uJYtM%T7tX
z#hUKk^}$ZR#0^RVl}UXL!M at nJ5=jf}9A~E^T>E6q#a17`Pq$LXJwGHtSTvh2&+7f7
zB7`WD)i5S^nr%kB^N_#wwF8&PSy=?K^yIdJ(oX0)h<0W|`DzCXL&A+C*smZR-brpQ
z)KgrlQuKF4Z$J9!vibXiTfh at l{1V?yYzJA6&5o=o3#fcbnCDcN?EPEb0#}_Rc7!#(
zqB!24C)uTVMoRNTL-BTHGj;PQN|8yHUUsjnsS9Fzz-6<&G at a#Q<-$U*!7C=6EImbQ
z@@vQL>l1s>a?h_SPQo2~0+)#hD65C at 1E6NYPqcH%wcVv(q-_Vu3!VDnrrPWvSK4q%
zy8XOpD-!pe6IS%URrG3oW~^6EsGRs#$d(F}XOlU+d|pKTayBB3HMnZWwCsR86>I|M
zZHAo2LuNim%NJhRX<_Hp6c9m+KrdAp?9k_R`h7U()OqZi3^CdeZ4--<d%u7z4BTvS
z=<kF5LOzIlQ7;?jmz<U;5x at d}S<?_#5JC-tEsjgveWEoSUbf3*kxPW0&K0iG=2*e7
zM5>*$kE1WSP(kRfeN4w&UL at V?_lEVil+Xce>CX#$We4_?fr?JmZOx2{hFX7hS3V&3
zfzhcVD8@=$8W!;Flly9=&%RbjH~e%CD~RVab$--igf60n0?ZyAC!3?}t1<>GZMU1j
z8y`Tkf5#>B3TDYZ2xEn=>xxR$r*oQa7`^^aoxmE$Ug}v65X)}oy?bx`y5tP%ZAiYw
zG7SC@`FW at 89!O(vYXWqIpfdsmZUzKw^(+Xlw_rI7R5n#4adm^k_ZO5c_|M$^MvZ_R
znv&o;L_$a$j&OB7S{Dv+Md?f2jyAuFQnfsE9jC`6KyFs8N`cjd;~|f@;*>L?%NG{}
z81Oolu%c?}D)rfw5ql24N=SUVkES5^7P5MCi`sHsEFRuURfmZXk<t;H;Rce9T^Wjl
zM~7l>g+S)X-n{j7vK6$m5CGs{DADOO1&@CxWSdxF2voy31`xPJUC%8zKD%NV;FAX2
z;Ky%i*SdqYhrAIsdpFdU82muK?2!s%u7ElyfvkJFhIXJxv~{()R7^WaIaUt55>y1L
zoBqS8T-QI|q9Tj|*cQhPMSKeG6^On8D-sM8Wfs&7 at ZkeV6Xel0cqEucPp3Tt4z*;c
zBkS49vL~kh3_~~iz4OSJcX0~sbtIb4s+$(yP2DCuy_6gJq{ir)mI?XwH*CzRR=19N
zfF&XK`BUPZvth;^U!R|CcqdUnmK-<fj=rQgx6k9!#KIbd#ejbfAV^JFQ>pB}dEoy6
D^V29c
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-fedora.png b/src/wok/plugins/kimchi/ui/images/icon-fedora.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b9dd06d1f766a3285cd0fb587c0be4114bfac47
GIT binary patch
literal 4449
zcmaJ_c{J2t*#FKj_9goWk+p>ETQP%#7_w#Gml9b*CXBIV-zj9vQiQRDDBCEzWGAvU
zmPupzp|OPVj`RNep7-4I+~?lso^#K=_dK8H`8+rNzM&2y-DNre02uXj at 0gHv_=V6=
zk^8UePD5lx<*cuB2ROfIZ`#W<$rf5)T`PY8pl7=f5b!!5N;Xml=pnSJ7bv+InZ>uS
z*nKCP_&m%k1GIdeJaO|5AWs26>#3VlfSap8kVn8H0UbTWeOD<rY5=&@qjyKc3^}(|
z at I1g~s-O>MlqYGG5wxjnsL9DnNqZHp3obSjF;FgZ@?dg`!8B6HOH&x|y`n8p!H#~N
z7I?)J3(r+q%QCs96+s2QTIQ_RuQ?9L7%SeoYL8p^AUR;Yln1LGkM2GQ8P7ajZQD^%
zRaFl&I&42VTU<I at 2tgkPX~Z(|sRsNWE!O%!2c>LZ9-(BiTi@~KygD^NgjoPg*syLT
zIPm)xu9f2lYPAnfJPHIo%JZf0z2d9ACug-L_>96w43>woPc5T&T-6()-~=qdi4mC}
z%mV1^E+gqJclLt?KLa0hg0KGf)%8Z_Dvg}F2 at T+x>5QDg69Wj~euiBLoY6Pv!}+ve
zB$f?(uV`kXoF2}HLtqiuGq_vI?<Phh4RR4r><$2x8Io9+f0c0+C00;`fliI93`^e_
z<8D%3p;%AK&=`ESY+p3fV9$je?M{UhQgbGcZ^SoYCDm*3X;R at X12Clxy;P at wQjV5!
zJke|X%U7tpCMgixCk7l#OY>|5e)9BI{v`>2da%v1Txjbo4I9z4dQNM%&>kIG91!-$
z&+)|wfyGD})H1JNxXdAWco-=ly`SV^`?uXHU(t<Wtp}3D_4ArUU1$ix!Y8`-0AR$Z
z$@6YIpNTnqAQ04aoi)8>sv<l??TwbBS;B|x<W!DvQj)Cb#WpJmYhNa={6JZ^7sm-Z
zOZByxv0?i%)C6YM-R6E4Ey=nccp@(^5$yZPb6u|PjY)|DuH2|-aA8Qw<-lX3Rj|Dn
z8dN)XZ;SLm6GI($#2h8RY6cH6p|rV+0Wu`fRnz^om6eXiPhhx==cbp;s?*=4TvAd$
zp#AkI@{Y1 at g&S<F<NL2WzTS$G5i*IZx59~7q+~j}>-gb*XX?3JxskZV%TS<v*uei`
z94fgTYQVXdAT9$%bVo+jaB%?igJR!L?E1P8W5#j}2Eiw_K)FZ!Y0;uD_lVk&k+RqN
zxAv2xl2V;ZZY#cpx7oTLU2YTu+v`owR^(D6b0S1+5m*5z at -NAzh0sec1C{+rFWT*L
zf@)}w{xX1fY_z0qed6~NnSXL|{Tj&jl*y1o{i&){tFQHg!MT|q{-+&EBQY+xT$)}D
z%!t}-j)bgh&gm>R(OU5QkH|T;Df|1kdsYi5WA%ku)fNi(dK?s1a5X=b%Xa(qbCv4=
z+20c)KAnYP(qJJ64BIx({2mP6i(^ggJm664Dn_X^wC6<1MAbaQgM2>EE3EjBfp1fr
zdAtbC8&1G?pu4 at y@GphxDRF-P4x_KtyP(BjXH(@~&=Mm58uV344^D!AbBO~>ucE-5
zmcMyyrvL8zz|F#sF#hTK0*{eyXh&5pv1rSg at QfcLS@0JErlAu0u1PK8_BQK5l1Bf{
zvSJ}kiQ>@5Fc#WhOU-T-10|5$II;dLKoR8Mq#35?!NT9x2DT~G`@}Z0j9=nML5ga<
zj|SzT_2!16osFt*@eGPvSLdhXe{?oeG)$$C-zNN2#9EMl*}><tiOeyrF|G&p#AN`H
z+AqitXJw<zI~=#^q>!1bJyOANu(2>ieIG7hl$dIS=u-KHCC4})@jko7LkfVoXNF>e
zh}tb%Fne58L5NAMWfV&Y at x3M8jmbuEV7UG;+_Xs&JN!r at eB$iPpFN%Vzh$|q3Bhxp
zX at Sv}yl72*>1a6`iq?X#cLP$`wVHalOP?{<Z39RF+B3Bz*PDdtDmIKrJS~{96*yk_
zIBOs62>sCdZ)Ejz!ny?3Zs2O7yQ5;BiqE?8>`e2s7e{M at OI80EcJDKv@iE@}$0YH6
zytqdBy4B3w1<*_xBxbA$MIqbV?5jgTq$?;A>L2(I_4?oDNuk~^doKvr__j0F22^K~
zAeP<zJ7c$~R;t!^I2dDAs?V><)k8CcSvNc~QSD>SJlh#yGizH at eZb<4Mpm|pn?vhH
z6&0=?*;^<wHz8HT-XP)`SojghuxaFaYyybvLF&%)J|?N_3-V?eCFs2ZILR(_Y+VO%
zd5oPh)4)kCO at Xe8pg7^)H61$onBrIQshd<%(~*F at 2MLt0xyPg14BI!JrPJ(TN$Rbh
zL|I>8fRd`jLY`K`xY6jH(heOoX-{jUtfe{)+p`gq^41fyo^dPWK!=?wllzl#xrtzk
z at SwG^1od}*J&<jU=?#A`pKO>H*Ghs3lU*^r0JZct-t#eVoOVO6#^A-~3E`%Jk7HwH
zMq*~IL{I)9J4^m*W at f6eG<bso_S{s_2amZT1v)EB+qdq~=PI&-eK%H_m_28e4L)i@
z&d^!N3MDbhH#Xr;2sCJVP%mLS{@_`etT4g~5VZri_x{l*)Tf%d{{xkfrp*#~SU_gK
z<@w9|jD)1+Ie%Yyyz=|Lu8Ov|s$Doro+apCBW-08k-q$!p^CWj<OkSP37?P?h}Y_|
z2{{5WxYI{Emi0Ti;aX&qWEGL at mTN}s_Nal}zp<sE#x}6kz;@Kxq(VTNZXAuM991U7
zrGqcA!C+f_(T`=fS)7mbejJK;{Q-ysHMBz$8yFfem!hsScge$X%<jp**7*%fKUWI~
zsrvu;HXk;8+ at EWe+|3$#5XfWHzN=u at z9B}J&FZHq8JKj(WilF4r+jbVMostTwOih{
zr+ZcJ{CiGmA3>hG3vJ8w`F@|2-9FkG-t_r{h(g78Xf-8h_D*^wZ5#m}56z`#^OeO4
zUaYL<l97|5PlCvaD`=B~FukamZ{0a}QzDjsp}N6#LI+Gj8P~=gFJf2JMO2i!c6o1(
z|7L!P2Yxr}v6#Q@`{C}GTX{4=ij}+2h<ujtS$oZ~tXWIC*jo990qm-{n02hDW;!n9
z-%lo1uf@`7p|VZ2*B`8mkKI<TSL92C*v)$@ILSUfH%Jt04c$RI_NAphO0ATM10~bL
zvGyqO=RJdaJAsGV9y_$A_Bpj4ph<-x&+zz1un4WD4TeLrX25C#?DaB}J at Z`2Yks!U
zW6#Ae{YmSsn6|q~I<$&AU7bPxqW!TEZ1)<khqsl`Rj<7d*{xcfMT8hxHh_<c4iCnE
zu<*Ku@(WE`r=mwhzZ4+8y3rx1L*%amnNu2FKmI;Qjym%TBW-d%LzQCuc}iu{&8vd;
zV~IK=yb1Nvzf!1z2|=T4KjG+~8roynSx)$RD4>B=-wvSE3cj4l>i4J9<JUU}Mc>6F
zal<0Z-T at c7*nB#vI_n$-qOi6K5XASp>?<tv&*7pY<x&Kb;+9v*t}mDK?MP^%V6TvH
z$ytJ8c+z9gDpzV(&O`n5ztCSb?j>ql-6!YjLm%IHQ+v9SdXqLxpKoy=+ialsE3=yj
zis_}JuK>y at 7SEottnK83z)N29$xx%4=G))r+Bbdv%Dw#@XPlx+W;`|5L95xxrfssK
z at qUrRCvgG%54KbU>nX*6MZ+PZq3#@qjo=n&;;3n}+5#k<jl<`yf5V?rAanSA3z7PD
zsOs_iV!j_0*FpWcE3iR>AO$u8Vf?)TW7UM3?>!Xg+8l^Y6p8FKT%pNDPeI5jHFhup
z%|LcvU1!^J83oFSz}KwdU4rPbyBXcC3~edw_0xD_bdv~RTDa-CqJdU?ryICmWDd$%
z3ptP1)h(9}qzn&g6ayff at FeYk%cgy7>b2!I{$P05msDXlQj2Y(73n?lm#@4<zYoQO
z%DcI*jot~@N3eRPix1MRrRrMGJ$0ADbxz)XXlV}8r8CKce#_;67xrkT+l6sUN^X6E
zlful@)$h8|3pfDxp01ZgKHqmARHv2aMT}0c^+Q1O<?B|UKlB1MW%PB9AKau?L%JY)
zsWG01hj{R at 4a$Cm at c6u<5*!yBmEe9*Er$4}i$LT^ztYDK!J2VZ?XmtEz at aNnXNnJ^
zD_CD_)TchDAC#40QN2CzG*aNd{}KrO&HenK(4!4QOy+sb2;tcB1Pt^{v_i~HrE{hd
zPtFI3iMa~qVI9%B5?x|EA3bwVzgC1A7{owEY3X{8BD<p7tqZ*5GDVZ|2cGyFpC9T!
zkvltkovckmVR6(}_>K%v;a(0Ka_phRmsurnW_Bd%-^?8uGLjTB>RM&S7R@}FcuMG;
zCG*r_R}gnREkn~Zb2o%$@9T$QNDq5~Z0!9ZQUros*4WIf|LoAV at 5`sbsQY9Wb{#(9
zX}m{TA#>g}1Fj4fkg(v at FAKw~*-7T>SnectGsIWi?Re71sBTS?M$iO1r>bR(qg1oQ
zIqF`)d#e;Nd!$8!A%C4955&#O0gfhs$V at L*m3ANc1LH2G-kLCAE(bOJoaTs5Dl7!l
zP*;P4qb&C&v$B<Qq(4T>y~`?pnd7u#k?b|M_m*?u5HwT9^G5*(zO-Vji6OElsc26V
zmu{72tm&7V;`&c7Ye at 6r(;qI53Le{GoyjoB!+_;JtKFU-3m^C+Q2Xe&5Jc2M<@s{2
zRVCk+dYQCHJjactvJO%j=RoH?o;c~&Fq$-jtn)iG{@I!mdn-Ht6~`W^Fyx6GKgq3u
zbC~o=y;h8H#iQ5LF5}L>j#-u8n(1Q#(r2r<>b6blJi_yX7v~d~k3GXb&3Yd{4gk@@
zU&Sib?LXv6p_P-iO0@?nuYD9(pI6~H-Cnqf{I(y0Nk6Cb9Z6?ef&{g-K42|VLHlUL
z35FWMgW>WA4xJkVZ<lIphdW(}6d8^`T6Q<I33oLCb@;)+H)jb=p9P2O73#!mMQ`4=
z7Wv8-KiamZEs;s5E<&X$ou6_^vhYK~*7t+MLXxyMo9qnJVKAxJu$RK#i7rRua}Sey
z3%W#NqKR6L9N1HvC2r*!i>%W!mMevZ6DPM{ZVQaoC6Y76(p}2LlJ4HQZ)FiGlXHEH
zLG2X^dq080-G1t$-_6_q=@{8<P_t$j|Ngm0(C-X<LwTf>MhOf^NNT<C!faTEKfxNA
z at bTR_!&u%B&2X^osa=}y;k8hCR%P|_^7bZU!yjfIBr%y;w_AZDxP!B$2Tv at MrHmJ#
z;oIM_ZRj`KM8Ot0Y-8wnv<zk&fu#a58pSQ{OIkg`q_vF^<m&pY*~>W-5&|vorD_M&
zm3R{)%06zE*7v_<n|c91%ca6B;rF6r-2FP2o<-D&E$lN*uwWe`FxXEUx8Z`UB|G;e
ze_jsq58UFiZ92Lg_BU#xLMl6({quV at tWMF)?k_Qi|BmrZaTygNI6}Asfd2bj&EsKQ
zr597j)a~AntQtr&)@U0 at yta@#h+KtzS*tmgsiV*h(Qsg02~gyBp4yMKBu0WB`pK+R
z-GEw{8wQ$Rce#<EC(POycrd;=re&j}gg`vuRsIo2HAZ!t@^;Z(28a6ziB93_i9${y
zztLyJxAFTsNIYn{CfVqwwbJ?bASqcI6KS=o3{i5m(HibhOhKjSr4FjTIGG4#zW>Q(
zd^*!|I(p>f_(UYHu&s=+Y4hNxXyBoaJsRcVEDUkfRaK%lygyDcaEMNf7{zSc1|!W`
zcgZyJ?y~o?2KFg9Z4q2;n9)J5kXJX=mCWU2TIUty!n4DzO4I%>FbKN_^ZcleF;)6Q
znZ_Q$okNii$uBs4cGZ6lNqNadVD_oQc>W;>qxYrr?5OPu?Em>4xL8V;J3`mux>fJu
S9$oyI0D9VncWN{pBmW0TFKp8Q
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-gentoo.png b/src/wok/plugins/kimchi/ui/images/icon-gentoo.png
new file mode 100644
index 0000000000000000000000000000000000000000..50d928fbfa30560fe873cf3de438a8f0c10a8f96
GIT binary patch
literal 15307
zcmV;+J2b?JP)<h;3K|Lk000e1NJLTq004jh004jp1^@s6!#-il00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY4#NNd4#NS*Z>VGd000McNliru-3uHIHU<90ip~H4AOJ~3
zK~#9!?Y(!HWLJ6T|2gNz%ALEXyQgPHqfrJ4fh3R+AhPZC+K<Do?Z^IMOmYC5j7{*8
z!5F+?ytYXO2X?VY0)d1C5?}*X0%eUfGa60qo}P}CZanAw{;2An>guYV9!V1bo#(lI
zL*1&by6^YA`F)Qt#t5DmKexmFss9BA5Fmsw>$?33z^@qMr|^LoAq2)4zJKHPV!fvG
z8io+^QmuKC)@(Ie3;-p8Fh+=~6ymUuJS?TSUnzZyZCgitUsRs=;;ogRcToJ)0ATh=
znfvZK<iv@(FsP?*ier8=iX}=}Xd^K+HV|M0AVIA7r3gR at gC)VX44!AOEIy-2KGfe=
zc;w2fHl$!Z0f5uy%Qe~h_1E0_`dUrDGYqXvYHV9+8`C7Zv}~kwK!^tM5eRW~FN8!|
z&HF3~fQlpHC_w8JDZsWgj%5<xH#3%_|M-`Gb=x(@7+49RCjf9V3IFYH-tnUHg85hw
z*;|v;v6ZngSYRZ=vXRopvTTH~5W+%Q65qFQ9f4&D3<9kUNur4&O&lwX(M_cRgk|A4
zHqy38qlhT1Auu?W!L?P8$#9>W(XV*%FK)g2XIVs?P5>}M2)_BHTmQ0Bldp^uXDrbU
z#yB8sq~%~)F4A%-7F-6097;tC#}QbzKnl>hZ8Kn+$4Wtx8sgXx)KeB06RNcsgFy<g
zYzJvc(j+2{L!{8Sj=^{Jo=jH!!!P{urVsrr>I<g at 0E7_c+ArSn)_P#QEr^_~G9KU{
zEC<W-a2%iEVV{u=4!u1R*M(GpRx63E^-+Rr4a%%MU)qdmY$}CnEu~UPD3?RDHb_fi
zSr*1<(j)|}aBNM+H<6#=V<QvJJD+;dhTvxf2&WVP4Z{D|Z-$}xw_4!33Lk`vB|U7{
zr&P)@G2yXkv&69>O*<1)H3_d;uj`}Nbr%pUAJf<`EW}hQ3H5pm7%baHU`W#ljKY?R
zY}SzR#e4floWH*8(vfnKXkpvp2>`5j#8HChyXLyD{BT<sitDO1=gd_57~x~t9<G;T
zpg+gi=Xh+~2uX63Sgk}`p5+>hI?4f-LD0NrRD%<A1VJ13(7N#*!%#Cj7ZTKCwAM(=
zLI_Z41V-anid at FvXT@uWHu#@->Qe_orL>SzJOO}Xji20pk38^5<=yqV{njw?(PWU8
zhv(-hl?puNVwVjYFc`!Vt8OR!(yVV40j;yW{WWclo~tfgpj~&Mxu2d62!aHqQiPNU
z2`Y(^LStK+Le7xM$zR*NIe+c8vkU480IV^-`lXu+Ci3 at H1FxiX1|u`LUY0_k#05{v
zuyre at i?>g#B3A3HS1Yfpc7nIu+YW?oAZX<}#=!J+NDxFQt+0duDNt#I6b8 at M6be)d
zz0O6KUq0~2Pm at SE;Q-KDV_BB@`qkfkU9IN*O%(fRkwMxSa`_%MY$$Ts(}l6u<CJa!
zVFkhUN)RlGge4HHxURc!4%0=UY*j3q|95saAPgI#LCA(j5}jaK2G3EHO5)xZ|I+A_
ze_E8p6AFOYBMS at +^_pw`-}in{t9e(%I*S$=JU35I?*LD`#9?>@bKD<n5bcCt0Rq)R
zaMeL1w7;*Lve+hmOjBWuW6kVrog`Hltq{^e>jWuGLs9f~+|z5l<GC*w`B1f*id at e6
z`2)bdM-GX5?zyiRSN*$dfj^O&EXWMGd at rM;Jv{9aX?*`NIu3LL2<;$f1wyMBP`ZO?
z=%7e;wHTUar7?};AV`^?570(8olIa%iY*MTqbTIrIWXk@;$_bm*mb&cgcBAGy!Xf3
z&y7O=mRgX_DUm^1If^|4oOM>7^DlT5v%V90CB|xcewAu9FOQxJv5I?ibnq%b>Z32W
zZkXn=ZiE<&24NtRvGLpji{*%VJwh9e5Dv;H!dQ|n>TOXJ at BGg7Q|}W(y#2KFx;~y?
z${2$X!hGXP-?=0V+}rA57A3OSPJzC at A<lo2$L7tC5AnO{2CZ8=S6Jo*s<ZCUNm=a1
z1(xokDJG&=vrrCDu|gTu2vHk_B at M2vDHhpZ>~*es<}>>rKAlX)#|;3+7^IZuYgd2!
z;y84FT#s at nlfm&y3=R(Rl#5-4hED+T+eE?&J)n)~t=CL*uT&S)vCY at 8%>MOiAS_u5
z7+5Gr1VN0^8bd=gSORRR$YnK!qV=-py>RHCYPD2kv)0cJ0E7_c>sNp0$x-0k9mF|O
zGPrJ$p^*_Txzwho=fo1flU|@y!`-Xe6-3otKWNnlRydWGh)<g%$sAP<k6H_c`T06Z
zYqU}rG*TF(G<a4 at Z?C*#cr0`Ilb>8je`Wx1-B)kAAgnp})WR%^EVf%<c*6!RyVRyw
zIyuBYYI`D<h~5f-t{`Z$9+pKxo29Vq7w8ahY6Za3d8HB&h6&nev{ncVmNeLwqL4GD
zXTW*NGoRUa,}e5 at Z(DOb7fYv0`%2i86H$VZdKvU3a%k8sH)r-1m4Uu7%_mets#
z1(pQaVH54wMDw~h`g+svgA|S9<xRGow{Ac_ at 6l7rB89}VY(SD~L85FHE0&l(l-%{*
zn`S;IgfK~>fBHCpQX1Q~%-6nf^FpPTDJfF`nPF&ToJ%itO<(^h=5Gd(rfoC6Im?%>
z>ki^!`C11TvT2JQn6?OGyKX>Jl$0w0X`+_7fs|kgjb|&0MIIhI%Q=5TZ$9oHaDI9?
zfNfjm+N*EAvsQCU+GIg^^bd at 1;f1FG at c{&8i3==kOEZ3%JIIwYe#Pu>;Q}i-0G&Ak
zOQvJXebD%fQZYj|>mh{1k~Ufkl$L~v&HSR+y7z&2=DvFuE?aMM>uCXi>%V&QKL&OC
zB4x4|;ZrE}bLO at z8%9qfJGUtgWDDV2iM{65B&6ghAi5H}g9vB`LdJI}6|zX#%sD`!
zj3iEN7AsbMao+sbcWylV>XQkAM+E>Ogt_sX-+ywwDqa<<42BGzUu5G%FK3@~3S|DV
zzOU8f1T7%ws1JzMx<RX~Z`U1`a!^GlPSASZvbP;cPbrIS*+|()XVXTIYMV;kVsSxy
z{Ko4KfA(a7;J9^wG*$fQ`?qB(b78Gq&5)Wr(k?JIKE`Fwu*qajKL9N01FbrMN*h^4
zY1-XVXx9tY+B!LkTCIcD(6*tmuht at xIBA5RjY0^pq{g*VN<HQg$4}3{>N%qUConnn
zxH*91*e0k&pQ;BA+IR at zQR?Yu+qTn__`2a25ZZvWFpi7yGniZfQ|iI=4`52Y;JQaS
zL#qz3N*@sG-=thA3YL7!ONaTaM<(kdg+NFfV;Xuvl-SJA%Pn!;t>5tN14D4)p6hXO
z0HrkFz3~T^))v$)^)QbjkLUHW?VJ%Vy7=@Vev%++HAoY%ZE(HDj0*yY!p5=VKqd>>
zEZFwZ at 17)x>BA7m>+=tEOffS at Q_Wg~N3EOyjvlAVP^s3NRzt(TETzGg38ex^KY8+V
zpEG=)<H%FX0c_hcX{f#!B`z8dAwBx~``CKs=|OmvA`Tx$OihCCL;nD#rx%mWVsbf*
z$U`Whs$r%M`={WcU9fW}V)`&bD}>`<#>O!dn=qc&BKwzgfi8+4on$^O=d9KfmRNyh
z35reSP>6<tp|v2 at 4vQ5*T66BX`Fm5paY{Kr9L0R^+dq0)P%)pXM|m`P{OkZ1TrkMl
z=bif5A4iD&2f%Y-Y#h at X1-#>K#E<Vh%#rCC3VDZO-owviDHc5jhYPqFflwd~^b}yj
z2-t4pHw6Lg-E%Y}Nv($qw0H|wae)^9z$(2!L$w~FlxifJ7=x6$kz<h2Wb^7RFL>d|
zhqTs02yt=&AcQd2efg%TTGbtnbrB=;jE-*PvS&DCbEg&n#=t`lA+&;X&u7ICx_dj~
z>aW~KrBcSVHJOadV!2Eqo1q>Al!`^hh6fni*vHUF54HoAg5d!eY9^~_4SOCzgyAtj
zU{(i<+8soll))8%0BW^}G)<ciRX5Ao6ggj$DX4e9 at P)(wD~^?TJVe5}@&RhqI^VqJ
z+b>t47}j`zjqCah4V`-80~|Vtn4N*GTUV;f`zPT){&PRo>H_(!<h*UeNU5k+Ep%#O
z$Z+sTg`eDWKfCw!ko6qSJZlpZTLw`_Y|3TC<})z14QFh{?Ae2;R+^$fbr1!nQI@!D
z`-`IhU2)FQJcDHri=)?aIgfe(Nun at DqKyF!wGe>6yy07irR!Snh at w=uu65#dfP5im
zY+=16O>K;^K{^x*J&cW?7Fs at 2hoM@7$-_reyS0W-er~5wNu4vsi)`E6gI0CosEj2O
zq^KZ>I6QTTfdP*&nnw^ZH8sf>ufB=<cOGQ14i9ce#8KljH*dydvmIgrZ4Mw>0nlmz
zw21!ptdkY at 1KEs+>)6Y6j at n3+wyB2}Va<B`4c|Ka0nf9IQu at RL;M0Hq&v}({rZx^n
zG)lBeJy{B+Q$PE)Zpi5{gaiBG2R}gU+mDzn8zDtNJ}>b-O&l$vk_t(*ND?ie)FQT3
z;o|dq at kE*Px0OhAh4TCYy*a at hw>-cj`;QPN at Zf`um;%6-Eg05e0<z>PX0>Oq)f8;S
zhF~S9$Yxwz$7w2u0%HWJu^J$#+kbxJ4Tt}?ZCmDq17O334WBexg0MkYIF3tCPs6iz
zn%MfJsUnUw^Yd{3eelqIf-|;kK&2sZP(>#}qY7BY=(LPcRnlkyla?u!B)fO)VB>HG
zDa*_)Ea1BVKlt7c33Wmc!mb at n+DJI#jE0ig&GWZJ>=jl(3$<k at 4$#3*V1R7K!LjXS
z>%bUEsx9iFB&^x5z2Sz#fBRVc1ji)d?LWF*danD6##jj9AT1l$^C=cNEsCd?%rs*R
zN@<cr6UUl*4bIv;NEpQk5faqqsMjW`*QPLP4wEjBMl+=G3=Rtv3W_6Bd)Uw~fEuo?
zIcwVxxBcKJ2nS|o6OJ5i{Nil(XiR})iGnt<Aev8o6$cQj#lsQ^G8qS_MI0E8f*`8f
zuld#ulkYw;05A|G%0kGzv>j~Q!j`h(xjIeK8!fBh=n+DYDov^sNur3Nl(43`{PL$_
z+bKe%O(%=Os05=UAVv}sh4bY6gs?tO5|=q^OP0gaQ#`z54}16TWBc}pFr at 5#L}40z
zCfKyO$pu&g2&}$N8^>q`$qJyf>ITg~l5JTHPJn1~0-GR|sL+4Mb>BMpKORl|Kprcc
zTA!cWBrL~rTo2o|acqgvDYe>(bWk4O7#Rk~wJ^q at wI)q9ahwtcF(xsDp~i6}X`&Fc
zsM{D2reS7 at 1dD(l-?I~)ED{C_<T9F}fdX5$odG7LyjW*`wke<6l|fds^iE2l=%ygH
zDTAv30c5i-mL-=#pp78WHuX>-)9e?%dHsRo4kycF*#1;&)hkjY!m;pt2iLVQMlm;M
zh@#V at gU0wcrch|;BuXjLrYHzPMQt%6NhOx!5Jhq0iMRS=G0kh5dYp2>)*^?eXUX`A
zAXsE_axa(&twNHd&g>D>8fsoG`#Z?}_Rw%^h`5s|Xcq&m;vtuHu`IEI6C}!_T9-H`
zd&~7V9^AGtZyrA#AgtGOcieIhF*Z)t!_7Llj$vWG!v4KYu6l}xl(2Cea(NFh7-LAa
zA&L!)i!tY&dl3r at bsWb*iUu1MLeS_V(g3>B3eOj$N}$3TLWkH^%s|Ouadr}w1gJEj
zTuD|deWEiEIuUS{;@8FvR@~pgL<GoXJY*9D#s~}+sghJ`5?g2PxbcS%WR||?V|D}u
zLHOY0)I8Rm_jB15S0S7f&yqwz!h!t}8Q&A56DwV>r(&FWCT4CP5k(&LdWbQm5dew|
zLS)&p<wEYi at 8)WyJom8Ym<7+by<EoWvn)Ao+cGPKz;i6-=NCwYjYZ1h;v!D$kn>WK
zI;5#X9IF)yXeaY;iI~!WZaRn%O$U%^QSoUx7A==di^E8?IgXmoIpetmVchgWHbR|g
z3bh)=f#T?Yl#1 at t*5l>1*LJZQ at wrcY_J@L$1N-+7-t=vxo#O>Bd_I<?h=PEJAC_q2
zi17)GIK^h+MHfO8+DuM)1VMn-rtyFRjqi@}yyw5--e+8yd7kfxp!I#f^V at ISIy{j5
zaDT6VRk=D_3bl*SHobYxS?6uQBoR at d2$RN)Tk`I~Y9oHxgj;G<rdx>E^b{^joi>Gg
zX{NUld<g_Bc^R8~+ZOnqO&FzU-T1Gm0g*sZ=c(VhdFFFMh~GaJ2#y&GxcXneVBLHF
zBa70?WUKW8sjxX?%NbnujLR^wA_^47IE;^ZY}tA=h;ph%5WpRGAf~5ND%EO3RvLvA
z;MkgcR*)~*e^M+tpSt+sOxhmrc*P(5#UIzB=<kF<^cQ at 7`B#65@|;JIWI*J&@S+LM
zf3h%91dr@)B$>2#Cs`37VrAm!T8Sd9A!5 at 4fK~gJ;~+{&6Wyp*7GMd5V=D?dO={IH
z{KXfI-TRn>L2rHIyT4xx^p%d?!$L(eIzB*}W_i&szZl<kN$N34Vki|eY(4|}22L#q
z(iHBz6EQVqm|v(Y^I5GEEWmLzzDJtNTR+lL{ppKeICOXWXZ-GOzvlK!o_fX8#x`6)
zJ+jcoqo;R>=RQA2p at 7-BqfvX%UQE(4Lb#qRp?1QrgZN9w<yxbSO5;9-V<|jGQ!Ei>
zOR9Lu#XU*4QnYme;BVglk+DNl)%{88GB7wyoLG!*9OHrQlbnCy#cbO)LEg_1)nbIO
z7#VSx*aY4w%n&jL4je%2*a7nk3H5r===mcc2?GoYOM+t?EU9DLGG*H)5a={X5-&}3
zU!3A6X~P4W&-e1wOY&^l0+WZJR_l-`(y0ZF>9B8Fpt=J9mc>gO2$pwk#D~V`RBLhb
zGa4ae$5LcGO`+F(_u0?td2Tm4uL}S|2=gbe`t$vspBt~#HNM}=hT&nN1S&O&kv?0u
zO>p_spG;Uzi6f2gIgE`7Mn=JQP8|^97<TVQ?B5TSYDy5q2q~}}8>19S9HNpKV-z&H
z3pO8W<4Ie#$KX&eXP at OTz7ZDY8^mudM(vs_*ji5BDKm(+<4z!G;{vTfXbmU^p(ak!
z<ri(Ka2-uPr}6UY;w!J{z3VaM1HAS1fB6qnGxb-+8idG`q&B&Ho=m1dF5g2GSqR7D
z>Cd>3GdGVCRTU~RWV06I<AQ-9u<TO at geZckDa3&TP%dkNK#?fjGz1$@+h~JI8|>7v
zE%F7I;bE5z8z7T`FgV(&tUY<OQ?m)v-fg5qjzGu6kWL_2OAIv6D>a2u4Io>>VA~4c
zH57Zz{Ii}_?CV79bpznfU;n{Oy}nRes79Q7&IE-*fx|P3!$%@4D?_nRL<-4#EoF3U
zf at eJAB6^EC;+i5&p^%e|jS2b(FqXq99n~sgZVt+2s8kzyf@#{2p|%YfUr;DOq0k__
zU?t((%gj}W-bJRpccJN=8PqXDs6`K0#roT3ek%~-*bqjI>LW>`1+HsraygBgO<wt|
zEBijxPVeK&2ztY-|KjsAbG6^uG%-RpE6HWEI9{HGs>{Kt8o6vgy`?<$Bn9CyGCayz
z=WU^w$q)w`l|Vix86AcGL5zKhfzbN%lBAIyu64u1x71#yy|k<o at s~=?+u8rBV$xP6
zusuVlP5En|{jHA6b{(MABCXamsctk(kWyjWnv8467Si&wpIs`o(|g^PyVhD{yq-VF
zXFX=-YD`a8IdE`}IIL65M4W$SmXRUN)a(={Rd_;E4;Ogoz8&0g$NeZL#V<;N#IR$R
z=B_&thxQ|q__S~*8^^);ej`0xwr29Q*!ipC`g9KXESHZR<Mp+ohil%uMh=4ON-Vk5
zFk6C=Xe~iG#T#y(e8r;{0ZR|+ZEt+{uT4#tzdSNHfJ&<Dn~r$e#iRIM5h+~|4o0}_
zJ`j at 277*IT&u8c@^#eBNJZUQ#&qYOsG%`4jWMl+JHh|}!;_y<lm{jYdEPqvTX%{hI
z%xW%R*61%p7Zb3X^4Codpe-h+6$Bwozd*wxaBV}z*Vvipj%Q!lb4e at Bj|%`xT|oZ$
z<!^b1u>E)Ed<$V>GWiViwV2Ht25{^gwwFN&7o`Q0vnkTfVhIN+Yzp}zem2LJGdI%P
zmq!JVMg~g?`UhZa6taa=1cYYwkW!7RA=L(guDt}-vI5p=26CJZAl3ju7`7^s4FLGQ
z!po*S^NO5!)BtG42FPYJ<`uvHroTbhuX9{YZy`%hDMK}gNVP#~hiooSZ~q9=a!3+b
ztZ8Nz6Z(7lK?|gCDD{;XpBQCq;{a&@Ndyu at Z;xPf42nG`83-)^=(@Fb7i&3Rv*D!a
zP#{7VMeuk5&;bN#dQ^NV1-1pgr}1-!#qxodz32s-KKrNv&<cWAzU(cponNf}?}33L
zLp?cqOF1f)8c~v<jbw45PH$fy{evUq^L?Zm7Ai5*a}kAnFTUfE#L&}MWOU;Owrm|m
z#}J1gwV_xNjEzE1Z*wt_Qw)H0bAWd3->kL-+HL=10ic`x-wpzROs-KMk;}v6!G<ry
z_rcFW7#z9z%4ZHdf5|iWm>NU~A<QdY`sQC)tku6UJk&4y3NE><N4*xHQ$;qPVScg3
z!hDrtsh7TiVS0N9u^o>ib9Ls*DVF7t_X}t($>g$ZI%AxPO`}L5Na~Gr=u#61rQSwb
z+=&LjvJS8$3Oe-^I*vw at -O9r{)&{f#z^wFcE(L^E0isDo--A*K`UhZW5VLo0qtwkv
zuxv=<#a)*_qqJ>VKYgq{f({=k^YM at TUC-Wwv)}ey`>B0JmqIo}oWvxFCZF at k<$Mkw
zS)f{tv2B<Bff0K82gzh|lxr!64p(vP3|YT`C2btnXUmxrjE)cC*fvS6 at ymOAV0;1!
z#S;Vqv$D(B3fsRG2xfKT$rXhntsTX>5q`Zffc1!gmiLa0!{8wF^)+sroJ1U)1YFRm
zAt=ure9p6n#+T^+xHO46bnq}^<0Iw|Ui#+OXrunB;LD6HG=)+gZ6Hkr#hgn%pJ8sH
z#==4!gH1kPWO!sFekMnv1iSXklF63H`Z+9NlgSm>Fh0WA#z9=^5Z4U?!Pc!XyrDBE
zJkbC+o>sFRBY|xSAnkF0E*`*k=TC=2dVArFGoa9-L{HBm4jl$<L2aha%;e64zxJCK
zJ-z^F7Yi?Y>07>+&x&VN7G}iI&>-1D2CW74dO}a$BVWi6Mw*$~GEoGcmtk~#Gnq^d
zBWxbpeS}hR2-~)?Etj62e)7c}ThH2vNG<AR#WSw3 at ck1DfQ~vqn-ZuytT|wgLjgP<
z?SC!VFC|>`6v*dS-m-rhF*64<(=loF2$lH*2mj~qK7APgk9(`w<_BN(rq{l^=;a3Q
zs0H;igRsuvU_XVTO%Nw6P6p&M4jV^%NHrXpsj_?L{dj(c(Xq{(b4DKq#jd?`6pQ^#
zA2~=67pa%4_;!Yko5t~d>y(&^t8)H3<n}F<hne;y53 at 1@NF0lWwaR<3GFxbw_RatG
zl&3(htxQiFDA%AiZ<w1|U~zUDPn6ALaReRL*!kci{N2Ytw^^z5mSRp1S(YH1%MztY
zvonXrvnBogy(ndvnX9t65R%L18Q*vYo}VL1G``b|@0Ktk%iz!`&wo*NeeLBRgB8$G
z_P6- at mFnIfU|q$bU0lCwg?&wzu=jcA9hLd5V{!qp>wd-lLkrw{?_E^ON4WIK#r^-^
z%YJEMiS8%VxY~Bk7C!cW-nHldeB%AXmB4*crDp9>sm3;fjBDX}g47r$r)Qa)Utq95
z%a$$u7#;G!eRrbM8e;=vWV{|U8F~kXdEN_75b=*G+E%83wb%Qtn6+)LUDn~wmF;~8
zTbfjf)_#U9Jqt0gX;Ww7M=4_WgNj|d5ApCL2biCq!*vqswQ$9~C*@H#(RRNOV#}*u
z{<cdCdHbWiMf({U$3j_}R4bBHbNI*tj%_hCnB%Oo&Ze*DOlqNvHa`7>!#w{51>?9U
zFQKHX3}_Pv%Q=4?DumlBgS)YL(}nG~R}n9X6Jua>6gF<`tQOq=0PNa*gq at E}GIMx8
zmIxW>vso-xLeui&PU>7T#)!Rp58l3c^Z4a2`Moz?JUU!>S1x1!x18^gq$!C~#A!-4
zKSFQMIn+W2WqgK)hI#Jui^lU$JkgC=hfEfoaj_!Nca3{n3AL;e98F7T#BfZLJ)4FN
zzar{qU|;~YoY7f@*s%+7$L;&L^WOXLT#NJ09$?3g9ptmUR2PDql+wa#7IvO=X1Zz9
z7{(ZJ<jCBeLqq+){5!w-+Og5G(%<!!ykE_ at HWTCLQpj(k-X#9W=m=L`l{c<;QeDCw
zxj>8lwjvvN1qWzX_*fmXUGaG>C=g<0*6<20(DL3=sgVZX>8n4o4{`I&ySe-R2PqbO
zCN{V{v~w3i*Gba?N}11EEmggz&BBrAZF`>e`q%yG;bLK9f0%d}<1w~z1JAzdB*}b(
zXkB8atGTC-y~vbqi~8wq?%qdX?qzdu?zx?bf8Y?}x^L~}CwD(UU$4)m4OtFNPxHvG
z?VPc31Hujtyz^bJ+Sp2So6}$z6N&4ux%ak8S at wsCj}ac5w~TY;v)z+gaALa5)b-kj
z%cftG3rMqi2AfWz;~3`N(v6u6oYRH)lhcTA-+X{O?|p!gp)7+v4m);DGCjSA4gE!I
z&m|1Y|NN*kf==Y@|K^wPm?>B6{zSPTGn{qy1eZQtp4 at 7qHYZRgkKgeoe$ohK9MkF3
z&CAz1as at cE%d&b?(}?T7wU0aQdVnn(dr5;ucI`Pttv<_!{tP2S15C|KS3dgD*A(07
zeJVMC`Pwx<=>Pf`@7TXsb~1 at _v79^?J!O>hpCrx6=R(KO{yPYB(Wb$-%l}Tgz$)#3
zN#?g{`K_a;2PP&u6aVlu;+n7T=H3T(aKTx_?A at PH^~nGL8%#+=K~%GsAPK3}ry1$b
zGT4`6c5ab0uK(_1N(z0vXZ>|wyY;zoXn&_xcSNFHT(8J8E+1j at 7IE@Dd~NFyu37EV
zVL|FOJArkP`R!oq=HwX~g5fSp?Hrs$eC2BovupQm&OLLG2OoSGFAG`+q~Rh1J$dT2
z8gXi_{_x+t`hRw!wLH1A%ruFA+Z&>~eN(mOibQ#2bNxK`c^gg*@!L$mV{rn}%|XQa
za`$9=E7`Vo^s=S5(AXHJ8}aw-M_m2oUF_Sxk8PX#xc`Bj6nkwZHuhqhkWJ&m#9^I8
z8HW13mrfo!(s82OCzJS6N^{*cw|}Nywf-Os9a21c`-gbWb4n*a`=^y|ZS4YDO|w?n
z-OczHq75|d9l at 50JY`#az_ciPEgr_Dux_c;`3pa|(}*u$^8j&NX2Vd9?GHW7=va=S
zfgDE;A7bO!0CUqvh at yy0#y;y!Z+&^an_hd;M8FrW`Kl<1jki|I*3-ho#R#9_kzt<m
z+&rFl3X?&X)+JWm3p`h``Y!7WubcI+q3j6(;~OEH?O+KSxa*!&eCexqQtEL at qbgI=
zhZx(CqrW#pr96vcL1kf)xw$fyE8hIU554xU*D`8O1^~=;-?+6`r1pVw*~-SLi;+H?
zHjnbGXZxqTuR!ZEw5=d8W_<uyI$t7??xgK^5i9K!ma@@{u#?{-Rq&%*Lh<!)+`*aK
zMmVr<KXJUk&_I at +qDvIalO!?qN`=Z|Kq}L(eE1`8`1ND8l|9iSz+8XrZJS8!Jqs0!
zRQU+Y=bUrLx#Uv&)OQ$aI)7Ho*ki>4Sjnna9k=`NMcaE?DBnsJ+lI|sI`f4nMttX{
zGB<tyE-t+A3?6u32N^G9sJ}?YH$?RrqA((gB7$l}V$}CP@{u?E`eSYo at mR<8*WUJQ
z6<Ob_RBaONW7!!le(E^qo-a?2_EM&Ec5ZvE{(3>M%E{j$P|ztbl*z(|4V{U<P)2<1
z>yzB~;BL-6XPgHg+(|wYFf>rW5)rk^G;y4O5`@)&Sfx8Z^3m5nXT6;LgaAMYVQ%=w
zZLf~%*2n9CL#jO-FVE$dkFx0$YWnT7pDwa{6)BDZf+etY<FulSeUE{G!A66tZf4%q
zU*5stnHhR}JoX<vKwnAG*Hc93h}oF~s5D06Q>#^pm0B3tlsPX9<8=$x#}xotYb?t$
zH+=K9zpgFHH#S1K9+_;3XFh9~4Wp;eq7vQGvX@=Lrn_Ihb>=TSbvl8d&G#$Xh(9vc
zSd*aB*!~dWi(k2$`NhNJvssJ at 819o~Gae=hIC6MDQC!EdvIJ2LrB&=?%=qj6>{aS`
zp2On?fG~*2WPS6kYj6L@>VkY#5H*&R$rbx})|CSc4xdKL$uyficFM^=mUE_){lB7@
zPX|ALdpzH^V0fglkku+>FNGi8S{K(|cNbwaM<HLNr`MvC6G%dIROiU_LBhC(#3zXp
zluoNy@!-4P^Tz0SAI0MWfNCY6P|TWdef_piR~N<0!q`C>k7CaNS6<mi|KRCGe4{&8
z=XR3)W*y&Lh?VADtFk9sroI9E3=DR89+fKM`WvVD-hbYMlp)1pp0N?1tPgRxK$6s%
zn>kFXLeMTCNOg4N;rRm_KL3diJ*tL%_Tw at 03&pIt{%g1WOLbBHUJ$z&e0qBOdFGXU
zr at UWKH+O!gx;)xgKkFp^GVAZA{57wYicl<e59MBS?Ze!^{b6h;C7<&+W1 at sDBdV1d
zOd7H{H-{#{wX>+ykg90^dp`JQ6Z3P6kJ^}iOaRbYH`)GeU#c#MUk?)pgHN${fM;IW
zd- at SyH=I7J8a2>a6dWTt=%_bObf*2Xejs3IxHHRF3hsSCi?3dL7t_--*tTL~yqErx
zi_ul8<#}`xQeIrd2t^@ZA`TS^)&1}Kz at JVWIWi}DdW)PA09ck~Zv5tL*Ouq`Z;d1l
zpF*jRD=t5MiLbj<<#tWb=r-$H+5H-Mf40+|<<|rF(XEmA#<y-qsSvHJJmtc3uuPpO
zEE7i+(x^_YT1QAI6?;g+lrXODc;|axb9PV<g`atBsZx*06ZoC$Z~szdo?oj+9tNLm
zzL%#zeUQ<Or!Vo_OSM;I?C8!FJDqCxkEJ6R1H}?1m+Soc{zHgw-FSdI at 7{@!DSf>b
zTQ?7(lL}hJ)a&!a)e2#h0E%KMi%wy&JoCffc*%di^89UE9v_qa(EvaQVQ#$s*8f$T
z=biP)LmLl2)5}vX9_EZQPkqPGc0WJ5nV8X`PJh*=yO at Y{-**}V0~o85OIIWAx=ZoZ
zYwu)!p+XSO^R%aICFdKGxPm1V)ygajb92oVO=Eg{vsl7reqrX5 at BYB+U-fvp?~fY*
zLI`u?b+=p<R=K%WcS*I6;}$vZ{87$5Pn_~jq3y))R-B>N=+(DM7g#6ZjcJr&m%2nY
z=NAz-+&IY(ZrzDeF|L<z;dvV|X$?byG%=O(4AWCHC<Sp`rLQ-K=Xq4B<=4LF18?})
z;~l#>E*+p!4!G%t|2i|Ob8`?lDD5Jx44XC$vw8DrLj0zOZ<&?rmb9#6wP<Pg0hnWZ
z|5`_>r_pC<l>{>I at FR#XedS*E95{kj0h>4VFflqp999rQg9 at 3MndHdy0vJK9Hb-x7
z79j=Y%Hn^2?+4#_?THB7ts4Mg5b?uXe`JX$cWbR8NwovAk+Z*PvrVCR8qNA9;g>8r
z)1f-I{d|Ro(5%l2Tmph^H;6Agh`wqKam#HruD$-p)aoI=uejhz8}Xf#II18>&`FKS
zLkF2(2(YA}TAQI*@Nr!ys at JPeegB8va{q~n+OAt#XR^Mr;_R1#3Vn%oFu3INJ&bS6
z(AU>Yg4E3x{N^Nf{#yEfx+SdJVG+mn(rn$0)wlZq%u0f{|FCQhdiz!rUz<jb{ujS|
zkbl4Chg7Ny3=cb8`jiP=E5N7-qv|Bl9FIJ*m-)pA&$Wr81&Re9-}m;_YxUCm{_4#S
zoXC*<x;enL*L?T4lZao5m4h)Zj+0 at -Xdi=vAgx9mU6`Y3Pl(3qEKOVZaWCU;b-|ir
zHC|k+CCjn;@pf<k2pX~bzP`>-uSbZx at 78?#yZ5kX-z1Kea>->|@kBxzSHZ+2X_X|Z
zv1jirMjP^3mnd8yoAt0AdB?lo|N2WRmD&lPNb3TC5W?K>^&ftsT9qi{f^;eM^wHZZ
z$YdMcv|0-r&FTe}1zqgquHfj#Mb>Dq-ifelDt5=ynso&?TwRL2^!`2j5qI6S$ajBq
z7nQ|DHjeeMb;|%rR6$#y(h8W6YPrn5{bd{*iUpTAu3=jeZPLGe?+4!eXD2IDYh6~r
zb=Q9XS`)gzRF6DTmBsN2Ol%rs>zS~$!gjaB$BxyqodPOdT(%s;1Y65aH(j!G*42-%
z!?~0VcHilHR|CX-_Zt4=hxf2+?_qQjaLLmevtE;;bx0aju<e8c2j-cXsglh)WPHFR
zD3uTf_2+*0qi_4JG3Iew9QrW<K&6TsZ at N|5v54wb%L>yB8lRrt5hf-IjE%RIHnYaE
z>TLixp5M2M=<P)7)@5U@>ua(7HYIS$snaQRYe4LL81B1&jyvw&#i2t}Y}-1-*l+=r
z)Dc3FBsI_hQp7y4eTtwSQ7m~_BEfMi;;0^{X|nkvAA9 at c$xhQ>697U8^OdW=bxp>~
z|4Kc~kf;ononvr#jI+<SaNVP<U#@fQyjDN at v4GIcEL$=Ap>t#9E;)I}(|OaF28YWR
zI&1hd^N1ZgQht2bZtj0 at ACiP8UoeUzQiM>AS)bIgWX$4Xne7iwVo5>P7g$z`@419g
z__ch&|Mhph=XIxK`K_)xK$<GP at XufAEfq_@QZEZIR%6*%*T?rQtft~8m;B+f%Nn`e
zW`A2sb$ebNqC=~+#_Dc}hLwkCmR>DKV)W7Tc0#wa{8gapVB!@^7`H<|f+$7o+-cac
zbAj7`vYo at zb8Oo>z}Rq}I1WIhq-h<aB5WD6W9NSM?wh5M^KdNH{CtO6z4p3~{oOl0
zTCWGEEH$<(0363QSAYKNmzxxfmKb3pu&^DMY_>^!K*^&kWOZcyodD1lDO)kk#Txp+
z(#qh?KSp#>;PlZ%jP<r!Z~aGpc6GC*rS~10LOk?f%>57U=AQd at QY`vhaoJ`}8W2TQ
z1QA-r2on)TW$yUNLsTm<eWg6E8)G{HgPgC|t1teCPrmoIQ(c?6rWN3M&WE%~5yC?V
zi4-=Lw8`b0?NM7-#p==xdrdB2IyhF$+M=MNOSThh*Xx+=Z6anZht6UR@!)pNp1rf&
ze#gDk!hk1Tu#rMm5JeSS+n~}AL<*+P<m4p(b;|?fvv~#w3OIISmCYoPcl`Z7UU126
zw{DSt|B3gU`qKPv2z<{Q-j;d#^Iud$Wr#zMIQ22YCztQ%yeH)vHh(+YmtEG(T|)sp
zUS-#GAY9j4JF~`nR<nED4zBD-A$ILFJn~45oe%G4 at 7{g%_2<~Uv6ou4jOR&I8X$$i
zsDL!7@{@ZW;=ukR3=RyC&)Y~5k*2BETE6*{pMLL0>h(ZmGCrrn=*j`kKL4C^69ulY
z8mnxIqvfzmuGJ;S53+e|)}a7)QUqb$1^H_MU_CRv{WM?bT!o_y?4LwD{9wX?>3OCn
zr-_pqPq}b2Nn9n4>eyBS8Z1&&S|tdp+;;nR(nPa);|5&cpjAMU$g1aMMnC$uZ?Ash
zQ|~!Vmfc<h0CAiUM9F3mrg%Aluq0B0MxwP|u8NVOLt~^)BA^QgXea!!fY2>KW4aO9
ztmWEncGMKB&AO>M*tK18U}}+>>3JO2P{@Jn_{32eDHDXz7*f)>4yMlBLXDlf_L9qF
z$PZ?)tdum3sRiOoPkq|Czx9WI^jn(KaM+z?ziZy}_7879Z)6*mZDFMXtp!>cRGN~e
zUF7~cW&bL|i|&Dz^%B)|Jz1$cxGwZ`@ZB3=wu*T8A$WNA5e^-i!E+75#E8@&Ed at ej
zTPZ4y3BwAG)zJ3m7V1n*P1E07YOJnKLZuQDN6A&6{-^hR?{7aI2u{<{RRn0Qhwr=V
zL7w%TXJR`NtprLNj8>G(ibBC!a~YIlIe^yV3lO3Uk&iR7U;w9~;Nf(T^K$`W*A94S
z`y_kzPGT9=SRP&pEXUw at AcZ1LV#1(;(IKv#5CjqBYMpYqLQkoHM4)xT{6g(UrPXhK
z at -y!#pAJ2k9u)wLFlv6TjBq?GW3aVE8Bkg?KU*iCFDxfSwmO1zOF+o9hzL#d8VzMp
zo1^FLzJXOhkSur6FfG7YPs+9>8`-#-+-fE<y@=SgD`w~RX?E at 2k4Y6hMGMCfc&^0r
z!IGLJj;IGUqOgMRX{3w^f|yDzBnSdL$H%0aauBdsslNPk|NQ>X96mfNKJm$SpVq`*
z69ASa7K5P9p4|u7vSkyN0$YJj3}Kj{RKqvEWV>szl8Cwk7g!R4LN(4+TWx(;9Y7x+
z2Qa4b-Eui76j!b>pn-jd5ZfON*uQ6reFqMaB#OaO79$Lft;iQ_90!s(q`FWcs4rq!
zid;^RBz2NRQ>z68VS<Vq*McOz-Lb;wfA(|lul&<z-zUUrPx>_gP%c-*M?U!Rot`VX
z^+&fbv1Kc^Coo2%j7BNNfqiAhCyJ~5|I6&&bg%|Guzj%(CGdD3X2x%rbxup)fz%*&
z><Re6_veY~Rc7X9m|rY2v0)G?3~^GYShC1vUE(lgZm~>ItDw_>QprWim?(^i6Gg2S
zQm-k3T7njYQBr^1KYjN7|5&Xy!nZ#y#9z}7 at V2+S|DrHRf07u7@$s|RFus{HCdLWt
zhA0B99Y#irWV6n?W&fiAz?u)Ur3_n}#xg0zQX@$N(U1^9g4neu;M!{*#1;~zQw~i}
zv1NP^DJ>QjD+~{1$z=se6tcK5Pf)L+Rfy{-N+p*#uA?=CK}@xpP_4v7u_7_?j;EbB
za^5Rm_lMfHBtMO#D*z7d`hobshi_E9y#+Fbab{-gT=A at DGSoXjSXV@mKx at g^cn_X$
zt=9fK5dL at pAjBF(r`gacZIoN(@{rGg<3g;U62kT!Rla%6UG$W4_?ZmVT8*BfL#4b(
zwQd+0$xz7BnDMhS&1GX#lDNV^zmGN%N-5IBP_Ly_$`O at D{e5a%@pC@$>G%DJpYqWa
z073}!C$D_#jgI5IAP93vKhLI(V?6tL&n2lvM0HIRgE1B(8%p>YtGfx<Wxu9Rpo=Il
zrm at tkv>NN<WU`G0iqeKe!)zIT_ at ha7Y~M>?PYy5R02Z#3aAbOh=_8A5+1yX5U=!Bs
zEY8mXAW;NCnS5U2dzv&&NK-`=X%^=LDwUXetdLgxuNyZFzwDjw{L_ at 5fw5*d_~kEs
z%SC;~+)r#T%i(E5Z-0r=(Jeglsw+t9ny?lV#Rj7#`Fw_fA- at r=6I}?uPE)Y`eyt%0
zno5h^VD)~cQFUWvBT#wo{T1%N?=aO`jjSgzIws?LC^WOvlPoM&nV9IOuO~yLyhy!L
z!?FaHG{j*QAwmiT8*NgOxIz3{C1!4}PPv+3EOo$fdH!cU^Ztj*<*FzYa{SB#-~;dZ
zn7#Ai192%^B9|{RznHS^?5)f!7 at qZ<D=6l2MD>IyXe<ydq)oAup;UBMu<B!SfhAL~
z2?VVmiXlmw;a}Ns;J9vs#Y-EoAOUW_{UEz{%@RccM#uCNGc1-D at w^;Tq-Y(`Q_7Ib
z*euM=6GsuYC6Q8-CUsO=Czlgg7Nki+lEkDbEG~vjO_vGd6x$Uq`PYB_;J=*iHvQuc
z03n2V<;&jm8<y>U(Xu at Hdxps6^UN<ML}`|Zty{S4l8ew$LL4gMNHrEvGLlTj#q%sY
z&%(9^mL-r at ORT?TrLERgIg+$-k7YMzyW=$WmfP5rfXS&EJ9kX+$ivfsMhJ!L7;3dT
z3ky~H`$`NCdE{~qLMv+3T9fc#bV8B at U?MU;xSl|zszG?ANfVfvtulFJ5o64!FS~5;
zk6-utHz#STg!NOZ=sjuxBuUD*Z~VUa@)vKYDx))%s$qO=9N*7@%ux#r1A{|ce#NEq
z_Vkd1F)CIhu|g at +QiLH92n@2RAj)Q=#OB_TSW+UbCb65F?SgcmT8lU`TV?O=BkbEd
zO+5(E7^F1x_hr%Auy6k~eWffLhO+eadBkBtwNgQ=6e$f#g{UM160%u~j4#nfktQjr
zQfSjye*M6qd1mIzKQ0yA|MBV1d|>y_;;dgc0G7rdzw#~b2*c!EqoX6tEhLmH38m5i
zBSQmt`63dJTsF`77hizqW)MhpYS5`drHwQlt&et75(tD8SW<!|ux){~8?4<J(^xn{
zB^;hw<o<geA*{z}t*FHjT3f_P6-R0`hB!^>FSwkwbqLE6)GBp?dL6A|j7fkLbOI(J
zla*w%4j9wW?$e~%6w+d at 9I|Wo)IllqZ+-srfBl20sTnam+|SSYSQh|<5at!X|Hg&Q
zn+Hl+-{ATMs)5J;$&kL at er(HQelcNaXn<lq!^HR~nS7p1wt(%qARF03rY-$P8%?S-
z(^Io7&PU81S)^R9P_0+-{VY-#G_Y8%vRJ8+q$!p#IF4Y;ra>k~i>NfBUJHoA0G*~F
z6k0_X-7x8lPVijF7yO2Pp&O1YV+;mCq72)29S$nx>K|SG?;rW+AP9x;d;GkNbr*-e
z<`3WcsxVIfp^*33GSP=+c_3Vj at Ti6s`zC8t%L$oG4%_!}q=Qn1f&M;*hx at Q4gkemY
zN at _twrBZ7Y^fXg<)6`(wHbGR!aU5#(ki}}1Ovb0TkfFC^G0>OCmXIV7^;!+fk{F#J
z1Xz|p7==<1Vc00KwxlAL%djN7jWNp`LUP}ZL(I)rU-89%|H!9*)>-{y27nO4y!@qa
zx=9<JTP$SQG+HE0B?t#US43J4J07X9?@+*#&mW_Z^@&4GkV>Xz7Kmew=lWzaS%O*>
zV+^kEA*6*cid^2Mkk1oE31JYB^=*24d|XFjv|3I(H%4JhiV(V?Hwc4P32{;<3Tnhr
z4JpC%Y%Hsh%+l&$Fu?r}O;M at VUzW?~|Lv2X_{%s+QeoQ`PXJ(zF*`fYXa4?QiaT~6
zTu{a^F`OriQfl=&xoiR3^Krc_`9d$Y?c=*H2%AJ{gn&#YkB~NC5JE1ml98sGG)<SI
zI2w&(Tgc_cN*as;6vk+ at N}Gj<4IrpABu(Om2+%1~N*vp6<S|&*GU=5uJoNB1<x22-
zzHfi&Q=fWYcsiwKo%R4&;sSs4ia)<NOw5ndB;w3Xee{%a2n(ciNtM8HJcP7SN}{#E
zc6=<$LRvOLN{-foiH0 at M?5}1xn$~MjU<}6S<qfSds0Pa?0j){Xm^h9boidxia$N`4
zaj<L)jG-Px>^rn@@bFCKEmu5k%m4e+H@;f`yt4bp41gsN{K4<P`AW~v{6`^YGuZ23
zHBC7otY-gv7qBqG0xYC-uxz_A^P7&>qpZ1+Zz$x^YEsLRU^J<UQE7tKG3W$iR0AMd
zH<p=8QdHV-95}Xv=XqGRL;!OOHD>2)|GDSD{9k?bD<Au2bFI852>)0Cu&fWf<SoAx
zDfP9p&KR}|8Pm)N7Np96&{)Dj8H12EmUPevY}>(gJZ#57V1W@$7H`nHQC at 6NO+S3t
zXy~`h6-3i~Ylw_gDYVj9mWAs&IF5r-nsOzm9-LadcK>AM_22x)$ETi{?I!>LOXDBk
z_hEU{kN57r_ at d1d#jI}3`sLLQk1AbD8hGoB2Me>*&SOO^pyj^S`tqjsu9RwQ+F)B2
z(y~yg(T8U$d-fe%eA~ZY{Wo8DVz!?o04((e{@ves!@Hh*-sszNnN(t&Mgos$N#hZs
zF~f~%h>2xtw<gNA)`+!g?#=fCN-gOG074y^tyT_B)js%d|M#!|3LuUX;W+jaR6SV$
zSen^F2tN3s&x`2;+dsBxEca^1 at tb{lbX&8`l_uHIbTG4m;DSc(VVbICr;U`7AXH2q
zsqU>*<F{RL*^|C7apoE37k}YO^8^`BApn-Sfl^quZC?4xcjS8u@`7UC`=>(QJy%)=
zV?;~!&e0 at 5(>nW`38zY>D5cTb5JZY{HQ8Pdl25y?^X1ucJoAOmf2h`oQzXK+pP22Z
z4FK91gAjt3yyP#6TPKPer8MViZLYE{xlKyWGKO)}6zZumsnTYz*5;8kH4iIoZWBU0
zRIaJ%eN)lFZ(j3PNs~)FA=7_~0I)pLG{te8<6_fFDIukNf;vA70C-}Y-s6dB_5=W)
d7(dVB{|A}{iGK_`5CH%H002ovPDHLkV1nH%iLU?v
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-opensuse.png b/src/wok/plugins/kimchi/ui/images/icon-opensuse.png
new file mode 100644
index 0000000000000000000000000000000000000000..83fe4d5df0f59b52dd609b3bd16838f4d2570ab8
GIT binary patch
literal 3046
zcmc&$i8s{i8~@HQh9R;H+2W=}wp4SGHNs%*jK<hz5C+v)$1<3yWFNYOrZjd!4B4kN
z_OeFZ5HcYtdl9Z~{ibt%|HFOHdEU=?pYuMSb3V`eocDZE>}`>UU@|ZO01jDNm^yNi
z@;mtXxO=xDevk{iVJ4Q&{M<$6_f6)W1&9`|Vch!@zXN2Vd_Rhtlnyt;ggagL3n$@2
zuK*+xNrP}LD9i^>yrOYE)c^jvz6<~e`dFG8J4ZcOD~QdK=#}p`3e%S;Ndc#V%ghT$
zp(kOYHqsIbHl`V6$|_^dh?MK%3Wy^%WlY3rh0i5oHgAfP%>`|a_nhlHrIeClN;cg}
zykmHFk4 at o&i<*6i{E8gydVh}9!aC22MebGv241g-ZBHQmTkvq*>sO3Maxs4<s}V5`
z*oAF at iE?Lv{{IL*&j$0zP+`3;Y#dIiP%0}elXinK0a9&5Y-kUT_#F;DU6<liG%20M
z*2GzKo;`8|W9G0zAyGa;7}t5ufYKTf)m2P_EXSS`tv;Mk%`C!iV?dSm+hAevNdU=n
z05ayOis!-b>Psou1rgq>;ukbIO?xX=oc%qFL_%{AAvB_;Rmi{!P?69BA at Q<gedeVw
zb+BR=?8Aq>C`Z&2(8WY=JI>sdS`S&TgNfg%Z_#nXYt}7N6quP2hsEBdjv<yb?79PS
zhMWA~w?Y!&6Y*gEqh3Z{sBiAymm<oiVT$qPUcdvWP(Z_l;dwO2j}xgr{3XWu)f#W1
z$r#L?k1RV`^>Qg(>MfWA)+P`<Uo>#8DFN_Q5IcNTexql*QE1<_e}!$qxrkfQS&Qc&
z)Q6F-&Tqnh3x#O##>0Z=oPFq{N$ij8p{^<8)&6|inzS25ih8LbN)3VLY7?if)Q6EK
zTo0v>k3Tj1I3@~(I1n{7)sA7rOvh$po(iCqX?#C#z&mZQbir|#cM at D`A at H^Ckq-vB
zPK}7LH%~?L4)fBzwc{k*tNYKixhKv~Om>C{>nN^S7kvQR7wPa#@9AkZ&ad0Ba?Py;
zd*d%e@#*n>N#<yqjtLqcwgzlrH<p>oFiB7~Q)6ukOW!Dc)QV3tR*`V4wx3Cs at 7e3y
z7y?t|It6-oIQ;8D*-ORETWc-NFTZC~uZVUo?zKHfbX;@PkE*?QJG~jLYz|HUz7tI2
z46=UpFuX<>{G7^1na!U0E6W%%VUQ at WYD+ViUyQtnt9a=TTy1i3Cvg>}LyiK?)g%vt
z{Acr{mjy?5(u$Y+3d;(!g)wr!5Kk57Oda_PYkdGXOkhSZ*r~-TMmR`0PW&lfvU?ql
zh(d0|HhXXBuaqe2Y9`-kp>*|D$Z1-jzCFjLS4|(em^iPqn$xS at aRsC)jmgc at lG6$5
z`+&-YI)v*+T47%JAAT?w>3eXj=6PwB<mx=e=1m!t+c!vl#_lp)4D^_NpPflz0A4B<
z2?{GSu0Ix#No(zfU*g1=q{C)|*c&ufT^?$h`%b;@oqK;cpu$4c&97*1r{pHJe=~#8
za|laME6iRwa4)ob at bk1Ld_};W@!TTO+l`}ALyS3*b8tJ?Zx<^x;QV{ky>H6j_H|j#
z?M1Q;vGkU2r<|2}iSk6Uafcn{6s3h?P`?5y>k}b?UN<5JgU%|S=XS3V$8*g0B;;Bf
znHHxXs6O0>6NRUaO|~XEJsPt6sz$t%yTl-*zjOp%Q&rEO9y)Yv_1lksy3C!6mNPOU
zb$MlhY>^1Jn>)Y=be%^skPy1HfUnG5LI)~}bIHl_dILN7rKT;R$Y%+*Wt}A|5|=0n
z;7`C+ES>SUV~7h+QxI3>ZJv3b+pu0Aw!tK(Gp`8|gj?AA5){&LcGB~hQ53oIZK~5Q
zS056Lhv)r}KNx%_si4aI!%Gizsb2Ngg2mCbcJo^qCc>0itHo%0RG9T+xbGN`^Sd2=
ze)qDn=&CgG)%tgKfGxDI{A_KKIKaxYh!ts-X+4345Mn6jXelN?ArI=xqRabqM}T-s
z|B94Ba{A7{Eguy`2o?u39i?g82|!X_5E-7 at fPasr&*3kND%8GfS5Jbo<tLAZXsZw3
zbwwDKE`#PV9e)SIT-5vow0b^g7q9#Sn(O|j&aK{KCJCd^*7>tIGk~CV-a65Q$0_h!
zYe+bdMipU_f)a54xWgWGY2mnvm<_x~Uqbg!b<di-dO{!IqddEJfirZgk0CU}UW(n}
z>*)_zz41~Eo+^!{-!t1U_lBlclrr^3WrCFson%eDB6GaehX*ZFwmdtjkpAZ2z)cc$
zSN0iN%|?U>+59H<@_ZBGlf*}(qxq<al7l($rvQR3Y+wqOpA?bfd`UPTGQ+Djh<sCJ
zzuo!WM2Xo&A1eQh{*x>u^isv0<xnch?q+MFj%S`GuUFg4(F!1M8pamlgV~FH?@bfE
zp{q*+9;#{!AvM$C4wt3T%D27ywfucHURkx7p~5`j`z#27k6PTbUnX#~V=Cv`5A-Cf
zLZaVWDOIbuY#(6#<sx7QB)N?5g-l%!B9sFM-u-9qe)WY%vknn>?Z2!qZzI!4FV-D%
z{N;&~%xAfNif;uF0xKZ5(WUgX-NO>0&`m2Tty<`am5hC4Vy>SwQIpB+Ld7hW=OVz$
zP5NyO%LlEu^rZp`ejgd#Sh`&kBCH8<%G;mc(p|nzN6ag`n-87iQ<Ph-dMD?2ymXH!
zo1yw*{Q;nrqvJ(xk<ZWakAGy+gm_{p96BS*!Z&JeJj1kvo<4de+eMU1M-{KH&-l13
zyrEJ_M}RTd`5&9b8+E4^rC*y(<>48#y~leyhSi;HW2JVSP4xxuSw|bkDW$c`*ckA>
z!Y<CD0$<!mE0<T=TRRrDx+Kn9!BZXfd-g=)gSsM=#77LWh#GdtdyQ4E#%p+JJYt{r
z*a7g=I$yL`iG>oyarCV*8xNUdbn)p+jw`%k%dO5D%10gdTo`$xShV_92UnbxM{)dP
z?4B;V5uxDi<?zifMa|#O)k}$6ZFJZ2!1yOreYhW^5P4Z?iyBT#bGx5aaprAU%bloO
zztEh^lZ68&=R~4uJ{z>I4&$2q*J$OAtcZf0Qa?}t;bBGi8O_tQkik!J{Q2hl8W*7Y
z9-DE_CJ%*iPm-n8hxNGsSiM^{;(m`)o<VYm+8mKX*3Asz6HDrS)Q^Q$ML+JZj(#kz
zQ83ruzf=}3GG5C!q7u at fO+>CXLoT99>Tf=;5dV4xVyhmiSWu9)k<mr`?A?e^Z9+KJ
z*Uko2F1%5D*#15}BDr9oeCkE7iiFa1-#xUkpq at D>wrR1L-qj>y{4R>pF?qLc{!YTf
zSZ3XM*URCvBa?}YQA!?{C~ch7do5p0GN5WXFGd`RwBh*&lw_*@%pBkiUVfYzP&cLE
zVAsGea3HB=)g&QEO~KOP at Z1ULo<Zcg$Iw|U9a`PeP+w`kDxx+q{&YInt^HVaC1;vB
zor9{EY!%%zYa?w{*{=!?0W at n1&%&~h3;H!0z9%S#lW5kKhwm(9_Ch1T`Z=qxV!V<$
zYm>A1=g at f<R5s$z?NY_Tj6bIFO7Xj+rR<TRzsIesF13whyQ(F~m1s%I_S`u^0#{sd
zFF#f8Io)js_WLWIx`^eZVspa`?mDz+-|BJD^Y`%rUuYZ{WI+4^2<rngns%qY{G_)|
zl8i+4F3Kf(ys}JfbED0EA+vJ*LQL8#gb at n{)VTWVeE-Vn8Mq79T>WljOT1hDTy^rb
k`wyDue`PEG?`HRnhNAAT>MrGXaXmR;X=ZC$Yl6G+KaKu$s{jB1
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-ubuntu.png b/src/wok/plugins/kimchi/ui/images/icon-ubuntu.png
new file mode 100644
index 0000000000000000000000000000000000000000..d92c00f357b6b0e1542413f6aaf0de8ef4b8d130
GIT binary patch
literal 4818
zcmb7Ig;!Kv_a1VFPU&ut7*J4<Zs`<6YUl>(W>CbDj+c1pW*7<S96}_eTUzNFy6YQ%
z at dtc&t$oir=j^l3UF+`W+3`h3ON9uZ4j%vj5WQAa)I*QZzXHNVzq_R&KhXoWm;7r3
z5c&xQ*}%|qJP*~kUTFQ<zk(splj)CMr1e%Z_SSc|^Y(*y+5-Ii`~)4{oV~0e9=3w+
zp7xn2Njd<4T>G`6oPmGVL3V(@!Sqs}Os#FrXATWaMN$=b)07FBLtU{UzX%&9N-x^P
zuR8vzp=_|DfH9SBZi_*klK;~tgHLRPM~JBk1O6sS7z>z<6>lIR!lq`#cSQ!pX_q;a
z-MlrTk$x>XDoLH>HF`ZPzLFI*D&BGW3ioxAYGNDBnyYNoRT8;uQu2Qx)^Uv(fxkWH
zPM~CiTLv2 at gzJD`jFo^`XlZvn{v1(og{j{{HtNQBp7|+Z-%rnPKOxTmh2aB(ThF_c
z_AzJpa$S8(Z=2vv(gJ|AZaW-7KnWlj8ZOM<(H!$5^g?wd5+yXY?{e3n2JefH at s@
zXCxhd*m~?g4suaM(axZ4x4c}SAPZ6cyASjSG%@!_)r#jkU@`$y=d#_j+hTPUz7uqA
ze0vLBfHuqOW)17AiyrYDwJq&j^em(=s~ThQ2>BRcoQ5Z_xoFkx12+LxoV)7Q^7!a8
zu~<}?>}#&kEDcyB^VulBHCI(5ay9f#uApy(O+3pD+dsHg-?UDKfR`f~*df at fo^xv9
zjS1Y&arOvknQv*3a~n}O_P_YP;x3cn0t}C_Bqx501;JZQ6thfd^R(f8(3PHH*i{WE
z-PW(=<FN>f8>WZ2%dbwpb=o!?J4Wy@%KJrc;ZYL^txcr#@W=i~n+GGfsF*$AUA;{;
zMY at e&3kj at RRZ5r|`V&I`aq+4lor<4S-<&l--<{k3?s<&(HO&xJ8}M at M?6=IZi+OBE
z3x9^oQa{_3;<sibxjqI@*!9A8cWkcsu6)$i9nnY8!oC$Com1J(y-ywL=6S~cQs=hu
z1-38+^kis7jTv=O(LG`__Q!{2;#rU;cfh-{EUzaOuL|jQ4zSg%&$URCA$cba9Z}MY
zR{*8jN4kb%xlnGNw(GD0flWfo6g~SEimw6CzU?*l+Zp|lUJ(xm>>ZV)_cL=2(U}pZ
z_AQ02fPe7frDaA&CETrkTo&a9#-*}_QAZE3nc?JV912d>#u!6X_pXbpUc at xxm_(bE
zOy#?6Z&D)o_uFuc&-oOHaFc2GV2SC`pDhLXx)wXIy~gp<T~DSh8%U3)$j%rzx68VX
zPzA1sTXi9)w98l)?AIF`ca{pS>z{z4+DC808%>E99FSBAXJ`24$_!f<6{T647dS>q
z_orp)C-^~{&Vme}Pc^R~HzcE+_TPN~*iOV=N0GIOchYSusHnNfO>HqHH-EpV#68as
zu%VWMpJ1K0qhTuky$~=7jr_>9QGyhTkDt>jSQW9kqB^PK{;{inbxY=l$Q2NQBA7Bf
zU8)KNC4F;zAUHqbCVe2z^FQII%&ww4;aX9CID7k at j+tdPzwPsDIj6Kyqv^b)6_xX(
zRz)%CPWfWDPX&GItA;-YllvTY&sJIt)j?ukmO2uT*DNe)y~zQZ?_TKCuX1s?3z at HW
z0aS9@(oz}UMa+krmKuE-F at OUofg{&!r-Yx%^3vthXA*@^?k;k1q<p3-%=sEvK89n&
zw?{QQfB~A!NX;IswAFyE6fLV{%uvZpBYoe!X8+|7!*ZgPXBK7F5KssZ?Z$o>VN|IQ
zP&xYuq;oM1{DgAt>B?ySLLb{T5<tW6NNC>h<P^#(|MQHwEYI`e$<^RR!{d;pR=4Dl
z;)hrjJh3TOoIClSgkA0jT9=arA`~-NJfXK<N*mNsS$G|GV}I(?@z*gTi`Q*V1X~O5
zFOx>q4^C7*r8%QyU~<v3i2)-o3AqA}IIfXs%j9scKEyG`CZCT0Hbe>ymRqSKSi+F}
z*x_yvPZLC|F;~4}_ at 5=cs7F<$+flU~4=cueM=n8*uHM4uVK;)qkH1tG+J(R*FUiyg
z28`9TdW|lKi1sWdiWiCRx=`LK$hk2xR!p4+=al at lxa{)kWZuwi9Prs4+u~Ih9fG;F
z`2KOHG}dZtjb4HqANOdMp*O7PLuaDeTW}Yk<c{rHUq at p;ff*{N(8u%IK%nVMN&Jjb
zu8MyKw2Q4F|4Rla0~QzSE at jK1bSXnobBs~br`1&p!4a?s#+Kcy)ONgaVEnh3*reks
zq4#oj?Cg*Tn?C-+B$c-+VaQ96!|P0FfX0WlHwM&^+9f+aWM2lCR$O?ItK?f1Sd*}K
zcWCmAd>X5b*fd|fkO at ppRI*++oPKjok~tIPL9*fZP;ejMvOCMn at kKU7)4(><lc2xV
z3O68anS26+gEG9uY4ETa6n35uAAHj#v#)iTV)AU9A7C4OL3TD*><rd9`Jr51npJU=
znnBH!|1i82kpUTO)b;4 at UXRJ88V_*|k}17IMJsB97z at d^t9+bWV7i?++jUB>whAni
zrmm72i5?-x&RpRVFHqd5lEC9^RaXJTVJ)#tw5hF`9Iz&F&zyn{8>}SDv;?->_-hz3
z38atL6TkJ$ctDzycmW)O4}As?nV1v%PpWcbg`a8*B|o1<a$)dzO}6;oP-=wn?DH)P
z-%Wq!>2PPOu-G}&*}Hdpky0zft+VweW%(Z?)d!!J>u!yS7U{ftAWbYW<n2Ucjv9*d
z1w!p<y_mlEo=C9m3QUZhqkRyIA#|PYgTU^cm>2iG@;RSX1finaNBB4&bb#*gFp;6}
z%#A=QA0F_YsXfa599(ELe-ZK}=r|iOL8oEo$-SJH#+xzE@*CR{{O`cSwSl4Iy9W1s
z$i3${7reyrYjR2a%9|9ipnb~eg1Ce$knERkZV5_yTJ}++^L-Mr>9x>5ZsR>F8pB?-
zcw(PPfHs4TX#B&G5kYIuiv<eg)k(ne-ALAfcG;yx<?hIoD`&oQFe}@gXv);1!qOkp
zxWPjz9Nk7GdAv?bk!10}Hbh;{@K;4 at W>KO{BRMdsn3>&956#2``j8;zOVJ5>eokM{
zUJLa{T7n%JYgX~KsvbQn_eUh<k=NNYclYLG%c;y2 at j-N*{}O15q2zk<2o=~H!#@$J
zZ0hO+lh7B4mO~iYe=E}UxOWLyYTr}Kq%1<a2;8h1FtD|;{Z-qF at q)c3H1Ku*on)qY
z+`I$w=x)VHq%YzS$^Y^5UbQM^8k20w&&IB#-n?S16T#f^Q<1M-s>>VCXzHfEbS2?J
zgLcf2aeJ8!5{0$KDkgre`YD135x)Z|nd@(nR2c9RHQuIBu^EVcq^3QiFBi`2C@#y~
zgktxC6v^QS&GYY!GD at WIuW#yi9cT-p0R<PN6Kv3L1hT2*LEL^79_wblDz~rX;2k_+
zh6Y{KRv#`Gs=k-JrY}dUn#W9 at 5R<;~*(r_xGSu2@$#H)sd~(4*YouB+ywqTQiy-Iv
zVgADDK?JBDnz$cNdgRxPn}8Y0k!uuRP>8~)1F at 9vmUoXvz0}`3sy%WsC+Y%J1T`cd
z7v}ohgveh4Rt_Q$eftWx;X%*{7)3f;sKX8hUAXzBOyj}5<R6WNL*Wcnnc`bqcCX`A
z*lElYNA5VCa}Z1fX5g;KsHGeYkc=Rc-80JVN9j1NU=>;3X0%U-2FCw3=I^n35ezFj
zy10fEez+QJ&)=UpRitJ-|AlSBgaI+!dg`aNo@?~D>2)<|1}Ms%ITi6ke-3vxlUQtH
z_Xu0K;u4kv8I*5&y3$w{O`6>$&I^~E^-rn#m2GW4d4q)QHg<Nbo`|Ap&+uz{`^Od#
zi=dQjN`@kuz<WZ7cUSyN><^83RqyFXb>8O|hQMrE4|mL^9BR}U$KRH-=LeQo`jhOi
z0SsNoDNL3zd<!RN<xT?1(10QuNh!*eE(!6UYq<0>>9{FEE&u~=jokMDEI|Z8%K at B$
zKYduX(q<8ATa#O4q~~+`(SY{2GhB;i0*hvKrmah8mrcpa^ku{__kB#Rr8va+dpRfr
zADAHSWIE^FmCDryWUCYtRm?6+Re>JSlJKsU1}xYaI<hYn<#RW$m6my4IxV-zIqU4`
zC at xXqaRL%T4yO}>j=ja3^s|Jii8&6VS`CWN;dgGjq(K-w_B+Z<5>E*Q78>CuhR^Ia
zAg!0Yf3f?UkpOHLnHxni)$Dk^k0qrsSG-|rU7_FQEV{fxgue9nzR{p~m?l8FnPU2Y
zdF*4k9`Nnf`NQ|Xm|l_ at xF>xyrlxCx2PWX?r4gdC{CnnBJ at 9=LC)&rYGOx=Kb$Xpu
z_G7Rnd`tQhxk343rYnge1yv)$oqq{~_cf8e%V#j#RUO>B-%ny_cd35U&D?8NWvi$3
zyON4#VCQ8;mZ|f^%%_CuA*)tQy)ik}XMa8bC6ayrfN%x<vGm(po(W-|i%#8#B${uQ
zPX at A;!8TS!F;BLYzm?_8r#-+WkixCZSk!HDGtG%A=Wo=}$(7#8)FzBAVY<RNuaqEj
zvxS-!dO7xuW}H4pQ)sfm{`2lx<nymbM;<JPyVXm#luFNXV|nyc7nVmI=iuT|>O6FR
zBR~dDo+5k>E}F}f$bq0*)L7jnGaNvoGv99)pDrFVZ_bU7J#E|?%{Y{Ic7h72?(zPA
zcy)|4r<vWSo=Si^l`F>OWK9#`_1l!}{T61uzXN849mY)v9g!+IRRI_ITE{mxqsElC
zEV}*nxQsb|**VAIvST3rCtQL9-9L&km6W at VDS7nP!^za43*l_x0lt6G>_rZ*%72WJ
zfq+ZvAKTo{C$wU7rF^3VW0~PqT}T^Tfn4Ouj_%smtJGA+M{;v>5F&BU1oXY_!+};K
zkd(Qoksv4bQN3qq0Ncry8Dw$&pyg(dt4 at dWB8uegzKot+&(Q1VkC#gqy)V)yzY#LU
z at vh7;$-KmsL`>C_D!#jy^dMnD{fK08Sh%+!zV~J5ArUG?ZS))@e#h_>LcYDy88bQ-
zNU0Tczuc at xN7F@hcebxn<ER`ioV(}kw-PEAK{d%Aqb)DkXRE;x%(QEsbCtMOYn9f|
zeN3K#H`kxpT$fsf;BtPc$?U7^V;#KN;iMeCQ{N_g4Mwx>QeZZ%N9 at uLRYo-vy@EMb
z!(M{BUkg9YhIWu_Q at 6uU`^TI1V|Aet{|k#C<~TadvyLr1kr8Pb?~LuaIMYUXGC_c?
z+l}1#H6lOs;B=}Yn9$-n6cQlz(rEAzOvBssJ`TZJ(B+c99bQ^b#NB$DHxuxfGj?#~
zkk;Km)})#?WJo$t{XT!&-^KLJP7kF_4O_wOQ|2uBpJ~i0hQ8Edzp~xT;$kOHr_bN4
z7Y{aNG0rvE16_lBby{626F#y}YDG!1m~3iu!ANDFc$)2gaKrreY6)mYykKBS at Lp2N
z0RL*^z>coFU)hJyMQDp2UPP3Rm at UiCJ4IQxP9mQ$PSdM%RNe6W?t|?%{Tf+B{4G at 4
zr4~`%RoLFAFxV4KW)-GSZ9efOmO9b at v`nTL_W;vBY2_$X7r2fR2d4np)T(|T_51Yu
zl)MrqgD&k5V@^V|t9i7A5Y&qiQ}YaB+3T*wn>_*JRJ9c8B~$;Re(=k~mUi3}rQgY#
z<=tZ!xvr$0j8`MG=*S)5#hx>^b*Px#@dI2gUY{ov-kCtqr~j!Kd&*7`8nPMzpVl>z
z*;&Vv=>KXBes{#Qs4)5Y at kecdPaT<ToM`()skt}HCME!#)+;0`c_<GN%wi~*w9H6_
zy-K8igwjM$QKYfx4pIvg$9K>$DOj&nVX3W+Uy=6lKnA_s at cX(*b+MwMyw$;*ew>2w
z(8?x;hMi84KQFCmtmhNB1H75HKC`o81OB&whE2}P5thm4EKmDHY75{|@aUB#jCYp!
zFBGt6LdU;MTqVd#$*Q0WwU?HxV^VrHD>koA0z<F#IjuClp8*(k`J5;{h-#QkEo@~@
z{Af~Ou_So&Sl&PWuLrQb?J1b<WJ9vEg+`gsa_^b)cY;-#|L-0!`ms0`;rTNdvrYKC
z)4quT#O1pvWWpE<JuoG*O_?xa`!lU)G53^QW}`UKO$o;L;x2F2*{4cbgr4{CxfpYv
z5H8cLN|CjCuPNnH$*TOLU#G%;NtjF)hS(8Y?>MRN6qAzlUh8_#4z1+rD~r>SF6EoG
zT3<7)d1Wex>Xl-wH0-awY=2YPS|4GhZWH$oqew?Zegvxs#>k7oA^zXUBZ(xz at KQls
T?|XFr3GiA;OR-Yk^22`sn~zF<
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-vm.png b/src/wok/plugins/kimchi/ui/images/icon-vm.png
new file mode 100644
index 0000000000000000000000000000000000000000..50dac50c5a0ee59f4e79170434f53bb3b94390e3
GIT binary patch
literal 2976
zcmbVOi8~YiAK$c?G*_1+SxjOnw_GDMmIx6-d=n-&8()kq<W|T%lAFvDQI1%-m1|)L
zlcVJ*<Q&6~-=FY(p3m`op6C63eO~YP`}I8UcZ`X#KIDYZ2><{9K^f?o9o~ea4Q4+)
zTM++z0RXsMP<l7a{~h~n$Ah+ at iE!)YqjU0|_6;wf3Y?G$eFEW)8b<MQ?WJ#f1svn~
zW8Di*&&S4-g#A+Fkt*GZrm-n<u_IM6(We`*ZXNYMVhw0Dd}H$USYdKOOU2Xs4X*T1
zd#1>T!sWRfzrMOa{5InHIB|B;uUC_y-b`P{ZH>Rk5(<NY|J%wp^O<gq>H9ra<F+|6
zGQ!&1-MW^RqUJqCnc(2Lz?#m}jmj$EY!((2tTXIgoMjoShCU#_*{IO9w4|NvVsN9l
zBBP?x^W$-I;(4CFM&ZL);KH-rwYl&`?~o>3KJ!OrlIR$KnP)UzTQn=j#XOI|ZF6-7
zU@(}#JeQbSsf9S at p&gpBFwo>5OsTn;Ou_&>RUmbpVE)U-m*ub6rNo1(x2IOJ#${-4
zhM$#gEU}KG!6 at slT|=`?%Q+m*mwCU0Lqa5J4I$NhCc#||5}_CV#ixK3qD}qi`<o`o
zP>|}IG5eWO7^>=Z*LQ-CVQs=AqFqs%TRRud9FtFOFIu`bQ at 6@ObG(bXh at GaiNOJ|C
zZa(i~qELOe>cw0ingv-<*OFiMN9q>Y^sgX5dL^#m6Ow_5OC4OkjoBqE%h~!|!ysE>
ze*jF6d8 at E(EE?L`;;SLkL7(ele1qYGjSfPQZ?wX8lb*YA5C{SrP*Jr93kM>oJ6%k}
z%Oxfvu#Z>fNw#a6su$WQW^v}~9w5rE<@xzQho4_FX>*pU#KDn~ZT2f{YTRdG<WY0K
zoF`7M9v&f|YFUB`&f}fV)%4a<r9+=o#mmijs<P+{=bkLA-}2-~Ei?XiAMOKrtvRSG
z{r&x0j2_}vlbgsrvTe*Kr4uv)t2hCG)+<}5Ei5h`xZ8}5R=dzA-+R&f25sNBmQ~Ix
z*5M71e`g>N$S}zE9eSYV)2B~f4y~D1AP9#Ts;RF*8IjD(cs)4R097IpWXgPU`0Kcw
zLl%cC(q~ed{eO?q1|{BgV0C?DwAEQDR!=z7Pk2o>GPB0FbX&R6082O^mlMyaCBsN(
z^yawPZ5A65_Y0lXx!4E<XcdbUt<gdBQG=%5ntKG*;4o{5*Gaq+{!#p|h6^z(%d<@i
zzqhloT*mch)2F-_ArN{RVR2!f`uQnW1$=ybJX^Q%)r~<ra;Txckti-mU%!K+cCI&5
zK~i#<W3}@-xUgD)7kW%*b8~ZF!I%Sz_4jXrGxxP$mT;KXLCW|x+(vnLPM&O>)0st&
zRsPdrB()|9Hb`Q;GdhMnArG6+#HfXQul>xgFk9<I- at ioSK<37c%KsFdO)_q*#4&v>
zr*p!a^(YaII(*t|O$0$uadaDrz at 97R(fo}X`hGgij-L%6t77)cS&C&Umx~V|twZXT
zPdoEPhj~m8<PN~FfaS@(`Y)wPNc<fau8HD29X>$epT)&sVKV4Xk(K_d--8?RUw$3v
zjt|(Iu~9H?py1~0gRwS9DV-(pvuY*0)|1k~GF%DZynoy_T`(^X{AyrZGDAo#KPpvP
zQNkR~z8LuYd~OP3yT4>SnNPdG>TBL|(z;^|Qp;aZPThZLTM??O=Q+cU`-%?^-j&I?
zpE3SxT>%DEZ2$LoL69_!9Udu|n7k^H{^agGkZkcu5iqbtDKRM)51Q7_c<Xb_r$?)E
zm`*?7E`EGz=Q(?I9 at xQF7+E77Yba?06lawZu<|duY<Wza=fMue^59UI9Y!#f><J|^
zX}%9AibhJTu|n`Gr#<A*z}ZCQzNL9jjcT{xR0$vjeLHv>6CWqMB6o1tI;$Vl at 33Z%
zWJIUAM2LcV6TKz8_idv8-ns>F%(}?cvK8aH at 5ulETwwOo9xvsZb|*s#e37!<d at v&6
zRGL10DnYx${=KIiSsKin`R!SEOOD}Z$iG?mQq0!RQ#psmF{-lN7uSSpzO@?mYr!7W
zFDPul;cOY)pIKuy7d^%S;9_wOpZ4mjpv9#noM_>|t3`zqcKo1du&&F+HR;urCdAWp
z<6k6<+8*7+DfKuISNP+hC#5lf!gWee)obKgHje7m6eM{AP~iW01B$<`iJhSM&^F7!
zY}*Dcck6%!N`&*!n2ZBq1l8*@8_Bx59T~ixOO_EBD3c$)p<(*<>Cn*7kD5RyK8n83
z%WjB34PP8WHq}p1m03tP0VOv2wJqc?%$%_T+Fg_NEXeR2t&(6||02b6g#UCLU~qi3
z9Xn=jumiaXz?dl$YeE=4#`d(AQuiW<8{|2s#32m7W9=2_DNOrZg7w9D6&P at HY4ipB
z?DMI*2m-#XN>R1Rj^tQ0saj^}#DB=)S(A}MITrK7Rl!{8Tn|qA$OE>V-D5jxYZEV9
zy49Pb4krQ-)Jl!c4lCX=I4)gi=%id*t;cur)5K8SQ`%x7-yPmvw*HDeV+0U&{kQ5F
zd65-0$fA=`QxY#Efu3C<DskAeNM-UhXNW{)qYU!~vdQ!<XeBkWhbk>$(!P=EDtGkh
z?1c{`PEK~M6EIQ7wsj|>RUYXmoR*W_np#5^Emo2TRwvi&O?DvHArYycuFQmCM#_Pc
z^NzLNd<%KA0Y&*o*2J4<KJWnZ&i6HB96Y3YX|v&8iRMoc3DpQHIncRhv5<GFEmo57
zT#=Np3n!gV3zl?Wu1N|##y>?@>uD`PKd(0!yleGwrru=pVcV(0^bDi7>k9)Uy7ys)
z>%tj;l6CdZyAj at unJa&yn^XsDB03(D0xoME6-S_p`eb;`{oGM3Q;#v-YOmgQYfXdj
ze at V^#XLPo8exZkW4*`)WGLR%cxdUaYmjN5aMSPgzF5atP+^c^s_ClG^5s)lHSuC!6
zT{sI+sVt3ye7L%LkJ?1Czg at DS@OI$!#Y6J(?bbDqExhMdfL#4W<+$&*>E%DLaw&Hj
z7Xhx=V+jjlhc?*}>qHQ69iGcR0hoDbRZmO{8(OR%)k8L$Kd{AuR+1uLB!<3#5=N!<
zRWb#Z|NLn(U)nzdzh_IcZjBDywN5>%kgj1fCqHG$O8&CQwn0e9p8DO1W}lgM#(Iwa
z at D-to`$u&1is*%4-nW?O<B at zkr4~V^?>jRIy*y5LOJ4VL2i?f(tXf at w9TGZ!f5#{m
zkknXdV=c4`qBJ_D=qm>c(Y%h!!n+q-X4i~z%Cio2=4~*qf?_Kbd^6<aKEnOxYW)Op
z^mQ)@OK6CFooaC;u at BLap_4avjFJIB(xZ(d4U?t*LN0vu80U}#O6v(-EzF;1Pn7X_
zuP=V|BxgQU;m+M-M-li at Ez$8akJ)}!!><TDF<cEqTNPdZ-rBV^bFE&*;nLvGcxfq~
zTS2eO%DRHQQyvko=d!Eh8W^e#9kz5)OSUUEwM)8P9OY3R`MLHT6?d`|#MIT)LgS<^
z6yx%0U4|_BHF=ZG%2GDU=aSt|&%+^$G(?AOZJ?6t#==lDO%vZ>TSUi+S!7o{{604J
zvOS*tTce4vA~B~W0$^`l^{C5&BjEa;P20|6Hf~`}BIc$_0isO&jc5U#c7UAbC-&sO
zotzTHYC7JUE;{TGL<fi6j8H3>-8pOYu|HJLvm)9;wPOpK^_ptrPX<rvG|jc;bq`#}
z at 9EWsf*>QL(>N1x7G0$tb~D_exI8=(L)?q%_H5YJhE?vk at SqODLErHLrnkGe6b+?I
mVQE8J@&9#74TC1P9{|tL%c2?+(}WHuZvg71u^w5+A?$zXeWqvt
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am b/src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am
new file mode 100644
index 0000000..7e11d75
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+imagedir = $(datadir)/wok/plugins/kimchi/ui/images/theme-default
+
+dist_image_DATA = *.png *.gif
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause.png b/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..9258aee87f0e2f430cf1fb12a4588f763f3c0a62
GIT binary patch
literal 1219
zcmbVMO>Em#9CtTbM!QYZ3R7EwV!5LOiP*7Yo5gCV96yIfTDmTcw6Ieh`=v3h{fzyx
zq`hSAssY^&+X3-;7(IbDF^V*#0ostNNpJ&chiPJ(*f=3gfS^*?io$c-6b{vpux!5%
z|9-#!$NT^N=IF at FyE^+iDT>;a83s8r_K~M&M+bTTG<W|x8G5l^z+<R{tA-CL)j~x`
zXB=Y!=AdCszxFL0q^RvBJ72(s>><TO4r_!Mw&r+*O;LkGHP0|7A*PFP!giC)FJE3`
zXxmCMN2P2m>uIoT56}2;Y-S{H&P<vKiy3-}9;_)uz=7DHYtED#D77TBrmK*7xXm&2
z8U#-!nRTZM*-=_UKBOf!9yMb;Ps=jPi;^t!FVI4a7q}R?<tQ&IlB at _X(i;~;toc?+
z$$|8SEwV~7WsE(A<EqsvTaB~GpWygJA`xl`LX;q)!L*BwTGS2tTM7UMrf+-LMlKyH
z8bwsWNrrg39)ja#vzx+hu#qT|GOlKL9M8r$#|h(FLkBnq|8ZkWbdaC+AeVyys`w^3
zk5Ye&Omg>VLm`lOqa5~aawx_WKxV~(F3x}?L%y(<Z7H#MN&~u_5<ptiMV?RbaS4!>
zrVD8v at O(>SE3PK#KozA#S`-LU7gZ6cs;KfBkmKouAhfs{H^7E#!j at f|*xleBd?Z)V
zd}v_g=MkD}RlsN&VHA{+M{8p;{oGO8wNN#9K0KcFXaV%?<Iqa`$f4KrtJquEkBR>k
z_d3`5KRM%wGhA34|0<T&7OB8+x>@>UvDrM(B^~3F);Mrp0;H{e&j2-FyH#9mHixz+
zsjfH1Eo=U_E3<{C2X?pDPc)w0Q`h${U)cTry;r_#-0i-(^1+#R+i$(o+oLyy)rrPR
zGqQa6RQ*y<Z%_B&waD#}Gs^kZ<Eed1jiuqwm$peKfB56{kCElaPu<xWX*Tygy#8yQ
z9UWc(m4ngZo|4tA&$sX2aW%f${zc=`{>0DYC!VN3CJ3Lly+xgTeKuD)G at tA0Klky%
zS!JL at nLTnk9qqeZzOi_&{C$L3`Rl_Qi*JAZ>Yq=2M&<4|=XMg!2b~wc+G{MR(t(fO
w>*#y%<Tu#??U}`^+b$Q*9#iveH;<`QTL-02da<sDMK=7cWb_g6NosuVZ*kO>5C8xG
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png b/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
new file mode 100644
index 0000000000000000000000000000000000000000..7cde85bcb26ca808b9b02d5336872f10556585a0
GIT binary patch
literal 1175
zcmbVMUue{J98c{SYPo?ZqV0n};)|2JOMXc%y~}#Gy(HIO+0}Br&chc?lV97|CciBC
z)w`CVuHZZen`;>q!NH~v?x9Y7Dzb+TRHmS);FB+cii#l4hoNGz{?hikJroBENq)cY
zFW=AS`#;Bfx;rB48`m=o6UlXI1-drUXUp1;>HE>d^Q&~(O7s%x#RH^l_=st at a6bY$
z#~4HfWLRTgUPmnqQ$JuAOQe+lTrsf|H$t6w#qlVbVOm-%o?#9n0{YRQ?WWlmzt6G2
zw$kjLM4r!kDjKpo$9>d0-d!}uhs~75w(bHg6@?Nwh!~*ajJSbPNwbT*3f+gt919jz
z$Z(ona;lW?0V?(pNW{gM$wLTaIS!?SEW;=ecqni at z2z8`l!UAZ&0zUrsWsmkPzqXh
z*%p=3><}TI!g1wtIbIgy*dOFzDwPU31R+K>V!@b8j7rQ6w$~Um6qvs45gWT8WHkEm
zC`q%_)1?p`FP~o_c7x?a(Ufr&!{cC_=Nu=DYf(EO1 at w;_t7-?uF%NMC6yQ<cr1cos
zUIWwIeb`W_NWD>Z`!+3#F`{8})Il!EX=#>ziCea%@M1>QbU7nvSxJ{5%s?@rQAyQ>
zEYu*Zajb?-3eBR(C#7sshY;#gQphxC+ck+-)ufnJ#Tqu}2E=epRI_VSyUSSdgIGoN
zkwLIu#CW9E0X;*Q;9v-QK<$;mjy<+(;d1b4Se~V5HRRg|k(Kqa0~YhE*sIv*rT>b1
z32XhIoN?3{E^Ll}HB0S?c3`+&X?-fJ3=eYY#Q1bH&XxYUOvmcaoYr2f-0PoTSZJ+J
zGaKuFVj6^FlarIb%*@=_c<offl__vP^D+Rfmu6?npH+9yD5o}m%``PNmBebKF#qJ%
zwr}PRFLb?o`wG|fbgrw;O`ZPatR9U<r+E2BU)xQvuUdEVLEBd+HjQdmH|(hH-!gr<
z+Sf6Ag+FlTSN+W9 at AgUu?sylUrsSi4bUlxpeCF-_aZPc)@rz)Bzwqs$H?Lnl-1+nE
zZNlC5ogI&|9~C0kBj>)K9Pawz at pRkY`;PY=8`;oyq>edy=*0QyXoDR7Dsp<a_FHEE
F#Cyajgunm*
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume.png b/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f1f16f52f2c000a7413e22a0105c5d0b09c7a2b
GIT binary patch
literal 1341
zcmeAS at N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}- at RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb at l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+ at n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn18<-kc7?=Qc8Ua<hnpheen>)I>
zSh!jkI9dYZ2Bz0Duec;JFF6%vZzj-Qs9rO?daay`QWHz^i$e1Ab6_bTAS1sdzc?em
zK*2fKOhF?&GcP5-yjT+yJrLizq!wkCrKY$Q<>xAZ!`CVki~T0%g!~QBn?g>Q=>r|3
z4 at w+Ji3KJEOo1RKJm~{D at XV8%2h1@=z^w7aYe at nF17ohIi(^Q|tu52`dL3~PIG%1+
z{qdYj)BS{nN)a4Uzgfz at U5|{==-~Rr(X?J+hS&Y0>>I9~a|+n7!)e0 at qjPDSCqysa
zelqu;f#OV^&$nmJ^%d*n=n)W<QMqBXLNn7=f3xbe`~%;@s_sSHJo4k~OgVK%Rrc$T
zR+%%`o}PbiUixvh#eaiq9=uWhwou#SM&C=8Uq&o5x)^q~e*7C)>7$^?RXt(u(xzEy
zOPU;}B=89}ep{<6u&4Nh>w+5DRCa}Vt_$zQ-(mgo)$`M{6pJ-XGfMySzIu_fqb8xM
zIo&>rjjbj2?e)nA^GjETTIn!NmEN#PGO#~*Y439ez4xkDnXXRN&Pke}eTMr4>oZ;x
zKDC3Jd3;tjEd1V+bK{)Y%G$QIDJfg_xop at z_u<1l?(CE;R_hhlnjVf9c&{M6XkYI=
z$N!Fd8jm^dX^2q>UEnA^L2H7Q^pY(86$;1V><mnqe;9lYxu>o-;m`U at 4@9nbC@(Pk
bs(gUqpHO<9rrQcmP=V&@>gTe~DWM4fDsR{!
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png b/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
new file mode 100644
index 0000000000000000000000000000000000000000..1714ba2d00294e99222f833b8cf5e33da31448f9
GIT binary patch
literal 1282
zcmeAS at N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}- at RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb at l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+ at n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn1xSBb;n7f#|S-2V*8oHV|I=Y#<
zS~!~;n_HL~7+4y?^m^tMmn7yTr^4*b1lkMLYl2s=m2**QVo82cNPd0}ECmE)<d at _Z
zXXF<sI0u_4XoP3xrR0|vYl5N&;#-&0qRg_?6t|-MTm^9WT4iFf-^84dzae^4$O$uj
zpkwqwi32IIz=VJ)5X6KheIN&(c~bL$Ii?7hH7ag6?Pg$LH1c$D45_%aXWGTy76pMe
z#*54EzIj}xurI?=?19(<x7iySHaBM<W7^hSeW!Y#j`idYMV)ys4*D7$JRonE*5IhM
zRONpX$ECYRU+uDc`!t~V)3Qvv1uJ>(TJRk9Wv+EDZnJyEl{9T%m!aDtjZ3lzucwwy
zndkU9=XRJJn_^3`-z1gDJsMmxyH<Q*>Nrw(reMu$E6&J{ZI{m9FXEiM!sA2qLEql4
zs%w7|zTdl|J2^M+!yb)}zAv@<{Ec(`CoA{--l4?RW_EbR_l}&24;eYxZZ#R+pPI&d
z%xQ`#>*>!j(GTAm-0<OWJhe&0QQ7NqNc)}Uh8%(S3rsu0FXRj4E66fk{VliT+D?am
zJVmW*?k+Ywy~(S-d0FN!6W0ZWZ4v(^pOtgWf7`vVwxRwd<J#Omaudp{ISm*X#7kc9
TIKK2Js8sTF^>bP0l+XkKJo~{m
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-black.png b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c05f00498232213a081497051c94d16537daab8
GIT binary patch
literal 2942
zcmV-^3xV{BP)<h;3K|Lk000e1NJLTq000gE000RH1^@s60!<xh00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0001~Nkl<Zc-oxNJxW7S5QgD*4hlCvSlFuR0 at Ge_ZDuQRGcH1qgN=nD*+C*$<h40h
zG at uEY>MQ2qgPBk{XD$FDVh-E^lOy|E;2qe6N<`dd=IYe8TI+0p1?Vz!djeVjuLVFI
zt6i=2>Iiylaa~&20iVF-U$~(+;0bss?Ku1Y at F9wb4}QKwE$URgR{P9UU8)c2y*e6p
ohvWRhz!<mz`j(%+o7#L0056AMLI?@#xBvhE07*qoM6N<$f;a(mxBvhE
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d04c841780fa57153d4a73f3bee69824f6efb57
GIT binary patch
literal 472
zcmV;}0Vn>6P)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0004xNkl<ZIE~%Wzi-W99L4e1`D&V|3LS(5xxKfOSt3TG2s0reX(TMQ_!VNZ
zh#xUYy4w5!VnqmI7D4*Gx9xXeu`;OkG58Xc5{txVd6FmRyg%nW5C821>bed}RaJVu
z-XEK1W at bjQKFOP^uIrRiwwF?NFD@>w`cp_<*TXo4o7h=lGtOZe`|G;?Ev(<~594T(
zsU*8_bqJG5_F)J&FwyV#r}1`TV&Z3z5gcomk6{7tsw5ARJWBF0$yk!pxP+}gLS|=Y
zD@@`{k_|}~lH5)*RpB8{;0~6s7Kd?pFc^G=4F-d%l(IL;xg?vCXak&2 at +z$eMsNj(
zunvoOf(uEWmQoJlV*92Gcz`2#-Rt!}fB!epM{yie-&A{vTWzIrd}!03$IEWF3*UoU
z*c$A?b!=&`-(z*FzuPW)(d~B27vC}v%+1XOJ8-Q%hub=j+dA{(<Ky3XehPy5`T1ZQ
zPT~OW;VhnaI-O<uUxJ`%8l{wtE$BX;bvm7;l{_m>(==7nG=J^?H}eT{w|+~olSG{W
O0000<MNUMnLSTa0 at YLi0
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down.png b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f5239bbb93ad8660f47d3def443e42b8f57c6e6
GIT binary patch
literal 537
zcmV+!0_OdRP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005dNkl<ZIE~$sze^Nw7>A$d6~#>G7g3=>Q#G^&cL#z*Q$%}FLnMWF=;0ky
z&|yo<#f2xjw6^sJL}L+>rbk<lQf`6m4I+8ox1kd>!=xqXGrqjf!~62S at ZUy&d_HeP
zq|VMxrlzL$3=a<v_W}piuaVE^O(~t<*x0zVwzk%>S4p8z=mPEn&wyM2ed+_?sd}|g
zDEv`2GBVPo-j0Z3L|jmxbYwD_l6og14yzZ{&P*orF`Lb<HX4l`lF`x89-yE;RF9}l
zbve`-b+%nN6cP8-Dsb{wNx57Obtoe4t4Gy!^@UpO$Y!%&)b|n5ubx)BBjTLem&@fE
z3kwV107|7&q?E1zkJS?@?IFtQCjrLB#sGR!N;UNca6sJv-T~w4LQ3g6 at CfJw)`1z|
zW~<d&nVz2hdHyY<_X2sKxVf6T1Uv_ZQc9<Q at 4!o-0xV5VP6BKfwPpJw;xbSN`rGAI
zU|+lcHBd|`E!OMxw8`x__5A$&`oO at zVnocUXCvZxM07_)Q+=!60+uHxCbn_E{h7JB
zIR*y at SJZj6S3RS?Qp*wXxmK&~V0NswHRI#sG at H$1z%}5F`k`8_wsvE7O{G$aN~QAG
b{J+T$+X03p_V~Q~00000NkvXXu0mjf`lS0g
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-up.png b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-up.png
new file mode 100644
index 0000000000000000000000000000000000000000..40ce708941a35d8e1578e3cafb13d330fcf37c10
GIT binary patch
literal 510
zcmV<a0RjGrP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005CNkl<ZIE~$rJ!?~O6vlt&78gOQf)-b$iZ2KSmn<r{=pcRoKR^>nFL|-K
z<P!wcpd?CfHn&cG04E2BSc>ALR0_q4C<tzXLwz0xuM%P+9mQw+bI$X7&N+YhZxw$l
zw%cuhqd)?D=yW<$dy{E}EXzXDIorAIN0Jt at ESnlU6=eH_?XILNk}lfr+Foe2S`+*K
zNN6^jGZAqXSOrdwgb8>L+_1gY?RIxYeKVtvMx(I at xN7?WaJqnO0H1(4;DGH5z`IhZ
zv^5+KzfWAv_T^%QGm=8mhNNXlHA$}}Vf&cvySA^_>-FFM07%nxFK`XWfmt9TVjW16
zBv}KHbRM`}OccO3AO%)?z24WTR;&AgMW7iGM~Z-T;AX$ye=$07nx?00KLjoTVfzbk
z2gnoK%eGs#=OiKNne7_za{MEDz1|z!4M|TW+4iBrpCyv!CC%!mp4eWr{k-4rdmL2U
z at s;he?Z=XKB<+(lALVlSxb1s at BVsAf^X*B1aaAgn!;<a;2P2}E09!x<ShBq<2*Aq9
z%4gsfPy;rTJkJGe0^5VZV7HuK`Ut!&82^}l07Tsjb=)@&!~g&Q07*qoM6N<$f&;VO
AtpET3
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow_out.png b/src/wok/plugins/kimchi/ui/images/theme-default/arrow_out.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5b4b8ed7de68dc79673472aab7c9672233bc8a7
GIT binary patch
literal 3048
zcmV<E3m5c>P)<h;3K|Lk000e1NJLTq000jF003YJ1^@s6!gMIb00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003KNkl<Zc-rjPy=ucS6o%nfjYQFsL4y`Up|{ngV{Xx_Z@^RUpit=64z(dod%7qP
zJC1#vLWgn$#=`RR`A^nxoQQC3yWtnjA3M&uSh@$`3;3RcA~LvgsO!1|0<h8C)!+p0
zJx$Ym6ucO4Iw&zla?Z4E+iL;_10e)bN>o*)3OGCHy;lcJCTasNK943~_H9lCNZE8V
zY!vV*B6lJZ2Qy3)kaK<jD&P(1)pOf>zXLkp73kOe7`uX=fM at 62UW+H82493{b9)UO
z<HH&_{#1K_l+q*cz61f>$r`o=?#upV35v)7-vY;_sGEaR_-|KF!-fqTHf-3iVZ(+E
q|3_?f604I~oy6)SRwucp{R{vP7|{U{#BK5b0000<MNUMnLSTa7ET*pj
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/group.png b/src/wok/plugins/kimchi/ui/images/theme-default/group.png
new file mode 100644
index 0000000000000000000000000000000000000000..1160bd97178375f202c3c20fef689ddf4a6dcfae
GIT binary patch
literal 1703
zcmV;Y23YxtP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU&Nl8RORCwCNS9?s8R}{bBqot*VmO`u2
z73hYPhb at ot@PRUQFz|tzm>K_=)0sIn{<XyibGT({Vw{pJTQnrgqMI>U7Ux{1;*3V8
zWNO4Ij{2AksU%LE7{a^H{mv%^EG?Kp;%!du*ZbY?o^yWpch0$&^ZWhmWi~M(Az^%0
z;+Vj5yq)KHJN_wse%}?p&tC at zdxEE4tFIe0z|Z_+)C<jmkS~+VzLm at 67Eu(Xaj(bA
z+#dIXzP`RSc&-VjM;xniQ6}2eYV~iCk&zK-3<xle<Cxd$WiFS?)ZNv6ytA{j)a`bk
z4rPQm765pGXR*52!}17ugi@&_BnIBeWHL!G#si&0PyT&k at _0P1VQY-ReTIdt9M7dF
z6bi|6BJ at z9F+xQYM1w}FDWh+O89=c7pC7?*x7!zD-zCU{l at B!nhBBMYwg4n$!P~$~
z|HBDQ;Q1mzxeuOP2GZwbqHHe~vXIi^H;V=GkXkqcNN8 at HKGr~e at Ro-~0FwoHSFKj5
z&uKK8burqQd~J-jC|VQ!fl95q4z_Ptw7C4l+V$_dh;SnrKr+Q at bq3ZR6#;@*p;T0Y
z-D{wbMMXuiNL3_LsZ`Q4M4^mSemO0Fx^DKI*{dd}OqN*h^ZAAejnn($k~e<vd3`U2
z0KBt+)gO~Wf|%G%dr3lZu2d)`V<3m87tHv6>a>De;ZUIO*R5ZB73<ZKL8Br-L`kuv
ztiXo?g;A*eB{mcJU{D<TyzHFpswvitVe`zdn%T}>J37!W&$i`cNy>u|5QA$05oJ>R
zr2O{w_CbYV8X=RHpZB`SWZJ)d=k~W+TU(1A4GxBQXXzQ~EIvN|3Z|{f&Ccrqc^z1L
zi^uJ$8Z{Fd40_ at At=nw0LPcCjO|{6gtvT&LqonS})dYjVP>5G@$VGcr?mfURXtml?
z at LcBcdiHjAckA)4Vvqwtu%U>s!kLBFLJ=xhKvY&Xzw8pe$w#VPVoT5b$Ci<K7;*s5
z_uy?lw(%_V%%x1Jic~SA>@D`p+}&YGNDI#>obgTByfW!ITv!q5R=>Bp2QXhSy<*x5
z1wTe8BKiPzJ&1Z0+-QNa%TPK?%9Kdks2gMeLj-LEYNa7bNJ_J;*^YNsuJ}4FEj6Ta
znlldu&R;NZeNLubS@~(D&oIHjqNAgUc&W%6c8D=5I!Z!mXpNAf2x#bHb=A@~>J9qm
z!-C^=*v~EXjvJrh?=L?cJyukEv6eO7Ym}HzF<riBA(8JZFuMXCZLhs_ at nFNB4Hqi6
zZd1csPg`4?NMx2WUx-EyfD5dnqhltg*XxH?w`45vD?T-YFq<&+`5*PyHlSY$p at Rk;
zE{NHrybf?5118gO at c6Fg^vUXn4<FX-*}XU7(W6JQaLNM>=L81S4smgDaZ+3hypV;x
zIfwYy5M(r=x3~8=tlf{r&cZ0^WCMjpbZ>)P6_^`Mkb-~=ggbNO*pVGi+u9Cn{BTp^
zXvLI5Rj1QAB?I8O5n1gf7L1|HMb^^<SD%Zy+%D-k5Ry`LLxQ4t)YE?=B#fnbKVPZ4
zyt8Ug)uodsYPgY5pluLD!OhboU5xGvxlA4tD6N4cLj(%se<B!(R2RVH{!BP9S4!Eu
zP>v8wUbcMMK|*Gv;zX^hvrERqdmV-rQ_UV)*8^FR79wQ<=|ANROVNS4uhnUH8I8tG
zvx;VUM+#$Ft6*vY6DJrZyxZH?D+FK}OCuxTl?eo$xb2h5GpA0TDxvtNW;UByVp0N2
zNK9lI85t}qJF^GQoEO2wr7bNj10Id(kjhCXWS0C|^2#}L=j=;MPb--?X(B@^rq?$i
zj(+(aavtImVX-9u{kU8Yu$C-BHWz2W3P>)7oYpkk<3O6H{?=W`U}6IN>hbV?r~zGF
zU5V+I3>WSLb)ib|bJY;>D~$K`45+FkPWeaY6u))bM?IxwrA$glV{9nJY+?BVwz*<+
z*NfgaxW`Xhm!L0)6gM|JjrW_HSYzYg?19tCoX!UWX|wr$v&8b`$;ktRrMf_O%OrCW
zSe`@&5GP*MkXVvak4k625bdv~yMqQG9X`8G at f>s9X|P}{9b$!8`h}XZf7}bXK4dL=
xz7t?K_Pq&p;n{h??+d&4&l&Ktujl^>FaVgriY_I-t at r={002ovPDHLkV1m5fG0*@2
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png b/src/wok/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
new file mode 100644
index 0000000000000000000000000000000000000000..da1cd3f2562a5905a526446bcc8fc18bea06c734
GIT binary patch
literal 1034
zcmV+l1oiugP)<h;3K|Lk000e1NJLTq003?P000^Y1^@s6R_JLg00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-3t>283nlSO%wnC03B&m
zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E at cM*00VAGL_t(&-tAexPZU8E
z{`PW&1_K4^OH?eZvAftnL5(5A#KOeLoryLc6xvbn7idfrLqY*-qLqe%L|Ypgg$i36
z(dbjkBSwPpvl)`j+}`fa-u^(2muzw~^LF01^X{8 at Zysm_jzUN2Fh`A~Pjc5hKFL~I
z+Z}W#NVXC{Y>}KuY7;pNNspw5tO0f7IFeP8D-r4|QCJ)u*CII!fKd<0S(2@?9Y=DD
z<R_9!@=PZG-V7bLl9r_ at 9LG4P1)Rq+9Y?Z{<af)|`7qr|9MBxV)c`acbbCfT&pQC{
z%j$mX<hUFic+YA-2XN6mak_;`9K$+|XK?mUTkTPj&CIsEF5cU<hDHKoBi7iJvbM^i
z*Tus8!czN9a>$8s1<N-8RRC8_`$GnE?vb2Jz_2+0dq-p)ngI3#?S24 at sTh|bQ+;d5
zH%uEL`5>TIAzA4bYua?6Ovagcnjz|Ai5Da5sM6$aQ8E^l$E3xZb^24#IlFC{{Sv!X
zdPZ`HoHhZhMyRZj95%WP!xe at 3m<5`5?4yL_;89M%??>JmIN;83>nfaa#_lVU`y{Vr
z67H9I<>i9?7&xxqKI>29L{6meTNYI%0Emdw!G8E&QVE-1Rcq#UWYToK0q{&jHq+Sd
zU}FNnI)H(=d=J2sh`dW;({;UEMO8gxC-hsZHn6+_8Cz8V%OQ7`GXQ2(brnD(BP{Cx
z=6&CP5~WnH*XNDysWO?Qs#^et%pdJCfS-x(Dpi%PY)T=^F&E8^3~dd>ISl}e&Opgd
z>jQ8Oz$E}@0sK%^x9UJ%4m8_i!$G%aL_`u-2dYWWvJAJ-u<F2q`TaRWw_eh}pDyEv
z>yyFRKMi0z&>mIQrid&iVqA_4oV3~tBC;bQJ7_QMEcIHnC?X#LytKL>s%r052kP~D
zY<0ls{5RDBFDZ*`N~hftRMj`pW7t-CT|^!ky^4A7udB@<*0kwB7vI-)nq=l_0(fe5
zkBi7gBF9Bcoc6<NF-#g4k&RAyOj^9%=3_<YamMC0fYCtLR}r}oxmAjYmj^hLTt`+1
zRCTyh@)?Dxh{Y^e+NuMpIv5&N7WDCVBl5M=0B!+z9Oa;-3`iRt9+5!hy{f(jFa_X-
zh^)1x14RNBkv{-#tLjpkD=*u5$B=13xe4GPc-8~JKL<=Y@!??g0{{R307*qoM6N<$
Ef;%S0RsaA1
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-back.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-back.png
new file mode 100644
index 0000000000000000000000000000000000000000..eca9948ca7f0c4eaa3c36d20e4fb2d72ac79b2d8
GIT binary patch
literal 244
zcmeAS at N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ-JULvArbCxuSRn<C<w3y#71eK
zT)K72v}tTjuGj8VdL~>5 at BMC(b=2TTSM%q?EFRVyo~rsxN}a;s^<!54Nr^X)q~g at x
z^JN^q%lN$@{6O#y=>_6_at*5DZ*m1wnKN6b$4D%Y<YV4)Sh2y?LNY=0pS;7ws8U8N
zRxu8ago~UK3wje6O$2ieNH=}5eE-k*!lQ-zA6s=>GtE7+RQk>%v4gUYTRgh7os8Nz
s0?gB1y)!t(JaL}EzvtS*278#<8D&)ztBkXBf!<*7boFyt=akR{0KU{)8UO$Q
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-camera.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-camera.png
new file mode 100644
index 0000000000000000000000000000000000000000..f181545ed44db658aa6373c28ca33724f84a3d05
GIT binary patch
literal 4860
zcmV<Y5(DjtP)<h;3K|Lk000e1NJLTq001oj001Be1^@s6hJ^7%00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000OlNkl<Zc-quhU2GM{75>hdnVq|LuT8-}*kHi?*lw|mkwt_|3oTMnkQzm$YEVU^
z76l|K+A2mWlEo8M+b4Kv6jjPYr55D{TBSmLX{AVQ`cOg=g{F}bYQmo)XhX4$@x|Bs
zGdt6V%wAo<fRRz!9%&zT_v|^}oH_HIbC#TQ_<s`#07P`}a{|Bsl-F?pjK8eE7XX?7
zbOLDedKSPGfZJYY5rEHmT?1eozzqP?{vO^(1wh%`$N|&<%m7He&HF*mAq*e{umnKl
zKfLX))B_3tED=Ji)ms0Qhz9+)*PL^|1~B8C>tyC{0O<1XJ}}07D at l?&4S{I_(5aLf
zB%(5al!(T&EPKmZJLP at 3xj>VTMgTzjt63>EAf@~!5s`E5N|t56GR905iz1?qAPAmk
z=0PbXm>JAGon_g{+1c5Ih*m45zAS|3VrBs7&-46%we}}jmK6(Mq_zHvlya1a0w17E
z2=V<|t at alm`Ltn|>!6k2#x?+ph^PWUF!MTQUMGY|0cdM&kF|CNK<J!vLWp)|ZVH0n
zkL7Z?*4*42#Bn^GB+2)rltG^7QYm$*R4QGGqDZ7^nx|>HBu&$ed7h_!Hw6)OF!N=l
zRF#=?0HrL;mJ1<z@;tBkl$!#O0LaNX2O??*uu>^Cq?CFNz#4B1N+}xzLC(x%j6s^F
zWQ-wy7KD`2hGCdQQDmi*aL&mr%fi{&SvJNvA;fGLh9(FCM?^5j=vu8twOY+(Sw;Ye
znW42#OQn*LQUU-QV^kc+NRs5bG3M1cj(=aIXA$YeK at e<}QobmJSS5r25rLTz1Ob8|
z05iiF17=2^=kSY#loCM at 008nlujido3PK1lGl&S*+PmJBN+tM3-sMLK@#&#rhG(|5
zQpz4FW$DhHJFhtB>gl1Sl+Q{jS7@!FwT6_k4!m$IrG!!n&bc~hB0{mqI`w$nyXdIl
zJu}w<H$E%;6#9M#V2tTZ({yjOTKz46xUlS)xm#<^Q4~RIeV2hoQA*99Po>PmFieCH
z);VXbwG_v(%Cf99Upvk at SZh(KRF(l)4d8kK+6p1i80CeC*4nIJzkYnvrcM9exN+mZ
zT3cHu0nAQJOxSbh&P8X=oawrB>CzXHBx!w=ts>$|DfaZMWW&q6psj_-(xpqQd-m+P
zyl>yWzXSLXz}o;Wc<SodwryM2$jC_f`0?YbPoF;h%+%D>m*!*F<01f5fKHfMJfJ$x
zTb3_hK6Uiy(RYW3hu;M7G7*IU+QTsXA^=X)^kSap?*jP5IX5sgH1wy#hYuf)<M_Ep
z`Sl#$3_uj1?*OP0k at 2V3H58pkinUg@w6x5OjEuZDJUsjdB6<bDK&4W78o*WnD*(ta
z3~yR%&!%bmOCq}HoC|mF-hJfc$&+1anhyKipDV992m<o8gbUCz%d#Kmd2V}qdn at H~
zSy^kH-xhiRP^Xj<-QC at t?d|RTy}iA>ef#!zi0BspHdQK>LjZOVQIim&pt3dA+NXpN
zLur~GBBJ-5bF-&To%&8oOUu?3D^@6Groy*B%-r7I-qzXKDFIvqFjEwl{^sW9mztWI
zI!mQeLPTyJr<#b!5s_+ZYrAsn*s<5PY}xWVB3ctg(IF!Gu9T9r)^+|RBIJ3FEXxqb
z@$0o(?fE20CYX6~M at Pqx!Z7?g5zWk%(nNIm!i5Wm0Mv>|3nJ<_#&o1<`q+7$B*|n?
zPtV6hB!eLMJP|#kl%jIETrVQU0e8+J&vPiHb};kKBuQR%&hgC53;^^!h`E?~nePTo
zp^*bfgb?+j@)+VaY}jzEt*wm#l!OpNLWrg?3{ftZp_IDMUQtN2)-Q~YkH0}gx3Vnz
zhqX3gW<3{!X{{ZA_Qv7 at B0>-Z&{{thXlBlvnwoC<{ue~lp_EdMRdp`z6+$2k!)0+C
zuLLk|t(_sFNu^ZhT+!BAlW*+!F3<&$KMrUjqKS!#qG?Z<xhkc!Qc8Xp=Mxdi<+4&r
zwfeTWWUVbVaPnL{{b}`H=;-5|6IZWZZS$aK0K6rHF!L!=eSLkO2q8*-YFX}_TWqbx
zqej35g9d=f$;sX$M~)ch9A{bfx^wP>M>*D7rw0xkI1k`55w$XN?|h5f69H|l-FV`}
zi48=Q1VM1a81o_#{qteK_wL>M{^re_&lAy at 5Mm88Z!1#sQNW)FXl7odl=?vwMXRdS
zs<?6E#z(t$?HXOSY}r|6HjTR7-QBlGM at P>cJb3WW0FDFb3xeQTDdpPv_CE4Sfc6v4
zjwp&o<2e2q5#4moof#V&%g>)b|J2ynSU(Xp_x1H9gM))Ny1TpIB%+rAY$}(_JDK_0
zMX&yuf|gQ>FbrR4Zf*{yr>9>cqMHC-bIzRw(39u+A|b>CfH#O}1rcp6m&;!zq8~~r
zL#_2^3%Z~rt+k4xXfJ^EaUB09P1E;;5Yx`N>j173QN+wU!!TSag!meOr-cwQ3`2xr
zIPX5bKDp3BdeVjwD-1&du$h at RODQkrdHy#5w}>bQP$8l|0Go)2rIaX at N)N1 at bGd2k
zr{jBnh%6wt>lH6al66^@tt$rMdnOSCL2zGh@(|n7_a60r`j&I<Z2+sDP=41ZY-0?J
zF(`@#GeZagrBq#SKAYUq(lQI61Hgv`=&6B$fuF~5ytZ1c4lOWK>X9xQuwr^|%>ViD
zaUoq at UDNyb@Bhe``-Hr)CIHI;Yy{Bn|KTb8_k|jMY<>*juK?aDKo|Ma=G(u>uj+q6
iasaacZWe!B|1$t|HV7wlk?hg{0000<MNUMnLSTY1+a*>2
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-design.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-design.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8931dae58e4d3d95d7a1ebba04ed0481f4b74ff
GIT binary patch
literal 4562
zcmV;@5iRbCP)<h;3K|Lk000e1NJLTq001Na000*V1^@s6WA5#n00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000L4Nkl<Zc-o{^TWnQX8UFrt+1GPz5zood4q!Tg&>;h+8I2`E6iK+GFHO{#8jzq5
zVoHpd5QCQ&HBrDABFUu22jYW~KtMxa3_^sqv;#C515}+-N()SZw&%2`=eG7<%ZJ&g
zITRQsx{{Ubo&B%<f9wCh?^}!T^1%Sah-f(xB>-5)7(qk~00B_On8(JLNdPqfJ`rVz
zXgL4 at zyQ$3m=Hh(K!J1qIFrc~jWGZK&N-&1r?IfGu$WZ50+5qPB)-o%|2%*MfFu!l
z04xATDK)fW#fq<4mNhXvJZ$;C{|zbS52NoIK-m~G4<H`|!9+Hj{n^OK$hF2Kd-v`|
zZ*T9%0%QOv#@HLSZNJGm2N5k!tu<=3ns at T#$y94=>!jy-CB|6MvMg6h2_oVEq%kI8
zjLB)OUthCk&2IoWQAPEmM~`sl&YkC~@KJyQ&iT8Z=b2P0h5Ae+5{Sp+PY)b8aHOTB
z<pTin;K76Ca=H8m*LDAxOeT>|r;$u17uPIXw(Nt>&dx~y9DuoZ?;g6ky3p6x_pt%h
z$CMDlSeAwQBqFR at wdzD?XXkm_w&xEWI;3W2XHl(Ir}O#z?-^qcIp>g4!m=z#DG`gs
z@>{oVEdbDW at 7^_CU0vw!?|&}Y(w6at>HvTV!?3KiHd<?N&S8v!5CU^^bH#o8_RVn4
zaq;3st6Hr}09LtNj#VlZ?Rg#;V`w07KAX+fCMPF@?c2Ark&zLq6Mre7x at sH%UIeNJ
zpbUT+W2#{oF8&w*7-J|D3f~$Y9=<m}KmT_ChKMZ7vRYi%{cgEj{#3o1i#z3f;o-xF
zs-vTWjgOC~qr8<UkE#O`0Bit^h?cvq`vocGW&lsi<?^Xot#;2CqhHiVBFbelncsSz
zH&m at w$0LjQEa!Y>T>uTSC=?2{b?equW at ctq#A2~82_fDx#{8>PD*Z_*HRk(15fMb>
zAHwsz?XK(ol!%%cW3X*|Td7n!%ouya7(>sn-55kMek>N-ETu#kh9DwXmIc>!!8w0s
z17R4h48!n?O-)T-2k=$Sxy=}Z5aRVP41X{%Fz_^+&4P$%6=N)wN~L}$rF_eA99WhG
ztu-o@%3K(R(sf-o9*;wa=UpNQ0w|@RwMLWxLWpN71OQrVy|A!QC>D!p0I+QvLI_Mv
zP2tR$Ghf-XY17~8EfWCZLWnm#&x7y#kWxZx4a>3;N+}2-z}SlgSqD((*is;kik4EQ
zecy)=0+wZgbB<D}1R+GS9wPvh02HN^bB^PDqE1B4Ic(crl=;g5HS*+D-x*`@eIJam
z#rViX>+I*u81pm?!}s&~{HeyiN1V86+x8G+%;5hVoby5|m3qe*Q*LM at 7-LTuV|f4)
z0Ap9LUabrc4i*j{KK!fM+1XP{sX!@JOQ+N4dV70&nwpy4R!W79vTr1J7=~dG1l1r2
zYA=eZ$N9eh?;}T!9BON8`*E#S8&^s}DK**M-TjNUwzgY!52U(+lu~STbTl_GFtFD5
zeS61_9b?_y-TxdK8rqdeB;K}dn>V&iYmH<wd9A&@{m-jcuO55w-~qpK<;uqC>FIA0
zQEDlmcszdT!i5XnK at ik#-MY1+udna5j*gD$4I4I$an5G|EC4XnuqzfBp+!UjKy~ff
zwfz45``^oCGC%iypVd_sh9NA=8a#IF*pJ%V+eacJtzN!-S?}Jx``b-TO~0lFQW<05
zIL^Cg&z{}h+}u2GK1^ywAwjf0TzZyi009w|0L*RMwoTo>ecO>z#<bQ;Jq5X3?yt?w
z%{KtdjE;`ZT)K3rxOwyD;^W7UuPUYfv$TCmsbqhDzXT8xQI&}10nA5E9lr1^o0you
zjT<+R$z<^4$rA>E6VbBhXjvRmN{o$-CC{HfzmUu2)UI8-D4)+u0G=_XrBo^<W3kwx
zZxIoKAn>nUyXNiOx$`3hvIuBqW(GYyJve>(^fN7FjICmf(bA*97_)o-{{8>hxN+lO
zlu`g-Nhw#muKS%@t at g>KRW-)M$H&J%4PYFvxD^5b1_uWl!PHyGf*|;e)*6k|7z1NW
zb1Iek$?@aIR~|ij)NszZ<2YLwV_&Y5Uu%sp455 at lrBaC%i^cZnHc79n(E9c3apJ at Y
zIF17Vuq-P$ckW!_`t|F-6heH?7}F92K~orpZsZxJwYBwq$8p>}d-kxNo}Qvo>OI at G
zhoqEgBGN=ulTsEFiNsVko1NIQWy^cfT57oBJZqpY^9}$sH#bMKv$M9=x>;+T(ptO5
z7(1%0v2A-Mm&;9Y&I>nh-c&*eUkLFU=RD0m>~kGd+4H=)bUIxWLX-eh{}(`rc0zSN
wHM~<pTXiH|G{o?RXWeiSGm)ZRn)JT|00_?=SoP}gcmMzZ07*qoM6N<$g1D)Tga7~l
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-detail.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-detail.png
new file mode 100644
index 0000000000000000000000000000000000000000..978df03ca7480d0f9ebb3b4f1a1f73226fcbe246
GIT binary patch
literal 3079
zcmV+i4EXbjP)<h;3K|Lk000e1NJLTq000~S000{Z1^@s6ZwT)!00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003pNkl<Zc-rjNKTg9i6oB#Xy(D%}o3>nnl_4EC2vUxQI+vN_AT9x__!AOR{8;RY
z1Gt^yB}1fqdbWR3#LT$lDgi`f18jgRKr?<n06p*yd;-TZzG$3t_o~{RVW?ncyKx-%
zfTdtr6h$W at TUA9wvKGy37>3~ys8aA(L~fjOR8 at tl<__KhYv3ydCsloR&fR(Mvrkyp
z^$Sn~LkjjHa#U5$v8B$r67Z*63Vbw8^WeR&7K=rxs#%H>SKGEvfB-?v3=t7CtAJ}@
z1r(WvlgR7`H~@zfTmws>O6Q!>;deAR{%5iB-gm0no#6~a2w~Uv{T`T34pp at ik*$bi
zzci{knAz-bb~rnn9nKDOI*c5e=x~|QVX`;?ufSUhYK;2$%(<rln4-f;F8$~IHvo#L
Voc;M?!D;{i002ovPDHLkV1gS<wu1lw
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-iso.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-iso.png
new file mode 100644
index 0000000000000000000000000000000000000000..d76290427e75fd1c6ad914acde114e065760b30d
GIT binary patch
literal 4188
zcmV-i5ToyjP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T700009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000GtNkl<Zc-rikT}+c_6vuxp)*{H47Ga2dNXU$JiP1HacmXp;vuWH%;>DJzOqc9t
zORRUh(aj6JYZu1NGEnqlTc(le<YJ3sC6S<16qOPXEmm7BQf+BV;Vtd^?1Hvhq)><s
zmU)t1^nK6!JpXgf^FJStLI}Y^79|T at 7R}i*qq!W|47?4j14 at Cs$m>C%ALs(E0j)sa
zRO`rk-L(5CW*cIq(Od<5T%Mi!)#jB;*_fBky5&nK%~F$>rkX$(7^i<&qU*^h9fKpZ
zI{fr`#=Zy6$$Fh>Hv1(FP-!%;20pJU%=r4F@*H-p&Y?JSaZ=yfyg at El-8A;OG1+~`
zfjU{QvnKVi5Msuk!qC2>tp27rc6C5J@(0CS<&i%qj$IuPW%W0O!qC1WnZ1(%w}0!|
z9&yp?7B5RKTHRvn*&d-VwC|sB|7eJnMsqIk7x30R6Soc6ChK+n$!X at x1pp490@yQE
zn#oP{#roVdvehYgq%fUB0RT!e)s##@lFp$39w{9ApRG<|eQsKu&V6r?`(9}}kVUh~
zgNCXistPkO*?nv|(?dz7n!}q4sMcy;&^^@hfCh^Tj}#_bokF!%gQ2o0PN%`*;^>uu
znLy6HlI&Z%JO)l_G@~?{*>a|5!kEgUn8%+7x8+O^N~0NoYORLDn+hn&RR4RW&Lf2}
z*?pMoK0H#G^|@(r;7oR3%%CX9eQTG$no?);O`M^UOf^R~6##Im`$^1;09Az<^H+--
zEG_`{uGO$ltDz)QO>w3gn^)pg_miZ~)+=uo8Z0gvEH0|G8uqT$uzp1v)mjb3nQD$+
z8JJ&yRfQQ;Mnd at Ql>r(oE~*MMXx_bsYORLT-LCoV2P+FRI8w2aBNZzX>fHARV at JVI
zRTRsG&AZnCV6yvYi4f<dd$1+K)~MH_2{{`2Xd;e=x>~E@#P(7=QaF}RkG45t%uW`d
zKatYuZWk>Nz1V!gnDw+dXqm*+^LO2GB#DBwJx7|Bhu)Zh)5y>Z{h-oleiP_k0AoNH
zD3tX&=VTA|0&PERE!n(bMcRz3{M_>t!*%CRfMEvJLx(oxfBMOqWizgM{c(UVF5Pbf
zoKrTe3PXEsZRcQ8J>3JZBtATUM<@*Kd#33n_q^ZOD{NjVsWodm2Zh4WUi<tSlSy)|
zV{jz7SwR6Gl;t1`aaw6KZvg%PIwG$(0^8p!$vU{JEQisMi~tlftQpz++H@>#ZFTsu
zd4mb(4FOm^63)Ol<vFQ*Q&GsftFjLMX&XKmHEv^GI@^k~cqcy{8E}n;P%uV$PHIAs
zHgAwtho8s<n0O{p7}{%UZaAk5K}eQ`#T5{j9X at f{;S&zu^z+GBNEWRT-OCQ2xZ at rb
zasu6&8&07xwAW0=GZkacHTJo2j*Q1W42A`_hDLEmn$e<+#S|=6O&c<Gih^aS&w}(g
z5aO<9>;*mN$T*FCZh&($RuWmSGnwqZ<0mc8%2gmFbITPV5Rw5XNLR5cBe{|Djr4dU
zCP2nF6DKV$Om^S#sb=OxIj^q1Ylx<P5ALxLw}t{p;fZ{ipQfTTOPzF5%TlM1u8QAg
zFfbki+0^f$zH11eF6mk<>vdM^u(Z?AF-YS*HxX>)E?GobwtCi?cd{3wAb+=d`0n~3
z)?sO9qCq}k)sXeNroSJ05B$>ml%A)fEKglTc~0t_N<;1v6)I&sfBT0ee!TsdzaDrG
z$a-DVT$_axmuz0eSV*qROINXG+1vms6_A&v!tS4_<u at LW@Y_8P%@g2G%(<J1+&tAQ
zjb`V7|G~xEL!*4A)sUaAnp2o>y8<*n^l{;y8|$#N6KGmcmq)+$KBaZQe>_46>;LQe
m?LTvY`TCCfHNclF{|o>aAZz-p)g%r80000<MNUMnLSTa4!QO}f
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-list.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-list.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b3b595ffce5fab49dbd2588cebd113922b9dcbd
GIT binary patch
literal 2983
zcmV;Y3t04tP)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0002eNkl<Zc-rjNF-`+95QX8-*%cTPAqu2GfrJD!-2V);oPd%7I;1GO5R##>F96Fn
z_%&nC6rS<>i%Ah-PA$x=9#TqoSm7NToa17mh7NecE4F<}b~)!K7{@W=Ea&_<<z&M!
zbm-~?FSQU6_jvw;-+aKbFOTeTi%awovBnLqa54cWQDce-DWzlVBVtiJJ)py`c<^II
zM2Dkt{j45dW0g{x9GcR6g(ey_4Vnf`gQh{#plQ(j8)%BDrzP(2QO?V{yZ(k7d|``C
dntRp%9so28)jylt{44+f002ovPDHLkV1h$EiK_qr
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-load.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-load.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ad195ca84691697a63e720003fe48b1573590f9
GIT binary patch
literal 3678
zcmV-k4x#ahP)<h;3K|Lk000e1NJLTq000;O000^Y1^@s6t-qY}000V4X+uL$P-t&-
zZ*ypGa3D!TLm+T+Z)Rz1WdHzp+MQEpR8#2|J@?-9LQ9B%luK_?6$l_wLW_VDktQl3
z2 at pz%A)(n7QNa;KMFbnjpojyGj)066Q7jCK3fKqaA)=0hqlk*i`{8?|Yu3E?=FR at K
z*FNX0^PRKL2fzpnmPj*EHGmAMLLL#|gU7_i;p8qrfeIvW01ybXWFd3?BLM*Temp!Y
zBESc}00DT at 3kU$fO`E_l9Ebl8>Oz at Z0f2-7z;ux~O9+4z06=<<LZ$#fMgf4Gm?l#I
zpacM5%VT2W08lLeU?+d((*S^-_?deF09%wH6#<};03Z`(h(rKrI{>WDR*FRcSTFz-
zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8
z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc-
z5#WRK{dmp}uFlRjj<yb8E$Y7p{~}^y<NoE(t8hR70O53g(f%wivl at Uq27qn;q9yJG
zXkH7Tb at z*AvJXJD0HEpGSMzZAemp!yp^&-R+2!Qq*h<7gTVcvqeg0>{U%*%WZ25jX
z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq
zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S
z1Au6Q;m>#f??3%Vpd|o+W=WE9003S at Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG
z3;bX<ghC|5!a@*23S at vBa$qT}f<h>U&9EIRU at z1_9W=mEXoiz;4lcq~xDGvV5BgyU
zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi at a{RY)E3
zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q
zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF
zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv at SV$}*
z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C
z$c5yc<iq4M<QwE6@>>d>VnA`E_*3F2Qp##d8RZb=H01_mm at +|Cqnc9PsG(F5HIG_C
zt)aG3uTh7n6Et<2In9F>NlT at zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c
z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWw<V8OKyGH!<s&=a~<gZ&g?-wkmuTk;)2{N|h#+
z8!9hUsj8-`-l_{#^Hs}KkEvc$eXd4TGgITK3DlOWRjQp(>r)$3XQ?}=hpK0&Z&W{|
zep&sA23f;Q!%st`QJ}G3<GjWo3u76xcq}1n4XcKAfi=V?vCY|hb}GA={T;iDJ*ugp
zIYTo_Ggq at x^OR;k2jiG=_?&c33Fj!Mm-Bv#-W2aC;wc-ZG)%cMWn62jmY0 at Tt4OO+
zt4Hg-Hm>cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP
zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By
zLtVo_L#1JrVVB{Ak-5=4qt!- at Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>=<rYWX7
zOgl`+&CJcB&DNPUn>{htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2
zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd
zlf9FDx_yoPJqHbk*$%56S{;6Kv~m<WRyy9A&YbQ)eZ};a=`Uwk&k)bpGvl at s%PGWZ
zol~3BM`ssjxpRZ_h>M9!g3B(KJ}#RZ#@)!h<Vtk)ab4kh()FF2vzx;0sN1jZHtuQe
zhuojcG at mJ+Su=Cc!^lJ6QRUG;3!jxRYu~JXPeV_EXSL at eFJmu}SFP8ux21Qg_hIiB
zKK4FxpW{B`JU8Al-dSJFH^8^Zx64n%Z=PR;-$Q>R|78Dq|Iq-afF%KE1Brn_fm;Im
z_<DRHzm7jT+hz8$+3i7$pt(U6L63s1g5|-jA!x|#kgXy2=a|ls&S?&XP=4sv&<A1W
zVT;3l3 at 3$$g;$0 at j&O)r8qqPAHFwe6Lv!Cm`b3sQ-kWDJPdTqGN;N7zsxE3g+Bdp1
zx<AG)W?9VDSe;l&Y)c$DE-J1zZfw5a{O$9H;+^6P<9ipFFUVbRd7;k2^o6GusV)*M
zI+j38h)y_^@IeqNs1}SR@)LI at jtY6g9l~cKFVQy9h}c71DjrVqNGeTwlI)SZHF+e(
zGo>u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x
zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote
z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE at iwJh+OsDs9zItL;~pu715HdQEGA
zUct(O!L<Qv>kCy1<%NCg+}G`0PgpNm-?d at -hMgNe6^V+j6x$b<6 at S<$+<4_1hi}Ti
zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B
zJh;4Nr^(LEJ3myURP<E(R5tF?-L+xY_- at he8+*L=H0;&eTfF!EKFPk at RRL8^)n?UY
z`$_w=_dl+Qs_FQa`)ysVPHl1R#{<#>{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o
z4K at u`jhx2fBXC4{<mvYb-}fF3I@)%Od#vFH(;s#nXB{tULYnfLMw?Tb`&(jLx=+kL
z(bnqTdi+P*9}k=~JXv{4^Hj-c+UbJRlV|eJjGdL8eSR+a++f?HwtMGe&fjVeZ|}Mg
zbm7uP|BL54ygSZZ^0;*JvfJeoSGZT2uR33C>U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0
z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ?
z-G|jbTmIbG at 7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd
z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P`
z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000SaNLh0L01FcU
z01FcV0GgZ_00007bV*G`2i*o42M;+N_sXUK00W{)L_t(Y$DP(|h*eb-2k_rL_s*zU
z<1`WqI@*IQERZY+ih*P-NXniRVSb59`_jWlR- at j1HLZ{kt;nbkQ_ at rDL0M#Jf)+&y
zQ6lB5am>+7%O=4XXXf-}-#Q)dkhtKmIcM$lU;D20|F3-u{>MTH1(Yxb<59$q_#uRl
z{$G5-NmvMB1fIuD at zV}m+uPT-tFf`sGb>lxvu97u*u=@%*_f1hKOeW0ip7T6vu0^-
zZXPf&8K5M2E5<TqZ45?MDwV?K&6`gyK?tFQQV5|bgwU9A^~Wb4n^xmO2uZC2CK>P~
zp7eIC!}<`yZH<LGHNfFGenBJd#)~0@=@@iEf(-brcovspB33+DZo2 at -Y9#1cwQPAe
z?u!Jt3ooNB`zw;ndKsR?unfpZToc)rr)2-kxeqnqsvIjH#k7AC#M2MO!x)_d`4gwr
zXfT|PCTy=khy@{p<{?ePBq4<UNWs?J#=r0-HVvScA{y`nKF|5aVcNd6n<OEGI$Vu2
za+|)vT6{f#DEnfPgP0i`p0z0}KYn{`f)SXIb9UhqZ1~{Qb;nT`!Ll~A+M5u<R=k??
zPr$?^)^SYE`8~cv$E4O)*pK`ys7EQ4_Qv-OHT+EphTzPcb4LU`ws`&m*ozgh41L&%
zT{xKG)*&3uV5CS&1E}-}ensD)Qk}@6^>Muz`=S{49XfnC+w^=HmCzl*8ZzITaOAqF
z*Qcvit<u)k*0W^ElD&8XgQM`eTU%TET3TAF<KdjB>Z~S8rO1NaI4|RDLEX)F-l22b
zcAcG_mM&e|gWq7ynl;+n+il#qQ3#<JlTN8IN`@3hB}3e^aNc6f&uw at lgzyy9*Vh|9
ze7H1CB}t;YyW7#DN2?<SZoulutg7wA^5nuBC&Rlnc-$63m_A6Nr>Dn^88Zq84jj<c
z)n(3{IaU1>aAh1ZLv!&R=qiK|3O{e#o{k<rZUyeoZTbVx;iX8`G}F6b at rIj=vAMXz
zcm?eV3Qxbe8XnK6wra!h7&hVs%)@Lf!-rT|1H2#KVheT`(lk}6REi7B<-SFg%H?<s
z=Q=g(j{<!Qub0c^j%t(o7gZ|t*op_ at dMe;s at jl+GD!-7X|4Ok^sSJu`nSgsSImhi<
zmg4sa{t at 26_HwzLo{%6WDMg`;!WEc`OX4^wW<YzR;(v;h_cMG^E|>TJ=YLT?K_<~)
woP~?xZ8tVjF^Nz0PTqpA&`~azd-FJd12*I@(BIHxlK=n!07*qoM6N<$g48GX-v9sr
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-local.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-local.png
new file mode 100644
index 0000000000000000000000000000000000000000..092026fbc9301b311d5e9bb8556450cd6fa93ff9
GIT binary patch
literal 425
zcmV;a0apHrP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80004SNkl<ZSV!%a
z3vt3g5QaekH~<v14oDTWC}^snNB{>oAXQKt6bFEU4h~uc at P9LR3`t0`$1CkjcIF>Q
z*t`919|`SN&DO3teyag!GGNU>tY)1DHtd`Hld3fqfJmEsRc%!8`;+c3%hpx_Ji6dr
zeNLr`5o9L6cj-q0VqLVZ41l1V9EcBzGKAPd&d)A55WwWD41m-PrH%9=eL5Hm1ScLz
zKs-q71%w$Ok>{)QEA=H(%5{jb2W11MBXLb*rtDM(VtLT<1drSXA%U~LlyK#4<|ZQx
zKtSK|rZF;-`9tBJnv7$BY{yeSU}(lm%ufOkxykSV*^VE}`TGjNJva~pDUni>;Q^NV
z!FN1mI5{$xq`|G_pu{>%1^`eUcl at n_d;Y$@93}&R-4#xD_7?vNfKufiBn3yO<4teR
z&<t20%)x;V1vtCbMGG5%Kal|*JiIRJuq_#g+|#gkXM(Nb#Z~_aZ_d;J)SiJoPBKc^
Ts5X1J00000NkvXXu0mjf;iIrQ
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-down.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-down.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c653bc6af72f628cea721d618849d912c1aa186
GIT binary patch
literal 4372
zcmV+v5$o=WP)<h;3K|Lk000e1NJLTq000;O000^Y1^@s6t-qY}00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000I*Nkl<Zc-owneQcH09mhYvbI$YJ=l0&)dwcr=SST;uV4zrVux5 at eLPZ9PLl(gq
z;uskcT}Gl)F_>X8MUX{IU at UHbY-?tw1~Qm245J%0p);bqxY9X6-df(;Vx_c~+xGT8
z=j at N(ON!2D_Di0Bo|E72`+NI-&k?@ZL?dRrDyd0erdgZ at j-9YqKkO%TU+DZL0GOak
zM*TLJ`NC+4EGb0%=%w)7!pLLyoJ^%s{Ce9q+S=OqzipN-t3MKJxZE1Q-JOXqa3}o+
zcVWRJYh6Apb<Qzo&YaKnHJ?+}b)`p9IuK>j;uA$-0VY=0pw;N7H*Dx at Zf<s87Qg^f
zr;-VU*dw;5XBbhehgehSs2~K<sOsqIbh~%&F8bNRcU^)b0aQYaUhPd>+F+_40_13T
zW%H)ou^oei_A{9&J at n4OgPo@jA5J|LnRZX5__H%E|JDmbr*@vQ*?~_3C_vxuO}u-V
zH+H*$WPqktN4I8c)BoDlezbpNaHSL%J34X?E_<x^myx<B=9uzl6re;_PSvH8A00UQ
z<cGG;6$1mPySy>8eqe5R)`%o4RD at 9~Lg}C#z3SmLca$XJ;+(rywsVeXs?=`y>BFTr
z4tlp45z^vQA->GisdYd1zp|VWnX5 at E7F*%ftc{5tTOmG4JpAksiD|Wc!EG~265^Q=
z at p0A>jmP45-McIuD~TPivK~qCNMMMe^#U_${SS5ZxM(_w0_;3pId_7 at 8xj~wF-R^C
zHB|#8zkBE%^R=4&elGkBU&2hkE}uEIbl{1lo6cps{^=vQ!h{oICO;n5EI+?zKWelD
z-aJz|-xEp1m4|WyMiY7D?t}8pX?vdEwE4ZB-YbZRj9g at AZ3yT+`HrsFxcGpD&f>9l
zP#%db3XC^irNkRGL1J|QiU<N>h?+X?g8!3+Zvy-FzW(}9mVQq}^fiFIMIv4dkSN+c
z#l_a+HuL9^WQaOlr=8rQ6q1gKt_jd+1o9zjM(t4ozXdomx1oV7_F{N7(?;GxE)PcV
zzjLz>7zKHN{bBdM+%N?ZK#TYyq?Hn)5m9Acu>;N_<ElOa+JOG2f3cpefBnnZ)T7I{
z+NxxyR9A$N_4l3d7uBBxx{8!K9A5r-z=hq#Dn!Hyq6}aS%BteViV$At?g1_VVZ?ZR
zck!LZEz1AHtzB-!ag&rK&STUY!1<56yNA1m(}Or|ao2Vqz&Pl2xJwF3hyNG`-)>FE
zq36(%!|uHU at 3Lyus+{r6S*b|A0t7%m(A(VH9R6neb^w{85)(sgY6MvXFvjA#hOnm`
zt`-E*3Ul_-x0`;n&inD9U9^92oc8v1Hg4RQ13m%RxpOCtjg4fpSpe;!g6TT3=$igp
zhm-_EcqVFkUH<Yp+kc=+2lI;)@<OI}y!hJcc8+fb*s^5{jg5^s=TJ(~+uKVflPMC_
zt?_H`7(;Zik3u83fkE`_$(?F!#en|Cl7(Do`JnfEksB5}hyz$0ll)ZuSXFXvU;a`{
zF3gk3WF(Wx(AU>TE|*io%@kJp6TY?7tKL>B-k36F at a(Xb`fHXP_U6slr~lp3DtnK;
ze<6RQb==fQd3|xwtPq*3;`6?$<B1{M=@a&9KcEW&8M#>{(?9cT at 4M5Cc`hcVHZ4AJ
zF-SItnmwgE`pn8VB_3 at O=bY-r+G8u8tgQOe-}jWoD`!(!*&LRBXF2cs+uLmRtql2-
z){zfHjja^_*0lK34N8 at XA*p=KU<mQRmb|#G$t;}xN8nW{h?sT|c0TxAz54wdF9n`I
z39X9j$5leIF3$j#&{+^r2mzW>F+|bmTpo!AHuC%fE&j>{JAjvgGerOaJZG(!*|uwL
z{#QFTsji-z#5Z8fHJ}`J_#Gh*gWx+s7uYS;<u=%Sf2()zyjOu&fd2qaM#?Y{0g}0v
zQ+0#SzP#Esy?;BOWKt+$xFRXshYs?EX(eM$H{5bL^7yh=U01so*bN*nUYnl=DBf~u
zXKi)vZ|~kZ^oPCQw?|IRq^GZp&<+cpR!+(id0juH$6vAFw3+|)gJ{(RybWBu?gjBb
z0E!j>mG(;JM%URhi|pWdoQnYp5hbx;NJghSB at sOY901Nx5WbQ2-vIzgSaovf<_KQ^
O0000<MNUMnLSTY^CsYvt
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-up.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-up.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4575f90120e56d21d42dc4fbefcfc571a30ef71
GIT binary patch
literal 4367
zcmV+q5%BJbP)<h;3K|Lk000e1NJLTq000;O000^Y1^@s6t-qY}00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000I$Nkl<Zc-oYfZE#i96^5U+_qpfX at 7#NnkS_uxfs7)QV4(;|h49fT6_rx@!PuF$
zfUQ3|wm(|Rw6s$#YAdZ~=+tq>l9^7ag>fR&I at oG~DNzJ9B7#yN5<(yb0)~7i_nf`^
zBe at b7I@<mB%v$ey-?i4ej_}D(l*UOH%LFgVRBO>#{?plJk7tLlpBVfp07#ce(dv!r
z56KMojbyYZn_hD6oIi0xb1I!jU0oe#&YZbntn+CA;wdI2GAvRd!3%>Q1XI4gZr+!_
zefy at TmFVt<hKBzOK;T;HP8jXD;zX0+h9MikxKz~yCA#?Ghac%_Y;63WQmGpNI;B%2
zGyWz?jX^Zp!6 at e{awHm29UT|!3okU};?#{~AIm^_QS{uE>MPZ=<RJuUZ?=!Wvd!%9
zvzY5E(~im>di|}AcaAruzW9LpY9hnzp+5G#`n=hB=^TUC11Lb>cCT7hvqZLPO`hXH
zewlqLY$m<)+CSO`5c_d)N<sVi_TlfZTh+bddun54jr>X}K=G}jN?pC{Nweufi?w4V
zQq%8Hvp!QRk7-BpVkse>7M!Rpe(- at GE{nyIVy*pHXKNuIOPdXw9!wTgn1$LAqDdi^
zCsI}|KUw$<Su?f=D!+`_?7QVhUWD<n6olhowNF|8l%C4`+Gsd}W5=}7T8Kpx at l`9o
zmWjsHiD=5;#lee$7e(JRSN&|}Qpyvt3<@xlXUU>W35&g`5RQVyClxLk{L;<aUN4B>
zyr0mJT)$F-*&ba{`q|{{f}cOyao)V at gsy(`VpK2qCTre4 at i$Z=pHTH|wNyKj at S-5f
zA}DSv|M8n;iTN-7X3Jx5T<PjVlw7-%)&zh)w%=Yjwx91BL&w$Cw<Oct<%UBORU{!r
znNntiJaAkvHlQFj_594z^)CZ^UfR7o+uuh>5It5Rt-Kf at ZW#OTdX9Fs^5>k40yrUN
zh_bgTrO3EpCO9sLfU!^<zx7>5MUDV1wTl+x579o5_0L%A6Br*6n3P%Q0uF)?@WElT
zC-BG2yv7wFqeO^=TuJNE`Ye#}CY%J$00Y1H<xlz3GYw}KRX_Ap#3|}XdZob~6`M{~
z7u?+pT*xJCd*62YLtM(SPzoy|$^ndMjOY<=0`v@??*c9YLCAGje&@YTV3z-@*5BwL
zc3RlUoKxcb6F7INvlD>8p#3b`HH;Ax91GpRMG=w!T0!gO{TZOEsp)Nd=+Hsdu3bCq
zIH9vqx9~Y23=9C>jg5`L*57XhkZ}{G!UUx3)jkPW$FYVBfzJoVQl$Vv)8n@;sN1n7
zRJY+U&8Od^wY8Pan>P;wmjQO}+(~_XJ^lUt09reQORD59WTcN4Lr8mBC2qtS?6V(r
zb=ZUPv at 9JN0YPbhdgJl!>zhyWIKY-ITd1$E$6AY0itg at idV70wi)wFQt(N5#aF5m_
zHj*`#@?=d%GCY1z*UnqXsh0P;r+r at CgC#yfPbex^b5i4^?c^KwNH!bL+uJL>y}k7G
z^e{X;tN=%8n6pC7uURa0UW}4xLQsyuV)<P851J~{OZMoa$BxK>eaFwA?K)asR;lLX
zrodRd!U<AaSWd$DobGI60MMfb>6J{8%!1YG{#zEv6K;g6Xj1TE;M;)G#LP>JtA72m
ztK)mcTC0ZpF at M~%rtsA8_80T>)odB{K;H*{5UyObt(V)`H`GtFwfK(9_;`wW(LAPW
z2Ng*OkvLfKah;gCZ|Yz7PR?Jx4cH~4CaJLm&o`}|^X{c*x4WKHDn at 242w->svV)fF
z5LlD50|<HGMFlquMtnjlYL-oY@<>hTx*fn at fR-G903l;d=)mdUEjn;^^P>a7<!M at h
z8eI?*K#(1=32Q-V&>@SJ0AnHU7MP_~zdbsw`2JnMbHMw66>G1tNe{^Tu>0_g#+FCc
zw_JH;$xv`5C4h*GxrP=q8W(nwwj#akqxlmz9xaN`+zm7UCvtcFdVt)O%NT3QPG0=`
zyu<C!toX36Y387RIc=@cBa<vP63X|>5_7w1O22cuGV_Hu1-%z|4QRjS58?&@xfccs
z2eVzb^bL2+%9_53U}Jz1M1^!b8*__0JSX`Ua1dw#{OgnacL3h*X|FQPz?=X8002ov
JPDHLkV1k37QX&8V
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-qcow2.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5220093e8143db08887f31decf8af059d654ba7
GIT binary patch
literal 4684
zcmV-S60_}zP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000U_X+uL$Nkc;*
zP;zf(X>4Tx0C?J+Q)g6D=@vcr-t<CCh=7z!Z&DQqAW}k$fE1A?Dj^9FN{At$*%eX2
z5k*A=8_1xD1CEY>j1^HV42lZa2jn55j)S9!ipu-pd!uXCy!YnK{<YUW=dAOcv(E>>
z2n?1;Gf_2w45>mM5#WQz#Kz&|E<k|_Bya!_2(x4%bNwR$0Qi19JS!r=2fhFSc+(3A
z0KiR~z%U$#{}1XynOp&YgaN>GkvK~TfD`~gdX7S-06<0ofSs5oQvjd at 0AR~wV&ec%
zEdXFAf9BHwfSvf6djSAjlpz%XppgI|6J>}*0BAb^tj|`8MF3bZ02F3R#5n-iEdVe{
zS7t~6u(trf&JYW-00;~KFj0twDF6g}0AR=?BX|IWnE(_<@>e|ZE3OddDgXd at nX){&
zBsoQaTL>+22Uk}v9w^R97b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&JM25
z&Nhy=4qq+mzXtyzVq)X|<<F~dKmY*YbbitPEHASffI9|&ZT_Mq?gVIF3!ruPi)OM9
zK(zp%>DpKGaQJ>aJVl|9x!Kv}<mA{nwP%2$2<XTo2=SN&}Hemwm5_29nZB!Mzr
zfky=R;KI!GOr;#pk_m)j+~$u*{I?7L{2kLG#7SbgSSl3bQ4(>EM4F8AGNmGkLXs)P
zCDQ+7;@>R$13uq10I+I40eg`xs9j?N_Dd%aSaiVR_W%I$yKlkNC<p_9XoKO;cmMA{
z{YRiB0Dxvml5qe4UPL4=RLZkI#|QubM4*8xut6L2!5A#S1{}c!+`$X{U^aw8B*el(
z5JC!MfE;pQDXfA*D2C0j9V%ci)Ic3Hz)@(1lW-0$!d18qJ#Y{DVF;eVD7=9Q1VP9M
z6Ja6Rhyh}XSR;-I7nz0lA;Cxl5{o1t$%qtDB1 at 4qNHJ21R3KGI9r8VL0y&3VM!JzZ
z$N(~e{D!<oF_eL_Q9aZQwL`h6HyVUSq6^SubTOKb7NDEZa<m#fj5eX?(5q+<+K)a%
z$1uR?7zZ=NY%ngy!$Pq*ED4ii%dsM?46DW(uvV-CyNUH<&#`v|5`jg)2{r_GLLgxt
zK}c9kSWehTs3069G!fbfHwgoTQNkx8lc-CyCb|*%#28{SF^5=4EF;zuj}tEtdx%5C
zHzX2?Loz41kOE1uq*T%p(niv5QX}asshc!N8Y7d*+GK082RW21AS=j)<elWh<TK<O
z<RS7~3Y}s=aisWD;wVzeYDyX95al%G24$EsK~<xgQr)PbR1r0gT0*U%wo<QAho}=Y
zb(%TNgBD3krLCfs(;8?OX!mKa=ybXf-IX3rm(W+z%jrkxm*@lZcMJ`N6@$l!XDAt)
z7zY?<8Fv`3m`tV_(~B9$R4_L&>zL=651DUOSSq$Ed=-((3YAKgCY2j1FI1_jrmEhm
z3sv(~%T$l4UQ>OpMpZLY<EaVMmaA2&olxsj8&hYgJE(`MXQ*#fKcs$H{fP!y!%V|Z
zL!?olv0vl7#vlu08MAmSA!`k*hIN58#3r%L*?e{?yO{kQyNf-lsi8STGfFd8vr_Yv
zW<Lkxm~r@=bWRE9D5sb6eu~}{?<wLb8>Tc&xiMv2YpRx)mRPGut5K^*>%BIv?Wdil
zy+ylO`+*KY$4Vz$Cr4+G&IO(4Q`uA9rwXSQO+7mGt}d!;r5mBUM0dY#r|y`ZzFvTy
zOmC;&dA;ZQ9DOhSRQ+xGr}ak+SO&8UBnI0I&KNw!HF0k|9WTe*@liuv!$3o&VU=N*
z;e?U7(LAHoMvX=fjA_PP<0Rv4#%;!<CI%)UCQD7~P41dfO}VBiraMeKOvla4&7#fL
znKhd|G1oHZo9CO?o8Px!T6kJ4wy3taWl6H+TBcd<w!ChIS~*#zSXEkGvqr6*ttHmG
zt-GfYr at 2m(POF~QXTz}Zw#l}sw;8bI*aq9Kwr#e3VP|3&XSc<!!|s#4lYP2<jr~0b
z4Tsqds~uV$esi>P6gpNq-kQ#w?mvCS^p@!_XIRe=&)75LwiC-K#A%&Vo6|>U7iYP1
zgY$@siA#dZE|)$on;XX6$i3uBboFsv;d;{botv|p!tJQrukJSPY3_&IpUgC$DV|v~
zbI`-cL*P;6(LW2Hl`w1HtbR{JPl0E(=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$
z-ZI`<U(7eax5&54Ps4AXUxnX8e<S~7|9bz?0H=T at 0cQh=fkA;=0{i%Sd?CM%KRVlG
z_OjXSL5!feK@~xdf~|t(!L1=^$n21<A@}E)&XLY(4uw#D=+ at 8&Vdi0r!+s1Wg@=V#
zhChyQh*%oYF_$%W(cD9G-$eREmPFp0XE9GXuPsV7Dn6<%YCPIEx-_~!#x7=A%+*+(
zSV?S4962s3t~PFLzTf=q^M~S{;tS(@7nm=|U2u7!&cgJCrxvL$5-d8FKum~EIF#@~
z5Gtq^j3x3DcO{MrdBPpSXCg1rHqnUKLtH8zPVz`9O?r~-k-Rl|B*inOEaka`C#jIU
zObtxkn>wBrnsy*<GCexIF at utkka0q)Ax)FEXX<C>W_HW0Wrec-#cqqYFCLW#$!oKa
ztOZ#u3bsO~=u}!L*D43HXJuDrzs-rtIhL!QE6wf9v&!3$H=OUE|LqdO65*1zrG`sa
zEge|qy{u|EvOIBl+X~|q1uKSD2CO`|inc0k)laMKSC_7Sy(W51Yk^+D%7VeQ0c-0E
zRSM;Wee2xU?Ojh;FInHUVfu!h8$K0 at imnvf7nc=(*eKk1<r{}@%D<W1l(ea<#JOb8
zX3}Qq=H4xyTMm}0m*$raZVlPmv<=@@wC(lwMcXfz%_!TugSJDtqrW`3yk)1!&dobN
zRHRh&RQgml?$X`0Vb}O>(e4|2y!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu8FGY
z_?G)^U9C=SaqY(g(gXbmBM!FLxzyDi(mhmCkJc;eM-ImyzW$x>cP$Mz4ONYt#^NJz
zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{
zoHRUHc}nwC$!Xf at g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR
z&Rp`ibn>#><r7!9SDLRnUv27i>OB6F(@)2{oV%K?xm;_x?s~noduI3P8=g1L-SoYA
z at fQEq)t)&$-M#aAZ}-Lb_1_lVesU-M&da;mcPH+xyidGe^g!)F*+boj)jwPQ+}Q8j
ze`>&Yp!3n(NB0JWgU|kv^^Xrj1&^7J%Z3ex>z+71IXU7#a{cN2r$f(V&nBK1{-XZN
zt``<Be)!ev*Ur(H(V>^}my^G3e5L*B!0Q>W+s4Ai9=^$VGcjKDR{QP2cieX!@1x%j
zPvm?ce<=TG`LXp=(5L&88IzO$1Ou4!{1CdwXaE2J24YJ`L;(K){{a7>y{D4^000Sa
zNLh0L01FcU01FcV0GgZ_00007bV*G`2i*w^2nIR7DLxkf00)RkL_t(o!|j-Ra8y?v
z$3N%ZeQ%zd4M_-TNKzAE1C){kLBXjMQ0#~>tzbr|NU61z4rSW<8pl!VAIb<b)>16*
z>EI}eMW at q31C)YOX;KJz(hw4pAdfsY at 9g{D;~%>TDcMXC4DCNXGyBJ$d+xoT^ZR{&
zk8|O(@&64Gb#g~(8n6Y(1Z;p4umXKRXp$K`KrOIaZYydY6Hx3Z6+ks`svyPI5 at S^T
zPOG6S-lY0EeOgRNm&#<C#~ad(CtG at RfYm^*+*TxqFEK>9Z7SdhZ7m4ulI;T_op_Tv
z$wre%1ib+byFo!!#4GB~G7B&bxHf#{kTq5xsZbw2R5~NZD6)Z84K^=5T1Wb;7kT|k
z*Q6`!z(;P<UoB_F-|Em{g#>qwO%yIad@(61V7*VZc3SKW{XrQ3e7=yRqRqpAN8|MM
z{z(`Ah1LNEd?CtPJ at f=MDL^)OWaCZUq(yac^@jX at 0K?8wLr5Zx0?OCBxY*(4Yxl(x
z(DX?K+`cHChce<QOtumugcyv6s`dHZqXtRZuCk}ye)&>Bm+>ZpqKHo at l}L#U>bkV6
ze2^JqSXZ-Ye#;2J*q6(e^apuQN}ceAKG`8<ICxB|@<w25;hGT|><eH6$)~^;wv-6}
z0#aC`YETG3hHa_}`1!(gHoBZxRE1*=T|9TDh5n#^??EFNBP=-F;aldVu+in at nbXZY
z_U2U{oML19l8i|O`Bt8Tn@>J~`}^~Fu^@HSb%s0gCkWV_pUe->UE`k(;edMbWE1bN
zoynGWTljpMo&C$RNU<4tt*V_D&R%1V)5 at M@)5&+*sP6Evxul884lfn!UA$iFru5bT
zXTCXuFZ}s3E3 at KRoF2<ehlO9Bzd>!Mms5|<U|)3yZeMT&U{niEk2h26_6<#c)ak>h
zDonK-dF9KQ{PjvFOO9M-RZaq*OE9x{Sr)Z!A2SbDQS0{c+Op{Yywlvv!l^M7rP}HB
zYZRv1S&(YyL~{=-k6mG3bvr>_(ihO^3u;j<7`3i8_4t|TumG?&*TGYBrXZ!H%@ZUy
z!NNZpx~XXQl6#<v`ffiir<MIR?X>g-I8f8UY^M!?lI9*3rp2%z&CdRsc8XH%6sFpF
zr at 4m<tsYk8Byw<h7AyW<M?jO~0F12JQ{B#Q7H9BCb^;61>}+3>!HMQxe43=O$It5f
z6PcTArS|cBvg6Ivba?r$E1COZO>A^Isp{|maPE3PiDs3h8FB2YXyfbI350aG*y`cg
zc`5wvOBrk`Y2xNU5W^^0*AUIcFPFEHWHGRNX(sVzmE%o4<R+LgtAb}vH?wbf7EjNe
z!XGZR(%9qYiIV at YcUcyfzcZWa4i8V1Gy&iZ>72XXN3zYx)owrCevN<K=tBa}&rfA)
zjEQ$2n*qSggH_aZc}MRD#g4MCAm!T#8MRGJG^=#^wR at eeL8!;&a|K@=;bJKflF_sD
zy@!in$Wb&HXTqx}a;W5d8nsS>Fe|z at ss>j~QLE2)YMa`8eA};6 at K8pKO+gHGssUZ%
z_JuI20x2P=>Gb$D`hz;z31;GqD#l?#9|-BxclmI8f}n`o6+)LR&WOV_xK at B)(>?Fs
z7|?7gM`p(>2hNYy&8+-WS;~7Iq<cbgUubJVju0Yt_=3#c<y`9xfI$HvaafFeus)w3
zoND5DT_=w}n2Il;@o-i=n`Sr=LU7{0eXM<>o}OU%D3fe6(e~5>cPg)5-B~t}ZR5x3
z3HFk+>s(sYH1k$*VXG%3^%3k5VXSdEkwyg>)L5D2;7su>Rv)e7czq|rsBozK7JsQ}
zXY*SP{QARNVb4s9rRjTf`RT%R&?IZ}93Ok;@X_eu)^NDd&LkhNdqbTBY at Fp}*M(M|
zU7SI2o`d=OD+vHX4ewJJZtwSJXIcnI_(f3~2_}`77N)bom5fP*BVoKPoidT|nv-PZ
z{Q7+23<?E at stJTcKYDX#Q25o^7S_GpFm!)zoQdhNrU~_%;|3H$Af;qpl7&lc9`ukt
ztVbK!+zBZWs=|>PH;=yAaMy?F37v5VA&)+i!wX-WhAJg8GAHj4$KZcefjp-bgAjL>
zybKfk=r9EN+ePUV=Q`Ma;TFfPbmHj`+}6E-m{=35avl6=ek%D%*09^}qFo<fkVJt*
z!rUYahgW3bUp}3y-2p1y9)y574lDO3m@!2*Gd$2H5pe9 at To48|3xO-qj4RPRvb2sL
zECd)Qs6iRMK#r}1F|XZzrW|~Y7qCnKP!I at 7$~t}bto)X_y?8@%a3cZ0G;Tnzu9La1
zlA=Fe;>Ca8oOHOKoWDWQo(gjJR?-{NiMTg79zX at qRUw4aYCxD3Qf!7Xg)my0ks}*+
z032om!mQ%78ZatC0QQKR#|)A#Ala;llcmM8zR~U1m})mh1=AzD5qAKHQO>!;=bxXK
zLUEo0hgn6DvL09jG>-QJW~EUPA8yEZ22$-tzmzZ#)J%R&8iv1gG%$GwoQPt<!RrBC
z%EPrC!WWWxa$C{j at qPkM1~vc%k<Y(_QFbpPMn)|6d%3OXCZCN-9{&S%4huE#v8l}f
O0000<MNUMnLSTX?tJj49
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-raw.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-raw.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5def8f3dddd81a3a570f3acbd3b206684275cbf
GIT binary patch
literal 4679
zcmV-N61eS&P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000U_X+uL$Nkc;*
zP;zf(X>4Tx0C?J+Q)g6D=@vcr-t<CCh=7z!Z&DQqAW}k$fE1A?Dj^9FN{At$*%eX2
z5k*A=8_1xD1CEY>j1^HV42lZa2jn55j)S9!ipu-pd!uXCy!YnK{<YUW=dAOcv(E>>
z2n?1;Gf_2w45>mM5#WQz#Kz&|E<k|_Bya!_2(x4%bNwR$0Qi19JS!r=2fhFSc+(3A
z0KiR~z%U$#{}1XynOp&YgaN>GkvK~TfD`~gdX7S-06<0ofSs5oQvjd at 0AR~wV&ec%
zEdXFAf9BHwfSvf6djSAjlpz%XppgI|6J>}*0BAb^tj|`8MF3bZ02F3R#5n-iEdVe{
zS7t~6u(trf&JYW-00;~KFj0twDF6g}0AR=?BX|IWnE(_<@>e|ZE3OddDgXd at nX){&
zBsoQaTL>+22Uk}v9w^R97b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&JM25
z&Nhy=4qq+mzXtyzVq)X|<<F~dKmY*YbbitPEHASffI9|&ZT_Mq?gVIF3!ruPi)OM9
zK(zp%>DpKGaQJ>aJVl|9x!Kv}<mA{nwP%2$2<XTo2=SN&}Hemwm5_29nZB!Mzr
zfky=R;KI!GOr;#pk_m)j+~$u*{I?7L{2kLG#7SbgSSl3bQ4(>EM4F8AGNmGkLXs)P
zCDQ+7;@>R$13uq10I+I40eg`xs9j?N_Dd%aSaiVR_W%I$yKlkNC<p_9XoKO;cmMA{
z{YRiB0Dxvml5qe4UPL4=RLZkI#|QubM4*8xut6L2!5A#S1{}c!+`$X{U^aw8B*el(
z5JC!MfE;pQDXfA*D2C0j9V%ci)Ic3Hz)@(1lW-0$!d18qJ#Y{DVF;eVD7=9Q1VP9M
z6Ja6Rhyh}XSR;-I7nz0lA;Cxl5{o1t$%qtDB1 at 4qNHJ21R3KGI9r8VL0y&3VM!JzZ
z$N(~e{D!<oF_eL_Q9aZQwL`h6HyVUSq6^SubTOKb7NDEZa<m#fj5eX?(5q+<+K)a%
z$1uR?7zZ=NY%ngy!$Pq*ED4ii%dsM?46DW(uvV-CyNUH<&#`v|5`jg)2{r_GLLgxt
zK}c9kSWehTs3069G!fbfHwgoTQNkx8lc-CyCb|*%#28{SF^5=4EF;zuj}tEtdx%5C
zHzX2?Loz41kOE1uq*T%p(niv5QX}asshc!N8Y7d*+GK082RW21AS=j)<elWh<TK<O
z<RS7~3Y}s=aisWD;wVzeYDyX95al%G24$EsK~<xgQr)PbR1r0gT0*U%wo<QAho}=Y
zb(%TNgBD3krLCfs(;8?OX!mKa=ybXf-IX3rm(W+z%jrkxm*@lZcMJ`N6@$l!XDAt)
z7zY?<8Fv`3m`tV_(~B9$R4_L&>zL=651DUOSSq$Ed=-((3YAKgCY2j1FI1_jrmEhm
z3sv(~%T$l4UQ>OpMpZLY<EaVMmaA2&olxsj8&hYgJE(`MXQ*#fKcs$H{fP!y!%V|Z
zL!?olv0vl7#vlu08MAmSA!`k*hIN58#3r%L*?e{?yO{kQyNf-lsi8STGfFd8vr_Yv
zW<Lkxm~r@=bWRE9D5sb6eu~}{?<wLb8>Tc&xiMv2YpRx)mRPGut5K^*>%BIv?Wdil
zy+ylO`+*KY$4Vz$Cr4+G&IO(4Q`uA9rwXSQO+7mGt}d!;r5mBUM0dY#r|y`ZzFvTy
zOmC;&dA;ZQ9DOhSRQ+xGr}ak+SO&8UBnI0I&KNw!HF0k|9WTe*@liuv!$3o&VU=N*
z;e?U7(LAHoMvX=fjA_PP<0Rv4#%;!<CI%)UCQD7~P41dfO}VBiraMeKOvla4&7#fL
znKhd|G1oHZo9CO?o8Px!T6kJ4wy3taWl6H+TBcd<w!ChIS~*#zSXEkGvqr6*ttHmG
zt-GfYr at 2m(POF~QXTz}Zw#l}sw;8bI*aq9Kwr#e3VP|3&XSc<!!|s#4lYP2<jr~0b
z4Tsqds~uV$esi>P6gpNq-kQ#w?mvCS^p@!_XIRe=&)75LwiC-K#A%&Vo6|>U7iYP1
zgY$@siA#dZE|)$on;XX6$i3uBboFsv;d;{botv|p!tJQrukJSPY3_&IpUgC$DV|v~
zbI`-cL*P;6(LW2Hl`w1HtbR{JPl0E(=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$
z-ZI`<U(7eax5&54Ps4AXUxnX8e<S~7|9bz?0H=T at 0cQh=fkA;=0{i%Sd?CM%KRVlG
z_OjXSL5!feK@~xdf~|t(!L1=^$n21<A@}E)&XLY(4uw#D=+ at 8&Vdi0r!+s1Wg@=V#
zhChyQh*%oYF_$%W(cD9G-$eREmPFp0XE9GXuPsV7Dn6<%YCPIEx-_~!#x7=A%+*+(
zSV?S4962s3t~PFLzTf=q^M~S{;tS(@7nm=|U2u7!&cgJCrxvL$5-d8FKum~EIF#@~
z5Gtq^j3x3DcO{MrdBPpSXCg1rHqnUKLtH8zPVz`9O?r~-k-Rl|B*inOEaka`C#jIU
zObtxkn>wBrnsy*<GCexIF at utkka0q)Ax)FEXX<C>W_HW0Wrec-#cqqYFCLW#$!oKa
ztOZ#u3bsO~=u}!L*D43HXJuDrzs-rtIhL!QE6wf9v&!3$H=OUE|LqdO65*1zrG`sa
zEge|qy{u|EvOIBl+X~|q1uKSD2CO`|inc0k)laMKSC_7Sy(W51Yk^+D%7VeQ0c-0E
zRSM;Wee2xU?Ojh;FInHUVfu!h8$K0 at imnvf7nc=(*eKk1<r{}@%D<W1l(ea<#JOb8
zX3}Qq=H4xyTMm}0m*$raZVlPmv<=@@wC(lwMcXfz%_!TugSJDtqrW`3yk)1!&dobN
zRHRh&RQgml?$X`0Vb}O>(e4|2y!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu8FGY
z_?G)^U9C=SaqY(g(gXbmBM!FLxzyDi(mhmCkJc;eM-ImyzW$x>cP$Mz4ONYt#^NJz
zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{
zoHRUHc}nwC$!Xf at g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR
z&Rp`ibn>#><r7!9SDLRnUv27i>OB6F(@)2{oV%K?xm;_x?s~noduI3P8=g1L-SoYA
z at fQEq)t)&$-M#aAZ}-Lb_1_lVesU-M&da;mcPH+xyidGe^g!)F*+boj)jwPQ+}Q8j
ze`>&Yp!3n(NB0JWgU|kv^^Xrj1&^7J%Z3ex>z+71IXU7#a{cN2r$f(V&nBK1{-XZN
zt``<Be)!ev*Ur(H(V>^}my^G3e5L*B!0Q>W+s4Ai9=^$VGcjKDR{QP2cieX!@1x%j
zPvm?ce<=TG`LXp=(5L&88IzO$1Ou4!{1CdwXaE2J24YJ`L;(K){{a7>y{D4^000Sa
zNLh0L01FcU01FcV0GgZ_00007bV*G`2i*w^2n8EKWGpZM00)CfL_t(o!|j-9Y*g13
z$A9;|nKz!r+jzWyaSRyjfDMLtX+fn)lqiU_RRT#9WCgmQC~cKiK=(%dfJjuSD4}YV
zgsMpcqEsphO{6B26sTC##@K*^mlVesfel`W$IIBW&wIBYW;`A*gKcWkFF9YH=Ds`k
z{m=QI|GDR0_}u<C6H^YpQa2CyK2QkQ02g2dhJnZ&WAFhV1N-F8>g&@26tC0?pcyz>
znQQBCnAM=mY8pt_)IfhgcSH=S%w>4|5yO0<!&3xo1d8R(YMD62G{xWM1J20y%CI5X
z<Bb at kYw8>aO(GF^LOOPnf~tsD)xGs8zyhE%ab`Rk8xLPnA3jibufr at B1HC#t`_PeA
z@?XEm!A}O}JhR at q>?Z&92G+mbiVo`~xQlF}>XAbiv!(>t7ErDIDfae}unYl#Ktyus
zmJhE_=btx6<~;c?^m_3IA~f{+7z*oBfNb~4tKEjCPf2m}*0K=*)80B$L?X=s8n%>j
zvCq#}?nx!28*>V9&)R$*EJ&j&+loU7F{+2AEoFmAMKbTT`tP}e^2LxL(>0T#h|j2$
zNQn#^hP11kD|DDPw`{BEm;^BOclBQ$33FOXgQ!EFtw|XbkESZ`gtk|0nndw%2%8X+
zQEbMJs!5A9_4#<}y>?m$0^`OTo++g~+s04NcCzPuPkj9S$Ct8UQ3i!?T%vP0#CKQb
z at ajW_{Hm^t7yfk<O%;qhU%`L+{gfYU0U#uWbxM&40m$)y-2Mo=KD^29+AdCYdRXDI
zv1?8KxH-j{DU at g10C;j~=D2q!Iy?YW<V4@!mm7Un<=O!#&9Y)r1ShV0k``vu?aFqa
zKg_P$E&y_ECc2+n&BAnT+?=P1qo6ML`>D!vP?)B1-4g=fc<jR!xpv-dAEYA3PJPb^
zl`(*;Vve2c^dzNTnNUBI+Gv#iaee$^PZwv==MS?x=ExIE#-iBl_S54HQ;};&Qw3!%
zEBhKhB_qW|QM!fIIW{7O<jjrX83LRT!4jtxV at DOnjw+6AD&bV8hnLQE#osT_N}<$c
z<^8Ke9KAM#Zb-gf?3_UJ5EVH#R=A>c{`JZLZhwTTJUgqhZJg^KVI*wK5a0y6HWXyp
z{w9_mXyS*bJ9wZVjlK8ZlR$42%-^mKG8EJ~dvlmC%yUqXI+g~<uY1V0nR%=zlPiM(
zhJrfhd%aZW*(uMq#q%_onI=)35XGQw#1-2%5a8we at 8OH{90~MB0lxjUCF7QPVreG7
zx!5~SDBmu1arS1E%JaQmzFF!bRa0-9f74Q&XnHI^EoyYqN|%)qr<DUOeJtDG#IpTO
zlpky+7%|4Fx!W72rO(fNhsK3o9{}~eUh*9p-muQOZtpAr%IOR0==L&7 at 1HKaX&ngA
zIuM|#&(Dbt4{PVAlJ78&(cCc<-G6UI!JO}jKF{13CTz$VHmon#Zvc)8Vcb5HcX>aN
zs2{Mia>JwurfK*UMaH+B|Hob at L0A;SKcz_4=cvuK{ra|B0iFpOR6bbXuqlXmry4RO
z?mz^yDv%Pwy1`ITXC!Q}IKx7kS;d^tUU(x0Z36+^zAz|)_(o+&))l0ojm{Mi)D7Ri
zyS%zh<?xDh<*nLevUv2*^|`0}$oEC$o0096MM8+w#0iD_8tC+dz@&hXI8)4=+fv5!
zC$Dj=wV!X?mq#F^^YEf{w%zMQ2*C$8hI#s(Hip8{qfE9<<JNapO-%hZb#J|Qv5lYS
zXV{OQ*<7kmDUzc#RlUB5G$vt>^3JAG7t*XC!#a;Ha&oF>IUA3(a;&W%VOBWM(8FI^
zKIPe??YtCg8rCmJ<=S)Qys#!8bjhX?=eRW!?W&KSL~zN at B$JC`ti}1(au=^%=;a6N
z3aBY at Qt`(|LV!@CehSl=zrQ at yK}f=`>Um^nDle|dXKQITnutnarY)T^8-1<JvQoRH
zj5L!%<$-2GQX*uM=FX(B`%DL$|K1+|e{q_|!c=Wm{pO4T3L%hEvN|h;k8b%eBF5A`
zS}fv1N`$I#xW&zr at 3r6YVR}|)+)<E6zFNeOzq9~VN at Q$IPDqZ?->L#7E-NM>?x=W~
zW_jrl2l?x@`P39U*>j<XcR%UJHxe4ldjXDAjmL_e{H!96vMg(q_B%LA%uFOxfJ8!h
zRtksKFCzHJLaq#kXmtA!0#-V$EXlB-#hghL+8hF${@Owi1!@t3(o74bnU+aD&O#6o
zz&y(wlyL>lG83kKH at 2o6{fr+-nFT;WC?cuv58Sowx8Ci?ACaSugaB>E0R4tR;hT+A
z|NbL>@?rO!gZo8o7uA2bMDZJqcp?Tddc!jTr~rm4gm76+2#Z3l%`|NyBr7vANxSK^
zm=G2fm(_$>5dyHsXr5Li13<P#5hv<umOnli)R}KLPYKM3c_StO5EIgHs_`GK&ZVZr
ziPNH at NZAIg1+LEY0<+Pqi1S;^T%kO>IVdG~!@3sKr77{F$$-fT;6##!T}0bBdFbOl
z5s1hVxwCrROs{~mfvrGg?D}_9Wp_g{G8Vbt%AM8Sd~S1W{{`>T2W#;P>wo|N002ov
JPDHLkV1mo3<ud>P
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-remote.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-remote.png
new file mode 100644
index 0000000000000000000000000000000000000000..e316dc0701db28b51db92b5e6e6985f3b82b25e9
GIT binary patch
literal 1005
zcmV<J0}}j+P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000BDNkl<ZSVxuC
zkM$Ep5C?FmK&Zf at 0<Z$l3WN#>6^IoWD-bF$Rv=bjr~s(IPytwh&gb4t+~2yJgn4gX
z_U7i#cjw>b{=F}wr=k9R at DltW_(__-kKfP1r{Fiif86T!{tb$P{S+*?ptle(fc%)i
zrZ(3A?8EYhCh&)Jd`!n~j${J3HGw`(IUuisf1V+j0pRS<bj<d*U|>$STt9S{)PJ7(
zfPR;t at 3<HNa2vsa_?S1Uo8B1ztR^Fe;IA_{5O;j_00jLjgG=|zJXe!R>6en;`8EBp
zf7E881<<Gcl#w3B?=iuYtOrr at rFr4}E(5pvF7r(ZS^)bH>h_+b4FIL_UPB3ZDI06N
zck32V>z5Dl?iGL;S~`Lqg3Y!YA<v@`lSO6YT=$!x5uHm>0646Uo!D$ySQCgdn?4Im
z$nfq4e<o{J066+8SmV_U&w!lMH&FmUBby)@;aB#YzYTtyzhXWFK$rfW!ELWmA5^Rj
z^$c0a*I*;8$pi$3zF<Ik|19l2KLg+pEd6Q<z%kg|_T)wy at lx{%x=(xhHO7FD`;M?b
zrLWfj2q-nx?Q4Pp;_qN%!+_pl0IU at W_)8;jA;gw{09twrfB@<)ZO(`zEbyALC7(MV
z=SS~Hb6*Nod(Xfq)q4Q`NsWFh?nACLY9_UndZ0#Spns`<*jZ|t@=TWiP*U?<@G-d3
z+1j_~YXIo#3qa_~z_y601klYI%%l_`y<r-FY6;j{R5OtL8{<Rpr{E8xCY%|sg*p{v
zq(-W200l(JoJZ62I^=9+U~58X)cV?jDZLipi?kns7Nqa`+9NeB+ZaM>5h=y_D>d*q
z0zmB)EVaFD`E6ZQnXByEB0?PK&PVBRbfYDNw%3TP+Uk>fzs6x}w1$8biyu4YK>;|#
zgECxOwWGB1-;Xfa2!Q$D2U~nwtTNOzr(jvAjX1n&2y1WDdkaRep7_-1MVjvztlVzD
z1b=RkLuQev4-m7FYyn99?t*UB8VKJS{|^K{H+-MEGJq6_p4JdlUERVnn;8M;pOMcz
z;6~Kh??yd<wiKgGltZ>|^y)%zuWBE-xuECN&j659JO=BBQ?Ob0jP}9GWC3Z&YqW-f
zuVV%Gd?#b0?&TD6LF?bqA<nfz^+rE(J&+}V?(&7S3;w^pngJ+>Zft9{UogPPIW30(
z11kt{RbwevCi+9V27nRgoN#>SQ#x}Ra)Ffy_}MgV=C=T7;{bt|1Xd-gY^d)sgI~b+
b->ZKC*A4Oh7Gf$=00000NkvXXu0mjfz>VSq
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-reset.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-reset.png
new file mode 100644
index 0000000000000000000000000000000000000000..eae8449a556d68a44c28144727f7bb3c5d2fc13c
GIT binary patch
literal 4576
zcmV<65g+b}P)<h;3K|Lk000e1NJLTq0012T000^Y1^@s6OO{u+00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000LINkl<Zc-ov+X>3&275?sh%e<MfXYuofZN|oUVX*_0eGw^OnTA9$p(zqZgfvB>
zs6wq8QKTXyn_onrN|D>NN|n$Cktj`xL4mL&ZNQB%0z`?cK)~2wmV%dA8PD>Td-}s;
zXKV$Ea-^&GboJi(biVVQh2iOq17HATSyA1La|ZwrkzreAoP<a}tt0s<zheLt05a#2
z)01C3Nmf)p7~{gW<H>mR{%|BX1b_h8ndcLo{Xdfc<fxj<Us63|kteUHG1p%(N0OC1
z0E~#z>BR8OXz;;5hVJ$r4?eil1Hj1mrtb;Lq>8$EtBNYBcRO4;3mD_-h${jZ1Hixl
zFvejSslHJE-9PvI``p{9M11gZz|s?FcL1;eki%OzV{+AuU)q-KU|;}a5E*Zbv5^A+
zT=KcS`pUvU)lAb!Ux-JBLXV?vqF5XNa`e*jy0V&CuLY)5-d@|V^g>7H1<7AjvVw@<
zb~*19<oUaNo}6yRcr<O8xwa50=NyaylB`zilP1qI(#g~D at L=q5^l|_aW6Yi7%dZT~
znA7AdEZr<AT6vz={aX9m`wo13{Iq`T?4>uC&a3ZzVdb(5nnMWzEN$C1zjCcxKXl~O
zx@$eRH>$GY;+z2tFj9&4yUrZj^e8k)*)%f%8UUV~S6EeCS-YkvQ2mM|Dbs1B9H8sI
z_uBvT#!msL06YMk0O9}=07S-z6i+1OLq|?E{Qblif3Pg82mmBmF$em(H~r^dpME%A
zC8`#vsGGaFux#o&)#;v1whhJ^7~=qA;GEt3?Y7MeRxO(!$zn!)N2*i+#&a9DHKl~~
z0b_6yfOOh8{lcQ@>vWH6cuX*p%cnT2XDxg+6bx4q32<2&0nAuDk(_+)a##JTW%E0}
zONqf?aP-yCbsaY at bsR04zVIW>o%0GK0TN<)dCkoFjZKZ`$Aok1#?_v-me*HrSoi!d
zIG3(u17f5U9K(s!GRv~Y-Jdyg20M1_Kz at Gy*lBHTMJ)ILx4JqH%Zi)^0Egz#j-EQR
z*fcGcT^e++=lb19Z`WI9D&bXK?%AM`d<r6{vV^YdJ&Ug1ysbPlt;!tzv8kyEu~;ly
z8*)oaivVC3y7g|$FzzzOsu&Rr%bF<p1k at PbQQ0$L;Ou);)WCmTAr;A_yVicDo)_
zlubG=%W~@BU~obIP-sqeq&}Z-T;$$@;_9k7OMk?<RA{6U5i^~NeVYqb2*3q^S(XJ^
z*L9et2`)+CoacZ5+ZJ#-)c)3AZE3mDd*_`KXV0(odvl93%vb;riA1t7Npt5G1*Xq=
zH*Zq;m3VmIux*)|0w)N7B1>?niX0Ay+3MA+At#eb0AO5_ED*&3K$0X3426`w`wwG{
z%NKs$xP0N4nOYu8_^w^Muyg0mF;pX&ykZ*ZUYEz$=yc~c638SW03rbR`i;GNLnlt2
zpo<qTjyWMBN(o{00RZO=@!@1)G#2+nBcVsFt*t`<1~QEt`}glhXJ_X)dSk)<aAe at W
zmn2yN;~ZR)6vh}h=Lp9hmF(X8yVA2~J5&ICT*I%PyZq&{Y0rEFK at bFJs{EVFr#{>_
z*#8i^uA{B34coVG&n}a3Rx|(E=E=3Q4hq{IR{}x^A#7_f8VMh^276oOty{N_&|{?0
ze(dDM!1USI1?*bR0K>4iG0po4 at bH^pFvyylo1Zu*6VdQR+cLw9aXtIq7J^&0D411W
zH}B1s1C@;ETR*a*qJH`Fd-6-lciZ+zU6Qc>`SrQawhZ3w>B}?+nlLc<=-`%BO<nNZ
z`cED1+?6B<mTdzJC@(2Kzv0Ekql;$G?9lz*TT)9)%V<(DV_FRk9{S*#!&|UM)3kz&
z!lvkx0!xVKej*-?fryBRgE5D!sD78%Ut2b9*5c^EgPXQxnx5i{az%5k5JHHu;=-%V
zFE+mQ>z{3Sr at nS-hs&wm0T3A%DFAlxy}#0zU)_B6O7Fw=9GB)NB7g{jMAAqMe-R4}
zTuwZS3`vUO$noV@<aqKLWQSHU(AT~GYUgK1w!FT3VKgazzjDbB&i-Ug!*Sj3xd&hn
zz at rQ!m<T#L=0w|H{`TX8M^66H>Cg%!&Ot;V2r$L~%5W?MD6>IWmbg})=XmKr+rGYg
z1Hr)5K&b^F3Lpl+oCq+{1ORFKtLqQ{y!oX~ZkKj0Wf){w76=TKX^|ir*}@1&n>Hj_
zs`+6<V}nD}Ff~xx4WJJ|a3bL2A|36e41jvSf3WENqo-f~rl)Uh at 16UVX~XmjAymc~
zDT<uP^Lj!vYb(1Nmdrc0V)5Mb0D1uoKXL1N3}`kJDgb#X94+|jYIogmDpf9Qk;@pM
zX^vQFQNgXcn#x<5oJF#R`}YPNH$^ffqGX;dYtJ<RJoU2uzX1S0-5^Y~P;dqS0000<
KMNUMnLSTYcw5GuT
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-search.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-search.png
new file mode 100644
index 0000000000000000000000000000000000000000..b38cf6cba2ae18095f990c7dd3736365d9965fe1
GIT binary patch
literal 4197
zcmV-r5Ss6aP)<h;3K|Lk000e1NJLTq000~S001Be1^@s60ks%H00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000G$Nkl<Zc-p*|ONd+79mc<N?zs=?>gsBS8P7<#)?_?m*OpR4pn}QMi_+9?LP#JO
z;w-Xh at od}}ZvqK;lU*Q`LcH>1*DgZB5R-u0O<O25UX((}*ltpft;xe<tQn8S(%h%+
z*F}z8#ZGL+4mlunb+0(T^M8EbUlJtoV=e^%LWurnq3`7YlmHa<wV|IU0JZ?M0o(u(
z0O$c2>eM8^1`fb14ccZH#)M^AzmQTsDumdf!5xzS&9dxt5Ck7+a7Q0xD5xOWkI)1#
z3ZP=!_9IHEm!*_D4a0zx5>m>WrzD9qP5%}}(W_AuE$OJ!yFp3b1WEutfbEXs{L(bd
z*QJz>Wm)ij|Hkz6^cT5YZnM>D6|Y^pHXX;Y9mg at EC|cgy+Il_+g7W|(0NJo9wE+00
zY0jFa`I=J7aU2H+4jedp{P^*Y_U_&LC4db8?S+Mf;;B=o4sUF1?2n>oS}FC1Ua$A-
zIF4go7T&dxx;bk3eEz*ssl-a9!lOrz{)OZ#Bwr-?Fv-0n_mKSQxpU{n>-GBkwOWlk
zckbl2ZQBkH+cbUPm{RKTVzIb3F)_ipxw(r;lFXBQisTNGHc3I!Aejds%jI&dR;z8)
z>vitlz55JFpQLj)pw!ofQfkUDj8VsNP^;Dcu9Rv5I1k_}Aw(pEpb(-5AOv7sxpJko
zwY7B?08G<- at XVPr72U~qTzz0Br7S6>U|AMi*ZmKGuK=tGA<}QOwGf%srQPXtzD$w?
zQc8byb+rn>B`JpiCID_IrC=BaE?v6R18`MGbDNZOljYMi^^+ul5F)Kst2qG9z at B#m
zMkGHILWELEEH5wrObBsR2oc}1fdF6wC`l<tNj{Wi8C=(0Ycv|^FkN~x!YGO^ko=bx
z_H&bylaFg{y87e}01v<ffC<~SpOaEf2_dj+*RCbkb%oAIHViP$vTQR=)3>rLgAl^a
z<#KO(p7$t#NdVgc>;UipfU at H_zfwxgE2WUn=R5QB^Z(So+7&|ZuI8-^oeCk|@jP$8
zX_~*aZTkVw^Zq1+_#lqsf0NvlQkJEZPe>`BFijJV<KWPtLyL_@;{t$-05*pbqt=*7
zGPk(6IM!%1{#dWqIXgScN~OZl(NX%o&tkF2QmMqTu`yPw)#TW*V{eh%uG8&mKNiDy
zDM<Dkq5!}@a^%PhOG`_KTdmfvFbqYKBp?aPvf|m<*$W2`9{l~ulP52d{7t9RN!so9
zLJ$O>0O)?#$od9Q-{?bq0FyxwlouBlAG&<`@=O#(Ub$S3_U+rZGB-DOdS+&3Tq*T#
z5Cm2jhDeg+Vh{w+gkiY+T}FNzZ~&?R<n_23)9-oRWS<Km&R46|(^;17CkZJfNFofw
z#a65J63I}HtL#n#xbGwckdWNe!}W@;k<uG%0Pwrr?hV_vk<aI0Syn&Y&yxIWtJPZ2
z-{q~Ty)D8am+AZd&r7A!pFPhjDE0NZ(=<i5+g)E at Uw^XQZhxX3toLo^J at nEY&33ze
zmgH-L&kVzW<2a**Lg7uzvI^RB<+lkR_X1v7SveWU at rPNK^~(X%G~v4LV<RIYztb`?
z2Bq at 7fx5>1G$osxn at 7_$z1sh|DW!yM+i+d?_{hk}!?#9xPZ9Q^B-QHb>g8^?`*N?>
z`+wS`gyT3l&-30a6bd5)#((cA)lia@&1Uo6Fbv<mHMO~1u3jt_=e3I&_XX?^Ze7pb
z_3PJPNs{E#erkmfuq+GX<Ks^Qn9&Y)f53ry8f$B7t!}q_Bu&$7uxt11*|QGdCtAz*
z9pPYV&1SRtQMp`xLkJNFAviTP)jV<H#6Ps_#P=io+a#j9(bLiF22jxftpNBKKodax
vg8&Dhrmoef9#;u~>-rS|p!l)>uKjNSf7rQAZ2gwc00000NkvXXu0mjfr62uF
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-sort.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-sort.png
new file mode 100644
index 0000000000000000000000000000000000000000..78e8b3930368c9ee163ea6f28a0c5a1d631241a9
GIT binary patch
literal 3421
zcmV-j4WjaiP)<h;3K|Lk000e1NJLTq000{R000;W1^@s63qXeZ00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0007rNkl<Zc-p*{&2G~`5XXPxIO&G8ZrU7BQOjo~M8ydSgt+#`i$pv_r5^ewRj<57
z%LQ=-iAtchK&1)<O+UO2PCOi#R<22c6C~zh%R9UO+4=3vT2z()Ws-ZZ0kc2^RDl%e
z0H=W3_XwCO%qyA#eIT*9=Rm5e8s?lFu(+|Yu?kSBR8nAfZEbDG7QeB+zP=iUVdZZ-
zNYgai+uQrPwYBvII0Slt<|CX3R-AL&`H4xA1h$*yMx*h%-|yGQNuBq;1_VGiER6N8
z<X9wD)g_=KBKujEeGY<PNkoD&i2D706?h8l0!Kx$enAYNVfp_a$MIv}J}_s|4zkdY
zOaU2Cu_s~4Y at 7hMMP%MYevCLAr@$vwod&Mi0qKk*)&uITR_kTA+np7WOjT8E>z7Jq
zB60vc0zwf<ZLG9d1RTV1+)&l1g#SG71o!}a%jdU at Re-ZNj&A`EjM*Sob>o#;-D=UH
zjCFu}#th?9v~yrzRcpWua8~pihnaKE?Ue8hffEtw76*coVol&<N#AGYKQIbPMtkPH
zZvrdULx-`ttgA`Ij)A+zOfKqX1gp-!i1mQFbMDn7tn$o4tD}~+rhJiRz at hcRgGpKC
zqp1Pcft%LP@?xP0HGy;Qeam{|>^Q9QmuIcrZZB_cZoVDmm?X&puw=nyLs%V)$j^aI
zQx#FwKtvRna?bf7chYka*>=vI4j2oq2X;pVtE#{2OjVt#R=xMr0~Tuo72`J%t4n6q
z!MoPSs^0sBD2m>tX*%b<e*qlX<>$Qj4}p8Yv at y~$tp51nQPseBG=V$7qH%c-d@<k1
z4oB65E`ExJvbw^o at Zmym#!gyNW}z~ss{9%N0 at n^A`j6H=00000NkvXXu0mjfD-&z2
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-tree.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-tree.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f7ed5312dac8d3bfb26010ea6555682f5a43f3d
GIT binary patch
literal 3526
zcmV;%4LS0OP)<h;3K|Lk000e1NJLTq000^Q001Ef1^@s6$M?IS00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0008<Nkl<Zc-qXCJ!@1!6o#KOb3byEtRluJMoA%Pv=dvqEsQ at vOxn~|b}7W)VPP*(
z5Ns4dL at -!Jv at jtUER1n6ux7K#HG6Y&Y|i4cNp5o24;&cwvdqjobIyC78BtaKMGF8#
zqz at Pb27m~Vu5k*qfDP+gz)oo)V8A(dUPLBEWV~Sf6IH#J=lN2vLa~TUI_GYA at A2O6
zH~w~>=bL$+-%-^_L|SEq#5s2 at iXxIEA&z52WY=I-MOAMuFE2j;R)Jbsp&jo%Ns>^h
zR0zXx-wAOX$G}<3Q%^z~$1!0T;+!iI^1u-wER&=5iY-9*3RicFq9_7RbZoMe&?fNk
zFcYfP>MC#?$V<CURrBfT=|_u;ix+COTGcs6mSwGay?$zBWMo6ERjbv;#KgpB;2W at 3
zMo5edgTNW!vh`J9c5H0y_5A$&D=XMFU>$f1yaYaoNLtnmDX<Lu0G5C`5eY^|M**Ih
zzyk0c_#`5AGsD0h6v4u}ZNEF62+D1-b>I__07<ji#7^)<MBdq=F>tIbt_q#gYV9g~
z-z%<yk`VU2;;Klf9g-I!;(((Tsy^r3cv)Np2kagZi7X$n{pY>+S{7GDLJBZEJlssv
zlr;V2WbZv?aaAOg1Jr7@`&MUPtpsL<hK8O7L2&UPWOd at o9dsh#BQOWd0`Gv0IF4ru
zOt2 at e4r7M7b{(mz0Dfv}>hZ$D!ljj!m1-14-ANMfz3;}AsOny>Nr3)JrLx*+G_H3E
z3D6Im1Fit0W|VddZT=Q854-^uOVyEWC^VaY1D<z<x&56P*0u~q+DpL>I_EAp=O%+7
z7~d~fs`@0$vU^#UEdkp-lR-po9dP>F-uulg%l;2C?6mPNB7xOW-`^lZ1~iQfn}3ZA
zs_N{{xdB|Y)BN}yG6V%wXxXirTHOFNI>>PMx5;2PZr%F(j+6dzGEflG{;r42X>()e
z6E4{GkSQZ%V&24#11BxnL08zf?bTGX7ghRm0P43^ani4pQUCw|07*qoM6N<$f?lhO
A0ssI2
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-user.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-user.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4258d420b98a019332bc742e15d53497e1012cf
GIT binary patch
literal 5366
zcmV<S6bb8zP)<h;3K|Lk000e1NJLTq001Na001Zm1^@s6mcm%$00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e at S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc at _vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z at C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z at 488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC- at r6P$!k}1U{(*I=Q-z at tBKHoI}uxdU5dyy at u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6 at fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA at W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t at q*0);U*o*SAPZv|vv at 2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w at D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w at Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E at oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim at mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz at C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f at NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC at Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl at Psh8QyPB@KTx+ at RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+ at AhPrP6BK<z=<L*0kfKU at CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E at 6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv at x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV at Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000UhNkl<Zc-pL3ON<=Xbv^gKS6y8_Gu at owkRlz*6o*5 at V}q6 at Bo3fJiC|=rI9ddO
zkYp1Z77W9mMGzp{AfJ_C!wC=wK{n1Niy&EfWynGtuSggHY%uaiwBXR<NJ9?iLr(vy
ztKNI}-YlxRO(l%j3Q|C!yQ*Jxox1njbI&dM`d|MImf461ckbT7y}SE3bLI?;Y}-5k
zscznVHqY~ObqF$<O!j88*>~!?{`O=tIXQps9Ijm1#{1d)`&mo?)a*it at pJwD+8+)E
zgAWb*1M=QOR56`Qad3F>M~8=p-&NJWGT8U<J~wY>OD$w(IOndUl>VNXKe at Kn$J*)|
zeC9z!AS2{?2d4&uZdsPUeROoRL!d7b(W}ee0|0zc6icNm#<;P!clYnQ-R>ugqJW5C
zR##9H5EyEPx~@@&fXsXJdcCLi?;X5y at u`b1X5Qai77%yy9FN;qdOh5|d-tW|<KySE
zEJFwZbzLLW0aX=H*8!of5kf#p2{9$)d5+<5c=^_?pMRN%VTPr4KN^i5i#p3P93CA0
zYMys;RYgjI7$fSchN{9b!(fOpBE|#}g@~ft&9S??`+HlLE`3!*-d-wYufF!$QlT`p
zU+VYQAR<U9BE|@2hM6^=Fr=7}QiO^Cs&MR3*LCms{{73Ux*VY4$;sovn4u_oYzCy%
zMkpl!3{eA96K;`&7!#5R)D&h0Q^PxZd$ugGy{aw+2rv;5s5a?xbrT&i0Reyk(*Bkt
zK~#|>!DU%EfByV|EpZ<J at SB^POI2ANf`l01U0db^h$_6xz)S#ul+q%d&38es*WK+E
z#T$~+a)7okUw-@|@1MT;(>FgH>Kfj8fC(T#)S%wLOfWMfk*3OGgro#(#Pamv!O^b~
z(Y2)jy><KcGNSn0bTYZ*Gmn%ah?+F2C``2_w>JEeCPE=bs2T1bA7APgZ@<XQ%K?fp
zE(7SeuImznRp;Wv<btY#m|zCzLlK&%udZsTs%n^bax6n^|I9NVf9#@8r}Lfb*S~k`
z at bKtkgF&Opb3Jm70VXg25rIg8iXx?i at o0?xss70eFTC(?CnqN$qQ?U|bLPx4!gze?
z(o?UP*&mNaqmOpcg^GYVftf)d7yvVELA4d;-GgU7{><05wl4kqwQJYW>2#K9u8%KA
z(S)KXzOlW%{pO7uH at -D1XT8jOuyZXSz+kQX8)67BGi-lo`!6?6Z~kqJX{qP{fWNc1
zzf{@7pxr!w{q)AhkAD8v?N6+(tN<cl<~gBSju0l(DbAifbNk#APyA~PmHqVQO?0yC
zk)Y=1=KS*ItX$fl5mA|U^B<|nC&UEMhBp9#7%){dY925+HTc2i>CJbT8LEnvm6b;d
zu84q$;GBE6Qa^n1JwVm{{^0vXw|Lo9(L5Xhrcgn9Y{>H*y`uNyI)w3i$Ui!Hj-%uI
zSX*7i2S4~EQcCcbx3(H3t}2`ihXB!{2R$lEZs2}+;lhOn$HzzO(w4aqfedi$K#sAt
zHVCIqt-m>)mipgYlbQnBJcsusB&CI}nHl`f&JMiyI6OSW^o^S!0%Az$^l|`-#>>15
z-0gGco_Ir5o-1cF#I~Kxn<+D+zqWQPl6Ggaa&hgv0{i^|ie3Q_P}NoAiytO+2mvBZ
zQ=F4hM35w5ZFLpn at dSC^0WrfGk$iCW?AgN*0`BeaV^)?(F+wDPiP0Yn!0h6|!C}3q
z(j?f}SVw=*ha`b^6a at MoVBXW@ONwA7s0u=iSYKa<iondw5oy2Q$E++d9#1fui~%#O
z^i}{6n29$}pQZ&-y+ at vR;WLjEBVc$Wn8!>VO*?2vYhWT6F#tUqW88M^;Ij-xuW0Os
zG(Alu0l-GDC_YfEtY9=8qSML13 at l@Hc<B*{$f at d;YF7QlbTYYGmL;lL1xeBrfN4Wm
z03n3l?mN4GUY66(6X^WhFaN*IWz2kaR+cZ#s`~eb!{LX^$pj~(5r(57s(J=#Qi&83
z>Z*qK9$A)MJwCqwO0QRZhMB+Vv+TP>^g4j>e*#1VIL8-M_2m%4%hT!f;%qj<WHQBg
zJi=%+Mp>4Kp at yn8gl|>Xd50|PAcT;0vh2A);W<>e<Jf)EXa1j<`MTlJJ<I<u^m#TV
z`Qp*h at vo;8w^Y?vRfXxa#CSBqWI91Ln<3OS8vD}ZLy18I)O7{tJeUbt=E07E8XsWh
zFNGLhDyQY^8yg${2;iRq)Q<$z_LR-KuKr{?oqoYNx6v3cpss7oW;4vn60>TCx~dUk
zY*VF+qA>_kB5+6uKA at WUM*R)QyE(F~12Q_RBENa(?w#N07TrH!;y)vzAIy82_rAG^
zna}R;?|&nN`o-1NHHa!=Y|K{O4u(}#HA7(vNGT#|S|}_)Z6!9ID8vBA4Cfj*Agbte
z1l~D#@8H;FlhOE7!_oNJet+;;QGJz};SUZDu(Gm3Kl{&He|mI${Nm}2^~Mux(-u;Q
zh$$h2fDi+cG?7tNKn?S0!pxx56fUtY#5KeKVuG4NQiO9JS?1xq2eX4?KKJ(9yI(0f
z`OS-$F23b<c0PjPaQO6%8~^cDW?IX<M+gxy#fBr2kXjeG0AdY+nW_0x=it0+pWeg!
z44HR}n>O~P>5rz0qzY33%-|ej|K7cGz15Zdi%&jz%`-bXI5_;R>12F<ePaWu9al^Z
zOii<Njv?N+irZPt at N<CHk{SlEV=(^$nD@;wfg0~k08}BufHjV at +wEd+@6M;++THz@
z4<S6czrX)GKFb;|IR^s33>dVXE(iogWQB>r(0FQTqc*QHP~#kl8ogx#m>AwU5HlRN
z{+kF)3?c?Iq3GrqPbOQpZrys`i^|n<R_<ipF9>R_`%6jMJtC#p at Td+5?Nl*0^o<G|
zh-m&EsS(FchRkQkIvsSftchCY!QKNzjT``NTA3d_IJxMny84wm)EnwrlDVd<t16^@
zwKDfTF$AR4P8KOaRhyJ80%XlZ(mqs^dO+2XQe#sVAhQhW91MgQ17O-wl_z{%)h8*Y
zo1v;d5 at JM_Weel303<ap4`d##HY#e?TGoft1&}rTQ&9*Bh?<D08iW*-WHEMw8Vj6)
z43nhqCy{Huljr~7oO><Q_4A_oyD_F;_Kw%h%taAMN>CA~86+uG1u%uE!BpDur$It(
zza~<s(!w(*NpQ^YnTKnm1JhE~Zi~pb$?z(OZWwUS!)yfLCm{R;z`qb-$3Pz~dd1bQ
z>C+*Et?9HpUyjEv#ekF)+8TTVK-`Arp)si8MdQ&sSqH^R4 at FUox<zr at G2axC8zA@N
zB;ki<*khoc8>DyjG6Nm}xXw)1vn<PsqF7sBKeg at H?TE;g$z-%OnUtH8>7+L+XT1<Y
zM^v1dF at eC&r7ZKQn-_Iabf>GUtHb`Fe}{;F7Gr#~uItw)lgWXZ)xXe+cW?hS0K=Ts
U)&>o#U;qFB07*qoM6N<$f|wvR(EtDd
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-volume-default.png b/src/wok/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac906c7723e9c26900c347cf5e47e3192a5b2f88
GIT binary patch
literal 4265
zcmV;a5LWMrP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000U_X+uL$Nkc;*
zP;zf(X>4Tx0C?J+Q)g6D=@vcr-t<CCh=7z!Z&DQqAW}k$fE1A?Dj^9FN{At$*%eX2
z5k*A=8_1xD1CEY>j1^HV42lZa2jn55j)S9!ipu-pd!uXCy!YnK{<YUW=dAOcv(E>>
z2n?1;Gf_2w45>mM5#WQz#Kz&|E<k|_Bya!_2(x4%bNwR$0Qi19JS!r=2fhFSc+(3A
z0KiR~z%U$#{}1XynOp&YgaN>GkvK~TfD`~gdX7S-06<0ofSs5oQvjd at 0AR~wV&ec%
zEdXFAf9BHwfSvf6djSAjlpz%XppgI|6J>}*0BAb^tj|`8MF3bZ02F3R#5n-iEdVe{
zS7t~6u(trf&JYW-00;~KFj0twDF6g}0AR=?BX|IWnE(_<@>e|ZE3OddDgXd at nX){&
zBsoQaTL>+22Uk}v9w^R97b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&JM25
z&Nhy=4qq+mzXtyzVq)X|<<F~dKmY*YbbitPEHASffI9|&ZT_Mq?gVIF3!ruPi)OM9
zK(zp%>DpKGaQJ>aJVl|9x!Kv}<mA{nwP%2$2<XTo2=SN&}Hemwm5_29nZB!Mzr
zfky=R;KI!GOr;#pk_m)j+~$u*{I?7L{2kLG#7SbgSSl3bQ4(>EM4F8AGNmGkLXs)P
zCDQ+7;@>R$13uq10I+I40eg`xs9j?N_Dd%aSaiVR_W%I$yKlkNC<p_9XoKO;cmMA{
z{YRiB0Dxvml5qe4UPL4=RLZkI#|QubM4*8xut6L2!5A#S1{}c!+`$X{U^aw8B*el(
z5JC!MfE;pQDXfA*D2C0j9V%ci)Ic3Hz)@(1lW-0$!d18qJ#Y{DVF;eVD7=9Q1VP9M
z6Ja6Rhyh}XSR;-I7nz0lA;Cxl5{o1t$%qtDB1 at 4qNHJ21R3KGI9r8VL0y&3VM!JzZ
z$N(~e{D!<oF_eL_Q9aZQwL`h6HyVUSq6^SubTOKb7NDEZa<m#fj5eX?(5q+<+K)a%
z$1uR?7zZ=NY%ngy!$Pq*ED4ii%dsM?46DW(uvV-CyNUH<&#`v|5`jg)2{r_GLLgxt
zK}c9kSWehTs3069G!fbfHwgoTQNkx8lc-CyCb|*%#28{SF^5=4EF;zuj}tEtdx%5C
zHzX2?Loz41kOE1uq*T%p(niv5QX}asshc!N8Y7d*+GK082RW21AS=j)<elWh<TK<O
z<RS7~3Y}s=aisWD;wVzeYDyX95al%G24$EsK~<xgQr)PbR1r0gT0*U%wo<QAho}=Y
zb(%TNgBD3krLCfs(;8?OX!mKa=ybXf-IX3rm(W+z%jrkxm*@lZcMJ`N6@$l!XDAt)
z7zY?<8Fv`3m`tV_(~B9$R4_L&>zL=651DUOSSq$Ed=-((3YAKgCY2j1FI1_jrmEhm
z3sv(~%T$l4UQ>OpMpZLY<EaVMmaA2&olxsj8&hYgJE(`MXQ*#fKcs$H{fP!y!%V|Z
zL!?olv0vl7#vlu08MAmSA!`k*hIN58#3r%L*?e{?yO{kQyNf-lsi8STGfFd8vr_Yv
zW<Lkxm~r@=bWRE9D5sb6eu~}{?<wLb8>Tc&xiMv2YpRx)mRPGut5K^*>%BIv?Wdil
zy+ylO`+*KY$4Vz$Cr4+G&IO(4Q`uA9rwXSQO+7mGt}d!;r5mBUM0dY#r|y`ZzFvTy
zOmC;&dA;ZQ9DOhSRQ+xGr}ak+SO&8UBnI0I&KNw!HF0k|9WTe*@liuv!$3o&VU=N*
z;e?U7(LAHoMvX=fjA_PP<0Rv4#%;!<CI%)UCQD7~P41dfO}VBiraMeKOvla4&7#fL
znKhd|G1oHZo9CO?o8Px!T6kJ4wy3taWl6H+TBcd<w!ChIS~*#zSXEkGvqr6*ttHmG
zt-GfYr at 2m(POF~QXTz}Zw#l}sw;8bI*aq9Kwr#e3VP|3&XSc<!!|s#4lYP2<jr~0b
z4Tsqds~uV$esi>P6gpNq-kQ#w?mvCS^p@!_XIRe=&)75LwiC-K#A%&Vo6|>U7iYP1
zgY$@siA#dZE|)$on;XX6$i3uBboFsv;d;{botv|p!tJQrukJSPY3_&IpUgC$DV|v~
zbI`-cL*P;6(LW2Hl`w1HtbR{JPl0E(=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$
z-ZI`<U(7eax5&54Ps4AXUxnX8e<S~7|9bz?0H=T at 0cQh=fkA;=0{i%Sd?CM%KRVlG
z_OjXSL5!feK@~xdf~|t(!L1=^$n21<A@}E)&XLY(4uw#D=+ at 8&Vdi0r!+s1Wg@=V#
zhChyQh*%oYF_$%W(cD9G-$eREmPFp0XE9GXuPsV7Dn6<%YCPIEx-_~!#x7=A%+*+(
zSV?S4962s3t~PFLzTf=q^M~S{;tS(@7nm=|U2u7!&cgJCrxvL$5-d8FKum~EIF#@~
z5Gtq^j3x3DcO{MrdBPpSXCg1rHqnUKLtH8zPVz`9O?r~-k-Rl|B*inOEaka`C#jIU
zObtxkn>wBrnsy*<GCexIF at utkka0q)Ax)FEXX<C>W_HW0Wrec-#cqqYFCLW#$!oKa
ztOZ#u3bsO~=u}!L*D43HXJuDrzs-rtIhL!QE6wf9v&!3$H=OUE|LqdO65*1zrG`sa
zEge|qy{u|EvOIBl+X~|q1uKSD2CO`|inc0k)laMKSC_7Sy(W51Yk^+D%7VeQ0c-0E
zRSM;Wee2xU?Ojh;FInHUVfu!h8$K0 at imnvf7nc=(*eKk1<r{}@%D<W1l(ea<#JOb8
zX3}Qq=H4xyTMm}0m*$raZVlPmv<=@@wC(lwMcXfz%_!TugSJDtqrW`3yk)1!&dobN
zRHRh&RQgml?$X`0Vb}O>(e4|2y!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu8FGY
z_?G)^U9C=SaqY(g(gXbmBM!FLxzyDi(mhmCkJc;eM-ImyzW$x>cP$Mz4ONYt#^NJz
zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{
zoHRUHc}nwC$!Xf at g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR
z&Rp`ibn>#><r7!9SDLRnUv27i>OB6F(@)2{oV%K?xm;_x?s~noduI3P8=g1L-SoYA
z at fQEq)t)&$-M#aAZ}-Lb_1_lVesU-M&da;mcPH+xyidGe^g!)F*+boj)jwPQ+}Q8j
ze`>&Yp!3n(NB0JWgU|kv^^Xrj1&^7J%Z3ex>z+71IXU7#a{cN2r$f(V&nBK1{-XZN
zt``<Be)!ev*Ur(H(V>^}my^G3e5L*B!0Q>W+s4Ai9=^$VGcjKDR{QP2cieX!@1x%j
zPvm?ce<=TG`LXp=(5L&88IzO$1Ou4!{1CdwXaE2J24YJ`L;(K){{a7>y{D4^000Sa
zNLh0L01FcU01FcV0GgZ_00007bV*G`2i*w^2m>lc;ERj^00reqL_t(o!|j-DY*XhI
z$A8bg*VnP*B;X`KYO)m4CLKx3IzlSYsKi>8s;kt3T7jZMHKA&4wN(u5ecFd<-IpO1
zX;WXOt*h8dtFcB*Rn>PYXr%%Pkdgvxng-FZm4spkg6-JX_ujJ)wu774#SRYJhn{bK
z{9HZ%bI$*N&UqgA%C5{*-o+<+8h{@FO at JS$1AM?mz%Da}IB)`ZMz(f-dRc(#i5>+U
z1NL;x_YVg=da}-EjMbQWB9d?dwkujW!!u#Kp0|g`n}M}Ji)`(b+$~0)&#nQ2_Lh#6
zD{PC|E;XiJ=Aa3JV%&15G&FQgJ*jW+tpFARr*n5sMq}-+qx$VTdTt1K)M8-NfroDE
z9w7Ae5&rh^SlOBN+(%(TPxrCrr2!mRBM@%(tL1m>JW`t%;9x at cMJg(XqA9U}M8X!1
zo{bZWJG}FsXxYhscr->VVbeDn=R(R61u_(ulV at Dh$(!P1o7$rQ#`Ye=7Q~~VZ(|!r
z&Q0*0uT^0=Zdn0tTNz??V>Qd`eFT(JSv`EXvHg5Oku*Hj`)D{Rk6W(Pn1-gQt5ixv
zkd*66rOv^ofU)8D=4Hdv09O5>_tt2NeIhPthpw)Pq{U<E+HPyh@^#Zve9^+MlrR%)
z^*)0qzum;@#%fZou=|rSe)`^NqN(C(kv-QE<;%-Kr2r{Zy1(3BzUO*wX$a6g7@@Js
z<dLQGs4x_p-#j&=&LR0!T)3}%xy|z%+|m%><)Ja|e`Sc({}>=@Io#Vkw=AhQrqs`p
zL5?RKR=jwEk$5Uy<tsgyy5jUjYZd^`Ac6@;I5-jmpt;7&d+WcB?Fx_W9i9b%S7?8|
zb20TkgIjlf#QrnU|Bn>sTK8at=l>Nh8 at RHFB-ehpYys<AgJrFcWsP7cU=p>Q*#Rhm
z0)_fQ6)G_u+k3CPp-6!gSDQ>|noPEw|3$A8P+rZQ$Q!{m^Ymi}BF^Ts2_8tgbgXU+
z_%+nzq-wcBIAP<_6(W#wTrMOXqA8cfbG%f0bUZoZMa*^?97_<6r$AGeI)p2%YOKc0
z?p2U<-1z&S#T>uRt{ZE#=MEH-#a%D-&fj;AP~4Vh?JXV6N~x;c4NcGVaeCYWLjxrQ
zD?A+B*v|L&oZ|I?2oHX90SU|D_C+;pz9EQGiZ}j!k at dR=xsXa<W$OJVXCMB?RO%1v
z+k0b+{ro&Mr}C|LH?%o<Rs3q#^3k|0?lkNfVytVcLp&Oia=2?zkiA_?Sld0o>w^)L
zM`K6d2!B8RIS;)$#BUFcq%*Uyic{ZP$}d-hz!BDERW8$MbTZCJF1X7S>KsXDMvd<-
zspF}`qdc~%k*?Mt%l^`j1t>l3r!p at 2`>VafSOUN9Y+#P5^Z1Goo7(CzRayzfj&xcn
z^17+k$AOLQR2v!{JC0$AprpWXXK4K9-C;JoHZ=KtOSQ?hRc1-^X3+qZQiupQ*H-Ys
z**LE4=FDi*hdU*L(lvG+4|CruLo>cimvqO?g6zJ#nIC^^A-V{XS(7Q`$o|$fXsz>M
zsF_t*qr^vtNszx=8KSEt$hN~H{PW`o at u+o)_X+}4Cik=i`Ps4swAcF5X`jKkUYtns
zfJ9(vZ3R2mEFyWwwS02kqCXr*DYz-<<GMLs%#1T%nCY+DxRq&)2zZsEZLXKLx!!3$
zmLLcl at RZ0w$=@K0oq$v^O;@tVOaK)n0907E&>Kn2TKnw{PcUIi))5OZiv~F1x->o8
zPv;*$;3xaflpWkJ4tz%EpN`V<=YGa*mrQz7#Q at X*S652a`3#g-W4_<GED;Ko8JR|y
zv<1Be%Bxf7Gw^6i0hO6FUsfbzK)qK}Z})U9x%Yh1;hIWMUSMv<8#M)hDsa!uUH{R|
z^XY0067=e5B7?w6;AF86nEf729op1hXDz7oBt;;Wa?GS7M(&}7fXNhaDo+Hn|68ue
z&J*WU!j at Lq+PSLOC*XQu6VQ=){>`dvHWVY7$o*cncAnuYE3^F<>K#$%^M|uQ00000
LNkvXXu0mjfnm8lp
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif b/src/wok/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
new file mode 100644
index 0000000000000000000000000000000000000000..aaa4f85a0560dcb59d4bb70154a9144417aae926
GIT binary patch
literal 1653
zcmZ?wbhEHb6krfwcz&0`fx$V3fzy*s(30KRoyj+pP0*a%B9B4Xkl)0X$H9|dJd8D}
zo<ZDBSSFF7*jZT0OhTc9Q7nTgk3rREDud*7MxI>8&Ju=(ISf+93MQOdag7Y~1hic{
z8T#{u6)cohTNtM^7+W$J#50+i$>`cj=^O84k`pyFn#{1$Ur8%a&i6QjtgEuCfQhw>
zh77A6gQ$gokA at _-E$2dp^>Sv?oMy2Rvbjr`S1FsTIOwZtnQE_R*m$2oUC1KhF at wT7
z#vS5TPBXdYi#jqhIC*|#&}Xr)`pY25?86wZk@$x}Azj<#4}*rAu{Vcnu(UhJUj}_&
zGsWW!mvn9Irz#jqI|d0m<_4Kq$D4?%x#%8bJFV#KwS(tqvz9fdTmMyIV-~+CKU<>^
zTODbStQ;$e9OEp8kfaJrQB(IojUXN?PfLA&1ruKlE$<Ybz{O>Dnh|c+IZj3l84L_z
z+ZiGkGQ_8gg)Ec{ZB|VbVu;;p8Ir+}TJcZ8St};J)7e)ugI_wAy~kUSA^Gq;v#nzB
zo6<uZ9TN=&l6EuXHCx41&a>X&p6tkweNrgxtWY&KLrITauKX0wDL;*ZSPITdWuHCl
z7S2#|o1wN-skGcGd-j}YNrw7v?ff;HUH7htly%83WoVk=SR=P3TA8QnVNZtdt|Td^
z4tBRT;l<gOCKJSuq^f)gOk<w3o@>%d>z1S5joVY2V;E+x4Cszxn7#dGQiZ}|@k{wq
ze5<)H#@>~ixp+mvx~nC^*GqKvReGJxyd=J8Z|Hp0)LG8{Q?7j|(|J;(^S(;?X-VtX
z{Ej0{$vo>WNUb at RHtpd12Emt&YTJ7ve>HRaY*WxWB$BmO<7<oVrMfE&d+u577yI7H
zdv${AuTG6`J!)PD74G*(XRN&WpI$)mKewN2NU*bGfUA+70W%{51B2pE7EU3C{|q`n
zHZYS2Ffee)GW_S1 at z}87U^9oXR?LYF3lFyoD0|KE*tqCuBO at a=9coY=j!k!j<aB0i
zc<9u4hfS*nq@!EHIP1=djf>s;v1`@Ep>^V-!(BqkNq@`*laF`Fn|H~0Zd!7(0h{Hf
zM42F;^~FLc<zy?bzucZ38xtI`nPf?{Nk)rZI#dI#a%KcAJ>AR3%!JJ}Tb!mjcL>V+
z&Dl|qe5_B>QtnB`#6;Il`9QBD85<TlO;@&EX5(p~fXzf_h=~b~c^s at tPtrczcWUF8
zl$)Y)G4W`lxU|rj6$Xj!z4E$EBA!9O at K)2-%Q<1V)NzW4rQ4Q{qQ at s^Df6<iU^CYa
zVJ@$f%ZvcUgKd2BZZRt+Jap&~-N|`mN5EtIK6cxtnin4*pO_@<TefG1V5)aFPwc)q
zGcP6L3rdhvk&Uz{R5;QluAbJjV`8#<o~Uk<jm4+?Cwh5=mxY`NNH{%#3wux+Vs{|2
sX~(-16pJpOC{Q`pufUDnn>s|9;tWh`McC5^G?`;~3OSj#0+YEl0GD)I?EnA(
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/loading.gif b/src/wok/plugins/kimchi/ui/images/theme-default/loading.gif
new file mode 100644
index 0000000000000000000000000000000000000000..60d46d2683817f81a678c5e3eef14ef35089d119
GIT binary patch
literal 2190
zcmb7_`)^a%9l+0hKYVRpUtc?ZTqoD at wG*cy3TcL*WhlA#65q>!8Yk0A87qcR5=z^Y
zJ}6yLW8%anCg23f7(z>6v~*HCLD#C)V8TgAFyR#lkMIsJ2?Pk}#t-{tn<Fg<w4ZkV
zfO9_jobTtHkX|!=MwA6Cc<KdxeSQ7?{R0C7hYuef92^`P8ai_1NH&{2di3b<@bIx?
z$BrLAe&WQ5lP6D}I(2GfWMp)7^z7NQ=g*%X8ymZL@#5vnm#<v8a`o!f>({T}ym|BX
z?b~<m+_`)A?)dol>C>k#UApw};lrm-pWeH7 at A2cuH*VZGbLPysbLXBsd2->xh5PsK
z- at 0|{(W6J#u3dZZ;6Wyn0ssH<{@XBrc3rJf9iClLR*pcq9lZaVGA~-cTwJ<V{Ke|%
z2aWGEu8xZHm#<vbu>9kwSiEM<nzB{zMe7^iee1olcb9({1m1t57!ACjbmI64F96?~
zNjEu4wk5OaB at yzSY2Ieh>Dp5^|8B3&GwnsKbC7a$H`o>bJ6m5!w>ATZM9Td{e3$tc
zjWsG1+oB*VWX5JIAat18f--iyEv<EJRR~i;Cf-a2+&r9sn5K5WWP~^dMM?AWd`gCE
z4IaD(EhZaO$j*A%VPl~Ei22Rqa||PO<e*;tUr^ukpc^xtP18S}nbda0%ZKZ0T8G8p
z_-8v_JHB!bzj0=-y7w>S?6jprX^u%;*E})&m at X<btU+0Z`K?TbG#Drbp10yUgr|`W
zsSa&(r-C#3M;hzlG(efi#Oyo+#L@^tFaR at dgJjB%nal{gP3J>3K01G|X8g?nL><w6
z1aWE-(DOXthRmj>vG=DZwWyk1N)@fI550V^^3~sM{VqGB(zZ9UqMYs4nAn|Im0Hn~
z{i;yVrft2O-bY1gl?bVTGbl921)4R0peU3hjHkO4jMfoIh0S)hN5$!GBTqrAU<9K!
zQ>fBI7Nbm~>HA2)=sDmanMH~IArHQ2N4Gjj=YF1UW2U3&$7p$uu5sV~x at o8$(JFq{
zQ?RMoL9TM`Q0{C2YvY$s-1?Rb3kd}E6 at MR4w9p)(etw>YhcpYVkSyy*b-Kjm@=y4q
zJG&H=)FGf5t!5p;=gNiv2^a!~zXVWjG;kK7D2V<_1Nn&qZj7o02i=E3cdd+`d<G~z
z516XzYSP{)O=^*G at 1AhHbI(t(cZP25_-<_K+yL2$T<n!#uC4F!K60k8Aw2Tu!l}LH
z*y~}*ODTleyiBJ&PN%sg9!a*(l at US%Tu6av3j<Wx?R8)>m5&1ogCH1zEIykIdN33G
zHozeXK{SSx-ahn21eb>-c#)EcObQg9=WDOp)RbLNoD-;II<@#0d(uBO%<_AJMbY5)
zxrDK0fG^8H$=%_mFuG}8{n+-Iuo|0PS<SJ!nNTpM4bjQcl&LkbAysNpU`)4!RMJGL
z0Cg7S<wg+&I069YM*LHF4WS_vF?c_y*Qjn36&x=m^}Rwyz-)tWK%YFz<AshB6CKN9
zQoA9Ou{gfDs-k{ne8;a+ACiDy5RV)kS;$%Qk at 1+wI=ZS_>NuRY)O3A2)tE#G-K3&a
z0 at ewe-OjWn+Y4;APe1-#V{>pAjcbTQEI{Qp1fVeei4!&poCd9QmC!{W)ncE!-QK)l
zt#^a>kZc_~ytH;w-3#faCenRHNM<df#qsleU$yT~|0v!$LbSe8QH7gBeO>Id108Vl
z`woUrXKup3EEFgZITI5xOlNQf!4oS~+{*KYwxpiwFem`l&7{_bY*+1tR;3w&+#E%*
z4%p<fXcn)*<Dta-1v_7I_?%8(fzYEOwwP1$q1>;P*XkzuUMM#?QErgWJuTJQC1jo+
z*gg87a_(tUpSOVvk7m+o2jE&`;0Y-ecSNiAOSssb$js78Hpvi*zNKRUj-%JdK~9}w
z;B*tAVh*nxRbk%Et at GG?7Q|^GSJ at X!ei>QkFQQ9J3Bj~5nCJPyV|6Wnt#Za=S*Vx}
zJiFKz!tIy{*UKg~FSJjWrp3^ge_veLL!aVjgjFk&go4E=Xp2=fEdlJ8gH7rAvjRp*
zOshhx-?g6BQ9sL)F;_`kYfF*}ZPA%!YF?2O(KrvQSf}`52TKqp9x~*aWmwJ^sRA3}
zS_^%qz(RrBW_Jf9UFJdqxv|Wu43nMI_d>a?6Xm*?oW81t^71YH{rh#fJY5sXfCgH?
zI3Rw#u`re!ykhCEe^7brrP2hbQ7vMbq!S_8>~wlo>*f at ZD?>AF%zY_39aYc*(V??;
z^BPXbhj-0mIEdnnorR>;ihB%U$z_#zUSjjs=@$8K@%|qTKRk2yzs*u;Qajlj8D~iW
zRL*!kx^qN^gKUkQ>Jxh%V(^<YOMDQ(@!&xD!JQSO(f(LfNuiD{mQAH?>okN(VXcX}
z6f;jI%sRPNwieo3WXNnaDi*g1=1mwzvk(z5D2o}_z5r%lqzfKS;0~GjgMwe~6W~7%
L$~1kj8oc at +?)_VM
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/user.png b/src/wok/plugins/kimchi/ui/images/theme-default/user.png
new file mode 100644
index 0000000000000000000000000000000000000000..c57a81a92757ef31c424a4e6c741f71db62a1092
GIT binary patch
literal 1322
zcmV+_1=aeAP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%t=H+RCwCFS6xgTRTRGSvwt(QEW2!%
zZEC<RY*%PmU|~TT(9l}brY~)zO*HkzHZ`VcV>GER{yyo84?Y{zXpHs6S4l9Y#$eJ`
zmI9TeNz<hS;wC6n(*0#;*YAuwlVv;L6r^`@m^(Xj at A=NT=X~eDmCI%J$6w2=dc>kV
zY@@+(9ODK4xF85;1zu=k91CHOq^hbvsYP|PR4&aWrYD(|;jiDtI5Pm<(b&U^nWnhO
zZnuB!bUFte4hIuOQ3F&emDt+a8q4K!YCf0$1oO+2)4!@#0EkwQl5$ualok1!EXhHq
z%gJmu8{>K206<bG6ogDB^F}6}*^Ol{S=pO6{k6PaIG$r3kLNqL+Z|Ng3M1<QNK>wD
z0wClKm&?WQ4U=X0#ew+2^IHe7-h8rlfP at r~VhtmXu2yJ}XCzr-e!u_2cz2($B>?5B
zi|2UO+S2;E!|Bj0HB)Q`0>S806y at n{9{~c7$%@p!ndP-YM`IIhEY=e{_Fn+RjXY4D
zb{x;w(OtLDQsClyUxV+7?FS)7Fxa?e#qxE6tFbYV-gXdDdWFN`J9K{(0F)I&&kRj$
zI|#vW?8M0vpCb(|D<`nShlY!hry^t9K7x{3LJ-PdzWUnvKdl1r at A9)#r$@fP4l7&p
zK#etB9o>b2g9B$ST)a at CRMeTzOi1}V at 4bC5&=`2jO0Zg at ViXxFP-BUi$(LJN_Ksfp
z=3D3WYuB~o(FYyT;UkCH$jA$KK}644v0lp-vto3ht%C^2h1~xbJa874jpHaz!TRjf
zY@!{XyqnEtPcAMl+BGYX^P$j_DNIKpA3+{;9_VVv`tOm%b^yJ6^VZZ?maAd3z0;0@
z^8+}4h*+&yEHYHNtJz%k6}(OoDNW5J6wD))C57Iu_-s)vYB2+#M<hwQVt3em#0U9&
zo&oSVtQoZgARg=c6uf^<=YBd{Y`}8a9F^U1Jl{ry%u<!a_#1N%?h2Ge at cpwW*%8Sl
zF#ymAiApspWGS6aAB88zHwA!z8&qWFXDTRUy%7gEZ}J3fMsuAPv~1!2Wj+Ec3L+D2
zqQ(OhuzFCF7qC8cf8~C7W^Vd{X+O}>78M%&4WH3QB-PYQo53<|<J#h5P&Rc-l^#J?
ztdGi32J7nTKEUIfrfCS5pT-%6Ny$cqM^~a*D~g8DbG5~0>&O6nb1AyN(`O36>+`;^
zE8i^Fw<;AciT(!v#fQ?cbAMMCx}7NsJl&F=7!*g?e<hVl1yaAKR6|o}Z|D*QkY09o
zN@#y%ln=dSY#kHg^-=2m9;N1QW$4+`+|+aik2gd;`n?U_M)dhR4nPNiKf{Ix&_Fij
z3wd5}JSG6RifhF^Mi%tOdm`1jyVF9%1!9s64=8STpq4mxa*!S{s%Us%UnHDGZax<4
zb!iSYtJOTviuu)rdkcFeCVpX4i3FROnWX~qzgZm!1kk2;v%da**4x{|>b>>js0Gj0
z79%RJ$03IxgUidyp5)ymo1dR&^T~O(w6w(16;L1%wz|4%C<yKjGVr{ij5;GUFVxVY
zR|qke<XXV1A0cCv`|^h6xNTp%_8-x2w{KCTwpR&x%A<1^#8<T}S=9xRvL(nY<R)Z}
gniR8!<R1YB09_*wa#VgYhyVZp07*qoM6N<$f^kM~^#A|>
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/js/Makefile.am b/src/wok/plugins/kimchi/ui/js/Makefile.am
new file mode 100644
index 0000000..c9d1218
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+EXTRA_DIST = src
+
+jsdir = $(datadir)/wok/plugins/kimchi/ui/js
+
+dist_js_DATA = kimchi.min.js $(filter-out kimchi.min.js, $(wildcard *.js))
+
+kimchi.min.js: src/*.js
+ cat $(sort $^) > $@
+
+CLEANFILES = kimchi.min.js
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
new file mode 100644
index 0000000..fde803a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
@@ -0,0 +1,1355 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+var kimchi = {
+
+ widget: {},
+
+ trackingTasks: [],
+
+ /**
+ *
+ * Get host capabilities
+ * suc: callback if succeed err: callback if failed
+ */
+ getCapabilities : function(suc, err, done) {
+ done = typeof done !== 'undefined' ? done: function(){};
+ wok.requestJSON({
+ url : "plugins/kimchi/config/capabilities",
+ type : "GET",
+ contentType : "application/json",
+ dataType : "json",
+ success: suc,
+ error: err,
+ complete: done
+ });
+ },
+
+ /**
+ * Get the i18 strings.
+ */
+ getI18n: function(suc, err, url, sync) {
+ wok.requestJSON({
+ url : url ? url : 'plugins/kimchi/i18n.json',
+ type : 'GET',
+ resend: true,
+ dataType : 'json',
+ async : !sync,
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the host static information.
+ */
+ getHost: function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host',
+ type : 'GET',
+ resend: true,
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the dynamic host stats (usually used for monitoring).
+ */
+ getHostStats : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/stats',
+ type : 'GET',
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the historic host stats.
+ */
+ getHostStatsHistory : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/stats/history',
+ type : 'GET',
+ resend: true,
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ *
+ * Create a new Virtual Machine. Usage: kimchi.createVM({ name: 'MyUbuntu',
+ * template: '/templates/ubuntu_base' }, creationSuc, creationErr);
+ *
+ * settings: name *(optional)*: The name of the VM. Used to identify the VM
+ * in this API. If omitted, a name will be chosen based on the template
+ * used. template: The URI of a Template to use when building the VM
+ * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
+ * suc: callback if succeed err: callback if failed
+ */
+ createVM : function(settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/kimchi/vms",
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json"
+ }).done(suc).fail(err);
+ },
+
+ /**
+ *
+ * Create a new Template. settings name: The name of the Template. Used to
+ * identify the Template in this API suc: callback if succeed err: callback
+ * if failed
+ */
+ createTemplate : function(settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/kimchi/templates",
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success: suc,
+ error: err
+ });
+ },
+
+ deleteTemplate : function(tem, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates/' + encodeURIComponent(tem),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ cloneTemplate : function(tem, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates/' + encodeURIComponent(tem) + "/clone",
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listTemplates : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Retrieve the information of a template by the given name.
+ */
+ retrieveTemplate : function(templateName, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates/' + encodeURIComponent(templateName),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json'
+ }).done(suc);
+ },
+
+ /**
+ * Update a template with new information. TODO: Update me when the RESTful
+ * API is available. Now work it around by remove the template and then
+ * recreate it with new information.
+ */
+ updateTemplate : function(name, settings, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/templates/' + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json'
+ }).done(suc).fail(err);
+ },
+
+ /**
+ * Create a new Storage Pool. settings name: The name of the Storage Pool
+ * path: The path of the defined Storage Pool type: The type of the defined
+ * Storage Pool capacity: The total space which can be used to store volumes
+ * The unit is MBytes suc: callback if succeed err: callback if failed
+ */
+ createStoragePool : function(settings, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools',
+ type : 'POST',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json'
+ }).done(suc).fail(err);
+ },
+
+ updateStoragePool : function(name, content, suc, err) {
+ $.ajax({
+ url : "plugins/kimchi/storagepools/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(content)
+ }).done(suc).fail(err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ });
+ },
+
+ startVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/start',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ poweroffVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/poweroff',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ shutdownVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/shutdown',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ resetVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/reset',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ suspendVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/suspend',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ resumeVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/resume',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Retrieve the information of a given VM by its name.
+ *
+ * @param vm VM name
+ * @param suc callback for success
+ * @param err callback for error
+ */
+ retrieveVM : function(vm, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ /**
+ * Update a VM with new information.
+ */
+ updateVM : function(name, settings, suc, err) {
+ $.ajax({
+ url : "plugins/kimchi/vms/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ deleteVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ vncToVM : function(vm) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/config',
+ type : 'GET',
+ dataType : 'json'
+ }).done(function(data, textStatus, xhr) {
+ proxy_port = data['display_proxy_port'];
+ wok.requestJSON({
+ url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
+ type : "POST",
+ dataType : "json"
+ }).done(function() {
+ url = 'https://' + location.hostname + ':' + proxy_port;
+ url += "/console.html?url=";
+ url += encodeURIComponent("plugins/kimchi/novnc/vnc_auto.html");
+ url += "&port=" + proxy_port;
+ /*
+ * From python documentation base64.urlsafe_b64encode(s)
+ * substitutes - instead of + and _ instead of / in the
+ * standard Base64 alphabet, BUT the result can still
+ * contain = which is not safe in a URL query component.
+ * So remove it when needed as base64 can work well without it.
+ * */
+ url += "&path=?token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
+ url += "&wok=" + location.port;
+ url += '&encrypt=1';
+ window.open(url);
+ });
+ }).error(function() {
+ wok.message.error.code('KCHAPI6002E');
+ });
+ },
+
+ spiceToVM : function(vm) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/config',
+ type : 'GET',
+ dataType : 'json'
+ }).done(function(data, textStatus, xhr) {
+ proxy_port = data['display_proxy_port'];
+ wok.requestJSON({
+ url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
+ type : "POST",
+ dataType : "json"
+ }).done(function(data, textStatus, xhr) {
+ url = 'https://' + location.hostname + ':' + proxy_port;
+ url += "/console.html?url=plugins/kimchi/spice_auto.html";
+ url += "&port=" + proxy_port + "&listen=" + location.hostname;
+ /*
+ * From python documentation base64.urlsafe_b64encode(s)
+ * substitutes - instead of + and _ instead of / in the
+ * standard Base64 alphabet, BUT the result can still
+ * contain = which is not safe in a URL query component.
+ * So remove it when needed as base64 can work well without it.
+ * */
+ url += "&token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
+ url += "&wok=" + location.port;
+ url += '&encrypt=1';
+ window.open(url);
+ });
+ }).error(function() {
+ wok.message.error.code('KCHAPI6002E');
+ });
+ },
+
+ listVMs : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms',
+ type : 'GET',
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ listTemplates : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ listStoragePools : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ listStorageVolumes : function(poolName, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listIsos : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listDistros : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/config/distros',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ stepListDeepScanIsos : function(suc, err) {
+ var deepScanHandler = {
+ stop : false
+ };
+ var isoPool = 'iso' + new Date().getTime();
+ kimchi.createStoragePool({
+ name : isoPool,
+ type : 'kimchi-iso',
+ path : '/'
+ }, function(result) {
+ var taskId = result.task_id;
+ function monitorTask() {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ kimchi.getTask(taskId, function(result) {
+ var status = result.status;
+ if (status === "finished") {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ kimchi.listStorageVolumes(isoPool, function(isos) {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ suc(isos, true);
+ }, err);
+ } else if (status === "running") {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ kimchi.listStorageVolumes(isoPool, function(isos) {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ suc(isos, false);
+ setTimeout(monitorTask, 2000);
+ }, err);
+ } else if (status === "failed") {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ err(result.message);
+ }
+ }, err);
+ }
+ setTimeout(monitorTask, 2000);
+ }, err);
+ return deepScanHandler;
+ },
+
+ getTask : function(taskId, suc, err) {
+ wok.requestJSON({
+ url : 'tasks/' + encodeURIComponent(taskId),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getTasksByFilter : function(filter, suc, err, sync) {
+ wok.requestJSON({
+ url : 'tasks?' + filter,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ async : !sync,
+ success : suc,
+ error : err
+ });
+ },
+
+ deleteStoragePool : function(poolName, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ changePoolState : function(poolName, state, suc, err) {
+ if (state === 'activate' || state === 'deactivate')
+ $.ajax({
+ url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/' + state,
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listNetworks : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ toggleNetwork : function(name, on, suc, err) {
+ var action = on ? "activate" : "deactivate";
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks/' + encodeURIComponent(name) + '/' + action,
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ createNetwork : function(network, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(network),
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getInterfaces : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/interfaces',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ deleteNetwork : function(name, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks/' + encodeURIComponent(name),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ listReports : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/debugreports',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ trackTask : function(taskID, suc, err, progress) {
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ switch(taskStatus) {
+ case 'running':
+ progress && progress(result);
+ setTimeout(function() {
+ kimchi.trackTask(taskID, suc, err, progress);
+ }, 2000);
+ break;
+ case 'finished':
+ suc && suc(result);
+ break;
+ case 'failed':
+ err && err(result);
+ break;
+ default:
+ break;
+ }
+ };
+
+ kimchi.getTask(taskID, onTaskResponse, err);
+ if(kimchi.trackingTasks.indexOf(taskID) < 0)
+ kimchi.trackingTasks.push(taskID);
+ },
+
+ createReport: function(settings, suc, err, progress) {
+ var onResponse = function(data) {
+ taskID = data['id'];
+ kimchi.trackTask(taskID, suc, err, progress);
+ };
+
+ wok.requestJSON({
+ url : 'plugins/kimchi/debugreports',
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success : onResponse,
+ error : err
+ });
+ },
+
+ renameReport : function(name, settings, suc, err) {
+ $.ajax({
+ url : "plugins/kimchi/debugreports/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ deleteReport: function(settings, suc, err) {
+ var reportName = encodeURIComponent(settings['name']);
+ wok.requestJSON({
+ url : 'plugins/kimchi/debugreports/' + reportName,
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ downloadReport: function(settings, suc, err) {
+ window.open(settings['file']);
+ },
+
+ shutdown: function(settings, suc, err) {
+ var reboot = settings && settings['reboot'] === true;
+ var url = 'plugins/kimchi/host/' + (reboot ? 'reboot' : 'shutdown');
+ wok.requestJSON({
+ url : url,
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listHostPartitions : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/partitions',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getStorageServers: function(type, suc, err) {
+ var url = 'plugins/kimchi/storageservers?_target_type=' + type;
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getStorageTargets: function(server,type, suc, err) {
+ var url = 'plugins/kimchi/storageservers/' + server + '/storagetargets?_target_type=' + type;
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ timeout: 2000,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getStoragePool: function(poolName, suc, err) {
+ var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName);
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ timeout: 2000,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getStoragePoolVolume: function(poolName, volumeName, suc, err) {
+ var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName);
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ timeout: 2000,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ addVMStorage : function(settings, suc, err) {
+ var vm = encodeURIComponent(settings['vm']);
+ delete settings['vm'];
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + vm + '/storages',
+ type : 'POST',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ retrieveVMStorage : function(settings, suc, err) {
+ var vm = encodeURIComponent(settings['vm']);
+ var dev = encodeURIComponent(settings['dev']);
+ wok.requestJSON({
+ url : "plugins/kimchi/vms/" + vm + '/storages/' + dev,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ replaceVMStorage : function(settings, suc, err) {
+ var vm = encodeURIComponent(settings['vm']);
+ var dev = encodeURIComponent(settings['dev']);
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + vm + '/storages/' + dev,
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify({
+ path: settings['path']
+ }),
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ deleteVMStorage : function(settings, suc, err) {
+ var vm = settings['vm'];
+ var dev = settings['dev'];
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
+ '/storages/' + encodeURIComponent(dev),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listVMStorages : function(params, suc, err) {
+ var vm = encodeURIComponent(params['vm']);
+ var type = params['storageType'];
+ var url = 'plugins/kimchi/vms/' + vm + '/storages';
+ if(type) {
+ url += '?type=' + type;
+ }
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listSoftwareUpdates : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/packagesupdate',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ updateSoftware : function(suc, err, progress) {
+ var taskID = -1;
+ var onResponse = function(data) {
+ taskID = data['id'];
+ trackTask();
+ };
+
+ var trackTask = function() {
+ kimchi.getTask(taskID, onTaskResponse, err);
+ };
+
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ switch(taskStatus) {
+ case 'running':
+ progress && progress(result);
+ setTimeout(function() {
+ trackTask();
+ }, 200);
+ break;
+ case 'finished':
+ case 'failed':
+ suc(result);
+ break;
+ default:
+ break;
+ }
+ };
+
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/swupdate',
+ type : "POST",
+ contentType : "application/json",
+ dataType : "json",
+ success : onResponse,
+ error : err
+ });
+ },
+
+ createRepository : function(settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/kimchi/host/repositories",
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success: suc,
+ error: err
+ });
+ },
+
+ retrieveRepository : function(repository, suc, err) {
+ var reposID = encodeURIComponent(repository);
+ wok.requestJSON({
+ url : "plugins/kimchi/host/repositories/" + reposID,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ updateRepository : function(name, settings, suc, err) {
+ var reposID = encodeURIComponent(name);
+ $.ajax({
+ url : "plugins/kimchi/host/repositories/" + reposID,
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ enableRepository : function(name, enable, suc, err) {
+ var reposID = encodeURIComponent(name);
+ $.ajax({
+ url : "plugins/kimchi/host/repositories/" + reposID +
+ '/' + (enable === true ? 'enable' : 'disable'),
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ deleteRepository : function(repository, suc, err) {
+ var reposID = encodeURIComponent(repository);
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/repositories/' + reposID,
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listRepositories : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/repositories',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ getHostFCDevices: function(suc, err) {
+ var url = 'plugins/kimchi/host/devices?_cap=fc_host';
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getGuestInterfaces: function(name, suc, err) {
+ var url = 'plugins/kimchi/vms/' + encodeURIComponent(name) + '/ifaces';
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err || function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ createGuestInterface : function(name, interface, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(name) + '/ifaces',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(interface),
+ success : suc,
+ error : err || function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ deleteGuestInterface : function(vm, mac, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/ifaces/' + encodeURIComponent(mac),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ updateGuestInterface : function(vm, mac, interface, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/ifaces/' + encodeURIComponent(mac),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(interface),
+ dataType : 'json',
+ success: suc,
+ error: err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getUserById : function(data, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/users?_user_id=' + data.user_id,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ async : false,
+ success : suc && suc(data),
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getUsers : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/users',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getGroups : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/groups',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getHostPCIDevices : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/devices?_passthrough=true&_cap=pci',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getPCIDeviceCompanions : function(pcidev, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/devices?_passthrough_affected_by=' + pcidev,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getISCSITargets : function(server, port, suc, err) {
+ server = encodeURIComponent(server);
+ port = port ? '&_server_port='+encodeURIComponent(port) : '';
+ wok.requestJSON({
+ url : 'plugins/kimchi/storageservers/' + server + '/storagetargets?_target_type=iscsi' + port,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getPeers : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/peers',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getVMPCIDevices : function(id, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(id) + '/hostdevs',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ addVMPCIDevice : function(vm, device, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm) +'/hostdevs',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(device),
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ removeVMPCIDevice : function(vm, device, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm) +'/hostdevs/' + encodeURIComponent(device),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ /**
+ * Create a new volume with capacity
+ */
+ createVolumeWithCapacity: function(poolName, settings, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes',
+ type : 'POST',
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Upload volume content
+ */
+ uploadVolumeToSP: function(poolName, volumeName, settings, suc, err) {
+ var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) + '/storagevolumes/' + encodeURIComponent(volumeName);
+ var fd = settings['formData'];
+ wok.requestJSON({
+ url : url,
+ type : 'PUT',
+ data : fd,
+ processData : false,
+ contentType : false,
+ dataType: 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Add a volume to a given storage pool by URL.
+ */
+ downloadVolumeToSP: function(settings, suc, err) {
+ var sp = encodeURIComponent(settings['sp']);
+ delete settings['sp'];
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools/' + sp + '/storagevolumes',
+ type : 'POST',
+ data : JSON.stringify(settings),
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ cloneGuest: function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + "/clone",
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ listSnapshots : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getCurrentSnapshot : function(vm, suc, err, sync) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots/current',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ async : !sync,
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ revertSnapshot : function(vm, snapshot, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots/' + encodeURIComponent(snapshot) + '/revert',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ createSnapshot : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ deleteSnapshot : function(vm, snapshot, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) + '/snapshots/' + encodeURIComponent(snapshot),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getCPUInfo : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/cpuinfo',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ }
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
new file mode 100644
index 0000000..6be6f9a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
@@ -0,0 +1,86 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.guest_add_main = function() {
+ var showTemplates = function() {
+ wok.topic('templateCreated').unsubscribe(showTemplates);
+ kimchi.listTemplates(function(result) {
+ if (result && result.length) {
+ $('#prompt-create-template').addClass('hidden');
+ $('#prompt-choose-template').removeClass('hidden');
+ var html = '';
+ var tmpl = $('#tmpl-template').html();
+ $.each(result, function(index, value) {
+ html += wok.substitute(tmpl, value);
+ });
+ $('#templateTile').html(html);
+ return;
+ }
+
+ $('#btn-create-template').on('click', function(event) {
+ wok.topic('templateCreated').subscribe(showTemplates);
+
+ wok.window.open('plugins/kimchi/template-add.html');
+
+ event.preventDefault();
+ });
+
+ $('#prompt-choose-template').addClass('hidden');
+ $('#prompt-create-template').removeClass('hidden');
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ };
+
+ function validateForm() {
+ if (!$('input[name=template]:checked', '#templateTile').val()) {
+ return false;
+ }
+ return true;
+ }
+
+ $('#form-vm-add').change(function() {
+ if (validateForm()) {
+ $('#vm-doAdd').attr('disabled', false);
+ }
+ });
+
+ var addGuest = function(event) {
+ $('#vm-doAdd').attr('disabled', true);
+ $('#vm-doAdd').attr('style', 'display:none');
+ $('#vm-doAdding').attr('style', 'display');
+ var formData = $('#form-vm-add').serializeObject();
+ kimchi.createVM(formData, function() {
+ kimchi.listVmsAuto();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ $('#vm-doAdd').attr('style', 'display');
+ $('#vm-doAdding').attr('style', 'display:none');
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+
+ return false;
+ };
+
+ $('#form-vm-add').on('submit', addGuest);
+ $('#vm-doAdd').on('click', addGuest);
+
+ showTemplates();
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
new file mode 100644
index 0000000..7105c88
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
@@ -0,0 +1,759 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.guest_edit_main = function() {
+ var buttonContainer = $('#action-button-container');
+ $('#guest-edit-tabs').tabs({
+ beforeActivate: function(event, ui) {
+ var display_list = null;
+ if(kimchi.thisVMState === "running") {
+ display_list = ['form-guest-edit-permission'];
+ } else {
+ display_list = ['form-guest-edit-general', 'form-guest-edit-permission'];
+ }
+ $(buttonContainer).addClass('hidden');
+ var deactivated = ui['newPanel'];
+ if(display_list.indexOf($(deactivated).attr('id')) >= 0) {
+ $(buttonContainer).removeClass('hidden');
+ }
+ }
+ });
+
+ var guestEditForm = $('#form-guest-edit-general');
+ var saveButton = $('#guest-edit-button-save');
+ var authType;
+
+ var refreshCDROMs = function() {
+ kimchi.listVMStorages({
+ vm: kimchi.selectedGuest
+ }, function(storages) {
+ var container = $('#form-guest-edit-storage .body');
+ $(container).empty();
+ $.each(storages, function(index, storage) {
+ storage['vm'] = kimchi.selectedGuest;
+ rowHTML = $('#' + storage['type'] + '-row-tmpl').html();
+ var templated = wok.substitute(rowHTML, storage);
+ container.append(templated);
+ });
+
+ $('.replace', container).button({
+ icons: {
+ primary: 'ui-icon-pencil'
+ },
+ text: false
+ });
+
+ $('.detach', container).button({
+ icons: {
+ primary: 'ui-icon-trash'
+ },
+ text: false
+ });
+ if (kimchi.thisVMState === 'running') {
+ $('.detach[data-type="cdrom"]', container).remove();
+ }
+
+ $('.save', container).button({
+ icons: {
+ primary: 'ui-icon-disk'
+ },
+ text: false
+ });
+
+ $('.cancel', container).button({
+ icons: {
+ primary: 'ui-icon-arrowreturnthick-1-w'
+ },
+ text: false
+ });
+ });
+ };
+
+ var initStorageListeners = function() {
+ var container = $('#form-guest-edit-storage .body');
+ var toggleCDROM = function(rowNode, toEdit) {
+ $('button.replace,button.detach', rowNode)
+ [(toEdit ? 'add' : 'remove') + 'Class']('hidden');
+ $('button.save,button.cancel', rowNode)
+ [(toEdit ? 'remove' : 'add') + 'Class']('hidden');
+ var pathBox = $('.path input', rowNode)
+ .prop('readonly', !toEdit);
+ toEdit && pathBox.select();
+ pathBox.val(pathBox.attr('value'));
+ };
+
+ var replaceCDROM = function(event) {
+ event.preventDefault();
+ kimchi.selectedGuestStorage = $(this).data('dev');
+ $('.item', container).each(function(i, n) {
+ toggleCDROM(n);
+ });
+ var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
+ toggleCDROM(rowNode, true);
+ };
+
+ $(container).on('click', 'button.replace', replaceCDROM);
+
+ $(container).on('click', 'button.detach', function(e) {
+ e.preventDefault();
+ var settings = {
+ title : i18n['KCHAPI6004M'],
+ content : i18n['KCHVMCD6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ if ($(this).data('type') == "disk")
+ settings['content'] = i18n['KCHVMCD6009M'];
+
+ var dev = $(this).data('dev');
+ wok.confirm(settings, function() {
+ kimchi.deleteVMStorage({
+ vm: kimchi.selectedGuest,
+ dev: dev
+ }, function() {
+ wok.topic('kimchi/vmCDROMDetached').publish();
+ });
+ });
+ });
+
+ $(container).on('click', 'button.save', function(event) {
+ event.preventDefault();
+ var path = $('#cdrom-path-' + kimchi.selectedGuestStorage).val();
+ var settings = {
+ vm: kimchi.selectedGuest,
+ dev: kimchi.selectedGuestStorage,
+ path: path
+ };
+
+ kimchi.replaceVMStorage(settings, function(result) {
+ wok.topic('kimchi/vmCDROMReplaced').publish({
+ result: result
+ });
+ }, function(result) {
+ var errText = result['reason'] ||
+ result['responseJSON']['reason'];
+ wok.message.error(errText);
+ });
+ });
+
+ $(container).on('click', 'button.cancel', function(event) {
+ event.preventDefault();
+ var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
+ toggleCDROM(rowNode);
+ });
+ };
+
+ var setupInterface = function() {
+ $(".add", "#form-guest-edit-interface").button({
+ icons: { primary: "ui-icon-plusthick" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ addItem({
+ id: -1,
+ mac: "",
+ network: "",
+ type: "network",
+ viewMode: "hide",
+ editMode: ""
+ });
+ });
+ var toggleEdit = function(item, on, itemId){
+ $("#label-mac-" + itemId, item).toggleClass("hide", on);
+ $("#edit-mac-" + itemId, item).toggleClass("hide", !on);
+ $("#label-network-" + itemId, item).toggleClass("hide", false);
+ $("select", item).toggleClass("hide", true);
+ $(".action-area", item).toggleClass("hide");
+ };
+ var addItem = function(data) {
+ if (data.id == -1) {
+ data.id = $('#form-guest-edit-interface > .body').children().size()
+ }
+ var itemNode = $.parseHTML(wok.substitute($('#interface-tmpl').html(),data));
+ $(".body", "#form-guest-edit-interface").append(itemNode);
+ $("select", itemNode).append(networkOptions);
+ if(data.network!==""){
+ $("select", itemNode).val(data.network);
+ }
+ $(".edit", itemNode).button({
+ disabled: kimchi.thisVMState === "running",
+ icons: { primary: "ui-icon-pencil" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ toggleEdit($(this).closest('div'), true, data.id);
+ });
+ $(".delete", itemNode).button({
+ icons: { primary: "ui-icon-trash" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ kimchi.deleteGuestInterface(kimchi.selectedGuest, item.prop("id"), function(){
+ item.remove();
+ });
+ });
+ $(".save", itemNode).button({
+ icons: { primary: "ui-icon-disk" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ var interface = {
+ network: $("select", item).val(),
+ type: "network",
+ mac: $(":text", item).val()
+ };
+ var postUpdate = function(mac){
+ $("#label-network-" + data.id, item).text(interface.network);
+ $("#label-mac-" + data.id, item).text(mac);
+ $("#edit-mac-" + data.id, item).val(mac);
+ toggleEdit(item, false, data.id);
+ };
+ if(item.prop("id")==""){
+ kimchi.createGuestInterface(kimchi.selectedGuest, interface, function(data){
+ item.prop("id", data.mac);
+ postUpdate(data.mac);
+ });
+ }else{
+ if (item.prop('id') == interface.mac) {
+ toggleEdit(item, false, data.id);
+ } else {
+ kimchi.updateGuestInterface(kimchi.selectedGuest, item.prop('id'),
+ interface, function(data){
+ item.prop("id", data.mac);
+ postUpdate(data.mac);
+ });
+ }
+ }
+ });
+ $(".cancel", itemNode).button({
+ icons: { primary: "ui-icon-arrowreturnthick-1-w" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ $("label", item).text()==="" ? item.remove() : toggleEdit(item, false, data.id);
+ });
+ };
+ var networkOptions = "";
+ kimchi.listNetworks(function(data){
+ for(var i=0;i<data.length;i++){
+ var isSlected = i==0 ? " selected" : "";
+ networkOptions += "<option"+isSlected+">"+data[i].name+"</option>";
+ }
+ kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data){
+ for(var i=0;i<data.length;i++){
+ data[i].viewMode = "";
+ data[i].editMode = "hide";
+ data[i].id = i;
+ addItem(data[i]);
+ }
+ });
+ });
+ };
+
+ var setupPermission = function() {
+ //set up for LDAP
+ $(".add", "#form-guest-edit-permission").button({
+ icons: { primary: "ui-icon-plusthick" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ addItem({
+ user: "",
+ freeze: false,
+ viewMode: "hide",
+ editMode: "",
+ checked: true
+ });
+ });
+ var addItem = function(data) {
+ var itemNode = $.parseHTML(wok.substitute($('#ldap-user-tmpl').html(),data));
+ $(".body", "#form-guest-edit-permission .ldap").append(itemNode);
+ $(".delete", itemNode).button({
+ icons: { primary: "ui-icon-trash" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ item.remove();
+ });
+ $("input").focusout(function() {
+ var item = $(this).parent().parent();
+ var user= $(this).val();
+ item.prop("id", user);
+ $("label", item).text(user);
+ });
+ $("input").focusin(function() {
+ $(this).removeClass("checked");
+ });
+
+ if (data.checked == true) {
+ $(".checked", itemNode).addClass("hide");
+ }
+ };
+ var toggleEdit = function(item, on){
+ $("label", item).toggleClass("hide", on);
+ $("input", item).toggleClass("hide", !on);
+ $(".action-area", item).toggleClass("hide");
+ };
+ //set up for PAM
+ var userNodes = {}, groupNodes = {};
+ authType = kimchi.capabilities['auth']
+ if (authType == 'pam') {
+ $("#form-guest-edit-permission .ldap").hide();
+ kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
+ kimchi.getUsers(function(users){
+ kimchi.getGroups(function(groups){
+ var subArray = function(a1, a2){ //a1-a2
+ for(var i=0; i<a2.length; i++){
+ for(var j=0; j<a1.length; j++){
+ if(a2[i] == a1[j]){
+ a1.splice(j, 1);
+ break;
+ }
+ }
+ }
+ };
+ subArray(users, vm.users); subArray(groups, vm.groups);
+ init(users, groups, vm.users, vm.groups);
+ });
+ });
+ });
+ } else if (authType == 'ldap') {
+ $("#form-guest-edit-permission .pam").hide();
+ kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
+ for (var i=0; i<vm.users.length; i++) {
+ addItem({
+ user: vm.users[i],
+ viewMode: "",
+ freeze: true,
+ editMode: "hide",
+ checked: true});
+ }
+ });
+ }
+ var sortNodes = function(container, isUser){
+ nodes = container.children();
+ var keys = [];
+ nodes.each(function(){
+ keys.push($("label", this).text());
+ });
+ keys.sort();
+ container.empty();
+ for(var i=0; i<keys.length; i++){
+ var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]];
+ $(itemNode).click(function(){
+ $(this).toggleClass("item-picked");
+ });
+ container.append(itemNode);
+ }
+ };
+ var init = function(availUsers, availGroups, selUsers, selGroups){
+ var initNode = function(key, isUserNode){
+ var nodeGroups = isUserNode ? userNodes : groupNodes;
+ nodeGroups[key] = $.parseHTML(wok.substitute($('#permission-item-pam').html(), {
+ val: key,
+ class: isUserNode? "user-icon" : "group-icon"
+ }));
+ };
+ for(var i=0; i<availUsers.length; i++){
+ initNode(availUsers[i], true);
+ $("#permission-avail-users").append(userNodes[availUsers[i]]);
+ sortNodes($("#permission-avail-users"), true);
+ }
+ for(var i=0; i<selUsers.length; i++){
+ initNode(selUsers[i], true);
+ $("#permission-sel-users").append(userNodes[selUsers[i]]);
+ sortNodes($("#permission-sel-users"), true);
+ }
+ for(var i=0; i<availGroups.length; i++){
+ initNode(availGroups[i], false);
+ $("#permission-avail-groups").append(groupNodes[availGroups[i]]);
+ sortNodes($("#permission-avail-groups"), false);
+ }
+ for(var i=0; i<selGroups.length; i++){
+ initNode(selGroups[i], false);
+ $("#permission-sel-groups").append(groupNodes[selGroups[i]]);
+ sortNodes($("#permission-sel-groups"), false);
+ }
+ };
+ var filterNodes = function(key, container){
+ container.children().each(function(){
+ $(this).css("display", $("label", this).text().indexOf(key)==-1 ? "none" : "");
+ });
+ }
+ $("#permission-avail-searchBox").on("keyup", function() {
+ var key = $(this).val();
+ filterNodes(key, $("#permission-avail-users"));
+ filterNodes(key, $("#permission-avail-groups"));
+ });
+ $("#permission-sel-searchBox").on("keyup", function() {
+ var key = $(this).val();
+ filterNodes(key, $("#permission-sel-users"));
+ filterNodes(key, $("#permission-sel-groups"));
+ });
+ $('#permissionGo').button().click(function(evt) {
+ evt.preventDefault();
+ $("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked");
+ sortNodes($("#permission-sel-users"), true);
+ $("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked");
+ sortNodes($("#permission-sel-groups"), false);
+ $("#permission-sel-searchBox").val("");
+ filterNodes("", $("#permission-sel-users"));
+ filterNodes("", $("#permission-sel-groups"));
+ });
+ $('#permissionBack').button().click(function(evt) {
+ evt.preventDefault();
+ $("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked");
+ sortNodes($("#permission-avail-users"), true);
+ $("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked");
+ sortNodes($("#permission-avail-groups"), false);
+ $("#permission-avail-searchBox").val("");
+ filterNodes("", $("#permission-avail-users"));
+ filterNodes("", $("#permission-avail-groups"));
+ });
+ }
+ var setupPCIDevice = function(){
+ kimchi.getHostPCIDevices(function(hostPCIs){
+ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){
+ var pciEnabled = kimchi.capabilities.kernel_vfio;
+ for(var i=0; i<hostPCIs.length; i++){
+ var itemNode = $.parseHTML(wok.substitute($('#pci-tmpl').html(),{
+ name: hostPCIs[i].name,
+ product: hostPCIs[i].product.description,
+ vendor: hostPCIs[i].vendor.description
+ }));
+ $(".body", "#form-guest-edit-pci").append(itemNode);
+ var iconClass = "ui-icon-plus";
+ for(var j=0; j<vmPCIs.length; j++){
+ if(hostPCIs[i].name==vmPCIs[j].name){
+ iconClass = "ui-icon-minus";
+ break;
+ }
+ }
+ pciEnabled || $("button", itemNode).remove();
+ $("button", itemNode).button({
+ icons: { primary: iconClass },
+ text: false
+ }).click(function(){
+ var obj = $(this);
+ if(obj.button("option", "icons").primary == "ui-icon-minus"){
+ kimchi.removeVMPCIDevice(kimchi.selectedGuest, obj.parent().prop("id"), function(){
+ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs1){
+ for(var k=0; k<hostPCIs.length; k++) {
+ $("button", "#" + hostPCIs[k].name).button("option", "icons", {primary: "ui-icon-plus"});
+ }
+ for(var k=0; k<vmPCIs1.length; k++) {
+ $("button", "#" + vmPCIs1[k].name).button("option", "icons", {primary: "ui-icon-minus"});
+ }
+ });
+ filterNodes($("select", "#form-guest-edit-pci").val(), $("input", "#form-guest-edit-pci").val());
+ });
+ } else {
+ kimchi.addVMPCIDevice(kimchi.selectedGuest, { name: obj.parent().prop("id") }, function(){
+ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs1){
+ for(var k=0; k<vmPCIs1.length; k++) {
+ $("button", "#" + vmPCIs1[k].name).button("option", "icons", {primary: "ui-icon-minus"});
+ }
+ });
+ filterNodes($("select", "#form-guest-edit-pci").val(), $("input", "#form-guest-edit-pci").val());
+ });
+ }
+ });
+ kimchi.getPCIDeviceCompanions(hostPCIs[i].name, function(infoData) {
+ var pciTitle = i18n["KCHVMED6007M"] + "\n";
+ var haveCompanions = false;
+ for(var p=0; p<infoData.length; p++) {
+ if(infoData[p].device_type === "net") {
+ haveCompanions = true;
+ pciTitle += " " + infoData[p].name + "\n";
+ pciTitle += " " + i18n["KCHVMED6001M"] + " " + infoData[p].interface;
+ pciTitle += ", " + i18n["KCHVMED6002M"] + " " + infoData[p].address;
+ pciTitle += ", " + i18n["KCHVMED6003M"] + " " + infoData[p].link_type + "\n";
+ } else if(infoData[p].device_type === "storage") {
+ haveCompanions = true;
+ pciTitle += " " + infoData[p].name + "\n";
+ pciTitle += " " + i18n["KCHVMED6004M"] + " " + infoData[p].block;
+ pciTitle += ", " + i18n["KCHVMED6005M"] + " " + infoData[p].drive_type;
+ pciTitle += ", " + i18n["KCHVMED6006M"] + " " + infoData[p].model + "\n";
+ }
+ }
+ for(var q=0; q<infoData.length; q++) {
+ haveCompanions && $(".name", "#" + infoData[q].parent).attr("title", pciTitle);
+ haveCompanions && $(".product", "#" + infoData[q].parent).attr("title", pciTitle);
+ haveCompanions && $(".vendor", "#" + infoData[q].parent).attr("title", pciTitle);
+ }
+ });
+ }
+ });
+ });
+ var filterNodes = function(group, text){
+ text = text.toLowerCase();
+ $(".body", "#form-guest-edit-pci").children().each(function(){
+ var textFilter = $(".name", this).text().toLowerCase().indexOf(text)!=-1;
+ textFilter = textFilter || $(".product", this).text().toLowerCase().indexOf(text)!=-1;
+ textFilter = textFilter || $(".vendor", this).text().toLowerCase().indexOf(text)!=-1;
+ var display = "none";
+ var itemGroup = $("button", this).button("option", "icons").primary;
+ if(textFilter){
+ if(group == "all"){
+ display = "";
+ }else if(group=="toAdd" && itemGroup=="ui-icon-plus"){
+ display = ""
+ }else if(group == "added" && itemGroup=="ui-icon-minus"){
+ display = ""
+ }
+ }
+ $(this).css("display", display);
+ });
+ };
+ $("select", "#form-guest-edit-pci").change(function(){
+ filterNodes($(this).val(), $("input", "#form-guest-edit-pci").val());
+ });
+ $("input", "#form-guest-edit-pci").on("keyup", function() {
+ filterNodes($("select", "#form-guest-edit-pci").val(), $(this).val());
+ });
+ };
+
+ var setupSnapshot = function() {
+ var currentSnapshot;
+ var setCurrentSnapshot = function(aSnapshot){
+ if(!aSnapshot)
+ kimchi.getCurrentSnapshot(kimchi.selectedGuest, function(snapshot){
+ if(snapshot&&snapshot.name) aSnapshot = snapshot.name;
+ }, null, true);
+ if(aSnapshot){
+ if(currentSnapshot) $(".ui-icon-check", "#"+currentSnapshot).addClass("hide");
+ $(".ui-icon-check", "#"+aSnapshot).removeClass("hide");
+ currentSnapshot = aSnapshot;
+ }
+ };
+ var addItem = function(data, container) {
+ var itemNode = $.parseHTML(wok.substitute($('#snapshot-tmpl').html(),data));
+ $("."+container, "#form-guest-edit-snapshot").append(itemNode);
+ $(".delete", itemNode).button({
+ icons: { primary: "ui-icon-trash" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ $("button", "#form-guest-edit-snapshot").button("disable");
+ kimchi.deleteSnapshot(kimchi.selectedGuest, item.prop("id"), function(){
+ item.remove();
+ setCurrentSnapshot();
+ $("button", "#form-guest-edit-snapshot").button("enable");
+ }, function(data){
+ wok.message.error(data.responseJSON.reason);
+ $("button", "#form-guest-edit-snapshot").button("enable");
+ });
+ });
+ $(".revert", itemNode).button({
+ icons: { primary: "ui-icon-arrowthick-1-ne" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ $(".ui-icon-check", item).addClass("hide");
+ $(".icon", item).removeClass("hide");
+ $("button", "#form-guest-edit-snapshot").button("disable");
+ kimchi.revertSnapshot(kimchi.selectedGuest, item.prop("id"), function(){
+ $(".icon", item).addClass("hide");
+ $("button", "#form-guest-edit-snapshot").button("enable");
+ setCurrentSnapshot(item.prop("id"));
+ kimchi.listVmsAuto();
+ wok.window.close();
+ }, function(data){
+ wok.message.error(data.responseJSON.reason);
+ $(".icon", item).addClass("hide");
+ $("button", "#form-guest-edit-snapshot").button("enable");
+ });
+ });
+ };
+ var addOngoingItem = function(task){
+ var uri = task.target_uri;
+ addItem({
+ name: uri.substring(uri.lastIndexOf('/')+1, uri.length),
+ created: "",
+ listMode: "hide",
+ createMode: ""
+ }, 'task');
+ if(kimchi.trackingTasks.indexOf(task.id)==-1)
+ kimchi.trackTask(task.id, function(task){
+ listGeneratingSnapshots();
+ $("button", "#form-guest-edit-snapshot").button("enable");
+ }, function(err){
+ wok.message.error(err.message);
+ listGeneratingSnapshots();
+ $("button", "#form-guest-edit-snapshot").button("enable");
+ });
+ };
+ var listGeneratingSnapshots = function(){
+ kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/snapshots/*'), function(tasks) {
+ $(".task", "#form-guest-edit-snapshot").empty();
+ for(var i=0;i<tasks.length;i++){
+ addOngoingItem(tasks[i]);
+ }
+ if(tasks.length==0) listSnapshots();
+ });
+ };
+ var listSnapshots = function(){
+ kimchi.listSnapshots(kimchi.selectedGuest, function(data){
+ $(".body", "#form-guest-edit-snapshot").empty();
+ for(var i=0;i<data.length;i++){
+ data[i].created = new Date(data[i].created*1000).toLocaleString();
+ data[i].createMode = "hide";
+ data[i].listMode = "";
+ addItem(data[i], 'body');
+ }
+ setCurrentSnapshot();
+ });
+ };
+ listGeneratingSnapshots();
+ $(".add", "#form-guest-edit-snapshot").button({
+ icons: { primary: "ui-icon-plusthick" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ kimchi.createSnapshot(kimchi.selectedGuest, function(task){
+ $("button", "#form-guest-edit-snapshot").button("disable");
+ addOngoingItem(task);
+ });
+ });
+ if(kimchi.thisVMState=="running") $("button", "#form-guest-edit-snapshot").remove();
+ };
+
+ var initContent = function(guest) {
+ guest['icon'] = guest['icon'] || 'plugins/kimchi/images/icon-vm.png';
+ $('#form-guest-edit-general').fillWithObject(guest);
+ kimchi.thisVMState = guest['state'];
+ refreshCDROMs();
+ $('#guest-edit-attach-cdrom-button').button({
+ icons: {
+ primary: "ui-icon-plusthick"
+ },
+ text: false
+ }).click(function(event) {
+ event.preventDefault();
+ wok.window.open("plugins/kimchi/guest-storage-add.html");
+ });
+ if(kimchi.thisVMState === "running") {
+ $("#form-guest-edit-general input").prop("disabled", true);
+ } else {
+ $("#action-button-container").removeClass("hidden");
+ }
+
+ var onAttached = function(params) {
+ refreshCDROMs();
+ };
+ var onReplaced = function(params) {
+ refreshCDROMs();
+ };
+ var onDetached = function(params) {
+ refreshCDROMs();
+ };
+
+ initStorageListeners();
+ setupInterface();
+ setupPermission();
+ setupPCIDevice();
+ setupSnapshot();
+
+ wok.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
+ wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
+ wok.topic('kimchi/vmCDROMDetached').subscribe(onDetached);
+
+ kimchi.clearGuestEdit = function() {
+ wok.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached);
+ wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
+ wok.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached);
+ };
+ };
+
+ kimchi.retrieveVM(kimchi.selectedGuest, initContent);
+
+ var generalSubmit = function(event) {
+ $(saveButton).prop('disabled', true);
+ var data=$('#form-guest-edit-general').serializeObject();
+ if(data['memory']!=undefined) {
+ data['memory'] = Number(data['memory']);
+ }
+ if(data['cpus']!=undefined) {
+ data['cpus'] = Number(data['cpus']);
+ }
+
+ kimchi.updateVM(kimchi.selectedGuest, data, function() {
+ kimchi.listVmsAuto();
+ wok.window.close();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $(saveButton).prop('disabled', false);
+ });
+ }
+
+ var permissionSubmit = function(event) {
+ var content = { users: [], groups: [] };
+ authType = kimchi.capabilities['auth']
+ if (authType == 'pam') {
+ $("#permission-sel-users").children().each(function(){
+ content.users.push($("label", this).text());
+ });
+ $("#permission-sel-groups").children().each(function(){
+ content.groups.push($("label", this).text());
+ });
+ kimchi.updateVM(kimchi.selectedGuest, content, function(){
+ wok.window.close();
+ });
+ } else if (authType == 'ldap') {
+ $(saveButton).prop('disabled', true);
+ var errors = 0;
+
+ $(".body", "#form-guest-edit-permission .ldap").children().each(function () {
+ var elem = $(this);
+ content.users.push(elem.attr("id"));
+
+ if (!$('input', elem).hasClass('hide')) {
+ var user = {'user_id': $(this).attr("id")};
+ kimchi.getUserById(user, null, function (data) {
+ errors += 1;
+ $("input", elem).addClass("checked");
+ });
+ }
+ });
+ if (errors == 0) {
+ kimchi.updateVM(kimchi.selectedGuest, content, function(){
+ wok.window.close();
+ });
+ } else {
+ $(saveButton).prop('disabled', false);
+ }
+ }
+ }
+
+ // tap map, "general": 0, "storage": 1, "interface": 2, "permission": 3, "password": 4
+ var submit_map = {0: generalSubmit, 3:permissionSubmit};
+ var submitForm = function(event) {
+ var current = $('#guest-edit-tabs').tabs( "option", "active" );
+ var submitFun = submit_map[current];
+ submitFun && submitFun(event);
+ event.preventDefault();
+ };
+
+ $(guestEditForm).on('submit', submitForm);
+ $(saveButton).on('click', submitForm);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js
new file mode 100644
index 0000000..7dd5d84
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js
@@ -0,0 +1,511 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+kimchi.sampleGuestObject = {
+ "name": "",
+ "uuid": "",
+ "state": "shutoff",
+ "persistent": true,
+ "icon": null,
+ "cpus": 0,
+ "memory": 0,
+ "stats": {
+ "net_throughput": 0,
+ "io_throughput_peak": 100,
+ "cpu_utilization": 0,
+ "io_throughput": 0,
+ "net_throughput_peak": 100
+ },
+ "screenshot": null,
+ "graphics": {
+ "passwd": null,
+ "passwdValidTo": null,
+ "type": "vnc",
+ "port": null,
+ "listen": "127.0.0.1"
+ },
+ "users": [],
+ "groups": [],
+ "access": "full"
+};
+
+kimchi.vmstart = function(event) {
+ var button=$(this);
+ if (!button.hasClass('loading')) {
+ button.addClass('loading');
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.startVM(vm_id, function(result) {
+ button.removeClass('loading');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ button.removeClass('loading');
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+};
+
+kimchi.vmsuspend = function(event) {
+ var button=$(this);
+ if (!button.hasClass('pause-gray')) {
+ button.addClass('pause-gray');
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.suspendVM(vm_id, function(result) {
+ button.removeClass('pause-gray');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ button.removeClass('pause-gray');
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+};
+
+kimchi.vmresume = function(event) {
+ var button=$(this);
+ if (!button.hasClass('resume-gray')) {
+ button.addClass('resume-gray');
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.resumeVM(vm_id, function(result) {
+ button.removeClass('resume-gray');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ button.removeClass('resume-gray');
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+};
+
+kimchi.vmpoweroff = function(event) {
+ var button=$(this);
+ if (!button.hasClass('loading')) {
+ button.addClass('loading');
+ var vm=button.closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var vmObject=vm.data();
+ var vm_persistent=vmObject.persistent == true;
+ var content_msg = vm_persistent ? i18n['KCHVM6003M'] :
+ i18n['KCHVM6009M'];
+ var settings = {
+ title : i18n['KCHVM6002M'],
+ content : content_msg,
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.poweroffVM(vm_id, function(result) {
+ button.removeClass('loading');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ });
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+};
+
+kimchi.vmshutdown = function(event){
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var settings = {
+ title : i18n['KCHVM6006M'],
+ content : i18n['KCHVM6007M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.shutdownVM(vm_id, function(result) {
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ }, function() {
+ });
+};
+
+kimchi.vmreset = function(event){
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var settings = {
+ title : i18n['KCHVM6004M'],
+ content : i18n['KCHVM6005M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.resetVM(vm_id, function(result) {
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ }, function() {
+ });
+};
+
+kimchi.vmdelete = function(event) {
+ var vm = $(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var settings = {
+ title : i18n['KCHVM6008M'],
+ content : i18n['KCHVM6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.deleteVM(vm_id, function(result) {
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ });
+};
+
+kimchi.vmedit = function(event) {
+ var vm = $(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.selectedGuest = vm_id;
+ wok.window.open({
+ url: 'plugins/kimchi/guest-edit.html',
+ close: function() {
+ kimchi.clearGuestEdit();
+ }
+ });
+};
+
+kimchi.openVmConsole = function(event) {
+ var vm=$(this).closest('li[name=guest]');
+ var vmObject=vm.data();
+ if (vmObject.graphics['type'] == 'vnc') {
+ kimchi.vncToVM(vm.attr('id'));
+ }
+ else if (vmObject.graphics['type'] == 'spice') {
+ kimchi.spiceToVM(vm.attr('id'));
+ }
+
+};
+
+kimchi.getVmsCurrentConsoleImgs = function() {
+ var res = new Object();
+ $('#guestList').children().each(function() {
+ res[$(this).attr('id')] = $(this).find('img.imgactive').attr('src');
+ })
+ return res;
+};
+
+kimchi.getOpenMenuVmId = function() {
+ var result;
+ var openMenu = $('#guestList div[name="actionmenu"] .popover:visible');
+ if(openMenu) {
+ var li_element=openMenu.closest('li');
+ result=li_element.attr('id');
+ }
+ return result;
+};
+
+kimchi.listVmsAuto = function() {
+ if (kimchi.vmTimeout) {
+ clearTimeout(kimchi.vmTimeout);
+ }
+ var getCreatingGuests = function(){
+ var guests = [];
+ kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/[^/]+$'), function(tasks) {
+ for(var i=0;i<tasks.length;i++){
+ var guestUri = tasks[i].target_uri;
+ var guestName = guestUri.split('/')[2]
+ guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName, isCreating: true}));
+ if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
+ kimchi.trackTask(tasks[i].id, null, function(err){
+ wok.message.error(err.message);
+ }, null);
+ }
+ }, null, true);
+ return guests;
+ };
+ var getCloningGuests = function(){
+ var guests = [];
+ kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/.+/clone'), function(tasks) {
+ for(var i=0;i<tasks.length;i++){
+ var guestUri = tasks[i].target_uri;
+ var guestName = guestUri.split('/')[2]
+ guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName, isCloning: true}));
+ if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
+ kimchi.trackTask(tasks[i].id, null, function(err){
+ wok.message.error(err.message);
+ }, null);
+ }
+ }, null, true);
+ return guests;
+ };
+ kimchi.listVMs(function(result, textStatus, jqXHR) {
+ if (result && textStatus=="success") {
+ result = getCloningGuests().concat(result);
+ result = getCreatingGuests().concat(result);
+ if(result.length) {
+ var listHtml = '';
+ var guestTemplate = kimchi.guestTemplate;
+ var currentConsoleImages = kimchi.getVmsCurrentConsoleImgs();
+ var openMenuGuest = kimchi.getOpenMenuVmId();
+ $('#guestList').empty();
+ $('#guestListField').show();
+ $('#noGuests').hide();
+
+ $.each(result, function(index, vm) {
+ var guestLI = kimchi.createGuestLi(vm, currentConsoleImages[vm.name], vm.name==openMenuGuest);
+ $('#guestList').append(guestLI);
+ });
+ } else {
+ $('#guestListField').hide();
+ $('#noGuests').show();
+ }
+ }
+
+ kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
+ }, function(errorResponse, textStatus, errorThrown) {
+ if(errorResponse.responseJSON && errorResponse.responseJSON.reason) {
+ wok.message.error(errorResponse.responseJSON.reason);
+ }
+ kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
+ });
+};
+
+kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
+ var result=kimchi.guestElem.clone();
+
+ //Setup the VM list entry
+ var vmRunningBool=(vmObject.state=="running");
+ var vmSuspendedBool = (vmObject.state=="paused");
+ var vmPoweredOffBool = (vmObject.state=="shutoff");
+ var vmPersistent = (vmObject.persistent == true);
+ result.attr('id',vmObject.name);
+ result.data(vmObject);
+
+ //Add the Name
+ var guestTitle=result.find('.title').attr('title',vmObject.name);
+ guestTitle.html(vmObject.name);
+
+ //Setup the VM console thumbnail display
+ var curImg = vmObject.icon;
+ if (vmObject.screenshot) {
+ curImg = vmObject.screenshot.replace(/^\//,'');
+ }
+ var load_src = curImg || 'plugins/kimchi/images/icon-vm.png';
+ var tile_src = prevScreenImage || vmObject['load-src'];
+ var liveTile=result.find('div[name=guest-tile] > .tile');
+ liveTile.addClass(vmObject.state);
+ liveTile.find('.imgactive').attr('src',tile_src);
+ var imgLoad=liveTile.find('.imgload');
+ imgLoad.on('load', function() {
+ var oldImg=$(this).parent().find('.imgactive');
+ oldImg.removeClass("imgactive").addClass("imgload");
+ oldImg.attr("src","");
+ $(this).addClass("imgactive").removeClass("imgload");
+ $(this).off('load');
+ });
+ imgLoad.attr('src',load_src);
+
+ //Link the stopped tile to the start action, the running tile to open the console, and the paused tile to resume
+ if(!(vmObject.isCloning || vmObject.isCreating)){
+ if (vmPoweredOffBool) {
+ liveTile.off("click", kimchi.openVmConsole);
+ liveTile.off("click", kimchi.vmresume);
+ liveTile.on("click", kimchi.vmstart);
+ liveTile.hover(function(event){$(this).find('.overlay').show()}, function(event){$(this).find('.overlay').hide()});
+ } else if (vmSuspendedBool) {
+ liveTile.off("click", kimchi.vmstart);
+ liveTile.off("click", kimchi.openVmConsole);
+ liveTile.on("click", kimchi.vmresume);
+ if(vmObject.state="paused") {
+ liveTile.find('.overlay').attr('src',"plugins/kimchi/images/theme-default/ac24_resume.png");
+ liveTile.find('.overlay').attr('alt',"Resume");
+ }
+ liveTile.hover(function(event){$(this).find('.overlay').show()}, function(event){$(this).find('.overlay').hide()});
+ } else {
+ liveTile.off("click", kimchi.vmstart);
+ liveTile.off("click", kimchi.vmresume);
+ liveTile.on("click", kimchi.openVmConsole);
+ }
+ }
+
+ //Setup the gauges
+ var stats=vmObject.stats;
+ var gaugeValue=0;
+ gaugeValue=parseInt(stats.net_throughput);
+ kimchi.circleGaugeInit(result, "net_throughput",gaugeValue,(gaugeValue*100/stats.net_throughput_peak));
+ gaugeValue=parseInt(stats.io_throughput);
+ kimchi.circleGaugeInit(result, "io_throughput",gaugeValue,(gaugeValue*100/stats.io_throughput_peak));
+ gaugeValue=parseInt(stats.cpu_utilization);
+ kimchi.circleGaugeInit(result, "cpu_utilization",gaugeValue+"%",gaugeValue);
+
+ //Setup the VM Actions
+ var guestActions=result.find("div[name=guest-actions]");
+ guestActions.find(".shutoff-disabled").prop("disabled", !vmRunningBool);
+ guestActions.find(".running-disabled").prop("disabled", vmRunningBool);
+ guestActions.find(".non-persistent-disabled").prop("disabled", !vmPersistent);
+ guestActions.find(".reset-disabled").prop("disabled", vmPoweredOffBool || !vmPersistent);
+ guestActions.find(".pause-disabled").prop("disabled", vmPoweredOffBool || !vmPersistent);
+
+ if (vmSuspendedBool) { //VM is paused
+ //Hide Start
+ guestActions.find(".running-hidden").hide();
+ //Hide Pause button and menu
+ guestActions.find(".pause-disabled").hide();
+ guestActions.find(".pause-hidden").hide();
+ }
+
+ if (vmRunningBool) { //VM IS running
+ //Hide Start
+ guestActions.find(".running-hidden").hide();
+ //Hide Resume
+ guestActions.find(".resume-hidden").hide();
+ }
+
+ if (vmPoweredOffBool) { //VM is powered off
+ //Hide PowerOff
+ guestActions.find(".shutoff-hidden").hide();
+ //Hide Pause
+ guestActions.find(".pause-hidden").hide();
+ //Hide Resume
+ guestActions.find(".resume-hidden").hide();
+ }
+
+ var consoleActions=guestActions.find("[name=vm-console]");
+
+ if ((vmObject.graphics['type'] == 'vnc') || (vmObject.graphics['type'] == 'spice')) {
+ consoleActions.on("click", kimchi.openVmConsole);
+ consoleActions.show();
+ } else { //we don't recognize the VMs supported graphics, so hide the menu choice
+ consoleActions.hide();
+ consoleActions.off("click",kimchi.openVmConsole);
+ }
+
+ //Setup action event handlers
+ if(!(vmObject.isCloning || vmObject.isCreating)){
+ guestActions.find("[name=vm-start]").on({click : kimchi.vmstart});
+ guestActions.find("[name=vm-poweroff]").on({click : kimchi.vmpoweroff});
+ if ((vmRunningBool) || (vmSuspendedBool)) {
+ //If the guest is not running, do not enable reset; otherwise, reset is enabled (when running or paused)
+ guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset});
+
+ //If the guest is not running, do not enable shutdown;otherwise, shutdown is enabled (when running or paused)
+ guestActions.find("[name=vm-shutdown]").on({click : kimchi.vmshutdown});
+ }
+
+ if (vmSuspendedBool) {
+ guestActions.find("[name=vm-resume]").on({click : kimchi.vmresume});
+ }
+
+ if (vmRunningBool) {
+ guestActions.find("[name=vm-pause]").on({click : kimchi.vmsuspend});
+ }
+
+ guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit});
+ guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
+ guestActions.find("[name=vm-clone]").click(function(){
+ var guest = $(this).closest('li[name=guest]').attr("id");
+ wok.confirm({
+ title : i18n['KCHAPI6006M'],
+ content : i18n['KCHVM6010M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ }, function() {
+ kimchi.cloneGuest(guest, function(data){
+ kimchi.listVmsAuto();
+ });
+ }, null);
+ });
+
+ //Maintain menu open state
+ var actionMenu=guestActions.find("div[name=actionmenu]");
+ if (openMenu) {
+ $('.popover', actionMenu).toggle();
+ }
+
+ }else{
+ guestActions.find('.btn').attr('disabled', true);
+ $('.popover', guestActions.find("div[name=actionmenu]")).remove();
+
+ result.find('.guest-pending').removeClass('hide-content');
+ pendingText = result.find('.guest-pending .text')
+ if(vmObject.isCloning)
+ pendingText.text(i18n['KCHAPI6009M']);
+ else
+ pendingText.text(i18n['KCHAPI6008M']);
+ }
+
+ return result;
+};
+
+kimchi.circleGaugeInit = function(topElement, divName, display, percentage){
+ var gauge=topElement.find('div[name="' + divName + '"] .circleGauge');
+ if(gauge) {
+ var data=Object();
+ data.percentage = percentage;
+ data.display = display;
+ gauge.data(data);
+ }
+ gauge.circleGauge();
+ return(gauge);
+};
+
+kimchi.guestSetRequestHeader = function(xhr) {
+ xhr.setRequestHeader('Accept', 'text/html');
+};
+
+kimchi.guest_main = function() {
+ if(wok.tabMode['guests'] === 'admin') {
+ $('.tools').attr('style','display');
+ $("#vm-add").on("click", function(event) {
+ wok.window.open('plugins/kimchi/guest-add.html');
+ });
+ }
+ kimchi.guestTemplate = $('#guest-tmpl').html();
+ kimchi.guestElem=$('<div/>').html(kimchi.guestTemplate).find('li');
+ $('#guests-root-container').on('remove', function() {
+ kimchi.vmTimeout && clearTimeout(kimchi.vmTimeout);
+ });
+ kimchi.listVmsAuto()
+};
+
+kimchi.editTemplate = function(guestTemplate, oldPopStat) {
+ if (oldPopStat) {
+ return guestTemplate.replace("vm-action", "vm-action open");
+ }
+ return guestTemplate;
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
new file mode 100644
index 0000000..b920527
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
@@ -0,0 +1,56 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.guest_media_main = function() {
+
+ var refreshCDROMs = function() {
+ kimchi.listVMStorages({
+ vm: kimchi.selectedGuest,
+ storageType: 'cdrom'
+ }, function(storages) {
+ var rowHTML = $('#cdrom-row-tmpl').html();
+ var container = $('#guest-edit-cdrom-row-container');
+ $(container).empty();
+
+ $.each(storages, function(index, storage) {
+ storage['vm'] = kimchi.selectedGuest;
+ var templated = wok.substitute(rowHTML, storage);
+ container.append(templated);
+ });
+
+ var replaceCDROM = function(event) {
+ event.preventDefault();
+ kimchi.selectedGuestStorage = $(this).data('dev');
+ wok.window.open("plugins/kimchi/guest-cdrom-edit.html");
+ };
+
+ $('input[type="text"][name="cdrom"]', container).on('click', replaceCDROM);
+ $('.replace', container).on('click', replaceCDROM);
+ });
+ };
+
+ refreshCDROMs();
+
+ var onReplaced = function(params) {
+ refreshCDROMs();
+ };
+ wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
+
+ kimchi.clearGuestMedia = function() {
+ wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
+ };
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
new file mode 100644
index 0000000..bc162e8
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
@@ -0,0 +1,199 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+kimchi.guest_storage_add_main = function() {
+ var types = [{
+ label: 'cdrom',
+ value: 'cdrom',
+ },
+ {
+ label: 'disk',
+ value: 'disk',
+ }];
+ var typesRunning = [{
+ label: 'disk',
+ value: 'disk'
+ }];
+
+ var storageAddForm = $('#form-guest-storage-add');
+ var submitButton = $('#guest-storage-button-add');
+ var typeTextbox = $('input[name="type"]', storageAddForm);
+ var pathTextbox = $('input[name="path"]', storageAddForm);
+ var poolTextbox = $('input[name="pool"]', storageAddForm);
+ var volTextbox = $('input[name="vol"]', storageAddForm);
+
+ typeTextbox.change(function() {
+ var pathObject = {'cdrom': ".path-section", 'disk': '.volume-section'}
+ selectType = $(this).val();
+ $.each(pathObject, function(type, value) {
+ if(selectType == type){
+ $(value).removeClass('hidden');
+ } else {
+ $(value).addClass('hidden');
+ }
+ });
+
+ if ($(".path-section").hasClass('hidden')) {
+ $(poolTextbox).val('default');
+ $(poolTextbox).change();
+ $(pathTextbox).val("");
+ }
+ else {
+ $(poolTextbox).val("");
+ $(volTextbox).val("");
+ }
+ });
+
+ kimchi.listStoragePools(function(result) {
+ var options = [];
+ if (result && result.length) {
+ $.each(result, function(index, storagePool) {
+ if ((storagePool.state=="active") && (storagePool.type !== 'kimchi-iso')) {
+ options.push({
+ label: storagePool.name,
+ value: storagePool.name
+ });
+ }
+ });
+ wok.select('guest-add-storage-pool-list', options);
+ }
+ });
+
+ poolTextbox.change(function() {
+ var options = [];
+ kimchi.listStorageVolumes($(this).val(), function(result) {
+ var validVolType = { cdrom: /iso/, disk: /^(raw|qcow|qcow2|bochs|qed|vmdk)$/};
+ $('#guest-disk').selectMenu();
+ if (result.length) {
+ $.each(result, function(index, value) {
+ // Only unused volume can be attached
+ if (value.used_by.length == 0 && (value.type != 'file' || validVolType[selectType].test(value.format))) {
+ options.push({
+ label: value.name,
+ value: value.name
+ });
+ }
+ });
+ if (options.length) {
+ $(volTextbox).val(options[0].value);
+ $(volTextbox).change();
+ }
+ }
+ $('#guest-disk').selectMenu("setData", options);
+ });
+ });
+
+
+ typeTextbox.change(function() {
+ var pathObject = {'cdrom': ".path-section", 'disk': '.volume-section'}
+ var selectType = $(this).val();
+ $.each(pathObject, function(type, value) {
+ if(selectType == type){
+ $(value).removeClass('hidden');
+ } else {
+ $(value).addClass('hidden');
+ }
+ });
+ });
+
+ if (kimchi.thisVMState === 'running') {
+ types =typesRunning;
+ $(typeTextbox).val('disk');
+ typeTextbox.change();
+ poolTextbox.change();
+ }
+ var selectType = $(typeTextbox).val();
+ wok.select('guest-storage-type-list', types);
+
+ var validateCDROM = function(settings) {
+ if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path']))
+ return true;
+ else {
+ wok.message.error.code('KCHVMSTOR0001E');
+ return false;
+ }
+ }
+
+ var validateDisk = function(settings) {
+ if (settings['pool'] && settings['vol'])
+ return true;
+ else {
+ wok.message.error.code('KCHVMSTOR0002E');
+ return false;
+ }
+ }
+
+ validator = {cdrom: validateCDROM, disk: validateDisk};
+ var submitForm = function(event) {
+ if (submitButton.prop('disabled')) {
+ return false;
+ }
+
+ var formData = storageAddForm.serializeObject();
+ var settings = {
+ vm: kimchi.selectedGuest,
+ type: typeTextbox.val(),
+ };
+
+ $(submitButton).prop('disabled', true);
+ $.each([pathTextbox, poolTextbox, volTextbox], function(i, c) {
+ $(c).prop('disabled', true);
+ val = $(c).val()
+ if (val && val != '') {
+ settings[$(c).attr('name')] = $(c).val();
+ }
+ });
+ // Validate form for cdrom and disk
+ validateSpecifiedForm = validator[settings['type']];
+ if (!validateSpecifiedForm(settings)) {
+ $(submitButton).prop('disabled', false);
+ $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c) {
+ $(c).prop('disabled', false);
+ });
+ return false;
+ }
+ $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']);
+
+ kimchi.addVMStorage(settings, function(result) {
+ wok.window.close();
+ wok.topic('kimchi/vmCDROMAttached').publish({
+ result: result
+ });
+ }, function(result) {
+ var errText = result['reason'] ||
+ result['responseJSON']['reason'];
+ wok.message.error(errText);
+
+ $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c) {
+ $(c).prop('disabled', false);
+ });
+ $(submitButton).removeClass('loading').text(i18n['KCHVMCD6002M']);
+ });
+
+ event.preventDefault();
+ };
+
+ storageAddForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+ pathTextbox.on('change input propertychange', function(event) {
+ $(submitButton).prop('disabled', $(this).val() === '');
+ });
+ volTextbox.on('change propertychange', function (event) {
+ $(submitButton).prop('disabled', $(this).val() === '');
+ });
+
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
new file mode 100644
index 0000000..e2d2511
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
@@ -0,0 +1,858 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.host={};
+
+kimchi.host_main = function() {
+ var expand = function(header, toExpand) {
+ var controlledNode = $(header).attr('aria-controls');
+ $('#' + controlledNode)[toExpand ? 'removeClass' : 'addClass']('hidden');
+ $(header).attr('aria-expanded', toExpand ? 'true' : 'false');
+ };
+
+ var repositoriesGrid = null;
+ var initRepositoriesGrid = function(repo_type) {
+ var gridFields=[];
+ if (repo_type == "yum") {
+ gridFields=[{
+ name: 'repo_id',
+ label: i18n['KCHREPO6004M'],
+ 'class': 'repository-id'
+ }, {
+ name: 'config[repo_name]',
+ label: i18n['KCHREPO6005M'],
+ 'class': 'repository-name'
+ }, {
+ name: 'enabled',
+ label: i18n['KCHREPO6009M'],
+ 'class': 'repository-enabled'
+ }];
+ }
+ else if (repo_type == "deb") {
+ gridFields=[{
+ name: 'baseurl',
+ label: i18n['KCHREPO6006M'],
+ makeTitle: true,
+ 'class': 'repository-baseurl deb'
+ }, {
+ name: 'enabled',
+ label: i18n['KCHREPO6009M'],
+ 'class': 'repository-enabled deb'
+ }, {
+ name: 'config[dist]',
+ label: "dist",
+ 'class': 'repository-gpgcheck deb'
+ }, {
+ name: 'config[comps]',
+ label: "comps",
+ 'class': 'repository-gpgcheck deb'
+ }];
+ }
+ else {
+ gridFields=[{
+ name: 'repo_id',
+ label: i18n['KCHREPO6004M'],
+ 'class': 'repository-id'
+ }, {
+ name: 'enabled',
+ label: i18n['KCHREPO6009M'],
+ 'class': 'repository-enabled'
+ }, {
+ name: 'baseurl',
+ label: i18n['KCHREPO6006M'],
+ makeTitle: true,
+ 'class': 'repository-baseurl'
+ }];
+ }
+ repositoriesGrid = new wok.widget.Grid({
+ container: 'repositories-grid-container',
+ id: 'repositories-grid',
+ title: i18n['KCHREPO6003M'],
+ toolbarButtons: [{
+ id: 'repositories-grid-add-button',
+ label: i18n['KCHREPO6012M'],
+ onClick: function(event) {
+ wok.window.open({url:'plugins/kimchi/repository-add.html',
+ class: repo_type});
+ }
+ }, {
+ id: 'repositories-grid-enable-button',
+ label: i18n['KCHREPO6016M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ var name = repository['repo_id'];
+ var enable = !repository['enabled'];
+ $(this).prop('disabled', true);
+ kimchi.enableRepository(name, enable, function() {
+ wok.topic('kimchi/repositoryUpdated').publish();
+ });
+ }
+ }, {
+ id: 'repositories-grid-edit-button',
+ label: i18n['KCHREPO6013M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ kimchi.selectedRepository = repository['repo_id'];
+ wok.window.open({url:'plugins/kimchi/repository-edit.html',
+ class: repo_type});
+ }
+ }, {
+ id: 'repositories-grid-remove-button',
+ label: i18n['KCHREPO6014M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+
+ var settings = {
+ title : i18n['KCHREPO6001M'],
+ content : i18n['KCHREPO6002M'],
+ confirm : i18n['KCHAPI6004M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.deleteRepository(
+ repository['repo_id'],
+ function(result) {
+ wok.topic('kimchi/repositoryDeleted').publish(result);
+ }, function(error) {
+ }
+ );
+ });
+ }
+ }],
+ onRowSelected: function(row) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ $('#repositories-grid-remove-button').prop('disabled', false);
+ $('#repositories-grid-edit-button').prop('disabled', false);
+ var enabled = repository['enabled'];
+ $('#repositories-grid-enable-button')
+ .text(i18n[enabled ? 'KCHREPO6017M' : 'KCHREPO6016M'])
+ .prop('disabled', false);
+ },
+ frozenFields: [],
+ fields: gridFields,
+ data: listRepositories
+ });
+ };
+
+ var listRepositories = function(gridCallback) {
+ kimchi.listRepositories(function(repositories) {
+ if($.isFunction(gridCallback)) {
+ gridCallback(repositories);
+ }
+ else {
+ if(repositoriesGrid) {
+ repositoriesGrid.setData(repositories);
+ }
+ else {
+ initRepositoriesGrid();
+ repositoriesGrid.setData(repositories);
+ }
+ }
+ },
+ function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+
+ if($.isFunction(gridCallback)) {
+ gridCallback([]);
+ }
+ repositoriesGrid &&
+ repositoriesGrid.showMessage(message || i18n['KCHUPD6008M']);
+ });
+
+ $('#repositories-grid-remove-button').prop('disabled', true);
+ $('#repositories-grid-edit-button').prop('disabled', true);
+ $('#repositories-grid-enable-button').prop('disabled', true);
+ };
+
+ var softwareUpdatesGridID = 'software-updates-grid';
+ var softwareUpdatesGrid = null;
+ var progressAreaID = 'software-updates-progress-textarea';
+ var reloadProgressArea = function(result) {
+ var progressArea = $('#' + progressAreaID)[0];
+ $(progressArea).text(result['message']);
+ var scrollTop = $(progressArea).prop('scrollHeight');
+ $(progressArea).prop('scrollTop', scrollTop);
+ };
+
+ var initSoftwareUpdatesGrid = function(softwareUpdates) {
+ softwareUpdatesGrid = new wok.widget.Grid({
+ container: 'software-updates-grid-container',
+ id: softwareUpdatesGridID,
+ title: i18n['KCHUPD6001M'],
+ rowSelection: 'disabled',
+ toolbarButtons: [{
+ id: softwareUpdatesGridID + '-update-button',
+ label: i18n['KCHUPD6006M'],
+ disabled: true,
+ onClick: function(event) {
+ var updateButton = $(this);
+ var progressArea = $('#' + progressAreaID)[0];
+ $('#software-updates-progress-container').removeClass('hidden');
+ $(progressArea).text('');
+ !wok.isElementInViewport(progressArea) &&
+ progressArea.scrollIntoView();
+ $(updateButton).text(i18n['KCHUPD6007M']).prop('disabled', true);
+
+ kimchi.updateSoftware(function(result) {
+ reloadProgressArea(result);
+ $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
+ wok.topic('kimchi/softwareUpdated').publish({
+ result: result
+ });
+ }, function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+ wok.message.error(message || i18n['KCHUPD6009M']);
+ $(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
+ }, reloadProgressArea);
+ }
+ }],
+ frozenFields: [],
+ fields: [{
+ name: 'package_name',
+ label: i18n['KCHUPD6002M'],
+ 'class': 'software-update-name'
+ }, {
+ name: 'version',
+ label: i18n['KCHUPD6003M'],
+ 'class': 'software-update-version'
+ }, {
+ name: 'arch',
+ label: i18n['KCHUPD6004M'],
+ 'class': 'software-update-arch'
+ }, {
+ name: 'repository',
+ label: i18n['KCHUPD6005M'],
+ 'class': 'software-update-repos'
+ }],
+ data: listSoftwareUpdates
+ });
+ };
+
+ var listSoftwareUpdates = function(gridCallback) {
+ kimchi.listSoftwareUpdates(function(softwareUpdates) {
+ if($.isFunction(gridCallback)) {
+ gridCallback(softwareUpdates);
+ }
+ else {
+ if(softwareUpdatesGrid) {
+ softwareUpdatesGrid.setData(softwareUpdates);
+ }
+ else {
+ initSoftwareUpdatesGrid(softwareUpdates);
+ }
+ }
+
+ var updateButton = $('#' + softwareUpdatesGridID + '-update-button');
+ $(updateButton).prop('disabled', softwareUpdates.length === 0);
+ }, function(error) {
+ var message = error && error['responseJSON'] && error['responseJSON']['reason'];
+ if($.isFunction(gridCallback)) {
+ gridCallback([]);
+ }
+ softwareUpdatesGrid &&
+ softwareUpdatesGrid.showMessage(message || i18n['KCHUPD6008M']);
+ });
+ };
+
+ var reportGridID = 'available-reports-grid';
+ var reportGrid = null;
+ var enableReportButtons = function(toEnable) {
+ var buttonID = '#{grid}-{btn}-button';
+ $.each(['rename', 'remove', 'download'], function(i, n) {
+ $(wok.substitute(buttonID, {
+ grid: reportGridID,
+ btn: n
+ })).prop('disabled', !toEnable);
+ });
+ };
+ var initReportGrid = function(reports) {
+ reportGrid = new wok.widget.Grid({
+ container: 'available-reports-grid-container',
+ id: reportGridID,
+ title: i18n['KCHDR6002M'],
+ toolbarButtons: [{
+ id: reportGridID + '-generate-button',
+ label: i18n['KCHDR6006M'],
+ onClick: function(event) {
+ wok.window.open('plugins/kimchi/report-add.html');
+ }
+ }, {
+ id: reportGridID + '-rename-button',
+ label: i18n['KCHDR6008M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ kimchi.selectedReport = report['name'];
+ wok.window.open('plugins/kimchi/report-rename.html');
+ }
+ }, {
+ id: reportGridID + '-remove-button',
+ label: i18n['KCHDR6009M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ var settings = {
+ title : i18n['KCHAPI6004M'],
+ content : i18n['KCHDR6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.deleteReport({
+ name: report['name']
+ }, function(result) {
+ listDebugReports();
+ }, function(error) {
+ wok.message.error(error.responseJSON.reason);
+ });
+ });
+ }
+ }, {
+ id: reportGridID + '-download-button',
+ label: i18n['KCHDR6010M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ kimchi.downloadReport({
+ file: report['uri']
+ });
+ }
+ }],
+ onRowSelected: function(row) {
+ var report = reportGrid.getSelected();
+ // Only enable report buttons if the selected line is not a
+ // pending report
+ if (report['time'] == i18n['KCHDR6007M']) {
+ var gridElement = $('#'+ reportGridID);
+ var row = $('tr:contains(' + report['name'] + ')', gridElement);
+ enableReportButtons(false);
+ row.attr('class', '');
+ }
+ else {
+ enableReportButtons(true);
+ }
+ },
+ frozenFields: [],
+ fields: [{
+ name: 'name',
+ label: i18n['KCHDR6003M'],
+ 'class': 'debug-report-name'
+ }, {
+ name: 'time',
+ label: i18n['KCHDR6005M'],
+ 'class': 'debug-report-time'
+ }],
+ data: reports
+ });
+ };
+
+ var getPendingReports = function() {
+ var reports = []
+ var filter = 'status=running&target_uri=' + encodeURIComponent('^/plugins/kimchi/debugreports/*')
+
+ kimchi.getTasksByFilter(filter, function(tasks) {
+ for(var i = 0; i < tasks.length; i++) {
+ reportName = tasks[i].target_uri.replace(/^\/plugins\/kimchi\/debugreports\//, '') || i18n['KCHDR6012M'];
+ reports.push({'name': reportName, 'time': i18n['KCHDR6007M']})
+
+ if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
+ continue;
+ }
+
+ kimchi.trackTask(tasks[i].id, function(result) {
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, null);
+ }
+ }, null, true);
+
+ return reports;
+ };
+
+ var listDebugReports = function() {
+ kimchi.listReports(function(reports) {
+ pendingReports = getPendingReports();
+ allReports = pendingReports.concat(reports);
+ $('#debug-report-section').removeClass('hidden');
+
+ // Row selection will be cleared so disable buttons here
+ enableReportButtons(false);
+
+ if(reportGrid) {
+ reportGrid.setData(allReports);
+ }
+ else {
+ initReportGrid(allReports);
+ }
+
+ // Set id-debug-img to pending reports
+ // It will display a loading icon
+ var gridElement = $('#' + reportGridID);
+ $.each($('td:contains(' + i18n['KCHDR6007M'] + ')', gridElement), function(index, row) {
+ $(row).parent().addClass('no-hover');
+ $(row).attr('id', 'id-debug-img');
+ });
+ }, function(error) {
+ if(error['status'] == 403) {
+ $('#debug-report-section').addClass('hidden');
+ return;
+ }
+ $('#debug-report-section').removeClass('hidden');
+ });
+ };
+
+ var shutdownButtonID = '#host-button-shutdown';
+ var restartButtonID = '#host-button-restart';
+ var shutdownHost = function(params) {
+ var settings = {
+ title : i18n['KCHAPI6004M'],
+ content : i18n['KCHHOST6008M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.shutdown(params);
+ $(shutdownButtonID).prop('disabled', true);
+ $(restartButtonID).prop('disabled', true);
+ // Check if there is any VM is running.
+ kimchi.listVMs(function(vms) {
+ for(var i = 0; i < vms.length; i++) {
+ if(vms[i]['state'] === 'running') {
+ wok.message.error.code('KCHHOST6001E');
+ $(shutdownButtonID).prop('disabled', false);
+ $(restartButtonID).prop('disabled', false);
+ return;
+ }
+ }
+
+ });
+ }, function() {
+ });
+ };
+
+ var initPage = function() {
+ $('#host-info-container .section-header').each(function(i, header) {
+ $('<span class="arrow"></span>').prependTo(header);
+ var toExpand = $(header).attr('aria-expanded') !== 'false';
+ expand(header, toExpand);
+ });
+
+ $('#host-info-container').on('click', '.section-header', function(event) {
+ var toExpand = $(this).attr('aria-expanded') === 'false';
+ expand(this, toExpand);
+ });
+
+ $('#host-button-shutdown').on('click', function(event) {
+ shutdownHost(null);
+ });
+
+ $('#host-button-restart').on('click', function(event) {
+ shutdownHost({
+ reboot: true
+ });
+ });
+
+ var setupUI = function() {
+ if (kimchi.capabilities == undefined) {
+ setTimeout(setupUI, 2000);
+ return;
+ }
+
+ if((kimchi.capabilities['repo_mngt_tool']) && (kimchi.capabilities['repo_mngt_tool']!="None")) {
+ initRepositoriesGrid(kimchi.capabilities['repo_mngt_tool']);
+ $('#repositories-section').switchClass('hidden', kimchi.capabilities['repo_mngt_tool']);
+ wok.topic('kimchi/repositoryAdded')
+ .subscribe(listRepositories);
+ wok.topic('kimchi/repositoryUpdated')
+ .subscribe(listRepositories);
+ wok.topic('kimchi/repositoryDeleted')
+ .subscribe(listRepositories);
+ }
+
+ if(kimchi.capabilities['update_tool']) {
+ $('#software-update-section').removeClass('hidden');
+ initSoftwareUpdatesGrid();
+ wok.topic('kimchi/softwareUpdated')
+ .subscribe(listSoftwareUpdates);
+ $('#software-updates-progress-container').accordion({
+ collapsible: true
+ });
+ }
+
+ if(kimchi.capabilities['system_report_tool']) {
+ listDebugReports();
+ wok.topic('kimchi/debugReportAdded')
+ .subscribe(listDebugReports);
+ wok.topic('kimchi/debugReportRenamed')
+ .subscribe(listDebugReports);
+ }
+ };
+ setupUI();
+ };
+
+ kimchi.getHost(function(data) {
+ var htmlTmpl = $('#host-tmpl').html();
+ data['logo'] = data['logo'] || '';
+ data['memory'] = wok.formatMeasurement(data['memory'], {
+ fixed: 2
+ });
+ var templated = wok.substitute(htmlTmpl, data);
+ $('#host-content-container').html(templated);
+
+ initPage();
+ initTracker();
+ });
+
+ var StatsMgr = function() {
+ var statsArray = {
+ cpu: {
+ u: {
+ type: 'percent',
+ legend: i18n['KCHHOST6002M'],
+ points: []
+ }
+ },
+ memory: {
+ u: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ legend: i18n['KCHHOST6003M'],
+ points: []
+ }
+ },
+ diskIO: {
+ r: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6004M'],
+ points: []
+ },
+ w: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6005M'],
+ 'class': 'disk-write',
+ points: []
+ }
+ },
+ networkIO: {
+ r: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6006M'],
+ points: []
+ },
+ s: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6007M'],
+ 'class': 'network-sent',
+ points: []
+ }
+ }
+ };
+ var SIZE = 20;
+ var cursor = SIZE;
+
+ var add = function(stats) {
+ for(var key in stats) {
+ var item = stats[key];
+ for(var metrics in item) {
+ var value = item[metrics]['v'];
+ var max = item[metrics]['max'];
+ var unifiedMetrics = statsArray[key][metrics];
+ var ps = unifiedMetrics['points'];
+ if(!Array.isArray(value)){
+ ps.push(value);
+ if(ps.length > SIZE + 1) {
+ ps.shift();
+ }
+ }
+ else{
+ ps=ps.concat(value);
+ ps.splice(0, ps.length-SIZE-1);
+ unifiedMetrics['points']=ps;
+ }
+ if(max !== undefined) {
+ unifiedMetrics['max'] = max;
+ }
+ else {
+ if(unifiedMetrics['type'] !== 'value') {
+ continue;
+ }
+ max = -Infinity;
+ $.each(ps, function(i, value) {
+ if(value > max) {
+ max = value;
+ }
+ });
+ if(max === 0) {
+ ++max;
+ }
+ max *= 1.1;
+ unifiedMetrics['max'] = max;
+ }
+ }
+ }
+ cursor++;
+ };
+
+ var get = function(which) {
+ var stats = statsArray[which];
+ var lines = [];
+ for(var k in stats) {
+ var obj = stats[k];
+ var line = {
+ type: obj['type'],
+ base: obj['base'],
+ unit: obj['unit'],
+ fixed: obj['fixed'],
+ legend: obj['legend']
+ };
+ if(obj['max']) {
+ line['max'] = obj['max'];
+ }
+ if(obj['class']) {
+ line['class'] = obj['class'];
+ }
+ var ps = obj['points'];
+ var numStats = ps.length;
+ var unifiedPoints = [];
+ $.each(ps, function(i, value) {
+ unifiedPoints.push({
+ x: cursor - numStats + i,
+ y: value
+ });
+ });
+ line['points'] = unifiedPoints;
+ lines.push(line);
+ }
+ return lines;
+ };
+
+ return {
+ add: add,
+ get: get
+ };
+ };
+
+ var Tracker = function(charts) {
+ var charts = charts;
+ var timer = null;
+ var statsPool = new StatsMgr();
+ var setCharts = function(newCharts) {
+ charts = newCharts;
+ for(var key in charts) {
+ var chart = charts[key];
+ chart.updateUI(statsPool.get(key));
+ }
+ };
+
+ var self = this;
+
+ var UnifyStats = function(stats) {
+ var result= {
+ cpu: {
+ u: {
+ v: stats['cpu_utilization']
+ }
+ },
+ memory: {
+ u: {
+ }
+ },
+ diskIO: {
+ r: {
+ v: stats['disk_read_rate']
+ },
+ w: {
+ v: stats['disk_write_rate']
+ }
+ },
+ networkIO: {
+ r: {
+ v: stats['net_recv_rate']
+ },
+ s: {
+ v: stats['net_sent_rate']
+ }
+ }
+ };
+ if(Array.isArray(stats['memory'])){
+ result.memory.u['v']=[];
+ result.memory.u['max']=-Infinity;
+ for(var i=0;i<stats['memory'].length;i++){
+ result.memory.u['v'].push(stats['memory'][i]['avail']);
+ result.memory.u['max']=Math.max(result.memory.u['max'],stats['memory'][i]['total']);
+ }
+ }
+ else {
+ result.memory.u['v']=stats['memory']['avail'],
+ result.memory.u['max']=stats['memory']['total']
+ }
+ return(result);
+ };
+
+
+ var statsCallback = function(stats) {
+ var unifiedStats = UnifyStats(stats);
+ statsPool.add(unifiedStats);
+ for(var key in charts) {
+ var chart = charts[key];
+ chart.updateUI(statsPool.get(key));
+ }
+ timer = setTimeout(function() {
+ continueTrack();
+ }, 1000);
+ };
+
+ var track = function() {
+ kimchi.getHostStatsHistory(statsCallback,
+ function() {
+ continueTrack();
+ });
+ };
+
+ var continueTrack = function() {
+ kimchi.getHostStats(statsCallback,
+ function() {
+ continueTrack();
+ });
+ };
+
+ var destroy = function() {
+ timer && clearTimeout(timer);
+ timer = null;
+ };
+
+ return {
+ setCharts: setCharts,
+ start: track,
+ stop: destroy
+ };
+ };
+
+ var initTracker = function() {
+ // TODO: Extend tabs with onUnload event to unregister timers.
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.stop();
+ delete kimchi.hostTimer;
+ }
+
+ var trackedCharts = {
+ cpu: new wok.widget.LineChart({
+ id: 'chart-cpu',
+ node: 'container-chart-cpu',
+ type: 'percent'
+ }),
+ memory: new wok.widget.LineChart({
+ id: 'chart-memory',
+ node: 'container-chart-memory',
+ type: 'value'
+ }),
+ diskIO: new wok.widget.LineChart({
+ id: 'chart-disk-io',
+ node: 'container-chart-disk-io',
+ type: 'value'
+ }),
+ networkIO: new wok.widget.LineChart({
+ id: 'chart-network-io',
+ node: 'container-chart-network-io',
+ type: 'value'
+ })
+ };
+
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.setCharts(trackedCharts);
+ }
+ else {
+ kimchi.hostTimer = new Tracker(trackedCharts);
+ kimchi.hostTimer.start();
+ }
+ };
+
+ $('#host-root-container').on('remove', function() {
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.stop();
+ delete kimchi.hostTimer;
+ }
+
+ repositoriesGrid && repositoriesGrid.destroy();
+ wok.topic('kimchi/repositoryAdded')
+ .unsubscribe(listRepositories);
+ wok.topic('kimchi/repositoryUpdated')
+ .unsubscribe(listRepositories);
+ wok.topic('kimchi/repositoryDeleted')
+ .unsubscribe(listRepositories);
+
+ softwareUpdatesGrid && softwareUpdatesGrid.destroy();
+ wok.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates);
+
+ reportGrid && reportGrid.destroy();
+ wok.topic('kimchi/debugReportAdded').unsubscribe(listDebugReports);
+ wok.topic('kimchi/debugReportRenamed').unsubscribe(listDebugReports);
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.main.js
new file mode 100644
index 0000000..2fdeb85
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.main.js
@@ -0,0 +1,26 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.capabilities = undefined;
+kimchi.getCapabilities(function(result) {
+ kimchi.capabilities = result;
+
+ if(kimchi.capabilities.federation=="on")
+ $('#peers').removeClass('hide-content');
+}, function() {
+ kimchi.capabilities = {};
+});
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.network.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.network.js
new file mode 100644
index 0000000..c43b59a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.network.js
@@ -0,0 +1,442 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+kimchi.NETWORK_TYPE_BRIDGE = "bridged";
+
+kimchi.initNetwork = function() {
+ if(wok.tabMode['network'] === 'admin') {
+ $('.tools').attr('style','display');
+ $('#network-content .header span:last-child').attr('style','display');
+ kimchi.initNetworkCreation();
+ }
+ kimchi.initNetworkListView();
+ kimchi.initNetworkDialog();
+ kimchi.initNetworkCleanup();
+};
+
+kimchi.initNetworkListView = function() {
+ kimchi.listNetworks(function(data) {
+ for (var i = 0; i < data.length; i++) {
+ var network = {
+ name : data[i].name,
+ in_use : data[i].in_use,
+ state : data[i].state === "active" ? "up" : "down"
+ };
+ if (data[i].connection === "bridge") {
+ network.type = kimchi.NETWORK_TYPE_BRIDGE;
+ } else {
+ network.type = data[i].connection;
+ }
+ network.interface = data[i].interface ? data[i].interface : null;
+ network.addrSpace = data[i].subnet ? data[i].subnet : null;
+ network.persistent = data[i].persistent;
+ kimchi.addNetworkItem(network);
+ }
+ $('#networkGrid').grid({enableSorting: false});
+ $('input', $('.grid-control', '#network-content')).on('keyup', function(){
+ $('#networkGrid').grid('filter', $(this).val());
+ });
+ });
+};
+
+kimchi.addNetworkItem = function(network) {
+ var itemNode = $.parseHTML(kimchi.getNetworkItemHtml(network));
+ $("#networkBody").append(itemNode);
+ if(wok.tabMode["network"] === "admin") {
+ $(".column-action").attr("style","display");
+ } else {
+ $(".column-space").addClass('column-space-no-border-right');
+ }
+ kimchi.addNetworkActions(network);
+ return itemNode;
+};
+
+kimchi.getNetworkItemHtml = function(network) {
+ if(!network.interface) {
+ network.interface = i18n["KCHNET6001M"];
+ }
+ if(!network.addrSpace) {
+ network.addrSpace = i18n["KCHNET6001M"];
+ }
+ if(i18n["network_type_" + network.type]) {
+ network.type = i18n["network_type_" + network.type];
+ }
+
+ var disable_in_use = network.in_use ? "ui-state-disabled" : "";
+ var networkItem = wok.substitute($('#networkItem').html(), {
+ name : network.name,
+ state : network.state,
+ type : network.type,
+ interface: network.interface,
+ addrSpace : network.addrSpace,
+ startClass : network.state === "up" ? "hide-action-item" : "",
+ stopClass : network.state === "down" ? "hide-action-item" : disable_in_use,
+ stopDisabled : network.in_use ? "disabled" : "",
+ deleteClass : network.state === "up" || network.in_use ? "ui-state-disabled" : "",
+ deleteDisabled: network.state === "up" || network.in_use ? "disabled" : ""
+ });
+ return networkItem;
+};
+
+kimchi.stopNetwork = function(network,menu) {
+ $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("up", "nw-loading");
+ $("[nwAct='stop']", menu).addClass("ui-state-disabled");
+ kimchi.toggleNetwork(network.name, false, function() {
+ $("[nwAct='start']", menu).removeClass("hide-action-item");
+ $("[nwAct='stop']", menu).addClass("hide-action-item");
+ $("[nwAct='stop']", menu).removeClass("ui-state-disabled");
+ if (!network.in_use) {
+ $("[nwAct='delete']", menu).removeClass("ui-state-disabled");
+ $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
+ }
+ $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "down");
+ }, function(err) {
+ $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "up");
+ if (!network.in_use) {
+ $("[nwAct='stop']", menu).removeClass("ui-state-disabled");
+ }
+ wok.message.error(err.responseJSON.reason);
+ });
+}
+
+kimchi.addNetworkActions = function(network) {
+ $(".menu-container", "#" + wok.escapeStr(network.name)).menu();
+
+ $('#' + wok.escapeStr(network.name)).on('click', '.menu-container li', function(evt) {
+ var menu = $(evt.currentTarget).parent();
+ if ($(evt.currentTarget).attr("nwAct") === "start") {
+ $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("down", "nw-loading");
+ $("[nwAct='start']", menu).addClass("ui-state-disabled");
+ $("[nwAct='delete']", menu).addClass("ui-state-disabled");
+ $(":first-child", $("[nwAct='delete']", menu)).attr("disabled", true);
+ kimchi.toggleNetwork(network.name, true, function() {
+ $("[nwAct='start']", menu).addClass("hide-action-item");
+ $("[nwAct='start']", menu).removeClass("ui-state-disabled");
+ $("[nwAct='stop']", menu).removeClass("hide-action-item");
+ network.state = "up";
+ if (network.in_use) {
+ $("[nwAct='stop']", menu).addClass("ui-state-disabled");
+ }
+ $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading", "up");
+ }, function(err) {
+ $(".network-state", $("#" + wok.escapeStr(network.name))).switchClass("nw-loading","down");
+ $("[nwAct='start']", menu).removeClass("ui-state-disabled");
+ if (!network.in_use) {
+ $("[nwAct='delete']", menu).removeClass("ui-state-disabled");
+ }
+ $(":first-child", $("[nwAct='delete']", menu)).removeAttr("disabled");
+ wok.message.error(err.responseJSON.reason);
+ });
+ } else if ($(evt.currentTarget).attr("nwAct") === "stop") {
+ if (network.in_use) {
+ return false;
+ }
+ if (!network.persistent) {
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHNET6004M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.stopNetwork(network, menu);
+ $('#networkGrid').grid('deleteRow', $(evt.currentTarget).parents(".row"));
+ }, null);
+ }
+ else {
+ kimchi.stopNetwork(network, menu);
+ network.state = "down";
+ }
+ } else if ($(evt.currentTarget).attr("nwAct") === "delete") {
+ if (network.state === "up" || network.in_use) {
+ return false;
+ }
+ wok.confirm({
+ title : i18n['KCHAPI6006M'],
+ content : i18n['KCHNET6002M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ }, function() {
+ kimchi.deleteNetwork(network.name, function() {
+ $('#networkGrid').grid('deleteRow', $(evt.currentTarget).parents(".row"));
+ });
+ }, null);
+ }
+ });
+
+ $("#networkBody .column-action .popable").button({
+ icons : {
+ secondary : "action-button-icon"
+ }
+ });
+
+};
+
+kimchi.initNetworkCreation = function() {
+ $("#networkAdd").on("click", function() {
+ kimchi.openNetworkDialog(function() {
+ var errorCallback = function(){
+ $("#networkFormOk").button("enable");
+ $("#networkName").removeAttr("readonly");
+ $("#networkFormOk span").text(i18n.KCHAPI6005M);
+ };
+ var network = kimchi.getNetworkDialogValues();
+ var data = {
+ name : network.name,
+ connection: network.type
+ };
+ if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
+ data.connection = "bridge";
+ data.interface = network.interface;
+ if ($("#enableVlan").prop("checked")) {
+ data.vlan_id = network.vlan_id;
+ if (!(data.vlan_id >=1 && data.vlan_id <= 4094)) {
+ wok.message.error.code('KCHNET6001E');
+ errorCallback();
+ return;
+ }
+ }
+ }
+ kimchi.createNetwork(data, function(result) {
+ network.state = result.state === "active" ? "up" : "down";
+ network.interface = result.interface ? result.interface : i18n["KCHNET6001M"];
+ network.addrSpace = result.subnet ? result.subnet : i18n["KCHNET6001M"];
+ network.persistent = result.persistent;
+ $('#networkGrid').grid('addRow', kimchi.addNetworkItem(network));
+ $("#networkConfig").dialog("close");
+ }, function(data) {
+ wok.message.error(data.responseJSON.reason);
+ errorCallback();
+ });
+ });
+ });
+};
+
+kimchi.initNetworkDialog = function() {
+ buttonsObj= {};
+ buttonsObj['id'] = "networkFormOk";
+ buttonsObj['text'] = i18n.KCHAPI6005M;
+ buttonsObj['class'] = "btn-normal";
+ buttonsObj['disabled'] = true;
+ buttonsObj['click'] = function() { };
+ buttonsObjCancel= {};
+ buttonsObjCancel['id'] = "networkFormCancel";
+ buttonsObjCancel['text'] = i18n.KCHAPI6003M;
+ buttonsObjCancel['class'] = "btn-normal";
+ buttonsObjCancel['disabled'] = false;
+ buttonsObjCancel['click'] = function() {
+ $(this).dialog("close");
+ };
+ $("#networkConfig").dialog({
+ autoOpen : false,
+ modal : true,
+ width : 600,
+ draggable : false,
+ resizable : false,
+ closeText: "X",
+ dialogClass : "network-ui-dialog remove-when-logged-off",
+ open : function(){
+ $(".ui-dialog-titlebar-close", $("#networkConfig").parent()).removeAttr("title");
+ $(".ui-widget-overlay").css({
+ "background": "#FFFFFF",
+ "opacity": "0.5"
+ });
+ },
+ beforeClose : function() {
+ kimchi.cleanNetworkDialog();
+ },
+ buttons : [buttonsObj, buttonsObjCancel]
+ });
+ $("#networkConfig").parent().css({
+ "background": "#FFFFFF",
+ "border-radius": 0,
+ "border": "2px solid #999999"
+ });
+ $(".ui-dialog-titlebar button", $("#networkConfig").parent()).remove();
+ $(".ui-dialog-titlebar span", $("#networkConfig").parent()).css({
+ "font-weight": "lighter",
+ "height": "48px",
+ "line-height": "48px",
+ "margin": "0 30px",
+ "color": "#444444",
+ "font-size": "22px"
+ });
+ $(".ui-dialog-titlebar", $("#networkConfig").parent()).css({
+ "box-shadow": "none",
+ "padding": "0",
+ });
+ $(".ui-dialog-buttonpane", $("#networkConfig").parent()).css({
+ "background": "#008ABF"
+ });
+ $(".ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset").css({
+ "padding": "0 10px",
+ "float": "left"
+ });
+ $(".ui-dialog-buttonpane .ui-dialog-buttonset button").removeClass("ui-corner-all");
+ $(".ui-dialog-buttonpane .ui-dialog-buttonset button").css({
+ "background": "#FFFFFF",
+ "color": "#444444",
+ "font-size": "13px",
+ "border-radius": "0",
+ "opacity": "1"
+ });
+ kimchi.setupNetworkFormEvent();
+};
+
+kimchi.openNetworkDialog = function(okCallback) {
+ kimchi.getInterfaces(function(result) {
+ var options = [];
+ $('#networkDestinationID').selectMenu();
+ var nics = {};
+ for (var i = 0; i < result.length; i++) {
+ options.push({label:result[i].name,value:result[i].name});
+ nics[result[i].name] = result[i];
+ }
+ result.length>0 && $("#networkDestinationID").selectMenu("setData", options);
+ onChange = function() {
+ $("#networkDestinationLabel").text($("#networkDestinationID li:first-child").text());
+ $("#networkDestinationID li:first-child").addClass("active");
+ if (result.length>0 && nics[$("#networkDestinationLabel").text()].type === "bridge") {
+ $("#enableVlan").prop("checked", false);
+ $("#enableVlan").prop("disabled", true);
+ $("#networkVlanID").val("");
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ } else {
+ $("#enableVlan").prop("disabled",false);
+ }
+ };
+ $("#networkDestinationLabel").on("change", onChange);
+ kimchi.setDefaultNetworkType(result.length!==0);
+ onChange();
+ });
+ $("#networkConfig").dialog({
+ title : i18n.KCHNET6003M
+ });
+ $("#networkFormOk").on("click", function() {
+ $("#networkFormOk").button("disable");
+ $("#networkName").prop("readonly", "readonly");
+ $("#networkFormOk span").text(i18n.KCHAPI6008M);
+ okCallback();
+ });
+ $("#enableVlan").on("click", function() {
+ $("#networkVlanID").prop("disabled", !this.checked);
+ if (!this.checked) {
+ $("#networkVlanID").slideUp(100);
+ $("#labelNetworkVlanID").slideUp(100);
+ $("#networkVlanID").val("");
+ }
+ else {
+ $("#networkVlanID").slideDown(100);
+ $("#labelNetworkVlanID").slideDown(100);
+ }
+ });
+ $("#networkConfig").dialog("open");
+};
+
+kimchi.enableBridgeOptions = function(enable) {
+ if (!enable) {
+ $("#enableVlan").prop("checked", false);
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ $("#networkVlanID").val("");
+ $("#networkDestinationLabel").text("");
+ $("#bridgeOptions").slideUp(100);
+ } else if (!$("#networkDestinationLabel").text()){
+ $("#networkDestinationLabel").text($("#networkDestinationID li:first-child").text());
+ $("#bridgeOptions").slideDown(100);
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ }
+};
+
+
+kimchi.setDefaultNetworkType = function(isInterfaceAvail) {
+ $("#networkTypeBri").prop("checked", isInterfaceAvail);
+ $("#networkTypeBri").prop("disabled", !isInterfaceAvail);
+ $("#networkTypeNat").prop("checked", !isInterfaceAvail);
+ if (!isInterfaceAvail) {
+ kimchi.enableBridgeOptions(false);
+ $("#networkBriDisabledLabel").show();
+ } else {
+ if (kimchi.capabilities && kimchi.capabilities.nm_running) {
+ wok.message.warn(i18n['KCHNET6001W']);
+ }
+ $("#bridgeOptions").slideDown(100);
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ $("#networkBriDisabledLabel").hide();
+ }
+};
+
+kimchi.getNetworkDialogValues = function() {
+ var network = {
+ name : $("#networkName").val(),
+ type : $("input:radio[name=networkType]:checked").val()
+ };
+ if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
+ network.interface = $("#networkDestinationLabel").text();
+ network.vlan_id = parseInt($("#networkVlanID").val());
+ }
+ return network;
+};
+
+kimchi.cleanNetworkDialog = function() {
+ $("input:text", "#networkConfig").val(null).removeClass("invalid-field");
+ $("#networkTypeIso").prop("checked", false);
+ $("#networkTypeNat").prop("checked", false);
+ $("#networkTypeBri").prop("checked", false);
+ $("#networkDestinationLabel").text($("#networkDestinationID li:first-child").text());
+ $("#networkFormOk").off("click");
+ $("#networkFormOk").button("disable");
+ $("#networkFormOk span").text(i18n.KCHAPI6005M);
+ $("#networkName").removeAttr("readonly");
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ $("#enableVlan").prop("checked", false);
+
+};
+kimchi.setupNetworkFormEvent = function() {
+ $("#networkName").on("keyup", function(event) {
+ $("#networkName").toggleClass("invalid-field", !$("#networkName").val().match(/^[^\"\/]+$/));
+ kimchi.updateNetworkFormButton();
+ });
+ $("#networkTypeIso").on("click", function(event) {
+ kimchi.enableBridgeOptions(false);
+ });
+ $("#networkTypeNat").on("click", function(event) {
+ kimchi.enableBridgeOptions(false);
+ });
+ $("#networkTypeBri").on("click", function(event) {
+ kimchi.enableBridgeOptions(true);
+ });
+};
+
+kimchi.updateNetworkFormButton = function() {
+ if($("#networkName").hasClass("invalid-field")){
+ $("#networkFormOk").button("disable");
+ }else{
+ $("#networkFormOk").button("enable");
+ }
+};
+
+kimchi.initNetworkCleanup = function() {
+ $("#network-content").on("remove", function() {
+ $("#networkConfig").dialog("destroy");
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
new file mode 100644
index 0000000..5f098d3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
@@ -0,0 +1,72 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.report_add_main = function() {
+ var reportGridID = 'available-reports-grid';
+ var addReportForm = $('#form-report-add');
+ var submitButton = $('#button-report-add');
+ var nameTextbox = $('input[name="name"]', addReportForm);
+ nameTextbox.select();
+
+ var submitForm = function(event) {
+ if(submitButton.prop('disabled')) {
+ return false;
+ }
+ var reportName = nameTextbox.val();
+ var validator = RegExp("^[_A-Za-z0-9-]*$");
+ if (!validator.test(reportName)) {
+ wok.message.error.code('KCHDR6011M');
+ return false;
+ }
+ var formData = addReportForm.serializeObject();
+ var taskAccepted = false;
+ var onTaskAccepted = function() {
+ if(taskAccepted) {
+ return;
+ }
+ taskAccepted = true;
+ wok.window.close();
+ wok.topic('kimchi/debugReportAdded').publish();
+ };
+
+ kimchi.createReport(formData, function(result) {
+ onTaskAccepted();
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+
+ taskAccepted &&
+ $('.grid-body-view table tr:first-child',
+ '#' + reportGridID).remove();
+ submitButton.prop('disabled', false);
+ nameTextbox.select();
+ }, onTaskAccepted);
+
+ event.preventDefault();
+ };
+
+ addReportForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
new file mode 100644
index 0000000..1bdb8d9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
@@ -0,0 +1,66 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.report_rename_main = function() {
+ var renameReportForm = $('#form-report-rename');
+ var submitButton = $('#button-report-rename');
+ var nameTextbox = $('input[name="name"]', renameReportForm);
+ var submitForm = function(event) {
+ if(submitButton.prop('disabled')) {
+ return false;
+ }
+ var reportName = nameTextbox.val();
+
+ // if the user hasn't changed the report's name,
+ // nothing should be done.
+ if (reportName == kimchi.selectedReport) {
+ wok.message.error.code('KCHDR6013M');
+ return false;
+ }
+
+ var validator = RegExp("^[A-Za-z0-9-]*$");
+ if (!validator.test(reportName)) {
+ wok.message.error.code('KCHDR6011M');
+ return false;
+ }
+ var formData = renameReportForm.serializeObject();
+ submitButton.prop('disabled', true);
+ nameTextbox.prop('disabled', true);
+ kimchi.renameReport(kimchi.selectedReport, formData, function(result) {
+ submitButton.prop('disabled', false);
+ nameTextbox.prop('disabled', false);
+ wok.window.close();
+ wok.topic('kimchi/debugReportRenamed').publish({
+ result: result
+ });
+ }, function(result) {
+ var errText = result &&
+ result['responseJSON'] &&
+ result['responseJSON']['reason'];
+ wok.message.error(errText);
+ submitButton.prop('disabled', false);
+ nameTextbox.prop('disabled', false).focus();
+ });
+
+ event.preventDefault();
+ };
+
+ renameReportForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+
+ nameTextbox.val(kimchi.selectedReport).select();
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
new file mode 100644
index 0000000..656306b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
@@ -0,0 +1,96 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.repository_add_main = function() {
+
+ var addForm = $('#form-repository-add');
+ var addButton = $('#button-repository-add');
+
+ var validateField = function(event) {
+ var valid=($(this).val()!=='');
+ $(addButton).prop('disabled', !valid);
+ return(valid);
+ };
+
+ var validateForm = function(event) {
+ var valid=false;
+ addForm.find('input.required').each( function() {
+ valid=($(this).val()!=='');
+ return(!valid);
+ });
+ return(valid);
+ }
+
+ addForm.find('input.required').on('input propertychange', validateField);
+
+ var weedObject = function(obj) {
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ if((typeof(obj[key])==="object") && !Array.isArray(obj[key])) {
+ weedObject(obj[key]);
+ }
+ else if(obj[key] == '') {
+ delete obj[key];
+ }
+ }
+ }
+ }
+
+ var addRepository = function(event) {
+ var valid = validateForm();
+ if(!valid) {
+ return false;
+ }
+
+ var formData = $(addForm).serializeObject();
+
+ if (formData && formData.isMirror!=undefined) {
+ formData.isMirror=(String(formData.isMirror).toLowerCase() === 'true');
+ }
+ if(formData.isMirror) {
+ if(formData.config==undefined) {
+ formData.config=new Object();
+ }
+ formData.config.mirrorlist=formData.baseurl;
+ delete formData.baseurl;
+ delete formData.isMirror;
+ }
+ weedObject(formData);
+ if(formData.config && formData.config.comps) {
+ formData.config.comps=formData.config.comps.split(/[,\s]/);
+ for(var i=0; i>formData.config.comps.length; i++) {
+ formData.config.comps[i]=formData.config.comps[i].trim();
+ }
+ for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
+ formData.config.comps.splice(j, 1);
+ }
+ }
+
+ kimchi.createRepository(formData, function() {
+ wok.topic('kimchi/repositoryAdded').publish();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+ return false;
+ };
+
+ $(addForm).on('submit', addRepository);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
new file mode 100644
index 0000000..5bfc51e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
@@ -0,0 +1,74 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.repository_edit_main = function() {
+
+ var editForm = $('#form-repository-edit');
+
+ var saveButton = $('#repository-edit-button-save');
+
+ if(kimchi.capabilities['repo_mngt_tool']=="yum") {
+ editForm.find('input.deb').prop('disabled', true);
+ }
+ else if(kimchi.capabilities['repo_mngt_tool']=="deb") {
+ editForm.find('input.yum').prop('disabled', true);
+ }
+
+ kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) {
+ editForm.fillWithObject(repository);
+
+ $('input', editForm).on('input propertychange', function(event) {
+ if($(this).val() !== '') {
+ $(saveButton).prop('disabled', false);
+ }
+ });
+ });
+
+
+ var editRepository = function(event) {
+ var formData = $(editForm).serializeObject();
+
+ if (formData && formData.config) {
+ formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() === 'true');
+ }
+
+ if(formData.config && formData.config.comps) {
+ formData.config.comps=formData.config.comps.split(/[,\s]/);
+ for(var i=0; i>formData.config.comps.length; i++) {
+ formData.config.comps[i]=formData.config.comps[i].trim();
+ }
+ for (var j=formData.config.comps.indexOf(""); j!=-1; j=formData.config.comps.indexOf("")) {
+ formData.config.comps.splice(j, 1);
+ }
+ }
+
+ kimchi.updateRepository(kimchi.selectedRepository, formData, function() {
+ wok.topic('kimchi/repositoryUpdated').publish();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+
+ return false;
+ };
+
+ $(editForm).on('submit', editRepository);
+ $(saveButton).on('click', editRepository);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js
new file mode 100644
index 0000000..40a43f6
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js
@@ -0,0 +1,428 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.doListStoragePools = function() {
+ kimchi.listStoragePools(function(result) {
+ var storageHtml = $('#storageTmpl').html();
+ if (result && result.length) {
+ var listHtml = '';
+ $.each(result, function(index, value) {
+ value.usage = Math.round(value.allocated / value.capacity * 100) || 0;
+ value.capacity = wok.changetoProperUnit(value.capacity,1);
+ value.allocated = wok.changetoProperUnit(value.allocated,1);
+ value.enableExt = value.type==="logical" ? "" : "hide-content";
+ if ('kimchi-iso' !== value.type) {
+ listHtml += wok.substitute(storageHtml, value);
+ }
+ });
+ if($('#storageGrid').hasClass('grid'))
+ $('#storageGrid').grid('destroy');
+ $('#storagepoolsList').html(listHtml);
+ if(wok.tabMode['storage'] === 'admin') {
+ $('.storage-button').attr('style','display');
+ } else {
+ $('.storage-allocate').addClass('storage-allocate-padding-user');
+ }
+ $('#storageGrid').grid({enableSorting: false});
+ $('input', $('.grid-control', '.storage')).on('keyup', function(){
+ $('#storageGrid').grid('filter', $(this).val());
+ });
+ kimchi.storageBindClick();
+ } else {
+ $('#storagepoolsList').html('');
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+}
+
+kimchi.storageBindClick = function() {
+
+ $('.inactive').each(function(index) {
+ if ('active' === $(this).data('state')) {
+ $(this).hide();
+ } else {
+ $(this).show();
+ }
+ });
+
+ $('.list-storage .storage-state .active').each(function(index) {
+ if ('active' === $(this).data('state')) {
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+
+ $('.pool-activate').each(function(index) {
+ if ('active' === $(this).data('stat')) {
+ $(this).hide();
+ } else {
+ $(this).show();
+ }
+ });
+
+ $('.pool-deactivate').each(function(index) {
+ if ('active' === $(this).data('stat')) {
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+
+ $('.pool-add-volume').each(function(index) {
+ var canAddVolume =
+ $(this).data('stat') === 'active' &&
+ $(this).data('type') !== 'iscsi' &&
+ $(this).data('type') !== 'scsi';
+ if(canAddVolume) {
+ $(this).show();
+ }
+ else {
+ $(this).hide();
+ }
+ });
+
+ if(wok.tabMode['storage'] === 'admin') {
+ $('.pool-delete').on('click', function(event) {
+ var $pool = $(this);
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHPOOL6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ var poolName = $pool.data('name');
+ kimchi.deleteStoragePool(poolName, function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+ });
+
+ $('.pool-activate').on('click', function(event) {
+ var poolName = $(this).data('name');
+ kimchi.changePoolState(poolName, 'activate', function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+
+ $('.pool-deactivate').on('click', function(event) {
+ var poolName = $(this).data('name');
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHPOOL6012M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ if (!$(this).data('persistent')) {
+ wok.confirm(settings, function() {
+ kimchi.changePoolState(poolName, 'deactivate', function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ return false;
+ });
+ }
+ else {
+ kimchi.changePoolState(poolName, 'deactivate', function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }
+ });
+
+ $('.pool-add-volume').on('click', function(event) {
+ var poolName = $(this).data('name');
+ kimchi.selectedSP = poolName;
+ wok.window.open('plugins/kimchi/storagepool-add-volume.html');
+ });
+
+ $('.storage-action').on('click', function() {
+ var storage_action = $(this);
+ var deleteButton = storage_action.find('.pool-delete');
+ if ('active' === deleteButton.data('stat')) {
+ deleteButton.attr('disabled', 'disabled');
+ } else {
+ deleteButton.removeAttr('disabled');
+ }
+ });
+
+ $('.pool-extend').on('click', function() {
+ $("#logicalPoolExtend").dialog("option", "poolName", $(this).data('name'));
+ $("#logicalPoolExtend").dialog("open");
+ });
+ }
+
+ $('.row').on('click', function(event) {
+ if (!$(event.target).parents().hasClass('bottom')) {
+ if ($(this).data('stat') === 'active') {
+ var that = $(this);
+ var volumeDiv = $('#volume' + that.data('name'));
+ var slide = $('.volumes', this);
+ if (that.hasClass('in')) {
+ that.css('height','auto');
+ kimchi.doListVolumes(that);
+ } else {
+ slide.slideUp('slow', function(){
+ that.css('height','');
+ });
+ that.addClass('in');
+ kimchi.changeArrow($('.arrow-up', this));
+ }
+ }
+ }
+ });
+}
+
+kimchi._generateVolumeHTML = function(volume) {
+ if(volume['type'] === 'kimchi-iso') {
+ return '';
+ }
+ var volumeHtml = $('#volumeTmpl').html();
+ volume.capacity = wok.changetoProperUnit(volume.capacity,1);
+ volume.allocation = wok.changetoProperUnit(volume.allocation,1);
+ return wok.substitute(volumeHtml, volume);
+};
+
+kimchi.doListVolumes = function(poolObj) {
+ var poolName = poolObj.data('name')
+
+ var getOngoingVolumes = function() {
+ var result = {}
+ var filter = 'status=running&target_uri=' + encodeURIComponent('^/plugins/kimchi/storagepools/' + poolName + '/*')
+ kimchi.getTasksByFilter(filter, function(tasks) {
+ for(var i = 0; i < tasks.length; i++) {
+ var volumeName = tasks[i].target_uri.split('/').pop();
+ result[volumeName] = tasks[i];
+
+ if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
+ continue;
+ }
+
+ kimchi.trackTask(tasks[i].id, function(result) {
+ wok.topic('kimchi/volumeTransferFinished').publish(result);
+ }, function(result) {
+ wok.topic('kimchi/volumeTransferError').publish(result);
+ }, function(result) {
+ wok.topic('kimchi/volumeTransferProgress').publish(result);
+ });
+ }
+ }, null, true);
+ return result;
+ };
+
+ var volumeDiv = $('#volume' + poolName);
+ $(volumeDiv).empty();
+ var slide = $('.volumes', poolObj);
+ var handleArrow = $('.arrow-down', poolObj);
+
+ kimchi.listStorageVolumes(poolName, function(result) {
+ var listHtml = '';
+ var ongoingVolumes = [];
+ var ongoingVolumesMap = getOngoingVolumes();
+ $.each(ongoingVolumesMap, function(volumeName, task) {
+ ongoingVolumes.push(volumeName)
+ var volume = {
+ poolName: poolName,
+ used_by: [],
+ capacity: 0,
+ name: volumeName,
+ format: '',
+ bootable: null,
+ os_distro: '',
+ allocation: 0,
+ os_version: '',
+ path: '',
+ type: 'file'
+ };
+ listHtml += kimchi._generateVolumeHTML(volume);
+ });
+
+ $.each(result, function(index, value) {
+ if (ongoingVolumes.indexOf(value.name) == -1) {
+ value.poolname = poolName;
+ listHtml += kimchi._generateVolumeHTML(value);
+ }
+ });
+
+ if (listHtml.length > 0) {
+ volumeDiv.html(listHtml);
+ } else {
+ volumeDiv.html("<div class='pool-empty'>" + i18n['KCHPOOL6002M'] + "</div>");
+ }
+
+ $.each(ongoingVolumesMap, function(volumeName, task) {
+ wok.topic('kimchi/volumeTransferProgress').publish(task);
+ });
+
+ poolObj.removeClass('in');
+ kimchi.changeArrow(handleArrow);
+ slide.slideDown('slow');
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+}
+
+kimchi.initLogicalPoolExtend = function() {
+ $("#logicalPoolExtend").dialog({
+ autoOpen : false,
+ modal : true,
+ width : 600,
+ resizable : false,
+ closeText: "X",
+ open : function(){
+ $('#loading-info', '#logicalPoolExtend').removeClass('hidden');
+ $(".ui-dialog-titlebar-close", $("#logicalPoolExtend").parent()).removeAttr("title");
+ kimchi.listHostPartitions(function(data) {
+ $('#loading-info', '#logicalPoolExtend').addClass('hidden');
+ if (data.length > 0) {
+ for(var i=0;i<data.length;i++){
+ if (data[i].type === 'part' || data[i].type === 'disk') {
+ $('.host-partition', '#logicalPoolExtend').append(wok.substitute($('#logicalPoolExtendTmpl').html(), data[i]));
+ }
+ }
+ } else {
+ $('.host-partition').html(i18n['KCHPOOL6011M']);
+ $('.host-partition').addClass('text-help');
+ }
+ }, function(err) {
+ $('#loading-info', '#logicalPoolExtend').addClass('hidden');
+ $('.host-partition').html(i18n['KCHPOOL6013M'] + '<br/>(' + err.responseJSON.reason + ')');
+ $('.host-partition').addClass('text-help');
+ });
+ },
+ beforeClose : function() { $('.host-partition', '#logicalPoolExtend').empty(); },
+ buttons : [{
+ class: "ui-button-primary",
+ text: i18n.KCHAPI6007M,
+ click: function(){
+ var devicePaths = [];
+ $("input[type='checkbox']:checked", "#logicalPoolExtend").each(function(){
+ devicePaths.push($(this).prop('value'));
+ })
+ kimchi.updateStoragePool($("#logicalPoolExtend").dialog("option", "poolName"),{disks: devicePaths},function(data){
+ var item = $("#"+$("#logicalPoolExtend").dialog("option", "poolName"));
+ $(".usage", $(".storage-name", item)).text((Math.round(data.allocated/data.capacity*100)||0)+"%");
+ $(".storage-text", $(".storage-capacity", item)).text(wok.changetoProperUnit(data.capacity,1));
+ $(".storage-text", $(".storage-allocate", item)).text(wok.changetoProperUnit(data.allocated,1));
+ });
+ $(this).dialog("close");
+ }
+ }]
+ });
+}
+
+kimchi.storage_main = function() {
+ if(wok.tabMode['storage'] === 'admin') {
+ $('.tools').attr('style','display');
+ $('#storage-pool-add').on('click', function() {
+ wok.window.open('plugins/kimchi/storagepool-add.html');
+ });
+ $('.list-title .title-actions').attr('style','display');
+ }
+ kimchi.doListStoragePools();
+ kimchi.initLogicalPoolExtend();
+
+ wok.topic('kimchi/storageVolumeAdded').subscribe(function() {
+ pool = kimchi.selectedSP;
+ var poolNode = $('.storage-li[data-name="' + pool + '"]');
+ kimchi.doListVolumes(poolNode);
+ });
+
+ wok.topic('kimchi/volumeTransferProgress').subscribe(function(result) {
+ var extractProgressData = function(data) {
+ var sizeArray = /(\d+)\/(\d+)/g.exec(data) || [0, 0, 0];
+ var downloaded = sizeArray[1];
+ var percent = 0;
+ if(downloaded) {
+ var total = sizeArray[2];
+ if(!isNaN(total)) {
+ percent = downloaded / total * 100;
+ }
+ }
+ var formatted = wok.formatMeasurement(downloaded);
+ var size = (1.0 * formatted['v']).toFixed(1) + formatted['s'];
+ return {
+ size: size,
+ percent: percent
+ };
+ };
+
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ var progress = extractProgressData(result['message']);
+ var size = progress['size'];
+ var percent = progress['percent'];
+
+ volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
+ $('.progress-bar-inner', volumeBox).css({
+ width: percent + '%'
+ });
+ $('.progress-transferred', volumeBox).text(size);
+ $('.volume-progress', volumeBox).removeClass('hidden');
+ $('.progress-status', volumeBox).text(i18n['KCHPOOL6014M']);
+ });
+
+ wok.topic('kimchi/volumeTransferFinished').subscribe(function(result) {
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ var volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
+ $('.volume-progress', volumeBox).addClass('hidden');
+ kimchi.getStoragePoolVolume(poolName, volumeName, function(volume) {
+ var html = kimchi._generateVolumeHTML(volume);
+ $(volumeBox).replaceWith(html);
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+
+ wok.topic('kimchi/volumeTransferError').subscribe(function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ volumeBox = $('#volume' + poolName + ' [data-volume-name="' + volumeName + '"]');
+ $('.progress-status', volumeBox).text(i18n['KCHPOOL6015M']);
+ });
+};
+
+kimchi.changeArrow = function(obj) {
+ if ($(obj).hasClass('arrow-down')) {
+ $(obj).removeClass('arrow-down').addClass('arrow-up');
+ } else {
+ $(obj).removeClass('arrow-up').addClass('arrow-down');
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
new file mode 100644
index 0000000..8c27539
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
@@ -0,0 +1,414 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+kimchi.storagepool_add_main = function() {
+ kimchi.initStorageAddPage();
+ $('#form-pool-add').on('submit', kimchi.addPool);
+ $('#pool-doAdd').on('click', kimchi.addPool);
+ // 'pool-doAdd' button starts as disabled.
+ $("#pool-doAdd").attr("disabled", true);
+ // Make any change in the form fields enables the
+ // 'pool-doAdd' button if all the visible form
+ // fields are filled, disables it otherwise.
+ $('#form-pool-add').on('input change propertychange', function() {
+ if (!kimchi.inputsNotBlank())
+ $("#pool-doAdd").attr("disabled", true);
+ else
+ $("#pool-doAdd").attr("disabled", false);
+ });
+};
+
+kimchi.storageFilterSelect = function(id, isUpdate) {
+ var input = $('input', '#'+id);
+ var options = $(".option", '#'+id);
+ var filter = function(container, key){
+ container.children().each(function(){
+ $(this).css("display", $(this).text().indexOf(key)==-1 ? "none" : "");
+ });
+ };
+ if(!isUpdate){
+ input.on("keyup", function(){
+ filter(options, input.val());
+ });
+ }
+ options.children().each(function(){
+ $(this).click(function(){
+ options.children().removeClass("active");
+ input.val($(this).text());
+ input.trigger("change");
+ $(this).addClass("active");
+ filter(options, "");
+ });
+ });
+};
+
+kimchi.setupISCSI = function(){
+ var loadTargets = function(server, port, callback){
+ var isUpdate = $(".option", "#iSCSITarget").children().length > 0;
+ $(".option", "#iSCSITarget").empty();
+ $('input', "#iSCSITarget").attr("placeholder", i18n['KCHPOOL6006M']);
+ kimchi.getISCSITargets(server, port, function(data){
+ if(data.length==0){
+ $('input', "#iSCSITarget").attr("placeholder", i18n['KCHPOOL6007M']);
+ }else{
+ for(var i=0; i<data.length; i++){
+ var itemNode = $.parseHTML("<li>"+data[i].target+"</li>");
+ $(".option", "#iSCSITarget").append(itemNode);
+ }
+ $('input', "#iSCSITarget").attr("placeholder", "");
+ $(".popover", "#iSCSITarget").css("display", "block");
+ }
+ kimchi.storageFilterSelect('iSCSITarget', isUpdate);
+ $('input', "#iSCSITarget").trigger("focus");
+ callback();
+ }, function(data){
+ $('input', "#iSCSITarget").attr("placeholder", i18n['KCHPOOL6008M']);
+ callback();
+ wok.message.error(data.responseJSON.reason);
+ });
+ };
+ var triggerLoadTarget = function(){
+ $('input', "#iSCSITarget").val("");
+ var server = $("#iscsiserverId").val().trim();
+ var port = $("#iscsiportId").val().trim();
+ if(server!="" && !$("#iscsiserverId").hasClass("invalid-field") && !$("#iscsiportId").hasClass("invalid-field")){
+ $("#iscsiserverId").attr("disabled", true);
+ $("#iscsiportId").attr("disabled", true);
+ loadTargets(server, port, function(){
+ $("#iscsiserverId").attr("disabled", false);
+ $("#iscsiportId").attr("disabled", false);
+ });
+ }
+ };
+ $("#iscsiserverId").change(function(){
+ $('input', "#iSCSITarget").off('focus', triggerLoadTarget);
+ $('input', "#iSCSITarget").one('focus', triggerLoadTarget);
+ });
+ $("#iscsiportId").change(function(){
+ $('input', "#iSCSITarget").off('focus', triggerLoadTarget);
+ $('input', "#iSCSITarget").one('focus', triggerLoadTarget);
+ });
+ var initISCSIServers = function(){
+ kimchi.getStorageServers("iscsi", function(data){
+ for(var i=0;i<data.length;i++){
+ var itemNode = $.parseHTML("<li>"+data[i].host+"</li>");
+ $(".option", "#iSCSIServer").append(itemNode);
+ $(itemNode).click(function(){
+ $("#iscsiportId").val($(this).prop("port"));
+ $("#iscsiserverId").val($(this).text());
+ triggerLoadTarget();
+ }).prop("port", data[i].port);
+ }
+ kimchi.storageFilterSelect('iSCSIServer', false);
+ });
+ };
+ initISCSIServers();
+};
+
+kimchi.initStorageAddPage = function() {
+ kimchi.listHostPartitions(function(data) {
+ if (data.length > 0) {
+ var deviceHtml = $('#partitionTmpl').html();
+ var listHtml = '';
+ valid_types = ['part', 'disk', 'mpath'];
+ $.each(data, function(index, value) {
+ if (valid_types.indexOf(value.type) != -1) {
+ listHtml += wok.substitute(deviceHtml, value);
+ }
+ });
+ $('.host-partition', '#form-pool-add').html(listHtml);
+ } else {
+ $('.host-partition').html(i18n['KCHPOOL6011M']);
+ $('.host-partition').addClass('text-help');
+ }
+ }, function(err) {
+ $('.host-partition').html(i18n['KCHPOOL6013M'] + '<br/>(' + err.responseJSON.reason + ')');
+ $('.host-partition').addClass('text-help');
+ });
+
+ kimchi.getHostFCDevices(function(data){
+ if(data.length>0){
+ for(var i=0;i<data.length;i++){
+ data[i].label = data[i].name;
+ data[i].value = data[i].name;
+ }
+ $('#scsiAdapter').selectMenu();
+ $("input", "#scsiAdapter").val(data[0].name);
+ $('#scsiAdapter').selectMenu("setData", data);
+ } else {
+ $('#scsiAdapter').html(i18n['KCHPOOL6005M']);
+ $('#scsiAdapter').addClass('text-help');
+ }
+ });
+
+ $('#poolTypeId').selectMenu();
+ $('#serverComboboxId').combobox();
+ $('#targetFilterSelectId').filterselect();
+ var options = [ {
+ label : "DIR",
+ value : "dir"
+ }, {
+ label : "NFS",
+ value : "netfs"
+ }, {
+ label : "iSCSI",
+ value : "iscsi"
+ }, {
+ label : "LOGICAL",
+ value : "logical"
+ }, {
+ label : i18n.KCHPOOL6004M,
+ value : "scsi"
+ } ];
+ $('#poolTypeId').selectMenu("setData", options);
+
+ kimchi.getStorageServers('netfs', function(data) {
+ var serverContent = [];
+ if (data.length > 0) {
+ $.each(data, function(index, value) {
+ serverContent.push({
+ label : value.host,
+ value : value.host
+ });
+ });
+ }
+ $('#serverComboboxId').combobox("setData", serverContent);
+ $('input[name=nfsServerType]').change(function() {
+ if ($(this).val() === 'input') {
+ $('#nfsServerInputDiv').removeClass('tmpl-html');
+ $('#nfsServerChooseDiv').addClass('tmpl-html');
+ } else {
+ $('#nfsServerInputDiv').addClass('tmpl-html');
+ $('#nfsServerChooseDiv').removeClass('tmpl-html');
+ }
+ });
+ $('#nfsserverId').on("change keyup",function() {
+ if ($(this).val() !== '' && wok.isServer($(this).val())) {
+ $('#nfspathId').prop('disabled',false);
+ $(this).removeClass("invalid-field");
+ } else {
+ $(this).addClass("invalid-field");
+ $('#nfspathId').prop( "disabled",true);
+ }
+ $('#targetFilterSelectId').filterselect('clear');
+ });
+ $('#nfspathId').focus(function() {
+ var targetContent = [];
+ kimchi.getStorageTargets($('#nfsserverId').val(), 'netfs', function(data) {
+ if (data.length > 0) {
+ $.each(data, function(index, value) {
+ targetContent.push({
+ label : value.target,
+ value : value.target
+ });
+ });
+ }
+ $('#targetFilterSelectId').filterselect("setData", targetContent);
+ });
+ });
+ });
+
+ $('#poolTypeInputId').change(function() {
+ var poolObject = {'dir': ".path-section", 'netfs': '.nfs-section',
+ 'iscsi': '.iscsi-section', 'scsi': '.scsi-section',
+ 'logical': '.logical-section'}
+ var selectType = $(this).val();
+ $.each(poolObject, function(type, value) {
+ if(selectType == type){
+ $(value).removeClass('tmpl-html');
+ } else {
+ $(value).addClass('tmpl-html');
+ }
+ });
+ });
+ $('#authId').click(function() {
+ if ($(this).prop("checked")) {
+ $('.authenticationfield').removeClass('tmpl-html');
+ } else {
+ $('.authenticationfield').addClass('tmpl-html');
+ }
+ });
+ $('#iscsiportId').keyup(function(event) {
+ $(this).toggleClass("invalid-field",!/^[0-9]*$/.test($(this).val()));
+ });
+ $('#iscsiserverId').keyup(function(event) {
+ $(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
+ }).change(function(event) {
+ $(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
+ });
+ kimchi.setupISCSI();
+};
+
+/* Returns 'true' if all form fields were filled, 'false' if
+ * any field is left blank. The function takes into account
+ * the current poolType selected.
+ *
+ * Any 'field is blank' verification that were done in other
+ * validate functions were deleted, since we're doing it here
+ * already.
+ */
+kimchi.inputsNotBlank = function() {
+ if (!$('#poolId').val()) return false;
+ var poolType = $("#poolTypeInputId").val();
+ if (poolType === "dir") {
+ if (!$('#pathId').val()) return false;
+ } else if (poolType === "netfs") {
+ if (!$('#nfspathId').val()) return false;
+ if (!$('#nfsserverId').val()) return false;
+ } else if (poolType === "iscsi") {
+ if (!$('#iscsiserverId').val()) return false;
+ if (!$('#iscsiTargetId').val()) return false;
+ } else if (poolType === "logical") {
+ if ($("input[name=devices]:checked").length === 0)
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateForm = function() {
+ var poolType = $("#poolTypeInputId").val();
+ if (poolType === "dir") {
+ return kimchi.validateDirForm();
+ } else if (poolType === "netfs") {
+ return kimchi.validateNfsForm();
+ } else if (poolType === "iscsi") {
+ return kimchi.validateIscsiForm();
+ } else if (poolType === "logical") {
+ return kimchi.validateLogicalForm();
+ } else {
+ return true;
+ }
+};
+
+kimchi.validateDirForm = function () {
+ var path = $('#pathId').val();
+ if (!/(^\/.*)$/.test(path)) {
+ wok.message.error.code('KCHAPI6003E');
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateNfsForm = function () {
+ var nfspath = $('#nfspathId').val();
+ var nfsserver = $('#nfsserverId').val();
+ if (!kimchi.validateServer(nfsserver)) {
+ return false;
+ }
+ if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
+ wok.message.error.code('KCHPOOL6005E');
+ return false;
+ }
+ $('#nfs-mount-loading').removeClass('hidden');
+ return true;
+};
+
+kimchi.validateIscsiForm = function() {
+ var iscsiServer = $('#iscsiserverId').val();
+ var iscsiTarget = $('#iscsiTargetId').val();
+ if (!kimchi.validateServer(iscsiServer)) {
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateServer = function(serverField) {
+ if(!wok.isServer(serverField)) {
+ wok.message.error.code('KCHPOOL6009E');
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateLogicalForm = function () {
+ if ($("input[name=devices]:checked").length === 0) {
+ wok.message.error.code('KCHPOOL6006E');
+ return false;
+ } else {
+ return true;
+ }
+};
+
+kimchi.addPool = function(event) {
+ if (kimchi.validateForm()) {
+ var formData = $('#form-pool-add').serializeObject();
+ delete formData.authname;
+ var poolType = $('#poolTypeId').selectMenu('value');
+ if (poolType === 'dir') {
+ formData.path = $('#pathId').val();
+ } else if (poolType === 'logical') {
+ var source = {};
+ if (!$.isArray(formData.devices)) {
+ var deviceObj = [];
+ deviceObj[0] = formData.devices;
+ source.devices = deviceObj;
+ } else {
+ source.devices = formData.devices;
+ }
+ delete formData.devices;
+ formData.source = source;
+ } else if (poolType === 'netfs'){
+ var source = {};
+ source.path = $('#nfspathId').val();
+ source.host = $('#nfsserverId').val();
+ formData.source = source;
+ } else if (poolType === 'iscsi') {
+ var source = {};
+ source.target = $('#iscsiTargetId').val();
+ source.host = $('#iscsiserverId').val();
+ $('#iscsiportId').val() !== '' ? source.port = parseInt($('#iscsiportId').val()): null;
+ if ($('#authId').prop("checked")) {
+ source.auth = {
+ "username" : $('#usernameId').val(),
+ "password" : $('#passwordId').val()
+ };
+ }
+ formData.source = source;
+ } else if (poolType === 'scsi'){
+ formData.source = { adapter_name: $('#scsiAdapter').selectMenu('value') };
+ }
+ var storagePoolAddingFunc = function() {
+ $('input', '#form-pool-add').attr('disabled','disabled');
+ $('#pool-doAdd').hide();
+ $('#pool-loading').show();
+ kimchi.createStoragePool(formData, function() {
+ kimchi.doListStoragePools();
+ wok.window.close();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $('input', '#form-pool-add').removeAttr('disabled');
+ $('#pool-loading').hide();
+ $('#pool-doAdd').show();
+ });
+ };
+ if (poolType === 'logical') {
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHPOOL6003M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ storagePoolAddingFunc();
+ }, function() {
+ });
+ } else {
+ storagePoolAddingFunc();
+ }
+ }
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
new file mode 100644
index 0000000..8479ab2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
@@ -0,0 +1,179 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+kimchi.sp_add_volume_main = function() {
+ // download from remote server or upload from local file
+ var type = 'download';
+
+ var addButton = $('#sp-add-volume-button');
+ var remoteURLBox = $('#volume-remote-url');
+ var localFileBox = $('#volume-input-file');
+ var typeRadios = $('input.volume-type');
+
+ var isValidURL = function() {
+ var url = $(remoteURLBox).val();
+ return kimchi.template_check_url(url);
+ };
+
+ var isValidFile = function() {
+ var fileName = $(localFileBox).val();
+ return fileName.length > 0;
+ };
+
+ $(typeRadios).change(function(event) {
+ $('.volume-input').prop('disabled', true);
+ $('.volume-input.' + this.value).prop('disabled', false);
+ type = this.value;
+ if(type == 'download') {
+ $(addButton).prop('disabled', !isValidURL());
+ }
+ else {
+ $(addButton).prop('disabled', !isValidFile());
+ }
+ });
+
+ $(remoteURLBox).on('input propertychange', function(event) {
+ $(addButton).prop('disabled', !isValidURL());
+ });
+
+ $(localFileBox).on('change', function(event) {
+ $(addButton).prop('disabled', !isValidFile());
+ });
+
+ var onError = function(result) {
+ $(this).prop('disabled', false);
+ $(typeRadios).prop('disabled', false);
+ if(!result) {
+ return;
+ }
+ var msg = result['message'] || (
+ result['responseJSON'] && result['responseJSON']['reason']
+ );
+ wok.message.error(msg);
+ };
+
+ var fetchRemoteFile = function() {
+ var volumeURL = remoteURLBox.val();
+ var volumeName = volumeURL.split(/(\\|\/)/g).pop();
+ kimchi.downloadVolumeToSP({
+ sp: kimchi.selectedSP,
+ url: volumeURL
+ }, function(result) {
+ wok.window.close();
+ wok.topic('kimchi/storageVolumeAdded').publish();
+ }, onError);
+ };
+
+ var uploadFile = function() {
+ var chunkSize = 8 * 1024 * 1024; // 8MB
+ var uploaded = 0;
+
+ var blobFile = $(localFileBox)[0].files[0];
+
+ var createUploadVol = function() {
+ kimchi.createVolumeWithCapacity(kimchi.selectedSP, {
+ name: blobFile.name,
+ format: '',
+ capacity: blobFile.size,
+ upload: true
+ }, function(result) {
+ wok.window.close();
+ trackVolCreation(result.id);
+ }, onError);
+ };
+
+ var uploadRequest = function(blob) {
+ var fd = new FormData();
+ fd.append('chunk', blob);
+ fd.append('chunk_size', blob.size);
+
+ kimchi.uploadVolumeToSP(kimchi.selectedSP, blobFile.name, {
+ formData: fd
+ }, function(result) {
+ if (uploaded < blobFile.size)
+ setTimeout(doUpload, 500);
+ }, onError);
+
+ uploaded += blob.size
+ };
+
+ // Check file exists and has read permission
+ try {
+ var blob = blobFile.slice(0, 20);
+ var reader = new FileReader();
+ reader.onloadend = function(e) {
+ if (e.loaded == 0)
+ wok.message.error.code('KCHAPI6008E');
+ else
+ createUploadVol();
+ };
+
+ reader.readAsBinaryString(blob);
+ } catch (err) {
+ wok.message.error.code('KCHAPI6008E');
+ return;
+ }
+
+ var doUpload = function() {
+ try {
+ var blob = blobFile.slice(uploaded, uploaded + chunkSize);
+ var reader = new FileReader();
+ reader.onloadend = function(e) {
+ if (e.loaded == 0)
+ wok.message.error.code('KCHAPI6009E');
+ else
+ uploadRequest(blob);
+ };
+
+ reader.readAsBinaryString(blob);
+ } catch (err) {
+ wok.message.error.code('KCHAPI6009E');
+ return;
+ }
+ }
+
+ var trackVolCreation = function(taskid) {
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ var taskMsg = result['message'];
+ if (taskStatus == 'running') {
+ if (taskMsg != 'ready for upload') {
+ setTimeout(function() {
+ trackVolCreation(taskid);
+ }, 2000);
+ } else {
+ wok.topic('kimchi/storageVolumeAdded').publish();
+ doUpload();
+ }
+ }
+ };
+ kimchi.getTask(taskid, onTaskResponse, onError);
+ };
+ };
+
+ $(addButton).on('click', function(event) {
+ $(this).prop('disabled', true);
+ $(typeRadios).prop('disabled', true);
+ if(type === 'download') {
+ fetchRemoteFile();
+ }
+ else {
+ uploadFile();
+ }
+ event.preventDefault();
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
new file mode 100644
index 0000000..01a47c2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
@@ -0,0 +1,441 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.switchPage = function(fromPageId, toPageId, direction) {
+ direction = direction || 'left';
+ var toLeftBegin;
+ var fromLeftEnd;
+ if('left' === direction) {
+ toLeftBegin = '100%';
+ fromLeftEnd = '-100%';
+ } else if('right' === direction) {
+ toLeftBegin = '-100%';
+ fromLeftEnd = '100%';
+ }
+ var formPage = $('#'+fromPageId);
+ var toPage = $('#'+toPageId);
+ toPage.css({
+ left: toLeftBegin
+ });
+ formPage.animate({
+ left: fromLeftEnd,
+ opacity: 0.1
+ }, 400);
+ toPage.animate({
+ left: '0',
+ opacity: 1
+ }, 400);
+};
+
+kimchi.template_add_main = function() {
+ kimchi.deepScanHandler = null;
+ // 1-1 local iso
+ $('#iso-local').click(function() {
+ kimchi.switchPage('iso-type-box', 'iso-local-box');
+ initLocalIsoField();
+ initIsoFileField();
+ kimchi.listIsos(function(isos) {
+ if (isos && isos.length) {
+ showLocalIsoField(isos);
+ $('#iso-more').show();
+ } else {
+ $('#iso-search').show();
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+
+ $('#iso-local-box-back').click(function() {
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ kimchi.switchPage('iso-local-box', 'iso-type-box', 'right');
+ });
+
+ $('#iso-search').click(function() {
+ var settings = {
+ content : i18n['KCHTMPL6002M']
+ };
+ wok.confirm(settings, function() {
+ $('#iso-search').hide();
+ $('#iso-search-loading').show();
+ deepScan('#iso-search');
+ });
+ });
+
+ $('#iso-more').click(function() {
+ var settings = {
+ content : i18n['KCHTMPL6002M']
+ };
+ wok.confirm(settings, function() {
+ $('#iso-more').hide();
+ $('#iso-more-loading').show();
+ deepScan('#iso-more');
+ });
+ });
+
+ $('#iso-search-loading').click(function() {
+ $('#iso-search-loading').hide();
+ $('#iso-search').show();
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ });
+
+ $('#iso-more-loading').click(function() {
+ $('#iso-more-loading').hide();
+ $('#iso-more').show();
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ });
+
+ var deepScan = function(button) {
+ kimchi.deepScanHandler = kimchi.stepListDeepScanIsos(function(isos, isFinished) {
+ if (isos && isos.length) {
+ if(button === '#iso-search') {
+ $(button + '-loading').hide();
+ button = '#iso-more';
+ $(button + '-loading').show();
+ }
+ showLocalIsoField(isos);
+ } else {
+ if (isFinished) {
+ wok.message.warn(i18n['KCHTMPL6001W']);
+ }
+ }
+ if (isFinished) {
+ $(button + '-loading').hide();
+ $(button).show();
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $(button + '-loading').hide();
+ $(button).show();
+ });
+ };
+
+ //1-1-1 local iso list
+ var initLocalIsoField = function() {
+ kimchi.isoInfo = {};
+ $('#local-iso-field').hide();
+ $('#select-all-local-iso').prop('checked', false);
+ $('#btn-template-local-iso-create').attr('disabled', 'disabled');
+ $('#iso-search').hide();
+ $('#iso-more').hide();
+ $('#iso-search-loading').hide();
+ $('#iso-more-loading').hide();
+ $('#list-local-iso').empty();
+ };
+
+ var showLocalIsoField = function(isos) {
+ var html = '';
+ var template = $('#tmpl-list-local-iso').html();
+ $.each(isos, function(index, volume) {
+ var isoId = volume.os_distro + '*' + volume.name + '*' + volume.os_version;
+ if (!kimchi.isoInfo[isoId]) {
+ volume.isoId = isoId;
+ volume.capacity = wok.changetoProperUnit(volume.capacity, 1);
+ kimchi.isoInfo[isoId] = volume;
+ html += wok.substitute(template, volume);
+ }
+ });
+ $('#list-local-iso').append(html);
+ $('#local-iso-field').show();
+ };
+
+ $('#select-all-local-iso').click(function() {
+ $('#list-local-iso [type="checkbox"]').prop('checked', $(this).prop('checked'));
+ if ($(this).prop('checked')) {
+ $('#btn-template-local-iso-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-local-iso-create').attr('disabled', 'disabled');
+ }
+ });
+
+ $('#list-local-iso').on('click', '[type="checkbox"]', function() {
+ var checkedLength = $('#list-local-iso [type="checkbox"]:checked').length;
+ if (checkedLength) {
+ $('#btn-template-local-iso-create').removeAttr('disabled');
+ var length = $('#list-local-iso [type="checkbox"]').length;
+ $('#select-all-local-iso').prop('checked', length == checkedLength);
+ } else {
+ $('#select-all-local-iso').prop('checked', false);
+ $('#btn-template-local-iso-create').attr('disabled', 'disabled');
+ }
+ });
+
+ $('#btn-template-local-iso-create').click(function() {
+ submitIso('form-local-iso');
+ });
+
+ //1-1-2 local iso file
+ var initIsoFileField = function() {
+ $('#iso-file-check').prop('checked', false);
+ $('#iso-file-box').hide();
+ $('#iso-file').val('');
+ $('#btn-template-file-create').attr('disabled', 'disabled');
+ };
+
+ $('#iso-file-check').click(function() {
+ if ($(this).prop('checked')) {
+ $('#iso-file-box').slideDown();
+ } else {
+ $('#iso-file-box').slideUp();
+ }
+ });
+
+ $('#iso-file').on('input propertychange', function() {
+ if ($('#iso-file').val()) {
+ $('#btn-template-file-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-file-create').attr('disabled', 'disabled');
+ }
+ });
+
+ $('#btn-template-file-create').click(function() {
+ var isoFile = $('#iso-file').val();
+ if (!kimchi.template_check_path(isoFile)) {
+ wok.message.error.code('KCHAPI6003E');
+ return;
+ }
+ var data = {
+ "cdrom" : isoFile
+ };
+ addTemplate(data);
+ });
+
+ //1-2 remote iso
+ $('#iso-remote').css('opacity', 0.3).css('cursor', 'not-allowed');
+
+ var enabledRemoteIso = function() {
+ if (kimchi.capabilities == undefined) {
+ setTimeout(enabledRemoteIso, 2000);
+ return;
+ }
+
+ if (kimchi.capabilities.qemu_stream != true) {
+ return;
+ }
+
+ $('#iso-remote').css('opacity', 1).css('cursor', 'pointer');
+ $('#iso-remote').click(function() {
+ kimchi.switchPage('iso-type-box', 'iso-remote-box');
+ initRemoteIsoField();
+ initIsoUrlField();
+ kimchi.listDistros(function(isos) {
+ showRemoteIsoField(isos);
+ }, function() {
+ });
+ });
+ };
+ enabledRemoteIso();
+
+ $('#iso-remote-box-back').click(function() {
+ kimchi.switchPage('iso-remote-box', 'iso-type-box', 'right');
+ });
+
+ //1-2-1 remote iso list
+ var initRemoteIsoField = function() {
+ $('#load-remote-iso').show();
+ $('#remote-iso-field').hide();
+ $('#iso-url-field').hide();
+ $('#select-all-remote-iso').prop('checked', false);
+ $('#btn-template-remote-iso-create').attr('disabled', 'disabled');
+ };
+
+ var showRemoteIsoField = function(isos) {
+ if (isos && isos.length) {
+ kimchi.isoInfo = {};
+ var html = '';
+ var template = $('#tmpl-list-remote-iso').html();
+ $.each(isos, function(index, volume) {
+ var isoId = volume.os_distro + '*' + volume.name + '*' + volume.os_version;
+ if (!kimchi.isoInfo[isoId]) {
+ volume.isoId = isoId;
+ kimchi.isoInfo[isoId] = volume;
+ html += wok.substitute(template, volume);
+ }
+ });
+ $('#list-remote-iso').html(html);
+ $('#load-remote-iso').hide()
+ $('#remote-iso-field').show();
+ $('#iso-url-field').show();
+ } else {
+ $('#load-remote-iso').hide()
+ $('#iso-url-field').show();
+ wok.message.warn(i18n['KCHTMPL6001W']);
+ }
+ };
+
+ $('#select-all-remote-iso').click(function() {
+ $('#list-remote-iso [type="checkbox"]').prop('checked', $(this).prop('checked'));
+ if ($(this).prop('checked')) {
+ $('#btn-template-remote-iso-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-remote-iso-create').attr('disabled', 'disabled');
+ }
+ });
+
+ $('#list-remote-iso').on('click', '[type="checkbox"]', function() {
+ var checkedLength = $('#list-remote-iso [type="checkbox"]:checked').length;
+ if (checkedLength) {
+ $('#btn-template-remote-iso-create').removeAttr('disabled');
+ var length = $('#list-remote-iso [type="checkbox"]').length;
+ $('#select-all-remote-iso').prop('checked', length == checkedLength);
+ } else {
+ $('#select-all-remote-iso').prop('checked', false);
+ $('#btn-template-remote-iso-create').attr('disabled', 'disabled');
+ }
+ });
+
+ $('#btn-template-remote-iso-create').click(function() {
+ submitIso('form-remote-iso');
+ });
+
+ //1-2-2 remote iso url
+ var initIsoUrlField = function() {
+ $('#iso-url-check').prop('checked', false);
+ $('#iso-url-box').hide();
+ $('#iso-url').val('');
+ $('#btn-template-url-create').attr('disabled', 'disabled');
+ }
+
+ $('#iso-url-check').click(function() {
+ if ($(this).prop('checked')) {
+ $('#iso-url-box').slideDown();
+ } else {
+ $('#iso-url-box').slideUp();
+ }
+ });
+
+ $('#iso-url').on('input propertychange', function() {
+ if ($('#iso-url').val()) {
+ $('#btn-template-url-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-url-create').attr('disabled', 'disabled');
+ }
+ });
+
+ $('#vm-image-local').click(function(){
+ kimchi.switchPage('iso-type-box', 'vm-image-local-box');
+ });
+ $('#vm-image-local-box-back').click(function(){
+ kimchi.switchPage('vm-image-local-box', 'iso-type-box', 'right');
+ });
+ $('input', '#vm-image-local-box').on('keyup cut paste', function(){
+ setTimeout(function(){
+ var isValid = kimchi.template_check_path($('input', '#vm-image-local-box').val());
+ $('input', '#vm-image-local-box').toggleClass('invalid-field', !isValid);
+ $('button', $('.body', '#vm-image-local-box')).button(isValid ? "enable" : "disable");
+ }, 0);
+ });
+ $('button', $('.body', '#vm-image-local-box')).button({
+ disabled: true
+ }).click(function(){
+ $('input', '#vm-image-local-box').prop('disabled', true);
+ $(this).button('option', {
+ label: i18n['KCHAPI6008M'],
+ disabled: true
+ });
+ addTemplate({disks:[{base:$('input', '#vm-image-local-box').val()}]}, function(){
+ $('input', '#vm-image-local-box').prop('disabled', false);
+ $('button', $('.body', '#vm-image-local-box')).button('option', {
+ label: i18n['KCHAPI6005M'],
+ disabled: false
+ });
+ });
+ });
+
+ $('#btn-template-url-create').click(function() {
+ var isoUrl = $('#iso-url').val();
+ if (!kimchi.template_check_url(isoUrl)) {
+ wok.message.error.code('KCHAPI6004E');
+ return;
+ }
+ var data = {
+ "cdrom" : isoUrl
+ };
+ addTemplate(data);
+ });
+
+ //do create
+ var addTemplate = function(data, callback) {
+ kimchi.createTemplate(data, function() {
+ if(callback) callback();
+ kimchi.doListTemplates();
+ wok.window.close();
+ wok.topic('templateCreated').publish();
+ }, function(err) {
+ if(callback) callback();
+ wok.message.error(err.responseJSON.reason);
+ });
+ };
+
+ var submitIso = function(formId) {
+ var formData = $('#' + formId).serializeObject();
+ if (formData.iso) {
+ var length = 0;
+ var successNum = 0;
+ var addTemplate = function(isoInfo) {
+ var data = {
+ "os_distro" : isoInfo.os_distro,
+ "os_version" : isoInfo.os_version,
+ "cdrom" : isoInfo.path
+ };
+ kimchi.createTemplate(data, function() {
+ successNum++;
+ $('input[value="' + isoInfo.isoId + '"]').prop('checked', false);
+ $('.check-all>input').prop('checked', false);
+ kimchi.doListTemplates();
+ wok.topic('templateCreated').publish(data);
+ if (successNum === length) {
+ wok.window.close();
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ };
+ if (formData.iso instanceof Array) {
+ length = formData.iso.length;
+ $.each(formData.iso, function(index, value) {
+ addTemplate(kimchi.isoInfo[value]);
+ });
+ } else {
+ length = 1;
+ addTemplate(kimchi.isoInfo[formData.iso]);
+ }
+ }
+ };
+};
+
+kimchi.template_check_url = function(url) {
+ var reg = /(https|http|ftp|ftps|tftp):\/\//;
+ if (url.constructor === String) {
+ return reg.test(url);
+ }
+ return false;
+};
+
+kimchi.template_check_path = function(filePath) {
+ var reg = /((\/([0-9a-zA-Z-_ \.]+))+)$/;
+ if (filePath.constructor === String) {
+ return reg.test(filePath);
+ }
+ return false;
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
new file mode 100644
index 0000000..d40b6c7
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
@@ -0,0 +1,343 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.template_edit_main = function() {
+ var templateEditMain = $('#edit-template-tabs');
+ var origDisks;
+ var origPool;
+ var origNetworks;
+ var templateDiskSize;
+ $('#template-name', templateEditMain).val(kimchi.selectedTemplate);
+ templateEditMain.tabs();
+
+ var initTemplate = function(template) {
+ origDisks = template.disks;
+ origPool = template.storagepool;
+ origNetworks = template.networks;
+ for(var i=0;i<template.disks.length;i++){
+ if(template.disks[i].base){
+ template["vm-image"] = template.disks[i].base;
+ $('.templ-edit-cdrom').addClass('hide');
+ $('.templ-edit-vm-image').removeClass('hide');
+ break;
+ }
+ }
+ for ( var prop in template) {
+ var value = template[prop];
+ if (prop == 'graphics') {
+ value = value["type"];
+ }
+ $('input[name="' + prop + '"]', templateEditMain).val(value);
+ }
+
+ var vncOpt = [{label: 'VNC', value: 'vnc'}];
+ $('#template-edit-graphics').append('<option selected>VNC</option>');
+ $('#template-edit-graphics').append('<option>Spice</option>');
+ wok.select('template-edit-graphics-list', vncOpt);
+ var enableSpice = function() {
+ if (kimchi.capabilities == undefined) {
+ setTimeout(enableSpice, 2000);
+ return;
+ }
+ if (kimchi.capabilities.qemu_spice == true) {
+ spiceOpt = [{label: 'Spice', value: 'spice'}]
+ wok.select('template-edit-graphics-list', spiceOpt);
+ }
+ };
+ enableSpice();
+ var initStorage = function(result) {
+ var scsipools = {};
+ var addStorageItem = function(storageData) {
+ var thisName = storageData.storageName;
+ var nodeStorage = $.parseHTML(wok.substitute($('#template-storage-pool-tmpl').html(), storageData));
+ $('.template-tab-body', '#form-template-storage').append(nodeStorage);
+ var storageOptions = '';
+ var scsiOptions = '';
+ $('#selectStorageName').find('option').remove();
+ $.each(result, function(index, storageEntities) {
+ if((storageEntities.state === 'active') && (storageEntities.type != 'kimchi-iso')) {
+ if(storageEntities.type === 'iscsi' || storageEntities.type === 'scsi') {
+ kimchi.listStorageVolumes(storageEntities.name, function(currentVolume) {
+ $.each(currentVolume, function(indexSCSI, scsiEntities) {
+ var tmpPath = storageEntities.name + '/' + scsiEntities.name;
+ var isSlected = tmpPath === thisName ? ' selected' : '';
+ scsiOptions += '<option' + isSlected + '>' + tmpPath + '</option>';
+ });
+ $('#selectStorageName').append(scsiOptions);
+ }, function() {});
+ } else {
+ var isSlected = storageEntities.name === thisName ? ' selected' : '';
+ storageOptions += '<option' + isSlected + '>' + storageEntities.name + '</option>';
+ }
+ }
+ });
+ $('#selectStorageName').append(storageOptions);
+
+ // Set disk format
+ $('#diskFormat').val(storageData.storageDiskFormat);
+ $('#diskFormat').on('change', function() {
+ $('.template-storage-disk-format').val($(this).val());
+ });
+
+ $('#selectStorageName').change(function() {
+ var selectedItem = $(this).parent().parent();
+ var tempStorageNameFull = $(this).val();
+ var tempName = tempStorageNameFull.split('/');
+ var tempStorageName = tempName[0];
+ $('.template-storage-name').val(tempStorageNameFull);
+ kimchi.getStoragePool(tempStorageName, function(info) {
+ tempType = info.type;
+ selectedItem.find('.template-storage-type').val(tempType);
+ if (tempType === 'iscsi' || tempType === 'scsi') {
+ kimchi.getStoragePoolVolume(tempStorageName, tempName[tempName.length-1], function(info) {
+ volSize = info.capacity / Math.pow(1024, 3);
+ $('.template-storage-disk', selectedItem).attr('readonly', true).val(volSize);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled', true).change();
+ });
+ } else if (tempType === 'logical') {
+ $('.template-storage-disk', selectedItem).attr('readonly', false);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled', true).change();
+ } else {
+ $('.template-storage-disk', selectedItem).attr('readonly', false);
+ if ($('#diskFormat').prop('disabled') == true) {
+ $('#diskFormat').val('qcow2');
+ $('#diskFormat').prop('disabled', false).change();
+ }
+ }
+ });
+ });
+ };
+
+ if ((origDisks && origDisks.length) && (origPool && origPool.length)) {
+ splitPool = origPool.split('/');
+ var defaultPool = splitPool[splitPool.length-1];
+ var defaultType;
+
+ kimchi.getStoragePool(defaultPool, function(info) {
+ defaultType = info.type;
+ $.each(origDisks, function(index, diskEntities) {
+ var storageNodeData = {
+ viewMode : '',
+ editMode : 'hide',
+ storageName : defaultPool,
+ storageType : defaultType,
+ storageDisk : diskEntities.size,
+ storageDiskFormat : diskEntities.format ? diskEntities.format : 'qcow2'
+ }
+
+ if (diskEntities.volume) {
+ kimchi.getStoragePoolVolume(defaultPool, diskEntities.volume, function(info) {
+ var volSize = info.capacity / Math.pow(1024, 3);
+ var nodeData = storageNodeData
+ nodeData.storageName = defaultPool + '/' + diskEntities.volume;
+ nodeData.storageDisk = volSize;
+ addStorageItem(nodeData);
+ $('.template-storage-disk').attr('readonly', true);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled', true).change();
+ });
+ } else if (defaultType === 'logical') {
+ addStorageItem(storageNodeData);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled', true).change();
+ } else {
+ addStorageItem(storageNodeData);
+ }
+ });
+ });
+ }
+
+ $('#template-edit-storage-add-button').button({
+ icons: {
+ primary: "ui-icon-plusthick"
+ },
+ text: false,
+ disabled: true
+ }).click(function(event) {
+ event.preventDefault();
+ var storageNodeData = {
+ viewMode : 'hide',
+ editMode : '',
+ storageName : 'null',
+ storageType : 'dir',
+ storageDisk : '10'
+ }
+ addStorageItem(storageNodeData);
+ });
+ };
+ var initInterface = function(result) {
+ var networkItemNum = 0;
+ var addInterfaceItem = function(networkData) {
+ var networkName = networkData.networkV;
+ var nodeInterface = $.parseHTML(wok.substitute($('#template-interface-tmpl').html(), networkData));
+ $('.template-tab-body', '#form-template-interface').append(nodeInterface);
+ $('.delete', '#form-template-interface').button({
+ icons : {primary : 'ui-icon-trash'},
+ text : false
+ }).click(function(evt) {
+ evt.preventDefault();
+ $(this).parent().parent().remove();
+ });
+ var networkOptions = '';
+ for(var i=0;i<result.length;i++){
+ if(result[i].state === "active") {
+ var isSlected = networkName===result[i].name ? ' selected' : '';
+ networkOptions += '<option' + isSlected + '>' + result[i].name + '</option>';
+ }
+ }
+ $('select', '#form-template-interface #networkID' + networkItemNum).append(networkOptions);
+ networkItemNum += 1;
+ };
+ if(result && result.length > 0) {
+ for(var i=0;i<origNetworks.length;i++) {
+ addInterfaceItem({
+ networkID : 'networkID' + networkItemNum,
+ networkV : origNetworks[i],
+ type : 'network'
+ });
+ }
+ }
+ $('#template-edit-interface-add-button').button({
+ icons: {
+ primary: 'ui-icon-plusthick'
+ },
+ text: false
+ }).click(function(evt) {
+ evt.preventDefault();
+ addInterfaceItem({
+ networkID : 'networkID' + networkItemNum,
+ networkV : 'default',
+ type : 'network'
+ });
+ });
+ };
+ var initProcessor = function(){
+ var setCPUValue = function(){
+ if(!$('#cores').hasClass("invalid-field")&&$('#cores').val()!=""){
+ $("#cpus").val(parseInt($("#cores").val())*parseInt($("#threads").val()));
+ }else{
+ $("#cpus").val('');
+ }
+ };
+ $("input:text", "#form-template-processor").on('keyup', function(){
+ $(this).toggleClass("invalid-field", !$(this).val().match('^[0-9]*$'));
+ if($(this).prop('id')=='cores') setCPUValue();
+ });
+ $("input:checkbox", "#form-template-processor").click(function(){
+ $(".topology", "#form-template-processor").toggleClass("hide", !$(this).prop("checked"));
+ $("#cpus").attr("disabled", $(this).prop("checked"));
+ setCPUValue();
+ });
+ $('select', '#form-template-processor').change(function(){
+ setCPUValue();
+ });
+ kimchi.getCPUInfo(function(data){
+ var options = "";
+ for(var i=0;Math.pow(2,i)<=data.threads_per_core;i++){
+ var lastOne = Math.pow(2,i+1)>data.threads_per_core?" selected":"";
+ options += "<option"+lastOne+">"+Math.pow(2,i)+"</option>";
+ }
+ $('select', '#form-template-processor').append(options);
+ if(template.cpus) $("#cpus").val(template.cpus);
+ var topo = template.cpu_info.topology;
+ if(topo&&topo.cores) $("#cores").val(topo.cores);
+ if(topo&&topo.threads){
+ $('select', '#form-template-processor').val(topo.threads);
+ $("input:checkbox", "#form-template-processor").trigger('click');
+ }
+ });
+ };
+ kimchi.listNetworks(initInterface);
+ kimchi.listStoragePools(initStorage);
+ initProcessor();
+ };
+ kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
+
+
+ $('#tmpl-edit-button-save').on('click', function() {
+ var editableFields = [ 'name', 'memory', 'disks', 'graphics'];
+ var data = {};
+ //Fix me: Only support one storage pool now
+ var storages = $('.template-tab-body .item', '#form-template-storage');
+ var tempName = $('.template-storage-name', storages).val();
+ var tmpItem = $('#form-template-storage .item');
+ tempName = tempName.split('/');
+ var tempNameHead = tempName[0];
+ var tempNameTail = tempNameHead;
+ if($('.template-storage-type', tmpItem).val() === 'iscsi' || $('.template-storage-type', tmpItem).val() == 'scsi') {
+ tempNameTail = tempName[tempName.length-1];
+ }
+ tempName = '/plugins/kimchi/storagepools/' + tempNameHead;
+ data['storagepool'] = tempName;
+ $.each(editableFields, function(i, field) {
+ /* Support only 1 disk at this moment */
+ if (field == 'disks') {
+ if($('.template-storage-type', tmpItem).val() === 'iscsi' || $('.template-storage-type', tmpItem).val() == 'scsi') {
+ origDisks[0]['size'] && delete origDisks[0]['size'];
+ origDisks[0]['volume'] = tempNameTail;
+ } else {
+ origDisks[0]['volume'] && delete origDisks[0]['volume'];
+ origDisks[0].size = Number($('.template-storage-disk', tmpItem).val());
+ }
+ origDisks[0].format = $('.template-storage-disk-format', tmpItem).val();
+ data[field] = origDisks;
+ }
+ else if (field == 'graphics') {
+ var type = $('#form-template-general [name="' + field + '"]').val();
+ data[field] = {'type': type};
+ }
+ else {
+ data[field] = $('#form-template-general [name="' + field + '"]').val();
+ }
+ });
+ data['memory'] = Number(data['memory']);
+ data['cpus'] = parseInt($('#cpus').val());
+ if($("input:checkbox", "#form-template-processor").prop("checked")){
+ data['cpu_info'] = {
+ topology: {
+ sockets: 1,
+ cores: parseInt($("#cores").val()),
+ threads: parseInt($("#threads").val())
+ }
+ };
+ }else{
+ data['cpu_info'] = {};
+ }
+ var networks = $('.template-tab-body .item', '#form-template-interface');
+ var networkForUpdate = new Array();
+ $.each(networks, function(index, networkEntities) {
+ var thisValue = $('select', networkEntities).val();
+ networkForUpdate.push(thisValue);
+ });
+ if (networkForUpdate instanceof Array) {
+ data.networks = networkForUpdate;
+ } else if (networkForUpdate != null) {
+ data.networks = [networkForUpdate];
+ } else {
+ data.networks = [];
+ }
+
+ kimchi.updateTemplate($('#template-name').val(), data, function() {
+ kimchi.doListTemplates();
+ wok.window.close();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js
new file mode 100644
index 0000000..b09fe12
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js
@@ -0,0 +1,111 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.doListTemplates = function() {
+ kimchi.listTemplates(function(result) {
+ if (result && result.length) {
+ $('#noTemplates').hide();
+ var listHtml = '';
+ var templateHtml = $('#templateTmpl').html();
+ $.each(result, function(index, value) {
+ var isLocal;
+ if(value.cdrom){
+ isLocal = /^\//.test(value['cdrom']);
+ }else{
+ for(var i=0;i<value.disks.length;i++){
+ if(value.disks[i].base){
+ isLocal = /^\//.test(value.disks[i].base);
+ break;
+ }
+ }
+ }
+ if(isLocal){
+ value.location = "plugins/kimchi/images/theme-default/icon-local.png";
+ }else{
+ value.location = "plugins/kimchi/images/theme-default/icon-remote.png";
+ }
+ listHtml += wok.substitute(templateHtml, value);
+ });
+ $('#templateList').html(listHtml);
+ kimchi.templateBindClick();
+ } else {
+ $('#templateList').html('');
+ $('#noTemplates').show();
+ }
+ $('html').removeClass('processing');
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $('html').removeClass('processing');
+ });
+};
+
+kimchi.templateBindClick = function() {
+ $('.template-edit').on('click', function(event) {
+ var templateName = $(this).data('template');
+ kimchi.selectedTemplate = templateName;
+ wok.window.open("plugins/kimchi/template-edit.html");
+ });
+ $('.template-clone').on('click', function(event) {
+ kimchi.selectedTemplate = $(this).data('template');
+ $('html').addClass('processing');
+ kimchi.cloneTemplate(kimchi.selectedTemplate, function() {
+ kimchi.doListTemplates();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ kimchi.doListTemplates();
+ });
+ });
+ $('.template-delete').on('click', function(event) {
+ var $template = $(this);
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHTMPL6003M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ var templateName = $template.data('template');
+ kimchi.deleteTemplate(templateName, function() {
+ kimchi.doListTemplates();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ });
+ });
+}
+kimchi.hideTitle = function() {
+ $('#tempTitle').hide();
+};
+
+kimchi.template_main = function() {
+ if(wok.tabMode['templates'] === 'admin') {
+ $('.tools').attr('style','display');
+ $("#template-add").on("click", function(event) {
+ wok.window.open({
+ url: 'plugins/kimchi/template-add.html',
+ close: function() {
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ }
+ });
+ });
+ }
+
+ kimchi.doListTemplates();
+};
diff --git a/src/wok/plugins/kimchi/ui/pages/Makefile.am b/src/wok/plugins/kimchi/ui/pages/Makefile.am
new file mode 100644
index 0000000..56288e3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+SUBDIRS = help
+
+htmldir = $(datadir)/wok/plugins/kimchi/ui/pages
+
+dist_html_DATA = $(wildcard *.tmpl) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl
new file mode 100644
index 0000000..3770d96
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl
@@ -0,0 +1,98 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<body>
+<div class="window" style="width: 900px;height: 580px;">
+ <header>
+ <h1 class="title h1 grey">$_("Create a New Virtual Machine")</h1>
+ </header>
+ <div class="content">
+ <form id="form-vm-add">
+ <section class="form-section">
+ <h2>1. $_("Virtual Machine Name")</h2>
+ <div class="field">
+ <input type="text" class="text" style="width: 300px" name="name"><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("The name used to identify the virtual machine. If omitted, a name will be chosen based on the template used.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>2. $_("Template")</h2>
+ <div class="field">
+ <div class="text-help">
+ <div id="prompt-create-template" class="hidden">
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <div class="text-help help-inline">$_("Please create a template first.")</div>
+ <a id="btn-create-template" class="btn-normal" href="templates.html">
+ <span class="text">$_("Create a Template")</span>
+ </a>
+ </div>
+ <div id="prompt-choose-template" class="hidden">
+ <span class="icon-info-circled light-grey c1"></span>
+ <span class="text-help">$_("Please choose a template.")</span>
+ </div>
+ </div>
+ <ul id="templateTile" class="tile-check tile-template">
+ </ul>
+ <script type="html/text" id="tmpl-template" class="tmpl-html">
+ <li>
+ <label>
+ <input type="radio" name="template" value="/plugins/kimchi/templates/{name}">
+ <div class="info">
+ <div class="summary os-icon">
+ <img src="{icon}">
+ <span class="title">{name}</span>
+ </div>
+ <ul class="list-info">
+ <li><label>$_("OS")</label><span>{os_distro}</span></li>
+ <li><label>$_("OS Version")</label><span>{os_version}</span></li>
+ <li><label>$_("CPUS")</label><span>{cpus}</span></li>
+ <li><label>$_("Memory")</label><span>{memory}M</span></li>
+ </ul>
+ </div>
+ </label>
+ </li>
+ </script>
+ </div>
+ </section>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="vm-doAdd" class="btn-normal" disabled="disabled" href="javascript:void(0);"><span class="text">$_("Create")</span></button>
+ <button id="vm-doAdding" class="btn-normal" disabled="disabled" style="display:none" href="javascript:void(0);"><span class="text">$_("Creating...")</span></button>
+ <button id="vm-add=cancel" class="btn-normal close" type="button">
+ <span class="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.guest_add_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl
new file mode 100644
index 0000000..c5acf04
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl
@@ -0,0 +1,311 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+<div id="guest-edit-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Edit Guest")</h1>
+ </header>
+ <div class="content">
+ <div id="guest-edit-tabs">
+ <ul>
+ <li>
+ <a href="#form-guest-edit-general">$_("General")</a>
+ </li>
+ <li>
+ <a href="#form-guest-edit-storage">$_("Storage")</a>
+ </li>
+ <li>
+ <a href="#form-guest-edit-interface">$_("Interface")</a>
+ </li>
+ <li>
+ <a href="#form-guest-edit-permission">$_("Permission")</a>
+ </li>
+ <li>
+ <a href="#form-guest-edit-pci">$_("Host PCI Device")</a>
+ </li>
+ <li>
+ <a href="#form-guest-edit-snapshot">$_("Snapshot")</a>
+ </li>
+ </ul>
+ <form id="form-guest-edit-general">
+ <fieldset class="guest-edit-fieldset">
+ <div class="edit-general-inline">
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-id-textbox">
+ $_("Name")
+ </label>
+ </div>
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-cores-textbox">
+ $_("CPUs")
+ </label>
+ </div>
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-memory-textbox">
+ $_("Memory (MB)")
+ </label>
+ </div>
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-icon-textbox">
+ $_("Icon")
+ </label>
+ </div>
+ </div>
+ <div class="edit-general-inline">
+ <div class="guest-edit-wrapper-controls">
+ <input id="guest-edit-id-textbox"
+ name="name" type="text" />
+ </div>
+ <div class="guest-edit-wrapper-controls">
+ <input
+ id="guest-edit-cores-textbox"
+ name="cpus"
+ type="text" />
+ </div>
+ <div class="guest-edit-wrapper-controls">
+ <input id="guest-edit-memory-textbox"
+ name="memory"
+ type="text" />
+ </div>
+ <div class="guest-edit-wrapper-controls">
+ <input
+ id="guest-edit-icon-textbox"
+ name="icon"
+ type="text"
+ disabled="disabled" />
+ </div>
+ </div>
+ </fieldset>
+ </form>
+ <form id="form-guest-edit-storage">
+ <div class="header">
+ <span class="cell">$_("Device")</span>
+ <span class="cell">$_("Path")</span>
+ <button type="button" id="guest-edit-attach-cdrom-button" class="action-area attach"></button>
+ </div>
+ <div class="body"></div>
+ </form>
+ <form id="form-guest-edit-interface" class="guest-edit-interface">
+ <div class="header">
+ <span class="cell">$_("Network")</span>
+ <span class="cell">$_("Type")</span>
+ <span class="cell">$_("MAC Address")</span>
+ <button class="add action-area"></button>
+ </div>
+ <div class="body"></div>
+ </form>
+ <form id="form-guest-edit-permission" class="guest-edit-permission">
+ <div class="pam">
+ <div class="column avail">
+ <div class="title">$_("Available system users and groups")</div>
+ <input type="text" id="permission-avail-searchBox">
+ <div class="body">
+ <div class="head">
+ <div class="column column-user"><div class="item">Users</div></div>
+ <div class="column column-group"><div class="item">Groups</div></div>
+ </div>
+ <div id="permission-avail-users" class="column column-user"></div>
+ <div id="permission-avail-groups" class="column column-group"></div>
+ </div>
+ </div>
+ <div class="column control">
+ <button id="permissionGo"> > </button>
+ <button id="permissionBack"> < </button>
+ </div>
+ <div class="column selected">
+ <div class="title">$_("Selected system users and groups")</div>
+ <input type="text" id="permission-sel-searchBox">
+ <div class="body">
+ <div class="head">
+ <div class="column column-user"><div class="item">Users</div></div>
+ <div class="column column-group"><div class="item">Groups</div></div>
+ </div>
+ <div id="permission-sel-users" class="column column-user"></div>
+ <div id="permission-sel-groups" class="column column-group"></div>
+ </div>
+ </div>
+ </div>
+ <div class="ldap">
+ <div class="header">
+ <span class="cell">$_("User")</span>
+ <button type="button" id="guest-edit-add-user-button" class="action-area add"></button>
+ </div>
+ <div class="body"></div>
+ </div>
+ </form>
+ <form id="form-guest-edit-pci" class="guest-edit-pci">
+ <div class="guest-scroll-indent">
+ <div class="filter">
+ <span class="group">
+ <select class="control">
+ <option value="all">$_("All")</option>
+ <option value="toAdd">$_("To Add")</option>
+ <option value="added">$_("Added")</option>
+ </select><input type="text" class="control" placeholder="$_("filter")">
+ </span>
+ </div>
+ <div class="header">
+ <span class="cell name">$_("Name")</span>
+ <span class="cell product">$_("Product")</span>
+ <span class="cell vendor">$_("Vendor")</span>
+ </div>
+ <div class="body"></div>
+ </div>
+ </form>
+ <form id="form-guest-edit-snapshot" class="guest-edit-snapshot">
+ <div class="header">
+ <span class="cell sel"></span>
+ <span class="cell name">$_("Name")</span>
+ <span class="cell created">$_("Created")</span>
+ <button class="add action-area"></button>
+ </div>
+ <div class="task"></div>
+ <div class="body"></div>
+ </form>
+ </div>
+ </div>
+ <footer>
+ <div id="action-button-container" class="btn-group hidden">
+ <button id="guest-edit-button-save" class="btn-normal">
+ <span class="text">$_("Save")</span>
+ </button>
+ </div>
+ <button id="guest-edit-button-cancel" class="btn-normal close">
+ <span class="text">$_("Cancel")</span>
+ </button>
+ </footer>
+</div>
+<script id="cdrom-row-tmpl" type="text/html">
+ <div class="item view" id="cdrom-{dev}">
+ <span class="cell dev">
+ <input type="text" readonly="readonly"
+ id="cdrom-dev-{dev}" name="cdrom-dev-{dev}" value="{dev}" />
+ </span>
+ <span class="cell path">
+ <input id="cdrom-path-{dev}" name="cdrom" type="text"
+ data-vm="{vm}" data-dev="{dev}"
+ value="{path}" readonly="readonly" />
+ </span>
+ <span class="action-area">
+ <button type="button" class="guest-edit-cdrom-button replace"
+ data-vm="{vm}" data-dev="{dev}"
+ title='$_("Replace")'>
+ </button>
+ <button type="button" class="guest-edit-cdrom-button detach"
+ data-vm="{vm}" data-dev="{dev}" data-type="{type}"
+ title='$_("Detach")'>
+ </button>
+ <button type="button" class="guest-edit-cdrom-button save hidden"
+ data-vm="{vm}" data-dev="{dev}"
+ title='$_("Save")'>
+ </button>
+ <button type="button" class="guest-edit-cdrom-button cancel hidden"
+ data-vm="{vm}" data-dev="{dev}"
+ title='$_("Cancel")'>
+ </button>
+ </span>
+ </div>
+</script>
+<script id="interface-tmpl" type="text/html">
+ <div class="item" id="{mac}">
+ <span class="cell">
+ <label id="label-network-{id}" class="{viewMode}">{network}</label>
+ <select class="{editMode}"></select>
+ </span>
+ <span class="cell">
+ <span>{type}</span>
+ </span>
+ <span class="cell">
+ <label id="label-mac-{id}" class="{viewMode}">{mac}</label>
+ <input class="{editMode}" type="text"
+ id="edit-mac-{id}" name="{mac}" value="{mac}" />
+ </span>
+ <span class="action-area {editMode}">
+ <button class="save"></button><button class="cancel"></button>
+ </span>
+ <span class="action-area {viewMode}">
+ <button class="edit"></button><button class="delete"></button>
+ </span>
+ <div>
+</script>
+<script id="ldap-user-tmpl" type="text/html">
+ <div class="item" id="{user}">
+ <span class="cell">
+ <label class="{viewMode}">{user}</label>
+ <input type="text" placeholder="LDAP User ID,e.g.foo at foo.com" class="{editMode}"/>
+ </span>
+ <span class="action-area">
+ <button class="delete"></button>
+ </span>
+ <div>
+</script>
+<script id="disk-row-tmpl" type="text/html">
+ <div class="item" id="cdrom-{dev}">
+ <span class="cell dev">
+ <input type="text" readonly="readonly"
+ id="disk-dev-{dev}" name="disk-dev-{dev}" value="{dev}" />
+ </span>
+ <span class="cell path">
+ <input id="disk-path-{dev}" name="path-{dev}" type="text"
+ data-vm="{vm}" data-dev="{dev}"
+ value="{path}" readonly="readonly" />
+ </span>
+ <span class="action-area">
+ <button type="button" class="guest-edit-cdrom-button detach"
+ data-vm="{vm}" data-dev="{dev}" data-type="{type}"
+ title="$_("Detach")">
+ </button>
+ </span>
+ </div>
+</script>
+<script id="permission-item-pam" type="text/html">
+<div class="item">
+ <span class="icon {class}"></span>
+ <label>{val}</label>
+</div>
+</script>
+<script id="pci-tmpl" type="text/html">
+<div class="item" id="{name}">
+ <span class="cell name" title="{name}">{name}</span>
+ <span class="cell product" title="{product}">{product}</span>
+ <span class="cell vendor" title="{vendor}">{vendor}</span>
+ <button></button>
+</div>
+</script>
+<script id="snapshot-tmpl" type="text/html">
+ <div class="item" id="{name}">
+ <span class="cell sel">
+ <span class="icon {createMode}"></span>
+ <span class="ui-icon ui-icon-check hide"></span>
+ </span>
+ <span class="cell name">{name}</span>
+ <span class="cell created">{created}</span>
+ <span class="action-area">
+ <button class="revert {listMode}" title="$_("revert")"></button>
+ <button class="delete {listMode}"></button>
+ </span>
+ <div>
+</script>
+<script type="text/javascript">
+ kimchi.guest_edit_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
new file mode 100644
index 0000000..a26e0f9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
@@ -0,0 +1,103 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<div id="guest-storage-add-window" class="window">
+ <header>
+ <h1 class="title">$_("Add a Storage Device to VM")</h1>
+ <div class="close">X</div>
+ </header>
+ <div class="content">
+ <form id="form-guest-storage-add">
+ <section class="form-section">
+ <h2>1. $_("Device Type")</h2>
+ <div class="field">
+ <p class="text-help">
+ $_("The device type. Currently, \"cdrom\" and \"disk\" are supported.")
+ </p>
+ <div class="btn dropdown popable">
+ <input id="guest-storage-type" name="type" value="cdrom" type="hidden" />
+ <span class="text" id="guest-storage-type-label"></span>
+ <span class="arrow"></span>
+ <div class="popover">
+ <ul class="select-list" id="guest-storage-type-list" data-target="guest-storage-type" data-label="guest-storage-type-label"></ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ <div class="volume-section hidden">
+ <section class="form-section">
+ <h2>2. $_("Storage Pool")</h2>
+ <div class="field storage-field">
+ <p class="text-help">
+ $_("Storage pool which volume located in")
+ </p>
+ <div class="btn dropdown popable">
+ <input value="default" id="guest-disk-pool" name="pool" type="hidden"/>
+ <span class="text" id="guest-disk-pool-label">default</span><span class="arrow"></span>
+ <div class="popover" style="width: 100%">
+ <ul class="select-list" id="guest-add-storage-pool-list" data-target="guest-disk-pool" data-label="guest-disk-pool-label"></ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>3. $_("Storage Volume")</h2>
+ <div class="field storage-field">
+ <p class="text-help">
+ $_("Storage volume to be attached")
+ </p>
+ <div class="btn dropdown popable" id="guest-disk">
+ <input id="guest-disk-vol" name="vol" type="hidden">
+ <span class="text" id="guest-disk-vol-label"></span><span class="arrow"></span>
+ <div class="popover" style="width: 100%">
+ <ul class="select-list" id="guest-add-storage-pool-list" data-target="guest-disk-vol" data-label="guest-disk-vol-label"></ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ </div>
+ <div class="path-section">
+ <section class="form-section">
+ <h2>2. $_("File Path")</h2>
+ <div class="field">
+ <p class="text-help">
+ $_("The ISO file path in the server for CDROM.")
+ </p>
+ <input type="text" class="text" name="path" />
+ </div>
+ </section>
+ </div>
+ </fieldset>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="guest-storage-button-add" class="btn-normal" disabled="disabled">
+ <span class="text">$_("Attach")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script type="text/javascript">
+ kimchi.guest_storage_add_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl
new file mode 100644
index 0000000..78e9161
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl
@@ -0,0 +1,77 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+ <li name="guest" class="guest">
+ <div class="sortable guest-type">
+ <div class="guest-general">
+ <h2 class="title" title="{name}">{name}</h2>
+ </div>
+ <div class="guest-pending hide-content">
+ <span class="icon"></span><span class="text"></span>
+ </div>
+ </div>
+ <div name="cpu_utilization" class="sortable">
+ <div class="circleGauge"></div>
+ </div>
+ <div name="io_throughput" class="sortable">
+ <div class="circleGauge"></div>
+ <div class="subtitle">KB/s</div>
+ </div>
+ <div name="net_throughput" class="sortable">
+ <div class="circleGauge"></div>
+ <div class="subtitle">KB/s</div>
+ </div>
+ <div name="guest-tile" class="sortable guest-tile">
+ <div class="tile ">
+ <img class="imgactive" alt="" src="">
+ <img class="imgload" alt="" src="">
+ <img class="overlay shutoff-hidden" alt="$_("Start")" src="plugins/kimchi/images/theme-default/icon-power-down.png" >
+ </div>
+ </div>
+ <div class="sortable guest-actions" name="guest-actions">
+ <div class="top">
+ <button class="btn reset-disabled" name="vm-reset" href="javascript:void(0);" title="$_("Reset")"><span class="icon reset"></span></button>
+ <button class="btn pause-disabled" name="vm-pause" href="javascript:void(0);" title="$_("Pause")"><span class="icon pause"></span></button>
+ <button class="btn resume-hidden" name="vm-resume" href="javascript:void(0);" title="$_("Resume")"><span class="icon resume"></span></button>
+ <button class="btn running-hidden" name="vm-start" href="javascript:void(0);" title="$_("Start")"><span class="icon power-down"></span></button>
+ <button class="btn shutoff-hidden" name="vm-poweroff" href="javascript:void(0);" title="$_("Power Off")"><span class="icon power-up"></span></button>
+ </div>
+ <div class="bottom">
+ <div name="actionmenu" class="btn dropdown popable vm-action" style="width: 126px">
+ <span class="text">$_("Actions")</span><span class="arrow"></span>
+ <div class="popover actionsheet right-side" style="width: 250px">
+ <button class="button-big shutoff-disabled" name="vm-console" ><span class="text">$_("Connect")</span></button>
+ <button class="button-big running-disabled" name="vm-clone"><span class="text">$_("Clone")</span></button>
+ <button class="button-big" name="vm-edit"><span class="text">$_("Edit")</span></button>
+ <button class="button-big shutoff-hidden non-persistent-disabled" name="vm-reset"><span class="text">$_("Reset")</span></button>
+ <button class="button-big pause-hidden non-persistent-disabled" name="vm-pause"><span class="text">$_("Pause")</span></button>
+ <button class="button-big resume-hidden" name="vm-resume"><span class="text">$_("Resume")</span></button>
+ <button class="button-big shutoff-hidden" name="vm-shutdown"><span class="text">$_("Shut Down")</span></button>
+ <button class="button-big running-hidden" name="vm-start"><span class="text">$_("Start")</span></button>
+ <button class="button-big shutoff-hidden" name="vm-poweroff"><span class="text">$_("Power Off")</span></button>
+ <button class="button-big red non-persistent-disabled" name="vm-delete">$_("Delete")</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </li>
diff --git a/src/wok/plugins/kimchi/ui/pages/guests.html.tmpl b/src/wok/plugins/kimchi/ui/pages/guests.html.tmpl
new file mode 100644
index 0000000..b8a1259
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guests.html.tmpl
@@ -0,0 +1,65 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#from Cheetah.Template import Template
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+#silent ht = Template
+
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div id="guests-root-container">
+ <div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="vm-add" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
+ </div>
+ </div>
+ <div id="guestListField" style="display: none">
+ <ul class="list-title">
+ <li class="guest-type">$_("Name")</li>
+ <li class="guest-cpu">$_("CPU")</li>
+ <li class="guest-storage">$_("Disk I/O")</li>
+ <li class="guest-network">$_("Network I/O")</li>
+ <li class="guest-tile">$_("Livetile")</li>
+ <li class="guest-actions">$_("Actions")</li>
+ </ul>
+ <ul id="guestList" class="list-vm empty-when-logged-off">
+ </ul>
+ </div>
+ <div id="noGuests" class="list-no-result" style="display: none;">
+ $_("No guests found.")
+ </div>
+ <script id="guest-tmpl" type="kimchi/template">
+ $ht(file=$data.ui_dir + "/pages/guest.html.tmpl", searchList=[self, {'lang':$lang}])
+ </script>
+ <script type="text/javascript">
+ kimchi.guest_main();
+ </script>
+</div>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/Makefile.am
new file mode 100644
index 0000000..a4ee361
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/Makefile.am
@@ -0,0 +1,34 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = zh_CN it_IT en_US zh_TW pt_BR ja_JP ru_RU ko_KR fr_FR de_DE es_ES
+
+DITA_HTML_FILES = $(patsubst %.dita,%.html,$(wildcard */*.dita))
+HTML_FILES = $(if $(DITA_HTML_FILES), $(DITA_HTML_FILES), $(wildcard */*.html))
+DITA_XSL_FILE = dita-help.xsl
+
+EXTRA_DIST = $(DITA_XSL_FILE)
+
+helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help
+
+dist_help_DATA = kimchi.css
+
+all: $(HTML_FILES) $(wildcard */*.dita)
+
+%.html: %.dita $(DITA_XSL_FILE)
+ xsltproc -o $@ $(DITA_XSL_FILE) $<
+
+CLEANFILES = $(HTML_FILES)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
new file mode 100644
index 0000000..3d99aae
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+de_DE_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/de_DE
+
+dist_de_DE_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita
new file mode 100644
index 0000000..1d64469
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="de-de">
+<title>Gäste</title>
+<shortdesc>Auf der Seite <wintitle>Gäste</wintitle> sind die definierten virtuellen
+Maschinen von KVM aufgelistet.</shortdesc>
+<csbody>
+<p>Für jeden Gast werden die folgenden Informationen angezeigt:<dl><dlentry>
+<dt>Name</dt>
+<dd>Name der virtuellen Maschine.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Prozentsatz der Prozessorauslastung in der virtuellen Maschine.</dd>
+</dlentry><dlentry>
+<dt>Netz-E/A</dt>
+<dd>Netz-E/A-Ãbertragungsrate in KB pro Sekunde.</dd>
+</dlentry><dlentry>
+<dt>Platten-E/A</dt>
+<dd>Platten-E/A-Ãbertragungsrate in KB pro Sekunde.</dd>
+</dlentry><dlentry>
+<dt>Live Tile</dt>
+<dd>Status der Konsole für das Gastbetriebssystem oder ein Symbol, das die
+<tm tmtype="tm" trademark="Linux">Linux</tm>-Verteilung darstellt, wenn
+der Gast nicht aktiv ist.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionssymbole werden für jeden Gast angezeigt:<dl>
+<dlentry>
+<dt>Zurücksetzen</dt>
+<dd>Klicken Sie hier, um den Gast zurückzusetzen. </dd>
+</dlentry><dlentry>
+<dt>Power (Starten oder Stoppen)</dt>
+<dd>Klicken Sie hier, um den Gast ein- bzw. auszuschalten. Wenn das Symbol rot ist,
+ist er ausgeschaltet. Wenn das Symbol grün ist, ist er eingeschaltet.</dd>
+</dlentry></dl> </p>
+<p>Die folgenden Aktionen können für jeden Gast ausgewählt werden:<ul>
+<li>Wählen Sie <uicontrol>Verbinden</uicontrol> aus, um eine Verbindung zur fernen Konsole
+für das Gastbetriebssystem herzustellen.</li>
+<li>Wählen Sie <uicontrol>Medien verwalten</uicontrol> aus, um den Pfad zu den
+Installationsmedien zu ändern.</li>
+<li>Wählen Sie <uicontrol>Zurücksetzen</uicontrol> aus, um den Gast zurückzusetzen.</li>
+<li>Wählen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die Eigenschaften eines
+bestehenden Gastes zu bearbeiten. Gäste können nur bearbeitet werden, wenn sie gestoppt sind.</li>
+<li>Wählen Sie <uicontrol>Löschen</uicontrol> aus, um den Gast zu löschen.</li>
+</ul>Um einen Gast bzw. eine virtuelle Maschine zu erstellen, klicken Sie auf das <uicontrol>Plus (+)</uicontrol>-Symbol oben rechts auf der Seite.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="de-de">
+<title>Virtuelle Maschine erstellen</title>
+<shortdesc>Erstellen Sie eine virtuelle Maschine mithilfe einer bestehenden Vorlage.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Geben Sie den Namen ein, mit dem die virtuelle Maschine gekennzeichnet wird.</li>
+<li rev="rev1">Wählen Sie eine Vorlage aus. <ul>
+<li>Wenn Vorlagen vorhanden sind, wählen Sie eine aus den angezeigten Vorlagen aus.</li>
+<li>Wenn keine Vorlagen vorhanden sind, klicken Sie auf <uicontrol>Vorlage erstellen</uicontrol>, um eine Vorlage zu erstellen.</li>
+</ul></li>
+<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="de-de">
+<title>Gast bearbeiten</title>
+<shortdesc>Bearbeiten Sie die Eigenschaften einer bestehenden virtuellen Maschine. Einige Eigenschaften können nur bearbeitet werden, solange der Gast gestoppt ist. Andere Eigenschaften treten beim nächsten Booten in Kraft. </shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Für jeden Gast werden die folgenden Informationen auf der Registerkarte <wintitle>Allgemein</wintitle> angezeigt:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name der virtuellen Maschine. (Kann nur bearbeitet werden, solange der Gast gestoppt ist.)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Anzahl der Prozessoren. (Wenn der Gast aktiv ist, tritt die neue Menge beim nächsten Booten in Kraft.)
+</dd>
+</dlentry><dlentry>
+<dt>Speicher</dt>
+<dd>Speicherkapazität in MB. (Wenn der Gast aktiv ist, tritt die neue Menge beim nächsten Booten in Kraft.)
+</dd>
+</dlentry><dlentry>
+<dt>Symbol</dt>
+<dd>Grafikbild, das die Linux-Verteilung darstellt und anstelle des aktuellen Status (Live Tile) angezeigt werden soll, wenn der Gast nicht aktiv ist.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Informationen werden auf der Registerkarte <wintitle>Speicher</wintitle> angezeigt.</p>
+<dl><dlentry>
+<dt>Speicher</dt>
+<dd>Zeigt die Position der ISO-Datei an, die für die Installation verwendet wird.</dd>
+</dlentry></dl>
+<p> Felder, die nicht inaktiviert sind, können bearbeitet werden. Nachdem Sie ein Feld bearbeitet haben, klicken Sie auf <uicontrol>Speichern</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="de-de">
+<title>Speichereinheit hinzufügen, ersetzen oder abhängen</title>
+<shortdesc rev="rev1">Sie können eine Speichereinheit zu Ihrer virtuellen Maschine hinzufügen oder diese ersetzen oder abhängen. Die einzige unterstützte Einheit ist CD-ROM. Führen Sie die folgenden Schritte aus, um Ihre Speichereinheiten zu bearbeiten:</shortdesc>
+<csbody>
+<ol>
+<li>Wählen Sie im Fenster <wintitle>Gast bearbeiten</wintitle> die Option <wintitle>Speicher</wintitle> aus.</li>
+<li>Um eine Speichereinheit zu ersetzen, klicken Sie auf das erste Symbol mit dem <uicontrol>orangefarbenen Schrägstrich (/)</uicontrol>. Geben Sie den ISO-Dateipfad ein und klicken Sie auf <uicontrol>Ersetzen</uicontrol>.</li>
+<li>Um eine Speichereinheit abzuhängen, klicken Sie auf das zweite Symbol mit dem <uicontrol>roten Gedankenstrich (-)</uicontrol>. Bestätigen Sie den Löschvorgang und klicken Sie auf <uicontrol>OK</uicontrol>.</li>
+<li>Um eine Speichereinheit hinzuzufügen, klicken Sie auf das dritte Symbol mit dem grünen <uicontrol>Pluszeichen (+)</uicontrol>. Geben Sie einen Einheitennamen und einen ISO-Dateipfad ein und klicken Sie auf <uicontrol>Anhängen</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="de-de">
+<title>CD-ROM für VM ersetzen</title>
+<shortdesc rev="rev1">Sie können den Inhalt der CD-ROM für eine virtuelle Maschine nach Abschluss der Installation ersetzen.</shortdesc>
+<csbody>
+<ol>
+<li>Stellen Sie sicher, dass die virtuelle Maschine gestartet ist.</li>
+<li>Wählen Sie aus dem Aktionsmenü die Option <uicontrol>Medien verwalten</uicontrol> aus.</li>
+<li>Um das zu ändern, was aktuell in der CD-ROM geladen ist, klicken Sie auf das Symbol mit dem <uicontrol>orangefarbenen Schrägstrich (/)</uicontrol> neben dem hdc-Feld.</li>
+<li>Geben Sie auf der Seite <wintitle>CD-ROM für VM ersetzen</wintitle> den ISO-Dateipfad ein. Die anderen beiden Felder sind schreibgeschützt.</li>
+<li>Klicken Sie auf <uicontrol>Ersetzen</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita b/src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita
new file mode 100644
index 0000000..33a40e3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="de-de">
+<title>Host</title>
+<shortdesc>Die Seite <wintitle>Host</wintitle> zeigt Informationen zum Hostsystem an und ermöglicht Ihnen, den Host herunterzufahren, erneut zu starten und eine Verbindung zu ihm herzustellen.</shortdesc>
+<csbody>
+<p>Sie können die folgenden Aktionen am Host durchführen:<ul>
+<li>Wählen Sie <uicontrol>Herunterfahren</uicontrol> aus, um das Hostsystem herunterzufahren.</li>
+<li>Wählen Sie <uicontrol>Erneut starten</uicontrol> aus, um das Hostsystem erneut zu starten.</li>
+<li>Wählen Sie <uicontrol>Verbinden</uicontrol> aus, um eine VNC-Verbindung zum Hostsystem herzustellen, wenn noch keine Verbindung besteht.</li>
+</ul></p>
+<p>Klicken Sie auf die folgenden Abschnitte, um Informationen zum Host anzuzeigen:<dl>
+<dlentry>
+<dt>Basisinformationen</dt>
+<dd>Dieser Abschnitt zeigt die Verteilung, die Version und den Codenamen des Hostbetriebssystems sowie den Prozessortyp und die Speicherkapazität in GB an.</dd>
+</dlentry><dlentry>
+<dt>Systemstatistik</dt>
+<dd>Dieser Abschnitt zeigt mithilfe von Grafiken Statistiken für CPU, Speicher, Platten-E/A und Netz-E/A für den Host an. Wählen Sie <uicontrol>Daten werden nach dem Verlassen dieser Seite gesammelt</uicontrol> aus, um mit der Sammlung von Daten fortzufahren, wenn die Host-Registerkarte nicht angezeigt wird.</dd>
+</dlentry><dlentry>
+<dt>Software-Updates</dt>
+<dd>Dieser Abschnitt zeigt Informationen für alle Pakete an, bei denen Aktualisierungen verfügbar sind, einschlieÃlich Paketname, Version, Architektur und Repository. Sie können alle aufgelisteten Pakete aktualisieren, indem Sie <uicontrol>Alle aktualisieren</uicontrol> auswählen. Sie können nicht einzelne Pakete zur Aktualisierung auswählen.</dd>
+</dlentry><dlentry>
+<dt>Repositorys</dt>
+<dd>Dieser Abschnitt zeigt Repositorys an, die dem Hostsystem zugeordnet sind. Sie können Repositorys hinzufügen, aktivieren, bearbeiten oder entfernen. Beim Hinzufügen wird ein Repository dem Hostsystem zugeordnet. Das Aktivieren eines Repositorys dagegen ermöglicht dem Host den Zugriff auf das Repository. Wenn Ihr System Red Hat Enterprise
+Linux oder Fedora ist, können Sie <filepath>yum</filepath>-Repositorys hinzufügen.
+Wenn Ihr System Ubuntu oder Debian ist, fügen Sie <filepath>deb</filepath>-Repositorys hinzu.<p>Wenn Sie mit yum-Repositorys arbeiten, können Sie eine GPG-Prüfung hinzufügen, um sicherzustellen, dass ein Paket aus diesem Repository nicht beschädigt wurde.
+Wählen Sie ein Repository und dann <uicontrol>Bearbeiten</uicontrol> aus. Wählen Sie <uicontrol>Ja</uicontrol> aus, um die GPG-Prüfung zu aktivieren, und geben Sie dann ein URL zur GPG-Schlüsseldatei für das Repository ein.</p></dd>
+</dlentry><dlentry>
+<dt>Debugberichte</dt>
+<dd>Dieser Abschnitt zeigt Debugberichte, einschlieÃlich Name und Dateipfad, an.
+Sie haben die Möglichkeit, einen neuen Bericht zu erstellen oder einen bestehenden Bericht umzubenennen, zu entfernen oder herunterzuladen.<p>Der Debugbericht wird während des Befehls <cmdname>sosreport</cmdname> generiert. Er ist verfügbar für Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>-, Fedora-
+und Ubuntu-Verteilungen. Der Befehl generiert eine .tar-Datei, die Konfigurations- und Diagnoseinformationen enthält, wie zum Beispiel Kernelversion, geladene Module sowie System- und Servicekonfigurationdateien.
+Der Befehl führt zudem externe Programme aus, um weitere Informationen zu sammeln, und speichert diese Ausgabe im resultierenden Archiv.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita b/src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita
new file mode 100644
index 0000000..49a2935
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="de-de">
+<title>Netz</title>
+<shortdesc>Die Seite <wintitle>Netz</wintitle> zeigt Informationen zur Netzverbindung an.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Netzname</dt>
+<dd>Name des Netzes oder <uicontrol>Standard</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Status</dt>
+<dd>Status des Netzes, aktiv (grün) oder inaktiv (rot). </dd>
+</dlentry><dlentry>
+<dt>Netztyp</dt>
+<dd>Netztyp, zum Beispiel <uicontrol>NAT</uicontrol> (Network
+Address Translation, Netzadressumsetzung).</dd>
+</dlentry><dlentry>
+<dt>Schnittstelle</dt>
+<dd>Netzschnittstelle, zum Beispiel <uicontrol>virbr0</uicontrol> (Standard).</dd>
+</dlentry><dlentry>
+<dt>Adressraum</dt>
+<dd>IP-Adresse.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionen können ausgewählt werden:<ul>
+<li rev="rev1">Wählen Sie <uicontrol>Starten</uicontrol> aus, um die Netzverbindung herzustellen.</li>
+<li>Wählen Sie <uicontrol>Stoppen</uicontrol> aus, um die Netzverbindung zu beenden.</li>
+<li>Wählen Sie <uicontrol>Löschen</uicontrol> aus, um die Verbindungsinformationen zu löschen.</li>
+</ul>Um ein Netz zu erstellen, klicken Sie auf das Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="de-de">
+<title>Netz erstellen</title>
+<shortdesc>Erstellen Sie ein Netz.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Geben Sie den Namen des Netzes ein.</li>
+<li>Klicken Sie hier, um den Netztyp auszuwählen. <dl rev="rev1"><dlentry>
+<dt><uicontrol>Isoliert</uicontrol></dt>
+<dd>Isolierter Modus. Gäste können keine Kommunikation an externe Systeme senden oder von ihnen empfangen.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Network Address Translation-Modus. Bei der Kommunikation von Gästen mit externen Systemen wird die Host-IP-Adresse verwendet. Externe Systeme können keine Kommunikation mit Gästen initiieren.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Ãberbrückt</uicontrol></dt>
+<dd>Ãberbrückt-Modus. Gäste können mit externen Systemen kommunizieren und von externen Systemen kontaktiert werden, als ob sie physische Systeme im Netz wären. Für den Ãberbrückt-Modus müssen Sie zusätzliche Ziel- und VLAN-Informationen angeben.</dd>
+</dlentry></dl></li>
+<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita
new file mode 100644
index 0000000..7f89603
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="de-de">
+<title>Speicher</title>
+<shortdesc>Auf der Seite <wintitle>Speicher</wintitle> werden die verfügbaren Speicherpools aufgelistet, einschlieÃlich der sofort einsatzfähigen Speicherpools 'default' und 'ISO'. Wenn Sie ein eigenes ISO-Image verwenden möchten, fügen Sie es zum Speicherpoolpfad 'ISO' hinzu.</shortdesc>
+<csbody>
+<p>Für jeden Speicherpool werden die folgenden Informationen angezeigt:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name des Speicherpools und genutzter Prozentsatz.</dd>
+</dlentry><dlentry>
+<dt>Status</dt>
+<dd>Status des Speicherpools, aktiv (grün) oder inaktiv (rot). </dd>
+</dlentry><dlentry>
+<dt>Position</dt>
+<dd>Dateipfad zur Position des Speicherpools.</dd>
+</dlentry><dlentry>
+<dt>Typ</dt>
+<dd>Typ des Speicherpools, zum Beispiel <uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Kapazität</dt>
+<dd>Speicherkapazität im Speicherpool.</dd>
+</dlentry><dlentry>
+<dt>Zugeordnet</dt>
+<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionen können für jeden Speicherpool ausgewählt werden:<ul>
+<li>Wählen Sie <uicontrol>Aktivieren</uicontrol> aus, um den Speicherpool zu aktivieren, damit er genutzt werden kann.</li>
+<li>Wählen Sie <uicontrol>Inaktivieren</uicontrol> aus, um einen aktiven Speicherpool zu inaktivieren.</li>
+<li>Wählen Sie <uicontrol>Definition aufheben</uicontrol>, um einen inaktiven Speicherpool zu entfernen.</li>
+</ul></p>
+<p>Um Details zum Speicherdatenträger anzuzeigen, klicken Sie auf den Pfeil auf der rechten Seite der Speicherpoolzeile. Zu den Details gehören folgende Informationen:<dl><dlentry>
+<dt>Typ</dt>
+<dd>Typ des Datenträgers, zum Beispiel <uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Format</dt>
+<dd>Das Format, variiert abhängig vom Typ.</dd>
+</dlentry><dlentry>
+<dt>Kapazität</dt>
+<dd>GröÃe des Speicherdatenträgers.</dd>
+</dlentry><dlentry>
+<dt>Zuordnung</dt>
+<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
+</dlentry></dl>Um einen Speicherpool zu definieren, klicken Sie auf das Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="de-de">
+<title>Speicherpool definieren</title>
+<shortdesc> Definieren Sie einen Speicherpool.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Geben Sie im Feld <uicontrol>Speicherpoolname</uicontrol> den Namen ein, mit dem der Speicherpool gekennzeichnet werden soll.</li>
+<li>Wählen Sie aus der Liste <uicontrol>Speicherpooltyp</uicontrol> den Typ aus: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Gibt einen Verzeichnispool an. Wenn Sie <uicontrol>DIR</uicontrol> auswählen, geben Sie den <uicontrol>Speicherpfad</uicontrol> ein (Dateipfad zum Speicherpool).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Gibt einen Netzdateisystempool an. Wenn Sie <uicontrol>NFS</uicontrol> auswählen,
+geben Sie <uicontrol>NFS-Server-IP</uicontrol> und <uicontrol>NFS-Pfad</uicontrol> an (Pfad des exportierten Verzeichnisses).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Gibt einen Pool an, der auf einem Ziel basiert, der auf einem iSCSI-Server zugeordnet ist.
+Wenn Sie <uicontrol>iSCSI</uicontrol> auswählen, geben Sie die IP-Adresse vom <uicontrol>iSCSI-Server</uicontrol> und das <uicontrol>Ziel</uicontrol> auf dem iSCSI-Server an. Sie können optional iSCSI-Authentifizierung hinzufügen.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logisch</uicontrol></dt>
+<dd>Gibt einen Speicherpool aus logischen Datenträgern an. Wählen Sie die Position zur Einheit im <uicontrol>Einheitenpfad</uicontrol> aus.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI-Fibre Channel</uicontrol></dt>
+<dd>Gibt einen Pool an, der auf einem SCSI-Fibre Channel basiert. Wählen Sie aus, welcher Adapter verwendet werden soll.</dd>
+</dlentry></dl></li>
+<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita
new file mode 100644
index 0000000..5063930
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="de-de">
+<title>Vorlagen</title>
+<shortdesc>Die Seite <wintitle>Vorlagen</wintitle> zeigt die definierten Vorlagen der virtuellen Maschine an, die zum Erstellen von KVM-Gästen verwendet werden können.</shortdesc>
+<csbody>
+<p>Für jede Vorlage werden die folgenden Informationen angezeigt:<dl>
+<dlentry>
+<dt>BS</dt>
+<dd>Name des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Anzahl der Prozessoren, die für die Vorlage definiert sind.</dd>
+</dlentry><dlentry>
+<dt>Speicher</dt>
+<dd>GröÃe des zuzuordnenden Arbeitsspeichers in MB.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionen können für jede Vorlage ausgewählt werden:<ul>
+<li>Wählen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die Vorlage zu bearbeiten.</li>
+<li>Wählen Sie <uicontrol>Löschen</uicontrol> aus, um die Vorlage zu löschen.</li>
+</ul>Um eine Vorlage hinzuzufügen, klicken Sie auf das Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="de-de">
+<title>Vorlage bearbeiten</title>
+<shortdesc>Bearbeiten Sie eine bestehende Vorlage.</shortdesc>
+<csbody>
+<p>Für jede Vorlage werden die folgenden Informationen angezeigt: <dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name der Vorlage.</dd>
+</dlentry><dlentry>
+<dt>Anbieter</dt>
+<dd>Der Name des Unternehmens, das das Betriebssystem oder die Verteilung erstellt hat, für die die Vorlage konfiguriert ist.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Die Version des Betriebssystems oder der Verteilung, für die die Vorlage konfiguriert ist.</dd>
+</dlentry><dlentry>
+<dt>CPU-Anzahl</dt>
+<dd>Anzahl der Prozessoren, die für die Vorlage definiert sind.</dd>
+</dlentry><dlentry>
+<dt>Speicher</dt>
+<dd>Speicherkapazität in MB, die der virtuellen Maschine zugeordnet werden soll.</dd>
+</dlentry><dlentry>
+<dt>Platte</dt>
+<dd>PlattengröÃe in GB.</dd>
+</dlentry><dlentry>
+<dt>CD-ROM</dt>
+<dd>Dateipfad zur Position der ISO-Datei an, die für die Installation des KVM-Gastes verwendet wird.</dd>
+</dlentry><dlentry>
+<dt>Speicherpool</dt>
+<dd>Bestimmter Speicherpool oder der Standardspeicherpool.</dd>
+</dlentry><dlentry>
+<dt>Netz</dt>
+<dd>Standardnetzschnittstelle, die für den KVM-Gast verfügbar ist. Sie können mehrere Netze auswählen.</dd>
+</dlentry></dl> Felder, die nicht inaktiviert sind, können bearbeitet werden. Nachdem Sie ein Feld bearbeitet haben, klicken Sie auf <uicontrol>Speichern</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Vorlage hinzufügen</title>
+<shortdesc>Fügen Sie eine Vorlage vom Quellendatenträger hinzu. Sie können für eine nachfolgende Erkennung Ihr eigenes ISO-Image zum Speicherpool 'ISO' hinzufügen.</shortdesc>
+<csbody>
+<p>Wählen Sie die Position des Quellendatenträgers aus den folgenden Optionen aus:<dl>
+<dlentry>
+<dt>Lokales ISO-Image</dt>
+<dd>Wählen Sie diese Option aus, um Speicherpools nach Installations-ISO-Images zu durchsuchen, die im System verfügbar sind.</dd>
+</dlentry><dlentry>
+<dt>Fernes ISO-Image</dt>
+<dd>Wählen Sie diese Option aus, um eine ferne Position für ein Installations-ISO-Image anzugeben.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Vorlage hinzufügen - lokales ISO-Image</title>
+<shortdesc>Fügen Sie eine Vorlage aus einem lokalen ISO-Image hinzu.</shortdesc>
+<csbody>
+<p>Die im System verfügbaren ISO-Images werden angezeigt.<dl><dlentry>
+<dt>BS</dt>
+<dd>Name des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>GröÃe</dt>
+<dd>GröÃe des ISO-Image.</dd>
+</dlentry></dl></p>
+<p>Um eine Vorlage aus einem ISO-Image zu erstellen, wählen Sie aus den folgenden
+Optionen aus:<ul>
+<li>Wählen Sie ein ISO-Image aus, aus dem Sie eine Vorlage erstellen möchten, und klicken Sie dann auf <uicontrol>Vorlagen aus ausgewähltem ISO erstellen</uicontrol>.</li>
+<li>Wählen Sie <uicontrol>Alle</uicontrol> aus, um eine Vorlage aus jedem aufgelisteten ISO-Image zu erstellen, und klicken Sie dann auf <uicontrol>Vorlagen aus ausgewähltem ISO erstellen</uicontrol>.</li>
+<li>Wenn das ISO-Image, das Sie verwenden möchten, nicht in den Suchergebnissen angezeigt wird, können Sie aus den folgenden Optionen auswählen:<ul>
+<li>Wählen Sie <uicontrol>Ich möchte eine bestimmte ISO-Datei verwenden</uicontrol> aus, um einen Pfad zum ISO-Image anzugeben.</li>
+<li>Klicken Sie auf <uicontrol>Weitere ISOs suchen</uicontrol>, um weitere ISO-Images zu suchen.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl b/src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl
new file mode 100644
index 0000000..45f0a3b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:output method="xml" indent="yes" encoding="UTF-8" />
+
+ <xsl:template match="/">
+ <html>
+ <head>
+ <title><xsl:value-of select="/cshelp/title" /></title>
+ <meta charset="UTF-8" />
+ <link rel="shortcut icon" href="images/logo.ico" />
+ <link rel="stylesheet" type="text/css" href="../kimchi.css" />
+ </head>
+ <body>
+ <xsl:apply-templates select="//cshelp" />
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="cshelp">
+ <h1><xsl:value-of select="title" /></h1>
+ <p class="shortdesc"><xsl:value-of select="shortdesc" /></p>
+ <p class="csbody"><xsl:copy-of select="csbody/node()" /></p>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am
new file mode 100644
index 0000000..d37f03a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+en_US_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/en_US
+
+dist_en_US_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita
new file mode 100644
index 0000000..1bb437a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="en-us">
+<title>Guests</title>
+<shortdesc>The <wintitle>Guests</wintitle> page lists the defined
+KVM virtual machines.</shortdesc>
+<csbody>
+<p>For each guest, the following information is displayed:<dl><dlentry>
+<dt>Name</dt>
+<dd>Name of the virtual machine.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Percentage of processor utilization in the virtual machine.</dd>
+</dlentry><dlentry>
+<dt>Network I/O</dt>
+<dd>Network input/output transmission rate in KB per seconds.</dd>
+</dlentry><dlentry>
+<dt>Disk I/O</dt>
+<dd>Disk input/output transmission rate in KB per seconds.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>State of guest operating system console, or an icon that represents
+the <tm tmtype="tm" trademark="Linux">Linux</tm> distribution if the
+guest is not active.</dd>
+</dlentry></dl></p>
+<p>The following actions icons are displayed for each guest:<dl>
+<dlentry>
+<dt>Reset</dt>
+<dd>Click to reset the guest. </dd>
+</dlentry><dlentry>
+<dt>Power (Start or Stop)</dt>
+<dd>Click to power on or power off the guest. If the icon is red,
+the power is off; if the icon is green, the power is on.</dd>
+</dlentry></dl> </p>
+<p>The following actions can be selected for each guest:<ul>
+<li>Select <uicontrol>Connect</uicontrol> to connect to the remote
+console for the guest operating system.</li>
+<li>Select <uicontrol>Manage media</uicontrol> to change the path
+to the installation media.</li>
+<li>Select <uicontrol>Reset</uicontrol> to reset the guest.</li>
+<li>Select <uicontrol>Edit</uicontrol> to edit the properties of an
+existing guest. Guests can be edited only while stopped.</li>
+<li>Select <uicontrol>Delete</uicontrol> to delete the guest.</li>
+</ul>To create a guest, or virtual machine, click the <uicontrol>plus
+(+)</uicontrol> icon in the upper right of the page.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="en-us">
+<title>Create virtual machine</title>
+<shortdesc>Create a virtual machine by using an existing template.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Type the name to be used to identify the virtual machine.</li>
+<li rev="rev1">Select a template. <ul>
+<li>If templates exist, select from displayed templates.</li>
+<li>If no templates exist, click <uicontrol>Create a template</uicontrol> to
+create a template.</li>
+</ul></li>
+<li>Click <uicontrol>Create</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="en-us">
+<title>Edit guest</title>
+<shortdesc>Edit the properties of an existing virtual machine. Some properties
+can be edited only while guest is stopped. Others will take effect in next boot.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>For each guest, the following information is displayed on the <wintitle>General</wintitle> tab:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name of the virtual machine. (can only be edited while guest is stopped)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Number of processors. (if guest is running, new amount will take effect
+in next boot)</dd>
+</dlentry><dlentry>
+<dt>Memory</dt>
+<dd>Amount of memory in MB. (if guest is running, new amount will take effect
+in next boot)</dd>
+</dlentry><dlentry>
+<dt>Icon</dt>
+<dd>Graphic image representing the Linux distribution to be displayed
+in place of current status (Livetile) when the guest is not active.</dd>
+</dlentry></dl></p>
+<p>The following information is displayed on the <wintitle>Storage</wintitle> tab.</p>
+<dl><dlentry>
+<dt>Storage</dt>
+<dd>Displays the location of the ISO file used for installation.</dd>
+</dlentry></dl><?Pub Caret -2?>
+<p> Fields that are not disabled can be edited. After you edit a field,
+click <uicontrol>Save</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="en-us">
+<title>Add, replace, or detach a storage device</title>
+<shortdesc rev="rev1">You can add, replace, or detach a storage device
+to your virtual machine. The only supported device is CDROM. To edit
+your storage devices, follow these steps:</shortdesc>
+<csbody>
+<ol>
+<li>On the <wintitle>Edit Guest</wintitle> window, select <wintitle>Storage</wintitle>.</li>
+<li>To replace a storage device, click the first icon with the <uicontrol>orange
+slash (/)</uicontrol>. Enter the ISO file path and click <uicontrol>Replace</uicontrol>.</li>
+<li>To detach a storage device, click the second icon with the <uicontrol>red
+dash (-)</uicontrol>. Confirm the deletion and click <uicontrol>OK</uicontrol>.</li>
+<li>To add a storage device, click the third icon with the green <uicontrol>plus
+sign (+)</uicontrol>. Enter a device name and ISO file path and click <uicontrol>Attach</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="en-us">
+<title>Replace a CDROM of VM</title>
+<shortdesc rev="rev1">You can replace the contents of the CDROM for
+a virtual machine after the installation is complete.</shortdesc>
+<csbody>
+<ol>
+<li>Ensure that the virtual machine is started.</li>
+<li>From the Actions menu, select <uicontrol>Manage Media</uicontrol>.</li>
+<li>To change what is currently loaded in the CDROM, click the <uicontrol>orange
+slash (/)</uicontrol> icon next to the hdc field.</li>
+<li>On the <wintitle>Replace a CDROM of VM</wintitle> page, enter
+the ISO file path. The other two fields are read-only.</li>
+<li>Click <uicontrol>Replace</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+<?Pub *0000005541?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita b/src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita
new file mode 100644
index 0000000..0dcb670
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="en-us">
+<title>Host</title>
+<shortdesc>The <wintitle>Host</wintitle> page shows information about
+the host system, and allows you to shut down, restart, and connect
+to the host.</shortdesc>
+<csbody>
+<p>You can perform the following actions on the host:<ul>
+<li>Select <uicontrol>Shut down</uicontrol> to shut down the host
+system.</li>
+<li>Select <uicontrol>Restart</uicontrol> to restart the host system.</li>
+<li>Select <uicontrol>Connect</uicontrol> to open a VNC connection
+to the host system, if it is not already connected.</li>
+</ul></p>
+<p>Click the following sections to display information about the host:<dl>
+<dlentry>
+<dt>Basic information</dt>
+<dd>This section displays the host operating system distribution,
+version, and code name, as well as the processor type, the number of
+online CPUs and amount of memory in GB.</dd>
+</dlentry><dlentry>
+<dt>System statistics</dt>
+<dd>This section displays graphs to show statistics for CPU, memory,
+disk I/O, and network I/O for the host. Select <uicontrol>Collecting
+data after leaving this page</uicontrol> to continue collecting data
+when the host tab is out of view.</dd>
+</dlentry><dlentry>
+<dt>Software Updates</dt>
+<dd>This section displays information for all of the packages that
+have updates available, including package name, version, architecture,
+and repository. You can update all of the packages listed by selecting <uicontrol>Update
+All</uicontrol>. You cannot select individual packages for updates.</dd>
+</dlentry><dlentry>
+<dt>Repositories</dt>
+<dd>This section displays repositories that are associated with the
+host system. You can add, enable, edit, or remove repositories. Adding
+a repository associates it with the host system while enabling a repository
+allows the host to access it. If your system is Red Hat Enterprise
+Linux or Fedora, you can add <filepath>yum</filepath> repositories.
+If your system is Ubuntu or Debian, then add <filepath>deb</filepath> repositories.<p>If
+you are working with yum repositories, you can add a GPG check to
+verify that a package from this repository have not been corrupted.
+Select a repository and then <uicontrol>Edit</uicontrol>. Select <uicontrol>Yes</uicontrol> to
+enable GPG Check and then enter a URL to the GPG key file for the
+repository.</p><?Pub Caret 156?></dd>
+</dlentry><dlentry>
+<dt>Debug reports</dt>
+<dd>This section displays debug reports, including name and file path.
+You can select from options to generate a new report, or rename, remove,
+or download an existing report.<p>The debug report is generated using
+the <cmdname>sosreport</cmdname> command. It is available for Red
+Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora,
+and Ubuntu distributions. The command generates a .tar file that contains
+configuration and diagnostic information, such as the running kernel
+version, loaded modules, and system and service configuration files.
+The command also runs external programs to collect further information
+and stores this output in the resulting archive.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+<?Pub *0000003492?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita b/src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita
new file mode 100644
index 0000000..25c05ff
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="en-us">
+<title>Network</title>
+<shortdesc>The <wintitle>Network</wintitle> page displays information
+about the network connection.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Network Name</dt>
+<dd>Name of the network, or <uicontrol>default</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>State</dt>
+<dd>State of the network, active (green) or inactive (red). </dd>
+</dlentry><dlentry>
+<dt>Network type</dt>
+<dd>Network type, for example, <uicontrol>NAT</uicontrol> (network
+address translation).</dd>
+</dlentry><dlentry>
+<dt>Interface</dt>
+<dd>Network interface, for example, <uicontrol>virbr0</uicontrol> (default).</dd>
+</dlentry><dlentry>
+<dt>Address space</dt>
+<dd>IP address.</dd>
+</dlentry></dl></p>
+<p>The following actions can be selected:<ul>
+<li rev="rev1">Select <uicontrol>Start</uicontrol> to begin the network
+connection.</li>
+<li>Select <uicontrol>Stop</uicontrol> to end the network connection.</li>
+<li>Select <uicontrol>Delete</uicontrol> to delete the connection
+information.</li>
+</ul>To create a network, click the <uicontrol>plus (+)</uicontrol> icon
+in the upper right of the display.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="en-us">
+<title>Create a network</title>
+<shortdesc>Create a network.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Type the name of the network.</li>
+<li>Click to select the network type. <dl rev="rev1"><dlentry>
+<dt><uicontrol>Isolated</uicontrol></dt>
+<dd>Isolated mode. Guests cannot send or receive communication to
+or from external systems.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Network Address Translation mode. Communication from guests to
+external systems uses the host IP address. External systems cannot
+initiate communication to guests.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Bridged</uicontrol></dt>
+<dd>Bridged mode. Guests can communicate with external systems and
+be contacted by external systems as if they were physical systems
+on the network. For bridged mode, you must specify additional destination
+and VLAN information.</dd>
+</dlentry></dl><?Pub Caret 224?></li>
+<li>Click <uicontrol>Create</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+<?Pub *0000002571?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita
new file mode 100644
index 0000000..d9a32f9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="en-us">
+<title>Storage</title>
+<shortdesc>The <wintitle>Storage</wintitle> page lists the available
+storage pools, including the out of box 'default' and 'ISO' storage pool.
+If you want to use your own ISO, please add it to 'ISO' storage pool path.</shortdesc>
+<csbody>
+<p>For each storage pool, the following information is displayed:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name of the storage pool and percentage used.</dd>
+</dlentry><dlentry>
+<dt>State</dt>
+<dd>State of the storage pool, active (green) or inactive (red). </dd>
+</dlentry><dlentry>
+<dt>Location</dt>
+<dd>File path to the location of the storage pool.</dd>
+</dlentry><dlentry>
+<dt>Type</dt>
+<dd>Type of storage pool, for example, <uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacity</dt>
+<dd>Amount of space in the storage pool.</dd>
+</dlentry><dlentry>
+<dt>Allocated</dt>
+<dd>Amount of space that is already allocated in the storage pool.</dd>
+</dlentry></dl></p>
+<p>The following actions can be selected for each storage pool:<ul>
+<li>Select <uicontrol>Activate</uicontrol> to activate the storage
+pool so that it can be used.</li>
+<li>Select <uicontrol>Deactivate</uicontrol> to deactivate an active
+storage pool.</li>
+<li>Select <uicontrol>Undefine</uicontrol> to remove an inactive storage
+pool.</li>
+</ul></p>
+<p>To display storage volume details for a storage pool, click the
+arrow on the right side of the storage pool row. Details include
+the following:<dl><dlentry>
+<dt>Type</dt>
+<dd>The type of volume, for example, <uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Format</dt>
+<dd>The format, varying dependent on the type.</dd>
+</dlentry><dlentry>
+<dt>Capacity</dt>
+<dd>Size of the storage volume.</dd>
+</dlentry><dlentry>
+<dt>Allocation</dt>
+<dd>Amount of space that is already allocated in the storage pool.</dd>
+</dlentry></dl>To define a storage pool, click the <uicontrol>plus
+(+)</uicontrol> icon in the upper right of the display.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="en-us">
+<title>Define a storage pool</title>
+<shortdesc> Define a storage pool.</shortdesc>
+<csbody>
+<p> <ol>
+<li>In the <uicontrol>Storage pool name</uicontrol> field, type the
+name to be used to identify the storage pool.</li>
+<li>In the <uicontrol>Storage pool type</uicontrol> list, select the
+type: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Specifies a directory pool. When selecting <uicontrol>DIR</uicontrol>,
+type the <uicontrol>Storage path</uicontrol> (file path to the storage
+pool).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Specifies a network filesystem pool. When selecting <uicontrol>NFS</uicontrol>,
+type the <uicontrol>NFS server IP</uicontrol> address and <uicontrol>NFS
+path</uicontrol> (path of the exported directory).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Specifies a pool based on a target allocated on an iSCSI server.
+When selecting <uicontrol>iSCSI</uicontrol>, type the <uicontrol>iSCSI
+server</uicontrol> IP address and <uicontrol>Target</uicontrol> on
+the iSCSI server. You can optionally select to add iSCSI authentication.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logical</uicontrol></dt>
+<dd>Specifies a logical volume storage pool. Select the location to
+the device in <uicontrol>Device path</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
+<dd>Specifies a pool based on an SCSI Fibre Channel. Select which
+SCSI adapter to use.</dd>
+</dlentry></dl><?Pub Caret 0?></li>
+<li>Click <uicontrol>Create</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+<?Pub *0000003914?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita
new file mode 100644
index 0000000..57ee9b5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="en-us">
+<title>Templates</title>
+<shortdesc>The <wintitle>Templates</wintitle> page shows the defined
+virtual machine templates that can be used to create KVM guests.</shortdesc>
+<csbody>
+<p>For each template, the following information is displayed:<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>Name of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Number of processors that are defined for the template.</dd>
+</dlentry><dlentry>
+<dt>Memory</dt>
+<dd>Amount of random access memory to be allocated, in MB.</dd>
+</dlentry></dl></p>
+<p>The following actions can be selected for each template:<ul>
+<li>Select <uicontrol>Edit</uicontrol> to edit the template.</li>
+<li>Select <uicontrol>Delete</uicontrol> to delete the template.</li>
+</ul>To add a template, click the <uicontrol>plus (+)</uicontrol> icon
+in the upper right of the display.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="en-us">
+<title>Edit template</title>
+<shortdesc>Edit an existing template.</shortdesc>
+<csbody>
+<p>For each template, the following information is displayed: <dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name of the template.</dd>
+</dlentry><dlentry>
+<dt>Vendor</dt>
+<dd>The name of the company that created the operating system or distribution
+that the template is configured to use.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>The version of the operating system or distribution that the template
+is configured to use.</dd>
+</dlentry><dlentry>
+<dt>CPU number</dt>
+<dd>Number of processors that are defined for the template.</dd>
+</dlentry><dlentry>
+<dt>Memory</dt>
+<dd>Amount of memory in MB to be allocated to the virtual machine.</dd>
+</dlentry><dlentry>
+<dt>Disk</dt>
+<dd>Disk size in GB.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>File path to the location of the ISO file used to install the
+KVM guest.</dd>
+</dlentry><dlentry>
+<dt>Storage pool</dt>
+<dd>Specific storage pool or the default storage pool.</dd>
+</dlentry><dlentry>
+<dt>Network</dt>
+<dd>Default network interfaces available to the KVM guest. You can
+select multiple networks.</dd>
+</dlentry></dl> Fields that are not disabled can be edited. After
+you edit a field, click <uicontrol>Save</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Add template</title>
+<shortdesc>Add a template from source media.
+You can add your own ISO image to 'ISO' storage pool for following discovery.</shortdesc>
+<csbody>
+<p>Select the location of the source media from the following options:<dl>
+<dlentry>
+<dt>Local ISO image</dt>
+<dd>Select to scan storage pools for installation ISO images available
+on the system.</dd>
+</dlentry><dlentry>
+<dt>Remote ISO image</dt>
+<dd>Select to specify a remote location for an installation ISO image.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Add template - local ISO image</title>
+<shortdesc>Add a template from a local ISO image.</shortdesc>
+<csbody>
+<p>The ISO images available on the system are displayed.<dl><dlentry>
+<dt>OS</dt>
+<dd>Name of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>Size</dt>
+<dd>Size of the ISO image.</dd>
+</dlentry></dl></p>
+<p>To create a template from an ISO image, choose from the following
+options:<ul>
+<li>Select an ISO image from which to create a template, then click <uicontrol>Create
+Templates from Selected ISO</uicontrol>.</li>
+<li>Select <uicontrol>All</uicontrol> to create a template from each
+ listed ISO image, then click <uicontrol>Create Templates from Selected
+ISO</uicontrol>.</li>
+<li>If the ISO image that you want to use does not appear in the scan
+results, you can select from the following options:<ul>
+<li>Select <uicontrol>I want to use a specific ISO file</uicontrol> to
+specify a path to the ISO image.</li>
+<li>Click <uicontrol>Search more ISOs</uicontrol> to search for more
+ISO images.</li>
+</ul></li><?Pub Caret 0?>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+<?Pub *0000004433?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
new file mode 100644
index 0000000..29c596f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+es_ES_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/es_ES
+
+dist_es_ES_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita
new file mode 100644
index 0000000..88e77e0
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="es-es">
+<title>Invitados</title>
+<shortdesc>La página <wintitle>Invitados</wintitle> lista las máquinas virtuales KVM definidas.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente información para cada invitado:<dl><dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la máquina virtual.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Porcentaje de utilización de procesador en la máquina virtual.</dd>
+</dlentry><dlentry>
+<dt>E/S de red</dt>
+<dd>Velocidad de transmisión de entrada/salida de red en KB por segundos.</dd>
+</dlentry><dlentry>
+<dt>E/S de disco</dt>
+<dd>Velocidad de transmisión de entrada/salida de disco en KB por segundos.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>Estado de la consola del sistema operativo invitado, o un icono que representa la distribución de <tm tmtype="tm" trademark="Linux">Linux</tm> si el invitado no está activo.</dd>
+</dlentry></dl></p>
+<p>Se visualizan los siguientes iconos de acciones para cada invitado:<dl>
+<dlentry>
+<dt>Restablecer</dt>
+<dd>Pulse aquà para restablecer el invitado. </dd>
+</dlentry><dlentry>
+<dt>Alimentación (Iniciar o Detener)</dt>
+<dd>Pulse aquà para encender o apagar el invitado. Si el icono es de color rojo, la alimentación está apagada; si el icono es de color verde, la alimentación está encendida.</dd>
+</dlentry></dl> </p>
+<p>Se pueden seleccionar las siguientes acciones para cada invitado:<ul>
+<li>Seleccione <uicontrol>Conectar</uicontrol> para conectarse a la consola remota para el sistema operativo invitado.</li>
+<li>Seleccione <uicontrol>Gestionar soporte</uicontrol> para cambiar la vÃa de acceso al soporte de instalación.</li>
+<li>Seleccione <uicontrol>Restablecer</uicontrol> para restablecer el invitado.</li>
+<li>Seleccione <uicontrol>Editar</uicontrol> para editar las propiedades de un invitado existente. Los invitados sólo pueden editarse mientras están detenidos.</li>
+<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir el invitado.</li>
+</ul>Para crear un invitado o máquina virtual, pulse el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la página.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="es-es">
+<title>Crear máquina virtual</title>
+<shortdesc>Crear una máquina virtual utilizando una plantilla existente.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Escriba el nombre a utilizar para identificar la máquina virtual.</li>
+<li rev="rev1">Seleccione una plantilla. <ul>
+<li>Si existen plantillas, seleccione entre las plantillas mostradas.</li>
+<li>Si no existen plantillas, pulse <uicontrol>Crear una plantilla</uicontrol> para crear una plantilla.</li>
+</ul></li>
+<li>Pulse <uicontrol>Crear</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="es-es">
+<title>Editar invitado</title>
+<shortdesc>Editar las propiedades de una máquina virtual existente. Algunas propiedades pueden editarse sólo cuando el invitado se ha detenido. Otras surtirán efecto en el arranque siguiente.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Se visualiza la siguiente información para cada invitado en la pestaña <wintitle>General</wintitle>:<dl>
+<dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la máquina virtual.(sólo puede editarse cuando el invitado se ha detenido)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Número de procesadores.(si el invitado está en ejecución, la nueva cantidad surtirá efecto en el siguiente arranque)
+</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>Cantidad de memoria en MB.(si el invitado está en ejecución, la nueva cantidad surtirá efecto en el siguiente arranque)
+</dd>
+</dlentry><dlentry>
+<dt>Icono</dt>
+<dd>Imagen gráfica que representa la distribución de Linux a visualizar en lugar del estado actual (Livetile) cuando el invitado no está activo.</dd>
+</dlentry></dl></p>
+<p>Se visualiza la siguiente información en la pestaña <wintitle>Almacenamiento</wintitle>.</p>
+<dl><dlentry>
+<dt>Almacenamiento</dt>
+<dd>Muestra la ubicación del archivo ISO utilizado para la instalación.</dd>
+</dlentry></dl>
+<p> Los campos que no están inhabilitados pueden editarse. Después de editar un campo, pulse <uicontrol>Guardar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="es-es">
+<title>Añadir, sustituir o desconectar un dispositivo de almacenamiento</title>
+<shortdesc rev="rev1">Puede añadir, sustituir o desconectar un dispositivo de almacenamiento a la máquina virtual. El único dispositivo soportado es CDROM. Para editar los dispositivos de almacenamiento, siga estos pasos:</shortdesc>
+<csbody>
+<ol>
+<li>En la ventana <wintitle>Editar invitado</wintitle>, seleccione <wintitle>Almacenamiento</wintitle>.</li>
+<li>Para sustituir un dispositivo de almacenamiento, pulse el primer icono con la <uicontrol>barra inclinada naranja (/)</uicontrol>. Especifique la vÃa de acceso del archivo ISO y pulse <uicontrol>Sustituir</uicontrol>.</li>
+<li>Para desconectar un dispositivo de almacenamiento, pulse el segundo icono con el <uicontrol>guión rojo (-)</uicontrol>. Confirme la supresión y pulse <uicontrol>Aceptar</uicontrol>.</li>
+<li>Para añadir un dispositivo de almacenamiento, pulse el tercer icono con el <uicontrol>signo más (+)</uicontrol> verde. Especifique un nombre de dispositivo y la vÃa de acceso del archivo ISO y pulse <uicontrol>Conectar</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="es-es">
+<title>Sustituir un CDROM de máquina virtual</title>
+<shortdesc rev="rev1">Puede sustituir el contenido del CDROM para una máquina virtual después de completarse la instalación.</shortdesc>
+<csbody>
+<ol>
+<li>Asegúrese de que la máquina virtual se ha iniciado.</li>
+<li>En el menú Acciones, seleccione <uicontrol>Gestionar soporte</uicontrol>.</li>
+<li>Para cambiar lo que está cargado actualmente en el CDROM, pulse el icono <uicontrol>barra inclinada naranja (/)</uicontrol> junto al campo hdc.</li>
+<li>En la página <wintitle>Sustituir un CDROM de máquina virtual</wintitle>, especifique la vÃa de acceso del archivo ISO. Los otros dos campos son de sólo lectura.</li>
+<li>Pulse <uicontrol>Sustituir</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita b/src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita
new file mode 100644
index 0000000..7734244
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="es-es">
+<title>Host</title>
+<shortdesc>La página <wintitle>Host</wintitle> muestra información sobre el sistema host y le permite concluir, reiniciar y conectar con el sistema principal.</shortdesc>
+<csbody>
+<p>Puede realizar las acciones siguientes en el host:<ul>
+<li>Seleccione <uicontrol>Concluir</uicontrol> para concluir el sistema host.</li>
+<li>Seleccione <uicontrol>Reiniciar</uicontrol> para reiniciar el sistema host.</li>
+<li>Seleccione <uicontrol>Conectar</uicontrol> para abrir una conexión VNC al sistema host, si no está conectado aún.</li>
+</ul></p>
+<p>Pulse en las secciones siguientes para visualizar información acerca del host:<dl>
+<dlentry>
+<dt>Información básica</dt>
+<dd>Esta sección muestra la distribución del sistema operativo de host, la versión y el nombre de código, asà como el tipo de procesador y la cantidad de memoria en GB.</dd>
+</dlentry><dlentry>
+<dt>EstadÃsticas del sistema</dt>
+<dd>Esta sección muestra gráficos para mostrar estadÃsticas para CPU, memoria, E/S de disco y E/S de red para el host. Seleccione <uicontrol>Recoger datos después de salir de esta página</uicontrol> para continuar la recogida de datos cuando la pestaña principal ya no está a la vista.</dd>
+</dlentry><dlentry>
+<dt>Actualizaciones de software</dt>
+<dd>En esta sección se muestra información para todos los paquetes que tienen actualizaciones disponibles, incluido el nombre de paquete, versión, arquitectura y repositorio. Puede actualizar todos los paquetes listados seleccionando <uicontrol>Actualizar todo</uicontrol>. No puede seleccionar paquetes individuales para las actualizaciones.</dd>
+</dlentry><dlentry>
+<dt>Repositorios</dt>
+<dd>En esta sección se muestran los repositorios que están asociados con el sistema host. Puede añadir, habilitar, editar o eliminar repositorios. Añadir un repositorio lo asocia con el sistema host mientras que habilitar un repositorio permite que el host acceda a él. Si el sistema es Red Hat Enterprise
+Linux o Fedora, puede añadir repositorios <filepath>yum</filepath>.
+Si el sistema es Ubuntu o Debian, añada repositorios <filepath>deb</filepath>.<p>Si está trabajando con repositorios yum, puede añadir una comprobación GPG para verificar que un paquete de este repositorio no ha resultado dañado.
+Seleccione un repositorio y, a continuación, <uicontrol>Editar</uicontrol>. Seleccione <uicontrol>SÃ</uicontrol> para habilitar la comprobación GPG y, a continuación, especifique un URL al archivo de claves GPG para el repositorio.</p></dd>
+</dlentry><dlentry>
+<dt>Informes de depuración</dt>
+<dd>En esta sección se muestran informes de depuración, incluido el nombre y la ruta de archivo.
+Puede seleccionar entre opciones para generar un informe nuevo, o bien redenominar, eliminar o descargar un informe existente.<p>El informe de depuración se genera utilizando el mandato <cmdname>sosreport</cmdname>. Está disponible para distribuciones de Red
+Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora y Ubuntu. El mandato genera un archivo .tar que contiene la información de configuración y de diagnóstico, como la versión de kernel en ejecución, los módulos de carga y los archivos de configuración del sistema y servicio.
+El mandato también ejecuta programas externos para recopilar información adicional y almacena esta salida en el archivo resultante.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita b/src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita
new file mode 100644
index 0000000..3654531
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="es-es">
+<title>Red</title>
+<shortdesc>La página <wintitle>Red</wintitle> muestra información sobre la conexión de red.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nombre de red</dt>
+<dd>Nombre de la red, o <uicontrol>predeterminado</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado de la red, activa (verde) o inactiva (rojo). </dd>
+</dlentry><dlentry>
+<dt>Tipo de red</dt>
+<dd>Tipo de red, por ejemplo, <uicontrol>NAT</uicontrol> (conversión de direcciones de red).</dd>
+</dlentry><dlentry>
+<dt>Interfaz</dt>
+<dd>La interfaz de red, por ejemplo, <uicontrol>virbr0</uicontrol> (predeterminada).</dd>
+</dlentry><dlentry>
+<dt>Espacio de direcciones</dt>
+<dd>Dirección IP.</dd>
+</dlentry></dl></p>
+<p>Se pueden seleccionar las siguientes acciones:<ul>
+<li rev="rev1">Seleccione <uicontrol>Iniciar</uicontrol> para iniciar la conexión de red.</li>
+<li>Seleccione <uicontrol>Detener</uicontrol> para finalizar la conexión de red.</li>
+<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la información de conexión.</li>
+</ul>Para crear una red, pulse en el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="es-es">
+<title>Crear una red</title>
+<shortdesc>Crear una red.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Escriba el nombre de la red.</li>
+<li>Pulse para seleccionar el tipo de red. <dl rev="rev1"><dlentry>
+<dt><uicontrol>Aislada</uicontrol></dt>
+<dd>Modalidad aislada. Los invitados no pueden enviar ni recibir comunicación a sistemas externos o desde ellos.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Modalidad de Conversión de direcciones de red. La comunicación de invitados a sistemas externos utiliza la dirección IP del host. Los sistemas externos no pueden iniciar la comunicación con los invitados.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Puenteada</uicontrol></dt>
+<dd>Modalidad puenteada. Los invitados pueden comunicarse con sistemas externos y ser contactados por sistemas externos como si fueran sistemas fÃsicos en la red. Para la modalidad puenteada, debe especificar información de destino y VLAN adicional.</dd>
+</dlentry></dl></li>
+<li>Pulse <uicontrol>Crear</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita
new file mode 100644
index 0000000..0c68951
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="es-es">
+<title>Almacenamiento</title>
+<shortdesc>La página <wintitle>Almacenamiento</wintitle> lista las agrupaciones de almacenamiento disponibles, incluyendo la agrupación de almacenamiento predefinida 'default' e 'ISO'.
+Si desea utilizar su propia ISO, añádala a la vÃa de acceso de la agrupación de almacenamiento 'ISO'.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente información para cada agrupación de almacenamiento:<dl>
+<dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la agrupación de almacenamiento y el porcentaje utilizado.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado de la agrupación de almacenamiento, activa (verde) o inactiva (rojo). </dd>
+</dlentry><dlentry>
+<dt>Ubicación</dt>
+<dd>VÃa de acceso de archivo a la ubicación de la agrupación de almacenamiento.</dd>
+</dlentry><dlentry>
+<dt>Tipo</dt>
+<dd>Tipo de agrupación de almacenamiento, por ejemplo, <uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacidad</dt>
+<dd>Cantidad de espacio en la agrupación de almacenamiento.</dd>
+</dlentry><dlentry>
+<dt>Asignado</dt>
+<dd>Cantidad de espacio que ya está asignado en la agrupación de almacenamiento.</dd>
+</dlentry></dl></p>
+<p>Se pueden seleccionar las siguientes acciones para cada agrupación de almacenamiento:<ul>
+<li>Seleccione <uicontrol>Activar</uicontrol> para activar la agrupación de almacenamiento para que pueda utilizarse.</li>
+<li>Seleccione <uicontrol>Desactivar</uicontrol> para desactivar una agrupación de almacenamiento activa.</li>
+<li>Seleccione <uicontrol>No definir</uicontrol> para eliminar una agrupación de almacenamiento inactiva.</li>
+</ul></p>
+<p>Para visualizar detalles de volumen de almacenamiento para una agrupación de almacenamiento, pulse la flecha situada en el lado derecho de la fila de agrupación de almacenamiento. Los detalles incluyen lo siguiente:<dl><dlentry>
+<dt>Tipo</dt>
+<dd>El tipo de volumen, por ejemplo, <uicontrol>archivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Formato</dt>
+<dd>El formato, variable dependiendo del tipo.</dd>
+</dlentry><dlentry>
+<dt>Capacidad</dt>
+<dd>Tamaño del volumen de almacenamiento.</dd>
+</dlentry><dlentry>
+<dt>Asignación</dt>
+<dd>Cantidad de espacio que ya está asignado en la agrupación de almacenamiento.</dd>
+</dlentry></dl>Para definir una agrupación de almacenamiento, pulse en el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="es-es">
+<title>Definir una agrupación de almacenamiento</title>
+<shortdesc> Definir una agrupación de almacenamiento.</shortdesc>
+<csbody>
+<p> <ol>
+<li>En el campo <uicontrol>Nombre de agrupación de almacenamiento</uicontrol>, escriba el nombre que se utilizará para identificar la agrupación de almacenamiento.</li>
+<li>En la lista <uicontrol>Tipo de agrupación almacenamiento</uicontrol>, seleccione el tipo: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Especifica una agrupación de directorio. Al seleccionar <uicontrol>DIR</uicontrol>, escriba la <uicontrol>VÃa de acceso de almacenamiento</uicontrol> (vÃa de acceso de archivo a la agrupación de almacenamiento).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Especifica una agrupación de sistema de archivos de red. Al seleccionar <uicontrol>NFS</uicontrol>, escriba la dirección <uicontrol>IP de servidor NFS</uicontrol> y <uicontrol>vÃa de acceso de NFS</uicontrol> (vÃa de acceso del directorio exportado).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Especifica una agrupación basada en un destino asignado en un servidor iSCSI.
+Al seleccionar <uicontrol>iSCSI</uicontrol>, escriba la dirección IP del <uicontrol>Servidor iSCSI</uicontrol> y el <uicontrol>Destino</uicontrol> en el servidor iSCSI. Opcionalmente puede seleccionar añadir autenticación iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Lógico</uicontrol></dt>
+<dd>Especifica una agrupación de almacenamiento de volumen lógico. Seleccione la ubicación al dispositivo en <uicontrol>VÃa de acceso de dispositivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Canal de fibra de SCSI</uicontrol></dt>
+<dd>Especifica una agrupación basada en un Canal de fibra SCSI. Seleccione qué adaptador SCSI se utilizará.</dd>
+</dlentry></dl></li>
+<li>Pulse <uicontrol>Crear</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita
new file mode 100644
index 0000000..8cceee7
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="es-es">
+<title>Plantillas</title>
+<shortdesc>La página <wintitle>Plantillas</wintitle> muestra las plantillas de máquina virtual definidas que se pueden utilizar para crear invitados KVM.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente información para cada plantilla:<dl>
+<dlentry>
+<dt>SO</dt>
+<dd>Nombre del sistema operativo o distribución.</dd>
+</dlentry><dlentry>
+<dt>Versión</dt>
+<dd>Versión del sistema operativo o distribución.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Número de procesadores que están definidos para la plantilla.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>Cantidad de memoria de acceso aleatorio a asignar, en MB.</dd>
+</dlentry></dl></p>
+<p>Se pueden seleccionar las siguientes acciones para cada plantilla:<ul>
+<li>Seleccione <uicontrol>Editar</uicontrol> para editar la plantilla.</li>
+<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la plantilla.</li>
+</ul>Para añadir una plantilla, pulse en el icono <uicontrol>más (+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="es-es">
+<title>Editar plantilla</title>
+<shortdesc>Editar una plantilla existente.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente información para cada plantilla: <dl>
+<dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la plantilla.</dd>
+</dlentry><dlentry>
+<dt>Proveedor</dt>
+<dd>El nombre de la empresa que creó el sistema operativo o distribución que la plantilla está configurada para utilizar.</dd>
+</dlentry><dlentry>
+<dt>Versión</dt>
+<dd>La versión del sistema operativo o distribución que la plantilla está configurada para utilizar.</dd>
+</dlentry><dlentry>
+<dt>Número de CPU</dt>
+<dd>Número de procesadores que están definidos para la plantilla.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>Cantidad de memoria en MB a asignar a la máquina virtual.</dd>
+</dlentry><dlentry>
+<dt>Disco</dt>
+<dd>Tamaño de disco en GB.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>VÃa de acceso de archivo a la ubicación del archivo ISO utilizado para instalar el invitado KVM.</dd>
+</dlentry><dlentry>
+<dt>Agrupación de almacenamiento</dt>
+<dd>Agrupación de almacenamiento especÃfica o la agrupación de almacenamiento predeterminada.</dd>
+</dlentry><dlentry>
+<dt>Red</dt>
+<dd>Interfaces de red predeterminadas disponibles para el invitado KVM. Puede seleccionar varias redes.</dd>
+</dlentry></dl> Los campos que no están inhabilitados pueden editarse. Después de editar un campo, pulse <uicontrol>Guardar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Añadir plantilla</title>
+<shortdesc>Añadir una plantilla desde el soporte de origen. Puede añadir su propia imagen ISO a la agrupación de almacenamiento 'ISO' para el siguiente descubrimiento.</shortdesc>
+<csbody>
+<p>Seleccione la ubicación del soporte de origen entre una de las opciones siguientes:<dl>
+<dlentry>
+<dt>Imagen ISO local</dt>
+<dd>Seleccione esta opción para explorar las agrupaciones de almacenamiento en busca de imágenes ISO de instalación disponibles en el sistema.</dd>
+</dlentry><dlentry>
+<dt>Imagen ISO remota</dt>
+<dd>Seleccione esta opción para especificar una ubicación remota para una imagen ISO de instalación.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Añadir plantilla â imagen ISO local</title>
+<shortdesc>Añadir una plantilla desde una imagen ISO local.</shortdesc>
+<csbody>
+<p>Se visualizan las imágenes ISO disponibles en el sistema.<dl><dlentry>
+<dt>SO</dt>
+<dd>Nombre del sistema operativo o distribución.</dd>
+</dlentry><dlentry>
+<dt>Versión</dt>
+<dd>Versión del sistema operativo o distribución.</dd>
+</dlentry><dlentry>
+<dt>Tamaño</dt>
+<dd>Tamaño de la imagen ISO.</dd>
+</dlentry></dl></p>
+<p>Para crear una plantilla a partir de una imagen ISO, elija entre las opciones siguientes:<ul>
+<li>Seleccione una imagen ISO desde la que desea crear una plantilla y, a continuación, pulse <uicontrol>Crear plantillas desde ISO seleccionada</uicontrol>.</li>
+<li>Seleccione <uicontrol>Todo</uicontrol> para crear una plantilla desde cada imagen ISO en la lista y, a continuación, pulse <uicontrol>Crear plantillas desde ISO seleccionada</uicontrol>.</li>
+<li>Si la imagen ISO que desea utilizar no aparece en los resultados de la exploración, puede seleccionar entre las opciones siguientes:<ul>
+<li>Seleccione <uicontrol>Deseo utilizar un archivo ISO especÃfico</uicontrol> para especificar una vÃa de acceso a la imagen ISO.</li>
+<li>Pulse <uicontrol>Buscar más ISO</uicontrol> para buscar más imágenes ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
new file mode 100644
index 0000000..11ce394
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+fr_FR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/fr_FR
+
+dist_fr_FR_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
new file mode 100644
index 0000000..ad5b4e4
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="fr-fr">
+<title>Invités</title>
+<shortdesc>La page <wintitle>Invités</wintitle> répertorie les machines virtuelles KVM définies.</shortdesc>
+<csbody>
+<p>Pour chaque invité, les informations suivantes sont affichées :<dl><dlentry>
+<dt>Nom</dt>
+<dd>Nom de la machine virtuelle.</dd>
+</dlentry><dlentry>
+<dt>UC</dt>
+<dd>Pourcentage d'utilisation du processeur sur la machine virtuelle.</dd>
+</dlentry><dlentry>
+<dt>E-S réseau</dt>
+<dd>Vitesse de transmission d'entrée-sortie du réseau, exprimée en ko par seconde.</dd>
+</dlentry><dlentry>
+<dt>E-S disque</dt>
+<dd>Vitesse de transmission d'entrée-sortie du disque, exprimée en ko par seconde.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>Etat de la console du système d'exploitation de l'hôte, ou
+icône représentant la distribution <tm tmtype="tm" trademark="Linux">Linux</tm>
+si l'invité n'est pas actif.</dd>
+</dlentry></dl></p>
+<p>Les icônes d'action suivantes sont affichées pour chaque invité :<dl>
+<dlentry>
+<dt>Réinitialiser</dt>
+<dd>Cliquez pour réinitialiser l'invité. </dd>
+</dlentry><dlentry>
+<dt>Alimentation (Démarrer ou Arrêter)</dt>
+<dd>Cliquez pour mettre sous ou hors tension l'invité. Si l'icône est rouge,
+l'alimentation est démarrée ; si l'icône est verte, l'alimentation est arrêtée.</dd>
+</dlentry></dl> </p>
+<p>Les actions suivantes peuvent être sélectionnées pour chaque invité :<ul>
+<li>Sélectionnez <uicontrol>Connexion</uicontrol> pour vous connecter à la console
+distante du système d'exploitation invité.</li>
+<li>Sélectionnez <uicontrol>Gérer le support</uicontrol> pour modifier le chemin
+d'accès au support d'installation.</li>
+<li>Sélectionnez <uicontrol>Réinitialiser</uicontrol> pour réinitialiser l'invité.</li>
+<li>Sélectionnez <uicontrol>Editer</uicontrol> pour éditer les propriétés d'un invité existant. Les invités peuvent être édités uniquement lorsqu'ils sont à l'arrêt.</li>
+<li>Sélectionnez <uicontrol>Supprimer</uicontrol> pour supprimer l'invité.</li>
+</ul>Pour créer un invité, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
+dans le coin supérieur droit de la page.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="fr-fr">
+<title>Créer une machine virtuelle</title>
+<shortdesc>Créez une machine virtuelle en utilisant un modèle existant.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Entrez le nom à utiliser pour identifier la machine virtuelle.</li>
+<li rev="rev1">Sélectionnez un modèle. <ul>
+<li>Si des modèles existent, faites un choix parmi les modèles affichés.</li>
+<li>Si aucun modèle n'existe, cliquez sur <uicontrol>Créer un modèle</uicontrol> pour créer un modèle.</li>
+</ul></li>
+<li>Cliquez sur <uicontrol>Créer</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="fr-fr">
+<title>Editer l'invité</title>
+<shortdesc>Editez les propriétés d'une machine virtuelle existante. Certaines propriétés
+peuvent être éditées uniquement lorsque l'invité est arrêté. D'autres seront appliquées à l'amorçage suivant.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Pour chaque invité, les informations suivantes sont affichées dans l'onglet <wintitle>Général</wintitle> :<dl>
+<dlentry>
+<dt>Nom</dt>
+<dd>Nom de la machine virtuelle. (Ne peut être édité que lorsque l'invité est arrêté)</dd>
+</dlentry><dlentry>
+<dt>UC</dt>
+<dd>Nombre de processeurs. (Si l'invité est en cours d'exécution, la nouvelle quantité sera appliquée à l'amorçage suivant)</dd>
+</dlentry><dlentry>
+<dt>Mémoire</dt>
+<dd>Quantité de mémoire en Mo. (Si l'invité est en cours d'exécution, la nouvelle quantité sera appliquée à l'amorçage suivant)</dd>
+</dlentry><dlentry>
+<dt>Icône</dt>
+<dd>Image graphique représentant la distribution Linux à afficher à la place
+du statut en cours (Livetile) lorsque l'invité n'est pas actif.</dd>
+</dlentry></dl></p>
+<p>Les informations suivantes sont affichées dans l'onglet <wintitle>Stockage</wintitle>.</p>
+<dl><dlentry>
+<dt>Stockage</dt>
+<dd>Affiche l'emplacement du fichier ISO utilisé pour l'installation.</dd>
+</dlentry></dl>
+<p> Les zones qui ne sont pas désactivées peuvent être éditées. Après que vous avez édité une zone, cliquez sur <uicontrol>Sauvegarder</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="fr-fr">
+<title>Ajoutez, remplacez ou détachez une unité de stockage</title>
+<shortdesc rev="rev1">Vous pouvez ajouter, remplacer ou détacher une unité de stockage
+pour votre machine virtuelle. Seule une unité CD-ROM est prise en charge. Pour éditer vos unités de stockage, procédez comme suit :</shortdesc>
+<csbody>
+<ol>
+<li>Dans la fenêtre <wintitle>Editer l'invité</wintitle>, sélectionnez <wintitle>Stockage</wintitle>.</li>
+<li>Pour remplacer une unité de stockage, cliquez sur la première icône avec la <uicontrol>barre oblique (/) orange</uicontrol>. Entrez le chemin d'accès au fichier ISO et cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
+<li>Pour détacher une unité de stockage, cliquez sur la deuxième icône avec le <uicontrol>tiret (-) rouge</uicontrol>. Confirmer la suppression et cliquez sur <uicontrol>OK</uicontrol>.</li>
+<li>Pour ajouter une unité de stockage, cliquez sur la troisième icône avec le <uicontrol>signe plus (+) vert</uicontrol>. Entrez un nom d'unité et un chemin d'accès au fichier ISO puis cliquez sur <uicontrol>Attacher</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="fr-fr">
+<title>Remplacer l'unité CD-ROM d'une machine virtuelle</title>
+<shortdesc rev="rev1">Vous pouvez remplacer le contenu du CD-ROM pour
+une machine virtuelle une fois l'installation terminée.</shortdesc>
+<csbody>
+<ol>
+<li>Vérifiez que la machine virtuelle est démarrée.</li>
+<li>Dans le menu Actions, sélectionnez <uicontrol>Gérer le support</uicontrol>.</li>
+<li>Pour modifier les données actuellement chargées dans l'unité de CD-ROM, cliquez sur l'icône
+<uicontrol>barre oblique (/) orange</uicontrol> en regard de la zone hdc.</li>
+<li>Sur la page <wintitle>Remplacer une unité CD-ROM d'une machine virtuelle</wintitle>,
+entrez le chemin d'accès au fichier ISO. Les deux autres zones sont en lecture seule.</li>
+<li>Cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita
new file mode 100644
index 0000000..f4c330b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="fr-fr">
+<title>Hôte</title>
+<shortdesc>La page <wintitle>Hôte</wintitle> affiche des informations
+sur le système hôte et vous permet d'arrêter, de redémarrer et de vous
+connecter à l'hôte.</shortdesc>
+<csbody>
+<p>Vous pouvez effectuer les actions suivantes sur l'hôte :<ul>
+<li>Sélectionnez <uicontrol>Arrêter</uicontrol> pour arrêter le système hôte.</li>
+<li>Sélectionnez <uicontrol>Redémarrer</uicontrol> pour redémarrer le système hôte.</li>
+<li>Sélectionnez <uicontrol>Connexion</uicontrol> pour ouvrir une connexion VNC
+au système hôte, si celui-ci n'est pas déjà connecté.</li>
+</ul></p>
+<p>Cliquez sur les sections suivantes pour afficher des informations sur l'hôte :<dl>
+<dlentry>
+<dt>Informations de base</dt>
+<dd>Cette section affiche la distribution, la version et le nom de code
+du système d'exploitation hôte, ainsi que le type de processeur et la quantité
+de mémoire en Go.</dd>
+</dlentry><dlentry>
+<dt>Statistiques système</dt>
+<dd>Cette section affiche les graphiques des statistiques pour l'UC, mémoire, ainsi que
+les E-S disque et E-S réseau pour l'hôte. Sélectionnez <uicontrol>Collecte des données une fois la page quittée</uicontrol>
+pour continuer la collecte de données lorsque l'onglet hôte n'est plus visible.</dd>
+</dlentry><dlentry>
+<dt>Mises à jour logicielles</dt>
+<dd>Cette section affiche des informations pour tous les modules qui
+disposent de mises à jour disponibles, y compris le nom de module, la version, l'architecture
+et le référentiel. Vous pouvez mettre à jour toutes les modules répertoriés en sélectionnant <uicontrol>Tout
+mettre à jour</uicontrol>. Vous ne pouvez pas sélectionner des modules individuels pour les mises à jour.</dd>
+</dlentry><dlentry>
+<dt>Référentiels</dt>
+<dd>Cette section affiche les référentiels associés au système hôte. Vous pouvez ajouter, activer, éditer ou retirer des référentiels. L'ajout d'un référentiel associe celui-ci au système hôte,
+tandis que l'activation d'un référentiel permet à l'hôte d'y accéder. Si votre système est Red Hat Enterprise Linux ou Fedora,
+vous pouvez ajouter des référentiels <filepath>yum</filepath>.
+Si votre système est de type Ubuntu ou Debian, ajoutez des référentiels
+<filepath>deb</filepath>.<p>Si vous travaillez avec des référentiels yum, vous pouvez ajouter un contrôle GPG
+afin de vérifier qu'un module provenant de ce référentiel n'a pas été endommagé.
+Sélectionnez un référentiel puis cliquez sur <uicontrol>Editer</uicontrol>. Sélectionnez <uicontrol>Oui</uicontrol> pour activer le contrôle GPG,
+puis entrez une URL pour le fichier de clés GPG du référentiel.</p></dd>
+</dlentry><dlentry>
+<dt>Rapports de débogage</dt>
+<dd>Cette section affiche les rapports de débogage, y compris le nom et le chemin du fichier.
+Vous pouvez faire un choix parmi les options afin de générer un nouveau rapport, ou renommer, supprimer,
+ou télécharger un rapport existant.<p>Le rapport de débogage est généré Ã
+l'aide de la commande <cmdname>sosreport</cmdname>. Cette option est disponible pour les distributions
+Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora et Ubuntu. La commande génère un fichier .tar contenant la configuration et des informations de diagnostic,
+telles que la version du noyau d'exécution, les modules chargés, ainsi que les fichiers de configuration
+du système et de la maintenance.
+La commande exécute également des programmes externes pour collecter des informations
+supplémentaires et stocke cette sortie dans l'archive résultante.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita
new file mode 100644
index 0000000..5c2e9dd
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="fr-fr">
+<title>Réseau</title>
+<shortdesc>La page <wintitle>Réseau</wintitle> affiche des informations sur la connexion réseau.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nom du réseau</dt>
+<dd>Nom du réseau, ou <uicontrol>par défaut</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Etat</dt>
+<dd>Etat du réseau, actif (vert) ou inactif (rouge). </dd>
+</dlentry><dlentry>
+<dt>Type de réseau</dt>
+<dd>Type du réseau, par exemple <uicontrol>NAT</uicontrol> (conversion d'adresses réseau).</dd>
+</dlentry><dlentry>
+<dt>Interface</dt>
+<dd>Interface réseau, par exemple <uicontrol>virbr0</uicontrol> (par défaut).</dd>
+</dlentry><dlentry>
+<dt>Espace adresse</dt>
+<dd>Adresse IP.</dd>
+</dlentry></dl></p>
+<p>Les actions suivantes peuvent être sélectionnées :<ul>
+<li rev="rev1">Sélectionnez <uicontrol>Démarrer</uicontrol> pour démarrer la connexion au réseau.</li>
+<li>Sélectionnez <uicontrol>Arrêter</uicontrol> pour mettre fin à la connexion au réseau.</li>
+<li>Sélectionnez <uicontrol>Supprimer</uicontrol> pour supprimer les informations de connexion.</li>
+</ul>Pour créer un réseau, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
+dans le coin supérieur droit de l'écran.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="fr-fr">
+<title>Créer un réseau</title>
+<shortdesc>Créez un réseau.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Entrez le nom du réseau.</li>
+<li>Cliquez pour sélectionner le type de réseau. <dl rev="rev1"><dlentry>
+<dt><uicontrol>Isolé</uicontrol></dt>
+<dd>Mode isolé. Les invités ne peuvent pas envoyer ni recevoir de communication avec des systèmes externes.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Mode de conversion d'adresses réseau. La communication à partir d'invités
+vers des systèmes externes utilise l'adresse IP hôte. Les systèmes externes ne
+peuvent pas initier de communication vers les invités.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Routé</uicontrol></dt>
+<dd>Mode routé. Les invités peuvent communiquer avec des systèmes externes et
+être contactés par des systèmes externes comme s'il s'agissait de systèmes physiques
+sur le réseau. Pour le mode routé, vous devez spécifier des informations supplémentaires
+sur la destination et le réseau local virtuel.</dd>
+</dlentry></dl></li>
+<li>Cliquez sur <uicontrol>Créer</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
new file mode 100644
index 0000000..eebf2bb
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="fr-fr">
+<title>Stockage</title>
+<shortdesc>La page <wintitle>Stockage</wintitle> répertorie les pools de stockage disponibles,
+y compris les pools de stockage 'default' et 'ISO' prêts à l'emploi.
+Si vous souhaitez utiliser votre propre pool de stockage ISO, ajoutez-le dans le chemin du pool de stockage 'ISO'.</shortdesc>
+<csbody>
+<p>Pour chaque pool de stockage, les informations suivantes sont affichées :<dl>
+<dlentry>
+<dt>Nom</dt>
+<dd>Nom du pool de stockage et pourcentage d'utilisation.</dd>
+</dlentry><dlentry>
+<dt>Etat</dt>
+<dd>Etat du pool de stockage, actif (vert) ou inactif (rouge). </dd>
+</dlentry><dlentry>
+<dt>Emplacement</dt>
+<dd>chemin d'accès au fichier pour l'emplacement du pool de stockage.</dd>
+</dlentry><dlentry>
+<dt>Type</dt>
+<dd>Type de pool de stockage, par exemple <uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacité</dt>
+<dd>Quantité d'espace dans le pool de stockage.</dd>
+</dlentry><dlentry>
+<dt>Alloué</dt>
+<dd>Quantité d'espace déjà allouée dans le pool de stockage.</dd>
+</dlentry></dl></p>
+<p>Les actions suivantes peuvent être sélectionnées pour chaque pool de stockage :<ul>
+<li>Sélectionnez <uicontrol>Activer</uicontrol> pour activer le pool de stockage pour utilisation.</li>
+<li>Sélectionnez <uicontrol>Désactiver</uicontrol> pour désactiver un pool de stockage actif.</li>
+<li>Sélectionnez <uicontrol>Annuler définition</uicontrol> pour retirer un pool de stockage inactif.</li>
+</ul></p>
+<p>Pour afficher les détails de volume de stockage pour un pool de stockage, cliquez sur la
+flèche située à droite de la ligne du pool de stockage. Détails inclus :<dl><dlentry>
+<dt>Type</dt>
+<dd>Type de volume, par exemple <uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Format</dt>
+<dd>Format, variable selon le type.</dd>
+</dlentry><dlentry>
+<dt>Capacité</dt>
+<dd>Taille du volume de stockage.</dd>
+</dlentry><dlentry>
+<dt>Allocation</dt>
+<dd>Quantité d'espace déjà allouée dans le pool de stockage.</dd>
+</dlentry></dl>Pour définir un pool de stockage, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
+dans le coin supérieur droit de l'écran.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="fr-fr">
+<title>Définir un pool de stockage</title>
+<shortdesc> Définissez un pool de stockage.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Dans la zone <uicontrol>Nom du pool de stockage</uicontrol>, entrez le nom à utiliser pour identifier le pool de stockage.</li>
+<li>Dans la zone <uicontrol>Type de pool de stockage</uicontrol>, sélectionnez le type : <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Indique un pool de répertoires. Lorsque vous sélectionnez <uicontrol>DIR</uicontrol>,
+indiquez le <uicontrol>Chemin de stockage</uicontrol> (chemin d'accès au fichier
+du pool de stockage).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>indique un pool de systèmes de fichiers réseau. Lorsque vous sélectionnez <uicontrol>NFS</uicontrol>,
+indiquez l'adresse <uicontrol>IP du serveur NFS</uicontrol> et le <uicontrol>Chemin NFS</uicontrol> (chemin d'accès au répertoire d'exportation).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Indique un pool basé sur une cible allouée sur un serveur iSCSI.
+Lorsque vous sélectionnez <uicontrol>iSCSI</uicontrol>, indiquez l'adresse IP du <uicontrol>Serveur iSCSI</uicontrol>
+et la <uicontrol>Cible</uicontrol> sur le serveur iSCSI. Vous avez la possibilité d'ajouter l'authentification iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logique</uicontrol></dt>
+<dd>Indique un pool de stockage de volumes logiques. Sélectionnez l'emplacement de l'unité dans <uicontrol>Chemin d'unité</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
+<dd>Indique un pool basée sur une connexion Fibre Channel SCSI. Sélectionnez l'adaptateur SCSI à utiliser.</dd>
+</dlentry></dl></li>
+<li>Cliquez sur <uicontrol>Créer</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
new file mode 100644
index 0000000..a517e33
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="fr-fr">
+<title>Modèles</title>
+<shortdesc>La page <wintitle>Modèles</wintitle> affiche les modèles de machine virtuelle définis
+pouvant être utilisés pour créer des hôtes KVM.</shortdesc>
+<csbody>
+<p>Pour chaque modèle, les informations suivantes sont affichées :<dl>
+<dlentry>
+<dt>SE</dt>
+<dd>Nom du système d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version du système d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>UC</dt>
+<dd>Nombre de processeurs définis pour le modèle.</dd>
+</dlentry><dlentry>
+<dt>Mémoire</dt>
+<dd>Quantité de mémoire vive à allouer, en Mo.</dd>
+</dlentry></dl></p>
+<p>Les actions suivantes peuvent être sélectionnées pour chaque modèle :<ul>
+<li>Sélectionnez <uicontrol>Editer</uicontrol> pour éditer le modèle.</li>
+<li>Sélectionnez <uicontrol>Supprimer</uicontrol> pour supprimer le modèle.</li>
+</ul>Pour ajouter un modèle, cliquez sur l'icône <uicontrol>plus (+)</uicontrol>
+dans le coin supérieur droit de l'écran.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="fr-fr">
+<title>Editer un modèle</title>
+<shortdesc>Editez un modèle existant.</shortdesc>
+<csbody>
+<p>Pour chaque modèle, les informations suivantes sont affichées : <dl>
+<dlentry>
+<dt>Nom</dt>
+<dd>Nom du modèle.</dd>
+</dlentry><dlentry>
+<dt>Fournisseur</dt>
+<dd>Nom de la société qui a créé le système d'exploitation ou la distribution
+pour lequel/laquelle le modèle est configuré.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version du système d'exploitation ou de la distribution
+pour lequel/laquelle le modèle est configuré.</dd>
+</dlentry><dlentry>
+<dt>Nombre d'UC</dt>
+<dd>Nombre de processeurs définis pour le modèle.</dd>
+</dlentry><dlentry>
+<dt>Mémoire</dt>
+<dd>Quantité de mémoire en Mo à allouer à la machine virtuelle.</dd>
+</dlentry><dlentry>
+<dt>Disque</dt>
+<dd>Taille du disque en Go.</dd>
+</dlentry><dlentry>
+<dt>CD-ROM</dt>
+<dd>chemin d'accès au fichier pour l'emplacement du fichier ISO utilisé pour l'installation de l'invité KVM.</dd>
+</dlentry><dlentry>
+<dt>Pool de stockage</dt>
+<dd>Pool de stockage spécifique ou pool de stockage par défaut.</dd>
+</dlentry><dlentry>
+<dt>Réseau</dt>
+<dd>Interfaces réseau par défaut disponibles pour l'invité KVM. Vous pouvez
+sélectionner plusieurs réseaux.</dd>
+</dlentry></dl> Les zones qui ne sont pas désactivées peuvent être éditées. Après que vous avez édité une zone, cliquez sur <uicontrol>Sauvegarder</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Ajouter un modèle</title>
+<shortdesc>Ajoutez un modèle à partir du support source.
+Vous pouvez ajouter votre propre image ISO au pool de stockage 'ISO' pour la reconnaissance suivante.</shortdesc>
+<csbody>
+<p>Sélectionnez l'emplacement du support source à partir des options suivantes :<dl>
+<dlentry>
+<dt>Image ISO locale</dt>
+<dd>Sélectionnez cette option pour rechercher dans les pools de stockage l'image d'installation ISO disponible sur le système.</dd>
+</dlentry><dlentry>
+<dt>Image ISO distante</dt>
+<dd>Sélectionnez cette option pour indiquer un emplacement distant pour une image d'installation ISO.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Ajouter un modèle - Image ISO locale</title>
+<shortdesc>Ajoutez un modèle à partir d'une image ISO locale.</shortdesc>
+<csbody>
+<p>Les images ISO disponibles sur le système sont affichées.<dl><dlentry>
+<dt>SE</dt>
+<dd>Nom du système d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version du système d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>Taille</dt>
+<dd>Taille de l'image ISO.</dd>
+</dlentry></dl></p>
+<p>Pour créer un modèle à partir d'une image ISO, choisissez parmi les options suivantes :<ul>
+<li>Sélectionnez une image ISO à partir de laquelle créer un modèle, puis cliquez sur <uicontrol>Créer des modèles à partir de l'ISO sélectionné </uicontrol>.</li>
+<li>Sélectionnez <uicontrol>Tout</uicontrol> pour créer un modèle à partir de chaque
+image ISO répertoriée, puis cliquez sur <uicontrol>Créer des modèles à partir de l'ISO sélectionné</uicontrol>.</li>
+<li>Si l'image ISO que vous souhaitez utiliser ne figure pas dans les résultats
+d'analyse, vous pouvez faire un choix parmi les options suivantes :<ul>
+<li>Sélectionnez <uicontrol>Je souhaite utiliser un fichier ISO spécifique</uicontrol> pour
+spécifier un chemin d'accès à l'image ISO.</li>
+<li>Cliquez sur <uicontrol>Rechercher d'autres images ISO</uicontrol> pour rechercher des images ISO supplémentaires.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
new file mode 100644
index 0000000..62e2f29
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+it_IT_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/it_IT
+
+dist_it_IT_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita
new file mode 100644
index 0000000..e05db7e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="it-it">
+<title>Guest</title>
+<shortdesc>La pagina <wintitle>Guest</wintitle> elenca le macchine virtuali
+KVM definite.</shortdesc>
+<csbody>
+<p>Per ciascuna macchina guest vengono visualizzate le seguenti informazioni:<dl><dlentry>
+<dt>Nome</dt>
+<dd>Il nome della macchina virtuale.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>La percentuale di utilizzo del processore nella macchina virtuale.</dd>
+</dlentry><dlentry>
+<dt>I/O di rete</dt>
+<dd>La velocità di trasmissione dell'input/output di rete in KB al secondo.</dd>
+</dlentry><dlentry>
+<dt>I/O disco</dt>
+<dd>La velocità di trasmissione dell'input/output disco in KB al secondo.</dd>
+</dlentry><dlentry>
+<dt>Riquadro animato</dt>
+<dd>Lo stato della console del sistema operativo della macchina guest o un'icona che rappresenta la distribuzione <tm tmtype="tm" trademark="Linux">Linux</tm> se la macchina guest non è attiva.</dd>
+</dlentry></dl></p>
+<p>Per ciascuna macchina guest vengono visualizzate le icone di azioni indicate di seguito:<dl>
+<dlentry>
+<dt>Reimposta</dt>
+<dd>Fare clic qui per reimpostare la macchina guest. </dd>
+</dlentry><dlentry>
+<dt>Alimentazione (Avvia o Arresta)</dt>
+<dd>Fare clic qui per accendere o spegnere la macchina guest. Se l'icona è rossa, la macchina è spenta, se è verde è accesa.</dd>
+</dlentry></dl> </p>
+<p>Per ciascuna macchina guest è possibile selezionare le azioni indicate di seguito:<ul>
+<li>Selezionare <uicontrol>Connetti</uicontrol> per effettuare la connessione alla console remota per il sistema operativo della macchina guest.</li>
+<li>Selezionare <uicontrol>Gestisci supporti</uicontrol> per modificare il percorso al supporto di installazione.</li>
+<li>Selezionare <uicontrol>Reimposta</uicontrol> per reimpostare la macchina guest.</li>
+<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare le proprietà  di una macchina guest esistente. à possibile modificare le macchine guest solo se sono arrestate.</li>
+<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare la macchina guest.</li>
+</ul>Per creare una macchina guest, o macchina virtuale, fare clic sull'icona <uicontrol>più
+(+)</uicontrol> nella parte in alto a destra della pagina.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="it-it">
+<title>Creare una macchina virtuale</title>
+<shortdesc>Creare una macchina virtuale utilizzando un modello esistente.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Immettere il nome da utilizzare per identificare la macchina virtuale.</li>
+<li rev="rev1">Selezionare un modello. <ul>
+<li>Se il modello esiste, selezionarlo dai modelli visualizzati.</li>
+<li>Se non esiste alcun modello, fare clic su <uicontrol>Crea un modello</uicontrol> per crearne uno.</li>
+</ul></li>
+<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="it-it">
+<title>Modifica macchina guest</title>
+<shortdesc>Modificare le proprietà di una macchina virtuale esistente. Alcune proprietà possono essere
+modificate solo mentre la macchina guest è arrestata. Altre diventeranno effettive al prossimo avvio.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Per ciascuna macchina guest vengono visualizzate le seguenti informazioni sulla scheda <wintitle>Generale</wintitle>:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Il nome della macchina virtuale. (Può essere modificato solo mentre la macchina guest è arrestata)</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Il numero di processori. (Se la macchina guest è in esecuzione, la nuova quantità diventerà effettiva
+al prossimo avvio)</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>La quantità di memoria in MB. (Se la macchina guest è in esecuzione, la nuova quantità diventerà effettiva
+al prossimo avvio)</dd>
+</dlentry><dlentry>
+<dt>Icona</dt>
+<dd>L'immagine grafica che rappresenta la distribuzione Linux da visualizzare al posto dello stato corrente (Riquadro animato) quando la macchina guest non è attiva.</dd>
+</dlentry></dl></p>
+<p>Sulla scheda <wintitle>Memoria</wintitle> vengono visualizzate le seguenti informazioni.</p>
+<dl><dlentry>
+<dt>Memoria</dt>
+<dd>Visualizza l'ubicazione del file ISO utilizzato per l'installazione.</dd>
+</dlentry></dl>
+<p> I campi non disabilitati possono essere modificati. Dopo aver modificato un campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="it-it">
+<title>Aggiungere, sostituire o scollegare un dispositivo di memoria.</title>
+<shortdesc rev="rev1">à possibile aggiungere, sostituire o scollegare un dispositivo di memoria per la macchina virtuale. L'unico dispositivo supportato è CDROM. Per modificare i dispositivi di memoria, attenersi alla seguente procedura:</shortdesc>
+<csbody>
+<ol>
+<li>Nella finestra <wintitle>Modifica macchina guest</wintitle>, selezionare <wintitle>Memoria</wintitle>.</li>
+<li>Per sostituire un dispositivo di memoria, fare clic sulla prima icona con la <uicontrol>barra (/) arancione</uicontrol>. Immettere il percorso del file ISO e fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
+<li>Per scollegare un dispositivo di memoria, fare clic sulla seconda icona con il <uicontrol>trattino (-) rosso</uicontrol>. Confermare l'eliminazione facendo clic su <uicontrol>OK</uicontrol>.</li>
+<li>Per aggiungere un dispositivo di memoria, fare clic sulla terza icona con il <uicontrol>segno più (+)</uicontrol> verde. Immettere un nome dispositivo e percorso file ISO e fare clic su <uicontrol>Collega</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="it-it">
+<title>Sostituisci un CDROM della macchina virtuale</title>
+<shortdesc rev="rev1">Ã possibile sostituire il contenuto del CDROM per una macchina virtuale dopo il completamento dell'installazione.</shortdesc>
+<csbody>
+<ol>
+<li>Assicurarsi che la macchina virtuale sia avviata.</li>
+<li>Dal menu Azioni, selezionare <uicontrol>Gestisci supporti</uicontrol>.</li>
+<li>Per modificare il contenuto correntemente caricato sul CDROM, fare clic sull'icona della <uicontrol>barra (/) arancione</uicontrol> accanto al campo hdc.</li>
+<li>Sulla pagina <wintitle>Sostituisci un CDROM della macchina virtuale</wintitle>, immettere il percorso del file ISO. Gli altri due campi sono di sola lettura.</li>
+<li>Fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita b/src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita
new file mode 100644
index 0000000..63d3367
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="it-it">
+<title>Host</title>
+<shortdesc>La pagina <wintitle>Host</wintitle> visualizza le informazioni sul sistema host e consente di arrestarlo, riavviarlo e connettersi ad esso.</shortdesc>
+<csbody>
+<p>Ã possibile effettuare le seguenti operazioni sull'host:<ul>
+<li>Selezionare <uicontrol>Arresta</uicontrol> per arrestare il sistema host.</li>
+<li>Selezionare <uicontrol>Riavvia</uicontrol> per riavviare il sistema host.</li>
+<li>Selezionare <uicontrol>Connetti</uicontrol> per aprire una connessione VNC al sistema host, se non è già connesso.</li>
+</ul></p>
+<p>Fare clic sulle seguenti sezioni per visualizzare le informazioni sull'host:<dl>
+<dlentry>
+<dt>Informazioni di base</dt>
+<dd>Questa sezione visualizza il nome codice, la versione e la distribuzione del sistema operativo, come pure il tipo di processore e la quantità di memoria in GB.</dd>
+</dlentry><dlentry>
+<dt>Statistiche di sistema</dt>
+<dd>Questa sezione visualizza i grafici che mostrano le statistiche per la CPU, la memoria, l'I/O disco e di rete per l'host. Selezionare <uicontrol>Raccolta dati all'uscita dalla pagina</uicontrol> per continuare la raccolta dei dati quando la scheda host non è più visibile.</dd>
+</dlentry><dlentry>
+<dt>Aggiornamenti del software</dt>
+<dd>Questa sezione visualizza le informazioni per tutti i pacchetti per cui sono disponibili gli aggiornamenti, incluso il nome, la versione, l'architettura e il repository del pacchetto. à possibile aggiornare tutti i pacchetti elencati, selezionando <uicontrol>Aggiorna tutto</uicontrol>. Non è possibile selezionare singoli pacchetti per gli aggiornamenti.</dd>
+</dlentry><dlentry>
+<dt>Repository</dt>
+<dd>Questa sezione visualizza i repository associati al sistema host. Ã possibile aggiungere, abilitare, modificare o rimuovere i repository. L'aggiunta di un repository lo associa al sistema host, mentre l'abilitazione di un repository
+consente all'host di accedervi. Se il sistema è Red Hat Enterprise
+Linux o Fedora, è possibile aggiungere i repository <filepath>yum</filepath>.
+Se il sistema è Ubuntu o Debian, aggiungere i repository <filepath>deb</filepath>.<p>Se si stanno utilizzando i repository yum, è possibile aggiungere un controllo GPG per verificare che un pacchetto da questo repository non sia stato corrotto.
+Selezionare un repository, quindi <uicontrol>Modifica</uicontrol>. Selezionare <uicontrol>Sì</uicontrol> per abilitare il controllo GPG, quindi immettere un URL al file di chiavi GPG per il
+repository.</p></dd>
+</dlentry><dlentry>
+<dt>Report di debug</dt>
+<dd>Questa sezione visualizza i report di debug, incluso il nome e il percorso file.
+Le opzioni disponibili consentono di generare un nuovo report oppure ridenominare, rimuovere o scaricare un report esistente.<p>Il report di debug viene generato utilizzando il comando <cmdname>sosreport</cmdname>. Ã disponibile per le distribuzioni Red
+Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora e Ubuntu. Il comando genera un file .tar che contiene informazioni di diagnostica e configurazione, come la versione del kernel in esecuzione, i moduli caricati e i file di configurazione del servizio e del sistema.
+Il comando esegue anche programmi esterni per raccogliere ulteriori informazioni e memorizza l'output nell'archivio risultante.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita b/src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita
new file mode 100644
index 0000000..a396d58
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="it-it">
+<title>Rete</title>
+<shortdesc>La pagina <wintitle>Rete</wintitle> visualizza le informazioni sulla connessione di rete.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nome rete</dt>
+<dd>Il nome della rete o il <uicontrol>valore predefinito</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Stato</dt>
+<dd>Lo stato della rete, attivo (verde) o non attivo (rosso). </dd>
+</dlentry><dlentry>
+<dt>Tipo di rete</dt>
+<dd>I tipo di rete, ad esempio, <uicontrol>NAT</uicontrol> (network
+address translation).</dd>
+</dlentry><dlentry>
+<dt>Interfaccia</dt>
+<dd>L'interfaccia di rete, ad esempio, <uicontrol>virbr0</uicontrol> (valore predefinito).</dd>
+</dlentry><dlentry>
+<dt>Spazio indirizzo</dt>
+<dd>L'indirizzo IP.</dd>
+</dlentry></dl></p>
+<p>Ã possibile selezionare le seguenti azioni:<ul>
+<li rev="rev1">Selezionare <uicontrol>Avvia</uicontrol> per iniziare la connessione di rete.</li>
+<li>Selezionare <uicontrol>Arresta</uicontrol> per terminare la connessione di rete.</li>
+<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare le informazioni di connessione.</li>
+</ul>Per creare una rete fare clic sull'icona <uicontrol>più
+(+)</uicontrol> nella parte in alto a destra del pannello.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="it-it">
+<title>Crea una rete</title>
+<shortdesc>Creare una rete.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Immettere il nome della rete.</li>
+<li>Fare clic per selezionare il tipo di rete. <dl rev="rev1"><dlentry>
+<dt><uicontrol>Isolata</uicontrol></dt>
+<dd>La modalità isolata. Le macchine guest non possono inviare o ricevere comunicazioni verso o da i sistemi esterni.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>La modalità NAT (Network Address Translation). La comunicazione dalle macchine guest ai sistemi esterni utilizza l'indirizzo IP host. I sistemi esterni non possono iniziare la comunicazione con le macchine guest.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Con bridge</uicontrol></dt>
+<dd>La modalità con bridge. Le macchine guest possono comunicare con i sistemi esterni ed essere contattate dai sistemi esterni come se fossero sistemi fisici sulla rete. Per la modalità con bridge, è necessario specificare informazioni aggiuntive su destinazione e VLAN.</dd>
+</dlentry></dl></li>
+<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita
new file mode 100644
index 0000000..5a9bc25
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="it-it">
+<title>Memoria</title>
+<shortdesc>La pagina <wintitle>Memoria</wintitle> elenca i pool di memoria
+disponibili, compresi i pool di memoria pronti per l'uso 'default' e 'ISO'.
+Se si desidera utilizzare un proprio ISO, aggiungerlo al percorso del pool di memoria 'ISO'.</shortdesc>
+<csbody>
+<p>Per ciascun pool di memoria vengono visualizzate le seguenti informazioni:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Il nome del pool di memoria e la percentuale utilizzata.</dd>
+</dlentry><dlentry>
+<dt>Stato</dt>
+<dd>Lo stato del pool di memoria, attivo (verde) o non attivo (rosso). </dd>
+</dlentry><dlentry>
+<dt>Ubicazione</dt>
+<dd>Il percorso file all'ubicazione del pool di memoria.</dd>
+</dlentry><dlentry>
+<dt>Tipo</dt>
+<dd>Il tipo di pool di memoria, ad esempio, <uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacità </dt>
+<dd>La quantità di spazio nel pool di memoria.</dd>
+</dlentry><dlentry>
+<dt>Assegnato</dt>
+<dd>La quantità di spazio già assegnato nel pool di memoria.</dd>
+</dlentry></dl></p>
+<p>Per ciascun pool di memoria è possibile selezionare le azioni indicate di seguito:<ul>
+<li>Selezionare <uicontrol>Attiva</uicontrol> per attivare il pool di memoria in modo da poterlo utilizzare.</li>
+<li>Selezionare <uicontrol>Disattiva</uicontrol> per disattivare un pool di memoria attivo.</li>
+<li>Selezionare <uicontrol>Rimuovi definizione</uicontrol> per rimuovere un pool di memoria non attivo.</li>
+</ul></p>
+<p>Per visualizzare i dettagli del volume di memoria per un pool di memoria, fare clic sulla freccia sul lato destro della riga del pool di memoria. I dettagli includono:<dl><dlentry>
+<dt>Tipo</dt>
+<dd>Il tipo di volume, ad esempio, <uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Formato</dt>
+<dd>Il formato, che varia in base al tipo.</dd>
+</dlentry><dlentry>
+<dt>Capacità </dt>
+<dd>La dimensione del volume di memoria.</dd>
+</dlentry><dlentry>
+<dt>Assegnazione</dt>
+<dd>La quantità di spazio già assegnato nel pool di memoria.</dd>
+</dlentry></dl>Per definire un pool di memoria fare clic sull'icona <uicontrol>più
+(+)</uicontrol> nella parte in alto a destra del pannello.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="it-it">
+<title>Definire un pool di memoria</title>
+<shortdesc> Definire un pool di memoria.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Nel campo <uicontrol>Nome pool di memoria</uicontrol>, immettere i l nome da utilizzare per definire il pool di memoria.</li>
+<li>Nell'elenco <uicontrol>Tipo pool di memoria</uicontrol>, selezionare il tipo: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Specifica un pool directory. Quando si seleziona <uicontrol>DIR</uicontrol>,
+immettere il <uicontrol>Percorso di memoria</uicontrol> (percorso file al pool di memoria).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Specifica un pool NFS (Network File System). Quando si seleziona <uicontrol>NFS</uicontrol>,
+immettere l'indirizzo <uicontrol>IP del server NFS</uicontrol> e il <uicontrol>Percorso NFS</uicontrol> (percorso alla directory esportata).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Specifica un pool basato su una destinazione assegnata su un server iSCSI.
+Quando si seleziona <uicontrol>iSCSI</uicontrol>, immettere l'indirizzo IP del <uicontrol>Server iSCSI</uicontrol> e la <uicontrol>Destinazione</uicontrol> sul server iSCSI. Ã possibile, facoltativamente, selezionare di aggiungere l'autenticazione iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logico</uicontrol></dt>
+<dd>Specifica un pool di memoria di tipo volume logico. Selezionare l'ubicazione del dispositivo in <uicontrol>Percorso dispositivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Canale a fibre ottiche SCSI</uicontrol></dt>
+<dd>Specifica un pool basato su un canale a fibre ottiche SCSI. Selezionare quale adattatore
+SCSI utilizzare.</dd>
+</dlentry></dl></li>
+<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita
new file mode 100644
index 0000000..9b84b16
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="it-it">
+<title>Modelli</title>
+<shortdesc>La pagina <wintitle>Modelli</wintitle> visualizza i modelli di macchina virtuale definiti che è possibile utilizzare per creare macchine guest KVM.</shortdesc>
+<csbody>
+<p>Per ciascun modello vengono visualizzate le seguenti informazioni:<dl>
+<dlentry>
+<dt>SO</dt>
+<dd>Il nome del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>Versione</dt>
+<dd>La versione del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Il numero di processori definiti per il modello.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>La quantità di memoria ad accesso casuale da assegnare, in MB.</dd>
+</dlentry></dl></p>
+<p>Per ciascun modello è possibile selezionare le azioni indicate di seguito:<ul>
+<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare il modello.</li>
+<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare il modello.</li>
+</ul>Per aggiungere un modello fare clic sull'icona <uicontrol>più
+(+)</uicontrol> nella parte in alto a destra del pannello.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="it-it">
+<title>Modifica modello</title>
+<shortdesc>Modificare un modello esistente.</shortdesc>
+<csbody>
+<p>Per ciascun modello vengono visualizzate le seguenti informazioni: <dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Il nome del modello.</dd>
+</dlentry><dlentry>
+<dt>Fornitore</dt>
+<dd>Il nome della società che ha creato il sistema operativo o la distribuzione per il cui utilizzo è configurato il modello.</dd>
+</dlentry><dlentry>
+<dt>Versione</dt>
+<dd>La versione del sistema operativo o della distribuzione per il cui utilizzo è configurato il modello.</dd>
+</dlentry><dlentry>
+<dt>Numero CPU</dt>
+<dd>Il numero di processori definiti per il modello.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>La quantità di memoria in MB da assegnare alla macchina virtuale.</dd>
+</dlentry><dlentry>
+<dt>Disco</dt>
+<dd>La dimensione del disco in GB.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>Il percorso file all'ubicazione del file ISO utilizzato per installare la macchina guest
+KVM.</dd>
+</dlentry><dlentry>
+<dt>Pool di memoria</dt>
+<dd>Un pool di memoria specifico o quello predefinito.</dd>
+</dlentry><dlentry>
+<dt>Rete</dt>
+<dd>Le interfacce di rete predefinite disponibili per la macchina guest KVM. à possibile selezionare più reti.</dd>
+</dlentry></dl> I campi non disabilitati possono essere modificati. Dopo aver modificato un campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Aggiungi modello</title>
+<shortdesc>Aggiungere un modello dal supporto di origine.
+Ã possibile aggiungere una propria immagine ISO al pool di memoria 'ISO' per la seguente individuazione.</shortdesc>
+<csbody>
+<p>Selezionare l'ubicazione del supporto di origine dalle seguenti opzioni:<dl>
+<dlentry>
+<dt>Immagine ISO locale</dt>
+<dd>Selezionare questa opzione per eseguire la scansione dei pool di memoria alla ricerca di immagini ISO di installazione disponibili sul sistema.</dd>
+</dlentry><dlentry>
+<dt>Immagine ISO remota</dt>
+<dd>Selezionare questa opzione per specificare un'ubicazione remota per un'immagine ISO di installazione.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Aggiungi modello - Immagine ISO locale</title>
+<shortdesc>Aggiungere un modello da un'immagine ISO locale.</shortdesc>
+<csbody>
+<p>Vengono visualizzate le immagini ISO disponibili sul sistema.<dl><dlentry>
+<dt>SO</dt>
+<dd>Il nome del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>Versione</dt>
+<dd>La versione del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>Dimensione</dt>
+<dd>La dimensione dell'immagine ISO.</dd>
+</dlentry></dl></p>
+<p>Per creare un modello da un'immagine ISO scegliere tra le seguenti opzioni:<ul>
+<li>Selezionare un'immagine ISO da cui creare un modello, quindi fare clic su <uicontrol>Crea modelli da ISO selezionato</uicontrol>.</li>
+<li>Selezionare <uicontrol>Tutti</uicontrol> per creare un modello da ciascuna immagine ISO elencata, quindi fare clic su <uicontrol>Crea modelli da ISO selezionato</uicontrol>.</li>
+<li>Se nei risultati della scansione non viene visualizzata l'immagine ISO che si desidera utilizzare, è possibile selezionare dalle seguenti opzioni:<ul>
+<li>Selezionare <uicontrol>Utilizzare un file ISO specifico</uicontrol> per specificare un percorso all'immagine ISO.</li>
+<li>Fare clic su <uicontrol>Ricerca più ISO</uicontrol> per ricercare più immagini
+ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
new file mode 100644
index 0000000..f9c2f33
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ja_JP_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ja_JP
+
+dist_ja_JP_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
new file mode 100644
index 0000000..5dade49
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="ja-jp">
+<title>ã²ã¹ã</title>
+<shortdesc><wintitle>ãã²ã¹ãã</wintitle>ãã¼ã¸ã«ã¯ãå®ç¾©æ¸ã¿ KVM ä»®æ³ãã·ã³ããªã¹ãããã¾ãã
+</shortdesc>
+<csbody>
+<p>ã²ã¹ããã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
+<dl><dlentry>
+<dt>åå</dt>
+<dd>ä»®æ³ãã·ã³ã®ååã
+</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>ä»®æ³ãã·ã³ã«ãããããã»ããµã¼ä½¿ç¨çã
+</dd>
+</dlentry><dlentry>
+<dt>ãããã¯ã¼ã¯å
¥åºå</dt>
+<dd>ãããã¯ã¼ã¯å
¥åºåã®é度 (KB/ç§)ã
+</dd>
+</dlentry><dlentry>
+<dt>ãã£ã¹ã¯å
¥åºå</dt>
+<dd>ãã£ã¹ã¯å
¥åºåã®é度 (KB/ç§)ã
+</dd>
+</dlentry><dlentry>
+<dt>ã©ã¤ãã¿ã¤ã«</dt>
+<dd>ã²ã¹ãã»ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã»ã³ã³ã½ã¼ã«ã®ç¶æ
ãã¾ãã¯ã²ã¹ããã¢ã¯ãã£ãã§ã¯ãªãå ´åã<tm tmtype="tm" trademark="Linux">Linux</tm>
+ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã表ãã¢ã¤ã³ã³ã
+</dd>
+</dlentry></dl></p>
+<p>ã²ã¹ããã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã»ã¢ã¤ã³ã³ã表示ããã¾ãã
+<dl>
+<dlentry>
+<dt>ãªã»ãã</dt>
+<dd>ã¯ãªãã¯ãã¦ã²ã¹ãããªã»ãããã¾ãã
+</dd>
+</dlentry><dlentry>
+<dt>黿º (éå§ã¾ãã¯åæ¢)</dt>
+<dd>ã¯ãªãã¯ãã¦ã²ã¹ãã®é»æºããªã³ã¾ãã¯ãªãã«ãã¾ãã
+ãã®ã¢ã¤ã³ã³ã赤ã§ããã°é»æºã¯ãªãã«ãªã£ã¦ãã¾ããç·ã§ããã°ãªã³ã«ãªã£ã¦ãã¾ãã
+</dd>
+</dlentry></dl> </p>
+<p>ã²ã¹ããã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
+<ul>
+<li>ã²ã¹ãã»ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã®ãªã¢ã¼ãã»ã³ã³ã½ã¼ã«ã«æ¥ç¶ããã«ã¯ã<uicontrol>ãæ¥ç¶ã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ã¤ã³ã¹ãã¼ã«ã»ã¡ãã£ã¢ã®ãã¹ã夿´ããã«ã¯ã<uicontrol>ãã¡ãã£ã¢ã®ç®¡çã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ã²ã¹ãããªã»ããããã«ã¯<uicontrol>ããªã»ããã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>æ¢åã®ã²ã¹ãã®ããããã£ã¼ãç·¨éããã«ã¯ã<uicontrol>ãç·¨éã</uicontrol>ã鏿ãã¾ãã
+ã²ã¹ãã¯ã忢ãã¦ããéã®ã¿ç·¨éã§ãã¾ãã
+</li>
+<li>ã²ã¹ããåé¤ããã«ã¯<uicontrol>ãåé¤ã</uicontrol>ã鏿ãã¾ãã
+</li>
+</ul>ã²ã¹ã (ä»®æ³ãã·ã³) ã使ããã«ã¯ããã¼ã¸ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
+</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="ja-jp">
+<title>ä»®æ³ãã·ã³ã®ä½æ</title>
+<shortdesc>æ¢åã®ãã³ãã¬ã¼ããç·¨éãããã¨ã«ãã£ã¦ãä»®æ³ãã·ã³ã使ãã¾ãã
+</shortdesc>
+<csbody>
+<p> <ol>
+<li>ä»®æ³ãã·ã³ãèå¥ããããã®ååãå
¥åãã¾ãã
+</li>
+<li rev="rev1">ãã³ãã¬ã¼ãã鏿ãã¾ãã
+<ul>
+<li>ãã³ãã¬ã¼ããåå¨ããå ´åã表示ããããã³ãã¬ã¼ããã鏿ãã¦ãã ããã
+</li>
+<li>ãã³ãã¬ã¼ããåå¨ããªãå ´åã¯ã<uicontrol>ããã³ãã¬ã¼ãã®ä½æã</uicontrol>ãã¯ãªãã¯ãã¦ãã³ãã¬ã¼ãã使ãã¾ãã
+</li>
+</ul></li>
+<li><uicontrol>ã使ã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
+</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="ja-jp">
+<title>ã²ã¹ãã®ç·¨é</title>
+<shortdesc>æ¢åã®ä»®æ³ãã·ã³ã®ããããã£ã¼ãç·¨éãã¾ãã
+ä¸é¨ã®ããããã£ã¼ã¯ãã²ã¹ãã忢ãã¦ããéã«éãç·¨éå¯è½ã§ãã
+ããã¨ã¯å¥ã«ã次ã®ãã¼ãã§æå¹ã«ãªãããããã£ã¼ãããã¾ãã</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>ã²ã¹ããã¨ã«ã以ä¸ã®æ
å ±ã<wintitle>ãä¸è¬ã</wintitle>ã¿ãã«è¡¨ç¤ºããã¾ãã
+<dl>
+<dlentry>
+<dt>åå</dt>
+<dd>ä»®æ³ãã·ã³ã®ååã
+(ã²ã¹ãã忢ãã¦ããéã«éãç·¨éå¯è½)</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>ããã»ããµã¼ã®æ°ã
+(ã²ã¹ãã稼åãã¦ããå ´åãæ°è¦ã®æ°ã¯æ¬¡ã®ãã¼ãã§æå¹ã«ãªã)</dd>
+</dlentry><dlentry>
+<dt>ã¡ã¢ãªã¼</dt>
+<dd>ã¡ã¢ãªã¼ã®é (MB åä½)ã
+(ã²ã¹ãã稼åãã¦ããå ´åãæ°è¦ã®éã¯æ¬¡ã®ãã¼ãã§æå¹ã«ãªã)</dd>
+</dlentry><dlentry>
+<dt>ã¢ã¤ã³ã³</dt>
+<dd>ã²ã¹ããã¢ã¯ãã£ãã§ã¯ãªãå ´åã«ç¾å¨ã®ç¶æ³ (ã©ã¤ãã¿ã¤ã«) ã¨ãã¦è¡¨ç¤ºããããLinux ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã表ãã°ã©ãã£ãã¯ã»ã¤ã¡ã¼ã¸ã
+</dd>
+</dlentry></dl></p>
+<p>æ¬¡ã®æ
å ±ã<wintitle>ãã¹ãã¬ã¼ã¸ã</wintitle>ã¿ãã«è¡¨ç¤ºããã¾ãã
+</p>
+<dl><dlentry>
+<dt>ã¹ãã¬ã¼ã¸</dt>
+<dd>ã¤ã³ã¹ãã¼ã«ã«ä½¿ç¨ããã ISO ãã¡ã¤ã«ã®ãã±ã¼ã·ã§ã³ã表示ãã¾ãã
+</dd>
+</dlentry></dl>
+<p> 使ç¨ä¸å¯ã«ãªã£ã¦ããªããã£ã¼ã«ããç·¨éã§ãã¾ãã
+ãã£ã¼ã«ããç·¨éããå¾ã<uicontrol>ãä¿åã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
+</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="ja-jp">
+<title>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã®è¿½å ã交æãã¾ãã¯åãé¢ã</title>
+<shortdesc rev="rev1">ä»®æ³ãã·ã³ã«ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã追å ãããã¤ã¹ã交æãã¾ãã¯ä»®æ³ãã·ã³ããåãé¢ããã¨ãã§ãã¾ãã
+ãµãã¼ãããã¦ããããã¤ã¹ã¯ CDROM ã ãã§ãã
+ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãç·¨éããã«ã¯ã以ä¸ã®æé ã«å¾ã£ã¦ãã ããã
+</shortdesc>
+<csbody>
+<ol>
+<li><wintitle>ãã²ã¹ãã®ç·¨éã</wintitle>ã¦ã£ã³ãã¦ã§<wintitle>ãã¹ãã¬ã¼ã¸ã</wintitle>ã鏿ãã¾ãã
+</li>
+<li>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã交æããã«ã¯ã<uicontrol>ãªã¬ã³ã¸ã®ã¹ã©ãã·ã¥ (/)</uicontrol> ãä»ããæåã®ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
+ISO ãã¡ã¤ã«ã»ãã¹ãå
¥åãã<uicontrol>ã交æã</uicontrol>ãã¯ãªãã¯ãã¾ãã
+</li>
+<li>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ãåãé¢ãã«ã¯ã<uicontrol>赤ãããã·ã¥ (-)</uicontrol> ãä»ãã 2 çªç®ã®ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
+åé¤ã確èªãã¦<uicontrol>ãOKã</uicontrol>ãã¯ãªãã¯ãã¾ãã
+</li>
+<li>ã¹ãã¬ã¼ã¸ã»ããã¤ã¹ã追å ããã«ã¯ã<uicontrol>ç·ã®æ£ç¬¦å· (+)</uicontrol> ãä»ãã 3 çªç®ã®ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
+ããã¤ã¹å㨠ISO ãã¡ã¤ã«ã»ãã¹ãå
¥åãã<uicontrol>ãæ¥ç¶ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
+</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="ja-jp">
+<title>VM ã® CDROM ã交æ</title>
+<shortdesc rev="rev1">ã¤ã³ã¹ãã¼ã«ãå®äºããå¾ã§ãä»®æ³ãã·ã³ã® CDROM ã®å
容ã交æãããã¨ãã§ãã¾ãã
+</shortdesc>
+<csbody>
+<ol>
+<li>ä»®æ³ãã·ã³ãå§åãã¦ãããã¨ã確èªãã¾ãã
+</li>
+<li>ãã¢ã¯ã·ã§ã³ãã¡ãã¥ã¼ãã<uicontrol>ãã¡ãã£ã¢ã®ç®¡çã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>CDROM ã«ãã¼ãããã¦ããå
容ã夿´ããã«ã¯ãhdc ãã£ã¼ã«ãã®æ¨ªã«ãã<uicontrol>ãªã¬ã³ã¸ã®ã¹ã©ãã·ã¥ (/)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¾ãã
+</li>
+<li><wintitle>ãVM ã® CDROM ã交æã</wintitle>ãã¼ã¸ã§ãISO ãã¡ã¤ã«ã»ãã¹ãå
¥åãã¾ãã
+ãã以å¤ã® 2 ã¤ã®ãã£ã¼ã«ãã¯èªã¿åãå°ç¨ã§ãã
+</li>
+<li><uicontrol>ã交æã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
+</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita
new file mode 100644
index 0000000..3a0141c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="ja-jp">
+<title>ãã¹ã</title>
+<shortdesc><wintitle>ããã¹ãã</wintitle>ãã¼ã¸ã«ã¯ããã¹ãã»ã·ã¹ãã ã«é¢ããæ
å ±ã表示ããã¾ããããã§ããã¹ããã·ã£ãããã¦ã³ãåå§åãã¾ããã¹ãã«æ¥ç¶ãããã¨ãã§ãã¾ãã
+</shortdesc>
+<csbody>
+<p>以ä¸ã®ã¢ã¯ã·ã§ã³ããã¹ãã«å¯¾ãã¦å®è¡ã§ãã¾ãã
+<ul>
+<li>ãã¹ãã»ã·ã¹ãã ãã·ã£ãããã¦ã³ããã«ã¯<uicontrol>ãã·ã£ãããã¦ã³ã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ãã¹ãã»ã·ã¹ãã ãåå§åããã«ã¯<uicontrol>ãåå§åã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ãã¹ãã»ã·ã¹ãã ã¸ã® VNC æ¥ç¶ã (ã¾ã æ¥ç¶ããã¦ããªãå ´åã«) ãªã¼ãã³ããã«ã¯ã<uicontrol>ãæ¥ç¶ã</uicontrol>ã鏿ãã¾ãã
+</li>
+</ul></p>
+<p>ãã¹ãã«é¢ããæ
å ±ã表示ããã«ã¯ã以ä¸ã®é¸æé
ç®ãã¯ãªãã¯ãã¦ãã ããã
+<dl>
+<dlentry>
+<dt>åºæ¬æ
å ±</dt>
+<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããã¹ãã»ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã®ãã£ã¹ããªãã¥ã¼ã·ã§ã³ããã¼ã¸ã§ã³ãããã³ã³ã¼ãåãããã«ããã»ããµã¼ã»ã¿ã¤ãã¨ã¡ã¢ãªã¼ã®é (GB åä½) ã表示ããã¾ãã
+</dd>
+</dlentry><dlentry>
+<dt>ã·ã¹ãã çµ±è¨æ
å ±</dt>
+<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããã¹ãã® CPUãã¡ã¢ãªã¼ããã£ã¹ã¯å
¥åºåãããã³ãããã¯ã¼ã¯å
¥åºåã®çµ±è¨æ
å ±ã表ãã°ã©ãã表示ããã¾ãã
+ãã¹ãã»ã¿ããéããã¨ãã«ãã¼ã¿ã®åéãç¶è¡ããã«ã¯ã<uicontrol>ããã®ãã¼ã¸ãéããå¾ããã¼ã¿ãåéããã</uicontrol>ã鏿ãã¦ãã ããã
+</dd>
+</dlentry><dlentry>
+<dt>ã½ããã¦ã§ã¢æ´æ°</dt>
+<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ãæ´æ°ãç¨æããã¦ããããã±ã¼ã¸ãã¹ã¦ã®æ
å ±
+(ããã±ã¼ã¸åããã¼ã¸ã§ã³ãã¢ã¼ããã¯ãã£ã¼ããªãã¸ããªã¼ãªã©) ã表示ããã¾ãã
+<uicontrol>ããã¹ã¦æ´æ°ã</uicontrol>ã鏿ããã¨ããªã¹ãããã¦ããããã±ã¼ã¸ãã¹ã¦ãæ´æ°ã§ãã¾ãã
+æ´æ°ãã対象ã¨ãã¦åå¥ã®ããã±ã¼ã¸ã鏿ãããã¨ã¯ã§ãã¾ããã
+</dd>
+</dlentry><dlentry>
+<dt>ãªãã¸ããªã¼</dt>
+<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããã¹ãã»ã·ã¹ãã ã«é¢é£ä»ãããã¦ãããªãã¸ããªã¼ã表示ããã¾ãã
+ãªãã¸ããªã¼ã追å ãããæå¹ã«ãããç·¨éãããã¾ãã¯åé¤ãããã¨ãã§ãã¾ãã
+ãªãã¸ããªã¼ã追å ããã¨ããã®ãªãã¸ããªã¼ããã¹ãã»ã·ã¹ãã ã«é¢é£ä»ãããããªãã¸ããªã¼ãæå¹ã«ããã¨ããã®ãªãã¸ããªã¼ã«ãã¹ããã¢ã¯ã»ã¹ã§ããããã«ãªãã¾ãã
+ã·ã¹ãã ã Red Hat Enterprise Linux ã¾ã㯠Fedora ã§ããã°ã<filepath>yum</filepath> ãªãã¸ããªã¼ã追å ã§ãã¾ãã
+ã·ã¹ãã ã Ubuntu ã¾ã㯠Debian ã§ããã°ã<filepath>deb</filepath> ãªãã¸ããªã¼ã追å ãã¦ãã ããã
+<p>yum ãªãã¸ããªã¼ãæä½ãã¦ããå ´åããã®ãªãã¸ããªã¼ã«å
¥ã£ã¦ããããã±ã¼ã¸ãå£ãã¦ããªããã¨ã確èªãããããGPG ãã§ãã¯ã追å ã§ãã¾ãã
+ãªãã¸ããªã¼ã鏿ãã<uicontrol>ãç·¨éã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
+<uicontrol>ãã¯ãã</uicontrol>ã鏿ã㦠GPG ãã§ãã¯ãæå¹ã«ãã¦ããããã®ãªãã¸ããªã¼ã® GPG éµãã¡ã¤ã«ã® URL ãå
¥åãã¦ãã ããã
+</p></dd>
+</dlentry><dlentry>
+<dt>ãããã°ã»ã¬ãã¼ã</dt>
+<dd>ãã®ã»ã¯ã·ã§ã³ã«ã¯ããããã°ã»ã¬ãã¼ã (ååããã¡ã¤ã«ã»ãã¹ãªã©) ã表示ããã¾ãã
+æ°ããã¬ãã¼ããçæãæ¢åã®ã¬ãã¼ããåå夿´ãåé¤ãã¾ãã¯ãã¦ã³ãã¼ãããããã®ãªãã·ã§ã³ã鏿ã§ãã¾ãã
+<p>ãããã°ã»ã¬ãã¼ãã¯ã<cmdname>sosreport</cmdname> ã³ãã³ãã§çæããã¾ãã
+ããã¯ãRed Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>ãFedoraãããã³ Ubuntu ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã«ç¨æããã¦ãã¾ãã
+ãã®ã³ãã³ãã¯ãæ§æããã³è¨ºææ
å ± (稼åä¸ã®ã«ã¼ãã«ã®ãã¼ã¸ã§ã³ããã¼ãããã¦ããã¢ã¸ã¥ã¼ã«ãã·ã¹ãã ããã³ãµã¼ãã¹æ§æãã¡ã¤ã«ãªã©) ãå
¥ã£ã .tar ãã¡ã¤ã«ãçæãã¾ãã
+ãã®ã³ãã³ãã¯ã¾ããå¤é¨ããã°ã©ã ãå®è¡ãã¦æ
å ±ãããã«åéãããã®åºåãçµæã®ã¢ã¼ã«ã¤ãã«ä¿ç®¡ãã¾ãã
+</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 227 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita
new file mode 100644
index 0000000..5d9ce05
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="ja-jp">
+<title> ãããã¯ã¼ã¯</title>
+<shortdesc><wintitle>ããããã¯ã¼ã¯ã</wintitle>ãã¼ã¸ã«ã¯ããããã¯ã¼ã¯æ¥ç¶ã«é¢ããæ
å ±ã表示ããã¾ãã
+</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>ãããã¯ã¼ã¯å</dt>
+<dd>ãããã¯ã¼ã¯ã®åå (ã¾ã㯠<uicontrol>default</uicontrol>) ã§ãã
+</dd>
+</dlentry><dlentry>
+<dt>ç¶æ
</dt>
+<dd>ãããã¯ã¼ã¯ã®ç¶æ
ã§ãã¢ã¯ãã£ã (ç·) ã¾ãã¯éã¢ã¯ãã£ã (赤) ã§ãã
+</dd>
+</dlentry><dlentry>
+<dt>ãããã¯ã¼ã¯ã»ã¿ã¤ã</dt>
+<dd>ãããã¯ã¼ã¯ã»ã¿ã¤ãã§ãä¾ãã° <uicontrol>NAT</uicontrol> (ãããã¯ã¼ã¯ã»ã¢ãã¬ã¹å¤æ) ã§ãã
+</dd>
+</dlentry><dlentry>
+<dt>ã¤ã³ã¿ã¼ãã§ã¼ã¹</dt>
+<dd>ãããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã§ãä¾ãã° <uicontrol>virbr0</uicontrol> (ããã©ã«ã) ã§ãã
+</dd>
+</dlentry><dlentry>
+<dt>ã¢ãã¬ã¹ã»ã¹ãã¼ã¹</dt>
+<dd>IP ã¢ãã¬ã¹ã</dd>
+</dlentry></dl></p>
+<p>以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
+<ul>
+<li rev="rev1">ãããã¯ã¼ã¯æ¥ç¶ãéå§ããã«ã¯<uicontrol>ãéå§ã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ãããã¯ã¼ã¯æ¥ç¶ãçµäºããã«ã¯<uicontrol>ã忢ã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>æ¥ç¶æ
å ±ãåé¤ããã«ã¯<uicontrol>ãåé¤ã</uicontrol>ã鏿ãã¾ãã
+</li>
+</ul>ãããã¯ã¼ã¯ã使ããã«ã¯ã表示ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
+</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="ja-jp">
+<title>ãããã¯ã¼ã¯ã®ä½æ</title>
+<shortdesc>ãããã¯ã¼ã¯ã使ãã¾ãã
+</shortdesc>
+<csbody>
+<p> <ol>
+<li>ãããã¯ã¼ã¯ã®ååãå
¥åãã¾ãã
+</li>
+<li>ã¯ãªãã¯ãã¦ãããã¯ã¼ã¯ã»ã¿ã¤ãã鏿ãã¾ãã
+<dl rev="rev1"><dlentry>
+<dt><uicontrol>éé¢</uicontrol></dt>
+<dd>éé¢ã¢ã¼ãã
+ã²ã¹ãã¯ãå¤é¨ã·ã¹ãã ã¨ã®éã®éä¿¡ãè¡ããã¨ãã§ãã¾ããã
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>ãããã¯ã¼ã¯ã»ã¢ãã¬ã¹å¤æã¢ã¼ãã
+ã²ã¹ãããå¤é¨ã·ã¹ãã ã¸ã®éä¿¡ã«ããã¹ã IP ã¢ãã¬ã¹ã使ç¨ããã¾ãã
+å¤é¨ã·ã¹ãã ã¯ãã²ã¹ãã¸ã®éä¿¡ãéå§ã§ãã¾ããã
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>ããªãã¸</uicontrol></dt>
+<dd>ããªãã¸ã»ã¢ã¼ãã
+ã²ã¹ãã¯å¤é¨ã·ã¹ãã ã¨ã®éä¿¡ãè¡ããã¨ãã§ãããããã¯ã¼ã¯ä¸ã®ç©çã·ã¹ãã ã§ãããã®ããã«å¤é¨ã·ã¹ãã ããæ¥ç¶ã§ãã¾ãã
+ããªãã¸ã»ã¢ã¼ãã§ã¯ãå®å
ããã³ VLAN æ
å ±ãããã«æå®ããå¿
è¦ãããã¾ãã
+</dd>
+</dlentry></dl></li>
+<li><uicontrol>ã使ã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
+</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
new file mode 100644
index 0000000..f975e7a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="ja-jp">
+<title>ã¹ãã¬ã¼ã¸</title>
+<shortdesc><wintitle>ãã¹ãã¬ã¼ã¸ã</wintitle>ãã¼ã¸ã«ã¯ã使ç¨å¯è½ãª
+ã¹ãã¬ã¼ã¸ã»ãã¼ã« (å³æä½¿ç¨å¯è½ãªãdefaultãã¹ãã¬ã¼ã¸ã»ãã¼ã«ããISOãã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå«ã) ããªã¹ãããã¾ãã
+ç¬èªã® ISO ã使ç¨ããå ´åã¯ãããããISOãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ãã¹ã«è¿½å ãã¦ãã ããã</shortdesc>
+<csbody>
+<p>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
+<dl>
+<dlentry>
+<dt>åå</dt>
+<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ååããã³ä½¿ç¨çã
+</dd>
+</dlentry><dlentry>
+<dt>ç¶æ
</dt>
+<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ç¶æ
ã§ãã¢ã¯ãã£ã (ç·) ã¾ãã¯éã¢ã¯ãã£ã (赤) ã§ãã
+</dd>
+</dlentry><dlentry>
+<dt>ãã±ã¼ã·ã§ã³</dt>
+<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ãã±ã¼ã·ã§ã³ã®ãã¡ã¤ã«ã»ãã¹ã
+</dd>
+</dlentry><dlentry>
+<dt>ã¿ã¤ã</dt>
+<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ã¿ã¤ãã§ãä¾ãã° <uicontrol>dir</uicontrol> ã§ãã
+</dd>
+</dlentry><dlentry>
+<dt>容é</dt>
+<dd>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«ãããã¹ãã¼ã¹ã®éã
+</dd>
+</dlentry><dlentry>
+<dt>å²ãå½ã¦æ¸ã¿</dt>
+<dd>æ¢ã«ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«å²ãå½ã¦ããã¦ããã¹ãã¼ã¹ã®éã
+</dd>
+</dlentry></dl></p>
+<p>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
+<ul>
+<li>使ç¨ã§ããããã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¢ã¯ãã£ãã«ããã«ã¯ã<uicontrol>ãã¢ã¯ãã£ãã«ããã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ã¢ã¯ãã£ãã»ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãéã¢ã¯ãã£ãã«ããã«ã¯ã<uicontrol>ãéã¢ã¯ãã£ãã«ããã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>éã¢ã¯ãã£ãã»ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãåé¤ããã«ã¯ã<uicontrol>ãå®ç¾©ãè§£é¤ããã</uicontrol>ã鏿ãã¾ãã
+</li>
+</ul></p>
+<p>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã 詳細ã表示ããã«ã¯ãã¹ãã¬ã¼ã¸ã»ãã¼ã«è¡ã®å³å´ã«ããç¢å°ãã¯ãªãã¯ãã¦ãã ããã
+詳細ã¯ä»¥ä¸ã®ã¨ããã§ãã
+<dl><dlentry>
+<dt>ã¿ã¤ã</dt>
+<dd>ããªã¥ã¼ã ã®ã¿ã¤ãã§ãä¾ãã° <uicontrol>file</uicontrol> ã§ãã
+</dd>
+</dlentry><dlentry>
+<dt>ãã©ã¼ããã</dt>
+<dd>ã¿ã¤ãã«ãã£ã¦ç°ãªããã©ã¼ãããã
+</dd>
+</dlentry><dlentry>
+<dt>容é</dt>
+<dd>ã¹ãã¬ã¼ã¸ã»ããªã¥ã¼ã ã®ãµã¤ãºã
+</dd>
+</dlentry><dlentry>
+<dt>å²ãæ¯ã</dt>
+<dd>æ¢ã«ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«å²ãå½ã¦ããã¦ããã¹ãã¼ã¹ã®éã
+</dd>
+</dlentry></dl>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå®ç¾©ããã«ã¯ã表示ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
+</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="ja-jp">
+<title>ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®å®ç¾©</title>
+<shortdesc> ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãå®ç¾©ãã¾ãã
+</shortdesc>
+<csbody>
+<p> <ol>
+<li><uicontrol>ãã¹ãã¬ã¼ã¸ã»ãã¼ã«åã</uicontrol>ãã£ã¼ã«ãã«ãã¹ãã¬ã¼ã¸ã»ãã¼ã«ãèå¥ããããã®ååãå
¥åãã¾ãã
+</li>
+<li><uicontrol>ãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã»ã¿ã¤ãã</uicontrol>ãªã¹ãããã以ä¸ã®ã¿ã¤ãã鏿ãã¾ãã
+<dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>ãã£ã¬ã¯ããªã¼ã»ãã¼ã«ãæå®ãã¾ãã
+<uicontrol>DIR</uicontrol> ã鏿ããå ´åã<uicontrol>ã¹ãã¬ã¼ã¸ã»ãã¹</uicontrol> (ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã®ãã¡ã¤ã«ã»ãã¹) ãå
¥åãã¦ãã ããã
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>ãããã¯ã¼ã¯ã»ãã¡ã¤ã«ã·ã¹ãã ã»ãã¼ã«ãæå®ãã¾ãã
+<uicontrol>NFS</uicontrol> ã鏿ããå ´åã<uicontrol>NFS ãµã¼ãã¼ IP</uicontrol> ã¢ãã¬ã¹ããã³ <uicontrol>NFS ãã¹</uicontrol>
+(ã¨ã¯ã¹ãã¼ãããããã£ã¬ã¯ããªã¼ã®ãã¹) ãå
¥åãã¦ãã ããã
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>iSCSI ãµã¼ãã¼ã«å²ãå½ã¦ããã¦ããã¿ã¼ã²ããã«åºã¥ãã¦ããã¼ã«ãæå®ãã¾ãã
+<uicontrol>iSCSI</uicontrol> ã鏿ããå ´åã<uicontrol>iSCSI ãµã¼ãã¼</uicontrol> IP ã¢ãã¬ã¹ã¨ããã® iSCSI ãµã¼ãã¼ä¸ã®<uicontrol>ã¿ã¼ã²ãã</uicontrol>ãå
¥åãã¦ãã ããã
+å¿
è¦ã«å¿ãã¦ãiSCSI èªè¨¼ã追å ãããã鏿ã§ãã¾ãã
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>è«ç</uicontrol></dt>
+<dd>è«çããªã¥ã¼ã ã»ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãæå®ãã¾ãã
+ããã¤ã¹ã®ãã±ã¼ã·ã§ã³ã<uicontrol>ãããã¤ã¹ã»ãã¹ã</uicontrol>ã§é¸æãã¦ãã ããã
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI ãã¡ã¤ãã¼ã»ãã£ãã«</uicontrol></dt>
+<dd>SCSI ãã¡ã¤ãã¼ã»ãã£ãã«ã«åºã¥ãã¦ãã¼ã«ã鏿ãã¾ãã
+使ç¨ãã SCSI ã¢ããã¿ã¼ã鏿ãã¦ãã ããã
+</dd>
+</dlentry></dl></li>
+<li><uicontrol>ã使ã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
+</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
new file mode 100644
index 0000000..24dc2ab
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="ja-jp">
+<title>ãã³ãã¬ã¼ã</title>
+<shortdesc><wintitle>ããã³ãã¬ã¼ãã</wintitle>ãã¼ã¸ã«ã¯ãKVM ã²ã¹ãã使ããããã«ä½¿ç¨ã§ãããå®ç¾©æ¸ã¿ä»®æ³ãã·ã³ã»ãã³ãã¬ã¼ãã表示ããã¾ãã
+</shortdesc>
+<csbody>
+<p>ãã³ãã¬ã¼ããã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
+<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ååã
+</dd>
+</dlentry><dlentry>
+<dt>ãã¼ã¸ã§ã³</dt>
+<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ã
+</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>ãã³ãã¬ã¼ãã«å®ç¾©ããã¦ããããã»ããµã¼ã®æ°ã
+</dd>
+</dlentry><dlentry>
+<dt>ã¡ã¢ãªã¼</dt>
+<dd>å²ãå½ã¦ãããã©ã³ãã ã»ã¢ã¯ã»ã¹ã»ã¡ã¢ãªã¼ã®é (MB åä½)ã
+</dd>
+</dlentry></dl></p>
+<p>ãã³ãã¬ã¼ããã¨ã«ã以ä¸ã®ã¢ã¯ã·ã§ã³ã鏿ã§ãã¾ãã
+<ul>
+<li>ãã³ãã¬ã¼ããç·¨éããã«ã¯<uicontrol>ãç·¨éã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ãã³ãã¬ã¼ããåé¤ããã«ã¯<uicontrol>ãåé¤ã</uicontrol>ã鏿ãã¾ãã
+</li>
+</ul>ãã³ãã¬ã¼ãã追å ããã«ã¯ã表示ã®å³ä¸ã«ãã<uicontrol>æ£ç¬¦å· (+)</uicontrol> ã¢ã¤ã³ã³ãã¯ãªãã¯ãã¦ãã ããã
+</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="ja-jp">
+<title>ãã³ãã¬ã¼ãã®ç·¨é</title>
+<shortdesc>æ¢åã®ãã³ãã¬ã¼ããç·¨éãã¾ãã
+</shortdesc>
+<csbody>
+<p>ãã³ãã¬ã¼ããã¨ã«ã以ä¸ã®æ
å ±ã表示ããã¾ãã
+<dl>
+<dlentry>
+<dt>åå</dt>
+<dd>ãã³ãã¬ã¼ãã®ååã
+</dd>
+</dlentry><dlentry>
+<dt>ãã³ãã¼</dt>
+<dd>ãã³ãã¬ã¼ãã使ç¨ããããæ§æããã¦ãããªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã使ããä¼ç¤¾ã®ååã
+</dd>
+</dlentry><dlentry>
+<dt>ãã¼ã¸ã§ã³</dt>
+<dd>ãã³ãã¬ã¼ãã使ç¨ããããæ§æããã¦ãããªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ã
+</dd>
+</dlentry><dlentry>
+<dt>CPU æ°</dt>
+<dd>ãã³ãã¬ã¼ãã«å®ç¾©ããã¦ããããã»ããµã¼ã®æ°ã
+</dd>
+</dlentry><dlentry>
+<dt>ã¡ã¢ãªã¼</dt>
+<dd>ä»®æ³ãã·ã³ã«å²ãå½ã¦ãããã¡ã¢ãªã¼ã®é (MB åä½)ã
+</dd>
+</dlentry><dlentry>
+<dt>ãã£ã¹ã¯</dt>
+<dd>ãã£ã¹ã¯ã»ãµã¤ãº (GB åä½)ã
+</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>KVM ã²ã¹ããã¤ã³ã¹ãã¼ã«ããããã«ä½¿ç¨ããã ISO ãã¡ã¤ã«ã®ãã±ã¼ã·ã§ã³ã®ãã¡ã¤ã«ã»ãã¹ã
+</dd>
+</dlentry><dlentry>
+<dt>ã¹ãã¬ã¼ã¸ã»ãã¼ã«</dt>
+<dd>ç¹å®ã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ãã¾ãã¯ããã©ã«ãã®ã¹ãã¬ã¼ã¸ã»ãã¼ã«ã
+</dd>
+</dlentry><dlentry>
+<dt> ãããã¯ã¼ã¯</dt>
+<dd>KVM ã²ã¹ãã使ç¨ã§ããããã©ã«ãã®ãããã¯ã¼ã¯ã»ã¤ã³ã¿ã¼ãã§ã¼ã¹ã
+è¤æ°ã®ãããã¯ã¼ã¯ã鏿ãããã¨ãã§ãã¾ãã
+</dd>
+</dlentry></dl> 使ç¨ä¸å¯ã«ãªã£ã¦ããªããã£ã¼ã«ããç·¨éã§ãã¾ãã
+ãã£ã¼ã«ããç·¨éããå¾ã<uicontrol>ãä¿åã</uicontrol>ãã¯ãªãã¯ãã¦ãã ããã
+</p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>ãã³ãã¬ã¼ãã®è¿½å </title>
+<shortdesc>ãã³ãã¬ã¼ããã½ã¼ã¹ã»ã¡ãã£ã¢ãã追å ãã¾ãã
+ä»å¾ã®ãã£ã¹ã«ããªã¼ã®ããã«ãç¬èªã® ISO ã¤ã¡ã¼ã¸ããISOãã¹ãã¬ã¼ã¸ã»ãã¼ã«ã«è¿½å ã§ãã¾ãã</shortdesc>
+<csbody>
+<p>ã½ã¼ã¹ã»ã¡ãã£ã¢ã®ãã±ã¼ã·ã§ã³ã以ä¸ã®ãªãã·ã§ã³ãã鏿ãã¦ãã ããã
+<dl>
+<dlentry>
+<dt>ãã¼ã«ã« ISO ã¤ã¡ã¼ã¸</dt>
+<dd>ããã鏿ãã¦ãã·ã¹ãã ã§ä½¿ç¨å¯è½ãªã¤ã³ã¹ãã¼ã« ISO ã¤ã¡ã¼ã¸ããã¹ãã¬ã¼ã¸ã»ãã¼ã«ã§ã¹ãã£ã³ãã¾ãã
+</dd>
+</dlentry><dlentry>
+<dt>ãªã¢ã¼ã ISO ã¤ã¡ã¼ã¸</dt>
+<dd>ããã鏿ãã¦ãã¤ã³ã¹ãã¼ã« ISO ã¤ã¡ã¼ã¸ã®ãªã¢ã¼ãã»ãã±ã¼ã·ã§ã³ãæå®ãã¾ãã
+</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>ãã³ãã¬ã¼ãã®è¿½å - ãã¼ã«ã« ISO ã¤ã¡ã¼ã¸</title>
+<shortdesc>ãã³ãã¬ã¼ãããã¼ã«ã« ISO ã¤ã¡ã¼ã¸ãã追å ãã¾ãã
+</shortdesc>
+<csbody>
+<p>ã·ã¹ãã ã§ä½¿ç¨å¯è½ãª ISO ã¤ã¡ã¼ã¸ã表示ããã¾ãã
+<dl><dlentry>
+<dt>OS</dt>
+<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ååã
+</dd>
+</dlentry><dlentry>
+<dt>ãã¼ã¸ã§ã³</dt>
+<dd>ãªãã¬ã¼ãã£ã³ã°ã»ã·ã¹ãã ã¾ãã¯ãã£ã¹ããªãã¥ã¼ã·ã§ã³ã®ãã¼ã¸ã§ã³ã
+</dd>
+</dlentry><dlentry>
+<dt>ãµã¤ãº</dt>
+<dd>ISO ã¤ã¡ã¼ã¸ã®ãµã¤ãºã
+</dd>
+</dlentry></dl></p>
+<p>ãã³ãã¬ã¼ãã ISO ã¤ã¡ã¼ã¸ãã使ããã«ã¯ã以ä¸ã®ãªãã·ã§ã³ã鏿ãã¦ãã ããã
+<ul>
+<li>ãã³ãã¬ã¼ãã使ããå
ã«ãªã ISO ã¤ã¡ã¼ã¸ã鏿ãã¦ã<uicontrol>ã鏿ãã ISO ãããã³ãã¬ã¼ãã使ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
+</li>
+<li>ãªã¹ãããã¦ãã ISO ã¤ã¡ã¼ã¸ãããããããã³ãã¬ã¼ãã使ããã«ã¯ã<uicontrol>ããã¹ã¦ã</uicontrol>ã鏿ãã¦ãã<uicontrol>ã鏿ãã ISO ãããã³ãã¬ã¼ãã使ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
+</li>
+<li>使ç¨ããã ISO ã¤ã¡ã¼ã¸ãã¹ãã£ã³çµæã«è¦ã¤ãããªãå ´åã以ä¸ã®ãªãã·ã§ã³ã鏿ã§ãã¾ãã
+<ul>
+<li>ISO ã¤ã¡ã¼ã¸ã®ãã¹ãæå®ããã«ã¯ã<uicontrol>ãç¹å®ã® ISO ãã¡ã¤ã«ã使ç¨ããã</uicontrol>ã鏿ãã¾ãã
+</li>
+<li>ãã以ä¸ã® ISO ã¤ã¡ã¼ã¸ãæ¤ç´¢ããã«ã¯ã<uicontrol>ãISO ãããã«æ¤ç´¢ã</uicontrol>ãã¯ãªãã¯ãã¾ãã
+</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/kimchi.css b/src/wok/plugins/kimchi/ui/pages/help/kimchi.css
new file mode 100644
index 0000000..32fae4a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/kimchi.css
@@ -0,0 +1,208 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+BODY {
+ background: #FFFFFF;
+ margin-bottom: 1em;
+ margin-left: .5em;
+}
+
+bold {
+ font-weight: bold;
+}
+
+boldItalic {
+ font-weight: bold;
+ font-style: italic;
+}
+
+italic {
+ font-style: italic;
+}
+
+underlined {
+ text-decoration: underline;
+}
+
+uicontrol {
+ font-weight: bold;
+}
+
+filepath {
+ font-family: monospace, monospace;
+}.option {
+ font-family: monospace, monospace;
+}
+
+cmdname {
+ font-weight: bold;
+ font-family: monospace, monospace;
+}
+
+.defparmname {
+ font-weight: bold;
+ text-decoration: underline;
+ font-family: monospace, monospace;
+}
+
+.kwd {
+ font-weight: bold;
+}
+
+.defkwd {
+ font-weight: bold;
+ text-decoration: underline;
+}
+
+var {
+ font-style : italic;
+}
+
+strongwintitle {
+ font-weight : bold;
+}
+
+parmname {
+ font-weight: bold;
+ font-family: monospace, monospace;
+ white-space: nowrap;
+}
+
+code {
+ font-family: monospace, monospace;
+}
+
+pre {
+ font-family: monospace, monospace;
+}
+
+CITE {
+ font-style: italic;
+}
+
+EM {
+ font-style: italic;
+}
+
+STRONG {
+ font-weight: bold;
+}
+
+VAR {
+ font-style: italic;
+}
+
+dt {
+ font-weight: bold;
+}
+
+/***********************************************************
+ * Basic fonts
+ ***********************************************************/
+body,
+td,
+th,
+caption {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10pt;
+}
+
+pre, code {
+ font-family: MS Courier New, Courier, monospace;
+}
+
+h1, h2, h3 {
+ font-size: 12pt;
+ font-weight: bold;
+ color: #336699;
+}
+
+h4 {
+ font-size: 10pt;
+ font-weight: bold;
+ color: #336699;
+}
+
+/***********************************************************
+ * Basic indents, padding, and margin
+ ***********************************************************/
+body {
+ color: black;
+ background-color: white;
+ margin: 0;
+ padding-top: 0.2em;
+ padding-left: 0.6em;
+ padding-right: 0.2em;
+ padding-bottom: 1em;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ padding: 0;
+ margin-top: 1em;
+ margin-bottom: 0.75em;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+address,
+dl,
+li,
+p {
+ padding: 0;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+ margin-left: 0;
+ margin-right: 0;
+ line-height: 125%;
+}
+
+td dl {
+ margin-left: 2em;
+}
+
+pre {
+ padding: 0;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+ margin-left: 2em;
+ margin-right: 0;
+}
+
+ol,
+ul {
+ padding: 0;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+ margin-left: 2.00em;
+ margin-right: 0;
+}
+
+dd {
+ margin-left: 3.00em;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+}
+
+dt {
+ margin-left: 1.00em;
+ margin-top: 0.75em;
+}
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
new file mode 100644
index 0000000..e441955
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ko_KR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ko_KR
+
+dist_ko_KR_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
new file mode 100644
index 0000000..2d9f32b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="ko-kr">
+<title>ê²ì¤í¸</title>
+<shortdesc><wintitle>ê²ì¤í¸</wintitle> íì´ì§ìë ì ìë KVM ê°ì 머ì ì´ ëì´ë©ëë¤.</shortdesc>
+<csbody>
+<p>ê° ê²ì¤í¸ì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤.<dl><dlentry>
+<dt>ì´ë¦</dt>
+<dd>ê°ì 머ì ì ì´ë¦ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>ê°ì 머ì ì íë¡ì¸ì ì´ì©ë¥ ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë¤í¸ìí¬ I/O</dt>
+<dd>ì´ë¹ ë¤í¸ìí¬ ì
/ì¶ë ¥(I/O) ì ì¡ ìë(KB)ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ëì¤í¬ I/O</dt>
+<dd>ì´ë¹ ëì¤í¬ ì
/ì¶ë ¥(I/O) ì ì¡ ìë(KB)ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë¼ì´ë¸íì¼</dt>
+<dd>ê²ì¤í¸ ì´ì ì²´ì ì ìíì´ê±°ë, ê²ì¤í¸ê° íì±ì´ ìë ê²½ì° <tm tmtype="tm" trademark="Linux">Linux</tm> ë°°í¬ë¥¼ ëíë´ë ìì´ì½ì
ëë¤.</dd>
+</dlentry></dl></p>
+<p>ë¤ì ì¡°ì¹ ìì´ì½ì´ ê° ê²ì¤í¸ë§ë¤ íìë©ëë¤.<dl>
+<dlentry>
+<dt>ë¤ì ì¤ì </dt>
+<dd>ê²ì¤í¸ë¥¼ ë¤ì ì¤ì íë ¤ë©´ í´ë¦í©ëë¤. </dd>
+</dlentry><dlentry>
+<dt>ì ì(ìì ëë ì¤ì§)</dt>
+<dd>ê²ì¤í¸ì ì ìì ì¼ê±°ë ëë ¤ë©´ í´ë¦í©ëë¤. ìì´ì½ì´ 빨ê°ìì´ë©´ ì ìì´ êº¼ì§ ê²ì´ê³ ìì´ì½ì´ ë
¹ìì´ë©´ ì ìì´ ì¼ì§ ê²ì
ëë¤.</dd>
+</dlentry></dl> </p>
+<p>ê° ê²ì¤í¸ë§ë¤ ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
+<li>ê²ì¤í¸ ì´ì ì²´ì ì ì격 ì½ìì ì°ê²°íë ¤ë©´ <uicontrol>ì°ê²°</uicontrol>ì ì íí©ëë¤.</li>
+<li>ê²½ë¡ë¥¼ ì¤ì¹ ë§¤ì²´ë¡ ë³ê²½íë ¤ë©´ <uicontrol>매체 ê´ë¦¬</uicontrol>를 ì íí©ëë¤.</li>
+<li>ê²ì¤í¸ë¥¼ ë¤ì ì¤ì íë ¤ë©´ <uicontrol>ë¤ì ì¤ì </uicontrol>ì ì íí©ëë¤.</li>
+<li>기존 ê²ì¤í¸ì í¹ì±ì í¸ì§íë ¤ë©´ <uicontrol>í¸ì§</uicontrol>ì ì íí©ëë¤. ê²ì¤í¸ë ì¤ì§ ìíì¼ ëë§ í¸ì§í ì ììµëë¤.</li>
+<li>ê²ì¤í¸ë¥¼ ìì íë ¤ë©´ <uicontrol>ìì </uicontrol>를 ì íí©ëë¤.</li>
+</ul>ê²ì¤í¸ ëë ê°ì 머ì ì ìì±íë ¤ë©´ íì´ì§ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="ko-kr">
+<title>ê°ì 머ì ìì±</title>
+<shortdesc>기존 í
í리í¸ë¥¼ ì¬ì©íì¬ ê°ì 머ì ì ìì±í©ëë¤.</shortdesc>
+<csbody>
+<p> <ol>
+<li>ê°ì 머ì ì ìë³íë ë° ì¬ì©ë ì´ë¦ì ì
ë ¥íììì¤.</li>
+<li rev="rev1">í
í리í¸ë¥¼ ì ííììì¤. <ul>
+<li>í
í리í¸ê° ì¡´ì¬íë ê²½ì°, íìë í
íë¦¬í¸ ì¤ìì ì ííììì¤.</li>
+<li>í
í리í¸ê° ìë ê²½ì°, <uicontrol>í
íë¦¬í¸ ìì±</uicontrol>ì í´ë¦íì¬ í
í리í¸ë¥¼ ìì±íììì¤.</li>
+</ul></li>
+<li><uicontrol>ìì±</uicontrol>ì í´ë¦íììì¤.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="ko-kr">
+<title>ê²ì¤í¸ í¸ì§</title>
+<shortdesc>기존 ê°ì 머ì ì í¹ì±ì í¸ì§í©ëë¤. ì¼ë¶ í¹ì±ì ê²ì¤í¸ê° ì¤ì§ë ëììë§ í¸ì§í ì ììµëë¤.
+ë¤ë¥¸ í¹ì±ì ë¤ì ë¶í¸ìì ì ì©ë©ëë¤. </shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>ê° ê²ì¤í¸ì ëí´ ë¤ì ì ë³´ê° <wintitle>ì¼ë°</wintitle> íì íìë©ëë¤.<dl>
+<dlentry>
+<dt>ì´ë¦</dt>
+<dd>ê°ì 머ì ì ì´ë¦ì
ëë¤(ê²ì¤í¸ê° ì¤ì§ë ëììë§ í¸ì§í ì ìì).</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>íë¡ì¸ì ìì
ëë¤(ê²ì¤í¸ê° ì¤í ì¤ì¸ ê²½ì° ì í¬ê¸°ë ë¤ì ë¶í¸ìì ì ì©ë¨).</dd>
+</dlentry><dlentry>
+<dt>ë©ëª¨ë¦¬</dt>
+<dd>ë©ëª¨ë¦¬ ì©ë(MB)ì
ëë¤(ê²ì¤í¸ê° ì¤í ì¤ì¸ ê²½ì° ì ì©ëì ë¤ì ë¶í¸ìì ì ì©ë¨).</dd>
+</dlentry><dlentry>
+<dt>ìì´ì½</dt>
+<dd>ê²ì¤í¸ê° íì±ì´ ìë ë íì¬ ìí(ë¼ì´ë¸íì¼) ëì ì íìë Linux ë°°í¬ë¥¼ ëíë´ë ê·¸ëí½ ì´ë¯¸ì§ì
ëë¤.</dd>
+</dlentry></dl></p>
+<p>ë¤ì ì ë³´ê° <wintitle>ì¤í 리ì§</wintitle> íì íìë©ëë¤.</p>
+<dl><dlentry>
+<dt>ì¤í 리ì§</dt>
+<dd>ì¤ì¹ì ì¬ì©ë ISO íì¼ì ìì¹ë¥¼ íìí©ëë¤.</dd>
+</dlentry></dl>
+<p> ì¬ì© ìí¨ì¼ë¡ ì¤ì ëì§ ìì íë를 í¸ì§í ì ììµëë¤. íë를 í¸ì§í íì <uicontrol>ì ì¥</uicontrol>ì í´ë¦í©ëë¤. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="ko-kr">
+<title>ì¤í ë¦¬ì§ ì¥ì¹ ì¶ê°, êµì²´ ëë ë¶ë¦¬</title>
+<shortdesc rev="rev1">ê°ì 머ì ì ëí´ ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì¶ê°, êµì²´ ëë ë¶ë¦¬í ì ììµëë¤. ì§ìëë ì¥ì¹ë CDROMë¿ì
ëë¤. ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ í¸ì§íë ¤ë©´ ë¤ì ë¨ê³ë¥¼ ìííììì¤.</shortdesc>
+<csbody>
+<ol>
+<li><wintitle>ê²ì¤í¸ í¸ì§</wintitle> ì°½ìì <wintitle>ì¤í 리ì§</wintitle>를 ì ííììì¤.</li>
+<li>ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ êµì²´íë ¤ë©´ <uicontrol>주í©ì ì¬ëì(/)</uicontrol>ê° ìë 첫 ë²ì§¸ ìì´ì½ì í´ë¦íììì¤. ISO íì¼ ê²½ë¡ë¥¼ ì
ë ¥íê³ <uicontrol>êµì²´</uicontrol>를 í´ë¦íììì¤.</li>
+<li>ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ë¶ë¦¬íë ¤ë©´ <uicontrol>빨ê°ì ëì(-)</uicontrol>ê° ìë ë ë²ì§¸ ìì´ì½ì í´ë¦íììì¤. ìì ì¬ë¶ë¥¼ íì¸íê³ <uicontrol>íì¸</uicontrol>ì í´ë¦íììì¤.</li>
+<li>ì¤í ë¦¬ì§ ì¥ì¹ë¥¼ ì¶ê°íë ¤ë©´ ë
¹ì <uicontrol>ëí기 ë¶í¸(+)</uicontrol>ê° ìë ì¸ ë²ì§¸ ìì´ì½ì í´ë¦íììì¤. ì¥ì¹ ì´ë¦ ë° ISO íì¼ ê²½ë¡ë¥¼ ì
ë ¥íê³ <uicontrol>ë¶ë¦¬</uicontrol>를 í´ë¦íììì¤.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="ko-kr">
+<title>VMì CDROM êµì²´</title>
+<shortdesc rev="rev1">ì¤ì¹ê° ìë£ë íì ê°ì 머ì ì ëí CDROMì 컨í
ì¸ ë¥¼ ë°ê¿ ì ììµëë¤.</shortdesc>
+<csbody>
+<ol>
+<li>ê°ì 머ì ì´ ììëìëì§ íì¸íììì¤.</li>
+<li>ì¡°ì¹ ë©ë´ìì <uicontrol>매체 ê´ë¦¬</uicontrol>를 ì ííììì¤.</li>
+<li>CDROMì íì¬ ë¡ëë í목ì ë³ê²½í기 ìí´ hdc íë ìì ìë <uicontrol>주í©ì ì¬ëì(/)</uicontrol> ìì´ì½ì í´ë¦íììì¤.</li>
+<li><wintitle>VMì CDROM êµì²´</wintitle> íì´ì§ìì ISO íì¼ ê²½ë¡ë¥¼ ì
ë ¥íììì¤. ë¤ë¥¸ ë íëë ì½ê¸° ì ì©ì
ëë¤.</li>
+<li><uicontrol>êµì²´</uicontrol>를 í´ë¦íììì¤.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita
new file mode 100644
index 0000000..ee4a9c3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="ko-kr">
+<title>í¸ì¤í¸</title>
+<shortdesc><wintitle>í¸ì¤í¸</wintitle> íì´ì§ìë í¸ì¤í¸ ìì¤í
ì ëí ì ë³´ê° íìëë©° ì´ íì´ì§ë¥¼ ì¬ì©íì¬ í¸ì¤í¸ë¥¼ ì¢
ë£ ë° ë¤ì ììíê±°ë í¸ì¤í¸ì ì°ê²°í ì ììµëë¤.</shortdesc>
+<csbody>
+<p>í¸ì¤í¸ì ëí´ ë¤ì ì¡°ì¹ë¥¼ ìíí ì ììµëë¤.<ul>
+<li>í¸ì¤í¸ ìì¤í
ì ì¢
ë£íë ¤ë©´ <uicontrol>ìì¤í
ì¢
ë£</uicontrol>를 ì íí©ëë¤.</li>
+<li>í¸ì¤í¸ ìì¤í
ì ë¤ì ììíë ¤ë©´ <uicontrol>ë¤ì ìì</uicontrol>ì ì íí©ëë¤.</li>
+<li>ì´ë¯¸ ì°ê²°ëì´ ìì§ ìì ê²½ì°, í¸ì¤í¸ ìì¤í
ì ëí VNC ì°ê²°ì ììíë ¤ë©´ <uicontrol>ì°ê²°</uicontrol>ì ì íí©ëë¤.</li>
+</ul></p>
+<p>í¸ì¤í¸ì ëí ì 보를 íìíë ¤ë©´ ë¤ì ì¹ì
ì í´ë¦íììì¤.<dl>
+<dlentry>
+<dt>기본 ì ë³´</dt>
+<dd>ì´ ì¹ì
ìë í¸ì¤í¸ ì´ì ì²´ì ë°°í¬, ë²ì , ì½ë ì´ë¦, íë¡ì¸ì ì í, ë©ëª¨ë¦¬ ì©ë(GB) ë±ì´ íìë©ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ìì¤í
íµê³</dt>
+<dd>ì´ ì¹ì
ìë í¸ì¤í¸ì CPU, ë©ëª¨ë¦¬, ëì¤í¬ I/O, ë¤í¸ìí¬ I/Oì ëí íµê³ë¥¼ íìíë ê·¸ëíê° íìë©ëë¤. í¸ì¤í¸ íì ë ë¬ì ë ë°ì´í° ìì§ì ê³ìíë ¤ë©´ <uicontrol>ì´ íì´ì§ë¥¼ ë ë íì ë°ì´í° ìì§</uicontrol>ì ì íí©ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ìíí¸ì¨ì´ ì
ë°ì´í¸</dt>
+<dd>ì´ ì¹ì
ìë í¨í¤ì§ ì´ë¦, ë²ì , ìí¤í
ì², ì ì¥ì를 ë¹ë¡¯íì¬ ì¬ì© ê°ë¥í ì
ë°ì´í¸ê° ìë 모ë í¨í¤ì§ì ëí ì ë³´ê° íìë©ëë¤. <uicontrol>모ë ì
ë°ì´í¸</uicontrol>를 ì ííì¬ ëì´ë 모ë í¨í¤ì§ë¥¼ ì
ë°ì´í¸í ì ììµëë¤. ì
ë°ì´í¸ì ëí´ ê°ë³ í¨í¤ì§ë¥¼ ì íí ìë ììµëë¤.</dd>
+</dlentry><dlentry>
+<dt>ì ì¥ì</dt>
+<dd>ì´ ì¹ì
ìë í¸ì¤í¸ ìì¤í
ê³¼ ì°ê´ë ì ì¥ìê° íìë©ëë¤. ì ì¥ì를 ì¶ê°íê±°ë, ì¬ì©ì¼ë¡ ì¤ì íê±°ë, í¸ì§íê±°ë, ì ê±°í ì ììµëë¤. ì ì¥ì를 ì¶ê°íë©´ ì ì¥ìê° í¸ì¤í¸ ìì¤í
ê³¼ ì°ê´ëë©°, ì ì¥ì를 ì¬ì©ì¼ë¡ ì¤ì íë©´ í¸ì¤í¸ê° ì ì¥ìì ì¡ì¸ì¤í ì ììµëë¤. í´ë¹ ìì¤í
ì´ Red Hat Enterprise Linux ëë Fedoraì¸ ê²½ì°, <filepath>yum</filepath> ì ì¥ì를 ì¶ê°í ì ììµëë¤.
+í´ë¹ ìì¤í
ì´ Ubuntu ëë Debianì¸ ê²½ì°, <filepath>deb</filepath> ì ì¥ì를 ì¶ê°íììì¤.<p>yum ì ì¥ìë¡ ìì
íë ê²½ì°, GPG ê²ì¬ë¥¼ ì¶ê°íì¬ ì´ ì ì¥ìì í¨í¤ì§ê° ììëì§ ììëì§ íì¸í ì ììµëë¤.
+ì ì¥ì를 ì íí í <uicontrol>í¸ì§</uicontrol>ì ì ííììì¤. <uicontrol>ì</uicontrol>를 ì ííì¬ GPG ê²ì¬ë¥¼ ì¬ì©ì¼ë¡ ì¤ì í í ì ì¥ìì ëí GPG í¤ íì¼ì URLì ì
ë ¥íììì¤.</p></dd>
+</dlentry><dlentry>
+<dt>ëë²ê·¸ ë³´ê³ ì</dt>
+<dd>ì´ ì¹ì
ìë ì´ë¦ ë° íì¼ ê²½ë¡ë¥¼ í¬í¨í ëë²ê·¸ ë³´ê³ ìê° íìë©ëë¤.
+ì ë³´ê³ ì ìì±, 기존 ë³´ê³ ì ì´ë¦ ë°ê¾¸ê¸°, ì ê±°, ë¤ì´ë¡ë ë±ì ìµì
ì¤ìì ì íí ì ììµëë¤.<p>ëë²ê·¸ ë³´ê³ ìë <cmdname>sosreport</cmdname> ëª
ë ¹ì ì¬ì©íì¬ ìì±ë©ëë¤. ì´ë Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora ë° Ubuntu ë°°í¬ìì ì¬ì© ê°ë¥í©ëë¤. ì´ ëª
ë ¹ì êµ¬ì± ë° ì§ë¨ ì ë³´(ì: ì¤í ì¤ì¸ 커ë ë²ì , ë¡ëë 모ë, ìì¤í
ë° ìë¹ì¤ êµ¬ì± íì¼)를 í¬í¨íë .tar íì¼ì ìì±í©ëë¤.
+ëí ì´ ëª
ë ¹ì ì¸ë¶ íë¡ê·¸ë¨ì ì¤ííì¬ ì¶ê° ì 보를 ìì§íê³ ê²°ê³¼ ìì¹´ì´ë¸ì ì´ ì¶ë ¥ì ì ì¥í©ëë¤.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita
new file mode 100644
index 0000000..451510f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="ko-kr">
+<title>ë¤í¸ìí¬</title>
+<shortdesc><wintitle>ë¤í¸ìí¬</wintitle> íì´ì§ìë ë¤í¸ìí¬ ì°ê²°ì ëí ì ë³´ê° íìë©ëë¤.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>ë¤í¸ìí¬ ì´ë¦</dt>
+<dd>ë¤í¸ìí¬ì ì´ë¦ ëë <uicontrol>기본ê°</uicontrol>ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ìí</dt>
+<dd>ë¤í¸ìí¬ì ìí(íì±ì ê²½ì° ë
¹ì, ë¹íì±ì ê²½ì° ë¹¨ê°ì)ì
ëë¤. </dd>
+</dlentry><dlentry>
+<dt>ë¤í¸ìí¬ ì í</dt>
+<dd>ë¤í¸ìí¬ ì íì
ëë¤. ì: <uicontrol>NAT</uicontrol>(Network Address Translation)</dd>
+</dlentry><dlentry>
+<dt>ì¸í°íì´ì¤</dt>
+<dd>ë¤í¸ìí¬ ì¸í°íì´ì¤ì
ëë¤. ì: <uicontrol>virbr0</uicontrol>(기본ê°)</dd>
+</dlentry><dlentry>
+<dt>주ì ê³µê°</dt>
+<dd>IP 주ìì
ëë¤.</dd>
+</dlentry></dl></p>
+<p>ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
+<li rev="rev1">ë¤í¸ìí¬ ì°ê²°ì ììíë ¤ë©´ <uicontrol>ìì</uicontrol>ì ì íí©ëë¤.</li>
+<li>ë¤í¸ìí¬ ì°ê²°ì ì¢
ë£íë ¤ë©´ <uicontrol>ì¤ì§</uicontrol>를 ì íí©ëë¤.</li>
+<li>ì°ê²° ì 보를 ìì íë ¤ë©´ <uicontrol>ìì </uicontrol>를 ì íí©ëë¤.</li>
+</ul>ë¤í¸ìí¬ë¥¼ ìì±íë ¤ë©´ íë©´ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="ko-kr">
+<title>ë¤í¸ìí¬ ìì±</title>
+<shortdesc>ë¤í¸ìí¬ë¥¼ ìì±í©ëë¤.</shortdesc>
+<csbody>
+<p> <ol>
+<li>ë¤í¸ìí¬ì ì´ë¦ì ì
ë ¥íììì¤.</li>
+<li>ë¤í¸ìí¬ ì íì ì ííë ¤ë©´ í´ë¦íììì¤. <dl rev="rev1"><dlentry>
+<dt><uicontrol>격리ë¨</uicontrol></dt>
+<dd>격리 모ëì
ëë¤. ê²ì¤í¸ë ì¸ë¶ ìì¤í
ì ëí´ íµì ì ë³´ë´ê±°ë ë°ì ì ììµëë¤.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Network Address Translation 모ëì
ëë¤. ê²ì¤í¸ê° ì¸ë¶ ìì¤í
ì¼ë¡ ë³´ë´ë íµì ìì í¸ì¤í¸ IP 주ì를 ì¬ì©í©ëë¤. ì¸ë¶ ìì¤í
ì ê²ì¤í¸ë¡ì íµì ì ììí ì ììµëë¤.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>ë¸ë¦¿ì§ë¨</uicontrol></dt>
+<dd>ë¸ë¦¿ì§ 모ëì
ëë¤. ê²ì¤í¸ë ì¸ë¶ ìì¤í
ê³¼ íµì í ì ìê³ ì¸ë¶ ìì¤í
ì ë¤í¸ìí¬ìì 물리ì ìì¤í
ì²ë¼ ê²ì¤í¸ì ì ìí ì ììµëë¤. ë¸ë¦¿ì§ 모ëì ê²½ì°, ì¶ê° 목ì ì§ ë° VLAN ì 보를 ì§ì í´ì¼ í©ëë¤.</dd>
+</dlentry></dl></li>
+<li><uicontrol>ìì±</uicontrol>ì í´ë¦íììì¤.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
new file mode 100644
index 0000000..2e6f5e8
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="ko-kr">
+<title>ì¤í 리ì§</title>
+<shortdesc><wintitle>ì¤í 리ì§</wintitle> íì´ì§ìë ë°ë¡ ì¬ì©í ì ìë '기본' ë° 'ISO' ì¤í ë¦¬ì§ íì í¬í¨íì¬ ì¬ì© ê°ë¥í ì¤í ë¦¬ì§ íì´ ëì´ë©ëë¤.
+ì¬ì©ì ì ì© ISO를 ì¬ì©íë ¤ë©´ ì´ë¥¼ 'ISO' ì¤í ë¦¬ì§ í ê²½ë¡ì ì¶ê°íììì¤.</shortdesc>
+<csbody>
+<p>ê° ì¤í ë¦¬ì§ íì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤.<dl>
+<dlentry>
+<dt>ì´ë¦</dt>
+<dd>ì¤í ë¦¬ì§ íì ì´ë¦ ë° ì¬ì©ë¥ ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ìí</dt>
+<dd>ì¤í ë¦¬ì§ íì ìí(íì±ì ê²½ì° ë
¹ì, ë¹íì±ì ê²½ì° ë¹¨ê°ì)ì
ëë¤. </dd>
+</dlentry><dlentry>
+<dt>ìì¹</dt>
+<dd>ì¤í ë¦¬ì§ íì ìì¹ì ëí íì¼ ê²½ë¡ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ì í</dt>
+<dd>ì¤í ë¦¬ì§ íì ì íì
ëë¤. ì: <uicontrol>dir</uicontrol></dd>
+</dlentry><dlentry>
+<dt>ì©ë</dt>
+<dd>ì¤í ë¦¬ì§ íìì ê³µê°ì ìì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>í ë¹ë¨</dt>
+<dd>ì¤í ë¦¬ì§ íì ì´ë¯¸ í ë¹ë ê³µê°ì ìì
ëë¤.</dd>
+</dlentry></dl></p>
+<p>ê° ì¤í ë¦¬ì§ íë§ë¤ ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
+<li>ì¬ì© ê°ë¥íëë¡ ì¤í ë¦¬ì§ íì íì±ííë ¤ë©´ <uicontrol>íì±í</uicontrol>를 ì íí©ëë¤.</li>
+<li>ì¤í ë¦¬ì§ íì ë¹íì±ííë ¤ë©´ <uicontrol>ë¹íì±í</uicontrol>를 ì íí©ëë¤.</li>
+<li>ë¹íì± ì¤í ë¦¬ì§ íì ì ê±°íë ¤ë©´ <uicontrol>ì ì ì·¨ì</uicontrol>를 ì íí©ëë¤.</li>
+</ul></p>
+<p>ì¤í ë¦¬ì§ íì ëí ì¤í ë¦¬ì§ ë³¼ë¥¨ ì¸ë¶ì¬íì íìíë ¤ë©´ ì¤í ë¦¬ì§ í íì ì¤ë¥¸ìª½ì ìë íì´í를 í´ë¦íììì¤. ì¸ë¶ì¬íìë ë¤ìì´ í¬í¨ë©ëë¤.<dl><dlentry>
+<dt>ì í</dt>
+<dd>볼륨ì ì íì
ëë¤. ì: <uicontrol>íì¼</uicontrol></dd>
+</dlentry><dlentry>
+<dt>íì</dt>
+<dd>íìì ì íì ë°ë¼ ë¬ë¼ì§ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ì©ë</dt>
+<dd>ì¤í ë¦¬ì§ ë³¼ë¥¨ì í¬ê¸°ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>í ë¹</dt>
+<dd>ì¤í ë¦¬ì§ íì ì´ë¯¸ í ë¹ë ê³µê°ì ìì
ëë¤.</dd>
+</dlentry></dl>ì¤í ë¦¬ì§ íì ì ìíë ¤ë©´ íë©´ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="ko-kr">
+<title>ì¤í ë¦¬ì§ í ì ì</title>
+<shortdesc> ì¤í ë¦¬ì§ íì ì ìí©ëë¤.</shortdesc>
+<csbody>
+<p> <ol>
+<li><uicontrol>ì¤í ë¦¬ì§ í ì´ë¦</uicontrol> íëìì, ì¤í ë¦¬ì§ íì ìë³íë ë° ì¬ì©ë ì´ë¦ì ì
ë ¥íììì¤.</li>
+<li><uicontrol>ì¤í ë¦¬ì§ í ì í</uicontrol> 목ë¡ìì ë¤ì ì íì ì ííììì¤. <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>ëë í 리 íì ì§ì í©ëë¤. <uicontrol>DIR</uicontrol> ì íì ì íí ê²½ì°, <uicontrol>ì¤í ë¦¬ì§ ê²½ë¡</uicontrol>(ì¤í ë¦¬ì§ íì íì¼ ê²½ë¡)를 ì
ë ¥í©ëë¤.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>ë¤í¸ìí¬ íì¼ ìì¤í
íì ì§ì í©ëë¤. <uicontrol>NFS</uicontrol>를 ì íí ê²½ì°, <uicontrol>NFS ìë² IP 주ì</uicontrol> ë° <uicontrol>NFS ê²½ë¡</uicontrol>(ìì ëë í 리ì ê²½ë¡)를 ì
ë ¥í©ëë¤.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>iSCSI ìë²ì í ë¹ë ëìì 기ë°ì¼ë¡ íì ì§ì í©ëë¤.
+<uicontrol>iSCSI</uicontrol>를 ì íí ê²½ì°, iSCSI ìë²ì ëí <uicontrol>iSCSI ìë² IP 주ì</uicontrol> ë° <uicontrol>ëì</uicontrol>ì ì
ë ¥í©ëë¤. ì íì ì¼ë¡, iSCSI ì¸ì¦ì ì¶ê°íëë¡ ì íí ì ììµëë¤.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>ë
¼ë¦¬ì </uicontrol></dt>
+<dd>ë
¼ë¦¬ì 볼륨 ì¤í ë¦¬ì§ íì ì§ì í©ëë¤. <uicontrol>ì¥ì¹ ê²½ë¡</uicontrol>ìì ì¥ì¹ì ëí ìì¹ë¥¼ ì íí©ëë¤.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI íì´ë² ì±ë</uicontrol></dt>
+<dd>SCSI íì´ë² ì±ëì 기ë°ì¼ë¡ íì ì§ì í©ëë¤. ì¬ì©í SCSI ì´ëí°ë¥¼ ì íí©ëë¤.</dd>
+</dlentry></dl></li>
+<li><uicontrol>ìì±</uicontrol>ì í´ë¦íììì¤.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
new file mode 100644
index 0000000..de16d6e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="ko-kr">
+<title>í
í리í¸</title>
+<shortdesc><wintitle>í
í리í¸</wintitle> íì´ì§ìë KVM ê²ì¤í¸ë¥¼ ìì±íë ë° ì¬ì©ë ì ìë ì ìë ê°ì 머ì í
í리í¸ê° íìë©ëë¤.</shortdesc>
+<csbody>
+<p>ê° í
í리í¸ì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤.<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>ì´ì ì²´ì ëë ë°°í¬ì ì´ë¦ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë²ì </dt>
+<dd>ì´ì ì²´ì ëë ë°°í¬ì ë²ì ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>í
í리í¸ì ëí´ ì ìë íë¡ì¸ìì ìì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë©ëª¨ë¦¬</dt>
+<dd>í ë¹ë RAM(Random Access Memory)ì ì(MB)ì
ëë¤.</dd>
+</dlentry></dl></p>
+<p>ê° í
í리í¸ë§ë¤ ë¤ì ì¡°ì¹ë¥¼ ì íí ì ììµëë¤.<ul>
+<li>í
í리í¸ë¥¼ í¸ì§íë ¤ë©´ <uicontrol>í¸ì§</uicontrol>ì ì íí©ëë¤.</li>
+<li>í
í리í¸ë¥¼ ìì íë ¤ë©´ <uicontrol>ìì </uicontrol>를 ì íí©ëë¤.</li>
+</ul>í
í리í¸ë¥¼ ì¶ê°íë ¤ë©´ íë©´ ì¤ë¥¸ìª½ ìë¨ì ìë <uicontrol>ëí기(+)</uicontrol> ìì´ì½ì í´ë¦í©ëë¤.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="ko-kr">
+<title>í
íë¦¬í¸ í¸ì§</title>
+<shortdesc>기존 í
í리í¸ë¥¼ í¸ì§í©ëë¤.</shortdesc>
+<csbody>
+<p>ê° í
í리í¸ì ëí´ ë¤ì ì ë³´ê° íìë©ëë¤. <dl>
+<dlentry>
+<dt>ì´ë¦</dt>
+<dd>í
í리í¸ì ì´ë¦ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ê³µê¸ì
ì²´</dt>
+<dd>í
í리í¸ê° ì¬ì©íëë¡ êµ¬ì±ë ì´ì ì²´ì ëë ë°°í¬ë¥¼ ìì±í íì¬ì ì´ë¦ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë²ì </dt>
+<dd>í
í리í¸ê° ì¬ì©íëë¡ êµ¬ì±ë ì´ì ì²´ì ëë ë°°í¬ì ë²ì ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>CPU ì</dt>
+<dd>í
í리í¸ì ëí´ ì ìë íë¡ì¸ìì ìì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë©ëª¨ë¦¬</dt>
+<dd>ê°ì 머ì ì í ë¹ë ë©ëª¨ë¦¬ ì©ë(MB)ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ëì¤í¬</dt>
+<dd>ëì¤í¬ í¬ê¸°(GB)ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>KVM ê²ì¤í¸ë¥¼ ì¤ì¹íë ë° ì¬ì©ë ISO íì¼ì ìì¹ì ëí íì¼ ê²½ë¡ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ì¤í ë¦¬ì§ í</dt>
+<dd>í¹ì ì¤í ë¦¬ì§ í ëë 기본 ì¤í ë¦¬ì§ íì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë¤í¸ìí¬</dt>
+<dd>KVM ê²ì¤í¸ì ì¬ì© ê°ë¥í 기본 ë¤í¸ìí¬ ì¸í°íì´ì¤ì
ëë¤. ì¬ë¬ ë¤í¸ìí¬ë¥¼ ì íí ì ììµëë¤.</dd>
+</dlentry></dl> ì¬ì© ìí¨ì¼ë¡ ì¤ì ëì§ ìì íë를 í¸ì§í ì ììµëë¤. íë를 í¸ì§í íì <uicontrol>ì ì¥</uicontrol>ì í´ë¦í©ëë¤. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>í
íë¦¬í¸ ì¶ê°</title>
+<shortdesc>ìì¤ ë§¤ì²´ë¡ë¶í° í
í리í¸ë¥¼ ì¶ê°í©ëë¤. ë¤ì ê²ìì ëí´ 'ISO' ì¤í ë¦¬ì§ íì ì¬ì©ì ì ì© ISO ì´ë¯¸ì§ë¥¼ ì¶ê°í ì ììµëë¤. </shortdesc>
+<csbody>
+<p>ë¤ì ìµì
ì¤ìì ìì¤ ë§¤ì²´ì ìì¹ë¥¼ ì ííììì¤.<dl>
+<dlentry>
+<dt>ë¡ì»¬ ISO ì´ë¯¸ì§</dt>
+<dd>ìì¤í
ìì ì¬ì© ê°ë¥í ì¤ì¹ ISO ì´ë¯¸ì§ì ì¤í ë¦¬ì§ íì ì¤ìºíë ¤ë©´ ì íí©ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ì격 ISO ì´ë¯¸ì§</dt>
+<dd>ì¤ì¹ ISO ì´ë¯¸ì§ì ì격 ìì¹ë¥¼ ì§ì íë ¤ë©´ ì íí©ëë¤.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>í
íë¦¬í¸ ì¶ê° - ë¡ì»¬ ISO ì´ë¯¸ì§</title>
+<shortdesc>ë¡ì»¬ ISO ì´ë¯¸ì§ë¡ë¶í° í
í리í¸ë¥¼ ì¶ê°í©ëë¤.</shortdesc>
+<csbody>
+<p>ìì¤í
ìì ì¬ì© ê°ë¥í ISO ì´ë¯¸ì§ê° íìë©ëë¤.<dl><dlentry>
+<dt>OS</dt>
+<dd>ì´ì ì²´ì ëë ë°°í¬ì ì´ë¦ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>ë²ì </dt>
+<dd>ì´ì ì²´ì ëë ë°°í¬ì ë²ì ì
ëë¤.</dd>
+</dlentry><dlentry>
+<dt>í¬ê¸°</dt>
+<dd>ISO ì´ë¯¸ì§ì í¬ê¸°ì
ëë¤.</dd>
+</dlentry></dl></p>
+<p>ISO ì´ë¯¸ì§ë¡ë¶í° í
í리í¸ë¥¼ ìì±íë ¤ë©´ ë¤ì ìµì
ì¤ìì ì ííììì¤.<ul>
+<li>í
í리í¸ë¥¼ ìì±í기 ìí ISO ì´ë¯¸ì§ë¥¼ ì íí í <uicontrol>ì íí ISOë¡ë¶í° í
íë¦¬í¸ ìì±</uicontrol>ì í´ë¦í©ëë¤.</li>
+<li>ëì´ë ê° ISO ì´ë¯¸ì§ë¡ë¶í° í
í리í¸ë¥¼ ìì±íë ¤ë©´ <uicontrol>모ë</uicontrol>를 ì íí í <uicontrol>ì íí ISOë¡ë¶í° í
íë¦¬í¸ ìì±</uicontrol>ì í´ë¦í©ëë¤.</li>
+<li>ì¬ì©íë ¤ë ISO ì´ë¯¸ì§ê° ì¤ìº ê²°ê³¼ì íìëì§ ìë ê²½ì°, ë¤ì ìµì
ì¤ìì ì íí ì ììµëë¤.<ul>
+<li>ISO ì´ë¯¸ì§ì ê²½ë¡ë¥¼ ì§ì íë ¤ë©´ <uicontrol>í¹ì ISO íì¼ì ì¬ì©íë ¤ê³ í©ëë¤.</uicontrol>를 ì íí©ëë¤.</li>
+<li>ì¶ê° ISO ì´ë¯¸ì§ë¥¼ ê²ìíë ¤ë©´ <uicontrol>ì¶ê° ISO ê²ì</uicontrol>ì í´ë¦í©ëë¤.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
new file mode 100644
index 0000000..7fc2cb0
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+pt_BR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/pt_BR
+
+dist_pt_BR_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
new file mode 100644
index 0000000..ac58d5c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="pt-br">
+<title>Máquinas Virtuais</title>
+<shortdesc>A página <wintitle>Máquinas Virtuais</wintitle> lista as máquinas virtuais
+KVM definidas.</shortdesc>
+<csbody>
+<p>Para cada convidado, as informações a seguir são exibidas:<dl><dlentry>
+<dt>Nome</dt>
+<dd>Nome da máquina virtual.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Porcentagem de utilização do processador na máquina virtual.</dd>
+</dlentry><dlentry>
+<dt>E/S de rede</dt>
+<dd>Taxa de transmissão de entrada/saÃda de rede em KB por segundo.</dd>
+</dlentry><dlentry>
+<dt>E/S de disco</dt>
+<dd>Taxa de transmissão de entrada/saÃda de disco em KB por segundo.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>Estado do console do sistema operacional guest ou um Ãcone que representa
+a distribuição <tm tmtype="tm" trademark="Linux">Linux</tm> se o
+convidado não estiver ativo.</dd>
+</dlentry></dl></p>
+<p>Os Ãcones de ações a seguir são exibidos para cada convidado:<dl>
+<dlentry>
+<dt>Reiniciar</dt>
+<dd>Clique para Reiniciar o convidado. </dd>
+</dlentry><dlentry>
+<dt>Energia (iniciar ou parar)</dt>
+<dd>Clique para ligar ou desligar o convidado. Se o Ãcone estiver vermelho,
+a energia está desligada; se o Ãcone estiver verde, a energia está ligada.</dd>
+</dlentry></dl> </p>
+<p>As ações a seguir podem ser selecionadas para cada convidado:<ul>
+<li>Selecione <uicontrol>Conectar</uicontrol> para conectar-se ao console
+remoto para o sistema operacional guest.</li>
+<li>Selecione <uicontrol>Gerenciar mÃdia</uicontrol> para alterar o caminho
+para a mÃdia de instalação.</li>
+<li>Selecione <uicontrol>Reiniciar</uicontrol> para Reiniciar o convidado.</li>
+<li>Selecione <uicontrol>Editar</uicontrol> para editar as propriedades de um
+convidado existente. Os Máquinas Virtuais podem ser editados somente quando interrompidos.</li>
+<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o convidado.</li>
+</ul>Para criar um convidado, ou máquina virtual, clique no Ãcone <uicontrol>mais
+(+)</uicontrol> na parte superior direita da página.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="en-us">
+<title>Criar máquina virtual</title>
+<shortdesc>Crie uma máquina virtual usando um modelo existente.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Digite o nome a ser usado para identificar a máquina virtual.</li>
+<li rev="rev1">Selecione um modelo. <ul>
+<li>Se existirem modelos, selecione a partir dos modelos exibidos.</li>
+<li>Se não existir nenhum modelo, clique em <uicontrol>Criar um modelo</uicontrol> para
+criar um modelo.</li>
+</ul></li>
+<li>Clique em <uicontrol>Criar</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="en-us">
+<title>Editar convidado</title>
+<shortdesc>Edite as propriedades de uma máquina virtual existente. Algumas propriedades podem ser editadas enquanto o convidado está interrompido. Outras entrarão em vigor na próxima inicialização.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Para cada convidado, as informações a seguir são exibidas na guia <wintitle>Geral</wintitle>:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Nome da máquina virtual. (somente pode ser editado enquanto o convidado está interrompido)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Número de processadores. (se o convidado estiver em execução, uma nova quantia entrará em vigor na próxima inicialização)</dd>
+</dlentry><dlentry>
+<dt>Memória</dt>
+<dd>Quantia de memória em MB. (se o convidado estiver em execução, uma nova quantia entrará em vigor na próxima inicialização)</dd>
+</dlentry><dlentry>
+<dt>Ãcone</dt>
+<dd>Imagem gráfica representando a distribuição Linux a ser exibida
+no lugar do status atual (Livetile) quando o convidado não está ativo.</dd>
+</dlentry></dl></p>
+<p>As informações a seguir são exibidas na guia <wintitle>Armazenamento</wintitle>.</p>
+<dl><dlentry>
+<dt>Armazenamento</dt>
+<dd>Exibe o local do arquivo ISO usado para instalação.</dd>
+</dlentry></dl>
+<p> Os campos que não estão desativados podem ser editados. Depois de editar um campo,
+clique em <uicontrol>Salvar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="en-us">
+<title>Incluir, substituir ou remover um dispositivo de armazenamento</title>
+<shortdesc rev="rev1">Ã possÃvel incluir, substituir ou remover um dispositivo de armazenamento
+para sua máquina virtual. O único dispositivo suportado é CD-ROM. Para editar
+seus dispositivos de armazenamento, siga estas etapas:</shortdesc>
+<csbody>
+<ol>
+<li>Na janela <wintitle>Editar convidado</wintitle>, selecione <wintitle>Armazenamento</wintitle>.</li>
+<li>Para substituir um dispositivo de armazenamento, clique no primeiro Ãcone com a <uicontrol>barra
+laranja (/)</uicontrol>. Insira o caminho do arquivo ISO e clique em <uicontrol>Substituir</uicontrol>.</li>
+<li>Para remover um dispositivo de armazenamento, clique no segundo Ãcone com o <uicontrol>traço
+vermelho (-)</uicontrol>. Confirme a exclusão e clique em <uicontrol>OK</uicontrol>.</li>
+<li>Para incluir um dispositivo de armazenamento, clique no terceiro Ãcone com o <uicontrol>sinal de
+mais (+)</uicontrol> verde. Insira um nome de dispositivo e um caminho de arquivo ISO e clique em <uicontrol>Conectar</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="en-us">
+<title>Substituir um CD-ROM da VM</title>
+<shortdesc rev="rev1">à possÃvel substituir o conteúdo do CD-ROM para
+uma máquina virtual após a instalação ser concluÃda.</shortdesc>
+<csbody>
+<ol>
+<li>Assegure-se de que a máquina virtual esteja iniciada.</li>
+<li>No menu Ações, selecione <uicontrol>Gerenciar mÃdia</uicontrol>.</li>
+<li>Para alterar o que está atualmente carregado no CD-ROM, clique no Ãcone <uicontrol>barra
+laranja (/)</uicontrol> próximo ao campo hdc.</li>
+<li>Na página <wintitle>Substituir um CD-ROM da VM</wintitle>, insira
+o caminho do arquivo ISO. Os outros dois campos são somente leitura.</li>
+<li>Clique em <uicontrol>Substituir</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita
new file mode 100644
index 0000000..88f7eb2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="pt-br">
+<title>Host</title>
+<shortdesc>A página <wintitle>Host</wintitle> mostra informações sobre
+o sistema host e permite encerrar, reiniciar e conectar
+ao host.</shortdesc>
+<csbody>
+<p>à possÃvel executar as ações a segur no host:<ul>
+<li>Selecione <uicontrol>Encerrar</uicontrol> para encerrar o sistema
+host.</li>
+<li>Selecione <uicontrol>Reiniciar</uicontrol> para reiniciar o sistema host.</li>
+<li>Selecione <uicontrol>Conectar</uicontrol> para abrir uma conexão VNC
+para o sistema host, se ele já não estiver conectado.</li>
+</ul></p>
+<p>Clique nas seções a seguir para exibir informações sobre o host:<dl>
+<dlentry>
+<dt>Informações básicas</dt>
+<dd>Esta seção exibe a distribuição do sistema operacional do host,
+a versão e o nome do código, bem como o tipo de processador e quantia de
+memória em GB.</dd>
+</dlentry><dlentry>
+<dt>EstatÃsticas do sistema</dt>
+<dd>Esta seção exibe gráficos para mostrar estatÃsticas para CPU, memória,
+E/S de disco e E/S de rede para o host. Selecione <uicontrol>Coletando
+dados depois de sair desta página</uicontrol> para continuar a coletar dados
+quando a guia do host estiver fora de visualização.</dd>
+</dlentry><dlentry>
+<dt>Atualizações de software</dt>
+<dd>Esta seção exibe informações de todos os pacotes que
+possuem atualizações disponÃveis, incluindo nome do pacote, versão, arquitetura
+e repositório. à possÃvel atualizar todos os pacotes listados selecionando <uicontrol>Atualizar
+todos</uicontrol>. Não é possÃvel selecionar pacotes individuais para atualizações.</dd>
+</dlentry><dlentry>
+<dt>Repositórios</dt>
+<dd>Esta seção exibe repositórios que estão associados ao
+sistema host. à possÃvel incluir, ativar, editar ou remover repositórios. Incluir
+um repositório o associa com o sistema host enquanto ativar um repositório
+permite que o host o acesse. Se o seu sistema for Red Hat Enterprise
+Linux ou Fedora, será possÃvel incluir repositórios <filepath>yum</filepath>.
+Se o seu sistema for Ubuntu ou Debian, inclua repositórios <filepath>deb</filepath>.<p>Se
+você estiver trabalhando com repositórios yum, será possÃvel incluir uma verificação de GPG para
+verificar se um pacote desse repositório não foi corrompido.
+Selecione um repositório e, em seguida, <uicontrol>Editar</uicontrol>. Selecione <uicontrol>Sim</uicontrol> para
+ativar a Verificação de GPG e, em seguida, insira uma URL no arquivo-chave de GPG para o
+repositório.</p></dd>
+</dlentry><dlentry>
+<dt>Relatórios de depuração</dt>
+<dd>Esta seção exibe relatórios de depuração, incluindo nome e caminho do arquivo.
+à possÃvel selecionar a partir das opções para gerar um novo relatório ou renomear, remover
+ou fazer o download de um relatório existente.<p>O relatório de depuração é gerado usando
+o comando <cmdname>sosreport</cmdname>. Ele está disponÃvel para distribuições
+Red Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora
+e Ubuntu. O comando gera um arquivo .tar que contém
+informações de configuração e de diagnóstico, como versão do kernel
+em execução, módulos carregados e arquivos de configuração de sistema e de serviço.
+O comando também executa programas externos para coletar informações adicionais
+e armazena essa saÃda no archive resultante.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita
new file mode 100644
index 0000000..1585298
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="pt-br">
+<title>Rede</title>
+<shortdesc>A página <wintitle>Rede</wintitle> exibe informações
+sobre a conexão de rede.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nome da rede</dt>
+<dd>Nome da rede ou <uicontrol>padrão</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado da rede, ativo (verde) ou inativo (vermelho). </dd>
+</dlentry><dlentry>
+<dt>Tipo de rede</dt>
+<dd>Tipo de rede, por exemplo, <uicontrol>NAT</uicontrol> (conversão
+de endereço de rede).</dd>
+</dlentry><dlentry>
+<dt>Interface</dt>
+<dd>Interface de rede, por exemplo, <uicontrol>virbr0</uicontrol> (padrão).</dd>
+</dlentry><dlentry>
+<dt>Espaço de endereço</dt>
+<dd>Endereço IP.</dd>
+</dlentry></dl></p>
+<p>As ações a seguir podem ser selecionadas:<ul>
+<li rev="rev1">Selecione <uicontrol>Iniciar</uicontrol> para iniciar a conexão
+de rede.</li>
+<li>Selecione <uicontrol>Parar</uicontrol> para terminar a conexão de rede.</li>
+<li>Selecione <uicontrol>Excluir</uicontrol> para excluir as informações
+de conexão.</li>
+</ul>Para criar uma rede, clique no Ãcone <uicontrol>mais (+)</uicontrol> na
+parte superior direita da exibição.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="en-us">
+<title>Criar uma rede</title>
+<shortdesc>Crie uma rede.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Digite o nome da rede.</li>
+<li>Clique para selecionar o tipo de rede. <dl rev="rev1"><dlentry>
+<dt><uicontrol>Isolado</uicontrol></dt>
+<dd>Modo isolado. Os Máquinas Virtuais não podem enviar ou receber comunicação para
+ou de sistemas externos.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Modo de Conversão de Endereço de Rede. A comunicação de Máquinas Virtuais com
+sistemas externos usa o endereço IP do host. Os sistemas externos não podem
+iniciar a comunicação com os Máquinas Virtuais.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>bridged</uicontrol></dt>
+<dd>Modo bridged. Os Máquinas Virtuais podem se comunicar com os sistemas externos e
+ser contatados por sistemas externos como se fossem sistemas fÃsicos
+na rede. Para o modo bridged, devem-se especificar informações adicionais
+de destino e de VLAN.</dd>
+</dlentry></dl></li>
+<li>Clique em <uicontrol>Criar</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
new file mode 100644
index 0000000..03c8cab
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="pt-br">
+<title>Armazenamento</title>
+<shortdesc>A página <wintitle>Armazenamento</wintitle> lista os conjuntos de armazenamentos disponÃveis, inclusive o conjunto de armazenamentos 'padrão' e 'ISO' integrado.
+Se desejar usar seu próprio ISO, inclua-o em seu caminho do conjunto de armazenamentos 'ISO'.</shortdesc>
+<csbody>
+<p>Para cada storage pool, as informações a seguir são exibidas:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Nome do storage pool e porcentagem usada.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado do storage pool, ativo (verde) ou inativo (vermelho). </dd>
+</dlentry><dlentry>
+<dt>Local</dt>
+<dd>Caminho do arquivo para o local do storage pool.</dd>
+</dlentry><dlentry>
+<dt>Tipo</dt>
+<dd>Tipo de storage pool, por exemplo, <uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacidade</dt>
+<dd>Quantia de espaço no storage pool.</dd>
+</dlentry><dlentry>
+<dt>Alocado</dt>
+<dd>Quantia de espaço já alocado no storage pool.</dd>
+</dlentry></dl></p>
+<p>As ações a seguir podem ser selecionadas para cada storage pool:<ul>
+<li>Selecione <uicontrol>Ativar</uicontrol> para ativar o storage pool
+para que ele possa ser usado.</li>
+<li>Selecione <uicontrol>Desativar</uicontrol> para desativar um storage pool
+ativo.</li>
+<li>Selecione <uicontrol>Indefinir</uicontrol> para remover um storage pool
+inativo.</li>
+</ul></p>
+<p>Para exibir detalhes do volume de armazenamento para um storage pool, clique na
+seta no lado direito da linha do storage pool. Os detalhes incluem
+os seguintes:<dl><dlentry>
+<dt>Tipo</dt>
+<dd>O tipo de volume, por exemplo, <uicontrol>arquivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Formato</dt>
+<dd>O formato, que varia dependendo do tipo.</dd>
+</dlentry><dlentry>
+<dt>Capacidade</dt>
+<dd>Tamanho do volume de armazenamento.</dd>
+</dlentry><dlentry>
+<dt>Alocação</dt>
+<dd>Quantia de espaço já alocado no storage pool.</dd>
+</dlentry></dl>Para definir um storage pool, clique no Ãcone <uicontrol>mais
+(+)</uicontrol> na parte superior direita da exibição.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="en-us">
+<title>Definir um storage pool</title>
+<shortdesc> Defina um storage pool.</shortdesc>
+<csbody>
+<p> <ol>
+<li>No campo <uicontrol>Nome do storage pool</uicontrol>, digite o
+nome a ser usado para identificar o storage pool.</li>
+<li>Na lista <uicontrol>Tipo de storage pool</uicontrol>, selecione o
+tipo: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Especifica um conjunto de diretórios. Ao selecionar <uicontrol>DIR</uicontrol>,
+digite o <uicontrol>Caminho do armazenamento</uicontrol> (caminho do arquivo para o
+storage pool).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Especifica um conjunto de sistema de arquivos de rede. Ao selecionar <uicontrol>NFS</uicontrol>,
+digite o endereço <uicontrol>IP do servidor NFS</uicontrol> e o <uicontrol>Caminho
+do NFS</uicontrol> (caminho do diretório exportado).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Especifica um conjunto com base em um destino alocado em um servidor iSCSI.
+Ao selecionar <uicontrol>iSCSI</uicontrol>, digite o endereço IP do <uicontrol>Servidor
+iSCSI</uicontrol> e o <uicontrol>Destino</uicontrol> no
+servidor iSCSI. Opcionalmente, é possÃvel selecionar para incluir a autenticação iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Lógico</uicontrol></dt>
+<dd>Especifica um storage pool do volume lógico. Selecione o local para
+o dispositivo em <uicontrol>Caminho do dispositivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
+<dd>Especifica um conjunto com base em um Fibre Channel SCSI. Selecione qual
+adaptador SCSI deve ser usado.</dd>
+</dlentry></dl></li>
+<li>Clique em <uicontrol>Criar</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
new file mode 100644
index 0000000..f3c6515
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="pt-br">
+<title>Modelos</title>
+<shortdesc>A página <wintitle>Modelos</wintitle> mostra os modelos de
+máquina virtual definidos que podem ser usados para criar Máquinas Virtuais do KVM.</shortdesc>
+<csbody>
+<p>Para cada modelo, as informações a seguir são exibidas:<dl>
+<dlentry>
+<dt>S.O.</dt>
+<dd>Nome do sistema operacional ou distribuição.</dd>
+</dlentry><dlentry>
+<dt>Versão</dt>
+<dd>Versão do sistema operacional ou distribuição.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Número de processadores que estão definidos para o modelo.</dd>
+</dlentry><dlentry>
+<dt>Memória</dt>
+<dd>Quantia de memória de acesso aleatório a ser alocada, em MB.</dd>
+</dlentry></dl></p>
+<p>As ações a seguir podem ser selecionadas para cada modelo:<ul>
+<li>Selecione <uicontrol>Editar</uicontrol> para editar o modelo.</li>
+<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o modelo.</li>
+</ul>Para incluir um modelo, clique no Ãcone <uicontrol>mais (+)</uicontrol> na
+parte superior direita da exibição.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="en-us">
+<title>Editar modelo</title>
+<shortdesc>Edite um modelo existente.</shortdesc>
+<csbody>
+<p>Para cada modelo, as informações a seguir são exibidas: <dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Nome do modelo.</dd>
+</dlentry><dlentry>
+<dt>Fornecedor</dt>
+<dd>O nome da empresa que criou o sistema operacional ou a distribuição
+que o modelo está configurado para usar.</dd>
+</dlentry><dlentry>
+<dt>Versão</dt>
+<dd>A versão do sistema operacional ou distribuição que o modelo
+está configurado para usar.</dd>
+</dlentry><dlentry>
+<dt>Número de CPU</dt>
+<dd>Número de processadores que estão definidos para o modelo.</dd>
+</dlentry><dlentry>
+<dt>Memória</dt>
+<dd>Quantia de memória em MB a ser alocada para a máquina virtual.</dd>
+</dlentry><dlentry>
+<dt>Disco</dt>
+<dd>O tamanho do disco em GB.</dd>
+</dlentry><dlentry>
+<dt>CD-ROM</dt>
+<dd>O caminho do arquivo para o local do arquivo ISO usado para instalar o
+convidado do KVM.</dd>
+</dlentry><dlentry>
+<dt>storage pool</dt>
+<dd>storage pool especÃfico ou storage pool padrão.</dd>
+</dlentry><dlentry>
+<dt>Rede</dt>
+<dd>As interfaces de rede padrão disponÃveis para o convidado do KVM. à possÃvel
+selecionar diversas redes.</dd>
+</dlentry></dl> Os campos que não estão desativados podem ser editados. Depois
+de editar um campo, clique em <uicontrol>Salvar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Incluir modelo</title>
+<shortdesc>Inclua um modelo a partir da mÃdia de origem.
+à possÃvel incluir sua própria imagem ISO em seu conjunto de armazenamentos 'ISO' para a descoberta a seguir.</shortdesc>
+<csbody>
+<p>Selecione o local da mÃdia de origem a partir das opções a seguir:<dl>
+<dlentry>
+<dt>Imagem ISO local</dt>
+<dd>Selecione para varrer conjuntos de armazenamentos para imagens ISO de instalação disponÃveis
+no sistema.</dd>
+</dlentry><dlentry>
+<dt>Imagem ISO remota</dt>
+<dd>Selecione para especificar um local remoto para uma imagem ISO de instalação.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Incluir modelo - imagem ISO local</title>
+<shortdesc>Inclua um modelo a partir de uma imagem ISO local.</shortdesc>
+<csbody>
+<p>As imagens ISO disponÃveis no sistema são exibidas.<dl><dlentry>
+<dt>S.O.</dt>
+<dd>Nome do sistema operacional ou distribuição.</dd>
+</dlentry><dlentry>
+<dt>Versão</dt>
+<dd>Versão do sistema operacional ou distribuição.</dd>
+</dlentry><dlentry>
+<dt>Tamanho</dt>
+<dd>Tamanho da imagem ISO.</dd>
+</dlentry></dl></p>
+<p>Para criar um modelo a partir de uma imagem ISO, escolha a partir das opções
+a seguir:<ul>
+<li>Selecione uma imagem ISO para criar um modelo a partir dela, em seguida, clique em <uicontrol>Criar
+modelos a partir do ISO selecionado</uicontrol>.</li>
+<li>Selecione <uicontrol>Todos</uicontrol> para criar um modelo a partir de cada
+imagem ISO listada, em seguida, clique em <uicontrol>Criar modelos a partir do
+ISO selecionado</uicontrol>.</li>
+<li>Se a imagem ISO que você deseja usar não aparecer nos resultados de
+varredura, será possÃvel selecionar a partir das opções a seguir:<ul>
+<li>Selecione <uicontrol>Eu desejo usar um arquivo ISO especÃfico</uicontrol> para
+especificar um caminho para a imagem ISO.</li>
+<li>Clique em <uicontrol>Procurar mais ISOs</uicontrol> para procurar mais
+imagens ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
new file mode 100644
index 0000000..85ca27a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ru_RU_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ru_RU
+
+dist_ru_RU_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
new file mode 100644
index 0000000..701dd7e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="ru-ru">
+<title>ÐоÑÑевÑе ÑиÑÑемÑ</title>
+<shortdesc>Ðа ÑÑÑаниÑе <wintitle>ÐоÑÑевÑе ÑиÑÑемÑ</wintitle> показÑваеÑÑÑ ÑпиÑок ÑозданнÑÑ
виÑÑÑалÑнÑÑ
маÑин KVM.</shortdesc>
+<csbody>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ:<dl><dlentry>
+<dt>ÐмÑ</dt>
+<dd>ÐÐ¼Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ.</dd>
+</dlentry><dlentry>
+<dt>ÐÑоÑеÑÑоÑ</dt>
+<dd>ÐÑоÑÐµÐ½Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿ÑоÑеÑÑоÑа в виÑÑÑалÑной маÑине.</dd>
+</dlentry><dlentry>
+<dt>СеÑевой ввод-вÑвод</dt>
+<dd>СкоÑоÑÑÑ ÑеÑевого ввода-вÑвода в ÐÐ/Ñ.</dd>
+</dlentry><dlentry>
+<dt>ÐиÑковÑй ввод-вÑвод</dt>
+<dd>СкоÑоÑÑÑ Ð´Ð¸Ñкового ввода-вÑвода в ÐÐ/Ñ.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>СоÑÑоÑние конÑоли гоÑÑевой опеÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ знаÑок, пÑедÑÑавлÑÑÑий ваÑÐ¸Ð°Ð½Ñ ÐС <tm tmtype="tm" trademark="Linux">Linux</tm>, еÑли гоÑÑÐµÐ²Ð°Ñ ÑиÑÑема не акÑивна.</dd>
+</dlentry></dl></p>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваÑÑÑÑ ÑледÑÑÑие знаÑки дейÑÑвий:<dl>
+<dlentry>
+<dt>СбÑоÑ</dt>
+<dd>СбÑÐ¾Ñ Ð³Ð¾ÑÑевой ÑиÑÑемÑ. </dd>
+</dlentry><dlentry>
+<dt>ÐиÑание (запÑÑк/оÑÑановка)</dt>
+<dd>ÐклÑÑение/вÑклÑÑение пиÑÐ°Ð½Ð¸Ñ Ð³Ð¾ÑÑевой ÑиÑÑемÑ. ÐÑли знаÑок кÑаÑнÑй, пиÑание вÑклÑÑено. ÐÑли знаÑок зеленÑй, пиÑание вклÑÑено.</dd>
+</dlentry></dl> </p>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ ÑледÑÑÑие дейÑÑвиÑ:<ul>
+<li><uicontrol>ÐодклÑÑиÑÑÑÑ</uicontrol> - подклÑÑиÑÑÑÑ Ðº Ñдаленной конÑоли гоÑÑевой опеÑаÑионной ÑиÑÑемÑ.</li>
+<li><uicontrol>УпÑавление ноÑиÑелÑми</uicontrol> - изменение пÑÑи к ÑÑÑановоÑÐ½Ð¾Ð¼Ñ Ð½Ð¾ÑиÑелÑ.</li>
+<li><uicontrol>СбÑоÑ</uicontrol> - ÑбÑÐ¾Ñ Ð³Ð¾ÑÑевой ÑиÑÑемÑ.</li>
+<li><uicontrol>ÐзмениÑÑ</uicontrol> - наÑÑÑойка ÑвойÑÑв гоÑÑевой ÑиÑÑемÑ. СвойÑÑва гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð¶Ð½Ð¾ изменÑÑÑ, ÑолÑко когда ÑиÑÑема оÑÑановлена.</li>
+<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ð³Ð¾ÑÑевÑÑ ÑиÑÑемÑ.</li>
+</ul>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð³Ð¾ÑÑевой ÑиÑÑÐµÐ¼Ñ (виÑÑÑалÑной маÑинÑ) ÑелкниÑе на знаÑке <uicontrol>плÑÑ
+(+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="ru-ru">
+<title>Создание виÑÑÑалÑной маÑинÑ</title>
+<shortdesc>Создание виÑÑÑалÑной маÑÐ¸Ð½Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñаблона.</shortdesc>
+<csbody>
+<p> <ol>
+<li>ÐведиÑе Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии виÑÑÑалÑной маÑинÑ.</li>
+<li rev="rev1">ÐÑбеÑиÑе Ñаблон. <ul>
+<li>ÐÑли еÑÑÑ ÑаблонÑ, вÑбеÑиÑе Ñаблон в ÑпиÑке.</li>
+<li>ÐÑли Ñаблонов неÑ, ÑелкниÑе на <uicontrol>СоздаÑÑ Ñаблон</uicontrol>, ÑÑÐ¾Ð±Ñ ÑоздаÑÑ Ñаблон.</li>
+</ul></li>
+<li>ЩелкниÑе на <uicontrol>СоздаÑÑ</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="ru-ru">
+<title>Ðзменение гоÑÑевой ÑиÑÑемÑ</title>
+<shortdesc>Ðзменение ÑвойÑÑв ÑÑÑеÑÑвÑÑÑей виÑÑÑалÑной маÑинÑ. ÐекоÑоÑÑе ÑвойÑÑва можно изменÑÑÑ ÑолÑко пока оÑÑановлена гоÑÑÐµÐ²Ð°Ñ ÑÑеда. ÐÑÑгие вÑÑÑпаÑÑ Ð² ÑÐ¸Ð»Ñ Ð¿Ð¾Ñле ÑледÑÑÑей пеÑезагÑÑзки.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ гоÑÑевой ÑиÑÑÐµÐ¼Ñ Ð¿Ð¾ÐºÐ°Ð·ÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð½Ð° вкладке <wintitle>ÐбÑие</wintitle>:<dl>
+<dlentry>
+<dt>ÐмÑ</dt>
+<dd>ÐÐ¼Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ. (можно ÑедакÑиÑоваÑÑ Ð¿Ð¾ÐºÐ° оÑÑановлена гоÑÑÐµÐ²Ð°Ñ ÑÑеда)</dd>
+</dlentry><dlentry>
+<dt>ÐÑоÑеÑÑоÑÑ</dt>
+<dd>ЧиÑло пÑоÑеÑÑоÑов. (еÑли гоÑÑÐµÐ²Ð°Ñ ÑÑеда ÑабоÑаеÑ, новое ÑиÑло вÑÑÑÐ¿Ð¸Ñ Ð² ÑÐ¸Ð»Ñ Ð¿Ð¾Ñле пеÑезагÑÑзки)</dd>
+</dlentry><dlentry>
+<dt>ÐамÑÑÑ</dt>
+<dd>ÐбÑем памÑÑи в ÐÐ. (еÑли гоÑÑÐµÐ²Ð°Ñ ÑÑеда ÑабоÑаеÑ, новое ÑиÑло вÑÑÑÐ¿Ð¸Ñ Ð² ÑÐ¸Ð»Ñ Ð¿Ð¾Ñле пеÑезагÑÑзки)</dd>
+</dlentry><dlentry>
+<dt>ÐнаÑок</dt>
+<dd>ÐÑаÑиÑеÑкое изобÑажение, пÑедÑÑавлÑÑÑее ваÑÐ¸Ð°Ð½Ñ ÐС Linux. Ðно показÑваеÑÑÑ Ð²Ð¼ÐµÑÑо ÑекÑÑего ÑоÑÑоÑниÑ
+(Livetile), когда гоÑÑÐµÐ²Ð°Ñ ÑиÑÑема не акÑивна.</dd>
+</dlentry></dl></p>
+<p>Ðа вкладке <wintitle>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</wintitle> показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ.</p>
+<dl><dlentry>
+<dt>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</dt>
+<dd>ÐоказÑÐ²Ð°ÐµÑ ÑаÑположение Ñайла ISO Ð´Ð»Ñ ÑÑÑановки.</dd>
+</dlentry></dl>
+<p> ÐкÑивнÑе Ð¿Ð¾Ð»Ñ Ð¼Ð¾Ð¶Ð½Ð¾ изменÑÑÑ. ÐоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ñ ÑелкниÑе на <uicontrol>СоÑ
ÑаниÑÑ</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="ru-ru">
+<title>Ðобавление, замена и оÑклÑÑение ÑÑÑÑойÑÑв Ñ
ÑанениÑ</title>
+<shortdesc rev="rev1">РвиÑÑÑалÑной маÑине можно добавлÑÑÑ, заменÑÑÑ Ð¸ оÑклÑÑаÑÑ ÑÑÑÑойÑÑва Ñ
ÑанениÑ. ÐдинÑÑвенное поддеÑживаемое ÑÑÑÑойÑÑво - CDROM. ÐÐ»Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑв Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð²ÑполниÑе ÑледÑÑÑие дейÑÑвиÑ:</shortdesc>
+<csbody>
+<ol>
+<li>Рокне <wintitle>ÐзмениÑÑ Ð³Ð¾ÑÑевÑÑ ÑиÑÑемÑ</wintitle> вÑбеÑиÑе <wintitle>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</wintitle>.</li>
+<li>ÐÐ»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ ÑÑÑÑойÑÑва Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑелкниÑе на пеÑвом знаÑке Ñ <uicontrol>оÑанжевой коÑой ÑеÑÑой (/)</uicontrol>. ÐведиÑе пÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO и ÑелкниÑе на <uicontrol>ÐамениÑÑ</uicontrol>.</li>
+<li>ÐÐ»Ñ Ð¾ÑклÑÑÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑелкниÑе на вÑоÑом знаÑке Ñ <uicontrol>кÑаÑной гоÑизонÑалÑной ÑеÑÑой (-)</uicontrol>. ÐодÑвеÑдиÑе Ñдаление и нажмиÑе ÐºÐ½Ð¾Ð¿ÐºÑ <uicontrol>OK</uicontrol>.</li>
+<li>ÐÐ»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ ÑÑÑÑойÑÑва Ñ
ÑÐ°Ð½ÐµÐ½Ð¸Ñ ÑелкниÑе на ÑÑеÑÑем знаÑке Ñ <uicontrol>зеленÑм плÑÑом
+(+)</uicontrol>. ÐведиÑе Ð¸Ð¼Ñ ÑÑÑÑойÑÑва и пÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO и ÑелкниÑе на <uicontrol>ÐодклÑÑиÑÑ</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="ru-ru">
+<title>Ðамена CDROM виÑÑÑалÑной маÑинÑ</title>
+<shortdesc rev="rev1">Ðо оконÑании ÑÑÑановки можно замениÑÑ ÑодеÑжимое CDROM Ð´Ð»Ñ Ð²Ð¸ÑÑÑалÑной маÑинÑ.</shortdesc>
+<csbody>
+<ol>
+<li>ÐапÑÑÑиÑе виÑÑÑалÑнÑÑ Ð¼Ð°ÑинÑ.</li>
+<li>Ð Ð¼ÐµÐ½Ñ ÐейÑÑÐ²Ð¸Ñ Ð²ÑбеÑиÑе <uicontrol>УпÑавление ноÑиÑелÑми</uicontrol>.</li>
+<li>ÐÐ»Ñ Ð·Ð°Ð¼ÐµÐ½Ñ Ð½Ð¾ÑиÑелÑ, вÑÑавленного в CDROM, ÑелкниÑе на знаÑке Ñ <uicontrol>оÑанжевой коÑой ÑеÑÑой
+(/)</uicontrol> ÑÑдом Ñ Ð¿Ð¾Ð»ÐµÐ¼ hdc.</li>
+<li>Ðа ÑÑÑаниÑе <wintitle>Ðамена CDROM виÑÑÑалÑной маÑинÑ</wintitle> введиÑе пÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO. Ðва дÑÑгиÑ
Ð¿Ð¾Ð»Ñ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ ÑолÑко Ð´Ð»Ñ ÑÑениÑ.</li>
+<li>ÐÑбеÑиÑе опÑÐ¸Ñ <uicontrol>ÐамениÑÑ</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita
new file mode 100644
index 0000000..fb72c21
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="ru-ru">
+<title>ХоÑÑ</title>
+<shortdesc>СÑÑаниÑа <wintitle>ХоÑÑ</wintitle> показÑÐ²Ð°ÐµÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑиÑÑеме Ñ
оÑÑа и позволÑÐµÑ Ð¾ÑÑанавливаÑÑ Ñ
оÑÑ, пеÑезапÑÑкаÑÑ Ñ
оÑÑ Ð¸ подклÑÑаÑÑÑÑ Ðº немÑ.</shortdesc>
+<csbody>
+<p>Ðа Ñ
оÑÑе можно вÑполнÑÑÑ ÑледÑÑÑие дейÑÑвиÑ:<ul>
+<li><uicontrol>ÐавеÑÑиÑÑ ÑабоÑÑ</uicontrol> - оÑÑановиÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа.</li>
+<li><uicontrol>ÐеÑезапÑÑÑиÑÑ</uicontrol> - пеÑезапÑÑÑиÑÑ ÑиÑÑÐµÐ¼Ñ Ñ
оÑÑа.</li>
+<li><uicontrol>ÐодклÑÑиÑÑÑÑ</uicontrol> - оÑкÑÑÑÑ Ñоединение VNC Ñ ÑиÑÑемой Ñ
оÑÑа, еÑли оно еÑе не ÑÑÑановлено.</li>
+</ul></p>
+<p>ЩелкниÑе на ÑледÑÑÑиÑ
ÑазделаÑ
Ð´Ð»Ñ Ð¿ÑоÑмоÑÑа инÑоÑмаÑии о Ñ
оÑÑе:<dl>
+<dlentry>
+<dt>ÐÐ°Ð·Ð¾Ð²Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ</dt>
+<dd>Ð ÑÑом Ñазделе показÑваеÑÑÑ Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑемÑ, его веÑÑÐ¸Ñ Ð¸ кодовое имÑ, а Ñакже Ñип пÑоÑеÑÑоÑа и обÑем памÑÑи в ÐÐ.</dd>
+</dlentry><dlentry>
+<dt>СиÑÑÐµÐ¼Ð½Ð°Ñ ÑÑаÑиÑÑика</dt>
+<dd>Ð ÑÑом Ñазделе показÑваÑÑÑÑ Ð³ÑаÑики, оÑÑажаÑÑие ÑÑаÑиÑÑиÑеÑкÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ пÑоÑеÑÑоÑе, памÑÑи, диÑковом вводе-вÑводе и ÑеÑевом вводе-вÑводе Ð´Ð»Ñ Ñ
оÑÑа. ÐÑбеÑиÑе <uicontrol>Ð¡Ð±Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ
поÑле закÑÑÑÐ¸Ñ ÑÑой ÑÑÑаниÑÑ</uicontrol>, ÑÑÐ¾Ð±Ñ ÑÐ±Ð¾Ñ Ð´Ð°Ð½Ð½ÑÑ
пÑодолжалÑÑ Ð¿Ð¾Ñле закÑÑÑÐ¸Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ¸ ХоÑÑ.</dd>
+</dlentry><dlentry>
+<dt>ÐÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿ÑогÑаммного обеÑпеÑениÑ</dt>
+<dd>Ð ÑÑом Ñазделе показÑваеÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾Ð±Ð¾ вÑеÑ
пакеÑаÑ
, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ
доÑÑÑÐ¿Ð½Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ, вклÑÑÐ°Ñ Ð¸Ð¼Ñ Ð¿Ð°ÐºÐµÑа, веÑÑиÑ, аÑÑ
иÑекÑÑÑÑ Ð¸ Ñ
ÑанилиÑе. Ðожно обновиÑÑ Ð²Ñе пакеÑÑ Ð² ÑпиÑке ÑелÑком на <uicontrol>ÐбновиÑÑ Ð²Ñе</uicontrol>. ÐÑделÑнÑе пакеÑÑ Ð´Ð»Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð²ÑбÑаÑÑ Ð½ÐµÐ»ÑзÑ.</dd>
+</dlentry><dlentry>
+<dt>Ð¥ÑанилиÑа</dt>
+<dd>Ð ÑÑом Ñазделе показÑваÑÑÑÑ Ñ
ÑанилиÑа, ÑвÑзаннÑе Ñ ÑиÑÑемой Ñ
оÑÑа. Ð¥ÑанилиÑа можно добавлÑÑÑ, акÑивиÑоваÑÑ, изменÑÑÑ Ð¸ ÑдалÑÑÑ. ÐÑи добавлении Ñ
ÑанилиÑе ÑвÑзÑваеÑÑÑ Ñ ÑиÑÑемой Ñ
оÑÑа, пÑи акÑиваÑии Ñ
ÑанилиÑе ÑÑановиÑÑÑ Ð´Ð¾ÑÑÑпнÑм Ð´Ð»Ñ Ñ
оÑÑа. ÐÑли ÑиÑÑема - Red Hat Enterprise Linux или Fedora, можно добавиÑÑ Ñ
ÑанилиÑа <filepath>yum</filepath>.
+ÐÑли ÑиÑÑема - Ubuntu или Debian, добавÑÑе Ñ
ÑанилиÑа <filepath>deb</filepath>.<p>ÐÑи ÑабоÑе Ñ Ñ
ÑанилиÑами yum можно добавиÑÑ Ð¿ÑовеÑÐºÑ GPG Ð´Ð»Ñ Ð¿ÑовеÑки ÑелоÑÑноÑÑи пакеÑов из данного Ñ
ÑанилиÑа.
+ÐÑбеÑиÑе Ñ
ÑанилиÑе и ÑелкниÑе на <uicontrol>ÐзмениÑÑ</uicontrol>. ÐÑбеÑиÑе <uicontrol>Ðа</uicontrol>, ÑÑÐ¾Ð±Ñ Ð²ÐºÐ»ÑÑиÑÑ Ð¿ÑовеÑÐºÑ GPG, и введиÑе URL Ñайла клÑÑей GPG Ð´Ð»Ñ Ñ
ÑанилиÑа.</p></dd>
+</dlentry><dlentry>
+<dt>ÐÑладоÑнÑе оÑÑеÑÑ</dt>
+<dd>Ð ÑÑом Ñазделе показÑваÑÑÑÑ Ð¾ÑладоÑнÑе оÑÑеÑÑ, вклÑÑÐ°Ñ Ð¸Ð¼Ñ Ð¸ пÑÑÑ.
+ÐоÑÑÑÐ¿Ð½Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ Ð´Ð»Ñ ÑозданиÑ, пеÑеименованиÑ, ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð¸ загÑÑзки оÑÑеÑов.<p>ÐÑладоÑнÑй оÑÑÐµÑ ÑоздаеÑÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ <cmdname>sosreport</cmdname>. Ðн доÑÑÑпен Ð´Ð»Ñ Red
+Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>, Fedora и Ubuntu. Ðоманда ÑÐ¾Ð·Ð´Ð°ÐµÑ Ñайл .tar Ñ ÐºÐ¾Ð½ÑигÑÑаÑионной и диагноÑÑиÑеÑкой инÑоÑмаÑией, Ñакой как веÑÑÐ¸Ñ ÑдÑа, загÑÑженнÑе модÑли и ÑÐ°Ð¹Ð»Ñ ÐºÐ¾Ð½ÑигÑÑаÑии ÑиÑÑÐµÐ¼Ñ Ð¸ ÑлÑжб.
+Ðоманда Ñакже вÑполнÑÐµÑ Ð²Ð½ÐµÑние пÑогÑÐ°Ð¼Ð¼Ñ Ð´Ð»Ñ ÑбоÑа дополниÑелÑной инÑоÑмаÑии и ÑоÑ
ÑанÑÐµÑ Ð¸Ñ
вÑвод в ÑезÑлÑÑиÑÑÑÑем аÑÑ
иве.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita
new file mode 100644
index 0000000..9cdcdd1
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="ru-ru">
+<title>СеÑÑ</title>
+<shortdesc>Ðа ÑÑÑаниÑе <wintitle>СеÑÑ</wintitle> показÑваеÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ ÑеÑевом Ñоединении.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>ÐÐ¼Ñ ÑеÑи</dt>
+<dd>ÐÐ¼Ñ ÑеÑи или <uicontrol>по ÑмолÑаниÑ</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>СоÑÑоÑние</dt>
+<dd>СоÑÑоÑние ÑеÑи - акÑÐ¸Ð²Ð½Ð°Ñ (зеленÑй) или неакÑÐ¸Ð²Ð½Ð°Ñ (кÑаÑнÑй). </dd>
+</dlentry><dlentry>
+<dt>Тип ÑеÑи</dt>
+<dd>Тип ÑеÑи, напÑÐ¸Ð¼ÐµÑ <uicontrol>NAT</uicontrol> (пÑеобÑазование ÑеÑевÑÑ
адÑеÑов).</dd>
+</dlentry><dlentry>
+<dt>ÐнÑеÑÑейÑ</dt>
+<dd>СеÑевой инÑеÑÑейÑ, напÑÐ¸Ð¼ÐµÑ <uicontrol>virbr0</uicontrol> (по ÑмолÑаниÑ).</dd>
+</dlentry><dlentry>
+<dt>ÐдÑеÑное пÑоÑÑÑанÑÑво</dt>
+<dd>IP-адÑеÑ.</dd>
+</dlentry></dl></p>
+<p>ÐоÑÑÑÐ¿Ð½Ñ ÑледÑÑÑие дейÑÑвиÑ:<ul>
+<li rev="rev1"><uicontrol>ÐапÑÑÑиÑÑ</uicontrol> - оÑкÑÑÑÑ ÑеÑевое Ñоединение.</li>
+<li><uicontrol>ÐÑÑановиÑÑ</uicontrol> - закÑÑÑÑ ÑеÑевое Ñоединение.</li>
+<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñоединении.</li>
+</ul>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ ÑеÑи ÑелкниÑе на знаÑке <uicontrol>плÑÑа (+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="ru-ru">
+<title>Создание ÑеÑи</title>
+<shortdesc>Создание ÑеÑи.</shortdesc>
+<csbody>
+<p> <ol>
+<li>ÐведиÑе Ð¸Ð¼Ñ ÑеÑи.</li>
+<li>ÐÑбеÑиÑе Ñип ÑеÑи. <dl rev="rev1"><dlentry>
+<dt><uicontrol>ÐзолиÑованнÑй</uicontrol></dt>
+<dd>ÐзолиÑованнÑй Ñежим. ÐоÑÑевÑе ÑиÑÑÐµÐ¼Ñ Ð½Ðµ могÑÑ Ð¾Ð±Ð¼ÐµÐ½Ð¸Ð²Ð°ÑÑÑÑ Ð´Ð°Ð½Ð½Ñми Ñ Ð²Ð½ÐµÑними ÑиÑÑемами.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Режим пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑеÑевÑÑ
адÑеÑов. Ðбмен даннÑми Ð¼ÐµÐ¶Ð´Ñ Ð³Ð¾ÑÑевÑми и внеÑними ÑиÑÑемами оÑÑÑеÑÑвлÑеÑÑÑ ÑеÑез IP-адÑÐµÑ Ñ
оÑÑа. ÐнеÑние ÑиÑÑÐµÐ¼Ñ Ð½Ðµ могÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑаÑÑÑÑ Ðº гоÑÑевÑм.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>ЧеÑез моÑÑ</uicontrol></dt>
+<dd>Режим ÑабоÑÑ ÑеÑез моÑÑ. ÐоÑÑевÑе ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð³ÑÑ Ð¾Ð±Ð¼ÐµÐ½Ð¸Ð²Ð°ÑÑÑÑ Ð´Ð°Ð½Ð½Ñми Ñ Ð²Ð½ÐµÑними ÑиÑÑемами, и внеÑние ÑиÑÑÐµÐ¼Ñ Ð¼Ð¾Ð³ÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑаÑÑÑÑ Ðº гоÑÑевÑм, как еÑли Ð±Ñ Ñе бÑли ÑизиÑеÑкими ÑиÑÑемами в ÑеÑи. Ð Ñежиме ÑабоÑÑ ÑеÑез моÑÑ Ð½ÐµÐ¾Ð±Ñ
одимо ÑказаÑÑ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ Ñелевом ÑаÑположении и VLAN.</dd>
+</dlentry></dl></li>
+<li>ЩелкниÑе на <uicontrol>СоздаÑÑ</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
new file mode 100644
index 0000000..fa37edc
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="ru-ru">
+<title>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</title>
+<shortdesc>Ðа ÑÑÑаниÑе <wintitle>ÐиÑÐºÐ¾Ð²Ð°Ñ Ð¿Ð°Ð¼ÑÑÑ</wintitle> показÑваеÑÑÑ ÑпиÑок доÑÑÑпнÑÑ
пÑлов памÑÑи, вклÑÑÐ°Ñ Ð¿ÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи 'по ÑмолÑаниÑ' и 'ISO'.
+ÐÑли Ð²Ñ Ñ
оÑиÑе иÑполÑзоваÑÑ ÑобÑÑвеннÑй ISO, добавÑÑе его в пÑÑÑ Ð´Ð¸Ñковой памÑÑи 'ISO'.</shortdesc>
+<csbody>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑла памÑÑи показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ:<dl>
+<dlentry>
+<dt>ÐмÑ</dt>
+<dd>ÐÐ¼Ñ Ð¿Ñла памÑÑи и пÑоÑÐµÐ½Ñ Ð¸ÑполÑзованиÑ.</dd>
+</dlentry><dlentry>
+<dt>СоÑÑоÑние</dt>
+<dd>СоÑÑоÑние пÑла памÑÑи - акÑивнÑй (зеленÑй) или неакÑивнÑй (кÑаÑнÑй). </dd>
+</dlentry><dlentry>
+<dt>РаÑположение</dt>
+<dd>ÐÑÑÑ Ðº ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñла памÑÑи.</dd>
+</dlentry><dlentry>
+<dt>Тип</dt>
+<dd>Тип пÑла памÑÑи, напÑÐ¸Ð¼ÐµÑ <uicontrol>каÑалог</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>ÐмкоÑÑÑ</dt>
+<dd>ÐбÑем пÑла памÑÑи.</dd>
+</dlentry><dlentry>
+<dt>ÐÑделено</dt>
+<dd>ÐбÑем вÑделенной памÑÑи в пÑле.</dd>
+</dlentry></dl></p>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ пÑла памÑÑи можно вÑбиÑаÑÑ ÑледÑÑÑие дейÑÑвиÑ:<ul>
+<li><uicontrol>ÐкÑивиÑоваÑÑ</uicontrol> - акÑивиÑоваÑÑ Ð¿Ñл памÑÑи, ÑÑÐ¾Ð±Ñ ÐµÐ³Ð¾ можно бÑло иÑполÑзоваÑÑ.</li>
+<li><uicontrol>ÐеакÑивиÑоваÑÑ</uicontrol> - деакÑивиÑоваÑÑ Ð°ÐºÑивнÑй пÑл памÑÑи.</li>
+<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ð½ÐµÐ°ÐºÑивнÑй пÑл памÑÑи.</li>
+</ul></p>
+<p>ÐÐ»Ñ Ð¿ÑоÑмоÑÑа Ñведений о ÑомаÑ
пÑла памÑÑи ÑелкниÑе на ÑÑÑелке в пÑавой ÑаÑÑи ÑÑÑоки пÑла памÑÑи. Ð¡Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð²ÐºÐ»ÑÑаÑÑ:<dl><dlentry>
+<dt>Тип</dt>
+<dd>Тип Ñома, напÑÐ¸Ð¼ÐµÑ <uicontrol>Ñайл</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>ФоÑмаÑ</dt>
+<dd>ФоÑÐ¼Ð°Ñ (завиÑÐ¸Ñ Ð¾Ñ Ñипа).</dd>
+</dlentry><dlentry>
+<dt>ÐмкоÑÑÑ</dt>
+<dd>Ð Ð°Ð·Ð¼ÐµÑ Ñома.</dd>
+</dlentry><dlentry>
+<dt>ÐÑделение</dt>
+<dd>ÐбÑем вÑделенной памÑÑи в пÑле.</dd>
+</dlentry></dl>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð¿Ñла памÑÑи ÑелкниÑе на знаÑке <uicontrol>плÑÑа (+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="ru-ru">
+<title>Создание пÑла памÑÑи</title>
+<shortdesc> Создание пÑла памÑÑи.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Рполе <uicontrol>ÐÐ¼Ñ Ð¿Ñла памÑÑи</uicontrol> введиÑе Ð¸Ð¼Ñ Ð´Ð»Ñ Ð¸Ð´ÐµÐ½ÑиÑикаÑии пÑла памÑÑи.</li>
+<li>Ð ÑпиÑке <uicontrol>Тип пÑла памÑÑи</uicontrol> вÑбеÑиÑе Ñип: <dl><dlentry>
+<dt><uicontrol>ÐаÑалог</uicontrol></dt>
+<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл-каÑалог. ÐÑи вÑбоÑе Ñипа <uicontrol>ÐаÑалог</uicontrol> заполниÑе поле
+<uicontrol>ÐÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи</uicontrol> (пÑÑÑ Ðº пÑÐ»Ñ Ð¿Ð°Ð¼ÑÑи в Ñайловой ÑиÑÑеме).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл на оÑнове ÑеÑевой Ñайловой ÑиÑÑемÑ. ÐÑи вÑбоÑе <uicontrol>NFS</uicontrol> ÑкажиÑе адÑÐµÑ Ð²
+поле <uicontrol>IP-адÑÐµÑ ÑеÑвеÑа NFS</uicontrol> и пÑÑÑ Ðº ÑкÑпоÑÑиÑÐ¾Ð²Ð°Ð½Ð½Ð¾Ð¼Ñ ÐºÐ°ÑÐ°Ð»Ð¾Ð³Ñ Ð² поле <uicontrol>ÐÑÑÑ NFS</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл на оÑнове Ñелевого обÑекÑа, вÑделенного на ÑеÑвеÑе iSCSI.
+ÐÑи вÑбоÑе Ñипа <uicontrol>iSCSI</uicontrol> ÑкажиÑе IP-адÑÐµÑ Ð² поле <uicontrol>СеÑÐ²ÐµÑ iSCSI</uicontrol> и Ñелевой обÑÐµÐºÑ Ð½Ð° ÑеÑвеÑе iSCSI в поле <uicontrol>Целевой обÑекÑ</uicontrol>. Ðожно Ñакже добавиÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑÐ¸Ñ iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>ÐогиÑеÑкий</uicontrol></dt>
+<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл памÑÑи на оÑнове логиÑеÑкого Ñома. ÐÑбеÑиÑе ÑаÑположение ÑÑÑÑойÑÑва в поле <uicontrol>ÐÑÑÑ Ðº ÑÑÑÑойÑÑвÑ</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
+<dd>ÐÐ°Ð´Ð°ÐµÑ Ð¿Ñл на оÑнове SCSI Fibre Channel. ÐÑбеÑиÑе адапÑÐµÑ SCSI.</dd>
+</dlentry></dl></li>
+<li>ЩелкниÑе на <uicontrol>СоздаÑÑ</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
new file mode 100644
index 0000000..27ce4ae
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="ru-ru">
+<title>ШаблонÑ</title>
+<shortdesc>Ðа ÑÑÑаниÑе <wintitle>ШаблонÑ</wintitle> показÑваÑÑÑÑ ÑозданнÑе ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð²Ð¸ÑÑÑалÑнÑÑ
маÑин, коÑоÑÑе можно иÑполÑзоваÑÑ Ð´Ð»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ð³Ð¾ÑÑевÑÑ
ÑиÑÑем KVM.</shortdesc>
+<csbody>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñаблона показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ:<dl>
+<dlentry>
+<dt>ÐС</dt>
+<dd>ÐÐ¼Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
+</dlentry><dlentry>
+<dt>ÐеÑÑиÑ</dt>
+<dd>ÐеÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
+</dlentry><dlentry>
+<dt>ÐÑоÑеÑÑоÑÑ</dt>
+<dd>ÐолиÑеÑÑво пÑоÑеÑÑоÑов Ð´Ð»Ñ Ñаблона.</dd>
+</dlentry><dlentry>
+<dt>ÐамÑÑÑ</dt>
+<dd>ÐÑделÑемÑй обÑем опеÑаÑивной памÑÑи в ÐÐ.</dd>
+</dlentry></dl></p>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñаблона можно вÑбиÑаÑÑ ÑледÑÑÑие дейÑÑвиÑ:<ul>
+<li><uicontrol>ÐзмениÑÑ</uicontrol> - измениÑÑ Ñаблон.</li>
+<li><uicontrol>УдалиÑÑ</uicontrol> - ÑдалиÑÑ Ñаблон.</li>
+</ul>ÐÐ»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñаблона ÑелкниÑе на знаÑке <uicontrol>плÑÑа (+)</uicontrol> в пÑавом веÑÑ
нем ÑÐ³Ð»Ñ ÑÑÑаниÑÑ.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="ru-ru">
+<title>ÐзмениÑÑ Ñаблон</title>
+<shortdesc>ÐзмениÑÑ ÑÑÑеÑÑвÑÑÑий Ñаблон.</shortdesc>
+<csbody>
+<p>ÐÐ»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ Ñаблона показÑваеÑÑÑ ÑледÑÑÑÐ°Ñ Ð¸Ð½ÑоÑмаÑиÑ: <dl>
+<dlentry>
+<dt>ÐмÑ</dt>
+<dd>ÐÐ¼Ñ Ñаблона.</dd>
+</dlentry><dlentry>
+<dt>ÐендоÑ</dt>
+<dd>ÐÐ¼Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ð¸Ð¸, ÑоздавÑей опеÑаÑионнÑÑ ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑÐ¸Ð°Ð½Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑемÑ, Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾ÑоÑÑÑ
наÑÑÑаиваеÑÑÑ Ñаблон.</dd>
+</dlentry><dlentry>
+<dt>ÐеÑÑиÑ</dt>
+<dd>ÐеÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ, Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐºÐ¾ÑоÑÑÑ
наÑÑÑаиваеÑÑÑ Ñаблон.</dd>
+</dlentry><dlentry>
+<dt>ÐолиÑеÑÑво пÑоÑеÑÑоÑов</dt>
+<dd>ÐолиÑеÑÑво пÑоÑеÑÑоÑов Ð´Ð»Ñ Ñаблона.</dd>
+</dlentry><dlentry>
+<dt>ÐамÑÑÑ</dt>
+<dd>ÐбÑем памÑÑи в ÐÐ, вÑделÑемÑй виÑÑÑалÑной маÑине.</dd>
+</dlentry><dlentry>
+<dt>ÐиÑк</dt>
+<dd>Ð Ð°Ð·Ð¼ÐµÑ Ð´Ð¸Ñка в ÐÐ.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>ÐÑÑÑ Ðº ÑÐ°Ð¹Ð»Ñ ISO Ð´Ð»Ñ ÑÑÑановки гоÑÑевой ÑиÑÑÐµÐ¼Ñ KVM.</dd>
+</dlentry><dlentry>
+<dt>ÐÑл памÑÑи</dt>
+<dd>ÐпÑеделеннÑй пÑл памÑÑи или пÑл памÑÑи по ÑмолÑаниÑ.</dd>
+</dlentry><dlentry>
+<dt>СеÑÑ</dt>
+<dd>СеÑевÑе инÑеÑÑейÑÑ Ð¿Ð¾ ÑмолÑаниÑ, доÑÑÑпнÑе Ð´Ð»Ñ Ð³Ð¾ÑÑевой ÑиÑÑÐµÐ¼Ñ KVM. Ðожно вÑбÑаÑÑ Ð½ÐµÑколÑко ÑеÑей.</dd>
+</dlentry></dl> ÐкÑивнÑе Ð¿Ð¾Ð»Ñ Ð¼Ð¾Ð¶Ð½Ð¾ изменÑÑÑ. ÐоÑле Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»Ñ ÑелкниÑе на <uicontrol>СоÑ
ÑаниÑÑ</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Ðобавление Ñаблона</title>
+<shortdesc>Ðобавление Ñаблона Ñ Ð¸ÑÑ
одного ноÑиÑелÑ. ÐобавÑÑе ÑобÑÑвеннÑй обÑаз ISO в диÑковÑÑ Ð¿Ð°Ð¼ÑÑÑ ISO Ð´Ð»Ñ Ð´Ð°Ð»ÑнейÑего поиÑка.</shortdesc>
+<csbody>
+<p>ÐÑбеÑиÑе один из ÑледÑÑÑиÑ
ваÑианÑов ÑаÑÐ¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¸ÑÑ
одного ноÑиÑелÑ:<dl>
+<dlentry>
+<dt>ÐокалÑнÑй обÑаз ISO</dt>
+<dd>ÐÑбеÑиÑе ÑÑÐ¾Ñ Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка ÑÑÑановоÑнÑÑ
обÑазов ISO в локалÑнÑÑ
пÑлаÑ
памÑÑи ÑиÑÑемÑ.</dd>
+</dlentry><dlentry>
+<dt>УдаленнÑй обÑаз ISO</dt>
+<dd>ÐÑбеÑиÑе ÑÑÐ¾Ñ Ð²Ð°ÑианÑ, ÑÑÐ¾Ð±Ñ ÑказаÑÑ Ñдаленное ÑаÑположение ÑÑÑановоÑного обÑаза ISO.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Ðобавление Ñаблона (локалÑнÑй обÑаз ISO)</title>
+<shortdesc>Ðобавление Ñаблона из локалÑного обÑаза ISO.</shortdesc>
+<csbody>
+<p>ÐÑдÑÑ Ð¿Ð¾ÐºÐ°Ð·Ð°Ð½Ñ Ð¾Ð±ÑÐ°Ð·Ñ ISO, доÑÑÑпнÑе в ÑиÑÑеме.<dl><dlentry>
+<dt>ÐС</dt>
+<dd>ÐÐ¼Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
+</dlentry><dlentry>
+<dt>ÐеÑÑиÑ</dt>
+<dd>ÐеÑÑÐ¸Ñ Ð¾Ð¿ÐµÑаÑионной ÑиÑÑÐµÐ¼Ñ Ð¸Ð»Ð¸ ваÑианÑа опеÑаÑионной ÑиÑÑемÑ.</dd>
+</dlentry><dlentry>
+<dt>РазмеÑ</dt>
+<dd>Ð Ð°Ð·Ð¼ÐµÑ Ð¾Ð±Ñаза ISO.</dd>
+</dlentry></dl></p>
+<p>ÐÐ»Ñ ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñаблона из обÑаза ISO вÑбеÑиÑе один из ÑледÑÑÑиÑ
ваÑианÑов:<ul>
+<li>ÐÑбеÑиÑе обÑаз ISO, из коÑоÑого нÑжно ÑоздаÑÑ Ñаблон, заÑем ÑелкниÑе на <uicontrol>СоздаÑÑ ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð¸Ð· вÑбÑаннÑÑ
обÑазов ISO</uicontrol>.</li>
+<li>ÐÑбеÑиÑе <uicontrol>ÐÑе</uicontrol>, ÑÑÐ¾Ð±Ñ ÑоздаÑÑ Ñаблон из каждого обÑаза ISO в ÑпиÑке, заÑем ÑелкниÑе на <uicontrol>СоздаÑÑ ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð¸Ð· вÑбÑаннÑÑ
обÑазов ISO</uicontrol>.</li>
+<li>ÐÑли ÑÑебÑемÑй обÑаз ISO оÑÑÑÑÑÑвÑÐµÑ Ð² ÑезÑлÑÑаÑаÑ
поиÑка, вÑбеÑиÑе один из ÑледÑÑÑиÑ
ваÑианÑов:<ul>
+<li>ÐÑбеÑиÑе <uicontrol>ÐÑполÑзоваÑÑ ÐºÐ¾Ð½ÐºÑеÑнÑй Ñайл ISO</uicontrol>, ÑÑÐ¾Ð±Ñ ÑказаÑÑ Ð¿ÑÑÑ Ðº обÑÐ°Ð·Ñ ISO.</li>
+<li>ЩелкниÑе на <uicontrol>ÐоиÑк дополниÑелÑнÑÑ
обÑазов ISO</uicontrol> Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка дополниÑелÑнÑÑ
обÑазов ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
new file mode 100644
index 0000000..e785048
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+zh_CN_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_CN
+
+dist_zh_CN_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
new file mode 100644
index 0000000..d684af2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="zh-cn">
+<title>访客</title>
+<shortdesc>â<wintitle>访客</wintitle>â页é¢å示已å®ä¹ç KVM èææºã</shortdesc>
+<csbody>
+<p>å¯¹äºæ¯ä¸ªè®¿å®¢ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl><dlentry>
+<dt>åç§°</dt>
+<dd>èææºçåç§°ã</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>èææºä¸å¤çå¨ä½¿ç¨ç¾åæ¯ã</dd>
+</dlentry><dlentry>
+<dt>ç½ç» I/O</dt>
+<dd>ç½ç»è¾å
¥/è¾åºä¼ è¾éåº¦ï¼æ KB/ç§è®¡ï¼ã</dd>
+</dlentry><dlentry>
+<dt>ç£ç I/O</dt>
+<dd>ç£çè¾å
¥/è¾åºä¼ è¾éåº¦ï¼æ KB/ç§è®¡ï¼ã</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>访客å¤äºéæ´»å¨ç¶ææ¶ï¼è®¿å®¢æä½ç³»ç»æ§å¶å°çç¶æï¼æè
表示 <tm tmtype="tm" trademark="Linux">Linux</tm> ååçç徿 ã</dd>
+</dlentry></dl></p>
+<p>å¯ä¸ºæ¯ä¸ªè®¿å®¢æ¾ç¤ºä»¥ä¸æä½å¾æ ï¼<dl>
+<dlentry>
+<dt>éç½®</dt>
+<dd>å廿¤é¡¹ä»¥é置访客ã</dd>
+</dlentry><dlentry>
+<dt>çµæºï¼å¯å¨æåæ¢ï¼</dt>
+<dd>å廿¤é¡¹ä»¥å¼å¯æå
³é访客ççµæºãå¦æè¯¥å¾æ 为红è²ï¼é£ä¹çµæºå·²å
³éï¼å¦æè¯¥å¾æ 为绿è²ï¼é£ä¹çµæºå·²å¼å¯ã</dd>
+</dlentry></dl> </p>
+<p>å¯ä¸ºæ¯ä¸ªè®¿å®¢éæ©ä»¥ä¸æä½ï¼<ul>
+<li>éæ©<uicontrol>è¿æ¥</uicontrol>ä»¥è¿æ¥å°è®¿å®¢æä½ç³»ç»çè¿ç¨æ§å¶å°ã</li>
+<li>éæ©<uicontrol>管çä»è´¨</uicontrol>ä»¥æ´æ¹å®è£
ä»è´¨çè·¯å¾ã</li>
+<li>éæ©<uicontrol>éç½®</uicontrol>以é置访客ã</li>
+<li>éæ©<uicontrol>ç¼è¾</uicontrol>以ç¼è¾ç°æè®¿å®¢ç屿§ãä»
å½åæ¢æ¶æå¯ç¼è¾è®¿å®¢ã</li>
+<li>éæ©<uicontrol>å é¤</uicontrol>以å é¤è®¿å®¢ã</li>
+</ul>è¦å建访客æèææºï¼è¯·åå»é¡µé¢å³ä¸æ¹ç<uicontrol>å å·é® (+) </uicontrol> 徿 ã</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="zh-cn">
+<title>åå»ºèææº</title>
+<shortdesc>éè¿ä½¿ç¨ç°ææ¨¡æ¿åå»ºèææºã</shortdesc>
+<csbody>
+<p> <ol>
+<li>è¾å
¥ç¨äºæ è¯èææºçåç§°ã</li>
+<li rev="rev1">éæ©æ¨¡æ¿ã<ul>
+<li>å¦ææ¨¡æ¿å·²åå¨ï¼è¯·ä»ææ¾ç¤ºççæ¨¡æ¿ä¸éæ©ã</li>
+<li>妿ä¸åå¨ä»»ä½æ¨¡æ¿ï¼è¯·åå»<uicontrol>å建模æ¿</uicontrol>以å建模æ¿ã</li>
+</ul></li>
+<li>åå»<uicontrol>å建</uicontrol>ã</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="zh-cn">
+<title>ç¼è¾è®¿å®¢</title>
+<shortdesc>ç¼è¾ç°æèææºç屿§ãä¸äºå±æ§åªè½å¨è®¿å®¢å·²åæ¢çæ
åµä¸ç¼è¾ãå
¶ä»å±æ§å°å¨ä¸ä¸æ¬¡å¼å¯¼æ¶çæã</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>å¯¹äºæ¯ä¸ªè®¿å®¢ï¼ä¼å¨â<wintitle>常è§</wintitle>âé项å¡ä¸æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
+<dlentry>
+<dt>åç§°</dt>
+<dd>èææºçåç§°ãï¼åªè½å¨è®¿å®¢å·²åæ¢çæ
åµä¸ç¼è¾ï¼</dd>
+</dlentry><dlentry>
+<dt>CPU æ°</dt>
+<dd>å¤çå¨çæ°ç®ãï¼å¦æè®¿å®¢æ£å¨è¿è¡ï¼æ°æ°éå°å¨ä¸ä¸æ¬¡å¼å¯¼æ¶çæï¼</dd>
+</dlentry><dlentry>
+<dt>å
å</dt>
+<dd>å
åéï¼ä»¥ MB 计ï¼ãï¼å¦æè®¿å®¢æ£å¨è¿è¡ï¼æ°æ°éå°å¨ä¸ä¸æ¬¡å¼å¯¼æ¶çæï¼</dd>
+</dlentry><dlentry>
+<dt>徿 </dt>
+<dd>访客å¤äºéæ´»å¨ç¶ææ¶ï¼è¡¨ç¤ºè¦æ¾ç¤ºç Linux ååçè䏿¯å½åç¶æ (Livetile) çå¾å½¢å¾åã</dd>
+</dlentry></dl></p>
+<p>ä¼å¨â<wintitle>åå¨å¨</wintitle>âé项å¡ä¸æ¾ç¤ºä»¥ä¸ä¿¡æ¯ã</p>
+<dl><dlentry>
+<dt>åå¨å¨</dt>
+<dd>æ¾ç¤ºç¨äºå®è£
ç ISO æä»¶æå¨çä½ç½®ã</dd>
+</dlentry></dl>
+<p> å¯å¯¹æªç¦ç¨çåæ®µè¿è¡ç¼è¾ãç¼è¾å段ä¹åï¼è¯·åå»<uicontrol>ä¿å</uicontrol>ã</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="zh-cn">
+<title>æ·»å ãæ¿æ¢ææç¦»åå¨è®¾å¤</title>
+<shortdesc rev="rev1">æ¨å¯ä»¥å¯¹èææºæ·»å ãæ¿æ¢ææç¦»åå¨è®¾å¤ãå¯ä¸åæ¯æç设å¤ä¸º CDROMãè¦ç¼è¾åå¨è®¾å¤ï¼è¯·éµå¾ªä»¥ä¸æ¥éª¤ï¼</shortdesc>
+<csbody>
+<ol>
+<li>å¨â<wintitle>ç¼è¾è®¿å®¢</wintitle>âçªå£ä¸ï¼éæ©â<wintitle>åå¨å¨</wintitle>âã</li>
+<li>è¦æ¿æ¢åå¨è®¾å¤ï¼è¯·åå»ç¬¬ä¸ä¸ªå¾æ ï¼å¸¦æ<uicontrol>æ©è²ææ (/)</uicontrol>ãè¾å
¥ ISO æä»¶è·¯å¾å¹¶åå»<uicontrol>æ¿æ¢</uicontrol>ã</li>
+<li>è¦æç¦»åå¨è®¾å¤ï¼è¯·åå»ç¬¬äºä¸ªå¾æ ï¼å¸¦æ<uicontrol>红è²çå线 (-)</uicontrol>ã确认å 餿ä½ï¼ç¶ååå»<uicontrol>ç¡®å®</uicontrol>ã</li>
+<li>è¦æ·»å åå¨è®¾å¤ï¼è¯·åå»ç¬¬ä¸ä¸ªå¾æ ï¼å¸¦æ<uicontrol>绿è²å å·é® (+)</uicontrol>ãè¾å
¥è®¾å¤åå ISO æä»¶è·¯å¾å¹¶åå»<uicontrol>æç¦»</uicontrol>ã</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="zh-cn">
+<title>æ¿æ¢ VM ç CDROM</title>
+<shortdesc rev="rev1">å®è£
宿ä¹åï¼æ¨å¯ä»¥æ¿æ¢èææºç CDROM çå
容ã</shortdesc>
+<csbody>
+<ol>
+<li>请确ä¿å·²å¯å¨èææºã</li>
+<li>ä»âæä½âèåä¸ï¼éæ©<uicontrol>管çä»è´¨</uicontrol>ã</li>
+<li>è¦æ´æ¹å½åè£
å
¥å° CDROM ä¸çå
容ï¼è¯·åå» hdc åæ®µæè¾¹ç<uicontrol>æ©è²ææ (/)</uicontrol> 徿 ã</li>
+<li>å¨â<wintitle>æ¿æ¢ VM ç CDROM</wintitle>â页é¢ä¸ï¼è¾å
¥ ISO æä»¶è·¯å¾ãå¦å¤ä¸¤ä¸ªå段为åªè¯»ã</li>
+<li>åå»<uicontrol>æ¿æ¢</uicontrol>ã</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita
new file mode 100644
index 0000000..78a89c3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="zh-cn">
+<title>主æº</title>
+<shortdesc>â<wintitle>主æº</wintitle>â页颿¾ç¤ºæå
³ä¸»æºç³»ç»çä¿¡æ¯ï¼å¹¶ä¸å
许æ¨å¯¹ä¸»æºè¿è¡å
³éãå¯å¨åè¿æ¥ã</shortdesc>
+<csbody>
+<p>å¯å¯¹ä¸»æºæ§è¡ä»¥ä¸æä½ï¼<ul>
+<li>éæ©<uicontrol>å
³é</uicontrol>以å
³é主æºç³»ç»ã</li>
+<li>éæ©<uicontrol>éæ°å¯å¨</uicontrol>以鿰å¯å¨ä¸»æºç³»ç»ã</li>
+<li>éæ©<uicontrol>è¿æ¥</uicontrol>以æå¼ä¸ä¸»æºç³»ç»ç VNC è¿æ¥ï¼å¦æå°æªè¿æ¥ï¼ã</li>
+</ul></p>
+<p>åå»ä»¥ä¸é¨å以æ¾ç¤ºæå
³ä¸»æºçä¿¡æ¯ï¼<dl>
+<dlentry>
+<dt>åºæ¬ä¿¡æ¯</dt>
+<dd>æ¬é¨åæ¾ç¤ºä¸»æºæä½ç³»ç»ååçãçæ¬å代ç å称以åå¤çå¨ç±»ååå
åéï¼ä»¥ GB 计ï¼ã</dd>
+</dlentry><dlentry>
+<dt>ç³»ç»ç»è®¡ä¿¡æ¯</dt>
+<dd>æ¬é¨åæ¾ç¤ºå¾å½¢ï¼ä»¥æ¾ç¤ºä¸»æºæå
³ CPUãå
åãç£ç I/O åç½ç» I/O çç»è®¡ä¿¡æ¯ãéæ©<uicontrol>ç¦»å¼æ¤é¡µé¢ä¹åæ¶éæ°æ®</uicontrol>以继ç»å¨ä¸»æºé项å¡ä¸å¨è§å¾ä¸æ¶æ¶éæ°æ®ã</dd>
+</dlentry><dlentry>
+<dt>è½¯ä»¶æ´æ°</dt>
+<dd>æ¬é¨åæ¾ç¤ºææ´æ°å¯ç¨çææè½¯ä»¶å
çä¿¡æ¯ï¼å
¶ä¸å
æ¬è½¯ä»¶å
åç§°ãçæ¬ãä½ç³»ç»æååå¨åºãå¯éè¿éæ©<uicontrol>å
¨é¨æ´æ°</uicontrol>æ¥æ´æ°æåç¤ºçææè½¯ä»¶å
ãä¸è½éå¯¹æ´æ°éæ©å个软件å
ã</dd>
+</dlentry><dlentry>
+<dt>åå¨åº</dt>
+<dd>æ¬é¨åæ¾ç¤ºä¸ä¸»æºç³»ç»å
³èçåå¨åºãæ¨å¯ä»¥æ·»å ãå¯ç¨ãç¼è¾æé¤å»åå¨åºãå½å¯ç¨åå¨åºä¼å
许主æºå¯¹å
¶è¿è¡è®¿é®æ¶ï¼æ·»å åå¨åºä¼å°å
¶ä¸ä¸»æºç³»ç»å
³èã妿æ¨çç³»ç»ä¸º Red Hat Enterprise Linux æ Fedoraï¼é£ä¹å¯æ·»å <filepath>yum</filepath> åå¨åºã妿æ¨çç³»ç»ä¸º Ubuntu æ Debianï¼é£ä¹è¯·æ·»å <filepath>deb</filepath> åå¨åºã<p>妿è¦å¤ç Yum åå¨åºï¼æ¨å¯ä»¥æ·»å GPG æ£æ¥ä»¥éªè¯æ¤åå¨åºä¸ç软件å
æ¯å¦å·²æåãéæ©ä¸ä¸ªåå¨åºï¼ç¶åéæ©<uicontrol>ç¼è¾</uicontrol>ãéæ©<uicontrol>æ¯</uicontrol>以å¯ç¨ GPG æ£æ¥ï¼ç¶åè¾å
¥åå¨åºä¸ GPG å¯é¥æä»¶ç URLã</p></dd>
+</dlentry><dlentry>
+<dt>è°è¯æ¥å</dt>
+<dd>æ¬é¨åæ¾ç¤ºè°è¯æ¥åï¼å
¶ä¸å
æ¬åç§°åæä»¶è·¯å¾ãæ¨å¯ä»¥ä»é项ä¸è¿è¡éæ©ä»¥çææ°æ¥åï¼æè
å¯¹ç°ææ¥åè¿è¡éå½åãé¤å»æä¸è½½ã<p>è°è¯æ¥åå°ä½¿ç¨
+<cmdname>sosreport</cmdname> å½ä»¤çæã该æ¥åå¯ç¨äº Red
+Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>ãFedora å Ubuntu ååçã该å½ä»¤å°çæå
å«é
ç½®åè¯æä¿¡æ¯ç .tar æä»¶ï¼ä¾å¦ï¼æ£å¨è¿è¡çå
æ ¸çæ¬ãå·²è£
å
¥ç模å以åç³»ç»åæå¡é
ç½®æä»¶ã该å½ä»¤è¿ä¼è¿è¡å¤é¨ç¨åºä»¥æ¶éæ´å¤ä¿¡æ¯å¹¶å°æ¤è¾åºåå¨å¨çæç彿¡£ä¸ã</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita
new file mode 100644
index 0000000..f6aa532
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="zh-cn">
+<title>ç½ç»</title>
+<shortdesc>â<wintitle>ç½ç»</wintitle>â页颿¾ç¤ºæå
³ç½ç»è¿æ¥çä¿¡æ¯ã</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>ç½ç»å</dt>
+<dd>ç½ç»çåç§°æ<uicontrol>缺çå¼</uicontrol>ã</dd>
+</dlentry><dlentry>
+<dt>ç¶æ</dt>
+<dd>ç½ç»çç¶æï¼æ´»å¨ï¼ç»¿è²ï¼æéæ´»å¨ï¼çº¢è²ï¼ã</dd>
+</dlentry><dlentry>
+<dt>ç½ç»ç±»å</dt>
+<dd>ç½ç»ç±»åï¼ä¾å¦ï¼<uicontrol>NAT</uicontrol>ï¼ç½ç»å°å转æ¢ï¼ã</dd>
+</dlentry><dlentry>
+<dt>æ¥å£</dt>
+<dd>ç½ç»æ¥å£ï¼ä¾å¦ï¼<uicontrol>virbr0</uicontrol>ï¼ç¼ºçå¼ï¼ã</dd>
+</dlentry><dlentry>
+<dt>å°å空é´</dt>
+<dd>IP å°åã</dd>
+</dlentry></dl></p>
+<p>å¯ä»¥éæ©ä»¥ä¸æä½ï¼<ul>
+<li rev="rev1">éæ©<uicontrol>å¼å§</uicontrol>以å¼å§ç½ç»è¿æ¥ã</li>
+<li>éæ©<uicontrol>忢</uicontrol>ä»¥ç»æç½ç»è¿æ¥ã</li>
+<li>éæ©<uicontrol>å é¤</uicontrol>以å é¤è¿æ¥ä¿¡æ¯ã</li>
+</ul>è¦å建ç½ç»ï¼è¯·å廿¾ç¤ºå±å³ä¸æ¹ç<uicontrol>å å·é® (+)</uicontrol> 徿 ã</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="zh-cn">
+<title>å建ç½ç»</title>
+<shortdesc>å建ç½ç»ã</shortdesc>
+<csbody>
+<p> <ol>
+<li>è¾å
¥ç½ç»çåç§°ã</li>
+<li>å廿¤é¡¹ä»¥éæ©ç½ç»ç±»åã<dl rev="rev1"><dlentry>
+<dt><uicontrol>é离</uicontrol></dt>
+<dd>é离æ¹å¼ãè®¿å®¢æ æ³åå¤é¨ç³»ç»åééä¿¡æä»å
¶æ¥æ¶éä¿¡ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>ç½ç»å°åè½¬æ¢æ¹å¼ãä»è®¿å®¢å°å¤é¨ç³»ç»çéä¿¡å°ä½¿ç¨ä¸»æº IP å°åãå¤é¨ç³»ç»æ æ³å¯å¨ä¸è®¿å®¢çéä¿¡ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>æ¡¥æ¥</uicontrol></dt>
+<dd>æ¡¥æ¥æ¹å¼ã访客å¯ä¸å¤é¨ç³»ç»è¿è¡éä¿¡å¹¶ä¸ç±ä½ä¸ºç½ç»ä¸çç©çç³»ç»çå¤é¨ç³»ç»èç³»ãå¯¹äºæ¡¥æ¥æ¹å¼ï¼å¿
é¡»æå®éå ç®æ å VLAN ä¿¡æ¯ã</dd>
+</dlentry></dl></li>
+<li>åå»<uicontrol>å建</uicontrol>ã</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
new file mode 100644
index 0000000..cfb09f5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="zh-cn">
+<title>åå¨å¨</title>
+<shortdesc>â<wintitle>åå¨å¨</wintitle>页é¢å示å¯ç¨å卿± ï¼å
¶ä¸å
æ¬ç°æçâ缺çâåâISOâå卿± ã妿æ¨è¦ä½¿ç¨æ¨èªå·±ç ISOï¼è¯·å°å®æ·»å è³âISOâå卿± è·¯å¾ã</shortdesc>
+<csbody>
+<p>å¯¹äºæ¯ä¸ªå卿± ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
+<dlentry>
+<dt>åç§°</dt>
+<dd>å卿± çå称以å使ç¨ç¾åæ¯ã</dd>
+</dlentry><dlentry>
+<dt>ç¶æ</dt>
+<dd>å卿± çç¶æï¼æ´»å¨ï¼ç»¿è²ï¼æéæ´»å¨ï¼çº¢è²ï¼ã</dd>
+</dlentry><dlentry>
+<dt>ä½ç½® </dt>
+<dd>å卿± æå¨ä½ç½®çæä»¶è·¯å¾ã</dd>
+</dlentry><dlentry>
+<dt>ç±»å</dt>
+<dd>å卿± çç±»åï¼ä¾å¦ï¼<uicontrol>dir</uicontrol>ã</dd>
+</dlentry><dlentry>
+<dt>容é</dt>
+<dd>å卿± ä¸ç空é´éã</dd>
+</dlentry><dlentry>
+<dt>å·²åé
</dt>
+<dd>å卿± ä¸å·²åé
ç空é´éã</dd>
+</dlentry></dl></p>
+<p>å¯ä¸ºæ¯ä¸ªå卿± 鿩以䏿ä½ï¼<ul>
+<li>éæ©<uicontrol>æ¿æ´»</uicontrol>ä»¥æ¿æ´»å卿± 以使å
¶å¯ä½¿ç¨ã</li>
+<li>éæ©<uicontrol>åæ¶æ¿æ´»</uicontrol>ä»¥åæ¶æ¿æ´»æ´»å¨å卿± ã</li>
+<li>éæ©<uicontrol>åæ¶å®ä¹</uicontrol>以é¤å»éæ´»å¨å卿± ã</li>
+</ul></p>
+<p>è¦æ¾ç¤ºå卿± çåå¨å·è¯¦ç»ä¿¡æ¯ï¼è¯·åå»å卿± è¡å³ç«¯çç®å¤´ã详ç»ä¿¡æ¯å
æ¬ä»¥ä¸å
容ï¼<dl><dlentry>
+<dt>ç±»å</dt>
+<dd>å·çç±»åï¼ä¾å¦ï¼<uicontrol>æä»¶</uicontrol>ã</dd>
+</dlentry><dlentry>
+<dt>æ ¼å¼</dt>
+<dd>æ ¼å¼å ç±»åèææä¸åã</dd>
+</dlentry><dlentry>
+<dt>容é</dt>
+<dd>åå¨å·ç大å°ã</dd>
+</dlentry><dlentry>
+<dt>åé
</dt>
+<dd>å卿± ä¸å·²åé
ç空é´éã</dd>
+</dlentry></dl>è¦å®ä¹å卿± ï¼è¯·å廿¾ç¤ºå±å³ä¸æ¹ç<uicontrol>å å·é® (+)</uicontrol> 徿 ã</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="zh-cn">
+<title>å®ä¹å卿± </title>
+<shortdesc> å®ä¹å卿± ã</shortdesc>
+<csbody>
+<p> <ol>
+<li>å¨<uicontrol>å卿± åç§°</uicontrol>åæ®µä¸ï¼è¾å
¥ç¨äºæ è¯å卿± çåç§°ã</li>
+<li>å¨<uicontrol>å卿± ç±»å</uicontrol>å表ä¸ï¼éæ©ç±»åï¼<dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>æå®ç®å½æ± ãå½éæ© <uicontrol>DIR</uicontrol> æ¶ï¼è¾å
¥<uicontrol>åå¨è·¯å¾</uicontrol>ï¼å卿± çæä»¶è·¯å¾ï¼ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>æå®ç½ç»æä»¶ç³»ç»æ± ãå½éæ© <uicontrol>NFS</uicontrol> æ¶ï¼è¾å
¥ <uicontrol>NFS æå¡å¨ IP å°å</uicontrol>å <uicontrol>NFS è·¯å¾</uicontrol>ï¼å·²å¯¼åºç®å½çè·¯å¾ï¼ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>æ ¹æ® iSCSI æå¡å¨ä¸åé
çç®æ æå®æ± ãå½éæ© <uicontrol>iSCSI</uicontrol> æ¶ï¼å¨ iSCSI æå¡å¨ä¸è¾å
¥ <uicontrol>iSCSI æå¡å¨ IP å°å</uicontrol>å<uicontrol>ç®æ </uicontrol>ãæ¨å¯ä»¥éæ©æ§å°éæ©æ·»å iSCSI 认è¯ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>é»è¾</uicontrol></dt>
+<dd>æå®é»è¾å·å卿± ãå¨<uicontrol>设å¤è·¯å¾</uicontrol>ä¸éæ©è®¾å¤çä½ç½®ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI å
纤éé</uicontrol></dt>
+<dd>æ ¹æ® SCSI å
纤ééæå®æ± ãéæ©è¦ä½¿ç¨ç SCSI éé
å¨ã</dd>
+</dlentry></dl></li>
+<li>åå»<uicontrol>å建</uicontrol>ã</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
new file mode 100644
index 0000000..ca50119
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="zh-cn">
+<title>模æ¿</title>
+<shortdesc>â<wintitle>模æ¿</wintitle>â页颿¾ç¤ºå¯ç¨äºå建 KVM 访客çå·²å®ä¹èææºæ¨¡æ¿ã</shortdesc>
+<csbody>
+<p>å¯¹äºæ¯ä¸ªæ¨¡æ¿ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
+<dlentry>
+<dt>æä½ç³»ç»</dt>
+<dd>æä½ç³»ç»æååççåç§°ã</dd>
+</dlentry><dlentry>
+<dt>çæ¬</dt>
+<dd>æä½ç³»ç»æååçççæ¬ã</dd>
+</dlentry><dlentry>
+<dt>CPU æ°</dt>
+<dd>为模æ¿å®ä¹çå¤ç卿°ã</dd>
+</dlentry><dlentry>
+<dt>å
å</dt>
+<dd>è¦åé
çéæºåååå¨éï¼ä»¥ MB 计ï¼ã</dd>
+</dlentry></dl></p>
+<p>å¯ä¸ºæ¯ä¸ªæ¨¡æ¿éæ©ä»¥ä¸æä½ï¼<ul>
+<li>éæ©<uicontrol>ç¼è¾</uicontrol>以ç¼è¾æ¨¡æ¿ã</li>
+<li>éæ©<uicontrol>å é¤</uicontrol>以å 餿¨¡æ¿ã</li>
+</ul>è¦æ·»å 模æ¿ï¼è¯·å廿¾ç¤ºå±å³ä¸æ¹ç<uicontrol>å å·é® (+)</uicontrol> 徿 ã</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="zh-cn">
+<title>ç¼è¾æ¨¡æ¿</title>
+<shortdesc>ç¼è¾ç°ææ¨¡æ¿ã</shortdesc>
+<csbody>
+<p>å¯¹äºæ¯ä¸ªæ¨¡æ¿ï¼ä¼æ¾ç¤ºä»¥ä¸ä¿¡æ¯ï¼<dl>
+<dlentry>
+<dt>åç§°</dt>
+<dd>模æ¿çåç§°ã</dd>
+</dlentry><dlentry>
+<dt>ä¾åºå</dt>
+<dd>å
¬å¸åç§°ï¼è¯¥å
¬å¸åå»ºäºæ¨¡æ¿å·²é
置使ç¨çæä½ç³»ç»æååçã</dd>
+</dlentry><dlentry>
+<dt>çæ¬</dt>
+<dd>模æ¿å·²é
置使ç¨çæä½ç³»ç»æååçççæ¬ã</dd>
+</dlentry><dlentry>
+<dt>CPU æ°é</dt>
+<dd>为模æ¿å®ä¹çå¤ç卿°ã</dd>
+</dlentry><dlentry>
+<dt>å
å</dt>
+<dd>è¦åé
ç»èææºçå
åéï¼ä»¥ MB 计ï¼ã</dd>
+</dlentry><dlentry>
+<dt>ç£ç</dt>
+<dd>ç£ç大å°ï¼ä»¥ GB 计ï¼ã</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>ç¨äºå®è£
KVM 访客ç ISO æä»¶æå¨ä½ç½®çæä»¶è·¯å¾ã</dd>
+</dlentry><dlentry>
+<dt>å卿± </dt>
+<dd>ç¹å®å卿± æç¼ºçå卿± ã</dd>
+</dlentry><dlentry>
+<dt>ç½ç»</dt>
+<dd>å¯ä¾ KVM 访客使ç¨ç缺çç½ç»æ¥å£ãæ¨å¯ä»¥éæ©å¤ä¸ªç½ç»ã</dd>
+</dlentry></dl> å¯å¯¹æªç¦ç¨çåæ®µè¿è¡ç¼è¾ãç¼è¾å段ä¹åï¼è¯·åå»<uicontrol>ä¿å</uicontrol>ã</p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>æ·»å æ¨¡æ¿</title>
+<shortdesc>仿ºä»è´¨ä¸æ·»å 模æ¿ãæ¨å¯ä»¥å°æ¨èªå·±ç ISO æ åæ·»å è³âISOâå卿± 以ç¨äºåç»åç°ã</shortdesc>
+<csbody>
+<p>ä»ä»¥ä¸é项鿩æºä»è´¨æå¨çä½ç½®ï¼<dl>
+<dlentry>
+<dt>æ¬å° ISO æ å</dt>
+<dd>éæ©æ¤é¡¹ä»¥å¯¹ç³»ç»ä¸å¯ç¨çå®è£
ISO æ åçå卿± è¿è¡æ«æã</dd>
+</dlentry><dlentry>
+<dt>è¿ç¨ ISO æ å</dt>
+<dd>éæ©æ¤é¡¹ä»¥æå®å®è£
ISO æ åçè¿ç¨ä½ç½®ã</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>æ·»å æ¨¡æ¿ - æ¬å° ISO æ å</title>
+<shortdesc>仿¬å° ISO æ åæ·»å 模æ¿ã</shortdesc>
+<csbody>
+<p>伿¾ç¤ºç³»ç»ä¸å¯ç¨ç ISO æ åã<dl><dlentry>
+<dt>æä½ç³»ç»</dt>
+<dd>æä½ç³»ç»æååççåç§°ã</dd>
+</dlentry><dlentry>
+<dt>çæ¬</dt>
+<dd>æä½ç³»ç»æååçççæ¬ã</dd>
+</dlentry><dlentry>
+<dt>大å°</dt>
+<dd>ISO æ åç大å°ã</dd>
+</dlentry></dl></p>
+<p>è¦ä» ISO æ åå建模æ¿ï¼è¯·ä»ä»¥ä¸é项ä¸éæ©ï¼<ul>
+<li>éæ©è¦ä»å
¶å建模æ¿ç ISO æ åï¼ç¶ååå»<uicontrol>仿é ISO å建模æ¿</uicontrol>ã</li>
+<li>éæ©<uicontrol>å
¨é¨</uicontrol>以仿¯ä¸ªæå示ç ISO æ åå建模æ¿ï¼ç¶ååå»<uicontrol>仿é ISO å建模æ¿</uicontrol>ã</li>
+<li>妿æ¨è¦ä½¿ç¨ç ISO æ åæªåºç°å¨æ«æç»æä¸ï¼é£ä¹å¯ä»ä»¥ä¸é项ä¸éæ©ï¼<ul>
+<li>éæ©<uicontrol>æè¦ä½¿ç¨ç¹å® ISO æä»¶</uicontrol>以æå® ISO æ åçè·¯å¾ã</li>
+<li>åå»<uicontrol>æç´¢æ´å¤ ISO</uicontrol> 以æç´¢æ´å¤ ISO æ åã</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
new file mode 100644
index 0000000..9c8ac26
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+zh_TW_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_TW
+
+dist_zh_TW_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
new file mode 100644
index 0000000..cf73785
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="zh-tw">
+<title>客é«</title>
+<shortdesc>ã<wintitle>客é«</wintitle>ãé 颿ååºå·²å®ç¾©ç KVM èæ¬æ©å¨ã</shortdesc>
+<csbody>
+<p>å°æ¼æ¯ä¸å客é«ï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl><dlentry>
+<dt>å稱</dt>
+<dd>èæ¬æ©å¨çå稱ã</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>èæ¬æ©å¨ä¸èçå¨ä½¿ç¨ççç¾åæ¯ã</dd>
+</dlentry><dlentry>
+<dt>網路 I/O</dt>
+<dd>網路輸å
¥/輸åºå³è¼¸éç (KB/s)ã</dd>
+</dlentry><dlentry>
+<dt>ç£ç¢ I/O</dt>
+<dd>ç£ç¢è¼¸å
¥/輸åºå³è¼¸éç (KB/s)ã</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>客é«ä½æ¥ç³»çµ±ä¸»æ§å°ççæ
ï¼ææ¯è¡¨ç¤º <tm tmtype="tm" trademark="Linux">Linux</tm> ç¼è¡å¥ä»¶çå示ï¼å¦æå®¢é«æªèæ¼ä½ç¨ä¸çæ
ï¼ã</dd>
+</dlentry></dl></p>
+<p>å°æ¼æ¯ä¸å客é«ï¼å°æé¡¯ç¤ºä¸ååä½å示ï¼<dl>
+<dlentry>
+<dt>éè¨</dt>
+<dd>æä¸ä¸å¯éè¨å®¢é«ã</dd>
+</dlentry><dlentry>
+<dt>黿ºï¼ååæåæ¢ï¼</dt>
+<dd>æä¸ä¸å¯éåæéé客é«ç黿ºãå¦æè©²å示çºç´
è²ï¼åè¡¨ç¤ºé»æºééï¼å¦æè©²å示çºç¶ è²ï¼åè¡¨ç¤ºé»æºéåã</dd>
+</dlentry></dl> </p>
+<p>å¯éå°æ¯ä¸å客é«é¸åä¸ååä½ï¼<ul>
+<li>é¸å<uicontrol>飿¥</uicontrol>å¯é£æ¥è³å®¢é«ä½æ¥ç³»çµ±çé 端主æ§å°ã</li>
+<li>é¸å<uicontrol>管çåªé«</uicontrol>å¯è®æ´å®è£åªé«çè·¯å¾ã</li>
+<li>é¸å<uicontrol>éè¨</uicontrol>å¯éè¨å®¢é«ã</li>
+<li>é¸å<uicontrol>編輯</uicontrol>å¯ç·¨è¼¯ç¾æå®¢é«çå
§å®¹ãå
å¨åæ¢æï¼æè½ç·¨è¼¯å®¢é«ã</li>
+<li>é¸å<uicontrol>åªé¤</uicontrol>å¯åªé¤å®¢é«ã</li>
+</ul>è¥è¦å»ºç«å®¢é«æèæ¬æ©å¨ï¼è«æä¸ä¸é¡¯ç¤ºé é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="zh-tw">
+<title>建ç«èæ¬æ©å¨</title>
+<shortdesc>使ç¨ç¾æç¯æ¬å»ºç«èæ¬æ©å¨ã</shortdesc>
+<csbody>
+<p> <ol>
+<li>輸å
¥ç¨ä¾èå¥èæ¬æ©å¨çå稱ã</li>
+<li rev="rev1">é¸åç¯æ¬ã<ul>
+<li>å¦æç¯æ¬åå¨ï¼è«å¾é¡¯ç¤ºçç¯æ¬ä¸é¸åã</li>
+<li>å¦ææ²æç¯æ¬ï¼è«æä¸ä¸<uicontrol>建ç«ç¯æ¬</uicontrol>ä¾å»ºç«ç¯æ¬ã</li>
+</ul></li>
+<li>æä¸ä¸<uicontrol>建ç«</uicontrol>ã</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="zh-tw">
+<title>編輯客é«</title>
+<shortdesc>ç·¨è¼¯ç¾æèæ¬æ©å¨çå
§å®¹ãé¨åå
§å®¹åªè½å¨å®¢é«åæ¢æé²è¡ç·¨è¼¯ãå
¶ä»å
§å®¹å°å¨ä¸ä¸æ¬¡ååæçæã</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>å°æ¼æ¯ä¸å客é«ï¼å°æå¨ã<wintitle>ä¸è¬</wintitle>ãæ¨ç±¤ä¸é¡¯ç¤ºä¸åè³è¨ï¼<dl>
+<dlentry>
+<dt>å稱</dt>
+<dd>èæ¬æ©å¨çå稱ãï¼åªè½å¨å®¢é«åæ¢æé²è¡ç·¨è¼¯ï¼</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>èç卿¸ç®ãï¼å¦æå®¢é«å¨å·è¡ä¸ï¼åæ°æ¸éå°å¨ä¸ä¸æ¬¡ååæçæï¼</dd>
+</dlentry><dlentry>
+<dt>è¨æ¶é«</dt>
+<dd>è¨æ¶é«æ¸é (MB)ãï¼å¦æå®¢é«å¨å·è¡ä¸ï¼åæ°æ¸éå°å¨ä¸ä¸æ¬¡ååæçæï¼</dd>
+</dlentry><dlentry>
+<dt>å示</dt>
+<dd>ç¶å®¢é«ä¸èæ¼ä½ç¨ä¸çæ
æï¼è¦å代ç¾è¡çæ
(Livetile) 顯示ç代表 Linux ç¼è¡å¥ä»¶çå形影åã</dd>
+</dlentry></dl></p>
+<p>ä¸åè³è¨æé¡¯ç¤ºå¨ã<wintitle>å²å</wintitle>ãæ¨ç±¤ä¸ã</p>
+<dl><dlentry>
+<dt>å²åé«</dt>
+<dd>é¡¯ç¤ºç¨æ¼å®è£ç ISO æªæ¡çä½ç½®ã</dd>
+</dlentry></dl>
+<p> å¯ä»¥ç·¨è¼¯æªåç¨çæ¬ä½ã編輯æ¬ä½ä¹å¾ï¼æä¸ä¸<uicontrol>å²å</uicontrol>ã</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="zh-tw">
+<title>æ°å¢ãå代æåé¢å²åè£ç½®</title>
+<shortdesc rev="rev1">æ¨å¯ä»¥æ°å¢ãå代æåé¢èæ¬æ©å¨çå²åè£ç½®ãå¯ä¸åæ¯æ´çè£ç½®æ¯ CDROMãè¥è¦ç·¨è¼¯å²åè£ç½®ï¼è«éµå¾ªä¸åæ¥é©ï¼</shortdesc>
+<csbody>
+<ol>
+<li>å¨ã<wintitle>編輯客é«</wintitle>ãè¦çªä¸ï¼é¸åã<wintitle>å²åé«</wintitle>ãã</li>
+<li>è¥è¦å代å²åè£ç½®ï¼è«æä¸ä¸å«æ<uicontrol>æ©è²æç· (/)</uicontrol> ç第ä¸åå示ã輸å
¥
+ISO æªæ¡è·¯å¾ï¼ç¶å¾æä¸ä¸<uicontrol>å代</uicontrol>ã</li>
+<li>è¥è¦åé¢å²åè£ç½®ï¼è«æä¸ä¸å«æ<uicontrol>ç´
è²æç· (/)</uicontrol> ç第äºåå示ã確èªåªé¤ï¼ç¶å¾æä¸ä¸<uicontrol>確å®</uicontrol>ã</li>
+<li>è¥è¦æ°å¢å²åè£ç½®ï¼è«æä¸ä¸å«æç¶ è²<uicontrol>å è (+)</uicontrol> ç第ä¸åå示ã輸å
¥è£ç½®å稱å
+ISO æªæ¡è·¯å¾ï¼ç¶å¾æä¸ä¸<uicontrol>飿¥</uicontrol>ã</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="zh-tw">
+<title>åä»£èæ¬æ©å¨ç CDROM</title>
+<shortdesc rev="rev1">å®è£å®æä¹å¾ï¼æ¨å¯ä»¥åä»£èæ¬æ©å¨ç CDROM çå
§å®¹ã</shortdesc>
+<csbody>
+<ol>
+<li>確å®èæ¬æ©å¨å·²ååã</li>
+<li>å¾ãåä½ãåè½è¡¨ä¸ï¼é¸å<uicontrol>管çåªé«</uicontrol>ã</li>
+<li>è¥è¦è®æ´ç®åå¨ CDROM ä¸å è¼çå
§å®¹ï¼è«æä¸ä¸ hdc æ¬ä½æéç<uicontrol>æ©è²æç· (/)</uicontrol> å示ã</li>
+<li>å¨ã<wintitle>åä»£èæ¬æ©å¨ç CDROM</wintitle>ãé é¢ä¸ï¼è¼¸å
¥ ISO æªæ¡è·¯å¾ãå¦å¤å
©åæ¬ä½æ¯å¯è®çã</li>
+<li>æä¸ä¸<uicontrol>å代</uicontrol>ã</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita
new file mode 100644
index 0000000..a55aae4
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="zh-tw">
+<title>主æ©</title>
+<shortdesc>ã<wintitle>主æ©</wintitle>ãé é¢æé¡¯ç¤ºä¸»æ©ç³»çµ±çç¸éè³è¨ï¼ä¸¦å®¹è¨±æ¨ééãéæ°åå以å飿¥å°ä¸»æ©ã</shortdesc>
+<csbody>
+<p>æ¨å¯ä»¥éå°ä¸»æ©å·è¡ä¸ååä½ï¼<ul>
+<li>é¸å<uicontrol>éé</uicontrol>以éé主æ©ç³»çµ±ã</li>
+<li>é¸å<uicontrol>éæ°åå</uicontrol>以鿰åå主æ©ç³»çµ±ã</li>
+<li>é¸å<uicontrol>飿¥</uicontrol>以éåè主æ©ç³»çµ±ç VNC é£ç·ï¼å¦æå°æªé£ç·å°ä¸»æ©ç³»çµ±ï¼ã</li>
+</ul></p>
+<p>æä¸ä¸ä¸ååæ®µä»¥é¡¯ç¤ºä¸»æ©çç¸éè³è¨ï¼<dl>
+<dlentry>
+<dt>åºæ¬è³è¨</dt>
+<dd>æ¤å段æé¡¯ç¤ºä¸»æ©ä½æ¥ç³»çµ±ç¼è¡å¥ä»¶ãçæ¬ãç¨å¼ç¢¼å稱ãèçå¨é¡å以åè¨æ¶é«æ¸é (GB)ã</dd>
+</dlentry><dlentry>
+<dt>系統統è¨è³æ</dt>
+<dd>æ¤å段æé¡¯ç¤ºä¸äºåå½¢ï¼ä»¥é¡¯ç¤ºä¸»æ©ç CPUãè¨æ¶é«ãç£ç¢ I/O å網路 I/O ççµ±è¨è³æãé¸å<uicontrol>é¢éæ¤é é¢ä¹å¾æ¶éè³æ</uicontrol>以å¨ä¸»æ©æ¨ç±¤å¾è¦ç·ä¸æ¶å¤±ä¹å¾ç¹¼çºæ¶éè³æã</dd>
+</dlentry><dlentry>
+<dt>è»é«æ´æ°</dt>
+<dd>æ¤å段æé¡¯ç¤ºå
·æå¯ç¨æ´æ°çææå¥ä»¶çç¸éè³è¨ï¼å
æ¬å¥ä»¶å稱ãçæ¬ãæ¶æ§åå²ååº«ãæ¨å¯ä»¥ééé¸å<uicontrol>å
¨é¨æ´æ°</uicontrol>便´æ°ææååºçå¥ä»¶ãä¸è½é¸ååå¥å¥ä»¶ä»¥é²è¡æ´æ°ã</dd>
+</dlentry><dlentry>
+<dt>å²å庫</dt>
+<dd>æ¤å段æé¡¯ç¤ºè主æ©ç³»çµ±ç¸éè¯çå²ååº«ãæ¨å¯ä»¥æ°å¢ãåç¨ã編輯æç§»é¤å²ååº«ãæ°å¢å²å庫å¯ä½¿å®è主æ©ç³»çµ±ç¸éè¯ï¼èåç¨å²å庫å容許主æ©ååå²å庫ã妿æ¨ç系統æ¯
+Red Hat Enterprise Linux æ Fedoraï¼åå¯ä»¥æ°å¢ <filepath>yum</filepath> å²å庫ã妿æ¨ç系統æ¯
+Ubuntu æ Debianï¼åå¯ä»¥æ°å¢ <filepath>deb</filepath> å²å庫ã<p>å¦ææ¨æ£å¨ä½¿ç¨
+yum å²å庫ï¼åå¯ä»¥æ°å¢ GPG 檢æ¥ä»¥é©èæ¤å²å庫ä¸çæåå¥ä»¶æ¯å¦æªæ¯æãé¸åå²å庫ï¼ç¶å¾é¸å<uicontrol>編輯</uicontrol>ãé¸å<uicontrol>æ¯</uicontrol>以åç¨
+GPG 檢æ¥ï¼ç¶å¾è¼¸å
¥å²å庫ç GPG éé°æªç URLã</p></dd>
+</dlentry><dlentry>
+<dt>é¤é¯å ±å</dt>
+<dd>æ¤å段顯示é¤é¯å ±åï¼å
æ¬åç¨±åæªæ¡è·¯å¾ãæ¨å¯ä»¥é¸åé¸é
以ç¢çæ°å ±åãææ¯éæ°å½åãç§»é¤æä¸è¼ç¾æå ±åã<p>é¤é¯å ±åæ¯ä½¿ç¨
+<cmdname>sosreport</cmdname> æä»¤ç¢ççã該æä»¤å¯ç¨æ¼ Red
+Hat Enterprise <tm tmtype="tm" trademark="Linux">Linux</tm>ãFedora
+å Ubuntu ç¼è¡å¥ä»¶ã該æä»¤æç¢ç .tar æªæ¡ï¼å
¶å
å«é
ç½®è診æ·è³è¨ï¼ä¾å¦å·è¡ä¸çæ ¸å¿çæ¬ãå·²è¼å
¥æ¨¡çµä»¥å系統åæåé
ç½®æªæ¡ã該æä»¤éæå·è¡å¤é¨ç¨å¼ä¾æ¶éæ´å¤è³è¨ä¸¦å°æ¤è¼¸åºå²åå¨ç¢ççä¿åæªä¸ã</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita
new file mode 100644
index 0000000..f392060
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="zh-tw">
+<title>網路</title>
+<shortdesc>ã<wintitle>網路</wintitle>ãé é¢æé¡¯ç¤ºç¶²è·¯é£ç·çç¸éè³è¨ã</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>網路å稱</dt>
+<dd>網路çåç¨±ï¼ææ¯<uicontrol>é è¨å¼</uicontrol>ã</dd>
+</dlentry><dlentry>
+<dt>çæ
</dt>
+<dd>網路ççæ
ï¼ä½ç¨ä¸ï¼ç¶ è²ï¼æéä½ç¨ä¸ï¼ç´
è²ï¼ã</dd>
+</dlentry><dlentry>
+<dt>網路é¡å</dt>
+<dd>網路é¡åï¼ä¾å¦ï¼<uicontrol>NAT</uicontrol>ï¼ç¶²åè½æï¼ã</dd>
+</dlentry><dlentry>
+<dt>ä»é¢</dt>
+<dd>網路ä»é¢ï¼ä¾å¦ï¼<uicontrol>virbr0</uicontrol>ï¼é è¨å¼ï¼ã</dd>
+</dlentry><dlentry>
+<dt>ä½å空é</dt>
+<dd>IP ä½åã</dd>
+</dlentry></dl></p>
+<p>å¯é¸åä¸ååä½ï¼<ul>
+<li rev="rev1">é¸å<uicontrol>éå§</uicontrol>以éå§ç¶²è·¯é£ç·ã</li>
+<li>é¸å<uicontrol>忢</uicontrol>ä»¥çµæç¶²è·¯é£ç·ã</li>
+<li>é¸å<uicontrol>åªé¤</uicontrol>以åªé¤é£ç·è³è¨ã</li>
+</ul>è¥è¦å»ºç«ç¶²è·¯ï¼è«æä¸ä¸é¡¯ç¤ºç«é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="zh-tw">
+<title>建ç«ç¶²è·¯</title>
+<shortdesc>建ç«ç¶²è·¯</shortdesc>
+<csbody>
+<p> <ol>
+<li>輸å
¥ç¶²è·¯çå稱ã</li>
+<li>æä¸ä¸ä»¥é¸å網路é¡åã<dl rev="rev1"><dlentry>
+<dt><uicontrol>å·²éé¢</uicontrol></dt>
+<dd>å·²é颿¨¡å¼ã客é«ç¡æ³å°éè¨å³éè³å¤é¨ç³»çµ±ï¼ä¹æ¥æ¶ä¸å°ä¾èªå¤é¨ç³»çµ±çéè¨ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>ç¶²åè½ææ¨¡å¼ãå¾å®¢é«å°å¤é¨ç³»çµ±çéè¨ä½¿ç¨ä¸»æ© IP ä½åãå¤é¨ç³»çµ±ç¡æ³èµ·å§å³éè³å®¢é«çéè¨ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>å·²æ©æ¥</uicontrol></dt>
+<dd>å·²æ©æ¥æ¨¡å¼ã客é«å¯ä»¥èå¤é¨ç³»çµ±éè¨ï¼ä¸¦ä¸å¤é¨ç³»çµ±å¯ä»¥é£æ¥è³å®¢é«ï¼å°±å¦å®¢é«æ¯ç¶²è·¯ä¸ç實é«ç³»çµ±ä¸æ¨£ãå°æ¼å·²æ©æ¥æ¨¡å¼ï¼æ¨å¿
é æå®å
¶ä»ç®çå°å VLAN è³è¨ã</dd>
+</dlentry></dl></li>
+<li>æä¸ä¸<uicontrol>建ç«</uicontrol>ã</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
new file mode 100644
index 0000000..971619c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="zh-tw">
+<title>å²åé«</title>
+<shortdesc>ã<wintitle>å²åé«</wintitle>ãé 颿ååºå¯ç¨çå²ååï¼å
æ¬ç¾æå¯ç¨çãé è¨ãå²ååå 'ISO' å²ååã妿è¦ä½¿ç¨æ¨èªå·±ç ISOï¼è«å°å
¶æ°å¢è³ 'ISO' å²ååè·¯å¾ã</shortdesc>
+<csbody>
+<p>å°æ¼æ¯ä¸åå²ååï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl>
+<dlentry>
+<dt>å稱</dt>
+<dd>å²ååçå稱å已使ç¨ç¾åæ¯ã</dd>
+</dlentry><dlentry>
+<dt>çæ
</dt>
+<dd>å²ååççæ
ï¼ä½ç¨ä¸ï¼ç¶ è²ï¼æéä½ç¨ä¸ï¼ç´
è²ï¼ã</dd>
+</dlentry><dlentry>
+<dt>ä½ç½®</dt>
+<dd>å²ååä½ç½®çæªæ¡è·¯å¾ã</dd>
+</dlentry><dlentry>
+<dt>é¡å</dt>
+<dd>å²ååçé¡åï¼ä¾å¦ï¼<uicontrol>dir</uicontrol>ã</dd>
+</dlentry><dlentry>
+<dt>容é</dt>
+<dd>å²ååä¸ç©ºéçæ¸éã</dd>
+</dlentry><dlentry>
+<dt>å·²é
ç½®</dt>
+<dd>å²ååä¸å·²é
ç½®çç©ºéæ¸éã</dd>
+</dlentry></dl></p>
+<p>å¯éå°æ¯ä¸åå²ååé¸åä¸ååä½ï¼<ul>
+<li>é¸å<uicontrol>åå</uicontrol>å¯ååå²ååï¼ä½¿ä¹å¯ä¾ä½¿ç¨ã</li>
+<li>é¸å<uicontrol>åæ¶åå</uicontrol>å¯åæ¶ååä½ç¨ä¸çå²ååã</li>
+<li>é¸å<uicontrol>åæ¶å®ç¾©</uicontrol>å¯ç§»é¤é使ç¨ä¸çå²ååã</li>
+</ul></p>
+<p>è¥è¦é¡¯ç¤ºå²ååçå²åç£åè©³ç´°è³æï¼è«æä¸ä¸å²åååå³å´çç®é ãè©³ç´°è³æå
æ¬ä¸ååé
ï¼<dl><dlentry>
+<dt>é¡å</dt>
+<dd>ç£åçé¡åï¼ä¾å¦ï¼<uicontrol>æªæ¡</uicontrol>ã</dd>
+</dlentry><dlentry>
+<dt>æ ¼å¼</dt>
+<dd>æ ¼å¼ï¼å é¡åèç°ã</dd>
+</dlentry><dlentry>
+<dt>容é</dt>
+<dd>å²åç£åç大å°ã</dd>
+</dlentry><dlentry>
+<dt>é
ç½®</dt>
+<dd>å²ååä¸å·²é
ç½®çç©ºéæ¸éã</dd>
+</dlentry></dl>è¥è¦å®ç¾©å²ååï¼è«æä¸ä¸é¡¯ç¤ºç«é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="zh-tw">
+<title>å®ç¾©å²åå</title>
+<shortdesc> å®ç¾©å²ååã</shortdesc>
+<csbody>
+<p> <ol>
+<li>å¨<uicontrol>å²ååå稱</uicontrol>æ¬ä½ä¸ï¼è¼¸å
¥ç¨ä¾èå¥å²ååçå稱ã</li>
+<li>å¨<uicontrol>å²ååé¡å</uicontrol>æ¸
å®ä¸ï¼é¸åé¡åï¼<dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>æå®ç®éå²ååãç¶é¸å <uicontrol>DIR</uicontrol> æï¼è«è¼¸å
¥<uicontrol>å²åé«è·¯å¾</uicontrol>ï¼å²ååçè·¯å¾ï¼ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>æå®ç¶²è·¯æªæ¡ç³»çµ±å²ååãç¶é¸å <uicontrol>NFS</uicontrol> æï¼è«è¼¸å
¥
+<uicontrol>NFS 伺æå¨ IP</uicontrol> ä½åå <uicontrol>NFS
+è·¯å¾</uicontrol>ï¼å¯åºçç®éçè·¯å¾ï¼ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>æ ¹æå iSCSI 伺æå¨ä¸é
ç½®çç®æ¨ï¼æå®å²ååãç¶é¸å
+<uicontrol>iSCSI</uicontrol> æï¼è«è¼¸å
¥ <uicontrol>iSCSI
+伺æå¨</uicontrol> IP ä½åå iSCSI 伺æå¨ä¸ç<uicontrol>ç®æ¨</uicontrol>ãæ¨å¯ä»¥é¸ææ§å°é¸åæ°å¢ iSCSI éå¥ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>é輯</uicontrol></dt>
+<dd>æå®é輯ç£åå²ååãå¨<uicontrol>è£ç½®è·¯å¾</uicontrol>ä¸é¸æè£ç½®çä½ç½®ã</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI å
çºéé</uicontrol></dt>
+<dd>æ ¹æ SCSI å
çºééæå®å²ååãé¸åè¦ä½¿ç¨ç SCSI é
æ¥å¡ã</dd>
+</dlentry></dl></li>
+<li>æä¸ä¸<uicontrol>建ç«</uicontrol>ã</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
new file mode 100644
index 0000000..4b3a6a6
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="zh-tw">
+<title>ç¯æ¬</title>
+<shortdesc>ã<wintitle>ç¯æ¬</wintitle>ãé é¢æé¡¯ç¤ºå¯ç¨ä¾å»ºç«
+KVM 客é«çå·²å®ç¾©èæ¬æ©å¨ç¯æ¬ã</shortdesc>
+<csbody>
+<p>å°æ¼æ¯ä¸åç¯æ¬ï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>使¥ç³»çµ±çå稱æç¼è¡å¥ä»¶çå稱ã</dd>
+</dlentry><dlentry>
+<dt>çæ¬</dt>
+<dd>使¥ç³»çµ±ççæ¬æç¼è¡å¥ä»¶ççæ¬ã</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>çºç¯æ¬å®ç¾©çèç卿¸ç®ã</dd>
+</dlentry><dlentry>
+<dt>è¨æ¶é«</dt>
+<dd>è¦é
ç½®ç鍿©ååè¨æ¶é«æ¸é (MB)ã</dd>
+</dlentry></dl></p>
+<p>å¯éå°æ¯ä¸åç¯æ¬é¸åä¸ååä½ï¼<ul>
+<li>é¸å<uicontrol>編輯</uicontrol>å¯ç·¨è¼¯ç¯æ¬ã</li>
+<li>é¸å<uicontrol>åªé¤</uicontrol>å¯åªé¤ç¯æ¬ã</li>
+</ul>è¥è¦å»ºç«ç¯æ¬ï¼è«æä¸ä¸é¡¯ç¤ºç«é¢å³ä¸æ¹ç<uicontrol>å è (+)</uicontrol> å示ã</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="zh-tw">
+<title>ç·¨è¼¯ç¯æ¬</title>
+<shortdesc>ç·¨è¼¯ç¾æç¯æ¬ã</shortdesc>
+<csbody>
+<p>å°æ¼æ¯ä¸åç¯æ¬ï¼å°æé¡¯ç¤ºä¸åè³è¨ï¼<dl>
+<dlentry>
+<dt>å稱</dt>
+<dd>ç¯æ¬çå稱ã</dd>
+</dlentry><dlentry>
+<dt>便å</dt>
+<dd>建ç«é
ç½®çµ¦ç¯æ¬ä½¿ç¨ä¹ä½æ¥ç³»çµ±æç¼è¡å¥ä»¶çå
¬å¸çå稱ã</dd>
+</dlentry><dlentry>
+<dt>çæ¬</dt>
+<dd>é
ç½®çµ¦ç¯æ¬ä½¿ç¨ä¹ä½æ¥ç³»çµ±æç¼è¡å¥ä»¶ççæ¬ã</dd>
+</dlentry><dlentry>
+<dt>CPU æ¸ç®</dt>
+<dd>çºç¯æ¬å®ç¾©çèç卿¸ç®ã</dd>
+</dlentry><dlentry>
+<dt>è¨æ¶é«</dt>
+<dd>è¦é
ç½®çµ¦èæ¬æ©å¨çè¨æ¶é«æ¸é (MB)ã</dd>
+</dlentry><dlentry>
+<dt>ç£ç¢</dt>
+<dd>ç£ç¢å¤§å° (GB)ã</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>ç¨ä¾å®è£ KVM 客é«ä¹ ISO æªæ¡ä½ç½®çæªæ¡è·¯å¾ã</dd>
+</dlentry><dlentry>
+<dt>å²åå</dt>
+<dd>ç¹å®å²ååæé è¨å²ååã</dd>
+</dlentry><dlentry>
+<dt>網路</dt>
+<dd>KVM 客é«å¯ä½¿ç¨çé è¨ç¶²è·¯ä»é¢ãæ¨å¯ä»¥é¸åå¤å網路ã</dd>
+</dlentry></dl> å¯ä»¥ç·¨è¼¯æªåç¨çæ¬ä½ã編輯æ¬ä½ä¹å¾ï¼æä¸ä¸<uicontrol>å²å</uicontrol>ã</p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>æ°å¢ç¯æ¬</title>
+<shortdesc>å¾ä¾æºåªé«ä¸æ°å¢ç¯æ¬ãæ¨å¯ä»¥å°èªå·±ç ISO æ åæªæ°å¢è³ 'ISO' å²ååï¼ä»¥é²è¡ä¸åæ¢ç´¢ã</shortdesc>
+<csbody>
+<p>å¾ä¸åé¸é
ä¸é¸å便ºåªé«çä½ç½®ï¼<dl>
+<dlentry>
+<dt>æ¬ç«¯ ISO æ åæª</dt>
+<dd>é¸åæ¤é
坿æå²åå以åå¾ç³»çµ±ä¸å¯ç¨çå®è£ ISO æ åæªã</dd>
+</dlentry><dlentry>
+<dt>é 端 ISO æ åæª</dt>
+<dd>é¸åæ¤é
坿å®å®è£ ISO æ åæªçé 端ä½ç½®ã</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>æ°å¢ç¯æ¬ - æ¬ç«¯ ISO æ åæª</title>
+<shortdesc>徿¬ç«¯ ISO æ åæªæ°å¢ç¯æ¬ã</shortdesc>
+<csbody>
+<p>å°æé¡¯ç¤ºç³»çµ±ä¸å¯ç¨ç ISO æ åæªã<dl><dlentry>
+<dt>OS</dt>
+<dd>使¥ç³»çµ±çå稱æç¼è¡å¥ä»¶çå稱ã</dd>
+</dlentry><dlentry>
+<dt>çæ¬</dt>
+<dd>使¥ç³»çµ±ççæ¬æç¼è¡å¥ä»¶ççæ¬ã</dd>
+</dlentry><dlentry>
+<dt>大å°</dt>
+<dd>ISO æ åæªç大å°ã</dd>
+</dlentry></dl></p>
+<p>è¥è¦å¾ ISO æ åæªå»ºç«ç¯æ¬ï¼è«å¾ä¸åé¸é
ä¸é¸æï¼<ul>
+<li>é¸åè¦ç¨ä¾å»ºç«ç¯æ¬ç ISO æ åæªï¼ç¶å¾æä¸ä¸<uicontrol>å¾æé¸ ISO 建ç«ç¯æ¬</uicontrol>ã</li>
+<li>é¸å<uicontrol>å
¨é¨</uicontrol>以徿¯ä¸åååºç ISO æ åæªå»ºç«ç¯æ¬ï¼ç¶å¾æä¸ä¸<uicontrol>å¾æé¸ ISO 建ç«ç¯æ¬</uicontrol>ã</li>
+<li>å¦è¦è¦ä½¿ç¨ç ISO æ åæªæªåºç¾å¨ææçµæä¸ï¼åå¯ä»¥å¾ä¸åé¸é
ä¸é¸æï¼<ul>
+<li>é¸å<uicontrol>ææ³ä½¿ç¨ç¹å®ç ISO æªæ¡</uicontrol>以æå® ISO æ åæªçè·¯å¾ã</li>
+<li>æä¸ä¸<uicontrol>æå°æ´å¤ ISO</uicontrol> 以æå°æ´å¤ ISO æ åæªã</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/host.html.tmpl b/src/wok/plugins/kimchi/ui/pages/host.html.tmpl
new file mode 100644
index 0000000..d87debc
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/host.html.tmpl
@@ -0,0 +1,177 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div id="host-root-container">
+ <div class="toolbar">
+ <div class="tools">
+ </div>
+ </div>
+ <div id="host-content-container" class="empty-when-logged-off"></div>
+</div>
+
+<script id="host-tmpl" type="kimchi/template">
+ <div class="host-panel">
+ <div class="logo-container">
+ <div class="logo" style="background-image: url({logo});"></div>
+ </div>
+ <div id="host-info-container" class="info-container">
+ <h2 class="hostname">{hostname}</h2>
+ <div class="action-panel">
+ <button id="host-button-shutdown" class="btn-normal-1 stop">
+ <div class="button-icon action-icon-stop"></div>
+ $_("Shut down")
+ </button>
+ <button id="host-button-restart" class="btn-normal-1 restart">
+ <div class="button-icon action-icon-restart"></div>
+ $_("Restart")
+ </button>
+ <button class="btn-normal-1 connect" disabled="disabled">
+ <div class="button-icon action-icon-connect"></div>
+ $_("Connect")
+ </button>
+ </div>
+ <div class="host-section">
+ <h3 class="section-header"
+ aria-expanded="false"
+ aria-controls="content-sys-info">
+ $_("Basic Information")
+ </h3>
+ <div id="content-sys-info" class="section-content">
+ <div class="section-row">
+ <div class="section-label">$_("OS Distro")</div>
+ <div class="section-value">{os_distro}</div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("OS Version")</div>
+ <div class="section-value">{os_version}</div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("OS Code Name")</div>
+ <div class="section-value">{os_codename}</div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("Processor")</div>
+ <div class="section-value">{cpu_model}</div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("CPU(s)")</div>
+ <div class="section-value">{cpus}</div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("Memory")</div>
+ <div class="section-value">{memory}</div>
+ </div>
+ </div>
+ </div>
+ <div class="host-section">
+ <h3 class="section-header"
+ aria-controls="content-sys-statistics">
+ $_("System Statistics")
+ </h3>
+ <div id="content-sys-statistics" class="section-content">
+ <div class="section-row">
+ <div class="section-label">$_("CPU")</div>
+ <div class="section-value">
+ <div id="container-chart-cpu" class="inline-block"></div>
+ </div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("Memory")</div>
+ <div class="section-value">
+ <div id="container-chart-memory" class="inline-block"></div>
+ </div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("Disk I/O")</div>
+ <div class="section-value">
+ <div id="container-chart-disk-io" class="inline-block"></div>
+ </div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("Network I/O")</div>
+ <div class="section-value">
+ <div id="container-chart-network-io" class="inline-block"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="software-update-section" class="host-section hidden">
+ <h3 class="section-header"
+ aria-controls="content-software-update">
+ $_("Software Updates")
+ </h3>
+ <div id="content-software-update" class="section-content">
+ <div class="section-row">
+ <div class="section-value">
+ <div id="software-updates-grid-container"></div>
+ <div id="software-updates-progress-container" class="hidden">
+ <label for="software-updates-progress-textarea">$_("Update Progress")</label>
+ <textarea id="software-updates-progress-textarea" readonly></textarea>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="repositories-section" class="host-section hidden">
+ <h3 class="section-header"
+ aria-controls="content-repositories">
+ $_("Repositories")
+ </h3>
+ <div id="content-repositories" class="section-content">
+ <div class="section-row">
+ <div class="section-value">
+ <div id="repositories-grid-container"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="debug-report-section" class="host-section hidden">
+ <h3 class="section-header"
+ aria-controls="content-sys-reports">
+ $_("Debug Reports")
+ </h3>
+ <div id="content-sys-reports" class="section-content">
+ <div class="section-row">
+ <div class="section-value">
+ <div id="available-reports-grid-container"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</script>
+
+<script type="text/javascript">
+ kimchi.host_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl b/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl
new file mode 100644
index 0000000..cd320e0
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl
@@ -0,0 +1,187 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+{
+ "KCHAUTH6001E": "$_("The username or password you entered is incorrect. Please try again.")",
+ "KCHAUTH6002E": "$_("This field is required.")",
+
+ "KCHAUTH6001M": "$_("Log in")",
+ "KCHAUTH6002M": "$_("Logging in...")",
+
+ "Host": "$_("Host")",
+ "Guests": "$_("Guests")",
+ "Templates": "$_("Templates")",
+ "Storage": "$_("Storage")",
+ "Network": "$_("Network")",
+
+ "KCHAPI6002E": "$_("Failed to get application configuration")",
+ "KCHAPI6003E": "$_("This is not a valid Linux path")",
+ "KCHAPI6004E": "$_("This is not a valid URL.")",
+ "KCHAPI6005E": "$_("No such data available.")",
+ "KCHAPI6007E": "$_("Can not contact the host system. Verify the host system is up and that you have network connectivity to it. HTTP request response %1. ")",
+ "KCHAPI6008E": "$_("Unable to read file.")",
+ "KCHAPI6009E": "$_("Error while uploading file.")",
+
+ "KCHAPI6001M": "$_("Delete Confirmation")",
+ "KCHAPI6002M": "$_("OK")",
+ "KCHAPI6003M": "$_("Cancel")",
+ "KCHAPI6004M": "$_("Confirm")",
+ "KCHAPI6005M": "$_("Create")",
+ "KCHAPI6006M": "$_("Warning")",
+ "KCHAPI6007M": "$_("Save")",
+ "KCHAPI6008M": "$_("Creating...")",
+ "KCHAPI6009M": "$_("Cloning...")",
+
+ "KCHGRD6001M": "$_("Loading...")",
+ "KCHGRD6002M": "$_("An error occurred while retrieving system information.")",
+ "KCHGRD6003M": "$_("Retry")",
+ "KCHGRD6004M": "$_("Detailed message:")",
+
+ "KCHTMPL6001W": "$_("No ISO found")",
+
+ "KCHTMPL6002E": "$_("This is not a valid ISO file.")",
+
+ "KCHTMPL6002M": "$_("This may take a long time. Do you want to continue?")",
+ "KCHTMPL6003M": "$_("This will permanently delete the template. Would you like to continue?")",
+
+ "KCHHOST6001E": "$_("Unable to shut down system as there are some virtual machines running!")",
+
+ "KCHHOST6001M": "$_("Max:")",
+ "KCHHOST6002M": "$_("Utilization")",
+ "KCHHOST6003M": "$_("Available")",
+ "KCHHOST6004M": "$_("Read Rate")",
+ "KCHHOST6005M": "$_("Write Rate")",
+ "KCHHOST6006M": "$_("Received")",
+ "KCHHOST6007M": "$_("Sent")",
+ "KCHHOST6008M": "$_("Shutting down or restarting host will cause unsaved work lost. Continue to shut down/restarting?")",
+
+
+ "KCHREPO6001M": "$_("Confirm")",
+ "KCHREPO6002M": "$_("Repository will be removed permanently and can't be recovered. Do you want to continue?")",
+ "KCHREPO6003M": "$_("Repositories")",
+ "KCHREPO6004M": "$_("ID")",
+ "KCHREPO6005M": "$_("Name")",
+ "KCHREPO6006M": "$_("Base URL")",
+ "KCHREPO6007M": "$_("Is Mirror")",
+ "KCHREPO6008M": "$_("URL Args")",
+ "KCHREPO6009M": "$_("Enabled")",
+ "KCHREPO6010M": "$_("GPG Check")",
+ "KCHREPO6011M": "$_("GPG Key")",
+ "KCHREPO6012M": "$_("Add")",
+ "KCHREPO6013M": "$_("Edit")",
+ "KCHREPO6014M": "$_("Remove")",
+ "KCHREPO6016M": "$_("Enable")",
+ "KCHREPO6017M": "$_("Disable")",
+
+
+ "KCHUPD6001M": "$_("Software Updates")",
+ "KCHUPD6002M": "$_("Package Name")",
+ "KCHUPD6003M": "$_("Version")",
+ "KCHUPD6004M": "$_("Architecture")",
+ "KCHUPD6005M": "$_("Repository")",
+ "KCHUPD6006M": "$_("Update All")",
+ "KCHUPD6007M": "$_("Updating...")",
+ "KCHUPD6008M": "$_("Failed to retrieve packages update information.")",
+ "KCHUPD6009M": "$_("Failed to update package(s).")",
+
+
+ "KCHDR6001M": "$_("Debug report will be removed permanently and can't be recovered. Do you want to continue?")",
+ "KCHDR6002M": "$_("Debug Reports")",
+ "KCHDR6003M": "$_("Name")",
+ "KCHDR6005M": "$_("Generated Time")",
+ "KCHDR6006M": "$_("Generate")",
+ "KCHDR6007M": "$_("Generating...")",
+ "KCHDR6008M": "$_("Rename")",
+ "KCHDR6009M": "$_("Remove")",
+ "KCHDR6010M": "$_("Download")",
+ "KCHDR6011M": "$_("Report name should contain only letters, digits, underscore ('_') and/or hyphen ('-').")",
+ "KCHDR6012M": "$_("Pending...")",
+ "KCHDR6013M": "$_("Report name is the same as the original one.")",
+
+ "KCHVM6001M": "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")",
+ "KCHVM6002M": "$_("Power off Confirmation")",
+ "KCHVM6003M": "$_("This action may produce undesirable results, "
+ "for example unflushed disk cache in the guest. "
+ "Would you like to continue?")",
+ "KCHVM6004M": "$_("Reset Confirmation")",
+ "KCHVM6005M": "$_("There is a risk of data loss caused by reset without"
+ " the guest OS shutdown. Would you like to continue?")",
+ "KCHVM6006M": "$_("Shut Down Confirmation")",
+ "KCHVM6007M": "$_("Note the guest OS may ignore this request. Would you like to continue?")",
+ "KCHVM6008M": "$_("Virtual Machine delete Confirmation")",
+ "KCHVM6009M": "$_("This virtual machine is not persistent. Power Off will delete it. Continue?")",
+ "KCHVM6010M": "$_("When the target guest has SCSI or iSCSI volumes, they will be cloned on default storage pool. The same will happen when the target pool does not have enough space to clone the volumes. Do you want to continue?")",
+
+ "KCHVMCD6001M": "$_("This CDROM will be detached permanently and you can re-attach it. Continue to detach it?")",
+ "KCHVMCD6002M": "$_("Attach")",
+ "KCHVMCD6003M": "$_("Attaching...")",
+ "KCHVMCD6004M": "$_("Replace")",
+ "KCHVMCD6005M": "$_("Replacing...")",
+ "KCHVMCD6006M": "$_("Successfully attached!")",
+ "KCHVMCD6007M": "$_("Successfully replaced!")",
+ "KCHVMCD6008M": "$_("Successfully detached!")",
+ "KCHVMCD6009M": "$_("This disk will be detached permanently and you can re-attach it. Continue to detach it?")",
+
+ "KCHVMED6001M": "$_("interface:")",
+ "KCHVMED6002M": "$_("address:")",
+ "KCHVMED6003M": "$_("link_type:")",
+ "KCHVMED6004M": "$_("block:")",
+ "KCHVMED6005M": "$_("drive_type:")",
+ "KCHVMED6006M": "$_("model:")",
+ "KCHVMED6007M": "$_("Affected devices:")",
+
+ "KCHNET6001E": "$_("The VLAN id must be between 1 and 4094.")",
+
+ "KCHNET6001M": "$_("unavailable")",
+ "KCHNET6002M": "$_("This action will interrupt network connectivity for any virtual machine that depend on this network.")",
+ "KCHNET6003M": "$_("Create a network")",
+ "KCHNET6004M": "$_("This network is not persistent. Instead of stop, this action will permanently delete it. Would you like to continue?")",
+ "KCHNET6001W": "$_("The bridged VLAN tag may not work well with NetworkManager enabled. You should consider disabling it.")",
+
+ "KCHPOOL6001M": "$_("This will permanently delete the storage pool. Would you like to continue?")",
+ "KCHPOOL6002M": "$_("This storage pool is empty.")",
+ "KCHPOOL6003M": "$_("It will format your disk and you will loose any data in there, are you sure to continue? ")",
+ "KCHPOOL6004M": "$_("SCSI Fibre Channel")",
+ "KCHPOOL6005M": "$_("No SCSI adapters found.")",
+ "KCHPOOL6006M": "$_("Loading iSCSI targets...")",
+ "KCHPOOL6007M": "$_("No iSCSI found. Please input one.")",
+ "KCHPOOL6008M": "$_("Failed to load iSCSI targets.")",
+
+ "KCHPOOL6001E": "$_("The storage pool name can not be blank.")",
+ "KCHPOOL6002E": "$_("The storage pool path can not be blank.")",
+ "KCHPOOL6003E": "$_("NFS server mount path can not be blank.")",
+ "KCHPOOL6005E": "$_("Invalid NFS mount path.")",
+ "KCHPOOL6006E": "$_("No logical device selected.")",
+ "KCHPOOL6007E": "$_("The iSCSI target can not be blank.")",
+ "KCHPOOL6008E": "$_("Server name can not be blank.")",
+ "KCHPOOL6009E": "$_("This is not a valid Server Name or IP. Please, modify it.")",
+ "KCHPOOL6010M": "$_("Looking for available partitions ...")",
+ "KCHPOOL6011M": "$_("No available partitions found.")",
+ "KCHPOOL6012M": "$_("This storage pool is not persistent. Instead of deactivate, this action will permanently delete it. Would you like to continue?")",
+ "KCHPOOL6013M": "$_("Unable to retrieve partitions information.")",
+ "KCHPOOL6014M": "$_("In progress...")",
+ "KCHPOOL6015M": "$_("Failed!")",
+
+ "KCHVMSTOR0001E": "$_("CDROM path needs to be a valid local/remote path and cannot be blank.")",
+ "KCHVMSTOR0002E": "$_("Disk pool or volume cannot be blank.")"
+}
diff --git a/src/wok/plugins/kimchi/ui/pages/network.html.tmpl b/src/wok/plugins/kimchi/ui/pages/network.html.tmpl
new file mode 100644
index 0000000..915feac
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/network.html.tmpl
@@ -0,0 +1,133 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="networkAdd" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
+ </div>
+</div>
+<div id="network-content" class="network">
+ <div class="grid-control"><input type="text" class="filter" placeholder="$_("Filter")"></div>
+ <div id="networkGrid" class="list">
+ <div>
+ <span class="column-name">$_("Network Name")</span><!--
+ --><span class="column-state">$_("State")</span><!--
+ --><span class="column-type">$_("Network Type")</span><!--
+ --><span class="column-interface">$_("Interface")</span><!--
+ --><span class="column-space">$_("Address Space")</span><!--
+ --><span style="display:none">$_("Actions")</span>
+ </div>
+ <div id="networkBody" class="empty-when-logged-off"></div>
+ </div>
+ <div id="networkConfig" class="network-config">
+ <div class="section-container">
+ <div class="section-header">1. $_("Network Name")</div>
+ <div class="section-content">
+ <input type="text" id="networkName" />
+ <div class="input-hint">
+ <span class="icon-info-circled light-grey c1 help-inline"></span>
+ <span class="input-hint-text help-inline">$_("Name should not contain '/' and '\"'.")</span>
+ </div>
+ </div>
+ </div>
+ <div class="section-container">
+ <div class="section-header">2. $_("Network Type")</div>
+ <div class="section-content">
+ <div class="input-container">
+ <input type="radio" id="networkTypeIso" name="networkType" value="isolated" />
+ <label for="networkTypeIso">$_("Isolated: no external network connection")</label>
+ </div>
+ <div class="input-container">
+ <input type="radio" id="networkTypeNat" name="networkType" value="nat" />
+ <label for="networkTypeNat">$_("NAT: outbound physical network connection only")</label>
+ </div>
+ <div class="input-container">
+ <div class="bridged-inline">
+ <input type="radio" id="networkTypeBri" name="networkType" value="bridged" />
+ </div>
+ <div class="bridged-inline">
+ <label for="networkTypeBri">$_("Bridged: Virtual machines are connected to physical network directly")</label><br />
+ <label id="networkBriDisabledLabel" style="display:none">$_("(No interfaces found)")</label>
+ </div>
+ </div>
+ <div id="bridgeOptions">
+ <div>
+ <div class="bridge-option-column">
+ <label for="networkInterface">$_("Destination"): </label>
+ </div>
+ <div class="bridge-option-column">
+ <div class="network-type-wrapper-controls">
+ <div id ="networkDestinationID">
+ <input id="networkDestinationInputId" name="type" type="hidden"/>
+ <span id="networkDestinationLabel" type="text"></span><span class="arrow"></span>
+ <div>
+ <ul id="networkInterface"></ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div>
+ <input id="enableVlan" type="checkbox" value="" />
+ <label for="enableVlan" id="labelEnableVlan">$_("Enable VLAN") </label>
+ </div>
+ <label for="networkVlanID" id="labelNetworkVlanID">$_("VLAN ID"): </label>
+ <input type="text" id="networkVlanID" class="network-label"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+<script id="networkItem" type="text/html">
+ <div id='{name}' class='remove-when-logged-off'>
+ <span class='column-name' title="{name}" val="{name}">{name}</span><!--
+ --><span class='column-state' val="{state}"><span class='network-state {state}'></span></span><!--
+ --><span class='column-type' val="{type}">{type}</span><!--
+ --><span class='column-interface' val="{interface}">{interface}</span><!--
+ --><span class='column-space' val="{addrSpace}">{addrSpace}</span><!--
+ --><span class='column-action' style="display:none">
+ <span class="ui-button-secondary dropdown popable action-button">
+ $_("Actions")
+ <ul class='popover actionsheet right-side menu-container'>
+ <li nwAct="start" class='{startClass}'><a class='button-big'>$_("Start")</a></li>
+ <li nwAct="stop" class='{stopClass}'><a {stopDisabled} class='button-big'>$_("Stop")</a></li>
+ <li nwAct="delete" class='{deleteClass}'><a {deleteDisabled} class='red'>$_("Delete")</a></li>
+ </ul>
+ </span>
+ </span>
+ </div>
+</script>
+<script>
+ kimchi.initNetwork();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl
new file mode 100644
index 0000000..25bf0a9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl
@@ -0,0 +1,56 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<div id="report-add-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Generate a New Debug Report")</h1>
+ </header>
+ <div class="content">
+ <form id="form-report-add">
+ <section class="form-section">
+ <h2>
+ <label for="report-name-textbox">$_("Report Name")</label>
+ </h2>
+ <div class="field">
+ <input type="text" class="text" id="report-name-textbox" name="name" />
+ <span class="icon-info-circled light-grey c1"></span>
+ <span class="info-add-debug-report">
+ $_("The name used to identify the report. If omitted, a name will be chosen based on current time. Name can contain: letters, digits, underscore (\"_\") and hyphen (\"-\").")
+ </span>
+ </div>
+ </section>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="button-report-add" class="btn-normal"><span class="text">$_("Generate")</span></button>
+ <button id="button-report-cancel" class="btn-normal close" type="button">
+ <span calss="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.report_add_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl b/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl
new file mode 100644
index 0000000..90a0a80
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl
@@ -0,0 +1,56 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<div id="report-rename-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Rename a Debug Report")</h1>
+ </header>
+ <div class="content">
+ <form id="form-report-rename">
+ <section class="form-section">
+ <h2>
+ <label for="report-name-textbox">$_("Report Name")</label>
+ </h2>
+ <div class="field">
+ <input type="text" class="text" id="report-name-textbox" name="name" />
+ <span class="icon-info-circled light-grey c1"></span>
+ <span class="info-debug-report-rename">
+ $_("The name used to identify the report. Name can contain: letters, digits and hyphen (\"-\").")
+ </span>
+ </div>
+ </section>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="button-report-rename" class="btn-normal"><span class="text">$_("Submit")</span></button>
+ <button id-"button-report-rename-cancel" class="btn-normal close" type="button">
+ <span class="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.report_rename_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl
new file mode 100644
index 0000000..950252a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl
@@ -0,0 +1,113 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<div id="repository-add-window" class="window">
+ <form id="form-repository-add">
+ <header class="window-header">
+ <h1 class="title h1 grey">$_("Add a Repository")</h1>
+ </header>
+ <section>
+ <div class="content">
+ <div class="form-section yum">
+ <h2>$_("Identifier")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text" name="repo_id" />
+ </div>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Single word, unique identifier for the repository.")
+ </p>
+ </div>
+ </div>
+ <section class="form-section yum">
+ <h2>$_("Name")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text" name="config[repo_name]" />
+ </div>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Textual name for the repository.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>$_("URL")<span class="required" role="presentation" title='$_("Required Field")'>*</span></h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text required" name="baseurl" />
+ </div>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("URL to the repository. Supported protocols are http, ftp, and file.")
+ </p>
+ </div>
+ <div class="field yum">
+ <p class="yum">
+ <input type="checkbox" name="isMirror" value="true" id="isMirror" />
+ <label id="isMirrorLabel" for="isMirror">$_("Repository is a mirror")</label>
+ </p>
+ </div>
+ </section>
+ <section class="form-section repository-dist deb">
+ <h2>$_("Distribution")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text" name="config[dist]" />
+ </div>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Distribution of the DEB repository.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section repository-comps deb">
+ <h2>$_("Components")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text" name="config[comps]" />
+ </div>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("List of components in DEB repository.")
+ </p>
+ </div>
+ </section>
+ </div>
+ </section>
+ <footer>
+ <div class="btn-group">
+ <button type="submit" id="button-repository-add" class="btn-normal" disabled="disabled">
+ <span class="text">$_("Add")</span>
+ </button>
+ <button type="button" id="button-repository-close" class="btn-normal close">
+ <span class="text">$("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+ </form>
+</div>
+<script>
+ kimchi.repository_add_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl b/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl
new file mode 100644
index 0000000..e5a3cfb
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl
@@ -0,0 +1,117 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+<div id="repository-edit-window" class="window">
+ <form id="form-repository-edit">
+ <header>
+ <h1 class="title h1 grey">$_("Edit Repository")</h1>
+ </header>
+ <div class="content">
+ <section id="form-repository-edit">
+ <fieldset class="repository-edit-fieldset">
+ <div class="repository-id yum">
+ <div class="repository-edit-wrapper-label">
+ <label for="repository-edit-id-textbox">$_("ID")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-id-textbox" name="repo_id" type="text" disabled="disabled" readonly="readonly"/>
+ </div>
+ </div>
+ <div class="repository-name yum">
+ <div class="repository-edit-wrapper-label">
+ <label for="repository-edit-name-textbox">$_("Name")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-name-textbox" class="yum" name="config[repo_name]" type="text" />
+ </div>
+ </div>
+ <div class="repository-url">
+ <div class="repository-edit-wrapper-label">
+ <label for="repository-edit-baseurl-textbox">$_("URL")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-baseurl-textbox" name="baseurl" type="text" />
+ </div>
+ </div>
+ <div class="repository-dist deb">
+ <div class="repository-edit-wrapper-label">
+ <label for="repository-edit-urlargs-textbox">$_("Distribution")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-urlargs-textbox" class="deb" name="config[dist]" type="text" />
+ </div>
+ </div>
+ <div class="repository-mirrorlist yum">
+ <div class="repository-edit-wrapper-label">
+ <label for="repository-edit-urlargs-textbox">$_("Mirror List URL")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-urlargs-textbox" class="yum" name="config[mirrorlist]" type="text" />
+ </div>
+ </div>
+ <div class="repository-comps deb">
+ <div class="repository-edit-wrapper-label">
+ <label for="repository-edit-urlargs-textbox">$_("Components")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-urlargs-textbox" class="deb" name="config[comps]" type="text" />
+ </div>
+ </div>
+ <div class="repository-gpgkey yum">
+ <div class="repository-edit-wrapper-label">
+ <label for="repository-edit-gpgkey-textbox">$_("GPG Key")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-gpgkey-textbox" class="yum" name="config[gpgkey]" type="text" />
+ </div>
+ </div>
+ <div class="repository-gpgcheck yum">
+ <div class="repository-edit-wrapper-label">
+ <label>$_("GPG Check")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-gpgcheck-radio-true" class="yum" name="config[gpgcheck]" type="radio" value="true" />
+ <label for="repository-edit-gpgcheck-radio-true">$_("Yes")</label>
+ <input id="repository-edit-gpgcheck-radio-false" class="yum" name="config[gpgcheck]" type="radio" value="false" />
+ <label for="repository-edit-gpgcheck-radio-false">$_("No")</label>
+ </div>
+ </div>
+ </fieldset>
+ </section>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button type="submit" id="repository-edit-button-save" class="btn-normal">
+ <span class="text">$_("Save")</span>
+ </button>
+ <button type="button" id="repository-edit-button-cancel" class="close btn-normal">
+ <span class="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+ </form>
+</div>
+<script type="text/javascript">
+ kimchi.repository_edit_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/storage.html.tmpl b/src/wok/plugins/kimchi/ui/pages/storage.html.tmpl
new file mode 100644
index 0000000..7b51a8b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/storage.html.tmpl
@@ -0,0 +1,143 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="storage-pool-add" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
+ </div>
+</div>
+<div class='storage'>
+<div class="grid-control"><input type="text" class="filter" placeholder="$_("Filter")"></div>
+<div id='storageGrid'>
+ <div>
+ <span class="storage-name">$_("Name")</span>
+ <span class="storage-state" >$_("State")</span>
+ <span class="storage-type">$_("Type")</span>
+ <span class="storage-capacity">$_("Capacity")</span>
+ <span class="storage-allocate">$_("Allocated")</span>
+ <span class="storage-location">$_("Location")</span>
+ </div>
+ <div id="storagepoolsList" class="list-storage empty-when-logged-off"></div>
+</div>
+</div>
+<div id="logicalPoolExtend" title="$_("Device path")">
+ <p id="loading-info" class="text-help">
+ <img src = "plugins/kimchi/images/theme-default/loading.gif" />
+ $_("Looking for available partitions ...")
+ </p>
+ <div class="host-partition">
+ </div>
+</div>
+<script id="storageTmpl" type="html/text">
+ <div id="{name}" class="storage-li in" data-name="{name}" data-stat="{state}">
+ <span class="storage-name" val="{name}{usage}%">
+ <span title="{name}">{name}</span>
+ <span class="usage">{usage}%</span>
+ </span>
+ <span class="storage-state">
+ <div class="status-dot toolable active" data-state="{state}">
+ <label class="tooltip">$_("active")</label>
+ </div>
+ <div class="status-dot toolable inactive" data-state="{state}">
+ <label class="tooltip">$_("inactive")</label>
+ </div>
+ </span>
+ <span class="storage-type" val="{type}">
+ <div>{type}</div>
+ </span>
+ <span class="storage-capacity" val="{capacity}">
+ <div data-type="{type}">{capacity}</div>
+ </span>
+ <span class="storage-allocate" val="{allocated}">
+ <div data-type="{type}">{allocated}</div>
+ </span>
+ <span class="storage-location" val="{path}">
+ <div>{path}</div>
+ </span>
+ <span class="bottom storage-button" style="display:none">
+ <div class="btn dropdown popable storage-action" data-state="{state}" data-type="{type}" data-name="{name}">
+ <span class="text">$_("Actions")</span><span class="arrow"></span>
+ <div class="popover actionsheet right-side" style="width: 250px">
+ <button class="button-big pool-deactivate" data-stat="{state}" data-name="{name}" data-persistent="{persistent}"><span class="text">$_("Deactivate")</span></button>
+ <button class="button-big pool-activate" data-stat="{state}" data-name="{name}"><span class="text">$_("Activate")</span></button>
+ <button class="button-big pool-add-volume" data-stat="{state}" data-name="{name}" data-type="{type}"><span class="text">$_("Add Volume")</span></button>
+ <button class="button-big pool-extend {enableExt}" data-stat="{state}" data-name="{name}"><span class="text">$_("Extend")</span></button>
+ <button class="button-big red pool-delete" data-stat="{state}" data-name="{name}"><span class="text">$_("Undefine")</span></button>
+ </div>
+ </div>
+ </span>
+ <span class="handle">
+ <div class="arrow-down"></div>
+ </span>
+ <div class="volumes">
+ <div id="volume{name}" class="volumeslist" data-name="{name}" ></div>
+ <div class="clear"></div>
+ </div>
+ </div>
+</script>
+<script id="volumeTmpl" type="html/text">
+ <div class="volume-box white-box" data-volume-name="{name}">
+ <div class="storage-icon volume-default icon-{format} ">
+ </div>
+ <div class="volume-title">
+ <div class="volume-name" title="{name}">{name}</div>
+ <div class="volume-progress hidden">
+ <div class="progress-bar-outer">
+ <div class="progress-bar-inner"></div>
+ </div>
+ <div class="progress-label">
+ <span class="progress-status"></span>
+ <span class="progress-transferred"></span>
+ </div>
+ </div>
+ </div>
+ <div class="volume-setting">
+ </div>
+ <div class="volume-type-position">
+ <div title="{type}" class="volume-text">$_("Type"): {type}</div>
+ <div title="{format}" class="volume-text">$_("Format"): {format}</div>
+ </div>
+ <div class="volume-quota-position">
+ <div title="{capacity}" class="volume-textquota">$_("Capacity"): {capacity}</div>
+ <div title="{allocation}"class="volume-textquota">$_("Allocation"): {allocation}</div>
+ </div>
+ </div>
+</script>
+<script id="logicalPoolExtendTmpl" type="html/text">
+ <div>
+ <input type="checkbox" value="{path}" name="devices">
+ <label for="{name}">{path}</label>
+ </div>
+</script>
+<script>
+ kimchi.storage_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl b/src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
new file mode 100644
index 0000000..ab10939
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
@@ -0,0 +1,79 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<div id="sp-add-volume-window" class="window">
+ <form id="form-sp-add-volume">
+ <header class="window-header">
+ <h1 class="title h1 grey">$_("Add a Volume to Storage Pool")</h1>
+ </header>
+ <section>
+ <div class="content">
+ <div class="form-section">
+ <h2>
+ <input type="radio" id="volume-type-download" class="volume-type" name="volumeType" value="download" checked="checked" />
+ <label for="volume-type-download">
+ $_("Fetch from remote URL")
+ </label>
+ </h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" id="volume-remote-url" class="text volume-input download" name="volumeRemoteURL" />
+ </div><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Enter the remote URL here.")
+ </p>
+ </div>
+ </div>
+ <div class="form-section">
+ <h2>
+ <input type="radio" id="volume-type-upload" class="volume-type" name="volumeType" value="upload"/>
+ <label for="volume-type-upload">
+ $_("Upload a file")
+ </label>
+ </h2>
+ <div class="field">
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Choose the file you want to upload.")
+ </p>
+ <div class="textbox-wrapper">
+ <input type="file" class="volume-input upload" id="volume-input-file" name="volumeLocalFile" disabled="disabled" />
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ <footer>
+ <div class="btn-group">
+ <button type="submit" id="sp-add-volume-button" class="btn-normal" disabled="disabled">
+ <span class="text">$_("Add")</span>
+ </button>
+ <button type="button" class="btn-normal close"><span class="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+ </form>
+</div>
+<script type="text/javascript">
+ kimchi.sp_add_volume_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
new file mode 100644
index 0000000..a697af5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
@@ -0,0 +1,186 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<body>
+ <div class="window storage-window storage-admin">
+ <header>
+ <h1 class="title h1 grey">$_("Define a New Storage Pool")</h1>
+ </header>
+ <div class="content">
+ <form id="form-pool-add">
+ <section class="form-section">
+ <h2>1. $_("Storage Pool Name")</h2>
+ <div class="field">
+ <input id="poolId" required="required" type="text" class="text storage-base-input-width" name="name"><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("The name used to identify the storage pools, and it should not be empty.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>2. $_("Storage Pool Type")</h2>
+ <div class="storage-type-wrapper-controls">
+ <div id="poolTypeId">
+ <input id="poolTypeInputId" name="type" type="hidden" value="dir"/>
+ <span id="pool-type-label" class="text"></span><span class="arrow"></span>
+ <div>
+ <ul id="storagePool-list">
+ </ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ <div class="path-section">
+ <section class="form-section">
+ <h2>3. $_("Storage Path")</h2>
+ <div class="field">
+ <input id="pathId" type="text" class="text storage-base-input-width"><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("The path of the Storage Pool. Each Storage Pool must have a unique path.")</p><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Kimchi will try to create the directory when it does not already exist in your system.")</p>
+ </div>
+ <div class="clear"></div>
+ </section>
+ </div>
+ <div class="nfs-section tmpl-html">
+ <section class="form-section">
+ <h2>3. $_("NFS Server IP")</h2>
+ <div class="field storage-field">
+ <div id="serverComboboxId" class="storage-add-input-width">
+ <input id="nfsserverId"/>
+ <div>
+ <ul id="nfs-server-used">
+ </ul>
+ </div>
+ </div><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("NFS server IP or hostname. It can be input or chosen from history.")</p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>4. $_("NFS Path")</h2>
+ <div class="field storage-field">
+ <div id="targetFilterSelectId" class="storage-add-input-width">
+ <input id="nfspathId" class="input" disabled/>
+ <div>
+ <ul id="nfs-server-target">
+ </ul>
+ </div>
+ </div><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">$_("The NFS exported path on NFS server.")</p>
+ </div>
+ </section>
+ </div>
+ <div class="logical-section tmpl-html">
+ <section class="form-section storageType">
+ <h2>3. $_("Device path")</h2>
+ <div class="host-partition">
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Looking for available partitions ...")
+ <img src = "plugins/kimchi/images/theme-default/loading.gif" />
+ </p>
+ </div>
+ </section>
+ </div>
+ <div class="iscsi-section tmpl-html">
+ <section class="form-section">
+ <h2>3. $_("iSCSI Server")</h2>
+ <div class="field">
+ <span class="filter-select popable" id="iSCSIServer">
+ <input id="iscsiserverId" type="text" placeholder="$_("Server")">
+ <div class="popover"><ul class="option select-list"></ul></div>
+ </span>
+ <input id="iscsiportId" placeholder="$_("Port")" type="text" class="text storage-port-width" maxlength="4"><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">
+ $_("iSCSI server IP or hostname. It should not be empty.")</p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>4. $_("Target")</h2>
+ <div class="field">
+ <span class="filter-select popable" id="iSCSITarget">
+ <input id="iscsiTargetId" type="text">
+ <div class="popover"><ul class="option select-list"></ul></div>
+ </span><br>
+ <div class="icon-info-circled light-grey c1 help-inline"></div>
+ <p class="text-help help-inline">$_("The iSCSI target on iSCSI server")</p>
+ </div>
+ </section>
+ <section class="form-section">
+ <div class="field">
+ <input type="checkbox" id="authId" name="authname">
+ <label for="authId">$_("Add iSCSI Authentication")</label>
+ </div>
+ </section>
+ <section class="authenticationfield form-section tmpl-html">
+ <h2>5. $_("iSCSI Authentication")</h2>
+ <div class="field">
+ <input id="usernameId" placeholder="$_("User Name")" type="text" class="text storage-auth-width">
+ <input id="passwordId" placeholder="$_("Password")" type="password" class="text storage-auth-width">
+ </div>
+ </section>
+ </div>
+ <div class="scsi-section tmpl-html">
+ <section class="form-section">
+ <h2>3. $_("SCSI Adapter")</h2>
+ <div class="storage-type-wrapper-controls">
+ <div id="scsiAdapter">
+ <input type="hidden"/>
+ <span class="text"></span><span class="arrow"></span>
+ <div><ul></ul></div>
+ </div>
+ </div>
+ </section>
+ </div>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="pool-doAdd" class="btn-normal">
+ <span class="text">$_("Create")</span>
+ </button>
+ <button class="btn-normal" id="pool-loading" style="display: none"><span class="text">$_("Please, wait...")</span></button>
+ <button class="btn-normal close" type="button"><span class="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+ </div>
+ <script>
+ kimchi.storagepool_add_main();
+ </script>
+ <script id="partitionTmpl" type="html/text">
+ <div>
+ <input type="checkbox" id="{name}" value="{path}" name="devices">
+ <label for="{name}">{path}</label>
+ </div>
+ </script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl b/src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl
new file mode 100644
index 0000000..b44db79
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl
@@ -0,0 +1,233 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<body>
+<div class="window" style="width: 992px;height: 660px;">
+ <header>
+ <h1 class="title h1 grey">$_("Add Template")</h1>
+ </header>
+ <div class="content" style="margin-bottom: 0">
+ <div class="page-list">
+ <!-- 1 -->
+ <div class="page" id="iso-type-box" style="left:0">
+ <h2 class="step-title">$_("Where is the source media for this template? ")</h2>
+ <ul class="step-choose">
+ <li>
+ <a id="iso-local" class="local">$_("Local ISO Image")</a>
+ </li>
+ <li>
+ <a id="vm-image-local" class="local">$_("Local Image File")</a>
+ </li>
+ <li>
+ <a id="iso-remote" class="remote">$_("Remote ISO Image")</a>
+ </li>
+ </ul>
+ </div>
+
+ <!-- 1-1 -->
+ <div class="page" id="iso-local-box">
+ <header>
+ <a class="back" id="iso-local-box-back"></a>
+ <h2 class="step-title">$_("Local ISO Image")</h2>
+ </header>
+
+ <button class="btn-normal" id="iso-search" style="display: none"><span class="text">$_("Search ISOs")</span></button>
+ <button class="btn-normal" id="iso-search-loading" style="display: none"><span class="text">$_("Please, wait...")</span></button>
+ <!-- 1-1-1 -->
+ <div id="local-iso-field" class="iso-field" style="display: none;">
+ <h3 class="step-subtitle">
+ $_("The following ISOs are available:")
+ </h3>
+ <div class="toolbar">
+ <label class="check-all">
+ <input type="checkbox" id="select-all-local-iso">$_("All")
+ </label>
+ </div>
+ <div>
+ <form id="form-local-iso">
+ <ul id="list-local-iso" class="list-iso">
+ </ul>
+ </form>
+ <script id="tmpl-list-local-iso" type="text/html">
+ <li>
+ <label>
+ <input type="checkbox" name="iso" value="{isoId}">
+ <div class="box box-iso">
+ <div class="iso-icon {os_distro}">
+ </div>
+ <h3 class="iso-title" title="{name}">
+ {name}
+ </h3>
+ <div class="iso-info">
+ <div class="iso-info-col">
+ <div class="iso-info-item" title="{os_distro}">
+ $_("OS: "){os_distro}
+ </div>
+ <div class="iso-info-item" title="{os_version}">
+ $_("Version: "){os_version}
+ </div>
+ </div>
+ <div class="iso-info-col">
+ <div class="iso-info-item" title="{capacity}">
+ $_("Size: "){capacity}
+ </div>
+ </div>
+ </div>
+ </div>
+ </label>
+ </li>
+ </script>
+ </div>
+ <div class="button-field">
+ <button class="btn-normal" id="iso-more" style="display: none"><span class="text">$_("Search more ISOs")</span></button>
+ <button class="btn-normal" id="iso-more-loading" style="display: none"><span class="text">$_("Please, wait...")</span></button>
+ <button class="btn-normal" id="btn-template-local-iso-create" disabled="disabled"><span class="text">$_("Create Templates from Selected ISO")</span></button>
+ </div>
+ </div>
+
+ <!-- 1-1-2 -->
+ <div id="iso-file-field">
+ <h3 class="step-subtitle">
+ <label>
+ <input type="checkbox" id="iso-file-check">
+ $_("I want to use a specific ISO file")
+ </label>
+ </h3>
+ <div id="iso-file-box" class="custom-iso-field">
+ <div class="input-wrapper"><input type="text" class="text" id="iso-file" name="iso-file"></div>
+ <button class="btn-normal" id="btn-template-file-create" disabled="disabled"><span class="text">$_("Create")</span></button>
+ </div>
+ </div>
+
+ </div>
+
+ <div class="page" id="vm-image-local-box">
+ <header>
+ <a class="back" id="vm-image-local-box-back"></a>
+ <h2 class="step-title">$_("Local Image File")</h2>
+ </header>
+ <div class="body">
+ <label for="vm-image-local-text">File Path:</label>
+ <input type="text" id="vm-image-local-text" />
+ <button class="ui-button-primary">$_("Create")</button>
+ </div>
+ </div>
+
+ <!-- 1-2 -->
+ <div class="page" id="iso-remote-box">
+ <header>
+ <a class="back" id="iso-remote-box-back"></a>
+ <h2 class="step-title">$_("Remote ISO Image")</h2>
+ </header>
+
+ <!-- 1-2-0 -->
+ <div id="load-remote-iso">
+ <h3 class="step-subtitle">
+ <label>
+ <img src = "plugins/kimchi/images/theme-default/loading.gif" />
+ $_("Loading default remote ISOs ...")
+ </label>
+ </h3>
+ </div>
+
+ <!-- 1-2-1 -->
+ <div id="remote-iso-field" class="iso-field" style="display: none;">
+ <h3 class="step-subtitle">
+ $_("The following ISOs are available:")
+ </h3>
+ <div class="toolbar">
+ <label class="check-all">
+ <input type="checkbox" id="select-all-remote-iso">$_("All")
+ </label>
+ </div>
+ <div>
+ <form id="form-remote-iso">
+ <ul id="list-remote-iso" class="list-iso">
+ </ul>
+ </form>
+ <script id="tmpl-list-remote-iso" type="text/html">
+ <li>
+ <label>
+ <input type="checkbox" name="iso" value="{isoId}">
+ <div class="box box-iso">
+ <div class="iso-icon {os_distro}">
+ </div>
+ <h3 class="iso-title" title="{name}">
+ {name}
+ </h3>
+ <div class="iso-info">
+ <div class="iso-info-col">
+ <div class="iso-info-item" title="{os_distro}">
+ $_("OS: "){os_distro}
+ </div>
+ <div class="iso-info-item" title="{os_version}">
+ $_("Version: "){os_version}
+ </div>
+
+ </div>
+ <div class="iso-info-col">
+ <div class="iso-info-item" title="{os_arch}">
+ $_("Arch: "){os_arch}
+ </div>
+ </div>
+ </div>
+ </div>
+ </label>
+ </li>
+ </script>
+ </div>
+ <div class="button-field">
+ <button class="btn-normal" id="btn-template-remote-iso-create" disabled="disabled"><span class="text">$_("Create Templates from Selected ISO")</span></button>
+ </div>
+ </div>
+
+ <!-- 1-2-2 -->
+ <div id="iso-url-field" style="display: none;">
+ <h3 class="step-subtitle">
+ <label>
+ <input type="checkbox" id="iso-url-check">
+ $_("I want to use a custom URL")
+ </label>
+ </h3>
+ <div id="iso-url-box" class="custom-iso-field">
+ <div class="input-wrapper"><input type="text" class="text" id="iso-url" name="iso-url"></div>
+ <button class="btn-normal" id="btn-template-url-create" disabled="disabled"><span class="text">$_("Create")</span></button>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ <footer>
+ <div class="button-group">
+ <button class="btn-normal close" type="button"><span type="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+</div>
+<script>
+kimchi.template_add_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl b/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
new file mode 100644
index 0000000..0588294
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
@@ -0,0 +1,193 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+<div id="template-edit-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Edit Template")</h1>
+ </header>
+ <div class="content">
+ <div id="edit-template-tabs">
+ <input type="hidden" id="template-name" name="templateName" />
+ <ul>
+ <li>
+ <a href="#form-template-general">$_("General")</a>
+ </li>
+ <li>
+ <a href="#form-template-storage">$_("Storage")</a>
+ </li>
+ <li>
+ <a href="#form-template-interface">$_("Interface")</a>
+ </li>
+ <li>
+ <a href="#form-template-processor">$_("Processor")</a>
+ </li>
+ </ul>
+ <form id="form-template-general">
+ <div class="form-template-inline-wrapper">
+ <div class="template-edit-wrapper-label">
+ <label for="template-edit-id-textbox">$_("Name")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label for="template-edit-vendor-textbox">$_("Vendor")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label for="template-edit-version-textbox">$_("Version")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label for="template-edit-memory-textbox">$_("Memory (MB)")</label>
+ </div>
+ <div class="template-edit-wrapper-label templ-edit-cdrom">
+ <label for="template-edit-cdrom-textbox">$_("CDROM")</label>
+ </div>
+ <div class="template-edit-wrapper-label templ-edit-vm-image hide">
+ <label for="template-edit-vmimage-textbox">$_("Image File")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label>$_("Graphics")</label>
+ </div>
+ </div>
+ <div class="form-template-inline-wrapper">
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-id-textbox" name="name" type="text" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-vendor-textbox" name="os_distro" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-version-textbox" name="os_version" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-memory-textbox" name="memory" type="text" />
+ </div>
+ <div class="template-edit-wrapper-controls templ-edit-cdrom">
+ <input id="template-edit-cdrom-textbox" name="cdrom" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls templ-edit-vm-image hide">
+ <input id="template-edit-vmimage-textbox" name="vm-image" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <div class="btn dropdown popable">
+ <input id="template-edit-graphics" name="graphics" type="hidden" />
+ <span class="text" id="template-edit-graphics-label"></span><span class="arrow"></span>
+ <div class="popover" style="width: 100%">
+ <ul class="select-list" id="template-edit-graphics-list" data-target="template-edit-graphics" data-label="template-edit-graphics-label">
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+ <form id="form-template-storage">
+ <div class="template-tab-header">
+ <span class="template-storage-cell">$_("Storage Pool")</span>
+ <span class="template-storage-cell">$_("Type")</span>
+ <span class="template-storage-cell">$_("Disk(GB)")</span>
+ <span class="template-storage-cell">$_("Disk Format")</span>
+ <button type="button" id="template-edit-storage-add-button" class="action-area"></button>
+ </div>
+ <div class="template-tab-body">
+ </div>
+ </form>
+ <form id="form-template-interface">
+ <div class="template-tab-header">
+ <span class="template-interface-cell">$_("Network")</span>
+ <span class="template-interface-cell">$_("Type")</span>
+ <button type="button" id="template-edit-interface-add-button" class="action-area"></button>
+ </div>
+ <div class="template-tab-body"></div>
+ </form>
+ <form id="form-template-processor">
+ <div>
+ <label for="cpus">$_("CPU Number"):</label>
+ <input type="text" value="1" id="cpus" />
+ </div>
+ <div class="manual">
+ <input type="checkbox" id="cpus-check" />
+ <label for="cpus-check">$_("Manually set CPU topology")</label>
+ </div>
+ <div class="topology hide">
+ <div>
+ <label for="cores">$_("Cores"):</label>
+ <input type="text" value="1" id="cores" />
+ </div>
+ <div>
+ <label for="threads">$_("Threads"):</label>
+ <select id="threads"></select>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <a id="tmpl-edit-button-save" class="btn-normal" href="javascript:void(0);"><span class="text">$_("Save")</span></a>
+ <button class="btn-normal close" type="button"><span class="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.template_edit_main();
+</script>
+<script id="template-storage-pool-tmpl" type="text/html">
+ <div class='item'>
+ <span class="template-storage-cell">
+ <input class="template-storage-name" value={storageName} type="text" style="display:none" />
+ <select id="selectStorageName"></select>
+ </span>
+ <span class="template-storage-cell">
+ <input class="template-storage-type" value={storageType} readonly=true type="text" />
+ </span>
+ <span class="template-storage-cell">
+ <input class="template-storage-disk" value={storageDisk} type="text" />
+ </span>
+ <span class="template-storage-cell">
+ <input class="template-storage-disk-format" value={storageDiskFormat} type="text" style="display:none" />
+ <select id="diskFormat">
+ <option value="qcow2">qcow2</option>
+ <option value="raw">raw</option>
+ <option value="bochs">bochs</option>
+ <option value="cloop">cloop</option>
+ <option value="cow">cow</option>
+ <option value="dmg">dmg</option>
+ <option value="qcow">qcow</option>
+ <option value="qed">qed</option>
+ <option value="vmdk">vmdk</option>
+ <option value="vpc">vpc</option>
+ </select>
+ </span>
+ </div>
+</script>
+<script id="template-interface-tmpl" type="text/html">
+ <div class="item" id={networkID}>
+ <span class="template-interface-cell">
+ <select></select>
+ </span>
+ <span class="template-interface-cell">
+ <input value={type} readonly=true type="text" />
+ </span>
+ <span class="action-area">
+ <button class="delete"></button>
+ </span>
+ </div>
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/templates.html.tmpl b/src/wok/plugins/kimchi/ui/pages/templates.html.tmpl
new file mode 100644
index 0000000..af1cf3f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/templates.html.tmpl
@@ -0,0 +1,77 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang, fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet" href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="template-add" class="btn-tool" href="javascript:void(0);"><span class="icon add">+</span></a>
+ </div>
+</div>
+<div>
+ <div id="noTemplates" class="list-no-result" style="display: none;">
+ $_("No templates found.")
+ </div>
+
+ <ul id="templateList" class="empty-when-logged-off"></ul>
+
+ <script id="templateTmpl" type="html/text">
+
+ <div class="template-box white-box template-border">
+ <div class="btn dropdown popable" style="width: 70px">
+ <span class="text">$_("Actions")</span><span class="arrow"></span>
+ <div class="popover actionsheet right-side" style="width: 250px">
+ <a class="button-big template-edit" data-template='{name}'>$_("Edit")</a>
+ <a class="button-big template-clone" data-template='{name}'>$_("Clone")</a>
+ <a class="button-big red template-delete" data-template='{name}'>$_("Delete")</a>
+ </div>
+ </div>
+
+ <div class="template-icon template-icon-position">
+ <img alt="" src="{icon}">
+ <img alt="" src="{location}" class="template-type-icon-position">
+ </div>
+ <div class="template-general template-title template-title-position">
+ <h2 class="title" title="{name}">{name}</h2>
+ </div>
+ <div class="template-os-position">
+ <div class="template-text">$_("OS"): {os_distro}</div>
+ <div class="template-text">$_("Version"): {os_version}</div>
+ </div>
+ <div class="template-cpu-position">
+ <div class="template-text">$_("CPUs"): {cpus}</div>
+ <div class="template-text">$_("Memory"): {memory}M</div>
+ </div>
+ </div>
+ </script>
+</div>
+<script>
+ kimchi.template_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/robots.txt b/src/wok/plugins/kimchi/ui/robots.txt
new file mode 100644
index 0000000..1f53798
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/Makefile.am b/src/wok/plugins/kimchi/ui/spice-html5/Makefile.am
new file mode 100644
index 0000000..c43f1ef
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+SUBDIRS = pages
+
+if WITH_SPICE
+SUBDIRS += css thirdparty
+
+spicehtml5dir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
+dist_spicehtml5_DATA = $(wildcard *.js) $(NULL)
+endif
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js b/src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js
new file mode 100644
index 0000000..e1e27fd
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js
@@ -0,0 +1,183 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Aric Stewart <aric at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three)
+ * sets of scancodes. Set3 can only be generated by a MF keyboard.
+ * Set2 sends a makecode for keypress, and the same code prefixed by a
+ * F0 for keyrelease. This is a little bit ugly to handle. Thus we use
+ * here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes.
+ * Bit 7 ist set if the key is released. The code E0 switches to a
+ * different meaning to add the new MF cursorkeys, while not breaking old
+ * applications. E1 is another special prefix. Since I assume that there
+ * will be further versions of PC/XT scancode compatible keyboards, we
+ * may be in trouble one day.
+ *
+ * IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3.
+ * 2) Use the keyboards native set and translate it to common keysyms.
+ */
+
+/*
+ * definition of the AT84/MF101/MF102 Keyboard:
+ * ============================================================
+ * Defined Key Cap Glyphs Pressed value
+ * Key Name Main Also (hex) (dec)
+ * ---------------- ---------- ------- ------ ------
+ */
+
+var KEY_Escape =/* Escape 0x01 */ 1
+var KEY_1 =/* 1 ! 0x02 */ 2
+var KEY_2 =/* 2 @ 0x03 */ 3
+var KEY_3 =/* 3 # 0x04 */ 4
+var KEY_4 =/* 4 $ 0x05 */ 5
+var KEY_5 =/* 5 % 0x06 */ 6
+var KEY_6 =/* 6 ^ 0x07 */ 7
+var KEY_7 =/* 7 & 0x08 */ 8
+var KEY_8 =/* 8 * 0x09 */ 9
+var KEY_9 =/* 9 ( 0x0a */ 10
+var KEY_0 =/* 0 ) 0x0b */ 11
+var KEY_Minus =/* - (Minus) _ (Under) 0x0c */ 12
+var KEY_Equal =/* = (Equal) + 0x0d */ 13
+var KEY_BackSpace =/* Back Space 0x0e */ 14
+var KEY_Tab =/* Tab 0x0f */ 15
+var KEY_Q =/* Q 0x10 */ 16
+var KEY_W =/* W 0x11 */ 17
+var KEY_E =/* E 0x12 */ 18
+var KEY_R =/* R 0x13 */ 19
+var KEY_T =/* T 0x14 */ 20
+var KEY_Y =/* Y 0x15 */ 21
+var KEY_U =/* U 0x16 */ 22
+var KEY_I =/* I 0x17 */ 23
+var KEY_O =/* O 0x18 */ 24
+var KEY_P =/* P 0x19 */ 25
+var KEY_LBrace =/* [ { 0x1a */ 26
+var KEY_RBrace =/* ] } 0x1b */ 27
+var KEY_Enter =/* Enter 0x1c */ 28
+var KEY_LCtrl =/* Ctrl(left) 0x1d */ 29
+var KEY_A =/* A 0x1e */ 30
+var KEY_S =/* S 0x1f */ 31
+var KEY_D =/* D 0x20 */ 32
+var KEY_F =/* F 0x21 */ 33
+var KEY_G =/* G 0x22 */ 34
+var KEY_H =/* H 0x23 */ 35
+var KEY_J =/* J 0x24 */ 36
+var KEY_K =/* K 0x25 */ 37
+var KEY_L =/* L 0x26 */ 38
+var KEY_SemiColon =/* ;(SemiColon) :(Colon) 0x27 */ 39
+var KEY_Quote =/* ' (Apostr) " (Quote) 0x28 */ 40
+var KEY_Tilde =/* ` (Accent) ~ (Tilde) 0x29 */ 41
+var KEY_ShiftL =/* Shift(left) 0x2a */ 42
+var KEY_BSlash =/* \(BckSlash) |(VertBar)0x2b */ 43
+var KEY_Z =/* Z 0x2c */ 44
+var KEY_X =/* X 0x2d */ 45
+var KEY_C =/* C 0x2e */ 46
+var KEY_V =/* V 0x2f */ 47
+var KEY_B =/* B 0x30 */ 48
+var KEY_N =/* N 0x31 */ 49
+var KEY_M =/* M 0x32 */ 50
+var KEY_Comma =/* , (Comma) < (Less) 0x33 */ 51
+var KEY_Period =/* . (Period) >(Greater)0x34 */ 52
+var KEY_Slash =/* / (Slash) ? 0x35 */ 53
+var KEY_ShiftR =/* Shift(right) 0x36 */ 54
+var KEY_KP_Multiply =/* * 0x37 */ 55
+var KEY_Alt =/* Alt(left) 0x38 */ 56
+var KEY_Space =/* (SpaceBar) 0x39 */ 57
+var KEY_CapsLock =/* CapsLock 0x3a */ 58
+var KEY_F1 =/* F1 0x3b */ 59
+var KEY_F2 =/* F2 0x3c */ 60
+var KEY_F3 =/* F3 0x3d */ 61
+var KEY_F4 =/* F4 0x3e */ 62
+var KEY_F5 =/* F5 0x3f */ 63
+var KEY_F6 =/* F6 0x40 */ 64
+var KEY_F7 =/* F7 0x41 */ 65
+var KEY_F8 =/* F8 0x42 */ 66
+var KEY_F9 =/* F9 0x43 */ 67
+var KEY_F10 =/* F10 0x44 */ 68
+var KEY_NumLock =/* NumLock 0x45 */ 69
+var KEY_ScrollLock =/* ScrollLock 0x46 */ 70
+var KEY_KP_7 =/* 7 Home 0x47 */ 71
+var KEY_KP_8 =/* 8 Up 0x48 */ 72
+var KEY_KP_9 =/* 9 PgUp 0x49 */ 73
+var KEY_KP_Minus =/* - (Minus) 0x4a */ 74
+var KEY_KP_4 =/* 4 Left 0x4b */ 75
+var KEY_KP_5 =/* 5 0x4c */ 76
+var KEY_KP_6 =/* 6 Right 0x4d */ 77
+var KEY_KP_Plus =/* + (Plus) 0x4e */ 78
+var KEY_KP_1 =/* 1 End 0x4f */ 79
+var KEY_KP_2 =/* 2 Down 0x50 */ 80
+var KEY_KP_3 =/* 3 PgDown 0x51 */ 81
+var KEY_KP_0 =/* 0 Insert 0x52 */ 82
+var KEY_KP_Decimal =/* . (Decimal) Delete 0x53 */ 83
+var KEY_SysReqest =/* SysReqest 0x54 */ 84
+ /* NOTUSED 0x55 */
+var KEY_Less =/* < (Less) >(Greater) 0x56 */ 86
+var KEY_F11 =/* F11 0x57 */ 87
+var KEY_F12 =/* F12 0x58 */ 88
+
+var KEY_Prefix0 =/* special 0x60 */ 96
+var KEY_Prefix1 =/* specail 0x61 */ 97
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/bitmap.js b/src/wok/plugins/kimchi/ui/spice-html5/bitmap.js
new file mode 100644
index 0000000..03f5127
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/bitmap.js
@@ -0,0 +1,51 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** bitmap.js
+** Handle SPICE_IMAGE_TYPE_BITMAP
+**--------------------------------------------------------------------------*/
+function convert_spice_bitmap_to_web(context, spice_bitmap)
+{
+ var ret;
+ var offset, x;
+ var u8 = new Uint8Array(spice_bitmap.data);
+ if (spice_bitmap.format != SPICE_BITMAP_FMT_32BIT &&
+ spice_bitmap.format != SPICE_BITMAP_FMT_RGBA)
+ return undefined;
+
+ ret = context.createImageData(spice_bitmap.x, spice_bitmap.y);
+ for (offset = 0; offset < (spice_bitmap.y * spice_bitmap.stride); )
+ for (x = 0; x < spice_bitmap.x; x++, offset += 4)
+ {
+ ret.data[offset + 0 ] = u8[offset + 2];
+ ret.data[offset + 1 ] = u8[offset + 1];
+ ret.data[offset + 2 ] = u8[offset + 0];
+
+ // FIXME - We effectively treat all images as having SPICE_IMAGE_FLAGS_HIGH_BITS_SET
+ if (spice_bitmap.format == SPICE_BITMAP_FMT_32BIT)
+ ret.data[offset + 3] = 255;
+ else
+ ret.data[offset + 3] = u8[offset];
+ }
+
+ return ret;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am b/src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am
new file mode 100644
index 0000000..ed51972
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+spicecssdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
+
+dist_spicecss_DATA = $(wildcard *.css) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/css/spice.css b/src/wok/plugins/kimchi/ui/spice-html5/css/spice.css
new file mode 100644
index 0000000..5d092ba
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/css/spice.css
@@ -0,0 +1,118 @@
+body
+{
+ background-color: #999999;
+ color: #000000; margin: 0; padding: 0;
+ font-family: "Lucida Grande", "Lucida Sans Unicode", "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;
+ font-size: 12pt;
+ line-height: 1.5em;
+}
+
+* { margin: 0; }
+
+#login
+{
+ width: 95%;
+ margin-left: auto;
+ margin-right: auto;
+ border: 1px solid #999999;
+ background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#24414e));
+ background: -moz-linear-gradient(top, #fff, #24414e);
+ background-color: #24414e;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+}
+#login span.logo
+{
+ display: inline-block;
+ margin-right: 5px;
+ padding: 2px 10px 2px 20px;
+ border-right: 1px solid #999999;
+ font-size: 20px;
+ font-weight: bolder;
+ text-shadow: #efefef 1px 1px 0px;
+}
+#login label { color: #ffffff; text-shadow: 1px 1px 0px rgba(175, 210, 220, 0.8); }
+#login input
+{
+ padding: 5px;
+ background-color: #fAfAfA;
+ border: 1px inset #999999;
+ outline: none;
+ -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+#login input#host { width: 200px; }
+#login input#port { width: 75px; }
+#login input#password { width: 100px; }
+#login button
+{
+ padding: 5px 10px 5px 10px;
+ margin-left: 5px;
+ text-shadow: #efefef 1px 1px 0px;
+ border: 1px outset #999999;
+ cursor: pointer;
+ -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
+}
+#login button:hover
+{
+ background-color: #666666;
+ color: #ffffff;
+}
+
+#spice-area
+{
+ height: 100%;
+ width: 95%;
+ padding: 0;
+ margin-left: auto;
+ margin-right: auto;
+ border: solid #222222 1px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+}
+.spice-screen
+{
+ min-height: 600px;
+ height: 100%;
+ margin: 10px;
+ padding: 0;
+ background-color: #333333;
+}
+.spice-message {
+ width: 700px;
+ height: 50px;
+ overflow: auto;
+ margin-top: 5px;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 10px;
+ background-color: #efefef;
+ border: solid #c3c3c3 2px;
+ font-size: 8pt;
+ line-height: 1.1em;
+ font-family: 'Andale Mono', monospace;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+}
+.spice-message p {
+ margin-bottom: 0em;
+ margin-top: 0em;
+}
+.spice-message-warning {
+ color: orange;
+}
+.spice-message-error {
+ color: red;
+}
+
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/cursor.js b/src/wok/plugins/kimchi/ui/spice-html5/cursor.js
new file mode 100644
index 0000000..71e941d
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/cursor.js
@@ -0,0 +1,110 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** SpiceCursorConn
+** Drive the Spice Cursor Channel
+**--------------------------------------------------------------------------*/
+function SpiceCursorConn()
+{
+ SpiceConn.apply(this, arguments);
+}
+
+SpiceCursorConn.prototype = Object.create(SpiceConn.prototype);
+SpiceCursorConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_CURSOR_INIT)
+ {
+ var cursor_init = new SpiceMsgCursorInit(msg.data);
+ DEBUG > 1 && console.log("SpiceMsgCursorInit");
+ if (this.parent && this.parent.inputs &&
+ this.parent.inputs.mouse_mode == SPICE_MOUSE_MODE_SERVER)
+ {
+ // FIXME - this imagines that the server actually
+ // provides the current cursor position,
+ // instead of 0,0. As of May 11, 2012,
+ // that assumption was false :-(.
+ this.parent.inputs.mousex = cursor_init.position.x;
+ this.parent.inputs.mousey = cursor_init.position.y;
+ }
+ // FIXME - We don't handle most of the parameters here...
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_SET)
+ {
+ var cursor_set = new SpiceMsgCursorSet(msg.data);
+ DEBUG > 1 && console.log("SpiceMsgCursorSet");
+ if (cursor_set.flags & SPICE_CURSOR_FLAGS_NONE)
+ {
+ document.getElementById(this.parent.screen_id).style.cursor = "none";
+ return true;
+ }
+
+ if (cursor_set.flags > 0)
+ this.log_warn("FIXME: No support for cursor flags " + cursor_set.flags);
+
+ if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA)
+ {
+ this.log_warn("FIXME: No support for cursor type " + cursor_set.cursor.header.type);
+ return false;
+ }
+
+ this.set_cursor(cursor_set.cursor);
+
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_HIDE)
+ {
+ DEBUG > 1 && console.log("SpiceMsgCursorHide");
+ document.getElementById(this.parent.screen_id).style.cursor = "none";
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_RESET)
+ {
+ DEBUG > 1 && console.log("SpiceMsgCursorReset");
+ document.getElementById(this.parent.screen_id).style.cursor = "auto";
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_INVAL_ALL)
+ {
+ DEBUG > 1 && console.log("SpiceMsgCursorInvalAll");
+ // FIXME - There may be something useful to do here...
+ return true;
+ }
+
+ return false;
+}
+
+SpiceCursorConn.prototype.set_cursor = function(cursor)
+{
+ var pngstr = create_rgba_png(cursor.header.height, cursor.header.width, cursor.data);
+ var curstr = 'url(data:image/png,' + pngstr + ') ' +
+ cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default";
+ var screen = document.getElementById(this.parent.screen_id);
+ screen.style.cursor = 'auto';
+ screen.style.cursor = curstr;
+ if (window.getComputedStyle(screen, null).cursor == 'auto')
+ SpiceSimulateCursor.simulate_cursor(this, cursor, screen, pngstr);
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/display.js b/src/wok/plugins/kimchi/ui/spice-html5/display.js
new file mode 100644
index 0000000..2aa5985
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/display.js
@@ -0,0 +1,823 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** FIXME: putImageData does not support Alpha blending
+** or compositing. So if we have data in an ImageData
+** format, we have to draw it onto a context,
+** and then use drawImage to put it onto the target,
+** as drawImage does alpha.
+**--------------------------------------------------------------------------*/
+function putImageDataWithAlpha(context, d, x, y)
+{
+ var c = document.createElement("canvas");
+ var t = c.getContext("2d");
+ c.setAttribute('width', d.width);
+ c.setAttribute('height', d.height);
+ t.putImageData(d, 0, 0);
+ context.drawImage(c, x, y, d.width, d.height);
+}
+
+/*----------------------------------------------------------------------------
+** FIXME: Spice will send an image with '0' alpha when it is intended to
+** go on a surface w/no alpha. So in that case, we have to strip
+** out the alpha. The test case for this was flux box; in a Xspice
+** server, right click on the desktop to get the menu; the top bar
+** doesn't paint/highlight correctly w/out this change.
+**--------------------------------------------------------------------------*/
+function stripAlpha(d)
+{
+ var i;
+ for (i = 0; i < (d.width * d.height * 4); i += 4)
+ d.data[i + 3] = 255;
+}
+
+/*----------------------------------------------------------------------------
+** SpiceDisplayConn
+** Drive the Spice Display Channel
+**--------------------------------------------------------------------------*/
+function SpiceDisplayConn()
+{
+ SpiceConn.apply(this, arguments);
+}
+
+SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype);
+SpiceDisplayConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_DISPLAY_MARK)
+ {
+ // FIXME - DISPLAY_MARK not implemented (may be hard or impossible)
+ this.known_unimplemented(msg.type, "Display Mark");
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_RESET)
+ {
+ DEBUG > 2 && console.log("Display reset");
+ this.surfaces[this.primary_surface].canvas.context.restore();
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_DRAW_COPY)
+ {
+ var draw_copy = new SpiceMsgDisplayDrawCopy(msg.data);
+
+ DEBUG > 1 && this.log_draw("DrawCopy", draw_copy);
+
+ if (! draw_copy.base.box.is_same_size(draw_copy.data.src_area))
+ this.log_warn("FIXME: DrawCopy src_area is a different size than base.box; we do not handle that yet.");
+ if (draw_copy.base.clip.type != SPICE_CLIP_TYPE_NONE)
+ this.log_warn("FIXME: DrawCopy we don't handle clipping yet");
+ if (draw_copy.data.rop_descriptor != SPICE_ROPD_OP_PUT)
+ this.log_warn("FIXME: DrawCopy we don't handle ropd type: " + draw_copy.data.rop_descriptor);
+ if (draw_copy.data.mask.flags)
+ this.log_warn("FIXME: DrawCopy we don't handle mask flag: " + draw_copy.data.mask.flags);
+ if (draw_copy.data.mask.bitmap)
+ this.log_warn("FIXME: DrawCopy we don't handle mask");
+
+ if (draw_copy.data && draw_copy.data.src_bitmap)
+ {
+ if (draw_copy.data.src_bitmap.descriptor.flags &&
+ draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_CACHE_ME &&
+ draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_HIGH_BITS_SET)
+ {
+ this.log_warn("FIXME: DrawCopy unhandled image flags: " + draw_copy.data.src_bitmap.descriptor.flags);
+ DEBUG <= 1 && this.log_draw("DrawCopy", draw_copy);
+ }
+
+ if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
+ {
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ if (! draw_copy.data.src_bitmap.quic)
+ {
+ this.log_warn("FIXME: DrawCopy could not handle this QUIC file.");
+ return false;
+ }
+ var source_img = convert_spice_quic_to_web(canvas.context,
+ draw_copy.data.src_bitmap.quic);
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: source_img,
+ tag: "copyquic." + draw_copy.data.src_bitmap.quic.type,
+ has_alpha: (draw_copy.data.src_bitmap.quic.type == QUIC_IMAGE_TYPE_RGBA ? true : false) ,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE ||
+ draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS)
+ {
+ if (! this.cache || ! this.cache[draw_copy.data.src_bitmap.descriptor.id])
+ {
+ this.log_warn("FIXME: DrawCopy did not find image id " + draw_copy.data.src_bitmap.descriptor.id + " in cache.");
+ return false;
+ }
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: this.cache[draw_copy.data.src_bitmap.descriptor.id],
+ tag: "copycache." + draw_copy.data.src_bitmap.descriptor.id,
+ has_alpha: true, /* FIXME - may want this to be false... */
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+
+ /* FIXME - LOSSLESS CACHE ramifications not understood or handled */
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
+ {
+ var source_context = this.surfaces[draw_copy.data.src_bitmap.surface_id].canvas.context;
+ var target_context = this.surfaces[draw_copy.base.surface_id].canvas.context;
+
+ var source_img = source_context.getImageData(
+ draw_copy.data.src_area.left, draw_copy.data.src_area.top,
+ draw_copy.data.src_area.right - draw_copy.data.src_area.left,
+ draw_copy.data.src_area.bottom - draw_copy.data.src_area.top);
+ var computed_src_area = new SpiceRect;
+ computed_src_area.top = computed_src_area.left = 0;
+ computed_src_area.right = source_img.width;
+ computed_src_area.bottom = source_img.height;
+
+ /* FIXME - there is a potential optimization here.
+ That is, if the surface is from 0,0, and
+ both surfaces are alpha surfaces, you should
+ be able to just do a drawImage, which should
+ save time. */
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: computed_src_area,
+ image_data: source_img,
+ tag: "copysurf." + draw_copy.data.src_bitmap.surface_id,
+ has_alpha: this.surfaces[draw_copy.data.src_bitmap.surface_id].format == SPICE_SURFACE_FMT_32_xRGB ? false : true,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+
+ return true;
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
+ {
+ if (! draw_copy.data.src_bitmap.jpeg)
+ {
+ this.log_warn("FIXME: DrawCopy could not handle this JPEG file.");
+ return false;
+ }
+
+ // FIXME - how lame is this. Be have it in binary format, and we have
+ // to put it into string to get it back into jpeg. Blech.
+ var tmpstr = "data:image/jpeg,";
+ var img = new Image;
+ var i;
+ var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg.data);
+ for (i = 0; i < qdv.length; i++)
+ {
+ tmpstr += '%';
+ if (qdv[i] < 16)
+ tmpstr += '0';
+ tmpstr += qdv[i].toString(16);
+ }
+
+ img.o =
+ { base: draw_copy.base,
+ tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
+ descriptor : draw_copy.data.src_bitmap.descriptor,
+ sc : this,
+ };
+ img.onload = handle_draw_jpeg_onload;
+ img.src = tmpstr;
+
+ return true;
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
+ {
+ if (! draw_copy.data.src_bitmap.jpeg_alpha)
+ {
+ this.log_warn("FIXME: DrawCopy could not handle this JPEG ALPHA file.");
+ return false;
+ }
+
+ // FIXME - how lame is this. Be have it in binary format, and we have
+ // to put it into string to get it back into jpeg. Blech.
+ var tmpstr = "data:image/jpeg,";
+ var img = new Image;
+ var i;
+ var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg_alpha.data);
+ for (i = 0; i < qdv.length; i++)
+ {
+ tmpstr += '%';
+ if (qdv[i] < 16)
+ tmpstr += '0';
+ tmpstr += qdv[i].toString(16);
+ }
+
+ img.o =
+ { base: draw_copy.base,
+ tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
+ descriptor : draw_copy.data.src_bitmap.descriptor,
+ sc : this,
+ };
+
+ if (this.surfaces[draw_copy.base.surface_id].format == SPICE_SURFACE_FMT_32_ARGB)
+ {
+
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ img.alpha_img = convert_spice_lz_to_web(canvas.context,
+ draw_copy.data.src_bitmap.jpeg_alpha.alpha);
+ }
+ img.onload = handle_draw_jpeg_onload;
+ img.src = tmpstr;
+
+ return true;
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
+ {
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ if (! draw_copy.data.src_bitmap.bitmap)
+ {
+ this.log_err("null bitmap");
+ return false;
+ }
+
+ var source_img = convert_spice_bitmap_to_web(canvas.context,
+ draw_copy.data.src_bitmap.bitmap);
+ if (! source_img)
+ {
+ this.log_warn("FIXME: Unable to interpret bitmap of format: " +
+ draw_copy.data.src_bitmap.bitmap.format);
+ return false;
+ }
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: source_img,
+ tag: "bitmap." + draw_copy.data.src_bitmap.bitmap.format,
+ has_alpha: draw_copy.data.src_bitmap.bitmap == SPICE_BITMAP_FMT_32BIT ? false : true,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
+ {
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ if (! draw_copy.data.src_bitmap.lz_rgb)
+ {
+ this.log_err("null lz_rgb ");
+ return false;
+ }
+
+ if (draw_copy.data.src_bitmap.lz_rgb.top_down != 1)
+ this.log_warn("FIXME: Implement non top down support for lz_rgb");
+
+ var source_img = convert_spice_lz_to_web(canvas.context,
+ draw_copy.data.src_bitmap.lz_rgb);
+ if (! source_img)
+ {
+ this.log_warn("FIXME: Unable to interpret bitmap of type: " +
+ draw_copy.data.src_bitmap.lz_rgb.type);
+ return false;
+ }
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: source_img,
+ tag: "lz_rgb." + draw_copy.data.src_bitmap.lz_rgb.type,
+ has_alpha: draw_copy.data.src_bitmap.lz_rgb.type == LZ_IMAGE_TYPE_RGBA ? true : false ,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+ }
+ else
+ {
+ this.log_warn("FIXME: DrawCopy unhandled image type: " + draw_copy.data.src_bitmap.descriptor.type);
+ this.log_draw("DrawCopy", draw_copy);
+ return false;
+ }
+ }
+
+ this.log_warn("FIXME: DrawCopy no src_bitmap.");
+ return false;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_DRAW_FILL)
+ {
+ var draw_fill = new SpiceMsgDisplayDrawFill(msg.data);
+
+ DEBUG > 1 && this.log_draw("DrawFill", draw_fill);
+
+ if (draw_fill.data.rop_descriptor != SPICE_ROPD_OP_PUT)
+ this.log_warn("FIXME: DrawFill we don't handle ropd type: " + draw_fill.data.rop_descriptor);
+ if (draw_fill.data.mask.flags)
+ this.log_warn("FIXME: DrawFill we don't handle mask flag: " + draw_fill.data.mask.flags);
+ if (draw_fill.data.mask.bitmap)
+ this.log_warn("FIXME: DrawFill we don't handle mask");
+
+ if (draw_fill.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
+ {
+ // FIXME - do brushes ever have alpha?
+ var color = draw_fill.data.brush.color & 0xffffff;
+ var color_str = "rgb(" + (color >> 16) + ", " + ((color >> 8) & 0xff) + ", " + (color & 0xff) + ")";
+ this.surfaces[draw_fill.base.surface_id].canvas.context.fillStyle = color_str;
+
+ this.surfaces[draw_fill.base.surface_id].canvas.context.fillRect(
+ draw_fill.base.box.left, draw_fill.base.box.top,
+ draw_fill.base.box.right - draw_fill.base.box.left,
+ draw_fill.base.box.bottom - draw_fill.base.box.top);
+
+ if (DUMP_DRAWS && this.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('width', this.surfaces[draw_fill.base.surface_id].canvas.width);
+ debug_canvas.setAttribute('height', this.surfaces[draw_fill.base.surface_id].canvas.height);
+ debug_canvas.setAttribute('id', "fillbrush." + draw_fill.base.surface_id + "." + this.surfaces[draw_fill.base.surface_id].draw_count);
+ debug_canvas.getContext("2d").fillStyle = color_str;
+ debug_canvas.getContext("2d").fillRect(
+ draw_fill.base.box.left, draw_fill.base.box.top,
+ draw_fill.base.box.right - draw_fill.base.box.left,
+ draw_fill.base.box.bottom - draw_fill.base.box.top);
+ document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
+ }
+
+ this.surfaces[draw_fill.base.surface_id].draw_count++;
+
+ }
+ else
+ {
+ this.log_warn("FIXME: DrawFill can't handle brush type: " + draw_fill.data.brush.type);
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_COPY_BITS)
+ {
+ var copy_bits = new SpiceMsgDisplayCopyBits(msg.data);
+
+ DEBUG > 1 && this.log_draw("CopyBits", copy_bits);
+
+ var source_canvas = this.surfaces[copy_bits.base.surface_id].canvas;
+ var source_context = source_canvas.context;
+
+ var width = source_canvas.width - copy_bits.src_pos.x;
+ var height = source_canvas.height - copy_bits.src_pos.y;
+ if (width > (copy_bits.base.box.right - copy_bits.base.box.left))
+ width = copy_bits.base.box.right - copy_bits.base.box.left;
+ if (height > (copy_bits.base.box.bottom - copy_bits.base.box.top))
+ height = copy_bits.base.box.bottom - copy_bits.base.box.top;
+
+ var source_img = source_context.getImageData(
+ copy_bits.src_pos.x, copy_bits.src_pos.y, width, height);
+ //source_context.putImageData(source_img, copy_bits.base.box.left, copy_bits.base.box.top);
+ putImageDataWithAlpha(source_context, source_img, copy_bits.base.box.left, copy_bits.base.box.top);
+
+ if (DUMP_DRAWS && this.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('width', width);
+ debug_canvas.setAttribute('height', height);
+ debug_canvas.setAttribute('id', "copybits" + copy_bits.base.surface_id + "." + this.surfaces[copy_bits.base.surface_id].draw_count);
+ debug_canvas.getContext("2d").putImageData(source_img, 0, 0);
+ document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
+ }
+
+
+ this.surfaces[copy_bits.base.surface_id].draw_count++;
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES)
+ {
+ this.known_unimplemented(msg.type, "Inval All Palettes");
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_SURFACE_CREATE)
+ {
+ if (! ("surfaces" in this))
+ this.surfaces = [];
+
+ var m = new SpiceMsgSurfaceCreate(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id " + m.surface.surface_id
+ + "; " + m.surface.width + "x" + m.surface.height
+ + "; format " + m.surface.format
+ + "; flags " + m.surface.flags);
+ if (m.surface.format != SPICE_SURFACE_FMT_32_xRGB &&
+ m.surface.format != SPICE_SURFACE_FMT_32_ARGB)
+ {
+ this.log_warn("FIXME: cannot handle surface format " + m.surface.format + " yet.");
+ return false;
+ }
+
+ var canvas = document.createElement("canvas");
+ canvas.setAttribute('width', m.surface.width);
+ canvas.setAttribute('height', m.surface.height);
+ canvas.setAttribute('id', "spice_surface_" + m.surface.surface_id);
+ canvas.setAttribute('tabindex', m.surface.surface_id);
+ canvas.context = canvas.getContext("2d");
+
+ if (DUMP_CANVASES && this.parent.dump_id)
+ document.getElementById(this.parent.dump_id).appendChild(canvas);
+
+ m.surface.canvas = canvas;
+ m.surface.draw_count = 0;
+ this.surfaces[m.surface.surface_id] = m.surface;
+
+ if (m.surface.flags & SPICE_SURFACE_FLAGS_PRIMARY)
+ {
+ this.primary_surface = m.surface.surface_id;
+
+ /* This .save() is done entirely to enable SPICE_MSG_DISPLAY_RESET */
+ canvas.context.save();
+ document.getElementById(this.parent.screen_id).appendChild(canvas);
+
+ /* We're going to leave width dynamic, but correctly set the height */
+ document.getElementById(this.parent.screen_id).style.height = m.surface.height + "px";
+ this.hook_events();
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_SURFACE_DESTROY)
+ {
+ var m = new SpiceMsgSurfaceDestroy(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id " + m.surface_id);
+ this.delete_surface(m.surface_id);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_CREATE)
+ {
+ var m = new SpiceMsgDisplayStreamCreate(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgStreamCreate id" + m.id);
+ if (!this.streams)
+ this.streams = new Array();
+ if (this.streams[m.id])
+ console.log("Stream already exists");
+ else
+ this.streams[m.id] = m;
+ if (m.codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG)
+ console.log("Unhandled stream codec: "+m.codec_type);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA)
+ {
+ var m = new SpiceMsgDisplayStreamData(msg.data);
+ if (!this.streams[m.base.id])
+ {
+ console.log("no stream for data");
+ return false;
+ }
+ if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
+ {
+ var tmpstr = "data:image/jpeg,";
+ var img = new Image;
+ var i;
+ for (i = 0; i < m.data.length; i++)
+ {
+ tmpstr += '%';
+ if (m.data[i] < 16)
+ tmpstr += '0';
+ tmpstr += m.data[i].toString(16);
+ }
+ var strm_base = new SpiceMsgDisplayBase();
+ strm_base.surface_id = this.streams[m.base.id].surface_id;
+ strm_base.box = this.streams[m.base.id].dest;
+ strm_base.clip = this.streams[m.base.id].clip;
+ img.o =
+ { base: strm_base,
+ tag: "mjpeg." + m.base.id,
+ descriptor: null,
+ sc : this,
+ };
+ img.onload = handle_draw_jpeg_onload;
+ img.src = tmpstr;
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
+ {
+ var m = new SpiceMsgDisplayStreamClip(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" + m.id);
+ this.streams[m.id].clip = m.clip;
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY)
+ {
+ var m = new SpiceMsgDisplayStreamDestroy(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgStreamDestroy id" + m.id);
+ this.streams[m.id] = undefined;
+ return true;
+ }
+ if (msg.type == SPICE_MSG_DISPLAY_INVAL_LIST)
+ {
+ var m = new SpiceMsgDisplayInvalList(msg.data);
+ var i;
+ DEBUG > 1 && console.log(this.type + ": MsgInvalList " + m.count + " items");
+ for (i = 0; i < m.count; i++)
+ if (this.cache[m.resources[i].id] != undefined)
+ delete this.cache[m.resources[i].id];
+ return true;
+ }
+
+ return false;
+}
+
+SpiceDisplayConn.prototype.delete_surface = function(surface_id)
+{
+ var canvas = document.getElementById("spice_surface_" + surface_id);
+ if (DUMP_CANVASES && this.parent.dump_id)
+ document.getElementById(this.parent.dump_id).removeChild(canvas);
+ if (this.primary_surface == surface_id)
+ {
+ this.unhook_events();
+ this.primary_surface = undefined;
+ document.getElementById(this.parent.screen_id).removeChild(canvas);
+ }
+
+ delete this.surfaces[surface_id];
+}
+
+
+SpiceDisplayConn.prototype.draw_copy_helper = function(o)
+{
+
+ var canvas = this.surfaces[o.base.surface_id].canvas;
+ if (o.has_alpha)
+ {
+ /* FIXME - This is based on trial + error, not a serious thoughtful
+ analysis of what Spice requires. See display.js for more. */
+ if (this.surfaces[o.base.surface_id].format == SPICE_SURFACE_FMT_32_xRGB)
+ {
+ stripAlpha(o.image_data);
+ canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
+ }
+ else
+ putImageDataWithAlpha(canvas.context, o.image_data,
+ o.base.box.left, o.base.box.top);
+ }
+ else
+ canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
+
+ if (o.src_area.left > 0 || o.src_area.top > 0)
+ {
+ this.log_warn("FIXME: DrawCopy not shifting draw copies just yet...");
+ }
+
+ if (o.descriptor && (o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
+ {
+ if (! ("cache" in this))
+ this.cache = {};
+ this.cache[o.descriptor.id] = o.image_data;
+ }
+
+ if (DUMP_DRAWS && this.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('width', o.image_data.width);
+ debug_canvas.setAttribute('height', o.image_data.height);
+ debug_canvas.setAttribute('id', o.tag + "." +
+ this.surfaces[o.base.surface_id].draw_count + "." +
+ o.base.surface_id + "@" + o.base.box.left + "x" + o.base.box.top);
+ debug_canvas.getContext("2d").putImageData(o.image_data, 0, 0);
+ document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
+ }
+
+ this.surfaces[o.base.surface_id].draw_count++;
+
+ return true;
+}
+
+
+SpiceDisplayConn.prototype.log_draw = function(prefix, draw)
+{
+ var str = prefix + "." + draw.base.surface_id + "." + this.surfaces[draw.base.surface_id].draw_count + ": ";
+ str += "base.box " + draw.base.box.left + ", " + draw.base.box.top + " to " +
+ draw.base.box.right + ", " + draw.base.box.bottom;
+ str += "; clip.type " + draw.base.clip.type;
+
+ if (draw.data)
+ {
+ if (draw.data.src_area)
+ str += "; src_area " + draw.data.src_area.left + ", " + draw.data.src_area.top + " to "
+ + draw.data.src_area.right + ", " + draw.data.src_area.bottom;
+
+ if (draw.data.src_bitmap && draw.data.src_bitmap != null)
+ {
+ str += "; src_bitmap id: " + draw.data.src_bitmap.descriptor.id;
+ str += "; src_bitmap width " + draw.data.src_bitmap.descriptor.width + ", height " + draw.data.src_bitmap.descriptor.height;
+ str += "; src_bitmap type " + draw.data.src_bitmap.descriptor.type + ", flags " + draw.data.src_bitmap.descriptor.flags;
+ if (draw.data.src_bitmap.surface_id !== undefined)
+ str += "; src_bitmap surface_id " + draw.data.src_bitmap.surface_id;
+ if (draw.data.src_bitmap.quic)
+ str += "; QUIC type " + draw.data.src_bitmap.quic.type +
+ "; width " + draw.data.src_bitmap.quic.width +
+ "; height " + draw.data.src_bitmap.quic.height ;
+ if (draw.data.src_bitmap.lz_rgb)
+ str += "; LZ_RGB length " + draw.data.src_bitmap.lz_rgb.length +
+ "; magic " + draw.data.src_bitmap.lz_rgb.magic +
+ "; version 0x" + draw.data.src_bitmap.lz_rgb.version.toString(16) +
+ "; type " + draw.data.src_bitmap.lz_rgb.type +
+ "; width " + draw.data.src_bitmap.lz_rgb.width +
+ "; height " + draw.data.src_bitmap.lz_rgb.height +
+ "; stride " + draw.data.src_bitmap.lz_rgb.stride +
+ "; top down " + draw.data.src_bitmap.lz_rgb.top_down;
+ }
+ else
+ str += "; src_bitmap is null";
+
+ if (draw.data.brush)
+ {
+ if (draw.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
+ str += "; brush.color 0x" + draw.data.brush.color.toString(16);
+ if (draw.data.brush.type == SPICE_BRUSH_TYPE_PATTERN)
+ {
+ str += "; brush.pat ";
+ if (draw.data.brush.pattern.pat != null)
+ str += "[SpiceImage]";
+ else
+ str += "[null]";
+ str += " at " + draw.data.brush.pattern.pos.x + ", " + draw.data.brush.pattern.pos.y;
+ }
+ }
+
+ str += "; rop_descriptor " + draw.data.rop_descriptor;
+ if (draw.data.scale_mode !== undefined)
+ str += "; scale_mode " + draw.data.scale_mode;
+ str += "; mask.flags " + draw.data.mask.flags;
+ str += "; mask.pos " + draw.data.mask.pos.x + ", " + draw.data.mask.pos.y;
+ if (draw.data.mask.bitmap != null)
+ {
+ str += "; mask.bitmap width " + draw.data.mask.bitmap.descriptor.width + ", height " + draw.data.mask.bitmap.descriptor.height;
+ str += "; mask.bitmap type " + draw.data.mask.bitmap.descriptor.type + ", flags " + draw.data.mask.bitmap.descriptor.flags;
+ }
+ else
+ str += "; mask.bitmap is null";
+ }
+
+ console.log(str);
+}
+
+SpiceDisplayConn.prototype.hook_events = function()
+{
+ if (this.primary_surface !== undefined)
+ {
+ var canvas = this.surfaces[this.primary_surface].canvas;
+ canvas.sc = this.parent;
+ canvas.addEventListener('mousemove', handle_mousemove);
+ canvas.addEventListener('mousedown', handle_mousedown);
+ canvas.addEventListener('contextmenu', handle_contextmenu);
+ canvas.addEventListener('mouseup', handle_mouseup);
+ canvas.addEventListener('keydown', handle_keydown);
+ canvas.addEventListener('keyup', handle_keyup);
+ canvas.addEventListener('mouseout', handle_mouseout);
+ canvas.addEventListener('mouseover', handle_mouseover);
+ canvas.addEventListener('mousewheel', handle_mousewheel);
+ canvas.focus();
+ }
+}
+
+SpiceDisplayConn.prototype.unhook_events = function()
+{
+ if (this.primary_surface !== undefined)
+ {
+ var canvas = this.surfaces[this.primary_surface].canvas;
+ canvas.removeEventListener('mousemove', handle_mousemove);
+ canvas.removeEventListener('mousedown', handle_mousedown);
+ canvas.removeEventListener('contextmenu', handle_contextmenu);
+ canvas.removeEventListener('mouseup', handle_mouseup);
+ canvas.removeEventListener('keydown', handle_keydown);
+ canvas.removeEventListener('keyup', handle_keyup);
+ canvas.removeEventListener('mouseout', handle_mouseout);
+ canvas.removeEventListener('mouseover', handle_mouseover);
+ canvas.removeEventListener('mousewheel', handle_mousewheel);
+ }
+}
+
+
+SpiceDisplayConn.prototype.destroy_surfaces = function()
+{
+ for (var s in this.surfaces)
+ {
+ this.delete_surface(this.surfaces[s].surface_id);
+ }
+
+ this.surfaces = undefined;
+}
+
+
+function handle_mouseover(e)
+{
+ this.focus();
+}
+
+function handle_mouseout(e)
+{
+ if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor)
+ this.sc.cursor.spice_simulated_cursor.style.display = 'none';
+ this.blur();
+}
+
+function handle_draw_jpeg_onload()
+{
+ var temp_canvas = null;
+ var context;
+
+ /*------------------------------------------------------------
+ ** FIXME:
+ ** The helper should be extended to be able to handle actual HtmlImageElements
+ ** ...and the cache should be modified to do so as well
+ **----------------------------------------------------------*/
+ if (this.o.sc.surfaces[this.o.base.surface_id] === undefined)
+ {
+ // This can happen; if the jpeg image loads after our surface
+ // has been destroyed (e.g. open a menu, close it quickly),
+ // we'll find we have no surface.
+ DEBUG > 2 && this.o.sc.log_info("Discarding jpeg; presumed lost surface " + this.o.base.surface_id);
+ temp_canvas = document.createElement("canvas");
+ temp_canvas.setAttribute('width', this.o.base.box.right);
+ temp_canvas.setAttribute('height', this.o.base.box.bottom);
+ context = temp_canvas.getContext("2d");
+ }
+ else
+ context = this.o.sc.surfaces[this.o.base.surface_id].canvas.context;
+
+ if (this.alpha_img)
+ {
+ var c = document.createElement("canvas");
+ var t = c.getContext("2d");
+ c.setAttribute('width', this.alpha_img.width);
+ c.setAttribute('height', this.alpha_img.height);
+ t.putImageData(this.alpha_img, 0, 0);
+ t.globalCompositeOperation = 'source-in';
+ t.drawImage(this, 0, 0);
+
+ context.drawImage(c, this.o.base.box.left, this.o.base.box.top);
+
+ if (this.o.descriptor &&
+ (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
+ {
+ if (! ("cache" in this.o.sc))
+ this.o.sc.cache = {};
+
+ this.o.sc.cache[this.o.descriptor.id] =
+ t.getImageData(0, 0,
+ this.alpha_img.width,
+ this.alpha_img.height);
+ }
+ }
+ else
+ {
+ context.drawImage(this, this.o.base.box.left, this.o.base.box.top);
+
+ // Give the Garbage collector a clue to recycle this; avoids
+ // fairly massive memory leaks during video playback
+ this.src = null;
+
+ if (this.o.descriptor &&
+ (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
+ {
+ if (! ("cache" in this.o.sc))
+ this.o.sc.cache = {};
+
+ this.o.sc.cache[this.o.descriptor.id] =
+ context.getImageData(this.o.base.box.left, this.o.base.box.top,
+ this.o.base.box.right - this.o.base.box.left,
+ this.o.base.box.bottom - this.o.base.box.top);
+ }
+ }
+
+ if (temp_canvas == null)
+ {
+ if (DUMP_DRAWS && this.o.sc.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('id', this.o.tag + "." +
+ this.o.sc.surfaces[this.o.base.surface_id].draw_count + "." +
+ this.o.base.surface_id + "@" + this.o.base.box.left + "x" + this.o.base.box.top);
+ debug_canvas.getContext("2d").drawImage(this, 0, 0);
+ document.getElementById(this.o.sc.parent.dump_id).appendChild(debug_canvas);
+ }
+
+ this.o.sc.surfaces[this.o.base.surface_id].draw_count++;
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/enums.js b/src/wok/plugins/kimchi/ui/spice-html5/enums.js
new file mode 100644
index 0000000..d99b38e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/enums.js
@@ -0,0 +1,324 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** enums.js
+** 'constants' for Spice
+**--------------------------------------------------------------------------*/
+var SPICE_MAGIC = "REDQ";
+var SPICE_VERSION_MAJOR = 2;
+var SPICE_VERSION_MINOR = 2;
+
+var SPICE_CONNECT_TIMEOUT = (30 * 1000);
+
+var SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION = 0;
+var SPICE_COMMON_CAP_AUTH_SPICE = 1;
+var SPICE_COMMON_CAP_AUTH_SASL = 2;
+var SPICE_COMMON_CAP_MINI_HEADER = 3;
+
+var SPICE_TICKET_KEY_PAIR_LENGTH = 1024;
+var SPICE_TICKET_PUBKEY_BYTES = (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34);
+
+var SPICE_LINK_ERR_OK = 0,
+ SPICE_LINK_ERR_ERROR = 1,
+ SPICE_LINK_ERR_INVALID_MAGIC = 2,
+ SPICE_LINK_ERR_INVALID_DATA = 3,
+ SPICE_LINK_ERR_VERSION_MISMATCH = 4,
+ SPICE_LINK_ERR_NEED_SECURED = 5,
+ SPICE_LINK_ERR_NEED_UNSECURED = 6,
+ SPICE_LINK_ERR_PERMISSION_DENIED = 7,
+ SPICE_LINK_ERR_BAD_CONNECTION_ID = 8,
+ SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE = 9;
+
+var SPICE_MSG_MIGRATE = 1;
+var SPICE_MSG_MIGRATE_DATA = 2;
+var SPICE_MSG_SET_ACK = 3;
+var SPICE_MSG_PING = 4;
+var SPICE_MSG_WAIT_FOR_CHANNELS = 5;
+var SPICE_MSG_DISCONNECTING = 6;
+var SPICE_MSG_NOTIFY = 7;
+var SPICE_MSG_LIST = 8;
+
+var SPICE_MSG_MAIN_MIGRATE_BEGIN = 101;
+var SPICE_MSG_MAIN_MIGRATE_CANCEL = 102;
+var SPICE_MSG_MAIN_INIT = 103;
+var SPICE_MSG_MAIN_CHANNELS_LIST = 104;
+var SPICE_MSG_MAIN_MOUSE_MODE = 105;
+var SPICE_MSG_MAIN_MULTI_MEDIA_TIME = 106;
+var SPICE_MSG_MAIN_AGENT_CONNECTED = 107;
+var SPICE_MSG_MAIN_AGENT_DISCONNECTED = 108;
+var SPICE_MSG_MAIN_AGENT_DATA = 109;
+var SPICE_MSG_MAIN_AGENT_TOKEN = 110;
+var SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST = 111;
+var SPICE_MSG_MAIN_MIGRATE_END = 112;
+var SPICE_MSG_MAIN_NAME = 113;
+var SPICE_MSG_MAIN_UUID = 114;
+var SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS = 115;
+var SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS = 116;
+var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK = 117;
+var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK = 118;
+var SPICE_MSG_END_MAIN = 119;
+
+
+
+var SPICE_MSGC_ACK_SYNC = 1;
+var SPICE_MSGC_ACK = 2;
+var SPICE_MSGC_PONG = 3;
+var SPICE_MSGC_MIGRATE_FLUSH_MARK = 4;
+var SPICE_MSGC_MIGRATE_DATA = 5;
+var SPICE_MSGC_DISCONNECTING = 6;
+
+
+var SPICE_MSGC_MAIN_CLIENT_INFO = 101;
+var SPICE_MSGC_MAIN_MIGRATE_CONNECTED = 102;
+var SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR = 103;
+var SPICE_MSGC_MAIN_ATTACH_CHANNELS = 104;
+var SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST = 105;
+var SPICE_MSGC_MAIN_AGENT_START = 106;
+var SPICE_MSGC_MAIN_AGENT_DATA = 107;
+var SPICE_MSGC_MAIN_AGENT_TOKEN = 108;
+var SPICE_MSGC_MAIN_MIGRATE_END = 109;
+var SPICE_MSGC_END_MAIN = 110;
+
+var SPICE_MSG_DISPLAY_MODE = 101;
+var SPICE_MSG_DISPLAY_MARK = 102;
+var SPICE_MSG_DISPLAY_RESET = 103;
+var SPICE_MSG_DISPLAY_COPY_BITS = 104;
+var SPICE_MSG_DISPLAY_INVAL_LIST = 105;
+var SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS = 106;
+var SPICE_MSG_DISPLAY_INVAL_PALETTE = 107;
+var SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES= 108;
+
+var SPICE_MSG_DISPLAY_STREAM_CREATE = 122;
+var SPICE_MSG_DISPLAY_STREAM_DATA = 123;
+var SPICE_MSG_DISPLAY_STREAM_CLIP = 124;
+var SPICE_MSG_DISPLAY_STREAM_DESTROY = 125;
+var SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL= 126;
+
+var SPICE_MSG_DISPLAY_DRAW_FILL = 302;
+var SPICE_MSG_DISPLAY_DRAW_OPAQUE = 303;
+var SPICE_MSG_DISPLAY_DRAW_COPY = 304;
+var SPICE_MSG_DISPLAY_DRAW_BLEND = 305;
+var SPICE_MSG_DISPLAY_DRAW_BLACKNESS = 306;
+var SPICE_MSG_DISPLAY_DRAW_WHITENESS = 307;
+var SPICE_MSG_DISPLAY_DRAW_INVERS = 308;
+var SPICE_MSG_DISPLAY_DRAW_ROP3 = 309;
+var SPICE_MSG_DISPLAY_DRAW_STROKE = 310;
+var SPICE_MSG_DISPLAY_DRAW_TEXT = 311;
+var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT = 312;
+var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND = 313;
+var SPICE_MSG_DISPLAY_SURFACE_CREATE = 314;
+var SPICE_MSG_DISPLAY_SURFACE_DESTROY = 315;
+
+var SPICE_MSGC_DISPLAY_INIT = 101;
+
+var SPICE_MSG_INPUTS_INIT = 101;
+var SPICE_MSG_INPUTS_KEY_MODIFIERS = 102;
+
+var SPICE_MSG_INPUTS_MOUSE_MOTION_ACK = 111;
+
+var SPICE_MSGC_INPUTS_KEY_DOWN = 101;
+var SPICE_MSGC_INPUTS_KEY_UP = 102;
+var SPICE_MSGC_INPUTS_KEY_MODIFIERS = 103;
+
+var SPICE_MSGC_INPUTS_MOUSE_MOTION = 111;
+var SPICE_MSGC_INPUTS_MOUSE_POSITION = 112;
+var SPICE_MSGC_INPUTS_MOUSE_PRESS = 113;
+var SPICE_MSGC_INPUTS_MOUSE_RELEASE = 114;
+
+var SPICE_MSG_CURSOR_INIT = 101;
+var SPICE_MSG_CURSOR_RESET = 102;
+var SPICE_MSG_CURSOR_SET = 103;
+var SPICE_MSG_CURSOR_MOVE = 104;
+var SPICE_MSG_CURSOR_HIDE = 105;
+var SPICE_MSG_CURSOR_TRAIL = 106;
+var SPICE_MSG_CURSOR_INVAL_ONE = 107;
+var SPICE_MSG_CURSOR_INVAL_ALL = 108;
+
+var SPICE_MSG_PLAYBACK_DATA = 101;
+var SPICE_MSG_PLAYBACK_MODE = 102;
+var SPICE_MSG_PLAYBACK_START = 103;
+var SPICE_MSG_PLAYBACK_STOP = 104;
+var SPICE_MSG_PLAYBACK_VOLUME = 105;
+var SPICE_MSG_PLAYBACK_MUTE = 106;
+var SPICE_MSG_PLAYBACK_LATENCY = 107;
+
+var SPICE_PLAYBACK_CAP_CELT_0_5_1 = 0;
+var SPICE_PLAYBACK_CAP_VOLUME = 1;
+var SPICE_PLAYBACK_CAP_LATENCY = 2;
+var SPICE_PLAYBACK_CAP_OPUS = 3;
+
+var SPICE_AUDIO_DATA_MODE_INVALID = 0;
+var SPICE_AUDIO_DATA_MODE_RAW = 1;
+var SPICE_AUDIO_DATA_MODE_CELT_0_5_1 = 2;
+var SPICE_AUDIO_DATA_MODE_OPUS = 3;
+
+var SPICE_AUDIO_FMT_INVALID = 0;
+var SPICE_AUDIO_FMT_S16 = 1;
+
+var SPICE_CHANNEL_MAIN = 1;
+var SPICE_CHANNEL_DISPLAY = 2;
+var SPICE_CHANNEL_INPUTS = 3;
+var SPICE_CHANNEL_CURSOR = 4;
+var SPICE_CHANNEL_PLAYBACK = 5;
+var SPICE_CHANNEL_RECORD = 6;
+var SPICE_CHANNEL_TUNNEL = 7;
+var SPICE_CHANNEL_SMARTCARD = 8;
+var SPICE_CHANNEL_USBREDIR = 9;
+
+var SPICE_SURFACE_FLAGS_PRIMARY = (1 << 0);
+
+var SPICE_NOTIFY_SEVERITY_INFO = 0;
+var SPICE_NOTIFY_SEVERITY_WARN = 1;
+var SPICE_NOTIFY_SEVERITY_ERROR = 2;
+
+var SPICE_MOUSE_MODE_SERVER = (1 << 0),
+ SPICE_MOUSE_MODE_CLIENT = (1 << 1),
+ SPICE_MOUSE_MODE_MASK = 0x3;
+
+var SPICE_CLIP_TYPE_NONE = 0;
+var SPICE_CLIP_TYPE_RECTS = 1;
+
+var SPICE_IMAGE_TYPE_BITMAP = 0;
+var SPICE_IMAGE_TYPE_QUIC = 1;
+var SPICE_IMAGE_TYPE_RESERVED = 2;
+var SPICE_IMAGE_TYPE_LZ_PLT = 100;
+var SPICE_IMAGE_TYPE_LZ_RGB = 101;
+var SPICE_IMAGE_TYPE_GLZ_RGB = 102;
+var SPICE_IMAGE_TYPE_FROM_CACHE = 103;
+var SPICE_IMAGE_TYPE_SURFACE = 104;
+var SPICE_IMAGE_TYPE_JPEG = 105;
+var SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS = 106;
+var SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB = 107;
+var SPICE_IMAGE_TYPE_JPEG_ALPHA = 108;
+
+var SPICE_IMAGE_FLAGS_CACHE_ME = (1 << 0),
+ SPICE_IMAGE_FLAGS_HIGH_BITS_SET = (1 << 1),
+ SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME = (1 << 2);
+
+var SPICE_BITMAP_FLAGS_PAL_CACHE_ME = (1 << 0),
+ SPICE_BITMAP_FLAGS_PAL_FROM_CACHE = (1 << 1),
+ SPICE_BITMAP_FLAGS_TOP_DOWN = (1 << 2),
+ SPICE_BITMAP_FLAGS_MASK = 0x7;
+
+var SPICE_BITMAP_FMT_INVALID = 0,
+ SPICE_BITMAP_FMT_1BIT_LE = 1,
+ SPICE_BITMAP_FMT_1BIT_BE = 2,
+ SPICE_BITMAP_FMT_4BIT_LE = 3,
+ SPICE_BITMAP_FMT_4BIT_BE = 4,
+ SPICE_BITMAP_FMT_8BIT = 5,
+ SPICE_BITMAP_FMT_16BIT = 6,
+ SPICE_BITMAP_FMT_24BIT = 7,
+ SPICE_BITMAP_FMT_32BIT = 8,
+ SPICE_BITMAP_FMT_RGBA = 9;
+
+
+var SPICE_CURSOR_FLAGS_NONE = (1 << 0),
+ SPICE_CURSOR_FLAGS_CACHE_ME = (1 << 1),
+ SPICE_CURSOR_FLAGS_FROM_CACHE = (1 << 2),
+ SPICE_CURSOR_FLAGS_MASK = 0x7;
+
+var SPICE_MOUSE_BUTTON_MASK_LEFT = (1 << 0),
+ SPICE_MOUSE_BUTTON_MASK_MIDDLE = (1 << 1),
+ SPICE_MOUSE_BUTTON_MASK_RIGHT = (1 << 2),
+ SPICE_MOUSE_BUTTON_MASK_MASK = 0x7;
+
+var SPICE_MOUSE_BUTTON_INVALID = 0;
+var SPICE_MOUSE_BUTTON_LEFT = 1;
+var SPICE_MOUSE_BUTTON_MIDDLE = 2;
+var SPICE_MOUSE_BUTTON_RIGHT = 3;
+var SPICE_MOUSE_BUTTON_UP = 4;
+var SPICE_MOUSE_BUTTON_DOWN = 5;
+
+var SPICE_BRUSH_TYPE_NONE = 0,
+ SPICE_BRUSH_TYPE_SOLID = 1,
+ SPICE_BRUSH_TYPE_PATTERN = 2;
+
+var SPICE_SURFACE_FMT_INVALID = 0,
+ SPICE_SURFACE_FMT_1_A = 1,
+ SPICE_SURFACE_FMT_8_A = 8,
+ SPICE_SURFACE_FMT_16_555 = 16,
+ SPICE_SURFACE_FMT_32_xRGB = 32,
+ SPICE_SURFACE_FMT_16_565 = 80,
+ SPICE_SURFACE_FMT_32_ARGB = 96;
+
+var SPICE_ROPD_INVERS_SRC = (1 << 0),
+ SPICE_ROPD_INVERS_BRUSH = (1 << 1),
+ SPICE_ROPD_INVERS_DEST = (1 << 2),
+ SPICE_ROPD_OP_PUT = (1 << 3),
+ SPICE_ROPD_OP_OR = (1 << 4),
+ SPICE_ROPD_OP_AND = (1 << 5),
+ SPICE_ROPD_OP_XOR = (1 << 6),
+ SPICE_ROPD_OP_BLACKNESS = (1 << 7),
+ SPICE_ROPD_OP_WHITENESS = (1 << 8),
+ SPICE_ROPD_OP_INVERS = (1 << 9),
+ SPICE_ROPD_INVERS_RES = (1 << 10),
+ SPICE_ROPD_MASK = 0x7ff;
+
+var LZ_IMAGE_TYPE_INVALID = 0,
+ LZ_IMAGE_TYPE_PLT1_LE = 1,
+ LZ_IMAGE_TYPE_PLT1_BE = 2, // PLT stands for palette
+ LZ_IMAGE_TYPE_PLT4_LE = 3,
+ LZ_IMAGE_TYPE_PLT4_BE = 4,
+ LZ_IMAGE_TYPE_PLT8 = 5,
+ LZ_IMAGE_TYPE_RGB16 = 6,
+ LZ_IMAGE_TYPE_RGB24 = 7,
+ LZ_IMAGE_TYPE_RGB32 = 8,
+ LZ_IMAGE_TYPE_RGBA = 9,
+ LZ_IMAGE_TYPE_XXXA = 10;
+
+
+var QUIC_IMAGE_TYPE_INVALID = 0,
+ QUIC_IMAGE_TYPE_GRAY = 1,
+ QUIC_IMAGE_TYPE_RGB16 = 2,
+ QUIC_IMAGE_TYPE_RGB24 = 3,
+ QUIC_IMAGE_TYPE_RGB32 = 4,
+ QUIC_IMAGE_TYPE_RGBA = 5;
+
+var SPICE_INPUT_MOTION_ACK_BUNCH = 4;
+
+
+var SPICE_CURSOR_TYPE_ALPHA = 0,
+ SPICE_CURSOR_TYPE_MONO = 1,
+ SPICE_CURSOR_TYPE_COLOR4 = 2,
+ SPICE_CURSOR_TYPE_COLOR8 = 3,
+ SPICE_CURSOR_TYPE_COLOR16 = 4,
+ SPICE_CURSOR_TYPE_COLOR24 = 5,
+ SPICE_CURSOR_TYPE_COLOR32 = 6;
+
+var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1;
+
+var VD_AGENT_PROTOCOL = 1;
+
+var VD_AGENT_MOUSE_STATE = 1,
+ VD_AGENT_MONITORS_CONFIG = 2,
+ VD_AGENT_REPLY = 3,
+ VD_AGENT_CLIPBOARD = 4,
+ VD_AGENT_DISPLAY_CONFIG = 5,
+ VD_AGENT_ANNOUNCE_CAPABILITIES = 6,
+ VD_AGENT_CLIPBOARD_GRAB = 7,
+ VD_AGENT_CLIPBOARD_REQUEST = 8,
+ VD_AGENT_CLIPBOARD_RELEASE = 9,
+ VD_AGENT_FILE_XFER_START =10,
+ VD_AGENT_FILE_XFER_STATUS =11,
+ VD_AGENT_FILE_XFER_DATA =12,
+ VD_AGENT_CLIENT_DISCONNECTED =13,
+ VD_AGENT_MAX_CLIPBOARD =14;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/inputs.js b/src/wok/plugins/kimchi/ui/spice-html5/inputs.js
new file mode 100644
index 0000000..c904eda
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/inputs.js
@@ -0,0 +1,280 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+ ** Modifier Keystates
+ ** These need to be tracked because focus in and out can get the keyboard
+ ** out of sync.
+ **------------------------------------------------------------------------*/
+var Shift_state = -1;
+var Ctrl_state = -1;
+var Alt_state = -1;
+var Meta_state = -1;
+
+/*----------------------------------------------------------------------------
+** SpiceInputsConn
+** Drive the Spice Inputs channel (e.g. mouse + keyboard)
+**--------------------------------------------------------------------------*/
+function SpiceInputsConn()
+{
+ SpiceConn.apply(this, arguments);
+
+ this.mousex = undefined;
+ this.mousey = undefined;
+ this.button_state = 0;
+ this.waiting_for_ack = 0;
+}
+
+SpiceInputsConn.prototype = Object.create(SpiceConn.prototype);
+SpiceInputsConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_INPUTS_INIT)
+ {
+ var inputs_init = new SpiceMsgInputsInit(msg.data);
+ this.keyboard_modifiers = inputs_init.keyboard_modifiers;
+ DEBUG > 1 && console.log("MsgInputsInit - modifier " + this.keyboard_modifiers);
+ // FIXME - We don't do anything with the keyboard modifiers...
+ return true;
+ }
+ if (msg.type == SPICE_MSG_INPUTS_KEY_MODIFIERS)
+ {
+ var key = new SpiceMsgInputsKeyModifiers(msg.data);
+ this.keyboard_modifiers = key.keyboard_modifiers;
+ DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier " + this.keyboard_modifiers);
+ // FIXME - We don't do anything with the keyboard modifiers...
+ return true;
+ }
+ if (msg.type == SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
+ {
+ DEBUG > 1 && console.log("mouse motion ack");
+ this.waiting_for_ack -= SPICE_INPUT_MOTION_ACK_BUNCH;
+ return true;
+ }
+ return false;
+}
+
+
+
+function handle_mousemove(e)
+{
+ var msg = new SpiceMiniData();
+ var move;
+ if (this.sc.mouse_mode == SPICE_MOUSE_MODE_CLIENT)
+ {
+ move = new SpiceMsgcMousePosition(this.sc, e)
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
+ }
+ else
+ {
+ move = new SpiceMsgcMouseMotion(this.sc, e)
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
+ }
+ if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
+ {
+ if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH))
+ {
+ this.sc.inputs.send_msg(msg);
+ this.sc.inputs.waiting_for_ack++;
+ }
+ else
+ {
+ DEBUG > 0 && this.sc.log_info("Discarding mouse motion");
+ }
+ }
+
+ if (this.sc && this.sc.cursor && this.sc.cursor.spice_simulated_cursor)
+ {
+ this.sc.cursor.spice_simulated_cursor.style.display = 'block';
+ this.sc.cursor.spice_simulated_cursor.style.left = e.pageX - this.sc.cursor.spice_simulated_cursor.spice_hot_x + 'px';
+ this.sc.cursor.spice_simulated_cursor.style.top = e.pageY - this.sc.cursor.spice_simulated_cursor.spice_hot_y + 'px';
+ e.preventDefault();
+ }
+
+}
+
+function handle_mousedown(e)
+{
+ var press = new SpiceMsgcMousePress(this.sc, e)
+ var msg = new SpiceMiniData();
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_contextmenu(e)
+{
+ e.preventDefault();
+ return false;
+}
+
+function handle_mouseup(e)
+{
+ var release = new SpiceMsgcMouseRelease(this.sc, e)
+ var msg = new SpiceMiniData();
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_mousewheel(e)
+{
+ var press = new SpiceMsgcMousePress;
+ var release = new SpiceMsgcMouseRelease;
+ if (e.wheelDelta > 0)
+ press.button = release.button = SPICE_MOUSE_BUTTON_UP;
+ else
+ press.button = release.button = SPICE_MOUSE_BUTTON_DOWN;
+ press.buttons_state = 0;
+ release.buttons_state = 0;
+
+ var msg = new SpiceMiniData();
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
+ this.sc.inputs.send_msg(msg);
+
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_keydown(e)
+{
+ var key = new SpiceMsgcKeyDown(e)
+ var msg = new SpiceMiniData();
+ check_and_update_modifiers(e, key.code, this.sc);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_keyup(e)
+{
+ var key = new SpiceMsgcKeyUp(e)
+ var msg = new SpiceMiniData();
+ check_and_update_modifiers(e, key.code, this.sc);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state === "ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function sendCtrlAltDel()
+{
+ if (sc && sc.inputs && sc.inputs.state === "ready"){
+ var key = new SpiceMsgcKeyDown();
+ var msg = new SpiceMiniData();
+
+ update_modifier(true, KEY_LCtrl, sc);
+ update_modifier(true, KEY_Alt, sc);
+
+ key.code = KEY_KP_Decimal;
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
+ sc.inputs.send_msg(msg);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
+ sc.inputs.send_msg(msg);
+
+ if(Ctrl_state == false) update_modifier(false, KEY_LCtrl, sc);
+ if(Alt_state == false) update_modifier(false, KEY_Alt, sc);
+ }
+}
+
+function update_modifier(state, code, sc)
+{
+ var msg = new SpiceMiniData();
+ if (!state)
+ {
+ var key = new SpiceMsgcKeyUp()
+ key.code =(0x80|code);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
+ }
+ else
+ {
+ var key = new SpiceMsgcKeyDown()
+ key.code = code;
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
+ }
+
+ sc.inputs.send_msg(msg);
+}
+
+function check_and_update_modifiers(e, code, sc)
+{
+ if (Shift_state === -1)
+ {
+ Shift_state = e.shiftKey;
+ Ctrl_state = e.ctrlKey;
+ Alt_state = e.altKey;
+ Meta_state = e.metaKey;
+ }
+
+ if (code === KEY_ShiftL)
+ Shift_state = true;
+ else if (code === KEY_Alt)
+ Alt_state = true;
+ else if (code === KEY_LCtrl)
+ Ctrl_state = true;
+ else if (code === 0xE0B5)
+ Meta_state = true;
+ else if (code === (0x80|KEY_ShiftL))
+ Shift_state = false;
+ else if (code === (0x80|KEY_Alt))
+ Alt_state = false;
+ else if (code === (0x80|KEY_LCtrl))
+ Ctrl_state = false;
+ else if (code === (0x80|0xE0B5))
+ Meta_state = false;
+
+ if (sc && sc.inputs && sc.inputs.state === "ready")
+ {
+ if (Shift_state != e.shiftKey)
+ {
+ console.log("Shift state out of sync");
+ update_modifier(e.shiftKey, KEY_ShiftL, sc);
+ Shift_state = e.shiftKey;
+ }
+ if (Alt_state != e.altKey)
+ {
+ console.log("Alt state out of sync");
+ update_modifier(e.altKey, KEY_Alt, sc);
+ Alt_state = e.altKey;
+ }
+ if (Ctrl_state != e.ctrlKey)
+ {
+ console.log("Ctrl state out of sync");
+ update_modifier(e.ctrlKey, KEY_LCtrl, sc);
+ Ctrl_state = e.ctrlKey;
+ }
+ if (Meta_state != e.metaKey)
+ {
+ console.log("Meta state out of sync");
+ update_modifier(e.metaKey, 0xE0B5, sc);
+ Meta_state = e.metaKey;
+ }
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/lz.js b/src/wok/plugins/kimchi/ui/spice-html5/lz.js
new file mode 100644
index 0000000..4292eac
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/lz.js
@@ -0,0 +1,166 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** lz.js
+** Functions for handling SPICE_IMAGE_TYPE_LZ_RGB
+** Adapted from lz.c .
+**--------------------------------------------------------------------------*/
+function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
+{
+ var encoder = at;
+ var op = 0;
+ var ctrl;
+ var ctr = 0;
+
+ for (ctrl = in_buf[encoder++]; (op * 4) < out_buf.length; ctrl = in_buf[encoder++])
+ {
+ var ref = op;
+ var len = ctrl >> 5;
+ var ofs = (ctrl & 31) << 8;
+
+//if (type == LZ_IMAGE_TYPE_RGBA)
+//console.log(ctr++ + ": from " + (encoder + 28) + ", ctrl " + ctrl + ", len " + len + ", ofs " + ofs + ", op " + op);
+ if (ctrl >= 32) {
+
+ var code;
+ len--;
+
+ if (len == 7 - 1) {
+ do {
+ code = in_buf[encoder++];
+ len += code;
+ } while (code == 255);
+ }
+ code = in_buf[encoder++];
+ ofs += code;
+
+
+ if (code == 255) {
+ if ((ofs - code) == (31 << 8)) {
+ ofs = in_buf[encoder++] << 8;
+ ofs += in_buf[encoder++];
+ ofs += 8191;
+ }
+ }
+ len += 1;
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ len += 2;
+
+ ofs += 1;
+
+ ref -= ofs;
+ if (ref == (op - 1)) {
+ var b = ref;
+//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha " + out_buf[(b*4)+3] + " dupped into pixel " + op + " through pixel " + (op + len));
+ for (; len; --len) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+ out_buf[(op*4) + 3] = out_buf[(b*4)+3];
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ out_buf[(op*4) + i] = out_buf[(b*4)+i];
+ }
+ op++;
+ }
+ } else {
+//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op + " through " + (op + len) + " from " + ref);
+ for (; len; --len) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+ out_buf[(op*4) + 3] = out_buf[(ref*4)+3];
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ out_buf[(op*4) + i] = out_buf[(ref*4)+i];
+ }
+ op++; ref++;
+ }
+ }
+ } else {
+ ctrl++;
+
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
+ out_buf[(op*4) + 3] = in_buf[encoder++];
+ }
+ else
+ {
+ out_buf[(op*4) + 0] = in_buf[encoder + 2];
+ out_buf[(op*4) + 1] = in_buf[encoder + 1];
+ out_buf[(op*4) + 2] = in_buf[encoder + 0];
+ if (default_alpha)
+ out_buf[(op*4) + 3] = 255;
+ encoder += 3;
+ }
+ op++;
+
+
+ for (--ctrl; ctrl; ctrl--) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
+ out_buf[(op*4) + 3] = in_buf[encoder++];
+ }
+ else
+ {
+ out_buf[(op*4) + 0] = in_buf[encoder + 2];
+ out_buf[(op*4) + 1] = in_buf[encoder + 1];
+ out_buf[(op*4) + 2] = in_buf[encoder + 0];
+ if (default_alpha)
+ out_buf[(op*4) + 3] = 255;
+ encoder += 3;
+ }
+ op++;
+ }
+ }
+
+ }
+ return encoder - 1;
+}
+
+function convert_spice_lz_to_web(context, lz_image)
+{
+ var at;
+ if (lz_image.type === LZ_IMAGE_TYPE_RGB32 || lz_image.type === LZ_IMAGE_TYPE_RGBA)
+ {
+ var u8 = new Uint8Array(lz_image.data);
+ var ret = context.createImageData(lz_image.width, lz_image.height);
+
+ at = lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGB32, lz_image.type != LZ_IMAGE_TYPE_RGBA);
+ if (lz_image.type == LZ_IMAGE_TYPE_RGBA)
+ lz_rgb32_decompress(u8, at, ret.data, LZ_IMAGE_TYPE_RGBA, false);
+ }
+ else if (lz_image.type === LZ_IMAGE_TYPE_XXXA)
+ {
+ var u8 = new Uint8Array(lz_image.data);
+ var ret = context.createImageData(lz_image.width, lz_image.height);
+ lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGBA, false);
+ }
+ else
+ return undefined;
+
+ return ret;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/main.js b/src/wok/plugins/kimchi/ui/spice-html5/main.js
new file mode 100644
index 0000000..91f1963
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/main.js
@@ -0,0 +1,231 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceMainConn
+** This is the master Javascript class for establishing and
+** managing a connection to a Spice Server.
+**
+** Invocation: You must pass an object with properties as follows:
+** uri (required) Uri of a WebSocket listener that is
+** connected to a spice server.
+** password (required) Password to send to the spice server
+** message_id (optional) Identifier of an element in the DOM
+** where SpiceConn will write messages.
+** It will use classes spice-messages-x,
+** where x is one of info, warning, or error.
+** screen_id (optional) Identifier of an element in the DOM
+** where SpiceConn will create any new
+** client screens. This is the main UI.
+** dump_id (optional) If given, an element to use for
+** dumping every single image + canvas drawn.
+** Sometimes useful for debugging.
+** onerror (optional) If given, a function to receive async
+** errors. Note that you should also catch
+** errors for ones that occur inline
+** onagent (optional) If given, a function to be called when
+** a VD agent is connected; a good opportunity
+** to request a resize
+**
+** Throws error if there are troubles. Requires a modern (by 2012 standards)
+** browser, including WebSocket and WebSocket.binaryType == arraybuffer
+**
+**--------------------------------------------------------------------------*/
+function SpiceMainConn()
+{
+ if (typeof WebSocket === "undefined")
+ throw new Error("WebSocket unavailable. You need to use a different browser.");
+
+ SpiceConn.apply(this, arguments);
+
+}
+
+SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
+SpiceMainConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_MAIN_INIT)
+ {
+ this.log_info("Connected to " + this.ws.url);
+ this.report_success("Connected")
+ this.main_init = new SpiceMsgMainInit(msg.data);
+ this.connection_id = this.main_init.session_id;
+
+ if (DEBUG > 0)
+ {
+ // FIXME - there is a lot here we don't handle; mouse modes, agent,
+ // ram_hint, multi_media_time
+ this.log_info("session id " + this.main_init.session_id +
+ " ; display_channels_hint " + this.main_init.display_channels_hint +
+ " ; supported_mouse_modes " + this.main_init.supported_mouse_modes +
+ " ; current_mouse_mode " + this.main_init.current_mouse_mode +
+ " ; agent_connected " + this.main_init.agent_connected +
+ " ; agent_tokens " + this.main_init.agent_tokens +
+ " ; multi_media_time " + this.main_init.multi_media_time +
+ " ; ram_hint " + this.main_init.ram_hint);
+ }
+
+ this.handle_mouse_mode(this.main_init.current_mouse_mode,
+ this.main_init.supported_mouse_modes);
+
+ if (this.main_init.agent_connected)
+ this.connect_agent();
+
+ var attach = new SpiceMiniData;
+ attach.type = SPICE_MSGC_MAIN_ATTACH_CHANNELS;
+ attach.size = attach.buffer_size();
+ this.send_msg(attach);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_MOUSE_MODE)
+ {
+ var mode = new SpiceMsgMainMouseMode(msg.data);
+ DEBUG > 0 && this.log_info("Mouse supported modes " + mode.supported_modes + "; current " + mode.current_mode);
+ this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_CHANNELS_LIST)
+ {
+ var i;
+ var chans;
+ DEBUG > 0 && console.log("channels");
+ chans = new SpiceMsgChannels(msg.data);
+ for (i = 0; i < chans.channels.length; i++)
+ {
+ var conn = {
+ uri: this.ws.url,
+ parent: this,
+ connection_id : this.connection_id,
+ type : chans.channels[i].type,
+ chan_id : chans.channels[i].id
+ };
+ if (chans.channels[i].type == SPICE_CHANNEL_DISPLAY)
+ this.display = new SpiceDisplayConn(conn);
+ else if (chans.channels[i].type == SPICE_CHANNEL_INPUTS)
+ {
+ this.inputs = new SpiceInputsConn(conn);
+ this.inputs.mouse_mode = this.mouse_mode;
+ }
+ else if (chans.channels[i].type == SPICE_CHANNEL_CURSOR)
+ this.cursor = new SpiceCursorConn(conn);
+ else if (chans.channels[i].type == SPICE_CHANNEL_PLAYBACK)
+ this.cursor = new SpicePlaybackConn(conn);
+ else
+ {
+ this.log_err("Channel type " + chans.channels[i].type + " unknown.");
+ if (! ("extra_channels" in this))
+ this.extra_channels = [];
+ this.extra_channels[i] = new SpiceConn(conn);
+ }
+
+ }
+
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED ||
+ msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS)
+ {
+ this.connect_agent();
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_AGENT_DISCONNECTED)
+ {
+ this.agent_connected = false;
+ return true;
+ }
+
+ return false;
+}
+
+SpiceMainConn.prototype.stop = function(msg)
+{
+ this.state = "closing";
+
+ if (this.inputs)
+ {
+ this.inputs.cleanup();
+ this.inputs = undefined;
+ }
+
+ if (this.cursor)
+ {
+ this.cursor.cleanup();
+ this.cursor = undefined;
+ }
+
+ if (this.display)
+ {
+ this.display.cleanup();
+ this.display.destroy_surfaces();
+ this.display = undefined;
+ }
+
+ this.cleanup();
+
+ if ("extra_channels" in this)
+ for (var e in this.extra_channels)
+ this.extra_channels[e].cleanup();
+ this.extra_channels = undefined;
+}
+
+SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y)
+{
+ if (this.agent_connected > 0)
+ {
+ var monitors_config = new VDAgentMonitorsConfig(flags, width, height, depth, x, y);
+ var agent_data = new SpiceMsgcMainAgentData(VD_AGENT_MONITORS_CONFIG, monitors_config);
+ var mr = new SpiceMiniData();
+ mr.build_msg(SPICE_MSGC_MAIN_AGENT_DATA, agent_data);
+ this.send_msg(mr);
+ }
+}
+
+SpiceMainConn.prototype.connect_agent = function()
+{
+ this.agent_connected = true;
+
+ var agent_start = new SpiceMsgcMainAgentStart(0);
+ var mr = new SpiceMiniData();
+ mr.build_msg(SPICE_MSGC_MAIN_AGENT_START, agent_start);
+ this.send_msg(mr);
+
+ if (this.onagent !== undefined)
+ this.onagent(this);
+
+}
+
+SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
+{
+ this.mouse_mode = current;
+ if (current != SPICE_MOUSE_MODE_CLIENT && (supported & SPICE_MOUSE_MODE_CLIENT))
+ {
+ var mode_request = new SpiceMsgcMainMouseModeRequest(SPICE_MOUSE_MODE_CLIENT);
+ var mr = new SpiceMiniData();
+ mr.build_msg(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
+ this.send_msg(mr);
+ }
+
+ if (this.inputs)
+ this.inputs.mouse_mode = current;
+}
+
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am b/src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am
new file mode 100644
index 0000000..431ec6c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+spicepagesdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/pages
+
+dist_spicepages_DATA = $(wildcard *.html) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
new file mode 100644
index 0000000..c87f5c2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
@@ -0,0 +1,200 @@
+<!--
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+
+ --------------------------------------------------
+ Spice Javascript client template.
+ Refer to main.js for more detailed information
+ --------------------------------------------------
+
+-->
+
+<!doctype html>
+<html>
+ <head>
+
+ <!--
+ The below sources were updated according to Kimchi configuration
+ to get the Javascript and CSS files from the installed spice-html5
+ package.
+ Kimchi is not using the default spice_auto.html because Kimchi uses
+ wss:// for all connections and it is only supported by recent
+ versions of spice-html5.
+ In addition to it, Kimchi points user to the right token on URL
+ (check line 146 of this file).
+ -->
+ <title>Spice Javascript client</title>
+ <script src="spice-html5/spicearraybuffer.js"></script>
+ <script src="spice-html5/enums.js"></script>
+ <script src="spice-html5/atKeynames.js"></script>
+ <script src="spice-html5/utils.js"></script>
+ <script src="spice-html5/png.js"></script>
+ <script src="spice-html5/lz.js"></script>
+ <script src="spice-html5/quic.js"></script>
+ <script src="spice-html5/bitmap.js"></script>
+ <script src="spice-html5/spicedataview.js"></script>
+ <script src="spice-html5/spicetype.js"></script>
+ <script src="spice-html5/spicemsg.js"></script>
+ <script src="spice-html5/wire.js"></script>
+ <script src="spice-html5/spiceconn.js"></script>
+ <script src="spice-html5/display.js"></script>
+ <script src="spice-html5/main.js"></script>
+ <script src="spice-html5/inputs.js"></script>
+ <script src="spice-html5/webm.js"></script>
+ <script src="spice-html5/playback.js"></script>
+ <script src="spice-html5/simulatecursor.js"></script>
+ <script src="spice-html5/cursor.js"></script>
+ <script src="spice-html5/thirdparty/jsbn.js"></script>
+ <script src="spice-html5/thirdparty/rsa.js"></script>
+ <script src="spice-html5/thirdparty/prng4.js"></script>
+ <script src="spice-html5/thirdparty/rng.js"></script>
+ <script src="spice-html5/thirdparty/sha1.js"></script>
+ <script src="spice-html5/ticket.js"></script>
+ <script src="spice-html5/resize.js"></script>
+ <link rel="stylesheet" type="text/css" href="spice-html5/spice.css" />
+
+ <script>
+ var host = null, port = null;
+ var sc;
+
+ function spice_set_cookie(name, value, days) {
+ var date, expires;
+ date = new Date();
+ date.setTime(date.getTime() + (days*24*60*60*1000));
+ expires = "; expires=" + date.toGMTString();
+ document.cookie = name + "=" + value + expires + "; path=/";
+ };
+
+ function spice_query_var(name, defvalue) {
+ var match = RegExp('[?&]' + name + '=([^&]*)')
+ .exec(window.location.search);
+ return match ?
+ decodeURIComponent(match[1].replace(/\+/g, ' '))
+ : defvalue;
+ }
+
+ function spice_error(e)
+ {
+ disconnect();
+ }
+
+ function connect()
+ {
+ var host, port, password, scheme = "ws://", uri;
+
+ // By default, use the host and port of server that served this file
+ host = spice_query_var('host', window.location.hostname);
+
+ // Note that using the web server port only makes sense
+ // if your web server has a reverse proxy to relay the WebSocket
+ // traffic to the correct destination port.
+ var default_port = window.location.port;
+ if (!default_port) {
+ if (window.location.protocol == 'http:') {
+ default_port = 80;
+ }
+ else if (window.location.protocol == 'https:') {
+ default_port = 443;
+ }
+ }
+ port = spice_query_var('port', default_port);
+ if (window.location.protocol == 'https:') {
+ scheme = "wss://";
+ }
+
+ // If a token variable is passed in, set the parameter in a cookie.
+ // This is used by nova-spiceproxy.
+ token = spice_query_var('token', null);
+ if (token) {
+ spice_set_cookie('token', token, 1)
+ }
+
+ password = spice_query_var('password', '');
+ path = spice_query_var('path', 'websockify');
+
+ if ((!host) || (!port)) {
+ console.log("must specify host and port in URL");
+ return;
+ }
+
+ if (sc) {
+ sc.stop();
+ }
+
+ /*
+ * The following line was modified from the original one:
+ *
+ * 'uri = scheme + host + ":" + port;'
+ *
+ * to point wok.user to a specific console represented by
+ * token value.
+ */
+ uri = scheme + host + ":" + port + "/?token=" + token;
+
+ try
+ {
+ sc = new SpiceMainConn({uri: uri, screen_id: "spice-screen", dump_id: "debug-div",
+ message_id: "message-div", password: password, onerror: spice_error, onagent: agent_connected });
+ }
+ catch (e)
+ {
+ alert(e.toString());
+ disconnect();
+ }
+
+ }
+
+ function disconnect()
+ {
+ console.log(">> disconnect");
+ if (sc) {
+ sc.stop();
+ }
+ console.log("<< disconnect");
+ }
+
+ function agent_connected(sc)
+ {
+ window.addEventListener('resize', handle_resize);
+ window.spice_connection = this;
+
+ resize_helper(this);
+ }
+
+ connect();
+ </script>
+
+ </head>
+
+ <body>
+
+ <div id="login">
+ <span class="logo">SPICE</span>
+ </div>
+
+ <div id="spice-area">
+ <div id="spice-screen" class="spice-screen"></div>
+ </div>
+
+ <div id="message-div" class="spice-message"></div>
+
+ <div id="debug-div">
+ <!-- If DUMPXXX is turned on, dumped images will go here -->
+ </div>
+
+ </body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/playback.js b/src/wok/plugins/kimchi/ui/spice-html5/playback.js
new file mode 100644
index 0000000..7209fbe
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/playback.js
@@ -0,0 +1,278 @@
+"use strict";
+/*
+ Copyright (C) 2014 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpicePlaybackConn
+** Drive the Spice Playback channel (sound out)
+**--------------------------------------------------------------------------*/
+function SpicePlaybackConn()
+{
+ SpiceConn.apply(this, arguments);
+
+ this.queue = new Array();
+ this.append_okay = false;
+ this.start_time = 0;
+ this.skip_until = 0;
+ this.gap_time = 0;
+}
+
+SpicePlaybackConn.prototype = Object.create(SpiceConn.prototype);
+SpicePlaybackConn.prototype.process_channel_message = function(msg)
+{
+ if (!!!window.MediaSource)
+ {
+ this.log_err('MediaSource API is not available');
+ return false;
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_START)
+ {
+ var start = new SpiceMsgPlaybackStart(msg.data);
+
+ DEBUG > 0 && console.log("PlaybackStart; frequency " + start.frequency);
+
+ if (start.frequency != OPUS_FREQUENCY)
+ {
+ this.log_err('This player cannot handle frequency ' + start.frequency);
+ return false;
+ }
+
+ if (start.channels != OPUS_CHANNELS)
+ {
+ this.log_err('This player cannot handle ' + start.channels + ' channels');
+ return false;
+ }
+
+ if (start.format != SPICE_AUDIO_FMT_S16)
+ {
+ this.log_err('This player cannot format ' + start.format);
+ return false;
+ }
+
+ if (! this.source_buffer)
+ {
+ this.media_source = new MediaSource();
+ this.media_source.spiceconn = this;
+
+ this.audio = document.createElement("audio");
+ this.audio.setAttribute('autoplay', true);
+ this.audio.src = window.URL.createObjectURL(this.media_source);
+ document.getElementById(this.parent.screen_id).appendChild(this.audio);
+
+ this.media_source.addEventListener('sourceopen', handle_source_open, false);
+ this.media_source.addEventListener('sourceended', handle_source_ended, false);
+ this.media_source.addEventListener('sourceclosed', handle_source_closed, false);
+
+ this.bytes_written = 0;
+
+ return true;
+ }
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_DATA)
+ {
+ var data = new SpiceMsgPlaybackData(msg.data);
+
+ // If this packet has the same time as the last, just bump up by one.
+ if (this.last_data_time && data.time <= this.last_data_time)
+ {
+ // FIXME - this is arguably wrong. But delaying the transmission was worse,
+ // in initial testing. Could use more research.
+ DEBUG > 1 && console.log("Hacking time of " + data.time + " to " + this.last_data_time + 1);
+ data.time = this.last_data_time + 1;
+ }
+
+ /* Gap detection: If there has been a delay since our last packet, then audio must
+ have paused. Handling that gets tricky. In Chrome, you can seek forward,
+ but you cannot in Firefox. And seeking forward in Chrome is nice, as it keeps
+ Chrome from being overly cautious in it's buffer strategy.
+
+ So we do two things. First, we seek forward. Second, we compute how much of a gap
+ there would have been, and essentially eliminate it.
+ */
+ if (this.last_data_time && data.time >= (this.last_data_time + GAP_DETECTION_THRESHOLD))
+ {
+ this.skip_until = data.time;
+ this.gap_time = (data.time - this.start_time) -
+ (this.source_buffer.buffered.end(this.source_buffer.buffered.end.length - 1) * 1000.0).toFixed(0);
+ }
+
+ this.last_data_time = data.time;
+
+
+ DEBUG > 1 && console.log("PlaybackData; time " + data.time + "; length " + data.data.byteLength);
+
+ if (! this.source_buffer)
+ return true;
+
+ if (this.start_time == 0)
+ this.start_playback(data);
+
+ else if (data.time - this.cluster_time >= MAX_CLUSTER_TIME || this.skip_until > 0)
+ this.new_cluster(data);
+
+ else
+ this.simple_block(data, false);
+
+ if (this.skip_until > 0)
+ {
+ this.audio.currentTime = (this.skip_until - this.start_time - this.gap_time) / 1000.0;
+ this.skip_until = 0;
+ }
+
+ if (this.audio.paused)
+ this.audio.play();
+
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_MODE)
+ {
+ var mode = new SpiceMsgPlaybackMode(msg.data);
+ if (mode.mode != SPICE_AUDIO_DATA_MODE_OPUS)
+ {
+ this.log_err('This player cannot handle mode ' + mode.mode);
+ delete this.source_buffer;
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_STOP)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+SpicePlaybackConn.prototype.start_playback = function(data)
+{
+ this.start_time = data.time;
+
+ var h = new webm_Header();
+
+ var mb = new ArrayBuffer(h.buffer_size())
+
+ this.bytes_written = h.to_buffer(mb);
+
+ this.source_buffer.addEventListener('error', handle_sourcebuffer_error, false);
+ this.source_buffer.addEventListener('updateend', handle_append_buffer_done, false);
+ playback_append_buffer(this, mb);
+
+ this.new_cluster(data);
+}
+
+SpicePlaybackConn.prototype.new_cluster = function(data)
+{
+ this.cluster_time = data.time;
+
+ var c = new webm_Cluster(data.time - this.start_time - this.gap_time);
+
+ var mb = new ArrayBuffer(c.buffer_size());
+ this.bytes_written += c.to_buffer(mb);
+
+ if (this.append_okay)
+ playback_append_buffer(this, mb);
+ else
+ this.queue.push(mb);
+
+ this.simple_block(data, true);
+}
+
+SpicePlaybackConn.prototype.simple_block = function(data, keyframe)
+{
+ var sb = new webm_SimpleBlock(data.time - this.cluster_time, data.data, keyframe);
+ var mb = new ArrayBuffer(sb.buffer_size());
+
+ this.bytes_written += sb.to_buffer(mb);
+
+ if (this.append_okay)
+ playback_append_buffer(this, mb);
+ else
+ this.queue.push(mb);
+}
+
+function handle_source_open(e)
+{
+ var p = this.spiceconn;
+
+ if (p.source_buffer)
+ return;
+
+ p.source_buffer = this.addSourceBuffer(SPICE_PLAYBACK_CODEC);
+ if (! p.source_buffer)
+ {
+ p.log_err('Codec ' + SPICE_PLAYBACK_CODEC + ' not available.');
+ return;
+ }
+ p.source_buffer.spiceconn = p;
+ p.source_buffer.mode = "segments";
+
+ // FIXME - Experimentation with segments and sequences was unsatisfying.
+ // Switching to sequence did not solve our gap problem,
+ // but the browsers didn't fully support the time seek capability
+ // we would expect to gain from 'segments'.
+ // Segments worked at the time of this patch, so segments it is for now.
+
+}
+
+function handle_source_ended(e)
+{
+ var p = this.spiceconn;
+ p.log_err('Audio source unexpectedly ended.');
+}
+
+function handle_source_closed(e)
+{
+ var p = this.spiceconn;
+ p.log_err('Audio source unexpectedly closed.');
+}
+
+function handle_append_buffer_done(b)
+{
+ var p = this.spiceconn;
+ if (p.queue.length > 0)
+ {
+ var mb = p.queue.shift();
+ playback_append_buffer(p, mb);
+ }
+ else
+ p.append_okay = true;
+
+}
+
+function handle_sourcebuffer_error(e)
+{
+ var p = this.spiceconn;
+ p.log_err('source_buffer error ' + e.message);
+}
+
+function playback_append_buffer(p, b)
+{
+ try
+ {
+ p.source_buffer.appendBuffer(b);
+ p.append_okay = false;
+ }
+ catch (e)
+ {
+ p.log_err("Error invoking appendBuffer: " + e.message);
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/png.js b/src/wok/plugins/kimchi/ui/spice-html5/png.js
new file mode 100644
index 0000000..6a26151
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/png.js
@@ -0,0 +1,256 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** crc logic from rfc2083 ported to Javascript
+**--------------------------------------------------------------------------*/
+
+var rfc2083_crc_table = Array(256);
+var rfc2083_crc_table_computed = 0;
+/* Make the table for a fast CRC. */
+function rfc2083_make_crc_table()
+{
+ var c;
+ var n, k;
+ for (n = 0; n < 256; n++)
+ {
+ c = n;
+ for (k = 0; k < 8; k++)
+ {
+ if (c & 1)
+ c = ((0xedb88320 ^ (c >>> 1)) >>> 0) & 0xffffffff;
+ else
+ c = c >>> 1;
+ }
+ rfc2083_crc_table[n] = c;
+ }
+
+ rfc2083_crc_table_computed = 1;
+}
+
+/* Update a running CRC with the bytes buf[0..len-1]--the CRC
+ should be initialized to all 1's, and the transmitted value
+ is the 1's complement of the final running CRC (see the
+ crc() routine below)). */
+
+function rfc2083_update_crc(crc, u8buf, at, len)
+{
+ var c = crc;
+ var n;
+
+ if (!rfc2083_crc_table_computed)
+ rfc2083_make_crc_table();
+
+ for (n = 0; n < len; n++)
+ {
+ c = rfc2083_crc_table[(c ^ u8buf[at + n]) & 0xff] ^ (c >>> 8);
+ }
+
+ return c;
+}
+
+function rfc2083_crc(u8buf, at, len)
+{
+ return rfc2083_update_crc(0xffffffff, u8buf, at, len) ^ 0xffffffff;
+}
+
+function crc32(mb, at, len)
+{
+ var u8 = new Uint8Array(mb);
+ return rfc2083_crc(u8, at, len);
+}
+
+function PngIHDR(width, height)
+{
+ this.width = width;
+ this.height = height;
+ this.depth = 8;
+ this.type = 6;
+ this.compression = 0;
+ this.filter = 0;
+ this.interlace = 0;
+}
+
+PngIHDR.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig = at;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.buffer_size() - 12); at += 4;
+ dv.setUint8(at, 'I'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'H'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'D'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'R'.charCodeAt(0)); at++;
+ dv.setUint32(at, this.width); at += 4;
+ dv.setUint32(at, this.height); at += 4;
+ dv.setUint8(at, this.depth); at++;
+ dv.setUint8(at, this.type); at++;
+ dv.setUint8(at, this.compression); at++;
+ dv.setUint8(at, this.filter); at++;
+ dv.setUint8(at, this.interlace); at++;
+ dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 12 + 13;
+ }
+}
+
+
+function adler()
+{
+ this.s1 = 1;
+ this.s2 = 0;
+}
+
+adler.prototype.update = function(b)
+{
+ this.s1 += b;
+ this.s1 %= 65521;
+ this.s2 += this.s1;
+ this.s2 %= 65521;
+}
+
+function PngIDAT(width, height, bytes)
+{
+ if (bytes.byteLength > 65535)
+ {
+ throw new Error("Cannot handle more than 64K");
+ }
+ this.data = bytes;
+ this.width = width;
+ this.height = height;
+}
+
+PngIDAT.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig = at;
+ var x, y, i, j;
+ var dv = new SpiceDataView(a);
+ var zsum = new adler();
+ dv.setUint32(at, this.buffer_size() - 12); at += 4;
+ dv.setUint8(at, 'I'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'D'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'A'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'T'.charCodeAt(0)); at++;
+
+ /* zlib header. */
+ dv.setUint8(at, 0x78); at++;
+ dv.setUint8(at, 0x01); at++;
+
+ /* Deflate header. Specifies uncompressed, final bit */
+ dv.setUint8(at, 0x80); at++;
+ dv.setUint16(at, this.data.byteLength + this.height); at += 2;
+ dv.setUint16(at, ~(this.data.byteLength + this.height)); at += 2;
+ var u8 = new Uint8Array(this.data);
+ for (i = 0, y = 0; y < this.height; y++)
+ {
+ /* Filter type 0 - uncompressed */
+ dv.setUint8(at, 0); at++;
+ zsum.update(0);
+ for (x = 0; x < this.width && i < this.data.byteLength; x++)
+ {
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ }
+ }
+
+ /* zlib checksum. */
+ dv.setUint16(at, zsum.s2); at+=2;
+ dv.setUint16(at, zsum.s1); at+=2;
+
+ /* FIXME - something is not quite right with the zlib code;
+ you get an error from libpng if you open the image in
+ gimp. But it works, so it's good enough for now... */
+
+ dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 12 + this.data.byteLength + this.height + 4 + 2 + 1 + 2 + 2;
+ }
+}
+
+
+function PngIEND()
+{
+}
+
+PngIEND.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig = at;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.buffer_size() - 12); at += 4;
+ dv.setUint8(at, 'I'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'E'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'N'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'D'.charCodeAt(0)); at++;
+ dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 12;
+ }
+}
+
+
+function create_rgba_png(width, height, bytes)
+{
+ var i;
+ var ihdr = new PngIHDR(width, height);
+ var idat = new PngIDAT(width, height, bytes);
+ var iend = new PngIEND;
+
+ var mb = new ArrayBuffer(ihdr.buffer_size() + idat.buffer_size() + iend.buffer_size());
+ var at = ihdr.to_buffer(mb);
+ at = idat.to_buffer(mb, at);
+ at = iend.to_buffer(mb, at);
+
+ var u8 = new Uint8Array(mb);
+ var str = "";
+ for (i = 0; i < at; i++)
+ {
+ str += "%";
+ if (u8[i] < 16)
+ str += "0";
+ str += u8[i].toString(16);
+ }
+
+
+ return "%89PNG%0D%0A%1A%0A" + str;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/quic.js b/src/wok/plugins/kimchi/ui/spice-html5/quic.js
new file mode 100644
index 0000000..9bb9f47
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/quic.js
@@ -0,0 +1,1335 @@
+/*"use strict";*/
+/* use strict is commented out because it results in a 5x slowdone in chrome */
+/*
+ * Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+ * Copyright (C) 2012 by Aric Stewart <aric at codeweavers.com>
+ *
+ * This file is part of spice-html5.
+ *
+ * spice-html5 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * spice-html5 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+var encoder;
+
+var QUIC_IMAGE_TYPE_INVALID = 0;
+var QUIC_IMAGE_TYPE_GRAY = 1;
+var QUIC_IMAGE_TYPE_RGB16 = 2;
+var QUIC_IMAGE_TYPE_RGB24 = 3;
+var QUIC_IMAGE_TYPE_RGB32 = 4;
+var QUIC_IMAGE_TYPE_RGBA = 5;
+var DEFevol = 3;
+var DEFwmimax = 6;
+var DEFwminext = 2048;
+var need_init = true;
+var DEFmaxclen = 26;
+var evol = DEFevol;
+var wmimax = DEFwmimax;
+var wminext = DEFwminext;
+var family_5bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
+ notGRcwlen:[0,0,0,0,0,0,0,0],
+ notGRprefixmask:[0,0,0,0,0,0,0,0],
+ notGRsuffixlen:[0,0,0,0,0,0,0,0],
+ xlatU2L:[0,0,0,0,0,0,0,0],
+ xlatL2U:[0,0,0,0,0,0,0,0]
+ };
+var family_8bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
+ notGRcwlen:[0,0,0,0,0,0,0,0],
+ notGRprefixmask:[0,0,0,0,0,0,0,0],
+ notGRsuffixlen:[0,0,0,0,0,0,0,0],
+ xlatU2L:[0,0,0,0,0,0,0,0],
+ xlatL2U:[0,0,0,0,0,0,0,0]
+ };
+var bppmask = [ 0x00000000,
+ 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
+ 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
+ 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
+ 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
+ 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
+ 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
+ 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
+ 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff];
+
+var zeroLUT = [];
+
+var besttrigtab = [
+ [ 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160],
+ [ 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140],
+ [ 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160]];
+
+var J = [ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 9, 10, 11, 12, 13, 14, 15];
+
+var lzeroes = [
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0];
+
+var tabrand_chaos = [
+ 0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052,
+ 0x57329b28, 0x2993868e, 0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac,
+ 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b, 0x9e3dce44, 0xdaabee13,
+ 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
+ 0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e,
+ 0xedd58794, 0xc5076689, 0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9,
+ 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45, 0x600bde29, 0xf3971ace,
+ 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
+ 0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136,
+ 0xf1840e7e, 0x6a6048c1, 0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d,
+ 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0, 0x8f9d8604, 0x4f86e73b,
+ 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
+ 0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee,
+ 0x92826ddf, 0x284bec73, 0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b,
+ 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76, 0xfc6fac0a, 0xce927e9b,
+ 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
+ 0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0,
+ 0xb7e8d590, 0xbe807feb, 0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c,
+ 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be, 0xb4805c77, 0x00c880fa,
+ 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
+ 0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf,
+ 0x29f8c9fb, 0x53dd6880, 0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119,
+ 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4, 0xc2b8a563, 0x94f2f741,
+ 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
+ 0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b,
+ 0xd161043e, 0x5d2fa2e2, 0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34,
+ 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d, 0xccb01948, 0x8d168df7,
+ 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
+ 0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098,
+ 0xce81675a, 0x4b372f7d, 0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6,
+ 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef, 0x80020447, 0x67976491,
+ 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
+ 0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d,
+ 0x624a78b4, 0x30dbee1b, 0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff,
+ 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4, 0x49e54438, 0x2f2577e6,
+ 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
+ 0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65,
+ 0xe0893818, 0x9e00a16a, 0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e,
+ 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97, 0x923a9559, 0x37a7a1f6,
+ 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
+ 0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649,
+ 0xdc0a36c0, 0x61cf2bba, 0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d,
+ 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5 ];
+
+var rgb32_pixel_pad = 3;
+var rgb32_pixel_r = 2;
+var rgb32_pixel_g = 1;
+var rgb32_pixel_b = 0;
+var rgb32_pixel_size = 4;
+
+/* Helper Functions */
+
+function ceil_log_2(val)
+{
+ if (val === 1)
+ return 0;
+
+ var result = 1;
+ val -= 1;
+ while (val = val >>> 1)
+ result++;
+
+ return result;
+}
+
+function family_init(family, bpc, limit)
+{
+ var l;
+ for (l = 0; l < bpc; l++)
+ {
+ var altprefixlen, altcodewords;
+ altprefixlen = limit - bpc;
+ if (altprefixlen > bppmask[bpc - l])
+ altprefixlen = bppmask[bpc - l];
+
+ altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
+ family.nGRcodewords[l] = (altprefixlen << l);
+ family.notGRcwlen[l] = altprefixlen + ceil_log_2(altcodewords);
+ family.notGRprefixmask[l] = bppmask[32 - altprefixlen]>>>0;
+ family.notGRsuffixlen[l] = ceil_log_2(altcodewords);
+ }
+
+ /* decorelate_init */
+ var pixelbitmask = bppmask[bpc];
+ var pixelbitmaskshr = pixelbitmask >>> 1;
+ var s;
+ for (s = 0; s <= pixelbitmask; s++) {
+ if (s <= pixelbitmaskshr) {
+ family.xlatU2L[s] = s << 1;
+ } else {
+ family.xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
+ }
+ }
+
+ /* corelate_init */
+ for (s = 0; s <= pixelbitmask; s++) {
+ if (s & 0x01) {
+ family.xlatL2U[s] = pixelbitmask - (s >>> 1);
+ } else {
+ family.xlatL2U[s] = (s >>> 1);
+ }
+ }
+}
+
+function quic_image_bpc(type)
+{
+ switch (type) {
+ case QUIC_IMAGE_TYPE_GRAY:
+ return 8;
+ case QUIC_IMAGE_TYPE_RGB16:
+ return 5;
+ case QUIC_IMAGE_TYPE_RGB24:
+ return 8;
+ case QUIC_IMAGE_TYPE_RGB32:
+ return 8;
+ case QUIC_IMAGE_TYPE_RGBA:
+ return 8;
+ case QUIC_IMAGE_TYPE_INVALID:
+ default:
+ console.log("quic: bad image type\n");
+ return 0;
+ }
+}
+
+function cnt_l_zeroes(bits)
+{
+ if (bits & 0xff800000) {
+ return lzeroes[bits >>> 24];
+ } else if (bits & 0xffff8000) {
+ return 8 + lzeroes[(bits >>> 16) & 0x000000ff];
+ } else if (bits & 0xffffff80) {
+ return 16 + lzeroes[(bits >>> 8) & 0x000000ff];
+ } else {
+ return 24 + lzeroes[bits & 0x000000ff];
+ }
+}
+
+function golomb_decoding_8bpc(l, bits)
+{
+ var rc;
+ var cwlen;
+
+ if (bits < 0 || bits > family_8bpc.notGRprefixmask[l])
+ {
+ var zeroprefix = cnt_l_zeroes(bits);
+ cwlen = zeroprefix + 1 + l;
+ rc = (zeroprefix << l) | (bits >> (32-cwlen)) & bppmask[l];
+ }
+ else
+ {
+ cwlen = family_8bpc.notGRcwlen[l];
+ rc = family_8bpc.nGRcodewords[l] + ((bits >> (32-cwlen)) & bppmask[family_8bpc.notGRsuffixlen[l]]);
+ }
+ return {'codewordlen':cwlen, 'rc':rc};
+}
+
+function golomb_code_len_8bpc(n, l)
+{
+ if (n < family_8bpc.nGRcodewords[l]) {
+ return (n >>> l) + 1 + l;
+ } else {
+ return family_8bpc.notGRcwlen[l];
+ }
+}
+
+function QuicModel(bpc)
+{
+ var bstart;
+ var bend = 0;
+
+ this.levels = 0x1 << bpc;
+ this.n_buckets_ptrs = 0;
+
+ switch (evol) {
+ case 1:
+ this.repfirst = 3;
+ this.firstsize = 1;
+ this.repnext = 2;
+ this.mulsize = 2;
+ break;
+ case 3:
+ this.repfirst = 1;
+ this.firstsize = 1;
+ this.repnext = 1;
+ this.mulsize = 2;
+ break;
+ case 5:
+ this.repfirst = 1;
+ this.firstsize = 1;
+ this.repnext = 1;
+ this.mulsize = 4;
+ break;
+ case 0:
+ case 2:
+ case 4:
+ console.log("quic: findmodelparams(): evol value obsolete!!!\n");
+ default:
+ console.log("quic: findmodelparams(): evol out of range!!!\n");
+ }
+
+ this.n_buckets = 0;
+ var repcntr = this.repfirst + 1;
+ var bsize = this.firstsize;
+
+ do {
+ if (this.n_buckets) {
+ bstart = bend + 1;
+ } else {
+ bstart = 0;
+ }
+
+ if (!--repcntr) {
+ repcntr = this.repnext;
+ bsize *= this.mulsize;
+ }
+
+ bend = bstart + bsize - 1;
+ if (bend + bsize >= this.levels) {
+ bend = this.levels - 1;
+ }
+
+ if (!this.n_buckets_ptrs) {
+ this.n_buckets_ptrs = this.levels;
+ }
+
+ (this.n_buckets)++;
+ } while (bend < this.levels - 1);
+}
+
+QuicModel.prototype = {
+ n_buckets : 0,
+ n_buckets_ptrs : 0,
+ repfirst : 0,
+ firstsize : 0,
+ repnext : 0,
+ mulsize : 0,
+ levels :0
+}
+
+function QuicBucket()
+{
+ this.counters = [0,0,0,0,0,0,0,0];
+}
+
+QuicBucket.prototype = {
+ bestcode: 0,
+
+ reste : function (bpp)
+ {
+ this.bestcode = bpp;
+ this.counters = [0,0,0,0,0,0,0,0];
+ },
+
+ update_model_8bpc : function (state, curval, bpp)
+ {
+ var i;
+
+ var bestcode = bpp - 1;
+ var bestcodelen = (this.counters[bestcode] += golomb_code_len_8bpc(curval, bestcode));
+
+ for (i = bpp - 2; i >= 0; i--) {
+ var ithcodelen = (this.counters[i] += golomb_code_len_8bpc(curval, i));
+
+ if (ithcodelen < bestcodelen) {
+ bestcode = i;
+ bestcodelen = ithcodelen;
+ }
+ }
+
+ this.bestcode = bestcode;
+
+ if (bestcodelen > state.wm_trigger) {
+ for (i = 0; i < bpp; i++) {
+ this.counters[i] = this.counters[i] >>> 1;
+ }
+ }
+ }
+}
+
+function QuicFamilyStat()
+{
+ this.buckets_ptrs = [];
+ this.buckets_buf = [];
+}
+
+QuicFamilyStat.prototype = {
+
+ fill_model_structures : function(model)
+ {
+ var bstart;
+ var bend = 0;
+ var bnumber = 0;
+
+ var repcntr = model.repfirst + 1;
+ var bsize = model.firstsize;
+
+ do {
+ if (bnumber) {
+ bstart = bend + 1;
+ } else {
+ bstart = 0;
+ }
+
+ if (!--repcntr) {
+ repcntr = model.repnext;
+ bsize *= model.mulsize;
+ }
+
+ bend = bstart + bsize - 1;
+ if (bend + bsize >= model.levels) {
+ bend = model.levels - 1;
+ }
+
+ this.buckets_buf[bnumber] = new QuicBucket;
+
+ var i;
+ for (i = bstart; i <= bend; i++) {
+ this.buckets_ptrs[i] = this.buckets_buf[bnumber];
+ }
+
+ bnumber++;
+ } while (bend < model.levels - 1);
+ return true;
+ }
+}
+
+function QuicChannel(model_8bpc, model_5bpc)
+{
+ this.state = new CommonState;
+ this.family_stat_8bpc = new QuicFamilyStat;
+ this.family_stat_5bpc = new QuicFamilyStat;
+ this.correlate_row = { zero: 0 , row:[] };
+ this.model_8bpc = model_8bpc;
+ this.model_5bpc = model_5bpc;
+ this.buckets_ptrs = [];
+
+ if (!this.family_stat_8bpc.fill_model_structures(this.model_8bpc))
+ return undefined;
+
+ if (!this.family_stat_5bpc.fill_model_structures(this.model_5bpc))
+ return undefined;
+}
+
+QuicChannel.prototype = {
+
+ reste : function (bpc)
+ {
+ var j;
+ this.correlate_row = { zero: 0 , row: []};
+
+ if (bpc == 8) {
+ for (j = 0; j < this.model_8bpc.n_buckets; j++)
+ this.family_stat_8bpc.buckets_buf[j].reste(7);
+ this.buckets_ptrs = this.family_stat_8bpc.buckets_ptrs;
+ } else if (bpc == 5) {
+ for (j = 0; j < this.model_5bpc.n_buckets; j++)
+ this.family_stat_8bpc.buckets_buf[j].reste(4);
+ this.buckets_ptrs = this.family_stat_5bpc.buckets_ptrs;
+ } else {
+ console.log("quic: %s: bad bpc %d\n", __FUNCTION__, bpc);
+ return false;
+ }
+
+ this.state.reste();
+ return true;
+ }
+}
+
+function CommonState()
+{
+}
+
+CommonState.prototype = {
+ waitcnt: 0,
+ tabrand_seed: 0xff,
+ wm_trigger: 0,
+ wmidx: 0,
+ wmileft: wminext,
+ melcstate: 0,
+ melclen: 0,
+ melcorder: 0,
+
+ set_wm_trigger : function()
+ {
+ var wm = this.wmidx;
+ if (wm > 10) {
+ wm = 10;
+ }
+
+ this.wm_trigger = besttrigtab[Math.floor(evol / 2)][wm];
+ },
+
+ reste : function()
+ {
+ this.waitcnt = 0;
+ this.tabrand_seed = 0x0ff;
+ this.wmidx = 0;
+ this.wmileft = wminext;
+
+ this.set_wm_trigger();
+
+ this.melcstate = 0;
+ this.melclen = J[0];
+ this.melcorder = 1 << this.melclen;
+ },
+
+ tabrand : function()
+ {
+ this.tabrand_seed++;
+ return tabrand_chaos[this.tabrand_seed & 0x0ff];
+ }
+}
+
+
+function QuicEncoder()
+{
+ this.rgb_state = new CommonState;
+ this.model_8bpc = new QuicModel(8);
+ this.model_5bpc = new QuicModel(5);
+ this.channels = [];
+
+ var i;
+ for (i = 0; i < 4; i++) {
+ this.channels[i] = new QuicChannel(this.model_8bpc, this.model_5bpc);
+ if (!this.channels[i])
+ {
+ console.log("quic: failed to create channel");
+ return undefined;
+ }
+ }
+}
+
+QuicEncoder.prototype = {
+ type: 0,
+ width: 0,
+ height: 0,
+ io_idx: 0,
+ io_available_bits: 0,
+ io_word: 0,
+ io_next_word: 0,
+ io_now: 0,
+ io_end: 0,
+ rows_completed: 0,
+ };
+
+QuicEncoder.prototype.reste = function(io_ptr)
+{
+ this.rgb_state.reste();
+
+ this.io_now = io_ptr;
+ this.io_end = this.io_now.length;
+ this.io_idx = 0;
+ this.rows_completed = 0;
+ return true;
+}
+
+QuicEncoder.prototype.read_io_word = function()
+{
+ if (this.io_idx >= this.io_end)
+ throw("quic: out of data");
+ this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8 | this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
+}
+
+QuicEncoder.prototype.decode_eatbits = function (len)
+{
+ this.io_word = this.io_word << len;
+
+ var delta = (this.io_available_bits - len);
+ if (delta >= 0)
+ {
+ this.io_available_bits = delta;
+ this.io_word |= this.io_next_word >>> this.io_available_bits;
+ }
+ else
+ {
+ delta = -1 * delta;
+ this.io_word |= this.io_next_word << delta;
+ this.read_io_word();
+ this.io_available_bits = 32 - delta;
+ this.io_word |= this.io_next_word >>> this.io_available_bits;
+ }
+}
+
+QuicEncoder.prototype.decode_eat32bits = function()
+{
+ this.decode_eatbits(16);
+ this.decode_eatbits(16);
+}
+
+QuicEncoder.prototype.reste_channels = function(bpc)
+{
+ var i;
+
+ for (i = 0; i < 4; i++)
+ if (!this.channels[i].reste(bpc))
+ return false;
+ return true;
+}
+
+QuicEncoder.prototype.quic_decode_begin = function(io_ptr)
+{
+ if (!this.reste(io_ptr)) {
+ return false;
+ }
+
+ this.io_idx = 0;
+ this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8 | this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
+ this.io_word = this.io_next_word;
+ this.io_available_bits = 0;
+
+ var magic = this.io_word;
+ this.decode_eat32bits();
+ if (magic != 0x43495551) /*QUIC*/ {
+ console.log("quic: bad magic "+magic.toString(16));
+ return false;
+ }
+
+ var version = this.io_word;
+ this.decode_eat32bits();
+ if (version != ((0 << 16) | (0 & 0xffff))) {
+ console.log("quic: bad version "+version.toString(16));
+ return false;
+ }
+
+ this.type = this.io_word;
+ this.decode_eat32bits();
+
+ this.width = this.io_word;
+ this.decode_eat32bits();
+
+ this.height = this.io_word;
+ this.decode_eat32bits();
+
+ var bpc = quic_image_bpc(this.type);
+
+ if (!this.reste_channels(bpc))
+ return false;
+
+ return true;
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row0_seg = function (i, cur_row, end,
+ waitmask, bpc, bpc_mask)
+{
+ var stopidx;
+ var n_channels = 3;
+ var c;
+ var a;
+
+ if (!i) {
+ cur_row[rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode, this.io_word);
+ this.channels[c].correlate_row.row[0] = a.rc;
+ cur_row[2-c] = (family_8bpc.xlatL2U[a.rc]&0xFF);
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+
+ if (this.rgb_state.waitcnt) {
+ --this.rgb_state.waitcnt;
+ } else {
+ this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
+ c = 0;
+ do
+ {
+ this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[0], bpc);
+ } while (++c < n_channels);
+ }
+ stopidx = ++i + this.rgb_state.waitcnt;
+ } else {
+ stopidx = i + this.rgb_state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i - 1]].bestcode, this.io_word);
+ this.channels[c].correlate_row.row[i] = a.rc;
+ cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+ c = 0;
+ do
+ {
+ this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx - 1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx], bpc);
+ } while (++c < n_channels);
+ stopidx = i + (this.rgb_state.tabrand() & waitmask);
+ }
+
+ for (; i < end; i++) {
+ cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i - 1]].bestcode, this.io_word);
+ this.channels[c].correlate_row.row[i] = a.rc;
+ cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+ this.rgb_state.waitcnt = stopidx - end;
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row0 = function (cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <= width)) {
+ if (this.rgb_state.wmileft) {
+ this.quic_rgb32_uncompress_row0_seg(pos, cur_row,
+ pos + this.rgb_state.wmileft,
+ bppmask[this.rgb_state.wmidx],
+ bpc, bpc_mask);
+ pos += this.rgb_state.wmileft;
+ width -= this.rgb_state.wmileft;
+ }
+
+ this.rgb_state.wmidx++;
+ this.rgb_state.set_wm_trigger();
+ this.rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_rgb32_uncompress_row0_seg(pos, cur_row, pos + width,
+ bppmask[this.rgb_state.wmidx], bpc, bpc_mask);
+ if (wmimax > this.rgb_state.wmidx) {
+ this.rgb_state.wmileft -= width;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row_seg = function( prev_row, cur_row, i, end, bpc, bpc_mask)
+{
+ var n_channels = 3;
+ var waitmask = bppmask[this.rgb_state.wmidx];
+
+ var a;
+ var run_index = 0;
+ var stopidx = 0;
+ var run_end = 0;
+ var c;
+
+ if (!i)
+ {
+ cur_row[rgb32_pixel_pad] = 0;
+
+ c = 0;
+ do {
+ a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode, this.io_word);
+ this.channels[c].correlate_row.row[0] = a.rc;
+ cur_row[2-c] = (family_8bpc.xlatL2U[this.channels[c].correlate_row.row[0]] + prev_row[2-c]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+
+ if (this.rgb_state.waitcnt) {
+ --this.rgb_state.waitcnt;
+ } else {
+ this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
+ c = 0;
+ do {
+ this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[0], bpc);
+ } while (++c < n_channels);
+ }
+ stopidx = ++i + this.rgb_state.waitcnt;
+ } else {
+ stopidx = i + this.rgb_state.waitcnt;
+ }
+ for (;;) {
+ var rc = 0;
+ while (stopidx < end && !rc) {
+ for (; i <= stopidx && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+
+ if ( prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r] && prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] && prev_row[pixelm1 + rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
+ {
+ if (run_index != i && i > 2 && (cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] && cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] && cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
+ {
+ /* do run */
+ this.rgb_state.waitcnt = stopidx - i;
+ run_index = i;
+ run_end = i + this.decode_run(this.rgb_state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ cur_row[pixel+rgb32_pixel_r] = cur_row[pixelm1+rgb32_pixel_r];
+ cur_row[pixel+rgb32_pixel_g] = cur_row[pixelm1+rgb32_pixel_g];
+ cur_row[pixel+rgb32_pixel_b] = cur_row[pixelm1+rgb32_pixel_b];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + this.rgb_state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ c = 0;
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ do {
+ var cc = this.channels[c];
+ var cr = cc.correlate_row;
+
+ a = golomb_decoding_8bpc(cc.buckets_ptrs[cr.row[i-1]].bestcode, this.io_word);
+ cr.row[i] = a.rc;
+ cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+ if (rc)
+ break;
+
+ c = 0;
+ do {
+ this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx - 1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx], bpc);
+ } while (++c < n_channels);
+
+ stopidx = i + (this.rgb_state.tabrand() & waitmask);
+ }
+
+ for (; i < end && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+
+ if (prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r] && prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] && prev_row[pixelm1+rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
+ {
+ if (run_index != i && i > 2 && (cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] && cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] && cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
+ {
+ /* do run */
+ this.rgb_state.waitcnt = stopidx - i;
+ run_index = i;
+ run_end = i + this.decode_run(this.rgb_state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ cur_row[pixel+rgb32_pixel_r] = cur_row[pixelm1+rgb32_pixel_r];
+ cur_row[pixel+rgb32_pixel_g] = cur_row[pixelm1+rgb32_pixel_g];
+ cur_row[pixel+rgb32_pixel_b] = cur_row[pixelm1+rgb32_pixel_b];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + this.rgb_state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a = golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i-1]].bestcode, this.io_word);
+ this.channels[c].correlate_row.row[i] = a.rc;
+ cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+
+ if (!rc)
+ {
+ this.rgb_state.waitcnt = stopidx - end;
+ return;
+ }
+ }
+}
+
+QuicEncoder.prototype.decode_run = function(state)
+{
+ var runlen = 0;
+
+ do {
+ var hits;
+ var x = (~(this.io_word >>> 24)>>>0)&0xff;
+ var temp = zeroLUT[x];
+
+ for (hits = 1; hits <= temp; hits++) {
+ runlen += state.melcorder;
+
+ if (state.melcstate < 32) {
+ state.melclen = J[++state.melcstate];
+ state.melcorder = (1 << state.melclen);
+ }
+ }
+ if (temp != 8) {
+ this.decode_eatbits(temp + 1);
+
+ break;
+ }
+ this.decode_eatbits(8);
+ } while (true);
+
+ if (state.melclen) {
+ runlen += this.io_word >>> (32 - state.melclen);
+ this.decode_eatbits(state.melclen);
+ }
+
+ if (state.melcstate) {
+ state.melclen = J[--state.melcstate];
+ state.melcorder = (1 << state.melclen);
+ }
+
+ return runlen;
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row = function (prev_row, cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <= width)) {
+ if (this.rgb_state.wmileft) {
+ this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
+ pos + this.rgb_state.wmileft, bpc, bpc_mask);
+ pos += this.rgb_state.wmileft;
+ width -= this.rgb_state.wmileft;
+ }
+
+ this.rgb_state.wmidx++;
+ this.rgb_state.set_wm_trigger();
+ this.rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
+ pos + width, bpc, bpc_mask);
+ if (wmimax > this.rgb_state.wmidx) {
+ this.rgb_state.wmileft -= width;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row0_seg = function (channel, i,
+ correlate_row, cur_row, end, waitmask,
+ bpc, bpc_mask)
+{
+ var stopidx;
+ var a;
+
+ if (i == 0) {
+ a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode, this.io_word);
+ correlate_row.row[0] = a.rc;
+ cur_row[rgb32_pixel_pad] = family_8bpc.xlatL2U[a.rc];
+ this.decode_eatbits(a.codewordlen);
+
+ if (channel.state.waitcnt) {
+ --channel.state.waitcnt;
+ } else {
+ channel.state.waitcnt = (channel.state.tabrand() & waitmask);
+ channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state, correlate_row.row[0], bpc);
+ }
+ stopidx = ++i + channel.state.waitcnt;
+ } else {
+ stopidx = i + channel.state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ var pbucket;
+
+ for (; i <= stopidx; i++) {
+ pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
+
+ a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
+ correlate_row.row[i] = a.rc;
+ cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+
+ pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
+
+ stopidx = i + (channel.state.tabrand() & waitmask);
+ }
+
+ for (; i < end; i++) {
+ a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode, this.io_word);
+
+ correlate_row.row[i] = a.rc;
+ cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+ channel.state.waitcnt = stopidx - end;
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row0 = function(channel, cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var correlate_row = channel.correlate_row;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <= width)) {
+ if (channel.state.wmileft) {
+ this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row,
+ pos + channel.state.wmileft, bppmask[channel.state.wmidx],
+ bpc, bpc_mask);
+ pos += channel.state.wmileft;
+ width -= channel.state.wmileft;
+ }
+
+ channel.state.wmidx++;
+ channel.state.set_wm_trigger();
+ channel.state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row, pos + width,
+ bppmask[channel.state.wmidx], bpc, bpc_mask);
+ if (wmimax > channel.state.wmidx) {
+ channel.state.wmileft -= width;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row_seg = function (channel,
+ correlate_row, prev_row, cur_row, i,
+ end, bpc, bpc_mask)
+{
+ var waitmask = bppmask[channel.state.wmidx];
+ var stopidx;
+
+ var run_index = 0;
+ var run_end;
+
+ var a;
+
+ if (i == 0) {
+ a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode, this.io_word);
+
+ correlate_row.row[0] = a.rc
+ cur_row[rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + prev_row[rgb32_pixel_pad]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+
+ if (channel.state.waitcnt) {
+ --channel.state.waitcnt;
+ } else {
+ channel.state.waitcnt = (channel.state.tabrand() & waitmask);
+ channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state, correlate_row.row[0], bpc);
+ }
+ stopidx = ++i + channel.state.waitcnt;
+ } else {
+ stopidx = i + channel.state.waitcnt;
+ }
+ for (;;) {
+ var rc = 0;
+ while (stopidx < end && !rc) {
+ var pbucket;
+ for (; i <= stopidx && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+
+ if (prev_row[pixelm1+rgb32_pixel_pad] == prev_row[pixel+rgb32_pixel_pad])
+ {
+ if (run_index != i && i > 2 && cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
+ {
+ /* do run */
+ channel.state.waitcnt = stopidx - i;
+ run_index = i;
+
+ run_end = i + this.decode_run(channel.state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] = cur_row[pixelm1+rgb32_pixel_pad];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + channel.state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
+ a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
+ correlate_row.row[i] = a.rc
+ cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+ if (rc)
+ break;
+
+ pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
+
+ stopidx = i + (channel.state.tabrand() & waitmask);
+ }
+
+ for (; i < end && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+ if (prev_row[pixelm1+rgb32_pixel_pad] == prev_row[pixel+rgb32_pixel_pad])
+ {
+ if (run_index != i && i > 2 && cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
+ {
+ /* do run */
+ channel.state.waitcnt = stopidx - i;
+ run_index = i;
+
+ run_end = i + this.decode_run(channel.state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] = cur_row[pixelm1+rgb32_pixel_pad];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + channel.state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode, this.io_word);
+ correlate_row.row[i] = a.rc;
+ cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] + ((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+
+ if (!rc)
+ {
+ channel.state.waitcnt = stopidx - end;
+ return;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row = function(channel, prev_row,
+ cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var correlate_row = channel.correlate_row;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <= width)) {
+ if (channel.state.wmileft) {
+ this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row, pos,
+ pos + channel.state.wmileft, bpc, bpc_mask);
+ pos += channel.state.wmileft;
+ width -= channel.state.wmileft;
+ }
+
+ channel.state.wmidx++;
+ channel.state.set_wm_trigger();
+ channel.state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row, pos,
+ pos + width, bpc, bpc_mask);
+ if (wmimax > channel.state.wmidx) {
+ channel.state.wmileft -= width;
+ }
+ }
+}
+
+/* We need to be generating rgb32 or rgba */
+QuicEncoder.prototype.quic_decode = function(buf, stride)
+{
+ var row;
+
+ switch (this.type)
+ {
+ case QUIC_IMAGE_TYPE_RGB32:
+ case QUIC_IMAGE_TYPE_RGB24:
+ this.channels[0].correlate_row.zero = 0;
+ this.channels[1].correlate_row.zero = 0;
+ this.channels[2].correlate_row.zero = 0;
+ this.quic_rgb32_uncompress_row0(buf);
+
+ this.rows_completed++;
+ for (row = 1; row < this.height; row++)
+ {
+ var prev = buf;
+ buf = prev.subarray(stride);
+ this.channels[0].correlate_row.zero = this.channels[0].correlate_row.row[0];
+ this.channels[1].correlate_row.zero = this.channels[1].correlate_row.row[0];
+ this.channels[2].correlate_row.zero = this.channels[2].correlate_row.row[0];
+ this.quic_rgb32_uncompress_row(prev, buf);
+ this.rows_completed++;
+ };
+ break;
+ case QUIC_IMAGE_TYPE_RGB16:
+ console.log("quic: unsupported output format\n");
+ return false;
+ break;
+ case QUIC_IMAGE_TYPE_RGBA:
+ this.channels[0].correlate_row.zero = 0;
+ this.channels[1].correlate_row.zero = 0;
+ this.channels[2].correlate_row.zero = 0;
+ this.quic_rgb32_uncompress_row0(buf);
+
+ this.channels[3].correlate_row.zero = 0;
+ this.quic_four_uncompress_row0(this.channels[3], buf);
+
+ this.rows_completed++;
+ for (row = 1; row < this.height; row++) {
+ var prev = buf;
+ buf = prev.subarray(stride);
+
+ this.channels[0].correlate_row.zero = this.channels[0].correlate_row.row[0];
+ this.channels[1].correlate_row.zero = this.channels[1].correlate_row.row[0];
+ this.channels[2].correlate_row.zero = this.channels[2].correlate_row.row[0];
+ this.quic_rgb32_uncompress_row(prev, buf);
+
+ this.channels[3].correlate_row.zero = this.channels[3].correlate_row.row[0];
+ this.quic_four_uncompress_row(encoder.channels[3], prev, buf);
+ this.rows_completed++;
+ }
+ break;
+
+ case QUIC_IMAGE_TYPE_GRAY:
+ console.log("quic: unsupported output format\n");
+ return false;
+ break;
+
+ case QUIC_IMAGE_TYPE_INVALID:
+ default:
+ console.log("quic: bad image type\n");
+ return false;
+ }
+ return true;
+}
+
+QuicEncoder.prototype.simple_quic_decode = function(buf)
+{
+ var stride = 4; /* FIXME - proper stride calc please */
+ if (!this.quic_decode_begin(buf))
+ return undefined;
+ if (this.type != QUIC_IMAGE_TYPE_RGB32 && this.type != QUIC_IMAGE_TYPE_RGB24
+ && this.type != QUIC_IMAGE_TYPE_RGBA)
+ return undefined;
+ var out = new Uint8Array(this.width*this.height*4);
+ out[0] = 69;
+ if (this.quic_decode( out, (this.width * stride)))
+ return out;
+ return undefined;
+}
+
+function SpiceQuic()
+{
+}
+
+SpiceQuic.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ if (!encoder)
+ throw("quic: no quic encoder");
+ this.data_size = dv.getUint32(at, true);
+ at += 4;
+ var buf = new Uint8Array(mb.slice(at));
+ this.outptr = encoder.simple_quic_decode(buf);
+ if (this.outptr)
+ {
+ this.type = encoder.type;
+ this.width = encoder.width;
+ this.height = encoder.height;
+ }
+ at += buf.length;
+ return at;
+ },
+}
+
+function convert_spice_quic_to_web(context, spice_quic)
+{
+ var ret = context.createImageData(spice_quic.width, spice_quic.height);
+ var i;
+ for (i = 0; i < (ret.width * ret.height * 4); i+=4)
+ {
+ ret.data[i + 0] = spice_quic.outptr[i + 2];
+ ret.data[i + 1] = spice_quic.outptr[i + 1];
+ ret.data[i + 2] = spice_quic.outptr[i + 0];
+ if (spice_quic.type !== QUIC_IMAGE_TYPE_RGBA)
+ ret.data[i + 3] = 255;
+ else
+ ret.data[i + 3] = 255 - spice_quic.outptr[i + 3];
+ }
+ return ret;
+}
+
+/* Module initialization */
+if (need_init)
+{
+ need_init = false;
+
+ family_init(family_8bpc, 8, DEFmaxclen);
+ family_init(family_5bpc, 5, DEFmaxclen);
+ /* init_zeroLUT */
+ var i, j, k, l;
+
+ j = k = 1;
+ l = 8;
+ for (i = 0; i < 256; ++i) {
+ zeroLUT[i] = l;
+ --k;
+ if (k == 0) {
+ k = j;
+ --l;
+ j *= 2;
+ }
+ }
+
+ encoder = new QuicEncoder;
+
+ if (!encoder)
+ throw("quic: failed to create encoder");
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/resize.js b/src/wok/plugins/kimchi/ui/spice-html5/resize.js
new file mode 100644
index 0000000..f5410d3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/resize.js
@@ -0,0 +1,70 @@
+"use strict";
+/*
+ Copyright (C) 2014 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** resize.js
+** This bit of Javascript is a set of logic to help with window
+** resizing, using the agent channel to request screen resizes.
+**
+** It's a bit tricky, as we want to wait for resizing to settle down
+** before sending a size. Further, while horizontal resizing to use the whole
+** browser width is fairly easy to arrange with css, resizing an element to use
+** the whole vertical space (or to force a middle div to consume the bulk of the browser
+** window size) is tricky, and the consensus seems to be that Javascript is
+** the only right way to do it.
+**--------------------------------------------------------------------------*/
+function resize_helper(sc)
+{
+ var w = document.getElementById(sc.screen_id).clientWidth;
+ var h = document.getElementById(sc.screen_id).clientHeight;
+
+ var m = document.getElementById(sc.message_id);
+
+ /* Resize vertically; basically we leave a 20 pixel margin
+ at the bottom, and use the position of the message window
+ to figure out how to resize */
+ var hd = window.innerHeight - m.offsetHeight - m.offsetTop - 20;
+
+ /* Xorg requires height be a multiple of 8; round up */
+ h = h + hd;
+ if (h % 8 > 0)
+ h += (8 - (h % 8));
+
+ /* Xorg requires width be a multiple of 8; round up */
+ if (w % 8 > 0)
+ w += (8 - (w % 8));
+
+
+ sc.resize_window(0, w, h, 32, 0, 0);
+ sc.spice_resize_timer = undefined;
+}
+
+function handle_resize(e)
+{
+ var sc = window.spice_connection;
+
+ if (sc && sc.spice_resize_timer)
+ {
+ window.clearTimeout(sc.spice_resize_timer);
+ sc.spice_resize_timer = undefined;
+ }
+
+ sc.spice_resize_timer = window.setTimeout(resize_helper, 200, sc);
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js b/src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js
new file mode 100644
index 0000000..b1fce06
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js
@@ -0,0 +1,202 @@
+"use strict";
+/*
+ Copyright (C) 2013 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceSimulateCursor
+** Internet Explorer 10 does not support data uri's in cursor assignment.
+** This file provides a number of gimmicks to compensate. First, if there
+** is a preloaded cursor available, we will use that. Failing that, we will
+** simulate a cursor using an image that is moved around the screen.
+**--------------------------------------------------------------------------*/
+var SpiceSimulateCursor = {
+
+cursors : new Array(),
+unknown_cursors : new Array(),
+warned: false,
+
+add_cursor: function(sha1, value)
+{
+ SpiceSimulateCursor.cursors[sha1] = value;
+},
+
+unknown_cursor: function(sha1, curdata)
+{
+ if (! SpiceSimulateCursor.warned)
+ {
+ SpiceSimulateCursor.warned = true;
+ alert("Internet Explorer does not support dynamic cursors. " +
+ "This page will now simulate cursors with images, " +
+ "which will be imperfect. We recommend using Chrome or Firefox instead. " +
+ "\n\nIf you need to use Internet Explorer, you can create a static cursor " +
+ "file for each cursor your application uses. " +
+ "View the console log for more information on creating static cursors for your environment.");
+ }
+
+ if (! SpiceSimulateCursor.unknown_cursors[sha1])
+ {
+ SpiceSimulateCursor.unknown_cursors[sha1] = curdata;
+ console.log('Unknown cursor. Simulation required. To avoid simulation for this cursor, create and include a custom javascript file, and add the following line:');
+ console.log('SpiceCursorSimulator.add_cursor("' + sha1 + '"), "<your filename here>.cur");');
+ console.log('And then run following command, redirecting output into <your filename here>.cur:');
+ console.log('php -r "echo urldecode(\'' + curdata + '\');"');
+ }
+},
+
+simulate_cursor: function (spicecursor, cursor, screen, pngstr)
+{
+ var cursor_sha = hex_sha1(pngstr + ' ' + cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y);
+ if (typeof SpiceSimulateCursor.cursors != 'undefined')
+ if (typeof SpiceSimulateCursor.cursors[cursor_sha] != 'undefined')
+ {
+ var curstr = 'url(' + SpiceSimulateCursor.cursors[cursor_sha] + '), default';
+ screen.style.cursor = curstr;
+ }
+
+ if (window.getComputedStyle(screen, null).cursor == 'auto')
+ {
+ SpiceSimulateCursor.unknown_cursor(cursor_sha,
+ SpiceSimulateCursor.create_icondir(cursor.header.width, cursor.header.height,
+ cursor.data.byteLength, cursor.header.hot_spot_x, cursor.header.hot_spot_y) + pngstr);
+
+ document.getElementById(spicecursor.parent.screen_id).style.cursor = 'none';
+ if (! spicecursor.spice_simulated_cursor)
+ {
+ spicecursor.spice_simulated_cursor = document.createElement('img');
+
+ spicecursor.spice_simulated_cursor.style.position = 'absolute';
+ spicecursor.spice_simulated_cursor.style.display = 'none';
+ spicecursor.spice_simulated_cursor.style.overflow = 'hidden';
+
+ spicecursor.spice_simulated_cursor.spice_screen = document.getElementById(spicecursor.parent.screen_id);
+
+ spicecursor.spice_simulated_cursor.addEventListener('mousemove', SpiceSimulateCursor.handle_sim_mousemove);
+
+ spicecursor.spice_simulated_cursor.spice_screen.appendChild(spicecursor.spice_simulated_cursor);
+ }
+
+ spicecursor.spice_simulated_cursor.src = 'data:image/png,' + pngstr;
+
+ spicecursor.spice_simulated_cursor.spice_hot_x = cursor.header.hot_spot_x;
+ spicecursor.spice_simulated_cursor.spice_hot_y = cursor.header.hot_spot_y;
+
+ spicecursor.spice_simulated_cursor.style.pointerEvents = "none";
+ }
+ else
+ {
+ if (spicecursor.spice_simulated_cursor)
+ {
+ spicecursor.spice_simulated_cursor.spice_screen.removeChild(spicecursor.spice_simulated_cursor);
+ delete spicecursor.spice_simulated_cursor;
+ }
+ }
+},
+
+handle_sim_mousemove: function(e)
+{
+ var retval;
+ var f = SpiceSimulateCursor.duplicate_mouse_event(e, this.spice_screen);
+ return this.spice_screen.dispatchEvent(f);
+},
+
+duplicate_mouse_event: function(e, target)
+{
+ var evt = document.createEvent("mouseevent");
+ evt.initMouseEvent(e.type, true, true, e.view, e.detail,
+ e.screenX, e.screenY, e.clientX, e.clientY,
+ e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
+ return evt;
+},
+
+ICONDIR: function ()
+{
+},
+
+ICONDIRENTRY: function(width, height, bytes, hot_x, hot_y)
+{
+ this.width = width;
+ this.height = height;
+ this.bytes = bytes;
+ this.hot_x = hot_x;
+ this.hot_y = hot_y;
+},
+
+
+create_icondir: function (width, height, bytes, hot_x, hot_y)
+{
+ var i;
+ var header = new SpiceSimulateCursor.ICONDIR();
+ var entry = new SpiceSimulateCursor.ICONDIRENTRY(width, height, bytes, hot_x, hot_y);
+
+ var mb = new ArrayBuffer(header.buffer_size() + entry.buffer_size());
+ var at = header.to_buffer(mb);
+ at = entry.to_buffer(mb, at);
+
+ var u8 = new Uint8Array(mb);
+ var str = "";
+ for (i = 0; i < at; i++)
+ {
+ str += "%";
+ if (u8[i] < 16)
+ str += "0";
+ str += u8[i].toString(16);
+ }
+ return str;
+},
+
+};
+
+SpiceSimulateCursor.ICONDIR.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint16(at, 0, true); at += 2;
+ dv.setUint16(at, 2, true); at += 2;
+ dv.setUint16(at, 1, true); at += 2;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 6;
+ }
+};
+
+SpiceSimulateCursor.ICONDIRENTRY.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint8(at, this.width); at++;
+ dv.setUint8(at, this.height); at++;
+ dv.setUint8(at, 0); at++; /* color palette count, unused */
+ dv.setUint8(at, 0); at++; /* reserved */
+ dv.setUint16(at, this.hot_x, true); at += 2;
+ dv.setUint16(at, this.hot_y, true); at += 2;
+ dv.setUint32(at, this.bytes, true); at += 4;
+ dv.setUint32(at, at + 4, true); at += 4; /* Offset to bytes */
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 16;
+ }
+};
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js b/src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
new file mode 100644
index 0000000..228bce6
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
@@ -0,0 +1,58 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceArrayBufferSlice
+** This function is a work around for IE 10, which has no slice()
+** method in it's subclass.
+**--------------------------------------------------------------------------*/
+function SpiceArrayBufferSlice(start, end)
+{
+ start = start || 0;
+ end = end || this.byteLength;
+ if (end < 0)
+ end = this.byteLength + end;
+ if (start < 0)
+ start = this.byteLength + start;
+ if (start < 0)
+ start = 0;
+ if (end < 0)
+ end = 0;
+ if (end > this.byteLength)
+ end = this.byteLength;
+ if (start > end)
+ start = end;
+
+ var ret = new ArrayBuffer(end - start);
+ var in1 = new Uint8Array(this, start, end - start);
+ var out = new Uint8Array(ret);
+ var i;
+
+ for (i = 0; i < end - start; i++)
+ out[i] = in1[i];
+
+ return ret;
+}
+
+if (! ArrayBuffer.prototype.slice)
+{
+ ArrayBuffer.prototype.slice = SpiceArrayBufferSlice;
+ console.log("WARNING: ArrayBuffer.slice() is missing; we are extending ArrayBuffer to compensate");
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js b/src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js
new file mode 100644
index 0000000..e33227e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js
@@ -0,0 +1,460 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceConn
+** This is the base Javascript class for establishing and
+** managing a connection to a Spice Server.
+** It is used to provide core functionality to the Spice main,
+** display, inputs, and cursor channels. See main.js for
+** usage.
+**--------------------------------------------------------------------------*/
+function SpiceConn(o)
+{
+ if (o === undefined || o.uri === undefined || ! o.uri)
+ throw new Error("You must specify a uri");
+
+ this.ws = new WebSocket(o.uri, 'binary');
+
+ if (! this.ws.binaryType)
+ throw new Error("WebSocket doesn't support binaryType. Try a different browser.");
+
+ this.connection_id = o.connection_id !== undefined ? o.connection_id : 0;
+ this.type = o.type !== undefined ? o.type : SPICE_CHANNEL_MAIN;
+ this.chan_id = o.chan_id !== undefined ? o.chan_id : 0;
+ if (o.parent !== undefined)
+ {
+ this.parent = o.parent;
+ this.message_id = o.parent.message_id;
+ this.password = o.parent.password;
+ }
+ if (o.screen_id !== undefined)
+ this.screen_id = o.screen_id;
+ if (o.dump_id !== undefined)
+ this.dump_id = o.dump_id;
+ if (o.message_id !== undefined)
+ this.message_id = o.message_id;
+ if (o.password !== undefined)
+ this.password = o.password;
+ if (o.onerror !== undefined)
+ this.onerror = o.onerror;
+ if (o.onsuccess !== undefined)
+ this.onsuccess = o.onsuccess;
+ if (o.onagent !== undefined)
+ this.onagent = o.onagent;
+
+ this.state = "connecting";
+ this.ws.parent = this;
+ this.wire_reader = new SpiceWireReader(this, this.process_inbound);
+ this.messages_sent = 0;
+ this.warnings = [];
+
+ this.ws.addEventListener('open', function(e) {
+ DEBUG > 0 && console.log(">> WebSockets.onopen");
+ DEBUG > 0 && console.log("id " + this.parent.connection_id +"; type " + this.parent.type);
+
+ /***********************************************************************
+ ** WHERE IT ALL REALLY BEGINS
+ ***********************************************************************/
+ this.parent.send_hdr();
+ this.parent.wire_reader.request(SpiceLinkHeader.prototype.buffer_size());
+ this.parent.state = "start";
+ });
+ this.ws.addEventListener('error', function(e) {
+ this.parent.log_err(">> WebSockets.onerror" + e.toString());
+ this.parent.report_error(e);
+ });
+ this.ws.addEventListener('close', function(e) {
+ DEBUG > 0 && console.log(">> WebSockets.onclose");
+ DEBUG > 0 && console.log("id " + this.parent.connection_id +"; type " + this.parent.type);
+ DEBUG > 0 && console.log(e);
+ if (this.parent.state != "closing" && this.parent.state != "error" && this.parent.onerror !== undefined)
+ {
+ var e;
+ if (this.parent.state == "connecting")
+ e = new Error("Connection refused.");
+ else if (this.parent.state == "start" || this.parent.state == "link")
+ e = new Error("Unexpected protocol mismatch.");
+ else if (this.parent.state == "ticket")
+ e = new Error("Bad password.");
+ else
+ e = new Error("Unexpected close while " + this.parent.state);
+
+ this.parent.onerror(e);
+ this.parent.log_err(e.toString());
+ }
+ });
+
+ if (this.ws.readyState == 2 || this.ws.readyState == 3)
+ throw new Error("Unable to connect to " + o.uri);
+
+ this.timeout = window.setTimeout(spiceconn_timeout, SPICE_CONNECT_TIMEOUT, this);
+}
+
+SpiceConn.prototype =
+{
+ send_hdr : function ()
+ {
+ var hdr = new SpiceLinkHeader;
+ var msg = new SpiceLinkMess;
+
+ msg.connection_id = this.connection_id;
+ msg.channel_type = this.type;
+ // FIXME - we're not setting a channel_id...
+ msg.common_caps.push(
+ (1 << SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION) |
+ (1 << SPICE_COMMON_CAP_MINI_HEADER)
+ );
+
+ if (msg.channel_type == SPICE_CHANNEL_PLAYBACK)
+ msg.channel_caps.push(
+ (1 << SPICE_PLAYBACK_CAP_OPUS)
+ );
+
+ hdr.size = msg.buffer_size();
+
+ var mb = new ArrayBuffer(hdr.buffer_size() + msg.buffer_size());
+ hdr.to_buffer(mb);
+ msg.to_buffer(mb, hdr.buffer_size());
+
+ DEBUG > 1 && console.log("Sending header:");
+ DEBUG > 2 && hexdump_buffer(mb);
+ this.ws.send(mb);
+ },
+
+ send_ticket: function(ticket)
+ {
+ var hdr = new SpiceLinkAuthTicket();
+ hdr.auth_mechanism = SPICE_COMMON_CAP_AUTH_SPICE;
+ // FIXME - we need to implement RSA to make this work right
+ hdr.encrypted_data = ticket;
+ var mb = new ArrayBuffer(hdr.buffer_size());
+
+ hdr.to_buffer(mb);
+ DEBUG > 1 && console.log("Sending ticket:");
+ DEBUG > 2 && hexdump_buffer(mb);
+ this.ws.send(mb);
+ },
+
+ send_msg: function(msg)
+ {
+ var mb = new ArrayBuffer(msg.buffer_size());
+ msg.to_buffer(mb);
+ this.messages_sent++;
+ DEBUG > 0 && console.log(">> hdr " + this.channel_type() + " type " + msg.type + " size " + mb.byteLength);
+ DEBUG > 2 && hexdump_buffer(mb);
+ this.ws.send(mb);
+ },
+
+ process_inbound: function(mb, saved_header)
+ {
+ DEBUG > 2 && console.log(this.type + ": processing message of size " + mb.byteLength + "; state is " + this.state);
+ if (this.state == "ready")
+ {
+ if (saved_header == undefined)
+ {
+ var msg = new SpiceMiniData(mb);
+
+ if (msg.type > 500)
+ {
+ alert("Something has gone very wrong; we think we have message of type " + msg.type);
+ debugger;
+ }
+
+ if (msg.size == 0)
+ {
+ this.process_message(msg);
+ this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
+ }
+ else
+ {
+ this.wire_reader.request(msg.size);
+ this.wire_reader.save_header(msg);
+ }
+ }
+ else
+ {
+ saved_header.data = mb;
+ this.process_message(saved_header);
+ this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
+ this.wire_reader.save_header(undefined);
+ }
+ }
+
+ else if (this.state == "start")
+ {
+ this.reply_hdr = new SpiceLinkHeader(mb);
+ if (this.reply_hdr.magic != SPICE_MAGIC)
+ {
+ this.state = "error";
+ var e = new Error('Error: magic mismatch: ' + this.reply_hdr.magic);
+ this.report_error(e);
+ }
+ else
+ {
+ // FIXME - Determine major/minor version requirements
+ this.wire_reader.request(this.reply_hdr.size);
+ this.state = "link";
+ }
+ }
+
+ else if (this.state == "link")
+ {
+ this.reply_link = new SpiceLinkReply(mb);
+ // FIXME - Screen the caps - require minihdr at least, right?
+ if (this.reply_link.error)
+ {
+ this.state = "error";
+ var e = new Error('Error: reply link error ' + this.reply_link.error);
+ this.report_error(e);
+ }
+ else
+ {
+ this.send_ticket(rsa_encrypt(this.reply_link.pub_key, this.password + String.fromCharCode(0)));
+ this.state = "ticket";
+ this.wire_reader.request(SpiceLinkAuthReply.prototype.buffer_size());
+ }
+ }
+
+ else if (this.state == "ticket")
+ {
+ this.auth_reply = new SpiceLinkAuthReply(mb);
+ if (this.auth_reply.auth_code == SPICE_LINK_ERR_OK)
+ {
+ DEBUG > 0 && console.log(this.type + ': Connected');
+
+ if (this.type == SPICE_CHANNEL_DISPLAY)
+ {
+ // FIXME - pixmap and glz dictionary config info?
+ var dinit = new SpiceMsgcDisplayInit();
+ var reply = new SpiceMiniData();
+ reply.build_msg(SPICE_MSGC_DISPLAY_INIT, dinit);
+ DEBUG > 0 && console.log("Request display init");
+ this.send_msg(reply);
+ }
+ this.state = "ready";
+ this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
+ if (this.timeout)
+ {
+ window.clearTimeout(this.timeout);
+ delete this.timeout;
+ }
+ }
+ else
+ {
+ this.state = "error";
+ if (this.auth_reply.auth_code == SPICE_LINK_ERR_PERMISSION_DENIED)
+ {
+ var e = new Error("Permission denied.");
+ }
+ else
+ {
+ var e = new Error("Unexpected link error " + this.auth_reply.auth_code);
+ }
+ this.report_error(e);
+ }
+ }
+ },
+
+ process_common_messages : function(msg)
+ {
+ if (msg.type == SPICE_MSG_SET_ACK)
+ {
+ var ack = new SpiceMsgSetAck(msg.data);
+ // FIXME - what to do with generation?
+ this.ack_window = ack.window;
+ DEBUG > 1 && console.log(this.type + ": set ack to " + ack.window);
+ this.msgs_until_ack = this.ack_window;
+ var ackack = new SpiceMsgcAckSync(ack);
+ var reply = new SpiceMiniData();
+ reply.build_msg(SPICE_MSGC_ACK_SYNC, ackack);
+ this.send_msg(reply);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_PING)
+ {
+ DEBUG > 1 && console.log("ping!");
+ var pong = new SpiceMiniData;
+ pong.type = SPICE_MSGC_PONG;
+ if (msg.data)
+ {
+ pong.data = msg.data.slice(0, 12);
+ }
+ pong.size = pong.buffer_size();
+ this.send_msg(pong);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_NOTIFY)
+ {
+ // FIXME - Visibility + what
+ var notify = new SpiceMsgNotify(msg.data);
+ if (notify.severity == SPICE_NOTIFY_SEVERITY_ERROR)
+ this.log_err(notify.message);
+ else if (notify.severity == SPICE_NOTIFY_SEVERITY_WARN )
+ this.log_warn(notify.message);
+ else
+ this.log_info(notify.message);
+ return true;
+ }
+
+ return false;
+
+ },
+
+ process_message: function(msg)
+ {
+ var rc;
+ DEBUG > 0 && console.log("<< hdr " + this.channel_type() + " type " + msg.type + " size " + (msg.data && msg.data.byteLength));
+ rc = this.process_common_messages(msg);
+ if (! rc)
+ {
+ if (this.process_channel_message)
+ {
+ rc = this.process_channel_message(msg);
+ if (! rc)
+ this.log_warn(this.type + ": Unknown message type " + msg.type + "!");
+ }
+ else
+ this.log_err(this.type + ": No message handlers for this channel; message " + msg.type);
+ }
+
+ if (this.msgs_until_ack !== undefined && this.ack_window)
+ {
+ this.msgs_until_ack--;
+ if (this.msgs_until_ack <= 0)
+ {
+ this.msgs_until_ack = this.ack_window;
+ var ack = new SpiceMiniData();
+ ack.type = SPICE_MSGC_ACK;
+ this.send_msg(ack);
+ DEBUG > 1 && console.log(this.type + ": sent ack");
+ }
+ }
+
+ return rc;
+ },
+
+ channel_type: function()
+ {
+ if (this.type == SPICE_CHANNEL_MAIN)
+ return "main";
+ else if (this.type == SPICE_CHANNEL_DISPLAY)
+ return "display";
+ else if (this.type == SPICE_CHANNEL_INPUTS)
+ return "inputs";
+ else if (this.type == SPICE_CHANNEL_CURSOR)
+ return "cursor";
+ return "unknown-" + this.type;
+
+ },
+
+ log_info: function()
+ {
+ var msg = Array.prototype.join.call(arguments, " ");
+ console.log(msg);
+ if (this.message_id)
+ {
+ var p = document.createElement("p");
+ p.appendChild(document.createTextNode(msg));
+ p.className += "spice-message-info";
+ document.getElementById(this.message_id).appendChild(p);
+ }
+ },
+
+ log_warn: function()
+ {
+ var msg = Array.prototype.join.call(arguments, " ");
+ console.log("WARNING: " + msg);
+ if (this.message_id)
+ {
+ var p = document.createElement("p");
+ p.appendChild(document.createTextNode(msg));
+ p.className += "spice-message-warning";
+ document.getElementById(this.message_id).appendChild(p);
+ }
+ },
+
+ log_err: function()
+ {
+ var msg = Array.prototype.join.call(arguments, " ");
+ console.log("ERROR: " + msg);
+ if (this.message_id)
+ {
+ var p = document.createElement("p");
+ p.appendChild(document.createTextNode(msg));
+ p.className += "spice-message-error";
+ document.getElementById(this.message_id).appendChild(p);
+ }
+ },
+
+ known_unimplemented: function(type, msg)
+ {
+ if ( (!this.warnings[type]) || DEBUG > 1)
+ {
+ var str = "";
+ if (DEBUG <= 1)
+ str = " [ further notices suppressed ]";
+ this.log_warn("Unimplemented function " + type + "(" + msg + ")" + str);
+ this.warnings[type] = true;
+ }
+ },
+
+ report_error: function(e)
+ {
+ this.log_err(e.toString());
+ if (this.onerror != undefined)
+ this.onerror(e);
+ else
+ throw(e);
+ },
+
+ report_success: function(m)
+ {
+ if (this.onsuccess != undefined)
+ this.onsuccess(m);
+ },
+
+ cleanup: function()
+ {
+ if (this.timeout)
+ {
+ window.clearTimeout(this.timeout);
+ delete this.timeout;
+ }
+ if (this.ws)
+ {
+ this.ws.close();
+ this.ws = undefined;
+ }
+ },
+
+ handle_timeout: function()
+ {
+ var e = new Error("Connection timed out.");
+ this.report_error(e);
+ },
+}
+
+function spiceconn_timeout(sc)
+{
+ SpiceConn.prototype.handle_timeout.call(sc);
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js b/src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js
new file mode 100644
index 0000000..800df03
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js
@@ -0,0 +1,120 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceDataView
+** FIXME FIXME
+** This is used because Firefox does not have DataView yet.
+** We should use DataView if we have it, because it *has* to
+** be faster than this code
+**--------------------------------------------------------------------------*/
+function SpiceDataView(buffer, byteOffset, byteLength)
+{
+ if (byteOffset !== undefined)
+ {
+ if (byteLength !== undefined)
+ this.u8 = new Uint8Array(buffer, byteOffset, byteLength);
+ else
+ this.u8 = new Uint8Array(buffer, byteOffset);
+ }
+ else
+ this.u8 = new Uint8Array(buffer);
+};
+
+SpiceDataView.prototype = {
+ getUint8: function(byteOffset)
+ {
+ return this.u8[byteOffset];
+ },
+ getUint16: function(byteOffset, littleEndian)
+ {
+ var low = 1, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 1;
+ }
+
+ return (this.u8[byteOffset + high] << 8) | this.u8[byteOffset + low];
+ },
+ getUint32: function(byteOffset, littleEndian)
+ {
+ var low = 2, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 2;
+ }
+
+ return (this.getUint16(byteOffset + high, littleEndian) << 16) |
+ this.getUint16(byteOffset + low, littleEndian);
+ },
+ getUint64: function (byteOffset, littleEndian)
+ {
+ var low = 4, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 4;
+ }
+
+ return (this.getUint32(byteOffset + high, littleEndian) << 32) |
+ this.getUint32(byteOffset + low, littleEndian);
+ },
+ setUint8: function(byteOffset, b)
+ {
+ this.u8[byteOffset] = (b & 0xff);
+ },
+ setUint16: function(byteOffset, i, littleEndian)
+ {
+ var low = 1, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 1;
+ }
+ this.u8[byteOffset + high] = (i & 0xffff) >> 8;
+ this.u8[byteOffset + low] = (i & 0x00ff);
+ },
+ setUint32: function(byteOffset, w, littleEndian)
+ {
+ var low = 2, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 2;
+ }
+
+ this.setUint16(byteOffset + high, (w & 0xffffffff) >> 16, littleEndian);
+ this.setUint16(byteOffset + low, (w & 0x0000ffff), littleEndian);
+ },
+ setUint64: function(byteOffset, w, littleEndian)
+ {
+ var low = 4, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 4;
+ }
+
+ this.setUint32(byteOffset + high, (w & 0xffffffffffffffff) >> 32, littleEndian);
+ this.setUint32(byteOffset + low, (w & 0x00000000ffffffff), littleEndian);
+ },
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js b/src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js
new file mode 100644
index 0000000..c64f5a3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js
@@ -0,0 +1,1047 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** Spice messages
+** This file contains classes for passing messages to and from
+** a spice server. This file should arguably be generated from
+** spice.proto, but it was instead put together by hand.
+**--------------------------------------------------------------------------*/
+function SpiceLinkHeader(a, at)
+{
+ this.magic = SPICE_MAGIC;
+ this.major_version = SPICE_VERSION_MAJOR;
+ this.minor_version = SPICE_VERSION_MINOR;
+ this.size = 0;
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkHeader.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.magic = "";
+ for (var i = 0; i < 4; i++)
+ this.magic += String.fromCharCode(dv.getUint8(at + i));
+ at += 4;
+
+ this.major_version = dv.getUint32(at, true); at += 4;
+ this.minor_version = dv.getUint32(at, true); at += 4;
+ this.size = dv.getUint32(at, true); at += 4;
+ },
+
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ for (var i = 0; i < 4; i++)
+ dv.setUint8(at + i, this.magic.charCodeAt(i));
+ at += 4;
+
+ dv.setUint32(at, this.major_version, true); at += 4;
+ dv.setUint32(at, this.minor_version, true); at += 4;
+ dv.setUint32(at, this.size, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 16;
+ },
+}
+
+function SpiceLinkMess(a, at)
+{
+ this.connection_id = 0;
+ this.channel_type = 0;
+ this.channel_id = 0;
+ this.common_caps = [];
+ this.channel_caps = [];
+
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkMess.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var orig_at = at;
+ var dv = new SpiceDataView(a);
+ this.connection_id = dv.getUint32(at, true); at += 4;
+ this.channel_type = dv.getUint8(at, true); at++;
+ this.channel_id = dv.getUint8(at, true); at++;
+ var num_common_caps = dv.getUint32(at, true); at += 4;
+ var num_channel_caps = dv.getUint32(at, true); at += 4;
+ var caps_offset = dv.getUint32(at, true); at += 4;
+
+ at = orig_at + caps_offset;
+ this.common_caps = [];
+ for (i = 0; i < num_common_caps; i++)
+ {
+ this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+
+ this.channel_caps = [];
+ for (i = 0; i < num_channel_caps; i++)
+ {
+ this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+ },
+
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig_at = at;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.connection_id, true); at += 4;
+ dv.setUint8(at, this.channel_type, true); at++;
+ dv.setUint8(at, this.channel_id, true); at++;
+ dv.setUint32(at, this.common_caps.length, true); at += 4;
+ dv.setUint32(at, this.channel_caps.length, true); at += 4;
+ dv.setUint32(at, (at - orig_at) + 4, true); at += 4;
+
+ for (i = 0; i < this.common_caps.length; i++)
+ {
+ dv.setUint32(at, this.common_caps[i], true); at += 4;
+ }
+
+ for (i = 0; i < this.channel_caps.length; i++)
+ {
+ dv.setUint32(at, this.channel_caps[i], true); at += 4;
+ }
+ },
+ buffer_size: function()
+ {
+ return 18 + (4 * this.common_caps.length) + (4 * this.channel_caps.length);
+ }
+}
+
+function SpiceLinkReply(a, at)
+{
+ this.error = 0;
+ this.pub_key = undefined;
+ this.common_caps = [];
+ this.channel_caps = [];
+
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkReply.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var orig_at = at;
+ var dv = new SpiceDataView(a);
+ this.error = dv.getUint32(at, true); at += 4;
+
+ this.pub_key = create_rsa_from_mb(a, at);
+ at += SPICE_TICKET_PUBKEY_BYTES;
+
+ var num_common_caps = dv.getUint32(at, true); at += 4;
+ var num_channel_caps = dv.getUint32(at, true); at += 4;
+ var caps_offset = dv.getUint32(at, true); at += 4;
+
+ at = orig_at + caps_offset;
+ this.common_caps = [];
+ for (i = 0; i < num_common_caps; i++)
+ {
+ this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+
+ this.channel_caps = [];
+ for (i = 0; i < num_channel_caps; i++)
+ {
+ this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+ },
+}
+
+function SpiceLinkAuthTicket(a, at)
+{
+ this.auth_mechanism = 0;
+ this.encrypted_data = undefined;
+}
+
+SpiceLinkAuthTicket.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.auth_mechanism, true); at += 4;
+ for (i = 0; i < SPICE_TICKET_KEY_PAIR_LENGTH / 8; i++)
+ {
+ if (this.encrypted_data && i < this.encrypted_data.length)
+ dv.setUint8(at, this.encrypted_data[i], true);
+ else
+ dv.setUint8(at, 0, true);
+ at++;
+ }
+ },
+ buffer_size: function()
+ {
+ return 4 + (SPICE_TICKET_KEY_PAIR_LENGTH / 8);
+ }
+}
+
+function SpiceLinkAuthReply(a, at)
+{
+ this.auth_code = 0;
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkAuthReply.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.auth_code = dv.getUint32(at, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMiniData(a, at)
+{
+ this.type = 0;
+ this.size = 0;
+ this.data = undefined;
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceMiniData.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ this.type = dv.getUint16(at, true); at += 2;
+ this.size = dv.getUint32(at, true); at += 4;
+ if (a.byteLength > at)
+ {
+ this.data = a.slice(at);
+ at += this.data.byteLength;
+ }
+ },
+ to_buffer : function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint16(at, this.type, true); at += 2;
+ dv.setUint32(at, this.data ? this.data.byteLength : 0, true); at += 4;
+ if (this.data && this.data.byteLength > 0)
+ {
+ var u8arr = new Uint8Array(this.data);
+ for (i = 0; i < u8arr.length; i++, at++)
+ dv.setUint8(at, u8arr[i], true);
+ }
+ },
+ build_msg : function(in_type, extra)
+ {
+ this.type = in_type;
+ this.size = extra.buffer_size();
+ this.data = new ArrayBuffer(this.size);
+ extra.to_buffer(this.data);
+ },
+ buffer_size: function()
+ {
+ if (this.data)
+ return 6 + this.data.byteLength;
+ else
+ return 6;
+ },
+}
+
+function SpiceMsgChannels(a, at)
+{
+ this.num_of_channels = 0;
+ this.channels = [];
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceMsgChannels.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ this.num_of_channels = dv.getUint32(at, true); at += 4;
+ for (i = 0; i < this.num_of_channels; i++)
+ {
+ var chan = new SpiceChannelId();
+ at = chan.from_dv(dv, at, a);
+ this.channels.push(chan);
+ }
+ },
+}
+
+function SpiceMsgMainInit(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgMainInit.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.session_id = dv.getUint32(at, true); at += 4;
+ this.display_channels_hint = dv.getUint32(at, true); at += 4;
+ this.supported_mouse_modes = dv.getUint32(at, true); at += 4;
+ this.current_mouse_mode = dv.getUint32(at, true); at += 4;
+ this.agent_connected = dv.getUint32(at, true); at += 4;
+ this.agent_tokens = dv.getUint32(at, true); at += 4;
+ this.multi_media_time = dv.getUint32(at, true); at += 4;
+ this.ram_hint = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgMainMouseMode(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgMainMouseMode.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.supported_modes = dv.getUint16(at, true); at += 2;
+ this.current_mode = dv.getUint16(at, true); at += 2;
+ },
+}
+
+function SpiceMsgSetAck(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgSetAck.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.generation = dv.getUint32(at, true); at += 4;
+ this.window = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgcAckSync(ack)
+{
+ this.generation = ack.generation;
+}
+
+SpiceMsgcAckSync.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.generation, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMsgcMainMouseModeRequest(mode)
+{
+ this.mode = mode;
+}
+
+SpiceMsgcMainMouseModeRequest.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint16(at, this.mode, true); at += 2;
+ },
+ buffer_size: function()
+ {
+ return 2;
+ }
+}
+
+function SpiceMsgcMainAgentStart(num_tokens)
+{
+ this.num_tokens = num_tokens;
+}
+
+SpiceMsgcMainAgentStart.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.num_tokens, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMsgcMainAgentData(type, data)
+{
+ this.protocol = VD_AGENT_PROTOCOL;
+ this.type = type;
+ this.opaque = 0;
+ this.size = data.buffer_size();
+ this.data = data;
+}
+
+SpiceMsgcMainAgentData.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.protocol, true); at += 4;
+ dv.setUint32(at, this.type, true); at += 4;
+ dv.setUint64(at, this.opaque, true); at += 8;
+ dv.setUint32(at, this.size, true); at += 4;
+ this.data.to_buffer(a, at);
+ },
+ buffer_size: function()
+ {
+ return 4 + 4 + 8 + 4 + this.data.buffer_size();
+ }
+}
+
+function VDAgentMonitorsConfig(flags, width, height, depth, x, y)
+{
+ this.num_mon = 1;
+ this.flags = flags;
+ this.width = width;
+ this.height = height;
+ this.depth = depth;
+ this.x = x;
+ this.y = y;
+}
+
+VDAgentMonitorsConfig.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.num_mon, true); at += 4;
+ dv.setUint32(at, this.flags, true); at += 4;
+ dv.setUint32(at, this.height, true); at += 4;
+ dv.setUint32(at, this.width, true); at += 4;
+ dv.setUint32(at, this.depth, true); at += 4;
+ dv.setUint32(at, this.x, true); at += 4;
+ dv.setUint32(at, this.y, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 28;
+ }
+}
+
+function SpiceMsgNotify(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgNotify.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ this.time_stamp = dv.getUint64(at, true); at += 8;
+ this.severity = dv.getUint32(at, true); at += 4;
+ this.visibility = dv.getUint32(at, true); at += 4;
+ this.what = dv.getUint32(at, true); at += 4;
+ this.message_len = dv.getUint32(at, true); at += 4;
+ this.message = "";
+ for (i = 0; i < this.message_len; i++)
+ {
+ var c = dv.getUint8(at, true); at++;
+ this.message += String.fromCharCode(c);
+ }
+ },
+}
+
+function SpiceMsgcDisplayInit()
+{
+ this.pixmap_cache_id = 1;
+ this.glz_dictionary_id = 0;
+ this.pixmap_cache_size = 10 * 1024 * 1024;
+ this.glz_dictionary_window_size = 0;
+}
+
+SpiceMsgcDisplayInit.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint8(at, this.pixmap_cache_id, true); at++;
+ dv.setUint64(at, this.pixmap_cache_size, true); at += 8;
+ dv.setUint8(at, this.glz_dictionary_id, true); at++;
+ dv.setUint32(at, this.glz_dictionary_window_size, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 14;
+ }
+}
+
+function SpiceMsgDisplayBase()
+{
+}
+
+SpiceMsgDisplayBase.prototype =
+{
+ from_dv : function(dv, at, mb)
+ {
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ this.box = new SpiceRect;
+ at = this.box.from_dv(dv, at, mb);
+ this.clip = new SpiceClip;
+ return this.clip.from_dv(dv, at, mb);
+ },
+}
+
+function SpiceMsgDisplayDrawCopy(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayDrawCopy.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceMsgDisplayBase;
+ at = this.base.from_dv(dv, at, a);
+ this.data = new SpiceCopy;
+ return this.data.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgDisplayDrawFill(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayDrawFill.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceMsgDisplayBase;
+ at = this.base.from_dv(dv, at, a);
+ this.data = new SpiceFill;
+ return this.data.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgDisplayCopyBits(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayCopyBits.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceMsgDisplayBase;
+ at = this.base.from_dv(dv, at, a);
+ this.src_pos = new SpicePoint;
+ return this.src_pos.from_dv(dv, at, a);
+ },
+}
+
+
+function SpiceMsgSurfaceCreate(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgSurfaceCreate.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.surface = new SpiceSurface;
+ return this.surface.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgSurfaceDestroy(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgSurfaceDestroy.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgInputsInit(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgInputsInit.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpiceMsgInputsKeyModifiers(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgInputsKeyModifiers.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpiceMsgCursorInit(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgCursorInit.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.position = new SpicePoint16;
+ at = this.position.from_dv(dv, at, mb);
+ this.trail_length = dv.getUint16(at, true); at += 2;
+ this.trail_frequency = dv.getUint16(at, true); at += 2;
+ this.visible = dv.getUint8(at, true); at ++;
+ this.cursor = new SpiceCursor;
+ return this.cursor.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgPlaybackData(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgPlaybackData.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.time = dv.getUint32(at, true); at += 4;
+ if (a.byteLength > at)
+ {
+ this.data = a.slice(at);
+ at += this.data.byteLength;
+ }
+ return at;
+ },
+}
+
+function SpiceMsgPlaybackMode(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgPlaybackMode.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.time = dv.getUint32(at, true); at += 4;
+ this.mode = dv.getUint16(at, true); at += 2;
+ if (a.byteLength > at)
+ {
+ this.data = a.slice(at);
+ at += this.data.byteLength;
+ }
+ return at;
+ },
+}
+
+function SpiceMsgPlaybackStart(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgPlaybackStart.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.channels = dv.getUint32(at, true); at += 4;
+ this.format = dv.getUint16(at, true); at += 2;
+ this.frequency = dv.getUint32(at, true); at += 4;
+ this.time = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+
+
+function SpiceMsgCursorSet(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgCursorSet.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.position = new SpicePoint16;
+ at = this.position.from_dv(dv, at, mb);
+ this.visible = dv.getUint8(at, true); at ++;
+ this.cursor = new SpiceCursor;
+ return this.cursor.from_dv(dv, at, a);
+ },
+}
+
+
+function SpiceMsgcMousePosition(sc, e)
+{
+ // FIXME - figure out how to correctly compute display_id
+ this.display_id = 0;
+ this.buttons_state = sc.buttons_state;
+ if (e)
+ {
+ var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
+ var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
+
+ this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft + scrollLeft;
+ this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop + scrollTop;
+ sc.mousex = this.x;
+ sc.mousey = this.y;
+ }
+ else
+ {
+ this.x = this.y = this.buttons_state = 0;
+ }
+}
+
+SpiceMsgcMousePosition.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.x, true); at += 4;
+ dv.setUint32(at, this.y, true); at += 4;
+ dv.setUint16(at, this.buttons_state, true); at += 2;
+ dv.setUint8(at, this.display_id, true); at += 1;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 11;
+ }
+}
+
+function SpiceMsgcMouseMotion(sc, e)
+{
+ // FIXME - figure out how to correctly compute display_id
+ this.display_id = 0;
+ this.buttons_state = sc.buttons_state;
+ if (e)
+ {
+ this.x = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
+ this.y = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
+
+ if (sc.mousex !== undefined)
+ {
+ this.x -= sc.mousex;
+ this.y -= sc.mousey;
+ }
+ sc.mousex = e.clientX - sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
+ sc.mousey = e.clientY - sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
+ }
+ else
+ {
+ this.x = this.y = this.buttons_state = 0;
+ }
+}
+
+/* Use the same functions as for MousePosition */
+SpiceMsgcMouseMotion.prototype.to_buffer = SpiceMsgcMousePosition.prototype.to_buffer;
+SpiceMsgcMouseMotion.prototype.buffer_size = SpiceMsgcMousePosition.prototype.buffer_size;
+
+function SpiceMsgcMousePress(sc, e)
+{
+ if (e)
+ {
+ this.button = e.button + 1;
+ this.buttons_state = 1 << e.button;
+ sc.buttons_state = this.buttons_state;
+ }
+ else
+ {
+ this.button = SPICE_MOUSE_BUTTON_LEFT;
+ this.buttons_state = SPICE_MOUSE_BUTTON_MASK_LEFT;
+ }
+}
+
+SpiceMsgcMousePress.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint8(at, this.button, true); at ++;
+ dv.setUint16(at, this.buttons_state, true); at += 2;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 3;
+ }
+}
+
+function SpiceMsgcMouseRelease(sc, e)
+{
+ if (e)
+ {
+ this.button = e.button + 1;
+ this.buttons_state = 0;
+ sc.buttons_state = this.buttons_state;
+ }
+ else
+ {
+ this.button = SPICE_MOUSE_BUTTON_LEFT;
+ this.buttons_state = 0;
+ }
+}
+
+/* Use the same functions as for MousePress */
+SpiceMsgcMouseRelease.prototype.to_buffer = SpiceMsgcMousePress.prototype.to_buffer;
+SpiceMsgcMouseRelease.prototype.buffer_size = SpiceMsgcMousePress.prototype.buffer_size;
+
+
+function SpiceMsgcKeyDown(e)
+{
+ if (e)
+ {
+ this.code = keycode_to_start_scan(e.keyCode);
+ }
+ else
+ {
+ this.code = 0;
+ }
+}
+
+SpiceMsgcKeyDown.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.code, true); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMsgcKeyUp(e)
+{
+ if (e)
+ {
+ this.code = keycode_to_end_scan(e.keyCode);
+ }
+ else
+ {
+ this.code = 0;
+ }
+}
+
+/* Use the same functions as for KeyDown */
+SpiceMsgcKeyUp.prototype.to_buffer = SpiceMsgcKeyDown.prototype.to_buffer;
+SpiceMsgcKeyUp.prototype.buffer_size = SpiceMsgcKeyDown.prototype.buffer_size;
+
+function SpiceMsgDisplayStreamCreate(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamCreate.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ this.id = dv.getUint32(at, true); at += 4;
+ this.flags = dv.getUint8(at, true); at += 1;
+ this.codec_type = dv.getUint8(at, true); at += 1;
+ this.stamp = dv.getUint64(at, true); at += 8;
+ this.stream_width = dv.getUint32(at, true); at += 4;
+ this.stream_height = dv.getUint32(at, true); at += 4;
+ this.src_width = dv.getUint32(at, true); at += 4;
+ this.src_height = dv.getUint32(at, true); at += 4;
+
+ this.dest = new SpiceRect;
+ at = this.dest.from_dv(dv, at, a);
+ this.clip = new SpiceClip;
+ this.clip.from_dv(dv, at, a);
+ },
+}
+
+function SpiceStreamDataHeader(a, at)
+{
+}
+
+SpiceStreamDataHeader.prototype =
+{
+ from_dv : function(dv, at, mb)
+ {
+ this.id = dv.getUint32(at, true); at += 4;
+ this.multi_media_time = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+function SpiceMsgDisplayStreamData(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamData.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceStreamDataHeader;
+ at = this.base.from_dv(dv, at, a);
+ this.data_size = dv.getUint32(at, true); at += 4;
+ this.data = dv.u8.subarray(at, at + this.data_size);
+ },
+}
+
+function SpiceMsgDisplayStreamClip(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamClip.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.id = dv.getUint32(at, true); at += 4;
+ this.clip = new SpiceClip;
+ this.clip.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgDisplayStreamDestroy(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamDestroy.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.id = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgDisplayInvalList(a, at)
+{
+ this.count = 0;
+ this.resources = [];
+ this.from_buffer(a,at);
+}
+
+SpiceMsgDisplayInvalList.prototype =
+{
+ from_buffer: function (a, at)
+ {
+ var i;
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.count = dv.getUint16(at, true); at += 2;
+ for (i = 0; i < this.count; i++)
+ {
+ this.resources[i] = {};
+ this.resources[i].type = dv.getUint8(at, true); at++;
+ this.resources[i].id = dv.getUint64(at, true); at += 8;
+ }
+ },
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicetype.js b/src/wok/plugins/kimchi/ui/spice-html5/spicetype.js
new file mode 100644
index 0000000..951b277
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicetype.js
@@ -0,0 +1,473 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** Spice types
+** This file contains classes for common spice types.
+** Generally, they are used as helpers in reading and writing messages
+** to and from the server.
+**--------------------------------------------------------------------------*/
+
+function SpiceChannelId()
+{
+}
+SpiceChannelId.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.type = dv.getUint8(at, true); at ++;
+ this.id = dv.getUint8(at, true); at ++;
+ return at;
+ },
+}
+
+function SpiceRect()
+{
+}
+
+SpiceRect.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.top = dv.getUint32(at, true); at += 4;
+ this.left = dv.getUint32(at, true); at += 4;
+ this.bottom = dv.getUint32(at, true); at += 4;
+ this.right = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+ is_same_size : function(r)
+ {
+ if ((this.bottom - this.top) == (r.bottom - r.top) &&
+ (this.right - this.left) == (r.right - r.left) )
+ return true;
+
+ return false;
+ },
+}
+
+function SpiceClipRects()
+{
+}
+
+SpiceClipRects.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var i;
+ this.num_rects = dv.getUint32(at, true); at += 4;
+ if (this.num_rects > 0)
+ this.rects = [];
+ for (i = 0; i < this.num_rects; i++)
+ {
+ this.rects[i] = new SpiceRect();
+ at = this.rects[i].from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+function SpiceClip()
+{
+}
+
+SpiceClip.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.type = dv.getUint8(at, true); at ++;
+ if (this.type == SPICE_CLIP_TYPE_RECTS)
+ {
+ this.rects = new SpiceClipRects();
+ at = this.rects.from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+function SpiceImageDescriptor()
+{
+}
+
+SpiceImageDescriptor.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.id = dv.getUint64(at, true); at += 8;
+ this.type = dv.getUint8(at, true); at ++;
+ this.flags = dv.getUint8(at, true); at ++;
+ this.width = dv.getUint32(at, true); at += 4;
+ this.height= dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+function SpicePalette()
+{
+}
+
+SpicePalette.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var i;
+ this.unique = dv.getUint64(at, true); at += 8;
+ this.num_ents = dv.getUint16(at, true); at += 2;
+ this.ents = [];
+ for (i = 0; i < this.num_ents; i++)
+ {
+ this.ents[i] = dv.getUint32(at, true); at += 4;
+ }
+ return at;
+ },
+}
+
+function SpiceBitmap()
+{
+}
+
+SpiceBitmap.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.format = dv.getUint8(at, true); at++;
+ this.flags = dv.getUint8(at, true); at++;
+ this.x = dv.getUint32(at, true); at += 4;
+ this.y = dv.getUint32(at, true); at += 4;
+ this.stride = dv.getUint32(at, true); at += 4;
+ if (this.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)
+ {
+ this.palette_id = dv.getUint64(at, true); at += 8;
+ }
+ else
+ {
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ this.palette = null;
+ else
+ {
+ this.palette = new SpicePalette;
+ this.palette.from_dv(dv, offset, mb);
+ }
+ }
+ // FIXME - should probably constrain this to the offset
+ // of palette, if non zero
+ this.data = mb.slice(at);
+ at += this.data.byteLength;
+ return at;
+ },
+}
+
+function SpiceImage()
+{
+}
+
+SpiceImage.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.descriptor = new SpiceImageDescriptor;
+ at = this.descriptor.from_dv(dv, at, mb);
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
+ {
+ this.lz_rgb = new Object();
+ this.lz_rgb.length = dv.getUint32(at, true); at += 4;
+ var initial_at = at;
+ this.lz_rgb.magic = "";
+ for (var i = 3; i >= 0; i--)
+ this.lz_rgb.magic += String.fromCharCode(dv.getUint8(at + i));
+ at += 4;
+
+ // NOTE: The endian change is *correct*
+ this.lz_rgb.version = dv.getUint32(at); at += 4;
+ this.lz_rgb.type = dv.getUint32(at); at += 4;
+ this.lz_rgb.width = dv.getUint32(at); at += 4;
+ this.lz_rgb.height = dv.getUint32(at); at += 4;
+ this.lz_rgb.stride = dv.getUint32(at); at += 4;
+ this.lz_rgb.top_down = dv.getUint32(at); at += 4;
+
+ var header_size = at - initial_at;
+
+ this.lz_rgb.data = mb.slice(at, this.lz_rgb.length + at - header_size);
+ at += this.lz_rgb.data.byteLength;
+
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
+ {
+ this.bitmap = new SpiceBitmap;
+ at = this.bitmap.from_dv(dv, at, mb);
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
+ {
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
+ {
+ this.jpeg = new Object;
+ this.jpeg.data_size = dv.getUint32(at, true); at += 4;
+ this.jpeg.data = mb.slice(at);
+ at += this.jpeg.data.byteLength;
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
+ {
+ this.jpeg_alpha = new Object;
+ this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1;
+ this.jpeg_alpha.jpeg_size = dv.getUint32(at, true); at += 4;
+ this.jpeg_alpha.data_size = dv.getUint32(at, true); at += 4;
+ this.jpeg_alpha.data = mb.slice(at, this.jpeg_alpha.jpeg_size + at);
+ at += this.jpeg_alpha.data.byteLength;
+ // Alpha channel is an LZ image
+ this.jpeg_alpha.alpha = new Object();
+ this.jpeg_alpha.alpha.length = this.jpeg_alpha.data_size - this.jpeg_alpha.jpeg_size;
+ var initial_at = at;
+ this.jpeg_alpha.alpha.magic = "";
+ for (var i = 3; i >= 0; i--)
+ this.jpeg_alpha.alpha.magic += String.fromCharCode(dv.getUint8(at + i));
+ at += 4;
+
+ // NOTE: The endian change is *correct*
+ this.jpeg_alpha.alpha.version = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.type = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.width = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.height = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.stride = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.top_down = dv.getUint32(at); at += 4;
+
+ var header_size = at - initial_at;
+
+ this.jpeg_alpha.alpha.data = mb.slice(at, this.jpeg_alpha.alpha.length + at - header_size);
+ at += this.jpeg_alpha.alpha.data.byteLength;
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
+ {
+ this.quic = new SpiceQuic;
+ at = this.quic.from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+
+function SpiceQMask()
+{
+}
+
+SpiceQMask.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.flags = dv.getUint8(at, true); at++;
+ this.pos = new SpicePoint;
+ at = this.pos.from_dv(dv, at, mb);
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ {
+ this.bitmap = null;
+ return at;
+ }
+
+ this.bitmap = new SpiceImage;
+ return this.bitmap.from_dv(dv, offset, mb);
+ },
+}
+
+
+function SpicePattern()
+{
+}
+
+SpicePattern.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ {
+ this.pat = null;
+ }
+ else
+ {
+ this.pat = new SpiceImage;
+ this.pat.from_dv(dv, offset, mb);
+ }
+
+ this.pos = new SpicePoint;
+ return this.pos.from_dv(dv, at, mb);
+ }
+}
+
+function SpiceBrush()
+{
+}
+
+SpiceBrush.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.type = dv.getUint8(at, true); at ++;
+ if (this.type == SPICE_BRUSH_TYPE_SOLID)
+ {
+ this.color = dv.getUint32(at, true); at += 4;
+ }
+ else if (this.type == SPICE_BRUSH_TYPE_PATTERN)
+ {
+ this.pattern = new SpicePattern;
+ at = this.pattern.from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+function SpiceFill()
+{
+}
+
+SpiceFill.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.brush = new SpiceBrush;
+ at = this.brush.from_dv(dv, at, mb);
+ this.rop_descriptor = dv.getUint16(at, true); at += 2;
+ this.mask = new SpiceQMask;
+ return this.mask.from_dv(dv, at, mb);
+ },
+}
+
+
+function SpiceCopy()
+{
+}
+
+SpiceCopy.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ {
+ this.src_bitmap = null;
+ }
+ else
+ {
+ this.src_bitmap = new SpiceImage;
+ this.src_bitmap.from_dv(dv, offset, mb);
+ }
+ this.src_area = new SpiceRect;
+ at = this.src_area.from_dv(dv, at, mb);
+ this.rop_descriptor = dv.getUint16(at, true); at += 2;
+ this.scale_mode = dv.getUint8(at, true); at ++;
+ this.mask = new SpiceQMask;
+ return this.mask.from_dv(dv, at, mb);
+ },
+}
+
+function SpicePoint16()
+{
+}
+
+SpicePoint16.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.x = dv.getUint16(at, true); at += 2;
+ this.y = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpicePoint()
+{
+}
+
+SpicePoint.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.x = dv.getUint32(at, true); at += 4;
+ this.y = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+function SpiceCursorHeader()
+{
+}
+
+SpiceCursorHeader.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.unique = dv.getUint64(at, true); at += 8;
+ this.type = dv.getUint8(at, true); at ++;
+ this.width = dv.getUint16(at, true); at += 2;
+ this.height = dv.getUint16(at, true); at += 2;
+ this.hot_spot_x = dv.getUint16(at, true); at += 2;
+ this.hot_spot_y = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpiceCursor()
+{
+}
+
+SpiceCursor.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.flags = dv.getUint16(at, true); at += 2;
+ if (this.flags & SPICE_CURSOR_FLAGS_NONE)
+ this.header = null;
+ else
+ {
+ this.header = new SpiceCursorHeader;
+ at = this.header.from_dv(dv, at, mb);
+ this.data = mb.slice(at);
+ at += this.data.byteLength;
+ }
+ return at;
+ },
+}
+
+function SpiceSurface()
+{
+}
+
+SpiceSurface.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ this.width = dv.getUint32(at, true); at += 4;
+ this.height = dv.getUint32(at, true); at += 4;
+ this.format = dv.getUint32(at, true); at += 4;
+ this.flags = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+/* FIXME - SpiceImage types lz_plt, jpeg, zlib_glz, and jpeg_alpha are
+ completely unimplemented */
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
new file mode 100644
index 0000000..474478d
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+thirdpartydir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/thirdparty
+
+dist_thirdparty_DATA = $(wildcard *.js) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
new file mode 100644
index 0000000..9b9476e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
@@ -0,0 +1,589 @@
+// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// Basic JavaScript BN library - subset useful for RSA encryption.
+
+// Bits per digit
+var dbits;
+
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary&0xffffff)==0xefcafe);
+
+// (public) Constructor
+function BigInteger(a,b,c) {
+ if(a != null)
+ if("number" == typeof a) this.fromNumber(a,b,c);
+ else if(b == null && "string" != typeof a) this.fromString(a,256);
+ else this.fromString(a,b);
+}
+
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i,x,w,j,c,n) {
+ while(--n >= 0) {
+ var v = x*this[i++]+w[j]+c;
+ c = Math.floor(v/0x4000000);
+ w[j++] = v&0x3ffffff;
+ }
+ return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i,x,w,j,c,n) {
+ var xl = x&0x7fff, xh = x>>15;
+ while(--n >= 0) {
+ var l = this[i]&0x7fff;
+ var h = this[i++]>>15;
+ var m = xh*l+h*xl;
+ l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
+ c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
+ w[j++] = l&0x3fffffff;
+ }
+ return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i,x,w,j,c,n) {
+ var xl = x&0x3fff, xh = x>>14;
+ while(--n >= 0) {
+ var l = this[i]&0x3fff;
+ var h = this[i++]>>14;
+ var m = xh*l+h*xl;
+ l = xl*l+((m&0x3fff)<<14)+w[j]+c;
+ c = (l>>28)+(m>>14)+xh*h;
+ w[j++] = l&0xfffffff;
+ }
+ return c;
+}
+if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+ BigInteger.prototype.am = am2;
+ dbits = 30;
+}
+else if(j_lm && (navigator.appName != "Netscape")) {
+ BigInteger.prototype.am = am1;
+ dbits = 26;
+}
+else { // Mozilla/Netscape seems to prefer am3
+ BigInteger.prototype.am = am3;
+ dbits = 28;
+}
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1<<dbits)-1);
+BigInteger.prototype.DV = (1<<dbits);
+
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2,BI_FP);
+BigInteger.prototype.F1 = BI_FP-dbits;
+BigInteger.prototype.F2 = 2*dbits-BI_FP;
+
+// Digit conversions
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+var BI_RC = new Array();
+var rr,vv;
+rr = "0".charCodeAt(0);
+for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+rr = "a".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+rr = "A".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+function int2char(n) { return BI_RM.charAt(n); }
+function intAt(s,i) {
+ var c = BI_RC[s.charCodeAt(i)];
+ return (c==null)?-1:c;
+}
+
+// (protected) copy this to r
+function bnpCopyTo(r) {
+ for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
+ r.t = this.t;
+ r.s = this.s;
+}
+
+// (protected) set from integer value x, -DV <= x < DV
+function bnpFromInt(x) {
+ this.t = 1;
+ this.s = (x<0)?-1:0;
+ if(x > 0) this[0] = x;
+ else if(x < -1) this[0] = x+DV;
+ else this.t = 0;
+}
+
+// return bigint initialized to value
+function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+// (protected) set from string and radix
+function bnpFromString(s,b) {
+ var k;
+ if(b == 16) k = 4;
+ else if(b == 8) k = 3;
+ else if(b == 256) k = 8; // byte array
+ else if(b == 2) k = 1;
+ else if(b == 32) k = 5;
+ else if(b == 4) k = 2;
+ else { this.fromRadix(s,b); return; }
+ this.t = 0;
+ this.s = 0;
+ var i = s.length, mi = false, sh = 0;
+ while(--i >= 0) {
+ var x = (k==8)?s[i]&0xff:intAt(s,i);
+ if(x < 0) {
+ if(s.charAt(i) == "-") mi = true;
+ continue;
+ }
+ mi = false;
+ if(sh == 0)
+ this[this.t++] = x;
+ else if(sh+k > this.DB) {
+ this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
+ this[this.t++] = (x>>(this.DB-sh));
+ }
+ else
+ this[this.t-1] |= x<<sh;
+ sh += k;
+ if(sh >= this.DB) sh -= this.DB;
+ }
+ if(k == 8 && (s[0]&0x80) != 0) {
+ this.s = -1;
+ if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
+ }
+ this.clamp();
+ if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) clamp off excess high words
+function bnpClamp() {
+ var c = this.s&this.DM;
+ while(this.t > 0 && this[this.t-1] == c) --this.t;
+}
+
+// (public) return string representation in given radix
+function bnToString(b) {
+ if(this.s < 0) return "-"+this.negate().toString(b);
+ var k;
+ if(b == 16) k = 4;
+ else if(b == 8) k = 3;
+ else if(b == 2) k = 1;
+ else if(b == 32) k = 5;
+ else if(b == 4) k = 2;
+ else return this.toRadix(b);
+ var km = (1<<k)-1, d, m = false, r = "", i = this.t;
+ var p = this.DB-(i*this.DB)%k;
+ if(i-- > 0) {
+ if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
+ while(i >= 0) {
+ if(p < k) {
+ d = (this[i]&((1<<p)-1))<<(k-p);
+ d |= this[--i]>>(p+=this.DB-k);
+ }
+ else {
+ d = (this[i]>>(p-=k))&km;
+ if(p <= 0) { p += this.DB; --i; }
+ }
+ if(d > 0) m = true;
+ if(m) r += int2char(d);
+ }
+ }
+ return m?r:"0";
+}
+
+// (public) -this
+function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
+
+// (public) |this|
+function bnAbs() { return (this.s<0)?this.negate():this; }
+
+// (public) return + if this > a, - if this < a, 0 if equal
+function bnCompareTo(a) {
+ var r = this.s-a.s;
+ if(r != 0) return r;
+ var i = this.t;
+ r = i-a.t;
+ if(r != 0) return r;
+ while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
+ return 0;
+}
+
+// returns bit length of the integer x
+function nbits(x) {
+ var r = 1, t;
+ if((t=x>>>16) != 0) { x = t; r += 16; }
+ if((t=x>>8) != 0) { x = t; r += 8; }
+ if((t=x>>4) != 0) { x = t; r += 4; }
+ if((t=x>>2) != 0) { x = t; r += 2; }
+ if((t=x>>1) != 0) { x = t; r += 1; }
+ return r;
+}
+
+// (public) return the number of bits in "this"
+function bnBitLength() {
+ if(this.t <= 0) return 0;
+ return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
+}
+
+// (protected) r = this << n*DB
+function bnpDLShiftTo(n,r) {
+ var i;
+ for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
+ for(i = n-1; i >= 0; --i) r[i] = 0;
+ r.t = this.t+n;
+ r.s = this.s;
+}
+
+// (protected) r = this >> n*DB
+function bnpDRShiftTo(n,r) {
+ for(var i = n; i < this.t; ++i) r[i-n] = this[i];
+ r.t = Math.max(this.t-n,0);
+ r.s = this.s;
+}
+
+// (protected) r = this << n
+function bnpLShiftTo(n,r) {
+ var bs = n%this.DB;
+ var cbs = this.DB-bs;
+ var bm = (1<<cbs)-1;
+ var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
+ for(i = this.t-1; i >= 0; --i) {
+ r[i+ds+1] = (this[i]>>cbs)|c;
+ c = (this[i]&bm)<<bs;
+ }
+ for(i = ds-1; i >= 0; --i) r[i] = 0;
+ r[ds] = c;
+ r.t = this.t+ds+1;
+ r.s = this.s;
+ r.clamp();
+}
+
+// (protected) r = this >> n
+function bnpRShiftTo(n,r) {
+ r.s = this.s;
+ var ds = Math.floor(n/this.DB);
+ if(ds >= this.t) { r.t = 0; return; }
+ var bs = n%this.DB;
+ var cbs = this.DB-bs;
+ var bm = (1<<bs)-1;
+ r[0] = this[ds]>>bs;
+ for(var i = ds+1; i < this.t; ++i) {
+ r[i-ds-1] |= (this[i]&bm)<<cbs;
+ r[i-ds] = this[i]>>bs;
+ }
+ if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
+ r.t = this.t-ds;
+ r.clamp();
+}
+
+// (protected) r = this - a
+function bnpSubTo(a,r) {
+ var i = 0, c = 0, m = Math.min(a.t,this.t);
+ while(i < m) {
+ c += this[i]-a[i];
+ r[i++] = c&this.DM;
+ c >>= this.DB;
+ }
+ if(a.t < this.t) {
+ c -= a.s;
+ while(i < this.t) {
+ c += this[i];
+ r[i++] = c&this.DM;
+ c >>= this.DB;
+ }
+ c += this.s;
+ }
+ else {
+ c += this.s;
+ while(i < a.t) {
+ c -= a[i];
+ r[i++] = c&this.DM;
+ c >>= this.DB;
+ }
+ c -= a.s;
+ }
+ r.s = (c<0)?-1:0;
+ if(c < -1) r[i++] = this.DV+c;
+ else if(c > 0) r[i++] = c;
+ r.t = i;
+ r.clamp();
+}
+
+// (protected) r = this * a, r != this,a (HAC 14.12)
+// "this" should be the larger one if appropriate.
+function bnpMultiplyTo(a,r) {
+ var x = this.abs(), y = a.abs();
+ var i = x.t;
+ r.t = i+y.t;
+ while(--i >= 0) r[i] = 0;
+ for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
+ r.s = 0;
+ r.clamp();
+ if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
+}
+
+// (protected) r = this^2, r != this (HAC 14.16)
+function bnpSquareTo(r) {
+ var x = this.abs();
+ var i = r.t = 2*x.t;
+ while(--i >= 0) r[i] = 0;
+ for(i = 0; i < x.t-1; ++i) {
+ var c = x.am(i,x[i],r,2*i,0,1);
+ if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
+ r[i+x.t] -= x.DV;
+ r[i+x.t+1] = 1;
+ }
+ }
+ if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
+ r.s = 0;
+ r.clamp();
+}
+
+// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+// r != q, this != m. q or r may be null.
+function bnpDivRemTo(m,q,r) {
+ var pm = m.abs();
+ if(pm.t <= 0) return;
+ var pt = this.abs();
+ if(pt.t < pm.t) {
+ if(q != null) q.fromInt(0);
+ if(r != null) this.copyTo(r);
+ return;
+ }
+ if(r == null) r = nbi();
+ var y = nbi(), ts = this.s, ms = m.s;
+ var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
+ if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
+ else { pm.copyTo(y); pt.copyTo(r); }
+ var ys = y.t;
+ var y0 = y[ys-1];
+ if(y0 == 0) return;
+ var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
+ var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
+ var i = r.t, j = i-ys, t = (q==null)?nbi():q;
+ y.dlShiftTo(j,t);
+ if(r.compareTo(t) >= 0) {
+ r[r.t++] = 1;
+ r.subTo(t,r);
+ }
+ BigInteger.ONE.dlShiftTo(ys,t);
+ t.subTo(y,y); // "negative" y so we can replace sub with am later
+ while(y.t < ys) y[y.t++] = 0;
+ while(--j >= 0) {
+ // Estimate quotient digit
+ var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
+ if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
+ y.dlShiftTo(j,t);
+ r.subTo(t,r);
+ while(r[i] < --qd) r.subTo(t,r);
+ }
+ }
+ if(q != null) {
+ r.drShiftTo(ys,q);
+ if(ts != ms) BigInteger.ZERO.subTo(q,q);
+ }
+ r.t = ys;
+ r.clamp();
+ if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
+ if(ts < 0) BigInteger.ZERO.subTo(r,r);
+}
+
+// (public) this mod a
+function bnMod(a) {
+ var r = nbi();
+ this.abs().divRemTo(a,null,r);
+ if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
+ return r;
+}
+
+// Modular reduction using "classic" algorithm
+function Classic(m) { this.m = m; }
+function cConvert(x) {
+ if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+ else return x;
+}
+function cRevert(x) { return x; }
+function cReduce(x) { x.divRemTo(this.m,null,x); }
+function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+Classic.prototype.convert = cConvert;
+Classic.prototype.revert = cRevert;
+Classic.prototype.reduce = cReduce;
+Classic.prototype.mulTo = cMulTo;
+Classic.prototype.sqrTo = cSqrTo;
+
+// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+// justification:
+// xy == 1 (mod m)
+// xy = 1+km
+// xy(2-xy) = (1+km)(1-km)
+// x[y(2-xy)] = 1-k^2m^2
+// x[y(2-xy)] == 1 (mod m^2)
+// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+// JS multiply "overflows" differently from C/C++, so care is needed here.
+function bnpInvDigit() {
+ if(this.t < 1) return 0;
+ var x = this[0];
+ if((x&1) == 0) return 0;
+ var y = x&3; // y == 1/x mod 2^2
+ y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
+ y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
+ y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
+ // last step - calculate inverse mod DV directly;
+ // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+ y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
+ // we really want the negative inverse, and -DV < y < DV
+ return (y>0)?this.DV-y:-y;
+}
+
+// Montgomery reduction
+function Montgomery(m) {
+ this.m = m;
+ this.mp = m.invDigit();
+ this.mpl = this.mp&0x7fff;
+ this.mph = this.mp>>15;
+ this.um = (1<<(m.DB-15))-1;
+ this.mt2 = 2*m.t;
+}
+
+// xR mod m
+function montConvert(x) {
+ var r = nbi();
+ x.abs().dlShiftTo(this.m.t,r);
+ r.divRemTo(this.m,null,r);
+ if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
+ return r;
+}
+
+// x/R mod m
+function montRevert(x) {
+ var r = nbi();
+ x.copyTo(r);
+ this.reduce(r);
+ return r;
+}
+
+// x = x/R mod m (HAC 14.32)
+function montReduce(x) {
+ while(x.t <= this.mt2) // pad x so am has enough room later
+ x[x.t++] = 0;
+ for(var i = 0; i < this.m.t; ++i) {
+ // faster way of calculating u0 = x[i]*mp mod DV
+ var j = x[i]&0x7fff;
+ var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
+ // use am to combine the multiply-shift-add into one call
+ j = i+this.m.t;
+ x[j] += this.m.am(0,u0,x,i,0,this.m.t);
+ // propagate carry
+ while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+ }
+ x.clamp();
+ x.drShiftTo(this.m.t,x);
+ if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = "x^2/R mod m"; x != r
+function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = "xy/R mod m"; x,y != r
+function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Montgomery.prototype.convert = montConvert;
+Montgomery.prototype.revert = montRevert;
+Montgomery.prototype.reduce = montReduce;
+Montgomery.prototype.mulTo = montMulTo;
+Montgomery.prototype.sqrTo = montSqrTo;
+
+// (protected) true iff this is even
+function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
+
+// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+function bnpExp(e,z) {
+ if(e > 0xffffffff || e < 1) return BigInteger.ONE;
+ var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
+ g.copyTo(r);
+ while(--i >= 0) {
+ z.sqrTo(r,r2);
+ if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
+ else { var t = r; r = r2; r2 = t; }
+ }
+ return z.revert(r);
+}
+
+// (public) this^e % m, 0 <= e < 2^32
+function bnModPowInt(e,m) {
+ var z;
+ if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+ return this.exp(e,z);
+}
+
+// protected
+BigInteger.prototype.copyTo = bnpCopyTo;
+BigInteger.prototype.fromInt = bnpFromInt;
+BigInteger.prototype.fromString = bnpFromString;
+BigInteger.prototype.clamp = bnpClamp;
+BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+BigInteger.prototype.lShiftTo = bnpLShiftTo;
+BigInteger.prototype.rShiftTo = bnpRShiftTo;
+BigInteger.prototype.subTo = bnpSubTo;
+BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+BigInteger.prototype.squareTo = bnpSquareTo;
+BigInteger.prototype.divRemTo = bnpDivRemTo;
+BigInteger.prototype.invDigit = bnpInvDigit;
+BigInteger.prototype.isEven = bnpIsEven;
+BigInteger.prototype.exp = bnpExp;
+
+// public
+BigInteger.prototype.toString = bnToString;
+BigInteger.prototype.negate = bnNegate;
+BigInteger.prototype.abs = bnAbs;
+BigInteger.prototype.compareTo = bnCompareTo;
+BigInteger.prototype.bitLength = bnBitLength;
+BigInteger.prototype.mod = bnMod;
+BigInteger.prototype.modPowInt = bnModPowInt;
+
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
new file mode 100644
index 0000000..4715372
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
@@ -0,0 +1,79 @@
+// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// prng4.js - uses Arcfour as a PRNG
+
+function Arcfour() {
+ this.i = 0;
+ this.j = 0;
+ this.S = new Array();
+}
+
+// Initialize arcfour context from key, an array of ints, each from [0..255]
+function ARC4init(key) {
+ var i, j, t;
+ for(i = 0; i < 256; ++i)
+ this.S[i] = i;
+ j = 0;
+ for(i = 0; i < 256; ++i) {
+ j = (j + this.S[i] + key[i % key.length]) & 255;
+ t = this.S[i];
+ this.S[i] = this.S[j];
+ this.S[j] = t;
+ }
+ this.i = 0;
+ this.j = 0;
+}
+
+function ARC4next() {
+ var t;
+ this.i = (this.i + 1) & 255;
+ this.j = (this.j + this.S[this.i]) & 255;
+ t = this.S[this.i];
+ this.S[this.i] = this.S[this.j];
+ this.S[this.j] = t;
+ return this.S[(t + this.S[this.i]) & 255];
+}
+
+Arcfour.prototype.init = ARC4init;
+Arcfour.prototype.next = ARC4next;
+
+// Plug in your RNG constructor here
+function prng_newstate() {
+ return new Arcfour();
+}
+
+// Pool size must be a multiple of 4 and greater than 32.
+// An array of bytes the size of the pool will be passed to init()
+var rng_psize = 256;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
new file mode 100644
index 0000000..829a23c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
@@ -0,0 +1,102 @@
+// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// Random number generator - requires a PRNG backend, e.g. prng4.js
+
+// For best results, put code like
+// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
+// in your main HTML document.
+
+var rng_state;
+var rng_pool;
+var rng_pptr;
+
+// Mix in a 32-bit integer into the pool
+function rng_seed_int(x) {
+ rng_pool[rng_pptr++] ^= x & 255;
+ rng_pool[rng_pptr++] ^= (x >> 8) & 255;
+ rng_pool[rng_pptr++] ^= (x >> 16) & 255;
+ rng_pool[rng_pptr++] ^= (x >> 24) & 255;
+ if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
+}
+
+// Mix in the current time (w/milliseconds) into the pool
+function rng_seed_time() {
+ rng_seed_int(new Date().getTime());
+}
+
+// Initialize the pool with junk if needed.
+if(rng_pool == null) {
+ rng_pool = new Array();
+ rng_pptr = 0;
+ var t;
+ if(navigator.appName == "Netscape" && navigator.appVersion < "5" && window.crypto) {
+ // Extract entropy (256 bits) from NS4 RNG if available
+ var z = window.crypto.random(32);
+ for(t = 0; t < z.length; ++t)
+ rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
+ }
+ while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
+ t = Math.floor(65536 * Math.random());
+ rng_pool[rng_pptr++] = t >>> 8;
+ rng_pool[rng_pptr++] = t & 255;
+ }
+ rng_pptr = 0;
+ rng_seed_time();
+ //rng_seed_int(window.screenX);
+ //rng_seed_int(window.screenY);
+}
+
+function rng_get_byte() {
+ if(rng_state == null) {
+ rng_seed_time();
+ rng_state = prng_newstate();
+ rng_state.init(rng_pool);
+ for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
+ rng_pool[rng_pptr] = 0;
+ rng_pptr = 0;
+ //rng_pool = null;
+ }
+ // TODO: allow reseeding after first request
+ return rng_state.next();
+}
+
+function rng_get_bytes(ba) {
+ var i;
+ for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
+}
+
+function SecureRandom() {}
+
+SecureRandom.prototype.nextBytes = rng_get_bytes;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
new file mode 100644
index 0000000..1bbf249
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
@@ -0,0 +1,146 @@
+// Downloaded from http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on 6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// Depends on jsbn.js and rng.js
+
+// Version 1.1: support utf-8 encoding in pkcs1pad2
+
+// convert a (hex) string to a bignum object
+function parseBigInt(str,r) {
+ return new BigInteger(str,r);
+}
+
+function linebrk(s,n) {
+ var ret = "";
+ var i = 0;
+ while(i + n < s.length) {
+ ret += s.substring(i,i+n) + "\n";
+ i += n;
+ }
+ return ret + s.substring(i,s.length);
+}
+
+function byte2Hex(b) {
+ if(b < 0x10)
+ return "0" + b.toString(16);
+ else
+ return b.toString(16);
+}
+
+// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+function pkcs1pad2(s,n) {
+ if(n < s.length + 11) { // TODO: fix for utf-8
+ alert("Message too long for RSA");
+ return null;
+ }
+ var ba = new Array();
+ var i = s.length - 1;
+ while(i >= 0 && n > 0) {
+ var c = s.charCodeAt(i--);
+ if(c < 128) { // encode using utf-8
+ ba[--n] = c;
+ }
+ else if((c > 127) && (c < 2048)) {
+ ba[--n] = (c & 63) | 128;
+ ba[--n] = (c >> 6) | 192;
+ }
+ else {
+ ba[--n] = (c & 63) | 128;
+ ba[--n] = ((c >> 6) & 63) | 128;
+ ba[--n] = (c >> 12) | 224;
+ }
+ }
+ ba[--n] = 0;
+ var rng = new SecureRandom();
+ var x = new Array();
+ while(n > 2) { // random non-zero pad
+ x[0] = 0;
+ while(x[0] == 0) rng.nextBytes(x);
+ ba[--n] = x[0];
+ }
+ ba[--n] = 2;
+ ba[--n] = 0;
+ return new BigInteger(ba);
+}
+
+// "empty" RSA key constructor
+function RSAKey() {
+ this.n = null;
+ this.e = 0;
+ this.d = null;
+ this.p = null;
+ this.q = null;
+ this.dmp1 = null;
+ this.dmq1 = null;
+ this.coeff = null;
+}
+
+// Set the public key fields N and e from hex strings
+function RSASetPublic(N,E) {
+ if(N != null && E != null && N.length > 0 && E.length > 0) {
+ this.n = parseBigInt(N,16);
+ this.e = parseInt(E,16);
+ }
+ else
+ alert("Invalid RSA public key");
+}
+
+// Perform raw public operation on "x": return x^e (mod n)
+function RSADoPublic(x) {
+ return x.modPowInt(this.e, this.n);
+}
+
+// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+function RSAEncrypt(text) {
+ var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
+ if(m == null) return null;
+ var c = this.doPublic(m);
+ if(c == null) return null;
+ var h = c.toString(16);
+ if((h.length & 1) == 0) return h; else return "0" + h;
+}
+
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+//function RSAEncryptB64(text) {
+// var h = this.encrypt(text);
+// if(h) return hex2b64(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPublic = RSADoPublic;
+
+// public
+RSAKey.prototype.setPublic = RSASetPublic;
+RSAKey.prototype.encrypt = RSAEncrypt;
+//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
new file mode 100644
index 0000000..8118cb4
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
@@ -0,0 +1,346 @@
+/*
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS 180-1
+ * Version 2.2 Copyright Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ */
+
+ /* Downloaded 6/1/2012 from the above address by Jeremy White.
+ License reproduce here for completeness:
+
+Copyright (c) 1998 - 2009, Paul Johnston & Contributors
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
+function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
+function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
+function hex_hmac_sha1(k, d)
+ { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_sha1(k, d)
+ { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_sha1(k, d, e)
+ { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha1_vm_test()
+{
+ return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
+}
+
+/*
+ * Calculate the SHA1 of a raw string
+ */
+function rstr_sha1(s)
+{
+ return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
+}
+
+/*
+ * Calculate the HMAC-SHA1 of a key and some data (raw strings)
+ */
+function rstr_hmac_sha1(key, data)
+{
+ var bkey = rstr2binb(key);
+ if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
+ return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
+}
+
+/*
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+ try { hexcase } catch(e) { hexcase=0; }
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var output = "";
+ var x;
+ for(var i = 0; i < input.length; i++)
+ {
+ x = input.charCodeAt(i);
+ output += hex_tab.charAt((x >>> 4) & 0x0F)
+ + hex_tab.charAt( x & 0x0F);
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+ try { b64pad } catch(e) { b64pad=''; }
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var output = "";
+ var len = input.length;
+ for(var i = 0; i < len; i += 3)
+ {
+ var triplet = (input.charCodeAt(i) << 16)
+ | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+ | (i + 2 < len ? input.charCodeAt(i+2) : 0);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+ else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+ }
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+ var divisor = encoding.length;
+ var remainders = Array();
+ var i, q, x, quotient;
+
+ /* Convert to an array of 16-bit big-endian values, forming the dividend */
+ var dividend = Array(Math.ceil(input.length / 2));
+ for(i = 0; i < dividend.length; i++)
+ {
+ dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+ }
+
+ /*
+ * Repeatedly perform a long division. The binary array forms the dividend,
+ * the length of the encoding is the divisor. Once computed, the quotient
+ * forms the dividend for the next step. We stop when the dividend is zero.
+ * All remainders are stored for later use.
+ */
+ while(dividend.length > 0)
+ {
+ quotient = Array();
+ x = 0;
+ for(i = 0; i < dividend.length; i++)
+ {
+ x = (x << 16) + dividend[i];
+ q = Math.floor(x / divisor);
+ x -= q * divisor;
+ if(quotient.length > 0 || q > 0)
+ quotient[quotient.length] = q;
+ }
+ remainders[remainders.length] = x;
+ dividend = quotient;
+ }
+
+ /* Convert the remainders to the output string */
+ var output = "";
+ for(i = remainders.length - 1; i >= 0; i--)
+ output += encoding.charAt(remainders[i]);
+
+ /* Append leading zero equivalents */
+ var full_length = Math.ceil(input.length * 8 /
+ (Math.log(encoding.length) / Math.log(2)))
+ for(i = output.length; i < full_length; i++)
+ output = encoding[0] + output;
+
+ return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+ var output = "";
+ var i = -1;
+ var x, y;
+
+ while(++i < input.length)
+ {
+ /* Decode utf-16 surrogate pairs */
+ x = input.charCodeAt(i);
+ y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+ if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+ {
+ x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+ i++;
+ }
+
+ /* Encode output as utf-8 */
+ if(x <= 0x7F)
+ output += String.fromCharCode(x);
+ else if(x <= 0x7FF)
+ output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0xFFFF)
+ output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0x1FFFFF)
+ output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+ 0x80 | ((x >>> 12) & 0x3F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ }
+ return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length; i++)
+ output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
+ (input.charCodeAt(i) >>> 8) & 0xFF);
+ return output;
+}
+
+function str2rstr_utf16be(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length; i++)
+ output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+ input.charCodeAt(i) & 0xFF);
+ return output;
+}
+
+/*
+ * Convert a raw string to an array of big-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binb(input)
+{
+ var output = Array(input.length >> 2);
+ for(var i = 0; i < output.length; i++)
+ output[i] = 0;
+ for(var i = 0; i < input.length * 8; i += 8)
+ output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
+ return output;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+function binb2rstr(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length * 32; i += 8)
+ output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
+ return output;
+}
+
+/*
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
+ */
+function binb_sha1(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << (24 - len % 32);
+ x[((len + 64 >> 9) << 4) + 15] = len;
+
+ var w = Array(80);
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+ var e = -1009589776;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+ var olde = e;
+
+ for(var j = 0; j < 80; j++)
+ {
+ if(j < 16) w[j] = x[i + j];
+ else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
+ var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
+ safe_add(safe_add(e, w[j]), sha1_kt(j)));
+ e = d;
+ d = c;
+ c = bit_rol(b, 30);
+ b = a;
+ a = t;
+ }
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ e = safe_add(e, olde);
+ }
+ return Array(a, b, c, d, e);
+
+}
+
+/*
+ * Perform the appropriate triplet combination function for the current
+ * iteration
+ */
+function sha1_ft(t, b, c, d)
+{
+ if(t < 20) return (b & c) | ((~b) & d);
+ if(t < 40) return b ^ c ^ d;
+ if(t < 60) return (b & c) | (b & d) | (c & d);
+ return b ^ c ^ d;
+}
+
+/*
+ * Determine the appropriate additive constant for the current iteration
+ */
+function sha1_kt(t)
+{
+ return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
+ (t < 60) ? -1894007588 : -899497514;
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/ticket.js b/src/wok/plugins/kimchi/ui/spice-html5/ticket.js
new file mode 100644
index 0000000..96577a3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/ticket.js
@@ -0,0 +1,250 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+var SHA_DIGEST_LENGTH = 20;
+
+/*----------------------------------------------------------------------------
+** General ticket RSA encryption functions - just good enough to
+** support what we need to send back an encrypted ticket.
+**--------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+** OAEP padding functions. Inspired by the OpenSSL implementation.
+**--------------------------------------------------------------------------*/
+function MGF1(mask, seed)
+{
+ var i, j, outlen;
+ for (i = 0, outlen = 0; outlen < mask.length; i++)
+ {
+ var combo_buf = new String;
+
+ for (j = 0; j < seed.length; j++)
+ combo_buf += String.fromCharCode(seed[j]);
+ combo_buf += String.fromCharCode((i >> 24) & 255);
+ combo_buf += String.fromCharCode((i >> 16) & 255);
+ combo_buf += String.fromCharCode((i >> 8) & 255);
+ combo_buf += String.fromCharCode((i) & 255);
+
+ var combo_hash = rstr_sha1(combo_buf);
+ for (j = 0; j < combo_hash.length && outlen < mask.length; j++, outlen++)
+ {
+ mask[outlen] = combo_hash.charCodeAt(j);
+ }
+ }
+}
+
+
+function RSA_padding_add_PKCS1_OAEP(tolen, from, param)
+{
+ var seed = new Array(SHA_DIGEST_LENGTH);
+ var rand = new SecureRandom();
+ rand.nextBytes(seed);
+
+ var dblen = tolen - 1 - seed.length;
+ var db = new Array(dblen);
+ var padlen = dblen - from.length - 1;
+ var i;
+
+ if (param === undefined)
+ param = "";
+
+ if (padlen < SHA_DIGEST_LENGTH)
+ {
+ console.log("Error - data too large for key size.");
+ return null;
+ }
+
+ for (i = 0; i < padlen; i++)
+ db[i] = 0;
+
+ var param_hash = rstr_sha1(param);
+ for (i = 0; i < param_hash.length; i++)
+ db[i] = param_hash.charCodeAt(i);
+
+ db[padlen] = 1;
+ for (i = 0; i < from.length; i++)
+ db[i + padlen + 1] = from.charCodeAt(i);
+
+ var dbmask = new Array(dblen);
+ if (MGF1(dbmask, seed) < 0)
+ return null;
+
+ for (i = 0; i < dbmask.length; i++)
+ db[i] ^= dbmask[i];
+
+
+ var seedmask = Array(SHA_DIGEST_LENGTH);
+ if (MGF1(seedmask, db) < 0)
+ return null;
+
+ for (i = 0; i < seedmask.length; i++)
+ seed[i] ^= seedmask[i];
+
+ var ret = new String;
+ ret += String.fromCharCode(0);
+ for (i = 0; i < seed.length; i++)
+ ret += String.fromCharCode(seed[i]);
+ for (i = 0; i < db.length; i++)
+ ret += String.fromCharCode(db[i]);
+ return ret;
+}
+
+
+function asn_get_length(u8, at)
+{
+ var len = u8[at++];
+ if (len > 0x80)
+ {
+ if (len != 0x81)
+ {
+ console.log("Error: we lazily don't support keys bigger than 255 bytes. It'd be easy to fix.");
+ return null;
+ }
+ len = u8[at++];
+ }
+
+ return [ at, len];
+}
+
+function find_sequence(u8, at)
+{
+ var lenblock;
+ at = at || 0;
+ if (u8[at++] != 0x30)
+ {
+ console.log("Error: public key should start with a sequence flag.");
+ return null;
+ }
+
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+ return lenblock;
+}
+
+/*----------------------------------------------------------------------------
+** Extract an RSA key from a memory buffer
+**--------------------------------------------------------------------------*/
+function create_rsa_from_mb(mb, at)
+{
+ var u8 = new Uint8Array(mb);
+ var lenblock;
+ var seq;
+ var ba;
+ var i;
+ var ret;
+
+ /* We have a sequence which contains a sequence followed by a bit string */
+ seq = find_sequence(u8, at);
+ if (! seq)
+ return null;
+
+ at = seq[0];
+ seq = find_sequence(u8, at);
+ if (! seq)
+ return null;
+
+ /* Skip over the contained sequence */
+ at = seq[0] + seq[1];
+ if (u8[at++] != 0x3)
+ {
+ console.log("Error: expecting bit string next.");
+ return null;
+ }
+
+ /* Get the bit string, which is *itself* a sequence. Having fun yet? */
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+
+ at = lenblock[0];
+ if (u8[at] != 0 && u8[at + 1] != 0x30)
+ {
+ console.log("Error: unexpected values in bit string.");
+ return null;
+ }
+
+ /* Okay, now we have a sequence of two binary values, we hope. */
+ seq = find_sequence(u8, at + 1);
+ if (! seq)
+ return null;
+
+ at = seq[0];
+ if (u8[at++] != 0x02)
+ {
+ console.log("Error: expecting integer n next.");
+ return null;
+ }
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+ at = lenblock[0];
+
+ ba = new Array(lenblock[1]);
+ for (i = 0; i < lenblock[1]; i++)
+ ba[i] = u8[at + i];
+
+ ret = new RSAKey();
+ ret.n = new BigInteger(ba);
+
+ at += lenblock[1];
+
+ if (u8[at++] != 0x02)
+ {
+ console.log("Error: expecting integer e next.");
+ return null;
+ }
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+ at = lenblock[0];
+
+ ret.e = u8[at++];
+ for (i = 1; i < lenblock[1]; i++)
+ {
+ ret.e <<= 8;
+ ret.e |= u8[at++];
+ }
+
+ return ret;
+}
+
+function rsa_encrypt(rsa, str)
+{
+ var i;
+ var ret = [];
+ var oaep = RSA_padding_add_PKCS1_OAEP((rsa.n.bitLength()+7)>>3, str);
+ if (! oaep)
+ return null;
+
+ var ba = new Array(oaep.length);
+
+ for (i = 0; i < oaep.length; i++)
+ ba[i] = oaep.charCodeAt(i);
+ var bigint = new BigInteger(ba);
+ var enc = rsa.doPublic(bigint);
+ var h = enc.toString(16);
+ if ((h.length & 1) != 0)
+ h = "0" + h;
+ for (i = 0; i < h.length; i += 2)
+ ret[i / 2] = parseInt(h.substring(i, i + 2), 16);
+ return ret;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/utils.js b/src/wok/plugins/kimchi/ui/spice-html5/utils.js
new file mode 100644
index 0000000..9eb42ff
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/utils.js
@@ -0,0 +1,265 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** Utility settings and functions for Spice
+**--------------------------------------------------------------------------*/
+var DEBUG = 0;
+var DUMP_DRAWS = false;
+var DUMP_CANVASES = false;
+
+
+/*----------------------------------------------------------------------------
+** combine_array_buffers
+** Combine two array buffers.
+** FIXME - this can't be optimal. See wire.js about eliminating the need.
+**--------------------------------------------------------------------------*/
+function combine_array_buffers(a1, a2)
+{
+ var in1 = new Uint8Array(a1);
+ var in2 = new Uint8Array(a2);
+ var ret = new ArrayBuffer(a1.byteLength + a2.byteLength);
+ var out = new Uint8Array(ret);
+ var o = 0;
+ var i;
+ for (i = 0; i < in1.length; i++)
+ out[o++] = in1[i];
+ for (i = 0; i < in2.length; i++)
+ out[o++] = in2[i];
+
+ return ret;
+}
+
+/*----------------------------------------------------------------------------
+** hexdump_buffer
+**--------------------------------------------------------------------------*/
+function hexdump_buffer(a)
+{
+ var mg = new Uint8Array(a);
+ var hex = "";
+ var str = "";
+ var last_zeros = 0;
+ for (var i = 0; i < mg.length; i++)
+ {
+ var h = Number(mg[i]).toString(16);
+ if (h.length == 1)
+ hex += "0";
+ hex += h + " ";
+
+ if (mg[i] == 10 || mg[i] == 13 || mg[i] == 8)
+ str += ".";
+ else
+ str += String.fromCharCode(mg[i]);
+
+ if ((i % 16 == 15) || (i == (mg.length - 1)))
+ {
+ while (i % 16 != 15)
+ {
+ hex += " ";
+ i++;
+ }
+
+ if (last_zeros == 0)
+ console.log(hex + " | " + str);
+
+ if (hex == "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ")
+ {
+ if (last_zeros == 1)
+ {
+ console.log(".");
+ last_zeros++;
+ }
+ else if (last_zeros == 0)
+ last_zeros++;
+ }
+ else
+ last_zeros = 0;
+
+ hex = str = "";
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+** Converting keycodes to AT scancodes is very hard.
+** luckly there are some resources on the web and in the Xorg driver that help
+** us figure out what browser depenend keycodes match to what scancodes.
+**
+** This will most likely not work for non US keyboard and browsers other than
+** modern Chrome and FireFox.
+**--------------------------------------------------------------------------*/
+var common_scanmap = [];
+common_scanmap['Q'.charCodeAt(0)] = KEY_Q;
+common_scanmap['W'.charCodeAt(0)] = KEY_W;
+common_scanmap['E'.charCodeAt(0)] = KEY_E;
+common_scanmap['R'.charCodeAt(0)] = KEY_R;
+common_scanmap['T'.charCodeAt(0)] = KEY_T;
+common_scanmap['Y'.charCodeAt(0)] = KEY_Y;
+common_scanmap['U'.charCodeAt(0)] = KEY_U;
+common_scanmap['I'.charCodeAt(0)] = KEY_I;
+common_scanmap['O'.charCodeAt(0)] = KEY_O;
+common_scanmap['P'.charCodeAt(0)] = KEY_P;
+common_scanmap['A'.charCodeAt(0)] = KEY_A;
+common_scanmap['S'.charCodeAt(0)] = KEY_S;
+common_scanmap['D'.charCodeAt(0)] = KEY_D;
+common_scanmap['F'.charCodeAt(0)] = KEY_F;
+common_scanmap['G'.charCodeAt(0)] = KEY_G;
+common_scanmap['H'.charCodeAt(0)] = KEY_H;
+common_scanmap['J'.charCodeAt(0)] = KEY_J;
+common_scanmap['K'.charCodeAt(0)] = KEY_K;
+common_scanmap['L'.charCodeAt(0)] = KEY_L;
+common_scanmap['Z'.charCodeAt(0)] = KEY_Z;
+common_scanmap['X'.charCodeAt(0)] = KEY_X;
+common_scanmap['C'.charCodeAt(0)] = KEY_C;
+common_scanmap['V'.charCodeAt(0)] = KEY_V;
+common_scanmap['B'.charCodeAt(0)] = KEY_B;
+common_scanmap['N'.charCodeAt(0)] = KEY_N;
+common_scanmap['M'.charCodeAt(0)] = KEY_M;
+common_scanmap[' '.charCodeAt(0)] = KEY_Space;
+common_scanmap[13] = KEY_Enter;
+common_scanmap[27] = KEY_Escape;
+common_scanmap[8] = KEY_BackSpace;
+common_scanmap[9] = KEY_Tab;
+common_scanmap[16] = KEY_ShiftL;
+common_scanmap[17] = KEY_LCtrl;
+common_scanmap[18] = KEY_Alt;
+common_scanmap[20] = KEY_CapsLock;
+common_scanmap[144] = KEY_NumLock;
+common_scanmap[112] = KEY_F1;
+common_scanmap[113] = KEY_F2;
+common_scanmap[114] = KEY_F3;
+common_scanmap[115] = KEY_F4;
+common_scanmap[116] = KEY_F5;
+common_scanmap[117] = KEY_F6;
+common_scanmap[118] = KEY_F7;
+common_scanmap[119] = KEY_F8;
+common_scanmap[120] = KEY_F9;
+common_scanmap[121] = KEY_F10;
+common_scanmap[122] = KEY_F11;
+common_scanmap[123] = KEY_F12;
+
+/* These externded scancodes do not line up with values from atKeynames */
+common_scanmap[42] = 99;
+common_scanmap[19] = 101; // Break
+common_scanmap[111] = 0xE035; // KP_Divide
+common_scanmap[106] = 0xE037; // KP_Multiply
+common_scanmap[36] = 0xE047; // Home
+common_scanmap[38] = 0xE048; // Up
+common_scanmap[33] = 0xE049; // PgUp
+common_scanmap[37] = 0xE04B; // Left
+common_scanmap[39] = 0xE04D; // Right
+common_scanmap[35] = 0xE04F; // End
+common_scanmap[40] = 0xE050; // Down
+common_scanmap[34] = 0xE051; // PgDown
+common_scanmap[45] = 0xE052; // Insert
+common_scanmap[46] = 0xE053; // Delete
+common_scanmap[44] = 0x2A37; // Print
+
+/* These are not common between ALL browsers but are between Firefox and DOM3 */
+common_scanmap['1'.charCodeAt(0)] = KEY_1;
+common_scanmap['2'.charCodeAt(0)] = KEY_2;
+common_scanmap['3'.charCodeAt(0)] = KEY_3;
+common_scanmap['4'.charCodeAt(0)] = KEY_4;
+common_scanmap['5'.charCodeAt(0)] = KEY_5;
+common_scanmap['6'.charCodeAt(0)] = KEY_6;
+common_scanmap['7'.charCodeAt(0)] = KEY_7;
+common_scanmap['8'.charCodeAt(0)] = KEY_8;
+common_scanmap['9'.charCodeAt(0)] = KEY_9;
+common_scanmap['0'.charCodeAt(0)] = KEY_0;
+common_scanmap[145] = KEY_ScrollLock;
+common_scanmap[103] = KEY_KP_7;
+common_scanmap[104] = KEY_KP_8;
+common_scanmap[105] = KEY_KP_9;
+common_scanmap[100] = KEY_KP_4;
+common_scanmap[101] = KEY_KP_5;
+common_scanmap[102] = KEY_KP_6;
+common_scanmap[107] = KEY_KP_Plus;
+common_scanmap[97] = KEY_KP_1;
+common_scanmap[98] = KEY_KP_2;
+common_scanmap[99] = KEY_KP_3;
+common_scanmap[96] = KEY_KP_0;
+common_scanmap[110] = KEY_KP_Decimal;
+common_scanmap[191] = KEY_Slash;
+common_scanmap[190] = KEY_Period;
+common_scanmap[188] = KEY_Comma;
+common_scanmap[220] = KEY_BSlash;
+common_scanmap[192] = KEY_Tilde;
+common_scanmap[222] = KEY_Quote;
+common_scanmap[219] = KEY_LBrace;
+common_scanmap[221] = KEY_RBrace;
+
+common_scanmap[91] = 0xE05B; //KEY_LMeta
+common_scanmap[92] = 0xE05C; //KEY_RMeta
+common_scanmap[93] = 0xE05D; //KEY_Menu
+
+/* Firefox/Mozilla codes */
+var firefox_scanmap = [];
+firefox_scanmap[173] = KEY_Minus;
+firefox_scanmap[109] = KEY_Minus;
+firefox_scanmap[61] = KEY_Equal;
+firefox_scanmap[59] = KEY_SemiColon;
+
+/* DOM3 codes */
+var DOM_scanmap = [];
+DOM_scanmap[189] = KEY_Minus;
+DOM_scanmap[187] = KEY_Equal;
+DOM_scanmap[186] = KEY_SemiColon;
+
+function get_scancode(code)
+{
+ if (common_scanmap[code] === undefined)
+ {
+ if (navigator.userAgent.indexOf("Firefox") != -1)
+ return firefox_scanmap[code];
+ else
+ return DOM_scanmap[code];
+ }
+ else
+ return common_scanmap[code];
+}
+
+function keycode_to_start_scan(code)
+{
+ var scancode = get_scancode(code);
+ if (scancode === undefined)
+ {
+ alert('no map for ' + code);
+ return 0;
+ }
+
+ if (scancode < 0x100) {
+ return scancode;
+ } else {
+ return 0xe0 | ((scancode - 0x100) << 8);
+ }
+}
+
+function keycode_to_end_scan(code)
+{
+ var scancode = get_scancode(code);
+ if (scancode === undefined)
+ return 0;
+
+ if (scancode < 0x100) {
+ return scancode | 0x80;
+ } else {
+ return 0x80e0 | ((scancode - 0x100) << 8);
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/webm.js b/src/wok/plugins/kimchi/ui/spice-html5/webm.js
new file mode 100644
index 0000000..35cbc07
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/webm.js
@@ -0,0 +1,553 @@
+"use strict";
+/*
+ Copyright (C) 2014 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** EBML identifiers
+**--------------------------------------------------------------------------*/
+var EBML_HEADER = [ 0x1a, 0x45, 0xdf, 0xa3 ];
+var EBML_HEADER_VERSION = [ 0x42, 0x86 ];
+var EBML_HEADER_READ_VERSION = [ 0x42, 0xf7 ];
+var EBML_HEADER_MAX_ID_LENGTH = [ 0x42, 0xf2 ];
+var EBML_HEADER_MAX_SIZE_LENGTH = [ 0x42, 0xf3 ];
+var EBML_HEADER_DOC_TYPE = [ 0x42, 0x82 ];
+var EBML_HEADER_DOC_TYPE_VERSION = [ 0x42, 0x87 ];
+var EBML_HEADER_DOC_TYPE_READ_VERSION = [ 0x42, 0x85 ];
+
+var WEBM_SEGMENT_HEADER = [ 0x18, 0x53, 0x80, 0x67 ];
+var WEBM_SEGMENT_INFORMATION = [ 0x15, 0x49, 0xA9, 0x66 ];
+
+var WEBM_TIMECODE_SCALE = [ 0x2A, 0xD7, 0xB1 ];
+var WEBM_MUXING_APP = [ 0x4D, 0x80 ];
+var WEBM_WRITING_APP = [ 0x57, 0x41 ];
+
+var WEBM_SEEK_HEAD = [ 0x11, 0x4D, 0x9B, 0x74 ];
+var WEBM_SEEK = [ 0x4D, 0xBB ];
+var WEBM_SEEK_ID = [ 0x53, 0xAB ];
+var WEBM_SEEK_POSITION = [ 0x53, 0xAC ];
+
+var WEBM_TRACKS = [ 0x16, 0x54, 0xAE, 0x6B ];
+var WEBM_TRACK_ENTRY = [ 0xAE ];
+var WEBM_TRACK_NUMBER = [ 0xD7 ];
+var WEBM_TRACK_UID = [ 0x73, 0xC5 ];
+var WEBM_TRACK_TYPE = [ 0x83 ];
+var WEBM_FLAG_ENABLED = [ 0xB9 ];
+var WEBM_FLAG_DEFAULT = [ 0x88 ];
+var WEBM_FLAG_FORCED = [ 0x55, 0xAA ];
+var WEBM_FLAG_LACING = [ 0x9C ];
+var WEBM_MIN_CACHE = [ 0x6D, 0xE7 ];
+
+var WEBM_MAX_BLOCK_ADDITION_ID = [ 0x55, 0xEE ];
+var WEBM_CODEC_DECODE_ALL = [ 0xAA ];
+var WEBM_SEEK_PRE_ROLL = [ 0x56, 0xBB ];
+var WEBM_CODEC_DELAY = [ 0x56, 0xAA ];
+var WEBM_CODEC_PRIVATE = [ 0x63, 0xA2 ];
+var WEBM_CODEC_ID = [ 0x86 ];
+
+var WEBM_AUDIO = [ 0xE1 ] ;
+var WEBM_SAMPLING_FREQUENCY = [ 0xB5 ] ;
+var WEBM_CHANNELS = [ 0x9F ] ;
+
+var WEBM_CLUSTER = [ 0x1F, 0x43, 0xB6, 0x75 ];
+var WEBM_TIME_CODE = [ 0xE7 ] ;
+var WEBM_SIMPLE_BLOCK = [ 0xA3 ] ;
+
+/*----------------------------------------------------------------------------
+** Various OPUS / Webm constants
+**--------------------------------------------------------------------------*/
+var CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME = 1 << 7;
+
+var OPUS_FREQUENCY = 48000;
+var OPUS_CHANNELS = 2;
+
+var SPICE_PLAYBACK_CODEC = 'audio/webm; codecs="opus"';
+var MAX_CLUSTER_TIME = 1000;
+
+var GAP_DETECTION_THRESHOLD = 50;
+
+/*----------------------------------------------------------------------------
+** EBML utility functions
+** These classes can create the binary representation of a webm file
+**--------------------------------------------------------------------------*/
+function EBML_write_u1_data_len(len, dv, at)
+{
+ var b = 0x80 | len;
+ dv.setUint8(at, b);
+ return at + 1;
+}
+
+function EBML_write_u8_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(1, dv, at);
+ dv.setUint8(at, val);
+ return at + 1;
+}
+
+function EBML_write_u32_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(4, dv, at);
+ dv.setUint32(at, val);
+ return at + 4;
+}
+
+function EBML_write_u16_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(2, dv, at);
+ dv.setUint16(at, val);
+ return at + 2;
+}
+
+function EBML_write_float_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(4, dv, at);
+ dv.setFloat32(at, val);
+ return at + 4;
+}
+
+
+
+function EBML_write_u64_data_len(len, dv, at)
+{
+ /* Javascript doesn't do 64 bit ints, so this cheats and
+ just has a max of 32 bits. Fine for our purposes */
+ dv.setUint8(at++, 0x01);
+ dv.setUint8(at++, 0x00);
+ dv.setUint8(at++, 0x00);
+ dv.setUint8(at++, 0x00);
+ var val = len & 0xFFFFFFFF;
+ for (var shift = 24; shift >= 0; shift -= 8)
+ dv.setUint8(at++, val >> shift);
+ return at;
+}
+
+function EBML_write_array(arr, dv, at)
+{
+ for (var i = 0; i < arr.length; i++)
+ dv.setUint8(at + i, arr[i]);
+ return at + arr.length;
+}
+
+function EBML_write_string(str, dv, at)
+{
+ for (var i = 0; i < str.length; i++)
+ dv.setUint8(at + i, str.charCodeAt(i));
+ return at + str.length;
+}
+
+function EBML_write_data(id, data, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ if (data.length < 127)
+ at = EBML_write_u1_data_len(data.length, dv, at);
+ else
+ at = EBML_write_u64_data_len(data.length, dv, at);
+ if ((typeof data) == "string")
+ at = EBML_write_string(data, dv, at);
+ else
+ at = EBML_write_array(data, dv, at);
+ return at;
+}
+
+/*----------------------------------------------------------------------------
+** Webm objects
+** These classes can create the binary representation of a webm file
+**--------------------------------------------------------------------------*/
+function EBMLHeader()
+{
+ this.id = EBML_HEADER;
+ this.Version = 1;
+ this.ReadVersion = 1;
+ this.MaxIDLength = 4;
+ this.MaxSizeLength = 8;
+ this.DocType = "webm";
+ this.DocTypeVersion = 2; /* Not well specified by the WebM guys, but functionally required for Firefox */
+ this.DocTypeReadVersion = 2;
+}
+
+EBMLHeader.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(0x1f, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_VERSION, this.Version, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_READ_VERSION, this.ReadVersion, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_MAX_ID_LENGTH, this.MaxIDLength, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_MAX_SIZE_LENGTH, this.MaxSizeLength, dv, at);
+ at = EBML_write_data(EBML_HEADER_DOC_TYPE, this.DocType, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_VERSION, this.DocTypeVersion, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_READ_VERSION, this.DocTypeReadVersion, dv, at);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 0x1f + 8 + this.id.length;
+ },
+}
+
+function webm_Segment()
+{
+ this.id = WEBM_SEGMENT_HEADER;
+}
+
+webm_Segment.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+
+ at = EBML_write_array(this.id, dv, at);
+ dv.setUint8(at++, 0xff);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 1;
+ },
+}
+
+function webm_SegmentInformation()
+{
+ this.id = WEBM_SEGMENT_INFORMATION;
+ this.timecode_scale = 1000000; /* 1 ms */
+ this.muxing_app = "spice";
+ this.writing_app = "spice-html5";
+
+}
+
+webm_SegmentInformation.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = EBML_write_u32_value(WEBM_TIMECODE_SCALE, this.timecode_scale, dv, at);
+ at = EBML_write_data(WEBM_MUXING_APP, this.muxing_app, dv, at);
+ at = EBML_write_data(WEBM_WRITING_APP, this.writing_app, dv, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ WEBM_TIMECODE_SCALE.length + 1 + 4 +
+ WEBM_MUXING_APP.length + 1 + this.muxing_app.length +
+ WEBM_WRITING_APP.length + 1 + this.writing_app.length;
+ },
+}
+
+function webm_Audio(frequency)
+{
+ this.id = WEBM_AUDIO;
+ this.sampling_frequency = frequency;
+ this.channels = OPUS_CHANNELS;
+}
+
+webm_Audio.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = EBML_write_u8_value(WEBM_CHANNELS, this.channels, dv, at);
+ at = EBML_write_float_value(WEBM_SAMPLING_FREQUENCY, this.sampling_frequency, dv, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ WEBM_SAMPLING_FREQUENCY.length + 1 + 4 +
+ WEBM_CHANNELS.length + 1 + 1;
+ },
+}
+
+
+/* ---------------------------
+ SeekHead not currently used. Hopefully not needed.
+*/
+function webm_Seek(seekid, pos)
+{
+ this.id = WEBM_SEEK;
+ this.pos = pos;
+ this.seekid = seekid;
+}
+
+webm_Seek.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u1_data_len(this.buffer_size() - 1 - this.id.length, dv, at);
+
+ at = EBML_write_data(WEBM_SEEK_ID, this.seekid, dv, at)
+ at = EBML_write_u16_value(WEBM_SEEK_POSITION, this.pos, dv, at)
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 1 +
+ WEBM_SEEK_ID.length + 1 + this.seekid.length +
+ WEBM_SEEK_POSITION.length + 1 + 2;
+ },
+}
+function webm_SeekHead(info_pos, track_pos)
+{
+ this.id = WEBM_SEEK_HEAD;
+ this.info = new webm_Seek(WEBM_SEGMENT_INFORMATION, info_pos);
+ this.track = new webm_Seek(WEBM_TRACKS, track_pos);
+}
+
+webm_SeekHead.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+
+ at = this.info.to_buffer(a, at);
+ at = this.track.to_buffer(a, at);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ this.info.buffer_size() +
+ this.track.buffer_size();
+ },
+}
+
+/* -------------------------------
+ End of Seek Head
+*/
+
+function webm_TrackEntry()
+{
+ this.id = WEBM_TRACK_ENTRY;
+ this.number = 1;
+ this.uid = 1;
+ this.type = 2; // Audio
+ this.flag_enabled = 1;
+ this.flag_default = 1;
+ this.flag_forced = 1;
+ this.flag_lacing = 0;
+ this.min_cache = 0; // fixme - check
+ this.max_block_addition_id = 0;
+ this.codec_decode_all = 0; // fixme - check
+ this.seek_pre_roll = 0; // 80000000; // fixme - check
+ this.codec_delay = 80000000; // Must match codec_private.preskip
+ this.codec_id = "A_OPUS";
+ this.audio = new webm_Audio(OPUS_FREQUENCY);
+
+ // See: http://tools.ietf.org/html/draft-terriberry-oggopus-01
+ this.codec_private = [ 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, // OpusHead
+ 0x01, // Version
+ OPUS_CHANNELS,
+ 0x00, 0x0F, // Preskip - 3840 samples - should be 8ms at 48kHz
+ 0x80, 0xbb, 0x00, 0x00, // 48000
+ 0x00, 0x00, // Output gain
+ 0x00 // Channel mapping family
+ ];
+}
+
+webm_TrackEntry.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = EBML_write_u8_value(WEBM_TRACK_NUMBER, this.number, dv, at);
+ at = EBML_write_u8_value(WEBM_TRACK_UID, this.uid, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_ENABLED, this.flag_enabled, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_DEFAULT, this.flag_default, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_FORCED, this.flag_forced, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_LACING, this.flag_lacing, dv, at);
+ at = EBML_write_data(WEBM_CODEC_ID, this.codec_id, dv, at);
+ at = EBML_write_u8_value(WEBM_MIN_CACHE, this.min_cache, dv, at);
+ at = EBML_write_u8_value(WEBM_MAX_BLOCK_ADDITION_ID, this.max_block_addition_id, dv, at);
+ at = EBML_write_u8_value(WEBM_CODEC_DECODE_ALL, this.codec_decode_all, dv, at);
+ at = EBML_write_u32_value(WEBM_CODEC_DELAY, this.codec_delay, dv, at);
+ at = EBML_write_u32_value(WEBM_SEEK_PRE_ROLL, this.seek_pre_roll, dv, at);
+ at = EBML_write_u8_value(WEBM_TRACK_TYPE, this.type, dv, at);
+ at = EBML_write_data(WEBM_CODEC_PRIVATE, this.codec_private, dv, at);
+
+ at = this.audio.to_buffer(a, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ WEBM_TRACK_NUMBER.length + 1 + 1 +
+ WEBM_TRACK_UID.length + 1 + 1 +
+ WEBM_TRACK_TYPE.length + 1 + 1 +
+ WEBM_FLAG_ENABLED.length + 1 + 1 +
+ WEBM_FLAG_DEFAULT.length + 1 + 1 +
+ WEBM_FLAG_FORCED.length + 1 + 1 +
+ WEBM_FLAG_LACING.length + 1 + 1 +
+ WEBM_MIN_CACHE.length + 1 + 1 +
+ WEBM_MAX_BLOCK_ADDITION_ID.length + 1 + 1 +
+ WEBM_CODEC_DECODE_ALL.length + 1 + 1 +
+ WEBM_SEEK_PRE_ROLL.length + 1 + 4 +
+ WEBM_CODEC_DELAY.length + 1 + 4 +
+ WEBM_CODEC_ID.length + this.codec_id.length + 1 +
+ WEBM_CODEC_PRIVATE.length + 1 + this.codec_private.length +
+ this.audio.buffer_size();
+ },
+}
+function webm_Tracks(entry)
+{
+ this.id = WEBM_TRACKS;
+ this.track_entry = entry;
+}
+
+webm_Tracks.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = this.track_entry.to_buffer(a, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ this.track_entry.buffer_size();
+ },
+}
+
+function webm_Cluster(timecode, data)
+{
+ this.id = WEBM_CLUSTER;
+ this.timecode = timecode;
+ this.data = data;
+}
+
+webm_Cluster.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ dv.setUint8(at++, 0xff);
+ at = EBML_write_u32_value(WEBM_TIME_CODE, this.timecode, dv, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 1 +
+ WEBM_TIME_CODE.length + 1 + 4;
+ },
+}
+
+function webm_SimpleBlock(timecode, data, keyframe)
+{
+ this.id = WEBM_SIMPLE_BLOCK;
+ this.timecode = timecode;
+ this.data = data;
+ this.keyframe = keyframe;
+}
+
+webm_SimpleBlock.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.data.byteLength + 4, dv, at);
+ at = EBML_write_u1_data_len(1, dv, at); // Track #
+ dv.setUint16(at, this.timecode); at += 2; // timecode - relative to cluster
+ dv.setUint8(at, this.keyframe ? CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 0); at += 1; // flags
+
+ // FIXME - There should be a better way to copy
+ var u8 = new Uint8Array(this.data);
+ for (var i = 0; i < this.data.byteLength; i++)
+ dv.setUint8(at++, u8[i]);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ 1 + 2 + 1 +
+ this.data.byteLength;
+ },
+}
+
+function webm_Header()
+{
+ this.ebml = new EBMLHeader;
+ this.segment = new webm_Segment;
+ this.seek_head = new webm_SeekHead(0, 0);
+
+ this.seek_head.info.pos = this.segment.buffer_size() + this.seek_head.buffer_size();
+
+ this.info = new webm_SegmentInformation;
+
+ this.seek_head.track.pos = this.seek_head.info.pos + this.info.buffer_size();
+
+ this.track_entry = new webm_TrackEntry;
+ this.tracks = new webm_Tracks(this.track_entry);
+}
+
+webm_Header.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ at = this.ebml.to_buffer(a, at);
+ at = this.segment.to_buffer(a, at);
+ at = this.info.to_buffer(a, at);
+ at = this.tracks.to_buffer(a, at);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.ebml.buffer_size() +
+ this.segment.buffer_size() +
+ this.info.buffer_size() +
+ this.tracks.buffer_size();
+ },
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/wire.js b/src/wok/plugins/kimchi/ui/spice-html5/wire.js
new file mode 100644
index 0000000..7407ce7
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/wire.js
@@ -0,0 +1,123 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite at codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*--------------------------------------------------------------------------------------
+** SpiceWireReader
+** This class will receive messages from a WebSocket and relay it to a given
+** callback. It will optionally save and pass along a header, useful in processing
+** the mini message format.
+**--------------------------------------------------------------------------------------*/
+function SpiceWireReader(sc, callback)
+{
+ this.sc = sc;
+ this.callback = callback;
+ this.needed = 0;
+
+ this.buffers = [];
+
+ this.sc.ws.wire_reader = this;
+ this.sc.ws.binaryType = "arraybuffer";
+ this.sc.ws.addEventListener('message', wire_blob_catcher);
+}
+
+SpiceWireReader.prototype =
+{
+
+ /*------------------------------------------------------------------------
+ ** Process messages coming in from our WebSocket
+ **----------------------------------------------------------------------*/
+ inbound: function (mb)
+ {
+ var at;
+
+ /* Just buffer if we don't need anything yet */
+ if (this.needed == 0)
+ {
+ this.buffers.push(mb);
+ return;
+ }
+
+ /* Optimization - if we have just one inbound block, and it's
+ suitable for our needs, just use it. */
+ if (this.buffers.length == 0 && mb.byteLength >= this.needed)
+ {
+ if (mb.byteLength > this.needed)
+ {
+ this.buffers.push(mb.slice(this.needed));
+ mb = mb.slice(0, this.needed);
+ }
+ this.callback.call(this.sc, mb,
+ this.saved_msg_header || undefined);
+ }
+ else
+ {
+ this.buffers.push(mb);
+ }
+
+
+ /* If we have fragments that add up to what we need, combine them */
+ /* FIXME - it would be faster to revise the processing code to handle
+ ** multiple fragments directly. Essentially, we should be
+ ** able to do this without any slice() or combine_array_buffers() calls */
+ while (this.buffers.length > 1 && this.buffers[0].byteLength < this.needed)
+ {
+ var mb1 = this.buffers.shift();
+ var mb2 = this.buffers.shift();
+
+ this.buffers.unshift(combine_array_buffers(mb1, mb2));
+ }
+
+
+ while (this.buffers.length > 0 && this.buffers[0].byteLength >= this.needed)
+ {
+ mb = this.buffers.shift();
+ if (mb.byteLength > this.needed)
+ {
+ this.buffers.unshift(mb.slice(this.needed));
+ mb = mb.slice(0, this.needed);
+ }
+ this.callback.call(this.sc, mb,
+ this.saved_msg_header || undefined);
+ }
+
+ },
+
+ request: function(n)
+ {
+ this.needed = n;
+ },
+
+ save_header: function(h)
+ {
+ this.saved_msg_header = h;
+ },
+
+ clear_header: function()
+ {
+ this.saved_msg_header = undefined;
+ },
+}
+
+function wire_blob_catcher(e)
+{
+ DEBUG > 1 && console.log(">> WebSockets.onmessage");
+ DEBUG > 1 && console.log("id " + this.wire_reader.sc.connection_id +"; type " + this.wire_reader.sc.type);
+ SpiceWireReader.prototype.inbound.call(this.wire_reader, e.data);
+}
diff --git a/src/wok/plugins/kimchi/utils.py b/src/wok/plugins/kimchi/utils.py
new file mode 100644
index 0000000..2480362
--- /dev/null
+++ b/src/wok/plugins/kimchi/utils.py
@@ -0,0 +1,39 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import re
+
+from wok.exception import InvalidParameter
+
+
+def _uri_to_name(collection, uri):
+ expr = '/plugins/kimchi/%s/(.*?)$' % collection
+ m = re.match(expr, uri)
+ if not m:
+ raise InvalidParameter("WOKUTILS0001E", {'uri': uri})
+ return m.group(1)
+
+
+def template_name_from_uri(uri):
+ return _uri_to_name('templates', uri)
+
+
+def pool_name_from_uri(uri):
+ return _uri_to_name('storagepools', uri)
diff --git a/src/wok/plugins/kimchi/vmtemplate.py b/src/wok/plugins/kimchi/vmtemplate.py
new file mode 100644
index 0000000..07e70ba
--- /dev/null
+++ b/src/wok/plugins/kimchi/vmtemplate.py
@@ -0,0 +1,431 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import stat
+import time
+import urlparse
+import uuid
+from lxml import etree
+from lxml.builder import E
+
+from wok.exception import InvalidParameter, ImageFormatError, IsoFormatError
+from wok.exception import MissingParameter, OperationFailed
+from wok.utils import check_url_path
+
+import imageinfo
+import osinfo
+from isoinfo import IsoImage
+from utils import pool_name_from_uri
+from xmlutils.cpu import get_cpu_xml
+from xmlutils.disk import get_disk_xml
+from xmlutils.graphics import get_graphics_xml
+from xmlutils.interface import get_iface_xml
+from xmlutils.qemucmdline import get_qemucmdline_xml
+
+
+class VMTemplate(object):
+ def __init__(self, args, scan=False):
+ """
+ Construct a VM Template from a widely variable amount of information.
+ The only required parameter is a name for the VMTemplate. If present,
+ the os_distro and os_version fields are used to lookup recommended
+ settings. Any parameters provided by the caller will override the
+ defaults. If scan is True and a cdrom or a base img is present, the
+ operating system will be detected by probing the installation media.
+ """
+ self.info = {}
+ self.fc_host_support = args.get('fc_host_support')
+
+ # Fetch defaults based on the os distro and version
+ try:
+ distro, version = self._get_os_info(args, scan)
+ except ImageFormatError as e:
+ raise OperationFailed('KCHTMPL0020E', {'err': e.message})
+ os_distro = args.get('os_distro', distro)
+ os_version = args.get('os_version', version)
+ entry = osinfo.lookup(os_distro, os_version)
+ self.info.update(entry)
+
+ # Auto-generate a template name and no one is passed
+ if 'name' not in args or args['name'] == '':
+ args['name'] = self._gen_name(distro, version)
+ self.name = args['name']
+
+ # Override with the passed in parameters
+ graph_args = args.get('graphics')
+ if graph_args:
+ graphics = dict(self.info['graphics'])
+ graphics.update(graph_args)
+ args['graphics'] = graphics
+ self.info.update(args)
+
+ # Assign right disk format to logical and [i]scsi storagepools
+ if self._get_storage_type() in ['logical', 'iscsi', 'scsi']:
+ for i, disk in enumerate(self.info['disks']):
+ self.info['disks'][i]['format'] = 'raw'
+
+ def _get_os_info(self, args, scan):
+ distro = version = 'unknown'
+
+ # Identify the cdrom if present
+ iso = args.get('cdrom', '')
+ if len(iso) > 0:
+ if not iso.startswith('/'):
+ self.info.update({'iso_stream': True})
+
+ if scan:
+ distro, version = self.get_iso_info(iso)
+
+ return distro, version
+
+ # CDROM is not presented: check for base image
+ base_imgs = []
+ for d in args.get('disks', []):
+ if 'base' in d.keys():
+ base_imgs.append(d)
+ if scan:
+ distro, version = imageinfo.probe_image(d['base'])
+
+ if 'size' not in d.keys():
+ d_info = imageinfo.probe_img_info(d['base'])
+ d['size'] = d_info['virtual-size']
+
+ if len(base_imgs) == 0:
+ raise MissingParameter("KCHTMPL0016E")
+
+ return distro, version
+
+ def _gen_name(self, distro, version):
+ if distro == 'unknown':
+ name = str(uuid.uuid4())
+ else:
+ name = distro + version + '.' + str(int(time.time() * 1000))
+ return name
+
+ def get_iso_info(self, iso):
+ iso_prefixes = ['/', 'http', 'https', 'ftp', 'ftps', 'tftp']
+ if len(filter(iso.startswith, iso_prefixes)) == 0:
+ raise InvalidParameter("KCHTMPL0006E", {'param': iso})
+ try:
+ iso_img = IsoImage(iso)
+ return iso_img.probe()
+ except IsoFormatError:
+ raise InvalidParameter("KCHISO0001E", {'filename': iso})
+
+ def _get_cdrom_xml(self, libvirt_stream_protocols):
+ if 'cdrom' not in self.info:
+ return ''
+
+ params = {}
+ params['type'] = 'cdrom'
+ params['format'] = 'raw'
+ params['bus'] = self.info['cdrom_bus']
+ params['index'] = self.info['cdrom_index']
+ params['path'] = self.info['cdrom']
+
+ if self.info.get('iso_stream', False):
+ protocol = urlparse.urlparse(params['path']).scheme
+ if protocol not in libvirt_stream_protocols:
+ driveOpt = 'file=%(path)s,if=none,id=drive-%(bus)s0-1-0,'
+ driveOpt += 'readonly=on,format=%(format)s'
+
+ deviceOpt = '%(bus)s-cd,bus=%(bus)s.1,unit=0,'
+ deviceOpt += 'drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'
+
+ args = {}
+ args['-drive'] = driveOpt % params
+ args['-device'] = deviceOpt % params
+ # return qemucmdline XML
+ return get_qemucmdline_xml(args)
+
+ dev, xml = get_disk_xml(params)
+ return xml
+
+ def _get_disks_xml(self, vm_uuid):
+ # Current implementation just allows to create disk in one single
+ # storage pool, so we cannot mix the types (scsi volumes vs img file)
+ storage_type = self._get_storage_type()
+ storage_path = self._get_storage_path()
+
+ base_disk_params = {'type': 'disk', 'disk': 'file',
+ 'bus': self.info['disk_bus'], 'format': 'qcow2'}
+ logical_disk_params = {'format': 'raw'}
+ iscsi_disk_params = {'disk': 'block', 'format': 'raw'}
+
+ scsi_disk = 'volume' if self.fc_host_support else 'block'
+ scsi_disk_params = {'disk': scsi_disk, 'type': 'lun',
+ 'format': 'raw', 'bus': 'scsi'}
+
+ disks_xml = ''
+ pool_name = pool_name_from_uri(self.info['storagepool'])
+ for index, disk in enumerate(self.info['disks']):
+ params = dict(base_disk_params)
+ params['format'] = disk.get('format', params['format'])
+ params.update(locals().get('%s_disk_params' % storage_type, {}))
+ params['index'] = index
+
+ volume = disk.get('volume')
+ if volume is not None:
+ params['path'] = self._get_volume_path(pool_name, volume)
+ else:
+ volume = "%s-%s.img" % (vm_uuid, params['index'])
+ params['path'] = os.path.join(storage_path, volume)
+
+ disks_xml += get_disk_xml(params)[1]
+
+ return unicode(disks_xml, 'utf-8')
+
+ def to_volume_list(self, vm_uuid):
+ storage_path = self._get_storage_path()
+ fmt = 'raw' if self._get_storage_type() in ['logical'] else 'qcow2'
+ ret = []
+ for i, d in enumerate(self.info['disks']):
+ index = d.get('index', i)
+ volume = "%s-%s.img" % (vm_uuid, index)
+
+ info = {'name': volume,
+ 'capacity': d['size'],
+ 'format': fmt,
+ 'path': '%s/%s' % (storage_path, volume)}
+
+ if 'logical' == self._get_storage_type() or \
+ fmt not in ['qcow2', 'raw']:
+ info['allocation'] = info['capacity']
+ else:
+ info['allocation'] = 0
+
+ if 'base' in d:
+ info['base'] = dict()
+ base_fmt = imageinfo.probe_img_info(d['base'])['format']
+ if base_fmt is None:
+ raise InvalidParameter("KCHTMPL0024E", {'path': d['base']})
+ info['base']['path'] = d['base']
+ info['base']['format'] = base_fmt
+
+ v_tree = E.volume(E.name(info['name']))
+ v_tree.append(E.allocation(str(info['allocation']), unit='G'))
+ v_tree.append(E.capacity(str(info['capacity']), unit='G'))
+ target = E.target(
+ E.format(type=info['format']), E.path(info['path']))
+ if 'base' in d:
+ v_tree.append(E.backingStore(
+ E.path(info['base']['path']),
+ E.format(type=info['base']['format'])))
+ v_tree.append(target)
+ info['xml'] = etree.tostring(v_tree)
+ ret.append(info)
+ return ret
+
+ def _get_networks_xml(self):
+ networks = ""
+ params = {'type': 'network',
+ 'model': self.info['nic_model']}
+ for nw in self.info['networks']:
+ params['network'] = nw
+ networks += get_iface_xml(params, self.info['arch'],
+ self.info['os_distro'],
+ self.info['os_version'])
+ return unicode(networks, 'utf-8')
+
+ def _get_input_output_xml(self):
+ sound = """
+ <sound model='%(sound_model)s' />
+ """
+ mouse = """
+ <input type='mouse' bus='%(mouse_bus)s'/>
+ """
+
+ keyboard = """
+ <input type='%(kbd_type)s' bus='%(kbd_bus)s'> </input>
+ """
+
+ tablet = """
+ <input type='tablet' bus='%(kbd_bus)s'> </input>
+ """
+
+ video = """
+ <video>
+ <model type='%(video_model)s'/>
+ </video>
+ """
+
+ input_output = ""
+ if 'mouse_bus' in self.info.keys():
+ input_output += mouse % self.info
+ if 'kbd_bus' in self.info.keys():
+ input_output += keyboard % self.info
+ if 'tablet_bus' in self.info.keys():
+ input_output += tablet % self.info
+ if 'sound_model' in self.info.keys():
+ input_output += sound % self.info
+ if 'video_model' in self.info.keys():
+ input_output += video % self.info
+ return input_output
+
+ def _get_cpu_xml(self):
+ # Include CPU topology, if provided
+ cpu_info = self.info.get('cpu_info')
+ if cpu_info is not None:
+ cpu_topo = cpu_info.get('topology')
+ return get_cpu_xml(self.info.get('cpus'),
+ self.info.get('memory') << 10,
+ cpu_topo)
+
+ def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
+ params = dict(self.info)
+ params['name'] = vm_name
+ params['uuid'] = vm_uuid
+ params['networks'] = self._get_networks_xml()
+ params['input_output'] = self._get_input_output_xml()
+ params['qemu-namespace'] = ''
+ params['cdroms'] = ''
+ params['qemu-stream-cmdline'] = ''
+ params['cpu_info'] = self._get_cpu_xml()
+ params['disks'] = self._get_disks_xml(vm_uuid)
+
+ graphics = dict(self.info['graphics'])
+ graphics.update(kwargs.get('graphics', {}))
+ params['graphics'] = get_graphics_xml(graphics)
+
+ libvirt_stream_protocols = kwargs.get('libvirt_stream_protocols', [])
+ cdrom_xml = self._get_cdrom_xml(libvirt_stream_protocols)
+
+ if not urlparse.urlparse(self.info.get('cdrom', "")).scheme in \
+ libvirt_stream_protocols and \
+ params.get('iso_stream', False):
+ params['qemu-stream-cmdline'] = cdrom_xml
+ else:
+ params['cdroms'] = cdrom_xml
+
+ # Setting maximum number of slots to avoid errors when hotplug memory
+ # Number of slots are the numbers of chunks of 1GB that fit inside
+ # the max_memory of the host minus memory assigned to the VM
+ params['slots'] = ((params['max_memory'] >> 10) -
+ params['memory']) >> 10
+ if params['slots'] < 0:
+ raise OperationFailed("KCHVM0041E")
+ elif params['slots'] == 0:
+ params['slots'] = 1
+
+ xml = """
+ <domain type='%(domain)s'>
+ %(qemu-stream-cmdline)s
+ <name>%(name)s</name>
+ <uuid>%(uuid)s</uuid>
+ <maxMemory slots='%(slots)s' unit='KiB'>%(max_memory)s</maxMemory>
+ <memory unit='MiB'>%(memory)s</memory>
+ <vcpu>%(cpus)s</vcpu>
+ %(cpu_info)s
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ %(disks)s
+ %(cdroms)s
+ %(networks)s
+ %(graphics)s
+ %(input_output)s
+ <memballoon model='virtio' />
+ </devices>
+ </domain>
+ """ % params
+
+ # Adding PPC console configuration
+ if params['arch'] in ['ppc', 'ppc64']:
+ ppc_console = """<memballoon model='virtio' />
+ <console type='pty'>
+ <target type='serial' port='1'/>
+ <address type='spapr-vio' reg='0x30001000'/>
+ </console>"""
+ xml = xml.replace("<memballoon model='virtio' />", ppc_console)
+
+ return xml
+
+ def validate(self):
+ self._storage_validate()
+ self._network_validate()
+ self._iso_validate()
+
+ def _iso_validate(self):
+ pass
+
+ def _network_validate(self):
+ pass
+
+ def _storage_validate(self):
+ pass
+
+ def fork_vm_storage(self, vm_uuid):
+ pass
+
+ def _get_storage_path(self):
+ return ''
+
+ def _get_storage_type(self):
+ return ''
+
+ def _get_volume_path(self):
+ return ''
+
+ def _get_all_networks_name(self):
+ return []
+
+ def _get_all_storagepools_name(self):
+ return []
+
+ def validate_integrity(self):
+ invalid = {}
+ # validate networks integrity
+ invalid_networks = list(set(self.info['networks']) -
+ set(self._get_all_networks_name()))
+ if invalid_networks:
+ invalid['networks'] = invalid_networks
+
+ # validate storagepools integrity
+ pool_uri = self.info['storagepool']
+ pool_name = pool_name_from_uri(pool_uri)
+ if pool_name not in self._get_all_storagepools_name():
+ invalid['storagepools'] = [pool_name]
+
+ # validate iso integrity
+ # FIXME when we support multiples cdrom devices
+ iso = self.info.get('cdrom')
+ if iso:
+ if os.path.exists(iso):
+ st_mode = os.stat(iso).st_mode
+ if not (stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode)):
+ invalid['cdrom'] = [iso]
+ elif not check_url_path(iso):
+ invalid['cdrom'] = [iso]
+
+ self.info['invalid'] = invalid
+
+ return self.info
diff --git a/src/wok/plugins/kimchi/vnc.py b/src/wok/plugins/kimchi/vnc.py
new file mode 100644
index 0000000..2532449
--- /dev/null
+++ b/src/wok/plugins/kimchi/vnc.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python2
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import base64
+import errno
+import os
+from multiprocessing import Process
+from websockify import WebSocketProxy
+
+from wok.config import config, paths
+
+
+WS_TOKENS_DIR = '/var/lib/wok/vnc-tokens'
+
+
+def new_ws_proxy():
+ try:
+ os.makedirs(WS_TOKENS_DIR, mode=0755)
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ pass
+
+ cert = config.get('server', 'ssl_cert')
+ key = config.get('server', 'ssl_key')
+ if not (cert and key):
+ cert = '%s/wok-cert.pem' % paths.conf_dir
+ key = '%s/wok-key.pem' % paths.conf_dir
+
+ params = {'web': os.path.join(paths.ui_dir, 'pages/websockify'),
+ 'listen_port': config.get('display', 'display_proxy_port'),
+ 'target_cfg': WS_TOKENS_DIR,
+ 'key': key, 'cert': cert, 'ssl_only': True}
+
+ def start_proxy():
+ server = WebSocketProxy(**params)
+ server.start_server()
+
+ proc = Process(target=start_proxy)
+ proc.start()
+ return proc
+
+
+def add_proxy_token(name, port):
+ with open(os.path.join(WS_TOKENS_DIR, name), 'w') as f:
+ """
+ From python documentation base64.urlsafe_b64encode(s)
+ substitutes - instead of + and _ instead of / in the
+ standard Base64 alphabet, BUT the result can still
+ contain = which is not safe in a URL query component.
+ So remove it when needed as base64 can work well without it.
+ """
+ name = base64.urlsafe_b64encode(name).rstrip('=')
+ f.write('%s: localhost:%s' % (name.encode('utf-8'), port))
+
+
+def remove_proxy_token(name):
+ try:
+ os.unlink(os.path.join(WS_TOKENS_DIR, name))
+ except OSError:
+ pass
diff --git a/src/wok/plugins/kimchi/xmlutils/Makefile.am b/src/wok/plugins/kimchi/xmlutils/Makefile.am
new file mode 100644
index 0000000..207ad7f
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+xmlutils_PYTHON = *.py
+
+xmlutilsdir = $(pythondir)/wok/plugins/kimchi/xmlutils
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(xmlutilsdir)
diff --git a/src/wok/plugins/kimchi/xmlutils/__init__.py b/src/wok/plugins/kimchi/xmlutils/__init__.py
new file mode 100644
index 0000000..ca7ede4
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/__init__.py
@@ -0,0 +1,18 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/src/wok/plugins/kimchi/xmlutils/cpu.py b/src/wok/plugins/kimchi/xmlutils/cpu.py
new file mode 100644
index 0000000..32c01a4
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/cpu.py
@@ -0,0 +1,60 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from lxml.builder import E
+
+
+def get_numa_xml(cpus, memory):
+ # Returns the NUMA xml to be add into CPU element
+ # Currently, supports only one node/cell
+ # <numa>
+ # <cell id='0' cpus='0-3' memory='512000' unit='KiB'/>
+ # </numa>
+ xml = E.numa(E.cell(
+ id='0',
+ cpus='0-' + str(cpus - 1) if cpus > 1 else '0',
+ memory=str(memory),
+ unit='KiB'))
+ return ET.tostring(xml)
+
+
+def get_topology_xml(cpu_topo):
+ # Return the cpu TOPOLOGY element
+ # <topology sockets='1' cores='2' threads='1'/>
+ xml = E.topology(
+ sockets=str(cpu_topo['sockets']),
+ cores=str(cpu_topo['cores']),
+ threads=str(cpu_topo['threads']))
+ return ET.tostring(xml)
+
+
+def get_cpu_xml(cpus, memory, cpu_topo=None):
+ # Returns the libvirt CPU element based on given numa and topology
+ # CPU element will always have numa element
+ # <cpu>
+ # <numa>
+ # <cell id='0' cpus='0-3' memory='512000' unit='KiB'/>
+ # </numa>
+ # <topology sockets='1' cores='2' threads='1'/>
+ # </cpu>
+ xml = E.cpu(ET.fromstring(get_numa_xml(cpus, memory)))
+ if cpu_topo is not None:
+ xml.insert(0, ET.fromstring(get_topology_xml(cpu_topo)))
+ return ET.tostring(xml)
diff --git a/src/wok/plugins/kimchi/xmlutils/disk.py b/src/wok/plugins/kimchi/xmlutils/disk.py
new file mode 100644
index 0000000..126ce77
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/disk.py
@@ -0,0 +1,164 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+import os
+import socket
+import stat
+import string
+import urlparse
+from lxml import objectify
+from lxml.builder import E
+
+from wok.exception import InvalidParameter, NotFoundError
+from wok.utils import check_url_path
+
+
+BUS_TO_DEV_MAP = {'ide': 'hd', 'virtio': 'vd', 'scsi': 'sd'}
+DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', 'block': 'dev'}
+
+
+def get_disk_xml(params):
+ """
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+
+ [source XML according to src_type]
+
+ <target dev='%(dev)s' bus='%(bus)s'/>
+ <readonly/>
+ </disk>
+ """
+ path = params['path']
+ disk_type = params.get('disk', None)
+ if disk_type is None:
+ disk_type = _get_disk_type(path) if len(path) > 0 else 'file'
+ disk = E.disk(type=disk_type, device=params['type'])
+ driver = E.driver(name='qemu', type=params['format'])
+ if params['type'] != 'cdrom':
+ driver.set('cache', 'none')
+
+ disk.append(driver)
+
+ # Get device name according to bus and index values
+ dev = params.get('dev', (BUS_TO_DEV_MAP[params['bus']] +
+ string.lowercase[params.get('index', 0)]))
+ disk.append(E.target(dev=dev, bus=params['bus']))
+
+ if params.get('address'):
+ # ide disk target id is always '0'
+ disk.append(E.address(
+ type='drive', controller=params['address']['controller'],
+ bus=params['address']['bus'], target='0',
+ unit=params['address']['unit']))
+
+ if len(params['path']) == 0:
+ return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
+
+ if disk_type == 'network':
+ """
+ <source protocol='%(protocol)s' name='%(url_path)s'>
+ <host name='%(hostname)s' port='%(port)s'/>
+ </source>
+ """
+ output = urlparse.urlparse(params['path'])
+ port = str(output.port or socket.getservbyname(output.scheme))
+
+ source = E.source(protocol=output.scheme, name=output.path)
+ source.append(E.host(name=output.hostname, port=port))
+ else:
+ """
+ <source file='%(src)s' />
+ """
+ source = E.source()
+ source.set(DEV_TYPE_SRC_ATTR_MAP[disk_type], params['path'])
+
+ disk.append(source)
+ return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
+
+
+def _get_disk_type(path):
+ if check_url_path(path):
+ return 'network'
+
+ if not os.path.exists(path):
+ raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
+
+ # Check if path is a valid local path
+ if os.path.isfile(path):
+ return 'file'
+
+ r_path = os.path.realpath(path)
+ if stat.S_ISBLK(os.stat(r_path).st_mode):
+ return 'block'
+
+ raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
+
+
+def get_device_node(dom, dev_name):
+ xml = dom.XMLDesc(0)
+ devices = objectify.fromstring(xml).devices
+ disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name)
+
+ if not disk:
+ raise NotFoundError("KCHVMSTOR0007E",
+ {'dev_name': dev_name,
+ 'vm_name': dom.name()})
+
+ return disk[0]
+
+
+def get_vm_disk_info(dom, dev_name):
+ # Retrieve disk xml and format return dict
+ disk = get_device_node(dom, dev_name)
+ if disk is None:
+ return None
+
+ try:
+ source = disk.source
+ if source is not None:
+ src_type = disk.attrib['type']
+ if src_type == 'network':
+ host = source.host
+ path = (source.attrib['protocol'] + '://' +
+ host.attrib['name'] + ':' +
+ host.attrib['port'] + source.attrib['name'])
+ else:
+ path = source.attrib[DEV_TYPE_SRC_ATTR_MAP[src_type]]
+ except:
+ path = ""
+
+ return {'dev': dev_name,
+ 'path': path,
+ 'type': disk.attrib['device'],
+ 'format': disk.driver.attrib['type'],
+ 'bus': disk.target.attrib['bus']}
+
+
+def get_vm_disks(dom):
+ xml = dom.XMLDesc(0)
+ devices = objectify.fromstring(xml).devices
+
+ storages = {}
+ all_disks = devices.xpath("./disk[@device='disk']")
+ all_disks.extend(devices.xpath("./disk[@device='cdrom']"))
+ for disk in all_disks:
+ storages[disk.target.attrib['dev']] = disk.target.attrib['bus']
+
+ return storages
diff --git a/src/wok/plugins/kimchi/xmlutils/graphics.py b/src/wok/plugins/kimchi/xmlutils/graphics.py
new file mode 100644
index 0000000..2b4346a
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/graphics.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from lxml.builder import E
+
+
+def get_graphics_xml(params):
+ """
+ <graphics type='%(type)s' autoport='yes' listen='%(listen)s'/>
+
+ - For spice graphics:
+
+ <channel type='spicevmc'>
+ <target type='virtio' name='com.redhat.spice.0'/>
+ </channel>
+ """
+ graphics = E.graphics(type=params['type'], autoport='yes',
+ listen=params['listen'])
+ graphics_xml = ET.tostring(graphics, encoding='utf-8', pretty_print=True)
+
+ if params['type'] == 'vnc':
+ return graphics_xml
+
+ # For spice graphics, a channel also must be configured
+ channel = E.channel(type='spicevmc')
+ channel.append(E.target(type='virtio', name='com.redhat.spice.0'))
+ channel_xml = ET.tostring(channel, encoding='utf-8', pretty_print=True)
+ return graphics_xml + channel_xml
diff --git a/src/wok/plugins/kimchi/xmlutils/interface.py b/src/wok/plugins/kimchi/xmlutils/interface.py
new file mode 100644
index 0000000..0f3e848
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/interface.py
@@ -0,0 +1,61 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from distutils.version import LooseVersion
+from lxml.builder import E
+
+from .. import osinfo
+
+
+def get_iface_xml(params, arch=None, os_distro=None, os_version=None):
+ """
+ <interface type='network'>
+ <source network='default'/>
+ <model type='virtio'/>
+ </interface>
+ """
+ interface = E.interface(type=params['type'])
+ interface.append(E.source(network=params['network']))
+
+ model = params.get('model')
+
+ # no model specified; let's try querying osinfo
+ if model is None:
+ # if os_distro and os_version are invalid, nic_model will also be None
+ model = osinfo.lookup(os_distro, os_version).get('nic_model')
+
+ # only append 'model' to the XML if it's been specified as a parameter or
+ # returned by osinfo.lookup; otherwise let libvirt use its default value
+ if model is not None:
+ interface.append(E.model(type=model))
+
+ mac = params.get('mac', None)
+ if mac is not None:
+ interface.append(E.mac(address=mac))
+
+ # Hack to disable vhost feature in Ubuntu LE and SLES LE (PPC)
+ if arch == 'ppc64' and \
+ ((os_distro == 'ubuntu' and
+ LooseVersion(os_version) >= LooseVersion('14.04')) or
+ (os_distro == 'sles' and
+ LooseVersion(os_version) >= LooseVersion('12'))):
+ interface.append(E.driver(name='qemu'))
+
+ return ET.tostring(interface, encoding='utf-8', pretty_print=True)
diff --git a/src/wok/plugins/kimchi/xmlutils/network.py b/src/wok/plugins/kimchi/xmlutils/network.py
new file mode 100644
index 0000000..c73aad9
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/network.py
@@ -0,0 +1,122 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ipaddr
+import lxml.etree as ET
+from lxml.builder import E
+
+
+# FIXME, do not support ipv6
+def _get_dhcp_elem(**kwargs):
+ """
+ <dhcp>
+ <range start="192.168.122.100" end="192.168.122.254" />
+ <host mac="00:16:3e:77:e2:ed" name="foo.test.com" ip="192.168.122.10" />
+ <host mac="00:16:3e:3e:a9:1a" name="bar.test.com" ip="192.168.122.11" />
+ </dhcp>
+ """
+ dhcp = E.dhcp()
+ if 'range' in kwargs.keys():
+ dhcp_range = E.range(start=kwargs['range']['start'],
+ end=kwargs['range']['end'])
+ dhcp.append(dhcp_range)
+
+ if 'hosts' in kwargs.keys():
+ for host in kwargs['hosts']:
+ dhcp.append(E.host(mac=host['mac'],
+ name=host['name'],
+ ip=host['ip']))
+
+ return dhcp if len(dhcp) > 0 else None
+
+
+def _get_ip_elem(**kwargs):
+ """
+ <ip address="192.168.152.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.152.2" end="192.168.152.254" />
+ </dhcp>
+ </ip>
+ """
+ if 'net' not in kwargs.keys():
+ return None
+
+ net = ipaddr.IPNetwork(kwargs['net'])
+ ip = E.ip(address=str(net.ip), netmask=str(net.netmask))
+
+ dhcp_params = kwargs.get('dhcp', {})
+ dhcp = _get_dhcp_elem(**dhcp_params)
+ if dhcp is not None:
+ ip.append(dhcp)
+
+ return ip
+
+
+def _get_forward_elem(**kwargs):
+ """
+ <forward mode='hostdev' dev='eth0' managed='yes'>
+ </forward>
+ """
+ if "mode" in kwargs.keys() and kwargs['mode'] is None:
+ return None
+
+ forward = E.forward()
+ if 'mode' in kwargs.keys():
+ forward.set('mode', kwargs['mode'])
+
+ if 'dev' in kwargs.keys():
+ forward.set('dev', kwargs['dev'])
+
+ if 'managed' in kwargs.keys():
+ forward.set('managed', kwargs['managed'])
+
+ return forward
+
+
+def to_network_xml(**kwargs):
+ network = E.network(E.name(kwargs['name']))
+ bridge = kwargs.get('bridge')
+ if bridge:
+ network.append(E.bridge(name=bridge))
+
+ # None means is Isolated network, {} means default mode nat
+ params = kwargs.get('forward', {"mode": None})
+ forward = _get_forward_elem(**params)
+ if forward is not None:
+ network.append(forward)
+
+ if 'net' in kwargs:
+ network.append(_get_ip_elem(**kwargs))
+
+ return ET.tostring(network)
+
+
+def create_vlan_tagged_bridge_xml(bridge, interface, vlan_id):
+ vlan = E.vlan(E.interface(name=interface))
+ vlan.set('tag', vlan_id)
+ m = E.interface(
+ E.start(mode='onboot'),
+ E.bridge(
+ E.interface(
+ vlan,
+ type='vlan',
+ name='.'.join([interface, vlan_id]))),
+ type='bridge',
+ name=bridge)
+ return ET.tostring(m)
diff --git a/src/wok/plugins/kimchi/xmlutils/qemucmdline.py b/src/wok/plugins/kimchi/xmlutils/qemucmdline.py
new file mode 100644
index 0000000..66238a7
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/qemucmdline.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from lxml.builder import ElementMaker
+
+QEMU_NAMESPACE = "http://libvirt.org/schemas/domain/qemu/1.0"
+
+
+def get_qemucmdline_xml(args):
+ """
+ <qemu:commandline xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
+ <qemu:arg value='-drive'/>
+ <qemu:arg value='file=%(path)s,if=none,id=drive-%(bus)s0-1-0,
+ readonly=on,format=%(format)s'/>
+ <qemu:arg value='-device'/>
+ <qemu:arg value='%(bus)s-cd,bus=%(bus)s.1,unit=0,
+ drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'/>
+ </qemu:commandline>
+ """
+ EM = ElementMaker(namespace=QEMU_NAMESPACE,
+ nsmap={'qemu': QEMU_NAMESPACE})
+
+ root = EM.commandline()
+ for opt, value in args.iteritems():
+ root.append(EM.arg(value=opt))
+ root.append(EM.arg(value=value))
+
+ return ET.tostring(root, encoding='utf-8', pretty_print=True)
diff --git a/src/wok/plugins/kimchi/yumparser.py b/src/wok/plugins/kimchi/yumparser.py
new file mode 100644
index 0000000..74f9fa0
--- /dev/null
+++ b/src/wok/plugins/kimchi/yumparser.py
@@ -0,0 +1,283 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import subprocess
+from os import listdir
+from os.path import isfile, splitext
+
+
+class YumRepoObject(object):
+
+ def __init__(self, repo_id, repofile):
+ self.repo_id = repo_id
+ self.name = None
+ self.baseurl = None
+ self.enabled = True
+ self.gpgcheck = True
+ self.gpgkey = None
+ self.metalink = None
+ self.mirrorlist = None
+ self.repofile = repofile
+ self.string_attrs = ['baseurl', 'gpgkey', 'name',
+ 'metalink', 'mirrorlist']
+ self.boolean_attrs = ['enabled', 'gpgcheck']
+
+ def set_attribute(self, key, strvalue):
+ if key in self.string_attrs:
+ setattr(self, key, strvalue)
+ elif key in self.boolean_attrs:
+ setattr(self, key, (strvalue == '1'))
+
+ def get_attribute_str(self, key):
+ if key not in self.get_attributes():
+ return None
+
+ if key in self.boolean_attrs:
+ str_value = '1' if getattr(self, key) is True else '0'
+ else:
+ str_value = getattr(self, key)
+
+ if str_value is None:
+ return None
+
+ return key + '=' + str_value
+
+ def get_attributes(self):
+ return self.string_attrs + self.boolean_attrs
+
+ def enable(self):
+ self.enabled = True
+
+ def disable(self):
+ self.enabled = False
+
+ def __str__(self):
+ str_obj = '[' + self.repo_id + ']' + '\n'
+ for key in self.get_attributes():
+ if self.get_attribute_str(key) is not None:
+ str_obj += self.get_attribute_str(key) + '\n'
+ return str_obj
+
+
+def get_repo_files():
+ def _is_repository_file(f):
+ _, f_extension = splitext(f)
+ return isfile(f) and (f_extension == '.repo')
+
+ YUM_REPO_DIR = '/etc/yum.repos.d'
+ return [YUM_REPO_DIR+'/'+f for f in listdir(YUM_REPO_DIR)
+ if _is_repository_file(YUM_REPO_DIR+'/'+f)]
+
+
+def _ignore_line_repo_file(line):
+ return line.startswith("#") or '=' not in line
+
+
+def _get_repos_from_file(repo_file):
+ repos_from_file = {}
+ current_repo = None
+ current_repo_id = None
+ with open(repo_file) as f:
+ for line in f.readlines():
+ line = line.strip()
+ if line.startswith("["):
+ if current_repo is not None:
+ repos_from_file[current_repo_id] = current_repo
+ current_repo_id = line.strip('[]')
+ current_repo = YumRepoObject(current_repo_id, repo_file)
+ continue
+ if _ignore_line_repo_file(line):
+ continue
+ key, value = line.split('=', 1)
+ key = key.strip()
+ value = value.strip()
+ current_repo.set_attribute(key, value)
+
+ # add the last repo from file.
+ if current_repo is not None:
+ repos_from_file[current_repo_id] = current_repo
+
+ return repos_from_file
+
+
+def get_yum_repositories():
+ repo_files = get_repo_files()
+ repos = {}
+ for yum_repo in repo_files:
+ repos.update(_get_repos_from_file(yum_repo))
+
+ return repos
+
+
+def _retrieve_repo_line_index(data, repo):
+ repo_entry = '[' + repo.repo_id + ']\n'
+ try:
+ repo_index = data.index(repo_entry)
+ except:
+ return None
+ return repo_index
+
+
+def _update_repo_file_data(data, repo, repo_index):
+ remaining_repo_attrs = repo.get_attributes()
+
+ for i in range(repo_index + 1, len(data)):
+ line = data[i].strip()
+ if line.startswith('['):
+ break
+ if _ignore_line_repo_file(line):
+ continue
+ key, _ = line.split('=', 1)
+ key = key.strip()
+ attr_str = repo.get_attribute_str(key)
+ if attr_str is None:
+ continue
+ remaining_repo_attrs.remove(key)
+ data[i] = attr_str + '\n'
+
+ for attr in remaining_repo_attrs:
+ attr_str = repo.get_attribute_str(attr)
+ if attr_str is None:
+ continue
+ data.insert(repo_index+1, attr_str + '\n')
+
+ return data
+
+
+def write_repo_to_file(repo):
+ with open(repo.repofile) as f:
+ data = f.readlines()
+
+ repo_index = _retrieve_repo_line_index(data, repo)
+ if repo_index is None:
+ return
+
+ data = _update_repo_file_data(data, repo, repo_index)
+
+ with open(repo.repofile, 'w') as f:
+ f.writelines(data)
+
+
+def _get_last_line_repo(data, repo_index):
+ stop_delete_index = None
+ for i in range(repo_index+1, len(data)):
+ line = data[i].strip()
+ if line.startswith('['):
+ stop_delete_index = i - 1
+ break
+ if stop_delete_index is None:
+ stop_delete_index = len(data) - 1
+
+ return stop_delete_index
+
+
+def _remove_repo_file_data(data, repo_index):
+ last_line_repo = _get_last_line_repo(data, repo_index)
+ for i in range(last_line_repo, repo_index - 1, -1):
+ data.pop(i)
+ return data
+
+
+def delete_repo_from_file(repo):
+ with open(repo.repofile) as f:
+ data = f.readlines()
+
+ repo_index = _retrieve_repo_line_index(data, repo)
+ if repo_index is None:
+ return
+
+ data = _remove_repo_file_data(data, repo_index)
+
+ with open(repo.repofile, 'w') as f:
+ f.writelines(data)
+
+
+class YumUpdatePackageObject(object):
+
+ def __init__(self, name, arch, version, repo):
+ self.name = name
+ self.arch = arch
+ self.version = version
+ self.ui_from_repo = repo
+
+
+def _include_line_checkupdate_output(line):
+ tokens = line.split()
+
+ if len(tokens) != 3:
+ return False
+
+ if '.' not in tokens[0]:
+ return False
+
+ return True
+
+
+def _ignore_obsoleting_packages_in(output):
+ out = ''
+ for l in output.split('\n'):
+ if 'Obsoleting ' in l:
+ break
+ out += l + '\n'
+ return out
+
+
+def _filter_lines_checkupdate_output(output):
+ if output is None:
+ return []
+
+ output = _ignore_obsoleting_packages_in(output)
+
+ out = [l for l in output.split('\n')
+ if _include_line_checkupdate_output(l)]
+ return out
+
+
+def _get_yum_checkupdate_output():
+ cmd = ['yum', 'check-update', '-d0']
+ yum_update_cmd = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, error = yum_update_cmd.communicate()
+ return_code = yum_update_cmd.returncode
+ if return_code == 1:
+ return None
+
+ return out
+
+
+def get_yum_packages_list_update(checkupdate_output=None):
+ if checkupdate_output is None:
+ checkupdate_output = _get_yum_checkupdate_output()
+
+ filtered_output = _filter_lines_checkupdate_output(checkupdate_output)
+
+ packages = []
+ for line in filtered_output:
+ line = line.split()
+ index = 0
+ name_arch = line[index]
+ index += 1
+ version = line[index]
+ index += 1
+ repo = line[index]
+ name, arch = name_arch.rsplit('.', 1)
+ packages.append(YumUpdatePackageObject(name, arch, version, repo))
+
+ return packages
diff --git a/src/wok/plugins/sample/API.json b/src/wok/plugins/sample/API.json
new file mode 100644
index 0000000..6ee7d91
--- /dev/null
+++ b/src/wok/plugins/sample/API.json
@@ -0,0 +1,56 @@
+{
+ "$schema": "http://json-schema.org/draft-03/schema#",
+ "title": "Plugin Sample API",
+ "description": "Json schema for Wok's Sample Plugin API",
+ "type": "object",
+ "error": "SPAPI0001E",
+ "properties": {
+ "rectangles_create": {
+ "type": "object",
+ "error": "SPRET0003E",
+ "properties": {
+ "name": {
+ "description": "The name of the new rectangle instance",
+ "type": "string",
+ "required": true,
+ "error": "SPRET0004E"
+ },
+ "length": {
+ "$ref": "#/definitions/positiveNumber",
+ "required": true,
+ "error": "SPRET0005E"
+ },
+ "width": {
+ "$ref": "#/definitions/positiveNumber",
+ "required": true,
+ "error": "SPRET0006E"
+ }
+ }
+ },
+ "circles_create": {
+ "type": "object",
+ "error": "SPCIRC0003E",
+ "properties": {
+ "name": {
+ "description": "The name of the new circle instance",
+ "type": "string",
+ "required": true,
+ "error": "SPCIRC0004E"
+ },
+ "radius": {
+ "$ref": "#/definitions/positiveNumber",
+ "required": true,
+ "error": "SPCIRC0005E"
+ }
+ }
+ }
+ },
+ "definitions": {
+ "positiveNumber": {
+ "error": "SPAPI0002E",
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMinimum": true
+ }
+ }
+}
diff --git a/src/wok/plugins/sample/Makefile.am b/src/wok/plugins/sample/Makefile.am
new file mode 100644
index 0000000..876ab54
--- /dev/null
+++ b/src/wok/plugins/sample/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = ui po
+
+EXTRA_DIST = API.json sample.conf.in $(wildcard *.py) config.status
+
+all-local:
+ while read L && test -n "$$L"; do \
+ dir=mo/$$L/LC_MESSAGES ; \
+ $(MKDIR_P) $$dir ; \
+ ln -sf ../../../po/$$L.gmo $$dir/sample.mo ; \
+ done < po/LINGUAS
diff --git a/src/wok/plugins/sample/__init__.py b/src/wok/plugins/sample/__init__.py
new file mode 100644
index 0000000..a3a8f05
--- /dev/null
+++ b/src/wok/plugins/sample/__init__.py
@@ -0,0 +1,97 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+from cherrypy import expose
+
+
+from wok.config import PluginPaths
+from wok.control.base import Collection, Resource
+from wok.root import WokRoot
+
+
+from plugins.sample.i18n import messages
+from plugins.sample.model import Model
+
+
+model = Model()
+
+
+class Drawings(WokRoot):
+ def __init__(self, wok_options):
+ Resource.__init__(self, model)
+ self.description = Description(model)
+ self.rectangles = Rectangles(model)
+ self.circles = Circles(model)
+ self.paths = PluginPaths('sample')
+ self.domain = 'sample'
+ self.messages = messages
+ self.api_schema = json.load(open(os.path.join(os.path.dirname(
+ os.path.abspath(__file__)), 'API.json')))
+
+ @expose
+ def index(self):
+ return 'This is a sample plugin for Wok'
+
+
+class Description(Resource):
+ def __init__(self, model):
+ super(Description, self).__init__(model)
+
+ @property
+ def data(self):
+ return {'name': 'sample', 'version': '0.1'}
+
+
+class Circles(Collection):
+ def __init__(self, model):
+ super(Circles, self).__init__(model)
+ self.resource = Circle
+ self.admin_methods = ['POST', 'PUT']
+
+
+class Rectangles(Collection):
+ def __init__(self, model):
+ super(Rectangles, self).__init__(model)
+ self.resource = Rectangle
+ self.admin_methods = ['POST', 'PUT']
+
+
+class Circle(Resource):
+ def __init__(self, model, ident):
+ super(Circle, self).__init__(model, ident)
+ self.update_params = ['radius']
+
+ @property
+ def data(self):
+ ret = {'name': self.ident}
+ ret.update(self.info)
+ return ret
+
+
+class Rectangle(Resource):
+ def __init__(self, model, ident):
+ super(Rectangle, self).__init__(model, ident)
+ self.update_params = ['length', 'width']
+
+ @property
+ def data(self):
+ self.info.update({'name': self.ident})
+ return self.info
diff --git a/src/wok/plugins/sample/config.status b/src/wok/plugins/sample/config.status
new file mode 120000
index 0000000..6cd6b4f
--- /dev/null
+++ b/src/wok/plugins/sample/config.status
@@ -0,0 +1 @@
+../../config.status
\ No newline at end of file
diff --git a/src/wok/plugins/sample/i18n.py b/src/wok/plugins/sample/i18n.py
new file mode 100644
index 0000000..763970f
--- /dev/null
+++ b/src/wok/plugins/sample/i18n.py
@@ -0,0 +1,40 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gettext
+
+_ = gettext.gettext
+
+
+messages = {
+ "SPAPI0001E": _("Unkown parameter specified %(value)s"),
+ "SPAPI0002E": _("The specified value %(value)s is not a positive number"),
+
+ "SPCIRC0002E": _("Circle %(name)s does not exist"),
+ "SPCIRC0003E": _("Specify name and radius to create a Circle"),
+ "SPCIRC0004E": _("Circle name must be a string"),
+ "SPCIRC0005E": _("Circle radius must be a positive number"),
+
+ "SPRET0001E": _("Rectangle %(name)s already exists"),
+ "SPRET0002E": _("Rectangle %(name)s does not exist"),
+ "SPRET0003E": _("Specify name, length and width to create a Rectangle"),
+ "SPRET0004E": _("Rectangle name must be a string"),
+ "SPRET0005E": _("Rectangle length must be a positive number"),
+ "SPRET0006E": _("Rectangle width must be a positive number"),
+}
diff --git a/src/wok/plugins/sample/model.py b/src/wok/plugins/sample/model.py
new file mode 100644
index 0000000..4ada648
--- /dev/null
+++ b/src/wok/plugins/sample/model.py
@@ -0,0 +1,131 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.basemodel import BaseModel
+from wok.exception import InvalidOperation, NotFoundError
+
+
+class CirclesModel(object):
+ def __init__(self):
+ self._circles = {}
+
+ def create(self, params):
+ name = params['name']
+ if name in self._circles:
+ raise InvalidOperation("SPCIRCLE0001E", {'name': name})
+ self._circles[name] = Circle(params['radius'])
+ return name
+
+ def get_list(self):
+ return sorted(self._circles)
+
+
+class CircleModel(object):
+ def __init__(self, parent_model):
+ # Circel and Circles models are friends, it's OK to share _circles.
+ self._circles = parent_model._circles
+
+ def lookup(self, name):
+ try:
+ circle = self._circles[name]
+ except KeyError:
+ raise NotFoundError("SPCIRC0002E", {'name': name})
+ return {'radius': circle.radius}
+
+ def update(self, name, params):
+ if name not in self._circles:
+ raise NotFoundError("SPCIRC0002E", {'name': name})
+ self._circles[name].radius = params['radius']
+ return name
+
+ def delete(self, name):
+ try:
+ del self._circles[name]
+ except KeyError:
+ pass
+
+
+class RectanglesModel(object):
+ def __init__(self):
+ self._rectangles = {}
+
+ def create(self, params):
+ name = params['name']
+ if name in self._rectangles:
+ raise InvalidOperation("SPRET0001E", {'name': name})
+ self._rectangles[name] = Rectangle(params['length'], params['width'])
+ return name
+
+ def get_list(self):
+ return sorted(self._rectangles)
+
+
+class RectangleModel(object):
+ def __init__(self, parent_model):
+ self._rectangles = parent_model._rectangles
+
+ def lookup(self, name):
+ try:
+ rectangle = self._rectangles[name]
+ except KeyError:
+ raise NotFoundError("SPRET0002E", {'name': name})
+ return {'length': rectangle.length, 'width': rectangle.width}
+
+ def update(self, name, params):
+ if name not in self._rectangles:
+ raise NotFoundError("SPRET0002E", {'name': name})
+ try:
+ self._rectangles[name].length = params['length']
+ except KeyError:
+ pass
+
+ try:
+ self._rectangles[name].width = params['width']
+ except KeyError:
+ pass
+ return name
+
+ def delete(self, name):
+ try:
+ del self._rectangles[name]
+ except KeyError:
+ pass
+
+
+class Model(BaseModel):
+ def __init__(self):
+ circles = CirclesModel()
+ circle = CircleModel(circles)
+
+ rectangles = RectanglesModel()
+ rectangle = RectangleModel(rectangles)
+
+ return super(Model, self).__init__(
+ [circle, circles, rectangle, rectangles])
+
+
+class Rectangle(object):
+ def __init__(self, length, width):
+ self.length = length
+ self.width = width
+
+
+class Circle(object):
+ def __init__(self, radius):
+ self.radius = radius
diff --git a/src/wok/plugins/sample/po/LINGUAS b/src/wok/plugins/sample/po/LINGUAS
new file mode 100644
index 0000000..469998e
--- /dev/null
+++ b/src/wok/plugins/sample/po/LINGUAS
@@ -0,0 +1,3 @@
+en_US
+pt_BR
+zh_CN
diff --git a/src/wok/plugins/sample/po/Makefile.in.in b/src/wok/plugins/sample/po/Makefile.in.in
new file mode 100644
index 0000000..52ab81c
--- /dev/null
+++ b/src/wok/plugins/sample/po/Makefile.in.in
@@ -0,0 +1,400 @@
+# Makefile for PO directory in any package using GNU gettext.
+# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper at gnu.ai.mit.edu>
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU General Public
+# License but which still want to provide support for the GNU gettext
+# functionality.
+# Please note that the actual code of GNU gettext is covered by the GNU
+# General Public License and is *not* in the public domain.
+#
+# Origin: gettext-0.18
+GETTEXT_MACRO_VERSION = 0.18
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+SHELL = /bin/sh
+ at SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+datadir = @datadir@
+localedir = @prefix@/share/locale
+gettextsrcdir = $(datadir)/gettext/po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+# We use $(MKDIR_P).
+# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
+# on invoking install-sh with the -d option, so your package should contain
+# install-sh as described under AC_PROG_INSTALL.
+mkinstalldirs = $(SHELL) @install_sh@ -d
+install_sh = $(SHELL) @install_sh@
+MKDIR_P = @MKDIR_P@
+MKDIR_P = @MKDIR_P@
+
+GMSGFMT_ = @GMSGFMT@
+GMSGFMT_no = @GMSGFMT@
+GMSGFMT_yes = @GMSGFMT_015@
+GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
+MSGFMT_ = @MSGFMT@
+MSGFMT_no = @MSGFMT@
+MSGFMT_yes = @MSGFMT_015@
+MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
+XGETTEXT_ = @XGETTEXT@
+XGETTEXT_no = @XGETTEXT@
+XGETTEXT_yes = @XGETTEXT_015@
+XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
+MSGMERGE = msgmerge
+MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGINIT = msginit
+MSGCONV = msgconv
+MSGFILTER = msgfilter
+
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+UPDATEPOFILES = @UPDATEPOFILES@
+DUMMYPOFILES = @DUMMYPOFILES@
+DISTFILES.common = Makefile.in.in \
+$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
+DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot \
+$(POFILES) $(GMOFILES) \
+$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+
+# Makevars gets inserted here. (Don't remove this line!)
+
+.SUFFIXES:
+.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
+
+.po.mo:
+ @echo "$(MSGFMT) -c -o $@ $<"; \
+ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
+
+.po.gmo:
+ @lang=`echo $* | sed -e 's,.*/,,'`; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \
+ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+
+.sin.sed:
+ sed -e '/^#/d' $< > t-$@
+ mv t-$@ $@
+
+
+all: check-macro-version update-gmo all- at USE_NLS@
+
+all-yes: stamp-po
+all-no:
+
+# Ensure that the gettext macros and this Makefile.in.in are in sync.
+check-macro-version:
+ @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
+ || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \
+ exit 1; \
+ }
+
+# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
+# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
+# we don't want to bother translators with empty POT files). We assume that
+# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
+# In this case, stamp-po is a nop (i.e. a phony target).
+
+# stamp-po is a timestamp denoting the last time at which the CATALOGS have
+# been loosely updated. Its purpose is that when a developer or translator
+# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
+# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
+# invocations of "make" will do nothing. This timestamp would not be necessary
+# if updating the $(CATALOGS) would always touch them; however, the rule for
+# $(POFILES) has been designed to not touch files that don't need to be
+# changed.
+stamp-po: $(srcdir)/$(DOMAIN).pot
+ test ! -f $(srcdir)/$(DOMAIN).pot || \
+ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
+ @test ! -f $(srcdir)/$(DOMAIN).pot || { \
+ echo "touch stamp-po" && \
+ echo timestamp > stamp-poT && \
+ mv stamp-poT stamp-po; \
+ }
+
+# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
+# otherwise packages like GCC can not be built if only parts of the source
+# have been downloaded.
+
+$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
+ $(srcdir)/gen-pot $(POTFILES)
+
+# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
+# every "make" invocation, only create it when it is missing.
+# Only "make $(DOMAIN).pot-update" or "make dist" will force an update.
+$(srcdir)/$(DOMAIN).pot:
+ $(MAKE) $(DOMAIN).pot-update
+
+# This target rebuilds a PO file if $(DOMAIN).pot has changed.
+# Note that a PO file is not touched if it doesn't need to be changed.
+$(POFILES): $(srcdir)/$(DOMAIN).pot
+ @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
+ if test -f "$(srcdir)/$${lang}.po"; then \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \
+ cd $(srcdir) \
+ && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \
+ esac; \
+ }; \
+ else \
+ $(MAKE) $${lang}.po-create; \
+ fi
+
+
+install:
+
+install-exec:
+install-data: install-data- at USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ $(INSTALL_DATA) $(srcdir)/$$file \
+ $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ for file in Makevars; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+install-data-no: all
+install-data-yes: all
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
+ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
+ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
+ fi; \
+ done; \
+ done
+
+install-strip: install
+
+installdirs: installdirs-exec installdirs-data
+installdirs-exec:
+installdirs-data: installdirs-data- at USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ : ; \
+ fi
+installdirs-data-no:
+installdirs-data-yes:
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ fi; \
+ done; \
+ done
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+
+uninstall-exec:
+uninstall-data: uninstall-data- at USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+uninstall-data-no:
+uninstall-data-yes:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ done; \
+ done
+
+check: all
+
+info dvi ps pdf html tags TAGS ctags CTAGS ID:
+
+mostlyclean:
+ rm -f remove-potcdate.sed
+ rm -f stamp-poT
+ rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f stamp-po $(GMOFILES)
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir:
+ $(MAKE) update-po
+ @$(MAKE) dist2
+# This is a separate target because 'update-po' must be executed before.
+dist2: stamp-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ dists="$$dists Makevars.template"; \
+ fi; \
+ if test -f $(srcdir)/$(DOMAIN).pot; then \
+ dists="$$dists $(DOMAIN).pot stamp-po"; \
+ fi; \
+ if test -f $(srcdir)/ChangeLog; then \
+ dists="$$dists ChangeLog"; \
+ fi; \
+ for i in 0 1 2 3 4 5 6 7 8 9; do \
+ if test -f $(srcdir)/ChangeLog.$$i; then \
+ dists="$$dists ChangeLog.$$i"; \
+ fi; \
+ done; \
+ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
+ for file in $$dists; do \
+ if test -f $$file; then \
+ cp -p $$file $(distdir) || exit 1; \
+ else \
+ cp -p $(srcdir)/$$file $(distdir) || exit 1; \
+ fi; \
+ done
+
+update-po: Makefile
+ $(MAKE) $(DOMAIN).pot-update
+ test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
+ $(MAKE) update-gmo
+
+# General rule for creating PO files.
+
+.nop.po-create:
+ @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
+ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \
+ exit 1
+
+# General rule for updating PO files.
+
+.nop.po-update:
+ @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
+ if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \
+ tmpdir=`pwd`; \
+ echo "$$lang:"; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \
+ cd $(srcdir); \
+ if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \
+ esac; \
+ }; then \
+ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "msgmerge for $$lang.po failed!" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi
+
+$(DUMMYPOFILES):
+
+update-gmo: Makefile $(GMOFILES)
+ @:
+
+# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
+# because execution permission bits may not work on the current file system.
+# Use @SHELL@, which is the shell determined by autoconf for the use by its
+# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
+Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
+ cd $(top_builddir) \
+ && @SHELL@ ./config.status $(subdir)/$@.in po-directories
+
+force:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/wok/plugins/sample/po/Makevars b/src/wok/plugins/sample/po/Makevars
new file mode 100644
index 0000000..60de3f1
--- /dev/null
+++ b/src/wok/plugins/sample/po/Makevars
@@ -0,0 +1,41 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = sample
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER =
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = kimchi-devel at ovirt.org
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/src/wok/plugins/sample/po/POTFILES.in b/src/wok/plugins/sample/po/POTFILES.in
new file mode 100644
index 0000000..7dbfb6c
--- /dev/null
+++ b/src/wok/plugins/sample/po/POTFILES.in
@@ -0,0 +1,2 @@
+# List of source files which contain translatable strings.
+plugins/sample/ui/pages/*.tmpl
diff --git a/src/wok/plugins/sample/po/en_US.po b/src/wok/plugins/sample/po/en_US.po
new file mode 100644
index 0000000..207d3c3
--- /dev/null
+++ b/src/wok/plugins/sample/po/en_US.po
@@ -0,0 +1,21 @@
+# English translations for kimchi package.
+# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the kimchi package.
+# shhfeng <shaohef at linux.vnet.ibm.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.2.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: 2014-05-17 02:08+0800\n"
+"Last-Translator: shhfeng <shaohef at linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"Language: en_US\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ASCII\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+
+msgid "SampleTab"
+msgstr "SampleTab"
diff --git a/src/wok/plugins/sample/po/gen-pot b/src/wok/plugins/sample/po/gen-pot
new file mode 100755
index 0000000..c1cfb8f
--- /dev/null
+++ b/src/wok/plugins/sample/po/gen-pot
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+for src in $@; do
+ if [ ${src: -3} == ".py" ]; then
+ cat $src
+ else
+ cat $src | cheetah compile -
+ fi
+done | xgettext --no-location -o sample.pot -L Python -
diff --git a/src/wok/plugins/sample/po/pt_BR.po b/src/wok/plugins/sample/po/pt_BR.po
new file mode 100644
index 0000000..8519d74
--- /dev/null
+++ b/src/wok/plugins/sample/po/pt_BR.po
@@ -0,0 +1,24 @@
+# Portuguese translations for kimchi package
+# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the kimchi package.
+# shhfeng <shaohef at linux.vnet.ibm.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.2.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: 2014-05-17 02:09+0800\n"
+"Last-Translator: CrÃstian Viana <vianac at linux.vnet.ibm.com>\n"
+"Language-Team: Aline Manera <alinefm at br.ibm.com>\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"X-Poedit-Country: Brazil\n"
+"X-Poedit-Language: Portuguese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "SampleTab"
+msgstr "Tab de exemplo"
diff --git a/src/wok/plugins/sample/po/sample.pot b/src/wok/plugins/sample/po/sample.pot
new file mode 100644
index 0000000..458ffe9
--- /dev/null
+++ b/src/wok/plugins/sample/po/sample.pot
@@ -0,0 +1,21 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "SampleTab"
+msgstr ""
diff --git a/src/wok/plugins/sample/po/zh_CN.po b/src/wok/plugins/sample/po/zh_CN.po
new file mode 100644
index 0000000..04b2501
--- /dev/null
+++ b/src/wok/plugins/sample/po/zh_CN.po
@@ -0,0 +1,24 @@
+# Chinese translations for kimchi package
+# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the kimchi package.
+# shhfeng <shaohef at linux.vnet.ibm.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.2.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: 2014-05-17 02:10+0800\n"
+"Last-Translator: shhfeng <shaohef at linux.vnet.ibm.com>\n"
+"Language-Team: Chinese (simplified)\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"X-Poedit-Country: CHINA\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "SampleTab"
+msgstr "ç¤ºä¾æ ç¾"
diff --git a/src/wok/plugins/sample/sample.conf.in b/src/wok/plugins/sample/sample.conf.in
new file mode 100644
index 0000000..9da33e1
--- /dev/null
+++ b/src/wok/plugins/sample/sample.conf.in
@@ -0,0 +1,27 @@
+[wok]
+enable = @ENABLE_SAMPLE@
+plugin_class = "Drawings"
+uri = "/plugins/sample"
+
+[/]
+tools.nocache.on = True
+tools.trailing_slash.on = False
+tools.sessions.on = True
+tools.sessions.name = 'wok'
+tools.sessions.httponly = True
+tools.sessions.locking = 'explicit'
+tools.sessions.storage_type = 'ram'
+
+[/description]
+tools.wokauth.on = True
+
+[/rectangles]
+tools.wokauth.on = True
+
+[/circles]
+tools.wokauth.on = True
+
+[/help]
+tools.staticdir.on = True
+tools.nocache.on = True
+tools.staticdir.dir = wok.config.PluginPaths('sample').ui_dir + '/pages/help'
diff --git a/src/wok/plugins/sample/ui/Makefile.am b/src/wok/plugins/sample/ui/Makefile.am
new file mode 100644
index 0000000..37fec98
--- /dev/null
+++ b/src/wok/plugins/sample/ui/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = config js pages
+
+
diff --git a/src/wok/plugins/sample/ui/config/Makefile.am b/src/wok/plugins/sample/ui/config/Makefile.am
new file mode 100644
index 0000000..cf9e09e
--- /dev/null
+++ b/src/wok/plugins/sample/ui/config/Makefile.am
@@ -0,0 +1,21 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = tab-ext.xml
+
diff --git a/src/wok/plugins/sample/ui/config/tab-ext.xml b/src/wok/plugins/sample/ui/config/tab-ext.xml
new file mode 100644
index 0000000..aff0d14
--- /dev/null
+++ b/src/wok/plugins/sample/ui/config/tab-ext.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<tabs-ext>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>SampleTab 1</title>
+ <path>plugins/sample/sample-tab1.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>SampleTab 2</title>
+ <path>plugins/sample/sample-tab2.html</path>
+ </tab>
+</tabs-ext>
diff --git a/src/wok/plugins/sample/ui/css/.gitignore b/src/wok/plugins/sample/ui/css/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/images/.gitignore b/src/wok/plugins/sample/ui/images/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/js/.gitignore b/src/wok/plugins/sample/ui/js/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/js/Makefile.am b/src/wok/plugins/sample/ui/js/Makefile.am
new file mode 100644
index 0000000..4d536ae
--- /dev/null
+++ b/src/wok/plugins/sample/ui/js/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = util.js
diff --git a/src/wok/plugins/sample/ui/js/util.js b/src/wok/plugins/sample/ui/js/util.js
new file mode 100644
index 0000000..7689a81
--- /dev/null
+++ b/src/wok/plugins/sample/ui/js/util.js
@@ -0,0 +1,33 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+
+sample = {};
+
+sample.description = function(suc, err){
+ wok.requestJSON({
+ url : 'plugins/sample/description',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err || function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+};
diff --git a/src/wok/plugins/sample/ui/libs/.gitignore b/src/wok/plugins/sample/ui/libs/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/pages/Makefile.am b/src/wok/plugins/sample/ui/pages/Makefile.am
new file mode 100644
index 0000000..3da95a2
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = i18n.json.tmpl sample-tab1.html.tmpl sample-tab2.html.tmpl
diff --git a/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html
new file mode 100644
index 0000000..7122124
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html
@@ -0,0 +1 @@
+Help page for TAB 1 of Wok's Sample plugin.
diff --git a/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html
new file mode 100644
index 0000000..1bfe448
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html
@@ -0,0 +1 @@
+Help page for TAB 2 of Wok's Sample plugin.
diff --git a/src/wok/plugins/sample/ui/pages/i18n.json.tmpl b/src/wok/plugins/sample/ui/pages/i18n.json.tmpl
new file mode 100644
index 0000000..737bb39
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/i18n.json.tmpl
@@ -0,0 +1,26 @@
+#*
+ * Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang)
+#silent _ = t.gettext
+#silent _t = t.gettext
+{
+ "SampleTab": "$_("SampleTab")"
+}
diff --git a/src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl b/src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl
new file mode 100644
index 0000000..4354d81
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl
@@ -0,0 +1,30 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+<!DOCTYPE html>
+<html>
+<script type="text/javascript" src="plugins/sample/js/util.js"></script>
+<body>
+ <div id="samplebody"/>
+</body>
+<script>
+ sample.description(function(r){
+ \$("#samplebody").html("name: " + r.name + " version: " + r.version);
+ });
+</script>
+</html>
diff --git a/src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl b/src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl
new file mode 100644
index 0000000..4354d81
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl
@@ -0,0 +1,30 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+<!DOCTYPE html>
+<html>
+<script type="text/javascript" src="plugins/sample/js/util.js"></script>
+<body>
+ <div id="samplebody"/>
+</body>
+<script>
+ sample.description(function(r){
+ \$("#samplebody").html("name: " + r.name + " version: " + r.version);
+ });
+</script>
+</html>
--
2.1.4
More information about the Kimchi-devel
mailing list